summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitri John Ledkov <xnox@ubuntu.com>2014-06-24 20:05:13 +0100
committerDimitri John Ledkov <xnox@ubuntu.com>2014-06-24 20:05:13 +0100
commitdd22bd15f6ed3e5eb5c77ab427029be50fe20148 (patch)
treed9491ee40d80688b7f5b1f20504f022686827a57
libavg (1.8.1-1) unstable; urgency=medium
* New upstream release (Closes: #739664) * Mark libdc1394-22-dev as linux-any build-dependency. * Add libvdpau-dev build-dependency. * Add libavresample-dev build-dependency. # imported from the archive
-rwxr-xr-xBuildMacDeps.sh139
-rw-r--r--COPYING504
-rwxr-xr-xCreateVersionFile.py212
-rw-r--r--Makefile.am11
-rw-r--r--NEWS452
-rwxr-xr-xbootstrap33
-rwxr-xr-xcompile99
-rw-r--r--configure.ac232
-rw-r--r--debian/avg_audioplayer.111
-rw-r--r--debian/avg_checktouch.111
-rw-r--r--debian/avg_checkvsync.111
-rw-r--r--debian/avg_chromakey.139
-rw-r--r--debian/avg_showcamera.154
-rw-r--r--debian/avg_showfile.111
-rw-r--r--debian/avg_showfont.119
-rw-r--r--debian/avg_showsvg.117
-rw-r--r--debian/avg_videoinfo.129
-rw-r--r--debian/avg_videoplayer.111
-rw-r--r--debian/changelog500
-rw-r--r--debian/compat1
-rw-r--r--debian/control39
-rw-r--r--debian/copyright45
-rw-r--r--debian/install2
-rw-r--r--debian/libavg.pth1
-rw-r--r--debian/links1
-rw-r--r--debian/patches/foreign.patch19
-rw-r--r--debian/patches/series1
-rw-r--r--debian/python-libavg.examples5
-rwxr-xr-xdebian/rules18
-rw-r--r--debian/source/format1
-rw-r--r--debian/watch2
-rwxr-xr-xdepcomp472
-rwxr-xr-xfixcopyright.py32
-rwxr-xr-xinstall-sh294
-rw-r--r--m4/ac_cxx_namespaces.m427
-rw-r--r--m4/ac_path_generic.m4140
-rw-r--r--m4/avg_version.m43
-rw-r--r--m4/ax_boost_thread.m472
-rw-r--r--m4/ax_check_define.m490
-rw-r--r--m4/ax_check_gl.m4335
-rw-r--r--m4/ax_python_devel.m4312
-rw-r--r--m4/pkg.m4114
-rwxr-xr-xmac/MakeDist.sh89
-rwxr-xr-xmac/PackDeps.sh12
-rwxr-xr-xmac/UnpackDeps.sh48
-rwxr-xr-xmac/avg_env.sh33
-rw-r--r--mac/dc1394_mavericks.patch77
-rw-r--r--mac/fontconfig-disablecache.patch12
-rw-r--r--mac/fontconfig.pc.in.patch4
-rw-r--r--mac/freetype_linespacing.patch13
-rwxr-xr-xmac/gcc-fat.sh113
-rw-r--r--mac/glib.patch4
-rw-r--r--mac/installscripts/background.tifbin0 -> 73280 bytes
-rw-r--r--mac/installscripts/postflight17
-rw-r--r--mac/libavg.10.6.pmdoc/01dist-contents.xml1
-rw-r--r--mac/libavg.10.6.pmdoc/01dist.xml1
-rw-r--r--mac/libavg.10.6.pmdoc/02bindist-contents.xml1
-rw-r--r--mac/libavg.10.6.pmdoc/02bindist.xml1
-rw-r--r--mac/libavg.10.6.pmdoc/index.xml1
-rw-r--r--mac/librsvg_configure.patch17
-rw-r--r--mac/librsvg_makefile.patch11
-rw-r--r--mac/libsdl_mavericks.patch11
-rw-r--r--mac/libtool.m4.patch20
-rw-r--r--mac/pkg-config-mavericks.patch6
-rw-r--r--mac/readme.txt3
-rw-r--r--mac/stpncpy.patch13
-rw-r--r--mac/welcome.txt3
-rwxr-xr-xmakedocs.sh6
-rw-r--r--man/Makefile.am3
-rw-r--r--man/avg_audioplayer.111
-rw-r--r--man/avg_chromakey.139
-rw-r--r--man/avg_showcamera.154
-rw-r--r--man/avg_showfile.111
-rw-r--r--man/avg_showfont.119
-rw-r--r--man/avg_videoinfo.129
-rw-r--r--man/avg_videoplayer.111
-rwxr-xr-xman/avgrc.533
-rwxr-xr-xmissing336
-rwxr-xr-xmkinstalldirs111
-rw-r--r--sphinxdoc/ButtonStates.pngbin0 -> 14193 bytes
-rw-r--r--sphinxdoc/Recognizer.graffle1780
-rw-r--r--sphinxdoc/Recognizer.pngbin0 -> 35806 bytes
-rw-r--r--sphinxdoc/ToggleButtonStates.pngbin0 -> 43048 bytes
-rw-r--r--sphinxdoc/animation.rst252
-rw-r--r--sphinxdoc/app.rst217
-rw-r--r--sphinxdoc/areanodes.rst831
-rw-r--r--sphinxdoc/basenodes.rst382
-rw-r--r--sphinxdoc/conf.py223
-rw-r--r--sphinxdoc/events.rst428
-rw-r--r--sphinxdoc/fx.rst140
-rw-r--r--sphinxdoc/gesture.rst347
-rw-r--r--sphinxdoc/index.rst31
-rw-r--r--sphinxdoc/misc.rst685
-rw-r--r--sphinxdoc/player.rst629
-rw-r--r--sphinxdoc/vectornodes.rst224
-rw-r--r--sphinxdoc/widget.rst591
-rw-r--r--src/Makefile.am16
-rwxr-xr-xsrc/addcopyright.py22
-rw-r--r--src/anim/Anim.cpp123
-rw-r--r--src/anim/Anim.h90
-rw-r--r--src/anim/AttrAnim.cpp103
-rw-r--r--src/anim/AttrAnim.h92
-rw-r--r--src/anim/ContinuousAnim.cpp91
-rw-r--r--src/anim/ContinuousAnim.h59
-rw-r--r--src/anim/EaseInOutAnim.cpp71
-rw-r--r--src/anim/EaseInOutAnim.h55
-rw-r--r--src/anim/LinearAnim.cpp73
-rw-r--r--src/anim/LinearAnim.h60
-rw-r--r--src/anim/Makefile.am9
-rw-r--r--src/anim/ParallelAnim.cpp113
-rw-r--r--src/anim/ParallelAnim.h64
-rw-r--r--src/anim/SimpleAnim.cpp182
-rw-r--r--src/anim/SimpleAnim.h79
-rw-r--r--src/anim/StateAnim.cpp123
-rw-r--r--src/anim/StateAnim.h69
-rw-r--r--src/anim/WaitAnim.cpp69
-rw-r--r--src/anim/WaitAnim.h57
-rw-r--r--src/api.h50
-rw-r--r--src/audio/AudioBuffer.cpp105
-rw-r--r--src/audio/AudioBuffer.h61
-rw-r--r--src/audio/AudioEngine.cpp295
-rw-r--r--src/audio/AudioEngine.h94
-rw-r--r--src/audio/AudioMsg.cpp165
-rw-r--r--src/audio/AudioMsg.h85
-rw-r--r--src/audio/AudioParams.cpp40
-rw-r--r--src/audio/AudioParams.h39
-rw-r--r--src/audio/AudioSource.cpp156
-rw-r--r--src/audio/AudioSource.h66
-rw-r--r--src/audio/Dynamics.h343
-rw-r--r--src/audio/IProcessor.h37
-rw-r--r--src/audio/Makefile.am17
-rw-r--r--src/audio/testlimiter.cpp112
-rw-r--r--src/avgconfig_win.h28
-rw-r--r--src/avgconfigwrapper.h37
-rw-r--r--src/avgrc42
-rw-r--r--src/base/Backtrace.cpp120
-rw-r--r--src/base/Backtrace.h36
-rw-r--r--src/base/BezierCurve.cpp56
-rw-r--r--src/base/BezierCurve.h56
-rw-r--r--src/base/CmdQueue.h56
-rw-r--r--src/base/Command.h56
-rw-r--r--src/base/ConfigMgr.cpp361
-rw-r--r--src/base/ConfigMgr.h93
-rw-r--r--src/base/CubicSpline.cpp104
-rw-r--r--src/base/CubicSpline.h56
-rw-r--r--src/base/DAG.cpp130
-rw-r--r--src/base/DAG.h64
-rw-r--r--src/base/DirEntry.cpp65
-rw-r--r--src/base/DirEntry.h67
-rw-r--r--src/base/Directory.cpp135
-rw-r--r--src/base/Directory.h64
-rw-r--r--src/base/DlfcnWrapper.cpp61
-rw-r--r--src/base/DlfcnWrapper.h41
-rw-r--r--src/base/Exception.cpp99
-rw-r--r--src/base/Exception.h88
-rw-r--r--src/base/FileHelper.cpp164
-rw-r--r--src/base/FileHelper.h53
-rw-r--r--src/base/GLMHelper.cpp183
-rw-r--r--src/base/GLMHelper.h70
-rw-r--r--src/base/GeomHelper.cpp178
-rw-r--r--src/base/GeomHelper.h51
-rw-r--r--src/base/IFrameEndListener.h37
-rw-r--r--src/base/ILogSink.h53
-rw-r--r--src/base/IPlaybackEndListener.h38
-rw-r--r--src/base/IPreRenderListener.h35
-rw-r--r--src/base/Logger.cpp280
-rw-r--r--src/base/Logger.h154
-rw-r--r--src/base/Makefile.am35
-rw-r--r--src/base/MathHelper.cpp78
-rw-r--r--src/base/MathHelper.h93
-rw-r--r--src/base/OSHelper.cpp308
-rw-r--r--src/base/OSHelper.h52
-rw-r--r--src/base/ObjectCounter.cpp187
-rw-r--r--src/base/ObjectCounter.h61
-rw-r--r--src/base/ProfilingZone.cpp91
-rw-r--r--src/base/ProfilingZone.h69
-rw-r--r--src/base/ProfilingZoneID.cpp57
-rw-r--r--src/base/ProfilingZoneID.h50
-rw-r--r--src/base/Queue.h160
-rw-r--r--src/base/Rect.h213
-rw-r--r--src/base/ScopeTimer.cpp35
-rw-r--r--src/base/ScopeTimer.h60
-rw-r--r--src/base/Signal.h119
-rw-r--r--src/base/StandardLogSink.cpp54
-rw-r--r--src/base/StandardLogSink.h39
-rw-r--r--src/base/StringHelper.cpp145
-rw-r--r--src/base/StringHelper.h133
-rw-r--r--src/base/Test.cpp114
-rw-r--r--src/base/Test.h81
-rw-r--r--src/base/TestSuite.cpp72
-rw-r--r--src/base/TestSuite.h49
-rw-r--r--src/base/ThreadHelper.cpp94
-rw-r--r--src/base/ThreadHelper.h37
-rw-r--r--src/base/ThreadProfiler.cpp184
-rw-r--r--src/base/ThreadProfiler.h88
-rw-r--r--src/base/TimeSource.cpp128
-rw-r--r--src/base/TimeSource.h60
-rw-r--r--src/base/Triangle.cpp105
-rw-r--r--src/base/Triangle.h52
-rw-r--r--src/base/UTF8String.cpp62
-rw-r--r--src/base/UTF8String.h46
-rw-r--r--src/base/WideLine.cpp53
-rw-r--r--src/base/WideLine.h48
-rw-r--r--src/base/WorkerThread.cpp41
-rw-r--r--src/base/WorkerThread.h169
-rw-r--r--src/base/XMLHelper.cpp225
-rw-r--r--src/base/XMLHelper.h78
-rw-r--r--src/base/testbase.cpp1024
-rw-r--r--src/base/triangulate/AdvancingFront.cpp104
-rw-r--r--src/base/triangulate/AdvancingFront.h118
-rw-r--r--src/base/triangulate/Makefile.am8
-rw-r--r--src/base/triangulate/Shapes.cpp353
-rw-r--r--src/base/triangulate/Shapes.h296
-rw-r--r--src/base/triangulate/Sweep.cpp796
-rw-r--r--src/base/triangulate/Sweep.h201
-rw-r--r--src/base/triangulate/SweepContext.cpp196
-rw-r--r--src/base/triangulate/SweepContext.h181
-rw-r--r--src/base/triangulate/Triangulate.cpp90
-rw-r--r--src/base/triangulate/Triangulate.h33
-rw-r--r--src/base/triangulate/Utils.h124
-rw-r--r--src/glm/CMakeLists.txt43
-rw-r--r--src/glm/core/_detail.hpp356
-rw-r--r--src/glm/core/_fixes.hpp18
-rw-r--r--src/glm/core/_swizzle.hpp1085
-rw-r--r--src/glm/core/dummy.cpp20
-rw-r--r--src/glm/core/func_common.hpp337
-rw-r--r--src/glm/core/func_common.inl1577
-rw-r--r--src/glm/core/func_exponential.hpp86
-rw-r--r--src/glm/core/func_exponential.inl358
-rw-r--r--src/glm/core/func_geometric.hpp108
-rw-r--r--src/glm/core/func_geometric.inl290
-rw-r--r--src/glm/core/func_integer.hpp158
-rw-r--r--src/glm/core/func_integer.inl597
-rw-r--r--src/glm/core/func_matrix.hpp111
-rw-r--r--src/glm/core/func_matrix.inl571
-rw-r--r--src/glm/core/func_noise.hpp62
-rw-r--r--src/glm/core/func_noise.inl21
-rw-r--r--src/glm/core/func_packing.hpp132
-rw-r--r--src/glm/core/func_packing.inl94
-rw-r--r--src/glm/core/func_trigonometric.hpp156
-rw-r--r--src/glm/core/func_trigonometric.inl745
-rw-r--r--src/glm/core/func_vector_relational.hpp215
-rw-r--r--src/glm/core/func_vector_relational.inl20
-rw-r--r--src/glm/core/hint.hpp21
-rw-r--r--src/glm/core/intrinsic_common.hpp70
-rw-r--r--src/glm/core/intrinsic_common.inl283
-rw-r--r--src/glm/core/intrinsic_exponential.hpp60
-rw-r--r--src/glm/core/intrinsic_exponential.inl0
-rw-r--r--src/glm/core/intrinsic_geometric.hpp57
-rw-r--r--src/glm/core/intrinsic_geometric.inl123
-rw-r--r--src/glm/core/intrinsic_matrix.hpp50
-rw-r--r--src/glm/core/intrinsic_matrix.inl1051
-rw-r--r--src/glm/core/intrinsic_trigonometric.hpp29
-rw-r--r--src/glm/core/intrinsic_trigonometric.inl0
-rw-r--r--src/glm/core/intrinsic_vector_relational.hpp29
-rw-r--r--src/glm/core/intrinsic_vector_relational.inl347
-rw-r--r--src/glm/core/setup.hpp480
-rw-r--r--src/glm/core/type.hpp322
-rw-r--r--src/glm/core/type_float.hpp74
-rw-r--r--src/glm/core/type_gentype.hpp150
-rw-r--r--src/glm/core/type_gentype.inl347
-rw-r--r--src/glm/core/type_half.hpp78
-rw-r--r--src/glm/core/type_half.inl357
-rw-r--r--src/glm/core/type_int.hpp109
-rw-r--r--src/glm/core/type_mat.hpp56
-rw-r--r--src/glm/core/type_mat.inl0
-rw-r--r--src/glm/core/type_mat2x2.hpp281
-rw-r--r--src/glm/core/type_mat2x2.inl648
-rw-r--r--src/glm/core/type_mat2x3.hpp227
-rw-r--r--src/glm/core/type_mat2x3.inl583
-rw-r--r--src/glm/core/type_mat2x4.hpp225
-rw-r--r--src/glm/core/type_mat2x4.inl611
-rw-r--r--src/glm/core/type_mat3x2.hpp231
-rw-r--r--src/glm/core/type_mat3x2.inl623
-rw-r--r--src/glm/core/type_mat3x3.hpp283
-rw-r--r--src/glm/core/type_mat3x3.inl750
-rw-r--r--src/glm/core/type_mat3x4.hpp232
-rw-r--r--src/glm/core/type_mat3x4.inl653
-rw-r--r--src/glm/core/type_mat4x2.hpp242
-rw-r--r--src/glm/core/type_mat4x2.inl670
-rw-r--r--src/glm/core/type_mat4x3.hpp240
-rw-r--r--src/glm/core/type_mat4x3.inl675
-rw-r--r--src/glm/core/type_mat4x4.hpp286
-rw-r--r--src/glm/core/type_mat4x4.inl840
-rw-r--r--src/glm/core/type_size.hpp24
-rw-r--r--src/glm/core/type_vec.hpp22
-rw-r--r--src/glm/core/type_vec.inl0
-rw-r--r--src/glm/core/type_vec1.hpp172
-rw-r--r--src/glm/core/type_vec1.inl884
-rw-r--r--src/glm/core/type_vec2.hpp263
-rw-r--r--src/glm/core/type_vec2.inl1010
-rw-r--r--src/glm/core/type_vec3.hpp269
-rw-r--r--src/glm/core/type_vec3.inl1097
-rw-r--r--src/glm/core/type_vec4.hpp282
-rw-r--r--src/glm/core/type_vec4.inl1226
-rw-r--r--src/glm/ext.hpp97
-rw-r--r--src/glm/glm.hpp93
-rw-r--r--src/glm/gtc/half_float.hpp401
-rw-r--r--src/glm/gtc/half_float.inl975
-rw-r--r--src/glm/gtc/matrix_access.hpp70
-rw-r--r--src/glm/gtc/matrix_access.inl59
-rw-r--r--src/glm/gtc/matrix_integer.hpp204
-rw-r--r--src/glm/gtc/matrix_inverse.hpp51
-rw-r--r--src/glm/gtc/matrix_inverse.inl139
-rw-r--r--src/glm/gtc/matrix_transform.hpp158
-rw-r--r--src/glm/gtc/matrix_transform.inl397
-rw-r--r--src/glm/gtc/quaternion.hpp245
-rw-r--r--src/glm/gtc/quaternion.inl584
-rw-r--r--src/glm/gtc/swizzle.hpp354
-rw-r--r--src/glm/gtc/swizzle.inl177
-rw-r--r--src/glm/gtc/type_precision.hpp220
-rw-r--r--src/glm/gtc/type_precision.inl13
-rw-r--r--src/glm/gtc/type_ptr.hpp449
-rw-r--r--src/glm/gtc/type_ptr.inl0
-rw-r--r--src/glm/gtx/associated_min_max.hpp82
-rw-r--r--src/glm/gtx/associated_min_max.inl916
-rw-r--r--src/glm/gtx/bit.hpp107
-rw-r--r--src/glm/gtx/bit.inl743
-rw-r--r--src/glm/gtx/closest_point.hpp47
-rw-r--r--src/glm/gtx/closest_point.inl41
-rw-r--r--src/glm/gtx/color_cast.hpp107
-rw-r--r--src/glm/gtx/color_cast.inl739
-rw-r--r--src/glm/gtx/color_space.hpp77
-rw-r--r--src/glm/gtx/color_space.inl154
-rw-r--r--src/glm/gtx/color_space_YCoCg.hpp65
-rw-r--r--src/glm/gtx/color_space_YCoCg.inl69
-rw-r--r--src/glm/gtx/compatibility.hpp170
-rw-r--r--src/glm/gtx/compatibility.inl141
-rw-r--r--src/glm/gtx/component_wise.hpp63
-rw-r--r--src/glm/gtx/component_wise.inl52
-rw-r--r--src/glm/gtx/epsilon.hpp59
-rw-r--r--src/glm/gtx/epsilon.inl234
-rw-r--r--src/glm/gtx/euler_angles.hpp141
-rw-r--r--src/glm/gtx/euler_angles.inl249
-rw-r--r--src/glm/gtx/extend.hpp47
-rw-r--r--src/glm/gtx/extend.inl60
-rw-r--r--src/glm/gtx/extented_min_max.hpp175
-rw-r--r--src/glm/gtx/extented_min_max.inl182
-rw-r--r--src/glm/gtx/fast_exponential.hpp81
-rw-r--r--src/glm/gtx/fast_exponential.inl294
-rw-r--r--src/glm/gtx/fast_square_root.hpp68
-rw-r--r--src/glm/gtx/fast_square_root.inl237
-rw-r--r--src/glm/gtx/fast_trigonometry.hpp81
-rw-r--r--src/glm/gtx/fast_trigonometry.inl272
-rw-r--r--src/glm/gtx/gradient_paint.hpp55
-rw-r--r--src/glm/gtx/gradient_paint.inl44
-rw-r--r--src/glm/gtx/handed_coordinate_space.hpp55
-rw-r--r--src/glm/gtx/handed_coordinate_space.inl34
-rw-r--r--src/glm/gtx/inertia.hpp95
-rw-r--r--src/glm/gtx/inertia.inl103
-rw-r--r--src/glm/gtx/int_10_10_10_2.hpp47
-rw-r--r--src/glm/gtx/int_10_10_10_2.inl21
-rw-r--r--src/glm/gtx/integer.hpp56
-rw-r--r--src/glm/gtx/integer.inl91
-rw-r--r--src/glm/gtx/intersect.hpp73
-rw-r--r--src/glm/gtx/intersect.inl201
-rw-r--r--src/glm/gtx/log_base.hpp47
-rw-r--r--src/glm/gtx/log_base.inl92
-rw-r--r--src/glm/gtx/matrix_cross_product.hpp51
-rw-r--r--src/glm/gtx/matrix_cross_product.inl44
-rw-r--r--src/glm/gtx/matrix_interpolation.hpp66
-rw-r--r--src/glm/gtx/matrix_interpolation.inl117
-rw-r--r--src/glm/gtx/matrix_major_storage.hpp123
-rw-r--r--src/glm/gtx/matrix_major_storage.inl176
-rw-r--r--src/glm/gtx/matrix_operation.hpp93
-rw-r--r--src/glm/gtx/matrix_operation.inl129
-rw-r--r--src/glm/gtx/matrix_query.hpp95
-rw-r--r--src/glm/gtx/matrix_query.inl144
-rw-r--r--src/glm/gtx/mixed_product.hpp46
-rw-r--r--src/glm/gtx/mixed_product.inl36
-rw-r--r--src/glm/gtx/multiple.hpp53
-rw-r--r--src/glm/gtx/multiple.inl191
-rw-r--r--src/glm/gtx/noise.hpp63
-rw-r--r--src/glm/gtx/noise.inl792
-rw-r--r--src/glm/gtx/norm.hpp143
-rw-r--r--src/glm/gtx/norm.inl130
-rw-r--r--src/glm/gtx/normal.hpp47
-rw-r--r--src/glm/gtx/normal.inl27
-rw-r--r--src/glm/gtx/normalize_dot.hpp59
-rw-r--r--src/glm/gtx/normalize_dot.inl120
-rw-r--r--src/glm/gtx/number_precision.hpp69
-rw-r--r--src/glm/gtx/number_precision.inl13
-rw-r--r--src/glm/gtx/ocl_type.hpp110
-rw-r--r--src/glm/gtx/ocl_type.inl0
-rw-r--r--src/glm/gtx/optimum_pow.hpp70
-rw-r--r--src/glm/gtx/optimum_pow.inl63
-rw-r--r--src/glm/gtx/orthonormalize.hpp52
-rw-r--r--src/glm/gtx/orthonormalize.inl49
-rw-r--r--src/glm/gtx/perpendicular.hpp62
-rw-r--r--src/glm/gtx/perpendicular.inl40
-rw-r--r--src/glm/gtx/polar_coordinates.hpp49
-rw-r--r--src/glm/gtx/polar_coordinates.inl42
-rw-r--r--src/glm/gtx/projection.hpp60
-rw-r--r--src/glm/gtx/projection.inl40
-rw-r--r--src/glm/gtx/quaternion.hpp217
-rw-r--r--src/glm/gtx/quaternion.inl303
-rw-r--r--src/glm/gtx/random.hpp89
-rw-r--r--src/glm/gtx/random.inl536
-rw-r--r--src/glm/gtx/raw_data.hpp58
-rw-r--r--src/glm/gtx/raw_data.inl11
-rw-r--r--src/glm/gtx/reciprocal.hpp99
-rw-r--r--src/glm/gtx/reciprocal.inl593
-rw-r--r--src/glm/gtx/rotate_vector.hpp114
-rw-r--r--src/glm/gtx/rotate_vector.inl149
-rw-r--r--src/glm/gtx/simd_mat4.hpp183
-rw-r--r--src/glm/gtx/simd_mat4.inl309
-rw-r--r--src/glm/gtx/simd_vec4.hpp474
-rw-r--r--src/glm/gtx/simd_vec4.inl730
-rw-r--r--src/glm/gtx/simplex.hpp70
-rw-r--r--src/glm/gtx/simplex.inl0
-rw-r--r--src/glm/gtx/spline.hpp73
-rw-r--r--src/glm/gtx/spline.inl74
-rw-r--r--src/glm/gtx/std_based_type.hpp72
-rw-r--r--src/glm/gtx/std_based_type.inl13
-rw-r--r--src/glm/gtx/string_cast.hpp57
-rw-r--r--src/glm/gtx/string_cast.inl597
-rw-r--r--src/glm/gtx/transform.hpp103
-rw-r--r--src/glm/gtx/transform.inl94
-rw-r--r--src/glm/gtx/transform2.hpp118
-rw-r--r--src/glm/gtx/transform2.inl159
-rw-r--r--src/glm/gtx/ulp.hpp70
-rw-r--r--src/glm/gtx/ulp.inl396
-rw-r--r--src/glm/gtx/unsigned_int.hpp59
-rw-r--r--src/glm/gtx/unsigned_int.inl45
-rw-r--r--src/glm/gtx/vec1.hpp121
-rw-r--r--src/glm/gtx/vec1.inl0
-rw-r--r--src/glm/gtx/vector_access.hpp66
-rw-r--r--src/glm/gtx/vector_access.inl58
-rw-r--r--src/glm/gtx/vector_angle.hpp72
-rw-r--r--src/glm/gtx/vector_angle.inl58
-rw-r--r--src/glm/gtx/vector_query.hpp95
-rw-r--r--src/glm/gtx/vector_query.inl174
-rw-r--r--src/glm/gtx/verbose_operator.hpp64
-rw-r--r--src/glm/gtx/verbose_operator.inl129
-rw-r--r--src/glm/gtx/wrap.hpp54
-rw-r--r--src/glm/gtx/wrap.inl173
-rw-r--r--src/glm/virtrev/xstream.hpp148
-rw-r--r--src/graphics/AppleDisplay.cpp75
-rw-r--r--src/graphics/AppleDisplay.h46
-rw-r--r--src/graphics/BCMDisplay.cpp142
-rw-r--r--src/graphics/BCMDisplay.h45
-rw-r--r--src/graphics/Bitmap.cpp1814
-rw-r--r--src/graphics/Bitmap.h186
-rw-r--r--src/graphics/BitmapLoader.cpp156
-rw-r--r--src/graphics/BitmapLoader.h55
-rw-r--r--src/graphics/BmpTextureMover.cpp111
-rw-r--r--src/graphics/BmpTextureMover.h54
-rw-r--r--src/graphics/CGLContext.cpp114
-rw-r--r--src/graphics/CGLContext.h56
-rw-r--r--src/graphics/ContribDefs.h75
-rw-r--r--src/graphics/Display.cpp136
-rw-r--r--src/graphics/Display.h71
-rw-r--r--src/graphics/EGLContext.cpp202
-rw-r--r--src/graphics/EGLContext.h61
-rw-r--r--src/graphics/FBO.cpp410
-rw-r--r--src/graphics/FBO.h97
-rw-r--r--src/graphics/Filter.cpp55
-rw-r--r--src/graphics/Filter.h56
-rw-r--r--src/graphics/Filter3x3.cpp68
-rw-r--r--src/graphics/Filter3x3.h82
-rw-r--r--src/graphics/FilterBandpass.cpp77
-rw-r--r--src/graphics/FilterBandpass.h52
-rw-r--r--src/graphics/FilterBlur.cpp69
-rw-r--r--src/graphics/FilterBlur.h45
-rw-r--r--src/graphics/FilterConvol.h141
-rw-r--r--src/graphics/FilterDilation.cpp71
-rw-r--r--src/graphics/FilterDilation.h45
-rw-r--r--src/graphics/FilterErosion.cpp71
-rw-r--r--src/graphics/FilterErosion.h45
-rw-r--r--src/graphics/FilterFastBandpass.cpp92
-rw-r--r--src/graphics/FilterFastBandpass.h46
-rw-r--r--src/graphics/FilterFastDownscale.cpp98
-rw-r--r--src/graphics/FilterFastDownscale.h47
-rw-r--r--src/graphics/FilterFloodfill.h165
-rw-r--r--src/graphics/FilterGauss.cpp203
-rw-r--r--src/graphics/FilterGauss.h52
-rw-r--r--src/graphics/FilterGetAlpha.cpp66
-rw-r--r--src/graphics/FilterGetAlpha.h45
-rw-r--r--src/graphics/FilterHighpass.cpp94
-rw-r--r--src/graphics/FilterHighpass.h46
-rw-r--r--src/graphics/FilterIntensity.cpp56
-rw-r--r--src/graphics/FilterIntensity.h45
-rw-r--r--src/graphics/FilterMask.cpp84
-rw-r--r--src/graphics/FilterMask.h45
-rw-r--r--src/graphics/FilterNormalize.cpp55
-rw-r--r--src/graphics/FilterNormalize.h44
-rw-r--r--src/graphics/FilterResizeBilinear.cpp77
-rw-r--r--src/graphics/FilterResizeBilinear.h39
-rw-r--r--src/graphics/FilterResizeGaussian.cpp78
-rw-r--r--src/graphics/FilterResizeGaussian.h41
-rw-r--r--src/graphics/FilterThreshold.cpp61
-rw-r--r--src/graphics/FilterThreshold.h44
-rw-r--r--src/graphics/FilterUnmultiplyAlpha.cpp96
-rw-r--r--src/graphics/FilterUnmultiplyAlpha.h43
-rw-r--r--src/graphics/Filtercolorize.cpp145
-rw-r--r--src/graphics/Filtercolorize.h48
-rw-r--r--src/graphics/Filterfill.h68
-rw-r--r--src/graphics/Filterfillrect.h75
-rw-r--r--src/graphics/Filterflip.cpp54
-rw-r--r--src/graphics/Filterflip.h43
-rw-r--r--src/graphics/FilterflipX.cpp78
-rw-r--r--src/graphics/FilterflipX.h43
-rw-r--r--src/graphics/Filterfliprgb.cpp92
-rw-r--r--src/graphics/Filterfliprgb.h45
-rw-r--r--src/graphics/Filterfliprgba.cpp56
-rw-r--r--src/graphics/Filterfliprgba.h44
-rw-r--r--src/graphics/Filterflipuv.cpp53
-rw-r--r--src/graphics/Filterflipuv.h44
-rw-r--r--src/graphics/Filtergrayscale.cpp80
-rw-r--r--src/graphics/Filtergrayscale.h45
-rw-r--r--src/graphics/GL/gl.h2262
-rw-r--r--src/graphics/GL/glext.h11489
-rw-r--r--src/graphics/GL/glu.h341
-rw-r--r--src/graphics/GL/glx.h552
-rw-r--r--src/graphics/GL/wglext.h943
-rw-r--r--src/graphics/GLBufferCache.cpp73
-rw-r--r--src/graphics/GLBufferCache.h55
-rw-r--r--src/graphics/GLConfig.cpp83
-rw-r--r--src/graphics/GLConfig.h52
-rw-r--r--src/graphics/GLContext.cpp656
-rw-r--r--src/graphics/GLContext.h156
-rw-r--r--src/graphics/GLContextAttribs.cpp67
-rw-r--r--src/graphics/GLContextAttribs.h44
-rw-r--r--src/graphics/GLShaderParam.cpp87
-rw-r--r--src/graphics/GLShaderParam.h128
-rw-r--r--src/graphics/GLTexture.cpp370
-rw-r--r--src/graphics/GLTexture.h98
-rw-r--r--src/graphics/GLXContext.cpp265
-rw-r--r--src/graphics/GLXContext.h65
-rw-r--r--src/graphics/GPUBandpassFilter.cpp78
-rw-r--r--src/graphics/GPUBandpassFilter.h56
-rw-r--r--src/graphics/GPUBlurFilter.cpp122
-rw-r--r--src/graphics/GPUBlurFilter.h68
-rw-r--r--src/graphics/GPUBrightnessFilter.cpp64
-rw-r--r--src/graphics/GPUBrightnessFilter.h50
-rw-r--r--src/graphics/GPUChromaKeyFilter.cpp137
-rw-r--r--src/graphics/GPUChromaKeyFilter.h74
-rw-r--r--src/graphics/GPUFilter.cpp287
-rw-r--r--src/graphics/GPUFilter.h89
-rw-r--r--src/graphics/GPUHueSatFilter.cpp77
-rw-r--r--src/graphics/GPUHueSatFilter.h59
-rw-r--r--src/graphics/GPUInvertFilter.cpp56
-rw-r--r--src/graphics/GPUInvertFilter.h49
-rw-r--r--src/graphics/GPUNullFilter.cpp61
-rw-r--r--src/graphics/GPUNullFilter.h48
-rw-r--r--src/graphics/GPURGB2YUVFilter.cpp68
-rw-r--r--src/graphics/GPURGB2YUVFilter.h48
-rw-r--r--src/graphics/GPUShadowFilter.cpp136
-rw-r--r--src/graphics/GPUShadowFilter.h76
-rw-r--r--src/graphics/GraphicsTest.cpp142
-rw-r--r--src/graphics/GraphicsTest.h52
-rw-r--r--src/graphics/HistoryPreProcessor.cpp157
-rw-r--r--src/graphics/HistoryPreProcessor.h89
-rw-r--r--src/graphics/ImagingProjection.cpp91
-rw-r--r--src/graphics/ImagingProjection.h66
-rw-r--r--src/graphics/Makefile.am95
-rw-r--r--src/graphics/OGLHelper.cpp440
-rw-r--r--src/graphics/OGLHelper.h253
-rw-r--r--src/graphics/OGLShader.cpp206
-rw-r--r--src/graphics/OGLShader.h101
-rw-r--r--src/graphics/PBO.cpp245
-rw-r--r--src/graphics/PBO.h74
-rw-r--r--src/graphics/Pixel16.h180
-rw-r--r--src/graphics/Pixel24.h190
-rw-r--r--src/graphics/Pixel32.cpp134
-rw-r--r--src/graphics/Pixel32.h208
-rw-r--r--src/graphics/Pixel8.h150
-rw-r--r--src/graphics/PixelFormat.cpp288
-rw-r--r--src/graphics/PixelFormat.h66
-rw-r--r--src/graphics/Pixeldefs.h29
-rw-r--r--src/graphics/ShaderRegistry.cpp193
-rw-r--r--src/graphics/ShaderRegistry.h73
-rw-r--r--src/graphics/StandardShader.cpp216
-rw-r--r--src/graphics/StandardShader.h106
-rw-r--r--src/graphics/SubVertexArray.cpp103
-rw-r--r--src/graphics/SubVertexArray.h75
-rw-r--r--src/graphics/TextureMover.cpp79
-rw-r--r--src/graphics/TextureMover.h71
-rw-r--r--src/graphics/TwoPassScale.h355
-rw-r--r--src/graphics/VertexArray.cpp159
-rw-r--r--src/graphics/VertexArray.h69
-rw-r--r--src/graphics/VertexData.cpp253
-rw-r--r--src/graphics/VertexData.h100
-rw-r--r--src/graphics/WGLContext.cpp184
-rw-r--r--src/graphics/WGLContext.h56
-rw-r--r--src/graphics/WinDisplay.cpp61
-rw-r--r--src/graphics/WinDisplay.h45
-rw-r--r--src/graphics/X11Display.cpp124
-rw-r--r--src/graphics/X11Display.h59
-rw-r--r--src/graphics/baseline/BandpassResult.pngbin0 -> 2864 bytes
-rw-r--r--src/graphics/baseline/BlurResult.pngbin0 -> 2809 bytes
-rw-r--r--src/graphics/baseline/ChromaKeyMedianResult.pngbin0 -> 607 bytes
-rw-r--r--src/graphics/baseline/ChromaKeyResult0.pngbin0 -> 410 bytes
-rw-r--r--src/graphics/baseline/ChromaKeyResult1.pngbin0 -> 503 bytes
-rw-r--r--src/graphics/baseline/ChromaKeyResult2.pngbin0 -> 497 bytes
-rw-r--r--src/graphics/baseline/ChromaKeySpillResult1.pngbin0 -> 370 bytes
-rw-r--r--src/graphics/baseline/ChromaKeySpillResult2.pngbin0 -> 335 bytes
-rw-r--r--src/graphics/baseline/ChromaKeySpillResult3.pngbin0 -> 353 bytes
-rw-r--r--src/graphics/baseline/DilationResult.pngbin0 -> 88 bytes
-rw-r--r--src/graphics/baseline/ErosionResult.pngbin0 -> 82 bytes
-rw-r--r--src/graphics/baseline/FastBandpassResult.pngbin0 -> 2859 bytes
-rw-r--r--src/graphics/baseline/FastDownscaleResult.pngbin0 -> 69 bytes
-rw-r--r--src/graphics/baseline/FloodfillResult.pngbin0 -> 121 bytes
-rw-r--r--src/graphics/baseline/Gauss15Result.pngbin0 -> 89 bytes
-rw-r--r--src/graphics/baseline/Gauss1Result.pngbin0 -> 81 bytes
-rw-r--r--src/graphics/baseline/Gauss3Result.pngbin0 -> 96 bytes
-rw-r--r--src/graphics/baseline/Gauss5Result.pngbin0 -> 95 bytes
-rw-r--r--src/graphics/baseline/GetAlphaResult.pngbin0 -> 1235 bytes
-rw-r--r--src/graphics/baseline/HighpassResult.pngbin0 -> 100 bytes
-rw-r--r--src/graphics/baseline/HslColorizeResult0.pngbin0 -> 3232 bytes
-rw-r--r--src/graphics/baseline/HslColorizeResult1.pngbin0 -> 3286 bytes
-rw-r--r--src/graphics/baseline/HslColorizeResult2.pngbin0 -> 3223 bytes
-rw-r--r--src/graphics/baseline/HslHueResult0.pngbin0 -> 3131 bytes
-rw-r--r--src/graphics/baseline/HslHueResult1.pngbin0 -> 3201 bytes
-rw-r--r--src/graphics/baseline/HslHueResult2.pngbin0 -> 3218 bytes
-rw-r--r--src/graphics/baseline/LineResultB8G8R8.pngbin0 -> 2848 bytes
-rw-r--r--src/graphics/baseline/LineResultB8G8R8A8.pngbin0 -> 2863 bytes
-rw-r--r--src/graphics/baseline/LineResultI8.pngbin0 -> 2855 bytes
-rw-r--r--src/graphics/baseline/MaskResultB8G8R8.pngbin0 -> 89 bytes
-rw-r--r--src/graphics/baseline/MaskResultB8G8R8X8.pngbin0 -> 89 bytes
-rw-r--r--src/graphics/baseline/MaskResultI8.pngbin0 -> 73 bytes
-rw-r--r--src/graphics/baseline/ResizeBilinearResultB8G8R8.pngbin0 -> 876 bytes
-rw-r--r--src/graphics/baseline/ResizeBilinearResultB8G8R8A8.pngbin0 -> 1288 bytes
-rw-r--r--src/graphics/baseline/ResizeBilinearResultB8G8R8X8.pngbin0 -> 812 bytes
-rw-r--r--src/graphics/baseline/ThresholdResult.pngbin0 -> 73 bytes
-rw-r--r--src/graphics/baseline/YUV2RGBResult1.pngbin0 -> 203 bytes
-rw-r--r--src/graphics/baseline/bandpass_i8-64x64.pngbin0 -> 1160 bytes
-rw-r--r--src/graphics/baseline/bandpass_spike.pngbin0 -> 293 bytes
-rw-r--r--src/graphics/baseline/blur05_flat.pngbin0 -> 1312 bytes
-rw-r--r--src/graphics/baseline/blur05_spike.pngbin0 -> 118 bytes
-rw-r--r--src/graphics/baseline/blur1_spike.pngbin0 -> 177 bytes
-rw-r--r--src/graphics/baseline/blur3_spike.pngbin0 -> 197 bytes
-rw-r--r--src/graphics/baseline/blur_rgb24-64x64.pngbin0 -> 3659 bytes
-rw-r--r--src/graphics/baseline/blur_rgb24alpha-64x64.pngbin0 -> 5501 bytes
-rw-r--r--src/graphics/baseline/copyPixels_B8G8R8X8_I8.pngbin0 -> 85 bytes
-rw-r--r--src/graphics/baseline/copyPixels_R8G8B8X8_I8.pngbin0 -> 85 bytes
-rw-r--r--src/graphics/baseline/invert_rgb24-64x64.pngbin0 -> 2393 bytes
-rw-r--r--src/graphics/benchmarkgraphics.cpp255
-rw-r--r--src/graphics/shaders/Makefile.am3
-rw-r--r--src/graphics/shaders/bandpass.frag42
-rw-r--r--src/graphics/shaders/brightness.frag35
-rw-r--r--src/graphics/shaders/chromakey.frag134
-rw-r--r--src/graphics/shaders/chromakey_erosion.frag47
-rw-r--r--src/graphics/shaders/helper.frag109
-rw-r--r--src/graphics/shaders/horizblur.frag43
-rw-r--r--src/graphics/shaders/horizshadow.frag44
-rw-r--r--src/graphics/shaders/huesat.frag72
-rw-r--r--src/graphics/shaders/invert.frag41
-rw-r--r--src/graphics/shaders/minimal.frag37
-rw-r--r--src/graphics/shaders/null.frag33
-rw-r--r--src/graphics/shaders/rgb2yuv.frag38
-rw-r--r--src/graphics/shaders/standard.frag101
-rw-r--r--src/graphics/shaders/standard.vert36
-rw-r--r--src/graphics/shaders/vertblur.frag42
-rw-r--r--src/graphics/shaders/vertshadow.frag54
-rw-r--r--src/graphics/testgpu.cpp530
-rw-r--r--src/graphics/testgraphics.cpp1057
-rw-r--r--src/imaging/Blob.cpp616
-rw-r--r--src/imaging/Blob.h120
-rw-r--r--src/imaging/CMUCamera.cpp466
-rw-r--r--src/imaging/CMUCamera.h82
-rw-r--r--src/imaging/CMUCameraUtils.cpp369
-rw-r--r--src/imaging/CMUCameraUtils.h46
-rw-r--r--src/imaging/Camera.cpp301
-rw-r--r--src/imaging/Camera.h120
-rw-r--r--src/imaging/CameraInfo.cpp159
-rw-r--r--src/imaging/CameraInfo.h100
-rw-r--r--src/imaging/CoordTransformer.cpp37
-rw-r--r--src/imaging/CoordTransformer.h45
-rw-r--r--src/imaging/DSCamera.cpp733
-rw-r--r--src/imaging/DSCamera.h105
-rw-r--r--src/imaging/DSHelper.cpp311
-rw-r--r--src/imaging/DSHelper.h63
-rw-r--r--src/imaging/DSSampleGrabber.cpp220
-rw-r--r--src/imaging/DSSampleGrabber.h91
-rw-r--r--src/imaging/DeDistort.cpp306
-rw-r--r--src/imaging/DeDistort.h88
-rw-r--r--src/imaging/FWCamera.cpp671
-rw-r--r--src/imaging/FWCamera.h94
-rw-r--r--src/imaging/FWCameraUtils.cpp366
-rw-r--r--src/imaging/FWCameraUtils.h48
-rw-r--r--src/imaging/FakeCamera.cpp149
-rw-r--r--src/imaging/FakeCamera.h69
-rw-r--r--src/imaging/FilterClearBorder.cpp67
-rw-r--r--src/imaging/FilterClearBorder.h51
-rw-r--r--src/imaging/FilterDistortion.cpp83
-rw-r--r--src/imaging/FilterDistortion.h56
-rw-r--r--src/imaging/FilterWipeBorder.cpp70
-rw-r--r--src/imaging/FilterWipeBorder.h50
-rw-r--r--src/imaging/IDSSampleCallback.h37
-rw-r--r--src/imaging/Makefile.am41
-rw-r--r--src/imaging/Run.cpp36
-rw-r--r--src/imaging/Run.h56
-rw-r--r--src/imaging/TrackerConfig.cpp268
-rw-r--r--src/imaging/TrackerConfig.h75
-rw-r--r--src/imaging/TrackerThread.cpp548
-rw-r--r--src/imaging/TrackerThread.h135
-rw-r--r--src/imaging/V4LCamera.cpp713
-rw-r--r--src/imaging/V4LCamera.h100
-rw-r--r--src/imaging/avgtrackerrc.minimal49
-rw-r--r--src/imaging/baseline/FilterClearBorderResult1.pngbin0 -> 220 bytes
-rw-r--r--src/imaging/baseline/FilterClearBorderResult3.pngbin0 -> 171 bytes
-rw-r--r--src/imaging/baseline/FilterWipeBorderResult1.pngbin0 -> 230 bytes
-rw-r--r--src/imaging/baseline/FilterWipeBorderResult3.pngbin0 -> 187 bytes
-rw-r--r--src/imaging/checktracking.cpp0
-rw-r--r--src/imaging/qedit.h9914
-rw-r--r--src/imaging/test_comp.pngbin0 -> 851 bytes
-rw-r--r--src/imaging/testimaging.cpp239
-rw-r--r--src/imaging/trackerconfigdtd.cpp175
-rw-r--r--src/imaging/trackerconfigdtd.h27
-rw-r--r--src/lmfit/Makefile.am7
-rw-r--r--src/lmfit/lm_eval.c81
-rw-r--r--src/lmfit/lm_eval.h11
-rw-r--r--src/lmfit/lmmin.c1320
-rw-r--r--src/lmfit/lmmin.h52
-rw-r--r--src/oscpack/CHANGES68
-rw-r--r--src/oscpack/IpEndpointName.cpp81
-rw-r--r--src/oscpack/IpEndpointName.h74
-rw-r--r--src/oscpack/LICENSE28
-rw-r--r--src/oscpack/Makefile.am12
-rw-r--r--src/oscpack/MessageMappingOscPacketListener.h73
-rw-r--r--src/oscpack/NetworkingUtils.cpp98
-rw-r--r--src/oscpack/NetworkingUtils.h49
-rw-r--r--src/oscpack/OscException.h54
-rw-r--r--src/oscpack/OscHostEndianness.h70
-rw-r--r--src/oscpack/OscOutboundPacketStream.cpp639
-rw-r--r--src/oscpack/OscOutboundPacketStream.h142
-rw-r--r--src/oscpack/OscPacketListener.h72
-rw-r--r--src/oscpack/OscPrintReceivedElements.cpp240
-rw-r--r--src/oscpack/OscPrintReceivedElements.h49
-rw-r--r--src/oscpack/OscReceivedElements.cpp722
-rw-r--r--src/oscpack/OscReceivedElements.h486
-rw-r--r--src/oscpack/OscTypes.cpp40
-rw-r--r--src/oscpack/OscTypes.h178
-rw-r--r--src/oscpack/PacketListener.h44
-rw-r--r--src/oscpack/README80
-rw-r--r--src/oscpack/TODO55
-rw-r--r--src/oscpack/TimerListener.h40
-rw-r--r--src/oscpack/UdpSocket.cpp1039
-rw-r--r--src/oscpack/UdpSocket.h158
-rw-r--r--src/player/AVGNode.cpp53
-rw-r--r--src/player/AVGNode.h45
-rw-r--r--src/player/AppleTrackpadInputDevice.cpp116
-rw-r--r--src/player/AppleTrackpadInputDevice.h85
-rw-r--r--src/player/AreaNode.cpp350
-rw-r--r--src/player/AreaNode.h132
-rw-r--r--src/player/Arg.cpp47
-rw-r--r--src/player/Arg.h119
-rw-r--r--src/player/ArgBase.cpp66
-rw-r--r--src/player/ArgBase.h65
-rw-r--r--src/player/ArgList.cpp278
-rw-r--r--src/player/ArgList.h84
-rw-r--r--src/player/BitmapManager.cpp147
-rw-r--r--src/player/BitmapManager.h66
-rw-r--r--src/player/BitmapManagerMsg.cpp121
-rw-r--r--src/player/BitmapManagerMsg.h76
-rw-r--r--src/player/BitmapManagerThread.cpp78
-rw-r--r--src/player/BitmapManagerThread.h55
-rw-r--r--src/player/BlurFXNode.cpp79
-rw-r--r--src/player/BlurFXNode.h58
-rw-r--r--src/player/BoostPython.h35
-rw-r--r--src/player/CameraNode.cpp414
-rw-r--r--src/player/CameraNode.h135
-rw-r--r--src/player/Canvas.cpp325
-rw-r--r--src/player/Canvas.h124
-rw-r--r--src/player/CanvasNode.cpp67
-rw-r--r--src/player/CanvasNode.h48
-rw-r--r--src/player/ChromaKeyFXNode.cpp154
-rw-r--r--src/player/ChromaKeyFXNode.h77
-rw-r--r--src/player/CircleNode.cpp291
-rw-r--r--src/player/CircleNode.h77
-rw-r--r--src/player/Contact.cpp239
-rw-r--r--src/player/Contact.h96
-rw-r--r--src/player/CursorEvent.cpp136
-rw-r--r--src/player/CursorEvent.h87
-rw-r--r--src/player/CursorState.cpp58
-rw-r--r--src/player/CursorState.h56
-rw-r--r--src/player/CurveNode.cpp183
-rw-r--r--src/player/CurveNode.h80
-rw-r--r--src/player/DisplayEngine.cpp187
-rw-r--r--src/player/DisplayEngine.h93
-rw-r--r--src/player/DisplayParams.cpp64
-rw-r--r--src/player/DisplayParams.h52
-rw-r--r--src/player/DivNode.cpp392
-rw-r--r--src/player/DivNode.h94
-rw-r--r--src/player/Event.cpp139
-rw-r--r--src/player/Event.h99
-rw-r--r--src/player/EventDispatcher.cpp184
-rw-r--r--src/player/EventDispatcher.h68
-rw-r--r--src/player/ExportedObject.cpp105
-rw-r--r--src/player/ExportedObject.h73
-rw-r--r--src/player/FXNode.cpp117
-rw-r--r--src/player/FXNode.h71
-rw-r--r--src/player/FilledVectorNode.cpp215
-rw-r--r--src/player/FilledVectorNode.h88
-rw-r--r--src/player/FontStyle.cpp315
-rw-r--r--src/player/FontStyle.h114
-rw-r--r--src/player/HueSatFXNode.cpp153
-rw-r--r--src/player/HueSatFXNode.h72
-rw-r--r--src/player/IBitmapLoadedListener.h44
-rw-r--r--src/player/IInputDevice.h82
-rw-r--r--src/player/Image.cpp399
-rw-r--r--src/player/Image.h97
-rw-r--r--src/player/ImageNode.cpp241
-rw-r--r--src/player/ImageNode.h76
-rw-r--r--src/player/InvertFXNode.cpp67
-rw-r--r--src/player/InvertFXNode.h57
-rw-r--r--src/player/KeyEvent.cpp80
-rw-r--r--src/player/KeyEvent.h335
-rw-r--r--src/player/LibMTDevInputDevice.cpp190
-rw-r--r--src/player/LibMTDevInputDevice.h73
-rw-r--r--src/player/LineNode.cpp106
-rw-r--r--src/player/LineNode.h64
-rw-r--r--src/player/MainCanvas.cpp87
-rw-r--r--src/player/MainCanvas.h51
-rw-r--r--src/player/Makefile.am121
-rw-r--r--src/player/MaterialInfo.cpp53
-rw-r--r--src/player/MaterialInfo.h47
-rw-r--r--src/player/MeshNode.cpp164
-rw-r--r--src/player/MeshNode.h71
-rw-r--r--src/player/MessageID.cpp62
-rw-r--r--src/player/MessageID.h48
-rw-r--r--src/player/MouseEvent.cpp89
-rw-r--r--src/player/MouseEvent.h66
-rw-r--r--src/player/MultitouchInputDevice.cpp136
-rw-r--r--src/player/MultitouchInputDevice.h79
-rw-r--r--src/player/Node.cpp624
-rw-r--r--src/player/Node.h195
-rw-r--r--src/player/NullFXNode.cpp61
-rw-r--r--src/player/NullFXNode.h53
-rw-r--r--src/player/OGLSurface.cpp262
-rw-r--r--src/player/OGLSurface.h93
-rw-r--r--src/player/OffscreenCanvas.cpp271
-rw-r--r--src/player/OffscreenCanvas.h91
-rw-r--r--src/player/OffscreenCanvasNode.cpp83
-rw-r--r--src/player/OffscreenCanvasNode.h57
-rw-r--r--src/player/Player.cpp1835
-rw-r--r--src/player/Player.h299
-rw-r--r--src/player/PluginManager.cpp187
-rw-r--r--src/player/PluginManager.h76
-rw-r--r--src/player/PolyLineNode.cpp118
-rw-r--r--src/player/PolyLineNode.h65
-rw-r--r--src/player/PolygonNode.cpp219
-rw-r--r--src/player/PolygonNode.h74
-rw-r--r--src/player/Publisher.cpp248
-rw-r--r--src/player/Publisher.h113
-rw-r--r--src/player/PublisherDefinition.cpp90
-rw-r--r--src/player/PublisherDefinition.h62
-rw-r--r--src/player/PublisherDefinitionRegistry.cpp90
-rw-r--r--src/player/PublisherDefinitionRegistry.h63
-rw-r--r--src/player/PythonLogSink.cpp90
-rw-r--r--src/player/PythonLogSink.h46
-rw-r--r--src/player/RasterNode.cpp599
-rw-r--r--src/player/RasterNode.h159
-rw-r--r--src/player/RectNode.cpp178
-rw-r--r--src/player/RectNode.h69
-rw-r--r--src/player/SDLDisplayEngine.cpp865
-rw-r--r--src/player/SDLDisplayEngine.h109
-rw-r--r--src/player/SDLMain.h14
-rw-r--r--src/player/SDLMain.m32
-rw-r--r--src/player/SVG.cpp180
-rw-r--r--src/player/SVG.h78
-rw-r--r--src/player/SVGElement.cpp116
-rw-r--r--src/player/SVGElement.h62
-rw-r--r--src/player/ShadowFXNode.cpp122
-rw-r--r--src/player/ShadowFXNode.h72
-rw-r--r--src/player/Shape.cpp129
-rw-r--r--src/player/Shape.h70
-rw-r--r--src/player/SoundNode.cpp354
-rw-r--r--src/player/SoundNode.h100
-rw-r--r--src/player/SubscriberInfo.cpp85
-rw-r--r--src/player/SubscriberInfo.h58
-rw-r--r--src/player/TUIOInputDevice.cpp216
-rw-r--r--src/player/TUIOInputDevice.h80
-rw-r--r--src/player/TestHelper.cpp152
-rw-r--r--src/player/TestHelper.h76
-rw-r--r--src/player/TextEngine.cpp313
-rw-r--r--src/player/TextEngine.h76
-rw-r--r--src/player/Timeout.cpp93
-rw-r--r--src/player/Timeout.h54
-rw-r--r--src/player/TouchEvent.cpp202
-rw-r--r--src/player/TouchEvent.h87
-rw-r--r--src/player/TouchStatus.cpp109
-rw-r--r--src/player/TouchStatus.h59
-rw-r--r--src/player/TrackerCalibrator.cpp236
-rw-r--r--src/player/TrackerCalibrator.h75
-rw-r--r--src/player/TrackerInputDevice.cpp493
-rw-r--r--src/player/TrackerInputDevice.h122
-rw-r--r--src/player/TrackerTouchStatus.cpp120
-rw-r--r--src/player/TrackerTouchStatus.h70
-rw-r--r--src/player/TypeDefinition.cpp130
-rw-r--r--src/player/TypeDefinition.h75
-rw-r--r--src/player/TypeRegistry.cpp159
-rw-r--r--src/player/TypeRegistry.h65
-rw-r--r--src/player/VectorNode.cpp524
-rw-r--r--src/player/VectorNode.h120
-rw-r--r--src/player/VersionInfo.cpp72
-rw-r--r--src/player/VersionInfo.h47
-rw-r--r--src/player/VideoNode.cpp812
-rw-r--r--src/player/VideoNode.h157
-rw-r--r--src/player/VideoWriter.cpp260
-rw-r--r--src/player/VideoWriter.h99
-rw-r--r--src/player/VideoWriterThread.cpp347
-rw-r--r--src/player/VideoWriterThread.h83
-rw-r--r--src/player/Win7TouchInputDevice.cpp186
-rw-r--r--src/player/Win7TouchInputDevice.h69
-rw-r--r--src/player/WordsNode.cpp816
-rw-r--r--src/player/WordsNode.h158
-rw-r--r--src/player/WrapPython.cpp72
-rw-r--r--src/player/WrapPython.h70
-rw-r--r--src/player/XInputMTInputDevice.cpp379
-rw-r--r--src/player/XInputMTInputDevice.h77
-rw-r--r--src/player/testcalibrator.cpp120
-rw-r--r--src/player/testplayer.cpp101
-rw-r--r--src/python/Makefile.am6
-rw-r--r--src/python/__init__.py29
-rw-r--r--src/python/app/Makefile.am3
-rw-r--r--src/python/app/__init__.py29
-rw-r--r--src/python/app/app.py385
-rw-r--r--src/python/app/debugpanel.py697
-rw-r--r--src/python/app/flashmessage.py98
-rw-r--r--src/python/app/keyboardmanager.py204
-rw-r--r--src/python/app/settings.py277
-rw-r--r--src/python/app/touchvisualization.py188
-rw-r--r--src/python/apphelpers.py235
-rw-r--r--src/python/appstarter.py396
-rw-r--r--src/python/avgapp.py142
-rw-r--r--src/python/camcalibrator.py469
-rw-r--r--src/python/coordcalibrator.py133
-rw-r--r--src/python/data/CamImgBorder.pngbin0 -> 3031 bytes
-rw-r--r--src/python/data/Feedback.pngbin0 -> 196 bytes
-rw-r--r--src/python/data/Makefile.am4
-rw-r--r--src/python/data/SimpleSkin.xml83
-rw-r--r--src/python/data/TouchFeedback.pngbin0 -> 4494 bytes
-rw-r--r--src/python/data/black.pngbin0 -> 142 bytes
-rw-r--r--src/python/data/border.pngbin0 -> 8074 bytes
-rw-r--r--src/python/data/button_bg_down.pngbin0 -> 4089 bytes
-rw-r--r--src/python/data/button_bg_up.pngbin0 -> 3995 bytes
-rw-r--r--src/python/data/checkbox_checked_disabled.pngbin0 -> 2908 bytes
-rw-r--r--src/python/data/checkbox_checked_down.pngbin0 -> 2902 bytes
-rw-r--r--src/python/data/checkbox_checked_up.pngbin0 -> 2902 bytes
-rw-r--r--src/python/data/checkbox_unchecked_disabled.pngbin0 -> 2856 bytes
-rw-r--r--src/python/data/checkbox_unchecked_down.pngbin0 -> 2849 bytes
-rw-r--r--src/python/data/checkbox_unchecked_up.pngbin0 -> 2849 bytes
-rw-r--r--src/python/data/crosshair.pngbin0 -> 189 bytes
-rw-r--r--src/python/data/mpeg1-48x48-sound.avibin0 -> 28534 bytes
-rw-r--r--src/python/data/mpeg1-48x48.movbin0 -> 9863 bytes
-rw-r--r--src/python/data/pause_button_down.pngbin0 -> 2826 bytes
-rw-r--r--src/python/data/pause_button_up.pngbin0 -> 2825 bytes
-rw-r--r--src/python/data/play_button_down.pngbin0 -> 2927 bytes
-rw-r--r--src/python/data/play_button_up.pngbin0 -> 2928 bytes
-rw-r--r--src/python/data/rgb24alpha-64x64.pngbin0 -> 3392 bytes
-rw-r--r--src/python/data/scrollarea_border.pngbin0 -> 3262 bytes
-rw-r--r--src/python/data/scrollbar_horiz_thumb_down.pngbin0 -> 2990 bytes
-rw-r--r--src/python/data/scrollbar_horiz_thumb_up.pngbin0 -> 2977 bytes
-rw-r--r--src/python/data/scrollbar_horiz_track.pngbin0 -> 2874 bytes
-rw-r--r--src/python/data/scrollbar_horiz_track_disabled.pngbin0 -> 2873 bytes
-rw-r--r--src/python/data/scrollbar_vert_thumb_down.pngbin0 -> 3008 bytes
-rw-r--r--src/python/data/scrollbar_vert_thumb_up.pngbin0 -> 2998 bytes
-rw-r--r--src/python/data/scrollbar_vert_track.pngbin0 -> 2903 bytes
-rw-r--r--src/python/data/scrollbar_vert_track_disabled.pngbin0 -> 2902 bytes
-rw-r--r--src/python/data/skin.xsd137
-rw-r--r--src/python/data/slider_horiz_track.pngbin0 -> 2858 bytes
-rw-r--r--src/python/data/slider_horiz_track_disabled.pngbin0 -> 2859 bytes
-rw-r--r--src/python/data/slider_thumb_down.pngbin0 -> 3200 bytes
-rw-r--r--src/python/data/slider_thumb_up.pngbin0 -> 3225 bytes
-rw-r--r--src/python/data/slider_vert_track.pngbin0 -> 2867 bytes
-rw-r--r--src/python/data/slider_vert_track_disabled.pngbin0 -> 2866 bytes
-rw-r--r--src/python/enumcompat.py37
-rw-r--r--src/python/filter.py95
-rw-r--r--src/python/geom.py202
-rw-r--r--src/python/gesture.py1000
-rw-r--r--src/python/graph.py229
-rw-r--r--src/python/mathutil.py168
-rw-r--r--src/python/methodref.py69
-rw-r--r--src/python/mtemu.py166
-rw-r--r--src/python/parsecamargs.py49
-rw-r--r--src/python/persist.py157
-rw-r--r--src/python/statemachine.py149
-rw-r--r--src/python/textarea.py833
-rw-r--r--src/python/utils.py63
-rw-r--r--src/python/widget/Makefile.am3
-rw-r--r--src/python/widget/__init__.py7
-rw-r--r--src/python/widget/base.py267
-rw-r--r--src/python/widget/button.py443
-rw-r--r--src/python/widget/keyboard.py302
-rw-r--r--src/python/widget/mediacontrol.py161
-rw-r--r--src/python/widget/scrollarea.py240
-rw-r--r--src/python/widget/skin.py161
-rw-r--r--src/python/widget/slider.py371
-rw-r--r--src/samples/Makefile.am5
-rwxr-xr-xsrc/samples/abort_gestures.py114
-rwxr-xr-xsrc/samples/anim1.py17
-rwxr-xr-xsrc/samples/anim2.py19
-rwxr-xr-xsrc/samples/app_complete.py58
-rwxr-xr-xsrc/samples/app_minimal.py17
-rwxr-xr-xsrc/samples/asyncload.py89
-rwxr-xr-xsrc/samples/attributes.py11
-rwxr-xr-xsrc/samples/canvas.py14
-rwxr-xr-xsrc/samples/drag.py36
-rwxr-xr-xsrc/samples/event1.py20
-rwxr-xr-xsrc/samples/event2.py21
-rw-r--r--src/samples/firebirds/LICENSE6
-rw-r--r--src/samples/firebirds/Makefile.am3
-rwxr-xr-xsrc/samples/firebirds/firebirds.py469
-rw-r--r--src/samples/firebirds/media/Fire_Birds.mp3bin0 -> 1824809 bytes
-rw-r--r--src/samples/firebirds/media/Makefile.am5
-rw-r--r--src/samples/firebirds/media/bullet.gifbin0 -> 188 bytes
-rw-r--r--src/samples/firebirds/media/bullet.movbin0 -> 37232 bytes
-rw-r--r--src/samples/firebirds/media/bulletSound.mp3bin0 -> 20062 bytes
-rw-r--r--src/samples/firebirds/media/enemy.gifbin0 -> 1123 bytes
-rw-r--r--src/samples/firebirds/media/enemy.movbin0 -> 603181 bytes
-rw-r--r--src/samples/firebirds/media/enemyDeath.mp3bin0 -> 63529 bytes
-rw-r--r--src/samples/firebirds/media/explosion.movbin0 -> 2218276 bytes
-rw-r--r--src/samples/firebirds/media/flySound.mp3bin0 -> 193097 bytes
-rw-r--r--src/samples/firebirds/media/ground.jpgbin0 -> 262162 bytes
-rw-r--r--src/samples/firebirds/media/gui_frame.pngbin0 -> 124453 bytes
-rw-r--r--src/samples/firebirds/media/gui_heatbar_bg.pngbin0 -> 12626 bytes
-rw-r--r--src/samples/firebirds/media/gui_heatbar_fg.pngbin0 -> 13937 bytes
-rw-r--r--src/samples/firebirds/media/gui_lives_bg.pngbin0 -> 3679 bytes
-rw-r--r--src/samples/firebirds/media/gui_lives_fg.pngbin0 -> 4655 bytes
-rw-r--r--src/samples/firebirds/media/gui_numbers.pngbin0 -> 12640 bytes
-rw-r--r--src/samples/firebirds/media/spitfire.gifbin0 -> 1109 bytes
-rw-r--r--src/samples/firebirds/media/spitfire.movbin0 -> 612657 bytes
-rw-r--r--src/samples/firebirds/plugin/CollisionDetector.cpp122
-rw-r--r--src/samples/firebirds/plugin/CollisionDetector.h28
-rw-r--r--src/samples/firebirds/plugin/Makefile.am16
-rw-r--r--src/samples/flashmessages.py58
-rwxr-xr-xsrc/samples/fontstyle.py23
-rwxr-xr-xsrc/samples/gestures.py287
-rwxr-xr-xsrc/samples/globalcoords.py9
-rwxr-xr-xsrc/samples/invertfx.py35
-rwxr-xr-xsrc/samples/localcoords.py10
-rwxr-xr-xsrc/samples/localcoordsrot.py11
-rwxr-xr-xsrc/samples/logsample.py55
-rwxr-xr-xsrc/samples/mesh.py13
-rwxr-xr-xsrc/samples/minimal.py9
-rw-r--r--src/samples/mpeg1-48x48-sound.avibin0 -> 28534 bytes
-rwxr-xr-xsrc/samples/plugin.py15
-rw-r--r--src/samples/rgb24-64x64.pngbin0 -> 2092 bytes
-rwxr-xr-xsrc/samples/rotcustompivot.py11
-rwxr-xr-xsrc/samples/rotdefaultpivot.py11
-rwxr-xr-xsrc/samples/showvideo.py14
-rwxr-xr-xsrc/samples/slideshow.py159
-rwxr-xr-xsrc/samples/subclass.py40
-rwxr-xr-xsrc/samples/timer.py16
-rwxr-xr-xsrc/samples/timer2.py17
-rwxr-xr-xsrc/samples/timer3.py19
-rwxr-xr-xsrc/samples/twovideos.py55
-rwxr-xr-xsrc/samples/video.py11
-rwxr-xr-xsrc/samples/videochooser.py87
-rwxr-xr-xsrc/samples/widget.py77
-rwxr-xr-xsrc/samples/wordspos.py15
-rw-r--r--src/test/AVGAppTest.py187
-rw-r--r--src/test/AVTest.py674
-rw-r--r--src/test/AnimTest.py512
-rw-r--r--src/test/AppTest.py299
-rw-r--r--src/test/DynamicsTest.py380
-rw-r--r--src/test/EventTest.py1086
-rw-r--r--src/test/FXTest.py483
-rw-r--r--src/test/GestureTest.py1048
-rw-r--r--src/test/ImageTest.py583
-rw-r--r--src/test/InputDeviceTest.py218
-rw-r--r--src/test/LoggerTest.py96
-rw-r--r--src/test/Makefile.am9
-rw-r--r--src/test/OffscreenTest.py472
-rw-r--r--src/test/PlayerTest.py853
-rw-r--r--src/test/PluginTest.py65
-rw-r--r--src/test/PythonTest.py239
-rwxr-xr-xsrc/test/Test.py150
-rw-r--r--src/test/VectorTest.py734
-rw-r--r--src/test/WidgetTest.py900
-rw-r--r--src/test/WordsTest.py701
-rw-r--r--src/test/baseline/test2VideosAtOnce1.pngbin0 -> 4250 bytes
-rw-r--r--src/test/baseline/testAVGFile.pngbin0 -> 5767 bytes
-rw-r--r--src/test/baseline/testAnim1.pngbin0 -> 6524 bytes
-rw-r--r--src/test/baseline/testAnim2.pngbin0 -> 5795 bytes
-rw-r--r--src/test/baseline/testAnim3.pngbin0 -> 6622 bytes
-rw-r--r--src/test/baseline/testArc1.pngbin0 -> 264 bytes
-rw-r--r--src/test/baseline/testArc2.pngbin0 -> 492 bytes
-rw-r--r--src/test/baseline/testBitmap1.pngbin0 -> 1257 bytes
-rw-r--r--src/test/baseline/testBitmap2.pngbin0 -> 2816 bytes
-rw-r--r--src/test/baseline/testBitmap3.pngbin0 -> 2918 bytes
-rw-r--r--src/test/baseline/testBitmap4.pngbin0 -> 3666 bytes
-rw-r--r--src/test/baseline/testBlend1.pngbin0 -> 24802 bytes
-rw-r--r--src/test/baseline/testBlend2.pngbin0 -> 23161 bytes
-rw-r--r--src/test/baseline/testBlurFX1.pngbin0 -> 2994 bytes
-rw-r--r--src/test/baseline/testBlurFX2.pngbin0 -> 6838 bytes
-rw-r--r--src/test/baseline/testBlurFX3.pngbin0 -> 2418 bytes
-rw-r--r--src/test/baseline/testButtonDisabled.pngbin0 -> 1561 bytes
-rw-r--r--src/test/baseline/testButtonDown.pngbin0 -> 1492 bytes
-rw-r--r--src/test/baseline/testButtonOver.pngbin0 -> 1399 bytes
-rw-r--r--src/test/baseline/testButtonUp.pngbin0 -> 1212 bytes
-rw-r--r--src/test/baseline/testCanvasAlpha.pngbin0 -> 3790 bytes
-rw-r--r--src/test/baseline/testCanvasBlendModes.pngbin0 -> 8527 bytes
-rw-r--r--src/test/baseline/testCanvasCrop.pngbin0 -> 1745 bytes
-rw-r--r--src/test/baseline/testCanvasDependencies1.pngbin0 -> 1022 bytes
-rw-r--r--src/test/baseline/testCanvasDependencies2.pngbin0 -> 2726 bytes
-rw-r--r--src/test/baseline/testCanvasMipmap.pngbin0 -> 893 bytes
-rw-r--r--src/test/baseline/testCanvasMultisample.pngbin0 -> 3472 bytes
-rw-r--r--src/test/baseline/testCanvasNullFX1.pngbin0 -> 2214 bytes
-rw-r--r--src/test/baseline/testCanvasNullFX2.pngbin0 -> 1995 bytes
-rw-r--r--src/test/baseline/testCanvasNullFX3.pngbin0 -> 1042 bytes
-rw-r--r--src/test/baseline/testCanvasResize.pngbin0 -> 1022 bytes
-rw-r--r--src/test/baseline/testCheckboxClickedDown.pngbin0 -> 1732 bytes
-rw-r--r--src/test/baseline/testCheckboxClickedOut.pngbin0 -> 1497 bytes
-rw-r--r--src/test/baseline/testCheckboxClickedOver.pngbin0 -> 1642 bytes
-rw-r--r--src/test/baseline/testCheckboxDown.pngbin0 -> 1492 bytes
-rw-r--r--src/test/baseline/testCheckboxOver.pngbin0 -> 1399 bytes
-rw-r--r--src/test/baseline/testCheckboxUp.pngbin0 -> 1212 bytes
-rw-r--r--src/test/baseline/testChromaKeyFX1.pngbin0 -> 2428 bytes
-rw-r--r--src/test/baseline/testChromaKeyFX2.pngbin0 -> 2230 bytes
-rw-r--r--src/test/baseline/testChromaKeyFX3.pngbin0 -> 2309 bytes
-rw-r--r--src/test/baseline/testChromaKeyFX4.pngbin0 -> 2186 bytes
-rw-r--r--src/test/baseline/testCircle1.pngbin0 -> 295 bytes
-rw-r--r--src/test/baseline/testCircle2.pngbin0 -> 414 bytes
-rw-r--r--src/test/baseline/testCircle3.pngbin0 -> 3350 bytes
-rw-r--r--src/test/baseline/testCircle4.pngbin0 -> 1620 bytes
-rw-r--r--src/test/baseline/testCircle5.pngbin0 -> 1821 bytes
-rw-r--r--src/test/baseline/testColorFX1.pngbin0 -> 2170 bytes
-rw-r--r--src/test/baseline/testColorFX2.pngbin0 -> 1166 bytes
-rw-r--r--src/test/baseline/testColorFX3.pngbin0 -> 1511 bytes
-rw-r--r--src/test/baseline/testColorFX4.pngbin0 -> 2103 bytes
-rw-r--r--src/test/baseline/testColorFX5.pngbin0 -> 2105 bytes
-rw-r--r--src/test/baseline/testColorFX6.pngbin0 -> 2082 bytes
-rw-r--r--src/test/baseline/testColorFX7.pngbin0 -> 3067 bytes
-rw-r--r--src/test/baseline/testComplexDiv1.pngbin0 -> 2404 bytes
-rw-r--r--src/test/baseline/testContAnim1.pngbin0 -> 6562 bytes
-rw-r--r--src/test/baseline/testContAnim2.pngbin0 -> 4908 bytes
-rw-r--r--src/test/baseline/testContAnim3.pngbin0 -> 4155 bytes
-rw-r--r--src/test/baseline/testContAnim4.pngbin0 -> 4553 bytes
-rw-r--r--src/test/baseline/testContinuousAnim1.pngbin0 -> 4723 bytes
-rw-r--r--src/test/baseline/testContinuousAnim2.pngbin0 -> 2548 bytes
-rw-r--r--src/test/baseline/testContrast1.pngbin0 -> 1640 bytes
-rw-r--r--src/test/baseline/testContrast2.pngbin0 -> 1385 bytes
-rw-r--r--src/test/baseline/testContrast3.pngbin0 -> 9533 bytes
-rw-r--r--src/test/baseline/testCropImage1.pngbin0 -> 1494 bytes
-rw-r--r--src/test/baseline/testCropImage10.pngbin0 -> 5718 bytes
-rw-r--r--src/test/baseline/testCropImage2.pngbin0 -> 1110 bytes
-rw-r--r--src/test/baseline/testCropImage3.pngbin0 -> 3572 bytes
-rw-r--r--src/test/baseline/testCropImage4.pngbin0 -> 3404 bytes
-rw-r--r--src/test/baseline/testCropImage5.pngbin0 -> 3389 bytes
-rw-r--r--src/test/baseline/testCropImage6.pngbin0 -> 7900 bytes
-rw-r--r--src/test/baseline/testCropImage7.pngbin0 -> 6616 bytes
-rw-r--r--src/test/baseline/testCropImage8.pngbin0 -> 5925 bytes
-rw-r--r--src/test/baseline/testCropImage9.pngbin0 -> 5823 bytes
-rw-r--r--src/test/baseline/testCropMovie1.pngbin0 -> 6265 bytes
-rw-r--r--src/test/baseline/testCropMovie10.pngbin0 -> 5754 bytes
-rw-r--r--src/test/baseline/testCropMovie2.pngbin0 -> 4527 bytes
-rw-r--r--src/test/baseline/testCropMovie3.pngbin0 -> 4102 bytes
-rw-r--r--src/test/baseline/testCropMovie4.pngbin0 -> 3482 bytes
-rw-r--r--src/test/baseline/testCropMovie5.pngbin0 -> 3350 bytes
-rw-r--r--src/test/baseline/testCropMovie6.pngbin0 -> 6430 bytes
-rw-r--r--src/test/baseline/testCropMovie7.pngbin0 -> 3948 bytes
-rw-r--r--src/test/baseline/testCropMovie8.pngbin0 -> 6345 bytes
-rw-r--r--src/test/baseline/testCropMovie9.pngbin0 -> 5786 bytes
-rw-r--r--src/test/baseline/testCurve1.pngbin0 -> 382 bytes
-rw-r--r--src/test/baseline/testCurve2.pngbin0 -> 552 bytes
-rw-r--r--src/test/baseline/testCurve3.pngbin0 -> 653 bytes
-rw-r--r--src/test/baseline/testCurve4.pngbin0 -> 829 bytes
-rw-r--r--src/test/baseline/testDivDynamics1.pngbin0 -> 2396 bytes
-rw-r--r--src/test/baseline/testDivDynamics2.pngbin0 -> 2620 bytes
-rw-r--r--src/test/baseline/testDivDynamics3.pngbin0 -> 2698 bytes
-rw-r--r--src/test/baseline/testDivDynamics4.pngbin0 -> 136 bytes
-rw-r--r--src/test/baseline/testDivDynamics5.pngbin0 -> 2396 bytes
-rw-r--r--src/test/baseline/testDraggable1.pngbin0 -> 5805 bytes
-rw-r--r--src/test/baseline/testDraggable2.pngbin0 -> 5765 bytes
-rw-r--r--src/test/baseline/testDynamicMediaDir1.pngbin0 -> 3302 bytes
-rw-r--r--src/test/baseline/testDynamicMediaDir2.pngbin0 -> 5141 bytes
-rw-r--r--src/test/baseline/testDynamicWords1.pngbin0 -> 390 bytes
-rw-r--r--src/test/baseline/testDynamicWords2.pngbin0 -> 1356 bytes
-rw-r--r--src/test/baseline/testDynamicWords3.pngbin0 -> 136 bytes
-rw-r--r--src/test/baseline/testDynamicWords4.pngbin0 -> 874 bytes
-rw-r--r--src/test/baseline/testEaseInOutAnim1.pngbin0 -> 4985 bytes
-rw-r--r--src/test/baseline/testEaseInOutAnim2.pngbin0 -> 5106 bytes
-rw-r--r--src/test/baseline/testEaseInOutAnim3.pngbin0 -> 5045 bytes
-rw-r--r--src/test/baseline/testEaseInOutAnimC1.pngbin0 -> 2513 bytes
-rw-r--r--src/test/baseline/testEaseInOutAnimC2.pngbin0 -> 2513 bytes
-rw-r--r--src/test/baseline/testEaseInOutAnimC3.pngbin0 -> 2481 bytes
-rw-r--r--src/test/baseline/testEaseInOutAnimC4.pngbin0 -> 2182 bytes
-rw-r--r--src/test/baseline/testEaseInOutAnimC5.pngbin0 -> 2481 bytes
-rw-r--r--src/test/baseline/testEaseInOutAnimC6.pngbin0 -> 2566 bytes
-rw-r--r--src/test/baseline/testEvents.pngbin0 -> 7493 bytes
-rw-r--r--src/test/baseline/testFXUpdateFX.pngbin0 -> 3452 bytes
-rw-r--r--src/test/baseline/testFXUpdateMaskPos.pngbin0 -> 2791 bytes
-rw-r--r--src/test/baseline/testFXUpdateMaskTex1.pngbin0 -> 1484 bytes
-rw-r--r--src/test/baseline/testFXUpdateMaskTex2.pngbin0 -> 2861 bytes
-rw-r--r--src/test/baseline/testFXUpdateTex.pngbin0 -> 2210 bytes
-rw-r--r--src/test/baseline/testFXUpdateVideo.pngbin0 -> 10424 bytes
-rw-r--r--src/test/baseline/testFadeIn1.pngbin0 -> 2161 bytes
-rw-r--r--src/test/baseline/testFadeIn2.pngbin0 -> 2304 bytes
-rw-r--r--src/test/baseline/testFadeIn3.pngbin0 -> 2473 bytes
-rw-r--r--src/test/baseline/testFadeOut1.pngbin0 -> 2161 bytes
-rw-r--r--src/test/baseline/testFadeOut2.pngbin0 -> 1886 bytes
-rw-r--r--src/test/baseline/testFadeOut3.pngbin0 -> 136 bytes
-rw-r--r--src/test/baseline/testFocusContext1.pngbin0 -> 3011 bytes
-rw-r--r--src/test/baseline/testFocusContext2.pngbin0 -> 3629 bytes
-rw-r--r--src/test/baseline/testFocusContext3.pngbin0 -> 4164 bytes
-rw-r--r--src/test/baseline/testFocusContext4.pngbin0 -> 2241 bytes
-rw-r--r--src/test/baseline/testFocusContext5.pngbin0 -> 1379 bytes
-rw-r--r--src/test/baseline/testFontDir.pngbin0 -> 1595 bytes
-rw-r--r--src/test/baseline/testFontStyle1.pngbin0 -> 1971 bytes
-rw-r--r--src/test/baseline/testFontStyle2.pngbin0 -> 2566 bytes
-rw-r--r--src/test/baseline/testGamma1.pngbin0 -> 2009 bytes
-rw-r--r--src/test/baseline/testGamma2.pngbin0 -> 2196 bytes
-rw-r--r--src/test/baseline/testHVStretchNode1.pngbin0 -> 339 bytes
-rw-r--r--src/test/baseline/testHVStretchNode2.pngbin0 -> 409 bytes
-rw-r--r--src/test/baseline/testHinting1.pngbin0 -> 2865 bytes
-rw-r--r--src/test/baseline/testHueSatFX1.pngbin0 -> 3456 bytes
-rw-r--r--src/test/baseline/testHueSatFX2.pngbin0 -> 3824 bytes
-rw-r--r--src/test/baseline/testHueSatFX3.pngbin0 -> 2641 bytes
-rw-r--r--src/test/baseline/testHueSatFX4.pngbin0 -> 3764 bytes
-rw-r--r--src/test/baseline/testHugeImage0.pngbin0 -> 3578 bytes
-rw-r--r--src/test/baseline/testHugeImage1.pngbin0 -> 3136 bytes
-rw-r--r--src/test/baseline/testI18NWords1.pngbin0 -> 2792 bytes
-rw-r--r--src/test/baseline/testI18NWords2.pngbin0 -> 3693 bytes
-rw-r--r--src/test/baseline/testI18NWords3.pngbin0 -> 3534 bytes
-rw-r--r--src/test/baseline/testImageNullFX1.pngbin0 -> 4153 bytes
-rw-r--r--src/test/baseline/testImageNullFX2.pngbin0 -> 4700 bytes
-rw-r--r--src/test/baseline/testImageNullFX3.pngbin0 -> 4174 bytes
-rw-r--r--src/test/baseline/testImgDynamics1.pngbin0 -> 2396 bytes
-rw-r--r--src/test/baseline/testImgDynamics2.pngbin0 -> 2620 bytes
-rw-r--r--src/test/baseline/testImgDynamics3.pngbin0 -> 2698 bytes
-rw-r--r--src/test/baseline/testImgDynamics4.pngbin0 -> 2858 bytes
-rw-r--r--src/test/baseline/testImgDynamics5.pngbin0 -> 2396 bytes
-rw-r--r--src/test/baseline/testImgHRef1.pngbin0 -> 2332 bytes
-rw-r--r--src/test/baseline/testImgHRef2.pngbin0 -> 2545 bytes
-rw-r--r--src/test/baseline/testImgHRef3.pngbin0 -> 3564 bytes
-rw-r--r--src/test/baseline/testImgMask1.pngbin0 -> 698 bytes
-rw-r--r--src/test/baseline/testImgMask2.pngbin0 -> 2333 bytes
-rw-r--r--src/test/baseline/testImgMask3.pngbin0 -> 2476 bytes
-rw-r--r--src/test/baseline/testImgMaskCanvas.pngbin0 -> 2081 bytes
-rw-r--r--src/test/baseline/testImgMaskPos.pngbin0 -> 867 bytes
-rw-r--r--src/test/baseline/testImgMaskSize1.pngbin0 -> 519 bytes
-rw-r--r--src/test/baseline/testImgMaskSize2.pngbin0 -> 849 bytes
-rw-r--r--src/test/baseline/testImgMaskSize3.pngbin0 -> 916 bytes
-rw-r--r--src/test/baseline/testImgPos1.pngbin0 -> 1182 bytes
-rw-r--r--src/test/baseline/testImgPos2.pngbin0 -> 1374 bytes
-rw-r--r--src/test/baseline/testImgSize1.pngbin0 -> 1055 bytes
-rw-r--r--src/test/baseline/testImgSize2.pngbin0 -> 1217 bytes
-rw-r--r--src/test/baseline/testImgWarp1.pngbin0 -> 1138 bytes
-rw-r--r--src/test/baseline/testImgWarp2.pngbin0 -> 2522 bytes
-rw-r--r--src/test/baseline/testInactiveVector1.pngbin0 -> 247 bytes
-rw-r--r--src/test/baseline/testInactiveVector2.pngbin0 -> 136 bytes
-rw-r--r--src/test/baseline/testIntAnim1.pngbin0 -> 2476 bytes
-rw-r--r--src/test/baseline/testIntAnim2.pngbin0 -> 2182 bytes
-rw-r--r--src/test/baseline/testIntensity1.pngbin0 -> 1620 bytes
-rw-r--r--src/test/baseline/testIntensity2.pngbin0 -> 1700 bytes
-rw-r--r--src/test/baseline/testIntensity3.pngbin0 -> 8629 bytes
-rw-r--r--src/test/baseline/testIntensity4.pngbin0 -> 3618 bytes
-rw-r--r--src/test/baseline/testInvertFX1.pngbin0 -> 619 bytes
-rw-r--r--src/test/baseline/testInvertFX2.pngbin0 -> 3674 bytes
-rw-r--r--src/test/baseline/testJustify.pngbin0 -> 2413 bytes
-rw-r--r--src/test/baseline/testLetterSpacing1.pngbin0 -> 1809 bytes
-rw-r--r--src/test/baseline/testLetterSpacing2.pngbin0 -> 1711 bytes
-rw-r--r--src/test/baseline/testLinearAnim1.pngbin0 -> 4985 bytes
-rw-r--r--src/test/baseline/testLinearAnim2.pngbin0 -> 5106 bytes
-rw-r--r--src/test/baseline/testLinearAnim3.pngbin0 -> 5106 bytes
-rw-r--r--src/test/baseline/testLinearAnimC1.pngbin0 -> 2513 bytes
-rw-r--r--src/test/baseline/testLinearAnimC2.pngbin0 -> 2469 bytes
-rw-r--r--src/test/baseline/testLinearAnimC3.pngbin0 -> 2508 bytes
-rw-r--r--src/test/baseline/testLinearAnimC4.pngbin0 -> 2182 bytes
-rw-r--r--src/test/baseline/testLinearAnimC5.pngbin0 -> 2508 bytes
-rw-r--r--src/test/baseline/testLinearAnimC6.pngbin0 -> 2500 bytes
-rw-r--r--src/test/baseline/testLinearAnimZeroDuration1.pngbin0 -> 5106 bytes
-rw-r--r--src/test/baseline/testLinearAnimZeroDuration2.pngbin0 -> 5784 bytes
-rw-r--r--src/test/baseline/testLinearAnimZeroDuration3.pngbin0 -> 5784 bytes
-rw-r--r--src/test/baseline/testLinearAnimZeroDurationC1.pngbin0 -> 2182 bytes
-rw-r--r--src/test/baseline/testLinearAnimZeroDurationC2.pngbin0 -> 5784 bytes
-rw-r--r--src/test/baseline/testLinearAnimZeroDurationC3.pngbin0 -> 5784 bytes
-rw-r--r--src/test/baseline/testMediaControl1.pngbin0 -> 1041 bytes
-rw-r--r--src/test/baseline/testMediaControl2.pngbin0 -> 1032 bytes
-rw-r--r--src/test/baseline/testMediaControl3.pngbin0 -> 1202 bytes
-rw-r--r--src/test/baseline/testMediaControl4.pngbin0 -> 1108 bytes
-rw-r--r--src/test/baseline/testMediaControl5.pngbin0 -> 930 bytes
-rw-r--r--src/test/baseline/testMediaDir1.pngbin0 -> 6900 bytes
-rw-r--r--src/test/baseline/testMediaDir2.pngbin0 -> 4961 bytes
-rw-r--r--src/test/baseline/testMesh1.pngbin0 -> 2390 bytes
-rw-r--r--src/test/baseline/testMesh2.pngbin0 -> 2103 bytes
-rw-r--r--src/test/baseline/testMesh3.pngbin0 -> 719 bytes
-rw-r--r--src/test/baseline/testMesh4.pngbin0 -> 1810 bytes
-rw-r--r--src/test/baseline/testMesh5.pngbin0 -> 2309 bytes
-rw-r--r--src/test/baseline/testMesh6.pngbin0 -> 136 bytes
-rw-r--r--src/test/baseline/testMesh7.pngbin0 -> 1481 bytes
-rw-r--r--src/test/baseline/testMesh8.pngbin0 -> 1870 bytes
-rw-r--r--src/test/baseline/testMipmap.pngbin0 -> 371 bytes
-rw-r--r--src/test/baseline/testMove1.pngbin0 -> 6514 bytes
-rw-r--r--src/test/baseline/testNodeInCanvasNullFX1.pngbin0 -> 2461 bytes
-rw-r--r--src/test/baseline/testOffscreen1.pngbin0 -> 2510 bytes
-rw-r--r--src/test/baseline/testOffscreen2.pngbin0 -> 136 bytes
-rw-r--r--src/test/baseline/testOffscreen3.pngbin0 -> 2464 bytes
-rw-r--r--src/test/baseline/testOffscreen4.pngbin0 -> 2510 bytes
-rw-r--r--src/test/baseline/testOffscreen5.pngbin0 -> 136 bytes
-rw-r--r--src/test/baseline/testOffscreenAutoRender1.pngbin0 -> 2510 bytes
-rw-r--r--src/test/baseline/testOffscreenAutoRender2.pngbin0 -> 2517 bytes
-rw-r--r--src/test/baseline/testOffscreenMultisampleScreenshot.pngbin0 -> 3713 bytes
-rw-r--r--src/test/baseline/testOffscreenScreenshot.pngbin0 -> 2792 bytes
-rw-r--r--src/test/baseline/testOpacity.pngbin0 -> 2457 bytes
-rw-r--r--src/test/baseline/testOutlines.pngbin0 -> 3282 bytes
-rw-r--r--src/test/baseline/testPanoDynamics1.pngbin0 -> 38510 bytes
-rw-r--r--src/test/baseline/testPanoDynamics2.pngbin0 -> 2858 bytes
-rw-r--r--src/test/baseline/testPanoDynamics3.pngbin0 -> 38564 bytes
-rw-r--r--src/test/baseline/testPanoImage.pngbin0 -> 37544 bytes
-rw-r--r--src/test/baseline/testPanoImagewNOP.pngbin0 -> 37544 bytes
-rw-r--r--src/test/baseline/testParaWords.pngbin0 -> 4290 bytes
-rw-r--r--src/test/baseline/testParallelAnimC1.pngbin0 -> 3283 bytes
-rw-r--r--src/test/baseline/testParallelAnimC2.pngbin0 -> 2586 bytes
-rw-r--r--src/test/baseline/testParallelAnimC3.pngbin0 -> 2519 bytes
-rw-r--r--src/test/baseline/testParallelAnims1.pngbin0 -> 5791 bytes
-rw-r--r--src/test/baseline/testParallelAnims2.pngbin0 -> 6139 bytes
-rw-r--r--src/test/baseline/testPieSlice1.pngbin0 -> 325 bytes
-rw-r--r--src/test/baseline/testPieSlice2.pngbin0 -> 800 bytes
-rw-r--r--src/test/baseline/testPieSlice3.pngbin0 -> 142 bytes
-rw-r--r--src/test/baseline/testPlayBeforeConnect.pngbin0 -> 3986 bytes
-rw-r--r--src/test/baseline/testPointAnim1.pngbin0 -> 2510 bytes
-rw-r--r--src/test/baseline/testPointAnim2.pngbin0 -> 2506 bytes
-rw-r--r--src/test/baseline/testPointAnim3.pngbin0 -> 2506 bytes
-rw-r--r--src/test/baseline/testPolyLine1.pngbin0 -> 432 bytes
-rw-r--r--src/test/baseline/testPolyLine2.pngbin0 -> 592 bytes
-rw-r--r--src/test/baseline/testPolyLine3.pngbin0 -> 558 bytes
-rw-r--r--src/test/baseline/testPolyLine4.pngbin0 -> 616 bytes
-rw-r--r--src/test/baseline/testPolyLine5.pngbin0 -> 558 bytes
-rw-r--r--src/test/baseline/testPolyLine6.pngbin0 -> 184 bytes
-rw-r--r--src/test/baseline/testPolygon1.pngbin0 -> 565 bytes
-rw-r--r--src/test/baseline/testPolygon2.pngbin0 -> 554 bytes
-rw-r--r--src/test/baseline/testPolygon3.pngbin0 -> 716 bytes
-rw-r--r--src/test/baseline/testPolygon4.pngbin0 -> 716 bytes
-rw-r--r--src/test/baseline/testPolygon5.pngbin0 -> 767 bytes
-rw-r--r--src/test/baseline/testPolygon6.pngbin0 -> 741 bytes
-rw-r--r--src/test/baseline/testPolygon7.pngbin0 -> 567 bytes
-rw-r--r--src/test/baseline/testPolygon8.pngbin0 -> 547 bytes
-rw-r--r--src/test/baseline/testPolygon9.pngbin0 -> 579 bytes
-rw-r--r--src/test/baseline/testPolygonHole1.pngbin0 -> 637 bytes
-rw-r--r--src/test/baseline/testPolygonHole2.pngbin0 -> 727 bytes
-rw-r--r--src/test/baseline/testPositioning.pngbin0 -> 3435 bytes
-rw-r--r--src/test/baseline/testProgressBar1.pngbin0 -> 318 bytes
-rw-r--r--src/test/baseline/testProgressBar2.pngbin0 -> 321 bytes
-rw-r--r--src/test/baseline/testProgressBar3.pngbin0 -> 303 bytes
-rw-r--r--src/test/baseline/testRawText1.pngbin0 -> 2771 bytes
-rw-r--r--src/test/baseline/testRawText2.pngbin0 -> 4481 bytes
-rw-r--r--src/test/baseline/testRawText3.pngbin0 -> 4222 bytes
-rw-r--r--src/test/baseline/testRawText4.pngbin0 -> 1946 bytes
-rw-r--r--src/test/baseline/testRect1.pngbin0 -> 212 bytes
-rw-r--r--src/test/baseline/testRect2.pngbin0 -> 196 bytes
-rw-r--r--src/test/baseline/testRect3.pngbin0 -> 235 bytes
-rw-r--r--src/test/baseline/testRect4.pngbin0 -> 321 bytes
-rw-r--r--src/test/baseline/testRenderPipeline.pngbin0 -> 3381 bytes
-rw-r--r--src/test/baseline/testRotate1.pngbin0 -> 4931 bytes
-rw-r--r--src/test/baseline/testRotate1a.pngbin0 -> 2369 bytes
-rw-r--r--src/test/baseline/testRotate1b.pngbin0 -> 2363 bytes
-rw-r--r--src/test/baseline/testRotate2.pngbin0 -> 980 bytes
-rw-r--r--src/test/baseline/testRotatePivot1.pngbin0 -> 4188 bytes
-rw-r--r--src/test/baseline/testRotatePivot2.pngbin0 -> 6048 bytes
-rw-r--r--src/test/baseline/testRotatePivot3.pngbin0 -> 4942 bytes
-rw-r--r--src/test/baseline/testRoundedRect1.pngbin0 -> 312 bytes
-rw-r--r--src/test/baseline/testRoundedRect2.pngbin0 -> 311 bytes
-rw-r--r--src/test/baseline/testRoundedRect3.pngbin0 -> 212 bytes
-rw-r--r--src/test/baseline/testRoundedRect4.pngbin0 -> 221 bytes
-rw-r--r--src/test/baseline/testRoundedRect5.pngbin0 -> 256 bytes
-rw-r--r--src/test/baseline/testRoundedRect6.pngbin0 -> 237 bytes
-rw-r--r--src/test/baseline/testScrollArea1.pngbin0 -> 741 bytes
-rw-r--r--src/test/baseline/testScrollArea2.pngbin0 -> 857 bytes
-rw-r--r--src/test/baseline/testScrollArea3.pngbin0 -> 745 bytes
-rw-r--r--src/test/baseline/testScrollBarHoriz1.pngbin0 -> 313 bytes
-rw-r--r--src/test/baseline/testScrollBarHoriz10.pngbin0 -> 319 bytes
-rw-r--r--src/test/baseline/testScrollBarHoriz11.pngbin0 -> 322 bytes
-rw-r--r--src/test/baseline/testScrollBarHoriz12.pngbin0 -> 314 bytes
-rw-r--r--src/test/baseline/testScrollBarHoriz2.pngbin0 -> 318 bytes
-rw-r--r--src/test/baseline/testScrollBarHoriz3.pngbin0 -> 315 bytes
-rw-r--r--src/test/baseline/testScrollBarHoriz4.pngbin0 -> 301 bytes
-rw-r--r--src/test/baseline/testScrollBarHoriz5.pngbin0 -> 327 bytes
-rw-r--r--src/test/baseline/testScrollBarHoriz6.pngbin0 -> 297 bytes
-rw-r--r--src/test/baseline/testScrollBarHoriz7.pngbin0 -> 331 bytes
-rw-r--r--src/test/baseline/testScrollBarHoriz8.pngbin0 -> 326 bytes
-rw-r--r--src/test/baseline/testScrollBarHoriz9.pngbin0 -> 331 bytes
-rw-r--r--src/test/baseline/testScrollBarVert1.pngbin0 -> 521 bytes
-rw-r--r--src/test/baseline/testScrollBarVert2.pngbin0 -> 523 bytes
-rw-r--r--src/test/baseline/testScrollBarVert3.pngbin0 -> 537 bytes
-rw-r--r--src/test/baseline/testScrollBarVert4.pngbin0 -> 520 bytes
-rw-r--r--src/test/baseline/testScrollBarVert5.pngbin0 -> 555 bytes
-rw-r--r--src/test/baseline/testScrollBarVert6.pngbin0 -> 500 bytes
-rw-r--r--src/test/baseline/testScrollBarVert7.pngbin0 -> 517 bytes
-rw-r--r--src/test/baseline/testScrollBarVert8.pngbin0 -> 539 bytes
-rw-r--r--src/test/baseline/testScrollBarVert9.pngbin0 -> 525 bytes
-rw-r--r--src/test/baseline/testScrollPane1.pngbin0 -> 429 bytes
-rw-r--r--src/test/baseline/testScrollPane2.pngbin0 -> 1682 bytes
-rw-r--r--src/test/baseline/testScrollPane3.pngbin0 -> 998 bytes
-rw-r--r--src/test/baseline/testSeekAfterEOF.pngbin0 -> 4114 bytes
-rw-r--r--src/test/baseline/testShadowFX1.pngbin0 -> 2173 bytes
-rw-r--r--src/test/baseline/testShadowFX2.pngbin0 -> 2759 bytes
-rw-r--r--src/test/baseline/testShadowFX3.pngbin0 -> 1157 bytes
-rw-r--r--src/test/baseline/testShadowFX4.pngbin0 -> 1154 bytes
-rw-r--r--src/test/baseline/testShadowFX5.pngbin0 -> 2703 bytes
-rw-r--r--src/test/baseline/testShadowFX6.pngbin0 -> 805 bytes
-rw-r--r--src/test/baseline/testSimpleWords.pngbin0 -> 1955 bytes
-rw-r--r--src/test/baseline/testSliderHoriz1.pngbin0 -> 412 bytes
-rw-r--r--src/test/baseline/testSliderHoriz2.pngbin0 -> 424 bytes
-rw-r--r--src/test/baseline/testSliderHoriz3.pngbin0 -> 431 bytes
-rw-r--r--src/test/baseline/testSliderHoriz4.pngbin0 -> 390 bytes
-rw-r--r--src/test/baseline/testSliderHoriz5.pngbin0 -> 381 bytes
-rw-r--r--src/test/baseline/testSliderVert1.pngbin0 -> 578 bytes
-rw-r--r--src/test/baseline/testSliderVert2.pngbin0 -> 581 bytes
-rw-r--r--src/test/baseline/testSliderVert3.pngbin0 -> 578 bytes
-rw-r--r--src/test/baseline/testSliderVert4.pngbin0 -> 504 bytes
-rw-r--r--src/test/baseline/testSliderVert5.pngbin0 -> 502 bytes
-rw-r--r--src/test/baseline/testSpanWords.pngbin0 -> 2503 bytes
-rw-r--r--src/test/baseline/testSplineAnim1.pngbin0 -> 4985 bytes
-rw-r--r--src/test/baseline/testSplineAnim2.pngbin0 -> 5106 bytes
-rw-r--r--src/test/baseline/testSplineAnim3.pngbin0 -> 6171 bytes
-rw-r--r--src/test/baseline/testStateAnim1.pngbin0 -> 5765 bytes
-rw-r--r--src/test/baseline/testStateAnim2.pngbin0 -> 5320 bytes
-rw-r--r--src/test/baseline/testStateAnim3.pngbin0 -> 5320 bytes
-rw-r--r--src/test/baseline/testStateAnim4.pngbin0 -> 5765 bytes
-rw-r--r--src/test/baseline/testStateAnim5.pngbin0 -> 5320 bytes
-rw-r--r--src/test/baseline/testStateAnimC1.pngbin0 -> 2473 bytes
-rw-r--r--src/test/baseline/testStateAnimC2.pngbin0 -> 2506 bytes
-rw-r--r--src/test/baseline/testStateAnimC3.pngbin0 -> 2472 bytes
-rw-r--r--src/test/baseline/testStateAnimC4.pngbin0 -> 2506 bytes
-rw-r--r--src/test/baseline/testStateAnimC5.pngbin0 -> 2506 bytes
-rw-r--r--src/test/baseline/testStretchNodeHoriz1.pngbin0 -> 1098 bytes
-rw-r--r--src/test/baseline/testStretchNodeHoriz2.pngbin0 -> 1118 bytes
-rw-r--r--src/test/baseline/testStretchNodeVert1.pngbin0 -> 1091 bytes
-rw-r--r--src/test/baseline/testStretchNodeVert2.pngbin0 -> 1224 bytes
-rw-r--r--src/test/baseline/testSvgBmp.pngbin0 -> 157 bytes
-rw-r--r--src/test/baseline/testSvgNode.pngbin0 -> 222 bytes
-rw-r--r--src/test/baseline/testSvgPosBmp.pngbin0 -> 155 bytes
-rw-r--r--src/test/baseline/testSvgScaleBmp1.pngbin0 -> 347 bytes
-rw-r--r--src/test/baseline/testSvgScaleBmp2.pngbin0 -> 207 bytes
-rw-r--r--src/test/baseline/testSvgScaledNode1.pngbin0 -> 359 bytes
-rw-r--r--src/test/baseline/testSvgScaledNode2.pngbin0 -> 511 bytes
-rw-r--r--src/test/baseline/testTexCompression1.pngbin0 -> 2367 bytes
-rw-r--r--src/test/baseline/testTexCompression2.pngbin0 -> 810 bytes
-rw-r--r--src/test/baseline/testTextArea1.pngbin0 -> 2792 bytes
-rw-r--r--src/test/baseline/testTextArea2.pngbin0 -> 460 bytes
-rw-r--r--src/test/baseline/testTextArea3.pngbin0 -> 511 bytes
-rw-r--r--src/test/baseline/testTextArea4.pngbin0 -> 1056 bytes
-rw-r--r--src/test/baseline/testTextArea5.pngbin0 -> 1100 bytes
-rw-r--r--src/test/baseline/testTextButtonDisabled.pngbin0 -> 1099 bytes
-rw-r--r--src/test/baseline/testTextButtonDown.pngbin0 -> 975 bytes
-rw-r--r--src/test/baseline/testTextButtonDownNewText.pngbin0 -> 1438 bytes
-rw-r--r--src/test/baseline/testTextButtonUp.pngbin0 -> 1099 bytes
-rw-r--r--src/test/baseline/testTextButtonUpNewText.pngbin0 -> 1559 bytes
-rw-r--r--src/test/baseline/testTexturedCurve1.pngbin0 -> 3811 bytes
-rw-r--r--src/test/baseline/testTexturedCurve2.pngbin0 -> 4002 bytes
-rw-r--r--src/test/baseline/testTexturedPolyLine1.pngbin0 -> 2755 bytes
-rw-r--r--src/test/baseline/testTexturedPolyLine2.pngbin0 -> 2545 bytes
-rw-r--r--src/test/baseline/testTexturedPolyLine3.pngbin0 -> 3059 bytes
-rw-r--r--src/test/baseline/testTexturedPolyLine4.pngbin0 -> 2329 bytes
-rw-r--r--src/test/baseline/testTexturedPolygon1.pngbin0 -> 5278 bytes
-rw-r--r--src/test/baseline/testTexturedPolygon2.pngbin0 -> 4889 bytes
-rw-r--r--src/test/baseline/testTexturedPolygon3.pngbin0 -> 4985 bytes
-rw-r--r--src/test/baseline/testTexturedPolygon4.pngbin0 -> 5447 bytes
-rw-r--r--src/test/baseline/testTexturedPolygon5.pngbin0 -> 2624 bytes
-rw-r--r--src/test/baseline/testTexturedPolygon6.pngbin0 -> 2629 bytes
-rw-r--r--src/test/baseline/testTexturedRect1.pngbin0 -> 2487 bytes
-rw-r--r--src/test/baseline/testTexturedRect2.pngbin0 -> 2515 bytes
-rw-r--r--src/test/baseline/testTexturedRect3.pngbin0 -> 3933 bytes
-rw-r--r--src/test/baseline/testTexturedRect4.pngbin0 -> 1950 bytes
-rw-r--r--src/test/baseline/testTexturedRect5.pngbin0 -> 2008 bytes
-rw-r--r--src/test/baseline/testTexturedRect6.pngbin0 -> 1491 bytes
-rw-r--r--src/test/baseline/testTexturedRect7.pngbin0 -> 251 bytes
-rw-r--r--src/test/baseline/testTexturedRect8.pngbin0 -> 283 bytes
-rw-r--r--src/test/baseline/testTimeSliderHoriz1.pngbin0 -> 416 bytes
-rw-r--r--src/test/baseline/testTimeSliderHoriz2.pngbin0 -> 501 bytes
-rw-r--r--src/test/baseline/testTimeSliderHoriz3.pngbin0 -> 499 bytes
-rw-r--r--src/test/baseline/testTimeSliderHoriz4.pngbin0 -> 461 bytes
-rw-r--r--src/test/baseline/testTimeSliderHoriz5.pngbin0 -> 461 bytes
-rw-r--r--src/test/baseline/testTimeSliderVert1.pngbin0 -> 570 bytes
-rw-r--r--src/test/baseline/testTimeSliderVert2.pngbin0 -> 674 bytes
-rw-r--r--src/test/baseline/testTimeSliderVert3.pngbin0 -> 665 bytes
-rw-r--r--src/test/baseline/testTimeSliderVert4.pngbin0 -> 591 bytes
-rw-r--r--src/test/baseline/testTimeSliderVert5.pngbin0 -> 591 bytes
-rw-r--r--src/test/baseline/testUIButtonDisabled.pngbin0 -> 1722 bytes
-rw-r--r--src/test/baseline/testUIButtonDown.pngbin0 -> 1657 bytes
-rw-r--r--src/test/baseline/testUIButtonUp.pngbin0 -> 1364 bytes
-rw-r--r--src/test/baseline/testUICheckBoxChecked_Down.pngbin0 -> 1506 bytes
-rw-r--r--src/test/baseline/testUICheckBoxChecked_Up.pngbin0 -> 1499 bytes
-rw-r--r--src/test/baseline/testUICheckBoxUnchecked_Disabled.pngbin0 -> 1440 bytes
-rw-r--r--src/test/baseline/testUICheckBoxUnchecked_Down.pngbin0 -> 1430 bytes
-rw-r--r--src/test/baseline/testUICheckBoxUnchecked_Up.pngbin0 -> 1471 bytes
-rw-r--r--src/test/baseline/testUIKeyboard.pngbin0 -> 859 bytes
-rw-r--r--src/test/baseline/testUIKeyboard1S.pngbin0 -> 911 bytes
-rw-r--r--src/test/baseline/testUIKeyboardA.pngbin0 -> 878 bytes
-rw-r--r--src/test/baseline/testUIKeyboardA1S.pngbin0 -> 885 bytes
-rw-r--r--src/test/baseline/testUIKeyboardAS.pngbin0 -> 883 bytes
-rw-r--r--src/test/baseline/testUIKeyboardDown11.pngbin0 -> 1979 bytes
-rw-r--r--src/test/baseline/testUIKeyboardDownA212S2.pngbin0 -> 2191 bytes
-rw-r--r--src/test/baseline/testUIKeyboardDownA2S1.pngbin0 -> 1205 bytes
-rw-r--r--src/test/baseline/testUIKeyboardFB.pngbin0 -> 859 bytes
-rw-r--r--src/test/baseline/testUIKeyboardFB1.pngbin0 -> 1616 bytes
-rw-r--r--src/test/baseline/testUIKeyboardFBA1S.pngbin0 -> 1587 bytes
-rw-r--r--src/test/baseline/testUIKeyboardFBAS.pngbin0 -> 2065 bytes
-rw-r--r--src/test/baseline/testUIKeyboardFBS.pngbin0 -> 854 bytes
-rw-r--r--src/test/baseline/testUIKeyboardNoFB1S.pngbin0 -> 910 bytes
-rw-r--r--src/test/baseline/testUIKeyboardS.pngbin0 -> 855 bytes
-rw-r--r--src/test/baseline/testUIToggleChecked_Disabled.pngbin0 -> 1276 bytes
-rw-r--r--src/test/baseline/testUIToggleChecked_Down.pngbin0 -> 1458 bytes
-rw-r--r--src/test/baseline/testUIToggleChecked_Up.pngbin0 -> 1450 bytes
-rw-r--r--src/test/baseline/testUIToggleUnchecked_Disabled.pngbin0 -> 959 bytes
-rw-r--r--src/test/baseline/testUIToggleUnchecked_Down.pngbin0 -> 1113 bytes
-rw-r--r--src/test/baseline/testUIToggleUnchecked_Up.pngbin0 -> 1115 bytes
-rw-r--r--src/test/baseline/testVideo-h264-48x48.h2641.pngbin0 -> 9756 bytes
-rw-r--r--src/test/baseline/testVideo-mjpeg-48x48.avi1.pngbin0 -> 13061 bytes
-rw-r--r--src/test/baseline/testVideo-mpeg1-48x48-sound.avi1.pngbin0 -> 10948 bytes
-rw-r--r--src/test/baseline/testVideo-mpeg1-48x48.mov1.pngbin0 -> 10904 bytes
-rw-r--r--src/test/baseline/testVideo-rgba-48x48.mov1.pngbin0 -> 6434 bytes
-rw-r--r--src/test/baseline/testVideo-vp6a-yuva-48x48.flv1.pngbin0 -> 10033 bytes
-rw-r--r--src/test/baseline/testVideoActive1.pngbin0 -> 136 bytes
-rw-r--r--src/test/baseline/testVideoActive2.pngbin0 -> 10508 bytes
-rw-r--r--src/test/baseline/testVideoDynamics1.pngbin0 -> 4236 bytes
-rw-r--r--src/test/baseline/testVideoDynamics2.pngbin0 -> 5735 bytes
-rw-r--r--src/test/baseline/testVideoDynamics3.pngbin0 -> 5598 bytes
-rw-r--r--src/test/baseline/testVideoDynamics4.pngbin0 -> 136 bytes
-rw-r--r--src/test/baseline/testVideoDynamics5.pngbin0 -> 4236 bytes
-rw-r--r--src/test/baseline/testVideoFPS.pngbin0 -> 3215 bytes
-rw-r--r--src/test/baseline/testVideoHRef1.pngbin0 -> 3531 bytes
-rw-r--r--src/test/baseline/testVideoLoop.pngbin0 -> 10904 bytes
-rw-r--r--src/test/baseline/testVideoMaskRGBA1.pngbin0 -> 804 bytes
-rw-r--r--src/test/baseline/testVideoMaskRGBA2.pngbin0 -> 2147 bytes
-rw-r--r--src/test/baseline/testVideoMaskRGBA3.pngbin0 -> 2619 bytes
-rw-r--r--src/test/baseline/testVideoMaskRGBA4.pngbin0 -> 2194 bytes
-rw-r--r--src/test/baseline/testVideoMaskYUV1.pngbin0 -> 1499 bytes
-rw-r--r--src/test/baseline/testVideoMaskYUV2.pngbin0 -> 4117 bytes
-rw-r--r--src/test/baseline/testVideoMaskYUV3.pngbin0 -> 3861 bytes
-rw-r--r--src/test/baseline/testVideoMaskYUV4.pngbin0 -> 3115 bytes
-rw-r--r--src/test/baseline/testVideoMaskYUVJ1.pngbin0 -> 1804 bytes
-rw-r--r--src/test/baseline/testVideoMaskYUVJ2.pngbin0 -> 417 bytes
-rw-r--r--src/test/baseline/testVideoMaskYUVJ3.pngbin0 -> 1524 bytes
-rw-r--r--src/test/baseline/testVideoMaskYUVJ4.pngbin0 -> 1092 bytes
-rw-r--r--src/test/baseline/testVideoNullFX.pngbin0 -> 4769 bytes
-rw-r--r--src/test/baseline/testVideoOpacityRGBA1.pngbin0 -> 2215 bytes
-rw-r--r--src/test/baseline/testVideoOpacityRGBA2.pngbin0 -> 2245 bytes
-rw-r--r--src/test/baseline/testVideoOpacityYUV1.pngbin0 -> 3986 bytes
-rw-r--r--src/test/baseline/testVideoOpacityYUV2.pngbin0 -> 3976 bytes
-rw-r--r--src/test/baseline/testVideoSeek0.pngbin0 -> 11091 bytes
-rw-r--r--src/test/baseline/testVideoSeek1.pngbin0 -> 11683 bytes
-rw-r--r--src/test/baseline/testVideoSeek2.pngbin0 -> 11139 bytes
-rw-r--r--src/test/baseline/testVideoSeek3.pngbin0 -> 851 bytes
-rw-r--r--src/test/baseline/testVideoState1.pngbin0 -> 10904 bytes
-rw-r--r--src/test/baseline/testVideoState2.pngbin0 -> 10424 bytes
-rw-r--r--src/test/baseline/testVideoState3.pngbin0 -> 10561 bytes
-rw-r--r--src/test/baseline/testVideoState4.pngbin0 -> 136 bytes
-rw-r--r--src/test/baseline/testVideoState5.pngbin0 -> 10904 bytes
-rw-r--r--src/test/baseline/testVideoWriter1.pngbin0 -> 4659 bytes
-rw-r--r--src/test/baseline/testVideoWriterCanvas1.pngbin0 -> 3935 bytes
-rw-r--r--src/test/baseline/testWarp1.pngbin0 -> 8512 bytes
-rw-r--r--src/test/baseline/testWarp2.pngbin0 -> 8401 bytes
-rw-r--r--src/test/baseline/testWarp3.pngbin0 -> 8451 bytes
-rw-r--r--src/test/baseline/testWordsBR.pngbin0 -> 1170 bytes
-rw-r--r--src/test/baseline/testWordsDynamics1.pngbin0 -> 513 bytes
-rw-r--r--src/test/baseline/testWordsDynamics2.pngbin0 -> 552 bytes
-rw-r--r--src/test/baseline/testWordsDynamics3.pngbin0 -> 552 bytes
-rw-r--r--src/test/baseline/testWordsDynamics4.pngbin0 -> 136 bytes
-rw-r--r--src/test/baseline/testWordsDynamics5.pngbin0 -> 513 bytes
-rw-r--r--src/test/baseline/testWordsGamma1.pngbin0 -> 3194 bytes
-rw-r--r--src/test/baseline/testWordsGamma2.pngbin0 -> 3174 bytes
-rw-r--r--src/test/baseline/testWordsIntensity.pngbin0 -> 2239 bytes
-rw-r--r--src/test/baseline/testWordsMask1.pngbin0 -> 4057 bytes
-rw-r--r--src/test/baseline/testWordsMask2.pngbin0 -> 3471 bytes
-rw-r--r--src/test/baseline/testWordsMask3.pngbin0 -> 3420 bytes
-rw-r--r--src/test/baseline/testWordsMask4.pngbin0 -> 4055 bytes
-rw-r--r--src/test/baseline/testWordsMask5.pngbin0 -> 4129 bytes
-rw-r--r--src/test/baseline/testWordsMask6.pngbin0 -> 3854 bytes
-rw-r--r--src/test/baseline/testWordsMask7.pngbin0 -> 3853 bytes
-rw-r--r--src/test/baseline/testWordsNullFX.pngbin0 -> 949 bytes
-rw-r--r--src/test/baseline/testWordsOutlines.pngbin0 -> 1024 bytes
-rw-r--r--src/test/baseline/testWordsShadowFX1.pngbin0 -> 2034 bytes
-rw-r--r--src/test/baseline/testWordsShadowFX2.pngbin0 -> 2228 bytes
-rw-r--r--src/test/baseline/testWrapMode1.pngbin0 -> 2901 bytes
-rw-r--r--src/test/baseline/testWrapMode2.pngbin0 -> 3698 bytes
-rw-r--r--src/test/baseline/testWrapMode3.pngbin0 -> 2901 bytes
-rw-r--r--src/test/baseline/testWrapMode4.pngbin0 -> 3927 bytes
-rw-r--r--src/test/baseline/testXPosPointAnim1.pngbin0 -> 5123 bytes
-rw-r--r--src/test/baseline/testXPosPointAnim2.pngbin0 -> 5106 bytes
-rw-r--r--src/test/baseline/testXPosPointAnim3.pngbin0 -> 5106 bytes
-rw-r--r--src/test/baseline/testYPosPointAnim1.pngbin0 -> 5123 bytes
-rw-r--r--src/test/baseline/testYPosPointAnim2.pngbin0 -> 5127 bytes
-rw-r--r--src/test/baseline/testYPosPointAnim3.pngbin0 -> 5127 bytes
-rw-r--r--src/test/baseline/testbasics.pngbin0 -> 2510 bytes
-rw-r--r--src/test/baseline/testline1.pngbin0 -> 348 bytes
-rw-r--r--src/test/baseline/testline2.pngbin0 -> 351 bytes
-rw-r--r--src/test/baseline/testline3.pngbin0 -> 364 bytes
-rw-r--r--src/test/baseline/testline4.pngbin0 -> 385 bytes
-rw-r--r--src/test/baseline/testlineopacity1.pngbin0 -> 154 bytes
-rw-r--r--src/test/baseline/testlineopacity2.pngbin0 -> 156 bytes
-rw-r--r--src/test/baseline/testlotsoflines.pngbin0 -> 369 bytes
-rw-r--r--src/test/baseline/testplugin1.pngbin0 -> 371 bytes
-rw-r--r--src/test/baseline/testplugin2.pngbin0 -> 375 bytes
-rw-r--r--src/test/baseline/testtexturedline1.pngbin0 -> 1854 bytes
-rw-r--r--src/test/baseline/testtexturedline2.pngbin0 -> 136 bytes
-rw-r--r--src/test/baseline/testtexturedline3.pngbin0 -> 1371 bytes
-rw-r--r--src/test/baseline/testtexturedline4.pngbin0 -> 1837 bytes
-rw-r--r--src/test/baseline/testtexturedline5.pngbin0 -> 213 bytes
-rw-r--r--src/test/camcfgs.py133
-rwxr-xr-xsrc/test/checkcamera.py225
-rw-r--r--src/test/extrafonts/testaddfontdir.ttfbin0 -> 1736 bytes
-rw-r--r--src/test/fonts/Vera.ttfbin0 -> 65932 bytes
-rw-r--r--src/test/fonts/VeraBI.ttfbin0 -> 63208 bytes
-rw-r--r--src/test/fonts/VeraBd.ttfbin0 -> 58716 bytes
-rw-r--r--src/test/fonts/VeraIt.ttfbin0 -> 63684 bytes
-rw-r--r--src/test/illustratorRect.svg7
-rw-r--r--src/test/image.avg8
-rw-r--r--src/test/media/1x1_white.pngbin0 -> 2791 bytes
-rwxr-xr-xsrc/test/media/22.050Hz_16bit_mono.wavbin0 -> 4454 bytes
-rw-r--r--src/test/media/44.1kHz_16bit_6Chan.oggbin0 -> 159170 bytes
-rwxr-xr-xsrc/test/media/44.1kHz_16bit_mono.wavbin0 -> 8864 bytes
-rwxr-xr-xsrc/test/media/44.1kHz_16bit_stereo.aifbin0 -> 352854 bytes
-rwxr-xr-xsrc/test/media/44.1kHz_16bit_stereo.wavbin0 -> 352844 bytes
-rwxr-xr-xsrc/test/media/44.1kHz_24bit_mono.wavbin0 -> 8864 bytes
-rwxr-xr-xsrc/test/media/44.1kHz_24bit_stereo.aifbin0 -> 529254 bytes
-rwxr-xr-xsrc/test/media/44.1kHz_24bit_stereo.wavbin0 -> 352844 bytes
-rwxr-xr-xsrc/test/media/44.1kHz_mono.oggbin0 -> 4177 bytes
-rw-r--r--src/test/media/44.1kHz_stereo.mp3bin0 -> 47647 bytes
-rw-r--r--src/test/media/44.1kHz_stereo.oggbin0 -> 10211 bytes
-rwxr-xr-xsrc/test/media/48kHz_16bit_mono.wavbin0 -> 9644 bytes
-rwxr-xr-xsrc/test/media/48kHz_16bit_stereo.aifbin0 -> 384054 bytes
-rwxr-xr-xsrc/test/media/48kHz_16bit_stereo.wavbin0 -> 384044 bytes
-rwxr-xr-xsrc/test/media/48kHz_24bit_mono.wavbin0 -> 9644 bytes
-rwxr-xr-xsrc/test/media/48kHz_24bit_stereo.aifbin0 -> 576054 bytes
-rwxr-xr-xsrc/test/media/48kHz_24bit_stereo.wavbin0 -> 384044 bytes
-rw-r--r--src/test/media/48kHz_stereo.mp3bin0 -> 47808 bytes
-rw-r--r--src/test/media/48kHz_stereo.oggbin0 -> 104701 bytes
-rw-r--r--src/test/media/CustomSkin.xml83
-rw-r--r--src/test/media/SimpleSkin.xml83
-rw-r--r--src/test/media/button_bg_down.pngbin0 -> 3212 bytes
-rw-r--r--src/test/media/button_bg_up.pngbin0 -> 3085 bytes
-rw-r--r--src/test/media/button_check.pngbin0 -> 3040 bytes
-rw-r--r--src/test/media/button_disabled.pngbin0 -> 4308 bytes
-rw-r--r--src/test/media/button_down.pngbin0 -> 4221 bytes
-rw-r--r--src/test/media/button_over.pngbin0 -> 4131 bytes
-rw-r--r--src/test/media/button_up.pngbin0 -> 3923 bytes
-rw-r--r--src/test/media/checkbox_checked_disabled.pngbin0 -> 2908 bytes
-rw-r--r--src/test/media/checkbox_checked_down.pngbin0 -> 2902 bytes
-rw-r--r--src/test/media/checkbox_checked_up.pngbin0 -> 2902 bytes
-rw-r--r--src/test/media/checkbox_unchecked_disabled.pngbin0 -> 2856 bytes
-rw-r--r--src/test/media/checkbox_unchecked_down.pngbin0 -> 2849 bytes
-rw-r--r--src/test/media/checkbox_unchecked_up.pngbin0 -> 2849 bytes
-rw-r--r--src/test/media/checker.pngbin0 -> 3526 bytes
-rw-r--r--src/test/media/chromakey-median.pngbin0 -> 3331 bytes
-rw-r--r--src/test/media/chromakey.pngbin0 -> 2995 bytes
-rw-r--r--src/test/media/colorramp.pngbin0 -> 4471 bytes
-rw-r--r--src/test/media/crop_bkgd.pngbin0 -> 369 bytes
-rw-r--r--src/test/media/dilation.pngbin0 -> 80 bytes
-rw-r--r--src/test/media/erosion.pngbin0 -> 960 bytes
-rw-r--r--src/test/media/filterwipeborder.pngbin0 -> 1166 bytes
-rw-r--r--src/test/media/flat.pngbin0 -> 2861 bytes
-rw-r--r--src/test/media/floodfill.pngbin0 -> 119 bytes
-rw-r--r--src/test/media/freidrehen.jpgbin0 -> 3856 bytes
-rw-r--r--src/test/media/greyscale.pngbin0 -> 2245 bytes
-rw-r--r--src/test/media/h264-48x48.h264bin0 -> 131081 bytes
-rw-r--r--src/test/media/hsl.pngbin0 -> 3131 bytes
-rw-r--r--src/test/media/i8-64x64.pngbin0 -> 2256 bytes
-rw-r--r--src/test/media/incompleteSkinMedia/IncompleteSkin.xml11
-rw-r--r--src/test/media/incompleteSkinMedia/scrollbar_horiz_thumb_down.pngbin0 -> 2990 bytes
-rw-r--r--src/test/media/incompleteSkinMedia/scrollbar_horiz_thumb_up.pngbin0 -> 2948 bytes
-rw-r--r--src/test/media/incompleteSkinMedia/scrollbar_horiz_track.pngbin0 -> 2843 bytes
-rw-r--r--src/test/media/incompleteSkinMedia/scrollbar_horiz_track_disabled.pngbin0 -> 2873 bytes
-rw-r--r--src/test/media/keyboard_bg.pngbin0 -> 781 bytes
-rw-r--r--src/test/media/keyboard_down.pngbin0 -> 775 bytes
-rw-r--r--src/test/media/keyboard_feedback.pngbin0 -> 2711 bytes
-rw-r--r--src/test/media/mask.pngbin0 -> 1270 bytes
-rw-r--r--src/test/media/mask1.pngbin0 -> 227 bytes
-rw-r--r--src/test/media/mask2.pngbin0 -> 1598 bytes
-rw-r--r--src/test/media/mjpeg-48x48.avibin0 -> 329852 bytes
-rw-r--r--src/test/media/mpeg1-48x48-sound.avibin0 -> 28534 bytes
-rw-r--r--src/test/media/mpeg1-48x48.movbin0 -> 9863 bytes
-rw-r--r--src/test/media/oe.pngbin0 -> 3178 bytes
-rw-r--r--src/test/media/pause_button_down.pngbin0 -> 2826 bytes
-rw-r--r--src/test/media/pause_button_up.pngbin0 -> 2825 bytes
-rw-r--r--src/test/media/play_button_down.pngbin0 -> 2927 bytes
-rw-r--r--src/test/media/play_button_up.pngbin0 -> 2928 bytes
-rw-r--r--src/test/media/rect.svg8
-rw-r--r--src/test/media/rectborder.pngbin0 -> 2810 bytes
-rw-r--r--src/test/media/rgb24-32x32.pngbin0 -> 3584 bytes
-rw-r--r--src/test/media/rgb24-64x64.pngbin0 -> 2092 bytes
-rw-r--r--src/test/media/rgb24-65x65.pngbin0 -> 2210 bytes
-rw-r--r--src/test/media/rgb24alpha-32x32.pngbin0 -> 4088 bytes
-rw-r--r--src/test/media/rgb24alpha-64x64.pngbin0 -> 3392 bytes
-rw-r--r--src/test/media/rgba-48x48.movbin0 -> 127378 bytes
-rw-r--r--src/test/media/scrollarea_border.pngbin0 -> 3262 bytes
-rw-r--r--src/test/media/scrollbar_horiz_thumb_disabled.pngbin0 -> 2924 bytes
-rw-r--r--src/test/media/scrollbar_horiz_thumb_down.pngbin0 -> 2990 bytes
-rw-r--r--src/test/media/scrollbar_horiz_thumb_up.pngbin0 -> 2948 bytes
-rw-r--r--src/test/media/scrollbar_horiz_track.pngbin0 -> 2843 bytes
-rw-r--r--src/test/media/scrollbar_horiz_track_disabled.pngbin0 -> 2873 bytes
-rw-r--r--src/test/media/scrollbar_vert_thumb_disabled.pngbin0 -> 2911 bytes
-rw-r--r--src/test/media/scrollbar_vert_thumb_down.pngbin0 -> 3008 bytes
-rw-r--r--src/test/media/scrollbar_vert_thumb_up.pngbin0 -> 2998 bytes
-rw-r--r--src/test/media/scrollbar_vert_track.pngbin0 -> 2903 bytes
-rw-r--r--src/test/media/scrollbar_vert_track_disabled.pngbin0 -> 2902 bytes
-rw-r--r--src/test/media/shadow.pngbin0 -> 3168 bytes
-rw-r--r--src/test/media/slider_horiz_track.pngbin0 -> 2858 bytes
-rw-r--r--src/test/media/slider_horiz_track_disabled.pngbin0 -> 2859 bytes
-rw-r--r--src/test/media/slider_thumb_down.pngbin0 -> 3200 bytes
-rw-r--r--src/test/media/slider_thumb_up.pngbin0 -> 3225 bytes
-rw-r--r--src/test/media/slider_vert_track.pngbin0 -> 2867 bytes
-rw-r--r--src/test/media/slider_vert_track_disabled.pngbin0 -> 2866 bytes
-rw-r--r--src/test/media/spike.pngbin0 -> 2820 bytes
-rw-r--r--src/test/media/toggle_checked_Disabled.pngbin0 -> 3886 bytes
-rw-r--r--src/test/media/toggle_checked_Down.pngbin0 -> 3873 bytes
-rw-r--r--src/test/media/toggle_checked_Up.pngbin0 -> 3867 bytes
-rw-r--r--src/test/media/toggle_unchecked_Disabled.pngbin0 -> 3555 bytes
-rw-r--r--src/test/media/toggle_unchecked_Down.pngbin0 -> 3506 bytes
-rw-r--r--src/test/media/toggle_unchecked_Up.pngbin0 -> 3517 bytes
-rw-r--r--src/test/media/vp6a-yuva-48x48.flvbin0 -> 13669 bytes
-rw-r--r--src/test/media/widebmp.jpgbin0 -> 33903 bytes
-rw-r--r--src/test/plugin/ColorNode.cpp153
-rw-r--r--src/test/plugin/Makefile.am19
-rwxr-xr-xsrc/test/plugin/test.sh5
-rw-r--r--src/test/testapp.py191
-rw-r--r--src/test/testcase.py369
-rw-r--r--src/test/testmediadir/mjpeg-48x48.avibin0 -> 10240 bytes
-rw-r--r--src/test/testmediadir/rgb24-64x64a.pngbin0 -> 3392 bytes
-rw-r--r--src/utils/Makefile.am5
-rwxr-xr-xsrc/utils/avg_audioplayer.py49
-rwxr-xr-xsrc/utils/avg_checkpolygonspeed.py145
-rwxr-xr-xsrc/utils/avg_checkspeed.py141
-rwxr-xr-xsrc/utils/avg_checktouch.py57
-rwxr-xr-xsrc/utils/avg_checkvsync.py44
-rwxr-xr-xsrc/utils/avg_chromakey.py189
-rwxr-xr-xsrc/utils/avg_jitterfilter.py111
-rwxr-xr-xsrc/utils/avg_showcamera.py201
-rwxr-xr-xsrc/utils/avg_showfile.py38
-rwxr-xr-xsrc/utils/avg_showfont.py68
-rwxr-xr-xsrc/utils/avg_showsvg.py63
-rwxr-xr-xsrc/utils/avg_videoinfo.py275
-rwxr-xr-xsrc/utils/avg_videoplayer.py143
-rw-r--r--src/video/AsyncVideoDecoder.cpp505
-rw-r--r--src/video/AsyncVideoDecoder.h117
-rw-r--r--src/video/AudioDecoderThread.cpp366
-rw-r--r--src/video/AudioDecoderThread.h88
-rw-r--r--src/video/FFMpegDemuxer.cpp153
-rw-r--r--src/video/FFMpegDemuxer.h58
-rw-r--r--src/video/FFMpegFrameDecoder.cpp258
-rw-r--r--src/video/FFMpegFrameDecoder.h72
-rw-r--r--src/video/Makefile.am50
-rw-r--r--src/video/SyncVideoDecoder.cpp261
-rw-r--r--src/video/SyncVideoDecoder.h77
-rw-r--r--src/video/VDPAUDecoder.cpp251
-rw-r--r--src/video/VDPAUDecoder.h67
-rw-r--r--src/video/VDPAUHelper.cpp182
-rw-r--r--src/video/VDPAUHelper.h76
-rw-r--r--src/video/VideoDecoder.cpp485
-rw-r--r--src/video/VideoDecoder.h138
-rw-r--r--src/video/VideoDecoderThread.cpp222
-rw-r--r--src/video/VideoDecoderThread.h83
-rw-r--r--src/video/VideoDemuxerThread.cpp157
-rw-r--r--src/video/VideoDemuxerThread.h63
-rw-r--r--src/video/VideoInfo.cpp94
-rw-r--r--src/video/VideoInfo.h71
-rw-r--r--src/video/VideoMsg.cpp94
-rw-r--r--src/video/VideoMsg.h72
-rw-r--r--src/video/WrapFFMpeg.h93
-rw-r--r--src/video/baseline/mjpeg-48x48.avi_1.pngbin0 -> 7047 bytes
-rw-r--r--src/video/baseline/mjpeg-48x48.avi_100.pngbin0 -> 6784 bytes
-rw-r--r--src/video/baseline/mjpeg-48x48.avi_2.pngbin0 -> 7029 bytes
-rw-r--r--src/video/baseline/mjpeg-48x48.avi_201.pngbin0 -> 6978 bytes
-rw-r--r--src/video/baseline/mjpeg-48x48.avi_53.pngbin0 -> 6817 bytes
-rw-r--r--src/video/baseline/mjpeg-48x48.avi_end.pngbin0 -> 6967 bytes
-rw-r--r--src/video/baseline/mjpeg-48x48.avi_loop.pngbin0 -> 7041 bytes
-rw-r--r--src/video/baseline/mpeg1-48x48-sound.avi_end.pngbin0 -> 3282 bytes
-rw-r--r--src/video/baseline/mpeg1-48x48-sound.avi_loop.pngbin0 -> 3428 bytes
-rw-r--r--src/video/baseline/mpeg1-48x48.mov_1.pngbin0 -> 3451 bytes
-rw-r--r--src/video/baseline/mpeg1-48x48.mov_2.pngbin0 -> 3301 bytes
-rw-r--r--src/video/baseline/mpeg1-48x48.mov_end.pngbin0 -> 3284 bytes
-rw-r--r--src/video/baseline/mpeg1-48x48.mov_loop.pngbin0 -> 3451 bytes
-rw-r--r--src/video/testvideo.cpp543
-rw-r--r--src/wrapper/Makefile.am45
-rw-r--r--src/wrapper/WrapHelper.cpp428
-rw-r--r--src/wrapper/WrapHelper.h397
-rw-r--r--src/wrapper/anim_wrap.cpp131
-rw-r--r--src/wrapper/avg_wrap.cpp355
-rw-r--r--src/wrapper/bitmap_wrap.cpp207
-rw-r--r--src/wrapper/event_wrap.cpp251
-rw-r--r--src/wrapper/fx_wrap.cpp100
-rw-r--r--src/wrapper/node_wrap.cpp333
-rw-r--r--src/wrapper/raster_wrap.cpp279
-rw-r--r--src/wrapper/raw_constructor.hpp61
-rwxr-xr-xupdateMessages.sh34
-rw-r--r--valgrind.cmdline1
-rw-r--r--valgrind.suppressions808
-rw-r--r--win/anim/anim.vcxproj93
-rw-r--r--win/audio/audio.vcxproj91
-rwxr-xr-xwin/base/base.vcxproj177
-rwxr-xr-xwin/genwinimportlibs.py35
-rwxr-xr-xwin/graphics/graphics.vcxproj211
-rw-r--r--win/imaging/imaging.vcxproj126
-rwxr-xr-xwin/libavg.props44
-rwxr-xr-xwin/libavg.sln191
-rw-r--r--win/lmfit/lmfit.vcxproj78
-rw-r--r--win/oscpack/oscpack.vcxproj100
-rw-r--r--win/player/player.vcxproj238
-rwxr-xr-xwin/testbase/testbase.vcxproj76
-rwxr-xr-xwin/testgpu/testgpu.vcxproj79
-rwxr-xr-xwin/testgraphics/testgraphics.vcxproj78
-rw-r--r--win/testimaging/testimaging.vcxproj79
-rw-r--r--win/testlimiter/testlimiter.vcxproj77
-rw-r--r--win/testplayer/testplayer.vcxproj77
-rw-r--r--win/testplugin/batch_template.txt18
-rw-r--r--win/testplugin/setup.py188
-rw-r--r--win/testplugin/testplugin.vcxproj91
-rw-r--r--win/testvideo/testvideo.vcxproj77
-rw-r--r--win/video/video.vcxproj97
-rw-r--r--win/wrapper/wrapper.vcxproj96
1804 files changed, 193959 insertions, 0 deletions
diff --git a/BuildMacDeps.sh b/BuildMacDeps.sh
new file mode 100755
index 0000000..50dfae1
--- /dev/null
+++ b/BuildMacDeps.sh
@@ -0,0 +1,139 @@
+#!/bin/bash
+
+set -e
+set -x
+
+clean()
+{
+ rm -rf ${AVG_PATH}/bin/
+ rm -rf ${AVG_PATH}/lib/
+ sudo rm -rf ${AVG_PATH}/include/
+
+ mkdir ${AVG_PATH}/bin
+ mkdir ${AVG_PATH}/lib
+ mkdir ${AVG_PATH}/include
+}
+
+buildLib()
+{
+ LIBNAME=$1
+ CONFIG_ARGS=$2
+
+ echo --------------------------------------------------------------------
+ cd ${LIBNAME}
+ ./configure --prefix=${AVG_PATH} ${CONFIG_ARGS}
+ make clean
+ make -j5
+ make install
+ cd ..
+}
+
+buildglib()
+{
+ echo --------------------------------------------------------------------
+ cd glib-2.29.2
+ LDFLAGS="-framework ApplicationServices $LDFLAGS -lresolv" ./configure --prefix=${AVG_PATH} --disable-shared --enable-static
+ make clean
+ make -j5
+ make install
+ cd ..
+}
+
+buildfontconfig()
+{
+ echo --------------------------------------------------------------------
+ cd fontconfig-2.7.0
+ automake
+ LDFLAGS="-framework ApplicationServices ${LDFLAGS}" ./configure --prefix=${AVG_PATH} --disable-shared --with-add-fonts=/Library/Fonts,/System/Library/Fonts,~/Library/Fonts --with-confdir=/etc/fonts --with-cache-dir=~/.fontconfig --with-cache-dir=~/.fontconfig
+ make clean
+ make -j5
+ sudo make install
+ sudo chown -R `whoami` ~/.fontconfig
+ cd ..
+}
+
+buildgdkpixbuf()
+{
+ echo --------------------------------------------------------------------
+ cd gdk-pixbuf-2.23.3
+ LDFLAGS="-framework ApplicationServices $LDFLAGS -lresolv" ./configure --prefix=${AVG_PATH} --disable-shared --with-included-loaders
+ make clean
+ make -j5
+ make install
+ cd ..
+}
+
+buildlibrsvg()
+{
+ echo --------------------------------------------------------------------
+ cd librsvg-2.34.0
+ autoreconf --force --install
+ LDFLAGS=`xml2-config --libs` CPPFLAGS=`xml2-config --cflags` ./configure --prefix=${AVG_PATH} --disable-shared --disable-gtk-theme --disable-tools
+ make clean
+ make -j5
+ make install
+ cd ..
+}
+
+buildboost()
+{
+ echo --------------------------------------------------------------------
+ cd boost_1_54_0
+ ./bootstrap.sh --prefix=${AVG_PATH} --with-libraries=python,thread,date_time,system
+ ./bjam clean
+ ./bjam install
+ cd ..
+ rm -f ../lib/libboost_thread.dylib
+ rm -f ../lib/libboost_python.dylib
+ rm -f ../lib/libboost_date_time.dylib
+ rm -f ../lib/libboost_system.dylib
+}
+if [[ x"${AVG_PATH}" == "x" ]]
+then
+ echo ${AVG_PATH}
+ echo Please set AVG_PATH and call 'source mac/avg_env.sh' before calling this script.
+ exit -1
+fi
+
+if [[ x"${AVG_MAC_ENV_SET}" == "x" ]]
+then
+ echo Please call 'source mac/avg_env.sh' before calling this script.
+ exit -1
+fi
+
+clean
+
+cd ../deps
+
+buildLib libtool-2.2.6
+buildLib autoconf-2.63
+buildLib automake-1.11
+buildLib nasm-2.10.09
+buildLib libjpeg-turbo-1.3.0 "--host x86_64-apple-darwin --disable-shared NASM=${AVG_PATH}/bin/nasm"
+buildLib tiff-3.8.2 --disable-shared
+buildLib libpng-1.2.41 --disable-shared
+buildLib pkg-config-0.20
+buildLib yasm-1.2.0
+buildLib libav-9.9 "--arch=x86_64 --disable-debug --enable-pthreads --enable-runtime-cpudetect"
+
+buildLib SDL-1.2.15 "--disable-shared --disable-cdrom --disable-threads --disable-file --disable-video-x11 --without-x"
+buildLib gettext-0.18.1.1 "--disable-shared --with-included-gettext --disable-csharp --disable-libasprintf"
+buildglib
+
+buildLib freetype-2.5.0.1 "--disable-shared --with-old-mac-fonts"
+buildLib expat-2.0.0 --disable-shared
+
+buildfontconfig
+
+buildLib pixman-0.22.0 --disable-shared
+buildLib cairo-1.10.2 "--disable-shared --enable-xlib=no --enable-xlib-xrender=no --enable-quartz=no --enable-quartz-font=no --enable-quartz-image=no --enable-ps=no --enable-pdf=no --enable-svg=no"
+buildLib pango-1.24.4 "--disable-shared --without-x --with-included-modules=yes"
+
+buildgdkpixbuf
+buildlibrsvg
+
+buildboost
+
+buildLib libdc1394-2.2.1 "--disable-shared --disable-doxygen-doc --without-x"
+
+cd ../libavg
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..223ede7
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,504 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
+
+
diff --git a/CreateVersionFile.py b/CreateVersionFile.py
new file mode 100755
index 0000000..59063ad
--- /dev/null
+++ b/CreateVersionFile.py
@@ -0,0 +1,212 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# libavg - Media Playback Engine.
+# Copyright (C) 2003-2014 Ulrich von Zadow
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Current versions can be found at www.libavg.de
+#
+
+# The script generates a header file that contains versioning data for
+# the current build.
+
+import os
+import sys
+import subprocess
+import errno
+import re
+import socket
+import getpass
+import platform
+import datetime
+import pickle
+
+CHECK_FIELDS = ('releaseVersion', 'revision', 'branchurl')
+OUTPUT_TEMPLATE = '''// version.h
+// This file is automatically generated by CreateVersionFile.py
+
+#define AVG_VERSION_RELEASE "%(releaseVersion)s"
+#define AVG_VERSION_FULL "%(fullVersion)s"
+#define AVG_VERSION_BRANCH_URL "%(branchurl)s"
+#define AVG_VERSION_BUILDER "%(builder)s"
+#define AVG_VERSION_BUILDTIME "%(buildtime)s"
+#define AVG_VERSION_REVISION %(revision)s
+#define AVG_VERSION_MAJOR "%(major)s"
+#define AVG_VERSION_MINOR "%(minor)s"
+#define AVG_VERSION_MICRO "%(micro)s"
+'''
+TOPDIR = os.path.dirname(os.path.abspath(__file__))
+INPUT_FILE = os.path.join(TOPDIR, 'm4', 'avg_version.m4')
+CACHE_FILE = os.path.join(TOPDIR, 'versioninfo.cache')
+OUTPUT_FILENAME = 'version.h'
+
+def err(text):
+ print >>sys.stderr, text
+
+def getSvnRevision():
+ revision = 0
+
+ try:
+ process = subprocess.Popen(['svnversion'],
+ cwd=TOPDIR,
+ stdout=subprocess.PIPE)
+
+ output, discard = process.communicate()
+ except OSError, e:
+ print e, dir(e)
+ if e.errno == errno.ENOENT:
+ err('Cannot query current revision number via svninfo: '
+ '"svnversion" executable cannot be found.')
+ else:
+ match = re.search(r'^(\d+)(?::(\d+))?', output)
+ if match:
+ if match.group(2):
+ revision = match.group(2)
+ else:
+ revision = match.group(1)
+
+ return int(revision)
+
+def getSvnBranch():
+ url = ''
+ branch = 'exported'
+
+ try:
+ env = os.environ.copy()
+ env['LC_ALL'] = 'C'
+ process = subprocess.Popen(['svn', 'info', '.'],
+ cwd=TOPDIR,
+ stdout=subprocess.PIPE,
+ env=env)
+
+ output, discard = process.communicate()
+ except OSError, e:
+ if e.errno == errno.ENOENT:
+ err('Cannot query current branch via svn: '
+ '"svn" executable cannot be found.')
+ branch = 'unknown'
+ else:
+ match = re.search(r'^URL: (.+)$', output, re.M)
+ if match:
+ url = match.group(1)
+
+ if 'svn/trunk' in url:
+ branch = 'trunk'
+ elif 'svn/branches/' in url:
+ match = re.search(r'svn\/branches\/(.+)/?', url)
+ if match:
+ branch = match.group(1)
+
+ return (url, branch)
+
+def getBuilder():
+ user = getpass.getuser()
+ hostname = socket.gethostname()
+
+ return '%s@%s %s' % (user, hostname, platform.platform())
+
+def extractComponentFromM4(text, component):
+ match = re.search(r'%s\s*\].*\[\s*([A-Za-z0-9\.]+)\s*\]' % component, text, re.M)
+ if match:
+ return match.group(1)
+ else:
+ err('Cannot identify %s version component in %s' % (component, INPUT_FILE))
+ sys.exit(1)
+
+def getVersionComponents():
+ f = open(INPUT_FILE)
+ contents = f.read()
+ f.close()
+
+ major = extractComponentFromM4(contents, 'VERSION_MAJOR')
+ minor = extractComponentFromM4(contents, 'VERSION_MINOR')
+ micro = extractComponentFromM4(contents, 'VERSION_MICRO')
+
+ return (major, minor, micro)
+
+def assembleVersionInfo(major, minor, micro):
+ releaseVersion = '%s.%s.%s' % (major, minor, micro)
+ revision = getSvnRevision()
+ branchurl, branch = getSvnBranch()
+ builder = getBuilder()
+ buildtime = datetime.datetime.now().isoformat()
+
+ if revision and branch:
+ fullVersion = '%s-%s/r%s' % (releaseVersion, branch, revision)
+ elif revision:
+ fullVersion = '%s-r%s' % (releaseVersion, revision)
+ else:
+ fullVersion = releaseVersion
+
+ return locals()
+
+def dumpVersionInfo(versionInfo):
+ for k, v in versionInfo.iteritems():
+ print ' %s: %s' % (k, v)
+
+def hasChanged(versionInfo):
+ try:
+ cachef = open(CACHE_FILE)
+ except IOError:
+ return True
+
+ try:
+ cachedVersionInfo = pickle.load(cachef)
+ except Exception, e:
+ err('Corrupted %s file, forcing rewrite (%s)' % (CACHE_FILE, str(e)))
+ cachef.close()
+ return True
+
+ cachef.close()
+
+ for field in CHECK_FIELDS:
+ if versionInfo.get(field) != cachedVersionInfo.get(field):
+ return True
+
+ return False
+
+def writeVersionHeader(versionInfo, originalFile):
+ outf = open(originalFile, 'w')
+ outf.write(OUTPUT_TEMPLATE % versionInfo)
+ outf.close()
+
+ try:
+ cachef = open(CACHE_FILE, 'w')
+ except IOError:
+ pass
+ else:
+ pickle.dump(versionInfo, cachef)
+ cachef.close()
+
+def main(topBuildDir=TOPDIR):
+ versionInfo = assembleVersionInfo(*getVersionComponents())
+ outputFile = os.path.join(topBuildDir, OUTPUT_FILENAME)
+
+ # Avoid to write again if the content hasn't significantly changed
+ if not os.path.exists(outputFile) or hasChanged(versionInfo):
+ dumpVersionInfo(versionInfo)
+ writeVersionHeader(versionInfo, outputFile)
+
+
+if __name__ == '__main__':
+ if len(sys.argv) == 2:
+ main(sys.argv[1])
+ elif len(sys.argv) == 1:
+ main()
+ else:
+ err('%s [top build dir]' % sys.argv[0])
+ sys.exit(1)
+
diff --git a/Makefile.am b/Makefile.am
new file mode 100644
index 0000000..0f31201
--- /dev/null
+++ b/Makefile.am
@@ -0,0 +1,11 @@
+SUBDIRS = src man
+
+ACLOCAL_AMFLAGS = -I m4
+
+EXTRA_DIST = bootstrap COPYING NEWS \
+ CreateVersionFile.py BuildMacDeps.sh makedocs.sh \
+ valgrind.cmdline valgrind.suppressions \
+ $(wildcard mac/*) $(wildcard mac/installscripts/*)
+
+install-data-hook:
+ $(mkinstalldirs) $(DESTDIR)/$(datadir)/avg/
diff --git a/NEWS b/NEWS
new file mode 100644
index 0000000..9a3660f
--- /dev/null
+++ b/NEWS
@@ -0,0 +1,452 @@
+libavg 1.8.1 - June 21, 2014
+
+ Bugfixes:
+ * Fixed anim keepAttr bug (#496)
+ * Fixed XInput multitouch support (r9651, #489)
+ * Documentation fixes (r9648, r9637, r9636, #487)
+ * Cleaner test output (r9629, r9630, #410)
+ * Fixed undefined reference in VDPAUHelper (r9635, #486)
+ * libav 0.10.0 support
+
+libavg 1.8.0 - Feb 15, 2014
+
+ svn revision 9557
+
+ Bugfixes
+
+libavg 1.8.0.pre2 - Feb 8, 2014
+
+ svn revision 9545
+
+ Bugfixes
+
+libavg 1.8.0.pre1 - Jan 11, 2014
+
+ svn revision 9495
+
+ Major New Features:
+ * Skinnable widget library including all standard button types, sliders, scroll and
+ progress bars, on-screen keyboard and media controls.
+ * Major speed improvements: libavg can now handle thousands of visible nodes, switched
+ to entirely shader-based rendering.
+ * New cool Firebirds sample (Scotty).
+ * Powerful unified event handling framework based on publish/subscribe pattern.
+ * Support for GLES and Raspberry Pi.
+ * Complete rewrite of the video decoder subsystem: Audio consistently works, VDPAU
+ support.
+ * Shiny new logging subsystem (Richy)
+ * Powerful new app class (OXullo)
+
+ Less Major New Features:
+ * New StateMachine class
+ * WordsNode.alphagamma
+ * GPUInvertFilter (Richy)
+ * Faster handling of filled vector nodes (Benjamin Granzow)
+ * Easier creation of derived node classes in python
+ * €1 jitter filter support for gestures
+ * Global libavg.player variable
+ * CPU Thread affinity used for cleaner playback when many threads are involved
+ * Debug OpenGL context support
+ * Player.callFromThread()
+ * FontStyle class
+ * SwipeRecognizer gesture recognizer
+ * Bitmaps: added blt(), getResized(), (Incomplete) support for bitmaps > 2 GB, thread
+ pool support for BitmapLoader.
+
+ LOTS of minor new features, support for current OSes and graphics drivers, bugfixes,
+ etc.
+
+libavg 1.7.1 - Jan 26, 2012
+
+ svn revision 7008, branch release1.7.x
+
+ Bugfixes:
+
+ - Mac avg_env.sh handling of PKG_CONFIG_PATH fixed (r6886).
+ - Fixed handling of files > 2 gb in VideoWriter (r6905, Bug #279).
+ - Fixed VideoWriter crash with some ffmpeg versions (r6922).
+ - Fixed crash when stopping and seeking one video simultaneously (r6961).
+ - Fixed slow tests on Linux machines with ATI display drivers (r6970).
+ - Fixed TUIO support under Linux x86-64 (r6982).
+
+libavg 1.7.0 - Oct 29, 2011
+
+ svn revision 6888, branch release1.7.x
+
+ Bugfixes
+
+libavg 1.7.0.pre1 - Oct 29, 2011
+
+ svn revision 6871
+
+ Major New Features:
+ * Expanded effects support: New HueSatFXNode and InvertFXNode by Richard Klemm, major
+ speed improvements.
+ * Polished multitouch gesture support.
+ * New Contact class that delivers per-touch data, per-touch callbacks that make
+ event handling a lot easier.
+ * SVG support.
+ * New BitmapManager that allows loading of bitmaps in a background thread (OXullo
+ Intersecans).
+
+ Other Changes:
+ * Lots of performance optimizations.
+ * Linux ATI graphics are supported now.
+ * Major speed improvements to VideoWriter. Saving full HD videos is not a problem
+ anymore and costs little performance for the main rendering thread.
+ * Callbacks don't hold references to python objects anymore - this should make
+ freeing nodes a lot easier.
+ * New StateMachine class.
+ * Added Player.getPixelsPerMM(), getPhysicalScreenDimensions(), assumePixelsPerMM()
+ * Added touch feedback class.
+
+libavg 1.6.0 - May 29, 2011
+
+ svn revision 6022, branch release1.6.x
+
+ Bugfix release
+
+libavg 1.6.0.pre2 - May 27, 2011
+
+ svn revision 6018, branch release1.6.x
+
+ Bugfix release
+
+libavg 1.6.0.pre1 - May 20, 2011
+
+ svn revision 5974
+
+ Major New Features:
+ * New Sphinx-based reference.
+ * Unified multitouch interface: internal tracker can now be activated using
+ enableMultitouch(), Windows 7 touch is supported, linux multitouch using
+ XInput 2.1 and LibMTDev. Drivers are autodetected if possible.
+ * (Finally!) Added clean windows build files for VS 2010 to the open source
+ distribution.
+
+ Other Changes:
+ * (Finally!) Found an invisible workaround for the Linux/Mesa graphics segfault
+ that's been plaguing us for years (Chase Douglas).
+ * Support for input devices defined in python (Henrik Thoms).
+ * Added VideoWriter class (initial version by Henrik Thoms).
+ * Added initial manipulation classes for multitouch gesture support.
+ * Added connect/disconnectEventHandler functions to replace setEventHandler()
+ * Added Player.getFrameDuration().
+ * Added geom.Arc and geom.PieSlice node classes.
+ * Added Player.isUsingShaders().
+ * Added Player.getScreenResolution().
+ * 16 bit texture support is more robust.
+ * Frame times are now monotonic, so libavg installations survive time zone changes.
+ * libavg can be built with binutils-gold under linux.
+ * Intelligent fallback for multisampling.
+ * FXNodes can now change the size of the node - necessary e.g. for blur and shadow.
+ * Added Player.getTimeSinceLastFrame().
+ * Added avg_checkvsync.py utility.
+
+libavg 1.5.3 - February 20, 2011 (Linux only)
+
+ svn revision 5599
+
+ Major new feature:
+ * Linux XInput 2.1 Multitouch support.
+
+libavg 1.5.1 - November 14, 2010 (Mac only)
+
+ svn revision 5275
+
+ Fixed bug that caused fullscreen apps to crash on the mac (Bug # 162).
+
+libavg 1.5.0 - November 6, 2010
+
+ svn revision 5270
+
+ Major New Features:
+ * Nodes can be constructed directly from python, making createNode unnecessary.
+ * Added support for rendering avg scenes to offscreen canvases.
+ * Added GPU-based effects framework and Blur, Shadow, Chromakey effects.
+ * Added multitouch driver model and support for Apple Magic Trackpads and TUIO
+ devices.
+ * Support for flash videos with an alpha channel. Decoding is GPU-accellerated.
+
+ Other Changes:
+ * Added color controls (gamma, brightness, contrast) to all RasterNodes.
+ * Node constructors have a parent parameter which makes a following addChild
+ redundant.
+ * Added Player.setEventHook().
+ * Added onscreen keyboard for touchscreens.
+ * WordsNode.getNumLines(), .getCharIndexFromPos(), .getTextAsDisplayed().
+ * DivNode.getEffectiveMediaDir().
+ * Clearer profiling that works for multiple threads.
+ * Added AVG_BREAK_ON_IMPORT and AVG_BREAK_ON_ASSERT env variables.
+ * Added AVG_DUMP_TEST_FRAMES env variable.
+ * Added Player.setWindowFrame().
+ * Added VideoNode.queuelength.
+ * Video stability & timing improvements.
+ * DivNode crop default is now false.
+ * Node class names are unified: All names end with 'Node': WordsNode, DivNode, etc.
+ * Added ImageNode.compression for 16 bpp texture support.
+ * Added avg_audioplayer.py.
+
+ * Various compiler compatibility fixes: Compiles with gcc 4.5 and VC++ 2010 now.
+ * Lots of bugfixes - see the bug tracker.
+
+libavg 1.5.0.pre3 - November 4, 2010
+
+ svn revision 5267
+
+libavg 1.5.0.pre2 - November 3, 2010
+
+ svn revision 5263
+
+libavg 1.5.0.pre1 - October 31, 2010
+
+ svn revision 5244
+
+libavg 1.0.0 - January 8, 2010
+
+ svn revision 4489
+
+ New Features:
+
+ * hinting is now optional in words node.
+ * Multitouch emulation module added to AVGMTApp.
+ * masks now work with words nodes.
+ * Added video.volume property and video.hasAudio() method.
+ * Added AVG_LOG_CATEGORIES environment variable. Log configuration is now
+ done using the environment and not by calling a method.
+ * Added maskpos and masksize attribute so masks can be moved and rescaled.
+ * Added Player.getKeyModifierState()
+ * Added sse2 version of yuv->rgb color conversion.
+ * Added avg_videoinfo.sh.
+ * Added mesh node.
+ * Added avg_showcamera --resetbus to reset the firewire bus after crashes.
+
+ Other Improvements:
+ * New anim framework is now stable.
+ * Snow Leopard compatibility.
+ * avg_showcamera has much better command line handling.
+ * The test suite is faster and a lot more comprehensive.
+ * hrefs and mediadirs are now unicode-aware, so filenames like "ö.png"
+ should work.
+ * node.unlink(True) now deletes all event handlers in the node, making
+ it a lot easier to avoid memory leaks.
+ * Lots of bug fixes:
+ - Windows gamma is now reset correctly on program end.
+ - Linux vsync now much more stable.
+ - Setting node.pos.x now throws an error instead of being ignored.
+ Same for all other Point2D attributes.
+ - video.getNumFrames() now returns the exact number of frames.
+ - Behaviour of nodes before Player.play() and when they are not in the
+ avg tree is now much more stable.
+ - Fixed words node sensitive area for centered and right-aligned nodes.
+
+libavg 1.0.0.pre3 - January 6, 2010
+
+ svn revision 4475
+
+libavg 1.0.0.pre2 - December 23, 2009
+
+ svn revision 4398
+
+libavg 1.0.0.pre1 - December 21, 2009
+
+ svn revision 4387
+
+libavg 0.9.0 - August 23, 2009
+
+ svn revision 4100
+
+ Major new features:
+
+ * Support for vector node types: Line, PolyLine, Curve, Circle, Polygon,
+ Rectangle. Vector nodes can be textured, with the closed vectors taking two
+ textures: one for the outline, one for the fill. Vector drawing is GPU-based.
+ * Plugin support. Plugins written in C++ can define complete new node types.
+ * Powerful (but still experimental) new animation framework.
+ * Unified & much more stable camera drivers. Consistent support for all
+ resolutions & framerates we could test. Support for more than one camera on all
+ platforms. fw800 is supported.
+ * Uniform support for aggregate types in node interfaces (node.pos, node.pivot,
+ ...)
+
+ Other improvements:
+ * gcc 4.4 and ffmpeg 0.5.0 compatibility.
+ * Added letterspacing support to words node.
+ * Threaded videos are now the default.
+ * Improved video seek and loop performance.
+ * New Node::getElementByPos() method that returns the node at that point on the
+ screen.
+ * Added avg.svnrevision and avg.svndate properties so the avg version can be
+ queried.
+ * New avg_showfont.py utility to help font selection.
+ * New avg_showcamera.py utility to help camera setup.
+ * New avg.getMemoryUsage function that returns the resident set size.
+ * New Words.addFontDir().
+ * Added support for mipmapping node textures, including videos.
+ * rasternode.maskhref to support static alpha masks for any videos, word nodes,
+ etc.
+
+ Syntax and semantic changes:
+ * In the course of adding aggregate types for node attributes, several attributes
+ have changed:
+ - words.size is now called words.fontsize.
+ - pivotx and pivoty have been replaced by pivot.
+ * right-aligned and centered words nodes are positioned differently.
+ * avgtrackerrc syntax has changed significantly; see src/avgtrackerrc.minimal.
+ * Support for firewire cameras using libdc1394 ver. 1 has been phased out. Please
+ install ver. 2.x.
+ * The old python-based anim framework is marked deprecated. You need to explicitly
+ use the namespace anim to access it.
+
+libavg 0.9.0.pre3 - August 20, 2009
+
+ svn rev. 4086
+
+libavg 0.9.0.pre2 - August 11, 2009
+
+ svn revision 4066
+
+libavg 0.9.0.pre1 - August 9, 2009
+
+ svn revision 4046
+
+libavg 0.8.0 - September 22, 2008
+
+ svn revision 3196
+
+libavg 0.8.0.pre3 - September 16, 2008
+
+ svn revision 3171
+
+ * Fixed testgpu bug on older graphics cards.
+ * Fixed gcc 4.3 compile.
+ * Error instead of crash if vertex buffers are not supported.
+
+libavg 0.8.0.pre2 - September 13, 2008
+
+ svn revision 3161
+
+ Major new Features:
+
+ * Major tracking improvements: Parts now run as shaders on the GPU,
+ lots of optimizations, speed and ellipse axes of blobs are now available
+ in python, blob contours can be calculated, etc.
+ * Major rendering performance improvements.
+ * Much improved words node - variant attribute to select font variant to use,
+ _much_ faster rendering, full unicode support, getGlyphPos() and
+ getGlyphSize() methods, avg_showfont.py utility (parts by oxullol02l.org).
+ * Support for stereo sound mixing (Mostly Nick Hebner - hebern@gmail.com).
+ * Support for audio playback for videos (Mostly Nick Hebner - hebern@gmail.com).
+
+ Other improvements:
+ * General Mac OS X 10.5 stability.
+ * Added mediadir attribute for div nodes to specify where media used in child
+ nodes should be loaded from.
+ * Switched from ImageMagick to GraphicsMagick.
+ * Nodes can now be constructed in python using a dict for the attributes (Nick
+ Hebner - hebern@gmail.com).
+ * Mouse Wheel support.
+ * Added Player::setWindowPos()
+ * Added Node::unlink() to remove a node from the tree.
+ * The anim module now allows only one animation per node attribute.
+ * avg_videoplayer.py utility.
+ * Support for application-specific fonts.
+ * Added Player::getGPUMemoryUsage() (oxullo@02l.net).
+ * Experimental button, checkbox and textarea gui classes.
+ * Added Player::loadString() to load avg tree from a string.
+ * Added DivNode::reorderChild(), ::insertChildBefore() and ::removeChild(pNode).
+ * Experimental TUIO protocol support in remote.py.
+ * Support for bayer pattern decoding (oxullo@02l.net).
+ * Added Node::getAbsPos().
+ * Added Node::getMediaSize().
+ * Unicode handling for keyboard events.
+ * New Point2D class exposed to python.
+ * Added anim.abortAnim(node, attrName).
+
+
+libavg 0.8.0.pre1 - September 9, 2008
+
+ svn revision 3118
+
+
+libavg 0.7.1.pre1 - November 25, 2007
+
+ svn revision 2439
+
+ Major new features:
+
+ * Rotating div nodes is now possible curtesy of Nick Hebner (hebnern@gmail.com)
+ * Works with Mac OS X 10.5 (Leopard)
+
+ Other improvements:
+
+ * Improved font rendering on Mac (pango-1.18.2, freetype-2.3.5)
+ * If AVG_CONSOLE_TEST is defined during make check, all tests that involve
+ opening windows are skipped.
+ * Fixed a memory corruption bug involving timeouts.
+ * Added draggable class.
+ * Added continuousAnimation class by Martin Heistermann
+ * Added DivNode::reorderChild()
+ * Fixes for new MacBook Pros with NVidia 8600 cards.
+
+
+libavg 0.7.0 - August 31, 2007
+
+ svn Revision 2309
+
+ Major new features:
+
+ * Support for camera tracking and multitouch surfaces. (Lots of code by
+ igor@c-base.org.)
+ * Multi-threaded video decoding and video playback at speeds other than the
+ player redraw speed.
+ * API cleanups (not really a major feature, but a heads up that things will
+ break :-)).
+ * Much improved documentation.
+
+ Other improvements:
+
+ * Improved dynamic node API (DivNode::insertChild()).
+ * Video4Linux support curtesy of Xullo (x@02l.net).
+ * Update to new ffmpeg version.
+ * Callback support on video end of file.
+ * Support for python threads.
+ * Improved warp interface.
+ * Event callbacks now pass the event as a parameter.
+ * Added Player::setOnFrameHandler().
+ * Added Node::getRelPos().
+ * Any pythoon callable can be used as event handler now using
+ Node::setEventHandler().
+ * Added Anim.abort() and .isDone().
+ * Lots of new automatic low-level tests.
+ * libavg now uses correct python package semantics. Use
+ 'from libavg import avg' to import it now. It shouldn't be necessary to
+ use PYTHONPATH anymore (igor@c-base.org).
+ * Much faster Image::setBitmap().
+
+libavg 0.6.0 - October 7, 2006
+
+ svn Revision 1664
+
+ Major new features:
+
+ * Added support for dynamically adding and removing nodes to/from the tree.
+ * libavg now runs under windows, curtesy of Thomas Schüppel.
+
+ Other improvements:
+
+ * Compatible with Mesa 6.5.1 OpenGL.
+ * Much improved Gentoo ebuild.
+ * Added event capture capability (setEventCapture/releaseEventCapture) to nodes.
+ * Major speed improvement for motion jpeg videos.
+ * Some panorama image improvements.
+ * Text rendering speed improvements, minor text rendering quality improvements.
+ * Fixed mac fontconfig configuration directory issue.
+ * Fixed camera bug that caused an endless loop after 16 open/close cycles.
+ * Better error checking for broken videos and missing video files.
+ * More minor bugfixes.
+
+libavg 0.5.9 - August 11, 2006
+
+ * Test suite now completely automatic and a lot faster.
+
diff --git a/bootstrap b/bootstrap
new file mode 100755
index 0000000..b5b3370
--- /dev/null
+++ b/bootstrap
@@ -0,0 +1,33 @@
+#!/bin/bash
+set -x
+set -e
+
+if [[ `uname` = Darwin ]]
+then
+ if [[ x"$(which port)" = x"/opt/local/bin/port" ]]
+ then
+ echo "Macports detected"
+ glibtoolize --copy --force
+ aclocal -I m4
+ else
+ if [[ "$AVG_MAC_ENV_SET" -ne "1" ]]
+ then
+ echo Please source mac/avg_env.sh before calling bootstrap.
+ exit 5
+ fi
+ # This uses locally-installed libtoolize and automake since the
+ # apple-supplied one is buggy as of OS X 10.4.7
+ libtoolize --copy --force
+ aclocal -I m4
+ # Patch that fixes 'absolute addressing not allowed in slidable
+ # image' linker error.
+ patch < mac/libtool.m4.patch m4/libtool.m4
+ fi
+else
+ libtoolize --copy --force
+ aclocal -I m4
+fi
+autoheader
+automake --foreign --add-missing --copy
+autoconf
+
diff --git a/compile b/compile
new file mode 100755
index 0000000..9bb997a
--- /dev/null
+++ b/compile
@@ -0,0 +1,99 @@
+#! /bin/sh
+
+# Wrapper for compilers which do not understand `-c -o'.
+
+# Copyright 1999, 2000 Free Software Foundation, Inc.
+# Written by Tom Tromey <tromey@cygnus.com>.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Usage:
+# compile PROGRAM [ARGS]...
+# `-o FOO.o' is removed from the args passed to the actual compile.
+
+prog=$1
+shift
+
+ofile=
+cfile=
+args=
+while test $# -gt 0; do
+ case "$1" in
+ -o)
+ # configure might choose to run compile as `compile cc -o foo foo.c'.
+ # So we do something ugly here.
+ ofile=$2
+ shift
+ case "$ofile" in
+ *.o | *.obj)
+ ;;
+ *)
+ args="$args -o $ofile"
+ ofile=
+ ;;
+ esac
+ ;;
+ *.c)
+ cfile=$1
+ args="$args $1"
+ ;;
+ *)
+ args="$args $1"
+ ;;
+ esac
+ shift
+done
+
+if test -z "$ofile" || test -z "$cfile"; then
+ # If no `-o' option was seen then we might have been invoked from a
+ # pattern rule where we don't need one. That is ok -- this is a
+ # normal compilation that the losing compiler can handle. If no
+ # `.c' file was seen then we are probably linking. That is also
+ # ok.
+ exec "$prog" $args
+fi
+
+# Name of file we expect compiler to create.
+cofile=`echo $cfile | sed -e 's|^.*/||' -e 's/\.c$/.o/'`
+
+# Create the lock directory.
+# Note: use `[/.-]' here to ensure that we don't use the same name
+# that we are using for the .o file. Also, base the name on the expected
+# object file name, since that is what matters with a parallel build.
+lockdir=`echo $cofile | sed -e 's|[/.-]|_|g'`.d
+while true; do
+ if mkdir $lockdir > /dev/null 2>&1; then
+ break
+ fi
+ sleep 1
+done
+# FIXME: race condition here if user kills between mkdir and trap.
+trap "rmdir $lockdir; exit 1" 1 2 15
+
+# Run the compile.
+"$prog" $args
+status=$?
+
+if test -f "$cofile"; then
+ mv "$cofile" "$ofile"
+fi
+
+rmdir $lockdir
+exit $status
diff --git a/configure.ac b/configure.ac
new file mode 100644
index 0000000..ce08096
--- /dev/null
+++ b/configure.ac
@@ -0,0 +1,232 @@
+AC_PREREQ(2.53)
+
+dnl Use this file to bump version on release
+m4_include([m4/avg_version.m4])
+
+AC_INIT(libavg, [VERSION_MAJOR.VERSION_MINOR.VERSION_MICRO], uzadow@libavg.de)
+
+dnl Hack to detect virtualenv
+if [[ x"$VIRTUAL_ENV" != "x" ]] && [[ $prefix = NONE ]]; then
+ prefix=$VIRTUAL_ENV
+ AC_MSG_RESULT([Virtualenv detected, setting prefix to $prefix])
+fi
+
+AC_CANONICAL_TARGET
+
+AC_DISABLE_STATIC
+AC_PROG_LIBTOOL
+
+AC_CONFIG_MACRO_DIR([m4])
+AC_CONFIG_SRCDIR([src/avgconfig.h.in])
+AM_INIT_AUTOMAKE([check-news dist-zip foreign])
+m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])])
+# Checks for programs.
+AC_PROG_CXX
+AC_PROG_CC
+AC_PROG_CPP
+CXXFLAGS="-O3 -ffast-math -Wall -pipe -Wno-invalid-offsetof -Woverloaded-virtual -Wswitch -Wuninitialized -Wempty-body $CXXFLAGS"
+CFLAGS="-O3 -ffast-math -Wall -pipe $CFLAGS"
+if [[ $host_cpu == i386 ]] || [[ $host_cpu == i686 ]] || [[ $host_cpu == x86_64 ]]; then
+ CXXFLAGS="-msse2 $CXXFLAGS"
+ CFLAGS="-msse2 $CFLAGS"
+fi
+OBJC="gcc"
+OBJCFLAGS=""
+OBJCLDFLAGS="-lobjc"
+AC_SUBST(OBJC)
+AC_SUBST(OBJCFLAGS)
+AC_SUBST(OBJCLDFLAGS)
+_AM_DEPENDENCIES([OBJC])
+LDFLAGS="$LDFLAGS -rdynamic"
+
+if [[ $target_vendor = apple ]] && [[ x"`which port`" = x"/opt/local/bin/port" ]]; then
+ AC_MSG_RESULT([Macports detected. Adding include and lib search paths])
+ CFLAGS="$CFLAGS -I/opt/local/include"
+ CXXFLAGS="$CXXFLAGS -I/opt/local/include"
+ LDFLAGS="$LDFLAGS -L/opt/local/lib"
+fi
+
+AC_SEARCH_LIBS([clock_gettime],[rt])
+AC_CHECK_LIB([dl], [dlopen])
+
+AC_PATH_GENERIC(xml2,,,AC_MSG_ERROR([libxml2 not found. Aborting.]))
+PKG_CHECK_MODULES([PANGOFT2], [pangoft2])
+AC_PATH_GENERIC(freetype,,,AC_MSG_ERROR([libfreetype not found. Aborting.]))
+
+PKG_CHECK_MODULES([GDK_PIXBUF], [gdk-pixbuf-2.0])
+PKG_CHECK_MODULES([LIBRSVG], [librsvg-2.0])
+PKG_CHECK_MODULES([FONTCONFIG], [fontconfig])
+
+PKG_CHECK_MODULES([FFMPEG], [libswscale libavformat libavcodec libavutil], [LIBFFMPEG="$FFMPEG_LIBS"], [:])
+AC_SUBST(LIBFFMPEG)
+AC_CHECK_HEADERS([libavformat/avformat.h])
+if test -z "$FFMPEG_LIBS"; then
+ AC_MSG_ERROR([Could not find ffmpeg development libraries.])
+fi
+
+PKG_CHECK_MODULES([AVRESAMPLE], [libavresample], [LIBAVRESAMPLE="$AVRESAMPLE_LIBS"], [:])
+AC_SUBST(LIBAVRESAMPLE)
+AC_CHECK_HEADERS([libavresample/avresample.h])
+
+AM_PATH_PYTHON
+AX_PYTHON_DEVEL
+
+AC_ARG_VAR(BOOST_PYTHON_LIBS, [linker flags for BOOST, defaults to -lboost_python])
+if test -z "$BOOST_PYTHON_LIBS"
+then
+ AC_CHECK_LIB(boost_python, main, libboost_python_installed=yes, , $PYTHON_LDFLAGS)
+ if test -z "$libboost_python_installed"
+ then
+ AC_MSG_ERROR([boost.python not found. Aborting.])
+ fi
+ BOOST_PYTHON_LIBS="-lboost_python"
+fi
+
+AX_BOOST_THREAD
+if test -z "$BOOST_THREAD_LIBS"; then
+ AC_MSG_ERROR([boost.thread not found. Aborting.])
+fi
+
+AC_ARG_ENABLE(dc1394,
+ AC_HELP_STRING([--enable-dc1394],
+ [compile support for firewire cameras]),
+ enable_1394=$enableval, enable_1394=maybe)
+if test "$enable_1394" = maybe; then
+ PKG_CHECK_MODULES([DC1394_2], [libdc1394-2],,AC_MSG_NOTICE([libdc1394 ver 2 not found]))
+fi
+AM_CONDITIONAL(ENABLE_1394_2, test x"$DC1394_2_LIBS" != x )
+if test x"$DC1394_2_LIBS" != "x"; then
+ AC_DEFINE(AVG_ENABLE_1394_2, 1, [Enable firewire camera support v.2])
+fi
+
+PKG_CHECK_MODULES([MTDEV], [mtdev],
+ [AC_DEFINE(AVG_ENABLE_MTDEV, 1, [Enable Linux kernel multitouch])],
+ AC_MSG_NOTICE(mtdev not found))
+AM_CONDITIONAL(ENABLE_MTDEV, test x"$MTDEV_LIBS" != x)
+
+if test $target_vendor = apple; then
+ AM_CONDITIONAL(HAVE_XI2_1, false)
+ AM_CONDITIONAL(HAVE_XI2_2, false)
+else
+ PKG_CHECK_MODULES(XI2_1, [xi >= 1.4.1.99.1] [inputproto >= 2.0.99.1] [inputproto < 2.1.99.5],
+ HAVE_XI2_1="yes"; AC_DEFINE(HAVE_XI2_1, 1, [XI2_1 available]),
+ HAVE_XI2_1="no");
+ PKG_CHECK_MODULES(XI2_2, [xi >= 1.5.99.2] [inputproto >= 2.1.99.5],
+ HAVE_XI2_2="yes"; AC_DEFINE(HAVE_XI2_2, 1, [XI2_2 available]),
+ HAVE_XI2_2="no");
+ AM_CONDITIONAL(HAVE_XI2_1, [ test "$HAVE_XI2_1" = "yes" ])
+ AM_CONDITIONAL(HAVE_XI2_2, [ test "$HAVE_XI2_2" = "yes" ])
+fi
+
+AC_ARG_ENABLE(v4l2,
+ AC_HELP_STRING([--enable-v4l2],
+ [compile support for video4linux v2 video devices]),
+ enable_v4l2=$enableval, enable_v4l2=maybe)
+if test "$enable_v4l2" = maybe; then
+ AC_CHECK_TYPE([struct v4l2_buffer],
+ [enable_v4l2=yes],
+ [enable_v4l2=no],
+ [#include <sys/time.h>
+ #include <linux/videodev2.h>])
+fi
+AM_CONDITIONAL(ENABLE_V4L2, test x$enable_v4l2 = xyes)
+if test "$enable_v4l2" = yes; then
+ AC_DEFINE(AVG_ENABLE_V4L2, 1, [Enable Video4Linux2 camera support])
+fi
+
+AC_CHECK_HEADER([linux/ppdev.h], enable_ParPort=yes, enable_ParPort=no)
+AM_CONDITIONAL(ENABLE_PARPORT, test x$enable_ParPort = xyes)
+if test "$enable_ParPort" = yes; then
+ AC_DEFINE(AVG_ENABLE_PARPORT, 1, [Enable parallel port support])
+fi
+
+AC_ARG_ENABLE(egl,
+ AC_HELP_STRING([--enable-egl], [include EGL support [default=no]]),
+ ,
+ enable_egl=no)
+
+AC_ARG_ENABLE(rpi,
+ AC_HELP_STRING([--enable-rpi], [configure for RaspberryPi [default=no]]),
+ ,
+ enable_rpi=no)
+
+if test "$enable_rpi" = yes; then
+ CPPFLAGS="$CPPFLAGS -I/opt/vc/include -I/opt/vc/include/interface/vmcs_host/linux -I/opt/vc/include/interface/vcos/pthreads"
+ LDFLAGS="$LDFLAGS -L/opt/vc/lib"
+ AC_DEFINE(AVG_ENABLE_RPI, 1, [Build on RaspberryPi])
+ AM_CONDITIONAL(ENABLE_RPI, true)
+ if test "$enable_egl" = no; then
+ enable_egl=yes
+ AC_MSG_NOTICE([--enable-rpi requires --enable-egl, added --enable-egl])
+ fi
+ # suppress several hundreds "swp{b} use is deprecated for this architecture" assembler warnings
+ CFLAGS="$CFLAGS -Wa,--no-warn"
+ CXXFLAGS="$CXXFLAGS -Wa,--no-warn"
+else
+ AM_CONDITIONAL(ENABLE_RPI, false)
+fi
+
+if test "$enable_egl" = yes; then
+ AC_CHECK_HEADERS(["EGL/egl.h"], [egl_present=yes;])
+ AC_CHECK_HEADERS(["GLES2/gl2.h"], [gles2_present=yes;])
+ if [[ x"$egl_present" == x ]] || [[ x"$gles2_present" == x ]]; then
+ AC_MSG_ERROR([EGL not found. Aborting])
+ fi
+ AC_DEFINE(AVG_ENABLE_EGL, 1, [Enable EGL support])
+else
+ AX_CHECK_GL
+ AX_CHECK_GLU
+ if test x"$GL_LIBS" = x; then
+ AC_MSG_ERROR([OpenGL not found. Aborting])
+ fi
+ AC_DEFINE(AVG_ENABLE_OPENGL, 1, [Enable OpenGL support])
+fi
+AM_CONDITIONAL(ENABLE_EGL, test x"$egl_present" != x)
+AM_CONDITIONAL(ENABLE_OPENGL, test x"$GL_LIBS" != x)
+
+AM_PATH_SDL(1.2.10,:,AC_MSG_ERROR([libSDL not found. Aborting.]))
+
+AC_CHECK_LIB([vdpau],[main],let vdpau_lib=1,let vdpau_lib=0)
+AC_CHECK_HEADERS([libavcodec/vdpau.h],let vdpau_h1=1,let vdpau_h1=0)
+AC_CHECK_HEADERS([vdpau/vdpau.h],let vdpau_h2=1,let vdpau_h2=0)
+if [[ $vdpau_lib -eq 1 ]] && [[ $vdpau_h1 -eq 1 ]] && [[ $vdpau_h2 -eq 1 ]]; then
+ AC_DEFINE(AVG_ENABLE_VDPAU, 1, [Enable VDPAU support])
+ LIBVIDEO_LDADD="-lvdpau"
+ AM_CONDITIONAL(USE_VDPAU_SRC, true)
+else
+ LIBVIDEO_LDADD=""
+ AM_CONDITIONAL(USE_VDPAU_SRC, false)
+fi
+AC_SUBST([LIBVIDEO_LDADD])
+
+AM_CONDITIONAL(APPLE, test $target_vendor = apple)
+
+PREFIX=$prefix
+AC_SUBST(PREFIX)
+AC_CONFIG_HEADERS(src/avgconfig.h)
+AC_OUTPUT(Makefile
+ src/Makefile
+ src/test/Makefile
+ src/test/plugin/Makefile
+ src/base/Makefile
+ src/base/triangulate/Makefile
+ src/lmfit/Makefile
+ src/wrapper/Makefile
+ src/player/Makefile
+ src/graphics/Makefile
+ src/graphics/shaders/Makefile
+ src/python/Makefile
+ src/imaging/Makefile
+ src/video/Makefile
+ src/audio/Makefile
+ src/utils/Makefile
+ src/anim/Makefile
+ src/python/data/Makefile
+ src/samples/Makefile
+ src/samples/firebirds/Makefile
+ src/samples/firebirds/plugin/Makefile
+ src/samples/firebirds/media/Makefile
+ src/python/widget/Makefile
+ src/python/app/Makefile
+ src/oscpack/Makefile
+ man/Makefile)
diff --git a/debian/avg_audioplayer.1 b/debian/avg_audioplayer.1
new file mode 100644
index 0000000..5084385
--- /dev/null
+++ b/debian/avg_audioplayer.1
@@ -0,0 +1,11 @@
+.TH AVG_AUDIPLAYER "1" "November 2011" "libavg 1.7.0" "User Commands"
+.SH NAME
+avg_audioplayer \- audio player
+.SH SYNOPSIS
+.B avg_audioplayer
+\fIfile\fR
+.SH DESCRIPTION
+Play an audio file.
+.PP
+.SH AUTHOR
+Ulrich von Zadow <coder@c-base.org>
diff --git a/debian/avg_checktouch.1 b/debian/avg_checktouch.1
new file mode 100644
index 0000000..604dd7f
--- /dev/null
+++ b/debian/avg_checktouch.1
@@ -0,0 +1,11 @@
+.TH AVG_CHECKTOUCH "1" "November 2011" "libavg 1.7.0" "User Commands"
+.SH NAME
+avg_checktouch \- test application for multitouch devices
+.SH SYNOPSIS
+.B avg_checktouch
+\fIfile\fR
+.SH DESCRIPTION
+Minimal application to test multitouch event and visualize them on screen
+.PP
+.SH AUTHOR
+Ulrich von Zadow <coder@c-base.org>
diff --git a/debian/avg_checkvsync.1 b/debian/avg_checkvsync.1
new file mode 100644
index 0000000..a020a99
--- /dev/null
+++ b/debian/avg_checkvsync.1
@@ -0,0 +1,11 @@
+.TH AVG_CHECKVSYNC "1" "November 2011" "libavg 1.7.0" "User Commands"
+.SH NAME
+avg_checkvsync \- vsync test application
+.SH SYNOPSIS
+.B avg_checkvsync
+\fIfile\fR
+.SH DESCRIPTION
+Minimal application to test vertical syncing
+.PP
+.SH AUTHOR
+Ulrich von Zadow <coder@c-base.org>
diff --git a/debian/avg_chromakey.1 b/debian/avg_chromakey.1
new file mode 100644
index 0000000..8261d85
--- /dev/null
+++ b/debian/avg_chromakey.1
@@ -0,0 +1,39 @@
+.TH AVG_CHROMAKEY "1" "November 2011" "libavg 1.7.0" "User Commands"
+.SH NAME
+avg_chromakey \- test application for libavg chromakey filter
+.SH SYNOPSIS
+.B avg_chromakey
+\fI\-t DRIVER [OPTION]...\fR
+.SH DESCRIPTION
+Stream a live image from a camera and apply a chromakey filter.
+.PP
+.SH OPTIONS
+.TP
+\fB\-h\fR, \fB\-\-help\fR
+Show a brief description of the options.
+.TP
+\fB\-t\fR, \fB\-\-driver\fR DRIVER
+One of the camera subsystems supported by libavg (supported: firewire, video4linux, directshow).
+.TP
+\fB\-d\fR, \fB\-\-device\fR DEVICE
+Camera device identifier (depending on the driver, a GUID or device path is expected).
+.TP
+\fB\-u\fR, \fB\-\-unit\fR UNIT
+Unit number. Used for cameras or other capture devices which deliver several images (e.g. stereo cameras or TV capture cards).
+.TP
+\fB\-w\fR, \fB\-\-width\fR WIDTH
+Camera image width.
+.TP
+\fB\-e\fR, \fB\-\-height\fR HEIGHT
+Camera image height.
+.TP
+\fB\-p\fR, \fB\-\-pixelformat\fR PIXELFORMAT
+Camera pixel format (one of: I8, I16, YUV411, YUV422, YUYV422, RGB, BGR, BAYER8).
+.TP
+\fB\-f\fR, \fB\-\-framerate\fR FRAMERATE
+Frames per second.
+.TP
+\fB\-8\fR, \fB\-\-fw800\fR
+Set firewire bus speed to s800 (if supported).
+.SH AUTHOR
+Ulrich von Zadow <coder@c-base.org>
diff --git a/debian/avg_showcamera.1 b/debian/avg_showcamera.1
new file mode 100644
index 0000000..350214b
--- /dev/null
+++ b/debian/avg_showcamera.1
@@ -0,0 +1,54 @@
+.TH AVG_SHOWCAMERA "1" "November 2011" "libavg 1.7.0" "User Commands"
+.SH NAME
+avg_showcamera \- camera discovery and display tool
+.SH SYNOPSIS
+.B avg_showcamera
+\fI\-l\fR
+.HP
+.B avg_showcamera
+\fI\-r\fR
+.HP
+.B avg_showcamera
+\fI\-t DRIVER [OPTION]...\fR
+.SH DESCRIPTION
+Query and list attached cameras, reset firewire bus, show video stream.
+.PP
+.SH OPTIONS
+.TP
+\fB\-h\fR, \fB\-\-help\fR
+Show a brief description of the options.
+.TP
+\fB\-l\fR, \fB\-\-dump\fR
+Dump a list of available cameras to the console.
+.TP
+\fB\-r\fR, \fB\-\-resetbus\fR
+Reset the firewire bus and free allocated bandwidth.
+.TP
+\fB\-t\fR, \fB\-\-driver\fR DRIVER
+One of the camera subsystems supported by libavg (supported: firewire, video4linux, directshow).
+.TP
+\fB\-d\fR, \fB\-\-device\fR DEVICE
+Camera device identifier (depending on the driver, a GUID or device path is expected).
+.TP
+\fB\-u\fR, \fB\-\-unit\fR UNIT
+Unit number. Used for cameras or other capture devices which deliver several images (e.g. stereo cameras or TV capture cards).
+.TP
+\fB\-w\fR, \fB\-\-width\fR WIDTH
+Camera image width.
+.TP
+\fB\-e\fR, \fB\-\-height\fR HEIGHT
+Camera image height.
+.TP
+\fB\-p\fR, \fB\-\-pixelformat\fR PIXELFORMAT
+Camera pixel format (one of: I8, I16, YUV411, YUV422, YUYV422, RGB, BGR, BAYER8).
+.TP
+\fB\-f\fR, \fB\-\-framerate\fR FRAMERATE
+Frames per second.
+.TP
+\fB\-8\fR, \fB\-\-fw800\fR
+Set firewire bus speed to s800 (if supported).
+.TP
+\fB\-s\fR, \fB\-\-noinfo\fR
+Don't show any info overlayed on the screen.
+.SH AUTHOR
+Ulrich von Zadow <coder@c-base.org>
diff --git a/debian/avg_showfile.1 b/debian/avg_showfile.1
new file mode 100644
index 0000000..cfc1561
--- /dev/null
+++ b/debian/avg_showfile.1
@@ -0,0 +1,11 @@
+.TH AVG_SHOWFILE "1" "November 2011" "libavg 1.7.0" "User Commands"
+.SH NAME
+avg_showfile \- display an avg file
+.SH SYNOPSIS
+.B avg_showfile
+\fIfile\fR
+.SH DESCRIPTION
+Open and render an avg file.
+.PP
+.SH AUTHOR
+Ulrich von Zadow <coder@c-base.org>
diff --git a/debian/avg_showfont.1 b/debian/avg_showfont.1
new file mode 100644
index 0000000..acbddf6
--- /dev/null
+++ b/debian/avg_showfont.1
@@ -0,0 +1,19 @@
+.TH AVG_SHOWFONT "1" "November 2011" "libavg 1.7.0" "User Commands"
+.SH NAME
+avg_showfont \- font enumeration and preview tool
+.SH SYNOPSIS
+.B avg_showfont
+[\fIfontname\fR] [\fItext\fR]
+.SH DESCRIPTION
+List available font faces and generate preview of their variants.
+.PP
+If invoked without arguments, avg_showfont generates a list of font family names and prints them on the console.
+Fontconfig is used for font discovery. Fonts are searched for in the system font path and in $PWD/fonts.
+.PP
+If \fBfontname\fR is specified, the chosen font is displayed in a window, with one line for
+each available variant.
+.PP
+If supplied, the optional \fBtext\fR argument is used instead of the variant name in the
+sample text.
+.SH AUTHOR
+Ulrich von Zadow <coder@c-base.org>
diff --git a/debian/avg_showsvg.1 b/debian/avg_showsvg.1
new file mode 100644
index 0000000..7dc67ba
--- /dev/null
+++ b/debian/avg_showsvg.1
@@ -0,0 +1,17 @@
+.TH AVG_SHOWSVG "1" "November 2011" "libavg 1.7.0" "User Commands"
+.SH NAME
+avg_showsvg \- basic svg rasterizer
+.SH SYNOPSIS
+.B avg_showsvg [-s FACTOR] [--save-image] <SVGFILE> <SVGID>
+.SH DESCRIPTION
+Opens an svg file and renders a specific element (chosen by ID) on screen or saves it to a png file.
+.PP
+.SH OPTIONS
+.TP
+\fB\-s\fR, \fB\-\-size\fR
+Specify a factor for the size of the element.
+.TP
+\fB\-\-save-image\fR
+Write the rendered output to a png file as <SVGID>.png
+.SH AUTHOR
+Ulrich von Zadow <coder@c-base.org>
diff --git a/debian/avg_videoinfo.1 b/debian/avg_videoinfo.1
new file mode 100644
index 0000000..23c313f
--- /dev/null
+++ b/debian/avg_videoinfo.1
@@ -0,0 +1,29 @@
+.TH AVG_VIDEOINFO "1" "November 2011" "libavg 1.7.0" "User Commands"
+.SH NAME
+avg_videoinfo \- video inspection tool
+.SH SYNOPSIS
+.B avg_videoinfo
+\fIfile(s)\fR \fI[OPTION]\fR
+.SH DESCRIPTION
+Dump video file format information to the console
+.PP
+Inspects the given file(s) and dumps information about duration, bitrate, video/audio codec,
+video frame size and pixel format, video fps, audio sample rate and number of channels for
+each file given.
+.PP
+The default output format is text.
+.PP
+XML and CSV formats can be chosen with the appropriate options.
+.PP
+.SH OPTIONS
+.TP
+\fB\-h\fR, \fB\-\-help\fR
+Show a brief description of the options.
+.TP
+\fB\-x\fR, \fB\-\-xml\fR
+XML output format.
+.TP
+\fB\-c\fR, \fB\-\-csv\fR
+CSV output format.
+.SH AUTHOR
+Ulrich von Zadow <coder@c-base.org>
diff --git a/debian/avg_videoplayer.1 b/debian/avg_videoplayer.1
new file mode 100644
index 0000000..d2f8cbd
--- /dev/null
+++ b/debian/avg_videoplayer.1
@@ -0,0 +1,11 @@
+.TH AVG_VIDEOPLAYER "1" "November 2011" "libavg 1.7.0" "User Commands"
+.SH NAME
+avg_videoplayer \- video player
+.SH SYNOPSIS
+.B avg_videoplayer
+\fIfile\fR
+.SH DESCRIPTION
+Play a video file using libavg.
+.PP
+.SH AUTHOR
+Ulrich von Zadow <coder@c-base.org>
diff --git a/debian/changelog b/debian/changelog
new file mode 100644
index 0000000..caa9dde
--- /dev/null
+++ b/debian/changelog
@@ -0,0 +1,500 @@
+libavg (1.8.1-1) unstable; urgency=medium
+
+ * New upstream release (Closes: #739664)
+ * Mark libdc1394-22-dev as linux-any build-dependency.
+ * Add libvdpau-dev build-dependency.
+ * Add libavresample-dev build-dependency.
+
+ -- Dimitri John Ledkov <xnox@ubuntu.com> Tue, 24 Jun 2014 20:05:13 +0100
+
+libavg (1.8.0-1) unstable; urgency=medium
+
+ * New upstream release. Closes: #721047
+ * Drop all patches, none are needed with this new upstream release.
+ * Port to dh.
+ * Specify foreign in configure.ac.
+
+ -- Dimitri John Ledkov <xnox@ubuntu.com> Thu, 20 Feb 2014 16:06:16 +0000
+
+libavg (1.7.1-4) unstable; urgency=low
+
+ * Drop automake1.10 dependency in favor of automake. Closes: #724398.
+
+ -- Dmitrijs Ledkovs <xnox@debian.org> Tue, 24 Sep 2013 09:14:03 +0100
+
+libavg (1.7.1-3ubuntu1) saucy; urgency=low
+
+ * Link against boost-system for boost1.50+
+
+ -- Dmitrijs Ledkovs <dmitrij.ledkov@ubuntu.com> Tue, 27 Aug 2013 16:49:57 +0100
+
+libavg (1.7.1-3) unstable; urgency=low
+
+ * Fix building against multiarched python.
+
+ -- Dmitrijs Ledkovs <dmitrij.ledkov@ubuntu.com> Wed, 20 Feb 2013 12:28:46 +0000
+
+libavg (1.7.1-2) unstable; urgency=low
+
+ * Change architecture to any
+ * Make some x86 specific debug code conditional (replacing it with a
+ deliberate segfault) (patch accepted upstream) (Closes: #683105)
+
+ -- Peter Michael Green <plugwash@raspbian.org> Fri, 27 Jul 2012 23:46:04 +0000
+
+libavg (1.7.1-1) unstable; urgency=low
+
+ * New maintainer
+ * debian/patches/series: Add patch to fix FTBFS with gcc 4.7 (LP: #1008300)
+ * debian/control: Correct the packaging URL
+ * debian/control: Bump the standards version to 3.9.3
+ * debian/copyright: Change the URL of the copyright format specification
+ * closing debian bugs, fixed in the previous ubuntu uploads:
+ - builds with gold (Closes: #555079)
+ - uses dh_python2 (Closes: #616859)
+ - no *.la files shipped (Closes: #621534)
+ - don't use -msse2 on non-ix86 architectures (Closes: #580678)
+
+ -- Dmitrijs Ledkovs <xnox@debian.org> Wed, 13 Jun 2012 21:36:19 +0100
+
+libavg (1.7.1-0ubuntu1) precise; urgency=low
+
+ * New upstream release (LP: #923302)
+
+ -- OXullo Intersecans <x@brainrapers.org> Sun, 29 Jan 2012 19:26:37 +0100
+
+libavg (1.7.0-0ubuntu1) precise; urgency=low
+
+ * New upstream release (LP: #899183)
+ * Remove patches 0002-libav-0.7.patch, 0003-fglrx-segfault-on-startup.patch
+ now merged to upstream
+ * Remove unnecessary .la files
+ * Update debian/watch file
+ * Fix debian/copyright dep-5 compliancy
+ * Update standards to version 3.9.2
+ * Add man pages for avg_checktouch, avg_checkvsync, avg_showsvg
+ * Minor debian/rules enhancement
+ * Add librsvg2-dev, libgdk-pixbuf2.0-dev to Build-Depends
+ * Proper transition to dh_python2
+
+ -- OXullo Intersecans <x@brainrapers.org> Tue, 06 Dec 2011 22:44:56 +0100
+
+libavg (1.5.4-0ubuntu4) oneiric; urgency=low
+
+ * Work around segfault when using fglrx (LP: #815922)
+
+ -- Stefano Rivera <stefanor@ubuntu.com> Sun, 09 Oct 2011 23:30:53 +0200
+
+libavg (1.5.4-0ubuntu3) oneiric; urgency=low
+
+ * Port to libav 0.7 API (LP: #831190).
+
+ -- Colin Watson <cjwatson@ubuntu.com> Mon, 29 Aug 2011 23:32:13 +0100
+
+libavg (1.5.4-0ubuntu2) natty; urgency=low
+
+ * Build arch restricted to the supported i386 and amd64 (LP: #735548)
+ * STDC macros define moved from CXXFLAGS to CPPFLAGS in order to autoconf
+ to set correctly the default (LP: #752924)
+
+ -- OXullo Intersecans <x@brainrapers.org> Wed, 06 Apr 2011 23:46:15 +0200
+
+libavg (1.5.4-0ubuntu1) natty; urgency=low
+
+ [ OXullo Intersecans ]
+ * Upstream update
+ * Removed 0002-load-libstdc++-first.patch which is now merged to upstream
+ * Add manpages
+
+ [ Chase Douglas ]
+ * Update debian/copyright for DEP5 standards
+ * Remove README.debian as its contents are no longer relevant
+ * Update debian/watch to version 3
+ * Add list-missing check for installed but not packaged files
+
+ -- OXullo Intersecans <x@brainrapers.org> Fri, 11 Mar 2011 20:24:54 +0100
+
+libavg (1.5.3-0ubuntu2) UNRELEASED; urgency=low
+
+ [ OXullo Intersecans ]
+ * New package descriptions
+
+ [ Chase Douglas ]
+ * Fix segfault on start up in Ubuntu due to Mesa glx tls issue
+ - Added 0002-load-libstdc++-first.patch
+
+ -- Chase Douglas <chase.douglas@ubuntu.com> Wed, 23 Feb 2011 15:04:56 -0500
+
+libavg (1.5.3-0ubuntu1) UNRELEASED; urgency=low
+
+ * Upstream update
+ * Reverted rules back to watch
+
+ -- OXullo Intersecans <x@brainrapers.org> Sun, 20 Feb 2011 14:27:42 +0100
+
+libavg (1.5.2+svn5577-0ubuntu1) UNRELEASED; urgency=low
+
+ * Upstream update
+
+ -- OXullo Intersecans <x@brainrapers.org> Sun, 13 Feb 2011 23:18:32 +0100
+
+libavg (1.5.2+svn5512-0ubuntu2) UNRELEASED; urgency=low
+
+ * Switched python-central to dh_python2
+
+ -- OXullo Intersecans <x@brainrapers.org> Sat, 12 Feb 2011 00:27:30 +0100
+
+libavg (1.5.2+svn5512-0ubuntu1) UNRELEASED; urgency=low
+
+ * Upstream update
+
+ -- OXullo Intersecans <x@brainrapers.org> Mon, 07 Feb 2011 18:17:48 +0100
+
+libavg (1.5.2+svn5510-0ubuntu1) UNRELEASED; urgency=low
+
+ * Upstream update
+ * Added libxi6 as package dependency
+
+ -- OXullo Intersecans <x@brainrapers.org> Sun, 06 Feb 2011 21:48:27 +0100
+
+libavg (1.5.2+svn5509-0ubuntu2) UNRELEASED; urgency=low
+
+ * Added libxi-dev as build dependency
+
+ -- OXullo Intersecans <x@brainrapers.org> Sun, 06 Feb 2011 20:32:47 +0100
+
+libavg (1.5.2+svn5509-0ubuntu1) UNRELEASED; urgency=low
+
+ * Upstream update
+
+ -- OXullo Intersecans <x@brainrapers.org> Sun, 06 Feb 2011 20:24:05 +0100
+
+libavg (1.5.2+svn5503-0ubuntu1) UNRELEASED; urgency=low
+
+ * Upstream update
+
+ -- OXullo Intersecans <x@brainrapers.org> Sun, 06 Feb 2011 17:50:24 +0100
+
+libavg (1.5.2+svn5481-0ubuntu1) UNRELEASED; urgency=low
+
+ * Upstream update
+ * Temporarily enabled svn upstream provider
+
+ -- OXullo Intersecans <x@brainrapers.org> Sat, 05 Feb 2011 02:07:31 +0100
+
+libavg (1.5.2+svn5420-0ubuntu2) UNRELEASED; urgency=low
+
+ * Upstream update
+
+ -- OXullo Intersecans <x@brainrapers.org> Wed, 26 Jan 2011 02:06:08 +0100
+
+libavg (1.5.2-0ubuntu1) UNRELEASED; urgency=low
+
+ * New upstream version
+ * Remove current examples in favour of upstream's src/samples.
+ * Remove patches merged upstream.
+ * Remove .py extension from new /usr/bin/ scripts.
+
+ -- OXullo Intersecans <x@brainrapers.org> Sun, 16 Jan 2011 23:11:32 +0100
+
+libavg (1.0.1-1ubuntu4) natty; urgency=low
+
+ * Fix build failure with ld --no-add-needed.
+
+ -- Matthias Klose <doko@ubuntu.com> Sat, 04 Dec 2010 11:55:19 +0100
+
+libavg (1.0.1-1ubuntu3) natty; urgency=low
+
+ * Rebuild to add support for python 2.7.
+
+ -- Matthias Klose <doko@ubuntu.com> Fri, 03 Dec 2010 00:02:50 +0000
+
+libavg (1.0.1-1ubuntu2) maverick; urgency=low
+
+ * Fix FTBFS, don't use -msse2 on non-ix86 architectures.
+
+ -- Matthias Klose <doko@ubuntu.com> Sun, 19 Sep 2010 14:16:51 +0200
+
+libavg (1.0.1-1ubuntu1) maverick; urgency=low
+
+ * debian/rules: added CXXFLAGS to fix a FTBFS with undefined UINT64_C error
+ with latest ffmpeg
+
+ -- Fabrice Coutadeur <fabricesp@ubuntu.com> Sat, 04 Sep 2010 19:47:32 +0000
+
+libavg (1.0.1-1) unstable; urgency=low
+
+ * new upstream release (Closes: #565512)
+ * Remove patches that have been merged upstream.
+ * Add a patch that avoids building tests by default.
+ * Remove .py extension from two more scripts in /usr/bin .
+ * Add 2 example files to /usr/share/doc/python-libavg/examples/ .
+ * Describe a workaround for bug #579937 in README.Debian.
+ * Install debian/libavg.pth into /usr/share/pyshared/ .
+ (Closes: #575551)
+ * Add get-orig-source target to debian/rules.
+
+ -- Torsten Werner <twerner@debian.org> Sun, 02 May 2010 23:50:04 +0200
+
+libavg (0.8.0-7) unstable; urgency=low
+
+ * Support all python versions; not just 2.5.
+ * Convert patches to dep3 format.
+ * Do no longer link with $py_localmodlibs. (Closes: #567144)
+ * Add Build-Depends: automake1.10 and run ./bootstrap before ./configure.
+ * Change Standards-Version: 3.8.4 (no changes).
+ * Switch to source format 3.0.
+
+ -- Torsten Werner <twerner@debian.org> Sat, 20 Mar 2010 22:22:05 +0100
+
+libavg (0.8.0-6) unstable; urgency=low
+
+ * Update library name for newer libboost-python-dev. (Closes: #545601)
+
+ -- Torsten Werner <twerner@debian.org> Wed, 09 Sep 2009 17:24:36 +0200
+
+libavg (0.8.0-5) unstable; urgency=low
+
+ * Configure library boost_thread-mt.
+ * Add suffix '-mt' to boost_python.
+ * Add Depends: ${misc:Depends}.
+ * Bump up Standards-Version: 3.8.1 (no changes).
+
+ -- Torsten Werner <twerner@debian.org> Mon, 11 May 2009 20:54:25 +0200
+
+libavg (0.8.0-4) unstable; urgency=low
+
+ * Add patch avg_namespace.diff; thanks to Luca Falavigna. (Closes: #520730)
+
+ -- Torsten Werner <twerner@debian.org> Wed, 01 Apr 2009 22:33:58 +0200
+
+libavg (0.8.0-3) unstable; urgency=low
+
+ * Add patch ffmpeg-includes.diff; thanks to Reinhard Tartler. (Closes:
+ #516951)
+
+ -- Torsten Werner <twerner@debian.org> Tue, 24 Feb 2009 22:26:54 +0100
+
+libavg (0.8.0-2) unstable; urgency=low
+
+ * Add patch gcc-4.4.diff provided by Martin Michlmayr.
+ (Closes: #505593)
+
+ -- Torsten Werner <twerner@debian.org> Fri, 14 Nov 2008 00:32:16 +0100
+
+libavg (0.8.0-1) unstable; urgency=low
+
+ * new upstream release
+ - Uses GraphicsMagick++ instead of ImageMagick++. (Closes: #485895)
+ - Does no longer support python 2.4.
+ * Remove patch libavg_gcc-4.3.diff because it is not needed any more.
+ * Remove .py extension from scripts installed into /usr/bin.
+
+ -- Torsten Werner <twerner@debian.org> Tue, 07 Oct 2008 22:49:40 +0200
+
+libavg (0.7.0-9) unstable; urgency=low
+
+ * Add missing Build-Depends: libswscale-dev. (Closes: #487644)
+ * Bump up Standards-Version: 3.8.0 (no changes needed).
+
+ -- Torsten Werner <twerner@debian.org> Fri, 15 Aug 2008 17:15:47 +0200
+
+libavg (0.7.0-8) unstable; urgency=medium
+
+ * Change Build-Depends: libdc1394-22-dev.
+
+ -- Torsten Werner <twerner@debian.org> Sun, 20 Jul 2008 23:14:49 +0200
+
+libavg (0.7.0-7) unstable; urgency=high
+
+ * Remove Build-Depends: liblzo-dev; thanks to Andreas Henriksson.
+ (Closes: #485914)
+
+ -- Torsten Werner <twerner@debian.org> Tue, 24 Jun 2008 23:37:17 +0200
+
+libavg (0.7.0-6) unstable; urgency=low
+
+ * Support both python 2.4 and 2.5.
+ * Build-Depend on a recent libboost-python-dev.
+ * Clean up Build-Depends on libmagick++.
+
+ -- Torsten Werner <twerner@debian.org> Sun, 23 Mar 2008 09:22:14 +0100
+
+libavg (0.7.0-5) unstable; urgency=low
+
+ * Add a patch from Cyril Brulebois to support g++ 4.3. (Closes: #455436)
+ * Make debian/copyright more verbose.
+ * Replace python by Python in description of the package.
+
+ -- Torsten Werner <twerner@debian.org> Fri, 07 Mar 2008 20:57:39 +0100
+
+libavg (0.7.0-4) unstable; urgency=low
+
+ * Update Homepage and Vcs fields.
+ * Set Standards-Version: 3.7.3.
+ * Remove redundant Build-Depends: python-all-dev.
+ * Install libavg.pth into the correct directory.
+ * Remove empty directory /usr/share/avg.
+
+ -- Torsten Werner <twerner@debian.org> Mon, 07 Jan 2008 21:14:49 +0100
+
+libavg (0.7.0-3) unstable; urgency=low
+
+ * Ignore errors from 'make check' because they are probably errors of the
+ buildd environment. (Closes: #447246)
+
+ -- Torsten Werner <twerner@debian.org> Sun, 09 Dec 2007 21:22:36 +0100
+
+libavg (0.7.0-2) unstable; urgency=low
+
+ * Remove the last patch because it is not needed anymore.
+ * Enable 'make check' during the build process.
+
+ -- Torsten Werner <twerner@debian.org> Tue, 02 Oct 2007 20:07:26 +0200
+
+libavg (0.7.0-1) unstable; urgency=low
+
+ * New upstream version
+ * Fix debian/watch to reflect the changes of the website.
+ * Remove patches that have been applied upstream.
+ * Refresh one remaining patch.
+ * Add missing Build-Depends: libboost-thread-dev.
+ * Do not run the autotools any more and remove the Build-Depends.
+ * Switch back to python 2.4 because boost has been built with that version.
+ * Do no longer specify BOOST_LIBS as an argument to configure because it is
+ not needed any more.
+
+ -- Torsten Werner <twerner@debian.org> Tue, 18 Sep 2007 19:10:28 +0200
+
+libavg (0.6.0-6) unstable; urgency=low
+
+ * Add a patch for newer ffmpeg provided by Ulrich von Zadow.
+ (Closes: #427202)
+ * Add patch from Martin Michlmayr for gcc-4.3. (Closes: #417357)
+
+ -- Torsten Werner <twerner@debian.org> Sat, 30 Jun 2007 09:20:54 +0200
+
+libavg (0.6.0-5) unstable; urgency=low
+
+ * Fix linking the boost_python library.
+
+ -- Torsten Werner <twerner@debian.org> Sun, 20 May 2007 13:55:49 +0200
+
+libavg (0.6.0-4) unstable; urgency=low
+
+ * Switch to new boost packages and python 2.5.
+ * Switch to debhelper 5.
+
+ -- Torsten Werner <twerner@debian.org> Sun, 20 May 2007 09:01:22 +0200
+
+libavg (0.6.0-3) unstable; urgency=low
+
+ * Add file /usr/lib/python2.4/site-packages/libavg.pth.
+
+ -- Torsten Werner <twerner@debian.org> Thu, 18 Jan 2007 07:22:37 +0100
+
+libavg (0.6.0-2) unstable; urgency=low
+
+ * Switch from dh_python to python-central.
+ * Add XS-X-Vcs-Svn header and Homepage to debian/control.
+
+ -- Torsten Werner <twerner@debian.org> Fri, 8 Dec 2006 14:25:40 +0100
+
+libavg (0.6.0-1) experimental; urgency=low
+
+ * New upstream release.
+ * Uploading to experimental.
+ * Removing all patches because they are not needed anymore.
+ * Do not run automake anymore.
+
+ -- Torsten Werner <twerner@debian.org> Sun, 5 Nov 2006 14:43:11 +0100
+
+libavg (0.5.9-4) unstable; urgency=low
+
+ * move patches/ directory into debian/ directory where cdbs expects it
+ * add patch 64bit.diff from upstream that fixes compilation errors on 64bit
+ platforms, closes: #386619
+ * add debian/pycompat (policy version 1)
+
+ -- Torsten Werner <twerner@debian.org> Sat, 9 Sep 2006 21:35:54 +0200
+
+libavg (0.5.9-3) unstable; urgency=low
+
+ * remove reference to www.debian-multimedia.org from package description
+
+ -- Torsten Werner <twerner@debian.org> Mon, 28 Aug 2006 07:06:46 +0200
+
+libavg (0.5.9-2) unstable; urgency=low
+
+ * uses libtool now; fixes non PIC code (patch sent to upstream author)
+ * add checks to debian/rules (still commented out)
+ * add patch for 'make check'
+ * removed any non-free Build-Depends and move the package from contrib to
+ main
+ * set Architecture back to any because it should be possible to autobuild
+ the package now
+ * removed stuff specific to the python 2.4 transition that has happened
+ finally
+ * add a cosmetic patch pkg-config.diff which is intended to be sent to the
+ upstream author
+
+ -- Torsten Werner <twerner@debian.org> Sun, 27 Aug 2006 23:25:58 +0200
+
+libavg (0.5.9-1) unstable; urgency=low
+
+ * fixed debian/watch
+ * new upstream release
+ * set Architecture to i386 because the package does not get autobuilded
+ * add patch for gcc 4.1.1 from Alexander Baldeck
+ * lintian fixes
+
+ -- Torsten Werner <twerner@debian.org> Sat, 12 Aug 2006 11:03:24 +0200
+
+libavg (0.5.7-1) experimental; urgency=low
+
+ * new upstream version
+ * set Standards-Version to 3.7.2, no changes needed
+ * use dh_python
+ * exclude avg.so from dh_makeshlibs
+ * documented the packages from debian-multimedia.org which are needed to
+ build libavg, closes: #376424
+ * minor lintian fixes
+ * updated description in debian/control
+ * upload to experimental because of the python2.4 transition
+ * add patch gcc.diff for newer gccs
+
+ -- Torsten Werner <twerner@debian.org> Tue, 11 Jul 2006 21:20:09 +0200
+
+libavg (0.5.4-1) unstable; urgency=low
+
+ * New upstream release
+ * final switch to pkg-config
+ * changed Build-Depends: libavcodeccvs51-dev | libavcodeccvs-dev | libavcodec2-dev
+ * added a lot of Build-Depends
+ * removed old autoconf changes
+
+ -- Torsten Werner <twerner@debian.org> Sun, 23 Apr 2006 19:22:04 +0200
+
+libavg (0.5.3-1) unstable; urgency=low
+
+ * new upstream
+ * switched from Magick++-config to pkg-config, closes: #347407
+
+ -- Torsten Werner <twerner@debian.org> Sat, 14 Jan 2006 12:37:39 +0100
+
+libavg (0.2.0-2) unstable; urgency=low
+
+ * changed Build-Depends: libmagick++9-dev | libmagick++6-dev,
+ closes: #341817
+ * added hint to Christian Marillat's archive to README.Debian,
+ closes: #332522
+ * changed Build-Depends: libavcodeccvs-dev | libavcodec2-dev
+ * some small lintian cleanups
+
+ -- Torsten Werner <twerner@debian.org> Sun, 4 Dec 2005 17:42:35 +0100
+
+libavg (0.2.0-1) unstable; urgency=low
+
+ * Initial Release, closes: #329429
+
+ -- Torsten Werner <twerner@debian.org> Wed, 21 Sep 2005 21:13:19 +0200
diff --git a/debian/compat b/debian/compat
new file mode 100644
index 0000000..ec63514
--- /dev/null
+++ b/debian/compat
@@ -0,0 +1 @@
+9
diff --git a/debian/control b/debian/control
new file mode 100644
index 0000000..0f9d094
--- /dev/null
+++ b/debian/control
@@ -0,0 +1,39 @@
+Source: libavg
+Section: python
+Priority: optional
+Maintainer: Dimitri John Ledkov <xnox@debian.org>
+Build-Depends: debhelper (>= 9),
+ dh-autoreconf,
+ libavcodec-dev,
+ libavformat-dev,
+ libavresample-dev,
+ libboost-python-dev (>= 1.34.1-8),
+ libboost-thread-dev,
+ libboost-system-dev,
+ libdc1394-22-dev [linux-any],
+ libvdpau-dev,
+ libgdk-pixbuf2.0-dev,
+ libgraphicsmagick++1-dev,
+ libmtdev-dev,
+ libpango1.0-dev,
+ librsvg2-dev,
+ libsdl1.2-dev,
+ libswscale-dev,
+ libtool,
+ libxi-dev (>= 2:1.4.1-1ubuntu1),
+ libxml2-dev,
+ libxxf86vm-dev,
+ python-all-dev (>= 2.6.6-3~)
+X-Python-Version: >= 2.6
+Homepage: http://www.libavg.de
+Standards-Version: 3.9.3
+
+Package: python-libavg
+Architecture: any
+Depends: ${misc:Depends}, ${python:Depends}, ${shlibs:Depends}
+Provides: ${python:Provides}
+Description: High-level development platform for media-centric applications
+ libavg is a high-level development platform for media-centric applications.
+ It uses an xml-based layout language for screen design and Python as scripting
+ language. libavg allows developers and media artists/designers to quickly
+ develop media applications.
diff --git a/debian/copyright b/debian/copyright
new file mode 100644
index 0000000..06e3f87
--- /dev/null
+++ b/debian/copyright
@@ -0,0 +1,45 @@
+Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
+Upstream-Name: libavg
+Upstream-Contact: Ulrich von Zadow <uzadow@libavg.de>,
+ OXullo Intersecans <x@brainrapers.org>
+Source: http://www.libavg.de/download.php
+
+Files: debian/*
+Copyright: 2005 Torsten Werner <twerner@debian.org>,
+ 2011-2012 OXullo Intersecans <x@brainrapers.org>,
+ 2012 Dmitrijs Ledkovs <xnox@debian.org>
+License: GPL-2+
+ On Debian systems, the full text of the GNU General Public License version 2 can
+ be found in the file `/usr/share/common-licenses/GPL-2'.
+
+Files: src/oscpack/*
+Copyright: 2004-2005 Ross Bencina <rossb@audiomulch.com>
+License: MIT/X11 (BSD like)
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files
+ (the "Software"), to deal in the Software without restriction,
+ including without limitation the rights to use, copy, modify, merge,
+ publish, distribute, sublicense, and/or sell copies of the Software,
+ and to permit persons to whom the Software is furnished to do so,
+ subject to the following conditions:
+ .
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+ .
+ Any person wishing to distribute modifications to the Software is
+ requested to send the modifications to the original developer so that
+ they can be incorporated into the canonical version.
+ .
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Files: *
+Copyright: 2003-2011 Ulrich von Zadow <uzadow@libavg.de>
+License: LGPL-2.1+
+ On Debian systems, the full text of the GNU Lesser General Public License
+ version 2.1 can be found in the file `/usr/share/common-licenses/LGPL-2.1'.
diff --git a/debian/install b/debian/install
new file mode 100644
index 0000000..55c5393
--- /dev/null
+++ b/debian/install
@@ -0,0 +1,2 @@
+debian/libavg.pth /usr/share/pyshared/
+src/avgrc /etc/
diff --git a/debian/libavg.pth b/debian/libavg.pth
new file mode 100644
index 0000000..dc7191a
--- /dev/null
+++ b/debian/libavg.pth
@@ -0,0 +1 @@
+libavg
diff --git a/debian/links b/debian/links
new file mode 100644
index 0000000..c713e54
--- /dev/null
+++ b/debian/links
@@ -0,0 +1 @@
+usr/lib/python2.7/dist-packages/libavg/avg.so usr/lib/python2.7/dist-packages/libavg/avg.so.0
diff --git a/debian/patches/foreign.patch b/debian/patches/foreign.patch
new file mode 100644
index 0000000..2f9a488
--- /dev/null
+++ b/debian/patches/foreign.patch
@@ -0,0 +1,19 @@
+Description: specify in configure that this is a foreign package
+Author: Dimitri John Ledkov <xnox@ubuntu.com>
+
+--- a/configure.ac
++++ b/configure.ac
+@@ -1,4 +1,3 @@
+-
+ AC_PREREQ(2.53)
+
+ dnl Use this file to bump version on release
+@@ -19,7 +18,7 @@
+
+ AC_CONFIG_MACRO_DIR([m4])
+ AC_CONFIG_SRCDIR([src/avgconfig.h.in])
+-AM_INIT_AUTOMAKE([check-news dist-zip])
++AM_INIT_AUTOMAKE([check-news dist-zip foreign])
+ m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])])
+ # Checks for programs.
+ AC_PROG_CXX
diff --git a/debian/patches/series b/debian/patches/series
new file mode 100644
index 0000000..d3b650a
--- /dev/null
+++ b/debian/patches/series
@@ -0,0 +1 @@
+foreign.patch
diff --git a/debian/python-libavg.examples b/debian/python-libavg.examples
new file mode 100644
index 0000000..7982f8e
--- /dev/null
+++ b/debian/python-libavg.examples
@@ -0,0 +1,5 @@
+src/samples/*.py
+src/samples/*.avg
+src/samples/*.png
+src/samples/*.avi
+
diff --git a/debian/rules b/debian/rules
new file mode 100755
index 0000000..4d78926
--- /dev/null
+++ b/debian/rules
@@ -0,0 +1,18 @@
+#!/usr/bin/make -f
+
+%:
+ dh $@ --with autoreconf,python2 --parallel
+
+override_dh_installman:
+ dh_installman debian/*.1
+
+override_dh_auto_test:
+ -dh_auto_test
+
+override_dh_shlibdeps:
+ dh_shlibdeps -l/usr/lib/python2.7/dist-packages/libavg/
+
+override_dh_install:
+ dh_install
+ prename -f 's/\.py$$//' ./debian/python-libavg/usr/bin/avg_*.py
+ find debian/python-libavg/ -name '*.la' -delete
diff --git a/debian/source/format b/debian/source/format
new file mode 100644
index 0000000..163aaf8
--- /dev/null
+++ b/debian/source/format
@@ -0,0 +1 @@
+3.0 (quilt)
diff --git a/debian/watch b/debian/watch
new file mode 100644
index 0000000..8f365be
--- /dev/null
+++ b/debian/watch
@@ -0,0 +1,2 @@
+version=3
+http://www.libavg.de/raw-attachment/wiki/DownLoad/ libavg-(\d+.\d+.\d+).tar.gz
diff --git a/depcomp b/depcomp
new file mode 100755
index 0000000..aea3d00
--- /dev/null
+++ b/depcomp
@@ -0,0 +1,472 @@
+#! /bin/sh
+
+# depcomp - compile a program generating dependencies as side-effects
+# Copyright 1999, 2000 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
+
+if test -z "$depmode" || test -z "$source" || test -z "$object"; then
+ echo "depcomp: Variables source, object and depmode must be set" 1>&2
+ exit 1
+fi
+# `libtool' can also be set to `yes' or `no'.
+
+if test -z "$depfile"; then
+ base=`echo "$object" | sed -e 's,^.*/,,' -e 's,\.\([^.]*\)$,.P\1,'`
+ dir=`echo "$object" | sed 's,/.*$,/,'`
+ if test "$dir" = "$object"; then
+ dir=
+ fi
+ # FIXME: should be _deps on DOS.
+ depfile="$dir.deps/$base"
+fi
+
+tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
+
+rm -f "$tmpdepfile"
+
+# Some modes work just like other modes, but use different flags. We
+# parameterize here, but still list the modes in the big case below,
+# to make depend.m4 easier to write. Note that we *cannot* use a case
+# here, because this file can only contain one case statement.
+if test "$depmode" = hp; then
+ # HP compiler uses -M and no extra arg.
+ gccflag=-M
+ depmode=gcc
+fi
+
+if test "$depmode" = dashXmstdout; then
+ # This is just like dashmstdout with a different argument.
+ dashmflag=-xM
+ depmode=dashmstdout
+fi
+
+case "$depmode" in
+gcc3)
+## gcc 3 implements dependency tracking that does exactly what
+## we want. Yay! Note: for some reason libtool 1.4 doesn't like
+## it if -MD -MP comes after the -MF stuff. Hmm.
+ "$@" -MT "$object" -MD -MP -MF "$tmpdepfile"
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ mv "$tmpdepfile" "$depfile"
+ ;;
+
+gcc)
+## There are various ways to get dependency output from gcc. Here's
+## why we pick this rather obscure method:
+## - Don't want to use -MD because we'd like the dependencies to end
+## up in a subdir. Having to rename by hand is ugly.
+## (We might end up doing this anyway to support other compilers.)
+## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
+## -MM, not -M (despite what the docs say).
+## - Using -M directly means running the compiler twice (even worse
+## than renaming).
+ if test -z "$gccflag"; then
+ gccflag=-MD,
+ fi
+ "$@" -Wp,"$gccflag$tmpdepfile"
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
+## The second -e expression handles DOS-style file names with drive letters.
+ sed -e 's/^[^:]*: / /' \
+ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
+## This next piece of magic avoids the `deleted header file' problem.
+## The problem is that when a header file which appears in a .P file
+## is deleted, the dependency causes make to die (because there is
+## typically no way to rebuild the header). We avoid this by adding
+## dummy dependencies for each header file. Too bad gcc doesn't do
+## this for us directly.
+ tr ' ' '
+' < "$tmpdepfile" |
+## Some versions of gcc put a space before the `:'. On the theory
+## that the space means something, we add a space to the output as
+## well.
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly. Breaking it into two sed invocations is a workaround.
+ sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+hp)
+ # This case exists only to let depend.m4 do its work. It works by
+ # looking at the text of this script. This case will never be run,
+ # since it is checked for above.
+ exit 1
+ ;;
+
+sgi)
+ if test "$libtool" = yes; then
+ "$@" "-Wp,-MDupdate,$tmpdepfile"
+ else
+ "$@" -MDupdate "$tmpdepfile"
+ fi
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+
+ if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
+ echo "$object : \\" > "$depfile"
+
+ # Clip off the initial element (the dependent). Don't try to be
+ # clever and replace this with sed code, as IRIX sed won't handle
+ # lines with more than a fixed number of characters (4096 in
+ # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
+ # the IRIX cc adds comments like `#:fec' to the end of the
+ # dependency line.
+ tr ' ' '
+' < "$tmpdepfile" \
+ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
+ tr '
+' ' ' >> $depfile
+ echo >> $depfile
+
+ # The second pass generates a dummy entry for each header file.
+ tr ' ' '
+' < "$tmpdepfile" \
+ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
+ >> $depfile
+ else
+ # The sourcefile does not contain any dependencies, so just
+ # store a dummy comment line, to avoid errors with the Makefile
+ # "include basename.Plo" scheme.
+ echo "#dummy" > "$depfile"
+ fi
+ rm -f "$tmpdepfile"
+ ;;
+
+aix)
+ # The C for AIX Compiler uses -M and outputs the dependencies
+ # in a .u file. This file always lives in the current directory.
+ # Also, the AIX compiler puts `$object:' at the start of each line;
+ # $object doesn't have directory information.
+ stripped=`echo "$object" | sed -e 's,^.*/,,' -e 's/\(.*\)\..*$/\1/'`
+ tmpdepfile="$stripped.u"
+ outname="$stripped.o"
+ if test "$libtool" = yes; then
+ "$@" -Wc,-M
+ else
+ "$@" -M
+ fi
+
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+
+ if test -f "$tmpdepfile"; then
+ # Each line is of the form `foo.o: dependent.h'.
+ # Do two passes, one to just change these to
+ # `$object: dependent.h' and one to simply `dependent.h:'.
+ sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile"
+ sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile"
+ else
+ # The sourcefile does not contain any dependencies, so just
+ # store a dummy comment line, to avoid errors with the Makefile
+ # "include basename.Plo" scheme.
+ echo "#dummy" > "$depfile"
+ fi
+ rm -f "$tmpdepfile"
+ ;;
+
+icc)
+ # Intel's C compiler understands `-MD -MF file'. However on
+ # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c
+ # ICC 7.0 will fill foo.d with something like
+ # foo.o: sub/foo.c
+ # foo.o: sub/foo.h
+ # which is wrong. We want:
+ # sub/foo.o: sub/foo.c
+ # sub/foo.o: sub/foo.h
+ # sub/foo.c:
+ # sub/foo.h:
+ # ICC 7.1 will output
+ # foo.o: sub/foo.c sub/foo.h
+ # and will wrap long lines using \ :
+ # foo.o: sub/foo.c ... \
+ # sub/foo.h ... \
+ # ...
+
+ "$@" -MD -MF "$tmpdepfile"
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+ # Each line is of the form `foo.o: dependent.h',
+ # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
+ # Do two passes, one to just change these to
+ # `$object: dependent.h' and one to simply `dependent.h:'.
+ sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
+ # Some versions of the HPUX 10.20 sed can't process this invocation
+ # correctly. Breaking it into two sed invocations is a workaround.
+ sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" |
+ sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+tru64)
+ # The Tru64 compiler uses -MD to generate dependencies as a side
+ # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
+ # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
+ # dependencies in `foo.d' instead, so we check for that too.
+ # Subdirectories are respected.
+ dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
+ test "x$dir" = "x$object" && dir=
+ base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
+
+ if test "$libtool" = yes; then
+ tmpdepfile1="$dir.libs/$base.lo.d"
+ tmpdepfile2="$dir.libs/$base.d"
+ "$@" -Wc,-MD
+ else
+ tmpdepfile1="$dir$base.o.d"
+ tmpdepfile2="$dir$base.d"
+ "$@" -MD
+ fi
+
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile1" "$tmpdepfile2"
+ exit $stat
+ fi
+
+ if test -f "$tmpdepfile1"; then
+ tmpdepfile="$tmpdepfile1"
+ else
+ tmpdepfile="$tmpdepfile2"
+ fi
+ if test -f "$tmpdepfile"; then
+ sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
+ # That's a space and a tab in the [].
+ sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
+ else
+ echo "#dummy" > "$depfile"
+ fi
+ rm -f "$tmpdepfile"
+ ;;
+
+#nosideeffect)
+ # This comment above is used by automake to tell side-effect
+ # dependency tracking mechanisms from slower ones.
+
+dashmstdout)
+ # Important note: in order to support this mode, a compiler *must*
+ # always write the proprocessed file to stdout, regardless of -o.
+ "$@" || exit $?
+
+ # Remove the call to Libtool.
+ if test "$libtool" = yes; then
+ while test $1 != '--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+
+ # Remove `-o $object'.
+ IFS=" "
+ for arg
+ do
+ case $arg in
+ -o)
+ shift
+ ;;
+ $object)
+ shift
+ ;;
+ *)
+ set fnord "$@" "$arg"
+ shift # fnord
+ shift # $arg
+ ;;
+ esac
+ done
+
+ test -z "$dashmflag" && dashmflag=-M
+ # Require at least two characters before searching for `:'
+ # in the target name. This is to cope with DOS-style filenames:
+ # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise.
+ "$@" $dashmflag |
+ sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile"
+ rm -f "$depfile"
+ cat < "$tmpdepfile" > "$depfile"
+ tr ' ' '
+' < "$tmpdepfile" | \
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly. Breaking it into two sed invocations is a workaround.
+ sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+dashXmstdout)
+ # This case only exists to satisfy depend.m4. It is never actually
+ # run, as this mode is specially recognized in the preamble.
+ exit 1
+ ;;
+
+makedepend)
+ "$@" || exit $?
+ # Remove any Libtool call
+ if test "$libtool" = yes; then
+ while test $1 != '--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+ # X makedepend
+ shift
+ cleared=no
+ for arg in "$@"; do
+ case $cleared in
+ no)
+ set ""; shift
+ cleared=yes ;;
+ esac
+ case "$arg" in
+ -D*|-I*)
+ set fnord "$@" "$arg"; shift ;;
+ # Strip any option that makedepend may not understand. Remove
+ # the object too, otherwise makedepend will parse it as a source file.
+ -*|$object)
+ ;;
+ *)
+ set fnord "$@" "$arg"; shift ;;
+ esac
+ done
+ obj_suffix="`echo $object | sed 's/^.*\././'`"
+ touch "$tmpdepfile"
+ ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
+ rm -f "$depfile"
+ cat < "$tmpdepfile" > "$depfile"
+ sed '1,2d' "$tmpdepfile" | tr ' ' '
+' | \
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly. Breaking it into two sed invocations is a workaround.
+ sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile" "$tmpdepfile".bak
+ ;;
+
+cpp)
+ # Important note: in order to support this mode, a compiler *must*
+ # always write the proprocessed file to stdout.
+ "$@" || exit $?
+
+ # Remove the call to Libtool.
+ if test "$libtool" = yes; then
+ while test $1 != '--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+
+ # Remove `-o $object'.
+ IFS=" "
+ for arg
+ do
+ case $arg in
+ -o)
+ shift
+ ;;
+ $object)
+ shift
+ ;;
+ *)
+ set fnord "$@" "$arg"
+ shift # fnord
+ shift # $arg
+ ;;
+ esac
+ done
+
+ "$@" -E |
+ sed -n '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
+ sed '$ s: \\$::' > "$tmpdepfile"
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ cat < "$tmpdepfile" >> "$depfile"
+ sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+msvisualcpp)
+ # Important note: in order to support this mode, a compiler *must*
+ # always write the proprocessed file to stdout, regardless of -o,
+ # because we must use -o when running libtool.
+ "$@" || exit $?
+ IFS=" "
+ for arg
+ do
+ case "$arg" in
+ "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
+ set fnord "$@"
+ shift
+ shift
+ ;;
+ *)
+ set fnord "$@" "$arg"
+ shift
+ shift
+ ;;
+ esac
+ done
+ "$@" -E |
+ sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile"
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile"
+ echo " " >> "$depfile"
+ . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+none)
+ exec "$@"
+ ;;
+
+*)
+ echo "Unknown depmode $depmode" 1>&2
+ exit 1
+ ;;
+esac
+
+exit 0
diff --git a/fixcopyright.py b/fixcopyright.py
new file mode 100755
index 0000000..2c0ba1d
--- /dev/null
+++ b/fixcopyright.py
@@ -0,0 +1,32 @@
+#!/usr/bin/env python
+
+import os
+import re
+
+def handleFile(path):
+ lines = file(path).readlines()
+ lineNumber = 0
+ found = False
+ for i, line in enumerate(lines):
+ match = re.match(r'((//)|(#))\s*Copyright \(C\) 2003-(.*) Ulrich von Zadow\s*', line)
+# m = re.match(r'#include\s*["<]([\-_a-zA-Z0-9\.\\/]+)[">]\s*', l)
+ if match:
+ if path[-2:] == 'py':
+ lines[i] = "# Copyright (C) 2003-2014 Ulrich von Zadow\n"
+ else:
+ lines[i] = "// Copyright (C) 2003-2014 Ulrich von Zadow\n"
+ found = True
+ if found:
+ outFile = open(path, "w")
+ for line in lines:
+ outFile.write(line)
+ else:
+ print path
+
+
+for ext in ("h", "c", "cpp", "py"):
+ cmd = 'find . -name "*.'+ext+'"'
+ files = os.popen(cmd).readlines()
+ for f in files:
+ handleFile(f.strip())
+
diff --git a/install-sh b/install-sh
new file mode 100755
index 0000000..6ce63b9
--- /dev/null
+++ b/install-sh
@@ -0,0 +1,294 @@
+#!/bin/sh
+#
+# install - install a program, script, or datafile
+#
+# This originates from X11R5 (mit/util/scripts/install.sh), which was
+# later released in X11R6 (xc/config/util/install.sh) with the
+# following copyright and license.
+#
+# Copyright (C) 1994 X Consortium
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
+# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+# Except as contained in this notice, the name of the X Consortium shall not
+# be used in advertising or otherwise to promote the sale, use or other deal-
+# ings in this Software without prior written authorization from the X Consor-
+# tium.
+#
+#
+# FSF changes to this file are in the public domain.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch. It can only install one file at a time, a restriction
+# shared with many OS's install programs.
+
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+transformbasename=""
+transform_arg=""
+instcmd="$mvprog"
+chmodcmd="$chmodprog 0755"
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+dir_arg=""
+
+while [ x"$1" != x ]; do
+ case $1 in
+ -c) instcmd=$cpprog
+ shift
+ continue;;
+
+ -d) dir_arg=true
+ shift
+ continue;;
+
+ -m) chmodcmd="$chmodprog $2"
+ shift
+ shift
+ continue;;
+
+ -o) chowncmd="$chownprog $2"
+ shift
+ shift
+ continue;;
+
+ -g) chgrpcmd="$chgrpprog $2"
+ shift
+ shift
+ continue;;
+
+ -s) stripcmd=$stripprog
+ shift
+ continue;;
+
+ -t=*) transformarg=`echo $1 | sed 's/-t=//'`
+ shift
+ continue;;
+
+ -b=*) transformbasename=`echo $1 | sed 's/-b=//'`
+ shift
+ continue;;
+
+ *) if [ x"$src" = x ]
+ then
+ src=$1
+ else
+ # this colon is to work around a 386BSD /bin/sh bug
+ :
+ dst=$1
+ fi
+ shift
+ continue;;
+ esac
+done
+
+if [ x"$src" = x ]
+then
+ echo "$0: no input file specified" >&2
+ exit 1
+else
+ :
+fi
+
+if [ x"$dir_arg" != x ]; then
+ dst=$src
+ src=""
+
+ if [ -d "$dst" ]; then
+ instcmd=:
+ chmodcmd=""
+ else
+ instcmd=$mkdirprog
+ fi
+else
+
+# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
+# might cause directories to be created, which would be especially bad
+# if $src (and thus $dsttmp) contains '*'.
+
+ if [ -f "$src" ] || [ -d "$src" ]
+ then
+ :
+ else
+ echo "$0: $src does not exist" >&2
+ exit 1
+ fi
+
+ if [ x"$dst" = x ]
+ then
+ echo "$0: no destination specified" >&2
+ exit 1
+ else
+ :
+ fi
+
+# If destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+ if [ -d "$dst" ]
+ then
+ dst=$dst/`basename "$src"`
+ else
+ :
+ fi
+fi
+
+## this sed command emulates the dirname command
+dstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
+
+# Make sure that the destination directory exists.
+# this part is taken from Noah Friedman's mkinstalldirs script
+
+# Skip lots of stat calls in the usual case.
+if [ ! -d "$dstdir" ]; then
+defaultIFS='
+ '
+IFS="${IFS-$defaultIFS}"
+
+oIFS=$IFS
+# Some sh's can't handle IFS=/ for some reason.
+IFS='%'
+set - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'`
+IFS=$oIFS
+
+pathcomp=''
+
+while [ $# -ne 0 ] ; do
+ pathcomp=$pathcomp$1
+ shift
+
+ if [ ! -d "$pathcomp" ] ;
+ then
+ $mkdirprog "$pathcomp"
+ else
+ :
+ fi
+
+ pathcomp=$pathcomp/
+done
+fi
+
+if [ x"$dir_arg" != x ]
+then
+ $doit $instcmd "$dst" &&
+
+ if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dst"; else : ; fi &&
+ if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dst"; else : ; fi &&
+ if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dst"; else : ; fi &&
+ if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dst"; else : ; fi
+else
+
+# If we're going to rename the final executable, determine the name now.
+
+ if [ x"$transformarg" = x ]
+ then
+ dstfile=`basename "$dst"`
+ else
+ dstfile=`basename "$dst" $transformbasename |
+ sed $transformarg`$transformbasename
+ fi
+
+# don't allow the sed command to completely eliminate the filename
+
+ if [ x"$dstfile" = x ]
+ then
+ dstfile=`basename "$dst"`
+ else
+ :
+ fi
+
+# Make a couple of temp file names in the proper directory.
+
+ dsttmp=$dstdir/_inst.$$_
+ rmtmp=$dstdir/_rm.$$_
+
+# Trap to clean up temp files at exit.
+
+ trap 'status=$?; rm -f "$dsttmp" "$rmtmp" && exit $status' 0
+ trap '(exit $?); exit' 1 2 13 15
+
+# Move or copy the file name to the temp name
+
+ $doit $instcmd "$src" "$dsttmp" &&
+
+# and set any options; do chmod last to preserve setuid bits
+
+# If any of these fail, we abort the whole thing. If we want to
+# ignore errors from any of these, just make sure not to ignore
+# errors from the above "$doit $instcmd $src $dsttmp" command.
+
+ if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dsttmp"; else :;fi &&
+ if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dsttmp"; else :;fi &&
+ if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dsttmp"; else :;fi &&
+ if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dsttmp"; else :;fi &&
+
+# Now remove or move aside any old file at destination location. We try this
+# two ways since rm can't unlink itself on some systems and the destination
+# file might be busy for other reasons. In this case, the final cleanup
+# might fail but the new file should still install successfully.
+
+{
+ if [ -f "$dstdir/$dstfile" ]
+ then
+ $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null ||
+ $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null ||
+ {
+ echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2
+ (exit 1); exit
+ }
+ else
+ :
+ fi
+} &&
+
+# Now rename the file to the real destination.
+
+ $doit $mvcmd "$dsttmp" "$dstdir/$dstfile"
+
+fi &&
+
+# The final little trick to "correctly" pass the exit status to the exit trap.
+
+{
+ (exit 0); exit
+}
diff --git a/m4/ac_cxx_namespaces.m4 b/m4/ac_cxx_namespaces.m4
new file mode 100644
index 0000000..7001b91
--- /dev/null
+++ b/m4/ac_cxx_namespaces.m4
@@ -0,0 +1,27 @@
+dnl @synopsis AC_CXX_NAMESPACES
+dnl
+dnl If the compiler can prevent names clashes using namespaces, define
+dnl HAVE_NAMESPACES.
+dnl
+dnl @category Cxx
+dnl @author Todd Veldhuizen
+dnl @author Luc Maisonobe <luc@spaceroots.org>
+dnl @version 2004-02-04
+dnl @license AllPermissive
+
+AC_DEFUN([AC_CXX_NAMESPACES],
+[AC_CACHE_CHECK(whether the compiler implements namespaces,
+ac_cv_cxx_namespaces,
+[AC_LANG_SAVE
+ AC_LANG_CPLUSPLUS
+ AC_TRY_COMPILE([namespace Outer { namespace Inner { int i = 0; }}],
+ [using namespace Outer::Inner; return i;],
+ ac_cv_cxx_namespaces=yes, ac_cv_cxx_namespaces=no)
+ AC_LANG_RESTORE
+])
+if test "$ac_cv_cxx_namespaces" = yes; then
+ AC_DEFINE(HAVE_NAMESPACES,,[define if the compiler implements namespaces])
+fi
+])
+
+
diff --git a/m4/ac_path_generic.m4 b/m4/ac_path_generic.m4
new file mode 100644
index 0000000..97d3279
--- /dev/null
+++ b/m4/ac_path_generic.m4
@@ -0,0 +1,140 @@
+dnl @synopsis AC_PATH_GENERIC(LIBRARY [, MINIMUM-VERSION [, ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]])
+dnl
+dnl Runs a LIBRARY-config script and defines LIBRARY_CFLAGS and
+dnl LIBRARY_LIBS
+dnl
+dnl The script must support `--cflags' and `--libs' args. If
+dnl MINIMUM-VERSION is specified, the script must also support the
+dnl `--version' arg. If the `--with-library-[exec-]prefix' arguments to
+dnl ./configure are given, it must also support `--prefix' and
+dnl `--exec-prefix'. (In other words, it must be like gtk-config.)
+dnl
+dnl For example:
+dnl
+dnl AC_PATH_GENERIC(Foo, 1.0.0)
+dnl
+dnl would run `foo-config --version' and check that it is at least
+dnl 1.0.0
+dnl
+dnl If so, the following would then be defined:
+dnl
+dnl FOO_CFLAGS to `foo-config --cflags`
+dnl FOO_LIBS to `foo-config --libs`
+dnl
+dnl At present there is no support for additional "MODULES" (see
+dnl AM_PATH_GTK) (shamelessly stolen from gtk.m4 and then hacked around
+dnl a fair amount)
+dnl
+dnl @category Misc
+dnl @author Angus Lees <gusl@cse.unsw.edu.au>
+dnl @version 2001-03-16
+dnl @license GPLWithACException
+
+AC_DEFUN([AC_PATH_GENERIC],
+[dnl
+dnl we're going to need uppercase, lowercase and user-friendly versions of the
+dnl string `LIBRARY'
+pushdef([UP], translit([$1], [a-z], [A-Z]))dnl
+pushdef([DOWN], translit([$1], [A-Z], [a-z]))dnl
+
+dnl
+dnl Get the cflags and libraries from the LIBRARY-config script
+dnl
+AC_ARG_WITH(DOWN-prefix,[ --with-]DOWN[-prefix=PFX Prefix where $1 is installed (optional)],
+ DOWN[]_config_prefix="$withval", DOWN[]_config_prefix="")
+AC_ARG_WITH(DOWN-exec-prefix,[ --with-]DOWN[-exec-prefix=PFX Exec prefix where $1 is installed (optional)],
+ DOWN[]_config_exec_prefix="$withval", DOWN[]_config_exec_prefix="")
+
+ if test x$DOWN[]_config_exec_prefix != x ; then
+ DOWN[]_config_args="$DOWN[]_config_args --exec-prefix=$DOWN[]_config_exec_prefix"
+ if test x${UP[]_CONFIG+set} != xset ; then
+ UP[]_CONFIG=$DOWN[]_config_exec_prefix/bin/DOWN-config
+ fi
+ fi
+ if test x$DOWN[]_config_prefix != x ; then
+ DOWN[]_config_args="$DOWN[]_config_args --prefix=$DOWN[]_config_prefix"
+ if test x${UP[]_CONFIG+set} != xset ; then
+ UP[]_CONFIG=$DOWN[]_config_prefix/bin/DOWN-config
+ fi
+ fi
+
+ AC_PATH_PROG(UP[]_CONFIG, DOWN-config, no)
+ ifelse([$2], ,
+ AC_MSG_CHECKING(for $1),
+ AC_MSG_CHECKING(for $1 - version >= $2)
+ )
+ no_[]DOWN=""
+ if test "$UP[]_CONFIG" = "no" ; then
+ no_[]DOWN=yes
+ else
+ UP[]_CFLAGS="`$UP[]_CONFIG $DOWN[]_config_args --cflags`"
+ UP[]_LIBS="`$UP[]_CONFIG $DOWN[]_config_args --libs`"
+ ifelse([$2], , ,[
+ DOWN[]_config_major_version=`$UP[]_CONFIG $DOWN[]_config_args \
+ --version | sed 's/[[^0-9]]*\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'`
+ DOWN[]_config_minor_version=`$UP[]_CONFIG $DOWN[]_config_args \
+ --version | sed 's/[[^0-9]]*\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'`
+ DOWN[]_config_micro_version=`$UP[]_CONFIG $DOWN[]_config_args \
+ --version | sed 's/[[^0-9]]*\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'`
+ DOWN[]_wanted_major_version="regexp($2, [\<\([0-9]*\)], [\1])"
+ DOWN[]_wanted_minor_version="regexp($2, [\<\([0-9]*\)\.\([0-9]*\)], [\2])"
+ DOWN[]_wanted_micro_version="regexp($2, [\<\([0-9]*\).\([0-9]*\).\([0-9]*\)], [\3])"
+
+ # Compare wanted version to what config script returned.
+ # If I knew what library was being run, i'd probably also compile
+ # a test program at this point (which also extracted and tested
+ # the version in some library-specific way)
+ if test "$DOWN[]_config_major_version" -lt \
+ "$DOWN[]_wanted_major_version" \
+ -o \( "$DOWN[]_config_major_version" -eq \
+ "$DOWN[]_wanted_major_version" \
+ -a "$DOWN[]_config_minor_version" -lt \
+ "$DOWN[]_wanted_minor_version" \) \
+ -o \( "$DOWN[]_config_major_version" -eq \
+ "$DOWN[]_wanted_major_version" \
+ -a "$DOWN[]_config_minor_version" -eq \
+ "$DOWN[]_wanted_minor_version" \
+ -a "$DOWN[]_config_micro_version" -lt \
+ "$DOWN[]_wanted_micro_version" \) ; then
+ # older version found
+ no_[]DOWN=yes
+ echo -n "*** An old version of $1 "
+ echo -n "($DOWN[]_config_major_version"
+ echo -n ".$DOWN[]_config_minor_version"
+ echo ".$DOWN[]_config_micro_version) was found."
+ echo -n "*** You need a version of $1 newer than "
+ echo -n "$DOWN[]_wanted_major_version"
+ echo -n ".$DOWN[]_wanted_minor_version"
+ echo ".$DOWN[]_wanted_micro_version."
+ echo "***"
+ echo "*** If you have already installed a sufficiently new version, this error"
+ echo "*** probably means that the wrong copy of the DOWN-config shell script is"
+ echo "*** being found. The easiest way to fix this is to remove the old version"
+ echo "*** of $1, but you can also set the UP[]_CONFIG environment to point to the"
+ echo "*** correct copy of DOWN-config. (In this case, you will have to"
+ echo "*** modify your LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf"
+ echo "*** so that the correct libraries are found at run-time)"
+ fi
+ ])
+ fi
+ if test "x$no_[]DOWN" = x ; then
+ AC_MSG_RESULT(yes)
+ ifelse([$3], , :, [$3])
+ else
+ AC_MSG_RESULT(no)
+ if test "$UP[]_CONFIG" = "no" ; then
+ echo "*** The DOWN-config script installed by $1 could not be found"
+ echo "*** If $1 was installed in PREFIX, make sure PREFIX/bin is in"
+ echo "*** your path, or set the UP[]_CONFIG environment variable to the"
+ echo "*** full path to DOWN-config."
+ fi
+ UP[]_CFLAGS=""
+ UP[]_LIBS=""
+ ifelse([$4], , :, [$4])
+ fi
+ AC_SUBST(UP[]_CFLAGS)
+ AC_SUBST(UP[]_LIBS)
+
+ popdef([UP])
+ popdef([DOWN])
+])
diff --git a/m4/avg_version.m4 b/m4/avg_version.m4
new file mode 100644
index 0000000..7ab45b0
--- /dev/null
+++ b/m4/avg_version.m4
@@ -0,0 +1,3 @@
+m4_define([VERSION_MAJOR], [1])
+m4_define([VERSION_MINOR], [8])
+m4_define([VERSION_MICRO], [1])
diff --git a/m4/ax_boost_thread.m4 b/m4/ax_boost_thread.m4
new file mode 100644
index 0000000..9590ee6
--- /dev/null
+++ b/m4/ax_boost_thread.m4
@@ -0,0 +1,72 @@
+dnl @synopsis AX_BOOST_THREAD
+dnl
+dnl This macro checks to see if the Boost.Thread library is installed.
+dnl It also attempts to guess the currect library name using several
+dnl attempts. It tries to build the library name using a user supplied
+dnl name or suffix and then just the raw library.
+dnl
+dnl If the library is found, HAVE_BOOST_THREAD is defined and
+dnl BOOST_THREAD_LIBS is set to the name of the library.
+dnl
+dnl This macro calls AC_SUBST(BOOST_THREAD_LIBS).
+dnl
+dnl @category InstalledPackages
+dnl @author Michael Tindal <mtindal@paradoxpoint.com>
+dnl @version 2004-09-20
+dnl @license GPLWithACException
+
+AC_DEFUN([AX_BOOST_THREAD],
+[AC_REQUIRE([AC_CXX_NAMESPACES])dnl
+
+AC_LANG_SAVE
+AC_LANG_CPLUSPLUS
+CXXFLAGS_SAVE=$CXXFLAGS
+LIBS_SAVE=$LIBS
+dnl FIXME: need to include a generic way to check for the flag
+dnl to turn on threading support.
+CXXFLAGS="-pthread $CXXFLAGS"
+
+AC_CACHE_CHECK(whether the Boost::Thread library is available,
+ax_cv_boost_thread,
+[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <boost/thread/thread.hpp>]],
+ [[boost::thread_group thrds; return 0;]])],
+ ax_cv_boost_thread=yes, ax_cv_boost_thread=no)
+])
+
+if test "$ax_cv_boost_thread" = yes; then
+ AC_DEFINE(HAVE_BOOST_THREAD,,[define if the Boost::Thread library is available])
+ dnl Now determine the appropriate file names
+ AC_ARG_WITH([boost-thread],AS_HELP_STRING([--with-boost-thread],
+ [specify the boost thread library suffix to use]),
+ [if test "x$with_boost_thread" != "xno"; then
+ ax_boost_thread_lib=boost_thread$with_boost_thread
+ fi])
+ for ax_lib in $ax_boost_thread_lib boost_thread boost_thread-mt; do
+ AC_CHECK_LIB($ax_lib, main, [BOOST_THREAD_LIBS=-l$ax_lib; break])
+ done
+
+ # OXullo 2012-07-18: since boost 1.50, boost::thread depends on boost::system
+ AC_CACHE_CHECK(whether Boost::Thread needs Boost::System library,
+ ax_cv_boost_thread_system,
+ [LIBS="$LIBS $BOOST_THREAD_LIBS"
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <boost/thread/thread.hpp>]],
+ [[boost::thread_group thrds; return 0;]])],
+ [ax_cv_boost_thread_system=no],
+ [LIBS="$LIBS $BOOST_THREAD_LIBS -lboost_system$with_boost_thread"
+ AC_LINK_IFELSE([
+ AC_LANG_PROGRAM([[#include <boost/thread/thread.hpp>]],
+ [[boost::thread_group thrds; return 0;]])
+ ],
+ [BOOST_THREAD_LIBS="$BOOST_THREAD_LIBS -lboost_system$with_boost_thread"
+ ax_cv_boost_thread_system=yes],
+ [AC_ERROR([Cannot use Boost::Thread])]
+ )])
+ ])
+
+ CXXFLAGS=$CXXFLAGS_SAVE
+ LIBS=$LIBS_SAVE
+ AC_LANG_RESTORE
+
+ AC_SUBST(BOOST_THREAD_LIBS)
+fi
+])dnl
diff --git a/m4/ax_check_define.m4 b/m4/ax_check_define.m4
new file mode 100644
index 0000000..cb0b5b5
--- /dev/null
+++ b/m4/ax_check_define.m4
@@ -0,0 +1,90 @@
+# ===========================================================================
+# http://www.gnu.org/software/autoconf-archive/ax_check_define.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AC_CHECK_DEFINE([symbol], [ACTION-IF-FOUND], [ACTION-IF-NOT])
+# AX_CHECK_DEFINE([includes],[symbol], [ACTION-IF-FOUND], [ACTION-IF-NOT])
+#
+# DESCRIPTION
+#
+# Complements AC_CHECK_FUNC but it does not check for a function but for a
+# define to exist. Consider a usage like:
+#
+# AC_CHECK_DEFINE(__STRICT_ANSI__, CFLAGS="$CFLAGS -D_XOPEN_SOURCE=500")
+#
+# LICENSE
+#
+# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at your
+# option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+# Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# As a special exception, the respective Autoconf Macro's copyright owner
+# gives unlimited permission to copy, distribute and modify the configure
+# scripts that are the output of Autoconf when processing the Macro. You
+# need not follow the terms of the GNU General Public License when using
+# or distributing such scripts, even though portions of the text of the
+# Macro appear in them. The GNU General Public License (GPL) does govern
+# all other use of the material that constitutes the Autoconf Macro.
+#
+# This special exception to the GPL applies to versions of the Autoconf
+# Macro released by the Autoconf Archive. When you make and distribute a
+# modified version of the Autoconf Macro, you may extend this special
+# exception to the GPL to apply to your modified version as well.
+
+#serial 7
+
+AC_DEFUN([AC_CHECK_DEFINED],[
+AS_VAR_PUSHDEF([ac_var],[ac_cv_defined_$1])dnl
+AC_CACHE_CHECK([for $1 defined], ac_var,
+AC_TRY_COMPILE(,[
+ #ifdef $1
+ int ok;
+ #else
+ choke me
+ #endif
+],AS_VAR_SET(ac_var, yes),AS_VAR_SET(ac_var, no)))
+AS_IF([test AS_VAR_GET(ac_var) != "no"], [$2], [$3])dnl
+AS_VAR_POPDEF([ac_var])dnl
+])
+
+AC_DEFUN([AX_CHECK_DEFINED],[
+AS_VAR_PUSHDEF([ac_var],[ac_cv_defined_$2])dnl
+AC_CACHE_CHECK([for $2 defined], ac_var,
+AC_TRY_COMPILE([#include "$1"],[
+ #ifdef $2
+ int ok;
+ #else
+ choke me
+ #endif
+],AS_VAR_SET(ac_var, yes),AS_VAR_SET(ac_var, no)))
+AS_IF([test AS_VAR_GET(ac_var) != "no"], [$3], [$4])dnl
+AS_VAR_POPDEF([ac_var])dnl
+])
+
+AC_DEFUN([AX_CHECK_FUNC],
+[AS_VAR_PUSHDEF([ac_var], [ac_cv_func_$2])dnl
+AC_CACHE_CHECK([for $2], ac_var,
+dnl AC_LANG_FUNC_LINK_TRY
+[AC_LINK_IFELSE([AC_LANG_PROGRAM([$1
+ #undef $2
+ char $2 ();],[
+ char (*f) () = $2;
+ return f != $2; ])],
+ [AS_VAR_SET(ac_var, yes)],
+ [AS_VAR_SET(ac_var, no)])])
+AS_IF([test AS_VAR_GET(ac_var) = yes], [$3], [$4])dnl
+AS_VAR_POPDEF([ac_var])dnl
+])# AC_CHECK_FUNC
diff --git a/m4/ax_check_gl.m4 b/m4/ax_check_gl.m4
new file mode 100644
index 0000000..124760c
--- /dev/null
+++ b/m4/ax_check_gl.m4
@@ -0,0 +1,335 @@
+# Copied from
+# http://ac-archive.sourceforge.net/
+#
+
+AC_DEFUN([ACX_PTHREAD], [
+AC_REQUIRE([AC_CANONICAL_HOST])
+AC_LANG_SAVE
+AC_LANG_C
+acx_pthread_ok=no
+
+# We used to check for pthread.h first, but this fails if pthread.h
+# requires special compiler flags (e.g. on True64 or Sequent).
+# It gets checked for in the link test anyway.
+
+# First of all, check if the user has set any of the PTHREAD_LIBS,
+# etcetera environment variables, and if threads linking works using
+# them:
+if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+ save_LIBS="$LIBS"
+ LIBS="$PTHREAD_LIBS $LIBS"
+ AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS])
+ AC_TRY_LINK_FUNC(pthread_join, acx_pthread_ok=yes)
+ AC_MSG_RESULT($acx_pthread_ok)
+ if test x"$acx_pthread_ok" = xno; then
+ PTHREAD_LIBS=""
+ PTHREAD_CFLAGS=""
+ fi
+ LIBS="$save_LIBS"
+ CFLAGS="$save_CFLAGS"
+fi
+
+# We must check for the threads library under a number of different
+# names; the ordering is very important because some systems
+# (e.g. DEC) have both -lpthread and -lpthreads, where one of the
+# libraries is broken (non-POSIX).
+
+# Create a list of thread flags to try. Items starting with a "-" are
+# C compiler flags, and other items are library names, except for "none"
+# which indicates that we try without any flags at all, and "pthread-config"
+# which is a program returning the flags for the Pth emulation library.
+
+acx_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
+
+# The ordering *is* (sometimes) important. Some notes on the
+# individual items follow:
+
+# pthreads: AIX (must check this before -lpthread)
+# none: in case threads are in libc; should be tried before -Kthread and
+# other compiler flags to prevent continual compiler warnings
+# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
+# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
+# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
+# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads)
+# -pthreads: Solaris/gcc
+# -mthreads: Mingw32/gcc, Lynx/gcc
+# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
+# doesn't hurt to check since this sometimes defines pthreads too;
+# also defines -D_REENTRANT)
+# pthread: Linux, etcetera
+# --thread-safe: KAI C++
+# pthread-config: use pthread-config program (for GNU Pth library)
+
+case "${host_cpu}-${host_os}" in
+ *solaris*)
+
+ # On Solaris (at least, for some versions), libc contains stubbed
+ # (non-functional) versions of the pthreads routines, so link-based
+ # tests will erroneously succeed. (We need to link with -pthread or
+ # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather
+ # a function called by this macro, so we could check for that, but
+ # who knows whether they'll stub that too in a future libc.) So,
+ # we'll just look for -pthreads and -lpthread first:
+
+ acx_pthread_flags="-pthread -pthreads pthread -mt $acx_pthread_flags"
+ ;;
+esac
+
+if test x"$acx_pthread_ok" = xno; then
+for flag in $acx_pthread_flags; do
+
+ case $flag in
+ none)
+ AC_MSG_CHECKING([whether pthreads work without any flags])
+ ;;
+
+ -*)
+ AC_MSG_CHECKING([whether pthreads work with $flag])
+ PTHREAD_CFLAGS="$flag"
+ ;;
+
+ pthread-config)
+ AC_CHECK_PROG(acx_pthread_config, pthread-config, yes, no)
+ if test x"$acx_pthread_config" = xno; then continue; fi
+ PTHREAD_CFLAGS="`pthread-config --cflags`"
+ PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
+ ;;
+
+ *)
+ AC_MSG_CHECKING([for the pthreads library -l$flag])
+ PTHREAD_LIBS="-l$flag"
+ ;;
+ esac
+
+ save_LIBS="$LIBS"
+ save_CFLAGS="$CFLAGS"
+ LIBS="$PTHREAD_LIBS $LIBS"
+ CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+
+ # Check for various functions. We must include pthread.h,
+ # since some functions may be macros. (On the Sequent, we
+ # need a special flag -Kthread to make this header compile.)
+ # We check for pthread_join because it is in -lpthread on IRIX
+ # while pthread_create is in libc. We check for pthread_attr_init
+ # due to DEC craziness with -lpthreads. We check for
+ # pthread_cleanup_push because it is one of the few pthread
+ # functions on Solaris that doesn't have a non-functional libc stub.
+ # We try pthread_create on general principles.
+ AC_TRY_LINK([#include <pthread.h>],
+ [pthread_t th; pthread_join(th, 0);
+ pthread_attr_init(0); pthread_cleanup_push(0, 0);
+ pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],
+ [acx_pthread_ok=yes])
+
+ LIBS="$save_LIBS"
+ CFLAGS="$save_CFLAGS"
+
+ AC_MSG_RESULT($acx_pthread_ok)
+ if test "x$acx_pthread_ok" = xyes; then
+ break;
+ fi
+
+ PTHREAD_LIBS=""
+ PTHREAD_CFLAGS=""
+done
+fi
+
+# Various other checks:
+if test "x$acx_pthread_ok" = xyes; then
+ save_LIBS="$LIBS"
+ LIBS="$PTHREAD_LIBS $LIBS"
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+
+ # Detect AIX lossage: threads are created detached by default
+ # and the JOINABLE attribute has a nonstandard name (UNDETACHED).
+ AC_MSG_CHECKING([for joinable pthread attribute])
+ AC_TRY_LINK([#include <pthread.h>],
+ [int attr=PTHREAD_CREATE_JOINABLE;],
+ ok=PTHREAD_CREATE_JOINABLE, ok=unknown)
+ if test x"$ok" = xunknown; then
+ AC_TRY_LINK([#include <pthread.h>],
+ [int attr=PTHREAD_CREATE_UNDETACHED;],
+ ok=PTHREAD_CREATE_UNDETACHED, ok=unknown)
+ fi
+ if test x"$ok" != xPTHREAD_CREATE_JOINABLE; then
+ AC_DEFINE(PTHREAD_CREATE_JOINABLE, $ok,
+ [Define to the necessary symbol if this constant
+ uses a non-standard name on your system.])
+ fi
+ AC_MSG_RESULT(${ok})
+ if test x"$ok" = xunknown; then
+ AC_MSG_WARN([we do not know how to create joinable pthreads])
+ fi
+
+ AC_MSG_CHECKING([if more special flags are required for pthreads])
+ flag=no
+ case "${host_cpu}-${host_os}" in
+ *-aix* | *-freebsd*) flag="-D_THREAD_SAFE";;
+ *solaris* | *-osf* | *-hpux*) flag="-D_REENTRANT";;
+ esac
+ AC_MSG_RESULT(${flag})
+ if test "x$flag" != xno; then
+ PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS"
+ fi
+
+ LIBS="$save_LIBS"
+ CFLAGS="$save_CFLAGS"
+
+ # More AIX lossage: must compile with cc_r
+ AC_CHECK_PROG(PTHREAD_CC, cc_r, cc_r, ${CC})
+else
+ PTHREAD_CC="$CC"
+fi
+
+AC_SUBST(PTHREAD_LIBS)
+AC_SUBST(PTHREAD_CFLAGS)
+AC_SUBST(PTHREAD_CC)
+
+# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
+if test x"$acx_pthread_ok" = xyes; then
+ ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1])
+ :
+else
+ acx_pthread_ok=no
+ $2
+fi
+AC_LANG_RESTORE
+])dnl ACX_PTHREAD
+
+
+
+AC_DEFUN([AX_CHECK_GL],
+[AC_REQUIRE([AC_PATH_X])dnl
+AC_REQUIRE([ACX_PTHREAD])dnl
+
+#
+# There isn't a reliable way to know we should use the Apple OpenGL framework
+# without a configure option. A Mac OS X user may have installed an
+# alternative GL implementation (e.g., Mesa), which may or may not depend on X.
+# libavg change: We just assume that libavg should always run using the mac
+# OpenGL framework on OS X.
+#
+if test $target_vendor = apple; then
+ AC_DEFINE([HAVE_APPLE_OPENGL_FRAMEWORK], [1],
+ [Use the Apple OpenGL framework.])
+ AC_MSG_NOTICE([Using Apple OpenGL framework])
+ GL_CFLAGS=""
+ GL_LIBS="-framework OpenGL -framework AGL"
+else
+ GL_CFLAGS="${PTHREAD_CFLAGS}"
+ GL_LIBS="${PTHREAD_LIBS} -lm"
+
+ #
+ # Use x_includes and x_libraries if they have been set (presumably by
+ # AC_PATH_X).
+ #
+ if test "X$no_x" != "Xyes"; then
+ if test -n "$x_includes"; then
+ GL_CFLAGS="-I${x_includes} ${GL_CFLAGS}"
+ fi
+ if test -n "$x_libraries"; then
+ GL_LIBS="-L${x_libraries} -lX11 ${GL_LIBS}"
+ fi
+ fi
+
+ AC_LANG_PUSH(C)
+
+ AC_CHECK_HEADERS([windows.h])
+
+ AC_CACHE_CHECK([for OpenGL library], [ax_cv_check_gl_libgl],
+ [ax_cv_check_gl_libgl="no"
+ ax_save_CPPFLAGS="${CPPFLAGS}"
+ CPPFLAGS="${GL_CFLAGS} ${CPPFLAGS}"
+ ax_save_LIBS="${LIBS}"
+ LIBS=""
+ ax_check_libs="-lopengl32 -lGL"
+ for ax_lib in ${ax_check_libs}; do
+ if test "X$CC" = "Xcl"; then
+ ax_try_lib=`echo $ax_lib | sed -e 's/^-l//' -e 's/$/.lib/'`
+ else
+ ax_try_lib="${ax_lib}"
+ fi
+ LIBS="${ax_try_lib} ${GL_LIBS} ${ax_save_LIBS}"
+ AC_TRY_LINK([
+# if HAVE_WINDOWS_H && defined(_WIN32)
+# include <windows.h>
+# endif
+# include <GL/gl.h>
+],
+ [glBegin(0)],
+ [ax_cv_check_gl_libgl="${ax_try_lib}"; break])
+ done
+ LIBS=${ax_save_LIBS}
+ CPPFLAGS=${ax_save_CPPFLAGS}])
+
+ if test "X${ax_cv_check_gl_libgl}" = "Xno"; then
+ no_gl="yes"
+ GL_CFLAGS=""
+ GL_LIBS=""
+ else
+ GL_LIBS="${ax_cv_check_gl_libgl} ${GL_LIBS}"
+ fi
+ AC_LANG_POP(C)
+fi
+
+AC_SUBST([GL_CFLAGS])
+AC_SUBST([GL_LIBS])
+])dnl
+
+
+AC_DEFUN([AX_CHECK_GLU],
+[AC_REQUIRE([AX_CHECK_GL])dnl
+GLU_CFLAGS="${GL_CFLAGS}"
+if test $target_vendor != apple; then
+ AC_CACHE_CHECK([for OpenGL Utility library], [ax_cv_check_glu_libglu],
+ [ax_cv_check_glu_libglu="no"
+ ax_save_CPPFLAGS="${CPPFLAGS}"
+ CPPFLAGS="${GL_CFLAGS} ${CPPFLAGS}"
+ ax_save_LIBS="${LIBS}"
+ LIBS=""
+ ax_check_libs="-lglu32 -lGLU"
+ for ax_lib in ${ax_check_libs}; do
+ if test "X$CC" = "Xcl"; then
+ ax_try_lib=`echo $ax_lib | sed -e 's/^-l//' -e 's/$/.lib/'`
+ else
+ ax_try_lib="${ax_lib}"
+ fi
+ LIBS="${ax_try_lib} ${GL_LIBS} ${ax_save_LIBS}"
+ #
+ # libGLU typically links with libstdc++ on POSIX platforms. However,
+ # setting the language to C++ means that test program source is named
+ # "conftest.cc"; and Microsoft cl doesn't know what to do with such a
+ # file.
+ #
+ if test "X$CXX" != "Xcl"; then
+ AC_LANG_PUSH([C++])
+ fi
+ AC_TRY_LINK([
+# if HAVE_WINDOWS_H && defined(_WIN32)
+# include <windows.h>
+# endif
+# include <GL/glu.h>
+],
+ [gluBeginCurve(0)],
+ [ax_cv_check_glu_libglu="${ax_try_lib}"; break])
+ if test "X$CXX" != "Xcl"; then
+ AC_LANG_POP([C++])
+ fi
+ done
+ LIBS=${ax_save_LIBS}
+ CPPFLAGS=${ax_save_CPPFLAGS}])
+ if test "X${ax_cv_check_glu_libglu}" = "Xno"; then
+ no_gl="yes"
+ GLU_CFLAGS=""
+ GLU_LIBS=""
+ else
+ GLU_LIBS="${ax_cv_check_glu_libglu} ${GL_LIBS}"
+ fi
+fi
+AC_SUBST([GLU_CFLAGS])
+AC_SUBST([GLU_LIBS])
+])
+
diff --git a/m4/ax_python_devel.m4 b/m4/ax_python_devel.m4
new file mode 100644
index 0000000..0151482
--- /dev/null
+++ b/m4/ax_python_devel.m4
@@ -0,0 +1,312 @@
+# ===========================================================================
+# http://www.gnu.org/software/autoconf-archive/ax_python_devel.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_PYTHON_DEVEL([version])
+#
+# DESCRIPTION
+#
+# Note: Defines as a precious variable "PYTHON_VERSION". Don't override it
+# in your configure.ac.
+#
+# This macro checks for Python and tries to get the include path to
+# 'Python.h'. It provides the $(PYTHON_CPPFLAGS) and $(PYTHON_LDFLAGS)
+# output variables. It also exports $(PYTHON_EXTRA_LIBS) and
+# $(PYTHON_EXTRA_LDFLAGS) for embedding Python in your code.
+#
+# You can search for some particular version of Python by passing a
+# parameter to this macro, for example ">= '2.3.1'", or "== '2.4'". Please
+# note that you *have* to pass also an operator along with the version to
+# match, and pay special attention to the single quotes surrounding the
+# version number. Don't use "PYTHON_VERSION" for this: that environment
+# variable is declared as precious and thus reserved for the end-user.
+#
+# This macro should work for all versions of Python >= 2.1.0. As an end
+# user, you can disable the check for the python version by setting the
+# PYTHON_NOVERSIONCHECK environment variable to something else than the
+# empty string.
+#
+# If you need to use this macro for an older Python version, please
+# contact the authors. We're always open for feedback.
+#
+# LICENSE
+#
+# Copyright (c) 2009 Sebastian Huber <sebastian-huber@web.de>
+# Copyright (c) 2009 Alan W. Irwin
+# Copyright (c) 2009 Rafael Laboissiere <rafael@laboissiere.net>
+# Copyright (c) 2009 Andrew Collier
+# Copyright (c) 2009 Matteo Settenvini <matteo@member.fsf.org>
+# Copyright (c) 2009 Horst Knorr <hk_classes@knoda.org>
+# Copyright (c) 2013 Daniel Mullner <muellner@math.stanford.edu>
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation, either version 3 of the License, or (at your
+# option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+# Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# As a special exception, the respective Autoconf Macro's copyright owner
+# gives unlimited permission to copy, distribute and modify the configure
+# scripts that are the output of Autoconf when processing the Macro. You
+# need not follow the terms of the GNU General Public License when using
+# or distributing such scripts, even though portions of the text of the
+# Macro appear in them. The GNU General Public License (GPL) does govern
+# all other use of the material that constitutes the Autoconf Macro.
+#
+# This special exception to the GPL applies to versions of the Autoconf
+# Macro released by the Autoconf Archive. When you make and distribute a
+# modified version of the Autoconf Macro, you may extend this special
+# exception to the GPL to apply to your modified version as well.
+
+#serial 16
+
+AU_ALIAS([AC_PYTHON_DEVEL], [AX_PYTHON_DEVEL])
+AC_DEFUN([AX_PYTHON_DEVEL],[
+ #
+ # Allow the use of a (user set) custom python version
+ #
+ AC_ARG_VAR([PYTHON_VERSION],[The installed Python
+ version to use, for example '2.3'. This string
+ will be appended to the Python interpreter
+ canonical name.])
+
+ AC_PATH_PROG([PYTHON],[python[$PYTHON_VERSION]])
+ if test -z "$PYTHON"; then
+ AC_MSG_ERROR([Cannot find python$PYTHON_VERSION in your system path])
+ PYTHON_VERSION=""
+ fi
+
+ #
+ # Check for a version of Python >= 2.1.0
+ #
+ AC_MSG_CHECKING([for a version of Python >= '2.1.0'])
+ ac_supports_python_ver=`$PYTHON -c "import sys; \
+ ver = sys.version.split ()[[0]]; \
+ print (ver >= '2.1.0')"`
+ if test "$ac_supports_python_ver" != "True"; then
+ if test -z "$PYTHON_NOVERSIONCHECK"; then
+ AC_MSG_RESULT([no])
+ AC_MSG_FAILURE([
+This version of the AC@&t@_PYTHON_DEVEL macro
+doesn't work properly with versions of Python before
+2.1.0. You may need to re-run configure, setting the
+variables PYTHON_CPPFLAGS, PYTHON_LDFLAGS, PYTHON_SITE_PKG,
+PYTHON_EXTRA_LIBS and PYTHON_EXTRA_LDFLAGS by hand.
+Moreover, to disable this check, set PYTHON_NOVERSIONCHECK
+to something else than an empty string.
+])
+ else
+ AC_MSG_RESULT([skip at user request])
+ fi
+ else
+ AC_MSG_RESULT([yes])
+ fi
+
+ #
+ # if the macro parameter ``version'' is set, honour it
+ #
+ if test -n "$1"; then
+ AC_MSG_CHECKING([for a version of Python $1])
+ ac_supports_python_ver=`$PYTHON -c "import sys; \
+ ver = sys.version.split ()[[0]]; \
+ print (ver $1)"`
+ if test "$ac_supports_python_ver" = "True"; then
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+ AC_MSG_ERROR([this package requires Python $1.
+If you have it installed, but it isn't the default Python
+interpreter in your system path, please pass the PYTHON_VERSION
+variable to configure. See ``configure --help'' for reference.
+])
+ PYTHON_VERSION=""
+ fi
+ fi
+
+ #
+ # Check if you have distutils, else fail
+ #
+ AC_MSG_CHECKING([for the distutils Python package])
+ ac_distutils_result=`$PYTHON -c "import distutils" 2>&1`
+ if test -z "$ac_distutils_result"; then
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+ AC_MSG_ERROR([cannot import Python module "distutils".
+Please check your Python installation. The error was:
+$ac_distutils_result])
+ PYTHON_VERSION=""
+ fi
+
+ #
+ # Check for Python include path
+ #
+ AC_MSG_CHECKING([for Python include path])
+ if test -z "$PYTHON_CPPFLAGS"; then
+ python_path=`$PYTHON -c "import distutils.sysconfig; \
+ print (distutils.sysconfig.get_python_inc ());"`
+ plat_python_path=`$PYTHON -c "import distutils.sysconfig; \
+ print (distutils.sysconfig.get_python_inc (plat_specific=1));"`
+ if test -n "${python_path}"; then
+ if test "${plat_python_path}" != "${python_path}"; then
+ python_path="-I$python_path -I$plat_python_path"
+ else
+ python_path="-I$python_path"
+ fi
+ fi
+ PYTHON_CPPFLAGS=$python_path
+ fi
+ AC_MSG_RESULT([$PYTHON_CPPFLAGS])
+ AC_SUBST([PYTHON_CPPFLAGS])
+
+ #
+ # Check for Python library path
+ #
+ AC_MSG_CHECKING([for Python library path])
+ if test -z "$PYTHON_LDFLAGS"; then
+ # (makes two attempts to ensure we've got a version number
+ # from the interpreter)
+ ac_python_version=`cat<<EOD | $PYTHON -
+
+# join all versioning strings, on some systems
+# major/minor numbers could be in different list elements
+from distutils.sysconfig import *
+e = get_config_var('VERSION')
+if e is not None:
+ print(e)
+EOD`
+
+ if test -z "$ac_python_version"; then
+ if test -n "$PYTHON_VERSION"; then
+ ac_python_version=$PYTHON_VERSION
+ else
+ ac_python_version=`$PYTHON -c "import sys; \
+ print (sys.version[[:3]])"`
+ fi
+ fi
+
+ # Make the versioning information available to the compiler
+ AC_DEFINE_UNQUOTED([HAVE_PYTHON], ["$ac_python_version"],
+ [If available, contains the Python version number currently in use.])
+
+ # First, the library directory:
+ ac_python_libdir=`cat<<EOD | $PYTHON -
+
+# There should be only one
+import distutils.sysconfig
+e = distutils.sysconfig.get_config_var('LIBDIR')
+if e is not None:
+ print (e)
+EOD`
+
+ # Now, for the library:
+ ac_python_library=`cat<<EOD | $PYTHON -
+
+import distutils.sysconfig
+c = distutils.sysconfig.get_config_vars()
+if 'LDVERSION' in c:
+ print ('python'+c[['LDVERSION']])
+else:
+ print ('python'+c[['VERSION']])
+EOD`
+
+ # This small piece shamelessly adapted from PostgreSQL python macro;
+ # credits goes to momjian, I think. I'd like to put the right name
+ # in the credits, if someone can point me in the right direction... ?
+ #
+ if test -n "$ac_python_libdir" -a -n "$ac_python_library"
+ then
+ # use the official shared library
+ ac_python_library=`echo "$ac_python_library" | sed "s/^lib//"`
+ PYTHON_LDFLAGS="-L$ac_python_libdir -l$ac_python_library"
+ else
+ # old way: use libpython from python_configdir
+ ac_python_libdir=`$PYTHON -c \
+ "from distutils.sysconfig import get_python_lib as f; \
+ import os; \
+ print (os.path.join(f(plat_specific=1, standard_lib=1), 'config'));"`
+ PYTHON_LDFLAGS="-L$ac_python_libdir -lpython$ac_python_version"
+ fi
+
+ if test -z "PYTHON_LDFLAGS"; then
+ AC_MSG_ERROR([
+ Cannot determine location of your Python DSO. Please check it was installed with
+ dynamic libraries enabled, or try setting PYTHON_LDFLAGS by hand.
+ ])
+ fi
+ fi
+ AC_MSG_RESULT([$PYTHON_LDFLAGS])
+ AC_SUBST([PYTHON_LDFLAGS])
+
+ #
+ # Check for site packages
+ #
+ AC_MSG_CHECKING([for Python site-packages path])
+ if test -z "$PYTHON_SITE_PKG"; then
+ PYTHON_SITE_PKG=`$PYTHON -c "import distutils.sysconfig; \
+ print (distutils.sysconfig.get_python_lib(0,0));"`
+ fi
+ AC_MSG_RESULT([$PYTHON_SITE_PKG])
+ AC_SUBST([PYTHON_SITE_PKG])
+
+ #
+ # libraries which must be linked in when embedding
+ #
+ AC_MSG_CHECKING(python extra libraries)
+ if test -z "$PYTHON_EXTRA_LIBS"; then
+ PYTHON_EXTRA_LIBS=`$PYTHON -c "import distutils.sysconfig; \
+ conf = distutils.sysconfig.get_config_var; \
+ print (conf('LIBS'))"`
+ fi
+ AC_MSG_RESULT([$PYTHON_EXTRA_LIBS])
+ AC_SUBST(PYTHON_EXTRA_LIBS)
+
+ #
+ # final check to see if everything compiles alright
+ #
+ AC_MSG_CHECKING([consistency of all components of python development environment])
+ # save current global flags
+ ac_save_LIBS="$LIBS"
+ ac_save_CPPFLAGS="$CPPFLAGS"
+ LIBS="$ac_save_LIBS $PYTHON_LDFLAGS $PYTHON_EXTRA_LIBS"
+ CPPFLAGS="$ac_save_CPPFLAGS $PYTHON_CPPFLAGS"
+ AC_LANG_PUSH([C])
+ AC_LINK_IFELSE([
+ AC_LANG_PROGRAM([[#include <Python.h>]],
+ [[Py_Initialize();]])
+ ],[pythonexists=yes],[pythonexists=no])
+ AC_LANG_POP([C])
+ # turn back to default flags
+ CPPFLAGS="$ac_save_CPPFLAGS"
+ LIBS="$ac_save_LIBS"
+
+ AC_MSG_RESULT([$pythonexists])
+
+ if test ! "x$pythonexists" = "xyes"; then
+ AC_MSG_FAILURE([
+ Could not link test program to Python. Maybe the main Python library has been
+ installed in some non-standard library path. If so, pass it to configure,
+ via the LDFLAGS environment variable.
+ Example: ./configure LDFLAGS="-L/usr/non-standard-path/python/lib"
+ ============================================================================
+ ERROR!
+ You probably have to install the development version of the Python package
+ for your distribution. The exact name of this package varies among them.
+ ============================================================================
+ ])
+ PYTHON_VERSION=""
+ fi
+
+ #
+ # all done!
+ #
+])
diff --git a/m4/pkg.m4 b/m4/pkg.m4
new file mode 100644
index 0000000..5122636
--- /dev/null
+++ b/m4/pkg.m4
@@ -0,0 +1,114 @@
+# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*-
+#
+# Copyright © 2004 Scott James Remnant <scott@netsplit.com>.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# PKG_PROG_PKG_CONFIG([MIN-VERSION])
+# ----------------------------------
+AC_DEFUN([PKG_PROG_PKG_CONFIG],
+[m4_pattern_forbid([^_?PKG_[A-Z_]+$])
+m4_pattern_allow([^PKG_CONFIG(_PATH)?$])
+AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])dnl
+if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
+ AC_PATH_TOOL([PKG_CONFIG], [pkg-config])
+fi
+if test -n "$PKG_CONFIG"; then
+ _pkg_min_version=m4_ifval([$1], [$1], [0.9.0])
+ AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version])
+ if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+ PKG_CONFIG=""
+ fi
+
+fi[]dnl
+])# PKG_PROG_PKG_CONFIG
+
+# _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES])
+# ---------------------------------------------
+m4_define([_PKG_CONFIG],
+[if test "x$ac_cv_env_[]$1[]_set" = "xset"; then
+ pkg_cv_[]$1=$ac_cv_env_[]$1[]_value
+elif test -n "$PKG_CONFIG"; then
+ if AC_RUN_LOG([$PKG_CONFIG --exists "$3" >/dev/null 2>&1]); then
+ pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`
+ else
+ pkg_failed=yes
+ fi
+else
+ pkg_failed=untried
+fi[]dnl
+])# _PKG_CONFIG
+
+# PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
+# [ACTION-IF-NOT-FOUND])
+#
+#
+# Note that if there is a possibility the first call to
+# PKG_CHECK_MODULES might not happen, you should be sure to include an
+# explicit call to PKG_PROG_PKG_CONFIG in your configure.in
+#
+#
+# --------------------------------------------------------------
+AC_DEFUN([PKG_CHECK_MODULES],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
+AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl
+AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl
+
+pkg_failed=no
+AC_CACHE_CHECK([for $1][_CFLAGS], [pkg_cv_][$1][_CFLAGS],
+ [_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2])])
+AC_CACHE_CHECK([for $1][_LIBS], [pkg_cv_][$1][_LIBS],
+ [_PKG_CONFIG([$1][_LIBS], [libs], [$2])])
+
+if test $pkg_failed = yes; then
+ $1[]_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "$2"`
+ # Put the nasty error message in config.log where it belongs
+ echo "$$1[]_PKG_ERRORS" 1>&AS_MESSAGE_LOG_FD
+
+ ifelse([$4], , [AC_MSG_ERROR(dnl
+[Package requirements ($2) were not met.
+Consider adjusting the PKG_CONFIG_PATH environment variable if you
+installed software in a non-standard prefix.
+
+Alternatively you may set the $1_CFLAGS and $1_LIBS environment variables
+to avoid the need to call pkg-config. See the pkg-config man page for
+more details.])],
+ [$4])
+elif test $pkg_failed = untried; then
+ ifelse([$4], , [AC_MSG_FAILURE(dnl
+[The pkg-config script could not be found or is too old. Make sure it
+is in your PATH or set the PKG_CONFIG environment variable to the full
+path to pkg-config.
+
+Alternatively you may set the $1_CFLAGS and $1_LIBS environment variables
+to avoid the need to call pkg-config. See the pkg-config man page for
+more details.
+
+To get pkg-config, see <http://www.freedesktop.org/software/pkgconfig>.])],
+ [$4])
+else
+ $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS
+ $1[]_LIBS=$pkg_cv_[]$1[]_LIBS
+ ifelse([$3], , :, [$3])
+fi[]dnl
+])# PKG_CHECK_MODULES
diff --git a/mac/MakeDist.sh b/mac/MakeDist.sh
new file mode 100755
index 0000000..a3c6faa
--- /dev/null
+++ b/mac/MakeDist.sh
@@ -0,0 +1,89 @@
+#!/bin/bash
+
+set -e
+set -x
+
+cd ..
+
+VERSION_MAJOR=$(grep VERSION_MAJOR m4/avg_version.m4 |
+ sed 's/^.*\[ *\([A-Za-z0-9\.]*\) *\].*$/\1/')
+VERSION_MINOR=$(grep VERSION_MINOR m4/avg_version.m4 |
+ sed 's/^.*\[ *\([A-Za-z0-9\.]*\) *\].*$/\1/')
+VERSION_MICRO=$(grep VERSION_MICRO m4/avg_version.m4 |
+ sed 's/^.*\[ *\([A-Za-z0-9\.]*\) *\].*$/\1/')
+
+export VERSION=$VERSION_MAJOR.$VERSION_MINOR.$VERSION_MICRO
+
+fixLib()
+{
+ INSTALL_PATH=$3
+ install_name_tool -change ${AVG_PATH}/lib/$2.dylib $INSTALL_PATH/avg/$2.dylib avg/$1
+ install_name_tool -id $INSTALL_PATH/avg/$2.dylib avg/$2.dylib
+}
+
+distLib()
+{
+ INSTALL_PATH=$2
+ cp -v ../../lib/$1.dylib ./avg
+ install_name_tool -change $AVG_PATH//lib/$1.dylib $INSTALL_PATH/avg/$1.dylib avg.0.so
+ fixLib ../avg.0.so $1 $INSTALL_PATH
+}
+
+makeOneDist()
+{
+ INSTALL_PATH=$1
+ PYTHON_VER=$2
+
+ # Copy distribution files into staging area.
+ cd $LIBAVGDIR/../dist
+ rm -rf *
+ mkdir libavg
+ cd libavg
+ mkdir avg
+ mkdir avg/test
+ cp -Rv ${BUILDDIR}/site-packages/libavg/ .
+ strip -S avg.0.so
+ cp ../../libavg/src/avgrc avg
+ mkdir etc
+ cp -R /etc/fonts etc/
+ cd $LIBAVGDIR/src/test
+ cp -Rv *.py *.avg *.svg ${AVG_PATH}/dist/libavg/avg/test
+ mkdir ${AVG_PATH}/dist/libavg/avg/test/baseline
+ cp -v baseline/* ${AVG_PATH}/dist/libavg/avg/test/baseline
+ mkdir ${AVG_PATH}/dist/libavg/avg/test/media
+ cp -Rv media/* ${AVG_PATH}/dist/libavg/avg/test/media
+ mkdir ${AVG_PATH}/dist/libavg/avg/test/testmediadir
+ cp -v testmediadir/* ${AVG_PATH}/dist/libavg/avg/test/testmediadir
+ mkdir ${AVG_PATH}/dist/libavg/avg/test/fonts
+ cp -v fonts/* ${AVG_PATH}/dist/libavg/avg/test/fonts
+ mkdir ${AVG_PATH}/dist/libavg/avg/test/plugin
+ cp -v plugin/.libs/colorplugin.so ${AVG_PATH}/dist/libavg/avg/test/plugin
+ cp -v plugin/.libs/colorplugin.0.so ${AVG_PATH}/dist/libavg/avg/test/plugin
+ mkdir ${AVG_PATH}/dist/libavg/avg/test/extrafonts
+ cp -v extrafonts/testaddfontdir.ttf ${AVG_PATH}/dist/libavg/avg/test/extrafonts
+
+
+ cd $LIBAVGDIR/../bindist
+ rm -rf *
+ cp /usr/local/bin/avg_* .
+}
+
+if [[ x"${PKG_CONFIG_PATH}" == "x" ]]
+then
+ echo Please call 'source mac/avg_env.sh' before calling this script.
+ exit -1
+fi
+
+LIBAVGDIR=`pwd`
+DARWINVER=`uname -r`
+DARWINMAJORVER=${DARWINVER%%.*}
+
+PYTHONVERSION=2.7
+OSXVERSION=10.6
+BUILDDIR=/usr/local/lib/python2.7/
+
+makeOneDist /Library/Python/${PYTHONVERSION}/site-packages/libavg ${PYTHONVERSION}
+cd $LIBAVGDIR
+/Developer/Applications/Utilities/PackageMaker.app/Contents/MacOS/PackageMaker --doc mac/libavg.10.6.pmdoc -v -o libavg.pkg
+hdiutil create libavg-mac-${VERSION}.dmg -srcfolder libavg.pkg -ov
+hdiutil internet-enable -yes libavg-mac-${VERSION}.dmg
diff --git a/mac/PackDeps.sh b/mac/PackDeps.sh
new file mode 100755
index 0000000..7535978
--- /dev/null
+++ b/mac/PackDeps.sh
@@ -0,0 +1,12 @@
+#!/bin/bash
+if [[ x"${AVG_PATH}" == "x" ]]
+then
+ echo Please set AVG_PATH before calling this script.
+ exit -1
+fi
+
+DEST_PATH=`pwd`
+cd $AVG_PATH/deps
+tar cjf $DEST_PATH/macdependencies.tar.bz2 tarballs
+
+echo "Done"
diff --git a/mac/UnpackDeps.sh b/mac/UnpackDeps.sh
new file mode 100755
index 0000000..cb9fe78
--- /dev/null
+++ b/mac/UnpackDeps.sh
@@ -0,0 +1,48 @@
+#!/bin/bash
+if [[ x"${AVG_PATH}" == "x" ]]
+then
+ echo Please set AVG_PATH before calling this script.
+ exit -1
+fi
+
+cd $AVG_PATH/deps
+
+for file in $(ls tarballs/*.gz) $(ls tarballs/*.bz2); do
+ echo " Unpacking $file."
+ tar xf $file
+done
+
+echo " Applying patches."
+cd gettext-0.18.1.1
+patch -p0 < ../../libavg/mac/stpncpy.patch
+cd ..
+cd fontconfig-2.7.0
+patch -R Makefile.am <../../libavg/mac/fontconfig-disablecache.patch
+patch fontconfig.pc.in < ../../libavg/mac/fontconfig.pc.in.patch
+cd ..
+cd librsvg-2.34.0
+patch Makefile.am < ../../libavg/mac/librsvg_makefile.patch
+patch configure.in < ../../libavg/mac/librsvg_configure.patch
+cd ..
+cd glib-2.29.2/glib
+patch -R gconvert.c < ../../../libavg/mac/glib.patch
+cd ../..
+cd freetype-2.5.0.1/
+patch -p1 -R < ../../libavg/mac/freetype_linespacing.patch
+cd ..
+
+DARWINVER=`uname -r`
+DARWINMAJORVER=${DARWINVER%%.*}
+if [[ "${DARWINMAJORVER}" == "13" ]]
+then
+ cd SDL-1.2.15
+ patch -p1 < ../../libavg/mac/libsdl_mavericks.patch
+ cd ..
+fi
+cd pkg-config-0.20/glib-1.2.8/
+patch -p0 -R glib.h ../../../libavg/mac/pkg-config-mavericks.patch
+cd ../..
+cd libdc1394-2.2.1
+patch -p1 < ../../libavg/mac/dc1394_mavericks.patch
+cd ..
+echo "Done"
diff --git a/mac/avg_env.sh b/mac/avg_env.sh
new file mode 100755
index 0000000..089a0e9
--- /dev/null
+++ b/mac/avg_env.sh
@@ -0,0 +1,33 @@
+if [[ x"${AVG_PATH}" == x"" ]]
+then
+ echo Please set AVG_PATH
+else
+ # Set the debug info flag to use depending on whether clang is used as compiler.
+ # Is there an easier way to do this?
+ if [[ "${CXX}" == "" ]]
+ then
+ CXX=gcc
+ fi
+ IS_CLANG="`${CXX} --version 2> /dev/null | grep clang`"
+ if [[ "${IS_CLANG}" == "" ]]
+ then
+ DEBUGINFOFLAG="-gstabs"
+ else
+ DEBUGINFOFLAG="-g"
+ fi
+ export PATH=${AVG_PATH}/bin:${PATH}
+ export CPPFLAGS="-I${AVG_PATH}/include "$CPPFLAGS
+ export CXXFLAGS="-O3 ${DEBUGINFOFLAG} -Wall -pipe "$CXXFLAGS
+ export CFLAGS="-O3 ${DEBUGINFOFLAG} -Wall -pipe "$CFLAGS
+ export LDFLAGS="-L${AVG_PATH}/lib "$LDFLAGS
+ export PKG_CONFIG_PATH=${PKG_CONFIG_PATH}:${AVG_PATH}/lib/pkgconfig
+ DARWINVER=`uname -r`
+ DARWINMAJORVER=${DARWINVER%%.*}
+ if [[ "${DARWINMAJORVER}" == "10" ]]
+ then
+ export PYTHONPATH=/usr/local/lib/python2.6/site-packages/:$PYTHONPATH
+ else
+ export PYTHONPATH=${AVG_PATH}/lib/python/2.5/site-packages/:$PYTHONPATH
+ fi
+ export AVG_MAC_ENV_SET=1
+fi
diff --git a/mac/dc1394_mavericks.patch b/mac/dc1394_mavericks.patch
new file mode 100644
index 0000000..fc65746
--- /dev/null
+++ b/mac/dc1394_mavericks.patch
@@ -0,0 +1,77 @@
+--- libdc1394-2.2.1/configure 2013-01-28 03:47:43.000000000 +0100
++++ libdc1394-2.2.1-changed/configure 2013-10-29 22:05:59.000000000 +0100
+@@ -13609,51 +13609,8 @@
+
+ ;;
+ *-*-darwin*)
+- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for IOMasterPort in -lIOKit" >&5
+-$as_echo_n "checking for IOMasterPort in -lIOKit... " >&6; }
+-if test "${ac_cv_lib_IOKit_IOMasterPort+set}" = set; then :
+- $as_echo_n "(cached) " >&6
+-else
+- ac_check_lib_save_LIBS=$LIBS
+-LIBS="-lIOKit $LIBS"
+-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+-/* end confdefs.h. */
+-
+-/* Override any GCC internal prototype to avoid an error.
+- Use char because int might match the return type of a GCC
+- builtin and then its argument prototype would still apply. */
+-#ifdef __cplusplus
+-extern "C"
+-#endif
+-char IOMasterPort ();
+-int
+-main ()
+-{
+-return IOMasterPort ();
+- ;
+- return 0;
+-}
+-_ACEOF
+-if ac_fn_c_try_link "$LINENO"; then :
+- ac_cv_lib_IOKit_IOMasterPort=yes
+-else
+- ac_cv_lib_IOKit_IOMasterPort=no
+-fi
+-rm -f core conftest.err conftest.$ac_objext \
+- conftest$ac_exeext conftest.$ac_ext
+-LIBS=$ac_check_lib_save_LIBS
+-fi
+-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_IOKit_IOMasterPort" >&5
+-$as_echo "$ac_cv_lib_IOKit_IOMasterPort" >&6; }
+-if test "x$ac_cv_lib_IOKit_IOMasterPort" = x""yes; then :
+-
+-$as_echo "#define HAVE_MACOSX /**/" >>confdefs.h
+- have_macosx=true
+-else
+- as_fn_error "IOKitLib not found." "$LINENO" 5
+-fi
+
+- platform_LDFLAGS="-framework CoreServices -framework CoreFoundation -framework Carbon"
++ platform_LDFLAGS="-framework CoreServices -framework CoreFoundation -framework Carbon -framework IOKit"
+
+ ;;
+ *-*-cygwin* | *-*-mingw*)
+--- libdc1394-2.2.1/dc1394/macosx/Makefile.in 2013-01-28 03:47:45.000000000 +0100
++++ libdc1394-2.2.1-changed/dc1394/macosx/Makefile.in 2013-10-29 22:03:29.000000000 +0100
+@@ -264,7 +264,7 @@
+ @HAVE_MACOSX_TRUE@ capture.h
+
+ AM_CFLAGS = -I..
+-libdc1394_macosx_la_LDFLAGS = -framework CoreFoundation -framework Carbon
++libdc1394_macosx_la_LDFLAGS = -framework CoreFoundation -framework Carbon -framework IOKit
+ libdc1394_macosx_la_LIBADD = -lIOKit
+ libdc1394_macosx_la_SOURCES = \
+ control.c \
+--- libdc1394-2.2.1/examples/Makefile.in 2013-01-28 03:47:45.000000000 +0100
++++ libdc1394-2.2.1-changed/examples/Makefile.in 2013-10-29 22:03:59.000000000 +0100
+@@ -350,7 +350,7 @@
+ B = dc1394_reset_bus $(am__append_2)
+ @HAVE_LINUX_TRUE@@HAVE_OPENGL_TRUE@GL_LIBS = -lGL
+ @HAVE_OPENGL_TRUE@@HAVE_WINDOWS_TRUE@GL_LIBS = -lopengl32
+-@HAVE_MACOSX_TRUE@AM_LDFLAGS = -framework CoreFoundation -framework Carbon
++@HAVE_MACOSX_TRUE@AM_LDFLAGS = -framework CoreFoundation -framework Carbon -framework IOKit
+ LDADD = ../dc1394/libdc1394.la
+ helloworld_SOURCES = helloworld.c
+ ladybug_SOURCES = ladybug.c
diff --git a/mac/fontconfig-disablecache.patch b/mac/fontconfig-disablecache.patch
new file mode 100644
index 0000000..a00d847
--- /dev/null
+++ b/mac/fontconfig-disablecache.patch
@@ -0,0 +1,12 @@
+57c57
+< #if CROSS_COMPILING
+---
+> if CROSS_COMPILING
+59,61c59,61
+< #else
+< # RUN_FC_CACHE_TEST=test -z "$(DESTDIR)"
+< #endif
+---
+> else
+> RUN_FC_CACHE_TEST=test -z "$(DESTDIR)"
+> endif
diff --git a/mac/fontconfig.pc.in.patch b/mac/fontconfig.pc.in.patch
new file mode 100644
index 0000000..64d2a76
--- /dev/null
+++ b/mac/fontconfig.pc.in.patch
@@ -0,0 +1,4 @@
+9c9
+< Libs: -L${libdir} -lfontconfig
+---
+> Libs: -L${libdir} -lfontconfig -lexpat
diff --git a/mac/freetype_linespacing.patch b/mac/freetype_linespacing.patch
new file mode 100644
index 0000000..426e18f
--- /dev/null
+++ b/mac/freetype_linespacing.patch
@@ -0,0 +1,13 @@
+--- a/src/truetype/ttdriver.c
++++ b/src/truetype/ttdriver.c
+@@ -246,7 +246,10 @@
+ FT_Request_Metrics( size->face, req );
+
+ if ( FT_IS_SCALABLE( size->face ) )
++ {
+ error = tt_size_reset( ttsize );
++ ttsize->root.metrics = ttsize->metrics;
++ }
+
+ return error;
+ }
diff --git a/mac/gcc-fat.sh b/mac/gcc-fat.sh
new file mode 100755
index 0000000..7d653eb
--- /dev/null
+++ b/mac/gcc-fat.sh
@@ -0,0 +1,113 @@
+#!/bin/sh
+#
+# Build Universal binaries on Mac OS X, thanks Ryan!
+#
+# Usage: ./configure CC="sh gcc-fat.sh" && make && rm -rf ppc x86
+
+
+# PowerPC compiler flags (10.2 runtime compatibility)
+PPC_SDK=MacOSX10.3.9.sdk
+
+GCC_COMPILE_PPC="gcc-3.3 -arch ppc \
+-DMAC_OS_X_VERSION_MIN_REQUIRED=1030 \
+-nostdinc \
+-F/Developer/SDKs/${PPC_SDK}/System/Library/Frameworks \
+-I/Developer/SDKs/${PPC_SDK}/usr/include/gcc/darwin/3.3 \
+-isystem /Developer/SDKs/${PPC_SDK}/usr/include"
+
+GCC_LINK_PPC="\
+-L/Developer/SDKs/${PPC_SDK}/usr/lib/gcc/darwin/3.3 \
+-F/Developer/SDKs/${PPC_SDK}/System/Library/Frameworks \
+-Wl,-syslibroot,/Developer/SDKs/${PPC_SDK}"
+
+# Intel compiler flags (10.4 runtime compatibility)
+GCC_COMPILE_X86="gcc-4.0 -arch i386 -mmacosx-version-min=10.4 \
+-DMAC_OS_X_VERSION_MIN_REQUIRED=1040 \
+-nostdinc \
+-F/Developer/SDKs/MacOSX10.4u.sdk/System/Library/Frameworks \
+-I/Developer/SDKs/MacOSX10.4u.sdk/usr/lib/gcc/i686-apple-darwin8/4.0.1/include \
+-isystem /Developer/SDKs/MacOSX10.4u.sdk/usr/include"
+
+GCC_LINK_X86="\
+-L/Developer/SDKs/MacOSX10.4u.sdk/usr/lib/gcc/i686-apple-darwin8/4.0.0 \
+-Wl,-syslibroot,/Developer/SDKs/MacOSX10.4u.sdk"
+
+# Output both PowerPC and Intel object files
+args="$*"
+compile=yes
+link=yes
+while test x$1 != x; do
+ case $1 in
+ --version) exec gcc $1;;
+ -v) exec gcc $1;;
+ -V) exec gcc $1;;
+ -print-prog-name=*) exec gcc $1;;
+ -print-search-dirs) exec gcc $1;;
+ -E) GCC_COMPILE_PPC="$GCC_COMPILE_PPC -E"
+ GCC_COMPILE_X86="$GCC_COMPILE_X86 -E"
+ compile=no; link=no;;
+ -c) link=no;;
+ -o) output=$2;;
+ *.c|*.cc|*.cpp|*.S) source=$1;;
+ esac
+ shift
+done
+if test x$link = xyes; then
+ GCC_COMPILE_PPC="$GCC_COMPILE_PPC $GCC_LINK_PPC"
+ GCC_COMPILE_X86="$GCC_COMPILE_X86 $GCC_LINK_X86"
+fi
+if test x"$output" = x; then
+ if test x$link = xyes; then
+ output=a.out
+ elif test x$compile = xyes; then
+ output=`echo $source | sed -e 's|.*/||' -e 's|\(.*\)\.[^\.]*|\1|'`.o
+ fi
+fi
+
+if test x"$output" != x; then
+ dir=ppc/`dirname $output`
+ if test -d $dir; then
+ :
+ else
+ mkdir -p $dir
+ fi
+fi
+set -- $args
+while test x$1 != x; do
+ if test -f "ppc/$1" && test "$1" != "$output"; then
+ ppc_args="$ppc_args ppc/$1"
+ else
+ ppc_args="$ppc_args $1"
+ fi
+ shift
+done
+$GCC_COMPILE_PPC $ppc_args || exit $?
+if test x"$output" != x; then
+ cp $output ppc/$output
+fi
+
+if test x"$output" != x; then
+ dir=x86/`dirname $output`
+ if test -d $dir; then
+ :
+ else
+ mkdir -p $dir
+ fi
+fi
+set -- $args
+while test x$1 != x; do
+ if test -f "x86/$1" && test "$1" != "$output"; then
+ x86_args="$x86_args x86/$1"
+ else
+ x86_args="$x86_args $1"
+ fi
+ shift
+done
+$GCC_COMPILE_X86 $x86_args || exit $?
+if test x"$output" != x; then
+ cp $output x86/$output
+fi
+
+if test x"$output" != x; then
+ lipo -create -o $output ppc/$output x86/$output
+fi
diff --git a/mac/glib.patch b/mac/glib.patch
new file mode 100644
index 0000000..fbd20e3
--- /dev/null
+++ b/mac/glib.patch
@@ -0,0 +1,4 @@
+54c54
+< #if !(defined(__APPLE__) && defined(__LP64__)) && !defined(USE_LIBICONV_GNU) && defined (_LIBICONV_H)
+---
+> #if !defined(USE_LIBICONV_GNU) && defined (_LIBICONV_H)
diff --git a/mac/installscripts/background.tif b/mac/installscripts/background.tif
new file mode 100644
index 0000000..0f81147
--- /dev/null
+++ b/mac/installscripts/background.tif
Binary files differ
diff --git a/mac/installscripts/postflight b/mac/installscripts/postflight
new file mode 100644
index 0000000..bb19ffe
--- /dev/null
+++ b/mac/installscripts/postflight
@@ -0,0 +1,17 @@
+#!/usr/bin/env python2.7
+
+import sys
+#sys.stdout = open("/Users/uzadow/Desktop/postflight.log", "w")
+print "Starting postinstall..."
+from libavg import avg
+
+print "Building font cache. This can take a while."
+Player=avg.Player.get()
+Player.loadString("""
+ <avg width="160" height="120">
+ <words x="1" y="1" fontsize="12" font="Bitstream Vera Sans"
+ text="Bitstream Vera Sans" variant="roman"/>
+ </avg>
+""")
+print "Done."
+sys.exit(0)
diff --git a/mac/libavg.10.6.pmdoc/01dist-contents.xml b/mac/libavg.10.6.pmdoc/01dist-contents.xml
new file mode 100644
index 0000000..36c6b84
--- /dev/null
+++ b/mac/libavg.10.6.pmdoc/01dist-contents.xml
@@ -0,0 +1 @@
+<pkg-contents spec="1.12"><f n="dist" o="uzadow" g="staff" p="16877" pt="/Users/uzadow/devel/libavg/dist" m="false" t="file"><f n="libavg" o="uzadow" g="staff" p="16877"><f n="__init__.py" o="uzadow" g="staff" p="33188"/><f n="__init__.pyc" o="uzadow" g="staff" p="33188"/><f n="__init__.pyo" o="uzadow" g="staff" p="33188"/><f n="anim.py" o="uzadow" g="staff" p="33188"/><f n="anim.pyc" o="uzadow" g="staff" p="33188"/><f n="anim.pyo" o="uzadow" g="staff" p="33188"/><f n="avg" o="uzadow" g="staff" p="16877"><f n="avgrc" o="uzadow" g="staff" p="33188"/><f n="test" o="uzadow" g="staff" p="16877"><f n="1x1_white.png" o="uzadow" g="staff" p="33188"/><f n="AnimTest.py" o="uzadow" g="staff" p="33188"/><f n="avg.avg" o="uzadow" g="staff" p="33188"/><f n="AVTest.py" o="uzadow" g="staff" p="33188"/><f n="baseline" o="uzadow" g="staff" p="16877"><f n="testAnim1.png" o="uzadow" g="staff" p="33188"/><f n="testAnim2.png" o="uzadow" g="staff" p="33188"/><f n="testAnim3.png" o="uzadow" g="staff" p="33188"/><f n="testbasics.png" o="uzadow" g="staff" p="33188"/><f n="testBitmap1.png" o="uzadow" g="staff" p="33188"/><f n="testBlend1.png" o="uzadow" g="staff" p="33188"/><f n="testBlend2.png" o="uzadow" g="staff" p="33188"/><f n="testBlurFX1.png" o="uzadow" g="staff" p="33188"/><f n="testBlurFX2.png" o="uzadow" g="staff" p="33188"/><f n="testButtonDisabled.png" o="uzadow" g="staff" p="33188"/><f n="testButtonDown.png" o="uzadow" g="staff" p="33188"/><f n="testButtonOver.png" o="uzadow" g="staff" p="33188"/><f n="testButtonUp.png" o="uzadow" g="staff" p="33188"/><f n="testCanvasAlpha.png" o="uzadow" g="staff" p="33188"/><f n="testCanvasBlendModes.png" o="uzadow" g="staff" p="33188"/><f n="testCanvasCrop.png" o="uzadow" g="staff" p="33188"/><f n="testCanvasDependencies1.png" o="uzadow" g="staff" p="33188"/><f n="testCanvasDependencies2.png" o="uzadow" g="staff" p="33188"/><f n="testCanvasMipmap.png" o="uzadow" g="staff" p="33188"/><f n="testCanvasMultisample.png" o="uzadow" g="staff" p="33188"/><f n="testCanvasNullFX1.png" o="uzadow" g="staff" p="33188"/><f n="testCanvasNullFX2.png" o="uzadow" g="staff" p="33188"/><f n="testCanvasResize.png" o="uzadow" g="staff" p="33188"/><f n="testCheckboxClickedDown.png" o="uzadow" g="staff" p="33188"/><f n="testCheckboxClickedOut.png" o="uzadow" g="staff" p="33188"/><f n="testCheckboxClickedOver.png" o="uzadow" g="staff" p="33188"/><f n="testCheckboxDown.png" o="uzadow" g="staff" p="33188"/><f n="testCheckboxOver.png" o="uzadow" g="staff" p="33188"/><f n="testCheckboxUp.png" o="uzadow" g="staff" p="33188"/><f n="testCircle1.png" o="uzadow" g="staff" p="33188"/><f n="testCircle2.png" o="uzadow" g="staff" p="33188"/><f n="testCircle3.png" o="uzadow" g="staff" p="33188"/><f n="testCircle4.png" o="uzadow" g="staff" p="33188"/><f n="testCircle5.png" o="uzadow" g="staff" p="33188"/><f n="testColorFX1.png" o="uzadow" g="staff" p="33188"/><f n="testColorFX2.png" o="uzadow" g="staff" p="33188"/><f n="testColorFX3.png" o="uzadow" g="staff" p="33188"/><f n="testColorFX4.png" o="uzadow" g="staff" p="33188"/><f n="testColorFX5.png" o="uzadow" g="staff" p="33188"/><f n="testColorFX6.png" o="uzadow" g="staff" p="33188"/><f n="testColorFX7.png" o="uzadow" g="staff" p="33188"/><f n="testComplexDiv1.png" o="uzadow" g="staff" p="33188"/><f n="testCompression.png" o="uzadow" g="staff" p="33188"/><f n="testContAnim1.png" o="uzadow" g="staff" p="33188"/><f n="testContAnim2.png" o="uzadow" g="staff" p="33188"/><f n="testContAnim3.png" o="uzadow" g="staff" p="33188"/><f n="testContAnim4.png" o="uzadow" g="staff" p="33188"/><f n="testContinuousAnim1.png" o="uzadow" g="staff" p="33188"/><f n="testContinuousAnim2.png" o="uzadow" g="staff" p="33188"/><f n="testContrast1.png" o="uzadow" g="staff" p="33188"/><f n="testContrast2.png" o="uzadow" g="staff" p="33188"/><f n="testContrast3.png" o="uzadow" g="staff" p="33188"/><f n="testCropImage1.png" o="uzadow" g="staff" p="33188"/><f n="testCropImage10.png" o="uzadow" g="staff" p="33188"/><f n="testCropImage2.png" o="uzadow" g="staff" p="33188"/><f n="testCropImage3.png" o="uzadow" g="staff" p="33188"/><f n="testCropImage4.png" o="uzadow" g="staff" p="33188"/><f n="testCropImage5.png" o="uzadow" g="staff" p="33188"/><f n="testCropImage6.png" o="uzadow" g="staff" p="33188"/><f n="testCropImage7.png" o="uzadow" g="staff" p="33188"/><f n="testCropImage8.png" o="uzadow" g="staff" p="33188"/><f n="testCropImage9.png" o="uzadow" g="staff" p="33188"/><f n="testCropMovie1.png" o="uzadow" g="staff" p="33188"/><f n="testCropMovie10.png" o="uzadow" g="staff" p="33188"/><f n="testCropMovie2.png" o="uzadow" g="staff" p="33188"/><f n="testCropMovie3.png" o="uzadow" g="staff" p="33188"/><f n="testCropMovie4.png" o="uzadow" g="staff" p="33188"/><f n="testCropMovie5.png" o="uzadow" g="staff" p="33188"/><f n="testCropMovie6.png" o="uzadow" g="staff" p="33188"/><f n="testCropMovie7.png" o="uzadow" g="staff" p="33188"/><f n="testCropMovie8.png" o="uzadow" g="staff" p="33188"/><f n="testCropMovie9.png" o="uzadow" g="staff" p="33188"/><f n="testCurve1.png" o="uzadow" g="staff" p="33188"/><f n="testCurve2.png" o="uzadow" g="staff" p="33188"/><f n="testCurve3.png" o="uzadow" g="staff" p="33188"/><f n="testCurve4.png" o="uzadow" g="staff" p="33188"/><f n="testDivDynamics1.png" o="uzadow" g="staff" p="33188"/><f n="testDivDynamics2.png" o="uzadow" g="staff" p="33188"/><f n="testDivDynamics3.png" o="uzadow" g="staff" p="33188"/><f n="testDivDynamics4.png" o="uzadow" g="staff" p="33188"/><f n="testDivDynamics5.png" o="uzadow" g="staff" p="33188"/><f n="testDraggable1.png" o="uzadow" g="staff" p="33188"/><f n="testDraggable2.png" o="uzadow" g="staff" p="33188"/><f n="testDynamicMediaDir1.png" o="uzadow" g="staff" p="33188"/><f n="testDynamicMediaDir2.png" o="uzadow" g="staff" p="33188"/><f n="testDynamicWords1.png" o="uzadow" g="staff" p="33188"/><f n="testDynamicWords2.png" o="uzadow" g="staff" p="33188"/><f n="testDynamicWords3.png" o="uzadow" g="staff" p="33188"/><f n="testDynamicWords4.png" o="uzadow" g="staff" p="33188"/><f n="testEaseInOutAnim1.png" o="uzadow" g="staff" p="33188"/><f n="testEaseInOutAnim2.png" o="uzadow" g="staff" p="33188"/><f n="testEaseInOutAnim3.png" o="uzadow" g="staff" p="33188"/><f n="testEaseInOutAnimC1.png" o="uzadow" g="staff" p="33188"/><f n="testEaseInOutAnimC2.png" o="uzadow" g="staff" p="33188"/><f n="testEaseInOutAnimC3.png" o="uzadow" g="staff" p="33188"/><f n="testEaseInOutAnimC4.png" o="uzadow" g="staff" p="33188"/><f n="testEaseInOutAnimC5.png" o="uzadow" g="staff" p="33188"/><f n="testEaseInOutAnimC6.png" o="uzadow" g="staff" p="33188"/><f n="testEvents.png" o="uzadow" g="staff" p="33188"/><f n="testFadeIn1.png" o="uzadow" g="staff" p="33188"/><f n="testFadeIn2.png" o="uzadow" g="staff" p="33188"/><f n="testFadeIn3.png" o="uzadow" g="staff" p="33188"/><f n="testFadeOut1.png" o="uzadow" g="staff" p="33188"/><f n="testFadeOut2.png" o="uzadow" g="staff" p="33188"/><f n="testFadeOut3.png" o="uzadow" g="staff" p="33188"/><f n="testFocusContext1.png" o="uzadow" g="staff" p="33188"/><f n="testFocusContext2.png" o="uzadow" g="staff" p="33188"/><f n="testFocusContext3.png" o="uzadow" g="staff" p="33188"/><f n="testFocusContext4.png" o="uzadow" g="staff" p="33188"/><f n="testFocusContext5.png" o="uzadow" g="staff" p="33188"/><f n="testFontDir.png" o="uzadow" g="staff" p="33188"/><f n="testGamma1.png" o="uzadow" g="staff" p="33188"/><f n="testGamma2.png" o="uzadow" g="staff" p="33188"/><f n="testHinting1.png" o="uzadow" g="staff" p="33188"/><f n="testHugeImage0.png" o="uzadow" g="staff" p="33188"/><f n="testHugeImage1.png" o="uzadow" g="staff" p="33188"/><f n="testI18NWords1.png" o="uzadow" g="staff" p="33188"/><f n="testI18NWords2.png" o="uzadow" g="staff" p="33188"/><f n="testI18NWords3.png" o="uzadow" g="staff" p="33188"/><f n="testImageNullFX1.png" o="uzadow" g="staff" p="33188"/><f n="testImageNullFX2.png" o="uzadow" g="staff" p="33188"/><f n="testImageNullFX3.png" o="uzadow" g="staff" p="33188"/><f n="testImgDynamics1.png" o="uzadow" g="staff" p="33188"/><f n="testImgDynamics2.png" o="uzadow" g="staff" p="33188"/><f n="testImgDynamics3.png" o="uzadow" g="staff" p="33188"/><f n="testImgDynamics4.png" o="uzadow" g="staff" p="33188"/><f n="testImgDynamics5.png" o="uzadow" g="staff" p="33188"/><f n="testImgHRef1.png" o="uzadow" g="staff" p="33188"/><f n="testImgHRef2.png" o="uzadow" g="staff" p="33188"/><f n="testImgHRef3.png" o="uzadow" g="staff" p="33188"/><f n="testImgMask1.png" o="uzadow" g="staff" p="33188"/><f n="testImgMask2.png" o="uzadow" g="staff" p="33188"/><f n="testImgMask3.png" o="uzadow" g="staff" p="33188"/><f n="testImgMaskPos.png" o="uzadow" g="staff" p="33188"/><f n="testImgMaskSize1.png" o="uzadow" g="staff" p="33188"/><f n="testImgMaskSize2.png" o="uzadow" g="staff" p="33188"/><f n="testImgMaskSize3.png" o="uzadow" g="staff" p="33188"/><f n="testImgPos1.png" o="uzadow" g="staff" p="33188"/><f n="testImgPos2.png" o="uzadow" g="staff" p="33188"/><f n="testImgSize1.png" o="uzadow" g="staff" p="33188"/><f n="testImgSize2.png" o="uzadow" g="staff" p="33188"/><f n="testImgWarp1.png" o="uzadow" g="staff" p="33188"/><f n="testInactiveVector1.png" o="uzadow" g="staff" p="33188"/><f n="testInactiveVector2.png" o="uzadow" g="staff" p="33188"/><f n="testIntAnim1.png" o="uzadow" g="staff" p="33188"/><f n="testIntAnim2.png" o="uzadow" g="staff" p="33188"/><f n="testIntensity1.png" o="uzadow" g="staff" p="33188"/><f n="testIntensity2.png" o="uzadow" g="staff" p="33188"/><f n="testIntensity3.png" o="uzadow" g="staff" p="33188"/><f n="testIntensity4.png" o="uzadow" g="staff" p="33188"/><f n="testJustify.png" o="uzadow" g="staff" p="33188"/><f n="testLetterSpacing1.png" o="uzadow" g="staff" p="33188"/><f n="testLetterSpacing2.png" o="uzadow" g="staff" p="33188"/><f n="testline1.png" o="uzadow" g="staff" p="33188"/><f n="testline2.png" o="uzadow" g="staff" p="33188"/><f n="testline3.png" o="uzadow" g="staff" p="33188"/><f n="testline4.png" o="uzadow" g="staff" p="33188"/><f n="testLinearAnim1.png" o="uzadow" g="staff" p="33188"/><f n="testLinearAnim2.png" o="uzadow" g="staff" p="33188"/><f n="testLinearAnim3.png" o="uzadow" g="staff" p="33188"/><f n="testLinearAnimC1.png" o="uzadow" g="staff" p="33188"/><f n="testLinearAnimC2.png" o="uzadow" g="staff" p="33188"/><f n="testLinearAnimC3.png" o="uzadow" g="staff" p="33188"/><f n="testLinearAnimC4.png" o="uzadow" g="staff" p="33188"/><f n="testLinearAnimC5.png" o="uzadow" g="staff" p="33188"/><f n="testLinearAnimC6.png" o="uzadow" g="staff" p="33188"/><f n="testLinearAnimZeroDuration1.png" o="uzadow" g="staff" p="33188"/><f n="testLinearAnimZeroDuration2.png" o="uzadow" g="staff" p="33188"/><f n="testLinearAnimZeroDuration3.png" o="uzadow" g="staff" p="33188"/><f n="testLinearAnimZeroDurationC1.png" o="uzadow" g="staff" p="33188"/><f n="testLinearAnimZeroDurationC2.png" o="uzadow" g="staff" p="33188"/><f n="testLinearAnimZeroDurationC3.png" o="uzadow" g="staff" p="33188"/><f n="testlineopacity1.png" o="uzadow" g="staff" p="33188"/><f n="testlineopacity2.png" o="uzadow" g="staff" p="33188"/><f n="testlotsoflines.png" o="uzadow" g="staff" p="33188"/><f n="testMediaDir1.png" o="uzadow" g="staff" p="33188"/><f n="testMediaDir2.png" o="uzadow" g="staff" p="33188"/><f n="testMesh1.png" o="uzadow" g="staff" p="33188"/><f n="testMesh2.png" o="uzadow" g="staff" p="33188"/><f n="testMesh3.png" o="uzadow" g="staff" p="33188"/><f n="testMesh4.png" o="uzadow" g="staff" p="33188"/><f n="testMesh5.png" o="uzadow" g="staff" p="33188"/><f n="testMesh6.png" o="uzadow" g="staff" p="33188"/><f n="testMipmap.png" o="uzadow" g="staff" p="33188"/><f n="testMove1.png" o="uzadow" g="staff" p="33188"/><f n="testOffscreen1.png" o="uzadow" g="staff" p="33188"/><f n="testOffscreen2.png" o="uzadow" g="staff" p="33188"/><f n="testOffscreen3.png" o="uzadow" g="staff" p="33188"/><f n="testOffscreen4.png" o="uzadow" g="staff" p="33188"/><f n="testOffscreen5.png" o="uzadow" g="staff" p="33188"/><f n="testOffscreenAutoRender1.png" o="uzadow" g="staff" p="33188"/><f n="testOffscreenAutoRender2.png" o="uzadow" g="staff" p="33188"/><f n="testOffscreenMultisampleScreenshot.png" o="uzadow" g="staff" p="33188"/><f n="testOffscreenScreenshot.png" o="uzadow" g="staff" p="33188"/><f n="testOutlines.png" o="uzadow" g="staff" p="33188"/><f n="testPanoDynamics1.png" o="uzadow" g="staff" p="33188"/><f n="testPanoDynamics2.png" o="uzadow" g="staff" p="33188"/><f n="testPanoDynamics3.png" o="uzadow" g="staff" p="33188"/><f n="testPanoImage.png" o="uzadow" g="staff" p="33188"/><f n="testPanoImagewNOP.png" o="uzadow" g="staff" p="33188"/><f n="testParallelAnimC1.png" o="uzadow" g="staff" p="33188"/><f n="testParallelAnimC2.png" o="uzadow" g="staff" p="33188"/><f n="testParallelAnimC3.png" o="uzadow" g="staff" p="33188"/><f n="testParallelAnims1.png" o="uzadow" g="staff" p="33188"/><f n="testParallelAnims2.png" o="uzadow" g="staff" p="33188"/><f n="testParaWords.png" o="uzadow" g="staff" p="33188"/><f n="testPlayBeforeConnect.png" o="uzadow" g="staff" p="33188"/><f n="testplugin1.png" o="uzadow" g="staff" p="33188"/><f n="testplugin2.png" o="uzadow" g="staff" p="33188"/><f n="testPointAnim1.png" o="uzadow" g="staff" p="33188"/><f n="testPointAnim2.png" o="uzadow" g="staff" p="33188"/><f n="testPointAnim3.png" o="uzadow" g="staff" p="33188"/><f n="testPolygon1.png" o="uzadow" g="staff" p="33188"/><f n="testPolygon2.png" o="uzadow" g="staff" p="33188"/><f n="testPolygon3.png" o="uzadow" g="staff" p="33188"/><f n="testPolygon4.png" o="uzadow" g="staff" p="33188"/><f n="testPolygon5.png" o="uzadow" g="staff" p="33188"/><f n="testPolygon6.png" o="uzadow" g="staff" p="33188"/><f n="testPolyLine1.png" o="uzadow" g="staff" p="33188"/><f n="testPolyLine2.png" o="uzadow" g="staff" p="33188"/><f n="testPolyLine3.png" o="uzadow" g="staff" p="33188"/><f n="testPolyLine4.png" o="uzadow" g="staff" p="33188"/><f n="testPolyLine5.png" o="uzadow" g="staff" p="33188"/><f n="testPolyLine6.png" o="uzadow" g="staff" p="33188"/><f n="testPositioning.png" o="uzadow" g="staff" p="33188"/><f n="testRawText1.png" o="uzadow" g="staff" p="33188"/><f n="testRawText2.png" o="uzadow" g="staff" p="33188"/><f n="testRawText3.png" o="uzadow" g="staff" p="33188"/><f n="testRawText4.png" o="uzadow" g="staff" p="33188"/><f n="testRect1.png" o="uzadow" g="staff" p="33188"/><f n="testRect2.png" o="uzadow" g="staff" p="33188"/><f n="testRect3.png" o="uzadow" g="staff" p="33188"/><f n="testRect4.png" o="uzadow" g="staff" p="33188"/><f n="testRotate1.png" o="uzadow" g="staff" p="33188"/><f n="testRotate1a.png" o="uzadow" g="staff" p="33188"/><f n="testRotate1b.png" o="uzadow" g="staff" p="33188"/><f n="testRotate2.png" o="uzadow" g="staff" p="33188"/><f n="testRotate3.png" o="uzadow" g="staff" p="33188"/><f n="testRotatePivot1.png" o="uzadow" g="staff" p="33188"/><f n="testRotatePivot2.png" o="uzadow" g="staff" p="33188"/><f n="testShadowFX1.png" o="uzadow" g="staff" p="33188"/><f n="testShadowFX2.png" o="uzadow" g="staff" p="33188"/><f n="testShadowFX3.png" o="uzadow" g="staff" p="33188"/><f n="testSimpleWords.png" o="uzadow" g="staff" p="33188"/><f n="testSpanWords.png" o="uzadow" g="staff" p="33188"/><f n="testSplineAnim1.png" o="uzadow" g="staff" p="33188"/><f n="testSplineAnim2.png" o="uzadow" g="staff" p="33188"/><f n="testSplineAnim3.png" o="uzadow" g="staff" p="33188"/><f n="testStateAnim1.png" o="uzadow" g="staff" p="33188"/><f n="testStateAnim2.png" o="uzadow" g="staff" p="33188"/><f n="testStateAnim3.png" o="uzadow" g="staff" p="33188"/><f n="testStateAnim4.png" o="uzadow" g="staff" p="33188"/><f n="testStateAnim5.png" o="uzadow" g="staff" p="33188"/><f n="testStateAnimC1.png" o="uzadow" g="staff" p="33188"/><f n="testStateAnimC2.png" o="uzadow" g="staff" p="33188"/><f n="testStateAnimC3.png" o="uzadow" g="staff" p="33188"/><f n="testStateAnimC4.png" o="uzadow" g="staff" p="33188"/><f n="testStateAnimC5.png" o="uzadow" g="staff" p="33188"/><f n="testTextArea1.png" o="uzadow" g="staff" p="33188"/><f n="testTextArea2.png" o="uzadow" g="staff" p="33188"/><f n="testTexturedCurve1.png" o="uzadow" g="staff" p="33188"/><f n="testTexturedCurve2.png" o="uzadow" g="staff" p="33188"/><f n="testtexturedline1.png" o="uzadow" g="staff" p="33188"/><f n="testtexturedline2.png" o="uzadow" g="staff" p="33188"/><f n="testtexturedline3.png" o="uzadow" g="staff" p="33188"/><f n="testtexturedline4.png" o="uzadow" g="staff" p="33188"/><f n="testtexturedline5.png" o="uzadow" g="staff" p="33188"/><f n="testTexturedPolygon1.png" o="uzadow" g="staff" p="33188"/><f n="testTexturedPolygon2.png" o="uzadow" g="staff" p="33188"/><f n="testTexturedPolygon3.png" o="uzadow" g="staff" p="33188"/><f n="testTexturedPolygon4.png" o="uzadow" g="staff" p="33188"/><f n="testTexturedPolygon5.png" o="uzadow" g="staff" p="33188"/><f n="testTexturedPolygon6.png" o="uzadow" g="staff" p="33188"/><f n="testTexturedPolyLine1.png" o="uzadow" g="staff" p="33188"/><f n="testTexturedPolyLine2.png" o="uzadow" g="staff" p="33188"/><f n="testTexturedPolyLine3.png" o="uzadow" g="staff" p="33188"/><f n="testTexturedPolyLine4.png" o="uzadow" g="staff" p="33188"/><f n="testTexturedRect1.png" o="uzadow" g="staff" p="33188"/><f n="testTexturedRect2.png" o="uzadow" g="staff" p="33188"/><f n="testTexturedRect3.png" o="uzadow" g="staff" p="33188"/><f n="testTexturedRect4.png" o="uzadow" g="staff" p="33188"/><f n="testTexturedRect5.png" o="uzadow" g="staff" p="33188"/><f n="testTexturedRect6.png" o="uzadow" g="staff" p="33188"/><f n="testTexturedRect7.png" o="uzadow" g="staff" p="33188"/><f n="testTexturedRect8.png" o="uzadow" g="staff" p="33188"/><f n="testUIButtonDisabled.png" o="uzadow" g="staff" p="33188"/><f n="testUIButtonDown.png" o="uzadow" g="staff" p="33188"/><f n="testUIButtonUp.png" o="uzadow" g="staff" p="33188"/><f n="testUIKeyboard.png" o="uzadow" g="staff" p="33188"/><f n="testUIKeyboardDownA1.png" o="uzadow" g="staff" p="33188"/><f n="testUIKeyboardDownA111S1.png" o="uzadow" g="staff" p="33188"/><f n="testUIKeyboardDownA212S2.png" o="uzadow" g="staff" p="33188"/><f n="testUIKeyboardDownS1.png" o="uzadow" g="staff" p="33188"/><f n="testVideo-h264-48x48.h2641.png" o="uzadow" g="staff" p="33188"/><f n="testVideo-mjpeg-48x48.avi1.png" o="uzadow" g="staff" p="33188"/><f n="testVideo-mpeg1-48x48-sound.avi1.png" o="uzadow" g="staff" p="33188"/><f n="testVideo-mpeg1-48x48.mpg1.png" o="uzadow" g="staff" p="33188"/><f n="testVideo-rgba-48x48.mov1.png" o="uzadow" g="staff" p="33188"/><f n="testVideo-vp6a-yuva-48x48.flv1.png" o="uzadow" g="staff" p="33188"/><f n="testVideoActive1.png" o="uzadow" g="staff" p="33188"/><f n="testVideoActive2.png" o="uzadow" g="staff" p="33188"/><f n="testVideoDynamics1.png" o="uzadow" g="staff" p="33188"/><f n="testVideoDynamics2.png" o="uzadow" g="staff" p="33188"/><f n="testVideoDynamics3.png" o="uzadow" g="staff" p="33188"/><f n="testVideoDynamics4.png" o="uzadow" g="staff" p="33188"/><f n="testVideoDynamics5.png" o="uzadow" g="staff" p="33188"/><f n="testVideoFPS.png" o="uzadow" g="staff" p="33188"/><f n="testVideoHRef1.png" o="uzadow" g="staff" p="33188"/><f n="testVideoLoop.png" o="uzadow" g="staff" p="33188"/><f n="testVideoMaskRGBA1.png" o="uzadow" g="staff" p="33188"/><f n="testVideoMaskRGBA2.png" o="uzadow" g="staff" p="33188"/><f n="testVideoMaskRGBA3.png" o="uzadow" g="staff" p="33188"/><f n="testVideoMaskRGBA4.png" o="uzadow" g="staff" p="33188"/><f n="testVideoMaskYUV1.png" o="uzadow" g="staff" p="33188"/><f n="testVideoMaskYUV2.png" o="uzadow" g="staff" p="33188"/><f n="testVideoMaskYUV3.png" o="uzadow" g="staff" p="33188"/><f n="testVideoMaskYUV4.png" o="uzadow" g="staff" p="33188"/><f n="testVideoMaskYUVJ1.png" o="uzadow" g="staff" p="33188"/><f n="testVideoMaskYUVJ2.png" o="uzadow" g="staff" p="33188"/><f n="testVideoMaskYUVJ3.png" o="uzadow" g="staff" p="33188"/><f n="testVideoMaskYUVJ4.png" o="uzadow" g="staff" p="33188"/><f n="testVideoNullFX.png" o="uzadow" g="staff" p="33188"/><f n="testVideoOpacityRGBA1.png" o="uzadow" g="staff" p="33188"/><f n="testVideoOpacityRGBA2.png" o="uzadow" g="staff" p="33188"/><f n="testVideoOpacityYUV1.png" o="uzadow" g="staff" p="33188"/><f n="testVideoOpacityYUV2.png" o="uzadow" g="staff" p="33188"/><f n="testVideoSeek0.png" o="uzadow" g="staff" p="33188"/><f n="testVideoSeek1.png" o="uzadow" g="staff" p="33188"/><f n="testVideoSeek2.png" o="uzadow" g="staff" p="33188"/><f n="testVideoSeek3.png" o="uzadow" g="staff" p="33188"/><f n="testVideoState1.png" o="uzadow" g="staff" p="33188"/><f n="testVideoState2.png" o="uzadow" g="staff" p="33188"/><f n="testVideoState3.png" o="uzadow" g="staff" p="33188"/><f n="testVideoState4.png" o="uzadow" g="staff" p="33188"/><f n="testVideoState5.png" o="uzadow" g="staff" p="33188"/><f n="testWarp1.png" o="uzadow" g="staff" p="33188"/><f n="testWarp2.png" o="uzadow" g="staff" p="33188"/><f n="testWarp3.png" o="uzadow" g="staff" p="33188"/><f n="testWordsBR.png" o="uzadow" g="staff" p="33188"/><f n="testWordsDynamics1.png" o="uzadow" g="staff" p="33188"/><f n="testWordsDynamics2.png" o="uzadow" g="staff" p="33188"/><f n="testWordsDynamics3.png" o="uzadow" g="staff" p="33188"/><f n="testWordsDynamics4.png" o="uzadow" g="staff" p="33188"/><f n="testWordsDynamics5.png" o="uzadow" g="staff" p="33188"/><f n="testWordsMask1.png" o="uzadow" g="staff" p="33188"/><f n="testWordsMask2.png" o="uzadow" g="staff" p="33188"/><f n="testWordsMask3.png" o="uzadow" g="staff" p="33188"/><f n="testWordsMask4.png" o="uzadow" g="staff" p="33188"/><f n="testWordsMask5.png" o="uzadow" g="staff" p="33188"/><f n="testWordsMask6.png" o="uzadow" g="staff" p="33188"/><f n="testWordsNullFX.png" o="uzadow" g="staff" p="33188"/><f n="testWrapMode1.png" o="uzadow" g="staff" p="33188"/><f n="testWrapMode2.png" o="uzadow" g="staff" p="33188"/><f n="testWrapMode3.png" o="uzadow" g="staff" p="33188"/><f n="testWrapMode4.png" o="uzadow" g="staff" p="33188"/></f><f n="button_check.png" o="uzadow" g="staff" p="33188"/><f n="button_disabled.png" o="uzadow" g="staff" p="33188"/><f n="button_down.png" o="uzadow" g="staff" p="33188"/><f n="button_over.png" o="uzadow" g="staff" p="33188"/><f n="button_up.png" o="uzadow" g="staff" p="33188"/><f n="camera.avg" o="uzadow" g="staff" p="33188"/><f n="checker.png" o="uzadow" g="staff" p="33188"/><f n="colorramp.png" o="uzadow" g="staff" p="33188"/><f n="crop.avg" o="uzadow" g="staff" p="33188"/><f n="crop2.avg" o="uzadow" g="staff" p="33188"/><f n="crop_bkgd.png" o="uzadow" g="staff" p="33188"/><f n="DynamicsTest.py" o="uzadow" g="staff" p="33188"/><f n="dynamictext.avg" o="uzadow" g="staff" p="33188"/><f n="EventTest.py" o="uzadow" g="staff" p="33188"/><f n="extrafonts" o="uzadow" g="staff" p="16877"><f n="testaddfontdir.ttf" o="uzadow" g="staff" p="33188"/></f><f n="fonts" o="uzadow" g="staff" p="16877"><f n="Vera.ttf" o="uzadow" g="staff" p="33188"/><f n="VeraBd.ttf" o="uzadow" g="staff" p="33188"/><f n="VeraBI.ttf" o="uzadow" g="staff" p="33188"/><f n="VeraIt.ttf" o="uzadow" g="staff" p="33188"/></f><f n="foo.png" o="uzadow" g="staff" p="33188"/><f n="freidrehen.jpg" o="uzadow" g="staff" p="33188"/><f n="FXTest.py" o="uzadow" g="staff" p="33188"/><f n="greyscale.png" o="uzadow" g="staff" p="33188"/><f n="i18ntext.avg" o="uzadow" g="staff" p="33188"/><f n="image.avg" o="uzadow" g="staff" p="33188"/><f n="ImageTest.py" o="uzadow" g="staff" p="33188"/><f n="invalidfilename.avg" o="uzadow" g="staff" p="33188"/><f n="invalidvideofilename.avg" o="uzadow" g="staff" p="33188"/><f n="keyboard_bg.png" o="uzadow" g="staff" p="33188"/><f n="keyboard_ovl.png" o="uzadow" g="staff" p="33188"/><f n="mask.png" o="uzadow" g="staff" p="33188"/><f n="mask1.png" o="uzadow" g="staff" p="33188"/><f n="mask2.png" o="uzadow" g="staff" p="33188"/><f n="mediadir.avg" o="uzadow" g="staff" p="33188"/><f n="mouseover.avg" o="uzadow" g="staff" p="33188"/><f n="noavg.avg" o="uzadow" g="staff" p="33188"/><f n="noavg2.avg" o="uzadow" g="staff" p="33188"/><f n="noxml.avg" o="uzadow" g="staff" p="33188"/><f n="oe.png" o="uzadow" g="staff" p="33188"/><f n="OffscreenTest.py" o="uzadow" g="staff" p="33188"/><f n="panoimage.avg" o="uzadow" g="staff" p="33188"/><f n="panoimage.png" o="uzadow" g="staff" p="33188"/><f n="PlayerTest.py" o="uzadow" g="staff" p="33188"/><f n="plugin" o="uzadow" g="staff" p="16877"><f n="libColorNode.0.so" o="uzadow" g="staff" p="33261"/><f n="libColorNode.so" o="uzadow" g="staff" p="33261"/></f><f n="PluginTest.py" o="uzadow" g="staff" p="33188"/><f n="PythonTest.py" o="uzadow" g="staff" p="33188"/><f n="rawtext.avg" o="uzadow" g="staff" p="33188"/><f n="rectborder.png" o="uzadow" g="staff" p="33188"/><f n="rgb24-32x32.png" o="uzadow" g="staff" p="33188"/><f n="rgb24-64x64.png" o="uzadow" g="staff" p="33188"/><f n="rgb24-65x65.png" o="uzadow" g="staff" p="33188"/><f n="rgb24alpha-32x32.png" o="uzadow" g="staff" p="33188"/><f n="rgb24alpha-64x64.png" o="uzadow" g="staff" p="33188"/><f n="rgb24alpha.tif" o="uzadow" g="staff" p="33188"/><f n="rotate.avg" o="uzadow" g="staff" p="33188"/><f n="rotate2.avg" o="uzadow" g="staff" p="33188"/><f n="rotate3.avg" o="uzadow" g="staff" p="33188"/><f n="shadow.png" o="uzadow" g="staff" p="33188"/><f n="Test.py" o="uzadow" g="staff" p="33261"/><f n="Test.sh" o="uzadow" g="staff" p="33261"/><f n="testapp.py" o="uzadow" g="staff" p="33188"/><f n="testcase.py" o="uzadow" g="staff" p="33188"/><f n="testmediadir" o="uzadow" g="staff" p="16877"><f n="mjpeg-48x48.avi" o="uzadow" g="staff" p="33188"/><f n="rgb24-64x64a.png" o="uzadow" g="staff" p="33188"/></f><f n="VectorTest.py" o="uzadow" g="staff" p="33188"/><f n="video.avg" o="uzadow" g="staff" p="33188"/><f n="videofps.avg" o="uzadow" g="staff" p="33188"/><f n="widebmp.jpg" o="uzadow" g="staff" p="33188"/><f n="WordsTest.py" o="uzadow" g="staff" p="33188"/></f><f n="video" o="uzadow" g="staff" p="16877"><f n="testfiles" o="uzadow" g="staff" p="16877"><f n="22.050Hz_16bit_mono.wav" o="uzadow" g="staff" p="33261"/><f n="44.1kHz_16bit_6Chan.ogg" o="uzadow" g="staff" p="33188"/><f n="44.1kHz_16bit_mono.wav" o="uzadow" g="staff" p="33261"/><f n="44.1kHz_16bit_stereo.aif" o="uzadow" g="staff" p="33261"/><f n="44.1kHz_16bit_stereo.wav" o="uzadow" g="staff" p="33261"/><f n="44.1kHz_24bit_mono.wav" o="uzadow" g="staff" p="33261"/><f n="44.1kHz_24bit_stereo.aif" o="uzadow" g="staff" p="33261"/><f n="44.1kHz_24bit_stereo.wav" o="uzadow" g="staff" p="33261"/><f n="44.1kHz_mono.ogg" o="uzadow" g="staff" p="33261"/><f n="44.1kHz_stereo.mp3" o="uzadow" g="staff" p="33188"/><f n="44.1kHz_stereo.ogg" o="uzadow" g="staff" p="33188"/><f n="48kHz_16bit_mono.wav" o="uzadow" g="staff" p="33261"/><f n="48kHz_16bit_stereo.aif" o="uzadow" g="staff" p="33261"/><f n="48kHz_16bit_stereo.wav" o="uzadow" g="staff" p="33261"/><f n="48kHz_24bit_mono.wav" o="uzadow" g="staff" p="33261"/><f n="48kHz_24bit_stereo.aif" o="uzadow" g="staff" p="33261"/><f n="48kHz_24bit_stereo.wav" o="uzadow" g="staff" p="33261"/><f n="48kHz_stereo.mp3" o="uzadow" g="staff" p="33188"/><f n="48kHz_stereo.ogg" o="uzadow" g="staff" p="33188"/><f n="h264-48x48.h264" o="uzadow" g="staff" p="33188"/><f n="mjpeg-48x48.avi" o="uzadow" g="staff" p="33188"/><f n="mpeg1-48x48-sound.avi" o="uzadow" g="staff" p="33188"/><f n="mpeg1-48x48.mpg" o="uzadow" g="staff" p="33188"/><f n="rgba-48x48.mov" o="uzadow" g="staff" p="33188"/></f></f></f><f n="avg.0.so" o="uzadow" g="staff" p="33261"/><f n="avg.la" o="uzadow" g="staff" p="33261"/><f n="avg.so" o="uzadow" g="staff" p="41453"/><f n="avg_audioplayer.py" o="uzadow" g="staff" p="33188"/><f n="avg_audioplayer.pyc" o="uzadow" g="staff" p="33188"/><f n="avg_audioplayer.pyo" o="uzadow" g="staff" p="33188"/><f n="avg_chromakey.py" o="uzadow" g="staff" p="33188"/><f n="avg_chromakey.pyc" o="uzadow" g="staff" p="33188"/><f n="avg_chromakey.pyo" o="uzadow" g="staff" p="33188"/><f n="avg_showcamera.py" o="uzadow" g="staff" p="33188"/><f n="avg_showcamera.pyc" o="uzadow" g="staff" p="33188"/><f n="avg_showcamera.pyo" o="uzadow" g="staff" p="33188"/><f n="avg_showfile.py" o="uzadow" g="staff" p="33188"/><f n="avg_showfile.pyc" o="uzadow" g="staff" p="33188"/><f n="avg_showfile.pyo" o="uzadow" g="staff" p="33188"/><f n="avg_showfont.py" o="uzadow" g="staff" p="33188"/><f n="avg_showfont.pyc" o="uzadow" g="staff" p="33188"/><f n="avg_showfont.pyo" o="uzadow" g="staff" p="33188"/><f n="avg_videoinfo.py" o="uzadow" g="staff" p="33188"/><f n="avg_videoinfo.pyc" o="uzadow" g="staff" p="33188"/><f n="avg_videoinfo.pyo" o="uzadow" g="staff" p="33188"/><f n="avg_videoplayer.py" o="uzadow" g="staff" p="33188"/><f n="avg_videoplayer.pyc" o="uzadow" g="staff" p="33188"/><f n="avg_videoplayer.pyo" o="uzadow" g="staff" p="33188"/><f n="AVGApp.py" o="uzadow" g="staff" p="33188"/><f n="AVGApp.pyc" o="uzadow" g="staff" p="33188"/><f n="AVGApp.pyo" o="uzadow" g="staff" p="33188"/><f n="AVGAppStarter.py" o="uzadow" g="staff" p="33188"/><f n="AVGAppStarter.pyc" o="uzadow" g="staff" p="33188"/><f n="AVGAppStarter.pyo" o="uzadow" g="staff" p="33188"/><f n="AVGAppStarterHelp.py" o="uzadow" g="staff" p="33188"/><f n="AVGAppStarterHelp.pyc" o="uzadow" g="staff" p="33188"/><f n="AVGAppStarterHelp.pyo" o="uzadow" g="staff" p="33188"/><f n="AVGAppUtil.py" o="uzadow" g="staff" p="33188"/><f n="AVGAppUtil.pyc" o="uzadow" g="staff" p="33188"/><f n="AVGAppUtil.pyo" o="uzadow" g="staff" p="33188"/><f n="AVGMTAppStarter.py" o="uzadow" g="staff" p="33188"/><f n="AVGMTAppStarter.pyc" o="uzadow" g="staff" p="33188"/><f n="AVGMTAppStarter.pyo" o="uzadow" g="staff" p="33188"/><f n="button.py" o="uzadow" g="staff" p="33188"/><f n="button.pyc" o="uzadow" g="staff" p="33188"/><f n="button.pyo" o="uzadow" g="staff" p="33188"/><f n="camcalibrator.py" o="uzadow" g="staff" p="33188"/><f n="camcalibrator.pyc" o="uzadow" g="staff" p="33188"/><f n="camcalibrator.pyo" o="uzadow" g="staff" p="33188"/><f n="clusteredEventList.py" o="uzadow" g="staff" p="33188"/><f n="clusteredEventList.pyc" o="uzadow" g="staff" p="33188"/><f n="clusteredEventList.pyo" o="uzadow" g="staff" p="33188"/><f n="data" o="uzadow" g="staff" p="16877"><f n="border.png" o="uzadow" g="staff" p="33188"/><f n="camcalibrator.avg" o="uzadow" g="staff" p="33188"/><f n="CamImgBorder.png" o="uzadow" g="staff" p="33188"/><f n="crosshair.png" o="uzadow" g="staff" p="33188"/></f><f n="draggable.py" o="uzadow" g="staff" p="33188"/><f n="draggable.pyc" o="uzadow" g="staff" p="33188"/><f n="draggable.pyo" o="uzadow" g="staff" p="33188"/><f n="etc" o="uzadow" g="staff" p="16877"><f n="fonts" o="uzadow" g="staff" p="16877"><f n="conf.avail" o="uzadow" g="staff" p="16877"><f n="10-autohint.conf" o="uzadow" g="staff" p="33188"/><f n="10-no-sub-pixel.conf" o="uzadow" g="staff" p="33188"/><f n="10-sub-pixel-bgr.conf" o="uzadow" g="staff" p="33188"/><f n="10-sub-pixel-rgb.conf" o="uzadow" g="staff" p="33188"/><f n="10-sub-pixel-vbgr.conf" o="uzadow" g="staff" p="33188"/><f n="10-sub-pixel-vrgb.conf" o="uzadow" g="staff" p="33188"/><f n="10-unhinted.conf" o="uzadow" g="staff" p="33188"/><f n="20-fix-globaladvance.conf" o="uzadow" g="staff" p="33188"/><f n="20-unhint-small-vera.conf" o="uzadow" g="staff" p="33188"/><f n="25-unhint-nonlatin.conf" o="uzadow" g="staff" p="33188"/><f n="30-metric-aliases.conf" o="uzadow" g="staff" p="33188"/><f n="30-urw-aliases.conf" o="uzadow" g="staff" p="33188"/><f n="40-nonlatin.conf" o="uzadow" g="staff" p="33188"/><f n="45-latin.conf" o="uzadow" g="staff" p="33188"/><f n="49-sansserif.conf" o="uzadow" g="staff" p="33188"/><f n="50-user.conf" o="uzadow" g="staff" p="33188"/><f n="51-local.conf" o="uzadow" g="staff" p="33188"/><f n="60-latin.conf" o="uzadow" g="staff" p="33188"/><f n="65-fonts-persian.conf" o="uzadow" g="staff" p="33188"/><f n="65-khmer.conf" o="uzadow" g="staff" p="33188"/><f n="65-nonlatin.conf" o="uzadow" g="staff" p="33188"/><f n="69-unifont.conf" o="uzadow" g="staff" p="33188"/><f n="70-no-bitmaps.conf" o="uzadow" g="staff" p="33188"/><f n="70-yes-bitmaps.conf" o="uzadow" g="staff" p="33188"/><f n="80-delicious.conf" o="uzadow" g="staff" p="33188"/><f n="90-synthetic.conf" o="uzadow" g="staff" p="33188"/><f n="README" o="uzadow" g="staff" p="33188"/></f><f n="conf.d" o="uzadow" g="staff" p="16877"><f n="20-fix-globaladvance.conf" o="uzadow" g="staff" p="41380"/><f n="20-unhint-small-vera.conf" o="uzadow" g="staff" p="41380"/><f n="30-metric-aliases.conf" o="uzadow" g="staff" p="41380"/><f n="30-urw-aliases.conf" o="uzadow" g="staff" p="41380"/><f n="40-nonlatin.conf" o="uzadow" g="staff" p="41380"/><f n="45-latin.conf" o="uzadow" g="staff" p="41380"/><f n="49-sansserif.conf" o="uzadow" g="staff" p="41380"/><f n="50-user.conf" o="uzadow" g="staff" p="41380"/><f n="51-local.conf" o="uzadow" g="staff" p="41380"/><f n="60-latin.conf" o="uzadow" g="staff" p="41380"/><f n="65-fonts-persian.conf" o="uzadow" g="staff" p="41380"/><f n="65-nonlatin.conf" o="uzadow" g="staff" p="41380"/><f n="69-unifont.conf" o="uzadow" g="staff" p="41380"/><f n="80-delicious.conf" o="uzadow" g="staff" p="41380"/><f n="90-synthetic.conf" o="uzadow" g="staff" p="41380"/><f n="README" o="uzadow" g="staff" p="33188"/></f><f n="fonts.conf" o="uzadow" g="staff" p="33188"/><f n="fonts.conf.bak" o="uzadow" g="staff" p="33188"/><f n="fonts.dtd" o="uzadow" g="staff" p="33188"/></f></f><f n="eventList.py" o="uzadow" g="staff" p="33188"/><f n="eventList.pyc" o="uzadow" g="staff" p="33188"/><f n="eventList.pyo" o="uzadow" g="staff" p="33188"/><f n="grabbable.py" o="uzadow" g="staff" p="33188"/><f n="grabbable.pyc" o="uzadow" g="staff" p="33188"/><f n="grabbable.pyo" o="uzadow" g="staff" p="33188"/><f n="libColorNode.0.so" o="uzadow" g="staff" p="33261"/><f n="libColorNode.la" o="uzadow" g="staff" p="33261"/><f n="libColorNode.so" o="uzadow" g="staff" p="41453"/><f n="mathutil.py" o="uzadow" g="staff" p="33188"/><f n="mathutil.pyc" o="uzadow" g="staff" p="33188"/><f n="mathutil.pyo" o="uzadow" g="staff" p="33188"/><f n="mtemu.py" o="uzadow" g="staff" p="33188"/><f n="mtemu.pyc" o="uzadow" g="staff" p="33188"/><f n="mtemu.pyo" o="uzadow" g="staff" p="33188"/><f n="parsecamargs.py" o="uzadow" g="staff" p="33188"/><f n="parsecamargs.pyc" o="uzadow" g="staff" p="33188"/><f n="parsecamargs.pyo" o="uzadow" g="staff" p="33188"/><f n="plugin" o="uzadow" g="staff" p="16877"><f n="fidtracker.so" o="uzadow" g="staff" p="33261"/><f n="osgnode.so" o="uzadow" g="staff" p="33261"/></f><f n="samples" o="uzadow" g="staff" p="16877"><f n="anim1.py" o="uzadow" g="staff" p="33188"/><f n="anim1.pyc" o="uzadow" g="staff" p="33188"/><f n="anim1.pyo" o="uzadow" g="staff" p="33188"/><f n="anim2.py" o="uzadow" g="staff" p="33188"/><f n="anim2.pyc" o="uzadow" g="staff" p="33188"/><f n="anim2.pyo" o="uzadow" g="staff" p="33188"/><f n="attributes.py" o="uzadow" g="staff" p="33188"/><f n="attributes.pyc" o="uzadow" g="staff" p="33188"/><f n="attributes.pyo" o="uzadow" g="staff" p="33188"/><f n="canvas.avg" o="uzadow" g="staff" p="33188"/><f n="canvas.py" o="uzadow" g="staff" p="33188"/><f n="canvas.pyc" o="uzadow" g="staff" p="33188"/><f n="canvas.pyo" o="uzadow" g="staff" p="33188"/><f n="drag.avg" o="uzadow" g="staff" p="33188"/><f n="drag.py" o="uzadow" g="staff" p="33188"/><f n="drag.pyc" o="uzadow" g="staff" p="33188"/><f n="drag.pyo" o="uzadow" g="staff" p="33188"/><f n="event1.avg" o="uzadow" g="staff" p="33188"/><f n="event1.py" o="uzadow" g="staff" p="33188"/><f n="event1.pyc" o="uzadow" g="staff" p="33188"/><f n="event1.pyo" o="uzadow" g="staff" p="33188"/><f n="event2.avg" o="uzadow" g="staff" p="33188"/><f n="event2.py" o="uzadow" g="staff" p="33188"/><f n="event2.pyc" o="uzadow" g="staff" p="33188"/><f n="event2.pyo" o="uzadow" g="staff" p="33188"/><f n="event3.py" o="uzadow" g="staff" p="33188"/><f n="event3.pyc" o="uzadow" g="staff" p="33188"/><f n="event3.pyo" o="uzadow" g="staff" p="33188"/><f n="globalcoords.avg" o="uzadow" g="staff" p="33188"/><f n="localcoords.avg" o="uzadow" g="staff" p="33188"/><f n="localcoordsrot.avg" o="uzadow" g="staff" p="33188"/><f n="mesh.py" o="uzadow" g="staff" p="33188"/><f n="mesh.pyc" o="uzadow" g="staff" p="33188"/><f n="mesh.pyo" o="uzadow" g="staff" p="33188"/><f n="minimal.py" o="uzadow" g="staff" p="33188"/><f n="minimal.pyc" o="uzadow" g="staff" p="33188"/><f n="minimal.pyo" o="uzadow" g="staff" p="33188"/><f n="plugin.py" o="uzadow" g="staff" p="33188"/><f n="plugin.pyc" o="uzadow" g="staff" p="33188"/><f n="plugin.pyo" o="uzadow" g="staff" p="33188"/><f n="rgb24-64x64.png" o="uzadow" g="staff" p="33188"/><f n="rotcustompivot.avg" o="uzadow" g="staff" p="33188"/><f n="rotdefaultpivot.avg" o="uzadow" g="staff" p="33188"/><f n="showvideo.py" o="uzadow" g="staff" p="33188"/><f n="showvideo.pyc" o="uzadow" g="staff" p="33188"/><f n="showvideo.pyo" o="uzadow" g="staff" p="33188"/><f n="text.avg" o="uzadow" g="staff" p="33188"/><f n="timer.py" o="uzadow" g="staff" p="33188"/><f n="timer.pyc" o="uzadow" g="staff" p="33188"/><f n="timer.pyo" o="uzadow" g="staff" p="33188"/><f n="timer2.py" o="uzadow" g="staff" p="33188"/><f n="timer2.pyc" o="uzadow" g="staff" p="33188"/><f n="timer2.pyo" o="uzadow" g="staff" p="33188"/><f n="timer3.py" o="uzadow" g="staff" p="33188"/><f n="timer3.pyc" o="uzadow" g="staff" p="33188"/><f n="timer3.pyo" o="uzadow" g="staff" p="33188"/><f n="twovideos.py" o="uzadow" g="staff" p="33188"/><f n="twovideos.pyc" o="uzadow" g="staff" p="33188"/><f n="twovideos.pyo" o="uzadow" g="staff" p="33188"/><f n="video.avg" o="uzadow" g="staff" p="33188"/><f n="video.py" o="uzadow" g="staff" p="33188"/><f n="video.pyc" o="uzadow" g="staff" p="33188"/><f n="video.pyo" o="uzadow" g="staff" p="33188"/><f n="videochooser.py" o="uzadow" g="staff" p="33188"/><f n="videochooser.pyc" o="uzadow" g="staff" p="33188"/><f n="videochooser.pyo" o="uzadow" g="staff" p="33188"/><f n="words1.avg" o="uzadow" g="staff" p="33188"/><f n="words2.avg" o="uzadow" g="staff" p="33188"/><f n="wordspos.avg" o="uzadow" g="staff" p="33188"/></f><f n="testapp.py" o="uzadow" g="staff" p="33188"/><f n="testapp.pyc" o="uzadow" g="staff" p="33188"/><f n="testapp.pyo" o="uzadow" g="staff" p="33188"/><f n="testcase.py" o="uzadow" g="staff" p="33188"/><f n="testcase.pyc" o="uzadow" g="staff" p="33188"/><f n="testcase.pyo" o="uzadow" g="staff" p="33188"/><f n="textarea.py" o="uzadow" g="staff" p="33188"/><f n="textarea.pyc" o="uzadow" g="staff" p="33188"/><f n="textarea.pyo" o="uzadow" g="staff" p="33188"/><f n="trackerhelper.py" o="uzadow" g="staff" p="33188"/><f n="trackerhelper.pyc" o="uzadow" g="staff" p="33188"/><f n="trackerhelper.pyo" o="uzadow" g="staff" p="33188"/><f n="ui" o="uzadow" g="staff" p="16877"><f n="__init__.py" o="uzadow" g="staff" p="33188"/><f n="__init__.pyc" o="uzadow" g="staff" p="33188"/><f n="__init__.pyo" o="uzadow" g="staff" p="33188"/><f n="button.py" o="uzadow" g="staff" p="33188"/><f n="button.pyc" o="uzadow" g="staff" p="33188"/><f n="button.pyo" o="uzadow" g="staff" p="33188"/><f n="keyboard.py" o="uzadow" g="staff" p="33188"/><f n="keyboard.pyc" o="uzadow" g="staff" p="33188"/><f n="keyboard.pyo" o="uzadow" g="staff" p="33188"/></f><f n="version.txt" o="uzadow" g="staff" p="33188"/></f></f></pkg-contents> \ No newline at end of file
diff --git a/mac/libavg.10.6.pmdoc/01dist.xml b/mac/libavg.10.6.pmdoc/01dist.xml
new file mode 100644
index 0000000..855a500
--- /dev/null
+++ b/mac/libavg.10.6.pmdoc/01dist.xml
@@ -0,0 +1 @@
+<pkgref spec="1.12" uuid="3F6840B1-53C2-4C3A-BD37-A49AFFC0F84B"><config><identifier>org.c-base.libavg.dist.pkg</identifier><version>1.8.1</version><description></description><post-install type="none"/><requireAuthorization/><installFrom mod="true">/Users/uzadow/devel/libavg/dist</installFrom><installTo mod="true">/Library/Python/2.7/site-packages/</installTo><flags><followSymbolicLinks/><discardResourceForks/><allowRevert/></flags><packageStore type="internal"></packageStore><mod>scripts.scriptsDirectoryPath.isAbsoluteType</mod><mod>scripts.scriptsDirectoryPath.isRelativeType</mod><mod>scripts.postflight.path</mod><mod>installTo</mod><mod>scripts.postinstall.path</mod><mod>scripts.postinstall.isRelativeType</mod><mod>version</mod><mod>parent</mod><mod>scripts.scriptsDirectoryPath.path</mod><mod>identifier</mod><mod>installFrom.path</mod><mod>installTo.path</mod></config><scripts><postflight mod="true">/Users/uzadow/libavg/libavg/mac/installscripts/postflight</postflight><scripts-dir mod="true">/Users/uzadow/devel/libavg/libavg/mac/installscripts</scripts-dir></scripts><contents><file-list>01dist-contents.xml</file-list><filter>/CVS$</filter><filter>/\.svn$</filter><filter>/\.cvsignore$</filter><filter>/\.cvspass$</filter><filter>/\.DS_Store$</filter></contents></pkgref> \ No newline at end of file
diff --git a/mac/libavg.10.6.pmdoc/02bindist-contents.xml b/mac/libavg.10.6.pmdoc/02bindist-contents.xml
new file mode 100644
index 0000000..5373587
--- /dev/null
+++ b/mac/libavg.10.6.pmdoc/02bindist-contents.xml
@@ -0,0 +1 @@
+<pkg-contents spec="1.12"><f n="bindist" o="" g="" p="0" pt="/Users/uzadow/devel/libavg/bindist" m="false" t="file"/></pkg-contents> \ No newline at end of file
diff --git a/mac/libavg.10.6.pmdoc/02bindist.xml b/mac/libavg.10.6.pmdoc/02bindist.xml
new file mode 100644
index 0000000..a88ca8a
--- /dev/null
+++ b/mac/libavg.10.6.pmdoc/02bindist.xml
@@ -0,0 +1 @@
+<pkgref spec="1.12" uuid="BCA7515E-4B15-4CF3-85BF-E4BE3BA42837"><config><identifier>org.c-base.libavg.bindist.pkg</identifier><version>1.8.1</version><description></description><post-install type="none"/><requireAuthorization/><installFrom mod="true">/Users/uzadow/devel/libavg/bindist</installFrom><installTo mod="true">/usr/bin</installTo><flags><followSymbolicLinks/></flags><packageStore type="internal"></packageStore><mod>installTo.path</mod><mod>installFrom.path</mod><mod>parent</mod><mod>installTo</mod><mod>version</mod></config><contents><file-list>02bindist-contents.xml</file-list><filter>/CVS$</filter><filter>/\.svn$</filter><filter>/\.cvsignore$</filter><filter>/\.cvspass$</filter><filter>/\.DS_Store$</filter></contents></pkgref> \ No newline at end of file
diff --git a/mac/libavg.10.6.pmdoc/index.xml b/mac/libavg.10.6.pmdoc/index.xml
new file mode 100644
index 0000000..562535b
--- /dev/null
+++ b/mac/libavg.10.6.pmdoc/index.xml
@@ -0,0 +1 @@
+<pkmkdoc spec="1.12"><properties><title>libavg</title><build>/Users/coder/Desktop/libavg.pkg</build><organization>org.c-base</organization><userSees ui="easy"/><min-target os="3"/><domain system="true"/></properties><distribution><versions min-spec="1.000000"/><scripts></scripts></distribution><contents><choice title="dist" id="choice1" starts_selected="true" starts_enabled="true" starts_hidden="false"><pkgref id="org.c-base.libavg.dist.pkg"/></choice><choice title="bindist" id="choice11" starts_selected="true" starts_enabled="true" starts_hidden="false"><pkgref id="org.c-base.libavg.bindist.pkg"/></choice></contents><resources bg-scale="proportional" bg-align="bottomleft"><locale lang="en"><resource relative="true" mod="true" type="background">installscripts/background.tif</resource><resource relative="true" mod="true" type="readme">welcome.txt</resource><resource relative="true" mod="true" type="welcome">readme.txt</resource></locale></resources><flags/><item type="file">01dist.xml</item><item type="file">02bindist.xml</item><mod>properties.customizeOption</mod><mod>description</mod></pkmkdoc> \ No newline at end of file
diff --git a/mac/librsvg_configure.patch b/mac/librsvg_configure.patch
new file mode 100644
index 0000000..fcb81d6
--- /dev/null
+++ b/mac/librsvg_configure.patch
@@ -0,0 +1,17 @@
+101d100
+< libxml-2.0 >= $LIBXML_REQUIRED \
+305,315d303
+< ##################################################
+< # Checks for gtk-doc and docbook-tools
+< ##################################################
+<
+< GTK_DOC_CHECK([1.13],[--flavour no-tmpl])
+<
+< AC_SUBST([GLIB_PREFIX],[$($PKG_CONFIG --variable=prefix glib-2.0)])
+< AC_SUBST([GDK_PIXBUF_PREFIX],[$($PKG_CONFIG --variable=prefix gdk-pixbuf-2.0)])
+< AC_SUBST([GTK_PREFIX],[$($PKG_CONFIG --variable=prefix gdk-pixbuf-2.0)])
+< AC_SUBST([CAIRO_PREFIX],[$($PKG_CONFIG --variable=prefix cairo)])
+<
+365,366d352
+< doc/Makefile
+< doc/version.xml
diff --git a/mac/librsvg_makefile.patch b/mac/librsvg_makefile.patch
new file mode 100644
index 0000000..c5c5e33
--- /dev/null
+++ b/mac/librsvg_makefile.patch
@@ -0,0 +1,11 @@
+1c1
+< SUBDIRS = . gdk-pixbuf-loader data tests tools doc
+---
+> SUBDIRS = . gdk-pixbuf-loader data tests tools
+200,201c200
+< librsvg.def \
+< gtk-doc.make
+---
+> librsvg.def
+245d243
+< DISTCHECK_CONFIGURE_FLAGS = --enable-gtk-doc
diff --git a/mac/libsdl_mavericks.patch b/mac/libsdl_mavericks.patch
new file mode 100644
index 0000000..bf07703
--- /dev/null
+++ b/mac/libsdl_mavericks.patch
@@ -0,0 +1,11 @@
+--- a/src/video/quartz/SDL_QuartzVideo.h Sat Aug 10 10:54:03 2013 -0700
++++ b/src/video/quartz/SDL_QuartzVideo.h Thu Sep 05 06:38:57 2013 -0700
+@@ -91,7 +91,6 @@
+ CGDirectDisplayID display; /* 0 == main display (only support single display) */
+ const void *mode; /* current mode of the display */
+ const void *save_mode; /* original mode of the display */
+- CGDirectPaletteRef palette; /* palette of an 8-bit display */
+ NSOpenGLContext *gl_context; /* OpenGL rendering context */
+ NSGraphicsContext *nsgfx_context; /* Cocoa graphics context */
+ Uint32 width, height, bpp; /* frequently used data about the display */
+
diff --git a/mac/libtool.m4.patch b/mac/libtool.m4.patch
new file mode 100644
index 0000000..d3215b0
--- /dev/null
+++ b/mac/libtool.m4.patch
@@ -0,0 +1,20 @@
+945c945
+< _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;;
+---
+> _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress ${wl}-read_only_relocs ${wl}suppress' ;;
+947c947
+< _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
+---
+> _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress ${wl}-read_only_relocs ${wl}suppress' ;;
+954c954
+< _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+---
+> _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup ${wl}-read_only_relocs ${wl}suppress' ;;
+956c956
+< _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
+---
+> _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress ${wl}-read_only_relocs ${wl}suppress' ;;
+958c958
+< _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+---
+> _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup ${wl}-read_only_relocs ${wl}suppress' ;;
diff --git a/mac/pkg-config-mavericks.patch b/mac/pkg-config-mavericks.patch
new file mode 100644
index 0000000..a19f1be
--- /dev/null
+++ b/mac/pkg-config-mavericks.patch
@@ -0,0 +1,6 @@
+205,207d204
+< #if defined (__clang__)
+< # define G_INLINE_FUNC inline
+< #else
+222d218
+< #endif
diff --git a/mac/readme.txt b/mac/readme.txt
new file mode 100644
index 0000000..e58f8f4
--- /dev/null
+++ b/mac/readme.txt
@@ -0,0 +1,3 @@
+
+This will install the libavg library on your computer. Installation can take a while - be patient.
+
diff --git a/mac/stpncpy.patch b/mac/stpncpy.patch
new file mode 100644
index 0000000..e18af95
--- /dev/null
+++ b/mac/stpncpy.patch
@@ -0,0 +1,13 @@
+diff -Naurp gettext-0.18.1.1.orig/gettext-tools/configure gettext-0.18.1.1/gettext-tools/configure
+--- gettext-tools/configure 2010-06-06 13:12:20.000000000 -0700
++++ gettext-tools/configure 2010-08-13 23:24:09.000000000 -0700
+@@ -40606,7 +40606,9 @@ else
+ #include <stdlib.h>
+ #include <string.h> /* for strcpy */
+ /* The stpncpy prototype is missing in <string.h> on AIX 4. */
++#ifndef stpncpy
+ extern char *stpncpy (char *dest, const char *src, size_t n);
++#endif
+ int main () {
+ const char *src = "Hello";
+ char dest[10];
diff --git a/mac/welcome.txt b/mac/welcome.txt
new file mode 100644
index 0000000..6e5198b
--- /dev/null
+++ b/mac/welcome.txt
@@ -0,0 +1,3 @@
+After the installer runs, please make sure that everything works by running the tests. To do this, open a terminal, cd to /Library/Python/2.7/site-packages/libavg/avg/test and call ./Test.py. You should see some test graphics flicker on the screen. The last message in the terminal should read 'OK'.
+
+We welcome your feedback. See http://www.libavg.de/ for details.
diff --git a/makedocs.sh b/makedocs.sh
new file mode 100755
index 0000000..11ad531
--- /dev/null
+++ b/makedocs.sh
@@ -0,0 +1,6 @@
+#!/bin/bash
+
+cd sphinxdoc
+#sphinx-build -b linkcheck . _build/
+sphinx-build -b coverage . _build/
+sphinx-build -b html . _build/reference
diff --git a/man/Makefile.am b/man/Makefile.am
new file mode 100644
index 0000000..e8e2106
--- /dev/null
+++ b/man/Makefile.am
@@ -0,0 +1,3 @@
+man_MANS = avgrc.5 avg_audioplayer.1 avg_showcamera.1 avg_showfont.1 avg_videoplayer.1 \
+ avg_chromakey.1 avg_showfile.1 avg_videoinfo.1
+EXTRA_DIST = $(man_MANS)
diff --git a/man/avg_audioplayer.1 b/man/avg_audioplayer.1
new file mode 100644
index 0000000..04b5d7b
--- /dev/null
+++ b/man/avg_audioplayer.1
@@ -0,0 +1,11 @@
+.TH AVG_AUDIPLAYER "1" "March 2011" "libavg 1.5.4" "User Commands"
+.SH NAME
+avg_audioplayer \- audio player
+.SH SYNOPSIS
+.B avg_audioplayer
+\fIfile\fR
+.SH DESCRIPTION
+Play an audio file.
+.PP
+.SH AUTHOR
+Ulrich von Zadow <coder@c-base.org>
diff --git a/man/avg_chromakey.1 b/man/avg_chromakey.1
new file mode 100644
index 0000000..12774b1
--- /dev/null
+++ b/man/avg_chromakey.1
@@ -0,0 +1,39 @@
+.TH AVG_CHROMAKEY "1" "March 2011" "libavg 1.5.4" "User Commands"
+.SH NAME
+avg_chromakey \- test application for libavg chromakey filter
+.SH SYNOPSIS
+.B avg_chromakey
+\fI\-t DRIVER [OPTION]...\fR
+.SH DESCRIPTION
+Stream a live image from a camera and apply a chromakey filter.
+.PP
+.SH OPTIONS
+.TP
+\fB\-h\fR, \fB\-\-help\fR
+Show a brief description of the options.
+.TP
+\fB\-t\fR, \fB\-\-driver\fR DRIVER
+One of the camera subsystems supported by libavg (supported: firewire, video4linux, directshow).
+.TP
+\fB\-d\fR, \fB\-\-device\fR DEVICE
+Camera device identifier (depending on the driver, a GUID or device path is expected).
+.TP
+\fB\-u\fR, \fB\-\-unit\fR UNIT
+Unit number. Used for cameras or other capture devices which deliver several images (e.g. stereo cameras or TV capture cards).
+.TP
+\fB\-w\fR, \fB\-\-width\fR WIDTH
+Camera image width.
+.TP
+\fB\-e\fR, \fB\-\-height\fR HEIGHT
+Camera image height.
+.TP
+\fB\-p\fR, \fB\-\-pixelformat\fR PIXELFORMAT
+Camera pixel format (one of: I8, I16, YUV411, YUV422, YUYV422, RGB, BGR, BAYER8).
+.TP
+\fB\-f\fR, \fB\-\-framerate\fR FRAMERATE
+Frames per second.
+.TP
+\fB\-8\fR, \fB\-\-fw800\fR
+Set firewire bus speed to s800 (if supported).
+.SH AUTHOR
+Ulrich von Zadow <coder@c-base.org>
diff --git a/man/avg_showcamera.1 b/man/avg_showcamera.1
new file mode 100644
index 0000000..88de2d4
--- /dev/null
+++ b/man/avg_showcamera.1
@@ -0,0 +1,54 @@
+.TH AVG_SHOWCAMERA "1" "March 2011" "libavg 1.5.4" "User Commands"
+.SH NAME
+avg_showcamera \- camera discovery and display tool
+.SH SYNOPSIS
+.B avg_showcamera
+\fI\-l\fR
+.HP
+.B avg_showcamera
+\fI\-r\fR
+.HP
+.B avg_showcamera
+\fI\-t DRIVER [OPTION]...\fR
+.SH DESCRIPTION
+Query and list attached cameras, reset firewire bus, show video stream.
+.PP
+.SH OPTIONS
+.TP
+\fB\-h\fR, \fB\-\-help\fR
+Show a brief description of the options.
+.TP
+\fB\-l\fR, \fB\-\-dump\fR
+Dump a list of available cameras to the console.
+.TP
+\fB\-r\fR, \fB\-\-resetbus\fR
+Reset the firewire bus and free allocated bandwidth.
+.TP
+\fB\-t\fR, \fB\-\-driver\fR DRIVER
+One of the camera subsystems supported by libavg (supported: firewire, video4linux, directshow).
+.TP
+\fB\-d\fR, \fB\-\-device\fR DEVICE
+Camera device identifier (depending on the driver, a GUID or device path is expected).
+.TP
+\fB\-u\fR, \fB\-\-unit\fR UNIT
+Unit number. Used for cameras or other capture devices which deliver several images (e.g. stereo cameras or TV capture cards).
+.TP
+\fB\-w\fR, \fB\-\-width\fR WIDTH
+Camera image width.
+.TP
+\fB\-e\fR, \fB\-\-height\fR HEIGHT
+Camera image height.
+.TP
+\fB\-p\fR, \fB\-\-pixelformat\fR PIXELFORMAT
+Camera pixel format (one of: I8, I16, YUV411, YUV422, YUYV422, RGB, BGR, BAYER8).
+.TP
+\fB\-f\fR, \fB\-\-framerate\fR FRAMERATE
+Frames per second.
+.TP
+\fB\-8\fR, \fB\-\-fw800\fR
+Set firewire bus speed to s800 (if supported).
+.TP
+\fB\-s\fR, \fB\-\-noinfo\fR
+Don't show any info overlayed on the screen.
+.SH AUTHOR
+Ulrich von Zadow <coder@c-base.org>
diff --git a/man/avg_showfile.1 b/man/avg_showfile.1
new file mode 100644
index 0000000..1f5329b
--- /dev/null
+++ b/man/avg_showfile.1
@@ -0,0 +1,11 @@
+.TH AVG_SHOWFILE "1" "March 2011" "libavg 1.5.4" "User Commands"
+.SH NAME
+avg_showfile \- display an avg file
+.SH SYNOPSIS
+.B avg_showfile
+\fIfile\fR
+.SH DESCRIPTION
+Open and render an avg file.
+.PP
+.SH AUTHOR
+Ulrich von Zadow <coder@c-base.org>
diff --git a/man/avg_showfont.1 b/man/avg_showfont.1
new file mode 100644
index 0000000..f9b26d8
--- /dev/null
+++ b/man/avg_showfont.1
@@ -0,0 +1,19 @@
+.TH AVG_SHOWFONT "1" "March 2011" "libavg 1.5.4" "User Commands"
+.SH NAME
+avg_showfont \- font enumeration and preview tool
+.SH SYNOPSIS
+.B avg_showfont
+[\fIfontname\fR] [\fItext\fR]
+.SH DESCRIPTION
+List available font faces and generate preview of their variants.
+.PP
+If invoked without arguments, avg_showfont generates a list of font family names and prints them on the console.
+Fontconfig is used for font discovery. Fonts are searched for in the system font path and in $PWD/fonts.
+.PP
+If \fBfontname\fR is specified, the chosen font is displayed in a window, with one line for
+each available variant.
+.PP
+If supplied, the optional \fBtext\fR argument is used instead of the variant name in the
+sample text.
+.SH AUTHOR
+Ulrich von Zadow <coder@c-base.org>
diff --git a/man/avg_videoinfo.1 b/man/avg_videoinfo.1
new file mode 100644
index 0000000..80c2e40
--- /dev/null
+++ b/man/avg_videoinfo.1
@@ -0,0 +1,29 @@
+.TH AVG_VIDEOINFO "1" "March 2011" "libavg 1.5.4" "User Commands"
+.SH NAME
+avg_videoinfo \- video inspection tool
+.SH SYNOPSIS
+.B avg_videoinfo
+\fIfile(s)\fR \fI[OPTION]\fR
+.SH DESCRIPTION
+Dump video file format information to the console
+.PP
+Inspects the given file(s) and dumps information about duration, bitrate, video/audio codec,
+video frame size and pixel format, video fps, audio sample rate and number of channels for
+each file given.
+.PP
+The default output format is text.
+.PP
+XML and CSV formats can be chosen with the appropriate options.
+.PP
+.SH OPTIONS
+.TP
+\fB\-h\fR, \fB\-\-help\fR
+Show a brief description of the options.
+.TP
+\fB\-x\fR, \fB\-\-xml\fR
+XML output format.
+.TP
+\fB\-c\fR, \fB\-\-csv\fR
+CSV output format.
+.SH AUTHOR
+Ulrich von Zadow <coder@c-base.org>
diff --git a/man/avg_videoplayer.1 b/man/avg_videoplayer.1
new file mode 100644
index 0000000..42b1129
--- /dev/null
+++ b/man/avg_videoplayer.1
@@ -0,0 +1,11 @@
+.TH AVG_VIDEOPLAYER "1" "March 2011" "libavg 1.5.4" "User Commands"
+.SH NAME
+avg_videoplayer \- video player
+.SH SYNOPSIS
+.B avg_videoplayer
+\fIfile\fR
+.SH DESCRIPTION
+Play a video file using libavg.
+.PP
+.SH AUTHOR
+Ulrich von Zadow <coder@c-base.org>
diff --git a/man/avgrc.5 b/man/avgrc.5
new file mode 100755
index 0000000..6582b7d
--- /dev/null
+++ b/man/avgrc.5
@@ -0,0 +1,33 @@
+.ad 1
+.nh
+.hlm 0
+.TH avgrc 5 "13 January 2005" "avg"
+.SH NAME
+avgrc \- avg configuration file
+.SH DESCRIPTION
+.I avgrc
+contains configuration information for the
+.B avg
+player, including display data and font directory information.
+.B avg
+looks
+for a system-wide file in
+.I /etc/
+and a user-specific file in
+.I $HOME.
+The file is xml-based. There is an example avgrc.default in the
+avg source directory. The available options are described in the
+.B avg
+(1) man page.
+
+.SH FILES
+.PD 0
+/etc/avgrc - System-wide configuration file.
+.P
+$HOME/avgrc - User-specific configuration file.
+.PD
+.SH SEE ALSO
+.B avg
+(1)
+.SH AUTHORS
+Ulrich von Zadow (coder@c-base.org)
diff --git a/missing b/missing
new file mode 100755
index 0000000..6a37006
--- /dev/null
+++ b/missing
@@ -0,0 +1,336 @@
+#! /bin/sh
+# Common stub for a few missing GNU programs while installing.
+# Copyright (C) 1996, 1997, 1999, 2000, 2002 Free Software Foundation, Inc.
+# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+if test $# -eq 0; then
+ echo 1>&2 "Try \`$0 --help' for more information"
+ exit 1
+fi
+
+run=:
+
+# In the cases where this matters, `missing' is being run in the
+# srcdir already.
+if test -f configure.ac; then
+ configure_ac=configure.ac
+else
+ configure_ac=configure.in
+fi
+
+case "$1" in
+--run)
+ # Try to run requested program, and just exit if it succeeds.
+ run=
+ shift
+ "$@" && exit 0
+ ;;
+esac
+
+# If it does not exist, or fails to run (possibly an outdated version),
+# try to emulate it.
+case "$1" in
+
+ -h|--h|--he|--hel|--help)
+ echo "\
+$0 [OPTION]... PROGRAM [ARGUMENT]...
+
+Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
+error status if there is no known handling for PROGRAM.
+
+Options:
+ -h, --help display this help and exit
+ -v, --version output version information and exit
+ --run try to run the given command, and emulate it if it fails
+
+Supported PROGRAM values:
+ aclocal touch file \`aclocal.m4'
+ autoconf touch file \`configure'
+ autoheader touch file \`config.h.in'
+ automake touch all \`Makefile.in' files
+ bison create \`y.tab.[ch]', if possible, from existing .[ch]
+ flex create \`lex.yy.c', if possible, from existing .c
+ help2man touch the output file
+ lex create \`lex.yy.c', if possible, from existing .c
+ makeinfo touch the output file
+ tar try tar, gnutar, gtar, then tar without non-portable flags
+ yacc create \`y.tab.[ch]', if possible, from existing .[ch]"
+ ;;
+
+ -v|--v|--ve|--ver|--vers|--versi|--versio|--version)
+ echo "missing 0.4 - GNU automake"
+ ;;
+
+ -*)
+ echo 1>&2 "$0: Unknown \`$1' option"
+ echo 1>&2 "Try \`$0 --help' for more information"
+ exit 1
+ ;;
+
+ aclocal*)
+ if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+ # We have it, but it failed.
+ exit 1
+ fi
+
+ echo 1>&2 "\
+WARNING: \`$1' is missing on your system. You should only need it if
+ you modified \`acinclude.m4' or \`${configure_ac}'. You might want
+ to install the \`Automake' and \`Perl' packages. Grab them from
+ any GNU archive site."
+ touch aclocal.m4
+ ;;
+
+ autoconf)
+ if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+ # We have it, but it failed.
+ exit 1
+ fi
+
+ echo 1>&2 "\
+WARNING: \`$1' is missing on your system. You should only need it if
+ you modified \`${configure_ac}'. You might want to install the
+ \`Autoconf' and \`GNU m4' packages. Grab them from any GNU
+ archive site."
+ touch configure
+ ;;
+
+ autoheader)
+ if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+ # We have it, but it failed.
+ exit 1
+ fi
+
+ echo 1>&2 "\
+WARNING: \`$1' is missing on your system. You should only need it if
+ you modified \`acconfig.h' or \`${configure_ac}'. You might want
+ to install the \`Autoconf' and \`GNU m4' packages. Grab them
+ from any GNU archive site."
+ files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
+ test -z "$files" && files="config.h"
+ touch_files=
+ for f in $files; do
+ case "$f" in
+ *:*) touch_files="$touch_files "`echo "$f" |
+ sed -e 's/^[^:]*://' -e 's/:.*//'`;;
+ *) touch_files="$touch_files $f.in";;
+ esac
+ done
+ touch $touch_files
+ ;;
+
+ automake*)
+ if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+ # We have it, but it failed.
+ exit 1
+ fi
+
+ echo 1>&2 "\
+WARNING: \`$1' is missing on your system. You should only need it if
+ you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
+ You might want to install the \`Automake' and \`Perl' packages.
+ Grab them from any GNU archive site."
+ find . -type f -name Makefile.am -print |
+ sed 's/\.am$/.in/' |
+ while read f; do touch "$f"; done
+ ;;
+
+ autom4te)
+ if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+ # We have it, but it failed.
+ exit 1
+ fi
+
+ echo 1>&2 "\
+WARNING: \`$1' is needed, and you do not seem to have it handy on your
+ system. You might have modified some files without having the
+ proper tools for further handling them.
+ You can get \`$1Help2man' as part of \`Autoconf' from any GNU
+ archive site."
+
+ file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'`
+ test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'`
+ if test -f "$file"; then
+ touch $file
+ else
+ test -z "$file" || exec >$file
+ echo "#! /bin/sh"
+ echo "# Created by GNU Automake missing as a replacement of"
+ echo "# $ $@"
+ echo "exit 0"
+ chmod +x $file
+ exit 1
+ fi
+ ;;
+
+ bison|yacc)
+ echo 1>&2 "\
+WARNING: \`$1' is missing on your system. You should only need it if
+ you modified a \`.y' file. You may need the \`Bison' package
+ in order for those modifications to take effect. You can get
+ \`Bison' from any GNU archive site."
+ rm -f y.tab.c y.tab.h
+ if [ $# -ne 1 ]; then
+ eval LASTARG="\${$#}"
+ case "$LASTARG" in
+ *.y)
+ SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
+ if [ -f "$SRCFILE" ]; then
+ cp "$SRCFILE" y.tab.c
+ fi
+ SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
+ if [ -f "$SRCFILE" ]; then
+ cp "$SRCFILE" y.tab.h
+ fi
+ ;;
+ esac
+ fi
+ if [ ! -f y.tab.h ]; then
+ echo >y.tab.h
+ fi
+ if [ ! -f y.tab.c ]; then
+ echo 'main() { return 0; }' >y.tab.c
+ fi
+ ;;
+
+ lex|flex)
+ echo 1>&2 "\
+WARNING: \`$1' is missing on your system. You should only need it if
+ you modified a \`.l' file. You may need the \`Flex' package
+ in order for those modifications to take effect. You can get
+ \`Flex' from any GNU archive site."
+ rm -f lex.yy.c
+ if [ $# -ne 1 ]; then
+ eval LASTARG="\${$#}"
+ case "$LASTARG" in
+ *.l)
+ SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
+ if [ -f "$SRCFILE" ]; then
+ cp "$SRCFILE" lex.yy.c
+ fi
+ ;;
+ esac
+ fi
+ if [ ! -f lex.yy.c ]; then
+ echo 'main() { return 0; }' >lex.yy.c
+ fi
+ ;;
+
+ help2man)
+ if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+ # We have it, but it failed.
+ exit 1
+ fi
+
+ echo 1>&2 "\
+WARNING: \`$1' is missing on your system. You should only need it if
+ you modified a dependency of a manual page. You may need the
+ \`Help2man' package in order for those modifications to take
+ effect. You can get \`Help2man' from any GNU archive site."
+
+ file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
+ if test -z "$file"; then
+ file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'`
+ fi
+ if [ -f "$file" ]; then
+ touch $file
+ else
+ test -z "$file" || exec >$file
+ echo ".ab help2man is required to generate this page"
+ exit 1
+ fi
+ ;;
+
+ makeinfo)
+ if test -z "$run" && (makeinfo --version) > /dev/null 2>&1; then
+ # We have makeinfo, but it failed.
+ exit 1
+ fi
+
+ echo 1>&2 "\
+WARNING: \`$1' is missing on your system. You should only need it if
+ you modified a \`.texi' or \`.texinfo' file, or any other file
+ indirectly affecting the aspect of the manual. The spurious
+ call might also be the consequence of using a buggy \`make' (AIX,
+ DU, IRIX). You might want to install the \`Texinfo' package or
+ the \`GNU make' package. Grab either from any GNU archive site."
+ file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
+ if test -z "$file"; then
+ file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
+ file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file`
+ fi
+ touch $file
+ ;;
+
+ tar)
+ shift
+ if test -n "$run"; then
+ echo 1>&2 "ERROR: \`tar' requires --run"
+ exit 1
+ fi
+
+ # We have already tried tar in the generic part.
+ # Look for gnutar/gtar before invocation to avoid ugly error
+ # messages.
+ if (gnutar --version > /dev/null 2>&1); then
+ gnutar "$@" && exit 0
+ fi
+ if (gtar --version > /dev/null 2>&1); then
+ gtar "$@" && exit 0
+ fi
+ firstarg="$1"
+ if shift; then
+ case "$firstarg" in
+ *o*)
+ firstarg=`echo "$firstarg" | sed s/o//`
+ tar "$firstarg" "$@" && exit 0
+ ;;
+ esac
+ case "$firstarg" in
+ *h*)
+ firstarg=`echo "$firstarg" | sed s/h//`
+ tar "$firstarg" "$@" && exit 0
+ ;;
+ esac
+ fi
+
+ echo 1>&2 "\
+WARNING: I can't seem to be able to run \`tar' with the given arguments.
+ You may want to install GNU tar or Free paxutils, or check the
+ command line arguments."
+ exit 1
+ ;;
+
+ *)
+ echo 1>&2 "\
+WARNING: \`$1' is needed, and you do not seem to have it handy on your
+ system. You might have modified some files without having the
+ proper tools for further handling them. Check the \`README' file,
+ it often tells you about the needed prerequirements for installing
+ this package. You may also peek at any GNU archive site, in case
+ some other package would contain this missing \`$1' program."
+ exit 1
+ ;;
+esac
+
+exit 0
diff --git a/mkinstalldirs b/mkinstalldirs
new file mode 100755
index 0000000..d2d5f21
--- /dev/null
+++ b/mkinstalldirs
@@ -0,0 +1,111 @@
+#! /bin/sh
+# mkinstalldirs --- make directory hierarchy
+# Author: Noah Friedman <friedman@prep.ai.mit.edu>
+# Created: 1993-05-16
+# Public domain
+
+errstatus=0
+dirmode=""
+
+usage="\
+Usage: mkinstalldirs [-h] [--help] [-m mode] dir ..."
+
+# process command line arguments
+while test $# -gt 0 ; do
+ case $1 in
+ -h | --help | --h*) # -h for help
+ echo "$usage" 1>&2
+ exit 0
+ ;;
+ -m) # -m PERM arg
+ shift
+ test $# -eq 0 && { echo "$usage" 1>&2; exit 1; }
+ dirmode=$1
+ shift
+ ;;
+ --) # stop option processing
+ shift
+ break
+ ;;
+ -*) # unknown option
+ echo "$usage" 1>&2
+ exit 1
+ ;;
+ *) # first non-opt arg
+ break
+ ;;
+ esac
+done
+
+for file
+do
+ if test -d "$file"; then
+ shift
+ else
+ break
+ fi
+done
+
+case $# in
+ 0) exit 0 ;;
+esac
+
+case $dirmode in
+ '')
+ if mkdir -p -- . 2>/dev/null; then
+ echo "mkdir -p -- $*"
+ exec mkdir -p -- "$@"
+ fi
+ ;;
+ *)
+ if mkdir -m "$dirmode" -p -- . 2>/dev/null; then
+ echo "mkdir -m $dirmode -p -- $*"
+ exec mkdir -m "$dirmode" -p -- "$@"
+ fi
+ ;;
+esac
+
+for file
+do
+ set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
+ shift
+
+ pathcomp=
+ for d
+ do
+ pathcomp="$pathcomp$d"
+ case $pathcomp in
+ -*) pathcomp=./$pathcomp ;;
+ esac
+
+ if test ! -d "$pathcomp"; then
+ echo "mkdir $pathcomp"
+
+ mkdir "$pathcomp" || lasterr=$?
+
+ if test ! -d "$pathcomp"; then
+ errstatus=$lasterr
+ else
+ if test ! -z "$dirmode"; then
+ echo "chmod $dirmode $pathcomp"
+ lasterr=""
+ chmod "$dirmode" "$pathcomp" || lasterr=$?
+
+ if test ! -z "$lasterr"; then
+ errstatus=$lasterr
+ fi
+ fi
+ fi
+ fi
+
+ pathcomp="$pathcomp/"
+ done
+done
+
+exit $errstatus
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# End:
+# mkinstalldirs ends here
diff --git a/sphinxdoc/ButtonStates.png b/sphinxdoc/ButtonStates.png
new file mode 100644
index 0000000..38d7764
--- /dev/null
+++ b/sphinxdoc/ButtonStates.png
Binary files differ
diff --git a/sphinxdoc/Recognizer.graffle b/sphinxdoc/Recognizer.graffle
new file mode 100644
index 0000000..cb2fe97
--- /dev/null
+++ b/sphinxdoc/Recognizer.graffle
@@ -0,0 +1,1780 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>ActiveLayerIndex</key>
+ <integer>0</integer>
+ <key>ApplicationVersion</key>
+ <array>
+ <string>com.omnigroup.OmniGraffle</string>
+ <string>138.28.0.154505</string>
+ </array>
+ <key>AutoAdjust</key>
+ <true/>
+ <key>BackgroundGraphic</key>
+ <dict>
+ <key>Bounds</key>
+ <string>{{0, 0}, {559, 783}}</string>
+ <key>Class</key>
+ <string>SolidGraphic</string>
+ <key>ID</key>
+ <integer>2</integer>
+ <key>Style</key>
+ <dict>
+ <key>shadow</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ </dict>
+ </dict>
+ <key>CanvasOrigin</key>
+ <string>{0, 0}</string>
+ <key>ColumnAlign</key>
+ <integer>1</integer>
+ <key>ColumnSpacing</key>
+ <real>36</real>
+ <key>CreationDate</key>
+ <string>2011-09-09 17:11:41 +0200</string>
+ <key>Creator</key>
+ <string>Ulrich von Zadow</string>
+ <key>DisplayScale</key>
+ <string>1.000 cm = 1.000 cm</string>
+ <key>GraphDocumentVersion</key>
+ <integer>6</integer>
+ <key>GraphicsList</key>
+ <array>
+ <dict>
+ <key>Bounds</key>
+ <string>{{256, 142.5}, {57, 21}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FitText</key>
+ <string>YES</string>
+ <key>Flow</key>
+ <string>Resize</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Font</key>
+ <string>HelveticaNeue</string>
+ <key>Size</key>
+ <real>9</real>
+ </dict>
+ <key>ID</key>
+ <integer>28</integer>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>fill</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>shadow</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>CornerRadius</key>
+ <real>7</real>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Align</key>
+ <integer>0</integer>
+ <key>Text</key>
+ <string>{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360
+{\fonttbl\f0\fnil\fcharset0 HelveticaNeue;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural\pardirnatural
+
+\f0\fs18 \cf0 onDetected}</string>
+ </dict>
+ <key>Wrap</key>
+ <string>NO</string>
+ </dict>
+ <dict>
+ <key>Class</key>
+ <string>LineGraphic</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Font</key>
+ <string>HelveticaNeue</string>
+ <key>Size</key>
+ <real>8</real>
+ </dict>
+ <key>Head</key>
+ <dict>
+ <key>ID</key>
+ <integer>13</integer>
+ </dict>
+ <key>ID</key>
+ <integer>27</integer>
+ <key>Points</key>
+ <array>
+ <string>{369.222, 223.693}</string>
+ <string>{317, 183}</string>
+ <string>{318, 122.5}</string>
+ <string>{369.337, 82.3082}</string>
+ </array>
+ <key>Style</key>
+ <dict>
+ <key>stroke</key>
+ <dict>
+ <key>CornerRadius</key>
+ <real>5</real>
+ <key>HeadArrow</key>
+ <string>0</string>
+ <key>HeadScale</key>
+ <real>3</real>
+ <key>HopLines</key>
+ <true/>
+ <key>HopType</key>
+ <integer>1</integer>
+ <key>LineType</key>
+ <integer>1</integer>
+ <key>TailArrow</key>
+ <string>FilledArrow</string>
+ <key>TailScale</key>
+ <real>3</real>
+ <key>Width</key>
+ <real>0.25</real>
+ </dict>
+ </dict>
+ <key>Tail</key>
+ <dict>
+ <key>ID</key>
+ <integer>21</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{480, 142.5}, {37, 21}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FitText</key>
+ <string>YES</string>
+ <key>Flow</key>
+ <string>Resize</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Font</key>
+ <string>HelveticaNeue</string>
+ <key>Size</key>
+ <real>9</real>
+ </dict>
+ <key>ID</key>
+ <integer>25</integer>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>fill</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>shadow</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>CornerRadius</key>
+ <real>7</real>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Align</key>
+ <integer>0</integer>
+ <key>Text</key>
+ <string>{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360
+{\fonttbl\f0\fnil\fcharset0 HelveticaNeue;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural\pardirnatural
+
+\f0\fs18 \cf0 onEnd}</string>
+ </dict>
+ <key>Wrap</key>
+ <string>NO</string>
+ </dict>
+ <dict>
+ <key>Class</key>
+ <string>LineGraphic</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Font</key>
+ <string>HelveticaNeue</string>
+ <key>Size</key>
+ <real>8</real>
+ </dict>
+ <key>Head</key>
+ <dict>
+ <key>ID</key>
+ <integer>13</integer>
+ </dict>
+ <key>ID</key>
+ <integer>24</integer>
+ <key>Points</key>
+ <array>
+ <string>{417.773, 223.685}</string>
+ <string>{474, 178}</string>
+ <string>{473, 125}</string>
+ <string>{418.603, 82.3087}</string>
+ </array>
+ <key>Style</key>
+ <dict>
+ <key>stroke</key>
+ <dict>
+ <key>CornerRadius</key>
+ <real>5</real>
+ <key>HeadArrow</key>
+ <string>FilledArrow</string>
+ <key>HeadScale</key>
+ <real>3</real>
+ <key>HopLines</key>
+ <true/>
+ <key>HopType</key>
+ <integer>1</integer>
+ <key>LineType</key>
+ <integer>1</integer>
+ <key>TailArrow</key>
+ <string>0</string>
+ <key>Width</key>
+ <real>0.25</real>
+ </dict>
+ </dict>
+ <key>Tail</key>
+ <dict>
+ <key>ID</key>
+ <integer>21</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{340, 183.5}, {57, 21}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FitText</key>
+ <string>YES</string>
+ <key>Flow</key>
+ <string>Resize</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Font</key>
+ <string>HelveticaNeue</string>
+ <key>Size</key>
+ <real>9</real>
+ </dict>
+ <key>ID</key>
+ <integer>23</integer>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>fill</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>shadow</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>CornerRadius</key>
+ <real>7</real>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Align</key>
+ <integer>0</integer>
+ <key>Text</key>
+ <string>{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360
+{\fonttbl\f0\fnil\fcharset0 HelveticaNeue;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural\pardirnatural
+
+\f0\fs18 \cf0 onDetected}</string>
+ </dict>
+ <key>Wrap</key>
+ <string>NO</string>
+ </dict>
+ <dict>
+ <key>Class</key>
+ <string>LineGraphic</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Font</key>
+ <string>HelveticaNeue</string>
+ <key>Size</key>
+ <real>8</real>
+ </dict>
+ <key>Head</key>
+ <dict>
+ <key>ID</key>
+ <integer>21</integer>
+ </dict>
+ <key>ID</key>
+ <integer>22</integer>
+ <key>Points</key>
+ <array>
+ <string>{394, 172.5}</string>
+ <string>{394, 223.5}</string>
+ </array>
+ <key>Style</key>
+ <dict>
+ <key>stroke</key>
+ <dict>
+ <key>CornerRadius</key>
+ <real>5</real>
+ <key>HeadArrow</key>
+ <string>FilledArrow</string>
+ <key>HeadScale</key>
+ <real>3</real>
+ <key>HopLines</key>
+ <true/>
+ <key>HopType</key>
+ <integer>1</integer>
+ <key>LineType</key>
+ <integer>1</integer>
+ <key>TailArrow</key>
+ <string>0</string>
+ <key>Width</key>
+ <real>0.25</real>
+ </dict>
+ </dict>
+ <key>Tail</key>
+ <dict>
+ <key>ID</key>
+ <integer>14</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{351.5, 224}, {85, 38}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>ID</key>
+ <integer>21</integer>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>fill</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Text</key>
+ <string>{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360
+{\fonttbl\f0\fnil\fcharset0 HelveticaNeue;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs18 \cf0 RUNNING}</string>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{323, 277.914}, {142, 25}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FitText</key>
+ <string>YES</string>
+ <key>Flow</key>
+ <string>Resize</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Font</key>
+ <string>HelveticaNeue</string>
+ <key>Size</key>
+ <real>12</real>
+ </dict>
+ <key>ID</key>
+ <integer>20</integer>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>fill</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>shadow</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>CornerRadius</key>
+ <real>7</real>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Text</key>
+ <string>{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360
+{\fonttbl\f0\fnil\fcharset0 HelveticaNeue;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf0 Continuous Recognizers}</string>
+ </dict>
+ <key>Wrap</key>
+ <string>NO</string>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{409, 97.086}, {35, 21}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FitText</key>
+ <string>YES</string>
+ <key>Flow</key>
+ <string>Resize</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Font</key>
+ <string>HelveticaNeue</string>
+ <key>Size</key>
+ <real>9</real>
+ </dict>
+ <key>ID</key>
+ <integer>19</integer>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>fill</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>shadow</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>CornerRadius</key>
+ <real>7</real>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Align</key>
+ <integer>0</integer>
+ <key>Text</key>
+ <string>{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360
+{\fonttbl\f0\fnil\fcharset0 HelveticaNeue;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural\pardirnatural
+
+\f0\fs18 \cf0 onFail}</string>
+ </dict>
+ <key>Wrap</key>
+ <string>NO</string>
+ </dict>
+ <dict>
+ <key>Class</key>
+ <string>LineGraphic</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Font</key>
+ <string>HelveticaNeue</string>
+ <key>Size</key>
+ <real>8</real>
+ </dict>
+ <key>Head</key>
+ <dict>
+ <key>ID</key>
+ <integer>13</integer>
+ </dict>
+ <key>ID</key>
+ <integer>17</integer>
+ <key>Points</key>
+ <array>
+ <string>{400.639, 133.527}</string>
+ <string>{409, 109}</string>
+ <string>{400.351, 82.4754}</string>
+ </array>
+ <key>Style</key>
+ <dict>
+ <key>stroke</key>
+ <dict>
+ <key>CornerRadius</key>
+ <real>5</real>
+ <key>HeadArrow</key>
+ <string>FilledArrow</string>
+ <key>HeadScale</key>
+ <real>3</real>
+ <key>HopLines</key>
+ <true/>
+ <key>HopType</key>
+ <integer>1</integer>
+ <key>LineType</key>
+ <integer>1</integer>
+ <key>TailArrow</key>
+ <string>0</string>
+ <key>Width</key>
+ <real>0.25</real>
+ </dict>
+ </dict>
+ <key>Tail</key>
+ <dict>
+ <key>ID</key>
+ <integer>14</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{342, 97.086}, {55, 21}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FitText</key>
+ <string>YES</string>
+ <key>Flow</key>
+ <string>Resize</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Font</key>
+ <string>HelveticaNeue</string>
+ <key>Size</key>
+ <real>9</real>
+ </dict>
+ <key>ID</key>
+ <integer>16</integer>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>fill</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>shadow</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>CornerRadius</key>
+ <real>7</real>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Align</key>
+ <integer>0</integer>
+ <key>Text</key>
+ <string>{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360
+{\fonttbl\f0\fnil\fcharset0 HelveticaNeue;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural\pardirnatural
+
+\f0\fs18 \cf0 onPossible}</string>
+ </dict>
+ <key>Wrap</key>
+ <string>NO</string>
+ </dict>
+ <dict>
+ <key>Class</key>
+ <string>LineGraphic</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Font</key>
+ <string>HelveticaNeue</string>
+ <key>Size</key>
+ <real>8</real>
+ </dict>
+ <key>Head</key>
+ <dict>
+ <key>ID</key>
+ <integer>14</integer>
+ </dict>
+ <key>ID</key>
+ <integer>15</integer>
+ <key>Points</key>
+ <array>
+ <string>{394, 82.5}</string>
+ <string>{394, 133.5}</string>
+ </array>
+ <key>Style</key>
+ <dict>
+ <key>stroke</key>
+ <dict>
+ <key>CornerRadius</key>
+ <real>5</real>
+ <key>HeadArrow</key>
+ <string>FilledArrow</string>
+ <key>HeadScale</key>
+ <real>3</real>
+ <key>HopLines</key>
+ <true/>
+ <key>HopType</key>
+ <integer>1</integer>
+ <key>LineType</key>
+ <integer>1</integer>
+ <key>TailArrow</key>
+ <string>0</string>
+ <key>Width</key>
+ <real>0.25</real>
+ </dict>
+ </dict>
+ <key>Tail</key>
+ <dict>
+ <key>ID</key>
+ <integer>13</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{351.5, 134}, {85, 38}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>ID</key>
+ <integer>14</integer>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>fill</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Text</key>
+ <string>{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360
+{\fonttbl\f0\fnil\fcharset0 HelveticaNeue;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs18 \cf0 POSSIBLE}</string>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{351.5, 44}, {85, 38}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>ID</key>
+ <integer>13</integer>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>fill</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Text</key>
+ <string>{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360
+{\fonttbl\f0\fnil\fcharset0 HelveticaNeue;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs18 \cf0 IDLE}</string>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{61.5, 277.914}, {124, 25}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FitText</key>
+ <string>YES</string>
+ <key>Flow</key>
+ <string>Resize</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Font</key>
+ <string>HelveticaNeue</string>
+ <key>Size</key>
+ <real>12</real>
+ </dict>
+ <key>ID</key>
+ <integer>12</integer>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>fill</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>shadow</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>CornerRadius</key>
+ <real>7</real>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Text</key>
+ <string>{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360
+{\fonttbl\f0\fnil\fcharset0 HelveticaNeue;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf0 Discrete Recognizers}</string>
+ </dict>
+ <key>Wrap</key>
+ <string>NO</string>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{151.5, 149}, {35, 21}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FitText</key>
+ <string>YES</string>
+ <key>Flow</key>
+ <string>Resize</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Font</key>
+ <string>HelveticaNeue</string>
+ <key>Size</key>
+ <real>9</real>
+ </dict>
+ <key>ID</key>
+ <integer>11</integer>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>fill</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>shadow</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>CornerRadius</key>
+ <real>7</real>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Align</key>
+ <integer>0</integer>
+ <key>Text</key>
+ <string>{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360
+{\fonttbl\f0\fnil\fcharset0 HelveticaNeue;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural
+
+\f0\fs18 \cf0 onFail}</string>
+ </dict>
+ <key>Wrap</key>
+ <string>NO</string>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{151.5, 135}, {57, 21}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FitText</key>
+ <string>YES</string>
+ <key>Flow</key>
+ <string>Resize</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Font</key>
+ <string>HelveticaNeue</string>
+ <key>Size</key>
+ <real>9</real>
+ </dict>
+ <key>ID</key>
+ <integer>10</integer>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>fill</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>shadow</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>CornerRadius</key>
+ <real>7</real>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Align</key>
+ <integer>0</integer>
+ <key>Text</key>
+ <string>{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360
+{\fonttbl\f0\fnil\fcharset0 HelveticaNeue;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural
+
+\f0\fs18 \cf0 onDetected}</string>
+ </dict>
+ <key>Wrap</key>
+ <string>NO</string>
+ </dict>
+ <dict>
+ <key>Class</key>
+ <string>LineGraphic</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Font</key>
+ <string>HelveticaNeue</string>
+ <key>Size</key>
+ <real>8</real>
+ </dict>
+ <key>Head</key>
+ <dict>
+ <key>ID</key>
+ <integer>4</integer>
+ </dict>
+ <key>ID</key>
+ <integer>8</integer>
+ <key>Points</key>
+ <array>
+ <string>{136.972, 178.574}</string>
+ <string>{151.5, 155}</string>
+ <string>{135.958, 127.436}</string>
+ </array>
+ <key>Style</key>
+ <dict>
+ <key>stroke</key>
+ <dict>
+ <key>CornerRadius</key>
+ <real>5</real>
+ <key>HeadArrow</key>
+ <string>FilledArrow</string>
+ <key>HeadScale</key>
+ <real>3</real>
+ <key>HopLines</key>
+ <true/>
+ <key>HopType</key>
+ <integer>1</integer>
+ <key>LineType</key>
+ <integer>1</integer>
+ <key>TailArrow</key>
+ <string>0</string>
+ <key>Width</key>
+ <real>0.25</real>
+ </dict>
+ </dict>
+ <key>Tail</key>
+ <dict>
+ <key>ID</key>
+ <integer>5</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{38.5, 142.5}, {55, 21}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FitText</key>
+ <string>YES</string>
+ <key>Flow</key>
+ <string>Resize</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Font</key>
+ <string>HelveticaNeue</string>
+ <key>Size</key>
+ <real>9</real>
+ </dict>
+ <key>ID</key>
+ <integer>7</integer>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>fill</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>shadow</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>CornerRadius</key>
+ <real>7</real>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Align</key>
+ <integer>0</integer>
+ <key>Text</key>
+ <string>{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360
+{\fonttbl\f0\fnil\fcharset0 HelveticaNeue;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural
+
+\f0\fs18 \cf0 onPossible}</string>
+ </dict>
+ <key>Wrap</key>
+ <string>NO</string>
+ </dict>
+ <dict>
+ <key>Class</key>
+ <string>LineGraphic</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Font</key>
+ <string>HelveticaNeue</string>
+ <key>Size</key>
+ <real>8</real>
+ </dict>
+ <key>Head</key>
+ <dict>
+ <key>ID</key>
+ <integer>5</integer>
+ </dict>
+ <key>ID</key>
+ <integer>6</integer>
+ <key>Points</key>
+ <array>
+ <string>{111.842, 127.414}</string>
+ <string>{94.5, 153}</string>
+ <string>{111.842, 178.586}</string>
+ </array>
+ <key>Style</key>
+ <dict>
+ <key>stroke</key>
+ <dict>
+ <key>CornerRadius</key>
+ <real>5</real>
+ <key>HeadArrow</key>
+ <string>FilledArrow</string>
+ <key>HeadScale</key>
+ <real>3</real>
+ <key>HopLines</key>
+ <true/>
+ <key>HopType</key>
+ <integer>1</integer>
+ <key>LineType</key>
+ <integer>1</integer>
+ <key>TailArrow</key>
+ <string>0</string>
+ <key>Width</key>
+ <real>0.25</real>
+ </dict>
+ </dict>
+ <key>Tail</key>
+ <dict>
+ <key>ID</key>
+ <integer>4</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{82.5, 179}, {85, 38}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>ID</key>
+ <integer>5</integer>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>fill</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Text</key>
+ <string>{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360
+{\fonttbl\f0\fnil\fcharset0 HelveticaNeue;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs18 \cf0 POSSIBLE}</string>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{82.5, 89}, {85, 38}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>ID</key>
+ <integer>4</integer>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>fill</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Text</key>
+ <string>{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360
+{\fonttbl\f0\fnil\fcharset0 HelveticaNeue;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs18 \cf0 IDLE}</string>
+ </dict>
+ </dict>
+ </array>
+ <key>GridInfo</key>
+ <dict/>
+ <key>GuidesLocked</key>
+ <string>NO</string>
+ <key>GuidesVisible</key>
+ <string>YES</string>
+ <key>HPages</key>
+ <integer>1</integer>
+ <key>ImageCounter</key>
+ <integer>1</integer>
+ <key>KeepToScale</key>
+ <false/>
+ <key>Layers</key>
+ <array>
+ <dict>
+ <key>Lock</key>
+ <string>NO</string>
+ <key>Name</key>
+ <string>Layer 1</string>
+ <key>Print</key>
+ <string>YES</string>
+ <key>View</key>
+ <string>YES</string>
+ </dict>
+ </array>
+ <key>LayoutInfo</key>
+ <dict>
+ <key>Animate</key>
+ <string>NO</string>
+ <key>circoMinDist</key>
+ <real>18</real>
+ <key>circoSeparation</key>
+ <real>0.0</real>
+ <key>layoutEngine</key>
+ <string>dot</string>
+ <key>neatoSeparation</key>
+ <real>0.0</real>
+ <key>twopiSeparation</key>
+ <real>0.0</real>
+ </dict>
+ <key>LinksVisible</key>
+ <string>NO</string>
+ <key>MagnetsVisible</key>
+ <string>NO</string>
+ <key>MasterSheets</key>
+ <array/>
+ <key>ModificationDate</key>
+ <string>2011-09-09 17:25:00 +0200</string>
+ <key>Modifier</key>
+ <string>Ulrich von Zadow</string>
+ <key>NotesVisible</key>
+ <string>NO</string>
+ <key>Orientation</key>
+ <integer>2</integer>
+ <key>OriginVisible</key>
+ <string>NO</string>
+ <key>PageBreaks</key>
+ <string>YES</string>
+ <key>PrintInfo</key>
+ <dict>
+ <key>NSBottomMargin</key>
+ <array>
+ <string>float</string>
+ <string>41</string>
+ </array>
+ <key>NSLeftMargin</key>
+ <array>
+ <string>float</string>
+ <string>18</string>
+ </array>
+ <key>NSPaperSize</key>
+ <array>
+ <string>coded</string>
+ <string>BAtzdHJlYW10eXBlZIHoA4QBQISEhAdOU1ZhbHVlAISECE5TT2JqZWN0AIWEASqEhAx7X05TU2l6ZT1mZn2WgVMCgUoDhg==</string>
+ </array>
+ <key>NSRightMargin</key>
+ <array>
+ <string>float</string>
+ <string>18</string>
+ </array>
+ <key>NSTopMargin</key>
+ <array>
+ <string>float</string>
+ <string>18</string>
+ </array>
+ </dict>
+ <key>PrintOnePage</key>
+ <false/>
+ <key>QuickLookPreview</key>
+ <data>
+ JVBERi0xLjMKJcTl8uXrp/Og0MTGCjUgMCBvYmoKPDwgL0xlbmd0aCA2IDAgUiAvRmls
+ dGVyIC9GbGF0ZURlY29kZSA+PgpzdHJlYW0KeAGtl8luG0cQhu/zFH1MDmp19d5XS3Yg
+ I3BsS0bODkPFNCQxFuUEyNPnq+ai4eokCASBnGFtXVX/X9VfzDvzxTj+Umqm1GAep+Zn
+ 82DOLxZiJgsj/W8xMWfOJqP/I8Fbc/52+jiZ/v709ePd8DjDlLjSzWVniiCdI2buzfnV
+ vZjLefe2K5LSWsSvRIaRSIjqNNd8wsxSJrW1zNrOOJqVjMvDMpyw9CXmNSf8bM7fT+8+
+ Ps3+mF7M7+aPs/vp0+NsYjhST8TFdT+UM9cXesb+cKYfZEztVU+MtZmaTKiawmtOiqbX
+ FDpD+kZa4jlPSXqeFzemLY01c9ZsqrG1ZoJNww05eyXW4ezm1nx3dfnjy+/NzWfz8maZ
+ w60Q1FQPQcpODDtuU00a7pZbLzZrOHg1O17f/nR9ffVi7NlZgv9zfJpNDkTE1ijFiC82
+ Smjmnvxn67K+C8m2KNW0iBuJ0cbi/eopBTNZf222hFRoALFFfDWSs4o2LaVNDe9SgvWu
+ qc4qy71RtYd7pjWOILGY7JJ11dVB42g2pFZN5kepIZg73iVbffPIVRta8Lz7ZPa0OcUt
+ hl/z/3kYpbOfWxO/0ZBSbBMMjvwJIKiSy9iflGizy3XY8jfSPtU8OZsc3F7veG3AA30z
+ f3g7Xyxmv9xNn7tn3fIHDxOybUUyWa42lRg0eVHPQD2lOIpCMZO2DO0uGZfeh/6GyiSa
+ un8PhCmxWh+K9GqTF4oKlHNALjRLx/FLCFYa1ThWSqKJCJicoq3JBU1tKBbUyZCxn2oT
+ TS0RpgzyMpE53zTdlPKA9qaUh1t4rUHnWYnYefaHOZqWRhr7kyCki7jG/oaR9qlSSnXU
+ kq7er6Zi8WA1L6dP08nT9Nfnao6qKLmZ7FV3F+NytD1efZzdHTbWDcWG5pJ7IQ3xHWRn
+ fJ6lbGs1cZeoLmeLyeN/Mujhvxj3LXJi8346mf/2MPtr+rh4ti0Q0aleDjRDMpjsrDys
+ WHmUr9CiKX4fTGMi3qXETsTDKSJeuqVbtqfBjt8NiIfnAfB/MbGeq4+De6NfxWebEy16
+ kC5VIicHPdLsoWUl+ExxQ4KfQoOG18+9ybfEj6NJO7D7Dh7fkMjK8iaWleXN86eROIGc
+ wk3IFEgnaJ8y+/Ns1eu7lfs3VKhGo1O2oveVpZKHw/VdsNFDc8xwMuR50ayLjCkBx64U
+ faHTBkaLjJUG3THLiCiI8CZZWKuYxmdJBfjwU2no12prQegYE/ZgUmhDbjohXe7BEKBO
+ xNyCDd4r60UHUbZMSRm0zVdlx0+8RRJt3m60b4fVUNtjQq3dRqMybLElY39V6bsQ7LO/
+ gQO4IkqOI3cj5VMFjTToiYKuyWu/oEfJS1tvRV2r/hhTVyb9pCjuGryYPzzNHr7Ovy4O
+ Es7wzwjH+9PIT9Ht96zWpx3cwd5/ePPm6s0Pz7R3YgXriCva/0v0efkW8lPeRn5i3Roj
+ f/ncq6rGN+LfRr5nJRkjfxPLCvmb5yXyl+LEfapRQmbkG4b+fgJXE3O3pPOH/Yl5bGZ0
+ 0IPjUoASW43NlS0SLLAVJGE/9CA6JlCbI6ilgwSQxf6m8ACeQb32vAt5kMz0SRGKgIp9
+ ABq6/jQsxsLCBGwRxlDO9IsIl5zG8h5113LMrAZ5IMz88tG6VvNQ2YWci6p3kMhZlKyv
+ cEkB7ey4PXSKAK2wCxNpacQOZKEu3LBA4QNKWu69h7RPF3mjwflYcb3u2XHtDzrwjqeR
+ P1NZ/TnSiiPW0a61t0sPOW1fmiLBwhEHVl85WvqXD31PGvqd6VjV+6Rij816K/BE1YEI
+ fiLYYXv13Dta5VYbKEQurg1CKJJiMEF3Ya7MExO0M3QB1esKe6fnDdWgI3TX9ZUNMXD5
+ kb6mIw7hcf1hMiQWatZMRon1nqWZyVBcZP/WIRcCbUV+sM6OfaTsHRPsHAP3clqHEUTs
+ MJxz3EQSX4RbJWUgKBsygSRtTM8EUapea+utfq19ejJsNBQh3HZ0J9/488CHO6DaXvsb
+ PGsNVdcYRv5G2qcQT0Nvyj5sX1uPln0f8e/+BimPk/sKZW5kc3RyZWFtCmVuZG9iago2
+ IDAgb2JqCjE1MzUKZW5kb2JqCjMgMCBvYmoKPDwgL1R5cGUgL1BhZ2UgL1BhcmVudCA0
+ IDAgUiAvUmVzb3VyY2VzIDcgMCBSIC9Db250ZW50cyA1IDAgUiAvTWVkaWFCb3ggWzAg
+ MCA1NTkgNzgzXQo+PgplbmRvYmoKNyAwIG9iago8PCAvUHJvY1NldCBbIC9QREYgL1Rl
+ eHQgL0ltYWdlQiAvSW1hZ2VDIC9JbWFnZUkgXSAvQ29sb3JTcGFjZSA8PCAvQ3MxIDgg
+ MCBSCi9DczIgMTUgMCBSID4+IC9Gb250IDw8IC9GMS4wIDE2IDAgUiA+PiAvWE9iamVj
+ dCA8PCAvSW0zIDEzIDAgUiAvSW0xIDkgMCBSCi9JbTIgMTEgMCBSID4+ID4+CmVuZG9i
+ agoxMyAwIG9iago8PCAvTGVuZ3RoIDE0IDAgUiAvVHlwZSAvWE9iamVjdCAvU3VidHlw
+ ZSAvSW1hZ2UgL1dpZHRoIDIxNCAvSGVpZ2h0IDEyMCAvSW50ZXJwb2xhdGUKdHJ1ZSAv
+ Q29sb3JTcGFjZSAxNyAwIFIgL0ludGVudCAvUGVyY2VwdHVhbCAvU01hc2sgMTggMCBS
+ IC9CaXRzUGVyQ29tcG9uZW50CjggL0ZpbHRlciAvRmxhdGVEZWNvZGUgPj4Kc3RyZWFt
+ CngB7dAxAQAAAMKg9U9tDQ+IQGHAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED
+ BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA
+ gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY
+ MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED
+ BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA
+ gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY
+ MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDgd2As
+ /wABCmVuZHN0cmVhbQplbmRvYmoKMTQgMCBvYmoKMzU5CmVuZG9iago5IDAgb2JqCjw8
+ IC9MZW5ndGggMTAgMCBSIC9UeXBlIC9YT2JqZWN0IC9TdWJ0eXBlIC9JbWFnZSAvV2lk
+ dGggMjE0IC9IZWlnaHQgMTIwIC9JbnRlcnBvbGF0ZQp0cnVlIC9Db2xvclNwYWNlIDE3
+ IDAgUiAvSW50ZW50IC9QZXJjZXB0dWFsIC9TTWFzayAyMCAwIFIgL0JpdHNQZXJDb21w
+ b25lbnQKOCAvRmlsdGVyIC9GbGF0ZURlY29kZSA+PgpzdHJlYW0KeAHt0DEBAAAAwqD1
+ T20ND4hAYcCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgw
+ YMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMG
+ DBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCA
+ AQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgw
+ YMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMG
+ DBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCA
+ AQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYOB3YCz/AAEKZW5kc3RyZWFt
+ CmVuZG9iagoxMCAwIG9iagozNTkKZW5kb2JqCjExIDAgb2JqCjw8IC9MZW5ndGggMTIg
+ MCBSIC9UeXBlIC9YT2JqZWN0IC9TdWJ0eXBlIC9JbWFnZSAvV2lkdGggMjE0IC9IZWln
+ aHQgMTIwIC9JbnRlcnBvbGF0ZQp0cnVlIC9Db2xvclNwYWNlIDE3IDAgUiAvSW50ZW50
+ IC9QZXJjZXB0dWFsIC9TTWFzayAyMiAwIFIgL0JpdHNQZXJDb21wb25lbnQKOCAvRmls
+ dGVyIC9GbGF0ZURlY29kZSA+PgpzdHJlYW0KeAHt0DEBAAAAwqD1T20ND4hAYcCAAQMG
+ DBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCA
+ AQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgw
+ YMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMG
+ DBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCA
+ AQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgw
+ YMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMG
+ DBgwYMCAAQMGDBgwYMCAAQMGDBgwYOB3YCz/AAEKZW5kc3RyZWFtCmVuZG9iagoxMiAw
+ IG9iagozNTkKZW5kb2JqCjE4IDAgb2JqCjw8IC9MZW5ndGggMTkgMCBSIC9UeXBlIC9Y
+ T2JqZWN0IC9TdWJ0eXBlIC9JbWFnZSAvV2lkdGggMjE0IC9IZWlnaHQgMTIwIC9Db2xv
+ clNwYWNlCi9EZXZpY2VHcmF5IC9JbnRlcnBvbGF0ZSB0cnVlIC9CaXRzUGVyQ29tcG9u
+ ZW50IDggL0ZpbHRlciAvRmxhdGVEZWNvZGUgPj4Kc3RyZWFtCngB7VyJdho7DE3fS9Ns
+ EAgECM2+NH3t///fu/dK9ngWIO4JwZ2Dcmb3MLqWLMuSnYODPe1rYF8D+xrY10C7Br4U
+ T22e190hnH/+CiKn65DEZxWif0WHBZJx5vX+DmCOCa8RzNeCifyBTULbhMs0j4gMz1Gx
+ ZPwRmeGKutY6MUFBTHgFcL6Bjgsl8gYWwSgEtl5ckpRhCnhOCiWrbCATLsFqCclu0O5J
+ UEcUEeCcnp6eGeGsEKoYAoNgk7hcXJ2wKCkDRUgO6FzkP1XEIeHo9JTAAqxuGy9RoUlB
+ UBLR+flgMBiScCyIAkvn56zlU4iL0qISdgjLQVH7Ts+ISG9fkHRWzK5iaTAAMsI6WgVL
+ +hckRUQXFyPQmDQa6ZeK2EWWyBTYHCTSausgUNH6SVKDIRAJz6VIp8XsEp6ALIXVgQqm
+ Ar0U1W8wBKTLy8lkMjWaTOyXStgnTIEr6JHBgslA02q1LIkKjQptCqD07lUgB1fIIXB1
+ BX4mE8Bi27Km1URFq079M1DTq6vZPKFZ/KWdnzT5mgZYXcICqkPqHyR1MZ4YpoWI4EpD
+ lXI2GV9AWuy2DlsqKAX8dnziqFI5zWaUdTF0NZul8royVCfotdBpNVTQUZmpmCavCVJJ
+ 1gLVmzaPGVWQ5n0FqmAAx5cRFapFbbIYqw5GaJgTec2ml+NgBluyorGgWVezmroCAhNA
+ TWA/i+iAxQT6HOCCNQv6NJUKwsM4om2vO01mLGrNKhFUQT7TRVNcsWHJXDRQwbGgsYBb
+ ARM4X9DwSfvY0aEDL4bg9kBcpoVgcjEXqsGZm4tVqEbjqVAl2ge9LYZQ7RCXa6FQmblY
+ g8pNoKPyJiUPspAxI0Z98LwDLDQtyKpmBLtklaCi+tFOwGzCbpYzzgeL5qfSZszeg+oE
+ r0BtoYF0J6awmaPRkG4Wh9KFEHg8Hw4xpEDbUr9FWV2w4tVhtWV1nKK6oucIZwSg0BLL
+ CaDBohEWlBAeOKs/ojqmc9FEhe7KUcEGUlTw84OkGMkphMQlpYWxkoQFG2iyUoe1AhWH
+ IeiFISq2qdBrM1BaBgUPiGNACQuMymWCQqEbbqCix05Zsb+asquiR2FtCgqLWEchpG6V
+ bYuGkK6TfAu2K3ntNVRfNA5xVPADWVajZ7YpgEJUtxAyRs9Y/dQqcHqJ2o+oak57AxXc
+ v9Vla9Xx6Rc5nOaU/XQgtQ/mcJpTtvYRv3D17Hr0wfdyOM0p22BTgBJTsrH9Md/ELRJe
+ xnl1p/GB+mUOpzll06+Qm48m/Gb6icZ5Dqc5ZavPOKZGotXSm9yrh7P9ps7OX7IaWocr
+ h9OcshGVyQlcf5TbQeibcqI5nOaUDagEKs1LMv8Hij6jXXLvnrFu1LzkqgjfUu1syInm
+ cJpT1lERVJXDUxZP45WE6zh+YaKJmygdqoUS9hIwElrIiYbqqx1zOM0pax8RKOgeM0Mh
+ hWcDZuO6Nni2TJolnMJ5M91nKbZjJUUtHdVpNHI4zSkrVAkoDA0834XgBvxhMq+MnmXA
+ WnkvJmiUpEkSY3hTmKvkocx9TUpem3Xfbq0XlI8KX6WklMKr0l3IeDmvDHNZtqgZTGQm
+ Yxw2f2ivARqSh4xArMqyHRzkcJpT1mSFRqXAvNx8so/UEDJBSAoZo8wKKVOkXRrPZoyR
+ m+3siZI29KchaoaLViYPt4qKliKCspAPmDSKCDAAxx+jkQtE4riJLPSf3lF6wsMkHP1E
+ WB39cU7955SlrIjKEkODYYwgiFHy7nHVxfXyGrRcLr9/tw2nOK+I16Tra2KeCRjzURUs
+ a0zJPofTnLKGSqJirHeksDwQiMi/QwGAG9Lt7e3dnW04vb27v4vEa9LNDV9bMK4wuXRY
+ alptM5jDaU7ZVFQCNSckMg8i/zdAo4v7h3vQw8PDo5POnp4eH7lxh2eie722vGZowWGp
+ aX0+KkQEMCJF/HoBqVAGFYd3dgG+Sc/PLy+2PYNeXl9A2uGuEeEB2M1yqaglA2GWuWkm
+ pKj7SSwCQ/x149ucsiYr/TbCh+Pp/JqCAiYKJNS/AAEN8Ly8/qjRG6+0w/FVBHgA5rAk
+ LKJakb/eNqrTM7aquST18ACZiKRcPItw3n46vfHsv/9s48mbo3sFLoN1zXSADIZyHC0V
+ zKn/nLKSlYwFsl2jy6s5RAWNexSkV/JnSgdQJhawn9KvX7gKm8GFzF6en6iE35eLGVAx
+ x7FLVGhWaFQA9SR9eyV/ktMrFA+ygHiAASAEhoffv39hpy2A/QldFCw0rev5dKyG1W0u
+ cuo/p2yQFaYxQFZCZaKiEVCtB+V7q1ABBEmggMiQ/abESD8h1FcIC03r+3IeG1Y7fb1l
+ a9HUQDYr2oYoK5qEhqykdQERIEZQxaCSfWUKBTYQve3tnVsLmGy1rxfatne0K1gO2A62
+ v9iwqIHDYNo/11ooOW791WwRYNFKgLyLkj7+gE7K8plZoPWr20C2POpfYgR3iorzg8y3
+ kGvBjhf9FToedKk4ktxwSBvDTiAkRVlIGhVhQod1fysbuDtrYS67Oxd0maiF8o7gYfCo
+ Lpliq3wLYoQAYfyx1ybo3KnzFqhd9lfw2TWZEP0wWhYzmcJFPxAeHf1B9wDlBxJhIIBs
+ +IF4wprAe3Bx4eFGBeyYmHSwTY9JIxHzmaCDSE0w6wd3UOMMO5i7XvPZwTe99fvKaVcF
+ 4G7itSNva067uqtP9QOJygZYGoto2KgkLcaGGh0uFj4caY6vMLa6aY2vICMOsZSLtgl/
+ GGB9lag+0wYehGCMzVKzmR0cynMmjkbEmFhjY8fGWBigMUIMFEbHPDK9bpMGdjZqTGEh
+ 8cc5EB67wLxWhS+QLI9DfTthqCKGAWLwIhZSxIORiwRUWwG32q6EStOPFWVCqEwzxW1e
+ dZxb7QGk9MAgDeI1Mc6UPCMiBmNsfG9D4ZYCbhdVAothTuRePQhIzroDgWQagcBAHhTU
+ PT7xSKIiZwrgMv8Dn7NBOR5rTln/DJtWCEkzkB4XYQBfg2rh2nPEMztIr1j8FoZiR/FA
+ QBMsaCFTIkdY1gRkxNZFFmdPA+x+zgU24fTEZuAky1k6RLVlDaTEIi4CCyu2LM2BZQ4g
+ 7RyvQK/d8Q1fUgU16NS/7fbCUQuphlRE5t4IbTN5QicpGHI8dqtKYflH6oectpJTtvEV
+ E5hB8/QiEP4poX5UT12GQh/O4TSnbB0Vrr6QxMsH7fBzrY+EGzmc5pQNv18/Clobm92u
+ 9hF3uBVv+Inu13+6dpXDaU7Z2kdaF4FbHFvPVt3IeSeH05yyq3jz+87ihlJdj99VDTmc
+ Nsr+8eysuj4lMth8mmrgmtIWkH7f7KyDNHrdm5l0BxZdYeKwV7MeuaCihzNUD78GVD5J
+ txeziTH102XVr5nfXP/HdgVUHkPA+O7vn6WfoopxBM4WOAvDhd0fUe+aSMy41jtXVDBq
+ 2b/VL0TVq5VK3mfbElRFtPqwqkzdcN9WAGINalirgLkuYc1gIq4kxLXbUwVTPYTK4Chm
+ 3od1H63Vmr1dWWsLG5OGpdaFSUmMFZdDyapaMhgXa3avF5a56N2Kdctx9Ou/CyB6yLR8
+ +KcJPflPEEBFYSkXYKsh+/FfOySs3v2HFQpLuV75uMxYxIwN5/qWQnn/DYcq6E2L/5Ck
+ J/+5iHH5RFpIvPTiv0wpw2FLJJJklGWaGvmonV4mHFm6K6zBWBFWlbDYtrhKgpkojBEd
+ wO5Hi4GDiiEwCDaTdFdX5BT3lAMgLOCyJNuKLFtX5u1z71kiDPkuMLtmVQmBImTKtmW4
+ mD4M2NYm03by0DJ4hom5IbC+QlRBWsyKeooNCbNCKaTwJKgVecmI08TlyUOHZj9Q2p55
+ P8/hrRWUQXNcUkW8RbkVR+TLk5IblC+Ky5KHQPUXEESwpj0lkOIp3yibIqv7k30N7Gtg
+ XwP7Gkhq4H+jmZ8lCmVuZHN0cmVhbQplbmRvYmoKMTkgMCBvYmoKMjkzMwplbmRvYmoK
+ MjAgMCBvYmoKPDwgL0xlbmd0aCAyMSAwIFIgL1R5cGUgL1hPYmplY3QgL1N1YnR5cGUg
+ L0ltYWdlIC9XaWR0aCAyMTQgL0hlaWdodCAxMjAgL0NvbG9yU3BhY2UKL0RldmljZUdy
+ YXkgL0ludGVycG9sYXRlIHRydWUgL0JpdHNQZXJDb21wb25lbnQgOCAvRmlsdGVyIC9G
+ bGF0ZURlY29kZSA+PgpzdHJlYW0KeAHtnOt24joMhZlz2k5LoZQ7lBaYy/s/49l7S06c
+ ACFeZ9bEZKEfXA3oi2TZlmwGg7vcr8D9CtyvwP0KnF6Bb9nLqc5NrxDnn5sQatpEUrxX
+ Ev0rechQTDO/7i3AnAkfI8xjxkL9oCbRrnGZ55HIeJ6yFdOPZMZV+NrJAzMUzISPAOc7
+ 5DlToW5QEYrCYM3mkqWMKfC8ZCp2sUEmLmGdGMleYNyToZ5oIuAMh8NXEzzKREqFoCDU
+ JJeb6ywWLWVQRHKgkcS/Kou7SKPhkGAB63yMl6nQpWAomWg0Go/HbxTcZyRBpdGIV3kI
+ c9FadMIzxnIoet/wlUT69ISiR9nclCqNxyAj1tMlLPlfsBSJJpN3yJTy/q5vyuKmUIlK
+ Qc1xZK1THwQVo58sNX4DkXhmEj3M5ibSCWQx1hkqhAqMUnS/8RuQZrP5fL4wmc/tm3K4
+ jZSCVvAjw0LIQNc66VkyFToV+hSg9NllEIfL5C5otYQ+8zmw2Lesa9WpGNXpfwa1WC5X
+ 60hWxTd1/qCu1yJgnTMWqB7of7DUZDo3po2EcLlRxZrNpxNYi8PWw4kLygG/P784VWyn
+ 1Yq2zkaWq1Vsr6VRvWDUwqBVc0GnslCxiD4mpJyiBS5v3D1WdEGG9wtUIQBOZwUVLov6
+ ZDZRHYowMEf2Wi1m0xAGT2zFYMGwrm61cAcEE6DmiJ9ZDMBSAmMOuBDNgj8t5IKYYTwx
+ tlcnTRYsKt0qMlRGc6ZJ3VxFx1K4qFFhYsFggWkFQuB6w8An7+NAhwE8G8G0B+YyL4SS
+ m7Woxq8eLi5RvU8Xooq8D36bjeCyw1zuhaKycNFA5SHQqbxLaQaZyZoRqz7MvAMWuhZs
+ VQmC52wVUdH9GCcQNhE381nnQ0WbpzJmrNpQveAjcFt4IKcTC8TM9/c3TrO4lM5EoOPo
+ 7Q1LCvQtjVu01YQXXgPWqa2eY6olZ46YjAAKPTGfBBoiGrHghJiB8/IXVM+cXNSpMFw5
+ FWIgTYV5frAUMzmZiLSktbBWkrEQA81WGrAuUHEZglEYpmKfCqM2E6V5SJgBcQ0oY0FR
+ TZngUBiGa1ScsdNWHK8WHKo4o7A+BYdFriMT0bDKvsVAyKmT5hbsV5q1V6i+aR3iVJgH
+ sq1Wz+xTgEJWNxMxRV95+elV0HSGq19QVSbtNSpM/y63rVyOv/4kRdOUtn8dpPKDKZqm
+ tK38yJUn7rZXWqW8naJpStt2OoinjDDne2W7r6q0StE0pW3lR84/AUMJdPkRUc9/weVX
+ UzRNaXv5F/0dZ/J6pQ1zVvO00iBqFEyLS5K5UjRNaXuNyuxU1iujSUllIHe0RK4UTVPa
+ NlMVTICxcqWXBa0yGCE+sq5LgyW5YYqmKW0bqQTlpT3W9qpCQBerfobyZ+N3Vt5M0TSl
+ beVH6k+8XvRo5Uov7WnJqSVaDOnVT5orIWakaJrStg4SP6epWFoBFKZfWDMU4ikCAaKW
+ piWbqp8sqCX4YIqmKW1jivrjAKVy5UiFvaioxyqaCyAJRj8UVv2LLj5P0TSl7cUfHAwc
+ Soay/EIlP2p1NCtajrEatTKhSjStfTBF05S2V6hYBNPkXwugMj2PchjrTS5YEPgyx6qf
+ GVOhV6FTWWVvwuwWV+AuyJkyFeKifDATckh4nStmXL5yKdc/pW3TLzKvzSLY+E0L1c12
+ ++GyRXUGgISDWKrHsVTMaGusFE1T2jZSaUktKCSAth+fn18un7vdDoBbE+AhhRWtzFsH
+ 9xRNU9o2UVm9kjXYxXqz3X3t9/uDyZ50QHPTbYAVKk9JLpiiaUrbZiqECiQVmKuHpfbH
+ WA5G9gn52FaTru0H4hRNU9pepxpPpovV5mP3dTj+oPyE/CDfYS8wGO1jC2Mhi4CEA+tp
+ OVNZuWj4ivzPwkxFoF8SJ4M7wiv3XztgeY3mFqgYAUUFU+2Pgem3kclgx8PxgB72AWMh
+ kzdCcM/fVkY1W6yNygz163cF63iksTZwwRulcv+rUdFW8ECz1S144FPwQIVA9CtZK5jK
+ YsYBVKFf5R8tMGHiJBDloigGhngBPAVCDl9ywDUHrBuIgYGqOl5ZaOctLGUxEKZSt7I9
+ BTcwCnMvVDy3OGgctuCnAUsjFgN7EQK1peBW5oHr9XanaaCmTZw62RiMqYVB2UYJq9Bk
+ PQ88mbNz2od5LUBw47PALaZLKiWxkqSay8mmlqb5S1STQqmnqc7xh2ZM9fWV9q9gCeIz
+ daxGbLUFJqywDAp7gZm5uMxRfSdF05S21V+pPOMKP1oLc1cEriZ3HbngidaNVsikpXy7
+ Yu5U2ryrJT7LgbbTFXTcHapFvi3zscAvVsIppkJq5G974CCkY7TIf0WOCRuqip3WzFjw
+ CTdZgUkbHsxSCQ7YDVVInVk+sNzoH++Gx54oJpiQOCNUWuKsEyoaK6Q5cS4jHDMpsp1h
+ O5SynGBCyiItydkRlbAsfas8uxLR8S6okJnWeZymcyuVOFQ86aJfoWcRC+ZC0LCaSJxa
+ D495dgrvtzgSVtCEB91QRVwEg5zsFrKXS6bWUZ1kXVHBXGYvFHwoDhHd8VWvNybW5Dqk
+ ornEJV+E+meEb0GSobqzlboA9C3RDKF+yxahu7S+78wDSw2pd4OUDds/yoCKrtgg7VnK
+ lv+D6k/tzqr73MnzBuQLb6XszhrEc8be7KQbWB6FJZpe7XpUdsh2E/dph+rDowqfYY90
+ T3YTY+sn13qBysuBYT9xmMF1fg8d03Z+W+nTT1SQqh+79FXQLc+JGJbW4vFSotvHiGfa
+ SGxHD9qcPdCZnpLKrYX1+G2ffundSSUfs+0IqrJ2SHYxzYUkFw9W5CLMWykhB/WkZuOp
+ Mg3DfTsBaOUM2//Rn9OayiUXoT2chORmFnlhDifwTQfzPkts8/bayVo72Bh1LPuody/f
+ gNT9XXSqlgoW3er8eWGFi96dWGfeny6oklpP/l0AWQ5uggtYPfknCFBZkcZnTX351w4Z
+ Cz4orN78wwqNpdqTsHrybzh0Qe9aDBk9+eci5noja2kvOgpNmv5lcwhfigSVWv3LlKoZ
+ /ftHMDOWlZ6wkEedCevD+MhAt8tF//VSISgINYvS3sVtAEqMEwsDlx9dUQ0twxvLn7T5
+ pz0vZcgLe/SviCzRMGlcngg7qahl84KVw1gIo8ZXiivIbovLKmpRJS27h2mlPeeiyST8
+ dG5imvHyQ6BwWTJpeMRyhH0i91tq2gBy5i1+Im85o/T9pfsVuF+B+xW4X4HBf/zBCjcK
+ ZW5kc3RyZWFtCmVuZG9iagoyMSAwIG9iagoyNDI2CmVuZG9iagoyMiAwIG9iago8PCAv
+ TGVuZ3RoIDIzIDAgUiAvVHlwZSAvWE9iamVjdCAvU3VidHlwZSAvSW1hZ2UgL1dpZHRo
+ IDIxNCAvSGVpZ2h0IDEyMCAvQ29sb3JTcGFjZQovRGV2aWNlR3JheSAvSW50ZXJwb2xh
+ dGUgdHJ1ZSAvQml0c1BlckNvbXBvbmVudCA4IC9GaWx0ZXIgL0ZsYXRlRGVjb2RlID4+
+ CnN0cmVhbQp4Ae2cCVcbyQ6FyRtCEsBsNmYJS1jCmsz8/3/37r2SqqsXG+rk2K7xoHPi
+ jW5bX0ulUknV2dj4kI8r8HEFPq7AxxXoX4FP1Utf53mfEOd//wqhpvNI0t8aor8kmxWK
+ aebX/R1gzoTTCPO5YqF+UJNob3GZ55HIeLaqFdOPZMaVfK33wgwFM+EU4HyBfK1UqBtU
+ hKIw2HxzyVLGFDzfKhW72CATl7B6RrIPGPdkqC2aCDjb29s7JnhViTQKQUGoSS431yAW
+ LWVQRHKgXYl/VRVPmUbb2wQLrOEYL1NhSMFQMtHu7mg02qPguSIJlXZ3eZW3YS5ai044
+ YCyHovdt75BIZ+9T9Kqah0al0QhkxNqahSX/C0uRaH//AHJIOTjQN1XxkFSiUlBzlFmr
+ 74OgYvSTpUZ7IBLPkUQvq3nIdAJZjjVAhVCBWYruN9oD0tHReDyemIzH9k01PGZKQSv4
+ kWEhZGBo9UaWTIVBhTEFKJ17HOJwlTyFVsfQZzwGFseWDa0uFaM6/c+gJsfH05NMpumb
+ Vv6iq9cksIaMBapN+h8stX84NqZTCeFqo8o1Gx/uw1qctjZ7LigH/PL1m1PldppOaetq
+ 5Hg6ze11bFTfMGth0uq4oFNZqJhkpwmppmiBy5sPjyldkOF9BlUEwMOjRIXLojFZTVSH
+ IgzMmb2mk6PDCIM9WzFYMKxrWE3cAcEEqDHiZxUTsJTAnAMuRLPwp4lcEBnGFmN7O2my
+ YNEaVpmhKsqZ9rvmSgNL4aJDhcSCwQJpBULgySkDn7yPEx0m8GoEaQ/MZV4IJU9PRDXa
+ 8XAxi+rgcCKqzPvgt9UILjvM5V4oKgsXc6g8BDqVDyllkJWsGbHqQ+YdWBhasFUrCA7Z
+ KqOi+zFOIGwibtazzoeKlqcyZkzfQ/UNp8Bt4YFMJyaImQcHe0yzuJSuRKDj7t4elhQY
+ W5q3aKt9XnhNWH1bfc2pjpk5IhkBFEZiPQU0RDRiwQmRgfPyJ6qvTC66VJiunAoxkKZC
+ nh+WYiWnEpGWtBbWSjIWYqDZShPWDCouQzALw1QcUzFrs1Bah0QGxDWgjAVFlTLBoTAN
+ d6iYsdNWnK8mnKqYUdiYgsOi1lGJaFrl2GIgZOqk3ILjSll7i+qT1iFOhTyQx2r1zDEF
+ KFR1KxFTdIeXn14FTY9w9RNVK2nvUCH9m31s63Is/U2JpiXHLh2k9YMlmpYc2/oRvvlD
+ 3+x939wPSjQtObb1oyT64zjSuyytn2i/KdG05NjmVzIi6/6VPs64HqRsfqX9qkTTkmPj
+ V5xpsC3Jue3taTtmwOxiBOdMrhJNS451KvM8tCWlfS+lYltvpnhPDX9v0APR2jYz26Il
+ mpYca1SC8q5ktPDenwCr9aTDA7DB+8x+L2026IYlmpYcKypC5R28bP2VVi3ZZ6m9l68+
+ +XcenOiMEHzONYRVomnJsaQSFHyPfSFkJBBrlllPyVWPj/TcKhGwa4QP8AcdanT4JuOj
+ W85sH5ZoWnJsGwoLg51odlHZYclqVOwfITNV90gHqwvlFwLGA5m6omy0DRirRNOSY0kF
+ r6el1MDjkjs6Q9Q2pF1ETP0UtFrYm2CfhUfgaLWhaDo22dA9BBjDiLDoGC0p0bTkWPwI
+ B5XK8kryceVRHnFdoS1fUvIiduo6oB5npTwrNgqPcGZNOCbArH2o1k1v3irRtOTYBMUO
+ imoIBKDaVNjUx1MqQ2K9emLl/tPTM8i5y9nZaVOgc8txoeDLH+uKLpmKbSEWRQ9UxGK1
+ hzpT+0BI6oPiO+TC5FJyhccLfHh+jpPUdJFlVSdmoQ6FsKEmB69othLEAmve6qLkWNlK
+ X00o1G6AZATUXYbgi+8Xpv/lFQiurq6uTX5Ibm7wdH3NP11cEI1WSyUgx1KTo2usEk1L
+ jtWosg4eFqToNJyenRsCdKcNBAGMALiB3FLuJPd39/c/f97f393d3pLu+ppm09UA3BSl
+ rWzF3u3dLM5WjBWsB8j/JrTTxSVNYRQ/4pkkxoHHe5JQHiiPj0+PDw8J7cc1bSZDEys6
+ UoMuWHL9S46lrcwBR3uoyZ8S6lIoNApdy0xDohaLcB6fnp+eJQR7eJDNbsQFsvPzdjG2
+ 1z1cqK2cig4I94PLEeXmFj4Fr3IT0TjUm/II61CI8/L88vL66/UFL5/MZHd3dES678X5
+ GYyF6gIKEeyzLZVKkxULvYd0QJmK9pG/2RMGT3K2JxLJPGR6eX19/UUR1/MjXVFYjB6X
+ 34HlvZtVUHGyYgQ8YaRAZGiNIg0j2ajFk4h+//77t7hgMNoLWLd03R/EgrFQ4dtFcF++
+ rYzqqKEKW93RZAwOcrzcSLSSmen33/8QC2+FhdHFeOhUp3DBVVFtMbHwcSVjYWTZuJIL
+ OhajHc1B/3uBNFiylUHBB0GlOANbwQPNVkv3QI+Bu4yBFtkvGdgVAxU1FP98YDFKhMkI
+ 9ov2kqVeImL8JBVMda1woXG1gmjB+SoGFmZhZEScemOi4hgzLAVBxgOLgRYxRAbvI9Iz
+ ooVMxShIqu8I7ZywVhEDbXcQu8i2jwYTMbMLT4ugXhiM8xWjhgQADPCCMSs9EYn+d3dL
+ JsRATFhpr8HSZ+FYhzBlYiKIpMnALF/yOTmCfEotjA6mw1RsQJFgiCnmKw+B2mqwvDxQ
+ yUXk7CjhK8FFyh7JOdGYQ9GpbLD1kifQIBWEkSAMf0p0fRK2DRTWuVleHqj0FtmFL0Wy
+ jrotQkhHy3nSzpzXfFOURoqQp5FEG1kWyHPO2Dhj34KzlRZYXVMtLmMiFUeWY9kOCC6z
+ YunIRQVXW1QUeBItrmREGRKc9oafM2G3tQiagQGFPcKsXGx0pCRjLTl2I68wIXHnvmMU
+ LrjMt8V9wiNdWgdzGUwR6bmtPEgDyZfEbHDSUr6NcYlULSzWzbClmuWiZv8xay9Rt+Be
+ qFj/R9HCePloVQFcCCvPqGmboPqmWqAHiqopcvqW/rRbnKYjIKwXYhUmK9K06jT6KKpN
+ 3PSMagyKTGapAQdcJJVhaVM175FBCa+5W0EFT9Y0vTKYSoFRUWvz6tPYMq8CEwpnhBou
+ nC2UKrBUaEejwNF4c0l2d4kVdEco85GSgoqtw7ae8Jco4xqT1W4/9UYVxvTCqjEMS5+8
+ JxJNEb+1iWajEI98kJ0d/ntLcCDOwJlfYKjZBekFU2Vcf6GNsBntqi0ILBfGE2L7AaqL
+ OX+II4Rk3odBNWCqhVM1BsP0hdghtoD7DCFgLgY741EH8qyGaQhqGVQG5s4YbDScRDoW
+ PeA0XBx+Eb6Tft6XxY6r1u9BBwi1SULbzZHNxO6XgDgQPx/f1vqB5s0SqfSjIuuwJciS
+ F/yiBqPzatlU8fNO9/4nI86Oj28aev7XUGU89nKIJj77A6o/2J1V4mqzj+2Bpg+8ZPKu
+ 3Vkb+Yy9NjvpNqwfYF22Ndr1qC4HS3zYdbdGO1Q3P8e+W9+kuxa7ibH103cTr9fO7+he
+ gwrNsbXZpe89eVElLK5PsZaoRRDStZE46nVWlfdSb2+PNNZ/dk/P+t39snZ3KqU2h+6/
+ 8uoPxhZK+bqxorUiX+EbbGNntZg72e1uOe9M2g717i59TcPrdgcg7kGNexXW6G7Ntb2z
+ 1oKg3dvd1FZZXOXwqkbSgDId07DS7Ved1abvDFm7O9bZ5WB2YTuudBtaspjvj7Ndcqt9
+ tMDnmvGOUrXwuOVkqIWigaVm7xr9TxCos9FYa/e/dshY8EElg7GP1noZ0dmo4znT6e3/
+ YYXGQuXVsdRoi+6F9jOn3sZqX3gDia2Ud/xvOHRBbREWVupFCWGFCdLATzcqqZMy938u
+ Yg8ls5Y1EL0voyZNNQ8CTb0hQrGHAuU7k5XV2nQ/AZ0QIWN9/kcwM5aw2D20/pO3nWpZ
+ M6ZOGBTydtfcbhftpSI5sbDpgGDGlveZqnlt2nm7S+436H9GpbFlXNZcs7Pre2QXDC0v
+ trvUSEFt18bR0KO1NJrWYd5Uq+u19cXY8GJdex6TnJDmYueQfaWiltqSD6Z+3vCaaygz
+ Hg4hF4RdMqPjN9QkpplpObst2XFGNiD8lMqfqGlH+Tfe8oy65Q2Ajz9/XIGPK/BxBf6j
+ V+D/By+qOwplbmRzdHJlYW0KZW5kb2JqCjIzIDAgb2JqCjMwNTkKZW5kb2JqCjI0IDAg
+ b2JqCjw8IC9MZW5ndGggMjUgMCBSIC9OIDMgL0FsdGVybmF0ZSAvRGV2aWNlUkdCIC9G
+ aWx0ZXIgL0ZsYXRlRGVjb2RlID4+CnN0cmVhbQp4AdWWZ1BUyRqG+5zJiTADQ5Aw5Izk
+ KDkOQZAomBhmyDAOQ0ZURMQVWAMiIqAs6BIVXAMga0BEMbAIKKCiLsgioKyLAVFB2TNQ
+ sFbdu//un9tV3efpt7/+us/pPlUvAOQ2Fo8XC4sAEMdN5Pu42DPWBwUzcEMAD7CACoSA
+ OoudwLPz9vYA/1o+DgBIMPhAR5DrX8P++4AoJyyBDQDkjQyHchLYcQhfQHiezeMnAgCf
+ RbgnJZGHMCoTYTE+skGECwUcscQ1Ag5d4suLMX4+DkhMDwB4MovFjwCA9BTRGcnsCCQP
+ aR5hPS4nigsAWRtha3Yki4OwYO/acXFbBVyMsHrod3kivmMWK3QlJ4sVscJL74LMRBZ2
+ jErgxbLSFjv/yyYuNgn5XouFirRkbuxawdmIIXWCw3J0X2Ze7OKZLephXH/fZZ0butZr
+ mcP5zj7LzEu0/469/Zb19EiHtcscluC0kiea5SY4s8X8/CQf/2VOSPZ1Wub0SL/AZeaE
+ Oa7o4VHOzGU9KpG5slbMVveVPQBfkAa4gA08AQskgEQQBviJYamJyDzgsJWXxo+KiExk
+ 2CE3LkybweSydbUZBnr6+oLh/5si+NeWNvuevvgPQfS7/2hpG5CridwtaM8/WhByrxsy
+ AJBo/EdTNgWAJgvApc/sJH7yUj604IEBRCCMnJAUkANKQB3oAANgAiyBLXACbsAL+IEg
+ sBn5wpEgDvBBCsgAu0AOyAMHwRFQAsrBSVADzoBzoBlcBtfBLXAP9IB+MASGwRh4DabB
+ RzAHQRAOokA0SAqSh1QgLcgAMoOsISfIA/KBgqAQKALiQklQBrQbyoMKoBKoAqqFfoEu
+ QdehO1Av9BgagSahd9AXGAWTYTFYFlaFV8NmsB3sDvvBm+AIOB5Oh7Ph/XAxXAmfhpvg
+ 6/A9uB8ehl/DMyiAIqHoKAWUDsoM5YDyQgWjwlF81A5ULqoIVYlqQLWiOlEPUMOoKdRn
+ NBZNQzPQOmhLtCvaH81Gx6N3oPPRJegadBO6A/0APYKeRn/DUDAyGC2MBYaJWY+JwKRg
+ cjBFmCrMRcxNTD9mDPMRi8XSsWpYU6wrNggbjd2GzccexzZi27C92FHsDA6Hk8Jp4axw
+ XjgWLhGXgzuGO427huvDjeE+4Ul4ebwB3hkfjOfis/BF+Dr8VXwffhw/RxAhqBAsCF4E
+ DiGNcIBwitBKuE8YI8wRRYlqRCuiHzGauItYTGwg3iQ+Jb4nkUiKJHPSOlIUKZNUTDpL
+ uk0aIX0mU8maZAfyRnISeT+5mtxGfkx+T6FQVCm2lGBKImU/pZZyg/Kc8kmIJqQrxBTi
+ CO0UKhVqEuoTeiNMEFYRthPeLJwuXCR8Xvi+8JQIQURVxEGEJbJDpFTkksigyIwoTVRf
+ 1Es0TjRftE70jugEFUdVpTpROdRs6knqDeooDUVTojnQ2LTdtFO0m7QxMayYmhhTLFos
+ T+yMWLfYtDhV3Eg8QDxVvFT8ivgwHUVXpTPpsfQD9HP0AfoXCVkJO4kwiX0SDRJ9ErOS
+ qyRtJcMkcyUbJfslv0gxpJykYqQOSTVLPZNGS2tKr5NOkT4hfVN6apXYKstV7FW5q86t
+ eiIDy2jK+Mhskzkp0yUzIysn6yLLkz0me0N2So4uZysXLVcod1VuUp4mby0fJV8of03+
+ FUOcYceIZRQzOhjTCjIKrgpJChUK3QpzimqK/opZio2Kz5SISmZK4UqFSu1K08ryyp7K
+ Gcr1yk9UCCpmKpEqR1U6VWZV1VQDVfeqNqtOqEmqMdXS1erVnqpT1G3U49Ur1R9qYDXM
+ NGI0jmv0aMKaxpqRmqWa97VgLROtKK3jWr3aGG1zba52pfagDlnHTidZp15nRJeu66Gb
+ pdus+2a18urg1YdWd67+pmesF6t3Sm9In6rvpp+l36r/zkDTgG1QavDQkGLobLjTsMXw
+ rZGWUZjRCaNHxjRjT+O9xu3GX01MTfgmDSaTpsqmIaZlpoNmYmbeZvlmt80x5vbmO80v
+ m3+2MLFItDhn8ZeljmWMZZ3lxBq1NWFrTq0ZtVK0YllVWA1bM6xDrH+yHrZRsGHZVNq8
+ sFWy5dhW2Y7badhF2522e2OvZ8+3v2g/62DhsN2hzRHl6OKY69jtRHXydypxeu6s6Bzh
+ XO887WLsss2lzRXj6u56yHWQKctkM2uZ026mbtvdOtzJ7r7uJe4vPDQ9+B6tnrCnm+dh
+ z6drVdZy1zZ7AS+m12GvZ95q3vHev67DrvNeV7rupY++T4ZPpy/Nd4tvne9HP3u/A35D
+ /ur+Sf7tAcIBGwNqA2YDHQMLAofXr16/ff29IOmgqKCWYFxwQHBV8MwGpw1HNoxtNN6Y
+ s3Fgk9qm1E13Nktvjt18ZYvwFtaW8yGYkMCQupB5lherkjUTygwtC51mO7CPsl9zbDmF
+ nMkwq7CCsPFwq/CC8IkIq4jDEZORNpFFkVNRDlElUW+jXaPLo2djvGKqYxZiA2Mb4/Bx
+ IXGXuFRuDLdjq9zW1K29PC1eDm843iL+SPw0351flQAlbEpoSRRDTE1XknrSnqSRZOvk
+ 0uRPKQEp51NFU7mpXWmaafvSxtOd03/eht7G3taeoZCxK2Nku932ih3QjtAd7TuVdmbv
+ HMt0yazZRdwVs+u3LL2sgqwPuwN3t2bLZmdmj+5x2VOfI5TDzxnca7m3/Af0D1E/dO8z
+ 3Hds37dcTu7dPL28orz5fHb+3R/1fyz+cWF/+P7uAyYHThzEHuQeHDhkc6imQLQgvWD0
+ sOfhpkJGYW7hhyNbjtwpMioqP0o8mnR0uNijuOWY8rGDx+ZLIkv6S+1LG8tkyvaVzR7n
+ HO87YXuioVy2PK/8y09RPz2qcKloqlStLDqJPZl88uWpgFOdP5v9XFslXZVX9bWaWz1c
+ 41PTUWtaW1snU3egHq5Pqp88vfF0zxnHMy0NOg0VjfTGvLPgbNLZV7+E/DJwzv1c+3mz
+ 8w0XVC6UXaRdzG2CmtKappsjm4dbglp6L7ldam+1bL34q+6v1ZcVLpdeEb9y4CrxavbV
+ hWvp12baeG1T1yOuj7ZvaR+6sf7Gw451Hd033W/evuV860anXee121a3L9+xuHPprtnd
+ 5nsm95q6jLsu/mb828Vuk+6m+6b3W3rMe1p71/Re7bPpu/7A8cGth8yH9/rX9vcO+A88
+ Gtw4OPyI82jicezjt0+Sn8wNZT7FPM19JvKs6LnM88rfNX5vHDYZvjLiONL1wvfF0Ch7
+ 9PUfCX/Mj2W/pLwsGpcfr50wmLg86TzZ82rDq7HXvNdzUzl/iv5Z9kb9zYW/bP/qml4/
+ PfaW/3bhXf57qffVH4w+tM94zzz/GPdxbjb3k9Snms9mnzu/BH4Zn0uZx80Xf9X42vrN
+ /dvThbiFBR6Lz1r0AiikhcPDAXhXDQAlCPEKiC8mCi154cUIaMm/Iyzw8Yte/j95yS8v
+ xpsAUGULQEAmQGwEAGVIVUH6VOQpsIR+tgA2NFypiCIoCeGGBosAkfmINfm0sPAe8Sy4
+ VgC+8hcW5o4vLHw9hXj2xwC0xS95cEG0hw4A6IfuTAOjW/6fMxfnf9f8DZxg52UKZW5k
+ c3RyZWFtCmVuZG9iagoyNSAwIG9iagoyNjcwCmVuZG9iagoxNyAwIG9iagpbIC9JQ0NC
+ YXNlZCAyNCAwIFIgXQplbmRvYmoKMjYgMCBvYmoKPDwgL0xlbmd0aCAyNyAwIFIgL04g
+ MyAvQWx0ZXJuYXRlIC9EZXZpY2VSR0IgL0ZpbHRlciAvRmxhdGVEZWNvZGUgPj4Kc3Ry
+ ZWFtCngBhVTPaxNBFP42bqnQIghaaw6yeJAiSVmraEXUNv0RYmsM2x+2RZBkM0nWbjbr
+ 7ia1pYjk4tEq3kXtoQf/gB568GQvSoVaRSjeqyhioRct8c1uTLal6sDOfvPeN+99b3bf
+ AA1y0jT1gATkDcdSohFpbHxCavyIAI6iCUE0JVXb7E4kBkGDc/l759h6D4FbVsN7+3ey
+ d62a0raaB4T9QOBHmtkqsO8XcQpZEgKIPN+hKcd0CN/j2PLsjzlOeXjBtQ8rPcRZInxA
+ NS3Of024U80l00CDSDiU9XFSPpzXi5TXHQdpbmbGyBC9T5Cmu8zuq2KhnE72DpC9nfR+
+ TrPePsIhwgsZrT9GuI2e9YzVP+Jh4aTmxIY9HBg19PhgFbcaqfg1whRfEE0nolRx2S4N
+ 8Ziu/VbySoJwkDjKZGGAc1pIT9dMbvi6hwV9JtcTr+J3VlHheY8TZ97U3e9F2gKvMA4d
+ DBoMmg1IUBBFBGGYsFBAhjwaMTSycj8jqwYbk3sydSRqu3RiRLFBezbcPbdRpN08/igi
+ cZRDtQiS/EH+Kq/JT+V5+ctcsNhW95Stm5q68uA7xeWZuRoe19PI43NNXnyV1HaTV0eW
+ rHl6vJrsGj/sV5cx5oI1j8RzsPvxLV+VzJcpjBTF41Xz6kuEdVoxN9+fbH87PeIuzy61
+ 1nOtiYs3VpuXZ/1qSPvuqryT5lX5T1718fxnzcRj4ikxJnaK5yGJl8Uu8ZLYS6sL4mBt
+ xwidlYYp0m2R+iTVYGCavPUvXT9beL1Gfwz1UZQZzNJUifd/wipkNJ25Dm/6j9vH/Bfk
+ 94rnnygCL2zgyJm6bVNx7xChZaVuc64CF7/RffC2bmujfjj8BFg8qxatUjWfILwBHHaH
+ eh7oKZjTlpbNOVKHLJ+TuunKYlLMUNtDUlLXJddlSxazmVVi6XbYmdMdbhyhOUL3xKdK
+ ZZP6r/ERsP2wUvn5rFLZfk4a1oGX+m/AvP1FCmVuZHN0cmVhbQplbmRvYmoKMjcgMCBv
+ YmoKNzM3CmVuZG9iago4IDAgb2JqClsgL0lDQ0Jhc2VkIDI2IDAgUiBdCmVuZG9iagoy
+ OCAwIG9iago8PCAvTGVuZ3RoIDI5IDAgUiAvTiAxIC9BbHRlcm5hdGUgL0RldmljZUdy
+ YXkgL0ZpbHRlciAvRmxhdGVEZWNvZGUgPj4Kc3RyZWFtCngBhVJPSBRRHP7NNhKEiEGF
+ eIh3CgmVKaysoNp2dVmVbVuV0qIYZ9+6o7Mz05vZNcWTBF2iPHUPomN07NChm5eiwKxL
+ 1yCpIAg8dej7zezqKIRveTvf+/39ft97RG2dpu87KUFUc0OVK6Wnbk5Ni4MfKUUd1E5Y
+ phX46WJxjLHruZK/u9fWZ9LYst7HtXb79j21lWVgIeottrcQ+iGRZgAfmZ8oZYCzwB2W
+ r9g+ATxYDqwa8COiAw+auTDT0Zx0pbItkVPmoigqr2I7Sa77+bnGvou1iYP+XI9m1o69
+ s+qq0UzUtPdEobwPrkQZz19U9mw1FKcN45xIQxop8q7V3ytMxxGRKxBKBlI1ZLmfak6d
+ deB1GLtdupPj+PYQpT7JYKiJtemymR2FfQB2KsvsEPAF6PGyYg/ngXth/1tRw5PAJ2E/
+ ZId51q0f9heuU+B7hD014M4UrsXx2oofXi0BQ/dUI2iMc03E09c5c6SI7zHUGZj3Rjmm
+ CzF3lqoTN4A7YR9ZqmYKsV37ruol7nsCd9PjO9GbOQtcoBxJcrEV2RTQPAlYFH2LsEkO
+ PD7OHlXgd6iYwBy5idzNKPce1REbZ6NSgVZ6jVfGT+O58cX4ZWwYz4B+rHbXe3z/6eMV
+ dde2Pjz5jXrcOa69nRtVYVZxZQvd/8cyhI/ZJzmmwdOhWVhr2HbkD5rMTLAMKMR/BT6X
+ +pITVdzV7u24RRLMUD4sbCW6S1RuKdTqPYNKrBwr2AB2cJLELFocuFNrujl4d9giem35
+ TVey64b++vZ6+9ryHm3KqCkoE82zRGaUsVuj5N142/1mkRGfODq+572KWsn+SUUQP4U5
+ WiryFFX0VlDWxG9nDn4btn5cP6Xn9UH9PAk9rZ/Rr+ijEb4MdEnPwnNRH6NJ8LBpIeIS
+ oIqDM9ROVGONA+Ip8fK0W2SR/Q9AGf1mCmVuZHN0cmVhbQplbmRvYmoKMjkgMCBvYmoK
+ NzA0CmVuZG9iagoxNSAwIG9iagpbIC9JQ0NCYXNlZCAyOCAwIFIgXQplbmRvYmoKNCAw
+ IG9iago8PCAvVHlwZSAvUGFnZXMgL01lZGlhQm94IFswIDAgNjEyIDc5Ml0gL0NvdW50
+ IDEgL0tpZHMgWyAzIDAgUiBdID4+CmVuZG9iagozMCAwIG9iago8PCAvVHlwZSAvQ2F0
+ YWxvZyAvT3V0bGluZXMgMiAwIFIgL1BhZ2VzIDQgMCBSIC9WZXJzaW9uIC8xLjQgPj4K
+ ZW5kb2JqCjIgMCBvYmoKPDwgL0xhc3QgMzEgMCBSIC9GaXJzdCAzMiAwIFIgPj4KZW5k
+ b2JqCjMyIDAgb2JqCjw8IC9QYXJlbnQgMzMgMCBSIC9Db3VudCAwIC9EZXN0IFsgMyAw
+ IFIgL1hZWiAwIDc4MyAwIF0gL1RpdGxlIChDYW52YXMgMSkKPj4KZW5kb2JqCjMzIDAg
+ b2JqCjw8ID4+CmVuZG9iagozMSAwIG9iago8PCAvUGFyZW50IDMzIDAgUiAvQ291bnQg
+ MCAvRGVzdCBbIDMgMCBSIC9YWVogMCA3ODMgMCBdIC9UaXRsZSAoQ2FudmFzIDEpCj4+
+ CmVuZG9iagozNCAwIG9iago8PCAvTGVuZ3RoIDM1IDAgUiAvTGVuZ3RoMSA3NjA4IC9G
+ aWx0ZXIgL0ZsYXRlRGVjb2RlID4+CnN0cmVhbQp4AeVZfWxb13W/91EkJVKmSJEURZHi
+ 1yP5xA+Romh+iRRF2ZIsWbYsyaYtypFlW5ItZ3Zt1K4RF24itGhsa0sX7I+safaRbVnX
+ bPWgDpsra2hgNEO2ZMBgFFi2ZEZRIFsXbMEQYMuyrjO933nv0V81ig7If6Nw3r3v6957
+ zvmd3zn36cLnv7DCWtka07DK0plj55j8a/o6mr9ZunjBp5zzo2iFE+dOnlHPl3H6ZydP
+ XzqhnGu/xZjj6urKMVyXf/+DY3YVF5RTvh1tcPXMhWeU8yY32sunzy6p97WrOK+cOfaM
+ Oj+7g3Pf546dWVGe734Rbc+5s+cvqOd9aI+e+/yK+jyfw3mzcq9xNDHG0fey55ie+ZmA
+ P/rZsHKsHffoT35Gv/Dcm4ttpU+4RfMhPXJj51Fq2Pff/ftS/bV70aayZhOnLeoI8jua
+ zXsx5m66jPvzTWV5JPkd9eDdZIYYXorRfGjjk5usZXruO5x/rbbJ7311c4R138SImsUj
+ vZuMx32+0VMjG/woToQ4LkT96GnivrENTWhsdk6s+dZ96xPL674x3+qx5Y2mkNzixsp6
+ LenbYPvnTuF4YM6/Uam57ndXarUBjNNE4+AVPL5ewwhPqyOglS8l7+IhbXzSt6EJT8/N
+ zG2sjbg2KiM1l9/vG924NT23cWvE5a/V8JTu/kqx4i+d6lTXrMeadVHcb1ZG2Y8xMERt
+ fZ3GxJkQ9m/cWl93rUMT+Yro3+RMvQBN6RlNaHSTV6bn6FZF9LvogugX/VhHbQRjt8Qn
+ 98+NYiV+WonhZ0zKRh4yqfH+QvFsK5ZnlE267TMyqekXMWnbL2RS8/2VPmJSC9ZsJpO2
+ P9mk4s8x6H0LV55g4TXFwmtPsLD1IQsDyPw/WD/vQLxcZ1PCD1hMuIV2CVKGfMpiXMNm
+ hbh8b6/wXywsXEWfnr3KQnh+t+BkQWGG7VTboNyWWZD9kI2S4N0KxgryvWwQc3l5kbXQ
+ Nf4jhlnV+GRgJx27hXMfO/wzcYbL/+efAK5rYlqMqse7Cmu0oGdgRszF2DYG6mBtkCf9
+ zMzC2pmV4prZIbRSkB+kkznlfhdzMTfrlvt08Kg9N67+iE/xG/xDwSa8Jrwh/FDj0bzR
+ FG66od2tXdOVde/qx/U/bp5qYS3RlpGWXzHEDfOGunHa+KrxL8A9/TDJ90FiGqzbCFLR
+ JhHayb5UyG/xhyx+C9+qr/G1+jP8xWb+cXNdZSsNm4IH14R3oJ+fxTnfghGNTAN24uYt
+ LFkv953mYS17Hyf/AhEWhl0gJ718N4K2AJmA1CCnIJcg1yAvQ16H3IS8Ddm2sMUiaJ2W
+ 9sImiyTlMSMYM9IYM4IxI/JfAccJSA1yCnIJcg3yMuR1yE3I25BtC4iBO1swtJG1y+Ny
+ 8yYL3MZVtIk7bIsF4DdSKACFjFCP+kb0GRPlPkO/A32G1/tS1ky63yPYbTqRW/z9ZSGz
+ PSxlypyahEbU3L97/Q1vLtq5a6b+Aa9lZnLusR3pXEo0927POF57z5OPde0a4r/+gb4z
+ Hi4UePpuVizslnY8ZRJs+wvZ3XaDQcvvPv+p0ZUQSyNYCWexex8Lfyj8AwuxM1sAheID
+ jxmm1uG0AxKGZCFjkIOQE5CLkOchL0G+CbkBeQuybQHG/Vt0/gkiLMAKTmZWXbmFERXN
+ dea+FE9DrYAJGnuEdH82J5pwmoDaZZx2CCOLzdunlvOzz1XjkdnL+6/9lmlR48lMJCtP
+ Fd3u4uHK5Bn+74VDA57iiWtTU1eXCy9die/JeftmzgzmV2f69hC4BRlj3wDGTFjFlzaZ
+ K0koa5OXQ95yQTrubDL9nc8GZdCWqdqSb9tUn7dB25xF8a6pSdSgK7tXvP7qjvmC0xXN
+ ZPvMdz+pfflAz5/8/rQQDe1aqexYKAetWuGLd7P9i788/+1vkT5c1qcMfYwsvYVIQNAB
+ Ui3Qouk25m6S56M1IIPjBq2hGYxC/WaswWrxZxp/U/zj+ll+vv4C/5rwzt3s9KfTH0w/
+ mEPEHC0M1iIqotf1mEO4jejmuMhwuTG+DnFPffKo1ZJWZ5ha5OP1TX6Rhua7aGgFZzeB
+ szj7nU3Wi2Go8KFXBYzNILrbuI42hDYEEjHfkTFoBgbNwKAZGDQDg2Zg0AwMmoFBMzBo
+ BgbNwKAZGDQDg+YGBs3AoBkYVGZwYVRXElYysqg8LUWiD1xJS/ChT9xL/SZoEnJAE3u6
+ wyQ8gKRHcDyKWGHZWar/5T8KnuLBfOlw2ecuLgz37MqH9YuG3MzJgepz1Vhi7tnpocu1
+ Gn9mOlUdCib3ncwXzlS3W8PFyFBtwDX09AtTY19eLqbIt7Mwx3dgdw1zbOGg2EZjlm0O
+ A4FRyb6zi2RTPIafggcJJ1rm3cJBeUdL75DzFDwoGsm+t0zx9+rPy/4Wvkjv70WQ4Bw2
+ mXx4TvJ7s2wM8nszxADrGZLqWojhGUSvzkH8tQUeR92qMBnWmeZpi2gR+d55gX9hdV6o
+ X5XXPXj3TbTfE3bS+gUWBvf8AJiwMon99SbrwaARSA9mtGFGG02koEDJaGG8lYWMQQ5C
+ TkAuQp6HvAT5JuQG5C2IykQMKMBUQEEEo3oQ7QYl2g3gf0OD/w0gCANY3YCcYgD/G8D/
+ BvC/AfxvAP8bwP8G8L8B/G8A/xswPLDUhtcIM23Aj6jiR6RIkEmM2FxBkCRzHAV9Aogy
+ CV91l44MDx8puRvtYuzgWrW6djDWaPlK9tSBdPrAqWyjnbiyOji4emUCbbm8eoWUkvng
+ OPzXDAte22R2OISrwU/8ZoeYobFW0VgLjbUNjbVYuhYaa6GxFhprobEWGmuhsRYaa6Gx
+ FhprobEWGmuhMeVmpDDiAQOmasFkpH0LtKd6iPpM4YH+DiQyiRMQOrJIYeL1rZnJyZn6
+ Py++f/rs2dP8AtftrFRGOD8Iggjyc8vLZxv6vAh9fNih/KbCEkiP8sAiZhZuKwzRjbzb
+ hevdct6VFO0kaCc1tJOgnQTtJGgnQTsJ2knQToJ2ErSToJ0E7SRoJ0E7ifxJ7LbJTNDs
+ 4QwdUBmOsngX+oEHGEe+dng0RAtI0WqyFjUiUjXUNwlTix+K0a7WJq0g6A1Pt7U1C4LG
+ 6JC8w8XzJ2JvfbSz5OotUVTwlF1MdnVlk2Fje3J7tqurT3LrhPbjw4eW69/9yUhWSnUb
+ sCRYO4R4WUK8FNgLlKu9smU8WFgEhR+ZX8Y4+UixiQ02sTVsYoNNbPKTBbQTkBrkFOQS
+ 5BrkZcjrkJuQtyHk8X7gh0YtUkWDylmexokpdSwn9x/L5boG5jPiA9Dr1KzO/3VeiOw6
+ kkstTMSl4dnq7LDk2z7s69lTEOeTM79USi1Np9Xrrt4Bz+5F/pNiNd/lTO/LpoYjTmt7
+ dyIk9Xe32qLDvcOLgx5HeqaQGUu4bJauiF9MultHFTvthp1AOKiJ4UwqoMk2BiyaI2io
+ zxu8SjjWqSWBrAlYCyVYIJyhTgcKE+Hq4uLhoycWX1m/8mtc4H9Vzx9dWjpK7a9+5RqG
+ C977RDAIFtbHdrA3t1hJNVEJs+kJMJhNr1RTJWSyEjJZCRxWAoeVwGElcFgJHFYCh5XA
+ YSVwWAkcVgKHleAAuZoqgcNKcOMWFAqykox6C6DaDt90wTdxxEUc59RPoZ9Cn5h7hHyW
+ g8tpETksqFXNd624mYNo8DD1aSBycvI2cl9GUV+lKn26zNXSRdCbNI1qjUyDk/sJskkw
+ tBlt+kB+VIxNlYJCVTOetUX8dnffkOgfSnlcybKYXRAlv3ShPVyKWkMuS3dioLBd2KF1
+ e7ihN+81tEd29BUiuvaAu9O5Ta/XtYv5uJQT20LRaIh3HGqPiI7m9m67L2Rr0RvJzwLb
+ Cdv3ws+dqCquo+qGMztxg9TthDrEF9Q2oW2CTRLom6AqXevAtQ5cM6HvVKLFiWhxNqLF
+ ia4TpnMi2JyIFieixYlocSJanIgWJ6LFiWhxIlqciBanHC00soiRRcqVBD6PSscUpFbW
+ Iy/NqnBkJu3RKJUgJQWdXrTwB/ZEDewRdlYFUySRtBZrxW5PsVbKztsFXjQHi/F4WWq3
+ hEuxyKBkJQoZdXjbm6MTx3O545NxKcaN9cHweD7gz+4KB8dyAV+WAoMTVvl/A6siu7SF
+ bZ8SF24FnW6g0w10uoFON9DpBjrdQKcb6HQDnW6g0w10uoFON9DpbqDTDXS6YTZgzYGC
+ i4zvgLY67Ouor4NJGIxuRmu786S6nz8osjr4b89pw8W98cGnBj3ewcPFpfOmQ827hnoG
+ ghZzqJzIVvhiYmfcHptcGRg4NhZePVra4cuMBKWJfCCrYILi0QRMWIGJP1dyiB2q0VIo
+ H1KFSbu0AHz/2dUWHRhVqZGAKvQ7MUMnZqB+FP0ooBDDhtAuxy5djVMWpYTdhuRDi6Ma
+ ohtplvrdQEjusRpCS/XUo1umtP1Zc7AUexgM/EUZMwnbw5ipP4aF94V36v/p8FqbYzJi
+ dsfDsTE5nsh2GuDDABwc3kIGUDKMDUujjwoNG9qwfg6tqGpvRdtKdXWbSnykRxe8Tw93
+ oc8xDPWpdAjSC4QBfxnQR/YUTbLzc/6sUhjZKSSy/A/qfyd0hDN+X0ZyHDhgHM1Gyz3t
+ nH9FsOcOj2Zqw0HBWz5cnrvAt3syPQ6HlP3jdL87ORhIrs4VesaPF4vL4z1zMjcneR36
+ 9IA+v7fFEmqRkpCX1cgEyv4gDz3ycEcTXsvLXqJ9if22vAdJAEAJ2CSB2EggNhKIjQRi
+ I4HYSCA2EoiNBGIjgdhIIDYSjdhIIDYSMnP7MXdCHtcPXPgQEGSQMjG0CyOThVxYlp6l
+ 5b4e/Qjonq5HgIaQRbSLCRjrwYY53aBfSZStJt3fPSuFJ69Pc8dsaudT+c7ugYMD/bUO
+ wRIeiNoTkotXhZ7ByeDlC/8WzQdMltBApCcvmi0gFv7e7lgsve9YIrO4K9rbF4iNp7tb
+ bD5HdCBofvbrYmFMDI1s9/oyOwLB8QJqMwHfzBijPTZ9/4H9HmRYxa7EvaSpjvCulR9Q
+ gMSJBTNiNxWJ36hWheOrqwt3fypoiacejPnz9kKjVXlPoe6FKnjxI/jawUYf3cuYVJ4j
+ ptdA7FgRBV4HIRoeUeu+VlyyqtselaEtyrcIO1YoZ0O9mKlUreGClMpXLdGR9PmMIGjv
+ /pQHxWK8M99X/11+IDra7z6CrZxSF3RhPf/f9jbPOuNFv78YdzbaeV/lyGB5oeLzVRbK
+ g0cqPi4kJ/q7uvonksmJVFdXaiJZOD4RiUwcLxSWJqLRiSU4hrNBHPYKVny7kcifylaD
+ /LcN/tum7EVpD6JsVFvUnEoey4SRTDODVVt8PD0675V99OP+vVn3vFAawr+KOPMiD74L
+ 3wywP6Jin8amjwEK29HHgBT6PjlaU8rXwhRqg1SjNkgh26cQninUBinUBinUBinUBinU
+ BinUBinUBinUBinUBinUBim5NjAi5okxo2jtECP6JYr/rMqWWUwcUkvGEG42Mif1vWDN
+ nBznyi4SGw6lpn7ks0RTgxIuVIVgaSom7RuSupODPk+pz2vzSVZ7JNCB0ixQ2B0PjObE
+ /sm5yf7OUNzWlZI6f69vZ6S9LVxOhvr9Nr1+m7W7w+Zs07XY/M7kUKjNIual/rzXYg/4
+ O71mncEhwWz4BMW7hVcRc8gWj0c+fc8hf+nREpc6oDP5jtjARmxA35LaVEqmrPHgCwwM
+ hQe1eNB+W2YJu2hPW7CfKPKMXCxY0pkb1bk5U3fSPyzZnCbtSUH7yiuT9e8G450tkxpD
+ exsfnoRnsagKfP0RaKWTzVABvE2m1FZM9/h6lYqQihiB8fsZQMnkD3EE7bWJlemLmp82
+ CVQDK9sF5UNm2s4/epglCgdcgGD9jkIS/Ej92yAJV28fffDBIkBD/B2srwV54OFvNg9/
+ hIHv7fhyxzN+u7+D/2n9Bi/VP8eDw8OTfG1A1lP5LyK79xv0Pf4JPy+uaYCuMKqNHkA3
+ iuooCWD2I99kgMA8GwHrjrFdbJztZnvYPjaDL1JV5LlDbI4t4G2O/y/gCw9+OmR0Nje6
+ Z3Z6Jja+cvriyoVTS8emVvAfW/a/k8SuQwplbmRzdHJlYW0KZW5kb2JqCjM1IDAgb2Jq
+ CjQ1MzUKZW5kb2JqCjM2IDAgb2JqCjw8IC9UeXBlIC9Gb250RGVzY3JpcHRvciAvQXNj
+ ZW50IDk1MiAvQ2FwSGVpZ2h0IDYyOSAvRGVzY2VudCAtMjEzIC9GbGFncyAzMgovRm9u
+ dEJCb3ggWy0zNDggLTIxNCAxMDg2IDk1Ml0gL0ZvbnROYW1lIC9YRUxSUFErSGVsdmV0
+ aWNhTmV1ZSAvSXRhbGljQW5nbGUKMCAvU3RlbVYgMCAvTGVhZGluZyAyOCAvTWF4V2lk
+ dGggMTE0OCAvWEhlaWdodCA1MjYgL0ZvbnRGaWxlMiAzNCAwIFIgPj4KZW5kb2JqCjM3
+ IDAgb2JqClsgMjc4IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAg
+ MCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDY4NQo3MjIgNzA0IDYxMSA1NzQgNzU5
+ IDAgMjU5IDAgMCA1NTYgMCA3MjIgNzYwIDY0OCAwIDY4NSA2NDggMCA3MjIgMCAwIDAg
+ MCAwCjAgMCAwIDAgMCAwIDUzNyA1OTMgNTM3IDU5MyA1MzcgMCA1NzQgMCAyMjIgMCAw
+ IDIyMiAwIDU1NiA1NzQgMCAwIDMzMyA1MDAKMzE1IDU1NiAwIDAgMCAwIDQ4MCBdCmVu
+ ZG9iagoxNiAwIG9iago8PCAvVHlwZSAvRm9udCAvU3VidHlwZSAvVHJ1ZVR5cGUgL0Jh
+ c2VGb250IC9YRUxSUFErSGVsdmV0aWNhTmV1ZSAvRm9udERlc2NyaXB0b3IKMzYgMCBS
+ IC9XaWR0aHMgMzcgMCBSIC9GaXJzdENoYXIgMzIgL0xhc3RDaGFyIDEyMiAvRW5jb2Rp
+ bmcgL01hY1JvbWFuRW5jb2RpbmcKPj4KZW5kb2JqCjM4IDAgb2JqCihNYWMgT1MgWCAx
+ MC42LjggUXVhcnR6IFBERkNvbnRleHQpCmVuZG9iagozOSAwIG9iagooRDoyMDExMDkw
+ OTE1NDczOVowMCcwMCcpCmVuZG9iagoxIDAgb2JqCjw8IC9Qcm9kdWNlciAzOCAwIFIg
+ L0NyZWF0aW9uRGF0ZSAzOSAwIFIgL01vZERhdGUgMzkgMCBSID4+CmVuZG9iagp4cmVm
+ CjAgNDAKMDAwMDAwMDAwMCA2NTUzNSBmIAowMDAwMDIzMjI4IDAwMDAwIG4gCjAwMDAw
+ MTc1NTEgMDAwMDAgbiAKMDAwMDAwMTY1MSAwMDAwMCBuIAowMDAwMDE3Mzg4IDAwMDAw
+ IG4gCjAwMDAwMDAwMjIgMDAwMDAgbiAKMDAwMDAwMTYzMSAwMDAwMCBuIAowMDAwMDAx
+ NzU1IDAwMDAwIG4gCjAwMDAwMTY0ODcgMDAwMDAgbiAKMDAwMDAwMjU0MCAwMDAwMCBu
+ IAowMDAwMDAzMTE5IDAwMDAwIG4gCjAwMDAwMDMxMzkgMDAwMDAgbiAKMDAwMDAwMzcx
+ OSAwMDAwMCBuIAowMDAwMDAxOTQwIDAwMDAwIG4gCjAwMDAwMDI1MjAgMDAwMDAgbiAK
+ MDAwMDAxNzM1MSAwMDAwMCBuIAowMDAwMDIyOTU1IDAwMDAwIG4gCjAwMDAwMTU1OTAg
+ MDAwMDAgbiAKMDAwMDAwMzczOSAwMDAwMCBuIAowMDAwMDA2ODY0IDAwMDAwIG4gCjAw
+ MDAwMDY4ODUgMDAwMDAgbiAKMDAwMDAwOTUwMyAwMDAwMCBuIAowMDAwMDA5NTI0IDAw
+ MDAwIG4gCjAwMDAwMTI3NzUgMDAwMDAgbiAKMDAwMDAxMjc5NiAwMDAwMCBuIAowMDAw
+ MDE1NTY5IDAwMDAwIG4gCjAwMDAwMTU2MjcgMDAwMDAgbiAKMDAwMDAxNjQ2NyAwMDAw
+ MCBuIAowMDAwMDE2NTIzIDAwMDAwIG4gCjAwMDAwMTczMzEgMDAwMDAgbiAKMDAwMDAx
+ NzQ3MSAwMDAwMCBuIAowMDAwMDE3NzE0IDAwMDAwIG4gCjAwMDAwMTc1OTkgMDAwMDAg
+ biAKMDAwMDAxNzY5MiAwMDAwMCBuIAowMDAwMDE3ODA3IDAwMDAwIG4gCjAwMDAwMjI0
+ MzIgMDAwMDAgbiAKMDAwMDAyMjQ1MyAwMDAwMCBuIAowMDAwMDIyNjkzIDAwMDAwIG4g
+ CjAwMDAwMjMxMzQgMDAwMDAgbiAKMDAwMDAyMzE4NiAwMDAwMCBuIAp0cmFpbGVyCjw8
+ IC9TaXplIDQwIC9Sb290IDMwIDAgUiAvSW5mbyAxIDAgUiAvSUQgWyA8ODBlNzY3MTk3
+ ZTU5OGIxYTliMTQxNDdjZjU1YWMxNjE+Cjw4MGU3NjcxOTdlNTk4YjFhOWIxNDE0N2Nm
+ NTVhYzE2MT4gXSA+PgpzdGFydHhyZWYKMjMzMDMKJSVFT0YKMSAwIG9iago8PC9BdXRo
+ b3IgKFVscmljaCB2b24gWmFkb3cpL0NyZWF0aW9uRGF0ZSAoRDoyMDExMDkwOTE1MTEw
+ MFopL0NyZWF0b3IgKE9tbmlHcmFmZmxlIDUuMy4yKS9Nb2REYXRlIChEOjIwMTEwOTA5
+ MTUyNTAwWikvUHJvZHVjZXIgMzggMCBSIC9UaXRsZSAoUmVjb2duaXplci5ncmFmZmxl
+ KT4+CmVuZG9iagp4cmVmCjEgMQowMDAwMDI0MjYxIDAwMDAwIG4gCnRyYWlsZXIKPDwv
+ SUQgWzw4MGU3NjcxOTdlNTk4YjFhOWIxNDE0N2NmNTVhYzE2MT4gPDgwZTc2NzE5N2U1
+ OThiMWE5YjE0MTQ3Y2Y1NWFjMTYxPl0gL0luZm8gMSAwIFIgL1ByZXYgMjMzMDMgL1Jv
+ b3QgMzAgMCBSIC9TaXplIDQwPj4Kc3RhcnR4cmVmCjI0NDQwCiUlRU9GCg==
+ </data>
+ <key>QuickLookThumbnail</key>
+ <data>
+ TU0AKgAACFaAP+BP8AQWDQeEQmFQuGQ2HQ+IRGJROKRWLQ1vxkAQMAAGPReKRx+SMACG
+ TAACymQSuCwOCSyYTGZTOaTWISN+ABrTsABefR2PzaExx5UUAAykAAM0uhRGXU2oVGpV
+ OZPqrABr1kACSuAAB1+gAGERyOR6xQezQx+2sAOS3AAFXEABy6VSF0+7Xm9XuqPm/ABs
+ 4EACjCSiVQtqYkAO3GAAG48ABTJAAPZW1WxwZkAAfOAAO5++Qa8aHSaXTRO/PkANrWYP
+ CykC2OBABubUAOfcV6wCDeAAN7/Lv0AZlwAADcfPaDSaPT83nc7U4DBYQUYbYwt79kAd
+ GD5wDgAE+Hg8PNd7kh3S8zn+v2XmrPoAMn5XO62mvgOEP79RvZ2iPgFADxnNAYAA/Azf
+ OA5aOPbBkGqgnAAHRCQAOye4AP0fwAARDaIHxDwAF1EIACdEiEFjE4ABtFQAAxFsEA26
+ z0wWiq1uEZ0bgACMdLCqiOHrH4AAfIQAN4EEHPbDDtr+jkNgQih7SgAB4SnFkXQAASEP
+ eAEarguS0wU/qKwq8jiqWDIASvHrZnfNgAS0E04SO5p9zoAEIPNNKLygezNs7LjjgMhk
+ ky1NNAL29SHI5Dx8AAcVHAAEdIt0/CFymeAAKKeQAAnTgAR+eoAAtUVBP23Bz09IE4BN
+ Hk5KijjovvGKDnHWjzoQelcAAAldw1Dk9vA8VF2ABKEVMyLJy5NMk0NPKhUQhtFQ/Whx
+ 0hSVYoOjj5GStq3p8C7jOQG9xVJDNjVwegAVVVlWpojkxvNWJq3lRtHskCgAHTfMeTof
+ cugVTdOhTgV/Qo7VtT6760nZhYABnhylKZJLothXVeXbGaIWjRlp2qEdJtkgh55FTCjT
+ SBeTgAB2VXWgsk3NXN1S/diWXc7Tw2JmSo1+uN/2FJqY5rC14LAmFnoZjUyPoDmKgI8c
+ uIPWNroVJOFnZgsLBPrOWZmi7o13pupLtX+KIPsiZ6RPEAovoyH2FeRq6ZrcIPtoiDSS
+ bu8AAEu95AAF+Vtb2uZo2dhZuva3HIABocWAAh8dXsnZymsub/n+14wicuQhuaP7/JLz
+ Lu2ZedGAAidNHiOUK5Gw8EisIIPr6ISSZvabjyXQoJLWKWaobZzGF3gKOpKJ3ezveYzz
+ CZwhLnQIliS/8NbDZy52KHrKoPBa9XnWIXLSsmvAsD+OpqOQkdHhAZF6Kb+tPqoltiWZ
+ 9DiYQhJJjfuAFf7/LQIf7HjVVhgACfAN1oAFhHmduQo6JgRst6b4eZJLySHFpgo51OrH
+ DzGfPQRN+p+1DETHjCEf7eBugAgAvaAyH0tLnWOvdcQN03FXg+4Mgh0XLOCGnDlHixlD
+ JJf6BBKSVDzAxiJAE1BfzWDaNcdV2IxInAAZEPNOxJE2DvRir8EUWUiG9iyCJLZmDNKG
+ g0RRJJjB2r4X1AAx4DTFmNCNG+L4/R/jrjowRJKwkkpccMpwCcKVGQ3JWRxLUSWSKaS4
+ RwHUiVZGhjMwiKDI2KN/kinVNLKgHOQa2Qs6MhDqNxkbCEeIAIWK/UM9ppsY0zRxaTGI
+ 5REnNkkUy3Ejiv4xvwJW54/bzSKymiCpdqJYFfqiAtJmApCVhLMbUQ6BZgmsgnXAoFLi
+ XEkpJIWWlijsUIDhm1I6McHCSOwYs++CRNUtEZG+ACZpEH2EffdMUpqWpfqUIcloY89U
+ gpDgSQ1JL4yHDun8AAFlAQAAVoIRRMbP58tHnGRObQ4SEOSdGLx0rpyHpahmS02ZHHAv
+ Rnc5ktidzOkPjuh9ZMySIs7LlSI/aaXDT8ISoMq8gCQ0LIchAb1N2UsrNI39v8XaOkgo
+ OhyhJTaUL/L08U79LnkJhoMdqcytnj00IVQkjkADozpp+RZLiWqOENiiQg8yhqLHIjwf
+ tnhUKRqMaHPKQNUm+rCUcOJjrH6GyPikkktMuEMwoh+ACvrLjcqfXSnGodWTx2CjWjxE
+ 4sacyXR0BEAFTyD2JliBqywAHgAuYITSrdMahPYJlLat60laqRY8mlt7+UoyjtWrlJIE
+ rYQOBLXOwCp4WMxtBYZGhbHdEqnaTGopMTuEGUNYWttTHrOEtItS0yaEAparKhmQ9yHY
+ uGZ/bWUTMLCW5t05d3JVyOTISwnpKNZyJvPNU7FsxdrRPSIIsKEljbnJYLJcit183UGz
+ sERyTtxrukXs6fC9RhyHJchYkIB5EEtLLORUoqd7SFJaQGOaVWDmzmzSTZYDVm7/l7TG
+ KLEAAAz4jIYOXEwAEbjOAAE3FhDFhOqUCezCDvSCTSP3f5ops32q8xxh0i7s3a4IlVb8
+ mFJUsSgrnbACSMrkY+ycXZLVqSTAhR5j0iqSXzPoaVkwl+T8vF9L/AydDWlDSxyRYlMb
+ ZSVWCRaBiR02ZtwZlaXzGeX87NdiQa2TrFLUm1G5M825uSDsnAWhc/YNdEFbK6lw4mgJ
+ umhzrnfSREpN56NfmtIFX69H8y6QV2NjwAaElVo2VkG9IX30nqkiMy4G5TkdNM/eqCDK
+ xTS39jmotH501lqrXj3SrjP2AjHK1wEo0BBZPfBKYNO692Y84/Z0UubDu9fhn+FlXa72
+ btnbRFtI7b29t+hWTSE5iIO4ZCGoktSxlSxxn9iUuM/sEmlLV1z9kHjHtKw2YlY6iI5h
+ NUKoykPpS1qLJHAQADK4RZh4LzDOpjLTMc5E1iVYZsu+StzixoKoVAlrJCBgPgAhyNOg
+ dBY+aGQzVYv9BAK6cjbGfgzlUOOvIMD3mmHNVYpj9KrMpRiOZI1csZNNPho9Dr8/4g+S
+ gAYmHKQjUDsc/AABh1EAEdB1gACL1cqG3ddEEHV10npP9wY+yQeamRzSAgAOAQAAAwAA
+ AAEATgAAAQEAAwAAAAEAKwAAAQIAAwAAAAQAAAkEAQMAAwAAAAEABQAAAQYAAwAAAAEA
+ AgAAAREABAAAAAEAAAAIARIAAwAAAAEAAQAAARUAAwAAAAEABAAAARYAAwAAAAEAKwAA
+ ARcABAAAAAEAAAhOARwAAwAAAAEAAQAAAT0AAwAAAAEAAgAAAVIAAwAAAAEAAQAAAVMA
+ AwAAAAQAAAkMAAAAAAAIAAgACAAIAAEAAQABAAE=
+ </data>
+ <key>ReadOnly</key>
+ <string>NO</string>
+ <key>RowAlign</key>
+ <integer>1</integer>
+ <key>RowSpacing</key>
+ <real>36</real>
+ <key>SheetTitle</key>
+ <string>Canvas 1</string>
+ <key>SmartAlignmentGuidesActive</key>
+ <string>YES</string>
+ <key>SmartDistanceGuidesActive</key>
+ <string>YES</string>
+ <key>UniqueID</key>
+ <integer>1</integer>
+ <key>UseEntirePage</key>
+ <false/>
+ <key>VPages</key>
+ <integer>1</integer>
+ <key>WindowInfo</key>
+ <dict>
+ <key>CurrentSheet</key>
+ <integer>0</integer>
+ <key>ExpandedCanvases</key>
+ <array>
+ <dict>
+ <key>name</key>
+ <string>Canvas 1</string>
+ </dict>
+ </array>
+ <key>Frame</key>
+ <string>{{476, 121}, {693, 937}}</string>
+ <key>ListView</key>
+ <true/>
+ <key>OutlineWidth</key>
+ <integer>142</integer>
+ <key>RightSidebar</key>
+ <false/>
+ <key>ShowRuler</key>
+ <true/>
+ <key>Sidebar</key>
+ <true/>
+ <key>SidebarWidth</key>
+ <integer>120</integer>
+ <key>VisibleRegion</key>
+ <string>{{0, 0}, {558, 783}}</string>
+ <key>Zoom</key>
+ <real>1</real>
+ <key>ZoomValues</key>
+ <array>
+ <array>
+ <string>Canvas 1</string>
+ <real>1</real>
+ <real>1</real>
+ </array>
+ </array>
+ </dict>
+ <key>saveQuickLookFiles</key>
+ <string>YES</string>
+</dict>
+</plist>
diff --git a/sphinxdoc/Recognizer.png b/sphinxdoc/Recognizer.png
new file mode 100644
index 0000000..e3a7d96
--- /dev/null
+++ b/sphinxdoc/Recognizer.png
Binary files differ
diff --git a/sphinxdoc/ToggleButtonStates.png b/sphinxdoc/ToggleButtonStates.png
new file mode 100644
index 0000000..2bd1002
--- /dev/null
+++ b/sphinxdoc/ToggleButtonStates.png
Binary files differ
diff --git a/sphinxdoc/animation.rst b/sphinxdoc/animation.rst
new file mode 100644
index 0000000..84538b1
--- /dev/null
+++ b/sphinxdoc/animation.rst
@@ -0,0 +1,252 @@
+Animation
+=========
+
+.. automodule:: libavg.avg
+ :no-members:
+
+ .. inheritance-diagram:: AnimState ContinuousAnim EaseInOutAnim LinearAnim ParallelAnim StateAnim WaitAnim
+ :parts: 1
+
+ .. autoclass:: Anim
+
+ Base class for all animations.
+
+ .. py:method:: setStartCallback(pyfunc)
+
+ Sets a python callable to be invoked when the animation starts.
+ Corresponds to the constructor parameter startCallback.
+
+ .. py:method:: setStopCallback(pyfunc)
+
+ Sets a python callable to invoke when the animation has
+ finished running. Corresponds to the constructor parameter stopCallback.
+
+ .. py:method:: abort
+
+ Stops the animation.
+
+ .. py:method:: start(keepAttr)
+
+ Starts the animation.
+
+ :param keepAttr:
+
+ If this parameter is set to :py:const:`True`, the animation doesn't
+ set the attribute value when starting. Instead, it calculates a virtual
+ start time from the current attribute value and proceeds from there.
+
+ .. py:method:: isRunning
+
+ Returns :py:const:`True` if the animation is currently executing.
+
+ .. autoclass:: AnimState(name, anim, nextName="")
+
+ One state of a :py:class:`StateAnim`.
+
+ :param name:
+
+ The name of the state. Used in :py:meth:`StateAnim.setState` and
+ :py:meth:`StateAnim.getState()`.
+
+ :param anim: The child animation to run when this state is active.
+
+ :param nextName: The name of the state to enter when this state is done.
+
+ .. autoclass:: AttrAnim
+
+ .. autoclass:: ContinuousAnim(node, attrName, startValue, speed, [useInt=False, startCallback=None, stopCallback=None])
+
+ Class that animates an attribute of a libavg node continuously and
+ linearly. The animation will not stop until the :py:meth:`abort()` method is
+ called.
+
+ A possible use case is the continuous rotation of an object.
+
+ :param node: The libavg node object to animate.
+
+ :param attrName:
+
+ The name of the attribute to change.
+
+ :param startValue: Initial value of the attribute.
+
+ :param speed: Attribute change per second.
+
+ :param useInt:
+
+ If :py:const:`True`, the attribute is always set to an integer value.
+
+ :param startCallback: Python callable to invoke when the animation starts.
+
+ :param stopCallback:
+
+ Python callable to invoke when the animation has
+ finished running, either because abort was called or because
+ another animation for the same attribute was started.
+
+ .. autoclass:: EaseInOutAnim(node, attrName, duration, startValue, endValue, easeInDuration, easeOutDuration, [useInt=False, startCallback=None, stopCallback=None])
+
+ Class that animates an attribute of a libavg node. The animation proceeds
+ in three phases: ease-in, linear and ease-out. Start and end speed are
+ zero. Ease-in and ease-out phases have the shape of one quadrant of the
+ sine curve.
+
+ :param node: The libavg node object to animate.
+
+ :param attrName:
+
+ The name of the attribute to change.
+
+ :param duration: The length of the animation in milliseconds.
+
+ :param startValue: Initial value of the attribute.
+
+ :param endValue: Value of the attribute after duration has elapsed.
+
+ :param easeInDuration: The duration of the ease-in phase in milliseconds.
+
+ :param easeOutDuration:
+
+ The duration of the ease-out phase in milliseconds.
+
+ :param useInt:
+
+ If :py:const:`True`, the attribute is always set to an integer value.
+
+ :param startCallback: Python callable to invoke when the animation starts.
+
+ :param stopCallback:
+
+ Python callable to invoke when the animation has
+ finished running, either because it has run the allotted time, because
+ abort was called or because another animation for the same
+ attribute was started.
+
+ .. autoclass:: LinearAnim(node, attrName, duration, startValue, endValue, [useInt=False, startCallback=None, stopCallback=None])
+
+ Class that animates an attribute of a libavg node by interpolating
+ linearly between start and end values.
+
+ :param node: The libavg node object to animate.
+
+ :param attrName:
+
+ The name of the attribute to change.
+
+ :param duration: The length of the animation in milliseconds.
+
+ :param startValue: Initial value of the attribute.
+
+ :param endValue: Value of the attribute after duration has elapsed.
+
+ :param useInt:
+
+ If :py:const:`True`, the attribute is always set to an integer value.
+
+ :param startCallback: Python callable to invoke when the animation starts.
+
+ :param stopCallback:
+
+ Python callable to invoke when the animation has
+ finished running, either because it has run the allotted time, because
+ abort was called or because another animation for the same
+ attribute was started.
+
+ .. autoclass:: ParallelAnim(anims, [startCallback, stopCallback, maxAge])
+
+ Animation that executes several child animations at the same time. The
+ duration of the ParallelAnim is the maximum of the child's durations or
+ maxAge, whatever is shorter.
+
+ :param anims: A list of child animations.
+
+ :param startCallback: Python callable to invoke when the animation starts.
+
+ :param stopCallback:
+
+ Python callable to invoke when the animation has
+ finished running, either because it has run the allotted time or because
+ abort was called.
+
+ :param maxAge: The maximum duration of the animation in milliseconds.
+
+ .. py:method:: start(keepAttr)
+
+ Starts the animation by calling :py:meth:`start` for each of the child
+ animations.
+
+ :param keepAttr:
+
+ This parameter is passed to the child animations.
+
+ .. autoclass:: SimpleAnim
+
+ Base class for animations that change libavg node attributes by
+ interpolating over a set amount of time. If :py:meth:`Anim.abort()` isn't needed,
+ there is no need to hold on to the animation object after calling
+ :py:meth:`Anim.start` - it will exist exactly as long as the animation lasts and
+ then disappear.
+
+ The animation framework makes sure that only one animation per attribute
+ of a node runs at any given time. If a second one is started, the first
+ one is aborted.
+
+ .. autoclass:: StateAnim(states)
+
+ Animation that executes one of several child animations depending on its
+ current state. The state can be None, in which case no animation is
+ executed. None is the initial state. Note that changing the state of an
+ animation during a start or stop callback of a child animation is not
+ possible. An attempt to do so is silently ignored.
+
+ :param states: A list of AnimState objects.
+
+ .. py:method:: getState
+
+ .. py:method:: setDebug(debug)
+
+ Setting this to :py:const:`True` causes all state changes to be printed on
+ the console.
+
+ .. py:method:: setState
+
+ .. autoclass:: WaitAnim([duration=-1, startCallback, stopCallback])
+
+
+ Animation that simply does nothing for a specified duration. Useful
+ in the context of StateAnims.
+
+ :param duration: The length of the animation in milliseconds.
+
+ :param startCallback: Python callable to invoke when the animation starts.
+
+ :param stopCallback:
+
+ Python callable to invoke when the animation has
+ finished running, either because it has run the allotted time or because
+ abort was called.
+
+ .. py:method:: start
+
+ .. autofunction:: fadeIn(node, duration, [max=1.0, stopCallback])
+
+ Fades the opacity of a node.
+
+ :param node: The node to fade.
+ :param duration: Length of the fade in milliseconds.
+ :param max: The opacity of the node at the end of the fade.
+ :param stopCallback: Function to call when the fade is over.
+
+ .. autofunction:: fadeOut(node, duration, [stopCallback])
+
+ Fades the opacity of a node to zero.
+
+ :param node: The node to fade.
+ :param duration: Length of the fade in milliseconds.
+ :param stopCallback: Function to call when the fade is over.
+
+ .. autofunction:: getNumRunningAnims() -> int
+
+ Returns the total number of running attribute-based animations (this
+ includes LinearAnim, EaseInOutAnim and ContinuousAnim). Useful for
+ debugging memory leaks.
diff --git a/sphinxdoc/app.rst b/sphinxdoc/app.rst
new file mode 100644
index 0000000..2fe03d1
--- /dev/null
+++ b/sphinxdoc/app.rst
@@ -0,0 +1,217 @@
+app module
+==========
+
+.. automodule:: libavg.app
+
+ .. note::
+
+ The app package is experimental. Functionality and interface are still in flux and
+ subject to change.
+
+ .. autoclass:: App
+
+ This class handles global application affairs. Among these are setting up a root
+ node along with window size (and possibly screen resolution) and screen
+ rotation, and creating an environment for the user's :py:class:`MainDiv`.
+ Global user interface items such as a debug panel and keyboard manager are also
+ set up. Additionally, :py:class:`App` handles configuration settings and command
+ line argument support.
+
+ :py:class:`App` usually does not need to be subclassed. Instead, subclass
+ :py:class:`MainDiv` and pass an instance of the derived class to :py:meth:`run()`.
+
+ .. py:attribute:: debugPanel
+
+ An instance of debugpanel.DebugPanel.
+
+ .. py:attribute:: mainDiv
+
+ The instance passed as first argument of the :py:meth:`run()` method.
+
+ .. py:attribute:: overlayPanel
+
+ DivNode that stands always on top of the MainDiv.
+
+ .. py:attribute:: settings
+
+ An instance of settings.Settings.
+
+ .. py:method:: dumpTextObjectCount()
+
+ Dumps on the console the current number of initialized objects. Normally
+ bound to the keypress :kbd:`CTRL-b`.
+
+ .. py:method:: onBeforeLaunch()
+
+ Called just before starting the main loop (:samp:`Player.play()`). Useful only
+ for subclassing. The display hasn't been initialized at this point.
+
+ .. py:method:: run(mainDiv, **kargs)
+
+ Starts the application using the provided :py:attr:`mainDiv` (an instance of
+ :py:class:`MainDiv`).
+
+ The optional additional kargs are used to set default settings - see
+ :py:class:`settings.Settings`.
+
+ .. py:method:: takeScreenshot(targetFolder='.')
+
+ Takes a screenshot of what is currently visible on the screen. Normally
+ bound to the keypress :kbd:`CTRL-p`. Screenshots are saved to the disk under
+ the name 'App-nnn.png', where nnn is a sequence number.
+
+
+ .. autoclass:: MainDiv
+
+ This abstract class must be subclassed to write a libavg application. It is the
+ main application entry point and should be the parent node for all
+ application-created nodes. All the public methods are empty and don't do anything
+ if not overridden.
+
+ .. py:attribute:: VERSION
+
+ A version string. This is shown using the :option:`-v` or :option:`--version`
+ command-line option.
+
+ .. py:method:: onArgvParsed(options, args, parser)
+
+ This method is called after command-line arguments have been parsed and should
+ be used to retrieve any application-specific options. The arguments
+ :py:attr:`options` and :py:attr:`args` are the result of calling
+ :samp:`options, args = parser.parse_args()`, where parser is an instance of
+ :py:class:`optparse.OptionParser` configured by calling
+ :py:meth:`onArgvParserCreated`.
+
+ .. py:method:: onArgvParserCreated(parser)
+
+ Called with an empty :py:class:`optparse.OptionParser` instance. Allows the
+ application to add additional command line options. :py:class:`App` adds it's
+ own parameters as well. If this is overridden, :py:meth:`onArgvParsed()`
+ should probably be overridden as well.
+
+ .. py:method:: onExit()
+
+ Called after the main loop exits.
+ Release resources and run cleanups here.
+
+ .. note::
+
+ onExit() doesn't get called if an exception is raised on the main thread.
+
+ .. py:method:: onFrame()
+
+ Called every frame.
+
+ .. py:method:: onInit()
+
+ Called by a libavg timer as soon as the main loop starts. At this point in
+ time, the window has been created and all render functions are available.
+ Build the application node tree here.
+
+ .. py:method:: onStartup()
+
+ Called before libavg has been setup, just after the :samp:`App().run()` call.
+ The window has not been created at this time.
+
+
+keyboardmanager Module
+----------------------
+
+.. automodule:: libavg.app.keyboardmanager
+ :no-members:
+
+ This module makes it possible to attach event handlers to individual keypresses.
+ Keys that are bound through the keyboard manager are also be shown in the debug panel
+ via the keyboard bindings widget along with their help string.
+ :py:class:`libavg.app.App` defines a range of keyboard bindings by default.
+ The keyboardmanager is usually set up by :py:class:`libavg.app.App`.
+ :py:class:`libavg.app.App` also reserves all keys modified by :kbd:`CTRL`.
+
+ For all the binding methods, keystring can be a python string or a unicode object.
+ Plain strings are matched to :py:attr:`libavg.avg.KeyEvent.keystring`, while unicode
+ objects are matched to :py:attr:`libavg.avg.KeyEvent.unicode`. The modifiers are
+ described under :py:attr:`libavg.avg.KeyEvent.modifiers`, with the additional modifiers
+ :py:const:`KEYMOD_SHIFT`, :py:const:`KEYMOD_CTRL` and :py:const:`KEYMOD_ALT` available
+ to simplify checking for left and right modifier keys at one time.
+
+ .. py:function:: bindKeyDown(keystring, handler, help, modifiers=avg.KEYMOD_NONE)
+
+ Sets up a key handler so that :py:attr:`handler` is called whenever
+ :py:attr:`keystring` is pressed.
+
+ .. py:function:: bindKeyUp(keystring, handler, help, modifiers=avg.KEYMOD_NONE)
+
+ Sets up a key handler so that :py:attr:`handler` is called whenever
+ :py:attr:`keystring` is released.
+
+ .. py:function:: disable()
+
+ Companion to :py:meth:`enable()`, disables all handlers.
+
+ .. py:function:: enable()
+
+ Companion to :py:meth:`disable()`, enables all handlers.
+
+ .. py:function:: getCurrentBindings()
+
+ Returns the currently assigned bindings as a list of named tuples.
+
+ .. py:function:: init()
+
+ Called by :py:class:`App`. Should not be called by user programs.
+
+ .. py:function:: pop()
+
+ Companion to :py:meth:`push()`, restores the non-modified key bindings
+ previously pushed onto the stack via :py:meth:`push()`.
+
+ .. py:function:: push()
+
+ Pushes all the non-modified key bindings onto a stack and clears them all.
+ Useful when the application flow branches to a state where a different key
+ bindings set is needed. The bindings can be then restored with :py:meth:`pop()`.
+
+ .. py:function:: unbindAll()
+
+ Removes all the defined key bindings at once.
+
+ .. py:function:: unbindKeyDown(keystring, modifiers=avg.KEYMOD_NONE)
+
+ Removes a previously defined key binding for a KEY_DOWN event.
+
+ .. py:function:: unbindKeyDown(keystring, modifiers=avg.KEYMOD_NONE)
+
+ Removes a previously defined key binding for a KEY_UP event.
+
+
+flashmessage Module
+-------------------
+
+.. automodule:: libavg.app.flashmessage
+ :no-members:
+
+ .. autoclass:: FlashMessage(text, timeout=DEFAULT_TIMEOUT, parent=None, isError=False, acknowledge=False)
+
+ A :py:class:`FlashMessage` is an easy way to show debug notification and similar
+ text in the libavg window. The message can have an optional timeout or stay
+ visible until clicked on by the user. It inserts itself into node tree at the top.
+ Multiple :py:class:`FlashMessage` instances are shown in the order they get
+ created.
+
+ :param timeout: The time in milliseconds the message should persist on screen
+ before it gets removed. Only valid if :py:attr:`acknowledge` is
+ :py:const:`False`.
+
+ :param parent: When specified, the parent node the message should be appending
+ itself to.
+
+ :param isError: A boolean flag to mark the message as error. Error-flagged
+ messages are shown in a different color and are routed to the
+ logger as well.
+
+ :param acknowledge: A flag to indicate whether the message should remove itself
+ automatically (after timeout has elapsed) or needs to be acknowledged
+ by the user (by clicking / touching on it).
+
+
+
diff --git a/sphinxdoc/areanodes.rst b/sphinxdoc/areanodes.rst
new file mode 100644
index 0000000..9bd54a3
--- /dev/null
+++ b/sphinxdoc/areanodes.rst
@@ -0,0 +1,831 @@
+Area Nodes
+==========
+
+.. automodule:: libavg.avg
+ :no-members:
+
+ .. inheritance-diagram:: AVGNode AreaNode CameraNode CanvasNode DivNode ImageNode Node RasterNode SoundNode VideoNode WordsNode
+ :parts: 1
+
+ .. autoclass:: AreaNode([x, y, pos, width, height, size, angle, pivot])
+
+ Base class for elements in the avg tree that define an area on the screen.
+ Responsible for coordinate transformations and event handling. See
+ http://www.libavg.de/wiki/ProgrammersGuide/CoordinateSystems
+ for an explanation of coordinate systems and reference points.
+
+ .. py:method:: getMediaSize() -> avg.Point2D
+
+ Returns the size in pixels of the media in the node. Image nodes
+ return the bitmap size, Camera nodes
+ the size of a camera frame and Words nodes the amount of space
+ the text takes. Video nodes return the video size if decoding has
+ started or (0,0) if not. Decoding starts after :py:func:`play` or
+ :py:func:`pause`
+ is called and the node can be rendered.
+
+ .. py:attribute:: x
+
+ This is the horizontal position of the node's reference point
+ relative to its parent node.
+
+ .. py:attribute:: y
+
+ This is the vertical position of the node's reference point
+ relative to its parent node.
+
+ .. py:attribute:: pos
+
+ This is the position of the node's reference point
+ relative to its parent node.
+
+ .. py:attribute:: width
+
+ .. py:attribute:: height
+
+ .. py:attribute:: angle
+
+ The angle that the node is rotated to in radians. 0 is
+ unchanged, 3.14 is upside-down.
+
+ .. py:attribute:: size
+
+ The size that the node takes on the canvas. Node types usually have sensible
+ defaults for the size. For media nodes, this is generally the size of the
+ media (so :samp:`size == getMediaSize()`). For DivNodes, the default size is
+ infinite.
+
+ .. py:attribute:: pivot
+
+ The position of the point that the node is rotated around.
+ Default is the center of the node.
+
+
+ .. autoclass:: AVGNode()
+
+ Root node of an onscreen avg tree. Defines the properties of the display
+ and handles key press events. The AVGNode's width and height define the
+ coordinate system for the display and are the default for the window
+ size used (i.e. by default, the coordinate system is pixel-based).
+
+
+ .. autoclass:: CameraControl
+
+ Camera controls are camera configuration parameters like brightness and white
+ balance. A CameraControl object contains information about the supported maximum
+ and minimum values as well as defaults for a specific control.
+
+ .. py:attribute:: controlName
+
+ String which tells which control is meant. Read-only.
+
+ .. py:attribute:: default
+
+ .. py:attribute:: max
+
+ .. py:attribute:: min
+
+ .. autoclass:: CameraImageFormat
+
+ CameraImageFormat objects contain information about a supported
+ image format of a camera.
+
+ .. py:attribute:: framerates
+
+ List of supported frame rates in images per second for that image format as
+ floats. Read-only.
+
+ .. py:attribute:: pixelFormat
+
+ String which tells about the pixel format (see :py:class:`Bitmap`). Read-only.
+
+ .. py:attribute:: size
+
+ A point which represents the resolution in width and height. Read-only.
+
+ .. autoclass:: CameraInfo
+
+ CameraInfo objects contain data about camera capabilities. The data can be used
+ to create create objects of class :py:class:`CameraNode`. The unique value to
+ identify the camera is stored in :py:attr:`device`, whereas :py:attr:`driver`
+ tells which driver is used to call the camera itself. Information about supported
+ camera :py:attr:`controls` or :py:attr:`imageFormats` are stored
+ in two separate lists.
+
+ .. py:attribute:: controls
+
+ List of :py:class:`CameraControl` objects with all possible controls for
+ that camera. Read-only.
+
+ .. py:attribute:: device
+
+ String which contains the unique id of the camera. Read-only.
+
+ .. py:attribute:: driver
+
+ String which contains the name of the driver. Read-only.
+
+ .. py:attribute:: imageFormats
+
+ List of :py:class:`CameraImageFormat` objects with all possible image
+ formats for that camera. Read-only.
+
+ .. autoclass:: CameraNode([driver='firewire', device="", unit=-1, fw800=False, framerate=15, capturewidth=640, captureheight=480, pixelformat="RGB", brightness, exposure, sharpness, saturation, camgamma, shutter, gain, strobeduration])
+
+ A node that displays the image of a camera. The attributes correspond to the
+ camera properties in .avgtrackerrc and are explained under
+ http://www.libavg.de/wiki/ProgrammersGuide/Tracker. An easy way to find the
+ appropriate parameters for your camera is to use :command:`avg_showcamera.py`.
+
+ CameraNodes open the camera device on construction and set the chosen camera
+ parameters immediately.
+
+ .. py:attribute:: brightness
+
+ .. py:attribute:: camgamma
+
+ .. py:attribute:: device
+
+ Read-only.
+
+ .. py:attribute:: driver
+
+ Read-only.
+
+ .. py:attribute:: framenum
+
+ The number of frames the camera has read since playback started. Read-only.
+
+ .. py:attribute:: framerate
+
+ Read-only.
+
+ .. py:attribute:: gain
+
+ .. py:attribute:: saturation
+
+ .. py:attribute:: sharpness
+
+ .. py:attribute:: shutter
+
+ .. py:attribute:: strobeduration
+
+ .. py:method:: doOneShotWhitebalance()
+
+ .. py:method:: getBitmap() -> Bitmap
+
+ Returns a copy of the last camera frame.
+
+ .. py:method:: getWhitebalanceU() -> int
+
+ .. py:method:: getWhitebalanceV() -> int
+
+ .. py:method:: isAvailable() -> bool
+
+ Returns :py:const:`True` if there is a working device that can deliver images
+ attached to the CameraNode.
+
+ .. py:method:: play()
+
+ Starts reading images from the camera device and displays them. Note that the
+ camera device is opened on construction of the CameraNode.
+
+ .. py:method:: setWhitebalance(u, v)
+
+ .. py:method:: stop()
+
+ Stops camera playback.
+
+ .. py:classmethod:: getCamerasInfos()
+
+ Returns a list of :py:class:`CameraInfo` objects, one for for each connected
+ camera.
+
+ .. py:classmethod:: resetFirewireBus()
+
+ Frees all allocated bandwidth and devices on the firewire bus. Helpful
+ if a program using a firewire device has crashed leaving resources
+ allocated. Note that all firewire devices (including for instance
+ external hard drives) are affected.
+
+ .. autoclass:: CanvasNode
+
+ Root node of a scene graph.
+
+ .. autoclass:: DivNode([crop=False, elementoutlinecolor, mediadir])
+
+ A div node is a node that groups other nodes logically and visually.
+ Its position is used as point of origin for the coordinates
+ of its child nodes. Its extents can be used to clip the children if crop is set
+ to :py:const:`True`. Its opacity is used as base opacity for the child nodes'
+ opacities. The children of a div node are drawn in the order they are found
+ in the avg file, so the first one is below all others in z-order.
+
+ .. py:attribute:: crop
+
+ Boolean that turns clipping on or off.
+
+ .. py:attribute:: elementoutlinecolor
+
+ Allows debugging of div node nesting by rendering the outlines of
+ this div and all its div children in the specified color (given in html hex
+ format). Turn off by setting the color to the empty string.
+
+ .. py:attribute:: mediadir
+
+ .. deprecated:: 1.7
+ Seldom used, error-prone and slow.
+
+ The directory that the media files for the children of this node are
+ in. Relative mediadirs are taken to mean subdirectories of the parent node's
+ mediadir.
+
+ .. py:method:: getNumChildren() -> int
+
+ Returns the number of immediate children that this div contains.
+
+ .. py:method:: getChild(i) -> Node
+
+ Returns the child at index :py:attr:`i`.
+
+ .. py:method:: appendChild(node)
+
+ Adds a new child to the container behind the last existing child.
+
+ .. py:method:: insertChildBefore(newNode, oldChild)
+
+ Adds a new child to the container before the existing node
+ :py:attr:`oldChild`. In z-order, the new child ist behind the old one.
+
+ .. py:method:: insertChildAfter(newNode, oldChild)
+
+ Adds a new child to the container after the existing node
+ :py:attr:`oldChild`. In z-order, the new child ist in front of the old one.
+
+ .. py:method:: insertChild(node, i)
+
+ Adds a new child to the container at index :py:attr:`i`.
+
+ .. py:method:: removeChild(node)
+
+ Removes the child given by :py:attr:`node` from the div. Note that as long as
+ other references to the node exist, the node is not deleted.
+
+ .. py:method:: removeChild(i)
+
+ Removes the child at index :py:attr:`i` from the div. Note that as long a`
+ other references to the node exist, the node is not deleted.
+
+ .. py:method:: reorderChild(oldIndex, newIndex)
+
+ Moves the child at :py:attr:`oldIndex` so it is at :py:attr:`newIndex`. This
+ function can be used to change the order in which the children are drawn.
+
+ .. py:method:: reorderChild(node, newPos)
+
+ Moves the child :py:attr:`node` so it is at index :py:attr:`newPos`. This
+ function can be used to change the order in which the children are drawn.
+
+ .. py:method:: indexOf(node)
+
+ Returns the index of the node given. Throws an exception if :py:attr:`node`
+ isn't a child of the :py:class:`DivNode`.
+
+ .. py:method:: getEffectiveMediaDir() -> string
+
+ Returns the node's effective mediadir by traversing the node
+ hierarchy up to the root node.
+
+ .. autoclass:: ImageNode([href, compression])
+
+ A static raster image on the screen. The content of an ImageNode can be loaded
+ from a file. It can also come from a :py:class:`Bitmap` object or from an
+ :py:class:`OffscreenCanvas`. Alpha channels of the image files are used as
+ transparency information.
+
+ .. py:attribute:: compression
+
+ The texture compression used for this image. Currently, :py:const:`none`
+ and :py:const:`B5G6R5` are supported. :py:const:`B5G6R5` causes the bitmap
+ to be compressed to 16 bit per pixel on load and is only valid if the source
+ is a filename. Read-only.
+
+ .. py:attribute:: href
+
+ In the standard case, this is the source filename of the image. To use a
+ bitmap as source, call setBitmap(). To use an offscreen canvas as source,
+ use the :samp:`canvas:` protocol: :samp:`href="canvas:{id}"`.
+
+ .. py:method:: getBitmap() -> Bitmap
+
+ Returns a copy of the bitmap that the node contains.
+
+ .. py:method:: setBitmap(bitmap)
+
+ Sets a bitmap to use as content for the ImageNode. Sets href to an empty
+ string.
+
+ .. autoclass:: RasterNode([maxtilewidth, maxtileheight, blendmode, mipmap, maskhref, maskpos, masksize, gamma, contrast, intensity])
+
+ Base class for all nodes that have a direct 2D raster representation.
+ This includes Image, Word, Camera, and Video nodes. The base class implements
+ color controls (:py:attr:`contrast`, :py:attr:`intensity`, :py:attr:`gamma`),
+ alpha masks (:py:attr:`maskhref`, :py:attr:`maskpos`, :py:attr:`masksize`),
+ several blend modes that define how compositing is done and mipmapping support.
+
+ Any Raster Node can have a GPU-based effect added to it by using
+ :py:meth:`setEffect`.
+
+ In addition, RasterNodes can be warped. By default, a RasterNode is rectangular.
+ However, it can be subdivided into a grid of reference points using
+ :py:attr:`maxtilewidth` and :py:attr:`maxtileheight`. The position of each of
+ these points can be changed with :py:meth:`getOrigVertexCoords`,
+ :py:meth:`getWarpedVertexCoords` and :py:meth:`setWarpedVertexCoords`,
+ yielding arbitrary shapes.
+
+ .. py:attribute:: blendmode
+
+ .. deprecated:: 1.7
+
+ The min and max blend modes will be removed.
+
+ The method of compositing the node with the nodes under
+ it. Valid values are :py:const:`blend`, :py:const:`add`, :py:const:`min`
+ and :py:const:`max`. For :py:const:`min` and :py:const:`max`
+ blend modes, opacity is ignored.
+
+ .. py:attribute:: contrast
+
+ A control for the color contrast of the node. contrast is a triple
+ that contains separate float values for red, green, and blue. A contrast
+ value of 1.0 in all channels leaves the image unchanged.
+
+ .. py:attribute:: gamma
+
+ Allows node-specific gamma correction. gamma is a triple that
+ contains separate float values for red, green, and blue. A gamma value of
+ 1.0 in all channels leaves the image unchanged. Higher gamma values
+ increase, lower values decrease the brightness. In all cases, black and
+ white pixels are not affected by gamma. See also
+ http://en.wikipedia.org/wiki/Gamma_correction.
+
+ .. py:attribute:: intensity
+
+ A control for the brightness of the node. intensity is a triple
+ that contains separate float values for red, green, and blue. An intensity
+ value of 1.0 in all channels leaves the image unchanged. This value
+ corresponds to the photoshop brightness value.
+
+ .. py:attribute:: maskhref
+
+ The source filename for a mask image to be used as alpha channel.
+ Where this file is white, the node is shown. Where it is black, the
+ node is transparent. If the node is an image with an alpha channel,
+ the alpha channel is replaced by the mask.
+
+ .. py:attribute:: maskpos
+
+ An offset for the mask image. For images and videos, the offset is
+ given in image or video pixels, respectively. For words nodes, the
+ offset is given in screen pixels. If portions of the node extend
+ outside the mask, the border pixels of the mask are taken. Note that the
+ maskpos is an offset from the top left of the node, even for
+ :py:class:`WordsNode` objects that have :py:attr:`alignment`
+ :py:const:`Center` or :py:const:`Right`.
+
+
+ .. py:attribute:: masksize
+
+ The size of the mask image. For images and videos, the size is
+ given in image or video pixels, respectively. For words nodes, the
+ size is given in screen pixels. If portions of the node extend
+ outside the mask, the border pixels of the mask are taken.
+
+ .. py:attribute:: maxtileheight
+
+ The maximum height of the tiles used for warping. The effective tile size is
+ also dependent on hardware and driver limits. Read-only.
+
+ .. py:attribute:: maxtilewidth
+
+ The maximum width of the tiles used for warping. The effective tile size is
+ also dependent on hardware and driver limits. Read-only.
+
+ .. py:attribute:: mipmap
+
+ Determines whether mipmaps (http://en.wikipedia.org/wiki/Mipmap) are
+ generated for this node. Setting this to :py:const:`True` improves the quality
+ of minified nodes. Depending on the graphics card in use, turning on mipmaps
+ may cause an extreme performance hit for every image change or have no
+ performance cost at all. Read-only.
+
+ .. py:method:: getOrigVertexCoords() -> list
+
+ Returns the unwarped coordinate of all vertices as a list of lists.
+
+ .. py:method:: getWarpedVertexCoords() -> list
+
+ Returnes the current coordinate of all vertices as a list of lists.
+
+ .. py:method:: setEffect(FXNode)
+
+ Attaches an :py:class:`FXNode` to the node that modifies how it looks.
+
+ .. py:method:: setWarpedVertexCoords(grid)
+
+ Changes the current coordinates of all vertices. :py:attr:`grid` is a list of
+ lists of coordinate tuples. :py:meth:`setWarpedVertexCoords` can only be called if
+ the node is in a renderable state. This means that :py:meth:`Player.play()` must have
+ been called and the node must be inserted in a Canvas. There must also be something to
+ render (for instance, :py:meth:`play()` must be called before
+ :py:meth:`setWarpedVertexCoords` in the case of a :py:class:`CameraNode`). The grid
+ submitted is lost if the node loses renderable status.
+
+ .. autoclass:: SoundNode([href, loop=False, volume=1.0])
+
+ A sound played from a file.
+
+ **Messages:**
+
+ To get this message, call :py:meth:`Publisher.subscribe`.
+
+ .. py:method:: Node.END_OF_FILE()
+
+ Emitted when the end of the audio stream has been reached.
+
+ .. py:attribute:: duration
+
+ The duration of the sound file in milliseconds. Some file formats don't store
+ valid durations; in this case, 0 is returned. Read-only.
+
+ .. py:attribute:: href
+
+ The source filename of the sound.
+
+ .. py:attribute:: loop
+
+ Whether to start the sound again when it has ended. Read-only.
+
+ .. py:attribute:: volume
+
+ Audio playback volume for this sound. 0 is silence, 1 passes media
+ file volume through unchanged. Values higher than 1 can be used to
+ amplify sound if the sound file doesn't use the complete dynamic
+ range.
+
+ .. py:method:: getAudioCodec() -> string
+
+ Returns the codec used as a string such as :samp:`"mp2"`.
+
+ .. py:method:: getAudioSampleRate() -> int
+
+ Returns the sample rate in samples per second (for example, 44100).
+
+ .. py:method:: getCurTime() -> time
+
+ Returns milliseconds of playback time since audio start.
+
+ .. py:method:: getNumAudioChannels() -> int
+
+ Returns the number of channels. 2 for stereo, etc.
+
+ .. py:method:: pause()
+
+ Stops audio playback but doesn't close the object. The playback
+ cursor stays at the same position.
+
+ .. py:method:: play()
+
+ Starts audio playback.
+
+ .. py:method:: seekToTime(time)
+
+ Moves the playback cursor to the time given in milliseconds.
+
+ .. py:method:: setEOFCallback(pyfunc)
+
+ .. deprecated:: 1.8
+ Use the message interface instead.
+
+ Sets a python callable to be invoked when the audio reaches end of file.
+
+ .. py:method:: stop()
+
+ Stops audio playback. Closes the object and 'rewinds' the playback cursor.
+
+ .. autoclass:: VideoNode([href, loop=False, threaded=True, fps, queuelength=8, volume=1.0, accelerated=True, enablesound=True])
+
+ Video nodes display a video file. Video formats and codecs supported
+ are all formats that ffmpeg/libavcodec supports. Usage is described thoroughly
+ in the libavg wiki: https://www.libavg.de/wiki/ProgrammersGuide/VideoNode.
+
+ **Messages:**
+
+ To get this message, call :py:meth:`Publisher.subscribe`.
+
+ .. py:method:: Node.END_OF_FILE()
+
+ Emitted when the end of the video stream has been reached.
+
+ .. py:attribute:: accelerated
+
+ On construction, set to :py:const:`True` if hardware acceleration should be
+ used to decode this video. Later queries of the attribute return
+ :py:const:`True` if acceleration is actually being used. Read-only.
+
+ .. py:attribute:: enablesound
+
+ On construction, set to :py:const:`True` if any audio present in the video
+ file should be played back as well. A value of :py:const:`False` ignores
+ audio and just plays a silent video.
+
+ .. py:attribute:: fps
+
+ The nominal frames per second the object should display at. Read-only.
+
+ .. py:attribute:: href
+
+ The source filename of the video.
+
+ .. py:attribute:: loop
+
+ Whether to start the video again when it has ended. Read-only.
+
+ .. py:attribute:: queuelength
+
+ The length of the decoder queue in video frames. This is the number of
+ frames that can be decoded before the first one is displayed. A higher
+ number increases memory consumption but also resilience against
+ data source latency (i.e. hiccups during disk reads). Can only be set at node
+ construction. Can't be set if :samp:`threaded=False`, since there is no queue
+ in that case.
+
+ .. py:attribute:: threaded
+
+ Whether to use separate threads to decode the video. The default is
+ :py:const:`True`. Setting this attribute to :py:const:`False` makes seeking
+ much quicker. On the other hand, it also disables audio and prevents libavg
+ from distributing the CPU load over several cores of a multi-core computer.
+
+ .. py:attribute:: volume
+
+ Audio playback volume for this video. 0 is silence, 1 passes media
+ file volume through unchanged. Values higher than 1 can be used to
+ amplify sound if the sound file doesn't use the complete dynamic
+ range. If there is no audio track, volume is ignored.
+
+ .. py:method:: getAudioCodec() -> string
+
+ Returns the audio codec used as a string such as :samp:`mp2`.
+
+ .. py:method:: getAudioSampleRate() -> int
+
+ Returns the sample rate in samples per second (for example, 44100).
+
+ .. py:method:: getBitrate() -> int
+
+ Returns the number of bits in the file per second.
+
+ .. py:method:: getContainerFormat() -> string
+
+ Returns the video file format. This is a string such as :samp:`avi` or
+ :samp:`mpeg`.
+
+ .. py:method:: getCurFrame() -> int
+
+ Returns the index of the video frame currently playing.
+
+ .. py:method:: getCurTime()
+
+ Returns milliseconds of playback time since video start.
+
+ .. py:method:: getDuration() -> int
+
+ Returns the duration of the video in milliseconds. Some file formats don't
+ store valid durations; in this case, 0 is returned. Read-only.
+
+ .. py:method:: getNumFrames() -> int
+
+ Returns the number of frames in the video.
+
+ .. py:method:: getNumAudioChannels() -> int
+
+ Returns the number of audio channels. 2 for stereo, etc.
+
+ .. py:method:: getNumFramesQueued() -> int
+
+ Returns the number of frames already decoded and waiting for playback.
+
+ .. py:method:: getStreamPixelFormat() -> string
+
+ Returns the pixel format of the video file as a string. Possible
+ pixel formats are described in
+ http://ffmpeg.mplayerhq.hu/doxygen/trunk/pixfmt_8h.html#60883d4958a60b91661e97027a85072a
+
+ .. py:method:: getVideoCodec() -> string
+
+ Returns the video codec used as a string such as :samp:`mpeg4`.
+
+ .. py:method:: hasAlpha() -> bool
+
+ Returns :py:const:`True` if the video contains an alpha (transparency)
+ channel. Throws an exception if the video has not been opened yet.
+
+ .. py:method:: hasAudio() -> bool
+
+ Returns :py:const:`True` if the video contains an audio stream. Throws an
+ exception if the video has not been opened yet.
+
+ .. py:method:: pause()
+
+ Stops video playback but doesn't close the object. The playback
+ cursor stays at the same position and the decoder queues remain full.
+
+ .. py:method:: play()
+
+ Starts video playback.
+
+ .. py:method:: seekToFrame(num)
+
+ Moves the playback cursor to the frame given.
+
+ .. py:method:: seekToTime(millisecs)
+
+ Moves the playback cursor to the time given.
+
+ .. py:method:: setEOFCallback(pyfunc)
+
+ .. deprecated:: 1.8
+ Use the message interface instead.
+
+ Sets a python callable to be invoked when the video reaches end of file.
+
+ .. py:method:: stop()
+
+ Stops video playback. Closes the file, 'rewinds' the playback
+ cursor and clears the decoder queues.
+
+ .. py:classmethod:: getVideoAccelConfig() -> enum
+
+ Returns either :py:const:`NO_ACCELERATION` if the current configuration does
+ not support hardware-accelerated video decoding or :py:const:`VDPAU` if VDPAU
+ can be used to decode videos.
+
+ .. autoclass:: WordsNode([fontstyle=None, font="sans", variant="", text="", color="FFFFFF", fontsize=15, indent=0, linespacing=-1, alignment="left", wrapmode="word", justify=False, rawtextmode=False, letterspacing=0, aagamma=1, hint=True])
+
+ A words node displays formatted text. All
+ properties are set in pixels. International and multi-byte character
+ sets are fully supported. Words nodes use UTF-8 to encode international
+ characters (use python unicode strings for this).
+
+ The pos attribute of a words node is the
+ logical top left of the first character for left-aligned text. For
+ centered and right-aligned text, it is the top center and right of the
+ first line, respectively. For latin text, the logical top usually
+ corresponds to the height of the ascender. There may be cases where
+ portions of the text are rendered to the left of or above the logical position,
+ for instance when italics are used.
+
+ Words nodes are rendered using pango internally.
+
+ .. py:attribute:: alignment
+
+ The paragraph alignment. Possible values are :py:const:`left`,
+ :py:const:`center` and :py:const:`right`.
+
+ .. py:attribute:: aagamma
+
+ Defines a gamma-correction value for the alpha (transparency) of the text
+ rendered. Using this attibute, it is possible to fine-tune the text
+ antialiasing and make sure rendering is smooth.
+
+ .. py:attribute:: color
+
+ The color of the text in standard html color notation: FF0000 is red,
+ 00FF00 green, etc.
+
+ .. py:attribute:: font
+
+ The family name of the truetype font to use. Font files can either be
+ installed in the system, be in a :file:`fonts/` subdirectory of the current
+ directory, or be in a directory specified using :py:meth:`addFontDir`. To
+ figure out which fonts and variants are available, use the
+ :command:`avg_showfonts.py` utility.
+
+ .. py:attribute:: fontsize
+
+ The font size in pixels. Fractional sizes are supported.
+
+ .. py:attribute:: fontstyle
+
+ A :py:class:`FontStyle` object that encapsulates all font attributes of the node. As a
+ constructor parameter, this attribute sets the default attributes and other
+ constructor arguments can override these. If set during :py:class:`WordsNode` use,
+ all relevant attributes are set to the new values.
+
+ .. py:attribute:: hint
+
+ Whether or not hinting (http://en.wikipedia.org/wiki/Font_hinting)
+ should be used when rendering the text. Unfortunately, this setting
+ does not override the fontconfig settings in
+ :file:`/etc/fonts/conf.d/*-hinting.conf` or other fontconfig configuration
+ files.
+
+ .. py:attribute:: indent
+
+ The indentation of the first line of the text.
+
+ .. py:attribute:: justify
+
+ Whether each complete line should be stretched to fill
+ the entire width of the layout. Default is false.
+
+ .. py:attribute:: letterspacing
+
+ The amount of space between the idividual glyphs of the text in
+ pixels, with 0 being standard spacing and negative values indicating
+ packed text (less letter spacing than normal). Only active when text
+ attribute markup is not being used.
+
+ .. py:attribute:: linespacing
+
+ The number of pixels between different lines of a paragraph. Setting this to
+ :samp:`-1` results in default line spacing.
+
+ .. py:attribute:: rawtextmode
+
+ Sets whether the text should be parsed to apply markup (:py:const:`False`,
+ default) or interpreted as raw string (:py:const:`True`).
+
+ .. py:attribute:: text
+
+ The string to display. If the node is created using xml, this is either the
+ text attribute of the words node or the content of the words
+ node itself. In the second case, the string can be formatted
+ using the pango text attribute markup language described at
+ http://developer.gnome.org/pango/unstable/PangoMarkupFormat.html.
+ Markup can also be used if the text is set using the python attribute.
+
+ Markup parsing can be turned on or off with :py:attr:`rawtextmode` attribute.
+
+ .. py:attribute:: variant
+
+ The variant (:samp:`bold`, :samp:`italic`, etc.) of the font to use.
+
+ .. py:attribute:: wrapmode
+
+ Controls at which points text can wrap to the next line. Possible values are
+ :py:const:`word` (split lines at the nearest whitespace, default),
+ :py:const:`char` (split at any position, ignoring word breaks) and
+ :py:const:`wordchar` (split at word boundaries but fall back
+ to char mode if there is no free space for a full word).
+
+ .. py:method:: getCharIndexFromPos(pos) -> int
+
+ Returns the index of the character at the coordinates :py:attr:`pos`, or
+ :py:const:`None` if there is no character at that position. :py:attr:`pos`
+ is relative to the node position.
+ Formatting markup such as <b> or <i> is treated as zero chars,
+ <br/> is treated as one char. To get the text matched to this
+ use :py:meth:`getTextAsDisplayed`.
+
+ .. py:method:: getGlyphPos(i) -> Point2D
+
+ Returns the position of the glyph at character index :py:attr:`i` in the
+ layout. The position is in pixels relative to the words
+ node. Formatting markup such as <b> or <i> is treated as zero chars,
+ <br/> is treated as one char.
+
+ .. py:method:: getGlyphSize(i) -> Point2D
+
+ Returns the size in pixels of the glyph at character index :py:attr:`i` in
+ the layout. Formatting markup such
+ as <b> or <i> is treated as zero chars, <br/> is treated as one char.
+
+ .. py:method:: getLineExtents(line) -> Point2D
+
+ Returns the width and height of the specified line in pixels.
+
+ .. py:method:: getNumLines() -> int
+
+ Returns the number of lines in the layout.
+
+ .. py:method:: getTextAsDisplayed
+
+ Returns the text without text attribute markup language. <br/>
+ is replaced by \\n.
+
+ .. py:classmethod:: addFontDir
+
+ Adds a directory to be searched for fonts.
+ May only be called before :py:meth:`Player.play`.
+
+ .. py:classmethod:: getFontFamilies() -> list
+
+ Returns a list of strings containing all font names available.
+
+ .. py:classmethod:: getFontVariants(fontname) -> list
+
+ Returns a list of available variants (:samp:`Regular`, :samp:`Bold`, etc.)
+ of a font.
+
diff --git a/sphinxdoc/basenodes.rst b/sphinxdoc/basenodes.rst
new file mode 100644
index 0000000..6b08120
--- /dev/null
+++ b/sphinxdoc/basenodes.rst
@@ -0,0 +1,382 @@
+Base Node Classes
+=================
+
+This section describes the base classes for all node classes that libavg provides.
+
+.. automodule:: libavg.avg
+ :no-members:
+
+ .. inheritance-diagram:: Node
+ :parts: 1
+
+ To be rendered, a :py:class:`Node` must be part of a scene graph. Scene graphs are
+ trees of :py:class:`Node` objects associated with a :py:class:`Canvas`. A
+ :py:class:`CanvasNode` is at the root of each scene graph. Scene graphs are pure tree
+ structures, so each :py:class:`Node` only has one parent node. Nodes that are not
+ linked to a canvas are not rendered. Any media that these nodes need are loaded from
+ disk, however.
+
+ libavg :py:class:`Node` classes make heavy use of inheritance. Concepts like
+ :py:attr:`id`, :py:attr:`position` and :py:attr:`opacity` are defined in base classes
+ and can be used in any of the subclasses.
+
+ .. note::
+
+ To reduce redundancy in the reference,
+ inherited methods and attributes are not mentioned in the derived class
+ documentation - follow the link to the base class to access them. This also
+ applies to constructor parameters: When constructing an object of a derived class,
+ constructor parameters of the base classes are also accepted.
+
+ There are several ways of constructing a
+ node. The reference documentation follows the python constructor syntax. The
+ parameters remain the same in all syntactic variations, however. The options for
+ construction are as follows:
+
+ **Use the standard python constructor**:
+ Nodes can be created using a standard python constructor. As an example::
+
+ node = ImageNode(id="background", href="sunset.png", pos=(0,0),
+ parent=rootNode)
+
+ Parameters to a node constructor are always named parameters. Nodes never have
+ positional constructor parameters.
+
+ **Use** :py:meth:`Player.createNode`:
+ There are two ways to create a node using createNode::
+
+ node = player.createNode("image",
+ {"id":"background", "href":"sunset.png", "pos":(0,0),
+ "parent":rootNode})
+
+ and::
+
+ node = player.createNode(
+ """<image id="background" href="sunset.png"
+ pos="(0,0)"/>""")
+
+ Using the second option, complete trees of nodes can be constructed in one
+ statement.
+
+ **Load it from an avg file**:
+ Complete scene graphs for onscreen display can be loaded from disk using
+ :py:meth:`Player.loadFile`::
+
+ root = player.loadFile("scene.avg")
+
+ **Create a complete scene graph using inline xml**:
+ :py:meth:`Player.loadString` allows using an avg-formatted xml string to
+ create a scene graph of nodes::
+
+ root = player.loadString("""
+ <avg size="(800,600)">
+ <image id="background" href="sunset.png"
+ pos="(0,0)"/>
+ </avg>
+ """)
+
+ The methods :py:meth:`Player.loadFile` and :py:meth:`Player.loadString` create
+ onscreen scene graphs. :py:meth:`Player.loadCanvasFile` and
+ :py:meth:`Player.loadCanvasString` are the equivalent methods for offscreen
+ canvases.
+
+ .. autoclass:: Node([id: string="", parent: DivNode=None, active=True, sensitive=True, opacity=1.0, style=None])
+
+ Base class for everything that can be put into an avg tree. This is an abstract
+ class.
+
+ **Messages:**
+
+ All cursor and hover messages are emitted only if the cursor is above the
+ :py:class:`Node` and
+ :py:attr:`active` as well as :py:attr:`sensitive` are True. The message
+ parameters are of type :py:class:`CursorEvent`. The CURSOR messages are
+ emitted for mouse and touch events. The HOVER events are emitted for touch
+ devices which can sense hands approaching the surface before the actual touch.
+
+ To get these messages, call :py:meth:`Publisher.subscribe`.
+
+ .. py:method:: CURSOR_DOWN(cursorevent)
+
+ Emitted whenever a mouse button is pressed or a new touch is registered.
+
+ .. py:method:: CURSOR_MOTION(cursorevent)
+
+ Emitted whenever a mouse or a touch moves.
+
+ .. py:method:: CURSOR_UP(cursorevent)
+
+ Emitted whenever a mouse button is released or a touch leaves the surface.
+
+ .. py:method:: CURSOR_OVER(cursorevent)
+
+ Emitted whenever a mouse or a touch enters the :py:class:`Node`'s area.
+
+ .. py:method:: CURSOR_OUT(cursorevent)
+
+ Emitted whenever a mouse or a touch leaves the :py:class:`Node`'s area.
+
+ .. py:method:: HOVER_DOWN(cursorevent)
+
+ Emitted whenever a new hover cursor is registered.
+
+ .. py:method:: HOVER_MOTION(cursorevent)
+
+ Emitted whenever a hover cursor moves.
+
+ .. py:method:: HOVER_UP(cursorevent)
+
+ Emitted whenever a hover cursor disappears.
+
+ .. py:method:: HOVER_OVER(cursorevent)
+
+ Emitted whenever a hover cursor enters the :py:class:`Node`'s area.
+
+ .. py:method:: HOVER_OUT(cursorevent)
+
+ Emitted whenever a hover cursor leaves the :py:class:`Node`'s area.
+
+ .. py:method:: SIZE_CHANGED(newSize)
+
+ Emitted whenever the size of the node changes. This includes any python
+ calls that change the size. In addition, image loading (for
+ :py:class:`ImageNode`), opening of video files (for
+ :py:class:`VideoNode`) and changes in the text displayed (in the case of
+ :py:class:`WordsNode`) can trigger :py:meth:`SIZE_CHANGED` messages. Note
+ that changing the size of a node inside a :py:meth:`SIZE_CHANGED` handler
+ will lead to an additional recursive invocation of
+ :py:meth:`SIZE_CHANGED`.
+
+ :py:class:`RectNode` and all classes derived from :py:class:`AreaNode`
+ support this message.
+
+
+ .. py:attribute:: id
+
+ A unique identifier that can be used to reference the node, for instance using
+ :py:meth:`Player.getElementByID`. Read-only.
+
+ .. py:attribute:: parent
+
+ A :py:class:`DivNode` that the node will become a child of. When used as a
+ constructor parameter, this is equivalent to calling
+ :py:meth:`DivNode.appendChild` directly after construction. Read-only.
+
+ .. py:attribute:: active
+
+ If this attribute is true, the node behaves as usual. If not, it
+ is neither drawn nor does it react to events.
+
+ .. py:attribute:: opacity
+
+ A measure of the node's transparency. 0.0 is completely
+ transparent, 1.0 is completely opaque. Opacity is relative to
+ the parent node's opacity.
+
+ .. py:attribute:: sensitive
+
+ A node only reacts to events if sensitive is true.
+
+ .. py:method:: connectEventHandler(type, source, pyobj, pyfunc)
+
+ .. deprecated:: 1.8
+ Use the message interface instead.
+
+ Sets a callback function that is invoked whenever an event of the
+ specified type from the specified source occurs. Unlike
+ :py:meth:`setEventHandler`, this method allows several handlers for one
+ type/source-combination. To remove a handler installed using
+ :py:meth:`connectEventHandler`, call :py:meth:`disconnectEventHandler`.
+
+ :param type:
+
+ One of the event types :py:const:`KEYUP`, :py:const:`KEYDOWN`,
+ :py:const:`CURSORMOTION`, :py:const:`CURSORUP`, :py:const:`CURSORDOWN`,
+ :py:const:`CURSOROVER` or :py:const:`CURSOROUT`.
+
+ :param source:
+
+ :py:const:`MOUSE` for mouse events, :py:const:`TOUCH` for multitouch touch
+ events, :py:const:`TRACK` for multitouch track events or other tracking,
+ :py:const:`NONE` for keyboard events. Sources can be or'ed together to
+ set a handler for several sources at once.
+
+ :param pyobj:
+
+ The python object that hosts the callback. This parameter is only needed
+ so that :py:meth:`disconnectEventHandler` can be called to remove all
+ handlers hosted by one object in one call.
+
+ :param pyfunc:
+
+ The python callable to invoke. This callable must take the event to
+ process as a parameter. In contrast to callbacks set up using
+ :py:meth:`setEventHandler`, it should not return anything. If
+ :py:meth:`connectEventHandler` is used, all events bubble up the tree.
+ pyfunc may not be :py:const:`None`.
+
+ .. py:method:: disconnectEventHandler(pyobj, [pyfunc])
+
+ .. deprecated:: 1.8
+ Use the message interface instead.
+
+ Removes one or more event handlers from the node's table of event handlers.
+ If several event handlers conform to the parameters given, all are removed.
+ It is an error if no matching event handler exists.
+
+ :param pyobj:
+
+ The python object that hosts the event handler.
+
+ :param pyfunc:
+
+ The python callable that should not be called anymore. If pyfunc is
+ absent, all callbacks hosted by :py:attr:`pyobj` are removed.
+
+ .. py:method:: getAbsPos(relpos) -> Point2D
+
+ Transforms a position in coordinates relative to the node to a
+ position in window coordinates.
+
+ .. py:method:: getElementByPos(pos) -> Node
+
+ Returns the topmost child node that is at the position given. :py:attr:`pos`
+ is in coordinates relative to the called node. The algorithm used
+ is the same as the cursor hit test algorithm used for events.
+
+ .. py:method:: getParent() -> Node
+
+ .. deprecated:: 1.8
+ Use :attr:`parent` instead.
+
+ Returns the container (:py:class:`AVGNode` or :py:class:`DivNode`) the node
+ is in. For the root node (or if the node is not connected), returns
+ :py:const:`None`.
+
+ .. py:method:: getRelPos(abspos) -> Point2D
+
+ Transforms a position in window coordinates to a position
+ in coordinates relative to the node.
+
+ .. py:method:: registerInstance(self, parent)
+
+ Needs to be called when deriving from a Node class in python in the derived
+ classes :py:meth:`__init__` method.
+
+ .. py:method:: releaseEventCapture([cursorid])
+
+ Restores normal cursor event handling after a call to
+ :py:meth:`setEventCapture()`. :py:attr:`cursorid` is the id of the
+ cursor to release. If :py:attr:`cursorid` is not given, the mouse cursor is
+ used.
+
+ .. py:method:: setEventCapture([cursorid])
+
+ Sets up event capturing so that cursor events are sent to this node
+ regardless of the cursor position. cursorid is optional; if left out,
+ the mouse cursor is captured. If not, events from a specific tracker
+ cursor are captured. The event propagates to the capturing node's
+ parent normally. This function is useful for the
+ implementation of user interface elements such as scroll bars. Only one
+ node can capture a cursor at any one time. Normal operation can
+ be restored by calling :py:meth:`releaseEventCapture()`.
+
+ .. py:method:: setEventHandler(type, source, pyfunc)
+
+ .. deprecated:: 1.7
+ Use the message interface instead.
+
+ Sets a callback function that is invoked whenever an event of the
+ specified type from the specified source occurs. This method removes all
+ other event handlers from this type/source-combination.
+
+ :param type:
+
+ One of the event types :py:const:`KEYUP`, :py:const:`KEYDOWN`,
+ :py:const:`CURSORMOTION`, :py:const:`CURSORUP`, :py:const:`CURSORDOWN`,
+ :py:const:`CURSOROVER` or :py:const:`CURSOROUT`.
+
+ :param source:
+
+ :py:const:`MOUSE` for mouse events, :py:const:`TOUCH` for multitouch
+ touch events, :py:const:`TRACK` for multitouch track events or other
+ tracking, :py:const:`NONE` for keyboard events. Sources can be or'ed
+ together to set a handler for several sources at once.
+
+ :param pyfunc:
+
+ The python callable to invoke. This callable must take the event to
+ process as a parameter. If pyfunc returns :py:const:`None` or
+ :py:const:`False`, the event bubbles up the node tree. If it is
+ :py:const:`True`, bubbling is suppressed.
+
+ If pyfunc is :py:const:`None`, the previous handler is removed.
+
+ .. py:method:: unlink([kill=False])
+
+ Removes a node from its parent container and optionally deletes all resources
+ the node holds. In the default case, :py:meth:`unlink` is equivalent to
+ :samp:`node.getParent().removeChild(node.getParent().indexOf(node))`,
+ except that if the node has no parent, unlink does nothing. Also in the
+ default case, textures are moved back to the CPU and event handlers are
+ preserved.
+
+ If :samp:`kill=True`, textures are not moved back. Event handlers for events
+ routed to this node are reset, all textures are deleted and the href is reset
+ to empty in this case, saving some time and making sure there are no
+ references to the node left on the libavg side. :py:attr:`kill` should always
+ be set to :py:const:`True` if the node will not be used after the unlink.
+
+
+ .. autoclass:: Publisher()
+
+ libavg supports event handling and callbacks through a publish/subscribe
+ interface. :py:class:`Publisher` is the base class for all classes that
+ send messages. Derived classes can send messages of arbitrary types. The base
+ class takes care of managing a list of subscribers for each message type and
+ sending the message to each subscriber.
+
+ Many libavg classes, including :py:class:`Node`, :py:class:`Player`,
+ :py:class:`Contact` and the :py:class:`Recognizer` classes derive from publisher.
+ In addition, it is possible to derive from :py:class:`Publisher` in client code
+ by calling the methods in the protected interface.
+
+ .. py:method:: subscribe(messageID, callable) -> int
+
+ Registers a subscriber for the given :py:attr:`messageID`. The
+ :py:attr:`callable` for all subscribers is invoked whenever the publisher
+ sends out the message with this ID.
+
+ :py:meth:`subscribe` returns a :py:attr:`subscriberID` that can be used to
+ unsubscribe if this becomes necessary. The subscription is also terminated if
+ either the publisher or the subscriber is deleted. The :py:class:`Publisher`
+ class works with weak references to subscribers when possible, so this should
+ happen automatically in most cases. The exception is when :py:attr:`callable`
+ is an anonymous function (a lambda expression). In this case, the
+ :py:class:`Publisher` needs to hold a reference to the callable to keep it
+ from being deleted immediately and :py:meth:`unsubscribe` needs to be called
+ manually.
+
+ .. py:method:: unsubscribe(messageID, subscriberID)
+ unsubscribe(messageID, callable)
+
+ Removes a subscriber from the list of subscribers for :py:attr:`messageID`.
+ The subscriber is either determined by the :py:attr:`subscriberID` returned
+ from :py:meth:`subscribe` or by the :py:attr:`callable` attached to the
+ subscription.
+
+ **Protected Interface:**
+
+ To be called from derived classes.
+
+ .. py:method:: publish(messageID)
+
+ Registers a :py:attr:`messageID` so that interested parties can subscribe
+ to this message.
+
+ .. py:method:: notifySubscribers(messageID, argsList)
+
+ Invokes all callables registered for this :py:attr:`messageID` using the
+ list of args passed. Subscribers are called synchronously; the order of
+ invokation is undefined.
+
diff --git a/sphinxdoc/conf.py b/sphinxdoc/conf.py
new file mode 100644
index 0000000..a27b2da
--- /dev/null
+++ b/sphinxdoc/conf.py
@@ -0,0 +1,223 @@
+# -*- coding: utf-8 -*-
+#
+# libavg documentation build configuration file, created by
+# sphinx-quickstart on Sun Nov 14 22:21:44 2010.
+#
+# This file is execfile()d with the current directory set to its containing dir.
+#
+# Note that not all possible configuration values are present in this
+# autogenerated file.
+#
+# All configuration values have a default; values that are commented out
+# serve to show the default.
+
+import sys
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+#sys.path.insert(0, os.path.abspath('.'))
+
+# -- General configuration -----------------------------------------------------
+
+# If your documentation needs a minimal Sphinx version, state it here.
+#needs_sphinx = '1.0'
+
+# Add any Sphinx extension module names here, as strings. They can be extensions
+# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
+extensions = ['sphinx.ext.autodoc', 'sphinx.ext.pngmath', 'sphinx.ext.coverage',
+ 'sphinx.ext.graphviz', 'sphinx.ext.inheritance_diagram']
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['_templates']
+
+# The suffix of source filenames.
+source_suffix = '.rst'
+
+# The encoding of source files.
+#source_encoding = 'utf-8-sig'
+
+# The master toctree document.
+master_doc = 'index'
+
+# General information about the project.
+project = u'libavg'
+copyright = u'2010, Ulrich von Zadow'
+
+# The version info for the project you're documenting, acts as replacement for
+# |version| and |release|, also used in various other places throughout the
+# built documents.
+#
+# The short X.Y version.
+version = '1.7'
+# The full version, including alpha/beta/rc tags.
+release = '1.7.svn'
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+#language = None
+
+# There are two options for replacing |today|: either, you set today to some
+# non-false value, then it is used:
+#today = ''
+# Else, today_fmt is used as the format for a strftime call.
+#today_fmt = '%B %d, %Y'
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+exclude_patterns = ['_build']
+
+# The reST default role (used for this markup: `text`) to use for all documents.
+#default_role = None
+
+# If true, '()' will be appended to :func: etc. cross-reference text.
+#add_function_parentheses = True
+
+# If true, the current module name will be prepended to all description
+# unit titles (such as .. function::).
+#add_module_names = True
+
+# If true, sectionauthor and moduleauthor directives will be shown in the
+# output. They are ignored by default.
+#show_authors = False
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+# A list of ignored prefixes for module index sorting.
+#modindex_common_prefix = []
+
+# -- Autodoc options -----------------------------------------------------------
+
+autodoc_member_order = 'groupwise'
+autodoc_default_flags = ['members', 'show-inheritance']
+
+# -- Options for HTML output ---------------------------------------------------
+
+# The theme to use for HTML and HTML Help pages. See the documentation for
+# a list of builtin themes.
+html_theme = 'sphinxdoc'
+
+# Theme options are theme-specific and customize the look and feel of a theme
+# further. For a list of options available for each theme, see the
+# documentation.
+#html_theme_options = {}
+
+# Add any paths that contain custom themes here, relative to this directory.
+#html_theme_path = []
+
+# The name for this set of Sphinx documents. If None, it defaults to
+# "<project> v<release> documentation".
+#html_title = None
+
+# A shorter title for the navigation bar. Default is the same as html_title.
+#html_short_title = None
+
+# The name of an image file (relative to this directory) to place at the top
+# of the sidebar.
+#html_logo = None
+
+# The name of an image file (within the static path) to use as favicon of the
+# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
+# pixels large.
+#html_favicon = None
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+html_static_path = ['_static']
+
+# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
+# using the given strftime format.
+#html_last_updated_fmt = '%b %d, %Y'
+
+# If true, SmartyPants will be used to convert quotes and dashes to
+# typographically correct entities.
+#html_use_smartypants = True
+
+# Custom sidebar templates, maps document names to template names.
+#html_sidebars = {}
+
+# Additional templates that should be rendered to pages, maps page names to
+# template names.
+#html_additional_pages = {}
+
+# If false, no module index is generated.
+#html_domain_indices = True
+
+# If false, no index is generated.
+#html_use_index = True
+
+# If true, the index is split into individual pages for each letter.
+#html_split_index = False
+
+# If true, links to the reST sources are added to the pages.
+#html_show_sourcelink = True
+
+# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
+#html_show_sphinx = True
+
+# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
+#html_show_copyright = True
+
+# If true, an OpenSearch description file will be output, and all pages will
+# contain a <link> tag referring to it. The value of this option must be the
+# base URL from which the finished HTML is served.
+#html_use_opensearch = ''
+
+# This is the file name suffix for HTML files (e.g. ".xhtml").
+#html_file_suffix = None
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'libavgdoc'
+
+
+# -- Options for LaTeX output --------------------------------------------------
+
+# The paper size ('letter' or 'a4').
+#latex_paper_size = 'letter'
+
+# The font size ('10pt', '11pt' or '12pt').
+#latex_font_size = '10pt'
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title, author, documentclass [howto/manual]).
+latex_documents = [
+ ('index', 'libavg.tex', u'libavg Documentation',
+ u'Ulrich von Zadow', 'manual'),
+]
+
+# The name of an image file (relative to this directory) to place at the top of
+# the title page.
+#latex_logo = None
+
+# For "manual" documents, if this is true, then toplevel headings are parts,
+# not chapters.
+#latex_use_parts = False
+
+# If true, show page references after internal links.
+#latex_show_pagerefs = False
+
+# If true, show URL addresses after external links.
+#latex_show_urls = False
+
+# Additional stuff for the LaTeX preamble.
+#latex_preamble = ''
+
+# Documents to append as an appendix to all manuals.
+#latex_appendices = []
+
+# If false, no module index is generated.
+#latex_domain_indices = True
+
+
+# -- Options for manual page output --------------------------------------------
+
+# One entry per manual page. List of tuples
+# (source start file, name, description, authors, manual section).
+man_pages = [
+ ('index', 'libavg', u'libavg Documentation',
+ [u'Ulrich von Zadow'], 1)
+]
+
+inheritance_graph_attrs = dict(rankdir="TB")
diff --git a/sphinxdoc/events.rst b/sphinxdoc/events.rst
new file mode 100644
index 0000000..0db8d97
--- /dev/null
+++ b/sphinxdoc/events.rst
@@ -0,0 +1,428 @@
+Input Handling
+==============
+
+.. automodule:: libavg.avg
+ :no-members:
+
+ .. inheritance-diagram:: Event CursorEvent MouseEvent TouchEvent KeyEvent
+ :parts: 1
+
+ .. inheritance-diagram:: Contact
+ :parts: 1
+
+ .. inheritance-diagram:: InputDevice
+ :parts: 1
+
+ .. autoclass:: Contact
+
+ A Contact encapsulates the information of one touch on an input device from
+ the down event to an up event. It exposes some aggregate information about the
+ touch - distance and direction travelled etc. - and supports event handlers that
+ are only called for this single contact.
+
+ For compatibility reasons, a mouse device also produces contacts. A mouse contact
+ exists from the press of a button to its release. If multiple buttons are
+ pressed without a complete release (e.g. LEFTDOWN-RIGHTDOWN-LEFTUP-RIGHTUP), the
+ mouse contact exists for the complete sequence.
+
+ **Messages:**
+
+ All message parameters are of type :py:class:`CursorEvent`.
+ To get these messages, call :py:meth:`Publisher.subscribe`. All subscribers
+ are unsubscribed automatically after the up event.
+
+ .. py:method:: CURSOR_MOTION(cursorevent)
+
+ Emitted whenever the contact moves.
+
+ .. py:method:: CURSOR_UP(cursorevent)
+
+ Emitted when the mouse button is released or the touch leaves the surface.
+
+ .. py:attribute:: age
+
+ Time that has passed since the down event in milliseconds. Read-only.
+
+ .. py:attribute:: distancefromstart
+
+ Distance of the current position from the initial position in pixels.
+ Read-only.
+
+ .. py:attribute:: distancetravelled
+
+ The total distance travelled since the initial down event. Read-only.
+
+ .. py:attribute:: events
+
+ An array containing all events that this contact has generated in the past.
+ Read-only.
+
+ .. py:attribute:: id
+
+ A numerical id for this contact. This corresponds to the
+ :py:attr:`CursorEvent.cursorid` field. Contacts for touch events have unique
+ ids, while contacts for mouse events always have the :py:attr:`id`
+ :py:const:`-1`. ids are not reused. Read-only.
+
+ .. py:attribute:: motionangle
+
+ Angle of the current position from the initial position in radians. Like all
+ angles in libavg, :py:attr:`motionangle` is 0 on the positive x axis and
+ increases clockwise. Read-only.
+
+ .. py:attribute:: motionvec
+
+ The difference of the current position and the initial position as a
+ :py:class:`Point2D`. Read-only.
+
+ .. py:method:: connectListener(motionCallback, upCallback) -> id
+
+ .. deprecated:: 1.8
+ Use the message interface instead.
+
+ Registers event handlers that get called when CURSORMOTION and CURSORUP
+ events for this :py:class:`Contact` occur. Event handlers can be unregistered
+ using :py:meth:`disconnectListener`. They are automatically unregistered
+ after the up event. The :py:attr:`id` returned is unique for this contact.
+
+ .. py:method:: disconnectListener(id)
+
+ .. deprecated:: 1.8
+ Use the message interface instead.
+
+ Unregisters an event handler. The parameter is the :py:attr:`id` returned in
+ :py:meth:`connectListener`. It is an error to call
+ :py:meth:`disconnectListener` with an invalid id.
+
+ .. autoclass:: CursorEvent
+
+ Base class for all events which contain a position in the global coordinate
+ system.
+
+ .. py:attribute:: contact
+
+ The :py:class:`Contact` that the event belongs to, if there is one.
+ Read-only.
+
+ .. py:attribute:: cursorid
+
+ A numerical identifier for the current cursor.
+
+ .. py:attribute:: node
+
+ The :py:class:`Node` that the event occured in. If this is :py:const:`None`,
+ the event happened outside of the application window and the cursor was
+ captured by the application.
+ Read-only.
+
+ .. py:attribute:: pos
+
+ Position in the global coordinate system. Read-only.
+
+ .. py:attribute:: source
+
+ The type of the device that emitted the event. See :py:attr:`Event.source`.
+ Read-only.
+
+ .. py:attribute:: x
+
+ x position in the global coordinate system. Read-only.
+
+ .. py:attribute:: y
+
+ y position in the global coordinate system. Read-only.
+
+
+ .. autoclass:: Event(type, source, [when])
+
+ Base class for user input events.
+
+ :param type type:
+
+ The type of the event. See :py:attr:`Event.type`.
+
+ :param source source:
+
+ The source of the event. See :py:attr:`Event.source`.
+
+ :param Integer when:
+
+ The time the event occured
+
+ .. py:attribute:: inputdevice
+
+ The address of the device that emitted the event.
+ Read-only
+
+ .. py:attribute:: inputdevicename
+
+ The name of the device that emitted the event.
+ Read-only.
+
+ .. py:attribute:: source
+
+ One of :py:const:`MOUSE`, :py:const:`TOUCH`, :py:const:`TRACK`,
+ :py:const:`CUSTOM` or :py:const:`NONE`. Read-only
+
+ .. py:attribute:: type
+
+ One of :py:const:`KEYUP`, :py:const:`KEYDOWN`, :py:const:`CURSORMOTION`,
+ :py:const:`CURSORUP`, :py:const:`CURSORDOWN`, :py:const:`CURSOROVER`
+ or :py:const:`CURSOROUT`. Read-only.
+
+ .. py:attribute:: when
+
+ The time when the event occured in milliseconds since program start.
+ Read-only.
+
+ .. autoclass:: InputDevice(name, [eventReceiverNode])
+
+ Base class for input devices which feed events to the system. Derived classes can
+ be either user-defined or one of the predefined libavg input devices. User-defined
+ InputDevice objects are registered with the system by calling
+ :py:meth:`Player.addInputDevice`. After this, the emitted
+ events are processed like any other events.
+
+ .. py:attribute:: eventreceivernode
+
+ The :py:class:`DivNode` that the input device will deliver events to. By
+ default, this is the libavg root node. Useful for restricting events to a
+ part of the total canvas or for sending events directly to an offscreen
+ canvas. Event bubbling starts at this node and proceeds down the tree from
+ there. Read-only.
+
+ .. py:attribute:: name
+
+ The name of the device. Read-only.
+
+ .. py:method:: pollEvents() -> list
+
+ Abstract method which returns a list of pending events. Override this method
+ in your derived input device class. After registering
+ the input device, this method gets called on every frame.
+
+ .. py:method:: start()
+
+ Initializes the input device if needed. By default this is an empty method.
+
+ .. autoclass:: KeyEvent
+
+ Generated when a key is pressed or released.
+
+ .. py:attribute:: keycode
+
+ The keycode of the key according to US keyboard layout. Read-only.
+
+ .. py:attribute:: keystring
+
+ A character or word describing the key pressed. Read-only.
+
+ .. py:attribute:: modifiers
+
+ Any modifier keys pressed, or'ed together. Possible Modifiers are
+ :py:const:`KEYMOD_NONE`, :py:const:`KEYMOD_LSHIFT`, :py:const:`KEYMOD_RSHIFT`,
+ :py:const:`KEYMOD_LCTRL`, :py:const:`KEYMOD_RCTRL`, :py:const:`KEYMOD_LALT`,
+ :py:const:`KEYMOD_RALT`, :py:const:`KEYMOD_LMETA`, :py:const:`KEYMOD_RMETA`,
+ :py:const:`KEYMOD_NUM`, :py:const:`KEYMOD_CAPS`, :py:const:`KEYMOD_MODE`.
+ Read-only.
+
+ .. py:attribute:: scancode
+
+ The untranslated (hardware-dependent) scancode of the key pressed.
+ Read-only.
+
+ .. py:attribute:: unicode
+
+ Unicode index of the character. Takes into account the current keyboard
+ layout and any modifiers pressed. This attribute is only filled in the
+ :py:const:`KEYDOWN` event. Read-only.
+
+ .. autoclass:: MouseEvent(type, leftButtonState, middleButtonState, rightButtonState, pos, button, [speed, when])
+
+ Generated when a mouse-related event occurs.
+
+ .. py:attribute:: button
+
+ The button that caused the event. Read-only.
+
+ .. py:attribute:: cursorid
+
+ Always :samp:`-1` for mouse events, but can be used to handle mouse and
+ tracking events in one handler. Read-only.
+
+ .. py:attribute:: leftbuttonstate
+
+ :py:const:`True` if the left mouse button is currently pressed. Read-only.
+
+ .. py:attribute:: middlebuttonstate
+
+ :py:const:`True` if the middle mouse button is currently pressed. Read-only.
+
+ .. py:attribute:: rightbuttonstate
+
+ :py:const:`True` if the right mouse button is currently pressed. Read-only.
+
+ .. py:attribute:: source
+
+ Always :py:const:`MOUSE`. Read-only
+
+ .. py:attribute:: speed
+
+ Current speed of the mouse in pixels per millisecond as a
+ :py:class:`Point2D`. Read-only.
+
+ .. autoclass:: TouchEvent(id, type, pos, source, [speed])
+
+ Generated when a touch or other tracking event occurs. Touch events happen
+ only when a multi-touch sensitive surface or other camera tracker is
+ active.
+
+ .. py:attribute:: area
+
+ Size of the blob found in pixels. Read-only.
+
+ .. py:attribute:: center
+
+ Position as :py:class:`Point2D`, with sub-pixel accuracy. Used for
+ calibration. Read-only.
+
+ .. py:attribute:: cursorid
+
+ An identifier for the current touch. A single touch will generate a down,
+ zero or more motion and a single up event in its lifetime, all with the same
+ :py:attr:`cursorid`.
+
+ .. py:attribute:: eccentricity
+
+ .. py:attribute:: handorientation
+
+ The angle of the hand relative to the finger. :py:attr:`handorientation` is
+ only defined for events with :py:attr:`source`=:py:const:`TOUCH`. If the
+ tracker has detected a hovering hand attached to the finger, this is the
+ actual hand-finger angle. If no hand was detected, the angle is approximated
+ using the position of the touch on the surface. :py:attr:`handorientation`
+ ranges from :py:const:`-pi` to :py:const:`pi`, with 0 being the positive x
+ axis. Angles increase in a clockwise fashion.
+
+ For :py:const:`CURSORUP` events, the angle is always approximated.
+
+ .. py:attribute:: majoraxis
+
+ Major axis of an ellipse that is similar to the blob. Read-only.
+
+ .. py:attribute:: minoraxis
+
+ Minor axis of an ellipse that is similar to the blob. Read-only.
+
+ .. py:attribute:: orientation
+
+ Angle of the blob in radians. For hovering hands, this is roughly the
+ direction of the hand, modulo 180 degrees. Read-only.
+
+ .. py:attribute:: source
+
+ :py:attr:`source` can be either :py:const:`TRACK` or :py:const:`TOUCH`.
+ In most cases, actual touches will generate :py:const:`TOUCH` events. When
+ used with a DI device, the internal tracker also generates :py:const:`TRACK`
+ events for hands above the surface. When used with an FTIR device, the
+ internal tracker generates :py:const:`TRACK` events for the actual touches.
+ Read-only.
+
+ .. py:attribute:: speed
+
+ Current speed of the touch in pixels per millisecond as a
+ :py:class:`Point2D`. Read-only.
+
+ .. py:method:: getContour() -> list
+
+ Returns the contour of the blob as a list of points if supported by the
+ tracker being used.
+
+ .. py:method:: getRelatedEvents() -> events
+
+ Only for DI devices and the internal tracker: Returns a python tuple
+ containing the events 'related' to this one. For :py:const:`TOUCH` events
+ (fingers), the tuple contains one element: the corresponding
+ :py:const:`TRACK` event (hand). For :py:const:`TRACK` events,
+ the tuple contains all :py:const:`TOUCH` events that belong to the same hand.
+
+ .. autoclass:: Tracker
+
+ A class that uses a camera to track moving objects and delivers the movements
+ as avg events. Create a tracker by using :py:meth:`Player.enableMultitouch()` with
+ :samp:`AVG_MULTITOUCH_DRIVER=TRACKER`. The properties of this class are explained
+ under https://www.libavg.de/wiki/ProgrammersGuide/Tracker.
+
+ .. py:method:: abortCalibration()
+
+ Aborts coordinate calibration session and restores the previous
+ coordinate transformer.
+
+ .. py:method:: endCalibration()
+
+ Ends coordinate calibration session and activates the coordinate
+ transformer generated.
+
+ .. py:method:: getDisplayROIPos()
+
+ .. py:method:: getDisplayROISize()
+
+ .. py:method:: getImage(imageid) -> Bitmap
+
+ Returns one of the intermediate images necessary for tracking.
+ These images are only available if setDebugImages was called before
+ with appropriate parameters. Possible :py:attr:`imageid` values are
+ :py:const:`IMG_CAMERA`, :py:const:`IMG_DISTORTED`, :py:const:`IMG_NOHISTORY`,
+ :py:const:`IMG_HISTOGRAM`, :py:const:`IMG_FINGERS` or
+ :py:const:`IMG_HIGHPASS`.
+
+ .. py:method:: getParam(element) -> value
+
+ Returns a tracker configuration parameter.
+
+ .. py:method:: resetHistory()
+
+ Throws away the current history image and generates a new one from
+ the next second of images.
+
+ .. py:method:: saveConfig()
+
+ Saves the current tracker configuration to the default config file.
+
+ .. py:method:: setDebugImages(img, finger)
+
+ Controls whether debug images of intermediate tracking results
+ and detected finger positions are generated and exported to
+ python. Generating the debug images takes a moderate amount of
+ time, so it is turned off by default.
+
+ :param img: Whether to generate intermediate result images.
+ :param finger: Whether to generate the :py:const:`IMG_FINGERS` result image.
+
+ .. py:method:: setParam(element, value)
+
+ Sets one of the tracker configuration parameters.
+
+ .. py:method:: startCalibration(displayextents) -> TrackerCalibrator
+
+ Starts coordinate calibration session. The returned
+ :py:class:`TrackerCalibrator` exists until :py:meth:`endCalibration`
+ or :py:meth:`abortCalibration` is called.
+
+ :param displayextents: The width and height of the display area.
+
+ .. autoclass:: TrackerCalibrator
+
+ Generates a mapping of display points to camera points using a set of reference
+ points. Python code should display reference points that the user must
+ touch to establish a mapping. Created by :py:meth:`Tracker.startCalibration`.
+
+ .. py:method:: getDisplayPoint() -> Point2D
+
+ .. py:method:: nextPoint() -> bool
+
+ Advances to the next point. Returns :py:const:`False` and ends calibration if
+ all points have been set.
+
+ .. py:method:: setCamPoint(pos)
+
diff --git a/sphinxdoc/fx.rst b/sphinxdoc/fx.rst
new file mode 100644
index 0000000..f74efca
--- /dev/null
+++ b/sphinxdoc/fx.rst
@@ -0,0 +1,140 @@
+Effect Nodes
+============
+
+.. automodule:: libavg.avg
+ :no-members:
+
+ .. inheritance-diagram:: BlurFXNode ChromaKeyFXNode HueSatFXNode InvertFXNode NullFXNode ShadowFXNode
+ :parts: 1
+
+ .. autoclass:: BlurFXNode(radius=1.0)
+
+ Blurs the node it is applied to. Corresponds to the Gaussian Blur effect in
+ Photoshop.
+
+ Not supported under minimal shaders. Programs can call
+ :py:meth:`Player.areFullShadersSupported` to ensure support.
+
+ .. py:attribute:: radius
+
+ The width of the blur. This corresponds to the radius parameter of
+ photoshop.
+
+ .. autoclass:: ChromaKeyFXNode
+
+ Chroma keying is the process of removing a uniformly colored background from an
+ image. The background is then replaced with a different image or video.
+ Actors are filmed in front of a blue- or green-colored background and chroma
+ keying is used to insert a different background.
+
+ The :py:class:`ChromaKeyFXNode` implements a high-quality realtime chroma key
+ (greenscreen or bluescreen) effect. It replaces all pixels that are similar to a
+ configured key color with transparency and can account for noise in the
+ background area as well as remove color spill from the background to the
+ foreground. All of the parameters can be manipulated for test purposes using the
+ :program:`avg_chromakey.py` script. The effect is carried out in the HSL
+ colorspace (http://en.wikipedia.org/wiki/HSL_and_HSV).
+
+ Not supported under minimal shaders. Programs can call
+ :py:meth:`Player.areFullShadersSupported` to ensure support.
+
+ .. py:attribute:: color
+
+ The color to key out. Pixels of this and similar colors are made transparent.
+
+ .. py:attribute:: erosion
+
+ Removes single non-keyed-out pixels in larger transparent areas. Values > 1
+ remove larger areas. Useful for removing camera noise.
+
+ .. py:attribute:: htolerance
+
+ Hue tolerance for the key color.
+
+ .. py:attribute:: ltolerance
+
+ Lightness tolerance for the key color.
+
+ .. py:attribute:: softness
+
+ :py:attr:`softness` > 0 causes pixels with a color close to the keyed-out
+ colors to become partially transparent. Greater values increase this effect.
+
+ .. py:attribute:: spillthreshold
+
+ Often, people in greenscreen studios aquire a greenish tint. Spill removal
+ works against this by desaturating pixels that are close to the key color.
+ Larger values cause more desaturation.
+
+ .. py:attribute:: stolerance
+
+ Saturation tolerance for the key color.
+
+ .. autoclass:: FXNode
+
+ Base class for GPU-based effects. These effects can be added to any
+ :py:class:`RasterNode` by calling :py:meth:`RasterNode.setEffect`.
+
+ .. autoclass:: HueSatFXNode(hue=0.0, saturation=0.0, lightness=0.0, colorize=False)
+
+ Color correction filter that works by converting pixels to the hsl color space
+ (http://en.wikipedia.org/wiki/HSL_and_HSV), changing the values there and
+ converting back to rgb. Can be used to change hue,
+ saturation and lightness of a node. Corresponds to the Photoshop Hue/Saturation
+ dialog.
+
+ .. py:attribute:: colorize
+
+ If :py:attr:`colorize` is :py:const:`True`, all colors will be tinted
+ according to the current :py:attr:`hue` value. Otherwise, :py:attr:`hue` is
+ treated as a difference value.
+
+ .. py:attribute:: hue
+
+ Used to get/set the color angle in degrees. Effective values are 0..360 or
+ -180..180, depending on the :py:attr:`colorize` value.
+
+ .. py:attribute:: lightness
+
+ Set :py:attr:`lightness` offset. Adds a per pixel offset in brightness. Values
+ range from -100 to 100, with -100 being very dark and 100 very bright.
+
+ .. py:attribute:: saturation
+
+ Set :py:attr:`saturation` of Node. In :py:attr:`colorize` mode, this is the
+ overall image saturation in the range 0..100, with 0 being greyscale and 100
+ very oversaturated. If :py:attr:`colorize` is false, the attribute is an
+ offset from -100 to 100.
+
+ .. autoclass:: InvertFXNode
+
+ Color Invert Effect. Inverts the brightness of nodes that it is attached to.
+
+ .. autoclass:: NullFXNode
+
+ Do-nothing effect. Exists primarily as aid in debugging libavg.
+
+ .. autoclass:: ShadowFXNode(offset=(0,0), radius=1.0, opacity=1.0, color="FFFFFF")
+
+ Adds a shadow behind the node.
+
+ Not supported under minimal shaders. Programs can call
+ :py:meth:`Player.areFullShadersSupported` to ensure support.
+
+ .. py:attribute:: offset
+
+ An adjustment to the shadow's position behind the node in pixels.
+
+ .. py:attribute:: radius
+
+ The blur radius of the shadow.
+
+ .. py:attribute:: opacity
+
+ The opacity of the shadow.
+
+ .. py:attribute:: color
+
+ The shadow color.
+
+
diff --git a/sphinxdoc/gesture.rst b/sphinxdoc/gesture.rst
new file mode 100644
index 0000000..ddac29b
--- /dev/null
+++ b/sphinxdoc/gesture.rst
@@ -0,0 +1,347 @@
+Gesture Support
+===============
+
+The namespace libavg.gesture exposes a group of configurable gesture recognizers.
+
+.. automodule:: libavg.gesture
+ :no-members:
+
+ .. inheritance-diagram:: DragRecognizer SwipeRecognizer TapRecognizer TransformRecognizer DoubletapRecognizer HoldRecognizer
+ :parts: 1
+
+ .. inheritance-diagram:: Transform
+ :parts: 1
+
+
+ .. autoclass:: DoubletapRecognizer(node, [maxTime=MAX_DOUBLETAP_TIME, maxDist=MAX_TAP_DIST, initialEvent=None, possibleHandler=None, failHandler=None, detectedHandler=None])
+
+ A :py:class:`DoubletapRecognizer` detects doubletaps: Two short touches in quick
+ succession without a large change of the cursor position.
+
+ :param maxTime: The maximum time that each phase of the tap may take.
+
+ :param maxDist: The maximum distance the contact may move in millimeters.
+
+
+ .. autoclass:: DragRecognizer(eventNode, [coordSysNode=None, initialEvent=None, direction=ANY_DIRECTION, directionTolerance=DIRECTION_TOLERANCE, friction=-1, minDragDist=None, possibleHandler=None, failHandler=None, detectedHandler=None, moveHandler=None, upHandler=None, endHandler=None])
+
+ A :py:class:`DragRecognizer` attaches itself to a node's cursor events and
+ delivers higher-level callbacks that can be used to implement dragging or
+ drag-like functionality.
+
+ :py:class:`DragRecognizer` supports inertia after the node is released.
+
+ :param avg.Node coordSysNode:
+
+ Used to determine the coordinate system for the offsets returned by the
+ callbacks. If :py:attr:`coordSysNode` is not given, :py:attr:`eventNode` is
+ used as default. The :py:class:`DragRecognizer` never modifies any nodes
+ itself. :py:attr:`coordSysNode` can be used to separate the node that
+ is the 'handle' for the events from the node that is being moved - for
+ instance, to allow moving a window by dragging the title bar.
+
+ :param direction:
+
+ Can be used to constrain the recognizer to :py:const:`VERTICAL` or
+ :py:const:`HORIZONTAL` drags only. If one of these constants is passed as
+ :py:attr:`direction`, the recognizer invokes :py:meth:`onPossible`
+ when the down event arrives, then determines whether the drag is a
+ predominantly horizontal or vertical drag and invokes either
+ :py:meth:`onDetected` or :py:meth:`onFail` depending on the result.
+
+ :param float directionTolerance:
+
+ A tolerance angle in radians for the detection of horizontal and vertical
+ drags.
+
+ :param avg.Node eventNode:
+
+ The node to attach to. The :py:class:`DragRecognizer` registers an event
+ handler to react to any contacts for this node.
+
+ :param float friction:
+
+ If set, this parameter enables inertia processing. It describes how
+ quickly the drag comes to a stop after the cursor is released.
+
+ :param float minDragDist:
+
+ Minimum distance in mm that the cursor must move for the recognizer to switch
+ from :py:const:`POSSIBLE` to :py:const:`DETECTED`. Default is either 0 (for
+ :py:const:`ANY_DIRECTION` recognizers) or :py:const:`MIN_DRAG_DIST` (for
+ constrained recognizers).
+
+ :param moveHandler:
+
+ A shortcut for
+ :samp:`Recognizer.subscribe(Recognizer.MOTION, moveHandler)`.
+
+ :param upHandler:
+
+ A shortcut for
+ :samp:`Recognizer.subscribe(Recognizer.UP, upHandler)`.
+
+ **Messages:**
+
+ To get these messages, call :py:meth:`Publisher.subscribe`.
+
+ .. py:method:: Recognizer.MOTION(offset)
+
+ Emitted when the drag should cause a position change. This usually happens
+ in response to a :py:const:`CURSORMOTION` event, but may also happen
+ because of inertia.
+
+ :param avg.Point2D offset:
+
+ The current offset from the start of the drag in coordinates relative
+ to the :py:attr:`coordSysNode`'s parent.
+
+ .. py:method:: Recognizer.UP(offset)
+
+ Emitted when the cursor is released. If inertia is enabled, there may be
+ move events after the up event.
+
+ :param avg.Point2D offset:
+
+ The current offset from the start of the drag in coordinates relative
+ to the :py:class:`coordSysNode`'s parent.
+
+ .. py:method:: abort()
+
+ Aborts the present recognized gesture and sliding caused by inertia
+
+
+ .. autoclass:: HoldRecognizer(node, [delay=HOLD_DELAY, maxDist=MAX_TAP_DIST, initialEvent=None, possibleHandler=None, failHandler=None, detectedHandler=None, stopHandler=None])
+
+ A :py:class:`HoldRecognizer` detects if a touch is held for a certain amount of
+ time. Holds are continuous events: the :py:meth:`stopHandler` is called when the
+ contact up event arrives.
+
+ :param delay: The amount of time that has to pass before the hold is recognized.
+
+ :param maxDist: The maximum distance the contact may move in millimeters.
+
+
+ .. autoclass:: Recognizer(node, isContinuous, maxContacts, initialEvent[, possibleHandler=None, failHandler=None, detectedHandler=None, endHandler=None])
+
+ Base class for gesture recognizers that attach to a node's cursor events and
+ emit higher-level events. Gesture recognizers have a standard set of states and
+ callbacks, but derived classes may add their own callbacks and do not need to
+ invoke all base class callbacks. The possible states vary depending on the value
+ of :py:attr:`isContinuous`:
+
+ .. image:: Recognizer.png
+
+ A usage example for the recognizers can be found under
+ :samp:`src/samples/gestures.py`. Many of the recognizers have default timeouts
+ and distance limits which can be changed by modifying :file:`avgrc`. The sample
+ file under :file:`src/avgrc` contains explanations.
+
+ :param Node node: Node to attach to.
+
+ :param bool isContinuous:
+
+ :py:const:`True` if the gesture stays active after it has been detected.
+
+
+ :param maxContacts:
+
+ The maximum number of contacts that the recognizer should handle.
+ :py:const:`None` if there is no maximum.
+
+ :param initialEvent:
+
+ A cursordown event to pass to the recognizer immediately.
+
+ :param possibleHandler:
+
+ A shortcut for
+ :samp:`Recognizer.subscribe(Recognizer.POSSIBLE, possibleHandler)`.
+
+ :param failHandler:
+
+ A shortcut for :samp:`Recognizer.subscribe(Recognizer.FAIL, failHandler)`.
+
+ :param detectedHandler:
+
+ A shortcut for
+ :samp:`Recognizer.subscribe(Recognizer.DETECTED, detectedHandler)`.
+
+ :param endHandler:
+
+ A shortcut for :samp:`Recognizer.subscribe(Recognizer.END, endHandler)`.
+
+ **Messages:**
+
+ Gesture recognizers emit messages whenever they change state - see the state
+ diagrams above. The messages have a parameter of type :py:class:`CursorEvent`.
+
+ To get these messages, call :py:meth:`Publisher.subscribe`.
+
+ .. py:method:: POSSIBLE()
+
+ Emit when gesture recognition begins - usually after a cursordown event.
+ Some continuous gestures (such as unconstrained drags) never emit
+ :py:meth:`POSSIBLE` but emit :py:meth:`DETECTED` immediately.
+
+ .. py:method:: FAILED()
+
+ Emitted when gesture recognition is rejected. For instance, in the case
+ of a :py:class:`DoubleTapRecognizer`, a :py:meth:`FAILED` message is
+ emitted if the touch stays on the surface for too long.
+
+ .. py:method:: DETECTED()
+
+ Emitted when the gesture is recognized. For discrete gestures, this
+ signifies the end of gesture processing.
+
+ .. py:method:: END()
+
+ Emitted when a continuous gesture ends. This is often a result of an
+ up event, but e.g. in the case of inertia, :py:meth:`END` is emitted
+ when movement stops.
+
+ .. py:attribute:: contacts
+
+ List of all contacts detected by the :py:class:`Recognizer`.
+
+ .. py:method:: abort()
+
+ Aborts the present recognized gesture.
+
+ .. py:method:: enable(isEnabled)
+
+ Enables or disables the :py:class:`Recognizer`.
+
+ .. py:method:: getState() -> String
+
+ Returns the state ("IDLE", "POSSIBLE" or "RUNNING") of the recognizer.
+
+
+ .. autoclass:: SwipeRecognizer(node, direction, [numContacts=1, directionTolerance=SWIPE_DIRECTION_TOLERANCE, minDist=MIN_SWIPE_DIST, maxContactDist=MAX_SWIPE_CONTACT_DIST, initialEvent=None, possibleHandler=None, failHandler=None, detectedHandler=None])
+
+ A :py:class:`SwipeRecognizer` detects movement of one or more contacts in a
+ specified direction and with a minimal distance. Whether the gesture is recognized
+ is determined when an up event occurs.
+
+ :param direction:
+
+ One of :py:const:`SwipeRecognizer.UP`, :py:const:`DOWN`, :py:const:`LEFT` or
+ :py:const:`RIGHT`.
+
+ :param numContacts: The minimum number of contacts for the swipe.
+
+ :param directionTolerance:
+
+ Maximum deviation from the ideal direction that the touch(es) may have in
+ radians.
+
+ :param minDist:
+
+ Minimum distance between start position and end position of each contact in
+ millimeters.
+
+ :param maxInterContactDist:
+
+ Maximum distance between the start positions of the different contacts.
+
+
+ .. autoclass:: TapRecognizer(node, [maxTime=MAX_TAP_TIME, maxDist=MAX_TAP_DIST, initialEvent=None, possibleHandler=None, failHandler=None, detectedHandler=None])
+
+ A :py:class:`TapRecognizer` detects short touches without a large change of the
+ cursor position.
+
+ :param maxTime: The maximum time that the tap may take in milliseconds.
+
+ :param maxDist: The maximum distance the contact may move in millimeters.
+
+
+ .. autoclass:: Transform(trans, [rot=0, scale=1, pivot=(0,0)])
+
+ Encapsulates a coordinate transformation and can be used to change the position,
+ rotation and scale of a node.
+
+ .. py:attribute:: pivot
+
+ The point around which rot and scale are applied.
+
+ .. py:attribute:: rot
+
+ Rotation in radians.
+
+ .. py:attribute:: scale
+
+ Multiplies the size of the node.
+
+ .. py:attribute:: trans
+
+ The translation.
+
+ .. py:method:: moveNode(node)
+
+ Changes a :py:attr:`node`'s pos, angle and size by applying the transform.
+
+
+ .. autoclass:: TransformRecognizer(eventNode, [coordSysNode=None, initialEvent=None, friction=-1, detectedHandler=None, moveHandler=None, upHandler=None, endHandler=None])
+
+ A :py:class:`TransformRecognizer` is used to support drag/zoom/rotate
+ functionality. From any number of touches on a node, it calculates an aggregate
+ transform that can be used to change the position, size and angle of a node.
+ The class supports intertia after the node is released.
+
+ :param avg.Node eventNode:
+
+ The node to attach to. The :py:class:`TransformRecognizer` registers an event
+ handler to react to any contacts for this node.
+
+ :param avg.Node coordSysNode:
+
+ Used to determine the coordinate system for the transforms returned by the
+ callbacks. If :py:attr:`coordSysNode` is not given, :py:attr:`eventNode` is
+ used as default. The :py:class:`TransformRecognizer` never modifies any nodes
+ itself. :py:attr:`coordSysNode` can be used to separate the node that
+ is the 'handle' for the events from the node that is being moved - for
+ instance, to allow moving and rotating a window by dragging the title bar.
+
+ :param float friction:
+
+ If set, this parameter enables inertia processing. It describes how
+ quickly the transform comes to a stop after the cursor is released.
+
+ :param moveHandler:
+
+ A shortcut for
+ :samp:`Recognizer.subscribe(Recognizer.MOTION, moveHandler)`.
+
+ :param upHandler:
+
+ A shortcut for
+ :samp:`Recognizer.subscribe(Recognizer.UP, upHandler)`.
+
+ **Messages:**
+
+ To get these messages, call :py:meth:`Publisher.subscribe`.
+
+ .. py:method:: Recognizer.MOTION(transform)
+
+ Emitted whenever the transform changes. This usually happens
+ in response to one or more :py:const:`CURSORMOTION` events, but may also
+ happen because of inertia.
+
+ :param Transform transform:
+
+ The change in transformation since the last call of move or up.
+
+ .. py:method:: Recognizer.UP(transform)
+
+ Called when the last touch is released. If inertia is enabled, there may
+ be move events after the up event.
+
+ :param Transform transform:
+
+ The change in transformation since the last call of move.
+
+ .. py:method:: abort()
+
+ Aborts the present recognized gesture and sliding caused by inertia.
+
diff --git a/sphinxdoc/index.rst b/sphinxdoc/index.rst
new file mode 100644
index 0000000..1611175
--- /dev/null
+++ b/sphinxdoc/index.rst
@@ -0,0 +1,31 @@
+libavg Reference
+================
+
+Welcome to the libavg reference documentation. This documentation describes the syntax
+and semantics of the library. As a reference, it aims to be exact and complete. It is not
+intended to be an informal introduction to libavg - for this, have a look at
+http://www.libavg.de/wiki/ProgrammersGuide.
+
+.. toctree::
+ :maxdepth: 1
+
+ player
+ app
+ basenodes
+ areanodes
+ vectornodes
+ events
+ animation
+ fx
+ gesture
+ widget
+ misc
+
+Indexes and tables
+==================
+
+* :ref:`genindex`
+* :ref:`modindex`
+* :ref:`search`
+
+Generated |today|.
diff --git a/sphinxdoc/misc.rst b/sphinxdoc/misc.rst
new file mode 100644
index 0000000..ed84ccc
--- /dev/null
+++ b/sphinxdoc/misc.rst
@@ -0,0 +1,685 @@
+Misc. Classes
+=============
+
+.. automodule:: libavg.avg
+ :no-members:
+
+ .. autoclass:: Bitmap
+
+ Class representing a rectangular set of pixels in CPU memory. Bitmaps can be
+ obtained from any :py:class:`RasterNode` or loaded from disk. For nodes of type
+ :py:class:`ImageNode`, the current bitmap can be set as well. In general, huge
+ Bitmaps (e.g. width>65536) are supported as long as they fit into memory.
+
+ The layout of the pixels in the bitmap is described by its pixel format.
+ The names for pixel format constants are confusing. They try to follow logic,
+ but it's a bit elusive: In many cases, each component is described by a single
+ letter indicating the component's role in the pixel and a number indicating the
+ number of bits used for this component.
+ Components are named in the order they appear in memory. In the cases where
+ the name doesn't follow this logic, reasons for the name are usually historical or
+ by convention.
+ You can receive a complete list of all supported pixel formats by calling
+ :py:func:`avg.getSupportedPixelFormats()`.
+ The pixel formats are:
+
+ * :py:const:`B5G6R5`: 16 bits per pixel blue, green, red components.
+ * :py:const:`B8G8R8`: 24 bits per pixel blue, green, red components.
+ * :py:const:`B8G8R8A8`: 32 bits per pixel: blue, green, red and an
+ alpha (opacity) component.
+ * :py:const:`B8G8R8X8`: 32 bits per pixel, with the last byte unused.
+ * :py:const:`A8B8G8R8`
+ * :py:const:`X8B8G8R8`
+ * :py:const:`R5G6B5`
+ * :py:const:`R8G8B8`
+ * :py:const:`R8G8B8A8`
+ * :py:const:`R8G8B8X8`
+ * :py:const:`A8R8G8B8`
+ * :py:const:`X8R8G8B8`
+ * :py:const:`I8`: 8 bits of greyscale intensity.
+ * :py:const:`I16`: 16 bits of greyscale intensity.
+ * :py:const:`A8`: 8 bits of transparency information.
+ * :py:const:`YCbCr411`: Interleaved YCbCr: Y Y Cb Y Y Cr.
+ Effectively 12 bits per pixel. Output format of some cameras.
+ * :py:const:`YCbCr422`: Interleaved YCbCr: Cb Y Cr Y.
+ Effectively 16 bits per pixel. Output format of some cameras.
+ * :py:const:`YUYV422`: Like YCbCr422, but grey values come first, so the
+ order is Y Cb Y Cr.
+ * :py:const:`YCbCr420p`: Not a valid pixel format for a single bitmap, but
+ still a description of planar bitmap coding. Signifies separate
+ bitmaps for Y, Cb and Cr components, with Cb and Cr half as big in both x
+ and y dimensions. This is mpeg YCbCr, where the color components have
+ values from 16...235. Used by many video formats, including mpeg.
+ * :py:const:`YCbCrJ420p`: Same as YCbCr420p, but this is the jpeg version
+ with component values in the range 0...255. Used in video as well, for
+ instance in motion jpeg encoding.
+ * :py:const:`YCbCrA420p`: YCbCr420p with an additional alpha (transparency)
+ bitmap at full resolution. Used in flash video with transparency.
+ * :py:const:`BAYER8`: Bayer pattern. This is raw camera sensor data with
+ an unspecified pixel order. The other :py:const:`BAYER_XXX` constants
+ specify differing camera sensor arrangements.
+ * :py:const:`BAYER8_RGGB`
+ * :py:const:`BAYER8_GBRG`
+ * :py:const:`BAYER8_GRBG`
+ * :py:const:`BAYER8_BGGR`
+ * :py:const:`R32G32B32A32F`: 32 bits per channel float RGBA.
+ * :py:const:`I32F`: 32 bits per channel greyscale intensity.
+
+ .. py:method:: __init__(size, pixelFormat, name)
+
+ Creates an uninitialized bitmap of the given size and pixel format.
+ :py:attr:`name` is a name to be used in debug output.
+
+ .. py:method:: __init__(bitmap)
+
+ Creates a copy of an already existing bitmap.
+
+ .. py:method:: __init__(bitmap, tlPos, brPos)
+
+ Returns a rectangle inside an existing bitmap as a new bitmap. Note that the
+ pixels are not copied and write operations will therefore effect the
+ original bitmap as well.
+
+ .. py:method:: __init__(fileName)
+
+ Loads an image file from disk and returns it as bitmap object.
+
+ .. py:method:: blt(srcBmp, pos)
+
+ Copies the pixels of srcBmp into the current bitmap at pos.
+
+ .. py:method:: getAvg() -> float
+
+ Returns the average of all bitmap pixels.
+
+ .. py:method:: getChannelAvg(channel) -> float
+
+ Returns the average of one of the bitmap color channels (red, green or blue).
+ Used for automatic tests.
+
+ .. py:method:: getFormat()
+
+ Returns the bitmap's pixel format.
+
+ .. py:method:: getName() -> string
+
+ .. py:method:: getPixel(pos) -> (r,g,b,a)
+
+ Returns one image pixel as a color tuple. This should only be used
+ for single pixels, as it is very slow.
+
+ .. py:method:: getPixels() -> string
+
+ Returns the raw pixel data in the bitmap as a python string. This
+ method can be used to interface to the python imaging library PIL
+ (http://www.pythonware.com/products/pil/).
+
+ .. py:method:: getResized(newSize) -> Bitmap
+
+ Returns a new bitmap that is a resized version of the original.
+
+ .. py:method:: getSize() -> Point2D
+
+ Returns the size of the image in pixels.
+
+ .. py:method:: getStdDev() -> float
+
+ Returns the standard deviation of all bitmap pixels.
+
+ .. py:method:: save(filename)
+
+ Writes the image to a file. File format is determined using the
+ extension. Supported file types are those supported by gdk-pixbuf. This
+ includes at least png, jpeg, gif, tiff and xpixmaps.
+
+ .. py:method:: setPixels(pixels)
+
+ Changes the raw pixel data in the bitmap. Doesn't change dimensions
+ or pixel format. Can be used to interface to the python imaging
+ library PIL (http://www.pythonware.com/products/pil/).
+
+ :param string pixels: Image data.
+
+ .. py:method:: subtract(otherbitmap) -> bmp
+
+ Subtracts two bitmaps and returns the result. Used mainly to compare
+ test images with the intended results (along with :py:meth:`getAvg` and
+ :py:meth:`getStdDev`).
+
+ .. autoclass:: BitmapManager
+
+ (EXPERIMENTAL) Singleton class that allow an asynchronous load of bitmaps.
+ The instance is accessed by :py:meth:`get`.
+
+ .. py:method:: loadBitmap(fileName, callback, pixelformat=NO_PIXELFORMAT)
+
+ Asynchronously loads a file into a Bitmap. The provided callback is invoked
+ with a Bitmap instance as argument in case of a successful load or with a
+ RuntimeError exception instance in case of failure. The optional parameter
+ :py:attr:`pixelformat` can be used to convert the bitmap to a specific format
+ asynchronously as well.
+
+ .. py:classmethod:: get() -> BitmapManager
+
+ This method gives access to the BitmapManager instance.
+
+ .. py:method:: setNumThreads(numThreads)
+
+ Sets the number of threads used to load bitmaps. The default is a single
+ thread. This should generally be less than the number of logical cores
+ available.
+
+ .. autoclass:: CubicSpline(controlpoints)
+
+ Class that generates a smooth curve between control points using cubic
+ spline-based interpolation. For an introduction on spline interpolation,
+ see http://en.wikipedia.org/wiki/Spline_interpolation.
+
+ :param controlpoints:
+
+ A list of 2D coordinates. The x coordinates must be in increasing order.
+
+ .. py:method:: interpolate(x) -> y
+
+ Takes an x coordinate and delivers a corresponding y coordinate.
+
+
+ .. autoclass:: FontStyle(font="sans", variant="", color="FFFFFF", fontsize=15, indent=0, linespacing=-1, alignment="left", wrapmode="word", justify=False, letterspacing=0, aagamma=1, hint=True)
+
+ A :py:class:`FontStyle` object encapsulates all configurable font attributes in a
+ :py:class:`WordsNode`. It provides a way to set all relevant attributes
+ (:py:attr:`font`, :py:attr:`fontsize`, etc.) in one line of code. The attributes
+ correspond to the :py:class:`WordsNode` attributes; refer to the
+ :py:class:`WordsNode` reference for descriptions.
+
+
+ .. autoclass:: Logger
+
+ An python interface to libavg's logger.
+ It can be accessed as follows:
+
+ .. code-block:: python
+
+ import libavg
+ libavg.logger
+
+
+
+ **Logging**
+
+ .. py:method:: log(message, category, severity)
+
+ Logs a message if category is active or severity is at least
+ :py:const:`ERROR`.
+
+ :param category:
+
+ One of the categories listed or a custom category. Defaults to
+ :py:const:`Logger.Category.APP`.
+
+ :param severity:
+ One of the severities listed. Defaults to :py:const:`Logger.Severity.INFO`.
+
+ :param message: The log message string.
+
+ .. py:method:: critical(msg, category)
+
+ Shortcut to :py:meth:`log` with **severity=** :py:const:`Logger.Severity.CRIT`.
+
+ .. py:method:: error(msg, category)
+
+ Shortcut to :py:meth:`log` with **severity=** :py:const:`Logger.Severity.ERR`.
+
+ .. py:method:: warning(msg, category)
+
+ Shortcut to :py:meth:`log` with **severity=** :py:const:`Logger.Severity.WARN`.
+
+ .. py:method:: info(msg, category)
+
+ Shortcut to :py:meth:`log` with **severity=** :py:const:`Logger.Severity.INFO`.
+
+ .. py:method:: debug(msg, category)
+
+ Shortcut to :py:meth:`log` with **severity=** :py:const:`Logger.Severity.DBG`.
+
+ **Configuration**
+
+ .. py:method:: addSink(logger)
+
+ Add a python logger object to libavg's logging handlers.
+ The python logger gets the key `category` as an "extra" kwarg, useful for
+ formatting the output.
+
+ .. py:method:: removeSink(logger)
+
+ Remove a previously added logger. It will not receive any messages dispatched
+ by the logger annymore. It's safe to call the function even if the logger is
+ not present.
+
+ .. py:method:: removeStdLogSink()
+
+ Remove libavg console printing sink.
+
+ Setting :envvar:`AVG_LOG_OMIT_STDERR` as EnvironmentVar has the same effect.
+
+ .. py:method:: configureCategory(category, severity)
+
+ Assign a severity to a given category.
+ category is either a custom string or a :py:const:`Logger.Category`
+ severity has to be one of :py:const:`Logger.Severity`, or it will default to
+ :py:const:`Logger.Severity.None`
+
+ .. py:method:: getCategories()
+
+ Returns a dict with **category** as key and **severity** as value
+
+
+ The Logger can also be configured using :envvar:`AVG_LOG_CATEGORIES` with
+ the format:
+
+ .. code-block:: bash
+
+ CATEGORY[:SEVERITY] [CATEGORY[:SEVERITY]]...
+
+ Thus it is possible to set a severity level for every category.
+ If no severity is given, the default severity is used.
+ (refer to: :py:meth:`setDefaultSeverity`)
+ If the category does not exist, it will be created.
+
+ .. code-block:: bash
+
+ export AVG_LOG_CATEGORIES="CONFIG:INFO APP:DBG PROFILE:DBG MEMORY"
+
+ Default categories are :py:const:`NONE`, :py:const:`APP` and
+ :py:const:`DEPREC`. They are set to the defaultSeverity.
+
+
+
+ **Categories:**
+
+ :py:const:`APP`
+ Reserved for application-level messages issued by python code.
+ :py:const:`CONFIG`
+ Outputs configuration data.
+ :py:const:`DEPREC`
+ Deprecation
+ Messages that warn of functionality that will be removed from libavg
+ in the future.
+ :py:const:`EVENTS`
+ Outputs basic event data.
+ :py:const:`MEMORY`
+ Outputs open/close information whenever a media file is accessed.
+ :py:const:`NONE`
+ Outputs everything that has not been categorized.
+ :py:const:`PROFILE`
+ Outputs performance statistics on player termination.
+ :py:const:`PROFILE_V`
+ Outputs performance statistics for video decoding.
+ :py:const:`PLUGIN`
+ Messages generated by loading plugins.
+ :py:const:`PLAYER`
+ General libavg playback messages.
+ :py:const:`SHADER`
+ Shader compiler messages.
+
+ **Severities**
+
+ :py:const:`CRIT` Critical
+
+ :py:const:`ERR` Error
+
+ :py:const:`WARN` Warning
+
+ :py:const:`INFO` Info
+
+ :py:const:`DBG` Debug
+
+ :py:const:`NONE` None
+
+
+ .. autoclass:: Point2D([x,y=(0,0)])
+
+ A point in 2D space. Supports most arithmetic operations on vectors. The
+ operators :py:attr:`+`, :py:attr:`-`, :py:attr:`==` and :py:attr:`\!=` are
+ defined for two :py:class:`Point2D` parameters. Unary :py:attr:`-` (negation)
+ is defined as well. :py:class:`Point2D` objects can also be multiplied and
+ divided by a scalar.
+
+ :py:class:`Point2D` implicitly converts from and to 2-element float tuples and
+ lists, so in most cases you can use one of these types whenever a point is needed.
+
+ .. py:attribute:: x
+
+ .. py:attribute:: y
+
+ .. py:method:: getAngle() -> float
+
+ Returns the direction of the vector as an angle between pi and -pi, with
+ 0 being the positive x axis. Angles run clockwise.
+
+ .. py:method:: getNorm() -> float
+
+ Returns the euclidian norm of the point, that is sqrt(x*x+y*y).
+
+ .. py:method:: getNormalized() -> Point2D
+
+ Returns a normalized version of the point with the same angle but a
+ norm of one. Throws an exception if called on Point2D(0,0).
+
+ .. py:method:: getRotated(angle) -> Point2D
+
+ Return the position of point rotated around the origin.
+
+ .. py:method:: getRotated(angle, pivot) -> Point2D
+
+ Return the position of point rotated around :py:attr:`pivot`.
+
+ .. py:classmethod:: fromPolar(angle, radius) -> Point2D
+
+ Converts polar to cartesian coordinates. :py:attr:`angle` is in radians with 0
+ being the positive x axis. Angle is clockwise (assuming that y points
+ downward).
+
+
+ .. autoclass:: SVG(filename, [unescapeIllustratorIDs=False])
+
+ :py:class:`SVG` objects load and parse an svg file and render images from it.
+ svg (*Scalable Vector Graphics*, see http://en.wikipedia.org/wiki/Svg) files are
+ xml-based and contain two-dimensional vector graphics. They can be created with
+ editors such as Adobe Illustrator and Inkscape. :py:class:`SVG` objects can render
+ elements in the file to bitmaps and create image nodes from elements in the file.
+ Since the files contain vector graphics, the elements can be scaled to any size
+ when rendering without loss of resolution.
+
+ :param filename: The name of the file to load.
+
+ :param unescapeIllustratorIDs:
+
+ If this is :py:const:`True`, the file is assumed to be generated by Adobe
+ Illustrator. Illustrator mangles element names to create IDs in the svg file.
+ Setting this parameter to :py:const:`True` allows these element names to be
+ passed as IDs.
+
+ .. py:method:: renderElement(elementID, [size | scale=1]) -> Bitmap
+
+ Renders an element to a :py:class:`Bitmap`. Either :py:attr:`scale` or
+ :py:attr:`size` may be given. :py:attr:`size` is the size of the bitmap.
+ :py:attr:`scale` is a factor to scale the native bitmap size with.
+
+ .. py:method:: createImageNode(elementID, nodeAttrs, [size | scale=1]) -> Node
+
+ Convenience method that calls :py:meth:`renderElement` to render a bitmap
+ and then creates an image node that displays that bitmap. :py:attr:`nodeAttrs`
+ is a dictionary containing constructor parameters for the node.
+
+ .. py:method:: getElementPos(elementID) -> Point2D
+
+ Returns the position of an element.
+
+ .. py:method:: getElementSize(elementID) -> Point2D
+
+ Returns the original size of an element.
+
+
+ .. autoclass:: TestHelper
+
+ Miscellaneous routines used by tests. Not intended for normal application usage.
+
+
+ .. autoclass:: VersionInfo
+
+ Exposes version data, including the specs of the builder.
+
+ .. py:attribute:: full
+
+ Full string containing a compact form of branch and revision number (if the
+ build doesn't come from an exported tree)
+
+ .. py:attribute:: release
+
+ String representation in the form `major.minor.micro`
+
+ .. py:attribute:: major
+
+ Integer component of the release version (major)
+
+ .. py:attribute:: minor
+
+ Integer component of the release version (minor)
+
+ .. py:attribute:: micro
+
+ Integer component of the release version (micro)
+
+ .. py:attribute:: revision
+
+ Revision number, if applicable, or 0
+
+ .. py:attribute:: branchurl
+
+ Full URL path that represents the branch root, if applicable, or empty string
+
+ .. py:attribute:: builder
+
+ String representation in the form of `user@hostname machinespecs`
+
+ .. py:attribute:: buildtime
+
+ ISO timestamp representation of the build
+
+
+ .. autoclass:: VideoWriter(canvas, filename, [framerate=30, qmin=3, qmax=5, synctoplayback=True])
+
+ Class that writes the contents of a canvas to disk as a video file. The videos
+ are written as motion jpeg-encoded mov files. Writing commences immediately upon
+ object construction and continues until :py:meth:`stop` is called.
+ :py:meth:`pause` and :py:meth:`play` can be used to pause and resume writing.
+
+ The VideoWriter is built for high performance: Opening, writing and closing the
+ video file is asynchronous to normal playback. Writing full HD videos of
+ offscreen canvasses to disk should cost virtually no time on the main thread of
+ execution for an Intel Core-class processor with a graphics card that supports
+ shaders.
+
+ :param canvas:
+
+ A libavg canvas used as source of the video.
+
+ .. py:attribute:: filename
+
+ The name of the file to write to. Read-only.
+
+ .. py:attribute:: framerate
+
+ The speed of the encoded video in frames per second. This is used for two
+ purposes. First, it determines the nominal playback speed of the video that is
+ encoded in the file. Second, if :py:attr:`synctoplayback` is
+ :py:const:`False`, the :py:class:`VideoWriter` will also use the
+ :py:attr:`framerate` value as the actual number of frames per second to
+ write. Read-only.
+
+ .. py:attribute:: qmin
+
+ .. py:attribute:: qmax
+
+ :py:attr:`qmin` and :py:attr:`qmax` specify the minimum and maximum encoding
+ quality to use. :samp:`qmin = qmax = 1` give maximum quality at maximum file
+ size. :samp:`qmin=3` and :samp:`qmax=5` (the default) give a good quality and
+ a smaller file. Read-only.
+
+ .. py:attribute:: synctoplayback
+
+ If :py:attr:`synctoplayback` is :py:const:`True` (the default), each frame
+ played back in the canvas will be written to disk. This makes a lot of sense
+ in combination with :py:meth:`Canvas.registerCameraNode()`. If not,
+ :py:attr:`framerate` is used to determine which frames to write to disk. For
+ instance, if :py:attr:`synctoplayback` is :py:const:`False`,
+ :py:attr:`framerate` is 25 and the player is running at 60 fps, one movie
+ frame will be written for each 2.5 frames of playback. The actual, not the
+ nominal playback speed is used in this case. Read-only.
+
+ .. py:method:: pause()
+
+ Temporarily stops recording.
+
+ .. py:method:: play()
+
+ Resumes recording after a call to :py:meth:`pause`. :py:meth:`play` doesn't
+ need to be called after construction of the :py:class:`VideoWriter` - writing
+ commences immediately.
+
+ .. py:method:: stop()
+
+ Ends the recording and writes the rest of the file to disk. Note that this is
+ asynchronous to normal playback. If you need to immediately re-open the
+ video file (e.g. for playback in a video node), destroy the python object
+ first. This waits for sync.
+
+ .. autofunction:: getMemoryUsage() -> int
+
+ Returns the amount of memory used by the application in bytes. More
+ precisely, this function returns the resident set size of the process
+ in bytes. This does not include shared libraries or memory paged out to
+ disk.
+
+ .. autofunction:: pointInPolygon(point, poly) -> bool
+
+ Checks if a point is inside a polygon.
+
+ :param Point2D point: Point to check.
+ :param poly: List of points which constitute a polygon to check against.
+ :returns: :py:const:`True` if point is inside, :py:const:`False` otherwise.
+
+ .. autofunction:: validateXml(xmlString, schemaString, xmlName, schemaName)
+
+ Validates an xml string using a schema. Throws an exception if the xml doesn't
+ conform to the schema.
+
+
+.. automodule:: libavg.statemachine
+ :no-members:
+
+ .. autoclass:: StateMachine(name, startState)
+
+ A generic state machine, useful for user interface and other states. Consists of
+ a set of states (represented by strings) and possible transitions between the
+ states. The :py:class:`StateMachine` can be configured to invoke callbacks at
+ specific transitions and when entering or leaving a state. All callbacks are
+ optional. State changes can be logged for debugging purposes.
+
+ State machines are initialized by calling :py:meth:`addState` for each
+ possible state after constructing it.
+
+ :param String name:
+
+ A name for the state machine to be used in debugging output.
+
+ :param String startState:
+
+ .. py:attribute:: state
+
+ The current state the :py:class:`StateMachine` is in. States are strings.
+
+ .. py:method:: addState(state, transitions, [enterFunc=None, leaveFunc=None])
+
+ Adds a state to the :py:class:`StateMachine`. Must be called before the first
+ changeState.
+
+ :param String state: The name of the state to add.
+ :param transitions:
+
+ This parameter can be either a list of destination states or a dict of
+ destinationState: callable pairs. The callables are invoked whenever the
+ corresponding state change happens. If :py:meth:`transitions` is a list,
+ no state change callbacks are registered.
+
+ :param enterFunc: A callable to invoke whenever the state is entered.
+ :param leaveFunc: A callable to invoke whenever the state is left.
+
+ .. py:method:: changeState(newState)
+
+ Changes the state. This includes calling the leave callback for the current
+ state, actually changing the state, calling the transition callback and
+ calling the enter callback for the new state.
+
+ Raises a :py:class:`RuntimeError` if :py:attr:`newState` is not a valid state
+ or if there is no transition defined from the current state to
+ :py:attr:`newState`.
+
+ .. py:method:: dump()
+
+ Prints all states and transitions to the console.
+
+ .. py:method:: makeDiagram(imageFName, [showMethods=False])
+
+ Dumps a graph of the state machine to an image file using dot. graphviz must
+ be installed and in the path for this to work. Very useful for debugging. If
+ :py:attr:`showMethods` is true, names of enter, leave and transition
+ methods are included in the diagram.
+
+ .. py:method:: traceChanges(trace)
+
+ If :py:attr:`trace` is set to :py:const:`True`, all state changes are dumped
+ to the console.
+
+
+.. automodule:: libavg.persist
+ :no-members:
+
+ .. autoclass:: Persist(storeFile, initialData[, validator=lambda v: True, autoCommit=False])
+
+ A general purpose persistent object.
+ Its state is defined in the :py:attr:`data` attribute and pickled
+ from/to a store file.
+
+
+ :param string storeFile:
+
+ Full path of the store file that is used to store and retrieve a
+ serialized version of the data.
+
+ :param initialData:
+
+ A pickle-able object that is assigned to the :py:attr:`data` attribute
+ when no file store exists or when the store file is corrupted.
+
+ :param callable validator:
+
+ An optional callable that receives the object state as soon it's
+ de-pickled from the store file. If the validator call doesn't return True,
+ the object state is restored to the provided `initialData`.
+
+ :param bool autoCommit:
+
+ If True, the :py:attr:`commit` method is registered as an `atexit` function.
+
+ .. py:attribute:: data
+
+ State of the persistent object.
+
+ .. py:attribute:: storeFile
+
+ Returns the full path of the store file.
+
+ .. py:method:: commit()
+
+ Dumps the contents of the :py:attr:`data` attribute to the store file.
+
+
+ .. autoclass:: UserPersistentData(appName, fileName, initialData[, validator=lambda v: True, autoCommit=False])
+
+ A :py:class:`Persist` subclass that sets up an OS-independent path for
+ the store file.
+ Under posix-compliant OSes is `$HOME/.avg/<appName>/<fileName>.pkl`
+ Under Windows is `%APPDATA%\Avg\<appName>/<fileName>.pkl`
+
+ :param string appName:
+
+ Name of the application. This string is used to compose the full path to
+ the file store and it creates a namespace (directory) for multiple files
+ for the same application.
+
+ :param string fileName:
+
+ Name of the file store file. `.pkl` will be added as extension.
+
diff --git a/sphinxdoc/player.rst b/sphinxdoc/player.rst
new file mode 100644
index 0000000..ba9115e
--- /dev/null
+++ b/sphinxdoc/player.rst
@@ -0,0 +1,629 @@
+Player & Canvas
+===============
+
+.. automodule:: libavg.avg
+ :no-members:
+
+ .. inheritance-diagram:: OffscreenCanvas
+ :parts: 1
+
+ .. inheritance-diagram:: Player
+ :parts: 1
+
+ This section describes the classes that provide a framework for rendering. The
+ :py:class:`Player` class is an interface to the avg renderer. The
+ :py:class:`Canvas` class and its descendant :py:class:`OffscreenCanvas` provide
+ areas to draw on.
+
+ .. autoclass:: Canvas
+
+ A Canvas is a tree of nodes. It is the place where a scenegraph is displayed. In
+ a libavg session, there is one main canvas that corresponds to the screen (which
+ is of class :py:class:`Canvas`) and zero or more canvases that are rendered
+ offscreen (which are of class :py:class:`OffscreenCanvas`).
+
+ .. py:method:: getElementByID(id) -> Node
+
+ Returns the element in the canvas's tree that has the :py:attr:`id`
+ given.
+
+ .. py:method:: screenshot() -> Bitmap
+
+ Returns the image the canvas has last rendered as :py:class:`Bitmap`. For
+ the main canvas, this is a real screenshot. For offscreen canvases, this
+ is the image rendered offscreen.
+
+ .. py:method:: getRootNode() -> CanvasNode
+
+ Returns the root of the scenegraph. For the main canvas, this is an
+ :py:class:`AVGNode`. For an offscreen canvas, this is a
+ :py:class:`CanvasNode`.
+
+ .. autoclass:: OffscreenCanvas
+
+ An OffscreenCanvas is a Canvas that is rendered to a texture. It can be
+ referenced in the href attribute of an image node. See
+ https://www.libavg.de/wiki/ProgrammersGuide/OffscreenRendering for an in-depth
+ explanation of using offscreen rendering. Offscreen canvases are created by
+ calling :py:meth:`Player.createCanvas`, :py:meth:`Player.loadCanvasFile` or
+ :py:meth:`Player.loadCanvasString`.
+
+ .. py:attribute:: autorender
+
+ Turns autorendering on or off. Default is :py:const:`True`.
+
+ .. py:attribute:: handleevents
+
+ :py:const:`True` if events that arrive at an image node that is displaying
+ this canvas are routed to the offscreen canvas. Read-only.
+
+ .. py:attribute:: mipmap
+
+ :py:const:`True` if mipmaps are generated and used for the canvas. This is
+ used instead of RasterNode.mipmap for images that render the canvas.
+ Read-only.
+
+ .. py:attribute:: multisamplesamples
+
+ Number of samples per pixel to use for multisampling. Setting this to
+ 1 disables multisampling. Read-only.
+
+ .. py:method:: getID() -> string
+
+ Returns the id of the canvas. This is the same as
+ calling :samp:`canvas.getRootNode().getID()`.
+
+ .. py:method:: getNumDependentCanvases
+
+ Returns the number of canvases that reference this canvas. Used mainly
+ for unit tests.
+
+ .. py:method:: registerCameraNode
+
+ .. py:method:: render()
+
+ Forces an immediate redraw of the offscreen canvas. This makes sure that
+ following calls to screenshot() get a current version of the canvas and
+ is usually used in combination with :samp:`autorender=False`.
+
+ .. py:method:: unregisterCameraNode
+
+ .. py:classmethod:: isMultisampleSupported() -> bool
+
+ :py:const:`True` if the machine's OpenGL implementation supports offscreen
+ multisampling.
+
+ .. autoclass:: Player
+
+ The class used to load and play avg files and the main interface to the avg
+ renderer. Player is a singleton. There is only one instance, accessed by
+ :py:attr:`avg.player`.
+
+ **Messages:**
+
+ To get these messages, call :py:meth:`Publisher.subscribe`.
+
+ .. py:method:: KEY_DOWN(keyEvent)
+
+ Called whenever a key is pressed.
+
+ .. py:method:: KEY_UP(keyEvent)
+
+ Called whenever a key is released.
+
+ .. py:method:: ON_FRAME()
+
+ Called each frame.
+
+ .. py:attribute:: pluginPath
+
+ A list of directories where the player searches for plugins when
+ :py:meth:`loadPlugin()` is called. The separator between path entries is a
+ semicolon (';') under Windows and a colon (':') under Mac and Linux.
+
+ .. py:attribute:: volume
+
+ Total audio playback volume. 0 is silence, 1 passes media file
+ volume through unchanged. Values higher than 1 can be used to
+ amplify playback. A limiter prevents distortion when the volume
+ is set too high.
+
+ .. py:method:: addInputDevice(inputDevice)
+
+ Registers an :py:class:`InputDevice` with the system.
+
+ .. py:method:: areFullShadersSupported() -> bool
+
+ Returns :py:const:`True` if the current OpenGL configuration has full shader
+ support. Platforms without full shader support (this includes OpenGL ES) disable
+ several :py:class:`FXNode` types. Calling this when playback is not running is
+ an error.
+
+ .. py:method:: assumePixelsPerMM(ppmm)
+
+ Tells the system to assume a resolution for the physical screen, overriding
+ operating system information. The parameter is the number of pixels per
+ millimeter as a :samp:`float`. This function affects the values returned by
+ :py:meth:`getPhysicalScreenDimensions` and :py:meth:`getPixelsPerMM`. It is
+ useful for situations in which the OS cannot know the resolution (e.g.
+ projectors) and when the automatic functions return wrong values (which
+ happens, unfortunately, because of operating system deficiencies).
+
+ .. py:method:: callFromThread(pyfunc)
+
+ Executes :py:attr:`pyfunc` in the main thread of execution, in the next event
+ handling phase. This method is the only libavg method that is thread-safe and
+ can be called from secondary threads of execution. :py:attr:`pyfunc` can be
+ any python callable, including any libavg methods.
+
+ .. py:method:: clearInterval(id) -> bool
+
+ Stops a timeout, an interval or an onFrameHandler from being called.
+ Returns :py:const:`True` if there was an interval with the given
+ :py:attr:`id`, :py:const:`False` if not.
+
+ :param int id:
+
+ An id returned by :py:meth:`setInterval`, :py:meth:`setTimeout`
+ or :py:meth:`setOnFrameHandler`.
+
+ .. py:method:: createCanvas(*params) -> OffscreenCanvas
+
+ Creates an empty offscreen canvas. Parameters are given under
+ :py:class:`OffscreenCanvas`.
+
+ .. py:method:: createMainCanvas(*params) -> Canvas
+
+ Creates an empty canvas with a render window and an AVGNode as root node.
+ Parameters are given under :py:class:`AVGNode`.
+
+ .. py:method:: createNode(xml) -> Node
+
+ Creates a new Node. This node can be used as parameter to
+ :py:meth:`DivNode.appendChild()` and :py:meth:`DivNode.insertChild()`.
+ This method will create any type of node, including :samp:`<div>` nodes
+ with children.
+
+ :param xml:
+
+ xml string conforming to the avg dtd that specifies the node to create.
+
+ .. py:method:: createNode(type, args) -> Node
+
+ Creates a new Node. This node can be used as parameter to
+ :py:meth:`DivNode.appendChild()` and :py:meth:`DivNode.insertChild()`.
+ This method will only create one node at a time.
+
+ :param string type:
+
+ Type string of the node to create (For example, :samp:`image` and
+ :samp:`words` are valid type strings).
+
+ :param dict args: a dictionary specifying attributes of the node.
+
+ .. py:method:: deleteCanvas(id)
+
+ Removes the canvas given by id from the player's internal list of
+ canvases. It is an error to delete a canvas that is still referenced by
+ an image node.
+
+ .. py:method:: enableGLErrorChecks(enable)
+
+ Enables or disables checking for errors after each OpenGL call. By default,
+ this is :py:const:`False`, since it hurts performance in some setups. It is
+ enabled by the tests. You do not need this method unless you are looking for
+ errors inside libavg.
+
+ .. py:method:: enableMouse(enable)
+
+ Enables or disable mouse event handling.
+
+ .. py:method:: enableMultitouch()
+
+ Enables multitouch event handling. Several drivers are available that
+ generate multitouch events. To choose a driver, set the environment
+ variable :envvar:`AVG_MULTITOUCH_DRIVER` to the appropriate value:
+
+ :samp:`TUIO`:
+ Listens for TUIO events from a tracker that conforms to the TUIO
+ protocol (http://www.tuio.org), a de-facto standard for multitouch
+ events. By default, it listens to events on the default TUIO UDP port
+ 3333, but this can be configured using the environment variable
+ :envvar:`AVG_TUIO_PORT`.
+
+ :samp:`APPLETRACKPAD`:
+ Uses the trackpad built into Mac Book Pros to generate events.
+
+ :samp:`LINUXMTDEV`:
+ Uses the linux mtdev library to interface to multitouch devices.
+ The environment variable :envvar:`AVG_LINUX_MULTITOUCH_DEVICE` is used
+ to determine which device file to open. Default is
+ :samp:`/dev/input/event3`.
+
+ :samp:`TRACKER`:
+ Enables the internal camera-based tracker. Configuring this tracker is
+ described under https://www.libavg.de/wiki/ProgrammersGuide/Tracker.
+
+ :samp:`WIN7TOUCH`:
+ Enables handling of Windows 7 touch events. This works with all devices
+ which have Windows 7 drivers.
+
+ :samp:`XINPUT`:
+ Uses X11-based multitouch detection. This needs X11 with XInput >= 2.1
+ support. For backwards compatibility reasons, XINPUT21 is supported as
+ value as well.
+
+ If :envvar:`AVG_MULTITOUCH_DRIVER` is not set, the driver defaults to
+ a plattform-specific one. Under Linux, the default is :samp:`XINPUT` if
+ XInput multitouch is supported on the system, otherwise :samp:`LINUXMTDEV`.
+ Under Windows, the default is :samp:`WIN7TOUCH`.
+
+ :py:meth:`enableMultitouch` throws an exception if the chosen driver is not
+ available or no multitouch device could be found. (Exception: Since there is
+ no way to determine if a TUIO device is available, :py:meth:`enableMultitouch`
+ always appears to succeed in this case.)
+
+ .. py:method:: getCanvas(id) -> OffscreenCanvas
+
+ Returns the offscreen canvas with the :py:attr:`id` given.
+
+ .. py:method:: getCurrentEvent() -> Event
+
+ Must be called inside an event handler and returns the event that's being
+ processed. Throws an exception if called outside an event handler.
+
+ .. py:method:: getEffectiveFramerate() -> float
+
+ Returns the framerate that the player is actually achieving. The
+ value returned is not averaged and reflects only the current frame.
+
+ .. py:method:: getElementByID(id) -> Node
+
+ Returns an element in the main avg tree.
+
+ :param id: id attribute of the node to return.
+
+ .. py:method:: getEventHook() -> pyfunc
+
+ Returns the last event hook set using :py:meth:`setEventHook`.
+
+ .. py:method:: getFrameDuration() -> float
+
+ Returns the number of milliseconds that have elapsed since the last
+ frame (i.e. the last display update).
+
+ .. py:method:: getFramerate() -> float
+
+ Returns the current target framerate in frames per second. To get the
+ actual framerate that the player is currently achieving, call
+ :py:meth:`getEffectiveFramerate`.
+
+ .. py:method:: getFrameTime() -> int
+
+ Returns the number of milliseconds that have elapsed since playback
+ has started. Honors FakeFPS. The time returned stays constant for an
+ entire frame; it is the time of the last display update.
+
+ .. py:method:: getKeyModifierState() -> KeyModifier
+
+ Returns the current modifier keys pressed, or'ed together. For a list of
+ possible values, see :py:attr:`KeyEvent.modifiers`.
+
+ .. py:method:: getMainCanvas() -> Canvas
+
+ Returns the main canvas. This is the canvas loaded using :py:meth:`loadFile`
+ or :py:meth:`loadString` and displayed on screen.
+
+ .. py:method:: getMouseState() -> MouseEvent
+
+ Returns the last mouse event generated.
+
+ .. py:method:: getPhysicalScreenDimensions() -> Point2D
+
+ Returns the size of the primary screen in millimeters.
+
+ .. py:method:: getPixelsPerMM() -> float
+
+ Returns the number of dots per millimeter of the primary display. Assumes
+ square pixels.
+
+ .. py:method:: getRootNode() -> Node
+
+ Returns the outermost element in the main avg tree.
+
+ .. py:method:: getScreenResolution() -> Point2D
+
+ Returns the size in pixels of the current screen.
+
+ .. py:method:: getTestHelper
+
+ .. py:method:: getTracker() -> Tracker
+
+ Returns a tracker previously created using :py:meth:`enableMultitouch` with
+ the internal tracker configured.
+
+ .. py:method:: getVideoMemInstalled() -> int
+
+ Returns the amount of dedicated video memory installed in the system in
+ bytes (which might be zero in case of shared-memory graphics cards).
+ Only available when using NVidia drivers.
+
+ .. py:method:: getVideoMemUsed() -> int
+
+ Returns the amount of dedicated video memory used in bytes. This
+ is the total amount used by all programs. Only available when using NVidia
+ drivers.
+
+ .. py:method:: getVideoRefreshRate() -> float
+
+ Returns the current hardware video refresh rate in number of
+ refreshes per second.
+
+ .. py:method:: isCursorShown()
+
+ Returns :py:const:`True` if the mouse cursor is visible.
+
+ .. py:method:: isFullscreen()
+
+ Returns :py:const:`True` if the player is running in fullscreen mode.
+
+ .. py:method:: isMultitouchAvailable() -> bool
+
+ Returns :py:const:`True` if a multitouch device has been configured and is
+ active, :py:const:`False` if not. Must be called after :py:meth:`play()`.
+
+ .. py:method:: isPlaying() -> bool
+
+ Returns :py:const:`True` if :py:meth:`play()` is currently executing,
+ :py:const:`False` if not.
+
+ .. py:method:: keepWindowOpen()
+
+ Tells the player to keep the playback window open after :py:meth:`play()`
+ has returned. This makes it possible to reuse the window with another scene
+ and :py:meth:`play()` call. It is used by the tests to keep flickering to a
+ minimum and increase speed.
+
+ .. py:method:: loadCanvasFile(filename) -> OffscreenCanvas
+
+ Loads the canvas file specified in filename and adds it to the
+ registered offscreen canvases.
+
+ .. py:method:: loadCanvasString(avgString) -> OffscreenCanvas
+
+ Parses avgString, loads the nodes it contains and adds the hierarchy
+ to the registered offscreen canvases.
+
+ :param string avgString: An xml string containing an avg node hierarchy.
+
+ .. py:method:: loadFile(filename) -> Canvas
+
+ Loads the avg file specified in filename. Returns the canvas loaded.
+ The canvas is the main canvas displayed onscreen.
+
+ .. py:method:: loadPlugin(name)
+
+ Load a Plugin.
+
+ :param string name: filename of the plugin without directory and
+ file extension.
+
+ .. py:method:: loadString(avgString) -> Canvas
+
+ Parses avgString and loads the nodes it contains. Returns the canvas
+ loaded. The canvas is the main canvas displayed onscreen.
+
+ :param string avgString: An xml string containing an avg node hierarchy.
+
+ .. py:method:: play()
+
+ Opens a playback window or screen and starts playback. play returns
+ when playback has ended.
+
+ .. py:method:: screenshot() -> Bitmap
+
+ Returns the contents of the current screen as a bitmap.
+
+ .. py:method:: setCursor(bitmap, hotspot)
+
+ Sets the mouse cursor to the bitmap given. The bitmap must have a size
+ divisible by 8 and an RGBA pixel format. The cursor generated is
+ binary black and white with a binary transparency channel. hotspot is
+ the relative position of the actual pointing coordinate in the
+ bitmap.
+
+ .. py:method:: setEventHook(pyfunc)
+
+ Set a callable which will receive all events before the standard event
+ handlers receive them. If this callable returns :py:const:`True`,
+ the event is not propagated to the standard event handlers.
+
+ Generally, :py:meth:`setEventHook` should be used as a last resort. In most
+ cases, standard event handlers are a lot cleaner. Also, setting several event
+ hooks is not supported by libavg. To get around this limitation, you can
+ use :py:meth:`getEventHook` to chain event hook functions.
+
+ Note that :py:attr:`event.node` is not set in the callback, since the
+ system hasn't determined the node to send the event to at that
+ point.
+
+ .. py:method:: setFakeFPS(fps)
+
+ Sets a fixed number of virtual frames per second that are used as
+ clock source for video playback, animations and other time-based
+ actions. If a value of :samp:`-1` is given as parameter, the real clock is
+ used. :py:meth:`setFakeFPS` can be used to get reproducible results for
+ recordings or automated tests. Setting FakeFPS has the side-effect of
+ disabling audio.
+
+ .. py:method:: setFramerate(framerate)
+
+ Sets the desired framerate for playback. Turns off syncronization
+ to the vertical blanking interval.
+
+ .. py:method:: setGamma(red, green, blue)
+
+ Sets display gamma. This is a control for overall brightness and
+ contrast that leaves black and white unchanged but adjusts greyscale
+ values. :samp:`1.0` is identity, higher values give a brighter image, lower
+ values a darker one.
+
+ .. py:method:: setInterval(time, pyfunc) -> int
+
+ Sets a python callable object that should be executed regularly.
+ :py:meth:`setInterval` returns an id that can be used to
+ call :py:meth:`clearInterval()` to stop the function from being called. The
+ callback is called at most once per frame.
+
+ :param int time: Number of milliseconds between two calls.
+
+ :param pyfunc: Python callable to execute.
+
+ .. py:method:: setMousePos(pos)
+
+ Sets the position of the mouse cursor. Generates a mouse motion event.
+
+ .. py:method:: setMultiSampleSamples(multiSampleSamples)
+
+ Sets the number of samples per pixel to compute.
+ This costs performance and smoothes the edges of polygons. A value of
+ :samp:`1` turns multisampling (also knowna as FSAA - Full-Screen
+ Antialiasing) off. Good values are dependent on the graphics driver and
+ the performance of the graphics card.
+
+ .. py:method:: setOGLOptions(usePOW2Textures, usePixelBuffers, multiSampleSamples, shaderUsage=AUTO, useDebugContext=False)
+
+ Determines which OpenGL extensions to check for and use if possible.
+ This method is mainly used for debugging purposes while developing libavg,
+ but can also be used to work around buggy drivers. The values set here
+ override those in the :file:`avgrc` file. Note that with the exception of
+ multiSampleSamples, fallbacks are always used - if a feature is
+ specified that the system doesn't support, a less demanding one will
+ be used.
+
+ Must be called before :py:meth:`play`.
+
+ :param bool usePOW2Textures:
+
+ If :py:const:`True`, restricts textures to power-of-two dimensions.
+
+ :param bool usePixelBuffers:
+
+ If :py:const:`False`, disables the use of OpenGL pixel buffer objects.
+
+ :param int multiSampleSamples:
+
+ The number of samples per pixel to compute.
+ This costs performance and smoothes the edges of polygons. A value of
+ :samp:`1` turns multisampling (also known as FSAA - Full-Screen
+ Antialiasing) off. Good values are dependent on the graphics driver and
+ the performance of the graphics card.
+
+ :param shaderUsage:
+
+ Either :py:const:`FULL`, :py:const:`MINIMAL` or :py:const:`AUTO`.
+ :py:const:`MINIMAL` restricts shader usage to a subset that doesn't use
+ much GPU power.
+
+ :param useDebugContext:
+
+ Uses an OpenGL Debug Context for rendering if the graphics driver supports
+ it. This causes more verbose error messages and warnings in the case of
+ OpenGL errors.
+
+
+ .. py:method:: setOnFrameHandler(pyfunc) -> int
+
+ Sets a python callable object that should be executed once per frame.
+ This is the same as :samp:`setInterval(0, pyfunc)`. Returns an id that can
+ be used to call :py:meth:`clearInterval()` to stop the function from being
+ called.
+
+ :param pyfunc: Python callable to execute.
+
+ .. py:method:: setResolution(fullscreen, width, height, bpp)
+
+ Sets display engine parameters. Must be called before :py:meth:`loadFile` or
+ :py:meth:`loadString`.
+
+ :param bool fullscreen:
+
+ :py:const:`True` if the avg file should be rendered fullscreen.
+
+ :param int width, height:
+
+ The window size (if fullscreen is :py:const:`False`)
+ or screen resolution (if fullscreen is :py:const:`True`).
+
+ :param int bpp:
+
+ Number of bits per pixel to use. Valid values are :samp:`15`, :samp:`16`,
+ :samp:`24` and :samp:`32`.
+
+ .. py:method:: setTimeout(time, pyfunc) -> int
+
+ Sets a python callable object that should be executed after a set
+ amount of time. :py:meth:`setTimeout` returns an id that can be used to
+ call :py:meth:`clearInterval()` to stop the function from being called.
+
+ :param int time: Number of milliseconds before the call.
+
+ :param pyfunc: Python callable to execute.
+
+ .. py:method:: setVBlankFramerate(rate)
+
+ Sets the desired number of monitor refreshes before the next
+ frame is displayed. The resulting framerate is determined by the
+ monitor refresh rate divided by the rate parameter.
+
+ :param int rate:
+
+ Number of vertical blanking intervals to wait. On Mac OS X, only :samp:`1`
+ is supported as rate.
+
+ .. py:method:: setWindowFrame(hasWindowFrame)
+
+ :py:attr:`hasWindowFrame` should be set to :py:const:`True` if a
+ non-fullscreen player should have a window frame. If set to
+ :py:const:`False`, the player runs with no title bar or window frame. Must
+ be called before :py:meth:`play` is called.
+
+ .. py:method:: setWindowPos(x, y)
+
+ Sets the location of the player window. Must be called before loadFile
+ or loadString.
+
+ .. py:method:: setWindowTitle(title)
+
+ Sets the string displayed in the title bar of the libavg window. Default is
+ 'libavg'.
+
+ .. py:method:: showCursor(show)
+
+ Shows or hides the mouse cursor.
+
+ :param bool show: :py:const:`True` if the mouse cursor should be visible.
+
+ .. py:method:: stop()
+
+ Stops playback and resets the video mode if necessary.
+
+ .. py:method:: stopOnEscape(stop)
+
+ Toggles player stop upon escape keystroke. If stop is :py:const:`True`
+ (the default), if player will halt playback when :kbd:`Esc` is pressed.
+
+ .. py:method:: useGLES(gles)
+
+ Chooses whether to use OpenGL ES or desktop OpenGL for rendering.
+ Must be called before :py:meth:`play`.
+
+ :param bool gles: :py:const:`True` if OpenGL ES should be used.
+
+ .. py:classmethod:: get() -> Player
+
+ .. deprecated:: 1.8
+ Use :attr:`avg.player` instead.
+
+ This method gives access to the player instance. If no player has been
+ created yet, a player is created.
diff --git a/sphinxdoc/vectornodes.rst b/sphinxdoc/vectornodes.rst
new file mode 100644
index 0000000..b45e750
--- /dev/null
+++ b/sphinxdoc/vectornodes.rst
@@ -0,0 +1,224 @@
+Vector Nodes
+============
+
+.. automodule:: libavg.avg
+ :no-members:
+
+ .. inheritance-diagram:: CircleNode CurveNode FilledVectorNode LineNode MeshNode Node PolygonNode PolyLineNode RectNode VectorNode libavg.geom.Arc libavg.geom.PieSlice libavg.geom.RoundedRect
+ :parts: 1
+
+ .. autoclass:: CircleNode([r=1, texcoord1=0, texcoord2=1])
+
+ A circle. The reference point for a circle is its center.
+
+ .. py:attribute:: r
+
+ The radius of the circle in pixels.
+
+ .. py:attribute:: texcoord1
+
+ .. py:attribute:: texcoord2
+
+ .. autoclass:: CurveNode([pos1, pos2, pos3, pos4, texcoord1, texcoord2])
+
+ A cubic bezier curve (`<http://en.wikipedia.org/wiki/Bezier_curve>`_).
+ :py:attr:`pos1` and :py:attr:`pos4` are the two endpoints of the curve.
+ :py:attr:`pos2` and :py:attr:`pos3` are control points.
+
+ .. py:method:: getPtOnCurve(t) -> pos
+
+ Returns a point on the curve. Which point is determined by the value of t.
+ If :samp:`t=0`, returns :py:attr:`pos1`. :samp:`t=1` returns :py:attr:`pos4`,
+ and values in between return the points in between.
+
+ .. py:attribute:: length
+
+ Returns an approximation of the length of the curve (ro).
+
+ .. py:attribute:: pos1
+
+ .. py:attribute:: pos2
+
+ .. py:attribute:: pos3
+
+ .. py:attribute:: pos4
+
+ .. py:attribute:: texcoord1
+
+ .. py:attribute:: texcoord2
+
+ .. autoclass:: FilledVectorNode([filltexhref, fillopacity=0, fillcolor="FFFFFF", filltexcoord1=Point2D(0,0), filltexcoord2=Point2D(1,1)])
+
+ Base class for vector nodes which have a filled area and a border. The area can
+ be filled either with a solid color (:py:attr:`fillcolor`) or with a texture
+ loaded from a file (:py:attr:`filltexhref`) or taken from a bitmap object
+ (:py:meth:`setFillBitmap`).
+
+ .. py:attribute:: fillcolor
+
+ .. py:attribute:: fillopacity
+
+ .. py:attribute:: filltexcoord1
+
+ .. py:attribute:: filltexcoord2
+
+ .. py:attribute:: filltexhref
+
+ An image file to use as a texture for the area of the node.
+
+ .. py:method:: setFillBitmap(bitmap)
+
+ Sets a bitmap to use as a fill texture. Sets :attr:`filltexhref` to an empty
+ string.
+
+ .. autoclass:: LineNode([pos1, pos2, texcoord1, texcoord2])
+
+ A line. :py:attr:`pos1` and :py:attr:`pos2` are the two endpoints of the line.
+
+ .. py:attribute:: pos1
+
+ .. py:attribute:: pos2
+
+ .. py:attribute:: texcoord1
+
+ .. py:attribute:: texcoord2
+
+ .. autoclass:: MeshNode([vertexcoords, texcoords, triangles])
+
+ This is a generalized mesh of textured triangles. See
+ https://www.libavg.de/wiki/ProgrammersGuide/MeshNode for an example.
+
+ .. py:attribute:: texcoords
+
+ .. py:attribute:: triangles
+
+ .. py:attribute:: vertexcoords
+
+ .. autoclass:: PolygonNode([linejoin="bevel", pos, texcoords])
+
+ A closed figure bounded by a number of line segments, optionally filled. Filled
+ polygons may not be self-intersecting.
+
+ .. py:attribute:: linejoin
+
+ The method by which line segments are joined together. Valid values are
+ :py:const:`bevel` and :py:const:`miter`.
+
+ .. py:attribute:: pos
+
+ A sequence (:py:class:`list` or :py:class:`tuple`) of pixel positions.
+
+ .. py:attribute:: texcoords
+
+ A sequence of float texture coordinates corresponding to the border positions.
+
+ .. autoclass:: PolyLineNode([linejoin="bevel", pos, texcoords])
+
+ A figure similar to a :py:class:`PolygonNode`, but not closed and never filled.
+
+ .. py:attribute:: linejoin
+
+ The method by which line segments are joined together. Valid values are
+ :py:const:`bevel` and :py:const:`miter`.
+
+ .. py:attribute:: pos
+
+ A sequence (:py:class:`list` or :py:class:`tuple`) of pixel positions.
+
+ .. py:attribute:: texcoords
+
+ A sequence of float texture coordinates corresponding to the border positions.
+
+ .. autoclass:: RectNode([pos, size, angle])
+
+ A rectangle that can be filled.
+
+ .. py:attribute:: angle
+
+ The angle that the rectangle is rotated to in radians. 0 is
+ unchanged, 3.14 is upside-down. The rectangle is rotated around its
+ center.
+
+ .. py:attribute:: pos
+
+ The position of the top left corner of the rectangle.
+
+ .. py:attribute:: size
+
+ .. py:attribute:: texcoords
+
+ .. autoclass:: VectorNode([color="FFFFFF", strokewidth=1, texhref, blendmode="blend"])
+
+ Base class for all nodes that draw geometrical primitives. All vector nodes
+ support configurable stroke width. Strokes can be filled either with a solid
+ color (:py:attr:`color`) or with a texture loaded from a file
+ (:py:attr:`texhref`) or taken from a bitmap object (:py:meth:`setBitmap`).
+
+ .. py:attribute:: blendmode
+
+ The method of compositing the node with the nodes under
+ it. Valid values are :py:const:`blend`, :py:const:`add`, :py:const:`min`
+ and :py:const:`max`. For :py:const:`min` and :py:const:`max`
+ blend modes, opacity is ignored.
+
+ .. py:attribute:: color
+
+ The color of the strokes in standard html color notation:
+ :samp:`"FF0000"` is red, :samp:`"00FF00"` green, etc.
+
+ .. py:attribute:: strokewidth
+
+ The width of the strokes in the vector. For lines, this is the line
+ width. For rectangles, it is the width of the outline, etc.
+
+ .. py:attribute:: texhref
+
+ An image file to use as a texture for the node.
+
+ .. py:method:: setBitmap(bitmap)
+
+ Sets a bitmap to use as a texture. Sets :attr:`texhref` to an empty
+ string.
+
+.. automodule:: libavg.geom
+ :no-members:
+
+ .. autoclass:: Arc(radius, startangle, endangle[, pos=(0,0)])
+
+ An unfilled arc (incomplete circle) from :py:attr:`startangle` to
+ :py:attr:`endangle`. :py:attr:`pos` is the center of the circle.
+
+ .. py:attribute:: endangle
+
+ .. py:attribute:: pos
+
+ .. py:attribute:: radius
+
+ .. py:attribute:: startangle
+
+
+ .. autoclass:: PieSlice(radius, startangle, endangle[, pos=(0,0)])
+
+ An arc (incomplete circle) from :py:attr:`startangle` to
+ :py:attr:`endangle` connected to the center of the circle. :py:attr:`pos` is the
+ center of the circle. A :py:class:`PieSlice` can be filled.
+
+ .. py:attribute:: endangle
+
+ .. py:attribute:: pos
+
+ .. py:attribute:: radius
+
+ .. py:attribute:: startangle
+
+
+ .. autoclass:: RoundedRect(size, radius, pos)
+
+ A rectangle with rounded corners. :py:attr:`radius` is the corner radius.
+
+ .. py:attribute:: pos
+
+ .. py:attribute:: radius
+
+ .. py:attribute:: size
+
diff --git a/sphinxdoc/widget.rst b/sphinxdoc/widget.rst
new file mode 100644
index 0000000..e37448f
--- /dev/null
+++ b/sphinxdoc/widget.rst
@@ -0,0 +1,591 @@
+Widget Classes
+==============
+
+The libavg.widget module contains high-level user interface elements such as buttons and
+list boxes. Widgets are fully skinnable (using the :py:class:`Skin` class and an xml
+configuration file) and multitouch-enabled. Sample code for all widgets can be found in the
+:samp:`widget.py` sample.
+
+.. note::
+
+ The widget module is experimental. Functionality and interface are still in flux and
+ subject to change.
+
+.. automodule:: libavg.widget
+ :no-members:
+
+ .. inheritance-diagram:: SwitchNode Button TextButton BmpButton ToggleButton CheckBox BmpToggleButton Keyboard Slider ScrollBar ProgressBar ScrollArea ScrollPane TimeSlider MediaControl
+ :parts: 1
+
+ .. inheritance-diagram:: HStretchNode VStretchNode HVStretchNode Skin
+ :parts: 1
+
+ .. autoclass:: BmpButton(upSrc, downSrc, [disabledSrc=None])
+
+ A :py:class:`Button` that is created from image files. Internally, it creates two or
+ three :py:class:`ImageNode` s and uses them as constructor parameters for
+ :py:class:`Button`.
+
+
+ .. autoclass:: BmpToggleButton(uncheckedUpSrc, uncheckedDownSrc, checkedUpSrc, checkedDownSrc, [uncheckedDisabledSrc=None, checkedDisabledSrc=None])
+
+ A :py:class:`ToggleButton` that is created from image files. Internally, it creates
+ image nodes for the src parameters and uses them as constructor parameters for
+ :py:class:`ToggleButton`.
+
+
+ .. autoclass:: Button(upNode, downNode, [disabledNode=None, activeAreaNode=None, fatFingerEnlarge=False, enabled=True])
+
+ A button that shows different user-supplied nodes depending on its
+ state. Possible button states are up, down and disabled. The nodes are attached
+ as children to the Button on construction. For a simple button, image nodes can
+ be passed. Uses the :py:class:`TapRecognizer` to detect clicks.
+
+ .. image:: ButtonStates.png
+
+ :param avg.Node upNode: The node displayed when the button is not pressed.
+
+ :param avg.Node downNode: The node displayed when the button is pressed.
+
+ :param avg.Node disabledNode: The node displayed when the button is disabled.
+
+ :param avg.Node activeAreaNode:
+
+ A node that is used only to determine if a click is over the button. Usually,
+ this node is invisible. :py:attr:`activeAreaNode` is useful for small touch
+ buttons, where the active area should be larger than the visible button to
+ account for touch inaccuracies.
+
+ :param bool fatFingerEnlarge:
+
+ If this parameter is set to :py:const:`True`, the button generates its own
+ internal :py:attr:`activeAreaNode` that is at least 20x20mm large.
+ :py:attr:`fatFingerEnlarge` is incompatible with a custom
+ :py:attr:`activeAreaNode`.
+
+ **Messages:**
+
+ To get these messages, call :py:meth:`Publisher.subscribe`.
+
+ .. py:method:: Button.PRESSED()
+
+ Called when a tap on the button is initiated.
+
+ .. py:method:: Button.RELEASED()
+
+ Called when a tap on the button ends. Emitted for both successful and
+ aborted taps.
+
+ .. py:method:: Button.CLICKED()
+
+ Called when the button is clicked.
+
+ .. py:attribute:: enabled
+
+ :py:const:`True` if the button accepts input. If the button is disabled,
+ it shows the :py:attr:`disabledNode`.
+
+
+ .. autoclass:: CheckBox([text="", skinObj=skin.Skin.default])
+
+ This is a classic checkbox with text to the right.
+
+ .. autoclass:: HStretchNode(endsExtent, [src=None, minExtent=-1])
+
+ A node that stretches its graphics to fill the size given horizontally. It is used
+ as base component for scrollbars and buttons. The base
+ bitmap is split into three parts: left, center and right. The left and right parts
+ are :py:attr:`endsExtent` wide and generated from the corresponding parts of the
+ source bitmap. The center part is generated from a one pixel wide slice of the
+ source bitmap and stretched to fill the space left between the left and right
+ parts.
+
+ :param int endsExtent:
+
+ Width of the left and right bitmaps in pixels.
+
+ :param src:
+
+ Either the name of a bitmap file or a :py:class:`Bitmap` object. Used to
+ generate the graphics used.
+
+ :param int minExtent:
+
+ Minimum horizontal size. The default of -1 uses :py:const:`2*endsExtent+1` as
+ minimum.
+
+
+ .. autoclass:: HVStretchNode(endsExtent, [src=None, minExtent=-(1,-1)])
+
+ A node that stretches its graphics to fill the size given horizontally and
+ vertically. It is used as base component for scrollareas. Similar to
+ :py:class:`HStretchNode`, the base bitmap is split and partial bitmaps are
+ extracted. Four corner bitmaps of size :py:attr:`endsExtent` stay the same size,
+ four one-pixel-slice bitmaps fill the sides, and a single one-pixel bitmap is used
+ to fill the center area.
+
+ :param IntPoint endsExtent:
+
+ Size of the corner bitmaps in pixels.
+
+ :param src:
+
+ Either the name of a bitmap file or a :py:class:`Bitmap` object. Used to
+ generate the graphics used.
+
+ :param IntPoint minExtent:
+
+ Minimum size. The default of :py:const:`(-1,-1]` uses :py:const:`2*endsExtent+1` as
+ minimum.
+
+
+ .. autoclass:: Keyboard(bgSrc, downSrc, keyDefs, shiftKeyCode, [altGrKeyCode=None, stickyShift=False, feedbackSrc=None])
+
+ Implements an onscreen keyboard that turns mouse clicks or touches into key
+ presses. The keyboard is completely configurable. Keyboard graphics are determined
+ by the two image files in :py:attr:`bgSrc` and :py:attr:`downSrc`. Keys can be
+ defined as rectangles anywhere on these images. Works for both single-touch and
+ multitouch devices. Generates events when keys are pressed or released.
+ An additional enlarged image of the key being pressed can be rendered above a
+ pending touch as well by using :py:attr:`feedbackSrc`.
+
+ Needs offscreen rendering support on the machine to generate individual key images
+ from the image files supplied.
+
+ :param string bgSrc:
+
+ Filename of an image that contains the keyboard with unpressed keys.
+
+ :param string downSrc:
+
+ Filename of an image that contains the keyboard with pressed keys.
+
+ :param list keyDefs:
+
+ List of key definitions. Keys can be either character keys:
+
+ [(<keycode>, <shift keycode>, <altgr keycode>), <feedback>, <repeat>,
+ <pos>, <size>]
+
+ or command keys:
+
+ [<keycode>, <feedback>, <repeat>, <pos>, <size>]
+
+ For character keys, the shift and altgr keycodes are optional. To define
+ entire rows of evenly-spaced keys, use :py:meth:`makeRowKeyDefs`.
+
+ :param shiftKeyCode:
+
+ One of the command keycodes. When a key with this code is pressed,
+ pressing other keys causes them to return the shifted keycode.
+
+ :param altGrKeyCode:
+
+ One of the command keycodes. When a key with this code is pressed,
+ pressing other keys causes them to return the altgr keycode.
+
+ :param bool stickyShift:
+
+ For single-touch devices, the shift key must stay in the pressed state
+ until the next normal key is pressed to have any effect. This is the
+ behaviour if :py:attr:`stickyShift` is :py:const:`True`. If it is
+ :py:const:`False` (the default), a
+ multitouch device is assumed and shift works like on a physical keyboard.
+
+ :param string feedbackSrc:
+
+ Filename of an image that contains an enlarged version of bgSrc for use as
+ feedback during key pressed. If this parameter not set the feedback funktion
+ is turned off.
+
+ **Messages:**
+
+ :py:class:`Keyboard` emits messages on every key press and release:
+ To get these messages, call :py:meth:`Publisher.subscribe`.
+
+ .. py:method:: DOWN(keycode)
+
+ Emitted whenever a key (command or char) is pressed.
+
+ .. py:method:: UP(keycode)
+
+ Emitted whenever a key (command or char) is released.
+
+ .. py:method:: CHAR(char)
+
+ Emitted whenever a character is generated. This is generally when a char key
+ is released and takes into account shift/altgr status.
+
+ .. py:method:: reset()
+
+ Resets any sticky keys (shift, altgr) to their default state.
+
+ .. py:classmethod:: makeRowKeyDefs(startPos, keySize, spacing, feedbackStr, keyStr, shiftKeyStr, [altGrKeyStr])
+
+ Creates key definitions for a row of uniform keys. Useful for creating the
+ keyDefs parameter of the Keyboard constructor. All the keys get no repeat
+ functionality.
+
+ :param avg.Point2D startPos: Top left position of the row.
+
+ :param avg.Point2D keySize: Size of each key.
+
+ :param int spacing: Number of empty pixels between two keys.
+
+ :param string keyStr:
+
+ Unicode string containing the unshifted keycodes (i.e.
+ :samp:`u"qwertzuiopżś"`)
+
+ :param string shiftKeyStr:
+
+ Unicode string containing the shifted keycodes
+ (i.e. :samp:`u"QWERTZUIOPńć"`)
+
+ :param string altGrKeyStr:
+
+ Unicode string containing the keycodes when altgr is pressed.
+
+
+ .. autoclass:: MediaControl([duration=1000, time=0, skinObj=skin.Skin.default])
+
+ A composite control that incorporates a :py:class:`Slider`, a play/pause
+ button and text widgets that display the time. By itself, the
+ :py:class:`MediaControl` is independent of a media node. The controlling
+ application is responsible for keeping track of media node and
+ :py:class:`MediaControl` state and syncing the two.
+
+ **Messages:**
+
+ .. py:method:: PLAY_CLICKED()
+
+ Emitted when the play/pause toggle is switched to play.
+
+ .. py:method:: PAUSE_CLICKED()
+
+ Emitted when the play/pause toggle is switched to pause.
+
+ .. py:method:: SEEK_PRESSED()
+
+ Emitted when the user starts dragging the seek thumb.
+
+ .. py:method:: SEEK_MOTION(curTime)
+
+ Emitted when the user moves the seek thumb.
+
+ .. py:method:: SEEK_RELEASED()
+
+ Emitted when the user releases the seek thumb.
+
+ .. py:attribute:: duration
+
+ Duration of the medium in milliseconds.
+
+ .. py:attribute:: time
+
+ Current media time in milliseconds.
+
+ .. py:method:: play()
+
+ Switches to play mode by toggling the button.
+
+ .. py:method:: pause()
+
+ Switches to pause mode by toggling the button.
+
+
+ .. autoclass:: Orientation()
+
+ .. py:data:: HORIZONTAL
+
+ .. py:data:: VERTICAL
+
+
+ .. autoclass:: ProgressBar(orientation, [skinObj=skin.Skin.default, height=0, width=0, range=(0.,1.), value=0.0])
+
+ A horizontal bar-shaped UI element that indicates the progression of an operation.
+
+ .. py:attribute:: range
+
+ Tuple giving minimum and maximum value.
+
+ .. py:attribute:: value
+
+ Current progression. The application is responsible for updating the value. In
+ general, :py:attr:`value` will start at :py:attr:`range[0]` and end with
+ :py:attr:`range[1]`.
+
+
+ .. autoclass:: ScrollArea(contentNode, size[, skinObj=skin.Skin.default, enabled=True, scrollBars=(Orientation.HORIZONTAL, Orientation.VERTICAL)])
+
+ A rectangular area that allows a user to choose a view into arbitrary content. The
+ content can be larger than the :py:class:`ScrollArea`, in which case scroll bars can
+ be used to allow the user to choose which part to view. Dragging the content to
+ determine the viewport is also supported. A :py:class:`ScrollArea` uses
+ :py:class:`ScrollPane` and :py:class:`ScrollBar` objects internally.
+
+ **Messages:**
+
+ To get these messages, call :py:meth:`Publisher.subscribe`.
+
+ .. py:method:: PRESSED()
+
+ Emitted when a content drag is initiated.
+
+ .. py:method:: RELEASED()
+
+ Emitted when a content drag is finished.
+
+ .. py:method:: CONTENT_POS_CHANGED(pos)
+
+ Emitted when the viewport changes for any reason.
+
+ .. py:attribute:: contentsize
+
+ The size of the :py:attr:`contentNode`.
+
+ .. py:attribute:: contentpos
+
+ The position of the content within the area.
+
+
+ .. autoclass:: ScrollBar([orientation=Orientation.HORIZONTAL, skinObj=skin.Skin.default, enabled=True, height=0, width=0, range=(0.,1.), thumbPos=0.0, thumbExtent=0.1])
+
+ A vertical or horizontal scroll bar.
+
+ **Messages:**
+
+ To get these messages, call :py:meth:`Publisher.subscribe`.
+
+ .. py:method:: PRESSED()
+
+ Emitted when a drag is initiated.
+
+ .. py:method:: RELEASED()
+
+ Emitted when a drag is finished.
+
+ .. py:method:: THUMB_POS_CHANGED(pos)
+
+ Emitted when the thumb is dragged.
+
+ .. py:attribute:: range
+
+ Minimum and maximum values for the thumb.
+
+ .. py:attribute:: thumbPos
+
+ .. py:attribute:: thumbExtent
+
+
+ .. autoclass:: ScrollPane(contentNode)
+
+ A rectangular view into arbitrary content. No user interaction is implemented.
+
+ .. py:attribute:: contentpos
+
+ .. py:attribute:: contentsize
+
+
+ .. autoclass:: Skin(skinXmlFName[, mediaDir=""])
+
+ A :py:class:`Skin` determines the appearance of any user interface elements that
+ use it. Skin configuration is determined by an xml file. This xml file determines
+ the bitmaps to use and the sizes of various components. It also determines the
+ fonts used by the elements. Skinnable user interface elements include
+ :py:class:`TextButton`, :py:class:`Slider`, :py:class:`ScrollBar`,
+ :py:class:`ProgressBar`, :py:class:`ScrollArea`, :py:class:`CheckBox` and
+ :py:class:`MediaControl`. In addition, the fonts defined can be accessed by the
+ application.
+
+ The default skin xml file is located at :samp:`src/python/data/SimpleSkin.xml`. It
+ provides a good basis from which to create your own skin.
+
+ :param string skinXmlFName:
+
+ The name of the xml configuration file.
+
+ :param string mediaDir:
+
+ The location of the image files to use.
+
+ .. py:attribute:: fonts:
+
+ A dictionary of :py:class:`FontStyle` objects created from the xml
+ configuration file.
+
+
+ .. autoclass:: Slider([orientation=Orientation.HORIZONTAL, skinObj=skin.Skin.default])
+
+ Sliders are horizontal or vertical bar with a draggable thumb that can be used
+ to set a value. In contrast to a scroll bar, the slider's thumb has no range.
+
+ **Messages:**
+
+ To get these messages, call :py:meth:`Publisher.subscribe`.
+
+ .. py:method:: PRESSED()
+
+ Emitted when a drag is initiated.
+
+ .. py:method:: RELEASED()
+
+ Emitted when a drag is finished.
+
+ .. py:method:: THUMB_POS_CHANGED(pos)
+
+ Emitted when the thumb is dragged.
+
+ .. py:attribute:: range
+
+ Minimum and maximum values for the thumb.
+
+ .. py:attribute:: thumbPos
+
+
+ .. autoclass:: SwitchNode([nodeMap=None, visibleid=None])
+
+ A :py:class:`DivNode` that keeps a map of child nodes and shows only one of
+ the map members at any time.
+
+ :param map nodeMap:
+
+ A map :py:const:`id->node` that contains the nodes to switch between.
+
+ .. py:method:: setNodeMap(nodeMap)
+
+ Can be used to set the :py:attr:`nodeMap` after construction if no node map
+ was set before.
+
+ .. py:attribute:: visibleid
+
+ The id of the visible child node.
+
+
+ .. autoclass:: TextButton(text, [skinObj=skin.Skin.default])
+
+ A :py:class:`Button` that is created using the given :py:class:`Skin` and a text.
+
+ .. py:attribute:: text
+
+ The string displayed on the button.
+
+
+ .. autoclass:: TimeSlider()
+
+ Works like a :py:class:`ProgressBar` with an additional slider thumb.
+
+ .. autoclass:: ToggleButton(uncheckedUpNode, uncheckedDownNode, checkedUpNode, checkedDownNode, [uncheckedDisabledNode=None, checkedDisabledNode=None, activeAreaNode=None, fatFingerEnlarge=False, enabled=True, checked=False])
+
+ A button that can be used to toggle between checked and unchecked states.
+ Classical GUI checkboxes are an example of this kind of button.
+
+ A :py:class:`ToggleButton` has a total of six visual states. In addition to the
+ distinction between checked and unchecked, a button can be enabled or disabled.
+ Buttons also change their appearance as soon as they are touched, leading to two
+ further states. For each visual state, a node is passed as constructor parameter.
+ The constructor attaches the nodes to the :py:class:`ToggleButton`.
+
+ Uses the :py:class:`TapRecognizer` to detect clicks.
+
+ .. image:: ToggleButtonStates.png
+
+ :param avg.Node uncheckedUpNode:
+
+ The node displayed when the button is unchecked and not touched.
+
+ :param avg.Node uncheckedDownNode:
+
+ The node displayed when the button is unchecked and touched.
+
+ :param avg.Node checkedUpNode:
+
+ The node displayed when the button is checked and not touched.
+
+ :param avg.Node checkedDownNode:
+
+ The node displayed when the button is checked and not touched.
+
+ :param avg.Node uncheckedDisabledNode:
+
+ The node displayed when the button is unchecked and disabled.
+
+ :param avg.Node checkedDisabledNode:
+
+ The node displayed when the button is checked and disabled.
+
+ :param avg.Node activeAreaNode:
+
+ A node that is used only to determine if a click is over the button. Usually,
+ this node is invisible. :py:attr:`activeAreaNode` is useful for small touch
+ buttons, where the active area should be larger than the visible button to
+ account for touch inaccuracies.
+
+ :param bool fatFingerEnlarge:
+
+ If this parameter is set to :py:const:`True`, the button generates its own
+ internal :py:attr:`activeAreaNode` that is at least 20x20mm large.
+ :py:attr:`fatFingerEnlarge` is incompatible with a custom
+ :py:attr:`activeAreaNode`.
+
+ :param bool checked:
+
+ If this parameter is set to :py:const:`True`, the button starts in the checked
+ state.
+
+ :param bool enabled:
+
+ If this parameter is set to :py:const:`True`, the button starts in the
+ disabled state.
+
+ **Messages:**
+
+ To get these messages, call :py:meth:`Publisher.subscribe`.
+
+ .. py:method:: Button.PRESSED()
+
+ Called when a tap on the button is initiated.
+
+ .. py:method:: Button.RELEASED()
+
+ Called when a tap on the button ends. Emitted for both successful and
+ aborted taps.
+
+ .. py:method:: Button.TOGGLED()
+
+ Called when the button changes from unchecked to checked or vice-versa.
+
+
+ .. py:attribute:: checked
+
+ The state of the toggle.
+
+ .. py:attribute:: enabled
+
+ Determines whether the button accepts input.
+
+
+ .. autoclass:: VStretchNode(endsExtent, [src=None, minExtent=-1])
+
+ A node that stretches its graphics to fill the size given vertically. It is used
+ as base component for scrollbars. The base
+ bitmap is split into three parts: top, center and bottom. The top and bottom parts
+ are :py:attr:`endsExtent` wide and generated from the corresponding parts of the
+ source bitmap. The center part is generated from a one pixel high slice of the
+ source bitmap and stretched to fill the space left between the top and bottom
+ parts.
+
+ :param int endsExtent:
+
+ Width of the top and bottom bitmaps in pixels.
+
+ :param src:
+
+ Either the name of a bitmap file or a :py:class:`Bitmap` object. Used to
+ generate the graphics used.
+
+ :param int minExtent:
+
+ Minimum vertical size. The default of :py:const:`-1` uses
+ :py:const:`2*endsExtent+1` as minimum.
+
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100644
index 0000000..bfb11d4
--- /dev/null
+++ b/src/Makefile.am
@@ -0,0 +1,16 @@
+SUBDIRS = base graphics imaging lmfit oscpack audio video player \
+ anim wrapper python test utils samples
+
+EXTRA_DIST = avgrc avgconfigwrapper.h api.h avgconfig_win.h version.h \
+ $(wildcard glm/*.hpp) $(wildcard glm/core/*.hpp) $(wildcard glm/core/*.inl) \
+ $(wildcard glm/gtc/*.hpp) $(wildcard glm/gtc/*.inl) \
+ $(wildcard glm/gtx/*.hpp) $(wildcard glm/gtx/*.inl) \
+ $(wildcard glm/virtrev/*.hpp)
+
+BUILT_SOURCES = version.h
+DISTCLEANFILES = version.h
+
+version.h: FORCE
+ $(top_srcdir)/CreateVersionFile.py $(top_builddir)/src
+
+FORCE:
diff --git a/src/addcopyright.py b/src/addcopyright.py
new file mode 100755
index 0000000..c8204ca
--- /dev/null
+++ b/src/addcopyright.py
@@ -0,0 +1,22 @@
+#!/usr/bin/python
+
+import sys, os, fnmatch
+
+CopyrightNoticeLines = file("Copyright").read().splitlines()
+
+for dir in ["base", "conradrelais", "graphics", "parport", "player", "python"]:
+ files = os.listdir(dir)
+ for f in files:
+ if fnmatch.fnmatch(f, "*.cpp") or fnmatch.fnmatch(f, "*.h"):
+ fname = dir+"/"+f
+ print "Processing " + fname
+ fobj = file(fname, "r+")
+ str = fobj.read()
+ lines = str.splitlines()
+ while lines[0].find('//') == 0:
+ lines = lines[1:]
+ lines = CopyrightNoticeLines+lines
+ fobj.seek(0)
+ fobj.truncate()
+ for line in lines:
+ fobj.write(line+"\n")
diff --git a/src/anim/Anim.cpp b/src/anim/Anim.cpp
new file mode 100644
index 0000000..69b245d
--- /dev/null
+++ b/src/anim/Anim.cpp
@@ -0,0 +1,123 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+
+#include "Anim.h"
+
+#include "../base/Exception.h"
+#include "../base/ObjectCounter.h"
+
+#include "../player/Player.h"
+
+using namespace boost::python;
+using namespace std;
+
+namespace avg {
+
+Anim::Anim(const object& startCallback, const object& stopCallback)
+ : m_StartCallback(startCallback),
+ m_StopCallback(stopCallback),
+ m_bRunning(false),
+ m_bIsRoot(true)
+{
+ ObjectCounter::get()->incRef(&typeid(*this));
+ Player::get()->registerPlaybackEndListener(this);
+}
+
+Anim::~Anim()
+{
+ ObjectCounter::get()->decRef(&typeid(*this));
+ if (Player::exists()) {
+ Player::get()->unregisterPlaybackEndListener(this);
+ }
+}
+
+void Anim::setStartCallback(const object& startCallback)
+{
+ m_StartCallback = startCallback;
+}
+
+void Anim::setStopCallback(const object& stopCallback)
+{
+ m_StopCallback = stopCallback;
+}
+
+void Anim::start(bool)
+{
+ if (m_bRunning) {
+ throw(Exception(AVG_ERR_UNSUPPORTED,
+ "Anim.start(): animation already running."));
+ }
+ if (!(Player::get()->isPlaying())) {
+ throw(Exception(AVG_ERR_UNSUPPORTED,
+ "Animation playback can only be started when the player is running."));
+ }
+ m_bRunning = true;
+ if (m_bIsRoot) {
+ Player::get()->registerPreRenderListener(this);
+ }
+ if (m_StartCallback != object()) {
+ call<void>(m_StartCallback.ptr());
+ }
+}
+
+bool Anim::isRunning() const
+{
+ return m_bRunning;
+}
+
+void Anim::setHasParent()
+{
+ assert(!m_bRunning);
+ m_bIsRoot = false;
+}
+
+void Anim::onPreRender()
+{
+ step();
+}
+
+void Anim::onPlaybackEnd()
+{
+ AnimPtr tempThis = shared_from_this();
+ m_StartCallback = object();
+ m_StopCallback = object();
+ if (m_bRunning) {
+ abort();
+ }
+}
+
+void Anim::setStopped()
+{
+ if (m_bIsRoot) {
+ Player::get()->unregisterPreRenderListener(this);
+ }
+ m_bRunning = false;
+ if (m_StopCallback != object()) {
+ try {
+ m_StopCallback();
+ } catch (error_already_set &) {
+ cerr << "Python exception in Anim stop callback." << endl;
+ PyErr_Print();
+ exit(5);
+ }
+ }
+}
+
+}
diff --git a/src/anim/Anim.h b/src/anim/Anim.h
new file mode 100644
index 0000000..3080141
--- /dev/null
+++ b/src/anim/Anim.h
@@ -0,0 +1,90 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _Anim_H_
+#define _Anim_H_
+
+#include "../api.h"
+// Python docs say python.h should be included before any standard headers (!)
+#include "../player/WrapPython.h"
+
+#include "../base/IPreRenderListener.h"
+#include "../base/IPlaybackEndListener.h"
+
+#include <boost/python.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/weak_ptr.hpp>
+#include <boost/enable_shared_from_this.hpp>
+
+#include <string>
+
+namespace avg {
+
+class Anim;
+class GroupAnim;
+
+typedef boost::shared_ptr<class Anim> AnimPtr;
+typedef boost::weak_ptr<class Anim> AnimWeakPtr;
+
+class AVG_API Anim: public boost::enable_shared_from_this<Anim>, IPreRenderListener,
+ IPlaybackEndListener
+{
+public:
+ Anim(const boost::python::object& startCallback,
+ const boost::python::object& stopCallback);
+ virtual ~Anim();
+
+ void setStartCallback(const boost::python::object& startCallback);
+ void setStopCallback(const boost::python::object& stopCallback);
+ virtual void start(bool bKeepAttr=false);
+ virtual void abort() = 0;
+ bool isRunning() const;
+ void setHasParent();
+
+ virtual void onPreRender();
+ virtual void onPlaybackEnd();
+ virtual bool step() = 0;
+
+protected:
+ void setStopped();
+
+private:
+ Anim();
+ Anim(const Anim&);
+ boost::python::object m_StartCallback;
+ boost::python::object m_StopCallback;
+ bool m_bRunning;
+ bool m_bIsRoot;
+};
+
+template<class T>
+bool isPythonType(const boost::python::object& obj)
+{
+ boost::python::extract<T> ext(obj);
+ return ext.check();
+}
+
+}
+
+#endif
+
+
+
diff --git a/src/anim/AttrAnim.cpp b/src/anim/AttrAnim.cpp
new file mode 100644
index 0000000..2791ed2
--- /dev/null
+++ b/src/anim/AttrAnim.cpp
@@ -0,0 +1,103 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+
+#include "AttrAnim.h"
+
+#include "../base/Exception.h"
+#include "../player/Player.h"
+#include "../player/Node.h"
+
+using namespace boost;
+using namespace boost::python;
+using namespace std;
+
+namespace avg {
+
+AttrAnim::AttrAnimationMap AttrAnim::s_ActiveAnimations;
+
+bool ObjAttrID::operator < (const ObjAttrID& other) const
+{
+ if (m_ObjHash < other.m_ObjHash) {
+ return true;
+ } else if (m_ObjHash > other.m_ObjHash) {
+ return false;
+ } else if (m_sAttrName < other.m_sAttrName) {
+ return true;
+ } else {
+ return false;
+ }
+}
+
+int AttrAnim::getNumRunningAnims()
+{
+ return s_ActiveAnimations.size();
+}
+
+AttrAnim::AttrAnim(const object& node, const string& sAttrName,
+ const object& startCallback, const object& stopCallback)
+ : Anim(startCallback, stopCallback),
+ m_Node(node),
+ m_sAttrName(sAttrName)
+{
+ object obj = getValue();
+}
+
+AttrAnim::~AttrAnim()
+{
+}
+
+void AttrAnim::start(bool bKeepAttr)
+{
+ stopActiveAttrAnim();
+ Anim::start();
+ addToMap();
+}
+
+object AttrAnim::getValue() const
+{
+ return m_Node.attr(m_sAttrName.c_str());
+}
+
+void AttrAnim::setValue(const object& val)
+{
+ m_Node.attr(m_sAttrName.c_str()) = val;
+}
+
+void AttrAnim::addToMap()
+{
+ s_ActiveAnimations[ObjAttrID(m_Node, m_sAttrName)] =
+ dynamic_pointer_cast<AttrAnim>(shared_from_this());
+}
+
+void AttrAnim::removeFromMap()
+{
+ s_ActiveAnimations.erase(ObjAttrID(m_Node, m_sAttrName));
+}
+
+void AttrAnim::stopActiveAttrAnim()
+{
+ ObjAttrID id(m_Node, m_sAttrName);
+ AttrAnimationMap::iterator it = s_ActiveAnimations.find(id);
+ if (it != s_ActiveAnimations.end()) {
+ it->second->abort();
+ }
+}
+
+}
diff --git a/src/anim/AttrAnim.h b/src/anim/AttrAnim.h
new file mode 100644
index 0000000..a546c95
--- /dev/null
+++ b/src/anim/AttrAnim.h
@@ -0,0 +1,92 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _AttrAnim_H_
+#define _AttrAnim_H_
+
+#include "Anim.h"
+
+#include "../api.h"
+// Python docs say python.h should be included before any standard headers (!)
+#include "../player/WrapPython.h"
+
+#include <boost/python.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/weak_ptr.hpp>
+
+#include <string>
+#include <map>
+
+namespace avg {
+
+struct ObjAttrID {
+ ObjAttrID(const boost::python::object& obj, const std::string& sAttrName)
+ : m_ObjHash(boost::python::extract<long>(obj.attr("__hash__")())),
+ m_sAttrName(sAttrName)
+ {
+ }
+ long m_ObjHash;
+ std::string m_sAttrName;
+ bool operator < (const ObjAttrID& other) const;
+};
+
+class AttrAnim;
+
+typedef boost::shared_ptr<class Anim> AttrAnimPtr;
+typedef boost::weak_ptr<class Anim> AttrAnimWeakPtr;
+
+class AVG_API AttrAnim: public Anim
+{
+public:
+ static int getNumRunningAnims();
+
+ AttrAnim(const boost::python::object& node, const std::string& sAttrName,
+ const boost::python::object& startCallback,
+ const boost::python::object& stopCallback);
+ virtual ~AttrAnim();
+
+ virtual void start(bool bKeepAttr=false);
+
+protected:
+ boost::python::object getValue() const;
+ void setValue(const boost::python::object& val);
+
+ void addToMap();
+ void removeFromMap();
+ void stopActiveAttrAnim();
+
+private:
+ AttrAnim();
+ AttrAnim(const AttrAnim&);
+
+ boost::python::object m_Node;
+ std::string m_sAttrName;
+
+ typedef std::map<ObjAttrID, AttrAnimPtr> AttrAnimationMap;
+ static AttrAnimationMap s_ActiveAnimations;
+};
+
+}
+
+#endif
+
+
+
diff --git a/src/anim/ContinuousAnim.cpp b/src/anim/ContinuousAnim.cpp
new file mode 100644
index 0000000..e6b8b02
--- /dev/null
+++ b/src/anim/ContinuousAnim.cpp
@@ -0,0 +1,91 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "ContinuousAnim.h"
+
+#include "../base/Exception.h"
+#include "../base/MathHelper.h"
+#include "../player/Player.h"
+
+using namespace boost::python;
+using namespace std;
+
+namespace avg {
+
+ContinuousAnim::ContinuousAnim(const object& node, const string& sAttrName,
+ const object& startValue, const object& speed, bool bUseInt,
+ const object& startCallback, const object& stopCallback)
+ : AttrAnim(node, sAttrName, startCallback, stopCallback),
+ m_StartValue(startValue),
+ m_Speed(speed),
+ m_bUseInt(bUseInt)
+{
+}
+
+ContinuousAnim::~ContinuousAnim()
+{
+}
+
+void ContinuousAnim::start(bool bKeepAttr)
+{
+ AttrAnim::start();
+ if (!bKeepAttr) {
+ setValue(m_StartValue);
+ }
+ m_EffStartValue = getValue();
+ m_StartTime = Player::get()->getFrameTime();
+}
+
+void ContinuousAnim::abort()
+{
+ if (isRunning()) {
+ AnimPtr tempThis = shared_from_this();
+ removeFromMap();
+ setStopped();
+ }
+}
+
+bool ContinuousAnim::step()
+{
+ object curValue;
+ float time = (Player::get()->getFrameTime()-m_StartTime)/1000.0f;
+ if (isPythonType<float>(m_EffStartValue)) {
+ curValue = object(time*extract<float>(m_Speed)+m_EffStartValue);
+ if (m_bUseInt) {
+ float d = extract<float>(curValue);
+ curValue = object(round(d));
+ }
+ } else if (isPythonType<glm::vec2>(m_EffStartValue)) {
+ glm::vec2 pt = extract<glm::vec2>(m_Speed)();
+ curValue = object(time*pt+m_EffStartValue);
+ if (m_bUseInt) {
+ glm::vec2 pt = extract<glm::vec2>(curValue)();
+ curValue = object(glm::vec2(round(pt.x), round(pt.y)));
+ }
+ } else {
+ throw (Exception(AVG_ERR_TYPE,
+ "Animated attributes must be either numbers or Point2D."));
+ }
+ setValue(curValue);
+ return false;
+}
+
+}
diff --git a/src/anim/ContinuousAnim.h b/src/anim/ContinuousAnim.h
new file mode 100644
index 0000000..c0bcb67
--- /dev/null
+++ b/src/anim/ContinuousAnim.h
@@ -0,0 +1,59 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _ContinuousAnim_H_
+#define _ContinuousAnim_H_
+
+#include "../api.h"
+
+#include "SimpleAnim.h"
+
+namespace avg {
+
+class AVG_API ContinuousAnim: public AttrAnim {
+public:
+ ContinuousAnim(const boost::python::object& node, const std::string& sAttrName,
+ const boost::python::object& startValue,
+ const boost::python::object& speed,
+ bool bUseInt=false,
+ const boost::python::object& startCallback=boost::python::object(),
+ const boost::python::object& stopCallback=boost::python::object());
+ virtual ~ContinuousAnim();
+
+ virtual void start(bool bKeepAttr=false);
+ virtual void abort();
+ virtual bool step();
+
+private:
+ boost::python::object m_StartValue;
+ boost::python::object m_Speed;
+ bool m_bUseInt;
+
+ boost::python::object m_EffStartValue;
+ long long m_StartTime;
+};
+
+}
+
+#endif
+
+
+
diff --git a/src/anim/EaseInOutAnim.cpp b/src/anim/EaseInOutAnim.cpp
new file mode 100644
index 0000000..c8a3cf7
--- /dev/null
+++ b/src/anim/EaseInOutAnim.cpp
@@ -0,0 +1,71 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "EaseInOutAnim.h"
+
+#include "../player/Player.h"
+#include "../base/MathHelper.h"
+
+#include <math.h>
+
+using namespace boost::python;
+using namespace std;
+
+namespace avg {
+
+EaseInOutAnim::EaseInOutAnim(const object& node, const string& sAttrName,
+ long long duration, const object& startValue, const object& endValue,
+ long long easeInDuration, long long easeOutDuration, bool bUseInt,
+ const object& startCallback, const object& stopCallback)
+ : SimpleAnim(node, sAttrName, duration, startValue, endValue, bUseInt, startCallback,
+ stopCallback),
+ m_EaseInDuration(float(easeInDuration)/duration),
+ m_EaseOutDuration(float(easeOutDuration)/duration)
+{
+}
+
+EaseInOutAnim::~EaseInOutAnim()
+{
+}
+
+float EaseInOutAnim::interpolate(float t)
+{
+ float accelDist = m_EaseInDuration*2/PI;
+ float decelDist = m_EaseOutDuration*2/PI;
+ float dist;
+ if (t<m_EaseInDuration) {
+ // Acceleration stage
+ float nt = t/m_EaseInDuration;
+ float s = sin(-PI/2+nt*PI/2)+1;
+ dist = s*accelDist;
+ } else if (t > 1-m_EaseOutDuration) {
+ // Deceleration stage
+ float nt = (t-(1-m_EaseOutDuration))/m_EaseOutDuration;
+ float s = sin(nt*PI/2);
+ dist = accelDist+(1-m_EaseInDuration-m_EaseOutDuration)+s*decelDist;
+ } else {
+ // Linear stage
+ dist = accelDist+t-m_EaseInDuration;
+ }
+ return dist/(accelDist+(1-m_EaseInDuration-m_EaseOutDuration)+decelDist);
+}
+
+}
diff --git a/src/anim/EaseInOutAnim.h b/src/anim/EaseInOutAnim.h
new file mode 100644
index 0000000..d4326da
--- /dev/null
+++ b/src/anim/EaseInOutAnim.h
@@ -0,0 +1,55 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _EaseInOutAnim_H_
+#define _EaseInOutAnim_H_
+
+#include "../api.h"
+
+#include "SimpleAnim.h"
+
+namespace avg {
+
+class AVG_API EaseInOutAnim: public SimpleAnim {
+public:
+ EaseInOutAnim(const boost::python::object& node, const std::string& sAttrName,
+ long long duration,
+ const boost::python::object& pStartValue,
+ const boost::python::object& pEndValue,
+ long long easeInDuration, long long easeOutDuration, bool bUseInt=false,
+ const boost::python::object& startCallback=boost::python::object(),
+ const boost::python::object& stopCallback=boost::python::object());
+ virtual ~EaseInOutAnim();
+
+protected:
+ virtual float interpolate(float t);
+
+private:
+ float m_EaseInDuration;
+ float m_EaseOutDuration;
+};
+
+}
+
+#endif
+
+
+
diff --git a/src/anim/LinearAnim.cpp b/src/anim/LinearAnim.cpp
new file mode 100644
index 0000000..7e34cfd
--- /dev/null
+++ b/src/anim/LinearAnim.cpp
@@ -0,0 +1,73 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "LinearAnim.h"
+
+#include "../player/Player.h"
+
+using namespace boost::python;
+using namespace std;
+
+namespace avg {
+
+LinearAnim::LinearAnim(const object& node, const string& sAttrName, long long duration,
+ const object& startValue, const object& endValue, bool bUseInt,
+ const object& startCallback, const object& stopCallback)
+ : SimpleAnim(node, sAttrName, duration, startValue, endValue, bUseInt, startCallback,
+ stopCallback)
+{
+}
+
+LinearAnim::~LinearAnim()
+{
+}
+
+float LinearAnim::interpolate(float t)
+{
+ return t;
+}
+
+float LinearAnim::getStartPart(float start, float end, float cur)
+{
+ return (cur-start)/(end-start);
+}
+
+AnimPtr fadeIn(const boost::python::object& node, long long duration, float max,
+ const boost::python::object& stopCallback)
+{
+ object startVal = node.attr("opacity");
+ AnimPtr pAnim(new LinearAnim(node, "opacity", duration, startVal,
+ object(max), false, object(), stopCallback));
+ pAnim->start(false);
+ return pAnim;
+}
+
+AnimPtr fadeOut(const boost::python::object& node, long long duration,
+ const boost::python::object& stopCallback)
+{
+ object startVal = node.attr("opacity");
+ AnimPtr pAnim(new LinearAnim(node, "opacity", duration, startVal,
+ object(0), false, object(), stopCallback));
+ pAnim->start(true);
+ return pAnim;
+}
+
+}
diff --git a/src/anim/LinearAnim.h b/src/anim/LinearAnim.h
new file mode 100644
index 0000000..1b58613
--- /dev/null
+++ b/src/anim/LinearAnim.h
@@ -0,0 +1,60 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _LinearAnim_H_
+#define _LinearAnim_H_
+
+#include "../api.h"
+
+#include "SimpleAnim.h"
+
+namespace avg {
+
+class AVG_API LinearAnim: public SimpleAnim {
+public:
+ LinearAnim(const boost::python::object& node, const std::string& sAttrName,
+ long long duration,
+ const boost::python::object& pStartValue,
+ const boost::python::object& pEndValue,
+ bool bUseInt=false,
+ const boost::python::object& startCallback=boost::python::object(),
+ const boost::python::object& stopCallback=boost::python::object());
+ virtual ~LinearAnim();
+
+protected:
+ virtual float interpolate(float t);
+
+private:
+ float getStartPart(float start, float end, float cur);
+};
+
+AnimPtr fadeIn(const boost::python::object& node, long long duration, float max=1.0f,
+ const boost::python::object& stopCallback=boost::python::object());
+
+AnimPtr fadeOut(const boost::python::object& node, long long duration,
+ const boost::python::object& stopCallback=boost::python::object());
+
+}
+
+#endif
+
+
+
diff --git a/src/anim/Makefile.am b/src/anim/Makefile.am
new file mode 100644
index 0000000..6c37d2a
--- /dev/null
+++ b/src/anim/Makefile.am
@@ -0,0 +1,9 @@
+AM_CPPFLAGS = -I.. @XML2_CFLAGS@ @PYTHON_CPPFLAGS@
+
+ALL_H = Anim.h SimpleAnim.h LinearAnim.h AttrAnim.h ContinuousAnim.h EaseInOutAnim.h \
+ WaitAnim.h ParallelAnim.h StateAnim.h
+ALL_CPP = Anim.cpp SimpleAnim.cpp LinearAnim.cpp AttrAnim.cpp ContinuousAnim.cpp \
+ EaseInOutAnim.cpp WaitAnim.cpp ParallelAnim.cpp StateAnim.cpp
+
+noinst_LTLIBRARIES = libanim.la
+libanim_la_SOURCES = $(ALL_CPP) $(ALL_H)
diff --git a/src/anim/ParallelAnim.cpp b/src/anim/ParallelAnim.cpp
new file mode 100644
index 0000000..0cfe799
--- /dev/null
+++ b/src/anim/ParallelAnim.cpp
@@ -0,0 +1,113 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "ParallelAnim.h"
+
+#include "../player/Player.h"
+
+using namespace boost;
+using namespace boost::python;
+using namespace std;
+
+namespace avg {
+
+ParallelAnim::ParallelAnim(const vector<AnimPtr>& anims,
+ const object& startCallback, const object& stopCallback, long long maxAge)
+ : Anim(startCallback, stopCallback),
+ m_Anims(anims),
+ m_MaxAge(maxAge)
+{
+ vector<AnimPtr>::iterator it;
+ for (it=m_Anims.begin(); it != m_Anims.end(); ++it) {
+ (*it)->setHasParent();
+ }
+}
+
+ParallelAnim::~ParallelAnim()
+{
+ if (Player::exists()) {
+ abort();
+ }
+}
+
+void ParallelAnim::start(bool bKeepAttr)
+{
+ Anim::start();
+ m_StartTime = Player::get()->getFrameTime();
+
+ vector<AnimPtr>::iterator it;
+ for (it=m_Anims.begin(); it != m_Anims.end(); ++it) {
+ (*it)->start(bKeepAttr);
+ if ((*it)->isRunning()) {
+ m_RunningAnims.push_back(*it);
+ }
+ m_This = dynamic_pointer_cast<ParallelAnim>(shared_from_this());
+ }
+}
+
+void ParallelAnim::abort()
+{
+ if (isRunning()) {
+ vector<AnimPtr>::iterator it;
+ for (it=m_RunningAnims.begin(); it != m_RunningAnims.end(); ++it) {
+ (*it)->abort();
+ }
+ m_RunningAnims.clear();
+ setStopped();
+ ParallelAnimPtr tempThis = m_This;
+ m_This = ParallelAnimPtr();
+ tempThis = ParallelAnimPtr();
+ }
+}
+
+bool ParallelAnim::step()
+{
+ assert(isRunning());
+ vector<AnimPtr>::iterator it;
+ for (it=m_RunningAnims.begin(); it != m_RunningAnims.end(); ) {
+ AnimPtr pAnim = (*it);
+ bool bDone;
+ if (pAnim->isRunning()) {
+ bDone = pAnim->step();
+ } else {
+ bDone = true;
+ }
+ if (bDone) {
+ it = m_RunningAnims.erase(it);
+ } else {
+ ++it;
+ }
+ }
+ if (m_RunningAnims.empty()) {
+ setStopped();
+ ParallelAnimPtr tempThis = m_This;
+ m_This = ParallelAnimPtr();
+ tempThis = ParallelAnimPtr();
+ return true;
+ }
+ if (m_MaxAge != -1 && Player::get()->getFrameTime()-m_StartTime >= m_MaxAge) {
+ abort();
+ return true;
+ }
+ return false;
+}
+
+}
diff --git a/src/anim/ParallelAnim.h b/src/anim/ParallelAnim.h
new file mode 100644
index 0000000..44d8e27
--- /dev/null
+++ b/src/anim/ParallelAnim.h
@@ -0,0 +1,64 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _ParallelAnim_H_
+#define _ParallelAnim_H_
+
+#include "../api.h"
+
+#include "Anim.h"
+
+#include <vector>
+
+namespace avg {
+
+class ParallelAnim;
+typedef boost::shared_ptr<class ParallelAnim> ParallelAnimPtr;
+
+class AVG_API ParallelAnim: public Anim {
+public:
+ virtual ~ParallelAnim();
+ ParallelAnim(const std::vector<AnimPtr>& anims,
+ const boost::python::object& startCallback=boost::python::object(),
+ const boost::python::object& stopCallback=boost::python::object(),
+ long long maxAge=-1);
+
+ virtual void start(bool bKeepAttr=false);
+ virtual void abort();
+
+ virtual bool step();
+
+private:
+ std::vector<AnimPtr> m_Anims;
+ std::vector<AnimPtr> m_RunningAnims;
+ long long m_MaxAge;
+
+ long long m_StartTime;
+ ParallelAnimPtr m_This; // Makes sure there is always a reference to the animation
+ // while it's running.
+};
+
+}
+
+#endif
+
+
+
diff --git a/src/anim/SimpleAnim.cpp b/src/anim/SimpleAnim.cpp
new file mode 100644
index 0000000..76ea4ee
--- /dev/null
+++ b/src/anim/SimpleAnim.cpp
@@ -0,0 +1,182 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+
+#include "SimpleAnim.h"
+
+#include "../base/Exception.h"
+#include "../base/MathHelper.h"
+#include "../player/Player.h"
+
+using namespace boost;
+using namespace boost::python;
+using namespace std;
+
+namespace avg {
+
+SimpleAnim::SimpleAnim(const object& node, const string& sAttrName, long long duration,
+ const object& startValue, const object& endValue, bool bUseInt,
+ const object& startCallback, const object& stopCallback)
+ : AttrAnim(node, sAttrName, startCallback, stopCallback),
+ m_Duration(duration),
+ m_StartValue(startValue),
+ m_EndValue(endValue),
+ m_bUseInt(bUseInt)
+{
+}
+
+SimpleAnim::~SimpleAnim()
+{
+ if (Player::exists() && isRunning()) {
+ setStopped();
+ }
+}
+
+void SimpleAnim::start(bool bKeepAttr)
+{
+ AttrAnim::start();
+ if (bKeepAttr) {
+ m_StartTime = calcStartTime();
+ } else {
+ m_StartTime = Player::get()->getFrameTime();
+ }
+ if (m_Duration == 0) {
+ setValue(m_EndValue);
+ remove();
+ } else {
+ step();
+ }
+}
+
+void SimpleAnim::abort()
+{
+ if (isRunning()) {
+ remove();
+ }
+}
+
+template<class T>
+object typedLERP(const object& startValue, const object& endValue, float part)
+{
+ T start = extract<T>(startValue);
+ T end = extract<T>(endValue);
+ T cur = start+(end-start)*part;
+ return object(cur);
+}
+
+bool SimpleAnim::step()
+{
+ assert(isRunning());
+ float t = ((float(Player::get()->getFrameTime())-m_StartTime)
+ /m_Duration);
+ if (t >= 1.0) {
+ setValue(m_EndValue);
+ remove();
+ return true;
+ } else {
+ object curValue;
+ float part = interpolate(t);
+ if (isPythonType<float>(m_StartValue)) {
+ curValue = typedLERP<float>(m_StartValue, m_EndValue, part);
+ if (m_bUseInt) {
+ float d = extract<float>(curValue);
+ curValue = object(round(d));
+ }
+ } else if (isPythonType<glm::vec2>(m_StartValue)) {
+ curValue = typedLERP<glm::vec2>(m_StartValue, m_EndValue, part);
+ if (m_bUseInt) {
+ glm::vec2 pt = extract<glm::vec2>(curValue);
+ curValue = object(glm::vec2(round(pt.x), round(pt.y)));
+ }
+ } else {
+ throw (Exception(AVG_ERR_TYPE,
+ "Animated attributes must be either numbers or Point2D."));
+ }
+ setValue(curValue);
+ return false;
+ }
+}
+
+long long SimpleAnim::getStartTime() const
+{
+ return m_StartTime;
+}
+
+long long SimpleAnim::getDuration() const
+{
+ return m_Duration;
+}
+
+long long SimpleAnim::calcStartTime()
+{
+ float part;
+ if (isPythonType<float>(m_StartValue)) {
+ if (m_EndValue == m_StartValue) {
+ part = 0;
+ } else {
+ part = getStartPart(extract<float>(m_StartValue),
+ extract<float>(m_EndValue), extract<float>(getValue()));
+ }
+ } else if (isPythonType<glm::vec2>(m_StartValue)) {
+ float start = glm::vec2(extract<glm::vec2>(m_StartValue)()).x;
+ float end = glm::vec2(extract<glm::vec2>(m_EndValue)()).x;
+ float cur = glm::vec2(extract<glm::vec2>(getValue())()).x;
+ if (start == end) {
+ start = glm::vec2(extract<glm::vec2>(m_StartValue)()).y;
+ end = glm::vec2(extract<glm::vec2>(m_EndValue)()).y;
+ cur = glm::vec2(extract<glm::vec2>(getValue())()).y;
+ }
+ if (start == end) {
+ part = 0;
+ } else {
+ part = getStartPart(start, end, cur);
+ }
+ } else {
+ throw (Exception(AVG_ERR_TYPE,
+ "Animated attributes must be either numbers or Point2D."));
+ }
+ return Player::get()->getFrameTime()-(long long)(part*getDuration());
+}
+
+float SimpleAnim::getStartPart(float start, float end, float cur)
+{
+ float tstart = 0;
+ float tend = 1;
+ bool bDir = (start < end);
+ for (int i=0; i<10; ++i) {
+ float tmiddle = (tstart+tend)/2;
+ float part = interpolate(tmiddle);
+ float middle = start+(end-start)*part;
+ if ((bDir && middle < cur) || (!bDir && middle >= cur)) {
+ tstart = tmiddle;
+ } else {
+ tend = tmiddle;
+ }
+ }
+ return (tend+tstart)/2;
+}
+
+void SimpleAnim::remove()
+{
+ AnimPtr tempThis = shared_from_this();
+ removeFromMap();
+ setStopped();
+}
+
+}
diff --git a/src/anim/SimpleAnim.h b/src/anim/SimpleAnim.h
new file mode 100644
index 0000000..502505b
--- /dev/null
+++ b/src/anim/SimpleAnim.h
@@ -0,0 +1,79 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _SimpleAnim_H_
+#define _SimpleAnim_H_
+
+#include "../api.h"
+// Python docs say python.h should be included before any standard headers (!)
+#include "../player/WrapPython.h"
+
+#include "AttrAnim.h"
+
+#include <boost/python.hpp>
+
+#include <string>
+#include <map>
+
+namespace avg {
+
+class SimpleAnim;
+typedef boost::shared_ptr<class SimpleAnim> SimpleAnimPtr;
+
+class AVG_API SimpleAnim: public AttrAnim
+{
+public:
+ SimpleAnim(const boost::python::object& node, const std::string& sAttrName,
+ long long duration,
+ const boost::python::object& pStartValue,
+ const boost::python::object& pEndValue,
+ bool bUseInt,
+ const boost::python::object& startCallback,
+ const boost::python::object& stopCallback);
+ virtual ~SimpleAnim()=0;
+
+ virtual void start(bool bKeepAttr=false);
+ virtual void abort();
+ virtual bool step();
+
+protected:
+ virtual float interpolate(float t)=0;
+ void remove();
+
+private:
+ long long getStartTime() const;
+ long long getDuration() const;
+ long long calcStartTime();
+ virtual float getStartPart(float start, float end, float cur);
+
+ long long m_Duration;
+ boost::python::object m_StartValue;
+ boost::python::object m_EndValue;
+ bool m_bUseInt;
+ long long m_StartTime;
+};
+
+}
+
+#endif
+
+
+
diff --git a/src/anim/StateAnim.cpp b/src/anim/StateAnim.cpp
new file mode 100644
index 0000000..4858c23
--- /dev/null
+++ b/src/anim/StateAnim.cpp
@@ -0,0 +1,123 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "StateAnim.h"
+
+#include "../base/Exception.h"
+#include "../player/Player.h"
+
+using namespace boost::python;
+using namespace std;
+
+namespace avg {
+
+AnimState::AnimState(const string& sName, AnimPtr pAnim, const string& sNextName)
+ : m_sName(sName),
+ m_pAnim(pAnim),
+ m_sNextName(sNextName)
+{
+}
+
+AnimState::AnimState()
+{
+}
+
+StateAnim::StateAnim(const vector<AnimState>& states)
+ : Anim(object(), object()),
+ m_bDebug(false)
+{
+ vector<AnimState>::const_iterator it;
+ for (it=states.begin(); it != states.end(); ++it) {
+ m_States[(*it).m_sName] = *it;
+ it->m_pAnim->setHasParent();
+ }
+}
+
+StateAnim::~StateAnim()
+{
+ setState("");
+}
+
+void StateAnim::abort()
+{
+ setState("");
+}
+
+void StateAnim::setState(const std::string& sName, bool bKeepAttr)
+{
+ if (m_sCurStateName == sName) {
+ return;
+ }
+ if (!m_sCurStateName.empty()) {
+ m_States[m_sCurStateName].m_pAnim->abort();
+ }
+ switchToNewState(sName, bKeepAttr);
+}
+
+const std::string& StateAnim::getState() const
+{
+ return m_sCurStateName;
+}
+
+void StateAnim::setDebug(bool bDebug)
+{
+ m_bDebug = bDebug;
+}
+
+bool StateAnim::step()
+{
+ // Make sure the object isn't deleted until the end of the method.
+ AnimPtr tempThis = shared_from_this();
+
+ if (!m_sCurStateName.empty()) {
+ const AnimState& curState = m_States[m_sCurStateName];
+ bool bDone = curState.m_pAnim->step();
+ if (bDone) {
+ switchToNewState(curState.m_sNextName, false);
+ }
+ }
+ return false;
+}
+
+void StateAnim::switchToNewState(const string& sName, bool bKeepAttr)
+{
+ if (m_bDebug) {
+ cerr << this << " State change: '" << m_sCurStateName << "' --> '" << sName
+ << "'" << endl;
+ }
+ string sOldStateName = m_sCurStateName;
+ m_sCurStateName = sName;
+ if (!sName.empty()) {
+ map<string, AnimState>::iterator it = m_States.find(sName);
+ if (it == m_States.end()) {
+ throw Exception(AVG_ERR_INVALID_ARGS, "StateAnim: State "+sName+" unknown.");
+ } else {
+ it->second.m_pAnim->start(bKeepAttr);
+ }
+ if (sOldStateName == "") {
+ Anim::start(false);
+ }
+ } else {
+ Anim::setStopped();
+ }
+}
+
+}
diff --git a/src/anim/StateAnim.h b/src/anim/StateAnim.h
new file mode 100644
index 0000000..135668a
--- /dev/null
+++ b/src/anim/StateAnim.h
@@ -0,0 +1,69 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _StateAnim_H_
+#define _StateAnim_H_
+
+#include "../api.h"
+
+#include "Anim.h"
+
+#include <vector>
+#include <map>
+
+namespace avg {
+
+struct AVG_API AnimState {
+ AnimState(const std::string& sName, AnimPtr pAnim, const std::string& sNextName = "");
+ AnimState();
+
+ std::string m_sName;
+ AnimPtr m_pAnim;
+ std::string m_sNextName;
+};
+
+class AVG_API StateAnim: public Anim {
+public:
+ StateAnim(const std::vector<AnimState>& states);
+ virtual ~StateAnim();
+
+ virtual void abort();
+
+ virtual void setState(const std::string& sName, bool bKeepAttr=false);
+ const std::string& getState() const;
+ void setDebug(bool bDebug);
+
+ virtual bool step();
+
+private:
+ void switchToNewState(const std::string& sName, bool bKeepAttr);
+
+ std::map<std::string, AnimState> m_States;
+ bool m_bDebug;
+ std::string m_sCurStateName;
+};
+
+}
+
+#endif
+
+
+
diff --git a/src/anim/WaitAnim.cpp b/src/anim/WaitAnim.cpp
new file mode 100644
index 0000000..7509504
--- /dev/null
+++ b/src/anim/WaitAnim.cpp
@@ -0,0 +1,69 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "WaitAnim.h"
+
+#include "../player/Player.h"
+
+using namespace boost;
+using namespace boost::python;
+using namespace std;
+
+namespace avg {
+
+WaitAnim::WaitAnim(long long duration, const object& startCallback,
+ const object& stopCallback)
+ : Anim(startCallback, stopCallback),
+ m_Duration(duration)
+{
+}
+
+WaitAnim::~WaitAnim()
+{
+}
+
+void WaitAnim::start(bool bKeepAttr)
+{
+ m_pThis = dynamic_pointer_cast<WaitAnim>(shared_from_this());
+ Anim::start();
+ m_StartTime = Player::get()->getFrameTime();
+}
+
+void WaitAnim::abort()
+{
+ setStopped();
+ m_pThis = WaitAnimPtr();
+}
+
+bool WaitAnim::step()
+{
+ assert(isRunning());
+ if (m_Duration != -1 && Player::get()->getFrameTime()-m_StartTime > m_Duration) {
+ setStopped();
+ m_pThis = WaitAnimPtr();
+ return true;
+ } else {
+ return false;
+ }
+
+}
+
+}
diff --git a/src/anim/WaitAnim.h b/src/anim/WaitAnim.h
new file mode 100644
index 0000000..e90daf2
--- /dev/null
+++ b/src/anim/WaitAnim.h
@@ -0,0 +1,57 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _WaitAnim_H_
+#define _WaitAnim_H_
+
+#include "../api.h"
+
+#include "SimpleAnim.h"
+
+namespace avg {
+
+class WaitAnim;
+typedef boost::shared_ptr<class WaitAnim> WaitAnimPtr;
+
+class AVG_API WaitAnim: public Anim {
+public:
+ WaitAnim(long long duration = -1,
+ const boost::python::object& startCallback=boost::python::object(),
+ const boost::python::object& stopCallback=boost::python::object());
+ virtual ~WaitAnim();
+
+ virtual void start(bool bKeepAttr=false);
+ virtual void abort();
+
+ virtual bool step();
+
+private:
+ long long m_Duration;
+ long long m_StartTime;
+ WaitAnimPtr m_pThis; // Make sure we're not deleted while running.
+};
+
+}
+
+#endif
+
+
+
diff --git a/src/api.h b/src/api.h
new file mode 100644
index 0000000..cd6001b
--- /dev/null
+++ b/src/api.h
@@ -0,0 +1,50 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+// Original author of this file is Jan Boelsche (regular.gonzales@googlemail.com).
+//
+
+#ifndef _API_H_
+#define _API_H_
+
+#ifdef _WIN32 // in declspec land
+#pragma warning(disable: 4251)
+#define AVG_PLUGIN_API extern "C" __declspec(dllexport)
+#ifdef AVG_PLUGIN
+#define AVG_API __declspec(dllimport)
+#define AVG_TEMPLATE_API
+#else
+#define AVG_API __declspec(dllexport)
+#define AVG_TEMPLATE_API __declspec(dllexport)
+#endif
+#else // not _WIN32, plain and simple
+#define AVG_API
+#define AVG_TEMPLATE_API
+#define AVG_PLUGIN_API extern "C"
+#endif
+
+#ifdef __APPLE__
+// Workaround for snow leopard incompatibility between c++ headers and python headers:
+// <iostream> always needs to be included before Python.h.
+#include <iostream>
+#endif
+
+#endif
+
diff --git a/src/audio/AudioBuffer.cpp b/src/audio/AudioBuffer.cpp
new file mode 100644
index 0000000..64032c3
--- /dev/null
+++ b/src/audio/AudioBuffer.cpp
@@ -0,0 +1,105 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+// Original author of this file is Nick Hebner (hebnern@gmail.com).
+//
+
+#include "AudioBuffer.h"
+
+#include <string>
+#include <cstring>
+
+#define VOLUME_FADE_SAMPLES 100
+
+namespace avg {
+
+AudioBuffer::AudioBuffer(int numFrames, AudioParams ap)
+ : m_NumFrames(numFrames),
+ m_AP(ap)
+{
+ m_pData = new short[numFrames*sizeof(short)*ap.m_Channels];
+}
+
+AudioBuffer::~AudioBuffer()
+{
+ delete[] m_pData;
+}
+
+short* AudioBuffer::getData()
+{
+ return m_pData;
+}
+
+int AudioBuffer::getNumFrames()
+{
+ return m_NumFrames;
+}
+
+int AudioBuffer::getNumBytes()
+{
+ return m_NumFrames*m_AP.m_Channels*sizeof(short);
+}
+
+int AudioBuffer::getFrameSize()
+{
+ return m_AP.m_Channels*sizeof(short);
+}
+
+int AudioBuffer::getNumChannels()
+{
+ return m_AP.m_Channels;
+}
+
+int AudioBuffer::getRate()
+{
+ return m_AP.m_SampleRate;
+}
+
+void AudioBuffer::clear()
+{
+ memset(m_pData, 0, m_NumFrames*sizeof(short)*m_AP.m_Channels);
+}
+
+void AudioBuffer::volumize(float lastVol, float curVol)
+{
+ float volDiff = lastVol - curVol;
+
+ if (curVol == 1.0f && volDiff == 0.0f) {
+ return;
+ }
+
+ for (int i = 0; i < m_NumFrames*m_AP.m_Channels; i++) {
+ float fadeVol = 0;
+ if (volDiff != 0 && i < VOLUME_FADE_SAMPLES) {
+ fadeVol = volDiff * (VOLUME_FADE_SAMPLES - i) / VOLUME_FADE_SAMPLES;
+ }
+
+ int s = int(m_pData[i] * (curVol + fadeVol));
+
+ if (s < -32768)
+ s = -32768;
+ if (s > 32767)
+ s = 32767;
+
+ m_pData[i] = s;
+ }
+}
+
+}
diff --git a/src/audio/AudioBuffer.h b/src/audio/AudioBuffer.h
new file mode 100644
index 0000000..1dbf068
--- /dev/null
+++ b/src/audio/AudioBuffer.h
@@ -0,0 +1,61 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+// Original author of this file is Nick Hebner (hebnern@gmail.com).
+//
+
+#ifndef _AudioBuffer_H_
+#define _AudioBuffer_H_
+
+#include "../api.h"
+#include "AudioParams.h"
+
+#include <boost/shared_ptr.hpp>
+
+namespace avg
+{
+
+class AVG_API AudioBuffer
+{
+ public:
+ AudioBuffer(int numFrames, AudioParams ap);
+ virtual ~AudioBuffer();
+
+ short* getData();
+ int getNumFrames();
+ int getNumBytes();
+ int getFrameSize();
+ int getNumChannels();
+ int getRate();
+ void clear();
+
+ void volumize(float lastVol, float curVol);
+
+ private:
+ int m_NumFrames;
+ short* m_pData;
+ AudioParams m_AP;
+};
+
+typedef boost::shared_ptr<AudioBuffer> AudioBufferPtr;
+
+}
+
+#endif
diff --git a/src/audio/AudioEngine.cpp b/src/audio/AudioEngine.cpp
new file mode 100644
index 0000000..aad1b9f
--- /dev/null
+++ b/src/audio/AudioEngine.cpp
@@ -0,0 +1,295 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+// Original author of this file is Nick Hebner (hebnern@gmail.com).
+//
+
+#include "AudioEngine.h"
+
+#include "Dynamics.h"
+
+#include "../base/Exception.h"
+#include "../base/Logger.h"
+
+#include <iostream>
+
+using namespace std;
+using namespace boost;
+
+namespace avg {
+
+AudioEngine* AudioEngine::s_pInstance = 0;
+
+AudioEngine* AudioEngine::get()
+{
+ return s_pInstance;
+}
+
+AudioEngine::AudioEngine()
+ : m_pTempBuffer(),
+ m_pMixBuffer(0),
+ m_pLimiter(0),
+ m_bEnabled(true),
+ m_Volume(1)
+{
+ AVG_ASSERT(s_pInstance == 0);
+ if (SDL_InitSubSystem(SDL_INIT_AUDIO) == -1) {
+ AVG_LOG_ERROR("Can't init SDL audio subsystem.");
+ exit(-1);
+ }
+ s_pInstance = this;
+}
+
+AudioEngine::~AudioEngine()
+{
+ if (m_pMixBuffer) {
+ delete[] m_pMixBuffer;
+ }
+ SDL_QuitSubSystem(SDL_INIT_AUDIO);
+ m_AudioSources.clear();
+}
+
+int AudioEngine::getChannels()
+{
+ return m_AP.m_Channels;
+}
+
+int AudioEngine::getSampleRate()
+{
+ return m_AP.m_SampleRate;
+}
+
+const AudioParams * AudioEngine::getParams()
+{
+ if (isEnabled()) {
+ return &m_AP;
+ } else {
+ return 0;
+ }
+}
+
+void AudioEngine::init(const AudioParams& ap, float volume)
+{
+ m_Volume = volume;
+ m_AP = ap;
+ Dynamics<float, 2>* pLimiter = new Dynamics<float, 2>(float(m_AP.m_SampleRate));
+ pLimiter->setThreshold(0.f); // in dB
+ pLimiter->setAttackTime(0.f); // in seconds
+ pLimiter->setReleaseTime(0.05f); // in seconds
+ pLimiter->setRmsTime(0.f); // in seconds
+ pLimiter->setRatio(std::numeric_limits<float>::infinity());
+ pLimiter->setMakeupGain(0.f); // in dB
+ m_pLimiter = pLimiter;
+
+ SDL_AudioSpec desired;
+ desired.freq = m_AP.m_SampleRate;
+ desired.format = AUDIO_S16SYS;
+ desired.channels = m_AP.m_Channels;
+ desired.silence = 0;
+ desired.samples = m_AP.m_OutputBufferSamples;
+ desired.callback = audioCallback;
+ desired.userdata = this;
+
+ int err = SDL_OpenAudio(&desired, 0);
+ if (err < 0) {
+ static bool bWarned = false;
+ if (!bWarned) {
+ AVG_TRACE(Logger::category::CONFIG, Logger::severity::WARNING,
+ "Can't open audio: " << SDL_GetError());
+ bWarned = true;
+ }
+ }
+}
+
+void AudioEngine::teardown()
+{
+ {
+ lock_guard lock(m_Mutex);
+ SDL_PauseAudio(1);
+ }
+ // Optimized away - takes too long.
+// SDL_CloseAudio();
+
+ m_AudioSources.clear();
+ if (m_pLimiter) {
+ delete m_pLimiter;
+ m_pLimiter = 0;
+ }
+}
+
+void AudioEngine::setAudioEnabled(bool bEnabled)
+{
+ SDL_LockAudio();
+ lock_guard lock(m_Mutex);
+ AVG_ASSERT(m_AudioSources.empty());
+ m_bEnabled = bEnabled;
+ if (m_bEnabled) {
+ play();
+ } else {
+ pause();
+ }
+ SDL_UnlockAudio();
+}
+
+void AudioEngine::play()
+{
+ SDL_PauseAudio(0);
+}
+
+void AudioEngine::pause()
+{
+ SDL_PauseAudio(1);
+}
+
+int AudioEngine::addSource(AudioMsgQueue& dataQ, AudioMsgQueue& statusQ)
+{
+ SDL_LockAudio();
+ lock_guard lock(m_Mutex);
+ static int nextID = -1;
+ nextID++;
+ AudioSourcePtr pSrc(new AudioSource(dataQ, statusQ, m_AP.m_SampleRate));
+ m_AudioSources[nextID] = pSrc;
+ SDL_UnlockAudio();
+ return nextID;
+}
+
+void AudioEngine::removeSource(int id)
+{
+ SDL_LockAudio();
+ lock_guard lock(m_Mutex);
+ int numErased = m_AudioSources.erase(id);
+ AVG_ASSERT(numErased == 1);
+ SDL_UnlockAudio();
+}
+
+void AudioEngine::pauseSource(int id)
+{
+ lock_guard lock(m_Mutex);
+ AudioSourceMap::iterator itSource = m_AudioSources.find(id);
+ AVG_ASSERT(itSource != m_AudioSources.end());
+ AudioSourcePtr pSource = itSource->second;
+ pSource->pause();
+}
+
+void AudioEngine::playSource(int id)
+{
+ lock_guard lock(m_Mutex);
+ AudioSourceMap::iterator itSource = m_AudioSources.find(id);
+ AVG_ASSERT(itSource != m_AudioSources.end());
+ AudioSourcePtr pSource = itSource->second;
+ pSource->play();
+}
+
+void AudioEngine::notifySeek(int id)
+{
+ lock_guard lock(m_Mutex);
+ AudioSourceMap::iterator itSource = m_AudioSources.find(id);
+ AVG_ASSERT(itSource != m_AudioSources.end());
+ AudioSourcePtr pSource = itSource->second;
+ pSource->notifySeek();
+}
+
+void AudioEngine::setSourceVolume(int id, float volume)
+{
+ lock_guard lock(m_Mutex);
+ AudioSourceMap::iterator itSource = m_AudioSources.find(id);
+ AVG_ASSERT(itSource != m_AudioSources.end());
+ AudioSourcePtr pSource = itSource->second;
+ pSource->setVolume(volume);
+}
+
+void AudioEngine::setVolume(float volume)
+{
+ SDL_LockAudio();
+ lock_guard lock(m_Mutex);
+ m_Volume = volume;
+ SDL_UnlockAudio();
+}
+
+float AudioEngine::getVolume() const
+{
+ return m_Volume;
+}
+
+bool AudioEngine::isEnabled() const
+{
+ return m_bEnabled;
+}
+
+void AudioEngine::mixAudio(Uint8 *pDestBuffer, int destBufferLen)
+{
+ int numFrames = destBufferLen/(2*getChannels()); // 16 bit samples.
+
+ if (m_AudioSources.size() == 0) {
+ return;
+ }
+ if (!m_pTempBuffer || m_pTempBuffer->getNumFrames() < numFrames) {
+ if (m_pTempBuffer) {
+ delete[] m_pMixBuffer;
+ }
+ m_pTempBuffer = AudioBufferPtr(new AudioBuffer(numFrames, m_AP));
+ m_pMixBuffer = new float[getChannels()*numFrames];
+ }
+
+ for (int i = 0; i < getChannels()*numFrames; ++i) {
+ m_pMixBuffer[i]=0;
+ }
+ {
+ lock_guard lock(m_Mutex);
+ AudioSourceMap::iterator it;
+ for (it = m_AudioSources.begin(); it != m_AudioSources.end(); it++) {
+ m_pTempBuffer->clear();
+ it->second->fillAudioBuffer(m_pTempBuffer);
+ addBuffers(m_pMixBuffer, m_pTempBuffer);
+ }
+ }
+ calcVolume(m_pMixBuffer, numFrames*getChannels(), getVolume());
+ for (int i = 0; i < numFrames; ++i) {
+ m_pLimiter->process(m_pMixBuffer+i*getChannels());
+ for (int j = 0; j < getChannels(); ++j) {
+ ((short*)pDestBuffer)[i*2+j]=short(m_pMixBuffer[i*2+j]*32768);
+ }
+ }
+}
+
+void AudioEngine::audioCallback(void *userData, Uint8 *audioBuffer, int audioBufferLen)
+{
+ AudioEngine *pThis = (AudioEngine*)userData;
+ pThis->mixAudio(audioBuffer, audioBufferLen);
+}
+
+void AudioEngine::addBuffers(float *pDest, AudioBufferPtr pSrc)
+{
+ int numFrames = pSrc->getNumFrames();
+ short * pData = pSrc->getData();
+ for(int i = 0; i < numFrames*getChannels(); ++i) {
+ pDest[i] += pData[i]/32768.0f;
+ }
+}
+
+void AudioEngine::calcVolume(float *pBuffer, int numSamples, float volume)
+{
+ // TODO: We need a VolumeFader class that keeps state.
+ for(int i = 0; i < numSamples; ++i) {
+ pBuffer[i] *= volume;
+ }
+}
+
+}
diff --git a/src/audio/AudioEngine.h b/src/audio/AudioEngine.h
new file mode 100644
index 0000000..bb93196
--- /dev/null
+++ b/src/audio/AudioEngine.h
@@ -0,0 +1,94 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+// Original author of this file is Nick Hebner (hebnern@gmail.com).
+//
+
+#ifndef _AudioEngine_H_
+#define _AudioEngine_H_
+
+#include "../api.h"
+#include "AudioSource.h"
+#include "AudioParams.h"
+#include "AudioBuffer.h"
+#include "IProcessor.h"
+
+#include <SDL/SDL.h>
+
+#include <boost/thread/mutex.hpp>
+
+#include <map>
+
+namespace avg {
+
+typedef std::map<int, AudioSourcePtr> AudioSourceMap;
+
+class AVG_API AudioEngine
+{
+ public:
+ static AudioEngine* get();
+ AudioEngine();
+ virtual ~AudioEngine();
+
+ int getChannels();
+ int getSampleRate();
+ const AudioParams * getParams();
+
+ void setAudioEnabled(bool bEnabled);
+
+ void init(const AudioParams& ap, float volume);
+ void teardown();
+
+ void play();
+ void pause();
+
+ int addSource(AudioMsgQueue& dataQ, AudioMsgQueue& statusQ);
+ void removeSource(int id);
+ void pauseSource(int id);
+ void playSource(int id);
+ void notifySeek(int id);
+ void setSourceVolume(int id, float volume);
+
+ void setVolume(float volume);
+ float getVolume() const;
+ bool isEnabled() const;
+
+ private:
+ void mixAudio(Uint8 *pDestBuffer, int destBufferLen);
+ static void audioCallback(void *userData, Uint8 *audioBuffer, int audioBufferLen);
+ void addBuffers(float *pDest, AudioBufferPtr pSrc);
+ void calcVolume(float *pBuffer, int numSamples, float volume);
+
+ AudioParams m_AP;
+ AudioBufferPtr m_pTempBuffer;
+ float * m_pMixBuffer;
+ IProcessor<float>* m_pLimiter;
+ boost::mutex m_Mutex;
+
+ bool m_bEnabled;
+ AudioSourceMap m_AudioSources;
+ float m_Volume;
+
+ static AudioEngine* s_pInstance;
+};
+
+}
+
+#endif
diff --git a/src/audio/AudioMsg.cpp b/src/audio/AudioMsg.cpp
new file mode 100644
index 0000000..2e1d6df
--- /dev/null
+++ b/src/audio/AudioMsg.cpp
@@ -0,0 +1,165 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "AudioMsg.h"
+
+#include "../base/ObjectCounter.h"
+#include "../base/Exception.h"
+
+#include <iostream>
+
+using namespace std;
+
+namespace avg {
+
+AudioMsg::AudioMsg()
+ : m_MsgType(NONE)
+{
+ ObjectCounter::get()->incRef(&typeid(*this));
+}
+
+AudioMsg::~AudioMsg()
+{
+ ObjectCounter::get()->decRef(&typeid(*this));
+}
+
+void AudioMsg::setAudio(AudioBufferPtr pAudioBuffer, float audioTime)
+{
+ AVG_ASSERT(pAudioBuffer);
+ setType(AUDIO);
+ m_pAudioBuffer = pAudioBuffer;
+ m_AudioTime = audioTime;
+}
+
+void AudioMsg::setAudioTime(float audioTime)
+{
+ setType(AUDIO_TIME);
+ m_AudioTime = audioTime;
+}
+
+void AudioMsg::setEOF()
+{
+ setType(END_OF_FILE);
+}
+
+void AudioMsg::setError(const Exception& ex)
+{
+ setType(ERROR);
+ m_pEx = new Exception(ex);
+}
+
+void AudioMsg::setSeekDone(int seqNum, float seekTime)
+{
+ setType(SEEK_DONE);
+ AVG_ASSERT(seqNum != -1);
+ m_SeekSeqNum = seqNum;
+ m_SeekTime = seekTime;
+}
+
+void AudioMsg::setClosed()
+{
+ setType(CLOSED);
+}
+
+AudioMsg::MsgType AudioMsg::getType()
+{
+ return m_MsgType;
+}
+
+AudioBufferPtr AudioMsg::getAudioBuffer() const
+{
+ AVG_ASSERT(m_MsgType == AUDIO);
+ return m_pAudioBuffer;
+}
+
+float AudioMsg::getAudioTime() const
+{
+ AVG_ASSERT(m_MsgType == AUDIO_TIME || m_MsgType == AUDIO);
+ return m_AudioTime;
+}
+
+const Exception& AudioMsg::getException() const
+{
+ AVG_ASSERT(m_MsgType == ERROR);
+ return *m_pEx;
+}
+
+int AudioMsg::getSeekSeqNum()
+{
+ AVG_ASSERT(m_MsgType == SEEK_DONE);
+ return m_SeekSeqNum;
+}
+
+float AudioMsg::getSeekTime()
+{
+ AVG_ASSERT(m_MsgType == SEEK_DONE);
+ return m_SeekTime;
+}
+
+void AudioMsg::dump()
+{
+ switch (m_MsgType) {
+ case NONE:
+ cerr << "NONE" << endl;
+ break;
+ case AUDIO:
+ cerr << "AUDIO" << endl;
+ break;
+ case AUDIO_TIME:
+ cerr << "AUDIO_TIME" << endl;
+ break;
+ case END_OF_FILE:
+ cerr << "END_OF_FILE" << endl;
+ break;
+ case ERROR:
+ cerr << "ERROR" << endl;
+ break;
+ case FRAME:
+ cerr << "FRAME" << endl;
+ break;
+ case VDPAU_FRAME:
+ cerr << "VDPAU_FRAME" << endl;
+ break;
+ case SEEK_DONE:
+ cerr << "SEEK_DONE" << endl;
+ break;
+ case PACKET:
+ cerr << "PACKET" << endl;
+ break;
+ case CLOSED:
+ cerr << "CLOSED" << endl;
+ break;
+ default:
+ AVG_ASSERT(false);
+ break;
+ }
+}
+
+void AudioMsg::setType(MsgType msgType)
+{
+ AVG_ASSERT(m_MsgType == NONE);
+ m_MsgType = msgType;
+}
+
+
+
+}
+
diff --git a/src/audio/AudioMsg.h b/src/audio/AudioMsg.h
new file mode 100644
index 0000000..89895e3
--- /dev/null
+++ b/src/audio/AudioMsg.h
@@ -0,0 +1,85 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _AudioMsg_H_
+#define _AudioMsg_H_
+
+#include "../api.h"
+#include "../base/Queue.h"
+
+#include "AudioBuffer.h"
+
+#include <boost/shared_ptr.hpp>
+
+namespace avg {
+
+class AVG_API AudioMsg {
+public:
+ enum MsgType {NONE, AUDIO, AUDIO_TIME, END_OF_FILE, ERROR, FRAME, VDPAU_FRAME,
+ SEEK_DONE, PACKET, CLOSED};
+ AudioMsg();
+ void setAudio(AudioBufferPtr pAudioBuffer, float audioTime);
+ void setAudioTime(float audioTime);
+ void setEOF();
+ void setError(const Exception& ex);
+ void setSeekDone(int seqNum, float seekTime);
+ void setClosed();
+
+ virtual ~AudioMsg();
+
+ MsgType getType();
+
+ AudioBufferPtr getAudioBuffer() const;
+ float getAudioTime() const;
+
+ const Exception& getException() const;
+
+ int getSeekSeqNum();
+ float getSeekTime();
+
+ virtual void dump();
+
+protected:
+ void setType(MsgType msgType);
+
+private:
+ MsgType m_MsgType;
+
+ // AUDIO
+ AudioBufferPtr m_pAudioBuffer;
+ float m_AudioTime;
+
+ // ERROR
+ Exception* m_pEx;
+
+ // SEEK_DONE
+ int m_SeekSeqNum;
+ float m_SeekTime;
+
+};
+
+typedef boost::shared_ptr<AudioMsg> AudioMsgPtr;
+typedef Queue<AudioMsg> AudioMsgQueue;
+typedef boost::shared_ptr<AudioMsgQueue> AudioMsgQueuePtr;
+
+}
+#endif
+
diff --git a/src/audio/AudioParams.cpp b/src/audio/AudioParams.cpp
new file mode 100644
index 0000000..eee3768
--- /dev/null
+++ b/src/audio/AudioParams.cpp
@@ -0,0 +1,40 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+// Original author of this file is Nick Hebner (hebnern@gmail.com).
+//
+
+#include "AudioParams.h"
+
+#include "../base/ObjectCounter.h"
+
+namespace avg {
+ AudioParams::AudioParams()
+ {
+ }
+
+ AudioParams::AudioParams(int sampleRate, int channels, int outputBufferSamples)
+ : m_SampleRate(sampleRate),
+ m_Channels(channels),
+ m_OutputBufferSamples(outputBufferSamples)
+ {
+ }
+}
+
diff --git a/src/audio/AudioParams.h b/src/audio/AudioParams.h
new file mode 100644
index 0000000..5e04b1d
--- /dev/null
+++ b/src/audio/AudioParams.h
@@ -0,0 +1,39 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+// Original author of this file is Nick Hebner (hebnern@gmail.com).
+//
+
+#ifndef _AudioParams_H_
+#define _AudioParams_H_
+
+namespace avg {
+
+struct AudioParams {
+ AudioParams();
+ AudioParams(int sampleRate, int channels, int outputBufferSamples);
+ int m_SampleRate;
+ int m_Channels;
+ int m_OutputBufferSamples;
+};
+
+}
+
+#endif
diff --git a/src/audio/AudioSource.cpp b/src/audio/AudioSource.cpp
new file mode 100644
index 0000000..7f6ae4a
--- /dev/null
+++ b/src/audio/AudioSource.cpp
@@ -0,0 +1,156 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "AudioSource.h"
+#include "AudioEngine.h"
+
+#include <string>
+#include <algorithm>
+
+using namespace std;
+
+namespace avg {
+
+AudioSource::AudioSource(AudioMsgQueue& msgQ, AudioMsgQueue& statusQ, int sampleRate)
+ : m_MsgQ(msgQ),
+ m_StatusQ(statusQ),
+ m_SampleRate(sampleRate),
+ m_bPaused(false),
+ m_bSeeking(false),
+ m_Volume(1.0),
+ m_LastVolume(1.0)
+{
+}
+
+AudioSource::~AudioSource()
+{
+}
+
+void AudioSource::pause()
+{
+ m_bPaused = true;
+}
+
+void AudioSource::play()
+{
+ m_bPaused = false;
+}
+
+void AudioSource::notifySeek()
+{
+ while (m_bSeeking) {
+ processNextMsg(true);
+ }
+ m_bSeeking = true;
+}
+
+void AudioSource::setVolume(float volume)
+{
+ m_Volume = volume;
+}
+
+void AudioSource::fillAudioBuffer(AudioBufferPtr pBuffer)
+{
+ bool bContinue = true;
+ while (bContinue && m_bSeeking) {
+ bContinue = processNextMsg(false);
+ }
+ if (!m_bPaused) {
+ unsigned char* pDest = (unsigned char *)(pBuffer->getData());
+ int framesLeftToFill = pBuffer->getNumFrames();
+ AudioMsgPtr pMsg;
+ while (framesLeftToFill > 0) {
+ int framesLeftInBuffer = 0;
+ if (m_pInputAudioBuffer) {
+ framesLeftInBuffer = m_pInputAudioBuffer->getNumFrames()
+ - m_CurInputAudioPos;
+ }
+ while (framesLeftInBuffer > 0 && framesLeftToFill > 0) {
+ int framesToCopy = min(framesLeftToFill, framesLeftInBuffer);
+ // cerr << "framesToCopy: " << framesToCopy << endl;
+ char * pInputPos = (char*)m_pInputAudioBuffer->getData() +
+ m_CurInputAudioPos*pBuffer->getFrameSize();
+ int bytesToCopy = framesToCopy*pBuffer->getFrameSize();
+ memcpy(pDest, pInputPos, bytesToCopy);
+ m_CurInputAudioPos += framesToCopy;
+ framesLeftToFill -= framesToCopy;
+ framesLeftInBuffer -= framesToCopy;
+ pDest += bytesToCopy;
+
+ m_LastTime += framesToCopy/m_SampleRate;
+ // cerr << " " << m_LastTime << endl;
+ }
+ if (framesLeftToFill != 0) {
+ bool bContinue = processNextMsg(false);
+ if (!bContinue) {
+ framesLeftToFill = 0;
+ }
+ }
+ }
+ pBuffer->volumize(m_LastVolume, m_Volume);
+ m_LastVolume = m_Volume;
+
+ AudioMsgPtr pStatusMsg(new AudioMsg);
+ pStatusMsg->setAudioTime(m_LastTime);
+ m_StatusQ.push(pStatusMsg);
+ }
+}
+
+bool AudioSource::processNextMsg(bool bWait)
+{
+ AudioMsgPtr pMsg = m_MsgQ.pop(bWait);
+ if (pMsg) {
+ switch (pMsg->getType()) {
+ case AudioMsg::AUDIO:
+ m_pInputAudioBuffer = pMsg->getAudioBuffer();
+ m_CurInputAudioPos = 0;
+ m_LastTime = pMsg->getAudioTime();
+// cerr << " New buffer: " << m_LastTime << endl;
+ return true;
+ case AudioMsg::END_OF_FILE: {
+// cerr << " AudioSource: EOF" << endl;
+ m_bSeeking = false;
+ AudioMsgPtr pStatusMsg(new AudioMsg);
+ pStatusMsg->setEOF();
+ m_StatusQ.push(pStatusMsg);
+ return false;
+ }
+ case AudioMsg::SEEK_DONE: {
+// cerr << " AudioSource: SEEK_DONE" << endl;
+ m_bSeeking = false;
+ m_pInputAudioBuffer = AudioBufferPtr();
+ m_LastTime = pMsg->getSeekTime();
+ AudioMsgPtr pStatusMsg(new AudioMsg);
+ pStatusMsg->setSeekDone(pMsg->getSeekSeqNum(), m_LastTime);
+ m_StatusQ.push(pStatusMsg);
+ return true;
+ }
+ default:
+ AVG_ASSERT(false);
+ return false;
+ }
+ } else {
+ // cerr << "no pop" << endl;
+ return false;
+ }
+}
+
+}
diff --git a/src/audio/AudioSource.h b/src/audio/AudioSource.h
new file mode 100644
index 0000000..f90daed
--- /dev/null
+++ b/src/audio/AudioSource.h
@@ -0,0 +1,66 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _AudioSource_H_
+#define _AudioSource_H_
+
+#include "../api.h"
+
+#include "AudioMsg.h"
+
+#include <boost/shared_ptr.hpp>
+
+namespace avg
+{
+
+class AVG_API AudioSource
+{
+public:
+ AudioSource(AudioMsgQueue& msgQ, AudioMsgQueue& statusQ, int sampleRate);
+ virtual ~AudioSource();
+
+ void pause();
+ void play();
+ void notifySeek();
+ void setVolume(float volume);
+
+ void fillAudioBuffer(AudioBufferPtr pBuffer);
+
+private:
+ bool processNextMsg(bool bWait);
+
+ AudioMsgQueue& m_MsgQ;
+ AudioMsgQueue& m_StatusQ;
+ int m_SampleRate;
+ AudioBufferPtr m_pInputAudioBuffer;
+ float m_LastTime;
+ int m_CurInputAudioPos;
+ bool m_bPaused;
+ bool m_bSeeking;
+ float m_Volume;
+ float m_LastVolume;
+};
+
+typedef boost::shared_ptr<AudioSource> AudioSourcePtr;
+
+}
+
+#endif
diff --git a/src/audio/Dynamics.h b/src/audio/Dynamics.h
new file mode 100644
index 0000000..e5293e5
--- /dev/null
+++ b/src/audio/Dynamics.h
@@ -0,0 +1,343 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+// Original author of this file is Andreas Beisler.
+//
+
+#pragma once
+#ifndef __Dynamics_H__
+#define __Dynamics_H__
+
+#include "../api.h"
+#include "IProcessor.h"
+
+#include <math.h>
+#include <cmath>
+#include <limits>
+#include <memory.h>
+
+#define LOOKAHEAD 64
+#define AVG1 27
+#define AVG2 38
+
+namespace avg {
+
+// Dynamics processor (compressor & limiter).
+template<typename T, int CHANNELS>
+class AVG_API Dynamics: public IProcessor<T>
+{
+ public:
+ Dynamics(T fs);
+ virtual ~Dynamics();
+ virtual void process(T* pSamples);
+
+ void setThreshold(T threshold);
+ T getThreshold() const;
+ void setRmsTime(T rmsTime);
+ T getRmsTime() const;
+ void setRatio(T ratio);
+ T getRatio() const;
+ void setAttackTime(T attTime);
+ T getAttackTime() const;
+ void setReleaseTime(T relTime);
+ T getReleaseTime() const;
+ void setMakeupGain(T makeupGain);
+ T getMakeupGain() const;
+
+ private:
+ void maxFilter(T& rms);
+
+ T m_fs;
+
+ T threshold_;
+ T preGain_;
+
+ T rmsTime_;
+ T rmsCoef_;
+ T rms1_;
+
+ T* lookaheadBuf_;
+ int lookaheadBufIdx_;
+
+ T ratio_;
+ T inverseRatio_;
+
+ T attTime_;
+ T attCoef_;
+ T relTime_;
+ T relCoef_;
+ T env1_;
+
+ T* avg1Buf_;
+ int avg1BufRIdx_;
+ int avg1BufWIdx_;
+ T avg1Old_;
+
+ T* avg2Buf_;
+ int avg2BufRIdx_;
+ int avg2BufWIdx_;
+ T avg2Old_;
+
+ T* delayBuf_;
+ int delayBufIdx_;
+
+ T makeupGain_;
+ T postGain_;
+};
+
+template<typename T, int CHANNELS>
+Dynamics<T, CHANNELS>::Dynamics(T fs)
+ : m_fs(fs),
+ threshold_(0.),
+ preGain_(1.),
+ rmsTime_(0.),
+ rmsCoef_(0.),
+ rms1_(0.),
+ lookaheadBuf_(0),
+ lookaheadBufIdx_(0),
+ ratio_(std::numeric_limits<T>::infinity()),
+ inverseRatio_(0.),
+ attTime_(0.),
+ attCoef_(0.),
+ relTime_(0.),
+ relCoef_(0.),
+ env1_(0.),
+ avg1Buf_(0),
+ avg1BufRIdx_(0),
+ avg1BufWIdx_(AVG1 - 1),
+ avg1Old_(0.),
+ avg2Buf_(0),
+ avg2BufRIdx_(0),
+ avg2BufWIdx_(AVG2 - 1),
+ avg2Old_(0.),
+ delayBuf_(0),
+ delayBufIdx_(0),
+ makeupGain_(0.),
+ postGain_(1.)
+{
+ lookaheadBuf_ = new T[LOOKAHEAD];
+ for (int i = 0; i < LOOKAHEAD; i++) {
+ lookaheadBuf_[i] = 1.f;
+ }
+
+ avg1Buf_ = new T[AVG1];
+ memset(avg1Buf_, 0, sizeof(T) * (AVG1));
+
+ avg2Buf_ = new T[AVG2];
+ memset(avg2Buf_, 0, sizeof(T) * (AVG2));
+
+ delayBuf_ = new T[LOOKAHEAD*CHANNELS];
+ memset(delayBuf_, 0, sizeof(T)*LOOKAHEAD*CHANNELS);
+
+ setThreshold(0.);
+ setRmsTime(0.);
+ setRatio(std::numeric_limits<T>::infinity());
+ setAttackTime(0.);
+ setReleaseTime(0.05);
+ setMakeupGain(0.);
+}
+
+template<typename T, int CHANNELS>
+Dynamics<T, CHANNELS>::~Dynamics()
+{
+ delete[] lookaheadBuf_;
+
+ delete[] avg1Buf_;
+ delete[] avg2Buf_;
+
+ delete[] delayBuf_;
+}
+
+template<typename T, int CHANNELS>
+void Dynamics<T, CHANNELS>::maxFilter(T& rms)
+{
+ int j = lookaheadBufIdx_;
+ for (int i = 0; i < LOOKAHEAD; i++)
+ {
+ j = (j+1)&(LOOKAHEAD-1);
+ if (lookaheadBuf_[j] < rms) {
+ lookaheadBuf_[j] = rms;
+ }
+ }
+}
+
+template<typename T, int CHANNELS>
+void Dynamics<T, CHANNELS>::process(T* pSamples)
+{
+
+ //---------------- Preprocessing
+ T x = 0.f;
+ for (int i = 0; i < CHANNELS; i++) {
+ // Apply pregain
+ const T tmp = pSamples[i] * preGain_;
+
+ T abs = std::fabs(tmp);
+ if (abs > x) {
+ x = abs;
+ }
+ }
+
+ //---------------- RMS
+ T rms = (1.f - rmsCoef_) * x * x + rmsCoef_ * rms1_;
+ rms1_ = rms;
+ rms = sqrt(rms);
+
+ //---------------- Max filter
+ if (rms > 1.) {
+ maxFilter(rms);
+ }
+
+ //---------------- Ratio
+ T dbMax = std::log10(lookaheadBuf_[lookaheadBufIdx_]);
+ T dbComp = dbMax * inverseRatio_;
+ T comp = std::pow(static_cast<T>(10.), dbComp);
+ T c = comp / lookaheadBuf_[lookaheadBufIdx_];
+
+ lookaheadBuf_[lookaheadBufIdx_] = 1.;
+ lookaheadBufIdx_ = (lookaheadBufIdx_+1)%LOOKAHEAD;
+
+ //---------------- Attack/release envelope
+ if (env1_ <= c) {
+ c = c + (env1_ - c) * relCoef_;
+ } else {
+ c = c + (env1_ - c) * attCoef_;
+ }
+ env1_ = c;
+
+ //---------------- Smoothing
+ const T tmp1 = avg1Old_ + c - avg1Buf_[avg1BufRIdx_];
+ avg1Old_ = tmp1;
+ avg1Buf_[avg1BufWIdx_] = c;
+ c = tmp1;
+ avg1BufRIdx_ = (avg1BufRIdx_+1)%AVG1;
+ avg1BufWIdx_ = (avg1BufWIdx_+1)%AVG1;
+
+ const T tmp2 = avg2Old_ + c - avg2Buf_[avg2BufRIdx_];
+ avg2Old_ = tmp2;
+ avg2Buf_[avg2BufWIdx_] = c;
+ c = tmp2;
+ avg2BufRIdx_ = (avg2BufRIdx_+1)%AVG2;
+ avg2BufWIdx_ = (avg2BufWIdx_+1)%AVG2;
+
+ c = c / (static_cast<T>(AVG1) * static_cast<T>(AVG2));
+
+ //---------------- Postprocessing
+ for (int i = 0; i < CHANNELS; i++) {
+ // Delay input samples
+ const T in = delayBuf_[delayBufIdx_*CHANNELS+i];
+ delayBuf_[delayBufIdx_*CHANNELS+i] = pSamples[i];
+
+ // Apply control signal
+ pSamples[i] = in * c * postGain_;
+ }
+
+ delayBufIdx_ = (delayBufIdx_+1)&(LOOKAHEAD-1);
+}
+
+template<typename T, int CHANNELS>
+void Dynamics<T, CHANNELS>::setThreshold(T threshold)
+{
+ threshold_ = threshold;
+ preGain_ = std::pow(10.f, -threshold / 20.f);
+}
+
+template<typename T, int CHANNELS>
+T Dynamics<T, CHANNELS>::getThreshold() const
+{
+ return threshold_;
+}
+
+template<typename T, int CHANNELS>
+void Dynamics<T, CHANNELS>::setRmsTime(T rmsTime)
+{
+ rmsTime_ = rmsTime;
+ rmsCoef_ = 0.f;
+ if (rmsTime > 0.f) {
+ rmsCoef_ = std::pow(0.001f, 1.f / (m_fs * rmsTime));
+ }
+}
+
+template<typename T, int CHANNELS>
+T Dynamics<T, CHANNELS>::getRmsTime() const
+{
+ return rmsTime_;
+}
+
+template<typename T, int CHANNELS>
+void Dynamics<T, CHANNELS>::setRatio(T ratio)
+{
+ ratio_ = ratio;
+ inverseRatio_ = 1.f / ratio;
+}
+
+template<typename T, int CHANNELS>
+T Dynamics<T, CHANNELS>::getRatio() const
+{
+ return ratio_;
+}
+
+template<typename T, int CHANNELS>
+void Dynamics<T, CHANNELS>::setAttackTime(T attTime)
+{
+ attTime_ = attTime;
+ attCoef_ = 0.f;
+ if (attTime > 0.f) {
+ attCoef_ = pow(0.001f, 1.f / (m_fs * attTime));
+ }
+}
+
+template<typename T, int CHANNELS>
+T Dynamics<T, CHANNELS>::getAttackTime() const
+{
+ return attTime_;
+}
+
+template<typename T, int CHANNELS>
+void Dynamics<T, CHANNELS>::setReleaseTime(T relTime)
+{
+ relTime_ = relTime;
+ relCoef_ = 0.f;
+ if (relTime > 0.f) {
+ relCoef_ = pow(0.001f, 1.f / (m_fs * relTime));
+ }
+}
+
+template<typename T, int CHANNELS>
+T Dynamics<T, CHANNELS>::getReleaseTime() const
+{
+ return relTime_;
+}
+
+template<typename T, int CHANNELS>
+void Dynamics<T, CHANNELS>::setMakeupGain(T makeupGain)
+{
+ makeupGain_ = makeupGain;
+ postGain_ = std::pow(10.f, makeupGain / 20.f);
+}
+
+template<typename T, int CHANNELS>
+T Dynamics<T, CHANNELS>::getMakeupGain() const
+{
+ return makeupGain_;
+}
+
+}
+
+#endif
diff --git a/src/audio/IProcessor.h b/src/audio/IProcessor.h
new file mode 100644
index 0000000..4eab2f0
--- /dev/null
+++ b/src/audio/IProcessor.h
@@ -0,0 +1,37 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _Processor_H_
+#define _Processor_H_
+
+namespace avg {
+
+template<typename T>
+class AVG_API IProcessor
+{
+public:
+ virtual ~IProcessor() {};
+ virtual void process(T* pSamples) = 0;
+
+};
+
+}
+#endif
diff --git a/src/audio/Makefile.am b/src/audio/Makefile.am
new file mode 100644
index 0000000..f475c7c
--- /dev/null
+++ b/src/audio/Makefile.am
@@ -0,0 +1,17 @@
+AM_CPPFLAGS = -I.. @PTHREAD_CFLAGS@
+
+ALL_H = AudioEngine.h AudioBuffer.h AudioParams.h \
+ Dynamics.h IProcessor.h AudioMsg.h AudioSource.h
+
+TESTS = testlimiter
+
+noinst_LTLIBRARIES = libaudio.la
+noinst_PROGRAMS = testlimiter
+
+libaudio_la_SOURCES = AudioEngine.cpp AudioBuffer.cpp AudioParams.cpp AudioMsg.cpp \
+ AudioSource.cpp $(ALL_H)
+
+testlimiter_SOURCES = testlimiter.cpp $(ALL_H)
+testlimiter_LDADD = ./libaudio.la ../base/libbase.la \
+ ../base/triangulate/libtriangulate.la \
+ @BOOST_THREAD_LIBS@ @PTHREAD_LIBS@
diff --git a/src/audio/testlimiter.cpp b/src/audio/testlimiter.cpp
new file mode 100644
index 0000000..5c3a515
--- /dev/null
+++ b/src/audio/testlimiter.cpp
@@ -0,0 +1,112 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "Dynamics.h"
+
+#include "../base/TestSuite.h"
+#include "../base/MathHelper.h"
+
+#include <stdlib.h>
+#include <iostream>
+
+using namespace avg;
+using namespace std;
+
+class LimiterTest: public Test {
+public:
+ LimiterTest()
+ : Test("LimiterTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+ const int CHANNELS = 2;
+ float fs = 44100.f;
+ int numSamples = int(fs * 0.1f);
+
+ // Setup a brickwall limiter
+ typedef Dynamics<float, CHANNELS> TStereoLimiter;
+ TStereoLimiter* d = new TStereoLimiter(fs);
+ d->setThreshold(0.f); // in dB
+ d->setAttackTime(0.f); // in seconds
+ d->setReleaseTime(0.05f); // in seconds
+ d->setRmsTime(0.f); // in seconds
+ d->setRatio(std::numeric_limits<float>::infinity());
+ d->setMakeupGain(0.f); // in dB
+
+ // Generate input and output test data
+ float* pSamples = new float[CHANNELS*numSamples];
+ for (int j = 0; j < numSamples; j++) {
+ for (int i = 0; i < CHANNELS; i++) {
+ pSamples[j*CHANNELS+i] = 2*sin(j*(440.f/44100)*float(M_PI));
+ }
+ }
+
+ // Let the limiter work.
+ for (int i=0; i<numSamples; ++i) {
+ d->process(pSamples+i*CHANNELS);
+ }
+
+ // Check if everything is ok.
+ bool bDiscontinuities = false;
+ bool bAboveThreshold = false;
+ for (int j = 1; j < numSamples; j++) {
+ for (int i = 0; i < CHANNELS; i++) {
+ // Test if anything is above the threshold.
+ if (pSamples[j*CHANNELS+i] > 1) {
+ bAboveThreshold = true;
+ }
+ if (fabs(pSamples[j*CHANNELS+i]-pSamples[(j-1)*CHANNELS+i]) > 0.05f) {
+ bDiscontinuities = true;
+// cerr << j << ": " << outSamples[j*OUT_CHANNELS+i] << ", " <<
+// outSamples[(j-1)*OUT_CHANNELS+i] << endl;
+ }
+ }
+ }
+ TEST(!bAboveThreshold);
+ TEST(!bDiscontinuities);
+/*
+ // Save data to ascii file.
+ FILE * pFile = fopen("data.txt", "w");
+ for (int j = 0; j < numSamples; j++) {
+ fprintf(pFile, "%f\n", pSamples[j*OUT_CHANNELS]);
+ }
+ fclose(pFile);
+*/
+ // Free memory
+ delete d;
+ delete[] pSamples;
+ }
+};
+
+int main(int nargs, char** args)
+{
+ LimiterTest test;
+ test.runTests();
+ bool bOK = test.isOk();
+
+ if (bOK) {
+ return 0;
+ } else {
+ return 1;
+ }
+}
diff --git a/src/avgconfig_win.h b/src/avgconfig_win.h
new file mode 100644
index 0000000..9b2bb31
--- /dev/null
+++ b/src/avgconfig_win.h
@@ -0,0 +1,28 @@
+/* src/avgconfig.h.in. Generated from configure.in by autoheader. */
+
+/* Enable DirectShow camera support */
+#define AVG_ENABLE_DSHOW
+
+/* Enable CMU 1394 Digital Camera Driver support */
+#define AVG_ENABLE_CMU1394
+
+/* Enable firewire camera support */
+#undef AVG_ENABLE_1394
+
+/* Enable firewire camera support v.2 */
+#undef AVG_ENABLE_1394_2
+
+/* ffmpeg >= 0.5.0 */
+#define HAVE_LIBAVFORMAT_AVFORMAT_H
+
+/* Enable Video4Linux2 camera support */
+#undef AVG_ENABLE_V4L2
+
+/* Enable parallel port support */
+#undef AVG_ENABLE_PARPORT
+
+/* Enable ffmpeg swscale support. */
+#define AVG_ENABLE_SWSCALE
+
+/* Name of package */
+#undef PACKAGE
diff --git a/src/avgconfigwrapper.h b/src/avgconfigwrapper.h
new file mode 100644
index 0000000..2408089
--- /dev/null
+++ b/src/avgconfigwrapper.h
@@ -0,0 +1,37 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "api.h"
+#ifdef _WIN32
+#include "../avgconfig_win.h"
+#else
+#include "avgconfig.h"
+#endif
+
+// These defines regularly cause multiple definition warnings and are usually
+// completely unneeded.
+#undef PACKAGE
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
diff --git a/src/avgrc b/src/avgrc
new file mode 100644
index 0000000..3f93e5a
--- /dev/null
+++ b/src/avgrc
@@ -0,0 +1,42 @@
+<avgrc>
+ <scr>
+ <gles>false</gles>
+ <bpp>24</bpp>
+ <fullscreen>false</fullscreen>
+ <usepow2textures>false</usepow2textures>
+ <usepixelbuffers>true</usepixelbuffers>
+ <multisamplesamples>4</multisamplesamples>
+ <dotspermm>0</dotspermm>
+ <shaderusage>auto</shaderusage>
+ <videoaccel>true</videoaccel>
+ </scr>
+ <aud>
+ <channels>2</channels>
+ <samplerate>44100</samplerate>
+ <outputbuffersamples>1024</outputbuffersamples>
+ </aud>
+ <gesture>
+ <!-- Max finger movement in millimeters for tap, doubletap and hold gestures. -->
+ <maxtapdist>15</maxtapdist>
+ <!-- Maximum duration of one phase of a doubletap in milliseconds. -->
+ <maxdoubletaptime>300</maxdoubletaptime>
+ <!-- Swipe parameters -->
+ <minswipedist>50</minswipedist>
+ <swipedirectiontolerance>0.393</swipedirectiontolerance>
+ <maxswipecontactdist>100</maxswipecontactdist>
+ <!-- Min. time in milliseconds for a hold gesture. -->
+ <holddelay>900</holddelay>
+ <!-- Min. finger movement in millimeters for a drag. -->
+ <mindragdist>5</mindragdist>
+ <!-- Friction for drag and transform gestures with inertia. -1 means no friction. -->
+ <friction>-1</friction>
+ <!-- The following two parameters configure the jitter filter for transform
+ gestures. Use avg_jitterfilter.py to find correct values for your hardware. -->
+ <filtermincutoff>0.1</filtermincutoff>
+ <filterbeta>0.03</filterbeta>
+ </gesture>
+ <touch>
+ <area>0, 0</area>
+ <offset>0, 0</offset>
+ </touch>
+</avgrc>
diff --git a/src/base/Backtrace.cpp b/src/base/Backtrace.cpp
new file mode 100644
index 0000000..2b85cde
--- /dev/null
+++ b/src/base/Backtrace.cpp
@@ -0,0 +1,120 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "Backtrace.h"
+
+#include "StringHelper.h"
+
+#ifndef _WIN32
+#include <execinfo.h>
+#include <cxxabi.h>
+#endif
+
+#include <stdlib.h>
+#include <iostream>
+#include <stdio.h>
+
+using namespace std;
+
+namespace avg {
+
+void dumpBacktrace()
+{
+#ifndef _WIN32
+ vector<string> sFuncs;
+ getBacktrace(sFuncs);
+ vector<string>::iterator it = sFuncs.begin();
+ ++it;
+ for (; it != sFuncs.end(); ++it) {
+ cerr << " " << *it << endl;
+ }
+#endif
+}
+
+string funcNameFromLine(const string& sLine)
+{
+ try {
+#ifdef __APPLE__
+ string::size_type addressPos = sLine.find("0x");
+ string::size_type namePos = sLine.find(" ", addressPos);
+ namePos++;
+ string::size_type nameEndPos = sLine.find(" ", namePos);
+#else
+ string::size_type namePos = sLine.find("(");
+ namePos++;
+ string::size_type nameEndPos = sLine.find_first_of(")+", namePos);
+#endif
+ return sLine.substr(namePos, nameEndPos-namePos);
+ } catch (exception&) {
+ return sLine;
+ }
+}
+
+void consolidateRepeatedLines(vector<string>& sFuncs, unsigned& i, unsigned numSameLines)
+{
+ unsigned firstSameLine = i - numSameLines;
+ sFuncs[firstSameLine+1] = " [...]";
+ sFuncs.erase(sFuncs.begin()+firstSameLine+2, sFuncs.begin()+i-1);
+ i = firstSameLine + 3;
+}
+
+void getBacktrace(vector<string>& sFuncs)
+{
+#ifndef _WIN32
+ void* callstack[128];
+ int numFrames = backtrace(callstack, 128);
+ char** ppszLines = backtrace_symbols(callstack, numFrames);
+ for (int i = 1; i < numFrames; ++i) {
+ string sLine = ppszLines[i];
+ string sFuncName = funcNameFromLine(sLine);
+ int result;
+ char * pszDemangledFuncName = abi::__cxa_demangle(sFuncName.c_str(), 0, 0,
+ &result);
+ if (!result) {
+ sFuncName = pszDemangledFuncName;
+ free(pszDemangledFuncName);
+ }
+ char szLineNum[10];
+ sprintf(szLineNum, "%3d", i);
+ sFuncs.push_back(string(szLineNum)+" "+sFuncName);
+ }
+ free(ppszLines);
+
+ unsigned numSameLines = 1;
+ unsigned i = 1;
+ for (i = 1; i < sFuncs.size(); ++i) {
+ if (sFuncs[i].substr(4, string::npos) == sFuncs[i-1].substr(4, string::npos)) {
+ numSameLines++;
+ } else {
+ if (numSameLines > 3) {
+ consolidateRepeatedLines(sFuncs, i, numSameLines);
+ }
+ numSameLines = 1;
+ }
+ }
+ if (numSameLines > 2) {
+ consolidateRepeatedLines(sFuncs, i, numSameLines);
+ }
+#endif
+}
+
+}
+
diff --git a/src/base/Backtrace.h b/src/base/Backtrace.h
new file mode 100644
index 0000000..2eee387
--- /dev/null
+++ b/src/base/Backtrace.h
@@ -0,0 +1,36 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _Backtrace_H_
+#define _Backtrace_H_
+
+#include <vector>
+#include <string>
+
+namespace avg {
+
+void dumpBacktrace();
+
+void getBacktrace(std::vector<std::string>& sFuncs);
+
+}
+
+#endif
diff --git a/src/base/BezierCurve.cpp b/src/base/BezierCurve.cpp
new file mode 100644
index 0000000..7e5fb8e
--- /dev/null
+++ b/src/base/BezierCurve.cpp
@@ -0,0 +1,56 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "BezierCurve.h"
+
+#include "GLMHelper.h"
+
+#include <iostream>
+
+using namespace std;
+
+namespace avg {
+
+BezierCurve::BezierCurve(const glm::vec2& p0, const glm::vec2& p1, const glm::vec2& p2,
+ const glm::vec2& p3)
+ : m_P0(p0),
+ m_P1(p1),
+ m_P2(p2),
+ m_P3(p3)
+{
+}
+
+glm::vec2 BezierCurve::interpolate(float t) const
+{
+ return (1.f-t)*(1.f-t)*(1.f-t)*m_P0+
+ 3.f*t*(1.f-t)*(1.f-t) *m_P1+
+ 3.f*t*t*(1.f-t) *m_P2+
+ t*t*t *m_P3;
+}
+
+glm::vec2 BezierCurve::getDeriv(float t) const
+{
+ return 3.f*(m_P1-m_P0)*(1.f-t)*(1.f-t)+
+ 6.f*(m_P2-m_P1)*(1.f-t)*t+
+ 3.f*(m_P3-m_P2)*t*t;
+}
+
+}
diff --git a/src/base/BezierCurve.h b/src/base/BezierCurve.h
new file mode 100644
index 0000000..b2ec1dc
--- /dev/null
+++ b/src/base/BezierCurve.h
@@ -0,0 +1,56 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _BezierCurve_H_
+#define _BezierCurve_H_
+
+#include "../api.h"
+
+#include "../glm/glm.hpp"
+
+#include <boost/shared_ptr.hpp>
+#include <vector>
+
+namespace avg {
+
+class AVG_API BezierCurve {
+public:
+ BezierCurve(const glm::vec2& p0, const glm::vec2& p1, const glm::vec2& p2,
+ const glm::vec2& p3);
+
+ glm::vec2 interpolate(float t) const;
+ glm::vec2 getDeriv(float t) const;
+
+private:
+ glm::vec2 m_P0;
+ glm::vec2 m_P1;
+ glm::vec2 m_P2;
+ glm::vec2 m_P3;
+};
+
+typedef boost::shared_ptr<BezierCurve> BezierCurvePtr;
+
+}
+
+#endif
+
+
+
diff --git a/src/base/CmdQueue.h b/src/base/CmdQueue.h
new file mode 100644
index 0000000..9d38f37
--- /dev/null
+++ b/src/base/CmdQueue.h
@@ -0,0 +1,56 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _CmdQueue_H_
+#define _CmdQueue_H_
+
+#include "Command.h"
+#include "Queue.h"
+
+#include "../api.h"
+
+namespace avg {
+
+template<class RECEIVER>
+class AVG_TEMPLATE_API CmdQueue: public Queue<Command<RECEIVER> >
+{
+public:
+ CmdQueue(int maxSize=-1);
+ typedef typename Queue<Command<RECEIVER> >::QElementPtr CmdPtr;
+ void pushCmd(typename Command<RECEIVER>::CmdFunc func);
+
+};
+
+template<class RECEIVER>
+CmdQueue<RECEIVER>::CmdQueue(int maxSize)
+ : Queue<Command<RECEIVER> >(maxSize)
+{
+}
+
+template<class RECEIVER>
+void CmdQueue<RECEIVER>::pushCmd(typename Command<RECEIVER>::CmdFunc func)
+{
+ this->push(CmdPtr(new Command<RECEIVER>(func)));
+}
+
+}
+
+#endif
diff --git a/src/base/Command.h b/src/base/Command.h
new file mode 100644
index 0000000..fe18171
--- /dev/null
+++ b/src/base/Command.h
@@ -0,0 +1,56 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _Command_H_
+#define _Command_H_
+
+#include "../api.h"
+#include <boost/function.hpp>
+
+namespace avg {
+
+template<class RECEIVER>
+class AVG_TEMPLATE_API Command {
+public:
+ typedef boost::function<void(RECEIVER*)> CmdFunc;
+
+ Command(CmdFunc Func);
+ void execute(RECEIVER* pTarget);
+
+private:
+ CmdFunc m_Func;
+};
+
+template<class RECEIVER>
+Command<RECEIVER>::Command(CmdFunc Func)
+ : m_Func(Func)
+{
+}
+
+template<class RECEIVER>
+void Command<RECEIVER>::execute(RECEIVER* pTarget)
+{
+ m_Func(pTarget);
+}
+
+}
+
+#endif
diff --git a/src/base/ConfigMgr.cpp b/src/base/ConfigMgr.cpp
new file mode 100644
index 0000000..0414037
--- /dev/null
+++ b/src/base/ConfigMgr.cpp
@@ -0,0 +1,361 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "ConfigMgr.h"
+#include "Logger.h"
+#include "Exception.h"
+#include "OSHelper.h"
+
+#include <libxml/xmlmemory.h>
+
+#include <iostream>
+#include <stdlib.h>
+#include <errno.h>
+
+#ifndef _WIN32
+#include <unistd.h>
+#else
+#include <io.h>
+#endif
+
+using namespace std;
+
+namespace avg {
+
+ConfigOption::ConfigOption(const string& sName, const string& sValue)
+ : m_sName(sName),
+ m_sValue(sValue)
+{
+}
+
+ConfigMgr* ConfigMgr::m_pGlobalConfigMgr = 0;
+
+void deleteConfigMgr()
+{
+ delete ConfigMgr::m_pGlobalConfigMgr;
+ ConfigMgr::m_pGlobalConfigMgr = 0;
+}
+
+ConfigMgr* ConfigMgr::get()
+{
+ if (!m_pGlobalConfigMgr) {
+ m_pGlobalConfigMgr = new ConfigMgr;
+ atexit(deleteConfigMgr);
+ }
+ return m_pGlobalConfigMgr;
+}
+
+ConfigMgr::ConfigMgr()
+{
+ addSubsys("scr");
+ addOption("scr", "gles", "false");
+ addOption("scr", "bpp", "24");
+ addOption("scr", "fullscreen", "false");
+ addOption("scr", "windowwidth", "0");
+ addOption("scr", "windowheight", "0");
+ addOption("scr", "dotspermm", "0");
+ addOption("scr", "usepow2textures", "false");
+ addOption("scr", "usepixelbuffers", "true");
+ addOption("scr", "multisamplesamples", "8");
+ addOption("scr", "shaderusage", "auto");
+ addOption("scr", "gamma", "-1,-1,-1");
+ addOption("scr", "vsyncmode", "auto");
+ addOption("scr", "videoaccel", "true");
+
+ addSubsys("aud");
+ addOption("aud", "channels", "2");
+ addOption("aud", "samplerate", "44100");
+ addOption("aud", "outputbuffersamples", "1024");
+
+ addSubsys("gesture");
+ addOption("gesture", "maxtapdist", "15");
+ addOption("gesture", "maxdoubletaptime", "300");
+ addOption("gesture", "minswipedist", "50");
+ addOption("gesture", "swipedirectiontolerance", "0.393"); // pi/8
+ addOption("gesture", "maxswipecontactdist", "100");
+ addOption("gesture", "holddelay", "500");
+ addOption("gesture", "mindragdist", "5");
+ addOption("gesture", "filtermincutoff", "0.1");
+ addOption("gesture", "filterbeta", "0.03");
+ addOption("gesture", "friction", "-1");
+
+ addSubsys("touch");
+ addOption("touch", "area", "0, 0");
+ addOption("touch", "offset", "0, 0");
+
+ m_sFName = "avgrc";
+ loadFile(getGlobalConfigDir()+m_sFName);
+ char * pHome = getenv("HOME");
+ if (pHome) {
+ loadFile(string(pHome)+"/."+m_sFName);
+ }
+}
+
+void ConfigMgr::addSubsys(const string& sName)
+{
+ m_SubsysOptionMap[sName] = ConfigOptionVector();
+}
+
+void ConfigMgr::addOption(const string& sSubsys, const string& sName,
+ const std::string& sDefault)
+{
+ ConfigOptionVector& Subsys = m_SubsysOptionMap[sSubsys];
+ Subsys.push_back(ConfigOption(sName, sDefault));
+}
+
+const ConfigOptionVector* ConfigMgr::getOptions(const string& sSubsys) const
+{
+ SubsysOptionMap::const_iterator it = m_SubsysOptionMap.find(sSubsys);
+ if (it == m_SubsysOptionMap.end()) {
+ return 0;
+ } else {
+ return &(*it).second;
+ }
+}
+
+const string* ConfigMgr::getOption(const string& sSubsys,
+ const string& sName) const
+{
+ const ConfigOptionVector* pOptionVector = getOptions(sSubsys);
+ if (!pOptionVector) {
+ return 0;
+ } else {
+ for (unsigned int i=0; i<pOptionVector->size(); i++) {
+ if ((*pOptionVector)[i].m_sName == sName) {
+ return &(*pOptionVector)[i].m_sValue;
+ }
+ }
+ return 0;
+ }
+}
+
+bool ConfigMgr::getBoolOption(const string& sSubsys,
+ const string& sName, bool bDefault) const
+{
+ const string * psOption = getOption(sSubsys, sName);
+ if (psOption == 0) {
+ return bDefault;
+ }
+ if (*psOption == "true") {
+ return true;
+ } else if (*psOption == "false") {
+ return false;
+ } else {
+ AVG_LOG_ERROR(m_sFName << ": Unrecognized value for option " << sName << ": "
+ << *psOption << ". Must be true or false. Aborting.");
+ exit(-1);
+ }
+}
+
+int ConfigMgr::getIntOption(const string& sSubsys,
+ const string& sName, int Default) const
+{
+ errno = 0;
+ const string * psOption = getOption(sSubsys, sName);
+ if (psOption == 0) {
+ return Default;
+ }
+ int Result = strtol(psOption->c_str(), 0, 10);
+ int rc = errno;
+ if (rc == EINVAL || rc == ERANGE) {
+ AVG_LOG_ERROR(m_sFName << ": Unrecognized value for option "<<sName<<": "
+ << *psOption << ". Must be an integer. Aborting.");
+ exit(-1);
+ }
+ return Result;
+}
+
+void ConfigMgr::getGammaOption(const string& sSubsys,
+ const string& sName, float* Val) const
+{
+ const string * psOption = getOption(sSubsys, sName);
+ if (psOption == 0) {
+ return;
+ }
+ int rc = sscanf(psOption->c_str(), "%f,%f,%f", Val, Val+1, Val+2);
+ if (rc < 3) {
+ AVG_LOG_ERROR(m_sFName << ": Unrecognized value for option "<<sName<<": "
+ << *psOption << ". Must be three comma-separated numbers. Aborting.");
+ exit(-1);
+ }
+}
+
+glm::vec2 ConfigMgr::getSizeOption(const string& sSubsys,
+ const string& sName) const
+{
+ const string * psOption = getOption(sSubsys, sName);
+ if (psOption == 0) {
+ return glm::vec2(0, 0);
+ }
+ float val[2];
+ int rc = sscanf(psOption->c_str(), "%f,%f", val, val+1);
+ if (rc < 2) {
+ AVG_LOG_ERROR(m_sFName << ": Unrecognized value for option " << sName << ": "
+ << *psOption << ". Must be 2 comma-separated numbers(x, y). Aborting.");
+ exit(-1);
+ }
+ return glm::vec2(val[0], val[1]);
+}
+
+void ConfigMgr::getStringOption(const string& sSubsys,
+ const string& sName, const string& sDefault, string& sVal) const
+{
+ const string * psOption = getOption(sSubsys, sName);
+ if (psOption == 0) {
+ sVal = sDefault;
+ } else {
+ sVal = *psOption;
+ }
+}
+
+
+bool ConfigMgr::loadFile(const std::string& sPath)
+{
+ string sSubsys;
+ try {
+#ifndef _WIN32
+ // I don't think read permissions on config files are an issue under windows.
+ int err = access(sPath.c_str(), R_OK);
+ if (err == -1) {
+ if (errno == EACCES) {
+ AVG_LOG_WARNING(sPath+
+ ": File exists, but process doesn't have read permissions!");
+ }
+ return false;
+ }
+#else
+ // but this actually prevents ugly XML parsing errors when file does not exist
+ // and cygwin is used
+ int err = _access(sPath.c_str(), 0);
+ if (err == -1) {
+ return false;
+ }
+#endif
+ xmlDocPtr doc;
+ doc = xmlParseFile(sPath.c_str());
+ if (!doc) {
+ throw Exception(AVG_ERR_XML_VALID, "Error parsing "+sPath
+ +". File is not well-formed.");
+ }
+ xmlNodePtr pRoot = xmlDocGetRootElement(doc);
+ if (xmlStrcmp(pRoot->name, (const xmlChar *)(m_sFName.c_str()))) {
+ AVG_LOG_ERROR(sPath+": Root node must be <"+m_sFName+">, found "
+ << pRoot->name << ". Aborting.");
+ exit(255);
+ }
+ xmlNodePtr pSubsysNode = pRoot->xmlChildrenNode;
+ while (pSubsysNode) {
+ if (xmlStrcmp(pSubsysNode->name, (const xmlChar *)"text") &&
+ xmlStrcmp(pSubsysNode->name, (const xmlChar *)"comment"))
+ {
+ sSubsys = ((const char *)pSubsysNode->name);
+ xmlNodePtr pOptionNode = pSubsysNode->xmlChildrenNode;
+ if (!pOptionNode) {
+ AVG_LOG_ERROR(sPath << ": Option " << sSubsys
+ << " has no value. Ignoring.");
+ } else {
+ ConfigOptionVector& CurSubsys = getSubsys(sSubsys);
+ while (pOptionNode) {
+ if (xmlStrcmp(pOptionNode->name, (const xmlChar *)"text") &&
+ xmlStrcmp(pOptionNode->name, (const xmlChar *)"comment"))
+ {
+ setOption(CurSubsys, doc, pOptionNode);
+ }
+ pOptionNode = pOptionNode->next;
+ }
+ }
+ }
+ pSubsysNode = pSubsysNode->next;
+ }
+ xmlFreeDoc(doc);
+ } catch (Exception& e) {
+ switch (e.getCode()) {
+ case AVG_ERR_OPTION_SUBSYS_UNKNOWN:
+ AVG_LOG_ERROR("While parsing " << sPath << ": Option group " <<
+ e.getStr() << " unknown. Aborting.");
+ exit(255);
+ case AVG_ERR_OPTION_UNKNOWN:
+ AVG_LOG_ERROR("While parsing " << sPath << ": Option " << sSubsys <<
+ ":" << e.getStr() << " unknown. Aborting.");
+ exit(255);
+ default:
+ throw;
+ }
+ }
+ return true;
+}
+
+ConfigOptionVector& ConfigMgr::getSubsys(const string& sName)
+{
+ SubsysOptionMap::iterator pos = m_SubsysOptionMap.find(sName);
+ if (pos == m_SubsysOptionMap.end()) {
+ throw Exception(AVG_ERR_OPTION_SUBSYS_UNKNOWN, sName);
+ } else {
+ return pos->second;
+ }
+}
+
+void ConfigMgr::setOption(ConfigOptionVector& optionVector,
+ xmlDocPtr doc, xmlNodePtr pNode)
+{
+ string sName = (const char *)pNode->name;
+ xmlChar * pVal = xmlNodeListGetString(doc, pNode->xmlChildrenNode, 1);
+ string sValue = (const char *)pVal;
+ xmlFree(pVal);
+ setOption(optionVector, sName, sValue);
+}
+
+void ConfigMgr::setOption(ConfigOptionVector& optionVector,
+ const string& sName, const string& sValue)
+{
+ for (unsigned int i = 0; i < optionVector.size(); i++) {
+ if (optionVector[i].m_sName == sName) {
+ optionVector[i].m_sValue = sValue;
+ return;
+ }
+ }
+ throw Exception(AVG_ERR_OPTION_UNKNOWN, sName);
+}
+
+void ConfigMgr::dump() const
+{
+ SubsysOptionMap::const_iterator it;
+ for (it = m_SubsysOptionMap.begin(); it != m_SubsysOptionMap.end(); ++it) {
+ cerr << (*it).first << ": " << endl;
+ const ConfigOptionVector& SubsysOptions = (*it).second;
+ for (unsigned int j = 0; j < SubsysOptions.size(); ++j) {
+ cerr << " " << SubsysOptions[j].m_sName << ": "
+ << SubsysOptions[j].m_sValue << endl;
+ }
+ }
+}
+
+string getGlobalConfigDir()
+{
+#ifdef _WIN32
+ return getAvgLibPath()+"/etc/";
+#else
+ return "/etc/";
+#endif
+}
+
+}
+
diff --git a/src/base/ConfigMgr.h b/src/base/ConfigMgr.h
new file mode 100644
index 0000000..e2af8f1
--- /dev/null
+++ b/src/base/ConfigMgr.h
@@ -0,0 +1,93 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _ConfigMgr_H_
+#define _ConfigMgr_H_
+
+#include "../api.h"
+
+#include "GLMHelper.h"
+#include <libxml/parser.h>
+
+#include <string>
+#include <vector>
+#include <map>
+
+namespace avg {
+
+struct ConfigOption {
+ ConfigOption(const std::string& sName, const std::string& sValue);
+
+ std::string m_sName;
+ std::string m_sValue;
+};
+
+typedef std::vector<ConfigOption> ConfigOptionVector;
+
+class AVG_API ConfigMgr {
+public:
+ static ConfigMgr* get();
+
+ void addSubsys(const std::string& sName);
+ void addOption(const std::string& sSubsys, const std::string& sName,
+ const std::string& sDefault);
+
+ const ConfigOptionVector* getOptions(const std::string& sSubsys) const;
+ const std::string* getOption(const std::string& sSubsys,
+ const std::string& sName) const;
+ bool getBoolOption(const std::string& sSubsys,
+ const std::string& sName, bool bDefault) const;
+ int getIntOption(const std::string& sSubsys,
+ const std::string& sName, int Default) const;
+ void getGammaOption(const std::string& sSubsys,
+ const std::string& sName, float* Val) const;
+ glm::vec2 getSizeOption(const std::string& sSubsys,
+ const std::string& sName) const;
+ void getStringOption(const std::string& sSubsys,
+ const std::string& sName, const std::string& sDefault, std::string& sVal)
+ const;
+
+ void dump() const;
+
+private:
+ ConfigMgr();
+
+ bool loadFile(const std::string& sPath);
+ ConfigOptionVector& getSubsys(const std::string& sName);
+ void setOption(ConfigOptionVector& optionVector,
+ xmlDocPtr doc, xmlNodePtr pNode);
+ void setOption(ConfigOptionVector& optionVector, const std::string& sName,
+ const std::string& sValue);
+
+ typedef std::map<std::string, ConfigOptionVector> SubsysOptionMap;
+ SubsysOptionMap m_SubsysOptionMap;
+
+ std::string m_sFName;
+
+ static ConfigMgr* m_pGlobalConfigMgr;
+ friend void deleteConfigMgr();
+};
+
+std::string getGlobalConfigDir();
+
+}
+#endif
+
diff --git a/src/base/CubicSpline.cpp b/src/base/CubicSpline.cpp
new file mode 100644
index 0000000..105563d
--- /dev/null
+++ b/src/base/CubicSpline.cpp
@@ -0,0 +1,104 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "CubicSpline.h"
+#include "Exception.h"
+#include "MathHelper.h"
+
+#include <iostream>
+
+using namespace std;
+
+namespace avg {
+
+CubicSpline::CubicSpline(const vector<float>& x, const vector<float>& y, bool bLoop)
+{
+ AVG_ASSERT(x.size() == y.size());
+ for (unsigned i=0; i<x.size(); ++i) {
+ m_Pts.push_back(glm::vec2(x[i], y[i]));
+ }
+ init();
+}
+
+CubicSpline::CubicSpline(const vector<glm::vec2>& pts, bool bLoop)
+ : m_Pts(pts)
+{
+ init();
+}
+
+CubicSpline::~CubicSpline()
+{
+}
+
+float CubicSpline::interpolate(float orig)
+{
+ int len = m_Pts.size();
+ int low = 0;
+ int high = len-1;
+ // Binary search.
+ while (high - low > 1) {
+ int avg = (high+low) / 2;
+ if (m_Pts[avg].x > orig) {
+ high = avg;
+ } else {
+ low = avg;
+ }
+ }
+ float h = m_Pts[high].x - m_Pts[low].x;
+ float a = (m_Pts[high].x-orig)/h;
+ float b = (orig-m_Pts[low].x)/h;
+
+ float y = a*m_Pts[low].y + b*m_Pts[high].y
+ + ((a*a*a-a)*m_Y2[low] + (b*b*b-b)*m_Y2[high])*(h*h)/6.f;
+ return y;
+}
+
+void CubicSpline::init()
+{
+ int len = m_Pts.size();
+ for (int i=1; i<len; ++i) {
+ if (m_Pts[i].x <= m_Pts[i-1].x) {
+ throw Exception(AVG_ERR_INVALID_ARGS,
+ "CubicSplines must have increasing x coordinates.");
+ }
+ }
+ vector<float> u(len-1,0);
+ m_Y2.push_back(0.f);
+ u[0] = 0.f;
+ for (int i=1; i<len-1; ++i) {
+ float sig = (m_Pts[i].x-m_Pts[i-1].x) / (m_Pts[i+1].x-m_Pts[i-1].x);
+ float p = sig * m_Y2[i-1]+2.0f;
+ m_Y2.push_back((sig-1.0f)/p);
+ u[i] = (m_Pts[i+1].y-m_Pts[i].y) / (m_Pts[i+1].x-m_Pts[i].x) -
+ (m_Pts[i].y - m_Pts[i-1].y) / (m_Pts[i].x-m_Pts[i-1].x);
+ u[i] = (6.f*u[i]/(m_Pts[i+1].x-m_Pts[i-1].x) - sig*u[i-1]) / p;
+ }
+ float qn = 0.f;
+ float un = 0.f;
+
+ m_Y2.push_back((un-qn*u[len-2]) / (qn*m_Y2[len-2]-1.0f));
+
+ for (int i=len-2; i>=0; i--) {
+ m_Y2[i] = m_Y2[i]*m_Y2[i+1]+u[i];
+ }
+}
+
+}
diff --git a/src/base/CubicSpline.h b/src/base/CubicSpline.h
new file mode 100644
index 0000000..a275413
--- /dev/null
+++ b/src/base/CubicSpline.h
@@ -0,0 +1,56 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _CubicSpline_H_
+#define _CubicSpline_H_
+
+#include "../api.h"
+#include "../glm/glm.hpp"
+
+#include <boost/shared_ptr.hpp>
+#include <vector>
+
+namespace avg {
+
+class AVG_API CubicSpline {
+public:
+ CubicSpline(const std::vector<float>& x, const std::vector<float>& y,
+ bool bLoop=false);
+ CubicSpline(const std::vector<glm::vec2>& pts, bool bLoop=false);
+ virtual ~CubicSpline();
+
+ float interpolate(float orig);
+
+private:
+ void init();
+
+ std::vector<glm::vec2> m_Pts;
+ std::vector<float> m_Y2; // Second derivatives
+};
+
+typedef boost::shared_ptr<CubicSpline> CubicSplinePtr;
+
+}
+
+#endif
+
+
+
diff --git a/src/base/DAG.cpp b/src/base/DAG.cpp
new file mode 100644
index 0000000..85ab8bb
--- /dev/null
+++ b/src/base/DAG.cpp
@@ -0,0 +1,130 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "DAG.h"
+
+#include "Exception.h"
+
+#include <boost/enable_shared_from_this.hpp>
+
+using namespace std;
+
+namespace avg {
+
+class AVG_API DAGNode: public boost::enable_shared_from_this<DAGNode>
+{
+public:
+ DAGNode(long vertexID, const std::set<long>& outgoingIDs);
+ void resolveIDs(DAG* pDAG);
+
+ long m_VertexID;
+ std::set<long> m_OutgoingIDs;
+ std::set<DAGNodePtr> m_pOutgoingNodes;
+ std::set<DAGNodePtr> m_pIncomingNodes;
+};
+
+
+DAGNode::DAGNode(long vertexID, const set<long>& outgoingIDs)
+{
+ m_VertexID = vertexID;
+ m_OutgoingIDs = outgoingIDs;
+}
+
+void DAGNode::resolveIDs(DAG* pDAG)
+{
+ set<long>::iterator it;
+ for (it=m_OutgoingIDs.begin(); it!=m_OutgoingIDs.end(); ++it) {
+ long outgoingID = *it;
+ DAGNodePtr pDestNode = pDAG->findNode(outgoingID);
+ m_pOutgoingNodes.insert(pDestNode);
+ pDestNode->m_pIncomingNodes.insert(shared_from_this());
+ }
+ m_OutgoingIDs.clear();
+}
+
+
+DAG::DAG()
+{
+}
+
+DAG::~DAG()
+{
+}
+
+void DAG::addNode(long vertexID, const set<long>& outgoingIDs)
+{
+ DAGNode* pNode = new DAGNode(vertexID, outgoingIDs);
+ m_pNodes.insert(DAGNodePtr(pNode));
+}
+
+void DAG::sort(vector<long>& pResults)
+{
+ resolveIDs();
+ while (!m_pNodes.empty()) {
+ DAGNodePtr pCurNode = findStartNode(*m_pNodes.begin());
+ removeNode(pCurNode);
+ pResults.push_back(pCurNode->m_VertexID);
+ }
+}
+
+void DAG::resolveIDs()
+{
+ set<DAGNodePtr>::iterator it;
+ for (it=m_pNodes.begin(); it!=m_pNodes.end(); ++it) {
+ (*it)->resolveIDs(this);
+ }
+}
+
+DAGNodePtr DAG::findNode(long id)
+{
+ set<DAGNodePtr>::iterator it;
+ for (it=m_pNodes.begin(); it!=m_pNodes.end(); ++it) {
+ if ((*it)->m_VertexID == id) {
+ return (*it);
+ }
+ }
+ AVG_ASSERT(false);
+ return DAGNodePtr();
+}
+
+void DAG::removeNode(DAGNodePtr pNode)
+{
+ set<DAGNodePtr>::iterator it;
+ for (it=pNode->m_pOutgoingNodes.begin(); it!=pNode->m_pOutgoingNodes.end(); ++it) {
+ DAGNodePtr pDestNode = *it;
+ pDestNode->m_pIncomingNodes.erase(pNode);
+ }
+ m_pNodes.erase(pNode);
+}
+
+DAGNodePtr DAG::findStartNode(DAGNodePtr pNode, unsigned depth)
+{
+ if (pNode->m_pIncomingNodes.empty()) {
+ return pNode;
+ } else {
+ if (depth > m_pNodes.size()) {
+ throw Exception(AVG_ERR_INVALID_ARGS, "cyclic graph");
+ }
+ return findStartNode(*pNode->m_pIncomingNodes.begin(), depth+1);
+ }
+}
+
+}
diff --git a/src/base/DAG.h b/src/base/DAG.h
new file mode 100644
index 0000000..929ecd2
--- /dev/null
+++ b/src/base/DAG.h
@@ -0,0 +1,64 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _DAG_H_
+#define _DAG_H_
+
+#include "../api.h"
+
+#include <set>
+#include <vector>
+#include <boost/shared_ptr.hpp>
+
+namespace avg {
+
+class DAG;
+class DAGNode;
+typedef boost::shared_ptr<DAGNode> DAGNodePtr;
+
+// Directed Acyclic Graph class.
+// Only useful for sorting. The process of sorting destroys the DAG.
+class AVG_API DAG
+{
+public:
+ DAG();
+ virtual ~DAG();
+
+ void addNode(long vertexID, const std::set<long>& outgoingIDs);
+ void sort(std::vector<long>& pResults);
+
+private:
+ friend class DAGNode;
+
+ void resolveIDs();
+ DAGNodePtr findNode(long pID);
+ void removeNode(DAGNodePtr pNode);
+ DAGNodePtr findStartNode(DAGNodePtr pNode, unsigned depth=0);
+
+ std::set<DAGNodePtr> m_pNodes;
+};
+
+}
+
+#endif
+
+
+
diff --git a/src/base/DirEntry.cpp b/src/base/DirEntry.cpp
new file mode 100644
index 0000000..c654e50
--- /dev/null
+++ b/src/base/DirEntry.cpp
@@ -0,0 +1,65 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "DirEntry.h"
+
+using namespace std;
+
+namespace avg {
+
+#ifdef _WIN32
+DirEntry::DirEntry(string sDirName, const _finddata_t& findData)
+ : m_sDirName(sDirName),
+ m_FindData(findData)
+{
+}
+
+#else
+DirEntry::DirEntry(string sDirName, dirent * pEntry)
+ : m_sDirName(sDirName),
+ m_pEntry(pEntry)
+{
+}
+#endif
+
+DirEntry::~DirEntry()
+{
+}
+
+std::string DirEntry::getName()
+{
+#ifdef _WIN32
+ return m_FindData.name;
+#else
+ return m_pEntry->d_name;
+#endif
+}
+
+void DirEntry::remove()
+{
+#ifdef _WIN32
+ ::_unlink((m_sDirName+"\\"+m_FindData.name).c_str());
+#else
+ ::unlink((m_sDirName+"/"+m_pEntry->d_name).c_str());
+#endif
+}
+
+}
diff --git a/src/base/DirEntry.h b/src/base/DirEntry.h
new file mode 100644
index 0000000..ac2fca9
--- /dev/null
+++ b/src/base/DirEntry.h
@@ -0,0 +1,67 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _DirEntry_H_
+#define _DirEntry_H_
+
+#include "../api.h"
+#include <boost/shared_ptr.hpp>
+
+#ifdef _WIN32
+#include <io.h>
+#else
+#include <dirent.h>
+#endif
+#include <string>
+
+namespace avg {
+
+class AVG_API DirEntry {
+public:
+#ifdef _WIN32
+ DirEntry(std::string sDirName, const _finddata_t& findData);
+#else
+ DirEntry(std::string sDirName, dirent * pEntry);
+#endif
+ virtual ~DirEntry();
+
+ std::string getName();
+ void remove();
+
+private:
+ std::string m_sDirName;
+
+#ifdef _WIN32
+ _finddata_t m_FindData;
+#else
+ dirent * m_pEntry;
+#endif
+
+};
+
+typedef boost::shared_ptr<DirEntry> DirEntryPtr;
+
+}
+
+#endif
+
+
+
diff --git a/src/base/Directory.cpp b/src/base/Directory.cpp
new file mode 100644
index 0000000..bc40ecc
--- /dev/null
+++ b/src/base/Directory.cpp
@@ -0,0 +1,135 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "Directory.h"
+
+#ifdef _WIN32
+#include <Windows.h>
+#endif
+#include <sys/stat.h>
+#include <iostream>
+
+using namespace std;
+
+namespace avg {
+
+Directory::Directory(std::string sName)
+ : m_sName(sName)
+{
+#ifdef _WIN32
+ m_hFile = -1;
+#else
+ m_pDir = 0;
+#endif
+}
+
+Directory::~Directory()
+{
+#ifdef _WIN32
+ _findclose(m_hFile);
+#else
+ if (m_pDir) {
+ closedir(m_pDir);
+ }
+#endif
+}
+
+int Directory::open(bool bCreateIfMissing)
+{
+#ifdef _WIN32
+ m_hFile = _findfirst((m_sName+"/*").c_str(), &m_FindData);
+ if(m_hFile == -1L) {
+ if (bCreateIfMissing) {
+ int err = CreateDirectory(m_sName.c_str(), 0);
+ if (err == 0) {
+ return -1;
+ } else {
+ m_hFile = _findfirst((m_sName+"/*").c_str(), &m_FindData);
+ m_bFirstFile = true;
+ return 0;
+ }
+ } else {
+ return -1;
+ }
+ } else {
+ m_bFirstFile = true;
+ return 0;
+ }
+#else
+ m_pDir = opendir(m_sName.c_str());
+ if (!m_pDir) {
+ if (bCreateIfMissing) {
+ int err = mkdir(m_sName.c_str(),
+ S_IRWXU | S_IRWXG | S_IRWXO);
+ if (err) {
+ return err;
+ } else {
+ m_pDir = opendir(m_sName.c_str());
+ return 0;
+ }
+ } else {
+ return -1;
+ }
+ } else {
+ return 0;
+ }
+#endif
+}
+
+DirEntryPtr Directory::getNextEntry()
+{
+#ifdef _WIN32
+ if (!m_bFirstFile) {
+ int rc = _findnext(m_hFile, &m_FindData);
+ if (rc == -1) {
+ return DirEntryPtr();
+ }
+ }
+ m_bFirstFile = false;
+ return DirEntryPtr(new DirEntry(m_sName, m_FindData));
+#else
+ dirent * pDirent;
+ pDirent = readdir(m_pDir);
+ if (pDirent) {
+ return DirEntryPtr(new DirEntry(m_sName, pDirent));
+ } else {
+ return DirEntryPtr();
+ }
+#endif
+}
+
+const std::string& Directory::getName()
+{
+ return m_sName;
+}
+
+void Directory::empty()
+{
+ DirEntryPtr pEntry;
+ do {
+ pEntry = getNextEntry();
+ if (pEntry) {
+ pEntry->remove();
+ }
+ } while (pEntry);
+}
+
+}
diff --git a/src/base/Directory.h b/src/base/Directory.h
new file mode 100644
index 0000000..f75107d
--- /dev/null
+++ b/src/base/Directory.h
@@ -0,0 +1,64 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _Directory_H_
+#define _Directory_H_
+
+#include "../api.h"
+#include "DirEntry.h"
+
+#ifdef _WIN32
+#include <io.h>
+#else
+#include <dirent.h>
+#endif
+
+#include <string>
+
+namespace avg {
+
+class AVG_API Directory {
+public:
+ Directory(std::string sName);
+ virtual ~Directory();
+
+ int open(bool bCreateIfMissing = false);
+ DirEntryPtr getNextEntry();
+ const std::string& getName();
+ void empty();
+
+private:
+ std::string m_sName;
+
+#ifdef _WIN32
+ _finddata_t m_FindData;
+ intptr_t m_hFile;
+ bool m_bFirstFile;
+#else
+ DIR * m_pDir;
+#endif
+};
+
+}
+
+#endif
+
+
diff --git a/src/base/DlfcnWrapper.cpp b/src/base/DlfcnWrapper.cpp
new file mode 100644
index 0000000..f8011b1
--- /dev/null
+++ b/src/base/DlfcnWrapper.cpp
@@ -0,0 +1,61 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "DlfcnWrapper.h"
+
+#include <sstream>
+#include <string.h>
+
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN
+#endif
+#include "windows.h"
+
+using namespace std;
+
+namespace avg {
+
+void* dlopen(const char *pszPath, int ignored)
+{
+ return LoadLibrary(pszPath);
+}
+
+void dlclose(void* handle)
+{
+ FreeLibrary((HMODULE)handle);
+}
+
+void* dlsym(void* handle, const char* functionName)
+{
+ return GetProcAddress((HMODULE)handle, functionName);
+}
+
+const char* dlerror()
+{
+ static char buffer[1024];
+ int err = GetLastError();
+ ostringstream ss;
+ ss << err;
+ strncpy(buffer,ss.str().c_str(),1023);
+ return buffer;
+}
+
+}
diff --git a/src/base/DlfcnWrapper.h b/src/base/DlfcnWrapper.h
new file mode 100644
index 0000000..883fb37
--- /dev/null
+++ b/src/base/DlfcnWrapper.h
@@ -0,0 +1,41 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _DlfcnWrapper_h_
+#define _DlfcnWrapper_h_
+
+#ifdef _WIN32
+#define RTLD_LOCAL 0
+#define RTLD_NOW 0
+
+namespace avg {
+
+void* dlopen(const char *pszPath, int ignored);
+void dlclose(void* handle);
+void* dlsym(void* handle, const char* functionName);
+const char* dlerror();
+
+}
+#else
+#include <dlfcn.h>
+#endif
+
+#endif
diff --git a/src/base/Exception.cpp b/src/base/Exception.cpp
new file mode 100644
index 0000000..eb4f03c
--- /dev/null
+++ b/src/base/Exception.cpp
@@ -0,0 +1,99 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "Exception.h"
+#include "Backtrace.h"
+#include "Logger.h"
+#include "OSHelper.h"
+
+#include <cstdlib>
+#include <sstream>
+
+#ifdef WIN32
+#include <intrin.h>
+#endif
+
+using namespace std;
+
+namespace avg {
+
+Exception::Exception(int code, const string& sErr)
+ : std::exception(),
+ m_Code (code),
+ m_sErr (sErr)
+{
+}
+
+Exception::Exception(const Exception& ex)
+ : std::exception(),
+ m_Code (ex.getCode()),
+ m_sErr (ex.getStr())
+{
+}
+
+Exception::~Exception() throw()
+{
+}
+
+int Exception::getCode() const
+{
+ return m_Code;
+}
+
+const string& Exception::getStr() const
+{
+ return m_sErr;
+}
+
+const char* Exception::what() const throw()
+{
+ return m_sErr.c_str();
+}
+
+void debugBreak()
+{
+#ifdef _WIN32
+ __debugbreak();
+#else
+ __builtin_trap();
+#endif
+}
+
+void avgAssert(bool b, const char * pszFile, int line, const char * pszReason)
+{
+ if (!b) {
+ string sDummy;
+ static bool bBreak = getEnv("AVG_BREAK_ON_ASSERT", sDummy);
+ if (bBreak) {
+ debugBreak();
+ } else {
+ stringstream ss;
+ ss << "Assertion failed in " << pszFile << ": " << line << endl;
+ if (pszReason) {
+ ss << "Reason: " << pszReason << endl;
+ }
+ dumpBacktrace();
+ throw(Exception(AVG_ERR_ASSERT_FAILED, ss.str()));
+ }
+ }
+}
+
+}
diff --git a/src/base/Exception.h b/src/base/Exception.h
new file mode 100644
index 0000000..b28dc1a
--- /dev/null
+++ b/src/base/Exception.h
@@ -0,0 +1,88 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _Exception_H_
+#define _Exception_H_
+
+#include "../api.h"
+#include <string>
+#include <exception>
+
+#define AVG_ERR_UNKNOWN -1
+#define AVG_ERR_XML_PARSE 1
+#define AVG_ERR_XML_VALID 2
+#define AVG_ERR_XML_EMPTY 3
+#define AVG_ERR_XML_NODE_UNKNOWN 4
+#define AVG_ERR_XML_DUPLICATE_ID 5
+#define AVG_ERR_VIDEO_INIT_FAILED 6
+#define AVG_ERR_VIDEO_GENERAL 7
+#define AVG_ERR_FONT_INIT_FAILED 10
+#define AVG_ERR_VIDEO_LOAD_FAILED 11
+#define AVG_ERR_UNSUPPORTED 12
+#define AVG_ERR_OPTION_SUBSYS_UNKNOWN 13
+#define AVG_ERR_OPTION_UNKNOWN 14
+#define AVG_ERR_FILEIO 15
+#define AVG_ERR_NOT_IN_SCENE 16
+#define AVG_ERR_OUT_OF_RANGE 17
+#define AVG_ERR_ALREADY_CONNECTED 18
+#define AVG_ERR_LOAD_DURING_PLAYBACK 19
+#define AVG_ERR_CANT_PARSE_STRING 20
+#define AVG_ERR_INVALID_CAPTURE 21
+
+#define AVG_ERR_NO_NODE 23
+#define AVG_ERR_NO_ARG 24
+#define AVG_ERR_INVALID_ARGS 25
+#define AVG_ERR_NO_BUILDER 26
+#define AVG_ERR_TYPE 27
+#define AVG_ERR_CORRUPT_PLUGIN 28
+#define AVG_ERR_CAMERA_FATAL 29
+#define AVG_ERR_CAMERA_NONFATAL 30
+#define AVG_ERR_DEPRECATED 31
+#define AVG_ERR_ASSERT_FAILED 32
+#define AVG_ERR_MT_INIT 33
+#define AVG_ERR_DEBUG_CONTEXT_FAILED 34
+
+namespace avg {
+
+class AVG_API Exception: public std::exception
+{
+ public:
+ Exception(int code, const std::string& sErr = "");
+ Exception(const Exception& ex);
+ virtual ~Exception() throw();
+ virtual int getCode() const;
+ virtual const std::string& getStr() const;
+ virtual const char* what() const throw();
+
+ private:
+ int m_Code;
+ std::string m_sErr;
+};
+
+void AVG_API debugBreak();
+void AVG_API avgAssert(bool b, const char * pszFile, int line, const char * pszReason=0);
+
+#define AVG_ASSERT(b) avgAssert((b) != 0, __FILE__, __LINE__);
+#define AVG_ASSERT_MSG(b, pszReason) avgAssert((b) != 0, __FILE__, __LINE__, pszReason);
+
+}
+
+#endif
diff --git a/src/base/FileHelper.cpp b/src/base/FileHelper.cpp
new file mode 100644
index 0000000..d9221c4
--- /dev/null
+++ b/src/base/FileHelper.cpp
@@ -0,0 +1,164 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "FileHelper.h"
+#include "Exception.h"
+
+#ifndef _WIN32
+#include <libgen.h>
+#else
+#include <direct.h>
+#endif
+#include <stdio.h>
+#include <sys/stat.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+#include <vector>
+#include <map>
+#include <cstring>
+#include <iostream>
+#include <fstream>
+
+using namespace std;
+
+namespace avg {
+
+string getPath(const string& sFilename)
+{
+ if (sFilename.length() > 0 && sFilename.at(sFilename.length()-1) == '/') {
+ return sFilename;
+ }
+#ifdef _WIN32
+ int pos = int(sFilename.find_last_of("\\/"));
+ string dirName;
+ if (pos >= 0) {
+ dirName = sFilename.substr(0, pos+1);
+ } else {
+ dirName = sFilename;
+ }
+#else
+ char * pszBuffer = strdup(sFilename.c_str());
+
+ string dirName(dirname(pszBuffer));
+ free(pszBuffer);
+ dirName += "/";
+#endif
+
+ return dirName;
+}
+
+string getFilenamePart(const string& sFilename)
+{
+ if (sFilename.find_last_of("\\/") == 0) {
+ return sFilename;
+ }
+#ifdef _WIN32
+ int pos = int(sFilename.find_last_of("\\/"));
+ string BaseName(sFilename.substr(pos+1));
+#else
+ char * pszBuffer = strdup(sFilename.c_str());
+
+ string BaseName(basename(pszBuffer));
+ free(pszBuffer);
+#endif
+
+ return BaseName;
+}
+
+string getExtension(const string& sFilename)
+{
+ int pos = int(sFilename.find_last_of("."));
+ if (pos == 0) {
+ return "";
+ } else {
+ return sFilename.substr(pos+1);
+ }
+}
+
+string getCWD()
+{
+
+ char szBuf[1024];
+#ifdef _WIN32
+ char * pBuf = _getcwd(szBuf, 1024);
+#else
+ char * pBuf = getcwd(szBuf, 1024);
+#endif
+ return string(pBuf)+"/";
+}
+
+bool isAbsPath(const std::string& path)
+{
+#ifdef _WIN32
+ return ((path.length() != 0) && path[1] == ':') || path[0] == '\\' || path[0] == '/';
+#else
+ return path[0] == '/';
+#endif
+
+}
+
+bool fileExists(const string& sFilename)
+{
+ struct stat myStat;
+ return stat(sFilename.c_str(), &myStat) != -1;
+}
+
+void readWholeFile(const string& sFilename, string& sContent)
+{
+ ifstream file(sFilename.c_str());
+ if (!file) {
+ throw Exception(AVG_ERR_FILEIO, "Opening "+sFilename+
+ " for reading failed.");
+ }
+ vector<char> buffer(65536);
+ sContent.resize(0);
+ while (file) {
+ file.read(&(*buffer.begin()), (streamsize)(buffer.size()));
+ sContent.append(&(*buffer.begin()), (unsigned)file.gcount());
+ }
+ if (!file.eof() || file.bad()) {
+ throw Exception(AVG_ERR_FILEIO, "Reading "+sFilename+
+ " failed.");
+ }
+}
+
+void writeWholeFile(const string& sFilename, const string& sContent)
+{
+ ofstream outFile(sFilename.c_str());
+ if (!outFile) {
+ throw Exception(AVG_ERR_FILEIO, "Opening "+sFilename+
+ " for writing failed.");
+ }
+ outFile << sContent;
+}
+
+
+void copyFile(const string& sSourceFile, const string& sDestFile)
+{
+ string sData;
+
+ readWholeFile(sSourceFile, sData);
+ writeWholeFile(sDestFile, sData);
+}
+
+}
diff --git a/src/base/FileHelper.h b/src/base/FileHelper.h
new file mode 100644
index 0000000..f367d0b
--- /dev/null
+++ b/src/base/FileHelper.h
@@ -0,0 +1,53 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _FileHelper_H_
+#define _FileHelper_H_
+
+#include "../api.h"
+#include <string>
+
+namespace avg {
+
+std::string AVG_API getPath(const std::string& sFilename);
+std::string AVG_API getFilenamePart(const std::string& sFilename);
+std::string AVG_API getExtension(const std::string& sFilename);
+std::string AVG_API getCWD();
+
+bool AVG_API isAbsPath(const std::string& path);
+
+bool AVG_API fileExists(const std::string& sFilename);
+
+void AVG_API readWholeFile(const std::string& sFilename, std::string& sContents);
+
+void AVG_API writeWholeFile(const std::string& sFilename, const std::string& sContent);
+
+void AVG_API copyFile(const std::string& sSourceFile, const std::string& sDestFile);
+
+
+#ifdef WIN32
+#define unlink _unlink
+#endif
+
+}
+
+#endif
+
diff --git a/src/base/GLMHelper.cpp b/src/base/GLMHelper.cpp
new file mode 100644
index 0000000..e4b0f43
--- /dev/null
+++ b/src/base/GLMHelper.cpp
@@ -0,0 +1,183 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "GLMHelper.h"
+#include "StringHelper.h"
+#include "MathHelper.h"
+
+#include "../glm/gtx/rotate_vector.hpp"
+
+using namespace std;
+
+namespace avg {
+
+glm::vec2 getRotated(const glm::vec2& vec, float angle)
+{
+ return glm::rotate(vec, angle*180/PI);
+}
+
+glm::vec2 getRotatedPivot(const glm::vec2& vec, float angle, const glm::vec2& pivot)
+{
+ // translate pivot to origin
+ glm::vec2 translated = vec - pivot;
+
+ // calculate rotated coordinates about the origin
+ glm::vec2 rotated = glm::rotate(translated, angle*180/PI);
+
+ // re-translate pivot to original position
+ rotated += pivot;
+
+ return rotated;
+}
+
+float getAngle(const glm::vec2& vec)
+{
+ return float(atan2(double(vec.y), double(vec.x)));
+}
+
+glm::vec2 fromPolar(float angle, float radius)
+{
+ return glm::vec2(cos(angle)*radius, sin(angle)*radius);
+}
+
+template<class NUM>
+bool almostEqual(const glm::detail::tvec2<NUM>& v1, const glm::detail::tvec2<NUM>& v2)
+{
+ return (fabs(v1.x-v2.x)+fabs(v1.y-v2.y)) < 0.0001;
+}
+
+template<class NUM>
+bool almostEqual(const glm::detail::tvec4<NUM>& v1, const glm::detail::tvec4<NUM>& v2)
+{
+ return (fabs(v1.x-v2.x)+fabs(v1.y-v2.y)+fabs(v1.z-v2.z)+fabs(v1.w-v2.w)) < 0.0001;
+}
+
+template<class NUM>
+std::ostream& operator<<( std::ostream& os, const glm::detail::tvec2<NUM> &v)
+{
+ os << "(" << v.x << "," << v.y << ")";
+ return os;
+}
+
+template<class NUM>
+std::ostream& operator<<( std::ostream& os, const glm::detail::tvec3<NUM> &v)
+{
+ os << "(" << v.x << "," << v.y << "," << v.z << ")";
+ return os;
+}
+
+template<class NUM>
+std::ostream& operator<<( std::ostream& os, const glm::detail::tvec4<NUM> &v)
+{
+ os << "(" << v.x << "," << v.y << "," << v.z << ", " << v.a << ")";
+ return os;
+}
+
+template<class NUM>
+std::ostream& operator<<( std::ostream& os, const glm::detail::tmat4x4<NUM> &m)
+{
+ os << "(" << m[0] << ", " << endl <<
+ m[1] << ", " << endl <<
+ m[2] << ", " << endl <<
+ m[3] << ", " << endl << ")";
+ return os;
+}
+
+template<class NUM>
+std::istream& operator>>(std::istream& is, glm::detail::tvec2<NUM>& p)
+{
+ skipToken(is, '(');
+ is >> p.x;
+ skipToken(is, ',');
+ is >> p.y;
+ skipToken(is, ')');
+ return is;
+}
+
+template<class NUM>
+std::istream& operator>>(std::istream& is, glm::detail::tvec3<NUM>& p)
+{
+ skipToken(is, '(');
+ is >> p.x;
+ skipToken(is, ',');
+ is >> p.y;
+ skipToken(is, ',');
+ is >> p.z;
+ skipToken(is, ')');
+ return is;
+}
+
+glm::vec2 stringToVec2(const std::string& s)
+{
+ glm::vec2 pt;
+ fromString(s, pt);
+ return pt;
+}
+
+glm::vec3 stringToVec3(const std::string& s)
+{
+ glm::vec3 pt;
+ fromString(s, pt);
+ return pt;
+}
+
+glm::ivec3 stringToIVec3(const std::string& s)
+{
+ glm::ivec3 pt;
+ fromString(s, pt);
+ return pt;
+}
+
+
+template AVG_TEMPLATE_API std::ostream& operator<<(std::ostream& os, const glm::detail::tvec2<int> &p);
+template AVG_TEMPLATE_API std::ostream& operator<<(std::ostream& os, const glm::detail::tvec2<float> &p);
+template AVG_TEMPLATE_API std::ostream& operator<<(std::ostream& os, const glm::detail::tvec2<double> &p);
+
+template AVG_TEMPLATE_API std::istream& operator>>(std::istream& is, glm::detail::tvec2<int>& p);
+template AVG_TEMPLATE_API std::istream& operator>>(std::istream& is, glm::detail::tvec2<float>& p);
+template AVG_TEMPLATE_API std::istream& operator>>(std::istream& is, glm::detail::tvec2<double>& p);
+
+template AVG_TEMPLATE_API std::ostream& operator<<(std::ostream& os, const glm::detail::tvec3<int> &p);
+template AVG_TEMPLATE_API std::ostream& operator<<(std::ostream& os, const glm::detail::tvec3<float> &p);
+template AVG_TEMPLATE_API std::ostream& operator<<(std::ostream& os, const glm::detail::tvec3<double> &p);
+
+template AVG_TEMPLATE_API std::istream& operator>>(std::istream& is, glm::detail::tvec3<int>& p);
+template AVG_TEMPLATE_API std::istream& operator>>(std::istream& is, glm::detail::tvec3<float>& p);
+template AVG_TEMPLATE_API std::istream& operator>>(std::istream& is, glm::detail::tvec3<double>& p);
+
+template AVG_TEMPLATE_API std::ostream& operator<<(std::ostream& os, const glm::detail::tvec4<int> &p);
+template AVG_TEMPLATE_API std::ostream& operator<<(std::ostream& os, const glm::detail::tvec4<float> &p);
+template AVG_TEMPLATE_API std::ostream& operator<<(std::ostream& os, const glm::detail::tvec4<double> &p);
+
+template AVG_TEMPLATE_API std::ostream& operator<<(std::ostream& os, const glm::detail::tmat4x4<float> &p);
+template AVG_TEMPLATE_API std::ostream& operator<<(std::ostream& os,
+ const glm::detail::tmat4x4<double> &p);
+
+template AVG_TEMPLATE_API bool almostEqual(const glm::detail::tvec2<float>& v1,
+ const glm::detail::tvec2<float>& v2);
+template AVG_TEMPLATE_API bool almostEqual(const glm::detail::tvec2<double>& v1,
+ const glm::detail::tvec2<double>& v2);
+template AVG_TEMPLATE_API bool almostEqual(const glm::detail::tvec4<float>& v1,
+ const glm::detail::tvec4<float>& v2);
+template AVG_TEMPLATE_API bool almostEqual(const glm::detail::tvec4<double>& v1,
+ const glm::detail::tvec4<double>& v2);
+}
+
diff --git a/src/base/GLMHelper.h b/src/base/GLMHelper.h
new file mode 100644
index 0000000..4af8991
--- /dev/null
+++ b/src/base/GLMHelper.h
@@ -0,0 +1,70 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _GLMHelper_H_
+#define _GLMHelper_H_
+
+#include "../api.h"
+
+#include "../glm/glm.hpp"
+#include "../glm/gtc/matrix_transform.hpp"
+#include "../glm/gtc/type_ptr.hpp"
+
+#include <iostream>
+#include <vector>
+
+namespace avg {
+
+glm::vec2 getRotated(const glm::vec2& vec, float angle);
+glm::vec2 getRotatedPivot(const glm::vec2& vec, float angle,
+ const glm::vec2& pivot=glm::vec2(0,0));
+float getAngle(const glm::vec2& vec);
+glm::vec2 fromPolar(float angle, float radius);
+
+template<class NUM>
+bool almostEqual(const glm::detail::tvec2<NUM>& v1, const glm::detail::tvec2<NUM>& v2);
+template<class NUM>
+bool almostEqual(const glm::detail::tvec4<NUM>& v1, const glm::detail::tvec4<NUM>& v2);
+
+template<class NUM>
+std::ostream& operator<<(std::ostream& os, const glm::detail::tvec2<NUM> &v);
+template<class NUM>
+std::ostream& operator<<(std::ostream& os, const glm::detail::tvec3<NUM> &v);
+template<class NUM>
+std::ostream& operator<<(std::ostream& os, const glm::detail::tvec4<NUM> &v);
+template<class NUM>
+std::ostream& operator<<(std::ostream& os, const glm::detail::tmat4x4<NUM> &v);
+
+template<class NUM>
+std::istream& operator>>(std::istream& is, glm::detail::tvec2<NUM>& p);
+template<class NUM>
+std::istream& operator>>(std::istream& is, glm::detail::tvec3<NUM>& p);
+
+typedef glm::ivec2 IntPoint;
+typedef std::vector<glm::vec2> Vec2Vector;
+
+glm::vec2 stringToVec2(const std::string& s);
+glm::vec3 stringToVec3(const std::string& s);
+glm::ivec3 stringToIVec3(const std::string& s);
+
+}
+
+#endif
diff --git a/src/base/GeomHelper.cpp b/src/base/GeomHelper.cpp
new file mode 100644
index 0000000..da167ad
--- /dev/null
+++ b/src/base/GeomHelper.cpp
@@ -0,0 +1,178 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "GeomHelper.h"
+
+#include <math.h>
+#include <iostream>
+
+using namespace std;
+
+namespace avg {
+
+LineSegment::LineSegment(const glm::vec2& pt0, const glm::vec2& pt1)
+ : p0(pt0),
+ p1(pt1)
+{
+}
+
+bool LineSegment::isPointOver(const glm::vec2& pt)
+{
+ glm::vec2 c = pt - p0;
+ glm::vec2 v = (p1 - p0);
+ float d = glm::length(v);
+ v /= d;
+ float t = glm::dot(v, c);
+
+ return (t >= 0 && t <= d);
+}
+
+// Code adapted from Antonio, Franklin, "Faster Line Segment Intersection,"
+// Graphics Gems III (David Kirk, ed.), Academic Press, pp. 199-202, 1992.
+bool lineSegmentsIntersect(const LineSegment& l0, const LineSegment& l1)
+{
+ float xdiff0 = l0.p1.x-l0.p0.x;
+ float xdiff1 = l1.p0.x-l1.p1.x;
+
+ float x1lo, x1hi;
+
+ /* X bound box test*/
+ if (xdiff0 < 0) {
+ x1lo=l0.p1.x;
+ x1hi=l0.p0.x;
+ } else {
+ x1hi=l0.p1.x;
+ x1lo=l0.p0.x;
+ }
+ if (xdiff1 > 0) {
+ if (x1hi < l1.p1.x || l1.p0.x < x1lo) {
+ return false;
+ }
+ } else {
+ if (x1hi < l1.p0.x || l1.p1.x < x1lo) {
+ return false;
+ }
+ }
+
+ float ydiff0 = l0.p1.y-l0.p0.y;
+ float ydiff1 = l1.p0.y-l1.p1.y;
+
+ float y1lo, y1hi;
+
+ /* Y bound box test*/
+ if (ydiff0 < 0) {
+ y1lo=l0.p1.y;
+ y1hi=l0.p0.y;
+ } else {
+ y1hi=l0.p1.y;
+ y1lo=l0.p0.y;
+ }
+ if (ydiff1 > 0) {
+ if (y1hi < l1.p1.y || l1.p0.y < y1lo) {
+ return false;
+ }
+ } else {
+ if (y1hi < l1.p0.y || l1.p1.y < y1lo) {
+ return false;
+ }
+ }
+
+ float Cx = l0.p0.x-l1.p0.x;
+ float Cy = l0.p0.y-l1.p0.y;
+ float d = ydiff1*Cx - xdiff1*Cy; /* alpha numerator*/
+ float f = ydiff0*xdiff1 - xdiff0*ydiff1; /* both denominator*/
+ if (f > 0) { /* alpha tests*/
+ if (d < 0 || d > f) {
+ return false;
+ }
+ } else {
+ if (d > 0 || d < f) {
+ return false;
+ }
+ }
+
+ float e = xdiff0*Cy - ydiff0*Cx; /* beta numerator*/
+ if(f > 0) { /* beta tests*/
+ if (e < 0 || e > f) {
+ return false;
+ }
+ } else {
+ if (e > 0 || e < f) {
+ return false;
+ }
+ }
+
+ if (f == 0) {
+ // Theoretically, lines could still intersect in this case, but we don't care
+ // because given numerical inaccuracies, the result is random anyway :-).
+ return false;
+ }
+
+// /*compute intersection coordinates*/
+// float num = d*xdiff0; /* numerator */
+// offset = SAME_SIGNS(num,f) ? f/2 : -f/2; /* round direction*/
+// *x = x1 + (num+offset) / f; /* intersection x */
+//
+// num = d*ydiff0;
+// offset = SAME_SIGNS(num,f) ? f/2 : -f/2;
+// *y = y1 + (num+offset) / f; /* intersection y */
+
+ return true;
+}
+
+// Original code from:
+// http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html.
+// Precomputing a bounding box for the polygon would speed this up a lot,
+// but the function hasn't shown up on any profiles so far.
+bool pointInPolygon(const glm::vec2& pt, const vector<glm::vec2>& poly)
+{
+ if (poly.size() < 3) {
+ return false;
+ }
+ bool bPtInPoly = false;
+ for (unsigned i = 0, j = poly.size()-1; i < poly.size(); j = i++) {
+ if (((poly[i].y > pt.y) != (poly[j].y > pt.y)) &&
+ (pt.x < (poly[j].x-poly[i].x)*(pt.y-poly[i].y) / (poly[j].y-poly[i].y)
+ +poly[i].x))
+ {
+ bPtInPoly = !bPtInPoly;
+ }
+ }
+ return bPtInPoly;
+}
+
+glm::vec2 getLineLineIntersection(const glm::vec2& p1, const glm::vec2& v1,
+ const glm::vec2& p2, const glm::vec2& v2)
+{
+ float denom = v2.y*v1.x-v2.x*v1.y;
+ if (fabs(denom) < 0.0000001) {
+ // If the lines are parallel or coincident, we just return p2!
+ return p2;
+ }
+ float numer = v2.x*(p1.y-p2.y) - v2.y*(p1.x-p2.x);
+ float ua = numer/denom;
+
+ return p1+ua*v1;
+
+}
+
+
+}
diff --git a/src/base/GeomHelper.h b/src/base/GeomHelper.h
new file mode 100644
index 0000000..5774231
--- /dev/null
+++ b/src/base/GeomHelper.h
@@ -0,0 +1,51 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _GeomHelper_H_
+#define _GeomHelper_H_
+
+#include "../api.h"
+
+#include "../glm/glm.hpp"
+
+#include <vector>
+
+namespace avg {
+
+struct AVG_API LineSegment {
+public:
+ LineSegment(const glm::vec2& pt0, const glm::vec2& pt1);
+ glm::vec2 p0;
+ glm::vec2 p1;
+
+ bool isPointOver(const glm::vec2& pt);
+};
+
+bool AVG_API lineSegmentsIntersect(const LineSegment& l0, const LineSegment& l1);
+
+bool AVG_API pointInPolygon(const glm::vec2& pt, const std::vector<glm::vec2>& poly);
+
+glm::vec2 AVG_API getLineLineIntersection(const glm::vec2& p1, const glm::vec2& v1,
+ const glm::vec2& p2, const glm::vec2& v2);
+
+}
+#endif
+
diff --git a/src/base/IFrameEndListener.h b/src/base/IFrameEndListener.h
new file mode 100644
index 0000000..6147dbe
--- /dev/null
+++ b/src/base/IFrameEndListener.h
@@ -0,0 +1,37 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _IFrameEndListener_H_
+#define _IFrameEndListener_H_
+
+#include "../api.h"
+
+namespace avg {
+
+class AVG_API IFrameEndListener {
+public:
+ virtual ~IFrameEndListener() {};
+ virtual void onFrameEnd() = 0;
+};
+
+}
+
+#endif
diff --git a/src/base/ILogSink.h b/src/base/ILogSink.h
new file mode 100644
index 0000000..de4c1da
--- /dev/null
+++ b/src/base/ILogSink.h
@@ -0,0 +1,53 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+
+#ifndef _ILOGHANDLER_H_
+#define _ILOGHANDLER_H_
+
+#include "UTF8String.h"
+
+#ifdef _WIN32
+#include <time.h>
+#else
+#include <sys/time.h>
+#endif
+
+#include <boost/shared_ptr.hpp>
+
+using namespace std;
+
+namespace avg{
+
+typedef unsigned severity_t;
+typedef UTF8String category_t;
+
+class AVG_API ILogSink
+{
+public:
+ virtual void logMessage(const tm* pTime, unsigned millis, const category_t& category,
+ severity_t severity, const UTF8String& sMsg) = 0;
+
+};
+
+typedef boost::shared_ptr<ILogSink> LogSinkPtr;
+
+}
+
+#endif
diff --git a/src/base/IPlaybackEndListener.h b/src/base/IPlaybackEndListener.h
new file mode 100644
index 0000000..f505177
--- /dev/null
+++ b/src/base/IPlaybackEndListener.h
@@ -0,0 +1,38 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _IPlaybackEndListener_H_
+#define _IPlaybackEndListener_H_
+
+#include "../api.h"
+
+namespace avg {
+
+class AVG_API IPlaybackEndListener {
+public:
+ virtual ~IPlaybackEndListener() {};
+ virtual void onPlaybackEnd() = 0;
+};
+
+}
+
+#endif
+
diff --git a/src/base/IPreRenderListener.h b/src/base/IPreRenderListener.h
new file mode 100644
index 0000000..32c244e
--- /dev/null
+++ b/src/base/IPreRenderListener.h
@@ -0,0 +1,35 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _IPreRenderListener_H_
+#define _IPreRenderListener_H_
+
+namespace avg {
+
+class AVG_API IPreRenderListener {
+public:
+ virtual ~IPreRenderListener() {};
+ virtual void onPreRender() = 0;
+};
+
+}
+
+#endif
diff --git a/src/base/Logger.cpp b/src/base/Logger.cpp
new file mode 100644
index 0000000..dd7efe1
--- /dev/null
+++ b/src/base/Logger.cpp
@@ -0,0 +1,280 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "Logger.h"
+#include "Exception.h"
+#include "StandardLogSink.h"
+#include "OSHelper.h"
+
+#include <boost/algorithm/string.hpp>
+
+#ifdef _WIN32
+#include <Winsock2.h>
+#include <time.h>
+#include <Mmsystem.h>
+#undef ERROR
+#else
+#include <sys/time.h>
+#include <syslog.h>
+#endif
+#include <iostream>
+#include <iomanip>
+
+using namespace std;
+namespace ba = boost::algorithm;
+
+namespace avg {
+ const severity_t Logger::severity::CRITICAL = 50;
+ const severity_t Logger::severity::ERROR = 40;
+ const severity_t Logger::severity::WARNING = 30;
+ const severity_t Logger::severity::INFO = 20;
+ const severity_t Logger::severity::DEBUG = 10;
+ const severity_t Logger::severity::NONE = 0;
+
+ const category_t Logger::category::NONE = UTF8String("NONE");
+ const category_t Logger::category::PROFILE = UTF8String("PROFILE");
+ const category_t Logger::category::PROFILE_VIDEO = UTF8String("PROFILE_V");
+ const category_t Logger::category::EVENTS = UTF8String("EVENTS");
+ const category_t Logger::category::CONFIG = UTF8String("CONFIG");
+ const category_t Logger::category::MEMORY = UTF8String("MEMORY");
+ const category_t Logger::category::APP = UTF8String("APP");
+ const category_t Logger::category::PLUGIN = UTF8String("PLUGIN");
+ const category_t Logger::category::PLAYER = UTF8String("PLAYER");
+ const category_t Logger::category::SHADER = UTF8String("SHADER");
+ const category_t Logger::category::DEPRECATION = UTF8String("DEPREC");
+
+namespace {
+ Logger* s_pLogger = 0;
+ boost::mutex s_logMutex;
+ boost::mutex s_traceMutex;
+ boost::mutex s_sinkMutex;
+ boost::mutex s_removeStdSinkMutex;
+}
+
+boost::mutex Logger::m_CategoryMutex;
+
+Logger * Logger::get()
+{
+ lock_guard lock(s_logMutex);
+ if (!s_pLogger) {
+ s_pLogger = new Logger;
+ }
+ return s_pLogger;
+}
+
+Logger::Logger()
+{
+ m_Severity = severity::WARNING;
+ string sEnvSeverity;
+ bool bEnvSeveritySet = getEnv("AVG_LOG_SEVERITY", sEnvSeverity);
+ if(bEnvSeveritySet) {
+ m_Severity = Logger::stringToSeverity(sEnvSeverity);
+ }
+ setupCategory();
+
+ string sEnvCategories;
+ bool bEnvSet = getEnv("AVG_LOG_CATEGORIES", sEnvCategories);
+ if (bEnvSet) {
+ vector<string> sCategories;
+ ba::split(sCategories, sEnvCategories, ba::is_any_of(" "), ba::token_compress_on);
+ vector<string>::iterator it;
+ for(it=sCategories.begin(); it!=sCategories.end(); it++) {
+ string::size_type pos = (*it).find(":");
+ string sCategory;
+ string sSeverity = "NONE";
+ if(pos == string::npos) {
+ sCategory = *it;
+ } else {
+ vector<string> tmpValues;
+ ba::split( tmpValues, *it, ba::is_any_of(":"), ba::token_compress_on);
+ sCategory = tmpValues.at(0);
+ sSeverity = tmpValues.at(1);
+ }
+ severity_t severity = stringToSeverity(sSeverity);
+ configureCategory(sCategory, severity);
+ }
+ }
+
+ string sDummy;
+ bool bEnvOmitStdErr = getEnv("AVG_LOG_OMIT_STDERR", sDummy);
+ if (!bEnvOmitStdErr) {
+ m_pStdSink = LogSinkPtr(new StandardLogSink);
+ addLogSink(m_pStdSink);
+ }
+}
+
+Logger::~Logger()
+{
+}
+
+void Logger::addLogSink(const LogSinkPtr& logSink)
+{
+ lock_guard lock(s_sinkMutex);
+ m_pSinks.push_back(logSink);
+}
+
+void Logger::removeLogSink(const LogSinkPtr& logSink)
+{
+ lock_guard lock(s_sinkMutex);
+ std::vector<LogSinkPtr>::iterator it;
+ it = find(m_pSinks.begin(), m_pSinks.end(), logSink);
+ if ( it != m_pSinks.end() ) {
+ m_pSinks.erase(it);
+ }
+}
+
+void Logger::removeStdLogSink()
+{
+ lock_guard lock(s_removeStdSinkMutex);
+ if ( m_pStdSink.get()) {
+ removeLogSink(m_pStdSink);
+ m_pStdSink = LogSinkPtr();
+ }
+}
+
+category_t Logger::configureCategory(category_t category, severity_t severity)
+{
+ lock_guard lock(m_CategoryMutex);
+ severity = (severity == Logger::severity::NONE) ? m_Severity : severity;
+ UTF8String sCategory = boost::to_upper_copy(string(category));
+ CatToSeverityMap::iterator it;
+ it = m_CategorySeverities.find(sCategory);
+ if ( it != m_CategorySeverities.end()) {
+ m_CategorySeverities.erase(sCategory);
+ }
+ pair<const category_t, const severity_t> element(sCategory, severity);
+ m_CategorySeverities.insert(element);
+ return sCategory;
+}
+
+CatToSeverityMap Logger::getCategories()
+{
+ return m_CategorySeverities;
+}
+
+void Logger::trace(const UTF8String& sMsg, const category_t& category,
+ severity_t severity) const
+{
+ lock_guard lock(s_traceMutex);
+ struct tm* pTime;
+ #ifdef _WIN32
+ __int64 now;
+ _time64(&now);
+ pTime = _localtime64(&now);
+ DWORD tms = timeGetTime();
+ unsigned millis = unsigned(tms % 1000);
+ #else
+ struct timeval time;
+ gettimeofday(&time, NULL);
+ pTime = localtime(&time.tv_sec);
+ unsigned millis = time.tv_usec/1000;
+ #endif
+ lock_guard lockHandler(s_sinkMutex);
+ std::vector<LogSinkPtr>::const_iterator it;
+ for(it=m_pSinks.begin(); it!=m_pSinks.end(); ++it){
+ (*it)->logMessage(pTime, millis, category, severity, sMsg);
+ }
+}
+
+void Logger::logDebug(const UTF8String& msg, const category_t& category) const
+{
+ log(msg, category, Logger::severity::DEBUG);
+}
+
+void Logger::logInfo(const UTF8String& msg, const category_t& category) const
+{
+ log(msg, category, Logger::severity::INFO);
+}
+
+void Logger::logWarning(const UTF8String& msg, const category_t& category) const
+{
+ log(msg, category, Logger::severity::WARNING);
+}
+
+void Logger::logError(const UTF8String& msg, const category_t& category) const
+{
+ log(msg, category, Logger::severity::ERROR);
+}
+
+void Logger::logCritical(const UTF8String& msg, const category_t& category) const
+{
+ log(msg, category, Logger::severity::CRITICAL);
+}
+
+void Logger::log(const UTF8String& msg, const category_t& category,
+ severity_t severity) const
+{
+ if(shouldLog(category, severity)) {
+ Logger::trace(msg, category, severity);
+ }
+}
+
+void Logger::setupCategory()
+{
+ configureCategory(category::NONE);
+ configureCategory(category::PROFILE);
+ configureCategory(category::PROFILE_VIDEO);
+ configureCategory(category::EVENTS);
+ configureCategory(category::CONFIG);
+ configureCategory(category::MEMORY);
+ configureCategory(category::APP);
+ configureCategory(category::PLUGIN);
+ configureCategory(category::PLAYER);
+ configureCategory(category::SHADER);
+ configureCategory(category::DEPRECATION);
+}
+
+severity_t Logger::stringToSeverity(const string& sSeverity)
+{
+ string severity = boost::to_upper_copy(string(sSeverity));
+ if (severity == "CRIT") {
+ return Logger::severity::CRITICAL;
+ } else if (severity == "ERR") {
+ return Logger::severity::ERROR;
+ } else if (severity == "WARN") {
+ return Logger::severity::WARNING;
+ } else if (severity == "INFO") {
+ return Logger::severity::INFO;
+ } else if (severity == "DBG") {
+ return Logger::severity::DEBUG;
+ } else if (severity == "NONE") {
+ return Logger::severity::NONE;
+ }
+ throw Exception(AVG_ERR_INVALID_ARGS, severity + " is an invalid log severity");
+}
+
+const char * Logger::severityToString(severity_t severity)
+{
+ if(severity == Logger::severity::CRITICAL) {
+ return "CRIT";
+ } else if(severity == Logger::severity::ERROR) {
+ return "ERR";
+ } else if(severity == Logger::severity::WARNING) {
+ return "WARN";
+ } else if(severity == Logger::severity::INFO) {
+ return "INFO";
+ } else if(severity == Logger::severity::DEBUG) {
+ return "DBG";
+ }
+ throw Exception(AVG_ERR_UNKNOWN, "Unkown log severity");
+}
+
+}
diff --git a/src/base/Logger.h b/src/base/Logger.h
new file mode 100644
index 0000000..197c0c2
--- /dev/null
+++ b/src/base/Logger.h
@@ -0,0 +1,154 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _Logger_H_
+#define _Logger_H_
+
+#include "Exception.h"
+#include "ILogSink.h"
+#include "UTF8String.h"
+#include "ThreadHelper.h"
+#include "../api.h"
+
+#include <boost/noncopyable.hpp>
+#include <boost/functional/hash.hpp>
+#include <boost/unordered_map.hpp>
+
+#include <string>
+#include <vector>
+#include <sstream>
+
+#ifdef ERROR
+#undef ERROR
+#endif
+
+namespace avg {
+
+typedef boost::unordered_map< const category_t, const severity_t > CatToSeverityMap;
+
+#ifdef _WIN32
+// non dll-interface class used as base for dll-interface class
+#pragma warning(disable:4275)
+#endif
+class AVG_API Logger: private boost::noncopyable {
+public:
+ struct AVG_API severity
+ {
+ static const severity_t CRITICAL;
+ static const severity_t ERROR;
+ static const severity_t WARNING;
+ static const severity_t INFO;
+ static const severity_t DEBUG;
+ static const severity_t NONE;
+ };
+
+ struct AVG_API category
+ {
+ static const category_t NONE;
+ static const category_t PROFILE;
+ static const category_t PROFILE_VIDEO;
+ static const category_t EVENTS;
+ static const category_t CONFIG;
+ static const category_t MEMORY;
+ static const category_t APP;
+ static const category_t PLUGIN;
+ static const category_t PLAYER;
+ static const category_t SHADER;
+ static const category_t DEPRECATION;
+ };
+
+ static Logger* get();
+ virtual ~Logger();
+
+ static severity_t stringToSeverity(const string& sSeverity);
+ static const char * severityToString(const severity_t severity);
+
+ void addLogSink(const LogSinkPtr& logSink);
+ void removeLogSink(const LogSinkPtr& logSink);
+ void removeStdLogSink();
+
+ category_t configureCategory(category_t category,
+ severity_t severity=severity::NONE);
+ CatToSeverityMap getCategories();
+
+ void trace(const UTF8String& sMsg, const category_t& category,
+ severity_t severity) const;
+ void logDebug(const UTF8String& msg,
+ const category_t& category=category::APP) const;
+ void logInfo(const UTF8String& msg,
+ const category_t& category=category::APP) const;
+ void logWarning(const UTF8String& msg,
+ const category_t& category=category::APP) const;
+ void logError(const UTF8String& msg,
+ const category_t& category=category::APP) const;
+ void logCritical(const UTF8String& msg,
+ const category_t& category=category::APP) const;
+ void log(const UTF8String& msg, const category_t& category=category::APP,
+ severity_t severity=severity::INFO) const;
+
+ inline bool shouldLog(const category_t& category, severity_t severity) const {
+ lock_guard lock(m_CategoryMutex);
+ try {
+ severity_t targetSeverity = m_CategorySeverities.at(category);
+ return (targetSeverity <= severity);
+ } catch (out_of_range e){
+ string msg("Unknown category: " + category);
+ throw Exception(AVG_ERR_INVALID_ARGS, msg);
+ }
+ }
+
+private:
+ Logger();
+ void setupCategory();
+
+ std::vector<LogSinkPtr> m_pSinks;
+ LogSinkPtr m_pStdSink;
+ CatToSeverityMap m_CategorySeverities;
+ severity_t m_Severity;
+ static boost::mutex m_CategoryMutex;
+};
+
+#define AVG_TRACE(category, severity, sMsg) { \
+if (Logger::get()->shouldLog(category, severity)) { \
+ std::stringstream tmp(std::stringstream::in | std::stringstream::out); \
+ tmp << sMsg; \
+ Logger::get()->trace(tmp.str(), category, severity); \
+ }\
+}\
+
+#define AVG_LOG_ERROR(sMsg){ \
+ AVG_TRACE(Logger::category::NONE, Logger::severity::ERROR, sMsg); \
+}\
+
+#define AVG_LOG_WARNING(sMsg){ \
+ AVG_TRACE(Logger::category::NONE, Logger::severity::WARNING, sMsg); \
+}\
+
+#define AVG_LOG_INFO(sMsg){ \
+ AVG_TRACE(Logger::category::NONE, Logger::severity::INFO, sMsg); \
+}\
+
+#define AVG_LOG_DEBUG(sMsg){ \
+ AVG_TRACE(Logger::category::NONE, Logger::severity::DEBUG, sMsg); \
+}\
+
+}
+#endif
diff --git a/src/base/Makefile.am b/src/base/Makefile.am
new file mode 100644
index 0000000..ce995f2
--- /dev/null
+++ b/src/base/Makefile.am
@@ -0,0 +1,35 @@
+SUBDIRS = triangulate
+
+AM_CPPFLAGS = -I.. @XML2_CFLAGS@ @PTHREAD_CFLAGS@
+ALL_H = FileHelper.h Exception.h Logger.h ConfigMgr.h ObjectCounter.h \
+ XMLHelper.h TimeSource.h ProfilingZone.h ThreadProfiler.h \
+ ScopeTimer.h IFrameEndListener.h IPreRenderListener.h IPlaybackEndListener.h \
+ Test.h TestSuite.h OSHelper.h Queue.h WorkerThread.h Command.h ObjectCounter.h \
+ Rect.h Directory.h DirEntry.h StringHelper.h MathHelper.h GeomHelper.h \
+ CubicSpline.h BezierCurve.h UTF8String.h Triangle.h DAG.h \
+ WideLine.h DlfcnWrapper.h Signal.h Backtrace.h \
+ CmdQueue.h ProfilingZoneID.h GLMHelper.h StandardLogSink.h ILogSink.h \
+ ThreadHelper.h
+
+TESTS = testbase
+
+EXTRA_DIST = DlfcnWrapper.cpp
+
+noinst_LTLIBRARIES = libbase.la
+libbase_la_SOURCES = FileHelper.cpp Exception.cpp Logger.cpp \
+ ConfigMgr.cpp XMLHelper.cpp TimeSource.cpp OSHelper.cpp \
+ ProfilingZone.cpp ThreadProfiler.cpp ScopeTimer.cpp Test.cpp \
+ TestSuite.cpp ObjectCounter.cpp Directory.cpp DirEntry.cpp \
+ StringHelper.cpp MathHelper.cpp GeomHelper.cpp CubicSpline.cpp \
+ BezierCurve.cpp UTF8String.cpp Triangle.cpp DAG.cpp WideLine.cpp \
+ Backtrace.cpp ProfilingZoneID.cpp GLMHelper.cpp \
+ WorkerThread.cpp StandardLogSink.cpp ThreadHelper.cpp \
+ $(ALL_H)
+libbase_a_CXXFLAGS = -Wno-format-y2k
+
+noinst_PROGRAMS = testbase
+testbase_SOURCES = testbase.cpp $(ALL_H)
+testbase_LDADD = ./libbase.la ./triangulate/libtriangulate.la \
+ @BOOST_THREAD_LIBS@ @XML2_LIBS@ @PTHREAD_LIBS@
+# -rdynamic needed only for testBacktrace to work under linux.
+testbase_LDFLAGS = -rdynamic
diff --git a/src/base/MathHelper.cpp b/src/base/MathHelper.cpp
new file mode 100644
index 0000000..388859d
--- /dev/null
+++ b/src/base/MathHelper.cpp
@@ -0,0 +1,78 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "MathHelper.h"
+
+#include <math.h>
+#include <iostream>
+
+using namespace std;
+
+namespace avg {
+
+bool ispow2(int n)
+{
+ return ((n & (n-1)) == 0);
+}
+
+int nextpow2(int n)
+{
+ n--;
+ n |= n >> 1; // handle 2 bit numbers
+ n |= n >> 2; // handle 4 bit numbers
+ n |= n >> 4; // handle 8 bit numbers
+ n |= n >> 8; // handle 16 bit numbers
+ n |= n >> 16; // handle 32 bit numbers
+ n++;
+ return n;
+}
+
+int safeCeil(float d)
+{
+ if (fabs(d-int(d)) < EPSILON) {
+ return int(d);
+ } else {
+ return int(d)+1;
+ }
+}
+
+float invSqrt(float x)
+{
+#if 0
+ // TODO: This gives incorrect results on Athlon X2, gcc 4.2.
+ float xhalf = 0.5f*x;
+ int i = *(int*)&x; // get bits for floating value
+ i = 0x5f3759d5 - (i>>1); // give initial guess y0
+ x = *(float*)&i; // convert bits back to float
+ x *= 1.5f - xhalf*x*x; // newton step, repeating this step
+ // increases accuracy
+ x *= 1.5f - xhalf*x*x;
+ return x;
+#endif
+ return 1/sqrt(x);
+}
+
+bool almostEqual(float d1, float d2, float epsilon)
+{
+ return (fabs(d1-d2)<epsilon);
+}
+
+}
diff --git a/src/base/MathHelper.h b/src/base/MathHelper.h
new file mode 100644
index 0000000..587ff2c
--- /dev/null
+++ b/src/base/MathHelper.h
@@ -0,0 +1,93 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _MathHelper_H_
+#define _MathHelper_H_
+
+#include "../api.h"
+#include <vector>
+#include <set>
+
+#include <math.h>
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
+namespace avg {
+
+static const float PI = 3.14159265358979323846f;
+static const float EPSILON = 0.00001f;
+
+bool ispow2(int n);
+
+int nextpow2(int n);
+
+int safeCeil(float d);
+
+bool almostEqual(float d1, float d2, float epsilon=EPSILON);
+
+float invSqrt(float x);
+
+template<class T>
+T sqr(T d)
+{
+ return d*d;
+}
+
+template<class T>
+int sgn(T val)
+{
+ return int(val/fabs(val));
+}
+
+template<class T>
+std::vector<T> vectorFromCArray(int n, T* pData)
+{
+ std::vector<T> v;
+ for (int i=0; i<n; ++i) {
+ v.push_back(*(pData+i));
+ }
+ return v;
+}
+
+template<class T>
+std::vector<std::vector<T> > vector2DFromCArray(int n, int m, T* pData)
+{
+ std::vector<std::vector<T> > v(4, std::vector<T>());
+ for (int i=0; i<n; ++i) {
+ for (int j=0; j<m; ++j) {
+ v[i].push_back(*(pData+j+i*m));
+ }
+ }
+ return v;
+}
+
+#ifndef round
+template<class T>
+T round(T d)
+{
+ return floor(d + 0.5f);
+}
+#endif
+
+}
+#endif
+
diff --git a/src/base/OSHelper.cpp b/src/base/OSHelper.cpp
new file mode 100644
index 0000000..377e725
--- /dev/null
+++ b/src/base/OSHelper.cpp
@@ -0,0 +1,308 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "OSHelper.h"
+#include "FileHelper.h"
+#include "Logger.h"
+#include "FileHelper.h"
+#include "Exception.h"
+
+#if defined(_WIN32)
+#include <windows.h>
+#include <psapi.h>
+#undef ERROR
+#undef WARNING
+#elif defined(__APPLE__)
+#include <mach-o/dyld.h>
+#include <mach/mach.h>
+#include <sys/utsname.h>
+#elif defined(__linux)
+#include <fstream>
+#include <unistd.h>
+#include <string.h>
+#endif
+
+#include <stdlib.h>
+#include <iostream>
+#include <cstdlib>
+
+using namespace std;
+
+namespace avg {
+
+#ifdef _WIN32
+string getWinErrMsg(unsigned err)
+{
+ LPVOID lpMsgBuf;
+ FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf,
+ 0, NULL );
+ string sMsg((char*)lpMsgBuf);
+ LocalFree(lpMsgBuf);
+ return sMsg;
+}
+#endif
+
+#if defined(__linux)
+// Adapted from binreloc
+static char *
+_br_find_exe_for_symbol (const void *symbol)
+{
+ #define SIZE 1024
+ FILE *f;
+ size_t address_string_len;
+ char *address_string, line[SIZE], *found;
+
+ if (symbol == NULL)
+ return (char *) NULL;
+
+ f = fopen ("/proc/self/maps", "r");
+ if (f == NULL)
+ return (char *) NULL;
+
+ address_string_len = 4;
+ address_string = (char *) malloc(address_string_len);
+ found = (char *) NULL;
+
+
+ while (!feof (f)) {
+ char *start_addr, *end_addr, *end_addr_end, *file;
+ void *start_addr_p, *end_addr_p;
+ size_t len;
+
+ if (fgets (line, SIZE, f) == NULL)
+ break;
+
+ /* Sanity check. */
+ if (strstr (line, " r-xp ") == NULL || strchr (line, '/') == NULL)
+ continue;
+
+ /* Parse line. */
+ start_addr = line;
+ end_addr = strchr (line, '-');
+ file = strchr (line, '/');
+
+ /* More sanity check. */
+ if (!(file > end_addr && end_addr != NULL && end_addr[0] == '-'))
+ continue;
+
+ end_addr[0] = '\0';
+ end_addr++;
+ end_addr_end = strchr (end_addr, ' ');
+ if (end_addr_end == NULL)
+ continue;
+
+ end_addr_end[0] = '\0';
+ len = strlen (file);
+ if (len == 0)
+ continue;
+ if (file[len - 1] == '\n')
+ file[len - 1] = '\0';
+
+ /* Get rid of "(deleted)" from the filename. */
+ len = strlen (file);
+ if (len > 10 && strcmp (file + len - 10, " (deleted)") == 0)
+ file[len - 10] = '\0';
+
+ /* I don't know whether this can happen but better safe than sorry. */
+ len = strlen (start_addr);
+ if (len != strlen (end_addr))
+ continue;
+
+
+ /* Transform the addresses into a string in the form of 0xdeadbeef,
+ * then transform that into a pointer. */
+ if (address_string_len < len + 3) {
+ address_string_len = len + 3;
+ address_string = (char *) realloc (address_string, address_string_len);
+ }
+
+ memcpy (address_string, "0x", 2);
+ memcpy (address_string + 2, start_addr, len);
+ address_string[2 + len] = '\0';
+ sscanf (address_string, "%p", &start_addr_p);
+
+ memcpy (address_string, "0x", 2);
+ memcpy (address_string + 2, end_addr, len);
+ address_string[2 + len] = '\0';
+ sscanf (address_string, "%p", &end_addr_p);
+
+
+ if (symbol >= start_addr_p && symbol < end_addr_p) {
+ found = file;
+ break;
+ }
+ }
+
+ free (address_string);
+ fclose (f);
+
+ if (found == NULL)
+ return (char *) NULL;
+ else
+ return strdup (found);
+}
+#endif
+
+string getAvgLibPath()
+{
+#if defined(_WIN32)
+ HMODULE hModule = GetModuleHandle("avg.pyd");
+ char szFilename[1024];
+ DWORD ok = GetModuleFileName(hModule, szFilename, sizeof(szFilename));
+ if (ok == 0) {
+ AVG_LOG_ERROR("getAvgLibPath(): " << getWinErrMsg(GetLastError()));
+ exit(5);
+ }
+ string sPath=getPath(szFilename);
+ return sPath;
+#elif defined(__APPLE__)
+ // We need to iterate through all images attached to the current executable
+ // and figure out which one is the one we are interested in.
+ uint32_t numImages = _dyld_image_count();
+ for (uint32_t i=0; i<numImages; i++) {
+ const char * pszImageName = _dyld_get_image_name(i);
+ string sFilePart=getFilenamePart(pszImageName);
+ if (sFilePart == "avg.so" || sFilePart == "avg.0.so"
+ || sFilePart == "avg.0.0.0.so")
+ {
+ return getPath(pszImageName);
+ }
+ }
+ char path[1024];
+ uint32_t pathLen = sizeof(path);
+ _NSGetExecutablePath(path, &pathLen);
+ return getPath(path);
+#else
+ char* pszFilename;
+ pszFilename = _br_find_exe_for_symbol((const void *)"");
+ return pszFilename;
+#endif
+}
+
+bool getEnv(const string & sName, string & sVal)
+{
+ const char * pszVal = getenv(sName.c_str());
+ if (pszVal) {
+ sVal = pszVal;
+ }
+ return (pszVal != 0);
+}
+
+void setEnv(const string & sName, const string & sVal)
+{
+#ifdef _WIN32
+ SetEnvironmentVariable(sName.c_str(), sVal.c_str());
+#else
+ setenv(sName.c_str(), sVal.c_str(), true);
+#endif
+}
+
+size_t getMemoryUsage()
+{
+#ifdef __APPLE__
+ kern_return_t rc;
+ mach_port_t task;
+ rc = task_for_pid(mach_task_self(), getpid(), &task);
+ AVG_ASSERT(rc == KERN_SUCCESS);
+ struct task_basic_info taskInfo;
+ mach_msg_type_number_t count = TASK_BASIC_INFO_COUNT;
+ rc = task_info(task, TASK_BASIC_INFO, (task_info_t)&taskInfo, &count);
+ AVG_ASSERT(rc == KERN_SUCCESS);
+ return taskInfo.resident_size;
+#else
+#ifdef _WIN32
+ DWORD pid = GetCurrentProcessId();
+ HANDLE hProcess;
+ PROCESS_MEMORY_COUNTERS pmc;
+ hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid);
+ BOOL bOk = GetProcessMemoryInfo(hProcess, &pmc, sizeof(pmc));
+ CloseHandle(hProcess);
+ return pmc.WorkingSetSize;
+#else
+ unsigned vmsize;
+ unsigned rssize;
+ // See 'man proc' for a documentation of this file's contents.
+ std::ifstream f("/proc/self/statm");
+ f >> vmsize >> rssize;
+ return rssize*(size_t)(getpagesize());
+#endif
+#endif
+}
+
+std::string convertUTF8ToFilename(const std::string & sName)
+{
+#ifdef _WIN32
+ // Conversion from utf-8 to something windows can use:
+ // utf-8 long filename -> utf-16 long filename -> utf-16 short filename (8.3)
+ // -> utf-8 short filename (= ASCII short filename).
+ wchar_t wideString[2048];
+ int err1 = MultiByteToWideChar(CP_UTF8, 0, sName.c_str(), sName.size()+1,
+ wideString, 2048);
+ if (err1 == 0) {
+ AVG_LOG_WARNING("Error in unicode conversion (MultiByteToWideChar): " <<
+ getWinErrMsg(GetLastError()));
+ return sName;
+ }
+ wchar_t wideShortFName[2048];
+ DWORD err2 = GetShortPathNameW(wideString, wideShortFName, 1024);
+ if (err2 != 0) {
+ char pShortName[1024];
+ err1 = WideCharToMultiByte(CP_UTF8, 0, wideShortFName, -1, pShortName,
+ 1024, 0, 0);
+ if (err1 == 0) {
+ AVG_LOG_WARNING("Error in unicode conversion (MultiByteToWideChar): " <<
+ getWinErrMsg(GetLastError()));
+ }
+ return pShortName;
+ } else {
+ return sName;
+ }
+#else
+ return sName;
+#endif
+}
+
+#ifdef __APPLE__
+int reallyGetOSXMajorVersion()
+{
+ utsname sysInfo;
+ int rc = uname(&sysInfo);
+ AVG_ASSERT(rc == 0);
+// cerr << sysInfo.sysname << ", " << sysInfo.nodename << ", " << sysInfo.release <<
+// ", " << sysInfo.version << ", " << sysInfo.machine << endl;
+ istringstream ss(sysInfo.release);
+ int major;
+ int minor;
+ int dot;
+ char c;
+ ss >> major >> c >> minor >> c >> dot;
+ return major;
+}
+
+int getOSXMajorVersion()
+{
+ static int major = reallyGetOSXMajorVersion(); // only called once for speed reasons.
+ return major;
+}
+#endif
+}
diff --git a/src/base/OSHelper.h b/src/base/OSHelper.h
new file mode 100644
index 0000000..6abda5a
--- /dev/null
+++ b/src/base/OSHelper.h
@@ -0,0 +1,52 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _OSHelper_H_
+#define _OSHelper_H_
+
+#include "../api.h"
+#include <string>
+
+namespace avg {
+
+#ifdef _WIN32
+std::string getWinErrMsg(unsigned err);
+#endif
+
+std::string getAvgLibPath();
+
+bool getEnv(const std::string & sName, std::string & sVal);
+void setEnv(const std::string & sName, const std::string & sVal);
+
+size_t getMemoryUsage();
+
+// Converts a utf-8-encoded filename to something windows can use.
+// Under other operating systems, returns the input string.
+AVG_API std::string convertUTF8ToFilename(const std::string & sName);
+
+#ifdef __APPLE__
+int getOSXMajorVersion();
+#endif
+
+}
+
+#endif
+
diff --git a/src/base/ObjectCounter.cpp b/src/base/ObjectCounter.cpp
new file mode 100644
index 0000000..e8136b7
--- /dev/null
+++ b/src/base/ObjectCounter.cpp
@@ -0,0 +1,187 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "ObjectCounter.h"
+#include "Exception.h"
+#include "Logger.h"
+
+#include <boost/thread/mutex.hpp>
+
+#include <iostream>
+#include <sstream>
+#include <vector>
+#include <algorithm>
+
+#ifdef WIN32
+#include <windows.h>
+#include <Dbghelp.h>
+#else
+#include <cxxabi.h>
+#endif
+
+#define DEBUG_ALLOC 1
+
+namespace avg {
+
+using namespace std;
+
+ObjectCounter* ObjectCounter::s_pObjectCounter = 0;
+bool ObjectCounter::s_bDeleted = false;
+boost::mutex * pCounterMutex;
+
+void deleteObjectCounter()
+{
+ delete ObjectCounter::s_pObjectCounter;
+ delete pCounterMutex;
+ ObjectCounter::s_pObjectCounter = 0;
+}
+
+ObjectCounter::ObjectCounter()
+{
+}
+
+ObjectCounter::~ObjectCounter()
+{
+ s_bDeleted = true;
+}
+
+ObjectCounter * ObjectCounter::get()
+{
+ if (!s_pObjectCounter) {
+ if (s_bDeleted) {
+ // This is _after_ the deleteObjectCounter has been called.
+ return 0;
+ } else {
+ s_pObjectCounter = new ObjectCounter;
+ pCounterMutex = new boost::mutex;
+ atexit(deleteObjectCounter);
+ }
+ }
+ return s_pObjectCounter;
+}
+
+void ObjectCounter::incRef(const std::type_info* pType)
+{
+#ifdef DEBUG_ALLOC
+ lock_guard Lock(*pCounterMutex);
+ TypeMap::iterator MapEntry = m_TypeMap.find(pType);
+ if (MapEntry == m_TypeMap.end()) {
+ m_TypeMap[pType] = 1;
+ } else {
+ (MapEntry->second)++;
+ }
+// cerr << "incRef " << demangle(pType->name()) << ":" << m_TypeMap[pType] << endl;
+#endif
+}
+
+void ObjectCounter::decRef(const std::type_info* pType)
+{
+#ifdef DEBUG_ALLOC
+ if (!this) {
+ // This happens if there are counted static objects that are deleted after
+ // s_pObjectCounter has been deleted.
+ return;
+ }
+ lock_guard Lock(*pCounterMutex);
+ TypeMap::iterator MapEntry = m_TypeMap.find(pType);
+ if (MapEntry == m_TypeMap.end()) {
+ cerr << "ObjectCounter for " << demangle(pType->name())
+ << " does not exist." << endl;
+ // Can't decref a type that hasn't been incref'd.
+ AVG_ASSERT(false);
+ } else {
+ (MapEntry->second)--;
+ if (MapEntry->second < 0) {
+ cerr << "ObjectCounter: refcount for " <<
+ demangle(MapEntry->first->name()) <<
+ " < 0" << endl;
+ AVG_ASSERT(false);
+ }
+ }
+// cerr << "decRef " << demangle(pType->name()) << ":" << MapEntry->second << endl;
+#endif
+}
+
+int ObjectCounter::getCount(const std::type_info* pType)
+{
+ TypeMap::iterator MapEntry = m_TypeMap.find(pType);
+ if (MapEntry == m_TypeMap.end()) {
+ return 0;
+ } else {
+ return MapEntry->second;
+ }
+
+}
+
+std::string ObjectCounter::dump()
+{
+ stringstream ss;
+ ss << "Object dump: " << endl;
+ TypeMap::iterator it;
+ vector<string> strings;
+ for (it = m_TypeMap.begin(); it != m_TypeMap.end(); ++it) {
+ stringstream tempStream;
+ if (it->second > 0) {
+ tempStream << " " << demangle(it->first->name()) << ": " << it->second;
+ strings.push_back(tempStream.str());
+ }
+ }
+ sort(strings.begin(), strings.end());
+ for (vector<string>::iterator it=strings.begin(); it != strings.end(); ++it) {
+ ss << *it << endl;
+ }
+ return ss.str();
+}
+
+string ObjectCounter::demangle(string s)
+{
+ int rc;
+ string sResult;
+#ifdef _WIN32
+ char szDemangledName[2048];
+ rc = int(UnDecorateSymbolName(s.c_str(), szDemangledName, sizeof(szDemangledName),
+ UNDNAME_COMPLETE));
+ if (rc) {
+ sResult = szDemangledName;
+ } else {
+ int error = GetLastError();
+ printf("UnDecorateSymbolName returned error %d\n", error);
+ sResult = s;
+ }
+#else
+ char * pszDemangled = abi::__cxa_demangle(s.c_str(), 0, 0, &rc);
+ if (rc) {
+ sResult = s;
+ } else {
+ sResult = pszDemangled;
+ }
+ if (pszDemangled) {
+ free(pszDemangled);
+ }
+#endif
+ return sResult;
+}
+
+TypeMap ObjectCounter::getObjectCount(){
+ return m_TypeMap;
+}
+
+}
diff --git a/src/base/ObjectCounter.h b/src/base/ObjectCounter.h
new file mode 100644
index 0000000..e370723
--- /dev/null
+++ b/src/base/ObjectCounter.h
@@ -0,0 +1,61 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _ObjectCounter_H_
+#define _ObjectCounter_H_
+
+#include "../api.h"
+#include <string>
+#include <map>
+#include <typeinfo>
+
+namespace avg {
+
+typedef std::map<const std::type_info *, int> TypeMap;
+
+class AVG_API ObjectCounter {
+public:
+ static ObjectCounter* get();
+ virtual ~ObjectCounter();
+
+ void incRef(const std::type_info* pType);
+ void decRef(const std::type_info* pType);
+
+ int getCount(const std::type_info* pType);
+
+ std::string demangle(std::string s);
+ std::string dump();
+ TypeMap getObjectCount();
+
+private:
+ ObjectCounter();
+ static void deleteSingleton();
+
+ TypeMap m_TypeMap;
+
+ static ObjectCounter* s_pObjectCounter;
+ static bool s_bDeleted;
+ friend void deleteObjectCounter();
+};
+
+}
+#endif
+
diff --git a/src/base/ProfilingZone.cpp b/src/base/ProfilingZone.cpp
new file mode 100644
index 0000000..9cdbbfe
--- /dev/null
+++ b/src/base/ProfilingZone.cpp
@@ -0,0 +1,91 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "ProfilingZone.h"
+#include "ObjectCounter.h"
+
+#include <iostream>
+
+using namespace boost;
+using namespace std;
+
+namespace avg {
+
+ProfilingZone::ProfilingZone(const ProfilingZoneID& zoneID)
+ : m_TimeSum(0),
+ m_AvgTime(0),
+ m_NumFrames(0),
+ m_Indent(0),
+ m_ZoneID(zoneID)
+{
+ ObjectCounter::get()->incRef(&typeid(*this));
+}
+
+ProfilingZone::~ProfilingZone()
+{
+ ObjectCounter::get()->decRef(&typeid(*this));
+}
+
+void ProfilingZone::restart()
+{
+ m_NumFrames = 0;
+ m_AvgTime = 0;
+ m_TimeSum = 0;
+}
+
+void ProfilingZone::reset()
+{
+ m_NumFrames++;
+ m_AvgTime = (m_AvgTime*(m_NumFrames-1)+m_TimeSum)/m_NumFrames;
+ m_TimeSum = 0;
+}
+
+long long ProfilingZone::getUSecs() const
+{
+ return m_TimeSum;
+}
+
+long long ProfilingZone::getAvgUSecs() const
+{
+ return m_AvgTime;
+}
+
+void ProfilingZone::setIndentLevel(int indent)
+{
+ m_Indent = indent;
+}
+
+int ProfilingZone::getIndentLevel() const
+{
+ return m_Indent;
+}
+
+string ProfilingZone::getIndentString() const
+{
+ return string(m_Indent, ' ');
+}
+
+const string& ProfilingZone::getName() const
+{
+ return m_ZoneID.getName();
+}
+
+}
diff --git a/src/base/ProfilingZone.h b/src/base/ProfilingZone.h
new file mode 100644
index 0000000..0d0ee42
--- /dev/null
+++ b/src/base/ProfilingZone.h
@@ -0,0 +1,69 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _ProfilingZone_H_
+#define _ProfilingZone_H_
+
+#include "../api.h"
+#include "ProfilingZoneID.h"
+#include "TimeSource.h"
+
+#include <boost/shared_ptr.hpp>
+
+namespace avg {
+
+class AVG_API ProfilingZone
+{
+public:
+ ProfilingZone(const ProfilingZoneID& zoneID);
+ virtual ~ProfilingZone();
+ void restart();
+
+ void start()
+ {
+ m_StartTime = TimeSource::get()->getCurrentMicrosecs();
+ };
+ void stop()
+ {
+ m_TimeSum += TimeSource::get()->getCurrentMicrosecs()-m_StartTime;
+ };
+ void reset();
+ long long getUSecs() const;
+ long long getAvgUSecs() const;
+ void setIndentLevel(int indent);
+ int getIndentLevel() const;
+ std::string getIndentString() const;
+ const std::string& getName() const;
+
+private:
+ long long m_TimeSum;
+ long long m_AvgTime;
+ long long m_StartTime;
+ int m_NumFrames;
+ int m_Indent;
+ const ProfilingZoneID& m_ZoneID;
+};
+
+typedef boost::shared_ptr<ProfilingZone> ProfilingZonePtr;
+
+}
+
+#endif
diff --git a/src/base/ProfilingZoneID.cpp b/src/base/ProfilingZoneID.cpp
new file mode 100644
index 0000000..7256887
--- /dev/null
+++ b/src/base/ProfilingZoneID.cpp
@@ -0,0 +1,57 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "ProfilingZoneID.h"
+#include "ThreadProfiler.h"
+
+using namespace std;
+
+namespace avg {
+
+ProfilingZoneID::ProfilingZoneID(const string& sName, bool bMultithreaded)
+ : m_sName(sName),
+ m_bMultithreaded(bMultithreaded),
+ m_pProfiler(0)
+{
+}
+
+ProfilingZoneID::~ProfilingZoneID()
+{
+}
+
+const string& ProfilingZoneID::getName() const
+{
+ return m_sName;
+}
+
+ThreadProfiler* ProfilingZoneID::getProfiler()
+{
+ if (!m_pProfiler) {
+ if (m_bMultithreaded) {
+ return ThreadProfiler::get();
+ } else {
+ m_pProfiler = ThreadProfiler::get();
+ }
+ }
+ return m_pProfiler;
+}
+
+}
diff --git a/src/base/ProfilingZoneID.h b/src/base/ProfilingZoneID.h
new file mode 100644
index 0000000..ca4d637
--- /dev/null
+++ b/src/base/ProfilingZoneID.h
@@ -0,0 +1,50 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _ProfilingZoneID_H_
+#define _ProfilingZoneID_H_
+
+#include "../api.h"
+
+#include <string>
+
+namespace avg {
+
+class ThreadProfiler;
+
+class AVG_API ProfilingZoneID
+{
+public:
+ ProfilingZoneID(const std::string& sName, bool bMultithreaded=false);
+ ~ProfilingZoneID();
+
+ const std::string& getName() const;
+ ThreadProfiler* getProfiler();
+
+private:
+ std::string m_sName;
+ bool m_bMultithreaded;
+ ThreadProfiler* m_pProfiler;
+};
+
+}
+
+#endif
diff --git a/src/base/Queue.h b/src/base/Queue.h
new file mode 100644
index 0000000..36a0eba
--- /dev/null
+++ b/src/base/Queue.h
@@ -0,0 +1,160 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _Queue_H_
+#define _Queue_H_
+
+#include "../api.h"
+#include "Exception.h"
+
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/condition.hpp>
+#include <boost/shared_ptr.hpp>
+
+#include <deque>
+#include <iostream>
+
+namespace avg {
+
+typedef boost::unique_lock<boost::mutex> unique_lock;
+
+template<class QElement>
+class AVG_TEMPLATE_API Queue
+{
+public:
+ typedef boost::shared_ptr<QElement> QElementPtr;
+
+ Queue(int maxSize=-1);
+ virtual ~Queue();
+
+ bool empty() const;
+ QElementPtr pop(bool bBlock = true);
+ void clear();
+ void push(const QElementPtr& pElem);
+ QElementPtr peek(bool bBlock = true) const;
+ int size() const;
+ int getMaxSize() const;
+
+private:
+ QElementPtr getFrontElement(bool bBlock, unique_lock& Lock) const;
+
+ std::deque<QElementPtr> m_pElements;
+ mutable boost::mutex m_Mutex;
+ mutable boost::condition m_Cond;
+ int m_MaxSize;
+};
+
+template<class QElement>
+Queue<QElement>::Queue(int maxSize)
+ : m_MaxSize(maxSize)
+{
+}
+
+template<class QElement>
+Queue<QElement>::~Queue()
+{
+}
+
+template<class QElement>
+bool Queue<QElement>::empty() const
+{
+ unique_lock Lock(m_Mutex);
+ return m_pElements.empty();
+}
+
+template<class QElement>
+typename Queue<QElement>::QElementPtr Queue<QElement>::pop(bool bBlock)
+{
+ unique_lock lock(m_Mutex);
+ QElementPtr pElem = getFrontElement(bBlock, lock);
+ if (pElem) {
+ m_pElements.pop_front();
+ m_Cond.notify_one();
+ }
+ return pElem;
+}
+
+template<class QElement>
+void Queue<QElement>::clear()
+{
+ QElementPtr pElem;
+ do {
+ pElem = pop(false);
+ } while (pElem);
+}
+
+template<class QElement>
+typename Queue<QElement>::QElementPtr Queue<QElement>::peek(bool bBlock) const
+{
+ unique_lock lock(m_Mutex);
+ QElementPtr pElem = getFrontElement(bBlock, lock);
+ if (pElem) {
+ m_Cond.notify_one();
+ }
+ return pElem;
+}
+
+template<class QElement>
+void Queue<QElement>::push(const QElementPtr& pElem)
+{
+ assert(pElem);
+ unique_lock lock(m_Mutex);
+ if (m_pElements.size() == (unsigned)m_MaxSize) {
+ while (m_pElements.size() == (unsigned)m_MaxSize) {
+ m_Cond.wait(lock);
+ }
+ }
+ m_pElements.push_back(pElem);
+ m_Cond.notify_one();
+}
+
+template<class QElement>
+int Queue<QElement>::size() const
+{
+ unique_lock lock(m_Mutex);
+ return int(m_pElements.size());
+}
+
+template<class QElement>
+int Queue<QElement>::getMaxSize() const
+{
+ unique_lock lock(m_Mutex);
+ return m_MaxSize;
+}
+
+template<class QElement>
+typename Queue<QElement>::QElementPtr
+ Queue<QElement>::getFrontElement(bool bBlock, unique_lock& lock) const
+{
+ if (m_pElements.empty()) {
+ if (bBlock) {
+ while (m_pElements.empty()) {
+ m_Cond.wait(lock);
+ }
+ } else {
+ return QElementPtr();
+ }
+ }
+ return m_pElements.front();
+}
+
+}
+#endif
diff --git a/src/base/Rect.h b/src/base/Rect.h
new file mode 100644
index 0000000..d668338
--- /dev/null
+++ b/src/base/Rect.h
@@ -0,0 +1,213 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _Rect_H_
+#define _Rect_H_
+
+#include "../api.h"
+
+#include "../base/GLMHelper.h"
+#include "../glm/glm.hpp"
+
+#include <algorithm>
+
+namespace avg {
+
+// Simple rectangle class.
+// If NUM is an integer, contains all points from tl up to but not including
+// br.
+template<class NUM>
+class AVG_TEMPLATE_API Rect
+{
+public:
+ typedef glm::detail::tvec2<NUM> Vec2;
+ Vec2 tl;
+ Vec2 br;
+
+ Rect();
+ Rect(NUM left, NUM top, NUM right, NUM bottom);
+ Rect(const Vec2& TL, const Vec2& BR);
+ template<class ORIGNUM> Rect(const Rect<ORIGNUM>& rc);
+
+ bool operator ==(const Rect<NUM>& rect) const;
+ bool operator !=(const Rect<NUM> & rect) const;
+ NUM width() const;
+ NUM height() const;
+ Vec2 center() const;
+ void setWidth(NUM width);
+ void setHeight(NUM height);
+ void setSize(const Vec2& size);
+ bool contains(const Vec2& pt) const;
+ bool contains(const Rect<NUM>& rect) const;
+ bool intersects(const Rect<NUM>& rect) const;
+ void expand(const Rect<NUM>& rect);
+ void intersect(const Rect<NUM>& rect);
+ Vec2 size() const;
+ Vec2 cropPoint(const Vec2& pt) const;
+};
+
+template<class NUM>
+std::ostream& operator<<( std::ostream& os, const Rect<NUM> &r)
+{
+ os << "(" << r.tl << "-" << r.br << ")";
+ return os;
+}
+
+
+typedef Rect<float> FRect;
+typedef Rect<int> IntRect;
+
+template<class NUM>
+Rect<NUM>::Rect()
+{}
+
+template<class NUM>
+Rect<NUM>::Rect(const Vec2& TL, const Vec2& BR)
+ : tl(TL), br(BR)
+{}
+
+template<class NUM>
+Rect<NUM>::Rect(NUM left, NUM top, NUM right, NUM bottom)
+ : tl(left, top),
+ br(right, bottom)
+{}
+
+template<class NUM>
+template<class ORIGNUM>
+Rect<NUM>::Rect(const Rect<ORIGNUM>& rc)
+ : tl (NUM(rc.tl.x), NUM(rc.tl.y)),
+ br (NUM(rc.br.x), NUM(rc.br.y))
+{
+}
+
+template<class NUM>
+bool Rect<NUM>::operator ==(const Rect<NUM> & rect) const
+{
+ return (tl == rect.tl && br == rect.br);
+}
+
+template<class NUM>
+bool Rect<NUM>::operator !=(const Rect<NUM> & rect) const
+{
+ return !(rect==*this);
+}
+
+template<class NUM>
+NUM Rect<NUM>::width() const
+{
+ return br.x-tl.x;
+}
+
+template<class NUM>
+NUM Rect<NUM>::height() const
+{
+ return br.y-tl.y;
+}
+
+template<class NUM>
+glm::detail::tvec2<NUM> Rect<NUM>::center() const
+{
+ return Vec2(tl+br)/2;
+}
+
+template<class NUM>
+void Rect<NUM>::setWidth(NUM width)
+{
+ br.x = tl.x+width;
+}
+
+template<class NUM>
+void Rect<NUM>::setHeight(NUM height)
+{
+ br.y = tl.y+height;
+}
+
+template<class NUM>
+void Rect<NUM>::setSize(const Vec2& size)
+{
+ setWidth(size.x);
+ setHeight(size.y);
+}
+
+template<class NUM>
+bool Rect<NUM>::contains(const Vec2& pt) const
+{
+ return (pt.x >= tl.x && pt.x < br.x &&
+ pt.y >= tl.y && pt.y < br.y);
+}
+
+template<class NUM>
+bool Rect<NUM>::contains(const Rect<NUM>& rect) const
+{
+ Vec2 brpt (rect.br.x-1, rect.br.y-1);
+ return Contains(rect.tl) && Contains(brpt);
+}
+
+template<class NUM>
+bool Rect<NUM>::intersects(const Rect<NUM>& rect) const
+{
+ if (rect.br.x <= tl.x || rect.tl.x >= br.x ||
+ rect.br.y <= tl.y || rect.tl.y >= br.y)
+ return false;
+ else
+ return true;
+}
+
+template<class NUM>
+void Rect<NUM>::expand(const Rect<NUM>& rect)
+{
+ tl.x = glm::min(tl.x, rect.tl.x);
+ tl.y = glm::min(tl.y, rect.tl.y);
+ br.x = glm::max(br.x, rect.br.x);
+ br.y = glm::max(br.y, rect.br.y);
+}
+
+template<class NUM>
+void Rect<NUM>::intersect(const Rect<NUM>& rect)
+{
+ tl.x = glm::max(tl.x, rect.tl.x);
+ tl.y = glm::max(tl.y, rect.tl.y);
+ br.x = glm::min(br.x, rect.br.x);
+ br.y = glm::min(br.y, rect.br.y);
+}
+
+template<class NUM>
+glm::detail::tvec2<NUM> Rect<NUM>::size() const
+{
+ return Vec2(width(), height());
+}
+
+template<class NUM>
+glm::detail::tvec2<NUM> Rect<NUM>::cropPoint(const Vec2& pt) const
+{
+ Vec2 Result;
+ Result.x = std::min(std::max(pt.x, tl.x), br.x-1);
+ Result.y = std::min(std::max(pt.y, tl.y), br.y-1);
+ return Result;
+}
+
+#undef min
+#undef max
+
+}
+
+#endif
+
diff --git a/src/base/ScopeTimer.cpp b/src/base/ScopeTimer.cpp
new file mode 100644
index 0000000..eb95736
--- /dev/null
+++ b/src/base/ScopeTimer.cpp
@@ -0,0 +1,35 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "ScopeTimer.h"
+
+using namespace std;
+
+namespace avg {
+
+bool ScopeTimer::s_bTimersEnabled = false;
+
+void ScopeTimer::enableTimers(bool bEnable)
+{
+ s_bTimersEnabled = bEnable;
+}
+
+}
diff --git a/src/base/ScopeTimer.h b/src/base/ScopeTimer.h
new file mode 100644
index 0000000..a87263f
--- /dev/null
+++ b/src/base/ScopeTimer.h
@@ -0,0 +1,60 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _ScopeTimer_H_
+#define _ScopeTimer_H_
+
+#include "../api.h"
+#include "ProfilingZoneID.h"
+#include "ThreadProfiler.h"
+
+namespace avg {
+
+class AVG_API ScopeTimer {
+public:
+ ScopeTimer(ProfilingZoneID& zoneID)
+ {
+ if (s_bTimersEnabled) {
+ m_pZoneID = &zoneID;
+ m_pZoneID->getProfiler()->startZone(zoneID);
+ } else {
+ m_pZoneID = 0;
+ }
+ };
+
+ ~ScopeTimer()
+ {
+ if (m_pZoneID) {
+ m_pZoneID->getProfiler()->stopZone(*m_pZoneID);
+ }
+ };
+
+ static void enableTimers(bool bEnable);
+
+private:
+ ProfilingZoneID* m_pZoneID;
+
+ static bool s_bTimersEnabled;
+};
+
+}
+
+#endif
diff --git a/src/base/Signal.h b/src/base/Signal.h
new file mode 100644
index 0000000..b670822
--- /dev/null
+++ b/src/base/Signal.h
@@ -0,0 +1,119 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _Signal_H_
+#define _Signal_H_
+
+#include "../api.h"
+
+#include "Exception.h"
+
+#include <list>
+
+namespace avg {
+
+
+// Simple implementation of a signal/slot mechanism.
+// Might need to be replaced by boost::signal when things get more complicated.
+template <class LISTENEROBJ>
+class AVG_TEMPLATE_API Signal {
+public:
+ typedef void (LISTENEROBJ::*ListenerFunc)() ;
+ Signal(ListenerFunc pFunc);
+ virtual ~Signal();
+
+ void connect(LISTENEROBJ* pListener);
+ void disconnect(LISTENEROBJ* pListener);
+
+ void emit();
+ int getNumListeners() const;
+
+private:
+ ListenerFunc m_pFunc;
+ std::list<LISTENEROBJ*> m_Listeners;
+ typedef typename std::list<LISTENEROBJ*>::iterator ListenerIterator;
+ LISTENEROBJ* m_pCurrentListener;
+ bool m_bKillCurrentListener;
+};
+
+template<class LISTENEROBJ>
+Signal<LISTENEROBJ>::Signal(ListenerFunc pFunc)
+ : m_pFunc(pFunc),
+ m_pCurrentListener(0),
+ m_bKillCurrentListener(false)
+{
+}
+
+template<class LISTENEROBJ>
+Signal<LISTENEROBJ>::~Signal()
+{
+}
+
+template<class LISTENEROBJ>
+void Signal<LISTENEROBJ>::connect(LISTENEROBJ* pListener)
+{
+ ListenerIterator it;
+ it = find(m_Listeners.begin(), m_Listeners.end(), pListener);
+ // If the listener is already connected, something is wrong, unless we're
+ // deleting it at this very moment.
+ AVG_ASSERT(it == m_Listeners.end() ||
+ (*it == m_pCurrentListener && m_bKillCurrentListener));
+ m_Listeners.push_back(pListener);
+}
+
+template<class LISTENEROBJ>
+void Signal<LISTENEROBJ>::disconnect(LISTENEROBJ* pListener)
+{
+ if (m_pCurrentListener == pListener) {
+ m_bKillCurrentListener = true;
+ } else {
+ ListenerIterator it;
+ it = find(m_Listeners.begin(), m_Listeners.end(), pListener);
+ AVG_ASSERT(it != m_Listeners.end());
+ m_Listeners.erase(it);
+ }
+}
+
+template<class LISTENEROBJ>
+void Signal<LISTENEROBJ>::emit()
+{
+ ListenerIterator it;
+ for (it=m_Listeners.begin(); it != m_Listeners.end();) {
+ m_pCurrentListener = *it;
+ ((*it)->*m_pFunc)(); // This is the actual call to the listener.
+ if (m_bKillCurrentListener) {
+ it = m_Listeners.erase(it);
+ m_bKillCurrentListener = false;
+ } else {
+ ++it;
+ }
+ }
+ m_pCurrentListener = 0;
+}
+
+template<class LISTENEROBJ>
+int Signal<LISTENEROBJ>::getNumListeners() const
+{
+ return m_Listeners.size();
+}
+
+}
+#endif
diff --git a/src/base/StandardLogSink.cpp b/src/base/StandardLogSink.cpp
new file mode 100644
index 0000000..510aa0b
--- /dev/null
+++ b/src/base/StandardLogSink.cpp
@@ -0,0 +1,54 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+
+#include "StandardLogSink.h"
+#include "Logger.h"
+
+#include <iostream>
+#include <iomanip>
+
+using namespace std;
+
+namespace avg
+{
+
+StandardLogSink::StandardLogSink()
+{
+
+}
+
+StandardLogSink::~StandardLogSink()
+{
+
+}
+
+void StandardLogSink::logMessage(const tm* pTime, unsigned millis,
+ const category_t& category, severity_t severity, const UTF8String& sMsg)
+{
+ char timeString[256];
+ strftime(timeString, sizeof(timeString), "%y-%m-%d %H:%M:%S", pTime);
+ cerr << "[" << timeString << "." <<
+ setw(3) << setfill('0') << millis << setw(0) << "][";
+ cerr << setw(4) << setfill('.') << Logger::severityToString(severity) << "][";
+ cerr << setw(9) << setfill('.') << category << "] : " << sMsg << endl;
+ cerr.flush();
+}
+
+}
diff --git a/src/base/StandardLogSink.h b/src/base/StandardLogSink.h
new file mode 100644
index 0000000..7cbfe2c
--- /dev/null
+++ b/src/base/StandardLogSink.h
@@ -0,0 +1,39 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+
+#ifndef _StandardLogSink_H_
+#define _StandardLogSink_H_
+
+#include "ILogSink.h"
+
+namespace avg{
+
+class StandardLogSink: public ILogSink
+{
+public:
+ StandardLogSink();
+ virtual ~StandardLogSink ();
+
+ virtual void logMessage(const tm* pTime, unsigned millis, const category_t& category,
+ severity_t severity, const UTF8String& sMsg);
+};
+
+}
+#endif
diff --git a/src/base/StringHelper.cpp b/src/base/StringHelper.cpp
new file mode 100644
index 0000000..6155859
--- /dev/null
+++ b/src/base/StringHelper.cpp
@@ -0,0 +1,145 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "StringHelper.h"
+
+#include <stdlib.h>
+#include <ctype.h>
+#include <algorithm>
+#include <cstdio>
+#include <iterator>
+
+using namespace std;
+
+namespace avg {
+
+bool isWhitespace(const string& s)
+{
+ return s.find_first_not_of(" \n\r\t") == s.npos;
+}
+
+void skipWhitespace(std::istream& is)
+{
+ string sWhitespace(" \n\r\t");
+ bool bWhitespace;
+ do {
+ int i = is.peek();
+ if (i == EOF) {
+ bWhitespace = false;
+ } else {
+ bWhitespace = (sWhitespace.find(char(i)) != sWhitespace.npos);
+ }
+ if (bWhitespace) {
+ is.ignore();
+ }
+ } while (bWhitespace);
+}
+
+void skipToken(std::istream& is, char token)
+{
+ skipWhitespace(is);
+ int i = is.peek();
+ if (i == token) {
+ is.ignore();
+ } else {
+ is.setstate(ios::failbit);
+ }
+}
+
+int stringToInt(const string& s)
+{
+ int i;
+ fromString(s, i);
+ return i;
+}
+
+float stringToFloat(const string& s)
+{
+ float d;
+ fromString(s, d);
+ return d;
+}
+
+bool stringToBool(const string& s)
+{
+ // avg usually wants xml attributes in lowercase, but python only
+ // sees 'True' as true, so we'll accept that too. Also, python 2.3
+ // has 1 as true, so that has to be ok too.
+ if (s == "True" || s == "true" || s == "1") {
+ return true;
+ }
+ if (s == "False" || s == "false" || s == "0") {
+ return false;
+ }
+ throw (Exception(AVG_ERR_TYPE, string("Could not convert ")+s+" to bool."));
+}
+
+std::string removeStartEndSpaces(const string& s)
+{
+ string sResult = s;
+ while (sResult.size() > 0 && (sResult[0] == ' ' || sResult[0] == '\n'
+ || sResult[0] == '\r' || sResult[0] == '\t'))
+ {
+ sResult.erase(0, 1);
+ }
+ if (sResult.size() == 0) {
+ return sResult;
+ }
+ char c = sResult[sResult.length()-1];
+ while (c == ' ' || c == '\n' || c == '\r' || c == '\t') {
+ sResult.erase(sResult.length()-1, 1);
+ c = sResult[sResult.length()-1];
+ }
+ return sResult;
+}
+
+string toLowerCase(const string& s)
+{
+ string sResult;
+ for (unsigned i=0; i<s.length(); ++i) {
+ sResult.push_back(::tolower(s[i]));
+ }
+ return sResult;
+}
+
+bool equalIgnoreCase(const string& s1, const string& s2)
+{
+ if (s1.length() != s2.length()) {
+ return false;
+ }
+ string sUpper1;
+ string sUpper2;
+ transform(s1.begin(), s1.end(), std::back_inserter(sUpper1), (int(*)(int)) toupper);
+ transform(s2.begin(), s2.end(), std::back_inserter(sUpper2), (int(*)(int)) toupper);
+ return sUpper1 == sUpper2;
+}
+
+string toString(const bool& b)
+{
+ if (b) {
+ return "true";
+ } else {
+ return "false";
+ }
+}
+
+}
+
diff --git a/src/base/StringHelper.h b/src/base/StringHelper.h
new file mode 100644
index 0000000..82713eb
--- /dev/null
+++ b/src/base/StringHelper.h
@@ -0,0 +1,133 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _StringHelper_H_
+#define _StringHelper_H_
+
+#include "../api.h"
+#include "Exception.h"
+
+#include <string>
+#include <sstream>
+#include <typeinfo>
+#include <iostream>
+#include <vector>
+
+#ifdef __GNUC__
+#include <cxxabi.h>
+#endif
+
+namespace avg {
+
+bool AVG_API isWhitespace(const std::string& s);
+void AVG_API skipWhitespace(std::istream& is);
+void AVG_API skipToken(std::istream& is, char token);
+
+template<class T>
+std::istream& operator >>(std::istream& is, std::vector<T>& v)
+{
+ skipToken(is, '(');
+ skipWhitespace(is);
+ int c = is.peek();
+ if (c == ')') {
+ is.ignore();
+ return is;
+ }
+ bool bDone = false;
+ do {
+ T elem;
+ is >> elem;
+ v.push_back(elem);
+ skipWhitespace(is);
+ int c = is.peek();
+ switch(c) {
+ case ',':
+ is.ignore();
+ break;
+ case ')':
+ bDone = true;
+ is.ignore();
+ break;
+ default:
+ is.setstate(std::ios::failbit);
+ bDone = true;
+ }
+ } while (!bDone);
+ return is;
+}
+
+int AVG_API stringToInt(const std::string& s);
+float AVG_API stringToFloat(const std::string& s);
+bool AVG_API stringToBool(const std::string& s);
+
+std::string AVG_API removeStartEndSpaces(const std::string& s);
+
+std::string AVG_API toLowerCase(const std::string& s);
+
+bool AVG_API equalIgnoreCase(const std::string& s1, const std::string& s2);
+
+template<class T>
+std::string toString(const T& i)
+{
+ std::stringstream stream;
+ stream << i;
+ return stream.str();
+}
+
+std::string AVG_API toString(const bool& b);
+
+template<class T>
+std::string getFriendlyTypeName(const T& dummy)
+{
+ std::string sTypeName = typeid(T).name();
+#ifdef __GNUC__
+ int status;
+ char* const pClearName = abi::__cxa_demangle (sTypeName.c_str(), 0, 0, &status);
+ if (status == 0) {
+ sTypeName = pClearName;
+ }
+#endif
+ return sTypeName;
+}
+
+template<class T>
+void fromString(const std::string& s, T& result)
+{
+ std::stringstream stream(s);
+ bool bOk = (stream >> result) != 0;
+ if (bOk) {
+ std::string sLeftover;
+ stream >> sLeftover;
+ bOk = isWhitespace(sLeftover);
+ }
+ if (!bOk) {
+ std::string sTypeName = getFriendlyTypeName(result);
+ throw (Exception(AVG_ERR_TYPE, std::string("Could not convert '")+s
+ + "' to "+sTypeName+"."));
+ }
+}
+
+
+}
+
+
+
+#endif
diff --git a/src/base/Test.cpp b/src/base/Test.cpp
new file mode 100644
index 0000000..b2c0b12
--- /dev/null
+++ b/src/base/Test.cpp
@@ -0,0 +1,114 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "Test.h"
+
+#include "../base/OSHelper.h"
+
+#include <iostream>
+#include <stdlib.h>
+
+using namespace std;
+
+namespace avg {
+
+string Test::s_sSrcDirName;
+
+Test::Test(const string & sName, int indentLevel)
+ : m_IndentLevel(indentLevel),
+ m_NumSucceeded(0),
+ m_NumFailed(0),
+ m_sName(sName)
+{
+}
+
+Test::~Test()
+{
+}
+
+void Test::test(bool b, const char * pszFile, int line)
+{
+ if (b) {
+ m_NumSucceeded++;
+ } else {
+ cerr << string(m_IndentLevel, ' ') << " ---->> failed at " << pszFile
+ << ", " << line << endl;
+ m_NumFailed++;
+ }
+}
+
+
+bool Test::isOk()
+{
+ return m_NumFailed == 0;
+}
+
+void Test::setFailed()
+{
+ m_NumFailed++;
+}
+
+int Test::getNumSucceeded() const
+{
+ return m_NumSucceeded;
+}
+
+int Test::getNumFailed() const
+{
+ return m_NumFailed;
+}
+
+const std::string& Test::getName() const
+{
+ return m_sName;
+}
+
+void Test::aggregateStatistics(const Test& ChildTest)
+{
+ m_NumSucceeded += ChildTest.getNumSucceeded();
+ m_NumFailed += ChildTest.getNumFailed();
+}
+
+void Test::printResults()
+{
+ if (m_NumFailed == 0) {
+ cerr << string(m_IndentLevel, ' ') << m_sName << " succeeded." << endl;
+ } else {
+ cerr << string(m_IndentLevel, ' ') << "######## " << m_sName <<
+ " failed. ########" << endl;
+ }
+
+}
+
+const string& Test::getSrcDirName()
+{
+ if (s_sSrcDirName == "") {
+ bool bInEnviron = getEnv("srcdir", s_sSrcDirName);
+ if (!bInEnviron) {
+ s_sSrcDirName = ".";
+ }
+ s_sSrcDirName += "/";
+ }
+ return s_sSrcDirName;
+}
+
+}
+
diff --git a/src/base/Test.h b/src/base/Test.h
new file mode 100644
index 0000000..0cc20ba
--- /dev/null
+++ b/src/base/Test.h
@@ -0,0 +1,81 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _Test_H_
+#define _Test_H_
+
+#include "../api.h"
+#include <boost/shared_ptr.hpp>
+
+#include <iostream>
+#include <sstream>
+#include <string>
+
+namespace avg {
+class AVG_API Test
+{
+public:
+ Test(const std::string & sName, int indentLevel);
+ virtual ~Test();
+
+ bool isOk();
+ virtual void runTests() = 0;
+
+ void test(bool b, const char * pszFile, int line);
+ void setFailed();
+
+ int getNumSucceeded() const;
+ int getNumFailed() const;
+ const std::string& getName() const;
+
+ void aggregateStatistics(const Test& childTest);
+ virtual void printResults();
+
+protected:
+ static const std::string& getSrcDirName();
+ static std::string s_sSrcDirName;
+
+ int m_IndentLevel;
+
+private:
+ int m_NumSucceeded;
+ int m_NumFailed;
+ std::string m_sName;
+};
+
+typedef boost::shared_ptr<Test> TestPtr;
+
+#define TEST_FAILED(s) \
+ cerr << string(m_IndentLevel+6, ' ') << s << endl; \
+ test(false, __FILE__, __LINE__);
+
+#define TEST(b) \
+ cerr << string(m_IndentLevel+4, ' ') << " TEST(" << #b << ")" << endl; \
+ test(b, __FILE__, __LINE__);
+
+#define QUIET_TEST(b) \
+ if(!(b)) { \
+ cerr << string(m_IndentLevel+4, ' ') << " TEST(" << #b << ")" << endl; \
+ } \
+ test(b, __FILE__, __LINE__);
+}
+#endif
+
diff --git a/src/base/TestSuite.cpp b/src/base/TestSuite.cpp
new file mode 100644
index 0000000..16a254c
--- /dev/null
+++ b/src/base/TestSuite.cpp
@@ -0,0 +1,72 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "TestSuite.h"
+#include "Exception.h"
+
+using namespace std;
+
+namespace avg {
+
+TestSuite::TestSuite(const string& sName)
+ : Test(sName, 0)
+{
+}
+
+TestSuite::~TestSuite()
+{
+}
+
+void TestSuite::addTest(TestPtr pNewTest)
+{
+ m_Tests.push_back(pNewTest);
+}
+
+void TestSuite::runTests()
+{
+ cerr << string(m_IndentLevel, ' ') << "Running suite " << getName() << endl;
+ for (unsigned i = 0; i < m_Tests.size(); ++i) {
+ cerr << string(m_IndentLevel, ' ') << " Running "
+ << m_Tests[i]->getName() << endl;
+ try {
+ m_Tests[i]->runTests();
+ aggregateStatistics(*m_Tests[i]);
+ m_Tests[i]->printResults();
+ } catch (Exception& ex) {
+ cerr << string(m_IndentLevel, ' ') << ex.getStr() << endl;
+ setFailed();
+ } catch (std::exception& ex) {
+ cerr << string(m_IndentLevel, ' ') << " ---->> failed, std::exception: "
+ << ex.what() << endl;
+ setFailed();
+ } catch (...) {
+ cerr << string(m_IndentLevel, ' ') <<
+ " ---->> failed, exception caught" << endl;
+ setFailed();
+ }
+ }
+
+ printResults();
+}
+
+
+}
+
diff --git a/src/base/TestSuite.h b/src/base/TestSuite.h
new file mode 100644
index 0000000..124bbc2
--- /dev/null
+++ b/src/base/TestSuite.h
@@ -0,0 +1,49 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _TestSuite_H_
+#define _TestSuite_H_
+
+#include "../api.h"
+#include "Test.h"
+
+#include <iostream>
+#include <sstream>
+#include <vector>
+
+namespace avg {
+class AVG_API TestSuite: public Test
+{
+public:
+ TestSuite(const std::string& sName);
+ virtual ~TestSuite();
+
+ void addTest(TestPtr pNewTest);
+
+ virtual void runTests();
+
+private:
+ std::vector<TestPtr> m_Tests;
+};
+
+}
+#endif
+
diff --git a/src/base/ThreadHelper.cpp b/src/base/ThreadHelper.cpp
new file mode 100644
index 0000000..105e116
--- /dev/null
+++ b/src/base/ThreadHelper.cpp
@@ -0,0 +1,94 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "ThreadHelper.h"
+#include "OSHelper.h"
+
+#ifdef _WIN32
+#include <Windows.h>
+#endif
+
+namespace avg {
+
+void setAffinityMask(bool bIsMainThread)
+{
+ // The main thread gets the first processor to itself. All other threads share the
+ // rest of the processors available, unless, of course, there is only one processor
+ // in the machine.
+#ifdef linux
+ static cpu_set_t allProcessors;
+ static bool bInitialized = false;
+ if (!bInitialized) {
+ int rc = sched_getaffinity(0, sizeof(allProcessors), &allProcessors);
+ AVG_ASSERT(rc == 0);
+// cerr << "All processors: ";
+// printAffinityMask(allProcessors);
+ bInitialized = true;
+ }
+ cpu_set_t mask;
+ if (bIsMainThread) {
+ CPU_ZERO(&mask);
+ CPU_SET(0, &mask);
+// cerr << "Main Thread: ";
+ } else {
+ mask = allProcessors;
+ if (CPU_COUNT(&mask) > 1) {
+ CPU_CLR(0, &mask);
+ }
+// cerr << "Aux Thread: ";
+ }
+// printAffinityMask(mask);
+ int rc = sched_setaffinity(0, sizeof(mask), &mask);
+ AVG_ASSERT(rc == 0);
+#elif defined _WIN32
+ DWORD processAffinityMask;
+ DWORD systemAffinityMask;
+ BOOL rc = GetProcessAffinityMask(GetCurrentProcess(), &processAffinityMask,
+ &systemAffinityMask);
+ AVG_ASSERT(rc == TRUE);
+ DWORD mainThreadMask = 1 << getLowestBitSet(processAffinityMask);
+ DWORD mask;
+ if (bIsMainThread) {
+ mask = mainThreadMask;
+ } else {
+ mask = processAffinityMask & ~mainThreadMask;
+ if (mask == 0) {
+ mask = processAffinityMask;
+ }
+ }
+ DWORD_PTR pPrevMask = SetThreadAffinityMask(GetCurrentThread(), mask);
+ AVG_ASSERT_MSG(pPrevMask != 0, getWinErrMsg(GetLastError()).c_str());
+#endif
+}
+
+unsigned getLowestBitSet(unsigned val)
+{
+ AVG_ASSERT(val != 0); // Doh
+
+ unsigned pos = 0;
+ while (!(val & 1)) {
+ val >>= 1;
+ ++pos;
+ }
+ return pos;
+}
+
+}
diff --git a/src/base/ThreadHelper.h b/src/base/ThreadHelper.h
new file mode 100644
index 0000000..7acf640
--- /dev/null
+++ b/src/base/ThreadHelper.h
@@ -0,0 +1,37 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _ThreadHelper_H_
+#define _ThreadHelper_H_
+
+#include "Exception.h"
+#include <boost/thread.hpp>
+#include <boost/thread/locks.hpp>
+
+namespace avg {
+
+void AVG_API setAffinityMask(bool bIsMainThread);
+typedef boost::lock_guard<boost::mutex> lock_guard;
+unsigned getLowestBitSet(unsigned val);
+
+}
+
+#endif
diff --git a/src/base/ThreadProfiler.cpp b/src/base/ThreadProfiler.cpp
new file mode 100644
index 0000000..1f1a354
--- /dev/null
+++ b/src/base/ThreadProfiler.cpp
@@ -0,0 +1,184 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "ThreadProfiler.h"
+
+#include "Logger.h"
+#include "Exception.h"
+#include "ProfilingZone.h"
+#include "ScopeTimer.h"
+
+#include <sstream>
+#include <iomanip>
+#include <iostream>
+
+using namespace std;
+using namespace boost;
+
+namespace avg {
+
+thread_specific_ptr<ThreadProfiler*> ThreadProfiler::s_pInstance;
+
+ThreadProfiler* ThreadProfiler::get()
+{
+ if (s_pInstance.get() == 0) {
+ s_pInstance.reset(new (ThreadProfiler*));
+ *s_pInstance = new ThreadProfiler();
+ }
+ return *s_pInstance;
+}
+
+void ThreadProfiler::kill()
+{
+ delete *s_pInstance;
+ s_pInstance.reset();
+}
+
+ThreadProfiler::ThreadProfiler()
+ : m_sName(""),
+ m_LogCategory(Logger::category::PROFILE)
+{
+ m_bRunning = false;
+ ScopeTimer::enableTimers(Logger::get()->shouldLog(m_LogCategory,
+ Logger::severity::INFO));
+}
+
+ThreadProfiler::~ThreadProfiler()
+{
+}
+
+void ThreadProfiler::setLogCategory(category_t category)
+{
+ AVG_ASSERT(!m_bRunning);
+ m_LogCategory = category;
+}
+
+void ThreadProfiler::start()
+{
+ m_bRunning = true;
+}
+
+void ThreadProfiler::restart()
+{
+ ZoneVector::iterator it;
+ for (it = m_Zones.begin(); it != m_Zones.end(); ++it) {
+ (*it)->restart();
+ }
+}
+
+void ThreadProfiler::startZone(const ProfilingZoneID& zoneID)
+{
+ ZoneMap::iterator it = m_ZoneMap.find(&zoneID);
+ // Duplicated code to avoid instantiating a new smart pointer when it's not
+ // necessary.
+ if (it == m_ZoneMap.end()) {
+ ProfilingZonePtr pZone = addZone(zoneID);
+ pZone->start();
+ m_ActiveZones.push_back(pZone);
+ } else {
+ ProfilingZonePtr& pZone = it->second;
+ pZone->start();
+ m_ActiveZones.push_back(pZone);
+ }
+}
+
+void ThreadProfiler::stopZone(const ProfilingZoneID& zoneID)
+{
+ ZoneMap::iterator it = m_ZoneMap.find(&zoneID);
+ ProfilingZonePtr& pZone = it->second;
+ pZone->stop();
+ m_ActiveZones.pop_back();
+}
+
+void ThreadProfiler::dumpStatistics()
+{
+ if (!m_Zones.empty()) {
+ AVG_TRACE(m_LogCategory, Logger::severity::INFO, "Thread " << m_sName);
+ AVG_TRACE(m_LogCategory, Logger::severity::INFO,
+ "Zone name Avg. time");
+ AVG_TRACE(m_LogCategory, Logger::severity::INFO,
+ "--------- ---------");
+
+ ZoneVector::iterator it;
+ for (it = m_Zones.begin(); it != m_Zones.end(); ++it) {
+ AVG_TRACE(m_LogCategory, Logger::severity::INFO,
+ std::setw(35) << std::left
+ << ((*it)->getIndentString()+(*it)->getName())
+ << std::setw(9) << std::right << (*it)->getAvgUSecs());
+ }
+ AVG_TRACE(m_LogCategory, Logger::severity::INFO, "");
+ }
+}
+
+void ThreadProfiler::reset()
+{
+ ZoneVector::iterator it;
+ for (it = m_Zones.begin(); it != m_Zones.end(); ++it) {
+ (*it)->reset();
+ }
+}
+
+int ThreadProfiler::getNumZones()
+{
+ return m_Zones.size();
+}
+
+const std::string& ThreadProfiler::getName() const
+{
+ return m_sName;
+}
+
+void ThreadProfiler::setName(const std::string& sName)
+{
+ m_sName = sName;
+}
+
+
+ProfilingZonePtr ThreadProfiler::addZone(const ProfilingZoneID& zoneID)
+{
+ ProfilingZonePtr pZone(new ProfilingZone(zoneID));
+ m_ZoneMap[&zoneID] = pZone;
+ ZoneVector::iterator it;
+ int parentIndent = -2;
+ if (m_ActiveZones.empty()) {
+ it = m_Zones.end();
+ } else {
+ ProfilingZonePtr pActiveZone = m_ActiveZones.back();
+ bool bParentFound = false;
+ for (it = m_Zones.begin(); it != m_Zones.end(); ++it)
+ {
+ if (pActiveZone == *it) {
+ bParentFound = true;
+ break;
+ }
+ }
+ AVG_ASSERT(bParentFound);
+ parentIndent = pActiveZone->getIndentLevel();
+ ++it;
+ for (; it != m_Zones.end() && (*it)->getIndentLevel() > parentIndent; ++it) {};
+ }
+ m_Zones.insert(it, pZone);
+ pZone->setIndentLevel(parentIndent+2);
+ return pZone;
+}
+
+}
+
diff --git a/src/base/ThreadProfiler.h b/src/base/ThreadProfiler.h
new file mode 100644
index 0000000..a581271
--- /dev/null
+++ b/src/base/ThreadProfiler.h
@@ -0,0 +1,88 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _ThreadProfiler_H_
+#define _ThreadProfiler_H_
+
+#include "../api.h"
+#include "ILogSink.h"
+
+#include <boost/thread.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/thread/tss.hpp>
+
+#include <vector>
+#include <map>
+#if defined(_WIN32) || defined(_LIBCPP_VERSION)
+#include <unordered_map>
+#else
+#include <tr1/unordered_map>
+#endif
+namespace avg {
+
+class ThreadProfiler;
+typedef boost::shared_ptr<ThreadProfiler> ThreadProfilerPtr;
+class ProfilingZone;
+typedef boost::shared_ptr<ProfilingZone> ProfilingZonePtr;
+class ProfilingZoneID;
+
+class AVG_API ThreadProfiler
+{
+public:
+ static ThreadProfiler* get();
+ static void kill();
+ ThreadProfiler();
+ virtual ~ThreadProfiler();
+ void setLogCategory(category_t category);
+
+ void start();
+ void restart();
+ void startZone(const ProfilingZoneID& zoneID);
+ void stopZone(const ProfilingZoneID& zoneID);
+ void dumpStatistics();
+ void reset();
+ int getNumZones();
+
+ const std::string& getName() const;
+ void setName(const std::string& sName);
+
+private:
+ ProfilingZonePtr addZone(const ProfilingZoneID& zoneID);
+ std::string m_sName;
+
+#if defined(_WIN32) || defined(_LIBCPP_VERSION)
+ typedef std::unordered_map<const ProfilingZoneID*, ProfilingZonePtr> ZoneMap;
+#else
+ typedef std::tr1::unordered_map<const ProfilingZoneID*, ProfilingZonePtr> ZoneMap;
+#endif
+ typedef std::vector<ProfilingZonePtr> ZoneVector;
+ ZoneMap m_ZoneMap;
+ ZoneVector m_ActiveZones;
+ ZoneVector m_Zones;
+ bool m_bRunning;
+ category_t m_LogCategory;
+
+ static boost::thread_specific_ptr<ThreadProfiler*> s_pInstance;
+};
+
+}
+
+#endif
diff --git a/src/base/TimeSource.cpp b/src/base/TimeSource.cpp
new file mode 100644
index 0000000..e90575d
--- /dev/null
+++ b/src/base/TimeSource.cpp
@@ -0,0 +1,128 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "TimeSource.h"
+
+#include "Logger.h"
+#include "Exception.h"
+
+#ifdef _WIN32
+#include <time.h>
+#include <sys/timeb.h>
+#include <windows.h>
+#include <Mmsystem.h>
+#else
+#include <sys/time.h>
+#endif
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <errno.h>
+#include <assert.h>
+#include <iostream>
+#include <sstream>
+#include <unistd.h>
+
+using namespace std;
+
+namespace avg {
+
+TimeSource* TimeSource::m_pTimeSource = 0;
+
+TimeSource * TimeSource::get()
+{
+ if (!m_pTimeSource) {
+#ifdef _WIN32
+ TIMECAPS tc;
+ UINT wTimerRes;
+ MMRESULT err = timeGetDevCaps(&tc, sizeof(TIMECAPS));
+ AVG_ASSERT(err == TIMERR_NOERROR);
+ wTimerRes = max(tc.wPeriodMin, 1);
+ timeBeginPeriod(wTimerRes);
+#endif
+ m_pTimeSource = new TimeSource;
+ }
+ return m_pTimeSource;
+}
+
+TimeSource::TimeSource()
+{
+#ifdef __APPLE__
+ mach_timebase_info(&m_TimebaseInfo);
+#endif
+}
+
+TimeSource::~TimeSource()
+{
+}
+
+long long TimeSource::getCurrentMillisecs()
+{
+ return getCurrentMicrosecs()/1000;
+}
+
+long long TimeSource::getCurrentMicrosecs()
+{
+#ifdef _WIN32
+ return (long long)(timeGetTime())*1000;
+#else
+#ifdef __APPLE__
+ long long systemTime = mach_absolute_time();
+ return (systemTime * m_TimebaseInfo.numer/m_TimebaseInfo.denom)/1000;
+#else
+ struct timespec now;
+ int rc = clock_gettime(CLOCK_MONOTONIC, &now);
+ assert(rc == 0);
+ return ((long long)now.tv_sec)*1000000+now.tv_nsec/1000;
+#endif
+#endif
+}
+
+void TimeSource::sleepUntil(long long targetTime)
+{
+ long long now = getCurrentMillisecs();
+#ifdef __APPLE__
+ if (targetTime > now) {
+ msleep(targetTime-now);
+ }
+#else
+ while (now<targetTime) {
+ if (targetTime-now<=2) {
+ msleep(0);
+ } else {
+ msleep(int(targetTime-now-2));
+ }
+ now = getCurrentMillisecs();
+ }
+#endif
+}
+
+void msleep(int millisecs)
+{
+#if _WIN32
+ Sleep(millisecs);
+#else
+ usleep((long long)(millisecs)*1000);
+#endif
+}
+
+}
+
diff --git a/src/base/TimeSource.h b/src/base/TimeSource.h
new file mode 100644
index 0000000..a4ca9ae
--- /dev/null
+++ b/src/base/TimeSource.h
@@ -0,0 +1,60 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _TimeSource_H_
+#define _TimeSource_H_
+
+#include "../api.h"
+
+#ifdef __APPLE__
+#include <mach/mach_time.h>
+#endif
+
+namespace avg {
+
+
+// This class is a monotonic time source with an undefined start time. Time is guarranteed
+// to increase monotonically. The time source has no jumps and does not go backwards,
+// even if system time is changed.
+class AVG_API TimeSource {
+public:
+ static TimeSource* get();
+ virtual ~TimeSource();
+
+ long long getCurrentMillisecs();
+ long long getCurrentMicrosecs();
+
+ void sleepUntil(long long targetTime);
+
+private:
+ TimeSource();
+#ifdef __APPLE__
+ mach_timebase_info_data_t m_TimebaseInfo;
+#endif
+
+ static TimeSource* m_pTimeSource;
+};
+
+void AVG_API msleep(int millisecs);
+
+}
+
+#endif
diff --git a/src/base/Triangle.cpp b/src/base/Triangle.cpp
new file mode 100644
index 0000000..7efe9f7
--- /dev/null
+++ b/src/base/Triangle.cpp
@@ -0,0 +1,105 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "Triangle.h"
+
+#include "GLMHelper.h"
+
+#include <math.h>
+
+namespace avg {
+
+Triangle::Triangle(const glm::vec2& P0, const glm::vec2& P1, const glm::vec2& P2)
+ : p0(P0),
+ p1(P1),
+ p2(P2)
+{
+}
+
+Triangle::Triangle()
+{
+}
+
+bool Triangle::operator ==(const Triangle & tri) const
+{
+ return (p0 == tri.p0 && p1 == tri.p1 && p2 == tri.p2);
+}
+
+bool Triangle::isInside(const glm::vec2& pt) const
+{
+/* Slower func that only works for cw triangles.
+
+ glm::vec2 a = p2-p1;
+ glm::vec2 bp = pt-p1;
+ float aCROSSbp = a.x*bp.y - a.y*bp.x;
+ if (aCROSSbp < 0.0) {
+ return false;
+ }
+
+ glm::vec2 b = p0-p2;
+ glm::vec2 cp = pt-p2;
+ float bCROSScp = b.x*cp.y - b.y*cp.x;
+ if (bCROSScp < 0.0) {
+ return false;
+ }
+
+ glm::vec2 c = p1-p0;
+ glm::vec2 ap = pt-p0;
+ float cCROSSap = c.x*ap.y - c.y*ap.x;
+ return cCROSSap >= 0.0;
+*/
+ glm::vec2 v0 = p2 - p0;
+ glm::vec2 v1 = p1 - p0;
+ glm::vec2 v2 = pt - p0;
+
+ float dot00 = glm::dot(v0, v0);
+ float dot01 = glm::dot(v0, v1);
+ float dot02 = glm::dot(v0, v2);
+ float dot11 = glm::dot(v1, v1);
+ float dot12 = glm::dot(v1, v2);
+
+ float invDenom = 1 / (dot00 * dot11 - dot01 * dot01);
+ float u = (dot11 * dot02 - dot01 * dot12) * invDenom;
+ float v = (dot00 * dot12 - dot01 * dot02) * invDenom;
+
+ return (u > 0) && (v > 0) && (u + v < 1);
+
+}
+
+float Triangle::getArea() const
+{
+ return fabs((((p1.x-p0.x)*(p2.y-p0.y)) - ((p1.y-p0.y)*(p2.x-p0.x)))/2);
+}
+
+bool Triangle::isClockwise() const
+{
+ return ((p1.x-p0.x)*(p2.y-p0.y)) - ((p1.y-p0.y)*(p2.x-p0.x)) < 0;
+}
+
+std::ostream& operator<<(std::ostream& os, const Triangle& tri)
+{
+ os << "(" << tri.p0 << "," << tri.p1 << "," << tri.p2 << ")";
+ return os;
+}
+
+
+}
+
diff --git a/src/base/Triangle.h b/src/base/Triangle.h
new file mode 100644
index 0000000..21ad35f
--- /dev/null
+++ b/src/base/Triangle.h
@@ -0,0 +1,52 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _Triangle_H_
+#define _Triangle_H_
+
+#include "../api.h"
+
+#include "../glm/glm.hpp"
+
+#include <iostream>
+
+namespace avg {
+
+struct AVG_API Triangle {
+public:
+ glm::vec2 p0;
+ glm::vec2 p1;
+ glm::vec2 p2;
+
+ Triangle(const glm::vec2& P0, const glm::vec2& P1, const glm::vec2& P2);
+ Triangle();
+
+ bool operator ==(const Triangle & tri) const;
+ bool isInside(const glm::vec2& pt) const;
+ float getArea() const;
+ bool isClockwise() const;
+};
+
+std::ostream& operator<<(std::ostream& os, const Triangle& tri);
+
+}
+
+#endif
diff --git a/src/base/UTF8String.cpp b/src/base/UTF8String.cpp
new file mode 100644
index 0000000..4855364
--- /dev/null
+++ b/src/base/UTF8String.cpp
@@ -0,0 +1,62 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "UTF8String.h"
+
+#include <iostream>
+
+using namespace std;
+
+namespace avg {
+
+UTF8String::UTF8String()
+{
+}
+
+UTF8String::UTF8String(const string& s)
+ : string(s)
+{
+}
+
+UTF8String::UTF8String(const char * psz)
+ : string(psz)
+{
+
+}
+
+UTF8String& UTF8String::operator =(const string& s)
+{
+ *dynamic_cast<string*>(this) = s;
+ return *this;
+}
+
+UTF8String& UTF8String::operator =(const char* psz)
+{
+ *dynamic_cast<string*>(this) = psz;
+ return *this;
+}
+
+std::size_t hash_value(const avg::UTF8String& x)
+{
+ boost::hash<std::string> hasher;
+ return hasher(x);
+};
+}
diff --git a/src/base/UTF8String.h b/src/base/UTF8String.h
new file mode 100644
index 0000000..3cee69d
--- /dev/null
+++ b/src/base/UTF8String.h
@@ -0,0 +1,46 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _UTF8String_H_
+#define _UTF8String_H_
+
+#include "../api.h"
+#include <boost/functional/hash.hpp>
+#include <string>
+
+namespace avg {
+
+class AVG_TEMPLATE_API UTF8String: public std::string
+{
+public:
+ UTF8String();
+ UTF8String(const std::string& s);
+ UTF8String(const char * psz);
+
+ UTF8String& operator =(const std::string& s);
+ UTF8String& operator =(const char * psz);
+
+};
+
+std::size_t hash_value(const avg::UTF8String& x);
+
+}
+#endif
diff --git a/src/base/WideLine.cpp b/src/base/WideLine.cpp
new file mode 100644
index 0000000..84f4096
--- /dev/null
+++ b/src/base/WideLine.cpp
@@ -0,0 +1,53 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "WideLine.h"
+
+#include "GLMHelper.h"
+
+namespace avg {
+
+WideLine::WideLine(const glm::vec2& p0, const glm::vec2& p1, float width)
+ : pt0(p0),
+ pt1(p1)
+{
+ glm::vec2 m = glm::normalize(pt1-pt0);
+ glm::vec2 w = glm::vec2(m.y, -m.x)*(width/2);
+ pl0 = p0-w;
+ pr0 = p0+w;
+ pl1 = p1-w;
+ pr1 = p1+w;
+ dir = glm::vec2(w.y, -w.x);
+}
+
+float WideLine::getLen() const
+{
+ return glm::length(pt1-pt0);
+}
+
+std::ostream& operator<<(std::ostream& os, const WideLine& line)
+{
+ os << "(" << line.pt0 << "," << line.pt1 << ")";
+ return os;
+}
+
+}
+
diff --git a/src/base/WideLine.h b/src/base/WideLine.h
new file mode 100644
index 0000000..28584ef
--- /dev/null
+++ b/src/base/WideLine.h
@@ -0,0 +1,48 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _WideLine_H_
+#define _WideLine_H_
+
+#include "../api.h"
+
+#include "../glm/glm.hpp"
+
+#include <iostream>
+
+namespace avg {
+
+struct AVG_API WideLine {
+ WideLine(const glm::vec2& p0, const glm::vec2& p1, float width);
+
+ float getLen() const;
+
+ glm::vec2 pt0, pt1;
+ glm::vec2 pl0, pl1;
+ glm::vec2 pr0, pr1;
+ glm::vec2 dir;
+};
+
+std::ostream& operator<<(std::ostream& os, const WideLine& line);
+
+}
+
+#endif
diff --git a/src/base/WorkerThread.cpp b/src/base/WorkerThread.cpp
new file mode 100644
index 0000000..f2efb0a
--- /dev/null
+++ b/src/base/WorkerThread.cpp
@@ -0,0 +1,41 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "WorkerThread.h"
+
+#include "OSHelper.h"
+
+namespace avg {
+
+using namespace std;
+
+#ifdef linux
+void printAffinityMask(cpu_set_t& mask)
+{
+ for (int i=0; i<32; ++i) {
+ cerr << int(CPU_ISSET(i, &mask));
+ }
+ cerr << endl;
+}
+#endif
+
+}
+
diff --git a/src/base/WorkerThread.h b/src/base/WorkerThread.h
new file mode 100644
index 0000000..c4cc3c4
--- /dev/null
+++ b/src/base/WorkerThread.h
@@ -0,0 +1,169 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _WorkerThread_H_
+#define _WorkerThread_H_
+
+#include "../api.h"
+#include "Command.h"
+#include "Exception.h"
+#include "Logger.h"
+#include "Queue.h"
+#include "ThreadHelper.h"
+#include "ThreadProfiler.h"
+#include "CmdQueue.h"
+
+#include <boost/shared_ptr.hpp>
+
+#include <iostream>
+
+namespace avg {
+
+
+template<class DERIVED_THREAD>
+class AVG_TEMPLATE_API WorkerThread {
+public:
+ typedef Command<DERIVED_THREAD> Cmd;
+ typedef typename boost::shared_ptr<Cmd> CmdPtr;
+ typedef CmdQueue<DERIVED_THREAD> CQueue;
+ typedef typename boost::shared_ptr<CQueue> CQueuePtr;
+
+ WorkerThread(const std::string& sName, CQueue& CmdQ,
+ category_t logCategory=Logger::category::PROFILE);
+ WorkerThread(WorkerThread const& other);
+ virtual ~WorkerThread();
+ void operator()();
+
+ void waitForCommand();
+ void stop();
+
+protected:
+ int getNumCmdsInQueue() const;
+
+private:
+ virtual bool init();
+ virtual bool work() = 0;
+ virtual void deinit() {};
+
+ void processCommands();
+
+ std::string m_sName;
+ bool m_bShouldStop;
+ CQueue& m_CmdQ;
+ category_t m_LogCategory;
+};
+
+template<class DERIVED_THREAD>
+WorkerThread<DERIVED_THREAD>::WorkerThread(const std::string& sName, CQueue& CmdQ,
+ category_t logCategory)
+ : m_sName(sName),
+ m_bShouldStop(false),
+ m_CmdQ(CmdQ),
+ m_LogCategory(logCategory)
+{
+}
+
+template<class DERIVED_THREAD>
+WorkerThread<DERIVED_THREAD>::WorkerThread(WorkerThread const& other)
+ : m_CmdQ(other.m_CmdQ)
+{
+ m_sName = other.m_sName;
+ m_bShouldStop = other.m_bShouldStop;
+ m_LogCategory = other.m_LogCategory;
+}
+
+template<class DERIVED_THREAD>
+WorkerThread<DERIVED_THREAD>::~WorkerThread()
+{
+}
+
+template<class DERIVED_THREAD>
+void WorkerThread<DERIVED_THREAD>::operator()()
+{
+ try {
+ setAffinityMask(false);
+ ThreadProfiler* pProfiler = ThreadProfiler::get();
+ pProfiler->setName(m_sName);
+ pProfiler->setLogCategory(m_LogCategory);
+ bool bOK;
+ bOK = init();
+ if (!bOK) {
+ return;
+ }
+ pProfiler->start();
+ while (!m_bShouldStop) {
+ bOK = work();
+ if (!bOK) {
+ m_bShouldStop = true;
+ }
+ if (!m_bShouldStop) {
+ processCommands();
+ }
+ }
+ deinit();
+ pProfiler->dumpStatistics();
+ pProfiler->kill();
+ } catch (const Exception& e) {
+ AVG_LOG_ERROR("Uncaught exception in thread " << m_sName << ": " << e.getStr());
+ throw;
+ }
+}
+
+template<class DERIVED_THREAD>
+void WorkerThread<DERIVED_THREAD>::waitForCommand()
+{
+ CmdPtr pCmd = m_CmdQ.pop(true);
+ pCmd->execute(dynamic_cast<DERIVED_THREAD*>(this));
+}
+
+template<class DERIVED_THREAD>
+void WorkerThread<DERIVED_THREAD>::stop()
+{
+ m_bShouldStop = true;
+}
+
+template<class DERIVED_THREAD>
+int WorkerThread<DERIVED_THREAD>::getNumCmdsInQueue() const
+{
+ return m_CmdQ.size();
+}
+
+template<class DERIVED_THREAD>
+bool WorkerThread<DERIVED_THREAD>::init()
+{
+ return true;
+}
+
+template<class DERIVED_THREAD>
+void WorkerThread<DERIVED_THREAD>::processCommands()
+{
+ CmdPtr pCmd = m_CmdQ.pop(false);
+ while (pCmd && !m_bShouldStop) {
+ pCmd->execute(dynamic_cast<DERIVED_THREAD*>(this));
+ if (!m_bShouldStop) {
+ pCmd = m_CmdQ.pop(false);
+ }
+ }
+}
+
+}
+
+#endif
diff --git a/src/base/XMLHelper.cpp b/src/base/XMLHelper.cpp
new file mode 100644
index 0000000..6f362e8
--- /dev/null
+++ b/src/base/XMLHelper.cpp
@@ -0,0 +1,225 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "XMLHelper.h"
+#include "Exception.h"
+#include "Logger.h"
+
+#include <libxml/parserInternals.h>
+#include <cstring>
+#include <iostream>
+
+using namespace std;
+
+namespace avg {
+
+string getXmlChildrenAsString(const xmlDocPtr xmlDoc, const xmlNodePtr& xmlNode)
+{
+ string s;
+ xmlBufferPtr pBuffer = xmlBufferCreate();
+ xmlNodeDump(pBuffer, xmlDoc, xmlNode, 0, 0);
+
+ s = (const char *)xmlBufferContent(pBuffer);
+ size_t StartPos = s.find('>')+1;
+ size_t EndPos = s.rfind('<')-1;
+ if (StartPos > EndPos) {
+ s = "";
+ } else {
+ s = s.substr(StartPos, EndPos-StartPos+1);
+ }
+ xmlBufferFree(pBuffer);
+ return s;
+}
+
+static xmlExternalEntityLoader DefaultLoaderProc = 0;
+static std::map<string, string> g_DTDMap;
+
+xmlParserInputPtr
+DTDExternalEntityLoader(const char *pURL, const char *pID, xmlParserCtxtPtr ctxt)
+{
+ xmlParserInputPtr ret;
+ /* lookup for the fileID depending on ID */
+ std::map<string, string>::iterator it = g_DTDMap.find(pURL);
+
+ if (it != g_DTDMap.end()) {
+ ret = xmlNewStringInputStream(ctxt, (const xmlChar *)(it->second.c_str()));
+ return(ret);
+ } else {
+ ret = DefaultLoaderProc(pURL, pID, ctxt);
+ return(ret);
+ }
+}
+
+void registerDTDEntityLoader(const string& sID, const string& sDTD)
+{
+ g_DTDMap[sID] = sDTD;
+ if (!DefaultLoaderProc) {
+ DefaultLoaderProc = xmlGetExternalEntityLoader();
+ }
+ xmlSetExternalEntityLoader(DTDExternalEntityLoader);
+}
+
+
+XMLParser::XMLParser()
+ : m_SchemaParserCtxt(0),
+ m_Schema(0),
+ m_SchemaValidCtxt(0),
+ m_DTD(0),
+ m_DTDValidCtxt(0),
+ m_Doc(0)
+{
+ xmlPedanticParserDefault(1);
+ xmlSetGenericErrorFunc(this, errorOutputFunc);
+ xmlDoValidityCheckingDefaultValue = 0;
+}
+
+XMLParser::~XMLParser()
+{
+ if (m_Schema) {
+ xmlSchemaFree(m_Schema);
+ }
+ if (m_SchemaParserCtxt) {
+ xmlSchemaFreeParserCtxt(m_SchemaParserCtxt);
+ }
+ if (m_SchemaValidCtxt) {
+ xmlSchemaFreeValidCtxt(m_SchemaValidCtxt);
+ }
+ if (m_DTD) {
+ xmlFreeDtd(m_DTD);
+ }
+ if (m_DTDValidCtxt) {
+ xmlFreeValidCtxt(m_DTDValidCtxt);
+ }
+ if (m_Doc) {
+ xmlFreeDoc(m_Doc);
+ }
+ xmlSetGenericErrorFunc(0, 0);
+}
+
+void XMLParser::setSchema(const string& sSchema, const string& sSchemaName)
+{
+ AVG_ASSERT(!m_SchemaParserCtxt);
+ AVG_ASSERT(!m_Schema);
+ AVG_ASSERT(!m_SchemaValidCtxt);
+ AVG_ASSERT(!m_DTD);
+ AVG_ASSERT(!m_DTDValidCtxt);
+
+ m_SchemaParserCtxt = xmlSchemaNewMemParserCtxt(sSchema.c_str(), sSchema.length());
+ checkError(!m_SchemaParserCtxt, sSchemaName);
+
+ m_Schema = xmlSchemaParse(m_SchemaParserCtxt);
+ checkError(!m_Schema, sSchemaName);
+
+ m_SchemaValidCtxt = xmlSchemaNewValidCtxt(m_Schema);
+ checkError(!m_SchemaValidCtxt, sSchemaName);
+}
+
+void XMLParser::setDTD(const std::string& sDTD, const std::string& sDTDName)
+{
+ AVG_ASSERT(!m_SchemaParserCtxt);
+ AVG_ASSERT(!m_Schema);
+ AVG_ASSERT(!m_SchemaValidCtxt);
+ AVG_ASSERT(!m_DTD);
+ AVG_ASSERT(!m_DTDValidCtxt);
+
+ registerDTDEntityLoader("memory.dtd", sDTD.c_str());
+ string sDTDFName = "memory.dtd";
+ m_DTD = xmlParseDTD(NULL, (const xmlChar*) sDTDFName.c_str());
+ checkError(!m_DTD, sDTDName);
+
+ m_DTDValidCtxt = xmlNewValidCtxt();
+ checkError(!m_DTDValidCtxt, sDTDName);
+ m_DTDValidCtxt->error = xmlParserValidityError;
+ m_DTDValidCtxt->warning = xmlParserValidityWarning;
+}
+
+void XMLParser::parse(const string& sXML, const string& sXMLName)
+{
+ if (m_Doc) {
+ xmlFreeDoc(m_Doc);
+ }
+ m_Doc = xmlParseMemory(sXML.c_str(), int(sXML.length()));
+ checkError(!m_Doc, sXMLName);
+
+ bool bOK = true;
+ if (m_SchemaValidCtxt) {
+ int err = xmlSchemaValidateDoc(m_SchemaValidCtxt, m_Doc);
+ AVG_ASSERT(err != -1);
+ bOK = (err == 0);
+ }
+ if (m_DTD) {
+ int err = xmlValidateDtd(m_DTDValidCtxt, m_Doc, m_DTD);
+ bOK = (err != 0);
+ }
+ if (!bOK) {
+ xmlFreeDoc(m_Doc);
+ m_Doc = 0;
+ checkError(true, sXMLName);
+ }
+}
+
+xmlDocPtr XMLParser::getDoc()
+{
+ AVG_ASSERT(m_Doc);
+ return m_Doc;
+}
+
+xmlNodePtr XMLParser::getRootNode()
+{
+ AVG_ASSERT(m_Doc);
+ return xmlDocGetRootElement(m_Doc);
+}
+
+void XMLParser::errorOutputFunc(void * ctx, const char * msg, ...)
+{
+ va_list args;
+ va_start(args, msg);
+ ((XMLParser*)ctx)->internalErrorHandler(msg, args);
+ va_end(args);
+}
+
+void XMLParser::internalErrorHandler(const char * msg, va_list args)
+{
+ char psz[1024];
+ vsnprintf(psz, 1024, msg, args);
+ m_sError += psz;
+}
+
+void XMLParser::checkError(bool bError, const string& sXMLName)
+{
+ if (bError) {
+ string sError = "Error parsing "+sXMLName+".\n";
+ sError += m_sError;
+ m_sError = "";
+ throw (Exception(AVG_ERR_XML_PARSE, sError));
+ }
+}
+
+void validateXml(const string& sXML, const string& sSchema, const string& sXMLName,
+ const string& sSchemaName)
+{
+ XMLParser parser;
+ parser.setSchema(sSchema, sSchemaName);
+
+ parser.parse(sXML, sXMLName);
+}
+
+}
diff --git a/src/base/XMLHelper.h b/src/base/XMLHelper.h
new file mode 100644
index 0000000..e258de2
--- /dev/null
+++ b/src/base/XMLHelper.h
@@ -0,0 +1,78 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _XMLHelper_H_
+#define _XMLHelper_H_
+
+#include "../api.h"
+
+#include <libxml/parser.h>
+#include <libxml/xmlwriter.h>
+#include <libxml/xmlschemas.h>
+
+#include <string>
+#include <map>
+#include <sstream>
+
+namespace avg {
+
+std::string getXmlChildrenAsString(const xmlDocPtr xmlDoc, const xmlNodePtr& xmlNode);
+
+void registerDTDEntityLoader(const std::string& sID, const std::string& sDTD);
+
+class XMLParser
+{
+public:
+ XMLParser();
+ virtual ~XMLParser();
+
+ void setSchema(const std::string& sSchema, const std::string& sSchemaName);
+ void setDTD(const std::string& sDTD, const std::string& sDTDName);
+ void parse(const std::string& sXML, const std::string& sXMLName);
+
+ xmlDocPtr getDoc();
+ xmlNodePtr getRootNode();
+
+private:
+ static void errorOutputFunc(void * ctx, const char * msg, ...);
+ void internalErrorHandler(const char * msg, va_list args);
+
+ void checkError(bool bError, const std::string& sXMLName);
+
+ xmlSchemaParserCtxtPtr m_SchemaParserCtxt;
+ xmlSchemaPtr m_Schema;
+ xmlSchemaValidCtxtPtr m_SchemaValidCtxt;
+
+ xmlDtdPtr m_DTD;
+ xmlValidCtxtPtr m_DTDValidCtxt;
+
+ xmlDocPtr m_Doc;
+
+ std::string m_sError;
+};
+
+void validateXml(const std::string& sXML, const std::string& sSchema,
+ const std::string& sXMLName, const std::string& sSchemaName);
+
+}
+
+#endif
+
diff --git a/src/base/testbase.cpp b/src/base/testbase.cpp
new file mode 100644
index 0000000..57faf36
--- /dev/null
+++ b/src/base/testbase.cpp
@@ -0,0 +1,1024 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "DAG.h"
+#include "Queue.h"
+#include "Command.h"
+#include "WorkerThread.h"
+#include "ObjectCounter.h"
+#include "triangulate/Triangulate.h"
+#include "GLMHelper.h"
+#include "GeomHelper.h"
+#include "OSHelper.h"
+#include "FileHelper.h"
+#include "StringHelper.h"
+#include "MathHelper.h"
+#include "CubicSpline.h"
+#include "BezierCurve.h"
+#include "Signal.h"
+#include "Backtrace.h"
+#include "WideLine.h"
+#include "Rect.h"
+#include "Triangle.h"
+#include "TestSuite.h"
+#include "TimeSource.h"
+#include "XMLHelper.h"
+#include "Logger.h"
+
+#include <boost/thread/thread.hpp>
+
+#include <boost/bind.hpp>
+
+#include <iostream>
+#include <sstream>
+#include <stdio.h>
+#include <stdlib.h>
+
+using namespace avg;
+using namespace std;
+using namespace boost;
+
+class DAGTest: public Test
+{
+public:
+ DAGTest()
+ : Test("DAGTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+ {
+ DAG dag;
+
+ dag.addNode(1, set<long>());
+ long outgoing2[] = {1};
+ dag.addNode(0, makeOutgoing(1, outgoing2));
+
+ long expected[] = {0, 1};
+ checkResults(&dag, expected);
+ }
+ {
+ DAG dag;
+
+ dag.addNode(2, set<long>());
+ long outgoing2[] = {1};
+ dag.addNode(0, makeOutgoing(1, outgoing2));
+ long outgoing3[] = {2};
+ dag.addNode(1, makeOutgoing(1, outgoing3));
+
+ long expected[] = {0, 1, 2};
+ checkResults(&dag, expected);
+ }
+ {
+ DAG dag;
+
+ long outgoing2[] = {1};
+ dag.addNode(0, makeOutgoing(1, outgoing2));
+ dag.addNode(2, set<long>());
+ long outgoing3[] = {2};
+ dag.addNode(1, makeOutgoing(1, outgoing3));
+
+ long expected[] = {0, 1, 2};
+ checkResults(&dag, expected);
+ }
+ {
+ DAG dag;
+
+ dag.addNode(2, set<long>());
+ long outgoing2[] = {1, 2};
+ dag.addNode(0, makeOutgoing(1, outgoing2));
+ long outgoing3[] = {2};
+ dag.addNode(1, makeOutgoing(1, outgoing3));
+
+ long expected[] = {0, 1, 2};
+ checkResults(&dag, expected);
+ }
+ {
+ DAG dag;
+
+ long outgoing2[] = {1};
+ dag.addNode(0, makeOutgoing(1, outgoing2));
+ long outgoing3[] = {0};
+ dag.addNode(1, makeOutgoing(1, outgoing3));
+
+ bool bExceptionThrown = false;
+ long expected[] = {0, 1, 2};
+ try {
+ checkResults(&dag, expected);
+ } catch (const Exception&) {
+ bExceptionThrown = true;
+ }
+ TEST(bExceptionThrown);
+ }
+ }
+
+private:
+ set<long> makeOutgoing(int n, long ids[])
+ {
+ set<long> v;
+ for (int i=0; i<n; ++i) {
+ v.insert(ids[i]);
+ }
+ return v;
+ }
+
+ void checkResults(DAG* pDAG, long expected[])
+ {
+ vector<long> results;
+ pDAG->sort(results);
+
+ for (unsigned i=0; i<results.size(); ++i) {
+ QUIET_TEST(results[i] == expected[i]);
+ }
+ }
+};
+
+class QueueTest: public Test
+{
+public:
+ QueueTest()
+ : Test("QueueTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+ runSingleThreadTests();
+ runMultiThreadTests();
+ }
+
+private:
+ typedef Queue<int>::QElementPtr ElemPtr;
+
+ void runSingleThreadTests()
+ {
+ Queue<string> q;
+ typedef Queue<string>::QElementPtr ElemPtr;
+ TEST(q.empty());
+ q.push(ElemPtr(new string("1")));
+ TEST(q.size() == 1);
+ TEST(!q.empty());
+ q.push(ElemPtr(new string("2")));
+ q.push(ElemPtr(new string("3")));
+ TEST(q.size() == 3);
+ TEST(*q.pop() == "1");
+ TEST(*q.pop() == "2");
+ q.push(ElemPtr(new string("4")));
+ TEST(*q.pop() == "3");
+ TEST(*q.peek() == "4");
+ TEST(*q.pop() == "4");
+ TEST(q.empty());
+ ElemPtr pElem = q.pop(false);
+ TEST(!pElem);
+ }
+
+ void runMultiThreadTests()
+ {
+ {
+ Queue<int> q(10);
+ thread pusher(boost::bind(&pushThread, &q, 100));
+ thread popper(boost::bind(&popThread, &q, 100));
+ pusher.join();
+ popper.join();
+ TEST(q.empty());
+ }
+ {
+ Queue<int> q(10);
+ thread pusher1(boost::bind(&pushThread, &q, 100));
+ thread pusher2(boost::bind(&pushThread, &q, 100));
+ thread popper(boost::bind(&popThread, &q, 200));
+ pusher1.join();
+ pusher2.join();
+ popper.join();
+ TEST(q.empty());
+ }
+ {
+ Queue<int> q(10);
+ thread pusher(boost::bind(&pushClearThread, &q, 100));
+ thread popper(boost::bind(&popClearThread, &q));
+ pusher.join();
+ popper.join();
+ TEST(q.empty());
+ }
+ }
+
+ static void pushThread(Queue<int>* pq, int numPushes)
+ {
+ for (int i=0; i<numPushes; ++i) {
+ pq->push(ElemPtr(new int(i)));
+ msleep(1);
+ }
+ }
+
+ static void popThread(Queue<int>* pq, int numPops)
+ {
+ for (int i=0; i<numPops; ++i) {
+ pq->peek();
+ pq->pop();
+ msleep(3);
+ }
+ }
+
+ static void pushClearThread(Queue<int>* pq, int numPushes)
+ {
+ typedef Queue<int>::QElementPtr ElemPtr;
+ for (int i=0; i<numPushes; ++i) {
+ pq->push(ElemPtr(new int(i)));
+ if (i%7 == 0) {
+ pq->clear();
+ }
+ msleep(1);
+ }
+ pq->push(ElemPtr(new int(-1)));
+ }
+
+ static void popClearThread(Queue<int>* pq)
+ {
+ ElemPtr pElem;
+ do {
+ pElem = pq->pop();
+ } while (*pElem != -1);
+ }
+};
+
+class TestWorkerThread: public WorkerThread<TestWorkerThread>
+{
+public:
+ TestWorkerThread(CQueue& cmdQ, int* pNumFuncCalls, int* pIntParam,
+ string* pStringParam)
+ : WorkerThread<TestWorkerThread>("Thread1", cmdQ),
+ m_pNumFuncCalls(pNumFuncCalls),
+ m_pIntParam(pIntParam),
+ m_pStringParam(pStringParam)
+ {
+ }
+
+ bool init()
+ {
+ (*m_pNumFuncCalls)++;
+ return true;
+ }
+
+ bool work()
+ {
+ (*m_pNumFuncCalls)++;
+ waitForCommand();
+ return true;
+ }
+
+ void deinit()
+ {
+ (*m_pNumFuncCalls)++;
+ }
+
+ void doSomething(int i, std::string s)
+ {
+ *m_pIntParam = i;
+ *m_pStringParam = s;
+ }
+
+private:
+ int * m_pNumFuncCalls;
+ int * m_pIntParam;
+ std::string * m_pStringParam;
+};
+
+
+class WorkerThreadTest: public Test
+{
+public:
+ WorkerThreadTest()
+ : Test("WorkerThreadTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+ typedef TestWorkerThread::CmdPtr CmdPtr;
+ TestWorkerThread::CQueue cmdQ;
+ boost::thread* pTestThread;
+ int numFuncCalls = 0;
+ int intParam = 0;
+ std::string stringParam;
+ cmdQ.pushCmd(boost::bind(&TestWorkerThread::doSomething, _1, 23, "foo"));
+ cmdQ.pushCmd(boost::bind(&TestWorkerThread::stop, _1));
+ pTestThread = new boost::thread(TestWorkerThread(cmdQ, &numFuncCalls,
+ &intParam, &stringParam));
+ pTestThread->join();
+ delete pTestThread;
+ TEST(numFuncCalls == 3);
+ TEST(intParam == 23);
+ TEST(stringParam == "foo");
+ }
+};
+
+
+class DummyClass
+{
+public:
+ DummyClass()
+ {
+ ObjectCounter::get()->incRef(&typeid(*this));
+ }
+
+ virtual ~DummyClass()
+ {
+ ObjectCounter::get()->decRef(&typeid(*this));
+ }
+
+ int i;
+};
+
+
+class ObjectCounterTest: public Test {
+public:
+ ObjectCounterTest()
+ : Test("ObjectCounterTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+ TEST(ObjectCounter::get()->getCount(&typeid(DummyClass)) == 0);
+ {
+ DummyClass dummy1;
+ DummyClass dummy2;
+ TEST(ObjectCounter::get()->getCount(&typeid(dummy1)) == 2);
+ }
+ TEST(ObjectCounter::get()->getCount(&typeid(DummyClass)) == 0);
+ }
+};
+
+
+// The following pragmas avoid a compiler warning (potential division by 0)
+#ifdef _MSC_VER
+#pragma optimize("", off)
+#pragma warning(push)
+#pragma warning(disable:4723)
+#endif
+class GeomTest: public Test
+{
+public:
+ GeomTest()
+ : Test("GeomTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+ // TODO: Move to a separate math test once we're done here.
+ TEST(almostEqual(invSqrt(1), 1));
+ TEST(almostEqual(invSqrt(4), 0.5));
+
+ {
+ LineSegment l1(glm::vec2(0,0), glm::vec2(2,2));
+ LineSegment l2(glm::vec2(2,0), glm::vec2(0,2));
+ TEST(lineSegmentsIntersect(l1, l2));
+ TEST(lineSegmentsIntersect(l2, l1));
+ }
+ {
+ LineSegment l1(glm::vec2(0,0), glm::vec2(0,2));
+ LineSegment l2(glm::vec2(2,0), glm::vec2(2,2));
+ TEST(!lineSegmentsIntersect(l1, l2));
+ }
+ {
+ LineSegment l1(glm::vec2(0,0), glm::vec2(2,0));
+ LineSegment l2(glm::vec2(0,2), glm::vec2(2,2));
+ TEST(!lineSegmentsIntersect(l1, l2));
+ }
+ {
+ LineSegment l1(glm::vec2(0,0), glm::vec2(2,0));
+ TEST(l1.isPointOver(glm::vec2(1,23)));
+ TEST(l1.isPointOver(glm::vec2(1.9,-5)));
+ TEST(!l1.isPointOver(glm::vec2(-1,1)));
+ TEST(!l1.isPointOver(glm::vec2(3,-1)));
+ }
+ {
+ glm::vec2 pt0(glm::vec2(1,1));
+ glm::vec2 pt1(glm::vec2(1,3));
+ glm::vec2 pt2(glm::vec2(1,-2));
+ vector<glm::vec2> poly;
+ poly.push_back(glm::vec2(0,0));
+ poly.push_back(glm::vec2(2,0));
+ poly.push_back(glm::vec2(2,2));
+ poly.push_back(glm::vec2(0,2));
+ TEST(pointInPolygon(pt0, poly));
+ TEST(!pointInPolygon(pt1, poly));
+ TEST(!pointInPolygon(pt2, poly));
+ poly.push_back(glm::vec2(2,1));
+ TEST(!pointInPolygon(pt0, poly));
+ }
+ {
+ glm::vec2 p1(glm::vec2(0,0));
+ glm::vec2 v1(glm::vec2(1,1));
+ glm::vec2 p2(glm::vec2(2,1));
+ glm::vec2 v2(glm::vec2(1,0));
+ TEST(getLineLineIntersection(p1, v1, p2, v2) == glm::vec2(1,1));
+ }
+ TEST(almostEqual(getRotatedPivot(glm::vec2(10,0), M_PI, glm::vec2(15,5)),
+ glm::vec2(20,10)));
+ TEST(almostEqual(getRotatedPivot(glm::vec2(10,0), M_PI*0.5, glm::vec2(15,5)),
+ glm::vec2(20,0)));
+ TEST(almostEqual(getRotatedPivot(glm::vec2(10,0), M_PI*1.5, glm::vec2(15,5)),
+ glm::vec2(10,10)));
+ TEST(almostEqual(getRotatedPivot(glm::vec2(10,0), M_PI*2, glm::vec2(15,5)),
+ glm::vec2(10,0)));
+ TEST(almostEqual(getRotatedPivot(glm::vec2(23,0), M_PI*0.5), glm::vec2(0,23)));
+
+ {
+ // TODO: More tests
+ FRect(0,0,10,10);
+ }
+ }
+};
+#ifdef _MSC_VER
+#pragma warning(pop)
+#pragma optimize("", on)
+#endif
+
+
+class TriangleTest: public Test
+{
+public:
+ TriangleTest()
+ : Test("TriangleTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+ Triangle tri(glm::vec2(0,0), glm::vec2(4,4), glm::vec2(4,8));
+ TEST(tri.isInside(glm::vec2(3,4)));
+ TEST(!tri.isInside(glm::vec2(1,4)));
+ TEST(!tri.isInside(glm::vec2(2,1)));
+ TEST(!tri.isInside(glm::vec2(-2,5)));
+ TEST(!tri.isInside(glm::vec2(5,5)));
+ tri = Triangle(glm::vec2(0,0), glm::vec2(4,8), glm::vec2(4,4));
+ TEST(tri.isInside(glm::vec2(3,4)));
+
+ glm::vec2 polyArray[] = {glm::vec2(0,0), glm::vec2(8,2), glm::vec2(9,0), glm::vec2(9,3),
+ glm::vec2(1,1), glm::vec2(0,3)};
+
+ Vec2Vector poly = vectorFromCArray(6, polyArray);
+ vector<unsigned int> triangulation;
+ triangulatePolygon(triangulation, poly);
+
+ TEST(triangulation.size() == 4*3);
+ unsigned int baselineIndexes[] = {5,0,4, 1,4,0, 4,1,3, 1,2,3};
+ TEST(triangulation == vectorFromCArray(12, baselineIndexes));
+/*
+ for (unsigned int i=0; i<triangulation.size(); i++) {
+ cerr << i << ":" << triangulation[i] << endl;
+ }
+*/
+ }
+
+};
+
+
+class FileTest: public Test
+{
+public:
+ FileTest()
+ : Test("FileTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+ TEST(getPath("/foo/bar.txt") == "/foo/");
+ TEST(getFilenamePart("/foo/bar.txt") == "bar.txt");
+ }
+};
+
+
+class OSTest: public Test
+{
+public:
+ OSTest()
+ : Test("OSTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+ cerr << getAvgLibPath() << endl;
+ TEST(getAvgLibPath() != "");
+#ifdef __APPLE__
+ TEST(getMemoryUsage() != 0);
+#endif
+ }
+};
+
+
+class StringTest: public Test
+{
+public:
+ StringTest()
+ : Test("StringTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+ TEST(stringToInt("5") == 5);
+ TEST(almostEqual(stringToFloat("5.5"), 5.5f));
+ TEST(stringToBool("False") == false);
+ bool bExceptionThrown = false;
+ try {
+ stringToInt("5a");
+ } catch (const Exception& e) {
+ if (e.getCode() == AVG_ERR_TYPE ) {
+ bExceptionThrown = true;
+ }
+ }
+ TEST(bExceptionThrown);
+ TEST(stringToVec2(" ( 3.4 , 2.1 ) ") == glm::vec2(3.4f, 2.1f));
+ vector<float> v;
+ fromString("(1,2,3,4,5)", v);
+ TEST(v.size() == 5 && v[0] == 1 && v[4] == 5);
+ v.clear();
+ fromString("()", v);
+ TEST(v.size() == 0);
+ }
+};
+
+
+class SplineTest: public Test
+{
+public:
+ SplineTest()
+ : Test("SplineTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+ {
+ float xd[] = {0,1,2,3};
+ vector<float> x = vectorFromCArray(4, xd);
+ float yd[] = {3,2,1,0};
+ vector<float> y = vectorFromCArray(4, yd);
+ CubicSpline spline(x, y);
+ TEST(almostEqual(spline.interpolate(-1), 4));
+ TEST(almostEqual(spline.interpolate(0), 3));
+ TEST(almostEqual(spline.interpolate(0.5), 2.5));
+ TEST(almostEqual(spline.interpolate(3), 0));
+ TEST(almostEqual(spline.interpolate(3.5), -0.5));
+ }
+ {
+ float xd[] = {2,4,6,8};
+ vector<float> x = vectorFromCArray(4, xd);
+ float yd[] = {0,1,3,6};
+ vector<float> y = vectorFromCArray(4, yd);
+ CubicSpline spline(x, y);
+ TEST(almostEqual(spline.interpolate(0), -1));
+ TEST(almostEqual(spline.interpolate(2), 0));
+ TEST(spline.interpolate(3) < 0.5);
+ TEST(spline.interpolate(3) > 0);
+ TEST(spline.interpolate(7) > 4);
+ TEST(spline.interpolate(7) < 5);
+ TEST(almostEqual(spline.interpolate(8), 6));
+ TEST(almostEqual(spline.interpolate(10), 9));
+ }
+ {
+ float xd[] = {0,1,1};
+ vector<float> x = vectorFromCArray(3, xd);
+ float yd[] = {1,2,1};
+ vector<float> y = vectorFromCArray(3, yd);
+ bool bExceptionThrown = false;
+ try {
+ CubicSpline spline(x, y);
+ } catch (const Exception&) {
+ bExceptionThrown = true;
+ }
+ TEST(bExceptionThrown);
+ }
+/*
+ {
+ float xd[] = {0,1,2};
+ vector<float> x = vectorFromCArray(3, xd);
+ float yd[] = {1,2,1};
+ vector<float> y = vectorFromCArray(3, yd);
+ CubicSpline spline(x, y, true);
+ TEST(almostEqual(spline.interpolate(0), 1));
+ TEST(almostEqual(spline.interpolate(0.5), 1.5));
+ TEST(almostEqual(spline.interpolate(2), 1));
+ TEST(almostEqual(spline.interpolate(3), 2));
+ }
+*/
+ }
+};
+
+
+class BezierCurveTest: public Test
+{
+public:
+ BezierCurveTest()
+ : Test("BezierCurveTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+ BezierCurve curve(glm::vec2(0,0), glm::vec2(1,0), glm::vec2(1,1), glm::vec2(0,1));
+ TEST(almostEqual(curve.interpolate(0), glm::vec2(0,0)));
+ TEST(almostEqual(curve.getDeriv(0), glm::vec2(3, 0)));
+ TEST(almostEqual(curve.interpolate(1), glm::vec2(0,1)));
+ TEST(almostEqual(curve.getDeriv(1), glm::vec2(-3, 0)));
+ TEST(almostEqual(curve.interpolate(0.5), glm::vec2(0.75,0.5)));
+ }
+};
+
+
+class WideLineTest: public Test
+{
+public:
+ WideLineTest()
+ : Test("WideLineTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+ WideLine line(glm::vec2(0,0), glm::vec2(4,3), 2);
+ TEST(almostEqual(line.getLen(), 5));
+ }
+};
+
+
+class Listener
+{
+public:
+ Listener(Signal<Listener>& signal)
+ : m_Signal(signal),
+ m_bFuncCalled(false)
+ {
+ }
+
+ virtual ~Listener()
+ {}
+
+ virtual void func()
+ {
+ m_bFuncCalled = true;
+ }
+
+ bool funcCalled() const
+ {
+ return m_bFuncCalled;
+ }
+
+ void reset()
+ {
+ m_bFuncCalled = false;
+ }
+
+protected:
+ Signal<Listener>& m_Signal;
+
+private:
+ bool m_bFuncCalled;
+};
+
+
+class DisconnectingSelfListener: public Listener
+{
+public:
+ DisconnectingSelfListener(Signal<Listener>& signal)
+ : Listener(signal)
+ {
+ }
+
+ virtual void func()
+ {
+ Listener::func();
+ m_Signal.disconnect(this);
+ }
+};
+
+
+class DisconnectingOtherListener: public Listener
+{
+public:
+ DisconnectingOtherListener(Signal<Listener>& signal, Listener* pOther)
+ : Listener(signal),
+ m_pOther(pOther)
+ {
+ }
+
+ virtual void func()
+ {
+ Listener::func();
+ if (m_pOther) {
+ m_Signal.disconnect(m_pOther);
+ m_pOther = 0;
+ }
+ }
+
+private:
+ Listener* m_pOther;
+};
+
+
+class ConnectingOtherListener: public Listener
+{
+public:
+ ConnectingOtherListener(Signal<Listener>& signal, Listener* pOther)
+ : Listener(signal),
+ m_pOther(pOther)
+ {
+ }
+
+ virtual void func()
+ {
+ Listener::func();
+ if (m_pOther) {
+ m_Signal.connect(m_pOther);
+ m_pOther = 0;
+ }
+ }
+
+private:
+ Listener* m_pOther;
+};
+
+
+class SignalTest: public Test
+{
+public:
+ SignalTest()
+ : Test("SignalTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+ Signal<Listener> s(&Listener::func);
+ Listener l1(s);
+ Listener l2(s);
+ s.connect(&l1);
+ s.connect(&l2);
+ s.emit();
+ TEST(l1.funcCalled() && l2.funcCalled());
+ l1.reset();
+ l2.reset();
+
+ s.disconnect(&l1);
+ s.emit();
+ TEST(!(l1.funcCalled()) && l2.funcCalled());
+ l2.reset();
+
+ {
+ DisconnectingSelfListener disconnecter(s);
+ s.connect(&disconnecter);
+ s.emit();
+ TEST(l2.funcCalled() && disconnecter.funcCalled());
+ TEST(s.getNumListeners() == 1);
+ l2.reset();
+ disconnecter.reset();
+
+ s.emit();
+ TEST(l2.funcCalled() && !(disconnecter.funcCalled()));
+ l2.reset();
+ }
+ {
+ DisconnectingOtherListener disconnecter(s, &l2);
+ s.connect(&disconnecter);
+ s.emit();
+ TEST(l2.funcCalled() && disconnecter.funcCalled());
+ TEST(s.getNumListeners() == 1);
+ l2.reset();
+ disconnecter.reset();
+
+ s.emit();
+ TEST(!(l2.funcCalled()) && disconnecter.funcCalled());
+ s.disconnect(&disconnecter);
+ }
+ {
+ ConnectingOtherListener connecter(s, &l2);
+ s.connect(&connecter);
+ s.emit();
+ TEST(l2.funcCalled() && connecter.funcCalled());
+ TEST(s.getNumListeners() == 2);
+ l2.reset();
+ connecter.reset();
+
+ s.emit();
+ TEST(l2.funcCalled() && connecter.funcCalled());
+ }
+ }
+};
+
+
+class BacktraceTest: public Test
+{
+public:
+ BacktraceTest()
+ : Test("BacktraceTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+ vector<string> sFuncs;
+ getBacktrace(sFuncs);
+#ifndef _WIN32
+ TEST(sFuncs[0].find("runTests") != string::npos);
+#endif
+ }
+};
+
+
+class PolygonTest: public Test
+{
+public:
+ PolygonTest()
+ : Test("PolygonTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+ glm::vec2 polyArray[] = {glm::vec2(30,0), glm::vec2(40,20), glm::vec2(60,30),
+ glm::vec2(40,40), glm::vec2(30,60), glm::vec2(20,40), glm::vec2(0,30),
+ glm::vec2(20,20)};
+
+ Vec2Vector poly = vectorFromCArray(8, polyArray);
+ vector<unsigned int> triangulation;
+ triangulatePolygon(triangulation, poly);
+
+ TEST(triangulation.size() == 6*3);
+ unsigned int baselineIndexes[] = {6,7,5, 5,7,1, 7,0,1, 5,1,3, 3,1,2, 4,5,3};
+ TEST(triangulation == vectorFromCArray(18, baselineIndexes));
+/*
+ for (unsigned int i=0; i<triangulation.size(); i++) {
+ cerr << i << ":" << triangulation[i] << endl;
+ }/
+*/
+ }
+
+};
+
+
+class XmlParserTest: public Test
+{
+public:
+ XmlParserTest()
+ : Test("XmlParserTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+ string sXmlString = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+ "<shiporder orderid=\"889923\">"
+ " <orderperson>John Smith</orderperson>"
+ "</shiporder>";
+
+ {
+ string sSchema = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+ "<xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\">"
+ "<xs:element name=\"shiporder\">"
+ " <xs:complexType>"
+ " <xs:sequence>"
+ " <xs:element name=\"orderperson\" type=\"xs:string\"/>"
+ " </xs:sequence>"
+ " <xs:attribute name=\"orderid\" type=\"xs:string\" use=\"required\"/>"
+ " </xs:complexType>"
+ "</xs:element>"
+ "</xs:schema>";
+
+ XMLParser parser;
+ parser.setSchema(sSchema, "shiporder.xsd");
+ parser.parse(sXmlString, "shiporder.xml");
+ }
+ {
+ string sDTD =
+ "<!ELEMENT shiporder (orderperson)* >"
+ "<!ATTLIST shiporder"
+ " orderid CDATA #IMPLIED>"
+ "<!ELEMENT orderperson (#PCDATA) >";
+ XMLParser parser;
+ parser.setDTD(sDTD, "shiporder.dtd");
+ parser.parse(sXmlString, "shiporder.xml");
+ }
+ }
+};
+
+
+class StandardLoggerTest: public Test
+{
+public:
+ StandardLoggerTest()
+ : Test("StandardLoggerTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+ std::stringstream buffer;
+ std::streambuf *sbuf = std::cerr.rdbuf();
+ Logger *logger = Logger::get();
+ {
+ std::cerr.rdbuf(buffer.rdbuf());
+ string msg("Test log message");
+ AVG_TRACE(Logger::category::NONE, Logger::severity::WARNING, msg);
+ std::cerr.rdbuf(sbuf);
+ TEST(buffer.str().find(msg) != string::npos);
+ buffer.str(string());
+
+ std::cerr.rdbuf(buffer.rdbuf());
+ AVG_TRACE(Logger::category::NONE, Logger::severity::DEBUG, msg);
+ std::cerr.rdbuf(sbuf);
+ std::cout << buffer.str();
+ TEST(buffer.str().find(msg) == string::npos);
+ buffer.str(string());
+ }
+ {
+ std::cerr.rdbuf(buffer.rdbuf());
+ category_t CUSTOM_CAT = logger->configureCategory("CUSTOM_CAT 1");
+ string msg("CUSTOM_CAT LOG");
+ AVG_TRACE(CUSTOM_CAT, Logger::severity::WARNING, msg);
+ std::cerr.rdbuf(sbuf);
+ TEST(buffer.str().find(msg) != string::npos);
+ buffer.str(string());
+ }
+ {
+ std::cerr.rdbuf(buffer.rdbuf());
+ category_t CUSTOM_CAT = logger->configureCategory("CUSTOM_CAT 1",
+ Logger::severity::CRITICAL);
+ string msg_info("CUSTOM_CAT LOG INFO");
+ AVG_TRACE(CUSTOM_CAT, Logger::severity::WARNING, msg_info);
+ std::cerr.rdbuf(sbuf);
+ TEST(buffer.str().find(msg_info) == string::npos);
+ buffer.str(string());
+
+ std::cerr.rdbuf(buffer.rdbuf());
+ string msg_critical("CUSTOM_CAT LOG CRITICAL");
+ AVG_TRACE(CUSTOM_CAT, Logger::severity::CRITICAL, msg_critical);
+ std::cerr.rdbuf(sbuf);
+ TEST(buffer.str().find(msg_critical) != string::npos);
+ buffer.str(string());
+ }
+ }
+};
+
+class BaseTestSuite: public TestSuite
+{
+public:
+ BaseTestSuite()
+ : TestSuite("BaseTestSuite")
+ {
+ addTest(TestPtr(new DAGTest));
+ addTest(TestPtr(new QueueTest));
+ addTest(TestPtr(new WorkerThreadTest));
+ addTest(TestPtr(new ObjectCounterTest));
+ addTest(TestPtr(new GeomTest));
+ addTest(TestPtr(new TriangleTest));
+ addTest(TestPtr(new FileTest));
+ addTest(TestPtr(new OSTest));
+ addTest(TestPtr(new StringTest));
+ addTest(TestPtr(new SplineTest));
+ addTest(TestPtr(new BezierCurveTest));
+ addTest(TestPtr(new SignalTest));
+ addTest(TestPtr(new BacktraceTest));
+ addTest(TestPtr(new PolygonTest));
+ addTest(TestPtr(new XmlParserTest));
+ addTest(TestPtr(new StandardLoggerTest));
+ }
+};
+
+
+int main(int nargs, char** args)
+{
+ BaseTestSuite suite;
+ suite.runTests();
+ bool bOK = suite.isOk();
+
+ if (bOK) {
+ return 0;
+ } else {
+ return 1;
+ }
+}
+
diff --git a/src/base/triangulate/AdvancingFront.cpp b/src/base/triangulate/AdvancingFront.cpp
new file mode 100644
index 0000000..d14f1d3
--- /dev/null
+++ b/src/base/triangulate/AdvancingFront.cpp
@@ -0,0 +1,104 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+//
+// Based on Poly2Tri algorithm.
+// Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
+// http://code.google.com/p/poly2tri/
+//
+
+#include "AdvancingFront.h"
+
+namespace avg {
+
+AdvancingFront::AdvancingFront(Node& head, Node& tail)
+{
+ m_Head = &head;
+ m_Tail = &tail;
+ m_SearchNode = &head;
+}
+
+Node* AdvancingFront::locateNode(const double& x)
+{
+ Node* node = m_SearchNode;
+
+ if (x < node->m_Value) {
+ while ((node = node->m_Prev) != NULL) {
+ if (x >= node->m_Value) {
+ m_SearchNode = node;
+ return node;
+ }
+ }
+ } else {
+ while ((node = node->m_Next) != NULL) {
+ if (x < node->m_Value) {
+ m_SearchNode = node->m_Prev;
+ return node->m_Prev;
+ }
+ }
+ }
+ return NULL;
+}
+
+Node* AdvancingFront::findSearchNode(const double& x)
+{
+ // TO DO: implement BST index
+ return m_SearchNode;
+}
+
+Node* AdvancingFront::locatePoint(const Point* point)
+{
+ const double px = point->m_X;
+ Node* node = findSearchNode(px);
+ const double nx = node->m_Point->m_X;
+
+ if (px == nx) {
+ if (point != node->m_Point) {
+ // We might have two nodes with same x value for a short time
+ if (point == node->m_Prev->m_Point) {
+ node = node->m_Prev;
+ } else if (point == node->m_Next->m_Point) {
+ node = node->m_Next;
+ } else {
+ assert(0);
+ }
+ }
+ } else if (px < nx) {
+ while ((node = node->m_Prev) != NULL) {
+ if (point == node->m_Point) {
+ break;
+ }
+ }
+ } else {
+ while ((node = node->m_Next) != NULL) {
+ if (point == node->m_Point)
+ break;
+ }
+ }
+ if (node)
+ m_SearchNode = node;
+ return node;
+}
+
+AdvancingFront::~AdvancingFront() {}
+
+}
+
diff --git a/src/base/triangulate/AdvancingFront.h b/src/base/triangulate/AdvancingFront.h
new file mode 100644
index 0000000..3bb0d5b
--- /dev/null
+++ b/src/base/triangulate/AdvancingFront.h
@@ -0,0 +1,118 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+//
+// Based on Poly2Tri algorithm.
+// Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
+// http://code.google.com/p/poly2tri/
+//
+
+#ifndef ADVANCED_FRONT_H
+#define ADVANCED_FRONT_H
+
+#include "Shapes.h"
+
+namespace avg {
+
+struct Node;
+
+struct Node
+{
+ Point* m_Point;
+ TriangulationTriangle* m_Triangle;
+
+ Node* m_Next;
+ Node* m_Prev;
+
+ double m_Value;
+
+ Node() : m_Point(NULL), m_Triangle(NULL), m_Next(NULL), m_Prev(NULL), m_Value(0)
+ {}
+
+ Node(Point& p) : m_Point(&p), m_Triangle(NULL), m_Next(NULL), m_Prev(NULL), m_Value(p.m_X)
+ {}
+
+ Node(Point& p, TriangulationTriangle& t) : m_Point(&p), m_Triangle(&t), m_Next(NULL), m_Prev(NULL), m_Value(p.m_X)
+ {}
+
+};
+
+
+class AdvancingFront
+{
+
+public:
+
+AdvancingFront(Node& head, Node& tail);
+
+~AdvancingFront();
+
+Node* head();
+void setHead(Node* node);
+Node* tail();
+void setTail(Node* node);
+Node* search();
+void setSearch(Node* node);
+
+/// Locate insertion point along advancing front
+Node* locateNode(const double& x);
+
+Node* locatePoint(const Point* point);
+
+private:
+
+Node* m_Head, *m_Tail, *m_SearchNode;
+
+Node* findSearchNode(const double& x);
+};
+
+
+inline Node* AdvancingFront::head()
+{
+ return m_Head;
+}
+inline void AdvancingFront::setHead(Node* node)
+{
+ m_Head = node;
+}
+
+inline Node* AdvancingFront::tail()
+{
+ return m_Tail;
+}
+inline void AdvancingFront::setTail(Node* node)
+{
+ m_Tail = node;
+}
+
+inline Node* AdvancingFront::search()
+{
+ return m_SearchNode;
+}
+
+inline void AdvancingFront::setSearch(Node* node)
+{
+ m_SearchNode = node;
+}
+
+}
+
+#endif
diff --git a/src/base/triangulate/Makefile.am b/src/base/triangulate/Makefile.am
new file mode 100644
index 0000000..9381e58
--- /dev/null
+++ b/src/base/triangulate/Makefile.am
@@ -0,0 +1,8 @@
+AM_CPPFLAGS = -I.. @XML2_CFLAGS@ @PTHREAD_CFLAGS@
+ALL_H = Triangulate.h Shapes.h Utils.h \
+ AdvancingFront.h Sweep.h SweepContext.h
+
+noinst_LTLIBRARIES = libtriangulate.la
+libtriangulate_la_SOURCES = Triangulate.cpp Shapes.cpp \
+ AdvancingFront.cpp Sweep.cpp SweepContext.cpp \
+ $(ALL_H)
diff --git a/src/base/triangulate/Shapes.cpp b/src/base/triangulate/Shapes.cpp
new file mode 100644
index 0000000..08e2e13
--- /dev/null
+++ b/src/base/triangulate/Shapes.cpp
@@ -0,0 +1,353 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+//
+// Based on Poly2Tri algorithm.
+// Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
+// http://code.google.com/p/poly2tri/
+//
+
+#include "Shapes.h"
+#include <iostream>
+
+namespace avg {
+
+TriangulationTriangle::TriangulationTriangle(Point& a, Point& b, Point& c)
+{
+ m_Points[0] = &a;
+ m_Points[1] = &b;
+ m_Points[2] = &c;
+ m_Neighbors[0] = NULL;
+ m_Neighbors[1] = NULL;
+ m_Neighbors[2] = NULL;
+ m_ConstrainedEdge[0] = m_ConstrainedEdge[1] = m_ConstrainedEdge[2] = false;
+ m_DelaunayEdge[0] = m_DelaunayEdge[1] = m_DelaunayEdge[2] = false;
+ m_Interior = false;
+}
+
+// Update neighbor pointers
+void TriangulationTriangle::markNeighbor(Point* p1, Point* p2,
+ TriangulationTriangle* t)
+{
+ if ((p1 == m_Points[2] && p2 == m_Points[1])
+ || (p1 == m_Points[1] && p2 == m_Points[2])) {
+ m_Neighbors[0] = t;
+ } else if ((p1 == m_Points[0] && p2 == m_Points[2])
+ || (p1 == m_Points[2] && p2 == m_Points[0])) {
+ m_Neighbors[1] = t;
+ } else if ((p1 == m_Points[0] && p2 == m_Points[1])
+ || (p1 == m_Points[1] && p2 == m_Points[0])) {
+ m_Neighbors[2] = t;
+ } else {
+ assert(0);
+ }
+
+}
+
+// Exhaustive search to update neighbor pointers
+void TriangulationTriangle::markNeighbor(TriangulationTriangle& t)
+{
+ if (t.contains(m_Points[1], m_Points[2])) {
+ m_Neighbors[0] = &t;
+ t.markNeighbor(m_Points[1], m_Points[2], this);
+ } else if (t.contains(m_Points[0], m_Points[2])) {
+ m_Neighbors[1] = &t;
+ t.markNeighbor(m_Points[0], m_Points[2], this);
+ } else if (t.contains(m_Points[0], m_Points[1])) {
+ m_Neighbors[2] = &t;
+ t.markNeighbor(m_Points[0], m_Points[1], this);
+ }
+}
+
+void TriangulationTriangle::clear()
+{
+ TriangulationTriangle *t;
+ for (int i = 0; i < 3; i++) {
+ t = m_Neighbors[i];
+ if (t != NULL) {
+ t->clearNeighbor(this);
+ }
+ }
+ clearNeighbors();
+ m_Points[0] = m_Points[1] = m_Points[2] = NULL;
+}
+
+void TriangulationTriangle::clearNeighbor(TriangulationTriangle *triangle)
+{
+ if (m_Neighbors[0] == triangle) {
+ m_Neighbors[0] = NULL;
+ } else if (m_Neighbors[1] == triangle) {
+ m_Neighbors[1] = NULL;
+ } else {
+ m_Neighbors[2] = NULL;
+ }
+}
+
+void TriangulationTriangle::clearNeighbors()
+{
+ m_Neighbors[0] = NULL;
+ m_Neighbors[1] = NULL;
+ m_Neighbors[2] = NULL;
+}
+
+void TriangulationTriangle::clearDelunayEdges()
+{
+ m_DelaunayEdge[0] = m_DelaunayEdge[1] = m_DelaunayEdge[2] = false;
+}
+
+Point* TriangulationTriangle::oppositePoint(TriangulationTriangle& t,
+ Point& p) {
+ Point *cw = t.pointCW(p);
+ return pointCW(*cw);
+}
+
+// Legalized triangle by rotating clockwise around point(0)
+void TriangulationTriangle::legalize(Point& point)
+{
+ m_Points[1] = m_Points[0];
+ m_Points[0] = m_Points[2];
+ m_Points[2] = &point;
+}
+
+// Legalize triagnle by rotating clockwise around oPoint
+void TriangulationTriangle::legalize(Point& opoint, Point& npoint)
+{
+ if (&opoint == m_Points[0]) {
+ m_Points[1] = m_Points[0];
+ m_Points[0] = m_Points[2];
+ m_Points[2] = &npoint;
+ } else if (&opoint == m_Points[1]) {
+ m_Points[2] = m_Points[1];
+ m_Points[1] = m_Points[0];
+ m_Points[0] = &npoint;
+ } else if (&opoint == m_Points[2]) {
+ m_Points[0] = m_Points[2];
+ m_Points[2] = m_Points[1];
+ m_Points[1] = &npoint;
+ } else {
+ assert(0);
+ }
+}
+
+unsigned int TriangulationTriangle::index(const Point* p)
+{
+ if (p == m_Points[0]) {
+ return 0;
+ } else if (p == m_Points[1]) {
+ return 1;
+ } else if (p == m_Points[2]) {
+ return 2;
+ }
+ assert(0);
+ return 0;
+}
+
+unsigned int TriangulationTriangle::edgeIndex(const Point* p1, const Point* p2)
+{
+ if (m_Points[0] == p1) {
+ if (m_Points[1] == p2) {
+ return 2;
+ } else if (m_Points[2] == p2) {
+ return 1;
+ }
+ } else if (m_Points[1] == p1) {
+ if (m_Points[2] == p2) {
+ return 0;
+ } else if (m_Points[0] == p2) {
+ return 2;
+ }
+ } else if (m_Points[2] == p1) {
+ if (m_Points[0] == p2) {
+ return 1;
+ } else if (m_Points[1] == p2) {
+ return 0;
+ }
+ }
+ return -1;
+}
+
+void TriangulationTriangle::markConstrainedEdge(const int index)
+{
+ m_ConstrainedEdge[index] = true;
+}
+
+void TriangulationTriangle::markConstrainedEdge(Edge& edge)
+{
+ markConstrainedEdge(edge.m_P, edge.m_Q);
+}
+
+void TriangulationTriangle::markConstrainedEdge(Point* p, Point* q)
+{
+ if ((q == m_Points[0] && p == m_Points[1])
+ || (q == m_Points[1] && p == m_Points[0])) {
+ m_ConstrainedEdge[2] = true;
+ } else if ((q == m_Points[0] && p == m_Points[2])
+ || (q == m_Points[2] && p == m_Points[0])) {
+ m_ConstrainedEdge[1] = true;
+ } else if ((q == m_Points[1] && p == m_Points[2])
+ || (q == m_Points[2] && p == m_Points[1])) {
+ m_ConstrainedEdge[0] = true;
+ }
+}
+
+// The point counter-clockwise to given point
+Point* TriangulationTriangle::pointCW(Point& point)
+{
+ if (&point == m_Points[0]) {
+ return m_Points[2];
+ } else if (&point == m_Points[1]) {
+ return m_Points[0];
+ } else if (&point == m_Points[2]) {
+ return m_Points[1];
+ }
+ assert(0);
+ return 0; // Silence compiler warning
+}
+
+Point* TriangulationTriangle::pointCCW(Point& point)
+{
+ if (&point == m_Points[0]) {
+ return m_Points[1];
+ } else if (&point == m_Points[1]) {
+ return m_Points[2];
+ } else if (&point == m_Points[2]) {
+ return m_Points[0];
+ }
+ assert(0);
+ return 0; // Silence compiler warning
+}
+
+TriangulationTriangle* TriangulationTriangle::neighborCW(Point& point)
+{
+ if (&point == m_Points[0]) {
+ return m_Neighbors[1];
+ } else if (&point == m_Points[1]) {
+ return m_Neighbors[2];
+ }
+ return m_Neighbors[0];
+}
+
+TriangulationTriangle* TriangulationTriangle::neighborCCW(Point& point)
+{
+ if (&point == m_Points[0]) {
+ return m_Neighbors[2];
+ } else if (&point == m_Points[1]) {
+ return m_Neighbors[0];
+ }
+ return m_Neighbors[1];
+}
+
+bool TriangulationTriangle::getConstrainedEdgeCCW(Point& p)
+{
+ if (&p == m_Points[0]) {
+ return m_ConstrainedEdge[2];
+ } else if (&p == m_Points[1]) {
+ return m_ConstrainedEdge[0];
+ }
+ return m_ConstrainedEdge[1];
+}
+
+bool TriangulationTriangle::getConstrainedEdgeCW(Point& p)
+{
+ if (&p == m_Points[0]) {
+ return m_ConstrainedEdge[1];
+ } else if (&p == m_Points[1]) {
+ return m_ConstrainedEdge[2];
+ }
+ return m_ConstrainedEdge[0];
+}
+
+void TriangulationTriangle::setConstrainedEdgeCCW(Point& p, bool ce)
+{
+ if (&p == m_Points[0]) {
+ m_ConstrainedEdge[2] = ce;
+ } else if (&p == m_Points[1]) {
+ m_ConstrainedEdge[0] = ce;
+ } else {
+ m_ConstrainedEdge[1] = ce;
+ }
+}
+
+void TriangulationTriangle::setConstrainedEdgeCW(Point& p, bool ce)
+{
+ if (&p == m_Points[0]) {
+ m_ConstrainedEdge[1] = ce;
+ } else if (&p == m_Points[1]) {
+ m_ConstrainedEdge[2] = ce;
+ } else {
+ m_ConstrainedEdge[0] = ce;
+ }
+}
+
+bool TriangulationTriangle::getDelunayEdgeCCW(Point& p)
+{
+ if (&p == m_Points[0]) {
+ return m_DelaunayEdge[2];
+ } else if (&p == m_Points[1]) {
+ return m_DelaunayEdge[0];
+ }
+ return m_DelaunayEdge[1];
+}
+
+bool TriangulationTriangle::getDelunayEdgeCW(Point& p)
+{
+ if (&p == m_Points[0]) {
+ return m_DelaunayEdge[1];
+ } else if (&p == m_Points[1]) {
+ return m_DelaunayEdge[2];
+ }
+ return m_DelaunayEdge[0];
+}
+
+void TriangulationTriangle::setDelunayEdgeCCW(Point& p, bool e)
+{
+ if (&p == m_Points[0]) {
+ m_DelaunayEdge[2] = e;
+ } else if (&p == m_Points[1]) {
+ m_DelaunayEdge[0] = e;
+ } else {
+ m_DelaunayEdge[1] = e;
+ }
+}
+
+void TriangulationTriangle::setDelunayEdgeCW(Point& p, bool e)
+{
+ if (&p == m_Points[0]) {
+ m_DelaunayEdge[1] = e;
+ } else if (&p == m_Points[1]) {
+ m_DelaunayEdge[2] = e;
+ } else {
+ m_DelaunayEdge[0] = e;
+ }
+}
+
+TriangulationTriangle& TriangulationTriangle::neighborAcross(Point& opoint)
+{
+ if (&opoint == m_Points[0]) {
+ return *m_Neighbors[0];
+ } else if (&opoint == m_Points[1]) {
+ return *m_Neighbors[1];
+ }
+ return *m_Neighbors[2];
+}
+
+}
+
diff --git a/src/base/triangulate/Shapes.h b/src/base/triangulate/Shapes.h
new file mode 100644
index 0000000..0417d7c
--- /dev/null
+++ b/src/base/triangulate/Shapes.h
@@ -0,0 +1,296 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+//
+// Based on Poly2Tri algorithm.
+// Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
+// http://code.google.com/p/poly2tri/
+//
+
+#ifndef SHAPES_H
+#define SHAPES_H
+
+#include <vector>
+#include <cstddef>
+#include <assert.h>
+#include <cmath>
+
+namespace avg {
+
+struct Edge;
+
+struct Point
+{
+ double m_X, m_Y;
+ int m_Index;
+
+ /// The edges this point constitutes an upper ending point
+ std::vector<Edge*> m_EdgeList;
+
+ /// Default constructor does nothing (for performance).
+ Point() {
+ m_X = 0.0;
+ m_Y = 0.0;
+ m_Index = 0;
+ }
+
+ Point(double x, double y, int index) :
+ m_X(x), m_Y(y), m_Index(index) {}
+
+ void set_zero()
+ {
+ m_X = 0.0;
+ m_Y = 0.0;
+ }
+
+ void set(double x_, double y_)
+ {
+ m_X = x_;
+ m_Y = y_;
+ }
+
+ Point operator -() const
+ {
+ Point v;
+ v.set(-m_X, -m_Y);
+ return v;
+ }
+
+ void operator +=(const Point& v)
+ {
+ m_X += v.m_X;
+ m_Y += v.m_Y;
+ }
+
+ void operator -=(const Point& v)
+ {
+ m_X -= v.m_X;
+ m_Y -= v.m_Y;
+ }
+
+ void operator *=(double a)
+ {
+ m_X *= a;
+ m_Y *= a;
+ }
+
+ double length() const
+ {
+ return sqrt(m_X * m_X + m_Y * m_Y);
+ }
+
+ /// Convert this point into a unit point. Returns the Length.
+ double normalize()
+ {
+ double len = length();
+ m_X /= len;
+ m_Y /= len;
+ return len;
+ }
+
+};
+
+
+// Represents a simple polygon's edge
+struct Edge
+{
+ Point* m_P, *m_Q;
+
+ Edge(Point& p1, Point& p2) :m_P(&p1), m_Q(&p2)
+ {
+ if (p1.m_Y > p2.m_Y) {
+ m_Q = &p1;
+ m_P = &p2;
+ } else if (p1.m_Y == p2.m_Y) {
+ if (p1.m_X > p2.m_X) {
+ m_Q = &p1;
+ m_P = &p2;
+ } else if (p1.m_X == p2.m_X) {
+ // Repeat points
+ assert(false);
+ }
+ }
+ m_Q->m_EdgeList.push_back(this);
+ }
+};
+
+
+class TriangulationTriangle
+{
+
+public:
+
+ TriangulationTriangle(Point& a, Point& b, Point& c);
+
+/// Flags to determine if an edge is a Constrained edge
+ bool m_ConstrainedEdge[3];
+/// Flags to determine if an edge is a Delauney edge
+ bool m_DelaunayEdge[3];
+
+ Point* getPoint(const int& index);
+ Point* pointCW(Point& point);
+ Point* pointCCW(Point& point);
+ Point* oppositePoint(TriangulationTriangle& t, Point& p);
+
+ TriangulationTriangle* getNeighbor(const int& index);
+ void markNeighbor(Point* p1, Point* p2, TriangulationTriangle* t);
+ void markNeighbor(TriangulationTriangle& t);
+
+ void markConstrainedEdge(const int index);
+ void markConstrainedEdge(Edge& edge);
+ void markConstrainedEdge(Point* p, Point* q);
+
+ unsigned int index(const Point* p);
+ unsigned int edgeIndex(const Point* p1, const Point* p2);
+
+ TriangulationTriangle* neighborCW(Point& point);
+ TriangulationTriangle* neighborCCW(Point& point);
+ bool getConstrainedEdgeCCW(Point& p);
+ bool getConstrainedEdgeCW(Point& p);
+ void setConstrainedEdgeCCW(Point& p, bool ce);
+ void setConstrainedEdgeCW(Point& p, bool ce);
+ bool getDelunayEdgeCCW(Point& p);
+ bool getDelunayEdgeCW(Point& p);
+ void setDelunayEdgeCCW(Point& p, bool e);
+ void setDelunayEdgeCW(Point& p, bool e);
+
+ bool contains(Point* p);
+ bool contains(const Edge& e);
+ bool contains(Point* p, Point* q);
+ void legalize(Point& point);
+ void legalize(Point& opoint, Point& npoint);
+
+ void clear();
+ void clearNeighbor(TriangulationTriangle *triangle);
+ void clearNeighbors();
+ void clearDelunayEdges();
+
+ inline bool isInterior();
+ inline void isInterior(bool b);
+
+ TriangulationTriangle& neighborAcross(Point& opoint);
+
+private:
+
+ Point* m_Points[3];
+
+ TriangulationTriangle* m_Neighbors[3];
+
+ bool m_Interior;
+};
+
+inline bool cmp(const Point* a, const Point* b)
+{
+ if (a->m_Y < b->m_Y) {
+ return true;
+ } else if (a->m_Y == b->m_Y) {
+ // Make sure q is point with greater x value
+ if (a->m_X < b->m_X) {
+ return true;
+ }
+ }
+ return false;
+}
+/*
+ inline Point operator +(const Point& a, const Point& b)
+ {
+ return Point(a.x + b.x, a.y + b.y);
+ }
+
+ inline Point operator -(const Point& a, const Point& b)
+ {
+ return Point(a.x - b.x, a.y - b.y);
+ }
+
+ inline Point operator *(double s, const Point& a)
+ {
+ return Point(s * a.x, s * a.y, a.index);
+ } */
+
+inline bool operator ==(const Point& a, const Point& b)
+{
+ return a.m_X == b.m_X && a.m_Y == b.m_Y;
+}
+
+inline bool operator !=(const Point& a, const Point& b)
+{
+ return a.m_X != b.m_X && a.m_Y != b.m_Y;
+}
+
+inline double dot(const Point& a, const Point& b)
+{
+ return a.m_X * b.m_X + a.m_Y * b.m_Y;
+}
+
+inline double cross(const Point& a, const Point& b)
+{
+ return a.m_X * b.m_Y - a.m_Y * b.m_X;
+}
+
+inline Point cross(const Point& a, double s)
+{
+ return Point(s * a.m_Y, -s * a.m_X, a.m_Index);
+}
+
+inline Point cross(const double s, const Point& a)
+{
+ return Point(-s * a.m_Y, s * a.m_X, a.m_Index);
+}
+
+inline Point* TriangulationTriangle::getPoint(const int& index)
+{
+ return m_Points[index];
+}
+
+inline TriangulationTriangle* TriangulationTriangle::getNeighbor(
+ const int& index)
+{
+ return m_Neighbors[index];
+}
+
+inline bool TriangulationTriangle::contains(Point* p)
+{
+ return p == m_Points[0] || p == m_Points[1] || p == m_Points[2];
+}
+
+inline bool TriangulationTriangle::contains(const Edge& e)
+{
+ return contains(e.m_P) && contains(e.m_Q);
+}
+
+inline bool TriangulationTriangle::contains(Point* p, Point* q)
+{
+ return contains(p) && contains(q);
+}
+
+inline bool TriangulationTriangle::isInterior()
+{
+ return m_Interior;
+}
+
+inline void TriangulationTriangle::isInterior(bool b)
+{
+ m_Interior = b;
+}
+
+}
+
+#endif
diff --git a/src/base/triangulate/Sweep.cpp b/src/base/triangulate/Sweep.cpp
new file mode 100644
index 0000000..2655cb0
--- /dev/null
+++ b/src/base/triangulate/Sweep.cpp
@@ -0,0 +1,796 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+//
+// Based on Poly2Tri algorithm.
+// Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
+// http://code.google.com/p/poly2tri/
+//
+
+#include <stdexcept>
+#include "Sweep.h"
+#include "SweepContext.h"
+#include "AdvancingFront.h"
+#include "Utils.h"
+
+namespace avg {
+
+void Sweep::Triangulate(SweepContext& sc)
+{
+ arrayCount = 0;
+ for (unsigned int i = 0; i < (unsigned)sc.pointCount(); i++) {
+ m_Nodes.push_back(new Node());
+ }
+ sc.initTriangulation();
+ sc.createAdvancingFront();
+ // Sweep points; build mesh
+ sweepPoints(sc);
+ // Clean up
+ finalizationPolygon(sc);
+}
+
+void Sweep::sweepPoints(SweepContext& sc)
+{
+ for (int i = 1; i < sc.pointCount(); i++) {
+ Point& point = *sc.getPoint(i);
+ Node* node = &pointEvent(sc, point);
+ for (unsigned int i = 0; i < point.m_EdgeList.size(); i++) {
+ edgeEvent(sc, point.m_EdgeList[i], node);
+ }
+ }
+}
+
+void Sweep::finalizationPolygon(SweepContext& sc)
+{
+ // Get an Internal triangle to start with
+ TriangulationTriangle* t = sc.front()->head()->m_Next->m_Triangle;
+ Point* p = sc.front()->head()->m_Next->m_Point;
+ while (!t->getConstrainedEdgeCW(*p)) {
+ t = t->neighborCCW(*p);
+ }
+
+ // Collect interior triangles constrained by edges
+ sc.meshClean(*t);
+}
+
+Node& Sweep::pointEvent(SweepContext& sc, Point& point)
+{
+ Node& node = sc.locateNode(point);
+ Node& new_node = newFrontTriangle(sc, point, node);
+
+ // Only need to check +epsilon since point never have smaller
+ // x value than node due to how we fetch nodes from the front
+ if (point.m_X <= node.m_Point->m_X + EPSILON) {
+ fill(sc, node);
+ }
+
+ //tcx.AddNode(new_node);
+
+ fillAdvancingFront(sc, new_node);
+ return new_node;
+}
+
+void Sweep::edgeEvent(SweepContext& sc, Edge* edge, Node* node)
+{
+ sc.m_EdgeEvent.m_ConstrainedEdge = edge;
+ sc.m_EdgeEvent.m_Right = (edge->m_P->m_X > edge->m_Q->m_X);
+
+ if (isEdgeSideOfTriangle(*node->m_Triangle, *edge->m_P, *edge->m_Q)) {
+ return;
+ }
+
+ // to do: integrate with flip process might give some better performance
+ // but for now this avoid the issue with cases that needs both flips and fills
+ fillEdgeEvent(sc, edge, node);
+ edgeEvent(sc, *edge->m_P, *edge->m_Q, node->m_Triangle, *edge->m_Q);
+}
+
+void Sweep::edgeEvent(SweepContext& sc, Point& ep, Point& eq,
+ TriangulationTriangle* triangle, Point& point)
+{
+ if (isEdgeSideOfTriangle(*triangle, ep, eq)) {
+ return;
+ }
+
+ Point* p1 = triangle->pointCCW(point);
+ Orientation o1 = orient2d(eq, *p1, ep);
+ if (o1 == COLLINEAR) {
+ if (triangle->contains(&eq, p1)) {
+ triangle->markConstrainedEdge(&eq, p1);
+ // We are modifying the constraint maybe it would be better to
+ // not change the given constraint and just keep a variable for the new constraint
+ sc.m_EdgeEvent.m_ConstrainedEdge->m_Q = p1;
+ triangle = &triangle->neighborAcross(point);
+ edgeEvent(sc, ep, *p1, triangle, *p1);
+ } else {
+ std::runtime_error("EdgeEvent - collinear points not supported");
+ assert(0);
+ }
+ return;
+ }
+
+ Point* p2 = triangle->pointCW(point);
+ Orientation o2 = orient2d(eq, *p2, ep);
+ if (o2 == COLLINEAR) {
+ if (triangle->contains(&eq, p2)) {
+ triangle->markConstrainedEdge(&eq, p2);
+ // We are modifying the constraint maybe it would be better to
+ // not change the given constraint and just keep a variable for the new constraint
+ sc.m_EdgeEvent.m_ConstrainedEdge->m_Q = p2;
+ triangle = &triangle->neighborAcross(point);
+ edgeEvent(sc, ep, *p2, triangle, *p2);
+ } else {
+ std::runtime_error("EdgeEvent - collinear points not supported");
+ assert(0);
+ }
+ return;
+ }
+
+ if (o1 == o2) {
+ // Need to decide if we are rotating CW or CCW to get to a triangle
+ // that will cross edge
+ if (o1 == CW) {
+ triangle = triangle->neighborCCW(point);
+ } else {
+ triangle = triangle->neighborCW(point);
+ }
+ edgeEvent(sc, ep, eq, triangle, point);
+ } else {
+ // This triangle crosses constraint so lets flippin start!
+ flipEdgeEvent(sc, ep, eq, triangle, point);
+ }
+}
+
+bool Sweep::isEdgeSideOfTriangle(TriangulationTriangle& triangle, Point& ep,
+ Point& eq)
+{
+ int index = triangle.edgeIndex(&ep, &eq);
+
+ if (index != -1) {
+ triangle.markConstrainedEdge(index);
+ TriangulationTriangle* t = triangle.getNeighbor(index);
+ if (t) {
+ t->markConstrainedEdge(&ep, &eq);
+ }
+ return true;
+ }
+ return false;
+}
+
+Node& Sweep::newFrontTriangle(SweepContext& sc, Point& point, Node& node)
+{
+ TriangulationTriangle* triangle = new TriangulationTriangle(point,
+ *node.m_Point, *node.m_Next->m_Point);
+
+ triangle->markNeighbor(*node.m_Triangle);
+ sc.addToMap(triangle);
+
+ Node* newNode = m_Nodes[arrayCount++]; //new Node(point);
+ newNode->m_Point = &point;
+ newNode->m_Value = point.m_X;
+// m_Nodes.push_back(newNode);
+
+ newNode->m_Next = node.m_Next;
+ newNode->m_Prev = &node;
+ node.m_Next->m_Prev = newNode;
+ node.m_Next = newNode;
+
+ if (!legalize(sc, *triangle)) {
+ sc.mapTriangleToNodes(*triangle);
+ }
+
+ return *newNode;
+}
+
+void Sweep::fill(SweepContext& sc, Node& node)
+{
+ TriangulationTriangle* triangle = new TriangulationTriangle(
+ *node.m_Prev->m_Point, *node.m_Point, *node.m_Next->m_Point);
+
+ // TO DO: should copy the constrained_edge value from neighbor triangles
+ // for now constrained_edge values are copied during the legalize
+ triangle->markNeighbor(*node.m_Prev->m_Triangle);
+ triangle->markNeighbor(*node.m_Triangle);
+
+ sc.addToMap(triangle);
+
+ // Update the advancing front
+ node.m_Prev->m_Next = node.m_Next;
+ node.m_Next->m_Prev = node.m_Prev;
+
+ // If it was legalized the triangle has already been mapped
+ if (!legalize(sc, *triangle)) {
+ sc.mapTriangleToNodes(*triangle);
+ }
+
+}
+
+void Sweep::fillAdvancingFront(SweepContext& sc, Node& n)
+{
+ Node* node = n.m_Next;
+
+ while (node->m_Next) {
+ double angle = holeAngle(*node);
+ if (angle > M_PI_2 || angle < -M_PI_2)
+ break;
+// ---------- LEAK FIX --------------
+// Fill(tcx, *node);
+// node = node->m_next;
+
+
+ Node *tmp = node;
+ node = node->m_Next;
+ fill(sc, *tmp);
+// ----------------------------------
+ }
+
+ node = n.m_Prev;
+
+ while (node->m_Prev) {
+ double angle = holeAngle(*node);
+ if (angle > M_PI_2 || angle < -M_PI_2)
+ break;
+ fill(sc, *node);
+ node = node->m_Prev;
+ }
+
+ if (n.m_Next && n.m_Next->m_Next) {
+ double angle = basinAngle(n);
+ if (angle < PI_3div4) {
+ fillBasin(sc, n);
+ }
+ }
+}
+
+double Sweep::basinAngle(Node& node)
+{
+ double ax = node.m_Point->m_X - node.m_Next->m_Next->m_Point->m_X;
+ double ay = node.m_Point->m_Y - node.m_Next->m_Next->m_Point->m_Y;
+ return atan2(ay, ax);
+}
+
+double Sweep::holeAngle(Node& node)
+{
+ /* Complex plane
+ * ab = cosA +i*sinA
+ * ab = (ax + ay*i)(bx + by*i) = (ax*bx + ay*by) + i(ax*by-ay*bx)
+ * atan2(y,x) computes the principal value of the argument function
+ * applied to the complex number x+iy
+ * Where x = ax*bx + ay*by
+ * y = ax*by - ay*bx
+ */
+ double ax = node.m_Next->m_Point->m_X - node.m_Point->m_X;
+ double ay = node.m_Next->m_Point->m_Y - node.m_Point->m_Y;
+ double bx = node.m_Prev->m_Point->m_X - node.m_Point->m_X;
+ double by = node.m_Prev->m_Point->m_Y - node.m_Point->m_Y;
+ return atan2(ax * by - ay * bx, ax * bx + ay * by);
+}
+
+bool Sweep::legalize(SweepContext& sc, TriangulationTriangle& t)
+{
+ // To legalize a triangle we start by finding if any of the three edges
+ // violate the Delaunay condition
+ for (int i = 0; i < 3; i++) {
+ if (t.m_DelaunayEdge[i])
+ continue;
+
+ TriangulationTriangle* ot = t.getNeighbor(i);
+
+ if (ot) {
+ Point* p = t.getPoint(i);
+ Point* op = ot->oppositePoint(t, *p);
+ int oi = ot->index(op);
+
+ // If this is a Constrained Edge or a Delaunay Edge(only during recursive legalization)
+ // then we should not try to legalize
+ if (ot->m_ConstrainedEdge[oi] || ot->m_DelaunayEdge[oi]) {
+ t.m_ConstrainedEdge[i] = ot->m_ConstrainedEdge[oi];
+ continue;
+ }
+
+ bool inside = incircle(*p, *t.pointCCW(*p), *t.pointCW(*p), *op);
+
+ if (inside) {
+ // Lets mark this shared edge as Delaunay
+ t.m_DelaunayEdge[i] = true;
+ ot->m_DelaunayEdge[oi] = true;
+
+ // Lets rotate shared edge one vertex CW to legalize it
+ rotateTrianglePair(t, *p, *ot, *op);
+
+ // We now got one valid Delaunay Edge shared by two triangles
+ // This gives us 4 new edges to check for Delaunay
+
+ // Make sure that triangle to node mapping is done only one time for a specific triangle
+ bool notLegalized = !legalize(sc, t);
+ if (notLegalized) {
+ sc.mapTriangleToNodes(t);
+ }
+
+ notLegalized = !legalize(sc, *ot);
+ if (notLegalized)
+ sc.mapTriangleToNodes(*ot);
+
+ // Reset the Delaunay edges, since they only are valid Delaunay edges
+ // until we add a new triangle or point.
+ // XX X: need to think about this. Can these edges be tried after we
+ // return to previous recursive level?
+ t.m_DelaunayEdge[i] = false;
+ ot->m_DelaunayEdge[oi] = false;
+
+ // If triangle have been legalized no need to check the other edges since
+ // the recursive legalization will handles those so we can end here.
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+bool Sweep::incircle(Point& pa, Point& pb, Point& pc, Point& pd)
+{
+ double adx = pa.m_X - pd.m_X;
+ double ady = pa.m_Y - pd.m_Y;
+ double bdx = pb.m_X - pd.m_X;
+ double bdy = pb.m_Y - pd.m_Y;
+
+ double adxbdy = adx * bdy;
+ double bdxady = bdx * ady;
+ double oabd = adxbdy - bdxady;
+
+ if (oabd <= 0) {
+ return false;
+ }
+
+ double cdx = pc.m_X - pd.m_X;
+ double cdy = pc.m_Y - pd.m_Y;
+
+ double cdxady = cdx * ady;
+ double adxcdy = adx * cdy;
+ double ocad = cdxady - adxcdy;
+
+ if (ocad <= 0) {
+ return false;
+ }
+
+ double bdxcdy = bdx * cdy;
+ double cdxbdy = cdx * bdy;
+
+ double alift = adx * adx + ady * ady;
+ double blift = bdx * bdx + bdy * bdy;
+ double clift = cdx * cdx + cdy * cdy;
+
+ double det = alift * (bdxcdy - cdxbdy) + blift * ocad + clift * oabd;
+
+ return det > 0;
+}
+
+void Sweep::rotateTrianglePair(TriangulationTriangle& t, Point& p,
+ TriangulationTriangle& ot, Point& op)
+{
+ TriangulationTriangle* n1, *n2, *n3, *n4;
+ n1 = t.neighborCCW(p);
+ n2 = t.neighborCW(p);
+ n3 = ot.neighborCCW(op);
+ n4 = ot.neighborCW(op);
+
+ bool ce1, ce2, ce3, ce4;
+ ce1 = t.getConstrainedEdgeCCW(p);
+ ce2 = t.getConstrainedEdgeCW(p);
+ ce3 = ot.getConstrainedEdgeCCW(op);
+ ce4 = ot.getConstrainedEdgeCW(op);
+
+ bool de1, de2, de3, de4;
+ de1 = t.getDelunayEdgeCCW(p);
+ de2 = t.getDelunayEdgeCW(p);
+ de3 = ot.getDelunayEdgeCCW(op);
+ de4 = ot.getDelunayEdgeCW(op);
+
+ t.legalize(p, op);
+ ot.legalize(op, p);
+
+ // Remap delaunay_edge
+ ot.setDelunayEdgeCCW(p, de1);
+ t.setDelunayEdgeCW(p, de2);
+ t.setDelunayEdgeCCW(op, de3);
+ ot.setDelunayEdgeCW(op, de4);
+
+ // Remap constrained_edge
+ ot.setConstrainedEdgeCCW(p, ce1);
+ t.setConstrainedEdgeCW(p, ce2);
+ t.setConstrainedEdgeCCW(op, ce3);
+ ot.setConstrainedEdgeCW(op, ce4);
+
+ // Remap neighbors
+ // XX X: might optimize the markNeighbor by keeping track of
+ // what side should be assigned to what neighbor after the
+ // rotation. Now mark neighbor does lots of testing to find
+ // the right side.
+ t.clearNeighbors();
+ ot.clearNeighbors();
+ if (n1) {
+ ot.markNeighbor(*n1);
+ }
+ if (n2) {
+ t.markNeighbor(*n2);
+ }
+ if (n3) {
+ t.markNeighbor(*n3);
+ }
+ if (n4) {
+ ot.markNeighbor(*n4);
+ }
+ t.markNeighbor(ot);
+}
+
+void Sweep::fillBasin(SweepContext& sc, Node& node)
+{
+ if (orient2d(*node.m_Point, *node.m_Next->m_Point, *node.m_Next->m_Next->m_Point)
+ == CCW) {
+ sc.m_Basin.m_LeftNode = node.m_Next->m_Next;
+ } else {
+ sc.m_Basin.m_LeftNode = node.m_Next;
+ }
+
+ // Find the bottom and right node
+ sc.m_Basin.m_BottomNode = sc.m_Basin.m_LeftNode;
+ while (sc.m_Basin.m_BottomNode->m_Next
+ && sc.m_Basin.m_BottomNode->m_Point->m_Y
+ >= sc.m_Basin.m_BottomNode->m_Next->m_Point->m_Y) {
+ sc.m_Basin.m_BottomNode = sc.m_Basin.m_BottomNode->m_Next;
+ }
+ if (sc.m_Basin.m_BottomNode == sc.m_Basin.m_LeftNode) {
+ // No valid basin
+ return;
+ }
+
+ sc.m_Basin.m_RightNode = sc.m_Basin.m_BottomNode;
+ while (sc.m_Basin.m_RightNode->m_Next
+ && sc.m_Basin.m_RightNode->m_Point->m_Y
+ < sc.m_Basin.m_RightNode->m_Next->m_Point->m_Y) {
+ sc.m_Basin.m_RightNode = sc.m_Basin.m_RightNode->m_Next;
+ }
+ if (sc.m_Basin.m_RightNode == sc.m_Basin.m_BottomNode) {
+ // No valid basins
+ return;
+ }
+
+ sc.m_Basin.m_Width = sc.m_Basin.m_RightNode->m_Point->m_X
+ - sc.m_Basin.m_LeftNode->m_Point->m_X;
+ sc.m_Basin.m_LeftHighest = sc.m_Basin.m_LeftNode->m_Point->m_Y
+ > sc.m_Basin.m_RightNode->m_Point->m_Y;
+
+ fillBasinReq(sc, sc.m_Basin.m_BottomNode);
+}
+
+void Sweep::fillBasinReq(SweepContext& sc, Node* node)
+{
+ // if shallow stop filling
+ if (isShallow(sc, *node)) {
+ return;
+ }
+
+ fill(sc, *node);
+
+ if (node->m_Prev == sc.m_Basin.m_LeftNode
+ && node->m_Next == sc.m_Basin.m_RightNode) {
+ return;
+ } else if (node->m_Prev == sc.m_Basin.m_LeftNode) {
+ Orientation o = orient2d(*node->m_Point, *node->m_Next->m_Point,
+ *node->m_Next->m_Next->m_Point);
+ if (o == CW) {
+ return;
+ }
+ node = node->m_Next;
+ } else if (node->m_Next == sc.m_Basin.m_RightNode) {
+ Orientation o = orient2d(*node->m_Point, *node->m_Prev->m_Point,
+ *node->m_Prev->m_Prev->m_Point);
+ if (o == CCW) {
+ return;
+ }
+ node = node->m_Prev;
+ } else {
+ // Continue with the neighbor node with lowest Y value
+ if (node->m_Prev->m_Point->m_Y < node->m_Next->m_Point->m_Y) {
+ node = node->m_Prev;
+ } else {
+ node = node->m_Next;
+ }
+ }
+
+ fillBasinReq(sc, node);
+}
+
+bool Sweep::isShallow(SweepContext& sc, Node& node)
+{
+ double height;
+
+ if (sc.m_Basin.m_LeftHighest) {
+ height = sc.m_Basin.m_LeftNode->m_Point->m_Y - node.m_Point->m_Y;
+ } else {
+ height = sc.m_Basin.m_RightNode->m_Point->m_Y - node.m_Point->m_Y;
+ }
+
+ // if shallow stop filling
+ if (sc.m_Basin.m_Width > height) {
+ return true;
+ }
+ return false;
+}
+
+void Sweep::fillEdgeEvent(SweepContext& sc, Edge* edge, Node* node)
+{
+ if (sc.m_EdgeEvent.m_Right) {
+ fillRightAboveEdgeEvent(sc, edge, node);
+ } else {
+ fillLeftAboveEdgeEvent(sc, edge, node);
+ }
+}
+
+void Sweep::fillRightAboveEdgeEvent(SweepContext& sc, Edge* edge, Node* node)
+{
+ while (node->m_Next->m_Point->m_X < edge->m_P->m_X) {
+ // Check if next node is below the edge
+ if (orient2d(*edge->m_Q, *node->m_Next->m_Point, *edge->m_P) == CCW) {
+ fillRightBelowEdgeEvent(sc, edge, *node);
+ } else {
+ node = node->m_Next;
+ }
+ }
+}
+
+void Sweep::fillRightBelowEdgeEvent(SweepContext& sc, Edge* edge, Node& node)
+{
+ if (node.m_Point->m_X < edge->m_P->m_X) {
+ if (orient2d(*node.m_Point, *node.m_Next->m_Point, *node.m_Next->m_Next->m_Point)
+ == CCW) {
+ // Concave
+ fillRightConcaveEdgeEvent(sc, edge, node);
+ } else {
+ // Convex
+ fillRightConvexEdgeEvent(sc, edge, node);
+ // Retry this one
+ fillRightBelowEdgeEvent(sc, edge, node);
+ }
+ }
+}
+
+void Sweep::fillRightConcaveEdgeEvent(SweepContext& sc, Edge* edge, Node& node)
+{
+ fill(sc, *node.m_Next);
+ if (node.m_Next->m_Point != edge->m_P) {
+ // Next above or below edge?
+ if (orient2d(*edge->m_Q, *node.m_Next->m_Point, *edge->m_P) == CCW) {
+ // Below
+ if (orient2d(*node.m_Point, *node.m_Next->m_Point,
+ *node.m_Next->m_Next->m_Point) == CCW) {
+ // Next is concave
+ fillRightConcaveEdgeEvent(sc, edge, node);
+ } else {
+ // Next is convex
+ }
+ }
+ }
+
+}
+
+void Sweep::fillRightConvexEdgeEvent(SweepContext& sc, Edge* edge, Node& node)
+{
+ // Next concave or convex?
+ if (orient2d(*node.m_Next->m_Point, *node.m_Next->m_Next->m_Point,
+ *node.m_Next->m_Next->m_Next->m_Point) == CCW) {
+ // Concave
+ fillRightConcaveEdgeEvent(sc, edge, *node.m_Next);
+ } else {
+ // Convex
+ // Next above or below edge?
+ if (orient2d(*edge->m_Q, *node.m_Next->m_Next->m_Point, *edge->m_P) == CCW) {
+ // Below
+ fillRightConvexEdgeEvent(sc, edge, *node.m_Next);
+ } else {
+ // Above
+ }
+ }
+}
+
+void Sweep::fillLeftAboveEdgeEvent(SweepContext& sc, Edge* edge, Node* node)
+{
+ while (node->m_Prev->m_Point->m_X > edge->m_P->m_X) {
+ // Check if next node is below the edge
+ if (orient2d(*edge->m_Q, *node->m_Prev->m_Point, *edge->m_P) == CW) {
+ fillLeftBelowEdgeEvent(sc, edge, *node);
+ } else {
+ node = node->m_Prev;
+ }
+ }
+}
+
+void Sweep::fillLeftBelowEdgeEvent(SweepContext& sc, Edge* edge, Node& node)
+{
+ if (node.m_Point->m_X > edge->m_P->m_X) {
+ if (orient2d(*node.m_Point, *node.m_Prev->m_Point, *node.m_Prev->m_Prev->m_Point)
+ == CW) {
+ // Concave
+ fillLeftConcaveEdgeEvent(sc, edge, node);
+ } else {
+ // Convex
+ fillLeftConvexEdgeEvent(sc, edge, node);
+ // Retry this one
+ fillLeftBelowEdgeEvent(sc, edge, node);
+ }
+ }
+}
+
+void Sweep::fillLeftConvexEdgeEvent(SweepContext& sc, Edge* edge, Node& node)
+{
+ // Next concave or convex?
+ if (orient2d(*node.m_Prev->m_Point, *node.m_Prev->m_Prev->m_Point,
+ *node.m_Prev->m_Prev->m_Prev->m_Point) == CW) {
+ // Concave
+ fillLeftConcaveEdgeEvent(sc, edge, *node.m_Prev);
+ } else {
+ // Convex
+ // Next above or below edge?
+ if (orient2d(*edge->m_Q, *node.m_Prev->m_Prev->m_Point, *edge->m_P) == CW) {
+ // Below
+ fillLeftConvexEdgeEvent(sc, edge, *node.m_Prev);
+ } else {
+ // Above
+ }
+ }
+}
+
+void Sweep::fillLeftConcaveEdgeEvent(SweepContext& sc, Edge* edge, Node& node)
+{
+ fill(sc, *node.m_Prev);
+ if (node.m_Prev->m_Point != edge->m_P) {
+ // Next above or below edge?
+ if (orient2d(*edge->m_Q, *node.m_Prev->m_Point, *edge->m_P) == CW) {
+ // Below
+ if (orient2d(*node.m_Point, *node.m_Prev->m_Point,
+ *node.m_Prev->m_Prev->m_Point) == CW) {
+ // Next is concave
+ fillLeftConcaveEdgeEvent(sc, edge, node);
+ } else {
+ // Next is convex
+ }
+ }
+ }
+
+}
+
+void Sweep::flipEdgeEvent(SweepContext& sc, Point& ep, Point& eq,
+ TriangulationTriangle* t, Point& p)
+{
+ TriangulationTriangle& ot = t->neighborAcross(p);
+ Point& op = *ot.oppositePoint(*t, p);
+
+ if (&ot == NULL) {
+ // If we want to integrate the fillEdgeEvent do it here
+ // With current implementation we should never get here
+ //throw new RuntimeException( "[BUG:FIXM E] FLIP failed due to missing triangle");
+ assert(0);
+ }
+
+ if (inScanArea(p, *t->pointCCW(p), *t->pointCW(p), op)) {
+ // Lets rotate shared edge one vertex CW
+ rotateTrianglePair(*t, p, ot, op);
+ sc.mapTriangleToNodes(*t);
+ sc.mapTriangleToNodes(ot);
+
+ if (p == eq && op == ep) {
+ if (eq == *sc.m_EdgeEvent.m_ConstrainedEdge->m_Q
+ && ep == *sc.m_EdgeEvent.m_ConstrainedEdge->m_P) {
+ t->markConstrainedEdge(&ep, &eq);
+ ot.markConstrainedEdge(&ep, &eq);
+ legalize(sc, *t);
+ legalize(sc, ot);
+ } else {
+ // One of the triangles should be legalized here?
+ }
+ } else {
+ Orientation o = orient2d(eq, op, ep);
+ t = &nextFlipTriangle(sc, (int) o, *t, ot, p, op);
+ flipEdgeEvent(sc, ep, eq, t, p);
+ }
+ } else {
+ Point& newP = nextFlipPoint(ep, eq, ot, op);
+ flipScanEdgeEvent(sc, ep, eq, *t, ot, newP);
+ edgeEvent(sc, ep, eq, t, p);
+ }
+}
+
+TriangulationTriangle& Sweep::nextFlipTriangle(SweepContext& sc, int o,
+ TriangulationTriangle& t, TriangulationTriangle& ot, Point& p, Point& op)
+{
+ if (o == CCW) {
+ // ot is not crossing edge after flip
+ int edgeIndex = ot.edgeIndex(&p, &op);
+ ot.m_DelaunayEdge[edgeIndex] = true;
+ legalize(sc, ot);
+ ot.clearDelunayEdges();
+ return t;
+ }
+
+ // t is not crossing edge after flip
+ int edgeIndex = t.edgeIndex(&p, &op);
+
+ t.m_DelaunayEdge[edgeIndex] = true;
+ legalize(sc, t);
+ t.clearDelunayEdges();
+ return ot;
+}
+
+Point& Sweep::nextFlipPoint(Point& ep, Point& eq, TriangulationTriangle& ot, Point& op)
+{
+ Orientation o2d = orient2d(eq, op, ep);
+ if (o2d == CW) {
+ // Right
+ return *ot.pointCCW(op);
+ } else if (o2d == CCW) {
+ // Left
+ return *ot.pointCW(op);
+ } else {
+ //throw new RuntimeException("[Unsupported] Opposing point on constrained edge");
+ assert(0);
+ return ep; // Silence compiler warning.
+ }
+}
+
+void Sweep::flipScanEdgeEvent(SweepContext& sc, Point& ep, Point& eq,
+ TriangulationTriangle& flipTriangle, TriangulationTriangle& t, Point& p)
+{
+ TriangulationTriangle& ot = t.neighborAcross(p);
+ Point& op = *ot.oppositePoint(t, p);
+
+ if (&t.neighborAcross(p) == NULL) {
+ // If we want to integrate the fillEdgeEvent do it here
+ // With current implementation we should never get here
+ //throw new RuntimeException( "[BUG:FIXM E] FLIP failed due to missing triangle");
+ assert(0);
+ }
+
+ if (inScanArea(eq, *flipTriangle.pointCCW(eq), *flipTriangle.pointCW(eq),
+ op)) {
+ // flip with new edge op->eq
+ flipEdgeEvent(sc, eq, op, &ot, op);
+ // To do: Actually I just figured out that it should be possible to
+ // improve this by getting the next ot and op before the the above
+ // flip and continue the flipScanEdgeEvent here
+ // set new ot and op here and loop back to inScanArea test
+ // also need to set a new flip_triangle first
+ // Turns out at first glance that this is somewhat complicated
+ // so it will have to wait.
+ } else {
+ Point& newP = nextFlipPoint(ep, eq, ot, op);
+ flipScanEdgeEvent(sc, ep, eq, flipTriangle, ot, newP);
+ }
+}
+
+Sweep::~Sweep()
+{
+ for (unsigned int i = 0; i < m_Nodes.size(); i++) {
+ delete m_Nodes[i];
+ }
+
+}
+
+}
diff --git a/src/base/triangulate/Sweep.h b/src/base/triangulate/Sweep.h
new file mode 100644
index 0000000..48cd13a
--- /dev/null
+++ b/src/base/triangulate/Sweep.h
@@ -0,0 +1,201 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+//
+// Based on Poly2Tri algorithm.
+// Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
+// http://code.google.com/p/poly2tri/
+//
+
+#ifndef SWEEP_H
+#define SWEEP_H
+
+#include <vector>
+
+namespace avg {
+
+class SweepContext;
+struct Node;
+struct Point;
+struct Edge;
+class TriangulationTriangle;
+
+class Sweep
+{
+
+public:
+
+ void Triangulate(SweepContext& sc);
+
+ ~Sweep();
+
+private:
+
+ void sweepPoints(SweepContext& sc);
+
+ Node& pointEvent(SweepContext& sc, Point& point);
+
+ void edgeEvent(SweepContext& sc, Edge* edge, Node* node);
+
+ void edgeEvent(SweepContext& sc, Point& ep, Point& eq,
+ TriangulationTriangle* triangle, Point& point);
+
+ Node& newFrontTriangle(SweepContext& sc, Point& point, Node& node);
+
+ void fill(SweepContext& sc, Node& node);
+
+ bool legalize(SweepContext& sc, TriangulationTriangle& t);
+
+ /**
+ * <b>Requirement</b>:<br>
+ * 1. a,b and c form a triangle.<br>
+ * 2. a and d is know to be on opposite side of bc<br>
+ * <pre>
+ * a
+ * +
+ * / \
+ * / \
+ * b/ \c
+ * +-------+
+ * / d \
+ * / \
+ * </pre>
+ * <b>Fact</b>: d has to be in area B to have a chance to be inside the circle formed by
+ * a,b and c<br>
+ * d is outside B if orient2d(a,b,d) or orient2d(c,a,d) is CW<br>
+ * This preknowledge gives us a way to optimize the incircle test
+ * @param a - triangle point, opposite d
+ * @param b - triangle point
+ * @param c - triangle point
+ * @param d - point opposite a
+ * @return true if d is inside circle, false if on circle edge
+ */
+ bool incircle(Point& pa, Point& pb, Point& pc, Point& pd);
+
+ /**
+ * Rotates a triangle pair one vertex CW
+ *<pre>
+ * n2 n2
+ * P +-----+ P +-----+
+ * | t /| |\ t |
+ * | / | | \ |
+ * n1| / |n3 n1| \ |n3
+ * | / | after CW | \ |
+ * |/ oT | | oT \|
+ * +-----+ oP +-----+
+ * n4 n4
+ * </pre>
+ */
+ void rotateTrianglePair(TriangulationTriangle& t, Point& p, TriangulationTriangle& ot,
+ Point& op);
+
+ void fillAdvancingFront(SweepContext& sc, Node& n);
+
+ double holeAngle(Node& node);
+
+ /**
+ * The basin angle is decided against the horizontal line [1,0]
+ */
+ double basinAngle(Node& node);
+
+ void fillBasin(SweepContext& sc, Node& node);
+
+ void fillBasinReq(SweepContext& sc, Node* node);
+
+ bool isShallow(SweepContext& sc, Node& node);
+
+ bool isEdgeSideOfTriangle(TriangulationTriangle& triangle, Point& ep, Point& eq);
+
+ void fillEdgeEvent(SweepContext& sc, Edge* edge, Node* node);
+
+ void fillRightAboveEdgeEvent(SweepContext& sc, Edge* edge, Node* node);
+
+ void fillRightBelowEdgeEvent(SweepContext& sc, Edge* edge, Node& node);
+
+ void fillRightConcaveEdgeEvent(SweepContext& sc, Edge* edge, Node& node);
+
+ void fillRightConvexEdgeEvent(SweepContext& sc, Edge* edge, Node& node);
+
+ void fillLeftAboveEdgeEvent(SweepContext& sc, Edge* edge, Node* node);
+
+ void fillLeftBelowEdgeEvent(SweepContext& sc, Edge* edge, Node& node);
+
+ void fillLeftConcaveEdgeEvent(SweepContext& sc, Edge* edge, Node& node);
+
+ void fillLeftConvexEdgeEvent(SweepContext& sc, Edge* edge, Node& node);
+
+ void flipEdgeEvent(SweepContext& sc, Point& ep, Point& eq, TriangulationTriangle* t,
+ Point& p);
+
+ /**
+ * After a flip we have two triangles and know that only one will still be
+ * intersecting the edge. So decide which to contiune with and legalize the other
+ *
+ * @param sc
+ * @param o - should be the result of an orient2d( eq, op, ep )
+ * @param t - triangle 1
+ * @param ot - triangle 2
+ * @param p - a point shared by both triangles
+ * @param op - another point shared by both triangles
+ * @return returns the triangle still intersecting the edge
+ */
+ TriangulationTriangle& nextFlipTriangle(SweepContext& sc, int o,
+ TriangulationTriangle& t, TriangulationTriangle& ot, Point& p, Point& op);
+
+ /**
+ * When we need to traverse from one triangle to the next we need
+ * the point in current triangle that is the opposite point to the next
+ * triangle.
+ *
+ * @param ep
+ * @param eq
+ * @param ot
+ * @param op
+ * @return
+ */
+ Point& nextFlipPoint(Point& ep, Point& eq, TriangulationTriangle& ot, Point& op);
+
+ /**
+ * Scan part of the FlipScan algorithm<br>
+ * When a triangle pair isn't flippable we will scan for the next
+ * point that is inside the flip triangle scan area. When found
+ * we generate a new flipEdgeEvent
+ *
+ * @param sc
+ * @param ep - last point on the edge we are traversing
+ * @param eq - first point on the edge we are traversing
+ * @param flipTriangle - the current triangle sharing the point eq with edge
+ * @param t
+ * @param p
+ */
+ void flipScanEdgeEvent(SweepContext& sc, Point& ep, Point& eq,
+ TriangulationTriangle& flip_triangle, TriangulationTriangle& t, Point& p);
+
+ void finalizationPolygon(SweepContext& sc);
+
+ std::vector<Node*> m_Nodes;
+ unsigned int arrayCount;
+
+};
+
+}
+
+#endif
diff --git a/src/base/triangulate/SweepContext.cpp b/src/base/triangulate/SweepContext.cpp
new file mode 100644
index 0000000..16e642e
--- /dev/null
+++ b/src/base/triangulate/SweepContext.cpp
@@ -0,0 +1,196 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+//
+// Based on Poly2Tri algorithm.
+// Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
+// http://code.google.com/p/poly2tri/
+//
+
+#include "SweepContext.h"
+#include <algorithm>
+#include "AdvancingFront.h"
+
+namespace avg {
+
+SweepContext::SweepContext(std::vector<Point*> polyline)
+{
+ m_Basin = Basin();
+ m_EdgeEvent = EdgeEvent();
+
+ m_Points = polyline;
+
+ initEdges(m_Points);
+}
+
+void SweepContext::addHole(std::vector<Point*> polyline)
+{
+ initEdges(polyline);
+ for (unsigned int i = 0; i < polyline.size(); i++) {
+ m_Points.push_back(polyline[i]);
+ }
+}
+
+void SweepContext::addPoint(Point* point)
+{
+ m_Points.push_back(point);
+}
+
+std::vector<TriangulationTriangle*>& SweepContext::getTriangles()
+{
+ return m_Triangles;
+}
+
+void SweepContext::initTriangulation()
+{
+ double xmax(m_Points[0]->m_X), xmin(m_Points[0]->m_X);
+ double ymax(m_Points[0]->m_Y), ymin(m_Points[0]->m_Y);
+
+ // Calculate bounds.
+ for (unsigned int i = 0; i < m_Points.size(); i++) {
+ Point& p = *m_Points[i];
+ if (p.m_X > xmax) {
+ xmax = p.m_X;
+ }
+ if (p.m_X < xmin) {
+ xmin = p.m_X;
+ }
+ if (p.m_Y > ymax) {
+ ymax = p.m_Y;
+ }
+ if (p.m_Y < ymin) {
+ ymin = p.m_Y;
+ }
+ }
+
+ double dx = kAlpha * (xmax - xmin);
+ double dy = kAlpha * (ymax - ymin);
+ m_Head = new Point(xmax + dx, ymin - dy, 0);
+ m_Tail = new Point(xmin - dx, ymin - dy, 0);
+
+ // Sort along y-axis
+ std::sort(m_Points.begin(), m_Points.end(), cmp);
+
+}
+
+void SweepContext::initEdges(std::vector<Point*> polyline)
+{
+ int numPoints = polyline.size();
+ for (int i = 0; i < numPoints; i++) {
+ int j = i < numPoints - 1 ? i + 1 : 0;
+
+ m_EdgeList.push_back(new Edge(*polyline[i], *polyline[j]));
+ }
+}
+
+Point* SweepContext::getPoint(const int& index)
+{
+ return m_Points[index];
+}
+
+void SweepContext::addToMap(TriangulationTriangle* triangle)
+{
+ m_Map.push_back(triangle);
+}
+
+Node& SweepContext::locateNode(Point& point)
+{
+ // TO DO implement search tree
+ return *m_Front->locateNode(point.m_X);
+}
+
+void SweepContext::createAdvancingFront()
+{
+ // Initial triangle
+ TriangulationTriangle* triangle = new TriangulationTriangle(*m_Points[0], *m_Tail,
+ *m_Head);
+
+ m_Map.push_back(triangle);
+
+ m_AfHead = new Node(*triangle->getPoint(1), *triangle);
+ m_AfMiddle = new Node(*triangle->getPoint(0), *triangle);
+ m_AfTail = new Node(*triangle->getPoint(2));
+ m_Front = new AdvancingFront(*m_AfHead, *m_AfTail);
+
+ m_AfHead->m_Next = m_AfMiddle;
+ m_AfMiddle->m_Next = m_AfTail;
+ m_AfMiddle->m_Prev = m_AfHead;
+ m_AfTail->m_Prev = m_AfMiddle;
+}
+
+void SweepContext::removeNode(Node* node)
+{
+ delete node;
+}
+
+void SweepContext::mapTriangleToNodes(TriangulationTriangle& t)
+{
+ for (int i = 0; i < 3; i++) {
+ if (!t.getNeighbor(i)) {
+ Node* n = m_Front->locatePoint(t.pointCW(*t.getPoint(i)));
+ if (n) {
+ n->m_Triangle = &t;
+ }
+ }
+ }
+}
+
+void SweepContext::removeFromMap(TriangulationTriangle* triangle)
+{
+ m_Map.remove(triangle);
+}
+
+void SweepContext::meshClean(TriangulationTriangle& triangle)
+{
+ if (&triangle != NULL && !triangle.isInterior()) {
+ triangle.isInterior(true);
+ m_Triangles.push_back(&triangle);
+ for (int i = 0; i < 3; i++) {
+ if (!triangle.m_ConstrainedEdge[i])
+ meshClean(*triangle.getNeighbor(i));
+ }
+ }
+}
+
+SweepContext::~SweepContext()
+{
+
+ delete m_Head;
+ delete m_Tail;
+ delete m_Front;
+ delete m_AfHead;
+ delete m_AfMiddle;
+ delete m_AfTail;
+
+ typedef std::list<TriangulationTriangle*> type_list;
+
+ for (type_list::iterator iter = m_Map.begin(); iter != m_Map.end(); ++iter) {
+ TriangulationTriangle* ptr = *iter;
+ delete ptr;
+ }
+
+ for (unsigned int i = 0; i < m_EdgeList.size(); i++) {
+ delete m_EdgeList[i];
+ }
+
+}
+
+}
diff --git a/src/base/triangulate/SweepContext.h b/src/base/triangulate/SweepContext.h
new file mode 100644
index 0000000..0b9e51d
--- /dev/null
+++ b/src/base/triangulate/SweepContext.h
@@ -0,0 +1,181 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+//
+// Based on Poly2Tri algorithm.
+// Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
+// http://code.google.com/p/poly2tri/
+//
+
+#ifndef SWEEP_CONTEXT_H
+#define SWEEP_CONTEXT_H
+
+#include <list>
+#include <vector>
+#include <cstddef>
+
+namespace avg {
+
+// Inital triangle factor, seed triangle will extend 30% of
+// PointSet width to both left and right.
+const double kAlpha = 0.3;
+
+struct Point;
+class TriangulationTriangle;
+struct Node;
+struct Edge;
+class AdvancingFront;
+
+class SweepContext
+{
+
+public:
+
+ SweepContext(std::vector<Point*> polyline);
+
+ ~SweepContext();
+
+ void setHead(Point* p1);
+
+ Point* head();
+
+ void setTail(Point* p1);
+
+ Point* tail();
+
+ int pointCount();
+
+ Node& locateNode(Point& point);
+
+ void removeNode(Node* node);
+
+ void createAdvancingFront();
+
+/// Try to map a node to all sides of this triangle that don't have a neighbor
+ void mapTriangleToNodes(TriangulationTriangle& t);
+
+ void addToMap(TriangulationTriangle* triangle);
+
+ Point* getPoint(const int& index);
+
+ Point* GetPoints();
+
+ void removeFromMap(TriangulationTriangle* triangle);
+
+ void addHole(std::vector<Point*> polyline);
+
+ void addPoint(Point* point);
+
+ AdvancingFront* front();
+
+ void meshClean(TriangulationTriangle& triangle);
+
+ std::vector<TriangulationTriangle*>& getTriangles();
+
+ std::vector<Edge*> m_EdgeList;
+
+ struct Basin
+ {
+ Node* m_LeftNode;
+ Node* m_BottomNode;
+ Node* m_RightNode;
+ double m_Width;
+ bool m_LeftHighest;
+
+ Basin()
+ {
+ clear();
+ }
+
+ void clear() {
+ m_LeftNode = NULL;
+ m_BottomNode = NULL;
+ m_RightNode = NULL;
+ m_Width = 0.0;
+ m_LeftHighest = false;
+ }
+ };
+
+ struct EdgeEvent
+ {
+ Edge* m_ConstrainedEdge;
+ bool m_Right;
+
+ EdgeEvent() :
+ m_ConstrainedEdge(NULL), m_Right(false) {
+ }
+ };
+
+ Basin m_Basin;
+ EdgeEvent m_EdgeEvent;
+
+private:
+
+ friend class Sweep;
+
+ std::vector<TriangulationTriangle*> m_Triangles;
+ std::list<TriangulationTriangle*> m_Map;
+ std::vector<Point*> m_Points;
+
+ AdvancingFront* m_Front;
+ Point* m_Head;
+ Point* m_Tail;
+
+ Node *m_AfHead, *m_AfMiddle, *m_AfTail;
+
+ void initTriangulation();
+ void initEdges(std::vector<Point*> polyline);
+
+};
+
+inline AdvancingFront* SweepContext::front()
+{
+ return m_Front;
+}
+
+inline int SweepContext::pointCount()
+{
+ return m_Points.size();
+}
+
+inline void SweepContext::setHead(Point* p1)
+{
+ m_Head = p1;
+}
+
+inline Point* SweepContext::head()
+{
+ return m_Head;
+}
+
+inline void SweepContext::setTail(Point* p1)
+{
+ m_Tail = p1;
+}
+
+inline Point* SweepContext::tail()
+{
+ return m_Tail;
+}
+
+}
+
+#endif
diff --git a/src/base/triangulate/Triangulate.cpp b/src/base/triangulate/Triangulate.cpp
new file mode 100644
index 0000000..9206327
--- /dev/null
+++ b/src/base/triangulate/Triangulate.cpp
@@ -0,0 +1,90 @@
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+//
+// Based on Poly2Tri algorithm.
+// Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
+// http://code.google.com/p/poly2tri/
+//
+
+#include "Triangulate.h"
+#include "Sweep.h"
+#include "SweepContext.h"
+
+#include "Shapes.h"
+
+using namespace std;
+
+namespace avg {
+
+void triangulatePolygon(std::vector<unsigned int>& dest, const Vec2Vector& points,
+ const std::vector<unsigned int>& holeIndexes)
+{
+ std::vector<Point*> polyline;
+ std::vector<Point*> holeLine;
+ unsigned int contourEnd;
+
+ if (holeIndexes.size() > 0) {
+ contourEnd = holeIndexes[0];
+ } else {
+ contourEnd = points.size();
+ }
+
+ for (unsigned int i = 0; i < contourEnd; i++) {
+ polyline.push_back(new Point(points[i].x, points[i].y, i));
+ }
+
+ SweepContext* sweepContext = new SweepContext(polyline);
+ Sweep* sweep = new Sweep;
+
+ if (holeIndexes.size() > 0) {
+ for (unsigned int i = 0; i < holeIndexes.size(); i++) {
+ if ( i < holeIndexes.size()-1) {
+ for (unsigned int j = holeIndexes[i]; j < points.size() && j <
+ holeIndexes[i+1]; j++)
+ {
+ holeLine.push_back(new Point(points[j].x, points[j].y, j));
+ }
+ } else {
+ for (unsigned int j = holeIndexes[i]; j < points.size(); j++) {
+ holeLine.push_back(new Point(points[j].x, points[j].y, j));
+ }
+ }
+ sweepContext->addHole(holeLine);
+ holeLine.clear();
+ }
+ }
+
+ sweep->Triangulate(*sweepContext);
+
+ std::vector<avg::TriangulationTriangle*>& triangles = sweepContext->getTriangles();
+ for (unsigned int i = 0; i < triangles.size(); ++i) {
+ dest.push_back(triangles[i]->getPoint(0)->m_Index);
+ dest.push_back(triangles[i]->getPoint(1)->m_Index);
+ dest.push_back(triangles[i]->getPoint(2)->m_Index);
+ }
+
+ delete sweep;
+ delete sweepContext;
+
+ for (unsigned int i = 0; i < polyline.size(); i++) {
+ delete polyline[i];
+ }
+}
+
+}
diff --git a/src/base/triangulate/Triangulate.h b/src/base/triangulate/Triangulate.h
new file mode 100644
index 0000000..af538a6
--- /dev/null
+++ b/src/base/triangulate/Triangulate.h
@@ -0,0 +1,33 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef TRIANGULATION_H_
+#define TRIANGULATION_H_
+
+#include "../GLMHelper.h"
+namespace avg {
+
+ void triangulatePolygon(std::vector<unsigned int>& dest, const Vec2Vector& points,
+ const std::vector<unsigned int>& holeIndexes = std::vector<unsigned int>());
+
+}
+
+#endif /* TRIANGULATION_H_ */
diff --git a/src/base/triangulate/Utils.h b/src/base/triangulate/Utils.h
new file mode 100644
index 0000000..5dd6685
--- /dev/null
+++ b/src/base/triangulate/Utils.h
@@ -0,0 +1,124 @@
+/*
+ * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
+ * http://code.google.com/p/poly2tri/
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * * Neither the name of Poly2Tri nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef UTILS_H
+#define UTILS_H
+
+// Otherwise #defines like M_PI are undeclared under Visual Studio
+#define _USE_MATH_DEFINES
+
+#include <exception>
+#include <math.h>
+
+namespace avg {
+
+const double PI_3div4 = 3 * M_PI / 4;
+const double EPSILON = 1e-12;
+
+enum Orientation
+{
+ CW, CCW, COLLINEAR
+};
+
+/**
+ * Forumla to calculate signed area<br>
+ * Positive if CCW<br>
+ * Negative if CW<br>
+ * 0 if collinear<br>
+ * <pre>
+ * A[P1,P2,P3] = (x1*y2 - y1*x2) + (x2*y3 - y2*x3) + (x3*y1 - y3*x1)
+ * = (x1-x3)*(y2-y3) - (y1-y3)*(x2-x3)
+ * </pre>
+ */
+Orientation orient2d(Point& pa, Point& pb, Point& pc)
+{
+ double detleft = (pa.m_X - pc.m_X) * (pb.m_Y - pc.m_Y);
+ double detright = (pa.m_Y - pc.m_Y) * (pb.m_X - pc.m_X);
+ double val = detleft - detright;
+ if (val > -EPSILON && val < EPSILON) {
+ return COLLINEAR;
+ } else if (val > 0) {
+ return CCW;
+ }
+ return CW;
+}
+
+/*
+ bool InScanArea(Point& pa, Point& pb, Point& pc, Point& pd)
+ {
+ double pdx = pd.x;
+ double pdy = pd.y;
+ double adx = pa.x - pdx;
+ double ady = pa.y - pdy;
+ double bdx = pb.x - pdx;
+ double bdy = pb.y - pdy;
+
+ double adxbdy = adx * bdy;
+ double bdxady = bdx * ady;
+ double oabd = adxbdy - bdxady;
+
+ if (oabd <= EPSILON) {
+ return false;
+ }
+
+ double cdx = pc.x - pdx;
+ double cdy = pc.y - pdy;
+
+ double cdxady = cdx * ady;
+ double adxcdy = adx * cdy;
+ double ocad = cdxady - adxcdy;
+
+ if (ocad <= EPSILON) {
+ return false;
+ }
+
+ return true;
+ }
+
+ */
+
+bool inScanArea(Point& pa, Point& pb, Point& pc, Point& pd)
+{
+ double oadb = (pa.m_X - pb.m_X) * (pd.m_Y - pb.m_Y) - (pd.m_X - pb.m_X) * (pa.m_Y - pb.m_Y);
+ if (oadb >= -EPSILON) {
+ return false;
+ }
+
+ double oadc = (pa.m_X - pc.m_X) * (pd.m_Y - pc.m_Y) - (pd.m_X - pc.m_X) * (pa.m_Y - pc.m_Y);
+ if (oadc <= EPSILON) {
+ return false;
+ }
+ return true;
+}
+
+}
+
+#endif
diff --git a/src/glm/CMakeLists.txt b/src/glm/CMakeLists.txt
new file mode 100644
index 0000000..d5ba209
--- /dev/null
+++ b/src/glm/CMakeLists.txt
@@ -0,0 +1,43 @@
+set(NAME glm)
+
+file(GLOB ROOT_SOURCE *.cpp)
+file(GLOB ROOT_INLINE *.inl)
+file(GLOB ROOT_HEADER *.hpp)
+
+file(GLOB_RECURSE CORE_SOURCE ./core/*.cpp)
+file(GLOB_RECURSE CORE_INLINE ./core/*.inl)
+file(GLOB_RECURSE CORE_HEADER ./core/*.hpp)
+
+file(GLOB_RECURSE GTC_SOURCE ./gtc/*.cpp)
+file(GLOB_RECURSE GTC_INLINE ./gtc/*.inl)
+file(GLOB_RECURSE GTC_HEADER ./gtc/*.hpp)
+
+file(GLOB_RECURSE GTX_SOURCE ./gtx/*.cpp)
+file(GLOB_RECURSE GTX_INLINE ./gtx/*.inl)
+file(GLOB_RECURSE GTX_HEADER ./gtx/*.hpp)
+
+file(GLOB_RECURSE VIRTREV_SOURCE ./virtrev/*.cpp)
+file(GLOB_RECURSE VIRTREV_INLINE ./virtrev/*.inl)
+file(GLOB_RECURSE VIRTREV_HEADER ./virtrev/*.hpp)
+
+source_group("Core Files" FILES ${CORE_SOURCE})
+source_group("Core Files" FILES ${CORE_INLINE})
+source_group("Core Files" FILES ${CORE_HEADER})
+source_group("GTC Files" FILES ${GTC_SOURCE})
+source_group("GTC Files" FILES ${GTC_INLINE})
+source_group("GTC Files" FILES ${GTC_HEADER})
+source_group("GTX Files" FILES ${GTX_SOURCE})
+source_group("GTX Files" FILES ${GTX_INLINE})
+source_group("GTX Files" FILES ${GTX_HEADER})
+source_group("VIRTREV Files" FILES ${VIRTREV_SOURCE})
+source_group("VIRTREV Files" FILES ${VIRTREV_INLINE})
+source_group("VIRTREV Files" FILES ${VIRTREV_HEADER})
+
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/..)
+
+add_executable(${NAME}
+ ${ROOT_SOURCE} ${ROOT_INLINE} ${ROOT_HEADER}
+ ${CORE_SOURCE} ${CORE_INLINE} ${CORE_HEADER}
+ ${GTC_SOURCE} ${GTC_INLINE} ${GTC_HEADER}
+ ${GTX_SOURCE} ${GTX_INLINE} ${GTX_HEADER}
+ ${VIRTREV_SOURCE} ${VIRTREV_INLINE} ${VIRTREV_HEADER})
diff --git a/src/glm/core/_detail.hpp b/src/glm/core/_detail.hpp
new file mode 100644
index 0000000..1ef629c
--- /dev/null
+++ b/src/glm/core/_detail.hpp
@@ -0,0 +1,356 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2008-07-24
+// Updated : 2008-08-31
+// Licence : This source is under MIT License
+// File : glm/core/_detail.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_core_detail
+#define glm_core_detail
+
+#include "setup.hpp"
+#include <cassert>
+
+namespace glm{
+namespace detail
+{
+ class thalf;
+
+#if(__STDC_VERSION__ >= 199901L) // C99 detected, 64 bit types available
+ typedef int64_t sint64;
+ typedef uint64_t uint64;
+#elif(GLM_COMPILER & GLM_COMPILER_VC)
+ typedef signed __int64 sint64;
+ typedef unsigned __int64 uint64;
+#elif(GLM_COMPILER & (GLM_COMPILER_GCC | GLM_COMPILER_LLVM_GCC | GLM_COMPILER_CLANG))
+ __extension__ typedef signed long long sint64;
+ __extension__ typedef unsigned long long uint64;
+#elif(GLM_COMPILER & GLM_COMPILER_BC)
+ typedef Int64 sint64;
+ typedef Uint64 uint64;
+#else//unknown compiler
+ typedef signed long long sint64;
+ typedef unsigned long long uint64;
+#endif//GLM_COMPILER
+
+ template<bool C>
+ struct If
+ {
+ template<typename F, typename T>
+ static GLM_FUNC_QUALIFIER T apply(F functor, const T& val)
+ {
+ return functor(val);
+ }
+ };
+
+ template<>
+ struct If<false>
+ {
+ template<typename F, typename T>
+ static GLM_FUNC_QUALIFIER T apply(F, const T& val)
+ {
+ return val;
+ }
+ };
+
+ //template <typename T>
+ //struct traits
+ //{
+ // static const bool is_signed = false;
+ // static const bool is_float = false;
+ // static const bool is_vector = false;
+ // static const bool is_matrix = false;
+ // static const bool is_genType = false;
+ // static const bool is_genIType = false;
+ // static const bool is_genUType = false;
+ //};
+
+ //template <>
+ //struct traits<half>
+ //{
+ // static const bool is_float = true;
+ // static const bool is_genType = true;
+ //};
+
+ //template <>
+ //struct traits<float>
+ //{
+ // static const bool is_float = true;
+ // static const bool is_genType = true;
+ //};
+
+ //template <>
+ //struct traits<double>
+ //{
+ // static const bool is_float = true;
+ // static const bool is_genType = true;
+ //};
+
+ //template <typename genType>
+ //struct desc
+ //{
+ // typedef genType type;
+ // typedef genType * pointer;
+ // typedef genType const* const_pointer;
+ // typedef genType const *const const_pointer_const;
+ // typedef genType *const pointer_const;
+ // typedef genType & reference;
+ // typedef genType const& const_reference;
+ // typedef genType const& param_type;
+
+ // typedef typename genType::value_type value_type;
+ // typedef typename genType::size_type size_type;
+ // static const typename size_type value_size;
+ //};
+
+ //template <typename genType>
+ //const typename desc<genType>::size_type desc<genType>::value_size = genType::value_size();
+
+ union uif32
+ {
+ GLM_FUNC_QUALIFIER uif32() :
+ i(0)
+ {}
+
+ GLM_FUNC_QUALIFIER uif32(float f) :
+ f(f)
+ {}
+
+ GLM_FUNC_QUALIFIER uif32(unsigned int i) :
+ i(i)
+ {}
+
+ float f;
+ unsigned int i;
+ };
+
+ union uif64
+ {
+ GLM_FUNC_QUALIFIER uif64() :
+ i(0)
+ {}
+
+ GLM_FUNC_QUALIFIER uif64(double f) :
+ f(f)
+ {}
+
+ GLM_FUNC_QUALIFIER uif64(uint64 i) :
+ i(i)
+ {}
+
+ double f;
+ uint64 i;
+ };
+
+ typedef uif32 uif;
+
+ //////////////////
+ // int
+
+ template <typename T>
+ struct is_int
+ {
+ enum is_int_enum
+ {
+ _YES = 0,
+ _NO = 1
+ };
+ };
+
+#define GLM_DETAIL_IS_INT(T) \
+ template <> \
+ struct is_int<T> \
+ { \
+ enum is_int_enum \
+ { \
+ _YES = 1, \
+ _NO = 0 \
+ }; \
+ }
+
+ //////////////////
+ // uint
+
+ template <typename T>
+ struct is_uint
+ {
+ enum is_uint_enum
+ {
+ _YES = 0,
+ _NO = 1
+ };
+ };
+
+#define GLM_DETAIL_IS_UINT(T) \
+ template <> \
+ struct is_uint<T> \
+ { \
+ enum is_uint_enum \
+ { \
+ _YES = 1, \
+ _NO = 0 \
+ }; \
+ }
+
+ //GLM_DETAIL_IS_UINT(unsigned long long)
+
+ //////////////////
+ // float
+
+ template <typename T>
+ struct is_float
+ {
+ enum is_float_enum
+ {
+ _YES = 0,
+ _NO = 1
+ };
+ };
+
+#define GLM_DETAIL_IS_FLOAT(T) \
+ template <> \
+ struct is_float<T> \
+ { \
+ enum is_float_enum \
+ { \
+ _YES = 1, \
+ _NO = 0 \
+ }; \
+ }
+
+ //////////////////
+ // bool
+
+ template <typename T>
+ struct is_bool
+ {
+ enum is_bool_enum
+ {
+ _YES = 0,
+ _NO = 1
+ };
+ };
+
+ template <>
+ struct is_bool<bool>
+ {
+ enum is_bool_enum
+ {
+ _YES = 1,
+ _NO = 0
+ };
+ };
+
+ //////////////////
+ // vector
+
+ template <typename T>
+ struct is_vector
+ {
+ enum is_vector_enum
+ {
+ _YES = 0,
+ _NO = 1
+ };
+ };
+
+# define GLM_DETAIL_IS_VECTOR(TYPE) \
+ template <typename T> \
+ struct is_vector<TYPE<T> > \
+ { \
+ enum is_vector_enum \
+ { \
+ _YES = 1, \
+ _NO = 0 \
+ }; \
+ }
+
+ //////////////////
+ // matrix
+
+ template <typename T>
+ struct is_matrix
+ {
+ enum is_matrix_enum
+ {
+ _YES = 0,
+ _NO = 1
+ };
+ };
+
+#define GLM_DETAIL_IS_MATRIX(T) \
+ template <> \
+ struct is_matrix \
+ { \
+ enum is_matrix_enum \
+ { \
+ _YES = 1, \
+ _NO = 0 \
+ }; \
+ }
+
+ //////////////////
+ // type
+
+ template <typename T>
+ struct type
+ {
+ enum type_enum
+ {
+ is_float = is_float<T>::_YES,
+ is_int = is_int<T>::_YES,
+ is_uint = is_uint<T>::_YES,
+ is_bool = is_bool<T>::_YES
+ };
+ };
+
+ //////////////////
+ // type
+
+ typedef signed char int8;
+ typedef signed short int16;
+ typedef signed int int32;
+ typedef detail::sint64 int64;
+
+ typedef unsigned char uint8;
+ typedef unsigned short uint16;
+ typedef unsigned int uint32;
+ typedef detail::uint64 uint64;
+
+ typedef detail::thalf float16;
+ typedef float float32;
+ typedef double float64;
+
+}//namespace detail
+}//namespace glm
+
+#if((GLM_COMPILER & GLM_COMPILER_VC) && (GLM_COMPILER >= GLM_COMPILER_VC2005))
+# define GLM_DEPRECATED __declspec(deprecated)
+# define GLM_ALIGN(x) __declspec(align(x))
+# define GLM_ALIGNED_STRUCT(x) __declspec(align(x)) struct
+# define GLM_RESTRICT __declspec(restrict)
+# define GLM_RESTRICT_VAR __restrict
+#elif((GLM_COMPILER & (GLM_COMPILER_GCC | GLM_COMPILER_LLVM_GCC)) && (GLM_COMPILER >= GLM_COMPILER_GCC31))
+# define GLM_DEPRECATED __attribute__((__deprecated__))
+# define GLM_ALIGN(x) __attribute__((aligned(x)))
+# define GLM_ALIGNED_STRUCT(x) struct __attribute__((aligned(x)))
+# if(GLM_COMPILER >= GLM_COMPILER_GCC33)
+# define GLM_RESTRICT __restrict__
+# define GLM_RESTRICT_VAR __restrict__
+# else
+# define GLM_RESTRICT
+# define GLM_RESTRICT_VAR
+# endif
+# define GLM_RESTRICT __restrict__
+# define GLM_RESTRICT_VAR __restrict__
+#else
+# define GLM_DEPRECATED
+# define GLM_ALIGN
+# define GLM_ALIGNED_STRUCT(x)
+# define GLM_RESTRICT
+# define GLM_RESTRICT_VAR
+#endif//GLM_COMPILER
+
+#endif//glm_core_detail
diff --git a/src/glm/core/_fixes.hpp b/src/glm/core/_fixes.hpp
new file mode 100644
index 0000000..50631b5
--- /dev/null
+++ b/src/glm/core/_fixes.hpp
@@ -0,0 +1,18 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2011-02-21
+// Updated : 2011-02-21
+// Licence : This source is under MIT License
+// File : glm/core/_fixes.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+//! Workaround for compatibility with other libraries
+#ifdef max
+#undef max
+#endif
+
+//! Workaround for compatibility with other libraries
+#ifdef min
+#undef min
+#endif
diff --git a/src/glm/core/_swizzle.hpp b/src/glm/core/_swizzle.hpp
new file mode 100644
index 0000000..04c85a0
--- /dev/null
+++ b/src/glm/core/_swizzle.hpp
@@ -0,0 +1,1085 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2006-04-20
+// Updated : 2008-08-22
+// Licence : This source is under MIT License
+// File : glm/core/_swizzle.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_core_swizzle
+#define glm_core_swizzle
+
+namespace glm
+{
+ enum comp
+ {
+ X = 0,
+ R = 0,
+ S = 0,
+ Y = 1,
+ G = 1,
+ T = 1,
+ Z = 2,
+ B = 2,
+ P = 2,
+ W = 3,
+ A = 3,
+ Q = 3
+ };
+}//namespace glm
+
+#if(defined(GLM_SWIZZLE_XYZW) || defined(GLM_SWIZZLE))
+
+#define xx swizzle(glm::X, glm::X)
+#define yx swizzle(glm::Y, glm::X)
+#define zx swizzle(glm::Z, glm::X)
+#define wx swizzle(glm::W, glm::X)
+#define xy swizzle(glm::X, glm::Y)
+#define yy swizzle(glm::Y, glm::Y)
+#define zy swizzle(glm::Z, glm::Y)
+#define wy swizzle(glm::W, glm::Y)
+#define xz swizzle(glm::X, glm::Z)
+#define yz swizzle(glm::Y, glm::Z)
+#define zz swizzle(glm::Z, glm::Z)
+#define wz swizzle(glm::W, glm::Z)
+#define xw swizzle(glm::X, glm::W)
+#define yw swizzle(glm::Y, glm::W)
+#define zw swizzle(glm::Z, glm::W)
+#define ww swizzle(glm::W, glm::W)
+
+#endif
+
+#if(defined(GLM_SWIZZLE_RGBA) || defined(GLM_SWIZZLE))
+
+#define rr swizzle(glm::X, glm::X)
+#define gr swizzle(glm::Y, glm::X)
+#define br swizzle(glm::Z, glm::X)
+#define ar swizzle(glm::W, glm::X)
+#define rg swizzle(glm::X, glm::Y)
+#define gg swizzle(glm::Y, glm::Y)
+#define bg swizzle(glm::Z, glm::Y)
+#define ag swizzle(glm::W, glm::Y)
+#define rb swizzle(glm::X, glm::Z)
+#define gb swizzle(glm::Y, glm::Z)
+#define bb swizzle(glm::Z, glm::Z)
+#define ab swizzle(glm::W, glm::Z)
+#define ra swizzle(glm::X, glm::W)
+#define ga swizzle(glm::Y, glm::W)
+#define ba swizzle(glm::Z, glm::W)
+#define aa swizzle(glm::W, glm::W)
+
+#endif
+
+#if(defined(GLM_FORCE_SWIZZLE_STPQ) || defined(GLM_SWIZZLE))
+
+#define ss swizzle(glm::X, glm::X)
+#define ts swizzle(glm::Y, glm::X)
+#define ps swizzle(glm::Z, glm::X)
+#define qs swizzle(glm::W, glm::X)
+#define st swizzle(glm::X, glm::Y)
+#define tt swizzle(glm::Y, glm::Y)
+#define pt swizzle(glm::Z, glm::Y)
+#define qt swizzle(glm::W, glm::Y)
+#define sp swizzle(glm::X, glm::Z)
+#define tp swizzle(glm::Y, glm::Z)
+#define pp swizzle(glm::Z, glm::Z)
+#define qp swizzle(glm::W, glm::Z)
+#define sq swizzle(glm::X, glm::W)
+#define tq swizzle(glm::Y, glm::W)
+#define pq swizzle(glm::Z, glm::W)
+#define qq swizzle(glm::W, glm::W)
+
+#endif
+
+#if(defined(GLM_SWIZZLE_XYZW) || defined(GLM_SWIZZLE))
+
+#define xxx swizzle(glm::X, glm::X, glm::X)
+#define yxx swizzle(glm::Y, glm::X, glm::X)
+#define zxx swizzle(glm::Z, glm::X, glm::X)
+#define wxx swizzle(glm::W, glm::X, glm::X)
+#define xyx swizzle(glm::X, glm::Y, glm::X)
+#define yyx swizzle(glm::Y, glm::Y, glm::X)
+#define zyx swizzle(glm::Z, glm::Y, glm::X)
+#define wyx swizzle(glm::W, glm::Y, glm::X)
+#define xzx swizzle(glm::X, glm::Z, glm::X)
+#define yzx swizzle(glm::Y, glm::Z, glm::X)
+#define zzx swizzle(glm::Z, glm::Z, glm::X)
+#define wzx swizzle(glm::W, glm::Z, glm::X)
+#define xwx swizzle(glm::X, glm::W, glm::X)
+#define ywx swizzle(glm::Y, glm::W, glm::X)
+#define zwx swizzle(glm::Z, glm::W, glm::X)
+#define wwx swizzle(glm::W, glm::W, glm::X)
+#define xxy swizzle(glm::X, glm::X, glm::Y)
+#define yxy swizzle(glm::Y, glm::X, glm::Y)
+#define zxy swizzle(glm::Z, glm::X, glm::Y)
+#define wxy swizzle(glm::W, glm::X, glm::Y)
+#define xyy swizzle(glm::X, glm::Y, glm::Y)
+#define yyy swizzle(glm::Y, glm::Y, glm::Y)
+#define zyy swizzle(glm::Z, glm::Y, glm::Y)
+#define wyy swizzle(glm::W, glm::Y, glm::Y)
+#define xzy swizzle(glm::X, glm::Z, glm::Y)
+#define yzy swizzle(glm::Y, glm::Z, glm::Y)
+#define zzy swizzle(glm::Z, glm::Z, glm::Y)
+#define wzy swizzle(glm::W, glm::Z, glm::Y)
+#define xwy swizzle(glm::X, glm::W, glm::Y)
+#define ywy swizzle(glm::Y, glm::W, glm::Y)
+#define zwy swizzle(glm::Z, glm::W, glm::Y)
+#define wwy swizzle(glm::W, glm::W, glm::Y)
+#define xxz swizzle(glm::X, glm::X, glm::Z)
+#define yxz swizzle(glm::Y, glm::X, glm::Z)
+#define zxz swizzle(glm::Z, glm::X, glm::Z)
+#define wxz swizzle(glm::W, glm::X, glm::Z)
+#define xyz swizzle(glm::X, glm::Y, glm::Z)
+#define yyz swizzle(glm::Y, glm::Y, glm::Z)
+#define zyz swizzle(glm::Z, glm::Y, glm::Z)
+#define wyz swizzle(glm::W, glm::Y, glm::Z)
+#define xzz swizzle(glm::X, glm::Z, glm::Z)
+#define yzz swizzle(glm::Y, glm::Z, glm::Z)
+#define zzz swizzle(glm::Z, glm::Z, glm::Z)
+#define wzz swizzle(glm::W, glm::Z, glm::Z)
+#define xwz swizzle(glm::X, glm::W, glm::Z)
+#define ywz swizzle(glm::Y, glm::W, glm::Z)
+#define zwz swizzle(glm::Z, glm::W, glm::Z)
+#define wwz swizzle(glm::W, glm::W, glm::Z)
+#define xxw swizzle(glm::X, glm::X, glm::W)
+#define yxw swizzle(glm::Y, glm::X, glm::W)
+#define zxw swizzle(glm::Z, glm::X, glm::W)
+#define wxw swizzle(glm::W, glm::X, glm::W)
+#define xyw swizzle(glm::X, glm::Y, glm::W)
+#define yyw swizzle(glm::Y, glm::Y, glm::W)
+#define zyw swizzle(glm::Z, glm::Y, glm::W)
+#define wyw swizzle(glm::W, glm::Y, glm::W)
+#define xzw swizzle(glm::X, glm::Z, glm::W)
+#define yzw swizzle(glm::Y, glm::Z, glm::W)
+#define zzw swizzle(glm::Z, glm::Z, glm::W)
+#define wzw swizzle(glm::W, glm::Z, glm::W)
+#define xww swizzle(glm::X, glm::W, glm::W)
+#define yww swizzle(glm::Y, glm::W, glm::W)
+#define zww swizzle(glm::Z, glm::W, glm::W)
+#define www swizzle(glm::W, glm::W, glm::W)
+
+#endif
+
+#if(defined(GLM_SWIZZLE_RGBA) || defined(GLM_SWIZZLE))
+
+#define rrr swizzle(glm::X, glm::X, glm::X)
+#define grr swizzle(glm::Y, glm::X, glm::X)
+#define brr swizzle(glm::Z, glm::X, glm::X)
+#define arr swizzle(glm::W, glm::X, glm::X)
+#define rgr swizzle(glm::X, glm::Y, glm::X)
+#define ggr swizzle(glm::Y, glm::Y, glm::X)
+#define bgr swizzle(glm::Z, glm::Y, glm::X)
+#define agr swizzle(glm::W, glm::Y, glm::X)
+#define rbr swizzle(glm::X, glm::Z, glm::X)
+#define gbr swizzle(glm::Y, glm::Z, glm::X)
+#define bbr swizzle(glm::Z, glm::Z, glm::X)
+#define abr swizzle(glm::W, glm::Z, glm::X)
+#define rar swizzle(glm::X, glm::W, glm::X)
+#define gar swizzle(glm::Y, glm::W, glm::X)
+#define bar swizzle(glm::Z, glm::W, glm::X)
+#define aar swizzle(glm::W, glm::W, glm::X)
+#define rrg swizzle(glm::X, glm::X, glm::Y)
+#define grg swizzle(glm::Y, glm::X, glm::Y)
+#define brg swizzle(glm::Z, glm::X, glm::Y)
+#define arg swizzle(glm::W, glm::X, glm::Y)
+#define rgg swizzle(glm::X, glm::Y, glm::Y)
+#define ggg swizzle(glm::Y, glm::Y, glm::Y)
+#define bgg swizzle(glm::Z, glm::Y, glm::Y)
+#define agg swizzle(glm::W, glm::Y, glm::Y)
+#define rbg swizzle(glm::X, glm::Z, glm::Y)
+#define gbg swizzle(glm::Y, glm::Z, glm::Y)
+#define bbg swizzle(glm::Z, glm::Z, glm::Y)
+#define abg swizzle(glm::W, glm::Z, glm::Y)
+#define rag swizzle(glm::X, glm::W, glm::Y)
+#define gag swizzle(glm::Y, glm::W, glm::Y)
+#define bag swizzle(glm::Z, glm::W, glm::Y)
+#define aag swizzle(glm::W, glm::W, glm::Y)
+#define rrb swizzle(glm::X, glm::X, glm::Z)
+#define grb swizzle(glm::Y, glm::X, glm::Z)
+#define brb swizzle(glm::Z, glm::X, glm::Z)
+#define arb swizzle(glm::W, glm::X, glm::Z)
+#define rgb swizzle(glm::X, glm::Y, glm::Z)
+#define ggb swizzle(glm::Y, glm::Y, glm::Z)
+#define bgb swizzle(glm::Z, glm::Y, glm::Z)
+#define agb swizzle(glm::W, glm::Y, glm::Z)
+#define rbb swizzle(glm::X, glm::Z, glm::Z)
+#define gbb swizzle(glm::Y, glm::Z, glm::Z)
+#define bbb swizzle(glm::Z, glm::Z, glm::Z)
+#define abb swizzle(glm::W, glm::Z, glm::Z)
+#define rab swizzle(glm::X, glm::W, glm::Z)
+#define gab swizzle(glm::Y, glm::W, glm::Z)
+#define bab swizzle(glm::Z, glm::W, glm::Z)
+#define aab swizzle(glm::W, glm::W, glm::Z)
+#define rra swizzle(glm::X, glm::X, glm::W)
+#define gra swizzle(glm::Y, glm::X, glm::W)
+#define bra swizzle(glm::Z, glm::X, glm::W)
+#define ara swizzle(glm::W, glm::X, glm::W)
+#define rga swizzle(glm::X, glm::Y, glm::W)
+#define gga swizzle(glm::Y, glm::Y, glm::W)
+#define bga swizzle(glm::Z, glm::Y, glm::W)
+#define aga swizzle(glm::W, glm::Y, glm::W)
+#define rba swizzle(glm::X, glm::Z, glm::W)
+#define gba swizzle(glm::Y, glm::Z, glm::W)
+#define bba swizzle(glm::Z, glm::Z, glm::W)
+#define aba swizzle(glm::W, glm::Z, glm::W)
+#define raa swizzle(glm::X, glm::W, glm::W)
+#define gaa swizzle(glm::Y, glm::W, glm::W)
+#define baa swizzle(glm::Z, glm::W, glm::W)
+#define aaa swizzle(glm::W, glm::W, glm::W)
+
+#endif
+
+#if(defined(GLM_FORCE_SWIZZLE_STPQ) || defined(GLM_SWIZZLE))
+
+#define sss swizzle(glm::X, glm::X, glm::X)
+#define tss swizzle(glm::Y, glm::X, glm::X)
+#define pss swizzle(glm::Z, glm::X, glm::X)
+#define qss swizzle(glm::W, glm::X, glm::X)
+#define sts swizzle(glm::X, glm::Y, glm::X)
+#define tts swizzle(glm::Y, glm::Y, glm::X)
+#define pts swizzle(glm::Z, glm::Y, glm::X)
+#define qts swizzle(glm::W, glm::Y, glm::X)
+#define sps swizzle(glm::X, glm::Z, glm::X)
+#define tps swizzle(glm::Y, glm::Z, glm::X)
+#define pps swizzle(glm::Z, glm::Z, glm::X)
+#define qps swizzle(glm::W, glm::Z, glm::X)
+#define sqs swizzle(glm::X, glm::W, glm::X)
+#define tqs swizzle(glm::Y, glm::W, glm::X)
+#define pqs swizzle(glm::Z, glm::W, glm::X)
+#define qqs swizzle(glm::W, glm::W, glm::X)
+#define sst swizzle(glm::X, glm::X, glm::Y)
+#define tst swizzle(glm::Y, glm::X, glm::Y)
+#define pst swizzle(glm::Z, glm::X, glm::Y)
+#define qst swizzle(glm::W, glm::X, glm::Y)
+#define stt swizzle(glm::X, glm::Y, glm::Y)
+#define ttt swizzle(glm::Y, glm::Y, glm::Y)
+#define ptt swizzle(glm::Z, glm::Y, glm::Y)
+#define qtt swizzle(glm::W, glm::Y, glm::Y)
+#define spt swizzle(glm::X, glm::Z, glm::Y)
+#define tpt swizzle(glm::Y, glm::Z, glm::Y)
+#define ppt swizzle(glm::Z, glm::Z, glm::Y)
+#define qpt swizzle(glm::W, glm::Z, glm::Y)
+#define sqt swizzle(glm::X, glm::W, glm::Y)
+#define tqt swizzle(glm::Y, glm::W, glm::Y)
+#define pqt swizzle(glm::Z, glm::W, glm::Y)
+#define qqt swizzle(glm::W, glm::W, glm::Y)
+#define ssp swizzle(glm::X, glm::X, glm::Z)
+#define tsp swizzle(glm::Y, glm::X, glm::Z)
+#define psp swizzle(glm::Z, glm::X, glm::Z)
+#define qsp swizzle(glm::W, glm::X, glm::Z)
+#define stp swizzle(glm::X, glm::Y, glm::Z)
+#define ttp swizzle(glm::Y, glm::Y, glm::Z)
+#define ptp swizzle(glm::Z, glm::Y, glm::Z)
+#define qtp swizzle(glm::W, glm::Y, glm::Z)
+#define spp swizzle(glm::X, glm::Z, glm::Z)
+#define tpp swizzle(glm::Y, glm::Z, glm::Z)
+#define ppp swizzle(glm::Z, glm::Z, glm::Z)
+#define qpp swizzle(glm::W, glm::Z, glm::Z)
+#define sqp swizzle(glm::X, glm::W, glm::Z)
+#define tqp swizzle(glm::Y, glm::W, glm::Z)
+#define pqp swizzle(glm::Z, glm::W, glm::Z)
+#define qqp swizzle(glm::W, glm::W, glm::Z)
+#define ssq swizzle(glm::X, glm::X, glm::W)
+#define tsq swizzle(glm::Y, glm::X, glm::W)
+#define psq swizzle(glm::Z, glm::X, glm::W)
+#define qsq swizzle(glm::W, glm::X, glm::W)
+#define stq swizzle(glm::X, glm::Y, glm::W)
+#define ttq swizzle(glm::Y, glm::Y, glm::W)
+#define ptq swizzle(glm::Z, glm::Y, glm::W)
+#define qtq swizzle(glm::W, glm::Y, glm::W)
+#define spq swizzle(glm::X, glm::Z, glm::W)
+#define tpq swizzle(glm::Y, glm::Z, glm::W)
+#define ppq swizzle(glm::Z, glm::Z, glm::W)
+#define qpq swizzle(glm::W, glm::Z, glm::W)
+#define sqq swizzle(glm::X, glm::W, glm::W)
+#define tqq swizzle(glm::Y, glm::W, glm::W)
+#define pqq swizzle(glm::Z, glm::W, glm::W)
+#define qqq swizzle(glm::W, glm::W, glm::W)
+
+#endif
+
+#if(defined(GLM_SWIZZLE_XYZW) || defined(GLM_SWIZZLE))
+
+#define xxxx swizzle(glm::X, glm::X, glm::X, glm::X)
+#define yxxx swizzle(glm::Y, glm::X, glm::X, glm::X)
+#define zxxx swizzle(glm::Z, glm::X, glm::X, glm::X)
+#define wxxx swizzle(glm::W, glm::X, glm::X, glm::X)
+#define xyxx swizzle(glm::X, glm::Y, glm::X, glm::X)
+#define yyxx swizzle(glm::Y, glm::Y, glm::X, glm::X)
+#define zyxx swizzle(glm::Z, glm::Y, glm::X, glm::X)
+#define wyxx swizzle(glm::W, glm::Y, glm::X, glm::X)
+#define xzxx swizzle(glm::X, glm::Z, glm::X, glm::X)
+#define yzxx swizzle(glm::Y, glm::Z, glm::X, glm::X)
+#define zzxx swizzle(glm::Z, glm::Z, glm::X, glm::X)
+#define wzxx swizzle(glm::W, glm::Z, glm::X, glm::X)
+#define xwxx swizzle(glm::X, glm::W, glm::X, glm::X)
+#define ywxx swizzle(glm::Y, glm::W, glm::X, glm::X)
+#define zwxx swizzle(glm::Z, glm::W, glm::X, glm::X)
+#define wwxx swizzle(glm::W, glm::W, glm::X, glm::X)
+#define xxyx swizzle(glm::X, glm::X, glm::Y, glm::X)
+#define yxyx swizzle(glm::Y, glm::X, glm::Y, glm::X)
+#define zxyx swizzle(glm::Z, glm::X, glm::Y, glm::X)
+#define wxyx swizzle(glm::W, glm::X, glm::Y, glm::X)
+#define xyyx swizzle(glm::X, glm::Y, glm::Y, glm::X)
+#define yyyx swizzle(glm::Y, glm::Y, glm::Y, glm::X)
+#define zyyx swizzle(glm::Z, glm::Y, glm::Y, glm::X)
+#define wyyx swizzle(glm::W, glm::Y, glm::Y, glm::X)
+#define xzyx swizzle(glm::X, glm::Z, glm::Y, glm::X)
+#define yzyx swizzle(glm::Y, glm::Z, glm::Y, glm::X)
+#define zzyx swizzle(glm::Z, glm::Z, glm::Y, glm::X)
+#define wzyx swizzle(glm::W, glm::Z, glm::Y, glm::X)
+#define xwyx swizzle(glm::X, glm::W, glm::Y, glm::X)
+#define ywyx swizzle(glm::Y, glm::W, glm::Y, glm::X)
+#define zwyx swizzle(glm::Z, glm::W, glm::Y, glm::X)
+#define wwyx swizzle(glm::W, glm::W, glm::Y, glm::X)
+#define xxzx swizzle(glm::X, glm::X, glm::Z, glm::X)
+#define yxzx swizzle(glm::Y, glm::X, glm::Z, glm::X)
+#define zxzx swizzle(glm::Z, glm::X, glm::Z, glm::X)
+#define wxzx swizzle(glm::W, glm::X, glm::Z, glm::X)
+#define xyzx swizzle(glm::X, glm::Y, glm::Z, glm::X)
+#define yyzx swizzle(glm::Y, glm::Y, glm::Z, glm::X)
+#define zyzx swizzle(glm::Z, glm::Y, glm::Z, glm::X)
+#define wyzx swizzle(glm::W, glm::Y, glm::Z, glm::X)
+#define xzzx swizzle(glm::X, glm::Z, glm::Z, glm::X)
+#define yzzx swizzle(glm::Y, glm::Z, glm::Z, glm::X)
+#define zzzx swizzle(glm::Z, glm::Z, glm::Z, glm::X)
+#define wzzx swizzle(glm::W, glm::Z, glm::Z, glm::X)
+#define xwzx swizzle(glm::X, glm::W, glm::Z, glm::X)
+#define ywzx swizzle(glm::Y, glm::W, glm::Z, glm::X)
+#define zwzx swizzle(glm::Z, glm::W, glm::Z, glm::X)
+#define wwzx swizzle(glm::W, glm::W, glm::Z, glm::X)
+#define xxwx swizzle(glm::X, glm::X, glm::W, glm::X)
+#define yxwx swizzle(glm::Y, glm::X, glm::W, glm::X)
+#define zxwx swizzle(glm::Z, glm::X, glm::W, glm::X)
+#define wxwx swizzle(glm::W, glm::X, glm::W, glm::X)
+#define xywx swizzle(glm::X, glm::Y, glm::W, glm::X)
+#define yywx swizzle(glm::Y, glm::Y, glm::W, glm::X)
+#define zywx swizzle(glm::Z, glm::Y, glm::W, glm::X)
+#define wywx swizzle(glm::W, glm::Y, glm::W, glm::X)
+#define xzwx swizzle(glm::X, glm::Z, glm::W, glm::X)
+#define yzwx swizzle(glm::Y, glm::Z, glm::W, glm::X)
+#define zzwx swizzle(glm::Z, glm::Z, glm::W, glm::X)
+#define wzwx swizzle(glm::W, glm::Z, glm::W, glm::X)
+#define xwwx swizzle(glm::X, glm::W, glm::W, glm::X)
+#define ywwx swizzle(glm::Y, glm::W, glm::W, glm::X)
+#define zwwx swizzle(glm::Z, glm::W, glm::W, glm::X)
+#define wwwx swizzle(glm::W, glm::W, glm::W, glm::X)
+#define xxxy swizzle(glm::X, glm::X, glm::X, glm::Y)
+#define yxxy swizzle(glm::Y, glm::X, glm::X, glm::Y)
+#define zxxy swizzle(glm::Z, glm::X, glm::X, glm::Y)
+#define wxxy swizzle(glm::W, glm::X, glm::X, glm::Y)
+#define xyxy swizzle(glm::X, glm::Y, glm::X, glm::Y)
+#define yyxy swizzle(glm::Y, glm::Y, glm::X, glm::Y)
+#define zyxy swizzle(glm::Z, glm::Y, glm::X, glm::Y)
+#define wyxy swizzle(glm::W, glm::Y, glm::X, glm::Y)
+#define xzxy swizzle(glm::X, glm::Z, glm::X, glm::Y)
+#define yzxy swizzle(glm::Y, glm::Z, glm::X, glm::Y)
+#define zzxy swizzle(glm::Z, glm::Z, glm::X, glm::Y)
+#define wzxy swizzle(glm::W, glm::Z, glm::X, glm::Y)
+#define xwxy swizzle(glm::X, glm::W, glm::X, glm::Y)
+#define ywxy swizzle(glm::Y, glm::W, glm::X, glm::Y)
+#define zwxy swizzle(glm::Z, glm::W, glm::X, glm::Y)
+#define wwxy swizzle(glm::W, glm::W, glm::X, glm::Y)
+#define xxyy swizzle(glm::X, glm::X, glm::Y, glm::Y)
+#define yxyy swizzle(glm::Y, glm::X, glm::Y, glm::Y)
+#define zxyy swizzle(glm::Z, glm::X, glm::Y, glm::Y)
+#define wxyy swizzle(glm::W, glm::X, glm::Y, glm::Y)
+#define xyyy swizzle(glm::X, glm::Y, glm::Y, glm::Y)
+#define yyyy swizzle(glm::Y, glm::Y, glm::Y, glm::Y)
+#define zyyy swizzle(glm::Z, glm::Y, glm::Y, glm::Y)
+#define wyyy swizzle(glm::W, glm::Y, glm::Y, glm::Y)
+#define xzyy swizzle(glm::X, glm::Z, glm::Y, glm::Y)
+#define yzyy swizzle(glm::Y, glm::Z, glm::Y, glm::Y)
+#define zzyy swizzle(glm::Z, glm::Z, glm::Y, glm::Y)
+#define wzyy swizzle(glm::W, glm::Z, glm::Y, glm::Y)
+#define xwyy swizzle(glm::X, glm::W, glm::Y, glm::Y)
+#define ywyy swizzle(glm::Y, glm::W, glm::Y, glm::Y)
+#define zwyy swizzle(glm::Z, glm::W, glm::Y, glm::Y)
+#define wwyy swizzle(glm::W, glm::W, glm::Y, glm::Y)
+#define xxzy swizzle(glm::X, glm::X, glm::Z, glm::Y)
+#define yxzy swizzle(glm::Y, glm::X, glm::Z, glm::Y)
+#define zxzy swizzle(glm::Z, glm::X, glm::Z, glm::Y)
+#define wxzy swizzle(glm::W, glm::X, glm::Z, glm::Y)
+#define xyzy swizzle(glm::X, glm::Y, glm::Z, glm::Y)
+#define yyzy swizzle(glm::Y, glm::Y, glm::Z, glm::Y)
+#define zyzy swizzle(glm::Z, glm::Y, glm::Z, glm::Y)
+#define wyzy swizzle(glm::W, glm::Y, glm::Z, glm::Y)
+#define xzzy swizzle(glm::X, glm::Z, glm::Z, glm::Y)
+#define yzzy swizzle(glm::Y, glm::Z, glm::Z, glm::Y)
+#define zzzy swizzle(glm::Z, glm::Z, glm::Z, glm::Y)
+#define wzzy swizzle(glm::W, glm::Z, glm::Z, glm::Y)
+#define xwzy swizzle(glm::X, glm::W, glm::Z, glm::Y)
+#define ywzy swizzle(glm::Y, glm::W, glm::Z, glm::Y)
+#define zwzy swizzle(glm::Z, glm::W, glm::Z, glm::Y)
+#define wwzy swizzle(glm::W, glm::W, glm::Z, glm::Y)
+#define xxwy swizzle(glm::X, glm::X, glm::W, glm::Y)
+#define yxwy swizzle(glm::Y, glm::X, glm::W, glm::Y)
+#define zxwy swizzle(glm::Z, glm::X, glm::W, glm::Y)
+#define wxwy swizzle(glm::W, glm::X, glm::W, glm::Y)
+#define xywy swizzle(glm::X, glm::Y, glm::W, glm::Y)
+#define yywy swizzle(glm::Y, glm::Y, glm::W, glm::Y)
+#define zywy swizzle(glm::Z, glm::Y, glm::W, glm::Y)
+#define wywy swizzle(glm::W, glm::Y, glm::W, glm::Y)
+#define xzwy swizzle(glm::X, glm::Z, glm::W, glm::Y)
+#define yzwy swizzle(glm::Y, glm::Z, glm::W, glm::Y)
+#define zzwy swizzle(glm::Z, glm::Z, glm::W, glm::Y)
+#define wzwy swizzle(glm::W, glm::Z, glm::W, glm::Y)
+#define xwwy swizzle(glm::X, glm::W, glm::W, glm::Y)
+#define ywwy swizzle(glm::Y, glm::W, glm::W, glm::Y)
+#define zwwy swizzle(glm::Z, glm::W, glm::W, glm::Y)
+#define wwwy swizzle(glm::W, glm::W, glm::W, glm::Y)
+#define xxxz swizzle(glm::X, glm::X, glm::X, glm::Z)
+#define yxxz swizzle(glm::Y, glm::X, glm::X, glm::Z)
+#define zxxz swizzle(glm::Z, glm::X, glm::X, glm::Z)
+#define wxxz swizzle(glm::W, glm::X, glm::X, glm::Z)
+#define xyxz swizzle(glm::X, glm::Y, glm::X, glm::Z)
+#define yyxz swizzle(glm::Y, glm::Y, glm::X, glm::Z)
+#define zyxz swizzle(glm::Z, glm::Y, glm::X, glm::Z)
+#define wyxz swizzle(glm::W, glm::Y, glm::X, glm::Z)
+#define xzxz swizzle(glm::X, glm::Z, glm::X, glm::Z)
+#define yzxz swizzle(glm::Y, glm::Z, glm::X, glm::Z)
+#define zzxz swizzle(glm::Z, glm::Z, glm::X, glm::Z)
+#define wzxz swizzle(glm::W, glm::Z, glm::X, glm::Z)
+#define xwxz swizzle(glm::X, glm::W, glm::X, glm::Z)
+#define ywxz swizzle(glm::Y, glm::W, glm::X, glm::Z)
+#define zwxz swizzle(glm::Z, glm::W, glm::X, glm::Z)
+#define wwxz swizzle(glm::W, glm::W, glm::X, glm::Z)
+#define xxyz swizzle(glm::X, glm::X, glm::Y, glm::Z)
+#define yxyz swizzle(glm::Y, glm::X, glm::Y, glm::Z)
+#define zxyz swizzle(glm::Z, glm::X, glm::Y, glm::Z)
+#define wxyz swizzle(glm::W, glm::X, glm::Y, glm::Z)
+#define xyyz swizzle(glm::X, glm::Y, glm::Y, glm::Z)
+#define yyyz swizzle(glm::Y, glm::Y, glm::Y, glm::Z)
+#define zyyz swizzle(glm::Z, glm::Y, glm::Y, glm::Z)
+#define wyyz swizzle(glm::W, glm::Y, glm::Y, glm::Z)
+#define xzyz swizzle(glm::X, glm::Z, glm::Y, glm::Z)
+#define yzyz swizzle(glm::Y, glm::Z, glm::Y, glm::Z)
+#define zzyz swizzle(glm::Z, glm::Z, glm::Y, glm::Z)
+#define wzyz swizzle(glm::W, glm::Z, glm::Y, glm::Z)
+#define xwyz swizzle(glm::X, glm::W, glm::Y, glm::Z)
+#define ywyz swizzle(glm::Y, glm::W, glm::Y, glm::Z)
+#define zwyz swizzle(glm::Z, glm::W, glm::Y, glm::Z)
+#define wwyz swizzle(glm::W, glm::W, glm::Y, glm::Z)
+#define xxzz swizzle(glm::X, glm::X, glm::Z, glm::Z)
+#define yxzz swizzle(glm::Y, glm::X, glm::Z, glm::Z)
+#define zxzz swizzle(glm::Z, glm::X, glm::Z, glm::Z)
+#define wxzz swizzle(glm::W, glm::X, glm::Z, glm::Z)
+#define xyzz swizzle(glm::X, glm::Y, glm::Z, glm::Z)
+#define yyzz swizzle(glm::Y, glm::Y, glm::Z, glm::Z)
+#define zyzz swizzle(glm::Z, glm::Y, glm::Z, glm::Z)
+#define wyzz swizzle(glm::W, glm::Y, glm::Z, glm::Z)
+#define xzzz swizzle(glm::X, glm::Z, glm::Z, glm::Z)
+#define yzzz swizzle(glm::Y, glm::Z, glm::Z, glm::Z)
+#define zzzz swizzle(glm::Z, glm::Z, glm::Z, glm::Z)
+#define wzzz swizzle(glm::W, glm::Z, glm::Z, glm::Z)
+#define xwzz swizzle(glm::X, glm::W, glm::Z, glm::Z)
+#define ywzz swizzle(glm::Y, glm::W, glm::Z, glm::Z)
+#define zwzz swizzle(glm::Z, glm::W, glm::Z, glm::Z)
+#define wwzz swizzle(glm::W, glm::W, glm::Z, glm::Z)
+#define xxwz swizzle(glm::X, glm::X, glm::W, glm::Z)
+#define yxwz swizzle(glm::Y, glm::X, glm::W, glm::Z)
+#define zxwz swizzle(glm::Z, glm::X, glm::W, glm::Z)
+#define wxwz swizzle(glm::W, glm::X, glm::W, glm::Z)
+#define xywz swizzle(glm::X, glm::Y, glm::W, glm::Z)
+#define yywz swizzle(glm::Y, glm::Y, glm::W, glm::Z)
+#define zywz swizzle(glm::Z, glm::Y, glm::W, glm::Z)
+#define wywz swizzle(glm::W, glm::Y, glm::W, glm::Z)
+#define xzwz swizzle(glm::X, glm::Z, glm::W, glm::Z)
+#define yzwz swizzle(glm::Y, glm::Z, glm::W, glm::Z)
+#define zzwz swizzle(glm::Z, glm::Z, glm::W, glm::Z)
+#define wzwz swizzle(glm::W, glm::Z, glm::W, glm::Z)
+#define xwwz swizzle(glm::X, glm::W, glm::W, glm::Z)
+#define ywwz swizzle(glm::Y, glm::W, glm::W, glm::Z)
+#define zwwz swizzle(glm::Z, glm::W, glm::W, glm::Z)
+#define wwwz swizzle(glm::W, glm::W, glm::W, glm::Z)
+#define xxxw swizzle(glm::X, glm::X, glm::X, glm::W)
+#define yxxw swizzle(glm::Y, glm::X, glm::X, glm::W)
+#define zxxw swizzle(glm::Z, glm::X, glm::X, glm::W)
+#define wxxw swizzle(glm::W, glm::X, glm::X, glm::W)
+#define xyxw swizzle(glm::X, glm::Y, glm::X, glm::W)
+#define yyxw swizzle(glm::Y, glm::Y, glm::X, glm::W)
+#define zyxw swizzle(glm::Z, glm::Y, glm::X, glm::W)
+#define wyxw swizzle(glm::W, glm::Y, glm::X, glm::W)
+#define xzxw swizzle(glm::X, glm::Z, glm::X, glm::W)
+#define yzxw swizzle(glm::Y, glm::Z, glm::X, glm::W)
+#define zzxw swizzle(glm::Z, glm::Z, glm::X, glm::W)
+#define wzxw swizzle(glm::W, glm::Z, glm::X, glm::W)
+#define xwxw swizzle(glm::X, glm::W, glm::X, glm::W)
+#define ywxw swizzle(glm::Y, glm::W, glm::X, glm::W)
+#define zwxw swizzle(glm::Z, glm::W, glm::X, glm::W)
+#define wwxw swizzle(glm::W, glm::W, glm::X, glm::W)
+#define xxyw swizzle(glm::X, glm::X, glm::Y, glm::W)
+#define yxyw swizzle(glm::Y, glm::X, glm::Y, glm::W)
+#define zxyw swizzle(glm::Z, glm::X, glm::Y, glm::W)
+#define wxyw swizzle(glm::W, glm::X, glm::Y, glm::W)
+#define xyyw swizzle(glm::X, glm::Y, glm::Y, glm::W)
+#define yyyw swizzle(glm::Y, glm::Y, glm::Y, glm::W)
+#define zyyw swizzle(glm::Z, glm::Y, glm::Y, glm::W)
+#define wyyw swizzle(glm::W, glm::Y, glm::Y, glm::W)
+#define xzyw swizzle(glm::X, glm::Z, glm::Y, glm::W)
+#define yzyw swizzle(glm::Y, glm::Z, glm::Y, glm::W)
+#define zzyw swizzle(glm::Z, glm::Z, glm::Y, glm::W)
+#define wzyw swizzle(glm::W, glm::Z, glm::Y, glm::W)
+#define xwyw swizzle(glm::X, glm::W, glm::Y, glm::W)
+#define ywyw swizzle(glm::Y, glm::W, glm::Y, glm::W)
+#define zwyw swizzle(glm::Z, glm::W, glm::Y, glm::W)
+#define wwyw swizzle(glm::W, glm::W, glm::Y, glm::W)
+#define xxzw swizzle(glm::X, glm::X, glm::Z, glm::W)
+#define yxzw swizzle(glm::Y, glm::X, glm::Z, glm::W)
+#define zxzw swizzle(glm::Z, glm::X, glm::Z, glm::W)
+#define wxzw swizzle(glm::W, glm::X, glm::Z, glm::W)
+#define xyzw swizzle(glm::X, glm::Y, glm::Z, glm::W)
+#define yyzw swizzle(glm::Y, glm::Y, glm::Z, glm::W)
+#define zyzw swizzle(glm::Z, glm::Y, glm::Z, glm::W)
+#define wyzw swizzle(glm::W, glm::Y, glm::Z, glm::W)
+#define xzzw swizzle(glm::X, glm::Z, glm::Z, glm::W)
+#define yzzw swizzle(glm::Y, glm::Z, glm::Z, glm::W)
+#define zzzw swizzle(glm::Z, glm::Z, glm::Z, glm::W)
+#define wzzw swizzle(glm::W, glm::Z, glm::Z, glm::W)
+#define xwzw swizzle(glm::X, glm::W, glm::Z, glm::W)
+#define ywzw swizzle(glm::Y, glm::W, glm::Z, glm::W)
+#define zwzw swizzle(glm::Z, glm::W, glm::Z, glm::W)
+#define wwzw swizzle(glm::W, glm::W, glm::Z, glm::W)
+#define xxww swizzle(glm::X, glm::X, glm::W, glm::W)
+#define yxww swizzle(glm::Y, glm::X, glm::W, glm::W)
+#define zxww swizzle(glm::Z, glm::X, glm::W, glm::W)
+#define wxww swizzle(glm::W, glm::X, glm::W, glm::W)
+#define xyww swizzle(glm::X, glm::Y, glm::W, glm::W)
+#define yyww swizzle(glm::Y, glm::Y, glm::W, glm::W)
+#define zyww swizzle(glm::Z, glm::Y, glm::W, glm::W)
+#define wyww swizzle(glm::W, glm::Y, glm::W, glm::W)
+#define xzww swizzle(glm::X, glm::Z, glm::W, glm::W)
+#define yzww swizzle(glm::Y, glm::Z, glm::W, glm::W)
+#define zzww swizzle(glm::Z, glm::Z, glm::W, glm::W)
+#define wzww swizzle(glm::W, glm::Z, glm::W, glm::W)
+#define xwww swizzle(glm::X, glm::W, glm::W, glm::W)
+#define ywww swizzle(glm::Y, glm::W, glm::W, glm::W)
+#define zwww swizzle(glm::Z, glm::W, glm::W, glm::W)
+#define wwww swizzle(glm::W, glm::W, glm::W, glm::W)
+
+#endif
+
+#if(defined(GLM_SWIZZLE_RGBA) || defined(GLM_SWIZZLE))
+
+#define rrrr swizzle(glm::X, glm::X, glm::X, glm::X)
+#define grrr swizzle(glm::Y, glm::X, glm::X, glm::X)
+#define brrr swizzle(glm::Z, glm::X, glm::X, glm::X)
+#define arrr swizzle(glm::W, glm::X, glm::X, glm::X)
+#define rgrr swizzle(glm::X, glm::Y, glm::X, glm::X)
+#define ggrr swizzle(glm::Y, glm::Y, glm::X, glm::X)
+#define bgrr swizzle(glm::Z, glm::Y, glm::X, glm::X)
+#define agrr swizzle(glm::W, glm::Y, glm::X, glm::X)
+#define rbrr swizzle(glm::X, glm::Z, glm::X, glm::X)
+#define gbrr swizzle(glm::Y, glm::Z, glm::X, glm::X)
+#define bbrr swizzle(glm::Z, glm::Z, glm::X, glm::X)
+#define abrr swizzle(glm::W, glm::Z, glm::X, glm::X)
+#define rarr swizzle(glm::X, glm::W, glm::X, glm::X)
+#define garr swizzle(glm::Y, glm::W, glm::X, glm::X)
+#define barr swizzle(glm::Z, glm::W, glm::X, glm::X)
+#define aarr swizzle(glm::W, glm::W, glm::X, glm::X)
+#define rrgr swizzle(glm::X, glm::X, glm::Y, glm::X)
+#define grgr swizzle(glm::Y, glm::X, glm::Y, glm::X)
+#define brgr swizzle(glm::Z, glm::X, glm::Y, glm::X)
+#define argr swizzle(glm::W, glm::X, glm::Y, glm::X)
+#define rggr swizzle(glm::X, glm::Y, glm::Y, glm::X)
+#define gggr swizzle(glm::Y, glm::Y, glm::Y, glm::X)
+#define bggr swizzle(glm::Z, glm::Y, glm::Y, glm::X)
+#define aggr swizzle(glm::W, glm::Y, glm::Y, glm::X)
+#define rbgr swizzle(glm::X, glm::Z, glm::Y, glm::X)
+#define gbgr swizzle(glm::Y, glm::Z, glm::Y, glm::X)
+#define bbgr swizzle(glm::Z, glm::Z, glm::Y, glm::X)
+#define abgr swizzle(glm::W, glm::Z, glm::Y, glm::X)
+#define ragr swizzle(glm::X, glm::W, glm::Y, glm::X)
+#define gagr swizzle(glm::Y, glm::W, glm::Y, glm::X)
+#define bagr swizzle(glm::Z, glm::W, glm::Y, glm::X)
+#define aagr swizzle(glm::W, glm::W, glm::Y, glm::X)
+#define rrbr swizzle(glm::X, glm::X, glm::Z, glm::X)
+#define grbr swizzle(glm::Y, glm::X, glm::Z, glm::X)
+#define brbr swizzle(glm::Z, glm::X, glm::Z, glm::X)
+#define arbr swizzle(glm::W, glm::X, glm::Z, glm::X)
+#define rgbr swizzle(glm::X, glm::Y, glm::Z, glm::X)
+#define ggbr swizzle(glm::Y, glm::Y, glm::Z, glm::X)
+#define bgbr swizzle(glm::Z, glm::Y, glm::Z, glm::X)
+#define agbr swizzle(glm::W, glm::Y, glm::Z, glm::X)
+#define rbbr swizzle(glm::X, glm::Z, glm::Z, glm::X)
+#define gbbr swizzle(glm::Y, glm::Z, glm::Z, glm::X)
+#define bbbr swizzle(glm::Z, glm::Z, glm::Z, glm::X)
+#define abbr swizzle(glm::W, glm::Z, glm::Z, glm::X)
+#define rabr swizzle(glm::X, glm::W, glm::Z, glm::X)
+#define gabr swizzle(glm::Y, glm::W, glm::Z, glm::X)
+#define babr swizzle(glm::Z, glm::W, glm::Z, glm::X)
+#define aabr swizzle(glm::W, glm::W, glm::Z, glm::X)
+#define rrar swizzle(glm::X, glm::X, glm::W, glm::X)
+#define grar swizzle(glm::Y, glm::X, glm::W, glm::X)
+#define brar swizzle(glm::Z, glm::X, glm::W, glm::X)
+#define arar swizzle(glm::W, glm::X, glm::W, glm::X)
+#define rgar swizzle(glm::X, glm::Y, glm::W, glm::X)
+#define ggar swizzle(glm::Y, glm::Y, glm::W, glm::X)
+#define bgar swizzle(glm::Z, glm::Y, glm::W, glm::X)
+#define agar swizzle(glm::W, glm::Y, glm::W, glm::X)
+#define rbar swizzle(glm::X, glm::Z, glm::W, glm::X)
+#define gbar swizzle(glm::Y, glm::Z, glm::W, glm::X)
+#define bbar swizzle(glm::Z, glm::Z, glm::W, glm::X)
+#define abar swizzle(glm::W, glm::Z, glm::W, glm::X)
+#define raar swizzle(glm::X, glm::W, glm::W, glm::X)
+#define gaar swizzle(glm::Y, glm::W, glm::W, glm::X)
+#define baar swizzle(glm::Z, glm::W, glm::W, glm::X)
+#define aaar swizzle(glm::W, glm::W, glm::W, glm::X)
+#define rrrg swizzle(glm::X, glm::X, glm::X, glm::Y)
+#define grrg swizzle(glm::Y, glm::X, glm::X, glm::Y)
+#define brrg swizzle(glm::Z, glm::X, glm::X, glm::Y)
+#define arrg swizzle(glm::W, glm::X, glm::X, glm::Y)
+#define rgrg swizzle(glm::X, glm::Y, glm::X, glm::Y)
+#define ggrg swizzle(glm::Y, glm::Y, glm::X, glm::Y)
+#define bgrg swizzle(glm::Z, glm::Y, glm::X, glm::Y)
+#define agrg swizzle(glm::W, glm::Y, glm::X, glm::Y)
+#define rbrg swizzle(glm::X, glm::Z, glm::X, glm::Y)
+#define gbrg swizzle(glm::Y, glm::Z, glm::X, glm::Y)
+#define bbrg swizzle(glm::Z, glm::Z, glm::X, glm::Y)
+#define abrg swizzle(glm::W, glm::Z, glm::X, glm::Y)
+#define rarg swizzle(glm::X, glm::W, glm::X, glm::Y)
+#define garg swizzle(glm::Y, glm::W, glm::X, glm::Y)
+#define barg swizzle(glm::Z, glm::W, glm::X, glm::Y)
+#define aarg swizzle(glm::W, glm::W, glm::X, glm::Y)
+#define rrgg swizzle(glm::X, glm::X, glm::Y, glm::Y)
+#define grgg swizzle(glm::Y, glm::X, glm::Y, glm::Y)
+#define brgg swizzle(glm::Z, glm::X, glm::Y, glm::Y)
+#define argg swizzle(glm::W, glm::X, glm::Y, glm::Y)
+#define rggg swizzle(glm::X, glm::Y, glm::Y, glm::Y)
+#define gggg swizzle(glm::Y, glm::Y, glm::Y, glm::Y)
+#define bggg swizzle(glm::Z, glm::Y, glm::Y, glm::Y)
+#define aggg swizzle(glm::W, glm::Y, glm::Y, glm::Y)
+#define rbgg swizzle(glm::X, glm::Z, glm::Y, glm::Y)
+#define gbgg swizzle(glm::Y, glm::Z, glm::Y, glm::Y)
+#define bbgg swizzle(glm::Z, glm::Z, glm::Y, glm::Y)
+#define abgg swizzle(glm::W, glm::Z, glm::Y, glm::Y)
+#define ragg swizzle(glm::X, glm::W, glm::Y, glm::Y)
+#define gagg swizzle(glm::Y, glm::W, glm::Y, glm::Y)
+#define bagg swizzle(glm::Z, glm::W, glm::Y, glm::Y)
+#define aagg swizzle(glm::W, glm::W, glm::Y, glm::Y)
+#define rrbg swizzle(glm::X, glm::X, glm::Z, glm::Y)
+#define grbg swizzle(glm::Y, glm::X, glm::Z, glm::Y)
+#define brbg swizzle(glm::Z, glm::X, glm::Z, glm::Y)
+#define arbg swizzle(glm::W, glm::X, glm::Z, glm::Y)
+#define rgbg swizzle(glm::X, glm::Y, glm::Z, glm::Y)
+#define ggbg swizzle(glm::Y, glm::Y, glm::Z, glm::Y)
+#define bgbg swizzle(glm::Z, glm::Y, glm::Z, glm::Y)
+#define agbg swizzle(glm::W, glm::Y, glm::Z, glm::Y)
+#define rbbg swizzle(glm::X, glm::Z, glm::Z, glm::Y)
+#define gbbg swizzle(glm::Y, glm::Z, glm::Z, glm::Y)
+#define bbbg swizzle(glm::Z, glm::Z, glm::Z, glm::Y)
+#define abbg swizzle(glm::W, glm::Z, glm::Z, glm::Y)
+#define rabg swizzle(glm::X, glm::W, glm::Z, glm::Y)
+#define gabg swizzle(glm::Y, glm::W, glm::Z, glm::Y)
+#define babg swizzle(glm::Z, glm::W, glm::Z, glm::Y)
+#define aabg swizzle(glm::W, glm::W, glm::Z, glm::Y)
+#define rrag swizzle(glm::X, glm::X, glm::W, glm::Y)
+#define grag swizzle(glm::Y, glm::X, glm::W, glm::Y)
+#define brag swizzle(glm::Z, glm::X, glm::W, glm::Y)
+#define arag swizzle(glm::W, glm::X, glm::W, glm::Y)
+#define rgag swizzle(glm::X, glm::Y, glm::W, glm::Y)
+#define ggag swizzle(glm::Y, glm::Y, glm::W, glm::Y)
+#define bgag swizzle(glm::Z, glm::Y, glm::W, glm::Y)
+#define agag swizzle(glm::W, glm::Y, glm::W, glm::Y)
+#define rbag swizzle(glm::X, glm::Z, glm::W, glm::Y)
+#define gbag swizzle(glm::Y, glm::Z, glm::W, glm::Y)
+#define bbag swizzle(glm::Z, glm::Z, glm::W, glm::Y)
+#define abag swizzle(glm::W, glm::Z, glm::W, glm::Y)
+#define raag swizzle(glm::X, glm::W, glm::W, glm::Y)
+#define gaag swizzle(glm::Y, glm::W, glm::W, glm::Y)
+#define baag swizzle(glm::Z, glm::W, glm::W, glm::Y)
+#define aaag swizzle(glm::W, glm::W, glm::W, glm::Y)
+#define rrrb swizzle(glm::X, glm::X, glm::X, glm::Z)
+#define grrb swizzle(glm::Y, glm::X, glm::X, glm::Z)
+#define brrb swizzle(glm::Z, glm::X, glm::X, glm::Z)
+#define arrb swizzle(glm::W, glm::X, glm::X, glm::Z)
+#define rgrb swizzle(glm::X, glm::Y, glm::X, glm::Z)
+#define ggrb swizzle(glm::Y, glm::Y, glm::X, glm::Z)
+#define bgrb swizzle(glm::Z, glm::Y, glm::X, glm::Z)
+#define agrb swizzle(glm::W, glm::Y, glm::X, glm::Z)
+#define rbrb swizzle(glm::X, glm::Z, glm::X, glm::Z)
+#define gbrb swizzle(glm::Y, glm::Z, glm::X, glm::Z)
+#define bbrb swizzle(glm::Z, glm::Z, glm::X, glm::Z)
+#define abrb swizzle(glm::W, glm::Z, glm::X, glm::Z)
+#define rarb swizzle(glm::X, glm::W, glm::X, glm::Z)
+#define garb swizzle(glm::Y, glm::W, glm::X, glm::Z)
+#define barb swizzle(glm::Z, glm::W, glm::X, glm::Z)
+#define aarb swizzle(glm::W, glm::W, glm::X, glm::Z)
+#define rrgb swizzle(glm::X, glm::X, glm::Y, glm::Z)
+#define grgb swizzle(glm::Y, glm::X, glm::Y, glm::Z)
+#define brgb swizzle(glm::Z, glm::X, glm::Y, glm::Z)
+#define argb swizzle(glm::W, glm::X, glm::Y, glm::Z)
+#define rggb swizzle(glm::X, glm::Y, glm::Y, glm::Z)
+#define gggb swizzle(glm::Y, glm::Y, glm::Y, glm::Z)
+#define bggb swizzle(glm::Z, glm::Y, glm::Y, glm::Z)
+#define aggb swizzle(glm::W, glm::Y, glm::Y, glm::Z)
+#define rbgb swizzle(glm::X, glm::Z, glm::Y, glm::Z)
+#define gbgb swizzle(glm::Y, glm::Z, glm::Y, glm::Z)
+#define bbgb swizzle(glm::Z, glm::Z, glm::Y, glm::Z)
+#define abgb swizzle(glm::W, glm::Z, glm::Y, glm::Z)
+#define ragb swizzle(glm::X, glm::W, glm::Y, glm::Z)
+#define gagb swizzle(glm::Y, glm::W, glm::Y, glm::Z)
+#define bagb swizzle(glm::Z, glm::W, glm::Y, glm::Z)
+#define aagb swizzle(glm::W, glm::W, glm::Y, glm::Z)
+#define rrbb swizzle(glm::X, glm::X, glm::Z, glm::Z)
+#define grbb swizzle(glm::Y, glm::X, glm::Z, glm::Z)
+#define brbb swizzle(glm::Z, glm::X, glm::Z, glm::Z)
+#define arbb swizzle(glm::W, glm::X, glm::Z, glm::Z)
+#define rgbb swizzle(glm::X, glm::Y, glm::Z, glm::Z)
+#define ggbb swizzle(glm::Y, glm::Y, glm::Z, glm::Z)
+#define bgbb swizzle(glm::Z, glm::Y, glm::Z, glm::Z)
+#define agbb swizzle(glm::W, glm::Y, glm::Z, glm::Z)
+#define rbbb swizzle(glm::X, glm::Z, glm::Z, glm::Z)
+#define gbbb swizzle(glm::Y, glm::Z, glm::Z, glm::Z)
+#define bbbb swizzle(glm::Z, glm::Z, glm::Z, glm::Z)
+#define abbb swizzle(glm::W, glm::Z, glm::Z, glm::Z)
+#define rabb swizzle(glm::X, glm::W, glm::Z, glm::Z)
+#define gabb swizzle(glm::Y, glm::W, glm::Z, glm::Z)
+#define babb swizzle(glm::Z, glm::W, glm::Z, glm::Z)
+#define aabb swizzle(glm::W, glm::W, glm::Z, glm::Z)
+#define rrab swizzle(glm::X, glm::X, glm::W, glm::Z)
+#define grab swizzle(glm::Y, glm::X, glm::W, glm::Z)
+#define brab swizzle(glm::Z, glm::X, glm::W, glm::Z)
+#define arab swizzle(glm::W, glm::X, glm::W, glm::Z)
+#define rgab swizzle(glm::X, glm::Y, glm::W, glm::Z)
+#define ggab swizzle(glm::Y, glm::Y, glm::W, glm::Z)
+#define bgab swizzle(glm::Z, glm::Y, glm::W, glm::Z)
+#define agab swizzle(glm::W, glm::Y, glm::W, glm::Z)
+#define rbab swizzle(glm::X, glm::Z, glm::W, glm::Z)
+#define gbab swizzle(glm::Y, glm::Z, glm::W, glm::Z)
+#define bbab swizzle(glm::Z, glm::Z, glm::W, glm::Z)
+#define abab swizzle(glm::W, glm::Z, glm::W, glm::Z)
+#define raab swizzle(glm::X, glm::W, glm::W, glm::Z)
+#define gaab swizzle(glm::Y, glm::W, glm::W, glm::Z)
+#define baab swizzle(glm::Z, glm::W, glm::W, glm::Z)
+#define aaab swizzle(glm::W, glm::W, glm::W, glm::Z)
+#define rrra swizzle(glm::X, glm::X, glm::X, glm::W)
+#define grra swizzle(glm::Y, glm::X, glm::X, glm::W)
+#define brra swizzle(glm::Z, glm::X, glm::X, glm::W)
+#define arra swizzle(glm::W, glm::X, glm::X, glm::W)
+#define rgra swizzle(glm::X, glm::Y, glm::X, glm::W)
+#define ggra swizzle(glm::Y, glm::Y, glm::X, glm::W)
+#define bgra swizzle(glm::Z, glm::Y, glm::X, glm::W)
+#define agra swizzle(glm::W, glm::Y, glm::X, glm::W)
+#define rbra swizzle(glm::X, glm::Z, glm::X, glm::W)
+#define gbra swizzle(glm::Y, glm::Z, glm::X, glm::W)
+#define bbra swizzle(glm::Z, glm::Z, glm::X, glm::W)
+#define abra swizzle(glm::W, glm::Z, glm::X, glm::W)
+#define rara swizzle(glm::X, glm::W, glm::X, glm::W)
+#define gara swizzle(glm::Y, glm::W, glm::X, glm::W)
+#define bara swizzle(glm::Z, glm::W, glm::X, glm::W)
+#define aara swizzle(glm::W, glm::W, glm::X, glm::W)
+#define rrga swizzle(glm::X, glm::X, glm::Y, glm::W)
+#define grga swizzle(glm::Y, glm::X, glm::Y, glm::W)
+#define brga swizzle(glm::Z, glm::X, glm::Y, glm::W)
+#define arga swizzle(glm::W, glm::X, glm::Y, glm::W)
+#define rgga swizzle(glm::X, glm::Y, glm::Y, glm::W)
+#define ggga swizzle(glm::Y, glm::Y, glm::Y, glm::W)
+#define bgga swizzle(glm::Z, glm::Y, glm::Y, glm::W)
+#define agga swizzle(glm::W, glm::Y, glm::Y, glm::W)
+#define rbga swizzle(glm::X, glm::Z, glm::Y, glm::W)
+#define gbga swizzle(glm::Y, glm::Z, glm::Y, glm::W)
+#define bbga swizzle(glm::Z, glm::Z, glm::Y, glm::W)
+#define abga swizzle(glm::W, glm::Z, glm::Y, glm::W)
+#define raga swizzle(glm::X, glm::W, glm::Y, glm::W)
+#define gaga swizzle(glm::Y, glm::W, glm::Y, glm::W)
+#define baga swizzle(glm::Z, glm::W, glm::Y, glm::W)
+#define aaga swizzle(glm::W, glm::W, glm::Y, glm::W)
+#define rrba swizzle(glm::X, glm::X, glm::Z, glm::W)
+#define grba swizzle(glm::Y, glm::X, glm::Z, glm::W)
+#define brba swizzle(glm::Z, glm::X, glm::Z, glm::W)
+#define arba swizzle(glm::W, glm::X, glm::Z, glm::W)
+#define rgba swizzle(glm::X, glm::Y, glm::Z, glm::W)
+#define ggba swizzle(glm::Y, glm::Y, glm::Z, glm::W)
+#define bgba swizzle(glm::Z, glm::Y, glm::Z, glm::W)
+#define agba swizzle(glm::W, glm::Y, glm::Z, glm::W)
+#define rbba swizzle(glm::X, glm::Z, glm::Z, glm::W)
+#define gbba swizzle(glm::Y, glm::Z, glm::Z, glm::W)
+#define bbba swizzle(glm::Z, glm::Z, glm::Z, glm::W)
+#define abba swizzle(glm::W, glm::Z, glm::Z, glm::W)
+#define raba swizzle(glm::X, glm::W, glm::Z, glm::W)
+#define gaba swizzle(glm::Y, glm::W, glm::Z, glm::W)
+#define baba swizzle(glm::Z, glm::W, glm::Z, glm::W)
+#define aaba swizzle(glm::W, glm::W, glm::Z, glm::W)
+#define rraa swizzle(glm::X, glm::X, glm::W, glm::W)
+#define graa swizzle(glm::Y, glm::X, glm::W, glm::W)
+#define braa swizzle(glm::Z, glm::X, glm::W, glm::W)
+#define araa swizzle(glm::W, glm::X, glm::W, glm::W)
+#define rgaa swizzle(glm::X, glm::Y, glm::W, glm::W)
+#define ggaa swizzle(glm::Y, glm::Y, glm::W, glm::W)
+#define bgaa swizzle(glm::Z, glm::Y, glm::W, glm::W)
+#define agaa swizzle(glm::W, glm::Y, glm::W, glm::W)
+#define rbaa swizzle(glm::X, glm::Z, glm::W, glm::W)
+#define gbaa swizzle(glm::Y, glm::Z, glm::W, glm::W)
+#define bbaa swizzle(glm::Z, glm::Z, glm::W, glm::W)
+#define abaa swizzle(glm::W, glm::Z, glm::W, glm::W)
+#define raaa swizzle(glm::X, glm::W, glm::W, glm::W)
+#define gaaa swizzle(glm::Y, glm::W, glm::W, glm::W)
+#define baaa swizzle(glm::Z, glm::W, glm::W, glm::W)
+#define aaaa swizzle(glm::W, glm::W, glm::W, glm::W)
+
+#endif
+
+#if(defined(GLM_FORCE_SWIZZLE_STPQ) || defined(GLM_SWIZZLE))
+
+#define ssss swizzle(glm::X, glm::X, glm::X, glm::X)
+#define tsss swizzle(glm::Y, glm::X, glm::X, glm::X)
+#define psss swizzle(glm::Z, glm::X, glm::X, glm::X)
+#define qsss swizzle(glm::W, glm::X, glm::X, glm::X)
+#define stss swizzle(glm::X, glm::Y, glm::X, glm::X)
+#define ttss swizzle(glm::Y, glm::Y, glm::X, glm::X)
+#define ptss swizzle(glm::Z, glm::Y, glm::X, glm::X)
+#define qtss swizzle(glm::W, glm::Y, glm::X, glm::X)
+#define spss swizzle(glm::X, glm::Z, glm::X, glm::X)
+#define tpss swizzle(glm::Y, glm::Z, glm::X, glm::X)
+#define ppss swizzle(glm::Z, glm::Z, glm::X, glm::X)
+#define qpss swizzle(glm::W, glm::Z, glm::X, glm::X)
+#define sqss swizzle(glm::X, glm::W, glm::X, glm::X)
+#define tqss swizzle(glm::Y, glm::W, glm::X, glm::X)
+#define pqss swizzle(glm::Z, glm::W, glm::X, glm::X)
+#define qqss swizzle(glm::W, glm::W, glm::X, glm::X)
+#define ssts swizzle(glm::X, glm::X, glm::Y, glm::X)
+#define tsts swizzle(glm::Y, glm::X, glm::Y, glm::X)
+#define psts swizzle(glm::Z, glm::X, glm::Y, glm::X)
+#define qsts swizzle(glm::W, glm::X, glm::Y, glm::X)
+#define stts swizzle(glm::X, glm::Y, glm::Y, glm::X)
+#define ttts swizzle(glm::Y, glm::Y, glm::Y, glm::X)
+#define ptts swizzle(glm::Z, glm::Y, glm::Y, glm::X)
+#define qtts swizzle(glm::W, glm::Y, glm::Y, glm::X)
+#define spts swizzle(glm::X, glm::Z, glm::Y, glm::X)
+#define tpts swizzle(glm::Y, glm::Z, glm::Y, glm::X)
+#define ppts swizzle(glm::Z, glm::Z, glm::Y, glm::X)
+#define qpts swizzle(glm::W, glm::Z, glm::Y, glm::X)
+#define sqts swizzle(glm::X, glm::W, glm::Y, glm::X)
+#define tqts swizzle(glm::Y, glm::W, glm::Y, glm::X)
+#define pqts swizzle(glm::Z, glm::W, glm::Y, glm::X)
+#define qqts swizzle(glm::W, glm::W, glm::Y, glm::X)
+#define ssps swizzle(glm::X, glm::X, glm::Z, glm::X)
+#define tsps swizzle(glm::Y, glm::X, glm::Z, glm::X)
+#define psps swizzle(glm::Z, glm::X, glm::Z, glm::X)
+#define qsps swizzle(glm::W, glm::X, glm::Z, glm::X)
+#define stps swizzle(glm::X, glm::Y, glm::Z, glm::X)
+#define ttps swizzle(glm::Y, glm::Y, glm::Z, glm::X)
+#define ptps swizzle(glm::Z, glm::Y, glm::Z, glm::X)
+#define qtps swizzle(glm::W, glm::Y, glm::Z, glm::X)
+#define spps swizzle(glm::X, glm::Z, glm::Z, glm::X)
+#define tpps swizzle(glm::Y, glm::Z, glm::Z, glm::X)
+#define ppps swizzle(glm::Z, glm::Z, glm::Z, glm::X)
+#define qpps swizzle(glm::W, glm::Z, glm::Z, glm::X)
+#define sqps swizzle(glm::X, glm::W, glm::Z, glm::X)
+#define tqps swizzle(glm::Y, glm::W, glm::Z, glm::X)
+#define pqps swizzle(glm::Z, glm::W, glm::Z, glm::X)
+#define qqps swizzle(glm::W, glm::W, glm::Z, glm::X)
+#define ssqs swizzle(glm::X, glm::X, glm::W, glm::X)
+#define tsqs swizzle(glm::Y, glm::X, glm::W, glm::X)
+#define psqs swizzle(glm::Z, glm::X, glm::W, glm::X)
+#define qsqs swizzle(glm::W, glm::X, glm::W, glm::X)
+#define stqs swizzle(glm::X, glm::Y, glm::W, glm::X)
+#define ttqs swizzle(glm::Y, glm::Y, glm::W, glm::X)
+#define ptqs swizzle(glm::Z, glm::Y, glm::W, glm::X)
+#define qtqs swizzle(glm::W, glm::Y, glm::W, glm::X)
+#define spqs swizzle(glm::X, glm::Z, glm::W, glm::X)
+#define tpqs swizzle(glm::Y, glm::Z, glm::W, glm::X)
+#define ppqs swizzle(glm::Z, glm::Z, glm::W, glm::X)
+#define qpqs swizzle(glm::W, glm::Z, glm::W, glm::X)
+#define sqqs swizzle(glm::X, glm::W, glm::W, glm::X)
+#define tqqs swizzle(glm::Y, glm::W, glm::W, glm::X)
+#define pqqs swizzle(glm::Z, glm::W, glm::W, glm::X)
+#define qqqs swizzle(glm::W, glm::W, glm::W, glm::X)
+#define ssst swizzle(glm::X, glm::X, glm::X, glm::Y)
+#define tsst swizzle(glm::Y, glm::X, glm::X, glm::Y)
+#define psst swizzle(glm::Z, glm::X, glm::X, glm::Y)
+#define qsst swizzle(glm::W, glm::X, glm::X, glm::Y)
+#define stst swizzle(glm::X, glm::Y, glm::X, glm::Y)
+#define ttst swizzle(glm::Y, glm::Y, glm::X, glm::Y)
+#define ptst swizzle(glm::Z, glm::Y, glm::X, glm::Y)
+#define qtst swizzle(glm::W, glm::Y, glm::X, glm::Y)
+#define spst swizzle(glm::X, glm::Z, glm::X, glm::Y)
+#define tpst swizzle(glm::Y, glm::Z, glm::X, glm::Y)
+#define ppst swizzle(glm::Z, glm::Z, glm::X, glm::Y)
+#define qpst swizzle(glm::W, glm::Z, glm::X, glm::Y)
+#define sqst swizzle(glm::X, glm::W, glm::X, glm::Y)
+#define tqst swizzle(glm::Y, glm::W, glm::X, glm::Y)
+#define pqst swizzle(glm::Z, glm::W, glm::X, glm::Y)
+#define qqst swizzle(glm::W, glm::W, glm::X, glm::Y)
+#define sstt swizzle(glm::X, glm::X, glm::Y, glm::Y)
+#define tstt swizzle(glm::Y, glm::X, glm::Y, glm::Y)
+#define pstt swizzle(glm::Z, glm::X, glm::Y, glm::Y)
+#define qstt swizzle(glm::W, glm::X, glm::Y, glm::Y)
+#define sttt swizzle(glm::X, glm::Y, glm::Y, glm::Y)
+#define tttt swizzle(glm::Y, glm::Y, glm::Y, glm::Y)
+#define pttt swizzle(glm::Z, glm::Y, glm::Y, glm::Y)
+#define qttt swizzle(glm::W, glm::Y, glm::Y, glm::Y)
+#define sptt swizzle(glm::X, glm::Z, glm::Y, glm::Y)
+#define tptt swizzle(glm::Y, glm::Z, glm::Y, glm::Y)
+#define pptt swizzle(glm::Z, glm::Z, glm::Y, glm::Y)
+#define qptt swizzle(glm::W, glm::Z, glm::Y, glm::Y)
+#define sqtt swizzle(glm::X, glm::W, glm::Y, glm::Y)
+#define tqtt swizzle(glm::Y, glm::W, glm::Y, glm::Y)
+#define pqtt swizzle(glm::Z, glm::W, glm::Y, glm::Y)
+#define qqtt swizzle(glm::W, glm::W, glm::Y, glm::Y)
+#define sspt swizzle(glm::X, glm::X, glm::Z, glm::Y)
+#define tspt swizzle(glm::Y, glm::X, glm::Z, glm::Y)
+#define pspt swizzle(glm::Z, glm::X, glm::Z, glm::Y)
+#define qspt swizzle(glm::W, glm::X, glm::Z, glm::Y)
+#define stpt swizzle(glm::X, glm::Y, glm::Z, glm::Y)
+#define ttpt swizzle(glm::Y, glm::Y, glm::Z, glm::Y)
+#define ptpt swizzle(glm::Z, glm::Y, glm::Z, glm::Y)
+#define qtpt swizzle(glm::W, glm::Y, glm::Z, glm::Y)
+#define sppt swizzle(glm::X, glm::Z, glm::Z, glm::Y)
+#define tppt swizzle(glm::Y, glm::Z, glm::Z, glm::Y)
+#define pppt swizzle(glm::Z, glm::Z, glm::Z, glm::Y)
+#define qppt swizzle(glm::W, glm::Z, glm::Z, glm::Y)
+#define sqpt swizzle(glm::X, glm::W, glm::Z, glm::Y)
+#define tqpt swizzle(glm::Y, glm::W, glm::Z, glm::Y)
+#define pqpt swizzle(glm::Z, glm::W, glm::Z, glm::Y)
+#define qqpt swizzle(glm::W, glm::W, glm::Z, glm::Y)
+#define ssqt swizzle(glm::X, glm::X, glm::W, glm::Y)
+#define tsqt swizzle(glm::Y, glm::X, glm::W, glm::Y)
+#define psqt swizzle(glm::Z, glm::X, glm::W, glm::Y)
+#define qsqt swizzle(glm::W, glm::X, glm::W, glm::Y)
+#define stqt swizzle(glm::X, glm::Y, glm::W, glm::Y)
+#define ttqt swizzle(glm::Y, glm::Y, glm::W, glm::Y)
+#define ptqt swizzle(glm::Z, glm::Y, glm::W, glm::Y)
+#define qtqt swizzle(glm::W, glm::Y, glm::W, glm::Y)
+#define spqt swizzle(glm::X, glm::Z, glm::W, glm::Y)
+#define tpqt swizzle(glm::Y, glm::Z, glm::W, glm::Y)
+#define ppqt swizzle(glm::Z, glm::Z, glm::W, glm::Y)
+#define qpqt swizzle(glm::W, glm::Z, glm::W, glm::Y)
+#define sqqt swizzle(glm::X, glm::W, glm::W, glm::Y)
+#define tqqt swizzle(glm::Y, glm::W, glm::W, glm::Y)
+#define pqqt swizzle(glm::Z, glm::W, glm::W, glm::Y)
+#define qqqt swizzle(glm::W, glm::W, glm::W, glm::Y)
+#define sssp swizzle(glm::X, glm::X, glm::X, glm::Z)
+#define tssp swizzle(glm::Y, glm::X, glm::X, glm::Z)
+#define pssp swizzle(glm::Z, glm::X, glm::X, glm::Z)
+#define qssp swizzle(glm::W, glm::X, glm::X, glm::Z)
+#define stsp swizzle(glm::X, glm::Y, glm::X, glm::Z)
+#define ttsp swizzle(glm::Y, glm::Y, glm::X, glm::Z)
+#define ptsp swizzle(glm::Z, glm::Y, glm::X, glm::Z)
+#define qtsp swizzle(glm::W, glm::Y, glm::X, glm::Z)
+#define spsp swizzle(glm::X, glm::Z, glm::X, glm::Z)
+#define tpsp swizzle(glm::Y, glm::Z, glm::X, glm::Z)
+#define ppsp swizzle(glm::Z, glm::Z, glm::X, glm::Z)
+#define qpsp swizzle(glm::W, glm::Z, glm::X, glm::Z)
+#define sqsp swizzle(glm::X, glm::W, glm::X, glm::Z)
+#define tqsp swizzle(glm::Y, glm::W, glm::X, glm::Z)
+#define pqsp swizzle(glm::Z, glm::W, glm::X, glm::Z)
+#define qqsp swizzle(glm::W, glm::W, glm::X, glm::Z)
+#define sstp swizzle(glm::X, glm::X, glm::Y, glm::Z)
+#define tstp swizzle(glm::Y, glm::X, glm::Y, glm::Z)
+#define pstp swizzle(glm::Z, glm::X, glm::Y, glm::Z)
+#define qstp swizzle(glm::W, glm::X, glm::Y, glm::Z)
+#define sttp swizzle(glm::X, glm::Y, glm::Y, glm::Z)
+#define tttp swizzle(glm::Y, glm::Y, glm::Y, glm::Z)
+#define pttp swizzle(glm::Z, glm::Y, glm::Y, glm::Z)
+#define qttp swizzle(glm::W, glm::Y, glm::Y, glm::Z)
+#define sptp swizzle(glm::X, glm::Z, glm::Y, glm::Z)
+#define tptp swizzle(glm::Y, glm::Z, glm::Y, glm::Z)
+#define pptp swizzle(glm::Z, glm::Z, glm::Y, glm::Z)
+#define qptp swizzle(glm::W, glm::Z, glm::Y, glm::Z)
+#define sqtp swizzle(glm::X, glm::W, glm::Y, glm::Z)
+#define tqtp swizzle(glm::Y, glm::W, glm::Y, glm::Z)
+#define pqtp swizzle(glm::Z, glm::W, glm::Y, glm::Z)
+#define qqtp swizzle(glm::W, glm::W, glm::Y, glm::Z)
+#define sspp swizzle(glm::X, glm::X, glm::Z, glm::Z)
+#define tspp swizzle(glm::Y, glm::X, glm::Z, glm::Z)
+#define pspp swizzle(glm::Z, glm::X, glm::Z, glm::Z)
+#define qspp swizzle(glm::W, glm::X, glm::Z, glm::Z)
+#define stpp swizzle(glm::X, glm::Y, glm::Z, glm::Z)
+#define ttpp swizzle(glm::Y, glm::Y, glm::Z, glm::Z)
+#define ptpp swizzle(glm::Z, glm::Y, glm::Z, glm::Z)
+#define qtpp swizzle(glm::W, glm::Y, glm::Z, glm::Z)
+#define sppp swizzle(glm::X, glm::Z, glm::Z, glm::Z)
+#define tppp swizzle(glm::Y, glm::Z, glm::Z, glm::Z)
+#define pppp swizzle(glm::Z, glm::Z, glm::Z, glm::Z)
+#define qppp swizzle(glm::W, glm::Z, glm::Z, glm::Z)
+#define sqpp swizzle(glm::X, glm::W, glm::Z, glm::Z)
+#define tqpp swizzle(glm::Y, glm::W, glm::Z, glm::Z)
+#define pqpp swizzle(glm::Z, glm::W, glm::Z, glm::Z)
+#define qqpp swizzle(glm::W, glm::W, glm::Z, glm::Z)
+#define ssqp swizzle(glm::X, glm::X, glm::W, glm::Z)
+#define tsqp swizzle(glm::Y, glm::X, glm::W, glm::Z)
+#define psqp swizzle(glm::Z, glm::X, glm::W, glm::Z)
+#define qsqp swizzle(glm::W, glm::X, glm::W, glm::Z)
+#define stqp swizzle(glm::X, glm::Y, glm::W, glm::Z)
+#define ttqp swizzle(glm::Y, glm::Y, glm::W, glm::Z)
+#define ptqp swizzle(glm::Z, glm::Y, glm::W, glm::Z)
+#define qtqp swizzle(glm::W, glm::Y, glm::W, glm::Z)
+#define spqp swizzle(glm::X, glm::Z, glm::W, glm::Z)
+#define tpqp swizzle(glm::Y, glm::Z, glm::W, glm::Z)
+#define ppqp swizzle(glm::Z, glm::Z, glm::W, glm::Z)
+#define qpqp swizzle(glm::W, glm::Z, glm::W, glm::Z)
+#define sqqp swizzle(glm::X, glm::W, glm::W, glm::Z)
+#define tqqp swizzle(glm::Y, glm::W, glm::W, glm::Z)
+#define pqqp swizzle(glm::Z, glm::W, glm::W, glm::Z)
+#define qqqp swizzle(glm::W, glm::W, glm::W, glm::Z)
+#define sssq swizzle(glm::X, glm::X, glm::X, glm::W)
+#define tssq swizzle(glm::Y, glm::X, glm::X, glm::W)
+#define pssq swizzle(glm::Z, glm::X, glm::X, glm::W)
+#define qssq swizzle(glm::W, glm::X, glm::X, glm::W)
+#define stsq swizzle(glm::X, glm::Y, glm::X, glm::W)
+#define ttsq swizzle(glm::Y, glm::Y, glm::X, glm::W)
+#define ptsq swizzle(glm::Z, glm::Y, glm::X, glm::W)
+#define qtsq swizzle(glm::W, glm::Y, glm::X, glm::W)
+#define spsq swizzle(glm::X, glm::Z, glm::X, glm::W)
+#define tpsq swizzle(glm::Y, glm::Z, glm::X, glm::W)
+#define ppsq swizzle(glm::Z, glm::Z, glm::X, glm::W)
+#define qpsq swizzle(glm::W, glm::Z, glm::X, glm::W)
+#define sqsq swizzle(glm::X, glm::W, glm::X, glm::W)
+#define tqsq swizzle(glm::Y, glm::W, glm::X, glm::W)
+#define pqsq swizzle(glm::Z, glm::W, glm::X, glm::W)
+#define qqsq swizzle(glm::W, glm::W, glm::X, glm::W)
+#define sstq swizzle(glm::X, glm::X, glm::Y, glm::W)
+#define tstq swizzle(glm::Y, glm::X, glm::Y, glm::W)
+#define pstq swizzle(glm::Z, glm::X, glm::Y, glm::W)
+#define qstq swizzle(glm::W, glm::X, glm::Y, glm::W)
+#define sttq swizzle(glm::X, glm::Y, glm::Y, glm::W)
+#define tttq swizzle(glm::Y, glm::Y, glm::Y, glm::W)
+#define pttq swizzle(glm::Z, glm::Y, glm::Y, glm::W)
+#define qttq swizzle(glm::W, glm::Y, glm::Y, glm::W)
+#define sptq swizzle(glm::X, glm::Z, glm::Y, glm::W)
+#define tptq swizzle(glm::Y, glm::Z, glm::Y, glm::W)
+#define pptq swizzle(glm::Z, glm::Z, glm::Y, glm::W)
+#define qptq swizzle(glm::W, glm::Z, glm::Y, glm::W)
+#define sqtq swizzle(glm::X, glm::W, glm::Y, glm::W)
+#define tqtq swizzle(glm::Y, glm::W, glm::Y, glm::W)
+#define pqtq swizzle(glm::Z, glm::W, glm::Y, glm::W)
+#define qqtq swizzle(glm::W, glm::W, glm::Y, glm::W)
+#define sspq swizzle(glm::X, glm::X, glm::Z, glm::W)
+#define tspq swizzle(glm::Y, glm::X, glm::Z, glm::W)
+#define pspq swizzle(glm::Z, glm::X, glm::Z, glm::W)
+#define qspq swizzle(glm::W, glm::X, glm::Z, glm::W)
+#define stpq swizzle(glm::X, glm::Y, glm::Z, glm::W)
+#define ttpq swizzle(glm::Y, glm::Y, glm::Z, glm::W)
+#define ptpq swizzle(glm::Z, glm::Y, glm::Z, glm::W)
+#define qtpq swizzle(glm::W, glm::Y, glm::Z, glm::W)
+#define sppq swizzle(glm::X, glm::Z, glm::Z, glm::W)
+#define tppq swizzle(glm::Y, glm::Z, glm::Z, glm::W)
+#define pppq swizzle(glm::Z, glm::Z, glm::Z, glm::W)
+#define qppq swizzle(glm::W, glm::Z, glm::Z, glm::W)
+#define sqpq swizzle(glm::X, glm::W, glm::Z, glm::W)
+#define tqpq swizzle(glm::Y, glm::W, glm::Z, glm::W)
+#define pqpq swizzle(glm::Z, glm::W, glm::Z, glm::W)
+#define qqpq swizzle(glm::W, glm::W, glm::Z, glm::W)
+#define ssqq swizzle(glm::X, glm::X, glm::W, glm::W)
+#define tsqq swizzle(glm::Y, glm::X, glm::W, glm::W)
+#define psqq swizzle(glm::Z, glm::X, glm::W, glm::W)
+#define qsqq swizzle(glm::W, glm::X, glm::W, glm::W)
+#define stqq swizzle(glm::X, glm::Y, glm::W, glm::W)
+#define ttqq swizzle(glm::Y, glm::Y, glm::W, glm::W)
+#define ptqq swizzle(glm::Z, glm::Y, glm::W, glm::W)
+#define qtqq swizzle(glm::W, glm::Y, glm::W, glm::W)
+#define spqq swizzle(glm::X, glm::Z, glm::W, glm::W)
+#define tpqq swizzle(glm::Y, glm::Z, glm::W, glm::W)
+#define ppqq swizzle(glm::Z, glm::Z, glm::W, glm::W)
+#define qpqq swizzle(glm::W, glm::Z, glm::W, glm::W)
+#define sqqq swizzle(glm::X, glm::W, glm::W, glm::W)
+#define tqqq swizzle(glm::Y, glm::W, glm::W, glm::W)
+#define pqqq swizzle(glm::Z, glm::W, glm::W, glm::W)
+#define qqqq swizzle(glm::W, glm::W, glm::W, glm::W)
+
+#endif
+
+#endif//glm_core_swizzle
diff --git a/src/glm/core/dummy.cpp b/src/glm/core/dummy.cpp
new file mode 100644
index 0000000..3c603ff
--- /dev/null
+++ b/src/glm/core/dummy.cpp
@@ -0,0 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2011-01-19
+// Updated : 2011-01-19
+// Licence : This source is under MIT License
+// File : glm/setup.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// GLM is a header only library. There is nothing to compile.
+// dummy.cpp exist only a wordaround for CMake file.
+
+#include "../glm.hpp"
+#include "../ext.hpp"
+
+//#error "GLM is a header only library"
+
+int main()
+{
+
+}
diff --git a/src/glm/core/func_common.hpp b/src/glm/core/func_common.hpp
new file mode 100644
index 0000000..1a233ec
--- /dev/null
+++ b/src/glm/core/func_common.hpp
@@ -0,0 +1,337 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2008-03-08
+// Updated : 2010-01-26
+// Licence : This source is under MIT License
+// File : glm/core/func_common.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_core_func_common
+#define glm_core_func_common
+
+#include "_fixes.hpp"
+
+namespace glm
+{
+ namespace core{
+ namespace function{
+ namespace common{ //!< Define common functions from Section 8.3 of GLSL 1.30.8 specification. Included in glm namespace.
+
+ /// \addtogroup core_funcs
+ ///@{
+
+ //! Returns x if x >= 0; otherwise, it returns -x.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/abs.xml">GLSL abs man page</a>
+ //! \li GLSL 1.30.08 specification, section 8.3
+ template <typename genFIType>
+ genFIType abs(genFIType const & x);
+
+ //! Returns 1.0 if x > 0, 0.0 if x == 0, or -1.0 if x < 0.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/sign.xml">GLSL sign man page</a>
+ //! \li GLSL 1.30.08 specification, section 8.3
+ template <typename genFIType>
+ genFIType sign(genFIType const & x);
+
+ //! Returns a value equal to the nearest integer that is less then or equal to x.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/floor.xml">GLSL floor man page</a>
+ //! \li GLSL 1.30.08 specification, section 8.3
+ template <typename genType>
+ genType floor(genType const & x);
+
+ //! Returns a value equal to the nearest integer to x
+ //! whose absolute value is not larger than the absolute value of x.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/trunc.xml">GLSL trunc man page</a>
+ //! \li GLSL 1.30.08 specification, section 8.3
+ template <typename genType>
+ genType trunc(genType const & x);
+
+ //! Returns a value equal to the nearest integer to x.
+ //! The fraction 0.5 will round in a direction chosen by the
+ //! implementation, presumably the direction that is fastest.
+ //! This includes the possibility that round(x) returns the
+ //! same value as roundEven(x) for all values of x.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/round.xml">GLSL round man page</a>
+ //! \li GLSL 1.30.08 specification, section 8.3
+ template <typename genType>
+ genType round(genType const & x);
+
+ //! Returns a value equal to the nearest integer to x.
+ //! A fractional part of 0.5 will round toward the nearest even
+ //! integer. (Both 3.5 and 4.5 for x will return 4.0.)
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/roundEven.xml">GLSL roundEven man page</a>
+ //! \li GLSL 1.30.08 specification, section 8.3
+ template <typename genType>
+ genType roundEven(genType const & x);
+
+ //! Returns a value equal to the nearest integer
+ //! that is greater than or equal to x.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/ceil.xml">GLSL ceil man page</a>
+ //! \li GLSL 1.30.08 specification, section 8.3
+ template <typename genType>
+ genType ceil(genType const & x);
+
+ //! Return x - floor(x).
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/fract.xml">GLSL fract man page</a>
+ //! \li GLSL 1.30.08 specification, section 8.3
+ template <typename genType>
+ genType fract(genType const & x);
+
+ //! Modulus. Returns x - y * floor(x / y)
+ //! for each component in x using the floating point value y.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/mod.xml">GLSL mod man page</a>
+ //! \li GLSL 1.30.08 specification, section 8.3
+ template <typename genType>
+ genType mod(
+ genType const & x,
+ genType const & y);
+
+ //! Modulus. Returns x - y * floor(x / y)
+ //! for each component in x using the floating point value y.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/mod.xml">GLSL mod man page</a>
+ //! \li GLSL 1.30.08 specification, section 8.3
+ template <typename genType>
+ genType mod(
+ genType const & x,
+ typename genType::value_type const & y);
+
+ //! Returns the fractional part of x and sets i to the integer
+ //! part (as a whole number floating point value). Both the
+ //! return value and the output parameter will have the same
+ //! sign as x.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/modf.xml">GLSL modf man page</a>
+ //! \li GLSL 1.30.08 specification, section 8.3
+ template <typename genType>
+ genType modf(
+ genType const & x,
+ genType & i);
+
+ //! Returns y if y < x; otherwise, it returns x.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/min.xml">GLSL min man page</a>
+ //! \li GLSL 1.30.08 specification, section 8.3
+ template <typename genType>
+ genType min(
+ genType const & x,
+ genType const & y);
+
+ template <typename genType>
+ genType min(
+ genType const & x,
+ typename genType::value_type const & y);
+
+ //! Returns y if x < y; otherwise, it returns x.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/max.xml">GLSL max man page</a>
+ //! \li GLSL 1.30.08 specification, section 8.3
+ template <typename genType>
+ genType max(
+ genType const & x,
+ genType const & y);
+
+ template <typename genType>
+ genType max(
+ genType const & x,
+ typename genType::value_type const & y);
+
+ //! Returns min(max(x, minVal), maxVal) for each component in x
+ //! using the floating-point values minVal and maxVal.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/clamp.xml">GLSL clamp man page</a>
+ //! \li GLSL 1.30.08 specification, section 8.3
+ template <typename genType>
+ genType clamp(
+ genType const & x,
+ genType const & minVal,
+ genType const & maxVal);
+
+ template <typename genType>
+ genType clamp(
+ genType const & x,
+ typename genType::value_type const & minVal,
+ typename genType::value_type const & maxVal);
+
+ //! \return If genTypeU is a floating scalar or vector:
+ //! Returns x * (1.0 - a) + y * a, i.e., the linear blend of
+ //! x and y using the floating-point value a.
+ //! The value for a is not restricted to the range [0, 1].
+ //!
+ //! \return If genTypeU is a boolean scalar or vector:
+ //! Selects which vector each returned component comes
+ //! from. For a component of a that is false, the
+ //! corresponding component of x is returned. For a
+ //! component of a that is true, the corresponding
+ //! component of y is returned. Components of x and y that
+ //! are not selected are allowed to be invalid floating point
+ //! values and will have no effect on the results. Thus, this
+ //! provides different functionality than
+ //! genType mix(genType x, genType y, genType(a))
+ //! where a is a Boolean vector.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/mix.xml">GLSL mix man page</a>
+ //! \li GLSL 1.30.08 specification, section 8.3
+ //!
+ //! \param[in] x Floating point scalar or vector.
+ //! \param[in] y Floating point scalar or vector.
+ //! \param[in] a Floating point or boolean scalar or vector.
+ //!
+ // \todo Test when 'a' is a boolean.
+ template <typename genTypeT, typename genTypeU>
+ genTypeT mix(genTypeT const & x, genTypeT const & y, genTypeU const & a);
+
+ //! Returns 0.0 if x < edge, otherwise it returns 1.0.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/step.xml">GLSL step man page</a>
+ //! \li GLSL 1.30.08 specification, section 8.3
+ template <typename genType>
+ genType step(
+ genType const & edge,
+ genType const & x);
+
+ template <typename genType>
+ genType step(
+ typename genType::value_type const & edge,
+ genType const & x);
+
+ //! Returns 0.0 if x <= edge0 and 1.0 if x >= edge1 and
+ //! performs smooth Hermite interpolation between 0 and 1
+ //! when edge0 < x < edge1. This is useful in cases where
+ //! you would want a threshold function with a smooth
+ //! transition. This is equivalent to:
+ //! genType t;
+ //! t = clamp ((x edge0) / (edge1 edge0), 0, 1);
+ //! return t * t * (3 2 * t);
+ //! Results are undefined if edge0 >= edge1.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/smoothstep.xml">GLSL smoothstep man page</a>
+ //! \li GLSL 1.30.08 specification, section 8.3
+ template <typename genType>
+ genType smoothstep(
+ genType const & edge0,
+ genType const & edge1,
+ genType const & x);
+
+ template <typename genType>
+ genType smoothstep(
+ typename genType::value_type const & edge0,
+ typename genType::value_type const & edge1,
+ genType const & x);
+
+ //! Returns true if x holds a NaN (not a number)
+ //! representation in the underlying implementation's set of
+ //! floating point representations. Returns false otherwise,
+ //! including for implementations with no NaN
+ //! representations.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/isnan.xml">GLSL isnan man page</a>
+ //! \li GLSL 1.30.08 specification, section 8.3
+ template <typename genType>
+ typename genType::bool_type isnan(genType const & x);
+
+ //! Returns true if x holds a positive infinity or negative
+ //! infinity representation in the underlying implementation's
+ //! set of floating point representations. Returns false
+ //! otherwise, including for implementations with no infinity
+ //! representations.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/isinf.xml">GLSL isinf man page</a>
+ //! \li GLSL 1.30.08 specification, section 8.3
+ template <typename genType>
+ typename genType::bool_type isinf(genType const & x);
+
+ //! Returns a signed integer value representing
+ //! the encoding of a floating-point value. The floatingpoint
+ //! value's bit-level representation is preserved.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/floatBitsToInt.xml">GLSL floatBitsToInt man page</a>
+ //! \li GLSL 4.00.08 specification, section 8.3
+ template <typename genType, typename genIType>
+ genIType floatBitsToInt(genType const & value);
+
+ //! Returns a unsigned integer value representing
+ //! the encoding of a floating-point value. The floatingpoint
+ //! value's bit-level representation is preserved.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/floatBitsToUint.xml">GLSL floatBitsToUint man page</a>
+ //! \li GLSL 4.00.08 specification, section 8.3
+ template <typename genType, typename genUType>
+ genUType floatBitsToUint(genType const & value);
+
+ //! Returns a floating-point value corresponding to a signed
+ //! integer encoding of a floating-point value.
+ //! If an inf or NaN is passed in, it will not signal, and the
+ //! resulting floating point value is unspecified. Otherwise,
+ //! the bit-level representation is preserved.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/intBitsToFloat.xml">GLSL intBitsToFloat man page</a>
+ //! \li GLSL 4.00.08 specification, section 8.3
+ template <typename genType, typename genIType>
+ genType intBitsToFloat(genIType const & value);
+
+ //! Returns a floating-point value corresponding to a
+ //! unsigned integer encoding of a floating-point value.
+ //! If an inf or NaN is passed in, it will not signal, and the
+ //! resulting floating point value is unspecified. Otherwise,
+ //! the bit-level representation is preserved.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/uintBitsToFloat.xml">GLSL uintBitsToFloat man page</a>
+ //! \li GLSL 4.00.08 specification, section 8.3
+ template <typename genType, typename genUType>
+ genType uintBitsToFloat(genUType const & value);
+
+ //! Computes and returns a * b + c.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/fma.xml">GLSL fma man page</a>
+ //! \li GLSL 4.00.08 specification, section 8.3
+ template <typename genType>
+ genType fma(genType const & a, genType const & b, genType const & c);
+
+ //! Splits x into a floating-point significand in the range
+ //! [0.5, 1.0) and an integral exponent of two, such that:
+ //! x = significand * exp(2, exponent)
+ //!
+ //! The significand is returned by the function and the
+ //! exponent is returned in the parameter exp. For a
+ //! floating-point value of zero, the significant and exponent
+ //! are both zero. For a floating-point value that is an
+ //! infinity or is not a number, the results are undefined.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/frexp.xml">GLSL frexp man page</a>
+ //! \li GLSL 4.00.08 specification, section 8.3
+ template <typename genType, typename genIType>
+ genType frexp(genType const & x, genIType & exp);
+
+ //! Builds a floating-point number from x and the
+ //! corresponding integral exponent of two in exp, returning:
+ //! significand * exp(2, exponent)
+ //!
+ //! If this product is too large to be represented in the
+ //! floating-point type, the result is undefined.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/ldexp.xml">GLSL ldexp man page</a>;
+ //! \li GLSL 4.00.08 specification, section 8.3
+ template <typename genType, typename genIType>
+ genType ldexp(genType const & x, genIType const & exp);
+
+ ///@}
+ }//namespace common
+ }//namespace function
+ }//namespace core
+
+ using namespace core::function::common;
+}//namespace glm
+
+#include "func_common.inl"
+
+#endif//glm_core_func_common
diff --git a/src/glm/core/func_common.inl b/src/glm/core/func_common.inl
new file mode 100644
index 0000000..38c65c9
--- /dev/null
+++ b/src/glm/core/func_common.inl
@@ -0,0 +1,1577 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2008-08-03
+// Updated : 2010-01-26
+// Licence : This source is under MIT License
+// File : glm/core/func_common.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm
+{
+ namespace detail
+ {
+ template <typename genFIType, bool /*signed*/>
+ struct Abs_
+ {
+ };
+
+ template <typename genFIType>
+ struct Abs_<genFIType, true>
+ {
+ static genFIType get(genFIType const & x)
+ {
+ GLM_STATIC_ASSERT(
+ detail::type<genFIType>::is_float ||
+ detail::type<genFIType>::is_int, "'abs' only accept floating-point and integer inputs");
+ return x >= genFIType(0) ? x : -x;
+ }
+ };
+
+ template <typename genFIType>
+ struct Abs_<genFIType, false>
+ {
+ static genFIType get(genFIType const & x)
+ {
+ GLM_STATIC_ASSERT(
+ detail::type<genFIType>::is_uint, "'abs' only accept floating-point and integer inputs");
+
+ return x;
+ }
+ };
+ }//namespace detail
+
+ namespace core{
+ namespace function{
+ namespace common{
+
+ // abs
+ template <typename genFIType>
+ GLM_FUNC_QUALIFIER genFIType abs(
+ genFIType const & x)
+ {
+ return detail::Abs_<genFIType, std::numeric_limits<genFIType>::is_signed>::get(x);
+ }
+
+ //template <typename T>
+ //GLM_FUNC_QUALIFIER detail::tvec1<T> abs(
+ // detail::tvec1<T> const & v)
+ //{
+ // return detail::tvec1<T>(
+ // abs(v.x));
+ //}
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<T> abs(
+ detail::tvec2<T> const & v)
+ {
+ return detail::tvec2<T>(
+ abs(v.x),
+ abs(v.y));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> abs(
+ detail::tvec3<T> const & v)
+ {
+ return detail::tvec3<T>(
+ abs(v.x),
+ abs(v.y),
+ abs(v.z));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<T> abs(
+ detail::tvec4<T> const & v)
+ {
+ return detail::tvec4<T>(
+ abs(v.x),
+ abs(v.y),
+ abs(v.z),
+ abs(v.w));
+ }
+
+ // sign
+
+ //Try something like based on x >> 31 to get the sign bit
+ template <typename genFIType>
+ GLM_FUNC_QUALIFIER genFIType sign(
+ genFIType const & x)
+ {
+ GLM_STATIC_ASSERT(
+ detail::type<genFIType>::is_float ||
+ detail::type<genFIType>::is_int, "'sign' only accept signed inputs");
+
+ genFIType result;
+ if(x > genFIType(0))
+ result = genFIType(1);
+ else if(x < genFIType(0))
+ result = genFIType(-1);
+ else
+ result = genFIType(0);
+ return result;
+ }
+
+ template <typename valFIType>
+ GLM_FUNC_QUALIFIER detail::tvec2<valFIType> sign(
+ detail::tvec2<valFIType> const & x)
+ {
+ return detail::tvec2<valFIType>(
+ sign(x.x),
+ sign(x.y));
+ }
+
+ template <typename valFIType>
+ GLM_FUNC_QUALIFIER detail::tvec3<valFIType> sign(
+ detail::tvec3<valFIType> const & x)
+ {
+ return detail::tvec3<valFIType>(
+ sign(x.x),
+ sign(x.y),
+ sign(x.z));
+ }
+
+ template <typename valFIType>
+ GLM_FUNC_QUALIFIER detail::tvec4<valFIType> sign(
+ detail::tvec4<valFIType> const & x)
+ {
+ return detail::tvec4<valFIType>(
+ sign(x.x),
+ sign(x.y),
+ sign(x.z),
+ sign(x.w));
+ }
+
+ // floor
+ template <>
+ GLM_FUNC_QUALIFIER detail::thalf floor<detail::thalf>(detail::thalf const& x)
+ {
+ return detail::thalf(::std::floor(float(x)));
+ }
+
+ template <typename genType>
+ GLM_FUNC_QUALIFIER genType floor(genType const& x)
+ {
+ GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'floor' only accept floating-point inputs");
+
+ return ::std::floor(x);
+ }
+
+ template <typename valType>
+ GLM_FUNC_QUALIFIER detail::tvec2<valType> floor(detail::tvec2<valType> const& x)
+ {
+ return detail::tvec2<valType>(
+ floor(x.x),
+ floor(x.y));
+ }
+
+ template <typename valType>
+ GLM_FUNC_QUALIFIER detail::tvec3<valType> floor(detail::tvec3<valType> const& x)
+ {
+ return detail::tvec3<valType>(
+ floor(x.x),
+ floor(x.y),
+ floor(x.z));
+ }
+
+ template <typename valType>
+ GLM_FUNC_QUALIFIER detail::tvec4<valType> floor(detail::tvec4<valType> const& x)
+ {
+ return detail::tvec4<valType>(
+ floor(x.x),
+ floor(x.y),
+ floor(x.z),
+ floor(x.w));
+ }
+
+ // trunc
+ template <typename genType>
+ GLM_FUNC_QUALIFIER genType trunc(genType const & x)
+ {
+ GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'trunc' only accept floating-point inputs");
+ return x < 0 ? -floor(-x) : floor(x);
+ }
+
+ template <typename valType>
+ GLM_FUNC_QUALIFIER detail::tvec2<valType> trunc(detail::tvec2<valType> const & x)
+ {
+ return detail::tvec2<valType>(
+ trunc(x.x),
+ trunc(x.y));
+ }
+
+ template <typename valType>
+ GLM_FUNC_QUALIFIER detail::tvec3<valType> trunc(detail::tvec3<valType> const & x)
+ {
+ return detail::tvec3<valType>(
+ trunc(x.x),
+ trunc(x.y),
+ trunc(x.z));
+ }
+
+ template <typename valType>
+ GLM_FUNC_QUALIFIER detail::tvec4<valType> trunc(detail::tvec4<valType> const & x)
+ {
+ return detail::tvec4<valType>(
+ trunc(x.x),
+ trunc(x.y),
+ trunc(x.z),
+ trunc(x.w));
+ }
+
+ // round
+ template <typename genType>
+ GLM_FUNC_QUALIFIER genType round(genType const& x)
+ {
+ GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'round' only accept floating-point inputs");
+
+ return genType(int(x + genType(0.5)));
+ }
+
+ template <typename valType>
+ GLM_FUNC_QUALIFIER detail::tvec2<valType> round(detail::tvec2<valType> const& x)
+ {
+ return detail::tvec2<valType>(
+ round(x.x),
+ round(x.y));
+ }
+
+ template <typename valType>
+ GLM_FUNC_QUALIFIER detail::tvec3<valType> round(detail::tvec3<valType> const& x)
+ {
+ return detail::tvec3<valType>(
+ round(x.x),
+ round(x.y),
+ round(x.z));
+ }
+
+ template <typename valType>
+ GLM_FUNC_QUALIFIER detail::tvec4<valType> round(detail::tvec4<valType> const& x)
+ {
+ return detail::tvec4<valType>(
+ round(x.x),
+ round(x.y),
+ round(x.z),
+ round(x.w));
+ }
+
+ // roundEven
+ template <typename genType>
+ GLM_FUNC_QUALIFIER genType roundEven(genType const& x)
+ {
+ GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'roundEven' only accept floating-point inputs");
+
+ return genType(int(x + genType(int(x) % 2)));
+ }
+
+ template <typename valType>
+ GLM_FUNC_QUALIFIER detail::tvec2<valType> roundEven(detail::tvec2<valType> const& x)
+ {
+ return detail::tvec2<valType>(
+ roundEven(x.x),
+ roundEven(x.y));
+ }
+
+ template <typename valType>
+ GLM_FUNC_QUALIFIER detail::tvec3<valType> roundEven(detail::tvec3<valType> const& x)
+ {
+ return detail::tvec3<valType>(
+ roundEven(x.x),
+ roundEven(x.y),
+ roundEven(x.z));
+ }
+
+ template <typename valType>
+ GLM_FUNC_QUALIFIER detail::tvec4<valType> roundEven(detail::tvec4<valType> const& x)
+ {
+ return detail::tvec4<valType>(
+ roundEven(x.x),
+ roundEven(x.y),
+ roundEven(x.z),
+ roundEven(x.w));
+ }
+
+ // ceil
+ template <typename genType>
+ GLM_FUNC_QUALIFIER genType ceil(genType const & x)
+ {
+ GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'ceil' only accept floating-point inputs");
+
+ return ::std::ceil(x);
+ }
+
+ template <typename valType>
+ GLM_FUNC_QUALIFIER detail::tvec2<valType> ceil(detail::tvec2<valType> const & x)
+ {
+ return detail::tvec2<valType>(
+ ceil(x.x),
+ ceil(x.y));
+ }
+
+ template <typename valType>
+ GLM_FUNC_QUALIFIER detail::tvec3<valType> ceil(detail::tvec3<valType> const & x)
+ {
+ return detail::tvec3<valType>(
+ ceil(x.x),
+ ceil(x.y),
+ ceil(x.z));
+ }
+
+ template <typename valType>
+ GLM_FUNC_QUALIFIER detail::tvec4<valType> ceil(detail::tvec4<valType> const & x)
+ {
+ return detail::tvec4<valType>(
+ ceil(x.x),
+ ceil(x.y),
+ ceil(x.z),
+ ceil(x.w));
+ }
+
+ // fract
+ template <typename genType>
+ GLM_FUNC_QUALIFIER genType fract
+ (
+ genType const & x
+ )
+ {
+ GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'fract' only accept floating-point inputs");
+
+ return x - ::std::floor(x);
+ }
+
+ template <typename valType>
+ GLM_FUNC_QUALIFIER detail::tvec2<valType> fract
+ (
+ detail::tvec2<valType> const & x
+ )
+ {
+ return detail::tvec2<valType>(
+ fract(x.x),
+ fract(x.y));
+ }
+
+ template <typename valType>
+ GLM_FUNC_QUALIFIER detail::tvec3<valType> fract
+ (
+ detail::tvec3<valType> const & x
+ )
+ {
+ return detail::tvec3<valType>(
+ fract(x.x),
+ fract(x.y),
+ fract(x.z));
+ }
+
+ template <typename valType>
+ GLM_FUNC_QUALIFIER detail::tvec4<valType> fract
+ (
+ detail::tvec4<valType> const & x
+ )
+ {
+ return detail::tvec4<valType>(
+ fract(x.x),
+ fract(x.y),
+ fract(x.z),
+ fract(x.w));
+ }
+
+ // mod
+ template <typename genType>
+ GLM_FUNC_QUALIFIER genType mod
+ (
+ genType const & x,
+ genType const & y
+ )
+ {
+ GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'mod' only accept floating-point inputs");
+
+ return x - y * floor(x / y);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<T> mod
+ (
+ detail::tvec2<T> const & x,
+ typename detail::tvec2<T>::value_type const & y
+ )
+ {
+ return detail::tvec2<T>(
+ mod(x.x, y),
+ mod(x.y, y));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> mod
+ (
+ detail::tvec3<T> const & x,
+ typename detail::tvec3<T>::value_type const & y
+ )
+ {
+ return detail::tvec3<T>(
+ mod(x.x, y),
+ mod(x.y, y),
+ mod(x.z, y));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<T> mod
+ (
+ detail::tvec4<T> const & x,
+ typename detail::tvec4<T>::value_type const & y
+ )
+ {
+ return detail::tvec4<T>(
+ mod(x.x, y),
+ mod(x.y, y),
+ mod(x.z, y),
+ mod(x.w, y));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<T> mod
+ (
+ detail::tvec2<T> const & x,
+ detail::tvec2<T> const & y
+ )
+ {
+ return detail::tvec2<T>(
+ mod(x.x, y.x),
+ mod(x.y, y.y));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> mod
+ (
+ detail::tvec3<T> const & x,
+ detail::tvec3<T> const & y
+ )
+ {
+ return detail::tvec3<T>(
+ mod(x.x, y.x),
+ mod(x.y, y.y),
+ mod(x.z, y.z));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<T> mod
+ (
+ detail::tvec4<T> const & x,
+ detail::tvec4<T> const & y
+ )
+ {
+ return detail::tvec4<T>(
+ mod(x.x, y.x),
+ mod(x.y, y.y),
+ mod(x.z, y.z),
+ mod(x.w, y.w));
+ }
+
+ // modf
+ template <typename genType>
+ GLM_FUNC_QUALIFIER genType modf
+ (
+ genType const & x,
+ genType & i
+ )
+ {
+ GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'modf' only accept floating-point inputs");
+
+ i = glm::floor(x);
+
+ return x - i;
+ }
+
+ template <typename valType>
+ GLM_FUNC_QUALIFIER detail::tvec2<valType> modf
+ (
+ detail::tvec2<valType> const & x,
+ detail::tvec2<valType> const & y
+ )
+ {
+ return detail::tvec2<valType>(
+ modf(x.x, y.x),
+ modf(x.y, y.y));
+ }
+
+ template <typename valType>
+ GLM_FUNC_QUALIFIER detail::tvec3<valType> modf
+ (
+ detail::tvec3<valType> const & x,
+ detail::tvec3<valType> const & y
+ )
+ {
+ return detail::tvec3<valType>(
+ modf(x.x, y.x),
+ modf(x.y, y.y),
+ modf(x.z, y.z));
+ }
+
+ template <typename valType>
+ GLM_FUNC_QUALIFIER detail::tvec4<valType> modf
+ (
+ detail::tvec4<valType> const & x,
+ detail::tvec4<valType> const & y
+ )
+ {
+ return detail::tvec4<valType>(
+ modf(x.x, y.x),
+ modf(x.y, y.y),
+ modf(x.z, y.z),
+ modf(x.w, y.w));
+ }
+
+ //// Only valid if (INT_MIN <= x-y <= INT_MAX)
+ //// min(x,y)
+ //r = y + ((x - y) & ((x - y) >> (sizeof(int) *
+ //CHAR_BIT 1)));
+ //// max(x,y)
+ //r = x - ((x - y) & ((x - y) >> (sizeof(int) *
+ //CHAR_BIT - 1)));
+
+ // min
+ template <typename genType>
+ GLM_FUNC_QUALIFIER genType min
+ (
+ genType const & x,
+ genType const & y
+ )
+ {
+ GLM_STATIC_ASSERT(
+ detail::type<genType>::is_float ||
+ detail::type<genType>::is_int ||
+ detail::type<genType>::is_uint, "'min' only accept numbers");
+
+ return x < y ? x : y;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<T> min
+ (
+ detail::tvec2<T> const & x,
+ typename detail::tvec2<T>::value_type const & y
+ )
+ {
+ return detail::tvec2<T>(
+ min(x.x, y),
+ min(x.y, y));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> min
+ (
+ detail::tvec3<T> const & x,
+ typename detail::tvec3<T>::value_type const & y
+ )
+ {
+ return detail::tvec3<T>(
+ min(x.x, y),
+ min(x.y, y),
+ min(x.z, y));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<T> min
+ (
+ detail::tvec4<T> const & x,
+ typename detail::tvec4<T>::value_type const & y
+ )
+ {
+ return detail::tvec4<T>(
+ min(x.x, y),
+ min(x.y, y),
+ min(x.z, y),
+ min(x.w, y));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<T> min
+ (
+ detail::tvec2<T> const & x,
+ detail::tvec2<T> const & y
+ )
+ {
+ return detail::tvec2<T>(
+ min(x.x, y.x),
+ min(x.y, y.y));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> min
+ (
+ detail::tvec3<T> const & x,
+ detail::tvec3<T> const & y
+ )
+ {
+ return detail::tvec3<T>(
+ min(x.x, y.x),
+ min(x.y, y.y),
+ min(x.z, y.z));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<T> min
+ (
+ detail::tvec4<T> const & x,
+ detail::tvec4<T> const & y
+ )
+ {
+ return detail::tvec4<T>(
+ min(x.x, y.x),
+ min(x.y, y.y),
+ min(x.z, y.z),
+ min(x.w, y.w));
+ }
+
+ // max
+ template <typename genType>
+ GLM_FUNC_QUALIFIER genType max
+ (
+ genType const & x,
+ genType const & y
+ )
+ {
+ GLM_STATIC_ASSERT(
+ detail::type<genType>::is_float ||
+ detail::type<genType>::is_int ||
+ detail::type<genType>::is_uint, "'max' only accept numbers");
+
+ return x > y ? x : y;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<T> max
+ (
+ detail::tvec2<T> const & x,
+ typename detail::tvec2<T>::value_type y
+ )
+ {
+ return detail::tvec2<T>(
+ max(x.x, y),
+ max(x.y, y));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> max
+ (
+ detail::tvec3<T> const & x,
+ typename detail::tvec3<T>::value_type y
+ )
+ {
+ return detail::tvec3<T>(
+ max(x.x, y),
+ max(x.y, y),
+ max(x.z, y));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<T> max
+ (
+ detail::tvec4<T> const & x,
+ typename detail::tvec4<T>::value_type y
+ )
+ {
+ return detail::tvec4<T>(
+ max(x.x, y),
+ max(x.y, y),
+ max(x.z, y),
+ max(x.w, y));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<T> max
+ (
+ detail::tvec2<T> const & x,
+ detail::tvec2<T> const & y
+ )
+ {
+ return detail::tvec2<T>(
+ max(x.x, y.x),
+ max(x.y, y.y));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> max
+ (
+ detail::tvec3<T> const & x,
+ detail::tvec3<T> const & y
+ )
+ {
+ return detail::tvec3<T>(
+ max(x.x, y.x),
+ max(x.y, y.y),
+ max(x.z, y.z));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<T> max
+ (
+ detail::tvec4<T> const & x,
+ detail::tvec4<T> const & y)
+ {
+ return detail::tvec4<T>(
+ max(x.x, y.x),
+ max(x.y, y.y),
+ max(x.z, y.z),
+ max(x.w, y.w));
+ }
+
+ // clamp
+ template <typename valType>
+ GLM_FUNC_QUALIFIER valType clamp
+ (
+ valType const & x,
+ valType const & minVal,
+ valType const & maxVal
+ )
+ {
+ GLM_STATIC_ASSERT(
+ detail::type<valType>::is_float ||
+ detail::type<valType>::is_int ||
+ detail::type<valType>::is_uint, "'clamp' only accept numbers");
+
+ // Old implementation, less predictable branching
+ //if(x >= maxVal) return maxVal;
+ //if(x <= minVal) return minVal;
+ //return x;
+ return glm::max(glm::min(x, maxVal), minVal);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<T> clamp
+ (
+ detail::tvec2<T> const & x,
+ typename detail::tvec2<T>::value_type const & minVal,
+ typename detail::tvec2<T>::value_type const & maxVal
+ )
+ {
+ return detail::tvec2<T>(
+ clamp(x.x, minVal, maxVal),
+ clamp(x.y, minVal, maxVal));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> clamp
+ (
+ detail::tvec3<T> const & x,
+ typename detail::tvec3<T>::value_type const & minVal,
+ typename detail::tvec3<T>::value_type const & maxVal
+ )
+ {
+ return detail::tvec3<T>(
+ clamp(x.x, minVal, maxVal),
+ clamp(x.y, minVal, maxVal),
+ clamp(x.z, minVal, maxVal));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<T> clamp
+ (
+ detail::tvec4<T> const & x,
+ typename detail::tvec4<T>::value_type const & minVal,
+ typename detail::tvec4<T>::value_type const & maxVal
+ )
+ {
+ return detail::tvec4<T>(
+ clamp(x.x, minVal, maxVal),
+ clamp(x.y, minVal, maxVal),
+ clamp(x.z, minVal, maxVal),
+ clamp(x.w, minVal, maxVal));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<T> clamp
+ (
+ detail::tvec2<T> const & x,
+ detail::tvec2<T> const & minVal,
+ detail::tvec2<T> const & maxVal
+ )
+ {
+ return detail::tvec2<T>(
+ clamp(x.x, minVal.x, maxVal.x),
+ clamp(x.y, minVal.y, maxVal.y));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> clamp
+ (
+ detail::tvec3<T> const & x,
+ detail::tvec3<T> const & minVal,
+ detail::tvec3<T> const & maxVal
+ )
+ {
+ return detail::tvec3<T>(
+ clamp(x.x, minVal.x, maxVal.x),
+ clamp(x.y, minVal.y, maxVal.y),
+ clamp(x.z, minVal.z, maxVal.z));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<T> clamp
+ (
+ detail::tvec4<T> const & x,
+ detail::tvec4<T> const & minVal,
+ detail::tvec4<T> const & maxVal
+ )
+ {
+ return detail::tvec4<T>(
+ clamp(x.x, minVal.x, maxVal.x),
+ clamp(x.y, minVal.y, maxVal.y),
+ clamp(x.z, minVal.z, maxVal.z),
+ clamp(x.w, minVal.w, maxVal.w));
+ }
+
+ // mix
+ template <typename genTypeT, typename genTypeU>
+ GLM_FUNC_QUALIFIER genTypeT mix
+ (
+ genTypeT const & x,
+ genTypeT const & y,
+ genTypeU const & a
+ )
+ {
+ // It could be a vector too
+ //GLM_STATIC_ASSERT(
+ // detail::type<genTypeT>::is_float &&
+ // detail::type<genTypeU>::is_float);
+
+ //return x + a * (y - x);
+ return genTypeT(genTypeU(x) + a * genTypeU(y - x));
+ }
+
+ template <typename valTypeA, typename valTypeB>
+ GLM_FUNC_QUALIFIER detail::tvec2<valTypeA> mix
+ (
+ detail::tvec2<valTypeA> const & x,
+ detail::tvec2<valTypeA> const & y,
+ valTypeB const & a
+ )
+ {
+ return detail::tvec2<valTypeA>(
+ detail::tvec2<valTypeB>(x) + a * detail::tvec2<valTypeB>(y - x));
+ }
+
+ template <typename valTypeA, typename valTypeB>
+ GLM_FUNC_QUALIFIER detail::tvec3<valTypeA> mix
+ (
+ detail::tvec3<valTypeA> const & x,
+ detail::tvec3<valTypeA> const & y,
+ valTypeB const & a
+ )
+ {
+ return detail::tvec3<valTypeA>(
+ detail::tvec3<valTypeB>(x) + a * detail::tvec3<valTypeB>(y - x));
+ }
+
+ template <typename valTypeA, typename valTypeB>
+ GLM_FUNC_QUALIFIER detail::tvec4<valTypeA> mix
+ (
+ detail::tvec4<valTypeA> const & x,
+ detail::tvec4<valTypeA> const & y,
+ valTypeB const & a
+ )
+ {
+ return detail::tvec4<valTypeA>(
+ detail::tvec4<valTypeB>(x) + a * detail::tvec4<valTypeB>(y - x));
+ }
+
+ template <typename valTypeA, typename valTypeB>
+ GLM_FUNC_QUALIFIER detail::tvec2<valTypeA> mix
+ (
+ detail::tvec2<valTypeA> const & x,
+ detail::tvec2<valTypeA> const & y,
+ detail::tvec2<valTypeB> const & a
+ )
+ {
+ return detail::tvec2<valTypeA>(
+ detail::tvec2<valTypeB>(x) + a * detail::tvec2<valTypeB>(y - x));
+ }
+
+ template <typename valTypeA, typename valTypeB>
+ GLM_FUNC_QUALIFIER detail::tvec3<valTypeA> mix
+ (
+ detail::tvec3<valTypeA> const & x,
+ detail::tvec3<valTypeA> const & y,
+ detail::tvec3<valTypeB> const & a
+ )
+ {
+ return detail::tvec3<valTypeA>(
+ detail::tvec3<valTypeB>(x) + a * detail::tvec3<valTypeB>(y - x));
+ }
+
+ template <typename valTypeA, typename valTypeB>
+ GLM_FUNC_QUALIFIER detail::tvec4<valTypeA> mix
+ (
+ detail::tvec4<valTypeA> const & x,
+ detail::tvec4<valTypeA> const & y,
+ detail::tvec4<valTypeB> const & a
+ )
+ {
+ return detail::tvec4<valTypeA>(
+ detail::tvec4<valTypeB>(x) + a * detail::tvec4<valTypeB>(y - x));
+ }
+
+ //template <typename genTypeT>
+ //GLM_FUNC_QUALIFIER genTypeT mix
+ //(
+ // genTypeT const & x,
+ // genTypeT const & y,
+ // float const & a
+ //)
+ //{
+ // // It could be a vector too
+ // //GLM_STATIC_ASSERT(
+ // // detail::type<genTypeT>::is_float &&
+ // // detail::type<genTypeU>::is_float);
+
+ // return x + a * (y - x);
+ //}
+
+ template <typename genType>
+ GLM_FUNC_QUALIFIER genType mix
+ (
+ genType const & x,
+ genType const & y,
+ bool a
+ )
+ {
+ GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'mix' only accept floating-point inputs");
+
+ return a ? x : y;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<T> mix
+ (
+ detail::tvec2<T> const & x,
+ detail::tvec2<T> const & y,
+ typename detail::tvec2<T>::bool_type a
+ )
+ {
+ GLM_STATIC_ASSERT(detail::type<T>::is_float, "'mix' only accept floating-point inputs");
+
+ detail::tvec2<T> result;
+ for
+ (
+ typename detail::tvec2<T>::size_type i = 0;
+ i < detail::tvec2<T>::value_size();
+ ++i
+ )
+ {
+ result[i] = a[i] ? x[i] : y[i];
+ }
+ return result;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> mix
+ (
+ detail::tvec3<T> const & x,
+ detail::tvec3<T> const & y,
+ typename detail::tvec3<T>::bool_type a
+ )
+ {
+ GLM_STATIC_ASSERT(detail::type<T>::is_float, "'mix' only accept floating-point inputs");
+
+ detail::tvec3<T> result;
+ for
+ (
+ typename detail::tvec3<T>::size_type i = 0;
+ i < detail::tvec3<T>::value_size();
+ ++i
+ )
+ {
+ result[i] = a[i] ? x[i] : y[i];
+ }
+ return result;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<T> mix
+ (
+ detail::tvec4<T> const & x,
+ detail::tvec4<T> const & y,
+ typename detail::tvec4<T>::bool_type a
+ )
+ {
+ GLM_STATIC_ASSERT(detail::type<T>::is_float, "'mix' only accept floating-point inputs");
+
+ detail::tvec4<T> result;
+ for
+ (
+ typename detail::tvec4<T>::size_type i = 0;
+ i < detail::tvec4<T>::value_size();
+ ++i
+ )
+ {
+ result[i] = a[i] ? x[i] : y[i];
+ }
+ return result;
+ }
+
+ // step
+ template <typename genType>
+ GLM_FUNC_QUALIFIER genType step
+ (
+ genType const & edge,
+ genType const & x
+ )
+ {
+ GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'mix' only accept floating-point inputs");
+
+ return x <= edge ? genType(0) : genType(1);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<T> step
+ (
+ typename detail::tvec2<T>::value_type const & edge,
+ detail::tvec2<T> const & x
+ )
+ {
+ return detail::tvec2<T>(
+ x.x <= edge ? T(0) : T(1),
+ x.y <= edge ? T(0) : T(1));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> step
+ (
+ typename detail::tvec3<T>::value_type const & edge,
+ detail::tvec3<T> const & x
+ )
+ {
+ return detail::tvec3<T>(
+ x.x <= edge ? T(0) : T(1),
+ x.y <= edge ? T(0) : T(1),
+ x.z <= edge ? T(0) : T(1));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<T> step
+ (
+ typename detail::tvec4<T>::value_type const & edge,
+ detail::tvec4<T> const & x
+ )
+ {
+ return detail::tvec4<T>(
+ x.x <= edge ? T(0) : T(1),
+ x.y <= edge ? T(0) : T(1),
+ x.z <= edge ? T(0) : T(1),
+ x.w <= edge ? T(0) : T(1));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<T> step
+ (
+ detail::tvec2<T> const & edge,
+ detail::tvec2<T> const & x
+ )
+ {
+ return detail::tvec2<T>(
+ x.x <= edge.x ? T(0) : T(1),
+ x.y <= edge.y ? T(0) : T(1));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> step
+ (
+ detail::tvec3<T> const & edge,
+ detail::tvec3<T> const & x
+ )
+ {
+ return detail::tvec3<T>(
+ x.x <= edge.x ? T(0) : T(1),
+ x.y <= edge.y ? T(0) : T(1),
+ x.z <= edge.z ? T(0) : T(1));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<T> step
+ (
+ detail::tvec4<T> const & edge,
+ detail::tvec4<T> const & x
+ )
+ {
+ return detail::tvec4<T>(
+ x.x <= edge.x ? T(0) : T(1),
+ x.y <= edge.y ? T(0) : T(1),
+ x.z <= edge.z ? T(0) : T(1),
+ x.w <= edge.w ? T(0) : T(1));
+ }
+
+ // smoothstep
+ template <typename genType>
+ GLM_FUNC_QUALIFIER genType smoothstep
+ (
+ genType const & edge0,
+ genType const & edge1,
+ genType const & x
+ )
+ {
+ GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'mix' only accept floating-point inputs");
+
+ genType tmp = clamp((x - edge0) / (edge1 - edge0), genType(0), genType(1));
+ return tmp * tmp * (genType(3) - genType(2) * tmp);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<T> smoothstep
+ (
+ typename detail::tvec2<T>::value_type const & edge0,
+ typename detail::tvec2<T>::value_type const & edge1,
+ detail::tvec2<T> const & x
+ )
+ {
+ return detail::tvec2<T>(
+ smoothstep(edge0, edge1, x.x),
+ smoothstep(edge0, edge1, x.y));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> smoothstep
+ (
+ typename detail::tvec3<T>::value_type const & edge0,
+ typename detail::tvec3<T>::value_type const & edge1,
+ detail::tvec3<T> const & x
+ )
+ {
+ return detail::tvec3<T>(
+ smoothstep(edge0, edge1, x.x),
+ smoothstep(edge0, edge1, x.y),
+ smoothstep(edge0, edge1, x.z));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<T> smoothstep
+ (
+ typename detail::tvec4<T>::value_type const & edge0,
+ typename detail::tvec4<T>::value_type const & edge1,
+ detail::tvec4<T> const & x
+ )
+ {
+ return detail::tvec4<T>(
+ smoothstep(edge0, edge1, x.x),
+ smoothstep(edge0, edge1, x.y),
+ smoothstep(edge0, edge1, x.z),
+ smoothstep(edge0, edge1, x.w));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<T> smoothstep
+ (
+ detail::tvec2<T> const & edge0,
+ detail::tvec2<T> const & edge1,
+ detail::tvec2<T> const & x
+ )
+ {
+ return detail::tvec2<T>(
+ smoothstep(edge0.x, edge1.x, x.x),
+ smoothstep(edge0.y, edge1.y, x.y));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> smoothstep
+ (
+ detail::tvec3<T> const & edge0,
+ detail::tvec3<T> const & edge1,
+ detail::tvec3<T> const & x
+ )
+ {
+ return detail::tvec3<T>(
+ smoothstep(edge0.x, edge1.x, x.x),
+ smoothstep(edge0.y, edge1.y, x.y),
+ smoothstep(edge0.z, edge1.z, x.z));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<T> smoothstep
+ (
+ detail::tvec4<T> const & edge0,
+ detail::tvec4<T> const & edge1,
+ detail::tvec4<T> const & x
+ )
+ {
+ return detail::tvec4<T>(
+ smoothstep(edge0.x, edge1.x, x.x),
+ smoothstep(edge0.y, edge1.y, x.y),
+ smoothstep(edge0.z, edge1.z, x.z),
+ smoothstep(edge0.w, edge1.w, x.w));
+ }
+
+ template <typename genType>
+ GLM_FUNC_QUALIFIER typename genType::bool_type isnan
+ (
+ genType const & x
+ )
+ {
+ GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'mix' only accept floating-point inputs");
+
+#if(GLM_COMPILER & GLM_COMPILER_VC)
+ return typename genType::bool_type(_isnan(x));
+#else
+ return typename genType::bool_type(std::isnan(x));
+#endif
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename detail::tvec2<T>::bool_type isnan
+ (
+ detail::tvec2<T> const & x
+ )
+ {
+ return typename detail::tvec2<T>::bool_type(
+ isnan(x.x),
+ isnan(x.y));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename detail::tvec3<T>::bool_type isnan
+ (
+ detail::tvec3<T> const & x
+ )
+ {
+ return typename detail::tvec3<T>::bool_type(
+ isnan(x.x),
+ isnan(x.y),
+ isnan(x.z));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename detail::tvec4<T>::bool_type isnan
+ (
+ detail::tvec4<T> const & x
+ )
+ {
+ return typename detail::tvec4<T>::bool_type(
+ isnan(x.x),
+ isnan(x.y),
+ isnan(x.z),
+ isnan(x.w));
+ }
+
+ template <typename genType>
+ GLM_FUNC_QUALIFIER typename genType::bool_type isinf
+ (
+ genType const & x
+ )
+ {
+ GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'isinf' only accept floating-point inputs");
+
+#if(GLM_COMPILER & GLM_COMPILER_VC)
+ return typename genType::bool_type(_fpclass(x) == _FPCLASS_NINF || _fpclass(x) == _FPCLASS_PINF);
+#else
+ return typename genType::bool_type(std::isinf(x));
+#endif
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename detail::tvec2<T>::bool_type isinf
+ (
+ detail::tvec2<T> const & x
+ )
+ {
+ return typename detail::tvec2<T>::bool_type(
+ isnan(x.x),
+ isnan(x.y));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename detail::tvec3<T>::bool_type isinf
+ (
+ detail::tvec3<T> const & x
+ )
+ {
+ return typename detail::tvec3<T>::bool_type(
+ isnan(x.x),
+ isnan(x.y),
+ isnan(x.z));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename detail::tvec4<T>::bool_type isinf
+ (
+ detail::tvec4<T> const & x
+ )
+ {
+ return typename detail::tvec4<T>::bool_type(
+ isnan(x.x),
+ isnan(x.y),
+ isnan(x.z),
+ isnan(x.w));
+ }
+
+ GLM_FUNC_QUALIFIER int floatBitsToInt(float const & value)
+ {
+ union
+ {
+ float f;
+ int i;
+ } fi;
+
+ fi.f = value;
+ return fi.i;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<int> floatBitsToInt
+ (
+ detail::tvec2<T> const & value
+ )
+ {
+ return detail::tvec2<T>(
+ floatBitsToInt(value.x),
+ floatBitsToInt(value.y));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<int> floatBitsToInt
+ (
+ detail::tvec3<T> const & value
+ )
+ {
+ return detail::tvec3<T>(
+ floatBitsToInt(value.x),
+ floatBitsToInt(value.y));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<int> floatBitsToInt
+ (
+ detail::tvec4<T> const & value
+ )
+ {
+ return detail::tvec4<T>(
+ floatBitsToInt(value.x),
+ floatBitsToInt(value.y));
+ }
+
+ GLM_FUNC_QUALIFIER uint floatBitsToUint(float const & value)
+ {
+ union
+ {
+ float f;
+ uint u;
+ } fu;
+
+ fu.f = value;
+ return fu.u;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<uint> floatBitsToUint
+ (
+ detail::tvec2<T> const & value
+ )
+ {
+ return detail::tvec2<T>(
+ floatBitsToUint(value.x),
+ floatBitsToUint(value.y));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<uint> floatBitsToUint
+ (
+ detail::tvec3<T> const & value
+ )
+ {
+ return detail::tvec3<T>(
+ floatBitsToUint(value.x),
+ floatBitsToUint(value.y));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<uint> floatBitsToUint
+ (
+ detail::tvec4<T> const & value
+ )
+ {
+ return detail::tvec4<T>(
+ floatBitsToUint(value.x),
+ floatBitsToUint(value.y));
+ }
+
+ GLM_FUNC_QUALIFIER float intBitsToFloat(int const & value)
+ {
+ union
+ {
+ float f;
+ int i;
+ } fi;
+
+ fi.i = value;
+ return fi.f;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<float> intBitsToFloat
+ (
+ detail::tvec2<T> const & value
+ )
+ {
+ return detail::tvec2<T>(
+ intBitsToFloat(value.x),
+ intBitsToFloat(value.y));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<float> intBitsToFloat
+ (
+ detail::tvec3<T> const & value
+ )
+ {
+ return detail::tvec3<T>(
+ intBitsToFloat(value.x),
+ intBitsToFloat(value.y));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<float> intBitsToFloat
+ (
+ detail::tvec4<T> const & value
+ )
+ {
+ return detail::tvec4<T>(
+ intBitsToFloat(value.x),
+ intBitsToFloat(value.y));
+ }
+
+ GLM_FUNC_QUALIFIER float uintBitsToFloat(uint const & value)
+ {
+ union
+ {
+ float f;
+ uint u;
+ } fu;
+
+ fu.u = value;
+ return fu.f;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<float> uintBitsToFloat
+ (
+ detail::tvec2<T> const & value
+ )
+ {
+ return detail::tvec2<T>(
+ uintBitsToFloat(value.x),
+ uintBitsToFloat(value.y));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<float> uintBitsToFloat
+ (
+ detail::tvec3<T> const & value
+ )
+ {
+ return detail::tvec3<T>(
+ uintBitsToFloat(value.x),
+ uintBitsToFloat(value.y));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<float> uintBitsToFloat
+ (
+ detail::tvec4<T> const & value
+ )
+ {
+ return detail::tvec4<T>(
+ uintBitsToFloat(value.x),
+ uintBitsToFloat(value.y));
+ }
+
+ template <typename genType>
+ GLM_FUNC_QUALIFIER genType fma
+ (
+ genType const & a,
+ genType const & b,
+ genType const & c
+ )
+ {
+ return a * b + c;
+ }
+
+ template <typename genType>
+ GLM_FUNC_QUALIFIER genType frexp
+ (
+ genType const & x,
+ int & exp
+ )
+ {
+ return std::frexp(x, exp);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<T> frexp
+ (
+ detail::tvec2<T> const & x,
+ detail::tvec2<int> & exp
+ )
+ {
+ return std::frexp(x, exp);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> frexp
+ (
+ detail::tvec3<T> const & x,
+ detail::tvec3<int> & exp
+ )
+ {
+ return std::frexp(x, exp);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<T> frexp
+ (
+ detail::tvec4<T> const & x,
+ detail::tvec4<int> & exp
+ )
+ {
+ return std::frexp(x, exp);
+ }
+
+ template <typename genType>
+ GLM_FUNC_QUALIFIER genType ldexp
+ (
+ genType const & x,
+ int const & exp
+ )
+ {
+ return std::frexp(x, exp);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<T> ldexp
+ (
+ detail::tvec2<T> const & x,
+ detail::tvec2<int> const & exp
+ )
+ {
+ return std::frexp(x, exp);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> ldexp
+ (
+ detail::tvec3<T> const & x,
+ detail::tvec3<int> const & exp
+ )
+ {
+ return std::frexp(x, exp);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<T> ldexp
+ (
+ detail::tvec4<T> const & x,
+ detail::tvec4<int> const & exp
+ )
+ {
+ return std::frexp(x, exp);
+ }
+
+ }//namespace common
+ }//namespace function
+ }//namespace core
+}//namespace glm
diff --git a/src/glm/core/func_exponential.hpp b/src/glm/core/func_exponential.hpp
new file mode 100644
index 0000000..c24ef04
--- /dev/null
+++ b/src/glm/core/func_exponential.hpp
@@ -0,0 +1,86 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2008-08-08
+// Updated : 2010-02-04
+// Licence : This source is under MIT License
+// File : glm/core/func_exponential.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_core_func_exponential
+#define glm_core_func_exponential
+
+namespace glm
+{
+ namespace core{
+ namespace function{
+ //! Define all exponential functions from Section 8.2 of GLSL 1.30.8 specification. Included in glm namespace.
+ namespace exponential{
+
+ /// \addtogroup core_funcs
+ ///@{
+
+ //! Returns x raised to the y power.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/pow.xml">GLSL pow man page</a>
+ //! \li GLSL 1.30.08 specification, section 8.2
+ template <typename genType>
+ genType pow(genType const & x, genType const & y);
+
+ //! Returns the natural exponentiation of x, i.e., e^x.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/exp.xml">GLSL exp man page</a>
+ //! \li GLSL 1.30.08 specification, section 8.2
+ template <typename genType>
+ genType exp(genType const & x);
+
+ //! Returns the natural logarithm of x, i.e.,
+ //! returns the value y which satisfies the equation x = e^y.
+ //! Results are undefined if x <= 0.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/log.xml">GLSL log man page</a>
+ //! \li GLSL 1.30.08 specification, section 8.2
+ template <typename genType>
+ genType log(genType const & x);
+
+ //! Returns 2 raised to the x power.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/exp2.xml">GLSL exp2 man page</a>
+ //! \li GLSL 1.30.08 specification, section 8.2
+ template <typename genType>
+ genType exp2(genType const & x);
+
+ //! Returns the base 2 log of x, i.e., returns the value y,
+ //! which satisfies the equation x = 2 ^ y.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/log2.xml">GLSL log2 man page</a>
+ //! \li GLSL 1.30.08 specification, section 8.2
+ template <typename genType>
+ genType log2(genType const & x);
+
+ //! Returns the positive square root of x.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/sqrt.xml">GLSL sqrt man page</a>
+ //! \li GLSL 1.30.08 specification, section 8.2
+ template <typename genType>
+ genType sqrt(genType const & x);
+
+ //! Returns the reciprocal of the positive square root of x.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/inversesqrt.xml">GLSL inversesqrt man page</a>
+ //! \li GLSL 1.30.08 specification, section 8.2
+ template <typename genType>
+ genType inversesqrt(genType const & x);
+
+ ///@}
+
+ }//namespace exponential
+ }//namespace function
+ }//namespace core
+
+ using namespace core::function::exponential;
+}//namespace glm
+
+#include "func_exponential.inl"
+
+#endif//glm_core_func_exponential
diff --git a/src/glm/core/func_exponential.inl b/src/glm/core/func_exponential.inl
new file mode 100644
index 0000000..181596f
--- /dev/null
+++ b/src/glm/core/func_exponential.inl
@@ -0,0 +1,358 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2008-08-03
+// Updated : 2010-02-04
+// Licence : This source is under MIT License
+// File : glm/core/func_exponential.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm
+{
+ namespace core{
+ namespace function{
+ namespace exponential{
+
+ // pow
+ template <typename genType>
+ GLM_FUNC_QUALIFIER genType pow
+ (
+ genType const & x,
+ genType const & y
+ )
+ {
+ GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'pow' only accept floating-point input");
+
+ return ::std::pow(x, y);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<T> pow
+ (
+ detail::tvec2<T> const & x,
+ detail::tvec2<T> const & y
+ )
+ {
+ return detail::tvec2<T>(
+ pow(x.x, y.x),
+ pow(x.y, y.y));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> pow
+ (
+ detail::tvec3<T> const & x,
+ detail::tvec3<T> const & y
+ )
+ {
+ return detail::tvec3<T>(
+ pow(x.x, y.x),
+ pow(x.y, y.y),
+ pow(x.z, y.z));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<T> pow
+ (
+ detail::tvec4<T> const & x,
+ detail::tvec4<T> const & y
+ )
+ {
+ return detail::tvec4<T>(
+ pow(x.x, y.x),
+ pow(x.y, y.y),
+ pow(x.z, y.z),
+ pow(x.w, y.w));
+ }
+
+ // exp
+ template <typename genType>
+ GLM_FUNC_QUALIFIER genType exp
+ (
+ genType const & x
+ )
+ {
+ GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'exp' only accept floating-point input");
+
+ return ::std::exp(x);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<T> exp
+ (
+ detail::tvec2<T> const & x
+ )
+ {
+ return detail::tvec2<T>(
+ exp(x.x),
+ exp(x.y));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> exp
+ (
+ detail::tvec3<T> const & x
+ )
+ {
+ return detail::tvec3<T>(
+ exp(x.x),
+ exp(x.y),
+ exp(x.z));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<T> exp
+ (
+ detail::tvec4<T> const & x
+ )
+ {
+ return detail::tvec4<T>(
+ exp(x.x),
+ exp(x.y),
+ exp(x.z),
+ exp(x.w));
+ }
+
+ // log
+ template <typename genType>
+ GLM_FUNC_QUALIFIER genType log
+ (
+ genType const & x
+ )
+ {
+ GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'log' only accept floating-point input");
+
+ return ::std::log(x);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<T> log
+ (
+ detail::tvec2<T> const & x
+ )
+ {
+ return detail::tvec2<T>(
+ log(x.x),
+ log(x.y));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> log
+ (
+ detail::tvec3<T> const & x
+ )
+ {
+ return detail::tvec3<T>(
+ log(x.x),
+ log(x.y),
+ log(x.z));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<T> log
+ (
+ detail::tvec4<T> const & x
+ )
+ {
+ return detail::tvec4<T>(
+ log(x.x),
+ log(x.y),
+ log(x.z),
+ log(x.w));
+ }
+
+ //exp2, ln2 = 0.69314718055994530941723212145818f
+ template <typename genType>
+ GLM_FUNC_QUALIFIER genType exp2
+ (
+ genType const & x
+ )
+ {
+ GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'exp2' only accept floating-point input");
+
+ return ::std::exp(genType(0.69314718055994530941723212145818) * x);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<T> exp2
+ (
+ detail::tvec2<T> const & x
+ )
+ {
+ return detail::tvec2<T>(
+ exp2(x.x),
+ exp2(x.y));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> exp2
+ (
+ detail::tvec3<T> const & x
+ )
+ {
+ return detail::tvec3<T>(
+ exp2(x.x),
+ exp2(x.y),
+ exp2(x.z));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<T> exp2
+ (
+ detail::tvec4<T> const & x
+ )
+ {
+ return detail::tvec4<T>(
+ exp2(x.x),
+ exp2(x.y),
+ exp2(x.z),
+ exp2(x.w));
+ }
+
+ // log2, ln2 = 0.69314718055994530941723212145818f
+ template <typename genType>
+ GLM_FUNC_QUALIFIER genType log2
+ (
+ genType const & x
+ )
+ {
+ GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'log2' only accept floating-point input");
+
+ return ::std::log(x) / genType(0.69314718055994530941723212145818);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<T> log2
+ (
+ detail::tvec2<T> const & x
+ )
+ {
+ return detail::tvec2<T>(
+ log2(x.x),
+ log2(x.y));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> log2
+ (
+ detail::tvec3<T> const & x
+ )
+ {
+ return detail::tvec3<T>(
+ log2(x.x),
+ log2(x.y),
+ log2(x.z));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<T> log2
+ (
+ detail::tvec4<T> const & x
+ )
+ {
+ return detail::tvec4<T>(
+ log2(x.x),
+ log2(x.y),
+ log2(x.z),
+ log2(x.w));
+ }
+
+ // sqrt
+ template <typename genType>
+ GLM_FUNC_QUALIFIER genType sqrt
+ (
+ genType const & x
+ )
+ {
+ GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'sqrt' only accept floating-point input");
+
+ return genType(::std::sqrt(x));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<T> sqrt
+ (
+ detail::tvec2<T> const & x
+ )
+ {
+ return detail::tvec2<T>(
+ sqrt(x.x),
+ sqrt(x.y));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> sqrt
+ (
+ detail::tvec3<T> const & x
+ )
+ {
+ return detail::tvec3<T>(
+ sqrt(x.x),
+ sqrt(x.y),
+ sqrt(x.z));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<T> sqrt
+ (
+ detail::tvec4<T> const & x
+ )
+ {
+ return detail::tvec4<T>(
+ sqrt(x.x),
+ sqrt(x.y),
+ sqrt(x.z),
+ sqrt(x.w));
+ }
+
+ template <typename genType>
+ GLM_FUNC_QUALIFIER genType inversesqrt
+ (
+ genType const & x
+ )
+ {
+ GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'inversesqrt' only accept floating-point input");
+
+ return genType(1) / ::std::sqrt(x);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<T> inversesqrt
+ (
+ detail::tvec2<T> const & x
+ )
+ {
+ return detail::tvec2<T>(
+ inversesqrt(x.x),
+ inversesqrt(x.y));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> inversesqrt
+ (
+ detail::tvec3<T> const & x
+ )
+ {
+ return detail::tvec3<T>(
+ inversesqrt(x.x),
+ inversesqrt(x.y),
+ inversesqrt(x.z));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<T> inversesqrt
+ (
+ detail::tvec4<T> const & x
+ )
+ {
+ return detail::tvec4<T>(
+ inversesqrt(x.x),
+ inversesqrt(x.y),
+ inversesqrt(x.z),
+ inversesqrt(x.w));
+ }
+
+ }//namespace exponential
+ }//namespace function
+ }//namespace core
+}//namespace glm
diff --git a/src/glm/core/func_geometric.hpp b/src/glm/core/func_geometric.hpp
new file mode 100644
index 0000000..a42ae1b
--- /dev/null
+++ b/src/glm/core/func_geometric.hpp
@@ -0,0 +1,108 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2008-08-03
+// Updated : 2010-02-04
+// Licence : This source is under MIT License
+// File : glm/core/func_geometric.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_core_func_geometric
+#define glm_core_func_geometric
+
+namespace glm
+{
+ namespace core{
+ namespace function{
+ namespace geometric{ //!< Define all geometric functions from Section 8.4 of GLSL 1.30.8 specification. Included in glm namespace.
+
+ /// \addtogroup core_funcs
+ ///@{
+
+ //! Returns the length of x, i.e., sqrt(x * x).
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/length.xml">GLSL length man page</a>
+ //! \li GLSL 1.30.08 specification, section 8.4
+ template <typename genType>
+ typename genType::value_type length(
+ genType const & x);
+
+ //! Returns the distance betwwen p0 and p1, i.e., length(p0 - p1).
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/distance.xml">GLSL distance man page</a>
+ //! \li GLSL 1.30.08 specification, section 8.4
+ template <typename genType>
+ typename genType::value_type distance(
+ genType const & p0,
+ genType const & p1);
+
+ //! Returns the dot product of x and y, i.e., result = x * y.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/dot.xml">GLSL dot man page</a>
+ //! \li GLSL 1.30.08 specification, section 8.4
+ template <typename genType>
+ typename genType::value_type dot(
+ genType const & x,
+ genType const & y);
+
+ //! Returns the cross product of x and y.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/cross.xml">GLSL cross man page</a>
+ //! \li GLSL 1.30.08 specification, section 8.4
+ template <typename T>
+ detail::tvec3<T> cross(
+ detail::tvec3<T> const & x,
+ detail::tvec3<T> const & y);
+
+ //! Returns a vector in the same direction as x but with length of 1.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/normalize.xml">GLSL normalize man page</a>
+ //! \li GLSL 1.30.08 specification, section 8.4
+ template <typename genType>
+ genType normalize(
+ genType const & x);
+
+ //! If dot(Nref, I) < 0.0, return N, otherwise, return -N.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/faceforward.xml">GLSL faceforward man page</a>
+ //! \li GLSL 1.30.08 specification, section 8.4
+ template <typename genType>
+ genType faceforward(
+ genType const & N,
+ genType const & I,
+ genType const & Nref);
+
+ //! For the incident vector I and surface orientation N,
+ //! returns the reflection direction : result = I - 2.0 * dot(N, I) * N.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/reflect.xml">GLSL reflect man page</a>
+ //! \li GLSL 1.30.08 specification, section 8.4
+ template <typename genType>
+ genType reflect(
+ genType const & I,
+ genType const & N);
+
+ //! For the incident vector I and surface normal N,
+ //! and the ratio of indices of refraction eta,
+ //! return the refraction vector.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/refract.xml">GLSL refract man page</a>
+ //! \li GLSL 1.30.08 specification, section 8.4
+ template <typename genType>
+ genType refract(
+ genType const & I,
+ genType const & N,
+ typename genType::value_type const & eta);
+
+ ///@}
+
+ }//namespace geometric
+ }//namespace function
+ }//namespace core
+
+ using namespace core::function::geometric;
+}//namespace glm
+
+#include "func_geometric.inl"
+
+#endif//glm_core_func_geometric
diff --git a/src/glm/core/func_geometric.inl b/src/glm/core/func_geometric.inl
new file mode 100644
index 0000000..9ffe8ca
--- /dev/null
+++ b/src/glm/core/func_geometric.inl
@@ -0,0 +1,290 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2008-08-03
+// Updated : 2010-02-04
+// Licence : This source is under MIT License
+// File : glm/core/func_geometric.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm
+{
+ namespace core{
+ namespace function{
+ namespace geometric{
+
+ // length
+ template <typename genType>
+ GLM_FUNC_QUALIFIER genType length
+ (
+ genType const & x
+ )
+ {
+ GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'length' only accept floating-point inputs");
+
+ genType sqr = x * x;
+ return sqrt(sqr);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename detail::tvec2<T>::value_type length
+ (
+ detail::tvec2<T> const & v
+ )
+ {
+ GLM_STATIC_ASSERT(detail::type<T>::is_float, "'length' only accept floating-point inputs");
+
+ typename detail::tvec2<T>::value_type sqr = v.x * v.x + v.y * v.y;
+ return sqrt(sqr);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename detail::tvec3<T>::value_type length
+ (
+ detail::tvec3<T> const & v
+ )
+ {
+ GLM_STATIC_ASSERT(detail::type<T>::is_float, "'length' only accept floating-point inputs");
+
+ typename detail::tvec3<T>::value_type sqr = v.x * v.x + v.y * v.y + v.z * v.z;
+ return sqrt(sqr);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename detail::tvec4<T>::value_type length
+ (
+ detail::tvec4<T> const & v
+ )
+ {
+ GLM_STATIC_ASSERT(detail::type<T>::is_float, "'length' only accept floating-point inputs");
+
+ typename detail::tvec4<T>::value_type sqr = v.x * v.x + v.y * v.y + v.z * v.z + v.w * v.w;
+ return sqrt(sqr);
+ }
+
+ // distance
+ template <typename genType>
+ GLM_FUNC_QUALIFIER genType distance
+ (
+ genType const & p0,
+ genType const & p1
+ )
+ {
+ GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'distance' only accept floating-point inputs");
+
+ return length(p1 - p0);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename detail::tvec2<T>::value_type distance
+ (
+ detail::tvec2<T> const & p0,
+ detail::tvec2<T> const & p1
+ )
+ {
+ GLM_STATIC_ASSERT(detail::type<T>::is_float, "'distance' only accept floating-point inputs");
+
+ return length(p1 - p0);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename detail::tvec3<T>::value_type distance
+ (
+ detail::tvec3<T> const & p0,
+ detail::tvec3<T> const & p1
+ )
+ {
+ GLM_STATIC_ASSERT(detail::type<T>::is_float, "'distance' only accept floating-point inputs");
+
+ return length(p1 - p0);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename detail::tvec4<T>::value_type distance
+ (
+ detail::tvec4<T> const & p0,
+ detail::tvec4<T> const & p1
+ )
+ {
+ GLM_STATIC_ASSERT(detail::type<T>::is_float, "'distance' only accept floating-point inputs");
+
+ return length(p1 - p0);
+ }
+
+ // dot
+ template <typename genType>
+ GLM_FUNC_QUALIFIER genType dot
+ (
+ genType const & x,
+ genType const & y
+ )
+ {
+ GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'dot' only accept floating-point inputs");
+
+ return x * y;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename detail::tvec2<T>::value_type dot
+ (
+ detail::tvec2<T> const & x,
+ detail::tvec2<T> const & y
+ )
+ {
+ GLM_STATIC_ASSERT(detail::type<T>::is_float, "'dot' only accept floating-point inputs");
+
+ return x.x * y.x + x.y * y.y;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER T dot
+ (
+ detail::tvec3<T> const & x,
+ detail::tvec3<T> const & y
+ )
+ {
+ GLM_STATIC_ASSERT(detail::type<T>::is_float, "'dot' only accept floating-point inputs");
+
+ return x.x * y.x + x.y * y.y + x.z * y.z;
+ }
+/* // SSE3
+ GLM_FUNC_QUALIFIER float dot(const tvec4<float>& x, const tvec4<float>& y)
+ {
+ float Result;
+ __asm
+ {
+ mov esi, x
+ mov edi, y
+ movaps xmm0, [esi]
+ mulps xmm0, [edi]
+ haddps( _xmm0, _xmm0 )
+ haddps( _xmm0, _xmm0 )
+ movss Result, xmm0
+ }
+ return Result;
+ }
+*/
+ template <typename T>
+ GLM_FUNC_QUALIFIER T dot
+ (
+ detail::tvec4<T> const & x,
+ detail::tvec4<T> const & y
+ )
+ {
+ GLM_STATIC_ASSERT(detail::type<T>::is_float, "'dot' only accept floating-point inputs");
+
+ return x.x * y.x + x.y * y.y + x.z * y.z + x.w * y.w;
+ }
+
+ // cross
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> cross
+ (
+ detail::tvec3<T> const & x,
+ detail::tvec3<T> const & y
+ )
+ {
+ GLM_STATIC_ASSERT(detail::type<T>::is_float, "'cross' only accept floating-point inputs");
+
+ return detail::tvec3<T>(
+ x.y * y.z - y.y * x.z,
+ x.z * y.x - y.z * x.x,
+ x.x * y.y - y.x * x.y);
+ }
+
+ // normalize
+ template <typename genType>
+ GLM_FUNC_QUALIFIER genType normalize
+ (
+ genType const & x
+ )
+ {
+ GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'normalize' only accept floating-point inputs");
+
+ return x < genType(0) ? genType(-1) : genType(1);
+ }
+
+ // According to issue 10 GLSL 1.10 specification, if length(x) == 0 then result is undefine and generate an error
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<T> normalize
+ (
+ detail::tvec2<T> const & x
+ )
+ {
+ GLM_STATIC_ASSERT(detail::type<T>::is_float, "'normalize' only accept floating-point inputs");
+
+ typename detail::tvec2<T>::value_type sqr = x.x * x.x + x.y * x.y;
+ return x * inversesqrt(sqr);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> normalize
+ (
+ detail::tvec3<T> const & x
+ )
+ {
+ GLM_STATIC_ASSERT(detail::type<T>::is_float, "'normalize' only accept floating-point inputs");
+
+ typename detail::tvec3<T>::value_type sqr = x.x * x.x + x.y * x.y + x.z * x.z;
+ return x * inversesqrt(sqr);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<T> normalize
+ (
+ detail::tvec4<T> const & x
+ )
+ {
+ GLM_STATIC_ASSERT(detail::type<T>::is_float, "'normalize' only accept floating-point inputs");
+
+ typename detail::tvec4<T>::value_type sqr = x.x * x.x + x.y * x.y + x.z * x.z + x.w * x.w;
+ return x * inversesqrt(sqr);
+ }
+
+ // faceforward
+ template <typename genType>
+ GLM_FUNC_QUALIFIER genType faceforward
+ (
+ genType const & N,
+ genType const & I,
+ genType const & Nref
+ )
+ {
+ return dot(Nref, I) < 0 ? N : -N;
+ }
+
+ // reflect
+ template <typename genType>
+ genType reflect
+ (
+ genType const & I,
+ genType const & N
+ )
+ {
+ return I - N * dot(N, I) * float(2);
+ }
+
+ // refract
+ template <typename genType>
+ GLM_FUNC_QUALIFIER genType refract
+ (
+ genType const & I,
+ genType const & N,
+ typename genType::value_type const & eta
+ )
+ {
+ //It could be a vector
+ //GLM_STATIC_ASSERT(detail::type<genType>::is_float);
+
+ typename genType::value_type dotValue = dot(N, I);
+ typename genType::value_type k = typename genType::value_type(1) - eta * eta * (typename genType::value_type(1) - dotValue * dotValue);
+ if(k < typename genType::value_type(0))
+ return genType(0);
+ else
+ return eta * I - (eta * dotValue + sqrt(k)) * N;
+ }
+
+ }//namespace geometric
+ }//namespace function
+ }//namespace core
+}//namespace glm
diff --git a/src/glm/core/func_integer.hpp b/src/glm/core/func_integer.hpp
new file mode 100644
index 0000000..5e3d68d
--- /dev/null
+++ b/src/glm/core/func_integer.hpp
@@ -0,0 +1,158 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2010-03-17
+// Updated : 2010-03-31
+// Licence : This source is under MIT License
+// File : glm/core/func_integer.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_core_func_integer
+#define glm_core_func_integer
+
+namespace glm
+{
+ namespace core{
+ namespace function{
+ //! Define integer functions from Section 8.8 of GLSL 4.00.8 specification.
+ namespace integer{
+
+ /// \addtogroup core_funcs
+ ///@{
+
+ //! Adds 32-bit unsigned integer x and y, returning the sum
+ //! modulo pow(2, 32). The value carry is set to 0 if the sum was
+ //! less than pow(2, 32), or to 1 otherwise.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/uaddCarry.xml">GLSL uaddCarry man page</a>
+ //! \li GLSL 4.00.08 specification, section 8.8
+ template <typename genUType>
+ genUType uaddCarry(
+ genUType const & x,
+ genUType const & y,
+ genUType & carry);
+
+ //! Subtracts the 32-bit unsigned integer y from x, returning
+ //! the difference if non-negative, or pow(2, 32) plus the difference
+ //! otherwise. The value borrow is set to 0 if x >= y, or to 1 otherwise.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/usubBorrow.xml">GLSL usubBorrow man page</a>
+ //! \li GLSL 4.00.08 specification, section 8.8
+ template <typename genUType>
+ genUType usubBorrow(
+ genUType const & x,
+ genUType const & y,
+ genUType & borrow);
+
+ //! Multiplies 32-bit integers x and y, producing a 64-bit
+ //! result. The 32 least-significant bits are returned in lsb.
+ //! The 32 most-significant bits are returned in msb.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/umulExtended.xml">GLSL umulExtended man page</a>
+ //! \li GLSL 4.00.08 specification, section 8.8
+ template <typename genUType>
+ void umulExtended(
+ genUType const & x,
+ genUType const & y,
+ genUType & msb,
+ genUType & lsb);
+
+ //! Multiplies 32-bit integers x and y, producing a 64-bit
+ //! result. The 32 least-significant bits are returned in lsb.
+ //! The 32 most-significant bits are returned in msb.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/imulExtended.xml">GLSL imulExtended man page</a>
+ //! \li GLSL 4.00.08 specification, section 8.8
+ template <typename genIType>
+ void imulExtended(
+ genIType const & x,
+ genIType const & y,
+ genIType & msb,
+ genIType & lsb);
+
+ //! Extracts bits [offset, offset + bits - 1] from value,
+ //! returning them in the least significant bits of the result.
+ //! For unsigned data types, the most significant bits of the
+ //! result will be set to zero. For signed data types, the
+ //! most significant bits will be set to the value of bit offset + base 1.
+ //!
+ //! If bits is zero, the result will be zero. The result will be
+ //! undefined if offset or bits is negative, or if the sum of
+ //! offset and bits is greater than the number of bits used
+ //! to store the operand.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/bitfieldExtract.xml">GLSL bitfieldExtract man page</a>
+ //! \li GLSL 4.00.08 specification, section 8.8
+ template <typename genIUType>
+ genIUType bitfieldExtract(
+ genIUType const & Value,
+ int const & Offset,
+ int const & Bits);
+
+ //! Returns the insertion the bits least-significant bits of insert into base.
+ //!
+ //! The result will have bits [offset, offset + bits - 1] taken
+ //! from bits [0, bits 1] of insert, and all other bits taken
+ //! directly from the corresponding bits of base. If bits is
+ //! zero, the result will simply be base. The result will be
+ //! undefined if offset or bits is negative, or if the sum of
+ //! offset and bits is greater than the number of bits used to
+ //! store the operand.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/bitfieldInsert.xml">GLSL bitfieldInsert man page</a>
+ //! \li GLSL 4.00.08 specification, section 8.8
+ template <typename genIUType>
+ genIUType bitfieldInsert(
+ genIUType const & Base,
+ genIUType const & Insert,
+ int const & Offset,
+ int const & Bits);
+
+ //! Returns the reversal of the bits of value.
+ //! The bit numbered n of the result will be taken from bit (bits - 1) - n of value,
+ //! where bits is the total number of bits used to represent value.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/bitfieldReverse.xml">GLSL bitfieldReverse man page</a>
+ //! \li GLSL 4.00.08 specification, section 8.8
+ template <typename genIUType>
+ genIUType bitfieldReverse(genIUType const & value);
+
+ //! Returns the number of bits set to 1 in the binary representation of value.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/bitCount.xml">GLSL bitCount man page</a>
+ //! \li GLSL 4.00.08 specification, section 8.8
+ template <typename T, template <typename> class C>
+ typename C<T>::signed_type bitCount(C<T> const & Value);
+
+ //! Returns the bit number of the least significant bit set to
+ //! 1 in the binary representation of value.
+ //! If value is zero, -1 will be returned.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/findLSB.xml">GLSL findLSB man page</a>
+ //! \li GLSL 4.00.08 specification, section 8.8
+ template <typename T, template <typename> class C>
+ typename C<T>::signed_type findLSB(C<T> const & Value);
+
+ //! Returns the bit number of the most significant bit in the binary representation of value.
+ //! For positive integers, the result will be the bit number of the most significant bit set to 1.
+ //! For negative integers, the result will be the bit number of the most significant
+ //! bit set to 0. For a value of zero or negative one, -1 will be returned.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/findMSB.xml">GLSL findMSB man page</a>
+ //! \li GLSL 4.00.08 specification, section 8.8
+ template <typename T, template <typename> class C>
+ typename C<T>::signed_type findMSB(C<T> const & Value);
+
+ ///@}
+
+ }//namespace integer
+ }//namespace function
+ }//namespace core
+
+ using namespace core::function::integer;
+}//namespace glm
+
+#include "func_integer.inl"
+
+#endif//glm_core_func_integer
+
diff --git a/src/glm/core/func_integer.inl b/src/glm/core/func_integer.inl
new file mode 100644
index 0000000..f68be11
--- /dev/null
+++ b/src/glm/core/func_integer.inl
@@ -0,0 +1,597 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2010-03-17
+// Updated : 2010-03-31
+// Licence : This source is under MIT License
+// File : glm/core/func_integer.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm
+{
+ namespace detail
+ {
+
+ }//namespace detail
+
+ namespace core{
+ namespace function{
+ namespace integer
+ {
+ // uaddCarry
+ template <typename genUType>
+ GLM_FUNC_QUALIFIER genUType uaddCarry
+ (
+ genUType const & x,
+ genUType const & y,
+ genUType & Carry
+ )
+ {
+ detail::highp_uint_t Value64 = detail::highp_uint_t(x) + detail::highp_uint_t(y);
+ genUType Result = genUType(Value64 % (detail::highp_uint_t(1) << detail::highp_uint_t(32)));
+ Carry = (Value64 % (detail::highp_uint_t(1) << detail::highp_uint_t(32))) > 1 ? 1 : 0;
+ return Result;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<T> uaddCarry
+ (
+ detail::tvec2<T> const & x,
+ detail::tvec2<T> const & y,
+ detail::tvec2<T> & Carry
+ )
+ {
+ return detail::tvec2<T>(
+ uaddCarry(x[0], y[0], Carry[0]),
+ uaddCarry(x[1], y[1], Carry[1]));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> uaddCarry
+ (
+ detail::tvec3<T> const & x,
+ detail::tvec3<T> const & y,
+ detail::tvec3<T> & Carry
+ )
+ {
+ return detail::tvec3<T>(
+ uaddCarry(x[0], y[0], Carry[0]),
+ uaddCarry(x[1], y[1], Carry[1]),
+ uaddCarry(x[2], y[2], Carry[2]));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<T> uaddCarry
+ (
+ detail::tvec4<T> const & x,
+ detail::tvec4<T> const & y,
+ detail::tvec4<T> & Carry
+ )
+ {
+ return detail::tvec4<T>(
+ uaddCarry(x[0], y[0], Carry[0]),
+ uaddCarry(x[1], y[1], Carry[1]),
+ uaddCarry(x[2], y[2], Carry[2]),
+ uaddCarry(x[3], y[3], Carry[3]));
+ }
+
+ // usubBorrow
+ template <typename genUType>
+ GLM_FUNC_QUALIFIER genUType usubBorrow
+ (
+ genUType const & x,
+ genUType const & y,
+ genUType & Borrow
+ )
+ {
+ Borrow = x >= y ? 0 : 1;
+ if(x > y)
+ return genUType(detail::highp_int_t(x) - detail::highp_int_t(y));
+ else
+ return genUType(detail::highp_int_t(1) << (detail::highp_int_t(32) + detail::highp_int_t(x) - detail::highp_int_t(y)));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<T> usubBorrow
+ (
+ detail::tvec2<T> const & x,
+ detail::tvec2<T> const & y,
+ detail::tvec2<T> & Borrow
+ )
+ {
+ return detail::tvec2<T>(
+ usubBorrow(x[0], y[0], Borrow[0]),
+ usubBorrow(x[1], y[1], Borrow[1]));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> usubBorrow
+ (
+ detail::tvec3<T> const & x,
+ detail::tvec3<T> const & y,
+ detail::tvec3<T> & Borrow
+ )
+ {
+ return detail::tvec3<T>(
+ usubBorrow(x[0], y[0], Borrow[0]),
+ usubBorrow(x[1], y[1], Borrow[1]),
+ usubBorrow(x[2], y[2], Borrow[2]));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<T> usubBorrow
+ (
+ detail::tvec4<T> const & x,
+ detail::tvec4<T> const & y,
+ detail::tvec4<T> & Borrow
+ )
+ {
+ return detail::tvec4<T>(
+ usubBorrow(x[0], y[0], Borrow[0]),
+ usubBorrow(x[1], y[1], Borrow[1]),
+ usubBorrow(x[2], y[2], Borrow[2]),
+ usubBorrow(x[3], y[3], Borrow[3]));
+ }
+
+ // umulExtended
+ template <typename genUType>
+ GLM_FUNC_QUALIFIER void umulExtended
+ (
+ genUType const & x,
+ genUType const & y,
+ genUType & msb,
+ genUType & lsb
+ )
+ {
+ detail::highp_uint_t ValueX64 = x;
+ detail::highp_uint_t ValueY64 = y;
+ detail::highp_uint_t Value64 = ValueX64 * ValueY64;
+ msb = *(genUType*)&genUType(Value64 & ((detail::highp_uint_t(1) << detail::highp_uint_t(32)) - detail::highp_uint_t(1)));
+ lsb = *(genUType*)&genUType(Value64 >> detail::highp_uint_t(32));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<T> umulExtended
+ (
+ detail::tvec2<T> const & x,
+ detail::tvec2<T> const & y,
+ detail::tvec2<T> & msb,
+ detail::tvec2<T> & lsb
+ )
+ {
+ return detail::tvec2<T>(
+ umulExtended(x[0], y[0], msb, lsb),
+ umulExtended(x[1], y[1], msb, lsb));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> umulExtended
+ (
+ detail::tvec3<T> const & x,
+ detail::tvec3<T> const & y,
+ detail::tvec3<T> & msb,
+ detail::tvec3<T> & lsb
+ )
+ {
+ return detail::tvec3<T>(
+ umulExtended(x[0], y[0], msb, lsb),
+ umulExtended(x[1], y[1], msb, lsb),
+ umulExtended(x[2], y[2], msb, lsb));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<T> umulExtended
+ (
+ detail::tvec4<T> const & x,
+ detail::tvec4<T> const & y,
+ detail::tvec4<T> & msb,
+ detail::tvec4<T> & lsb
+ )
+ {
+ return detail::tvec4<T>(
+ umulExtended(x[0], y[0], msb, lsb),
+ umulExtended(x[1], y[1], msb, lsb),
+ umulExtended(x[2], y[2], msb, lsb),
+ umulExtended(x[3], y[3], msb, lsb));
+ }
+
+ // imulExtended
+ template <typename genIType>
+ GLM_FUNC_QUALIFIER void imulExtended
+ (
+ genIType const & x,
+ genIType const & y,
+ genIType & msb,
+ genIType & lsb
+ )
+ {
+ detail::highp_int_t ValueX64 = x;
+ detail::highp_int_t ValueY64 = y;
+ detail::highp_int_t Value64 = ValueX64 * ValueY64;
+ msb = *(genIType*)&genIType(Value64 & ((detail::highp_uint_t(1) << detail::highp_uint_t(32)) - detail::highp_uint_t(1)));
+ lsb = *(genIType*)&genIType(Value64 >> detail::highp_uint_t(32));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<T> imulExtended
+ (
+ detail::tvec2<T> const & x,
+ detail::tvec2<T> const & y,
+ detail::tvec2<T> & msb,
+ detail::tvec2<T> & lsb
+ )
+ {
+ return detail::tvec2<T>(
+ imulExtended(x[0], y[0], msb, lsb),
+ imulExtended(x[1], y[1], msb, lsb));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> imulExtended
+ (
+ detail::tvec3<T> const & x,
+ detail::tvec3<T> const & y,
+ detail::tvec3<T> & msb,
+ detail::tvec3<T> & lsb
+ )
+ {
+ return detail::tvec3<T>(
+ imulExtended(x[0], y[0], msb, lsb),
+ imulExtended(x[1], y[1], msb, lsb),
+ imulExtended(x[2], y[2], msb, lsb));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<T> imulExtended
+ (
+ detail::tvec4<T> const & x,
+ detail::tvec4<T> const & y,
+ detail::tvec4<T> & msb,
+ detail::tvec4<T> & lsb
+ )
+ {
+ return detail::tvec4<T>(
+ imulExtended(x[0], y[0], msb, lsb),
+ imulExtended(x[1], y[1], msb, lsb),
+ imulExtended(x[2], y[2], msb, lsb),
+ imulExtended(x[3], y[3], msb, lsb));
+ }
+
+ // bitfieldExtract
+ template <typename genIUType>
+ GLM_FUNC_QUALIFIER genIUType bitfieldExtract
+ (
+ genIUType const & Value,
+ int const & Offset,
+ int const & Bits
+ )
+ {
+ int GenSize = int(sizeof(genIUType)) << int(3);
+
+ assert(Offset + Bits <= GenSize);
+
+ genIUType ShiftLeft = Bits ? Value << (GenSize - (Bits + Offset)) : genIUType(0);
+ genIUType ShiftBack = ShiftLeft >> genIUType(GenSize - Bits);
+
+ return ShiftBack;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<T> bitfieldExtract
+ (
+ detail::tvec2<T> const & Value,
+ int const & Offset,
+ int const & Bits
+ )
+ {
+ return detail::tvec2<T>(
+ bitfieldExtract(Value[0]),
+ bitfieldExtract(Value[1]));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> bitfieldExtract
+ (
+ detail::tvec3<T> const & Value,
+ int const & Offset,
+ int const & Bits
+ )
+ {
+ return detail::tvec3<T>(
+ bitfieldExtract(Value[0]),
+ bitfieldExtract(Value[1]),
+ bitfieldExtract(Value[2]));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<T> bitfieldExtract
+ (
+ detail::tvec4<T> const & Value,
+ int const & Offset,
+ int const & Bits
+ )
+ {
+ return detail::tvec4<T>(
+ bitfieldExtract(Value[0]),
+ bitfieldExtract(Value[1]),
+ bitfieldExtract(Value[2]),
+ bitfieldExtract(Value[3]));
+ }
+
+ // bitfieldInsert
+ template <typename genIUType>
+ GLM_FUNC_QUALIFIER genIUType bitfieldInsert
+ (
+ genIUType const & Base,
+ genIUType const & Insert,
+ int const & Offset,
+ int const & Bits
+ )
+ {
+ GLM_STATIC_ASSERT(std::numeric_limits<genIUType>::is_integer, "'bitfieldInsert' only accept integer values");
+ assert(Offset + Bits <= sizeof(genIUType));
+
+ if(Bits == 0)
+ return Base;
+
+ genIUType Mask = 0;
+ for(int Bit = Offset; Bit < Offset + Bits; ++Bit)
+ Mask |= (1 << Bit);
+
+ return (Base & ~Mask) | (Insert & Mask);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<T> bitfieldInsert
+ (
+ detail::tvec2<T> const & Base,
+ detail::tvec2<T> const & Insert,
+ int const & Offset,
+ int const & Bits
+ )
+ {
+ return detail::tvec2<T>(
+ bitfieldInsert(Base[0], Insert[0], Offset, Bits),
+ bitfieldInsert(Base[1], Insert[1], Offset, Bits));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> bitfieldInsert
+ (
+ detail::tvec3<T> const & Base,
+ detail::tvec3<T> const & Insert,
+ int const & Offset,
+ int const & Bits
+ )
+ {
+ return detail::tvec3<T>(
+ bitfieldInsert(Base[0], Insert[0], Offset, Bits),
+ bitfieldInsert(Base[1], Insert[1], Offset, Bits),
+ bitfieldInsert(Base[2], Insert[2], Offset, Bits));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<T> bitfieldInsert
+ (
+ detail::tvec4<T> const & Base,
+ detail::tvec4<T> const & Insert,
+ int const & Offset,
+ int const & Bits
+ )
+ {
+ return detail::tvec4<T>(
+ bitfieldInsert(Base[0], Insert[0], Offset, Bits),
+ bitfieldInsert(Base[1], Insert[1], Offset, Bits),
+ bitfieldInsert(Base[2], Insert[2], Offset, Bits),
+ bitfieldInsert(Base[3], Insert[3], Offset, Bits));
+ }
+
+ // bitfieldReverse
+ template <typename genIUType>
+ GLM_FUNC_QUALIFIER genIUType bitfieldReverse(genIUType const & Value)
+ {
+ GLM_STATIC_ASSERT(std::numeric_limits<genIUType>::is_integer, "'bitfieldReverse' only accept integer values");
+
+ genIUType Out = 0;
+ std::size_t BitSize = sizeof(genIUType) * 8;
+ for(std::size_t i = 0; i < BitSize; ++i)
+ if(Value & (genIUType(1) << i))
+ Out |= genIUType(1) << (BitSize - 1 - i);
+ return Out;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<T> bitfieldReverse
+ (
+ detail::tvec2<T> const & value
+ )
+ {
+ return detail::tvec2<T>(
+ bitfieldReverse(value[0]),
+ bitfieldReverse(value[1]));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> bitfieldReverse
+ (
+ detail::tvec3<T> const & value
+ )
+ {
+ return detail::tvec3<T>(
+ bitfieldReverse(value[0]),
+ bitfieldReverse(value[1]),
+ bitfieldReverse(value[2]));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<T> bitfieldReverse
+ (
+ detail::tvec4<T> const & value
+ )
+ {
+ return detail::tvec4<T>(
+ bitfieldReverse(value[0]),
+ bitfieldReverse(value[1]),
+ bitfieldReverse(value[2]),
+ bitfieldReverse(value[3]));
+ }
+
+ // bitCount
+ template <typename genIUType>
+ GLM_FUNC_QUALIFIER int bitCount(genIUType const & Value)
+ {
+ GLM_STATIC_ASSERT(std::numeric_limits<genIUType>::is_integer, "'bitCount' only accept integer values");
+
+ int Count = 0;
+ for(std::size_t i = 0; i < sizeof(genIUType) * std::size_t(8); ++i)
+ {
+ if(Value & (1 << i))
+ ++Count;
+ }
+ return Count;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<int> bitCount
+ (
+ detail::tvec2<T> const & value
+ )
+ {
+ return detail::tvec2<int>(
+ bitCount(value[0]),
+ bitCount(value[1]));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<int> bitCount
+ (
+ detail::tvec3<T> const & value
+ )
+ {
+ return detail::tvec3<int>(
+ bitCount(value[0]),
+ bitCount(value[1]),
+ bitCount(value[2]));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<int> bitCount
+ (
+ detail::tvec4<T> const & value
+ )
+ {
+ return detail::tvec4<int>(
+ bitCount(value[0]),
+ bitCount(value[1]),
+ bitCount(value[2]),
+ bitCount(value[3]));
+ }
+
+ // findLSB
+ template <typename genIUType>
+ GLM_FUNC_QUALIFIER int findLSB
+ (
+ genIUType const & Value
+ )
+ {
+ GLM_STATIC_ASSERT(std::numeric_limits<genIUType>::is_integer, "'findLSB' only accept integer values");
+ if(Value == 0)
+ return -1;
+
+ genIUType Bit;
+ for(Bit = genIUType(0); !(Value & (1 << Bit)); ++Bit){}
+ return Bit;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<int> findLSB
+ (
+ detail::tvec2<T> const & value
+ )
+ {
+ return detail::tvec2<int>(
+ findLSB(value[0]),
+ findLSB(value[1]));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<int> findLSB
+ (
+ detail::tvec3<T> const & value
+ )
+ {
+ return detail::tvec3<int>(
+ findLSB(value[0]),
+ findLSB(value[1]),
+ findLSB(value[2]));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<int> findLSB
+ (
+ detail::tvec4<T> const & value
+ )
+ {
+ return detail::tvec4<int>(
+ findLSB(value[0]),
+ findLSB(value[1]),
+ findLSB(value[2]),
+ findLSB(value[3]));
+ }
+
+ // findMSB
+ template <typename genIUType>
+ GLM_FUNC_QUALIFIER int findMSB
+ (
+ genIUType const & Value
+ )
+ {
+ GLM_STATIC_ASSERT(std::numeric_limits<genIUType>::is_integer, "'findMSB' only accept integer values");
+ if(Value == 0)
+ return -1;
+
+ genIUType bit = genIUType(-1);
+ for(genIUType tmp = Value; tmp; tmp >>= 1, ++bit){}
+ return bit;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<int> findMSB
+ (
+ detail::tvec2<T> const & value
+ )
+ {
+ return detail::tvec2<int>(
+ findMSB(value[0]),
+ findMSB(value[1]));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<int> findMSB
+ (
+ detail::tvec3<T> const & value
+ )
+ {
+ return detail::tvec3<int>(
+ findMSB(value[0]),
+ findMSB(value[1]),
+ findMSB(value[2]));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<int> findMSB
+ (
+ detail::tvec4<T> const & value
+ )
+ {
+ return detail::tvec4<int>(
+ findMSB(value[0]),
+ findMSB(value[1]),
+ findMSB(value[2]),
+ findMSB(value[3]));
+ }
+
+ }//namespace integer
+ }//namespace function
+ }//namespace core
+}//namespace glm
diff --git a/src/glm/core/func_matrix.hpp b/src/glm/core/func_matrix.hpp
new file mode 100644
index 0000000..b41e980
--- /dev/null
+++ b/src/glm/core/func_matrix.hpp
@@ -0,0 +1,111 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2008-08-03
+// Updated : 2010-02-04
+// Licence : This source is under MIT License
+// File : glm/core/func_matrix.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_core_func_matrix
+#define glm_core_func_matrix
+
+namespace glm
+{
+ namespace core{
+ namespace function{
+ //! Define all matrix functions from Section 8.5 of GLSL 1.30.8 specification. Included in glm namespace.
+ namespace matrix{
+
+ /// \addtogroup core_funcs
+ ///@{
+
+ //! Multiply matrix x by matrix y component-wise, i.e.,
+ //! result[i][j] is the scalar product of x[i][j] and y[i][j].
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/matrixCompMult.xml">GLSL matrixCompMult man page</a>
+ //! \li GLSL 1.30.08 specification, section 8.5
+ template <typename matType>
+ matType matrixCompMult(
+ matType const & x,
+ matType const & y);
+
+ //! Treats the first parameter c as a column vector
+ //! and the second parameter r as a row vector
+ //! and does a linear algebraic matrix multiply c * r.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/outerProduct.xml">GLSL outerProduct man page</a>
+ //! \li GLSL 1.30.08 specification, section 8.5
+ template <typename vecType, typename matType>
+ matType outerProduct(
+ vecType const & c,
+ vecType const & r);
+
+ //! Returns the transposed matrix of x
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/transpose.xml">GLSL transpose man page</a>
+ //! \li GLSL 1.30.08 specification, section 8.5
+ template <typename matType>
+ typename matType::transpose_type transpose(
+ matType const & x);
+
+ //! Return the determinant of a mat2 matrix.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/determinant.xml">GLSL determinant man page</a>
+ //! \li GLSL 1.30.08 specification, section 8.5
+ template <typename T>
+ typename detail::tmat2x2<T>::value_type determinant(
+ detail::tmat2x2<T> const & m);
+
+ //! Return the determinant of a mat3 matrix.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/determinant.xml">GLSL determinant man page</a>
+ //! \li GLSL 1.30.08 specification, section 8.5
+ template <typename T>
+ typename detail::tmat3x3<T>::value_type determinant(
+ detail::tmat3x3<T> const & m);
+
+ //! Return the determinant of a mat4 matrix.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/determinant.xml">GLSL determinant man page</a>
+ //! \li GLSL 1.30.08 specification, section 8.5
+ template <typename T>
+ typename detail::tmat4x4<T>::value_type determinant(
+ detail::tmat4x4<T> const & m);
+
+ //! Return the inverse of a mat2 matrix.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/inverse.xml">GLSL inverse man page</a>
+ //! \li GLSL 1.40.07 specification, section 8.5
+ template <typename T>
+ detail::tmat2x2<T> inverse(
+ detail::tmat2x2<T> const & m);
+
+ //! Return the inverse of a mat3 matrix.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/inverse.xml">GLSL inverse man page</a>
+ //! \li GLSL 1.40.07 specification, section 8.5
+ template <typename T>
+ detail::tmat3x3<T> inverse(
+ detail::tmat3x3<T> const & m);
+
+ //! Return the inverse of a mat4 matrix.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/inverse.xml">GLSL inverse man page</a>
+ //! \li GLSL 1.40.07 specification, section 8.5
+ template <typename T>
+ detail::tmat4x4<T> inverse(
+ detail::tmat4x4<T> const & m);
+
+ ///@}
+
+ }//namespace matrix
+ }//namespace function
+ }//namespace core
+
+ using namespace core::function::matrix;
+}//namespace glm
+
+#include "func_matrix.inl"
+
+#endif//glm_core_func_matrix
diff --git a/src/glm/core/func_matrix.inl b/src/glm/core/func_matrix.inl
new file mode 100644
index 0000000..fb2adb8
--- /dev/null
+++ b/src/glm/core/func_matrix.inl
@@ -0,0 +1,571 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2008-03-08
+// Updated : 2010-02-04
+// Licence : This source is under MIT License
+// File : glm/core/func_matrix.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm
+{
+ namespace core{
+ namespace function{
+ namespace matrix{
+
+ // matrixCompMult
+ template <typename matType>
+ GLM_FUNC_QUALIFIER matType matrixCompMult
+ (
+ matType const & x,
+ matType const & y
+ )
+ {
+ GLM_STATIC_ASSERT(detail::type<typename matType::value_type>::is_float, "'matrixCompMult' only accept floating-point inputs");
+
+ matType result(matType::null);
+ for(typename matType::size_type i = 0; i < matType::col_size(); ++i)
+ result[i] = x[i] * y[i];
+ return result;
+ }
+
+ // outerProduct
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tmat2x2<T> outerProduct
+ (
+ detail::tvec2<T> const & c,
+ detail::tvec2<T> const & r
+ )
+ {
+ GLM_STATIC_ASSERT(detail::type<T>::is_float, "'outerProduct' only accept floating-point inputs");
+
+ detail::tmat2x2<T> m(detail::tmat2x2<T>::null);
+ m[0][0] = c[0] * r[0];
+ m[0][1] = c[1] * r[0];
+ m[1][0] = c[0] * r[1];
+ m[1][1] = c[1] * r[1];
+ return m;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tmat3x3<T> outerProduct
+ (
+ detail::tvec3<T> const & c,
+ detail::tvec3<T> const & r
+ )
+ {
+ GLM_STATIC_ASSERT(detail::type<T>::is_float, "'outerProduct' only accept floating-point inputs");
+
+ detail::tmat3x3<T> m(detail::tmat3x3<T>::null);
+ for(typename detail::tmat3x3<T>::size_type i = 0; i < detail::tmat3x3<T>::col_size(); ++i)
+ m[i] = c * r[i];
+ return m;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tmat4x4<T> outerProduct
+ (
+ detail::tvec4<T> const & c,
+ detail::tvec4<T> const & r
+ )
+ {
+ GLM_STATIC_ASSERT(detail::type<T>::is_float, "'outerProduct' only accept floating-point inputs");
+
+ detail::tmat4x4<T> m(detail::tmat4x4<T>::null);
+ for(typename detail::tmat4x4<T>::size_type i = 0; i < detail::tmat4x4<T>::col_size(); ++i)
+ m[i] = c * r[i];
+ return m;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tmat2x3<T> outerProduct
+ (
+ detail::tvec3<T> const & c,
+ detail::tvec2<T> const & r
+ )
+ {
+ GLM_STATIC_ASSERT(detail::type<T>::is_float, "'outerProduct' only accept floating-point inputs");
+
+ detail::tmat2x3<T> m(detail::tmat2x3<T>::null);
+ m[0][0] = c.x * r.x;
+ m[0][1] = c.y * r.x;
+ m[0][2] = c.z * r.x;
+ m[1][0] = c.x * r.y;
+ m[1][1] = c.y * r.y;
+ m[1][2] = c.z * r.y;
+ return m;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tmat3x2<T> outerProduct
+ (
+ detail::tvec2<T> const & c,
+ detail::tvec3<T> const & r
+ )
+ {
+ GLM_STATIC_ASSERT(detail::type<T>::is_float, "'outerProduct' only accept floating-point inputs");
+
+ detail::tmat3x2<T> m(detail::tmat3x2<T>::null);
+ m[0][0] = c.x * r.x;
+ m[0][1] = c.y * r.x;
+ m[1][0] = c.x * r.y;
+ m[1][1] = c.y * r.y;
+ m[2][0] = c.x * r.z;
+ m[2][1] = c.y * r.z;
+ return m;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tmat2x4<T> outerProduct
+ (
+ detail::tvec2<T> const & c,
+ detail::tvec4<T> const & r
+ )
+ {
+ GLM_STATIC_ASSERT(detail::type<T>::is_float, "'outerProduct' only accept floating-point inputs");
+
+ detail::tmat2x4<T> m(detail::tmat2x4<T>::null);
+ m[0][0] = c.x * r.x;
+ m[0][1] = c.y * r.x;
+ m[0][2] = c.z * r.x;
+ m[0][3] = c.w * r.x;
+ m[1][0] = c.x * r.y;
+ m[1][1] = c.y * r.y;
+ m[1][2] = c.z * r.y;
+ m[1][3] = c.w * r.y;
+ return m;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tmat4x2<T> outerProduct
+ (
+ detail::tvec4<T> const & c,
+ detail::tvec2<T> const & r
+ )
+ {
+ GLM_STATIC_ASSERT(detail::type<T>::is_float, "'outerProduct' only accept floating-point inputs");
+
+ detail::tmat4x2<T> m(detail::tmat4x2<T>::null);
+ m[0][0] = c.x * r.x;
+ m[0][1] = c.y * r.x;
+ m[1][0] = c.x * r.y;
+ m[1][1] = c.y * r.y;
+ m[2][0] = c.x * r.z;
+ m[2][1] = c.y * r.z;
+ m[3][0] = c.x * r.w;
+ m[3][1] = c.y * r.w;
+ return m;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tmat3x4<T> outerProduct
+ (
+ detail::tvec4<T> const & c,
+ detail::tvec3<T> const & r
+ )
+ {
+ GLM_STATIC_ASSERT(detail::type<T>::is_float, "'outerProduct' only accept floating-point inputs");
+
+ detail::tmat3x4<T> m(detail::tmat3x4<T>::null);
+ m[0][0] = c.x * r.x;
+ m[0][1] = c.y * r.x;
+ m[0][2] = c.z * r.x;
+ m[0][3] = c.w * r.x;
+ m[1][0] = c.x * r.y;
+ m[1][1] = c.y * r.y;
+ m[1][2] = c.z * r.y;
+ m[1][3] = c.w * r.y;
+ m[2][0] = c.x * r.z;
+ m[2][1] = c.y * r.z;
+ m[2][2] = c.z * r.z;
+ m[2][3] = c.w * r.z;
+ return m;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tmat4x3<T> outerProduct
+ (
+ detail::tvec3<T> const & c,
+ detail::tvec4<T> const & r
+ )
+ {
+ GLM_STATIC_ASSERT(detail::type<T>::is_float, "'outerProduct' only accept floating-point inputs");
+
+ detail::tmat4x3<T> m(detail::tmat4x3<T>::null);
+ m[0][0] = c.x * r.x;
+ m[0][1] = c.y * r.x;
+ m[0][2] = c.z * r.x;
+ m[1][0] = c.x * r.y;
+ m[1][1] = c.y * r.y;
+ m[1][2] = c.z * r.y;
+ m[2][0] = c.x * r.z;
+ m[2][1] = c.y * r.z;
+ m[2][2] = c.z * r.z;
+ m[3][0] = c.x * r.w;
+ m[3][1] = c.y * r.w;
+ m[3][2] = c.z * r.w;
+ return m;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tmat2x2<T> transpose
+ (
+ detail::tmat2x2<T> const & m
+ )
+ {
+ GLM_STATIC_ASSERT(detail::type<T>::is_float, "'transpose' only accept floating-point inputs");
+
+ detail::tmat2x2<T> result(detail::tmat2x2<T>::null);
+ result[0][0] = m[0][0];
+ result[0][1] = m[1][0];
+ result[1][0] = m[0][1];
+ result[1][1] = m[1][1];
+ return result;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tmat3x3<T> transpose
+ (
+ detail::tmat3x3<T> const & m
+ )
+ {
+ GLM_STATIC_ASSERT(detail::type<T>::is_float, "'transpose' only accept floating-point inputs");
+
+ detail::tmat3x3<T> result(detail::tmat3x3<T>::null);
+ result[0][0] = m[0][0];
+ result[0][1] = m[1][0];
+ result[0][2] = m[2][0];
+
+ result[1][0] = m[0][1];
+ result[1][1] = m[1][1];
+ result[1][2] = m[2][1];
+
+ result[2][0] = m[0][2];
+ result[2][1] = m[1][2];
+ result[2][2] = m[2][2];
+ return result;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tmat4x4<T> transpose
+ (
+ detail::tmat4x4<T> const & m
+ )
+ {
+ GLM_STATIC_ASSERT(detail::type<T>::is_float, "'transpose' only accept floating-point inputs");
+
+ detail::tmat4x4<T> result(detail::tmat4x4<T>::null);
+ result[0][0] = m[0][0];
+ result[0][1] = m[1][0];
+ result[0][2] = m[2][0];
+ result[0][3] = m[3][0];
+
+ result[1][0] = m[0][1];
+ result[1][1] = m[1][1];
+ result[1][2] = m[2][1];
+ result[1][3] = m[3][1];
+
+ result[2][0] = m[0][2];
+ result[2][1] = m[1][2];
+ result[2][2] = m[2][2];
+ result[2][3] = m[3][2];
+
+ result[3][0] = m[0][3];
+ result[3][1] = m[1][3];
+ result[3][2] = m[2][3];
+ result[3][3] = m[3][3];
+ return result;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tmat2x3<T> transpose
+ (
+ detail::tmat3x2<T> const & m
+ )
+ {
+ GLM_STATIC_ASSERT(detail::type<T>::is_float, "'transpose' only accept floating-point inputs");
+
+ detail::tmat2x3<T> result(detail::tmat2x3<T>::null);
+ result[0][0] = m[0][0];
+ result[0][1] = m[1][0];
+ result[0][2] = m[2][0];
+ result[1][0] = m[0][1];
+ result[1][1] = m[1][1];
+ result[1][2] = m[2][1];
+ return result;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tmat3x2<T> transpose
+ (
+ detail::tmat2x3<T> const & m
+ )
+ {
+ GLM_STATIC_ASSERT(detail::type<T>::is_float, "'transpose' only accept floating-point inputs");
+
+ detail::tmat3x2<T> result(detail::tmat3x2<T>::null);
+ result[0][0] = m[0][0];
+ result[0][1] = m[1][0];
+ result[1][0] = m[0][1];
+ result[1][1] = m[1][1];
+ result[2][0] = m[0][2];
+ result[2][1] = m[1][2];
+ return result;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tmat2x4<T> transpose
+ (
+ detail::tmat4x2<T> const & m
+ )
+ {
+ GLM_STATIC_ASSERT(detail::type<T>::is_float, "'transpose' only accept floating-point inputs");
+
+ detail::tmat2x4<T> result(detail::tmat2x4<T>::null);
+ result[0][0] = m[0][0];
+ result[0][1] = m[1][0];
+ result[0][2] = m[2][0];
+ result[0][3] = m[3][0];
+ result[1][0] = m[0][1];
+ result[1][1] = m[1][1];
+ result[1][2] = m[2][1];
+ result[1][3] = m[3][1];
+ return result;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tmat4x2<T> transpose
+ (
+ detail::tmat2x4<T> const & m
+ )
+ {
+ GLM_STATIC_ASSERT(detail::type<T>::is_float, "'transpose' only accept floating-point inputs");
+
+ detail::tmat4x2<T> result(detail::tmat4x2<T>::null);
+ result[0][0] = m[0][0];
+ result[0][1] = m[1][0];
+ result[1][0] = m[0][1];
+ result[1][1] = m[1][1];
+ result[2][0] = m[0][2];
+ result[2][1] = m[1][2];
+ result[3][0] = m[0][3];
+ result[3][1] = m[1][3];
+ return result;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tmat3x4<T> transpose
+ (
+ detail::tmat4x3<T> const & m
+ )
+ {
+ GLM_STATIC_ASSERT(detail::type<T>::is_float, "'transpose' only accept floating-point inputs");
+
+ detail::tmat3x4<T> result(detail::tmat3x4<T>::null);
+ result[0][0] = m[0][0];
+ result[0][1] = m[1][0];
+ result[0][2] = m[2][0];
+ result[0][3] = m[3][0];
+ result[1][0] = m[0][1];
+ result[1][1] = m[1][1];
+ result[1][2] = m[2][1];
+ result[1][3] = m[3][1];
+ result[2][0] = m[0][2];
+ result[2][1] = m[1][2];
+ result[2][2] = m[2][2];
+ result[2][3] = m[3][2];
+ return result;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tmat4x3<T> transpose
+ (
+ detail::tmat3x4<T> const & m
+ )
+ {
+ GLM_STATIC_ASSERT(detail::type<T>::is_float, "'transpose' only accept floating-point inputs");
+
+ detail::tmat4x3<T> result(detail::tmat4x3<T>::null);
+ result[0][0] = m[0][0];
+ result[0][1] = m[1][0];
+ result[0][2] = m[2][0];
+ result[1][0] = m[0][1];
+ result[1][1] = m[1][1];
+ result[1][2] = m[2][1];
+ result[2][0] = m[0][2];
+ result[2][1] = m[1][2];
+ result[2][2] = m[2][2];
+ result[3][0] = m[0][3];
+ result[3][1] = m[1][3];
+ result[3][2] = m[2][3];
+ return result;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename detail::tmat2x2<T>::value_type determinant
+ (
+ detail::tmat2x2<T> const & m
+ )
+ {
+ GLM_STATIC_ASSERT(detail::type<T>::is_float, "'determinant' only accept floating-point inputs");
+
+ return m[0][0] * m[1][1] - m[1][0] * m[0][1];
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename detail::tmat3x3<T>::value_type determinant
+ (
+ detail::tmat3x3<T> const & m
+ )
+ {
+ GLM_STATIC_ASSERT(detail::type<T>::is_float, "'determinant' only accept floating-point inputs");
+
+ return
+ + m[0][0] * (m[1][1] * m[2][2] - m[2][1] * m[1][2])
+ - m[1][0] * (m[0][1] * m[2][2] - m[2][1] * m[0][2])
+ + m[2][0] * (m[0][1] * m[1][2] - m[1][1] * m[0][2]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename detail::tmat4x4<T>::value_type determinant
+ (
+ detail::tmat4x4<T> const & m
+ )
+ {
+ GLM_STATIC_ASSERT(detail::type<T>::is_float, "'determinant' only accept floating-point inputs");
+
+ T SubFactor00 = m[2][2] * m[3][3] - m[3][2] * m[2][3];
+ T SubFactor01 = m[2][1] * m[3][3] - m[3][1] * m[2][3];
+ T SubFactor02 = m[2][1] * m[3][2] - m[3][1] * m[2][2];
+ T SubFactor03 = m[2][0] * m[3][3] - m[3][0] * m[2][3];
+ T SubFactor04 = m[2][0] * m[3][2] - m[3][0] * m[2][2];
+ T SubFactor05 = m[2][0] * m[3][1] - m[3][0] * m[2][1];
+
+ detail::tvec4<T> DetCof(
+ + (m[1][1] * SubFactor00 - m[1][2] * SubFactor01 + m[1][3] * SubFactor02),
+ - (m[1][0] * SubFactor00 - m[1][2] * SubFactor03 + m[1][3] * SubFactor04),
+ + (m[1][0] * SubFactor01 - m[1][1] * SubFactor03 + m[1][3] * SubFactor05),
+ - (m[1][0] * SubFactor02 - m[1][1] * SubFactor04 + m[1][2] * SubFactor05));
+
+ return m[0][0] * DetCof[0]
+ + m[0][1] * DetCof[1]
+ + m[0][2] * DetCof[2]
+ + m[0][3] * DetCof[3];
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tmat2x2<T> inverse
+ (
+ detail::tmat2x2<T> const & m
+ )
+ {
+ GLM_STATIC_ASSERT(detail::type<T>::is_float, "'inverse' only accept floating-point inputs");
+
+ //valType Determinant = m[0][0] * m[1][1] - m[1][0] * m[0][1];
+ T Determinant = determinant(m);
+
+ detail::tmat2x2<T> Inverse(
+ + m[1][1] / Determinant,
+ - m[0][1] / Determinant,
+ - m[1][0] / Determinant,
+ + m[0][0] / Determinant);
+
+ return Inverse;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tmat3x3<T> inverse
+ (
+ detail::tmat3x3<T> const & m
+ )
+ {
+ GLM_STATIC_ASSERT(detail::type<T>::is_float, "'inverse' only accept floating-point inputs");
+
+ //valType Determinant = m[0][0] * (m[1][1] * m[2][2] - m[2][1] * m[1][2])
+ // - m[1][0] * (m[0][1] * m[2][2] - m[2][1] * m[0][2])
+ // + m[2][0] * (m[0][1] * m[1][2] - m[1][1] * m[0][2]);
+
+ T Determinant = determinant(m);
+
+ detail::tmat3x3<T> Inverse(detail::tmat3x3<T>::null);
+ Inverse[0][0] = + (m[1][1] * m[2][2] - m[2][1] * m[1][2]);
+ Inverse[1][0] = - (m[1][0] * m[2][2] - m[2][0] * m[1][2]);
+ Inverse[2][0] = + (m[1][0] * m[2][1] - m[2][0] * m[1][1]);
+ Inverse[0][1] = - (m[0][1] * m[2][2] - m[2][1] * m[0][2]);
+ Inverse[1][1] = + (m[0][0] * m[2][2] - m[2][0] * m[0][2]);
+ Inverse[2][1] = - (m[0][0] * m[2][1] - m[2][0] * m[0][1]);
+ Inverse[0][2] = + (m[0][1] * m[1][2] - m[1][1] * m[0][2]);
+ Inverse[1][2] = - (m[0][0] * m[1][2] - m[1][0] * m[0][2]);
+ Inverse[2][2] = + (m[0][0] * m[1][1] - m[1][0] * m[0][1]);
+ Inverse /= Determinant;
+
+ return Inverse;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tmat4x4<T> inverse
+ (
+ detail::tmat4x4<T> const & m
+ )
+ {
+ GLM_STATIC_ASSERT(detail::type<T>::is_float, "'inverse' only accept floating-point inputs");
+
+ T Coef00 = m[2][2] * m[3][3] - m[3][2] * m[2][3];
+ T Coef02 = m[1][2] * m[3][3] - m[3][2] * m[1][3];
+ T Coef03 = m[1][2] * m[2][3] - m[2][2] * m[1][3];
+
+ T Coef04 = m[2][1] * m[3][3] - m[3][1] * m[2][3];
+ T Coef06 = m[1][1] * m[3][3] - m[3][1] * m[1][3];
+ T Coef07 = m[1][1] * m[2][3] - m[2][1] * m[1][3];
+
+ T Coef08 = m[2][1] * m[3][2] - m[3][1] * m[2][2];
+ T Coef10 = m[1][1] * m[3][2] - m[3][1] * m[1][2];
+ T Coef11 = m[1][1] * m[2][2] - m[2][1] * m[1][2];
+
+ T Coef12 = m[2][0] * m[3][3] - m[3][0] * m[2][3];
+ T Coef14 = m[1][0] * m[3][3] - m[3][0] * m[1][3];
+ T Coef15 = m[1][0] * m[2][3] - m[2][0] * m[1][3];
+
+ T Coef16 = m[2][0] * m[3][2] - m[3][0] * m[2][2];
+ T Coef18 = m[1][0] * m[3][2] - m[3][0] * m[1][2];
+ T Coef19 = m[1][0] * m[2][2] - m[2][0] * m[1][2];
+
+ T Coef20 = m[2][0] * m[3][1] - m[3][0] * m[2][1];
+ T Coef22 = m[1][0] * m[3][1] - m[3][0] * m[1][1];
+ T Coef23 = m[1][0] * m[2][1] - m[2][0] * m[1][1];
+
+ detail::tvec4<T> const SignA(+1, -1, +1, -1);
+ detail::tvec4<T> const SignB(-1, +1, -1, +1);
+
+ detail::tvec4<T> Fac0(Coef00, Coef00, Coef02, Coef03);
+ detail::tvec4<T> Fac1(Coef04, Coef04, Coef06, Coef07);
+ detail::tvec4<T> Fac2(Coef08, Coef08, Coef10, Coef11);
+ detail::tvec4<T> Fac3(Coef12, Coef12, Coef14, Coef15);
+ detail::tvec4<T> Fac4(Coef16, Coef16, Coef18, Coef19);
+ detail::tvec4<T> Fac5(Coef20, Coef20, Coef22, Coef23);
+
+ detail::tvec4<T> Vec0(m[1][0], m[0][0], m[0][0], m[0][0]);
+ detail::tvec4<T> Vec1(m[1][1], m[0][1], m[0][1], m[0][1]);
+ detail::tvec4<T> Vec2(m[1][2], m[0][2], m[0][2], m[0][2]);
+ detail::tvec4<T> Vec3(m[1][3], m[0][3], m[0][3], m[0][3]);
+
+ detail::tvec4<T> Inv0 = SignA * (Vec1 * Fac0 - Vec2 * Fac1 + Vec3 * Fac2);
+ detail::tvec4<T> Inv1 = SignB * (Vec0 * Fac0 - Vec2 * Fac3 + Vec3 * Fac4);
+ detail::tvec4<T> Inv2 = SignA * (Vec0 * Fac1 - Vec1 * Fac3 + Vec3 * Fac5);
+ detail::tvec4<T> Inv3 = SignB * (Vec0 * Fac2 - Vec1 * Fac4 + Vec2 * Fac5);
+
+ detail::tmat4x4<T> Inverse(Inv0, Inv1, Inv2, Inv3);
+
+ detail::tvec4<T> Row0(Inverse[0][0], Inverse[1][0], Inverse[2][0], Inverse[3][0]);
+
+ T Determinant = glm::dot(m[0], Row0);
+
+ Inverse /= Determinant;
+
+ return Inverse;
+ }
+
+ }//namespace matrix
+ }//namespace function
+ }//namespace core
+}//namespace glm
diff --git a/src/glm/core/func_noise.hpp b/src/glm/core/func_noise.hpp
new file mode 100644
index 0000000..0dd0631
--- /dev/null
+++ b/src/glm/core/func_noise.hpp
@@ -0,0 +1,62 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2008-08-01
+// Updated : 2008-09-10
+// Licence : This source is under MIT License
+// File : glm/core/func_noise.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_core_func_noise
+#define glm_core_func_noise
+
+namespace glm
+{
+ namespace core{
+ namespace function{
+ // Define all noise functions from Section 8.9 of GLSL 1.30.8 specification. Included in glm namespace.
+ namespace noise{
+
+ /// \addtogroup core_funcs
+ ///@{
+
+ //! Returns a 1D noise value based on the input value x.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/noise1.xml">GLSL noise1 man page</a>
+ //! \li GLSL 1.30.08 specification, section 8.9
+ template <typename genType>
+ typename genType::value_type noise1(genType const & x);
+
+ //! Returns a 2D noise value based on the input value x.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/noise2.xml">GLSL noise2 man page</a>
+ //! \li GLSL 1.30.08 specification, section 8.9
+ template <typename genType>
+ detail::tvec2<typename genType::value_type> noise2(genType const & x);
+
+ //! Returns a 3D noise value based on the input value x.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/noise3.xml">GLSL noise3 man page</a>
+ //! \li GLSL 1.30.08 specification, section 8.9
+ template <typename genType>
+ detail::tvec3<typename genType::value_type> noise3(genType const & x);
+
+ //! Returns a 4D noise value based on the input value x.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/noise4.xml">GLSL noise4 man page</a>
+ //! \li GLSL 1.30.08 specification, section 8.9
+ template <typename genType>
+ detail::tvec4<typename genType::value_type> noise4(genType const & x);
+
+ ///@}
+
+ }//namespace noise
+ }//namespace function
+ }//namespace core
+
+ using namespace core::function::noise;
+}//namespace glm
+
+#include "func_noise.inl"
+
+#endif//glm_core_func_noise
diff --git a/src/glm/core/func_noise.inl b/src/glm/core/func_noise.inl
new file mode 100644
index 0000000..f5a02dc
--- /dev/null
+++ b/src/glm/core/func_noise.inl
@@ -0,0 +1,21 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2008-08-01
+// Updated : 2011-04-14
+// Licence : This source is under MIT License
+// File : glm/core/func_noise.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm
+{
+ namespace core{
+ namespace function{
+ namespace noise{
+
+
+
+ }//namespace noise
+ }//namespace function
+ }//namespace core
+}//namespace glm
diff --git a/src/glm/core/func_packing.hpp b/src/glm/core/func_packing.hpp
new file mode 100644
index 0000000..a84036a
--- /dev/null
+++ b/src/glm/core/func_packing.hpp
@@ -0,0 +1,132 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2010-03-17
+// Updated : 2010-03-17
+// Licence : This source is under MIT License
+// File : glm/core/func_packing.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_core_func_packing
+#define glm_core_func_packing
+
+namespace glm
+{
+ namespace core{
+ namespace function{
+ //! Define packing functions from section 8.4 floating-point pack and unpack functions of GLSL 4.00.8 specification
+ namespace packing
+ {
+ /// \addtogroup core_funcs
+ ///@{
+
+ //! First, converts each component of the normalized floating-point value v into 8- or 16-bit integer values.
+ //! Then, the results are packed into the returned 32-bit unsigned integer.
+ //!
+ //! The conversion for component c of v to fixed point is done as follows:
+ //! packUnorm2x16: round(clamp(c, 0, +1) * 65535.0)
+ //!
+ //! The first component of the vector will be written to the least significant bits of the output;
+ //! the last component will be written to the most significant bits.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/packUnorm2x16.xml">GLSL packUnorm2x16 man page</a>
+ //! \li GLSL 4.00.08 specification, section 8.4
+ detail::uint32 packUnorm2x16(detail::tvec2<detail::float32> const & v);
+
+ //! First, converts each component of the normalized floating-point value v into 8- or 16-bit integer values.
+ //! Then, the results are packed into the returned 32-bit unsigned integer.
+ //!
+ //! The conversion for component c of v to fixed point is done as follows:
+ //! packUnorm4x8: round(clamp(c, 0, +1) * 255.0)
+ //!
+ //! The first component of the vector will be written to the least significant bits of the output;
+ //! the last component will be written to the most significant bits.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/packUnorm4x8.xml">GLSL packUnorm4x8 man page</a>
+ //! \li GLSL 4.00.08 specification, section 8.4
+ detail::uint32 packUnorm4x8(detail::tvec4<detail::float32> const & v);
+
+ //! First, converts each component of the normalized floating-point value v into 8- or 16-bit integer values.
+ //! Then, the results are packed into the returned 32-bit unsigned integer.
+ //!
+ //! The conversion for component c of v to fixed point is done as follows:
+ //! packSnorm4x8: round(clamp(c, -1, +1) * 127.0)
+ //!
+ //! The first component of the vector will be written to the least significant bits of the output;
+ //! the last component will be written to the most significant bits.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/packSnorm4x8.xml">GLSL packSnorm4x8 man page</a>
+ //! \li GLSL 4.00.08 specification, section 8.4
+ detail::uint32 packSnorm4x8(detail::tvec4<detail::float32> const & v);
+
+ //! First, unpacks a single 32-bit unsigned integer p into a pair of 16-bit unsigned integers, four 8-bit unsigned integers, or four 8-bit signed integers.
+ //! Then, each component is converted to a normalized floating-point value to generate the returned two- or four-component vector.
+ //!
+ //! The conversion for unpacked fixed-point value f to floating point is done as follows:
+ //! unpackUnorm2x16: f / 65535.0
+ //!
+ //! The first component of the returned vector will be extracted from the least significant bits of the input;
+ //! the last component will be extracted from the most significant bits.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/unpackUnorm2x16.xml">GLSL unpackUnorm2x16 man page</a>
+ //! \li GLSL 4.00.08 specification, section 8.4
+ detail::tvec2<detail::float32> unpackUnorm2x16(detail::uint32 const & p);
+
+ //! First, unpacks a single 32-bit unsigned integer p into a pair of 16-bit unsigned integers, four 8-bit unsigned integers, or four 8-bit signed integers.
+ //! Then, each component is converted to a normalized floating-point value to generate the returned two- or four-component vector.
+ //!
+ //! The conversion for unpacked fixed-point value f to floating point is done as follows:
+ //! unpackUnorm4x8: f / 255.0
+ //!
+ //! The first component of the returned vector will be extracted from the least significant bits of the input;
+ //! the last component will be extracted from the most significant bits.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/unpackUnorm4x8.xml">GLSL unpackUnorm4x8 man page</a>
+ //! \li GLSL 4.00.08 specification, section 8.4
+ detail::tvec4<detail::float32> unpackUnorm4x8(detail::uint32 const & p);
+
+ //! First, unpacks a single 32-bit unsigned integer p into a pair of 16-bit unsigned integers, four 8-bit unsigned integers, or four 8-bit signed integers.
+ //! Then, each component is converted to a normalized floating-point value to generate the returned two- or four-component vector.
+ //!
+ //! The conversion for unpacked fixed-point value f to floating point is done as follows:
+ //! unpackSnorm4x8: clamp(f / 127.0, -1, +1)
+ //!
+ //! The first component of the returned vector will be extracted from the least significant bits of the input;
+ //! the last component will be extracted from the most significant bits.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/unpackSnorm4x8.xml">GLSL unpackSnorm4x8 man page</a>
+ //! \li GLSL 4.00.08 specification, section 8.4
+ detail::tvec4<detail::float32> unpackSnorm4x8(detail::uint32 const & p);
+
+ //! Returns a double-precision value obtained by packing the components of v into a 64-bit value.
+ //! If an IEEE 754 Inf or NaN is created, it will not signal, and the resulting floating point value is unspecified.
+ //! Otherwise, the bit- level representation of v is preserved.
+ //! The first vector component specifies the 32 least significant bits;
+ //! the second component specifies the 32 most significant bits.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/packDouble2x32.xml">GLSL packDouble2x32 man page</a>
+ //! \li GLSL 4.00.08 specification, section 8.4
+ double packDouble2x32(detail::tvec2<detail::uint32> const & v);
+
+ //! Returns a two-component unsigned integer vector representation of v.
+ //! The bit-level representation of v is preserved.
+ //! The first component of the vector contains the 32 least significant bits of the double;
+ //! the second component consists the 32 most significant bits.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/unpackDouble2x32.xml">GLSL unpackDouble2x32 man page</a>
+ //! \li GLSL 4.00.08 specification, section 8.4
+ detail::tvec2<detail::uint32> unpackDouble2x32(double const & v);
+
+ ///@}
+
+ }//namespace packing
+ }//namespace function
+ }//namespace core
+
+ using namespace core::function::packing;
+}//namespace glm
+
+#include "func_packing.inl"
+
+#endif//glm_core_func_packing
+
diff --git a/src/glm/core/func_packing.inl b/src/glm/core/func_packing.inl
new file mode 100644
index 0000000..d582b0e
--- /dev/null
+++ b/src/glm/core/func_packing.inl
@@ -0,0 +1,94 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2010-03-17
+// Updated : 2010-03-17
+// Licence : This source is under MIT License
+// File : glm/core/func_packing.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm
+{
+ namespace detail
+ {
+
+ }//namespace detail
+
+ namespace core{
+ namespace function{
+ namespace packing
+ {
+ GLM_FUNC_QUALIFIER detail::uint32 packUnorm2x16(detail::tvec2<detail::float32> const & v)
+ {
+ detail::uint16 A((detail::uint16)round(clamp(v.x, 0.0f, 1.0f) * 65535.0f));
+ detail::uint16 B((detail::uint16)round(clamp(v.y, 0.0f, 1.0f) * 65535.0f));
+ return detail::uint32((B << 16) | A);
+ }
+
+ GLM_FUNC_QUALIFIER detail::uint32 packUnorm4x8(detail::tvec4<detail::float32> const & v)
+ {
+ detail::uint8 A((detail::uint8)round(clamp(v.x, 0.0f, 1.0f) * 255.0f));
+ detail::uint8 B((detail::uint8)round(clamp(v.y, 0.0f, 1.0f) * 255.0f));
+ detail::uint8 C((detail::uint8)round(clamp(v.z, 0.0f, 1.0f) * 255.0f));
+ detail::uint8 D((detail::uint8)round(clamp(v.w, 0.0f, 1.0f) * 255.0f));
+ return detail::uint32((D << 24) | (C << 16) | (B << 8) | A);
+ }
+
+ GLM_FUNC_QUALIFIER detail::uint32 packSnorm4x8(detail::tvec4<detail::float32> const & v)
+ {
+ detail::uint8 A((detail::uint8)round(clamp(v.x,-1.0f, 1.0f) * 255.0f));
+ detail::uint8 B((detail::uint8)round(clamp(v.y,-1.0f, 1.0f) * 255.0f));
+ detail::uint8 C((detail::uint8)round(clamp(v.z,-1.0f, 1.0f) * 255.0f));
+ detail::uint8 D((detail::uint8)round(clamp(v.w,-1.0f, 1.0f) * 255.0f));
+ return detail::uint32((D << 24) | (C << 16) | (B << 8) | A);
+ }
+
+ GLM_FUNC_QUALIFIER detail::tvec2<detail::float32> unpackUnorm2x16(detail::uint32 const & p)
+ {
+ detail::uint16 A(detail::uint16(p >> 0));
+ detail::uint16 B(detail::uint16(p >> 16));
+ return detail::tvec2<detail::float32>(
+ A * 1.0f / 65535.0f,
+ B * 1.0f / 65535.0f);
+ }
+
+ GLM_FUNC_QUALIFIER detail::tvec4<detail::float32> unpackUnorm4x8(detail::uint32 const & p)
+ {
+ detail::uint8 A(detail::uint8(p >> 0));
+ detail::uint8 B(detail::uint8(p >> 8));
+ detail::uint8 C(detail::uint8(p >> 16));
+ detail::uint8 D(detail::uint8(p >> 24));
+ return detail::tvec4<detail::float32>(
+ A * 1.0f / 255.0f,
+ B * 1.0f / 255.0f,
+ C * 1.0f / 255.0f,
+ D * 1.0f / 255.0f);
+ }
+
+ GLM_FUNC_QUALIFIER detail::tvec4<detail::float32> unpackSnorm4x8(detail::uint32 const & p)
+ {
+ detail::uint8 A(detail::uint8(p >> 0));
+ detail::uint8 B(detail::uint8(p >> 8));
+ detail::uint8 C(detail::uint8(p >> 16));
+ detail::uint8 D(detail::uint8(p >> 24));
+ return clamp(detail::tvec4<detail::float32>(
+ A * 1.0f / 127.0f,
+ B * 1.0f / 127.0f,
+ C * 1.0f / 127.0f,
+ D * 1.0f / 127.0f), -1.0f, 1.0f);
+ }
+
+ GLM_FUNC_QUALIFIER double packDouble2x32(detail::tvec2<detail::uint32> const & v)
+ {
+ return *(double*)&v;
+ }
+
+ GLM_FUNC_QUALIFIER detail::tvec2<detail::uint32> unpackDouble2x32(double const & v)
+ {
+ return *(detail::tvec2<detail::uint32>*)&v;
+ }
+
+ }//namespace packing
+ }//namespace function
+ }//namespace core
+}//namespace glm
diff --git a/src/glm/core/func_trigonometric.hpp b/src/glm/core/func_trigonometric.hpp
new file mode 100644
index 0000000..4626f1e
--- /dev/null
+++ b/src/glm/core/func_trigonometric.hpp
@@ -0,0 +1,156 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2008-08-01
+// Updated : 2008-09-10
+// Licence : This source is under MIT License
+// File : glm/core/func_trigonometric.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_core_func_trigonometric
+#define glm_core_func_trigonometric
+
+namespace glm
+{
+ namespace core{
+ namespace function{
+ //! Define Angle and trigonometry functions
+ //! from Section 8.1 of GLSL 1.30.8 specification.
+ //! Included in glm namespace.
+ namespace trigonometric{
+
+ /// \addtogroup core_funcs
+ ///@{
+
+ //! Converts degrees to radians and returns the result.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/radians.xml">GLSL radians man page</a>
+ //! \li GLSL 1.30.08 specification, section 8.1
+ template <typename genType>
+ genType radians(genType const & degrees);
+
+ //! Converts radians to degrees and returns the result.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/degrees.xml">GLSL degrees man page</a>
+ //! \li GLSL 1.30.08 specification, section 8.1
+ template <typename genType>
+ genType degrees(genType const & radians);
+
+ //! The standard trigonometric sine function.
+ //! The values returned by this function will range from [-1, 1].
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/sin.xml">GLSL sin man page</a>
+ //! \li GLSL 1.30.08 specification, section 8.1
+ template <typename genType>
+ genType sin(genType const & angle);
+
+ //! The standard trigonometric cosine function.
+ //! The values returned by this function will range from [-1, 1].
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/cos.xml">GLSL cos man page</a>
+ //! \li GLSL 1.30.08 specification, section 8.1
+ template <typename genType>
+ genType cos(genType const & angle);
+
+ //! The standard trigonometric tangent function.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/tan.xml">GLSL tan man page</a>
+ //! \li GLSL 1.30.08 specification, section 8.1
+ template <typename genType>
+ genType tan(genType const & angle);
+
+ //! Arc sine. Returns an angle whose sine is x.
+ //! The range of values returned by this function is [-PI/2, PI/2].
+ //! Results are undefined if |x| > 1.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/asin.xml">GLSL asin man page</a>
+ //! \li GLSL 1.30.08 specification, section 8.1
+ template <typename genType>
+ genType asin(genType const & x);
+
+ //! Arc cosine. Returns an angle whose sine is x.
+ //! The range of values returned by this function is [0, PI].
+ //! Results are undefined if |x| > 1.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/acos.xml">GLSL acos man page</a>
+ //! \li GLSL 1.30.08 specification, section 8.1
+ template <typename genType>
+ genType acos(genType const & x);
+
+ //! Arc tangent. Returns an angle whose tangent is y/x.
+ //! The signs of x and y are used to determine what
+ //! quadrant the angle is in. The range of values returned
+ //! by this function is [-PI, PI]. Results are undefined
+ //! if x and y are both 0.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/atan.xml">GLSL atan man page</a>
+ //! \li GLSL 1.30.08 specification, section 8.1
+ template <typename genType>
+ genType atan(genType const & y, genType const & x);
+
+ //! Arc tangent. Returns an angle whose tangent is y_over_x.
+ //! The range of values returned by this function is [-PI/2, PI/2].
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/atan.xml">GLSL atan man page</a>
+ //! \li GLSL 1.30.08 specification, section 8.1
+ template <typename genType>
+ genType atan(genType const & y_over_x);
+
+ //! Returns the hyperbolic sine function, (exp(x) - exp(-x)) / 2
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/sinh.xml">GLSL sinh man page</a>
+ //! \li GLSL 1.30.08 specification, section 8.1
+ template <typename genType>
+ genType sinh(genType const & angle);
+
+ //! Returns the hyperbolic cosine function, (exp(x) + exp(-x)) / 2
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/cosh.xml">GLSL cosh man page</a>
+ //! \li GLSL 1.30.08 specification, section 8.1
+ template <typename genType>
+ genType cosh(genType const & angle);
+
+ //! Returns the hyperbolic tangent function, sinh(angle) / cosh(angle)
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/tanh.xml">GLSL tanh man page</a>
+ //! \li GLSL 1.30.08 specification, section 8.1
+ template <typename genType>
+ genType tanh(genType const & angle);
+
+ //! Arc hyperbolic sine; returns the inverse of sinh.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/asinh.xml">GLSL asinh man page</a>
+ //! \li GLSL 1.30.08 specification, section 8.1
+ template <typename genType>
+ genType asinh(genType const & x);
+
+ //! Arc hyperbolic cosine; returns the non-negative inverse
+ //! of cosh. Results are undefined if x < 1.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/acosh.xml">GLSL acosh man page</a>
+ //! \li GLSL 1.30.08 specification, section 8.1
+ template <typename genType>
+ genType acosh(genType const & x);
+
+ //! Arc hyperbolic tangent; returns the inverse of tanh.
+ //! Results are undefined if abs(x) >= 1.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/atanh.xml">GLSL atanh man page</a>
+ //! \li GLSL 1.30.08 specification, section 8.1
+ template <typename genType>
+ genType atanh(genType const & x);
+
+ ///@}
+
+ }//namespace trigonometric
+ }//namespace function
+ }//namespace core
+
+ using namespace core::function::trigonometric;
+}//namespace glm
+
+#include "func_trigonometric.inl"
+
+#endif//glm_core_func_trigonometric
+
+
diff --git a/src/glm/core/func_trigonometric.inl b/src/glm/core/func_trigonometric.inl
new file mode 100644
index 0000000..07490e9
--- /dev/null
+++ b/src/glm/core/func_trigonometric.inl
@@ -0,0 +1,745 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2008-08-03
+// Updated : 2008-09-14
+// Licence : This source is under MIT License
+// File : glm/core/func_trigonometric.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm
+{
+ namespace core{
+ namespace function{
+ namespace trigonometric{
+
+ // radians
+ template <typename genType>
+ GLM_FUNC_QUALIFIER genType radians
+ (
+ genType const & degrees
+ )
+ {
+ GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'radians' only accept floating-point input");
+
+ const genType pi = genType(3.1415926535897932384626433832795);
+ return degrees * (pi / genType(180));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<T> radians
+ (
+ detail::tvec2<T> const & degrees
+ )
+ {
+ return detail::tvec2<T>(
+ radians(degrees.x),
+ radians(degrees.y));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> radians
+ (
+ detail::tvec3<T> const & degrees
+ )
+ {
+ return detail::tvec3<T>(
+ radians(degrees.x),
+ radians(degrees.y),
+ radians(degrees.z));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<T> radians
+ (
+ detail::tvec4<T> const & degrees
+ )
+ {
+ return detail::tvec4<T>(
+ radians(degrees.x),
+ radians(degrees.y),
+ radians(degrees.z),
+ radians(degrees.w));
+ }
+
+ // degrees
+ template <typename genType>
+ GLM_FUNC_QUALIFIER genType degrees
+ (
+ genType const & radians
+ )
+ {
+ GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'degrees' only accept floating-point input");
+
+ const genType pi = genType(3.1415926535897932384626433832795);
+ return radians * (genType(180) / pi);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<T> degrees
+ (
+ detail::tvec2<T> const & radians
+ )
+ {
+ return detail::tvec2<T>(
+ degrees(radians.x),
+ degrees(radians.y));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> degrees
+ (
+ detail::tvec3<T> const & radians
+ )
+ {
+ return detail::tvec3<T>(
+ degrees(radians.x),
+ degrees(radians.y),
+ degrees(radians.z));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<T> degrees
+ (
+ detail::tvec4<T> const & radians
+ )
+ {
+ return detail::tvec4<T>(
+ degrees(radians.x),
+ degrees(radians.y),
+ degrees(radians.z),
+ degrees(radians.w));
+ }
+
+ // sin
+ template <typename genType>
+ GLM_FUNC_QUALIFIER genType sin
+ (
+ genType const & angle
+ )
+ {
+ GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'sin' only accept floating-point input");
+
+ return ::std::sin(angle);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<T> sin
+ (
+ detail::tvec2<T> const & angle
+ )
+ {
+ return detail::tvec2<T>(
+ sin(angle.x),
+ sin(angle.y));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> sin
+ (
+ detail::tvec3<T> const & angle
+ )
+ {
+ return detail::tvec3<T>(
+ sin(angle.x),
+ sin(angle.y),
+ sin(angle.z));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<T> sin
+ (
+ detail::tvec4<T> const & angle
+ )
+ {
+ return detail::tvec4<T>(
+ sin(angle.x),
+ sin(angle.y),
+ sin(angle.z),
+ sin(angle.w));
+ }
+
+ // cos
+ template <typename genType>
+ GLM_FUNC_QUALIFIER genType cos(genType const & angle)
+ {
+ GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'cos' only accept floating-point input");
+
+ return ::std::cos(angle);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<T> cos
+ (
+ detail::tvec2<T> const & angle
+ )
+ {
+ return detail::tvec2<T>(
+ cos(angle.x),
+ cos(angle.y));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> cos
+ (
+ detail::tvec3<T> const & angle
+ )
+ {
+ return detail::tvec3<T>(
+ cos(angle.x),
+ cos(angle.y),
+ cos(angle.z));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<T> cos
+ (
+ detail::tvec4<T> const & angle
+ )
+ {
+ return detail::tvec4<T>(
+ cos(angle.x),
+ cos(angle.y),
+ cos(angle.z),
+ cos(angle.w));
+ }
+
+ // tan
+ template <typename genType>
+ GLM_FUNC_QUALIFIER genType tan
+ (
+ genType const & angle
+ )
+ {
+ GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'tan' only accept floating-point input");
+
+ return ::std::tan(angle);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<T> tan
+ (
+ detail::tvec2<T> const & angle
+ )
+ {
+ return detail::tvec2<T>(
+ tan(angle.x),
+ tan(angle.y));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> tan
+ (
+ detail::tvec3<T> const & angle
+ )
+ {
+ return detail::tvec3<T>(
+ tan(angle.x),
+ tan(angle.y),
+ tan(angle.z));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<T> tan
+ (
+ detail::tvec4<T> const & angle
+ )
+ {
+ return detail::tvec4<T>(
+ tan(angle.x),
+ tan(angle.y),
+ tan(angle.z),
+ tan(angle.w));
+ }
+
+ // asin
+ template <typename genType>
+ GLM_FUNC_QUALIFIER genType asin
+ (
+ genType const & x
+ )
+ {
+ GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'asin' only accept floating-point input");
+
+ return ::std::asin(x);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<T> asin
+ (
+ detail::tvec2<T> const & x
+ )
+ {
+ return detail::tvec2<T>(
+ asin(x.x),
+ asin(x.y));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> asin
+ (
+ detail::tvec3<T> const & x
+ )
+ {
+ return detail::tvec3<T>(
+ asin(x.x),
+ asin(x.y),
+ asin(x.z));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<T> asin
+ (
+ detail::tvec4<T> const & x
+ )
+ {
+ return detail::tvec4<T>(
+ asin(x.x),
+ asin(x.y),
+ asin(x.z),
+ asin(x.w));
+ }
+
+ // acos
+ template <typename genType>
+ GLM_FUNC_QUALIFIER genType acos
+ (
+ genType const & x
+ )
+ {
+ GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'acos' only accept floating-point input");
+
+ return ::std::acos(x);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<T> acos
+ (
+ detail::tvec2<T> const & x
+ )
+ {
+ return detail::tvec2<T>(
+ acos(x.x),
+ acos(x.y));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> acos
+ (
+ detail::tvec3<T> const & x
+ )
+ {
+ return detail::tvec3<T>(
+ acos(x.x),
+ acos(x.y),
+ acos(x.z));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<T> acos
+ (
+ detail::tvec4<T> const & x
+ )
+ {
+ return detail::tvec4<T>(
+ acos(x.x),
+ acos(x.y),
+ acos(x.z),
+ acos(x.w));
+ }
+
+ // atan
+ template <typename genType>
+ GLM_FUNC_QUALIFIER genType atan
+ (
+ genType const & y,
+ genType const & x
+ )
+ {
+ GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'atan' only accept floating-point input");
+
+ return ::std::atan2(y, x);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<T> atan
+ (
+ detail::tvec2<T> const & y,
+ detail::tvec2<T> const & x
+ )
+ {
+ return detail::tvec2<T>(
+ atan(y.x, x.x),
+ atan(y.y, x.y));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> atan
+ (
+ detail::tvec3<T> const & y,
+ detail::tvec3<T> const & x
+ )
+ {
+ return detail::tvec3<T>(
+ atan(y.x, x.x),
+ atan(y.y, x.y),
+ atan(y.z, x.z));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<T> atan
+ (
+ detail::tvec4<T> const & y,
+ detail::tvec4<T> const & x
+ )
+ {
+ return detail::tvec4<T>(
+ atan(y.x, x.x),
+ atan(y.y, x.y),
+ atan(y.z, x.z),
+ atan(y.w, x.w));
+ }
+
+ template <typename genType>
+ GLM_FUNC_QUALIFIER genType atan
+ (
+ genType const & x
+ )
+ {
+ GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'atan' only accept floating-point input");
+
+ return ::std::atan(x);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<T> atan
+ (
+ detail::tvec2<T> const & x
+ )
+ {
+ return detail::tvec2<T>(
+ atan(x.x),
+ atan(x.y));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> atan
+ (
+ detail::tvec3<T> const & x
+ )
+ {
+ return detail::tvec3<T>(
+ atan(x.x),
+ atan(x.y),
+ atan(x.z));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<T> atan
+ (
+ detail::tvec4<T> const & x
+ )
+ {
+ return detail::tvec4<T>(
+ atan(x.x),
+ atan(x.y),
+ atan(x.z),
+ atan(x.w));
+ }
+
+ // sinh
+ template <typename genType>
+ GLM_FUNC_QUALIFIER genType sinh
+ (
+ genType const & angle
+ )
+ {
+ GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'sinh' only accept floating-point input");
+
+ return std::sinh(angle);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<T> sinh
+ (
+ detail::tvec2<T> const & angle
+ )
+ {
+ return detail::tvec2<T>(
+ sinh(angle.x),
+ sinh(angle.y));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> sinh
+ (
+ detail::tvec3<T> const & angle
+ )
+ {
+ return detail::tvec3<T>(
+ sinh(angle.x),
+ sinh(angle.y),
+ sinh(angle.z));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<T> sinh
+ (
+ detail::tvec4<T> const & angle
+ )
+ {
+ return detail::tvec4<T>(
+ sinh(angle.x),
+ sinh(angle.y),
+ sinh(angle.z),
+ sinh(angle.w));
+ }
+
+ // cosh
+ template <typename genType>
+ GLM_FUNC_QUALIFIER genType cosh
+ (
+ genType const & angle
+ )
+ {
+ GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'cosh' only accept floating-point input");
+
+ return std::cosh(angle);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<T> cosh
+ (
+ detail::tvec2<T> const & angle
+ )
+ {
+ return detail::tvec2<T>(
+ cosh(angle.x),
+ cosh(angle.y));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> cosh
+ (
+ detail::tvec3<T> const & angle
+ )
+ {
+ return detail::tvec3<T>(
+ cosh(angle.x),
+ cosh(angle.y),
+ cosh(angle.z));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<T> cosh
+ (
+ detail::tvec4<T> const & angle
+ )
+ {
+ return detail::tvec4<T>(
+ cosh(angle.x),
+ cosh(angle.y),
+ cosh(angle.z),
+ cosh(angle.w));
+ }
+
+ // tanh
+ template <typename genType>
+ GLM_FUNC_QUALIFIER genType tanh
+ (
+ genType const & angle
+ )
+ {
+ GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'tanh' only accept floating-point input");
+
+ return std::tanh(angle);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<T> tanh
+ (
+ detail::tvec2<T> const & angle
+ )
+ {
+ return detail::tvec2<T>(
+ tanh(angle.x),
+ tanh(angle.y));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> tanh
+ (
+ detail::tvec3<T> const & angle
+ )
+ {
+ return detail::tvec3<T>(
+ tanh(angle.x),
+ tanh(angle.y),
+ tanh(angle.z));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<T> tanh
+ (
+ detail::tvec4<T> const & angle
+ )
+ {
+ return detail::tvec4<T>(
+ tanh(angle.x),
+ tanh(angle.y),
+ tanh(angle.z),
+ tanh(angle.w));
+ }
+
+ // asinh
+ template <typename genType>
+ GLM_FUNC_QUALIFIER genType asinh
+ (
+ genType const & x
+ )
+ {
+ GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'asinh' only accept floating-point input");
+
+ return (x < genType(0) ? genType(-1) : (x > genType(0) ? genType(1) : genType(0))) * log(abs(x) + sqrt(genType(1) + x * x));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<T> asinh
+ (
+ detail::tvec2<T> const & x
+ )
+ {
+ return detail::tvec2<T>(
+ asinh(x.x),
+ asinh(x.y));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> asinh
+ (
+ detail::tvec3<T> const & x
+ )
+ {
+ return detail::tvec3<T>(
+ asinh(x.x),
+ asinh(x.y),
+ asinh(x.z));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<T> asinh
+ (
+ detail::tvec4<T> const & x
+ )
+ {
+ return detail::tvec4<T>(
+ asinh(x.x),
+ asinh(x.y),
+ asinh(x.z),
+ asinh(x.w));
+ }
+
+ // acosh
+ template <typename genType>
+ GLM_FUNC_QUALIFIER genType acosh
+ (
+ genType const & x
+ )
+ {
+ GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'acosh' only accept floating-point input");
+
+ if(x < genType(1))
+ return genType(0);
+ return log(x + sqrt(x * x - genType(1)));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<T> acosh
+ (
+ detail::tvec2<T> const & x
+ )
+ {
+ return detail::tvec2<T>(
+ acosh(x.x),
+ acosh(x.y));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> acosh
+ (
+ detail::tvec3<T> const & x
+ )
+ {
+ return detail::tvec3<T>(
+ acosh(x.x),
+ acosh(x.y),
+ acosh(x.z));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<T> acosh
+ (
+ detail::tvec4<T> const & x
+ )
+ {
+ return detail::tvec4<T>(
+ acosh(x.x),
+ acosh(x.y),
+ acosh(x.z),
+ acosh(x.w));
+ }
+
+ // atanh
+ template <typename genType>
+ GLM_FUNC_QUALIFIER genType atanh
+ (
+ genType const & x
+ )
+ {
+ GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'atanh' only accept floating-point input");
+
+ if(abs(x) >= genType(1))
+ return 0;
+ return genType(0.5) * log((genType(1) + x) / (genType(1) - x));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<T> atanh
+ (
+ detail::tvec2<T> const & x
+ )
+ {
+ return detail::tvec2<T>(
+ atanh(x.x),
+ atanh(x.y));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> atanh
+ (
+ detail::tvec3<T> const & x
+ )
+ {
+ return detail::tvec3<T>(
+ atanh(x.x),
+ atanh(x.y),
+ atanh(x.z));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<T> atanh
+ (
+ detail::tvec4<T> const & x
+ )
+ {
+ return detail::tvec4<T>(
+ atanh(x.x),
+ atanh(x.y),
+ atanh(x.z),
+ atanh(x.w));
+ }
+
+ }//namespace trigonometric
+ }//namespace function
+ }//namespace core
+}//namespace glm
diff --git a/src/glm/core/func_vector_relational.hpp b/src/glm/core/func_vector_relational.hpp
new file mode 100644
index 0000000..e8d9677
--- /dev/null
+++ b/src/glm/core/func_vector_relational.hpp
@@ -0,0 +1,215 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2008-08-03
+// Updated : 2008-09-09
+// Licence : This source is under MIT License
+// File : glm/core/func_vector_relational.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_core_func_vector_relational
+#define glm_core_func_vector_relational
+
+#include "_detail.hpp"
+
+namespace glm
+{
+ namespace core{
+ namespace function{
+ //! Define vector relational functions from Section 8.6 of GLSL 1.30.8 specification.
+ //! Included in glm namespace.
+ namespace vector_relational
+ {
+ /// \addtogroup core_funcs
+ ///@{
+
+ //! Returns the component-wise comparison result of x < y.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/lessThan.xml">GLSL lessThan man page</a>
+ //! \li GLSL 1.30.08 specification, section 8.6
+ template <typename T, template <typename> class vecType>
+ GLM_FUNC_QUALIFIER typename vecType<T>::bool_type lessThan
+ (
+ vecType<T> const & x,
+ vecType<T> const & y
+ )
+ {
+ GLM_STATIC_ASSERT(detail::is_vector<vecType<T> >::_YES,
+ "Invalid template instantiation of 'lessThan', GLM vector types required");
+ GLM_STATIC_ASSERT(detail::is_bool<T>::_NO,
+ "Invalid template instantiation of 'lessThan', GLM vector types required floating-point or integer value types vectors");
+
+ typename vecType<bool>::bool_type Result(vecType<bool>::null);
+ for(typename vecType<bool>::size_type i = 0; i < vecType<bool>::value_size(); ++i)
+ Result[i] = x[i] < y[i];
+
+ return Result;
+ }
+
+ //! Returns the component-wise comparison of result x <= y.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/lessThanEqual.xml">GLSL lessThanEqual man page</a>
+ //! \li GLSL 1.30.08 specification, section 8.6
+ template <typename T, template <typename> class vecType>
+ GLM_FUNC_QUALIFIER typename vecType<T>::bool_type lessThanEqual
+ (
+ vecType<T> const & x,
+ vecType<T> const & y
+ )
+ {
+ GLM_STATIC_ASSERT(detail::is_vector<vecType<T> >::_YES,
+ "Invalid template instantiation of 'lessThanEqual', GLM vector types required");
+ GLM_STATIC_ASSERT(detail::is_bool<T>::_NO,
+ "Invalid template instantiation of 'lessThanEqual', GLM vector types required floating-point or integer value types vectors");
+
+ typename vecType<bool>::bool_type Result(vecType<bool>::null);
+ for(typename vecType<bool>::size_type i = 0; i < vecType<bool>::value_size(); ++i)
+ Result[i] = x[i] <= y[i];
+ return Result;
+ }
+
+ //! Returns the component-wise comparison of result x > y.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/greaterThan.xml">GLSL greaterThan man page</a>
+ //! \li GLSL 1.30.08 specification, section 8.6
+ template <typename T, template <typename> class vecType>
+ GLM_FUNC_QUALIFIER typename vecType<T>::bool_type greaterThan
+ (
+ vecType<T> const & x,
+ vecType<T> const & y
+ )
+ {
+ GLM_STATIC_ASSERT(detail::is_vector<vecType<T> >::_YES,
+ "Invalid template instantiation of 'greaterThan', GLM vector types required");
+ GLM_STATIC_ASSERT(detail::is_bool<T>::_NO,
+ "Invalid template instantiation of 'greaterThan', GLM vector types required floating-point or integer value types vectors");
+
+ typename vecType<bool>::bool_type Result(vecType<bool>::null);
+ for(typename vecType<bool>::size_type i = 0; i < vecType<bool>::value_size(); ++i)
+ Result[i] = x[i] > y[i];
+ return Result;
+ }
+
+ //! Returns the component-wise comparison of result x >= y.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/greaterThanEqual.xml">GLSL greaterThanEqual man page</a>
+ //! \li GLSL 1.30.08 specification, section 8.6
+ template <typename T, template <typename> class vecType>
+ GLM_FUNC_QUALIFIER typename vecType<T>::bool_type greaterThanEqual
+ (
+ vecType<T> const & x,
+ vecType<T> const & y
+ )
+ {
+ GLM_STATIC_ASSERT(detail::is_vector<vecType<T> >::_YES,
+ "Invalid template instantiation of 'greaterThanEqual', GLM vector types required");
+ GLM_STATIC_ASSERT(detail::is_bool<T>::_NO,
+ "Invalid template instantiation of 'greaterThanEqual', GLM vector types required floating-point or integer value types vectors");
+
+ typename vecType<bool>::bool_type Result(vecType<bool>::null);
+ for(typename vecType<bool>::size_type i = 0; i < vecType<bool>::value_size(); ++i)
+ Result[i] = x[i] >= y[i];
+ return Result;
+ }
+
+ //! Returns the component-wise comparison of result x == y.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/equal.xml">GLSL equal man page</a>
+ //! \li GLSL 1.30.08 specification, section 8.6
+ template <typename T, template <typename> class vecType>
+ GLM_FUNC_QUALIFIER typename vecType<T>::bool_type equal
+ (
+ vecType<T> const & x,
+ vecType<T> const & y
+ )
+ {
+ GLM_STATIC_ASSERT(detail::is_vector<vecType<T> >::_YES,
+ "Invalid template instantiation of 'equal', GLM vector types required");
+
+ typename vecType<bool>::bool_type Result(vecType<bool>::null);
+ for(typename vecType<bool>::size_type i = 0; i < vecType<bool>::value_size(); ++i)
+ Result[i] = x[i] == y[i];
+ return Result;
+ }
+
+ //! Returns the component-wise comparison of result x != y.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/notEqual.xml">GLSL notEqual man page</a>
+ //! \li GLSL 1.30.08 specification, section 8.6
+ template <typename T, template <typename> class vecType>
+ GLM_FUNC_QUALIFIER typename vecType<T>::bool_type notEqual
+ (
+ vecType<T> const & x,
+ vecType<T> const & y
+ )
+ {
+ GLM_STATIC_ASSERT(detail::is_vector<vecType<T> >::_YES,
+ "Invalid template instantiation of 'notEqual', GLM vector types required");
+
+ typename vecType<bool>::bool_type Result(vecType<bool>::null);
+ for(typename vecType<bool>::size_type i = 0; i < vecType<bool>::value_size(); ++i)
+ Result[i] = x[i] != y[i];
+ return Result;
+ }
+
+ //! Returns true if any component of x is true.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/any.xml">GLSL any man page</a>
+ //! \li GLSL 1.30.08 specification, section 8.6
+ template <template <typename> class vecType>
+ GLM_FUNC_QUALIFIER bool any(vecType<bool> const & v)
+ {
+ GLM_STATIC_ASSERT(detail::is_vector<vecType<bool> >::_YES,
+ "Invalid template instantiation of 'any', GLM boolean vector types required");
+
+ bool Result = false;
+ for(typename vecType<bool>::size_type i = 0; i < vecType<bool>::value_size(); ++i)
+ Result = Result || v[i];
+ return Result;
+ }
+
+ //! Returns true if all components of x are true.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/all.xml">GLSL all man page</a>
+ //! \li GLSL 1.30.08 specification, section 8.6
+ template <template <typename> class vecType>
+ GLM_FUNC_QUALIFIER bool all(vecType<bool> const & v)
+ {
+ GLM_STATIC_ASSERT(detail::is_vector<vecType<bool> >::_YES,
+ "Invalid template instantiation of 'all', GLM boolean vector types required");
+
+ bool Result = true;
+ for(typename vecType<bool>::size_type i = 0; i < vecType<bool>::value_size(); ++i)
+ Result = Result && v[i];
+ return Result;
+ }
+
+ //! Returns the component-wise logical complement of x.
+ //! /!\ Because of language incompatibilities between C++ and GLSL, GLM defines the function not but not_ instead.
+ //!
+ //! \li <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/not.xml">GLSL not man page</a>
+ //! \li GLSL 1.30.08 specification, section 8.6
+ template <template <typename> class vecType>
+ GLM_FUNC_QUALIFIER vecType<bool> not_(vecType<bool> const & v)
+ {
+ GLM_STATIC_ASSERT(detail::is_vector<vecType<bool> >::_YES,
+ "Invalid template instantiation of 'not_', GLM vector types required");
+
+ typename vecType<bool>::bool_type Result(vecType<bool>::null);
+ for(typename vecType<bool>::size_type i = 0; i < vecType<bool>::value_size(); ++i)
+ Result[i] = !v[i];
+ return Result;
+ }
+
+ ///@}
+
+ }//namespace vector_relational
+ }//namespace function
+ }//namespace core
+
+ using namespace core::function::vector_relational;
+}//namespace glm
+
+#include "func_vector_relational.inl"
+
+#endif//glm_core_func_vector_relational
diff --git a/src/glm/core/func_vector_relational.inl b/src/glm/core/func_vector_relational.inl
new file mode 100644
index 0000000..35fc30e
--- /dev/null
+++ b/src/glm/core/func_vector_relational.inl
@@ -0,0 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2008-08-03
+// Updated : 2008-09-14
+// Licence : This source is under MIT License
+// File : glm/core/func_vector_relational.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm
+{
+ namespace core{
+ namespace function{
+ namespace vector_relational{
+
+ }//namespace vector_relational
+ }//namespace function
+ }//namespace core
+}//namespace glm
+
diff --git a/src/glm/core/hint.hpp b/src/glm/core/hint.hpp
new file mode 100644
index 0000000..ae75a79
--- /dev/null
+++ b/src/glm/core/hint.hpp
@@ -0,0 +1,21 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2008-08-14
+// Updated : 2008-08-14
+// Licence : This source is under MIT License
+// File : glm/core/hint.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_core_type
+#define glm_core_type
+
+namespace glm
+{
+ // Use dont_care, nicest and fastest to optimize implementations.
+ class dont_care {};
+ class nicest {};
+ class fastest {};
+};
+
+#endif//glm_core_type
diff --git a/src/glm/core/intrinsic_common.hpp b/src/glm/core/intrinsic_common.hpp
new file mode 100644
index 0000000..455464b
--- /dev/null
+++ b/src/glm/core/intrinsic_common.hpp
@@ -0,0 +1,70 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2009-05-11
+// Updated : 2009-05-11
+// Licence : This source is under MIT License
+// File : glm/core/intrinsic_common.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_detail_intrinsic_common
+#define glm_detail_intrinsic_common
+
+#include "setup.hpp"
+
+#if((GLM_ARCH & GLM_ARCH_SSE2) != GLM_ARCH_SSE2)
+# error "SSE2 instructions not supported or enabled"
+#else
+
+namespace glm{
+namespace detail
+{
+ __m128 sse_abs_ps(__m128 x);
+
+ __m128 sse_sgn_ps(__m128 x);
+
+ //floor
+ __m128 sse_flr_ps(__m128 v);
+
+ //trunc
+ __m128 sse_trc_ps(__m128 v);
+
+ //round
+ __m128 sse_nd_ps(__m128 v);
+
+ //roundEven
+ __m128 sse_rde_ps(__m128 v);
+
+ __m128 sse_rnd_ps(__m128 x);
+
+ __m128 sse_ceil_ps(__m128 v);
+
+ __m128 sse_frc_ps(__m128 x);
+
+ __m128 sse_mod_ps(__m128 x, __m128 y);
+
+ __m128 sse_modf_ps(__m128 x, __m128i & i);
+
+ //GLM_FUNC_QUALIFIER __m128 sse_min_ps(__m128 x, __m128 y)
+
+ //GLM_FUNC_QUALIFIER __m128 sse_max_ps(__m128 x, __m128 y)
+
+ __m128 sse_clp_ps(__m128 v, __m128 minVal, __m128 maxVal);
+
+ __m128 sse_mix_ps(__m128 v1, __m128 v2, __m128 a);
+
+ __m128 sse_stp_ps(__m128 edge, __m128 x);
+
+ __m128 sse_ssp_ps(__m128 edge0, __m128 edge1, __m128 x);
+
+ __m128 sse_nan_ps(__m128 x);
+
+ __m128 sse_inf_ps(__m128 x);
+
+}//namespace detail
+}//namespace glm
+
+#include "intrinsic_common.inl"
+
+#endif//GLM_ARCH
+#endif//glm_detail_intrinsic_common
diff --git a/src/glm/core/intrinsic_common.inl b/src/glm/core/intrinsic_common.inl
new file mode 100644
index 0000000..b7792aa
--- /dev/null
+++ b/src/glm/core/intrinsic_common.inl
@@ -0,0 +1,283 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2009-05-08
+// Updated : 2009-05-08
+// Licence : This source is under MIT License
+// File : glm/core/intrinsic_common.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm{
+namespace detail{
+
+ union ieee754_QNAN
+ {
+ const float f;
+ struct i
+ {
+ const unsigned int mantissa:23, exp:8, sign:1;
+ };
+
+ ieee754_QNAN() : f(0.0)/*, mantissa(0x7FFFFF), exp(0xFF), sign(0x0)*/ {}
+ };
+
+ static const __m128 GLM_VAR_USED zero = _mm_setzero_ps();
+ static const __m128 GLM_VAR_USED one = _mm_set_ps1(1.0f);
+ static const __m128 GLM_VAR_USED minus_one = _mm_set_ps1(-1.0f);
+ static const __m128 GLM_VAR_USED two = _mm_set_ps1(2.0f);
+ static const __m128 GLM_VAR_USED three = _mm_set_ps1(3.0f);
+ static const __m128 GLM_VAR_USED pi = _mm_set_ps1(3.1415926535897932384626433832795f);
+ static const __m128 GLM_VAR_USED hundred_eighty = _mm_set_ps1(180.f);
+ static const __m128 GLM_VAR_USED pi_over_hundred_eighty = _mm_set_ps1(0.017453292519943295769236907684886f);
+ static const __m128 GLM_VAR_USED hundred_eighty_over_pi = _mm_set_ps1(57.295779513082320876798154814105f);
+
+ static const ieee754_QNAN absMask;
+ static const __m128 GLM_VAR_USED abs4Mask = _mm_set_ps1(absMask.f);
+
+ static const __m128 GLM_VAR_USED _epi32_sign_mask = _mm_castsi128_ps(_mm_set1_epi32(0x80000000));
+ //static const __m128 GLM_VAR_USED _epi32_inv_sign_mask = _mm_castsi128_ps(_mm_set1_epi32(0x7FFFFFFF));
+ //static const __m128 GLM_VAR_USED _epi32_mant_mask = _mm_castsi128_ps(_mm_set1_epi32(0x7F800000));
+ //static const __m128 GLM_VAR_USED _epi32_inv_mant_mask = _mm_castsi128_ps(_mm_set1_epi32(0x807FFFFF));
+ //static const __m128 GLM_VAR_USED _epi32_min_norm_pos = _mm_castsi128_ps(_mm_set1_epi32(0x00800000));
+ static const __m128 GLM_VAR_USED _epi32_0 = _mm_set_ps1(0);
+ static const __m128 GLM_VAR_USED _epi32_1 = _mm_set_ps1(1);
+ static const __m128 GLM_VAR_USED _epi32_2 = _mm_set_ps1(2);
+ static const __m128 GLM_VAR_USED _epi32_3 = _mm_set_ps1(3);
+ static const __m128 GLM_VAR_USED _epi32_4 = _mm_set_ps1(4);
+ static const __m128 GLM_VAR_USED _epi32_5 = _mm_set_ps1(5);
+ static const __m128 GLM_VAR_USED _epi32_6 = _mm_set_ps1(6);
+ static const __m128 GLM_VAR_USED _epi32_7 = _mm_set_ps1(7);
+ static const __m128 GLM_VAR_USED _epi32_8 = _mm_set_ps1(8);
+ static const __m128 GLM_VAR_USED _epi32_9 = _mm_set_ps1(9);
+ static const __m128 GLM_VAR_USED _epi32_127 = _mm_set_ps1(127);
+ //static const __m128 GLM_VAR_USED _epi32_ninf = _mm_castsi128_ps(_mm_set1_epi32(0xFF800000));
+ //static const __m128 GLM_VAR_USED _epi32_pinf = _mm_castsi128_ps(_mm_set1_epi32(0x7F800000));
+
+ static const __m128 GLM_VAR_USED _ps_1_3 = _mm_set_ps1(0.33333333333333333333333333333333f);
+ static const __m128 GLM_VAR_USED _ps_0p5 = _mm_set_ps1(0.5f);
+ static const __m128 GLM_VAR_USED _ps_1 = _mm_set_ps1(1.0f);
+ static const __m128 GLM_VAR_USED _ps_m1 = _mm_set_ps1(-1.0f);
+ static const __m128 GLM_VAR_USED _ps_2 = _mm_set_ps1(2.0f);
+ static const __m128 GLM_VAR_USED _ps_3 = _mm_set_ps1(3.0f);
+ static const __m128 GLM_VAR_USED _ps_127 = _mm_set_ps1(127.0f);
+ static const __m128 GLM_VAR_USED _ps_255 = _mm_set_ps1(255.0f);
+ static const __m128 GLM_VAR_USED _ps_2pow23 = _mm_set_ps1(8388608.0f);
+
+ static const __m128 GLM_VAR_USED _ps_1_0_0_0 = _mm_set_ps(1.0f, 0.0f, 0.0f, 0.0f);
+ static const __m128 GLM_VAR_USED _ps_0_1_0_0 = _mm_set_ps(0.0f, 1.0f, 0.0f, 0.0f);
+ static const __m128 GLM_VAR_USED _ps_0_0_1_0 = _mm_set_ps(0.0f, 0.0f, 1.0f, 0.0f);
+ static const __m128 GLM_VAR_USED _ps_0_0_0_1 = _mm_set_ps(0.0f, 0.0f, 0.0f, 1.0f);
+
+ static const __m128 GLM_VAR_USED _ps_pi = _mm_set_ps1(3.1415926535897932384626433832795f);
+ static const __m128 GLM_VAR_USED _ps_pi2 = _mm_set_ps1(6.283185307179586476925286766560f);
+ static const __m128 GLM_VAR_USED _ps_2_pi = _mm_set_ps1(0.63661977236758134307553505349006f);
+ static const __m128 GLM_VAR_USED _ps_pi_2 = _mm_set_ps1(1.5707963267948966192313216916398f);
+ static const __m128 GLM_VAR_USED _ps_4_pi = _mm_set_ps1(1.2732395447351626861510701069801f);
+ static const __m128 GLM_VAR_USED _ps_pi_4 = _mm_set_ps1(0.78539816339744830961566084581988f);
+
+ static const __m128 GLM_VAR_USED _ps_sincos_p0 = _mm_set_ps1(0.15707963267948963959e1f);
+ static const __m128 GLM_VAR_USED _ps_sincos_p1 = _mm_set_ps1(-0.64596409750621907082e0f);
+ static const __m128 GLM_VAR_USED _ps_sincos_p2 = _mm_set_ps1(0.7969262624561800806e-1f);
+ static const __m128 GLM_VAR_USED _ps_sincos_p3 = _mm_set_ps1(-0.468175413106023168e-2f);
+ static const __m128 GLM_VAR_USED _ps_tan_p0 = _mm_set_ps1(-1.79565251976484877988e7f);
+ static const __m128 GLM_VAR_USED _ps_tan_p1 = _mm_set_ps1(1.15351664838587416140e6f);
+ static const __m128 GLM_VAR_USED _ps_tan_p2 = _mm_set_ps1(-1.30936939181383777646e4f);
+ static const __m128 GLM_VAR_USED _ps_tan_q0 = _mm_set_ps1(-5.38695755929454629881e7f);
+ static const __m128 GLM_VAR_USED _ps_tan_q1 = _mm_set_ps1(2.50083801823357915839e7f);
+ static const __m128 GLM_VAR_USED _ps_tan_q2 = _mm_set_ps1(-1.32089234440210967447e6f);
+ static const __m128 GLM_VAR_USED _ps_tan_q3 = _mm_set_ps1(1.36812963470692954678e4f);
+ static const __m128 GLM_VAR_USED _ps_tan_poleval = _mm_set_ps1(3.68935e19f);
+ static const __m128 GLM_VAR_USED _ps_atan_t0 = _mm_set_ps1(-0.91646118527267623468e-1f);
+ static const __m128 GLM_VAR_USED _ps_atan_t1 = _mm_set_ps1(-0.13956945682312098640e1f);
+ static const __m128 GLM_VAR_USED _ps_atan_t2 = _mm_set_ps1(-0.94393926122725531747e2f);
+ static const __m128 GLM_VAR_USED _ps_atan_t3 = _mm_set_ps1(0.12888383034157279340e2f);
+ static const __m128 GLM_VAR_USED _ps_atan_s0 = _mm_set_ps1(0.12797564625607904396e1f);
+ static const __m128 GLM_VAR_USED _ps_atan_s1 = _mm_set_ps1(0.21972168858277355914e1f);
+ static const __m128 GLM_VAR_USED _ps_atan_s2 = _mm_set_ps1(0.68193064729268275701e1f);
+ static const __m128 GLM_VAR_USED _ps_atan_s3 = _mm_set_ps1(0.28205206687035841409e2f);
+
+ static const __m128 GLM_VAR_USED _ps_exp_hi = _mm_set_ps1(88.3762626647949f);
+ static const __m128 GLM_VAR_USED _ps_exp_lo = _mm_set_ps1(-88.3762626647949f);
+ static const __m128 GLM_VAR_USED _ps_exp_rln2 = _mm_set_ps1(1.4426950408889634073599f);
+ static const __m128 GLM_VAR_USED _ps_exp_p0 = _mm_set_ps1(1.26177193074810590878e-4f);
+ static const __m128 GLM_VAR_USED _ps_exp_p1 = _mm_set_ps1(3.02994407707441961300e-2f);
+ static const __m128 GLM_VAR_USED _ps_exp_q0 = _mm_set_ps1(3.00198505138664455042e-6f);
+ static const __m128 GLM_VAR_USED _ps_exp_q1 = _mm_set_ps1(2.52448340349684104192e-3f);
+ static const __m128 GLM_VAR_USED _ps_exp_q2 = _mm_set_ps1(2.27265548208155028766e-1f);
+ static const __m128 GLM_VAR_USED _ps_exp_q3 = _mm_set_ps1(2.00000000000000000009e0f);
+ static const __m128 GLM_VAR_USED _ps_exp_c1 = _mm_set_ps1(6.93145751953125e-1f);
+ static const __m128 GLM_VAR_USED _ps_exp_c2 = _mm_set_ps1(1.42860682030941723212e-6f);
+ static const __m128 GLM_VAR_USED _ps_exp2_hi = _mm_set_ps1(127.4999961853f);
+ static const __m128 GLM_VAR_USED _ps_exp2_lo = _mm_set_ps1(-127.4999961853f);
+ static const __m128 GLM_VAR_USED _ps_exp2_p0 = _mm_set_ps1(2.30933477057345225087e-2f);
+ static const __m128 GLM_VAR_USED _ps_exp2_p1 = _mm_set_ps1(2.02020656693165307700e1f);
+ static const __m128 GLM_VAR_USED _ps_exp2_p2 = _mm_set_ps1(1.51390680115615096133e3f);
+ static const __m128 GLM_VAR_USED _ps_exp2_q0 = _mm_set_ps1(2.33184211722314911771e2f);
+ static const __m128 GLM_VAR_USED _ps_exp2_q1 = _mm_set_ps1(4.36821166879210612817e3f);
+ static const __m128 GLM_VAR_USED _ps_log_p0 = _mm_set_ps1(-7.89580278884799154124e-1f);
+ static const __m128 GLM_VAR_USED _ps_log_p1 = _mm_set_ps1(1.63866645699558079767e1f);
+ static const __m128 GLM_VAR_USED _ps_log_p2 = _mm_set_ps1(-6.41409952958715622951e1f);
+ static const __m128 GLM_VAR_USED _ps_log_q0 = _mm_set_ps1(-3.56722798256324312549e1f);
+ static const __m128 GLM_VAR_USED _ps_log_q1 = _mm_set_ps1(3.12093766372244180303e2f);
+ static const __m128 GLM_VAR_USED _ps_log_q2 = _mm_set_ps1(-7.69691943550460008604e2f);
+ static const __m128 GLM_VAR_USED _ps_log_c0 = _mm_set_ps1(0.693147180559945f);
+ static const __m128 GLM_VAR_USED _ps_log2_c0 = _mm_set_ps1(1.44269504088896340735992f);
+
+GLM_FUNC_QUALIFIER __m128 sse_abs_ps(__m128 x)
+{
+ return _mm_and_ps(glm::detail::abs4Mask, x);
+}
+
+GLM_FUNC_QUALIFIER __m128 sse_sgn_ps(__m128 x)
+{
+ __m128 Neg = _mm_set1_ps(-1.0f);
+ __m128 Pos = _mm_set1_ps(1.0f);
+
+ __m128 Cmp0 = _mm_cmplt_ps(x, zero);
+ __m128 Cmp1 = _mm_cmpgt_ps(x, zero);
+
+ __m128 And0 = _mm_and_ps(Cmp0, Neg);
+ __m128 And1 = _mm_and_ps(Cmp1, Pos);
+
+ return _mm_or_ps(And0, And1);
+}
+
+//floor
+GLM_FUNC_QUALIFIER __m128 sse_flr_ps(__m128 x)
+{
+ __m128 rnd0 = sse_rnd_ps(x);
+ __m128 cmp0 = _mm_cmplt_ps(x, rnd0);
+ __m128 and0 = _mm_and_ps(cmp0, glm::detail::_ps_1);
+ __m128 sub0 = _mm_sub_ps(rnd0, and0);
+ return sub0;
+}
+
+//trunc
+/*
+GLM_FUNC_QUALIFIER __m128 _mm_trc_ps(__m128 v)
+{
+ return __m128();
+}
+*/
+//round
+GLM_FUNC_QUALIFIER __m128 sse_rnd_ps(__m128 x)
+{
+ __m128 and0 = _mm_and_ps(glm::detail::_epi32_sign_mask, x);
+ __m128 or0 = _mm_or_ps(and0, glm::detail::_ps_2pow23);
+ __m128 add0 = _mm_add_ps(x, or0);
+ __m128 sub0 = _mm_sub_ps(add0, or0);
+ return sub0;
+}
+
+//roundEven
+GLM_FUNC_QUALIFIER __m128 sse_rde_ps(__m128 x)
+{
+ __m128 and0 = _mm_and_ps(glm::detail::_epi32_sign_mask, x);
+ __m128 or0 = _mm_or_ps(and0, glm::detail::_ps_2pow23);
+ __m128 add0 = _mm_add_ps(x, or0);
+ __m128 sub0 = _mm_sub_ps(add0, or0);
+ return sub0;
+}
+
+GLM_FUNC_QUALIFIER __m128 sse_ceil_ps(__m128 x)
+{
+ __m128 rnd0 = sse_rnd_ps(x);
+ __m128 cmp0 = _mm_cmpgt_ps(x, rnd0);
+ __m128 and0 = _mm_and_ps(cmp0, glm::detail::_ps_1);
+ __m128 add0 = _mm_add_ps(rnd0, and0);
+ return add0;
+}
+
+GLM_FUNC_QUALIFIER __m128 sse_frc_ps(__m128 x)
+{
+ __m128 flr0 = sse_flr_ps(x);
+ __m128 sub0 = _mm_sub_ps(x, flr0);
+ return sub0;
+}
+
+GLM_FUNC_QUALIFIER __m128 sse_mod_ps(__m128 x, __m128 y)
+{
+ __m128 div0 = _mm_div_ps(x, y);
+ __m128 flr0 = sse_flr_ps(div0);
+ __m128 mul0 = _mm_mul_ps(y, flr0);
+ __m128 sub0 = _mm_sub_ps(x, mul0);
+ return sub0;
+}
+
+/// TODO
+GLM_FUNC_QUALIFIER __m128 sse_modf_ps(__m128 x, __m128i & i)
+{
+ __m128 empty;
+ return empty;
+}
+
+//GLM_FUNC_QUALIFIER __m128 _mm_min_ps(__m128 x, __m128 y)
+
+//GLM_FUNC_QUALIFIER __m128 _mm_max_ps(__m128 x, __m128 y)
+
+GLM_FUNC_QUALIFIER __m128 sse_clp_ps(__m128 v, __m128 minVal, __m128 maxVal)
+{
+ __m128 min0 = _mm_min_ps(v, maxVal);
+ __m128 max0 = _mm_max_ps(min0, minVal);
+ return max0;
+}
+
+GLM_FUNC_QUALIFIER __m128 sse_mix_ps(__m128 v1, __m128 v2, __m128 a)
+{
+ __m128 sub0 = _mm_sub_ps(glm::detail::one, a);
+ __m128 mul0 = _mm_mul_ps(v1, sub0);
+ __m128 mul1 = _mm_mul_ps(v2, a);
+ __m128 add0 = _mm_add_ps(mul0, mul1);
+ return add0;
+}
+
+GLM_FUNC_QUALIFIER __m128 sse_stp_ps(__m128 edge, __m128 x)
+{
+ __m128 cmp = _mm_cmple_ps(x, edge);
+ if(_mm_movemask_ps(cmp) == 0)
+ return glm::detail::one;
+ else
+ return glm::detail::zero;
+}
+
+GLM_FUNC_QUALIFIER __m128 sse_ssp_ps(__m128 edge0, __m128 edge1, __m128 x)
+{
+ __m128 sub0 = _mm_sub_ps(x, edge0);
+ __m128 sub1 = _mm_sub_ps(edge1, edge0);
+ __m128 div0 = _mm_sub_ps(sub0, sub1);
+ __m128 clp0 = sse_clp_ps(div0, glm::detail::zero, glm::detail::one);
+ __m128 mul0 = _mm_mul_ps(glm::detail::two, clp0);
+ __m128 sub2 = _mm_sub_ps(glm::detail::three, mul0);
+ __m128 mul1 = _mm_mul_ps(clp0, clp0);
+ __m128 mul2 = _mm_mul_ps(mul1, sub2);
+ return mul2;
+}
+
+/// \todo
+GLM_FUNC_QUALIFIER __m128 sse_nan_ps(__m128 x)
+{
+ __m128 empty;
+ return empty;
+}
+
+/// \todo
+GLM_FUNC_QUALIFIER __m128 sse_inf_ps(__m128 x)
+{
+ __m128 empty;
+ return empty;
+}
+
+// SSE scalar reciprocal sqrt using rsqrt op, plus one Newton-Rhaphson iteration
+// By Elan Ruskin, http://assemblyrequired.crashworks.org/
+GLM_FUNC_QUALIFIER __m128 sse_sqrt_wip_ss(__m128 const & x)
+{
+ __m128 recip = _mm_rsqrt_ss(x); // "estimate" opcode
+ const static __m128 three = {3, 3, 3, 3}; // aligned consts for fast load
+ const static __m128 half = {0.5,0.5,0.5,0.5};
+ __m128 halfrecip = _mm_mul_ss(half, recip);
+ __m128 threeminus_xrr = _mm_sub_ss(three, _mm_mul_ss(x, _mm_mul_ss (recip, recip)));
+ return _mm_mul_ss( halfrecip, threeminus_xrr);
+}
+
+}//namespace detail
+}//namespace glms
diff --git a/src/glm/core/intrinsic_exponential.hpp b/src/glm/core/intrinsic_exponential.hpp
new file mode 100644
index 0000000..1e105ca
--- /dev/null
+++ b/src/glm/core/intrinsic_exponential.hpp
@@ -0,0 +1,60 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2009-05-11
+// Updated : 2009-05-11
+// Licence : This source is under MIT License
+// File : glm/core/intrinsic_exponential.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_detail_intrinsic_exponential
+#define glm_detail_intrinsic_exponential
+
+#include "setup.hpp"
+
+#if((GLM_ARCH & GLM_ARCH_SSE2) != GLM_ARCH_SSE2)
+# error "SSE2 instructions not supported or enabled"
+#else
+
+namespace glm{
+namespace detail
+{
+/*
+GLM_FUNC_QUALIFIER __m128 sse_rsqrt_nr_ss(__m128 const x)
+{
+ __m128 recip = _mm_rsqrt_ss( x ); // "estimate" opcode
+ const static __m128 three = { 3, 3, 3, 3 }; // aligned consts for fast load
+ const static __m128 half = { 0.5,0.5,0.5,0.5 };
+ __m128 halfrecip = _mm_mul_ss( half, recip );
+ __m128 threeminus_xrr = _mm_sub_ss( three, _mm_mul_ss( x, _mm_mul_ss ( recip, recip ) ) );
+ return _mm_mul_ss( halfrecip, threeminus_xrr );
+}
+
+GLM_FUNC_QUALIFIER __m128 sse_normalize_fast_ps( float * RESTRICT vOut, float * RESTRICT vIn )
+{
+ __m128 x = _mm_load_ss(&vIn[0]);
+ __m128 y = _mm_load_ss(&vIn[1]);
+ __m128 z = _mm_load_ss(&vIn[2]);
+
+ const __m128 l = // compute x*x + y*y + z*z
+ _mm_add_ss(
+ _mm_add_ss( _mm_mul_ss(x,x),
+ _mm_mul_ss(y,y)
+ ),
+ _mm_mul_ss( z, z )
+ );
+
+
+ const __m128 rsqt = _mm_rsqrt_nr_ss( l );
+ _mm_store_ss( &vOut[0] , _mm_mul_ss( rsqt, x ) );
+ _mm_store_ss( &vOut[1] , _mm_mul_ss( rsqt, y ) );
+ _mm_store_ss( &vOut[2] , _mm_mul_ss( rsqt, z ) );
+
+ return _mm_mul_ss( l , rsqt );
+}
+*/
+}//namespace detail
+}//namespace glm
+
+#endif//GLM_ARCH
+#endif//glm_detail_intrinsic_exponential
diff --git a/src/glm/core/intrinsic_exponential.inl b/src/glm/core/intrinsic_exponential.inl
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/glm/core/intrinsic_exponential.inl
diff --git a/src/glm/core/intrinsic_geometric.hpp b/src/glm/core/intrinsic_geometric.hpp
new file mode 100644
index 0000000..cb6e45d
--- /dev/null
+++ b/src/glm/core/intrinsic_geometric.hpp
@@ -0,0 +1,57 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2009-05-08
+// Updated : 2009-05-08
+// Licence : This source is under MIT License
+// File : glm/core/intrinsic_geometric.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_core_intrinsic_geometric
+#define glm_core_intrinsic_geometric
+
+#include "setup.hpp"
+
+#if((GLM_ARCH & GLM_ARCH_SSE2) != GLM_ARCH_SSE2)
+# error "SSE2 instructions not supported or enabled"
+#else
+
+#include "intrinsic_common.hpp"
+
+namespace glm{
+namespace detail
+{
+ //length
+ __m128 sse_len_ps(__m128 x);
+
+ //distance
+ __m128 sse_dst_ps(__m128 p0, __m128 p1);
+
+ //dot
+ __m128 sse_dot_ps(__m128 v1, __m128 v2);
+
+ // SSE1
+ __m128 sse_dot_ss(__m128 v1, __m128 v2);
+
+ //cross
+ __m128 sse_xpd_ps(__m128 v1, __m128 v2);
+
+ //normalize
+ __m128 sse_nrm_ps(__m128 v);
+
+ //faceforward
+ __m128 sse_ffd_ps(__m128 N, __m128 I, __m128 Nref);
+
+ //reflect
+ __m128 sse_rfe_ps(__m128 I, __m128 N);
+
+ //refract
+ __m128 sse_rfa_ps(__m128 I, __m128 N, __m128 eta);
+
+}//namespace detail
+}//namespace glm
+
+#include "intrinsic_geometric.inl"
+
+#endif//GLM_ARCH
+#endif//glm_core_intrinsic_geometric
diff --git a/src/glm/core/intrinsic_geometric.inl b/src/glm/core/intrinsic_geometric.inl
new file mode 100644
index 0000000..06f0ee7
--- /dev/null
+++ b/src/glm/core/intrinsic_geometric.inl
@@ -0,0 +1,123 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2009-05-08
+// Updated : 2009-05-08
+// Licence : This source is under MIT License
+// File : glm/core/intrinsic_geometric.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm{
+namespace detail{
+
+//length
+GLM_FUNC_QUALIFIER __m128 sse_len_ps(__m128 x)
+{
+ __m128 dot0 = sse_dot_ps(x, x);
+ __m128 sqt0 = _mm_sqrt_ps(dot0);
+ return sqt0;
+}
+
+//distance
+GLM_FUNC_QUALIFIER __m128 sse_dst_ps(__m128 p0, __m128 p1)
+{
+ __m128 sub0 = _mm_sub_ps(p0, p1);
+ __m128 len0 = sse_len_ps(sub0);
+ return len0;
+}
+
+//dot
+GLM_FUNC_QUALIFIER __m128 sse_dot_ps(__m128 v1, __m128 v2)
+{
+ __m128 mul0 = _mm_mul_ps(v1, v2);
+ __m128 swp0 = _mm_shuffle_ps(mul0, mul0, _MM_SHUFFLE(2, 3, 0, 1));
+ __m128 add0 = _mm_add_ps(mul0, swp0);
+ __m128 swp1 = _mm_shuffle_ps(add0, add0, _MM_SHUFFLE(0, 1, 2, 3));
+ __m128 add1 = _mm_add_ps(add0, swp1);
+ return add1;
+}
+
+// SSE1
+GLM_FUNC_QUALIFIER __m128 sse_dot_ss(__m128 v1, __m128 v2)
+{
+ __m128 mul0 = _mm_mul_ps(v1, v2);
+ __m128 mov0 = _mm_movehl_ps(mul0, mul0);
+ __m128 add0 = _mm_add_ps(mov0, mul0);
+ __m128 swp1 = _mm_shuffle_ps(add0, add0, 1);
+ __m128 add1 = _mm_add_ss(add0, swp1);
+ return add1;
+}
+
+//cross
+GLM_FUNC_QUALIFIER __m128 sse_xpd_ps(__m128 v1, __m128 v2)
+{
+ __m128 swp0 = _mm_shuffle_ps(v1, v1, _MM_SHUFFLE(3, 0, 2, 1));
+ __m128 swp1 = _mm_shuffle_ps(v1, v1, _MM_SHUFFLE(3, 1, 0, 2));
+ __m128 swp2 = _mm_shuffle_ps(v2, v2, _MM_SHUFFLE(3, 0, 2, 1));
+ __m128 swp3 = _mm_shuffle_ps(v2, v2, _MM_SHUFFLE(3, 1, 0, 2));
+ __m128 mul0 = _mm_mul_ps(swp0, swp3);
+ __m128 mul1 = _mm_mul_ps(swp1, swp2);
+ __m128 sub0 = _mm_sub_ps(mul0, mul1);
+ return sub0;
+}
+
+//normalize
+GLM_FUNC_QUALIFIER __m128 sse_nrm_ps(__m128 v)
+{
+ __m128 dot0 = sse_dot_ps(v, v);
+ __m128 isr0 = _mm_rsqrt_ps(dot0);
+ __m128 mul0 = _mm_mul_ps(v, isr0);
+ return mul0;
+}
+
+//faceforward
+GLM_FUNC_QUALIFIER __m128 sse_ffd_ps(__m128 N, __m128 I, __m128 Nref)
+{
+ //__m128 dot0 = _mm_dot_ps(v, v);
+ //__m128 neg0 = _mm_neg_ps(N);
+ //__m128 sgn0 = _mm_sgn_ps(dot0);
+ //__m128 mix0 = _mm_mix_ps(N, neg0, sgn0);
+ //return mix0;
+
+ __m128 dot0 = sse_dot_ps(Nref, I);
+ __m128 sgn0 = sse_sgn_ps(dot0);
+ __m128 mul0 = _mm_mul_ps(sgn0, glm::detail::minus_one);
+ __m128 mul1 = _mm_mul_ps(N, mul0);
+ return mul1;
+}
+
+//reflect
+GLM_FUNC_QUALIFIER __m128 sse_rfe_ps(__m128 I, __m128 N)
+{
+ __m128 dot0 = sse_dot_ps(N, I);
+ __m128 mul0 = _mm_mul_ps(N, dot0);
+ __m128 mul1 = _mm_mul_ps(mul0, glm::detail::two);
+ __m128 sub0 = _mm_sub_ps(I, mul1);
+ return sub0;
+}
+
+//refract
+GLM_FUNC_QUALIFIER __m128 sse_rfa_ps(__m128 I, __m128 N, __m128 eta)
+{
+ __m128 dot0 = sse_dot_ps(N, I);
+ __m128 mul0 = _mm_mul_ps(eta, eta);
+ __m128 mul1 = _mm_mul_ps(dot0, dot0);
+ __m128 sub0 = _mm_sub_ps(glm::detail::one, mul0);
+ __m128 sub1 = _mm_sub_ps(glm::detail::one, mul1);
+ __m128 mul2 = _mm_mul_ps(sub0, sub1);
+
+ if(_mm_movemask_ps(_mm_cmplt_ss(mul2, glm::detail::zero)) == 0)
+ return glm::detail::zero;
+
+ __m128 sqt0 = _mm_sqrt_ps(mul2);
+ __m128 mul3 = _mm_mul_ps(eta, dot0);
+ __m128 add0 = _mm_add_ps(mul3, sqt0);
+ __m128 mul4 = _mm_mul_ps(add0, N);
+ __m128 mul5 = _mm_mul_ps(eta, I);
+ __m128 sub2 = _mm_sub_ps(mul5, mul4);
+
+ return sub2;
+}
+
+}//namespace detail
+}//namespace glm
diff --git a/src/glm/core/intrinsic_matrix.hpp b/src/glm/core/intrinsic_matrix.hpp
new file mode 100644
index 0000000..2744318
--- /dev/null
+++ b/src/glm/core/intrinsic_matrix.hpp
@@ -0,0 +1,50 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2009-06-05
+// Updated : 2009-06-05
+// Licence : This source is under MIT License
+// File : glm/core/intrinsic_common.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_detail_intrinsic_matrix
+#define glm_detail_intrinsic_matrix
+
+#include "setup.hpp"
+
+#if((GLM_ARCH & GLM_ARCH_SSE2) != GLM_ARCH_SSE2)
+# error "SSE2 instructions not supported or enabled"
+#else
+
+#include "intrinsic_geometric.hpp"
+
+namespace glm{
+namespace detail
+{
+ void sse_add_ps(__m128 in1[4], __m128 in2[4], __m128 out[4]);
+
+ void sse_sub_ps(__m128 in1[4], __m128 in2[4], __m128 out[4]);
+
+ __m128 sse_mul_ps(__m128 m[4], __m128 v);
+
+ __m128 sse_mul_ps(__m128 v, __m128 m[4]);
+
+ void sse_mul_ps(__m128 const in1[4], __m128 const in2[4], __m128 out[4]);
+
+ void sse_transpose_ps(__m128 const in[4], __m128 out[4]);
+
+ void sse_inverse_ps(__m128 const in[4], __m128 out[4]);
+
+ void sse_rotate_ps(__m128 const in[4], float Angle, float const v[3], __m128 out[4]);
+
+ __m128 sse_det_ps(__m128 const m[4]);
+
+ __m128 sse_slow_det_ps(__m128 const m[4]);
+
+}//namespace detail
+}//namespace glm
+
+#include "intrinsic_matrix.inl"
+
+#endif//GLM_ARCH
+#endif//glm_detail_intrinsic_matrix
diff --git a/src/glm/core/intrinsic_matrix.inl b/src/glm/core/intrinsic_matrix.inl
new file mode 100644
index 0000000..b3c1d6d
--- /dev/null
+++ b/src/glm/core/intrinsic_matrix.inl
@@ -0,0 +1,1051 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2009-06-05
+// Updated : 2009-06-05
+// Licence : This source is under MIT License
+// File : glm/core/intrinsic_common.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm{
+namespace detail{
+
+static const __m128 GLM_VAR_USED _m128_rad_ps = _mm_set_ps1(3.141592653589793238462643383279f / 180.f);
+static const __m128 GLM_VAR_USED _m128_deg_ps = _mm_set_ps1(180.f / 3.141592653589793238462643383279f);
+
+template <typename matType>
+GLM_FUNC_QUALIFIER matType sse_comp_mul_ps
+(
+ __m128 const in1[4],
+ __m128 const in2[4],
+ __m128 out[4]
+)
+{
+ out[0] = _mm_mul_ps(in1[0], in2[0]);
+ out[1] = _mm_mul_ps(in1[1], in2[1]);
+ out[2] = _mm_mul_ps(in1[2], in2[2]);
+ out[3] = _mm_mul_ps(in1[3], in2[3]);
+}
+
+GLM_FUNC_QUALIFIER void sse_add_ps(__m128 in1[4], __m128 in2[4], __m128 out[4])
+{
+ {
+ out[0] = _mm_add_ps(in1[0], in2[0]);
+ out[1] = _mm_add_ps(in1[1], in2[1]);
+ out[2] = _mm_add_ps(in1[2], in2[2]);
+ out[3] = _mm_add_ps(in1[3], in2[3]);
+ }
+}
+
+GLM_FUNC_QUALIFIER void sse_sub_ps(__m128 in1[4], __m128 in2[4], __m128 out[4])
+{
+ {
+ out[0] = _mm_sub_ps(in1[0], in2[0]);
+ out[1] = _mm_sub_ps(in1[1], in2[1]);
+ out[2] = _mm_sub_ps(in1[2], in2[2]);
+ out[3] = _mm_sub_ps(in1[3], in2[3]);
+ }
+}
+
+GLM_FUNC_QUALIFIER __m128 sse_mul_ps(__m128 m[4], __m128 v)
+{
+ __m128 v0 = _mm_shuffle_ps(v, v, _MM_SHUFFLE(0, 0, 0, 0));
+ __m128 v1 = _mm_shuffle_ps(v, v, _MM_SHUFFLE(1, 1, 1, 1));
+ __m128 v2 = _mm_shuffle_ps(v, v, _MM_SHUFFLE(2, 2, 2, 2));
+ __m128 v3 = _mm_shuffle_ps(v, v, _MM_SHUFFLE(3, 3, 3, 3));
+
+ __m128 m0 = _mm_mul_ps(m[0], v0);
+ __m128 m1 = _mm_mul_ps(m[1], v1);
+ __m128 m2 = _mm_mul_ps(m[2], v2);
+ __m128 m3 = _mm_mul_ps(m[3], v3);
+
+ __m128 a0 = _mm_add_ps(m0, m1);
+ __m128 a1 = _mm_add_ps(m2, m3);
+ __m128 a2 = _mm_add_ps(a0, a1);
+
+ return a2;
+}
+
+GLM_FUNC_QUALIFIER __m128 sse_mul_ps(__m128 v, __m128 m[4])
+{
+ __m128 i0 = m[0];
+ __m128 i1 = m[1];
+ __m128 i2 = m[2];
+ __m128 i3 = m[3];
+
+ __m128 m0 = _mm_mul_ps(v, i0);
+ __m128 m1 = _mm_mul_ps(v, i1);
+ __m128 m2 = _mm_mul_ps(v, i2);
+ __m128 m3 = _mm_mul_ps(v, i3);
+
+ __m128 u0 = _mm_unpacklo_ps(m0, m1);
+ __m128 u1 = _mm_unpackhi_ps(m0, m1);
+ __m128 a0 = _mm_add_ps(u0, u1);
+
+ __m128 u2 = _mm_unpacklo_ps(m2, m3);
+ __m128 u3 = _mm_unpackhi_ps(m2, m3);
+ __m128 a1 = _mm_add_ps(u2, u3);
+
+ __m128 f0 = _mm_movelh_ps(a0, a1);
+ __m128 f1 = _mm_movehl_ps(a1, a0);
+ __m128 f2 = _mm_add_ps(f0, f1);
+
+ return f2;
+}
+
+GLM_FUNC_QUALIFIER void sse_mul_ps(__m128 const in1[4], __m128 const in2[4], __m128 out[4])
+{
+ {
+ __m128 e0 = _mm_shuffle_ps(in2[0], in2[0], _MM_SHUFFLE(0, 0, 0, 0));
+ __m128 e1 = _mm_shuffle_ps(in2[0], in2[0], _MM_SHUFFLE(1, 1, 1, 1));
+ __m128 e2 = _mm_shuffle_ps(in2[0], in2[0], _MM_SHUFFLE(2, 2, 2, 2));
+ __m128 e3 = _mm_shuffle_ps(in2[0], in2[0], _MM_SHUFFLE(3, 3, 3, 3));
+
+ __m128 m0 = _mm_mul_ps(in1[0], e0);
+ __m128 m1 = _mm_mul_ps(in1[1], e1);
+ __m128 m2 = _mm_mul_ps(in1[2], e2);
+ __m128 m3 = _mm_mul_ps(in1[3], e3);
+
+ __m128 a0 = _mm_add_ps(m0, m1);
+ __m128 a1 = _mm_add_ps(m2, m3);
+ __m128 a2 = _mm_add_ps(a0, a1);
+
+ out[0] = a2;
+ }
+
+ {
+ __m128 e0 = _mm_shuffle_ps(in2[1], in2[1], _MM_SHUFFLE(0, 0, 0, 0));
+ __m128 e1 = _mm_shuffle_ps(in2[1], in2[1], _MM_SHUFFLE(1, 1, 1, 1));
+ __m128 e2 = _mm_shuffle_ps(in2[1], in2[1], _MM_SHUFFLE(2, 2, 2, 2));
+ __m128 e3 = _mm_shuffle_ps(in2[1], in2[1], _MM_SHUFFLE(3, 3, 3, 3));
+
+ __m128 m0 = _mm_mul_ps(in1[0], e0);
+ __m128 m1 = _mm_mul_ps(in1[1], e1);
+ __m128 m2 = _mm_mul_ps(in1[2], e2);
+ __m128 m3 = _mm_mul_ps(in1[3], e3);
+
+ __m128 a0 = _mm_add_ps(m0, m1);
+ __m128 a1 = _mm_add_ps(m2, m3);
+ __m128 a2 = _mm_add_ps(a0, a1);
+
+ out[1] = a2;
+ }
+
+ {
+ __m128 e0 = _mm_shuffle_ps(in2[2], in2[2], _MM_SHUFFLE(0, 0, 0, 0));
+ __m128 e1 = _mm_shuffle_ps(in2[2], in2[2], _MM_SHUFFLE(1, 1, 1, 1));
+ __m128 e2 = _mm_shuffle_ps(in2[2], in2[2], _MM_SHUFFLE(2, 2, 2, 2));
+ __m128 e3 = _mm_shuffle_ps(in2[2], in2[2], _MM_SHUFFLE(3, 3, 3, 3));
+
+ __m128 m0 = _mm_mul_ps(in1[0], e0);
+ __m128 m1 = _mm_mul_ps(in1[1], e1);
+ __m128 m2 = _mm_mul_ps(in1[2], e2);
+ __m128 m3 = _mm_mul_ps(in1[3], e3);
+
+ __m128 a0 = _mm_add_ps(m0, m1);
+ __m128 a1 = _mm_add_ps(m2, m3);
+ __m128 a2 = _mm_add_ps(a0, a1);
+
+ out[2] = a2;
+ }
+
+ {
+ //(__m128&)_mm_shuffle_epi32(__m128i&)in2[0], _MM_SHUFFLE(3, 3, 3, 3))
+ __m128 e0 = _mm_shuffle_ps(in2[3], in2[3], _MM_SHUFFLE(0, 0, 0, 0));
+ __m128 e1 = _mm_shuffle_ps(in2[3], in2[3], _MM_SHUFFLE(1, 1, 1, 1));
+ __m128 e2 = _mm_shuffle_ps(in2[3], in2[3], _MM_SHUFFLE(2, 2, 2, 2));
+ __m128 e3 = _mm_shuffle_ps(in2[3], in2[3], _MM_SHUFFLE(3, 3, 3, 3));
+
+ __m128 m0 = _mm_mul_ps(in1[0], e0);
+ __m128 m1 = _mm_mul_ps(in1[1], e1);
+ __m128 m2 = _mm_mul_ps(in1[2], e2);
+ __m128 m3 = _mm_mul_ps(in1[3], e3);
+
+ __m128 a0 = _mm_add_ps(m0, m1);
+ __m128 a1 = _mm_add_ps(m2, m3);
+ __m128 a2 = _mm_add_ps(a0, a1);
+
+ out[3] = a2;
+ }
+}
+
+GLM_FUNC_QUALIFIER void sse_transpose_ps(__m128 const in[4], __m128 out[4])
+{
+ __m128 tmp0 = _mm_shuffle_ps(in[0], in[1], 0x44);
+ __m128 tmp2 = _mm_shuffle_ps(in[0], in[1], 0xEE);
+ __m128 tmp1 = _mm_shuffle_ps(in[2], in[3], 0x44);
+ __m128 tmp3 = _mm_shuffle_ps(in[2], in[3], 0xEE);
+
+ out[0] = _mm_shuffle_ps(tmp0, tmp1, 0x88);
+ out[1] = _mm_shuffle_ps(tmp0, tmp1, 0xDD);
+ out[2] = _mm_shuffle_ps(tmp2, tmp3, 0x88);
+ out[3] = _mm_shuffle_ps(tmp2, tmp3, 0xDD);
+}
+
+GLM_FUNC_QUALIFIER __m128 sse_slow_det_ps(__m128 const in[4])
+{
+ __m128 Fac0;
+ {
+ // valType SubFactor00 = m[2][2] * m[3][3] - m[3][2] * m[2][3];
+ // valType SubFactor00 = m[2][2] * m[3][3] - m[3][2] * m[2][3];
+ // valType SubFactor06 = m[1][2] * m[3][3] - m[3][2] * m[1][3];
+ // valType SubFactor13 = m[1][2] * m[2][3] - m[2][2] * m[1][3];
+
+ __m128 Swp0a = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(3, 3, 3, 3));
+ __m128 Swp0b = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(2, 2, 2, 2));
+
+ __m128 Swp00 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(2, 2, 2, 2));
+ __m128 Swp01 = _mm_shuffle_ps(Swp0a, Swp0a, _MM_SHUFFLE(2, 0, 0, 0));
+ __m128 Swp02 = _mm_shuffle_ps(Swp0b, Swp0b, _MM_SHUFFLE(2, 0, 0, 0));
+ __m128 Swp03 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(3, 3, 3, 3));
+
+ __m128 Mul00 = _mm_mul_ps(Swp00, Swp01);
+ __m128 Mul01 = _mm_mul_ps(Swp02, Swp03);
+ Fac0 = _mm_sub_ps(Mul00, Mul01);
+ }
+
+ __m128 Fac1;
+ {
+ // valType SubFactor01 = m[2][1] * m[3][3] - m[3][1] * m[2][3];
+ // valType SubFactor01 = m[2][1] * m[3][3] - m[3][1] * m[2][3];
+ // valType SubFactor07 = m[1][1] * m[3][3] - m[3][1] * m[1][3];
+ // valType SubFactor14 = m[1][1] * m[2][3] - m[2][1] * m[1][3];
+
+ __m128 Swp0a = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(3, 3, 3, 3));
+ __m128 Swp0b = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(1, 1, 1, 1));
+
+ __m128 Swp00 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(1, 1, 1, 1));
+ __m128 Swp01 = _mm_shuffle_ps(Swp0a, Swp0a, _MM_SHUFFLE(2, 0, 0, 0));
+ __m128 Swp02 = _mm_shuffle_ps(Swp0b, Swp0b, _MM_SHUFFLE(2, 0, 0, 0));
+ __m128 Swp03 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(3, 3, 3, 3));
+
+ __m128 Mul00 = _mm_mul_ps(Swp00, Swp01);
+ __m128 Mul01 = _mm_mul_ps(Swp02, Swp03);
+ Fac1 = _mm_sub_ps(Mul00, Mul01);
+ }
+
+
+ __m128 Fac2;
+ {
+ // valType SubFactor02 = m[2][1] * m[3][2] - m[3][1] * m[2][2];
+ // valType SubFactor02 = m[2][1] * m[3][2] - m[3][1] * m[2][2];
+ // valType SubFactor08 = m[1][1] * m[3][2] - m[3][1] * m[1][2];
+ // valType SubFactor15 = m[1][1] * m[2][2] - m[2][1] * m[1][2];
+
+ __m128 Swp0a = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(2, 2, 2, 2));
+ __m128 Swp0b = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(1, 1, 1, 1));
+
+ __m128 Swp00 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(1, 1, 1, 1));
+ __m128 Swp01 = _mm_shuffle_ps(Swp0a, Swp0a, _MM_SHUFFLE(2, 0, 0, 0));
+ __m128 Swp02 = _mm_shuffle_ps(Swp0b, Swp0b, _MM_SHUFFLE(2, 0, 0, 0));
+ __m128 Swp03 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(2, 2, 2, 2));
+
+ __m128 Mul00 = _mm_mul_ps(Swp00, Swp01);
+ __m128 Mul01 = _mm_mul_ps(Swp02, Swp03);
+ Fac2 = _mm_sub_ps(Mul00, Mul01);
+ }
+
+ __m128 Fac3;
+ {
+ // valType SubFactor03 = m[2][0] * m[3][3] - m[3][0] * m[2][3];
+ // valType SubFactor03 = m[2][0] * m[3][3] - m[3][0] * m[2][3];
+ // valType SubFactor09 = m[1][0] * m[3][3] - m[3][0] * m[1][3];
+ // valType SubFactor16 = m[1][0] * m[2][3] - m[2][0] * m[1][3];
+
+ __m128 Swp0a = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(3, 3, 3, 3));
+ __m128 Swp0b = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(0, 0, 0, 0));
+
+ __m128 Swp00 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(0, 0, 0, 0));
+ __m128 Swp01 = _mm_shuffle_ps(Swp0a, Swp0a, _MM_SHUFFLE(2, 0, 0, 0));
+ __m128 Swp02 = _mm_shuffle_ps(Swp0b, Swp0b, _MM_SHUFFLE(2, 0, 0, 0));
+ __m128 Swp03 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(3, 3, 3, 3));
+
+ __m128 Mul00 = _mm_mul_ps(Swp00, Swp01);
+ __m128 Mul01 = _mm_mul_ps(Swp02, Swp03);
+ Fac3 = _mm_sub_ps(Mul00, Mul01);
+ }
+
+ __m128 Fac4;
+ {
+ // valType SubFactor04 = m[2][0] * m[3][2] - m[3][0] * m[2][2];
+ // valType SubFactor04 = m[2][0] * m[3][2] - m[3][0] * m[2][2];
+ // valType SubFactor10 = m[1][0] * m[3][2] - m[3][0] * m[1][2];
+ // valType SubFactor17 = m[1][0] * m[2][2] - m[2][0] * m[1][2];
+
+ __m128 Swp0a = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(2, 2, 2, 2));
+ __m128 Swp0b = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(0, 0, 0, 0));
+
+ __m128 Swp00 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(0, 0, 0, 0));
+ __m128 Swp01 = _mm_shuffle_ps(Swp0a, Swp0a, _MM_SHUFFLE(2, 0, 0, 0));
+ __m128 Swp02 = _mm_shuffle_ps(Swp0b, Swp0b, _MM_SHUFFLE(2, 0, 0, 0));
+ __m128 Swp03 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(2, 2, 2, 2));
+
+ __m128 Mul00 = _mm_mul_ps(Swp00, Swp01);
+ __m128 Mul01 = _mm_mul_ps(Swp02, Swp03);
+ Fac4 = _mm_sub_ps(Mul00, Mul01);
+ }
+
+ __m128 Fac5;
+ {
+ // valType SubFactor05 = m[2][0] * m[3][1] - m[3][0] * m[2][1];
+ // valType SubFactor05 = m[2][0] * m[3][1] - m[3][0] * m[2][1];
+ // valType SubFactor12 = m[1][0] * m[3][1] - m[3][0] * m[1][1];
+ // valType SubFactor18 = m[1][0] * m[2][1] - m[2][0] * m[1][1];
+
+ __m128 Swp0a = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(1, 1, 1, 1));
+ __m128 Swp0b = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(0, 0, 0, 0));
+
+ __m128 Swp00 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(0, 0, 0, 0));
+ __m128 Swp01 = _mm_shuffle_ps(Swp0a, Swp0a, _MM_SHUFFLE(2, 0, 0, 0));
+ __m128 Swp02 = _mm_shuffle_ps(Swp0b, Swp0b, _MM_SHUFFLE(2, 0, 0, 0));
+ __m128 Swp03 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(1, 1, 1, 1));
+
+ __m128 Mul00 = _mm_mul_ps(Swp00, Swp01);
+ __m128 Mul01 = _mm_mul_ps(Swp02, Swp03);
+ Fac5 = _mm_sub_ps(Mul00, Mul01);
+ }
+
+ __m128 SignA = _mm_set_ps( 1.0f,-1.0f, 1.0f,-1.0f);
+ __m128 SignB = _mm_set_ps(-1.0f, 1.0f,-1.0f, 1.0f);
+
+ // m[1][0]
+ // m[0][0]
+ // m[0][0]
+ // m[0][0]
+ __m128 Temp0 = _mm_shuffle_ps(in[1], in[0], _MM_SHUFFLE(0, 0, 0, 0));
+ __m128 Vec0 = _mm_shuffle_ps(Temp0, Temp0, _MM_SHUFFLE(2, 2, 2, 0));
+
+ // m[1][1]
+ // m[0][1]
+ // m[0][1]
+ // m[0][1]
+ __m128 Temp1 = _mm_shuffle_ps(in[1], in[0], _MM_SHUFFLE(1, 1, 1, 1));
+ __m128 Vec1 = _mm_shuffle_ps(Temp1, Temp1, _MM_SHUFFLE(2, 2, 2, 0));
+
+ // m[1][2]
+ // m[0][2]
+ // m[0][2]
+ // m[0][2]
+ __m128 Temp2 = _mm_shuffle_ps(in[1], in[0], _MM_SHUFFLE(2, 2, 2, 2));
+ __m128 Vec2 = _mm_shuffle_ps(Temp2, Temp2, _MM_SHUFFLE(2, 2, 2, 0));
+
+ // m[1][3]
+ // m[0][3]
+ // m[0][3]
+ // m[0][3]
+ __m128 Temp3 = _mm_shuffle_ps(in[1], in[0], _MM_SHUFFLE(3, 3, 3, 3));
+ __m128 Vec3 = _mm_shuffle_ps(Temp3, Temp3, _MM_SHUFFLE(2, 2, 2, 0));
+
+ // col0
+ // + (Vec1[0] * Fac0[0] - Vec2[0] * Fac1[0] + Vec3[0] * Fac2[0]),
+ // - (Vec1[1] * Fac0[1] - Vec2[1] * Fac1[1] + Vec3[1] * Fac2[1]),
+ // + (Vec1[2] * Fac0[2] - Vec2[2] * Fac1[2] + Vec3[2] * Fac2[2]),
+ // - (Vec1[3] * Fac0[3] - Vec2[3] * Fac1[3] + Vec3[3] * Fac2[3]),
+ __m128 Mul00 = _mm_mul_ps(Vec1, Fac0);
+ __m128 Mul01 = _mm_mul_ps(Vec2, Fac1);
+ __m128 Mul02 = _mm_mul_ps(Vec3, Fac2);
+ __m128 Sub00 = _mm_sub_ps(Mul00, Mul01);
+ __m128 Add00 = _mm_add_ps(Sub00, Mul02);
+ __m128 Inv0 = _mm_mul_ps(SignB, Add00);
+
+ // col1
+ // - (Vec0[0] * Fac0[0] - Vec2[0] * Fac3[0] + Vec3[0] * Fac4[0]),
+ // + (Vec0[0] * Fac0[1] - Vec2[1] * Fac3[1] + Vec3[1] * Fac4[1]),
+ // - (Vec0[0] * Fac0[2] - Vec2[2] * Fac3[2] + Vec3[2] * Fac4[2]),
+ // + (Vec0[0] * Fac0[3] - Vec2[3] * Fac3[3] + Vec3[3] * Fac4[3]),
+ __m128 Mul03 = _mm_mul_ps(Vec0, Fac0);
+ __m128 Mul04 = _mm_mul_ps(Vec2, Fac3);
+ __m128 Mul05 = _mm_mul_ps(Vec3, Fac4);
+ __m128 Sub01 = _mm_sub_ps(Mul03, Mul04);
+ __m128 Add01 = _mm_add_ps(Sub01, Mul05);
+ __m128 Inv1 = _mm_mul_ps(SignA, Add01);
+
+ // col2
+ // + (Vec0[0] * Fac1[0] - Vec1[0] * Fac3[0] + Vec3[0] * Fac5[0]),
+ // - (Vec0[0] * Fac1[1] - Vec1[1] * Fac3[1] + Vec3[1] * Fac5[1]),
+ // + (Vec0[0] * Fac1[2] - Vec1[2] * Fac3[2] + Vec3[2] * Fac5[2]),
+ // - (Vec0[0] * Fac1[3] - Vec1[3] * Fac3[3] + Vec3[3] * Fac5[3]),
+ __m128 Mul06 = _mm_mul_ps(Vec0, Fac1);
+ __m128 Mul07 = _mm_mul_ps(Vec1, Fac3);
+ __m128 Mul08 = _mm_mul_ps(Vec3, Fac5);
+ __m128 Sub02 = _mm_sub_ps(Mul06, Mul07);
+ __m128 Add02 = _mm_add_ps(Sub02, Mul08);
+ __m128 Inv2 = _mm_mul_ps(SignB, Add02);
+
+ // col3
+ // - (Vec1[0] * Fac2[0] - Vec1[0] * Fac4[0] + Vec2[0] * Fac5[0]),
+ // + (Vec1[0] * Fac2[1] - Vec1[1] * Fac4[1] + Vec2[1] * Fac5[1]),
+ // - (Vec1[0] * Fac2[2] - Vec1[2] * Fac4[2] + Vec2[2] * Fac5[2]),
+ // + (Vec1[0] * Fac2[3] - Vec1[3] * Fac4[3] + Vec2[3] * Fac5[3]));
+ __m128 Mul09 = _mm_mul_ps(Vec0, Fac2);
+ __m128 Mul10 = _mm_mul_ps(Vec1, Fac4);
+ __m128 Mul11 = _mm_mul_ps(Vec2, Fac5);
+ __m128 Sub03 = _mm_sub_ps(Mul09, Mul10);
+ __m128 Add03 = _mm_add_ps(Sub03, Mul11);
+ __m128 Inv3 = _mm_mul_ps(SignA, Add03);
+
+ __m128 Row0 = _mm_shuffle_ps(Inv0, Inv1, _MM_SHUFFLE(0, 0, 0, 0));
+ __m128 Row1 = _mm_shuffle_ps(Inv2, Inv3, _MM_SHUFFLE(0, 0, 0, 0));
+ __m128 Row2 = _mm_shuffle_ps(Row0, Row1, _MM_SHUFFLE(2, 0, 2, 0));
+
+ // valType Determinant = m[0][0] * Inverse[0][0]
+ // + m[0][1] * Inverse[1][0]
+ // + m[0][2] * Inverse[2][0]
+ // + m[0][3] * Inverse[3][0];
+ __m128 Det0 = sse_dot_ps(in[0], Row2);
+ return Det0;
+}
+
+GLM_FUNC_QUALIFIER __m128 sse_detd_ps
+(
+ __m128 const m[4]
+)
+{
+ // _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(
+
+ //T SubFactor00 = m[2][2] * m[3][3] - m[3][2] * m[2][3];
+ //T SubFactor01 = m[2][1] * m[3][3] - m[3][1] * m[2][3];
+ //T SubFactor02 = m[2][1] * m[3][2] - m[3][1] * m[2][2];
+ //T SubFactor03 = m[2][0] * m[3][3] - m[3][0] * m[2][3];
+ //T SubFactor04 = m[2][0] * m[3][2] - m[3][0] * m[2][2];
+ //T SubFactor05 = m[2][0] * m[3][1] - m[3][0] * m[2][1];
+
+ // First 2 columns
+ __m128 Swp2A = _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(m[2]), _MM_SHUFFLE(0, 1, 1, 2)));
+ __m128 Swp3A = _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(m[3]), _MM_SHUFFLE(3, 2, 3, 3)));
+ __m128 MulA = _mm_mul_ps(Swp2A, Swp3A);
+
+ // Second 2 columns
+ __m128 Swp2B = _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(m[2]), _MM_SHUFFLE(3, 2, 3, 3)));
+ __m128 Swp3B = _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(m[3]), _MM_SHUFFLE(0, 1, 1, 2)));
+ __m128 MulB = _mm_mul_ps(Swp2B, Swp3B);
+
+ // Columns subtraction
+ __m128 SubE = _mm_sub_ps(MulA, MulB);
+
+ // Last 2 rows
+ __m128 Swp2C = _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(m[2]), _MM_SHUFFLE(0, 0, 1, 2)));
+ __m128 Swp3C = _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(m[3]), _MM_SHUFFLE(1, 2, 0, 0)));
+ __m128 MulC = _mm_mul_ps(Swp2C, Swp3C);
+ __m128 SubF = _mm_sub_ps(_mm_movehl_ps(MulC, MulC), MulC);
+
+ //detail::tvec4<T> DetCof(
+ // + (m[1][1] * SubFactor00 - m[1][2] * SubFactor01 + m[1][3] * SubFactor02),
+ // - (m[1][0] * SubFactor00 - m[1][2] * SubFactor03 + m[1][3] * SubFactor04),
+ // + (m[1][0] * SubFactor01 - m[1][1] * SubFactor03 + m[1][3] * SubFactor05),
+ // - (m[1][0] * SubFactor02 - m[1][1] * SubFactor04 + m[1][2] * SubFactor05));
+
+ __m128 SubFacA = _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(SubE), _MM_SHUFFLE(2, 1, 0, 0)));
+ __m128 SwpFacA = _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(m[1]), _MM_SHUFFLE(0, 0, 0, 1)));
+ __m128 MulFacA = _mm_mul_ps(SwpFacA, SubFacA);
+
+ __m128 SubTmpB = _mm_shuffle_ps(SubE, SubF, _MM_SHUFFLE(0, 0, 3, 1));
+ __m128 SubFacB = _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(SubTmpB), _MM_SHUFFLE(3, 1, 1, 0)));//SubF[0], SubE[3], SubE[3], SubE[1];
+ __m128 SwpFacB = _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(m[1]), _MM_SHUFFLE(1, 1, 2, 2)));
+ __m128 MulFacB = _mm_mul_ps(SwpFacB, SubFacB);
+
+ __m128 SubRes = _mm_sub_ps(MulFacA, MulFacB);
+
+ __m128 SubTmpC = _mm_shuffle_ps(SubE, SubF, _MM_SHUFFLE(1, 0, 2, 2));
+ __m128 SubFacC = _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(SubTmpC), _MM_SHUFFLE(3, 3, 2, 0)));
+ __m128 SwpFacC = _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(m[1]), _MM_SHUFFLE(2, 3, 3, 3)));
+ __m128 MulFacC = _mm_mul_ps(SwpFacC, SubFacC);
+
+ __m128 AddRes = _mm_add_ps(SubRes, MulFacC);
+ __m128 DetCof = _mm_mul_ps(AddRes, _mm_setr_ps( 1.0f,-1.0f, 1.0f,-1.0f));
+
+ //return m[0][0] * DetCof[0]
+ // + m[0][1] * DetCof[1]
+ // + m[0][2] * DetCof[2]
+ // + m[0][3] * DetCof[3];
+
+ return sse_dot_ps(m[0], DetCof);
+}
+
+GLM_FUNC_QUALIFIER __m128 sse_det_ps
+(
+ __m128 const m[4]
+)
+{
+ // _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(add)
+
+ //T SubFactor00 = m[2][2] * m[3][3] - m[3][2] * m[2][3];
+ //T SubFactor01 = m[2][1] * m[3][3] - m[3][1] * m[2][3];
+ //T SubFactor02 = m[2][1] * m[3][2] - m[3][1] * m[2][2];
+ //T SubFactor03 = m[2][0] * m[3][3] - m[3][0] * m[2][3];
+ //T SubFactor04 = m[2][0] * m[3][2] - m[3][0] * m[2][2];
+ //T SubFactor05 = m[2][0] * m[3][1] - m[3][0] * m[2][1];
+
+ // First 2 columns
+ __m128 Swp2A = _mm_shuffle_ps(m[2], m[2], _MM_SHUFFLE(0, 1, 1, 2));
+ __m128 Swp3A = _mm_shuffle_ps(m[3], m[3], _MM_SHUFFLE(3, 2, 3, 3));
+ __m128 MulA = _mm_mul_ps(Swp2A, Swp3A);
+
+ // Second 2 columns
+ __m128 Swp2B = _mm_shuffle_ps(m[2], m[2], _MM_SHUFFLE(3, 2, 3, 3));
+ __m128 Swp3B = _mm_shuffle_ps(m[3], m[3], _MM_SHUFFLE(0, 1, 1, 2));
+ __m128 MulB = _mm_mul_ps(Swp2B, Swp3B);
+
+ // Columns subtraction
+ __m128 SubE = _mm_sub_ps(MulA, MulB);
+
+ // Last 2 rows
+ __m128 Swp2C = _mm_shuffle_ps(m[2], m[2], _MM_SHUFFLE(0, 0, 1, 2));
+ __m128 Swp3C = _mm_shuffle_ps(m[3], m[3], _MM_SHUFFLE(1, 2, 0, 0));
+ __m128 MulC = _mm_mul_ps(Swp2C, Swp3C);
+ __m128 SubF = _mm_sub_ps(_mm_movehl_ps(MulC, MulC), MulC);
+
+ //detail::tvec4<T> DetCof(
+ // + (m[1][1] * SubFactor00 - m[1][2] * SubFactor01 + m[1][3] * SubFactor02),
+ // - (m[1][0] * SubFactor00 - m[1][2] * SubFactor03 + m[1][3] * SubFactor04),
+ // + (m[1][0] * SubFactor01 - m[1][1] * SubFactor03 + m[1][3] * SubFactor05),
+ // - (m[1][0] * SubFactor02 - m[1][1] * SubFactor04 + m[1][2] * SubFactor05));
+
+ __m128 SubFacA = _mm_shuffle_ps(SubE, SubE, _MM_SHUFFLE(2, 1, 0, 0));
+ __m128 SwpFacA = _mm_shuffle_ps(m[1], m[1], _MM_SHUFFLE(0, 0, 0, 1));
+ __m128 MulFacA = _mm_mul_ps(SwpFacA, SubFacA);
+
+ __m128 SubTmpB = _mm_shuffle_ps(SubE, SubF, _MM_SHUFFLE(0, 0, 3, 1));
+ __m128 SubFacB = _mm_shuffle_ps(SubTmpB, SubTmpB, _MM_SHUFFLE(3, 1, 1, 0));//SubF[0], SubE[3], SubE[3], SubE[1];
+ __m128 SwpFacB = _mm_shuffle_ps(m[1], m[1], _MM_SHUFFLE(1, 1, 2, 2));
+ __m128 MulFacB = _mm_mul_ps(SwpFacB, SubFacB);
+
+ __m128 SubRes = _mm_sub_ps(MulFacA, MulFacB);
+
+ __m128 SubTmpC = _mm_shuffle_ps(SubE, SubF, _MM_SHUFFLE(1, 0, 2, 2));
+ __m128 SubFacC = _mm_shuffle_ps(SubTmpC, SubTmpC, _MM_SHUFFLE(3, 3, 2, 0));
+ __m128 SwpFacC = _mm_shuffle_ps(m[1], m[1], _MM_SHUFFLE(2, 3, 3, 3));
+ __m128 MulFacC = _mm_mul_ps(SwpFacC, SubFacC);
+
+ __m128 AddRes = _mm_add_ps(SubRes, MulFacC);
+ __m128 DetCof = _mm_mul_ps(AddRes, _mm_setr_ps( 1.0f,-1.0f, 1.0f,-1.0f));
+
+ //return m[0][0] * DetCof[0]
+ // + m[0][1] * DetCof[1]
+ // + m[0][2] * DetCof[2]
+ // + m[0][3] * DetCof[3];
+
+ return sse_dot_ps(m[0], DetCof);
+}
+
+GLM_FUNC_QUALIFIER void sse_inverse_ps(__m128 const in[4], __m128 out[4])
+{
+ __m128 Fac0;
+ {
+ // valType SubFactor00 = m[2][2] * m[3][3] - m[3][2] * m[2][3];
+ // valType SubFactor00 = m[2][2] * m[3][3] - m[3][2] * m[2][3];
+ // valType SubFactor06 = m[1][2] * m[3][3] - m[3][2] * m[1][3];
+ // valType SubFactor13 = m[1][2] * m[2][3] - m[2][2] * m[1][3];
+
+ __m128 Swp0a = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(3, 3, 3, 3));
+ __m128 Swp0b = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(2, 2, 2, 2));
+
+ __m128 Swp00 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(2, 2, 2, 2));
+ __m128 Swp01 = _mm_shuffle_ps(Swp0a, Swp0a, _MM_SHUFFLE(2, 0, 0, 0));
+ __m128 Swp02 = _mm_shuffle_ps(Swp0b, Swp0b, _MM_SHUFFLE(2, 0, 0, 0));
+ __m128 Swp03 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(3, 3, 3, 3));
+
+ __m128 Mul00 = _mm_mul_ps(Swp00, Swp01);
+ __m128 Mul01 = _mm_mul_ps(Swp02, Swp03);
+ Fac0 = _mm_sub_ps(Mul00, Mul01);
+ }
+
+ __m128 Fac1;
+ {
+ // valType SubFactor01 = m[2][1] * m[3][3] - m[3][1] * m[2][3];
+ // valType SubFactor01 = m[2][1] * m[3][3] - m[3][1] * m[2][3];
+ // valType SubFactor07 = m[1][1] * m[3][3] - m[3][1] * m[1][3];
+ // valType SubFactor14 = m[1][1] * m[2][3] - m[2][1] * m[1][3];
+
+ __m128 Swp0a = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(3, 3, 3, 3));
+ __m128 Swp0b = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(1, 1, 1, 1));
+
+ __m128 Swp00 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(1, 1, 1, 1));
+ __m128 Swp01 = _mm_shuffle_ps(Swp0a, Swp0a, _MM_SHUFFLE(2, 0, 0, 0));
+ __m128 Swp02 = _mm_shuffle_ps(Swp0b, Swp0b, _MM_SHUFFLE(2, 0, 0, 0));
+ __m128 Swp03 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(3, 3, 3, 3));
+
+ __m128 Mul00 = _mm_mul_ps(Swp00, Swp01);
+ __m128 Mul01 = _mm_mul_ps(Swp02, Swp03);
+ Fac1 = _mm_sub_ps(Mul00, Mul01);
+ }
+
+
+ __m128 Fac2;
+ {
+ // valType SubFactor02 = m[2][1] * m[3][2] - m[3][1] * m[2][2];
+ // valType SubFactor02 = m[2][1] * m[3][2] - m[3][1] * m[2][2];
+ // valType SubFactor08 = m[1][1] * m[3][2] - m[3][1] * m[1][2];
+ // valType SubFactor15 = m[1][1] * m[2][2] - m[2][1] * m[1][2];
+
+ __m128 Swp0a = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(2, 2, 2, 2));
+ __m128 Swp0b = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(1, 1, 1, 1));
+
+ __m128 Swp00 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(1, 1, 1, 1));
+ __m128 Swp01 = _mm_shuffle_ps(Swp0a, Swp0a, _MM_SHUFFLE(2, 0, 0, 0));
+ __m128 Swp02 = _mm_shuffle_ps(Swp0b, Swp0b, _MM_SHUFFLE(2, 0, 0, 0));
+ __m128 Swp03 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(2, 2, 2, 2));
+
+ __m128 Mul00 = _mm_mul_ps(Swp00, Swp01);
+ __m128 Mul01 = _mm_mul_ps(Swp02, Swp03);
+ Fac2 = _mm_sub_ps(Mul00, Mul01);
+ }
+
+ __m128 Fac3;
+ {
+ // valType SubFactor03 = m[2][0] * m[3][3] - m[3][0] * m[2][3];
+ // valType SubFactor03 = m[2][0] * m[3][3] - m[3][0] * m[2][3];
+ // valType SubFactor09 = m[1][0] * m[3][3] - m[3][0] * m[1][3];
+ // valType SubFactor16 = m[1][0] * m[2][3] - m[2][0] * m[1][3];
+
+ __m128 Swp0a = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(3, 3, 3, 3));
+ __m128 Swp0b = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(0, 0, 0, 0));
+
+ __m128 Swp00 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(0, 0, 0, 0));
+ __m128 Swp01 = _mm_shuffle_ps(Swp0a, Swp0a, _MM_SHUFFLE(2, 0, 0, 0));
+ __m128 Swp02 = _mm_shuffle_ps(Swp0b, Swp0b, _MM_SHUFFLE(2, 0, 0, 0));
+ __m128 Swp03 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(3, 3, 3, 3));
+
+ __m128 Mul00 = _mm_mul_ps(Swp00, Swp01);
+ __m128 Mul01 = _mm_mul_ps(Swp02, Swp03);
+ Fac3 = _mm_sub_ps(Mul00, Mul01);
+ }
+
+ __m128 Fac4;
+ {
+ // valType SubFactor04 = m[2][0] * m[3][2] - m[3][0] * m[2][2];
+ // valType SubFactor04 = m[2][0] * m[3][2] - m[3][0] * m[2][2];
+ // valType SubFactor10 = m[1][0] * m[3][2] - m[3][0] * m[1][2];
+ // valType SubFactor17 = m[1][0] * m[2][2] - m[2][0] * m[1][2];
+
+ __m128 Swp0a = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(2, 2, 2, 2));
+ __m128 Swp0b = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(0, 0, 0, 0));
+
+ __m128 Swp00 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(0, 0, 0, 0));
+ __m128 Swp01 = _mm_shuffle_ps(Swp0a, Swp0a, _MM_SHUFFLE(2, 0, 0, 0));
+ __m128 Swp02 = _mm_shuffle_ps(Swp0b, Swp0b, _MM_SHUFFLE(2, 0, 0, 0));
+ __m128 Swp03 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(2, 2, 2, 2));
+
+ __m128 Mul00 = _mm_mul_ps(Swp00, Swp01);
+ __m128 Mul01 = _mm_mul_ps(Swp02, Swp03);
+ Fac4 = _mm_sub_ps(Mul00, Mul01);
+ }
+
+ __m128 Fac5;
+ {
+ // valType SubFactor05 = m[2][0] * m[3][1] - m[3][0] * m[2][1];
+ // valType SubFactor05 = m[2][0] * m[3][1] - m[3][0] * m[2][1];
+ // valType SubFactor12 = m[1][0] * m[3][1] - m[3][0] * m[1][1];
+ // valType SubFactor18 = m[1][0] * m[2][1] - m[2][0] * m[1][1];
+
+ __m128 Swp0a = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(1, 1, 1, 1));
+ __m128 Swp0b = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(0, 0, 0, 0));
+
+ __m128 Swp00 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(0, 0, 0, 0));
+ __m128 Swp01 = _mm_shuffle_ps(Swp0a, Swp0a, _MM_SHUFFLE(2, 0, 0, 0));
+ __m128 Swp02 = _mm_shuffle_ps(Swp0b, Swp0b, _MM_SHUFFLE(2, 0, 0, 0));
+ __m128 Swp03 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(1, 1, 1, 1));
+
+ __m128 Mul00 = _mm_mul_ps(Swp00, Swp01);
+ __m128 Mul01 = _mm_mul_ps(Swp02, Swp03);
+ Fac5 = _mm_sub_ps(Mul00, Mul01);
+ }
+
+ __m128 SignA = _mm_set_ps( 1.0f,-1.0f, 1.0f,-1.0f);
+ __m128 SignB = _mm_set_ps(-1.0f, 1.0f,-1.0f, 1.0f);
+
+ // m[1][0]
+ // m[0][0]
+ // m[0][0]
+ // m[0][0]
+ __m128 Temp0 = _mm_shuffle_ps(in[1], in[0], _MM_SHUFFLE(0, 0, 0, 0));
+ __m128 Vec0 = _mm_shuffle_ps(Temp0, Temp0, _MM_SHUFFLE(2, 2, 2, 0));
+
+ // m[1][1]
+ // m[0][1]
+ // m[0][1]
+ // m[0][1]
+ __m128 Temp1 = _mm_shuffle_ps(in[1], in[0], _MM_SHUFFLE(1, 1, 1, 1));
+ __m128 Vec1 = _mm_shuffle_ps(Temp1, Temp1, _MM_SHUFFLE(2, 2, 2, 0));
+
+ // m[1][2]
+ // m[0][2]
+ // m[0][2]
+ // m[0][2]
+ __m128 Temp2 = _mm_shuffle_ps(in[1], in[0], _MM_SHUFFLE(2, 2, 2, 2));
+ __m128 Vec2 = _mm_shuffle_ps(Temp2, Temp2, _MM_SHUFFLE(2, 2, 2, 0));
+
+ // m[1][3]
+ // m[0][3]
+ // m[0][3]
+ // m[0][3]
+ __m128 Temp3 = _mm_shuffle_ps(in[1], in[0], _MM_SHUFFLE(3, 3, 3, 3));
+ __m128 Vec3 = _mm_shuffle_ps(Temp3, Temp3, _MM_SHUFFLE(2, 2, 2, 0));
+
+ // col0
+ // + (Vec1[0] * Fac0[0] - Vec2[0] * Fac1[0] + Vec3[0] * Fac2[0]),
+ // - (Vec1[1] * Fac0[1] - Vec2[1] * Fac1[1] + Vec3[1] * Fac2[1]),
+ // + (Vec1[2] * Fac0[2] - Vec2[2] * Fac1[2] + Vec3[2] * Fac2[2]),
+ // - (Vec1[3] * Fac0[3] - Vec2[3] * Fac1[3] + Vec3[3] * Fac2[3]),
+ __m128 Mul00 = _mm_mul_ps(Vec1, Fac0);
+ __m128 Mul01 = _mm_mul_ps(Vec2, Fac1);
+ __m128 Mul02 = _mm_mul_ps(Vec3, Fac2);
+ __m128 Sub00 = _mm_sub_ps(Mul00, Mul01);
+ __m128 Add00 = _mm_add_ps(Sub00, Mul02);
+ __m128 Inv0 = _mm_mul_ps(SignB, Add00);
+
+ // col1
+ // - (Vec0[0] * Fac0[0] - Vec2[0] * Fac3[0] + Vec3[0] * Fac4[0]),
+ // + (Vec0[0] * Fac0[1] - Vec2[1] * Fac3[1] + Vec3[1] * Fac4[1]),
+ // - (Vec0[0] * Fac0[2] - Vec2[2] * Fac3[2] + Vec3[2] * Fac4[2]),
+ // + (Vec0[0] * Fac0[3] - Vec2[3] * Fac3[3] + Vec3[3] * Fac4[3]),
+ __m128 Mul03 = _mm_mul_ps(Vec0, Fac0);
+ __m128 Mul04 = _mm_mul_ps(Vec2, Fac3);
+ __m128 Mul05 = _mm_mul_ps(Vec3, Fac4);
+ __m128 Sub01 = _mm_sub_ps(Mul03, Mul04);
+ __m128 Add01 = _mm_add_ps(Sub01, Mul05);
+ __m128 Inv1 = _mm_mul_ps(SignA, Add01);
+
+ // col2
+ // + (Vec0[0] * Fac1[0] - Vec1[0] * Fac3[0] + Vec3[0] * Fac5[0]),
+ // - (Vec0[0] * Fac1[1] - Vec1[1] * Fac3[1] + Vec3[1] * Fac5[1]),
+ // + (Vec0[0] * Fac1[2] - Vec1[2] * Fac3[2] + Vec3[2] * Fac5[2]),
+ // - (Vec0[0] * Fac1[3] - Vec1[3] * Fac3[3] + Vec3[3] * Fac5[3]),
+ __m128 Mul06 = _mm_mul_ps(Vec0, Fac1);
+ __m128 Mul07 = _mm_mul_ps(Vec1, Fac3);
+ __m128 Mul08 = _mm_mul_ps(Vec3, Fac5);
+ __m128 Sub02 = _mm_sub_ps(Mul06, Mul07);
+ __m128 Add02 = _mm_add_ps(Sub02, Mul08);
+ __m128 Inv2 = _mm_mul_ps(SignB, Add02);
+
+ // col3
+ // - (Vec1[0] * Fac2[0] - Vec1[0] * Fac4[0] + Vec2[0] * Fac5[0]),
+ // + (Vec1[0] * Fac2[1] - Vec1[1] * Fac4[1] + Vec2[1] * Fac5[1]),
+ // - (Vec1[0] * Fac2[2] - Vec1[2] * Fac4[2] + Vec2[2] * Fac5[2]),
+ // + (Vec1[0] * Fac2[3] - Vec1[3] * Fac4[3] + Vec2[3] * Fac5[3]));
+ __m128 Mul09 = _mm_mul_ps(Vec0, Fac2);
+ __m128 Mul10 = _mm_mul_ps(Vec1, Fac4);
+ __m128 Mul11 = _mm_mul_ps(Vec2, Fac5);
+ __m128 Sub03 = _mm_sub_ps(Mul09, Mul10);
+ __m128 Add03 = _mm_add_ps(Sub03, Mul11);
+ __m128 Inv3 = _mm_mul_ps(SignA, Add03);
+
+ __m128 Row0 = _mm_shuffle_ps(Inv0, Inv1, _MM_SHUFFLE(0, 0, 0, 0));
+ __m128 Row1 = _mm_shuffle_ps(Inv2, Inv3, _MM_SHUFFLE(0, 0, 0, 0));
+ __m128 Row2 = _mm_shuffle_ps(Row0, Row1, _MM_SHUFFLE(2, 0, 2, 0));
+
+ // valType Determinant = m[0][0] * Inverse[0][0]
+ // + m[0][1] * Inverse[1][0]
+ // + m[0][2] * Inverse[2][0]
+ // + m[0][3] * Inverse[3][0];
+ __m128 Det0 = sse_dot_ps(in[0], Row2);
+ __m128 Rcp0 = _mm_div_ps(one, Det0);
+ //__m128 Rcp0 = _mm_rcp_ps(Det0);
+
+ // Inverse /= Determinant;
+ out[0] = _mm_mul_ps(Inv0, Rcp0);
+ out[1] = _mm_mul_ps(Inv1, Rcp0);
+ out[2] = _mm_mul_ps(Inv2, Rcp0);
+ out[3] = _mm_mul_ps(Inv3, Rcp0);
+}
+
+GLM_FUNC_QUALIFIER void sse_inverse_fast_ps(__m128 const in[4], __m128 out[4])
+{
+ __m128 Fac0;
+ {
+ // valType SubFactor00 = m[2][2] * m[3][3] - m[3][2] * m[2][3];
+ // valType SubFactor00 = m[2][2] * m[3][3] - m[3][2] * m[2][3];
+ // valType SubFactor06 = m[1][2] * m[3][3] - m[3][2] * m[1][3];
+ // valType SubFactor13 = m[1][2] * m[2][3] - m[2][2] * m[1][3];
+
+ __m128 Swp0a = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(3, 3, 3, 3));
+ __m128 Swp0b = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(2, 2, 2, 2));
+
+ __m128 Swp00 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(2, 2, 2, 2));
+ __m128 Swp01 = _mm_shuffle_ps(Swp0a, Swp0a, _MM_SHUFFLE(2, 0, 0, 0));
+ __m128 Swp02 = _mm_shuffle_ps(Swp0b, Swp0b, _MM_SHUFFLE(2, 0, 0, 0));
+ __m128 Swp03 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(3, 3, 3, 3));
+
+ __m128 Mul00 = _mm_mul_ps(Swp00, Swp01);
+ __m128 Mul01 = _mm_mul_ps(Swp02, Swp03);
+ Fac0 = _mm_sub_ps(Mul00, Mul01);
+ }
+
+ __m128 Fac1;
+ {
+ // valType SubFactor01 = m[2][1] * m[3][3] - m[3][1] * m[2][3];
+ // valType SubFactor01 = m[2][1] * m[3][3] - m[3][1] * m[2][3];
+ // valType SubFactor07 = m[1][1] * m[3][3] - m[3][1] * m[1][3];
+ // valType SubFactor14 = m[1][1] * m[2][3] - m[2][1] * m[1][3];
+
+ __m128 Swp0a = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(3, 3, 3, 3));
+ __m128 Swp0b = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(1, 1, 1, 1));
+
+ __m128 Swp00 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(1, 1, 1, 1));
+ __m128 Swp01 = _mm_shuffle_ps(Swp0a, Swp0a, _MM_SHUFFLE(2, 0, 0, 0));
+ __m128 Swp02 = _mm_shuffle_ps(Swp0b, Swp0b, _MM_SHUFFLE(2, 0, 0, 0));
+ __m128 Swp03 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(3, 3, 3, 3));
+
+ __m128 Mul00 = _mm_mul_ps(Swp00, Swp01);
+ __m128 Mul01 = _mm_mul_ps(Swp02, Swp03);
+ Fac1 = _mm_sub_ps(Mul00, Mul01);
+ }
+
+
+ __m128 Fac2;
+ {
+ // valType SubFactor02 = m[2][1] * m[3][2] - m[3][1] * m[2][2];
+ // valType SubFactor02 = m[2][1] * m[3][2] - m[3][1] * m[2][2];
+ // valType SubFactor08 = m[1][1] * m[3][2] - m[3][1] * m[1][2];
+ // valType SubFactor15 = m[1][1] * m[2][2] - m[2][1] * m[1][2];
+
+ __m128 Swp0a = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(2, 2, 2, 2));
+ __m128 Swp0b = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(1, 1, 1, 1));
+
+ __m128 Swp00 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(1, 1, 1, 1));
+ __m128 Swp01 = _mm_shuffle_ps(Swp0a, Swp0a, _MM_SHUFFLE(2, 0, 0, 0));
+ __m128 Swp02 = _mm_shuffle_ps(Swp0b, Swp0b, _MM_SHUFFLE(2, 0, 0, 0));
+ __m128 Swp03 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(2, 2, 2, 2));
+
+ __m128 Mul00 = _mm_mul_ps(Swp00, Swp01);
+ __m128 Mul01 = _mm_mul_ps(Swp02, Swp03);
+ Fac2 = _mm_sub_ps(Mul00, Mul01);
+ }
+
+ __m128 Fac3;
+ {
+ // valType SubFactor03 = m[2][0] * m[3][3] - m[3][0] * m[2][3];
+ // valType SubFactor03 = m[2][0] * m[3][3] - m[3][0] * m[2][3];
+ // valType SubFactor09 = m[1][0] * m[3][3] - m[3][0] * m[1][3];
+ // valType SubFactor16 = m[1][0] * m[2][3] - m[2][0] * m[1][3];
+
+ __m128 Swp0a = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(3, 3, 3, 3));
+ __m128 Swp0b = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(0, 0, 0, 0));
+
+ __m128 Swp00 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(0, 0, 0, 0));
+ __m128 Swp01 = _mm_shuffle_ps(Swp0a, Swp0a, _MM_SHUFFLE(2, 0, 0, 0));
+ __m128 Swp02 = _mm_shuffle_ps(Swp0b, Swp0b, _MM_SHUFFLE(2, 0, 0, 0));
+ __m128 Swp03 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(3, 3, 3, 3));
+
+ __m128 Mul00 = _mm_mul_ps(Swp00, Swp01);
+ __m128 Mul01 = _mm_mul_ps(Swp02, Swp03);
+ Fac3 = _mm_sub_ps(Mul00, Mul01);
+ }
+
+ __m128 Fac4;
+ {
+ // valType SubFactor04 = m[2][0] * m[3][2] - m[3][0] * m[2][2];
+ // valType SubFactor04 = m[2][0] * m[3][2] - m[3][0] * m[2][2];
+ // valType SubFactor10 = m[1][0] * m[3][2] - m[3][0] * m[1][2];
+ // valType SubFactor17 = m[1][0] * m[2][2] - m[2][0] * m[1][2];
+
+ __m128 Swp0a = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(2, 2, 2, 2));
+ __m128 Swp0b = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(0, 0, 0, 0));
+
+ __m128 Swp00 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(0, 0, 0, 0));
+ __m128 Swp01 = _mm_shuffle_ps(Swp0a, Swp0a, _MM_SHUFFLE(2, 0, 0, 0));
+ __m128 Swp02 = _mm_shuffle_ps(Swp0b, Swp0b, _MM_SHUFFLE(2, 0, 0, 0));
+ __m128 Swp03 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(2, 2, 2, 2));
+
+ __m128 Mul00 = _mm_mul_ps(Swp00, Swp01);
+ __m128 Mul01 = _mm_mul_ps(Swp02, Swp03);
+ Fac4 = _mm_sub_ps(Mul00, Mul01);
+ }
+
+ __m128 Fac5;
+ {
+ // valType SubFactor05 = m[2][0] * m[3][1] - m[3][0] * m[2][1];
+ // valType SubFactor05 = m[2][0] * m[3][1] - m[3][0] * m[2][1];
+ // valType SubFactor12 = m[1][0] * m[3][1] - m[3][0] * m[1][1];
+ // valType SubFactor18 = m[1][0] * m[2][1] - m[2][0] * m[1][1];
+
+ __m128 Swp0a = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(1, 1, 1, 1));
+ __m128 Swp0b = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(0, 0, 0, 0));
+
+ __m128 Swp00 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(0, 0, 0, 0));
+ __m128 Swp01 = _mm_shuffle_ps(Swp0a, Swp0a, _MM_SHUFFLE(2, 0, 0, 0));
+ __m128 Swp02 = _mm_shuffle_ps(Swp0b, Swp0b, _MM_SHUFFLE(2, 0, 0, 0));
+ __m128 Swp03 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(1, 1, 1, 1));
+
+ __m128 Mul00 = _mm_mul_ps(Swp00, Swp01);
+ __m128 Mul01 = _mm_mul_ps(Swp02, Swp03);
+ Fac5 = _mm_sub_ps(Mul00, Mul01);
+ }
+
+ __m128 SignA = _mm_set_ps( 1.0f,-1.0f, 1.0f,-1.0f);
+ __m128 SignB = _mm_set_ps(-1.0f, 1.0f,-1.0f, 1.0f);
+
+ // m[1][0]
+ // m[0][0]
+ // m[0][0]
+ // m[0][0]
+ __m128 Temp0 = _mm_shuffle_ps(in[1], in[0], _MM_SHUFFLE(0, 0, 0, 0));
+ __m128 Vec0 = _mm_shuffle_ps(Temp0, Temp0, _MM_SHUFFLE(2, 2, 2, 0));
+
+ // m[1][1]
+ // m[0][1]
+ // m[0][1]
+ // m[0][1]
+ __m128 Temp1 = _mm_shuffle_ps(in[1], in[0], _MM_SHUFFLE(1, 1, 1, 1));
+ __m128 Vec1 = _mm_shuffle_ps(Temp1, Temp1, _MM_SHUFFLE(2, 2, 2, 0));
+
+ // m[1][2]
+ // m[0][2]
+ // m[0][2]
+ // m[0][2]
+ __m128 Temp2 = _mm_shuffle_ps(in[1], in[0], _MM_SHUFFLE(2, 2, 2, 2));
+ __m128 Vec2 = _mm_shuffle_ps(Temp2, Temp2, _MM_SHUFFLE(2, 2, 2, 0));
+
+ // m[1][3]
+ // m[0][3]
+ // m[0][3]
+ // m[0][3]
+ __m128 Temp3 = _mm_shuffle_ps(in[1], in[0], _MM_SHUFFLE(3, 3, 3, 3));
+ __m128 Vec3 = _mm_shuffle_ps(Temp3, Temp3, _MM_SHUFFLE(2, 2, 2, 0));
+
+ // col0
+ // + (Vec1[0] * Fac0[0] - Vec2[0] * Fac1[0] + Vec3[0] * Fac2[0]),
+ // - (Vec1[1] * Fac0[1] - Vec2[1] * Fac1[1] + Vec3[1] * Fac2[1]),
+ // + (Vec1[2] * Fac0[2] - Vec2[2] * Fac1[2] + Vec3[2] * Fac2[2]),
+ // - (Vec1[3] * Fac0[3] - Vec2[3] * Fac1[3] + Vec3[3] * Fac2[3]),
+ __m128 Mul00 = _mm_mul_ps(Vec1, Fac0);
+ __m128 Mul01 = _mm_mul_ps(Vec2, Fac1);
+ __m128 Mul02 = _mm_mul_ps(Vec3, Fac2);
+ __m128 Sub00 = _mm_sub_ps(Mul00, Mul01);
+ __m128 Add00 = _mm_add_ps(Sub00, Mul02);
+ __m128 Inv0 = _mm_mul_ps(SignB, Add00);
+
+ // col1
+ // - (Vec0[0] * Fac0[0] - Vec2[0] * Fac3[0] + Vec3[0] * Fac4[0]),
+ // + (Vec0[0] * Fac0[1] - Vec2[1] * Fac3[1] + Vec3[1] * Fac4[1]),
+ // - (Vec0[0] * Fac0[2] - Vec2[2] * Fac3[2] + Vec3[2] * Fac4[2]),
+ // + (Vec0[0] * Fac0[3] - Vec2[3] * Fac3[3] + Vec3[3] * Fac4[3]),
+ __m128 Mul03 = _mm_mul_ps(Vec0, Fac0);
+ __m128 Mul04 = _mm_mul_ps(Vec2, Fac3);
+ __m128 Mul05 = _mm_mul_ps(Vec3, Fac4);
+ __m128 Sub01 = _mm_sub_ps(Mul03, Mul04);
+ __m128 Add01 = _mm_add_ps(Sub01, Mul05);
+ __m128 Inv1 = _mm_mul_ps(SignA, Add01);
+
+ // col2
+ // + (Vec0[0] * Fac1[0] - Vec1[0] * Fac3[0] + Vec3[0] * Fac5[0]),
+ // - (Vec0[0] * Fac1[1] - Vec1[1] * Fac3[1] + Vec3[1] * Fac5[1]),
+ // + (Vec0[0] * Fac1[2] - Vec1[2] * Fac3[2] + Vec3[2] * Fac5[2]),
+ // - (Vec0[0] * Fac1[3] - Vec1[3] * Fac3[3] + Vec3[3] * Fac5[3]),
+ __m128 Mul06 = _mm_mul_ps(Vec0, Fac1);
+ __m128 Mul07 = _mm_mul_ps(Vec1, Fac3);
+ __m128 Mul08 = _mm_mul_ps(Vec3, Fac5);
+ __m128 Sub02 = _mm_sub_ps(Mul06, Mul07);
+ __m128 Add02 = _mm_add_ps(Sub02, Mul08);
+ __m128 Inv2 = _mm_mul_ps(SignB, Add02);
+
+ // col3
+ // - (Vec1[0] * Fac2[0] - Vec1[0] * Fac4[0] + Vec2[0] * Fac5[0]),
+ // + (Vec1[0] * Fac2[1] - Vec1[1] * Fac4[1] + Vec2[1] * Fac5[1]),
+ // - (Vec1[0] * Fac2[2] - Vec1[2] * Fac4[2] + Vec2[2] * Fac5[2]),
+ // + (Vec1[0] * Fac2[3] - Vec1[3] * Fac4[3] + Vec2[3] * Fac5[3]));
+ __m128 Mul09 = _mm_mul_ps(Vec0, Fac2);
+ __m128 Mul10 = _mm_mul_ps(Vec1, Fac4);
+ __m128 Mul11 = _mm_mul_ps(Vec2, Fac5);
+ __m128 Sub03 = _mm_sub_ps(Mul09, Mul10);
+ __m128 Add03 = _mm_add_ps(Sub03, Mul11);
+ __m128 Inv3 = _mm_mul_ps(SignA, Add03);
+
+ __m128 Row0 = _mm_shuffle_ps(Inv0, Inv1, _MM_SHUFFLE(0, 0, 0, 0));
+ __m128 Row1 = _mm_shuffle_ps(Inv2, Inv3, _MM_SHUFFLE(0, 0, 0, 0));
+ __m128 Row2 = _mm_shuffle_ps(Row0, Row1, _MM_SHUFFLE(2, 0, 2, 0));
+
+ // valType Determinant = m[0][0] * Inverse[0][0]
+ // + m[0][1] * Inverse[1][0]
+ // + m[0][2] * Inverse[2][0]
+ // + m[0][3] * Inverse[3][0];
+ __m128 Det0 = sse_dot_ps(in[0], Row2);
+ __m128 Rcp0 = _mm_rcp_ps(Det0);
+ //__m128 Rcp0 = _mm_div_ps(one, Det0);
+ // Inverse /= Determinant;
+ out[0] = _mm_mul_ps(Inv0, Rcp0);
+ out[1] = _mm_mul_ps(Inv1, Rcp0);
+ out[2] = _mm_mul_ps(Inv2, Rcp0);
+ out[3] = _mm_mul_ps(Inv3, Rcp0);
+}
+/*
+GLM_FUNC_QUALIFIER void sse_rotate_ps(__m128 const in[4], float Angle, float const v[3], __m128 out[4])
+{
+ float a = glm::radians(Angle);
+ float c = cos(a);
+ float s = sin(a);
+
+ glm::vec4 AxisA(v[0], v[1], v[2], float(0));
+ __m128 AxisB = _mm_set_ps(AxisA.w, AxisA.z, AxisA.y, AxisA.x);
+ __m128 AxisC = detail::sse_nrm_ps(AxisB);
+
+ __m128 Cos0 = _mm_set_ss(c);
+ __m128 CosA = _mm_shuffle_ps(Cos0, Cos0, _MM_SHUFFLE(0, 0, 0, 0));
+ __m128 Sin0 = _mm_set_ss(s);
+ __m128 SinA = _mm_shuffle_ps(Sin0, Sin0, _MM_SHUFFLE(0, 0, 0, 0));
+
+ // detail::tvec3<valType> temp = (valType(1) - c) * axis;
+ __m128 Temp0 = _mm_sub_ps(one, CosA);
+ __m128 Temp1 = _mm_mul_ps(Temp0, AxisC);
+
+ //Rotate[0][0] = c + temp[0] * axis[0];
+ //Rotate[0][1] = 0 + temp[0] * axis[1] + s * axis[2];
+ //Rotate[0][2] = 0 + temp[0] * axis[2] - s * axis[1];
+ __m128 Axis0 = _mm_shuffle_ps(AxisC, AxisC, _MM_SHUFFLE(0, 0, 0, 0));
+ __m128 TmpA0 = _mm_mul_ps(Axis0, AxisC);
+ __m128 CosA0 = _mm_shuffle_ps(Cos0, Cos0, _MM_SHUFFLE(1, 1, 1, 0));
+ __m128 TmpA1 = _mm_add_ps(CosA0, TmpA0);
+ __m128 SinA0 = SinA;//_mm_set_ps(0.0f, s, -s, 0.0f);
+ __m128 TmpA2 = _mm_shuffle_ps(AxisC, AxisC, _MM_SHUFFLE(3, 1, 2, 3));
+ __m128 TmpA3 = _mm_mul_ps(SinA0, TmpA2);
+ __m128 TmpA4 = _mm_add_ps(TmpA1, TmpA3);
+
+ //Rotate[1][0] = 0 + temp[1] * axis[0] - s * axis[2];
+ //Rotate[1][1] = c + temp[1] * axis[1];
+ //Rotate[1][2] = 0 + temp[1] * axis[2] + s * axis[0];
+ __m128 Axis1 = _mm_shuffle_ps(AxisC, AxisC, _MM_SHUFFLE(1, 1, 1, 1));
+ __m128 TmpB0 = _mm_mul_ps(Axis1, AxisC);
+ __m128 CosA1 = _mm_shuffle_ps(Cos0, Cos0, _MM_SHUFFLE(1, 1, 0, 1));
+ __m128 TmpB1 = _mm_add_ps(CosA1, TmpB0);
+ __m128 SinB0 = SinA;//_mm_set_ps(-s, 0.0f, s, 0.0f);
+ __m128 TmpB2 = _mm_shuffle_ps(AxisC, AxisC, _MM_SHUFFLE(3, 0, 3, 2));
+ __m128 TmpB3 = _mm_mul_ps(SinA0, TmpB2);
+ __m128 TmpB4 = _mm_add_ps(TmpB1, TmpB3);
+
+ //Rotate[2][0] = 0 + temp[2] * axis[0] + s * axis[1];
+ //Rotate[2][1] = 0 + temp[2] * axis[1] - s * axis[0];
+ //Rotate[2][2] = c + temp[2] * axis[2];
+ __m128 Axis2 = _mm_shuffle_ps(AxisC, AxisC, _MM_SHUFFLE(2, 2, 2, 2));
+ __m128 TmpC0 = _mm_mul_ps(Axis2, AxisC);
+ __m128 CosA2 = _mm_shuffle_ps(Cos0, Cos0, _MM_SHUFFLE(1, 0, 1, 1));
+ __m128 TmpC1 = _mm_add_ps(CosA2, TmpC0);
+ __m128 SinC0 = SinA;//_mm_set_ps(s, -s, 0.0f, 0.0f);
+ __m128 TmpC2 = _mm_shuffle_ps(AxisC, AxisC, _MM_SHUFFLE(3, 3, 0, 1));
+ __m128 TmpC3 = _mm_mul_ps(SinA0, TmpC2);
+ __m128 TmpC4 = _mm_add_ps(TmpC1, TmpC3);
+
+ __m128 Result[4];
+ Result[0] = TmpA4;
+ Result[1] = TmpB4;
+ Result[2] = TmpC4;
+ Result[3] = _mm_set_ps(1, 0, 0, 0);
+
+ //detail::tmat4x4<valType> Result(detail::tmat4x4<valType>::null);
+ //Result[0] = m[0] * Rotate[0][0] + m[1] * Rotate[0][1] + m[2] * Rotate[0][2];
+ //Result[1] = m[0] * Rotate[1][0] + m[1] * Rotate[1][1] + m[2] * Rotate[1][2];
+ //Result[2] = m[0] * Rotate[2][0] + m[1] * Rotate[2][1] + m[2] * Rotate[2][2];
+ //Result[3] = m[3];
+ //return Result;
+ sse_mul_ps(in, Result, out);
+}
+*/
+GLM_FUNC_QUALIFIER void sse_outer_ps(__m128 const & c, __m128 const & r, __m128 out[4])
+{
+ out[0] = _mm_mul_ps(c, _mm_shuffle_ps(r, r, _MM_SHUFFLE(0, 0, 0, 0)));
+ out[1] = _mm_mul_ps(c, _mm_shuffle_ps(r, r, _MM_SHUFFLE(1, 1, 1, 1)));
+ out[2] = _mm_mul_ps(c, _mm_shuffle_ps(r, r, _MM_SHUFFLE(2, 2, 2, 2)));
+ out[3] = _mm_mul_ps(c, _mm_shuffle_ps(r, r, _MM_SHUFFLE(3, 3, 3, 3)));
+}
+
+}//namespace detail
+}//namespace glm
diff --git a/src/glm/core/intrinsic_trigonometric.hpp b/src/glm/core/intrinsic_trigonometric.hpp
new file mode 100644
index 0000000..9b69bf7
--- /dev/null
+++ b/src/glm/core/intrinsic_trigonometric.hpp
@@ -0,0 +1,29 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2009-06-09
+// Updated : 2009-06-09
+// Licence : This source is under MIT License
+// File : glm/core/intrinsic_trigonometric.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_detail_intrinsic_trigonometric
+#define glm_detail_intrinsic_trigonometric
+
+#include "setup.hpp"
+
+#if((GLM_ARCH & GLM_ARCH_SSE2) != GLM_ARCH_SSE2)
+# error "SSE2 instructions not supported or enabled"
+#else
+
+namespace glm{
+namespace detail
+{
+
+}//namespace detail
+}//namespace glm
+
+#include "intrinsic_trigonometric.inl"
+
+#endif//GLM_ARCH
+#endif//glm_detail_intrinsic_trigonometric
diff --git a/src/glm/core/intrinsic_trigonometric.inl b/src/glm/core/intrinsic_trigonometric.inl
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/glm/core/intrinsic_trigonometric.inl
diff --git a/src/glm/core/intrinsic_vector_relational.hpp b/src/glm/core/intrinsic_vector_relational.hpp
new file mode 100644
index 0000000..f064995
--- /dev/null
+++ b/src/glm/core/intrinsic_vector_relational.hpp
@@ -0,0 +1,29 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2009-06-09
+// Updated : 2009-06-09
+// Licence : This source is under MIT License
+// File : glm/core/intrinsic_vector_relational.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_detail_intrinsic_vector_relational
+#define glm_detail_intrinsic_vector_relational
+
+#include "setup.hpp"
+
+#if((GLM_ARCH & GLM_ARCH_SSE2) != GLM_ARCH_SSE2)
+# error "SSE2 instructions not supported or enabled"
+#else
+
+namespace glm{
+namespace detail
+{
+
+}//namespace detail
+}//namespace glm
+
+#include "intrinsic_vector_relational.inl"
+
+#endif//GLM_ARCH
+#endif//glm_detail_intrinsic_vector_relational
diff --git a/src/glm/core/intrinsic_vector_relational.inl b/src/glm/core/intrinsic_vector_relational.inl
new file mode 100644
index 0000000..0b8dc9d
--- /dev/null
+++ b/src/glm/core/intrinsic_vector_relational.inl
@@ -0,0 +1,347 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2009-06-09
+// Updated : 2009-06-09
+// Licence : This source is under MIT License
+// File : glm/core/intrinsic_vector_relational.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+//
+//// lessThan
+//template <typename valType>
+//GLM_FUNC_QUALIFIER typename detail::tvec2<valType>::bool_type lessThan
+//(
+// detail::tvec2<valType> const & x,
+// detail::tvec2<valType> const & y
+//)
+//{
+// GLM_STATIC_ASSERT(
+// detail::type<valType>::is_float ||
+// detail::type<valType>::is_int ||
+// detail::type<valType>::is_uint);
+//
+// return typename detail::tvec2<bool>::bool_type(x.x < y.x, x.y < y.y);
+//}
+//
+//template <typename valType>
+//GLM_FUNC_QUALIFIER typename detail::tvec3<valType>::bool_type lessThan
+//(
+// detail::tvec3<valType> const & x,
+// detail::tvec3<valType> const & y
+//)
+//{
+// GLM_STATIC_ASSERT(
+// detail::type<valType>::is_float ||
+// detail::type<valType>::is_int ||
+// detail::type<valType>::is_uint);
+//
+// return typename detail::tvec3<bool>::bool_type(x.x < y.x, x.y < y.y, x.z < y.z);
+//}
+//
+//template <typename valType>
+//GLM_FUNC_QUALIFIER typename detail::tvec4<valType>::bool_type lessThan
+//(
+// detail::tvec4<valType> const & x,
+// detail::tvec4<valType> const & y
+//)
+//{
+// GLM_STATIC_ASSERT(
+// detail::type<valType>::is_float ||
+// detail::type<valType>::is_int ||
+// detail::type<valType>::is_uint);
+//
+// return typename detail::tvec4<bool>::bool_type(x.x < y.x, x.y < y.y, x.z < y.z, x.w < y.w);
+//}
+//
+//// lessThanEqual
+//template <typename valType>
+//GLM_FUNC_QUALIFIER typename detail::tvec2<valType>::bool_type lessThanEqual
+//(
+// detail::tvec2<valType> const & x,
+// detail::tvec2<valType> const & y
+//)
+//{
+// GLM_STATIC_ASSERT(
+// detail::type<valType>::is_float ||
+// detail::type<valType>::is_int ||
+// detail::type<valType>::is_uint);
+//
+// return typename detail::tvec2<bool>::bool_type(x.x <= y.x, x.y <= y.y);
+//}
+//
+//template <typename valType>
+//GLM_FUNC_QUALIFIER typename detail::tvec3<valType>::bool_type lessThanEqual
+//(
+// detail::tvec3<valType> const & x,
+// detail::tvec3<valType> const & y
+//)
+//{
+// GLM_STATIC_ASSERT(
+// detail::type<valType>::is_float ||
+// detail::type<valType>::is_int ||
+// detail::type<valType>::is_uint);
+//
+// return typename detail::tvec3<bool>::bool_type(x.x <= y.x, x.y <= y.y, x.z <= y.z);
+//}
+//
+//template <typename valType>
+//GLM_FUNC_QUALIFIER typename detail::tvec4<valType>::bool_type lessThanEqual
+//(
+// detail::tvec4<valType> const & x,
+// detail::tvec4<valType> const & y
+//)
+//{
+// GLM_STATIC_ASSERT(
+// detail::type<valType>::is_float ||
+// detail::type<valType>::is_int ||
+// detail::type<valType>::is_uint);
+//
+// return typename detail::tvec4<bool>::bool_type(x.x <= y.x, x.y <= y.y, x.z <= y.z, x.w <= y.w);
+//}
+//
+//// greaterThan
+//template <typename valType>
+//GLM_FUNC_QUALIFIER typename detail::tvec2<valType>::bool_type greaterThan
+//(
+// detail::tvec2<valType> const & x,
+// detail::tvec2<valType> const & y
+//)
+//{
+// GLM_STATIC_ASSERT(
+// detail::type<valType>::is_float ||
+// detail::type<valType>::is_int ||
+// detail::type<valType>::is_uint);
+//
+// return typename detail::tvec2<bool>::bool_type(x.x > y.x, x.y > y.y);
+//}
+//
+//template <typename valType>
+//GLM_FUNC_QUALIFIER typename detail::tvec3<valType>::bool_type greaterThan
+//(
+// detail::tvec3<valType> const & x,
+// detail::tvec3<valType> const & y
+//)
+//{
+// GLM_STATIC_ASSERT(
+// detail::type<valType>::is_float ||
+// detail::type<valType>::is_int ||
+// detail::type<valType>::is_uint);
+//
+// return typename detail::tvec3<bool>::bool_type(x.x > y.x, x.y > y.y, x.z > y.z);
+//}
+//
+//template <typename valType>
+//GLM_FUNC_QUALIFIER typename detail::tvec4<valType>::bool_type greaterThan
+//(
+// detail::tvec4<valType> const & x,
+// detail::tvec4<valType> const & y
+//)
+//{
+// GLM_STATIC_ASSERT(
+// detail::type<valType>::is_float ||
+// detail::type<valType>::is_int ||
+// detail::type<valType>::is_uint);
+//
+// return typename detail::tvec4<bool>::bool_type(x.x > y.x, x.y > y.y, x.z > y.z, x.w > y.w);
+//}
+//
+//// greaterThanEqual
+//template <typename valType>
+//GLM_FUNC_QUALIFIER typename detail::tvec2<valType>::bool_type greaterThanEqual
+//(
+// detail::tvec2<valType> const & x,
+// detail::tvec2<valType> const & y
+//)
+//{
+// GLM_STATIC_ASSERT(
+// detail::type<valType>::is_float ||
+// detail::type<valType>::is_int ||
+// detail::type<valType>::is_uint);
+//
+// return typename detail::tvec2<bool>::bool_type(x.x >= y.x, x.y >= y.y);
+//}
+//
+//template <typename valType>
+//GLM_FUNC_QUALIFIER typename detail::tvec3<valType>::bool_type greaterThanEqual
+//(
+// detail::tvec3<valType> const & x,
+// detail::tvec3<valType> const & y
+//)
+//{
+// GLM_STATIC_ASSERT(
+// detail::type<valType>::is_float ||
+// detail::type<valType>::is_int ||
+// detail::type<valType>::is_uint);
+//
+// return typename detail::tvec3<bool>::bool_type(x.x >= y.x, x.y >= y.y, x.z >= y.z);
+//}
+//
+//template <typename valType>
+//GLM_FUNC_QUALIFIER typename detail::tvec4<valType>::bool_type greaterThanEqual
+//(
+// detail::tvec4<valType> const & x,
+// detail::tvec4<valType> const & y
+//)
+//{
+// GLM_STATIC_ASSERT(
+// detail::type<valType>::is_float ||
+// detail::type<valType>::is_int ||
+// detail::type<valType>::is_uint);
+//
+// return typename detail::tvec4<bool>::bool_type(x.x >= y.x, x.y >= y.y, x.z >= y.z, x.w >= y.w);
+//}
+//
+//// equal
+//template <typename valType>
+//GLM_FUNC_QUALIFIER typename detail::tvec2<valType>::bool_type equal
+//(
+// detail::tvec2<valType> const & x,
+// detail::tvec2<valType> const & y
+//)
+//{
+// GLM_STATIC_ASSERT(
+// detail::type<valType>::is_float ||
+// detail::type<valType>::is_int ||
+// detail::type<valType>::is_uint ||
+// detail::type<valType>::is_bool);
+//
+// return typename detail::tvec2<valType>::bool_type(x.x == y.x, x.y == y.y);
+//}
+//
+//template <typename valType>
+//GLM_FUNC_QUALIFIER typename detail::tvec3<valType>::bool_type equal
+//(
+// detail::tvec3<valType> const & x,
+// detail::tvec3<valType> const & y
+//)
+//{
+// GLM_STATIC_ASSERT(
+// detail::type<valType>::is_float ||
+// detail::type<valType>::is_int ||
+// detail::type<valType>::is_uint ||
+// detail::type<valType>::is_bool);
+//
+// return typename detail::tvec3<valType>::bool_type(x.x == y.x, x.y == y.y, x.z == y.z);
+//}
+//
+//template <typename valType>
+//GLM_FUNC_QUALIFIER typename detail::tvec4<valType>::bool_type equal
+//(
+// detail::tvec4<valType> const & x,
+// detail::tvec4<valType> const & y
+//)
+//{
+// GLM_STATIC_ASSERT(
+// detail::type<valType>::is_float ||
+// detail::type<valType>::is_int ||
+// detail::type<valType>::is_uint ||
+// detail::type<valType>::is_bool);
+//
+// return typename detail::tvec4<valType>::bool_type(x.x == y.x, x.y == y.y, x.z == y.z, x.w == y.w);
+//}
+//
+//// notEqual
+//template <typename valType>
+//GLM_FUNC_QUALIFIER typename detail::tvec2<valType>::bool_type notEqual
+//(
+// detail::tvec2<valType> const & x,
+// detail::tvec2<valType> const & y
+//)
+//{
+// GLM_STATIC_ASSERT(
+// detail::type<valType>::is_float ||
+// detail::type<valType>::is_int ||
+// detail::type<valType>::is_uint ||
+// detail::type<valType>::is_bool);
+//
+// return typename detail::tvec2<valType>::bool_type(x.x != y.x, x.y != y.y);
+//}
+//
+//template <typename valType>
+//GLM_FUNC_QUALIFIER typename detail::tvec3<valType>::bool_type notEqual
+//(
+// detail::tvec3<valType> const & x,
+// detail::tvec3<valType> const & y
+//)
+//{
+// GLM_STATIC_ASSERT(
+// detail::type<valType>::is_float ||
+// detail::type<valType>::is_int ||
+// detail::type<valType>::is_uint ||
+// detail::type<valType>::is_bool);
+//
+// return typename detail::tvec3<valType>::bool_type(x.x != y.x, x.y != y.y, x.z != y.z);
+//}
+//
+//template <typename valType>
+//GLM_FUNC_QUALIFIER typename detail::tvec4<valType>::bool_type notEqual
+//(
+// detail::tvec4<valType> const & x,
+// detail::tvec4<valType> const & y
+//)
+//{
+// GLM_STATIC_ASSERT(
+// detail::type<valType>::is_float ||
+// detail::type<valType>::is_int ||
+// detail::type<valType>::is_uint ||
+// detail::type<valType>::is_bool);
+//
+// return typename detail::tvec4<valType>::bool_type(x.x != y.x, x.y != y.y, x.z != y.z, x.w != y.w);
+//}
+//
+//// any
+//GLM_FUNC_QUALIFIER bool any(detail::tvec2<bool> const & x)
+//{
+// return x.x || x.y;
+//}
+//
+//GLM_FUNC_QUALIFIER bool any(detail::tvec3<bool> const & x)
+//{
+// return x.x || x.y || x.z;
+//}
+//
+//GLM_FUNC_QUALIFIER bool any(detail::tvec4<bool> const & x)
+//{
+// return x.x || x.y || x.z || x.w;
+//}
+//
+//// all
+//GLM_FUNC_QUALIFIER bool all(const detail::tvec2<bool>& x)
+//{
+// return x.x && x.y;
+//}
+//
+//GLM_FUNC_QUALIFIER bool all(const detail::tvec3<bool>& x)
+//{
+// return x.x && x.y && x.z;
+//}
+//
+//GLM_FUNC_QUALIFIER bool all(const detail::tvec4<bool>& x)
+//{
+// return x.x && x.y && x.z && x.w;
+//}
+//
+//// not
+//GLM_FUNC_QUALIFIER detail::tvec2<bool>::bool_type not_
+//(
+// detail::tvec2<bool> const & v
+//)
+//{
+// return detail::tvec2<bool>::bool_type(!v.x, !v.y);
+//}
+//
+//GLM_FUNC_QUALIFIER detail::tvec3<bool>::bool_type not_
+//(
+// detail::tvec3<bool> const & v
+//)
+//{
+// return detail::tvec3<bool>::bool_type(!v.x, !v.y, !v.z);
+//}
+//
+//GLM_FUNC_QUALIFIER detail::tvec4<bool>::bool_type not_
+//(
+// detail::tvec4<bool> const & v
+//)
+//{
+// return detail::tvec4<bool>::bool_type(!v.x, !v.y, !v.z, !v.w);
+//} \ No newline at end of file
diff --git a/src/glm/core/setup.hpp b/src/glm/core/setup.hpp
new file mode 100644
index 0000000..05f68d4
--- /dev/null
+++ b/src/glm/core/setup.hpp
@@ -0,0 +1,480 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2006-11-13
+// Updated : 2011-01-26
+// Licence : This source is under MIT License
+// File : glm/setup.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_setup
+#define glm_setup
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Version
+
+#define GLM_VERSION 92
+#define GLM_VERSION_MAJOR 0
+#define GLM_VERSION_MINOR 9
+#define GLM_VERSION_PATCH 2
+#define GLM_VERSION_REVISION 3
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Compiler
+
+// User defines: GLM_FORCE_COMPILER_UNKNOWN
+// TODO ? __llvm__
+
+#define GLM_COMPILER_UNKNOWN 0x00000000
+
+// Visual C++ defines
+#define GLM_COMPILER_VC 0x01000000
+#define GLM_COMPILER_VC2 0x01000010
+#define GLM_COMPILER_VC4 0x01000020
+#define GLM_COMPILER_VC5 0x01000030
+#define GLM_COMPILER_VC6 0x01000040
+#define GLM_COMPILER_VC2002 0x01000050
+#define GLM_COMPILER_VC2003 0x01000060
+#define GLM_COMPILER_VC2005 0x01000070
+#define GLM_COMPILER_VC2008 0x01000080
+#define GLM_COMPILER_VC2010 0x01000090
+#define GLM_COMPILER_VC2011 0x010000A0
+
+// GCC defines
+#define GLM_COMPILER_GCC 0x02000000
+#define GLM_COMPILER_GCC_LLVM 0x02000001
+#define GLM_COMPILER_GCC_CLANG 0x02000002
+#define GLM_COMPILER_GCC30 0x02000010
+#define GLM_COMPILER_GCC31 0x02000020
+#define GLM_COMPILER_GCC32 0x02000030
+#define GLM_COMPILER_GCC33 0x02000040
+#define GLM_COMPILER_GCC34 0x02000050
+#define GLM_COMPILER_GCC35 0x02000060
+#define GLM_COMPILER_GCC40 0x02000070
+#define GLM_COMPILER_GCC41 0x02000080
+#define GLM_COMPILER_GCC42 0x02000090
+#define GLM_COMPILER_GCC43 0x020000A0
+#define GLM_COMPILER_GCC44 0x020000B0
+#define GLM_COMPILER_GCC45 0x020000C0
+#define GLM_COMPILER_GCC46 0x020000D0
+#define GLM_COMPILER_GCC47 0x020000E0
+#define GLM_COMPILER_GCC48 0x020000F0
+#define GLM_COMPILER_GCC49 0x02000100
+#define GLM_COMPILER_GCC50 0x02000200
+
+// G++ command line to display defined
+// echo "" | g++ -E -dM -x c++ - | sort
+
+// Borland C++ defines. How to identify BC?
+#define GLM_COMPILER_BC 0x04000000
+#define GLM_COMPILER_BCB4 0x04000100
+#define GLM_COMPILER_BCB5 0x04000200
+#define GLM_COMPILER_BCB6 0x04000300
+//#define GLM_COMPILER_BCBX 0x04000400 // What's the version value?
+#define GLM_COMPILER_BCB2009 0x04000500
+
+// CodeWarrior
+#define GLM_COMPILER_CODEWARRIOR 0x08000000
+
+// CUDA
+#define GLM_COMPILER_CUDA 0x10000000
+#define GLM_COMPILER_CUDA30 0x10000010
+#define GLM_COMPILER_CUDA31 0x10000020
+#define GLM_COMPILER_CUDA32 0x10000030
+#define GLM_COMPILER_CUDA40 0x10000040
+
+// Clang
+#define GLM_COMPILER_CLANG 0x20000000
+#define GLM_COMPILER_CLANG26 0x20000010
+#define GLM_COMPILER_CLANG27 0x20000020
+#define GLM_COMPILER_CLANG28 0x20000030
+#define GLM_COMPILER_CLANG29 0x20000040
+
+// LLVM GCC
+#define GLM_COMPILER_LLVM_GCC 0x40000000
+
+// Build model
+#define GLM_MODEL_32 0x00000010
+#define GLM_MODEL_64 0x00000020
+
+// Force generic C++ compiler
+#ifdef GLM_FORCE_COMPILER_UNKNOWN
+# define GLM_COMPILER GLM_COMPILER_UNKNOWN
+
+// CUDA
+#elif defined(__CUDACC__)
+# define GLM_COMPILER GLM_COMPILER_CUDA
+
+// Visual C++
+#elif defined(_MSC_VER)
+# if _MSC_VER == 900
+# define GLM_COMPILER GLM_COMPILER_VC2
+# elif _MSC_VER == 1000
+# define GLM_COMPILER GLM_COMPILER_VC4
+# elif _MSC_VER == 1100
+# define GLM_COMPILER GLM_COMPILER_VC5
+# elif _MSC_VER == 1200
+# define GLM_COMPILER GLM_COMPILER_VC6
+# elif _MSC_VER == 1300
+# define GLM_COMPILER GLM_COMPILER_VC2002
+# elif _MSC_VER == 1310
+# define GLM_COMPILER GLM_COMPILER_VC2003
+# elif _MSC_VER == 1400
+# define GLM_COMPILER GLM_COMPILER_VC2005
+# elif _MSC_VER == 1500
+# define GLM_COMPILER GLM_COMPILER_VC2008
+# elif _MSC_VER == 1600
+# define GLM_COMPILER GLM_COMPILER_VC2010
+# elif _MSC_VER == 1700
+# define GLM_COMPILER GLM_COMPILER_VC2011
+# else//_MSC_VER
+# define GLM_COMPILER GLM_COMPILER_VC
+# endif//_MSC_VER
+
+// G++
+#elif defined(__GNUC__) || defined(__llvm__) || defined(__clang__)
+# if defined (__llvm__)
+# define GLM_COMPILER_GCC_EXTRA GLM_COMPILER_GCC_LLVM
+# elif defined (__clang__)
+# define GLM_COMPILER_GCC_EXTRA GLM_COMPILER_GCC_CLANG
+# else
+# define GLM_COMPILER_GCC_EXTRA 0
+# endif
+#
+# if (__GNUC__ == 3) && (__GNUC_MINOR__ == 2)
+# define GLM_COMPILER GLM_COMPILER_GCC32
+# elif (__GNUC__ == 3) && (__GNUC_MINOR__ == 3)
+# define GLM_COMPILER GLM_COMPILER_GCC33
+# elif (__GNUC__ == 3) && (__GNUC_MINOR__ == 4)
+# define GLM_COMPILER GLM_COMPILER_GCC34
+# elif (__GNUC__ == 3) && (__GNUC_MINOR__ == 5)
+# define GLM_COMPILER GLM_COMPILER_GCC35
+# elif (__GNUC__ == 4) && (__GNUC_MINOR__ == 0)
+# define GLM_COMPILER (GLM_COMPILER_GCC40 | GLM_COMPILER_GCC_EXTRA)
+# elif (__GNUC__ == 4) && (__GNUC_MINOR__ == 1)
+# define GLM_COMPILER (GLM_COMPILER_GCC41 | GLM_COMPILER_GCC_EXTRA)
+# elif (__GNUC__ == 4) && (__GNUC_MINOR__ == 2)
+# define GLM_COMPILER (GLM_COMPILER_GCC42 | GLM_COMPILER_GCC_EXTRA)
+# elif (__GNUC__ == 4) && (__GNUC_MINOR__ == 3)
+# define GLM_COMPILER (GLM_COMPILER_GCC43 | GLM_COMPILER_GCC_EXTRA)
+# elif (__GNUC__ == 4) && (__GNUC_MINOR__ == 4)
+# define GLM_COMPILER (GLM_COMPILER_GCC44 | GLM_COMPILER_GCC_EXTRA)
+# elif (__GNUC__ == 4) && (__GNUC_MINOR__ == 5)
+# define GLM_COMPILER (GLM_COMPILER_GCC45 | GLM_COMPILER_GCC_EXTRA)
+# elif (__GNUC__ == 4) && (__GNUC_MINOR__ == 6)
+# define GLM_COMPILER (GLM_COMPILER_GCC46 | GLM_COMPILER_GCC_EXTRA)
+# elif (__GNUC__ == 4) && (__GNUC_MINOR__ == 7)
+# define GLM_COMPILER (GLM_COMPILER_GCC47 | GLM_COMPILER_GCC_EXTRA)
+# elif (__GNUC__ == 4) && (__GNUC_MINOR__ == 8)
+# define GLM_COMPILER (GLM_COMPILER_GCC48 | GLM_COMPILER_GCC_EXTRA)
+# elif (__GNUC__ == 4) && (__GNUC_MINOR__ == 9)
+# define GLM_COMPILER (GLM_COMPILER_GCC49 | GLM_COMPILER_GCC_EXTRA)
+# elif (__GNUC__ == 5) && (__GNUC_MINOR__ == 0)
+# define GLM_COMPILER (GLM_COMPILER_GCC50 | GLM_COMPILER_GCC_EXTRA)
+# else
+# define GLM_COMPILER (GLM_COMPILER_GCC | GLM_COMPILER_GCC_EXTRA)
+# endif
+
+// Borland C++
+#elif defined(_BORLANDC_)
+# if defined(VER125)
+# define GLM_COMPILER GLM_COMPILER_BCB4
+# elif defined(VER130)
+# define GLM_COMPILER GLM_COMPILER_BCB5
+# elif defined(VER140)
+# define GLM_COMPILER GLM_COMPILER_BCB6
+# elif defined(VER200)
+# define GLM_COMPILER GLM_COMPILER_BCB2009
+# else
+# define GLM_COMPILER GLM_COMPILER_BC
+# endif
+
+// Codewarrior
+#elif defined(__MWERKS__)
+# define GLM_COMPILER GLM_COMPILER_CODEWARRIOR
+
+#else
+# define GLM_COMPILER GLM_COMPILER_UNKNOWN
+#endif
+
+#ifndef GLM_COMPILER
+#error "GLM_COMPILER undefined, your compiler may not be supported by GLM. Add #define GLM_COMPILER 0 to ignore this message."
+#endif//GLM_COMPILER
+
+// Report compiler detection
+#if(defined(GLM_MESSAGES) && !defined(GLM_MESSAGE_COMPILER_DISPLAYED))
+# define GLM_MESSAGE_COMPILER_DISPLAYED
+# if(GLM_COMPILER & GLM_COMPILER_CUDA)
+# pragma message("GLM: CUDA compiler detected")
+# elif(GLM_COMPILER & GLM_COMPILER_VC)
+# pragma message("GLM: Visual C++ compiler detected")
+# elif(GLM_COMPILER & GLM_COMPILER_CLANG)
+# pragma message("GLM: Clang compiler detected")
+# elif(GLM_COMPILER & GLM_COMPILER_LLVM_GCC)
+# pragma message("GLM: LLVM GCC compiler detected")
+# elif(GLM_COMPILER & GLM_COMPILER_GCC)
+# if(GLM_COMPILER == GLM_COMPILER_GCC_LLVM)
+# pragma message("GLM: LLVM GCC compiler detected")
+# elif(GLM_COMPILER == GLM_COMPILER_GCC_CLANG)
+# pragma message("GLM: CLANG compiler detected")
+# else
+# pragma message("GLM: GCC compiler detected")
+# endif
+# elif(GLM_COMPILER & GLM_COMPILER_BC)
+# pragma message("GLM: Borland compiler detected but not supported")
+# elif(GLM_COMPILER & GLM_COMPILER_CODEWARRIOR)
+# pragma message("GLM: Codewarrior compiler detected but not supported")
+# else
+# pragma message("GLM: Compiler not detected")
+# endif
+#endif//GLM_MESSAGE
+
+/////////////////
+// Build model //
+
+#if(GLM_COMPILER & GLM_COMPILER_VC)
+# if defined(_M_X64)
+# define GLM_MODEL GLM_MODEL_64
+# else
+# define GLM_MODEL GLM_MODEL_32
+# endif//_M_X64
+#elif(GLM_COMPILER & GLM_COMPILER_GCC)
+# if(defined(__WORDSIZE) && (__WORDSIZE == 64)) || defined(__arch64__) || defined(__LP64__) || defined(__x86_64__)
+# define GLM_MODEL GLM_MODEL_64
+# else
+# define GLM_MODEL GLM_MODEL_32
+# endif//
+#else
+# define GLM_MODEL GLM_MODEL_32
+#endif//
+
+#if(!defined(GLM_MODEL) && GLM_COMPILER != 0)
+#error "GLM_MODEL undefined, your compiler may not be supported by GLM. Add #define GLM_MODEL 0 to ignore this message."
+#endif//GLM_MODEL
+
+#if(defined(GLM_MESSAGES) && !defined(GLM_MESSAGE_MODEL_DISPLAYED))
+# define GLM_MESSAGE_MODEL_DISPLAYED
+# if(GLM_MODEL == GLM_MODEL_64)
+# pragma message("GLM: 64 bits model")
+# elif(GLM_MODEL == GLM_MODEL_32)
+# pragma message("GLM: 32 bits model")
+# endif//GLM_MODEL
+#endif//GLM_MESSAGE
+
+/////////////////
+// C++ Version //
+
+// User defines: GLM_FORCE_CXX98
+
+#define GLM_LANG_CXX 0
+#define GLM_LANG_CXX98 1
+#define GLM_LANG_CXX0X 2
+#define GLM_LANG_CXXMS 3
+#define GLM_LANG_CXXGNU 4
+
+#if(defined(GLM_FORCE_CXX98))
+# define GLM_LANG GLM_LANG_CXX98
+#elif(((GLM_COMPILER & GLM_COMPILER_GCC) == GLM_COMPILER_GCC) && defined(__GXX_EXPERIMENTAL_CXX0X__)) // -std=c++0x or -std=gnu++0x
+# define GLM_LANG GLM_LANG_CXX0X
+#elif(GLM_COMPILER == GLM_COMPILER_VC2010) //_MSC_EXTENSIONS for MS language extensions
+# define GLM_LANG GLM_LANG_CXX0X
+#elif(((GLM_COMPILER & GLM_COMPILER_GCC) == GLM_COMPILER_GCC) && defined(__STRICT_ANSI__))
+# define GLM_LANG GLM_LANG_CXX98
+#elif(((GLM_COMPILER & GLM_COMPILER_VC) == GLM_COMPILER_VC) && !defined(_MSC_EXTENSIONS))
+# define GLM_LANG GLM_LANG_CXX98
+#else
+# define GLM_LANG GLM_LANG_CXX
+#endif
+
+#if(defined(GLM_MESSAGES) && !defined(GLM_MESSAGE_LANG_DISPLAYED))
+# define GLM_MESSAGE_LANG_DISPLAYED
+# if(GLM_LANG == GLM_LANG_CXX98)
+# pragma message("GLM: C++98")
+# elif(GLM_LANG == GLM_LANG_CXX0X)
+# pragma message("GLM: C++0x")
+# endif//GLM_MODEL
+#endif//GLM_MESSAGE
+
+/////////////////
+// Platform
+
+// User defines: GLM_FORCE_PURE GLM_FORCE_SSE2 GLM_FORCE_AVX
+
+#define GLM_ARCH_PURE 0x0000 //(0x0000)
+#define GLM_ARCH_SSE2 0x0001 //(0x0001)
+#define GLM_ARCH_SSE3 0x0003 //(0x0002 | GLM_ARCH_SSE2)
+#define GLM_ARCH_AVX 0x0007 //(0x0004 | GLM_ARCH_SSE3 | GLM_ARCH_SSE2)
+
+#if(defined(GLM_FORCE_PURE))
+# define GLM_ARCH GLM_ARCH_PURE
+#elif(defined(GLM_FORCE_AVX))
+# define GLM_ARCH GLM_ARCH_AVX
+#elif(defined(GLM_FORCE_SSE3))
+# define GLM_ARCH GLM_ARCH_SSE3
+#elif(defined(GLM_FORCE_SSE2))
+# define GLM_ARCH GLM_ARCH_SSE2
+#elif((GLM_COMPILER & GLM_COMPILER_VC) && (defined(_M_IX86) || defined(_M_X64)))
+# if(defined(_M_CEE_PURE))
+# define GLM_ARCH GLM_ARCH_PURE
+# elif(GLM_COMPILER >= GLM_COMPILER_VC2010)
+# if(_MSC_FULL_VER >= 160031118) //160031118: VC2010 SP1 beta full version
+# define GLM_ARCH GLM_ARCH_AVX //GLM_ARCH_AVX (Require SP1)
+# else
+# define GLM_ARCH GLM_ARCH_SSE3
+# endif
+# elif(GLM_COMPILER >= GLM_COMPILER_VC2008)
+# define GLM_ARCH GLM_ARCH_SSE3
+# elif(GLM_COMPILER >= GLM_COMPILER_VC2005)
+# define GLM_ARCH GLM_ARCH_SSE2
+# else
+# define GLM_ARCH GLM_ARCH_PURE
+# endif
+#elif(GLM_COMPILER & GLM_COMPILER_LLVM_GCC)
+# if(defined(__AVX__))
+# define GLM_ARCH GLM_ARCH_AVX
+# elif(defined(__SSE3__))
+# define GLM_ARCH GLM_ARCH_SSE3
+# elif(defined(__SSE2__))
+# define GLM_ARCH GLM_ARCH_SSE2
+# else
+# define GLM_ARCH GLM_ARCH_PURE
+# endif
+#elif((GLM_COMPILER & GLM_COMPILER_GCC) && (defined(__i386__) || defined(__x86_64__)))
+# if(defined(__AVX__))
+# define GLM_ARCH GLM_ARCH_AVX
+# elif(defined(__SSE3__))
+# define GLM_ARCH GLM_ARCH_SSE3
+# elif(defined(__SSE2__))
+# define GLM_ARCH GLM_ARCH_SSE2
+# else
+# define GLM_ARCH GLM_ARCH_PURE
+# endif
+#else
+# define GLM_ARCH GLM_ARCH_PURE
+#endif
+
+#if(GLM_ARCH != GLM_ARCH_PURE)
+#if((GLM_ARCH & GLM_ARCH_AVX) == GLM_ARCH_AVX)
+# include <immintrin.h>
+#endif//GLM_ARCH
+#if((GLM_ARCH & GLM_ARCH_SSE3) == GLM_ARCH_SSE3)
+# include <pmmintrin.h>
+#endif//GLM_ARCH
+#if((GLM_ARCH & GLM_ARCH_SSE2) == GLM_ARCH_SSE2)
+# include <emmintrin.h>
+#endif//GLM_ARCH
+#endif//(GLM_ARCH != GLM_ARCH_PURE)
+
+#if(defined(GLM_MESSAGES) && !defined(GLM_MESSAGE_ARCH_DISPLAYED))
+# define GLM_MESSAGE_ARCH_DISPLAYED
+# if(GLM_ARCH == GLM_ARCH_PURE)
+# pragma message("GLM: Platform independent")
+# elif(GLM_ARCH == GLM_ARCH_SSE2)
+# pragma message("GLM: SSE2 build platform")
+# elif(GLM_ARCH == GLM_ARCH_SSE3)
+# pragma message("GLM: SSE3 build platform")
+# elif(GLM_ARCH == GLM_ARCH_AVX)
+# pragma message("GLM: AVX build platform")
+# endif//GLM_ARCH
+#endif//GLM_MESSAGE
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Components
+
+//#define GLM_FORCE_ONLY_XYZW
+#define GLM_COMPONENT_GLSL_NAMES 0
+#define GLM_COMPONENT_ONLY_XYZW 1 // To disable multiple vector component names access.
+#define GLM_COMPONENT_MS_EXT 2 // To use anonymous union to provide multiple component names access for class valType. Visual C++ only.
+
+#ifndef GLM_FORCE_ONLY_XYZW
+# if((GLM_COMPILER & GLM_COMPILER_VC) && defined(_MSC_EXTENSIONS))
+# define GLM_COMPONENT GLM_COMPONENT_MS_EXT
+# else
+# define GLM_COMPONENT GLM_COMPONENT_GLSL_NAMES
+# endif
+#else
+# define GLM_COMPONENT GLM_COMPONENT_ONLY_XYZW
+#endif
+
+#if((GLM_COMPONENT == GLM_COMPONENT_MS_EXT) && !(GLM_COMPILER & GLM_COMPILER_VC))
+# error "GLM_COMPONENT value is GLM_COMPONENT_MS_EXT but this is not allowed with the current compiler."
+#endif
+
+#if(defined(GLM_MESSAGES) && !defined(GLM_MESSAGE_COMPONENT_DISPLAYED))
+# define GLM_MESSAGE_COMPONENT_DISPLAYED
+# if(GLM_COMPONENT == GLM_COMPONENT_GLSL_NAMES)
+# pragma message("GLM: GLSL multiple vector component names")
+# elif(GLM_COMPONENT == GLM_COMPONENT_ONLY_XYZW)
+# pragma message("GLM: x,y,z,w vector component names only")
+# elif(GLM_COMPONENT == GLM_COMPONENT_MS_EXT)
+# pragma message("GLM: Multiple vector component names through Visual C++ language extensions")
+# else
+# error "GLM_COMPONENT value unknown"
+# endif//GLM_MESSAGE_COMPONENT_DISPLAYED
+#endif//GLM_MESSAGE
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Static assert
+
+#if(GLM_LANG == GLM_LANG_CXX0X)
+# define GLM_STATIC_ASSERT(x, message) static_assert(x, message)
+#elif(defined(BOOST_STATIC_ASSERT))
+# define GLM_STATIC_ASSERT(x, message) BOOST_STATIC_ASSERT(x)
+#elif(GLM_COMPILER & GLM_COMPILER_VC)
+# define GLM_STATIC_ASSERT(x, message) typedef char __CASSERT__##__LINE__[(x) ? 1 : -1]
+#else
+# define GLM_STATIC_ASSERT(x, message)
+# define GLM_STATIC_ASSERT_NULL
+#endif//GLM_LANG
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Qualifiers
+
+// User defines: GLM_FORCE_INLINE GLM_FORCE_CUDA
+
+#if(defined(GLM_FORCE_CUDA) || (GLM_COMPILER & GLM_COMPILER_CUDA))
+# define GLM_CUDA_FUNC_DEF __device__ __host__
+# define GLM_CUDA_FUNC_DECL __device__ __host__
+#else
+# define GLM_CUDA_FUNC_DEF
+# define GLM_CUDA_FUNC_DECL
+#endif
+
+#if GLM_COMPILER & GLM_COMPILER_GCC
+#define GLM_VAR_USED __attribute__ ((unused))
+#else
+#define GLM_VAR_USED
+#endif
+
+#if(defined(GLM_FORCE_INLINE))
+# if((GLM_COMPILER & GLM_COMPILER_VC) && (GLM_COMPILER >= GLM_COMPILER_VC2005))
+# define GLM_INLINE __forceinline
+# elif((GLM_COMPILER & GLM_COMPILER_GCC) && (GLM_COMPILER >= GLM_COMPILER_GCC34))
+# define GLM_INLINE __attribute__((always_inline))
+# else
+# define GLM_INLINE inline
+# endif//GLM_COMPILER
+#else
+# define GLM_INLINE inline
+#endif//defined(GLM_FORCE_INLINE)
+
+#define GLM_FUNC_DECL GLM_CUDA_FUNC_DECL
+#define GLM_FUNC_QUALIFIER GLM_CUDA_FUNC_DEF GLM_INLINE
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Swizzle operators
+
+// User defines: GLM_SWIZZLE_XYZW GLM_SWIZZLE_RGBA GLM_SWIZZLE_STQP GLM_SWIZZLE
+
+#if(defined(GLM_MESSAGES) && !defined(GLM_MESSAGE_SWIZZLE_DISPLAYED))
+# define GLM_MESSAGE_SWIZZLE_DISPLAYED
+# if(defined(GLM_SWIZZLE))
+# pragma message("GLM: Full swizzling operator enabled")
+# elif(!defined(GLM_SWIZZLE_XYZW) && !defined(GLM_SWIZZLE_RGBA) && !defined(GLM_SWIZZLE_STQP) && !defined(GLM_SWIZZLE))
+# pragma message("GLM: No swizzling operator enabled")
+# else
+# pragma message("GLM: Partial swizzling operator enabled")
+# endif
+#endif//GLM_MESSAGE
+
+#endif//glm_setup
diff --git a/src/glm/core/type.hpp b/src/glm/core/type.hpp
new file mode 100644
index 0000000..25585cb
--- /dev/null
+++ b/src/glm/core/type.hpp
@@ -0,0 +1,322 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2008-01-08
+// Updated : 2008-01-08
+// Licence : This source is under MIT License
+// File : glm/core/type.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_core_type
+#define glm_core_type
+
+#include "type_half.hpp"
+#include "type_float.hpp"
+#include "type_int.hpp"
+
+#include "type_gentype.hpp"
+
+#include "type_vec1.hpp"
+#include "type_vec2.hpp"
+#include "type_vec3.hpp"
+#include "type_vec4.hpp"
+
+#include "type_mat2x2.hpp"
+#include "type_mat2x3.hpp"
+#include "type_mat2x4.hpp"
+#include "type_mat3x2.hpp"
+#include "type_mat3x3.hpp"
+#include "type_mat3x4.hpp"
+#include "type_mat4x2.hpp"
+#include "type_mat4x3.hpp"
+#include "type_mat4x4.hpp"
+
+namespace glm{
+namespace core{
+namespace type
+{
+ //////////////////////////
+ // Float definition
+
+#if(defined(GLM_PRECISION_HIGHP_FLOAT))
+ typedef precision::highp_vec2 vec2;
+ typedef precision::highp_vec3 vec3;
+ typedef precision::highp_vec4 vec4;
+ typedef precision::highp_mat2x2 mat2x2;
+ typedef precision::highp_mat2x3 mat2x3;
+ typedef precision::highp_mat2x4 mat2x4;
+ typedef precision::highp_mat3x2 mat3x2;
+ typedef precision::highp_mat3x3 mat3x3;
+ typedef precision::highp_mat3x4 mat3x4;
+ typedef precision::highp_mat4x2 mat4x2;
+ typedef precision::highp_mat4x3 mat4x3;
+ typedef precision::highp_mat4x4 mat4x4;
+#elif(defined(GLM_PRECISION_MEDIUMP_FLOAT))
+ typedef precision::mediump_vec2 vec2;
+ typedef precision::mediump_vec3 vec3;
+ typedef precision::mediump_vec4 vec4;
+ typedef precision::mediump_mat2x2 mat2x2;
+ typedef precision::mediump_mat2x3 mat2x3;
+ typedef precision::mediump_mat2x4 mat2x4;
+ typedef precision::mediump_mat3x2 mat3x2;
+ typedef precision::mediump_mat3x3 mat3x3;
+ typedef precision::mediump_mat3x4 mat3x4;
+ typedef precision::mediump_mat4x2 mat4x2;
+ typedef precision::mediump_mat4x3 mat4x3;
+ typedef precision::mediump_mat4x4 mat4x4;
+#elif(defined(GLM_PRECISION_LOWP_FLOAT))
+ typedef precision::lowp_vec2 vec2;
+ typedef precision::lowp_vec3 vec3;
+ typedef precision::lowp_vec4 vec4;
+ typedef precision::lowp_mat2x2 mat2x2;
+ typedef precision::lowp_mat2x3 mat2x3;
+ typedef precision::lowp_mat2x4 mat2x4;
+ typedef precision::lowp_mat3x2 mat3x2;
+ typedef precision::lowp_mat3x3 mat3x3;
+ typedef precision::lowp_mat3x4 mat3x4;
+ typedef precision::lowp_mat4x2 mat4x2;
+ typedef precision::lowp_mat4x3 mat4x3;
+ typedef precision::lowp_mat4x4 mat4x4;
+#else
+ //! 2 components vector of floating-point numbers.
+ //! From GLSL 1.30.8 specification, section 4.1.5 Vectors.
+ //! \ingroup core_types
+ typedef precision::mediump_vec2 vec2;
+
+ //! 3 components vector of floating-point numbers.
+ //! From GLSL 1.30.8 specification, section 4.1.5 Vectors.
+ //! \ingroup core_types
+ typedef precision::mediump_vec3 vec3;
+
+ //! 4 components vector of floating-point numbers.
+ //! From GLSL 1.30.8 specification, section 4.1.5 Vectors.
+ //! \ingroup core_types
+ typedef precision::mediump_vec4 vec4;
+
+ //! 2 columns of 2 components matrix of floating-point numbers.
+ //! (From GLSL 1.30.8 specification, section 4.1.6 Matrices)
+ //! \ingroup core_types
+ typedef precision::mediump_mat2x2 mat2x2;
+
+ //! 2 columns of 3 components matrix of floating-point numbers.
+ //! (From GLSL 1.30.8 specification, section 4.1.6 Matrices)
+ //! \ingroup core_types
+ typedef precision::mediump_mat2x3 mat2x3;
+
+ //! 2 columns of 4 components matrix of floating-point numbers.
+ //! (From GLSL 1.30.8 specification, section 4.1.6 Matrices)
+ //! \ingroup core_types
+ typedef precision::mediump_mat2x4 mat2x4;
+
+ //! 3 columns of 2 components matrix of floating-point numbers.
+ //! (From GLSL 1.30.8 specification, section 4.1.6 Matrices)
+ //! \ingroup core_types
+ typedef precision::mediump_mat3x2 mat3x2;
+
+ //! 3 columns of 3 components matrix of floating-point numbers.
+ //! (From GLSL 1.30.8 specification, section 4.1.6 Matrices)
+ //! \ingroup core_types
+ typedef precision::mediump_mat3x3 mat3x3;
+
+ //! 3 columns of 4 components matrix of floating-point numbers.
+ //! (From GLSL 1.30.8 specification, section 4.1.6 Matrices)
+ //! \ingroup core_types
+ typedef precision::mediump_mat3x4 mat3x4;
+
+ //! 4 columns of 2 components matrix of floating-point numbers.
+ //! (From GLSL 1.30.8 specification, section 4.1.6 Matrices)
+ //! \ingroup core_types
+ typedef precision::mediump_mat4x2 mat4x2;
+
+ //! 4 columns of 3 components matrix of floating-point numbers.
+ //! (From GLSL 1.30.8 specification, section 4.1.6 Matrices)
+ //! \ingroup core_types
+ typedef precision::mediump_mat4x3 mat4x3;
+
+ //! 4 columns of 4 components matrix of floating-point numbers.
+ //! (From GLSL 1.30.8 specification, section 4.1.6 Matrices)
+ //! \ingroup core_types
+ typedef precision::mediump_mat4x4 mat4x4;
+
+#endif//GLM_PRECISION
+
+ //! 2 columns of 2 components matrix of floating-point numbers.
+ //! (From GLSL 1.30.8 specification, section 4.1.6 Matrices)
+ //! \ingroup core_types
+ typedef mat2x2 mat2;
+
+ //! 3 columns of 3 components matrix of floating-point numbers.
+ //! (From GLSL 1.30.8 specification, section 4.1.6 Matrices)
+ //! \ingroup core_types
+ typedef mat3x3 mat3;
+
+ //! 4 columns of 4 components matrix of floating-point numbers.
+ //! (From GLSL 1.30.8 specification, section 4.1.6 Matrices)
+ //! \ingroup core_types
+ typedef mat4x4 mat4;
+
+ //////////////////////////
+ // Signed integer definition
+
+#if(defined(GLM_PRECISION_HIGHP_INT))
+ typedef precision::highp_ivec2 ivec2;
+ typedef precision::highp_ivec3 ivec3;
+ typedef precision::highp_ivec4 ivec4;
+#elif(defined(GLM_PRECISION_MEDIUMP_INT))
+ typedef precision::mediump_ivec2 ivec2;
+ typedef precision::mediump_ivec3 ivec3;
+ typedef precision::mediump_ivec4 ivec4;
+#elif(defined(GLM_PRECISION_LOWP_INT))
+ typedef precision::lowp_ivec2 ivec2;
+ typedef precision::lowp_ivec3 ivec3;
+ typedef precision::lowp_ivec4 ivec4;
+#else
+ //! 2 components vector of signed integer numbers.
+ //! From GLSL 1.30.8 specification, section 4.1.5 Vectors.
+ //! \ingroup core_types
+ typedef precision::mediump_ivec2 ivec2;
+
+ //! 3 components vector of signed integer numbers.
+ //! From GLSL 1.30.8 specification, section 4.1.5 Vectors.
+ //! \ingroup core_types
+ typedef precision::mediump_ivec3 ivec3;
+
+ //! 4 components vector of signed integer numbers.
+ //! From GLSL 1.30.8 specification, section 4.1.5 Vectors.
+ //! \ingroup core_types
+ typedef precision::mediump_ivec4 ivec4;
+#endif//GLM_PRECISION
+
+ //////////////////////////
+ // Unsigned integer definition
+
+#if(defined(GLM_PRECISION_HIGHP_UINT))
+ typedef precision::highp_uvec2 uvec2;
+ typedef precision::highp_uvec3 uvec3;
+ typedef precision::highp_uvec4 uvec4;
+#elif(defined(GLM_PRECISION_MEDIUMP_UINT))
+ typedef precision::mediump_uvec2 uvec2;
+ typedef precision::mediump_uvec3 uvec3;
+ typedef precision::mediump_uvec4 uvec4;
+#elif(defined(GLM_PRECISION_LOWP_UINT))
+ typedef precision::lowp_uvec2 uvec2;
+ typedef precision::lowp_uvec3 uvec3;
+ typedef precision::lowp_uvec4 uvec4;
+#else
+ //! 2 components vector of unsigned integer numbers.
+ //! From GLSL 1.30.8 specification, section 4.1.5 Vectors.
+ //! \ingroup core_types
+ typedef precision::mediump_uvec2 uvec2;
+
+ //! 3 components vector of unsigned integer numbers.
+ //! From GLSL 1.30.8 specification, section 4.1.5 Vectors.
+ //! \ingroup core_types
+ typedef precision::mediump_uvec3 uvec3;
+
+ //! 4 components vector of unsigned integer numbers.
+ //! From GLSL 1.30.8 specification, section 4.1.5 Vectors.
+ //! \ingroup core_types
+ typedef precision::mediump_uvec4 uvec4;
+#endif//GLM_PRECISION
+
+ //////////////////////////
+ // Boolean definition
+
+ //! 2 components vector of boolean.
+ //! From GLSL 1.30.8 specification, section 4.1.5 Vectors.
+ //! \ingroup core_types
+ typedef detail::tvec2<bool> bvec2;
+
+ //! 3 components vector of boolean.
+ //! From GLSL 1.30.8 specification, section 4.1.5 Vectors.
+ //! \ingroup core_types
+ typedef detail::tvec3<bool> bvec3;
+
+ //! 4 components vector of boolean.
+ //! From GLSL 1.30.8 specification, section 4.1.5 Vectors.
+ //! \ingroup core_types
+ typedef detail::tvec4<bool> bvec4;
+
+ //////////////////////////
+ // Double definition
+
+ //! Vector of 2 double-precision floating-point numbers.
+ //! From GLSL 4.00.8 specification, section 4.1 Basic Types.
+ //! \ingroup core_types
+ typedef detail::tvec2<double> dvec2;
+
+ //! Vector of 3 double-precision floating-point numbers.
+ //! From GLSL 4.00.8 specification, section 4.1 Basic Types.
+ //! \ingroup core_types
+ typedef detail::tvec3<double> dvec3;
+
+ //! Vector of 4 double-precision floating-point numbers.
+ //! From GLSL 4.00.8 specification, section 4.1 Basic Types.
+ //! \ingroup core_types
+ typedef detail::tvec4<double> dvec4;
+
+ //! 2 * 2 matrix of double-precision floating-point numbers.
+ //! From GLSL 4.00.8 specification, section 4.1 Basic Types.
+ //! \ingroup core_types
+ typedef detail::tmat2x2<double> dmat2;
+
+ //! 3 * 3 matrix of double-precision floating-point numbers.
+ //! From GLSL 4.00.8 specification, section 4.1 Basic Types.
+ //! \ingroup core_types
+ typedef detail::tmat3x3<double> dmat3;
+
+ //! 4 * 4 matrix of double-precision floating-point numbers.
+ //! From GLSL 4.00.8 specification, section 4.1 Basic Types.
+ //! \ingroup core_types
+ typedef detail::tmat4x4<double> dmat4;
+
+ //! 2 * 2 matrix of double-precision floating-point numbers.
+ //! From GLSL 4.00.8 specification, section 4.1 Basic Types.
+ //! \ingroup core_types
+ typedef detail::tmat2x2<double> dmat2x2;
+
+ //! 2 * 3 matrix of double-precision floating-point numbers.
+ //! From GLSL 4.00.8 specification, section 4.1 Basic Types.
+ //! \ingroup core_types
+ typedef detail::tmat2x3<double> dmat2x3;
+
+ //! 2 * 4 matrix of double-precision floating-point numbers.
+ //! From GLSL 4.00.8 specification, section 4.1 Basic Types.
+ //! \ingroup core_types
+ typedef detail::tmat2x4<double> dmat2x4;
+
+ //! 3 * 2 matrix of double-precision floating-point numbers.
+ //! From GLSL 4.00.8 specification, section 4.1 Basic Types.
+ //! \ingroup core_types
+ typedef detail::tmat3x2<double> dmat3x2;
+
+ //! 3 * 3 matrix of double-precision floating-point numbers.
+ //! From GLSL 4.00.8 specification, section 4.1 Basic Types.
+ //! \ingroup core_types
+ typedef detail::tmat3x3<double> dmat3x3;
+
+ //! 3 * 4 matrix of double-precision floating-point numbers.
+ //! From GLSL 4.00.8 specification, section 4.1 Basic Types.
+ //! \ingroup core_types
+ typedef detail::tmat3x4<double> dmat3x4;
+
+ //! 4 * 2 matrix of double-precision floating-point numbers.
+ //! From GLSL 4.00.8 specification, section 4.1 Basic Types.
+ //! \ingroup core_types
+ typedef detail::tmat4x2<double> dmat4x2;
+
+ //! 4 * 3 matrix of double-precision floating-point numbers.
+ //! From GLSL 4.00.8 specification, section 4.1 Basic Types.
+ //! \ingroup core_types
+ typedef detail::tmat4x3<double> dmat4x3;
+
+ //! 4 * 4 matrix of double-precision floating-point numbers.
+ //! From GLSL 4.00.8 specification, section 4.1 Basic Types.
+ //! \ingroup core_types
+ typedef detail::tmat4x4<double> dmat4x4;
+
+}//namespace type
+}//namespace core
+}//namespace glm
+
+#endif//glm_core_type
diff --git a/src/glm/core/type_float.hpp b/src/glm/core/type_float.hpp
new file mode 100644
index 0000000..1d96eae
--- /dev/null
+++ b/src/glm/core/type_float.hpp
@@ -0,0 +1,74 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2008-08-22
+// Updated : 2010-02-08
+// Licence : This source is under MIT License
+// File : glm/core/type_float.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_core_type_float
+#define glm_core_type_float
+
+#include "type_half.hpp"
+#include "setup.hpp"
+
+namespace glm
+{
+ namespace detail
+ {
+ GLM_DETAIL_IS_FLOAT(detail::thalf);
+ GLM_DETAIL_IS_FLOAT(float);
+ GLM_DETAIL_IS_FLOAT(double);
+ GLM_DETAIL_IS_FLOAT(long double);
+ }
+ //namespace detail
+
+ namespace core{
+ namespace type{
+
+ namespace precision
+ {
+#ifdef GLM_USE_HALF_SCALAR
+ typedef detail::thalf lowp_float_t;
+#else//GLM_USE_HALF_SCALAR
+ typedef float lowp_float_t;
+#endif//GLM_USE_HALF_SCALAR
+ typedef float mediump_float_t;
+ typedef double highp_float_t;
+
+ //! Low precision floating-point numbers.
+ //! There is no guarantee on the actual precision.
+ //! From GLSL 1.30.8 specification
+ //! \ingroup core_precision
+ typedef lowp_float_t lowp_float;
+ //! Medium precision floating-point numbers.
+ //! There is no guarantee on the actual precision.
+ //! From GLSL 1.30.8 specification
+ //! \ingroup core_precision
+ typedef mediump_float_t mediump_float;
+ //! High precision floating-point numbers.
+ //! There is no guarantee on the actual precision.
+ //! From GLSL 1.30.8 specification
+ //! \ingroup core_precision
+ typedef highp_float_t highp_float;
+ }
+ //namespace precision
+
+#if(!defined(GLM_PRECISION_HIGHP_FLOAT) && !defined(GLM_PRECISION_MEDIUMP_FLOAT) && !defined(GLM_PRECISION_LOWP_FLOAT))
+ typedef precision::mediump_float float_t;
+#elif(defined(GLM_PRECISION_HIGHP_FLOAT) && !defined(GLM_PRECISION_MEDIUMP_FLOAT) && !defined(GLM_PRECISION_LOWP_FLOAT))
+ typedef precision::highp_float float_t;
+#elif(!defined(GLM_PRECISION_HIGHP_FLOAT) && defined(GLM_PRECISION_MEDIUMP_FLOAT) && !defined(GLM_PRECISION_LOWP_FLOAT))
+ typedef precision::mediump_float float_t;
+#elif(!defined(GLM_PRECISION_HIGHP_FLOAT) && !defined(GLM_PRECISION_MEDIUMP_FLOAT) && defined(GLM_PRECISION_LOWP_FLOAT))
+ typedef precision::lowp_float float_t;
+#else
+# error "GLM error: multiple default precision requested for floating-point types"
+#endif
+
+ }//namespace type
+ }//namespace core
+}//namespace glm
+
+#endif//glm_core_type_float
diff --git a/src/glm/core/type_gentype.hpp b/src/glm/core/type_gentype.hpp
new file mode 100644
index 0000000..3b59b2c
--- /dev/null
+++ b/src/glm/core/type_gentype.hpp
@@ -0,0 +1,150 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2008-10-05
+// Updated : 2010-01-26
+// Licence : This source is under MIT License
+// File : glm/core/type_gentype.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_core_type_gentype
+#define glm_core_type_gentype
+
+#include "type_size.hpp"
+
+namespace glm
+{
+ enum profile
+ {
+ nice,
+ fast,
+ simd
+ };
+
+namespace detail
+{
+ template
+ <
+ typename VALTYPE,
+ template <typename> class TYPE
+ >
+ struct genType
+ {
+ public:
+ enum ctor{null};
+
+ typedef VALTYPE value_type;
+ typedef VALTYPE & value_reference;
+ typedef VALTYPE * value_pointer;
+ typedef VALTYPE const * value_const_pointer;
+ typedef TYPE<bool> bool_type;
+
+ typedef sizeType size_type;
+ static bool is_vector();
+ static bool is_matrix();
+
+ typedef TYPE<VALTYPE> type;
+ typedef TYPE<VALTYPE> * pointer;
+ typedef TYPE<VALTYPE> const * const_pointer;
+ typedef TYPE<VALTYPE> const * const const_pointer_const;
+ typedef TYPE<VALTYPE> * const pointer_const;
+ typedef TYPE<VALTYPE> & reference;
+ typedef TYPE<VALTYPE> const & const_reference;
+ typedef TYPE<VALTYPE> const & param_type;
+
+ //////////////////////////////////////
+ // Address (Implementation details)
+
+ value_const_pointer value_address() const{return value_pointer(this);}
+ value_pointer value_address(){return value_pointer(this);}
+
+ //protected:
+ // enum kind
+ // {
+ // GEN_TYPE,
+ // VEC_TYPE,
+ // MAT_TYPE
+ // };
+
+ // typedef typename TYPE::kind kind;
+ };
+
+ template
+ <
+ typename VALTYPE,
+ template <typename> class TYPE
+ >
+ bool genType<VALTYPE, TYPE>::is_vector()
+ {
+ return true;
+ }
+/*
+ template <typename valTypeT, unsigned int colT, unsigned int rowT, profile proT = nice>
+ class base
+ {
+ public:
+ //////////////////////////////////////
+ // Traits
+
+ typedef sizeType size_type;
+ typedef valTypeT value_type;
+
+ typedef base<value_type, colT, rowT> class_type;
+
+ typedef base<bool, colT, rowT> bool_type;
+ typedef base<value_type, rowT, 1> col_type;
+ typedef base<value_type, colT, 1> row_type;
+ typedef base<value_type, rowT, colT> transpose_type;
+
+ static size_type col_size();
+ static size_type row_size();
+ static size_type value_size();
+ static bool is_scalar();
+ static bool is_vector();
+ static bool is_matrix();
+
+ private:
+ // Data
+ col_type value[colT];
+
+ public:
+ //////////////////////////////////////
+ // Constructors
+ base();
+ base(class_type const & m);
+
+ explicit base(value_type const & x);
+ explicit base(value_type const * const x);
+ explicit base(col_type const * const x);
+
+ //////////////////////////////////////
+ // Conversions
+ template <typename vU, uint cU, uint rU, profile pU>
+ explicit base(base<vU, cU, rU, pU> const & m);
+
+ //////////////////////////////////////
+ // Accesses
+ col_type& operator[](size_type i);
+ col_type const & operator[](size_type i) const;
+
+ //////////////////////////////////////
+ // Unary updatable operators
+ class_type& operator= (class_type const & x);
+ class_type& operator+= (value_type const & x);
+ class_type& operator+= (class_type const & x);
+ class_type& operator-= (value_type const & x);
+ class_type& operator-= (class_type const & x);
+ class_type& operator*= (value_type const & x);
+ class_type& operator*= (class_type const & x);
+ class_type& operator/= (value_type const & x);
+ class_type& operator/= (class_type const & x);
+ class_type& operator++ ();
+ class_type& operator-- ();
+ };
+*/
+ }//namespace detail
+}//namespace glm
+
+//#include "type_gentype.inl"
+
+#endif//glm_core_type_gentype
diff --git a/src/glm/core/type_gentype.inl b/src/glm/core/type_gentype.inl
new file mode 100644
index 0000000..ab2e18f
--- /dev/null
+++ b/src/glm/core/type_gentype.inl
@@ -0,0 +1,347 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2008-10-05
+// Updated : 2008-10-05
+// Licence : This source is under MIT License
+// File : glm/core/type_gentype.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm{
+namespace detail{
+
+/////////////////////////////////
+// Static functions
+
+template <typename vT, uint cT, uint rT, profile pT>
+typename base<vT, cT, rT, pT>::size_type base<vT, cT, rT, pT>::col_size()
+{
+ return cT;
+}
+
+template <typename vT, uint cT, uint rT, profile pT>
+typename base<vT, cT, rT, pT>::size_type base<vT, cT, rT, pT>::row_size()
+{
+ return rT;
+}
+
+template <typename vT, uint cT, uint rT, profile pT>
+typename base<vT, cT, rT, pT>::size_type base<vT, cT, rT, pT>::value_size()
+{
+ return rT * cT;
+}
+
+template <typename vT, uint cT, uint rT, profile pT>
+bool base<vT, cT, rT, pT>::is_scalar()
+{
+ return rT == 1 && cT == 1;
+}
+
+template <typename vT, uint cT, uint rT, profile pT>
+bool base<vT, cT, rT, pT>::is_vector()
+{
+ return rT == 1;
+}
+
+template <typename vT, uint cT, uint rT, profile pT>
+bool base<vT, cT, rT, pT>::is_matrix()
+{
+ return rT != 1;
+}
+
+/////////////////////////////////
+// Constructor
+
+template <typename vT, uint cT, uint rT, profile pT>
+base<vT, cT, rT, pT>::base()
+{
+ memset(&this->value, 0, cT * rT * sizeof(vT));
+}
+
+template <typename vT, uint cT, uint rT, profile pT>
+base<vT, cT, rT, pT>::base
+(
+ typename base<vT, cT, rT, pT>::class_type const & m
+)
+{
+ for
+ (
+ typename genType<vT, cT, rT, pT>::size_type i = typename base<vT, cT, rT, pT>::size_type(0);
+ i < base<vT, cT, rT, pT>::col_size();
+ ++i
+ )
+ {
+ this->value[i] = m[i];
+ }
+}
+
+template <typename vT, uint cT, uint rT, profile pT>
+base<vT, cT, rT, pT>::base
+(
+ typename base<vT, cT, rT, pT>::value_type const & x
+)
+{
+ if(rT == 1) // vector
+ {
+ for
+ (
+ typename base<vT, cT, rT, pT>::size_type i = typename base<vT, cT, rT, pT>::size_type(0);
+ i < base<vT, cT, rT, pT>::col_size();
+ ++i
+ )
+ {
+ this->value[i][rT] = x;
+ }
+ }
+ else // matrix
+ {
+ memset(&this->value, 0, cT * rT * sizeof(vT));
+
+ typename base<vT, cT, rT, pT>::size_type stop = cT < rT ? cT : rT;
+
+ for
+ (
+ typename base<vT, cT, rT, pT>::size_type i = typename base<vT, cT, rT, pT>::size_type(0);
+ i < stop;
+ ++i
+ )
+ {
+ this->value[i][i] = x;
+ }
+ }
+}
+
+template <typename vT, uint cT, uint rT, profile pT>
+base<vT, cT, rT, pT>::base
+(
+ typename base<vT, cT, rT, pT>::value_type const * const x
+)
+{
+ memcpy(&this->value, &x.value, cT * rT * sizeof(vT));
+}
+
+template <typename vT, uint cT, uint rT, profile pT>
+base<vT, cT, rT, pT>::base
+(
+ typename base<vT, cT, rT, pT>::col_type const * const x
+)
+{
+ for
+ (
+ typename base<vT, cT, rT, pT>::size_type i = typename base<vT, cT, rT, pT>::size_type(0);
+ i < base<vT, cT, rT, pT>::col_size();
+ ++i
+ )
+ {
+ this->value[i] = x[i];
+ }
+}
+
+template <typename vT, uint cT, uint rT, profile pT>
+template <typename vU, uint cU, uint rU, profile pU>
+base<vT, cT, rT, pT>::base
+(
+ base<vU, cU, rU, pU> const & m
+)
+{
+ for
+ (
+ typename base<vT, cT, rT, pT>::size_type i = typename base<vT, cT, rT, pT>::size_type(0);
+ i < base<vT, cT, rT, pT>::col_size();
+ ++i
+ )
+ {
+ this->value[i] = base<vT, cT, rT, pT>(m[i]);
+ }
+}
+
+//////////////////////////////////////
+// Accesses
+
+template <typename vT, uint cT, uint rT, profile pT>
+typename base<vT, cT, rT, pT>::col_type& base<vT, cT, rT, pT>::operator[]
+(
+ typename base<vT, cT, rT, pT>::size_type i
+)
+{
+ return this->value[i];
+}
+
+template <typename vT, uint cT, uint rT, profile pT>
+typename base<vT, cT, rT, pT>::col_type const & base<vT, cT, rT, pT>::operator[]
+(
+ typename base<vT, cT, rT, pT>::size_type i
+) const
+{
+ return this->value[i];
+}
+
+//////////////////////////////////////
+// Unary updatable operators
+
+template <typename vT, uint cT, uint rT, profile pT>
+typename base<vT, cT, rT, pT>::class_type& base<vT, cT, rT, pT>::operator=
+(
+ typename base<vT, cT, rT, pT>::class_type const & x
+)
+{
+ memcpy(&this->value, &x.value, cT * rT * sizeof(vT));
+ return *this;
+}
+
+template <typename vT, uint cT, uint rT, profile pT>
+typename base<vT, cT, rT, pT>::class_type& base<vT, cT, rT, pT>::operator+=
+(
+ typename base<vT, cT, rT, pT>::value_type const & x
+)
+{
+ typename base<vT, cT, rT, pT>::size_type stop_col = x.col_size();
+ typename base<vT, cT, rT, pT>::size_type stop_row = x.row_size();
+
+ for(typename base<vT, cT, rT, pT>::size_type j = 0; j < stop_col; ++j)
+ for(typename base<vT, cT, rT, pT>::size_type i = 0; i < stop_row; ++i)
+ this->value[j][i] += x;
+
+ return *this;
+}
+
+template <typename vT, uint cT, uint rT, profile pT>
+typename base<vT, cT, rT, pT>::class_type& base<vT, cT, rT, pT>::operator+=
+(
+ typename base<vT, cT, rT, pT>::class_type const & x
+)
+{
+ typename base<vT, cT, rT, pT>::size_type stop_col = x.col_size();
+ typename base<vT, cT, rT, pT>::size_type stop_row = x.row_size();
+
+ for(typename base<vT, cT, rT, pT>::size_type j = 0; j < stop_col; ++j)
+ for(typename base<vT, cT, rT, pT>::size_type i = 0; i < stop_row; ++i)
+ this->value[j][i] += x[j][i];
+
+ return *this;
+}
+
+template <typename vT, uint cT, uint rT, profile pT>
+typename base<vT, cT, rT, pT>::class_type& base<vT, cT, rT, pT>::operator-=
+(
+ typename base<vT, cT, rT, pT>::value_type const & x
+)
+{
+ typename base<vT, cT, rT, pT>::size_type stop_col = x.col_size();
+ typename base<vT, cT, rT, pT>::size_type stop_row = x.row_size();
+
+ for(typename base<vT, cT, rT, pT>::size_type j = 0; j < stop_col; ++j)
+ for(typename base<vT, cT, rT, pT>::size_type i = 0; i < stop_row; ++i)
+ this->value[j][i] -= x;
+
+ return *this;
+}
+
+template <typename vT, uint cT, uint rT, profile pT>
+typename base<vT, cT, rT, pT>::class_type& base<vT, cT, rT, pT>::operator-=
+(
+ typename base<vT, cT, rT, pT>::class_type const & x
+)
+{
+ typename base<vT, cT, rT, pT>::size_type stop_col = x.col_size();
+ typename base<vT, cT, rT, pT>::size_type stop_row = x.row_size();
+
+ for(typename base<vT, cT, rT, pT>::size_type j = 0; j < stop_col; ++j)
+ for(typename base<vT, cT, rT, pT>::size_type i = 0; i < stop_row; ++i)
+ this->value[j][i] -= x[j][i];
+
+ return *this;
+}
+
+template <typename vT, uint cT, uint rT, profile pT>
+typename base<vT, cT, rT, pT>::class_type& base<vT, cT, rT, pT>::operator*=
+(
+ typename base<vT, cT, rT, pT>::value_type const & x
+)
+{
+ typename base<vT, cT, rT, pT>::size_type stop_col = x.col_size();
+ typename base<vT, cT, rT, pT>::size_type stop_row = x.row_size();
+
+ for(typename base<vT, cT, rT, pT>::size_type j = 0; j < stop_col; ++j)
+ for(typename base<vT, cT, rT, pT>::size_type i = 0; i < stop_row; ++i)
+ this->value[j][i] *= x;
+
+ return *this;
+}
+
+template <typename vT, uint cT, uint rT, profile pT>
+typename base<vT, cT, rT, pT>::class_type& base<vT, cT, rT, pT>::operator*=
+(
+ typename base<vT, cT, rT, pT>::class_type const & x
+)
+{
+ typename base<vT, cT, rT, pT>::size_type stop_col = x.col_size();
+ typename base<vT, cT, rT, pT>::size_type stop_row = x.row_size();
+
+ for(typename base<vT, cT, rT, pT>::size_type j = 0; j < stop_col; ++j)
+ for(typename base<vT, cT, rT, pT>::size_type i = 0; i < stop_row; ++i)
+ this->value[j][i] *= x[j][i];
+
+ return *this;
+}
+
+template <typename vT, uint cT, uint rT, profile pT>
+typename base<vT, cT, rT, pT>::class_type& base<vT, cT, rT, pT>::operator/=
+(
+ typename base<vT, cT, rT, pT>::value_type const & x
+)
+{
+ typename base<vT, cT, rT, pT>::size_type stop_col = x.col_size();
+ typename base<vT, cT, rT, pT>::size_type stop_row = x.row_size();
+
+ for(typename base<vT, cT, rT, pT>::size_type j = 0; j < stop_col; ++j)
+ for(typename base<vT, cT, rT, pT>::size_type i = 0; i < stop_row; ++i)
+ this->value[j][i] /= x;
+
+ return *this;
+}
+
+template <typename vT, uint cT, uint rT, profile pT>
+typename base<vT, cT, rT, pT>::class_type& base<vT, cT, rT, pT>::operator/=
+(
+ typename base<vT, cT, rT, pT>::class_type const & x
+)
+{
+ typename base<vT, cT, rT, pT>::size_type stop_col = x.col_size();
+ typename base<vT, cT, rT, pT>::size_type stop_row = x.row_size();
+
+ for(typename base<vT, cT, rT, pT>::size_type j = 0; j < stop_col; ++j)
+ for(typename base<vT, cT, rT, pT>::size_type i = 0; i < stop_row; ++i)
+ this->value[j][i] /= x[j][i];
+
+ return *this;
+}
+
+template <typename vT, uint cT, uint rT, profile pT>
+typename base<vT, cT, rT, pT>::class_type& base<vT, cT, rT, pT>::operator++ ()
+{
+ typename base<vT, cT, rT, pT>::size_type stop_col = col_size();
+ typename base<vT, cT, rT, pT>::size_type stop_row = row_size();
+
+ for(typename base<vT, cT, rT, pT>::size_type j = 0; j < stop_col; ++j)
+ for(typename base<vT, cT, rT, pT>::size_type i = 0; i < stop_row; ++i)
+ ++this->value[j][i];
+
+ return *this;
+}
+
+template <typename vT, uint cT, uint rT, profile pT>
+typename base<vT, cT, rT, pT>::class_type& base<vT, cT, rT, pT>::operator-- ()
+{
+ typename base<vT, cT, rT, pT>::size_type stop_col = col_size();
+ typename base<vT, cT, rT, pT>::size_type stop_row = row_size();
+
+ for(typename base<vT, cT, rT, pT>::size_type j = 0; j < stop_col; ++j)
+ for(typename base<vT, cT, rT, pT>::size_type i = 0; i < stop_row; ++i)
+ --this->value[j][i];
+
+ return *this;
+}
+
+} //namespace detail
+} //namespace glm
diff --git a/src/glm/core/type_half.hpp b/src/glm/core/type_half.hpp
new file mode 100644
index 0000000..b6bcd48
--- /dev/null
+++ b/src/glm/core/type_half.hpp
@@ -0,0 +1,78 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2008-08-17
+// Updated : 2010-02-17
+// Licence : This source is under MIT License
+// File : glm/core/type_half.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_core_type_half
+#define glm_core_type_half
+
+#include <cstdlib>
+
+namespace glm{
+namespace detail
+{
+ typedef short hdata;
+
+ float toFloat32(hdata value);
+ hdata toFloat16(float const & value);
+
+ ///16-bit floating point type.
+ /// \ingroup gtc_half_float
+ class thalf
+ {
+ public:
+ // Constructors
+ GLM_FUNC_DECL thalf();
+ GLM_FUNC_DECL thalf(thalf const & s);
+
+ template <typename U>
+ GLM_FUNC_DECL explicit thalf(U const & s);
+
+ // Cast
+ //operator float();
+ GLM_FUNC_DECL operator float() const;
+ //operator double();
+ //operator double() const;
+
+ // Unary updatable operators
+ GLM_FUNC_DECL thalf& operator= (thalf const & s);
+ GLM_FUNC_DECL thalf& operator+=(thalf const & s);
+ GLM_FUNC_DECL thalf& operator-=(thalf const & s);
+ GLM_FUNC_DECL thalf& operator*=(thalf const & s);
+ GLM_FUNC_DECL thalf& operator/=(thalf const & s);
+ GLM_FUNC_DECL thalf& operator++();
+ GLM_FUNC_DECL thalf& operator--();
+
+ GLM_FUNC_DECL float toFloat() const{return toFloat32(data);}
+
+ GLM_FUNC_DECL hdata _data() const{return data;}
+
+ private:
+ hdata data;
+ };
+
+ thalf operator+ (thalf const & s1, thalf const & s2);
+
+ thalf operator- (thalf const & s1, thalf const & s2);
+
+ thalf operator* (thalf const & s1, thalf const & s2);
+
+ thalf operator/ (thalf const & s1, thalf const & s2);
+
+ // Unary constant operators
+ thalf operator- (thalf const & s);
+
+ thalf operator-- (thalf const & s, int);
+
+ thalf operator++ (thalf const & s, int);
+
+}//namespace detail
+}//namespace glm
+
+#include "type_half.inl"
+
+#endif//glm_core_type_half
diff --git a/src/glm/core/type_half.inl b/src/glm/core/type_half.inl
new file mode 100644
index 0000000..c98cd5b
--- /dev/null
+++ b/src/glm/core/type_half.inl
@@ -0,0 +1,357 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2008-08-17
+// Updated : 2009-11-12
+// Licence : This source is under MIT License
+// File : glm/core/type_half.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Copyright:
+// This half implementation is based on OpenEXR which is Copyright (c) 2002,
+// Industrial Light & Magic, a division of Lucas Digital Ltd. LLC
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#include "_detail.hpp"
+
+namespace glm{
+namespace detail
+{
+ GLM_FUNC_QUALIFIER float overflow()
+ {
+ volatile float f = 1e10;
+
+ for(int i = 0; i < 10; ++i)
+ f *= f; // this will overflow before
+ // the forloop terminates
+ return f;
+ }
+
+ GLM_FUNC_QUALIFIER float toFloat32(hdata value)
+ {
+ int s = (value >> 15) & 0x00000001;
+ int e = (value >> 10) & 0x0000001f;
+ int m = value & 0x000003ff;
+
+ if(e == 0)
+ {
+ if(m == 0)
+ {
+ //
+ // Plus or minus zero
+ //
+
+ detail::uif result;
+ result.i = s << 31;
+ return result.f;
+ }
+ else
+ {
+ //
+ // Denormalized number -- renormalize it
+ //
+
+ while(!(m & 0x00000400))
+ {
+ m <<= 1;
+ e -= 1;
+ }
+
+ e += 1;
+ m &= ~0x00000400;
+ }
+ }
+ else if(e == 31)
+ {
+ if(m == 0)
+ {
+ //
+ // Positive or negative infinity
+ //
+
+ uif result;
+ result.i = (s << 31) | 0x7f800000;
+ return result.f;
+ }
+ else
+ {
+ //
+ // Nan -- preserve sign and significand bits
+ //
+
+ uif result;
+ result.i = (s << 31) | 0x7f800000 | (m << 13);
+ return result.f;
+ }
+ }
+
+ //
+ // Normalized number
+ //
+
+ e = e + (127 - 15);
+ m = m << 13;
+
+ //
+ // Assemble s, e and m.
+ //
+
+ uif Result;
+ Result.i = (s << 31) | (e << 23) | m;
+ return Result.f;
+ }
+
+ GLM_FUNC_QUALIFIER hdata toFloat16(float const & f)
+ {
+ uif Entry;
+ Entry.f = f;
+ int i = Entry.i;
+
+ //
+ // Our floating point number, f, is represented by the bit
+ // pattern in integer i. Disassemble that bit pattern into
+ // the sign, s, the exponent, e, and the significand, m.
+ // Shift s into the position where it will go in in the
+ // resulting half number.
+ // Adjust e, accounting for the different exponent bias
+ // of float and half (127 versus 15).
+ //
+
+ register int s = (i >> 16) & 0x00008000;
+ register int e = ((i >> 23) & 0x000000ff) - (127 - 15);
+ register int m = i & 0x007fffff;
+
+ //
+ // Now reassemble s, e and m into a half:
+ //
+
+ if(e <= 0)
+ {
+ if(e < -10)
+ {
+ //
+ // E is less than -10. The absolute value of f is
+ // less than half_MIN (f may be a small normalized
+ // float, a denormalized float or a zero).
+ //
+ // We convert f to a _halfGTX zero.
+ //
+
+ return 0;
+ }
+
+ //
+ // E is between -10 and 0. F is a normalized float,
+ // whose magnitude is less than __half_NRM_MIN.
+ //
+ // We convert f to a denormalized _halfGTX.
+ //
+
+ m = (m | 0x00800000) >> (1 - e);
+
+ //
+ // Round to nearest, round "0.5" up.
+ //
+ // Rounding may cause the significand to overflow and make
+ // our number normalized. Because of the way a half's bits
+ // are laid out, we don't have to treat this case separately;
+ // the code below will handle it correctly.
+ //
+
+ if(m & 0x00001000)
+ m += 0x00002000;
+
+ //
+ // Assemble the _halfGTX from s, e (zero) and m.
+ //
+
+ return hdata(s | (m >> 13));
+ }
+ else if(e == 0xff - (127 - 15))
+ {
+ if(m == 0)
+ {
+ //
+ // F is an infinity; convert f to a half
+ // infinity with the same sign as f.
+ //
+
+ return hdata(s | 0x7c00);
+ }
+ else
+ {
+ //
+ // F is a NAN; we produce a half NAN that preserves
+ // the sign bit and the 10 leftmost bits of the
+ // significand of f, with one exception: If the 10
+ // leftmost bits are all zero, the NAN would turn
+ // into an infinity, so we have to set at least one
+ // bit in the significand.
+ //
+
+ m >>= 13;
+
+ return hdata(s | 0x7c00 | m | (m == 0));
+ }
+ }
+ else
+ {
+ //
+ // E is greater than zero. F is a normalized float.
+ // We try to convert f to a normalized half.
+ //
+
+ //
+ // Round to nearest, round "0.5" up
+ //
+
+ if(m & 0x00001000)
+ {
+ m += 0x00002000;
+
+ if(m & 0x00800000)
+ {
+ m = 0; // overflow in significand,
+ e += 1; // adjust exponent
+ }
+ }
+
+ //
+ // Handle exponent overflow
+ //
+
+ if (e > 30)
+ {
+ overflow(); // Cause a hardware floating point overflow;
+
+ return hdata(s | 0x7c00);
+ // if this returns, the half becomes an
+ } // infinity with the same sign as f.
+
+ //
+ // Assemble the half from s, e and m.
+ //
+
+ return hdata(s | (e << 10) | (m >> 13));
+ }
+ }
+
+ GLM_FUNC_QUALIFIER thalf::thalf() :
+ data(0)
+ {}
+
+ GLM_FUNC_QUALIFIER thalf::thalf(thalf const & s) :
+ data(s.data)
+ {}
+
+ template <typename U>
+ GLM_FUNC_QUALIFIER thalf::thalf(U const & s) :
+ data(toFloat16(float(s)))
+ {}
+
+ // Cast
+ //GLM_FUNC_QUALIFIER half::operator float()
+ //{
+ // return toFloat();
+ //}
+
+ GLM_FUNC_QUALIFIER thalf::operator float() const
+ {
+ return toFloat32(this->data);
+ }
+
+ //GLM_FUNC_QUALIFIER half::operator double()
+ //{
+ // return double(toFloat());
+ //}
+
+ //GLM_FUNC_QUALIFIER half::operator double() const
+ //{
+ // return double(toFloat());
+ //}
+
+ // Unary updatable operators
+ GLM_FUNC_QUALIFIER thalf& thalf::operator= (thalf const & s)
+ {
+ data = s.data;
+ return *this;
+ }
+
+ GLM_FUNC_QUALIFIER thalf& thalf::operator+=(thalf const & s)
+ {
+ data = toFloat16(toFloat32(data) + toFloat32(s.data));
+ return *this;
+ }
+
+ GLM_FUNC_QUALIFIER thalf& thalf::operator-=(thalf const & s)
+ {
+ data = toFloat16(toFloat32(data) - toFloat32(s.data));
+ return *this;
+ }
+
+ GLM_FUNC_QUALIFIER thalf& thalf::operator*=(thalf const & s)
+ {
+ data = toFloat16(toFloat32(data) * toFloat32(s.data));
+ return *this;
+ }
+
+ GLM_FUNC_QUALIFIER thalf& thalf::operator/=(thalf const & s)
+ {
+ data = toFloat16(toFloat32(data) / toFloat32(s.data));
+ return *this;
+ }
+
+ GLM_FUNC_QUALIFIER thalf& thalf::operator++()
+ {
+ float Casted = toFloat32(data);
+ data = toFloat16(++Casted);
+ return *this;
+ }
+
+ GLM_FUNC_QUALIFIER thalf& thalf::operator--()
+ {
+ float Casted = toFloat32(data);
+ data = toFloat16(--Casted);
+ return *this;
+ }
+
+ //////////////////////////////////////
+ // Binary arithmetic operators
+
+ GLM_FUNC_QUALIFIER detail::thalf operator+ (detail::thalf const & s1, detail::thalf const & s2)
+ {
+ return detail::thalf(float(s1) + float(s2));
+ }
+
+ GLM_FUNC_QUALIFIER detail::thalf operator- (detail::thalf const & s1, detail::thalf const & s2)
+ {
+ return detail::thalf(float(s1) - float(s2));
+ }
+
+ GLM_FUNC_QUALIFIER detail::thalf operator* (detail::thalf const & s1, detail::thalf const & s2)
+ {
+ return detail::thalf(float(s1) * float(s2));
+ }
+
+ GLM_FUNC_QUALIFIER detail::thalf operator/ (detail::thalf const & s1, detail::thalf const & s2)
+ {
+ return detail::thalf(float(s1) / float(s2));
+ }
+
+ // Unary constant operators
+ GLM_FUNC_QUALIFIER detail::thalf operator- (detail::thalf const & s)
+ {
+ return detail::thalf(-float(s));
+ }
+
+ GLM_FUNC_QUALIFIER detail::thalf operator-- (detail::thalf const & s, int)
+ {
+ return detail::thalf(float(s) - 1.0f);
+ }
+
+ GLM_FUNC_QUALIFIER detail::thalf operator++ (detail::thalf const & s, int)
+ {
+ return detail::thalf(float(s) + 1.0f);
+ }
+
+}//namespace detail
+}//namespace glm
diff --git a/src/glm/core/type_int.hpp b/src/glm/core/type_int.hpp
new file mode 100644
index 0000000..eda4bed
--- /dev/null
+++ b/src/glm/core/type_int.hpp
@@ -0,0 +1,109 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2008-08-22
+// Updated : 2008-09-17
+// Licence : This source is under MIT License
+// File : glm/core/type_int.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_core_type_int
+#define glm_core_type_int
+
+#include "setup.hpp"
+#include "_detail.hpp"
+
+namespace glm{
+namespace detail
+{
+ typedef signed short lowp_int_t;
+ typedef signed int mediump_int_t;
+ typedef sint64 highp_int_t;
+
+ typedef unsigned short lowp_uint_t;
+ typedef unsigned int mediump_uint_t;
+ typedef uint64 highp_uint_t;
+
+ GLM_DETAIL_IS_INT(signed char);
+ GLM_DETAIL_IS_INT(signed short);
+ GLM_DETAIL_IS_INT(signed int);
+ GLM_DETAIL_IS_INT(signed long);
+ GLM_DETAIL_IS_INT(highp_int_t);
+
+ GLM_DETAIL_IS_UINT(unsigned char);
+ GLM_DETAIL_IS_UINT(unsigned short);
+ GLM_DETAIL_IS_UINT(unsigned int);
+ GLM_DETAIL_IS_UINT(unsigned long);
+ GLM_DETAIL_IS_UINT(highp_uint_t);
+}//namespace detail
+
+namespace core{
+namespace type{
+namespace precision //!< Namespace for precision stuff.
+{
+ //! Low precision signed integer.
+ //! There is no guarantee on the actual precision.
+ //! From GLSL 1.30.8 specification.
+ //! \ingroup core_precision
+ typedef detail::lowp_int_t lowp_int;
+ //! Medium precision signed integer.
+ //! There is no guarantee on the actual precision.
+ //! From GLSL 1.30.8 specification.
+ //! \ingroup core_precision
+ typedef detail::mediump_int_t mediump_int;
+ //! High precision signed integer.
+ //! There is no guarantee on the actual precision.
+ //! From GLSL 1.30.8 specification.
+ //! \ingroup core_precision
+ typedef detail::highp_int_t highp_int;
+
+ //! Low precision unsigned integer.
+ //! There is no guarantee on the actual precision.
+ //! From GLSL 1.30.8 specification.
+ //! \ingroup core_precision
+ typedef detail::lowp_uint_t lowp_uint;
+ //! Medium precision unsigned integer.
+ //! There is no guarantee on the actual precision.
+ //! From GLSL 1.30.8 specification.
+ //! \ingroup core_precision
+ typedef detail::mediump_uint_t mediump_uint;
+ //! High precision unsigned integer.
+ //! There is no guarantee on the actual precision.
+ //! From GLSL 1.30.8 specification.
+ //! \ingroup core_precision
+ typedef detail::highp_uint_t highp_uint;
+}//namespace precision
+
+#if(!defined(GLM_PRECISION_HIGHP_INT) && !defined(GLM_PRECISION_MEDIUMP_INT) && !defined(GLM_PRECISION_LOWP_INT))
+ typedef precision::mediump_int int_t;
+#elif(defined(GLM_PRECISION_HIGHP_INT) && !defined(GLM_PRECISION_MEDIUMP_INT) && !defined(GLM_PRECISION_LOWP_INT))
+ typedef precision::highp_int int_t;
+#elif(!defined(GLM_PRECISION_HIGHP_INT) && defined(GLM_PRECISION_MEDIUMP_INT) && !defined(GLM_PRECISION_LOWP_INT))
+ typedef precision::mediump_int int_t;
+#elif(!defined(GLM_PRECISION_HIGHP_INT) && !defined(GLM_PRECISION_MEDIUMP_INT) && defined(GLM_PRECISION_LOWP_INT))
+ typedef precision::lowp_int int_t;
+#else
+# error "GLM error: multiple default precision requested for signed interger types"
+#endif
+
+#if(!defined(GLM_PRECISION_HIGHP_UINT) && !defined(GLM_PRECISION_MEDIUMP_UINT) && !defined(GLM_PRECISION_LOWP_UINT))
+ typedef precision::mediump_uint uint_t;
+#elif(defined(GLM_PRECISION_HIGHP_UINT) && !defined(GLM_PRECISION_MEDIUMP_UINT) && !defined(GLM_PRECISION_LOWP_UINT))
+ typedef precision::highp_uint uint_t;
+#elif(!defined(GLM_PRECISION_HIGHP_UINT) && defined(GLM_PRECISION_MEDIUMP_UINT) && !defined(GLM_PRECISION_LOWP_UINT))
+ typedef precision::mediump_uint uint_t;
+#elif(!defined(GLM_PRECISION_HIGHP_UINT) && !defined(GLM_PRECISION_MEDIUMP_UINT) && defined(GLM_PRECISION_LOWP_UINT))
+ typedef precision::lowp_uint uint_t;
+#else
+# error "GLM error: multiple default precision requested for unsigned interger types"
+#endif
+
+ //! Unsigned integer.
+ //! From GLSL 1.30.8 specification section 4.1.3 Integers.
+ typedef uint_t uint;
+
+}//namespace type
+}//namespace core
+}//namespace glm
+
+#endif//glm_core_type_int
diff --git a/src/glm/core/type_mat.hpp b/src/glm/core/type_mat.hpp
new file mode 100644
index 0000000..027e0eb
--- /dev/null
+++ b/src/glm/core/type_mat.hpp
@@ -0,0 +1,56 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2010-01-26
+// Updated : 2010-01-26
+// Licence : This source is under MIT License
+// File : glm/core/type_mat.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_core_type_mat
+#define glm_core_type_mat
+
+#include "type_gentype.hpp"
+
+namespace glm{
+namespace detail
+{
+ //template
+ //<
+ // typename T,
+ // template <typename> class C,
+ // template <typename> class R
+ //>
+ //struct matType
+ //{
+ // enum ctor{null};
+ // typedef T value_type;
+ // typedef std::size_t size_type;
+ // typedef C<T> col_type;
+ // typedef R<T> row_type;
+ // static size_type const col_size;
+ // static size_type const row_size;
+ //};
+
+ //template
+ //<
+ // typename T,
+ // template <typename> class C,
+ // template <typename> class R
+ //>
+ //typename matType<T, C, R>::size_type const
+ //matType<T, C, R>::col_size = matType<T, C, R>::col_type::value_size;
+
+ //template
+ //<
+ // typename T,
+ // template <typename> class C,
+ // template <typename> class R
+ //>
+ //typename matType<T, C, R>::size_type const
+ //matType<T, C, R>::row_size = matType<T, C, R>::row_type::value_size;
+
+}//namespace detail
+}//namespace glm
+
+#endif//glm_core_type_mat
diff --git a/src/glm/core/type_mat.inl b/src/glm/core/type_mat.inl
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/glm/core/type_mat.inl
diff --git a/src/glm/core/type_mat2x2.hpp b/src/glm/core/type_mat2x2.hpp
new file mode 100644
index 0000000..74f5295
--- /dev/null
+++ b/src/glm/core/type_mat2x2.hpp
@@ -0,0 +1,281 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2005-01-27
+// Updated : 2010-02-11
+// Licence : This source is under MIT License
+// File : glm/core/type_mat2x2.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_core_type_mat2x2
+#define glm_core_type_mat2x2
+
+#include "type_mat.hpp"
+
+namespace glm{
+namespace detail
+{
+ template <typename T> struct tvec1;
+ template <typename T> struct tvec2;
+ template <typename T> struct tvec3;
+ template <typename T> struct tvec4;
+ template <typename T> struct tmat2x2;
+ template <typename T> struct tmat2x3;
+ template <typename T> struct tmat2x4;
+ template <typename T> struct tmat3x2;
+ template <typename T> struct tmat3x3;
+ template <typename T> struct tmat3x4;
+ template <typename T> struct tmat4x2;
+ template <typename T> struct tmat4x3;
+ template <typename T> struct tmat4x4;
+
+ //! \brief Template for 2 * 2 matrix of floating-point numbers.
+ //! \ingroup core_template
+ template <typename T>
+ struct tmat2x2
+ {
+ enum ctor{null};
+ typedef T value_type;
+ typedef std::size_t size_type;
+ typedef tvec2<T> col_type;
+ typedef tvec2<T> row_type;
+ static GLM_FUNC_DECL size_type col_size();
+ static GLM_FUNC_DECL size_type row_size();
+
+ typedef tmat2x2<T> type;
+ typedef tmat2x2<T> transpose_type;
+
+ public:
+ // Implementation detail
+ GLM_FUNC_DECL tmat2x2<T> _inverse() const;
+
+ private:
+ //////////////////////////////////////
+ // Data
+ col_type value[2];
+
+ public:
+ //////////////////////////////////////
+ // Constructors
+ GLM_FUNC_DECL tmat2x2();
+ GLM_FUNC_DECL tmat2x2(
+ tmat2x2 const & m);
+
+ GLM_FUNC_DECL explicit tmat2x2(
+ ctor Null);
+ GLM_FUNC_DECL explicit tmat2x2(
+ value_type const & x);
+ GLM_FUNC_DECL explicit tmat2x2(
+ value_type const & x1, value_type const & y1,
+ value_type const & x2, value_type const & y2);
+ GLM_FUNC_DECL explicit tmat2x2(
+ col_type const & v1,
+ col_type const & v2);
+
+ //////////////////////////////////////
+ // Conversions
+ template <typename U>
+ GLM_FUNC_DECL explicit tmat2x2(
+ U const & x);
+
+ template <typename U, typename V, typename M, typename N>
+ GLM_FUNC_DECL explicit tmat2x2(
+ U const & x1, V const & y1,
+ M const & x2, N const & y2);
+
+ template <typename U, typename V>
+ GLM_FUNC_DECL explicit tmat2x2(
+ tvec2<U> const & v1,
+ tvec2<V> const & v2);
+
+ //////////////////////////////////////
+ // Matrix conversions
+ template <typename U>
+ GLM_FUNC_DECL explicit tmat2x2(tmat2x2<U> const & m);
+
+ GLM_FUNC_DECL explicit tmat2x2(tmat3x3<T> const & x);
+ GLM_FUNC_DECL explicit tmat2x2(tmat4x4<T> const & x);
+ GLM_FUNC_DECL explicit tmat2x2(tmat2x3<T> const & x);
+ GLM_FUNC_DECL explicit tmat2x2(tmat3x2<T> const & x);
+ GLM_FUNC_DECL explicit tmat2x2(tmat2x4<T> const & x);
+ GLM_FUNC_DECL explicit tmat2x2(tmat4x2<T> const & x);
+ GLM_FUNC_DECL explicit tmat2x2(tmat3x4<T> const & x);
+ GLM_FUNC_DECL explicit tmat2x2(tmat4x3<T> const & x);
+
+ //////////////////////////////////////
+ // Accesses
+
+ GLM_FUNC_DECL col_type & operator[](size_type i);
+ GLM_FUNC_DECL col_type const & operator[](size_type i) const;
+
+ // Unary updatable operators
+ GLM_FUNC_DECL tmat2x2<T> & operator=(tmat2x2<T> const & m);
+ template <typename U>
+ GLM_FUNC_DECL tmat2x2<T> & operator=(tmat2x2<U> const & m);
+ template <typename U>
+ GLM_FUNC_DECL tmat2x2<T> & operator+=(U const & s);
+ template <typename U>
+ GLM_FUNC_DECL tmat2x2<T> & operator+=(tmat2x2<U> const & m);
+ template <typename U>
+ GLM_FUNC_DECL tmat2x2<T> & operator-=(U const & s);
+ template <typename U>
+ GLM_FUNC_DECL tmat2x2<T> & operator-=(tmat2x2<U> const & m);
+ template <typename U>
+ GLM_FUNC_DECL tmat2x2<T> & operator*=(U const & s);
+ template <typename U>
+ GLM_FUNC_DECL tmat2x2<T> & operator*=(tmat2x2<U> const & m);
+ template <typename U>
+ GLM_FUNC_DECL tmat2x2<T> & operator/=(U const & s);
+ template <typename U>
+ GLM_FUNC_DECL tmat2x2<T> & operator/=(tmat2x2<U> const & m);
+ GLM_FUNC_DECL tmat2x2<T> & operator++();
+ GLM_FUNC_DECL tmat2x2<T> & operator--();
+ };
+
+ // Binary operators
+ template <typename T>
+ tmat2x2<T> operator+ (
+ tmat2x2<T> const & m,
+ typename tmat2x2<T>::value_type const & s);
+
+ template <typename T>
+ tmat2x2<T> operator+ (
+ typename tmat2x2<T>::value_type const & s,
+ tmat2x2<T> const & m);
+
+ template <typename T>
+ tmat2x2<T> operator+ (
+ tmat2x2<T> const & m1,
+ tmat2x2<T> const & m2);
+
+ template <typename T>
+ tmat2x2<T> operator- (
+ tmat2x2<T> const & m,
+ typename tmat2x2<T>::value_type const & s);
+
+ template <typename T>
+ tmat2x2<T> operator- (
+ typename tmat2x2<T>::value_type const & s,
+ tmat2x2<T> const & m);
+
+ template <typename T>
+ tmat2x2<T> operator- (
+ tmat2x2<T> const & m1,
+ tmat2x2<T> const & m2);
+
+ template <typename T>
+ tmat2x2<T> operator* (
+ tmat2x2<T> const & m,
+ typename tmat2x2<T>::value_type const & s);
+
+ template <typename T>
+ tmat2x2<T> operator* (
+ typename tmat2x2<T>::value_type const & s,
+ tmat2x2<T> const & m);
+
+ template <typename T>
+ typename tmat2x2<T>::col_type operator* (
+ tmat2x2<T> const & m,
+ typename tmat2x2<T>::row_type const & v);
+
+ template <typename T>
+ typename tmat2x2<T>::row_type operator* (
+ typename tmat2x2<T>::col_type const & v,
+ tmat2x2<T> const & m);
+
+ template <typename T>
+ tmat2x2<T> operator* (
+ tmat2x2<T> const & m1,
+ tmat2x2<T> const & m2);
+
+ template <typename T>
+ tmat2x2<T> operator/ (
+ tmat2x2<T> const & m,
+ typename tmat2x2<T>::value_type const & s);
+
+ template <typename T>
+ tmat2x2<T> operator/ (
+ typename tmat2x2<T>::value_type const & s,
+ tmat2x2<T> const & m);
+
+ template <typename T>
+ typename tmat2x2<T>::col_type operator/ (
+ tmat2x2<T> const & m,
+ typename tmat2x2<T>::row_type const & v);
+
+ template <typename T>
+ typename tmat2x2<T>::row_type operator/ (
+ typename tmat2x2<T>::col_type const & v,
+ tmat2x2<T> const & m);
+
+ template <typename T>
+ tmat2x2<T> operator/ (
+ tmat2x2<T> const & m1,
+ tmat2x2<T> const & m2);
+
+ // Unary constant operators
+ template <typename T>
+ tmat2x2<T> const operator- (
+ tmat2x2<T> const & m);
+
+ template <typename T>
+ tmat2x2<T> const operator-- (
+ tmat2x2<T> const & m,
+ int);
+
+ template <typename T>
+ tmat2x2<T> const operator++ (
+ tmat2x2<T> const & m,
+ int);
+} //namespace detail
+
+namespace core{
+namespace type{
+namespace precision
+{
+ //! 2 columns of 2 components matrix of low precision floating-point numbers.
+ //! There is no guarantee on the actual precision.
+ //! From GLSL 1.30.8 specification, section 4.1.6 Matrices and section 4.5 Precision and Precision Qualifiers
+ //! \ingroup core_precision
+ typedef detail::tmat2x2<lowp_float> lowp_mat2;
+
+ //! 2 columns of 2 components matrix of medium precision floating-point numbers.
+ //! There is no guarantee on the actual precision.
+ //! From GLSL 1.30.8 specification, section 4.1.6 Matrices and section 4.5 Precision and Precision Qualifiers
+ //! \ingroup core_precision
+ typedef detail::tmat2x2<mediump_float> mediump_mat2;
+
+ //! 2 columns of 2 components matrix of high precision floating-point numbers.
+ //! There is no guarantee on the actual precision.
+ //! From GLSL 1.30.8 specification, section 4.1.6 Matrices and section 4.5 Precision and Precision Qualifiers
+ //! \ingroup core_precision
+ typedef detail::tmat2x2<highp_float> highp_mat2;
+
+ //! 2 columns of 2 components matrix of low precision floating-point numbers.
+ //! There is no guarantee on the actual precision.
+ //! From GLSL 1.30.8 specification, section 4.1.6 Matrices and section 4.5 Precision and Precision Qualifiers
+ //! \ingroup core_precision
+ typedef detail::tmat2x2<lowp_float> lowp_mat2x2;
+
+ //! 2 columns of 2 components matrix of medium precision floating-point numbers.
+ //! There is no guarantee on the actual precision.
+ //! From GLSL 1.30.8 specification, section 4.1.6 Matrices and section 4.5 Precision and Precision Qualifiers
+ //! \ingroup core_precision
+ typedef detail::tmat2x2<mediump_float> mediump_mat2x2;
+
+ //! 2 columns of 2 components matrix of high precision floating-point numbers.
+ //! There is no guarantee on the actual precision.
+ //! From GLSL 1.30.8 specification, section 4.1.6 Matrices and section 4.5 Precision and Precision Qualifiers
+ //! \ingroup core_precision
+ typedef detail::tmat2x2<highp_float> highp_mat2x2;
+
+}//namespace precision
+}//namespace type
+}//namespace core
+}//namespace glm
+
+#ifndef GLM_EXTERNAL_TEMPLATE
+#include "type_mat2x2.inl"
+#endif
+
+#endif //glm_core_type_mat2x2
diff --git a/src/glm/core/type_mat2x2.inl b/src/glm/core/type_mat2x2.inl
new file mode 100644
index 0000000..bdb663d
--- /dev/null
+++ b/src/glm/core/type_mat2x2.inl
@@ -0,0 +1,648 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2005-01-16
+// Updated : 2010-02-11
+// Licence : This source is under MIT License
+// File : glm/core/type_mat2x2.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm{
+namespace detail
+{
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename tmat2x2<T>::size_type tmat2x2<T>::col_size()
+ {
+ return 2;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename tmat2x2<T>::size_type tmat2x2<T>::row_size()
+ {
+ return 2;
+ }
+
+ //////////////////////////////////////
+ // Accesses
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename tmat2x2<T>::col_type &
+ tmat2x2<T>::operator[]
+ (
+ size_type i
+ )
+ {
+ assert(i < this->row_size());
+ return this->value[i];
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename tmat2x2<T>::col_type const &
+ tmat2x2<T>::operator[]
+ (
+ size_type i
+ ) const
+ {
+ assert(i < this->row_size());
+ return this->value[i];
+ }
+
+ //////////////////////////////////////////////////////////////
+ // Constructors
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x2<T>::tmat2x2()
+ {
+ this->value[0] = col_type(1, 0);
+ this->value[1] = col_type(0, 1);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x2<T>::tmat2x2
+ (
+ tmat2x2<T> const & m
+ )
+ {
+ this->value[0] = m.value[0];
+ this->value[1] = m.value[1];
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x2<T>::tmat2x2
+ (
+ ctor
+ )
+ {}
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x2<T>::tmat2x2
+ (
+ value_type const & s
+ )
+ {
+ value_type const Zero(0);
+ this->value[0] = col_type(s, Zero);
+ this->value[1] = col_type(Zero, s);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x2<T>::tmat2x2
+ (
+ value_type const & x0, value_type const & y0,
+ value_type const & x1, value_type const & y1
+ )
+ {
+ this->value[0] = col_type(x0, y0);
+ this->value[1] = col_type(x1, y1);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x2<T>::tmat2x2
+ (
+ col_type const & v0,
+ col_type const & v1
+ )
+ {
+ this->value[0] = v0;
+ this->value[1] = v1;
+ }
+
+ //////////////////////////////////////
+ // Convertion constructors
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_DECL tmat2x2<T>::tmat2x2
+ (
+ U const & s
+ )
+ {
+ value_type const Zero(0);
+ this->value[0] = tvec2<T>(value_type(s), Zero);
+ this->value[1] = tvec2<T>(Zero, value_type(s));
+ }
+
+ template <typename T>
+ template <typename X1, typename Y1, typename X2, typename Y2>
+ GLM_FUNC_DECL tmat2x2<T>::tmat2x2
+ (
+ X1 const & x1, Y1 const & y1,
+ X2 const & x2, Y2 const & y2
+ )
+ {
+ this->value[0] = col_type(value_type(x1), value_type(y1));
+ this->value[1] = col_type(value_type(x2), value_type(y2));
+ }
+
+ template <typename T>
+ template <typename V1, typename V2>
+ GLM_FUNC_DECL tmat2x2<T>::tmat2x2
+ (
+ tvec2<V1> const & v1,
+ tvec2<V2> const & v2
+ )
+ {
+ this->value[0] = col_type(v1);
+ this->value[1] = col_type(v2);
+ }
+
+ //////////////////////////////////////////////////////////////
+ // mat2x2 matrix conversions
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat2x2<T>::tmat2x2
+ (
+ tmat2x2<U> const & m
+ )
+ {
+ this->value[0] = col_type(m[0]);
+ this->value[1] = col_type(m[1]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x2<T>::tmat2x2
+ (
+ tmat3x3<T> const & m
+ )
+ {
+ this->value[0] = col_type(m[0]);
+ this->value[1] = col_type(m[1]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x2<T>::tmat2x2
+ (
+ tmat4x4<T> const & m
+ )
+ {
+ this->value[0] = col_type(m[0]);
+ this->value[1] = col_type(m[1]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x2<T>::tmat2x2
+ (
+ tmat2x3<T> const & m
+ )
+ {
+ this->value[0] = col_type(m[0]);
+ this->value[1] = col_type(m[1]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x2<T>::tmat2x2
+ (
+ tmat3x2<T> const & m
+ )
+ {
+ this->value[0] = m[0];
+ this->value[1] = m[1];
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x2<T>::tmat2x2
+ (
+ tmat2x4<T> const & m
+ )
+ {
+ this->value[0] = col_type(m[0]);
+ this->value[1] = col_type(m[1]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x2<T>::tmat2x2
+ (
+ tmat4x2<T> const & m
+ )
+ {
+ this->value[0] = m[0];
+ this->value[1] = m[1];
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x2<T>::tmat2x2
+ (
+ tmat3x4<T> const & m
+ )
+ {
+ this->value[0] = col_type(m[0]);
+ this->value[1] = col_type(m[1]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x2<T>::tmat2x2
+ (
+ tmat4x3<T> const & m
+ )
+ {
+ this->value[0] = col_type(m[0]);
+ this->value[1] = col_type(m[1]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x2<T> tmat2x2<T>::_inverse() const
+ {
+ typename tmat2x2<T>::value_type Determinant = this->value[0][0] * this->value[1][1] - this->value[1][0] * this->value[0][1];
+
+ tmat2x2<T> Inverse(
+ + this->value[1][1] / Determinant,
+ - this->value[1][0] / Determinant,
+ - this->value[0][1] / Determinant,
+ + this->value[0][0] / Determinant);
+ return Inverse;
+ }
+
+ //////////////////////////////////////////////////////////////
+ // mat2x2 operators
+
+ // This function shouldn't required but it seems that VC7.1 have an optimisation bug if this operator wasn't declared
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x2<T>& tmat2x2<T>::operator=
+ (
+ tmat2x2<T> const & m
+ )
+ {
+ this->value[0] = m[0];
+ this->value[1] = m[1];
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat2x2<T>& tmat2x2<T>::operator=
+ (
+ tmat2x2<U> const & m
+ )
+ {
+ this->value[0] = m[0];
+ this->value[1] = m[1];
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat2x2<T>& tmat2x2<T>::operator+=
+ (
+ U const & s
+ )
+ {
+ this->value[0] += s;
+ this->value[1] += s;
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat2x2<T>& tmat2x2<T>::operator+=
+ (
+ tmat2x2<U> const & m
+ )
+ {
+ this->value[0] += m[0];
+ this->value[1] += m[1];
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat2x2<T>& tmat2x2<T>::operator-=
+ (
+ U const & s
+ )
+ {
+ this->value[0] -= s;
+ this->value[1] -= s;
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat2x2<T>& tmat2x2<T>::operator-=
+ (
+ tmat2x2<U> const & m
+ )
+ {
+ this->value[0] -= m[0];
+ this->value[1] -= m[1];
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat2x2<T>& tmat2x2<T>::operator*=
+ (
+ U const & s
+ )
+ {
+ this->value[0] *= s;
+ this->value[1] *= s;
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat2x2<T>& tmat2x2<T>::operator*=
+ (
+ tmat2x2<U> const & m
+ )
+ {
+ return (*this = *this * m);
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat2x2<T>& tmat2x2<T>::operator/=
+ (
+ U const & s
+ )
+ {
+ this->value[0] /= s;
+ this->value[1] /= s;
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat2x2<T>& tmat2x2<T>::operator/=
+ (
+ tmat2x2<U> const & m
+ )
+ {
+ return (*this = *this / m);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x2<T>& tmat2x2<T>::operator++ ()
+ {
+ ++this->value[0];
+ ++this->value[1];
+ return *this;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x2<T>& tmat2x2<T>::operator-- ()
+ {
+ --this->value[0];
+ --this->value[1];
+ return *this;
+ }
+
+ //////////////////////////////////////////////////////////////
+ // Binary operators
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x2<T> operator+
+ (
+ tmat2x2<T> const & m,
+ typename tmat2x2<T>::value_type const & s
+ )
+ {
+ return tmat2x2<T>(
+ m[0] + s,
+ m[1] + s);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x2<T> operator+
+ (
+ typename tmat2x2<T>::value_type const & s,
+ tmat2x2<T> const & m
+ )
+ {
+ return tmat2x2<T>(
+ m[0] + s,
+ m[1] + s);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x2<T> operator+
+ (
+ tmat2x2<T> const & m1,
+ tmat2x2<T> const & m2
+ )
+ {
+ return tmat2x2<T>(
+ m1[0] + m2[0],
+ m1[1] + m2[1]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x2<T> operator-
+ (
+ tmat2x2<T> const & m,
+ typename tmat2x2<T>::value_type const & s
+ )
+ {
+ return tmat2x2<T>(
+ m[0] - s,
+ m[1] - s);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x2<T> operator-
+ (
+ typename tmat2x2<T>::value_type const & s,
+ tmat2x2<T> const & m
+ )
+ {
+ return tmat2x2<T>(
+ s - m[0],
+ s - m[1]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x2<T> operator-
+ (
+ tmat2x2<T> const & m1,
+ tmat2x2<T> const & m2
+ )
+ {
+ return tmat2x2<T>(
+ m1[0] - m2[0],
+ m1[1] - m2[1]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x2<T> operator*
+ (
+ tmat2x2<T> const & m,
+ typename tmat2x2<T>::value_type const & s
+ )
+ {
+ return tmat2x2<T>(
+ m[0] * s,
+ m[1] * s);
+ }
+
+ // X
+ // X
+ // X X
+ // X X
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x2<T> operator*
+ (
+ typename tmat2x2<T>::value_type const & s,
+ tmat2x2<T> const & m
+ )
+ {
+ return tmat2x2<T>(
+ m[0] * s,
+ m[1] * s);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename tmat2x2<T>::col_type operator*
+ (
+ tmat2x2<T> const & m,
+ typename tmat2x2<T>::row_type const & v
+ )
+ {
+ return detail::tvec2<T>(
+ m[0][0] * v.x + m[1][0] * v.y,
+ m[0][1] * v.x + m[1][1] * v.y);
+ }
+
+ // X X
+ // X X
+ // X X
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename tmat2x2<T>::row_type operator*
+ (
+ typename tmat2x2<T>::col_type const & v,
+ tmat2x2<T> const & m
+ )
+ {
+ return detail::tvec2<T>(
+ v.x * m[0][0] + v.y * m[0][1],
+ v.x * m[1][0] + v.y * m[1][1]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x2<T> operator*
+ (
+ tmat2x2<T> const & m1,
+ tmat2x2<T> const & m2
+ )
+ {
+ return tmat2x2<T>(
+ m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1],
+ m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1],
+ m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1],
+ m1[0][1] * m2[1][0] + m1[1][1] * m2[1][1]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x2<T> operator/
+ (
+ tmat2x2<T> const & m,
+ typename tmat2x2<T>::value_type const & s
+ )
+ {
+ return tmat2x2<T>(
+ m[0] / s,
+ m[1] / s);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x2<T> operator/
+ (
+ typename tmat2x2<T>::value_type const & s,
+ tmat2x2<T> const & m
+ )
+ {
+ return tmat2x2<T>(
+ s / m[0],
+ s / m[1]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename tmat2x2<T>::col_type operator/
+ (
+ tmat2x2<T> const & m,
+ typename tmat2x2<T>::row_type & v
+ )
+ {
+ return m._inverse() * v;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename tmat2x2<T>::row_type operator/
+ (
+ typename tmat2x2<T>::col_type const & v,
+ tmat2x2<T> const & m
+ )
+ {
+ return v * m._inverse();
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x2<T> operator/
+ (
+ tmat2x2<T> const & m1,
+ tmat2x2<T> const & m2
+ )
+ {
+ return m1 * m2._inverse();
+ }
+
+ // Unary constant operators
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x2<T> const operator-
+ (
+ tmat2x2<T> const & m
+ )
+ {
+ return tmat2x2<T>(
+ -m[0],
+ -m[1]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x2<T> const operator++
+ (
+ tmat2x2<T> const & m,
+ int
+ )
+ {
+ return tmat2x2<T>(
+ m[0] + T(1),
+ m[1] + T(1));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x2<T> const operator--
+ (
+ tmat2x2<T> const & m,
+ int
+ )
+ {
+ return tmat2x2<T>(
+ m[0] - T(1),
+ m[1] - T(1));
+ }
+
+ //////////////////////////////////////
+ // Boolean operators
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER bool operator==
+ (
+ tmat2x2<T> const & m1,
+ tmat2x2<T> const & m2
+ )
+ {
+ return (m1[0] == m2[0]) && (m1[1] == m2[1]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER bool operator!=
+ (
+ tmat2x2<T> const & m1,
+ tmat2x2<T> const & m2
+ )
+ {
+ return (m1[0] != m2[0]) || (m1[1] != m2[1]);
+ }
+
+} //namespace detail
+} //namespace glm
diff --git a/src/glm/core/type_mat2x3.hpp b/src/glm/core/type_mat2x3.hpp
new file mode 100644
index 0000000..63d1d0e
--- /dev/null
+++ b/src/glm/core/type_mat2x3.hpp
@@ -0,0 +1,227 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2006-10-01
+// Updated : 2010-02-03
+// Licence : This source is under MIT License
+// File : glm/core/type_mat2x3.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_core_type_mat2x3
+#define glm_core_type_mat2x3
+
+#include "type_mat.hpp"
+
+namespace glm{
+namespace detail
+{
+ template <typename T> struct tvec1;
+ template <typename T> struct tvec2;
+ template <typename T> struct tvec3;
+ template <typename T> struct tvec4;
+ template <typename T> struct tmat2x2;
+ template <typename T> struct tmat2x3;
+ template <typename T> struct tmat2x4;
+ template <typename T> struct tmat3x2;
+ template <typename T> struct tmat3x3;
+ template <typename T> struct tmat3x4;
+ template <typename T> struct tmat4x2;
+ template <typename T> struct tmat4x3;
+ template <typename T> struct tmat4x4;
+
+ //! \brief Template for 2 columns and 3 rows matrix of floating-point numbers.
+ //! \ingroup core_template
+ template <typename T>
+ struct tmat2x3
+ {
+ enum ctor{null};
+ typedef T value_type;
+ typedef std::size_t size_type;
+ typedef tvec3<T> col_type;
+ typedef tvec2<T> row_type;
+ static GLM_FUNC_DECL size_type col_size();
+ static GLM_FUNC_DECL size_type row_size();
+
+ typedef tmat2x3<T> type;
+ typedef tmat3x2<T> transpose_type;
+
+ private:
+ // Data
+ col_type value[2];
+
+ public:
+ // Constructors
+ GLM_FUNC_DECL tmat2x3();
+ GLM_FUNC_DECL tmat2x3(tmat2x3 const & m);
+
+ GLM_FUNC_DECL explicit tmat2x3(
+ ctor);
+ GLM_FUNC_DECL explicit tmat2x3(
+ value_type const & s);
+ GLM_FUNC_DECL explicit tmat2x3(
+ value_type const & x0, value_type const & y0, value_type const & z0,
+ value_type const & x1, value_type const & y1, value_type const & z1);
+ GLM_FUNC_DECL explicit tmat2x3(
+ col_type const & v0,
+ col_type const & v1);
+
+
+ //////////////////////////////////////
+ // Conversions
+ template <typename U>
+ GLM_FUNC_DECL explicit tmat2x3(
+ U const & x);
+
+ template <typename X1, typename Y1, typename Z1, typename X2, typename Y2, typename Z2>
+ GLM_FUNC_DECL explicit tmat2x3(
+ X1 const & x1, Y1 const & y1, Z1 const & z1,
+ X2 const & x2, Y2 const & y2, Z2 const & z2);
+
+ template <typename U, typename V>
+ GLM_FUNC_DECL explicit tmat2x3(
+ tvec3<U> const & v1,
+ tvec3<V> const & v2);
+
+ //////////////////////////////////////
+ // Matrix conversion
+ template <typename U>
+ GLM_FUNC_DECL explicit tmat2x3(tmat2x3<U> const & m);
+
+ GLM_FUNC_DECL explicit tmat2x3(tmat2x2<T> const & x);
+ GLM_FUNC_DECL explicit tmat2x3(tmat3x3<T> const & x);
+ GLM_FUNC_DECL explicit tmat2x3(tmat4x4<T> const & x);
+ GLM_FUNC_DECL explicit tmat2x3(tmat2x4<T> const & x);
+ GLM_FUNC_DECL explicit tmat2x3(tmat3x2<T> const & x);
+ GLM_FUNC_DECL explicit tmat2x3(tmat3x4<T> const & x);
+ GLM_FUNC_DECL explicit tmat2x3(tmat4x2<T> const & x);
+ GLM_FUNC_DECL explicit tmat2x3(tmat4x3<T> const & x);
+
+ // Accesses
+ col_type & operator[](size_type i);
+ col_type const & operator[](size_type i) const;
+
+ // Unary updatable operators
+ GLM_FUNC_DECL tmat2x3<T> & operator= (tmat2x3<T> const & m);
+ template <typename U>
+ GLM_FUNC_DECL tmat2x3<T> & operator= (tmat2x3<U> const & m);
+ template <typename U>
+ GLM_FUNC_DECL tmat2x3<T> & operator+= (U const & s);
+ template <typename U>
+ GLM_FUNC_DECL tmat2x3<T> & operator+= (tmat2x3<U> const & m);
+ template <typename U>
+ GLM_FUNC_DECL tmat2x3<T> & operator-= (U const & s);
+ template <typename U>
+ GLM_FUNC_DECL tmat2x3<T> & operator-= (tmat2x3<U> const & m);
+ template <typename U>
+ GLM_FUNC_DECL tmat2x3<T> & operator*= (U const & s);
+ template <typename U>
+ GLM_FUNC_DECL tmat2x3<T> & operator*= (tmat2x3<U> const & m);
+ template <typename U>
+ GLM_FUNC_DECL tmat2x3<T> & operator/= (U const & s);
+
+ GLM_FUNC_DECL tmat2x3<T> & operator++ ();
+ GLM_FUNC_DECL tmat2x3<T> & operator-- ();
+ };
+
+ // Binary operators
+ template <typename T>
+ tmat2x3<T> operator+ (
+ tmat2x3<T> const & m,
+ typename tmat2x3<T>::value_type const & s);
+
+ template <typename T>
+ tmat2x3<T> operator+ (
+ tmat2x3<T> const & m1,
+ tmat2x3<T> const & m2);
+
+ template <typename T>
+ tmat2x3<T> operator- (
+ tmat2x3<T> const & m,
+ typename tmat2x3<T>::value_type const & s);
+
+ template <typename T>
+ tmat2x3<T> operator- (
+ tmat2x3<T> const & m1,
+ tmat2x3<T> const & m2);
+
+ template <typename T>
+ tmat2x3<T> operator* (
+ tmat2x3<T> const & m,
+ typename tmat2x3<T>::value_type const & s);
+
+ template <typename T>
+ tmat2x3<T> operator* (
+ typename tmat2x3<T>::value_type const & s,
+ tmat2x3<T> const & m);
+
+ template <typename T>
+ typename tmat2x3<T>::col_type operator* (
+ tmat2x3<T> const & m,
+ typename tmat2x3<T>::row_type const & v);
+
+ template <typename T>
+ typename tmat2x3<T>::row_type operator* (
+ typename tmat2x3<T>::col_type const & v,
+ tmat2x3<T> const & m);
+
+ template <typename T>
+ tmat3x3<T> operator* (
+ tmat2x3<T> const & m1,
+ tmat3x2<T> const & m2);
+
+ template <typename T>
+ tmat2x3<T> operator/ (
+ tmat2x3<T> const & m,
+ typename tmat2x3<T>::value_type const & s);
+
+ template <typename T>
+ tmat2x3<T> operator/ (
+ typename tmat2x3<T>::value_type const & s,
+ tmat2x3<T> const & m);
+
+ // Unary constant operators
+ template <typename T>
+ tmat2x3<T> const operator- (
+ tmat2x3<T> const & m);
+
+ template <typename T>
+ tmat2x3<T> const operator-- (
+ tmat2x3<T> const & m,
+ int);
+
+ template <typename T>
+ tmat2x3<T> const operator++ (
+ tmat2x3<T> const & m,
+ int);
+
+} //namespace detail
+
+namespace core{
+namespace type{
+namespace precision
+{
+ //! 2 columns of 3 components matrix of low precision floating-point numbers.
+ //! There is no guarantee on the actual precision.
+ //! (From GLSL 1.30.8 specification, section 4.1.6 Matrices and section 4.5 Precision and Precision Qualifiers)
+ //! \ingroup core_precision
+ typedef detail::tmat2x3<lowp_float> lowp_mat2x3;
+ //! 2 columns of 3 components matrix of medium precision floating-point numbers.
+ //! There is no guarantee on the actual precision.
+ //! (From GLSL 1.30.8 specification, section 4.1.6 Matrices and section 4.5 Precision and Precision Qualifiers)
+ //! \ingroup core_precision
+ typedef detail::tmat2x3<mediump_float> mediump_mat2x3;
+ //! 2 columns of 3 components matrix of high precision floating-point numbers.
+ //! There is no guarantee on the actual precision.
+ //! (From GLSL 1.30.8 specification, section 4.1.6 Matrices and section 4.5 Precision and Precision Qualifiers)
+ //! \ingroup core_precision
+ typedef detail::tmat2x3<highp_float> highp_mat2x3;
+}//namespace precision
+}//namespace type
+}//namespace core
+}//namespace glm
+
+#ifndef GLM_EXTERNAL_TEMPLATE
+#include "type_mat2x3.inl"
+#endif
+
+#endif //glm_core_type_mat2x3
diff --git a/src/glm/core/type_mat2x3.inl b/src/glm/core/type_mat2x3.inl
new file mode 100644
index 0000000..7b987e0
--- /dev/null
+++ b/src/glm/core/type_mat2x3.inl
@@ -0,0 +1,583 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2006-08-05
+// Updated : 2010-02-03
+// Licence : This source is under MIT License
+// File : glm/core/type_mat2x3.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm{
+namespace detail
+{
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename tmat2x3<T>::size_type tmat2x3<T>::col_size()
+ {
+ return 3;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename tmat2x3<T>::size_type tmat2x3<T>::row_size()
+ {
+ return 2;
+ }
+
+ //////////////////////////////////////
+ // Accesses
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename tmat2x3<T>::col_type &
+ tmat2x3<T>::operator[]
+ (
+ size_type i
+ )
+ {
+ assert(i < this->row_size());
+ return this->value[i];
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename tmat2x3<T>::col_type const &
+ tmat2x3<T>::operator[]
+ (
+ size_type i
+ ) const
+ {
+ assert(i < this->row_size());
+ return this->value[i];
+ }
+
+ //////////////////////////////////////////////////////////////
+ // Constructors
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x3<T>::tmat2x3()
+ {
+ this->value[0] = col_type(T(1), T(0), T(0));
+ this->value[1] = col_type(T(0), T(1), T(0));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x3<T>::tmat2x3
+ (
+ tmat2x3<T> const & m
+ )
+ {
+ this->value[0] = m.value[0];
+ this->value[1] = m.value[1];
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x3<T>::tmat2x3
+ (
+ ctor
+ )
+ {}
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x3<T>::tmat2x3
+ (
+ value_type const & s
+ )
+ {
+ this->value[0] = col_type(s, T(0), T(0));
+ this->value[1] = col_type(T(0), s, T(0));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x3<T>::tmat2x3
+ (
+ value_type const & x0, value_type const & y0, value_type const & z0,
+ value_type const & x1, value_type const & y1, value_type const & z1
+ )
+ {
+ this->value[0] = col_type(x0, y0, z0);
+ this->value[1] = col_type(x1, y1, z1);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x3<T>::tmat2x3
+ (
+ col_type const & v0,
+ col_type const & v1
+ )
+ {
+ this->value[0] = v0;
+ this->value[1] = v1;
+ }
+
+ //////////////////////////////////////
+ // Convertion constructors
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_DECL tmat2x3<T>::tmat2x3
+ (
+ U const & s
+ )
+ {
+ value_type const Zero(0);
+ this->value[0] = tvec3<T>(value_type(s), Zero, Zero);
+ this->value[1] = tvec3<T>(Zero, value_type(s), Zero);
+ }
+
+ template <typename T>
+ template <
+ typename X1, typename Y1, typename Z1,
+ typename X2, typename Y2, typename Z2>
+ GLM_FUNC_DECL tmat2x3<T>::tmat2x3
+ (
+ X1 const & x1, Y1 const & y1, Z1 const & z1,
+ X2 const & x2, Y2 const & y2, Z2 const & z2
+ )
+ {
+ this->value[0] = col_type(value_type(x1), value_type(y1), value_type(z1));
+ this->value[1] = col_type(value_type(x2), value_type(y2), value_type(z2));
+ }
+
+ template <typename T>
+ template <typename V1, typename V2>
+ GLM_FUNC_DECL tmat2x3<T>::tmat2x3
+ (
+ tvec3<V1> const & v1,
+ tvec3<V2> const & v2
+ )
+ {
+ this->value[0] = col_type(v1);
+ this->value[1] = col_type(v2);
+ }
+
+ //////////////////////////////////////
+ // Matrix conversions
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat2x3<T>::tmat2x3
+ (
+ tmat2x3<U> const & m
+ )
+ {
+ this->value[0] = col_type(m[0]);
+ this->value[1] = col_type(m[1]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x3<T>::tmat2x3
+ (
+ tmat2x2<T> const & m
+ )
+ {
+ this->value[0] = col_type(m[0], T(0));
+ this->value[1] = col_type(m[1], T(0));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x3<T>::tmat2x3
+ (
+ tmat3x3<T> const & m
+ )
+ {
+ this->value[0] = col_type(m[0]);
+ this->value[1] = col_type(m[1]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x3<T>::tmat2x3
+ (
+ tmat4x4<T> const & m
+ )
+ {
+ this->value[0] = col_type(m[0]);
+ this->value[1] = col_type(m[1]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x3<T>::tmat2x3
+ (
+ tmat2x4<T> const & m
+ )
+ {
+ this->value[0] = col_type(m[0]);
+ this->value[1] = col_type(m[1]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x3<T>::tmat2x3
+ (
+ tmat3x2<T> const & m
+ )
+ {
+ this->value[0] = col_type(m[0], T(0));
+ this->value[1] = col_type(m[1], T(0));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x3<T>::tmat2x3
+ (
+ tmat3x4<T> const & m
+ )
+ {
+ this->value[0] = col_type(m[0]);
+ this->value[1] = col_type(m[1]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x3<T>::tmat2x3
+ (
+ tmat4x2<T> const & m
+ )
+ {
+ this->value[0] = col_type(m[0], T(0));
+ this->value[1] = col_type(m[1], T(0));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x3<T>::tmat2x3
+ (
+ tmat4x3<T> const & m
+ )
+ {
+ this->value[0] = m[0];
+ this->value[1] = m[1];
+ }
+
+ //////////////////////////////////////////////////////////////
+ // Unary updatable operators
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x3<T>& tmat2x3<T>::operator=
+ (
+ tmat2x3<T> const & m
+ )
+ {
+ this->value[0] = m[0];
+ this->value[1] = m[1];
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat2x3<T>& tmat2x3<T>::operator=
+ (
+ tmat2x3<U> const & m
+ )
+ {
+ this->value[0] = m[0];
+ this->value[1] = m[1];
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat2x3<T> & tmat2x3<T>::operator+=
+ (
+ U const & s
+ )
+ {
+ this->value[0] += s;
+ this->value[1] += s;
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat2x3<T>& tmat2x3<T>::operator+=
+ (
+ tmat2x3<U> const & m
+ )
+ {
+ this->value[0] += m[0];
+ this->value[1] += m[1];
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat2x3<T>& tmat2x3<T>::operator-=
+ (
+ U const & s
+ )
+ {
+ this->value[0] -= s;
+ this->value[1] -= s;
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat2x3<T>& tmat2x3<T>::operator-=
+ (
+ tmat2x3<U> const & m
+ )
+ {
+ this->value[0] -= m[0];
+ this->value[1] -= m[1];
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat2x3<T>& tmat2x3<T>::operator*=
+ (
+ U const & s
+ )
+ {
+ this->value[0] *= s;
+ this->value[1] *= s;
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat2x3<T> & tmat2x3<T>::operator*=
+ (
+ tmat2x3<U> const & m
+ )
+ {
+ return (*this = tmat2x3<U>(*this * m));
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat2x3<T> & tmat2x3<T>::operator/=
+ (
+ U const & s
+ )
+ {
+ this->value[0] /= s;
+ this->value[1] /= s;
+ return *this;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x3<T> & tmat2x3<T>::operator++ ()
+ {
+ ++this->value[0];
+ ++this->value[1];
+ return *this;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x3<T> & tmat2x3<T>::operator-- ()
+ {
+ --this->value[0];
+ --this->value[1];
+ return *this;
+ }
+
+ //////////////////////////////////////////////////////////////
+ // Binary operators
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x3<T> operator+
+ (
+ tmat2x3<T> const & m,
+ typename tmat2x3<T>::value_type const & s
+ )
+ {
+ return tmat2x3<T>(
+ m[0] + s,
+ m[1] + s);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x3<T> operator+
+ (
+ tmat2x3<T> const & m1,
+ tmat2x3<T> const & m2
+ )
+ {
+ return tmat2x3<T>(
+ m1[0] + m2[0],
+ m1[1] + m2[1]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x3<T> operator-
+ (
+ tmat2x3<T> const & m,
+ typename tmat2x3<T>::value_type const & s
+ )
+ {
+ return tmat2x3<T>(
+ m[0] - s,
+ m[1] - s);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x3<T> operator-
+ (
+ tmat2x3<T> const & m1,
+ tmat2x3<T> const & m2
+ )
+ {
+ return tmat2x3<T>(
+ m1[0] - m2[0],
+ m1[1] - m2[1]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x3<T> operator*
+ (
+ tmat2x3<T> const & m,
+ typename tmat2x3<T>::value_type const & s
+ )
+ {
+ return tmat2x3<T>(
+ m[0] * s,
+ m[1] * s);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x3<T> operator*
+ (
+ typename tmat2x3<T>::value_type const & s,
+ tmat2x3<T> const & m
+ )
+ {
+ return tmat2x3<T>(
+ m[0] * s,
+ m[1] * s);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename tmat2x3<T>::col_type operator*
+ (
+ tmat2x3<T> const & m,
+ typename tmat2x3<T>::row_type const & v)
+ {
+ return typename tmat2x3<T>::col_type(
+ m[0][0] * v.x + m[1][0] * v.y,
+ m[0][1] * v.x + m[1][1] * v.y,
+ m[0][2] * v.x + m[1][2] * v.y);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename tmat2x3<T>::row_type operator*
+ (
+ typename tmat2x3<T>::col_type const & v,
+ tmat2x3<T> const & m)
+ {
+ return typename tmat2x3<T>::row_type(
+ v.x * m[0][0] + v.y * m[0][1] + v.z * m[0][2],
+ v.x * m[1][0] + v.y * m[1][1] + v.z * m[1][2]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x3<T> operator*
+ (
+ tmat2x3<T> const & m1,
+ tmat3x2<T> const & m2
+ )
+ {
+ typename tmat2x3<T>::value_type SrcA00 = m1[0][0];
+ typename tmat2x3<T>::value_type SrcA01 = m1[0][1];
+ typename tmat2x3<T>::value_type SrcA02 = m1[0][2];
+ typename tmat2x3<T>::value_type SrcA10 = m1[1][0];
+ typename tmat2x3<T>::value_type SrcA11 = m1[1][1];
+ typename tmat2x3<T>::value_type SrcA12 = m1[1][2];
+
+ typename tmat2x3<T>::value_type SrcB00 = m2[0][0];
+ typename tmat2x3<T>::value_type SrcB01 = m2[0][1];
+ typename tmat2x3<T>::value_type SrcB10 = m2[1][0];
+ typename tmat2x3<T>::value_type SrcB11 = m2[1][1];
+ typename tmat2x3<T>::value_type SrcB20 = m2[2][0];
+ typename tmat2x3<T>::value_type SrcB21 = m2[2][1];
+
+ tmat3x3<T> Result(tmat3x3<T>::null);
+ Result[0][0] = SrcA00 * SrcB00 + SrcA10 * SrcB01;
+ Result[0][1] = SrcA01 * SrcB00 + SrcA11 * SrcB01;
+ Result[0][2] = SrcA02 * SrcB00 + SrcA12 * SrcB01;
+ Result[1][0] = SrcA00 * SrcB10 + SrcA10 * SrcB11;
+ Result[1][1] = SrcA01 * SrcB10 + SrcA11 * SrcB11;
+ Result[1][2] = SrcA02 * SrcB10 + SrcA12 * SrcB11;
+ Result[2][0] = SrcA00 * SrcB20 + SrcA10 * SrcB21;
+ Result[2][1] = SrcA01 * SrcB20 + SrcA11 * SrcB21;
+ Result[2][2] = SrcA02 * SrcB20 + SrcA12 * SrcB21;
+ return Result;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x3<T> operator/
+ (
+ tmat2x3<T> const & m,
+ typename tmat2x3<T>::value_type const & s
+ )
+ {
+ return tmat2x3<T>(
+ m[0] / s,
+ m[1] / s);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x3<T> operator/
+ (
+ typename tmat2x3<T>::value_type const & s,
+ tmat2x3<T> const & m
+ )
+ {
+ return tmat2x3<T>(
+ s / m[0],
+ s / m[1]);
+ }
+
+ // Unary constant operators
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x3<T> const operator-
+ (
+ tmat2x3<T> const & m
+ )
+ {
+ return tmat2x3<T>(
+ -m[0],
+ -m[1]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x3<T> const operator++
+ (
+ tmat2x3<T> const & m,
+ int
+ )
+ {
+ return tmat2x3<T>(
+ m[0] + typename tmat2x3<T>::value_type(1),
+ m[1] + typename tmat2x3<T>::value_type(1));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x3<T> const operator--
+ (
+ tmat2x3<T> const & m,
+ int
+ )
+ {
+ return tmat2x3<T>(
+ m[0] - typename tmat2x3<T>::value_type(1),
+ m[1] - typename tmat2x3<T>::value_type(1));
+ }
+
+ //////////////////////////////////////
+ // Boolean operators
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER bool operator==
+ (
+ tmat2x3<T> const & m1,
+ tmat2x3<T> const & m2
+ )
+ {
+ return (m1[0] == m2[0]) && (m1[1] == m2[1]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER bool operator!=
+ (
+ tmat2x3<T> const & m1,
+ tmat2x3<T> const & m2
+ )
+ {
+ return (m1[0] != m2[0]) || (m1[1] != m2[1]);
+ }
+
+} //namespace detail
+} //namespace glm
diff --git a/src/glm/core/type_mat2x4.hpp b/src/glm/core/type_mat2x4.hpp
new file mode 100644
index 0000000..0016ed4
--- /dev/null
+++ b/src/glm/core/type_mat2x4.hpp
@@ -0,0 +1,225 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2006-08-05
+// Updated : 2010-02-11
+// Licence : This source is under MIT License
+// File : glm/core/type_mat2x4.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_core_type_mat2x4
+#define glm_core_type_mat2x4
+
+#include "type_mat.hpp"
+
+namespace glm{
+namespace detail
+{
+ template <typename T> struct tvec1;
+ template <typename T> struct tvec2;
+ template <typename T> struct tvec3;
+ template <typename T> struct tvec4;
+ template <typename T> struct tmat2x2;
+ template <typename T> struct tmat2x3;
+ template <typename T> struct tmat2x4;
+ template <typename T> struct tmat3x2;
+ template <typename T> struct tmat3x3;
+ template <typename T> struct tmat3x4;
+ template <typename T> struct tmat4x2;
+ template <typename T> struct tmat4x3;
+ template <typename T> struct tmat4x4;
+
+ //! Template for 2 columns and 4 rows matrix of floating-point numbers.
+ //! \ingroup core_template
+ template <typename T>
+ struct tmat2x4
+ {
+ enum ctor{null};
+ typedef T value_type;
+ typedef std::size_t size_type;
+ typedef tvec4<T> col_type;
+ typedef tvec2<T> row_type;
+ static GLM_FUNC_DECL size_type col_size();
+ static GLM_FUNC_DECL size_type row_size();
+
+ typedef tmat2x4<T> type;
+ typedef tmat4x2<T> transpose_type;
+
+ private:
+ // Data
+ col_type value[2];
+
+ public:
+ // Constructors
+ GLM_FUNC_DECL tmat2x4();
+ GLM_FUNC_DECL tmat2x4(tmat2x4 const & m);
+
+ GLM_FUNC_DECL explicit tmat2x4(
+ ctor);
+ GLM_FUNC_DECL explicit tmat2x4(
+ value_type const & s);
+ GLM_FUNC_DECL explicit tmat2x4(
+ value_type const & x0, value_type const & y0, value_type const & z0, value_type const & w0,
+ value_type const & x1, value_type const & y1, value_type const & z1, value_type const & w1);
+ GLM_FUNC_DECL explicit tmat2x4(
+ col_type const & v0,
+ col_type const & v1);
+
+ //////////////////////////////////////
+ // Conversions
+ template <typename U>
+ GLM_FUNC_DECL explicit tmat2x4(
+ U const & x);
+
+ template <
+ typename X1, typename Y1, typename Z1, typename W1,
+ typename X2, typename Y2, typename Z2, typename W2>
+ GLM_FUNC_DECL explicit tmat2x4(
+ X1 const & x1, Y1 const & y1, Z1 const & z1, W1 const & w1,
+ X2 const & x2, Y2 const & y2, Z2 const & z2, W2 const & w2);
+
+ template <typename U, typename V>
+ GLM_FUNC_DECL explicit tmat2x4(
+ tvec4<U> const & v1,
+ tvec4<V> const & v2);
+
+ //////////////////////////////////////
+ // Matrix conversions
+ template <typename U>
+ GLM_FUNC_DECL explicit tmat2x4(tmat2x4<U> const & m);
+
+ GLM_FUNC_DECL explicit tmat2x4(tmat2x2<T> const & x);
+ GLM_FUNC_DECL explicit tmat2x4(tmat3x3<T> const & x);
+ GLM_FUNC_DECL explicit tmat2x4(tmat4x4<T> const & x);
+ GLM_FUNC_DECL explicit tmat2x4(tmat2x3<T> const & x);
+ GLM_FUNC_DECL explicit tmat2x4(tmat3x2<T> const & x);
+ GLM_FUNC_DECL explicit tmat2x4(tmat3x4<T> const & x);
+ GLM_FUNC_DECL explicit tmat2x4(tmat4x2<T> const & x);
+ GLM_FUNC_DECL explicit tmat2x4(tmat4x3<T> const & x);
+
+ // Accesses
+ GLM_FUNC_DECL col_type & operator[](size_type i);
+ GLM_FUNC_DECL col_type const & operator[](size_type i) const;
+
+ // Unary updatable operators
+ GLM_FUNC_DECL tmat2x4<T>& operator= (tmat2x4<T> const & m);
+ template <typename U>
+ GLM_FUNC_DECL tmat2x4<T>& operator= (tmat2x4<U> const & m);
+ template <typename U>
+ GLM_FUNC_DECL tmat2x4<T>& operator+= (U const & s);
+ template <typename U>
+ GLM_FUNC_DECL tmat2x4<T>& operator+= (tmat2x4<U> const & m);
+ template <typename U>
+ GLM_FUNC_DECL tmat2x4<T>& operator-= (U const & s);
+ template <typename U>
+ GLM_FUNC_DECL tmat2x4<T>& operator-= (tmat2x4<U> const & m);
+ template <typename U>
+ GLM_FUNC_DECL tmat2x4<T>& operator*= (U const & s);
+ template <typename U>
+ GLM_FUNC_DECL tmat2x4<T>& operator*= (tmat2x4<U> const & m);
+ template <typename U>
+ GLM_FUNC_DECL tmat2x4<T>& operator/= (U const & s);
+
+ GLM_FUNC_DECL tmat2x4<T>& operator++ ();
+ GLM_FUNC_DECL tmat2x4<T>& operator-- ();
+ };
+
+ // Binary operators
+ template <typename T>
+ tmat2x4<T> operator+ (
+ tmat2x4<T> const & m,
+ typename tmat2x4<T>::value_type const & s);
+
+ template <typename T>
+ tmat2x4<T> operator+ (
+ tmat2x4<T> const & m1,
+ tmat2x4<T> const & m2);
+
+ template <typename T>
+ tmat2x4<T> operator- (
+ tmat2x4<T> const & m,
+ typename tmat2x4<T>::value_type const & s);
+
+ template <typename T>
+ tmat2x4<T> operator- (
+ tmat2x4<T> const & m1,
+ tmat2x4<T> const & m2);
+
+ template <typename T>
+ tmat2x4<T> operator* (
+ tmat2x4<T> const & m,
+ typename tmat2x4<T>::value_type const & s);
+
+ template <typename T>
+ tmat2x4<T> operator* (
+ typename tmat2x4<T>::value_type const & s,
+ tmat2x4<T> const & m);
+
+ template <typename T>
+ typename tmat2x4<T>::col_type operator* (
+ tmat2x4<T> const & m,
+ typename tmat2x4<T>::row_type const & v);
+
+ template <typename T>
+ typename tmat2x4<T>::row_type operator* (
+ typename tmat2x4<T>::col_type const & v,
+ tmat2x4<T> const & m);
+
+ template <typename T>
+ tmat2x4<T> operator* (
+ tmat2x4<T> const & m1,
+ tmat2x4<T> const & m2);
+
+ template <typename T>
+ tmat2x4<T> operator/ (
+ tmat2x4<T> const & m,
+ typename tmat2x4<T>::value_type const & s);
+
+ template <typename T>
+ tmat2x4<T> operator/ (
+ typename tmat2x4<T>::value_type const & s,
+ tmat2x4<T> const & m);
+
+ // Unary constant operators
+ template <typename T>
+ tmat2x4<T> const operator- (
+ tmat2x4<T> const & m);
+
+ template <typename T>
+ tmat2x4<T> const operator-- (
+ tmat2x4<T> const & m,
+ int);
+
+ template <typename T>
+ tmat2x4<T> const operator++ (
+ tmat2x4<T> const & m,
+ int);
+
+} //namespace detail
+
+namespace core{
+namespace type{
+namespace precision
+{
+ //! 2 columns of 4 components matrix of low precision floating-point numbers.
+ //! There is no guarantee on the actual precision.
+ //! (From GLSL 1.30.8 specification, section 4.1.6 Matrices and section 4.5 Precision and Precision Qualifiers)
+ typedef detail::tmat2x4<lowp_float> lowp_mat2x4;
+ //! 2 columns of 4 components matrix of medium precision floating-point numbers.
+ //! There is no guarantee on the actual precision.
+ //! (From GLSL 1.30.8 specification, section 4.1.6 Matrices and section 4.5 Precision and Precision Qualifiers)
+ typedef detail::tmat2x4<mediump_float> mediump_mat2x4;
+ //! 2 columns of 4 components matrix of high precision floating-point numbers.
+ //! There is no guarantee on the actual precision.
+ //! (From GLSL 1.30.8 specification, section 4.1.6 Matrices and section 4.5 Precision and Precision Qualifiers)
+ typedef detail::tmat2x4<highp_float> highp_mat2x4;
+}//namespace precision
+}//namespace type
+}//namespace core
+}//namespace glm
+
+#ifndef GLM_EXTERNAL_TEMPLATE
+#include "type_mat2x4.inl"
+#endif
+
+#endif //glm_core_type_mat2x4
diff --git a/src/glm/core/type_mat2x4.inl b/src/glm/core/type_mat2x4.inl
new file mode 100644
index 0000000..94e9852
--- /dev/null
+++ b/src/glm/core/type_mat2x4.inl
@@ -0,0 +1,611 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2006-08-05
+// Updated : 2010-02-03
+// Licence : This source is under MIT License
+// File : glm/core/type_mat2x4.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm{
+namespace detail
+{
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename tmat2x4<T>::size_type tmat2x4<T>::col_size()
+ {
+ return 4;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename tmat2x4<T>::size_type tmat2x4<T>::row_size()
+ {
+ return 2;
+ }
+
+ //////////////////////////////////////
+ // Accesses
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename tmat2x4<T>::col_type &
+ tmat2x4<T>::operator[]
+ (
+ size_type i
+ )
+ {
+ assert(i < this->row_size());
+ return this->value[i];
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename tmat2x4<T>::col_type const &
+ tmat2x4<T>::operator[]
+ (
+ size_type i
+ ) const
+ {
+ assert(i < this->row_size());
+ return this->value[i];
+ }
+
+ //////////////////////////////////////////////////////////////
+ // Constructors
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x4<T>::tmat2x4()
+ {
+ value_type const Zero(0);
+ value_type const One(1);
+ this->value[0] = col_type(One, Zero, Zero, Zero);
+ this->value[1] = col_type(Zero, One, Zero, Zero);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x4<T>::tmat2x4
+ (
+ tmat2x4<T> const & m
+ )
+ {
+ this->value[0] = m.value[0];
+ this->value[1] = m.value[1];
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x4<T>::tmat2x4
+ (
+ ctor
+ )
+ {}
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x4<T>::tmat2x4
+ (
+ value_type const & s
+ )
+ {
+ value_type const Zero(0);
+ this->value[0] = col_type(s, Zero, Zero, Zero);
+ this->value[1] = col_type(Zero, Zero, Zero, Zero);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x4<T>::tmat2x4
+ (
+ value_type const & x0, value_type const & y0, value_type const & z0, value_type const & w0,
+ value_type const & x1, value_type const & y1, value_type const & z1, value_type const & w1
+ )
+ {
+ this->value[0] = col_type(x0, y0, z0, w0);
+ this->value[1] = col_type(x1, y1, z1, w1);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x4<T>::tmat2x4
+ (
+ col_type const & v0,
+ col_type const & v1
+ )
+ {
+ this->value[0] = v0;
+ this->value[1] = v1;
+ }
+
+ //////////////////////////////////////
+ // Convertion constructors
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_DECL tmat2x4<T>::tmat2x4
+ (
+ U const & s
+ )
+ {
+ value_type const Zero(0);
+ this->value[0] = tvec4<T>(value_type(s), Zero, Zero, Zero);
+ this->value[1] = tvec4<T>(Zero, value_type(s), Zero, Zero);
+ }
+
+ template <typename T>
+ template <
+ typename X1, typename Y1, typename Z1, typename W1,
+ typename X2, typename Y2, typename Z2, typename W2>
+ GLM_FUNC_DECL tmat2x4<T>::tmat2x4
+ (
+ X1 const & x1, Y1 const & y1, Z1 const & z1, W1 const & w1,
+ X2 const & x2, Y2 const & y2, Z2 const & z2, W2 const & w2
+ )
+ {
+ this->value[0] = col_type(value_type(x1), value_type(y1), value_type(z1), value_type(w1));
+ this->value[1] = col_type(value_type(x2), value_type(y2), value_type(z2), value_type(w2));
+ }
+
+ template <typename T>
+ template <typename V1, typename V2>
+ GLM_FUNC_DECL tmat2x4<T>::tmat2x4
+ (
+ tvec4<V1> const & v1,
+ tvec4<V2> const & v2
+ )
+ {
+ this->value[0] = col_type(v1);
+ this->value[1] = col_type(v2);
+ }
+
+ //////////////////////////////////////
+ // Matrix conversions
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat2x4<T>::tmat2x4
+ (
+ tmat2x4<U> const & m
+ )
+ {
+ this->value[0] = col_type(m[0]);
+ this->value[1] = col_type(m[1]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x4<T>::tmat2x4
+ (
+ tmat2x2<T> const & m
+ )
+ {
+ this->value[0] = col_type(m[0], detail::tvec2<T>(0));
+ this->value[1] = col_type(m[1], detail::tvec2<T>(0));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x4<T>::tmat2x4
+ (
+ tmat3x3<T> const & m
+ )
+ {
+ this->value[0] = col_type(m[0], T(0));
+ this->value[1] = col_type(m[1], T(0));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x4<T>::tmat2x4
+ (
+ tmat4x4<T> const & m
+ )
+ {
+ this->value[0] = col_type(m[0]);
+ this->value[1] = col_type(m[1]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x4<T>::tmat2x4
+ (
+ tmat2x3<T> const & m
+ )
+ {
+ this->value[0] = col_type(m[0], T(0));
+ this->value[1] = col_type(m[1], T(0));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x4<T>::tmat2x4
+ (
+ tmat3x2<T> const & m
+ )
+ {
+ this->value[0] = col_type(m[0], detail::tvec2<T>(0));
+ this->value[1] = col_type(m[1], detail::tvec2<T>(0));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x4<T>::tmat2x4
+ (
+ tmat3x4<T> const & m
+ )
+ {
+ this->value[0] = m[0];
+ this->value[1] = m[1];
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x4<T>::tmat2x4
+ (
+ tmat4x2<T> const & m
+ )
+ {
+ this->value[0] = col_type(m[0], detail::tvec2<T>(T(0)));
+ this->value[1] = col_type(m[1], detail::tvec2<T>(T(0)));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x4<T>::tmat2x4
+ (
+ tmat4x3<T> const & m
+ )
+ {
+ this->value[0] = col_type(m[0], T(0));
+ this->value[1] = col_type(m[1], T(0));
+ }
+
+ //////////////////////////////////////////////////////////////
+ // Unary updatable operators
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x4<T>& tmat2x4<T>::operator=
+ (
+ tmat2x4<T> const & m
+ )
+ {
+ this->value[0] = m[0];
+ this->value[1] = m[1];
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat2x4<T>& tmat2x4<T>::operator=
+ (
+ tmat2x4<U> const & m
+ )
+ {
+ this->value[0] = m[0];
+ this->value[1] = m[1];
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat2x4<T>& tmat2x4<T>::operator+=
+ (
+ U const & s
+ )
+ {
+ this->value[0] += s;
+ this->value[1] += s;
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat2x4<T>& tmat2x4<T>::operator+=
+ (
+ tmat2x4<U> const & m
+ )
+ {
+ this->value[0] += m[0];
+ this->value[1] += m[1];
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat2x4<T>& tmat2x4<T>::operator-=
+ (
+ U const & s
+ )
+ {
+ this->value[0] -= s;
+ this->value[1] -= s;
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat2x4<T>& tmat2x4<T>::operator-=
+ (
+ tmat2x4<U> const & m
+ )
+ {
+ this->value[0] -= m[0];
+ this->value[1] -= m[1];
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat2x4<T>& tmat2x4<T>::operator*=
+ (
+ U const & s
+ )
+ {
+ this->value[0] *= s;
+ this->value[1] *= s;
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat2x4<T>& tmat2x4<T>::operator*=
+ (
+ tmat2x4<U> const & m
+ )
+ {
+ return (*this = tmat2x4<T>(*this * m));
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat2x4<T> & tmat2x4<T>::operator/=
+ (
+ U const & s
+ )
+ {
+ this->value[0] /= s;
+ this->value[1] /= s;
+ return *this;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x4<T>& tmat2x4<T>::operator++ ()
+ {
+ ++this->value[0];
+ ++this->value[1];
+ return *this;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x4<T>& tmat2x4<T>::operator-- ()
+ {
+ --this->value[0];
+ --this->value[1];
+ return *this;
+ }
+
+ //////////////////////////////////////////////////////////////
+ // Binary operators
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x4<T> operator+
+ (
+ tmat2x4<T> const & m,
+ typename tmat2x4<T>::value_type const & s
+ )
+ {
+ return tmat2x4<T>(
+ m[0] + s,
+ m[1] + s);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x4<T> operator+
+ (
+ tmat2x4<T> const & m1,
+ tmat2x4<T> const & m2
+ )
+ {
+ return tmat2x4<T>(
+ m1[0] + m2[0],
+ m1[1] + m2[1]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x4<T> operator-
+ (
+ tmat2x4<T> const & m,
+ typename tmat2x4<T>::value_type const & s
+ )
+ {
+ return tmat2x4<T>(
+ m[0] - s,
+ m[1] - s);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x4<T> operator-
+ (
+ tmat2x4<T> const & m1,
+ tmat2x4<T> const & m2
+ )
+ {
+ return tmat2x4<T>(
+ m1[0] - m2[0],
+ m1[1] - m2[1]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x4<T> operator*
+ (
+ tmat2x4<T> const & m,
+ typename tmat2x4<T>::value_type const & s
+ )
+ {
+ return tmat2x4<T>(
+ m[0] * s,
+ m[1] * s);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x4<T> operator*
+ (
+ typename tmat2x4<T>::value_type const & s,
+ tmat2x4<T> const & m
+ )
+ {
+ return tmat2x4<T>(
+ m[0] * s,
+ m[1] * s);
+ }
+
+ // X
+ // X
+ // X X
+ // X X
+ // X X
+ // X X
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename tmat2x4<T>::col_type operator*
+ (
+ tmat2x4<T> const & m,
+ typename tmat2x4<T>::row_type const & v
+ )
+ {
+ return typename tmat2x4<T>::col_type(
+ m[0][0] * v.x + m[1][0] * v.y,
+ m[0][1] * v.x + m[1][1] * v.y,
+ m[0][2] * v.x + m[1][2] * v.y,
+ m[0][3] * v.x + m[1][3] * v.y);
+ }
+
+ // X X
+ // X X
+ // X X
+ // X X
+ // X X X X
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename tmat2x4<T>::row_type operator*
+ (
+ typename tmat2x4<T>::col_type const & v,
+ tmat2x4<T> const & m
+ )
+ {
+ return typename tmat2x4<T>::row_type(
+ v.x * m[0][0] + v.y * m[0][1] + v.z * m[0][2] + v.w * m[0][3],
+ v.x * m[1][0] + v.y * m[1][1] + v.z * m[1][2] + v.w * m[1][3]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x4<T> operator*
+ (
+ tmat2x4<T> const & m1,
+ tmat4x2<T> const & m2
+ )
+ {
+ typename tmat2x4<T>::value_type SrcA00 = m1[0][0];
+ typename tmat2x4<T>::value_type SrcA01 = m1[0][1];
+ typename tmat2x4<T>::value_type SrcA02 = m1[0][2];
+ typename tmat2x4<T>::value_type SrcA03 = m1[0][3];
+ typename tmat2x4<T>::value_type SrcA10 = m1[1][0];
+ typename tmat2x4<T>::value_type SrcA11 = m1[1][1];
+ typename tmat2x4<T>::value_type SrcA12 = m1[1][2];
+ typename tmat2x4<T>::value_type SrcA13 = m1[1][3];
+
+ typename tmat2x4<T>::value_type SrcB00 = m2[0][0];
+ typename tmat2x4<T>::value_type SrcB01 = m2[0][1];
+ typename tmat2x4<T>::value_type SrcB10 = m2[1][0];
+ typename tmat2x4<T>::value_type SrcB11 = m2[1][1];
+ typename tmat2x4<T>::value_type SrcB20 = m2[2][0];
+ typename tmat2x4<T>::value_type SrcB21 = m2[2][1];
+ typename tmat2x4<T>::value_type SrcB30 = m2[3][0];
+ typename tmat2x4<T>::value_type SrcB31 = m2[3][1];
+
+ tmat4x4<T> Result(tmat4x4<T>::null);
+ Result[0][0] = SrcA00 * SrcB00 + SrcA10 * SrcB01;
+ Result[0][1] = SrcA01 * SrcB00 + SrcA11 * SrcB01;
+ Result[0][2] = SrcA02 * SrcB00 + SrcA12 * SrcB01;
+ Result[0][3] = SrcA03 * SrcB00 + SrcA13 * SrcB01;
+ Result[1][0] = SrcA00 * SrcB10 + SrcA10 * SrcB11;
+ Result[1][1] = SrcA01 * SrcB10 + SrcA11 * SrcB11;
+ Result[1][2] = SrcA02 * SrcB10 + SrcA12 * SrcB11;
+ Result[1][3] = SrcA03 * SrcB10 + SrcA13 * SrcB11;
+ Result[2][0] = SrcA00 * SrcB20 + SrcA10 * SrcB21;
+ Result[2][1] = SrcA01 * SrcB20 + SrcA11 * SrcB21;
+ Result[2][2] = SrcA02 * SrcB20 + SrcA12 * SrcB21;
+ Result[2][3] = SrcA03 * SrcB20 + SrcA13 * SrcB21;
+ Result[3][0] = SrcA00 * SrcB30 + SrcA10 * SrcB31;
+ Result[3][1] = SrcA01 * SrcB30 + SrcA11 * SrcB31;
+ Result[3][2] = SrcA02 * SrcB30 + SrcA12 * SrcB31;
+ Result[3][3] = SrcA03 * SrcB30 + SrcA13 * SrcB31;
+ return Result;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x4<T> operator/
+ (
+ tmat2x4<T> const & m,
+ typename tmat2x4<T>::value_type const & s
+ )
+ {
+ return tmat2x4<T>(
+ m[0] / s,
+ m[1] / s);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x4<T> operator/
+ (
+ typename tmat2x4<T>::value_type const & s,
+ tmat2x4<T> const & m
+ )
+ {
+ return tmat2x4<T>(
+ s / m[0],
+ s / m[1]);
+ }
+
+ // Unary constant operators
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x4<T> const operator-
+ (
+ tmat2x4<T> const & m
+ )
+ {
+ return tmat2x4<T>(
+ -m[0],
+ -m[1]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x4<T> const operator++
+ (
+ tmat2x4<T> const & m,
+ int
+ )
+ {
+ return tmat2x4<T>(
+ m[0] + typename tmat2x4<T>::value_type(1),
+ m[1] + typename tmat2x4<T>::value_type(1));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x4<T> const operator--
+ (
+ tmat2x4<T> const & m,
+ int
+ )
+ {
+ return tmat2x4<T>(
+ m[0] - typename tmat2x4<T>::value_type(1),
+ m[1] - typename tmat2x4<T>::value_type(1));
+ }
+
+ //////////////////////////////////////
+ // Boolean operators
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER bool operator==
+ (
+ tmat2x4<T> const & m1,
+ tmat2x4<T> const & m2
+ )
+ {
+ return (m1[0] == m2[0]) && (m1[1] == m2[1]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER bool operator!=
+ (
+ tmat2x4<T> const & m1,
+ tmat2x4<T> const & m2
+ )
+ {
+ return (m1[0] != m2[0]) || (m1[1] != m2[1]);
+ }
+
+} //namespace detail
+} //namespace glm
diff --git a/src/glm/core/type_mat3x2.hpp b/src/glm/core/type_mat3x2.hpp
new file mode 100644
index 0000000..1a89835
--- /dev/null
+++ b/src/glm/core/type_mat3x2.hpp
@@ -0,0 +1,231 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2006-08-05
+// Updated : 2010-02-05
+// Licence : This source is under MIT License
+// File : glm/core/type_mat3x2.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_core_type_mat3x2
+#define glm_core_type_mat3x2
+
+#include "type_mat.hpp"
+
+namespace glm{
+namespace detail
+{
+ template <typename T> struct tvec1;
+ template <typename T> struct tvec2;
+ template <typename T> struct tvec3;
+ template <typename T> struct tvec4;
+ template <typename T> struct tmat2x2;
+ template <typename T> struct tmat2x3;
+ template <typename T> struct tmat2x4;
+ template <typename T> struct tmat3x2;
+ template <typename T> struct tmat3x3;
+ template <typename T> struct tmat3x4;
+ template <typename T> struct tmat4x2;
+ template <typename T> struct tmat4x3;
+ template <typename T> struct tmat4x4;
+
+ //! \brief Template for 3 columns and 2 rows matrix of floating-point numbers.
+ //! \ingroup core_template
+ template <typename T>
+ struct tmat3x2
+ {
+ enum ctor{null};
+ typedef T value_type;
+ typedef std::size_t size_type;
+ typedef tvec2<T> col_type;
+ typedef tvec3<T> row_type;
+ static GLM_FUNC_DECL size_type col_size();
+ static GLM_FUNC_DECL size_type row_size();
+
+ typedef tmat3x2<T> type;
+ typedef tmat2x3<T> transpose_type;
+
+ private:
+ // Data
+ col_type value[3];
+
+ public:
+ // Constructors
+ GLM_FUNC_DECL tmat3x2();
+ GLM_FUNC_DECL tmat3x2(tmat3x2 const & m);
+
+ GLM_FUNC_DECL explicit tmat3x2(
+ ctor);
+ GLM_FUNC_DECL explicit tmat3x2(
+ value_type const & s);
+ GLM_FUNC_DECL explicit tmat3x2(
+ value_type const & x0, value_type const & y0,
+ value_type const & x1, value_type const & y1,
+ value_type const & x2, value_type const & y2);
+ GLM_FUNC_DECL explicit tmat3x2(
+ col_type const & v0,
+ col_type const & v1,
+ col_type const & v2);
+
+ //////////////////////////////////////
+ // Conversions
+ template <typename U>
+ GLM_FUNC_DECL explicit tmat3x2(
+ U const & x);
+
+ template
+ <
+ typename X1, typename Y1,
+ typename X2, typename Y2,
+ typename X3, typename Y3
+ >
+ GLM_FUNC_DECL explicit tmat3x2(
+ X1 const & x1, Y1 const & y1,
+ X2 const & x2, Y2 const & y2,
+ X3 const & x3, Y3 const & y3);
+
+ template <typename V1, typename V2, typename V3>
+ GLM_FUNC_DECL explicit tmat3x2(
+ tvec2<V1> const & v1,
+ tvec2<V2> const & v2,
+ tvec2<V3> const & v3);
+
+ // Matrix conversions
+ template <typename U>
+ GLM_FUNC_DECL explicit tmat3x2(tmat3x2<U> const & m);
+
+ GLM_FUNC_DECL explicit tmat3x2(tmat2x2<T> const & x);
+ GLM_FUNC_DECL explicit tmat3x2(tmat3x3<T> const & x);
+ GLM_FUNC_DECL explicit tmat3x2(tmat4x4<T> const & x);
+ GLM_FUNC_DECL explicit tmat3x2(tmat2x3<T> const & x);
+ GLM_FUNC_DECL explicit tmat3x2(tmat2x4<T> const & x);
+ GLM_FUNC_DECL explicit tmat3x2(tmat3x4<T> const & x);
+ GLM_FUNC_DECL explicit tmat3x2(tmat4x2<T> const & x);
+ GLM_FUNC_DECL explicit tmat3x2(tmat4x3<T> const & x);
+
+ // Accesses
+ GLM_FUNC_DECL col_type & operator[](size_type i);
+ GLM_FUNC_DECL col_type const & operator[](size_type i) const;
+
+ // Unary updatable operators
+ GLM_FUNC_DECL tmat3x2<T> & operator= (tmat3x2<T> const & m);
+ template <typename U>
+ GLM_FUNC_DECL tmat3x2<T> & operator= (tmat3x2<U> const & m);
+ template <typename U>
+ GLM_FUNC_DECL tmat3x2<T> & operator+= (U const & s);
+ template <typename U>
+ GLM_FUNC_DECL tmat3x2<T> & operator+= (tmat3x2<U> const & m);
+ template <typename U>
+ GLM_FUNC_DECL tmat3x2<T> & operator-= (U const & s);
+ template <typename U>
+ GLM_FUNC_DECL tmat3x2<T> & operator-= (tmat3x2<U> const & m);
+ template <typename U>
+ GLM_FUNC_DECL tmat3x2<T> & operator*= (U const & s);
+ template <typename U>
+ GLM_FUNC_DECL tmat3x2<T> & operator*= (tmat3x2<U> const & m);
+ template <typename U>
+ GLM_FUNC_DECL tmat3x2<T> & operator/= (U const & s);
+
+ GLM_FUNC_DECL tmat3x2<T> & operator++ ();
+ GLM_FUNC_DECL tmat3x2<T> & operator-- ();
+ };
+
+ // Binary operators
+ template <typename T>
+ tmat3x2<T> operator+ (
+ tmat3x2<T> const & m,
+ typename tmat3x2<T>::value_type const & s);
+
+ template <typename T>
+ tmat3x2<T> operator+ (
+ tmat3x2<T> const & m1,
+ tmat3x2<T> const & m2);
+
+ template <typename T>
+ tmat3x2<T> operator- (
+ tmat3x2<T> const & m,
+ typename tmat3x2<T>::value_type const & s);
+
+ template <typename T>
+ tmat3x2<T> operator- (
+ tmat3x2<T> const & m1,
+ tmat3x2<T> const & m2);
+
+ template <typename T>
+ tmat3x2<T> operator* (
+ tmat3x2<T> const & m,
+ typename tmat3x2<T>::value_type const & s);
+
+ template <typename T>
+ tmat3x2<T> operator* (
+ typename tmat3x2<T>::value_type const & s,
+ tmat3x2<T> const & m);
+
+ template <typename T>
+ typename tmat3x2<T>::col_type operator* (
+ tmat3x2<T> const & m,
+ typename tmat3x2<T>::row_type const & v);
+
+ template <typename T>
+ typename tmat3x2<T>::row_type operator* (
+ typename tmat3x2<T>::col_type const & v,
+ tmat3x2<T> const & m);
+
+ template <typename T>
+ tmat2x2<T> operator* (
+ tmat3x2<T> const & m1,
+ tmat2x3<T> const & m2);
+
+ template <typename T>
+ tmat3x2<T> operator/ (
+ tmat3x2<T> const & m,
+ typename tmat3x2<T>::value_type const & s);
+
+ template <typename T>
+ tmat3x2<T> operator/ (
+ typename tmat3x2<T>::value_type const & s,
+ tmat3x2<T> const & m);
+
+ // Unary constant operators
+ template <typename T>
+ tmat3x2<T> const operator- (
+ tmat3x2<T> const & m);
+
+ template <typename T>
+ tmat3x2<T> const operator-- (
+ tmat3x2<T> const & m,
+ int);
+
+ template <typename T>
+ tmat3x2<T> const operator++ (
+ tmat3x2<T> const & m,
+ int);
+
+} //namespace detail
+
+namespace core{
+namespace type{
+namespace precision
+{
+ //! 3 columns of 2 components matrix of low precision floating-point numbers.
+ //! There is no guarantee on the actual precision.
+ //! (From GLSL 1.30.8 specification, section 4.1.6 Matrices and section 4.5 Precision and Precision Qualifiers)
+ typedef detail::tmat3x2<lowp_float> lowp_mat3x2;
+ //! 3 columns of 2 components matrix of medium precision floating-point numbers.
+ //! There is no guarantee on the actual precision.
+ //! (From GLSL 1.30.8 specification, section 4.1.6 Matrices and section 4.5 Precision and Precision Qualifiers)
+ typedef detail::tmat3x2<mediump_float> mediump_mat3x2;
+ //! 3 columns of 2 components matrix of high precision floating-point numbers.
+ //! There is no guarantee on the actual precision.
+ //! (From GLSL 1.30.8 specification, section 4.1.6 Matrices and section 4.5 Precision and Precision Qualifiers)
+ typedef detail::tmat3x2<highp_float> highp_mat3x2;
+}//namespace precision
+}//namespace type
+}//namespace core
+}//namespace glm
+
+#ifndef GLM_EXTERNAL_TEMPLATE
+#include "type_mat3x2.inl"
+#endif
+
+#endif //glm_core_type_mat3x2
diff --git a/src/glm/core/type_mat3x2.inl b/src/glm/core/type_mat3x2.inl
new file mode 100644
index 0000000..51e56a4
--- /dev/null
+++ b/src/glm/core/type_mat3x2.inl
@@ -0,0 +1,623 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2006-08-05
+// Updated : 2010-01-05
+// Licence : This source is under MIT License
+// File : glm/core/type_mat3x2.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm{
+namespace detail
+{
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename tmat3x2<T>::size_type tmat3x2<T>::col_size()
+ {
+ return 2;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename tmat3x2<T>::size_type tmat3x2<T>::row_size()
+ {
+ return 3;
+ }
+
+ //////////////////////////////////////
+ // Accesses
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename tmat3x2<T>::col_type &
+ tmat3x2<T>::operator[]
+ (
+ size_type i
+ )
+ {
+ assert(i < this->row_size());
+ return this->value[i];
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename tmat3x2<T>::col_type const &
+ tmat3x2<T>::operator[]
+ (
+ size_type i
+ ) const
+ {
+ assert(i < this->row_size());
+ return this->value[i];
+ }
+
+ //////////////////////////////////////////////////////////////
+ // Constructors
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x2<T>::tmat3x2()
+ {
+ this->value[0] = col_type(1, 0);
+ this->value[1] = col_type(0, 1);
+ this->value[2] = col_type(0, 0);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x2<T>::tmat3x2
+ (
+ tmat3x2<T> const & m
+ )
+ {
+ this->value[0] = m.value[0];
+ this->value[1] = m.value[1];
+ this->value[2] = m.value[2];
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x2<T>::tmat3x2
+ (
+ ctor
+ )
+ {}
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x2<T>::tmat3x2
+ (
+ value_type const & s
+ )
+ {
+ this->value[0] = col_type(s, 0);
+ this->value[1] = col_type(0, s);
+ this->value[2] = col_type(0, 0);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x2<T>::tmat3x2
+ (
+ value_type const & x0, value_type const & y0,
+ value_type const & x1, value_type const & y1,
+ value_type const & x2, value_type const & y2
+ )
+ {
+ this->value[0] = col_type(x0, y0);
+ this->value[1] = col_type(x1, y1);
+ this->value[2] = col_type(x2, y2);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x2<T>::tmat3x2
+ (
+ col_type const & v0,
+ col_type const & v1,
+ col_type const & v2
+ )
+ {
+ this->value[0] = v0;
+ this->value[1] = v1;
+ this->value[2] = v2;
+ }
+
+ //////////////////////////////////////
+ // Convertion constructors
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_DECL tmat3x2<T>::tmat3x2
+ (
+ U const & s
+ )
+ {
+ value_type const Zero(0);
+ this->value[0] = tvec2<T>(value_type(s), Zero);
+ this->value[1] = tvec2<T>(Zero, value_type(s));
+ this->value[2] = tvec2<T>(Zero);
+ }
+
+ template <typename T>
+ template <
+ typename X1, typename Y1,
+ typename X2, typename Y2,
+ typename X3, typename Y3>
+ GLM_FUNC_DECL tmat3x2<T>::tmat3x2
+ (
+ X1 const & x1, Y1 const & y1,
+ X2 const & x2, Y2 const & y2,
+ X3 const & x3, Y3 const & y3
+ )
+ {
+ this->value[0] = col_type(value_type(x1), value_type(y1));
+ this->value[1] = col_type(value_type(x2), value_type(y2));
+ this->value[2] = col_type(value_type(x3), value_type(y3));
+ }
+
+ template <typename T>
+ template <typename V1, typename V2, typename V3>
+ GLM_FUNC_DECL tmat3x2<T>::tmat3x2
+ (
+ tvec2<V1> const & v1,
+ tvec2<V2> const & v2,
+ tvec2<V3> const & v3
+ )
+ {
+ this->value[0] = col_type(v1);
+ this->value[1] = col_type(v2);
+ this->value[2] = col_type(v3);
+ }
+
+ //////////////////////////////////////////////////////////////
+ // mat3x2 matrix conversions
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat3x2<T>::tmat3x2
+ (
+ tmat3x2<U> const & m
+ )
+ {
+ this->value[0] = col_type(m[0]);
+ this->value[1] = col_type(m[1]);
+ this->value[2] = col_type(m[2]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x2<T>::tmat3x2
+ (
+ tmat2x2<T> const & m
+ )
+ {
+ this->value[0] = m[0];
+ this->value[1] = m[1];
+ this->value[2] = col_type(T(0));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x2<T>::tmat3x2
+ (
+ tmat3x3<T> const & m
+ )
+ {
+ this->value[0] = col_type(m[0]);
+ this->value[1] = col_type(m[1]);
+ this->value[2] = col_type(m[2]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x2<T>::tmat3x2
+ (
+ tmat4x4<T> const & m
+ )
+ {
+ this->value[0] = col_type(m[0]);
+ this->value[1] = col_type(m[1]);
+ this->value[2] = col_type(m[2]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x2<T>::tmat3x2
+ (
+ tmat2x3<T> const & m
+ )
+ {
+ this->value[0] = col_type(m[0]);
+ this->value[1] = col_type(m[1]);
+ this->value[2] = col_type(T(0));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x2<T>::tmat3x2
+ (
+ tmat2x4<T> const & m
+ )
+ {
+ this->value[0] = col_type(m[0]);
+ this->value[1] = col_type(m[1]);
+ this->value[2] = col_type(T(0));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x2<T>::tmat3x2
+ (
+ tmat3x4<T> const & m
+ )
+ {
+ this->value[0] = col_type(m[0]);
+ this->value[1] = col_type(m[1]);
+ this->value[2] = col_type(m[2]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x2<T>::tmat3x2
+ (
+ tmat4x2<T> const & m
+ )
+ {
+ this->value[0] = m[0];
+ this->value[1] = m[1];
+ this->value[2] = m[2];
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x2<T>::tmat3x2
+ (
+ tmat4x3<T> const & m
+ )
+ {
+ this->value[0] = col_type(m[0]);
+ this->value[1] = col_type(m[1]);
+ this->value[2] = col_type(m[2]);
+ }
+
+ //////////////////////////////////////////////////////////////
+ // Unary updatable operators
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x2<T>& tmat3x2<T>::operator=
+ (
+ tmat3x2<T> const & m
+ )
+ {
+ this->value[0] = m[0];
+ this->value[1] = m[1];
+ this->value[2] = m[2];
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat3x2<T>& tmat3x2<T>::operator=
+ (
+ tmat3x2<U> const & m
+ )
+ {
+ this->value[0] = m[0];
+ this->value[1] = m[1];
+ this->value[2] = m[2];
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat3x2<T>& tmat3x2<T>::operator+=
+ (
+ U const & s
+ )
+ {
+ this->value[0] += s;
+ this->value[1] += s;
+ this->value[2] += s;
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat3x2<T>& tmat3x2<T>::operator+=
+ (
+ tmat3x2<U> const & m
+ )
+ {
+ this->value[0] += m[0];
+ this->value[1] += m[1];
+ this->value[2] += m[2];
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat3x2<T>& tmat3x2<T>::operator-=
+ (
+ U const & s
+ )
+ {
+ this->value[0] -= s;
+ this->value[1] -= s;
+ this->value[2] -= s;
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat3x2<T>& tmat3x2<T>::operator-=
+ (
+ tmat3x2<U> const & m
+ )
+ {
+ this->value[0] -= m[0];
+ this->value[1] -= m[1];
+ this->value[2] -= m[2];
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat3x2<T>& tmat3x2<T>::operator*=
+ (
+ U const & s
+ )
+ {
+ this->value[0] *= s;
+ this->value[1] *= s;
+ this->value[2] *= s;
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat3x2<T>& tmat3x2<T>::operator*=
+ (
+ tmat3x2<U> const & m
+ )
+ {
+ return (*this = tmat3x2<T>(*this * m));
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat3x2<T> & tmat3x2<T>::operator/=
+ (
+ U const & s
+ )
+ {
+ this->value[0] /= s;
+ this->value[1] /= s;
+ this->value[2] /= s;
+ return *this;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x2<T>& tmat3x2<T>::operator++ ()
+ {
+ ++this->value[0];
+ ++this->value[1];
+ ++this->value[2];
+ return *this;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x2<T>& tmat3x2<T>::operator-- ()
+ {
+ --this->value[0];
+ --this->value[1];
+ --this->value[2];
+ return *this;
+ }
+
+ //////////////////////////////////////////////////////////////
+ // Binary operators
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x2<T> operator+
+ (
+ tmat3x2<T> const & m,
+ typename tmat3x2<T>::value_type const & s
+ )
+ {
+ return tmat3x2<T>(
+ m[0] + s,
+ m[1] + s,
+ m[2] + s);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x2<T> operator+
+ (
+ tmat3x2<T> const & m1,
+ tmat3x2<T> const & m2
+ )
+ {
+ return tmat3x2<T>(
+ m1[0] + m2[0],
+ m1[1] + m2[1],
+ m1[2] + m2[2]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x2<T> operator-
+ (
+ tmat3x2<T> const & m,
+ typename tmat3x2<T>::value_type const & s
+ )
+ {
+ return tmat3x2<T>(
+ m[0] - s,
+ m[1] - s,
+ m[2] - s);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x2<T> operator-
+ (
+ tmat3x2<T> const & m1,
+ tmat3x2<T> const & m2
+ )
+ {
+ return tmat3x2<T>(
+ m1[0] - m2[0],
+ m1[1] - m2[1],
+ m1[2] - m2[2]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x2<T> operator*
+ (
+ tmat3x2<T> const & m,
+ typename tmat3x2<T>::value_type const & s
+ )
+ {
+ return tmat3x2<T>(
+ m[0] * s,
+ m[1] * s,
+ m[2] * s);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x2<T> operator*
+ (
+ typename tmat3x2<T>::value_type const & s,
+ tmat3x2<T> const & m
+ )
+ {
+ return tmat3x2<T>(
+ m[0] * s,
+ m[1] * s,
+ m[2] * s);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename tmat3x2<T>::col_type operator*
+ (
+ tmat3x2<T> const & m,
+ typename tmat3x2<T>::row_type const & v)
+ {
+ return typename tmat3x2<T>::col_type(
+ m[0][0] * v.x + m[1][0] * v.y + m[2][0] * v.z,
+ m[0][1] * v.x + m[1][1] * v.y + m[2][1] * v.z);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename tmat3x2<T>::row_type operator*
+ (
+ typename tmat3x2<T>::col_type const & v,
+ tmat3x2<T> const & m)
+ {
+ return typename tmat3x2<T>::row_type(
+ v.x * m[0][0] + v.y * m[0][1],
+ v.x * m[1][0] + v.y * m[1][1],
+ v.x * m[2][0] + v.y * m[2][1]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x2<T> operator*
+ (
+ tmat3x2<T> const & m1,
+ tmat2x3<T> const & m2
+ )
+ {
+ const T SrcA00 = m1[0][0];
+ const T SrcA01 = m1[0][1];
+ const T SrcA10 = m1[1][0];
+ const T SrcA11 = m1[1][1];
+ const T SrcA20 = m1[2][0];
+ const T SrcA21 = m1[2][1];
+
+ const T SrcB00 = m2[0][0];
+ const T SrcB01 = m2[0][1];
+ const T SrcB02 = m2[0][2];
+ const T SrcB10 = m2[1][0];
+ const T SrcB11 = m2[1][1];
+ const T SrcB12 = m2[1][2];
+
+ tmat2x2<T> Result(tmat2x2<T>::null);
+ Result[0][0] = SrcA00 * SrcB00 + SrcA10 * SrcB01 + SrcA20 * SrcB02;
+ Result[0][1] = SrcA01 * SrcB00 + SrcA11 * SrcB01 + SrcA21 * SrcB02;
+ Result[1][0] = SrcA00 * SrcB10 + SrcA10 * SrcB11 + SrcA20 * SrcB12;
+ Result[1][1] = SrcA01 * SrcB10 + SrcA11 * SrcB11 + SrcA21 * SrcB12;
+ return Result;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x2<T> operator/
+ (
+ tmat3x2<T> const & m,
+ typename tmat3x2<T>::value_type const & s
+ )
+ {
+ return tmat3x2<T>(
+ m[0] / s,
+ m[1] / s,
+ m[2] / s);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x2<T> operator/
+ (
+ typename tmat3x2<T>::value_type const & s,
+ tmat3x2<T> const & m
+ )
+ {
+ return tmat3x2<T>(
+ s / m[0],
+ s / m[1],
+ s / m[2]);
+ }
+
+ // Unary constant operators
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x2<T> const operator-
+ (
+ tmat3x2<T> const & m
+ )
+ {
+ return tmat3x2<T>(
+ -m[0],
+ -m[1],
+ -m[2]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x2<T> const operator++
+ (
+ tmat3x2<T> const & m,
+ int
+ )
+ {
+ typename tmat3x2<T>::value_type One(1);
+ return tmat3x2<T>(
+ m[0] + One,
+ m[1] + One,
+ m[2] + One);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x2<T> const operator--
+ (
+ tmat3x2<T> const & m,
+ int
+ )
+ {
+ typename tmat3x2<T>::value_type One(1);
+ return tmat3x2<T>(
+ m[0] - One,
+ m[1] - One,
+ m[2] - One);
+ }
+
+ //////////////////////////////////////
+ // Boolean operators
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER bool operator==
+ (
+ tmat3x2<T> const & m1,
+ tmat3x2<T> const & m2
+ )
+ {
+ return (m1[0] == m2[0]) && (m1[1] == m2[1]) && (m1[2] == m2[2]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER bool operator!=
+ (
+ tmat3x2<T> const & m1,
+ tmat3x2<T> const & m2
+ )
+ {
+ return (m1[0] != m2[0]) || (m1[1] != m2[1]) || (m1[2] != m2[2]);
+ }
+
+} //namespace detail
+} //namespace glm
diff --git a/src/glm/core/type_mat3x3.hpp b/src/glm/core/type_mat3x3.hpp
new file mode 100644
index 0000000..36a695f
--- /dev/null
+++ b/src/glm/core/type_mat3x3.hpp
@@ -0,0 +1,283 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2005-01-27
+// Updated : 2010-02-03
+// Licence : This source is under MIT License
+// File : glm/core/type_mat3x3.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_core_type_mat3x3
+#define glm_core_type_mat3x3
+
+#include "type_mat.hpp"
+
+namespace glm{
+namespace detail
+{
+ template <typename T> struct tvec1;
+ template <typename T> struct tvec2;
+ template <typename T> struct tvec3;
+ template <typename T> struct tvec4;
+ template <typename T> struct tmat2x2;
+ template <typename T> struct tmat2x3;
+ template <typename T> struct tmat2x4;
+ template <typename T> struct tmat3x2;
+ template <typename T> struct tmat3x3;
+ template <typename T> struct tmat3x4;
+ template <typename T> struct tmat4x2;
+ template <typename T> struct tmat4x3;
+ template <typename T> struct tmat4x4;
+
+ //! \brief Template for 3 * 3 matrix of floating-point numbers.
+ //! \ingroup core_template
+ template <typename T>
+ struct tmat3x3
+ {
+ enum ctor{null};
+ typedef T value_type;
+ typedef std::size_t size_type;
+ typedef tvec3<T> col_type;
+ typedef tvec3<T> row_type;
+ static GLM_FUNC_DECL size_type col_size();
+ static GLM_FUNC_DECL size_type row_size();
+
+ typedef tmat3x3<T> type;
+ typedef tmat3x3<T> transpose_type;
+
+ public:
+ // Implementation detail
+ GLM_FUNC_DECL tmat3x3<T> _inverse() const;
+
+ private:
+ // Data
+ col_type value[3];
+
+ public:
+ // Constructors
+ GLM_FUNC_DECL tmat3x3();
+ GLM_FUNC_DECL tmat3x3(tmat3x3 const & m);
+
+ GLM_FUNC_DECL explicit tmat3x3(
+ ctor Null);
+ GLM_FUNC_DECL explicit tmat3x3(
+ value_type const & s);
+ GLM_FUNC_DECL explicit tmat3x3(
+ value_type const & x0, value_type const & y0, value_type const & z0,
+ value_type const & x1, value_type const & y1, value_type const & z1,
+ value_type const & x2, value_type const & y2, value_type const & z2);
+ GLM_FUNC_DECL explicit tmat3x3(
+ col_type const & v0,
+ col_type const & v1,
+ col_type const & v2);
+
+ //////////////////////////////////////
+ // Conversions
+ template <typename U>
+ GLM_FUNC_DECL explicit tmat3x3(
+ U const & x);
+
+ template
+ <
+ typename X1, typename Y1, typename Z1,
+ typename X2, typename Y2, typename Z2,
+ typename X3, typename Y3, typename Z3
+ >
+ GLM_FUNC_DECL explicit tmat3x3(
+ X1 const & x1, Y1 const & y1, Z1 const & z1,
+ X2 const & x2, Y2 const & y2, Z2 const & z2,
+ X3 const & x3, Y3 const & y3, Z3 const & z3);
+
+ template <typename V1, typename V2, typename V3>
+ GLM_FUNC_DECL explicit tmat3x3(
+ tvec3<V1> const & v1,
+ tvec3<V2> const & v2,
+ tvec3<V3> const & v3);
+
+ // Matrix conversions
+ template <typename U>
+ GLM_FUNC_DECL explicit tmat3x3(tmat3x3<U> const & m);
+
+ GLM_FUNC_DECL explicit tmat3x3(tmat2x2<T> const & x);
+ GLM_FUNC_DECL explicit tmat3x3(tmat4x4<T> const & x);
+ GLM_FUNC_DECL explicit tmat3x3(tmat2x3<T> const & x);
+ GLM_FUNC_DECL explicit tmat3x3(tmat3x2<T> const & x);
+ GLM_FUNC_DECL explicit tmat3x3(tmat2x4<T> const & x);
+ GLM_FUNC_DECL explicit tmat3x3(tmat4x2<T> const & x);
+ GLM_FUNC_DECL explicit tmat3x3(tmat3x4<T> const & x);
+ GLM_FUNC_DECL explicit tmat3x3(tmat4x3<T> const & x);
+
+ // Accesses
+ GLM_FUNC_DECL col_type & operator[](size_type i);
+ GLM_FUNC_DECL col_type const & operator[](size_type i) const;
+
+ // Unary updatable operators
+ GLM_FUNC_DECL tmat3x3<T>& operator= (tmat3x3<T> const & m);
+ template <typename U>
+ GLM_FUNC_DECL tmat3x3<T>& operator= (tmat3x3<U> const & m);
+ template <typename U>
+ GLM_FUNC_DECL tmat3x3<T>& operator+= (U const & s);
+ template <typename U>
+ GLM_FUNC_DECL tmat3x3<T>& operator+= (tmat3x3<U> const & m);
+ template <typename U>
+ GLM_FUNC_DECL tmat3x3<T>& operator-= (U const & s);
+ template <typename U>
+ GLM_FUNC_DECL tmat3x3<T>& operator-= (tmat3x3<U> const & m);
+ template <typename U>
+ GLM_FUNC_DECL tmat3x3<T>& operator*= (U const & s);
+ template <typename U>
+ GLM_FUNC_DECL tmat3x3<T>& operator*= (tmat3x3<U> const & m);
+ template <typename U>
+ GLM_FUNC_DECL tmat3x3<T>& operator/= (U const & s);
+ template <typename U>
+ GLM_FUNC_DECL tmat3x3<T>& operator/= (tmat3x3<U> const & m);
+ GLM_FUNC_DECL tmat3x3<T>& operator++ ();
+ GLM_FUNC_DECL tmat3x3<T>& operator-- ();
+ };
+
+ // Binary operators
+ template <typename T>
+ tmat3x3<T> operator+ (
+ tmat3x3<T> const & m,
+ typename tmat3x3<T>::value_type const & s);
+
+ template <typename T>
+ tmat3x3<T> operator+ (
+ typename tmat3x3<T>::value_type const & s,
+ tmat3x3<T> const & m);
+
+ template <typename T>
+ tmat3x3<T> operator+ (
+ tmat3x3<T> const & m1,
+ tmat3x3<T> const & m2);
+
+ template <typename T>
+ tmat3x3<T> operator- (
+ tmat3x3<T> const & m,
+ typename tmat3x3<T>::value_type const & s);
+
+ template <typename T>
+ tmat3x3<T> operator- (
+ typename tmat3x3<T>::value_type const & s,
+ tmat3x3<T> const & m);
+
+ template <typename T>
+ tmat3x3<T> operator- (
+ tmat3x3<T> const & m1,
+ tmat3x3<T> const & m2);
+
+ template <typename T>
+ tmat3x3<T> operator* (
+ tmat3x3<T> const & m,
+ typename tmat3x3<T>::value_type const & s);
+
+ template <typename T>
+ tmat3x3<T> operator* (
+ typename tmat3x3<T>::value_type const & s,
+ tmat3x3<T> const & m);
+
+ template <typename T>
+ typename tmat3x3<T>::col_type operator* (
+ tmat3x3<T> const & m,
+ typename tmat3x3<T>::row_type const & v);
+
+ template <typename T>
+ typename tmat3x3<T>::row_type operator* (
+ typename tmat3x3<T>::col_type const & v,
+ tmat3x3<T> const & m);
+
+ template <typename T>
+ tmat3x3<T> operator* (
+ tmat3x3<T> const & m1,
+ tmat3x3<T> const & m2);
+
+ template <typename T>
+ tmat3x3<T> operator/ (
+ tmat3x3<T> const & m,
+ typename tmat3x3<T>::value_type const & s);
+
+ template <typename T>
+ tmat3x3<T> operator/ (
+ typename tmat3x3<T>::value_type const & s,
+ tmat3x3<T> const & m);
+
+ template <typename T>
+ typename tmat3x3<T>::col_type operator/ (
+ tmat3x3<T> const & m,
+ typename tmat3x3<T>::row_type const & v);
+
+ template <typename T>
+ typename tmat3x3<T>::row_type operator/ (
+ typename tmat3x3<T>::col_type const & v,
+ tmat3x3<T> const & m);
+
+ template <typename T>
+ tmat3x3<T> operator/ (
+ tmat3x3<T> const & m1,
+ tmat3x3<T> const & m2);
+
+ // Unary constant operators
+ template <typename T>
+ tmat3x3<T> const operator- (
+ tmat3x3<T> const & m);
+
+ template <typename T>
+ tmat3x3<T> const operator-- (
+ tmat3x3<T> const & m,
+ int);
+
+ template <typename T>
+ tmat3x3<T> const operator++ (
+ tmat3x3<T> const & m,
+ int);
+
+} //namespace detail
+
+namespace core{
+namespace type{
+namespace precision
+{
+ //! 3 columns of 3 components matrix of low precision floating-point numbers.
+ //! There is no guarantee on the actual precision.
+ //! From GLSL 1.30.8 specification, section 4.1.6 Matrices and section 4.5 Precision and Precision Qualifiers
+ //! \ingroup core_precision
+ typedef detail::tmat3x3<lowp_float> lowp_mat3;
+ //! 3 columns of 3 components matrix of medium precision floating-point numbers.
+ //! There is no guarantee on the actual precision.
+ //! From GLSL 1.30.8 specification, section 4.1.6 Matrices and section 4.5 Precision and Precision Qualifiers
+ //! \ingroup core_precision
+ typedef detail::tmat3x3<mediump_float> mediump_mat3;
+ //! 3 columns of 3 components matrix of high precision floating-point numbers.
+ //! There is no guarantee on the actual precision.
+ //! From GLSL 1.30.8 specification, section 4.1.6 Matrices and section 4.5 Precision and Precision Qualifiers
+ //! \ingroup core_precision
+ typedef detail::tmat3x3<highp_float> highp_mat3;
+
+ //! 3 columns of 3 components matrix of low precision floating-point numbers.
+ //! There is no guarantee on the actual precision.
+ //! From GLSL 1.30.8 specification, section 4.1.6 Matrices and section 4.5 Precision and Precision Qualifiers
+ //! \ingroup core_precision
+ typedef detail::tmat3x3<lowp_float> lowp_mat3x3;
+
+ //! 3 columns of 3 components matrix of medium precision floating-point numbers.
+ //! There is no guarantee on the actual precision.
+ //! From GLSL 1.30.8 specification, section 4.1.6 Matrices and section 4.5 Precision and Precision Qualifiers
+ //! \ingroup core_precision
+ typedef detail::tmat3x3<mediump_float> mediump_mat3x3;
+
+ //! 3 columns of 3 components matrix of high precision floating-point numbers.
+ //! There is no guarantee on the actual precision.
+ //! From GLSL 1.30.8 specification, section 4.1.6 Matrices and section 4.5 Precision and Precision Qualifiers
+ //! \ingroup core_precision
+ typedef detail::tmat3x3<highp_float> highp_mat3x3;
+
+}//namespace precision
+}//namespace type
+}//namespace core
+}//namespace glm
+
+#ifndef GLM_EXTERNAL_TEMPLATE
+#include "type_mat3x3.inl"
+#endif
+
+#endif //glm_core_type_mat3x3
diff --git a/src/glm/core/type_mat3x3.inl b/src/glm/core/type_mat3x3.inl
new file mode 100644
index 0000000..a9fdfcc
--- /dev/null
+++ b/src/glm/core/type_mat3x3.inl
@@ -0,0 +1,750 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2005-01-27
+// Updated : 2010-02-03
+// Licence : This source is under MIT License
+// File : glm/core/type_mat3x3.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm{
+namespace detail
+{
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename tmat3x3<T>::size_type tmat3x3<T>::col_size()
+ {
+ return 3;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename tmat3x3<T>::size_type tmat3x3<T>::row_size()
+ {
+ return 3;
+ }
+
+ //////////////////////////////////////
+ // Accesses
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename tmat3x3<T>::col_type &
+ tmat3x3<T>::operator[]
+ (
+ size_type i
+ )
+ {
+ assert(i < this->row_size());
+ return this->value[i];
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename tmat3x3<T>::col_type const &
+ tmat3x3<T>::operator[]
+ (
+ size_type i
+ ) const
+ {
+ assert(i < this->row_size());
+ return this->value[i];
+ }
+
+ //////////////////////////////////////////////////////////////
+ // Constructors
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x3<T>::tmat3x3()
+ {
+ value_type const Zero(0);
+ value_type const One(1);
+ this->value[0] = col_type(One, Zero, Zero);
+ this->value[1] = col_type(Zero, One, Zero);
+ this->value[2] = col_type(Zero, Zero, One);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x3<T>::tmat3x3
+ (
+ tmat3x3<T> const & m
+ )
+ {
+ this->value[0] = m.value[0];
+ this->value[1] = m.value[1];
+ this->value[2] = m.value[2];
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x3<T>::tmat3x3
+ (
+ ctor
+ )
+ {}
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x3<T>::tmat3x3
+ (
+ value_type const & s
+ )
+ {
+ value_type const Zero(0);
+ this->value[0] = col_type(s, Zero, Zero);
+ this->value[1] = col_type(Zero, s, Zero);
+ this->value[2] = col_type(Zero, Zero, s);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x3<T>::tmat3x3
+ (
+ value_type const & x0, value_type const & y0, value_type const & z0,
+ value_type const & x1, value_type const & y1, value_type const & z1,
+ value_type const & x2, value_type const & y2, value_type const & z2
+ )
+ {
+ this->value[0] = col_type(x0, y0, z0);
+ this->value[1] = col_type(x1, y1, z1);
+ this->value[2] = col_type(x2, y2, z2);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x3<T>::tmat3x3
+ (
+ col_type const & v0,
+ col_type const & v1,
+ col_type const & v2
+ )
+ {
+ this->value[0] = v0;
+ this->value[1] = v1;
+ this->value[2] = v2;
+ }
+
+ //////////////////////////////////////
+ // Convertion constructors
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_DECL tmat3x3<T>::tmat3x3
+ (
+ U const & s
+ )
+ {
+ value_type const Zero(0);
+ this->value[0] = tvec3<T>(value_type(s), Zero, Zero);
+ this->value[1] = tvec3<T>(Zero, value_type(s), Zero);
+ this->value[2] = tvec3<T>(Zero, Zero, value_type(s));
+ }
+
+ template <typename T>
+ template <
+ typename X1, typename Y1, typename Z1,
+ typename X2, typename Y2, typename Z2,
+ typename X3, typename Y3, typename Z3>
+ GLM_FUNC_DECL tmat3x3<T>::tmat3x3
+ (
+ X1 const & x1, Y1 const & y1, Z1 const & z1,
+ X2 const & x2, Y2 const & y2, Z2 const & z2,
+ X3 const & x3, Y3 const & y3, Z3 const & z3
+ )
+ {
+ this->value[0] = col_type(value_type(x1), value_type(y1), value_type(z1));
+ this->value[1] = col_type(value_type(x2), value_type(y2), value_type(z2));
+ this->value[2] = col_type(value_type(x3), value_type(y3), value_type(z3));
+ }
+
+ template <typename T>
+ template <typename V1, typename V2, typename V3>
+ GLM_FUNC_DECL tmat3x3<T>::tmat3x3
+ (
+ tvec3<V1> const & v1,
+ tvec3<V2> const & v2,
+ tvec3<V3> const & v3
+ )
+ {
+ this->value[0] = col_type(v1);
+ this->value[1] = col_type(v2);
+ this->value[2] = col_type(v3);
+ }
+
+ //////////////////////////////////////////////////////////////
+ // Conversions
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat3x3<T>::tmat3x3
+ (
+ tmat3x3<U> const & m
+ )
+ {
+ this->value[0] = col_type(m[0]);
+ this->value[1] = col_type(m[1]);
+ this->value[2] = col_type(m[2]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x3<T>::tmat3x3
+ (
+ tmat2x2<T> const & m
+ )
+ {
+ this->value[0] = col_type(m[0], value_type(0));
+ this->value[1] = col_type(m[1], value_type(0));
+ this->value[2] = col_type(detail::tvec2<T>(0), value_type(1));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x3<T>::tmat3x3
+ (
+ tmat4x4<T> const & m
+ )
+ {
+ this->value[0] = col_type(m[0]);
+ this->value[1] = col_type(m[1]);
+ this->value[2] = col_type(m[2]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x3<T>::tmat3x3
+ (
+ tmat2x3<T> const & m
+ )
+ {
+ this->value[0] = m[0];
+ this->value[1] = m[1];
+ this->value[2] = col_type(detail::tvec2<T>(0), value_type(1));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x3<T>::tmat3x3
+ (
+ tmat3x2<T> const & m
+ )
+ {
+ this->value[0] = col_type(m[0], value_type(0));
+ this->value[1] = col_type(m[1], value_type(0));
+ this->value[2] = col_type(m[2], value_type(1));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x3<T>::tmat3x3
+ (
+ tmat2x4<T> const & m
+ )
+ {
+ this->value[0] = col_type(m[0]);
+ this->value[1] = col_type(m[1]);
+ this->value[2] = col_type(detail::tvec2<T>(0), value_type(1));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x3<T>::tmat3x3
+ (
+ tmat4x2<T> const & m
+ )
+ {
+ this->value[0] = col_type(m[0], value_type(0));
+ this->value[1] = col_type(m[1], value_type(0));
+ this->value[2] = col_type(m[2], value_type(1));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x3<T>::tmat3x3
+ (
+ tmat3x4<T> const & m
+ )
+ {
+ this->value[0] = col_type(m[0]);
+ this->value[1] = col_type(m[1]);
+ this->value[2] = col_type(m[2]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x3<T>::tmat3x3
+ (
+ tmat4x3<T> const & m
+ )
+ {
+ this->value[0] = m[0];
+ this->value[1] = m[1];
+ this->value[2] = m[2];
+ }
+
+ //////////////////////////////////////////////////////////////
+ // Operators
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x3<T> & tmat3x3<T>::operator=
+ (
+ tmat3x3<T> const & m
+ )
+ {
+ this->value[0] = m[0];
+ this->value[1] = m[1];
+ this->value[2] = m[2];
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat3x3<T> & tmat3x3<T>::operator=
+ (
+ tmat3x3<U> const & m
+ )
+ {
+ this->value[0] = m[0];
+ this->value[1] = m[1];
+ this->value[2] = m[2];
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat3x3<T> & tmat3x3<T>::operator+=
+ (
+ U const & s
+ )
+ {
+ this->value[0] += s;
+ this->value[1] += s;
+ this->value[2] += s;
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat3x3<T> & tmat3x3<T>::operator+=
+ (
+ tmat3x3<U> const & m
+ )
+ {
+ this->value[0] += m[0];
+ this->value[1] += m[1];
+ this->value[2] += m[2];
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat3x3<T> & tmat3x3<T>::operator-=
+ (
+ U const & s
+ )
+ {
+ this->value[0] -= s;
+ this->value[1] -= s;
+ this->value[2] -= s;
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat3x3<T> & tmat3x3<T>::operator-=
+ (
+ tmat3x3<U> const & m
+ )
+ {
+ this->value[0] -= m[0];
+ this->value[1] -= m[1];
+ this->value[2] -= m[2];
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat3x3<T> & tmat3x3<T>::operator*=
+ (
+ U const & s
+ )
+ {
+ this->value[0] *= s;
+ this->value[1] *= s;
+ this->value[2] *= s;
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat3x3<T> & tmat3x3<T>::operator*=
+ (
+ tmat3x3<U> const & m
+ )
+ {
+ return (*this = *this * m);
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat3x3<T> & tmat3x3<T>::operator/=
+ (
+ U const & s
+ )
+ {
+ this->value[0] /= s;
+ this->value[1] /= s;
+ this->value[2] /= s;
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat3x3<T> & tmat3x3<T>::operator/=
+ (
+ tmat3x3<U> const & m
+ )
+ {
+ return (*this = *this / m);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x3<T> & tmat3x3<T>::operator++ ()
+ {
+ ++this->value[0];
+ ++this->value[1];
+ ++this->value[2];
+ return *this;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x3<T> & tmat3x3<T>::operator-- ()
+ {
+ --this->value[0];
+ --this->value[1];
+ --this->value[2];
+ return *this;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x3<T> tmat3x3<T>::_inverse() const
+ {
+ T S00 = value[0][0];
+ T S01 = value[0][1];
+ T S02 = value[0][2];
+
+ T S10 = value[1][0];
+ T S11 = value[1][1];
+ T S12 = value[1][2];
+
+ T S20 = value[2][0];
+ T S21 = value[2][1];
+ T S22 = value[2][2];
+/*
+ tmat3x3<T> Inverse(
+ + (S11 * S22 - S21 * S12),
+ - (S10 * S22 - S20 * S12),
+ + (S10 * S21 - S20 * S11),
+ - (S01 * S22 - S21 * S02),
+ + (S00 * S22 - S20 * S02),
+ - (S00 * S21 - S20 * S01),
+ + (S01 * S12 - S11 * S02),
+ - (S00 * S12 - S10 * S02),
+ + (S00 * S11 - S10 * S01));
+*/
+ tmat3x3<T> Inverse(
+ S11 * S22 - S21 * S12,
+ S12 * S20 - S22 * S10,
+ S10 * S21 - S20 * S11,
+ S02 * S21 - S01 * S22,
+ S00 * S22 - S02 * S20,
+ S01 * S20 - S00 * S21,
+ S12 * S01 - S11 * S02,
+ S10 * S02 - S12 * S00,
+ S11 * S00 - S10 * S01);
+
+ T Determinant = S00 * (S11 * S22 - S21 * S12)
+ - S10 * (S01 * S22 - S21 * S02)
+ + S20 * (S01 * S12 - S11 * S02);
+
+ Inverse /= Determinant;
+ return Inverse;
+ }
+
+ //////////////////////////////////////////////////////////////
+ // Binary operators
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x3<T> operator+
+ (
+ tmat3x3<T> const & m,
+ typename tmat3x3<T>::value_type const & s
+ )
+ {
+ return tmat3x3<T>(
+ m[0] + s,
+ m[1] + s,
+ m[2] + s);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x3<T> operator+
+ (
+ typename tmat3x3<T>::value_type const & s,
+ tmat3x3<T> const & m
+ )
+ {
+ return tmat3x3<T>(
+ m[0] + s,
+ m[1] + s,
+ m[2] + s);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x3<T> operator+
+ (
+ tmat3x3<T> const & m1,
+ tmat3x3<T> const & m2
+ )
+ {
+ return tmat3x3<T>(
+ m1[0] + m2[0],
+ m1[1] + m2[1],
+ m1[2] + m2[2]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x3<T> operator-
+ (
+ tmat3x3<T> const & m,
+ typename tmat3x3<T>::value_type const & s
+ )
+ {
+ return tmat3x3<T>(
+ m[0] - s,
+ m[1] - s,
+ m[2] - s);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x3<T> operator-
+ (
+ typename tmat3x3<T>::value_type const & s,
+ tmat3x3<T> const & m
+ )
+ {
+ return tmat3x3<T>(
+ s - m[0],
+ s - m[1],
+ s - m[2]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x3<T> operator-
+ (
+ tmat3x3<T> const & m1,
+ tmat3x3<T> const & m2
+ )
+ {
+ return tmat3x3<T>(
+ m1[0] - m2[0],
+ m1[1] - m2[1],
+ m1[2] - m2[2]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x3<T> operator*
+ (
+ tmat3x3<T> const & m,
+ typename tmat3x3<T>::value_type const & s
+ )
+ {
+ return tmat3x3<T>(
+ m[0] * s,
+ m[1] * s,
+ m[2] * s);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x3<T> operator*
+ (
+ typename tmat3x3<T>::value_type const & s,
+ tmat3x3<T> const & m
+ )
+ {
+ return tmat3x3<T>(
+ m[0] * s,
+ m[1] * s,
+ m[2] * s);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename tmat3x3<T>::col_type operator*
+ (
+ tmat3x3<T> const & m,
+ typename tmat3x3<T>::row_type const & v
+ )
+ {
+ return typename tmat3x3<T>::col_type(
+ m[0][0] * v.x + m[1][0] * v.y + m[2][0] * v.z,
+ m[0][1] * v.x + m[1][1] * v.y + m[2][1] * v.z,
+ m[0][2] * v.x + m[1][2] * v.y + m[2][2] * v.z);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename tmat3x3<T>::row_type operator*
+ (
+ typename tmat3x3<T>::col_type const & v,
+ tmat3x3<T> const & m
+ )
+ {
+ return typename tmat3x3<T>::row_type(
+ m[0][0] * v.x + m[0][1] * v.y + m[0][2] * v.z,
+ m[1][0] * v.x + m[1][1] * v.y + m[1][2] * v.z,
+ m[2][0] * v.x + m[2][1] * v.y + m[2][2] * v.z);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x3<T> operator*
+ (
+ tmat3x3<T> const & m1,
+ tmat3x3<T> const & m2
+ )
+ {
+ typename tmat3x3<T>::value_type const SrcA00 = m1[0][0];
+ typename tmat3x3<T>::value_type const SrcA01 = m1[0][1];
+ typename tmat3x3<T>::value_type const SrcA02 = m1[0][2];
+ typename tmat3x3<T>::value_type const SrcA10 = m1[1][0];
+ typename tmat3x3<T>::value_type const SrcA11 = m1[1][1];
+ typename tmat3x3<T>::value_type const SrcA12 = m1[1][2];
+ typename tmat3x3<T>::value_type const SrcA20 = m1[2][0];
+ typename tmat3x3<T>::value_type const SrcA21 = m1[2][1];
+ typename tmat3x3<T>::value_type const SrcA22 = m1[2][2];
+
+ typename tmat3x3<T>::value_type const SrcB00 = m2[0][0];
+ typename tmat3x3<T>::value_type const SrcB01 = m2[0][1];
+ typename tmat3x3<T>::value_type const SrcB02 = m2[0][2];
+ typename tmat3x3<T>::value_type const SrcB10 = m2[1][0];
+ typename tmat3x3<T>::value_type const SrcB11 = m2[1][1];
+ typename tmat3x3<T>::value_type const SrcB12 = m2[1][2];
+ typename tmat3x3<T>::value_type const SrcB20 = m2[2][0];
+ typename tmat3x3<T>::value_type const SrcB21 = m2[2][1];
+ typename tmat3x3<T>::value_type const SrcB22 = m2[2][2];
+
+ tmat3x3<T> Result(tmat3x3<T>::null);
+ Result[0][0] = SrcA00 * SrcB00 + SrcA10 * SrcB01 + SrcA20 * SrcB02;
+ Result[0][1] = SrcA01 * SrcB00 + SrcA11 * SrcB01 + SrcA21 * SrcB02;
+ Result[0][2] = SrcA02 * SrcB00 + SrcA12 * SrcB01 + SrcA22 * SrcB02;
+ Result[1][0] = SrcA00 * SrcB10 + SrcA10 * SrcB11 + SrcA20 * SrcB12;
+ Result[1][1] = SrcA01 * SrcB10 + SrcA11 * SrcB11 + SrcA21 * SrcB12;
+ Result[1][2] = SrcA02 * SrcB10 + SrcA12 * SrcB11 + SrcA22 * SrcB12;
+ Result[2][0] = SrcA00 * SrcB20 + SrcA10 * SrcB21 + SrcA20 * SrcB22;
+ Result[2][1] = SrcA01 * SrcB20 + SrcA11 * SrcB21 + SrcA21 * SrcB22;
+ Result[2][2] = SrcA02 * SrcB20 + SrcA12 * SrcB21 + SrcA22 * SrcB22;
+ return Result;
+ }
+
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x3<T> operator/
+ (
+ tmat3x3<T> const & m,
+ typename tmat3x3<T>::value_type const & s
+ )
+ {
+ return tmat3x3<T>(
+ m[0] / s,
+ m[1] / s,
+ m[2] / s);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x3<T> operator/
+ (
+ typename tmat3x3<T>::value_type const & s,
+ tmat3x3<T> const & m
+ )
+ {
+ return tmat3x3<T>(
+ s / m[0],
+ s / m[1],
+ s / m[2]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename tmat3x3<T>::col_type operator/
+ (
+ tmat3x3<T> const & m,
+ typename tmat3x3<T>::row_type const & v
+ )
+ {
+ return m._inverse() * v;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename tmat3x3<T>::row_type operator/
+ (
+ typename tmat3x3<T>::col_type const & v,
+ tmat3x3<T> const & m
+ )
+ {
+ return v * m._inverse();
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x3<T> operator/
+ (
+ tmat3x3<T> const & m1,
+ tmat3x3<T> const & m2
+ )
+ {
+ return m1 * m2._inverse();
+ }
+
+ // Unary constant operators
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x3<T> const operator-
+ (
+ tmat3x3<T> const & m
+ )
+ {
+ return tmat3x3<T>(
+ -m[0],
+ -m[1],
+ -m[2]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x3<T> const operator++
+ (
+ tmat3x3<T> const & m,
+ int
+ )
+ {
+ return tmat3x3<T>(
+ m[0] + T(1),
+ m[1] + T(1),
+ m[2] + T(1));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x3<T> const operator--
+ (
+ tmat3x3<T> const & m,
+ int
+ )
+ {
+ return tmat3x3<T>(
+ m[0] - T(1),
+ m[1] - T(1),
+ m[2] - T(1));
+ }
+
+ //////////////////////////////////////
+ // Boolean operators
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER bool operator==
+ (
+ tmat3x3<T> const & m1,
+ tmat3x3<T> const & m2
+ )
+ {
+ return (m1[0] == m2[0]) && (m1[1] == m2[1]) && (m1[2] == m2[2]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER bool operator!=
+ (
+ tmat3x3<T> const & m1,
+ tmat3x3<T> const & m2
+ )
+ {
+ return (m1[0] != m2[0]) || (m1[1] != m2[1]) || (m1[2] != m2[2]);
+ }
+
+} //namespace detail
+} //namespace glm
diff --git a/src/glm/core/type_mat3x4.hpp b/src/glm/core/type_mat3x4.hpp
new file mode 100644
index 0000000..26e6d29
--- /dev/null
+++ b/src/glm/core/type_mat3x4.hpp
@@ -0,0 +1,232 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2006-08-05
+// Updated : 2010-02-05
+// Licence : This source is under MIT License
+// File : glm/core/type_mat3x4.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_core_type_mat3x4
+#define glm_core_type_mat3x4
+
+#include "type_mat.hpp"
+
+namespace glm{
+namespace detail
+{
+ template <typename T> struct tvec1;
+ template <typename T> struct tvec2;
+ template <typename T> struct tvec3;
+ template <typename T> struct tvec4;
+ template <typename T> struct tmat2x2;
+ template <typename T> struct tmat2x3;
+ template <typename T> struct tmat2x4;
+ template <typename T> struct tmat3x2;
+ template <typename T> struct tmat3x3;
+ template <typename T> struct tmat3x4;
+ template <typename T> struct tmat4x2;
+ template <typename T> struct tmat4x3;
+ template <typename T> struct tmat4x4;
+
+ //! \brief Template for 3 columns and 4 rows matrix of floating-point numbers.
+ //! \ingroup core_template
+ template <typename T>
+ struct tmat3x4
+ {
+ enum ctor{null};
+ typedef T value_type;
+ typedef std::size_t size_type;
+ typedef tvec4<T> col_type;
+ typedef tvec3<T> row_type;
+ static GLM_FUNC_DECL size_type col_size();
+ static GLM_FUNC_DECL size_type row_size();
+
+ typedef tmat3x4<T> type;
+ typedef tmat4x3<T> transpose_type;
+
+ private:
+ // Data
+ col_type value[3];
+
+ public:
+ // Constructors
+ GLM_FUNC_DECL tmat3x4();
+ GLM_FUNC_DECL tmat3x4(tmat3x4 const & m);
+
+ GLM_FUNC_DECL explicit tmat3x4(
+ ctor Null);
+ GLM_FUNC_DECL explicit tmat3x4(
+ value_type const & s);
+ GLM_FUNC_DECL explicit tmat3x4(
+ value_type const & x0, value_type const & y0, value_type const & z0, value_type const & w0,
+ value_type const & x1, value_type const & y1, value_type const & z1, value_type const & w1,
+ value_type const & x2, value_type const & y2, value_type const & z2, value_type const & w2);
+ GLM_FUNC_DECL explicit tmat3x4(
+ col_type const & v0,
+ col_type const & v1,
+ col_type const & v2);
+
+ //////////////////////////////////////
+ // Conversions
+ template <typename U>
+ GLM_FUNC_DECL explicit tmat3x4(
+ U const & x);
+
+ template
+ <
+ typename X1, typename Y1, typename Z1, typename W1,
+ typename X2, typename Y2, typename Z2, typename W2,
+ typename X3, typename Y3, typename Z3, typename W3
+ >
+ GLM_FUNC_DECL explicit tmat3x4(
+ X1 const & x1, Y1 const & y1, Z1 const & z1, W1 const & w1,
+ X2 const & x2, Y2 const & y2, Z2 const & z2, W2 const & w2,
+ X3 const & x3, Y3 const & y3, Z3 const & z3, W3 const & w3);
+
+ template <typename V1, typename V2, typename V3>
+ GLM_FUNC_DECL explicit tmat3x4(
+ tvec4<V1> const & v1,
+ tvec4<V2> const & v2,
+ tvec4<V3> const & v3);
+
+ // Matrix conversion
+ template <typename U>
+ GLM_FUNC_DECL explicit tmat3x4(tmat3x4<U> const & m);
+
+ GLM_FUNC_DECL explicit tmat3x4(tmat2x2<T> const & x);
+ GLM_FUNC_DECL explicit tmat3x4(tmat3x3<T> const & x);
+ GLM_FUNC_DECL explicit tmat3x4(tmat4x4<T> const & x);
+ GLM_FUNC_DECL explicit tmat3x4(tmat2x3<T> const & x);
+ GLM_FUNC_DECL explicit tmat3x4(tmat3x2<T> const & x);
+ GLM_FUNC_DECL explicit tmat3x4(tmat2x4<T> const & x);
+ GLM_FUNC_DECL explicit tmat3x4(tmat4x2<T> const & x);
+ GLM_FUNC_DECL explicit tmat3x4(tmat4x3<T> const & x);
+
+ // Accesses
+ col_type & operator[](size_type i);
+ col_type const & operator[](size_type i) const;
+
+ // Unary updatable operators
+ GLM_FUNC_DECL tmat3x4<T> & operator= (tmat3x4<T> const & m);
+ template <typename U>
+ GLM_FUNC_DECL tmat3x4<T> & operator= (tmat3x4<U> const & m);
+ template <typename U>
+ GLM_FUNC_DECL tmat3x4<T> & operator+= (U const & s);
+ template <typename U>
+ GLM_FUNC_DECL tmat3x4<T> & operator+= (tmat3x4<U> const & m);
+ template <typename U>
+ GLM_FUNC_DECL tmat3x4<T> & operator-= (U const & s);
+ template <typename U>
+ GLM_FUNC_DECL tmat3x4<T> & operator-= (tmat3x4<U> const & m);
+ template <typename U>
+ GLM_FUNC_DECL tmat3x4<T> & operator*= (U const & s);
+ template <typename U>
+ GLM_FUNC_DECL tmat3x4<T> & operator*= (tmat3x4<U> const & m);
+ template <typename U>
+ GLM_FUNC_DECL tmat3x4<T> & operator/= (U const & s);
+
+ GLM_FUNC_DECL tmat3x4<T> & operator++ ();
+ GLM_FUNC_DECL tmat3x4<T> & operator-- ();
+ };
+
+ // Binary operators
+ template <typename T>
+ tmat3x4<T> operator+ (
+ tmat3x4<T> const & m,
+ typename tmat3x4<T>::value_type const & s);
+
+ template <typename T>
+ tmat3x4<T> operator+ (
+ tmat3x4<T> const & m1,
+ tmat3x4<T> const & m2);
+
+ template <typename T>
+ tmat3x4<T> operator- (
+ tmat3x4<T> const & m,
+ typename tmat3x4<T>::value_type const & s);
+
+ template <typename T>
+ tmat3x4<T> operator- (
+ tmat3x4<T> const & m1,
+ tmat3x4<T> const & m2);
+
+ template <typename T>
+ tmat3x4<T> operator* (
+ tmat3x4<T> const & m,
+ typename tmat3x4<T>::value_type const & s);
+
+ template <typename T>
+ tmat3x4<T> operator* (
+ typename tmat3x4<T>::value_type const & s,
+ tmat3x4<T> const & m);
+
+ template <typename T>
+ typename tmat3x4<T>::col_type operator* (
+ tmat3x4<T> const & m,
+ typename tmat3x4<T>::row_type const & v);
+
+ template <typename T>
+ typename tmat3x4<T>::row_type operator* (
+ typename tmat3x4<T>::col_type const & v,
+ tmat3x4<T> const & m);
+
+ template <typename T>
+ tmat4x4<T> operator* (
+ tmat3x4<T> const & m1,
+ tmat4x3<T> const & m2);
+
+ template <typename T>
+ tmat3x4<T> operator/ (
+ tmat3x4<T> const & m,
+ typename tmat3x4<T>::value_type const & s);
+
+ template <typename T>
+ tmat3x4<T> operator/ (
+ typename tmat3x4<T>::value_type const & s,
+ tmat3x4<T> const & m);
+
+ // Unary constant operators
+ template <typename T>
+ tmat3x4<T> const operator- (
+ tmat3x4<T> const & m);
+
+ template <typename T>
+ tmat3x4<T> const operator-- (
+ tmat3x4<T> const & m,
+ int);
+
+ template <typename T>
+ tmat3x4<T> const operator++ (
+ tmat3x4<T> const & m,
+ int);
+
+}//namespace detail
+
+namespace core{
+namespace type{
+namespace precision
+{
+ //! 3 columns of 4 components matrix of low precision floating-point numbers.
+ //! There is no guarantee on the actual precision.
+ //! (From GLSL 1.30.8 specification, section 4.1.6 Matrices and section 4.5 Precision and Precision Qualifiers)
+ typedef detail::tmat3x4<lowp_float> lowp_mat3x4;
+ //! 3 columns of 4 components matrix of medium precision floating-point numbers.
+ //! There is no guarantee on the actual precision.
+ //! (From GLSL 1.30.8 specification, section 4.1.6 Matrices and section 4.5 Precision and Precision Qualifiers)
+ typedef detail::tmat3x4<mediump_float> mediump_mat3x4;
+ //! 3 columns of 4 components matrix of high precision floating-point numbers.
+ //! There is no guarantee on the actual precision.
+ //! (From GLSL 1.30.8 specification, section 4.1.6 Matrices and section 4.5 Precision and Precision Qualifiers)
+ typedef detail::tmat3x4<highp_float> highp_mat3x4;
+
+}//namespace precision
+}//namespace type
+}//namespace core
+}//namespace glm
+
+#ifndef GLM_EXTERNAL_TEMPLATE
+#include "type_mat3x4.inl"
+#endif
+
+#endif //glm_core_type_mat3x4
diff --git a/src/glm/core/type_mat3x4.inl b/src/glm/core/type_mat3x4.inl
new file mode 100644
index 0000000..542bfaa
--- /dev/null
+++ b/src/glm/core/type_mat3x4.inl
@@ -0,0 +1,653 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2006-08-05
+// Updated : 2010-02-05
+// Licence : This source is under MIT License
+// File : glm/core/type_mat3x4.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm{
+namespace detail
+{
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename tmat3x4<T>::size_type tmat3x4<T>::col_size()
+ {
+ return 4;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename tmat3x4<T>::size_type tmat3x4<T>::row_size()
+ {
+ return 3;
+ }
+
+ //////////////////////////////////////
+ // Accesses
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename tmat3x4<T>::col_type &
+ tmat3x4<T>::operator[]
+ (
+ size_type i
+ )
+ {
+ assert(i < this->row_size());
+ return this->value[i];
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename tmat3x4<T>::col_type const &
+ tmat3x4<T>::operator[]
+ (
+ size_type i
+ ) const
+ {
+ assert(i < this->row_size());
+ return this->value[i];
+ }
+
+ //////////////////////////////////////////////////////////////
+ // Constructors
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x4<T>::tmat3x4()
+ {
+ this->value[0] = col_type(1, 0, 0, 0);
+ this->value[1] = col_type(0, 1, 0, 0);
+ this->value[2] = col_type(0, 0, 1, 0);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x4<T>::tmat3x4
+ (
+ tmat3x4<T> const & m
+ )
+ {
+ this->value[0] = m.value[0];
+ this->value[1] = m.value[1];
+ this->value[2] = m.value[2];
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x4<T>::tmat3x4
+ (
+ ctor
+ )
+ {}
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x4<T>::tmat3x4
+ (
+ value_type const & s
+ )
+ {
+ value_type const Zero(0);
+ this->value[0] = col_type(s, Zero, Zero, Zero);
+ this->value[1] = col_type(Zero, s, Zero, Zero);
+ this->value[2] = col_type(Zero, Zero, s, Zero);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x4<T>::tmat3x4
+ (
+ value_type const & x0, value_type const & y0, value_type const & z0, value_type const & w0,
+ value_type const & x1, value_type const & y1, value_type const & z1, value_type const & w1,
+ value_type const & x2, value_type const & y2, value_type const & z2, value_type const & w2
+ )
+ {
+ this->value[0] = col_type(x0, y0, z0, w0);
+ this->value[1] = col_type(x1, y1, z1, w1);
+ this->value[2] = col_type(x2, y2, z2, w2);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x4<T>::tmat3x4
+ (
+ col_type const & v0,
+ col_type const & v1,
+ col_type const & v2
+ )
+ {
+ this->value[0] = v0;
+ this->value[1] = v1;
+ this->value[2] = v2;
+ }
+
+ //////////////////////////////////////
+ // Convertion constructors
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_DECL tmat3x4<T>::tmat3x4
+ (
+ U const & s
+ )
+ {
+ value_type const Zero(0);
+ this->value[0] = tvec4<T>(value_type(s), Zero, Zero, Zero);
+ this->value[1] = tvec4<T>(Zero, value_type(s), Zero, Zero);
+ this->value[2] = tvec4<T>(Zero, Zero, value_type(s), Zero);
+ }
+
+ template <typename T>
+ template <
+ typename X1, typename Y1, typename Z1, typename W1,
+ typename X2, typename Y2, typename Z2, typename W2,
+ typename X3, typename Y3, typename Z3, typename W3>
+ GLM_FUNC_DECL tmat3x4<T>::tmat3x4
+ (
+ X1 const & x1, Y1 const & y1, Z1 const & z1, W1 const & w1,
+ X2 const & x2, Y2 const & y2, Z2 const & z2, W2 const & w2,
+ X3 const & x3, Y3 const & y3, Z3 const & z3, W3 const & w3
+ )
+ {
+ this->value[0] = col_type(value_type(x1), value_type(y1), value_type(z1), value_type(w1));
+ this->value[1] = col_type(value_type(x2), value_type(y2), value_type(z2), value_type(w2));
+ this->value[2] = col_type(value_type(x3), value_type(y3), value_type(z3), value_type(w3));
+ }
+
+ template <typename T>
+ template <typename V1, typename V2, typename V3>
+ GLM_FUNC_DECL tmat3x4<T>::tmat3x4
+ (
+ tvec4<V1> const & v1,
+ tvec4<V2> const & v2,
+ tvec4<V3> const & v3
+ )
+ {
+ this->value[0] = col_type(v1);
+ this->value[1] = col_type(v2);
+ this->value[2] = col_type(v3);
+ }
+
+ // Conversion
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat3x4<T>::tmat3x4
+ (
+ tmat3x4<U> const & m
+ )
+ {
+ this->value[0] = col_type(m[0]);
+ this->value[1] = col_type(m[1]);
+ this->value[2] = col_type(m[2]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x4<T>::tmat3x4
+ (
+ tmat2x2<T> const & m
+ )
+ {
+ this->value[0] = col_type(m[0], detail::tvec2<T>(0));
+ this->value[1] = col_type(m[1], detail::tvec2<T>(0));
+ this->value[2] = col_type(T(0), T(0), T(1), T(0));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x4<T>::tmat3x4
+ (
+ tmat3x3<T> const & m
+ )
+ {
+ this->value[0] = col_type(m[0], T(0));
+ this->value[1] = col_type(m[1], T(0));
+ this->value[2] = col_type(m[2], T(0));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x4<T>::tmat3x4
+ (
+ tmat4x4<T> const & m
+ )
+ {
+ this->value[0] = col_type(m[0]);
+ this->value[1] = col_type(m[1]);
+ this->value[2] = col_type(m[2]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x4<T>::tmat3x4
+ (
+ tmat2x3<T> const & m
+ )
+ {
+ this->value[0] = col_type(m[0], T(0));
+ this->value[1] = col_type(m[1], T(0));
+ this->value[2] = col_type(T(0), T(0), T(1), T(0));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x4<T>::tmat3x4
+ (
+ tmat3x2<T> const & m
+ )
+ {
+ this->value[0] = col_type(m[0], detail::tvec2<T>(0));
+ this->value[1] = col_type(m[1], detail::tvec2<T>(0));
+ this->value[2] = col_type(m[2], T(0), T(1));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x4<T>::tmat3x4
+ (
+ tmat2x4<T> const & m
+ )
+ {
+ this->value[0] = col_type(m[0]);
+ this->value[1] = col_type(m[1]);
+ this->value[2] = col_type(T(0), T(0), T(1), T(0));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x4<T>::tmat3x4
+ (
+ tmat4x2<T> const & m
+ )
+ {
+ this->value[0] = col_type(m[0], detail::tvec2<T>(T(0)));
+ this->value[1] = col_type(m[1], detail::tvec2<T>(T(0)));
+ this->value[2] = col_type(m[2], detail::tvec2<T>(T(1), T(0)));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x4<T>::tmat3x4
+ (
+ tmat4x3<T> const & m
+ )
+ {
+ this->value[0] = col_type(m[0], T(0));
+ this->value[1] = col_type(m[1], T(0));
+ this->value[2] = col_type(m[2], T(0));
+ }
+
+ //////////////////////////////////////////////////////////////
+ // Unary updatable operators
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x4<T>& tmat3x4<T>::operator=
+ (
+ tmat3x4<T> const & m
+ )
+ {
+ this->value[0] = m[0];
+ this->value[1] = m[1];
+ this->value[2] = m[2];
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat3x4<T>& tmat3x4<T>::operator=
+ (
+ tmat3x4<U> const & m
+ )
+ {
+ this->value[0] = m[0];
+ this->value[1] = m[1];
+ this->value[2] = m[2];
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat3x4<T>& tmat3x4<T>::operator+=
+ (
+ U const & s
+ )
+ {
+ this->value[0] += s;
+ this->value[1] += s;
+ this->value[2] += s;
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat3x4<T>& tmat3x4<T>::operator+=
+ (
+ tmat3x4<U> const & m
+ )
+ {
+ this->value[0] += m[0];
+ this->value[1] += m[1];
+ this->value[2] += m[2];
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat3x4<T>& tmat3x4<T>::operator-=
+ (
+ U const & s
+ )
+ {
+ this->value[0] -= s;
+ this->value[1] -= s;
+ this->value[2] -= s;
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat3x4<T>& tmat3x4<T>::operator-=
+ (
+ tmat3x4<U> const & m
+ )
+ {
+ this->value[0] -= m[0];
+ this->value[1] -= m[1];
+ this->value[2] -= m[2];
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat3x4<T>& tmat3x4<T>::operator*=
+ (
+ U const & s
+ )
+ {
+ this->value[0] *= s;
+ this->value[1] *= s;
+ this->value[2] *= s;
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat3x4<T>& tmat3x4<T>::operator*=
+ (
+ tmat3x4<U> const & m
+ )
+ {
+ return (*this = tmat3x4<T>(*this * m));
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat3x4<T> & tmat3x4<T>::operator/=
+ (
+ U const & s
+ )
+ {
+ this->value[0] /= s;
+ this->value[1] /= s;
+ this->value[2] /= s;
+ return *this;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x4<T>& tmat3x4<T>::operator++ ()
+ {
+ ++this->value[0];
+ ++this->value[1];
+ ++this->value[2];
+ return *this;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x4<T>& tmat3x4<T>::operator-- ()
+ {
+ --this->value[0];
+ --this->value[1];
+ --this->value[2];
+ return *this;
+ }
+
+ //////////////////////////////////////////////////////////////
+ // Binary operators
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x4<T> operator+
+ (
+ tmat3x4<T> const & m,
+ typename tmat3x4<T>::value_type const & s
+ )
+ {
+ return tmat3x4<T>(
+ m[0] + s,
+ m[1] + s,
+ m[2] + s);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x4<T> operator+
+ (
+ tmat3x4<T> const & m1,
+ tmat3x4<T> const & m2
+ )
+ {
+ return tmat3x4<T>(
+ m1[0] + m2[0],
+ m1[1] + m2[1],
+ m1[2] + m2[2]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x4<T> operator-
+ (
+ tmat3x4<T> const & m,
+ typename tmat3x4<T>::value_type const & s
+ )
+ {
+ return tmat3x4<T>(
+ m[0] - s,
+ m[1] - s,
+ m[2] - s);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x4<T> operator-
+ (
+ tmat3x4<T> const & m1,
+ tmat3x4<T> const & m2
+ )
+ {
+ return tmat3x4<T>(
+ m1[0] - m2[0],
+ m1[1] - m2[1],
+ m1[2] - m2[2]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x4<T> operator*
+ (
+ tmat3x4<T> const & m,
+ typename tmat3x4<T>::value_type const & s
+ )
+ {
+ return tmat3x4<T>(
+ m[0] * s,
+ m[1] * s,
+ m[2] * s);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x4<T> operator*
+ (
+ typename tmat3x4<T>::value_type const & s,
+ tmat3x4<T> const & m
+ )
+ {
+ return tmat3x4<T>(
+ m[0] * s,
+ m[1] * s,
+ m[2] * s);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename tmat3x4<T>::col_type operator*
+ (
+ tmat3x4<T> const & m,
+ typename tmat3x4<T>::row_type const & v
+ )
+ {
+ return typename tmat3x4<T>::col_type(
+ m[0][0] * v.x + m[1][0] * v.y + m[2][0] * v.z,
+ m[0][1] * v.x + m[1][1] * v.y + m[2][1] * v.z,
+ m[0][2] * v.x + m[1][2] * v.y + m[2][2] * v.z,
+ m[0][3] * v.x + m[1][3] * v.y + m[2][3] * v.z);
+ }
+
+ // X X X
+ // X X X
+ // X X X
+ // X X X
+ // X X X X
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename tmat3x4<T>::row_type operator*
+ (
+ typename tmat3x4<T>::col_type const & v,
+ tmat3x4<T> const & m
+ )
+ {
+ return typename tmat3x4<T>::row_type(
+ v.x * m[0][0] + v.y * m[0][1] + v.z * m[0][2] + v.w * m[0][3],
+ v.x * m[1][0] + v.y * m[1][1] + v.z * m[1][2] + v.w * m[1][3],
+ v.x * m[2][0] + v.y * m[2][1] + v.z * m[2][2] + v.w * m[2][3]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x4<T> operator*
+ (
+ tmat3x4<T> const & m1,
+ tmat4x3<T> const & m2
+ )
+ {
+ const T SrcA00 = m1[0][0];
+ const T SrcA01 = m1[0][1];
+ const T SrcA02 = m1[0][2];
+ const T SrcA03 = m1[0][3];
+ const T SrcA10 = m1[1][0];
+ const T SrcA11 = m1[1][1];
+ const T SrcA12 = m1[1][2];
+ const T SrcA13 = m1[1][3];
+ const T SrcA20 = m1[2][0];
+ const T SrcA21 = m1[2][1];
+ const T SrcA22 = m1[2][2];
+ const T SrcA23 = m1[2][3];
+
+ const T SrcB00 = m2[0][0];
+ const T SrcB01 = m2[0][1];
+ const T SrcB02 = m2[0][2];
+ const T SrcB10 = m2[1][0];
+ const T SrcB11 = m2[1][1];
+ const T SrcB12 = m2[1][2];
+ const T SrcB20 = m2[2][0];
+ const T SrcB21 = m2[2][1];
+ const T SrcB22 = m2[2][2];
+ const T SrcB30 = m2[3][0];
+ const T SrcB31 = m2[3][1];
+ const T SrcB32 = m2[3][2];
+
+ tmat4x4<T> Result(tmat4x4<T>::null);
+ Result[0][0] = SrcA00 * SrcB00 + SrcA10 * SrcB01 + SrcA20 * SrcB02;
+ Result[0][1] = SrcA01 * SrcB00 + SrcA11 * SrcB01 + SrcA21 * SrcB02;
+ Result[0][2] = SrcA02 * SrcB00 + SrcA12 * SrcB01 + SrcA22 * SrcB02;
+ Result[0][3] = SrcA03 * SrcB00 + SrcA13 * SrcB01 + SrcA23 * SrcB02;
+ Result[1][0] = SrcA00 * SrcB10 + SrcA10 * SrcB11 + SrcA20 * SrcB12;
+ Result[1][1] = SrcA01 * SrcB10 + SrcA11 * SrcB11 + SrcA21 * SrcB12;
+ Result[1][2] = SrcA02 * SrcB10 + SrcA12 * SrcB11 + SrcA22 * SrcB12;
+ Result[1][3] = SrcA03 * SrcB10 + SrcA13 * SrcB11 + SrcA23 * SrcB12;
+ Result[2][0] = SrcA00 * SrcB20 + SrcA10 * SrcB21 + SrcA20 * SrcB22;
+ Result[2][1] = SrcA01 * SrcB20 + SrcA11 * SrcB21 + SrcA21 * SrcB22;
+ Result[2][2] = SrcA02 * SrcB20 + SrcA12 * SrcB21 + SrcA22 * SrcB22;
+ Result[2][3] = SrcA03 * SrcB20 + SrcA13 * SrcB21 + SrcA23 * SrcB22;
+ Result[3][0] = SrcA00 * SrcB30 + SrcA10 * SrcB31 + SrcA20 * SrcB32;
+ Result[3][1] = SrcA01 * SrcB30 + SrcA11 * SrcB31 + SrcA21 * SrcB32;
+ Result[3][2] = SrcA02 * SrcB30 + SrcA12 * SrcB31 + SrcA22 * SrcB32;
+ Result[3][3] = SrcA03 * SrcB30 + SrcA13 * SrcB31 + SrcA23 * SrcB32;
+ return Result;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x4<T> operator/
+ (
+ tmat3x4<T> const & m,
+ typename tmat3x4<T>::value_type const & s
+ )
+ {
+ return tmat3x4<T>(
+ m[0] / s,
+ m[1] / s,
+ m[2] / s);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x4<T> operator/
+ (
+ typename tmat3x4<T>::value_type const & s,
+ tmat3x4<T> const & m
+ )
+ {
+ return tmat3x4<T>(
+ s / m[0],
+ s / m[1],
+ s / m[2]);
+ }
+
+ // Unary constant operators
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x4<T> const operator-
+ (
+ tmat3x4<T> const & m
+ )
+ {
+ return tmat3x4<T>(
+ -m[0],
+ -m[1],
+ -m[2]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x4<T> const operator++
+ (
+ tmat3x4<T> const & m,
+ int
+ )
+ {
+ return tmat3x4<T>(
+ m[0] + T(1),
+ m[1] + T(1),
+ m[2] + T(1));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x4<T> const operator--
+ (
+ tmat3x4<T> const & m,
+ int
+ )
+ {
+ return tmat3x4<T>(
+ m[0] - T(1),
+ m[1] - T(1),
+ m[2] - T(1));
+ }
+
+ //////////////////////////////////////
+ // Boolean operators
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER bool operator==
+ (
+ tmat3x4<T> const & m1,
+ tmat3x4<T> const & m2
+ )
+ {
+ return (m1[0] == m2[0]) && (m1[1] == m2[1]) && (m1[2] == m2[2]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER bool operator!=
+ (
+ tmat3x4<T> const & m1,
+ tmat3x4<T> const & m2
+ )
+ {
+ return (m1[0] != m2[0]) || (m1[1] != m2[1]) || (m1[2] != m2[2]);
+ }
+
+} //namespace detail
+} //namespace glm
diff --git a/src/glm/core/type_mat4x2.hpp b/src/glm/core/type_mat4x2.hpp
new file mode 100644
index 0000000..35388bc
--- /dev/null
+++ b/src/glm/core/type_mat4x2.hpp
@@ -0,0 +1,242 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2006-10-01
+// Updated : 2010-02-11
+// Licence : This source is under MIT License
+// File : glm/core/type_mat4x2.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_core_type_mat4x2
+#define glm_core_type_mat4x2
+
+#include "type_mat.hpp"
+
+namespace glm{
+namespace detail
+{
+ template <typename T> struct tvec1;
+ template <typename T> struct tvec2;
+ template <typename T> struct tvec3;
+ template <typename T> struct tvec4;
+ template <typename T> struct tmat2x2;
+ template <typename T> struct tmat2x3;
+ template <typename T> struct tmat2x4;
+ template <typename T> struct tmat3x2;
+ template <typename T> struct tmat3x3;
+ template <typename T> struct tmat3x4;
+ template <typename T> struct tmat4x2;
+ template <typename T> struct tmat4x3;
+ template <typename T> struct tmat4x4;
+
+ //! \brief Template for 4 columns and 2 rows matrix of floating-point numbers.
+ //! \ingroup core_template
+ template <typename T>
+ struct tmat4x2
+ {
+ enum ctor{null};
+ typedef T value_type;
+ typedef std::size_t size_type;
+ typedef tvec2<T> col_type;
+ typedef tvec4<T> row_type;
+ static GLM_FUNC_DECL size_type col_size();
+ static GLM_FUNC_DECL size_type row_size();
+
+ typedef tmat4x2<T> type;
+ typedef tmat2x4<T> transpose_type;
+
+ private:
+ // Data
+ col_type value[4];
+
+ public:
+ // Constructors
+ GLM_FUNC_DECL tmat4x2();
+ GLM_FUNC_DECL tmat4x2(tmat4x2 const & m);
+
+ GLM_FUNC_DECL explicit tmat4x2(
+ ctor Null);
+ GLM_FUNC_DECL explicit tmat4x2(
+ value_type const & x);
+ GLM_FUNC_DECL explicit tmat4x2(
+ value_type const & x0, value_type const & y0,
+ value_type const & x1, value_type const & y1,
+ value_type const & x2, value_type const & y2,
+ value_type const & x3, value_type const & y3);
+ GLM_FUNC_DECL explicit tmat4x2(
+ col_type const & v0,
+ col_type const & v1,
+ col_type const & v2,
+ col_type const & v3);
+
+ //////////////////////////////////////
+ // Conversions
+ template <typename U>
+ GLM_FUNC_DECL explicit tmat4x2(
+ U const & x);
+
+ template
+ <
+ typename X1, typename Y1,
+ typename X2, typename Y2,
+ typename X3, typename Y3,
+ typename X4, typename Y4
+ >
+ GLM_FUNC_DECL explicit tmat4x2(
+ X1 const & x1, Y1 const & y1,
+ X2 const & x2, Y2 const & y2,
+ X3 const & x3, Y3 const & y3,
+ X4 const & x4, Y4 const & y4);
+
+ template <typename V1, typename V2, typename V3, typename V4>
+ GLM_FUNC_DECL explicit tmat4x2(
+ tvec2<V1> const & v1,
+ tvec2<V2> const & v2,
+ tvec2<V3> const & v3,
+ tvec2<V4> const & v4);
+
+ // Matrix conversions
+ template <typename U>
+ GLM_FUNC_DECL explicit tmat4x2(tmat4x2<U> const & m);
+
+ GLM_FUNC_DECL explicit tmat4x2(tmat2x2<T> const & x);
+ GLM_FUNC_DECL explicit tmat4x2(tmat3x3<T> const & x);
+ GLM_FUNC_DECL explicit tmat4x2(tmat4x4<T> const & x);
+ GLM_FUNC_DECL explicit tmat4x2(tmat2x3<T> const & x);
+ GLM_FUNC_DECL explicit tmat4x2(tmat3x2<T> const & x);
+ GLM_FUNC_DECL explicit tmat4x2(tmat2x4<T> const & x);
+ GLM_FUNC_DECL explicit tmat4x2(tmat4x3<T> const & x);
+ GLM_FUNC_DECL explicit tmat4x2(tmat3x4<T> const & x);
+
+ // Accesses
+ GLM_FUNC_DECL col_type & operator[](size_type i);
+ GLM_FUNC_DECL col_type const & operator[](size_type i) const;
+
+ // Unary updatable operators
+ GLM_FUNC_DECL tmat4x2<T>& operator= (tmat4x2<T> const & m);
+ template <typename U>
+ GLM_FUNC_DECL tmat4x2<T>& operator= (tmat4x2<U> const & m);
+ template <typename U>
+ GLM_FUNC_DECL tmat4x2<T>& operator+= (U const & s);
+ template <typename U>
+ GLM_FUNC_DECL tmat4x2<T>& operator+= (tmat4x2<U> const & m);
+ template <typename U>
+ GLM_FUNC_DECL tmat4x2<T>& operator-= (U const & s);
+ template <typename U>
+ GLM_FUNC_DECL tmat4x2<T>& operator-= (tmat4x2<U> const & m);
+ template <typename U>
+ GLM_FUNC_DECL tmat4x2<T>& operator*= (U const & s);
+ template <typename U>
+ GLM_FUNC_DECL tmat4x2<T>& operator*= (tmat4x2<U> const & m);
+ template <typename U>
+ GLM_FUNC_DECL tmat4x2<T>& operator/= (U const & s);
+
+ GLM_FUNC_DECL tmat4x2<T>& operator++ ();
+ GLM_FUNC_DECL tmat4x2<T>& operator-- ();
+ };
+
+ // Binary operators
+ template <typename T>
+ tmat4x2<T> operator+ (
+ tmat4x2<T> const & m,
+ typename tmat4x2<T>::value_type const & s);
+
+ template <typename T>
+ tmat4x2<T> operator+ (
+ tmat4x2<T> const & m1,
+ tmat4x2<T> const & m2);
+
+ template <typename T>
+ tmat4x2<T> operator- (
+ tmat4x2<T> const & m,
+ typename tmat4x2<T>::value_type const & s);
+
+ template <typename T>
+ tmat4x2<T> operator- (
+ tmat4x2<T> const & m1,
+ tmat4x2<T> const & m2);
+
+ template <typename T>
+ tmat4x2<T> operator* (
+ tmat4x2<T> const & m,
+ typename tmat4x2<T>::value_type const & s);
+
+ template <typename T>
+ tmat4x2<T> operator* (
+ typename tmat4x2<T>::value_type const & s,
+ tmat4x2<T> const & m);
+
+ template <typename T>
+ typename tmat4x2<T>::col_type operator* (
+ tmat4x2<T> const & m,
+ typename tmat4x2<T>::row_type const & v);
+
+ template <typename T>
+ typename tmat4x2<T>::row_type operator* (
+ typename tmat4x2<T>::col_type const & v,
+ tmat4x2<T> const & m);
+
+ template <typename T>
+ tmat2x2<T> operator* (
+ tmat4x2<T> const & m1,
+ tmat2x4<T> const & m2);
+
+ template <typename T>
+ tmat4x2<T> operator/ (
+ tmat4x2<T> const & m,
+ typename tmat4x2<T>::value_type const & s);
+
+ template <typename T>
+ tmat4x2<T> operator/ (
+ typename tmat4x2<T>::value_type const & s,
+ tmat4x2<T> const & m);
+
+ // Unary constant operators
+ template <typename T>
+ tmat4x2<T> const operator- (
+ tmat4x2<T> const & m);
+
+ template <typename T>
+ tmat4x2<T> const operator-- (
+ tmat4x2<T> const & m,
+ int);
+
+ template <typename T>
+ tmat4x2<T> const operator++ (
+ tmat4x2<T> const & m,
+ int);
+
+} //namespace detail
+
+namespace core{
+namespace type{
+namespace precision
+{
+ //! 4 columns of 2 components matrix of low precision floating-point numbers.
+ //! There is no guarantee on the actual precision.
+ //! (From GLSL 1.30.8 specification, section 4.1.6 Matrices and section 4.5 Precision and Precision Qualifiers)
+ //! \ingroup core_precision
+ typedef detail::tmat4x2<lowp_float> lowp_mat4x2;
+
+ //! 4 columns of 2 components matrix of medium precision floating-point numbers.
+ //! There is no guarantee on the actual precision.
+ //! (From GLSL 1.30.8 specification, section 4.1.6 Matrices and section 4.5 Precision and Precision Qualifiers)
+ //! \ingroup core_precision
+ typedef detail::tmat4x2<mediump_float> mediump_mat4x2;
+
+ //! 4 columns of 2 components matrix of high precision floating-point numbers.
+ //! There is no guarantee on the actual precision.
+ //! (From GLSL 1.30.8 specification, section 4.1.6 Matrices and section 4.5 Precision and Precision Qualifiers)
+ //! \ingroup core_precision
+ typedef detail::tmat4x2<highp_float> highp_mat4x2;
+
+}//namespace precision
+}//namespace type
+}//namespace core
+}//namespace glm
+
+#ifndef GLM_EXTERNAL_TEMPLATE
+#include "type_mat4x2.inl"
+#endif
+
+#endif //glm_core_type_mat4x2
diff --git a/src/glm/core/type_mat4x2.inl b/src/glm/core/type_mat4x2.inl
new file mode 100644
index 0000000..9f01899
--- /dev/null
+++ b/src/glm/core/type_mat4x2.inl
@@ -0,0 +1,670 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2006-10-01
+// Updated : 2010-02-03
+// Licence : This source is under MIT License
+// File : glm/core/type_mat4x2.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm{
+namespace detail
+{
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename tmat4x2<T>::size_type tmat4x2<T>::col_size()
+ {
+ return 2;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename tmat4x2<T>::size_type tmat4x2<T>::row_size()
+ {
+ return 4;
+ }
+
+ //////////////////////////////////////
+ // Accesses
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename tmat4x2<T>::col_type &
+ tmat4x2<T>::operator[]
+ (
+ size_type i
+ )
+ {
+ assert(i < this->row_size());
+ return this->value[i];
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename tmat4x2<T>::col_type const &
+ tmat4x2<T>::operator[]
+ (
+ size_type i
+ ) const
+ {
+ assert(i < this->row_size());
+ return this->value[i];
+ }
+
+ //////////////////////////////////////////////////////////////
+ // Constructors
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x2<T>::tmat4x2()
+ {
+ value_type const Zero(0);
+ value_type const One(1);
+ this->value[0] = col_type(One, Zero);
+ this->value[1] = col_type(Zero, One);
+ this->value[2] = col_type(Zero, Zero);
+ this->value[3] = col_type(Zero, Zero);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x2<T>::tmat4x2
+ (
+ tmat4x2<T> const & m
+ )
+ {
+ this->value[0] = m.value[0];
+ this->value[1] = m.value[1];
+ this->value[2] = m.value[2];
+ this->value[3] = m.value[3];
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x2<T>::tmat4x2
+ (
+ ctor
+ )
+ {}
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x2<T>::tmat4x2
+ (
+ value_type const & s
+ )
+ {
+ value_type const Zero(0);
+ this->value[0] = col_type(s, Zero);
+ this->value[1] = col_type(Zero, s);
+ this->value[2] = col_type(Zero, Zero);
+ this->value[3] = col_type(Zero, Zero);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x2<T>::tmat4x2
+ (
+ value_type const & x0, value_type const & y0,
+ value_type const & x1, value_type const & y1,
+ value_type const & x2, value_type const & y2,
+ value_type const & x3, value_type const & y3
+ )
+ {
+ this->value[0] = col_type(x0, y0);
+ this->value[1] = col_type(x1, y1);
+ this->value[2] = col_type(x2, y2);
+ this->value[3] = col_type(x3, y3);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x2<T>::tmat4x2
+ (
+ col_type const & v0,
+ col_type const & v1,
+ col_type const & v2,
+ col_type const & v3
+ )
+ {
+ this->value[0] = v0;
+ this->value[1] = v1;
+ this->value[2] = v2;
+ this->value[3] = v3;
+ }
+
+ //////////////////////////////////////
+ // Convertion constructors
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_DECL tmat4x2<T>::tmat4x2
+ (
+ U const & s
+ )
+ {
+ value_type const Zero(0);
+ this->value[0] = tvec2<T>(value_type(s), Zero);
+ this->value[1] = tvec2<T>(Zero, value_type(s));
+ this->value[2] = tvec2<T>(Zero, Zero);
+ this->value[3] = tvec2<T>(Zero, Zero);
+ }
+
+ template <typename T>
+ template <
+ typename X1, typename Y1,
+ typename X2, typename Y2,
+ typename X3, typename Y3,
+ typename X4, typename Y4>
+ GLM_FUNC_DECL tmat4x2<T>::tmat4x2
+ (
+ X1 const & x1, Y1 const & y1,
+ X2 const & x2, Y2 const & y2,
+ X3 const & x3, Y3 const & y3,
+ X4 const & x4, Y4 const & y4
+ )
+ {
+ this->value[0] = col_type(value_type(x1), value_type(y1));
+ this->value[1] = col_type(value_type(x2), value_type(y2));
+ this->value[2] = col_type(value_type(x3), value_type(y3));
+ this->value[3] = col_type(value_type(x4), value_type(y4));
+ }
+
+ template <typename T>
+ template <typename V1, typename V2, typename V3, typename V4>
+ GLM_FUNC_DECL tmat4x2<T>::tmat4x2
+ (
+ tvec2<V1> const & v1,
+ tvec2<V2> const & v2,
+ tvec2<V3> const & v3,
+ tvec2<V4> const & v4
+ )
+ {
+ this->value[0] = col_type(v1);
+ this->value[1] = col_type(v2);
+ this->value[2] = col_type(v3);
+ this->value[3] = col_type(v4);
+ }
+
+ // Conversion
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat4x2<T>::tmat4x2
+ (
+ tmat4x2<U> const & m
+ )
+ {
+ this->value[0] = col_type(m[0]);
+ this->value[1] = col_type(m[1]);
+ this->value[2] = col_type(m[2]);
+ this->value[3] = col_type(m[3]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x2<T>::tmat4x2
+ (
+ tmat2x2<T> const & m
+ )
+ {
+ this->value[0] = col_type(m[0]);
+ this->value[1] = col_type(m[1]);
+ this->value[2] = col_type(value_type(0));
+ this->value[3] = col_type(value_type(0));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x2<T>::tmat4x2
+ (
+ tmat3x3<T> const & m
+ )
+ {
+ this->value[0] = col_type(m[0]);
+ this->value[1] = col_type(m[1]);
+ this->value[2] = col_type(m[2]);
+ this->value[3] = col_type(value_type(0));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x2<T>::tmat4x2
+ (
+ tmat4x4<T> const & m
+ )
+ {
+ this->value[0] = col_type(m[0]);
+ this->value[1] = col_type(m[1]);
+ this->value[2] = col_type(m[2]);
+ this->value[3] = col_type(m[3]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x2<T>::tmat4x2
+ (
+ tmat2x3<T> const & m
+ )
+ {
+ this->value[0] = col_type(m[0]);
+ this->value[1] = col_type(m[1]);
+ this->value[2] = col_type(value_type(0));
+ this->value[3] = col_type(value_type(0));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x2<T>::tmat4x2
+ (
+ tmat3x2<T> const & m
+ )
+ {
+ this->value[0] = col_type(m[0]);
+ this->value[1] = col_type(m[1]);
+ this->value[2] = col_type(m[2]);
+ this->value[3] = col_type(value_type(0));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x2<T>::tmat4x2
+ (
+ tmat2x4<T> const & m
+ )
+ {
+ this->value[0] = col_type(m[0]);
+ this->value[1] = col_type(m[1]);
+ this->value[2] = col_type(value_type(0));
+ this->value[3] = col_type(value_type(0));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x2<T>::tmat4x2
+ (
+ tmat4x3<T> const & m
+ )
+ {
+ this->value[0] = col_type(m[0]);
+ this->value[1] = col_type(m[1]);
+ this->value[2] = col_type(m[2]);
+ this->value[3] = col_type(m[3]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x2<T>::tmat4x2
+ (
+ tmat3x4<T> const & m
+ )
+ {
+ this->value[0] = col_type(m[0]);
+ this->value[1] = col_type(m[1]);
+ this->value[2] = col_type(m[2]);
+ this->value[3] = col_type(value_type(0));
+ }
+
+ //////////////////////////////////////////////////////////////
+ // Unary updatable operators
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x2<T>& tmat4x2<T>::operator=
+ (
+ tmat4x2<T> const & m
+ )
+ {
+ this->value[0] = m[0];
+ this->value[1] = m[1];
+ this->value[2] = m[2];
+ this->value[3] = m[3];
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat4x2<T>& tmat4x2<T>::operator=
+ (
+ tmat4x2<U> const & m
+ )
+ {
+ this->value[0] = m[0];
+ this->value[1] = m[1];
+ this->value[2] = m[2];
+ this->value[3] = m[3];
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat4x2<T> & tmat4x2<T>::operator+=
+ (
+ U const & s
+ )
+ {
+ this->value[0] += s;
+ this->value[1] += s;
+ this->value[2] += s;
+ this->value[3] += s;
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat4x2<T> & tmat4x2<T>::operator+=
+ (
+ tmat4x2<U> const & m
+ )
+ {
+ this->value[0] += m[0];
+ this->value[1] += m[1];
+ this->value[2] += m[2];
+ this->value[3] += m[3];
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat4x2<T> & tmat4x2<T>::operator-=
+ (
+ U const & s
+ )
+ {
+ this->value[0] -= s;
+ this->value[1] -= s;
+ this->value[2] -= s;
+ this->value[3] -= s;
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat4x2<T> & tmat4x2<T>::operator-=
+ (
+ tmat4x2<U> const & m
+ )
+ {
+ this->value[0] -= m[0];
+ this->value[1] -= m[1];
+ this->value[2] -= m[2];
+ this->value[3] -= m[3];
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat4x2<T> & tmat4x2<T>::operator*=
+ (
+ U const & s
+ )
+ {
+ this->value[0] *= s;
+ this->value[1] *= s;
+ this->value[2] *= s;
+ this->value[3] *= s;
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat4x2<T> & tmat4x2<T>::operator*=
+ (
+ tmat4x2<U> const & m
+ )
+ {
+ return (*this = tmat4x2<T>(*this * m));
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat4x2<T> & tmat4x2<T>::operator/=
+ (
+ U const & s
+ )
+ {
+ this->value[0] /= s;
+ this->value[1] /= s;
+ this->value[2] /= s;
+ this->value[3] /= s;
+ return *this;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x2<T> & tmat4x2<T>::operator++ ()
+ {
+ ++this->value[0];
+ ++this->value[1];
+ ++this->value[2];
+ ++this->value[3];
+ return *this;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x2<T> & tmat4x2<T>::operator-- ()
+ {
+ --this->value[0];
+ --this->value[1];
+ --this->value[2];
+ --this->value[3];
+ return *this;
+ }
+
+ //////////////////////////////////////////////////////////////
+ // Binary operators
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x2<T> operator+
+ (
+ tmat4x2<T> const & m,
+ typename tmat4x2<T>::value_type const & s
+ )
+ {
+ return tmat4x2<T>(
+ m[0] + s,
+ m[1] + s,
+ m[2] + s,
+ m[3] + s);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x2<T> operator+
+ (
+ tmat4x2<T> const & m1,
+ tmat4x2<T> const & m2
+ )
+ {
+ return tmat4x2<T>(
+ m1[0] + m2[0],
+ m1[1] + m2[1],
+ m1[2] + m2[2],
+ m1[3] + m2[3]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x2<T> operator-
+ (
+ tmat4x2<T> const & m,
+ typename tmat4x2<T>::value_type const & s
+ )
+ {
+ return tmat4x2<T>(
+ m[0] - s,
+ m[1] - s,
+ m[2] - s,
+ m[3] - s);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x2<T> operator-
+ (
+ tmat4x2<T> const & m1,
+ tmat4x2<T> const & m2
+ )
+ {
+ return tmat4x2<T>(
+ m1[0] - m2[0],
+ m1[1] - m2[1],
+ m1[2] - m2[2],
+ m1[3] - m2[3]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x2<T> operator*
+ (
+ tmat4x2<T> const & m,
+ typename tmat4x2<T>::value_type const & s
+ )
+ {
+ return tmat4x2<T>(
+ m[0] * s,
+ m[1] * s,
+ m[2] * s,
+ m[3] * s);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x2<T> operator*
+ (
+ typename tmat4x2<T>::value_type const & s,
+ tmat4x2<T> const & m
+ )
+ {
+ return tmat4x2<T>(
+ m[0] * s,
+ m[1] * s,
+ m[2] * s,
+ m[3] * s);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename tmat4x2<T>::col_type operator*
+ (
+ tmat4x2<T> const & m,
+ typename tmat4x2<T>::row_type const & v)
+ {
+ return typename tmat4x2<T>::col_type(
+ m[0][0] * v.x + m[1][0] * v.y + m[2][0] * v.z + m[3][0] * v.w,
+ m[0][1] * v.x + m[1][1] * v.y + m[2][1] * v.z + m[3][1] * v.w);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename tmat4x2<T>::row_type operator*
+ (
+ typename tmat4x2<T>::col_type const & v,
+ tmat4x2<T> const & m)
+ {
+ return typename tmat4x2<T>::row_type(
+ v.x * m[0][0] + v.y * m[0][1],
+ v.x * m[1][0] + v.y * m[1][1],
+ v.x * m[2][0] + v.y * m[2][1],
+ v.x * m[3][0] + v.y * m[3][1]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat2x2<T> operator*
+ (
+ tmat4x2<T> const & m1,
+ tmat2x4<T> const & m2
+ )
+ {
+ T const SrcA00 = m1[0][0];
+ T const SrcA01 = m1[0][1];
+ T const SrcA10 = m1[1][0];
+ T const SrcA11 = m1[1][1];
+ T const SrcA20 = m1[2][0];
+ T const SrcA21 = m1[2][1];
+ T const SrcA30 = m1[3][0];
+ T const SrcA31 = m1[3][1];
+
+ T const SrcB00 = m2[0][0];
+ T const SrcB01 = m2[0][1];
+ T const SrcB02 = m2[0][2];
+ T const SrcB03 = m2[0][3];
+ T const SrcB10 = m2[1][0];
+ T const SrcB11 = m2[1][1];
+ T const SrcB12 = m2[1][2];
+ T const SrcB13 = m2[1][3];
+
+ tmat2x2<T> Result(tmat2x2<T>::null);
+ Result[0][0] = SrcA00 * SrcB00 + SrcA10 * SrcB01 + SrcA20 * SrcB02 + SrcA30 * SrcB03;
+ Result[0][1] = SrcA01 * SrcB00 + SrcA11 * SrcB01 + SrcA21 * SrcB02 + SrcA31 * SrcB03;
+ Result[1][0] = SrcA00 * SrcB10 + SrcA10 * SrcB11 + SrcA20 * SrcB12 + SrcA30 * SrcB13;
+ Result[1][1] = SrcA01 * SrcB10 + SrcA11 * SrcB11 + SrcA21 * SrcB12 + SrcA31 * SrcB13;
+ return Result;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x2<T> operator/
+ (
+ tmat4x2<T> const & m,
+ typename tmat4x2<T>::value_type const & s
+ )
+ {
+ return tmat4x2<T>(
+ m[0] / s,
+ m[1] / s,
+ m[2] / s,
+ m[3] / s);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x2<T> operator/
+ (
+ typename tmat4x2<T>::value_type const & s,
+ tmat4x2<T> const & m
+ )
+ {
+ return tmat4x2<T>(
+ s / m[0],
+ s / m[1],
+ s / m[2],
+ s / m[3]);
+ }
+
+ // Unary constant operators
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x2<T> const operator-
+ (
+ tmat4x2<T> const & m
+ )
+ {
+ return tmat4x2<T>(
+ -m[0],
+ -m[1],
+ -m[2],
+ -m[3]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x2<T> const operator++
+ (
+ tmat4x2<T> const & m,
+ int
+ )
+ {
+ return tmat4x2<T>(
+ m[0] + typename tmat4x2<T>::value_type(1),
+ m[1] + typename tmat4x2<T>::value_type(1),
+ m[2] + typename tmat4x2<T>::value_type(1),
+ m[3] + typename tmat4x2<T>::value_type(1));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x2<T> const operator--
+ (
+ tmat4x2<T> const & m,
+ int
+ )
+ {
+ return tmat4x2<T>(
+ m[0] - typename tmat4x2<T>::value_type(1),
+ m[1] - typename tmat4x2<T>::value_type(1),
+ m[2] - typename tmat4x2<T>::value_type(1),
+ m[3] - typename tmat4x2<T>::value_type(1));
+ }
+
+ //////////////////////////////////////
+ // Boolean operators
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER bool operator==
+ (
+ tmat4x2<T> const & m1,
+ tmat4x2<T> const & m2
+ )
+ {
+ return (m1[0] == m2[0]) && (m1[1] == m2[1]) && (m1[2] == m2[2]) && (m1[3] == m2[3]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER bool operator!=
+ (
+ tmat4x2<T> const & m1,
+ tmat4x2<T> const & m2
+ )
+ {
+ return (m1[0] != m2[0]) || (m1[1] != m2[1]) || (m1[2] != m2[2]) || (m1[3] != m2[3]);
+ }
+
+} //namespace detail
+} //namespace glm
diff --git a/src/glm/core/type_mat4x3.hpp b/src/glm/core/type_mat4x3.hpp
new file mode 100644
index 0000000..bd1ad9f
--- /dev/null
+++ b/src/glm/core/type_mat4x3.hpp
@@ -0,0 +1,240 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2006-08-04
+// Updated : 2010-02-11
+// Licence : This source is under MIT License
+// File : glm/core/type_mat4x3.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_core_type_mat4x3
+#define glm_core_type_mat4x3
+
+#include "type_mat.hpp"
+
+namespace glm{
+namespace detail
+{
+ template <typename T> struct tvec1;
+ template <typename T> struct tvec2;
+ template <typename T> struct tvec3;
+ template <typename T> struct tvec4;
+ template <typename T> struct tmat2x2;
+ template <typename T> struct tmat2x3;
+ template <typename T> struct tmat2x4;
+ template <typename T> struct tmat3x2;
+ template <typename T> struct tmat3x3;
+ template <typename T> struct tmat3x4;
+ template <typename T> struct tmat4x2;
+ template <typename T> struct tmat4x3;
+ template <typename T> struct tmat4x4;
+
+ //! \brief Template for 4 columns and 3 rows matrix of floating-point numbers.
+ //! \ingroup core_template
+ template <typename T>
+ struct tmat4x3
+ {
+ enum ctor{null};
+ typedef T value_type;
+ typedef std::size_t size_type;
+ typedef tvec3<T> col_type;
+ typedef tvec4<T> row_type;
+ static GLM_FUNC_DECL size_type col_size();
+ static GLM_FUNC_DECL size_type row_size();
+
+ typedef tmat4x3<T> type;
+ typedef tmat3x4<T> transpose_type;
+
+ private:
+ // Data
+ col_type value[4];
+
+ public:
+ // Constructors
+ GLM_FUNC_DECL tmat4x3();
+ GLM_FUNC_DECL tmat4x3(tmat4x3 const & m);
+
+ GLM_FUNC_DECL explicit tmat4x3(
+ ctor Null);
+ GLM_FUNC_DECL explicit tmat4x3(
+ value_type const & x);
+ GLM_FUNC_DECL explicit tmat4x3(
+ value_type const & x0, value_type const & y0, value_type const & z0,
+ value_type const & x1, value_type const & y1, value_type const & z1,
+ value_type const & x2, value_type const & y2, value_type const & z2,
+ value_type const & x3, value_type const & y3, value_type const & z3);
+ GLM_FUNC_DECL explicit tmat4x3(
+ col_type const & v0,
+ col_type const & v1,
+ col_type const & v2,
+ col_type const & v3);
+
+ //////////////////////////////////////
+ // Conversions
+ template <typename U>
+ GLM_FUNC_DECL explicit tmat4x3(
+ U const & x);
+
+ template <
+ typename X1, typename Y1, typename Z1,
+ typename X2, typename Y2, typename Z2,
+ typename X3, typename Y3, typename Z3,
+ typename X4, typename Y4, typename Z4>
+ GLM_FUNC_DECL explicit tmat4x3(
+ X1 const & x1, Y1 const & y1, Z1 const & z1,
+ X2 const & x2, Y2 const & y2, Z2 const & z2,
+ X3 const & x3, Y3 const & y3, Z3 const & z3,
+ X4 const & x4, Y4 const & y4, Z4 const & z4);
+
+ template <typename V1, typename V2, typename V3, typename V4>
+ GLM_FUNC_DECL explicit tmat4x3(
+ tvec3<V1> const & v1,
+ tvec3<V2> const & v2,
+ tvec3<V3> const & v3,
+ tvec3<V4> const & v4);
+
+ // Matrix conversions
+ template <typename U>
+ GLM_FUNC_DECL explicit tmat4x3(tmat4x3<U> const & m);
+
+ GLM_FUNC_DECL explicit tmat4x3(tmat2x2<T> const & x);
+ GLM_FUNC_DECL explicit tmat4x3(tmat3x3<T> const & x);
+ GLM_FUNC_DECL explicit tmat4x3(tmat4x4<T> const & x);
+ GLM_FUNC_DECL explicit tmat4x3(tmat2x3<T> const & x);
+ GLM_FUNC_DECL explicit tmat4x3(tmat3x2<T> const & x);
+ GLM_FUNC_DECL explicit tmat4x3(tmat2x4<T> const & x);
+ GLM_FUNC_DECL explicit tmat4x3(tmat4x2<T> const & x);
+ GLM_FUNC_DECL explicit tmat4x3(tmat3x4<T> const & x);
+
+ // Accesses
+ col_type & operator[](size_type i);
+ col_type const & operator[](size_type i) const;
+
+ // Unary updatable operators
+ GLM_FUNC_DECL tmat4x3<T> & operator= (tmat4x3<T> const & m);
+ template <typename U>
+ GLM_FUNC_DECL tmat4x3<T> & operator= (tmat4x3<U> const & m);
+ template <typename U>
+ GLM_FUNC_DECL tmat4x3<T> & operator+= (U const & s);
+ template <typename U>
+ GLM_FUNC_DECL tmat4x3<T> & operator+= (tmat4x3<U> const & m);
+ template <typename U>
+ GLM_FUNC_DECL tmat4x3<T> & operator-= (U const & s);
+ template <typename U>
+ GLM_FUNC_DECL tmat4x3<T> & operator-= (tmat4x3<U> const & m);
+ template <typename U>
+ GLM_FUNC_DECL tmat4x3<T> & operator*= (U const & s);
+ template <typename U>
+ GLM_FUNC_DECL tmat4x3<T> & operator*= (tmat4x3<U> const & m);
+ template <typename U>
+ GLM_FUNC_DECL tmat4x3<T> & operator/= (U const & s);
+
+ GLM_FUNC_DECL tmat4x3<T> & operator++ ();
+ GLM_FUNC_DECL tmat4x3<T> & operator-- ();
+ };
+
+ // Binary operators
+ template <typename T>
+ tmat4x3<T> operator+ (
+ tmat4x3<T> const & m,
+ typename tmat4x3<T>::value_type const & s);
+
+ template <typename T>
+ tmat4x3<T> operator+ (
+ tmat4x3<T> const & m1,
+ tmat4x3<T> const & m2);
+
+ template <typename T>
+ tmat4x3<T> operator- (
+ tmat4x3<T> const & m,
+ typename tmat4x3<T>::value_type const & s);
+
+ template <typename T>
+ tmat4x3<T> operator- (
+ tmat4x3<T> const & m1,
+ tmat4x3<T> const & m2);
+
+ template <typename T>
+ tmat4x3<T> operator* (
+ tmat4x3<T> const & m,
+ typename tmat4x3<T>::value_type const & s);
+
+ template <typename T>
+ tmat4x3<T> operator* (
+ typename tmat4x3<T>::value_type const & s,
+ tmat4x3<T> const & m);
+
+ template <typename T>
+ typename tmat4x3<T>::col_type operator* (
+ tmat4x3<T> const & m,
+ typename tmat4x3<T>::row_type const & v);
+
+ template <typename T>
+ typename tmat4x3<T>::row_type operator* (
+ typename tmat4x3<T>::col_type const & v,
+ tmat4x3<T> const & m);
+
+ template <typename T>
+ tmat3x3<T> operator* (
+ tmat4x3<T> const & m1,
+ tmat3x4<T> const & m2);
+
+ template <typename T>
+ tmat4x3<T> operator/ (
+ tmat4x3<T> const & m,
+ typename tmat4x3<T>::value_type const & s);
+
+ template <typename T>
+ tmat4x3<T> operator/ (
+ typename tmat4x3<T>::value_type const & s,
+ tmat4x3<T> const & m);
+
+ // Unary constant operators
+ template <typename T>
+ tmat4x3<T> const operator- (
+ tmat4x3<T> const & m);
+
+ template <typename T>
+ tmat4x3<T> const operator-- (
+ tmat4x3<T> const & m,
+ int);
+
+ template <typename T>
+ tmat4x3<T> const operator++ (
+ tmat4x3<T> const & m,
+ int);
+
+}//namespace detail
+
+namespace core{
+namespace type{
+namespace precision
+{
+ //! 4 columns of 3 components matrix of low precision floating-point numbers.
+ //! There is no guarantee on the actual precision.
+ //! (From GLSL 1.30.8 specification, section 4.1.6 Matrices and section 4.5 Precision and Precision Qualifiers)
+ //! \ingroup core_precision
+ typedef detail::tmat4x3<lowp_float> lowp_mat4x3;
+
+ //! 4 columns of 3 components matrix of medium precision floating-point numbers.
+ //! There is no guarantee on the actual precision.
+ //! (From GLSL 1.30.8 specification, section 4.1.6 Matrices and section 4.5 Precision and Precision Qualifiers)
+ //! \ingroup core_precision
+ typedef detail::tmat4x3<mediump_float> mediump_mat4x3;
+
+ //! 4 columns of 3 components matrix of high precision floating-point numbers.
+ //! There is no guarantee on the actual precision.
+ //! (From GLSL 1.30.8 specification, section 4.1.6 Matrices and section 4.5 Precision and Precision Qualifiers)
+ //! \ingroup core_precision
+ typedef detail::tmat4x3<highp_float> highp_mat4x3;
+
+}//namespace precision
+}//namespace type
+}//namespace core
+}//namespace glm
+
+#ifndef GLM_EXTERNAL_TEMPLATE
+#include "type_mat4x3.inl"
+#endif //GLM_EXTERNAL_TEMPLATE
+
+#endif//glm_core_type_mat4x3
diff --git a/src/glm/core/type_mat4x3.inl b/src/glm/core/type_mat4x3.inl
new file mode 100644
index 0000000..b07c078
--- /dev/null
+++ b/src/glm/core/type_mat4x3.inl
@@ -0,0 +1,675 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2006-04-17
+// Updated : 2010-02-02
+// Licence : This source is under MIT License
+// File : glm/core/type_mat4x3.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm{
+namespace detail
+{
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename tmat4x3<T>::size_type tmat4x3<T>::col_size()
+ {
+ return 3;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename tmat4x3<T>::size_type tmat4x3<T>::row_size()
+ {
+ return 4;
+ }
+
+ //////////////////////////////////////
+ // Accesses
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename tmat4x3<T>::col_type &
+ tmat4x3<T>::operator[]
+ (
+ size_type i
+ )
+ {
+ assert(i < this->row_size());
+ return this->value[i];
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename tmat4x3<T>::col_type const &
+ tmat4x3<T>::operator[]
+ (
+ size_type i
+ ) const
+ {
+ assert(i < this->row_size());
+ return this->value[i];
+ }
+
+ //////////////////////////////////////////////////////////////
+ // Constructors
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x3<T>::tmat4x3()
+ {
+ value_type const Zero(0);
+ value_type const One(1);
+ this->value[0] = col_type(One, Zero, Zero);
+ this->value[1] = col_type(Zero, One, Zero);
+ this->value[2] = col_type(Zero, Zero, One);
+ this->value[3] = col_type(Zero, Zero, Zero);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x3<T>::tmat4x3
+ (
+ tmat4x3<T> const & m
+ )
+ {
+ this->value[0] = m.value[0];
+ this->value[1] = m.value[1];
+ this->value[2] = m.value[2];
+ this->value[3] = m.value[3];
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x3<T>::tmat4x3
+ (
+ ctor
+ )
+ {}
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x3<T>::tmat4x3
+ (
+ value_type const & s
+ )
+ {
+ value_type const Zero(0);
+ this->value[0] = col_type(s, Zero, Zero);
+ this->value[1] = col_type(Zero, s, Zero);
+ this->value[2] = col_type(Zero, Zero, s);
+ this->value[3] = col_type(Zero, Zero, Zero);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x3<T>::tmat4x3
+ (
+ value_type const & x0, value_type const & y0, value_type const & z0,
+ value_type const & x1, value_type const & y1, value_type const & z1,
+ value_type const & x2, value_type const & y2, value_type const & z2,
+ value_type const & x3, value_type const & y3, value_type const & z3
+ )
+ {
+ this->value[0] = col_type(x0, y0, z0);
+ this->value[1] = col_type(x1, y1, z1);
+ this->value[2] = col_type(x2, y2, z2);
+ this->value[3] = col_type(x3, y3, z3);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x3<T>::tmat4x3
+ (
+ col_type const & v0,
+ col_type const & v1,
+ col_type const & v2,
+ col_type const & v3
+ )
+ {
+ this->value[0] = v0;
+ this->value[1] = v1;
+ this->value[2] = v2;
+ this->value[3] = v3;
+ }
+
+ //////////////////////////////////////
+ // Convertion constructors
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_DECL tmat4x3<T>::tmat4x3
+ (
+ U const & s
+ )
+ {
+ value_type const Zero(0);
+ this->value[0] = tvec3<T>(value_type(s), Zero, Zero);
+ this->value[1] = tvec3<T>(Zero, value_type(s), Zero);
+ this->value[2] = tvec3<T>(Zero, Zero, value_type(s));
+ this->value[3] = tvec3<T>(Zero, Zero, Zero);
+ }
+
+ template <typename T>
+ template <
+ typename X1, typename Y1, typename Z1,
+ typename X2, typename Y2, typename Z2,
+ typename X3, typename Y3, typename Z3,
+ typename X4, typename Y4, typename Z4>
+ GLM_FUNC_DECL tmat4x3<T>::tmat4x3
+ (
+ X1 const & x1, Y1 const & y1, Z1 const & z1,
+ X2 const & x2, Y2 const & y2, Z2 const & z2,
+ X3 const & x3, Y3 const & y3, Z3 const & z3,
+ X4 const & x4, Y4 const & y4, Z4 const & z4
+ )
+ {
+ this->value[0] = col_type(value_type(x1), value_type(y1), value_type(z1));
+ this->value[1] = col_type(value_type(x2), value_type(y2), value_type(z2));
+ this->value[2] = col_type(value_type(x3), value_type(y3), value_type(z3));
+ this->value[3] = col_type(value_type(x4), value_type(y4), value_type(z4));
+ }
+
+ template <typename T>
+ template <typename V1, typename V2, typename V3, typename V4>
+ GLM_FUNC_DECL tmat4x3<T>::tmat4x3
+ (
+ tvec3<V1> const & v1,
+ tvec3<V2> const & v2,
+ tvec3<V3> const & v3,
+ tvec3<V4> const & v4
+ )
+ {
+ this->value[0] = col_type(v1);
+ this->value[1] = col_type(v2);
+ this->value[2] = col_type(v3);
+ this->value[3] = col_type(v4);
+ }
+
+ //////////////////////////////////////////////////////////////
+ // Matrix conversions
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat4x3<T>::tmat4x3
+ (
+ tmat4x3<U> const & m
+ )
+ {
+ this->value[0] = col_type(m[0]);
+ this->value[1] = col_type(m[1]);
+ this->value[2] = col_type(m[2]);
+ this->value[3] = col_type(m[3]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x3<T>::tmat4x3
+ (
+ tmat2x2<T> const & m
+ )
+ {
+ this->value[0] = col_type(m[0], value_type(0));
+ this->value[1] = col_type(m[1], value_type(0));
+ this->value[2] = col_type(m[2], value_type(1));
+ this->value[3] = col_type(value_type(0));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x3<T>::tmat4x3
+ (
+ tmat3x3<T> const & m
+ )
+ {
+ this->value[0] = col_type(m[0]);
+ this->value[1] = col_type(m[1]);
+ this->value[2] = col_type(m[2]);
+ this->value[3] = col_type(value_type(0));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x3<T>::tmat4x3
+ (
+ tmat4x4<T> const & m
+ )
+ {
+ this->value[0] = col_type(m[0]);
+ this->value[1] = col_type(m[1]);
+ this->value[2] = col_type(m[2]);
+ this->value[3] = col_type(m[3]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x3<T>::tmat4x3
+ (
+ tmat2x3<T> const & m
+ )
+ {
+ this->value[0] = col_type(m[0]);
+ this->value[1] = col_type(m[1]);
+ this->value[2] = col_type(value_type(0), value_type(0), value_type(1));
+ this->value[3] = col_type(value_type(0));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x3<T>::tmat4x3
+ (
+ tmat3x2<T> const & m
+ )
+ {
+ this->value[0] = col_type(m[0], value_type(0));
+ this->value[1] = col_type(m[1], value_type(0));
+ this->value[2] = col_type(m[2], value_type(1));
+ this->value[3] = col_type(value_type(0));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x3<T>::tmat4x3
+ (
+ tmat2x4<T> const & m
+ )
+ {
+ this->value[0] = col_type(m[0]);
+ this->value[1] = col_type(m[1]);
+ this->value[2] = col_type(value_type(0), value_type(0), value_type(1));
+ this->value[3] = col_type(value_type(0));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x3<T>::tmat4x3
+ (
+ tmat4x2<T> const & m
+ )
+ {
+ this->value[0] = col_type(m[0], value_type(0));
+ this->value[1] = col_type(m[1], value_type(0));
+ this->value[2] = col_type(m[2], value_type(1));
+ this->value[3] = col_type(m[3], value_type(0));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x3<T>::tmat4x3
+ (
+ tmat3x4<T> const & m
+ )
+ {
+ this->value[0] = col_type(m[0]);
+ this->value[1] = col_type(m[1]);
+ this->value[2] = col_type(m[2]);
+ this->value[3] = col_type(value_type(0));
+ }
+
+ //////////////////////////////////////////////////////////////
+ // Unary updatable operators
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x3<T>& tmat4x3<T>::operator=
+ (
+ tmat4x3<T> const & m
+ )
+ {
+ this->value[0] = m[0];
+ this->value[1] = m[1];
+ this->value[2] = m[2];
+ this->value[3] = m[3];
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat4x3<T>& tmat4x3<T>::operator=
+ (
+ tmat4x3<U> const & m
+ )
+ {
+ this->value[0] = m[0];
+ this->value[1] = m[1];
+ this->value[2] = m[2];
+ this->value[3] = m[3];
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat4x3<T> & tmat4x3<T>::operator+=
+ (
+ U const & s
+ )
+ {
+ this->value[0] += s;
+ this->value[1] += s;
+ this->value[2] += s;
+ this->value[3] += s;
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat4x3<T> & tmat4x3<T>::operator+=
+ (
+ tmat4x3<U> const & m
+ )
+ {
+ this->value[0] += m[0];
+ this->value[1] += m[1];
+ this->value[2] += m[2];
+ this->value[3] += m[3];
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat4x3<T> & tmat4x3<T>::operator-=
+ (
+ U const & s
+ )
+ {
+ this->value[0] -= s;
+ this->value[1] -= s;
+ this->value[2] -= s;
+ this->value[3] -= s;
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat4x3<T> & tmat4x3<T>::operator-=
+ (
+ tmat4x3<U> const & m
+ )
+ {
+ this->value[0] -= m[0];
+ this->value[1] -= m[1];
+ this->value[2] -= m[2];
+ this->value[3] -= m[3];
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat4x3<T> & tmat4x3<T>::operator*=
+ (
+ U const & s
+ )
+ {
+ this->value[0] *= s;
+ this->value[1] *= s;
+ this->value[2] *= s;
+ this->value[3] *= s;
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat4x3<T> & tmat4x3<T>::operator*=
+ (
+ tmat4x3<U> const & m
+ )
+ {
+ return (*this = tmat4x3<T>(*this * m));
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat4x3<T> & tmat4x3<T>::operator/=
+ (
+ U const & s
+ )
+ {
+ this->value[0] /= s;
+ this->value[1] /= s;
+ this->value[2] /= s;
+ this->value[3] /= s;
+ return *this;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x3<T> & tmat4x3<T>::operator++ ()
+ {
+ ++this->value[0];
+ ++this->value[1];
+ ++this->value[2];
+ ++this->value[3];
+ return *this;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x3<T> & tmat4x3<T>::operator-- ()
+ {
+ --this->value[0];
+ --this->value[1];
+ --this->value[2];
+ --this->value[3];
+ return *this;
+ }
+
+ //////////////////////////////////////////////////////////////
+ // Binary operators
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x3<T> operator+ (
+ tmat4x3<T> const & m,
+ typename tmat4x3<T>::value_type const & s)
+ {
+ return tmat4x3<T>(
+ m[0] + s,
+ m[1] + s,
+ m[2] + s,
+ m[3] + s);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x3<T> operator+ (
+ tmat4x3<T> const & m1,
+ tmat4x3<T> const & m2)
+ {
+ return tmat4x3<T>(
+ m1[0] + m2[0],
+ m1[1] + m2[1],
+ m1[2] + m2[2],
+ m1[3] + m2[3]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x3<T> operator- (
+ tmat4x3<T> const & m,
+ typename tmat4x3<T>::value_type const & s)
+ {
+ return tmat4x3<T>(
+ m[0] - s,
+ m[1] - s,
+ m[2] - s,
+ m[3] - s);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x3<T> operator- (
+ tmat4x3<T> const & m1,
+ tmat4x3<T> const & m2)
+ {
+ return tmat4x3<T>(
+ m1[0] - m2[0],
+ m1[1] - m2[1],
+ m1[2] - m2[2],
+ m1[3] - m2[3]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x3<T> operator* (
+ tmat4x3<T> const & m,
+ typename tmat4x3<T>::value_type const & s)
+ {
+ return tmat4x3<T>(
+ m[0] * s,
+ m[1] * s,
+ m[2] * s,
+ m[3] * s);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x3<T> operator* (
+ typename tmat4x3<T>::value_type const & s,
+ tmat4x3<T> const & m)
+ {
+ return tmat4x3<T>(
+ m[0] * s,
+ m[1] * s,
+ m[2] * s,
+ m[3] * s);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename tmat4x3<T>::col_type operator*
+ (
+ tmat4x3<T> const & m,
+ typename tmat4x3<T>::row_type const & v)
+ {
+ return typename tmat4x3<T>::col_type(
+ m[0][0] * v.x + m[1][0] * v.y + m[2][0] * v.z + m[3][0] * v.w,
+ m[0][1] * v.x + m[1][1] * v.y + m[2][1] * v.z + m[3][1] * v.w,
+ m[0][2] * v.x + m[1][2] * v.y + m[2][2] * v.z + m[3][2] * v.w);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename tmat4x3<T>::row_type operator*
+ (
+ typename tmat4x3<T>::col_type const & v,
+ tmat4x3<T> const & m)
+ {
+ return typename tmat4x3<T>::row_type(
+ v.x * m[0][0] + v.y * m[0][1] + v.z * m[0][2],
+ v.x * m[1][0] + v.y * m[1][1] + v.z * m[1][2],
+ v.x * m[2][0] + v.y * m[2][1] + v.z * m[2][2],
+ v.x * m[3][0] + v.y * m[3][1] + v.z * m[3][2]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat3x3<T> operator*
+ (
+ tmat4x3<T> const & m1,
+ tmat3x4<T> const & m2
+ )
+ {
+ T const SrcA00 = m1[0][0];
+ T const SrcA01 = m1[0][1];
+ T const SrcA02 = m1[0][2];
+ T const SrcA10 = m1[1][0];
+ T const SrcA11 = m1[1][1];
+ T const SrcA12 = m1[1][2];
+ T const SrcA20 = m1[2][0];
+ T const SrcA21 = m1[2][1];
+ T const SrcA22 = m1[2][2];
+ T const SrcA30 = m1[3][0];
+ T const SrcA31 = m1[3][1];
+ T const SrcA32 = m1[3][2];
+
+ T const SrcB00 = m2[0][0];
+ T const SrcB01 = m2[0][1];
+ T const SrcB02 = m2[0][2];
+ T const SrcB03 = m2[0][3];
+ T const SrcB10 = m2[1][0];
+ T const SrcB11 = m2[1][1];
+ T const SrcB12 = m2[1][2];
+ T const SrcB13 = m2[1][3];
+ T const SrcB20 = m2[2][0];
+ T const SrcB21 = m2[2][1];
+ T const SrcB22 = m2[2][2];
+ T const SrcB23 = m2[2][3];
+
+ tmat3x3<T> Result(tmat3x3<T>::null);
+ Result[0][0] = SrcA00 * SrcB00 + SrcA10 * SrcB01 + SrcA20 * SrcB02 + SrcA30 * SrcB03;
+ Result[0][1] = SrcA01 * SrcB00 + SrcA11 * SrcB01 + SrcA21 * SrcB02 + SrcA31 * SrcB03;
+ Result[0][2] = SrcA02 * SrcB00 + SrcA12 * SrcB01 + SrcA22 * SrcB02 + SrcA32 * SrcB03;
+ Result[1][0] = SrcA00 * SrcB10 + SrcA10 * SrcB11 + SrcA20 * SrcB12 + SrcA30 * SrcB13;
+ Result[1][1] = SrcA01 * SrcB10 + SrcA11 * SrcB11 + SrcA21 * SrcB12 + SrcA31 * SrcB13;
+ Result[1][2] = SrcA02 * SrcB10 + SrcA12 * SrcB11 + SrcA22 * SrcB12 + SrcA32 * SrcB13;
+ Result[2][0] = SrcA00 * SrcB20 + SrcA10 * SrcB21 + SrcA20 * SrcB22 + SrcA30 * SrcB23;
+ Result[2][1] = SrcA01 * SrcB20 + SrcA11 * SrcB21 + SrcA21 * SrcB22 + SrcA31 * SrcB23;
+ Result[2][2] = SrcA02 * SrcB20 + SrcA12 * SrcB21 + SrcA22 * SrcB22 + SrcA32 * SrcB23;
+ return Result;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x3<T> operator/
+ (
+ tmat4x3<T> const & m,
+ typename tmat4x3<T>::value_type const & s
+ )
+ {
+ return tmat4x3<T>(
+ m[0] / s,
+ m[1] / s,
+ m[2] / s,
+ m[3] / s);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x3<T> operator/
+ (
+ typename tmat4x3<T>::value_type const & s,
+ tmat4x3<T> const & m
+ )
+ {
+ return tmat4x3<T>(
+ s / m[0],
+ s / m[1],
+ s / m[2],
+ s / m[3]);
+ }
+
+ // Unary constant operators
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x3<T> const operator-
+ (
+ tmat4x3<T> const & m
+ )
+ {
+ return tmat4x3<T>(
+ -m[0],
+ -m[1],
+ -m[2],
+ -m[3]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x3<T> const operator++
+ (
+ tmat4x3<T> const & m,
+ int
+ )
+ {
+ return tmat4x3<T>(
+ m[0] + T(1),
+ m[1] + T(1),
+ m[2] + T(1),
+ m[3] + T(1));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x3<T> const operator--
+ (
+ tmat4x3<T> const & m,
+ int
+ )
+ {
+ return tmat4x3<T>(
+ m[0] - T(1),
+ m[1] - T(1),
+ m[2] - T(1),
+ m[3] - T(1));
+ }
+
+ //////////////////////////////////////
+ // Boolean operators
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER bool operator==
+ (
+ tmat4x3<T> const & m1,
+ tmat4x3<T> const & m2
+ )
+ {
+ return (m1[0] == m2[0]) && (m1[1] == m2[1]) && (m1[2] == m2[2]) && (m1[3] == m2[3]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER bool operator!=
+ (
+ tmat4x3<T> const & m1,
+ tmat4x3<T> const & m2
+ )
+ {
+ return (m1[0] != m2[0]) || (m1[1] != m2[1]) || (m1[2] != m2[2]) || (m1[3] != m2[3]);
+ }
+
+} //namespace detail
+} //namespace glm
+
diff --git a/src/glm/core/type_mat4x4.hpp b/src/glm/core/type_mat4x4.hpp
new file mode 100644
index 0000000..da93efd
--- /dev/null
+++ b/src/glm/core/type_mat4x4.hpp
@@ -0,0 +1,286 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2005-01-27
+// Updated : 2011-06-02
+// Licence : This source is under MIT License
+// File : glm/core/type_mat4x4.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_core_type_mat4x4
+#define glm_core_type_mat4x4
+
+#include "type_mat.hpp"
+
+namespace glm{
+namespace detail
+{
+ template <typename T> struct tvec1;
+ template <typename T> struct tvec2;
+ template <typename T> struct tvec3;
+ template <typename T> struct tvec4;
+ template <typename T> struct tmat2x2;
+ template <typename T> struct tmat2x3;
+ template <typename T> struct tmat2x4;
+ template <typename T> struct tmat3x2;
+ template <typename T> struct tmat3x3;
+ template <typename T> struct tmat3x4;
+ template <typename T> struct tmat4x2;
+ template <typename T> struct tmat4x3;
+ template <typename T> struct tmat4x4;
+
+ //! \brief Template for 4 * 4 matrix of floating-point numbers.
+ //! \ingroup core_template
+ template <typename T>
+ struct tmat4x4
+ {
+ enum ctor{null};
+ typedef T value_type;
+ typedef std::size_t size_type;
+ typedef tvec4<T> col_type;
+ typedef tvec4<T> row_type;
+ static GLM_FUNC_DECL size_type col_size();
+ static GLM_FUNC_DECL size_type row_size();
+
+ typedef tmat4x4<T> type;
+ typedef tmat4x4<T> transpose_type;
+
+ public:
+ // Implementation detail
+ GLM_FUNC_DECL tmat4x4<T> _inverse() const;
+
+ private:
+ // Data
+ col_type value[4];
+
+ public:
+ // Constructors
+ GLM_FUNC_DECL tmat4x4();
+ GLM_FUNC_DECL tmat4x4(tmat4x4 const & m);
+
+ GLM_FUNC_DECL explicit tmat4x4(
+ ctor Null);
+ GLM_FUNC_DECL explicit tmat4x4(
+ value_type const & x);
+ GLM_FUNC_DECL explicit tmat4x4(
+ value_type const & x0, value_type const & y0, value_type const & z0, value_type const & w0,
+ value_type const & x1, value_type const & y1, value_type const & z1, value_type const & w1,
+ value_type const & x2, value_type const & y2, value_type const & z2, value_type const & w2,
+ value_type const & x3, value_type const & y3, value_type const & z3, value_type const & w3);
+ GLM_FUNC_DECL explicit tmat4x4(
+ col_type const & v0,
+ col_type const & v1,
+ col_type const & v2,
+ col_type const & v3);
+
+ //////////////////////////////////////
+ // Conversions
+ template <typename U>
+ GLM_FUNC_DECL explicit tmat4x4(
+ U const & x);
+
+ template <
+ typename X1, typename Y1, typename Z1, typename W1,
+ typename X2, typename Y2, typename Z2, typename W2,
+ typename X3, typename Y3, typename Z3, typename W3,
+ typename X4, typename Y4, typename Z4, typename W4>
+ GLM_FUNC_DECL explicit tmat4x4(
+ X1 const & x1, Y1 const & y1, Z1 const & z1, W1 const & w1,
+ X2 const & x2, Y2 const & y2, Z2 const & z2, W2 const & w2,
+ X3 const & x3, Y3 const & y3, Z3 const & z3, W3 const & w3,
+ X4 const & x4, Y4 const & y4, Z4 const & z4, W4 const & w4);
+
+ template <typename V1, typename V2, typename V3, typename V4>
+ GLM_FUNC_DECL explicit tmat4x4(
+ tvec4<V1> const & v1,
+ tvec4<V2> const & v2,
+ tvec4<V3> const & v3,
+ tvec4<V4> const & v4);
+
+ // Matrix conversions
+ template <typename U>
+ GLM_FUNC_DECL explicit tmat4x4(tmat4x4<U> const & m);
+
+ GLM_FUNC_DECL explicit tmat4x4(tmat2x2<T> const & x);
+ GLM_FUNC_DECL explicit tmat4x4(tmat3x3<T> const & x);
+ GLM_FUNC_DECL explicit tmat4x4(tmat2x3<T> const & x);
+ GLM_FUNC_DECL explicit tmat4x4(tmat3x2<T> const & x);
+ GLM_FUNC_DECL explicit tmat4x4(tmat2x4<T> const & x);
+ GLM_FUNC_DECL explicit tmat4x4(tmat4x2<T> const & x);
+ GLM_FUNC_DECL explicit tmat4x4(tmat3x4<T> const & x);
+ GLM_FUNC_DECL explicit tmat4x4(tmat4x3<T> const & x);
+
+ // Accesses
+ GLM_FUNC_DECL col_type & operator[](size_type i);
+ GLM_FUNC_DECL col_type const & operator[](size_type i) const;
+
+ // Unary updatable operators
+ GLM_FUNC_DECL tmat4x4<T> & operator= (tmat4x4<T> const & m);
+ template <typename U>
+ GLM_FUNC_DECL tmat4x4<T> & operator= (tmat4x4<U> const & m);
+ template <typename U>
+ GLM_FUNC_DECL tmat4x4<T> & operator+= (U const & s);
+ template <typename U>
+ GLM_FUNC_DECL tmat4x4<T> & operator+= (tmat4x4<U> const & m);
+ template <typename U>
+ GLM_FUNC_DECL tmat4x4<T> & operator-= (U const & s);
+ template <typename U>
+ GLM_FUNC_DECL tmat4x4<T> & operator-= (tmat4x4<U> const & m);
+ template <typename U>
+ GLM_FUNC_DECL tmat4x4<T> & operator*= (U const & s);
+ template <typename U>
+ GLM_FUNC_DECL tmat4x4<T> & operator*= (tmat4x4<U> const & m);
+ template <typename U>
+ GLM_FUNC_DECL tmat4x4<T> & operator/= (U const & s);
+ template <typename U>
+ GLM_FUNC_DECL tmat4x4<T> & operator/= (tmat4x4<U> const & m);
+ GLM_FUNC_DECL tmat4x4<T> & operator++ ();
+ GLM_FUNC_DECL tmat4x4<T> & operator-- ();
+ };
+
+ // Binary operators
+ template <typename T>
+ tmat4x4<T> operator+ (
+ tmat4x4<T> const & m,
+ typename tmat4x4<T>::value_type const & s);
+
+ template <typename T>
+ tmat4x4<T> operator+ (
+ typename tmat4x4<T>::value_type const & s,
+ tmat4x4<T> const & m);
+
+ template <typename T>
+ tmat4x4<T> operator+ (
+ tmat4x4<T> const & m1,
+ tmat4x4<T> const & m2);
+
+ template <typename T>
+ tmat4x4<T> operator- (
+ tmat4x4<T> const & m,
+ typename tmat4x4<T>::value_type const & s);
+
+ template <typename T>
+ tmat4x4<T> operator- (
+ typename tmat4x4<T>::value_type const & s,
+ tmat4x4<T> const & m);
+
+ template <typename T>
+ tmat4x4<T> operator- (
+ tmat4x4<T> const & m1,
+ tmat4x4<T> const & m2);
+
+ template <typename T>
+ tmat4x4<T> operator* (
+ tmat4x4<T> const & m,
+ typename tmat4x4<T>::value_type const & s);
+
+ template <typename T>
+ tmat4x4<T> operator* (
+ typename tmat4x4<T>::value_type const & s,
+ tmat4x4<T> const & m);
+
+ template <typename T>
+ typename tmat4x4<T>::col_type operator* (
+ tmat4x4<T> const & m,
+ typename tmat4x4<T>::row_type const & v);
+
+ template <typename T>
+ typename tmat4x4<T>::row_type operator* (
+ typename tmat4x4<T>::col_type const & v,
+ tmat4x4<T> const & m);
+
+ template <typename T>
+ tmat4x4<T> operator* (
+ tmat4x4<T> const & m1,
+ tmat4x4<T> const & m2);
+
+ template <typename T>
+ tmat4x4<T> operator/ (
+ tmat4x4<T> const & m,
+ typename tmat4x4<T>::value_type const & s);
+
+ template <typename T>
+ tmat4x4<T> operator/ (
+ typename tmat4x4<T>::value_type const & s,
+ tmat4x4<T> const & m);
+
+ template <typename T>
+ typename tmat4x4<T>::col_type operator/ (
+ tmat4x4<T> const & m,
+ typename tmat4x4<T>::row_type const & v);
+
+ template <typename T>
+ typename tmat4x4<T>::row_type operator/ (
+ typename tmat4x4<T>::col_type & v,
+ tmat4x4<T> const & m);
+
+ template <typename T>
+ tmat4x4<T> operator/ (
+ tmat4x4<T> const & m1,
+ tmat4x4<T> const & m2);
+
+ // Unary constant operators
+ template <typename T>
+ tmat4x4<T> const operator- (
+ tmat4x4<T> const & m);
+
+ template <typename T>
+ tmat4x4<T> const operator-- (
+ tmat4x4<T> const & m, int);
+
+ template <typename T>
+ tmat4x4<T> const operator++ (
+ tmat4x4<T> const & m, int);
+
+} //namespace detail
+
+namespace core{
+namespace type{
+namespace precision
+{
+ //! 4 columns of 4 components matrix of low precision floating-point numbers.
+ //! There is no guarantee on the actual precision.
+ //! From GLSL 1.30.8 specification, section 4.1.6 Matrices and section 4.5 Precision and Precision Qualifiers
+ //! \ingroup core_precision
+ typedef detail::tmat4x4<lowp_float> lowp_mat4;
+
+ //! 4 columns of 4 components matrix of medium precision floating-point numbers.
+ //! There is no guarantee on the actual precision.
+ //! From GLSL 1.30.8 specification, section 4.1.6 Matrices and section 4.5 Precision and Precision Qualifiers
+ //! \ingroup core_precision
+ typedef detail::tmat4x4<mediump_float> mediump_mat4;
+
+ //! 4 columns of 4 components matrix of high precision floating-point numbers.
+ //! There is no guarantee on the actual precision.
+ //! From GLSL 1.30.8 specification, section 4.1.6 Matrices and section 4.5 Precision and Precision Qualifiers
+ //! \ingroup core_precision
+ typedef detail::tmat4x4<highp_float> highp_mat4;
+
+ //! 4 columns of 4 components matrix of low precision floating-point numbers.
+ //! There is no guarantee on the actual precision.
+ //! From GLSL 1.30.8 specification, section 4.1.6 Matrices and section 4.5 Precision and Precision Qualifiers
+ //! \ingroup core_precision
+ typedef detail::tmat4x4<lowp_float> lowp_mat4x4;
+
+ //! 4 columns of 4 components matrix of medium precision floating-point numbers.
+ //! There is no guarantee on the actual precision.
+ //! From GLSL 1.30.8 specification, section 4.1.6 Matrices and section 4.5 Precision and Precision Qualifiers
+ //! \ingroup core_precision
+ typedef detail::tmat4x4<mediump_float> mediump_mat4x4;
+
+ //! 4 columns of 4 components matrix of high precision floating-point numbers.
+ //! There is no guarantee on the actual precision.
+ //! From GLSL 1.30.8 specification, section 4.1.6 Matrices and section 4.5 Precision and Precision Qualifiers
+ //! \ingroup core_precision
+ typedef detail::tmat4x4<highp_float> highp_mat4x4;
+
+}//namespace precision
+}//namespace type
+}//namespace core
+}//namespace glm
+
+#ifndef GLM_EXTERNAL_TEMPLATE
+#include "type_mat4x4.inl"
+#endif//GLM_EXTERNAL_TEMPLATE
+
+#endif//glm_core_type_mat4x4
diff --git a/src/glm/core/type_mat4x4.inl b/src/glm/core/type_mat4x4.inl
new file mode 100644
index 0000000..b1322db
--- /dev/null
+++ b/src/glm/core/type_mat4x4.inl
@@ -0,0 +1,840 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2005-01-27
+// Updated : 2010-02-05
+// Licence : This source is under MIT License
+// File : glm/core/type_mat4x4.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm{
+namespace detail
+{
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename tmat4x4<T>::size_type tmat4x4<T>::col_size()
+ {
+ return 4;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename tmat4x4<T>::size_type tmat4x4<T>::row_size()
+ {
+ return 4;
+ }
+
+ //////////////////////////////////////
+ // Accesses
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename tmat4x4<T>::col_type &
+ tmat4x4<T>::operator[]
+ (
+ size_type i
+ )
+ {
+ assert(i < this->row_size());
+ return this->value[i];
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename tmat4x4<T>::col_type const &
+ tmat4x4<T>::operator[]
+ (
+ size_type i
+ ) const
+ {
+ assert(i < this->row_size());
+ return this->value[i];
+ }
+
+ //////////////////////////////////////////////////////////////
+ // Constructors
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x4<T>::tmat4x4()
+ {
+ value_type Zero(0);
+ value_type One(1);
+ this->value[0] = col_type(One, Zero, Zero, Zero);
+ this->value[1] = col_type(Zero, One, Zero, Zero);
+ this->value[2] = col_type(Zero, Zero, One, Zero);
+ this->value[3] = col_type(Zero, Zero, Zero, One);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x4<T>::tmat4x4
+ (
+ tmat4x4<T> const & m
+ )
+ {
+ this->value[0] = m.value[0];
+ this->value[1] = m.value[1];
+ this->value[2] = m.value[2];
+ this->value[3] = m.value[3];
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x4<T>::tmat4x4
+ (
+ ctor
+ )
+ {}
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x4<T>::tmat4x4
+ (
+ value_type const & s
+ )
+ {
+ value_type const Zero(0);
+ this->value[0] = col_type(s, Zero, Zero, Zero);
+ this->value[1] = col_type(Zero, s, Zero, Zero);
+ this->value[2] = col_type(Zero, Zero, s, Zero);
+ this->value[3] = col_type(Zero, Zero, Zero, s);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x4<T>::tmat4x4
+ (
+ value_type const & x0, value_type const & y0, value_type const & z0, value_type const & w0,
+ value_type const & x1, value_type const & y1, value_type const & z1, value_type const & w1,
+ value_type const & x2, value_type const & y2, value_type const & z2, value_type const & w2,
+ value_type const & x3, value_type const & y3, value_type const & z3, value_type const & w3
+ )
+ {
+ this->value[0] = col_type(x0, y0, z0, w0);
+ this->value[1] = col_type(x1, y1, z1, w1);
+ this->value[2] = col_type(x2, y2, z2, w2);
+ this->value[3] = col_type(x3, y3, z3, w3);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x4<T>::tmat4x4
+ (
+ col_type const & v0,
+ col_type const & v1,
+ col_type const & v2,
+ col_type const & v3
+ )
+ {
+ this->value[0] = v0;
+ this->value[1] = v1;
+ this->value[2] = v2;
+ this->value[3] = v3;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat4x4<T>::tmat4x4
+ (
+ tmat4x4<U> const & m
+ )
+ {
+ this->value[0] = col_type(m[0]);
+ this->value[1] = col_type(m[1]);
+ this->value[2] = col_type(m[2]);
+ this->value[3] = col_type(m[3]);
+ }
+
+ //////////////////////////////////////
+ // Convertion constructors
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_DECL tmat4x4<T>::tmat4x4
+ (
+ U const & s
+ )
+ {
+ GLM_STATIC_ASSERT(detail::type<U>::is_float || std::numeric_limits<U>::is_integer, "*mat4x4 constructor only takes float and integer types");
+
+ value_type const Zero(0);
+ this->value[0] = tvec4<T>(value_type(s), Zero, Zero, Zero);
+ this->value[1] = tvec4<T>(Zero, value_type(s), Zero, Zero);
+ this->value[2] = tvec4<T>(Zero, Zero, value_type(s), Zero);
+ this->value[3] = tvec4<T>(Zero, Zero, Zero, value_type(s));
+ }
+
+ template <typename T>
+ template <
+ typename X1, typename Y1, typename Z1, typename W1,
+ typename X2, typename Y2, typename Z2, typename W2,
+ typename X3, typename Y3, typename Z3, typename W3,
+ typename X4, typename Y4, typename Z4, typename W4>
+ GLM_FUNC_DECL tmat4x4<T>::tmat4x4
+ (
+ X1 const & x1, Y1 const & y1, Z1 const & z1, W1 const & w1,
+ X2 const & x2, Y2 const & y2, Z2 const & z2, W2 const & w2,
+ X3 const & x3, Y3 const & y3, Z3 const & z3, W3 const & w3,
+ X4 const & x4, Y4 const & y4, Z4 const & z4, W4 const & w4
+ )
+ {
+ GLM_STATIC_ASSERT(detail::type<X1>::is_float || std::numeric_limits<X1>::is_integer, "*mat4x4 constructor only takes float and integer types, 1st parameter type invalid.");
+ GLM_STATIC_ASSERT(detail::type<Y1>::is_float || std::numeric_limits<Y1>::is_integer, "*mat4x4 constructor only takes float and integer types, 2nd parameter type invalid.");
+ GLM_STATIC_ASSERT(detail::type<Z1>::is_float || std::numeric_limits<Z1>::is_integer, "*mat4x4 constructor only takes float and integer types, 3rd parameter type invalid.");
+ GLM_STATIC_ASSERT(detail::type<W1>::is_float || std::numeric_limits<W1>::is_integer, "*mat4x4 constructor only takes float and integer types, 4th parameter type invalid.");
+
+ GLM_STATIC_ASSERT(detail::type<X2>::is_float || std::numeric_limits<X2>::is_integer, "*mat4x4 constructor only takes float and integer types, 5th parameter type invalid.");
+ GLM_STATIC_ASSERT(detail::type<Y2>::is_float || std::numeric_limits<Y2>::is_integer, "*mat4x4 constructor only takes float and integer types, 6th parameter type invalid.");
+ GLM_STATIC_ASSERT(detail::type<Z2>::is_float || std::numeric_limits<Z2>::is_integer, "*mat4x4 constructor only takes float and integer types, 7th parameter type invalid.");
+ GLM_STATIC_ASSERT(detail::type<W2>::is_float || std::numeric_limits<W2>::is_integer, "*mat4x4 constructor only takes float and integer types, 8th parameter type invalid.");
+
+ GLM_STATIC_ASSERT(detail::type<X3>::is_float || std::numeric_limits<X3>::is_integer, "*mat4x4 constructor only takes float and integer types, 9th parameter type invalid.");
+ GLM_STATIC_ASSERT(detail::type<Y3>::is_float || std::numeric_limits<Y3>::is_integer, "*mat4x4 constructor only takes float and integer types, 10th parameter type invalid.");
+ GLM_STATIC_ASSERT(detail::type<Z3>::is_float || std::numeric_limits<Z3>::is_integer, "*mat4x4 constructor only takes float and integer types, 11th parameter type invalid.");
+ GLM_STATIC_ASSERT(detail::type<W3>::is_float || std::numeric_limits<W3>::is_integer, "*mat4x4 constructor only takes float and integer types, 12th parameter type invalid.");
+
+ GLM_STATIC_ASSERT(detail::type<X4>::is_float || std::numeric_limits<X4>::is_integer, "*mat4x4 constructor only takes float and integer types, 13th parameter type invalid.");
+ GLM_STATIC_ASSERT(detail::type<Y4>::is_float || std::numeric_limits<Y4>::is_integer, "*mat4x4 constructor only takes float and integer types, 14th parameter type invalid.");
+ GLM_STATIC_ASSERT(detail::type<Z4>::is_float || std::numeric_limits<Z4>::is_integer, "*mat4x4 constructor only takes float and integer types, 15th parameter type invalid.");
+ GLM_STATIC_ASSERT(detail::type<W4>::is_float || std::numeric_limits<W4>::is_integer, "*mat4x4 constructor only takes float and integer types, 16th parameter type invalid.");
+
+ this->value[0] = col_type(value_type(x1), value_type(y1), value_type(z1), value_type(w1));
+ this->value[1] = col_type(value_type(x2), value_type(y2), value_type(z2), value_type(w2));
+ this->value[2] = col_type(value_type(x3), value_type(y3), value_type(z3), value_type(w3));
+ this->value[3] = col_type(value_type(x4), value_type(y4), value_type(z4), value_type(w4));
+ }
+
+ template <typename T>
+ template <typename V1, typename V2, typename V3, typename V4>
+ GLM_FUNC_DECL tmat4x4<T>::tmat4x4
+ (
+ tvec4<V1> const & v1,
+ tvec4<V2> const & v2,
+ tvec4<V3> const & v3,
+ tvec4<V4> const & v4
+ )
+ {
+ GLM_STATIC_ASSERT(detail::type<V1>::is_float || std::numeric_limits<V1>::is_integer, "*mat4x4 constructor only takes float and integer types, 1st parameter type invalid.");
+ GLM_STATIC_ASSERT(detail::type<V2>::is_float || std::numeric_limits<V2>::is_integer, "*mat4x4 constructor only takes float and integer types, 2nd parameter type invalid.");
+ GLM_STATIC_ASSERT(detail::type<V3>::is_float || std::numeric_limits<V3>::is_integer, "*mat4x4 constructor only takes float and integer types, 3rd parameter type invalid.");
+ GLM_STATIC_ASSERT(detail::type<V4>::is_float || std::numeric_limits<V4>::is_integer, "*mat4x4 constructor only takes float and integer types, 4th parameter type invalid.");
+
+ this->value[0] = col_type(v1);
+ this->value[1] = col_type(v2);
+ this->value[2] = col_type(v3);
+ this->value[3] = col_type(v4);
+ }
+
+ //////////////////////////////////////
+ // Matrix convertion constructors
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x4<T>::tmat4x4
+ (
+ tmat2x2<T> const & m
+ )
+ {
+ this->value[0] = col_type(m[0], detail::tvec2<T>(0));
+ this->value[1] = col_type(m[1], detail::tvec2<T>(0));
+ this->value[2] = col_type(value_type(0));
+ this->value[3] = col_type(value_type(0), value_type(0), value_type(0), value_type(1));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x4<T>::tmat4x4
+ (
+ tmat3x3<T> const & m
+ )
+ {
+ this->value[0] = col_type(m[0], value_type(0));
+ this->value[1] = col_type(m[1], value_type(0));
+ this->value[2] = col_type(m[2], value_type(0));
+ this->value[3] = col_type(value_type(0), value_type(0), value_type(0), value_type(1));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x4<T>::tmat4x4
+ (
+ tmat2x3<T> const & m
+ )
+ {
+ this->value[0] = col_type(m[0], value_type(0));
+ this->value[1] = col_type(m[1], value_type(0));
+ this->value[2] = col_type(value_type(0));
+ this->value[3] = col_type(value_type(0), value_type(0), value_type(0), value_type(1));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x4<T>::tmat4x4
+ (
+ tmat3x2<T> const & m
+ )
+ {
+ this->value[0] = col_type(m[0], detail::tvec2<T>(0));
+ this->value[1] = col_type(m[1], detail::tvec2<T>(0));
+ this->value[2] = col_type(m[2], detail::tvec2<T>(0));
+ this->value[3] = col_type(value_type(0), value_type(0), value_type(0), value_type(1));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x4<T>::tmat4x4
+ (
+ tmat2x4<T> const & m
+ )
+ {
+ this->value[0] = m[0];
+ this->value[1] = m[1];
+ this->value[2] = col_type(T(0));
+ this->value[3] = col_type(T(0), T(0), T(0), T(1));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x4<T>::tmat4x4
+ (
+ tmat4x2<T> const & m
+ )
+ {
+ this->value[0] = col_type(m[0], detail::tvec2<T>(0));
+ this->value[1] = col_type(m[1], detail::tvec2<T>(0));
+ this->value[2] = col_type(T(0));
+ this->value[3] = col_type(T(0), T(0), T(0), T(1));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x4<T>::tmat4x4
+ (
+ tmat3x4<T> const & m
+ )
+ {
+ this->value[0] = m[0];
+ this->value[1] = m[1];
+ this->value[2] = m[2];
+ this->value[3] = col_type(T(0), T(0), T(0), T(1));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x4<T>::tmat4x4
+ (
+ tmat4x3<T> const & m
+ )
+ {
+ this->value[0] = col_type(m[0], T(0));
+ this->value[1] = col_type(m[1], T(0));
+ this->value[2] = col_type(m[2], T(0));
+ this->value[3] = col_type(m[3], T(1));
+ }
+
+ //////////////////////////////////////////////////////////////
+ // Operators
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x4<T>& tmat4x4<T>::operator=
+ (
+ tmat4x4<T> const & m
+ )
+ {
+ //memcpy could be faster
+ //memcpy(&this->value, &m.value, 16 * sizeof(valType));
+ this->value[0] = m[0];
+ this->value[1] = m[1];
+ this->value[2] = m[2];
+ this->value[3] = m[3];
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat4x4<T>& tmat4x4<T>::operator=
+ (
+ tmat4x4<U> const & m
+ )
+ {
+ //memcpy could be faster
+ //memcpy(&this->value, &m.value, 16 * sizeof(valType));
+ this->value[0] = m[0];
+ this->value[1] = m[1];
+ this->value[2] = m[2];
+ this->value[3] = m[3];
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat4x4<T>& tmat4x4<T>::operator+=
+ (
+ U const & s
+ )
+ {
+ this->value[0] += s;
+ this->value[1] += s;
+ this->value[2] += s;
+ this->value[3] += s;
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat4x4<T>& tmat4x4<T>::operator+=
+ (
+ tmat4x4<U> const & m
+ )
+ {
+ this->value[0] += m[0];
+ this->value[1] += m[1];
+ this->value[2] += m[2];
+ this->value[3] += m[3];
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat4x4<T> & tmat4x4<T>::operator-=
+ (
+ U const & s
+ )
+ {
+ this->value[0] -= s;
+ this->value[1] -= s;
+ this->value[2] -= s;
+ this->value[3] -= s;
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat4x4<T> & tmat4x4<T>::operator-=
+ (
+ tmat4x4<U> const & m
+ )
+ {
+ this->value[0] -= m[0];
+ this->value[1] -= m[1];
+ this->value[2] -= m[2];
+ this->value[3] -= m[3];
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat4x4<T> & tmat4x4<T>::operator*=
+ (
+ U const & s
+ )
+ {
+ this->value[0] *= s;
+ this->value[1] *= s;
+ this->value[2] *= s;
+ this->value[3] *= s;
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat4x4<T> & tmat4x4<T>::operator*=
+ (
+ tmat4x4<U> const & m
+ )
+ {
+ return (*this = *this * m);
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat4x4<T> & tmat4x4<T>::operator/=
+ (
+ U const & s
+ )
+ {
+ this->value[0] /= s;
+ this->value[1] /= s;
+ this->value[2] /= s;
+ this->value[3] /= s;
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tmat4x4<T> & tmat4x4<T>::operator/=
+ (
+ tmat4x4<U> const & m
+ )
+ {
+ return (*this = *this / m);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x4<T> & tmat4x4<T>::operator++ ()
+ {
+ ++this->value[0];
+ ++this->value[1];
+ ++this->value[2];
+ ++this->value[3];
+ return *this;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x4<T> & tmat4x4<T>::operator-- ()
+ {
+ --this->value[0];
+ --this->value[1];
+ --this->value[2];
+ --this->value[3];
+ return *this;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x4<T> tmat4x4<T>::_inverse() const
+ {
+ // Calculate all mat2 determinants
+ value_type SubFactor00 = this->value[2][2] * this->value[3][3] - this->value[3][2] * this->value[2][3];
+ value_type SubFactor01 = this->value[2][1] * this->value[3][3] - this->value[3][1] * this->value[2][3];
+ value_type SubFactor02 = this->value[2][1] * this->value[3][2] - this->value[3][1] * this->value[2][2];
+ value_type SubFactor03 = this->value[2][0] * this->value[3][3] - this->value[3][0] * this->value[2][3];
+ value_type SubFactor04 = this->value[2][0] * this->value[3][2] - this->value[3][0] * this->value[2][2];
+ value_type SubFactor05 = this->value[2][0] * this->value[3][1] - this->value[3][0] * this->value[2][1];
+ value_type SubFactor06 = this->value[1][2] * this->value[3][3] - this->value[3][2] * this->value[1][3];
+ value_type SubFactor07 = this->value[1][1] * this->value[3][3] - this->value[3][1] * this->value[1][3];
+ value_type SubFactor08 = this->value[1][1] * this->value[3][2] - this->value[3][1] * this->value[1][2];
+ value_type SubFactor09 = this->value[1][0] * this->value[3][3] - this->value[3][0] * this->value[1][3];
+ value_type SubFactor10 = this->value[1][0] * this->value[3][2] - this->value[3][0] * this->value[1][2];
+ value_type SubFactor11 = this->value[1][1] * this->value[3][3] - this->value[3][1] * this->value[1][3];
+ value_type SubFactor12 = this->value[1][0] * this->value[3][1] - this->value[3][0] * this->value[1][1];
+ value_type SubFactor13 = this->value[1][2] * this->value[2][3] - this->value[2][2] * this->value[1][3];
+ value_type SubFactor14 = this->value[1][1] * this->value[2][3] - this->value[2][1] * this->value[1][3];
+ value_type SubFactor15 = this->value[1][1] * this->value[2][2] - this->value[2][1] * this->value[1][2];
+ value_type SubFactor16 = this->value[1][0] * this->value[2][3] - this->value[2][0] * this->value[1][3];
+ value_type SubFactor17 = this->value[1][0] * this->value[2][2] - this->value[2][0] * this->value[1][2];
+ value_type SubFactor18 = this->value[1][0] * this->value[2][1] - this->value[2][0] * this->value[1][1];
+/*
+ tmat4x4<T> Inverse(
+ + (this->value[1][1] * SubFactor00 - this->value[1][2] * SubFactor01 + this->value[1][3] * SubFactor02),
+ - (this->value[1][0] * SubFactor00 - this->value[1][2] * SubFactor03 + this->value[1][3] * SubFactor04),
+ + (this->value[1][0] * SubFactor01 - this->value[1][1] * SubFactor03 + this->value[1][3] * SubFactor05),
+ - (this->value[1][0] * SubFactor02 - this->value[1][1] * SubFactor04 + this->value[1][2] * SubFactor05),
+
+ - (this->value[0][1] * SubFactor00 - this->value[0][2] * SubFactor01 + this->value[0][3] * SubFactor02),
+ + (this->value[0][0] * SubFactor00 - this->value[0][2] * SubFactor03 + this->value[0][3] * SubFactor04),
+ - (this->value[0][0] * SubFactor01 - this->value[0][1] * SubFactor03 + this->value[0][3] * SubFactor05),
+ + (this->value[0][0] * SubFactor02 - this->value[0][1] * SubFactor04 + this->value[0][2] * SubFactor05),
+
+ + (this->value[0][1] * SubFactor06 - this->value[0][2] * SubFactor07 + this->value[0][3] * SubFactor08),
+ - (this->value[0][0] * SubFactor06 - this->value[0][2] * SubFactor09 + this->value[0][3] * SubFactor10),
+ + (this->value[0][0] * SubFactor11 - this->value[0][1] * SubFactor09 + this->value[0][3] * SubFactor12),
+ - (this->value[0][0] * SubFactor08 - this->value[0][1] * SubFactor10 + this->value[0][2] * SubFactor12),
+
+ - (this->value[0][1] * SubFactor13 - this->value[0][2] * SubFactor14 + this->value[0][3] * SubFactor15),
+ + (this->value[0][0] * SubFactor13 - this->value[0][2] * SubFactor16 + this->value[0][3] * SubFactor17),
+ - (this->value[0][0] * SubFactor14 - this->value[0][1] * SubFactor16 + this->value[0][3] * SubFactor18),
+ + (this->value[0][0] * SubFactor15 - this->value[0][1] * SubFactor17 + this->value[0][2] * SubFactor18));
+*/
+ tmat4x4<T> Inverse(
+ + this->value[1][1] * SubFactor00 - this->value[1][2] * SubFactor01 + this->value[1][3] * SubFactor02,
+ - this->value[1][0] * SubFactor00 + this->value[1][2] * SubFactor03 - this->value[1][3] * SubFactor04,
+ + this->value[1][0] * SubFactor01 - this->value[1][1] * SubFactor03 + this->value[1][3] * SubFactor05,
+ - this->value[1][0] * SubFactor02 + this->value[1][1] * SubFactor04 - this->value[1][2] * SubFactor05,
+
+ - this->value[0][1] * SubFactor00 + this->value[0][2] * SubFactor01 - this->value[0][3] * SubFactor02,
+ + this->value[0][0] * SubFactor00 - this->value[0][2] * SubFactor03 + this->value[0][3] * SubFactor04,
+ - this->value[0][0] * SubFactor01 + this->value[0][1] * SubFactor03 - this->value[0][3] * SubFactor05,
+ + this->value[0][0] * SubFactor02 - this->value[0][1] * SubFactor04 + this->value[0][2] * SubFactor05,
+
+ + this->value[0][1] * SubFactor06 - this->value[0][2] * SubFactor07 + this->value[0][3] * SubFactor08,
+ - this->value[0][0] * SubFactor06 + this->value[0][2] * SubFactor09 - this->value[0][3] * SubFactor10,
+ + this->value[0][0] * SubFactor11 - this->value[0][1] * SubFactor09 + this->value[0][3] * SubFactor12,
+ - this->value[0][0] * SubFactor08 + this->value[0][1] * SubFactor10 - this->value[0][2] * SubFactor12,
+
+ - this->value[0][1] * SubFactor13 + this->value[0][2] * SubFactor14 - this->value[0][3] * SubFactor15,
+ + this->value[0][0] * SubFactor13 - this->value[0][2] * SubFactor16 + this->value[0][3] * SubFactor17,
+ - this->value[0][0] * SubFactor14 + this->value[0][1] * SubFactor16 - this->value[0][3] * SubFactor18,
+ + this->value[0][0] * SubFactor15 - this->value[0][1] * SubFactor17 + this->value[0][2] * SubFactor18);
+
+ value_type Determinant =
+ + this->value[0][0] * Inverse[0][0]
+ + this->value[0][1] * Inverse[1][0]
+ + this->value[0][2] * Inverse[2][0]
+ + this->value[0][3] * Inverse[3][0];
+
+ Inverse /= Determinant;
+ return Inverse;
+ }
+
+ // Binary operators
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x4<T> operator+
+ (
+ tmat4x4<T> const & m,
+ typename tmat4x4<T>::value_type const & s
+ )
+ {
+ return tmat4x4<T>(
+ m[0] + s,
+ m[1] + s,
+ m[2] + s,
+ m[3] + s);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x4<T> operator+
+ (
+ typename tmat4x4<T>::value_type const & s,
+ tmat4x4<T> const & m
+ )
+ {
+ return tmat4x4<T>(
+ m[0] + s,
+ m[1] + s,
+ m[2] + s,
+ m[3] + s);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x4<T> operator+
+ (
+ tmat4x4<T> const & m1,
+ tmat4x4<T> const & m2
+ )
+ {
+ return tmat4x4<T>(
+ m1[0] + m2[0],
+ m1[1] + m2[1],
+ m1[2] + m2[2],
+ m1[3] + m2[3]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x4<T> operator-
+ (
+ tmat4x4<T> const & m,
+ typename tmat4x4<T>::value_type const & s
+ )
+ {
+ return tmat4x4<T>(
+ m[0] - s,
+ m[1] - s,
+ m[2] - s,
+ m[3] - s);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x4<T> operator-
+ (
+ typename tmat4x4<T>::value_type const & s,
+ tmat4x4<T> const & m
+ )
+ {
+ return tmat4x4<T>(
+ s - m[0],
+ s - m[1],
+ s - m[2],
+ s - m[3]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x4<T> operator-
+ (
+ tmat4x4<T> const & m1,
+ tmat4x4<T> const & m2
+ )
+ {
+ return tmat4x4<T>(
+ m1[0] - m2[0],
+ m1[1] - m2[1],
+ m1[2] - m2[2],
+ m1[3] - m2[3]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x4<T> operator*
+ (
+ tmat4x4<T> const & m,
+ typename tmat4x4<T>::value_type const & s
+ )
+ {
+ return tmat4x4<T>(
+ m[0] * s,
+ m[1] * s,
+ m[2] * s,
+ m[3] * s);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x4<T> operator*
+ (
+ typename tmat4x4<T>::value_type const & s,
+ tmat4x4<T> const & m
+ )
+ {
+ return tmat4x4<T>(
+ m[0] * s,
+ m[1] * s,
+ m[2] * s,
+ m[3] * s);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename tmat4x4<T>::col_type operator*
+ (
+ tmat4x4<T> const & m,
+ typename tmat4x4<T>::row_type const & v
+ )
+ {
+ return typename tmat4x4<T>::col_type(
+ m[0][0] * v.x + m[1][0] * v.y + m[2][0] * v.z + m[3][0] * v.w,
+ m[0][1] * v.x + m[1][1] * v.y + m[2][1] * v.z + m[3][1] * v.w,
+ m[0][2] * v.x + m[1][2] * v.y + m[2][2] * v.z + m[3][2] * v.w,
+ m[0][3] * v.x + m[1][3] * v.y + m[2][3] * v.z + m[3][3] * v.w);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename tmat4x4<T>::row_type operator*
+ (
+ typename tmat4x4<T>::col_type const & v,
+ tmat4x4<T> const & m
+ )
+ {
+ return typename tmat4x4<T>::row_type(
+ m[0][0] * v.x + m[0][1] * v.y + m[0][2] * v.z + m[0][3] * v.w,
+ m[1][0] * v.x + m[1][1] * v.y + m[1][2] * v.z + m[1][3] * v.w,
+ m[2][0] * v.x + m[2][1] * v.y + m[2][2] * v.z + m[2][3] * v.w,
+ m[3][0] * v.x + m[3][1] * v.y + m[3][2] * v.z + m[3][3] * v.w);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x4<T> operator*
+ (
+ tmat4x4<T> const & m1,
+ tmat4x4<T> const & m2
+ )
+ {
+ typename tmat4x4<T>::col_type const SrcA0 = m1[0];
+ typename tmat4x4<T>::col_type const SrcA1 = m1[1];
+ typename tmat4x4<T>::col_type const SrcA2 = m1[2];
+ typename tmat4x4<T>::col_type const SrcA3 = m1[3];
+
+ typename tmat4x4<T>::col_type const SrcB0 = m2[0];
+ typename tmat4x4<T>::col_type const SrcB1 = m2[1];
+ typename tmat4x4<T>::col_type const SrcB2 = m2[2];
+ typename tmat4x4<T>::col_type const SrcB3 = m2[3];
+
+ tmat4x4<T> Result(tmat4x4<T>::null);
+ Result[0] = SrcA0 * SrcB0[0] + SrcA1 * SrcB0[1] + SrcA2 * SrcB0[2] + SrcA3 * SrcB0[3];
+ Result[1] = SrcA0 * SrcB1[0] + SrcA1 * SrcB1[1] + SrcA2 * SrcB1[2] + SrcA3 * SrcB1[3];
+ Result[2] = SrcA0 * SrcB2[0] + SrcA1 * SrcB2[1] + SrcA2 * SrcB2[2] + SrcA3 * SrcB2[3];
+ Result[3] = SrcA0 * SrcB3[0] + SrcA1 * SrcB3[1] + SrcA2 * SrcB3[2] + SrcA3 * SrcB3[3];
+ return Result;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x4<T> operator/
+ (
+ tmat4x4<T> const & m,
+ typename tmat4x4<T>::value_type const & s
+ )
+ {
+ return tmat4x4<T>(
+ m[0] / s,
+ m[1] / s,
+ m[2] / s,
+ m[3] / s);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x4<T> operator/
+ (
+ typename tmat4x4<T>::value_type const & s,
+ tmat4x4<T> const & m
+ )
+ {
+ return tmat4x4<T>(
+ s / m[0],
+ s / m[1],
+ s / m[2],
+ s / m[3]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename tmat4x4<T>::col_type operator/
+ (
+ tmat4x4<T> const & m,
+ typename tmat4x4<T>::row_type const & v
+ )
+ {
+ return m._inverse() * v;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename tmat4x4<T>::row_type operator/
+ (
+ typename tmat4x4<T>::col_type const & v,
+ tmat4x4<T> const & m
+ )
+ {
+ return v * m._inverse();
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x4<T> operator/
+ (
+ tmat4x4<T> const & m1,
+ tmat4x4<T> const & m2
+ )
+ {
+ return m1 * m2._inverse();
+ }
+
+ // Unary constant operators
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x4<T> const operator-
+ (
+ tmat4x4<T> const & m
+ )
+ {
+ return tmat4x4<T>(
+ -m[0],
+ -m[1],
+ -m[2],
+ -m[3]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x4<T> const operator++
+ (
+ tmat4x4<T> const & m,
+ int
+ )
+ {
+ return tmat4x4<T>(
+ m[0] + typename tmat4x4<T>::value_type(1),
+ m[1] + typename tmat4x4<T>::value_type(1),
+ m[2] + typename tmat4x4<T>::value_type(1),
+ m[3] + typename tmat4x4<T>::value_type(1));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tmat4x4<T> const operator--
+ (
+ tmat4x4<T> const & m,
+ int
+ )
+ {
+ return tmat4x4<T>(
+ m[0] - typename tmat4x4<T>::value_type(1),
+ m[1] - typename tmat4x4<T>::value_type(1),
+ m[2] - typename tmat4x4<T>::value_type(1),
+ m[3] - typename tmat4x4<T>::value_type(1));
+ }
+
+ //////////////////////////////////////
+ // Boolean operators
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER bool operator==
+ (
+ tmat4x4<T> const & m1,
+ tmat4x4<T> const & m2
+ )
+ {
+ return (m1[0] == m2[0]) && (m1[1] == m2[1]) && (m1[2] == m2[2]) && (m1[3] == m2[3]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER bool operator!=
+ (
+ tmat4x4<T> const & m1,
+ tmat4x4<T> const & m2
+ )
+ {
+ return (m1[0] != m2[0]) || (m1[1] != m2[1]) || (m1[2] != m2[2]) || (m1[3] != m2[3]);
+ }
+
+} //namespace detail
+} //namespace glm
diff --git a/src/glm/core/type_size.hpp b/src/glm/core/type_size.hpp
new file mode 100644
index 0000000..a0b0815
--- /dev/null
+++ b/src/glm/core/type_size.hpp
@@ -0,0 +1,24 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2008-10-05
+// Updated : 2008-10-05
+// Licence : This source is under MIT License
+// File : glm/core/type_size.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_core_type_size
+#define glm_core_type_size
+
+#include <cstdlib>
+
+namespace glm{
+namespace detail
+{
+ //typedef std::size_t size_t;
+ typedef int sizeType;
+
+}//namespace detail
+}//namespace glm
+
+#endif//glm_core_type_size
diff --git a/src/glm/core/type_vec.hpp b/src/glm/core/type_vec.hpp
new file mode 100644
index 0000000..06569b0
--- /dev/null
+++ b/src/glm/core/type_vec.hpp
@@ -0,0 +1,22 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2010-01-26
+// Updated : 2010-02-04
+// Licence : This source is under MIT License
+// File : glm/core/type_vec.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_core_type_vec
+#define glm_core_type_vec
+
+#include "type_gentype.hpp"
+
+namespace glm{
+namespace detail
+{
+
+}//namespace detail
+}//namespace glm
+
+#endif//glm_core_type_vec
diff --git a/src/glm/core/type_vec.inl b/src/glm/core/type_vec.inl
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/glm/core/type_vec.inl
diff --git a/src/glm/core/type_vec1.hpp b/src/glm/core/type_vec1.hpp
new file mode 100644
index 0000000..3059196
--- /dev/null
+++ b/src/glm/core/type_vec1.hpp
@@ -0,0 +1,172 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2008-08-25
+// Updated : 2010-02-04
+// Licence : This source is under MIT License
+// File : glm/core/type_vec1.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_core_type_gentype1
+#define glm_core_type_gentype1
+
+#include "type_vec.hpp"
+#include "type_float.hpp"
+#include "type_int.hpp"
+#include "type_size.hpp"
+#include "_swizzle.hpp"
+
+namespace glm{
+namespace detail
+{
+ template <typename T> struct tref1;
+ template <typename T> struct tref2;
+ template <typename T> struct tref3;
+ template <typename T> struct tref4;
+ template <typename T> struct tvec1;
+ template <typename T> struct tvec2;
+ template <typename T> struct tvec3;
+ template <typename T> struct tvec4;
+
+ template <typename T>
+ struct tvec1
+ {
+ enum ctor{null};
+
+ typedef T value_type;
+ typedef std::size_t size_type;
+ GLM_FUNC_DECL size_type length() const;
+ static GLM_FUNC_DECL size_type value_size();
+
+ typedef tvec1<T> type;
+ typedef tvec1<bool> bool_type;
+
+ //////////////////////////////////////
+ // Data
+
+# if(GLM_COMPONENT == GLM_COMPONENT_ONLY_XYZW)
+ value_type x;
+# else//(GLM_COMPONENT == GLM_COMPONENT_GLSL_NAMES)
+ union {value_type x, r, s;};
+# endif//GLM_COMPONENT
+
+ //////////////////////////////////////
+ // Accesses
+
+ GLM_FUNC_DECL value_type & operator[](size_type i);
+ GLM_FUNC_DECL value_type const & operator[](size_type i) const;
+
+ //////////////////////////////////////
+ // Implicit basic constructors
+
+ GLM_FUNC_DECL tvec1();
+ GLM_FUNC_DECL tvec1(tvec1<T> const & v);
+
+ //////////////////////////////////////
+ // Explicit basic constructors
+
+ GLM_FUNC_DECL explicit tvec1(
+ ctor);
+ GLM_FUNC_DECL explicit tvec1(
+ value_type const & s);
+
+ //////////////////////////////////////
+ // Swizzle constructors
+
+ GLM_FUNC_DECL tvec1(tref1<T> const & r);
+
+ //////////////////////////////////////
+ // Convertion scalar constructors
+
+ //! Explicit converions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
+ template <typename U>
+ GLM_FUNC_DECL explicit tvec1(U const & s);
+
+ //////////////////////////////////////
+ // Convertion vector constructors
+
+ //! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
+ template <typename U>
+ GLM_FUNC_DECL explicit tvec1(tvec2<U> const & v);
+ //! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
+ template <typename U>
+ GLM_FUNC_DECL explicit tvec1(tvec3<U> const & v);
+ //! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
+ template <typename U>
+ GLM_FUNC_DECL explicit tvec1(tvec4<U> const & v);
+
+ //////////////////////////////////////
+ // Unary arithmetic operators
+
+ GLM_FUNC_DECL tvec1<T> & operator= (tvec1<T> const & v);
+
+ GLM_FUNC_DECL tvec1<T> & operator+=(value_type const & s);
+ GLM_FUNC_DECL tvec1<T> & operator+=(tvec1<T> const & v);
+ GLM_FUNC_DECL tvec1<T> & operator-=(value_type const & s);
+ GLM_FUNC_DECL tvec1<T> & operator-=(tvec1<T> const & v);
+ GLM_FUNC_DECL tvec1<T> & operator*=(value_type const & s);
+ GLM_FUNC_DECL tvec1<T> & operator*=(tvec1<T> const & v);
+ GLM_FUNC_DECL tvec1<T> & operator/=(value_type const & s);
+ GLM_FUNC_DECL tvec1<T> & operator/=(tvec1<T> const & v);
+ GLM_FUNC_DECL tvec1<T> & operator++();
+ GLM_FUNC_DECL tvec1<T> & operator--();
+
+ //////////////////////////////////////
+ // Unary bit operators
+
+ GLM_FUNC_DECL tvec1<T> & operator%=(value_type const & s);
+ GLM_FUNC_DECL tvec1<T> & operator%=(tvec1<T> const & v);
+ GLM_FUNC_DECL tvec1<T> & operator&=(value_type const & s);
+ GLM_FUNC_DECL tvec1<T> & operator&=(tvec1<T> const & v);
+ GLM_FUNC_DECL tvec1<T> & operator|=(value_type const & s);
+ GLM_FUNC_DECL tvec1<T> & operator|=(tvec1<T> const & v);
+ GLM_FUNC_DECL tvec1<T> & operator^=(value_type const & s);
+ GLM_FUNC_DECL tvec1<T> & operator^=(tvec1<T> const & v);
+ GLM_FUNC_DECL tvec1<T> & operator<<=(value_type const & s);
+ GLM_FUNC_DECL tvec1<T> & operator<<=(tvec1<T> const & v);
+ GLM_FUNC_DECL tvec1<T> & operator>>=(value_type const & s);
+ GLM_FUNC_DECL tvec1<T> & operator>>=(tvec1<T> const & v);
+
+ //////////////////////////////////////
+ // Swizzle operators
+
+ GLM_FUNC_DECL value_type swizzle(comp X) const;
+ GLM_FUNC_DECL tvec2<T> swizzle(comp X, comp Y) const;
+ GLM_FUNC_DECL tvec3<T> swizzle(comp X, comp Y, comp Z) const;
+ GLM_FUNC_DECL tvec4<T> swizzle(comp X, comp Y, comp Z, comp W) const;
+ GLM_FUNC_DECL tref1<T> swizzle(comp X);
+ };
+
+ template <typename T>
+ struct tref1
+ {
+ GLM_FUNC_DECL tref1(T & x);
+ GLM_FUNC_DECL tref1(tref1<T> const & r);
+ GLM_FUNC_DECL tref1(tvec1<T> const & v);
+
+ GLM_FUNC_DECL tref1<T> & operator= (tref1<T> const & r);
+ GLM_FUNC_DECL tref1<T> & operator= (tvec1<T> const & v);
+
+ T& x;
+ };
+
+ GLM_DETAIL_IS_VECTOR(tvec1);
+
+ typedef detail::tvec1<core::type::precision::highp_float> highp_vec1_t;
+ typedef detail::tvec1<core::type::precision::mediump_float> mediump_vec1_t;
+ typedef detail::tvec1<core::type::precision::lowp_float> lowp_vec1_t;
+ typedef detail::tvec1<core::type::precision::highp_int> highp_ivec1_t;
+ typedef detail::tvec1<core::type::precision::mediump_int> mediump_ivec1_t;
+ typedef detail::tvec1<core::type::precision::lowp_int> lowp_ivec1_t;
+ typedef detail::tvec1<core::type::precision::highp_uint> highp_uvec1_t;
+ typedef detail::tvec1<core::type::precision::mediump_uint> mediump_uvec1_t;
+ typedef detail::tvec1<core::type::precision::lowp_uint> lowp_uvec1_t;
+
+}//namespace detail
+}//namespace glm
+
+#ifndef GLM_EXTERNAL_TEMPLATE
+#include "type_vec1.inl"
+#endif//GLM_EXTERNAL_TEMPLATE
+
+#endif//glm_core_type_gentype1
diff --git a/src/glm/core/type_vec1.inl b/src/glm/core/type_vec1.inl
new file mode 100644
index 0000000..25d4f87
--- /dev/null
+++ b/src/glm/core/type_vec1.inl
@@ -0,0 +1,884 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2008-08-25
+// Updated : 2010-02-04
+// Licence : This source is under MIT License
+// File : glm/core/type_vec1.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm{
+namespace detail
+{
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename tvec1<T>::size_type tvec1<T>::length() const
+ {
+ return 1;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename tvec1<T>::size_type tvec1<T>::value_size()
+ {
+ return 1;
+ }
+
+ //////////////////////////////////////
+ // Accesses
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename tvec1<T>::value_type & tvec1<T>::operator[]
+ (
+ size_type i
+ )
+ {
+ assert(i < value_size());
+ return (&x)[i];
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename tvec1<T>::value_type const & tvec1<T>::operator[]
+ (
+ size_type i
+ ) const
+ {
+ assert(i < value_size());
+ return (&x)[i];
+ }
+
+ //////////////////////////////////////
+ // Implicit basic constructors
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec1<T>::tvec1() :
+ x(value_type(0))
+ {}
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec1<T>::tvec1
+ (
+ ctor
+ )
+ {}
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec1<T>::tvec1
+ (
+ tvec1<T> const & v
+ ) :
+ x(v.x)
+ {}
+
+ //////////////////////////////////////
+ // Explicit basic constructors
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec1<T>::tvec1
+ (
+ value_type const & s
+ ) :
+ x(s)
+ {}
+
+ //////////////////////////////////////
+ // Swizzle constructors
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec1<T>::tvec1
+ (
+ tref1<T> const & r
+ ) :
+ x(r.x)
+ {}
+
+ //////////////////////////////////////
+ // Convertion scalar constructors
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tvec1<T>::tvec1
+ (
+ U const & s
+ ) :
+ x(value_type(s))
+ {}
+
+ //////////////////////////////////////
+ // Convertion vector constructors
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tvec1<T>::tvec1
+ (
+ tvec2<U> const & v
+ ) :
+ x(value_type(v.x))
+ {}
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tvec1<T>::tvec1
+ (
+ tvec3<U> const & v
+ ) :
+ x(value_type(v.x))
+ {}
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tvec1<T>::tvec1
+ (
+ tvec4<U> const & v
+ ) :
+ x(value_type(v.x))
+ {}
+
+ //////////////////////////////////////
+ // Unary arithmetic operators
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec1<T> & tvec1<T>::operator=
+ (
+ tvec1<T> const & v
+ )
+ {
+ this->x = v.x;
+ return *this;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec1<T> & tvec1<T>::operator+=
+ (
+ value_type const & s
+ )
+ {
+ this->x += s;
+ return *this;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec1<T> & tvec1<T>::operator+=
+ (
+ tvec1<T> const & v
+ )
+ {
+ this->x += v.x;
+ return *this;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec1<T> & tvec1<T>::operator-=
+ (
+ value_type const & s
+ )
+ {
+ this->x -= s;
+ return *this;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec1<T> & tvec1<T>::operator-=
+ (
+ tvec1<T> const & v
+ )
+ {
+ this->x -= v.x;
+ return *this;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec1<T> & tvec1<T>::operator*=
+ (
+ value_type const & s
+ )
+ {
+ this->x *= s;
+ return *this;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec1<T> & tvec1<T>::operator*=
+ (
+ tvec1<T> const & v
+ )
+ {
+ this->x *= v.x;
+ return *this;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec1<T> & tvec1<T>::operator/=
+ (
+ value_type const & s
+ )
+ {
+ this->x /= s;
+ return *this;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec1<T> & tvec1<T>::operator/=
+ (
+ tvec1<T> const & v
+ )
+ {
+ this->x /= v.x;
+ return *this;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec1<T> & tvec1<T>::operator++()
+ {
+ ++this->x;
+ return *this;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec1<T> & tvec1<T>::operator--()
+ {
+ --this->x;
+ return *this;
+ }
+
+ //////////////////////////////////////
+ // Boolean operators
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER bool operator==
+ (
+ tvec1<T> const & v1,
+ tvec1<T> const & v2
+ )
+ {
+ return (v1.x == v2.x);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER bool operator!=
+ (
+ tvec1<T> const & v1,
+ tvec1<T> const & v2
+ )
+ {
+ return (v1.x != v2.x);
+ }
+
+ //////////////////////////////////////
+ // Unary bit operators
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec1<T> & tvec1<T>::operator%=
+ (
+ value_type const & s
+ )
+ {
+ this->x %= s;
+ return *this;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec1<T> & tvec1<T>::operator%=
+ (
+ tvec1<T> const & v
+ )
+ {
+ this->x %= v.x;
+ return *this;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec1<T> & tvec1<T>::operator&=
+ (
+ value_type const & s
+ )
+ {
+ this->x &= s;
+ return *this;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec1<T> & tvec1<T>::operator&=
+ (
+ tvec1<T> const & v
+ )
+ {
+ this->x &= v.x;
+ return *this;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec1<T> & tvec1<T>::operator|=
+ (
+ value_type const & s
+ )
+ {
+ this->x |= s;
+ return *this;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec1<T> & tvec1<T>::operator|=
+ (
+ tvec1<T> const & v
+ )
+ {
+ this->x |= v.x;
+ return *this;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec1<T> & tvec1<T>::operator^=
+ (
+ value_type const & s
+ )
+ {
+ this->x ^= s;
+ return *this;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec1<T> & tvec1<T>::operator^=
+ (
+ tvec1<T> const & v
+ )
+ {
+ this->x ^= v.x;
+ return *this;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec1<T> & tvec1<T>::operator<<=
+ (
+ value_type const & s
+ )
+ {
+ this->x <<= s;
+ return *this;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec1<T> & tvec1<T>::operator<<=
+ (
+ tvec1<T> const & v
+ )
+ {
+ this->x <<= v.x;
+ return *this;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec1<T> & tvec1<T>::operator>>=
+ (
+ value_type const & s
+ )
+ {
+ this->x >>= s;
+ return *this;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec1<T> & tvec1<T>::operator>>=
+ (
+ tvec1<T> const & v
+ )
+ {
+ this->x >>= v.x;
+ return *this;
+ }
+
+ //////////////////////////////////////
+ // Swizzle operators
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER T
+ tvec1<T>::swizzle(comp x) const
+ {
+ return (*this)[x];
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec2<T>
+ tvec1<T>::swizzle
+ (
+ comp x,
+ comp y
+ ) const
+ {
+ return tvec2<T>(
+ (*this)[x],
+ (*this)[y]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec3<T>
+ tvec1<T>::swizzle
+ (
+ comp x,
+ comp y,
+ comp z
+ ) const
+ {
+ return tvec3<T>(
+ (*this)[x],
+ (*this)[y],
+ (*this)[z]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec4<T>
+ tvec1<T>::swizzle
+ (
+ comp x,
+ comp y,
+ comp z,
+ comp w
+ ) const
+ {
+ return tvec4<T>(
+ (*this)[x],
+ (*this)[y],
+ (*this)[z],
+ (*this)[w]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tref1<T>
+ tvec1<T>::swizzle
+ (
+ comp x
+ )
+ {
+ return tref1<T>(
+ (*this)[x]);
+ }
+
+ //////////////////////////////////////
+ // Binary arithmetic operators
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec1<T> operator+
+ (
+ tvec1<T> const & v,
+ typename tvec1<T>::value_type const & s
+ )
+ {
+ return tvec1<T>(
+ v.x + s);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec1<T> operator+
+ (
+ typename tvec1<T>::value_type const & s,
+ tvec1<T> const & v
+ )
+ {
+ return tvec1<T>(
+ s + v.x);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec1<T> operator+
+ (
+ tvec1<T> const & v1,
+ tvec1<T> const & v2
+ )
+ {
+ return tvec1<T>(
+ v1.x + v2.x);
+ }
+
+ //operator-
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec1<T> operator-
+ (
+ tvec1<T> const & v,
+ typename tvec1<T>::value_type const & s
+ )
+ {
+ return tvec1<T>(
+ v.x - s);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec1<T> operator-
+ (
+ typename tvec1<T>::value_type const & s,
+ tvec1<T> const & v
+ )
+ {
+ return tvec1<T>(
+ s - v.x);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec1<T> operator-
+ (
+ tvec1<T> const & v1,
+ tvec1<T> const & v2
+ )
+ {
+ return tvec1<T>(
+ v1.x - v2.x);
+ }
+
+ //operator*
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec1<T> operator*
+ (
+ tvec1<T> const & v,
+ typename tvec1<T>::value_type const & s
+ )
+ {
+ return tvec1<T>(
+ v.x * s);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec1<T> operator*
+ (
+ typename tvec1<T>::value_type const & s,
+ tvec1<T> const & v
+ )
+ {
+ return tvec1<T>(
+ s * v.x);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec1<T> operator*
+ (
+ tvec1<T> const & v1,
+ tvec1<T> const & v2
+ )
+ {
+ return tvec1<T>(
+ v1.x * v2.x);
+ }
+
+ //operator/
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec1<T> operator/
+ (
+ tvec1<T> const & v,
+ typename tvec1<T>::value_type const & s
+ )
+ {
+ return tvec1<T>(
+ v.x / s);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec1<T> operator/
+ (
+ typename tvec1<T>::value_type const & s,
+ tvec1<T> const & v
+ )
+ {
+ return tvec1<T>(
+ s / v.x);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec1<T> operator/
+ (
+ tvec1<T> const & v1,
+ tvec1<T> const & v2
+ )
+ {
+ return tvec1<T>(
+ v1.x / v2.x);
+ }
+
+ // Unary constant operators
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec1<T> operator-
+ (
+ tvec1<T> const & v
+ )
+ {
+ return tvec1<T>(
+ -v.x);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec1<T> operator++
+ (
+ tvec1<T> const & v,
+ int
+ )
+ {
+ return tvec1<T>(
+ v.x + T(1));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec1<T> operator--
+ (
+ tvec1<T> const & v,
+ int
+ )
+ {
+ return tvec1<T>(
+ v.x - T(1));
+ }
+
+ //////////////////////////////////////
+ // Binary bit operators
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec1<T> operator%
+ (
+ tvec1<T> const & v,
+ typename tvec1<T>::value_type const & s
+ )
+ {
+ return tvec1<T>(
+ v.x % s);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec1<T> operator%
+ (
+ typename tvec1<T>::value_type const & s,
+ tvec1<T> const & v
+ )
+ {
+ return tvec1<T>(
+ s % v.x);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec1<T> operator%
+ (
+ tvec1<T> const & v1,
+ tvec1<T> const & v2
+ )
+ {
+ return tvec1<T>(
+ v1.x % v2.x);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec1<T> operator&
+ (
+ tvec1<T> const & v,
+ typename tvec1<T>::value_type const & s
+ )
+ {
+ return tvec1<T>(
+ v.x & s);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec1<T> operator&
+ (
+ typename tvec1<T>::value_type const & s,
+ tvec1<T> const & v
+ )
+ {
+ return tvec1<T>(
+ s & v.x);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec1<T> operator&
+ (
+ tvec1<T> const & v1,
+ tvec1<T> const & v2
+ )
+ {
+ return tvec1<T>(
+ v1.x & v2.x);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec1<T> operator|
+ (
+ tvec1<T> const & v,
+ typename tvec1<T>::value_type const & s
+ )
+ {
+ return tvec1<T>(
+ v.x | s);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec1<T> operator|
+ (
+ typename tvec1<T>::value_type const & s,
+ tvec1<T> const & v
+ )
+ {
+ return tvec1<T>(
+ s | v.x);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec1<T> operator|
+ (
+ tvec1<T> const & v1,
+ tvec1<T> const & v2
+ )
+ {
+ return tvec1<T>(
+ v1.x | v2.x);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec1<T> operator^
+ (
+ tvec1<T> const & v,
+ typename tvec1<T>::value_type const & s
+ )
+ {
+ return tvec1<T>(
+ v.x ^ s);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec1<T> operator^
+ (
+ typename tvec1<T>::value_type const & s,
+ tvec1<T> const & v
+ )
+ {
+ return tvec1<T>(
+ s ^ v.x);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec1<T> operator^
+ (
+ tvec1<T> const & v1,
+ tvec1<T> const & v2
+ )
+ {
+ return tvec1<T>(
+ v1.x ^ v2.x);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec1<T> operator<<
+ (
+ tvec1<T> const & v,
+ typename tvec1<T>::value_type const & s
+ )
+ {
+ return tvec1<T>(
+ v.x << s);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec1<T> operator<<
+ (
+ typename tvec1<T>::value_type const & s,
+ tvec1<T> const & v
+ )
+ {
+ return tvec1<T>(
+ s << v.x);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec1<T> operator<<
+ (
+ tvec1<T> const & v1,
+ tvec1<T> const & v2
+ )
+ {
+ return tvec1<T>(
+ v1.x << v2.x);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec1<T> operator>>
+ (
+ tvec1<T> const & v,
+ typename tvec1<T>::value_type const & s
+ )
+ {
+ return tvec1<T>(
+ v.x >> s);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec1<T> operator>>
+ (
+ typename tvec1<T>::value_type const & s,
+ tvec1<T> const & v
+ )
+ {
+ return tvec1<T>(
+ s >> v.x);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec1<T> operator>>
+ (
+ tvec1<T> const & v1,
+ tvec1<T> const & v2
+ )
+ {
+ return tvec1<T>(
+ v1.x >> v2.x);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec1<T> operator~
+ (
+ tvec1<T> const & v
+ )
+ {
+ return tvec1<T>(
+ ~v.x);
+ }
+
+ //////////////////////////////////////
+ // tref definition
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tref1<T>::tref1
+ (
+ T & x
+ ) :
+ x(x)
+ {}
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tref1<T>::tref1
+ (
+ tref1<T> const & r
+ ) :
+ x(r.x)
+ {}
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tref1<T>::tref1
+ (
+ tvec1<T> const & v
+ ) :
+ x(v.x)
+ {}
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tref1<T> & tref1<T>::operator=
+ (
+ tref1<T> const & r
+ )
+ {
+ x = r.x;
+ return *this;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tref1<T> & tref1<T>::operator=
+ (
+ tvec1<T> const & v
+ )
+ {
+ x = v.x;
+ return *this;
+ }
+
+}//namespace detail
+}//namespace glm
diff --git a/src/glm/core/type_vec2.hpp b/src/glm/core/type_vec2.hpp
new file mode 100644
index 0000000..703e2f2
--- /dev/null
+++ b/src/glm/core/type_vec2.hpp
@@ -0,0 +1,263 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2008-08-18
+// Updated : 2010-02-04
+// Licence : This source is under MIT License
+// File : glm/core/type_tvec2.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_core_type_gentype2
+#define glm_core_type_gentype2
+
+#include "type_vec.hpp"
+#include "type_float.hpp"
+#include "type_int.hpp"
+#include "type_size.hpp"
+#include "_swizzle.hpp"
+
+namespace glm{
+namespace detail
+{
+ template <typename T> struct tref2;
+ template <typename T> struct tref3;
+ template <typename T> struct tref4;
+ template <typename T> struct tvec3;
+ template <typename T> struct tvec4;
+
+ //! The basic 2D vector type.
+ //! \ingroup core_template
+ template <typename T>
+ struct tvec2
+ {
+ enum ctor{null};
+
+ typedef T value_type;
+ typedef std::size_t size_type;
+ GLM_FUNC_DECL size_type length() const;
+ static GLM_FUNC_DECL size_type value_size();
+
+ typedef tvec2<T> type;
+ typedef tvec2<bool> bool_type;
+
+ //////////////////////////////////////
+ // Data
+
+# if(GLM_COMPONENT == GLM_COMPONENT_ONLY_XYZW)
+ value_type x, y;
+# elif(GLM_COMPONENT == GLM_COMPONENT_MS_EXT)
+ union
+ {
+ struct{value_type x, y;};
+ struct{value_type r, g;};
+ struct{value_type s, t;};
+ };
+# else//(GLM_COMPONENT == GLM_COMPONENT_GLSL_NAMES)
+ union {value_type x, r, s;};
+ union {value_type y, g, t;};
+# endif//GLM_COMPONENT
+
+ //////////////////////////////////////
+ // Accesses
+
+ GLM_FUNC_DECL value_type & operator[](size_type i);
+ GLM_FUNC_DECL value_type const & operator[](size_type i) const;
+
+ //////////////////////////////////////
+ // Implicit basic constructors
+
+ GLM_FUNC_DECL tvec2();
+ GLM_FUNC_DECL tvec2(tvec2<T> const & v);
+
+ //////////////////////////////////////
+ // Explicit basic constructors
+
+ GLM_FUNC_DECL explicit tvec2(
+ ctor);
+ GLM_FUNC_DECL explicit tvec2(
+ value_type const & s);
+ GLM_FUNC_DECL explicit tvec2(
+ value_type const & s1,
+ value_type const & s2);
+
+ //////////////////////////////////////
+ // Swizzle constructors
+
+ tvec2(tref2<T> const & r);
+
+ //////////////////////////////////////
+ // Convertion constructors
+
+ //! Explicit converions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
+// template <typename U>
+// GLM_FUNC_DECL explicit tvec2(
+// U const & x);
+ //! Explicit converions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
+ template <typename U, typename V>
+ GLM_FUNC_DECL explicit tvec2(
+ U const & x,
+ V const & y);
+
+ //////////////////////////////////////
+ // Convertion vector constructors
+
+ //! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
+ template <typename U>
+ GLM_FUNC_DECL explicit tvec2(tvec2<U> const & v);
+ //! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
+ template <typename U>
+ GLM_FUNC_DECL explicit tvec2(tvec3<U> const & v);
+ //! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
+ template <typename U>
+ GLM_FUNC_DECL explicit tvec2(tvec4<U> const & v);
+
+ //////////////////////////////////////
+ // Unary arithmetic operators
+
+ GLM_FUNC_DECL tvec2<T> & operator= (tvec2<T> const & v);
+ template <typename U>
+ GLM_FUNC_DECL tvec2<T> & operator= (tvec2<U> const & v);
+
+ template <typename U>
+ GLM_FUNC_DECL tvec2<T> & operator+=(U const & s);
+ template <typename U>
+ GLM_FUNC_DECL tvec2<T> & operator+=(tvec2<U> const & v);
+ template <typename U>
+ GLM_FUNC_DECL tvec2<T> & operator-=(U const & s);
+ template <typename U>
+ GLM_FUNC_DECL tvec2<T> & operator-=(tvec2<U> const & v);
+ template <typename U>
+ GLM_FUNC_DECL tvec2<T> & operator*=(U const & s);
+ template <typename U>
+ GLM_FUNC_DECL tvec2<T> & operator*=(tvec2<U> const & v);
+ template <typename U>
+ GLM_FUNC_DECL tvec2<T> & operator/=(U const & s);
+ template <typename U>
+ GLM_FUNC_DECL tvec2<T> & operator/=(tvec2<U> const & v);
+ GLM_FUNC_DECL tvec2<T> & operator++();
+ GLM_FUNC_DECL tvec2<T> & operator--();
+
+ //////////////////////////////////////
+ // Unary bit operators
+
+ template <typename U>
+ GLM_FUNC_DECL tvec2<T> & operator%= (U const & s);
+ template <typename U>
+ GLM_FUNC_DECL tvec2<T> & operator%= (tvec2<U> const & v);
+ template <typename U>
+ GLM_FUNC_DECL tvec2<T> & operator&= (U const & s);
+ template <typename U>
+ GLM_FUNC_DECL tvec2<T> & operator&= (tvec2<U> const & v);
+ template <typename U>
+ GLM_FUNC_DECL tvec2<T> & operator|= (U const & s);
+ template <typename U>
+ GLM_FUNC_DECL tvec2<T> & operator|= (tvec2<U> const & v);
+ template <typename U>
+ GLM_FUNC_DECL tvec2<T> & operator^= (U const & s);
+ template <typename U>
+ GLM_FUNC_DECL tvec2<T> & operator^= (tvec2<U> const & v);
+ template <typename U>
+ GLM_FUNC_DECL tvec2<T> & operator<<=(U const & s);
+ template <typename U>
+ GLM_FUNC_DECL tvec2<T> & operator<<=(tvec2<U> const & v);
+ template <typename U>
+ GLM_FUNC_DECL tvec2<T> & operator>>=(U const & s);
+ template <typename U>
+ GLM_FUNC_DECL tvec2<T> & operator>>=(tvec2<U> const & v);
+
+ //////////////////////////////////////
+ // Swizzle operators
+
+ GLM_FUNC_DECL value_type swizzle(comp X) const;
+ GLM_FUNC_DECL tvec2<T> swizzle(comp X, comp Y) const;
+ GLM_FUNC_DECL tvec3<T> swizzle(comp X, comp Y, comp Z) const;
+ GLM_FUNC_DECL tvec4<T> swizzle(comp X, comp Y, comp Z, comp W) const;
+ GLM_FUNC_DECL tref2<T> swizzle(comp X, comp Y);
+ };
+
+ template <typename T>
+ struct tref2
+ {
+ GLM_FUNC_DECL tref2(T & x, T & y);
+ GLM_FUNC_DECL tref2(tref2<T> const & r);
+ GLM_FUNC_DECL tref2(tvec2<T> const & v);
+
+ GLM_FUNC_DECL tref2<T> & operator= (tref2<T> const & r);
+ GLM_FUNC_DECL tref2<T> & operator= (tvec2<T> const & v);
+
+ T& x;
+ T& y;
+ };
+
+ GLM_DETAIL_IS_VECTOR(tvec2);
+
+} //namespace detail
+
+namespace core{
+namespace type{
+namespace precision
+{
+ //! 2 components vector of high precision floating-point numbers.
+ //! There is no guarantee on the actual precision.
+ //! From GLSL 1.30.8 specification, section 4.5.2 Precision Qualifiers.
+ //! \ingroup core_precision
+ typedef detail::tvec2<highp_float> highp_vec2;
+
+ //! 2 components vector of medium precision floating-point numbers.
+ //! There is no guarantee on the actual precision.
+ //! From GLSL 1.30.8 specification, section 4.5.2 Precision Qualifiers.
+ //! \ingroup core_precision
+ typedef detail::tvec2<mediump_float> mediump_vec2;
+
+ //! 2 components vector of low precision floating-point numbers.
+ //! There is no guarantee on the actual precision.
+ //! From GLSL 1.30.8 specification, section 4.5.2 Precision Qualifiers.
+ //! \ingroup core_precision
+ typedef detail::tvec2<lowp_float> lowp_vec2;
+
+ //! 2 components vector of high precision signed integer numbers.
+ //! There is no guarantee on the actual precision.
+ //! From GLSL 1.30.8 specification, section 4.1.5 Precision Qualifiers.
+ //! \ingroup core_precision
+ typedef detail::tvec2<highp_int> highp_ivec2;
+
+ //! 2 components vector of medium precision signed integer numbers.
+ //! There is no guarantee on the actual precision.
+ //! From GLSL 1.30.8 specification, section 4.1.5 Precision Qualifiers.
+ //! \ingroup core_precision
+ typedef detail::tvec2<mediump_int> mediump_ivec2;
+
+ //! 2 components vector of low precision signed integer numbers.
+ //! There is no guarantee on the actual precision.
+ //! From GLSL 1.30.8 specification, section 4.1.5 Precision Qualifiers.
+ //! \ingroup core_precision
+ typedef detail::tvec2<lowp_int> lowp_ivec2;
+
+ //! 2 components vector of high precision unsigned integer numbers.
+ //! There is no guarantee on the actual precision.
+ //! From GLSL 1.30.8 specification, section 4.1.5 Precision Qualifiers.
+ //! \ingroup core_precision
+ typedef detail::tvec2<highp_uint> highp_uvec2;
+
+ //! 2 components vector of medium precision unsigned integer numbers.
+ //! There is no guarantee on the actual precision.
+ //! From GLSL 1.30.8 specification, section 4.1.5 Precision Qualifiers.
+ //! \ingroup core_precision
+ typedef detail::tvec2<mediump_uint> mediump_uvec2;
+
+ //! 2 components vector of low precision unsigned integer numbers.
+ //! There is no guarantee on the actual precision.
+ //! From GLSL 1.30.8 specification, section 4.1.5 Precision Qualifiers.
+ //! \ingroup core_precision
+ typedef detail::tvec2<lowp_uint> lowp_uvec2;
+
+}//namespace precision
+}//namespace type
+}//namespace core
+}//namespace glm
+
+#ifndef GLM_EXTERNAL_TEMPLATE
+#include "type_vec2.inl"
+#endif//GLM_EXTERNAL_TEMPLATE
+
+#endif//glm_core_type_gentype2
diff --git a/src/glm/core/type_vec2.inl b/src/glm/core/type_vec2.inl
new file mode 100644
index 0000000..5d4594b
--- /dev/null
+++ b/src/glm/core/type_vec2.inl
@@ -0,0 +1,1010 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2008-08-18
+// Updated : 2010-10-26
+// Licence : This source is under MIT License
+// File : glm/core/type_tvec2.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm{
+namespace detail
+{
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename tvec2<T>::size_type tvec2<T>::length() const
+ {
+ return 2;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename tvec2<T>::size_type tvec2<T>::value_size()
+ {
+ return 2;
+ }
+
+ //////////////////////////////////////
+ // Accesses
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename tvec2<T>::value_type &
+ tvec2<T>::operator[]
+ (
+ size_type i
+ )
+ {
+ assert(i < value_size());
+ return (&x)[i];
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename tvec2<T>::value_type const &
+ tvec2<T>::operator[]
+ (
+ size_type i
+ ) const
+ {
+ assert(i < value_size());
+ return (&x)[i];
+ }
+
+ //////////////////////////////////////
+ // Implicit basic constructors
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec2<T>::tvec2() :
+ x(value_type(0)),
+ y(value_type(0))
+ {}
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec2<T>::tvec2
+ (
+ ctor
+ )
+ {}
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec2<T>::tvec2
+ (
+ tvec2<T> const & v
+ ) :
+ x(v.x),
+ y(v.y)
+ {}
+
+ //////////////////////////////////////
+ // Explicit basic constructors
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec2<T>::tvec2
+ (
+ value_type const & s
+ ) :
+ x(s),
+ y(s)
+ {}
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec2<T>::tvec2
+ (
+ value_type const & s1,
+ value_type const & s2
+ ) :
+ x(s1),
+ y(s2)
+ {}
+
+ //////////////////////////////////////
+ // Swizzle constructors
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec2<T>::tvec2
+ (
+ tref2<T> const & r
+ ) :
+ x(r.x),
+ y(r.y)
+ {}
+
+ //////////////////////////////////////
+ // Convertion scalar constructors
+/*
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tvec2<T>::tvec2
+ (
+ U const & x
+ ) :
+ x(value_type(x)),
+ y(value_type(x))
+ {}
+*/
+ template <typename T>
+ template <typename U, typename V>
+ GLM_FUNC_QUALIFIER tvec2<T>::tvec2
+ (
+ U const & x,
+ V const & y
+ ) :
+ x(value_type(x)),
+ y(value_type(y))
+ {}
+
+ //////////////////////////////////////
+ // Convertion vector constructors
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tvec2<T>::tvec2
+ (
+ tvec2<U> const & v
+ ) :
+ x(value_type(v.x)),
+ y(value_type(v.y))
+ {}
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tvec2<T>::tvec2
+ (
+ tvec3<U> const & v
+ ) :
+ x(value_type(v.x)),
+ y(value_type(v.y))
+ {}
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tvec2<T>::tvec2
+ (
+ tvec4<U> const & v
+ ) :
+ x(value_type(v.x)),
+ y(value_type(v.y))
+ {}
+
+ //////////////////////////////////////
+ // Unary arithmetic operators
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec2<T> & tvec2<T>::operator=
+ (
+ tvec2<T> const & v
+ )
+ {
+ this->x = v.x;
+ this->y = v.y;
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tvec2<T> & tvec2<T>::operator=
+ (
+ tvec2<U> const & v
+ )
+ {
+ this->x = T(v.x);
+ this->y = T(v.y);
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tvec2<T> & tvec2<T>::operator+=
+ (
+ U const & s
+ )
+ {
+ this->x += T(s);
+ this->y += T(s);
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tvec2<T> & tvec2<T>::operator+=
+ (
+ tvec2<U> const & v
+ )
+ {
+ this->x += T(v.x);
+ this->y += T(v.y);
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tvec2<T> & tvec2<T>::operator-=
+ (
+ U const & s
+ )
+ {
+ this->x -= T(s);
+ this->y -= T(s);
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tvec2<T> & tvec2<T>::operator-=
+ (
+ tvec2<U> const & v
+ )
+ {
+ this->x -= T(v.x);
+ this->y -= T(v.y);
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tvec2<T> & tvec2<T>::operator*=
+ (
+ U const & s
+ )
+ {
+ this->x *= T(s);
+ this->y *= T(s);
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tvec2<T> & tvec2<T>::operator*=
+ (
+ tvec2<U> const & v
+ )
+ {
+ this->x *= T(v.x);
+ this->y *= T(v.y);
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tvec2<T> & tvec2<T>::operator/=
+ (
+ U const & s
+ )
+ {
+ this->x /= T(s);
+ this->y /= T(s);
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tvec2<T> & tvec2<T>::operator/=
+ (
+ tvec2<U> const & v
+ )
+ {
+ this->x /= T(v.x);
+ this->y /= T(v.y);
+ return *this;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec2<T> & tvec2<T>::operator++()
+ {
+ ++this->x;
+ ++this->y;
+ return *this;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec2<T> & tvec2<T>::operator--()
+ {
+ --this->x;
+ --this->y;
+ return *this;
+ }
+
+ //////////////////////////////////////
+ // Boolean operators
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER bool operator==
+ (
+ tvec2<T> const & v1,
+ tvec2<T> const & v2
+ )
+ {
+ return (v1.x == v2.x) && (v1.y == v2.y);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER bool operator!=
+ (
+ tvec2<T> const & v1,
+ tvec2<T> const & v2
+ )
+ {
+ return (v1.x != v2.x) || (v1.y != v2.y);
+ }
+
+ //////////////////////////////////////
+ // Unary bit operators
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tvec2<T> & tvec2<T>::operator%=
+ (
+ U const & s
+ )
+ {
+ this->x %= T(s);
+ this->y %= T(s);
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tvec2<T> & tvec2<T>::operator%=
+ (
+ tvec2<U> const & v
+ )
+ {
+ this->x %= T(v.x);
+ this->y %= T(v.y);
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tvec2<T> & tvec2<T>::operator&=
+ (
+ U const & s
+ )
+ {
+ this->x &= T(s);
+ this->y &= T(s);
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tvec2<T> & tvec2<T>::operator&=
+ (
+ tvec2<U> const & v
+ )
+ {
+ this->x &= T(v.x);
+ this->y &= T(v.y);
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tvec2<T> & tvec2<T>::operator|=
+ (
+ U const & s
+ )
+ {
+ this->x |= T(s);
+ this->y |= T(s);
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tvec2<T> & tvec2<T>::operator|=
+ (
+ tvec2<U> const & v
+ )
+ {
+ this->x |= T(v.x);
+ this->y |= T(v.y);
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tvec2<T> & tvec2<T>::operator^=
+ (
+ U const & s
+ )
+ {
+ this->x ^= T(s);
+ this->y ^= T(s);
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tvec2<T> & tvec2<T>::operator^=
+ (
+ tvec2<U> const & v
+ )
+ {
+ this->x ^= T(v.x);
+ this->y ^= T(v.y);
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tvec2<T> & tvec2<T>::operator<<=
+ (
+ U const & s
+ )
+ {
+ this->x <<= T(s);
+ this->y <<= T(s);
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tvec2<T> & tvec2<T>::operator<<=
+ (
+ tvec2<U> const & v
+ )
+ {
+ this->x <<= T(v.x);
+ this->y <<= T(v.y);
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tvec2<T> & tvec2<T>::operator>>=
+ (
+ U const & s
+ )
+ {
+ this->x >>= T(s);
+ this->y >>= T(s);
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tvec2<T> & tvec2<T>::operator>>=
+ (
+ tvec2<U> const & v
+ )
+ {
+ this->x >>= T(v.x);
+ this->y >>= T(v.y);
+ return *this;
+ }
+
+ //////////////////////////////////////
+ // Swizzle operators
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename tvec2<T>::value_type tvec2<T>::swizzle
+ (
+ comp x
+ ) const
+ {
+ return (*this)[x];
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec2<T> tvec2<T>::swizzle
+ (
+ comp x,
+ comp y
+ ) const
+ {
+ return tvec2<T>(
+ (*this)[x],
+ (*this)[y]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec3<T> tvec2<T>::swizzle
+ (
+ comp x,
+ comp y,
+ comp z
+ ) const
+ {
+ return tvec3<T>(
+ (*this)[x],
+ (*this)[y],
+ (*this)[z]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec4<T> tvec2<T>::swizzle
+ (
+ comp x,
+ comp y,
+ comp z,
+ comp w
+ ) const
+ {
+ return tvec4<T>(
+ (*this)[x],
+ (*this)[y],
+ (*this)[z],
+ (*this)[w]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tref2<T> tvec2<T>::swizzle
+ (
+ comp x,
+ comp y
+ )
+ {
+ return tref2<T>(
+ (*this)[x],
+ (*this)[y]);
+ }
+
+ //////////////////////////////////////
+ // Binary arithmetic operators
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec2<T> operator+
+ (
+ tvec2<T> const & v,
+ T const & s
+ )
+ {
+ return tvec2<T>(
+ v.x + T(s),
+ v.y + T(s));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec2<T> operator+
+ (
+ T const & s,
+ tvec2<T> const & v
+ )
+ {
+ return tvec2<T>(
+ T(s) + v.x,
+ T(s) + v.y);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec2<T> operator+
+ (
+ tvec2<T> const & v1,
+ tvec2<T> const & v2
+ )
+ {
+ return tvec2<T>(
+ v1.x + T(v2.x),
+ v1.y + T(v2.y));
+ }
+
+ //operator-
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec2<T> operator-
+ (
+ tvec2<T> const & v,
+ T const & s
+ )
+ {
+ return tvec2<T>(
+ v.x - T(s),
+ v.y - T(s));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec2<T> operator-
+ (
+ T const & s,
+ tvec2<T> const & v
+ )
+ {
+ return tvec2<T>(
+ T(s) - v.x,
+ T(s) - v.y);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec2<T> operator-
+ (
+ tvec2<T> const & v1,
+ tvec2<T> const & v2
+ )
+ {
+ return tvec2<T>(
+ v1.x - T(v2.x),
+ v1.y - T(v2.y));
+ }
+
+ //operator*
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec2<T> operator*
+ (
+ tvec2<T> const & v,
+ T const & s
+ )
+ {
+ return tvec2<T>(
+ v.x * T(s),
+ v.y * T(s));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec2<T> operator*
+ (
+ T const & s,
+ tvec2<T> const & v
+ )
+ {
+ return tvec2<T>(
+ T(s) * v.x,
+ T(s) * v.y);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec2<T> operator*
+ (
+ tvec2<T> const & v1,
+ tvec2<T> const & v2
+ )
+ {
+ return tvec2<T>(
+ v1.x * T(v2.x),
+ v1.y * T(v2.y));
+ }
+
+ //operator/
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec2<T> operator/
+ (
+ tvec2<T> const & v,
+ T const & s
+ )
+ {
+ return tvec2<T>(
+ v.x / T(s),
+ v.y / T(s));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec2<T> operator/
+ (
+ T const & s,
+ tvec2<T> const & v
+ )
+ {
+ return tvec2<T>(
+ T(s) / v.x,
+ T(s) / v.y);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec2<T> operator/
+ (
+ tvec2<T> const & v1,
+ tvec2<T> const & v2
+ )
+ {
+ return tvec2<T>(
+ v1.x / T(v2.x),
+ v1.y / T(v2.y));
+ }
+
+ // Unary constant operators
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec2<T> operator-
+ (
+ tvec2<T> const & v
+ )
+ {
+ return tvec2<T>(
+ -v.x,
+ -v.y);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec2<T> operator++
+ (
+ tvec2<T> const & v,
+ int
+ )
+ {
+ return tvec2<T>(
+ v.x + T(1),
+ v.y + T(1));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec2<T> operator--
+ (
+ tvec2<T> const & v,
+ int
+ )
+ {
+ return tvec2<T>(
+ v.x - T(1),
+ v.y - T(1));
+ }
+
+ //////////////////////////////////////
+ // Binary bit operators
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec2<T> operator%
+ (
+ tvec2<T> const & v,
+ T const & s
+ )
+ {
+ return tvec2<T>(
+ v.x % T(s),
+ v.y % T(s));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec2<T> operator%
+ (
+ T const & s,
+ tvec2<T> const & v
+ )
+ {
+ return tvec2<T>(
+ T(s) % v.x,
+ T(s) % v.y);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec2<T> operator%
+ (
+ tvec2<T> const & v1,
+ tvec2<T> const & v2
+ )
+ {
+ return tvec2<T>(
+ v1.x % T(v2.x),
+ v1.y % T(v2.y));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec2<T> operator&
+ (
+ tvec2<T> const & v,
+ T const & s
+ )
+ {
+ return tvec2<T>(
+ v.x & T(s),
+ v.y & T(s));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec2<T> operator&
+ (
+ T const & s,
+ tvec2<T> const & v
+ )
+ {
+ return tvec2<T>(
+ T(s) & v.x,
+ T(s) & v.y);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec2<T> operator&
+ (
+ tvec2<T> const & v1,
+ tvec2<T> const & v2
+ )
+ {
+ return tvec2<T>(
+ v1.x & T(v2.x),
+ v1.y & T(v2.y));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec2<T> operator|
+ (
+ tvec2<T> const & v,
+ T const & s
+ )
+ {
+ return tvec2<T>(
+ v.x | T(s),
+ v.y | T(s));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec2<T> operator|
+ (
+ T const & s,
+ tvec2<T> const & v
+ )
+ {
+ return tvec2<T>(
+ T(s) | v.x,
+ T(s) | v.y);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec2<T> operator|
+ (
+ tvec2<T> const & v1,
+ tvec2<T> const & v2
+ )
+ {
+ return tvec2<T>(
+ v1.x | T(v2.x),
+ v1.y | T(v2.y));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec2<T> operator^
+ (
+ tvec2<T> const & v,
+ T const & s
+ )
+ {
+ return tvec2<T>(
+ v.x ^ T(s),
+ v.y ^ T(s));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec2<T> operator^
+ (
+ T const & s,
+ tvec2<T> const & v
+ )
+ {
+ return tvec2<T>(
+ T(s) ^ v.x,
+ T(s) ^ v.y);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec2<T> operator^
+ (
+ tvec2<T> const & v1,
+ tvec2<T> const & v2
+ )
+ {
+ return tvec2<T>(
+ v1.x ^ T(v2.x),
+ v1.y ^ T(v2.y));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec2<T> operator<<
+ (
+ tvec2<T> const & v,
+ T const & s
+ )
+ {
+ return tvec2<T>(
+ v.x << T(s),
+ v.y << T(s));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec2<T> operator<<
+ (
+ T const & s,
+ tvec2<T> const & v
+ )
+ {
+ return tvec2<T>(
+ s << T(v.x),
+ s << T(v.y));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec2<T> operator<<
+ (
+ tvec2<T> const & v1,
+ tvec2<T> const & v2
+ )
+ {
+ return tvec2<T>(
+ v1.x << T(v2.x),
+ v1.y << T(v2.y));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec2<T> operator>>
+ (
+ tvec2<T> const & v,
+ T const & s
+ )
+ {
+ return tvec2<T>(
+ v.x >> T(s),
+ v.y >> T(s));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec2<T> operator>>
+ (
+ T const & s,
+ tvec2<T> const & v
+ )
+ {
+ return tvec2<T>(
+ T(s) >> v.x,
+ T(s) >> v.y);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec2<T> operator>>
+ (
+ tvec2<T> const & v1,
+ tvec2<T> const & v2
+ )
+ {
+ return tvec2<T>(
+ v1.x >> T(v2.x),
+ v1.y >> T(v2.y));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec2<T> operator~
+ (
+ tvec2<T> const & v
+ )
+ {
+ return tvec2<T>(
+ ~v.x,
+ ~v.y);
+ }
+
+ //////////////////////////////////////
+ // tref definition
+
+ template <typename T>
+ tref2<T>::tref2
+ (
+ T & x,
+ T & y
+ ) :
+ x(x),
+ y(y)
+ {}
+
+ template <typename T>
+ tref2<T>::tref2
+ (
+ tref2<T> const & r
+ ) :
+ x(r.x),
+ y(r.y)
+ {}
+
+ template <typename T>
+ tref2<T>::tref2
+ (
+ tvec2<T> const & v
+ ) :
+ x(v.x),
+ y(v.y)
+ {}
+
+ template <typename T>
+ tref2<T>& tref2<T>::operator=
+ (
+ tref2<T> const & r
+ )
+ {
+ x = r.x;
+ y = r.y;
+ return *this;
+ }
+
+ template <typename T>
+ tref2<T>& tref2<T>::operator=
+ (
+ tvec2<T> const & v
+ )
+ {
+ x = v.x;
+ y = v.y;
+ return *this;
+ }
+
+}//namespace detail
+}//namespace glm
diff --git a/src/glm/core/type_vec3.hpp b/src/glm/core/type_vec3.hpp
new file mode 100644
index 0000000..8864d7d
--- /dev/null
+++ b/src/glm/core/type_vec3.hpp
@@ -0,0 +1,269 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2008-08-22
+// Updated : 2010-02-03
+// Licence : This source is under MIT License
+// File : glm/core/type_tvec3.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_core_type_gentype3
+#define glm_core_type_gentype3
+
+#include "type_vec.hpp"
+#include "type_float.hpp"
+#include "type_int.hpp"
+#include "type_size.hpp"
+#include "_swizzle.hpp"
+
+namespace glm{
+namespace detail
+{
+ template <typename T> struct tref2;
+ template <typename T> struct tref3;
+ template <typename T> struct tref4;
+ template <typename T> struct tvec2;
+ template <typename T> struct tvec4;
+
+ //! Basic 3D vector type.
+ //! \ingroup core_template
+ template <typename T>
+ struct tvec3
+ {
+ enum ctor{null};
+
+ typedef T value_type;
+ typedef std::size_t size_type;
+ GLM_FUNC_DECL size_type length() const;
+ static GLM_FUNC_DECL size_type value_size();
+
+ typedef tvec3<T> type;
+ typedef tvec3<bool> bool_type;
+
+ //////////////////////////////////////
+ // Data
+
+# if(GLM_COMPONENT == GLM_COMPONENT_ONLY_XYZW)
+ value_type x, y, z;
+# elif(GLM_COMPONENT == GLM_COMPONENT_MS_EXT)
+ union
+ {
+ struct{value_type x, y, z;};
+ struct{value_type r, g, b;};
+ struct{value_type s, t, p;};
+ };
+# else//(GLM_COMPONENT == GLM_COMPONENT_GLSL_NAMES)
+ union {value_type x, r, s;};
+ union {value_type y, g, t;};
+ union {value_type z, b, p;};
+# endif//GLM_COMPONENT
+
+ //////////////////////////////////////
+ // Accesses
+
+ GLM_FUNC_DECL value_type & operator[](size_type i);
+ GLM_FUNC_DECL value_type const & operator[](size_type i) const;
+
+ //////////////////////////////////////
+ // Implicit basic constructors
+
+ GLM_FUNC_DECL tvec3();
+ GLM_FUNC_DECL tvec3(tvec3<T> const & v);
+
+ //////////////////////////////////////
+ // Explicit basic constructors
+
+ GLM_FUNC_DECL explicit tvec3(
+ ctor);
+ GLM_FUNC_DECL explicit tvec3(
+ value_type const & s);
+ GLM_FUNC_DECL explicit tvec3(
+ value_type const & s1,
+ value_type const & s2,
+ value_type const & s3);
+
+ //////////////////////////////////////
+ // Swizzle constructors
+
+ GLM_FUNC_DECL tvec3(tref3<T> const & r);
+
+ //////////////////////////////////////
+ // Convertion scalar constructors
+
+ //! Explicit converions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
+ template <typename U>
+ GLM_FUNC_DECL explicit tvec3(
+ U const & x);
+ //! Explicit converions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
+ template <typename U, typename V, typename W>
+ GLM_FUNC_DECL explicit tvec3(
+ U const & x,
+ V const & y,
+ W const & z);
+
+ //////////////////////////////////////
+ // Convertion vector constructors
+
+ //! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
+ template <typename A, typename B>
+ GLM_FUNC_DECL explicit tvec3(tvec2<A> const & v, B const & s);
+ //! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
+ template <typename A, typename B>
+ GLM_FUNC_DECL explicit tvec3(A const & s, tvec2<B> const & v);
+ //! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
+ template <typename U>
+ GLM_FUNC_DECL explicit tvec3(tvec3<U> const & v);
+ //! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
+ template <typename U>
+ GLM_FUNC_DECL explicit tvec3(tvec4<U> const & v);
+
+ //////////////////////////////////////
+ // Unary arithmetic operators
+
+ GLM_FUNC_DECL tvec3<T> & operator= (tvec3<T> const & v);
+ template <typename U>
+ GLM_FUNC_DECL tvec3<T> & operator= (tvec3<U> const & v);
+
+ template <typename U>
+ GLM_FUNC_DECL tvec3<T> & operator+=(U const & s);
+ template <typename U>
+ GLM_FUNC_DECL tvec3<T> & operator+=(tvec3<U> const & v);
+ template <typename U>
+ GLM_FUNC_DECL tvec3<T> & operator-=(U const & s);
+ template <typename U>
+ GLM_FUNC_DECL tvec3<T> & operator-=(tvec3<U> const & v);
+ template <typename U>
+ GLM_FUNC_DECL tvec3<T> & operator*=(U const & s);
+ template <typename U>
+ GLM_FUNC_DECL tvec3<T> & operator*=(tvec3<U> const & v);
+ template <typename U>
+ GLM_FUNC_DECL tvec3<T> & operator/=(U const & s);
+ template <typename U>
+ GLM_FUNC_DECL tvec3<T> & operator/=(tvec3<U> const & v);
+ GLM_FUNC_DECL tvec3<T> & operator++();
+ GLM_FUNC_DECL tvec3<T> & operator--();
+
+ //////////////////////////////////////
+ // Unary bit operators
+
+ template <typename U>
+ GLM_FUNC_DECL tvec3<T> & operator%= (U const & s);
+ template <typename U>
+ GLM_FUNC_DECL tvec3<T> & operator%= (tvec3<U> const & v);
+ template <typename U>
+ GLM_FUNC_DECL tvec3<T> & operator&= (U const & s);
+ template <typename U>
+ GLM_FUNC_DECL tvec3<T> & operator&= (tvec3<U> const & v);
+ template <typename U>
+ GLM_FUNC_DECL tvec3<T> & operator|= (U const & s);
+ template <typename U>
+ GLM_FUNC_DECL tvec3<T> & operator|= (tvec3<U> const & v);
+ template <typename U>
+ GLM_FUNC_DECL tvec3<T> & operator^= (U const & s);
+ template <typename U>
+ GLM_FUNC_DECL tvec3<T> & operator^= (tvec3<U> const & v);
+ template <typename U>
+ GLM_FUNC_DECL tvec3<T> & operator<<=(U const & s);
+ template <typename U>
+ GLM_FUNC_DECL tvec3<T> & operator<<=(tvec3<U> const & v);
+ template <typename U>
+ GLM_FUNC_DECL tvec3<T> & operator>>=(U const & s);
+ template <typename U>
+ GLM_FUNC_DECL tvec3<T> & operator>>=(tvec3<U> const & v);
+
+ //////////////////////////////////////
+ // Swizzle operators
+
+ GLM_FUNC_DECL value_type swizzle(comp X) const;
+ GLM_FUNC_DECL tvec2<T> swizzle(comp X, comp Y) const;
+ GLM_FUNC_DECL tvec3<T> swizzle(comp X, comp Y, comp Z) const;
+ GLM_FUNC_DECL tvec4<T> swizzle(comp X, comp Y, comp Z, comp W) const;
+ GLM_FUNC_DECL tref3<T> swizzle(comp X, comp Y, comp Z);
+ };
+
+ template <typename T>
+ struct tref3
+ {
+ GLM_FUNC_DECL tref3(T & x, T & y, T & z);
+ GLM_FUNC_DECL tref3(tref3<T> const & r);
+ GLM_FUNC_DECL tref3(tvec3<T> const & v);
+
+ GLM_FUNC_DECL tref3<T> & operator= (tref3<T> const & r);
+ GLM_FUNC_DECL tref3<T> & operator= (tvec3<T> const & v);
+
+ T & x;
+ T & y;
+ T & z;
+ };
+
+ GLM_DETAIL_IS_VECTOR(tvec3);
+} //namespace detail
+
+namespace core{
+namespace type{
+namespace precision
+{
+ //! 3 components vector of high precision floating-point numbers.
+ //! There is no guarantee on the actual precision.
+ //! From GLSL 1.30.8 specification, section 4.5.2 Precision Qualifiers.
+ //! \ingroup core_precision
+ typedef detail::tvec3<highp_float> highp_vec3;
+
+ //! 3 components vector of medium precision floating-point numbers.
+ //! There is no guarantee on the actual precision.
+ //! From GLSL 1.30.8 specification, section 4.5.2 Precision Qualifiers.
+ //! \ingroup core_precision
+ typedef detail::tvec3<mediump_float> mediump_vec3;
+
+ //! 3 components vector of low precision floating-point numbers.
+ //! There is no guarantee on the actual precision.
+ //! From GLSL 1.30.8 specification, section 4.5.2 Precision Qualifiers.
+ //! \ingroup core_precision
+ typedef detail::tvec3<lowp_float> lowp_vec3;
+
+ //! 3 components vector of high precision signed integer numbers.
+ //! There is no guarantee on the actual precision.
+ //! From GLSL 1.30.8 specification, section 4.1.5 Precision Qualifiers.
+ //! \ingroup core_precision
+ typedef detail::tvec3<highp_int> highp_ivec3;
+
+ //! 3 components vector of medium precision signed integer numbers.
+ //! There is no guarantee on the actual precision.
+ //! From GLSL 1.30.8 specification, section 4.1.5 Precision Qualifiers.
+ //! \ingroup core_precision
+ typedef detail::tvec3<mediump_int> mediump_ivec3;
+
+ //! 3 components vector of low precision signed integer numbers.
+ //! There is no guarantee on the actual precision.
+ //! From GLSL 1.30.8 specification, section 4.1.5 Precision Qualifiers.
+ //! \ingroup core_precision
+ typedef detail::tvec3<lowp_int> lowp_ivec3;
+
+ //! 3 components vector of high precision unsigned integer numbers.
+ //! There is no guarantee on the actual precision.
+ //! From GLSL 1.30.8 specification, section 4.1.5 Precision Qualifiers.
+ //! \ingroup core_precision
+ typedef detail::tvec3<highp_uint> highp_uvec3;
+
+ //! 3 components vector of medium precision unsigned integer numbers.
+ //! There is no guarantee on the actual precision.
+ //! From GLSL 1.30.8 specification, section 4.1.5 Precision Qualifiers.
+ //! \ingroup core_precision
+ typedef detail::tvec3<mediump_uint> mediump_uvec3;
+
+ //! 3 components vector of low precision unsigned integer numbers.
+ //! There is no guarantee on the actual precision.
+ //! From GLSL 1.30.8 specification, section 4.1.5 Precision Qualifiers.
+ //! \ingroup core_precision
+ typedef detail::tvec3<lowp_uint> lowp_uvec3;
+
+}//namespace precision
+}//namespace type
+}//namespace core
+}//namespace glm
+
+#ifndef GLM_EXTERNAL_TEMPLATE
+#include "type_vec3.inl"
+#endif//GLM_EXTERNAL_TEMPLATE
+
+#endif//glm_core_type_gentype3
diff --git a/src/glm/core/type_vec3.inl b/src/glm/core/type_vec3.inl
new file mode 100644
index 0000000..f7a3542
--- /dev/null
+++ b/src/glm/core/type_vec3.inl
@@ -0,0 +1,1097 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2008-08-22
+// Updated : 2010-02-04
+// Licence : This source is under MIT License
+// File : glm/core/type_tvec3.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm{
+namespace detail
+{
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename tvec3<T>::size_type tvec3<T>::length() const
+ {
+ return 3;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename tvec3<T>::size_type tvec3<T>::value_size()
+ {
+ return 3;
+ }
+
+ //////////////////////////////////////
+ // Accesses
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename tvec3<T>::value_type &
+ tvec3<T>::operator[]
+ (
+ size_type i
+ )
+ {
+ assert(i < value_size());
+ return (&x)[i];
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename tvec3<T>::value_type const &
+ tvec3<T>::operator[]
+ (
+ size_type i
+ ) const
+ {
+ assert(i < value_size());
+ return (&x)[i];
+ }
+
+ //////////////////////////////////////
+ // Implicit basic constructors
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec3<T>::tvec3() :
+ x(value_type(0)),
+ y(value_type(0)),
+ z(value_type(0))
+ {}
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec3<T>::tvec3
+ (
+ ctor
+ )
+ {}
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec3<T>::tvec3
+ (
+ tvec3<T> const & v
+ ) :
+ x(v.x),
+ y(v.y),
+ z(v.z)
+ {}
+
+ //////////////////////////////////////
+ // Explicit basic constructors
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec3<T>::tvec3
+ (
+ value_type const & s
+ ) :
+ x(s),
+ y(s),
+ z(s)
+ {}
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec3<T>::tvec3
+ (
+ value_type const & s0,
+ value_type const & s1,
+ value_type const & s2
+ ) :
+ x(s0),
+ y(s1),
+ z(s2)
+ {}
+
+ //////////////////////////////////////
+ // Swizzle constructors
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec3<T>::tvec3
+ (
+ tref3<T> const & r
+ ) :
+ x(r.x),
+ y(r.y),
+ z(r.z)
+ {}
+
+ //////////////////////////////////////
+ // Convertion scalar constructors
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tvec3<T>::tvec3
+ (
+ U const & s
+ ) :
+ x(value_type(s)),
+ y(value_type(s)),
+ z(value_type(s))
+ {}
+
+ template <typename T>
+ template <typename A, typename B, typename C>
+ GLM_FUNC_QUALIFIER tvec3<T>::tvec3
+ (
+ A const & x,
+ B const & y,
+ C const & z
+ ) :
+ x(value_type(x)),
+ y(value_type(y)),
+ z(value_type(z))
+ {}
+
+ //////////////////////////////////////
+ // Convertion vector constructors
+
+ template <typename T>
+ template <typename A, typename B>
+ GLM_FUNC_QUALIFIER tvec3<T>::tvec3
+ (
+ tvec2<A> const & v,
+ B const & s
+ ) :
+ x(value_type(v.x)),
+ y(value_type(v.y)),
+ z(value_type(s))
+ {}
+
+ template <typename T>
+ template <typename A, typename B>
+ GLM_FUNC_QUALIFIER tvec3<T>::tvec3
+ (
+ A const & s,
+ tvec2<B> const & v
+ ) :
+ x(value_type(s)),
+ y(value_type(v.x)),
+ z(value_type(v.y))
+ {}
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tvec3<T>::tvec3
+ (
+ tvec3<U> const & v
+ ) :
+ x(value_type(v.x)),
+ y(value_type(v.y)),
+ z(value_type(v.z))
+ {}
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tvec3<T>::tvec3
+ (
+ tvec4<U> const & v
+ ) :
+ x(value_type(v.x)),
+ y(value_type(v.y)),
+ z(value_type(v.z))
+ {}
+
+ //////////////////////////////////////
+ // Unary arithmetic operators
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec3<T>& tvec3<T>::operator=
+ (
+ tvec3<T> const & v
+ )
+ {
+ this->x = v.x;
+ this->y = v.y;
+ this->z = v.z;
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tvec3<T>& tvec3<T>::operator=
+ (
+ tvec3<U> const & v
+ )
+ {
+ this->x = T(v.x);
+ this->y = T(v.y);
+ this->z = T(v.z);
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tvec3<T> & tvec3<T>::operator+=
+ (
+ U const & s
+ )
+ {
+ this->x += T(s);
+ this->y += T(s);
+ this->z += T(s);
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tvec3<T> & tvec3<T>::operator+=
+ (
+ tvec3<U> const & v
+ )
+ {
+ this->x += T(v.x);
+ this->y += T(v.y);
+ this->z += T(v.z);
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tvec3<T> & tvec3<T>::operator-=
+ (
+ U const & s
+ )
+ {
+ this->x -= T(s);
+ this->y -= T(s);
+ this->z -= T(s);
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tvec3<T> & tvec3<T>::operator-=
+ (
+ tvec3<U> const & v
+ )
+ {
+ this->x -= T(v.x);
+ this->y -= T(v.y);
+ this->z -= T(v.z);
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tvec3<T> & tvec3<T>::operator*=
+ (
+ U const & s
+ )
+ {
+ this->x *= T(s);
+ this->y *= T(s);
+ this->z *= T(s);
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tvec3<T> & tvec3<T>::operator*=
+ (
+ tvec3<U> const & v
+ )
+ {
+ this->x *= T(v.x);
+ this->y *= T(v.y);
+ this->z *= T(v.z);
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tvec3<T> & tvec3<T>::operator/=
+ (
+ U const & s
+ )
+ {
+ this->x /= T(s);
+ this->y /= T(s);
+ this->z /= T(s);
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tvec3<T> & tvec3<T>::operator/=
+ (
+ tvec3<U> const & v
+ )
+ {
+ this->x /= T(v.x);
+ this->y /= T(v.y);
+ this->z /= T(v.z);
+ return *this;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec3<T> & tvec3<T>::operator++()
+ {
+ ++this->x;
+ ++this->y;
+ ++this->z;
+ return *this;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec3<T> & tvec3<T>::operator--()
+ {
+ --this->x;
+ --this->y;
+ --this->z;
+ return *this;
+ }
+
+ //////////////////////////////////////
+ // Boolean operators
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER bool operator==
+ (
+ tvec3<T> const & v1,
+ tvec3<T> const & v2
+ )
+ {
+ return (v1.x == v2.x) && (v1.y == v2.y) && (v1.z == v2.z);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER bool operator!=
+ (
+ tvec3<T> const & v1,
+ tvec3<T> const & v2
+ )
+ {
+ return (v1.x != v2.x) || (v1.y != v2.y) || (v1.z != v2.z);
+ }
+
+ //////////////////////////////////////
+ // Unary bit operators
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tvec3<T> & tvec3<T>::operator%=
+ (
+ U const & s
+ )
+ {
+ this->x %= s;
+ this->y %= s;
+ this->z %= s;
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tvec3<T> & tvec3<T>::operator%=
+ (
+ tvec3<U> const & v
+ )
+ {
+ this->x %= v.x;
+ this->y %= v.y;
+ this->z %= v.z;
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tvec3<T> & tvec3<T>::operator&=
+ (
+ U const & s
+ )
+ {
+ this->x &= s;
+ this->y &= s;
+ this->z &= s;
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tvec3<T> & tvec3<T>::operator&=
+ (
+ tvec3<U> const & v
+ )
+ {
+ this->x &= v.x;
+ this->y &= v.y;
+ this->z &= v.z;
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tvec3<T> & tvec3<T>::operator|=
+ (
+ U const & s
+ )
+ {
+ this->x |= s;
+ this->y |= s;
+ this->z |= s;
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tvec3<T> & tvec3<T>::operator|=
+ (
+ tvec3<U> const & v
+ )
+ {
+ this->x |= v.x;
+ this->y |= v.y;
+ this->z |= v.z;
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tvec3<T> & tvec3<T>::operator^=
+ (
+ U const & s
+ )
+ {
+ this->x ^= s;
+ this->y ^= s;
+ this->z ^= s;
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tvec3<T> & tvec3<T>::operator^=
+ (
+ tvec3<U> const & v
+ )
+ {
+ this->x ^= v.x;
+ this->y ^= v.y;
+ this->z ^= v.z;
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tvec3<T> & tvec3<T>::operator<<=
+ (
+ U const & s
+ )
+ {
+ this->x <<= s;
+ this->y <<= s;
+ this->z <<= s;
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tvec3<T> & tvec3<T>::operator<<=
+ (
+ tvec3<U> const & v
+ )
+ {
+ this->x <<= T(v.x);
+ this->y <<= T(v.y);
+ this->z <<= T(v.z);
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tvec3<T> & tvec3<T>::operator>>=
+ (
+ U const & s
+ )
+ {
+ this->x >>= T(s);
+ this->y >>= T(s);
+ this->z >>= T(s);
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tvec3<T> & tvec3<T>::operator>>=
+ (
+ tvec3<U> const & v
+ )
+ {
+ this->x >>= T(v.x);
+ this->y >>= T(v.y);
+ this->z >>= T(v.z);
+ return *this;
+ }
+
+ //////////////////////////////////////
+ // Swizzle operators
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename tvec3<T>::value_type
+ tvec3<T>::swizzle
+ (
+ comp x
+ ) const
+ {
+ return (*this)[x];
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec2<T> tvec3<T>::swizzle
+ (
+ comp x,
+ comp y
+ ) const
+ {
+ return tvec2<T>(
+ (*this)[x],
+ (*this)[y]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec3<T> tvec3<T>::swizzle
+ (
+ comp x,
+ comp y,
+ comp z
+ ) const
+ {
+ return tvec3<T>(
+ (*this)[x],
+ (*this)[y],
+ (*this)[z]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec4<T> tvec3<T>::swizzle
+ (
+ comp x,
+ comp y,
+ comp z,
+ comp w
+ ) const
+ {
+ return tvec4<T>(
+ (*this)[x],
+ (*this)[y],
+ (*this)[z],
+ (*this)[w]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tref3<T> tvec3<T>::swizzle
+ (
+ comp x,
+ comp y,
+ comp z
+ )
+ {
+ return tref3<T>(
+ (*this)[x],
+ (*this)[y],
+ (*this)[z]);
+ }
+
+ //////////////////////////////////////
+ // Binary arithmetic operators
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec3<T> operator+
+ (
+ tvec3<T> const & v,
+ T const & s
+ )
+ {
+ return tvec3<T>(
+ v.x + T(s),
+ v.y + T(s),
+ v.z + T(s));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec3<T> operator+
+ (
+ T const & s,
+ tvec3<T> const & v
+ )
+ {
+ return tvec3<T>(
+ T(s) + v.x,
+ T(s) + v.y,
+ T(s) + v.z);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec3<T> operator+
+ (
+ tvec3<T> const & v1,
+ tvec3<T> const & v2
+ )
+ {
+ return tvec3<T>(
+ v1.x + T(v2.x),
+ v1.y + T(v2.y),
+ v1.z + T(v2.z));
+ }
+
+ //operator-
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec3<T> operator-
+ (
+ tvec3<T> const & v,
+ T const & s
+ )
+ {
+ return tvec3<T>(
+ v.x - T(s),
+ v.y - T(s),
+ v.z - T(s));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec3<T> operator-
+ (
+ T const & s,
+ tvec3<T> const & v
+ )
+ {
+ return tvec3<T>(
+ T(s) - v.x,
+ T(s) - v.y,
+ T(s) - v.z);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec3<T> operator-
+ (
+ tvec3<T> const & v1,
+ tvec3<T> const & v2
+ )
+ {
+ return tvec3<T>(
+ v1.x - T(v2.x),
+ v1.y - T(v2.y),
+ v1.z - T(v2.z));
+ }
+
+ //operator*
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec3<T> operator*
+ (
+ tvec3<T> const & v,
+ T const & s
+ )
+ {
+ return tvec3<T>(
+ v.x * T(s),
+ v.y * T(s),
+ v.z * T(s));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec3<T> operator*
+ (
+ T const & s,
+ tvec3<T> const & v
+ )
+ {
+ return tvec3<T>(
+ T(s) * v.x,
+ T(s) * v.y,
+ T(s) * v.z);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec3<T> operator*
+ (
+ tvec3<T> const & v1,
+ tvec3<T> const & v2
+ )
+ {
+ return tvec3<T>(
+ v1.x * T(v2.x),
+ v1.y * T(v2.y),
+ v1.z * T(v2.z));
+ }
+
+ //operator/
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec3<T> operator/
+ (
+ tvec3<T> const & v,
+ T const & s
+ )
+ {
+ return tvec3<T>(
+ v.x / T(s),
+ v.y / T(s),
+ v.z / T(s));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec3<T> operator/
+ (
+ T const & s,
+ tvec3<T> const & v
+ )
+ {
+ return tvec3<T>(
+ T(s) / v.x,
+ T(s) / v.y,
+ T(s) / v.z);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec3<T> operator/
+ (
+ tvec3<T> const & v1,
+ tvec3<T> const & v2
+ )
+ {
+ return tvec3<T>(
+ v1.x / T(v2.x),
+ v1.y / T(v2.y),
+ v1.z / T(v2.z));
+ }
+
+ // Unary constant operators
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec3<T> operator-
+ (
+ tvec3<T> const & v
+ )
+ {
+ return tvec3<T>(
+ -v.x,
+ -v.y,
+ -v.z);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec3<T> operator++
+ (
+ tvec3<T> const & v,
+ int
+ )
+ {
+ return tvec3<T>(
+ v.x + T(1),
+ v.y + T(1),
+ v.z + T(1));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec3<T> operator--
+ (
+ tvec3<T> const & v,
+ int
+ )
+ {
+ return tvec3<T>(
+ v.x - T(1),
+ v.y - T(1),
+ v.z - T(1));
+ }
+
+ //////////////////////////////////////
+ // Binary bit operators
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec3<T> operator%
+ (
+ tvec3<T> const & v,
+ T const & s
+ )
+ {
+ return tvec3<T>(
+ v.x % T(s),
+ v.y % T(s),
+ v.z % T(s));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec3<T> operator%
+ (
+ T const & s,
+ tvec3<T> const & v
+ )
+ {
+ return tvec3<T>(
+ T(s) % v.x,
+ T(s) % v.y,
+ T(s) % v.z);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec3<T> operator%
+ (
+ tvec3<T> const & v1,
+ tvec3<T> const & v2
+ )
+ {
+ return tvec3<T>(
+ v1.x % T(v2.x),
+ v1.y % T(v2.y),
+ v1.z % T(v2.z));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec3<T> operator&
+ (
+ tvec3<T> const & v,
+ T const & s
+ )
+ {
+ return tvec3<T>(
+ v.x & T(s),
+ v.y & T(s),
+ v.z & T(s));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec3<T> operator&
+ (
+ T const & s,
+ tvec3<T> const & v
+ )
+ {
+ return tvec3<T>(
+ T(s) & v.x,
+ T(s) & v.y,
+ T(s) & v.z);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec3<T> operator&
+ (
+ tvec3<T> const & v1,
+ tvec3<T> const & v2
+ )
+ {
+ return tvec3<T>(
+ v1.x & T(v2.x),
+ v1.y & T(v2.y),
+ v1.z & T(v2.z));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec3<T> operator|
+ (
+ tvec3<T> const & v,
+ T const & s
+ )
+ {
+ return tvec3<T>(
+ v.x | T(s),
+ v.y | T(s),
+ v.z | T(s));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec3<T> operator|
+ (
+ T const & s,
+ tvec3<T> const & v
+ )
+ {
+ return tvec3<T>(
+ T(s) | v.x,
+ T(s) | v.y,
+ T(s) | v.z);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec3<T> operator|
+ (
+ tvec3<T> const & v1,
+ tvec3<T> const & v2
+ )
+ {
+ return tvec3<T>(
+ v1.x | T(v2.x),
+ v1.y | T(v2.y),
+ v1.z | T(v2.z));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec3<T> operator^
+ (
+ tvec3<T> const & v,
+ T const & s
+ )
+ {
+ return tvec3<T>(
+ v.x ^ T(s),
+ v.y ^ T(s),
+ v.z ^ T(s));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec3<T> operator^
+ (
+ T const & s,
+ tvec3<T> const & v
+ )
+ {
+ return tvec3<T>(
+ T(s) ^ v.x,
+ T(s) ^ v.y,
+ T(s) ^ v.z);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec3<T> operator^
+ (
+ tvec3<T> const & v1,
+ tvec3<T> const & v2
+ )
+ {
+ return tvec3<T>(
+ v1.x ^ T(v2.x),
+ v1.y ^ T(v2.y),
+ v1.z ^ T(v2.z));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec3<T> operator<<
+ (
+ tvec3<T> const & v,
+ T const & s
+ )
+ {
+ return tvec3<T>(
+ v.x << T(s),
+ v.y << T(s),
+ v.z << T(s));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec3<T> operator<<
+ (
+ T const & s,
+ tvec3<T> const & v
+ )
+ {
+ return tvec3<T>(
+ T(s) << v.x,
+ T(s) << v.y,
+ T(s) << v.z);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec3<T> operator<<
+ (
+ tvec3<T> const & v1,
+ tvec3<T> const & v2
+ )
+ {
+ return tvec3<T>(
+ v1.x << T(v2.x),
+ v1.y << T(v2.y),
+ v1.z << T(v2.z));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec3<T> operator>>
+ (
+ tvec3<T> const & v,
+ T const & s
+ )
+ {
+ return tvec3<T>(
+ v.x >> T(s),
+ v.y >> T(s),
+ v.z >> T(s));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec3<T> operator>>
+ (
+ T const & s,
+ tvec3<T> const & v
+ )
+ {
+ return tvec3<T>(
+ s >> T(v.x),
+ s >> T(v.y),
+ s >> T(v.z));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec3<T> operator>>
+ (
+ tvec3<T> const & v1,
+ tvec3<T> const & v2
+ )
+ {
+ return tvec3<T>(
+ v1.x >> T(v2.x),
+ v1.y >> T(v2.y),
+ v1.z >> T(v2.z));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec3<T> operator~
+ (
+ tvec3<T> const & v
+ )
+ {
+ return tvec3<T>(
+ ~v.x,
+ ~v.y,
+ ~v.z);
+ }
+
+ //////////////////////////////////////
+ // tref definition
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tref3<T>::tref3(T & x, T & y, T & z) :
+ x(x),
+ y(y),
+ z(z)
+ {}
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tref3<T>::tref3
+ (
+ tref3<T> const & r
+ ) :
+ x(r.x),
+ y(r.y),
+ z(r.z)
+ {}
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tref3<T>::tref3
+ (
+ tvec3<T> const & v
+ ) :
+ x(v.x),
+ y(v.y),
+ z(v.z)
+ {}
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tref3<T> & tref3<T>::operator=
+ (
+ tref3<T> const & r
+ )
+ {
+ x = r.x;
+ y = r.y;
+ z = r.z;
+ return *this;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tref3<T> & tref3<T>::operator=
+ (
+ tvec3<T> const & v
+ )
+ {
+ x = v.x;
+ y = v.y;
+ z = v.z;
+ return *this;
+ }
+
+}//namespace detail
+}//namespace glm
diff --git a/src/glm/core/type_vec4.hpp b/src/glm/core/type_vec4.hpp
new file mode 100644
index 0000000..df74e79
--- /dev/null
+++ b/src/glm/core/type_vec4.hpp
@@ -0,0 +1,282 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2008-08-22
+// Updated : 2010-02-03
+// Licence : This source is under MIT License
+// File : glm/core/type_tvec4.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_core_type_gentype4
+#define glm_core_type_gentype4
+
+#include "type_vec.hpp"
+#include "type_float.hpp"
+#include "type_int.hpp"
+#include "type_size.hpp"
+#include "_swizzle.hpp"
+
+namespace glm{
+namespace detail
+{
+ template <typename T> struct tref2;
+ template <typename T> struct tref3;
+ template <typename T> struct tref4;
+ template <typename T> struct tvec2;
+ template <typename T> struct tvec3;
+
+ ///Basic 4D vector type.
+ //! \ingroup core_template
+ template <typename T>
+ struct tvec4
+ {
+ enum ctor{null};
+
+ typedef T value_type;
+ typedef std::size_t size_type;
+ GLM_FUNC_DECL size_type length() const;
+ static GLM_FUNC_DECL size_type value_size();
+
+ typedef tvec4<T> type;
+ typedef tvec4<bool> bool_type;
+
+ //////////////////////////////////////
+ // Data
+
+# if(GLM_COMPONENT == GLM_COMPONENT_ONLY_XYZW)
+ value_type x, y, z, w;
+# elif(GLM_COMPONENT == GLM_COMPONENT_MS_EXT)
+ union
+ {
+ struct{value_type x, y, z, w;};
+ struct{value_type r, g, b, a;};
+ struct{value_type s, t, p, q;};
+ };
+# else//(GLM_COMPONENT == GLM_COMPONENT_GLSL_NAMES)
+ union {value_type x, r, s;};
+ union {value_type y, g, t;};
+ union {value_type z, b, p;};
+ union {value_type w, a, q;};
+# endif//GLM_COMPONENT
+
+ //////////////////////////////////////
+ // Accesses
+
+ GLM_FUNC_DECL value_type & operator[](size_type i);
+ GLM_FUNC_DECL value_type const & operator[](size_type i) const;
+
+ //////////////////////////////////////
+ // Implicit basic constructors
+
+ GLM_FUNC_DECL tvec4();
+ GLM_FUNC_DECL tvec4(type const & v);
+
+ //////////////////////////////////////
+ // Explicit basic constructors
+
+ GLM_FUNC_DECL explicit tvec4(
+ ctor);
+ GLM_FUNC_DECL explicit tvec4(
+ value_type const & s);
+ GLM_FUNC_DECL explicit tvec4(
+ value_type const & s0,
+ value_type const & s1,
+ value_type const & s2,
+ value_type const & s3);
+
+ //////////////////////////////////////
+ // Swizzle constructors
+
+ GLM_FUNC_DECL tvec4(tref4<T> const & r);
+
+ //////////////////////////////////////
+ // Convertion scalar constructors
+
+ //! Explicit converions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
+ template <typename U>
+ GLM_FUNC_DECL explicit tvec4(
+ U const & x);
+ //! Explicit converions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
+ template <typename A, typename B, typename C, typename D>
+ GLM_FUNC_DECL explicit tvec4(
+ A const & x,
+ B const & y,
+ C const & z,
+ D const & w);
+
+ //////////////////////////////////////
+ // Convertion vector constructors
+
+ //! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
+ template <typename A, typename B, typename C>
+ GLM_FUNC_DECL explicit tvec4(tvec2<A> const & v, B const & s1, C const & s2);
+ //! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
+ template <typename A, typename B, typename C>
+ GLM_FUNC_DECL explicit tvec4(A const & s1, tvec2<B> const & v, C const & s2);
+ //! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
+ template <typename A, typename B, typename C>
+ GLM_FUNC_DECL explicit tvec4(A const & s1, B const & s2, tvec2<C> const & v);
+ //! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
+ template <typename A, typename B>
+ GLM_FUNC_DECL explicit tvec4(tvec3<A> const & v, B const & s);
+ //! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
+ template <typename A, typename B>
+ GLM_FUNC_DECL explicit tvec4(A const & s, tvec3<B> const & v);
+ //! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
+ template <typename A, typename B>
+ GLM_FUNC_DECL explicit tvec4(tvec2<A> const & v1, tvec2<B> const & v2);
+ //! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
+ template <typename U>
+ GLM_FUNC_DECL explicit tvec4(tvec4<U> const & v);
+
+ //////////////////////////////////////
+ // Unary arithmetic operators
+
+ GLM_FUNC_DECL tvec4<T> & operator= (tvec4<T> const & v);
+ template <typename U>
+ GLM_FUNC_DECL tvec4<T> & operator= (tvec4<U> const & v);
+
+ template <typename U>
+ GLM_FUNC_DECL tvec4<T> & operator+=(U const & s);
+ template <typename U>
+ GLM_FUNC_DECL tvec4<T> & operator+=(tvec4<U> const & v);
+ template <typename U>
+ GLM_FUNC_DECL tvec4<T> & operator-=(U const & s);
+ template <typename U>
+ GLM_FUNC_DECL tvec4<T> & operator-=(tvec4<U> const & v);
+ template <typename U>
+ GLM_FUNC_DECL tvec4<T> & operator*=(U const & s);
+ template <typename U>
+ GLM_FUNC_DECL tvec4<T> & operator*=(tvec4<U> const & v);
+ template <typename U>
+ GLM_FUNC_DECL tvec4<T> & operator/=(U const & s);
+ template <typename U>
+ GLM_FUNC_DECL tvec4<T> & operator/=(tvec4<U> const & v);
+ GLM_FUNC_DECL tvec4<T> & operator++();
+ GLM_FUNC_DECL tvec4<T> & operator--();
+
+ //////////////////////////////////////
+ // Unary bit operators
+
+ template <typename U>
+ GLM_FUNC_DECL tvec4<T> & operator%= (U const & s);
+ template <typename U>
+ GLM_FUNC_DECL tvec4<T> & operator%= (tvec4<U> const & v);
+ template <typename U>
+ GLM_FUNC_DECL tvec4<T> & operator&= (U const & s);
+ template <typename U>
+ GLM_FUNC_DECL tvec4<T> & operator&= (tvec4<U> const & v);
+ template <typename U>
+ GLM_FUNC_DECL tvec4<T> & operator|= (U const & s);
+ template <typename U>
+ GLM_FUNC_DECL tvec4<T> & operator|= (tvec4<U> const & v);
+ template <typename U>
+ GLM_FUNC_DECL tvec4<T> & operator^= (U const & s);
+ template <typename U>
+ GLM_FUNC_DECL tvec4<T> & operator^= (tvec4<U> const & v);
+ template <typename U>
+ GLM_FUNC_DECL tvec4<T> & operator<<=(U const & s);
+ template <typename U>
+ GLM_FUNC_DECL tvec4<T> & operator<<=(tvec4<U> const & v);
+ template <typename U>
+ GLM_FUNC_DECL tvec4<T> & operator>>=(U const & s);
+ template <typename U>
+ GLM_FUNC_DECL tvec4<T> & operator>>=(tvec4<U> const & v);
+
+ //////////////////////////////////////
+ // Swizzle operators
+
+ GLM_FUNC_DECL value_type swizzle(comp X) const;
+ GLM_FUNC_DECL tvec2<T> swizzle(comp X, comp Y) const;
+ GLM_FUNC_DECL tvec3<T> swizzle(comp X, comp Y, comp Z) const;
+ GLM_FUNC_DECL tvec4<T> swizzle(comp X, comp Y, comp Z, comp W) const;
+ GLM_FUNC_DECL tref4<T> swizzle(comp X, comp Y, comp Z, comp W);
+ };
+
+ template <typename T>
+ struct tref4
+ {
+ GLM_FUNC_DECL tref4(T & x, T & y, T & z, T & w);
+ GLM_FUNC_DECL tref4(tref4<T> const & r);
+ GLM_FUNC_DECL tref4(tvec4<T> const & v);
+
+ GLM_FUNC_DECL tref4<T> & operator= (tref4<T> const & r);
+ GLM_FUNC_DECL tref4<T> & operator= (tvec4<T> const & v);
+
+ T & x;
+ T & y;
+ T & z;
+ T & w;
+ };
+
+ GLM_DETAIL_IS_VECTOR(tvec4);
+}//namespace detail
+
+namespace core{
+namespace type{
+namespace precision
+{
+ //! 4 components vector of high precision floating-point numbers.
+ //! There is no guarantee on the actual precision.
+ //! From GLSL 1.30.8 specification, section 4.5.2 Precision Qualifiers.
+ //! \ingroup core_precision
+ typedef detail::tvec4<highp_float> highp_vec4;
+
+ //! 4 components vector of medium precision floating-point numbers.
+ //! There is no guarantee on the actual precision.
+ //! From GLSL 1.30.8 specification, section 4.5.2 Precision Qualifiers.
+ //! \ingroup core_precision
+ typedef detail::tvec4<mediump_float> mediump_vec4;
+
+ //! 4 components vector of low precision floating-point numbers.
+ //! There is no guarantee on the actual precision.
+ //! From GLSL 1.30.8 specification, section 4.5.2 Precision Qualifiers.
+ //! \ingroup core_precision
+ typedef detail::tvec4<lowp_float> lowp_vec4;
+
+ //! 4 components vector of high precision signed integer numbers.
+ //! There is no guarantee on the actual precision.
+ //! From GLSL 1.30.8 specification, section 4.1.5 Precision Qualifiers.
+ //! \ingroup core_precision
+ typedef detail::tvec4<highp_int> highp_ivec4;
+
+ //! 4 components vector of medium precision signed integer numbers.
+ //! There is no guarantee on the actual precision.
+ //! From GLSL 1.30.8 specification, section 4.1.5 Precision Qualifiers.
+ //! \ingroup core_precision
+ typedef detail::tvec4<mediump_int> mediump_ivec4;
+
+ //! 4 components vector of low precision signed integer numbers.
+ //! There is no guarantee on the actual precision.
+ //! From GLSL 1.30.8 specification, section 4.1.5 Precision Qualifiers.
+ //! \ingroup core_precision
+ typedef detail::tvec4<lowp_int> lowp_ivec4;
+
+ //! 4 components vector of high precision unsigned integer numbers.
+ //! There is no guarantee on the actual precision.
+ //! From GLSL 1.30.8 specification, section 4.1.5 Precision Qualifiers.
+ //! \ingroup core_precision
+ typedef detail::tvec4<highp_uint> highp_uvec4;
+
+ //! 4 components vector of medium precision unsigned integer numbers.
+ //! There is no guarantee on the actual precision.
+ //! From GLSL 1.30.8 specification, section 4.1.5 Precision Qualifiers.
+ //! \ingroup core_precision
+ typedef detail::tvec4<mediump_uint> mediump_uvec4;
+
+ //! 4 components vector of low precision unsigned integer numbers.
+ //! There is no guarantee on the actual precision.
+ //! From GLSL 1.30.8 specification, section 4.1.5 Precision Qualifiers.
+ //! \ingroup core_precision
+ typedef detail::tvec4<lowp_uint> lowp_uvec4;
+
+}//namespace precision
+}//namespace type
+}//namespace core
+}//namespace glm
+
+#ifndef GLM_EXTERNAL_TEMPLATE
+#include "type_vec4.inl"
+#endif//GLM_EXTERNAL_TEMPLATE
+
+#endif//glm_core_type_gentype4
diff --git a/src/glm/core/type_vec4.inl b/src/glm/core/type_vec4.inl
new file mode 100644
index 0000000..6d96ab8
--- /dev/null
+++ b/src/glm/core/type_vec4.inl
@@ -0,0 +1,1226 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2008-08-23
+// Updated : 2010-02-05
+// Licence : This source is under MIT License
+// File : glm/core/type_tvec4.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm{
+namespace detail
+{
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename tvec4<T>::size_type tvec4<T>::length() const
+ {
+ return 4;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename tvec4<T>::size_type tvec4<T>::value_size()
+ {
+ return 4;
+ }
+
+ //////////////////////////////////////
+ // Accesses
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename tvec4<T>::value_type &
+ tvec4<T>::operator[]
+ (
+ size_type i
+ )
+ {
+ assert(i < value_size());
+ return (&x)[i];
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename tvec4<T>::value_type const &
+ tvec4<T>::operator[]
+ (
+ size_type i
+ ) const
+ {
+ assert(i < value_size());
+ return (&x)[i];
+ }
+
+ //////////////////////////////////////
+ // Implicit basic constructors
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec4<T>::tvec4() :
+ x(value_type(0)),
+ y(value_type(0)),
+ z(value_type(0)),
+ w(value_type(0))
+ {}
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec4<T>::tvec4
+ (
+ ctor
+ )
+ {}
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec4<T>::tvec4
+ (
+ type const & v
+ ) :
+ x(v.x),
+ y(v.y),
+ z(v.z),
+ w(v.w)
+ {}
+
+ //////////////////////////////////////
+ // Explicit basic constructors
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec4<T>::tvec4
+ (
+ value_type const & s
+ ) :
+ x(s),
+ y(s),
+ z(s),
+ w(s)
+ {}
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec4<T>::tvec4
+ (
+ value_type const & s1,
+ value_type const & s2,
+ value_type const & s3,
+ value_type const & s4
+ ) :
+ x(s1),
+ y(s2),
+ z(s3),
+ w(s4)
+ {}
+
+ //////////////////////////////////////
+ // Swizzle constructors
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec4<T>::tvec4
+ (
+ tref4<T> const & r
+ ) :
+ x(r.x),
+ y(r.y),
+ z(r.z),
+ w(r.w)
+ {}
+
+ //////////////////////////////////////
+ // Convertion scalar constructors
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tvec4<T>::tvec4
+ (
+ U const & x
+ ) :
+ x(value_type(x)),
+ y(value_type(x)),
+ z(value_type(x)),
+ w(value_type(x))
+ {}
+
+ template <typename T>
+ template <typename A, typename B, typename C, typename D>
+ GLM_FUNC_QUALIFIER tvec4<T>::tvec4
+ (
+ A const & x,
+ B const & y,
+ C const & z,
+ D const & w
+ ) :
+ x(value_type(x)),
+ y(value_type(y)),
+ z(value_type(z)),
+ w(value_type(w))
+ {}
+
+ //////////////////////////////////////
+ // Convertion vector constructors
+
+ template <typename T>
+ template <typename A, typename B, typename C>
+ GLM_FUNC_QUALIFIER tvec4<T>::tvec4
+ (
+ tvec2<A> const & v,
+ B const & s1,
+ C const & s2
+ ) :
+ x(value_type(v.x)),
+ y(value_type(v.y)),
+ z(value_type(s1)),
+ w(value_type(s2))
+ {}
+
+ template <typename T>
+ template <typename A, typename B, typename C>
+ GLM_FUNC_QUALIFIER tvec4<T>::tvec4
+ (
+ A const & s1,
+ tvec2<B> const & v,
+ C const & s2
+ ) :
+ x(value_type(s1)),
+ y(value_type(v.x)),
+ z(value_type(v.y)),
+ w(value_type(s2))
+ {}
+
+ template <typename T>
+ template <typename A, typename B, typename C>
+ GLM_FUNC_QUALIFIER tvec4<T>::tvec4
+ (
+ A const & s1,
+ B const & s2,
+ tvec2<C> const & v
+ ) :
+ x(value_type(s1)),
+ y(value_type(s2)),
+ z(value_type(v.x)),
+ w(value_type(v.y))
+ {}
+
+ template <typename T>
+ template <typename A, typename B>
+ GLM_FUNC_QUALIFIER tvec4<T>::tvec4
+ (
+ tvec3<A> const & v,
+ B const & s
+ ) :
+ x(value_type(v.x)),
+ y(value_type(v.y)),
+ z(value_type(v.z)),
+ w(value_type(s))
+ {}
+
+ template <typename T>
+ template <typename A, typename B>
+ GLM_FUNC_QUALIFIER tvec4<T>::tvec4
+ (
+ A const & s,
+ tvec3<B> const & v
+ ) :
+ x(value_type(s)),
+ y(value_type(v.x)),
+ z(value_type(v.y)),
+ w(value_type(v.z))
+ {}
+
+ template <typename T>
+ template <typename A, typename B>
+ GLM_FUNC_QUALIFIER tvec4<T>::tvec4
+ (
+ tvec2<A> const & v1,
+ tvec2<B> const & v2
+ ) :
+ x(value_type(v1.x)),
+ y(value_type(v1.y)),
+ z(value_type(v2.x)),
+ w(value_type(v2.y))
+ {}
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tvec4<T>::tvec4
+ (
+ tvec4<U> const & v
+ ) :
+ x(value_type(v.x)),
+ y(value_type(v.y)),
+ z(value_type(v.z)),
+ w(value_type(v.w))
+ {}
+
+ //////////////////////////////////////
+ // Unary arithmetic operators
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec4<T> & tvec4<T>::operator=
+ (
+ tvec4<T> const & v
+ )
+ {
+ this->x = v.x;
+ this->y = v.y;
+ this->z = v.z;
+ this->w = v.w;
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tvec4<T> & tvec4<T>::operator=
+ (
+ tvec4<U> const & v
+ )
+ {
+ this->x = T(v.x);
+ this->y = T(v.y);
+ this->z = T(v.z);
+ this->w = T(v.w);
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tvec4<T> & tvec4<T>::operator+=
+ (
+ U const & s
+ )
+ {
+ this->x += T(s);
+ this->y += T(s);
+ this->z += T(s);
+ this->w += T(s);
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tvec4<T> & tvec4<T>::operator+=
+ (
+ tvec4<U> const & v
+ )
+ {
+ this->x += T(v.x);
+ this->y += T(v.y);
+ this->z += T(v.z);
+ this->w += T(v.w);
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tvec4<T> & tvec4<T>::operator-=
+ (
+ U const & s
+ )
+ {
+ this->x -= T(s);
+ this->y -= T(s);
+ this->z -= T(s);
+ this->w -= T(s);
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tvec4<T> & tvec4<T>::operator-=
+ (
+ tvec4<U> const & v
+ )
+ {
+ this->x -= T(v.x);
+ this->y -= T(v.y);
+ this->z -= T(v.z);
+ this->w -= T(v.w);
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tvec4<T> & tvec4<T>::operator*=
+ (
+ U const & s
+ )
+ {
+ this->x *= T(s);
+ this->y *= T(s);
+ this->z *= T(s);
+ this->w *= T(s);
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tvec4<T> & tvec4<T>::operator*=
+ (
+ tvec4<U> const & v
+ )
+ {
+ this->x *= T(v.x);
+ this->y *= T(v.y);
+ this->z *= T(v.z);
+ this->w *= T(v.w);
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tvec4<T> & tvec4<T>::operator/=
+ (
+ U const & s
+ )
+ {
+ this->x /= T(s);
+ this->y /= T(s);
+ this->z /= T(s);
+ this->w /= T(s);
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tvec4<T> & tvec4<T>::operator/=
+ (
+ tvec4<U> const & v
+ )
+ {
+ this->x /= T(v.x);
+ this->y /= T(v.y);
+ this->z /= T(v.z);
+ this->w /= T(v.w);
+ return *this;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec4<T> & tvec4<T>::operator++()
+ {
+ ++this->x;
+ ++this->y;
+ ++this->z;
+ ++this->w;
+ return *this;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec4<T> & tvec4<T>::operator--()
+ {
+ --this->x;
+ --this->y;
+ --this->z;
+ --this->w;
+ return *this;
+ }
+
+ //////////////////////////////////////
+ // Unary bit operators
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tvec4<T> & tvec4<T>::operator%=
+ (
+ U const & s
+ )
+ {
+ this->x %= T(s);
+ this->y %= T(s);
+ this->z %= T(s);
+ this->w %= T(s);
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tvec4<T> & tvec4<T>::operator%=
+ (
+ tvec4<U> const & v
+ )
+ {
+ this->x %= T(v.x);
+ this->y %= T(v.y);
+ this->z %= T(v.z);
+ this->w %= T(v.w);
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tvec4<T> & tvec4<T>::operator&=
+ (
+ U const & s
+ )
+ {
+ this->x &= T(s);
+ this->y &= T(s);
+ this->z &= T(s);
+ this->w &= T(s);
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tvec4<T> & tvec4<T>::operator&=
+ (
+ tvec4<U> const & v
+ )
+ {
+ this->x &= T(v.x);
+ this->y &= T(v.y);
+ this->z &= T(v.z);
+ this->w &= T(v.w);
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tvec4<T> & tvec4<T>::operator|=
+ (
+ U const & s
+ )
+ {
+ this->x |= T(s);
+ this->y |= T(s);
+ this->z |= T(s);
+ this->w |= T(s);
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tvec4<T> & tvec4<T>::operator|=
+ (
+ tvec4<U> const & v
+ )
+ {
+ this->x |= T(v.x);
+ this->y |= T(v.y);
+ this->z |= T(v.z);
+ this->w |= T(v.w);
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tvec4<T> & tvec4<T>::operator^=
+ (
+ U const & s
+ )
+ {
+ this->x ^= T(s);
+ this->y ^= T(s);
+ this->z ^= T(s);
+ this->w ^= T(s);
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tvec4<T> & tvec4<T>::operator^=
+ (
+ tvec4<U> const & v
+ )
+ {
+ this->x ^= T(v.x);
+ this->y ^= T(v.y);
+ this->z ^= T(v.z);
+ this->w ^= T(v.w);
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tvec4<T> & tvec4<T>::operator<<=
+ (
+ U const & s
+ )
+ {
+ this->x <<= T(s);
+ this->y <<= T(s);
+ this->z <<= T(s);
+ this->w <<= T(s);
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tvec4<T> & tvec4<T>::operator<<=
+ (
+ tvec4<U> const & v
+ )
+ {
+ this->x <<= T(v.x);
+ this->y <<= T(v.y);
+ this->z <<= T(v.z);
+ this->w <<= T(v.w);
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tvec4<T> & tvec4<T>::operator>>=
+ (
+ U const & s
+ )
+ {
+ this->x >>= T(s);
+ this->y >>= T(s);
+ this->z >>= T(s);
+ this->w >>= T(s);
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ GLM_FUNC_QUALIFIER tvec4<T> & tvec4<T>::operator>>=
+ (
+ tvec4<U> const & v
+ )
+ {
+ this->x >>= T(v.x);
+ this->y >>= T(v.y);
+ this->z >>= T(v.z);
+ this->w >>= T(v.w);
+ return *this;
+ }
+
+ //////////////////////////////////////
+ // Swizzle operators
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename tvec4<T>::value_type
+ tvec4<T>::swizzle
+ (
+ comp x
+ ) const
+ {
+ return (*this)[x];
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec2<T> tvec4<T>::swizzle
+ (
+ comp x,
+ comp y
+ ) const
+ {
+ return tvec2<T>(
+ (*this)[x],
+ (*this)[y]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec3<T> tvec4<T>::swizzle
+ (
+ comp x,
+ comp y,
+ comp z
+ ) const
+ {
+ return tvec3<T>(
+ (*this)[x],
+ (*this)[y],
+ (*this)[z]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec4<T> tvec4<T>::swizzle
+ (
+ comp x,
+ comp y,
+ comp z,
+ comp w
+ ) const
+ {
+ return tvec4<T>(
+ (*this)[x],
+ (*this)[y],
+ (*this)[z],
+ (*this)[w]);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tref4<T> tvec4<T>::swizzle
+ (
+ comp x,
+ comp y,
+ comp z,
+ comp w
+ )
+ {
+ return tref4<T>(
+ (*this)[x],
+ (*this)[y],
+ (*this)[z],
+ (*this)[w]);
+ }
+
+ //////////////////////////////////////
+ // Binary arithmetic operators
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec4<T> operator+
+ (
+ tvec4<T> const & v,
+ typename tvec4<T>::value_type const & s
+ )
+ {
+ return tvec4<T>(
+ v.x + s,
+ v.y + s,
+ v.z + s,
+ v.w + s);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec4<T> operator+
+ (
+ typename tvec4<T>::value_type const & s,
+ tvec4<T> const & v
+ )
+ {
+ return tvec4<T>(
+ s + v.x,
+ s + v.y,
+ s + v.z,
+ s + v.w);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec4<T> operator+
+ (
+ tvec4<T> const & v1,
+ tvec4<T> const & v2
+ )
+ {
+ return tvec4<T>(
+ v1.x + v2.x,
+ v1.y + v2.y,
+ v1.z + v2.z,
+ v1.w + v2.w);
+ }
+
+ //operator-
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec4<T> operator-
+ (
+ tvec4<T> const & v,
+ typename tvec4<T>::value_type const & s
+ )
+ {
+ return tvec4<T>(
+ v.x - s,
+ v.y - s,
+ v.z - s,
+ v.w - s);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec4<T> operator-
+ (
+ typename tvec4<T>::value_type const & s,
+ tvec4<T> const & v
+ )
+ {
+ return tvec4<T>(
+ s - v.x,
+ s - v.y,
+ s - v.z,
+ s - v.w);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec4<T> operator-
+ (
+ tvec4<T> const & v1,
+ tvec4<T> const & v2
+ )
+ {
+ return tvec4<T>(
+ v1.x - v2.x,
+ v1.y - v2.y,
+ v1.z - v2.z,
+ v1.w - v2.w);
+ }
+
+ //operator*
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec4<T> operator*
+ (
+ tvec4<T> const & v,
+ typename tvec4<T>::value_type const & s
+ )
+ {
+ return tvec4<T>(
+ v.x * s,
+ v.y * s,
+ v.z * s,
+ v.w * s);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec4<T> operator*
+ (
+ typename tvec4<T>::value_type const & s,
+ tvec4<T> const & v
+ )
+ {
+ return tvec4<T>(
+ s * v.x,
+ s * v.y,
+ s * v.z,
+ s * v.w);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec4<T> operator*
+ (
+ tvec4<T> const & v1,
+ tvec4<T> const & v2
+ )
+ {
+ return tvec4<T>(
+ v1.x * v2.x,
+ v1.y * v2.y,
+ v1.z * v2.z,
+ v1.w * v2.w);
+ }
+
+ //operator/
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec4<T> operator/
+ (
+ tvec4<T> const & v,
+ typename tvec4<T>::value_type const & s
+ )
+ {
+ return tvec4<T>(
+ v.x / s,
+ v.y / s,
+ v.z / s,
+ v.w / s);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec4<T> operator/
+ (
+ typename tvec4<T>::value_type const & s,
+ tvec4<T> const & v
+ )
+ {
+ return tvec4<T>(
+ s / v.x,
+ s / v.y,
+ s / v.z,
+ s / v.w);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec4<T> operator/
+ (
+ tvec4<T> const & v1,
+ tvec4<T> const & v2
+ )
+ {
+ return tvec4<T>(
+ v1.x / v2.x,
+ v1.y / v2.y,
+ v1.z / v2.z,
+ v1.w / v2.w);
+ }
+
+ // Unary constant operators
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec4<T> operator-
+ (
+ tvec4<T> const & v
+ )
+ {
+ return tvec4<T>(
+ -v.x,
+ -v.y,
+ -v.z,
+ -v.w);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec4<T> operator++
+ (
+ tvec4<T> const & v,
+ int
+ )
+ {
+ typename tvec4<T>::value_type One(1);
+ return tvec4<T>(
+ v.x + One,
+ v.y + One,
+ v.z + One,
+ v.w + One);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec4<T> operator--
+ (
+ tvec4<T> const & v,
+ int
+ )
+ {
+ typename tvec4<T>::value_type One(1);
+ return tvec4<T>(
+ v.x - One,
+ v.y - One,
+ v.z - One,
+ v.w - One);
+ }
+
+ //////////////////////////////////////
+ // Boolean operators
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER bool operator==
+ (
+ tvec4<T> const & v1,
+ tvec4<T> const & v2
+ )
+ {
+ return (v1.x == v2.x) && (v1.y == v2.y) && (v1.z == v2.z) && (v1.w == v2.w);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER bool operator!=
+ (
+ tvec4<T> const & v1,
+ tvec4<T> const & v2
+ )
+ {
+ return (v1.x != v2.x) || (v1.y != v2.y) || (v1.z != v2.z) || (v1.w != v2.w);
+ }
+
+ //////////////////////////////////////
+ // Binary bit operators
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec4<T> operator%
+ (
+ tvec4<T> const & v,
+ typename tvec4<T>::value_type const & s
+ )
+ {
+ return tvec4<T>(
+ v.x % s,
+ v.y % s,
+ v.z % s,
+ v.w % s);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec4<T> operator%
+ (
+ typename tvec4<T>::value_type const & s,
+ tvec4<T> const & v
+ )
+ {
+ return tvec4<T>(
+ s % v.x,
+ s % v.y,
+ s % v.z,
+ s % v.w);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec4<T> operator%
+ (
+ tvec4<T> const & v1,
+ tvec4<T> const & v2
+ )
+ {
+ return tvec4<T>(
+ v1.x % v2.x,
+ v1.y % v2.y,
+ v1.z % v2.z,
+ v1.w % v2.w);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec4<T> operator&
+ (
+ tvec4<T> const & v,
+ typename tvec4<T>::value_type const & s
+ )
+ {
+ return tvec4<T>(
+ v.x & s,
+ v.y & s,
+ v.z & s,
+ v.w & s);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec4<T> operator&
+ (
+ typename tvec4<T>::value_type const & s,
+ tvec4<T> const & v
+ )
+ {
+ return tvec4<T>(
+ s & v.x,
+ s & v.y,
+ s & v.z,
+ s & v.w);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec4<T> operator&
+ (
+ tvec4<T> const & v1,
+ tvec4<T> const & v2
+ )
+ {
+ return tvec4<T>(
+ v1.x & v2.x,
+ v1.y & v2.y,
+ v1.z & v2.z,
+ v1.w & v2.w);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec4<T> operator|
+ (
+ tvec4<T> const & v,
+ typename tvec4<T>::value_type const & s
+ )
+ {
+ return tvec4<T>(
+ v.x | s,
+ v.y | s,
+ v.z | s,
+ v.w | s);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec4<T> operator|
+ (
+ typename tvec4<T>::value_type const & s,
+ tvec4<T> const & v
+ )
+ {
+ return tvec4<T>(
+ s | v.x,
+ s | v.y,
+ s | v.z,
+ s | v.w);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec4<T> operator|
+ (
+ tvec4<T> const & v1,
+ tvec4<T> const & v2
+ )
+ {
+ return tvec4<T>(
+ v1.x | v2.x,
+ v1.y | v2.y,
+ v1.z | v2.z,
+ v1.w | v2.w);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec4<T> operator^
+ (
+ tvec4<T> const & v,
+ typename tvec4<T>::value_type const & s
+ )
+ {
+ return tvec4<T>(
+ v.x ^ s,
+ v.y ^ s,
+ v.z ^ s,
+ v.w ^ s);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec4<T> operator^
+ (
+ typename tvec4<T>::value_type const & s,
+ tvec4<T> const & v
+ )
+ {
+ return tvec4<T>(
+ s ^ v.x,
+ s ^ v.y,
+ s ^ v.z,
+ s ^ v.w);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec4<T> operator^
+ (
+ tvec4<T> const & v1,
+ tvec4<T> const & v2
+ )
+ {
+ return tvec4<T>(
+ v1.x ^ v2.x,
+ v1.y ^ v2.y,
+ v1.z ^ v2.z,
+ v1.w ^ v2.w);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec4<T> operator<<
+ (
+ tvec4<T> const & v,
+ typename tvec4<T>::value_type const & s
+ )
+ {
+ return tvec4<T>(
+ v.x << s,
+ v.y << s,
+ v.z << s,
+ v.w << s);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec4<T> operator<<
+ (
+ typename tvec4<T>::value_type const & s,
+ tvec4<T> const & v
+ )
+ {
+ return tvec4<T>(
+ s << v.x,
+ s << v.y,
+ s << v.z,
+ s << v.w);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec4<T> operator<<
+ (
+ tvec4<T> const & v1,
+ tvec4<T> const & v2
+ )
+ {
+ return tvec4<T>(
+ v1.x << v2.x,
+ v1.y << v2.y,
+ v1.z << v2.z,
+ v1.w << v2.w);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec4<T> operator>>
+ (
+ tvec4<T> const & v,
+ typename tvec4<T>::value_type const & s
+ )
+ {
+ return tvec4<T>(
+ v.x >> s,
+ v.y >> s,
+ v.z >> s,
+ v.w >> s);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec4<T> operator>>
+ (
+ typename tvec4<T>::value_type const & s,
+ tvec4<T> const & v
+ )
+ {
+ return tvec4<T>(
+ s >> v.x,
+ s >> v.y,
+ s >> v.z,
+ s >> v.w);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec4<T> operator>>
+ (
+ tvec4<T> const & v1,
+ tvec4<T> const & v2
+ )
+ {
+ return tvec4<T>(
+ v1.x >> v2.x,
+ v1.y >> v2.y,
+ v1.z >> v2.z,
+ v1.w >> v2.w);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tvec4<T> operator~
+ (
+ tvec4<T> const & v
+ )
+ {
+ return tvec4<T>(
+ ~v.x,
+ ~v.y,
+ ~v.z,
+ ~v.w);
+ }
+
+ //////////////////////////////////////
+ // tref definition
+
+ template <typename T>
+ tref4<T>::tref4
+ (
+ T & x,
+ T & y,
+ T & z,
+ T & w
+ ) :
+ x(x),
+ y(y),
+ z(z),
+ w(w)
+ {}
+
+ template <typename T>
+ tref4<T>::tref4
+ (
+ tref4<T> const & r
+ ) :
+ x(r.x),
+ y(r.y),
+ z(r.z),
+ w(r.w)
+ {}
+
+ template <typename T>
+ tref4<T>::tref4
+ (
+ tvec4<T> const & v
+ ) :
+ x(v.x),
+ y(v.y),
+ z(v.z),
+ w(v.w)
+ {}
+
+ template <typename T>
+ tref4<T>& tref4<T>::operator=
+ (
+ tref4<T> const & r
+ )
+ {
+ x = r.x;
+ y = r.y;
+ z = r.z;
+ w = r.w;
+ return *this;
+ }
+
+ template <typename T>
+ tref4<T>& tref4<T>::operator=
+ (
+ tvec4<T> const & v
+ )
+ {
+ x = v.x;
+ y = v.y;
+ z = v.z;
+ w = v.w;
+ return *this;
+ }
+
+}//namespace detail
+}//namespace glm
diff --git a/src/glm/ext.hpp b/src/glm/ext.hpp
new file mode 100644
index 0000000..8dd89fa
--- /dev/null
+++ b/src/glm/ext.hpp
@@ -0,0 +1,97 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2009-05-01
+// Updated : 2010-12-13
+// Licence : This source is under MIT License
+// File : glm/ext.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_ext
+#define glm_ext
+
+#if(defined(GLM_MESSAGES) && !defined(GLM_MESSAGE_EXT_INCLUDED_DISPLAYED))
+# define GLM_MESSAGE_EXT_INCLUDED_DISPLAYED
+# pragma message("GLM: All extensions included (not recommanded)")
+#endif//GLM_MESSAGES
+
+#include "./gtc/half_float.hpp"
+#include "./gtc/matrix_access.hpp"
+#include "./gtc/matrix_integer.hpp"
+#include "./gtc/matrix_inverse.hpp"
+#include "./gtc/matrix_transform.hpp"
+#include "./gtc/quaternion.hpp"
+#include "./gtc/swizzle.hpp"
+#include "./gtc/type_precision.hpp"
+#include "./gtc/type_ptr.hpp"
+
+#include "./gtx/associated_min_max.hpp"
+#include "./gtx/bit.hpp"
+#include "./gtx/closest_point.hpp"
+#include "./gtx/color_cast.hpp"
+#include "./gtx/color_space.hpp"
+#include "./gtx/color_space_YCoCg.hpp"
+#include "./gtx/compatibility.hpp"
+#include "./gtx/component_wise.hpp"
+#include "./gtx/epsilon.hpp"
+#include "./gtx/euler_angles.hpp"
+#include "./gtx/extend.hpp"
+#include "./gtx/extented_min_max.hpp"
+#include "./gtx/fast_exponential.hpp"
+#include "./gtx/fast_square_root.hpp"
+#include "./gtx/fast_trigonometry.hpp"
+#include "./gtx/gradient_paint.hpp"
+#include "./gtx/handed_coordinate_space.hpp"
+#include "./gtx/inertia.hpp"
+#include "./gtx/int_10_10_10_2.hpp"
+#include "./gtx/integer.hpp"
+#include "./gtx/intersect.hpp"
+#include "./gtx/log_base.hpp"
+#include "./gtx/matrix_cross_product.hpp"
+#include "./gtx/matrix_interpolation.hpp"
+#include "./gtx/matrix_major_storage.hpp"
+#include "./gtx/matrix_operation.hpp"
+#include "./gtx/matrix_query.hpp"
+#include "./gtx/mixed_product.hpp"
+#include "./gtx/multiple.hpp"
+#include "./gtx/noise.hpp"
+#include "./gtx/norm.hpp"
+#include "./gtx/normal.hpp"
+#include "./gtx/normalize_dot.hpp"
+#include "./gtx/number_precision.hpp"
+#include "./gtx/ocl_type.hpp"
+#include "./gtx/optimum_pow.hpp"
+#include "./gtx/orthonormalize.hpp"
+#include "./gtx/perpendicular.hpp"
+#include "./gtx/polar_coordinates.hpp"
+#include "./gtx/projection.hpp"
+#include "./gtx/quaternion.hpp"
+#include "./gtx/random.hpp"
+#include "./gtx/raw_data.hpp"
+#include "./gtx/reciprocal.hpp"
+#include "./gtx/rotate_vector.hpp"
+#include "./gtx/spline.hpp"
+#include "./gtx/std_based_type.hpp"
+#include "./gtx/string_cast.hpp"
+#include "./gtx/transform.hpp"
+#include "./gtx/transform2.hpp"
+#include "./gtx/ulp.hpp"
+#include "./gtx/unsigned_int.hpp"
+#include "./gtx/vec1.hpp"
+#include "./gtx/vector_access.hpp"
+#include "./gtx/vector_angle.hpp"
+#include "./gtx/vector_query.hpp"
+#include "./gtx/verbose_operator.hpp"
+#include "./gtx/wrap.hpp"
+
+#if(GLM_ARCH & GLM_ARCH_SSE2)
+# include "./gtx/simd_vec4.hpp"
+# include "./gtx/simd_mat4.hpp"
+#endif
+
+#include "./virtrev/xstream.hpp"
+
+//const float goldenRatio = 1.618033988749894848f;
+//const float pi = 3.141592653589793238f;
+
+#endif //glm_ext
diff --git a/src/glm/glm.hpp b/src/glm/glm.hpp
new file mode 100644
index 0000000..5fb8cce
--- /dev/null
+++ b/src/glm/glm.hpp
@@ -0,0 +1,93 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2005-01-14
+// Updated : 2011-01-19
+// Licence : This source is under MIT License
+// File : glm/glm.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#include "core/_fixes.hpp"
+
+#ifndef glm_glm
+#define glm_glm
+
+#include <cmath>
+#include <climits>
+#include <cfloat>
+#include <limits>
+#include "core/setup.hpp"
+
+#if(defined(GLM_MESSAGES) && !defined(GLM_MESSAGE_CORE_INCLUDED_DISPLAYED))
+# define GLM_MESSAGE_CORE_INCLUDED_DISPLAYED
+# pragma message("GLM: Core library included")
+#endif//GLM_MESSAGE
+
+//! GLM namespace, it contains all GLSL based features.
+namespace glm
+{
+ //! GLM core. Namespace that includes all the feature define by GLSL 4.10.6 specification. This namespace is included in glm namespace.
+ namespace core
+ {
+ //! Scalar, vectors and matrices
+ //! from section 4.1.2 Booleans, 4.1.3 Integers section, 4.1.4 Floats section,
+ //! 4.1.5 Vectors and section 4.1.6 Matrices of GLSL 1.30.8 specification.
+ //! This namespace resolves precision qualifier define in section 4.5 of GLSL 1.30.8 specification.
+ namespace type
+ {
+ namespace precision{}
+ }
+
+ //! Some of the functions defined in section 8 Built-in Functions of GLSL 1.30.8 specification.
+ //! Angle and trigonometry, exponential, common, geometric, matrix and vector relational functions.
+ namespace function{}
+ }//namespace core
+
+ //! G-Truc Creation stable extensions.
+ namespace gtc{}
+
+ //! G-Truc Creation experimental extensions.
+ //! The interface could change between releases.
+ namespace gtx{}
+
+ //! VIRTREV extensions.
+ namespace virtrev{}
+
+ using namespace core::type;
+ using namespace core::type::precision;
+ using namespace core::function;
+}//namespace glm
+
+#include "./core/_detail.hpp"
+#include "./core/type.hpp"
+
+#include "./core/func_trigonometric.hpp"
+#include "./core/func_exponential.hpp"
+#include "./core/func_common.hpp"
+#include "./core/func_packing.hpp"
+#include "./core/func_geometric.hpp"
+#include "./core/func_matrix.hpp"
+#include "./core/func_vector_relational.hpp"
+#include "./core/func_integer.hpp"
+#include "./core/func_noise.hpp"
+#include "./core/_swizzle.hpp"
+
+////////////////////
+// check type sizes
+#ifndef GLM_STATIC_ASSERT_NULL
+ GLM_STATIC_ASSERT(sizeof(glm::detail::int8) == 1, "int8 size isn't 1 byte on this platform");
+ GLM_STATIC_ASSERT(sizeof(glm::detail::int16) == 2, "int16 size isn't 2 bytes on this platform");
+ GLM_STATIC_ASSERT(sizeof(glm::detail::int32) == 4, "int32 size isn't 4 bytes on this platform");
+ GLM_STATIC_ASSERT(sizeof(glm::detail::int64) == 8, "int64 size isn't 8 bytes on this platform");
+
+ GLM_STATIC_ASSERT(sizeof(glm::detail::uint8) == 1, "uint8 size isn't 1 byte on this platform");
+ GLM_STATIC_ASSERT(sizeof(glm::detail::uint16) == 2, "uint16 size isn't 2 bytes on this platform");
+ GLM_STATIC_ASSERT(sizeof(glm::detail::uint32) == 4, "uint32 size isn't 4 bytes on this platform");
+ GLM_STATIC_ASSERT(sizeof(glm::detail::uint64) == 8, "uint64 size isn't 8 bytes on this platform");
+
+ GLM_STATIC_ASSERT(sizeof(glm::detail::float16) == 2, "float16 size isn't 2 bytes on this platform");
+ GLM_STATIC_ASSERT(sizeof(glm::detail::float32) == 4, "float32 size isn't 4 bytes on this platform");
+ GLM_STATIC_ASSERT(sizeof(glm::detail::float64) == 8, "float64 size isn't 8 bytes on this platform");
+#endif//GLM_STATIC_ASSERT_NULL
+
+#endif//glm_glm
diff --git a/src/glm/gtc/half_float.hpp b/src/glm/gtc/half_float.hpp
new file mode 100644
index 0000000..32f6d4b
--- /dev/null
+++ b/src/glm/gtc/half_float.hpp
@@ -0,0 +1,401 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2009-04-29
+// Updated : 2010-02-07
+// Licence : This source is under MIT License
+// File : glm/gtc/half_float.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_gtc_half_float
+#define glm_gtc_half_float
+
+// Dependency:
+#include "../glm.hpp"
+
+#if(defined(GLM_MESSAGES) && !defined(glm_ext))
+# pragma message("GLM: GLM_GTC_half_float extension included")
+#endif
+
+namespace glm{
+namespace detail
+{
+#ifndef _MSC_EXTENSIONS
+ template <>
+ struct tvec2<thalf>
+ {
+ enum ctor{null};
+ typedef thalf value_type;
+ typedef std::size_t size_type;
+ static size_type value_size();
+
+ typedef tvec2<thalf> type;
+ typedef tvec2<bool> bool_type;
+
+ //////////////////////////////////////
+ // Data
+
+ thalf x, y;
+
+ //////////////////////////////////////
+ // Accesses
+
+ thalf & operator[](size_type i);
+ thalf const & operator[](size_type i) const;
+
+ //////////////////////////////////////
+ // Implicit basic constructors
+
+ tvec2();
+ tvec2(tvec2<thalf> const & v);
+
+ //////////////////////////////////////
+ // Explicit basic constructors
+
+ explicit tvec2(ctor);
+ explicit tvec2(
+ thalf const & s);
+ explicit tvec2(
+ thalf const & s1,
+ thalf const & s2);
+
+ //////////////////////////////////////
+ // Swizzle constructors
+
+ tvec2(tref2<thalf> const & r);
+
+ //////////////////////////////////////
+ // Convertion scalar constructors
+
+ //! Explicit converions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
+ template <typename U>
+ explicit tvec2(U const & x);
+ //! Explicit converions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
+ template <typename U, typename V>
+ explicit tvec2(U const & x, V const & y);
+
+ //////////////////////////////////////
+ // Convertion vector constructors
+
+ //! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
+ template <typename U>
+ explicit tvec2(tvec2<U> const & v);
+ //! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
+ template <typename U>
+ explicit tvec2(tvec3<U> const & v);
+ //! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
+ template <typename U>
+ explicit tvec2(tvec4<U> const & v);
+
+ //////////////////////////////////////
+ // Unary arithmetic operators
+
+ tvec2<thalf>& operator= (tvec2<thalf> const & v);
+
+ tvec2<thalf>& operator+=(thalf const & s);
+ tvec2<thalf>& operator+=(tvec2<thalf> const & v);
+ tvec2<thalf>& operator-=(thalf const & s);
+ tvec2<thalf>& operator-=(tvec2<thalf> const & v);
+ tvec2<thalf>& operator*=(thalf const & s);
+ tvec2<thalf>& operator*=(tvec2<thalf> const & v);
+ tvec2<thalf>& operator/=(thalf const & s);
+ tvec2<thalf>& operator/=(tvec2<thalf> const & v);
+ tvec2<thalf>& operator++();
+ tvec2<thalf>& operator--();
+
+ //////////////////////////////////////
+ // Swizzle operators
+
+ thalf swizzle(comp X) const;
+ tvec2<thalf> swizzle(comp X, comp Y) const;
+ tvec3<thalf> swizzle(comp X, comp Y, comp Z) const;
+ tvec4<thalf> swizzle(comp X, comp Y, comp Z, comp W) const;
+ tref2<thalf> swizzle(comp X, comp Y);
+ };
+
+ template <>
+ struct tvec3<thalf>
+ {
+ enum ctor{null};
+ typedef thalf value_type;
+ typedef std::size_t size_type;
+ static size_type value_size();
+
+ typedef tvec3<thalf> type;
+ typedef tvec3<bool> bool_type;
+
+ //////////////////////////////////////
+ // Data
+
+ thalf x, y, z;
+
+ //////////////////////////////////////
+ // Accesses
+
+ thalf & operator[](size_type i);
+ thalf const & operator[](size_type i) const;
+
+ //////////////////////////////////////
+ // Implicit basic constructors
+
+ tvec3();
+ tvec3(tvec3<thalf> const & v);
+
+ //////////////////////////////////////
+ // Explicit basic constructors
+
+ explicit tvec3(ctor);
+ explicit tvec3(
+ thalf const & s);
+ explicit tvec3(
+ thalf const & s1,
+ thalf const & s2,
+ thalf const & s3);
+
+ //////////////////////////////////////
+ // Swizzle constructors
+
+ tvec3(tref3<thalf> const & r);
+
+ //////////////////////////////////////
+ // Convertion scalar constructors
+
+ //! Explicit converions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
+ template <typename U>
+ explicit tvec3(U const & x);
+ //! Explicit converions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
+ template <typename U, typename V, typename W>
+ explicit tvec3(U const & x, V const & y, W const & z);
+
+ //////////////////////////////////////
+ // Convertion vector constructors
+
+ //! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
+ template <typename A, typename B>
+ explicit tvec3(tvec2<A> const & v, B const & s);
+ //! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
+ template <typename A, typename B>
+ explicit tvec3(A const & s, tvec2<B> const & v);
+ //! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
+ template <typename U>
+ explicit tvec3(tvec3<U> const & v);
+ //! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
+ template <typename U>
+ explicit tvec3(tvec4<U> const & v);
+
+ //////////////////////////////////////
+ // Unary arithmetic operators
+
+ tvec3<thalf>& operator= (tvec3<thalf> const & v);
+
+ tvec3<thalf>& operator+=(thalf const & s);
+ tvec3<thalf>& operator+=(tvec3<thalf> const & v);
+ tvec3<thalf>& operator-=(thalf const & s);
+ tvec3<thalf>& operator-=(tvec3<thalf> const & v);
+ tvec3<thalf>& operator*=(thalf const & s);
+ tvec3<thalf>& operator*=(tvec3<thalf> const & v);
+ tvec3<thalf>& operator/=(thalf const & s);
+ tvec3<thalf>& operator/=(tvec3<thalf> const & v);
+ tvec3<thalf>& operator++();
+ tvec3<thalf>& operator--();
+
+ //////////////////////////////////////
+ // Swizzle operators
+
+ thalf swizzle(comp X) const;
+ tvec2<thalf> swizzle(comp X, comp Y) const;
+ tvec3<thalf> swizzle(comp X, comp Y, comp Z) const;
+ tvec4<thalf> swizzle(comp X, comp Y, comp Z, comp W) const;
+ tref3<thalf> swizzle(comp X, comp Y, comp Z);
+ };
+
+ template <>
+ struct tvec4<thalf>
+ {
+ enum ctor{null};
+ typedef thalf value_type;
+ typedef std::size_t size_type;
+ static size_type value_size();
+
+ typedef tvec4<thalf> type;
+ typedef tvec4<bool> bool_type;
+
+ //////////////////////////////////////
+ // Data
+
+ thalf x, y, z, w;
+
+ //////////////////////////////////////
+ // Accesses
+
+ thalf & operator[](size_type i);
+ thalf const & operator[](size_type i) const;
+
+ //////////////////////////////////////
+ // Implicit basic constructors
+
+ tvec4();
+ tvec4(tvec4<thalf> const & v);
+
+ //////////////////////////////////////
+ // Explicit basic constructors
+
+ explicit tvec4(ctor);
+ explicit tvec4(
+ thalf const & s);
+ explicit tvec4(
+ thalf const & s0,
+ thalf const & s1,
+ thalf const & s2,
+ thalf const & s3);
+
+ //////////////////////////////////////
+ // Swizzle constructors
+
+ tvec4(tref4<thalf> const & r);
+
+ //////////////////////////////////////
+ // Convertion scalar constructors
+
+ //! Explicit converions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
+ template <typename U>
+ explicit tvec4(U const & x);
+ //! Explicit converions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
+ template <typename A, typename B, typename C, typename D>
+ explicit tvec4(A const & x, B const & y, C const & z, D const & w);
+
+ //////////////////////////////////////
+ // Convertion vector constructors
+
+ //! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
+ template <typename A, typename B, typename C>
+ explicit tvec4(tvec2<A> const & v, B const & s1, C const & s2);
+ //! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
+ template <typename A, typename B, typename C>
+ explicit tvec4(A const & s1, tvec2<B> const & v, C const & s2);
+ //! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
+ template <typename A, typename B, typename C>
+ explicit tvec4(A const & s1, B const & s2, tvec2<C> const & v);
+ //! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
+ template <typename A, typename B>
+ explicit tvec4(tvec3<A> const & v, B const & s);
+ //! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
+ template <typename A, typename B>
+ explicit tvec4(A const & s, tvec3<B> const & v);
+ //! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
+ template <typename A, typename B>
+ explicit tvec4(tvec2<A> const & v1, tvec2<B> const & v2);
+ //! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
+ template <typename U>
+ explicit tvec4(tvec4<U> const & v);
+
+ //////////////////////////////////////
+ // Unary arithmetic operators
+
+ tvec4<thalf>& operator= (tvec4<thalf> const & v);
+
+ tvec4<thalf>& operator+=(thalf const & s);
+ tvec4<thalf>& operator+=(tvec4<thalf> const & v);
+ tvec4<thalf>& operator-=(thalf const & s);
+ tvec4<thalf>& operator-=(tvec4<thalf> const & v);
+ tvec4<thalf>& operator*=(thalf const & s);
+ tvec4<thalf>& operator*=(tvec4<thalf> const & v);
+ tvec4<thalf>& operator/=(thalf const & s);
+ tvec4<thalf>& operator/=(tvec4<thalf> const & v);
+ tvec4<thalf>& operator++();
+ tvec4<thalf>& operator--();
+
+ //////////////////////////////////////
+ // Swizzle operators
+
+ thalf swizzle(comp X) const;
+ tvec2<thalf> swizzle(comp X, comp Y) const;
+ tvec3<thalf> swizzle(comp X, comp Y, comp Z) const;
+ tvec4<thalf> swizzle(comp X, comp Y, comp Z, comp W) const;
+ tref4<thalf> swizzle(comp X, comp Y, comp Z, comp W);
+ };
+#endif//_MSC_EXTENSIONS
+}
+//namespace detail
+
+namespace gtc{
+namespace half_float ///< GLM_GTC_half_float extension: Add support for half precision floating-point types
+{
+ /// \addtogroup gtc_half_float
+ ///@{
+
+ /// Type for half-precision floating-point numbers.
+ /// From GLM_GTC_half_float extension.
+ typedef detail::thalf half;
+
+ /// Vector of 2 half-precision floating-point numbers.
+ /// From GLM_GTC_half_float extension.
+ typedef detail::tvec2<detail::thalf> hvec2;
+
+ /// Vector of 3 half-precision floating-point numbers.
+ /// From GLM_GTC_half_float extension.
+ typedef detail::tvec3<detail::thalf> hvec3;
+
+ /// Vector of 4 half-precision floating-point numbers.
+ /// From GLM_GTC_half_float extension.
+ typedef detail::tvec4<detail::thalf> hvec4;
+
+ /// 2 * 2 matrix of half-precision floating-point numbers.
+ /// From GLM_GTC_half_float extension.
+ typedef detail::tmat2x2<detail::thalf> hmat2;
+
+ /// 3 * 3 matrix of half-precision floating-point numbers.
+ /// From GLM_GTC_half_float extension.
+ typedef detail::tmat3x3<detail::thalf> hmat3;
+
+ /// 4 * 4 matrix of half-precision floating-point numbers.
+ /// From GLM_GTC_half_float extension.
+ typedef detail::tmat4x4<detail::thalf> hmat4;
+
+ /// 2 * 2 matrix of half-precision floating-point numbers.
+ /// From GLM_GTC_half_float extension.
+ typedef detail::tmat2x2<detail::thalf> hmat2x2;
+
+ /// 2 * 3 matrix of half-precision floating-point numbers.
+ /// From GLM_GTC_half_float extension.
+ typedef detail::tmat2x3<detail::thalf> hmat2x3;
+
+ /// 2 * 4 matrix of half-precision floating-point numbers.
+ /// From GLM_GTC_half_float extension.
+ typedef detail::tmat2x4<detail::thalf> hmat2x4;
+
+ /// 3 * 2 matrix of half-precision floating-point numbers.
+ /// From GLM_GTC_half_float extension.
+ typedef detail::tmat3x2<detail::thalf> hmat3x2;
+
+ /// 3 * 3 matrix of half-precision floating-point numbers.
+ /// From GLM_GTC_half_float extension.
+ typedef detail::tmat3x3<detail::thalf> hmat3x3;
+
+ /// 3 * 4 matrix of half-precision floating-point numbers.
+ /// From GLM_GTC_half_float extension.
+ typedef detail::tmat3x4<detail::thalf> hmat3x4;
+
+ /// 4 * 2 matrix of half-precision floating-point numbers.
+ /// From GLM_GTC_half_float extension.
+ typedef detail::tmat4x2<detail::thalf> hmat4x2;
+
+ /// 4 * 3 matrix of half-precision floating-point numbers.
+ /// From GLM_GTC_half_float extension.
+ typedef detail::tmat4x3<detail::thalf> hmat4x3;
+
+ /// 4 * 4 matrix of half-precision floating-point numbers.
+ /// From GLM_GTC_half_float extension.
+ typedef detail::tmat4x4<detail::thalf> hmat4x4;
+
+ /// @}
+
+}// namespace half_float
+}// namespace gtc
+}// namespace glm
+
+#include "half_float.inl"
+
+namespace glm{using namespace gtc::half_float;}
+
+#endif//glm_gtc_half_float
diff --git a/src/glm/gtc/half_float.inl b/src/glm/gtc/half_float.inl
new file mode 100644
index 0000000..46171d0
--- /dev/null
+++ b/src/glm/gtc/half_float.inl
@@ -0,0 +1,975 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2005-12-21
+// Updated : 2010-02-07
+// Licence : This source is under MIT licence
+// File : glm/gtc/half_float.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm{
+namespace detail{
+
+#ifndef _MSC_EXTENSIONS
+
+//////////////////////////////////////
+// hvec2
+
+GLM_FUNC_QUALIFIER tvec2<thalf>::size_type tvec2<thalf>::value_size()
+{
+ return 2;
+}
+
+//////////////////////////////////////
+// Accesses
+
+GLM_FUNC_QUALIFIER thalf & tvec2<thalf>::operator[](tvec2<thalf>::size_type i)
+{
+ assert(/*i >= tvec2<thalf>::size_type(0) && */i < tvec2<thalf>::value_size());
+ return (&x)[i];
+}
+
+GLM_FUNC_QUALIFIER thalf const & tvec2<thalf>::operator[](tvec2<thalf>::size_type i) const
+{
+ assert(/*i >= tvec2<thalf>::size_type(0) && */i < tvec2<thalf>::value_size());
+ return (&x)[i];
+}
+
+//////////////////////////////////////
+// Implicit basic constructors
+
+GLM_FUNC_QUALIFIER tvec2<thalf>::tvec2() :
+ x(thalf(0.f)),
+ y(thalf(0.f))
+{}
+
+GLM_FUNC_QUALIFIER tvec2<thalf>::tvec2
+(
+ tvec2<thalf> const & v
+) :
+ x(v.x),
+ y(v.y)
+{}
+
+//////////////////////////////////////
+// Explicit basic constructors
+
+GLM_FUNC_QUALIFIER tvec2<thalf>::tvec2
+(
+ thalf const & s
+) :
+ x(s),
+ y(s)
+{}
+
+GLM_FUNC_QUALIFIER tvec2<thalf>::tvec2
+(
+ thalf const & s1,
+ thalf const & s2
+) :
+ x(s1),
+ y(s2)
+{}
+
+//////////////////////////////////////
+// Swizzle constructors
+
+GLM_FUNC_QUALIFIER tvec2<thalf>::tvec2
+(
+ tref2<thalf> const & r
+) :
+ x(r.x),
+ y(r.y)
+{}
+
+//////////////////////////////////////
+// Convertion scalar constructors
+
+template <typename U>
+GLM_FUNC_QUALIFIER tvec2<thalf>::tvec2
+(
+ U const & x
+) :
+ x(thalf(x)),
+ y(thalf(x))
+{}
+
+template <typename U, typename V>
+GLM_FUNC_QUALIFIER tvec2<thalf>::tvec2
+(
+ U const & x,
+ V const & y
+) :
+ x(thalf(x)),
+ y(thalf(y))
+{}
+
+//////////////////////////////////////
+// Convertion vector constructors
+
+template <typename U>
+GLM_FUNC_QUALIFIER tvec2<thalf>::tvec2
+(
+ tvec2<U> const & v
+) :
+ x(thalf(v.x)),
+ y(thalf(v.y))
+{}
+
+template <typename U>
+GLM_FUNC_QUALIFIER tvec2<thalf>::tvec2
+(
+ tvec3<U> const & v
+) :
+ x(thalf(v.x)),
+ y(thalf(v.y))
+{}
+
+template <typename U>
+GLM_FUNC_QUALIFIER tvec2<thalf>::tvec2
+(
+ tvec4<U> const & v
+) :
+ x(thalf(v.x)),
+ y(thalf(v.y))
+{}
+
+//////////////////////////////////////
+// Unary arithmetic operators
+
+GLM_FUNC_QUALIFIER tvec2<thalf> & tvec2<thalf>::operator=
+(
+ tvec2<thalf> const & v
+)
+{
+ this->x = v.x;
+ this->y = v.y;
+ return *this;
+}
+
+GLM_FUNC_QUALIFIER tvec2<thalf> & tvec2<thalf>::operator+=
+(
+ thalf const & s
+)
+{
+ this->x += s;
+ this->y += s;
+ return *this;
+}
+
+GLM_FUNC_QUALIFIER tvec2<thalf> & tvec2<thalf>::operator+=
+(
+ tvec2<thalf> const & v
+)
+{
+ this->x += v.x;
+ this->y += v.y;
+ return *this;
+}
+
+GLM_FUNC_QUALIFIER tvec2<thalf> & tvec2<thalf>::operator-=
+(
+ thalf const & s
+)
+{
+ this->x -= s;
+ this->y -= s;
+ return *this;
+}
+
+GLM_FUNC_QUALIFIER tvec2<thalf> & tvec2<thalf>::operator-=
+(
+ tvec2<thalf> const & v
+)
+{
+ this->x -= v.x;
+ this->y -= v.y;
+ return *this;
+}
+
+GLM_FUNC_QUALIFIER tvec2<thalf>& tvec2<thalf>::operator*=
+(
+ thalf const & s
+)
+{
+ this->x *= s;
+ this->y *= s;
+ return *this;
+}
+
+GLM_FUNC_QUALIFIER tvec2<thalf> & tvec2<thalf>::operator*=
+(
+ tvec2<thalf> const & v
+)
+{
+ this->x *= v.x;
+ this->y *= v.y;
+ return *this;
+}
+
+GLM_FUNC_QUALIFIER tvec2<thalf> & tvec2<thalf>::operator/=
+(
+ thalf const & s
+)
+{
+ this->x /= s;
+ this->y /= s;
+ return *this;
+}
+
+GLM_FUNC_QUALIFIER tvec2<thalf> & tvec2<thalf>::operator/=
+(
+ tvec2<thalf> const & v
+)
+{
+ this->x /= v.x;
+ this->y /= v.y;
+ return *this;
+}
+
+GLM_FUNC_QUALIFIER tvec2<thalf> & tvec2<thalf>::operator++()
+{
+ ++this->x;
+ ++this->y;
+ return *this;
+}
+
+GLM_FUNC_QUALIFIER tvec2<thalf>& tvec2<thalf>::operator--()
+{
+ --this->x;
+ --this->y;
+ return *this;
+}
+
+//////////////////////////////////////
+// Swizzle operators
+
+GLM_FUNC_QUALIFIER thalf tvec2<thalf>::swizzle(comp x) const
+{
+ return (*this)[x];
+}
+
+GLM_FUNC_QUALIFIER tvec2<thalf> tvec2<thalf>::swizzle(comp x, comp y) const
+{
+ return tvec2<thalf>(
+ (*this)[x],
+ (*this)[y]);
+}
+
+GLM_FUNC_QUALIFIER tvec3<thalf> tvec2<thalf>::swizzle(comp x, comp y, comp z) const
+{
+ return tvec3<thalf>(
+ (*this)[x],
+ (*this)[y],
+ (*this)[z]);
+}
+
+GLM_FUNC_QUALIFIER tvec4<thalf> tvec2<thalf>::swizzle(comp x, comp y, comp z, comp w) const
+{
+ return tvec4<thalf>(
+ (*this)[x],
+ (*this)[y],
+ (*this)[z],
+ (*this)[w]);
+}
+
+GLM_FUNC_QUALIFIER tref2<thalf> tvec2<thalf>::swizzle(comp x, comp y)
+{
+ return tref2<thalf>(
+ (*this)[x],
+ (*this)[y]);
+}
+
+//////////////////////////////////////
+// hvec3
+
+GLM_FUNC_QUALIFIER tvec3<thalf>::size_type tvec3<thalf>::value_size()
+{
+ return 3;
+}
+
+//////////////////////////////////////
+// Accesses
+
+GLM_FUNC_QUALIFIER thalf & tvec3<thalf>::operator[]
+(
+ tvec3<thalf>::size_type i
+)
+{
+ assert(/*i >= tvec3<thalf>::size_type(0) &&*/ i < tvec3<thalf>::value_size());
+
+ return (&x)[i];
+}
+
+GLM_FUNC_QUALIFIER thalf const & tvec3<thalf>::operator[]
+(
+ tvec3<thalf>::size_type i
+) const
+{
+ assert(/*i >= tvec3<thalf>::size_type(0) &&*/ i < tvec3<thalf>::value_size());
+
+ return (&x)[i];
+}
+
+//////////////////////////////////////
+// Implicit basic constructors
+
+GLM_FUNC_QUALIFIER tvec3<thalf>::tvec3() :
+ x(thalf(0)),
+ y(thalf(0)),
+ z(thalf(0))
+{}
+
+GLM_FUNC_QUALIFIER tvec3<thalf>::tvec3
+(
+ tvec3<thalf> const & v
+) :
+ x(v.x),
+ y(v.y),
+ z(v.z)
+{}
+
+//////////////////////////////////////
+// Explicit basic constructors
+
+GLM_FUNC_QUALIFIER tvec3<thalf>::tvec3
+(
+ thalf const & s
+) :
+ x(s),
+ y(s),
+ z(s)
+{}
+
+GLM_FUNC_QUALIFIER tvec3<thalf>::tvec3
+(
+ thalf const & s0,
+ thalf const & s1,
+ thalf const & s2
+) :
+ x(s0),
+ y(s1),
+ z(s2)
+{}
+
+//////////////////////////////////////
+// Swizzle constructors
+
+GLM_FUNC_QUALIFIER tvec3<thalf>::tvec3
+(
+ tref3<thalf> const & r
+) :
+ x(r.x),
+ y(r.y),
+ z(r.z)
+{}
+
+//////////////////////////////////////
+// Convertion scalar constructors
+
+template <typename U>
+GLM_FUNC_QUALIFIER tvec3<thalf>::tvec3
+(
+ U const & x
+) :
+ x(thalf(x)),
+ y(thalf(x)),
+ z(thalf(x))
+{}
+
+template <typename A, typename B, typename C>
+GLM_FUNC_QUALIFIER tvec3<thalf>::tvec3
+(
+ A const & x,
+ B const & y,
+ C const & z
+) :
+ x(thalf(x)),
+ y(thalf(y)),
+ z(thalf(z))
+{}
+
+//////////////////////////////////////
+// Convertion vector constructors
+
+template <typename A, typename B>
+GLM_FUNC_QUALIFIER tvec3<thalf>::tvec3
+(
+ tvec2<A> const & v,
+ B const & s
+) :
+ x(thalf(v.x)),
+ y(thalf(v.y)),
+ z(thalf(s))
+{}
+
+template <typename A, typename B>
+GLM_FUNC_QUALIFIER tvec3<thalf>::tvec3
+(
+ A const & s,
+ tvec2<B> const & v
+) :
+ x(thalf(s)),
+ y(thalf(v.x)),
+ z(thalf(v.y))
+{}
+
+template <typename U>
+GLM_FUNC_QUALIFIER tvec3<thalf>::tvec3
+(
+ tvec3<U> const & v
+) :
+ x(thalf(v.x)),
+ y(thalf(v.y)),
+ z(thalf(v.z))
+{}
+
+template <typename U>
+GLM_FUNC_QUALIFIER tvec3<thalf>::tvec3
+(
+ tvec4<U> const & v
+) :
+ x(thalf(v.x)),
+ y(thalf(v.y)),
+ z(thalf(v.z))
+{}
+
+//////////////////////////////////////
+// Unary arithmetic operators
+
+GLM_FUNC_QUALIFIER tvec3<thalf> & tvec3<thalf>::operator=
+(
+ tvec3<thalf> const & v
+)
+{
+ this->x = v.x;
+ this->y = v.y;
+ this->z = v.z;
+ return *this;
+}
+
+GLM_FUNC_QUALIFIER tvec3<thalf> & tvec3<thalf>::operator+=
+(
+ thalf const & s
+)
+{
+ this->x += s;
+ this->y += s;
+ this->z += s;
+ return *this;
+}
+
+GLM_FUNC_QUALIFIER tvec3<thalf> & tvec3<thalf>::operator+=
+(
+ tvec3<thalf> const & v
+)
+{
+ this->x += v.x;
+ this->y += v.y;
+ this->z += v.z;
+ return *this;
+}
+
+GLM_FUNC_QUALIFIER tvec3<thalf> & tvec3<thalf>::operator-=
+(
+ thalf const & s
+)
+{
+ this->x -= s;
+ this->y -= s;
+ this->z -= s;
+ return *this;
+}
+
+GLM_FUNC_QUALIFIER tvec3<thalf> & tvec3<thalf>::operator-=
+(
+ tvec3<thalf> const & v
+)
+{
+ this->x -= v.x;
+ this->y -= v.y;
+ this->z -= v.z;
+ return *this;
+}
+
+GLM_FUNC_QUALIFIER tvec3<thalf> & tvec3<thalf>::operator*=
+(
+ thalf const & s
+)
+{
+ this->x *= s;
+ this->y *= s;
+ this->z *= s;
+ return *this;
+}
+
+GLM_FUNC_QUALIFIER tvec3<thalf> & tvec3<thalf>::operator*=
+(
+ tvec3<thalf> const & v
+)
+{
+ this->x *= v.x;
+ this->y *= v.y;
+ this->z *= v.z;
+ return *this;
+}
+
+GLM_FUNC_QUALIFIER tvec3<thalf> & tvec3<thalf>::operator/=
+(
+ thalf const & s
+)
+{
+ this->x /= s;
+ this->y /= s;
+ this->z /= s;
+ return *this;
+}
+
+GLM_FUNC_QUALIFIER tvec3<thalf> & tvec3<thalf>::operator/=
+(
+ tvec3<thalf> const & v
+)
+{
+ this->x /= v.x;
+ this->y /= v.y;
+ this->z /= v.z;
+ return *this;
+}
+
+GLM_FUNC_QUALIFIER tvec3<thalf> & tvec3<thalf>::operator++()
+{
+ ++this->x;
+ ++this->y;
+ ++this->z;
+ return *this;
+}
+
+GLM_FUNC_QUALIFIER tvec3<thalf> & tvec3<thalf>::operator--()
+{
+ --this->x;
+ --this->y;
+ --this->z;
+ return *this;
+}
+
+//////////////////////////////////////
+// Swizzle operators
+
+GLM_FUNC_QUALIFIER thalf tvec3<thalf>::swizzle(comp x) const
+{
+ return (*this)[x];
+}
+
+GLM_FUNC_QUALIFIER tvec2<thalf> tvec3<thalf>::swizzle(comp x, comp y) const
+{
+ return tvec2<thalf>(
+ (*this)[x],
+ (*this)[y]);
+}
+
+GLM_FUNC_QUALIFIER tvec3<thalf> tvec3<thalf>::swizzle(comp x, comp y, comp z) const
+{
+ return tvec3<thalf>(
+ (*this)[x],
+ (*this)[y],
+ (*this)[z]);
+}
+
+GLM_FUNC_QUALIFIER tvec4<thalf> tvec3<thalf>::swizzle(comp x, comp y, comp z, comp w) const
+{
+ return tvec4<thalf>(
+ (*this)[x],
+ (*this)[y],
+ (*this)[z],
+ (*this)[w]);
+}
+
+GLM_FUNC_QUALIFIER tref3<thalf> tvec3<thalf>::swizzle(comp x, comp y, comp z)
+{
+ return tref3<thalf>(
+ (*this)[x],
+ (*this)[y],
+ (*this)[z]);
+}
+
+//////////////////////////////////////
+// hvec4
+
+GLM_FUNC_QUALIFIER tvec4<thalf>::size_type tvec4<thalf>::value_size()
+{
+ return 4;
+}
+
+//////////////////////////////////////
+// Accesses
+
+GLM_FUNC_QUALIFIER thalf & tvec4<thalf>::operator[]
+(
+ tvec4<thalf>::size_type i
+)
+{
+ assert(/*i >= tvec4<thalf>::size_type(0) && */i < tvec4<thalf>::value_size());
+
+ return (&x)[i];
+}
+
+GLM_FUNC_QUALIFIER thalf const & tvec4<thalf>::operator[]
+(
+ tvec4<thalf>::size_type i
+) const
+{
+ assert(/*i >= tvec4<thalf>::size_type(0) && */i < tvec4<thalf>::value_size());
+
+ return (&x)[i];
+}
+
+//////////////////////////////////////
+// Implicit basic constructors
+
+GLM_FUNC_QUALIFIER tvec4<thalf>::tvec4() :
+ x(thalf(0)),
+ y(thalf(0)),
+ z(thalf(0)),
+ w(thalf(0))
+{}
+
+GLM_FUNC_QUALIFIER tvec4<thalf>::tvec4
+(
+ tvec4<thalf> const & v
+) :
+ x(v.x),
+ y(v.y),
+ z(v.z),
+ w(v.w)
+{}
+
+//////////////////////////////////////
+// Explicit basic constructors
+
+GLM_FUNC_QUALIFIER tvec4<thalf>::tvec4
+(
+ thalf const & s
+) :
+ x(s),
+ y(s),
+ z(s),
+ w(s)
+{}
+
+GLM_FUNC_QUALIFIER tvec4<thalf>::tvec4
+(
+ thalf const & s1,
+ thalf const & s2,
+ thalf const & s3,
+ thalf const & s4
+) :
+ x(s1),
+ y(s2),
+ z(s3),
+ w(s4)
+{}
+
+//////////////////////////////////////
+// Swizzle constructors
+
+GLM_FUNC_QUALIFIER tvec4<thalf>::tvec4
+(
+ tref4<thalf> const & r
+) :
+ x(r.x),
+ y(r.y),
+ z(r.z),
+ w(r.w)
+{}
+
+//////////////////////////////////////
+// Convertion scalar constructors
+
+template <typename U>
+GLM_FUNC_QUALIFIER tvec4<thalf>::tvec4
+(
+ U const & x
+) :
+ x(thalf(x)),
+ y(thalf(x)),
+ z(thalf(x)),
+ w(thalf(x))
+{}
+
+template <typename A, typename B, typename C, typename D>
+GLM_FUNC_QUALIFIER tvec4<thalf>::tvec4
+(
+ A const & x,
+ B const & y,
+ C const & z,
+ D const & w
+) :
+ x(thalf(x)),
+ y(thalf(y)),
+ z(thalf(z)),
+ w(thalf(w))
+{}
+
+//////////////////////////////////////
+// Convertion vector constructors
+
+template <typename A, typename B, typename C>
+GLM_FUNC_QUALIFIER tvec4<thalf>::tvec4
+(
+ tvec2<A> const & v,
+ B const & s1,
+ C const & s2
+) :
+ x(thalf(v.x)),
+ y(thalf(v.y)),
+ z(thalf(s1)),
+ w(thalf(s2))
+{}
+
+template <typename A, typename B, typename C>
+GLM_FUNC_QUALIFIER tvec4<thalf>::tvec4
+(
+ A const & s1,
+ tvec2<B> const & v,
+ C const & s2
+) :
+ x(thalf(s1)),
+ y(thalf(v.x)),
+ z(thalf(v.y)),
+ w(thalf(s2))
+{}
+
+template <typename A, typename B, typename C>
+GLM_FUNC_QUALIFIER tvec4<thalf>::tvec4
+(
+ A const & s1,
+ B const & s2,
+ tvec2<C> const & v
+) :
+ x(thalf(s1)),
+ y(thalf(s2)),
+ z(thalf(v.x)),
+ w(thalf(v.y))
+{}
+
+template <typename A, typename B>
+GLM_FUNC_QUALIFIER tvec4<thalf>::tvec4
+(
+ tvec3<A> const & v,
+ B const & s
+) :
+ x(thalf(v.x)),
+ y(thalf(v.y)),
+ z(thalf(v.z)),
+ w(thalf(s))
+{}
+
+template <typename A, typename B>
+GLM_FUNC_QUALIFIER tvec4<thalf>::tvec4
+(
+ A const & s,
+ tvec3<B> const & v
+) :
+ x(thalf(s)),
+ y(thalf(v.x)),
+ z(thalf(v.y)),
+ w(thalf(v.z))
+{}
+
+template <typename A, typename B>
+GLM_FUNC_QUALIFIER tvec4<thalf>::tvec4
+(
+ tvec2<A> const & v1,
+ tvec2<B> const & v2
+) :
+ x(thalf(v1.x)),
+ y(thalf(v1.y)),
+ z(thalf(v2.x)),
+ w(thalf(v2.y))
+{}
+
+template <typename U>
+GLM_FUNC_QUALIFIER tvec4<thalf>::tvec4
+(
+ tvec4<U> const & v
+) :
+ x(thalf(v.x)),
+ y(thalf(v.y)),
+ z(thalf(v.z)),
+ w(thalf(v.w))
+{}
+
+//////////////////////////////////////
+// Unary arithmetic operators
+
+GLM_FUNC_QUALIFIER tvec4<thalf>& tvec4<thalf>::operator=
+(
+ tvec4<thalf> const & v
+)
+{
+ this->x = v.x;
+ this->y = v.y;
+ this->z = v.z;
+ this->w = v.w;
+ return *this;
+}
+
+GLM_FUNC_QUALIFIER tvec4<thalf>& tvec4<thalf>::operator+=
+(
+ thalf const & s
+)
+{
+ this->x += s;
+ this->y += s;
+ this->z += s;
+ this->w += s;
+ return *this;
+}
+
+GLM_FUNC_QUALIFIER tvec4<thalf>& tvec4<thalf>::operator+=
+(
+ tvec4<thalf> const & v
+)
+{
+ this->x += v.x;
+ this->y += v.y;
+ this->z += v.z;
+ this->w += v.w;
+ return *this;
+}
+
+GLM_FUNC_QUALIFIER tvec4<thalf>& tvec4<thalf>::operator-=
+(
+ thalf const & s
+)
+{
+ this->x -= s;
+ this->y -= s;
+ this->z -= s;
+ this->w -= s;
+ return *this;
+}
+
+GLM_FUNC_QUALIFIER tvec4<thalf>& tvec4<thalf>::operator-=
+(
+ tvec4<thalf> const & v
+)
+{
+ this->x -= v.x;
+ this->y -= v.y;
+ this->z -= v.z;
+ this->w -= v.w;
+ return *this;
+}
+
+GLM_FUNC_QUALIFIER tvec4<thalf>& tvec4<thalf>::operator*=
+(
+ thalf const & s
+)
+{
+ this->x *= s;
+ this->y *= s;
+ this->z *= s;
+ this->w *= s;
+ return *this;
+}
+
+GLM_FUNC_QUALIFIER tvec4<thalf>& tvec4<thalf>::operator*=
+(
+ tvec4<thalf> const & v
+)
+{
+ this->x *= v.x;
+ this->y *= v.y;
+ this->z *= v.z;
+ this->w *= v.w;
+ return *this;
+}
+
+GLM_FUNC_QUALIFIER tvec4<thalf>& tvec4<thalf>::operator/=
+(
+ thalf const & s
+)
+{
+ this->x /= s;
+ this->y /= s;
+ this->z /= s;
+ this->w /= s;
+ return *this;
+}
+
+GLM_FUNC_QUALIFIER tvec4<thalf>& tvec4<thalf>::operator/=
+(
+ tvec4<thalf> const & v
+)
+{
+ this->x /= v.x;
+ this->y /= v.y;
+ this->z /= v.z;
+ this->w /= v.w;
+ return *this;
+}
+
+GLM_FUNC_QUALIFIER tvec4<thalf>& tvec4<thalf>::operator++()
+{
+ ++this->x;
+ ++this->y;
+ ++this->z;
+ ++this->w;
+ return *this;
+}
+
+GLM_FUNC_QUALIFIER tvec4<thalf>& tvec4<thalf>::operator--()
+{
+ --this->x;
+ --this->y;
+ --this->z;
+ --this->w;
+ return *this;
+}
+
+//////////////////////////////////////
+// Swizzle operators
+
+GLM_FUNC_QUALIFIER thalf tvec4<thalf>::swizzle(comp x) const
+{
+ return (*this)[x];
+}
+
+GLM_FUNC_QUALIFIER tvec2<thalf> tvec4<thalf>::swizzle(comp x, comp y) const
+{
+ return tvec2<thalf>(
+ (*this)[x],
+ (*this)[y]);
+}
+
+GLM_FUNC_QUALIFIER tvec3<thalf> tvec4<thalf>::swizzle(comp x, comp y, comp z) const
+{
+ return tvec3<thalf>(
+ (*this)[x],
+ (*this)[y],
+ (*this)[z]);
+}
+
+GLM_FUNC_QUALIFIER tvec4<thalf> tvec4<thalf>::swizzle(comp x, comp y, comp z, comp w) const
+{
+ return tvec4<thalf>(
+ (*this)[x],
+ (*this)[y],
+ (*this)[z],
+ (*this)[w]);
+}
+
+GLM_FUNC_QUALIFIER tref4<thalf> tvec4<thalf>::swizzle(comp x, comp y, comp z, comp w)
+{
+ return tref4<thalf>(
+ (*this)[x],
+ (*this)[y],
+ (*this)[z],
+ (*this)[w]);
+}
+
+#endif//_MSC_EXTENSIONS
+
+}//namespace detail
+}//namespace glm
diff --git a/src/glm/gtc/matrix_access.hpp b/src/glm/gtc/matrix_access.hpp
new file mode 100644
index 0000000..d01e5e1
--- /dev/null
+++ b/src/glm/gtc/matrix_access.hpp
@@ -0,0 +1,70 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2005-12-27
+// Updated : 2010-11-12
+// Licence : This source is under MIT License
+// File : glm/gtc/matrix_access.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_gtc_matrix_access
+#define glm_gtc_matrix_access
+
+// Dependency:
+#include "../glm.hpp"
+
+#if(defined(GLM_MESSAGES) && !defined(glm_ext))
+# pragma message("GLM: GLM_GTC_matrix_access extension included")
+#endif
+
+namespace glm{
+namespace gtc{
+namespace matrix_access ///< GLM_GTC_matrix_access extension: Set a column or a row of a matrix
+{
+ /// \addtogroup gtc_matrix_access
+ ///@{
+
+ //! Get a specific row of a matrix.
+ //! From GLM_GTC_matrix_access extension.
+ template <typename genType>
+ typename genType::row_type row(
+ genType const & m,
+ int index);
+
+ //! Set a specific row to a matrix.
+ //! From GLM_GTC_matrix_access extension.
+ template <typename genType>
+ genType row(
+ genType const & m,
+ int index,
+ typename genType::row_type const & x);
+
+ //! Get a specific column of a matrix.
+ //! From GLM_GTC_matrix_access extension.
+ template <typename genType>
+ typename genType::col_type column(
+ genType const & m,
+ int index);
+
+ //! Set a specific column to a matrix.
+ //! From GLM_GTC_matrix_access extension.
+ template <typename genType>
+ genType column(
+ genType const & m,
+ int index,
+ typename genType::col_type const & x);
+
+ ///@}
+
+}//namespace matrix_access
+}//namespace gtc
+}//namespace glm
+
+#include "matrix_access.inl"
+
+namespace glm{using namespace gtc::matrix_access;}
+
+#endif//glm_gtc_matrix_access
diff --git a/src/glm/gtc/matrix_access.inl b/src/glm/gtc/matrix_access.inl
new file mode 100644
index 0000000..a53ef91
--- /dev/null
+++ b/src/glm/gtc/matrix_access.inl
@@ -0,0 +1,59 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2005-12-27
+// Updated : 2010-11-12
+// Licence : This source is under MIT License
+// File : glm/gtc/matrix_access.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm{
+namespace gtc{
+namespace matrix_access
+{
+ template <typename genType>
+ GLM_FUNC_QUALIFIER genType row(
+ genType const & m,
+ int index,
+ typename genType::row_type const & x)
+ {
+ genType Result = m;
+ for(typename genType::size_type i = 0; i < genType::row_size(); ++i)
+ Result[i][index] = x[i];
+ return Result;
+ }
+
+ template <typename genType>
+ GLM_FUNC_QUALIFIER typename genType::row_type row(
+ genType const & m,
+ int index)
+ {
+ typename genType::row_type Result;
+ for(typename genType::size_type i = 0; i < genType::row_size(); ++i)
+ Result[i] = m[i][index];
+ return Result;
+ }
+
+ template <typename genType>
+ GLM_FUNC_QUALIFIER genType column(
+ genType const & m,
+ int index,
+ typename genType::col_type const & x)
+ {
+ genType Result = m;
+ Result[index] = x;
+ return Result;
+ }
+
+ template <typename genType>
+ GLM_FUNC_QUALIFIER typename genType::col_type column(
+ genType const & m,
+ int index)
+ {
+ return m[index];
+ }
+
+}//namespace matrix_access
+}//namespace gtc
+}//namespace glm
+
diff --git a/src/glm/gtc/matrix_integer.hpp b/src/glm/gtc/matrix_integer.hpp
new file mode 100644
index 0000000..0e52b8f
--- /dev/null
+++ b/src/glm/gtc/matrix_integer.hpp
@@ -0,0 +1,204 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2011-01-20
+// Updated : 2011-01-20
+// Licence : This source is under MIT License
+// File : glm/gtc/matrix_integer.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_gtc_matrix_integer
+#define glm_gtc_matrix_integer
+
+// Dependency:
+#include "../glm.hpp"
+
+#if(defined(GLM_MESSAGES) && !defined(glm_ext))
+# pragma message("GLM: GLM_GTC_matrix_integer extension included")
+#endif
+
+namespace glm{
+namespace gtc{
+namespace matrix_integer ///< GLM_GTC_matrix_integer extension: Add integer matrices
+{
+ /// \addtogroup gtc_matrix_integer
+ ///@{
+
+ typedef detail::tmat2x2<highp_int> highp_imat2; //!< \brief High-precision signed integer 2x2 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef detail::tmat3x3<highp_int> highp_imat3; //!< \brief High-precision signed integer 3x3 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef detail::tmat4x4<highp_int> highp_imat4; //!< \brief High-precision signed integer 4x4 matrix. (from GLM_GTC_matrix_integer extension)
+
+ typedef detail::tmat2x2<highp_int> highp_imat2x2; //!< \brief High-precision signed integer 2x2 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef detail::tmat2x3<highp_int> highp_imat2x3; //!< \brief High-precision signed integer 2x3 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef detail::tmat2x4<highp_int> highp_imat2x4; //!< \brief High-precision signed integer 2x4 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef detail::tmat3x2<highp_int> highp_imat3x2; //!< \brief High-precision signed integer 3x2 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef detail::tmat3x3<highp_int> highp_imat3x3; //!< \brief High-precision signed integer 3x3 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef detail::tmat3x4<highp_int> highp_imat3x4; //!< \brief High-precision signed integer 3x4 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef detail::tmat4x2<highp_int> highp_imat4x2; //!< \brief High-precision signed integer 4x2 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef detail::tmat4x3<highp_int> highp_imat4x3; //!< \brief High-precision signed integer 4x3 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef detail::tmat4x4<highp_int> highp_imat4x4; //!< \brief High-precision signed integer 4x4 matrix. (from GLM_GTC_matrix_integer extension)
+
+ typedef detail::tmat2x2<mediump_int> mediump_imat2; //!< \brief Medium-precision signed integer 2x2 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef detail::tmat3x3<mediump_int> mediump_imat3; //!< \brief Medium-precision signed integer 3x3 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef detail::tmat4x4<mediump_int> mediump_imat4; //!< \brief Medium-precision signed integer 4x4 matrix. (from GLM_GTC_matrix_integer extension)
+
+ typedef detail::tmat2x2<mediump_int> mediump_imat2x2; //!< \brief Medium-precision signed integer 2x2 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef detail::tmat2x3<mediump_int> mediump_imat2x3; //!< \brief Medium-precision signed integer 2x3 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef detail::tmat2x4<mediump_int> mediump_imat2x4; //!< \brief Medium-precision signed integer 2x4 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef detail::tmat3x2<mediump_int> mediump_imat3x2; //!< \brief Medium-precision signed integer 3x2 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef detail::tmat3x3<mediump_int> mediump_imat3x3; //!< \brief Medium-precision signed integer 3x3 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef detail::tmat3x4<mediump_int> mediump_imat3x4; //!< \brief Medium-precision signed integer 3x4 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef detail::tmat4x2<mediump_int> mediump_imat4x2; //!< \brief Medium-precision signed integer 4x2 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef detail::tmat4x3<mediump_int> mediump_imat4x3; //!< \brief Medium-precision signed integer 4x3 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef detail::tmat4x4<mediump_int> mediump_imat4x4; //!< \brief Medium-precision signed integer 4x4 matrix. (from GLM_GTC_matrix_integer extension)
+
+ typedef detail::tmat2x2<lowp_int> lowp_imat2; //!< \brief Low-precision signed integer 2x2 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef detail::tmat3x3<lowp_int> lowp_imat3; //!< \brief Low-precision signed integer 3x3 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef detail::tmat4x4<lowp_int> lowp_imat4; //!< \brief Low-precision signed integer 4x4 matrix. (from GLM_GTC_matrix_integer extension)
+
+ typedef detail::tmat2x2<lowp_int> lowp_imat2x2; //!< \brief Low-precision signed integer 2x2 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef detail::tmat2x3<lowp_int> lowp_imat2x3; //!< \brief Low-precision signed integer 2x3 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef detail::tmat2x4<lowp_int> lowp_imat2x4; //!< \brief Low-precision signed integer 2x4 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef detail::tmat3x2<lowp_int> lowp_imat3x2; //!< \brief Low-precision signed integer 3x2 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef detail::tmat3x3<lowp_int> lowp_imat3x3; //!< \brief Low-precision signed integer 3x3 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef detail::tmat3x4<lowp_int> lowp_imat3x4; //!< \brief Low-precision signed integer 3x4 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef detail::tmat4x2<lowp_int> lowp_imat4x2; //!< \brief Low-precision signed integer 4x2 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef detail::tmat4x3<lowp_int> lowp_imat4x3; //!< \brief Low-precision signed integer 4x3 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef detail::tmat4x4<lowp_int> lowp_imat4x4; //!< \brief Low-precision signed integer 4x4 matrix. (from GLM_GTC_matrix_integer extension)
+
+ typedef detail::tmat2x2<highp_uint> highp_umat2; //!< \brief High-precision signed integer 2x2 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef detail::tmat3x3<highp_uint> highp_umat3; //!< \brief High-precision signed integer 3x3 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef detail::tmat4x4<highp_uint> highp_umat4; //!< \brief High-precision signed integer 4x4 matrix. (from GLM_GTC_matrix_integer extension)
+
+ typedef detail::tmat2x2<highp_uint> highp_umat2x2; //!< \brief High-precision signed integer 2x2 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef detail::tmat2x3<highp_uint> highp_umat2x3; //!< \brief High-precision signed integer 2x3 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef detail::tmat2x4<highp_uint> highp_umat2x4; //!< \brief High-precision signed integer 2x4 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef detail::tmat3x2<highp_uint> highp_umat3x2; //!< \brief High-precision signed integer 3x2 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef detail::tmat3x3<highp_uint> highp_umat3x3; //!< \brief High-precision signed integer 3x3 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef detail::tmat3x4<highp_uint> highp_umat3x4; //!< \brief High-precision signed integer 3x4 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef detail::tmat4x2<highp_uint> highp_umat4x2; //!< \brief High-precision signed integer 4x2 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef detail::tmat4x3<highp_uint> highp_umat4x3; //!< \brief High-precision signed integer 4x3 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef detail::tmat4x4<highp_uint> highp_umat4x4; //!< \brief High-precision signed integer 4x4 matrix. (from GLM_GTC_matrix_integer extension)
+
+ typedef detail::tmat2x2<mediump_uint> mediump_umat2; //!< \brief Medium-precision signed integer 2x2 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef detail::tmat3x3<mediump_uint> mediump_umat3; //!< \brief Medium-precision signed integer 3x3 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef detail::tmat4x4<mediump_uint> mediump_umat4; //!< \brief Medium-precision signed integer 4x4 matrix. (from GLM_GTC_matrix_integer extension)
+
+ typedef detail::tmat2x2<mediump_uint> mediump_umat2x2; //!< \brief Medium-precision signed integer 2x2 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef detail::tmat2x3<mediump_uint> mediump_umat2x3; //!< \brief Medium-precision signed integer 2x3 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef detail::tmat2x4<mediump_uint> mediump_umat2x4; //!< \brief Medium-precision signed integer 2x4 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef detail::tmat3x2<mediump_uint> mediump_umat3x2; //!< \brief Medium-precision signed integer 3x2 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef detail::tmat3x3<mediump_uint> mediump_umat3x3; //!< \brief Medium-precision signed integer 3x3 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef detail::tmat3x4<mediump_uint> mediump_umat3x4; //!< \brief Medium-precision signed integer 3x4 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef detail::tmat4x2<mediump_uint> mediump_umat4x2; //!< \brief Medium-precision signed integer 4x2 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef detail::tmat4x3<mediump_uint> mediump_umat4x3; //!< \brief Medium-precision signed integer 4x3 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef detail::tmat4x4<mediump_uint> mediump_umat4x4; //!< \brief Medium-precision signed integer 4x4 matrix. (from GLM_GTC_matrix_integer extension)
+
+ typedef detail::tmat2x2<lowp_uint> lowp_umat2; //!< \brief Low-precision signed integer 2x2 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef detail::tmat3x3<lowp_uint> lowp_umat3; //!< \brief Low-precision signed integer 3x3 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef detail::tmat4x4<lowp_uint> lowp_umat4; //!< \brief Low-precision signed integer 4x4 matrix. (from GLM_GTC_matrix_integer extension)
+
+ typedef detail::tmat2x2<lowp_uint> lowp_umat2x2; //!< \brief Low-precision signed integer 2x2 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef detail::tmat2x3<lowp_uint> lowp_umat2x3; //!< \brief Low-precision signed integer 2x3 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef detail::tmat2x4<lowp_uint> lowp_umat2x4; //!< \brief Low-precision signed integer 2x4 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef detail::tmat3x2<lowp_uint> lowp_umat3x2; //!< \brief Low-precision signed integer 3x2 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef detail::tmat3x3<lowp_uint> lowp_umat3x3; //!< \brief Low-precision signed integer 3x3 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef detail::tmat3x4<lowp_uint> lowp_umat3x4; //!< \brief Low-precision signed integer 3x4 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef detail::tmat4x2<lowp_uint> lowp_umat4x2; //!< \brief Low-precision signed integer 4x2 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef detail::tmat4x3<lowp_uint> lowp_umat4x3; //!< \brief Low-precision signed integer 4x3 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef detail::tmat4x4<lowp_uint> lowp_umat4x4; //!< \brief Low-precision signed integer 4x4 matrix. (from GLM_GTC_matrix_integer extension)
+
+#if(defined(GLM_PRECISION_HIGHP_INT))
+ typedef highp_imat2 imat2; //!< \brief Signed integer 2x2 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef highp_imat3 imat3; //!< \brief Signed integer 3x3 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef highp_imat4 imat4; //!< \brief Signed integer 4x4 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef highp_imat2x2 imat2x2; //!< \brief Signed integer 2x2 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef highp_imat2x3 imat2x3; //!< \brief Signed integer 2x3 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef highp_imat2x4 imat2x4; //!< \brief Signed integer 2x4 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef highp_imat3x2 imat3x2; //!< \brief Signed integer 3x2 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef highp_imat3x3 imat3x3; //!< \brief Signed integer 3x3 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef highp_imat3x4 imat3x4; //!< \brief Signed integer 3x4 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef highp_imat4x2 imat4x2; //!< \brief Signed integer 4x2 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef highp_imat4x3 imat4x3; //!< \brief Signed integer 4x3 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef highp_imat4x4 imat4x4; //!< \brief Signed integer 4x4 matrix. (from GLM_GTC_matrix_integer extension)
+#elif(defined(GLM_PRECISION_LOWP_INT))
+ typedef lowp_imat2 imat2; //!< \brief Signed integer 2x2 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef lowp_imat3 imat3; //!< \brief Signed integer 3x3 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef lowp_imat4 imat4; //!< \brief Signed integer 4x4 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef lowp_imat2x2 imat2x2; //!< \brief Signed integer 2x2 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef lowp_imat2x3 imat2x3; //!< \brief Signed integer 2x3 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef lowp_imat2x4 imat2x4; //!< \brief Signed integer 2x4 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef lowp_imat3x2 imat3x2; //!< \brief Signed integer 3x2 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef lowp_imat3x3 imat3x3; //!< \brief Signed integer 3x3 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef lowp_imat3x4 imat3x4; //!< \brief Signed integer 3x4 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef lowp_imat4x2 imat4x2; //!< \brief Signed integer 4x2 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef lowp_imat4x3 imat4x3; //!< \brief Signed integer 4x3 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef lowp_imat4x4 imat4x4; //!< \brief Signed integer 4x4 matrix. (from GLM_GTC_matrix_integer extension)
+#else //if(defined(GLM_PRECISION_MEDIUMP_INT))
+ typedef mediump_imat2 imat2; //!< \brief Signed integer 2x2 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef mediump_imat3 imat3; //!< \brief Signed integer 3x3 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef mediump_imat4 imat4; //!< \brief Signed integer 4x4 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef mediump_imat2x2 imat2x2; //!< \brief Signed integer 2x2 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef mediump_imat2x3 imat2x3; //!< \brief Signed integer 2x3 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef mediump_imat2x4 imat2x4; //!< \brief Signed integer 2x4 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef mediump_imat3x2 imat3x2; //!< \brief Signed integer 3x2 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef mediump_imat3x3 imat3x3; //!< \brief Signed integer 3x3 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef mediump_imat3x4 imat3x4; //!< \brief Signed integer 3x4 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef mediump_imat4x2 imat4x2; //!< \brief Signed integer 4x2 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef mediump_imat4x3 imat4x3; //!< \brief Signed integer 4x3 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef mediump_imat4x4 imat4x4; //!< \brief Signed integer 4x4 matrix. (from GLM_GTC_matrix_integer extension)
+#endif//GLM_PRECISION
+
+#if(defined(GLM_PRECISION_HIGHP_UINT))
+ typedef highp_umat2 umat2; //!< \brief Unsigned integer 2x2 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef highp_umat3 umat3; //!< \brief Unsigned integer 3x3 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef highp_umat4 umat4; //!< \brief Unsigned integer 4x4 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef highp_umat2x2 umat2x2; //!< \brief Unsigned integer 2x2 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef highp_umat2x3 umat2x3; //!< \brief Unsigned integer 2x3 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef highp_umat2x4 umat2x4; //!< \brief Unsigned integer 2x4 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef highp_umat3x2 umat3x2; //!< \brief Unsigned integer 3x2 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef highp_umat3x3 umat3x3; //!< \brief Unsigned integer 3x3 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef highp_umat3x4 umat3x4; //!< \brief Unsigned integer 3x4 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef highp_umat4x2 umat4x2; //!< \brief Unsigned integer 4x2 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef highp_umat4x3 umat4x3; //!< \brief Unsigned integer 4x3 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef highp_umat4x4 umat4x4; //!< \brief Unsigned integer 4x4 matrix. (from GLM_GTC_matrix_integer extension)
+#elif(defined(GLM_PRECISION_LOWP_UINT))
+ typedef lowp_umat2 umat2; //!< \brief Unsigned integer 2x2 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef lowp_umat3 umat3; //!< \brief Unsigned integer 3x3 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef lowp_umat4 umat4; //!< \brief Unsigned integer 4x4 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef lowp_umat2x2 umat2x2; //!< \brief Unsigned integer 2x2 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef lowp_umat2x3 umat2x3; //!< \brief Unsigned integer 2x3 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef lowp_umat2x4 umat2x4; //!< \brief Unsigned integer 2x4 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef lowp_umat3x2 umat3x2; //!< \brief Unsigned integer 3x2 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef lowp_umat3x3 umat3x3; //!< \brief Unsigned integer 3x3 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef lowp_umat3x4 umat3x4; //!< \brief Unsigned integer 3x4 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef lowp_umat4x2 umat4x2; //!< \brief Unsigned integer 4x2 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef lowp_umat4x3 umat4x3; //!< \brief Unsigned integer 4x3 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef lowp_umat4x4 umat4x4; //!< \brief Unsigned integer 4x4 matrix. (from GLM_GTC_matrix_integer extension)
+#else //if(defined(GLM_PRECISION_MEDIUMP_UINT))
+ typedef mediump_umat2 umat2; //!< \brief Unsigned integer 2x2 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef mediump_umat3 umat3; //!< \brief Unsigned integer 3x3 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef mediump_umat4 umat4; //!< \brief Unsigned integer 4x4 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef mediump_umat2x2 umat2x2; //!< \brief Unsigned integer 2x2 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef mediump_umat2x3 umat2x3; //!< \brief Unsigned integer 2x3 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef mediump_umat2x4 umat2x4; //!< \brief Unsigned integer 2x4 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef mediump_umat3x2 umat3x2; //!< \brief Unsigned integer 3x2 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef mediump_umat3x3 umat3x3; //!< \brief Unsigned integer 3x3 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef mediump_umat3x4 umat3x4; //!< \brief Unsigned integer 3x4 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef mediump_umat4x2 umat4x2; //!< \brief Unsigned integer 4x2 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef mediump_umat4x3 umat4x3; //!< \brief Unsigned integer 4x3 matrix. (from GLM_GTC_matrix_integer extension)
+ typedef mediump_umat4x4 umat4x4; //!< \brief Unsigned integer 4x4 matrix. (from GLM_GTC_matrix_integer extension)
+#endif//GLM_PRECISION
+
+ ///@}
+
+}//namespace matrix_integer
+}//namespace gtc
+}//namespace glm
+
+namespace glm{using namespace gtc::matrix_integer;}
+
+#endif//glm_gtc_matrix_integer
diff --git a/src/glm/gtc/matrix_inverse.hpp b/src/glm/gtc/matrix_inverse.hpp
new file mode 100644
index 0000000..4968128
--- /dev/null
+++ b/src/glm/gtc/matrix_inverse.hpp
@@ -0,0 +1,51 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2005-12-21
+// Updated : 2010-12-13
+// Licence : This source is under MIT License
+// File : glm/gtc/matrix_inverse.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_gtc_matrix_inverse
+#define glm_gtc_matrix_inverse
+
+// Dependency:
+#include "../glm.hpp"
+
+#if(defined(GLM_MESSAGES) && !defined(glm_ext))
+# pragma message("GLM: GLM_GTC_matrix_inverse extension included")
+#endif
+
+namespace glm{
+namespace gtc{
+namespace matrix_inverse ///< GLM_GTC_matrix_inverse extension: Inverse matrix functions
+{
+ /// \addtogroup gtc_matrix_inverse
+ ///@{
+
+ //! Fast matrix inverse for affine matrix.
+ //! From GLM_GTC_matrix_inverse extension.
+ template <typename genType>
+ genType affineInverse(genType const & m);
+
+ //! Compute the inverse transpose of a matrix.
+ //! From GLM_GTC_matrix_inverse extension.
+ template <typename genType>
+ GLM_FUNC_QUALIFIER typename genType::value_type inverseTranspose(
+ genType const & m);
+
+ ///@}
+
+}//namespace matrix_inverse
+}//namespace gtc
+}//namespace glm
+
+#include "matrix_inverse.inl"
+
+namespace glm{using namespace gtc::matrix_inverse;}
+
+#endif//glm_gtc_matrix_inverse
diff --git a/src/glm/gtc/matrix_inverse.inl b/src/glm/gtc/matrix_inverse.inl
new file mode 100644
index 0000000..50e10ec
--- /dev/null
+++ b/src/glm/gtc/matrix_inverse.inl
@@ -0,0 +1,139 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2005-12-21
+// Updated : 2010-12-13
+// Licence : This source is under MIT License
+// File : glm/gtc/matrix_inverse.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm{
+namespace gtc{
+namespace matrix_inverse
+{
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tmat3x3<T> affineInverse
+ (
+ detail::tmat3x3<T> const & m
+ )
+ {
+ detail::tmat3x3<T> Result(m);
+ Result[2] = detail::tvec3<T>(0, 0, 1);
+ Result = transpose(Result);
+ detail::tvec3<T> Translation = Result * detail::tvec3<T>(-detail::tvec2<T>(m[2]), m[2][2]);
+ Result[2] = Translation;
+ return Result;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tmat4x4<T> affineInverse
+ (
+ detail::tmat4x4<T> const & m
+ )
+ {
+ detail::tmat4x4<T> Result(m);
+ Result[3] = detail::tvec4<T>(0, 0, 0, 1);
+ Result = transpose(Result);
+ detail::tvec4<T> Translation = Result * detail::tvec4<T>(-detail::tvec3<T>(m[3]), m[3][3]);
+ Result[3] = Translation;
+ return Result;
+ }
+
+ template <typename valType>
+ GLM_FUNC_QUALIFIER detail::tmat2x2<valType> inverseTranspose(
+ detail::tmat2x2<valType> const & m)
+ {
+ valType Determinant = m[0][0] * m[1][1] - m[1][0] * m[0][1];
+
+ detail::tmat2x2<valType> Inverse(
+ + m[1][1] / Determinant,
+ - m[0][1] / Determinant,
+ - m[1][0] / Determinant,
+ + m[0][0] / Determinant);
+
+ return Inverse;
+ }
+
+ template <typename valType>
+ GLM_FUNC_QUALIFIER detail::tmat3x3<valType> inverseTranspose(
+ detail::tmat3x3<valType> const & m)
+ {
+ valType Determinant =
+ + m[0][0] * (m[1][1] * m[2][2] - m[1][2] * m[2][1])
+ - m[0][1] * (m[1][0] * m[2][2] - m[1][2] * m[2][0])
+ + m[0][2] * (m[1][0] * m[2][1] - m[1][1] * m[2][0]);
+
+ detail::tmat3x3<valType> Inverse;
+ Inverse[0][0] = + (m[1][1] * m[2][2] - m[2][1] * m[1][2]);
+ Inverse[0][1] = - (m[1][0] * m[2][2] - m[2][0] * m[1][2]);
+ Inverse[0][2] = + (m[1][0] * m[2][1] - m[2][0] * m[1][1]);
+ Inverse[1][0] = - (m[0][1] * m[2][2] - m[2][1] * m[0][2]);
+ Inverse[1][1] = + (m[0][0] * m[2][2] - m[2][0] * m[0][2]);
+ Inverse[1][2] = - (m[0][0] * m[2][1] - m[2][0] * m[0][1]);
+ Inverse[2][0] = + (m[0][1] * m[1][2] - m[1][1] * m[0][2]);
+ Inverse[2][1] = - (m[0][0] * m[1][2] - m[1][0] * m[0][2]);
+ Inverse[2][2] = + (m[0][0] * m[1][1] - m[1][0] * m[0][1]);
+ Inverse /= Determinant;
+
+ return Inverse;
+ }
+
+ template <typename valType>
+ GLM_FUNC_QUALIFIER detail::tmat4x4<valType> inverseTranspose(
+ detail::tmat4x4<valType> const & m)
+ {
+ valType SubFactor00 = m[2][2] * m[3][3] - m[3][2] * m[2][3];
+ valType SubFactor01 = m[2][1] * m[3][3] - m[3][1] * m[2][3];
+ valType SubFactor02 = m[2][1] * m[3][2] - m[3][1] * m[2][2];
+ valType SubFactor03 = m[2][0] * m[3][3] - m[3][0] * m[2][3];
+ valType SubFactor04 = m[2][0] * m[3][2] - m[3][0] * m[2][2];
+ valType SubFactor05 = m[2][0] * m[3][1] - m[3][0] * m[2][1];
+ valType SubFactor06 = m[1][2] * m[3][3] - m[3][2] * m[1][3];
+ valType SubFactor07 = m[1][1] * m[3][3] - m[3][1] * m[1][3];
+ valType SubFactor08 = m[1][1] * m[3][2] - m[3][1] * m[1][2];
+ valType SubFactor09 = m[1][0] * m[3][3] - m[3][0] * m[1][3];
+ valType SubFactor10 = m[1][0] * m[3][2] - m[3][0] * m[1][2];
+ valType SubFactor11 = m[1][1] * m[3][3] - m[3][1] * m[1][3];
+ valType SubFactor12 = m[1][0] * m[3][1] - m[3][0] * m[1][1];
+ valType SubFactor13 = m[1][2] * m[2][3] - m[2][2] * m[1][3];
+ valType SubFactor14 = m[1][1] * m[2][3] - m[2][1] * m[1][3];
+ valType SubFactor15 = m[1][1] * m[2][2] - m[2][1] * m[1][2];
+ valType SubFactor16 = m[1][0] * m[2][3] - m[2][0] * m[1][3];
+ valType SubFactor17 = m[1][0] * m[2][2] - m[2][0] * m[1][2];
+ valType SubFactor18 = m[1][0] * m[2][1] - m[2][0] * m[1][1];
+
+ detail::tmat4x4<valType> Inverse;
+ Inverse[0][0] = + (m[1][1] * SubFactor00 - m[1][2] * SubFactor01 + m[1][3] * SubFactor02);
+ Inverse[0][1] = - (m[1][0] * SubFactor00 - m[1][2] * SubFactor03 + m[1][3] * SubFactor04);
+ Inverse[0][2] = + (m[1][0] * SubFactor01 - m[1][1] * SubFactor03 + m[1][3] * SubFactor05);
+ Inverse[0][3] = - (m[1][0] * SubFactor02 - m[1][1] * SubFactor04 + m[1][2] * SubFactor05);
+
+ Inverse[1][0] = - (m[0][1] * SubFactor00 - m[0][2] * SubFactor01 + m[0][3] * SubFactor02);
+ Inverse[1][1] = + (m[0][0] * SubFactor00 - m[0][2] * SubFactor03 + m[0][3] * SubFactor04);
+ Inverse[1][2] = - (m[0][0] * SubFactor01 - m[0][1] * SubFactor03 + m[0][3] * SubFactor05);
+ Inverse[1][3] = + (m[0][0] * SubFactor02 - m[0][1] * SubFactor04 + m[0][2] * SubFactor05);
+
+ Inverse[2][0] = + (m[0][1] * SubFactor06 - m[0][2] * SubFactor07 + m[0][3] * SubFactor08);
+ Inverse[2][1] = - (m[0][0] * SubFactor06 - m[0][2] * SubFactor09 + m[0][3] * SubFactor10);
+ Inverse[2][2] = + (m[0][0] * SubFactor11 - m[0][1] * SubFactor09 + m[0][3] * SubFactor12);
+ Inverse[2][3] = - (m[0][0] * SubFactor08 - m[0][1] * SubFactor10 + m[0][2] * SubFactor12);
+
+ Inverse[3][0] = - (m[0][1] * SubFactor13 - m[0][2] * SubFactor14 + m[0][3] * SubFactor15);
+ Inverse[3][1] = + (m[0][0] * SubFactor13 - m[0][2] * SubFactor16 + m[0][3] * SubFactor17);
+ Inverse[3][2] = - (m[0][0] * SubFactor14 - m[0][1] * SubFactor16 + m[0][3] * SubFactor18);
+ Inverse[3][3] = + (m[0][0] * SubFactor15 - m[0][1] * SubFactor17 + m[0][2] * SubFactor18);
+
+ valType Determinant =
+ + m[0][0] * Inverse[0][0]
+ + m[0][1] * Inverse[0][1]
+ + m[0][2] * Inverse[0][2]
+ + m[0][3] * Inverse[0][3];
+
+ Inverse /= Determinant;
+
+ return Inverse;
+ }
+
+}//namespace matrix_inverse
+}//namespace gtc
+}//namespace glm
diff --git a/src/glm/gtc/matrix_transform.hpp b/src/glm/gtc/matrix_transform.hpp
new file mode 100644
index 0000000..ab1ce7f
--- /dev/null
+++ b/src/glm/gtc/matrix_transform.hpp
@@ -0,0 +1,158 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2009-04-29
+// Updated : 2009-04-29
+// Licence : This source is under MIT License
+// File : glm/gtc/matrix_transform.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+// - GLM_GTC_matrix_operation
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_gtc_matrix_transform
+#define glm_gtc_matrix_transform
+
+// Dependency:
+#include "../glm.hpp"
+
+#if(defined(GLM_MESSAGES) && !defined(glm_ext))
+# pragma message("GLM: GLM_GTC_matrix_transform extension included")
+#endif
+
+namespace glm{
+namespace gtc{
+namespace matrix_transform ///< GLM_GTC_matrix_transform extension: Add transformation matrices
+{
+ /// \addtogroup gtc_matrix_transform
+ ///@{
+
+ //! Builds a translation 4 * 4 matrix created from a vector of 3 components.
+ //! From GLM_GTC_matrix_transform extension.
+ template <typename T>
+ detail::tmat4x4<T> translate(
+ detail::tmat4x4<T> const & m,
+ detail::tvec3<T> const & v);
+
+ //! Builds a rotation 4 * 4 matrix created from an axis vector and an angle expressed in degrees.
+ //! From GLM_GTC_matrix_transform extension.
+ template <typename T>
+ detail::tmat4x4<T> rotate(
+ detail::tmat4x4<T> const & m,
+ T const & angle,
+ detail::tvec3<T> const & v);
+
+ //! Builds a scale 4 * 4 matrix created from 3 scalars.
+ //! From GLM_GTC_matrix_transform extension.
+ template <typename T>
+ detail::tmat4x4<T> scale(
+ detail::tmat4x4<T> const & m,
+ detail::tvec3<T> const & v);
+
+ //! Creates a matrix for an orthographic parallel viewing volume.
+ //! From GLM_GTC_matrix_transform extension.
+ template <typename T>
+ detail::tmat4x4<T> ortho(
+ T const & left,
+ T const & right,
+ T const & bottom,
+ T const & top,
+ T const & zNear,
+ T const & zFar);
+
+ //! Creates a matrix for projecting two-dimensional coordinates onto the screen.
+ //! From GLM_GTC_matrix_transform extension.
+ template <typename T>
+ detail::tmat4x4<T> ortho(
+ T const & left,
+ T const & right,
+ T const & bottom,
+ T const & top);
+
+ //! Creates a frustum matrix.
+ //! From GLM_GTC_matrix_transform extension.
+ template <typename T>
+ detail::tmat4x4<T> frustum(
+ T const & left,
+ T const & right,
+ T const & bottom,
+ T const & top,
+ T const & nearVal,
+ T const & farVal);
+
+ //! Creates a matrix for a symetric perspective-view frustum.
+ //! From GLM_GTC_matrix_transform extension.
+ template <typename T>
+ detail::tmat4x4<T> perspective(
+ T const & fovy,
+ T const & aspect,
+ T const & zNear,
+ T const & zFar);
+
+ //! Builds a perspective projection matrix based on a field of view
+ //! From GLM_GTC_matrix_transform extension.
+ template <typename valType>
+ detail::tmat4x4<valType> perspectiveFov(
+ valType const & fov,
+ valType const & width,
+ valType const & height,
+ valType const & zNear,
+ valType const & zFar);
+
+ //! Creates a matrix for a symmetric perspective-view frustum with far plane at infinite .
+ //! From GLM_GTC_matrix_transform extension.
+ template <typename T>
+ detail::tmat4x4<T> infinitePerspective(
+ T fovy, T aspect, T zNear);
+
+ //! Creates a matrix for a symmetric perspective-view frustum with far plane at infinite for graphics hardware that doesn't support depth clamping.
+ //! From GLM_GTC_matrix_transform extension.
+ template <typename T>
+ detail::tmat4x4<T> tweakedInfinitePerspective(
+ T fovy, T aspect, T zNear);
+
+ //! Map the specified object coordinates (obj.x, obj.y, obj.z) into window coordinates.
+ //! From GLM_GTC_matrix_transform extension.
+ template <typename T, typename U>
+ detail::tvec3<T> project(
+ detail::tvec3<T> const & obj,
+ detail::tmat4x4<T> const & model,
+ detail::tmat4x4<T> const & proj,
+ detail::tvec4<U> const & viewport);
+
+ //! Map the specified window coordinates (win.x, win.y, win.z) into object coordinates.
+ //! From GLM_GTC_matrix_transform extension.
+ template <typename T, typename U>
+ detail::tvec3<T> unProject(
+ detail::tvec3<T> const & win,
+ detail::tmat4x4<T> const & model,
+ detail::tmat4x4<T> const & proj,
+ detail::tvec4<U> const & viewport);
+
+ //! Define a picking region
+ //! From GLM_GTC_matrix_transform extension.
+ template <typename T, typename U>
+ detail::tmat4x4<T> pickMatrix(
+ detail::tvec2<T> const & center,
+ detail::tvec2<T> const & delta,
+ detail::tvec4<U> const & viewport);
+
+ //! Build a look at view matrix.
+ //! From GLM_GTC_matrix_transform extension.
+ template <typename T>
+ detail::tmat4x4<T> lookAt(
+ detail::tvec3<T> const & eye,
+ detail::tvec3<T> const & center,
+ detail::tvec3<T> const & up);
+
+ ///@}
+}//namespace matrix_transform
+}//namespace gtc
+}//namespace glm
+
+#include "matrix_transform.inl"
+
+namespace glm{using namespace gtc::matrix_transform;}
+
+#endif//glm_gtc_matrix_transform
diff --git a/src/glm/gtc/matrix_transform.inl b/src/glm/gtc/matrix_transform.inl
new file mode 100644
index 0000000..2b84faf
--- /dev/null
+++ b/src/glm/gtc/matrix_transform.inl
@@ -0,0 +1,397 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2009-04-29
+// Updated : 2009-04-29
+// Licence : This source is under MIT License
+// File : glm/gtc/matrix_transform.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm{
+namespace gtc{
+namespace matrix_transform
+{
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tmat4x4<T> translate
+ (
+ detail::tmat4x4<T> const & m,
+ detail::tvec3<T> const & v
+ )
+ {
+ detail::tmat4x4<T> Result(m);
+ Result[3] = m[0] * v[0] + m[1] * v[1] + m[2] * v[2] + m[3];
+ return Result;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tmat4x4<T> rotate
+ (
+ detail::tmat4x4<T> const & m,
+ T const & angle,
+ detail::tvec3<T> const & v
+ )
+ {
+ T a = radians(angle);
+ T c = cos(a);
+ T s = sin(a);
+
+ detail::tvec3<T> axis = normalize(v);
+
+ detail::tvec3<T> temp = (T(1) - c) * axis;
+
+ detail::tmat4x4<T> Rotate(detail::tmat4x4<T>::null);
+ Rotate[0][0] = c + temp[0] * axis[0];
+ Rotate[0][1] = 0 + temp[0] * axis[1] + s * axis[2];
+ Rotate[0][2] = 0 + temp[0] * axis[2] - s * axis[1];
+
+ Rotate[1][0] = 0 + temp[1] * axis[0] - s * axis[2];
+ Rotate[1][1] = c + temp[1] * axis[1];
+ Rotate[1][2] = 0 + temp[1] * axis[2] + s * axis[0];
+
+ Rotate[2][0] = 0 + temp[2] * axis[0] + s * axis[1];
+ Rotate[2][1] = 0 + temp[2] * axis[1] - s * axis[0];
+ Rotate[2][2] = c + temp[2] * axis[2];
+
+ detail::tmat4x4<T> Result(detail::tmat4x4<T>::null);
+ Result[0] = m[0] * Rotate[0][0] + m[1] * Rotate[0][1] + m[2] * Rotate[0][2];
+ Result[1] = m[0] * Rotate[1][0] + m[1] * Rotate[1][1] + m[2] * Rotate[1][2];
+ Result[2] = m[0] * Rotate[2][0] + m[1] * Rotate[2][1] + m[2] * Rotate[2][2];
+ Result[3] = m[3];
+ return Result;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tmat4x4<T> scale
+ (
+ detail::tmat4x4<T> const & m,
+ detail::tvec3<T> const & v
+ )
+ {
+ detail::tmat4x4<T> Result(detail::tmat4x4<T>::null);
+ Result[0] = m[0] * v[0];
+ Result[1] = m[1] * v[1];
+ Result[2] = m[2] * v[2];
+ Result[3] = m[3];
+ return Result;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tmat4x4<T> translate_slow
+ (
+ detail::tmat4x4<T> const & m,
+ detail::tvec3<T> const & v
+ )
+ {
+ detail::tmat4x4<T> Result(T(1));
+ Result[3] = detail::tvec4<T>(v, T(1));
+ return m * Result;
+
+ //detail::tmat4x4<valType> Result(m);
+ Result[3] = m[0] * v[0] + m[1] * v[1] + m[2] * v[2] + m[3];
+ //Result[3][0] = m[0][0] * v[0] + m[1][0] * v[1] + m[2][0] * v[2] + m[3][0];
+ //Result[3][1] = m[0][1] * v[0] + m[1][1] * v[1] + m[2][1] * v[2] + m[3][1];
+ //Result[3][2] = m[0][2] * v[0] + m[1][2] * v[1] + m[2][2] * v[2] + m[3][2];
+ //Result[3][3] = m[0][3] * v[0] + m[1][3] * v[1] + m[2][3] * v[2] + m[3][3];
+ //return Result;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tmat4x4<T> rotate_slow
+ (
+ detail::tmat4x4<T> const & m,
+ T const & angle,
+ detail::tvec3<T> const & v
+ )
+ {
+ T a = radians(angle);
+ T c = cos(a);
+ T s = sin(a);
+ detail::tmat4x4<T> Result;
+
+ detail::tvec3<T> axis = normalize(v);
+
+ Result[0][0] = c + (1 - c) * axis.x * axis.x;
+ Result[0][1] = (1 - c) * axis.x * axis.y + s * axis.z;
+ Result[0][2] = (1 - c) * axis.x * axis.z - s * axis.y;
+ Result[0][3] = 0;
+
+ Result[1][0] = (1 - c) * axis.y * axis.x - s * axis.z;
+ Result[1][1] = c + (1 - c) * axis.y * axis.y;
+ Result[1][2] = (1 - c) * axis.y * axis.z + s * axis.x;
+ Result[1][3] = 0;
+
+ Result[2][0] = (1 - c) * axis.z * axis.x + s * axis.y;
+ Result[2][1] = (1 - c) * axis.z * axis.y - s * axis.x;
+ Result[2][2] = c + (1 - c) * axis.z * axis.z;
+ Result[2][3] = 0;
+
+ Result[3] = detail::tvec4<T>(0, 0, 0, 1);
+ return m * Result;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tmat4x4<T> scale_slow
+ (
+ detail::tmat4x4<T> const & m,
+ detail::tvec3<T> const & v
+ )
+ {
+ detail::tmat4x4<T> Result(T(1));
+ Result[0][0] = v.x;
+ Result[1][1] = v.y;
+ Result[2][2] = v.z;
+ return m * Result;
+ }
+
+ template <typename valType>
+ GLM_FUNC_QUALIFIER detail::tmat4x4<valType> ortho
+ (
+ valType const & left,
+ valType const & right,
+ valType const & bottom,
+ valType const & top,
+ valType const & zNear,
+ valType const & zFar
+ )
+ {
+ detail::tmat4x4<valType> Result(1);
+ Result[0][0] = valType(2) / (right - left);
+ Result[1][1] = valType(2) / (top - bottom);
+ Result[2][2] = - valType(2) / (zFar - zNear);
+ Result[3][0] = - (right + left) / (right - left);
+ Result[3][1] = - (top + bottom) / (top - bottom);
+ Result[3][2] = - (zFar + zNear) / (zFar - zNear);
+ return Result;
+ }
+
+ template <typename valType>
+ GLM_FUNC_QUALIFIER detail::tmat4x4<valType> ortho(
+ valType const & left,
+ valType const & right,
+ valType const & bottom,
+ valType const & top)
+ {
+ detail::tmat4x4<valType> Result(1);
+ Result[0][0] = valType(2) / (right - left);
+ Result[1][1] = valType(2) / (top - bottom);
+ Result[2][2] = - valType(1);
+ Result[3][0] = - (right + left) / (right - left);
+ Result[3][1] = - (top + bottom) / (top - bottom);
+ return Result;
+ }
+
+ template <typename valType>
+ GLM_FUNC_QUALIFIER detail::tmat4x4<valType> frustum
+ (
+ valType const & left,
+ valType const & right,
+ valType const & bottom,
+ valType const & top,
+ valType const & nearVal,
+ valType const & farVal
+ )
+ {
+ detail::tmat4x4<valType> Result(0);
+ Result[0][0] = (valType(2) * nearVal) / (right - left);
+ Result[1][1] = (valType(2) * nearVal) / (top - bottom);
+ Result[2][0] = (right + left) / (right - left);
+ Result[2][1] = (top + bottom) / (top - bottom);
+ Result[2][2] = -(farVal + nearVal) / (farVal - nearVal);
+ Result[2][3] = valType(-1);
+ Result[3][2] = -(valType(2) * farVal * nearVal) / (farVal - nearVal);
+ return Result;
+ }
+
+ template <typename valType>
+ GLM_FUNC_QUALIFIER detail::tmat4x4<valType> perspective
+ (
+ valType const & fovy,
+ valType const & aspect,
+ valType const & zNear,
+ valType const & zFar
+ )
+ {
+ valType range = tan(radians(fovy / valType(2))) * zNear;
+ valType left = -range * aspect;
+ valType right = range * aspect;
+ valType bottom = -range;
+ valType top = range;
+
+ detail::tmat4x4<valType> Result(valType(0));
+ Result[0][0] = (valType(2) * zNear) / (right - left);
+ Result[1][1] = (valType(2) * zNear) / (top - bottom);
+ Result[2][2] = - (zFar + zNear) / (zFar - zNear);
+ Result[2][3] = - valType(1);
+ Result[3][2] = - (valType(2) * zFar * zNear) / (zFar - zNear);
+ return Result;
+ }
+
+ template <typename valType>
+ GLM_FUNC_QUALIFIER detail::tmat4x4<valType> perspectiveFov
+ (
+ valType const & fov,
+ valType const & width,
+ valType const & height,
+ valType const & zNear,
+ valType const & zFar
+ )
+ {
+ valType rad = glm::radians(fov);
+ valType h = glm::cos(valType(0.5) * rad) / glm::sin(valType(0.5) * rad);
+ valType w = h * height / width;
+
+ detail::tmat4x4<valType> Result(valType(0));
+ Result[0][0] = w;
+ Result[1][1] = h;
+ Result[2][2] = (zFar + zNear) / (zFar - zNear);
+ Result[2][3] = valType(1);
+ Result[3][2] = -(valType(2) * zFar * zNear) / (zFar - zNear);
+ return Result;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tmat4x4<T> infinitePerspective
+ (
+ T fovy,
+ T aspect,
+ T zNear
+ )
+ {
+ T range = tan(radians(fovy / T(2))) * zNear;
+ T left = -range * aspect;
+ T right = range * aspect;
+ T bottom = -range;
+ T top = range;
+
+ detail::tmat4x4<T> Result(T(0));
+ Result[0][0] = (T(2) * zNear) / (right - left);
+ Result[1][1] = (T(2) * zNear) / (top - bottom);
+ Result[2][2] = - T(1);
+ Result[2][3] = - T(1);
+ Result[3][2] = - T(2) * zNear;
+ return Result;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tmat4x4<T> tweakedInfinitePerspective
+ (
+ T fovy,
+ T aspect,
+ T zNear
+ )
+ {
+ T range = tan(radians(fovy / T(2))) * zNear;
+ T left = -range * aspect;
+ T right = range * aspect;
+ T bottom = -range;
+ T top = range;
+
+ detail::tmat4x4<T> Result(T(0));
+ Result[0][0] = (T(2) * zNear) / (right - left);
+ Result[1][1] = (T(2) * zNear) / (top - bottom);
+ Result[2][2] = T(0.0001) - T(1);
+ Result[2][3] = T(-1);
+ Result[3][2] = - (T(0.0001) - T(2)) * zNear;
+ return Result;
+ }
+
+ template <typename T, typename U>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> project
+ (
+ detail::tvec3<T> const & obj,
+ detail::tmat4x4<T> const & model,
+ detail::tmat4x4<T> const & proj,
+ detail::tvec4<U> const & viewport
+ )
+ {
+ detail::tvec4<T> tmp = detail::tvec4<T>(obj, T(1));
+ tmp = model * tmp;
+ tmp = proj * tmp;
+
+ tmp /= tmp.w;
+ tmp = tmp * T(0.5) + T(0.5);
+ tmp[0] = tmp[0] * T(viewport[2]) + T(viewport[0]);
+ tmp[1] = tmp[1] * T(viewport[3]) + T(viewport[1]);
+
+ return detail::tvec3<T>(tmp);
+ }
+
+ template <typename T, typename U>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> unProject
+ (
+ detail::tvec3<T> const & win,
+ detail::tmat4x4<T> const & model,
+ detail::tmat4x4<T> const & proj,
+ detail::tvec4<U> const & viewport
+ )
+ {
+ detail::tmat4x4<T> inverse = glm::inverse(proj * model);
+
+ detail::tvec4<T> tmp = detail::tvec4<T>(win, T(1));
+ tmp.x = (tmp.x - T(viewport[0])) / T(viewport[2]);
+ tmp.y = (tmp.y - T(viewport[1])) / T(viewport[3]);
+ tmp = tmp * T(2) - T(1);
+
+ detail::tvec4<T> obj = inverse * tmp;
+ obj /= obj.w;
+
+ return detail::tvec3<T>(obj);
+ }
+
+ template <typename T, typename U>
+ detail::tmat4x4<T> pickMatrix
+ (
+ detail::tvec2<T> const & center,
+ detail::tvec2<T> const & delta,
+ detail::tvec4<U> const & viewport
+ )
+ {
+ assert(delta.x > T(0) && delta.y > T(0));
+ detail::tmat4x4<T> Result(1.0f);
+
+ if(!(delta.x > T(0) && delta.y > T(0)))
+ return Result; // Error
+
+ detail::tvec3<T> Temp(
+ (T(viewport[2]) - T(2) * (center.x - T(viewport[0]))) / delta.x,
+ (T(viewport[3]) - T(2) * (center.y - T(viewport[1]))) / delta.y,
+ T(0));
+
+ // Translate and scale the picked region to the entire window
+ Result = translate(Result, Temp);
+ return scale(Result, detail::tvec3<T>(T(viewport[2]) / delta.x, T(viewport[3]) / delta.y, T(1)));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tmat4x4<T> lookAt
+ (
+ detail::tvec3<T> const & eye,
+ detail::tvec3<T> const & center,
+ detail::tvec3<T> const & up
+ )
+ {
+ detail::tvec3<T> f = normalize(center - eye);
+ detail::tvec3<T> u = normalize(up);
+ detail::tvec3<T> s = normalize(cross(f, u));
+ u = cross(s, f);
+
+ detail::tmat4x4<T> Result(1);
+ Result[0][0] = s.x;
+ Result[1][0] = s.y;
+ Result[2][0] = s.z;
+ Result[0][1] = u.x;
+ Result[1][1] = u.y;
+ Result[2][1] = u.z;
+ Result[0][2] =-f.x;
+ Result[1][2] =-f.y;
+ Result[2][2] =-f.z;
+ /* Test this instead of translate3D
+ Result[3][0] =-dot(s, eye);
+ Result[3][1] =-dot(y, eye);
+ Result[3][2] = dot(f, eye);
+ */
+ return gtc::matrix_transform::translate(Result, -eye);
+ }
+}//namespace matrix_transform
+}//namespace gtc
+}//namespace glm
diff --git a/src/glm/gtc/quaternion.hpp b/src/glm/gtc/quaternion.hpp
new file mode 100644
index 0000000..4fc8ca3
--- /dev/null
+++ b/src/glm/gtc/quaternion.hpp
@@ -0,0 +1,245 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2009-05-21
+// Updated : 2010-02-04
+// Licence : This source is under MIT License
+// File : glm/gtc/quaternion.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+// - GLM_GTC_half_float
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// ToDo:
+// - Study constructors with angles and axis
+// - Study constructors with vec3 that are the imaginary component of quaternion
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_gtc_quaternion
+#define glm_gtc_quaternion
+
+// Dependency:
+#include "../glm.hpp"
+#include "../gtc/half_float.hpp"
+
+#if(defined(GLM_MESSAGES) && !defined(glm_ext))
+# pragma message("GLM: GLM_GTC_quaternion extension included")
+#endif
+
+namespace glm{
+namespace detail
+{
+ //! \brief Template for quaternion.
+ //! From GLM_GTC_quaternion extension.
+ /// \ingroup gtc_quaternion
+ template <typename T>
+ struct tquat// : public genType<T, tquat>
+ {
+ typedef T value_type;
+
+ public:
+ value_type x, y, z, w;
+
+ // Constructors
+ tquat();
+ explicit tquat(
+ value_type const & s,
+ tvec3<T> const & v);
+ explicit tquat(
+ value_type const & w,
+ value_type const & x,
+ value_type const & y,
+ value_type const & z);
+
+ // Convertions
+ //explicit tquat(valType const & pitch, valType const & yaw, valType const & roll);
+ //! pitch, yaw, roll
+ explicit tquat(
+ tvec3<T> const & eulerAngles);
+ explicit tquat(
+ tmat3x3<T> const & m);
+ explicit tquat(
+ tmat4x4<T> const & m);
+
+ // Accesses
+ value_type & operator[](int i);
+ value_type const & operator[](int i) const;
+
+ // Operators
+ tquat<T> & operator*=(value_type const & s);
+ tquat<T> & operator/=(value_type const & s);
+ };
+
+ template <typename T>
+ detail::tquat<T> operator- (
+ detail::tquat<T> const & q);
+
+ template <typename T>
+ detail::tquat<T> operator+ (
+ detail::tquat<T> const & q,
+ detail::tquat<T> const & p);
+
+ template <typename T>
+ detail::tquat<T> operator* (
+ detail::tquat<T> const & q,
+ detail::tquat<T> const & p);
+
+ template <typename T>
+ detail::tvec3<T> operator* (
+ detail::tquat<T> const & q,
+ detail::tvec3<T> const & v);
+
+ template <typename T>
+ detail::tvec3<T> operator* (
+ detail::tvec3<T> const & v,
+ detail::tquat<T> const & q);
+
+ template <typename T>
+ detail::tvec4<T> operator* (
+ detail::tquat<T> const & q,
+ detail::tvec4<T> const & v);
+
+ template <typename T>
+ detail::tvec4<T> operator* (
+ detail::tvec4<T> const & v,
+ detail::tquat<T> const & q);
+
+ template <typename T>
+ detail::tquat<T> operator* (
+ detail::tquat<T> const & q,
+ typename detail::tquat<T>::value_type const & s);
+
+ template <typename T>
+ detail::tquat<T> operator* (
+ typename detail::tquat<T>::value_type const & s,
+ detail::tquat<T> const & q);
+
+ template <typename T>
+ detail::tquat<T> operator/ (
+ detail::tquat<T> const & q,
+ typename detail::tquat<T>::value_type const & s);
+
+} //namespace detail
+
+namespace gtc{
+namespace quaternion ///< GLM_GTC_quaternion extension: Quaternion types and functions
+{
+ /// \addtogroup gtc_quaternion
+ ///@{
+
+ //! Returns the length of the quaternion.
+ //! From GLM_GTC_quaternion extension.
+ template <typename T>
+ typename detail::tquat<T>::value_type length(
+ detail::tquat<T> const & q);
+
+ //! Returns the normalized quaternion.
+ //! From GLM_GTC_quaternion extension.
+ template <typename T>
+ detail::tquat<T> normalize(
+ detail::tquat<T> const & q);
+
+ //! Returns dot product of q1 and q2, i.e., q1[0] * q2[0] + q1[1] * q2[1] + ...
+ //! From GLM_GTC_quaternion extension.
+ template <typename T>
+ typename detail::tquat<T>::value_type dot(
+ detail::tquat<T> const & q1,
+ detail::tquat<T> const & q2);
+
+ //! Returns the cross product of q1 and q2.
+ //! From GLM_GTC_quaternion extension.
+ template <typename T>
+ GLM_DEPRECATED detail::tquat<T> cross(
+ detail::tquat<T> const & q1,
+ detail::tquat<T> const & q2);
+
+ //! Returns a SLERP interpolated quaternion of x and y according a.
+ //! From GLM_GTC_quaternion extension.
+ template <typename T>
+ detail::tquat<T> mix(
+ detail::tquat<T> const & x,
+ detail::tquat<T> const & y,
+ T const & a);
+
+ //! Returns the q conjugate.
+ //! From GLM_GTC_quaternion extension.
+ template <typename T>
+ detail::tquat<T> conjugate(
+ detail::tquat<T> const & q);
+
+ //! Returns the q inverse.
+ //! From GLM_GTC_quaternion extension.
+ template <typename T>
+ detail::tquat<T> inverse(
+ detail::tquat<T> const & q);
+
+ //! Rotates a quaternion from an vector of 3 components axis and an angle expressed in degrees.
+ //! From GLM_GTC_quaternion extension.
+ template <typename T>
+ detail::tquat<T> rotate(
+ detail::tquat<T> const & q,
+ typename detail::tquat<T>::value_type const & angle,
+ detail::tvec3<T> const & v);
+
+ //! Converts a quaternion to a 3 * 3 matrix.
+ //! From GLM_GTC_quaternion extension.
+ template <typename T>
+ detail::tmat3x3<T> mat3_cast(
+ detail::tquat<T> const & x);
+
+ //! Converts a quaternion to a 4 * 4 matrix.
+ //! From GLM_GTC_quaternion extension.
+ template <typename T>
+ detail::tmat4x4<T> mat4_cast(
+ detail::tquat<T> const & x);
+
+ //! Converts a 3 * 3 matrix to a quaternion.
+ //! From GLM_GTC_quaternion extension.
+ template <typename T>
+ detail::tquat<T> quat_cast(
+ detail::tmat3x3<T> const & x);
+
+ //! Converts a 4 * 4 matrix to a quaternion.
+ //! From GLM_GTC_quaternion extension.
+ template <typename T>
+ detail::tquat<T> quat_cast(
+ detail::tmat4x4<T> const & x);
+
+ //! Quaternion of floating-point numbers.
+ //! From GLM_GTC_quaternion extension.
+ typedef detail::tquat<float> quat;
+
+ //! Quaternion of half-precision floating-point numbers.
+ //! From GLM_GTC_quaternion extension.
+ typedef detail::tquat<detail::thalf> hquat;
+
+ //! Quaternion of single-precision floating-point numbers.
+ //! From GLM_GTC_quaternion extension.
+ typedef detail::tquat<float> fquat;
+
+ //! Quaternion of double-precision floating-point numbers.
+ //! From GLM_GTC_quaternion extension.
+ typedef detail::tquat<double> dquat;
+
+ //! Quaternion of low precision floating-point numbers.
+ //! From GLM_GTC_quaternion extension.
+ typedef detail::tquat<lowp_float> lowp_quat;
+
+ //! Quaternion of medium precision floating-point numbers.
+ //! From GLM_GTC_quaternion extension.
+ typedef detail::tquat<mediump_float> mediump_quat;
+
+ //! Quaternion of high precision floating-point numbers.
+ //! From GLM_GTC_quaternion extension.
+ typedef detail::tquat<highp_float> highp_quat;
+ ///@}
+
+} //namespace quaternion
+} //namespace gtc
+} //namespace glm
+
+#include "quaternion.inl"
+
+namespace glm{using namespace gtc::quaternion;}
+
+#endif//glm_gtc_quaternion
diff --git a/src/glm/gtc/quaternion.inl b/src/glm/gtc/quaternion.inl
new file mode 100644
index 0000000..3090527
--- /dev/null
+++ b/src/glm/gtc/quaternion.inl
@@ -0,0 +1,584 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2009-05-21
+// Updated : 2010-02-04
+// Licence : This source is under MIT License
+// File : glm/gtc/quaternion.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#include <limits>
+
+namespace glm{
+namespace detail{
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tquat<T>::tquat() :
+ x(0),
+ y(0),
+ z(0),
+ w(1)
+ {}
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tquat<T>::tquat
+ (
+ value_type const & s,
+ tvec3<T> const & v
+ ) :
+ x(v.x),
+ y(v.y),
+ z(v.z),
+ w(s)
+ {}
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tquat<T>::tquat
+ (
+ value_type const & w,
+ value_type const & x,
+ value_type const & y,
+ value_type const & z
+ ) :
+ x(x),
+ y(y),
+ z(z),
+ w(w)
+ {}
+
+ //////////////////////////////////////////////////////////////
+ // tquat conversions
+
+ //template <typename valType>
+ //GLM_FUNC_QUALIFIER tquat<valType>::tquat
+ //(
+ // valType const & pitch,
+ // valType const & yaw,
+ // valType const & roll
+ //)
+ //{
+ // tvec3<valType> eulerAngle(pitch * valType(0.5), yaw * valType(0.5), roll * valType(0.5));
+ // tvec3<valType> c = glm::cos(eulerAngle * valType(0.5));
+ // tvec3<valType> s = glm::sin(eulerAngle * valType(0.5));
+ //
+ // this->w = c.x * c.y * c.z + s.x * s.y * s.z;
+ // this->x = s.x * c.y * c.z - c.x * s.y * s.z;
+ // this->y = c.x * s.y * c.z + s.x * c.y * s.z;
+ // this->z = c.x * c.y * s.z - s.x * s.y * c.z;
+ //}
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tquat<T>::tquat
+ (
+ tvec3<T> const & eulerAngle
+ )
+ {
+ tvec3<T> c = glm::cos(eulerAngle * value_type(0.5));
+ tvec3<T> s = glm::sin(eulerAngle * value_type(0.5));
+
+ this->w = c.x * c.y * c.z + s.x * s.y * s.z;
+ this->x = s.x * c.y * c.z - c.x * s.y * s.z;
+ this->y = c.x * s.y * c.z + s.x * c.y * s.z;
+ this->z = c.x * c.y * s.z - s.x * s.y * c.z;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tquat<T>::tquat
+ (
+ tmat3x3<T> const & m
+ )
+ {
+ *this = toQuat(m);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tquat<T>::tquat
+ (
+ tmat4x4<T> const & m
+ )
+ {
+ *this = toQuat(m);
+ }
+
+ //////////////////////////////////////////////////////////////
+ // tquat<T> accesses
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename tquat<T>::value_type & tquat<T>::operator [] (int i)
+ {
+ return (&x)[i];
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename tquat<T>::value_type const & tquat<T>::operator [] (int i) const
+ {
+ return (&x)[i];
+ }
+
+ //////////////////////////////////////////////////////////////
+ // tquat<valType> operators
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tquat<T> & tquat<T>::operator *=
+ (
+ value_type const & s
+ )
+ {
+ this->w *= s;
+ this->x *= s;
+ this->y *= s;
+ this->z *= s;
+ return *this;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER tquat<T> & tquat<T>::operator /=
+ (
+ value_type const & s
+ )
+ {
+ this->w /= s;
+ this->x /= s;
+ this->y /= s;
+ this->z /= s;
+ return *this;
+ }
+
+ //////////////////////////////////////////////////////////////
+ // tquat<valType> external operators
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tquat<T> operator-
+ (
+ detail::tquat<T> const & q
+ )
+ {
+ return detail::tquat<T>(-q.w, -q.x, -q.y, -q.z);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tquat<T> operator+
+ (
+ detail::tquat<T> const & q,
+ detail::tquat<T> const & p
+ )
+ {
+ return detail::tquat<T>(
+ q.w + p.w,
+ q.x + p.x,
+ q.y + p.y,
+ q.z + p.z);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tquat<T> operator*
+ (
+ detail::tquat<T> const & q,
+ detail::tquat<T> const & p
+ )
+ {
+ return detail::tquat<T>(
+ q.w * p.w - q.x * p.x - q.y * p.y - q.z * p.z,
+ q.w * p.x + q.x * p.w + q.y * p.z - q.z * p.y,
+ q.w * p.y + q.y * p.w + q.z * p.x - q.x * p.z,
+ q.w * p.z + q.z * p.w + q.x * p.y - q.y * p.x);
+ }
+
+ // Transformation
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> operator*
+ (
+ detail::tquat<T> const & q,
+ detail::tvec3<T> const & v
+ )
+ {
+ typename detail::tquat<T>::value_type Two(2);
+
+ detail::tvec3<T> uv, uuv;
+ detail::tvec3<T> QuatVector(q.x, q.y, q.z);
+ uv = glm::cross(QuatVector, v);
+ uuv = glm::cross(QuatVector, uv);
+ uv *= (Two * q.w);
+ uuv *= Two;
+
+ return v + uv + uuv;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> operator*
+ (
+ detail::tvec3<T> const & v,
+ detail::tquat<T> const & q
+ )
+ {
+ return gtc::quaternion::inverse(q) * v;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<T> operator*
+ (
+ detail::tquat<T> const & q,
+ detail::tvec4<T> const & v
+ )
+ {
+ return detail::tvec4<T>(q * detail::tvec3<T>(v), v.w);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<T> operator*
+ (
+ detail::tvec4<T> const & v,
+ detail::tquat<T> const & q
+ )
+ {
+ return gtc::quaternion::inverse(q) * v;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tquat<T> operator*
+ (
+ detail::tquat<T> const & q,
+ typename detail::tquat<T>::value_type const & s
+ )
+ {
+ return detail::tquat<T>(
+ q.w * s, q.x * s, q.y * s, q.z * s);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tquat<T> operator*
+ (
+ typename detail::tquat<T>::value_type const & s,
+ detail::tquat<T> const & q
+ )
+ {
+ return q * s;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tquat<T> operator/
+ (
+ detail::tquat<T> const & q,
+ typename detail::tquat<T>::value_type const & s
+ )
+ {
+ return detail::tquat<T>(
+ q.w / s, q.x / s, q.y / s, q.z / s);
+ }
+
+ //////////////////////////////////////
+ // Boolean operators
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER bool operator==
+ (
+ detail::tquat<T> const & q1,
+ detail::tquat<T> const & q2
+ )
+ {
+ return (q1.x == q2.x) && (q1.y == q2.y) && (q1.z == q2.z) && (q1.w == q2.w);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER bool operator!=
+ (
+ detail::tquat<T> const & q1,
+ detail::tquat<T> const & q2
+ )
+ {
+ return (q1.x != q2.x) || (q1.y != q2.y) || (q1.z != q2.z) || (q1.w != q2.w);
+ }
+
+}//namespace detail
+
+namespace gtc{
+namespace quaternion{
+
+ ////////////////////////////////////////////////////////
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename detail::tquat<T>::value_type length
+ (
+ detail::tquat<T> const & q
+ )
+ {
+ return glm::sqrt(dot(q, q));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tquat<T> normalize
+ (
+ detail::tquat<T> const & q
+ )
+ {
+ typename detail::tquat<T>::value_type len = length(q);
+ if(len <= typename detail::tquat<T>::value_type(0)) // Problem
+ return detail::tquat<T>(1, 0, 0, 0);
+ typename detail::tquat<T>::value_type oneOverLen = typename detail::tquat<T>::value_type(1) / len;
+ return detail::tquat<T>(q.w * oneOverLen, q.x * oneOverLen, q.y * oneOverLen, q.z * oneOverLen);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER typename detail::tquat<T>::value_type dot
+ (
+ detail::tquat<T> const & q1,
+ detail::tquat<T> const & q2
+ )
+ {
+ return q1.x * q2.x + q1.y * q2.y + q1.z * q2.z + q1.w * q2.w;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tquat<T> cross
+ (
+ detail::tquat<T> const & q1,
+ detail::tquat<T> const & q2
+ )
+ {
+ return detail::tquat<T>(
+ q1.w * q2.w - q1.x * q2.x - q1.y * q2.y - q1.z * q2.z,
+ q1.w * q2.x + q1.x * q2.w + q1.y * q2.z - q1.z * q2.y,
+ q1.w * q2.y + q1.y * q2.w + q1.z * q2.x - q1.x * q2.z,
+ q1.w * q2.z + q1.z * q2.w + q1.x * q2.y - q1.y * q2.x);
+ }
+/*
+ // (x * sin(1 - a) * angle / sin(angle)) + (y * sin(a) * angle / sin(angle))
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tquat<T> mix
+ (
+ detail::tquat<T> const & x,
+ detail::tquat<T> const & y,
+ typename detail::tquat<T>::value_type const & a
+ )
+ {
+ if(a <= typename detail::tquat<T>::value_type(0)) return x;
+ if(a >= typename detail::tquat<T>::value_type(1)) return y;
+
+ float fCos = dot(x, y);
+ detail::tquat<T> y2(y); //BUG!!! tquat<T> y2;
+ if(fCos < typename detail::tquat<T>::value_type(0))
+ {
+ y2 = -y;
+ fCos = -fCos;
+ }
+
+ //if(fCos > 1.0f) // problem
+ float k0, k1;
+ if(fCos > typename detail::tquat<T>::value_type(0.9999))
+ {
+ k0 = typename detail::tquat<T>::value_type(1) - a;
+ k1 = typename detail::tquat<T>::value_type(0) + a; //BUG!!! 1.0f + a;
+ }
+ else
+ {
+ typename detail::tquat<T>::value_type fSin = sqrt(T(1) - fCos * fCos);
+ typename detail::tquat<T>::value_type fAngle = atan(fSin, fCos);
+ typename detail::tquat<T>::value_type fOneOverSin = T(1) / fSin;
+ k0 = sin((typename detail::tquat<T>::value_type(1) - a) * fAngle) * fOneOverSin;
+ k1 = sin((typename detail::tquat<T>::value_type(0) + a) * fAngle) * fOneOverSin;
+ }
+
+ return detail::tquat<T>(
+ k0 * x.w + k1 * y2.w,
+ k0 * x.x + k1 * y2.x,
+ k0 * x.y + k1 * y2.y,
+ k0 * x.z + k1 * y2.z);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tquat<T> mix2
+ (
+ detail::tquat<T> const & x,
+ detail::tquat<T> const & y,
+ T const & a
+ )
+ {
+ bool flip = false;
+ if(a <= T(0)) return x;
+ if(a >= T(1)) return y;
+
+ T cos_t = dot(x, y);
+ if(cos_t < T(0))
+ {
+ cos_t = -cos_t;
+ flip = true;
+ }
+
+ T alpha(0), beta(0);
+
+ if(T(1) - cos_t < 1e-7)
+ beta = T(1) - alpha;
+ else
+ {
+ T theta = acos(cos_t);
+ T sin_t = sin(theta);
+ beta = sin(theta * (T(1) - alpha)) / sin_t;
+ alpha = sin(alpha * theta) / sin_t;
+ }
+
+ if(flip)
+ alpha = -alpha;
+
+ return normalize(beta * x + alpha * y);
+ }
+*/
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tquat<T> mix
+ (
+ detail::tquat<T> const & x,
+ detail::tquat<T> const & y,
+ T const & a
+ )
+ {
+ T angle = acos(dot(x, y));
+ return (glm::sin((T(1) - a) * angle) * x + glm::sin(a * angle) * y) / glm::sin(angle);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tquat<T> conjugate
+ (
+ detail::tquat<T> const & q
+ )
+ {
+ return detail::tquat<T>(q.w, -q.x, -q.y, -q.z);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tquat<T> inverse
+ (
+ detail::tquat<T> const & q
+ )
+ {
+ return gtc::quaternion::conjugate(q) / gtc::quaternion::dot(q, q);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tquat<T> rotate
+ (
+ detail::tquat<T> const & q,
+ typename detail::tquat<T>::value_type const & angle,
+ detail::tvec3<T> const & v
+ )
+ {
+ detail::tvec3<T> Tmp = v;
+
+ // Axis of rotation must be normalised
+ typename detail::tquat<T>::value_type len = glm::core::function::geometric::length(Tmp);
+ if(abs(len - typename detail::tquat<T>::value_type(1)) > typename detail::tquat<T>::value_type(0.001))
+ {
+ T oneOverLen = T(1) / len;
+ Tmp.x *= oneOverLen;
+ Tmp.y *= oneOverLen;
+ Tmp.z *= oneOverLen;
+ }
+
+ typename detail::tquat<T>::value_type AngleRad = radians(angle);
+ typename detail::tquat<T>::value_type fSin = sin(AngleRad * T(0.5));
+
+ return gtc::quaternion::cross(q, detail::tquat<T>(cos(AngleRad * T(0.5)), Tmp.x * fSin, Tmp.y * fSin, Tmp.z * fSin));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tmat3x3<T> mat3_cast
+ (
+ detail::tquat<T> const & q
+ )
+ {
+ detail::tmat3x3<T> Result(typename detail::tquat<T>::value_type(1));
+ Result[0][0] = 1 - 2 * q.y * q.y - 2 * q.z * q.z;
+ Result[0][1] = 2 * q.x * q.y + 2 * q.w * q.z;
+ Result[0][2] = 2 * q.x * q.z - 2 * q.w * q.y;
+
+ Result[1][0] = 2 * q.x * q.y - 2 * q.w * q.z;
+ Result[1][1] = 1 - 2 * q.x * q.x - 2 * q.z * q.z;
+ Result[1][2] = 2 * q.y * q.z + 2 * q.w * q.x;
+
+ Result[2][0] = 2 * q.x * q.z + 2 * q.w * q.y;
+ Result[2][1] = 2 * q.y * q.z - 2 * q.w * q.x;
+ Result[2][2] = 1 - 2 * q.x * q.x - 2 * q.y * q.y;
+ return Result;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tmat4x4<T> mat4_cast
+ (
+ detail::tquat<T> const & q
+ )
+ {
+ return detail::tmat4x4<T>(mat3_cast(q));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tquat<T> quat_cast
+ (
+ detail::tmat3x3<T> const & m
+ )
+ {
+ typename detail::tquat<T>::value_type fourXSquaredMinus1 = m[0][0] - m[1][1] - m[2][2];
+ typename detail::tquat<T>::value_type fourYSquaredMinus1 = m[1][1] - m[0][0] - m[2][2];
+ typename detail::tquat<T>::value_type fourZSquaredMinus1 = m[2][2] - m[0][0] - m[1][1];
+ typename detail::tquat<T>::value_type fourWSquaredMinus1 = m[0][0] + m[1][1] + m[2][2];
+
+ int biggestIndex = 0;
+ typename detail::tquat<T>::value_type fourBiggestSquaredMinus1 = fourWSquaredMinus1;
+ if(fourXSquaredMinus1 > fourBiggestSquaredMinus1)
+ {
+ fourBiggestSquaredMinus1 = fourXSquaredMinus1;
+ biggestIndex = 1;
+ }
+ if(fourYSquaredMinus1 > fourBiggestSquaredMinus1)
+ {
+ fourBiggestSquaredMinus1 = fourYSquaredMinus1;
+ biggestIndex = 2;
+ }
+ if(fourZSquaredMinus1 > fourBiggestSquaredMinus1)
+ {
+ fourBiggestSquaredMinus1 = fourZSquaredMinus1;
+ biggestIndex = 3;
+ }
+
+ typename detail::tquat<T>::value_type biggestVal = sqrt(fourBiggestSquaredMinus1 + typename detail::tquat<T>::value_type(1)) * typename detail::tquat<T>::value_type(0.5);
+ typename detail::tquat<T>::value_type mult = typename detail::tquat<T>::value_type(0.25) / biggestVal;
+
+ detail::tquat<T> Result;
+ switch(biggestIndex)
+ {
+ case 0:
+ Result.w = biggestVal;
+ Result.x = (m[1][2] - m[2][1]) * mult;
+ Result.y = (m[2][0] - m[0][2]) * mult;
+ Result.z = (m[0][1] - m[1][0]) * mult;
+ break;
+ case 1:
+ Result.w = (m[1][2] - m[2][1]) * mult;
+ Result.x = biggestVal;
+ Result.y = (m[0][1] + m[1][0]) * mult;
+ Result.z = (m[2][0] + m[0][2]) * mult;
+ break;
+ case 2:
+ Result.w = (m[2][0] - m[0][2]) * mult;
+ Result.x = (m[0][1] + m[1][0]) * mult;
+ Result.y = biggestVal;
+ Result.z = (m[1][2] + m[2][1]) * mult;
+ break;
+ case 3:
+ Result.w = (m[0][1] - m[1][0]) * mult;
+ Result.x = (m[2][0] + m[0][2]) * mult;
+ Result.y = (m[1][2] + m[2][1]) * mult;
+ Result.z = biggestVal;
+ break;
+ }
+ return Result;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tquat<T> quat_cast
+ (
+ detail::tmat4x4<T> const & m4
+ )
+ {
+ return quat_cast(detail::tmat3x3<T>(m4));
+ }
+
+}//namespace quaternion
+}//namespace gtc
+}//namespace glm
diff --git a/src/glm/gtc/swizzle.hpp b/src/glm/gtc/swizzle.hpp
new file mode 100644
index 0000000..10c0836
--- /dev/null
+++ b/src/glm/gtc/swizzle.hpp
@@ -0,0 +1,354 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2010-02-20
+// Updated : 2010-02-20
+// Licence : This source is under MIT License
+// File : glm/gtc/swizzle.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_gtc_swizzle
+#define glm_gtc_swizzle
+
+// Dependency:
+#include "../glm.hpp"
+#include "../gtc/type_precision.hpp"
+
+#if(defined(GLM_MESSAGES) && !defined(glm_ext))
+# pragma message("GLM: GLM_GTC_swizzle extension included")
+#endif
+
+namespace glm{
+namespace gtc{
+namespace swizzle ///< GLM_GTC_swizzle extension
+{
+ using namespace gtc::half_float;
+
+ template <typename T, template <typename> class vecType>
+ T const & swizzle(
+ vecType<T> const & v,
+ comp x);
+
+ template <typename T, template <typename> class vecType>
+ detail::tvec2<T> const & swizzle(
+ vecType<T> const & v,
+ comp x, comp y);
+
+ template <typename T, template <typename> class vecType>
+ detail::tvec3<T> const & swizzle(
+ vecType<T> const & v,
+ comp x, comp y, comp z);
+
+ template <typename T, template <typename> class vecType>
+ detail::tvec4<T> const & swizzle(
+ vecType<T> const & v,
+ comp x, comp y, comp z, comp w);
+
+ template <typename T, template <typename> class vecType>
+ T & swizzle(
+ vecType<T> & v,
+ comp x);
+
+ template <typename T, template <typename> class vecType>
+ detail::tref2<T> swizzle(
+ vecType<T> & v,
+ comp x, comp y);
+
+ template <typename T, template <typename> class vecType>
+ detail::tref3<T> swizzle(
+ vecType<T> & v,
+ comp x, comp y, comp z);
+
+ template <typename T, template <typename> class vecType>
+ detail::tref4<T> swizzle(
+ vecType<T> & v,
+ comp x, comp y, comp z, comp w);
+
+# define static_swizzle1_const(TYPE, SIZE) \
+ template <comp x> \
+ GLM_FUNC_QUALIFIER TYPE swizzle(detail::tvec##SIZE<TYPE> const & v) \
+ {return v[x];}
+
+# define static_swizzle1_ref(TYPE, SIZE) \
+ template <comp x> \
+ GLM_FUNC_QUALIFIER TYPE& swizzle(detail::tvec##SIZE<TYPE> & v) \
+ {return v[x];}
+
+ static_swizzle1_ref(detail::float16, 2)
+ static_swizzle1_ref(detail::float16, 3)
+ static_swizzle1_ref(detail::float16, 4)
+ static_swizzle1_ref(detail::float32, 2)
+ static_swizzle1_ref(detail::float32, 3)
+ static_swizzle1_ref(detail::float32, 4)
+ static_swizzle1_ref(detail::float64, 2)
+ static_swizzle1_ref(detail::float64, 3)
+ static_swizzle1_ref(detail::float64, 4)
+
+ static_swizzle1_ref(detail::int8, 2)
+ static_swizzle1_ref(detail::int8, 3)
+ static_swizzle1_ref(detail::int8, 4)
+ static_swizzle1_ref(detail::int16, 2)
+ static_swizzle1_ref(detail::int16, 3)
+ static_swizzle1_ref(detail::int16, 4)
+ static_swizzle1_ref(detail::int32, 2)
+ static_swizzle1_ref(detail::int32, 3)
+ static_swizzle1_ref(detail::int32, 4)
+ static_swizzle1_ref(detail::int64, 2)
+ static_swizzle1_ref(detail::int64, 3)
+ static_swizzle1_ref(detail::int64, 4)
+
+ static_swizzle1_ref(detail::uint8, 2)
+ static_swizzle1_ref(detail::uint8, 3)
+ static_swizzle1_ref(detail::uint8, 4)
+ static_swizzle1_ref(detail::uint16, 2)
+ static_swizzle1_ref(detail::uint16, 3)
+ static_swizzle1_ref(detail::uint16, 4)
+ static_swizzle1_ref(detail::uint32, 2)
+ static_swizzle1_ref(detail::uint32, 3)
+ static_swizzle1_ref(detail::uint32, 4)
+ static_swizzle1_ref(detail::uint64, 2)
+ static_swizzle1_ref(detail::uint64, 3)
+ static_swizzle1_ref(detail::uint64, 4)
+/*
+# define static_swizzle2_const(TYPE) \
+ template <comp x, comp y> \
+ GLM_FUNC_QUALIFIER TYPE swizzle(TYPE const & v) \
+ {return TYPE(v[x], v[y]);}
+
+# define static_swizzle3_const(TYPE) \
+ template <comp x, comp y, comp z> \
+ GLM_FUNC_QUALIFIER TYPE swizzle(TYPE const & v) \
+ {return TYPE(v[x], v[y], v[z]);}
+
+# define static_swizzle4_const(TYPE) \
+ template <comp x, comp y, comp z, comp w> \
+ GLM_FUNC_QUALIFIER TYPE swizzle(TYPE const & v) \
+ {return TYPE(v[x], v[y], v[z], v[w]);}
+*/
+
+# define static_swizzle2_const(TYPE, SIZE) \
+ template <comp x, comp y> \
+ GLM_FUNC_QUALIFIER detail::tvec2<TYPE> swizzle(detail::tvec##SIZE<TYPE> const & v) \
+ {return detail::tvec2<TYPE>(v[x], v[y]);}
+
+# define static_swizzle3_const(TYPE, SIZE) \
+ template <comp x, comp y, comp z> \
+ GLM_FUNC_QUALIFIER detail::tvec3<TYPE> swizzle(detail::tvec##SIZE<TYPE> const & v) \
+ {return detail::tvec3<TYPE>(v[x], v[y], v[z]);}
+
+# define static_swizzle4_const(TYPE, SIZE) \
+ template <comp x, comp y, comp z, comp w> \
+ GLM_FUNC_QUALIFIER detail::tvec4<TYPE> swizzle(detail::tvec##SIZE<TYPE> const & v) \
+ {return detail::tvec4<TYPE>(v[x], v[y], v[z], v[w]);}
+
+
+ static_swizzle2_const(glm::f16, 2)
+ static_swizzle2_const(glm::f16, 3)
+ static_swizzle2_const(glm::f16, 4)
+ static_swizzle2_const(glm::f32, 2)
+ static_swizzle2_const(glm::f32, 3)
+ static_swizzle2_const(glm::f32, 4)
+ static_swizzle2_const(glm::f64, 2)
+ static_swizzle2_const(glm::f64, 3)
+ static_swizzle2_const(glm::f64, 4)
+
+ static_swizzle2_const(glm::i8, 2)
+ static_swizzle2_const(glm::i8, 3)
+ static_swizzle2_const(glm::i8, 4)
+ static_swizzle2_const(glm::i16, 2)
+ static_swizzle2_const(glm::i16, 3)
+ static_swizzle2_const(glm::i16, 4)
+ static_swizzle2_const(glm::i32, 2)
+ static_swizzle2_const(glm::i32, 3)
+ static_swizzle2_const(glm::i32, 4)
+ static_swizzle2_const(glm::i64, 2)
+ static_swizzle2_const(glm::i64, 3)
+ static_swizzle2_const(glm::i64, 4)
+
+ static_swizzle2_const(glm::u8, 2)
+ static_swizzle2_const(glm::u8, 3)
+ static_swizzle2_const(glm::u8, 4)
+ static_swizzle2_const(glm::u16, 2)
+ static_swizzle2_const(glm::u16, 3)
+ static_swizzle2_const(glm::u16, 4)
+ static_swizzle2_const(glm::u32, 2)
+ static_swizzle2_const(glm::u32, 3)
+ static_swizzle2_const(glm::u32, 4)
+ static_swizzle2_const(glm::u64, 2)
+ static_swizzle2_const(glm::u64, 3)
+ static_swizzle2_const(glm::u64, 4)
+
+ static_swizzle3_const(glm::f16, 2)
+ static_swizzle3_const(glm::f16, 3)
+ static_swizzle3_const(glm::f16, 4)
+ static_swizzle3_const(glm::f32, 2)
+ static_swizzle3_const(glm::f32, 3)
+ static_swizzle3_const(glm::f32, 4)
+ static_swizzle3_const(glm::f64, 2)
+ static_swizzle3_const(glm::f64, 3)
+ static_swizzle3_const(glm::f64, 4)
+
+ static_swizzle3_const(glm::i8, 2)
+ static_swizzle3_const(glm::i8, 3)
+ static_swizzle3_const(glm::i8, 4)
+ static_swizzle3_const(glm::i16, 2)
+ static_swizzle3_const(glm::i16, 3)
+ static_swizzle3_const(glm::i16, 4)
+ static_swizzle3_const(glm::i32, 2)
+ static_swizzle3_const(glm::i32, 3)
+ static_swizzle3_const(glm::i32, 4)
+ static_swizzle3_const(glm::i64, 2)
+ static_swizzle3_const(glm::i64, 3)
+ static_swizzle3_const(glm::i64, 4)
+
+ static_swizzle3_const(glm::u8, 2)
+ static_swizzle3_const(glm::u8, 3)
+ static_swizzle3_const(glm::u8, 4)
+ static_swizzle3_const(glm::u16, 2)
+ static_swizzle3_const(glm::u16, 3)
+ static_swizzle3_const(glm::u16, 4)
+ static_swizzle3_const(glm::u32, 2)
+ static_swizzle3_const(glm::u32, 3)
+ static_swizzle3_const(glm::u32, 4)
+ static_swizzle3_const(glm::u64, 2)
+ static_swizzle3_const(glm::u64, 3)
+ static_swizzle3_const(glm::u64, 4)
+
+ static_swizzle4_const(glm::f16, 2)
+ static_swizzle4_const(glm::f16, 3)
+ static_swizzle4_const(glm::f16, 4)
+ static_swizzle4_const(glm::f32, 2)
+ static_swizzle4_const(glm::f32, 3)
+ static_swizzle4_const(glm::f32, 4)
+ static_swizzle4_const(glm::f64, 2)
+ static_swizzle4_const(glm::f64, 3)
+ static_swizzle4_const(glm::f64, 4)
+
+ static_swizzle4_const(glm::i8, 2)
+ static_swizzle4_const(glm::i8, 3)
+ static_swizzle4_const(glm::i8, 4)
+ static_swizzle4_const(glm::i16, 2)
+ static_swizzle4_const(glm::i16, 3)
+ static_swizzle4_const(glm::i16, 4)
+ static_swizzle4_const(glm::i32, 2)
+ static_swizzle4_const(glm::i32, 3)
+ static_swizzle4_const(glm::i32, 4)
+ static_swizzle4_const(glm::i64, 2)
+ static_swizzle4_const(glm::i64, 3)
+ static_swizzle4_const(glm::i64, 4)
+
+ static_swizzle4_const(glm::u8, 2)
+ static_swizzle4_const(glm::u8, 3)
+ static_swizzle4_const(glm::u8, 4)
+ static_swizzle4_const(glm::u16, 2)
+ static_swizzle4_const(glm::u16, 3)
+ static_swizzle4_const(glm::u16, 4)
+ static_swizzle4_const(glm::u32, 2)
+ static_swizzle4_const(glm::u32, 3)
+ static_swizzle4_const(glm::u32, 4)
+ static_swizzle4_const(glm::u64, 2)
+ static_swizzle4_const(glm::u64, 3)
+ static_swizzle4_const(glm::u64, 4)
+
+# define static_swizzle2_ref(TYPE, SIZE) \
+ template <glm::comp x, glm::comp y> \
+ GLM_FUNC_QUALIFIER glm::detail::tref2<TYPE> swizzle(detail::tvec##SIZE<TYPE> & v) \
+ {return glm::detail::tref2<TYPE>(v[x], v[y]);}
+
+# define static_swizzle3_ref(TYPE, SIZE) \
+ template <glm::comp x, glm::comp y, glm::comp z> \
+ GLM_FUNC_QUALIFIER glm::detail::tref3<TYPE> swizzle(detail::tvec##SIZE<TYPE> & v) \
+ {return glm::detail::tref3<TYPE>(v[x], v[y], v[z]);}
+
+# define static_swizzle4_ref(TYPE, SIZE) \
+ template <glm::comp x, glm::comp y, glm::comp z, glm::comp w> \
+ GLM_FUNC_QUALIFIER glm::detail::tref4<TYPE> swizzle(detail::tvec##SIZE<TYPE> & v) \
+ {return glm::detail::tref4<TYPE>(v[x], v[y], v[z], v[w]);}
+
+ static_swizzle2_ref(glm::f16, 2)
+ static_swizzle2_ref(glm::f16, 3)
+ static_swizzle2_ref(glm::f16, 4)
+ static_swizzle2_ref(glm::f32, 2)
+ static_swizzle2_ref(glm::f32, 3)
+ static_swizzle2_ref(glm::f32, 4)
+ static_swizzle2_ref(glm::f64, 2)
+ static_swizzle2_ref(glm::f64, 3)
+ static_swizzle2_ref(glm::f64, 4)
+
+ static_swizzle2_ref(glm::i8, 2)
+ static_swizzle2_ref(glm::i8, 3)
+ static_swizzle2_ref(glm::i8, 4)
+ static_swizzle2_ref(glm::i16, 2)
+ static_swizzle2_ref(glm::i16, 3)
+ static_swizzle2_ref(glm::i16, 4)
+ static_swizzle2_ref(glm::i32, 2)
+ static_swizzle2_ref(glm::i32, 3)
+ static_swizzle2_ref(glm::i32, 4)
+ static_swizzle2_ref(glm::i64, 2)
+ static_swizzle2_ref(glm::i64, 3)
+ static_swizzle2_ref(glm::i64, 4)
+
+ static_swizzle2_ref(glm::u8, 2)
+ static_swizzle2_ref(glm::u8, 3)
+ static_swizzle2_ref(glm::u8, 4)
+ static_swizzle2_ref(glm::u16, 2)
+ static_swizzle2_ref(glm::u16, 3)
+ static_swizzle2_ref(glm::u16, 4)
+ static_swizzle2_ref(glm::u32, 2)
+ static_swizzle2_ref(glm::u32, 3)
+ static_swizzle2_ref(glm::u32, 4)
+ static_swizzle2_ref(glm::u64, 2)
+ static_swizzle2_ref(glm::u64, 3)
+ static_swizzle2_ref(glm::u64, 4)
+
+ static_swizzle3_ref(glm::f16, 3)
+ static_swizzle3_ref(glm::f16, 4)
+ static_swizzle3_ref(glm::f32, 3)
+ static_swizzle3_ref(glm::f32, 4)
+ static_swizzle3_ref(glm::f64, 3)
+ static_swizzle3_ref(glm::f64, 4)
+
+ static_swizzle3_ref(glm::i8, 3)
+ static_swizzle3_ref(glm::i8, 4)
+ static_swizzle3_ref(glm::i16, 3)
+ static_swizzle3_ref(glm::i16, 4)
+ static_swizzle3_ref(glm::i32, 3)
+ static_swizzle3_ref(glm::i32, 4)
+ static_swizzle3_ref(glm::i64, 3)
+ static_swizzle3_ref(glm::i64, 4)
+
+ static_swizzle3_ref(glm::u8, 3)
+ static_swizzle3_ref(glm::u8, 4)
+ static_swizzle3_ref(glm::u16, 3)
+ static_swizzle3_ref(glm::u16, 4)
+ static_swizzle3_ref(glm::u32, 3)
+ static_swizzle3_ref(glm::u32, 4)
+ static_swizzle3_ref(glm::u64, 3)
+ static_swizzle3_ref(glm::u64, 4)
+
+ static_swizzle4_ref(glm::f16, 4)
+ static_swizzle4_ref(glm::f32, 4)
+ static_swizzle4_ref(glm::f64, 4)
+
+ static_swizzle4_ref(glm::i8, 4)
+ static_swizzle4_ref(glm::i16, 4)
+ static_swizzle4_ref(glm::i32, 4)
+ static_swizzle4_ref(glm::i64, 4)
+
+ static_swizzle4_ref(glm::u8, 4)
+ static_swizzle4_ref(glm::u16, 4)
+ static_swizzle4_ref(glm::u32, 4)
+ static_swizzle4_ref(glm::u64, 4)
+
+}//namespace swizzle
+}//namespace gtc
+}//namespace glm
+
+#include "swizzle.inl"
+
+namespace glm{using namespace gtc::swizzle;}
+
+#endif//glm_gtc_swizzle
diff --git a/src/glm/gtc/swizzle.inl b/src/glm/gtc/swizzle.inl
new file mode 100644
index 0000000..77f1a50
--- /dev/null
+++ b/src/glm/gtc/swizzle.inl
@@ -0,0 +1,177 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2011-01-15
+// Updated : 2011-01-15
+// Licence : This source is under MIT License
+// File : glm/gtc/swizzle.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm{
+namespace gtc{
+namespace swizzle{
+
+template <typename T, template <typename> class vecType>
+GLM_FUNC_QUALIFIER T swizzle
+(
+ vecType<T> const & v,
+ comp x
+)
+{
+ assert(int(x) < int(vecType<T>::value_size));
+ return v[x];
+}
+
+template <typename T, template <typename> class vecType>
+GLM_FUNC_QUALIFIER detail::tvec2<T> swizzle
+(
+ vecType<T> const & v,
+ comp x, comp y
+)
+{
+ return detail::tvec2<T>(
+ v[x],
+ v[y]);
+}
+
+template <typename T, template <typename> class vecType>
+GLM_FUNC_QUALIFIER detail::tvec3<T> swizzle
+(
+ vecType<T> const & v,
+ comp x, comp y, comp z
+)
+{
+ return detail::tvec3<T>(
+ v[x],
+ v[y],
+ v[z]);
+}
+
+template <typename T, template <typename> class vecType>
+GLM_FUNC_QUALIFIER detail::tvec4<T> swizzle
+(
+ vecType<T> const & v,
+ comp x, comp y, comp z, comp w
+)
+{
+ return detail::tvec4<T>(v[x], v[y], v[z], v[w]);
+}
+
+template <typename T>
+GLM_FUNC_QUALIFIER T& swizzle
+(
+ detail::tvec4<T> & v,
+ comp x
+)
+{
+ return v[x];
+}
+
+template <typename T>
+GLM_FUNC_QUALIFIER detail::tref2<T> swizzle
+(
+ detail::tvec4<T> & v,
+ comp x, comp y
+)
+{
+ return detail::tref2<T>(v[x], v[y]);
+}
+
+template <typename T>
+GLM_FUNC_QUALIFIER detail::tref3<T> swizzle
+(
+ detail::tvec4<T> & v,
+ comp x, comp y, comp z
+)
+{
+ return detail::tref3<T>(v[x], v[y], v[z]);
+}
+
+template <typename T>
+GLM_FUNC_QUALIFIER detail::tref4<T> swizzle
+(
+ detail::tvec4<T> & v,
+ comp x, comp y, comp z, comp w
+)
+{
+ return detail::tref4<T>(v[x], v[y], v[z], v[w]);
+}
+/*
+template <comp x>
+GLM_FUNC_QUALIFIER float& swizzle
+(
+ detail::tvec4<float> & v
+)
+{
+ return v[x];
+}
+
+template <comp x>
+GLM_FUNC_QUALIFIER int& swizzle
+(
+ detail::tvec4<int> & v
+)
+{
+ return v[x];
+}
+
+template <comp x, comp y>
+GLM_FUNC_QUALIFIER detail::tref2<float> swizzle
+(
+ detail::tvec4<float> & v
+)
+{
+ return detail::tref2<float>(v[x], v[y]);
+}
+
+template <comp x, comp y>
+GLM_FUNC_QUALIFIER detail::tref2<int> swizzle
+(
+ detail::tvec4<int> & v
+)
+{
+ return detail::tref2<int>(v[x], v[y]);
+}
+
+template <comp x, comp y, comp z>
+GLM_FUNC_QUALIFIER detail::tref3<float> swizzle
+(
+ detail::tvec4<float> & v
+)
+{
+ return detail::tref3<float>(v[x], v[y], v[z]);
+}
+
+template <comp x, comp y, comp z>
+GLM_FUNC_QUALIFIER detail::tref3<int> swizzle
+(
+ detail::tvec4<int> & v
+)
+{
+ return detail::tref3<int>(v[x], v[y], v[z]);
+}
+
+template <comp x, comp y, comp z, comp w>
+GLM_FUNC_QUALIFIER detail::tref4<float> swizzle
+(
+ detail::tvec4<float> & v
+)
+{
+ return detail::tref4<float>(v[x], v[y], v[z], v[w]);
+}
+
+template <comp x, comp y, comp z, comp w>
+GLM_FUNC_QUALIFIER detail::tref4<int> swizzle
+(
+ detail::tvec4<int> & v
+)
+{
+ return detail::tref4<int>(v[x], v[y], v[z], v[w]);
+}
+*/
+}//namespace swizzle
+}//namespace gtc
+}//namespace glm
diff --git a/src/glm/gtc/type_precision.hpp b/src/glm/gtc/type_precision.hpp
new file mode 100644
index 0000000..41e411b
--- /dev/null
+++ b/src/glm/gtc/type_precision.hpp
@@ -0,0 +1,220 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2009-06-04
+// Updated : 2009-06-04
+// Licence : This source is under MIT License
+// File : glm/gtc/type_precision.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+// - GLM_GTC_half
+// - GLM_GTC_quaternion
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_gtc_type_precision
+#define glm_gtc_type_precision
+
+// Dependency:
+#include "../glm.hpp"
+#include "../gtc/half_float.hpp"
+#include "../gtc/quaternion.hpp"
+
+#if(defined(GLM_MESSAGES) && !defined(glm_ext))
+# pragma message("GLM: GLM_GTC_type_precision extension included")
+#endif
+
+namespace glm{
+namespace gtc{
+namespace type_precision ///< GLM_GTC_type_precision extension: Defined types with specific size.
+{
+ ///////////////////////////
+ // Dependences
+
+ using namespace gtc::half_float;
+ using namespace gtc::quaternion;
+
+ ///////////////////////////
+ // Signed int vector types
+
+ /// \addtogroup gtc_type_precision
+ ///@{
+
+ typedef detail::int8 int8; //!< \brief 8bit signed integer. (from GLM_GTC_type_precision extension)
+ typedef detail::int16 int16; //!< \brief 16bit signed integer. (from GLM_GTC_type_precision extension)
+ typedef detail::int32 int32; //!< \brief 32bit signed integer. (from GLM_GTC_type_precision extension)
+ typedef detail::int64 int64; //!< \brief 64bit signed integer. (from GLM_GTC_type_precision extension)
+
+ typedef int8 i8; //!< \brief 8bit signed integer. (from GLM_GTC_type_precision extension)
+ typedef int16 i16; //!< \brief 16bit signed integer. (from GLM_GTC_type_precision extension)
+ typedef int32 i32; //!< \brief 32bit signed integer. (from GLM_GTC_type_precision extension)
+ typedef int64 i64; //!< \brief 64bit signed integer. (from GLM_GTC_type_precision extension)
+
+ //typedef i8 i8vec1; //!< \brief 8bit signed integer scalar. (from GLM_GTC_type_precision extension)
+ typedef detail::tvec2<i8> i8vec2; //!< \brief 8bit signed integer vector of 2 components. (from GLM_GTC_type_precision extension)
+ typedef detail::tvec3<i8> i8vec3; //!< \brief 8bit signed integer vector of 3 components. (from GLM_GTC_type_precision extension)
+ typedef detail::tvec4<i8> i8vec4; //!< \brief 8bit signed integer vector of 4 components. (from GLM_GTC_type_precision extension)
+
+ //typedef i16 i16vec1; //!< \brief 16bit signed integer scalar. (from GLM_GTC_type_precision extension)
+ typedef detail::tvec2<i16> i16vec2; //!< \brief 16bit signed integer vector of 2 components. (from GLM_GTC_type_precision extension)
+ typedef detail::tvec3<i16> i16vec3; //!< \brief 16bit signed integer vector of 3 components. (from GLM_GTC_type_precision extension)
+ typedef detail::tvec4<i16> i16vec4; //!< \brief 16bit signed integer vector of 4 components. (from GLM_GTC_type_precision extension)
+
+ //typedef i32 i32vec1; //!< \brief 32bit signed integer scalar. (from GLM_GTC_type_precision extension)
+ typedef detail::tvec2<i32> i32vec2; //!< \brief 32bit signed integer vector of 2 components. (from GLM_GTC_type_precision extension)
+ typedef detail::tvec3<i32> i32vec3; //!< \brief 32bit signed integer vector of 3 components. (from GLM_GTC_type_precision extension)
+ typedef detail::tvec4<i32> i32vec4; //!< \brief 32bit signed integer vector of 4 components. (from GLM_GTC_type_precision extension)
+
+ //typedef i64 i64vec1; //!< \brief 32bit signed integer scalar. (from GLM_GTC_type_precision extension)
+ typedef detail::tvec2<i64> i64vec2; //!< \brief 64bit signed integer vector of 2 components. (from GLM_GTC_type_precision extension)
+ typedef detail::tvec3<i64> i64vec3; //!< \brief 64bit signed integer vector of 3 components. (from GLM_GTC_type_precision extension)
+ typedef detail::tvec4<i64> i64vec4; //!< \brief 64bit signed integer vector of 4 components. (from GLM_GTC_type_precision extension)
+
+ /////////////////////////////
+ // Unsigned int vector types
+
+ typedef detail::uint8 uint8; //!< \brief 8bit unsigned integer. (from GLM_GTC_type_precision extension)
+ typedef detail::uint16 uint16; //!< \brief 16bit unsigned integer. (from GLM_GTC_type_precision extension)
+ typedef detail::uint32 uint32; //!< \brief 32bit unsigned integer. (from GLM_GTC_type_precision extension)
+ typedef detail::uint64 uint64; //!< \brief 64bit unsigned integer. (from GLM_GTC_type_precision extension)
+
+ typedef uint8 u8; //!< \brief 8bit unsigned integer. (from GLM_GTC_type_precision extension)
+ typedef uint16 u16; //!< \brief 16bit unsigned integer. (from GLM_GTC_type_precision extension)
+ typedef uint32 u32; //!< \brief 32bit unsigned integer. (from GLM_GTC_type_precision extension)
+ typedef uint64 u64; //!< \brief 64bit unsigned integer. (from GLM_GTC_type_precision extension)
+
+ //typedef u8 u8vec1; //!< \brief 8bit unsigned integer scalar. (from GLM_GTC_type_precision extension)
+ typedef detail::tvec2<u8> u8vec2; //!< \brief 8bit unsigned integer vector of 2 components. (from GLM_GTC_type_precision extension)
+ typedef detail::tvec3<u8> u8vec3; //!< \brief 8bit unsigned integer vector of 3 components. (from GLM_GTC_type_precision extension)
+ typedef detail::tvec4<u8> u8vec4; //!< \brief 8bit unsigned integer vector of 4 components. (from GLM_GTC_type_precision extension)
+
+ //typedef u16 u16vec1; //!< \brief 16bit unsigned integer scalar. (from GLM_GTC_type_precision extension)
+ typedef detail::tvec2<u16> u16vec2; //!< \brief 16bit unsigned integer vector of 2 components. (from GLM_GTC_type_precision extension)
+ typedef detail::tvec3<u16> u16vec3; //!< \brief 16bit unsigned integer vector of 3 components. (from GLM_GTC_type_precision extension)
+ typedef detail::tvec4<u16> u16vec4; //!< \brief 16bit unsigned integer vector of 4 components. (from GLM_GTC_type_precision extension)
+
+ //typedef u32 u32vec1; //!< \brief 32bit unsigned integer scalar. (from GLM_GTC_type_precision extension)
+ typedef detail::tvec2<u32> u32vec2; //!< \brief 32bit unsigned integer vector of 2 components. (from GLM_GTC_type_precision extension)
+ typedef detail::tvec3<u32> u32vec3; //!< \brief 32bit unsigned integer vector of 3 components. (from GLM_GTC_type_precision extension)
+ typedef detail::tvec4<u32> u32vec4; //!< \brief 32bit unsigned integer vector of 4 components. (from GLM_GTC_type_precision extension)
+
+ //typedef u64 u64vec1; //!< \brief 64bit unsigned integer scalar. (from GLM_GTC_type_precision extension)
+ typedef detail::tvec2<u64> u64vec2; //!< \brief 64bit unsigned integer vector of 2 components. (from GLM_GTC_type_precision extension)
+ typedef detail::tvec3<u64> u64vec3; //!< \brief 64bit unsigned integer vector of 3 components. (from GLM_GTC_type_precision extension)
+ typedef detail::tvec4<u64> u64vec4; //!< \brief 64bit unsigned integer vector of 4 components. (from GLM_GTC_type_precision extension)
+
+ //////////////////////
+ // Float vector types
+
+ typedef detail::float16 float16; //!< \brief Half-precision floating-point scalar. (from GLM_GTC_type_precision extension)
+ typedef detail::float32 float32; //!< \brief Single-precision floating-point scalar. (from GLM_GTC_type_precision extension)
+ typedef detail::float64 float64; //!< \brief Double-precision floating-point scalar. (from GLM_GTC_type_precision extension)
+
+ typedef float16 f16; //!< \brief Half-precision floating-point scalar. (from GLM_GTC_type_precision extension)
+ typedef float32 f32; //!< \brief Single-precision floating-point scalar. (from GLM_GTC_type_precision extension)
+ typedef float64 f64; //!< \brief Double-precision floating-point scalar. (from GLM_GTC_type_precision extension)
+
+ typedef detail::tvec2<float> fvec2; //!< Vector of 2 single-precision floating-point numbers. (from GLM_GTC_type_precision extension)
+ typedef detail::tvec3<float> fvec3; //!< Vector of 3 single-precision floating-point numbers. (from GLM_GTC_type_precision extension)
+ typedef detail::tvec4<float> fvec4; //!< Vector of 4 single-precision floating-point numbers. (from GLM_GTC_type_precision extension)
+
+ //typedef f16 f16vec1; //!< \brief Half-precision floating-point scalar. (from GLM_GTC_type_precision extension)
+ typedef detail::tvec2<f16> f16vec2; //!< \brief Half-precision floating-point vector of 2 components. (from GLM_GTC_type_precision extension)
+ typedef detail::tvec3<f16> f16vec3; //!< \brief Half-precision floating-point vector of 3 components. (from GLM_GTC_type_precision extension)
+ typedef detail::tvec4<f16> f16vec4; //!< \brief Half-precision floating-point vector of 4 components. (from GLM_GTC_type_precision extension)
+
+ //typedef f32 f32vec1; //!< \brief Single-precision floating-point scalar. (from GLM_GTC_type_precision extension)
+ typedef detail::tvec2<f32> f32vec2; //!< \brief Single-precision floating-point vector of 2 components. (from GLM_GTC_type_precision extension)
+ typedef detail::tvec3<f32> f32vec3; //!< \brief Single-precision floating-point vector of 3 components. (from GLM_GTC_type_precision extension)
+ typedef detail::tvec4<f32> f32vec4; //!< \brief Single-precision floating-point vector of 4 components. (from GLM_GTC_type_precision extension)
+
+ //typedef f64 f64vec1; //!< \brief Single-precision floating-point scalar. (from GLM_GTC_type_precision extension)
+ typedef detail::tvec2<f64> f64vec2; //!< \brief Double-precision floating-point vector of 2 components. (from GLM_GTC_type_precision extension)
+ typedef detail::tvec3<f64> f64vec3; //!< \brief Double-precision floating-point vector of 3 components. (from GLM_GTC_type_precision extension)
+ typedef detail::tvec4<f64> f64vec4; //!< \brief Double-precision floating-point vector of 4 components. (from GLM_GTC_type_precision extension)
+
+ //////////////////////
+ // Float matrix types
+
+ //typedef f32 fmat1; //!< \brief Single-precision floating-point scalar. (from GLM_GTC_type_precision extension)
+ typedef detail::tmat2x2<f32> fmat2; //!< \brief Single-precision floating-point 2x2 matrix. (from GLM_GTC_type_precision extension)
+ typedef detail::tmat3x3<f32> fmat3; //!< \brief Single-precision floating-point 3x3 matrix. (from GLM_GTC_type_precision extension)
+ typedef detail::tmat4x4<f32> fmat4; //!< \brief Single-precision floating-point 4x4 matrix. (from GLM_GTC_type_precision extension)
+
+ //typedef f32 fmat1x1; //!< \brief Single-precision floating-point scalar. (from GLM_GTC_type_precision extension)
+ typedef detail::tmat2x2<f32> fmat2x2; //!< \brief Single-precision floating-point 2x2 matrix. (from GLM_GTC_type_precision extension)
+ typedef detail::tmat2x3<f32> fmat2x3; //!< \brief Single-precision floating-point 2x3 matrix. (from GLM_GTC_type_precision extension)
+ typedef detail::tmat2x4<f32> fmat2x4; //!< \brief Single-precision floating-point 2x4 matrix. (from GLM_GTC_type_precision extension)
+ typedef detail::tmat3x2<f32> fmat3x2; //!< \brief Single-precision floating-point 3x2 matrix. (from GLM_GTC_type_precision extension)
+ typedef detail::tmat3x3<f32> fmat3x3; //!< \brief Single-precision floating-point 3x3 matrix. (from GLM_GTC_type_precision extension)
+ typedef detail::tmat3x4<f32> fmat3x4; //!< \brief Single-precision floating-point 3x4 matrix. (from GLM_GTC_type_precision extension)
+ typedef detail::tmat4x2<f32> fmat4x2; //!< \brief Single-precision floating-point 4x2 matrix. (from GLM_GTC_type_precision extension)
+ typedef detail::tmat4x3<f32> fmat4x3; //!< \brief Single-precision floating-point 4x3 matrix. (from GLM_GTC_type_precision extension)
+ typedef detail::tmat4x4<f32> fmat4x4; //!< \brief Single-precision floating-point 4x4 matrix. (from GLM_GTC_type_precision extension)
+
+ //typedef f16 f16mat1; //!< \brief Half-precision floating-point scalar. (from GLM_GTC_type_precision extension)
+ typedef detail::tmat2x2<f16> f16mat2; //!< \brief Half-precision floating-point 2x2 matrix. (from GLM_GTC_type_precision extension)
+ typedef detail::tmat3x3<f16> f16mat3; //!< \brief Half-precision floating-point 3x3 matrix. (from GLM_GTC_type_precision extension)
+ typedef detail::tmat4x4<f16> f16mat4; //!< \brief Half-precision floating-point 4x4 matrix. (from GLM_GTC_type_precision extension)
+
+ //typedef f16 f16mat1x1; //!< \brief Half-precision floating-point scalar. (from GLM_GTC_type_precision extension)
+ typedef detail::tmat2x2<f16> f16mat2x2; //!< \brief Half-precision floating-point 2x2 matrix. (from GLM_GTC_type_precision extension)
+ typedef detail::tmat2x3<f16> f16mat2x3; //!< \brief Half-precision floating-point 2x3 matrix. (from GLM_GTC_type_precision extension)
+ typedef detail::tmat2x4<f16> f16mat2x4; //!< \brief Half-precision floating-point 2x4 matrix. (from GLM_GTC_type_precision extension)
+ typedef detail::tmat3x2<f16> f16mat3x2; //!< \brief Half-precision floating-point 3x2 matrix. (from GLM_GTC_type_precision extension)
+ typedef detail::tmat3x3<f16> f16mat3x3; //!< \brief Half-precision floating-point 3x3 matrix. (from GLM_GTC_type_precision extension)
+ typedef detail::tmat3x4<f16> f16mat3x4; //!< \brief Half-precision floating-point 3x4 matrix. (from GLM_GTC_type_precision extension)
+ typedef detail::tmat4x2<f16> f16mat4x2; //!< \brief Half-precision floating-point 4x2 matrix. (from GLM_GTC_type_precision extension)
+ typedef detail::tmat4x3<f16> f16mat4x3; //!< \brief Half-precision floating-point 4x3 matrix. (from GLM_GTC_type_precision extension)
+ typedef detail::tmat4x4<f16> f16mat4x4; //!< \brief Half-precision floating-point 4x4 matrix. (from GLM_GTC_type_precision extension)
+
+ //typedef f32 f32mat1; //!< \brief Single-precision floating-point scalar. (from GLM_GTC_type_precision extension)
+ typedef detail::tmat2x2<f32> f32mat2; //!< \brief Single-precision floating-point 2x2 matrix. (from GLM_GTC_type_precision extension)
+ typedef detail::tmat3x3<f32> f32mat3; //!< \brief Single-precision floating-point 3x3 matrix. (from GLM_GTC_type_precision extension)
+ typedef detail::tmat4x4<f32> f32mat4; //!< \brief Single-precision floating-point 4x4 matrix. (from GLM_GTC_type_precision extension)
+
+ //typedef f32 f32mat1x1; //!< \brief Single-precision floating-point scalar. (from GLM_GTC_type_precision extension)
+ typedef detail::tmat2x2<f32> f32mat2x2; //!< \brief Single-precision floating-point 2x2 matrix. (from GLM_GTC_type_precision extension)
+ typedef detail::tmat2x3<f32> f32mat2x3; //!< \brief Single-precision floating-point 2x3 matrix. (from GLM_GTC_type_precision extension)
+ typedef detail::tmat2x4<f32> f32mat2x4; //!< \brief Single-precision floating-point 2x4 matrix. (from GLM_GTC_type_precision extension)
+ typedef detail::tmat3x2<f32> f32mat3x2; //!< \brief Single-precision floating-point 3x2 matrix. (from GLM_GTC_type_precision extension)
+ typedef detail::tmat3x3<f32> f32mat3x3; //!< \brief Single-precision floating-point 3x3 matrix. (from GLM_GTC_type_precision extension)
+ typedef detail::tmat3x4<f32> f32mat3x4; //!< \brief Single-precision floating-point 3x4 matrix. (from GLM_GTC_type_precision extension)
+ typedef detail::tmat4x2<f32> f32mat4x2; //!< \brief Single-precision floating-point 4x2 matrix. (from GLM_GTC_type_precision extension)
+ typedef detail::tmat4x3<f32> f32mat4x3; //!< \brief Single-precision floating-point 4x3 matrix. (from GLM_GTC_type_precision extension)
+ typedef detail::tmat4x4<f32> f32mat4x4; //!< \brief Single-precision floating-point 4x4 matrix. (from GLM_GTC_type_precision extension)
+
+ //typedef f64 f64mat1; //!< \brief Double-precision floating-point scalar. (from GLM_GTC_type_precision extension)
+ typedef detail::tmat2x2<f64> f64mat2; //!< \brief Double-precision floating-point 2x2 matrix. (from GLM_GTC_type_precision extension)
+ typedef detail::tmat3x3<f64> f64mat3; //!< \brief Double-precision floating-point 3x3 matrix. (from GLM_GTC_type_precision extension)
+ typedef detail::tmat4x4<f64> f64mat4; //!< \brief Double-precision floating-point 4x4 matrix. (from GLM_GTC_type_precision extension)
+
+ //typedef f64 f64mat1x1; //!< \brief Double-precision floating-point scalar. (from GLM_GTC_type_precision extension)
+ typedef detail::tmat2x2<f64> f64mat2x2; //!< \brief Double-precision floating-point 2x2 matrix. (from GLM_GTC_type_precision extension)
+ typedef detail::tmat2x3<f64> f64mat2x3; //!< \brief Double-precision floating-point 2x3 matrix. (from GLM_GTC_type_precision extension)
+ typedef detail::tmat2x4<f64> f64mat2x4; //!< \brief Double-precision floating-point 2x4 matrix. (from GLM_GTC_type_precision extension)
+ typedef detail::tmat3x2<f64> f64mat3x2; //!< \brief Double-precision floating-point 3x2 matrix. (from GLM_GTC_type_precision extension)
+ typedef detail::tmat3x3<f64> f64mat3x3; //!< \brief Double-precision floating-point 3x3 matrix. (from GLM_GTC_type_precision extension)
+ typedef detail::tmat3x4<f64> f64mat3x4; //!< \brief Double-precision floating-point 3x4 matrix. (from GLM_GTC_type_precision extension)
+ typedef detail::tmat4x2<f64> f64mat4x2; //!< \brief Double-precision floating-point 4x2 matrix. (from GLM_GTC_type_precision extension)
+ typedef detail::tmat4x3<f64> f64mat4x3; //!< \brief Double-precision floating-point 4x3 matrix. (from GLM_GTC_type_precision extension)
+ typedef detail::tmat4x4<f64> f64mat4x4; //!< \brief Double-precision floating-point 4x4 matrix. (from GLM_GTC_type_precision extension)
+
+ //////////////////////////
+ // Float quaternion types
+
+ typedef detail::tquat<f16> f16quat; //!< \brief Half-precision floating-point quaternion. (from GLM_GTC_type_precision extension)
+ typedef detail::tquat<f32> f32quat; //!< \brief Single-precision floating-point quaternion. (from GLM_GTC_type_precision extension)
+ typedef detail::tquat<f64> f64quat; //!< \brief Double-precision floating-point quaternion. (from GLM_GTC_type_precision extension)
+
+ ///@}
+
+}//namespace type_precision
+}//namespace gtc
+}//namespace glm
+
+#include "type_precision.inl"
+
+namespace glm{using namespace gtc::type_precision;}
+
+#endif//glm_gtc_type_precision
diff --git a/src/glm/gtc/type_precision.inl b/src/glm/gtc/type_precision.inl
new file mode 100644
index 0000000..b0ec53b
--- /dev/null
+++ b/src/glm/gtc/type_precision.inl
@@ -0,0 +1,13 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2009-06-14
+// Updated : 2009-06-14
+// Licence : This source is under MIT License
+// File : glm/gtc/type_precision.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm
+{
+
+}
diff --git a/src/glm/gtc/type_ptr.hpp b/src/glm/gtc/type_ptr.hpp
new file mode 100644
index 0000000..15ef009
--- /dev/null
+++ b/src/glm/gtc/type_ptr.hpp
@@ -0,0 +1,449 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2009-05-06
+// Updated : 2010-04-30
+// Licence : This source is under MIT License
+// File : glm/gtc/type_ptr.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_gtc_type_ptr
+#define glm_gtc_type_ptr
+
+// Dependency:
+#include "../glm.hpp"
+#include <cstring>
+
+#if(defined(GLM_MESSAGES) && !defined(glm_ext))
+# pragma message("GLM: GLM_GTC_type_ptr extension included")
+#endif
+
+namespace glm{
+namespace gtc{
+namespace type_ptr ///< GLM_GTC_type_ptr extension: Get access to vectors & matrices value type address.
+{
+
+ /// \addtogroup gtc_type_ptr
+ ///@{
+
+ //! Get the const address of the vector content.
+ //! From GLM_GTC_type_ptr extension.
+ template<typename T>
+ GLM_FUNC_QUALIFIER T const * value_ptr
+ (
+ detail::tvec2<T> const & vec
+ )
+ {
+ return &(vec.x);
+ }
+
+ //! Get the address of the vector content.
+ //! From GLM_GTC_type_ptr extension.
+ template<typename T>
+ GLM_FUNC_QUALIFIER T * value_ptr
+ (
+ detail::tvec2<T> & vec
+ )
+ {
+ return &(vec.x);
+ }
+
+ //! Get the const address of the vector content.
+ //! From GLM_GTC_type_ptr extension.
+ template<typename T>
+ GLM_FUNC_QUALIFIER T const * value_ptr
+ (
+ detail::tvec3<T> const & vec
+ )
+ {
+ return &(vec.x);
+ }
+
+ //! Get the address of the vector content.
+ //! From GLM_GTC_type_ptr extension.
+ template<typename T>
+ GLM_FUNC_QUALIFIER T * value_ptr
+ (
+ detail::tvec3<T> & vec
+ )
+ {
+ return &(vec.x);
+ }
+
+ //! Get the const address of the vector content.
+ //! From GLM_GTC_type_ptr extension.
+ template<typename T>
+ GLM_FUNC_QUALIFIER T const * value_ptr
+ (
+ detail::tvec4<T> const & vec
+ )
+ {
+ return &(vec.x);
+ }
+
+ //! Get the address of the vector content.
+ //! From GLM_GTC_type_ptr extension.
+ template<typename T>
+ GLM_FUNC_QUALIFIER T * value_ptr
+ (
+ detail::tvec4<T> & vec
+ )
+ {
+ return &(vec.x);
+ }
+
+ //! Get the const address of the matrix content.
+ //! From GLM_GTC_type_ptr extension.
+ template<typename T>
+ GLM_FUNC_QUALIFIER T const * value_ptr
+ (
+ detail::tmat2x2<T> const & mat
+ )
+ {
+ return &(mat[0].x);
+ }
+
+ //! Get the address of the matrix content.
+ //! From GLM_GTC_type_ptr extension.
+ template<typename T>
+ GLM_FUNC_QUALIFIER T * value_ptr
+ (
+ detail::tmat2x2<T> & mat
+ )
+ {
+ return &(mat[0].x);
+ }
+
+ //! Get the const address of the matrix content.
+ //! From GLM_GTC_type_ptr extension.
+ template<typename T>
+ GLM_FUNC_QUALIFIER T const * value_ptr
+ (
+ detail::tmat3x3<T> const & mat
+ )
+ {
+ return &(mat[0].x);
+ }
+
+ //! Get the address of the matrix content.
+ //! From GLM_GTC_type_ptr extension.
+ template<typename T>
+ GLM_FUNC_QUALIFIER T * value_ptr
+ (
+ detail::tmat3x3<T> & mat
+ )
+ {
+ return &(mat[0].x);
+ }
+
+ //! Get the const address of the matrix content.
+ //! From GLM_GTC_type_ptr extension.
+ template<typename T>
+ GLM_FUNC_QUALIFIER T const * value_ptr
+ (
+ detail::tmat4x4<T> const & mat
+ )
+ {
+ return &(mat[0].x);
+ }
+
+ //! Get the address of the matrix content.
+ //! From GLM_GTC_type_ptr extension.
+ template<typename T>
+ GLM_FUNC_QUALIFIER T * value_ptr
+ (
+ detail::tmat4x4<T> & mat
+ )
+ {
+ return &(mat[0].x);
+ }
+
+ //! Get the const address of the matrix content.
+ //! From GLM_GTC_type_ptr extension.
+ template<typename T>
+ GLM_FUNC_QUALIFIER T const * value_ptr
+ (
+ detail::tmat2x3<T> const & mat
+ )
+ {
+ return &(mat[0].x);
+ }
+
+ //! Get the address of the matrix content.
+ //! From GLM_GTC_type_ptr extension.
+ template<typename T>
+ GLM_FUNC_QUALIFIER T * value_ptr
+ (
+ detail::tmat2x3<T> & mat
+ )
+ {
+ return &(mat[0].x);
+ }
+
+ //! Get the const address of the matrix content.
+ //! From GLM_GTC_type_ptr extension.
+ template<typename T>
+ GLM_FUNC_QUALIFIER T const * value_ptr
+ (
+ detail::tmat3x2<T> const & mat
+ )
+ {
+ return &(mat[0].x);
+ }
+
+ //! Get the address of the matrix content.
+ //! From GLM_GTC_type_ptr extension.
+ template<typename T>
+ GLM_FUNC_QUALIFIER T * value_ptr
+ (
+ detail::tmat3x2<T> & mat
+ )
+ {
+ return &(mat[0].x);
+ }
+
+ //! Get the const address of the matrix content.
+ //! From GLM_GTC_type_ptr extension.
+ template<typename T>
+ GLM_FUNC_QUALIFIER T const * value_ptr
+ (
+ detail::tmat2x4<T> const & mat
+ )
+ {
+ return &(mat[0].x);
+ }
+
+ //! Get the address of the matrix content.
+ //! From GLM_GTC_type_ptr extension.
+ template<typename T>
+ GLM_FUNC_QUALIFIER T * value_ptr
+ (
+ detail::tmat2x4<T> & mat
+ )
+ {
+ return &(mat[0].x);
+ }
+
+ //! Get the const address of the matrix content.
+ //! From GLM_GTC_type_ptr extension.
+ template<typename T>
+ GLM_FUNC_QUALIFIER T const * value_ptr
+ (
+ detail::tmat4x2<T> const & mat
+ )
+ {
+ return &(mat[0].x);
+ }
+
+ //! Get the address of the matrix content.
+ //! From GLM_GTC_type_ptr extension.
+ template<typename T>
+ GLM_FUNC_QUALIFIER T * value_ptr
+ (
+ detail::tmat4x2<T> & mat
+ )
+ {
+ return &(mat[0].x);
+ }
+
+ //! Get the const address of the matrix content.
+ //! From GLM_GTC_type_ptr extension.
+ template<typename T>
+ GLM_FUNC_QUALIFIER T const * value_ptr
+ (
+ detail::tmat3x4<T> const & mat
+ )
+ {
+ return &(mat[0].x);
+ }
+
+ //! Get the address of the matrix content.
+ //! From GLM_GTC_type_ptr extension.
+ template<typename T>
+ GLM_FUNC_QUALIFIER T * value_ptr
+ (
+ detail::tmat3x4<T> & mat
+ )
+ {
+ return &(mat[0].x);
+ }
+
+ //! Get the const address of the matrix content.
+ //! From GLM_GTC_type_ptr extension.
+ template<typename T>
+ GLM_FUNC_QUALIFIER T const * value_ptr
+ (
+ detail::tmat4x3<T> const & mat
+ )
+ {
+ return &(mat[0].x);
+ }
+
+ //! Get the address of the matrix content.
+ //! From GLM_GTC_type_ptr extension.
+ template<typename T>
+ GLM_FUNC_QUALIFIER T * value_ptr(detail::tmat4x3<T> & mat)
+ {
+ return &(mat[0].x);
+ }
+
+ //! Build a vector from a pointer.
+ //! From GLM_GTC_type_ptr extension.
+ template<typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<T> make_vec2(T const * const ptr)
+ {
+ detail::tvec2<T> Result;
+ memcpy(value_ptr(Result), ptr, sizeof(detail::tvec2<T>));
+ return Result;
+ }
+
+ //! Build a vector from a pointer.
+ //! From GLM_GTC_type_ptr extension.
+ template<typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> make_vec3(T const * const ptr)
+ {
+ detail::tvec3<T> Result;
+ memcpy(value_ptr(Result), ptr, sizeof(detail::tvec3<T>));
+ return Result;
+ }
+
+ //! Build a vector from a pointer.
+ //! From GLM_GTC_type_ptr extension.
+ template<typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<T> make_vec4(T const * const ptr)
+ {
+ detail::tvec4<T> Result;
+ memcpy(value_ptr(Result), ptr, sizeof(detail::tvec4<T>));
+ return Result;
+ }
+
+ //! Build a matrix from a pointer.
+ //! From GLM_GTC_type_ptr extension.
+ template<typename T>
+ GLM_FUNC_QUALIFIER detail::tmat2x2<T> make_mat2x2(T const * const ptr)
+ {
+ detail::tmat2x2<T> Result;
+ memcpy(value_ptr(Result), ptr, sizeof(detail::tmat2x2<T>));
+ return Result;
+ }
+
+ //! Build a matrix from a pointer.
+ //! From GLM_GTC_type_ptr extension.
+ template<typename T>
+ GLM_FUNC_QUALIFIER detail::tmat2x3<T> make_mat2x3(T const * const ptr)
+ {
+ detail::tmat2x3<T> Result;
+ memcpy(value_ptr(Result), ptr, sizeof(detail::tmat2x3<T>));
+ return Result;
+ }
+
+ //! Build a matrix from a pointer.
+ //! From GLM_GTC_type_ptr extension.
+ template<typename T>
+ GLM_FUNC_QUALIFIER detail::tmat2x4<T> make_mat2x4(T const * const ptr)
+ {
+ detail::tmat2x4<T> Result;
+ memcpy(value_ptr(Result), ptr, sizeof(detail::tmat2x4<T>));
+ return Result;
+ }
+
+ //! Build a matrix from a pointer.
+ //! From GLM_GTC_type_ptr extension.
+ template<typename T>
+ GLM_FUNC_QUALIFIER detail::tmat3x2<T> make_mat3x2(T const * const ptr)
+ {
+ detail::tmat3x2<T> Result;
+ memcpy(value_ptr(Result), ptr, sizeof(detail::tmat3x2<T>));
+ return Result;
+ }
+
+ //! Build a matrix from a pointer.
+ //! From GLM_GTC_type_ptr extension.
+ template<typename T>
+ GLM_FUNC_QUALIFIER detail::tmat3x3<T> make_mat3x3(T const * const ptr)
+ {
+ detail::tmat3x3<T> Result;
+ memcpy(value_ptr(Result), ptr, sizeof(detail::tmat3x3<T>));
+ return Result;
+ }
+
+ //! Build a matrix from a pointer.
+ //! From GLM_GTC_type_ptr extension.
+ template<typename T>
+ GLM_FUNC_QUALIFIER detail::tmat3x4<T> make_mat3x4(T const * const ptr)
+ {
+ detail::tmat3x4<T> Result;
+ memcpy(value_ptr(Result), ptr, sizeof(detail::tmat3x4<T>));
+ return Result;
+ }
+
+
+ //! Build a matrix from a pointer.
+ //! From GLM_GTC_type_ptr extension.
+ template<typename T>
+ GLM_FUNC_QUALIFIER detail::tmat4x2<T> make_mat4x2(T const * const ptr)
+ {
+ detail::tmat4x2<T> Result;
+ memcpy(value_ptr(Result), ptr, sizeof(detail::tmat4x2<T>));
+ return Result;
+ }
+
+ //! Build a matrix from a pointer.
+ //! From GLM_GTC_type_ptr extension.
+ template<typename T>
+ GLM_FUNC_QUALIFIER detail::tmat4x3<T> make_mat4x3(T const * const ptr)
+ {
+ detail::tmat4x3<T> Result;
+ memcpy(value_ptr(Result), ptr, sizeof(detail::tmat4x3<T>));
+ return Result;
+ }
+
+ //! Build a matrix from a pointer.
+ //! From GLM_GTC_type_ptr extension.
+ template<typename T>
+ GLM_FUNC_QUALIFIER detail::tmat4x4<T> make_mat4x4(T const * const ptr)
+ {
+ detail::tmat4x4<T> Result;
+ memcpy(value_ptr(Result), ptr, sizeof(detail::tmat4x4<T>));
+ return Result;
+ }
+
+ //! Build a matrix from a pointer.
+ //! From GLM_GTC_type_ptr extension.
+ template<typename T>
+ GLM_FUNC_QUALIFIER detail::tmat2x2<T> make_mat2(T const * const ptr)
+ {
+ return make_mat2x2(ptr);
+ }
+
+ //! Build a matrix from a pointer.
+ //! From GLM_GTC_type_ptr extension.
+ template<typename T>
+ GLM_FUNC_QUALIFIER detail::tmat3x3<T> make_mat3(T const * const ptr)
+ {
+ return make_mat3x3(ptr);
+ }
+
+ //! Build a matrix from a pointer.
+ //! From GLM_GTC_type_ptr extension.
+ template<typename T>
+ GLM_FUNC_QUALIFIER detail::tmat4x4<T> make_mat4(T const * const ptr)
+ {
+ return make_mat4x4(ptr);
+ }
+
+ ///@}
+
+}//namespace type_ptr
+}//namespace gtc
+}//namespace glm
+
+#include "type_ptr.inl"
+
+namespace glm{using namespace gtc::type_ptr;}
+
+#endif//glm_gtx_type_ptr
+
diff --git a/src/glm/gtc/type_ptr.inl b/src/glm/gtc/type_ptr.inl
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/glm/gtc/type_ptr.inl
diff --git a/src/glm/gtx/associated_min_max.hpp b/src/glm/gtx/associated_min_max.hpp
new file mode 100644
index 0000000..fe3e714
--- /dev/null
+++ b/src/glm/gtx/associated_min_max.hpp
@@ -0,0 +1,82 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2008-03-10
+// Updated : 2008-03-15
+// Licence : This source is under MIT License
+// File : gtx_associated_min_max.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+// - GLM_GTX_extented_min_max
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_gtx_associated_min_max
+#define glm_gtx_associated_min_max
+
+// Dependency:
+#include "../glm.hpp"
+
+#if(defined(GLM_MESSAGES) && !defined(glm_ext))
+# pragma message("GLM: GLM_GTX_associated_min_max extension included")
+#endif
+
+namespace glm{
+namespace gtx{
+namespace associated_min_max ///< GLM_GTX_associated_min_max extension: Min and max functions that return associated values not the compared onces.
+{
+ /// \addtogroup gtx_associated_min_max
+ ///@{
+
+ //! \brief Min comparison between 2 variables
+ template<typename genTypeT, typename genTypeU>
+ genTypeU associatedMin(
+ const genTypeT& x, const genTypeU& a,
+ const genTypeT& y, const genTypeU& b);
+
+ //! \brief Min comparison between 3 variables
+ template<typename genTypeT, typename genTypeU>
+ genTypeU associatedMin(
+ const genTypeT& x, const genTypeU& a,
+ const genTypeT& y, const genTypeU& b,
+ const genTypeT& z, const genTypeU& c);
+
+ //! \brief Min comparison between 4 variables
+ template<typename genTypeT, typename genTypeU>
+ genTypeU associatedMin(
+ const genTypeT& x, const genTypeU& a,
+ const genTypeT& y, const genTypeU& b,
+ const genTypeT& z, const genTypeU& c,
+ const genTypeT& w, const genTypeU& d);
+
+ //! \brief Max comparison between 2 variables
+ template<typename genTypeT, typename genTypeU>
+ genTypeU associatedMax(
+ const genTypeT& x, const genTypeU& a,
+ const genTypeT& y, const genTypeU& b);
+
+ //! \brief Max comparison between 3 variables
+ template<typename genTypeT, typename genTypeU>
+ genTypeU associatedMax(
+ const genTypeT& x, const genTypeU& a,
+ const genTypeT& y, const genTypeU& b,
+ const genTypeT& z, const genTypeU& c);
+
+ //! \brief Max comparison between 4 variables
+ template<typename genTypeT, typename genTypeU>
+ genTypeU associatedMax(
+ const genTypeT& x, const genTypeU& a,
+ const genTypeT& y, const genTypeU& b,
+ const genTypeT& z, const genTypeU& c,
+ const genTypeT& w, const genTypeU& d);
+
+ ///@}
+} //namespace associated_min_max
+} //namespace gtx
+} //namespace glm
+
+#include "associated_min_max.inl"
+
+namespace glm{using namespace gtx::associated_min_max;}
+
+#endif//glm_gtx_associated_min_max
diff --git a/src/glm/gtx/associated_min_max.inl b/src/glm/gtx/associated_min_max.inl
new file mode 100644
index 0000000..8b6daa1
--- /dev/null
+++ b/src/glm/gtx/associated_min_max.inl
@@ -0,0 +1,916 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2008-03-10
+// Updated : 2008-03-15
+// Licence : This source is under MIT License
+// File : gtx_associated_min_max.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm{
+namespace gtx{
+namespace associated_min_max{
+
+ // Min comparison between 2 variables
+ template<typename T, typename U>
+ GLM_FUNC_QUALIFIER U associatedMin(T x, U a, T y, U b)
+ {
+ return x < y ? a : b;
+ }
+
+ template<typename T, typename U>
+ GLM_FUNC_QUALIFIER detail::tvec2<U> associatedMin
+ (
+ const detail::tvec2<T>& x, const detail::tvec2<U>& a,
+ const detail::tvec2<T>& y, const detail::tvec2<U>& b
+ )
+ {
+ detail::tvec2<U> Result;
+ //Result.x = x[0] < y[0] ? a[0] : b[0];
+ //Result.y = x[1] < y[1] ? a[1] : b[1];
+ for(typename detail::tvec2<U>::size_type i = 0; i < detail::tvec2<U>::value_size; ++i)
+ Result[i] = x[i] < y[i] ? a[i] : b[i];
+ return Result;
+ }
+
+ template<typename T, typename U>
+ GLM_FUNC_QUALIFIER detail::tvec3<U> associatedMin
+ (
+ const detail::tvec3<T>& x, const detail::tvec3<U>& a,
+ const detail::tvec3<T>& y, const detail::tvec3<U>& b
+ )
+ {
+ detail::tvec3<U> Result;
+ for(typename detail::tvec3<U>::size_type i = 0; i < detail::tvec3<U>::value_size; ++i)
+ Result[i] = x[i] < y[i] ? a[i] : b[i];
+ return Result;
+ }
+
+ template<typename T, typename U>
+ GLM_FUNC_QUALIFIER detail::tvec4<U> associatedMin
+ (
+ const detail::tvec4<T>& x, const detail::tvec4<U>& a,
+ const detail::tvec4<T>& y, const detail::tvec4<U>& b
+ )
+ {
+ detail::tvec4<U> Result;
+ for(typename detail::tvec4<U>::size_type i = 0; i < detail::tvec4<U>::value_size; ++i)
+ Result[i] = x[i] < y[i] ? a[i] : b[i];
+ return Result;
+ }
+
+ template<typename T, typename U>
+ GLM_FUNC_QUALIFIER detail::tvec2<U> associatedMin
+ (
+ T x, const detail::tvec2<U>& a,
+ T y, const detail::tvec2<U>& b
+ )
+ {
+ detail::tvec2<U> Result;
+ for(typename detail::tvec2<U>::size_type i = 0; i < detail::tvec2<U>::value_size; ++i)
+ Result[i] = x < y ? a[i] : b[i];
+ return Result;
+ }
+
+ template<typename T, typename U>
+ GLM_FUNC_QUALIFIER detail::tvec3<U> associatedMin
+ (
+ T x, const detail::tvec3<U>& a,
+ T y, const detail::tvec3<U>& b
+ )
+ {
+ detail::tvec3<U> Result;
+ for(typename detail::tvec3<U>::size_type i = 0; i < detail::tvec3<U>::value_size; ++i)
+ Result[i] = x < y ? a[i] : b[i];
+ return Result;
+ }
+
+ template<typename T, typename U>
+ GLM_FUNC_QUALIFIER detail::tvec4<U> associatedMin
+ (
+ T x, const detail::tvec4<U>& a,
+ T y, const detail::tvec4<U>& b
+ )
+ {
+ detail::tvec4<U> Result;
+ for(typename detail::tvec4<U>::size_type i = 0; i < detail::tvec4<U>::value_size; ++i)
+ Result[i] = x < y ? a[i] : b[i];
+ return Result;
+ }
+
+ template<typename T, typename U>
+ GLM_FUNC_QUALIFIER detail::tvec2<U> associatedMin
+ (
+ const detail::tvec2<T>& x, U a,
+ const detail::tvec2<T>& y, U b
+ )
+ {
+ detail::tvec2<U> Result;
+ for(typename detail::tvec2<U>::size_type i = 0; i < detail::tvec2<T>::value_size(); ++i)
+ Result[i] = x[i] < y[i] ? a : b;
+ return Result;
+ }
+
+ template<typename T, typename U>
+ GLM_FUNC_QUALIFIER detail::tvec3<U> associatedMin
+ (
+ const detail::tvec3<T>& x, U a,
+ const detail::tvec3<T>& y, U b
+ )
+ {
+ detail::tvec3<U> Result;
+ for(typename detail::tvec3<U>::size_type i = 0; i < detail::tvec3<T>::value_size(); ++i)
+ Result[i] = x[i] < y[i] ? a : b;
+ return Result;
+ }
+
+ template<typename T, typename U>
+ GLM_FUNC_QUALIFIER detail::tvec4<U> associatedMin
+ (
+ const detail::tvec4<T>& x, U a,
+ const detail::tvec4<T>& y, U b
+ )
+ {
+ detail::tvec4<U> Result;
+ for(typename detail::tvec4<U>::size_type i = 0; i < detail::tvec4<T>::value_size(); ++i)
+ Result[i] = x[i] < y[i] ? a : b;
+ return Result;
+ }
+
+ // Min comparison between 3 variables
+ template<typename T, typename U>
+ GLM_FUNC_QUALIFIER U associatedMin
+ (
+ T x, U a,
+ T y, U b,
+ T z, U c
+ )
+ {
+ U Result = x < y ? (x < z ? a : c) : (y < z ? b : c);
+ return Result;
+ }
+
+ template<typename T, typename U>
+ GLM_FUNC_QUALIFIER detail::tvec2<U> associatedMin
+ (
+ const detail::tvec2<T>& x, const detail::tvec2<U>& a,
+ const detail::tvec2<T>& y, const detail::tvec2<U>& b,
+ const detail::tvec2<T>& z, const detail::tvec2<U>& c
+ )
+ {
+ detail::tvec2<U> Result;
+ for(typename detail::tvec2<U>::size_type i = 0; i < detail::tvec2<U>::value_size; ++i)
+ Result[i] = x[i] < y[i] ? (x[i] < z[i] ? a[i] : c[i]) : (y[i] < z[i] ? b[i] : c[i]);
+ return Result;
+ }
+
+ template<typename T, typename U>
+ GLM_FUNC_QUALIFIER detail::tvec3<U> associatedMin
+ (
+ const detail::tvec3<T>& x, const detail::tvec3<U>& a,
+ const detail::tvec3<T>& y, const detail::tvec3<U>& b,
+ const detail::tvec3<T>& z, const detail::tvec3<U>& c
+ )
+ {
+ detail::tvec3<U> Result;
+ for(typename detail::tvec3<U>::size_type i = 0; i < detail::tvec3<U>::value_size; ++i)
+ Result[i] = x[i] < y[i] ? (x[i] < z[i] ? a[i] : c[i]) : (y[i] < z[i] ? b[i] : c[i]);
+ return Result;
+ }
+
+ template<typename T, typename U>
+ GLM_FUNC_QUALIFIER detail::tvec4<U> associatedMin
+ (
+ const detail::tvec4<T>& x, const detail::tvec4<U>& a,
+ const detail::tvec4<T>& y, const detail::tvec4<U>& b,
+ const detail::tvec4<T>& z, const detail::tvec4<U>& c
+ )
+ {
+ detail::tvec4<U> Result;
+ for(typename detail::tvec4<U>::size_type i = 0; i < detail::tvec4<U>::value_size; ++i)
+ Result[i] = x[i] < y[i] ? (x[i] < z[i] ? a[i] : c[i]) : (y[i] < z[i] ? b[i] : c[i]);
+ return Result;
+ }
+
+ // Min comparison between 4 variables
+ template<typename T, typename U>
+ GLM_FUNC_QUALIFIER U associatedMin
+ (
+ T x, U a,
+ T y, U b,
+ T z, U c,
+ T w, U d
+ )
+ {
+ T Test1 = min(x, y);
+ T Test2 = min(z, w);;
+ U Result1 = x < y ? a : b;
+ U Result2 = z < w ? c : d;
+ U Result = Test1 < Test2 ? Result1 : Result2;
+ return Result;
+ }
+
+ // Min comparison between 4 variables
+ template<typename T, typename U>
+ GLM_FUNC_QUALIFIER detail::tvec2<U> associatedMin
+ (
+ const detail::tvec2<T>& x, const detail::tvec2<U>& a,
+ const detail::tvec2<T>& y, const detail::tvec2<U>& b,
+ const detail::tvec2<T>& z, const detail::tvec2<U>& c,
+ const detail::tvec2<T>& w, const detail::tvec2<U>& d
+ )
+ {
+ detail::tvec2<U> Result;
+ for(typename detail::tvec2<U>::size_type i = 0; i < detail::tvec2<U>::value_size; ++i)
+ {
+ T Test1 = min(x[i], y[i]);
+ T Test2 = min(z[i], w[i]);
+ U Result1 = x[i] < y[i] ? a[i] : b[i];
+ U Result2 = z[i] < w[i] ? c[i] : d[i];
+ Result[i] = Test1 < Test2 ? Result1 : Result2;
+ }
+ return Result;
+ }
+
+ // Min comparison between 4 variables
+ template<typename T, typename U>
+ GLM_FUNC_QUALIFIER detail::tvec3<U> associatedMin
+ (
+ const detail::tvec3<T>& x, const detail::tvec3<U>& a,
+ const detail::tvec3<T>& y, const detail::tvec3<U>& b,
+ const detail::tvec3<T>& z, const detail::tvec3<U>& c,
+ const detail::tvec3<T>& w, const detail::tvec3<U>& d
+ )
+ {
+ detail::tvec3<U> Result;
+ for(typename detail::tvec3<U>::size_type i = 0; i < detail::tvec3<U>::value_size; ++i)
+ {
+ T Test1 = min(x[i], y[i]);
+ T Test2 = min(z[i], w[i]);
+ U Result1 = x[i] < y[i] ? a[i] : b[i];
+ U Result2 = z[i] < w[i] ? c[i] : d[i];
+ Result[i] = Test1 < Test2 ? Result1 : Result2;
+ }
+ return Result;
+ }
+
+ // Min comparison between 4 variables
+ template<typename T, typename U>
+ GLM_FUNC_QUALIFIER detail::tvec4<U> associatedMin
+ (
+ const detail::tvec4<T>& x, const detail::tvec4<U>& a,
+ const detail::tvec4<T>& y, const detail::tvec4<U>& b,
+ const detail::tvec4<T>& z, const detail::tvec4<U>& c,
+ const detail::tvec4<T>& w, const detail::tvec4<U>& d
+ )
+ {
+ detail::tvec4<U> Result;
+ for(typename detail::tvec4<U>::size_type i = 0; i < detail::tvec4<U>::value_size; ++i)
+ {
+ T Test1 = min(x[i], y[i]);
+ T Test2 = min(z[i], w[i]);
+ U Result1 = x[i] < y[i] ? a[i] : b[i];
+ U Result2 = z[i] < w[i] ? c[i] : d[i];
+ Result[i] = Test1 < Test2 ? Result1 : Result2;
+ }
+ return Result;
+ }
+
+ // Min comparison between 4 variables
+ template<typename T, typename U>
+ GLM_FUNC_QUALIFIER detail::tvec2<U> associatedMin
+ (
+ T x, const detail::tvec2<U>& a,
+ T y, const detail::tvec2<U>& b,
+ T z, const detail::tvec2<U>& c,
+ T w, const detail::tvec2<U>& d
+ )
+ {
+ T Test1 = min(x, y);
+ T Test2 = min(z, w);
+
+ detail::tvec2<U> Result;
+ for(typename detail::tvec2<U>::size_type i = 0; i < detail::tvec2<U>::value_size; ++i)
+ {
+ U Result1 = x < y ? a[i] : b[i];
+ U Result2 = z < w ? c[i] : d[i];
+ Result[i] = Test1 < Test2 ? Result1 : Result2;
+ }
+ return Result;
+ }
+
+ // Min comparison between 4 variables
+ template<typename T, typename U>
+ GLM_FUNC_QUALIFIER detail::tvec3<U> associatedMin
+ (
+ T x, const detail::tvec3<U>& a,
+ T y, const detail::tvec3<U>& b,
+ T z, const detail::tvec3<U>& c,
+ T w, const detail::tvec3<U>& d
+ )
+ {
+ T Test1 = min(x, y);
+ T Test2 = min(z, w);
+
+ detail::tvec3<U> Result;
+ for(typename detail::tvec3<U>::size_type i = 0; i < detail::tvec3<U>::value_size; ++i)
+ {
+ U Result1 = x < y ? a[i] : b[i];
+ U Result2 = z < w ? c[i] : d[i];
+ Result[i] = Test1 < Test2 ? Result1 : Result2;
+ }
+ return Result;
+ }
+
+ // Min comparison between 4 variables
+ template<typename T, typename U>
+ GLM_FUNC_QUALIFIER detail::tvec4<U> associatedMin
+ (
+ T x, const detail::tvec4<U>& a,
+ T y, const detail::tvec4<U>& b,
+ T z, const detail::tvec4<U>& c,
+ T w, const detail::tvec4<U>& d
+ )
+ {
+ T Test1 = min(x, y);
+ T Test2 = min(z, w);
+
+ detail::tvec4<U> Result;
+ for(typename detail::tvec4<U>::size_type i = 0; i < detail::tvec4<U>::value_size; ++i)
+ {
+ U Result1 = x < y ? a[i] : b[i];
+ U Result2 = z < w ? c[i] : d[i];
+ Result[i] = Test1 < Test2 ? Result1 : Result2;
+ }
+ return Result;
+ }
+
+ // Min comparison between 4 variables
+ template<typename T, typename U>
+ GLM_FUNC_QUALIFIER detail::tvec2<U> associatedMin
+ (
+ const detail::tvec2<T>& x, U a,
+ const detail::tvec2<T>& y, U b,
+ const detail::tvec2<T>& z, U c,
+ const detail::tvec2<T>& w, U d
+ )
+ {
+ detail::tvec2<U> Result;
+ for(typename detail::tvec2<T>::size_type i = 0; i < detail::tvec2<T>::value_size(); ++i)
+ {
+ T Test1 = min(x[i], y[i]);
+ T Test2 = min(z[i], w[i]);;
+ U Result1 = x[i] < y[i] ? a : b;
+ U Result2 = z[i] < w[i] ? c : d;
+ Result[i] = Test1 < Test2 ? Result1 : Result2;
+ }
+ return Result;
+ }
+
+ // Min comparison between 4 variables
+ template<typename T, typename U>
+ GLM_FUNC_QUALIFIER detail::tvec3<U> associatedMin
+ (
+ const detail::tvec3<T>& x, U a,
+ const detail::tvec3<T>& y, U b,
+ const detail::tvec3<T>& z, U c,
+ const detail::tvec3<T>& w, U d
+ )
+ {
+ detail::tvec3<U> Result;
+ for(typename detail::tvec3<T>::size_type i = 0; i < detail::tvec3<T>::value_size(); ++i)
+ {
+ T Test1 = min(x[i], y[i]);
+ T Test2 = min(z[i], w[i]);;
+ U Result1 = x[i] < y[i] ? a : b;
+ U Result2 = z[i] < w[i] ? c : d;
+ Result[i] = Test1 < Test2 ? Result1 : Result2;
+ }
+ return Result;
+ }
+
+ // Min comparison between 4 variables
+ template<typename T, typename U>
+ GLM_FUNC_QUALIFIER detail::tvec4<U> associatedMin
+ (
+ const detail::tvec4<T>& x, U a,
+ const detail::tvec4<T>& y, U b,
+ const detail::tvec4<T>& z, U c,
+ const detail::tvec4<T>& w, U d
+ )
+ {
+ detail::tvec4<U> Result;
+ for(typename detail::tvec4<T>::size_type i = 0; i < detail::tvec4<T>::value_size(); ++i)
+ {
+ T Test1 = min(x[i], y[i]);
+ T Test2 = min(z[i], w[i]);;
+ U Result1 = x[i] < y[i] ? a : b;
+ U Result2 = z[i] < w[i] ? c : d;
+ Result[i] = Test1 < Test2 ? Result1 : Result2;
+ }
+ return Result;
+ }
+
+ // Max comparison between 2 variables
+ template<typename T, typename U>
+ GLM_FUNC_QUALIFIER U associatedMax(T x, U a, T y, U b)
+ {
+ return x > y ? a : b;
+ }
+
+ // Max comparison between 2 variables
+ template<typename T, typename U>
+ GLM_FUNC_QUALIFIER detail::tvec2<U> associatedMax
+ (
+ const detail::tvec2<T>& x, const detail::tvec2<U>& a,
+ const detail::tvec2<T>& y, const detail::tvec2<U>& b
+ )
+ {
+ detail::tvec2<U> Result;
+ for(typename detail::tvec2<U>::size_type i = 0; i < detail::tvec2<U>::value_size; ++i)
+ Result[i] = x[i] > y[i] ? a[i] : b[i];
+ return Result;
+ }
+
+ // Max comparison between 2 variables
+ template<typename T, typename U>
+ GLM_FUNC_QUALIFIER detail::tvec3<U> associatedMax
+ (
+ const detail::tvec3<T>& x, const detail::tvec3<U>& a,
+ const detail::tvec3<T>& y, const detail::tvec3<U>& b
+ )
+ {
+ detail::tvec3<U> Result;
+ for(typename detail::tvec3<U>::size_type i = 0; i < detail::tvec3<U>::value_size; ++i)
+ Result[i] = x[i] > y[i] ? a[i] : b[i];
+ return Result;
+ }
+
+ // Max comparison between 2 variables
+ template<typename T, typename U>
+ GLM_FUNC_QUALIFIER detail::tvec4<U> associatedMax
+ (
+ const detail::tvec4<T>& x, const detail::tvec4<U>& a,
+ const detail::tvec4<T>& y, const detail::tvec4<U>& b
+ )
+ {
+ detail::tvec4<U> Result;
+ for(typename detail::tvec4<U>::size_type i = 0; i < detail::tvec4<U>::value_size; ++i)
+ Result[i] = x[i] > y[i] ? a[i] : b[i];
+ return Result;
+ }
+
+ // Max comparison between 2 variables
+ template<typename T, typename U>
+ GLM_FUNC_QUALIFIER detail::tvec2<U> associatedMax
+ (
+ T x, const detail::tvec2<U>& a,
+ T y, const detail::tvec2<U>& b
+ )
+ {
+ detail::tvec2<U> Result;
+ for(typename detail::tvec2<U>::size_type i = 0; i < detail::tvec2<U>::value_size; ++i)
+ Result[i] = x > y ? a[i] : b[i];
+ return Result;
+ }
+
+ // Max comparison between 2 variables
+ template<typename T, typename U>
+ GLM_FUNC_QUALIFIER detail::tvec3<U> associatedMax
+ (
+ T x, const detail::tvec3<U>& a,
+ T y, const detail::tvec3<U>& b
+ )
+ {
+ detail::tvec3<U> Result;
+ for(typename detail::tvec3<U>::size_type i = 0; i < detail::tvec3<U>::value_size; ++i)
+ Result[i] = x > y ? a[i] : b[i];
+ return Result;
+ }
+
+ // Max comparison between 2 variables
+ template<typename T, typename U>
+ GLM_FUNC_QUALIFIER detail::tvec4<U> associatedMax
+ (
+ T x, const detail::tvec4<U>& a,
+ T y, const detail::tvec4<U>& b
+ )
+ {
+ detail::tvec4<U> Result;
+ for(typename detail::tvec4<U>::size_type i = 0; i < detail::tvec4<U>::value_size; ++i)
+ Result[i] = x > y ? a[i] : b[i];
+ return Result;
+ }
+
+ // Max comparison between 2 variables
+ template<typename T, typename U>
+ GLM_FUNC_QUALIFIER detail::tvec2<U> associatedMax
+ (
+ const detail::tvec2<T>& x, U a,
+ const detail::tvec2<T>& y, U b
+ )
+ {
+ detail::tvec2<U> Result;
+ for(typename detail::tvec2<T>::size_type i = 0; i < detail::tvec2<T>::value_size(); ++i)
+ Result[i] = x[i] > y[i] ? a : b;
+ return Result;
+ }
+
+ // Max comparison between 2 variables
+ template<typename T, typename U>
+ GLM_FUNC_QUALIFIER detail::tvec3<U> associatedMax
+ (
+ const detail::tvec3<T>& x, U a,
+ const detail::tvec3<T>& y, U b
+ )
+ {
+ detail::tvec3<U> Result;
+ for(typename detail::tvec3<T>::size_type i = 0; i < detail::tvec3<T>::value_size(); ++i)
+ Result[i] = x[i] > y[i] ? a : b;
+ return Result;
+ }
+
+ // Max comparison between 2 variables
+ template<typename T, typename U>
+ GLM_FUNC_QUALIFIER detail::tvec4<U> associatedMax
+ (
+ const detail::tvec4<T>& x, U a,
+ const detail::tvec4<T>& y, U b
+ )
+ {
+ detail::tvec4<U> Result;
+ for(typename detail::tvec4<T>::size_type i = 0; i < detail::tvec4<T>::value_size(); ++i)
+ Result[i] = x[i] > y[i] ? a : b;
+ return Result;
+ }
+
+ // Max comparison between 3 variables
+ template<typename T, typename U>
+ GLM_FUNC_QUALIFIER U associatedMax
+ (
+ T x, U a,
+ T y, U b,
+ T z, U c
+ )
+ {
+ U Result = x > y ? (x > z ? a : c) : (y > z ? b : c);
+ return Result;
+ }
+
+ // Max comparison between 3 variables
+ template<typename T, typename U>
+ GLM_FUNC_QUALIFIER detail::tvec2<U> associatedMax
+ (
+ const detail::tvec2<T>& x, const detail::tvec2<U>& a,
+ const detail::tvec2<T>& y, const detail::tvec2<U>& b,
+ const detail::tvec2<T>& z, const detail::tvec2<U>& c
+ )
+ {
+ detail::tvec2<U> Result;
+ for(typename detail::tvec2<U>::size_type i = 0; i < detail::tvec2<U>::value_size; ++i)
+ Result[i] = x[i] > y[i] ? (x[i] > z[i] ? a[i] : c[i]) : (y[i] > z[i] ? b[i] : c[i]);
+ return Result;
+ }
+
+ // Max comparison between 3 variables
+ template<typename T, typename U>
+ GLM_FUNC_QUALIFIER detail::tvec3<U> associatedMax
+ (
+ const detail::tvec3<T>& x, const detail::tvec3<U>& a,
+ const detail::tvec3<T>& y, const detail::tvec3<U>& b,
+ const detail::tvec3<T>& z, const detail::tvec3<U>& c
+ )
+ {
+ detail::tvec3<U> Result;
+ for(typename detail::tvec3<U>::size_type i = 0; i < detail::tvec3<U>::value_size; ++i)
+ Result[i] = x[i] > y[i] ? (x[i] > z[i] ? a[i] : c[i]) : (y[i] > z[i] ? b[i] : c[i]);
+ return Result;
+ }
+
+ // Max comparison between 3 variables
+ template<typename T, typename U>
+ GLM_FUNC_QUALIFIER detail::tvec4<U> associatedMax
+ (
+ const detail::tvec4<T>& x, const detail::tvec4<U>& a,
+ const detail::tvec4<T>& y, const detail::tvec4<U>& b,
+ const detail::tvec4<T>& z, const detail::tvec4<U>& c
+ )
+ {
+ detail::tvec4<U> Result;
+ for(typename detail::tvec4<U>::size_type i = 0; i < detail::tvec4<U>::value_size; ++i)
+ Result[i] = x[i] > y[i] ? (x[i] > z[i] ? a[i] : c[i]) : (y[i] > z[i] ? b[i] : c[i]);
+ return Result;
+ }
+
+ // Max comparison between 3 variables
+ template<typename T, typename U>
+ GLM_FUNC_QUALIFIER detail::tvec2<U> associatedMax
+ (
+ T x, const detail::tvec2<U>& a,
+ T y, const detail::tvec2<U>& b,
+ T z, const detail::tvec2<U>& c
+ )
+ {
+ detail::tvec2<U> Result;
+ for(typename detail::tvec2<U>::size_type i = 0; i < detail::tvec2<U>::value_size; ++i)
+ Result[i] = x > y ? (x > z ? a[i] : c[i]) : (y > z ? b[i] : c[i]);
+ return Result;
+ }
+
+ // Max comparison between 3 variables
+ template<typename T, typename U>
+ GLM_FUNC_QUALIFIER detail::tvec3<U> associatedMax
+ (
+ T x, const detail::tvec3<U>& a,
+ T y, const detail::tvec3<U>& b,
+ T z, const detail::tvec3<U>& c
+ )
+ {
+ detail::tvec3<U> Result;
+ for(typename detail::tvec3<U>::size_type i = 0; i < detail::tvec3<U>::value_size; ++i)
+ Result[i] = x > y ? (x > z ? a[i] : c[i]) : (y > z ? b[i] : c[i]);
+ return Result;
+ }
+
+ // Max comparison between 3 variables
+ template<typename T, typename U>
+ GLM_FUNC_QUALIFIER detail::tvec4<U> associatedMax
+ (
+ T x, const detail::tvec4<U>& a,
+ T y, const detail::tvec4<U>& b,
+ T z, const detail::tvec4<U>& c
+ )
+ {
+ detail::tvec4<U> Result;
+ for(typename detail::tvec4<U>::size_type i = 0; i < detail::tvec4<U>::value_size; ++i)
+ Result[i] = x > y ? (x > z ? a[i] : c[i]) : (y > z ? b[i] : c[i]);
+ return Result;
+ }
+
+ // Max comparison between 3 variables
+ template<typename T, typename U>
+ GLM_FUNC_QUALIFIER detail::tvec2<U> associatedMax
+ (
+ const detail::tvec2<T>& x, U a,
+ const detail::tvec2<T>& y, U b,
+ const detail::tvec2<T>& z, U c
+ )
+ {
+ detail::tvec2<U> Result;
+ for(typename detail::tvec2<T>::size_type i = 0; i < detail::tvec2<T>::value_size(); ++i)
+ Result[i] = x[i] > y[i] ? (x[i] > z[i] ? a : c) : (y[i] > z[i] ? b : c);
+ return Result;
+ }
+
+ // Max comparison between 3 variables
+ template<typename T, typename U>
+ GLM_FUNC_QUALIFIER detail::tvec3<U> associatedMax
+ (
+ const detail::tvec3<T>& x, U a,
+ const detail::tvec3<T>& y, U b,
+ const detail::tvec3<T>& z, U c
+ )
+ {
+ detail::tvec3<U> Result;
+ for(typename detail::tvec3<T>::size_type i = 0; i < detail::tvec3<T>::value_size(); ++i)
+ Result[i] = x[i] > y[i] ? (x[i] > z[i] ? a : c) : (y[i] > z[i] ? b : c);
+ return Result;
+ }
+
+ // Max comparison between 3 variables
+ template<typename T, typename U>
+ GLM_FUNC_QUALIFIER detail::tvec4<U> associatedMax
+ (
+ const detail::tvec4<T>& x, U a,
+ const detail::tvec4<T>& y, U b,
+ const detail::tvec4<T>& z, U c
+ )
+ {
+ detail::tvec4<U> Result;
+ for(typename detail::tvec4<T>::size_type i = 0; i < detail::tvec4<T>::value_size(); ++i)
+ Result[i] = x[i] > y[i] ? (x[i] > z[i] ? a : c) : (y[i] > z[i] ? b : c);
+ return Result;
+ }
+
+ // Max comparison between 4 variables
+ template<typename T, typename U>
+ GLM_FUNC_QUALIFIER U associatedMax
+ (
+ T x, U a,
+ T y, U b,
+ T z, U c,
+ T w, U d
+ )
+ {
+ T Test1 = max(x, y);
+ T Test2 = max(z, w);;
+ U Result1 = x > y ? a : b;
+ U Result2 = z > w ? c : d;
+ U Result = Test1 > Test2 ? Result1 : Result2;
+ return Result;
+ }
+
+ // Max comparison between 4 variables
+ template<typename T, typename U>
+ GLM_FUNC_QUALIFIER detail::tvec2<U> associatedMax
+ (
+ const detail::tvec2<T>& x, const detail::tvec2<U>& a,
+ const detail::tvec2<T>& y, const detail::tvec2<U>& b,
+ const detail::tvec2<T>& z, const detail::tvec2<U>& c,
+ const detail::tvec2<T>& w, const detail::tvec2<U>& d
+ )
+ {
+ detail::tvec2<U> Result;
+ for(typename detail::tvec2<U>::size_type i = 0; i < detail::tvec2<U>::value_size; ++i)
+ {
+ T Test1 = max(x[i], y[i]);
+ T Test2 = max(z[i], w[i]);
+ U Result1 = x[i] > y[i] ? a[i] : b[i];
+ U Result2 = z[i] > w[i] ? c[i] : d[i];
+ Result[i] = Test1 > Test2 ? Result1 : Result2;
+ }
+ return Result;
+ }
+
+ // Max comparison between 4 variables
+ template<typename T, typename U>
+ GLM_FUNC_QUALIFIER detail::tvec3<U> associatedMax
+ (
+ const detail::tvec3<T>& x, const detail::tvec3<U>& a,
+ const detail::tvec3<T>& y, const detail::tvec3<U>& b,
+ const detail::tvec3<T>& z, const detail::tvec3<U>& c,
+ const detail::tvec3<T>& w, const detail::tvec3<U>& d
+ )
+ {
+ detail::tvec3<U> Result;
+ for(typename detail::tvec3<U>::size_type i = 0; i < detail::tvec3<U>::value_size; ++i)
+ {
+ T Test1 = max(x[i], y[i]);
+ T Test2 = max(z[i], w[i]);
+ U Result1 = x[i] > y[i] ? a[i] : b[i];
+ U Result2 = z[i] > w[i] ? c[i] : d[i];
+ Result[i] = Test1 > Test2 ? Result1 : Result2;
+ }
+ return Result;
+ }
+
+ // Max comparison between 4 variables
+ template<typename T, typename U>
+ GLM_FUNC_QUALIFIER detail::tvec4<U> associatedMax
+ (
+ const detail::tvec4<T>& x, const detail::tvec4<U>& a,
+ const detail::tvec4<T>& y, const detail::tvec4<U>& b,
+ const detail::tvec4<T>& z, const detail::tvec4<U>& c,
+ const detail::tvec4<T>& w, const detail::tvec4<U>& d
+ )
+ {
+ detail::tvec4<U> Result;
+ for(typename detail::tvec4<U>::size_type i = 0; i < detail::tvec4<U>::value_size; ++i)
+ {
+ T Test1 = max(x[i], y[i]);
+ T Test2 = max(z[i], w[i]);
+ U Result1 = x[i] > y[i] ? a[i] : b[i];
+ U Result2 = z[i] > w[i] ? c[i] : d[i];
+ Result[i] = Test1 > Test2 ? Result1 : Result2;
+ }
+ return Result;
+ }
+
+ // Max comparison between 4 variables
+ template<typename T, typename U>
+ GLM_FUNC_QUALIFIER detail::tvec2<U> associatedMax
+ (
+ T x, const detail::tvec2<U>& a,
+ T y, const detail::tvec2<U>& b,
+ T z, const detail::tvec2<U>& c,
+ T w, const detail::tvec2<U>& d
+ )
+ {
+ T Test1 = max(x, y);
+ T Test2 = max(z, w);
+
+ detail::tvec2<U> Result;
+ for(typename detail::tvec2<U>::size_type i = 0; i < detail::tvec2<U>::value_size; ++i)
+ {
+ U Result1 = x > y ? a[i] : b[i];
+ U Result2 = z > w ? c[i] : d[i];
+ Result[i] = Test1 > Test2 ? Result1 : Result2;
+ }
+ return Result;
+ }
+
+ // Max comparison between 4 variables
+ template<typename T, typename U>
+ GLM_FUNC_QUALIFIER detail::tvec3<U> associatedMax
+ (
+ T x, const detail::tvec3<U>& a,
+ T y, const detail::tvec3<U>& b,
+ T z, const detail::tvec3<U>& c,
+ T w, const detail::tvec3<U>& d
+ )
+ {
+ T Test1 = max(x, y);
+ T Test2 = max(z, w);
+
+ detail::tvec3<U> Result;
+ for(typename detail::tvec3<U>::size_type i = 0; i < detail::tvec3<U>::value_size; ++i)
+ {
+ U Result1 = x > y ? a[i] : b[i];
+ U Result2 = z > w ? c[i] : d[i];
+ Result[i] = Test1 > Test2 ? Result1 : Result2;
+ }
+ return Result;
+ }
+
+ // Max comparison between 4 variables
+ template<typename T, typename U>
+ GLM_FUNC_QUALIFIER detail::tvec4<U> associatedMax
+ (
+ T x, const detail::tvec4<U>& a,
+ T y, const detail::tvec4<U>& b,
+ T z, const detail::tvec4<U>& c,
+ T w, const detail::tvec4<U>& d
+ )
+ {
+ T Test1 = max(x, y);
+ T Test2 = max(z, w);
+
+ detail::tvec4<U> Result;
+ for(typename detail::tvec4<U>::size_type i = 0; i < detail::tvec4<U>::value_size; ++i)
+ {
+ U Result1 = x > y ? a[i] : b[i];
+ U Result2 = z > w ? c[i] : d[i];
+ Result[i] = Test1 > Test2 ? Result1 : Result2;
+ }
+ return Result;
+ }
+
+ // Max comparison between 4 variables
+ template<typename T, typename U>
+ GLM_FUNC_QUALIFIER detail::tvec2<U> associatedMax
+ (
+ const detail::tvec2<T>& x, U a,
+ const detail::tvec2<T>& y, U b,
+ const detail::tvec2<T>& z, U c,
+ const detail::tvec2<T>& w, U d
+ )
+ {
+ detail::tvec2<U> Result;
+ for(typename detail::tvec2<T>::size_type i = 0; i < detail::tvec2<T>::value_size(); ++i)
+ {
+ T Test1 = max(x[i], y[i]);
+ T Test2 = max(z[i], w[i]);;
+ U Result1 = x[i] > y[i] ? a : b;
+ U Result2 = z[i] > w[i] ? c : d;
+ Result[i] = Test1 > Test2 ? Result1 : Result2;
+ }
+ return Result;
+ }
+
+ // Max comparison between 4 variables
+ template<typename T, typename U>
+ GLM_FUNC_QUALIFIER detail::tvec3<U> associatedMax
+ (
+ const detail::tvec3<T>& x, U a,
+ const detail::tvec3<T>& y, U b,
+ const detail::tvec3<T>& z, U c,
+ const detail::tvec3<T>& w, U d
+ )
+ {
+ detail::tvec3<U> Result;
+ for(typename detail::tvec3<T>::size_type i = 0; i < detail::tvec3<T>::value_size(); ++i)
+ {
+ T Test1 = max(x[i], y[i]);
+ T Test2 = max(z[i], w[i]);;
+ U Result1 = x[i] > y[i] ? a : b;
+ U Result2 = z[i] > w[i] ? c : d;
+ Result[i] = Test1 > Test2 ? Result1 : Result2;
+ }
+ return Result;
+ }
+
+ // Max comparison between 4 variables
+ template<typename T, typename U>
+ GLM_FUNC_QUALIFIER detail::tvec4<U> associatedMax
+ (
+ const detail::tvec4<T>& x, U a,
+ const detail::tvec4<T>& y, U b,
+ const detail::tvec4<T>& z, U c,
+ const detail::tvec4<T>& w, U d
+ )
+ {
+ detail::tvec4<U> Result;
+ for(typename detail::tvec4<T>::size_type i = 0; i < detail::tvec4<T>::value_size(); ++i)
+ {
+ T Test1 = max(x[i], y[i]);
+ T Test2 = max(z[i], w[i]);;
+ U Result1 = x[i] > y[i] ? a : b;
+ U Result2 = z[i] > w[i] ? c : d;
+ Result[i] = Test1 > Test2 ? Result1 : Result2;
+ }
+ return Result;
+ }
+
+}//namespace associated_min_max
+}//namespace gtx
+}//namespace glm
diff --git a/src/glm/gtx/bit.hpp b/src/glm/gtx/bit.hpp
new file mode 100644
index 0000000..6cf49d4
--- /dev/null
+++ b/src/glm/gtx/bit.hpp
@@ -0,0 +1,107 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2007-03-14
+// Updated : 2008-11-14
+// Licence : This source is under MIT License
+// File : glm/gtx/bit.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+// - GLM_GTC_half_float
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_gtx_bit
+#define glm_gtx_bit
+
+// Dependency:
+#include "../glm.hpp"
+#include "../gtc/half_float.hpp"
+
+#if(defined(GLM_MESSAGES) && !defined(glm_ext))
+# pragma message("GLM: GLM_GTX_bit extension included")
+#endif
+
+namespace glm{
+namespace gtx{
+namespace bit ///< GLM_GTX_bit extension: Allow to perform bit operations on integer values
+{
+ using namespace gtc::half_float;
+
+ /// \addtogroup gtx_bit
+ ///@{
+
+ //! Build a mask of 'count' bits
+ //! From GLM_GTX_bit extension.
+ template <typename genIType>
+ genIType mask(genIType const & count);
+
+ //! Component wise extraction of bit fields.
+ //! genType and genIType could be a scalar or a vector.
+ //! From GLM_GTX_bit extension.
+ template <typename genIUType, typename sizeType>
+ genIUType extractField(
+ genIUType const & v,
+ sizeType const & first,
+ sizeType const & count);
+
+ //! Find the lowest bit set to 1 in a integer variable.
+ //! From GLM_GTX_bit extension.
+ template <typename genType>
+ int lowestBit(genType const & value);
+
+ //! Find the highest bit set to 1 in a integer variable.
+ //! From GLM_GTX_bit extension.
+ template <typename genType>
+ int highestBit(genType const & value);
+
+ //! Find the highest bit set to 1 in a integer variable and return its value.
+ //! From GLM_GTX_bit extension.
+ template <typename genType>
+ genType highestBitValue(genType const & value);
+
+ //! Return true if the value is a power of two number.
+ //! From GLM_GTX_bit extension.
+ template <typename genType>
+ bool isPowerOfTwo(genType const & value);
+
+ //! Return the power of two number which value is just higher the input value.
+ //! From GLM_GTX_bit extension.
+ template <typename genType>
+ genType powerOfTwoAbove(genType const & value);
+
+ //! Return the power of two number which value is just lower the input value.
+ //! From GLM_GTX_bit extension.
+ template <typename genType>
+ genType powerOfTwoBelow(genType const & value);
+
+ //! Return the power of two number which value is the closet to the input value.
+ //! From GLM_GTX_bit extension.
+ template <typename genType>
+ genType powerOfTwoNearest(genType const & value);
+
+ //! Revert all bits of any integer based type.
+ //! From GLM_GTX_bit extension.
+ template <typename genType>
+ genType bitRevert(genType const & value);
+
+ //! Rotate all bits to the right.
+ //! From GLM_GTX_bit extension.
+ template <typename genType>
+ genType bitRotateRight(genType const & In, std::size_t Shift);
+
+ //! Rotate all bits to the left.
+ //! From GLM_GTX_bit extension.
+ template <typename genType>
+ genType bitRotateLeft(genType const & In, std::size_t Shift);
+
+ ///@}
+}//namespace bit
+}//namespace gtx
+}//namespace glm
+
+#include "bit.inl"
+
+namespace glm{using namespace gtx::bit;}
+
+#endif//glm_gtx_bit
diff --git a/src/glm/gtx/bit.inl b/src/glm/gtx/bit.inl
new file mode 100644
index 0000000..72d3c7a
--- /dev/null
+++ b/src/glm/gtx/bit.inl
@@ -0,0 +1,743 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2007-03-14
+// Updated : 2008-11-14
+// Licence : This source is under MIT License
+// File : glm/gtx/bit.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#include "../core/_detail.hpp"
+
+namespace glm{
+namespace gtx{
+namespace bit{
+
+template <typename genIType>
+GLM_FUNC_QUALIFIER genIType mask
+(
+ genIType const & count
+)
+{
+ return ((genIType(1) << (count)) - genIType(1));
+}
+
+template <typename valIType>
+GLM_FUNC_QUALIFIER detail::tvec2<valIType> mask
+(
+ detail::tvec2<valIType> const & count
+)
+{
+ return detail::tvec2<valIType>(
+ mask(count[0]),
+ mask(count[1]));
+}
+
+template <typename valIType>
+GLM_FUNC_QUALIFIER detail::tvec3<valIType> mask
+(
+ detail::tvec3<valIType> const & count
+)
+{
+ return detail::tvec3<valIType>(
+ mask(count[0]),
+ mask(count[1]),
+ mask(count[2]));
+}
+
+template <typename valIType>
+GLM_FUNC_QUALIFIER detail::tvec4<valIType> mask
+(
+ detail::tvec4<valIType> const & count
+)
+{
+ return detail::tvec4<valIType>(
+ mask(count[0]),
+ mask(count[1]),
+ mask(count[2]),
+ mask(count[3]));
+}
+
+// extractField
+template <typename genIType>
+GLM_FUNC_QUALIFIER genIType extractField
+(
+ gtc::half_float::half const & value,
+ genIType const & first,
+ genIType const & count
+)
+{
+ assert(first + count < sizeof(gtc::half_float::half));
+ return (value._data() << first) >> ((sizeof(gtc::half_float::half) << 3) - count);
+}
+
+template <typename genIType>
+GLM_FUNC_QUALIFIER genIType extractField
+(
+ float const & value,
+ genIType const & first,
+ genIType const & count
+)
+{
+ assert(first + count < sizeof(float));
+ return (detail::uif32(value).i << first) >> ((sizeof(float) << 3) - count);
+}
+
+template <typename genIType>
+GLM_FUNC_QUALIFIER genIType extractField
+(
+ double const & value,
+ genIType const & first,
+ genIType const & count
+)
+{
+ assert(first + count < sizeof(double));
+ return (detail::uif64(value).i << first) >> ((sizeof(double) << genIType(3)) - count);
+}
+
+template <typename genIUType, typename sizeType>
+GLM_FUNC_QUALIFIER genIUType extractField
+(
+ genIUType const & Value,
+ sizeType const & First,
+ sizeType const & Count
+)
+{
+ sizeType GenSize = sizeof(genIUType) << 3;
+
+ assert(First + Count <= GenSize);
+
+ genIUType ShiftLeft = Count ? Value << (GenSize - (Count + First)) : 0;
+ genIUType ShiftBack = ShiftLeft >> genIUType(GenSize - Count);
+
+ return ShiftBack;
+}
+
+template <typename genIUType, typename sizeType>
+GLM_FUNC_QUALIFIER detail::tvec2<genIUType> extractField
+(
+ detail::tvec2<genIUType> const & value,
+ sizeType const & first,
+ sizeType const & count
+)
+{
+ return detail::tvec2<genIUType>(
+ extractField(value[0], first, count),
+ extractField(value[1], first, count));
+}
+
+template <typename genIUType, typename sizeType>
+GLM_FUNC_QUALIFIER detail::tvec3<genIUType> extractField
+(
+ detail::tvec3<genIUType> const & value,
+ sizeType const & first,
+ sizeType const & count
+)
+{
+ return detail::tvec3<genIUType>(
+ extractField(value[0], first, count),
+ extractField(value[1], first, count),
+ extractField(value[2], first, count));
+}
+
+template <typename genIUType, typename sizeType>
+GLM_FUNC_QUALIFIER detail::tvec4<genIUType> extractField
+(
+ detail::tvec4<genIUType> const & value,
+ sizeType const & first,
+ sizeType const & count
+)
+{
+ return detail::tvec4<genIUType>(
+ extractField(value[0], first, count),
+ extractField(value[1], first, count),
+ extractField(value[2], first, count),
+ extractField(value[3], first, count));
+}
+
+template <typename genIUType, typename sizeType>
+GLM_FUNC_QUALIFIER detail::tvec2<genIUType> extractField
+(
+ detail::tvec2<genIUType> const & value,
+ detail::tvec2<sizeType> const & first,
+ detail::tvec2<sizeType> const & count
+)
+{
+ return detail::tvec2<genIUType>(
+ extractField(value[0], first[0], count[0]),
+ extractField(value[1], first[1], count[1]));
+}
+
+template <typename genIUType, typename sizeType>
+GLM_FUNC_QUALIFIER detail::tvec3<genIUType> extractField
+(
+ detail::tvec3<genIUType> const & value,
+ detail::tvec3<sizeType> const & first,
+ detail::tvec3<sizeType> const & count
+)
+{
+ return detail::tvec3<genIUType>(
+ extractField(value[0], first[0], count[0]),
+ extractField(value[1], first[1], count[1]),
+ extractField(value[2], first[2], count[2]));
+}
+
+template <typename genIUType, typename sizeType>
+GLM_FUNC_QUALIFIER detail::tvec4<genIUType> extractField
+(
+ detail::tvec4<genIUType> const & value,
+ detail::tvec4<sizeType> const & first,
+ detail::tvec4<sizeType> const & count
+)
+{
+ return detail::tvec4<genIUType>(
+ extractField(value[0], first[0], count[0]),
+ extractField(value[1], first[1], count[1]),
+ extractField(value[2], first[2], count[2]),
+ extractField(value[3], first[3], count[3]));
+}
+
+template <typename genIUType, typename sizeType>
+GLM_FUNC_QUALIFIER detail::tvec2<genIUType> extractField
+(
+ genIUType const & value,
+ detail::tvec2<sizeType> const & first,
+ detail::tvec2<sizeType> const & count
+)
+{
+ return detail::tvec2<genIUType>(
+ extractField(value, first[0], count[0]),
+ extractField(value, first[1], count[1]));
+}
+
+template <typename genIUType, typename sizeType>
+GLM_FUNC_QUALIFIER detail::tvec3<genIUType> extractField
+(
+ genIUType const & value,
+ detail::tvec3<sizeType> const & first,
+ detail::tvec3<sizeType> const & count
+)
+{
+ return detail::tvec3<genIUType>(
+ extractField(value, first[0], count[0]),
+ extractField(value, first[1], count[1]),
+ extractField(value, first[2], count[2]));
+}
+
+template <typename genIUType, typename sizeType>
+GLM_FUNC_QUALIFIER detail::tvec4<genIUType> extractField
+(
+ genIUType const & value,
+ detail::tvec4<sizeType> const & first,
+ detail::tvec4<sizeType> const & count
+)
+{
+ return detail::tvec4<genIUType>(
+ extractField(value, first[0], count[0]),
+ extractField(value, first[1], count[1]),
+ extractField(value, first[2], count[2]),
+ extractField(value, first[3], count[3]));
+}
+
+// lowestBit
+template <typename genType>
+GLM_FUNC_QUALIFIER int lowestBit
+(
+ genType const & Value
+)
+{
+ assert(Value != genType(0)); // not valid call
+
+ genType Bit;
+ for(Bit = genType(0); !(Value & (1 << Bit)); ++Bit){}
+ return Bit;
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec2<int> lowestBit
+(
+ detail::tvec2<valType> const & value
+)
+{
+ return detail::tvec2<int>(
+ lowestBit(value[0]),
+ lowestBit(value[1]));
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec3<int> lowestBit
+(
+ detail::tvec3<valType> const & value
+)
+{
+ return detail::tvec3<int>(
+ lowestBit(value[0]),
+ lowestBit(value[1]),
+ lowestBit(value[2]));
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec4<int> lowestBit
+(
+ detail::tvec4<valType> const & value
+)
+{
+ return detail::tvec4<int>(
+ lowestBit(value[0]),
+ lowestBit(value[1]),
+ lowestBit(value[2]),
+ lowestBit(value[3]));
+}
+
+// highestBit
+template <typename genType>
+GLM_FUNC_QUALIFIER int highestBit
+(
+ genType const & value
+)
+{
+ assert(value != genType(0)); // not valid call
+
+ genType bit = genType(-1);
+ for(genType tmp = value; tmp; tmp >>= 1, ++bit){}
+ return bit;
+}
+
+//template <>
+//GLM_FUNC_QUALIFIER int highestBit<int>
+//(
+// int value
+//)
+//{
+// int bit = -1;
+// for(int tmp = value; tmp; tmp >>= 1, ++bit);
+// return bit;
+//}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec2<int> highestBit
+(
+ detail::tvec2<valType> const & value
+)
+{
+ return detail::tvec2<int>(
+ highestBit(value[0]),
+ highestBit(value[1]));
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec3<int> highestBit
+(
+ detail::tvec3<valType> const & value
+)
+{
+ return detail::tvec3<int>(
+ highestBit(value[0]),
+ highestBit(value[1]),
+ highestBit(value[2]));
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec4<int> highestBit
+(
+ detail::tvec4<valType> const & value
+)
+{
+ return detail::tvec4<int>(
+ highestBit(value[0]),
+ highestBit(value[1]),
+ highestBit(value[2]),
+ highestBit(value[3]));
+}
+
+// highestBitValue
+template <typename genType>
+GLM_FUNC_QUALIFIER genType highestBitValue
+(
+ genType const & value
+)
+{
+ genType tmp = value;
+ genType result = genType(0);
+ while(tmp)
+ {
+ result = (tmp & (~tmp + 1)); // grab lowest bit
+ tmp &= ~result; // clear lowest bit
+ }
+ return result;
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec2<int> highestBitValue
+(
+ detail::tvec2<valType> const & value
+)
+{
+ return detail::tvec2<int>(
+ highestBitValue(value[0]),
+ highestBitValue(value[1]));
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec3<int> highestBitValue
+(
+ detail::tvec3<valType> const & value
+)
+{
+ return detail::tvec3<int>(
+ highestBitValue(value[0]),
+ highestBitValue(value[1]),
+ highestBitValue(value[2]));
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec4<int> highestBitValue
+(
+ detail::tvec4<valType> const & value
+)
+{
+ return detail::tvec4<int>(
+ highestBitValue(value[0]),
+ highestBitValue(value[1]),
+ highestBitValue(value[2]),
+ highestBitValue(value[3]));
+}
+
+// isPowerOfTwo
+template <typename genType>
+GLM_FUNC_QUALIFIER bool isPowerOfTwo(genType const & Value)
+{
+ //detail::If<std::numeric_limits<genType>::is_signed>::apply(abs, Value);
+ //return !(Value & (Value - 1));
+
+ // For old complier?
+ genType Result = Value;
+ if(std::numeric_limits<genType>::is_signed)
+ Result = abs(Result);
+ return !(Result & (Result - 1));
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec2<bool> isPowerOfTwo
+(
+ detail::tvec2<valType> const & value
+)
+{
+ return detail::tvec2<bool>(
+ isPowerOfTwo(value[0]),
+ isPowerOfTwo(value[1]));
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec3<bool> isPowerOfTwo
+(
+ detail::tvec3<valType> const & value
+)
+{
+ return detail::tvec3<bool>(
+ isPowerOfTwo(value[0]),
+ isPowerOfTwo(value[1]),
+ isPowerOfTwo(value[2]));
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec4<bool> isPowerOfTwo
+(
+ detail::tvec4<valType> const & value
+)
+{
+ return detail::tvec4<bool>(
+ isPowerOfTwo(value[0]),
+ isPowerOfTwo(value[1]),
+ isPowerOfTwo(value[2]),
+ isPowerOfTwo(value[3]));
+}
+
+// powerOfTwoAbove
+template <typename genType>
+GLM_FUNC_QUALIFIER genType powerOfTwoAbove(genType const & value)
+{
+ return isPowerOfTwo(value) ? value : highestBitValue(value) << 1;
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec2<valType> powerOfTwoAbove
+(
+ detail::tvec2<valType> const & value
+)
+{
+ return detail::tvec2<valType>(
+ powerOfTwoAbove(value[0]),
+ powerOfTwoAbove(value[1]));
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec3<valType> powerOfTwoAbove
+(
+ detail::tvec3<valType> const & value
+)
+{
+ return detail::tvec3<valType>(
+ powerOfTwoAbove(value[0]),
+ powerOfTwoAbove(value[1]),
+ powerOfTwoAbove(value[2]));
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec4<valType> powerOfTwoAbove
+(
+ detail::tvec4<valType> const & value
+)
+{
+ return detail::tvec4<valType>(
+ powerOfTwoAbove(value[0]),
+ powerOfTwoAbove(value[1]),
+ powerOfTwoAbove(value[2]),
+ powerOfTwoAbove(value[3]));
+}
+
+// powerOfTwoBelow
+template <typename genType>
+GLM_FUNC_QUALIFIER genType powerOfTwoBelow
+(
+ genType const & value
+)
+{
+ return isPowerOfTwo(value) ? value : highestBitValue(value);
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec2<valType> powerOfTwoBelow
+(
+ detail::tvec2<valType> const & value
+)
+{
+ return detail::tvec2<valType>(
+ powerOfTwoBelow(value[0]),
+ powerOfTwoBelow(value[1]));
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec3<valType> powerOfTwoBelow
+(
+ detail::tvec3<valType> const & value
+)
+{
+ return detail::tvec3<valType>(
+ powerOfTwoBelow(value[0]),
+ powerOfTwoBelow(value[1]),
+ powerOfTwoBelow(value[2]));
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec4<valType> powerOfTwoBelow
+(
+ detail::tvec4<valType> const & value
+)
+{
+ return detail::tvec4<valType>(
+ powerOfTwoBelow(value[0]),
+ powerOfTwoBelow(value[1]),
+ powerOfTwoBelow(value[2]),
+ powerOfTwoBelow(value[3]));
+}
+
+// powerOfTwoNearest
+template <typename genType>
+GLM_FUNC_QUALIFIER genType powerOfTwoNearest
+(
+ genType const & value
+)
+{
+ if(isPowerOfTwo(value))
+ return value;
+
+ genType prev = highestBitValue(value);
+ genType next = prev << 1;
+ return (next - value) < (value - prev) ? next : prev;
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec2<valType> powerOfTwoNearest
+(
+ detail::tvec2<valType> const & value
+)
+{
+ return detail::tvec2<valType>(
+ powerOfTwoNearest(value[0]),
+ powerOfTwoNearest(value[1]));
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec3<valType> powerOfTwoNearest
+(
+ detail::tvec3<valType> const & value
+)
+{
+ return detail::tvec3<valType>(
+ powerOfTwoNearest(value[0]),
+ powerOfTwoNearest(value[1]),
+ powerOfTwoNearest(value[2]));
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec4<valType> powerOfTwoNearest
+(
+ detail::tvec4<valType> const & value
+)
+{
+ return detail::tvec4<valType>(
+ powerOfTwoNearest(value[0]),
+ powerOfTwoNearest(value[1]),
+ powerOfTwoNearest(value[2]),
+ powerOfTwoNearest(value[3]));
+}
+
+template <typename genType>
+GLM_FUNC_QUALIFIER genType bitRevert(genType const & In)
+{
+ GLM_STATIC_ASSERT(std::numeric_limits<genType>::is_integer, "'bitRevert' only accept integer values");
+
+ genType Out = 0;
+ std::size_t BitSize = sizeof(genType) * 8;
+ for(std::size_t i = 0; i < BitSize; ++i)
+ if(In & (genType(1) << i))
+ Out |= genType(1) << (BitSize - 1 - i);
+ return Out;
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec2<valType> bitRevert
+(
+ detail::tvec2<valType> const & Value
+)
+{
+ return detail::tvec2<valType>(
+ bitRevert(Value[0]),
+ bitRevert(Value[1]));
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec3<valType> bitRevert
+(
+ detail::tvec3<valType> const & Value
+)
+{
+ return detail::tvec3<valType>(
+ bitRevert(Value[0]),
+ bitRevert(Value[1]),
+ bitRevert(Value[2]));
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec4<valType> bitRevert
+(
+ detail::tvec4<valType> const & Value
+)
+{
+ return detail::tvec4<valType>(
+ bitRevert(Value[0]),
+ bitRevert(Value[1]),
+ bitRevert(Value[2]),
+ bitRevert(Value[3]));
+}
+
+template <typename genType>
+GLM_FUNC_QUALIFIER genType bitRotateRight(genType const & In, std::size_t Shift)
+{
+ GLM_STATIC_ASSERT(std::numeric_limits<genType>::is_integer, "'bitRotateRight' only accept integer values");
+
+ std::size_t BitSize = sizeof(genType) * 8;
+ return (In << Shift) | (In >> (BitSize - Shift));
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec2<valType> bitRotateRight
+(
+ detail::tvec2<valType> const & Value,
+ std::size_t Shift
+)
+{
+ return detail::tvec2<valType>(
+ bitRotateRight(Value[0], Shift),
+ bitRotateRight(Value[1], Shift));
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec3<valType> bitRotateRight
+(
+ detail::tvec3<valType> const & Value,
+ std::size_t Shift
+)
+{
+ return detail::tvec3<valType>(
+ bitRotateRight(Value[0], Shift),
+ bitRotateRight(Value[1], Shift),
+ bitRotateRight(Value[2], Shift));
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec4<valType> bitRotateRight
+(
+ detail::tvec4<valType> const & Value,
+ std::size_t Shift
+)
+{
+ return detail::tvec4<valType>(
+ bitRotateRight(Value[0], Shift),
+ bitRotateRight(Value[1], Shift),
+ bitRotateRight(Value[2], Shift),
+ bitRotateRight(Value[3], Shift));
+}
+
+template <typename genType>
+GLM_FUNC_QUALIFIER genType bitRotateLeft(genType const & In, std::size_t Shift)
+{
+ GLM_STATIC_ASSERT(std::numeric_limits<genType>::is_integer, "'bitRotateLeft' only accept integer values");
+
+ std::size_t BitSize = sizeof(genType) * 8;
+ return (In >> Shift) | (In << (BitSize - Shift));
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec2<valType> bitRotateLeft
+(
+ detail::tvec2<valType> const & Value,
+ std::size_t Shift
+)
+{
+ return detail::tvec2<valType>(
+ bitRotateLeft(Value[0], Shift),
+ bitRotateLeft(Value[1], Shift));
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec3<valType> bitRotateLeft
+(
+ detail::tvec3<valType> const & Value,
+ std::size_t Shift
+)
+{
+ return detail::tvec3<valType>(
+ bitRotateLeft(Value[0], Shift),
+ bitRotateLeft(Value[1], Shift),
+ bitRotateLeft(Value[2], Shift));
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec4<valType> bitRotateLeft
+(
+ detail::tvec4<valType> const & Value,
+ std::size_t Shift
+)
+{
+ return detail::tvec4<valType>(
+ bitRotateLeft(Value[0], Shift),
+ bitRotateLeft(Value[1], Shift),
+ bitRotateLeft(Value[2], Shift),
+ bitRotateLeft(Value[3], Shift));
+}
+
+}//namespace bit
+}//namespace gtx
+}//namespace glm
diff --git a/src/glm/gtx/closest_point.hpp b/src/glm/gtx/closest_point.hpp
new file mode 100644
index 0000000..e70d561
--- /dev/null
+++ b/src/glm/gtx/closest_point.hpp
@@ -0,0 +1,47 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2005-12-30
+// Updated : 2008-10-05
+// Licence : This source is under MIT License
+// File : glm/gtx/closest_point.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_gtx_closest_point
+#define glm_gtx_closest_point
+
+// Dependency:
+#include "../glm.hpp"
+
+#if(defined(GLM_MESSAGES) && !defined(glm_ext))
+# pragma message("GLM: GLM_GTX_closest_point extension included")
+#endif
+
+namespace glm{
+namespace gtx{
+namespace closest_point ///< GLM_GTX_closest_point extension: Find the point on a straight line which is the closet of a point.
+{
+ /// \addtogroup gtx_closest_point
+ /// @{
+
+ /// Find the point on a straight line which is the closet of a point.
+ /// From GLM_GTX_closest_point extension.
+ template <typename T>
+ detail::tvec3<T> closestPointOnLine(
+ detail::tvec3<T> const & point,
+ detail::tvec3<T> const & a,
+ detail::tvec3<T> const & b);
+
+ /// @}
+}// namespace closest_point
+}// namespace gtx
+}// namespace glm
+
+#include "closest_point.inl"
+
+namespace glm{using namespace gtx::closest_point;}
+
+#endif//glm_gtx_closest_point
diff --git a/src/glm/gtx/closest_point.inl b/src/glm/gtx/closest_point.inl
new file mode 100644
index 0000000..efd110c
--- /dev/null
+++ b/src/glm/gtx/closest_point.inl
@@ -0,0 +1,41 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2005-12-30
+// Updated : 2008-10-05
+// Licence : This source is under MIT License
+// File : glm/gtx/closest_point.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_gtx_closest_point
+#define glm_gtx_closest_point
+
+namespace glm{
+namespace gtx{
+namespace closest_point{
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec3<valType> closestPointOnLine
+(
+ detail::tvec3<valType> const & point,
+ detail::tvec3<valType> const & a,
+ detail::tvec3<valType> const & b
+)
+{
+ valType LineLength = distance(a, b);
+ detail::tvec3<valType> Vector = point - a;
+ detail::tvec3<valType> LineDirection = (b - a) / LineLength;
+
+ // Project Vector to LineDirection to get the distance of point from a
+ valType Distance = dot(Vector, LineDirection);
+
+ if(Distance <= valType(0)) return a;
+ if(Distance >= LineLength) return b;
+ return a + LineDirection * Distance;
+}
+
+}//namespace closest_point
+}//namespace gtx
+}//namespace glm
+
+#endif//glm_gtx_closest_point
diff --git a/src/glm/gtx/color_cast.hpp b/src/glm/gtx/color_cast.hpp
new file mode 100644
index 0000000..165181f
--- /dev/null
+++ b/src/glm/gtx/color_cast.hpp
@@ -0,0 +1,107 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2007-06-21
+// Updated : 2009-06-05
+// Licence : This source is under MIT License
+// File : glm/gtx/color_cast.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+// - GLM_GTX_number_precision
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_gtx_color_cast
+#define glm_gtx_color_cast
+
+// Dependency:
+#include "../glm.hpp"
+#include "../gtx/number_precision.hpp"
+
+#if(defined(GLM_MESSAGES) && !defined(glm_ext))
+# pragma message("GLM: GLM_GTX_color_cast extension included")
+#endif
+
+namespace glm{
+namespace gtx{
+namespace color_cast ///< GLM_GTX_color_cast extension: Conversion between two color types
+{
+ using namespace gtx::number_precision;
+
+ /// \addtogroup gtx_color_cast
+ ///@{
+
+ //! Conversion of a floating value into a 8bit unsigned int value.
+ //! From GLM_GTX_color_cast extension.
+ template <typename valType> gtc::type_precision::uint8 u8channel_cast(valType a);
+
+ //! Conversion of a floating value into a 16bit unsigned int value.
+ //! From GLM_GTX_color_cast extension.
+ template <typename valType> gtc::type_precision::uint16 u16channel_cast(valType a);
+
+ template <typename T> gtc::type_precision::uint32 u32_rgbx_cast(const detail::tvec3<T>& c); //!< \brief Conversion of a 3 components color into an 32bit unsigned int value. (From GLM_GTX_color_cast extension)
+ template <typename T> gtc::type_precision::uint32 u32_xrgb_cast(const detail::tvec3<T>& c); //!< \brief Conversion of a 3 components color into an 32bit unsigned int value. (From GLM_GTX_color_cast extension)
+ template <typename T> gtc::type_precision::uint32 u32_bgrx_cast(const detail::tvec3<T>& c); //!< \brief Conversion of a 3 components color into an 32bit unsigned int value. (From GLM_GTX_color_cast extension)
+ template <typename T> gtc::type_precision::uint32 u32_xbgr_cast(const detail::tvec3<T>& c); //!< \brief Conversion of a 3 components color into an 32bit unsigned int value. (From GLM_GTX_color_cast extension)
+
+ template <typename T> gtc::type_precision::uint32 u32_rgba_cast(const detail::tvec4<T>& c); //!< \brief Conversion of a 4 components color into an 32bit unsigned int value. (From GLM_GTX_color_cast extension)
+ template <typename T> gtc::type_precision::uint32 u32_argb_cast(const detail::tvec4<T>& c); //!< \brief Conversion of a 4 components color into an 32bit unsigned int value. (From GLM_GTX_color_cast extension)
+ template <typename T> gtc::type_precision::uint32 u32_bgra_cast(const detail::tvec4<T>& c); //!< \brief Conversion of a 4 components color into an 32bit unsigned int value. (From GLM_GTX_color_cast extension)
+ template <typename T> gtc::type_precision::uint32 u32_abgr_cast(const detail::tvec4<T>& c); //!< \brief Conversion of a 4 components color into an 32bit unsigned int value. (From GLM_GTX_color_cast extension)
+
+ template <typename T> gtc::type_precision::uint64 u64_rgbx_cast(const detail::tvec3<T>& c); //!< \brief Conversion of a 3 components color into an 64bit unsigned int value. (From GLM_GTX_color_cast extension)
+ template <typename T> gtc::type_precision::uint64 u64_xrgb_cast(const detail::tvec3<T>& c); //!< \brief Conversion of a 3 components color into an 64bit unsigned int value. (From GLM_GTX_color_cast extension)
+ template <typename T> gtc::type_precision::uint64 u64_bgrx_cast(const detail::tvec3<T>& c); //!< \brief Conversion of a 3 components color into an 64bit unsigned int value. (From GLM_GTX_color_cast extension)
+ template <typename T> gtc::type_precision::uint64 u64_xbgr_cast(const detail::tvec3<T>& c); //!< \brief Conversion of a 3 components color into an 64bit unsigned int value. (From GLM_GTX_color_cast extension)
+
+ template <typename T> gtc::type_precision::uint64 u64_rgba_cast(const detail::tvec4<T>& c); //!< \brief Conversion of a 4 components color into an 64bit unsigned int value. (From GLM_GTX_color_cast extension)
+ template <typename T> gtc::type_precision::uint64 u64_argb_cast(const detail::tvec4<T>& c); //!< \brief Conversion of a 4 components color into an 64bit unsigned int value. (From GLM_GTX_color_cast extension)
+ template <typename T> gtc::type_precision::uint64 u64_bgra_cast(const detail::tvec4<T>& c); //!< \brief Conversion of a 4 components color into an 64bit unsigned int value. (From GLM_GTX_color_cast extension)
+ template <typename T> gtc::type_precision::uint64 u64_abgr_cast(const detail::tvec4<T>& c); //!< \brief Conversion of a 4 components color into an 64bit unsigned int value. (From GLM_GTX_color_cast extension)
+
+ template <typename T> gtx::number_precision::f16vec1 f16_channel_cast(T a); //!< \brief Conversion of a u8 or u16 value to a single channel floating value. (From GLM_GTX_color_cast extension)
+
+ template <typename T> gtc::type_precision::f16vec3 f16_rgbx_cast(T c); //!< \brief Conversion of a u32 or u64 color into 3 components floating color. (From GLM_GTX_color_cast extension)
+ template <typename T> gtc::type_precision::f16vec3 f16_xrgb_cast(T c); //!< \brief Conversion of a u32 or u64 color into 3 components floating color. (From GLM_GTX_color_cast extension)
+ template <typename T> gtc::type_precision::f16vec3 f16_bgrx_cast(T c); //!< \brief Conversion of a u32 or u64 color into 3 components floating color. (From GLM_GTX_color_cast extension)
+ template <typename T> gtc::type_precision::f16vec3 f16_xbgr_cast(T c); //!< \brief Conversion of a u32 or u64 color into 3 components floating color. (From GLM_GTX_color_cast extension)
+
+ template <typename T> gtc::type_precision::f16vec4 f16_rgba_cast(T c); //!< \brief Conversion of a u32 or u64 color into 4 components floating color. (From GLM_GTX_color_cast extension)
+ template <typename T> gtc::type_precision::f16vec4 f16_argb_cast(T c); //!< \brief Conversion of a u32 or u64 color into 4 components floating color. (From GLM_GTX_color_cast extension)
+ template <typename T> gtc::type_precision::f16vec4 f16_bgra_cast(T c); //!< \brief Conversion of a u32 or u64 color into 4 components floating color. (From GLM_GTX_color_cast extension)
+ template <typename T> gtc::type_precision::f16vec4 f16_abgr_cast(T c); //!< \brief Conversion of a u32 or u64 color into 4 components floating color. (From GLM_GTX_color_cast extension)
+
+ template <typename T> gtx::number_precision::f32vec1 f32_channel_cast(T a); //!< \brief Conversion of a u8 or u16 value to a single channel floating value. (From GLM_GTX_color_cast extension)
+
+ template <typename T> gtc::type_precision::f32vec3 f32_rgbx_cast(T c); //!< \brief Conversion of a u32 or u64 color into 3 components floating color. (From GLM_GTX_color_cast extension)
+ template <typename T> gtc::type_precision::f32vec3 f32_xrgb_cast(T c); //!< \brief Conversion of a u32 or u64 color into 3 components floating color. (From GLM_GTX_color_cast extension)
+ template <typename T> gtc::type_precision::f32vec3 f32_bgrx_cast(T c); //!< \brief Conversion of a u32 or u64 color into 3 components floating color. (From GLM_GTX_color_cast extension)
+ template <typename T> gtc::type_precision::f32vec3 f32_xbgr_cast(T c); //!< \brief Conversion of a u32 or u64 color into 3 components floating color. (From GLM_GTX_color_cast extension)
+
+ template <typename T> gtc::type_precision::f32vec4 f32_rgba_cast(T c); //!< \brief Conversion of a u32 or u64 color into 4 components floating color. (From GLM_GTX_color_cast extension)
+ template <typename T> gtc::type_precision::f32vec4 f32_argb_cast(T c); //!< \brief Conversion of a u32 or u64 color into 4 components floating color. (From GLM_GTX_color_cast extension)
+ template <typename T> gtc::type_precision::f32vec4 f32_bgra_cast(T c); //!< \brief Conversion of a u32 or u64 color into 4 components floating color. (From GLM_GTX_color_cast extension)
+ template <typename T> gtc::type_precision::f32vec4 f32_abgr_cast(T c); //!< \brief Conversion of a u32 or u64 color into 4 components floating color. (From GLM_GTX_color_cast extension)
+
+ template <typename T> gtx::number_precision::f64vec1 f64_channel_cast(T a); //!< \brief Conversion of a u8 or u16 value to a single channel floating value. (From GLM_GTX_color_cast extension)
+
+ template <typename T> gtc::type_precision::f64vec3 f64_rgbx_cast(T c); //!< \brief Conversion of a u32 or u64 color into 3 components floating color. (From GLM_GTX_color_cast extension)
+ template <typename T> gtc::type_precision::f64vec3 f64_xrgb_cast(T c); //!< \brief Conversion of a u32 or u64 color into 3 components floating color. (From GLM_GTX_color_cast extension)
+ template <typename T> gtc::type_precision::f64vec3 f64_bgrx_cast(T c); //!< \brief Conversion of a u32 or u64 color into 3 components floating color. (From GLM_GTX_color_cast extension)
+ template <typename T> gtc::type_precision::f64vec3 f64_xbgr_cast(T c); //!< \brief Conversion of a u32 or u64 color into 3 components floating color. (From GLM_GTX_color_cast extension)
+
+ template <typename T> gtc::type_precision::f64vec4 f64_rgba_cast(T c); //!< \brief Conversion of a u32 or u64 color into 4 components floating color. (From GLM_GTX_color_cast extension)
+ template <typename T> gtc::type_precision::f64vec4 f64_argb_cast(T c); //!< \brief Conversion of a u32 or u64 color into 4 components floating color. (From GLM_GTX_color_cast extension)
+ template <typename T> gtc::type_precision::f64vec4 f64_bgra_cast(T c); //!< \brief Conversion of a u32 or u64 color into 4 components floating color. (From GLM_GTX_color_cast extension)
+ template <typename T> gtc::type_precision::f64vec4 f64_abgr_cast(T c); //!< \brief Conversion of a u32 or u64 color into 4 components floating color. (From GLM_GTX_color_cast extension)
+
+ ///@}
+}//namespace color_space
+}//namespace gtx
+}//namespace glm
+
+#include "color_cast.inl"
+
+namespace glm{using namespace gtx::color_cast;}
+
+#endif//glm_gtx_color_cast
diff --git a/src/glm/gtx/color_cast.inl b/src/glm/gtx/color_cast.inl
new file mode 100644
index 0000000..e1dc171
--- /dev/null
+++ b/src/glm/gtx/color_cast.inl
@@ -0,0 +1,739 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2007-06-21
+// Updated : 2007-08-03
+// Licence : This source is under MIT License
+// File : glm/gtx/color_cast.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm{
+namespace gtx{
+//! GLM_GTX_color_cast extension: Conversion between two color types
+namespace color_cast{
+
+template <typename T>
+GLM_FUNC_QUALIFIER gtc::type_precision::uint8 u8channel_cast(T a)
+{
+ return static_cast<gtc::type_precision::uint8>(a * T(255));
+}
+
+template <typename T>
+GLM_FUNC_QUALIFIER gtc::type_precision::uint16 u16channel_cast(T a)
+{
+ return static_cast<gtc::type_precision::uint16>(a * T(65535));
+}
+
+template <typename T>
+GLM_FUNC_QUALIFIER gtc::type_precision::uint32 u32_rgbx_cast(const detail::tvec3<T>& c)
+{
+ gtc::type_precision::uint32 result = 0;
+ result += static_cast<gtc::type_precision::uint32>(c.x * detail::tvec3<T>::value_type(255)) << 0;
+ result += static_cast<gtc::type_precision::uint32>(c.y * detail::tvec3<T>::value_type(255)) << 8;
+ result += static_cast<gtc::type_precision::uint32>(c.z * detail::tvec3<T>::value_type(255)) << 16;
+ return result;
+}
+
+template <typename T>
+GLM_FUNC_QUALIFIER gtc::type_precision::uint32 u32_xrgb_cast(const detail::tvec3<T>& c)
+{
+ gtc::type_precision::uint32 result = 0;
+ result += static_cast<gtc::type_precision::uint32>(c.x * detail::tvec3<T>::value_type(255)) << 8;
+ result += static_cast<gtc::type_precision::uint32>(c.y * detail::tvec3<T>::value_type(255)) << 16;
+ result += static_cast<gtc::type_precision::uint32>(c.z * detail::tvec3<T>::value_type(255)) << 24;
+ return result;
+}
+
+template <typename T>
+GLM_FUNC_QUALIFIER gtc::type_precision::uint32 u32_bgrx_cast(const detail::tvec3<T>& c)
+{
+ gtc::type_precision::uint32 result = 0;
+ result += static_cast<gtc::type_precision::uint32>(c.x * detail::tvec3<T>::value_type(255)) << 16;
+ result += static_cast<gtc::type_precision::uint32>(c.y * detail::tvec3<T>::value_type(255)) << 8;
+ result += static_cast<gtc::type_precision::uint32>(c.z * detail::tvec3<T>::value_type(255)) << 0;
+ return result;
+}
+
+template <typename T>
+GLM_FUNC_QUALIFIER gtc::type_precision::uint32 u32_xbgr_cast(const detail::tvec3<T>& c)
+{
+ gtc::type_precision::uint32 result = 0;
+ result += static_cast<gtc::type_precision::uint32>(c.x * detail::tvec3<T>::value_type(255)) << 24;
+ result += static_cast<gtc::type_precision::uint32>(c.y * detail::tvec3<T>::value_type(255)) << 16;
+ result += static_cast<gtc::type_precision::uint32>(c.z * detail::tvec3<T>::value_type(255)) << 8;
+ result += static_cast<gtc::type_precision::uint32>(c.w * detail::tvec3<T>::value_type(255)) << 0;
+ return result;
+}
+
+template <typename T>
+GLM_FUNC_QUALIFIER gtc::type_precision::uint32 u32_rgba_cast(const detail::tvec4<T>& c)
+{
+ gtc::type_precision::uint32 result = 0;
+ result += static_cast<gtc::type_precision::uint32>(c.x * detail::tvec4<T>::value_type(255)) << 0;
+ result += static_cast<gtc::type_precision::uint32>(c.y * detail::tvec4<T>::value_type(255)) << 8;
+ result += static_cast<gtc::type_precision::uint32>(c.z * detail::tvec4<T>::value_type(255)) << 16;
+ result += static_cast<gtc::type_precision::uint32>(c.w * detail::tvec4<T>::value_type(255)) << 24;
+ return result;
+}
+
+template <typename T>
+GLM_FUNC_QUALIFIER gtc::type_precision::uint32 u32_argb_cast(const detail::tvec4<T>& c)
+{
+ gtc::type_precision::uint32 result = 0;
+ result += static_cast<gtc::type_precision::uint32>(c.x * detail::tvec4<T>::value_type(255)) << 8;
+ result += static_cast<gtc::type_precision::uint32>(c.y * detail::tvec4<T>::value_type(255)) << 16;
+ result += static_cast<gtc::type_precision::uint32>(c.z * detail::tvec4<T>::value_type(255)) << 24;
+ result += static_cast<gtc::type_precision::uint32>(c.w * detail::tvec4<T>::value_type(255)) << 0;
+ return result;
+}
+
+template <typename T>
+GLM_FUNC_QUALIFIER gtc::type_precision::uint32 u32_bgra_cast(const detail::tvec4<T>& c)
+{
+ gtc::type_precision::uint32 result = 0;
+ result += static_cast<gtc::type_precision::uint32>(c.x * detail::tvec4<T>::value_type(255)) << 16;
+ result += static_cast<gtc::type_precision::uint32>(c.y * detail::tvec4<T>::value_type(255)) << 8;
+ result += static_cast<gtc::type_precision::uint32>(c.z * detail::tvec4<T>::value_type(255)) << 0;
+ result += static_cast<gtc::type_precision::uint32>(c.w * detail::tvec4<T>::value_type(255)) << 24;
+ return result;
+}
+
+template <typename T>
+GLM_FUNC_QUALIFIER gtc::type_precision::uint32 u32_abgr_cast(const detail::tvec4<T>& c)
+{
+ gtc::type_precision::uint32 result = 0;
+ result += static_cast<gtc::type_precision::uint32>(c.x * detail::tvec4<T>::value_type(255)) << 24;
+ result += static_cast<gtc::type_precision::uint32>(c.y * detail::tvec4<T>::value_type(255)) << 16;
+ result += static_cast<gtc::type_precision::uint32>(c.z * detail::tvec4<T>::value_type(255)) << 8;
+ result += static_cast<gtc::type_precision::uint32>(c.w * detail::tvec4<T>::value_type(255)) << 0;
+ return result;
+}
+
+template <typename T>
+GLM_FUNC_QUALIFIER gtc::type_precision::uint64 u64_rgbx_cast(const detail::tvec3<T>& c)
+{
+ gtc::type_precision::uint64 result = 0;
+ result += static_cast<gtc::type_precision::uint64>(c.x * detail::tvec3<T>::value_type(65535)) << 0;
+ result += static_cast<gtc::type_precision::uint64>(c.y * detail::tvec3<T>::value_type(65535)) << 16;
+ result += static_cast<gtc::type_precision::uint64>(c.z * detail::tvec3<T>::value_type(65535)) << 32;
+ return result;
+}
+
+template <typename T>
+GLM_FUNC_QUALIFIER gtc::type_precision::uint64 u32_xrgb_cast(const detail::tvec3<T>& c)
+{
+ gtc::type_precision::uint64 result = 0;
+ result += static_cast<gtc::type_precision::uint64>(c.x * detail::tvec3<T>::value_type(65535)) << 16;
+ result += static_cast<gtc::type_precision::uint64>(c.y * detail::tvec3<T>::value_type(65535)) << 32;
+ result += static_cast<gtc::type_precision::uint64>(c.z * detail::tvec3<T>::value_type(65535)) << 48;
+ return result;
+}
+
+template <typename T>
+GLM_FUNC_QUALIFIER gtc::type_precision::uint64 u32_bgrx_cast(const detail::tvec3<T>& c)
+{
+ gtc::type_precision::uint64 result = 0;
+ result += static_cast<gtc::type_precision::uint64>(c.x * detail::tvec3<T>::value_type(65535)) << 32;
+ result += static_cast<gtc::type_precision::uint64>(c.y * detail::tvec3<T>::value_type(65535)) << 16;
+ result += static_cast<gtc::type_precision::uint64>(c.z * detail::tvec3<T>::value_type(65535)) << 0;
+ return result;
+}
+
+template <typename T>
+GLM_FUNC_QUALIFIER gtc::type_precision::uint64 u32_xbgr_cast(const detail::tvec3<T>& c)
+{
+ gtc::type_precision::uint64 result = 0;
+ result += static_cast<gtc::type_precision::uint64>(c.x * detail::tvec3<T>::value_type(65535)) << 48;
+ result += static_cast<gtc::type_precision::uint64>(c.y * detail::tvec3<T>::value_type(65535)) << 32;
+ result += static_cast<gtc::type_precision::uint64>(c.z * detail::tvec3<T>::value_type(65535)) << 16;
+ result += static_cast<gtc::type_precision::uint64>(c.w * detail::tvec3<T>::value_type(65535)) << 0;
+ return result;
+}
+
+template <typename T>
+GLM_FUNC_QUALIFIER gtc::type_precision::uint64 u64_rgba_cast(const detail::tvec4<T>& c)
+{
+ gtc::type_precision::uint64 result = 0;
+ result += static_cast<gtc::type_precision::uint64>(c.x * detail::tvec4<T>::value_type(65535)) << 0;
+ result += static_cast<gtc::type_precision::uint64>(c.y * detail::tvec4<T>::value_type(65535)) << 16;
+ result += static_cast<gtc::type_precision::uint64>(c.z * detail::tvec4<T>::value_type(65535)) << 32;
+ result += static_cast<gtc::type_precision::uint64>(c.w * detail::tvec4<T>::value_type(65535)) << 48;
+ return result;
+}
+
+template <typename T>
+GLM_FUNC_QUALIFIER gtc::type_precision::uint64 u64_argb_cast(const detail::tvec4<T>& c)
+{
+ gtc::type_precision::uint64 result = 0;
+ result += static_cast<gtc::type_precision::uint64>(c.x * detail::tvec4<T>::value_type(65535)) << 16;
+ result += static_cast<gtc::type_precision::uint64>(c.y * detail::tvec4<T>::value_type(65535)) << 32;
+ result += static_cast<gtc::type_precision::uint64>(c.z * detail::tvec4<T>::value_type(65535)) << 48;
+ result += static_cast<gtc::type_precision::uint64>(c.w * detail::tvec4<T>::value_type(65535)) << 0;
+ return result;
+}
+
+template <typename T>
+GLM_FUNC_QUALIFIER gtc::type_precision::uint64 u64_bgra_cast(const detail::tvec4<T>& c)
+{
+ gtc::type_precision::uint64 result = 0;
+ result += static_cast<gtc::type_precision::uint64>(c.x * detail::tvec4<T>::value_type(65535)) << 32;
+ result += static_cast<gtc::type_precision::uint64>(c.y * detail::tvec4<T>::value_type(65535)) << 16;
+ result += static_cast<gtc::type_precision::uint64>(c.z * detail::tvec4<T>::value_type(65535)) << 0;
+ result += static_cast<gtc::type_precision::uint64>(c.w * detail::tvec4<T>::value_type(65535)) << 48;
+ return result;
+}
+
+template <typename T>
+GLM_FUNC_QUALIFIER gtc::type_precision::uint64 u64_abgr_cast(const detail::tvec4<T>& c)
+{
+ gtc::type_precision::uint64 result = 0;
+ result += static_cast<gtc::type_precision::uint64>(c.x * detail::tvec4<T>::value_type(65535)) << 48;
+ result += static_cast<gtc::type_precision::uint64>(c.y * detail::tvec4<T>::value_type(65535)) << 32;
+ result += static_cast<gtc::type_precision::uint64>(c.z * detail::tvec4<T>::value_type(65535)) << 16;
+ result += static_cast<gtc::type_precision::uint64>(c.w * detail::tvec4<T>::value_type(65535)) << 0;
+ return result;
+}
+
+template <>
+GLM_FUNC_QUALIFIER f16vec1 f16_channel_cast<gtc::type_precision::uint32>(gtc::type_precision::uint32 color)
+{
+ return gtc::type_precision::f16(static_cast<float>(color >> 0) / static_cast<float>(255));
+}
+
+template <>
+GLM_FUNC_QUALIFIER gtc::type_precision::f16vec3 f16_rgbx_cast<gtc::type_precision::uint32>(gtc::type_precision::uint32 color)
+{
+ gtc::type_precision::f16vec3 result;
+ result.x = gtc::type_precision::f16(static_cast<float>(color >> 0) / static_cast<float>(255));
+ result.y = gtc::type_precision::f16(static_cast<float>(color >> 8) / static_cast<float>(255));
+ result.z = gtc::type_precision::f16(static_cast<float>(color >> 16) / static_cast<float>(255));
+ return result;
+}
+
+template <>
+GLM_FUNC_QUALIFIER gtc::type_precision::f16vec3 f16_xrgb_cast<gtc::type_precision::uint32>(gtc::type_precision::uint32 color)
+{
+ gtc::type_precision::f16vec3 result;
+ result.x = gtc::type_precision::f16(static_cast<float>(color >> 8) / static_cast<float>(255));
+ result.y = gtc::type_precision::f16(static_cast<float>(color >> 16) / static_cast<float>(255));
+ result.z = gtc::type_precision::f16(static_cast<float>(color >> 24) / static_cast<float>(255));
+ return result;
+}
+
+template <>
+GLM_FUNC_QUALIFIER f16vec3 f16_bgrx_cast<uint32>(uint32 color)
+{
+ f16vec3 result;
+ result.x = f16(static_cast<float>(color >> 16) / static_cast<float>(255));
+ result.y = f16(static_cast<float>(color >> 8) / static_cast<float>(255));
+ result.z = f16(static_cast<float>(color >> 0) / static_cast<float>(255));
+ return result;
+}
+
+template <>
+GLM_FUNC_QUALIFIER f16vec3 f16_xbgr_cast<uint32>(uint32 color)
+{
+ f16vec3 result;
+ result.x = f16(static_cast<float>(color >> 24) / static_cast<float>(255));
+ result.y = f16(static_cast<float>(color >> 16) / static_cast<float>(255));
+ result.z = f16(static_cast<float>(color >> 8) / static_cast<float>(255));
+ return result;
+}
+
+template <>
+GLM_FUNC_QUALIFIER f16vec4 f16_rgba_cast<uint32>(uint32 color)
+{
+ f16vec4 result;
+ result.x = f16(static_cast<float>(color >> 0) / static_cast<float>(255));
+ result.y = f16(static_cast<float>(color >> 8) / static_cast<float>(255));
+ result.z = f16(static_cast<float>(color >> 16) / static_cast<float>(255));
+ result.w = f16(static_cast<float>(color >> 24) / static_cast<float>(255));
+ return result;
+}
+
+template <>
+GLM_FUNC_QUALIFIER f16vec4 f16_argb_cast<uint32>(uint32 color)
+{
+ f16vec4 result;
+ result.x = f16(static_cast<float>(color >> 8) / static_cast<float>(255));
+ result.y = f16(static_cast<float>(color >> 16) / static_cast<float>(255));
+ result.z = f16(static_cast<float>(color >> 24) / static_cast<float>(255));
+ result.w = f16(static_cast<float>(color >> 0) / static_cast<float>(255));
+ return result;
+}
+
+template <>
+GLM_FUNC_QUALIFIER f16vec4 f16_bgra_cast<uint32>(uint32 color)
+{
+ f16vec4 result;
+ result.x = f16(static_cast<float>(color >> 16) / static_cast<float>(255));
+ result.y = f16(static_cast<float>(color >> 8) / static_cast<float>(255));
+ result.z = f16(static_cast<float>(color >> 0) / static_cast<float>(255));
+ result.w = f16(static_cast<float>(color >> 24) / static_cast<float>(255));
+ return result;
+}
+
+template <>
+GLM_FUNC_QUALIFIER f16vec4 f16_abgr_cast<uint32>(uint32 color)
+{
+ f16vec4 result;
+ result.x = f16(static_cast<float>(color >> 24) / static_cast<float>(255));
+ result.y = f16(static_cast<float>(color >> 16) / static_cast<float>(255));
+ result.z = f16(static_cast<float>(color >> 8) / static_cast<float>(255));
+ result.w = f16(static_cast<float>(color >> 0) / static_cast<float>(255));
+ return result;
+}
+
+template <>
+GLM_FUNC_QUALIFIER float f32_channel_cast<uint8>(uint8 color)
+{
+ return static_cast<float>(color >> 0) / static_cast<float>(255);
+}
+
+template <>
+GLM_FUNC_QUALIFIER detail::tvec3<float> f32_rgbx_cast<uint32>(uint32 color)
+{
+ detail::tvec3<float> result;
+ result.x = static_cast<float>(color >> 0) / static_cast<float>(255);
+ result.y = static_cast<float>(color >> 8) / static_cast<float>(255);
+ result.z = static_cast<float>(color >> 16) / static_cast<float>(255);
+ return result;
+}
+
+template <>
+GLM_FUNC_QUALIFIER detail::tvec3<float> f32_xrgb_cast<uint32>(uint32 color)
+{
+ detail::tvec3<float> result;
+ result.x = static_cast<float>(color >> 8) / static_cast<float>(255);
+ result.y = static_cast<float>(color >> 16) / static_cast<float>(255);
+ result.z = static_cast<float>(color >> 24) / static_cast<float>(255);
+ return result;
+}
+
+template <>
+GLM_FUNC_QUALIFIER detail::tvec3<float> f32_bgrx_cast<uint32>(uint32 color)
+{
+ detail::tvec3<float> result;
+ result.x = static_cast<float>(color >> 16) / static_cast<float>(255);
+ result.y = static_cast<float>(color >> 8) / static_cast<float>(255);
+ result.z = static_cast<float>(color >> 0) / static_cast<float>(255);
+ return result;
+}
+
+template <>
+GLM_FUNC_QUALIFIER detail::tvec3<float> f32_xbgr_cast<uint32>(uint32 color)
+{
+ detail::tvec3<float> result;
+ result.x = static_cast<float>(color >> 24) / static_cast<float>(255);
+ result.y = static_cast<float>(color >> 16) / static_cast<float>(255);
+ result.z = static_cast<float>(color >> 8) / static_cast<float>(255);
+ return result;
+}
+
+template <>
+GLM_FUNC_QUALIFIER detail::tvec4<float> f32_rgba_cast<uint32>(uint32 color)
+{
+ detail::tvec4<float> result;
+ result.x = static_cast<float>(color >> 0) / static_cast<float>(255);
+ result.y = static_cast<float>(color >> 8) / static_cast<float>(255);
+ result.z = static_cast<float>(color >> 16) / static_cast<float>(255);
+ result.w = static_cast<float>(color >> 24) / static_cast<float>(255);
+ return result;
+}
+
+template <>
+GLM_FUNC_QUALIFIER detail::tvec4<float> f32_argb_cast<uint32>(uint32 color)
+{
+ detail::tvec4<float> result;
+ result.x = static_cast<float>(color >> 8) / static_cast<float>(255);
+ result.y = static_cast<float>(color >> 16) / static_cast<float>(255);
+ result.z = static_cast<float>(color >> 24) / static_cast<float>(255);
+ result.w = static_cast<float>(color >> 0) / static_cast<float>(255);
+ return result;
+}
+
+template <>
+GLM_FUNC_QUALIFIER detail::tvec4<float> f32_bgra_cast<uint32>(uint32 color)
+{
+ detail::tvec4<float> result;
+ result.x = static_cast<float>(color >> 16) / static_cast<float>(255);
+ result.y = static_cast<float>(color >> 8) / static_cast<float>(255);
+ result.z = static_cast<float>(color >> 0) / static_cast<float>(255);
+ result.w = static_cast<float>(color >> 24) / static_cast<float>(255);
+ return result;
+}
+
+template <>
+GLM_FUNC_QUALIFIER detail::tvec4<float> f32_abgr_cast<uint32>(uint32 color)
+{
+ detail::tvec4<float> result;
+ result.x = static_cast<float>(color >> 24) / static_cast<float>(255);
+ result.y = static_cast<float>(color >> 16) / static_cast<float>(255);
+ result.z = static_cast<float>(color >> 8) / static_cast<float>(255);
+ result.w = static_cast<float>(color >> 0) / static_cast<float>(255);
+ return result;
+}
+
+template <>
+GLM_FUNC_QUALIFIER double f64_channel_cast<uint8>(uint8 color)
+{
+ return static_cast<double>(color >> 0) / static_cast<double>(255);
+}
+
+template <>
+GLM_FUNC_QUALIFIER detail::tvec3<double> f64_rgbx_cast<uint32>(uint32 color)
+{
+ detail::tvec3<double> result;
+ result.x = static_cast<double>(color >> 0) / static_cast<double>(255);
+ result.y = static_cast<double>(color >> 8) / static_cast<double>(255);
+ result.z = static_cast<double>(color >> 16) / static_cast<double>(255);
+ return result;
+}
+
+template <>
+GLM_FUNC_QUALIFIER detail::tvec3<double> f64_xrgb_cast<uint32>(uint32 color)
+{
+ detail::tvec3<double> result;
+ result.x = static_cast<double>(color >> 8) / static_cast<double>(255);
+ result.y = static_cast<double>(color >> 16) / static_cast<double>(255);
+ result.z = static_cast<double>(color >> 24) / static_cast<double>(255);
+ return result;
+}
+
+template <>
+GLM_FUNC_QUALIFIER detail::tvec3<double> f64_bgrx_cast<uint32>(uint32 color)
+{
+ detail::tvec3<double> result;
+ result.x = static_cast<double>(color >> 16) / static_cast<double>(255);
+ result.y = static_cast<double>(color >> 8) / static_cast<double>(255);
+ result.z = static_cast<double>(color >> 0) / static_cast<double>(255);
+ return result;
+}
+
+template <>
+GLM_FUNC_QUALIFIER detail::tvec3<double> f64_xbgr_cast<uint32>(uint32 color)
+{
+ detail::tvec3<double> result;
+ result.x = static_cast<double>(color >> 24) / static_cast<double>(255);
+ result.y = static_cast<double>(color >> 16) / static_cast<double>(255);
+ result.z = static_cast<double>(color >> 8) / static_cast<double>(255);
+ return result;
+}
+
+template <>
+GLM_FUNC_QUALIFIER detail::tvec4<double> f64_rgba_cast<uint32>(uint32 color)
+{
+ detail::tvec4<double> result;
+ result.x = static_cast<double>(color >> 0) / static_cast<double>(255);
+ result.y = static_cast<double>(color >> 8) / static_cast<double>(255);
+ result.z = static_cast<double>(color >> 16) / static_cast<double>(255);
+ result.w = static_cast<double>(color >> 24) / static_cast<double>(255);
+ return result;
+}
+
+template <>
+GLM_FUNC_QUALIFIER detail::tvec4<double> f64_argb_cast<uint32>(uint32 color)
+{
+ detail::tvec4<double> result;
+ result.x = static_cast<double>(color >> 8) / static_cast<double>(255);
+ result.y = static_cast<double>(color >> 16) / static_cast<double>(255);
+ result.z = static_cast<double>(color >> 24) / static_cast<double>(255);
+ result.w = static_cast<double>(color >> 0) / static_cast<double>(255);
+ return result;
+}
+
+template <>
+GLM_FUNC_QUALIFIER detail::tvec4<double> f64_bgra_cast<uint32>(uint32 color)
+{
+ detail::tvec4<double> result;
+ result.x = static_cast<double>(color >> 16) / static_cast<double>(255);
+ result.y = static_cast<double>(color >> 8) / static_cast<double>(255);
+ result.z = static_cast<double>(color >> 0) / static_cast<double>(255);
+ result.w = static_cast<double>(color >> 24) / static_cast<double>(255);
+ return result;
+}
+
+template <>
+GLM_FUNC_QUALIFIER detail::tvec4<double> f64_abgr_cast<uint32>(uint32 color)
+{
+ detail::tvec4<double> result;
+ result.x = static_cast<double>(color >> 24) / static_cast<double>(255);
+ result.y = static_cast<double>(color >> 16) / static_cast<double>(255);
+ result.z = static_cast<double>(color >> 8) / static_cast<double>(255);
+ result.w = static_cast<double>(color >> 0) / static_cast<double>(255);
+ return result;
+}
+
+template <>
+GLM_FUNC_QUALIFIER detail::thalf f16_channel_cast<uint16>(uint16 color)
+{
+ return detail::thalf(static_cast<float>(color >> 0) / static_cast<float>(65535));
+}
+
+template <>
+GLM_FUNC_QUALIFIER detail::tvec3<detail::thalf> f16_rgbx_cast<uint64>(uint64 color)
+{
+ detail::tvec3<detail::thalf> result;
+ result.x = detail::thalf(static_cast<float>(color >> 0) / static_cast<float>(65535));
+ result.y = detail::thalf(static_cast<float>(color >> 16) / static_cast<float>(65535));
+ result.z = detail::thalf(static_cast<float>(color >> 32) / static_cast<float>(65535));
+ return result;
+}
+
+template <>
+GLM_FUNC_QUALIFIER detail::tvec3<detail::thalf> f16_xrgb_cast<uint64>(uint64 color)
+{
+ detail::tvec3<detail::thalf> result;
+ result.x = detail::thalf(static_cast<float>(color >> 16) / static_cast<float>(65535));
+ result.y = detail::thalf(static_cast<float>(color >> 32) / static_cast<float>(65535));
+ result.z = detail::thalf(static_cast<float>(color >> 48) / static_cast<float>(65535));
+ return result;
+}
+
+template <>
+GLM_FUNC_QUALIFIER detail::tvec3<detail::thalf> f16_bgrx_cast<uint64>(uint64 color)
+{
+ detail::tvec3<detail::thalf> result;
+ result.x = detail::thalf(static_cast<float>(color >> 32) / static_cast<float>(65535));
+ result.y = detail::thalf(static_cast<float>(color >> 16) / static_cast<float>(65535));
+ result.z = detail::thalf(static_cast<float>(color >> 0) / static_cast<float>(65535));
+ return result;
+}
+
+template <>
+GLM_FUNC_QUALIFIER detail::tvec3<detail::thalf> f16_xbgr_cast<uint64>(uint64 color)
+{
+ detail::tvec3<detail::thalf> result;
+ result.x = detail::thalf(static_cast<float>(color >> 48) / static_cast<float>(65535));
+ result.y = detail::thalf(static_cast<float>(color >> 32) / static_cast<float>(65535));
+ result.z = detail::thalf(static_cast<float>(color >> 16) / static_cast<float>(65535));
+ return result;
+}
+
+template <>
+GLM_FUNC_QUALIFIER detail::tvec4<detail::thalf> f16_rgba_cast<uint64>(uint64 color)
+{
+ detail::tvec4<detail::thalf> result;
+ result.x = detail::thalf(static_cast<float>(color >> 0) / static_cast<float>(65535));
+ result.y = detail::thalf(static_cast<float>(color >> 16) / static_cast<float>(65535));
+ result.z = detail::thalf(static_cast<float>(color >> 32) / static_cast<float>(65535));
+ result.w = detail::thalf(static_cast<float>(color >> 48) / static_cast<float>(65535));
+ return result;
+}
+
+template <>
+GLM_FUNC_QUALIFIER detail::tvec4<detail::thalf> f16_argb_cast<uint64>(uint64 color)
+{
+ detail::tvec4<detail::thalf> result;
+ result.x = detail::thalf(static_cast<float>(color >> 16) / static_cast<float>(65535));
+ result.y = detail::thalf(static_cast<float>(color >> 32) / static_cast<float>(65535));
+ result.z = detail::thalf(static_cast<float>(color >> 48) / static_cast<float>(65535));
+ result.w = detail::thalf(static_cast<float>(color >> 0) / static_cast<float>(65535));
+ return result;
+}
+
+template <>
+GLM_FUNC_QUALIFIER detail::tvec4<detail::thalf> f16_bgra_cast<uint64>(uint64 color)
+{
+ detail::tvec4<detail::thalf> result;
+ result.x = detail::thalf(static_cast<float>(color >> 32) / static_cast<float>(65535));
+ result.y = detail::thalf(static_cast<float>(color >> 16) / static_cast<float>(65535));
+ result.z = detail::thalf(static_cast<float>(color >> 0) / static_cast<float>(65535));
+ result.w = detail::thalf(static_cast<float>(color >> 48) / static_cast<float>(65535));
+ return result;
+}
+
+template <>
+GLM_FUNC_QUALIFIER detail::tvec4<detail::thalf> f16_abgr_cast<uint64>(uint64 color)
+{
+ detail::tvec4<detail::thalf> result;
+ result.x = detail::thalf(static_cast<float>(color >> 48) / static_cast<float>(65535));
+ result.y = detail::thalf(static_cast<float>(color >> 32) / static_cast<float>(65535));
+ result.z = detail::thalf(static_cast<float>(color >> 16) / static_cast<float>(65535));
+ result.w = detail::thalf(static_cast<float>(color >> 0) / static_cast<float>(65535));
+ return result;
+}
+
+template <>
+GLM_FUNC_QUALIFIER float f32_channel_cast<uint16>(uint16 color)
+{
+ return static_cast<float>(color >> 0) / static_cast<float>(65535);
+}
+
+template <>
+GLM_FUNC_QUALIFIER detail::tvec3<float> f32_rgbx_cast<uint64>(uint64 color)
+{
+ detail::tvec3<float> result;
+ result.x = static_cast<float>(color >> 0) / static_cast<float>(65535);
+ result.y = static_cast<float>(color >> 16) / static_cast<float>(65535);
+ result.z = static_cast<float>(color >> 32) / static_cast<float>(65535);
+ return result;
+}
+
+template <>
+GLM_FUNC_QUALIFIER detail::tvec3<float> f32_xrgb_cast<uint64>(uint64 color)
+{
+ detail::tvec3<float> result;
+ result.x = static_cast<float>(color >> 16) / static_cast<float>(65535);
+ result.y = static_cast<float>(color >> 32) / static_cast<float>(65535);
+ result.z = static_cast<float>(color >> 48) / static_cast<float>(65535);
+ return result;
+}
+
+template <>
+GLM_FUNC_QUALIFIER detail::tvec3<float> f32_bgrx_cast<uint64>(uint64 color)
+{
+ detail::tvec3<float> result;
+ result.x = static_cast<float>(color >> 32) / static_cast<float>(65535);
+ result.y = static_cast<float>(color >> 16) / static_cast<float>(65535);
+ result.z = static_cast<float>(color >> 0) / static_cast<float>(65535);
+ return result;
+}
+
+template <>
+GLM_FUNC_QUALIFIER detail::tvec3<float> f32_xbgr_cast<uint64>(uint64 color)
+{
+ detail::tvec3<float> result;
+ result.x = static_cast<float>(color >> 48) / static_cast<float>(65535);
+ result.y = static_cast<float>(color >> 32) / static_cast<float>(65535);
+ result.z = static_cast<float>(color >> 16) / static_cast<float>(65535);
+ return result;
+}
+
+template <>
+GLM_FUNC_QUALIFIER detail::tvec4<float> f32_rgba_cast<uint64>(uint64 color)
+{
+ detail::tvec4<float> result;
+ result.x = static_cast<float>(color >> 0) / static_cast<float>(65535);
+ result.y = static_cast<float>(color >> 16) / static_cast<float>(65535);
+ result.z = static_cast<float>(color >> 32) / static_cast<float>(65535);
+ result.w = static_cast<float>(color >> 48) / static_cast<float>(65535);
+ return result;
+}
+
+template <>
+GLM_FUNC_QUALIFIER detail::tvec4<float> f32_argb_cast<uint64>(uint64 color)
+{
+ detail::tvec4<float> result;
+ result.x = static_cast<float>(color >> 16) / static_cast<float>(65535);
+ result.y = static_cast<float>(color >> 32) / static_cast<float>(65535);
+ result.z = static_cast<float>(color >> 48) / static_cast<float>(65535);
+ result.w = static_cast<float>(color >> 0) / static_cast<float>(65535);
+ return result;
+}
+
+template <>
+GLM_FUNC_QUALIFIER detail::tvec4<float> f32_bgra_cast<uint64>(uint64 color)
+{
+ detail::tvec4<float> result;
+ result.x = static_cast<float>(color >> 32) / static_cast<float>(65535);
+ result.y = static_cast<float>(color >> 16) / static_cast<float>(65535);
+ result.z = static_cast<float>(color >> 0) / static_cast<float>(65535);
+ result.w = static_cast<float>(color >> 48) / static_cast<float>(65535);
+ return result;
+}
+
+template <>
+GLM_FUNC_QUALIFIER detail::tvec4<float> f32_abgr_cast<uint64>(uint64 color)
+{
+ detail::tvec4<float> result;
+ result.x = static_cast<float>(color >> 48) / static_cast<float>(65535);
+ result.y = static_cast<float>(color >> 32) / static_cast<float>(65535);
+ result.z = static_cast<float>(color >> 16) / static_cast<float>(65535);
+ result.w = static_cast<float>(color >> 0) / static_cast<float>(65535);
+ return result;
+}
+
+template <>
+GLM_FUNC_QUALIFIER double f64_channel_cast<uint16>(uint16 color)
+{
+ return static_cast<double>(color >> 0) / static_cast<double>(65535);
+}
+
+template <>
+GLM_FUNC_QUALIFIER detail::tvec3<double> f64_rgbx_cast<uint64>(uint64 color)
+{
+ detail::tvec3<double> result;
+ result.x = static_cast<double>(color >> 0) / static_cast<double>(65535);
+ result.y = static_cast<double>(color >> 16) / static_cast<double>(65535);
+ result.z = static_cast<double>(color >> 32) / static_cast<double>(65535);
+ return result;
+}
+
+template <>
+GLM_FUNC_QUALIFIER detail::tvec3<double> f64_xrgb_cast<uint64>(uint64 color)
+{
+ detail::tvec3<double> result;
+ result.x = static_cast<double>(color >> 16) / static_cast<double>(65535);
+ result.y = static_cast<double>(color >> 32) / static_cast<double>(65535);
+ result.z = static_cast<double>(color >> 48) / static_cast<double>(65535);
+ return result;
+}
+
+template <>
+GLM_FUNC_QUALIFIER detail::tvec3<double> f64_bgrx_cast<uint64>(uint64 color)
+{
+ detail::tvec3<double> result;
+ result.x = static_cast<double>(color >> 32) / static_cast<double>(65535);
+ result.y = static_cast<double>(color >> 16) / static_cast<double>(65535);
+ result.z = static_cast<double>(color >> 0) / static_cast<double>(65535);
+ return result;
+}
+
+template <>
+GLM_FUNC_QUALIFIER detail::tvec3<double> f64_xbgr_cast<uint64>(uint64 color)
+{
+ detail::tvec3<double> result;
+ result.x = static_cast<double>(color >> 48) / static_cast<double>(65535);
+ result.y = static_cast<double>(color >> 32) / static_cast<double>(65535);
+ result.z = static_cast<double>(color >> 16) / static_cast<double>(65535);
+ return result;
+}
+
+template <>
+GLM_FUNC_QUALIFIER detail::tvec4<double> f64_rgba_cast<uint64>(uint64 color)
+{
+ detail::tvec4<double> result;
+ result.x = static_cast<double>(color >> 0) / static_cast<double>(65535);
+ result.y = static_cast<double>(color >> 16) / static_cast<double>(65535);
+ result.z = static_cast<double>(color >> 32) / static_cast<double>(65535);
+ result.w = static_cast<double>(color >> 48) / static_cast<double>(65535);
+ return result;
+}
+
+template <>
+GLM_FUNC_QUALIFIER detail::tvec4<double> f64_argb_cast<uint64>(uint64 color)
+{
+ detail::tvec4<double> result;
+ result.x = static_cast<double>(color >> 16) / static_cast<double>(65535);
+ result.y = static_cast<double>(color >> 32) / static_cast<double>(65535);
+ result.z = static_cast<double>(color >> 48) / static_cast<double>(65535);
+ result.w = static_cast<double>(color >> 0) / static_cast<double>(65535);
+ return result;
+}
+
+template <>
+GLM_FUNC_QUALIFIER detail::tvec4<double> f64_bgra_cast<uint64>(uint64 color)
+{
+ detail::tvec4<double> result;
+ result.x = static_cast<double>(color >> 32) / static_cast<double>(65535);
+ result.y = static_cast<double>(color >> 16) / static_cast<double>(65535);
+ result.z = static_cast<double>(color >> 0) / static_cast<double>(65535);
+ result.w = static_cast<double>(color >> 48) / static_cast<double>(65535);
+ return result;
+}
+
+template <>
+GLM_FUNC_QUALIFIER detail::tvec4<double> f64_abgr_cast<uint64>(uint64 color)
+{
+ detail::tvec4<double> result;
+ result.x = static_cast<double>(color >> 48) / static_cast<double>(65535);
+ result.y = static_cast<double>(color >> 32) / static_cast<double>(65535);
+ result.z = static_cast<double>(color >> 16) / static_cast<double>(65535);
+ result.w = static_cast<double>(color >> 0) / static_cast<double>(65535);
+ return result;
+}
+
+}//namespace color_space
+}//namespace gtx
+}//namespace glm
diff --git a/src/glm/gtx/color_space.hpp b/src/glm/gtx/color_space.hpp
new file mode 100644
index 0000000..03052f5
--- /dev/null
+++ b/src/glm/gtx/color_space.hpp
@@ -0,0 +1,77 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2005-12-21
+// Updated : 2007-02-22
+// Licence : This source is under MIT License
+// File : glm/gtx/color_space.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_gtx_color_space
+#define glm_gtx_color_space
+
+// Dependency:
+#include "../glm.hpp"
+
+#if(defined(GLM_MESSAGES) && !defined(glm_ext))
+# pragma message("GLM: GLM_GTX_color_space extension included")
+#endif
+
+namespace glm{
+namespace gtx{
+namespace color_space ///< GLM_GTX_color_space extension: Related to RGB to HSV conversions and operations
+{
+ /// \addtogroup gtx_color_space
+ /// @{
+
+ //! Converts a color from HSV color space to its color in RGB color space.
+ //! From GLM_GTX_color_space extension.
+ template <typename valType>
+ detail::tvec3<valType> rgbColor(
+ detail::tvec3<valType> const & hsvValue);
+
+ //! Converts a color from RGB color space to its color in HSV color space.
+ //! From GLM_GTX_color_space extension.
+ template <typename valType>
+ detail::tvec3<valType> hsvColor(
+ detail::tvec3<valType> const & rgbValue);
+
+ //! Build a saturation matrix.
+ //! From GLM_GTX_color_space extension
+ template <typename valType>
+ detail::tmat4x4<valType> saturation(
+ valType const s);
+
+ //! Modify the saturation of a color.
+ //! From GLM_GTX_color_space extension.
+ template <typename valType>
+ detail::tvec3<valType> saturation(
+ valType const s,
+ detail::tvec3<valType> const & color);
+
+ //! Modify the saturation of a color.
+ //! From GLM_GTX_color_space extension.
+ template <typename valType>
+ detail::tvec4<valType> saturation(
+ valType const s,
+ detail::tvec4<valType> const & color);
+
+ //! Compute color luminosity associating ratios (0.33, 0.59, 0.11) to RGB canals.
+ //! From GLM_GTX_color_space extension.
+ template <typename valType>
+ valType luminosity(
+ detail::tvec3<valType> const & color);
+
+ /// @}
+}//namespace color_space
+}//namespace gtx
+}//namespace glm
+
+#include "color_space.inl"
+
+namespace glm{using namespace gtx::color_space;}
+
+#endif//glm_gtx_color_space
diff --git a/src/glm/gtx/color_space.inl b/src/glm/gtx/color_space.inl
new file mode 100644
index 0000000..d885cd8
--- /dev/null
+++ b/src/glm/gtx/color_space.inl
@@ -0,0 +1,154 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2005-12-21
+// Updated : 2007-02-22
+// Licence : This source is under MIT License
+// File : glm/gtx/color_space.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm{
+namespace gtx{
+namespace color_space
+{
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> rgbColor(const detail::tvec3<T>& hsvColor)
+ {
+ detail::tvec3<T> hsv = hsvColor;
+ detail::tvec3<T> rgbColor;
+
+ if(hsv.y == T(0))
+ // achromatic (grey)
+ rgbColor = detail::tvec3<T>(hsv.z);
+ else
+ {
+ T sector = floor(hsv.x / T(60));
+ T frac = (hsv.x / T(60)) - sector;
+ // factorial part of h
+ T o = hsv.z * (T(1) - hsv.y);
+ T p = hsv.z * (T(1) - hsv.y * frac);
+ T q = hsv.z * (T(1) - hsv.y * (T(1) - frac));
+
+ switch(int(sector))
+ {
+ default:
+ case 0:
+ rgbColor.r = hsv.z;
+ rgbColor.g = q;
+ rgbColor.b = o;
+ break;
+ case 1:
+ rgbColor.r = p;
+ rgbColor.g = hsv.z;
+ rgbColor.b = o;
+ break;
+ case 2:
+ rgbColor.r = o;
+ rgbColor.g = hsv.z;
+ rgbColor.b = q;
+ break;
+ case 3:
+ rgbColor.r = o;
+ rgbColor.g = p;
+ rgbColor.b = hsv.z;
+ break;
+ case 4:
+ rgbColor.r = q;
+ rgbColor.g = o;
+ rgbColor.b = hsv.z;
+ break;
+ case 5:
+ rgbColor.r = hsv.z;
+ rgbColor.g = o;
+ rgbColor.b = p;
+ break;
+ }
+ }
+
+ return rgbColor;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> hsvColor(const detail::tvec3<T>& rgbColor)
+ {
+ detail::tvec3<T> hsv = rgbColor;
+ float Min = min(min(rgbColor.r, rgbColor.g), rgbColor.b);
+ float Max = max(max(rgbColor.r, rgbColor.g), rgbColor.b);
+ float Delta = Max - Min;
+
+ hsv.z = Max;
+
+ if(Max != T(0))
+ {
+ hsv.y = Delta / hsv.z;
+ T h = T(0);
+
+ if(rgbColor.r == Max)
+ // between yellow & magenta
+ h = T(0) + T(60) * (rgbColor.g - rgbColor.b) / Delta;
+ else if(rgbColor.g == Max)
+ // between cyan & yellow
+ h = T(120) + T(60) * (rgbColor.b - rgbColor.r) / Delta;
+ else
+ // between magenta & cyan
+ h = T(240) + T(60) * (rgbColor.r - rgbColor.g) / Delta;
+
+ if(h < T(0))
+ hsv.x = h + T(360);
+ else
+ hsv.x = h;
+ }
+ else
+ {
+ // If r = g = b = 0 then s = 0, h is undefined
+ hsv.y = T(0);
+ hsv.x = T(0);
+ }
+
+ return hsv;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tmat4x4<T> saturation(const T s)
+ {
+ detail::tvec3<T> rgbw = detail::tvec3<T>(T(0.2126), T(0.7152), T(0.0722));
+
+ T col0 = (T(1) - s) * rgbw.r;
+ T col1 = (T(1) - s) * rgbw.g;
+ T col2 = (T(1) - s) * rgbw.b;
+
+ detail::tmat4x4<T> result(T(1));
+ result[0][0] = col0 + s;
+ result[0][1] = col0;
+ result[0][2] = col0;
+ result[1][0] = col1;
+ result[1][1] = col1 + s;
+ result[1][2] = col1;
+ result[2][0] = col2;
+ result[2][1] = col2;
+ result[2][2] = col2 + s;
+ return result;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> saturation(const T s, const detail::tvec3<T>& color)
+ {
+ return detail::tvec3<T>(saturation(s) * detail::tvec4<T>(color, T(0)));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<T> saturation(const T s, const detail::tvec4<T>& color)
+ {
+ return saturation(s) * color;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER T luminosity(const detail::tvec3<T>& color)
+ {
+ const detail::tvec3<T> tmp = detail::tvec3<T>(0.33, 0.59, 0.11);
+ return dot(color, tmp);
+ }
+
+}//namespace color_space
+}//namespace gtx
+}//namespace glm
diff --git a/src/glm/gtx/color_space_YCoCg.hpp b/src/glm/gtx/color_space_YCoCg.hpp
new file mode 100644
index 0000000..d97d19c
--- /dev/null
+++ b/src/glm/gtx/color_space_YCoCg.hpp
@@ -0,0 +1,65 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2008-10-28
+// Updated : 2008-10-28
+// Licence : This source is under MIT License
+// File : glm/gtx/color_space_YCoCg.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_gtx_color_space_YCoCg
+#define glm_gtx_color_space_YCoCg
+
+// Dependency:
+#include "../glm.hpp"
+
+#if(defined(GLM_MESSAGES) && !defined(glm_ext))
+# pragma message("GLM: GLM_GTX_color_space_YCoCg extension included")
+#endif
+
+namespace glm{
+namespace gtx{
+namespace color_space_YCoCg ///< GLM_GTX_color_space_YCoCg extension: RGB to YCoCg conversions and operations
+{
+ /// \addtogroup gtx_color_space_YCoCg
+ ///@{
+
+ //! Convert a color from RGB color space to YCoCg color space.
+ //! From GLM_GTX_color_space_YCoCg extension.
+ template <typename valType>
+ detail::tvec3<valType> rgb2YCoCg(
+ detail::tvec3<valType> const & rgbColor);
+
+ //! Convert a color from YCoCg color space to RGB color space.
+ //! From GLM_GTX_color_space_YCoCg extension.
+ template <typename valType>
+ detail::tvec3<valType> YCoCg2rgb(
+ detail::tvec3<valType> const & YCoCgColor);
+
+ //! Convert a color from RGB color space to YCoCgR color space.
+ //! \see "YCoCg-R: A Color Space with RGB Reversibility and Low Dynamic Range"
+ //! From GLM_GTX_color_space_YCoCg extension.
+ template <typename valType>
+ detail::tvec3<valType> rgb2YCoCgR(
+ detail::tvec3<valType> const & rgbColor);
+
+ //! Convert a color from YCoCgR color space to RGB color space.
+ //! \see "YCoCg-R: A Color Space with RGB Reversibility and Low Dynamic Range"
+ //! From GLM_GTX_color_space_YCoCg extension.
+ template <typename valType>
+ detail::tvec3<valType> YCoCgR2rgb(
+ detail::tvec3<valType> const & YCoCgColor);
+
+ /// @}
+}//namespace color_space_YCoCg
+}//namespace gtx
+}//namespace glm
+
+#include "color_space_YCoCg.inl"
+
+namespace glm{using namespace gtx::color_space_YCoCg;}
+
+#endif//glm_gtx_color_space_YCoCg
diff --git a/src/glm/gtx/color_space_YCoCg.inl b/src/glm/gtx/color_space_YCoCg.inl
new file mode 100644
index 0000000..54a048c
--- /dev/null
+++ b/src/glm/gtx/color_space_YCoCg.inl
@@ -0,0 +1,69 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2008-10-28
+// Updated : 2008-10-28
+// Licence : This source is under MIT License
+// File : glm/gtx/color_space_YCoCg.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm{
+namespace gtx{
+namespace color_space_YCoCg{
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec3<valType> rgb2YCoCg
+(
+ detail::tvec3<valType> const & rgbColor
+)
+{
+ detail::tvec3<valType> result;
+ result.x/*Y */ = rgbColor.r / valType(4) + rgbColor.g / valType(2) + rgbColor.b / valType(4);
+ result.y/*Co*/ = rgbColor.r / valType(2) + rgbColor.g * valType(0) - rgbColor.b / valType(2);
+ result.z/*Cg*/ = - rgbColor.r / valType(4) + rgbColor.g / valType(2) - rgbColor.b / valType(4);
+ return result;
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec3<valType> rgb2YCoCgR
+(
+ detail::tvec3<valType> const & rgbColor
+)
+{
+ detail::tvec3<valType> result;
+ result.x/*Y */ = rgbColor.g / valType(2) + (rgbColor.r + rgbColor.b) / valType(4);
+ result.y/*Co*/ = rgbColor.r - rgbColor.b;
+ result.z/*Cg*/ = rgbColor.g - (rgbColor.r + rgbColor.b) / valType(2);
+ return result;
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec3<valType> YCoCg2rgb
+(
+ detail::tvec3<valType> const & YCoCgColor
+)
+{
+ detail::tvec3<valType> result;
+ result.r = YCoCgColor.x + YCoCgColor.y - YCoCgColor.z;
+ result.g = YCoCgColor.x + YCoCgColor.z;
+ result.b = YCoCgColor.x - YCoCgColor.y - YCoCgColor.z;
+ return result;
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec3<valType> YCoCgR2rgb
+(
+ detail::tvec3<valType> const & YCoCgRColor
+)
+{
+ detail::tvec3<valType> result;
+ valType tmp = YCoCgRColor.x - (YCoCgRColor.z / valType(2));
+ result.g = YCoCgRColor.z + tmp;
+ result.b = tmp - (YCoCgRColor.y / valType(2));
+ result.r = result.b + YCoCgRColor.y;
+ return result;
+}
+
+}//namespace color_space_YCoCg
+}//namespace gtx
+}//namespace glm
diff --git a/src/glm/gtx/compatibility.hpp b/src/glm/gtx/compatibility.hpp
new file mode 100644
index 0000000..a62a9e1
--- /dev/null
+++ b/src/glm/gtx/compatibility.hpp
@@ -0,0 +1,170 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2007-01-24
+// Updated : 2008-10-24
+// Licence : This source is under MIT License
+// File : glm/gtx/compatibility.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+// - GLM_GTC_half_float
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_gtx_compatibility
+#define glm_gtx_compatibility
+
+// Dependency:
+#include "../glm.hpp"
+#include "../gtc/half_float.hpp"
+
+#if(defined(GLM_MESSAGES) && !defined(glm_ext))
+# pragma message("GLM: GLM_GTX_compatibility extension included")
+#endif
+
+#if(GLM_COMPILER & GLM_COMPILER_VC)
+#include <cfloat>
+#elif(GLM_COMPILER & GLM_COMPILER_GCC)
+#include <cmath>
+#endif//GLM_COMPILER
+
+namespace glm{
+namespace gtx{
+namespace compatibility ///< GLM_GTX_compatibility extension: Provide functions to increase the compatibility with Cg and HLSL languages
+{
+ /// \addtogroup gtx_compatibility
+ ///@{
+
+ template <typename T> GLM_FUNC_QUALIFIER T lerp(T x, T y, T a){return mix(x, y, a);} //!< \brief Returns x * (1.0 - a) + y * a, i.e., the linear blend of x and y using the floating-point value a. The value for a is not restricted to the range [0, 1]. (From GLM_GTX_compatibility)
+ template <typename T> GLM_FUNC_QUALIFIER detail::tvec2<T> lerp(const detail::tvec2<T>& x, const detail::tvec2<T>& y, T a){return mix(x, y, a);} //!< \brief Returns x * (1.0 - a) + y * a, i.e., the linear blend of x and y using the floating-point value a. The value for a is not restricted to the range [0, 1]. (From GLM_GTX_compatibility)
+ template <typename T> GLM_FUNC_QUALIFIER detail::tvec3<T> lerp(const detail::tvec3<T>& x, const detail::tvec3<T>& y, T a){return mix(x, y, a);} //!< \brief Returns x * (1.0 - a) + y * a, i.e., the linear blend of x and y using the floating-point value a. The value for a is not restricted to the range [0, 1]. (From GLM_GTX_compatibility)
+ template <typename T> GLM_FUNC_QUALIFIER detail::tvec4<T> lerp(const detail::tvec4<T>& x, const detail::tvec4<T>& y, T a){return mix(x, y, a);} //!< \brief Returns x * (1.0 - a) + y * a, i.e., the linear blend of x and y using the floating-point value a. The value for a is not restricted to the range [0, 1]. (From GLM_GTX_compatibility)
+ template <typename T> GLM_FUNC_QUALIFIER detail::tvec2<T> lerp(const detail::tvec2<T>& x, const detail::tvec2<T>& y, const detail::tvec2<T>& a){return mix(x, y, a);} //!< \brief Returns the component-wise result of x * (1.0 - a) + y * a, i.e., the linear blend of x and y using vector a. The value for a is not restricted to the range [0, 1]. (From GLM_GTX_compatibility)
+ template <typename T> GLM_FUNC_QUALIFIER detail::tvec3<T> lerp(const detail::tvec3<T>& x, const detail::tvec3<T>& y, const detail::tvec3<T>& a){return mix(x, y, a);} //!< \brief Returns the component-wise result of x * (1.0 - a) + y * a, i.e., the linear blend of x and y using vector a. The value for a is not restricted to the range [0, 1]. (From GLM_GTX_compatibility)
+ template <typename T> GLM_FUNC_QUALIFIER detail::tvec4<T> lerp(const detail::tvec4<T>& x, const detail::tvec4<T>& y, const detail::tvec4<T>& a){return mix(x, y, a);} //!< \brief Returns the component-wise result of x * (1.0 - a) + y * a, i.e., the linear blend of x and y using vector a. The value for a is not restricted to the range [0, 1]. (From GLM_GTX_compatibility)
+
+ template <typename T> GLM_FUNC_QUALIFIER T saturate(T x){return clamp(x, T(0), T(1));} //!< \brief Returns clamp(x, 0, 1) for each component in x. (From GLM_GTX_compatibility)
+ template <typename T> GLM_FUNC_QUALIFIER detail::tvec2<T> saturate(const detail::tvec2<T>& x){return clamp(x, T(0), T(1));} //!< \brief Returns clamp(x, 0, 1) for each component in x. (From GLM_GTX_compatibility)
+ template <typename T> GLM_FUNC_QUALIFIER detail::tvec3<T> saturate(const detail::tvec3<T>& x){return clamp(x, T(0), T(1));} //!< \brief Returns clamp(x, 0, 1) for each component in x. (From GLM_GTX_compatibility)
+ template <typename T> GLM_FUNC_QUALIFIER detail::tvec4<T> saturate(const detail::tvec4<T>& x){return clamp(x, T(0), T(1));} //!< \brief Returns clamp(x, 0, 1) for each component in x. (From GLM_GTX_compatibility)
+
+ template <typename T> GLM_FUNC_QUALIFIER T atan2(T x, T y){return atan(x, y);} //!< \brief Arc tangent. Returns an angle whose tangent is y/x. The signs of x and y are used to determine what quadrant the angle is in. The range of values returned by this function is [-PI, PI]. Results are undefined if x and y are both 0. (From GLM_GTX_compatibility)
+ template <typename T> GLM_FUNC_QUALIFIER detail::tvec2<T> atan2(const detail::tvec2<T>& x, const detail::tvec2<T>& y){return atan(x, y);} //!< \brief Arc tangent. Returns an angle whose tangent is y/x. The signs of x and y are used to determine what quadrant the angle is in. The range of values returned by this function is [-PI, PI]. Results are undefined if x and y are both 0. (From GLM_GTX_compatibility)
+ template <typename T> GLM_FUNC_QUALIFIER detail::tvec3<T> atan2(const detail::tvec3<T>& x, const detail::tvec3<T>& y){return atan(x, y);} //!< \brief Arc tangent. Returns an angle whose tangent is y/x. The signs of x and y are used to determine what quadrant the angle is in. The range of values returned by this function is [-PI, PI]. Results are undefined if x and y are both 0. (From GLM_GTX_compatibility)
+ template <typename T> GLM_FUNC_QUALIFIER detail::tvec4<T> atan2(const detail::tvec4<T>& x, const detail::tvec4<T>& y){return atan(x, y);} //!< \brief Arc tangent. Returns an angle whose tangent is y/x. The signs of x and y are used to determine what quadrant the angle is in. The range of values returned by this function is [-PI, PI]. Results are undefined if x and y are both 0. (From GLM_GTX_compatibility)
+
+ template <typename genType> bool isfinite(genType const & x); //!< \brief Test whether or not a scalar or each vector component is a finite value. (From GLM_GTX_compatibility)
+ template <typename valType> detail::tvec2<bool> isfinite(const detail::tvec2<valType>& x); //!< \brief Test whether or not a scalar or each vector component is a finite value. (From GLM_GTX_compatibility)
+ template <typename valType> detail::tvec3<bool> isfinite(const detail::tvec3<valType>& x); //!< \brief Test whether or not a scalar or each vector component is a finite value. (From GLM_GTX_compatibility)
+ template <typename valType> detail::tvec4<bool> isfinite(const detail::tvec4<valType>& x); //!< \brief Test whether or not a scalar or each vector component is a finite value. (From GLM_GTX_compatibility)
+
+ template <typename genType> bool isinf(genType const & x); //!< \brief Determines whether the given floating-point value is infinite. (From GLM_GTX_compatibility extension)
+ template <typename genType> detail::tvec2<bool> isinf(const detail::tvec2<genType>& x); //!< \brief Determines whether the given floating-point value is infinite. (From GLM_GTX_compatibility extension)
+ template <typename genType> detail::tvec3<bool> isinf(const detail::tvec3<genType>& x); //!< \brief Determines whether the given floating-point value is infinite. (From GLM_GTX_compatibility extension)
+ template <typename genType> detail::tvec4<bool> isinf(const detail::tvec4<genType>& x); //!< \brief Determines whether the given floating-point value is infinite. (From GLM_GTX_compatibility extension)
+
+ template <typename genType> bool isnan(genType const & x); //!< \brief Checks given floating-point value for not a number (NAN) (From GLM_GTX_compatibility extension)
+ template <typename genType> detail::tvec2<bool> isnan(const detail::tvec2<genType>& x); //!< \brief Checks given floating-point value for not a number (NAN) (From GLM_GTX_compatibility extension)
+ template <typename genType> detail::tvec3<bool> isnan(const detail::tvec3<genType>& x); //!< \brief Checks given floating-point value for not a number (NAN) (From GLM_GTX_compatibility extension)
+ template <typename genType> detail::tvec4<bool> isnan(const detail::tvec4<genType>& x); //!< \brief Checks given floating-point value for not a number (NAN) (From GLM_GTX_compatibility extension)
+
+ typedef bool bool1; //!< \brief boolean type with 1 component. (From GLM_GTX_compatibility extension)
+ typedef detail::tvec2<bool> bool2; //!< \brief boolean type with 2 components. (From GLM_GTX_compatibility extension)
+ typedef detail::tvec3<bool> bool3; //!< \brief boolean type with 3 components. (From GLM_GTX_compatibility extension)
+ typedef detail::tvec4<bool> bool4; //!< \brief boolean type with 4 components. (From GLM_GTX_compatibility extension)
+
+ typedef bool bool1x1; //!< \brief boolean matrix with 1 x 1 component. (From GLM_GTX_compatibility extension)
+ typedef detail::tmat2x2<bool> bool2x2; //!< \brief boolean matrix with 2 x 2 components. (From GLM_GTX_compatibility extension)
+ typedef detail::tmat2x3<bool> bool2x3; //!< \brief boolean matrix with 2 x 3 components. (From GLM_GTX_compatibility extension)
+ typedef detail::tmat2x4<bool> bool2x4; //!< \brief boolean matrix with 2 x 4 components. (From GLM_GTX_compatibility extension)
+ typedef detail::tmat3x2<bool> bool3x2; //!< \brief boolean matrix with 3 x 2 components. (From GLM_GTX_compatibility extension)
+ typedef detail::tmat3x3<bool> bool3x3; //!< \brief boolean matrix with 3 x 3 components. (From GLM_GTX_compatibility extension)
+ typedef detail::tmat3x4<bool> bool3x4; //!< \brief boolean matrix with 3 x 4 components. (From GLM_GTX_compatibility extension)
+ typedef detail::tmat4x2<bool> bool4x2; //!< \brief boolean matrix with 4 x 2 components. (From GLM_GTX_compatibility extension)
+ typedef detail::tmat4x3<bool> bool4x3; //!< \brief boolean matrix with 4 x 3 components. (From GLM_GTX_compatibility extension)
+ typedef detail::tmat4x4<bool> bool4x4; //!< \brief boolean matrix with 4 x 4 components. (From GLM_GTX_compatibility extension)
+
+ typedef int int1; //!< \brief integer vector with 1 component. (From GLM_GTX_compatibility extension)
+ typedef detail::tvec2<int> int2; //!< \brief integer vector with 2 components. (From GLM_GTX_compatibility extension)
+ typedef detail::tvec3<int> int3; //!< \brief integer vector with 3 components. (From GLM_GTX_compatibility extension)
+ typedef detail::tvec4<int> int4; //!< \brief integer vector with 4 components. (From GLM_GTX_compatibility extension)
+
+ typedef int int1x1; //!< \brief integer matrix with 1 component. (From GLM_GTX_compatibility extension)
+ typedef detail::tmat2x2<int> int2x2; //!< \brief integer matrix with 2 x 2 components. (From GLM_GTX_compatibility extension)
+ typedef detail::tmat2x3<int> int2x3; //!< \brief integer matrix with 2 x 3 components. (From GLM_GTX_compatibility extension)
+ typedef detail::tmat2x4<int> int2x4; //!< \brief integer matrix with 2 x 4 components. (From GLM_GTX_compatibility extension)
+ typedef detail::tmat3x2<int> int3x2; //!< \brief integer matrix with 3 x 2 components. (From GLM_GTX_compatibility extension)
+ typedef detail::tmat3x3<int> int3x3; //!< \brief integer matrix with 3 x 3 components. (From GLM_GTX_compatibility extension)
+ typedef detail::tmat3x4<int> int3x4; //!< \brief integer matrix with 3 x 4 components. (From GLM_GTX_compatibility extension)
+ typedef detail::tmat4x2<int> int4x2; //!< \brief integer matrix with 4 x 2 components. (From GLM_GTX_compatibility extension)
+ typedef detail::tmat4x3<int> int4x3; //!< \brief integer matrix with 4 x 3 components. (From GLM_GTX_compatibility extension)
+ typedef detail::tmat4x4<int> int4x4; //!< \brief integer matrix with 4 x 4 components. (From GLM_GTX_compatibility extension)
+
+ typedef gtc::half_float::half half1; //!< \brief half-precision floating-point vector with 1 component. (From GLM_GTX_compatibility extension)
+ typedef detail::tvec2<gtc::half_float::half> half2; //!< \brief half-precision floating-point vector with 2 components. (From GLM_GTX_compatibility extension)
+ typedef detail::tvec3<gtc::half_float::half> half3; //!< \brief half-precision floating-point vector with 2 components. (From GLM_GTX_compatibility extension)
+ typedef detail::tvec4<gtc::half_float::half> half4; //!< \brief half-precision floating-point vector with 2 components. (From GLM_GTX_compatibility extension)
+
+ typedef gtc::half_float::half half1x1; //!< \brief half-precision floating-point matrix with 1 component. (From GLM_GTX_compatibility extension)
+ typedef detail::tmat2x2<gtc::half_float::half> half2x2; //!< \brief half-precision floating-point matrix with 2 x 2 components. (From GLM_GTX_compatibility extension)
+ typedef detail::tmat2x3<gtc::half_float::half> half2x3; //!< \brief half-precision floating-point matrix with 2 x 3 components. (From GLM_GTX_compatibility extension)
+ typedef detail::tmat2x4<gtc::half_float::half> half2x4; //!< \brief half-precision floating-point matrix with 2 x 4 components. (From GLM_GTX_compatibility extension)
+ typedef detail::tmat3x2<gtc::half_float::half> half3x2; //!< \brief half-precision floating-point matrix with 3 x 2 components. (From GLM_GTX_compatibility extension)
+ typedef detail::tmat3x3<gtc::half_float::half> half3x3; //!< \brief half-precision floating-point matrix with 3 x 3 components. (From GLM_GTX_compatibility extension)
+ typedef detail::tmat3x4<gtc::half_float::half> half3x4; //!< \brief half-precision floating-point matrix with 3 x 3 components. (From GLM_GTX_compatibility extension)
+ typedef detail::tmat4x2<gtc::half_float::half> half4x2; //!< \brief half-precision floating-point matrix with 4 x 2 components. (From GLM_GTX_compatibility extension)
+ typedef detail::tmat4x3<gtc::half_float::half> half4x3; //!< \brief half-precision floating-point matrix with 4 x 3 components. (From GLM_GTX_compatibility extension)
+ typedef detail::tmat4x4<gtc::half_float::half> half4x4; //!< \brief half-precision floating-point matrix with 4 x 4 components. (From GLM_GTX_compatibility extension)
+
+ typedef float float1; //!< \brief single-precision floating-point vector with 1 component. (From GLM_GTX_compatibility extension)
+ typedef detail::tvec2<float> float2; //!< \brief single-precision floating-point vector with 2 components. (From GLM_GTX_compatibility extension)
+ typedef detail::tvec3<float> float3; //!< \brief single-precision floating-point vector with 3 components. (From GLM_GTX_compatibility extension)
+ typedef detail::tvec4<float> float4; //!< \brief single-precision floating-point vector with 4 components. (From GLM_GTX_compatibility extension)
+
+ typedef float float1x1; //!< \brief single-precision floating-point matrix with 1 component. (From GLM_GTX_compatibility extension)
+ typedef detail::tmat2x2<float> float2x2; //!< \brief single-precision floating-point matrix with 2 x 2 components. (From GLM_GTX_compatibility extension)
+ typedef detail::tmat2x3<float> float2x3; //!< \brief single-precision floating-point matrix with 2 x 3 components. (From GLM_GTX_compatibility extension)
+ typedef detail::tmat2x4<float> float2x4; //!< \brief single-precision floating-point matrix with 2 x 4 components. (From GLM_GTX_compatibility extension)
+ typedef detail::tmat3x2<float> float3x2; //!< \brief single-precision floating-point matrix with 3 x 2 components. (From GLM_GTX_compatibility extension)
+ typedef detail::tmat3x3<float> float3x3; //!< \brief single-precision floating-point matrix with 3 x 3 components. (From GLM_GTX_compatibility extension)
+ typedef detail::tmat3x4<float> float3x4; //!< \brief single-precision floating-point matrix with 3 x 4 components. (From GLM_GTX_compatibility extension)
+ typedef detail::tmat4x2<float> float4x2; //!< \brief single-precision floating-point matrix with 4 x 2 components. (From GLM_GTX_compatibility extension)
+ typedef detail::tmat4x3<float> float4x3; //!< \brief single-precision floating-point matrix with 4 x 3 components. (From GLM_GTX_compatibility extension)
+ typedef detail::tmat4x4<float> float4x4; //!< \brief single-precision floating-point matrix with 4 x 4 components. (From GLM_GTX_compatibility extension)
+
+ typedef double double1; //!< \brief double-precision floating-point vector with 1 component. (From GLM_GTX_compatibility extension)
+ typedef detail::tvec2<double> double2; //!< \brief double-precision floating-point vector with 2 components. (From GLM_GTX_compatibility extension)
+ typedef detail::tvec3<double> double3; //!< \brief double-precision floating-point vector with 3 components. (From GLM_GTX_compatibility extension)
+ typedef detail::tvec4<double> double4; //!< \brief double-precision floating-point vector with 4 components. (From GLM_GTX_compatibility extension)
+
+ typedef double double1x1; //!< \brief double-precision floating-point matrix with 1 component. (From GLM_GTX_compatibility extension)
+ typedef detail::tmat2x2<double> double2x2; //!< \brief double-precision floating-point matrix with 2 x 2 components. (From GLM_GTX_compatibility extension)
+ typedef detail::tmat2x3<double> double2x3; //!< \brief double-precision floating-point matrix with 2 x 3 components. (From GLM_GTX_compatibility extension)
+ typedef detail::tmat2x4<double> double2x4; //!< \brief double-precision floating-point matrix with 2 x 4 components. (From GLM_GTX_compatibility extension)
+ typedef detail::tmat3x2<double> double3x2; //!< \brief double-precision floating-point matrix with 3 x 2 components. (From GLM_GTX_compatibility extension)
+ typedef detail::tmat3x3<double> double3x3; //!< \brief double-precision floating-point matrix with 3 x 3 components. (From GLM_GTX_compatibility extension)
+ typedef detail::tmat3x4<double> double3x4; //!< \brief double-precision floating-point matrix with 3 x 4 components. (From GLM_GTX_compatibility extension)
+ typedef detail::tmat4x2<double> double4x2; //!< \brief double-precision floating-point matrix with 4 x 2 components. (From GLM_GTX_compatibility extension)
+ typedef detail::tmat4x3<double> double4x3; //!< \brief double-precision floating-point matrix with 4 x 3 components. (From GLM_GTX_compatibility extension)
+ typedef detail::tmat4x4<double> double4x4; //!< \brief double-precision floating-point matrix with 4 x 4 components. (From GLM_GTX_compatibility extension)
+
+ /// @}
+}//namespace compatibility
+}//namespace gtx
+}//namespace glm
+
+#include "compatibility.inl"
+
+namespace glm{using namespace gtx::compatibility;}
+
+#endif//glm_gtx_compatibility
+
+
+
+
+
+
+
+
+
+
diff --git a/src/glm/gtx/compatibility.inl b/src/glm/gtx/compatibility.inl
new file mode 100644
index 0000000..4cdef01
--- /dev/null
+++ b/src/glm/gtx/compatibility.inl
@@ -0,0 +1,141 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2007-03-16
+// Updated : 2008-10-24
+// Licence : This source is under MIT License
+// File : glm/gtx/compatibility.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm{
+namespace gtx{
+namespace compatibility{
+
+// isfinite
+template <typename genType>
+GLM_FUNC_QUALIFIER bool isfinite(
+ genType const & x)
+{
+#if(GLM_COMPILER & GLM_COMPILER_VC)
+ return _finite(x);
+#else//(GLM_COMPILER & GLM_COMPILER_GCC)
+ return std::isfinite(x) != 0;
+#endif
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec2<bool> isfinite(
+ detail::tvec2<valType> const & x)
+{
+ return detail::tvec2<bool>(
+ isfinite(x.x),
+ isfinite(x.y));
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec3<bool> isfinite(
+ detail::tvec3<valType> const & x)
+{
+ return detail::tvec3<bool>(
+ isfinite(x.x),
+ isfinite(x.y),
+ isfinite(x.z));
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec4<bool> isfinite(
+ detail::tvec4<valType> const & x)
+{
+ return detail::tvec4<bool>(
+ isfinite(x.x),
+ isfinite(x.y),
+ isfinite(x.z),
+ isfinite(x.w));
+}
+
+// isinf
+template <typename genType>
+GLM_FUNC_QUALIFIER bool isinf(
+ genType const & x)
+{
+#if(GLM_COMPILER & GLM_COMPILER_VC)
+ return _fpclass(x) == _FPCLASS_NINF || _fpclass(x) == _FPCLASS_PINF;
+#else
+ return std::isinf(x) != 0;
+#endif
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec2<bool> isinf(
+ detail::tvec2<valType> const & x)
+{
+ return detail::tvec2<bool>(
+ isinf(x.x),
+ isinf(x.y));
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec3<bool> isinf(
+ detail::tvec3<valType> const & x)
+{
+ return detail::tvec3<bool>(
+ isinf(x.x),
+ isinf(x.y),
+ isinf(x.z));
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec4<bool> isinf(
+ detail::tvec4<valType> const & x)
+{
+ return detail::tvec4<bool>(
+ isinf(x.x),
+ isinf(x.y),
+ isinf(x.z),
+ isinf(x.w));
+}
+
+// isnan
+template <typename genType>
+GLM_FUNC_QUALIFIER bool isnan(genType const & x)
+{
+#if(GLM_COMPILER & GLM_COMPILER_VC)
+ return _isnan(x);
+#else
+ return std::isnan(x) != 0;
+#endif
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec2<bool> isnan(
+ detail::tvec2<valType> const & x)
+{
+ return detail::tvec2<bool>(
+ isnan(x.x),
+ isnan(x.y));
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec3<bool> isnan(
+ detail::tvec3<valType> const & x)
+{
+ return detail::tvec3<bool>(
+ isnan(x.x),
+ isnan(x.y),
+ isnan(x.z));
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec4<bool> isnan(
+ detail::tvec4<valType> const & x)
+{
+ return detail::tvec4<bool>(
+ isnan(x.x),
+ isnan(x.y),
+ isnan(x.z),
+ isnan(x.w));
+}
+
+}//namespace compatibility
+}//namespace gtx
+}//namespace glm
diff --git a/src/glm/gtx/component_wise.hpp b/src/glm/gtx/component_wise.hpp
new file mode 100644
index 0000000..e22a2a5
--- /dev/null
+++ b/src/glm/gtx/component_wise.hpp
@@ -0,0 +1,63 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2007-05-21
+// Updated : 2007-05-21
+// Licence : This source is under MIT License
+// File : glm/gtx/component_wise.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_gtx_component_wise
+#define glm_gtx_component_wise
+
+// Dependency:
+#include "../glm.hpp"
+
+#if(defined(GLM_MESSAGES) && !defined(glm_ext))
+# pragma message("GLM: GLM_GTX_component_wise extension included")
+#endif
+
+namespace glm{
+namespace gtx{
+namespace component_wise ///< GLM_GTX_component_wise extension: Operations between components of a type
+{
+ /// \addtogroup gtx_component_wise
+ /// @{
+
+ //! Add all vector components together.
+ //! From GLM_GTX_component_wise extension.
+ template <typename genType>
+ typename genType::value_type compAdd(
+ genType const & v);
+
+ //! Multiply all vector components together.
+ //! From GLM_GTX_component_wise extension.
+ template <typename genType>
+ typename genType::value_type compMul(
+ genType const & v);
+
+ //! Find the minimum value between single vector components.
+ //! From GLM_GTX_component_wise extension.
+ template <typename genType>
+ typename genType::value_type compMin(
+ genType const & v);
+
+ //! Find the maximum value between single vector components.
+ //! From GLM_GTX_component_wise extension.
+ template <typename genType>
+ typename genType::value_type compMax(
+ genType const & v);
+
+ /// @}
+}//namespace component_wise
+}//namespace gtx
+}//namespace glm
+
+#include "component_wise.inl"
+
+namespace glm{using namespace gtx::component_wise;}
+
+#endif//glm_gtx_component_wise
diff --git a/src/glm/gtx/component_wise.inl b/src/glm/gtx/component_wise.inl
new file mode 100644
index 0000000..b3d2517
--- /dev/null
+++ b/src/glm/gtx/component_wise.inl
@@ -0,0 +1,52 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2007-05-21
+// Updated : 2010-02-12
+// Licence : This source is under MIT License
+// File : gtx_component_wise.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm{
+namespace gtx{
+namespace component_wise
+{
+ template <typename genType>
+ GLM_FUNC_QUALIFIER typename genType::value_type compAdd(genType const & v)
+ {
+ typename genType::size_type result = typename genType::value_type(0);
+ for(typename genType::size_type i = 0; i < genType::value_size(); ++i)
+ result += v[i];
+ return result;
+ }
+
+ template <typename genType>
+ GLM_FUNC_QUALIFIER typename genType::value_type compMul(genType const & v)
+ {
+ typename genType::value_type result = typename genType::value_type(1);
+ for(typename genType::size_type i = 0; i < genType::value_size(); ++i)
+ result *= v[i];
+ return result;
+ }
+
+ template <typename genType>
+ GLM_FUNC_QUALIFIER typename genType::value_type compMin(genType const & v)
+ {
+ typename genType::value_type result = typename genType::value_type(v[0]);
+ for(typename genType::size_type i = 1; i < genType::value_size(); ++i)
+ result = min(result, v[i]);
+ return result;
+ }
+
+ template <typename genType>
+ GLM_FUNC_QUALIFIER typename genType::value_type compMax(genType const & v)
+ {
+ typename genType::value_type result = typename genType::value_type(v[0]);
+ for(typename genType::size_type i = 1; i < genType::value_size(); ++i)
+ result = max(result, v[i]);
+ return result;
+ }
+
+}//namespace component_wise
+}//namespace gtx
+}//namespace glm
diff --git a/src/glm/gtx/epsilon.hpp b/src/glm/gtx/epsilon.hpp
new file mode 100644
index 0000000..4f0fdd5
--- /dev/null
+++ b/src/glm/gtx/epsilon.hpp
@@ -0,0 +1,59 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2005-12-21
+// Updated : 2006-11-13
+// Licence : This source is under MIT License
+// File : glm/gtx/epsilon.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+// - GLM_GTC_half_float
+// - GLM_GTC_quaternion
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_gtx_epsilon
+#define glm_gtx_epsilon
+
+// Dependency:
+#include "../glm.hpp"
+#include "../gtc/half_float.hpp"
+#include "../gtc/quaternion.hpp"
+
+#if(defined(GLM_MESSAGES) && !defined(glm_ext))
+# pragma message("GLM: GLM_GTX_epsilon extension included")
+#endif
+
+namespace glm{
+namespace gtx{
+namespace epsilon ///< GLM_GTX_epsilon extension: Comparison functions for a user defined epsilon values.
+{
+ /// \addtogroup gtx_epsilon
+ ///@{
+
+ //! Returns the component-wise compare of |x - y| < epsilon.
+ //! From GLM_GTX_epsilon extension.
+ template <typename genTypeT, typename genTypeU>
+ bool equalEpsilon(
+ genTypeT const & x,
+ genTypeT const & y,
+ genTypeU const & epsilon);
+
+ //! Returns the component-wise compare of |x - y| >= epsilon.
+ //! From GLM_GTX_epsilon extension.
+ template <typename genTypeT, typename genTypeU>
+ bool notEqualEpsilon(
+ genTypeT const & x,
+ genTypeT const & y,
+ genTypeU const & epsilon);
+
+ ///@}
+}//namespace epsilon
+}//namespace gtx
+}//namespace glm
+
+#include "epsilon.inl"
+
+namespace glm{using namespace gtx::epsilon;}
+
+#endif//glm_gtx_epsilon
diff --git a/src/glm/gtx/epsilon.inl b/src/glm/gtx/epsilon.inl
new file mode 100644
index 0000000..e81d0ed
--- /dev/null
+++ b/src/glm/gtx/epsilon.inl
@@ -0,0 +1,234 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2005-12-21
+// Updated : 2006-01-16
+// Licence : This source is under MIT License
+// File : glm/gtx/epsilon.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm{
+namespace gtx{
+namespace epsilon{
+
+template <typename genType>
+GLM_FUNC_QUALIFIER bool equalEpsilon
+(
+ genType const & x,
+ genType const & y,
+ genType const & epsilon
+)
+{
+ return abs(x - y) < epsilon;
+}
+
+template <typename genType>
+GLM_FUNC_QUALIFIER bool notEqualEpsilon
+(
+ genType const & x,
+ genType const & y,
+ genType const & epsilon
+)
+{
+ return abs(x - y) >= epsilon;
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec2<bool> equalEpsilon
+(
+ detail::tvec2<valType> const & x,
+ detail::tvec2<valType> const & y,
+ valType const & epsilon)
+{
+ return detail::tvec2<bool>(
+ abs(x.x - y.x) < epsilon,
+ abs(x.y - y.y) < epsilon);
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec3<bool> equalEpsilon
+(
+ detail::tvec3<valType> const & x,
+ detail::tvec3<valType> const & y,
+ valType const & epsilon)
+{
+ return detail::tvec3<bool>(
+ abs(x.x - y.x) < epsilon,
+ abs(x.y - y.y) < epsilon,
+ abs(x.z - y.z) < epsilon);
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec4<bool> equalEpsilon
+(
+ detail::tvec4<valType> const & x,
+ detail::tvec4<valType> const & y,
+ valType const & epsilon
+)
+{
+ return detail::tvec4<bool>(
+ abs(x.x - y.x) < epsilon,
+ abs(x.y - y.y) < epsilon,
+ abs(x.z - y.z) < epsilon,
+ abs(x.w - y.w) < epsilon);
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec2<bool> notEqualEpsilon
+(
+ detail::tvec2<valType> const & x,
+ detail::tvec2<valType> const & y,
+ valType const & epsilon
+)
+{
+ return detail::tvec2<bool>(
+ abs(x.x - y.x) >= epsilon,
+ abs(x.y - y.y) >= epsilon);
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec3<bool> notEqualEpsilon
+(
+ detail::tvec3<valType> const & x,
+ detail::tvec3<valType> const & y,
+ valType const & epsilon
+)
+{
+ return detail::tvec3<bool>(
+ abs(x.x - y.x) >= epsilon,
+ abs(x.y - y.y) >= epsilon,
+ abs(x.z - y.z) >= epsilon);
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec4<bool> notEqualEpsilon
+(
+ detail::tvec4<valType> const & x,
+ detail::tvec4<valType> const & y,
+ valType const & epsilon
+)
+{
+ return detail::tvec4<bool>(
+ abs(x.x - y.x) >= epsilon,
+ abs(x.y - y.y) >= epsilon,
+ abs(x.z - y.z) >= epsilon,
+ abs(x.w - y.w) >= epsilon);
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec2<bool> equalEpsilon
+(
+ detail::tvec2<valType> const & x,
+ detail::tvec2<valType> const & y,
+ detail::tvec2<valType> const & epsilon
+)
+{
+ return detail::tvec2<bool>(
+ abs(x.x - y.x) < epsilon.x,
+ abs(x.y - y.y) < epsilon.y);
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec3<bool> equalEpsilon
+(
+ detail::tvec3<valType> const & x,
+ detail::tvec3<valType> const & y,
+ detail::tvec3<valType> const & epsilon
+)
+{
+ return detail::tvec3<bool>(
+ abs(x.x - y.x) < epsilon.x,
+ abs(x.y - y.y) < epsilon.y,
+ abs(x.z - y.z) < epsilon.z);
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec4<bool> equalEpsilon
+(
+ detail::tvec4<valType> const & x,
+ detail::tvec4<valType> const & y,
+ detail::tvec4<valType> const & epsilon
+)
+{
+ return detail::tvec4<bool>(
+ abs(x.x - y.x) < epsilon.x,
+ abs(x.y - y.y) < epsilon.y,
+ abs(x.z - y.z) < epsilon.z,
+ abs(x.w - y.w) < epsilon.w);
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec4<bool> equalEpsilon
+(
+ detail::tquat<valType> const & x,
+ detail::tquat<valType> const & y,
+ detail::tquat<valType> const & epsilon
+)
+{
+ return detail::tvec4<bool>(
+ abs(x.x - y.x) < epsilon.x,
+ abs(x.y - y.y) < epsilon.y,
+ abs(x.z - y.z) < epsilon.z,
+ abs(x.w - y.w) < epsilon.w);
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec2<bool> notEqualEpsilon
+(
+ detail::tvec2<valType> const & x,
+ detail::tvec2<valType> const & y,
+ detail::tvec2<valType> const & epsilon
+)
+{
+ return detail::tvec2<bool>(
+ abs(x.x - y.x) >= epsilon.x,
+ abs(x.y - y.y) >= epsilon.y);
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec3<bool> notEqualEpsilon
+(
+ detail::tvec3<valType> const & x,
+ detail::tvec3<valType> const & y,
+ detail::tvec3<valType> const & epsilon
+)
+{
+ return detail::tvec3<bool>(
+ abs(x.x - y.x) >= epsilon.x,
+ abs(x.y - y.y) >= epsilon.y,
+ abs(x.z - y.z) >= epsilon.z);
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec4<bool> notEqualEpsilon
+(
+ detail::tvec4<valType> const & x,
+ detail::tvec4<valType> const & y,
+ detail::tvec4<valType> const & epsilon
+)
+{
+ return detail::tvec4<bool>(
+ abs(x.x - y.x) >= epsilon.x,
+ abs(x.y - y.y) >= epsilon.y,
+ abs(x.z - y.z) >= epsilon.z,
+ abs(x.w - y.w) >= epsilon.w);
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec4<bool> notEqualEpsilon
+(
+ detail::tquat<valType> const & x,
+ detail::tquat<valType> const & y,
+ detail::tquat<valType> const & epsilon
+)
+{
+ return detail::tvec4<bool>(
+ abs(x.x - y.x) >= epsilon.x,
+ abs(x.y - y.y) >= epsilon.y,
+ abs(x.z - y.z) >= epsilon.z,
+ abs(x.w - y.w) >= epsilon.w);
+}
+
+}//namespace epsilon
+}//namespace gtx
+}//namespace glm
diff --git a/src/glm/gtx/euler_angles.hpp b/src/glm/gtx/euler_angles.hpp
new file mode 100644
index 0000000..0c4abba
--- /dev/null
+++ b/src/glm/gtx/euler_angles.hpp
@@ -0,0 +1,141 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2005-12-21
+// Updated : 2007-08-14
+// Licence : This source is under MIT License
+// File : glm/gtx/euler_angles.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+// - GLM_GTC_half_float
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// ToDo:
+// - mat2 mat2GTX(const vec2& angles) undefined
+// - mat3 mat3GTX(const vec2& angles) undefined
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_gtx_euler_angles
+#define glm_gtx_euler_angles
+
+// Dependency:
+#include "../glm.hpp"
+#include "../gtc/half_float.hpp"
+
+#if(defined(GLM_MESSAGES) && !defined(glm_ext))
+# pragma message("GLM: GLM_GTX_euler_angles extension included")
+#endif
+
+namespace glm{
+namespace gtx{
+namespace euler_angles ///< GLM_GTX_euler_angles extension: Build matrices from Euler angles.
+{
+ /// \addtogroup gtx_euler_angles
+ /// @{
+
+ //! Creates a 3D 4 * 4 homogeneous rotation matrix from an euler angle X.
+ //! From GLM_GTX_euler_angles extension.
+ template <typename valType>
+ detail::tmat4x4<valType> eulerAngleX(
+ valType const & angleX);
+
+ //! Creates a 3D 4 * 4 homogeneous rotation matrix from an euler angle Y.
+ //! From GLM_GTX_euler_angles extension.
+ template <typename valType>
+ detail::tmat4x4<valType> eulerAngleY(
+ valType const & angleY);
+
+ //! Creates a 3D 4 * 4 homogeneous rotation matrix from an euler angle Z.
+ //! From GLM_GTX_euler_angles extension.
+ template <typename valType>
+ detail::tmat4x4<valType> eulerAngleZ(
+ valType const & angleZ);
+
+ //! Creates a 3D 4 * 4 homogeneous rotation matrix from euler angles (X * Y).
+ //! From GLM_GTX_euler_angles extension.
+ template <typename valType>
+ detail::tmat4x4<valType> eulerAngleXY(
+ valType const & angleX,
+ valType const & angleY);
+
+ //! Creates a 3D 4 * 4 homogeneous rotation matrix from euler angles (Y * X).
+ //! From GLM_GTX_euler_angles extension.
+ template <typename valType>
+ detail::tmat4x4<valType> eulerAngleYX(
+ valType const & angleY,
+ valType const & angleX);
+
+ //! Creates a 3D 4 * 4 homogeneous rotation matrix from euler angles (X * Z).
+ //! From GLM_GTX_euler_angles extension.
+ template <typename valType>
+ detail::tmat4x4<valType> eulerAngleXZ(
+ valType const & angleX,
+ valType const & angleZ);
+
+ //! Creates a 3D 4 * 4 homogeneous rotation matrix from euler angles (Z * X).
+ //! From GLM_GTX_euler_angles extension.
+ template <typename valType>
+ detail::tmat4x4<valType> eulerAngleZX(
+ valType const & angleZ,
+ valType const & angleX);
+
+ //! Creates a 3D 4 * 4 homogeneous rotation matrix from euler angles (Y * Z).
+ //! From GLM_GTX_euler_angles extension.
+ template <typename valType>
+ detail::tmat4x4<valType> eulerAngleYZ(
+ valType const & angleY,
+ valType const & angleZ);
+
+ //! Creates a 3D 4 * 4 homogeneous rotation matrix from euler angles (Z * Y).
+ //! From GLM_GTX_euler_angles extension.
+ template <typename valType>
+ detail::tmat4x4<valType> eulerAngleZY(
+ valType const & angleZ,
+ valType const & angleY);
+
+ //! Creates a 3D 4 * 4 homogeneous rotation matrix from euler angles (Y * X * Z).
+ //! From GLM_GTX_euler_angles extension.
+ template <typename valType>
+ detail::tmat4x4<valType> eulerAngleYXZ(
+ valType const & yaw,
+ valType const & pitch,
+ valType const & roll);
+
+ //! Creates a 3D 4 * 4 homogeneous rotation matrix from euler angles (Y * X * Z).
+ //! From GLM_GTX_euler_angles extension.
+ template <typename valType>
+ detail::tmat4x4<valType> yawPitchRoll(
+ valType const & yaw,
+ valType const & pitch,
+ valType const & roll);
+
+ //! Creates a 2D 2 * 2 rotation matrix from an euler angle.
+ //! From GLM_GTX_euler_angles extension.
+ template <typename T>
+ detail::tmat2x2<T> orientate2(T const & angle);
+
+ //! Creates a 2D 4 * 4 homogeneous rotation matrix from an euler angle.
+ //! From GLM_GTX_euler_angles extension.
+ template <typename T>
+ detail::tmat3x3<T> orientate3(T const & angle);
+
+ //! Creates a 3D 3 * 3 rotation matrix from euler angles (Y * X * Z).
+ //! From GLM_GTX_euler_angles extension.
+ template <typename T>
+ detail::tmat3x3<T> orientate3(detail::tvec3<T> const & angles);
+
+ //! Creates a 3D 4 * 4 homogeneous rotation matrix from euler angles (Y * X * Z).
+ //! From GLM_GTX_euler_angles extension.
+ template <typename T>
+ detail::tmat4x4<T> orientate4(detail::tvec3<T> const & angles);
+
+ /// @}
+}//namespace euler_angles
+}//namespace gtx
+}//namespace glm
+
+#include "euler_angles.inl"
+
+namespace glm{using namespace gtx::euler_angles;}
+
+#endif//glm_gtx_euler_angles
diff --git a/src/glm/gtx/euler_angles.inl b/src/glm/gtx/euler_angles.inl
new file mode 100644
index 0000000..6748ae1
--- /dev/null
+++ b/src/glm/gtx/euler_angles.inl
@@ -0,0 +1,249 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2005-12-21
+// Updated : 2007-08-14
+// Licence : This source is under MIT License
+// File : glm/gtx/euler_angles.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm{
+namespace gtx{
+namespace euler_angles{
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tmat4x4<valType> eulerAngleX
+(
+ valType const & angleX
+)
+{
+ valType cosX = glm::cos(angleX);
+ valType sinX = glm::sin(angleX);
+
+ return detail::tmat4x4<valType>(
+ valType(1), valType(0), valType(0), valType(0),
+ valType(0), cosX, sinX, valType(0),
+ valType(0),-sinX, cosX, valType(0),
+ valType(0), valType(0), valType(0), valType(1));
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tmat4x4<valType> eulerAngleY
+(
+ valType const & angleY
+)
+{
+ valType cosY = glm::cos(angleY);
+ valType sinY = glm::sin(angleY);
+
+ return detail::tmat4x4<valType>(
+ cosY, valType(0), sinY, valType(0),
+ valType(0), valType(1), valType(0), valType(0),
+ -sinY, valType(0), cosY, valType(0),
+ valType(0), valType(0), valType(0), valType(1));
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tmat4x4<valType> eulerAngleZ
+(
+ valType const & angleZ
+)
+{
+ valType cosZ = glm::cos(angleZ);
+ valType sinZ = glm::sin(angleZ);
+
+ return detail::tmat4x4<valType>(
+ cosZ, sinZ, valType(0), valType(0),
+ -sinZ, cosZ, valType(0), valType(0),
+ valType(0), valType(0), valType(1), valType(0),
+ valType(0), valType(0), valType(0), valType(1));
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tmat4x4<valType> eulerAngleXY
+(
+ valType const & angleX,
+ valType const & angleY
+)
+{
+ valType cosX = glm::cos(angleX);
+ valType sinX = glm::sin(angleX);
+ valType cosY = glm::cos(angleY);
+ valType sinY = glm::sin(angleY);
+
+ return detail::tmat4x4<valType>(
+ cosY, -sinX * sinY, cosX * sinY, valType(0),
+ valType(0), cosX, sinX, valType(0),
+ -sinY , -sinX * cosY, cosX * cosY, valType(0),
+ valType(0), valType(0), valType(0), valType(1));
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tmat4x4<valType> eulerAngleYX
+(
+ valType const & angleY,
+ valType const & angleX
+)
+{
+ valType cosX = glm::cos(angleX);
+ valType sinX = glm::sin(angleX);
+ valType cosY = glm::cos(angleY);
+ valType sinY = glm::sin(angleY);
+
+ return detail::tmat4x4<valType>(
+ cosY, valType(0), sinY, valType(0),
+ -sinX * sinY, cosX, sinX * cosY, valType(0),
+ -cosX * sinY, -sinX, cosX * cosY, valType(0),
+ valType(0), valType(0), valType(0), valType(1));
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tmat4x4<valType> eulerAngleXZ
+(
+ valType const & angleX,
+ valType const & angleZ
+)
+{
+ return eulerAngleX(angleX) * eulerAngleZ(angleZ);
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tmat4x4<valType> eulerAngleZX
+(
+ valType const & angleZ,
+ valType const & angleX
+)
+{
+ return eulerAngleZ(angleZ) * eulerAngleX(angleX);
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tmat4x4<valType> eulerAngleYXZ
+(
+ valType const & yaw,
+ valType const & pitch,
+ valType const & roll
+)
+{
+ valType tmp_ch = glm::cos(yaw);
+ valType tmp_sh = glm::sin(yaw);
+ valType tmp_cp = glm::cos(pitch);
+ valType tmp_sp = glm::sin(pitch);
+ valType tmp_cb = glm::cos(roll);
+ valType tmp_sb = glm::sin(roll);
+
+ detail::tmat4x4<valType> Result;
+ Result[0][0] = tmp_ch * tmp_cb + tmp_sh * tmp_sp * tmp_sb;
+ Result[0][1] = tmp_sb * tmp_cp;
+ Result[0][2] = -tmp_sh * tmp_cb + tmp_ch * tmp_sp * tmp_sb;
+ Result[0][3] = valType(0);
+ Result[1][0] = -tmp_ch * tmp_sb + tmp_sh * tmp_sp * tmp_cb;
+ Result[1][1] = tmp_cb * tmp_cp;
+ Result[1][2] = tmp_sb * tmp_sh + tmp_ch * tmp_sp * tmp_cb;
+ Result[1][3] = valType(0);
+ Result[2][0] = tmp_sh * tmp_cp;
+ Result[2][1] = -tmp_sp;
+ Result[2][2] = tmp_ch * tmp_cp;
+ Result[2][3] = valType(0);
+ Result[3][0] = valType(0);
+ Result[3][1] = valType(0);
+ Result[3][2] = valType(0);
+ Result[3][3] = valType(1);
+ return Result;
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tmat4x4<valType> yawPitchRoll
+(
+ valType const & yaw,
+ valType const & pitch,
+ valType const & roll
+)
+{
+ valType tmp_ch = glm::cos(yaw);
+ valType tmp_sh = glm::sin(yaw);
+ valType tmp_cp = glm::cos(pitch);
+ valType tmp_sp = glm::sin(pitch);
+ valType tmp_cb = glm::cos(roll);
+ valType tmp_sb = glm::sin(roll);
+
+ detail::tmat4x4<valType> Result;
+ Result[0][0] = tmp_ch * tmp_cb + tmp_sh * tmp_sp * tmp_sb;
+ Result[0][1] = tmp_sb * tmp_cp;
+ Result[0][2] = -tmp_sh * tmp_cb + tmp_ch * tmp_sp * tmp_sb;
+ Result[0][3] = valType(0);
+ Result[1][0] = -tmp_ch * tmp_sb + tmp_sh * tmp_sp * tmp_cb;
+ Result[1][1] = tmp_cb * tmp_cp;
+ Result[1][2] = tmp_sb * tmp_sh + tmp_ch * tmp_sp * tmp_cb;
+ Result[1][3] = valType(0);
+ Result[2][0] = tmp_sh * tmp_cp;
+ Result[2][1] = -tmp_sp;
+ Result[2][2] = tmp_ch * tmp_cp;
+ Result[2][3] = valType(0);
+ Result[3][0] = valType(0);
+ Result[3][1] = valType(0);
+ Result[3][2] = valType(0);
+ Result[3][3] = valType(1);
+ return Result;
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tmat2x2<valType> orientate2
+(
+ valType const & angle
+)
+{
+ valType c = glm::cos(angle);
+ valType s = glm::sin(angle);
+
+ detail::tmat2x2<valType> Result;
+ Result[0][0] = c;
+ Result[0][1] = s;
+ Result[1][0] = -s;
+ Result[1][1] = c;
+ return Result;
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tmat3x3<valType> orientate3
+(
+ valType const & angle
+)
+{
+ valType c = glm::cos(angle);
+ valType s = glm::sin(angle);
+
+ detail::tmat3x3<valType> Result;
+ Result[0][0] = c;
+ Result[0][1] = s;
+ Result[0][2] = 0.0f;
+ Result[1][0] = -s;
+ Result[1][1] = c;
+ Result[1][2] = 0.0f;
+ Result[2][0] = 0.0f;
+ Result[2][1] = 0.0f;
+ Result[2][2] = 1.0f;
+ return Result;
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tmat3x3<valType> orientate3
+(
+ detail::tvec3<valType> const & angles
+)
+{
+ return detail::tmat3x3<valType>(yawPitchRoll(angles.x, angles.y, angles.z));
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tmat4x4<valType> orientate4
+(
+ detail::tvec3<valType> const & angles
+)
+{
+ return yawPitchRoll(angles.z, angles.x, angles.y);
+}
+
+}//namespace euler_angles
+}//namespace gtx
+}//namespace glm
diff --git a/src/glm/gtx/extend.hpp b/src/glm/gtx/extend.hpp
new file mode 100644
index 0000000..2b9ebf8
--- /dev/null
+++ b/src/glm/gtx/extend.hpp
@@ -0,0 +1,47 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2006-01-07
+// Updated : 2006-11-13
+// Licence : This source is under MIT License
+// File : glm/gtx/extend.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_gtx_extend
+#define glm_gtx_extend
+
+// Dependency:
+#include "../glm.hpp"
+
+#if(defined(GLM_MESSAGES) && !defined(glm_ext))
+# pragma message("GLM: GLM_GTX_extend extension included")
+#endif
+
+namespace glm{
+namespace gtx{
+namespace extend ///< GLM_GTX_extend extension: Extend a position from a source to a position at a defined length.
+{
+ /// \addtogroup gtx_extend
+ /// @{
+
+ //! Extends of Length the Origin position using the (Source - Origin) direction.
+ //! From GLM_GTX_extend extension.
+ template <typename genType>
+ genType extend(
+ genType const & Origin,
+ genType const & Source,
+ typename genType::value_type const Length);
+
+ /// @}
+}//namespace extend
+}//namespace gtx
+}//namespace glm
+
+#include "extend.inl"
+
+namespace glm{using namespace gtx::extend;}
+
+#endif//glm_gtx_extend
diff --git a/src/glm/gtx/extend.inl b/src/glm/gtx/extend.inl
new file mode 100644
index 0000000..8a193c0
--- /dev/null
+++ b/src/glm/gtx/extend.inl
@@ -0,0 +1,60 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2006-01-07
+// Updated : 2008-10-05
+// Licence : This source is under MIT License
+// File : glm/gtx/extend.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm{
+namespace gtx{
+namespace extend{
+
+template <typename genType>
+genType extend
+(
+ genType const & Origin,
+ genType const & Source,
+ genType const & Distance
+)
+{
+ return Origin + (Source - Origin) * Distance;
+}
+
+template <typename valType>
+detail::tvec2<valType> extend
+(
+ detail::tvec2<valType> const & Origin,
+ detail::tvec2<valType> const & Source,
+ valType const & Distance
+)
+{
+ return Origin + (Source - Origin) * Distance;
+}
+
+template <typename valType>
+detail::tvec3<valType> extend
+(
+ detail::tvec3<valType> const & Origin,
+ detail::tvec3<valType> const & Source,
+ valType const & Distance
+)
+{
+ return Origin + (Source - Origin) * Distance;
+}
+
+template <typename valType>
+detail::tvec4<valType> extend
+(
+ detail::tvec4<valType> const & Origin,
+ detail::tvec4<valType> const & Source,
+ valType const & Distance
+)
+{
+ return Origin + (Source - Origin) * Distance;
+}
+
+}//namespace extend
+}//namespace gtx
+}//namespace glm
diff --git a/src/glm/gtx/extented_min_max.hpp b/src/glm/gtx/extented_min_max.hpp
new file mode 100644
index 0000000..857c1f5
--- /dev/null
+++ b/src/glm/gtx/extented_min_max.hpp
@@ -0,0 +1,175 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2007-03-14
+// Updated : 2010-02-19
+// Licence : This source is under MIT License
+// File : gtx_extented_min_max.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+// - GLM_GTX_half_float
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_gtx_extented_min_max
+#define glm_gtx_extented_min_max
+
+// Dependency:
+#include "../glm.hpp"
+#include "../gtc/half_float.hpp"
+
+#if(defined(GLM_MESSAGES) && !defined(glm_ext))
+# pragma message("GLM: GLM_GTX_extented_min_max extension included")
+#endif
+
+namespace glm{
+namespace gtx{
+namespace extented_min_max ///< GLM_GTX_extented_min_max extension: Min and max functions for 3 to 4 parameters.
+{
+ /// \addtogroup gtx_extented_min_max
+ ///@{
+
+ //< Return the minimum component-wise values of 3 inputs
+ //< From GLM_GTX_extented_min_max extension
+ template <typename T>
+ T min(
+ T const & x,
+ T const & y,
+ T const & z);
+
+ //< Return the minimum component-wise values of 3 inputs
+ //< From GLM_GTX_extented_min_max extension
+ template
+ <
+ typename T,
+ template <typename> class C
+ >
+ C<T> min(
+ C<T> const & x,
+ typename C<T>::value_type const & y,
+ typename C<T>::value_type const & z);
+
+ //< Return the minimum component-wise values of 3 inputs
+ //< From GLM_GTX_extented_min_max extension
+ template
+ <
+ typename T,
+ template <typename> class C
+ >
+ C<T> min(
+ C<T> const & x,
+ C<T> const & y,
+ C<T> const & z);
+
+ //< Return the minimum component-wise values of 4 inputs
+ //< From GLM_GTX_extented_min_max extension
+ template <typename T>
+ T min(
+ T const & x,
+ T const & y,
+ T const & z,
+ T const & w);
+
+ //< Return the minimum component-wise values of 4 inputs
+ //< From GLM_GTX_extented_min_max extension
+ template
+ <
+ typename T,
+ template <typename> class C
+ >
+ C<T> min(
+ C<T> const & x,
+ typename C<T>::value_type const & y,
+ typename C<T>::value_type const & z,
+ typename C<T>::value_type const & w);
+
+ //< Return the minimum component-wise values of 4 inputs
+ //< From GLM_GTX_extented_min_max extension
+ template
+ <
+ typename T,
+ template <typename> class C
+ >
+ C<T> min(
+ C<T> const & x,
+ C<T> const & y,
+ C<T> const & z,
+ C<T> const & w);
+
+ //< Return the maximum component-wise values of 3 inputs
+ //< From GLM_GTX_extented_min_max extension
+ template <typename T>
+ T max(
+ T const & x,
+ T const & y,
+ T const & z);
+
+ //< Return the maximum component-wise values of 3 inputs
+ //< From GLM_GTX_extented_min_max extension
+ template
+ <
+ typename T,
+ template <typename> class C
+ >
+ C<T> max(
+ C<T> const & x,
+ typename C<T>::value_type const & y,
+ typename C<T>::value_type const & z);
+
+ //< Return the maximum component-wise values of 3 inputs
+ //< From GLM_GTX_extented_min_max extension
+ template
+ <
+ typename T,
+ template <typename> class C
+ >
+ C<T> max(
+ C<T> const & x,
+ C<T> const & y,
+ C<T> const & z);
+
+ //< Return the maximum component-wise values of 4 inputs
+ //< From GLM_GTX_extented_min_max extension
+ template <typename T>
+ T max(
+ T const & x,
+ T const & y,
+ T const & z,
+ T const & w);
+
+ //< Return the maximum component-wise values of 4 inputs
+ //< From GLM_GTX_extented_min_max extension
+ template
+ <
+ typename T,
+ template <typename> class C
+ >
+ C<T> max(
+ C<T> const & x,
+ typename C<T>::value_type const & y,
+ typename C<T>::value_type const & z,
+ typename C<T>::value_type const & w);
+
+ //< Return the maximum component-wise values of 4 inputs
+ //< From GLM_GTX_extented_min_max extension
+ template
+ <
+ typename T,
+ template <typename> class C
+ >
+ C<T> max(
+ C<T> const & x,
+ C<T> const & y,
+ C<T> const & z,
+ C<T> const & w);
+
+ /// @}
+}//namespace extented_min_max
+}//namespace gtx
+}//namespace glm
+
+#include "extented_min_max.inl"
+
+namespace glm{using namespace gtx::extented_min_max;}
+
+#endif//glm_gtx_extented_min_max
diff --git a/src/glm/gtx/extented_min_max.inl b/src/glm/gtx/extented_min_max.inl
new file mode 100644
index 0000000..caaf0c5
--- /dev/null
+++ b/src/glm/gtx/extented_min_max.inl
@@ -0,0 +1,182 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2007-03-14
+// Updated : 2010-02-19
+// Licence : This source is under MIT License
+// File : gtx_extented_min_max.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm{
+namespace gtx{
+namespace extented_min_max
+{
+ template <typename T>
+ GLM_FUNC_QUALIFIER T min(
+ T const & x,
+ T const & y,
+ T const & z)
+ {
+ return glm::min(glm::min(x, y), z);
+ }
+
+ template
+ <
+ typename T,
+ template <typename> class C
+ >
+ GLM_FUNC_QUALIFIER C<T> min
+ (
+ C<T> const & x,
+ typename C<T>::value_type const & y,
+ typename C<T>::value_type const & z
+ )
+ {
+ return glm::min(glm::min(x, y), z);
+ }
+
+ template
+ <
+ typename T,
+ template <typename> class C
+ >
+ GLM_FUNC_QUALIFIER C<T> min
+ (
+ C<T> const & x,
+ C<T> const & y,
+ C<T> const & z
+ )
+ {
+ return glm::min(glm::min(x, y), z);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER T min
+ (
+ T const & x,
+ T const & y,
+ T const & z,
+ T const & w
+ )
+ {
+ return glm::min(glm::min(x, y), glm::min(z, w));
+ }
+
+ template
+ <
+ typename T,
+ template <typename> class C
+ >
+ GLM_FUNC_QUALIFIER C<T> min
+ (
+ C<T> const & x,
+ typename C<T>::value_type const & y,
+ typename C<T>::value_type const & z,
+ typename C<T>::value_type const & w
+ )
+ {
+ return glm::min(glm::min(x, y), glm::min(z, w));
+ }
+
+ template
+ <
+ typename T,
+ template <typename> class C
+ >
+ GLM_FUNC_QUALIFIER C<T> min
+ (
+ C<T> const & x,
+ C<T> const & y,
+ C<T> const & z,
+ C<T> const & w
+ )
+ {
+ return glm::min(glm::min(x, y), glm::min(z, w));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER T max(
+ T const & x,
+ T const & y,
+ T const & z)
+ {
+ return glm::max(glm::max(x, y), z);
+ }
+
+ template
+ <
+ typename T,
+ template <typename> class C
+ >
+ GLM_FUNC_QUALIFIER C<T> max
+ (
+ C<T> const & x,
+ typename C<T>::value_type const & y,
+ typename C<T>::value_type const & z
+ )
+ {
+ return glm::max(glm::max(x, y), z);
+ }
+
+ template
+ <
+ typename T,
+ template <typename> class C
+ >
+ GLM_FUNC_QUALIFIER C<T> max
+ (
+ C<T> const & x,
+ C<T> const & y,
+ C<T> const & z
+ )
+ {
+ return glm::max(glm::max(x, y), z);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER T max
+ (
+ T const & x,
+ T const & y,
+ T const & z,
+ T const & w
+ )
+ {
+ return glm::max(glm::max(x, y), glm::max(z, w));
+ }
+
+ template
+ <
+ typename T,
+ template <typename> class C
+ >
+ GLM_FUNC_QUALIFIER C<T> max
+ (
+ C<T> const & x,
+ typename C<T>::value_type const & y,
+ typename C<T>::value_type const & z,
+ typename C<T>::value_type const & w
+ )
+ {
+ return glm::max(glm::max(x, y), glm::max(z, w));
+ }
+
+ template
+ <
+ typename T,
+ template <typename> class C
+ >
+ GLM_FUNC_QUALIFIER C<T> max
+ (
+ C<T> const & x,
+ C<T> const & y,
+ C<T> const & z,
+ C<T> const & w
+ )
+ {
+ return glm::max(glm::max(x, y), glm::max(z, w));
+ }
+
+}//namespace extented_min_max
+}//namespace gtx
+}//namespace glm
diff --git a/src/glm/gtx/fast_exponential.hpp b/src/glm/gtx/fast_exponential.hpp
new file mode 100644
index 0000000..c7ec5bd
--- /dev/null
+++ b/src/glm/gtx/fast_exponential.hpp
@@ -0,0 +1,81 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2006-01-09
+// Updated : 2006-11-13
+// Licence : This source is under MIT License
+// File : glm/gtx/fast_exponential.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+// - GLM_GTC_half_float
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_gtx_fast_exponential
+#define glm_gtx_fast_exponential
+
+// Dependency:
+#include "../glm.hpp"
+#include "../gtc/half_float.hpp"
+
+#if(defined(GLM_MESSAGES) && !defined(glm_ext))
+# pragma message("GLM: GLM_GTX_fast_exponential extension included")
+#endif
+
+namespace glm{
+namespace gtx{
+namespace fast_exponential ///< GLM_GTX_fast_exponential extension: Fast but less accurate implementations of exponential based functions.
+{
+ using namespace gtc::half_float;
+ /// \addtogroup gtx_fast_exponential
+ /// @{
+
+ //! Faster than the common pow function but less accurate.
+ //! From GLM_GTX_fast_exponential extension.
+ template <typename valType>
+ valType fastPow(
+ valType const & x,
+ valType const & y);
+
+ //! Faster than the common pow function but less accurate.
+ //! From GLM_GTX_fast_exponential extension.
+ template <typename T, typename U>
+ T fastPow(
+ const T& x,
+ const U& y);
+
+ //! Faster than the common exp function but less accurate.
+ //! From GLM_GTX_fast_exponential extension.
+ template <typename T>
+ T fastExp(const T& x);
+
+ //! Faster than the common log function but less accurate.
+ //! From GLM_GTX_fast_exponential extension.
+ template <typename T>
+ T fastLog(const T& x);
+
+ //! Faster than the common exp2 function but less accurate.
+ //! From GLM_GTX_fast_exponential extension.
+ template <typename T>
+ T fastExp2(const T& x);
+
+ //! Faster than the common log2 function but less accurate.
+ //! From GLM_GTX_fast_exponential extension.
+ template <typename T>
+ T fastLog2(const T& x);
+
+ //! Faster than the common ln function but less accurate.
+ //! From GLM_GTX_fast_exponential extension.
+ template <typename T>
+ T fastLn(const T& x);
+
+ /// @}
+}//namespace fast_exponential
+}//namespace gtx
+}//namespace glm
+
+#include "fast_exponential.inl"
+
+namespace glm{using namespace gtx::fast_exponential;}
+
+#endif//glm_gtx_fast_exponential
diff --git a/src/glm/gtx/fast_exponential.inl b/src/glm/gtx/fast_exponential.inl
new file mode 100644
index 0000000..59c0397
--- /dev/null
+++ b/src/glm/gtx/fast_exponential.inl
@@ -0,0 +1,294 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2006-01-09
+// Updated : 2006-01-09
+// Licence : This source is under MIT License
+// File : glm/gtx/fast_exponential.h
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm{
+namespace gtx{
+namespace fast_exponential
+{
+ // fastPow:
+ template <typename T>
+ GLM_FUNC_QUALIFIER T fastPow(const T x, const T y)
+ {
+ return exp(y * log(x));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<T> fastPow(
+ const detail::tvec2<T>& x,
+ const detail::tvec2<T>& y)
+ {
+ return detail::tvec2<T>(
+ fastPow(x.x, y.x),
+ fastPow(x.y, y.y));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> fastPow(
+ const detail::tvec3<T>& x,
+ const detail::tvec3<T>& y)
+ {
+ return detail::tvec3<T>(
+ fastPow(x.x, y.x),
+ fastPow(x.y, y.y),
+ fastPow(x.z, y.z));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<T> fastPow(
+ const detail::tvec4<T>& x,
+ const detail::tvec4<T>& y)
+ {
+ return detail::tvec4<T>(
+ fastPow(x.x, y.x),
+ fastPow(x.y, y.y),
+ fastPow(x.z, y.z),
+ fastPow(x.w, y.w));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER T fastPow(const T x, int y)
+ {
+ T f = T(1);
+ for(int i = 0; i < y; ++i)
+ f *= x;
+ return f;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<T> fastPow(
+ const detail::tvec2<T>& x,
+ const detail::tvec2<int>& y)
+ {
+ return detail::tvec2<T>(
+ fastPow(x.x, y.x),
+ fastPow(x.y, y.y));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> fastPow(
+ const detail::tvec3<T>& x,
+ const detail::tvec3<int>& y)
+ {
+ return detail::tvec3<T>(
+ fastPow(x.x, y.x),
+ fastPow(x.y, y.y),
+ fastPow(x.z, y.z));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<T> fastPow(
+ const detail::tvec4<T>& x,
+ const detail::tvec4<int>& y)
+ {
+ return detail::tvec4<T>(
+ fastPow(x.x, y.x),
+ fastPow(x.y, y.y),
+ fastPow(x.z, y.z),
+ fastPow(x.w, y.w));
+ }
+
+ // fastExp
+ // Note: This function provides accurate results only for value between -1 and 1, else avoid it.
+ template <typename T>
+ GLM_FUNC_QUALIFIER T fastExp(const T x)
+ {
+ // This has a better looking and same performance in release mode than the following code. However, in debug mode it's slower.
+ // return 1.0f + x * (1.0f + x * 0.5f * (1.0f + x * 0.3333333333f * (1.0f + x * 0.25 * (1.0f + x * 0.2f))));
+ T x2 = x * x;
+ T x3 = x2 * x;
+ T x4 = x3 * x;
+ T x5 = x4 * x;
+ return T(1) + x + (x2 * T(0.5)) + (x3 * T(0.1666666667)) + (x4 * T(0.041666667)) + (x5 * T(0.008333333333));
+ }
+/* // Try to handle all values of float... but often shower than std::exp, glm::floor and the loop kill the performance
+ GLM_FUNC_QUALIFIER float fastExp(float x)
+ {
+ const float e = 2.718281828f;
+ const float IntegerPart = floor(x);
+ const float FloatPart = x - IntegerPart;
+ float z = 1.f;
+
+ for(int i = 0; i < int(IntegerPart); ++i)
+ z *= e;
+
+ const float x2 = FloatPart * FloatPart;
+ const float x3 = x2 * FloatPart;
+ const float x4 = x3 * FloatPart;
+ const float x5 = x4 * FloatPart;
+ return z * (1.0f + FloatPart + (x2 * 0.5f) + (x3 * 0.1666666667f) + (x4 * 0.041666667f) + (x5 * 0.008333333333f));
+ }
+
+ // Increase accuracy on number bigger that 1 and smaller than -1 but it's not enough for high and negative numbers
+ GLM_FUNC_QUALIFIER float fastExp(float x)
+ {
+ // This has a better looking and same performance in release mode than the following code. However, in debug mode it's slower.
+ // return 1.0f + x * (1.0f + x * 0.5f * (1.0f + x * 0.3333333333f * (1.0f + x * 0.25 * (1.0f + x * 0.2f))));
+ float x2 = x * x;
+ float x3 = x2 * x;
+ float x4 = x3 * x;
+ float x5 = x4 * x;
+ float x6 = x5 * x;
+ float x7 = x6 * x;
+ float x8 = x7 * x;
+ return 1.0f + x + (x2 * 0.5f) + (x3 * 0.1666666667f) + (x4 * 0.041666667f) + (x5 * 0.008333333333f)+ (x6 * 0.00138888888888f) + (x7 * 0.000198412698f) + (x8 * 0.0000248015873f);;
+ }
+*/
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<T> fastExp(
+ const detail::tvec2<T>& x)
+ {
+ return detail::tvec2<T>(
+ fastExp(x.x),
+ fastExp(x.y));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> fastExp(
+ const detail::tvec3<T>& x)
+ {
+ return detail::tvec3<T>(
+ fastExp(x.x),
+ fastExp(x.y),
+ fastExp(x.z));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<T> fastExp(
+ const detail::tvec4<T>& x)
+ {
+ return detail::tvec4<T>(
+ fastExp(x.x),
+ fastExp(x.y),
+ fastExp(x.z),
+ fastExp(x.w));
+ }
+
+ // fastLog
+ template <typename T>
+ GLM_FUNC_QUALIFIER T fastLog(const T x)
+ {
+ return std::log(x);
+ }
+
+ /* Slower than the VC7.1 function...
+ GLM_FUNC_QUALIFIER float fastLog(float x)
+ {
+ float y1 = (x - 1.0f) / (x + 1.0f);
+ float y2 = y1 * y1;
+ return 2.0f * y1 * (1.0f + y2 * (0.3333333333f + y2 * (0.2f + y2 * 0.1428571429f)));
+ }
+ */
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<T> fastLog(
+ const detail::tvec2<T>& x)
+ {
+ return detail::tvec2<T>(
+ fastLog(x.x),
+ fastLog(x.y));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> fastLog(
+ const detail::tvec3<T>& x)
+ {
+ return detail::tvec3<T>(
+ fastLog(x.x),
+ fastLog(x.y),
+ fastLog(x.z));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<T> fastLog(
+ const detail::tvec4<T>& x)
+ {
+ return detail::tvec4<T>(
+ fastLog(x.x),
+ fastLog(x.y),
+ fastLog(x.z),
+ fastLog(x.w));
+ }
+
+ //fastExp2, ln2 = 0.69314718055994530941723212145818f
+ template <typename T>
+ GLM_FUNC_QUALIFIER T fastExp2(const T x)
+ {
+ return fastExp(0.69314718055994530941723212145818f * x);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<T> fastExp2(
+ const detail::tvec2<T>& x)
+ {
+ return detail::tvec2<T>(
+ fastExp2(x.x),
+ fastExp2(x.y));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> fastExp2(
+ const detail::tvec3<T>& x)
+ {
+ return detail::tvec3<T>(
+ fastExp2(x.x),
+ fastExp2(x.y),
+ fastExp2(x.z));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<T> fastExp2(
+ const detail::tvec4<T>& x)
+ {
+ return detail::tvec4<T>(
+ fastExp2(x.x),
+ fastExp2(x.y),
+ fastExp2(x.z),
+ fastExp2(x.w));
+ }
+
+ // fastLog2, ln2 = 0.69314718055994530941723212145818f
+ template <typename T>
+ GLM_FUNC_QUALIFIER T fastLog2(const T x)
+ {
+ return fastLog(x) / 0.69314718055994530941723212145818f;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<T> fastLog2(
+ const detail::tvec2<T>& x)
+ {
+ return detail::tvec2<T>(
+ fastLog2(x.x),
+ fastLog2(x.y));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> fastLog2(
+ const detail::tvec3<T>& x)
+ {
+ return detail::tvec3<T>(
+ fastLog2(x.x),
+ fastLog2(x.y),
+ fastLog2(x.z));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<T> fastLog2(
+ const detail::tvec4<T>& x)
+ {
+ return detail::tvec4<T>(
+ fastLog2(x.x),
+ fastLog2(x.y),
+ fastLog2(x.z),
+ fastLog2(x.w));
+ }
+
+}//namespace fast_exponential
+}//namespace gtx
+}//namespace glm
diff --git a/src/glm/gtx/fast_square_root.hpp b/src/glm/gtx/fast_square_root.hpp
new file mode 100644
index 0000000..c9ded29
--- /dev/null
+++ b/src/glm/gtx/fast_square_root.hpp
@@ -0,0 +1,68 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2006-01-04
+// Updated : 2008-10-07
+// Licence : This source is under MIT License
+// File : glm/gtx/fast_square_root.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Note:
+// - Sqrt optimisation based on Newton's method,
+// www.gamedev.net/community/forums/topic.asp?topic id=139956
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_gtx_fast_square_root
+#define glm_gtx_fast_square_root
+
+// Dependency:
+#include "../glm.hpp"
+
+#if(defined(GLM_MESSAGES) && !defined(glm_ext))
+# pragma message("GLM: GLM_GTX_fast_square_root extension included")
+#endif
+
+namespace glm{
+namespace gtx{
+namespace fast_square_root ///< GLM_GTX_fast_square_root extension: Fast but less accurate implementations of square root based functions.
+{
+ /// \addtogroup gtx_fast_square_root
+ /// @{
+
+ //! Faster than the common sqrt function but less accurate.
+ //! From GLM_GTX_fast_square_root extension.
+ template <typename genType>
+ genType fastSqrt(genType const & x);
+
+ //! Faster than the common inversesqrt function but less accurate.
+ //! From GLM_GTX_fast_square_root extension.
+ template <typename genType>
+ genType fastInverseSqrt(genType const & x);
+
+ //! Faster than the common length function but less accurate.
+ //! From GLM_GTX_fast_square_root extension.
+ template <typename genType>
+ typename genType::value_type fastLength(genType const & x);
+
+ //! Faster than the common distance function but less accurate.
+ //! From GLM_GTX_fast_square_root extension.
+ template <typename genType>
+ typename genType::value_type fastDistance(genType const & x, genType const & y);
+
+ //! Faster than the common normalize function but less accurate.
+ //! From GLM_GTX_fast_square_root extension.
+ template <typename genType>
+ genType fastNormalize(genType const & x);
+
+ /// @}
+}// namespace fast_square_root
+}// namespace gtx
+}// namespace glm
+
+#include "fast_square_root.inl"
+
+namespace glm{using namespace gtx::fast_square_root;}
+
+#endif//glm_gtx_fast_square_root
diff --git a/src/glm/gtx/fast_square_root.inl b/src/glm/gtx/fast_square_root.inl
new file mode 100644
index 0000000..76d0e15
--- /dev/null
+++ b/src/glm/gtx/fast_square_root.inl
@@ -0,0 +1,237 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2006-01-04
+// Updated : 2008-10-07
+// Licence : This source is under MIT License
+// File : glm/gtx/fast_square_root.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm{
+namespace gtx{
+namespace fast_square_root{
+
+// fastSqrt
+template <typename genType>
+GLM_FUNC_QUALIFIER genType fastSqrt
+(
+ genType const & x
+)
+{
+ return genType(1) / fastInverseSqrt(x);
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec2<valType> fastSqrt
+(
+ detail::tvec2<valType> const & x
+)
+{
+ return detail::tvec2<valType>(
+ fastSqrt(x.x),
+ fastSqrt(x.y));
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec3<valType> fastSqrt
+(
+ detail::tvec3<valType> const & x
+)
+{
+ return detail::tvec3<valType>(
+ fastSqrt(x.x),
+ fastSqrt(x.y),
+ fastSqrt(x.z));
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec4<valType> fastSqrt
+(
+ detail::tvec4<valType> const & x
+)
+{
+ return detail::tvec4<valType>(
+ fastSqrt(x.x),
+ fastSqrt(x.y),
+ fastSqrt(x.z),
+ fastSqrt(x.w));
+}
+
+// fastInversesqrt
+template <typename genType>
+GLM_FUNC_QUALIFIER genType fastInverseSqrt
+(
+ genType const & x
+)
+{
+ genType tmp = x;
+ float xhalf = 0.5f * float(tmp);
+ uint i = *(uint*)&x;
+ i = 0x5f375a86 - (i >> 1);
+ //x = *(float*)&i;
+ //x = *((float*)(char*)&i);
+ tmp = detail::uif(i).f;
+ tmp = tmp * (1.5f - xhalf * tmp * tmp);
+ return genType(tmp);
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec2<valType> fastInverseSqrt
+(
+ detail::tvec2<valType> const & x
+)
+{
+ return detail::tvec2<valType>(
+ fastInverseSqrt(x.x),
+ fastInverseSqrt(x.y));
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec3<valType> fastInverseSqrt
+(
+ detail::tvec3<valType> const & x
+)
+{
+ return detail::tvec3<valType>(
+ fastInverseSqrt(x.x),
+ fastInverseSqrt(x.y),
+ fastInverseSqrt(x.z));
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec4<valType> fastInverseSqrt
+(
+ detail::tvec4<valType> const & x
+)
+{
+ return detail::tvec4<valType>(
+ fastInverseSqrt(x.x),
+ fastInverseSqrt(x.y),
+ fastInverseSqrt(x.z),
+ fastInverseSqrt(x.w));
+}
+
+// fastLength
+template <typename genType>
+GLM_FUNC_QUALIFIER genType fastLength
+(
+ genType const & x
+)
+{
+ return abs(x);
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER valType fastLength
+(
+ detail::tvec2<valType> const & x
+)
+{
+ valType sqr = x.x * x.x + x.y * x.y;
+ return fastSqrt(sqr);
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER valType fastLength
+(
+ detail::tvec3<valType> const & x
+)
+{
+ valType sqr = x.x * x.x + x.y * x.y + x.z * x.z;
+ return fastSqrt(sqr);
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER valType fastLength
+(
+ detail::tvec4<valType> const & x
+)
+{
+ valType sqr = x.x * x.x + x.y * x.y + x.z * x.z + x.w * x.w;
+ return fastSqrt(sqr);
+}
+
+// fastDistance
+template <typename genType>
+GLM_FUNC_QUALIFIER genType fastDistance
+(
+ genType const & x,
+ genType const & y
+)
+{
+ return fastLength(y - x);
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER valType fastDistance
+(
+ detail::tvec2<valType> const & x,
+ detail::tvec2<valType> const & y
+)
+{
+ return fastLength(y - x);
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER valType fastDistance
+(
+ detail::tvec3<valType> const & x,
+ detail::tvec3<valType> const & y
+)
+{
+ return fastLength(y - x);
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER valType fastDistance
+(
+ detail::tvec4<valType> const & x,
+ detail::tvec4<valType> const & y
+)
+{
+ return fastLength(y - x);
+}
+
+// fastNormalize
+template <typename genType>
+GLM_FUNC_QUALIFIER genType fastNormalize
+(
+ genType const & x
+)
+{
+ return x > genType(0) ? genType(1) : -genType(1);
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec2<valType> fastNormalize
+(
+ detail::tvec2<valType> const & x
+)
+{
+ valType sqr = x.x * x.x + x.y * x.y;
+ return x * fastInverseSqrt(sqr);
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec3<valType> fastNormalize
+(
+ detail::tvec3<valType> const & x
+)
+{
+ valType sqr = x.x * x.x + x.y * x.y + x.z * x.z;
+ return x * fastInverseSqrt(sqr);
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec4<valType> fastNormalize
+(
+ detail::tvec4<valType> const & x
+)
+{
+ valType sqr = x.x * x.x + x.y * x.y + x.z * x.z + x.w * x.w;
+ return x * fastInverseSqrt(sqr);
+}
+
+}//namespace fast_square_root
+}//namespace gtx
+}//namespace glm
diff --git a/src/glm/gtx/fast_trigonometry.hpp b/src/glm/gtx/fast_trigonometry.hpp
new file mode 100644
index 0000000..d597df2
--- /dev/null
+++ b/src/glm/gtx/fast_trigonometry.hpp
@@ -0,0 +1,81 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2006-01-08
+// Updated : 2006-11-13
+// Licence : This source is under MIT License
+// File : glm/gtx/fast_trigonometry.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_gtx_fast_trigonometry
+#define glm_gtx_fast_trigonometry
+
+// Dependency:
+#include "../glm.hpp"
+
+#if(defined(GLM_MESSAGES) && !defined(glm_ext))
+# pragma message("GLM: GLM_GTX_fast_trigonometry extension included")
+#endif
+
+namespace glm{
+namespace gtx{
+namespace fast_trigonometry ///< GLM_GTX_fast_trigonometry extension: Fast but less accurate implementations of trigonometric functions.
+{
+ /// \addtogroup gtx_fast_trigonometry
+ /// @{
+
+ //! Faster than the common sin function but less accurate.
+ //! Defined between -2pi and 2pi.
+ //! From GLM_GTX_fast_trigonometry extension.
+ template <typename T>
+ T fastSin(const T& angle);
+
+ //! Faster than the common cos function but less accurate.
+ //! Defined between -2pi and 2pi.
+ //! From GLM_GTX_fast_trigonometry extension.
+ template <typename T>
+ T fastCos(const T& angle);
+
+ //! Faster than the common tan function but less accurate.
+ //! Defined between -2pi and 2pi.
+ //! From GLM_GTX_fast_trigonometry extension.
+ template <typename T>
+ T fastTan(const T& angle);
+
+ //! Faster than the common asin function but less accurate.
+ //! Defined between -2pi and 2pi.
+ //! From GLM_GTX_fast_trigonometry extension.
+ template <typename T>
+ T fastAsin(const T& angle);
+
+ //! Faster than the common acos function but less accurate.
+ //! Defined between -2pi and 2pi.
+ //! From GLM_GTX_fast_trigonometry extension.
+ template <typename T>
+ T fastAcos(const T& angle);
+
+ //! Faster than the common atan function but less accurate.
+ //! Defined between -2pi and 2pi.
+ //! From GLM_GTX_fast_trigonometry extension.
+ template <typename T>
+ T fastAtan(const T& y, const T& x);
+
+ //! Faster than the common atan function but less accurate.
+ //! Defined between -2pi and 2pi.
+ //! From GLM_GTX_fast_trigonometry extension.
+ template <typename T>
+ T fastAtan(const T& angle);
+
+ /// @}
+}//namespace fast_trigonometry
+}//namespace gtx
+}//namespace glm
+
+#include "fast_trigonometry.inl"
+
+namespace glm{using namespace gtx::fast_trigonometry;}
+
+#endif//glm_gtx_fast_trigonometry
diff --git a/src/glm/gtx/fast_trigonometry.inl b/src/glm/gtx/fast_trigonometry.inl
new file mode 100644
index 0000000..3f3750f
--- /dev/null
+++ b/src/glm/gtx/fast_trigonometry.inl
@@ -0,0 +1,272 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2006-01-08
+// Updated : 2006-01-08
+// Licence : This source is under MIT License
+// File : glm/gtx/fast_trigonometry.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm{
+namespace gtx{
+namespace fast_trigonometry
+{
+ // sin
+ template <typename T>
+ GLM_FUNC_QUALIFIER T fastSin(const T x)
+ {
+ return x - ((x * x * x) / T(6)) + ((x * x * x * x * x) / T(120)) - ((x * x * x * x * x * x * x) / T(5040));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<T> fastSin(
+ const detail::tvec2<T>& x)
+ {
+ return detail::tvec2<T>(
+ fastSin(x.x),
+ fastSin(x.y));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> fastSin(
+ const detail::tvec3<T>& x)
+ {
+ return detail::tvec3<T>(
+ fastSin(x.x),
+ fastSin(x.y),
+ fastSin(x.z));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<T> fastSin(
+ const detail::tvec4<T>& x)
+ {
+ return detail::tvec4<T>(
+ fastSin(x.x),
+ fastSin(x.y),
+ fastSin(x.z),
+ fastSin(x.w));
+ }
+
+ // cos
+ template <typename T>
+ GLM_FUNC_QUALIFIER T fastCos(const T x)
+ {
+ return T(1) - (x * x * T(0.5)) + (x * x * x * x * T(0.041666666666)) - (x * x * x * x * x * x * T(0.00138888888888));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<T> fastCos(
+ const detail::tvec2<T>& x)
+ {
+ return detail::tvec2<T>(
+ fastCos(x.x),
+ fastCos(x.y));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> fastCos(
+ const detail::tvec3<T>& x)
+ {
+ return detail::tvec3<T>(
+ fastCos(x.x),
+ fastCos(x.y),
+ fastCos(x.z));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<T> fastCos(
+ const detail::tvec4<T>& x)
+ {
+ return detail::tvec4<T>(
+ fastCos(x.x),
+ fastCos(x.y),
+ fastCos(x.z),
+ fastCos(x.w));
+ }
+
+ // tan
+ template <typename T>
+ GLM_FUNC_QUALIFIER T fastTan(const T x)
+ {
+ return x + (x * x * x * T(0.3333333333)) + (x * x * x * x * x * T(0.1333333333333)) + (x * x * x * x * x * x * x * T(0.0539682539));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<T> fastTan(
+ const detail::tvec2<T>& x)
+ {
+ return detail::tvec2<T>(
+ fastTan(x.x),
+ fastTan(x.y));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> fastTan(
+ const detail::tvec3<T>& x)
+ {
+ return detail::tvec3<T>(
+ fastTan(x.x),
+ fastTan(x.y),
+ fastTan(x.z));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<T> fastTan(
+ const detail::tvec4<T>& x)
+ {
+ return detail::tvec4<T>(
+ fastTan(x.x),
+ fastTan(x.y),
+ fastTan(x.z),
+ fastTan(x.w));
+ }
+
+ // asin
+ template <typename T>
+ GLM_FUNC_QUALIFIER T fastAsin(const T x)
+ {
+ return x + (x * x * x * T(0.166666667)) + (x * x * x * x * x * T(0.075)) + (x * x * x * x * x * x * x * T(0.0446428571)) + (x * x * x * x * x * x * x * x * x * T(0.0303819444));// + (x * x * x * x * x * x * x * x * x * x * x * T(0.022372159));
+ }
+
+ template <typename T> detail::tvec2<T> fastAsin(
+ const detail::tvec2<T>& x)
+ {
+ return detail::tvec2<T>(
+ fastAsin(x.x),
+ fastAsin(x.y));
+ }
+
+ template <typename T> detail::tvec3<T> fastAsin(
+ const detail::tvec3<T>& x)
+ {
+ return detail::tvec3<T>(
+ fastAsin(x.x),
+ fastAsin(x.y),
+ fastAsin(x.z));
+ }
+
+ template <typename T> detail::tvec4<T> fastAsin(
+ const detail::tvec4<T>& x)
+ {
+ return detail::tvec4<T>(
+ fastAsin(x.x),
+ fastAsin(x.y),
+ fastAsin(x.z),
+ fastAsin(x.w));
+ }
+
+ // acos
+ template <typename T>
+ GLM_FUNC_QUALIFIER T fastAcos(const T x)
+ {
+ return T(1.5707963267948966192313216916398) - fastAsin(x); //(PI / 2)
+ }
+
+ template <typename T> detail::tvec2<T> fastAcos(
+ const detail::tvec2<T>& x)
+ {
+ return detail::tvec2<T>(
+ fastAcos(x.x),
+ fastAcos(x.y));
+ }
+
+ template <typename T> detail::tvec3<T> fastAcos(
+ const detail::tvec3<T>& x)
+ {
+ return detail::tvec3<T>(
+ fastAcos(x.x),
+ fastAcos(x.y),
+ fastAcos(x.z));
+ }
+
+ template <typename T> detail::tvec4<T> fastAcos(
+ const detail::tvec4<T>& x)
+ {
+ return detail::tvec4<T>(
+ fastAcos(x.x),
+ fastAcos(x.y),
+ fastAcos(x.z),
+ fastAcos(x.w));
+ }
+
+ // atan
+ template <typename T>
+ GLM_FUNC_QUALIFIER T fastAtan(const T y, const T x)
+ {
+ T sgn = sign(y) * sign(x);
+ return abs(fastAtan(y / x)) * sgn;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<T> fastAtan(
+ const detail::tvec2<T>& y,
+ const detail::tvec2<T>& x)
+ {
+ return detail::tvec2<T>(
+ fastAtan(y.x, x.x),
+ fastAtan(y.y, x.y));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> fastAtan(
+ const detail::tvec3<T>& y,
+ const detail::tvec3<T>& x)
+ {
+ return detail::tvec3<T>(
+ fastAtan(y.x, x.x),
+ fastAtan(y.y, x.y),
+ fastAtan(y.z, x.z));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<T> fastAtan(
+ const detail::tvec4<T>& y,
+ const detail::tvec4<T>& x)
+ {
+ return detail::tvec4<T>(
+ fastAtan(y.x, x.x),
+ fastAtan(y.y, x.y),
+ fastAtan(y.z, x.z),
+ fastAtan(y.w, x.w));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER T fastAtan(const T x)
+ {
+ return x - (x * x * x * T(0.333333333333)) + (x * x * x * x * x * T(0.2)) - (x * x * x * x * x * x * x * T(0.1428571429)) + (x * x * x * x * x * x * x * x * x * T(0.111111111111)) - (x * x * x * x * x * x * x * x * x * x * x * T(0.0909090909));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<T> fastAtan(
+ const detail::tvec2<T>& x)
+ {
+ return detail::tvec2<T>(
+ fastAtan(x.x),
+ fastAtan(x.y));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> fastAtan(
+ const detail::tvec3<T>& x)
+ {
+ return detail::tvec3<T>(
+ fastAtan(x.x),
+ fastAtan(x.y),
+ fastAtan(x.z));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<T> fastAtan(
+ const detail::tvec4<T>& x)
+ {
+ return detail::tvec4<T>(
+ fastAtan(x.x),
+ fastAtan(x.y),
+ fastAtan(x.z),
+ fastAtan(x.w));
+ }
+
+}//namespace fast_trigonometry
+}//namespace gtx
+}//namespace glm
diff --git a/src/glm/gtx/gradient_paint.hpp b/src/glm/gtx/gradient_paint.hpp
new file mode 100644
index 0000000..389600a
--- /dev/null
+++ b/src/glm/gtx/gradient_paint.hpp
@@ -0,0 +1,55 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2009-03-06
+// Updated : 2009-03-09
+// Licence : This source is under MIT License
+// File : glm/gtx/gradient_paint.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_gtx_gradient_paint
+#define glm_gtx_gradient_paint
+
+// Dependency:
+#include "../glm.hpp"
+#include "../gtx/optimum_pow.hpp"
+
+#if(defined(GLM_MESSAGES) && !defined(glm_ext))
+# pragma message("GLM: GLM_GTX_gradient_paint extension included")
+#endif
+
+namespace glm{
+namespace gtx{
+namespace gradient_paint ///< GLM_GTX_gradient_paint extension: Compute a radient gradient according section OpenVG 1.1 specifications, 9.3.2 Radial Gradients
+{
+ using namespace gtx::optimum_pow;
+
+ /// \addtogroup gtx_gradient_paint
+ /// @{
+
+ template <typename valType>
+ valType radialGradient(
+ glm::detail::tvec2<valType> const & Center,
+ valType const & Radius,
+ glm::detail::tvec2<valType> const & Focal,
+ glm::detail::tvec2<valType> const & Position);
+
+ template <typename valType>
+ valType linearGradient(
+ glm::detail::tvec2<valType> const & Point0,
+ glm::detail::tvec2<valType> const & Point1,
+ glm::detail::tvec2<valType> const & Position);
+
+ /// @}
+}// namespace gradient_paint
+}// namespace gtx
+}// namespace glm
+
+#include "gradient_paint.inl"
+
+namespace glm{using namespace gtx::gradient_paint;}
+
+#endif//glm_gtx_gradient_paint
diff --git a/src/glm/gtx/gradient_paint.inl b/src/glm/gtx/gradient_paint.inl
new file mode 100644
index 0000000..6967ff4
--- /dev/null
+++ b/src/glm/gtx/gradient_paint.inl
@@ -0,0 +1,44 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2009-03-06
+// Updated : 2009-03-09
+// Licence : This source is under MIT License
+// File : glm/gtx/gradient_paint.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm{
+namespace gtx{
+namespace gradient_paint{
+
+ template <typename valType>
+ valType radialGradient(
+ glm::detail::tvec2<valType> const & Center,
+ valType const & Radius,
+ glm::detail::tvec2<valType> const & Focal,
+ glm::detail::tvec2<valType> const & Position)
+ {
+ glm::detail::tvec2<valType> F = Focal - Center;
+ glm::detail::tvec2<valType> D = Position - Focal;
+ valType Radius2 = gtx::optimum_pow::pow2(Radius);
+ valType Fx2 = gtx::optimum_pow::pow2(F.x);
+ valType Fy2 = gtx::optimum_pow::pow2(F.y);
+
+ valType Numerator = (D.x * F.x + D.y * F.y) + glm::sqrt(Radius2 * (gtx::optimum_pow::pow2(D.x) + gtx::optimum_pow::pow2(D.y)) - gtx::optimum_pow::pow2(D.x * F.y - D.y * F.x));
+ valType Denominator = Radius2 - (Fx2 + Fy2);
+ return Numerator / Denominator;
+ }
+
+ template <typename valType>
+ valType linearGradient(
+ glm::detail::tvec2<valType> const & Point0,
+ glm::detail::tvec2<valType> const & Point1,
+ glm::detail::tvec2<valType> const & Position)
+ {
+ glm::detail::tvec2<valType> Dist = Point1 - Point0;
+ return (Dist.x * (Position.x - Point0.x) + Dist.y * (Position.y - Point0.y)) / glm::dot(Dist, Dist);
+ }
+
+}//namespace gradient_paint
+}//namespace gtx
+}//namespace glm
diff --git a/src/glm/gtx/handed_coordinate_space.hpp b/src/glm/gtx/handed_coordinate_space.hpp
new file mode 100644
index 0000000..05d5f89
--- /dev/null
+++ b/src/glm/gtx/handed_coordinate_space.hpp
@@ -0,0 +1,55 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2005-12-21
+// Updated : 2009-02-19
+// Licence : This source is under MIT License
+// File : glm/gtx/handed_coordinate_space.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_gtx_handed_coordinate_space
+#define glm_gtx_handed_coordinate_space
+
+// Dependency:
+#include "../glm.hpp"
+
+#if(defined(GLM_MESSAGES) && !defined(glm_ext))
+# pragma message("GLM: GLM_GTX_handed_coordinate_space extension included")
+#endif
+
+namespace glm{
+namespace gtx{
+namespace handed_coordinate_space ///< GLM_GTX_handed_coordinate_space extension: To know if a set of three basis vectors defines a right or left-handed coordinate system.
+{
+ /// \addtogroup gtx_handed_coordinate_space
+ /// @{
+
+ //! Return if a trihedron right handed or not.
+ //! From GLM_GTX_handed_coordinate_space extension.
+ template <typename T>
+ bool rightHanded(
+ detail::tvec3<T> const & tangent,
+ detail::tvec3<T> const & binormal,
+ detail::tvec3<T> const & normal);
+
+ //! Return if a trihedron left handed or not.
+ //! From GLM_GTX_handed_coordinate_space extension.
+ template <typename T>
+ bool leftHanded(
+ detail::tvec3<T> const & tangent,
+ detail::tvec3<T> const & binormal,
+ detail::tvec3<T> const & normal);
+
+ /// @}
+}// namespace handed_coordinate_space
+}// namespace gtx
+}// namespace glm
+
+#include "handed_coordinate_space.inl"
+
+namespace glm{using namespace gtx::handed_coordinate_space;}
+
+#endif//glm_gtx_handed_coordinate_space
diff --git a/src/glm/gtx/handed_coordinate_space.inl b/src/glm/gtx/handed_coordinate_space.inl
new file mode 100644
index 0000000..fb7bae7
--- /dev/null
+++ b/src/glm/gtx/handed_coordinate_space.inl
@@ -0,0 +1,34 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2005-12-21
+// Updated : 2009-02-19
+// Licence : This source is under MIT License
+// File : glm/gtx/handed_coordinate_space.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm{
+namespace gtx{
+namespace handed_coordinate_space
+{
+ template <typename T>
+ GLM_FUNC_QUALIFIER bool rightHanded(
+ detail::tvec3<T> const & tangent,
+ detail::tvec3<T> const & binormal,
+ detail::tvec3<T> const & normal)
+ {
+ return dot(cross(normal, tangent), binormal) > T(0);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER bool leftHanded(
+ detail::tvec3<T> const & tangent,
+ detail::tvec3<T> const & binormal,
+ detail::tvec3<T> const & normal)
+ {
+ return dot(cross(normal, tangent), binormal) < T(0);
+ }
+
+}//namespace handed_coordinate_space
+}//namespace gtx
+}//namespace glm
diff --git a/src/glm/gtx/inertia.hpp b/src/glm/gtx/inertia.hpp
new file mode 100644
index 0000000..602de82
--- /dev/null
+++ b/src/glm/gtx/inertia.hpp
@@ -0,0 +1,95 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2006-04-21
+// Updated : 2006-11-13
+// Licence : This source is under MIT License
+// File : glm/gtx/inertia.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_gtx_inertia
+#define glm_gtx_inertia
+
+// Dependency:
+#include "../glm.hpp"
+
+#if(defined(GLM_MESSAGES) && !defined(glm_ext))
+# pragma message("GLM: GLM_GTX_inertia extension included")
+#endif
+
+namespace glm{
+namespace gtx{
+namespace inertia ///< GLM_GTX_inertia extension: Create inertia matrices
+{
+ /// \addtogroup gtx_inertia
+ /// @{
+
+ //! Build an inertia matrix for a box.
+ //! From GLM_GTX_inertia extension.
+ template <typename T>
+ detail::tmat3x3<T> boxInertia3(
+ const T Mass,
+ const detail::tvec3<T>& Scale);
+
+ //! Build an inertia matrix for a box.
+ //! From GLM_GTX_inertia extension.
+ template <typename T>
+ detail::tmat4x4<T> boxInertia4(
+ const T Mass,
+ const detail::tvec3<T>& Scale);
+
+ //! Build an inertia matrix for a disk.
+ //! From GLM_GTX_inertia extension.
+ template <typename T>
+ detail::tmat3x3<T> diskInertia3(
+ const T Mass,
+ const T Radius);
+
+ //! Build an inertia matrix for a disk.
+ //! From GLM_GTX_inertia extension.
+ template <typename T>
+ detail::tmat4x4<T> diskInertia4(
+ const T Mass,
+ const T Radius);
+
+ //! Build an inertia matrix for a ball.
+ //! From GLM_GTX_inertia extension.
+ template <typename T>
+ detail::tmat3x3<T> ballInertia3(
+ const T Mass,
+ const T Radius);
+
+ //! Build an inertia matrix for a ball.
+ //! From GLM_GTX_inertia extension.
+ template <typename T>
+ detail::tmat4x4<T> ballInertia4(
+ const T Mass,
+ const T Radius);
+
+ //! Build an inertia matrix for a sphere.
+ //! From GLM_GTX_inertia extension.
+ template <typename T>
+ detail::tmat3x3<T> sphereInertia3(
+ const T Mass,
+ const T Radius);
+
+ //! Build an inertia matrix for a sphere.
+ //! From GLM_GTX_inertia extension.
+ template <typename T>
+ detail::tmat4x4<T> sphereInertia4(
+ const T Mass,
+ const T Radius);
+
+ /// @}
+}// namespace inertia
+}// namespace gtx
+}// namespace glm
+
+#include "inertia.inl"
+
+namespace glm{using namespace gtx::inertia;}
+
+#endif//glm_gtx_inertia
diff --git a/src/glm/gtx/inertia.inl b/src/glm/gtx/inertia.inl
new file mode 100644
index 0000000..6e4be3d
--- /dev/null
+++ b/src/glm/gtx/inertia.inl
@@ -0,0 +1,103 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2006-04-21
+// Updated : 2006-12-06
+// Licence : This source is under MIT License
+// File : glm/gtx/inertia.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm{
+namespace gtx{
+namespace inertia{
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tmat3x3<T> boxInertia3(
+ const T Mass,
+ const detail::tvec3<T>& Scale)
+ {
+ detail::tmat3x3<T> Result(T(1));
+ Result[0][0] = (Scale.y * Scale.y + Scale.z * Scale.z) * Mass / T(12);
+ Result[1][1] = (Scale.x * Scale.x + Scale.z * Scale.z) * Mass / T(12);
+ Result[2][2] = (Scale.x * Scale.x + Scale.y * Scale.y) * Mass / T(12);
+ return Result;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tmat4x4<T> boxInertia4(
+ const T Mass,
+ const detail::tvec3<T>& Scale)
+ {
+ detail::tmat4x4<T> Result(T(1));
+ Result[0][0] = (Scale.y * Scale.y + Scale.z * Scale.z) * Mass / T(12);
+ Result[1][1] = (Scale.x * Scale.x + Scale.z * Scale.z) * Mass / T(12);
+ Result[2][2] = (Scale.x * Scale.x + Scale.y * Scale.y) * Mass / T(12);
+ return Result;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tmat3x3<T> diskInertia3(
+ const T Mass,
+ const T Radius)
+ {
+ T a = Mass * Radius * Radius / T(2);
+ detail::tmat3x3<T> Result(a);
+ Result[2][2] *= T(2);
+ return Result;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tmat4x4<T> diskInertia4(
+ const T Mass,
+ const T Radius)
+ {
+ T a = Mass * Radius * Radius / T(2);
+ detail::tmat4x4<T> Result(a);
+ Result[2][2] *= T(2);
+ Result[3][3] = T(1);
+ return Result;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tmat3x3<T> ballInertia3(
+ const T Mass,
+ const T Radius)
+ {
+ T a = T(2) * Mass * Radius * Radius / T(5);
+ return detail::tmat3x3<T>(a);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tmat4x4<T> ballInertia4(
+ const T Mass,
+ const T Radius)
+ {
+ T a = T(2) * Mass * Radius * Radius / T(5);
+ detail::tmat4x4<T> Result(a);
+ Result[3][3] = T(1);
+ return Result;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tmat3x3<T> sphereInertia3(
+ const T Mass,
+ const T Radius)
+ {
+ T a = T(2) * Mass * Radius * Radius / T(3);
+ return detail::tmat3x3<T>(a);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tmat4x4<T> sphereInertia4(
+ const T Mass,
+ const T Radius)
+ {
+ T a = T(2) * Mass * Radius * Radius / T(3);
+ detail::tmat4x4<T> Result(a);
+ Result[3][3] = T(1);
+ return Result;
+ }
+
+}//namespace inertia
+}//namespace gtx
+}//namespace glm
diff --git a/src/glm/gtx/int_10_10_10_2.hpp b/src/glm/gtx/int_10_10_10_2.hpp
new file mode 100644
index 0000000..8fa697b
--- /dev/null
+++ b/src/glm/gtx/int_10_10_10_2.hpp
@@ -0,0 +1,47 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2010-07-07
+// Updated : 2010-07-07
+// Licence : This source is under MIT License
+// File : glm/gtx/int_10_10_10_2.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_gtx_int_10_10_10_2
+#define glm_gtx_int_10_10_10_2
+
+// Dependency:
+#include "../glm.hpp"
+#include "../gtx/raw_data.hpp"
+
+#if(defined(GLM_MESSAGES) && !defined(glm_ext))
+# pragma message("GLM: GLM_GTX_int_10_10_10_2 extension included")
+#endif
+
+namespace glm{
+namespace gtx{
+namespace int_10_10_10_2 ///< GLM_GTX_int_10_10_10_2 extension: Add support for integer for core functions
+{
+ using namespace gtx::raw_data;
+
+ /// \addtogroup gtx_int_10_10_10_2
+ ///@{
+
+ //! From GLM_GTX_int_10_10_10_2 extension.
+ //! Cast a vec4 to an u_10_10_10_2.
+ dword uint10_10_10_2_cast(glm::vec4 const & v);
+
+ ///@}
+
+}//namespace integer
+}//namespace gtx
+}//namespace glm
+
+#include "int_10_10_10_2.inl"
+
+namespace glm{using namespace gtx::int_10_10_10_2;}
+
+#endif//glm_gtx_int_10_10_10_2
diff --git a/src/glm/gtx/int_10_10_10_2.inl b/src/glm/gtx/int_10_10_10_2.inl
new file mode 100644
index 0000000..68efc55
--- /dev/null
+++ b/src/glm/gtx/int_10_10_10_2.inl
@@ -0,0 +1,21 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2010-07-07
+// Updated : 2010-07-07
+// Licence : This source is under MIT License
+// File : glm/gtx/int_10_10_10_2.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm{
+namespace gtx{
+namespace int_10_10_10_2
+{
+ GLM_FUNC_QUALIFIER dword uint10_10_10_2_cast(glm::vec4 const & v)
+ {
+ return dword(uint(v.x * 2047.f) << 0 | uint(v.y * 2047.f) << 10 | uint(v.z * 2047.f) << 20 | uint(v.w * 3.f) << 30);
+ }
+
+}//namespace int_10_10_10_2
+}//namespace gtx
+}//namespace glm
diff --git a/src/glm/gtx/integer.hpp b/src/glm/gtx/integer.hpp
new file mode 100644
index 0000000..fe05b8f
--- /dev/null
+++ b/src/glm/gtx/integer.hpp
@@ -0,0 +1,56 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2005-12-24
+// Updated : 2006-11-14
+// Licence : This source is under MIT License
+// File : glm/gtx/integer.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_gtx_integer
+#define glm_gtx_integer
+
+// Dependency:
+#include "../glm.hpp"
+
+#if(defined(GLM_MESSAGES) && !defined(glm_ext))
+# pragma message("GLM: GLM_GTX_integer extension included")
+#endif
+
+namespace glm{
+namespace gtx{
+namespace integer ///< GLM_GTX_integer extension: Add support for integer for core functions
+{
+ /// \addtogroup gtx_integer
+ /// @{
+
+ //! Returns x raised to the y power.
+ //! From GLM_GTX_integer extension.
+ int pow(int x, int y);
+
+ //! Returns the positive square root of x.
+ //! From GLM_GTX_integer extension.
+ int sqrt(int x);
+
+ //! Modulus. Returns x - y * floor(x / y) for each component in x using the floating point value y.
+ //! From GLM_GTX_integer extension.
+ int mod(int x, int y);
+
+ //! Return the factorial value of a number (!12 max, integer only)
+ //! From GLM_GTX_integer extension.
+ template <typename genType>
+ genType factorial(genType const & x);
+
+ /// @}
+}//namespace integer
+}//namespace gtx
+}//namespace glm
+
+#include "integer.inl"
+
+namespace glm{using namespace gtx::integer;}
+
+#endif//glm_gtx_integer
diff --git a/src/glm/gtx/integer.inl b/src/glm/gtx/integer.inl
new file mode 100644
index 0000000..7bf5011
--- /dev/null
+++ b/src/glm/gtx/integer.inl
@@ -0,0 +1,91 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2005-12-24
+// Updated : 2006-12-06
+// Licence : This source is under MIT License
+// File : glm/gtx/integer.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm{
+namespace gtx{
+namespace integer
+{
+ // pow
+ GLM_FUNC_QUALIFIER int pow(int x, int y)
+ {
+ if(y == 0)
+ return 1;
+ int result = x;
+ for(int i = 1; i < y; ++i)
+ result *= x;
+ return result;
+ }
+
+ // sqrt: From Christopher J. Musial, An integer square root, Graphics Gems, 1990, page 387
+ GLM_FUNC_QUALIFIER int sqrt(int x)
+ {
+ if(x <= 1) return x;
+
+ int NextTrial = x >> 1;
+ int CurrentAnswer;
+
+ do
+ {
+ CurrentAnswer = NextTrial;
+ NextTrial = (NextTrial + x / NextTrial) >> 1;
+ } while(NextTrial < CurrentAnswer);
+
+ return CurrentAnswer;
+ }
+
+ // mod
+ GLM_FUNC_QUALIFIER int mod(int x, int y)
+ {
+ return x - y * (x / y);
+ }
+
+ // factorial (!12 max, integer only)
+ template <typename genType>
+ GLM_FUNC_QUALIFIER genType factorial(genType const & x)
+ {
+ genType Temp = x;
+ genType Result;
+ for(Result = 1; Temp > 1; --Temp)
+ Result *= Temp;
+ return Result;
+ }
+
+ template <typename valType>
+ GLM_FUNC_QUALIFIER detail::tvec2<valType> factorial(
+ detail::tvec2<valType> const & x)
+ {
+ return detail::tvec2<valType>(
+ factorial(x.x),
+ factorial(x.y));
+ }
+
+ template <typename valType>
+ GLM_FUNC_QUALIFIER detail::tvec3<valType> factorial(
+ detail::tvec3<valType> const & x)
+ {
+ return detail::tvec3<valType>(
+ factorial(x.x),
+ factorial(x.y),
+ factorial(x.z));
+ }
+
+ template <typename valType>
+ GLM_FUNC_QUALIFIER detail::tvec4<valType> factorial(
+ detail::tvec4<valType> const & x)
+ {
+ return detail::tvec4<valType>(
+ factorial(x.x),
+ factorial(x.y),
+ factorial(x.z),
+ factorial(x.w));
+ }
+
+}//namespace integer
+}//namespace gtx
+}//namespace glm
diff --git a/src/glm/gtx/intersect.hpp b/src/glm/gtx/intersect.hpp
new file mode 100644
index 0000000..df5e083
--- /dev/null
+++ b/src/glm/gtx/intersect.hpp
@@ -0,0 +1,73 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2007-04-03
+// Updated : 2009-01-20
+// Licence : This source is under MIT License
+// File : glm/gtx/intersect.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+// - GLM_GTX_closest_point
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_gtx_intersect
+#define glm_gtx_intersect
+
+// Dependency:
+#include "../glm.hpp"
+#include "../gtx/closest_point.hpp"
+
+#if(defined(GLM_MESSAGES) && !defined(glm_ext))
+# pragma message("GLM: GLM_GTX_closest_point extension included")
+#endif
+
+namespace glm{
+namespace gtx{
+namespace intersect ///< GLM_GTX_intersect extension: Add intersection functions
+{
+ /// \addtogroup gtx_intersect
+ /// @{
+
+ //! Compute the intersection of a ray and a triangle.
+ //! From GLM_GTX_intersect extension.
+ template <typename genType>
+ bool intersectRayTriangle(
+ genType const & orig, genType const & dir,
+ genType const & vert0, genType const & vert1, genType const & vert2,
+ genType & baryPosition);
+
+ //! Compute the intersection of a line and a triangle.
+ //! From GLM_GTX_intersect extension.
+ template <typename genType>
+ bool intersectLineTriangle(
+ genType const & orig, genType const & dir,
+ genType const & vert0, genType const & vert1, genType const & vert2,
+ genType & position);
+
+ //! Compute the intersection of a ray and a sphere.
+ //! From GLM_GTX_intersect extension.
+ template <typename genType>
+ bool intersectRaySphere(
+ genType const & orig, genType const & dir,
+ genType const & center, typename genType::value_type radius,
+ genType & position, genType & normal);
+
+ //! Compute the intersection of a line and a sphere.
+ //! From GLM_GTX_intersect extension
+ template <typename genType>
+ bool intersectLineSphere(
+ genType const & point0, genType const & point1,
+ genType const & center, typename genType::value_type radius,
+ genType & position, genType & normal);
+
+ /// @}
+}//namespace intersect
+}//namespace gtx
+}//namespace glm
+
+#include "intersect.inl"
+
+namespace glm{using namespace gtx::intersect;}
+
+#endif//glm_gtx_intersect
diff --git a/src/glm/gtx/intersect.inl b/src/glm/gtx/intersect.inl
new file mode 100644
index 0000000..b9f318a
--- /dev/null
+++ b/src/glm/gtx/intersect.inl
@@ -0,0 +1,201 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2007-04-03
+// Updated : 2009-01-20
+// Licence : This source is under MIT licence
+// File : glm/gtx/intersect.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#include <cfloat>
+#include <limits>
+
+namespace glm{
+namespace gtx{
+namespace intersect{
+
+template <typename genType>
+GLM_FUNC_QUALIFIER bool intersectRayTriangle
+(
+ genType const & orig, genType const & dir,
+ genType const & v0, genType const & v1, genType const & v2,
+ genType & baryPosition
+)
+{
+ genType e1 = v1 - v0;
+ genType e2 = v2 - v0;
+
+ genType p = glm::cross(dir, e2);
+
+ typename genType::value_type a = glm::dot(e1, p);
+
+ typename genType::value_type Epsilon = std::numeric_limits<typename genType::value_type>::epsilon();
+ if(a < Epsilon)
+ return false;
+
+ typename genType::value_type f = typename genType::value_type(1.0f) / a;
+
+ genType s = orig - v0;
+ baryPosition.x = f * glm::dot(s, p);
+ if(baryPosition.x < typename genType::value_type(0.0f))
+ return false;
+ if(baryPosition.x > typename genType::value_type(1.0f))
+ return false;
+
+ genType q = glm::cross(s, e1);
+ baryPosition.y = f * glm::dot(dir, q);
+ if(baryPosition.y < typename genType::value_type(0.0f))
+ return false;
+ if(baryPosition.y + baryPosition.x > typename genType::value_type(1.0f))
+ return false;
+
+ baryPosition.z = f * glm::dot(e2, q);
+
+ return baryPosition.z >= typename genType::value_type(0.0f);
+}
+
+//template <typename genType>
+//GLM_FUNC_QUALIFIER bool intersectRayTriangle
+//(
+// genType const & orig, genType const & dir,
+// genType const & vert0, genType const & vert1, genType const & vert2,
+// genType & position
+//)
+//{
+// typename genType::value_type Epsilon = std::numeric_limits<typename genType::value_type>::epsilon();
+//
+// genType edge1 = vert1 - vert0;
+// genType edge2 = vert2 - vert0;
+//
+// genType pvec = cross(dir, edge2);
+//
+// float det = dot(edge1, pvec);
+// if(det < Epsilon)
+// return false;
+//
+// genType tvec = orig - vert0;
+//
+// position.y = dot(tvec, pvec);
+// if (position.y < typename genType::value_type(0) || position.y > det)
+// return typename genType::value_type(0);
+//
+// genType qvec = cross(tvec, edge1);
+//
+// position.z = dot(dir, qvec);
+// if (position.z < typename genType::value_type(0) || position.y + position.z > det)
+// return typename genType::value_type(0);
+//
+// position.x = dot(edge2, qvec);
+// position *= typename genType::value_type(1) / det;
+//
+// return typename genType::value_type(1);
+//}
+
+template <typename genType>
+GLM_FUNC_QUALIFIER bool intersectLineTriangle
+(
+ genType const & orig, genType const & dir,
+ genType const & vert0, genType const & vert1, genType const & vert2,
+ genType & position
+)
+{
+ typename genType::value_type Epsilon = std::numeric_limits<typename genType::value_type>::epsilon();
+
+ genType edge1 = vert1 - vert0;
+ genType edge2 = vert2 - vert0;
+
+ genType pvec = cross(dir, edge2);
+
+ float det = dot(edge1, pvec);
+
+ if (det > -Epsilon && det < Epsilon)
+ return false;
+ float inv_det = typename genType::value_type(1) / det;
+
+ genType tvec = orig - vert0;
+
+ position.y = dot(tvec, pvec) * inv_det;
+ if (position.y < typename genType::value_type(0) || position.y > typename genType::value_type(1))
+ return false;
+
+ genType qvec = cross(tvec, edge1);
+
+ position.z = dot(dir, qvec) * inv_det;
+ if (position.z < typename genType::value_type(0) || position.y + position.z > typename genType::value_type(1))
+ return false;
+
+ position.x = dot(edge2, qvec) * inv_det;
+
+ return true;
+}
+
+template <typename genType>
+GLM_FUNC_QUALIFIER bool intersectRaySphere
+(
+ genType const & rayStarting, genType const & rayDirection,
+ genType const & sphereCenter, typename genType::value_type sphereRadius,
+ genType & position, genType & normal
+)
+{
+ typename genType::value_type Epsilon = std::numeric_limits<typename genType::value_type>::epsilon();
+
+ typename genType::value_type a = dot(rayDirection, rayDirection);
+ typename genType::value_type b = typename genType::value_type(2) * dot(rayStarting, rayDirection);
+ typename genType::value_type c = dot(rayStarting, rayStarting) - sphereRadius * sphereRadius;
+ typename genType::value_type d = b * b - typename genType::value_type(4) * a * c;
+ typename genType::value_type e = sqrt(d);
+ typename genType::value_type x1 = (-b - e) / (typename genType::value_type(2) * a);
+ typename genType::value_type x2 = (-b + e) / (typename genType::value_type(2) * a);
+
+ if(x1 > Epsilon)
+ {
+ position = rayStarting + rayDirection * sphereRadius;
+ normal = (position - sphereCenter) / sphereRadius;
+ return true;
+ }
+ else if(x2 > Epsilon)
+ {
+ position = rayStarting + rayDirection * sphereRadius;
+ normal = (position - sphereCenter) / sphereRadius;
+ return true;
+ }
+ return false;
+}
+
+template <typename genType>
+GLM_FUNC_QUALIFIER bool intersectLineSphere
+(
+ genType const & point0, genType const & point1,
+ genType const & center, typename genType::value_type radius,
+ genType & position, genType & normal
+)
+{
+ typename genType::value_type Epsilon = std::numeric_limits<typename genType::value_type>::epsilon();
+
+ genType dir = point1 - point0;
+ typename genType::value_type a = dot(dir, dir);
+ typename genType::value_type b = typename genType::value_type(2) * dot(center, dir);
+ typename genType::value_type c = dot(center, center) - radius * radius;
+ typename genType::value_type d = b * b - typename genType::value_type(4) * a * c;
+ typename genType::value_type e = sqrt(d);
+ typename genType::value_type x1 = (-b - e) / (typename genType::value_type(2) * a);
+ typename genType::value_type x2 = (-b + e) / (typename genType::value_type(2) * a);
+
+ if(x1 > Epsilon)
+ {
+ position = center + dir * radius;
+ normal = (position - center) / radius;
+ return true;
+ }
+ else if(x2 > Epsilon)
+ {
+ position = center + dir * radius;
+ normal = (position - center) / radius;
+ return true;
+ }
+ return false;
+}
+
+}//namespace intersect
+}//namespace gtx
+}//namespace glm
diff --git a/src/glm/gtx/log_base.hpp b/src/glm/gtx/log_base.hpp
new file mode 100644
index 0000000..d30d822
--- /dev/null
+++ b/src/glm/gtx/log_base.hpp
@@ -0,0 +1,47 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2008-10-24
+// Updated : 2008-10-24
+// Licence : This source is under MIT License
+// File : glm/gtx/log_base.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_gtx_log_base
+#define glm_gtx_log_base
+
+// Dependency:
+#include "../glm.hpp"
+
+#if(defined(GLM_MESSAGES) && !defined(glm_ext))
+# pragma message("GLM: GLM_GTX_log_base extension included")
+#endif
+
+namespace glm{
+namespace gtx{
+namespace log_base ///< GLM_GTX_log_base extension: Logarithm for any base. base can be a vector or a scalar.
+{
+ /// \addtogroup gtx_log_base
+ /// @{
+
+ //! Logarithm for any base.
+ //! From GLM_GTX_log_base.
+ template <typename genType>
+ genType log(
+ genType const & x,
+ genType const & base);
+
+ /// @}
+
+}//namespace extend
+}//namespace gtx
+}//namespace glm
+
+#include "log_base.inl"
+
+namespace glm{using namespace gtx::log_base;}
+
+#endif//glm_gtx_log_base
diff --git a/src/glm/gtx/log_base.inl b/src/glm/gtx/log_base.inl
new file mode 100644
index 0000000..b76d2f3
--- /dev/null
+++ b/src/glm/gtx/log_base.inl
@@ -0,0 +1,92 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2008-10-24
+// Updated : 2008-10-24
+// Licence : This source is under MIT License
+// File : glm/gtx/log_base.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm{
+namespace gtx{
+namespace log_base{
+
+template <typename genType>
+GLM_FUNC_QUALIFIER genType log(
+ genType const & x,
+ genType const & base)
+{
+ assert(x != genType(0));
+
+ return glm::log(x) / glm::log(base);
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec2<valType> log(
+ detail::tvec2<valType> const & v,
+ valType const & base)
+{
+ return detail::tvec2<valType>(
+ log(v.x, base),
+ log(v.y, base));
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec3<valType> log(
+ detail::tvec3<valType> const & v,
+ valType const & base)
+{
+ return detail::tvec3<valType>(
+ log(v.x, base),
+ log(v.y, base),
+ log(v.z, base));
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec4<valType> log(
+ detail::tvec4<valType> const & v,
+ valType const & base)
+{
+ return detail::tvec4<valType>(
+ log(v.x, base),
+ log(v.y, base),
+ log(v.z, base),
+ log(v.w, base));
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec2<valType> log(
+ detail::tvec2<valType> const & v,
+ detail::tvec2<valType> const & base)
+{
+ return detail::tvec2<valType>(
+ log(v.x, base.x),
+ log(v.y, base.y));
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec3<valType> log(
+ detail::tvec3<valType> const & v,
+ detail::tvec3<valType> const & base)
+{
+ return detail::tvec3<valType>(
+ log(v.x, base.x),
+ log(v.y, base.y),
+ log(v.z, base.z));
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec4<valType> log(
+ detail::tvec4<valType> const & v,
+ detail::tvec4<valType> const & base)
+{
+ return detail::tvec4<valType>(
+ log(v.x, base.x),
+ log(v.y, base.y),
+ log(v.z, base.z),
+ log(v.w, base.w));
+}
+
+}//namespace log_base
+}//namespace gtx
+}//namespace glm
diff --git a/src/glm/gtx/matrix_cross_product.hpp b/src/glm/gtx/matrix_cross_product.hpp
new file mode 100644
index 0000000..1039bdb
--- /dev/null
+++ b/src/glm/gtx/matrix_cross_product.hpp
@@ -0,0 +1,51 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2005-12-21
+// Updated : 2006-11-13
+// Licence : This source is under MIT License
+// File : glm/gtx/matrix_cross_product.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_gtx_matrix_cross_product
+#define glm_gtx_matrix_cross_product
+
+// Dependency:
+#include "../glm.hpp"
+
+#if(defined(GLM_MESSAGES) && !defined(glm_ext))
+# pragma message("GLM: GLM_GTX_matrix_cross_product extension included")
+#endif
+
+namespace glm{
+namespace gtx{
+namespace matrix_cross_product ///< GLM_GTX_matrix_cross_product: Build cross product matrices
+{
+ /// \addtogroup gtx_matrix_cross_product
+ /// @{
+
+ //! Build a cross product matrix.
+ //! From GLM_GTX_matrix_cross_product extension.
+ template <typename T>
+ detail::tmat3x3<T> matrixCross3(
+ detail::tvec3<T> const & x);
+
+ //! Build a cross product matrix.
+ //! From GLM_GTX_matrix_cross_product extension.
+ template <typename T>
+ detail::tmat4x4<T> matrixCross4(
+ detail::tvec3<T> const & x);
+
+ /// @}
+}//namespace matrix_cross_product
+}//namespace gtx
+}//namespace glm
+
+#include "matrix_cross_product.inl"
+
+namespace glm{using namespace gtx::matrix_cross_product;}
+
+#endif//glm_gtx_matrix_cross_product
diff --git a/src/glm/gtx/matrix_cross_product.inl b/src/glm/gtx/matrix_cross_product.inl
new file mode 100644
index 0000000..174b968
--- /dev/null
+++ b/src/glm/gtx/matrix_cross_product.inl
@@ -0,0 +1,44 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2005-12-21
+// Updated : 2005-12-21
+// Licence : This source is under MIT License
+// File : glm/gtx/matrix_cross_product.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm{
+namespace gtx{
+namespace matrix_cross_product
+{
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tmat3x3<T> matrixCross3(
+ detail::tvec3<T> const & x)
+ {
+ detail::tmat3x3<T> Result(T(0));
+ Result[0][1] = x.z;
+ Result[1][0] = -x.z;
+ Result[0][2] = -x.y;
+ Result[2][0] = x.y;
+ Result[1][2] = x.x;
+ Result[2][1] = -x.x;
+ return Result;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tmat4x4<T> matrixCross4(
+ detail::tvec3<T> const & x)
+ {
+ detail::tmat4x4<T> Result(T(0));
+ Result[0][1] = x.z;
+ Result[1][0] = -x.z;
+ Result[0][2] = -x.y;
+ Result[2][0] = x.y;
+ Result[1][2] = x.x;
+ Result[2][1] = -x.x;
+ return Result;
+ }
+
+}//namespace matrix_cross_product
+}//namespace gtx
+}//namespace glm
diff --git a/src/glm/gtx/matrix_interpolation.hpp b/src/glm/gtx/matrix_interpolation.hpp
new file mode 100644
index 0000000..bf7910c
--- /dev/null
+++ b/src/glm/gtx/matrix_interpolation.hpp
@@ -0,0 +1,66 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2011-03-05
+// Updated : 2011-03-05
+// Licence : This source is under MIT License
+// File : glm/gtx/matrix_interpolation.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+// - GLM_GTX_matric_interpolation
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// This extension has been written by Ghenadii Ursachi (the.asteroth@gmail.com)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_gtx_matrix_interpolation
+#define glm_gtx_matrix_interpolation
+
+// Dependency:
+//#include "../glm.hpp"
+
+#if(defined(GLM_MESSAGES) && !defined(glm_ext))
+# pragma message("GLM: GLM_GTX_matrix_interpolation extension included")
+#endif
+
+namespace glm{
+namespace gtx{
+namespace matrix_interpolation ///< GLM_GTX_matrix_interpolation extension: Add transformation matrices
+{
+ /// \addtogroup gtx_matrix_interpolation
+ /// @{
+
+ //! Get the axis and angle of the rotation from a matrix.
+ //! From GLM_GTX_matrix_interpolation extension.
+ template <typename T>
+ void axisAngle(
+ detail::tmat4x4<T> const & mat,
+ detail::tvec3<T> & axis,
+ T & angle);
+
+ //! Build a matrix from axis and angle.
+ //! From GLM_GTX_matrix_interpolation extension.
+ template <typename T>
+ detail::tmat4x4<T> axisAngleMatrix(
+ detail::tvec3<T> const & axis,
+ T const angle);
+
+ //! Build a interpolation of 4 * 4 matrixes.
+ //! From GLM_GTX_matrix_interpolation extension.
+ //! Warning! works only with rotation and/or translation matrixes, scale will generate unexpected results.
+ template <typename T>
+ detail::tmat4x4<T> interpolate(
+ detail::tmat4x4<T> const & m1,
+ detail::tmat4x4<T> const & m2,
+ T const delta);
+
+ /// @}
+}//namespace matrix_interpolation
+}//namespace gtx
+}//namespace glm
+
+#include "matrix_interpolation.inl"
+
+namespace glm{using namespace gtx::matrix_interpolation;}
+
+#endif//glm_gtx_transform
diff --git a/src/glm/gtx/matrix_interpolation.inl b/src/glm/gtx/matrix_interpolation.inl
new file mode 100644
index 0000000..a6a237b
--- /dev/null
+++ b/src/glm/gtx/matrix_interpolation.inl
@@ -0,0 +1,117 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2011-03-05
+// Updated : 2011-03-05
+// Licence : This source is under MIT License
+// File : glm/gtx/matrix_interpolation.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm{
+namespace gtx{
+namespace matrix_interpolation
+{
+ template <typename T>
+ GLM_FUNC_QUALIFIER void axisAngle(
+ detail::tmat4x4<T> const & mat,
+ detail::tvec3<T> & axis,
+ T & angle)
+ {
+ T epsilon = (T)0.01;
+ T epsilon2 = (T)0.1;
+
+ if ((fabs(mat[1][0] - mat[0][1]) < epsilon) && (fabs(mat[2][0] - mat[0][2]) < epsilon) && (fabs(mat[2][1] - mat[1][2]) < epsilon)) {
+ if ((fabs(mat[1][0] + mat[0][1]) < epsilon2) && (fabs(mat[2][0] + mat[0][2]) < epsilon2) && (fabs(mat[2][1] + mat[1][2]) < epsilon2) && (fabs(mat[0][0] + mat[1][1] + mat[2][2] - (T)3.0) < epsilon2)) {
+ angle = (T)0.0;
+ axis.x = (T)1.0;
+ axis.y = (T)0.0;
+ axis.z = (T)0.0;
+ return;
+ }
+ angle = M_1_PI;
+ T xx = (mat[0][0] + (T)1.0) / (T)2.0;
+ T yy = (mat[1][1] + (T)1.0) / (T)2.0;
+ T zz = (mat[2][2] + (T)1.0) / (T)2.0;
+ T xy = (mat[1][0] + mat[0][1]) / (T)4.0;
+ T xz = (mat[2][0] + mat[0][2]) / (T)4.0;
+ T yz = (mat[2][1] + mat[1][2]) / (T)4.0;
+ if ((xx > yy) && (xx > zz)) {
+ if (xx < epsilon) {
+ axis.x = (T)0.0;
+ axis.y = (T)0.7071;
+ axis.z = (T)0.7071;
+ } else {
+ axis.x = sqrt(xx);
+ axis.y = xy / axis.x;
+ axis.z = xz / axis.x;
+ }
+ } else if (yy > zz) {
+ if (yy < epsilon) {
+ axis.x = (T)0.7071;
+ axis.y = (T)0.0;
+ axis.z = (T)0.7071;
+ } else {
+ axis.y = sqrt(yy);
+ axis.x = xy / axis.y;
+ axis.z = yz / axis.y;
+ }
+ } else {
+ if (zz < epsilon) {
+ axis.x = (T)0.7071;
+ axis.y = (T)0.7071;
+ axis.z = (T)0.0;
+ } else {
+ axis.z = sqrt(zz);
+ axis.x = xz / axis.z;
+ axis.y = yz / axis.z;
+ }
+ }
+ return;
+ }
+ T s = sqrt((mat[2][1] - mat[1][2]) * (mat[2][1] - mat[1][2]) + (mat[2][0] - mat[0][2]) * (mat[2][0] - mat[0][2]) + (mat[1][0] - mat[0][1]) * (mat[1][0] - mat[0][1]));
+ if (glm::abs(s) < T(0.001))
+ s = (T)1.0;
+ angle = acos((mat[0][0] + mat[1][1] + mat[2][2] - (T)1.0) / (T)2.0);
+ axis.x = (mat[1][2] - mat[2][1]) / s;
+ axis.y = (mat[2][0] - mat[0][2]) / s;
+ axis.z = (mat[0][1] - mat[1][0]) / s;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tmat4x4<T> axisAngleMatrix(
+ detail::tvec3<T> const & axis,
+ T const angle)
+ {
+ T c = cos(angle);
+ T s = sin(angle);
+ T t = T(1) - c;
+ detail::tvec3<T> n = normalize(axis);
+
+ return detail::tmat4x4<T>(
+ t * n.x * n.x + c, t * n.x * n.y + n.z * s, t * n.x * n.z - n.y * s, T(0),
+ t * n.x * n.y - n.z * s, t * n.y * n.y + c, t * n.y * n.z + n.x * s, T(0),
+ t * n.x * n.z + n.y * s, t * n.y * n.z - n.x * s, t * n.z * n.z + c, T(0),
+ T(0), T(0), T(0), T(1)
+ );
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tmat4x4<T> interpolate(
+ detail::tmat4x4<T> const & m1,
+ detail::tmat4x4<T> const & m2,
+ T const delta)
+ {
+ detail::tmat4x4<T> dltRotation = m2 * transpose(m1);
+ detail::tvec3<T> dltAxis;
+ T dltAngle;
+ axisAngle(dltRotation, dltAxis, dltAngle);
+ detail::tmat4x4<T> out = axisAngleMatrix(dltAxis, dltAngle * delta) * rotationMatrix(m1);
+ out[3][0] = m1[3][0] + delta * (m2[3][0] - m1[3][0]);
+ out[3][1] = m1[3][1] + delta * (m2[3][1] - m1[3][1]);
+ out[3][2] = m1[3][2] + delta * (m2[3][2] - m1[3][2]);
+ return out;
+ }
+
+}//namespace transform
+}//namespace gtx
+}//namespace glm
diff --git a/src/glm/gtx/matrix_major_storage.hpp b/src/glm/gtx/matrix_major_storage.hpp
new file mode 100644
index 0000000..73db97f
--- /dev/null
+++ b/src/glm/gtx/matrix_major_storage.hpp
@@ -0,0 +1,123 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2006-04-19
+// Updated : 2009-02-19
+// Licence : This source is under MIT License
+// File : glm/gtx/matrix_major_storage.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_gtx_matrix_major_storage
+#define glm_gtx_matrix_major_storage
+
+// Dependency:
+#include "../glm.hpp"
+
+#if(defined(GLM_MESSAGES) && !defined(glm_ext))
+# pragma message("GLM: GLM_GTX_matrix_major_storage extension included")
+#endif
+
+namespace glm{
+namespace gtx{
+namespace matrix_major_storage ///< GLM_GTX_matrix_major_storage: Build matrices with specific matrix order, row or column
+{
+ /// \addtogroup gtx_matrix_major_storage
+ /// @{
+
+ //! Build a row major matrix from row vectors.
+ //! From GLM_GTX_matrix_major_storage extension.
+ template <typename T>
+ detail::tmat2x2<T> rowMajor2(
+ const detail::tvec2<T>& v1,
+ const detail::tvec2<T>& v2);
+
+ //! Build a row major matrix from other matrix.
+ //! From GLM_GTX_matrix_major_storage extension.
+ template <typename T>
+ detail::tmat2x2<T> rowMajor2(
+ const detail::tmat2x2<T>& m);
+
+ //! Build a row major matrix from row vectors.
+ //! From GLM_GTX_matrix_major_storage extension.
+ template <typename T>
+ detail::tmat3x3<T> rowMajor3(
+ const detail::tvec3<T>& v1,
+ const detail::tvec3<T>& v2,
+ const detail::tvec3<T>& v3);
+
+ //! Build a row major matrix from other matrix.
+ //! From GLM_GTX_matrix_major_storage extension.
+ template <typename T>
+ detail::tmat3x3<T> rowMajor3(
+ const detail::tmat3x3<T>& m);
+
+ //! Build a row major matrix from row vectors.
+ //! From GLM_GTX_matrix_major_storage extension.
+ template <typename T>
+ detail::tmat4x4<T> rowMajor4(
+ const detail::tvec4<T>& v1,
+ const detail::tvec4<T>& v2,
+ const detail::tvec4<T>& v3,
+ const detail::tvec4<T>& v4);
+
+ //! Build a row major matrix from other matrix.
+ //! From GLM_GTX_matrix_major_storage extension.
+ template <typename T>
+ detail::tmat4x4<T> rowMajor4(
+ const detail::tmat4x4<T>& m);
+
+ //! Build a column major matrix from column vectors.
+ //! From GLM_GTX_matrix_major_storage extension.
+ template <typename T>
+ detail::tmat2x2<T> colMajor2(
+ const detail::tvec2<T>& v1,
+ const detail::tvec2<T>& v2);
+
+ //! Build a column major matrix from other matrix.
+ //! From GLM_GTX_matrix_major_storage extension.
+ template <typename T>
+ detail::tmat2x2<T> colMajor2(
+ const detail::tmat2x2<T>& m);
+
+ //! Build a column major matrix from column vectors.
+ //! From GLM_GTX_matrix_major_storage extension.
+ template <typename T>
+ detail::tmat3x3<T> colMajor3(
+ const detail::tvec3<T>& v1,
+ const detail::tvec3<T>& v2,
+ const detail::tvec3<T>& v3);
+
+ //! Build a column major matrix from other matrix.
+ //! From GLM_GTX_matrix_major_storage extension.
+ template <typename T>
+ detail::tmat3x3<T> colMajor3(
+ const detail::tmat3x3<T>& m);
+
+ //! Build a column major matrix from column vectors.
+ //! From GLM_GTX_matrix_major_storage extension.
+ template <typename T>
+ detail::tmat4x4<T> colMajor4(
+ const detail::tvec4<T>& v1,
+ const detail::tvec4<T>& v2,
+ const detail::tvec4<T>& v3,
+ const detail::tvec4<T>& v4);
+
+ //! Build a column major matrix from other matrix.
+ //! From GLM_GTX_matrix_major_storage extension.
+ template <typename T>
+ detail::tmat4x4<T> colMajor4(
+ const detail::tmat4x4<T>& m);
+
+ /// @}
+}//namespace matrix_major_storage
+}//namespace gtx
+}//namespace glm
+
+#include "matrix_major_storage.inl"
+
+namespace glm{using namespace gtx::matrix_major_storage;}
+
+#endif//glm_gtx_matrix_major_storage
diff --git a/src/glm/gtx/matrix_major_storage.inl b/src/glm/gtx/matrix_major_storage.inl
new file mode 100644
index 0000000..e33efdc
--- /dev/null
+++ b/src/glm/gtx/matrix_major_storage.inl
@@ -0,0 +1,176 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2006-04-19
+// Updated : 2009-02-19
+// Licence : This source is under MIT License
+// File : glm/gtx/matrix_major_storage.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm{
+namespace gtx{
+namespace matrix_major_storage
+{
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tmat2x2<T> rowMajor2(
+ const detail::tvec2<T>& v1,
+ const detail::tvec2<T>& v2)
+ {
+ detail::tmat2x2<T> Result;
+ Result[0][0] = v1.x;
+ Result[1][0] = v1.y;
+ Result[0][1] = v2.x;
+ Result[1][1] = v2.y;
+ return Result;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tmat2x2<T> rowMajor2(
+ const detail::tmat2x2<T>& m)
+ {
+ detail::tmat2x2<T> Result;
+ Result[0][0] = m[0][0];
+ Result[0][1] = m[1][0];
+ Result[1][0] = m[0][1];
+ Result[1][1] = m[1][1];
+ return Result;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tmat3x3<T> rowMajor3(
+ const detail::tvec3<T>& v1,
+ const detail::tvec3<T>& v2,
+ const detail::tvec3<T>& v3)
+ {
+ detail::tmat3x3<T> Result;
+ Result[0][0] = v1.x;
+ Result[1][0] = v1.y;
+ Result[2][0] = v1.z;
+ Result[0][1] = v2.x;
+ Result[1][1] = v2.y;
+ Result[2][1] = v2.z;
+ Result[0][2] = v3.x;
+ Result[1][2] = v3.y;
+ Result[2][2] = v3.z;
+ return Result;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tmat3x3<T> rowMajor3(
+ const detail::tmat3x3<T>& m)
+ {
+ detail::tmat3x3<T> Result;
+ Result[0][0] = m[0][0];
+ Result[0][1] = m[1][0];
+ Result[0][2] = m[2][0];
+ Result[1][0] = m[0][1];
+ Result[1][1] = m[1][1];
+ Result[1][2] = m[2][1];
+ Result[2][0] = m[0][2];
+ Result[2][1] = m[1][2];
+ Result[2][2] = m[2][2];
+ return Result;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tmat4x4<T> rowMajor4(
+ const detail::tvec4<T>& v1,
+ const detail::tvec4<T>& v2,
+ const detail::tvec4<T>& v3,
+ const detail::tvec4<T>& v4)
+ {
+ detail::tmat4x4<T> Result;
+ Result[0][0] = v1.x;
+ Result[1][0] = v1.y;
+ Result[2][0] = v1.z;
+ Result[3][0] = v1.w;
+ Result[0][1] = v2.x;
+ Result[1][1] = v2.y;
+ Result[2][1] = v2.z;
+ Result[3][1] = v2.w;
+ Result[0][2] = v3.x;
+ Result[1][2] = v3.y;
+ Result[2][2] = v3.z;
+ Result[3][2] = v3.w;
+ Result[0][3] = v4.x;
+ Result[1][3] = v4.y;
+ Result[2][3] = v4.z;
+ Result[3][3] = v4.w;
+ return Result;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tmat4x4<T> rowMajor4(
+ const detail::tmat4x4<T>& m)
+ {
+ detail::tmat4x4<T> Result;
+ Result[0][0] = m[0][0];
+ Result[0][1] = m[1][0];
+ Result[0][2] = m[2][0];
+ Result[0][3] = m[3][0];
+ Result[1][0] = m[0][1];
+ Result[1][1] = m[1][1];
+ Result[1][2] = m[2][1];
+ Result[1][3] = m[3][1];
+ Result[2][0] = m[0][2];
+ Result[2][1] = m[1][2];
+ Result[2][2] = m[2][2];
+ Result[2][3] = m[3][2];
+ Result[3][0] = m[0][3];
+ Result[3][1] = m[1][3];
+ Result[3][2] = m[2][3];
+ Result[3][3] = m[3][3];
+ return Result;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tmat2x2<T> colMajor2(
+ const detail::tvec2<T>& v1,
+ const detail::tvec2<T>& v2)
+ {
+ return detail::tmat2x2<T>(v1, v2);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tmat2x2<T> colMajor2(
+ const detail::tmat2x2<T>& m)
+ {
+ return detail::tmat2x2<T>(m);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tmat3x3<T> colMajor3(
+ const detail::tvec3<T>& v1,
+ const detail::tvec3<T>& v2,
+ const detail::tvec3<T>& v3)
+ {
+ return detail::tmat3x3<T>(v1, v2, v3);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tmat3x3<T> colMajor3(
+ const detail::tmat3x3<T>& m)
+ {
+ return detail::tmat3x3<T>(m);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tmat4x4<T> colMajor4(
+ const detail::tvec4<T>& v1,
+ const detail::tvec4<T>& v2,
+ const detail::tvec4<T>& v3,
+ const detail::tvec4<T>& v4)
+ {
+ return detail::tmat4x4<T>(v1, v2, v3, v4);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tmat4x4<T> colMajor4(
+ const detail::tmat4x4<T>& m)
+ {
+ return detail::tmat4x4<T>(m);
+ }
+
+}//namespace matrix_major_storage
+}//namespace gtx
+}//namespace glm
diff --git a/src/glm/gtx/matrix_operation.hpp b/src/glm/gtx/matrix_operation.hpp
new file mode 100644
index 0000000..0962743
--- /dev/null
+++ b/src/glm/gtx/matrix_operation.hpp
@@ -0,0 +1,93 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2009-08-29
+// Updated : 2009-08-29
+// Licence : This source is under MIT License
+// File : glm/gtx/matrix_operation.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_gtx_matrix_operation
+#define glm_gtx_matrix_operation
+
+// Dependency:
+#include "../glm.hpp"
+
+#if(defined(GLM_MESSAGES) && !defined(glm_ext))
+# pragma message("GLM: GLM_GTX_matrix_operation extension included")
+#endif
+
+namespace glm{
+namespace gtx{
+namespace matrix_operation ///< GLM_GTX_matrix_operation: Build diagonal matrices
+{
+ /// \addtogroup gtx_matrix_operation
+ /// @{
+
+ //! Build a diagonal matrix.
+ //! From GLM_GTX_matrix_operation extension.
+ template <typename valType>
+ detail::tmat2x2<valType> diagonal2x2(
+ detail::tvec2<valType> const & v);
+
+ //! Build a diagonal matrix.
+ //! From GLM_GTX_matrix_operation extension.
+ template <typename valType>
+ detail::tmat2x3<valType> diagonal2x3(
+ detail::tvec2<valType> const & v);
+
+ //! Build a diagonal matrix.
+ //! From GLM_GTX_matrix_operation extension.
+ template <typename valType>
+ detail::tmat2x4<valType> diagonal2x4(
+ detail::tvec2<valType> const & v);
+
+ //! Build a diagonal matrix.
+ //! From GLM_GTX_matrix_operation extension.
+ template <typename valType>
+ detail::tmat3x2<valType> diagonal3x2(
+ detail::tvec2<valType> const & v);
+
+ //! Build a diagonal matrix.
+ //! From GLM_GTX_matrix_operation extension.
+ template <typename valType>
+ detail::tmat3x3<valType> diagonal3x3(
+ detail::tvec3<valType> const & v);
+
+ //! Build a diagonal matrix.
+ //! From GLM_GTX_matrix_operation extension.
+ template <typename valType>
+ detail::tmat3x4<valType> diagonal3x4(
+ detail::tvec3<valType> const & v);
+
+ //! Build a diagonal matrix.
+ //! From GLM_GTX_matrix_operation extension.
+ template <typename valType>
+ detail::tmat4x2<valType> diagonal4x2(
+ detail::tvec2<valType> const & v);
+
+ //! Build a diagonal matrix.
+ //! From GLM_GTX_matrix_operation extension.
+ template <typename valType>
+ detail::tmat4x3<valType> diagonal4x3(
+ detail::tvec3<valType> const & v);
+
+ //! Build a diagonal matrix.
+ //! From GLM_GTX_matrix_operation extension.
+ template <typename valType>
+ detail::tmat4x4<valType> diagonal4x4(
+ detail::tvec4<valType> const & v);
+
+ /// @}
+}//namespace matrix_operation
+}//namespace gtx
+}//namespace glm
+
+#include "matrix_operation.inl"
+
+namespace glm{using namespace gtx::matrix_operation;}
+
+#endif//glm_gtx_matrix_operation
diff --git a/src/glm/gtx/matrix_operation.inl b/src/glm/gtx/matrix_operation.inl
new file mode 100644
index 0000000..250a42e
--- /dev/null
+++ b/src/glm/gtx/matrix_operation.inl
@@ -0,0 +1,129 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2009-08-29
+// Updated : 2009-08-29
+// Licence : This source is under MIT License
+// File : glm/gtx/matrix_operation.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm{
+namespace gtx{
+namespace matrix_operation
+{
+ template <typename valType>
+ GLM_FUNC_QUALIFIER detail::tmat2x2<valType> diagonal2x2
+ (
+ detail::tvec2<valType> const & v
+ )
+ {
+ detail::tmat2x2<valType> Result(valType(1));
+ Result[0][0] = v[0];
+ Result[1][1] = v[1];
+ return Result;
+ }
+
+ template <typename valType>
+ GLM_FUNC_QUALIFIER detail::tmat2x3<valType> diagonal2x3
+ (
+ detail::tvec2<valType> const & v
+ )
+ {
+ detail::tmat2x3<valType> Result(valType(1));
+ Result[0][0] = v[0];
+ Result[1][1] = v[1];
+ return Result;
+ }
+
+ template <typename valType>
+ GLM_FUNC_QUALIFIER detail::tmat2x4<valType> diagonal2x4
+ (
+ detail::tvec2<valType> const & v
+ )
+ {
+ detail::tmat2x4<valType> Result(valType(1));
+ Result[0][0] = v[0];
+ Result[1][1] = v[1];
+ return Result;
+ }
+
+ template <typename valType>
+ GLM_FUNC_QUALIFIER detail::tmat3x2<valType> diagonal3x2
+ (
+ detail::tvec2<valType> const & v
+ )
+ {
+ detail::tmat3x2<valType> Result(valType(1));
+ Result[0][0] = v[0];
+ Result[1][1] = v[1];
+ return Result;
+ }
+
+ template <typename valType>
+ GLM_FUNC_QUALIFIER detail::tmat3x3<valType> diagonal3x3
+ (
+ detail::tvec3<valType> const & v
+ )
+ {
+ detail::tmat3x3<valType> Result(valType(1));
+ Result[0][0] = v[0];
+ Result[1][1] = v[1];
+ Result[2][2] = v[2];
+ return Result;
+ }
+
+ template <typename valType>
+ GLM_FUNC_QUALIFIER detail::tmat3x4<valType> diagonal3x4
+ (
+ detail::tvec3<valType> const & v
+ )
+ {
+ detail::tmat3x4<valType> Result(valType(1));
+ Result[0][0] = v[0];
+ Result[1][1] = v[1];
+ Result[2][2] = v[2];
+ return Result;
+ }
+
+ template <typename valType>
+ GLM_FUNC_QUALIFIER detail::tmat4x4<valType> diagonal4x4
+ (
+ detail::tvec4<valType> const & v
+ )
+ {
+ detail::tmat4x4<valType> Result(valType(1));
+ Result[0][0] = v[0];
+ Result[1][1] = v[1];
+ Result[2][2] = v[2];
+ Result[3][3] = v[3];
+ return Result;
+ }
+
+ template <typename valType>
+ GLM_FUNC_QUALIFIER detail::tmat4x3<valType> diagonal4x3
+ (
+ detail::tvec3<valType> const & v
+ )
+ {
+ detail::tmat4x3<valType> Result(valType(1));
+ Result[0][0] = v[0];
+ Result[1][1] = v[1];
+ Result[2][2] = v[2];
+ return Result;
+ }
+
+ template <typename valType>
+ GLM_FUNC_QUALIFIER detail::tmat4x2<valType> diagonal4x2
+ (
+ detail::tvec2<valType> const & v
+ )
+ {
+ detail::tmat4x2<valType> Result(valType(1));
+ Result[0][0] = v[0];
+ Result[1][1] = v[1];
+ return Result;
+ }
+
+}//namespace matrix_operation
+}//namespace gtx
+}//namespace glm
diff --git a/src/glm/gtx/matrix_query.hpp b/src/glm/gtx/matrix_query.hpp
new file mode 100644
index 0000000..d19a535
--- /dev/null
+++ b/src/glm/gtx/matrix_query.hpp
@@ -0,0 +1,95 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2007-03-05
+// Updated : 2007-03-05
+// Licence : This source is under MIT License
+// File : glm/gtx/matrix_query.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_gtx_matrix_query
+#define glm_gtx_matrix_query
+
+// Dependency:
+#include "../glm.hpp"
+
+#if(defined(GLM_MESSAGES) && !defined(glm_ext))
+# pragma message("GLM: GLM_GTX_matrix_query extension included")
+#endif
+
+namespace glm{
+namespace gtx{
+namespace matrix_query ///< GLM_GTX_matrix_query: Query to evaluate matrix properties
+{
+ /// \addtogroup gtx_matrix_query
+ /// @{
+
+ //! Return if a matrix a null matrix.
+ //! From GLM_GTX_matrix_query extension.
+ template<typename T>
+ bool isNull(
+ const detail::tmat2x2<T>& m,
+ const T epsilon = std::numeric_limits<T>::epsilon());
+
+ //! Return if a matrix a null matrix.
+ //! From GLM_GTX_matrix_query extension.
+ template<typename T>
+ bool isNull(
+ const detail::tmat3x3<T>& m,
+ const T epsilon = std::numeric_limits<T>::epsilon());
+
+ //! Return if a matrix a null matrix.
+ //! From GLM_GTX_matrix_query extension.
+ template<typename T>
+ bool isNull(
+ const detail::tmat4x4<T>& m,
+ const T epsilon = std::numeric_limits<T>::epsilon());
+
+ //! Return if a matrix an identity matrix.
+ //! From GLM_GTX_matrix_query extension.
+ template<typename genType>
+ bool isIdentity(
+ const genType& m,
+ const typename genType::value_type epsilon = std::numeric_limits<typename genType::value_type>::epsilon());
+
+ //! Return if a matrix a normalized matrix.
+ //! From GLM_GTX_matrix_query extension.
+ template<typename T>
+ bool isNormalized(
+ const detail::tmat2x2<T>& m,
+ const T epsilon = std::numeric_limits<T>::epsilon());
+
+ //! Return if a matrix a normalized matrix.
+ //! From GLM_GTX_matrix_query extension.
+ template<typename T>
+ bool isNormalized(
+ const detail::tmat3x3<T>& m,
+ const T epsilon = std::numeric_limits<T>::epsilon());
+
+ //! Return if a matrix a normalized matrix.
+ //! From GLM_GTX_matrix_query extension.
+ template<typename T>
+ bool isNormalized(
+ const detail::tmat4x4<T>& m,
+ const T epsilon = std::numeric_limits<T>::epsilon());
+
+ //! Return if a matrix an orthonormalized matrix.
+ //! From GLM_GTX_matrix_query extension.
+ template<typename genType>
+ bool isOrthogonal(
+ const genType& m,
+ const typename genType::value_type epsilon = std::numeric_limits<typename genType::value_type>::epsilon());
+
+ /// @}
+}//namespace matrix_query
+}//namespace gtx
+}//namespace glm
+
+#include "matrix_query.inl"
+
+namespace glm{using namespace gtx::matrix_query;}
+
+#endif//glm_gtx_matrix_query
diff --git a/src/glm/gtx/matrix_query.inl b/src/glm/gtx/matrix_query.inl
new file mode 100644
index 0000000..deae669
--- /dev/null
+++ b/src/glm/gtx/matrix_query.inl
@@ -0,0 +1,144 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2007-03-05
+// Updated : 2007-03-05
+// Licence : This source is under MIT License
+// File : glm/gtx/matrix_query.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm{
+namespace gtx{
+namespace matrix_query
+{
+ template<typename T>
+ GLM_FUNC_QUALIFIER bool isNull(
+ const detail::tmat2x2<T>& m,
+ const T epsilon)
+ {
+ bool result = true;
+ for(int i = 0; result && i < 2 ; ++i)
+ result = isNull(m[i], epsilon);
+ return result;
+ }
+
+ template<typename T>
+ GLM_FUNC_QUALIFIER bool isNull(
+ const detail::tmat3x3<T>& m,
+ const T epsilon)
+ {
+ bool result = true;
+ for(int i = 0; result && i < 3 ; ++i)
+ result = isNull(m[i], epsilon);
+ return result;
+ }
+
+ template<typename T>
+ GLM_FUNC_QUALIFIER bool isNull(
+ const detail::tmat4x4<T>& m,
+ const T epsilon)
+ {
+ bool result = true;
+ for(int i = 0; result && i < 4 ; ++i)
+ result = isNull(m[i], epsilon);
+ return result;
+ }
+
+ template<typename genType>
+ GLM_FUNC_QUALIFIER bool isIdentity(
+ const genType& m,
+ const typename genType::value_type epsilon)
+ {
+ bool result = true;
+ for(typename genType::value_type i = typename genType::value_type(0); result && i < genType::col_size(); ++i)
+ {
+ for(typename genType::value_type j = typename genType::value_type(0); result && j < i ; ++j)
+ result = abs(m[i][j]) <= epsilon;
+ if(result)
+ result = abs(m[i][i] - typename genType::value_type(1)) <= epsilon;
+ for(typename genType::value_type j = i + typename genType::value_type(1); result && j < genType::row_size(); ++j)
+ result = abs(m[i][j]) <= epsilon;
+ }
+ return result;
+ }
+
+ template<typename T>
+ GLM_FUNC_QUALIFIER bool isNormalized(
+ const detail::tmat2x2<T>& m,
+ const T epsilon)
+ {
+ bool result = true;
+ for(int i = 0; result && i < 2; ++i)
+ result = isNormalized(m[i], epsilon);
+ for(int i = 0; result && i < 2; ++i)
+ {
+ detail::tvec2<T> v;
+ for(int j = 0; j < 2; ++j)
+ v[j] = m[j][i];
+ result = isNormalized(v, epsilon);
+ }
+ return result;
+ }
+
+ template<typename T>
+ GLM_FUNC_QUALIFIER bool isNormalized(
+ const detail::tmat3x3<T>& m,
+ const T epsilon)
+ {
+ bool result = true;
+ for(int i = 0; result && i < 3; ++i)
+ result = isNormalized(m[i], epsilon);
+ for(int i = 0; result && i < 3; ++i)
+ {
+ detail::tvec3<T> v;
+ for(int j = 0; j < 3; ++j)
+ v[j] = m[j][i];
+ result = isNormalized(v, epsilon);
+ }
+ return result;
+ }
+
+ template<typename T>
+ GLM_FUNC_QUALIFIER bool isNormalized(
+ const detail::tmat4x4<T>& m,
+ const T epsilon)
+ {
+ bool result = true;
+ for(int i = 0; result && i < 4; ++i)
+ result = isNormalized(m[i], epsilon);
+ for(int i = 0; result && i < 4; ++i)
+ {
+ detail::tvec4<T> v;
+ for(int j = 0; j < 4; ++j)
+ v[j] = m[j][i];
+ result = isNormalized(v, epsilon);
+ }
+ return result;
+ }
+
+ template<typename genType>
+ GLM_FUNC_QUALIFIER bool isOrthogonal(
+ const genType& m,
+ const typename genType::value_type epsilon)
+ {
+ bool result = true;
+ for(int i = 0; result && i < genType::col_size() - 1; ++i)
+ for(int j= i + 1; result && j < genType::col_size(); ++j)
+ result = areOrthogonal(m[i], m[j], epsilon);
+
+ if(result)
+ {
+ genType tmp = transpose(m);
+ for(int i = 0; result && i < genType::col_size() - 1 ; ++i)
+ for(int j = i + 1; result && j < genType::col_size(); ++j)
+ result = areOrthogonal(tmp[i], tmp[j], epsilon);
+ }
+ return result;
+ }
+
+}//namespace matrix_query
+}//namespace gtx
+}//namespace glm
diff --git a/src/glm/gtx/mixed_product.hpp b/src/glm/gtx/mixed_product.hpp
new file mode 100644
index 0000000..b4ebebd
--- /dev/null
+++ b/src/glm/gtx/mixed_product.hpp
@@ -0,0 +1,46 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2007-04-03
+// Updated : 2008-09-17
+// Licence : This source is under MIT License
+// File : glm/gtx/mixed_product.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_gtx_mixed_product
+#define glm_gtx_mixed_product
+
+// Dependency:
+#include "../glm.hpp"
+
+#if(defined(GLM_MESSAGES) && !defined(glm_ext))
+# pragma message("GLM: GLM_GTX_mixed_product extension included")
+#endif
+
+namespace glm{
+namespace gtx{
+namespace mixed_product ///< GLM_GTX_mixed_product extension: Mixed product of 3 vectors.
+{
+ /// \addtogroup gtx_mixed_product
+ /// @{
+
+ //! \brief Mixed product of 3 vectors (from GLM_GTX_mixed_product extension)
+ template <typename valType>
+ valType mixedProduct(
+ detail::tvec3<valType> const & v1,
+ detail::tvec3<valType> const & v2,
+ detail::tvec3<valType> const & v3);
+
+ /// @}
+}// namespace mixed_product
+}// namespace gtx
+}// namespace glm
+
+#include "mixed_product.inl"
+
+namespace glm{using namespace gtx::mixed_product;}
+
+#endif//glm_gtx_mixed_product
diff --git a/src/glm/gtx/mixed_product.inl b/src/glm/gtx/mixed_product.inl
new file mode 100644
index 0000000..a813606
--- /dev/null
+++ b/src/glm/gtx/mixed_product.inl
@@ -0,0 +1,36 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2007-04-03
+// Updated : 2008-09-17
+// Licence : This source is under MIT License
+// File : glm/gtx/mixed_product.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm{
+namespace gtx{
+
+namespace mixed_product
+{
+ template <typename valType>
+ GLM_FUNC_QUALIFIER valType mixedProduct(
+ detail::tvec3<valType> const & v1,
+ detail::tvec3<valType> const & v2,
+ detail::tvec3<valType> const & v3)
+ {
+ return dot(cross(v1, v2), v3);
+ }
+}
+//namespace mixed_product
+
+}//namespace gtx
+}//namespace glm
+
+
+
+
+
+
+
+
+
diff --git a/src/glm/gtx/multiple.hpp b/src/glm/gtx/multiple.hpp
new file mode 100644
index 0000000..cf7f858
--- /dev/null
+++ b/src/glm/gtx/multiple.hpp
@@ -0,0 +1,53 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2009-10-26
+// Updated : 2009-10-26
+// Licence : This source is under MIT License
+// File : glm/gtx/multiple.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_gtx_multiple
+#define glm_gtx_multiple
+
+// Dependency:
+#include "../glm.hpp"
+
+#if(defined(GLM_MESSAGES) && !defined(glm_ext))
+# pragma message("GLM: GLM_GTX_multiple extension included")
+#endif
+
+namespace glm{
+namespace gtx{
+namespace multiple ///< GLM_GTX_multiple: Find the closest number of a number multiple of other number.
+{
+ /// \addtogroup gtx_multiple
+ /// @{
+
+ //! Higher Multiple number of Source.
+ //! From GLM_GTX_multiple extension.
+ template <typename genType>
+ genType higherMultiple(
+ genType const & Source,
+ genType const & Multiple);
+
+ //! Lower Multiple number of Source.
+ //! From GLM_GTX_multiple extension.
+ template <typename genType>
+ genType lowerMultiple(
+ genType const & Source,
+ genType const & Multiple);
+
+ /// @}
+}//namespace multiple
+}//namespace gtx
+}//namespace glm
+
+#include "multiple.inl"
+
+namespace glm{using namespace gtx::multiple;}
+
+#endif//glm_gtx_multiple
diff --git a/src/glm/gtx/multiple.inl b/src/glm/gtx/multiple.inl
new file mode 100644
index 0000000..6ccf1ad
--- /dev/null
+++ b/src/glm/gtx/multiple.inl
@@ -0,0 +1,191 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2009-10-26
+// Updated : 2009-10-26
+// Licence : This source is under MIT License
+// File : glm/gtx/multiple.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm{
+namespace gtx{
+namespace multiple
+{
+ //////////////////////
+ // higherMultiple
+
+ template <typename genType>
+ GLM_FUNC_QUALIFIER genType higherMultiple
+ (
+ genType const & Source,
+ genType const & Multiple
+ )
+ {
+ genType Tmp = Source % Multiple;
+ return Tmp ? Source + Multiple - Tmp : Source;
+ }
+
+ template <>
+ GLM_FUNC_QUALIFIER detail::thalf higherMultiple
+ (
+ detail::thalf const & Source,
+ detail::thalf const & Multiple
+ )
+ {
+ int Tmp = int(float(Source)) % int(float(Multiple));
+ return Tmp ? Source + Multiple - detail::thalf(float(Tmp)) : Source;
+ }
+
+ template <>
+ GLM_FUNC_QUALIFIER float higherMultiple
+ (
+ float const & Source,
+ float const & Multiple
+ )
+ {
+ int Tmp = int(Source) % int(Multiple);
+ return Tmp ? Source + Multiple - float(Tmp) : Source;
+ }
+
+ template <>
+ GLM_FUNC_QUALIFIER double higherMultiple
+ (
+ double const & Source,
+ double const & Multiple
+ )
+ {
+ long Tmp = long(Source) % long(Multiple);
+ return Tmp ? Source + Multiple - double(Tmp) : Source;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<T> higherMultiple
+ (
+ detail::tvec2<T> const & Source,
+ detail::tvec2<T> const & Multiple
+ )
+ {
+ detail::tvec2<T> Result;
+ for(typename detail::tvec2<T>::size_type i = 0; i < detail::tvec2<T>::value_size(); ++i)
+ Result[i] = higherMultiple(Source[i], Multiple[i]);
+ return Result;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> higherMultiple
+ (
+ detail::tvec3<T> const & Source,
+ detail::tvec3<T> const & Multiple
+ )
+ {
+ detail::tvec3<T> Result;
+ for(typename detail::tvec3<T>::size_type i = 0; i < detail::tvec3<T>::value_size(); ++i)
+ Result[i] = higherMultiple(Source[i], Multiple[i]);
+ return Result;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<T> higherMultiple
+ (
+ detail::tvec4<T> const & Source,
+ detail::tvec4<T> const & Multiple
+ )
+ {
+ detail::tvec4<T> Result;
+ for(typename detail::tvec4<T>::size_type i = 0; i < detail::tvec4<T>::value_size(); ++i)
+ Result[i] = higherMultiple(Source[i], Multiple[i]);
+ return Result;
+ }
+
+ //////////////////////
+ // lowerMultiple
+
+ template <typename genType>
+ GLM_FUNC_QUALIFIER genType lowerMultiple
+ (
+ genType const & Source,
+ genType const & Multiple
+ )
+ {
+ genType Tmp = Source % Multiple;
+ return Tmp ? Source - Tmp : Source;
+ }
+
+ template <>
+ GLM_FUNC_QUALIFIER detail::thalf lowerMultiple
+ (
+ detail::thalf const & Source,
+ detail::thalf const & Multiple
+ )
+ {
+ int Tmp = int(float(Source)) % int(float(Multiple));
+ return Tmp ? Source - detail::thalf(float(Tmp)) : Source;
+ }
+
+ template <>
+ GLM_FUNC_QUALIFIER float lowerMultiple
+ (
+ float const & Source,
+ float const & Multiple
+ )
+ {
+ int Tmp = int(Source) % int(Multiple);
+ return Tmp ? Source - float(Tmp) : Source;
+ }
+
+ template <>
+ GLM_FUNC_QUALIFIER double lowerMultiple
+ (
+ double const & Source,
+ double const & Multiple
+ )
+ {
+ long Tmp = long(Source) % long(Multiple);
+ return Tmp ? Source - double(Tmp) : Source;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<T> lowerMultiple
+ (
+ detail::tvec2<T> const & Source,
+ detail::tvec2<T> const & Multiple
+ )
+ {
+ detail::tvec2<T> Result;
+ for(typename detail::tvec2<T>::size_type i = 0; i < detail::tvec2<T>::value_size(); ++i)
+ Result[i] = lowerMultiple(Source[i], Multiple[i]);
+ return Result;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> lowerMultiple
+ (
+ detail::tvec3<T> const & Source,
+ detail::tvec3<T> const & Multiple
+ )
+ {
+ detail::tvec3<T> Result;
+ for(typename detail::tvec3<T>::size_type i = 0; i < detail::tvec3<T>::value_size(); ++i)
+ Result[i] = lowerMultiple(Source[i], Multiple[i]);
+ return Result;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<T> lowerMultiple
+ (
+ detail::tvec4<T> const & Source,
+ detail::tvec4<T> const & Multiple
+ )
+ {
+ detail::tvec4<T> Result;
+ for(typename detail::tvec4<T>::size_type i = 0; i < detail::tvec4<T>::value_size(); ++i)
+ Result[i] = lowerMultiple(Source[i], Multiple[i]);
+ return Result;
+ }
+
+}//namespace multiple
+}//namespace gtx
+}//namespace glm
diff --git a/src/glm/gtx/noise.hpp b/src/glm/gtx/noise.hpp
new file mode 100644
index 0000000..bef412f
--- /dev/null
+++ b/src/glm/gtx/noise.hpp
@@ -0,0 +1,63 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Based on the work of Stefan Gustavson and Ashima Arts on "webgl-noise":
+// https://github.com/ashima/webgl-noise
+// Following Stefan Gustavson's paper "Simplex noise demystified":
+// http://www.itn.liu.se/~stegu/simplexnoise/simplexnoise.pdf
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2011-04-21
+// Updated : 2011-04-21
+// Licence : This source is under MIT License
+// File : glm/gtx/noise.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_gtx_noise
+#define glm_gtx_noise
+
+// Dependency:
+#include "../glm.hpp"
+
+#if(defined(GLM_MESSAGES) && !defined(glm_ext))
+# pragma message("GLM: GLM_GTX_noise extension included")
+#endif
+
+namespace glm{
+namespace gtx{
+namespace noise ///< GLM_GTX_noise extension: Comparison functions for a user defined epsilon values.
+{
+ /// \addtogroup gtx_noise
+ /// @{
+
+ //! Classic perlin noise.
+ //! From GLM_GTX_noise extension.
+ template <typename T, template<typename> class vecType>
+ T perlin(
+ vecType<T> const & p);
+
+ //! Periodic perlin noise.
+ //! From GLM_GTX_noise extension.
+ template <typename T, template<typename> class vecType>
+ T perlin(
+ vecType<T> const & p,
+ vecType<T> const & rep);
+
+ //! Simplex noise.
+ //! From GLM_GTX_noise extension.
+ template <typename T, template<typename> class vecType>
+ T simplex(
+ vecType<T> const & p);
+
+ /// @}
+}//namespace noise
+}//namespace gtx
+}//namespace glm
+
+#include "noise.inl"
+
+namespace glm{using namespace gtx::noise;}
+
+#endif//glm_gtx_noise
diff --git a/src/glm/gtx/noise.inl b/src/glm/gtx/noise.inl
new file mode 100644
index 0000000..566074d
--- /dev/null
+++ b/src/glm/gtx/noise.inl
@@ -0,0 +1,792 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Based on the work of Stefan Gustavson and Ashima Arts on "webgl-noise":
+// https://github.com/ashima/webgl-noise
+// Following Stefan Gustavson's paper "Simplex noise demystified":
+// http://www.itn.liu.se/~stegu/simplexnoise/simplexnoise.pdf
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2011-04-21
+// Updated : 2011-04-21
+// Licence : This source is under MIT License
+// File : glm/gtx/noise.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm
+{
+ template <typename T>
+ GLM_FUNC_QUALIFIER T permute(T const & x)
+ {
+ return mod(((x * T(34)) + T(1)) * x, T(289));
+ }
+
+ template <typename T, template<typename> class vecType>
+ GLM_FUNC_QUALIFIER vecType<T> permute(vecType<T> const & x)
+ {
+ return mod(((x * T(34)) + T(1)) * x, T(289));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER T taylorInvSqrt(T const & r)
+ {
+ return T(1.79284291400159) - T(0.85373472095314) * r;
+ }
+
+ template <typename T, template<typename> class vecType>
+ GLM_FUNC_QUALIFIER vecType<T> taylorInvSqrt(vecType<T> const & r)
+ {
+ return T(1.79284291400159) - T(0.85373472095314) * r;
+ }
+
+ template <typename T, template <typename> class vecType>
+ GLM_FUNC_QUALIFIER vecType<T> fade(vecType<T> const & t)
+ {
+ return t * t * t * (t * (t * T(6) - T(15)) + T(10));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<T> grad4(T const & j, detail::tvec4<T> const & ip)
+ {
+ detail::tvec3<T> pXYZ = floor(fract(detail::tvec3<T>(j) * detail::tvec3<T>(ip)) * T(7)) * ip[2] - T(1);
+ T pW = T(1.5) - dot(abs(pXYZ), detail::tvec3<T>(1));
+ detail::tvec4<T> s = detail::tvec4<T>(lessThan(detail::tvec4<T>(pXYZ, pW), detail::tvec4<T>(0.0)));
+ pXYZ = pXYZ + (detail::tvec3<T>(s) * T(2) - T(1)) * s.w;
+ return detail::tvec4<T>(pXYZ, pW);
+ }
+
+namespace gtx{
+namespace noise
+{
+ // Classic Perlin noise
+ template <typename T>
+ GLM_FUNC_QUALIFIER T perlin(detail::tvec2<T> const & P)
+ {
+ detail::tvec4<T> Pi = floor(detail::tvec4<T>(P.x, P.y, P.x, P.y)) + detail::tvec4<T>(0.0, 0.0, 1.0, 1.0);
+ detail::tvec4<T> Pf = fract(detail::tvec4<T>(P.x, P.y, P.x, P.y)) - detail::tvec4<T>(0.0, 0.0, 1.0, 1.0);
+ Pi = mod(Pi, T(289)); // To avoid truncation effects in permutation
+ detail::tvec4<T> ix(Pi.x, Pi.z, Pi.x, Pi.z);
+ detail::tvec4<T> iy(Pi.y, Pi.y, Pi.w, Pi.w);
+ detail::tvec4<T> fx(Pf.x, Pf.z, Pf.x, Pf.z);
+ detail::tvec4<T> fy(Pf.y, Pf.y, Pf.w, Pf.w);
+
+ detail::tvec4<T> i = permute(permute(ix) + iy);
+
+ detail::tvec4<T> gx = T(2) * fract(i / T(41)) - T(1);
+ detail::tvec4<T> gy = abs(gx) - T(0.5);
+ detail::tvec4<T> tx = floor(gx + T(0.5));
+ gx = gx - tx;
+
+ detail::tvec2<T> g00(gx.x, gy.x);
+ detail::tvec2<T> g10(gx.y, gy.y);
+ detail::tvec2<T> g01(gx.z, gy.z);
+ detail::tvec2<T> g11(gx.w, gy.w);
+
+ detail::tvec4<T> norm = taylorInvSqrt(detail::tvec4<T>(dot(g00, g00), dot(g01, g01), dot(g10, g10), dot(g11, g11)));
+ g00 *= norm.x;
+ g01 *= norm.y;
+ g10 *= norm.z;
+ g11 *= norm.w;
+
+ T n00 = dot(g00, detail::tvec2<T>(fx.x, fy.x));
+ T n10 = dot(g10, detail::tvec2<T>(fx.y, fy.y));
+ T n01 = dot(g01, detail::tvec2<T>(fx.z, fy.z));
+ T n11 = dot(g11, detail::tvec2<T>(fx.w, fy.w));
+
+ detail::tvec2<T> fade_xy = fade(detail::tvec2<T>(Pf.x, Pf.y));
+ detail::tvec2<T> n_x = mix(detail::tvec2<T>(n00, n01), detail::tvec2<T>(n10, n11), fade_xy.x);
+ T n_xy = mix(n_x.x, n_x.y, fade_xy.y);
+ return T(2.3) * n_xy;
+ }
+
+ // Classic Perlin noise
+ template <typename T>
+ GLM_FUNC_QUALIFIER T perlin(detail::tvec3<T> const & P)
+ {
+ detail::tvec3<T> Pi0 = floor(P); // Integer part for indexing
+ detail::tvec3<T> Pi1 = Pi0 + T(1); // Integer part + 1
+ Pi0 = mod(Pi0, T(289));
+ Pi1 = mod(Pi1, T(289));
+ detail::tvec3<T> Pf0 = fract(P); // Fractional part for interpolation
+ detail::tvec3<T> Pf1 = Pf0 - T(1); // Fractional part - 1.0
+ detail::tvec4<T> ix(Pi0.x, Pi1.x, Pi0.x, Pi1.x);
+ detail::tvec4<T> iy(Pi0.y, Pi0.y, Pi1.y, Pi1.y);
+ detail::tvec4<T> iz0(Pi0.z);
+ detail::tvec4<T> iz1(Pi1.z);
+
+ detail::tvec4<T> ixy = permute(permute(ix) + iy);
+ detail::tvec4<T> ixy0 = permute(ixy + iz0);
+ detail::tvec4<T> ixy1 = permute(ixy + iz1);
+
+ detail::tvec4<T> gx0 = ixy0 / T(7);
+ detail::tvec4<T> gy0 = fract(floor(gx0) / T(7)) - T(0.5);
+ gx0 = fract(gx0);
+ detail::tvec4<T> gz0 = detail::tvec4<T>(0.5) - abs(gx0) - abs(gy0);
+ detail::tvec4<T> sz0 = step(gz0, detail::tvec4<T>(0.0));
+ gx0 -= sz0 * (step(0.0, gx0) - T(0.5));
+ gy0 -= sz0 * (step(0.0, gy0) - T(0.5));
+
+ detail::tvec4<T> gx1 = ixy1 / T(7);
+ detail::tvec4<T> gy1 = fract(floor(gx1) / T(7)) - T(0.5);
+ gx1 = fract(gx1);
+ detail::tvec4<T> gz1 = detail::tvec4<T>(0.5) - abs(gx1) - abs(gy1);
+ detail::tvec4<T> sz1 = step(gz1, detail::tvec4<T>(0.0));
+ gx1 -= sz1 * (step(T(0), gx1) - T(0.5));
+ gy1 -= sz1 * (step(T(0), gy1) - T(0.5));
+
+ detail::tvec3<T> g000(gx0.x, gy0.x, gz0.x);
+ detail::tvec3<T> g100(gx0.y, gy0.y, gz0.y);
+ detail::tvec3<T> g010(gx0.z, gy0.z, gz0.z);
+ detail::tvec3<T> g110(gx0.w, gy0.w, gz0.w);
+ detail::tvec3<T> g001(gx1.x, gy1.x, gz1.x);
+ detail::tvec3<T> g101(gx1.y, gy1.y, gz1.y);
+ detail::tvec3<T> g011(gx1.z, gy1.z, gz1.z);
+ detail::tvec3<T> g111(gx1.w, gy1.w, gz1.w);
+
+ detail::tvec4<T> norm0 = taylorInvSqrt(detail::tvec4<T>(dot(g000, g000), dot(g010, g010), dot(g100, g100), dot(g110, g110)));
+ g000 *= norm0.x;
+ g010 *= norm0.y;
+ g100 *= norm0.z;
+ g110 *= norm0.w;
+ detail::tvec4<T> norm1 = taylorInvSqrt(detail::tvec4<T>(dot(g001, g001), dot(g011, g011), dot(g101, g101), dot(g111, g111)));
+ g001 *= norm1.x;
+ g011 *= norm1.y;
+ g101 *= norm1.z;
+ g111 *= norm1.w;
+
+ T n000 = dot(g000, Pf0);
+ T n100 = dot(g100, detail::tvec3<T>(Pf1.x, Pf0.y, Pf0.z));
+ T n010 = dot(g010, detail::tvec3<T>(Pf0.x, Pf1.y, Pf0.z));
+ T n110 = dot(g110, detail::tvec3<T>(Pf1.x, Pf1.y, Pf0.z));
+ T n001 = dot(g001, detail::tvec3<T>(Pf0.x, Pf0.y, Pf1.z));
+ T n101 = dot(g101, detail::tvec3<T>(Pf1.x, Pf0.y, Pf1.z));
+ T n011 = dot(g011, detail::tvec3<T>(Pf0.x, Pf1.y, Pf1.z));
+ T n111 = dot(g111, Pf1);
+
+ detail::tvec3<T> fade_xyz = fade(Pf0);
+ detail::tvec4<T> n_z = mix(detail::tvec4<T>(n000, n100, n010, n110), detail::tvec4<T>(n001, n101, n011, n111), fade_xyz.z);
+ detail::tvec2<T> n_yz = mix(
+ detail::tvec2<T>(n_z.x, n_z.y),
+ detail::tvec2<T>(n_z.z, n_z.w), fade_xyz.y);
+ T n_xyz = mix(n_yz.x, n_yz.y, fade_xyz.x);
+ return T(2.2) * n_xyz;
+ }
+
+ // Classic Perlin noise
+ template <typename T>
+ GLM_FUNC_QUALIFIER T perlin(detail::tvec4<T> const & P)
+ {
+ detail::tvec4<T> Pi0 = floor(P); // Integer part for indexing
+ detail::tvec4<T> Pi1 = Pi0 + T(1); // Integer part + 1
+ Pi0 = mod(Pi0, T(289));
+ Pi1 = mod(Pi1, T(289));
+ detail::tvec4<T> Pf0 = fract(P); // Fractional part for interpolation
+ detail::tvec4<T> Pf1 = Pf0 - T(1); // Fractional part - 1.0
+ detail::tvec4<T> ix(Pi0.x, Pi1.x, Pi0.x, Pi1.x);
+ detail::tvec4<T> iy(Pi0.y, Pi0.y, Pi1.y, Pi1.y);
+ detail::tvec4<T> iz0(Pi0.z);
+ detail::tvec4<T> iz1(Pi1.z);
+ detail::tvec4<T> iw0(Pi0.w);
+ detail::tvec4<T> iw1(Pi1.w);
+
+ detail::tvec4<T> ixy = permute(permute(ix) + iy);
+ detail::tvec4<T> ixy0 = permute(ixy + iz0);
+ detail::tvec4<T> ixy1 = permute(ixy + iz1);
+ detail::tvec4<T> ixy00 = permute(ixy0 + iw0);
+ detail::tvec4<T> ixy01 = permute(ixy0 + iw1);
+ detail::tvec4<T> ixy10 = permute(ixy1 + iw0);
+ detail::tvec4<T> ixy11 = permute(ixy1 + iw1);
+
+ detail::tvec4<T> gx00 = ixy00 / T(7);
+ detail::tvec4<T> gy00 = floor(gx00) / T(7);
+ detail::tvec4<T> gz00 = floor(gy00) / T(6);
+ gx00 = fract(gx00) - T(0.5);
+ gy00 = fract(gy00) - T(0.5);
+ gz00 = fract(gz00) - T(0.5);
+ detail::tvec4<T> gw00 = detail::tvec4<T>(0.75) - abs(gx00) - abs(gy00) - abs(gz00);
+ detail::tvec4<T> sw00 = step(gw00, detail::tvec4<T>(0.0));
+ gx00 -= sw00 * (step(T(0), gx00) - T(0.5));
+ gy00 -= sw00 * (step(T(0), gy00) - T(0.5));
+
+ detail::tvec4<T> gx01 = ixy01 / T(7);
+ detail::tvec4<T> gy01 = floor(gx01) / T(7);
+ detail::tvec4<T> gz01 = floor(gy01) / T(6);
+ gx01 = fract(gx01) - T(0.5);
+ gy01 = fract(gy01) - T(0.5);
+ gz01 = fract(gz01) - T(0.5);
+ detail::tvec4<T> gw01 = detail::tvec4<T>(0.75) - abs(gx01) - abs(gy01) - abs(gz01);
+ detail::tvec4<T> sw01 = step(gw01, detail::tvec4<T>(0.0));
+ gx01 -= sw01 * (step(T(0), gx01) - T(0.5));
+ gy01 -= sw01 * (step(T(0), gy01) - T(0.5));
+
+ detail::tvec4<T> gx10 = ixy10 / T(7);
+ detail::tvec4<T> gy10 = floor(gx10) / T(7);
+ detail::tvec4<T> gz10 = floor(gy10) / T(6);
+ gx10 = fract(gx10) - T(0.5);
+ gy10 = fract(gy10) - T(0.5);
+ gz10 = fract(gz10) - T(0.5);
+ detail::tvec4<T> gw10 = detail::tvec4<T>(0.75) - abs(gx10) - abs(gy10) - abs(gz10);
+ detail::tvec4<T> sw10 = step(gw10, detail::tvec4<T>(0));
+ gx10 -= sw10 * (step(T(0), gx10) - T(0.5));
+ gy10 -= sw10 * (step(T(0), gy10) - T(0.5));
+
+ detail::tvec4<T> gx11 = ixy11 / T(7);
+ detail::tvec4<T> gy11 = floor(gx11) / T(7);
+ detail::tvec4<T> gz11 = floor(gy11) / T(6);
+ gx11 = fract(gx11) - T(0.5);
+ gy11 = fract(gy11) - T(0.5);
+ gz11 = fract(gz11) - T(0.5);
+ detail::tvec4<T> gw11 = detail::tvec4<T>(0.75) - abs(gx11) - abs(gy11) - abs(gz11);
+ detail::tvec4<T> sw11 = step(gw11, detail::tvec4<T>(0.0));
+ gx11 -= sw11 * (step(T(0), gx11) - T(0.5));
+ gy11 -= sw11 * (step(T(0), gy11) - T(0.5));
+
+ detail::tvec4<T> g0000(gx00.x, gy00.x, gz00.x, gw00.x);
+ detail::tvec4<T> g1000(gx00.y, gy00.y, gz00.y, gw00.y);
+ detail::tvec4<T> g0100(gx00.z, gy00.z, gz00.z, gw00.z);
+ detail::tvec4<T> g1100(gx00.w, gy00.w, gz00.w, gw00.w);
+ detail::tvec4<T> g0010(gx10.x, gy10.x, gz10.x, gw10.x);
+ detail::tvec4<T> g1010(gx10.y, gy10.y, gz10.y, gw10.y);
+ detail::tvec4<T> g0110(gx10.z, gy10.z, gz10.z, gw10.z);
+ detail::tvec4<T> g1110(gx10.w, gy10.w, gz10.w, gw10.w);
+ detail::tvec4<T> g0001(gx01.x, gy01.x, gz01.x, gw01.x);
+ detail::tvec4<T> g1001(gx01.y, gy01.y, gz01.y, gw01.y);
+ detail::tvec4<T> g0101(gx01.z, gy01.z, gz01.z, gw01.z);
+ detail::tvec4<T> g1101(gx01.w, gy01.w, gz01.w, gw01.w);
+ detail::tvec4<T> g0011(gx11.x, gy11.x, gz11.x, gw11.x);
+ detail::tvec4<T> g1011(gx11.y, gy11.y, gz11.y, gw11.y);
+ detail::tvec4<T> g0111(gx11.z, gy11.z, gz11.z, gw11.z);
+ detail::tvec4<T> g1111(gx11.w, gy11.w, gz11.w, gw11.w);
+
+ detail::tvec4<T> norm00 = taylorInvSqrt(detail::tvec4<T>(dot(g0000, g0000), dot(g0100, g0100), dot(g1000, g1000), dot(g1100, g1100)));
+ g0000 *= norm00.x;
+ g0100 *= norm00.y;
+ g1000 *= norm00.z;
+ g1100 *= norm00.w;
+
+ detail::tvec4<T> norm01 = taylorInvSqrt(detail::tvec4<T>(dot(g0001, g0001), dot(g0101, g0101), dot(g1001, g1001), dot(g1101, g1101)));
+ g0001 *= norm01.x;
+ g0101 *= norm01.y;
+ g1001 *= norm01.z;
+ g1101 *= norm01.w;
+
+ detail::tvec4<T> norm10 = taylorInvSqrt(detail::tvec4<T>(dot(g0010, g0010), dot(g0110, g0110), dot(g1010, g1010), dot(g1110, g1110)));
+ g0010 *= norm10.x;
+ g0110 *= norm10.y;
+ g1010 *= norm10.z;
+ g1110 *= norm10.w;
+
+ detail::tvec4<T> norm11 = taylorInvSqrt(detail::tvec4<T>(dot(g0011, g0011), dot(g0111, g0111), dot(g1011, g1011), dot(g1111, g1111)));
+ g0011 *= norm11.x;
+ g0111 *= norm11.y;
+ g1011 *= norm11.z;
+ g1111 *= norm11.w;
+
+ T n0000 = dot(g0000, Pf0);
+ T n1000 = dot(g1000, detail::tvec4<T>(Pf1.x, Pf0.y, Pf0.z, Pf0.w));
+ T n0100 = dot(g0100, detail::tvec4<T>(Pf0.x, Pf1.y, Pf0.z, Pf0.w));
+ T n1100 = dot(g1100, detail::tvec4<T>(Pf1.x, Pf1.y, Pf0.z, Pf0.w));
+ T n0010 = dot(g0010, detail::tvec4<T>(Pf0.x, Pf0.y, Pf1.z, Pf0.w));
+ T n1010 = dot(g1010, detail::tvec4<T>(Pf1.x, Pf0.y, Pf1.z, Pf0.w));
+ T n0110 = dot(g0110, detail::tvec4<T>(Pf0.x, Pf1.y, Pf1.z, Pf0.w));
+ T n1110 = dot(g1110, detail::tvec4<T>(Pf1.x, Pf1.y, Pf1.z, Pf0.w));
+ T n0001 = dot(g0001, detail::tvec4<T>(Pf0.x, Pf0.y, Pf0.z, Pf1.w));
+ T n1001 = dot(g1001, detail::tvec4<T>(Pf1.x, Pf0.y, Pf0.z, Pf1.w));
+ T n0101 = dot(g0101, detail::tvec4<T>(Pf0.x, Pf1.y, Pf0.z, Pf1.w));
+ T n1101 = dot(g1101, detail::tvec4<T>(Pf1.x, Pf1.y, Pf0.z, Pf1.w));
+ T n0011 = dot(g0011, detail::tvec4<T>(Pf0.x, Pf0.y, Pf1.z, Pf1.w));
+ T n1011 = dot(g1011, detail::tvec4<T>(Pf1.x, Pf0.y, Pf1.z, Pf1.w));
+ T n0111 = dot(g0111, detail::tvec4<T>(Pf0.x, Pf1.y, Pf1.z, Pf1.w));
+ T n1111 = dot(g1111, Pf1);
+
+ detail::tvec4<T> fade_xyzw = fade(Pf0);
+ detail::tvec4<T> n_0w = mix(detail::tvec4<T>(n0000, n1000, n0100, n1100), detail::tvec4<T>(n0001, n1001, n0101, n1101), fade_xyzw.w);
+ detail::tvec4<T> n_1w = mix(detail::tvec4<T>(n0010, n1010, n0110, n1110), detail::tvec4<T>(n0011, n1011, n0111, n1111), fade_xyzw.w);
+ detail::tvec4<T> n_zw = mix(n_0w, n_1w, fade_xyzw.z);
+ detail::tvec2<T> n_yzw = mix(detail::tvec2<T>(n_zw.x, n_zw.y), detail::tvec2<T>(n_zw.z, n_zw.w), fade_xyzw.y);
+ T n_xyzw = mix(n_yzw.x, n_yzw.y, fade_xyzw.x);
+ return T(2.2) * n_xyzw;
+ }
+
+ // Classic Perlin noise, periodic variant
+ template <typename T>
+ GLM_FUNC_QUALIFIER T perlin(detail::tvec2<T> const & P, detail::tvec2<T> const & rep)
+ {
+ detail::tvec4<T> Pi = floor(detail::tvec4<T>(P.x, P.y, P.x, P.y)) + detail::tvec4<T>(0.0, 0.0, 1.0, 1.0);
+ detail::tvec4<T> Pf = fract(detail::tvec4<T>(P.x, P.y, P.x, P.y)) - detail::tvec4<T>(0.0, 0.0, 1.0, 1.0);
+ Pi = mod(Pi, detail::tvec4<T>(rep.x, rep.y, rep.x, rep.y)); // To create noise with explicit period
+ Pi = mod(Pi, T(289)); // To avoid truncation effects in permutation
+ detail::tvec4<T> ix(Pi.x, Pi.z, Pi.x, Pi.z);
+ detail::tvec4<T> iy(Pi.y, Pi.y, Pi.w, Pi.w);
+ detail::tvec4<T> fx(Pf.x, Pf.z, Pf.x, Pf.z);
+ detail::tvec4<T> fy(Pf.y, Pf.y, Pf.w, Pf.w);
+
+ detail::tvec4<T> i = permute(permute(ix) + iy);
+
+ detail::tvec4<T> gx = T(2) * fract(i / T(41)) - T(1);
+ detail::tvec4<T> gy = abs(gx) - T(0.5);
+ detail::tvec4<T> tx = floor(gx + T(0.5));
+ gx = gx - tx;
+
+ detail::tvec2<T> g00(gx.x, gy.x);
+ detail::tvec2<T> g10(gx.y, gy.y);
+ detail::tvec2<T> g01(gx.z, gy.z);
+ detail::tvec2<T> g11(gx.w, gy.w);
+
+ detail::tvec4<T> norm = taylorInvSqrt(detail::tvec4<T>(dot(g00, g00), dot(g01, g01), dot(g10, g10), dot(g11, g11)));
+ g00 *= norm.x;
+ g01 *= norm.y;
+ g10 *= norm.z;
+ g11 *= norm.w;
+
+ T n00 = dot(g00, detail::tvec2<T>(fx.x, fy.x));
+ T n10 = dot(g10, detail::tvec2<T>(fx.y, fy.y));
+ T n01 = dot(g01, detail::tvec2<T>(fx.z, fy.z));
+ T n11 = dot(g11, detail::tvec2<T>(fx.w, fy.w));
+
+ detail::tvec2<T> fade_xy = fade(detail::tvec2<T>(Pf.x, Pf.y));
+ detail::tvec2<T> n_x = mix(detail::tvec2<T>(n00, n01), detail::tvec2<T>(n10, n11), fade_xy.x);
+ T n_xy = mix(n_x.x, n_x.y, fade_xy.y);
+ return T(2.3) * n_xy;
+ }
+
+ // Classic Perlin noise, periodic variant
+ template <typename T>
+ GLM_FUNC_QUALIFIER T perlin(detail::tvec3<T> const & P, detail::tvec3<T> const & rep)
+ {
+ detail::tvec3<T> Pi0 = mod(floor(P), rep); // Integer part, modulo period
+ detail::tvec3<T> Pi1 = mod(Pi0 + detail::tvec3<T>(1.0), rep); // Integer part + 1, mod period
+ Pi0 = mod(Pi0, T(289));
+ Pi1 = mod(Pi1, T(289));
+ detail::tvec3<T> Pf0 = fract(P); // Fractional part for interpolation
+ detail::tvec3<T> Pf1 = Pf0 - detail::tvec3<T>(1.0); // Fractional part - 1.0
+ detail::tvec4<T> ix = detail::tvec4<T>(Pi0.x, Pi1.x, Pi0.x, Pi1.x);
+ detail::tvec4<T> iy = detail::tvec4<T>(Pi0.y, Pi0.y, Pi1.y, Pi1.y);
+ detail::tvec4<T> iz0(Pi0.z);
+ detail::tvec4<T> iz1(Pi1.z);
+
+ detail::tvec4<T> ixy = permute(permute(ix) + iy);
+ detail::tvec4<T> ixy0 = permute(ixy + iz0);
+ detail::tvec4<T> ixy1 = permute(ixy + iz1);
+
+ detail::tvec4<T> gx0 = ixy0 / T(7);
+ detail::tvec4<T> gy0 = fract(floor(gx0) / T(7)) - T(0.5);
+ gx0 = fract(gx0);
+ detail::tvec4<T> gz0 = detail::tvec4<T>(0.5) - abs(gx0) - abs(gy0);
+ detail::tvec4<T> sz0 = step(gz0, detail::tvec4<T>(0));
+ gx0 -= sz0 * (step(0.0, gx0) - T(0.5));
+ gy0 -= sz0 * (step(0.0, gy0) - T(0.5));
+
+ detail::tvec4<T> gx1 = ixy1 / T(7);
+ detail::tvec4<T> gy1 = fract(floor(gx1) / T(7)) - T(0.5);
+ gx1 = fract(gx1);
+ detail::tvec4<T> gz1 = detail::tvec4<T>(0.5) - abs(gx1) - abs(gy1);
+ detail::tvec4<T> sz1 = step(gz1, detail::tvec4<T>(0.0));
+ gx1 -= sz1 * (step(0.0, gx1) - T(0.5));
+ gy1 -= sz1 * (step(0.0, gy1) - T(0.5));
+
+ detail::tvec3<T> g000 = detail::tvec3<T>(gx0.x, gy0.x, gz0.x);
+ detail::tvec3<T> g100 = detail::tvec3<T>(gx0.y, gy0.y, gz0.y);
+ detail::tvec3<T> g010 = detail::tvec3<T>(gx0.z, gy0.z, gz0.z);
+ detail::tvec3<T> g110 = detail::tvec3<T>(gx0.w, gy0.w, gz0.w);
+ detail::tvec3<T> g001 = detail::tvec3<T>(gx1.x, gy1.x, gz1.x);
+ detail::tvec3<T> g101 = detail::tvec3<T>(gx1.y, gy1.y, gz1.y);
+ detail::tvec3<T> g011 = detail::tvec3<T>(gx1.z, gy1.z, gz1.z);
+ detail::tvec3<T> g111 = detail::tvec3<T>(gx1.w, gy1.w, gz1.w);
+
+ detail::tvec4<T> norm0 = taylorInvSqrt(detail::tvec4<T>(dot(g000, g000), dot(g010, g010), dot(g100, g100), dot(g110, g110)));
+ g000 *= norm0.x;
+ g010 *= norm0.y;
+ g100 *= norm0.z;
+ g110 *= norm0.w;
+ detail::tvec4<T> norm1 = taylorInvSqrt(detail::tvec4<T>(dot(g001, g001), dot(g011, g011), dot(g101, g101), dot(g111, g111)));
+ g001 *= norm1.x;
+ g011 *= norm1.y;
+ g101 *= norm1.z;
+ g111 *= norm1.w;
+
+ T n000 = dot(g000, Pf0);
+ T n100 = dot(g100, detail::tvec3<T>(Pf1.x, Pf0.y, Pf0.z));
+ T n010 = dot(g010, detail::tvec3<T>(Pf0.x, Pf1.y, Pf0.z));
+ T n110 = dot(g110, detail::tvec3<T>(Pf1.x, Pf1.y, Pf0.z));
+ T n001 = dot(g001, detail::tvec3<T>(Pf0.x, Pf0.y, Pf1.z));
+ T n101 = dot(g101, detail::tvec3<T>(Pf1.x, Pf0.y, Pf1.z));
+ T n011 = dot(g011, detail::tvec3<T>(Pf0.x, Pf1.y, Pf1.z));
+ T n111 = dot(g111, Pf1);
+
+ detail::tvec3<T> fade_xyz = fade(Pf0);
+ detail::tvec4<T> n_z = mix(detail::tvec4<T>(n000, n100, n010, n110), detail::tvec4<T>(n001, n101, n011, n111), fade_xyz.z);
+ detail::tvec2<T> n_yz = mix(detail::tvec2<T>(n_z.x, n_z.y), detail::tvec2<T>(n_z.z, n_z.w), fade_xyz.y);
+ T n_xyz = mix(n_yz.x, n_yz.y, fade_xyz.x);
+ return T(2.2) * n_xyz;
+ }
+
+ // Classic Perlin noise, periodic version
+ template <typename T>
+ GLM_FUNC_QUALIFIER T perlin(detail::tvec4<T> const & P, detail::tvec4<T> const & rep)
+ {
+ detail::tvec4<T> Pi0 = mod(floor(P), rep); // Integer part modulo rep
+ detail::tvec4<T> Pi1 = mod(Pi0 + T(1), rep); // Integer part + 1 mod rep
+ detail::tvec4<T> Pf0 = fract(P); // Fractional part for interpolation
+ detail::tvec4<T> Pf1 = Pf0 - T(1); // Fractional part - 1.0
+ detail::tvec4<T> ix = detail::tvec4<T>(Pi0.x, Pi1.x, Pi0.x, Pi1.x);
+ detail::tvec4<T> iy = detail::tvec4<T>(Pi0.y, Pi0.y, Pi1.y, Pi1.y);
+ detail::tvec4<T> iz0(Pi0.z);
+ detail::tvec4<T> iz1(Pi1.z);
+ detail::tvec4<T> iw0(Pi0.w);
+ detail::tvec4<T> iw1(Pi1.w);
+
+ detail::tvec4<T> ixy = permute(permute(ix) + iy);
+ detail::tvec4<T> ixy0 = permute(ixy + iz0);
+ detail::tvec4<T> ixy1 = permute(ixy + iz1);
+ detail::tvec4<T> ixy00 = permute(ixy0 + iw0);
+ detail::tvec4<T> ixy01 = permute(ixy0 + iw1);
+ detail::tvec4<T> ixy10 = permute(ixy1 + iw0);
+ detail::tvec4<T> ixy11 = permute(ixy1 + iw1);
+
+ detail::tvec4<T> gx00 = ixy00 / T(7);
+ detail::tvec4<T> gy00 = floor(gx00) / T(7);
+ detail::tvec4<T> gz00 = floor(gy00) / T(6);
+ gx00 = fract(gx00) - T(0.5);
+ gy00 = fract(gy00) - T(0.5);
+ gz00 = fract(gz00) - T(0.5);
+ detail::tvec4<T> gw00 = detail::tvec4<T>(0.75) - abs(gx00) - abs(gy00) - abs(gz00);
+ detail::tvec4<T> sw00 = step(gw00, detail::tvec4<T>(0));
+ gx00 -= sw00 * (step(0.0, gx00) - T(0.5));
+ gy00 -= sw00 * (step(0.0, gy00) - T(0.5));
+
+ detail::tvec4<T> gx01 = ixy01 / T(7);
+ detail::tvec4<T> gy01 = floor(gx01) / T(7);
+ detail::tvec4<T> gz01 = floor(gy01) / T(6);
+ gx01 = fract(gx01) - T(0.5);
+ gy01 = fract(gy01) - T(0.5);
+ gz01 = fract(gz01) - T(0.5);
+ detail::tvec4<T> gw01 = detail::tvec4<T>(0.75) - abs(gx01) - abs(gy01) - abs(gz01);
+ detail::tvec4<T> sw01 = step(gw01, detail::tvec4<T>(0.0));
+ gx01 -= sw01 * (step(0.0, gx01) - T(0.5));
+ gy01 -= sw01 * (step(0.0, gy01) - T(0.5));
+
+ detail::tvec4<T> gx10 = ixy10 / T(7);
+ detail::tvec4<T> gy10 = floor(gx10) / T(7);
+ detail::tvec4<T> gz10 = floor(gy10) / T(6);
+ gx10 = fract(gx10) - T(0.5);
+ gy10 = fract(gy10) - T(0.5);
+ gz10 = fract(gz10) - T(0.5);
+ detail::tvec4<T> gw10 = detail::tvec4<T>(0.75) - abs(gx10) - abs(gy10) - abs(gz10);
+ detail::tvec4<T> sw10 = step(gw10, detail::tvec4<T>(0.0));
+ gx10 -= sw10 * (step(0.0, gx10) - T(0.5));
+ gy10 -= sw10 * (step(0.0, gy10) - T(0.5));
+
+ detail::tvec4<T> gx11 = ixy11 / T(7);
+ detail::tvec4<T> gy11 = floor(gx11) / T(7);
+ detail::tvec4<T> gz11 = floor(gy11) / T(6);
+ gx11 = fract(gx11) - T(0.5);
+ gy11 = fract(gy11) - T(0.5);
+ gz11 = fract(gz11) - T(0.5);
+ detail::tvec4<T> gw11 = detail::tvec4<T>(0.75) - abs(gx11) - abs(gy11) - abs(gz11);
+ detail::tvec4<T> sw11 = step(gw11, detail::tvec4<T>(0.0));
+ gx11 -= sw11 * (step(0.0, gx11) - T(0.5));
+ gy11 -= sw11 * (step(0.0, gy11) - T(0.5));
+
+ detail::tvec4<T> g0000(gx00.x, gy00.x, gz00.x, gw00.x);
+ detail::tvec4<T> g1000(gx00.y, gy00.y, gz00.y, gw00.y);
+ detail::tvec4<T> g0100(gx00.z, gy00.z, gz00.z, gw00.z);
+ detail::tvec4<T> g1100(gx00.w, gy00.w, gz00.w, gw00.w);
+ detail::tvec4<T> g0010(gx10.x, gy10.x, gz10.x, gw10.x);
+ detail::tvec4<T> g1010(gx10.y, gy10.y, gz10.y, gw10.y);
+ detail::tvec4<T> g0110(gx10.z, gy10.z, gz10.z, gw10.z);
+ detail::tvec4<T> g1110(gx10.w, gy10.w, gz10.w, gw10.w);
+ detail::tvec4<T> g0001(gx01.x, gy01.x, gz01.x, gw01.x);
+ detail::tvec4<T> g1001(gx01.y, gy01.y, gz01.y, gw01.y);
+ detail::tvec4<T> g0101(gx01.z, gy01.z, gz01.z, gw01.z);
+ detail::tvec4<T> g1101(gx01.w, gy01.w, gz01.w, gw01.w);
+ detail::tvec4<T> g0011(gx11.x, gy11.x, gz11.x, gw11.x);
+ detail::tvec4<T> g1011(gx11.y, gy11.y, gz11.y, gw11.y);
+ detail::tvec4<T> g0111(gx11.z, gy11.z, gz11.z, gw11.z);
+ detail::tvec4<T> g1111(gx11.w, gy11.w, gz11.w, gw11.w);
+
+ detail::tvec4<T> norm00 = taylorInvSqrt(detail::tvec4<T>(dot(g0000, g0000), dot(g0100, g0100), dot(g1000, g1000), dot(g1100, g1100)));
+ g0000 *= norm00.x;
+ g0100 *= norm00.y;
+ g1000 *= norm00.z;
+ g1100 *= norm00.w;
+
+ detail::tvec4<T> norm01 = taylorInvSqrt(detail::tvec4<T>(dot(g0001, g0001), dot(g0101, g0101), dot(g1001, g1001), dot(g1101, g1101)));
+ g0001 *= norm01.x;
+ g0101 *= norm01.y;
+ g1001 *= norm01.z;
+ g1101 *= norm01.w;
+
+ detail::tvec4<T> norm10 = taylorInvSqrt(detail::tvec4<T>(dot(g0010, g0010), dot(g0110, g0110), dot(g1010, g1010), dot(g1110, g1110)));
+ g0010 *= norm10.x;
+ g0110 *= norm10.y;
+ g1010 *= norm10.z;
+ g1110 *= norm10.w;
+
+ detail::tvec4<T> norm11 = taylorInvSqrt(detail::tvec4<T>(dot(g0011, g0011), dot(g0111, g0111), dot(g1011, g1011), dot(g1111, g1111)));
+ g0011 *= norm11.x;
+ g0111 *= norm11.y;
+ g1011 *= norm11.z;
+ g1111 *= norm11.w;
+
+ T n0000 = dot(g0000, Pf0);
+ T n1000 = dot(g1000, detail::tvec4<T>(Pf1.x, Pf0.y, Pf0.z, Pf0.w));
+ T n0100 = dot(g0100, detail::tvec4<T>(Pf0.x, Pf1.y, Pf0.z, Pf0.w));
+ T n1100 = dot(g1100, detail::tvec4<T>(Pf1.x, Pf1.y, Pf0.z, Pf0.w));
+ T n0010 = dot(g0010, detail::tvec4<T>(Pf0.x, Pf0.y, Pf1.z, Pf0.w));
+ T n1010 = dot(g1010, detail::tvec4<T>(Pf1.x, Pf0.y, Pf1.z, Pf0.w));
+ T n0110 = dot(g0110, detail::tvec4<T>(Pf0.x, Pf1.y, Pf1.z, Pf0.w));
+ T n1110 = dot(g1110, detail::tvec4<T>(Pf1.x, Pf1.y, Pf1.z, Pf0.w));
+ T n0001 = dot(g0001, detail::tvec4<T>(Pf0.x, Pf0.y, Pf0.z, Pf1.w));
+ T n1001 = dot(g1001, detail::tvec4<T>(Pf1.x, Pf0.y, Pf0.z, Pf1.w));
+ T n0101 = dot(g0101, detail::tvec4<T>(Pf0.x, Pf1.y, Pf0.z, Pf1.w));
+ T n1101 = dot(g1101, detail::tvec4<T>(Pf1.x, Pf1.y, Pf0.z, Pf1.w));
+ T n0011 = dot(g0011, detail::tvec4<T>(Pf0.x, Pf0.y, Pf1.z, Pf1.w));
+ T n1011 = dot(g1011, detail::tvec4<T>(Pf1.x, Pf0.y, Pf1.z, Pf1.w));
+ T n0111 = dot(g0111, detail::tvec4<T>(Pf0.x, Pf1.y, Pf1.z, Pf1.w));
+ T n1111 = dot(g1111, Pf1);
+
+ detail::tvec4<T> fade_xyzw = fade(Pf0);
+ detail::tvec4<T> n_0w = mix(detail::tvec4<T>(n0000, n1000, n0100, n1100), detail::tvec4<T>(n0001, n1001, n0101, n1101), fade_xyzw.w);
+ detail::tvec4<T> n_1w = mix(detail::tvec4<T>(n0010, n1010, n0110, n1110), detail::tvec4<T>(n0011, n1011, n0111, n1111), fade_xyzw.w);
+ detail::tvec4<T> n_zw = mix(n_0w, n_1w, fade_xyzw.z);
+ detail::tvec2<T> n_yzw = mix(detail::tvec2<T>(n_zw.x, n_zw.y), detail::tvec2<T>(n_zw.z, n_zw.w), fade_xyzw.y);
+ T n_xyzw = mix(n_yzw.x, n_yzw.y, fade_xyzw.x);
+ return T(2.2) * n_xyzw;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER T simplex(glm::detail::tvec2<T> const & v)
+ {
+ detail::tvec4<T> const C = detail::tvec4<T>(
+ T( 0.211324865405187), // (3.0 - sqrt(3.0)) / 6.0
+ T( 0.366025403784439), // 0.5 * (sqrt(3.0) - 1.0)
+ T(-0.577350269189626), // -1.0 + 2.0 * C.x
+ T( 0.024390243902439)); // 1.0 / 41.0
+
+ // First corner
+ detail::tvec2<T> i = floor(v + dot(v, detail::tvec2<T>(C[1])));
+ detail::tvec2<T> x0 = v - i + dot(i, detail::tvec2<T>(C[0]));
+
+ // Other corners
+ //i1.x = step( x0.y, x0.x ); // x0.x > x0.y ? 1.0 : 0.0
+ //i1.y = 1.0 - i1.x;
+ detail::tvec2<T> i1 = (x0.x > x0.y) ? detail::tvec2<T>(1, 0) : detail::tvec2<T>(0, 1);
+ // x0 = x0 - 0.0 + 0.0 * C.xx ;
+ // x1 = x0 - i1 + 1.0 * C.xx ;
+ // x2 = x0 - 1.0 + 2.0 * C.xx ;
+ detail::tvec4<T> x12 = detail::tvec4<T>(x0.x, x0.y, x0.x, x0.y) + detail::tvec4<T>(C.x, C.x, C.z, C.z);
+ x12 = detail::tvec4<T>(detail::tvec2<T>(x12) - i1, x12.z, x12.w);
+
+ // Permutations
+ i = mod(i, T(289)); // Avoid truncation effects in permutation
+ detail::tvec3<T> p = permute(
+ permute(i.y + detail::tvec3<T>(T(0), i1.y, T(1)))
+ + i.x + detail::tvec3<T>(T(0), i1.x, T(1)));
+
+ detail::tvec3<T> m = max(T(0.5) - detail::tvec3<T>(
+ dot(x0, x0),
+ dot(detail::tvec2<T>(x12.x, x12.y), detail::tvec2<T>(x12.x, x12.y)),
+ dot(detail::tvec2<T>(x12.z, x12.w), detail::tvec2<T>(x12.z, x12.w))), T(0));
+ m = m * m ;
+ m = m * m ;
+
+ // Gradients: 41 points uniformly over a line, mapped onto a diamond.
+ // The ring size 17*17 = 289 is close to a multiple of 41 (41*7 = 287)
+
+ detail::tvec3<T> x = T(2) * fract(p * C.w) - T(1);
+ detail::tvec3<T> h = abs(x) - T(0.5);
+ detail::tvec3<T> ox = floor(x + T(0.5));
+ detail::tvec3<T> a0 = x - ox;
+
+ // Normalise gradients implicitly by scaling m
+ // Inlined for speed: m *= taylorInvSqrt( a0*a0 + h*h );
+ m *= T(1.79284291400159) - T(0.85373472095314) * (a0 * a0 + h * h);
+
+ // Compute final noise value at P
+ detail::tvec3<T> g;
+ g.x = a0.x * x0.x + h.x * x0.y;
+ //g.yz = a0.yz * x12.xz + h.yz * x12.yw;
+ g.y = a0.y * x12.x + h.y * x12.y;
+ g.z = a0.z * x12.z + h.z * x12.w;
+ return T(130) * dot(m, g);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER T simplex(detail::tvec3<T> const & v)
+ {
+ detail::tvec2<T> const C = detail::tvec2<T>(1.0 / 6.0, 1.0 / 3.0);
+ detail::tvec4<T> const D = detail::tvec4<T>(0.0, 0.5, 1.0, 2.0);
+
+ // First corner
+ detail::tvec3<T> i = floor(v + dot(v, detail::tvec3<T>(C.y)));
+ detail::tvec3<T> x0 = v - i + dot(i, detail::tvec3<T>(C.x));
+
+ // Other corners
+ detail::tvec3<T> g = step(detail::tvec3<T>(x0.y, x0.z, x0.x), detail::tvec3<T>(x0.x, x0.y, x0.z));
+ detail::tvec3<T> l = T(1) - g;
+ detail::tvec3<T> i1 = min(detail::tvec3<T>(g.x, g.y, g.z), detail::tvec3<T>(l.z, l.x, l.y));
+ detail::tvec3<T> i2 = max(detail::tvec3<T>(g.x, g.y, g.z), detail::tvec3<T>(l.z, l.x, l.y));
+
+ // x0 = x0 - 0.0 + 0.0 * C.xxx;
+ // x1 = x0 - i1 + 1.0 * C.xxx;
+ // x2 = x0 - i2 + 2.0 * C.xxx;
+ // x3 = x0 - 1.0 + 3.0 * C.xxx;
+ detail::tvec3<T> x1 = x0 - i1 + C.x;
+ detail::tvec3<T> x2 = x0 - i2 + C.y; // 2.0*C.x = 1/3 = C.y
+ detail::tvec3<T> x3 = x0 - D.y; // -1.0+3.0*C.x = -0.5 = -D.y
+
+ // Permutations
+ i = mod(i, T(289));
+ detail::tvec4<T> p = permute(permute(permute(
+ i.z + detail::tvec4<T>(0.0, i1.z, i2.z, 1.0)) +
+ i.y + detail::tvec4<T>(0.0, i1.y, i2.y, 1.0)) +
+ i.x + detail::tvec4<T>(0.0, i1.x, i2.x, 1.0));
+
+ // Gradients: 7x7 points over a square, mapped onto an octahedron.
+ // The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294)
+ T n_ = T(0.142857142857); // 1.0/7.0
+ detail::tvec3<T> ns = n_ * detail::tvec3<T>(D.w, D.y, D.z) - detail::tvec3<T>(D.x, D.z, D.x);
+
+ detail::tvec4<T> j = p - T(49) * floor(p * ns.z * ns.z); // mod(p,7*7)
+
+ detail::tvec4<T> x_ = floor(j * ns.z);
+ detail::tvec4<T> y_ = floor(j - T(7) * x_); // mod(j,N)
+
+ detail::tvec4<T> x = x_ * ns.x + ns.y;
+ detail::tvec4<T> y = y_ * ns.x + ns.y;
+ detail::tvec4<T> h = T(1) - abs(x) - abs(y);
+
+ detail::tvec4<T> b0 = detail::tvec4<T>(x.x, x.y, y.x, y.y);
+ detail::tvec4<T> b1 = detail::tvec4<T>(x.z, x.w, y.z, y.w);
+
+ //vec4 s0 = vec4(lessThan(b0,0.0))*2.0 - 1.0;
+ //vec4 s1 = vec4(lessThan(b1,0.0))*2.0 - 1.0;
+ detail::tvec4<T> s0 = floor(b0) * T(2) + T(1);
+ detail::tvec4<T> s1 = floor(b1) * T(2) + T(1);
+ detail::tvec4<T> sh = -step(h, detail::tvec4<T>(0));
+
+ detail::tvec4<T> a0 = b0 + s0 * detail::tvec4<T>(sh.x, sh.x, sh.y, sh.y);
+ detail::tvec4<T> a1 = b1 + s1 * detail::tvec4<T>(sh.z, sh.z, sh.w, sh.w);
+
+ detail::tvec3<T> p0 = vec3(a0.x, a0.y, h.x);
+ detail::tvec3<T> p1 = vec3(a0.z, a0.w, h.y);
+ detail::tvec3<T> p2 = vec3(a1.x, a1.y, h.z);
+ detail::tvec3<T> p3 = vec3(a1.z, a1.w, h.w);
+
+ //Normalise gradients
+ detail::tvec4<T> norm = taylorInvSqrt(detail::tvec4<T>(
+ dot(p0, p0),
+ dot(p1, p1),
+ dot(p2, p2),
+ dot(p3, p3)));
+ p0 *= norm.x;
+ p1 *= norm.y;
+ p2 *= norm.z;
+ p3 *= norm.w;
+
+ // Mix final noise value
+ vec4 m = max(T(0.6) - detail::tvec4<T>(
+ dot(x0, x0),
+ dot(x1, x1),
+ dot(x2, x2),
+ dot(x3, x3)), T(0));
+ m = m * m;
+ return T(42) * dot(m * m, detail::tvec4<T>(
+ dot(p0, x0),
+ dot(p1, x1),
+ dot(p2, x2),
+ dot(p3, x3)));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER T simplex(detail::tvec4<T> const & v)
+ {
+ detail::tvec4<T> const C(
+ 0.138196601125011, // (5 - sqrt(5))/20 G4
+ 0.276393202250021, // 2 * G4
+ 0.414589803375032, // 3 * G4
+ -0.447213595499958); // -1 + 4 * G4
+
+ // (sqrt(5) - 1)/4 = F4, used once below
+ T const F4 = T(0.309016994374947451);
+
+ // First corner
+ detail::tvec4<T> i = floor(v + dot(v, vec4(F4)));
+ detail::tvec4<T> x0 = v - i + dot(i, vec4(C.x));
+
+ // Other corners
+
+ // Rank sorting originally contributed by Bill Licea-Kane, AMD (formerly ATI)
+ detail::tvec4<T> i0;
+ detail::tvec3<T> isX = step(detail::tvec3<T>(x0.y, x0.z, x0.w), detail::tvec3<T>(x0.x));
+ detail::tvec3<T> isYZ = step(detail::tvec3<T>(x0.z, x0.w, x0.w), detail::tvec3<T>(x0.y, x0.y, x0.z));
+ // i0.x = dot(isX, vec3(1.0));
+ //i0.x = isX.x + isX.y + isX.z;
+ //i0.yzw = T(1) - isX;
+ i0 = detail::tvec4<T>(isX.x + isX.y + isX.z, T(1) - isX);
+ // i0.y += dot(isYZ.xy, vec2(1.0));
+ i0.y += isYZ.x + isYZ.y;
+ //i0.zw += 1.0 - detail::tvec2<T>(isYZ.x, isYZ.y);
+ i0.z += T(1) - isYZ.x;
+ i0.w += T(1) - isYZ.y;
+ i0.z += isYZ.z;
+ i0.w += T(1) - isYZ.z;
+
+ // i0 now contains the unique values 0,1,2,3 in each channel
+ detail::tvec4<T> i3 = clamp(i0, 0.0, 1.0);
+ detail::tvec4<T> i2 = clamp(i0 - 1.0, 0.0, 1.0);
+ detail::tvec4<T> i1 = clamp(i0 - 2.0, 0.0, 1.0);
+
+ // x0 = x0 - 0.0 + 0.0 * C.xxxx
+ // x1 = x0 - i1 + 0.0 * C.xxxx
+ // x2 = x0 - i2 + 0.0 * C.xxxx
+ // x3 = x0 - i3 + 0.0 * C.xxxx
+ // x4 = x0 - 1.0 + 4.0 * C.xxxx
+ detail::tvec4<T> x1 = x0 - i1 + C.x;
+ detail::tvec4<T> x2 = x0 - i2 + C.y;
+ detail::tvec4<T> x3 = x0 - i3 + C.z;
+ detail::tvec4<T> x4 = x0 + C.w;
+
+ // Permutations
+ i = mod(i, T(289));
+ T j0 = permute(permute(permute(permute(i.w) + i.z) + i.y) + i.x);
+ detail::tvec4<T> j1 = permute(permute(permute(permute(
+ i.w + detail::tvec4<T>(i1.w, i2.w, i3.w, T(1)))
+ + i.z + detail::tvec4<T>(i1.z, i2.z, i3.z, T(1)))
+ + i.y + detail::tvec4<T>(i1.y, i2.y, i3.y, T(1)))
+ + i.x + detail::tvec4<T>(i1.x, i2.x, i3.x, T(1)));
+
+ // Gradients: 7x7x6 points over a cube, mapped onto a 4-cross polytope
+ // 7*7*6 = 294, which is close to the ring size 17*17 = 289.
+ detail::tvec4<T> ip = detail::tvec4<T>(T(1) / T(294), T(1) / T(49), T(1) / T(7), T(0));
+
+ detail::tvec4<T> p0 = grad4(j0, ip);
+ detail::tvec4<T> p1 = grad4(j1.x, ip);
+ detail::tvec4<T> p2 = grad4(j1.y, ip);
+ detail::tvec4<T> p3 = grad4(j1.z, ip);
+ detail::tvec4<T> p4 = grad4(j1.w, ip);
+
+ // Normalise gradients
+ detail::tvec4<T> norm = taylorInvSqrt(detail::tvec4<T>(dot(p0, p0), dot(p1, p1), dot(p2, p2), dot(p3, p3)));
+ p0 *= norm.x;
+ p1 *= norm.y;
+ p2 *= norm.z;
+ p3 *= norm.w;
+ p4 *= taylorInvSqrt(dot(p4, p4));
+
+ // Mix contributions from the five corners
+ detail::tvec3<T> m0 = max(T(0.6) - detail::tvec3<T>(dot(x0, x0), dot(x1, x1), dot(x2, x2)), T(0));
+ detail::tvec2<T> m1 = max(T(0.6) - detail::tvec2<T>(dot(x3, x3), dot(x4, x4) ), T(0));
+ m0 = m0 * m0;
+ m1 = m1 * m1;
+ return T(49) *
+ (dot(m0 * m0, detail::tvec3<T>(dot(p0, x0), dot(p1, x1), dot(p2, x2))) +
+ dot(m1 * m1, detail::tvec2<T>(dot(p3, x3), dot(p4, x4))));
+ }
+
+}//namespace noise
+}//namespace gtx
+}//namespace glm
diff --git a/src/glm/gtx/norm.hpp b/src/glm/gtx/norm.hpp
new file mode 100644
index 0000000..af0d630
--- /dev/null
+++ b/src/glm/gtx/norm.hpp
@@ -0,0 +1,143 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2005-12-21
+// Updated : 2008-07-24
+// Licence : This source is under MIT License
+// File : glm/gtx/norm.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+// - GLM_GTX_quaternion
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// ToDo:
+// - Study the validity of the notion of length2 to quaternion
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_gtx_norm
+#define glm_gtx_norm
+
+// Dependency:
+#include "../glm.hpp"
+#include "../gtx/quaternion.hpp"
+
+#if(defined(GLM_MESSAGES) && !defined(glm_ext))
+# pragma message("GLM: GLM_GTX_norm extension included")
+#endif
+
+namespace glm{
+namespace gtx{
+namespace norm ///< GLM_GTX_norm extension: Various way to compute vector norms.
+{
+ /// \addtogroup gtx_norm
+ /// @{
+
+ //! Returns the squared length of x.
+ //! From GLM_GTX_norm extension.
+ template <typename T>
+ T length2(
+ const T x);
+
+ //! Returns the squared length of x.
+ //! From GLM_GTX_norm extension.
+ template <typename T>
+ T length2(
+ const detail::tvec2<T> & x);
+
+ //! Returns the squared length of x.
+ //! From GLM_GTX_norm extension.
+ template <typename T>
+ T length2(
+ const detail::tvec3<T>& x);
+
+ //! Returns the squared length of x.
+ //! From GLM_GTX_norm extension.
+ template <typename T>
+ T length2(
+ const detail::tvec4<T>& x);
+
+ //! Returns the squared length of x.
+ //! From GLM_GTX_norm extension.
+ template <typename T>
+ T length2(
+ const detail::tquat<T>& q);
+
+ //! Returns the squared distance between p0 and p1, i.e., length(p0 - p1).
+ //! From GLM_GTX_norm extension.
+ template <typename T>
+ T distance2(
+ const T p0,
+ const T p1);
+
+ //! Returns the squared distance between p0 and p1, i.e., length(p0 - p1).
+ //! From GLM_GTX_norm extension.
+ template <typename T>
+ T distance2(
+ const detail::tvec2<T>& p0,
+ const detail::tvec2<T>& p1);
+
+ //! Returns the squared distance between p0 and p1, i.e., length(p0 - p1).
+ //! From GLM_GTX_norm extension.
+ template <typename T>
+ T distance2(
+ const detail::tvec3<T>& p0,
+ const detail::tvec3<T>& p1);
+
+ //! Returns the squared distance between p0 and p1, i.e., length(p0 - p1).
+ //! From GLM_GTX_norm extension.
+ template <typename T>
+ T distance2(
+ const detail::tvec4<T>& p0,
+ const detail::tvec4<T>& p1);
+
+ //! Returns the L1 norm between x and y.
+ //! From GLM_GTX_norm extension.
+ template <typename T>
+ T l1Norm(
+ const detail::tvec3<T>& x,
+ const detail::tvec3<T>& y);
+
+ //! Returns the L1 norm of v.
+ //! From GLM_GTX_norm extension.
+ template <typename T>
+ T l1Norm(
+ const detail::tvec3<T>& v);
+
+ //! Returns the L2 norm between x and y.
+ //! From GLM_GTX_norm extension.
+ template <typename T>
+ T l2Norm(
+ const detail::tvec3<T>& x,
+ const detail::tvec3<T>& y);
+
+ //! Returns the L2 norm of v.
+ //! From GLM_GTX_norm extension.
+ template <typename T>
+ T l2Norm(
+ const detail::tvec3<T>& x);
+
+ //! Returns the L norm between x and y.
+ //! From GLM_GTX_norm extension.
+ template <typename T>
+ T lxNorm(
+ const detail::tvec3<T>& x,
+ const detail::tvec3<T>& y,
+ unsigned int Depth);
+
+ //! Returns the L norm of v.
+ //! From GLM_GTX_norm extension.
+ template <typename T>
+ T lxNorm(
+ const detail::tvec3<T>& x,
+ unsigned int Depth);
+
+ /// @}
+}//namespace norm
+}//namespace gtx
+}//namespace glm
+
+#include "norm.inl"
+
+namespace glm{using namespace gtx::norm;}
+
+#endif//glm_gtx_norm
diff --git a/src/glm/gtx/norm.inl b/src/glm/gtx/norm.inl
new file mode 100644
index 0000000..c0713a3
--- /dev/null
+++ b/src/glm/gtx/norm.inl
@@ -0,0 +1,130 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2005-12-21
+// Updated : 2008-07-24
+// Licence : This source is under MIT License
+// File : glm/gtx/norm.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm{
+namespace gtx{
+namespace norm
+{
+ template <typename T>
+ GLM_FUNC_QUALIFIER T length2(
+ const T x)
+ {
+ return x * x;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER T length2(
+ const detail::tvec2<T>& x)
+ {
+ return dot(x, x);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER T length2(
+ const detail::tvec3<T>& x)
+ {
+ return dot(x, x);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER T length2(
+ const detail::tvec4<T>& x)
+ {
+ return dot(x, x);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER T length2(
+ const detail::tquat<T>& q)
+ {
+ return q.x * q.x + q.y * q.y + q.z * q.z + q.w * q.w;
+ }
+
+ template <typename T>
+ T distance2(
+ const T p0,
+ const T p1)
+ {
+ return length2(p1 - p0);
+ }
+
+ template <typename T>
+ T distance2(
+ const detail::tvec2<T>& p0,
+ const detail::tvec2<T>& p1)
+ {
+ return length2(p1 - p0);
+ }
+
+ template <typename T>
+ T distance2(
+ const detail::tvec3<T>& p0,
+ const detail::tvec3<T>& p1)
+ {
+ return length2(p1 - p0);
+ }
+
+ template <typename T>
+ T distance2(
+ const detail::tvec4<T>& p0,
+ const detail::tvec4<T>& p1)
+ {
+ return length2(p1 - p0);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER T l1Norm(
+ const detail::tvec3<T>& a,
+ const detail::tvec3<T>& b)
+ {
+ return abs(b.x - a.x) + abs(b.y - a.y) + abs(b.z - a.z);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER T l1Norm(
+ const detail::tvec3<T>& v)
+ {
+ return abs(v.x) + abs(v.y) + abs(v.z);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER T l2Norm(
+ const detail::tvec3<T>& a,
+ const detail::tvec3<T>& b)
+ {
+ return length(b - a);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER T l2Norm(
+ const detail::tvec3<T>& v)
+ {
+ return length(v);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER T lxNorm(
+ const detail::tvec3<T>& x,
+ const detail::tvec3<T>& y,
+ unsigned int Depth)
+ {
+ return pow(pow(y.x - x.x, T(Depth)) + pow(y.y - x.y, T(Depth)) + pow(y.z - x.z, T(Depth)), T(1) / T(Depth));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER T lxNorm(
+ const detail::tvec3<T>& v,
+ unsigned int Depth)
+ {
+ return pow(pow(v.x, T(Depth)) + pow(v.y, T(Depth)) + pow(v.z, T(Depth)), T(1) / T(Depth));
+ }
+
+}//namespace norm
+}//namespace gtx
+}//namespace glm
diff --git a/src/glm/gtx/normal.hpp b/src/glm/gtx/normal.hpp
new file mode 100644
index 0000000..49ca4c4
--- /dev/null
+++ b/src/glm/gtx/normal.hpp
@@ -0,0 +1,47 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2005-12-21
+// Updated : 2006-11-13
+// Licence : This source is under MIT License
+// File : glm/gtx/normal.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_gtx_normal
+#define glm_gtx_normal
+
+// Dependency:
+#include "../glm.hpp"
+
+#if(defined(GLM_MESSAGES) && !defined(glm_ext))
+# pragma message("GLM: GLM_GTX_normal extension included")
+#endif
+
+namespace glm{
+namespace gtx{
+namespace normal ///< GLM_GTX_normal extension: Compute the normal of a triangle.
+{
+ /// \addtogroup gtx_normal
+ /// @{
+
+ //! Computes triangle normal from triangle points.
+ //! From GLM_GTX_normal extension.
+ template <typename T>
+ detail::tvec3<T> triangleNormal(
+ detail::tvec3<T> const & p1,
+ detail::tvec3<T> const & p2,
+ detail::tvec3<T> const & p3);
+
+ /// @}
+}//namespace normal
+}//namespace gtx
+}//namespace glm
+
+#include "normal.inl"
+
+namespace glm{using namespace gtx::normal;}
+
+#endif//glm_gtx_normal
diff --git a/src/glm/gtx/normal.inl b/src/glm/gtx/normal.inl
new file mode 100644
index 0000000..8414f51
--- /dev/null
+++ b/src/glm/gtx/normal.inl
@@ -0,0 +1,27 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2005-12-21
+// Updated : 2005-12-21
+// Licence : This source is under MIT License
+// File : glm/gtx/normal.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm{
+namespace gtx{
+namespace normal{
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> triangleNormal
+ (
+ detail::tvec3<T> const & p1,
+ detail::tvec3<T> const & p2,
+ detail::tvec3<T> const & p3
+ )
+ {
+ return normalize(cross(p1 - p2, p1 - p3));
+ }
+
+}//namespace normal
+}//namespace gtx
+}//namespace glm
diff --git a/src/glm/gtx/normalize_dot.hpp b/src/glm/gtx/normalize_dot.hpp
new file mode 100644
index 0000000..444fd95
--- /dev/null
+++ b/src/glm/gtx/normalize_dot.hpp
@@ -0,0 +1,59 @@
+//////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+//////////////////////////////////////////////////////////////////////////////////
+// Created : 2007-09-28
+// Updated : 2008-10-07
+// Licence : This source is under MIT License
+// File : glm/gtx/normalize_dot.hpp
+//////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+// - GLM_GTX_fast_square_root
+//////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_gtx_normalize_dot
+#define glm_gtx_normalize_dot
+
+// Dependency:
+#include "../glm.hpp"
+#include "../gtx/fast_square_root.hpp"
+
+#if(defined(GLM_MESSAGES) && !defined(glm_ext))
+# pragma message("GLM: GLM_GTX_normalize_dot extension included")
+#endif
+
+namespace glm{
+namespace gtx{
+namespace normalize_dot ///< GLM_GTX_normalize_dot extension: Dot product of vectors that need to be normalize with a single square root.
+{
+ using namespace gtx::fast_square_root;
+
+ /// \addtogroup gtx_normalize_dot
+ /// @{
+
+ //! Normalize parameters and returns the dot product of x and y.
+ //! It's faster that dot(normalize(x), normalize(y)).
+ //! From GLM_GTX_normalize_dot extension.
+ template <typename genType>
+ typename genType::value_type normalizeDot(
+ genType const & x,
+ genType const & y);
+
+ //! Normalize parameters and returns the dot product of x and y.
+ //! Faster that dot(fastNormalize(x), fastNormalize(y)).
+ //! From GLM_GTX_normalize_dot extension.
+ template <typename genType>
+ typename genType::value_type fastNormalizeDot(
+ genType const & x,
+ genType const & y);
+
+ /// @}
+}//namespace normalize_dot
+}//namespace gtx
+}//namespace glm
+
+#include "normalize_dot.inl"
+
+namespace glm{using namespace gtx::normalize_dot;}
+
+#endif//glm_gtx_normalize_dot
diff --git a/src/glm/gtx/normalize_dot.inl b/src/glm/gtx/normalize_dot.inl
new file mode 100644
index 0000000..206f734
--- /dev/null
+++ b/src/glm/gtx/normalize_dot.inl
@@ -0,0 +1,120 @@
+//////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+//////////////////////////////////////////////////////////////////////////////////
+// Created : 2007-09-28
+// Updated : 2008-10-07
+// Licence : This source is under MIT License
+// File : glm/gtx/normalize_dot.inl
+//////////////////////////////////////////////////////////////////////////////////
+
+namespace glm{
+namespace gtx{
+namespace normalize_dot{
+
+template <typename genType>
+GLM_FUNC_QUALIFIER genType normalizeDot
+(
+ genType const & x,
+ genType const & y
+)
+{
+ return
+ glm::dot(x, y) *
+ glm::inversesqrt(glm::dot(x, x) *
+ glm::dot(y, y));
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER valType normalizeDot
+(
+ detail::tvec2<valType> const & x,
+ detail::tvec2<valType> const & y
+)
+{
+ return
+ glm::dot(x, y) *
+ glm::inversesqrt(glm::dot(x, x) *
+ glm::dot(y, y));
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER valType normalizeDot
+(
+ detail::tvec3<valType> const & x,
+ detail::tvec3<valType> const & y
+)
+{
+ return
+ glm::dot(x, y) *
+ glm::inversesqrt(glm::dot(x, x) *
+ glm::dot(y, y));
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER valType normalizeDot
+(
+ detail::tvec4<valType> const & x,
+ detail::tvec4<valType> const & y
+)
+{
+ return
+ glm::dot(x, y) *
+ glm::inversesqrt(glm::dot(x, x) *
+ glm::dot(y, y));
+}
+
+template <typename genType>
+GLM_FUNC_QUALIFIER genType fastNormalizeDot
+(
+ genType const & x,
+ genType const & y
+)
+{
+ return
+ glm::dot(x, y) *
+ glm::gtx::fast_square_root::fastInverseSqrt(glm::dot(x, x) *
+ glm::dot(y, y));
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER valType fastNormalizeDot
+(
+ detail::tvec2<valType> const & x,
+ detail::tvec2<valType> const & y
+)
+{
+ return
+ glm::dot(x, y) *
+ glm::gtx::fast_square_root::fastInverseSqrt(glm::dot(x, x) *
+ glm::dot(y, y));
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER valType fastNormalizeDot
+(
+ detail::tvec3<valType> const & x,
+ detail::tvec3<valType> const & y
+)
+{
+ return
+ glm::dot(x, y) *
+ glm::gtx::fast_square_root::fastInverseSqrt(glm::dot(x, x) *
+ glm::dot(y, y));
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER valType fastNormalizeDot
+(
+ detail::tvec4<valType> const & x,
+ detail::tvec4<valType> const & y
+)
+{
+ return
+ glm::dot(x, y) *
+ glm::gtx::fast_square_root::fastInverseSqrt(glm::dot(x, x) *
+ glm::dot(y, y));
+}
+
+}//namespace normalize_dot
+}//namespace gtx
+}//namespace glm
diff --git a/src/glm/gtx/number_precision.hpp b/src/glm/gtx/number_precision.hpp
new file mode 100644
index 0000000..ed86bc3
--- /dev/null
+++ b/src/glm/gtx/number_precision.hpp
@@ -0,0 +1,69 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2007-05-10
+// Updated : 2009-06-04
+// Licence : This source is under MIT License
+// File : glm/gtx/number_precision.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+// - GLM_GTC_type_precision
+// - GLM_GTC_quaternion
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_gtx_number_precision
+#define glm_gtx_number_precision
+
+// Dependency:
+#include "../glm.hpp"
+#include "../gtc/type_precision.hpp"
+
+#if(defined(GLM_MESSAGES) && !defined(glm_ext))
+# pragma message("GLM: GLM_GTX_number_precision extension included")
+#endif
+
+namespace glm{
+namespace gtx{
+namespace number_precision ///< GLM_GTX_number_precision extension: Defined size types.
+{
+ using namespace gtc::type_precision;
+
+ /////////////////////////////
+ // Unsigned int vector types
+
+ /// \addtogroup gtx_number_precision
+ /// @{
+
+ typedef u8 u8vec1; //!< \brief 8bit unsigned integer scalar. (from GLM_GTX_number_precision extension)
+ typedef u16 u16vec1; //!< \brief 16bit unsigned integer scalar. (from GLM_GTX_number_precision extension)
+ typedef u32 u32vec1; //!< \brief 32bit unsigned integer scalar. (from GLM_GTX_number_precision extension)
+ typedef u64 u64vec1; //!< \brief 64bit unsigned integer scalar. (from GLM_GTX_number_precision extension)
+
+ //////////////////////
+ // Float vector types
+
+ typedef f16 f16vec1; //!< \brief Half-precision floating-point scalar. (from GLM_GTX_number_precision extension)
+ typedef f32 f32vec1; //!< \brief Single-precision floating-point scalar. (from GLM_GTX_number_precision extension)
+ typedef f64 f64vec1; //!< \brief Single-precision floating-point scalar. (from GLM_GTX_number_precision extension)
+
+ //////////////////////
+ // Float matrix types
+
+ typedef f16 f16mat1; //!< \brief Half-precision floating-point scalar. (from GLM_GTX_number_precision extension)
+ typedef f16 f16mat1x1; //!< \brief Half-precision floating-point scalar. (from GLM_GTX_number_precision extension)
+ typedef f32 f32mat1; //!< \brief Single-precision floating-point scalar. (from GLM_GTX_number_precision extension)
+ typedef f32 f32mat1x1; //!< \brief Single-precision floating-point scalar. (from GLM_GTX_number_precision extension)
+ typedef f64 f64mat1; //!< \brief Double-precision floating-point scalar. (from GLM_GTX_number_precision extension)
+ typedef f64 f64mat1x1; //!< \brief Double-precision floating-point scalar. (from GLM_GTX_number_precision extension)
+
+ /// @}
+}//namespace number_precision
+}//namespace gtx
+}//namespace glm
+
+#include "number_precision.inl"
+
+namespace glm{using namespace gtx::number_precision;}
+
+#endif//glm_gtx_number_precision
diff --git a/src/glm/gtx/number_precision.inl b/src/glm/gtx/number_precision.inl
new file mode 100644
index 0000000..9cac138
--- /dev/null
+++ b/src/glm/gtx/number_precision.inl
@@ -0,0 +1,13 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2007-05-10
+// Updated : 2007-05-10
+// Licence : This source is under MIT License
+// File : glm/gtx/number_precision.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm
+{
+
+}
diff --git a/src/glm/gtx/ocl_type.hpp b/src/glm/gtx/ocl_type.hpp
new file mode 100644
index 0000000..3ec31c1
--- /dev/null
+++ b/src/glm/gtx/ocl_type.hpp
@@ -0,0 +1,110 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2009-05-07
+// Updated : 2009-05-07
+// Licence : This source is under MIT License
+// File : glm/gtx/number_precision.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_gtx_ocl_type
+#define glm_gtx_ocl_type
+
+// Dependency:
+#include "../glm.hpp"
+
+#if(defined(GLM_MESSAGES) && !defined(glm_ext))
+# pragma message("GLM: GLM_GTX_ocl_type extension included")
+#endif
+
+namespace glm{
+namespace gtx{
+namespace ocl_type ///< GLM_GTX_ocl_type extension: OpenCL types.
+{
+ ///////////////////////////
+ // Scalar types
+
+ /// \addtogroup gtx_ocl_type
+ /// @{
+
+ typedef detail::int8 cl_char; //!< \brief 8bit signed integer. (from GLM_GTX_ocl_type extension)
+ typedef detail::int16 cl_short; //!< \brief 16bit signed integer. (from GLM_GTX_ocl_type extension)
+ typedef detail::int32 cl_int; //!< \brief 32bit signed integer. (from GLM_GTX_ocl_type extension)
+ typedef detail::int64 cl_long; //!< \brief 64bit signed integer. (from GLM_GTX_ocl_type extension)
+
+ typedef detail::uint8 cl_uchar; //!< \brief 8bit signed integer. (from GLM_GTX_ocl_type extension)
+ typedef detail::uint16 cl_ushort; //!< \brief 16bit signed integer. (from GLM_GTX_ocl_type extension)
+ typedef detail::uint32 cl_uint; //!< \brief 32bit signed integer. (from GLM_GTX_ocl_type extension)
+ typedef detail::uint64 cl_ulong; //!< \brief 64bit signed integer. (from GLM_GTX_ocl_type extension)
+
+ typedef detail::float16 cl_half; //!< \brief Half-precision floating-point scalar. (from GLM_GTX_ocl_type extension)
+ typedef detail::float32 cl_float; //!< \brief Single-precision floating-point scalar. (from GLM_GTX_ocl_type extension)
+
+
+ typedef detail::int8 cl_char1; //!< \brief 8bit signed integer. (from GLM_GTX_ocl_type extension)
+ typedef detail::int16 cl_short1; //!< \brief 16bit signed integer. (from GLM_GTX_ocl_type extension)
+ typedef detail::int32 cl_int1; //!< \brief 32bit signed integer. (from GLM_GTX_ocl_type extension)
+ typedef detail::int64 cl_long1; //!< \brief 64bit signed integer. (from GLM_GTX_ocl_type extension)
+
+ typedef detail::uint8 cl_uchar1; //!< \brief 8bit signed integer. (from GLM_GTX_ocl_type extension)
+ typedef detail::uint16 cl_ushort1; //!< \brief 16bit signed integer. (from GLM_GTX_ocl_type extension)
+ typedef detail::uint32 cl_uint1; //!< \brief 32bit signed integer. (from GLM_GTX_ocl_type extension)
+ typedef detail::uint64 cl_ulong1; //!< \brief 64bit signed integer. (from GLM_GTX_ocl_type extension)
+
+ //typedef detail::float16 cl_half1; //!< \brief Half-precision floating-point scalar. (from GLM_GTX_ocl_type extension)
+ typedef detail::float32 cl_float1; //!< \brief Single-precision floating-point scalar. (from GLM_GTX_ocl_type extension)
+
+
+ typedef detail::tvec2<detail::int8> cl_char2; //!< \brief 8bit signed integer. (from GLM_GTX_ocl_type extension)
+ typedef detail::tvec2<detail::int16> cl_short2; //!< \brief 16bit signed integer. (from GLM_GTX_ocl_type extension)
+ typedef detail::tvec2<detail::int32> cl_int2; //!< \brief 32bit signed integer. (from GLM_GTX_ocl_type extension)
+ typedef detail::tvec2<detail::int64> cl_long2; //!< \brief 64bit signed integer. (from GLM_GTX_ocl_type extension)
+
+ typedef detail::tvec2<detail::uint8> cl_uchar2; //!< \brief 8bit signed integer. (from GLM_GTX_ocl_type extension)
+ typedef detail::tvec2<detail::uint16> cl_ushort2; //!< \brief 16bit signed integer. (from GLM_GTX_ocl_type extension)
+ typedef detail::tvec2<detail::uint32> cl_uint2; //!< \brief 32bit signed integer. (from GLM_GTX_ocl_type extension)
+ typedef detail::tvec2<detail::uint64> cl_ulong2; //!< \brief 64bit signed integer. (from GLM_GTX_ocl_type extension)
+
+ //typedef detail::tvec2<detail::float16> cl_half2; //!< \brief Half-precision floating-point scalar. (from GLM_GTX_ocl_type extension)
+ typedef detail::tvec2<detail::float32> cl_float2; //!< \brief Single-precision floating-point scalar. (from GLM_GTX_ocl_type extension)
+
+
+ typedef detail::tvec3<detail::int8> cl_char3; //!< \brief 8bit signed integer. (from GLM_GTX_ocl_type extension)
+ typedef detail::tvec3<detail::int16> cl_short3; //!< \brief 16bit signed integer. (from GLM_GTX_ocl_type extension)
+ typedef detail::tvec3<detail::int32> cl_int3; //!< \brief 32bit signed integer. (from GLM_GTX_ocl_type extension)
+ typedef detail::tvec3<detail::int64> cl_long3; //!< \brief 64bit signed integer. (from GLM_GTX_ocl_type extension)
+
+ typedef detail::tvec3<detail::uint8> cl_uchar3; //!< \brief 8bit signed integer. (from GLM_GTX_ocl_type extension)
+ typedef detail::tvec3<detail::uint16> cl_ushort3; //!< \brief 16bit signed integer. (from GLM_GTX_ocl_type extension)
+ typedef detail::tvec3<detail::uint32> cl_uint3; //!< \brief 32bit signed integer. (from GLM_GTX_ocl_type extension)
+ typedef detail::tvec3<detail::uint64> cl_ulong3; //!< \brief 64bit signed integer. (from GLM_GTX_ocl_type extension)
+
+ //typedef detail::tvec3<detail::float16> cl_half3; //!< \brief Half-precision floating-point scalar. (from GLM_GTX_ocl_type extension)
+ typedef detail::tvec3<detail::float32> cl_float3; //!< \brief Single-precision floating-point scalar. (from GLM_GTX_ocl_type extension)
+
+
+ typedef detail::tvec4<detail::int8> cl_char4; //!< \brief 8bit signed integer. (from GLM_GTX_ocl_type extension)
+ typedef detail::tvec4<detail::int16> cl_short4; //!< \brief 16bit signed integer. (from GLM_GTX_ocl_type extension)
+ typedef detail::tvec4<detail::int32> cl_int4; //!< \brief 32bit signed integer. (from GLM_GTX_ocl_type extension)
+ typedef detail::tvec4<detail::int64> cl_long4; //!< \brief 64bit signed integer. (from GLM_GTX_ocl_type extension)
+ typedef detail::tvec4<detail::uint8> cl_uchar4; //!< \brief 8bit signed integer. (from GLM_GTX_ocl_type extension)
+ typedef detail::tvec4<detail::uint16> cl_ushort4; //!< \brief 16bit signed integer. (from GLM_GTX_ocl_type extension)
+ typedef detail::tvec4<detail::uint32> cl_uint4; //!< \brief 32bit signed integer. (from GLM_GTX_ocl_type extension)
+ typedef detail::tvec4<detail::uint64> cl_ulong4; //!< \brief 64bit signed integer. (from GLM_GTX_ocl_type extension)
+
+ //typedef detail::tvec4<detail::float16> cl_half4; //!< \brief Half-precision floating-point scalar. (from GLM_GTX_ocl_type extension)
+ typedef detail::tvec4<detail::float32> cl_float4; //!< \brief Single-precision floating-point scalar. (from GLM_GTX_ocl_type extension)
+
+ /// @}
+}//namespace ocl_type
+}//namespace gtx
+}//namespace glm
+
+#include "ocl_type.inl"
+
+namespace glm{using namespace gtx::ocl_type;}
+
+#endif//glm_gtx_ocl_type
diff --git a/src/glm/gtx/ocl_type.inl b/src/glm/gtx/ocl_type.inl
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/glm/gtx/ocl_type.inl
diff --git a/src/glm/gtx/optimum_pow.hpp b/src/glm/gtx/optimum_pow.hpp
new file mode 100644
index 0000000..fd1542f
--- /dev/null
+++ b/src/glm/gtx/optimum_pow.hpp
@@ -0,0 +1,70 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2005-12-21
+// Updated : 2006-11-13
+// Licence : This source is under MIT License
+// File : glm/gtx/optimum_pow.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_gtx_optimum_pow
+#define glm_gtx_optimum_pow
+
+// Dependency:
+#include "../glm.hpp"
+
+#if(defined(GLM_MESSAGES) && !defined(glm_ext))
+# pragma message("GLM: GLM_GTX_optimum_pow extension included")
+#endif
+
+namespace glm{
+namespace gtx{
+namespace optimum_pow ///< GLM_GTX_optimum_pow extension: Integer exponentiation of power functions.
+{
+ /// \addtogroup gtx_optimum_pow
+ /// @{
+
+ //! Returns x raised to the power of 2.
+ //! From GLM_GTX_optimum_pow extension.
+ template <typename genType>
+ genType pow2(const genType& x);
+
+ //! Returns x raised to the power of 3.
+ //! From GLM_GTX_optimum_pow extension.
+ template <typename genType>
+ genType pow3(const genType& x);
+
+ //! Returns x raised to the power of 4.
+ //! From GLM_GTX_optimum_pow extension.
+ template <typename genType>
+ genType pow4(const genType& x);
+
+ //! Checks if the parameter is a power of 2 number.
+ //! From GLM_GTX_optimum_pow extension.
+ bool powOfTwo(int num);
+
+ //! Checks to determine if the parameter component are power of 2 numbers.
+ //! From GLM_GTX_optimum_pow extension.
+ detail::tvec2<bool> powOfTwo(const detail::tvec2<int>& x);
+
+ //! Checks to determine if the parameter component are power of 2 numbers.
+ //! From GLM_GTX_optimum_pow extension.
+ detail::tvec3<bool> powOfTwo(const detail::tvec3<int>& x);
+
+ //! Checks to determine if the parameter component are power of 2 numbers.
+ //! From GLM_GTX_optimum_pow extension.
+ detail::tvec4<bool> powOfTwo(const detail::tvec4<int>& x);
+
+ /// @}
+}//namespace optimum_pow
+}//namespace gtx
+}//namespace glm
+
+#include "optimum_pow.inl"
+
+namespace glm{using namespace gtx::optimum_pow;}
+
+#endif//glm_gtx_optimum_pow
diff --git a/src/glm/gtx/optimum_pow.inl b/src/glm/gtx/optimum_pow.inl
new file mode 100644
index 0000000..a941ec3
--- /dev/null
+++ b/src/glm/gtx/optimum_pow.inl
@@ -0,0 +1,63 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2005-12-21
+// Updated : 2005-12-27
+// Licence : This source is under MIT License
+// File : glm/gtx/optimum_pow.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm{
+namespace gtx{
+namespace optimum_pow{
+
+ template <typename genType>
+ GLM_FUNC_QUALIFIER genType pow2(const genType& x)
+ {
+ return x * x;
+ }
+
+ template <typename genType>
+ GLM_FUNC_QUALIFIER genType pow3(const genType& x)
+ {
+ return x * x * x;
+ }
+
+ template <typename genType>
+ GLM_FUNC_QUALIFIER genType pow4(const genType& x)
+ {
+ return x * x * x * x;
+ }
+
+ GLM_FUNC_QUALIFIER bool powOfTwo(int x)
+ {
+ return !(x & (x - 1));
+ }
+
+ GLM_FUNC_QUALIFIER detail::tvec2<bool> powOfTwo(const detail::tvec2<int>& x)
+ {
+ return detail::tvec2<bool>(
+ powOfTwo(x.x),
+ powOfTwo(x.y));
+ }
+
+ GLM_FUNC_QUALIFIER detail::tvec3<bool> powOfTwo(const detail::tvec3<int>& x)
+ {
+ return detail::tvec3<bool>(
+ powOfTwo(x.x),
+ powOfTwo(x.y),
+ powOfTwo(x.z));
+ }
+
+ GLM_FUNC_QUALIFIER detail::tvec4<bool> powOfTwo(const detail::tvec4<int>& x)
+ {
+ return detail::tvec4<bool>(
+ powOfTwo(x.x),
+ powOfTwo(x.y),
+ powOfTwo(x.z),
+ powOfTwo(x.w));
+ }
+
+}//namespace optimum_pow
+}//namespace gtx
+}//namespace glm
diff --git a/src/glm/gtx/orthonormalize.hpp b/src/glm/gtx/orthonormalize.hpp
new file mode 100644
index 0000000..c7890c9
--- /dev/null
+++ b/src/glm/gtx/orthonormalize.hpp
@@ -0,0 +1,52 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2005-12-21
+// Updated : 2006-11-13
+// Licence : This source is under MIT License
+// File : glm/gtx/orthonormalize.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_gtx_orthonormalize
+#define glm_gtx_orthonormalize
+
+// Dependency:
+#include "../glm.hpp"
+
+#if(defined(GLM_MESSAGES) && !defined(glm_ext))
+# pragma message("GLM: GLM_GTX_orthonormalize extension included")
+#endif
+
+namespace glm{
+namespace gtx{
+namespace orthonormalize ///< GLM_GTX_orthonormalize extension: Orthonormalize matrices.
+{
+ /// \addtogroup gtx_orthonormalize
+ /// @{
+
+ //! Returns the orthonormalized matrix of m.
+ //! From GLM_GTX_orthonormalize extension.
+ template <typename T>
+ detail::tmat3x3<T> orthonormalize(
+ const detail::tmat3x3<T>& m);
+
+ //! Orthonormalizes x according y.
+ //! From GLM_GTX_orthonormalize extension.
+ template <typename T>
+ detail::tvec3<T> orthonormalize(
+ const detail::tvec3<T>& x,
+ const detail::tvec3<T>& y);
+
+ /// @}
+}//namespace orthonormalize
+}//namespace gtx
+}//namespace glm
+
+#include "orthonormalize.inl"
+
+namespace glm{using namespace gtx::orthonormalize;}
+
+#endif//glm_gtx_orthonormalize
diff --git a/src/glm/gtx/orthonormalize.inl b/src/glm/gtx/orthonormalize.inl
new file mode 100644
index 0000000..9293606
--- /dev/null
+++ b/src/glm/gtx/orthonormalize.inl
@@ -0,0 +1,49 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2005-12-21
+// Updated : 2005-12-21
+// Licence : This source is under MIT License
+// File : glm/gtx/orthonormalize.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm{
+namespace gtx{
+namespace orthonormalize{
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tmat3x3<T> orthonormalize
+ (
+ const detail::tmat3x3<T>& m
+ )
+ {
+ detail::tmat3x3<T> r = m;
+
+ r[0] = normalize(r[0]);
+
+ float d0 = dot(r[0], r[1]);
+ r[1] -= r[0] * d0;
+ r[1] = normalize(r[1]);
+
+ float d1 = dot(r[1], r[2]);
+ d0 = dot(r[0], r[2]);
+ r[2] -= r[0] * d0 + r[1] * d1;
+ r[2] = normalize(r[2]);
+
+ return r;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> orthonormalize
+ (
+ const detail::tvec3<T>& x,
+ const detail::tvec3<T>& y
+ )
+ {
+ return normalize(x - y * dot(y, x));
+ }
+
+}//namespace orthonormalize
+}//namespace gtx
+}//namespace glm
+
diff --git a/src/glm/gtx/perpendicular.hpp b/src/glm/gtx/perpendicular.hpp
new file mode 100644
index 0000000..86dcef7
--- /dev/null
+++ b/src/glm/gtx/perpendicular.hpp
@@ -0,0 +1,62 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2005-12-21
+// Updated : 2009-03-06
+// Licence : This source is under MIT License
+// File : glm/gtx/perpendicular.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+// - GLM_GTX_projection
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_gtx_perpendicular
+#define glm_gtx_perpendicular
+
+// Dependency:
+#include "../glm.hpp"
+#include "../gtx/projection.hpp"
+
+#if(defined(GLM_MESSAGES) && !defined(glm_ext))
+# pragma message("GLM: GLM_GTX_perpendicular extension included")
+#endif
+
+namespace glm{
+namespace gtx{
+namespace perpendicular ///< GLM_GTX_perpendicular extension: Perpendicular of a vector from other one
+{
+ /// \addtogroup gtx_perpendicular
+ /// @{
+
+ //! Projects x a perpendicular axis of Normal.
+ //! From GLM_GTX_perpendicular extension.
+ template <typename T>
+ detail::tvec2<T> perp(
+ detail::tvec2<T> const & x,
+ detail::tvec2<T> const & Normal);
+
+ //! Projects x a perpendicular axis of Normal.
+ //! From GLM_GTX_perpendicular extension.
+ template <typename T>
+ detail::tvec3<T> perp(
+ detail::tvec3<T> const & x,
+ detail::tvec3<T> const & Normal);
+
+ //! Projects x a perpendicular axis of Normal.
+ //! From GLM_GTX_perpendicular extension.
+ template <typename T>
+ detail::tvec4<T> perp(
+ detail::tvec4<T> const & x,
+ detail::tvec4<T> const & Normal);
+
+ /// @}
+}//namespace perpendicular
+}//namespace gtx
+}//namespace glm
+
+#include "perpendicular.inl"
+
+namespace glm{using namespace gtx::perpendicular;}
+
+#endif//glm_gtx_perpendicular
diff --git a/src/glm/gtx/perpendicular.inl b/src/glm/gtx/perpendicular.inl
new file mode 100644
index 0000000..2b49371
--- /dev/null
+++ b/src/glm/gtx/perpendicular.inl
@@ -0,0 +1,40 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2005-12-21
+// Updated : 2009-03-06
+// Licence : This source is under MIT License
+// File : glm/gtx/perpendicular.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm{
+namespace gtx{
+namespace perpendicular{
+
+template <typename T>
+GLM_FUNC_QUALIFIER detail::tvec2<T> perp(
+ detail::tvec2<T> const & x,
+ detail::tvec2<T> const & Normal)
+{
+ return x - projection::proj(x, Normal);
+}
+
+template <typename T>
+GLM_FUNC_QUALIFIER detail::tvec3<T> perp(
+ detail::tvec3<T> const & x,
+ detail::tvec3<T> const & Normal)
+{
+ return x - projection::proj(x, Normal);
+}
+
+template <typename T>
+GLM_FUNC_QUALIFIER detail::tvec4<T> perp(
+ detail::tvec4<T> const & x,
+ detail::tvec4<T> const & Normal)
+{
+ return x - projection::proj(x, Normal);
+}
+
+}//namespace perpendicular
+}//namespace gtx
+}//namespace glm
diff --git a/src/glm/gtx/polar_coordinates.hpp b/src/glm/gtx/polar_coordinates.hpp
new file mode 100644
index 0000000..3bf6582
--- /dev/null
+++ b/src/glm/gtx/polar_coordinates.hpp
@@ -0,0 +1,49 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2007-03-06
+// Updated : 2009-05-01
+// Licence : This source is under MIT License
+// File : glm/gtx/polar_coordinates.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_gtx_polar_coordinates
+#define glm_gtx_polar_coordinates
+
+// Dependency:
+#include "../glm.hpp"
+
+#if(defined(GLM_MESSAGES) && !defined(glm_ext))
+# pragma message("GLM: GLM_GTX_polar_coordinates extension included")
+#endif
+
+namespace glm{
+namespace gtx{
+namespace polar_coordinates ///< GLM_GTX_polar_coordinates extension: Conversion from Euclidean space to polar space and revert.
+{
+ /// \addtogroup gtx_polar_coordinates
+ /// @{
+
+ //! Convert Euclidean to Polar coordinates, x is the xz distance, y, the latitude and z the longitude.
+ //! From GLM_GTX_polar_coordinates extension.
+ template <typename T>
+ detail::tvec3<T> polar(const detail::tvec3<T>& euclidean);
+
+ //! Convert Polar to Euclidean coordinates.
+ //! From GLM_GTX_polar_coordinates extension.
+ template <typename T>
+ detail::tvec3<T> euclidean(const detail::tvec3<T>& polar);
+
+ /// @}
+}//namespace polar_coordinates
+}//namespace gtx
+}//namespace glm
+
+#include "polar_coordinates.inl"
+
+namespace glm{using namespace gtx::polar_coordinates;}
+
+#endif//glm_gtx_polar_coordinates
diff --git a/src/glm/gtx/polar_coordinates.inl b/src/glm/gtx/polar_coordinates.inl
new file mode 100644
index 0000000..8f2d327
--- /dev/null
+++ b/src/glm/gtx/polar_coordinates.inl
@@ -0,0 +1,42 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2007-03-06
+// Updated : 2009-05-01
+// Licence : This source is under MIT License
+// File : glm/gtx/polar_coordinates.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm{
+namespace gtx{
+namespace polar_coordinates
+{
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> polar(
+ const detail::tvec3<T>& euclidean)
+ {
+ T length = length(euclidean);
+ detail::tvec3<T> tmp = euclidean / length;
+ T xz_dist = sqrt(tmp.x * tmp.x + tmp.z * tmp.z);
+
+ return detail::tvec3<T>(
+ degrees(atan(xz_dist, tmp.y)), // latitude
+ degrees(atan(tmp.x, tmp.z)), // longitude
+ xz_dist); // xz distance
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> euclidean(
+ const detail::tvec3<T>& polar)
+ {
+ T latitude = radians(polar.x);
+ T longitude = radians(polar.y);
+ return detail::tvec3<T>(
+ cos(latitude) * sin(longitude),
+ sin(latitude),
+ cos(latitude) * cos(longitude));
+ }
+
+}//namespace polar_coordinates
+}//namespace gtx
+}//namespace glm
diff --git a/src/glm/gtx/projection.hpp b/src/glm/gtx/projection.hpp
new file mode 100644
index 0000000..fa8e072
--- /dev/null
+++ b/src/glm/gtx/projection.hpp
@@ -0,0 +1,60 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2005-12-21
+// Updated : 2009-03-06
+// Licence : This source is under MIT License
+// File : glm/gtx/projection.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_gtx_projection
+#define glm_gtx_projection
+
+// Dependency:
+#include "../glm.hpp"
+
+#if(defined(GLM_MESSAGES) && !defined(glm_ext))
+# pragma message("GLM: GLM_GTX_projection extension included")
+#endif
+
+namespace glm{
+namespace gtx{
+namespace projection ///< GLM_GTX_projection extension: Projection of a vector to other one
+{
+ /// \addtogroup gtx_projection
+ /// @{
+
+ //! Projects x on Normal.
+ //! From GLM_GTX_projection extension.
+ template <typename T>
+ detail::tvec2<T> proj(
+ detail::tvec2<T> const & x,
+ detail::tvec2<T> const & Normal);
+
+ //! Projects x on Normal.
+ //! From GLM_GTX_projection extension.
+ template <typename T>
+ detail::tvec3<T> proj(
+ detail::tvec3<T> const & x,
+ detail::tvec3<T> const & Normal);
+
+ //! Projects x on Normal.
+ //! From GLM_GTX_projection extension.
+ template <typename T>
+ detail::tvec4<T> proj(
+ detail::tvec4<T> const & x,
+ detail::tvec4<T> const & Normal);
+
+ /// @}
+}//namespace projection
+}//namespace gtx
+}//namespace glm
+
+#include "projection.inl"
+
+namespace glm{using namespace gtx::projection;}
+
+#endif//glm_gtx_projection
diff --git a/src/glm/gtx/projection.inl b/src/glm/gtx/projection.inl
new file mode 100644
index 0000000..51eb4c5
--- /dev/null
+++ b/src/glm/gtx/projection.inl
@@ -0,0 +1,40 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2005-12-21
+// Updated : 2009-03-06
+// Licence : This source is under MIT License
+// File : glm/gtx/projection.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm{
+namespace gtx{
+namespace projection{
+
+template <typename T>
+GLM_FUNC_QUALIFIER detail::tvec2<T> proj(
+ detail::tvec2<T> const & x,
+ detail::tvec2<T> const & Normal)
+{
+ return glm::dot(x, Normal) / glm::dot(Normal, Normal) * Normal;
+}
+
+template <typename T>
+GLM_FUNC_QUALIFIER detail::tvec3<T> proj(
+ detail::tvec3<T> const & x,
+ detail::tvec3<T> const & Normal)
+{
+ return dot(x, Normal) / glm::dot(Normal, Normal) * Normal;
+}
+
+template <typename T>
+GLM_FUNC_QUALIFIER detail::tvec4<T> proj(
+ detail::tvec4<T> const & x,
+ detail::tvec4<T> const & Normal)
+{
+ return glm::dot(x, Normal) / glm::dot(Normal, Normal) * Normal;
+}
+
+}//namespace projection
+}//namespace gtx
+}//namespace glm
diff --git a/src/glm/gtx/quaternion.hpp b/src/glm/gtx/quaternion.hpp
new file mode 100644
index 0000000..97271e0
--- /dev/null
+++ b/src/glm/gtx/quaternion.hpp
@@ -0,0 +1,217 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2005-12-21
+// Updated : 2009-05-21
+// Licence : This source is under MIT License
+// File : glm/gtx/quaternion.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// ToDo:
+// - Study constructors with angles and axis
+// - Study constructors with vec3 that are the imaginary component of quaternion
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_gtx_quaternion
+#define glm_gtx_quaternion
+
+// Dependency:
+#include "../glm.hpp"
+#include "../gtc/quaternion.hpp"
+
+#if(defined(GLM_MESSAGES) && !defined(glm_ext))
+# pragma message("GLM: GLM_GTX_quaternion extension included")
+#endif
+
+namespace glm{
+namespace gtx{
+namespace quaternion ///< GLM_GTX_quaternion extension: Quaternion types and functions
+{
+ using namespace gtc::quaternion;
+
+ /// \addtogroup gtx_quaternion
+ ///@{
+
+ //! Compute a cross product between a quaternion and a vector.
+ //! From GLM_GTX_quaternion extension.
+ template <typename valType>
+ detail::tvec3<valType> cross(
+ detail::tquat<valType> const & q,
+ detail::tvec3<valType> const & v);
+
+ //! Compute a cross product between a vector and a quaternion.
+ //! From GLM_GTX_quaternion extension.
+ template <typename valType>
+ detail::tvec3<valType> cross(
+ detail::tvec3<valType> const & v,
+ detail::tquat<valType> const & q);
+
+ //! Compute a point on a path according squad equation.
+ //! q1 and q2 are control points; s1 and s2 are intermediate control points.
+ //! From GLM_GTX_quaternion extension.
+ template <typename valType>
+ detail::tquat<valType> squad(
+ detail::tquat<valType> const & q1,
+ detail::tquat<valType> const & q2,
+ detail::tquat<valType> const & s1,
+ detail::tquat<valType> const & s2,
+ valType const & h);
+
+ //! Returns an intermediate control point for squad interpolation.
+ //! From GLM_GTX_quaternion extension.
+ template <typename valType>
+ detail::tquat<valType> intermediate(
+ detail::tquat<valType> const & prev,
+ detail::tquat<valType> const & curr,
+ detail::tquat<valType> const & next);
+
+ //! Returns a exp of a quaternion.
+ //! From GLM_GTX_quaternion extension.
+ template <typename valType>
+ detail::tquat<valType> exp(
+ detail::tquat<valType> const & q,
+ valType const & exponent);
+
+ //! Returns a log of a quaternion.
+ //! From GLM_GTX_quaternion extension.
+ template <typename valType>
+ detail::tquat<valType> log(
+ detail::tquat<valType> const & q);
+
+ //! Returns x raised to the y power.
+ //! From GLM_GTX_quaternion extension.
+ template <typename valType>
+ detail::tquat<valType> pow(
+ detail::tquat<valType> const & x,
+ valType const & y);
+
+ //! Returns quarternion square root.
+ //! From GLM_GTX_quaternion extension.
+ //template <typename valType>
+ //detail::tquat<valType> sqrt(
+ // detail::tquat<valType> const & q);
+
+ //! Rotates a 3 components vector by a quaternion.
+ //! From GLM_GTX_transform extension.
+ template <typename valType>
+ detail::tvec3<valType> rotate(
+ detail::tquat<valType> const & q,
+ detail::tvec3<valType> const & v);
+
+ //! Rotates a 4 components vector by a quaternion.
+ //! From GLM_GTX_transform extension.
+ template <typename valType>
+ detail::tvec4<valType> rotate(
+ detail::tquat<valType> const & q,
+ detail::tvec4<valType> const & v);
+
+ //! Returns the quaternion rotation angle.
+ //! From GLM_GTX_quaternion extension.
+ template <typename valType>
+ valType angle(
+ detail::tquat<valType> const & x);
+
+ //! Returns the q rotation axis.
+ //! From GLM_GTX_quaternion extension.
+ template <typename valType>
+ detail::tvec3<valType> axis(
+ detail::tquat<valType> const & x);
+
+ //! Build a quaternion from an angle and a normalized axis.
+ //! From GLM_GTX_quaternion extension.
+ template <typename valType>
+ detail::tquat<valType> angleAxis(
+ valType const & angle,
+ valType const & x,
+ valType const & y,
+ valType const & z);
+
+ //! Build a quaternion from an angle and a normalized axis.
+ //! From GLM_GTX_quaternion extension.
+ template <typename valType>
+ detail::tquat<valType> angleAxis(
+ valType const & angle,
+ detail::tvec3<valType> const & axis);
+
+ //! Extract the real component of a quaternion.
+ //! From GLM_GTX_quaternion extension.
+ template <typename valType>
+ valType extractRealComponent(
+ detail::tquat<valType> const & q);
+
+ //! Returns roll value of euler angles.
+ //! From GLM_GTX_quaternion extension.
+ template <typename valType>
+ valType roll(
+ detail::tquat<valType> const & x);
+
+ //! Returns pitch value of euler angles.
+ //! From GLM_GTX_quaternion extension.
+ template <typename valType>
+ valType pitch(
+ detail::tquat<valType> const & x);
+
+ //! Returns yaw value of euler angles.
+ //! From GLM_GTX_quaternion extension.
+ template <typename valType>
+ valType yaw(
+ detail::tquat<valType> const & x);
+
+ //! Returns euler angles, yitch as x, yaw as y, roll as z.
+ //! From GLM_GTX_quaternion extension.
+ template <typename valType>
+ detail::tvec3<valType> eularAngles(
+ detail::tquat<valType> const & x);
+
+ //! Converts a quaternion to a 3 * 3 matrix.
+ //! From GLM_GTX_quaternion extension.
+ template <typename valType>
+ detail::tmat3x3<valType> toMat3(
+ detail::tquat<valType> const & x){return gtc::quaternion::mat3_cast(x);}
+
+ //! Converts a quaternion to a 4 * 4 matrix.
+ //! From GLM_GTX_quaternion extension.
+ template <typename valType>
+ detail::tmat4x4<valType> toMat4(
+ detail::tquat<valType> const & x){return gtc::quaternion::mat4_cast(x);}
+
+ //! Converts a 3 * 3 matrix to a quaternion.
+ //! From GLM_GTX_quaternion extension.
+ template <typename valType>
+ detail::tquat<valType> toQuat(
+ detail::tmat3x3<valType> const & x){return gtc::quaternion::quat_cast(x);}
+
+ //! Converts a 4 * 4 matrix to a quaternion.
+ //! From GLM_GTX_quaternion extension.
+ template <typename valType>
+ detail::tquat<valType> toQuat(
+ detail::tmat4x4<valType> const & x){return gtc::quaternion::quat_cast(x);}
+
+ //! Quaternion interpolation using the rotation short path.
+ //! From GLM_GTX_quaternion extension.
+ template <typename T>
+ detail::tquat<T> shortMix(
+ detail::tquat<T> const & x,
+ detail::tquat<T> const & y,
+ T const & a);
+
+ //! Quaternion normalized linear interpolation.
+ //! From GLM_GTX_quaternion extension.
+ template <typename T>
+ detail::tquat<T> fastMix(
+ detail::tquat<T> const & x,
+ detail::tquat<T> const & y,
+ T const & a);
+
+ /// @}
+}//namespace quaternion
+}//namespace gtx
+} //namespace glm
+
+#include "quaternion.inl"
+
+namespace glm{using namespace gtx::quaternion;}
+
+#endif//glm_gtx_quaternion
diff --git a/src/glm/gtx/quaternion.inl b/src/glm/gtx/quaternion.inl
new file mode 100644
index 0000000..a65b2c0
--- /dev/null
+++ b/src/glm/gtx/quaternion.inl
@@ -0,0 +1,303 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2005-12-21
+// Updated : 2008-11-27
+// Licence : This source is under MIT License
+// File : glm/gtx/quaternion.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#include <limits>
+
+namespace glm{
+namespace gtx{
+namespace quaternion
+{
+ template <typename valType>
+ GLM_FUNC_QUALIFIER detail::tvec3<valType> cross
+ (
+ detail::tvec3<valType> const & v,
+ detail::tquat<valType> const & q
+ )
+ {
+ return gtc::quaternion::inverse(q) * v;
+ }
+
+ template <typename valType>
+ GLM_FUNC_QUALIFIER detail::tvec3<valType> cross
+ (
+ detail::tquat<valType> const & q,
+ detail::tvec3<valType> const & v
+ )
+ {
+ return q * v;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tquat<T> squad
+ (
+ detail::tquat<T> const & q1,
+ detail::tquat<T> const & q2,
+ detail::tquat<T> const & s1,
+ detail::tquat<T> const & s2,
+ T const & h)
+ {
+ return mix(mix(q1, q2, h), mix(s1, s2, h), T(2) * h (T(1) - h));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tquat<T> intermediate
+ (
+ detail::tquat<T> const & prev,
+ detail::tquat<T> const & curr,
+ detail::tquat<T> const & next
+ )
+ {
+ detail::tquat<T> invQuat = gtc::quaternion::inverse(curr);
+ return ext((log(next + invQuat) + log(prev + invQuat)) / T(-4)) * curr;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tquat<T> exp
+ (
+ detail::tquat<T> const & q,
+ T const & exponent
+ )
+ {
+ detail::tvec3<T> u(q.x, q.y, q.z);
+ float a = glm::length(u);
+ detail::tvec3<T> v(u / a);
+ return detail::tquat<T>(cos(a), sin(a) * v);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tquat<T> log
+ (
+ detail::tquat<T> const & q
+ )
+ {
+ if((q.x == T(0)) && (q.y == T(0)) && (q.z == T(0)))
+ {
+ if(q.w > T(0))
+ return detail::tquat<T>(log(q.w), T(0), T(0), T(0));
+ else if(q.w < T(0))
+ return detail::tquat<T>(log(-q.w), T(3.1415926535897932384626433832795), T(0),T(0));
+ else
+ return detail::tquat<T>(std::numeric_limits<T>::infinity(), std::numeric_limits<T>::infinity(), std::numeric_limits<T>::infinity(), std::numeric_limits<T>::infinity());
+ }
+ else
+ {
+ T Vec3Len = sqrt(q.x * q.x + q.y * q.y + q.z * q.z);
+ T QuatLen = sqrt(Vec3Len * Vec3Len + q.w * q.w);
+ T t = atan(Vec3Len, T(q.w)) / Vec3Len;
+ return detail::tquat<T>(t * q.x, t * q.y, t * q.z, log(QuatLen));
+ }
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tquat<T> pow
+ (
+ detail::tquat<T> const & x,
+ T const & y
+ )
+ {
+ if(abs(x.w) > T(0.9999))
+ return x;
+ float Angle = acos(y);
+ float NewAngle = Angle * y;
+ float Div = sin(NewAngle) / sin(Angle);
+ return detail::tquat<T>(
+ cos(NewAngle),
+ x.x * Div,
+ x.y * Div,
+ x.z * Div);
+ }
+
+ //template <typename T>
+ //GLM_FUNC_QUALIFIER detail::tquat<T> sqrt
+ //(
+ // detail::tquat<T> const & q
+ //)
+ //{
+ // T q0 = T(1) - dot(q, q);
+ // return T(2) * (T(1) + q0) * q;
+ //}
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> rotate
+ (
+ detail::tquat<T> const & q,
+ detail::tvec3<T> const & v
+ )
+ {
+ return q * v;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<T> rotate
+ (
+ detail::tquat<T> const & q,
+ detail::tvec4<T> const & v
+ )
+ {
+ return q * v;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER T angle
+ (
+ detail::tquat<T> const & x
+ )
+ {
+ return glm::degrees(acos(x.w) * T(2));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> axis
+ (
+ detail::tquat<T> const & x
+ )
+ {
+ T tmp1 = T(1) - x.w * x.w;
+ if(tmp1 <= T(0))
+ return detail::tvec3<T>(0, 0, 1);
+ T tmp2 = T(1) / sqrt(tmp1);
+ return detail::tvec3<T>(x.x * tmp2, x.y * tmp2, x.z * tmp2);
+ }
+
+ template <typename valType>
+ GLM_FUNC_QUALIFIER detail::tquat<valType> angleAxis
+ (
+ valType const & angle,
+ valType const & x,
+ valType const & y,
+ valType const & z
+ )
+ {
+ return angleAxis(angle, detail::tvec3<valType>(x, y, z));
+ }
+
+ template <typename valType>
+ GLM_FUNC_QUALIFIER detail::tquat<valType> angleAxis
+ (
+ valType const & angle,
+ detail::tvec3<valType> const & v
+ )
+ {
+ detail::tquat<valType> result;
+
+ valType a = glm::radians(angle);
+ valType s = glm::sin(a * valType(0.5));
+
+ result.w = glm::cos(a * valType(0.5));
+ result.x = v.x * s;
+ result.y = v.y * s;
+ result.z = v.z * s;
+ return result;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER T extractRealComponent
+ (
+ detail::tquat<T> const & q
+ )
+ {
+ T w = T(1.0) - q.x * q.x - q.y * q.y - q.z * q.z;
+ if(w < T(0))
+ return T(0);
+ else
+ return -sqrt(w);
+ }
+
+ template <typename valType>
+ GLM_FUNC_QUALIFIER valType roll
+ (
+ detail::tquat<valType> const & q
+ )
+ {
+ return atan2(valType(2) * (q.x * q.y + q.w * q.z), q.w * q.w + q.x * q.x - q.y * q.y - q.z * q.z);
+ }
+
+ template <typename valType>
+ GLM_FUNC_QUALIFIER valType pitch
+ (
+ detail::tquat<valType> const & q
+ )
+ {
+ return atan2(valType(2) * (q.y * q.z + q.w * q.x), q.w * q.w - q.x * q.x - q.y * q.y + q.z * q.z);
+ }
+
+ template <typename valType>
+ GLM_FUNC_QUALIFIER valType yaw
+ (
+ detail::tquat<valType> const & q
+ )
+ {
+ return asin(valType(-2) * (q.x * q.z - q.w * q.y));
+ }
+
+ template <typename valType>
+ GLM_FUNC_QUALIFIER detail::tvec3<valType> eularAngles
+ (
+ detail::tquat<valType> const & x
+ )
+ {
+ return detail::tvec3<valType>(pitch(x), yaw(x), roll(x));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tquat<T> shortMix
+ (
+ detail::tquat<T> const & x,
+ detail::tquat<T> const & y,
+ T const & a
+ )
+ {
+ if(a <= typename detail::tquat<T>::value_type(0)) return x;
+ if(a >= typename detail::tquat<T>::value_type(1)) return y;
+
+ T fCos = dot(x, y);
+ detail::tquat<T> y2(y); //BUG!!! tquat<T> y2;
+ if(fCos < T(0))
+ {
+ y2 = -y;
+ fCos = -fCos;
+ }
+
+ //if(fCos > 1.0f) // problem
+ T k0, k1;
+ if(fCos > T(0.9999))
+ {
+ k0 = T(1) - a;
+ k1 = T(0) + a; //BUG!!! 1.0f + a;
+ }
+ else
+ {
+ T fSin = sqrt(T(1) - fCos * fCos);
+ T fAngle = atan(fSin, fCos);
+ T fOneOverSin = T(1) / fSin;
+ k0 = sin((T(1) - a) * fAngle) * fOneOverSin;
+ k1 = sin((T(0) + a) * fAngle) * fOneOverSin;
+ }
+
+ return detail::tquat<T>(
+ k0 * x.w + k1 * y2.w,
+ k0 * x.x + k1 * y2.x,
+ k0 * x.y + k1 * y2.y,
+ k0 * x.z + k1 * y2.z);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tquat<T> fastMix
+ (
+ detail::tquat<T> const & x,
+ detail::tquat<T> const & y,
+ T const & a
+ )
+ {
+ return glm::normalize(x * (T(1) - a) + (y * a));
+ }
+
+}//namespace quaternion
+}//namespace gtx
+}//namespace glm
diff --git a/src/glm/gtx/random.hpp b/src/glm/gtx/random.hpp
new file mode 100644
index 0000000..00c1a23
--- /dev/null
+++ b/src/glm/gtx/random.hpp
@@ -0,0 +1,89 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2006-01-16
+// Updated : 2007-08-30
+// Licence : This source is under MIT License
+// File : glm/gtx/random.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+// - GLM_GTX_vecx
+// - GLM_GTX_half_float
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_gtx_random
+#define glm_gtx_random
+
+// Dependency:
+#include "../glm.hpp"
+#include "../gtc/half_float.hpp"
+
+#if(defined(GLM_MESSAGES) && !defined(glm_ext))
+# pragma message("GLM: GLM_GTX_random extension included")
+#endif
+
+namespace glm{
+namespace gtx{
+namespace random ///< GLM_GTX_random extension: Generate random number from various distribution methods
+{
+ /// \addtogroup gtx_random
+ /// @{
+
+ //! Generate a random number in the interval [-1, 1], according a linear distribution.
+ //! From GLM_GTX_random extension.
+ template <typename T> T signedRand1();
+
+ template <> float signedRand1(); //!< \brief Generate a random number in the interval [-1, 1], according a linear distribution (From GLM_GTX_random extension)
+ template <> double signedRand1(); //!< \brief Generate a random number in the interval [-1, 1], according a linear distribution (From GLM_GTX_random extension)
+ template <typename T> detail::tvec2<T> signedRand2(); //!< \brief Generate 2 random numbers in the interval [-1, 1], according a linear distribution (From GLM_GTX_random extension)
+ template <typename T> detail::tvec3<T> signedRand3(); //!< \brief Generate 3 random numbers in the interval [-1, 1], according a linear distribution (From GLM_GTX_random extension)
+ template <typename T> detail::tvec4<T> signedRand4(); //!< \brief Generate 4 random numbers in the interval [-1, 1], according a linear distribution (From GLM_GTX_random extension)
+
+ template <typename T> detail::tvec2<T> normalizedRand2(); //!< \brief Generate a normalized 2D vector regulary distribute on a circle (From GLM_GTX_random extension)
+ template <typename T> detail::tvec2<T> normalizedRand2(T Min, T Max); //!< \brief Generate a scaled and normalized 2D vector regulary distribute on a circle (From GLM_GTX_random extension)
+ template <typename T> detail::tvec3<T> normalizedRand3(); //!< \brief Generate a normalized 3D vector regulary distribute on a sphere (From GLM_GTX_random extension)
+ template <typename T> detail::tvec3<T> normalizedRand3(T Min, T Max); //!< \brief Generate a scaled and normalized 3D vector regulary distribute on a sphere (From GLM_GTX_random extension)
+
+ template <typename T> T compRand1(); //!< \brief Generate a random number in the interval [0, 1], according a linear distribution (From GLM_GTX_random extension)
+ template <> float compRand1(); //!< \brief Generate a random number in the interval [0, 1], according a linear distribution (From GLM_GTX_random extension)
+ template <> double compRand1(); //!< \brief Generate a random number in the interval [0, 1], according a linear distribution (From GLM_GTX_random extension)
+ template <typename T> T compRand1(T Min, T Max); //!< \brief Generate a random number in the interval [Min, Max], according a linear distribution (From GLM_GTX_random extension)
+ template <typename T> detail::tvec2<T> compRand2(T Min, T Max); //!< \brief Generate 2 random numbers in the interval [Min, Max], according a linear distribution (From GLM_GTX_random extension)
+ template <typename T> detail::tvec3<T> compRand3(T Min, T Max); //!< \brief Generate 3 random numbers in the interval [Min, Max], according a linear distribution (From GLM_GTX_random extension)
+ template <typename T> detail::tvec4<T> compRand4(T Min, T Max); //!< \brief Generate 4 random numbers in the interval [Min, Max], according a linear distribution (From GLM_GTX_random extension)
+ template <typename T> detail::tvec2<T> compRand2(const detail::tvec2<T>& Min, const detail::tvec2<T>& Max); //!< \brief Generate 2 random numbers in the interval [Min, Max], according a linear distribution (From GLM_GTX_random extension)
+ template <typename T> detail::tvec3<T> compRand3(const detail::tvec3<T>& Min, const detail::tvec3<T>& Max); //!< \brief Generate 3 random numbers in the interval [Min, Max], according a linear distribution (From GLM_GTX_random extension)
+ template <typename T> detail::tvec3<T> compRand4(const detail::tvec4<T>& Min, const detail::tvec4<T>& Max); //!< \brief Generate 4 random numbers in the interval [Min, Max], according a linear distribution (From GLM_GTX_random extension)
+
+ template <typename T> detail::tvec2<T> vecRand2(); //!< \brief Generate a random normalized 2 component vector. It's a spherical uniform distribution. (From GLM_GTX_random extension)
+ template <typename T> detail::tvec2<T> vecRand2(T MinRadius, T MaxRadius); //!< \brief Generate a random normalized 2 component vector. It's a spherical uniform distribution. (From GLM_GTX_random extension)
+ template <typename T> detail::tvec3<T> vecRand3(); //!< \brief Generate a random normalized 3 component vector. It's a spherical uniform distribution. (From GLM_GTX_random extension)
+ template <typename T> detail::tvec3<T> vecRand3(T MinRadius, T MaxRadius); //!< \brief Generate a random normalized 3 component vector. It's a spherical uniform distribution. (From GLM_GTX_random extension)
+ template <typename T> detail::tvec4<T> vecRand4(); //!< \brief Generate a random normalized 4 component vector. It's a spherical uniform distribution. (From GLM_GTX_random extension)
+ template <typename T> detail::tvec4<T> vecRand4(T MinRadius, T MaxRadius); //!< \brief Generate a random normalized 4 component vector. It's a spherical uniform distribution. (From GLM_GTX_random extension)
+
+ template <typename T> T gaussRand1(T mean, T std_deviation); //!< \brief Gererate a random floating number according a Gauss distribution. (From GLM_GTX_random extension)
+ template <typename T> detail::tvec2<T> gaussRand2(T mean, T std_deviation); //!< \brief Gererate 2 random floating numbers according a Gauss distribution. (From GLM_GTX_random extension)
+ template <typename T> detail::tvec3<T> gaussRand3(T mean, T std_deviation); //!< \brief Gererate 3 random floating numbers according a Gauss distribution. (From GLM_GTX_random extension)
+ template <typename T> detail::tvec4<T> gaussRand4(T mean, T std_deviation); //!< \brief Gererate 4 random floating numbers according a Gauss distribution. (From GLM_GTX_random extension)
+ template <typename T> detail::tvec2<T> gaussRand2(const detail::tvec2<T>& mean, T std_deviation); //!< \brief Gererate 2 random floating numbers according a Gauss distribution. (From GLM_GTX_random extension)
+ template <typename T> detail::tvec3<T> gaussRand3(const detail::tvec3<T>& mean, T std_deviation); //!< \brief Gererate 3 random floating numbers according a Gauss distribution. (From GLM_GTX_random extension)
+ template <typename T> detail::tvec4<T> gaussRand4(const detail::tvec4<T>& mean, T std_deviation); //!< \brief Gererate 4 random floating numbers according a Gauss distribution. (From GLM_GTX_random extension)
+ template <typename T> detail::tvec2<T> gaussRand2(T mean, const detail::tvec2<T>& std_deviation); //!< \brief Gererate 2 random floating numbers according a Gauss distribution. (From GLM_GTX_random extension)
+ template <typename T> detail::tvec3<T> gaussRand3(T mean, const detail::tvec3<T>& std_deviation); //!< \brief Gererate 3 random floating numbers according a Gauss distribution. (From GLM_GTX_random extension)
+ template <typename T> detail::tvec4<T> gaussRand4(T mean, const detail::tvec4<T>& std_deviation); //!< \brief Gererate 4 random floating numbers according a Gauss distribution. (From GLM_GTX_random extension)
+ template <typename T> detail::tvec2<T> gaussRand2(const detail::tvec2<T>& mean, const detail::tvec2<T>& std_deviation); //!< \brief Gererate 2 random floating numbers according a Gauss distribution. (From GLM_GTX_random extension)
+ template <typename T> detail::tvec3<T> gaussRand3(const detail::tvec3<T>& mean, const detail::tvec3<T>& std_deviation); //!< \brief Gererate 3 random floating numbers according a Gauss distribution. (From GLM_GTX_random extension)
+ template <typename T> detail::tvec4<T> gaussRand4(const detail::tvec4<T>& mean, const detail::tvec4<T>& std_deviation); //!< \brief Gererate 4 random floating numbers according a Gauss distribution. (From GLM_GTX_random extension)
+
+ ///@}
+}//namespace random
+}//namespace gtx
+}//namespace glm
+
+#include "random.inl"
+
+namespace glm{using namespace gtx::random;}
+
+#endif//glm_gtx_random
diff --git a/src/glm/gtx/random.inl b/src/glm/gtx/random.inl
new file mode 100644
index 0000000..5cd0095
--- /dev/null
+++ b/src/glm/gtx/random.inl
@@ -0,0 +1,536 @@
+//////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+//////////////////////////////////////////////////////////////////////////////////
+// Created : 2006-01-16
+// Updated : 2006-01-16
+// Licence : This source is under MIT License
+// File : glm/gtx/random.inl
+//////////////////////////////////////////////////////////////////////////////////
+
+#include <ctime>
+#include <cassert>
+
+namespace glm{
+namespace gtx{
+namespace random
+{
+ template <>
+ GLM_FUNC_QUALIFIER float signedRand1()
+ {
+ #if(GLM_COMPILER & GLM_COMPILER_VC)// && (GLM_COMPILER < GLM_COMPILER_VC2010)
+ #define RAND_SHIFT_NUM 5
+ #else
+ #define RAND_SHIFT_NUM 0
+ #endif
+ return float((std::rand() - (RAND_MAX >> 1) - 1) << 1) / float(RAND_MAX - RAND_SHIFT_NUM);
+ }
+
+ template <>
+ GLM_FUNC_QUALIFIER double signedRand1()
+ {
+ return double(signedRand1<float>());
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<T> signedRand2()
+ {
+ return detail::tvec2<T>(
+ signedRand1<float>(),
+ signedRand1<float>());
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> signedRand3()
+ {
+ return detail::tvec3<T>(
+ signedRand1<float>(),
+ signedRand1<float>(),
+ signedRand1<float>());
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<T> signedRand4()
+ {
+ return detail::tvec4<T>(
+ signedRand1<float>(),
+ signedRand1<float>(),
+ signedRand1<float>(),
+ signedRand1<float>());
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<T> normalizedRand2()
+ {
+ T a = compRand1<T>(T(0), T(6.283185307179586476925286766559f));
+ return detail::tvec2<T>(cos(a), sin(a));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> normalizedRand3()
+ {
+ T z = compRand1(T(-1), T(1));
+ T a = compRand1(T(0), T(6.283185307179586476925286766559f));
+
+ T r = sqrt(T(1) - z * z);
+
+ T x = r * cos(a);
+ T y = r * sin(a);
+
+ return detail::tvec3<T>(x, y, z);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> normalizedRand3(
+ T Min,
+ T Max)
+ {
+ return normalizedRand3<T>() * compRand1(Min, Max);
+ }
+
+ template <>
+ GLM_FUNC_QUALIFIER float compRand1()
+ {
+ return float(std::rand()) / float(RAND_MAX);
+ }
+
+ template <>
+ GLM_FUNC_QUALIFIER double compRand1()
+ {
+ return double(std::rand()) / double(RAND_MAX);
+ }
+
+ GLM_FUNC_QUALIFIER glm::half compRand1(
+ glm::half Min,
+ glm::half Max)
+ {
+ return compRand1<glm::half>() * (Max - Min) + Min;
+ }
+
+ GLM_FUNC_QUALIFIER float compRand1(
+ float Min,
+ float Max)
+ {
+ return compRand1<float>() * (Max - Min) + Min;
+ }
+
+ GLM_FUNC_QUALIFIER double compRand1(
+ double Min,
+ double Max)
+ {
+ return compRand1<double>() * (Max - Min) + Min;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER T compRand1(
+ T Min,
+ T Max)
+ {
+ return T(compRand1<double>() * double(Max - Min) + double(Min));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<T> compRand2(
+ T Min,
+ T Max)
+ {
+ return detail::tvec2<T>(
+ compRand1(Min, Max),
+ compRand1(Min, Max));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> compRand3(
+ T Min,
+ T Max)
+ {
+ return detail::tvec3<T>(
+ compRand1(Min, Max),
+ compRand1(Min, Max),
+ compRand1(Min, Max));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<T> compRand4(
+ T Min,
+ T Max)
+ {
+ return detail::tvec4<T>(
+ compRand1(Min, Max),
+ compRand1(Min, Max),
+ compRand1(Min, Max),
+ compRand1(Min, Max));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<T> compRand2(
+ T Min,
+ const detail::tvec2<T>& Max)
+ {
+ return detail::tvec2<T>(
+ compRand1(Min.x, Max.x),
+ compRand1(Min.y, Max.y));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> compRand3(
+ T Min,
+ const detail::tvec3<T>& Max)
+ {
+ return detail::tvec3<T>(
+ compRand1(Min.x, Max.x),
+ compRand1(Min.y, Max.y),
+ compRand1(Min.z, Max.z));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<T> compRand4(
+ T Min,
+ const detail::tvec4<T>& Max)
+ {
+ return detail::tvec4<T>(
+ compRand1(Min.x, Max.x),
+ compRand1(Min.y, Max.y),
+ compRand1(Min.z, Max.z),
+ compRand1(Min.w, Max.w));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<T> compRand2(
+ const detail::tvec2<T>& Min,
+ T Max)
+ {
+ return detail::tvec2<T>(
+ compRand1(Min.x, Max.x),
+ compRand1(Min.y, Max.y));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> compRand3(
+ const detail::tvec3<T>& Min,
+ T Max)
+ {
+ return detail::tvec3<T>(
+ compRand1(Min.x, Max.x),
+ compRand1(Min.y, Max.y),
+ compRand1(Min.z, Max.z));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<T> compRand4(
+ const detail::tvec4<T>& Min,
+ T Max)
+ {
+ return detail::tvec4<T>(
+ compRand1(Min.x, Max.x),
+ compRand1(Min.y, Max.y),
+ compRand1(Min.z, Max.z),
+ compRand1(Min.w, Max.w));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<T> compRand2(
+ const detail::tvec2<T>& Min,
+ const detail::tvec2<T>& Max)
+ {
+ return detail::tvec2<T>(
+ compRand1(Min.x, Max.x),
+ compRand1(Min.y, Max.y));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> compRand3(
+ const detail::tvec3<T>& Min,
+ const detail::tvec3<T>& Max)
+ {
+ return detail::tvec3<T>(
+ compRand1(Min.x, Max.x),
+ compRand1(Min.y, Max.y),
+ compRand1(Min.z, Max.z));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<T> compRand4(
+ const detail::tvec4<T>& Min,
+ const detail::tvec4<T>& Max)
+ {
+ return detail::tvec4<T>(
+ compRand1(Min.x, Max.x),
+ compRand1(Min.y, Max.y),
+ compRand1(Min.z, Max.z),
+ compRand1(Min.w, Max.w));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<float> vecRand2()
+ {
+ detail::tvec2<float> result(float(0));
+ do
+ {
+ result = compRand2(float(-1), float(1));
+ } while (length(result) > float(1));
+
+ return result;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<double> vecRand2()
+ {
+ detail::tvec2<double> result(double(0));
+ do
+ {
+ result = compRand2(double(-1), double(1));
+ } while (length(result) > double(1));
+
+ return result;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<T> vecRand2(
+ T MinRadius,
+ T MaxRadius)
+ {
+ assert(MinRadius <= MaxRadius);
+
+ detail::tvec2<T> Result(T(0));
+ T LenRadius(0);
+
+ do
+ {
+ Result = compRand2(-MaxRadius, MaxRadius);
+ LenRadius = length(Result);
+ }
+ while(LenRadius > MaxRadius || LenRadius < MinRadius);
+
+ return Result;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> vecRand3()
+ {
+ detail::tvec3<T> Result(T(0));
+ do
+ {
+ Result = compRand3(T(-1), T(1));
+ }
+ while(length(Result) > T(1));
+
+ return Result;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> vecRand3(
+ T MinRadius,
+ T MaxRadius)
+ {
+ assert(MinRadius <= MaxRadius);
+
+ detail::tvec3<T> Result(0);
+ T LenRadius(0);
+
+ do
+ {
+ Result = compRand3(-MaxRadius, MaxRadius);
+ LenRadius = length(Result);
+ }
+ while(LenRadius > MaxRadius || LenRadius < MinRadius);
+
+ return Result;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<float> vecRand4()
+ {
+ detail::tvec4<float> result(float(0));
+ do
+ {
+ result = compRand4(float(-1), float(1));
+ } while (length(result) > float(1));
+
+ return result;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<double> vecRand4()
+ {
+ detail::tvec4<double> result(double(0));
+ do
+ {
+ result = compRand4(double(-1), double(1));
+ } while (length(result) > double(1));
+
+ return result;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<T> vecRand4(
+ T MinRadius,
+ T MaxRadius)
+ {
+ assert(MinRadius <= MaxRadius);
+
+ detail::tvec4<T> Result(T(0));
+ T LenRadius(T(0));
+
+ do
+ {
+ Result = compRand4(-MaxRadius, MaxRadius);
+ LenRadius = length(Result);
+ }
+ while(LenRadius > MaxRadius || LenRadius < MinRadius);
+
+ return Result;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER T gaussRand1(
+ T mean,
+ T std_deviation)
+ {
+ T w, x1, x2;
+
+ do
+ {
+ x1 = compRand1(T(-1), T(1));
+ x2 = compRand1(T(-1), T(1));
+
+ w = x1 * x1 + x2 * x2;
+ } while(w > T(1));
+
+ return x2 * std_deviation * std_deviation * sqrt((T(-2) * log(w)) / w) + mean;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<T> gaussRand2(
+ T mean,
+ T std_deviation)
+ {
+ return detail::tvec2<T>(
+ gaussRand1(mean, std_deviation),
+ gaussRand1(mean, std_deviation));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> gaussRand3(
+ T mean,
+ T std_deviation)
+ {
+ return detail::tvec3<T>(
+ gaussRand1(mean, std_deviation),
+ gaussRand1(mean, std_deviation),
+ gaussRand1(mean, std_deviation));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<T> gaussRand4(
+ T mean,
+ T std_deviation)
+ {
+ return detail::tvec4<T>(
+ gaussRand1(mean, std_deviation),
+ gaussRand1(mean, std_deviation),
+ gaussRand1(mean, std_deviation),
+ gaussRand1(mean, std_deviation));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<T> gaussRand2(
+ T mean,
+ const detail::tvec2<T>& std_deviation)
+ {
+ return detail::tvec2<T>(
+ gaussRand1(mean, std_deviation.x),
+ gaussRand1(mean, std_deviation.y));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> gaussRand3(
+ T mean,
+ const detail::tvec3<T>& std_deviation)
+ {
+ return detail::tvec3<T>(
+ gaussRand1(mean, std_deviation.x),
+ gaussRand1(mean, std_deviation.y),
+ gaussRand1(mean, std_deviation.z));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<T> gaussRand4(
+ T mean,
+ const detail::tvec4<T>& std_deviation)
+ {
+ return detail::tvec4<T>(
+ gaussRand1(mean, std_deviation.x),
+ gaussRand1(mean, std_deviation.y),
+ gaussRand1(mean, std_deviation.z),
+ gaussRand1(mean, std_deviation.w));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<T> gaussRand2(
+ const detail::tvec2<T>& mean,
+ T std_deviation)
+ {
+ return detail::tvec2<T>(
+ gaussRand1(mean.x, std_deviation),
+ gaussRand1(mean.y, std_deviation));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> gaussRand3(
+ const detail::tvec3<T>& mean,
+ T std_deviation)
+ {
+ return detail::tvec3<T>(
+ gaussRand1(mean.x, std_deviation),
+ gaussRand1(mean.y, std_deviation),
+ gaussRand1(mean.z, std_deviation));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<T> gaussRand4(
+ const detail::tvec4<T>& mean,
+ T std_deviation)
+ {
+ return detail::tvec4<T>(
+ gaussRand1(mean.x, std_deviation),
+ gaussRand1(mean.y, std_deviation),
+ gaussRand1(mean.z, std_deviation),
+ gaussRand1(mean.w, std_deviation));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<T> gaussRand2(
+ const detail::tvec2<T>& mean,
+ const detail::tvec2<T>& std_deviation)
+ {
+ return detail::tvec2<T>(
+ gaussRand1(mean.x, std_deviation.x),
+ gaussRand1(mean.y, std_deviation.y));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> gaussRand3(
+ const detail::tvec3<T>& mean,
+ const detail::tvec3<T>& std_deviation)
+ {
+ return detail::tvec3<T>(
+ gaussRand1(mean.x, std_deviation.x),
+ gaussRand1(mean.y, std_deviation.y),
+ gaussRand1(mean.z, std_deviation.z));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<T> gaussRand4(
+ const detail::tvec4<T>& mean,
+ const detail::tvec4<T>& std_deviation)
+ {
+ return detail::tvec4<T>(
+ gaussRand1(mean.x, std_deviation.x),
+ gaussRand1(mean.y, std_deviation.y),
+ gaussRand1(mean.z, std_deviation.z),
+ gaussRand1(mean.w, std_deviation.w));
+ }
+
+}//namespace random
+}//namespace gtx
+}//namespace glm
diff --git a/src/glm/gtx/raw_data.hpp b/src/glm/gtx/raw_data.hpp
new file mode 100644
index 0000000..9479bb2
--- /dev/null
+++ b/src/glm/gtx/raw_data.hpp
@@ -0,0 +1,58 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2008-11-19
+// Updated : 2010-01-28
+// Licence : This source is under MIT License
+// File : glm/gtx/raw_data.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_gtx_raw_data
+#define glm_gtx_raw_data
+
+// Dependency:
+#include "../glm.hpp"
+#include "../gtc/type_precision.hpp"
+
+#if(defined(GLM_MESSAGES) && !defined(glm_ext))
+# pragma message("GLM: GLM_GTX_raw_data extension included")
+#endif
+
+namespace glm{
+namespace gtx{
+namespace raw_data ///< GLM_GTX_raw_data extension: Projection of a vector to other one
+{
+ using namespace gtc::type_precision;
+
+ /// \addtogroup gtx_raw_data
+ ///@{
+
+ //! Type for byte numbers.
+ //! From GLM_GTX_raw_data extension.
+ typedef uint8 byte;
+
+ //! Type for word numbers.
+ //! From GLM_GTX_raw_data extension.
+ typedef uint16 word;
+
+ //! Type for dword numbers.
+ //! From GLM_GTX_raw_data extension.
+ typedef uint32 dword;
+
+ //! Type for qword numbers.
+ //! From GLM_GTX_raw_data extension.
+ typedef uint64 qword;
+
+ ///@}
+}// namespace raw_data
+}// namespace gtx
+}// namespace glm
+
+#include "raw_data.inl"
+
+namespace glm{using namespace gtx::raw_data;}
+
+#endif//glm_gtx_raw_data
diff --git a/src/glm/gtx/raw_data.inl b/src/glm/gtx/raw_data.inl
new file mode 100644
index 0000000..893d550
--- /dev/null
+++ b/src/glm/gtx/raw_data.inl
@@ -0,0 +1,11 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2008-11-19
+// Updated : 2008-11-19
+// Licence : This source is under MIT License
+// File : glm/gtx/raw_data.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/glm/gtx/reciprocal.hpp b/src/glm/gtx/reciprocal.hpp
new file mode 100644
index 0000000..af9b288
--- /dev/null
+++ b/src/glm/gtx/reciprocal.hpp
@@ -0,0 +1,99 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2008-10-09
+// Updated : 2008-10-09
+// Licence : This source is under MIT License
+// File : glm/gtx/reciprocal.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_gtx_reciprocal
+#define glm_gtx_reciprocal
+
+// Dependency:
+#include "../glm.hpp"
+
+#if(defined(GLM_MESSAGES) && !defined(glm_ext))
+# pragma message("GLM: GLM_GTX_reciprocal extension included")
+#endif
+
+namespace glm{
+namespace gtx{
+namespace reciprocal ///< GLM_GTX_reciprocal extension: Define secant, cosecant and cotangent functions.
+{
+ /// \addtogroup gtx_reciprocal
+ /// @{
+
+ //! Secant function.
+ //! hypotenuse / adjacent or 1 / cos(x)
+ //! From GLM_GTX_reciprocal extension.
+ template <typename genType>
+ genType sec(genType const & angle);
+
+ //! Cosecant function.
+ //! hypotenuse / opposite or 1 / sin(x)
+ //! From GLM_GTX_reciprocal extension.
+ template <typename genType>
+ genType csc(genType const & angle);
+
+ //! Cotangent function.
+ //! adjacent / opposite or 1 / tan(x)
+ //! From GLM_GTX_reciprocal extension.
+ template <typename genType>
+ genType cot(genType const & angle);
+
+ //! Inverse secant function.
+ //! From GLM_GTX_reciprocal extension.
+ template <typename genType>
+ genType asec(genType const & x);
+
+ //! Inverse cosecant function.
+ //! From GLM_GTX_reciprocal extension.
+ template <typename genType>
+ genType acsc(genType const & x);
+
+ //! Inverse cotangent function.
+ //! From GLM_GTX_reciprocal extension.
+ template <typename genType>
+ genType acot(genType const & x);
+
+ //! Secant hyperbolic function.
+ //! From GLM_GTX_reciprocal extension.
+ template <typename genType>
+ genType sech(genType const & angle);
+
+ //! Cosecant hyperbolic function.
+ //! From GLM_GTX_reciprocal extension.
+ template <typename genType>
+ genType csch(genType const & angle);
+
+ //! Cotangent hyperbolic function.
+ //! From GLM_GTX_reciprocal extension.
+ template <typename genType>
+ genType coth(genType const & angle);
+
+ //! Inverse secant hyperbolic function.
+ //! From GLM_GTX_reciprocal extension.
+ template <typename genType>
+ genType asech(genType const & x);
+
+ //! Inverse cosecant hyperbolic function.
+ //! From GLM_GTX_reciprocal extension.
+ template <typename genType>
+ genType acsch(genType const & x);
+
+ //! Inverse cotangent hyperbolic function.
+ //! From GLM_GTX_reciprocal extension.
+ template <typename genType>
+ genType acoth(genType const & x);
+
+ /// @}
+}//namespace reciprocal
+}//namespace gtx
+}//namespace glm
+
+#include "reciprocal.inl"
+
+namespace glm{using namespace gtx::reciprocal;}
+
+#endif//glm_gtx_reciprocal
diff --git a/src/glm/gtx/reciprocal.inl b/src/glm/gtx/reciprocal.inl
new file mode 100644
index 0000000..27ecd1e
--- /dev/null
+++ b/src/glm/gtx/reciprocal.inl
@@ -0,0 +1,593 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2008-10-09
+// Updated : 2008-10-09
+// Licence : This source is under MIT License
+// File : glm/gtx/reciprocal.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm{
+namespace gtx{
+namespace reciprocal{
+
+// sec
+template <typename genType>
+GLM_FUNC_QUALIFIER genType sec
+(
+ genType const & angle
+)
+{
+ GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'sec' only accept floating-point values");
+
+ return genType(1) / glm::cos(angle);
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec2<valType> sec
+(
+ detail::tvec2<valType> const & angle
+)
+{
+ return detail::tvec2<valType>(
+ sec(angle.x),
+ sec(angle.y));
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec3<valType> sec
+(
+ detail::tvec3<valType> const & angle
+)
+{
+ return detail::tvec3<valType>(
+ sec(angle.x),
+ sec(angle.y),
+ sec(angle.z));
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec4<valType> sec
+(
+ detail::tvec4<valType> const & angle
+)
+{
+ return detail::tvec4<valType>(
+ sec(angle.x),
+ sec(angle.y),
+ sec(angle.z),
+ sec(angle.w));
+}
+
+// csc
+template <typename genType>
+GLM_FUNC_QUALIFIER genType csc
+(
+ genType const & angle
+)
+{
+ GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'csc' only accept floating-point values");
+
+ return genType(1) / glm::sin(angle);
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec2<valType> csc
+(
+ detail::tvec2<valType> const & angle
+)
+{
+ return detail::tvec2<valType>(
+ csc(angle.x),
+ csc(angle.y));
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec3<valType> csc
+(
+ detail::tvec3<valType> const & angle
+)
+{
+ return detail::tvec3<valType>(
+ csc(angle.x),
+ csc(angle.y),
+ csc(angle.z));
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec4<valType> csc
+(
+ detail::tvec4<valType> const & angle
+)
+{
+ return detail::tvec4<valType>(
+ csc(angle.x),
+ csc(angle.y),
+ csc(angle.z),
+ csc(angle.w));
+}
+
+// cot
+template <typename genType>
+GLM_FUNC_QUALIFIER genType cot
+(
+ genType const & angle
+)
+{
+ GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'cot' only accept floating-point values");
+
+ return genType(1) / glm::tan(angle);
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec2<valType> cot
+(
+ detail::tvec2<valType> const & angle
+)
+{
+ return detail::tvec2<valType>(
+ cot(angle.x),
+ cot(angle.y));
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec3<valType> cot
+(
+ detail::tvec3<valType> const & angle
+)
+{
+ return detail::tvec3<valType>(
+ cot(angle.x),
+ cot(angle.y),
+ cot(angle.z));
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec4<valType> cot
+(
+ detail::tvec4<valType> const & angle
+)
+{
+ return detail::tvec4<valType>(
+ cot(angle.x),
+ cot(angle.y),
+ cot(angle.z),
+ cot(angle.w));
+}
+
+// asec
+template <typename genType>
+GLM_FUNC_QUALIFIER genType asec
+(
+ genType const & x
+)
+{
+ GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'asec' only accept floating-point values");
+
+ return acos(genType(1) / x);
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec2<valType> asec
+(
+ detail::tvec2<valType> const & x
+)
+{
+ return detail::tvec2<valType>(
+ asec(x.x),
+ asec(x.y));
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec3<valType> asec
+(
+ detail::tvec3<valType> const & x
+)
+{
+ return detail::tvec3<valType>(
+ asec(x.x),
+ asec(x.y),
+ asec(x.z));
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec4<valType> asec
+(
+ detail::tvec4<valType> const & x
+)
+{
+ return detail::tvec4<valType>(
+ asec(x.x),
+ asec(x.y),
+ asec(x.z),
+ asec(x.w));
+}
+
+// acsc
+template <typename genType>
+GLM_FUNC_QUALIFIER genType acsc
+(
+ genType const & x
+)
+{
+ GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'acsc' only accept floating-point values");
+
+ return asin(genType(1) / x);
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec2<valType> acsc
+(
+ detail::tvec2<valType> const & x
+)
+{
+ return detail::tvec2<valType>(
+ acsc(x.x),
+ acsc(x.y));
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec3<valType> acsc
+(
+ detail::tvec3<valType> const & x
+)
+{
+ return detail::tvec3<valType>(
+ acsc(x.x),
+ acsc(x.y),
+ acsc(x.z));
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec4<valType> acsc
+(
+ detail::tvec4<valType> const & x
+)
+{
+ return detail::tvec4<valType>(
+ acsc(x.x),
+ acsc(x.y),
+ acsc(x.z),
+ acsc(x.w));
+}
+
+// acot
+template <typename genType>
+GLM_FUNC_QUALIFIER genType acot
+(
+ genType const & x
+)
+{
+ GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'acot' only accept floating-point values");
+
+ genType const pi_over_2 = genType(3.1415926535897932384626433832795 / 2.0);
+ return pi_over_2 - atan(x);
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec2<valType> acot
+(
+ detail::tvec2<valType> const & x
+)
+{
+ return detail::tvec2<valType>(
+ acot(x.x),
+ acot(x.y));
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec3<valType> acot
+(
+ detail::tvec3<valType> const & x
+)
+{
+ return detail::tvec3<valType>(
+ acot(x.x),
+ acot(x.y),
+ acot(x.z));
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec4<valType> acot
+(
+ detail::tvec4<valType> const & x
+)
+{
+ return detail::tvec4<valType>(
+ acot(x.x),
+ acot(x.y),
+ acot(x.z),
+ acot(x.w));
+}
+
+// sech
+template <typename genType>
+GLM_FUNC_QUALIFIER genType sech
+(
+ genType const & angle
+)
+{
+ GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'sech' only accept floating-point values");
+
+ return genType(1) / glm::cosh(angle);
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec2<valType> sech
+(
+ detail::tvec2<valType> const & angle
+)
+{
+ return detail::tvec2<valType>(
+ sech(angle.x),
+ sech(angle.y));
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec3<valType> sech
+(
+ detail::tvec3<valType> const & angle
+)
+{
+ return detail::tvec3<valType>(
+ sech(angle.x),
+ sech(angle.y),
+ sech(angle.z));
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec4<valType> sech
+(
+ detail::tvec4<valType> const & angle
+)
+{
+ return detail::tvec4<valType>(
+ sech(angle.x),
+ sech(angle.y),
+ sech(angle.z),
+ sech(angle.w));
+}
+
+// csch
+template <typename genType>
+GLM_FUNC_QUALIFIER genType csch
+(
+ genType const & angle
+)
+{
+ GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'csch' only accept floating-point values");
+
+ return genType(1) / glm::sinh(angle);
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec2<valType> csch
+(
+ detail::tvec2<valType> const & angle
+)
+{
+ return detail::tvec2<valType>(
+ csch(angle.x),
+ csch(angle.y));
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec3<valType> csch
+(
+ detail::tvec3<valType> const & angle
+)
+{
+ return detail::tvec3<valType>(
+ csch(angle.x),
+ csch(angle.y),
+ csch(angle.z));
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec4<valType> csch
+(
+ detail::tvec4<valType> const & angle
+)
+{
+ return detail::tvec4<valType>(
+ csch(angle.x),
+ csch(angle.y),
+ csch(angle.z),
+ csch(angle.w));
+}
+
+// coth
+template <typename genType>
+GLM_FUNC_QUALIFIER genType coth
+(
+ genType const & angle
+)
+{
+ GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'coth' only accept floating-point values");
+
+ return glm::cosh(angle) / glm::sinh(angle);
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec2<valType> coth
+(
+ detail::tvec2<valType> const & angle
+)
+{
+ return detail::tvec2<valType>(
+ coth(angle.x),
+ coth(angle.y));
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec3<valType> coth
+(
+ detail::tvec3<valType> const & angle
+)
+{
+ return detail::tvec3<valType>(
+ coth(angle.x),
+ coth(angle.y),
+ coth(angle.z));
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec4<valType> coth
+(
+ detail::tvec4<valType> const & angle
+)
+{
+ return detail::tvec4<valType>(
+ coth(angle.x),
+ coth(angle.y),
+ coth(angle.z),
+ coth(angle.w));
+}
+
+// asech
+template <typename genType>
+GLM_FUNC_QUALIFIER genType asech
+(
+ genType const & x
+)
+{
+ GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'asech' only accept floating-point values");
+
+ return acosh(genType(1) / x);
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec2<valType> asech
+(
+ detail::tvec2<valType> const & x
+)
+{
+ return detail::tvec2<valType>(
+ asech(x.x),
+ asech(x.y));
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec3<valType> asech
+(
+ detail::tvec3<valType> const & x
+)
+{
+ return detail::tvec3<valType>(
+ asech(x.x),
+ asech(x.y),
+ asech(x.z));
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec4<valType> asech
+(
+ detail::tvec4<valType> const & x
+)
+{
+ return detail::tvec4<valType>(
+ asech(x.x),
+ asech(x.y),
+ asech(x.z),
+ asech(x.w));
+}
+
+// acsch
+template <typename genType>
+GLM_FUNC_QUALIFIER genType acsch
+(
+ genType const & x
+)
+{
+ GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'acsch' only accept floating-point values");
+
+ return asinh(genType(1) / x);
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec2<valType> acsch
+(
+ detail::tvec2<valType> const & x
+)
+{
+ return detail::tvec2<valType>(
+ acsch(x.x),
+ acsch(x.y));
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec3<valType> acsch
+(
+ detail::tvec3<valType> const & x
+)
+{
+ return detail::tvec3<valType>(
+ acsch(x.x),
+ acsch(x.y),
+ acsch(x.z));
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec4<valType> acsch
+(
+ detail::tvec4<valType> const & x
+)
+{
+ return detail::tvec4<valType>(
+ acsch(x.x),
+ acsch(x.y),
+ acsch(x.z),
+ acsch(x.w));
+}
+
+// acoth
+template <typename genType>
+GLM_FUNC_QUALIFIER genType acoth
+(
+ genType const & x
+)
+{
+ GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'acoth' only accept floating-point values");
+
+ return atanh(genType(1) / x);
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec2<valType> acoth
+(
+ detail::tvec2<valType> const & x
+)
+{
+ return detail::tvec2<valType>(
+ acoth(x.x),
+ acoth(x.y));
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec3<valType> acoth
+(
+ detail::tvec3<valType> const & x
+)
+{
+ return detail::tvec3<valType>(
+ acoth(x.x),
+ acoth(x.y),
+ acoth(x.z));
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER detail::tvec4<valType> acoth
+(
+ detail::tvec4<valType> const & x
+)
+{
+ return detail::tvec4<valType>(
+ acoth(x.x),
+ acoth(x.y),
+ acoth(x.z),
+ acoth(x.w));
+}
+
+}//namespace reciprocal
+}//namespace gtx
+}//namespace glm
diff --git a/src/glm/gtx/rotate_vector.hpp b/src/glm/gtx/rotate_vector.hpp
new file mode 100644
index 0000000..bb9148f
--- /dev/null
+++ b/src/glm/gtx/rotate_vector.hpp
@@ -0,0 +1,114 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2006-11-02
+// Updated : 2009-02-19
+// Licence : This source is under MIT License
+// File : glm/gtx/rotate_vector.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_gtx_rotate_vector
+#define glm_gtx_rotate_vector
+
+// Dependency:
+#include "../glm.hpp"
+#include "../gtx/transform.hpp"
+
+#if(defined(GLM_MESSAGES) && !defined(glm_ext))
+# pragma message("GLM: GLM_GTX_rotate_vector extension included")
+#endif
+
+namespace glm{
+namespace gtx{
+namespace rotate_vector ///< GLM_GTX_rotate_vector extension: Function to directly rotate a vector
+{
+ using namespace transform;
+
+ /// \addtogroup gtx_rotate_vector
+ /// @{
+
+ //! Rotate a two dimensional vector.
+ //! From GLM_GTX_rotate_vector extension.
+ template <typename T>
+ detail::tvec2<T> rotate(
+ detail::tvec2<T> const & v,
+ T const & angle);
+
+ //! Rotate a three dimensional vector around an axis.
+ //! From GLM_GTX_rotate_vector extension.
+ template <typename T>
+ detail::tvec3<T> rotate(
+ detail::tvec3<T> const & v,
+ T const & angle,
+ detail::tvec3<T> const & normal);
+
+ //! Rotate a four dimensional vector around an axis.
+ //! From GLM_GTX_rotate_vector extension.
+ template <typename T>
+ detail::tvec4<T> rotate(
+ detail::tvec4<T> const & v,
+ T const & angle,
+ detail::tvec3<T> const & normal);
+
+ //! Rotate a three dimensional vector around the X axis.
+ //! From GLM_GTX_rotate_vector extension.
+ template <typename T>
+ detail::tvec3<T> rotateX(
+ detail::tvec3<T> const & v,
+ T const & angle);
+
+ //! Rotate a three dimensional vector around the Y axis.
+ //! From GLM_GTX_rotate_vector extension.
+ template <typename T>
+ detail::tvec3<T> rotateY(
+ detail::tvec3<T> const & v,
+ T const & angle);
+
+ //! Rotate a three dimensional vector around the Z axis.
+ //! From GLM_GTX_rotate_vector extension.
+ template <typename T>
+ detail::tvec3<T> rotateZ(
+ detail::tvec3<T> const & v,
+ T const & angle);
+
+ //! Rotate a four dimentionnals vector around the X axis.
+ //! From GLM_GTX_rotate_vector extension.
+ template <typename T>
+ detail::tvec4<T> rotateX(
+ detail::tvec4<T> const & v,
+ T const & angle);
+
+ //! Rotate a four dimensional vector around the X axis.
+ //! From GLM_GTX_rotate_vector extension.
+ template <typename T>
+ detail::tvec4<T> rotateY(
+ detail::tvec4<T> const & v,
+ T const & angle);
+
+ //! Rotate a four dimensional vector around the X axis.
+ //! From GLM_GTX_rotate_vector extension.
+ template <typename T>
+ detail::tvec4<T> rotateZ(
+ detail::tvec4<T> const & v,
+ T const & angle);
+
+ //! Build a rotation matrix from a normal and a up vector.
+ //! From GLM_GTX_rotate_vector extension.
+ template <typename T>
+ detail::tmat4x4<T> orientation(
+ detail::tvec3<T> const & Normal,
+ detail::tvec3<T> const & Up);
+
+ /// @}
+}//namespace rotate_vector
+}//namespace gtx
+}//namespace glm
+
+#include "rotate_vector.inl"
+
+namespace glm{using namespace gtx::rotate_vector;}
+
+#endif//glm_gtx_rotate_vector
diff --git a/src/glm/gtx/rotate_vector.inl b/src/glm/gtx/rotate_vector.inl
new file mode 100644
index 0000000..0db2308
--- /dev/null
+++ b/src/glm/gtx/rotate_vector.inl
@@ -0,0 +1,149 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2006-11-02
+// Updated : 2009-02-19
+// Licence : This source is under MIT License
+// File : glm/gtx/rotate_vector.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm{
+namespace gtx{
+namespace rotate_vector
+{
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<T> rotate(
+ detail::tvec2<T> const & v,
+ T const & angle)
+ {
+ detail::tvec2<T> Result;
+ const T Cos = cos(radians(angle));
+ const T Sin = sin(radians(angle));
+ Result.x = v.x * Cos - v.y * Sin;
+ Result.y = v.x * Sin + v.y * Cos;
+ return Result;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> rotate(
+ const detail::tvec3<T> & v,
+ T const & angle,
+ const detail::tvec3<T> & normal)
+ {
+ return detail::tmat3x3<T>(glm::gtx::transform::rotate(angle, normal)) * v;
+ }
+/*
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> rotateGTX(
+ const detail::tvec3<T>& x,
+ T angle,
+ const detail::tvec3<T>& normal)
+ {
+ const T Cos = cos(radians(angle));
+ const T Sin = sin(radians(angle));
+ return x * Cos + ((x * normal) * (T(1) - Cos)) * normal + cross(x, normal) * Sin;
+ }
+*/
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<T> rotate(
+ detail::tvec4<T> const & v,
+ T const & angle,
+ detail::tvec3<T> const & normal)
+ {
+ return glm::gtx::transform::rotate(angle, normal) * v;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> rotateX(
+ detail::tvec3<T> const & v,
+ T const & angle)
+ {
+ detail::tvec3<T> Result = v;
+ const T Cos = cos(radians(angle));
+ const T Sin = sin(radians(angle));
+ Result.y = v.y * Cos - v.z * Sin;
+ Result.z = v.y * Sin + v.z * Cos;
+ return Result;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> rotateY(
+ detail::tvec3<T> const & v,
+ T const & angle)
+ {
+ detail::tvec3<T> Result = v;
+ const T Cos = cos(radians(angle));
+ const T Sin = sin(radians(angle));
+ Result.x = v.x * Cos + v.z * Sin;
+ Result.z = -v.x * Sin + v.z * Cos;
+ return Result;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> rotateZ(
+ detail::tvec3<T> const & v,
+ T const & angle)
+ {
+ detail::tvec3<T> Result = v;
+ const T Cos = cos(radians(angle));
+ const T Sin = sin(radians(angle));
+ Result.x = v.x * Cos - v.y * Sin;
+ Result.y = v.x * Sin + v.y * Cos;
+ return Result;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<T> rotateX(
+ detail::tvec4<T> const & v,
+ T const & angle)
+ {
+ detail::tvec4<T> Result = v;
+ const T Cos = cos(radians(angle));
+ const T Sin = sin(radians(angle));
+ Result.y = v.y * Cos - v.z * Sin;
+ Result.z = v.y * Sin + v.z * Cos;
+ return Result;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<T> rotateY(
+ detail::tvec4<T> const & v,
+ T const & angle)
+ {
+ detail::tvec4<T> Result = v;
+ const T Cos = cos(radians(angle));
+ const T Sin = sin(radians(angle));
+ Result.x = v.x * Cos + v.z * Sin;
+ Result.z = -v.x * Sin + v.z * Cos;
+ return Result;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<T> rotateZ(
+ detail::tvec4<T> const & v,
+ T const & angle)
+ {
+ detail::tvec4<T> Result = v;
+ const T Cos = cos(radians(angle));
+ const T Sin = sin(radians(angle));
+ Result.x = v.x * Cos - v.y * Sin;
+ Result.y = v.x * Sin + v.y * Cos;
+ return Result;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tmat4x4<T> orientation(
+ detail::tvec3<T> const & Normal,
+ detail::tvec3<T> const & Up)
+ {
+ if(all(equal(Normal, Up)))
+ return detail::tmat4x4<T>(T(1));
+
+ detail::tvec3<T> RotationAxis = cross(Up, Normal);
+ T Angle = degrees(acos(dot(Normal, Up)));
+ return glm::gtx::transform::rotate(Angle, RotationAxis);
+ }
+
+}//namespace rotate_vector
+}//namespace gtx
+}//namespace glm
diff --git a/src/glm/gtx/simd_mat4.hpp b/src/glm/gtx/simd_mat4.hpp
new file mode 100644
index 0000000..5c822cc
--- /dev/null
+++ b/src/glm/gtx/simd_mat4.hpp
@@ -0,0 +1,183 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2009-05-07
+// Updated : 2009-05-07
+// Licence : This source is under MIT License
+// File : glm/gtx/simd_vec4.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+// - intrinsic
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_gtx_simd_mat4
+#define glm_gtx_simd_mat4
+
+// Dependency:
+#include "../glm.hpp"
+
+#if(GLM_ARCH & GLM_ARCH_SSE2)
+# include "../core/intrinsic_matrix.hpp"
+# include "../gtx/simd_vec4.hpp"
+#else
+# error "GLM: GLM_GTX_simd_mat4 requires compiler support of SSE2 through intrinsics"
+#endif
+
+#if(defined(GLM_MESSAGES) && !defined(glm_ext))
+# pragma message("GLM: GLM_GTX_simd_mat4 extension included")
+#endif
+
+namespace glm{
+namespace detail
+{
+ /// 4x4 Matrix implemented using SIMD SEE intrinsics.
+ /// \ingroup gtx_simd_mat4
+ GLM_ALIGNED_STRUCT(16) fmat4x4SIMD
+ {
+ enum ctor{null};
+
+ typedef float value_type;
+ typedef fvec4SIMD col_type;
+ typedef fvec4SIMD row_type;
+ typedef std::size_t size_type;
+ static size_type value_size();
+ static size_type col_size();
+ static size_type row_size();
+ static bool is_matrix();
+
+ fvec4SIMD Data[4];
+
+ //////////////////////////////////////
+ // Constructors
+
+ fmat4x4SIMD();
+ explicit fmat4x4SIMD(float const & s);
+ explicit fmat4x4SIMD(
+ float const & x0, float const & y0, float const & z0, float const & w0,
+ float const & x1, float const & y1, float const & z1, float const & w1,
+ float const & x2, float const & y2, float const & z2, float const & w2,
+ float const & x3, float const & y3, float const & z3, float const & w3);
+ explicit fmat4x4SIMD(
+ fvec4SIMD const & v0,
+ fvec4SIMD const & v1,
+ fvec4SIMD const & v2,
+ fvec4SIMD const & v3);
+ explicit fmat4x4SIMD(
+ tmat4x4<float> const & m);
+
+ // Conversions
+ //template <typename U>
+ //explicit tmat4x4(tmat4x4<U> const & m);
+
+ //explicit tmat4x4(tmat2x2<T> const & x);
+ //explicit tmat4x4(tmat3x3<T> const & x);
+ //explicit tmat4x4(tmat2x3<T> const & x);
+ //explicit tmat4x4(tmat3x2<T> const & x);
+ //explicit tmat4x4(tmat2x4<T> const & x);
+ //explicit tmat4x4(tmat4x2<T> const & x);
+ //explicit tmat4x4(tmat3x4<T> const & x);
+ //explicit tmat4x4(tmat4x3<T> const & x);
+
+ // Accesses
+ fvec4SIMD & operator[](size_type i);
+ fvec4SIMD const & operator[](size_type i) const;
+
+ // Unary updatable operators
+ fmat4x4SIMD & operator= (fmat4x4SIMD const & m);
+ fmat4x4SIMD & operator+= (float const & s);
+ fmat4x4SIMD & operator+= (fmat4x4SIMD const & m);
+ fmat4x4SIMD & operator-= (float const & s);
+ fmat4x4SIMD & operator-= (fmat4x4SIMD const & m);
+ fmat4x4SIMD & operator*= (float const & s);
+ fmat4x4SIMD & operator*= (fmat4x4SIMD const & m);
+ fmat4x4SIMD & operator/= (float const & s);
+ fmat4x4SIMD & operator/= (fmat4x4SIMD const & m);
+ fmat4x4SIMD & operator++ ();
+ fmat4x4SIMD & operator-- ();
+ };
+
+ // Binary operators
+ fmat4x4SIMD operator+ (fmat4x4SIMD const & m, float const & s);
+ fmat4x4SIMD operator+ (float const & s, fmat4x4SIMD const & m);
+ fmat4x4SIMD operator+ (fmat4x4SIMD const & m1, fmat4x4SIMD const & m2);
+
+ fmat4x4SIMD operator- (fmat4x4SIMD const & m, float const & s);
+ fmat4x4SIMD operator- (float const & s, fmat4x4SIMD const & m);
+ fmat4x4SIMD operator- (fmat4x4SIMD const & m1, fmat4x4SIMD const & m2);
+
+ fmat4x4SIMD operator* (fmat4x4SIMD const & m, float const & s);
+ fmat4x4SIMD operator* (float const & s, fmat4x4SIMD const & m);
+
+ fvec4SIMD operator* (fmat4x4SIMD const & m, fvec4SIMD const & v);
+ fvec4SIMD operator* (fvec4SIMD const & v, fmat4x4SIMD const & m);
+
+ fmat4x4SIMD operator* (fmat4x4SIMD const & m1, fmat4x4SIMD const & m2);
+
+ fmat4x4SIMD operator/ (fmat4x4SIMD const & m, float const & s);
+ fmat4x4SIMD operator/ (float const & s, fmat4x4SIMD const & m);
+
+ fvec4SIMD operator/ (fmat4x4SIMD const & m, fvec4SIMD const & v);
+ fvec4SIMD operator/ (fvec4SIMD const & v, fmat4x4SIMD const & m);
+
+ fmat4x4SIMD operator/ (fmat4x4SIMD const & m1, fmat4x4SIMD const & m2);
+
+ // Unary constant operators
+ fmat4x4SIMD const operator- (fmat4x4SIMD const & m);
+ fmat4x4SIMD const operator-- (fmat4x4SIMD const & m, int);
+ fmat4x4SIMD const operator++ (fmat4x4SIMD const & m, int);
+}//namespace detail
+
+namespace gtx{
+namespace simd_mat4 ///< GLM_GTX_simd_mat4 extension: SIMD implementation of mat4 type.
+{
+ typedef detail::fmat4x4SIMD simdMat4;
+
+ /// \addtogroup gtx_simd_mat4
+ ///@{
+
+ //! Convert a simdMat4 to a mat4.
+ //! (From GLM_GTX_simd_mat4 extension)
+ detail::tmat4x4<float> mat4_cast(
+ detail::fmat4x4SIMD const & x);
+
+ //! Multiply matrix x by matrix y component-wise, i.e.,
+ //! result[i][j] is the scalar product of x[i][j] and y[i][j].
+ //! (From GLM_GTX_simd_mat4 extension).
+ detail::fmat4x4SIMD matrixCompMult(
+ detail::fmat4x4SIMD const & x,
+ detail::fmat4x4SIMD const & y);
+
+ //! Treats the first parameter c as a column vector
+ //! and the second parameter r as a row vector
+ //! and does a linear algebraic matrix multiply c * r.
+ //! (From GLM_GTX_simd_mat4 extension).
+ detail::fmat4x4SIMD outerProduct(
+ detail::fvec4SIMD const & c,
+ detail::fvec4SIMD const & r);
+
+ //! Returns the transposed matrix of x
+ //! (From GLM_GTX_simd_mat4 extension).
+ detail::fmat4x4SIMD transpose(
+ detail::fmat4x4SIMD const & x);
+
+ //! Return the determinant of a mat4 matrix.
+ //! (From GLM_GTX_simd_mat4 extension).
+ float determinant(
+ detail::fmat4x4SIMD const & m);
+
+ //! Return the inverse of a mat4 matrix.
+ //! (From GLM_GTX_simd_mat4 extension).
+ detail::fmat4x4SIMD inverse(
+ detail::fmat4x4SIMD const & m);
+
+ /// @}
+}// namespace simd_mat4
+}// namespace gtx
+}// namespace glm
+
+#include "simd_mat4.inl"
+
+namespace glm{using namespace gtx::simd_mat4;}
+
+#endif//glm_gtx_simd_mat4
diff --git a/src/glm/gtx/simd_mat4.inl b/src/glm/gtx/simd_mat4.inl
new file mode 100644
index 0000000..6f4b918
--- /dev/null
+++ b/src/glm/gtx/simd_mat4.inl
@@ -0,0 +1,309 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2009-05-19
+// Updated : 2009-05-19
+// Licence : This source is under MIT License
+// File : glm/gtx/simd_mat4.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm{
+namespace detail
+{
+ GLM_FUNC_QUALIFIER fmat4x4SIMD::size_type fmat4x4SIMD::value_size()
+ {
+ return sizeof(value_type);
+ }
+
+ GLM_FUNC_QUALIFIER fmat4x4SIMD::size_type fmat4x4SIMD::col_size()
+ {
+ return 4;
+ }
+
+ GLM_FUNC_QUALIFIER fmat4x4SIMD::size_type fmat4x4SIMD::row_size()
+ {
+ return 4;
+ }
+
+ GLM_FUNC_QUALIFIER fmat4x4SIMD::fmat4x4SIMD()
+ {}
+
+ GLM_FUNC_QUALIFIER fmat4x4SIMD::fmat4x4SIMD(float const & s)
+ {
+ this->Data[0] = fvec4SIMD(s, 0, 0, 0);
+ this->Data[1] = fvec4SIMD(0, s, 0, 0);
+ this->Data[2] = fvec4SIMD(0, 0, s, 0);
+ this->Data[3] = fvec4SIMD(0, 0, 0, s);
+ }
+
+ GLM_FUNC_QUALIFIER fmat4x4SIMD::fmat4x4SIMD
+ (
+ float const & x0, float const & y0, float const & z0, float const & w0,
+ float const & x1, float const & y1, float const & z1, float const & w1,
+ float const & x2, float const & y2, float const & z2, float const & w2,
+ float const & x3, float const & y3, float const & z3, float const & w3
+ )
+ {
+ this->Data[0] = fvec4SIMD(x0, y0, z0, w0);
+ this->Data[1] = fvec4SIMD(x1, y1, z1, w1);
+ this->Data[2] = fvec4SIMD(x2, y2, z2, w2);
+ this->Data[3] = fvec4SIMD(x3, y3, z3, w3);
+ }
+
+ GLM_FUNC_QUALIFIER fmat4x4SIMD::fmat4x4SIMD
+ (
+ fvec4SIMD const & v0,
+ fvec4SIMD const & v1,
+ fvec4SIMD const & v2,
+ fvec4SIMD const & v3
+ )
+ {
+ this->Data[0] = v0;
+ this->Data[1] = v1;
+ this->Data[2] = v2;
+ this->Data[3] = v3;
+ }
+
+ GLM_FUNC_QUALIFIER fmat4x4SIMD::fmat4x4SIMD
+ (
+ tmat4x4<float> const & m
+ )
+ {
+ this->Data[0] = fvec4SIMD(m[0]);
+ this->Data[1] = fvec4SIMD(m[1]);
+ this->Data[2] = fvec4SIMD(m[2]);
+ this->Data[3] = fvec4SIMD(m[3]);
+ }
+
+ //////////////////////////////////////
+ // Accesses
+
+ GLM_FUNC_QUALIFIER fvec4SIMD & fmat4x4SIMD::operator[]
+ (
+ fmat4x4SIMD::size_type i
+ )
+ {
+ assert(
+ i >= fmat4x4SIMD::size_type(0) &&
+ i < fmat4x4SIMD::col_size());
+
+ return this->Data[i];
+ }
+
+ GLM_FUNC_QUALIFIER fvec4SIMD const & fmat4x4SIMD::operator[]
+ (
+ fmat4x4SIMD::size_type i
+ ) const
+ {
+ assert(
+ i >= fmat4x4SIMD::size_type(0) &&
+ i < fmat4x4SIMD::col_size());
+
+ return this->Data[i];
+ }
+
+ //////////////////////////////////////////////////////////////
+ // mat4 operators
+
+ GLM_FUNC_QUALIFIER fmat4x4SIMD& fmat4x4SIMD::operator=
+ (
+ fmat4x4SIMD const & m
+ )
+ {
+ this->Data[0] = m[0];
+ this->Data[1] = m[1];
+ this->Data[2] = m[2];
+ this->Data[3] = m[3];
+ return *this;
+ }
+
+ GLM_FUNC_QUALIFIER fmat4x4SIMD & fmat4x4SIMD::operator+=
+ (
+ fmat4x4SIMD const & m
+ )
+ {
+ this->Data[0].Data = _mm_add_ps(this->Data[0].Data, m[0].Data);
+ this->Data[1].Data = _mm_add_ps(this->Data[1].Data, m[1].Data);
+ this->Data[2].Data = _mm_add_ps(this->Data[2].Data, m[2].Data);
+ this->Data[3].Data = _mm_add_ps(this->Data[3].Data, m[3].Data);
+ return *this;
+ }
+
+ GLM_FUNC_QUALIFIER fmat4x4SIMD & fmat4x4SIMD::operator-=
+ (
+ fmat4x4SIMD const & m
+ )
+ {
+ this->Data[0].Data = _mm_sub_ps(this->Data[0].Data, m[0].Data);
+ this->Data[1].Data = _mm_sub_ps(this->Data[1].Data, m[1].Data);
+ this->Data[2].Data = _mm_sub_ps(this->Data[2].Data, m[2].Data);
+ this->Data[3].Data = _mm_sub_ps(this->Data[3].Data, m[3].Data);
+
+ return *this;
+ }
+
+ GLM_FUNC_QUALIFIER fmat4x4SIMD & fmat4x4SIMD::operator*=
+ (
+ fmat4x4SIMD const & m
+ )
+ {
+ sse_mul_ps(&this->Data[0].Data, &m.Data[0].Data, &this->Data[0].Data);
+ return *this;
+ }
+
+ GLM_FUNC_QUALIFIER fmat4x4SIMD & fmat4x4SIMD::operator/=
+ (
+ fmat4x4SIMD const & m
+ )
+ {
+ __m128 Inv[4];
+ sse_inverse_ps(&this->Data[0].Data, Inv);
+ sse_mul_ps(&this->Data[0].Data, Inv, &this->Data[0].Data);
+ return *this;
+ }
+
+ GLM_FUNC_QUALIFIER fmat4x4SIMD & fmat4x4SIMD::operator+=
+ (
+ float const & s
+ )
+ {
+ __m128 Operand = _mm_set_ps1(s);
+ this->Data[0].Data = _mm_add_ps(this->Data[0].Data, Operand);
+ this->Data[1].Data = _mm_add_ps(this->Data[1].Data, Operand);
+ this->Data[2].Data = _mm_add_ps(this->Data[2].Data, Operand);
+ this->Data[3].Data = _mm_add_ps(this->Data[3].Data, Operand);
+ return *this;
+ }
+
+ GLM_FUNC_QUALIFIER fmat4x4SIMD & fmat4x4SIMD::operator-=
+ (
+ float const & s
+ )
+ {
+ __m128 Operand = _mm_set_ps1(s);
+ this->Data[0].Data = _mm_sub_ps(this->Data[0].Data, Operand);
+ this->Data[1].Data = _mm_sub_ps(this->Data[1].Data, Operand);
+ this->Data[2].Data = _mm_sub_ps(this->Data[2].Data, Operand);
+ this->Data[3].Data = _mm_sub_ps(this->Data[3].Data, Operand);
+ return *this;
+ }
+
+ GLM_FUNC_QUALIFIER fmat4x4SIMD & fmat4x4SIMD::operator*=
+ (
+ float const & s
+ )
+ {
+ __m128 Operand = _mm_set_ps1(s);
+ this->Data[0].Data = _mm_mul_ps(this->Data[0].Data, Operand);
+ this->Data[1].Data = _mm_mul_ps(this->Data[1].Data, Operand);
+ this->Data[2].Data = _mm_mul_ps(this->Data[2].Data, Operand);
+ this->Data[3].Data = _mm_mul_ps(this->Data[3].Data, Operand);
+ return *this;
+ }
+
+ GLM_FUNC_QUALIFIER fmat4x4SIMD & fmat4x4SIMD::operator/=
+ (
+ float const & s
+ )
+ {
+ __m128 Operand = _mm_div_ps(one, _mm_set_ps1(s));
+ this->Data[0].Data = _mm_mul_ps(this->Data[0].Data, Operand);
+ this->Data[1].Data = _mm_mul_ps(this->Data[1].Data, Operand);
+ this->Data[2].Data = _mm_mul_ps(this->Data[2].Data, Operand);
+ this->Data[3].Data = _mm_mul_ps(this->Data[3].Data, Operand);
+ return *this;
+ }
+
+ GLM_FUNC_QUALIFIER fmat4x4SIMD & fmat4x4SIMD::operator++ ()
+ {
+ this->Data[0].Data = _mm_add_ps(this->Data[0].Data, one);
+ this->Data[1].Data = _mm_add_ps(this->Data[1].Data, one);
+ this->Data[2].Data = _mm_add_ps(this->Data[2].Data, one);
+ this->Data[3].Data = _mm_add_ps(this->Data[3].Data, one);
+ return *this;
+ }
+
+ GLM_FUNC_QUALIFIER fmat4x4SIMD & fmat4x4SIMD::operator-- ()
+ {
+ this->Data[0].Data = _mm_sub_ps(this->Data[0].Data, one);
+ this->Data[1].Data = _mm_sub_ps(this->Data[1].Data, one);
+ this->Data[2].Data = _mm_sub_ps(this->Data[2].Data, one);
+ this->Data[3].Data = _mm_sub_ps(this->Data[3].Data, one);
+ return *this;
+ }
+
+}//namespace detail
+
+namespace gtx{
+namespace simd_mat4
+{
+ GLM_FUNC_QUALIFIER detail::tmat4x4<float> mat4_cast
+ (
+ detail::fmat4x4SIMD const & x
+ )
+ {
+ GLM_ALIGN(16) detail::tmat4x4<float> Result;
+ _mm_store_ps(&Result[0][0], x.Data[0].Data);
+ _mm_store_ps(&Result[1][0], x.Data[1].Data);
+ _mm_store_ps(&Result[2][0], x.Data[2].Data);
+ _mm_store_ps(&Result[3][0], x.Data[3].Data);
+ return Result;
+ }
+
+ GLM_FUNC_QUALIFIER detail::fmat4x4SIMD matrixCompMult
+ (
+ detail::fmat4x4SIMD const & x,
+ detail::fmat4x4SIMD const & y
+ )
+ {
+ detail::fmat4x4SIMD result;
+ result[0] = x[0] * y[0];
+ result[1] = x[1] * y[1];
+ result[2] = x[2] * y[2];
+ result[3] = x[3] * y[3];
+ return result;
+ }
+
+ GLM_FUNC_QUALIFIER detail::fmat4x4SIMD outerProduct
+ (
+ detail::fvec4SIMD const & c,
+ detail::fvec4SIMD const & r
+ )
+ {
+ __m128 Shu0 = _mm_shuffle_ps(r.Data, r.Data, _MM_SHUFFLE(0, 0, 0, 0));
+ __m128 Shu1 = _mm_shuffle_ps(r.Data, r.Data, _MM_SHUFFLE(1, 1, 1, 1));
+ __m128 Shu2 = _mm_shuffle_ps(r.Data, r.Data, _MM_SHUFFLE(2, 2, 2, 2));
+ __m128 Shu3 = _mm_shuffle_ps(r.Data, r.Data, _MM_SHUFFLE(3, 3, 3, 3));
+
+ detail::fmat4x4SIMD result(detail::fmat4x4SIMD::null);
+ result[0].Data = _mm_mul_ps(c.Data, Shu0);
+ result[1].Data = _mm_mul_ps(c.Data, Shu1);
+ result[2].Data = _mm_mul_ps(c.Data, Shu2);
+ result[3].Data = _mm_mul_ps(c.Data, Shu3);
+ return result;
+ }
+
+ GLM_FUNC_QUALIFIER detail::fmat4x4SIMD transpose(detail::fmat4x4SIMD const & m)
+ {
+ detail::fmat4x4SIMD result;
+ detail::sse_transpose_ps(&m[0].Data, &result[0].Data);
+ return result;
+ }
+
+ GLM_FUNC_QUALIFIER float determinant(detail::fmat4x4SIMD const & m)
+ {
+ float Result;
+ _mm_store_ss(&Result, detail::sse_det_ps(&m[0].Data));
+ return Result;
+ }
+
+ GLM_FUNC_QUALIFIER detail::fmat4x4SIMD inverse(detail::fmat4x4SIMD const & m)
+ {
+ detail::fmat4x4SIMD result;
+ detail::sse_inverse_ps(&m[0].Data, &result[0].Data);
+ return result;
+ }
+}//namespace simd_mat4
+}//namespace gtx
+
+}//namespace glm
diff --git a/src/glm/gtx/simd_vec4.hpp b/src/glm/gtx/simd_vec4.hpp
new file mode 100644
index 0000000..f801437
--- /dev/null
+++ b/src/glm/gtx/simd_vec4.hpp
@@ -0,0 +1,474 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2009-05-07
+// Updated : 2009-05-07
+// Licence : This source is under MIT License
+// File : glm/gtx/simd_vec4.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+// - intrinsic
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_gtx_simd_vec4
+#define glm_gtx_simd_vec4
+
+// Dependency:
+#include "../glm.hpp"
+
+#if(GLM_ARCH & GLM_ARCH_SSE2)
+# include "../core/intrinsic_common.hpp"
+# include "../core/intrinsic_geometric.hpp"
+#else
+# error "GLM: GLM_GTX_simd_vec4 requires compiler support of SSE2 through intrinsics"
+#endif
+
+#if(defined(GLM_MESSAGES) && !defined(glm_ext))
+# pragma message("GLM: GLM_GTX_simd_vec4 extension included")
+#endif
+
+namespace glm{
+namespace detail
+{
+ /// 4-dimensional vector implemented using SIMD SEE intrinsics.
+ /// \ingroup gtx_simd_vec4
+ GLM_ALIGNED_STRUCT(16) fvec4SIMD
+ {
+ enum ctor{null};
+ typedef __m128 value_type;
+ typedef std::size_t size_type;
+ static size_type value_size();
+
+ typedef fvec4SIMD type;
+ typedef tvec4<bool> bool_type;
+
+ __m128 Data;
+
+ //////////////////////////////////////
+ // Implicit basic constructors
+
+ fvec4SIMD();
+ fvec4SIMD(__m128 const & Data);
+ fvec4SIMD(fvec4SIMD const & v);
+
+ //////////////////////////////////////
+ // Explicit basic constructors
+
+ explicit fvec4SIMD(
+ ctor);
+ explicit fvec4SIMD(
+ float const & s);
+ explicit fvec4SIMD(
+ float const & x,
+ float const & y,
+ float const & z,
+ float const & w);
+ explicit fvec4SIMD(
+ tvec4<float> const & v);
+
+ ////////////////////////////////////////
+ //// Convertion vector constructors
+
+ fvec4SIMD(vec2 const & v, float const & s1, float const & s2);
+ fvec4SIMD(float const & s1, vec2 const & v, float const & s2);
+ fvec4SIMD(float const & s1, float const & s2, vec2 const & v);
+ fvec4SIMD(vec3 const & v, float const & s);
+ fvec4SIMD(float const & s, vec3 const & v);
+ fvec4SIMD(vec2 const & v1, vec2 const & v2);
+ //fvec4SIMD(ivec4SIMD const & v);
+
+ //////////////////////////////////////
+ // Unary arithmetic operators
+
+ fvec4SIMD& operator= (fvec4SIMD const & v);
+ fvec4SIMD& operator+=(fvec4SIMD const & v);
+ fvec4SIMD& operator-=(fvec4SIMD const & v);
+ fvec4SIMD& operator*=(fvec4SIMD const & v);
+ fvec4SIMD& operator/=(fvec4SIMD const & v);
+
+ fvec4SIMD& operator+=(float const & s);
+ fvec4SIMD& operator-=(float const & s);
+ fvec4SIMD& operator*=(float const & s);
+ fvec4SIMD& operator/=(float const & s);
+
+ fvec4SIMD& operator++();
+ fvec4SIMD& operator--();
+
+ //////////////////////////////////////
+ // Swizzle operators
+
+ template <comp X, comp Y, comp Z, comp W>
+ fvec4SIMD& swizzle();
+ template <comp X, comp Y, comp Z, comp W>
+ fvec4SIMD swizzle() const;
+ template <comp X, comp Y, comp Z>
+ fvec4SIMD swizzle() const;
+ template <comp X, comp Y>
+ fvec4SIMD swizzle() const;
+ template <comp X>
+ fvec4SIMD swizzle() const;
+ };
+}//namespace detail
+
+namespace gtx{
+namespace simd_vec4 ///< GLM_GTX_simd_vec4 extension: SIMD implementation of vec4 type.
+{
+ typedef glm::detail::fvec4SIMD simdVec4;
+
+ /// \addtogroup gtx_simd_vec4
+ ///@{
+
+ //! Convert a simdVec4 to a vec4.
+ //! (From GLM_GTX_simd_vec4 extension)
+ detail::tvec4<float> vec4_cast(
+ detail::fvec4SIMD const & x);
+
+ //! Returns x if x >= 0; otherwise, it returns -x.
+ //! (From GLM_GTX_simd_vec4 extension, common function)
+ detail::fvec4SIMD abs(detail::fvec4SIMD const & x);
+
+ //! Returns 1.0 if x > 0, 0.0 if x = 0, or -1.0 if x < 0.
+ //! (From GLM_GTX_simd_vec4 extension, common function)
+ detail::fvec4SIMD sign(detail::fvec4SIMD const & x);
+
+ //! Returns a value equal to the nearest integer that is less then or equal to x.
+ //! (From GLM_GTX_simd_vec4 extension, common function)
+ detail::fvec4SIMD floor(detail::fvec4SIMD const & x);
+
+ //! Returns a value equal to the nearest integer to x
+ //! whose absolute value is not larger than the absolute value of x.
+ //! (From GLM_GTX_simd_vec4 extension, common function)
+ detail::fvec4SIMD trunc(detail::fvec4SIMD const & x);
+
+ //! Returns a value equal to the nearest integer to x.
+ //! The fraction 0.5 will round in a direction chosen by the
+ //! implementation, presumably the direction that is fastest.
+ //! This includes the possibility that round(x) returns the
+ //! same value as roundEven(x) for all values of x.
+ //! (From GLM_GTX_simd_vec4 extension, common function)
+ detail::fvec4SIMD round(detail::fvec4SIMD const & x);
+
+ //! Returns a value equal to the nearest integer to x.
+ //! A fractional part of 0.5 will round toward the nearest even
+ //! integer. (Both 3.5 and 4.5 for x will return 4.0.)
+ //! (From GLM_GTX_simd_vec4 extension, common function)
+ //detail::fvec4SIMD roundEven(detail::fvec4SIMD const & x);
+
+ //! Returns a value equal to the nearest integer
+ //! that is greater than or equal to x.
+ //! (From GLM_GTX_simd_vec4 extension, common function)
+ detail::fvec4SIMD ceil(detail::fvec4SIMD const & x);
+
+ //! Return x - floor(x).
+ //! (From GLM_GTX_simd_vec4 extension, common function)
+ detail::fvec4SIMD fract(detail::fvec4SIMD const & x);
+
+ //! Modulus. Returns x - y * floor(x / y)
+ //! for each component in x using the floating point value y.
+ //! (From GLM_GTX_simd_vec4 extension, common function)
+ detail::fvec4SIMD mod(
+ detail::fvec4SIMD const & x,
+ detail::fvec4SIMD const & y);
+
+ //! Modulus. Returns x - y * floor(x / y)
+ //! for each component in x using the floating point value y.
+ //! (From GLM_GTX_simd_vec4 extension, common function)
+ detail::fvec4SIMD mod(
+ detail::fvec4SIMD const & x,
+ float const & y);
+
+ //! Returns the fractional part of x and sets i to the integer
+ //! part (as a whole number floating point value). Both the
+ //! return value and the output parameter will have the same
+ //! sign as x.
+ //! (From GLM_GTX_simd_vec4 extension, common function)
+ //detail::fvec4SIMD modf(
+ // detail::fvec4SIMD const & x,
+ // detail::fvec4SIMD & i);
+
+ //! Returns y if y < x; otherwise, it returns x.
+ //! (From GLM_GTX_simd_vec4 extension, common function)
+ detail::fvec4SIMD min(
+ detail::fvec4SIMD const & x,
+ detail::fvec4SIMD const & y);
+
+ detail::fvec4SIMD min(
+ detail::fvec4SIMD const & x,
+ float const & y);
+
+ //! Returns y if x < y; otherwise, it returns x.
+ //! (From GLM_GTX_simd_vec4 extension, common function)
+ detail::fvec4SIMD max(
+ detail::fvec4SIMD const & x,
+ detail::fvec4SIMD const & y);
+
+ detail::fvec4SIMD max(
+ detail::fvec4SIMD const & x,
+ float const & y);
+
+ //! Returns min(max(x, minVal), maxVal) for each component in x
+ //! using the floating-point values minVal and maxVal.
+ //! (From GLM_GTX_simd_vec4 extension, common function)
+ detail::fvec4SIMD clamp(
+ detail::fvec4SIMD const & x,
+ detail::fvec4SIMD const & minVal,
+ detail::fvec4SIMD const & maxVal);
+
+ detail::fvec4SIMD clamp(
+ detail::fvec4SIMD const & x,
+ float const & minVal,
+ float const & maxVal);
+
+ //! \return If genTypeU is a floating scalar or vector:
+ //! Returns x * (1.0 - a) + y * a, i.e., the linear blend of
+ //! x and y using the floating-point value a.
+ //! The value for a is not restricted to the range [0, 1].
+ //!
+ //! \return If genTypeU is a boolean scalar or vector:
+ //! Selects which vector each returned component comes
+ //! from. For a component of a that is false, the
+ //! corresponding component of x is returned. For a
+ //! component of a that is true, the corresponding
+ //! component of y is returned. Components of x and y that
+ //! are not selected are allowed to be invalid floating point
+ //! values and will have no effect on the results. Thus, this
+ //! provides different functionality than
+ //! genType mix(genType x, genType y, genType(a))
+ //! where a is a Boolean vector.
+ //!
+ //! From GLSL 1.30.08 specification, section 8.3
+ //!
+ //! \param[in] x Floating point scalar or vector.
+ //! \param[in] y Floating point scalar or vector.
+ //! \param[in] a Floating point or boolean scalar or vector.
+ //!
+ // \todo Test when 'a' is a boolean.
+ //! (From GLM_GTX_simd_vec4 extension, common function)
+ detail::fvec4SIMD mix(
+ detail::fvec4SIMD const & x,
+ detail::fvec4SIMD const & y,
+ detail::fvec4SIMD const & a);
+
+ //! Returns 0.0 if x < edge, otherwise it returns 1.0.
+ //! (From GLM_GTX_simd_vec4 extension, common function)
+ detail::fvec4SIMD step(
+ detail::fvec4SIMD const & edge,
+ detail::fvec4SIMD const & x);
+
+ detail::fvec4SIMD step(
+ float const & edge,
+ detail::fvec4SIMD const & x);
+
+ //! Returns 0.0 if x <= edge0 and 1.0 if x >= edge1 and
+ //! performs smooth Hermite interpolation between 0 and 1
+ //! when edge0 < x < edge1. This is useful in cases where
+ //! you would want a threshold function with a smooth
+ //! transition. This is equivalent to:
+ //! genType t;
+ //! t = clamp ((x edge0) / (edge1 edge0), 0, 1);
+ //! return t * t * (3 2 * t);
+ //! Results are undefined if edge0 >= edge1.
+ //! (From GLM_GTX_simd_vec4 extension, common function)
+ detail::fvec4SIMD smoothstep(
+ detail::fvec4SIMD const & edge0,
+ detail::fvec4SIMD const & edge1,
+ detail::fvec4SIMD const & x);
+
+ detail::fvec4SIMD smoothstep(
+ float const & edge0,
+ float const & edge1,
+ detail::fvec4SIMD const & x);
+
+ //! Returns true if x holds a NaN (not a number)
+ //! representation in the underlying implementation's set of
+ //! floating point representations. Returns false otherwise,
+ //! including for implementations with no NaN
+ //! representations.
+ //! (From GLM_GTX_simd_vec4 extension, common function)
+ //bvec4 isnan(detail::fvec4SIMD const & x);
+
+ //! Returns true if x holds a positive infinity or negative
+ //! infinity representation in the underlying implementation's
+ //! set of floating point representations. Returns false
+ //! otherwise, including for implementations with no infinity
+ //! representations.
+ //! (From GLM_GTX_simd_vec4 extension, common function)
+ //bvec4 isinf(detail::fvec4SIMD const & x);
+
+ //! Returns a signed or unsigned integer value representing
+ //! the encoding of a floating-point value. The floatingpoint
+ //! value's bit-level representation is preserved.
+ //! (From GLM_GTX_simd_vec4 extension, common function)
+ //detail::ivec4SIMD floatBitsToInt(detail::fvec4SIMD const & value);
+
+ //! Returns a floating-point value corresponding to a signed
+ //! or unsigned integer encoding of a floating-point value.
+ //! If an inf or NaN is passed in, it will not signal, and the
+ //! resulting floating point value is unspecified. Otherwise,
+ //! the bit-level representation is preserved.
+ //! (From GLM_GTX_simd_vec4 extension, common function)
+ //detail::fvec4SIMD intBitsToFloat(detail::ivec4SIMD const & value);
+
+ //! Computes and returns a * b + c.
+ //! (From GLM_GTX_simd_vec4 extension, common function)
+ detail::fvec4SIMD fma(
+ detail::fvec4SIMD const & a,
+ detail::fvec4SIMD const & b,
+ detail::fvec4SIMD const & c);
+
+ //! Splits x into a floating-point significand in the range
+ //! [0.5, 1.0) and an integral exponent of two, such that:
+ //! x = significand * exp(2, exponent)
+ //! The significand is returned by the function and the
+ //! exponent is returned in the parameter exp. For a
+ //! floating-point value of zero, the significant and exponent
+ //! are both zero. For a floating-point value that is an
+ //! infinity or is not a number, the results are undefined.
+ //! (From GLM_GTX_simd_vec4 extension, common function)
+ //detail::fvec4SIMD frexp(detail::fvec4SIMD const & x, detail::ivec4SIMD & exp);
+
+ //! Builds a floating-point number from x and the
+ //! corresponding integral exponent of two in exp, returning:
+ //! significand * exp(2, exponent)
+ //! If this product is too large to be represented in the
+ //! floating-point type, the result is undefined.
+ //! (From GLM_GTX_simd_vec4 extension, common function)
+ //detail::fvec4SIMD ldexp(detail::fvec4SIMD const & x, detail::ivec4SIMD const & exp);
+
+ //! Returns the length of x, i.e., sqrt(x * x).
+ //! (From GLM_GTX_simd_vec4 extension, geometry functions)
+ float length(
+ detail::fvec4SIMD const & x);
+
+ //! Returns the length of x, i.e., sqrt(x * x).
+ //! Less accurate but much faster than simdLength.
+ //! (From GLM_GTX_simd_vec4 extension, geometry functions)
+ float fastLength(
+ detail::fvec4SIMD const & x);
+
+ //! Returns the length of x, i.e., sqrt(x * x).
+ //! Slightly more accurate but much slower than simdLength.
+ //! (From GLM_GTX_simd_vec4 extension, geometry functions)
+ float niceLength(
+ detail::fvec4SIMD const & x);
+
+ //! Returns the length of x, i.e., sqrt(x * x).
+ //! (From GLM_GTX_simd_vec4 extension, geometry functions)
+ detail::fvec4SIMD length4(
+ detail::fvec4SIMD const & x);
+
+ //! Returns the length of x, i.e., sqrt(x * x).
+ //! Less accurate but much faster than simdLength4.
+ //! (From GLM_GTX_simd_vec4 extension, geometry functions)
+ detail::fvec4SIMD fastLength4(
+ detail::fvec4SIMD const & x);
+
+ //! Returns the length of x, i.e., sqrt(x * x).
+ //! Slightly more accurate but much slower than simdLength4.
+ //! (From GLM_GTX_simd_vec4 extension, geometry functions)
+ detail::fvec4SIMD niceLength4(
+ detail::fvec4SIMD const & x);
+
+ //! Returns the distance betwwen p0 and p1, i.e., length(p0 - p1).
+ //! (From GLM_GTX_simd_vec4 extension, geometry functions)
+ float distance(
+ detail::fvec4SIMD const & p0,
+ detail::fvec4SIMD const & p1);
+
+ //! Returns the distance betwwen p0 and p1, i.e., length(p0 - p1).
+ //! (From GLM_GTX_simd_vec4 extension, geometry functions)
+ detail::fvec4SIMD distance4(
+ detail::fvec4SIMD const & p0,
+ detail::fvec4SIMD const & p1);
+
+ //! Returns the dot product of x and y, i.e., result = x * y.
+ //! (From GLM_GTX_simd_vec4 extension, geometry functions)
+ float simdDot(
+ detail::fvec4SIMD const & x,
+ detail::fvec4SIMD const & y);
+
+ //! Returns the dot product of x and y, i.e., result = x * y.
+ //! (From GLM_GTX_simd_vec4 extension, geometry functions)
+ detail::fvec4SIMD dot4(
+ detail::fvec4SIMD const & x,
+ detail::fvec4SIMD const & y);
+
+ //! Returns the cross product of x and y.
+ //! (From GLM_GTX_simd_vec4 extension, geometry functions)
+ detail::fvec4SIMD cross(
+ detail::fvec4SIMD const & x,
+ detail::fvec4SIMD const & y);
+
+ //! Returns a vector in the same direction as x but with length of 1.
+ //! (From GLM_GTX_simd_vec4 extension, geometry functions)
+ detail::fvec4SIMD normalize(
+ detail::fvec4SIMD const & x);
+
+ //! Returns a vector in the same direction as x but with length of 1.
+ //! Less accurate but much faster than simdNormalize.
+ //! (From GLM_GTX_simd_vec4 extension, geometry functions)
+ detail::fvec4SIMD fastNormalize(
+ detail::fvec4SIMD const & x);
+
+ //! If dot(Nref, I) < 0.0, return N, otherwise, return -N.
+ //! (From GLM_GTX_simd_vec4 extension, geometry functions)
+ detail::fvec4SIMD simdFaceforward(
+ detail::fvec4SIMD const & N,
+ detail::fvec4SIMD const & I,
+ detail::fvec4SIMD const & Nref);
+
+ //! For the incident vector I and surface orientation N,
+ //! returns the reflection direction : result = I - 2.0 * dot(N, I) * N.
+ //! (From GLM_GTX_simd_vec4 extension, geometry functions)
+ detail::fvec4SIMD reflect(
+ detail::fvec4SIMD const & I,
+ detail::fvec4SIMD const & N);
+
+ //! For the incident vector I and surface normal N,
+ //! and the ratio of indices of refraction eta,
+ //! return the refraction vector.
+ //! (From GLM_GTX_simd_vec4 extension, geometry functions)
+ detail::fvec4SIMD refract(
+ detail::fvec4SIMD const & I,
+ detail::fvec4SIMD const & N,
+ float const & eta);
+
+ //! Returns the positive square root of x.
+ //! (From GLM_GTX_simd_vec4 extension, exponential function)
+ detail::fvec4SIMD sqrt(
+ detail::fvec4SIMD const & x);
+
+ //! Returns the positive square root of x with the nicest quality but very slow.
+ //! Slightly more accurate but much slower than simdSqrt.
+ //! (From GLM_GTX_simd_vec4 extension, exponential function)
+ detail::fvec4SIMD niceSqrt(
+ detail::fvec4SIMD const & x);
+
+ //! Returns the positive square root of x
+ //! Less accurate but much faster than sqrt.
+ //! (From GLM_GTX_simd_vec4 extension, exponential function)
+ detail::fvec4SIMD fastSqrt(
+ detail::fvec4SIMD const & x);
+
+ //! Returns the reciprocal of the positive square root of x.
+ //! (From GLM_GTX_simd_vec4 extension, exponential function)
+ detail::fvec4SIMD inversesqrt(
+ detail::fvec4SIMD const & x);
+
+ //! Returns the reciprocal of the positive square root of x.
+ //! Faster than inversesqrt but less accurate.
+ //! (From GLM_GTX_simd_vec4 extension, exponential function)
+ detail::fvec4SIMD fastInversesqrt(
+ detail::fvec4SIMD const & x);
+
+ /// @}
+}//namespace simd_vec4
+}//namespace gtx
+}//namespace glm
+
+#include "simd_vec4.inl"
+
+namespace glm{using namespace gtx::simd_vec4;}
+
+#endif//glm_gtx_simd_vec4
diff --git a/src/glm/gtx/simd_vec4.inl b/src/glm/gtx/simd_vec4.inl
new file mode 100644
index 0000000..2f8397f
--- /dev/null
+++ b/src/glm/gtx/simd_vec4.inl
@@ -0,0 +1,730 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2009-05-07
+// Updated : 2009-05-07
+// Licence : This source is under MIT License
+// File : glm/gtx/simd_vec4.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm
+{
+ namespace detail
+ {
+ template <int Value>
+ struct mask
+ {
+ enum{value = Value};
+ };
+
+ //////////////////////////////////////
+ // Implicit basic constructors
+
+ GLM_FUNC_QUALIFIER fvec4SIMD::fvec4SIMD()
+ {}
+
+ GLM_FUNC_QUALIFIER fvec4SIMD::fvec4SIMD(__m128 const & Data) :
+ Data(Data)
+ {}
+
+ GLM_FUNC_QUALIFIER fvec4SIMD::fvec4SIMD(fvec4SIMD const & v) :
+ Data(v.Data)
+ {}
+
+ GLM_FUNC_QUALIFIER fvec4SIMD::fvec4SIMD(tvec4<float> const & v) :
+ Data(_mm_set_ps(v.w, v.z, v.y, v.x))
+ {}
+
+ //////////////////////////////////////
+ // Explicit basic constructors
+
+ GLM_FUNC_QUALIFIER fvec4SIMD::fvec4SIMD(float const & s) :
+ Data(_mm_set1_ps(s))
+ {}
+
+ GLM_FUNC_QUALIFIER fvec4SIMD::fvec4SIMD(float const & x, float const & y, float const & z, float const & w) :
+ // Data(_mm_setr_ps(x, y, z, w))
+ Data(_mm_set_ps(w, z, y, x))
+ {}
+/*
+ GLM_FUNC_QUALIFIER fvec4SIMD::fvec4SIMD(float const v[4]) :
+ Data(_mm_load_ps(v))
+ {}
+*/
+ //////////////////////////////////////
+ // Swizzle constructors
+
+ //fvec4SIMD(ref4<float> const & r);
+
+ //////////////////////////////////////
+ // Convertion vector constructors
+
+ GLM_FUNC_QUALIFIER fvec4SIMD::fvec4SIMD(vec2 const & v, float const & s1, float const & s2) :
+ Data(_mm_set_ps(s2, s1, v.y, v.x))
+ {}
+
+ GLM_FUNC_QUALIFIER fvec4SIMD::fvec4SIMD(float const & s1, vec2 const & v, float const & s2) :
+ Data(_mm_set_ps(s2, v.y, v.x, s1))
+ {}
+
+ GLM_FUNC_QUALIFIER fvec4SIMD::fvec4SIMD(float const & s1, float const & s2, vec2 const & v) :
+ Data(_mm_set_ps(v.y, v.x, s2, s1))
+ {}
+
+ GLM_FUNC_QUALIFIER fvec4SIMD::fvec4SIMD(vec3 const & v, float const & s) :
+ Data(_mm_set_ps(s, v.z, v.y, v.x))
+ {}
+
+ GLM_FUNC_QUALIFIER fvec4SIMD::fvec4SIMD(float const & s, vec3 const & v) :
+ Data(_mm_set_ps(v.z, v.y, v.x, s))
+ {}
+
+ GLM_FUNC_QUALIFIER fvec4SIMD::fvec4SIMD(vec2 const & v1, vec2 const & v2) :
+ Data(_mm_set_ps(v2.y, v2.x, v1.y, v1.x))
+ {}
+
+ //GLM_FUNC_QUALIFIER fvec4SIMD::fvec4SIMD(ivec4SIMD const & v) :
+ // Data(_mm_cvtepi32_ps(v.Data))
+ //{}
+
+ //////////////////////////////////////
+ // Unary arithmetic operators
+
+ GLM_FUNC_QUALIFIER fvec4SIMD& fvec4SIMD::operator=(fvec4SIMD const & v)
+ {
+ this->Data = v.Data;
+ return *this;
+ }
+
+ GLM_FUNC_QUALIFIER fvec4SIMD& fvec4SIMD::operator+=(float const & s)
+ {
+ this->Data = _mm_add_ps(Data, _mm_set_ps1(s));
+ return *this;
+ }
+
+ GLM_FUNC_QUALIFIER fvec4SIMD& fvec4SIMD::operator+=(fvec4SIMD const & v)
+ {
+ this->Data = _mm_add_ps(this->Data , v.Data);
+ return *this;
+ }
+
+ GLM_FUNC_QUALIFIER fvec4SIMD& fvec4SIMD::operator-=(float const & s)
+ {
+ this->Data = _mm_sub_ps(Data, _mm_set_ps1(s));
+ return *this;
+ }
+
+ GLM_FUNC_QUALIFIER fvec4SIMD& fvec4SIMD::operator-=(fvec4SIMD const & v)
+ {
+ this->Data = _mm_sub_ps(this->Data , v.Data);
+ return *this;
+ }
+
+ GLM_FUNC_QUALIFIER fvec4SIMD& fvec4SIMD::operator*=(float const & s)
+ {
+ this->Data = _mm_mul_ps(this->Data, _mm_set_ps1(s));
+ return *this;
+ }
+
+ GLM_FUNC_QUALIFIER fvec4SIMD& fvec4SIMD::operator*=(fvec4SIMD const & v)
+ {
+ this->Data = _mm_mul_ps(this->Data , v.Data);
+ return *this;
+ }
+
+ GLM_FUNC_QUALIFIER fvec4SIMD& fvec4SIMD::operator/=(float const & s)
+ {
+ this->Data = _mm_div_ps(Data, _mm_set1_ps(s));
+ return *this;
+ }
+
+ GLM_FUNC_QUALIFIER fvec4SIMD& fvec4SIMD::operator/=(fvec4SIMD const & v)
+ {
+ this->Data = _mm_div_ps(this->Data , v.Data);
+ return *this;
+ }
+
+ GLM_FUNC_QUALIFIER fvec4SIMD& fvec4SIMD::operator++()
+ {
+ this->Data = _mm_add_ps(this->Data , glm::detail::one);
+ return *this;
+ }
+
+ GLM_FUNC_QUALIFIER fvec4SIMD& fvec4SIMD::operator--()
+ {
+ this->Data = _mm_sub_ps(this->Data, glm::detail::one);
+ return *this;
+ }
+
+ //////////////////////////////////////
+ // Swizzle operators
+
+ template <comp X, comp Y, comp Z, comp W>
+ GLM_FUNC_QUALIFIER fvec4SIMD fvec4SIMD::swizzle() const
+ {
+ __m128 Data = _mm_shuffle_ps(
+ this->Data, this->Data,
+ mask<(W << 6) | (Z << 4) | (Y << 2) | (X << 0)>::value);
+ return fvec4SIMD(Data);
+ }
+
+ template <comp X, comp Y, comp Z, comp W>
+ GLM_FUNC_QUALIFIER fvec4SIMD& fvec4SIMD::swizzle()
+ {
+ this->Data = _mm_shuffle_ps(
+ this->Data, this->Data,
+ mask<(W << 6) | (Z << 4) | (Y << 2) | (X << 0)>::value);
+ return *this;
+ }
+
+ // operator+
+ GLM_FUNC_QUALIFIER fvec4SIMD operator+ (fvec4SIMD const & v, float s)
+ {
+ return fvec4SIMD(_mm_add_ps(v.Data, _mm_set1_ps(s)));
+ }
+
+ GLM_FUNC_QUALIFIER fvec4SIMD operator+ (float s, fvec4SIMD const & v)
+ {
+ return fvec4SIMD(_mm_add_ps(_mm_set1_ps(s), v.Data));
+ }
+
+ GLM_FUNC_QUALIFIER fvec4SIMD operator+ (fvec4SIMD const & v1, fvec4SIMD const & v2)
+ {
+ return fvec4SIMD(_mm_add_ps(v1.Data, v2.Data));
+ }
+
+ //operator-
+ GLM_FUNC_QUALIFIER fvec4SIMD operator- (fvec4SIMD const & v, float s)
+ {
+ return fvec4SIMD(_mm_sub_ps(v.Data, _mm_set1_ps(s)));
+ }
+
+ GLM_FUNC_QUALIFIER fvec4SIMD operator- (float s, fvec4SIMD const & v)
+ {
+ return fvec4SIMD(_mm_sub_ps(_mm_set1_ps(s), v.Data));
+ }
+
+ GLM_FUNC_QUALIFIER fvec4SIMD operator- (fvec4SIMD const & v1, fvec4SIMD const & v2)
+ {
+ return fvec4SIMD(_mm_sub_ps(v1.Data, v2.Data));
+ }
+
+ //operator*
+ GLM_FUNC_QUALIFIER fvec4SIMD operator* (fvec4SIMD const & v, float s)
+ {
+ __m128 par0 = v.Data;
+ __m128 par1 = _mm_set1_ps(s);
+ return fvec4SIMD(_mm_mul_ps(par0, par1));
+ }
+
+ GLM_FUNC_QUALIFIER fvec4SIMD operator* (float s, fvec4SIMD const & v)
+ {
+ __m128 par0 = _mm_set1_ps(s);
+ __m128 par1 = v.Data;
+ return fvec4SIMD(_mm_mul_ps(par0, par1));
+ }
+
+ GLM_FUNC_QUALIFIER fvec4SIMD operator* (fvec4SIMD const & v1, fvec4SIMD const & v2)
+ {
+ return fvec4SIMD(_mm_mul_ps(v1.Data, v2.Data));
+ }
+
+ //operator/
+ GLM_FUNC_QUALIFIER fvec4SIMD operator/ (fvec4SIMD const & v, float s)
+ {
+ __m128 par0 = v.Data;
+ __m128 par1 = _mm_set1_ps(s);
+ return fvec4SIMD(_mm_div_ps(par0, par1));
+ }
+
+ GLM_FUNC_QUALIFIER fvec4SIMD operator/ (float s, fvec4SIMD const & v)
+ {
+ __m128 par0 = _mm_set1_ps(s);
+ __m128 par1 = v.Data;
+ return fvec4SIMD(_mm_div_ps(par0, par1));
+ }
+
+ GLM_FUNC_QUALIFIER fvec4SIMD operator/ (fvec4SIMD const & v1, fvec4SIMD const & v2)
+ {
+ return fvec4SIMD(_mm_div_ps(v1.Data, v2.Data));
+ }
+
+ // Unary constant operators
+ GLM_FUNC_QUALIFIER fvec4SIMD operator- (fvec4SIMD const & v)
+ {
+ return fvec4SIMD(_mm_sub_ps(_mm_setzero_ps(), v.Data));
+ }
+
+ GLM_FUNC_QUALIFIER fvec4SIMD operator++ (fvec4SIMD const & v, int)
+ {
+ return fvec4SIMD(_mm_add_ps(v.Data, glm::detail::one));
+ }
+
+ GLM_FUNC_QUALIFIER fvec4SIMD operator-- (fvec4SIMD const & v, int)
+ {
+ return fvec4SIMD(_mm_sub_ps(v.Data, glm::detail::one));
+ }
+
+ }//namespace detail
+
+ namespace gtx{
+ namespace simd_vec4
+ {
+ GLM_FUNC_QUALIFIER detail::tvec4<float> vec4_cast
+ (
+ detail::fvec4SIMD const & x
+ )
+ {
+ GLM_ALIGN(16) detail::tvec4<float> Result;
+ _mm_store_ps(&Result[0], x.Data);
+ return Result;
+ }
+
+ // Other possible implementation
+ //float abs(float a)
+ //{
+ // return max(-a, a);
+ //}
+ GLM_FUNC_QUALIFIER detail::fvec4SIMD abs
+ (
+ detail::fvec4SIMD const & x
+ )
+ {
+ return detail::sse_abs_ps(x.Data);
+ }
+
+ GLM_FUNC_QUALIFIER detail::fvec4SIMD sign
+ (
+ detail::fvec4SIMD const & x
+ )
+ {
+ return detail::sse_sgn_ps(x.Data);
+ }
+
+ GLM_FUNC_QUALIFIER detail::fvec4SIMD floor
+ (
+ detail::fvec4SIMD const & x
+ )
+ {
+ return detail::sse_flr_ps(x.Data);
+ }
+
+ GLM_FUNC_QUALIFIER detail::fvec4SIMD trunc
+ (
+ detail::fvec4SIMD const & x
+ )
+ {
+ //return x < 0 ? -floor(-x) : floor(x);
+
+ __m128 Flr0 = detail::sse_flr_ps(_mm_sub_ps(_mm_setzero_ps(), x.Data));
+ __m128 Sub0 = _mm_sub_ps(Flr0, x.Data);
+ __m128 Flr1 = detail::sse_flr_ps(x.Data);
+
+ __m128 Cmp0 = _mm_cmplt_ps(x.Data, glm::detail::zero);
+ __m128 Cmp1 = _mm_cmpnlt_ps(x.Data, glm::detail::zero);
+
+ __m128 And0 = _mm_and_ps(Sub0, Cmp0);
+ __m128 And1 = _mm_and_ps(Flr1, Cmp1);
+
+ return _mm_or_ps(And0, And1);
+ }
+
+ GLM_FUNC_QUALIFIER detail::fvec4SIMD round
+ (
+ detail::fvec4SIMD const & x
+ )
+ {
+ return detail::sse_rnd_ps(x.Data);
+ }
+
+ //GLM_FUNC_QUALIFIER detail::fvec4SIMD roundEven
+ //(
+ // detail::fvec4SIMD const & x
+ //)
+ //{
+
+ //}
+
+ GLM_FUNC_QUALIFIER detail::fvec4SIMD ceil
+ (
+ detail::fvec4SIMD const & x
+ )
+ {
+ return detail::sse_ceil_ps(x.Data);
+ }
+
+ GLM_FUNC_QUALIFIER detail::fvec4SIMD fract
+ (
+ detail::fvec4SIMD const & x
+ )
+ {
+ return detail::sse_frc_ps(x.Data);
+ }
+
+ GLM_FUNC_QUALIFIER detail::fvec4SIMD mod
+ (
+ detail::fvec4SIMD const & x,
+ detail::fvec4SIMD const & y
+ )
+ {
+ return detail::sse_mod_ps(x.Data, y.Data);
+ }
+
+ GLM_FUNC_QUALIFIER detail::fvec4SIMD mod
+ (
+ detail::fvec4SIMD const & x,
+ float const & y
+ )
+ {
+ return detail::sse_mod_ps(x.Data, _mm_set1_ps(y));
+ }
+
+ //GLM_FUNC_QUALIFIER detail::fvec4SIMD modf
+ //(
+ // detail::fvec4SIMD const & x,
+ // detail::fvec4SIMD & i
+ //)
+ //{
+
+ //}
+
+ GLM_FUNC_QUALIFIER detail::fvec4SIMD min
+ (
+ detail::fvec4SIMD const & x,
+ detail::fvec4SIMD const & y
+ )
+ {
+ return _mm_min_ps(x.Data, y.Data);
+ }
+
+ GLM_FUNC_QUALIFIER detail::fvec4SIMD min
+ (
+ detail::fvec4SIMD const & x,
+ float const & y
+ )
+ {
+ return _mm_min_ps(x.Data, _mm_set1_ps(y));
+ }
+
+ GLM_FUNC_QUALIFIER detail::fvec4SIMD max
+ (
+ detail::fvec4SIMD const & x,
+ detail::fvec4SIMD const & y
+ )
+ {
+ return _mm_max_ps(x.Data, y.Data);
+ }
+
+ GLM_FUNC_QUALIFIER detail::fvec4SIMD max
+ (
+ detail::fvec4SIMD const & x,
+ float const & y
+ )
+ {
+ return _mm_max_ps(x.Data, _mm_set1_ps(y));
+ }
+
+ GLM_FUNC_QUALIFIER detail::fvec4SIMD clamp
+ (
+ detail::fvec4SIMD const & x,
+ detail::fvec4SIMD const & minVal,
+ detail::fvec4SIMD const & maxVal
+ )
+ {
+ return detail::sse_clp_ps(x.Data, minVal.Data, maxVal.Data);
+ }
+
+ GLM_FUNC_QUALIFIER detail::fvec4SIMD clamp
+ (
+ detail::fvec4SIMD const & x,
+ float const & minVal,
+ float const & maxVal
+ )
+ {
+ return detail::sse_clp_ps(x.Data, _mm_set1_ps(minVal), _mm_set1_ps(maxVal));
+ }
+
+ GLM_FUNC_QUALIFIER detail::fvec4SIMD mix
+ (
+ detail::fvec4SIMD const & x,
+ detail::fvec4SIMD const & y,
+ detail::fvec4SIMD const & a
+ )
+ {
+ __m128 Sub0 = _mm_sub_ps(y.Data, x.Data);
+ __m128 Mul0 = _mm_mul_ps(a.Data, Sub0);
+ return _mm_mul_ps(x.Data, Mul0);
+ }
+
+ GLM_FUNC_QUALIFIER detail::fvec4SIMD step
+ (
+ detail::fvec4SIMD const & edge,
+ detail::fvec4SIMD const & x
+ )
+ {
+ __m128 cmp0 = _mm_cmpngt_ps(x.Data, edge.Data);
+ return _mm_max_ps(_mm_min_ps(cmp0, _mm_setzero_ps()), detail::one);
+ }
+
+ GLM_FUNC_QUALIFIER detail::fvec4SIMD step
+ (
+ float const & edge,
+ detail::fvec4SIMD const & x
+ )
+ {
+ __m128 cmp0 = _mm_cmpngt_ps(x.Data, _mm_set1_ps(edge));
+ return _mm_max_ps(_mm_min_ps(cmp0, _mm_setzero_ps()), detail::one);
+ }
+
+ GLM_FUNC_QUALIFIER detail::fvec4SIMD smoothstep
+ (
+ detail::fvec4SIMD const & edge0,
+ detail::fvec4SIMD const & edge1,
+ detail::fvec4SIMD const & x
+ )
+ {
+ return detail::sse_ssp_ps(edge0.Data, edge1.Data, x.Data);
+ }
+
+ GLM_FUNC_QUALIFIER detail::fvec4SIMD smoothstep
+ (
+ float const & edge0,
+ float const & edge1,
+ detail::fvec4SIMD const & x
+ )
+ {
+ return detail::sse_ssp_ps(_mm_set1_ps(edge0), _mm_set1_ps(edge1), x.Data);
+ }
+
+ //GLM_FUNC_QUALIFIER bvec4 isnan(detail::fvec4SIMD const & x)
+ //{
+
+ //}
+
+ //GLM_FUNC_QUALIFIER bvec4 isinf(detail::fvec4SIMD const & x)
+ //{
+
+ //}
+
+ //GLM_FUNC_QUALIFIER detail::ivec4SIMD floatBitsToInt
+ //(
+ // detail::fvec4SIMD const & value
+ //)
+ //{
+
+ //}
+
+ //GLM_FUNC_QUALIFIER detail::fvec4SIMD intBitsToFloat
+ //(
+ // detail::ivec4SIMD const & value
+ //)
+ //{
+
+ //}
+
+ GLM_FUNC_QUALIFIER detail::fvec4SIMD fma
+ (
+ detail::fvec4SIMD const & a,
+ detail::fvec4SIMD const & b,
+ detail::fvec4SIMD const & c
+ )
+ {
+ return _mm_add_ps(_mm_mul_ps(a.Data, b.Data), c.Data);
+ }
+
+ GLM_FUNC_QUALIFIER float length
+ (
+ detail::fvec4SIMD const & x
+ )
+ {
+ detail::fvec4SIMD dot0 = detail::sse_dot_ss(x.Data, x.Data);
+ detail::fvec4SIMD sqt0 = sqrt(dot0);
+ float Result = 0;
+ _mm_store_ss(&Result, sqt0.Data);
+ return Result;
+ }
+
+ GLM_FUNC_QUALIFIER float fastLength
+ (
+ detail::fvec4SIMD const & x
+ )
+ {
+ detail::fvec4SIMD dot0 = detail::sse_dot_ss(x.Data, x.Data);
+ detail::fvec4SIMD sqt0 = fastSqrt(dot0);
+ float Result = 0;
+ _mm_store_ss(&Result, sqt0.Data);
+ return Result;
+ }
+
+ GLM_FUNC_QUALIFIER float niceLength
+ (
+ detail::fvec4SIMD const & x
+ )
+ {
+ detail::fvec4SIMD dot0 = detail::sse_dot_ss(x.Data, x.Data);
+ detail::fvec4SIMD sqt0 = niceSqrt(dot0);
+ float Result = 0;
+ _mm_store_ss(&Result, sqt0.Data);
+ return Result;
+ }
+
+ GLM_FUNC_QUALIFIER detail::fvec4SIMD length4
+ (
+ detail::fvec4SIMD const & x
+ )
+ {
+ return sqrt(dot4(x, x));
+ }
+
+ GLM_FUNC_QUALIFIER detail::fvec4SIMD fastLength4
+ (
+ detail::fvec4SIMD const & x
+ )
+ {
+ return fastSqrt(dot4(x, x));
+ }
+
+ GLM_FUNC_QUALIFIER detail::fvec4SIMD niceLength4
+ (
+ detail::fvec4SIMD const & x
+ )
+ {
+ return niceSqrt(dot4(x, x));
+ }
+
+ GLM_FUNC_QUALIFIER float distance
+ (
+ detail::fvec4SIMD const & p0,
+ detail::fvec4SIMD const & p1
+ )
+ {
+ float Result = 0;
+ _mm_store_ss(&Result, detail::sse_dst_ps(p0.Data, p1.Data));
+ return Result;
+ }
+
+ GLM_FUNC_QUALIFIER detail::fvec4SIMD distance4
+ (
+ detail::fvec4SIMD const & p0,
+ detail::fvec4SIMD const & p1
+ )
+ {
+ return detail::sse_dst_ps(p0.Data, p1.Data);
+ }
+
+ GLM_FUNC_QUALIFIER float dot
+ (
+ detail::fvec4SIMD const & x,
+ detail::fvec4SIMD const & y
+ )
+ {
+ float Result = 0;
+ _mm_store_ss(&Result, detail::sse_dot_ss(x.Data, y.Data));
+ return Result;
+ }
+
+ GLM_FUNC_QUALIFIER detail::fvec4SIMD dot4
+ (
+ detail::fvec4SIMD const & x,
+ detail::fvec4SIMD const & y
+ )
+ {
+ return detail::sse_dot_ps(x.Data, y.Data);
+ }
+
+ GLM_FUNC_QUALIFIER detail::fvec4SIMD cross
+ (
+ detail::fvec4SIMD const & x,
+ detail::fvec4SIMD const & y
+ )
+ {
+ return detail::sse_xpd_ps(x.Data, y.Data);
+ }
+
+ GLM_FUNC_QUALIFIER detail::fvec4SIMD normalize
+ (
+ detail::fvec4SIMD const & x
+ )
+ {
+ __m128 dot0 = detail::sse_dot_ps(x.Data, x.Data);
+ __m128 isr0 = inversesqrt(dot0).Data;
+ __m128 mul0 = _mm_mul_ps(x.Data, isr0);
+ return mul0;
+ }
+
+ GLM_FUNC_QUALIFIER detail::fvec4SIMD fastNormalize
+ (
+ detail::fvec4SIMD const & x
+ )
+ {
+ __m128 dot0 = detail::sse_dot_ps(x.Data, x.Data);
+ __m128 isr0 = fastInversesqrt(dot0).Data;
+ __m128 mul0 = _mm_mul_ps(x.Data, isr0);
+ return mul0;
+ }
+
+ GLM_FUNC_QUALIFIER detail::fvec4SIMD faceforward
+ (
+ detail::fvec4SIMD const & N,
+ detail::fvec4SIMD const & I,
+ detail::fvec4SIMD const & Nref
+ )
+ {
+ return detail::sse_ffd_ps(N.Data, I.Data, Nref.Data);
+ }
+
+ GLM_FUNC_QUALIFIER detail::fvec4SIMD reflect
+ (
+ detail::fvec4SIMD const & I,
+ detail::fvec4SIMD const & N
+ )
+ {
+ return detail::sse_rfe_ps(I.Data, N.Data);
+ }
+
+ GLM_FUNC_QUALIFIER detail::fvec4SIMD refract
+ (
+ detail::fvec4SIMD const & I,
+ detail::fvec4SIMD const & N,
+ float const & eta
+ )
+ {
+ return detail::sse_rfa_ps(I.Data, N.Data, _mm_set1_ps(eta));
+ }
+
+ GLM_FUNC_QUALIFIER detail::fvec4SIMD sqrt(detail::fvec4SIMD const & x)
+ {
+ return _mm_mul_ps(inversesqrt(x.Data).Data, x.Data);
+ }
+
+ GLM_FUNC_QUALIFIER detail::fvec4SIMD niceSqrt(detail::fvec4SIMD const & x)
+ {
+ return _mm_sqrt_ps(x.Data);
+ }
+
+ GLM_FUNC_QUALIFIER detail::fvec4SIMD fastSqrt(detail::fvec4SIMD const & x)
+ {
+ return _mm_mul_ps(fastInversesqrt(x.Data).Data, x.Data);
+ }
+
+ // SSE scalar reciprocal sqrt using rsqrt op, plus one Newton-Rhaphson iteration
+ // By Elan Ruskin, http://assemblyrequired.crashworks.org/
+ GLM_FUNC_QUALIFIER detail::fvec4SIMD inversesqrt(detail::fvec4SIMD const & x)
+ {
+ GLM_ALIGN(4) static const __m128 three = {3, 3, 3, 3}; // aligned consts for fast load
+ GLM_ALIGN(4) static const __m128 half = {0.5,0.5,0.5,0.5};
+
+ __m128 recip = _mm_rsqrt_ps(x.Data); // "estimate" opcode
+ __m128 halfrecip = _mm_mul_ps(half, recip);
+ __m128 threeminus_xrr = _mm_sub_ps(three, _mm_mul_ps(x.Data, _mm_mul_ps(recip, recip)));
+ return _mm_mul_ps(halfrecip, threeminus_xrr);
+ }
+
+ GLM_FUNC_QUALIFIER detail::fvec4SIMD fastInversesqrt(detail::fvec4SIMD const & x)
+ {
+ return _mm_rsqrt_ps(x.Data);
+ }
+
+ }//namespace simd_vec4
+ }//namespace gtx
+}//namespace glm
diff --git a/src/glm/gtx/simplex.hpp b/src/glm/gtx/simplex.hpp
new file mode 100644
index 0000000..b05a450
--- /dev/null
+++ b/src/glm/gtx/simplex.hpp
@@ -0,0 +1,70 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2011-04-09
+// Updated : 2011-04-09
+// Licence : This source is under MIT License
+// File : glm/gtx/simplex.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_gtx_simplex
+#define glm_gtx_simplex
+
+// Dependency:
+#include "../glm.hpp"
+
+#if(defined(GLM_MESSAGES) && !defined(glm_ext))
+# pragma message("GLM: GLM_GTX_simplex extension included")
+#endif
+
+namespace glm{
+namespace gtx{
+namespace spline ///< GLM_GTX_simplex extension: Spline functions
+{
+ /// \addtogroup gtx_spline
+ ///@{
+
+ //! Return a point from a catmull rom curve.
+ //! From GLM_GTX_spline extension.
+ template <typename genType>
+ genType catmullRom(
+ genType const & v1,
+ genType const & v2,
+ genType const & v3,
+ genType const & v4,
+ typename genType::value_type const & s);
+
+ //! Return a point from a hermite curve.
+ //! From GLM_GTX_spline extension.
+ template <typename genType>
+ genType hermite(
+ genType const & v1,
+ genType const & t1,
+ genType const & v2,
+ genType const & t2,
+ typename genType::value_type const & s);
+
+ //! Return a point from a cubic curve.
+ //! From GLM_GTX_spline extension.
+ template <typename genType>
+ genType cubic(
+ genType const & v1,
+ genType const & v2,
+ genType const & v3,
+ genType const & v4,
+ typename genType::value_type const & s);
+
+ /// @}
+}// namespace simplex
+}// namespace gtx
+}// namespace glm
+
+#include "simplex.inl"
+
+namespace glm{using namespace gtx::simplex;}
+
+#endif//glm_gtx_spline
+
diff --git a/src/glm/gtx/simplex.inl b/src/glm/gtx/simplex.inl
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/glm/gtx/simplex.inl
diff --git a/src/glm/gtx/spline.hpp b/src/glm/gtx/spline.hpp
new file mode 100644
index 0000000..e6da3dc
--- /dev/null
+++ b/src/glm/gtx/spline.hpp
@@ -0,0 +1,73 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2007-01-25
+// Updated : 2009-02-19
+// Licence : This source is under MIT License
+// File : glm/gtx/spline.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_gtx_spline
+#define glm_gtx_spline
+
+// Dependency:
+#include "../glm.hpp"
+#include "../gtx/optimum_pow.hpp"
+
+#if(defined(GLM_MESSAGES) && !defined(glm_ext))
+# pragma message("GLM: GLM_GTX_spline extension included")
+#endif
+
+namespace glm{
+namespace gtx{
+namespace spline ///< GLM_GTX_spline extension: Spline functions
+{
+ using namespace gtx::optimum_pow;
+
+ /// \addtogroup gtx_spline
+ /// @{
+
+ //! Return a point from a catmull rom curve.
+ //! From GLM_GTX_spline extension.
+ template <typename genType>
+ genType catmullRom(
+ genType const & v1,
+ genType const & v2,
+ genType const & v3,
+ genType const & v4,
+ typename genType::value_type const & s);
+
+ //! Return a point from a hermite curve.
+ //! From GLM_GTX_spline extension.
+ template <typename genType>
+ genType hermite(
+ genType const & v1,
+ genType const & t1,
+ genType const & v2,
+ genType const & t2,
+ typename genType::value_type const & s);
+
+ //! Return a point from a cubic curve.
+ //! From GLM_GTX_spline extension.
+ template <typename genType>
+ genType cubic(
+ genType const & v1,
+ genType const & v2,
+ genType const & v3,
+ genType const & v4,
+ typename genType::value_type const & s);
+
+ /// @}
+}//namespace spline
+}//namespace gtx
+}//namespace glm
+
+#include "spline.inl"
+
+namespace glm{using namespace gtx::spline;}
+
+#endif//glm_gtx_spline
+
diff --git a/src/glm/gtx/spline.inl b/src/glm/gtx/spline.inl
new file mode 100644
index 0000000..c85f4ef
--- /dev/null
+++ b/src/glm/gtx/spline.inl
@@ -0,0 +1,74 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2007-01-25
+// Updated : 2009-02-19
+// Licence : This source is under MIT License
+// File : glm/gtx/spline.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm{
+namespace gtx{
+namespace spline
+{
+ template <typename genType>
+ GLM_FUNC_QUALIFIER genType catmullRom
+ (
+ genType const & v1,
+ genType const & v2,
+ genType const & v3,
+ genType const & v4,
+ typename genType::value_type const & s
+ )
+ {
+ typename genType::value_type s1 = s;
+ typename genType::value_type s2 = optimum_pow::pow2(s);
+ typename genType::value_type s3 = optimum_pow::pow3(s);
+
+ typename genType::value_type f1 = -s3 + typename genType::value_type(2) * s2 - s;
+ typename genType::value_type f2 = typename genType::value_type(3) * s3 - typename genType::value_type(5) * s2 + typename genType::value_type(2);
+ typename genType::value_type f3 = typename genType::value_type(-3) * s3 + typename genType::value_type(4) * s2 + s;
+ typename genType::value_type f4 = s3 - s2;
+
+ return (f1 * v1 + f2 * v2 + f3 * v3 + f4 * v4) / typename genType::value_type(2);
+
+ }
+
+ template <typename genType>
+ GLM_FUNC_QUALIFIER genType hermite
+ (
+ genType const & v1,
+ genType const & t1,
+ genType const & v2,
+ genType const & t2,
+ typename genType::value_type const & s
+ )
+ {
+ typename genType::value_type s1 = s;
+ typename genType::value_type s2 = optimum_pow::pow2(s);
+ typename genType::value_type s3 = optimum_pow::pow3(s);
+
+ typename genType::value_type f1 = typename genType::value_type(2) * s3 - typename genType::value_type(3) * s2 + typename genType::value_type(1);
+ typename genType::value_type f2 = typename genType::value_type(-2) * s3 + typename genType::value_type(3) * s2;
+ typename genType::value_type f3 = s3 - typename genType::value_type(2) * s2 + s;
+ typename genType::value_type f4 = s3 - s2;
+
+ return f1 * v1 + f2 * v2 + f3 * t1 + f4 * t2;
+ }
+
+ template <typename genType>
+ GLM_FUNC_QUALIFIER genType cubic
+ (
+ genType const & v1,
+ genType const & v2,
+ genType const & v3,
+ genType const & v4,
+ typename genType::value_type const & s
+ )
+ {
+ return ((v1 * s + v2) * s + v3) * s + v4;
+ }
+
+}//namespace spline
+}//namespace gtx
+}//namespace glm
diff --git a/src/glm/gtx/std_based_type.hpp b/src/glm/gtx/std_based_type.hpp
new file mode 100644
index 0000000..2d2ca31
--- /dev/null
+++ b/src/glm/gtx/std_based_type.hpp
@@ -0,0 +1,72 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2008-06-08
+// Updated : 2008-06-08
+// Licence : This source is under MIT License
+// File : glm/gtx/std_based_type.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_gtx_std_based_type
+#define glm_gtx_std_based_type
+
+// Dependency:
+#include "../glm.hpp"
+#include <cstdlib>
+
+#if(defined(GLM_MESSAGES) && !defined(glm_ext))
+# pragma message("GLM: GLM_GTX_std_based_type extension included")
+#endif
+
+namespace glm{
+namespace gtx{
+namespace std_based_type ///< GLM_GTX_std_based_type extension: Add support vector types based on C++ standard type
+{
+ typedef detail::tvec2<std::size_t> size2;
+ typedef detail::tvec3<std::size_t> size3;
+ typedef detail::tvec4<std::size_t> size4;
+
+ typedef detail::tvec2<signed char> scvec2;
+ typedef detail::tvec3<signed char> scvec3;
+ typedef detail::tvec4<signed char> scvec4;
+
+ typedef detail::tvec2<unsigned char> ucvec2;
+ typedef detail::tvec3<unsigned char> ucvec3;
+ typedef detail::tvec4<unsigned char> ucvec4;
+
+ typedef detail::tvec2<signed short> ssvec2;
+ typedef detail::tvec3<signed short> ssvec3;
+ typedef detail::tvec4<signed short> ssvec4;
+
+ typedef detail::tvec2<unsigned short> usvec2;
+ typedef detail::tvec3<unsigned short> usvec3;
+ typedef detail::tvec4<unsigned short> usvec4;
+
+ typedef detail::tvec2<signed int> sivec2;
+ typedef detail::tvec3<signed int> sivec3;
+ typedef detail::tvec4<signed int> sivec4;
+
+ typedef detail::tvec2<unsigned int> uivec2;
+ typedef detail::tvec3<unsigned int> uivec3;
+ typedef detail::tvec4<unsigned int> uivec4;
+
+ typedef detail::tvec2<signed long> slvec2;
+ typedef detail::tvec3<signed long> slvec3;
+ typedef detail::tvec4<signed long> slvec4;
+
+ typedef detail::tvec2<unsigned long> ulvec2;
+ typedef detail::tvec3<unsigned long> ulvec3;
+ typedef detail::tvec4<unsigned long> ulvec4;
+
+}//namespace std_based_type
+}//namespace gtx
+}//namespace glm
+
+#include "std_based_type.inl"
+
+namespace glm{using namespace gtx::std_based_type;}
+
+#endif//glm_gtx_std_based_type
diff --git a/src/glm/gtx/std_based_type.inl b/src/glm/gtx/std_based_type.inl
new file mode 100644
index 0000000..6562a67
--- /dev/null
+++ b/src/glm/gtx/std_based_type.inl
@@ -0,0 +1,13 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2008-06-08
+// Updated : 2008-06-08
+// Licence : This source is under MIT License
+// File : glm/gtx/std_based_type.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm
+{
+
+}
diff --git a/src/glm/gtx/string_cast.hpp b/src/glm/gtx/string_cast.hpp
new file mode 100644
index 0000000..0d93487
--- /dev/null
+++ b/src/glm/gtx/string_cast.hpp
@@ -0,0 +1,57 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2008-04-26
+// Updated : 2010-01-28
+// Licence : This source is under MIT License
+// File : glm/gtx/string_cast.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+// - GLM_GTC_half_float
+// - GLM_GTX_integer
+// - GLM_GTX_quaternion
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_gtx_string_cast
+#define glm_gtx_string_cast
+
+// Dependency:
+#include "../glm.hpp"
+#include "../gtc/half_float.hpp"
+#include "../gtx/integer.hpp"
+#include "../gtx/unsigned_int.hpp"
+#include "../gtx/quaternion.hpp"
+#include <string>
+
+#if(defined(GLM_MESSAGES) && !defined(glm_ext))
+# pragma message("GLM: GLM_GTX_string_cast extension included")
+#endif
+
+namespace glm{
+namespace gtx{
+namespace string_cast ///< GLM_GTX_string_cast extension: Setup strings for GLM type values
+{
+ using namespace gtc::half_float;
+ using namespace gtx::integer;
+ using namespace gtx::unsigned_int;
+ using namespace gtx::quaternion;
+
+ /// \addtogroup gtx_string_cast
+ /// @{
+
+ //! Create a string from a GLM type value.
+ //! From GLM_GTX_string_cast extension.
+ template <typename genType>
+ std::string to_string(genType const & x);
+
+ /// @}
+}//namespace string_cast
+}//namespace gtx
+}//namespace glm
+
+#include "string_cast.inl"
+
+namespace glm{using namespace gtx::string_cast;}
+
+#endif//glm_gtx_string_cast
diff --git a/src/glm/gtx/string_cast.inl b/src/glm/gtx/string_cast.inl
new file mode 100644
index 0000000..7881d19
--- /dev/null
+++ b/src/glm/gtx/string_cast.inl
@@ -0,0 +1,597 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2006 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2008-04-27
+// Updated : 2008-05-24
+// Licence : This source is under MIT License
+// File : glm/gtx/string_cast.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#include <cstdarg>
+#include <cstdio>
+
+namespace glm{
+namespace detail
+{
+ GLM_FUNC_QUALIFIER std::string format(const char* msg, ...)
+ {
+ const int STRING_BUFFER = 4096;
+ char text[STRING_BUFFER];
+ va_list list;
+
+ if(msg == 0)
+ return std::string();
+
+ va_start(list, msg);
+ vsprintf(text, msg, list);
+ va_end(list);
+
+ return std::string(text);
+ }
+
+ static const char* True = "true";
+ static const char* False = "false";
+}//namespace detail
+
+namespace gtx{
+namespace string_cast
+{
+ ////////////////////////////////
+ // Scalars
+
+ GLM_FUNC_QUALIFIER std::string to_string(detail::thalf const & x)
+ {
+ return detail::format("half(%f)", float(x));
+ }
+
+ GLM_FUNC_QUALIFIER std::string to_string(float x)
+ {
+ return detail::format("float(%f)", x);
+ }
+
+ GLM_FUNC_QUALIFIER std::string to_string(double x)
+ {
+ return detail::format("double(%f)", x);
+ }
+
+ GLM_FUNC_QUALIFIER std::string to_string(int x)
+ {
+ return detail::format("int(%d)", x);
+ }
+
+ GLM_FUNC_QUALIFIER std::string to_string(unsigned int x)
+ {
+ return detail::format("uint(%d)", x);
+ }
+
+ ////////////////////////////////
+ // Bool vectors
+
+ GLM_FUNC_QUALIFIER std::string to_string
+ (
+ detail::tvec2<bool> const & v
+ )
+ {
+ return detail::format("bvec2(%s, %s)",
+ v.x ? detail::True : detail::False,
+ v.y ? detail::True : detail::False);
+ }
+
+ GLM_FUNC_QUALIFIER std::string to_string
+ (
+ detail::tvec3<bool> const & v
+ )
+ {
+ return detail::format("bvec3(%s, %s, %s)",
+ v.x ? detail::True : detail::False,
+ v.y ? detail::True : detail::False,
+ v.z ? detail::True : detail::False);
+ }
+
+ GLM_FUNC_QUALIFIER std::string to_string
+ (
+ detail::tvec4<bool> const & v
+ )
+ {
+ return detail::format("bvec4(%s, %s, %s, %s)",
+ v.x ? detail::True : detail::False,
+ v.y ? detail::True : detail::False,
+ v.z ? detail::True : detail::False,
+ v.w ? detail::True : detail::False);
+ }
+
+ ////////////////////////////////
+ // Half vectors
+
+ template <>
+ GLM_FUNC_QUALIFIER std::string to_string
+ (
+ detail::tvec2<detail::thalf> const & v
+ )
+ {
+ return detail::format("hvec2(%f, %f)", float(v.x), float(v.y));
+ }
+
+ template <>
+ GLM_FUNC_QUALIFIER std::string to_string
+ (
+ detail::tvec3<detail::thalf> const & v
+ )
+ {
+ return detail::format("hvec3(%f, %f, %f)", float(v.x), float(v.y), float(v.z));
+ }
+
+ template <>
+ GLM_FUNC_QUALIFIER std::string to_string
+ (
+ detail::tvec4<detail::thalf> const & v
+ )
+ {
+ return detail::format("hvec4(%f, %f, %f, %f)", float(v.x), float(v.y), float(v.z), float(v.w));
+ }
+
+ ////////////////////////////////
+ // Float vectors
+
+ template <>
+ GLM_FUNC_QUALIFIER std::string to_string
+ (
+ detail::tvec2<float> const & v
+ )
+ {
+ return detail::format("fvec2(%f, %f)", v.x, v.y);
+ }
+
+ template <>
+ GLM_FUNC_QUALIFIER std::string to_string
+ (
+ detail::tvec3<float> const & v
+ )
+ {
+ return detail::format("fvec3(%f, %f, %f)", v.x, v.y, v.z);
+ }
+
+ template <>
+ GLM_FUNC_QUALIFIER std::string to_string
+ (
+ detail::tvec4<float> const & v
+ )
+ {
+ return detail::format("fvec4(%f, %f, %f, %f)", v.x, v.y, v.z, v.w);
+ }
+
+ ////////////////////////////////
+ // Double vectors
+
+ template <>
+ GLM_FUNC_QUALIFIER std::string to_string
+ (
+ detail::tvec2<double> const & v
+ )
+ {
+ return detail::format("dvec2(%f, %f)", v.x, v.y);
+ }
+
+ template <>
+ GLM_FUNC_QUALIFIER std::string to_string
+ (
+ detail::tvec3<double> const & v
+ )
+ {
+ return detail::format("dvec3(%f, %f, %f)", v.x, v.y, v.z);
+ }
+
+ template <>
+ GLM_FUNC_QUALIFIER std::string to_string
+ (
+ detail::tvec4<double> const & v
+ )
+ {
+ return detail::format("dvec4(%f, %f, %f, %f)", v.x, v.y, v.z, v.w);
+ }
+
+ ////////////////////////////////
+ // Int vectors
+
+ template <>
+ GLM_FUNC_QUALIFIER std::string to_string
+ (
+ detail::tvec2<int> const & v
+ )
+ {
+ return detail::format("ivec2(%d, %d)", v.x, v.y);
+ }
+
+ template <>
+ GLM_FUNC_QUALIFIER std::string to_string
+ (
+ detail::tvec3<int> const & v
+ )
+ {
+ return detail::format("ivec3(%d, %d, %d)", v.x, v.y, v.z);
+ }
+
+ template <>
+ GLM_FUNC_QUALIFIER std::string to_string
+ (
+ detail::tvec4<int> const & v
+ )
+ {
+ return detail::format("ivec4(%d, %d, %d, %d)", v.x, v.y, v.z, v.w);
+ }
+
+ ////////////////////////////////
+ // Unsigned int vectors
+
+ template <>
+ GLM_FUNC_QUALIFIER std::string to_string
+ (
+ detail::tvec2<unsigned int> const & v
+ )
+ {
+ return detail::format("uvec2(%d, %d)", v.x, v.y);
+ }
+
+ template <>
+ GLM_FUNC_QUALIFIER std::string to_string
+ (
+ detail::tvec3<unsigned int> const & v
+ )
+ {
+ return detail::format("uvec3(%d, %d, %d)", v.x, v.y, v.z);
+ }
+
+ template <>
+ GLM_FUNC_QUALIFIER std::string to_string
+ (
+ detail::tvec4<unsigned int> const & v
+ )
+ {
+ return detail::format("uvec4(%d, %d, %d, %d)", v.x, v.y, v.z, v.w);
+ }
+
+ ////////////////////////////////
+ // Half matrices
+
+ template <>
+ GLM_FUNC_QUALIFIER std::string to_string
+ (
+ detail::tmat2x2<detail::thalf> const & m
+ )
+ {
+ detail::tmat2x2<float> x(m);
+ return detail::format("hmat2x2((%f, %f), (%f, %f))",
+ x[0][0], x[0][1],
+ x[1][0], x[1][1]);
+ }
+
+ template <>
+ GLM_FUNC_QUALIFIER std::string to_string
+ (
+ detail::tmat2x3<detail::thalf> const & m
+ )
+ {
+ detail::tmat2x3<float> x(m);
+ return detail::format("hmat2x3((%f, %f, %f), (%f, %f, %f))",
+ x[0][0], x[0][1], x[0][2],
+ x[1][0], x[1][1], x[1][2]);
+ }
+
+ template <>
+ GLM_FUNC_QUALIFIER std::string to_string
+ (
+ detail::tmat2x4<detail::thalf> const & m
+ )
+ {
+ detail::tmat2x4<float> x(m);
+ return detail::format("hmat2x4((%f, %f, %f, %f), (%f, %f, %f, %f))",
+ x[0][0], x[0][1], x[0][2], x[0][3],
+ x[1][0], x[1][1], x[1][2], x[1][3]);
+ }
+
+ template <>
+ GLM_FUNC_QUALIFIER std::string to_string
+ (
+ detail::tmat3x2<detail::thalf> const & m
+ )
+ {
+ detail::tmat3x2<float> x(m);
+ return detail::format("hmat3x2((%f, %f), (%f, %f), (%f, %f))",
+ x[0][0], x[0][1],
+ x[1][0], x[1][1],
+ x[2][0], x[2][1]);
+ }
+
+ template <>
+ GLM_FUNC_QUALIFIER std::string to_string
+ (
+ detail::tmat3x3<detail::thalf> const & m
+ )
+ {
+ detail::tmat3x3<float> x(m);
+ return detail::format("hmat3x3((%f, %f, %f), (%f, %f, %f), (%f, %f, %f))",
+ x[0][0], x[0][1], x[0][2],
+ x[1][0], x[1][1], x[1][2],
+ x[2][0], x[2][1], x[2][2]);
+ }
+
+ template <>
+ GLM_FUNC_QUALIFIER std::string to_string
+ (
+ detail::tmat3x4<detail::thalf> const & m
+ )
+ {
+ detail::tmat3x4<float> x(m);
+ return detail::format("hmat3x4((%f, %f, %f, %f), (%f, %f, %f, %f), (%f, %f, %f, %f))",
+ x[0][0], x[0][1], x[0][2], x[0][3],
+ x[1][0], x[1][1], x[1][2], x[1][3],
+ x[2][0], x[2][1], x[2][2], x[2][3]);
+ }
+
+ template <>
+ GLM_FUNC_QUALIFIER std::string to_string
+ (
+ detail::tmat4x2<detail::thalf> const & m
+ )
+ {
+ detail::tmat4x2<float> x(m);
+ return detail::format("hmat4x2((%f, %f), (%f, %f), (%f, %f), (%f, %f))",
+ x[0][0], x[0][1],
+ x[1][0], x[1][1],
+ x[2][0], x[2][1],
+ x[3][0], x[3][1]);
+ }
+
+ template <>
+ GLM_FUNC_QUALIFIER std::string to_string
+ (
+ detail::tmat4x3<detail::thalf> const & m
+ )
+ {
+ detail::tmat4x3<float> x(m);
+ return detail::format("hmat4x3((%f, %f, %f), (%f, %f, %f), (%f, %f, %f), (%f, %f, %f))",
+ x[0][0], x[0][1], x[0][2],
+ x[1][0], x[1][1], x[1][2],
+ x[2][0], x[2][1], x[2][2],
+ x[3][0], x[3][1], x[3][2]);
+ }
+
+ template <>
+ GLM_FUNC_QUALIFIER std::string to_string
+ (
+ detail::tmat4x4<detail::thalf> const & m
+ )
+ {
+ detail::tmat4x4<float> x(m);
+ return detail::format("hmat4x4((%f, %f, %f, %f), (%f, %f, %f, %f), (%f, %f, %f, %f), (%f, %f, %f, %f))",
+ x[0][0], x[0][1], x[0][2], x[0][3],
+ x[1][0], x[1][1], x[1][2], x[1][3],
+ x[2][0], x[2][1], x[2][2], x[2][3],
+ x[3][0], x[3][1], x[3][2], x[3][3]);
+ }
+
+ ////////////////////////////////
+ // Float matrices
+
+ template <>
+ GLM_FUNC_QUALIFIER std::string to_string
+ (
+ detail::tmat2x2<float> const & x
+ )
+ {
+ return detail::format("mat2x2((%f, %f), (%f, %f))",
+ x[0][0], x[0][1],
+ x[1][0], x[1][1]);
+ }
+
+ template <>
+ GLM_FUNC_QUALIFIER std::string to_string
+ (
+ detail::tmat2x3<float> const & x
+ )
+ {
+ return detail::format("mat2x3((%f, %f, %f), (%f, %f, %f))",
+ x[0][0], x[0][1], x[0][2],
+ x[1][0], x[1][1], x[1][2]);
+ }
+
+ template <>
+ GLM_FUNC_QUALIFIER std::string to_string
+ (
+ detail::tmat2x4<float> const & x
+ )
+ {
+ return detail::format("mat2x4((%f, %f, %f, %f), (%f, %f, %f, %f))",
+ x[0][0], x[0][1], x[0][2], x[0][3],
+ x[1][0], x[1][1], x[1][2], x[1][3]);
+ }
+
+ template <>
+ GLM_FUNC_QUALIFIER std::string to_string
+ (
+ detail::tmat3x2<float> const & x
+ )
+ {
+ return detail::format("mat3x2((%f, %f), (%f, %f), (%f, %f))",
+ x[0][0], x[0][1],
+ x[1][0], x[1][1],
+ x[2][0], x[2][1]);
+ }
+
+ template <>
+ GLM_FUNC_QUALIFIER std::string to_string
+ (
+ detail::tmat3x3<float> const & x
+ )
+ {
+ return detail::format("mat3x3((%f, %f, %f), (%f, %f, %f), (%f, %f, %f))",
+ x[0][0], x[0][1], x[0][2],
+ x[1][0], x[1][1], x[1][2],
+ x[2][0], x[2][1], x[2][2]);
+ }
+
+ template <>
+ GLM_FUNC_QUALIFIER std::string to_string
+ (
+ detail::tmat3x4<float> const & x
+ )
+ {
+ return detail::format("mat3x4((%f, %f, %f, %f), (%f, %f, %f, %f), (%f, %f, %f, %f))",
+ x[0][0], x[0][1], x[0][2], x[0][3],
+ x[1][0], x[1][1], x[1][2], x[1][3],
+ x[2][0], x[2][1], x[2][2], x[2][3]);
+ }
+
+ template <>
+ GLM_FUNC_QUALIFIER std::string to_string
+ (
+ detail::tmat4x2<float> const & x
+ )
+ {
+ return detail::format("mat4x2((%f, %f), (%f, %f), (%f, %f), (%f, %f))",
+ x[0][0], x[0][1],
+ x[1][0], x[1][1],
+ x[2][0], x[2][1],
+ x[3][0], x[3][1]);
+ }
+
+ template <>
+ GLM_FUNC_QUALIFIER std::string to_string
+ (
+ detail::tmat4x3<float> const & x
+ )
+ {
+ return detail::format("mat4x3((%f, %f, %f), (%f, %f, %f), (%f, %f, %f), (%f, %f, %f))",
+ x[0][0], x[0][1], x[0][2],
+ x[1][0], x[1][1], x[1][2],
+ x[2][0], x[2][1], x[2][2],
+ x[3][0], x[3][1], x[3][2]);
+ }
+
+ template <>
+ GLM_FUNC_QUALIFIER std::string to_string
+ (
+ detail::tmat4x4<float> const & x
+ )
+ {
+ return detail::format("mat4x4((%f, %f, %f, %f), (%f, %f, %f, %f), (%f, %f, %f, %f), (%f, %f, %f, %f))",
+ x[0][0], x[0][1], x[0][2], x[0][3],
+ x[1][0], x[1][1], x[1][2], x[1][3],
+ x[2][0], x[2][1], x[2][2], x[2][3],
+ x[3][0], x[3][1], x[3][2], x[3][3]);
+ }
+
+ ////////////////////////////////
+ // Double matrices
+
+ template <>
+ GLM_FUNC_QUALIFIER std::string to_string
+ (
+ detail::tmat2x2<double> const & x
+ )
+ {
+ return detail::format("dmat2x2((%f, %f), (%f, %f))",
+ x[0][0], x[0][1],
+ x[1][0], x[1][1]);
+ }
+
+ template <>
+ GLM_FUNC_QUALIFIER std::string to_string
+ (
+ detail::tmat2x3<double> const & x
+ )
+ {
+ return detail::format("dmat2x3((%f, %f, %f), (%f, %f, %f))",
+ x[0][0], x[0][1], x[0][2],
+ x[1][0], x[1][1], x[1][2]);
+ }
+
+ template <>
+ GLM_FUNC_QUALIFIER std::string to_string
+ (
+ detail::tmat2x4<double> const & x
+ )
+ {
+ return detail::format("dmat2x4((%f, %f, %f, %f), (%f, %f, %f, %f))",
+ x[0][0], x[0][1], x[0][2], x[0][3],
+ x[1][0], x[1][1], x[1][2], x[1][3]);
+ }
+
+ template <>
+ GLM_FUNC_QUALIFIER std::string to_string
+ (
+ detail::tmat3x2<double> const & x
+ )
+ {
+ return detail::format("dmat3x2((%f, %f), (%f, %f), (%f, %f))",
+ x[0][0], x[0][1],
+ x[1][0], x[1][1],
+ x[2][0], x[2][1]);
+ }
+
+ template <>
+ GLM_FUNC_QUALIFIER std::string to_string
+ (
+ detail::tmat3x3<double> const & x
+ )
+ {
+ return detail::format("dmat3x3((%f, %f, %f), (%f, %f, %f), (%f, %f, %f))",
+ x[0][0], x[0][1], x[0][2],
+ x[1][0], x[1][1], x[1][2],
+ x[2][0], x[2][1], x[2][2]);
+ }
+
+ template <>
+ GLM_FUNC_QUALIFIER std::string to_string
+ (
+ detail::tmat3x4<double> const & x
+ )
+ {
+ return detail::format("dmat3x4((%f, %f, %f, %f), (%f, %f, %f, %f), (%f, %f, %f, %f))",
+ x[0][0], x[0][1], x[0][2], x[0][3],
+ x[1][0], x[1][1], x[1][2], x[1][3],
+ x[2][0], x[2][1], x[2][2], x[2][3]);
+ }
+
+ template <>
+ GLM_FUNC_QUALIFIER std::string to_string
+ (
+ detail::tmat4x2<double> const & x
+ )
+ {
+ return detail::format("dmat4x2((%f, %f), (%f, %f), (%f, %f), (%f, %f))",
+ x[0][0], x[0][1],
+ x[1][0], x[1][1],
+ x[2][0], x[2][1],
+ x[3][0], x[3][1]);
+ }
+
+ template <>
+ GLM_FUNC_QUALIFIER std::string to_string
+ (
+ detail::tmat4x3<double> const & x
+ )
+ {
+ return detail::format("dmat4x3((%f, %f, %f), (%f, %f, %f), (%f, %f, %f), (%f, %f, %f))",
+ x[0][0], x[0][1], x[0][2],
+ x[1][0], x[1][1], x[1][2],
+ x[2][0], x[2][1], x[2][2],
+ x[3][0], x[3][1], x[3][2]);
+ }
+
+ template <>
+ GLM_FUNC_QUALIFIER std::string to_string
+ (
+ detail::tmat4x4<double> const & x
+ )
+ {
+ return detail::format("dmat4x4((%f, %f, %f, %f), (%f, %f, %f, %f), (%f, %f, %f, %f), (%f, %f, %f, %f))",
+ x[0][0], x[0][1], x[0][2], x[0][3],
+ x[1][0], x[1][1], x[1][2], x[1][3],
+ x[2][0], x[2][1], x[2][2], x[2][3],
+ x[3][0], x[3][1], x[3][2], x[3][3]);
+ }
+
+ }//namespace string_cast
+ }//namespace gtx
+}//namespace glm
diff --git a/src/glm/gtx/transform.hpp b/src/glm/gtx/transform.hpp
new file mode 100644
index 0000000..1a38544
--- /dev/null
+++ b/src/glm/gtx/transform.hpp
@@ -0,0 +1,103 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2005-12-21
+// Updated : 2009-04-29
+// Licence : This source is under MIT License
+// File : glm/gtx/transform.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+// - GLM_GTC_matric_transform
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_gtx_transform
+#define glm_gtx_transform
+
+// Dependency:
+#include "../glm.hpp"
+#include "../gtc/matrix_transform.hpp"
+
+#if(defined(GLM_MESSAGES) && !defined(glm_ext))
+# pragma message("GLM: GLM_GTX_transform extension included")
+#endif
+
+namespace glm{
+namespace gtx{
+namespace transform ///< GLM_GTX_transform extension: Add transformation matrices
+{
+ using namespace gtc::matrix_transform;
+
+ /// \addtogroup gtx_transform
+ /// @{
+
+ //! Builds a translation 4 * 4 matrix created from 3 scalars.
+ //! From GLM_GTX_transform extension.
+ template <typename T>
+ detail::tmat4x4<T> translate(
+ T x, T y, T z);
+
+ //! Transforms a matrix with a translation 4 * 4 matrix created from 3 scalars.
+ //! From GLM_GTX_transform extension.
+ template <typename T>
+ detail::tmat4x4<T> translate(
+ detail::tmat4x4<T> const & m,
+ T x, T y, T z);
+
+ //! Transforms a matrix with a translation 4 * 4 matrix created from 3 scalars.
+ //! From GLM_GTX_transform extension.
+ template <typename T>
+ detail::tmat4x4<T> translate(
+ detail::tvec3<T> const & v);
+
+ //! Builds a rotation 4 * 4 matrix created from an axis of 3 scalars and an angle expressed in degrees.
+ //! From GLM_GTX_transform extension.
+ template <typename T>
+ detail::tmat4x4<T> rotate(
+ T angle,
+ T x, T y, T z);
+
+ //! Builds a rotation 4 * 4 matrix created from an axis of 3 scalars and an angle expressed in degrees.
+ //! From GLM_GTX_transform extension.
+ template <typename T>
+ detail::tmat4x4<T> rotate(
+ T angle,
+ detail::tvec3<T> const & v);
+
+ //! Transforms a matrix with a rotation 4 * 4 matrix created from an axis of 3 scalars and an angle expressed in degrees.
+ //! From GLM_GTX_transform extension.
+ template <typename T>
+ detail::tmat4x4<T> rotate(
+ detail::tmat4x4<T> const & m,
+ T angle,
+ T x, T y, T z);
+
+ //! Builds a scale 4 * 4 matrix created from 3 scalars.
+ //! From GLM_GTX_transform extension.
+ template <typename T>
+ detail::tmat4x4<T> scale(
+ T x, T y, T z);
+
+ //! Transforms a matrix with a scale 4 * 4 matrix created from 3 scalars.
+ //! From GLM_GTX_transform extension.
+ template <typename T>
+ detail::tmat4x4<T> scale(
+ detail::tmat4x4<T> const & m,
+ T x, T y, T z);
+
+ //! Transforms a matrix with a scale 4 * 4 matrix created from a vector of 3 components.
+ //! From GLM_GTX_transform extension.
+ template <typename T>
+ detail::tmat4x4<T> scale(
+ detail::tvec3<T> const & v);
+
+ /// @}
+}//namespace transform
+}//namespace gtx
+}//namespace glm
+
+#include "transform.inl"
+
+namespace glm{using namespace gtx::transform;}
+
+#endif//glm_gtx_transform
diff --git a/src/glm/gtx/transform.inl b/src/glm/gtx/transform.inl
new file mode 100644
index 0000000..740c1ec
--- /dev/null
+++ b/src/glm/gtx/transform.inl
@@ -0,0 +1,94 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2005-12-21
+// Updated : 2009-04-29
+// Licence : This source is under MIT License
+// File : glm/gtx/transform.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm{
+namespace gtx{
+namespace transform
+{
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tmat4x4<T> translate(
+ T x, T y, T z)
+ {
+ return gtc::matrix_transform::translate(
+ detail::tmat4x4<T>(1.0f),
+ detail::tvec3<T>(x, y , z));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tmat4x4<T> translate(
+ detail::tmat4x4<T> const & m,
+ T x, T y, T z)
+ {
+ return gtc::matrix_transform::translate(
+ m, detail::tvec3<T>(x, y , z));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tmat4x4<T> translate(
+ detail::tvec3<T> const & v)
+ {
+ return gtc::matrix_transform::translate(
+ detail::tmat4x4<T>(1.0f), v);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tmat4x4<T> rotate(
+ T angle,
+ T x, T y, T z)
+ {
+ return gtc::matrix_transform::rotate(
+ detail::tmat4x4<T>(1), angle, detail::tvec3<T>(x, y, z));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tmat4x4<T> rotate(
+ T angle,
+ detail::tvec3<T> const & v)
+ {
+ return gtc::matrix_transform::rotate(
+ detail::tmat4x4<T>(1), angle, v);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tmat4x4<T> rotate(
+ detail::tmat4x4<T> const & m,
+ T angle,
+ T x, T y, T z)
+ {
+ return gtc::matrix_transform::rotate(
+ m, angle, detail::tvec3<T>(x, y, z));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tmat4x4<T> scale(T x, T y, T z)
+ {
+ return gtc::matrix_transform::scale(
+ detail::tmat4x4<T>(1), detail::tvec3<T>(x, y, z));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tmat4x4<T> scale(
+ detail::tmat4x4<T> const & m,
+ T x, T y, T z)
+ {
+ return gtc::matrix_transform::scale(
+ m, detail::tvec3<T>(x, y, z));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tmat4x4<T> scale(
+ detail::tvec3<T> const & v)
+ {
+ return gtc::matrix_transform::scale(
+ detail::tmat4x4<T>(1.0f), v);
+ }
+
+}//namespace transform
+}//namespace gtx
+}//namespace glm
diff --git a/src/glm/gtx/transform2.hpp b/src/glm/gtx/transform2.hpp
new file mode 100644
index 0000000..b0278a3
--- /dev/null
+++ b/src/glm/gtx/transform2.hpp
@@ -0,0 +1,118 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2005-12-21
+// Updated : 2006-11-13
+// Licence : This source is under MIT License
+// File : glm/gtx/transform2.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+// - GLM_GTX_transform
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_gtx_transform2
+#define glm_gtx_transform2
+
+// Dependency:
+#include "../glm.hpp"
+#include "../gtx/transform.hpp"
+
+#if(defined(GLM_MESSAGES) && !defined(glm_ext))
+# pragma message("GLM: GLM_GTX_transform2 extension included")
+#endif
+
+namespace glm{
+namespace gtx{
+namespace transform2 ///< GLM_GTX_transform2 extension: Add extra transformation matrices
+{
+ using namespace gtx::transform;
+
+ /// \addtogroup gtx_transform2
+ /// @{
+
+ //! Transforms a matrix with a shearing on X axis.
+ //! From GLM_GTX_transform2 extension.
+ template <typename T>
+ detail::tmat3x3<T> shearX2D(
+ detail::tmat3x3<T> const & m,
+ T y);
+
+ //! Transforms a matrix with a shearing on Y axis.
+ //! From GLM_GTX_transform2 extension.
+ template <typename T>
+ detail::tmat3x3<T> shearY2D(
+ detail::tmat3x3<T> const & m,
+ T x);
+
+ //! Transforms a matrix with a shearing on X axis
+ //! From GLM_GTX_transform2 extension.
+ template <typename T>
+ detail::tmat4x4<T> shearX3D(
+ const detail::tmat4x4<T> & m,
+ T y,
+ T z);
+
+ //! Transforms a matrix with a shearing on Y axis.
+ //! From GLM_GTX_transform2 extension.
+ template <typename T>
+ detail::tmat4x4<T> shearY3D(
+ const detail::tmat4x4<T> & m,
+ T x,
+ T z);
+
+ //! Transforms a matrix with a shearing on Z axis.
+ //! From GLM_GTX_transform2 extension.
+ template <typename T>
+ detail::tmat4x4<T> shearZ3D(
+ const detail::tmat4x4<T> & m,
+ T x,
+ T y);
+
+ //template <typename T> GLM_FUNC_QUALIFIER detail::tmat4x4<T> shear(const detail::tmat4x4<T> & m, shearPlane, planePoint, angle)
+ // Identity + tan(angle) * cross(Normal, OnPlaneVector) 0
+ // - dot(PointOnPlane, normal) * OnPlaneVector 1
+
+ // Reflect functions seem to don't work
+ //template <typename T> detail::tmat3x3<T> reflect2D(const detail::tmat3x3<T> & m, const detail::tvec3<T>& normal){return reflect2DGTX(m, normal);} //!< \brief Build a reflection matrix (from GLM_GTX_transform2 extension)
+ //template <typename T> detail::tmat4x4<T> reflect3D(const detail::tmat4x4<T> & m, const detail::tvec3<T>& normal){return reflect3DGTX(m, normal);} //!< \brief Build a reflection matrix (from GLM_GTX_transform2 extension)
+
+ //! Build planar projection matrix along normal axis.
+ //! From GLM_GTX_transform2 extension.
+ template <typename T>
+ detail::tmat3x3<T> proj2D(
+ const detail::tmat3x3<T> & m,
+ const detail::tvec3<T>& normal);
+
+ //! Build planar projection matrix along normal axis.
+ //! From GLM_GTX_transform2 extension.
+ template <typename T>
+ detail::tmat4x4<T> proj3D(
+ const detail::tmat4x4<T> & m,
+ const detail::tvec3<T>& normal);
+
+ //! Build a scale bias matrix.
+ //! From GLM_GTX_transform2 extension.
+ template <typename valType>
+ detail::tmat4x4<valType> scaleBias(
+ valType scale,
+ valType bias);
+
+ //! Build a scale bias matrix.
+ //! From GLM_GTX_transform2 extension.
+ template <typename valType>
+ detail::tmat4x4<valType> scaleBias(
+ detail::tmat4x4<valType> const & m,
+ valType scale,
+ valType bias);
+
+ /// @}
+}// namespace transform2
+}// namespace gtx
+}// namespace glm
+
+#include "transform2.inl"
+
+namespace glm{using namespace gtx::transform2;}
+
+#endif//glm_gtx_transform2
diff --git a/src/glm/gtx/transform2.inl b/src/glm/gtx/transform2.inl
new file mode 100644
index 0000000..8b7e4d6
--- /dev/null
+++ b/src/glm/gtx/transform2.inl
@@ -0,0 +1,159 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2005-02-28
+// Updated : 2005-04-23
+// Licence : This source is under MIT License
+// File : glm/gtx/transform2.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm{
+namespace gtx{
+namespace transform2
+{
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tmat3x3<T> shearX2D(
+ const detail::tmat3x3<T>& m,
+ T s)
+ {
+ detail::tmat3x3<T> r(1);
+ r[0][1] = s;
+ return m * r;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tmat3x3<T> shearY2D(
+ const detail::tmat3x3<T>& m,
+ T s)
+ {
+ detail::tmat3x3<T> r(1);
+ r[1][0] = s;
+ return m * r;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tmat4x4<T> shearX3D(
+ const detail::tmat4x4<T>& m,
+ T s,
+ T t)
+ {
+ detail::tmat4x4<T> r(1);
+ r[1][0] = s;
+ r[2][0] = t;
+ return m * r;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tmat4x4<T> shearY3D(
+ const detail::tmat4x4<T>& m,
+ T s,
+ T t)
+ {
+ detail::tmat4x4<T> r(1);
+ r[0][1] = s;
+ r[2][1] = t;
+ return m * r;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tmat4x4<T> shearZ3D(
+ const detail::tmat4x4<T>& m,
+ T s,
+ T t)
+ {
+ detail::tmat4x4<T> r(1);
+ r[0][2] = s;
+ r[1][2] = t;
+ return m * r;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tmat3x3<T> reflect2D(
+ const detail::tmat3x3<T>& m,
+ const detail::tvec3<T>& normal)
+ {
+ detail::tmat3x3<T> r(1);
+ r[0][0] = 1 - 2 * normal.x * normal.x;
+ r[0][1] = -2 * normal.x * normal.y;
+ r[1][0] = -2 * normal.x * normal.y;
+ r[1][1] = 1 - 2 * normal.y * normal.y;
+ return m * r;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tmat4x4<T> reflect3D(
+ const detail::tmat4x4<T>& m,
+ const detail::tvec3<T>& normal)
+ {
+ detail::tmat4x4<T> r(1);
+ r[0][0] = 1 - 2 * normal.x * normal.x;
+ r[0][1] = -2 * normal.x * normal.y;
+ r[0][2] = -2 * normal.x * normal.z;
+
+ r[1][0] = -2 * normal.x * normal.y;
+ r[1][1] = 1 - 2 * normal.y * normal.y;
+ r[1][2] = -2 * normal.y * normal.z;
+
+ r[2][0] = -2 * normal.x * normal.z;
+ r[2][1] = -2 * normal.y * normal.z;
+ r[2][2] = 1 - 2 * normal.z * normal.z;
+ return m * r;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tmat3x3<T> proj2D(
+ const detail::tmat3x3<T>& m,
+ const detail::tvec3<T>& normal)
+ {
+ detail::tmat3x3<T> r(1);
+ r[0][0] = 1 - normal.x * normal.x;
+ r[0][1] = - normal.x * normal.y;
+ r[1][0] = - normal.x * normal.y;
+ r[1][1] = 1 - normal.y * normal.y;
+ return m * r;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tmat4x4<T> proj3D(
+ const detail::tmat4x4<T>& m,
+ const detail::tvec3<T>& normal)
+ {
+ detail::tmat4x4<T> r(1);
+ r[0][0] = 1 - normal.x * normal.x;
+ r[0][1] = - normal.x * normal.y;
+ r[0][2] = - normal.x * normal.z;
+ r[1][0] = - normal.x * normal.y;
+ r[1][1] = 1 - normal.y * normal.y;
+ r[1][2] = - normal.y * normal.z;
+ r[2][0] = - normal.x * normal.z;
+ r[2][1] = - normal.y * normal.z;
+ r[2][2] = 1 - normal.z * normal.z;
+ return m * r;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tmat4x4<T> scaleBias(
+ T scale,
+ T bias)
+ {
+ detail::tmat4x4<T> result;
+ result[3] = detail::tvec4<T>(detail::tvec3<T>(bias), T(1));
+ result[0][0] = scale;
+ result[1][1] = scale;
+ result[2][2] = scale;
+ return result;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tmat4x4<T> scaleBias(
+ const detail::tmat4x4<T>& m,
+ T scale,
+ T bias)
+ {
+ return m * scaleBias(scale, bias);
+ }
+
+}//namespace transform2
+}//namespace gtx
+}//namespace glm
+
diff --git a/src/glm/gtx/ulp.hpp b/src/glm/gtx/ulp.hpp
new file mode 100644
index 0000000..0c60718
--- /dev/null
+++ b/src/glm/gtx/ulp.hpp
@@ -0,0 +1,70 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2011-02-21
+// Updated : 2009-02-21
+// Licence : This source is under MIT License
+// File : glm/gtx/ulp.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_gtx_ulp
+#define glm_gtx_ulp
+
+// Dependency:
+#include "../glm.hpp"
+
+#if(defined(GLM_MESSAGES) && !defined(glm_ext))
+# pragma message("GLM: GLM_GTX_ulp extension included")
+#endif
+
+namespace glm{
+namespace gtx{
+namespace ulp ///< GLM_GTX_ulp extension: Precision calculation functions
+{
+ /// \addtogroup gtx_ulp
+ /// @{
+
+ //! Return the next ULP value(s) after the input value(s).
+ //! From GLM_GTX_ulp extension.
+ template <typename genType>
+ genType next_float(genType const & x);
+
+ //! Return the previous ULP value(s) before the input value(s).
+ //! From GLM_GTX_ulp extension.
+ template <typename genType>
+ genType prev_float(genType const & x);
+
+ //! Return the value(s) ULP distance after the input value(s).
+ //! From GLM_GTX_ulp extension.
+ template <typename genType>
+ genType next_float(genType const & x, uint const & Distance);
+
+ //! Return the value(s) ULP distance before the input value(s).
+ //! From GLM_GTX_ulp extension.
+ template <typename genType>
+ genType prev_float(genType const & x, uint const & Distance);
+
+ //! Return the distance in the number of ULP between 2 scalars.
+ //! From GLM_GTX_ulp extension.
+ template <typename T>
+ uint float_distance(T const & x, T const & y);
+
+ //! Return the distance in the number of ULP between 2 vectors.
+ //! From GLM_GTX_ulp extension.
+ template<typename T, template<typename> class vecType>
+ vecType<uint> float_distance(vecType<T> const & x, vecType<T> const & y);
+
+ ///@}
+}// namespace ulp
+}// namespace gtx
+}// namespace glm
+
+#include "ulp.inl"
+
+namespace glm{using namespace gtx::ulp;}
+
+#endif//glm_gtx_ulp
+
diff --git a/src/glm/gtx/ulp.inl b/src/glm/gtx/ulp.inl
new file mode 100644
index 0000000..7a5b2a7
--- /dev/null
+++ b/src/glm/gtx/ulp.inl
@@ -0,0 +1,396 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2011-03-07
+// Updated : 2011-04-26
+// Licence : This source is under MIT License
+// File : glm/gtx/ulp.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#include <cmath>
+#include <cfloat>
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+typedef union
+{
+ float value;
+ /* FIXME: Assumes 32 bit int. */
+ unsigned int word;
+} ieee_float_shape_type;
+
+typedef union
+{
+ double value;
+ struct
+ {
+ glm::detail::int32 lsw;
+ glm::detail::int32 msw;
+ } parts;
+} ieee_double_shape_type;
+
+#define GLM_EXTRACT_WORDS(ix0,ix1,d) \
+do { \
+ ieee_double_shape_type ew_u; \
+ ew_u.value = (d); \
+ (ix0) = ew_u.parts.msw; \
+ (ix1) = ew_u.parts.lsw; \
+} while (0)
+
+#define GLM_GET_FLOAT_WORD(i,d) \
+do { \
+ ieee_float_shape_type gf_u; \
+ gf_u.value = (d); \
+ (i) = gf_u.word; \
+} while (0)
+
+#define GLM_SET_FLOAT_WORD(d,i) \
+do { \
+ ieee_float_shape_type sf_u; \
+ sf_u.word = (i); \
+ (d) = sf_u.value; \
+} while (0)
+
+#define GLM_INSERT_WORDS(d,ix0,ix1) \
+do { \
+ ieee_double_shape_type iw_u; \
+ iw_u.parts.msw = (ix0); \
+ iw_u.parts.lsw = (ix1); \
+ (d) = iw_u.value; \
+} while (0)
+
+namespace glm{
+namespace detail
+{
+ GLM_FUNC_QUALIFIER float nextafterf(float x, float y)
+ {
+ volatile float t;
+ glm::detail::int32 hx, hy, ix, iy;
+
+ GLM_GET_FLOAT_WORD(hx,x);
+ GLM_GET_FLOAT_WORD(hy,y);
+ ix = hx&0x7fffffff; // |x|
+ iy = hy&0x7fffffff; // |y|
+
+ if((ix>0x7f800000) || // x is nan
+ (iy>0x7f800000)) // y is nan
+ return x+y;
+ if(x==y) return y; // x=y, return y
+ if(ix==0) { // x == 0
+ GLM_SET_FLOAT_WORD(x,(hy&0x80000000)|1);// return +-minsubnormal
+ t = x*x;
+ if(t==x) return t; else return x; // raise underflow flag
+ }
+ if(hx>=0) { // x > 0
+ if(hx>hy) { // x > y, x -= ulp
+ hx -= 1;
+ } else { // x < y, x += ulp
+ hx += 1;
+ }
+ } else { // x < 0
+ if(hy>=0||hx>hy){ // x < y, x -= ulp
+ hx -= 1;
+ } else { // x > y, x += ulp
+ hx += 1;
+ }
+ }
+ hy = hx&0x7f800000;
+ if(hy>=0x7f800000) return x+x; // overflow
+ if(hy<0x00800000) { // underflow
+ t = x*x;
+ if(t!=x) { // raise underflow flag
+ GLM_SET_FLOAT_WORD(y,hx);
+ return y;
+ }
+ }
+ GLM_SET_FLOAT_WORD(x,hx);
+ return x;
+ }
+
+ GLM_FUNC_QUALIFIER double nextafter(double x, double y)
+ {
+ volatile double t;
+ glm::detail::int32 hx, hy, ix, iy;
+ glm::detail::uint32 lx, ly;
+
+ GLM_EXTRACT_WORDS(hx, lx, x);
+ GLM_EXTRACT_WORDS(hy, ly, y);
+ ix = hx & 0x7fffffff; // |x|
+ iy = hy & 0x7fffffff; // |y|
+
+ if(((ix>=0x7ff00000)&&((ix-0x7ff00000)|lx)!=0) || // x is nan
+ ((iy>=0x7ff00000)&&((iy-0x7ff00000)|ly)!=0)) // y is nan
+ return x+y;
+ if(x==y) return y; // x=y, return y
+ if((ix|lx)==0) { // x == 0
+ GLM_INSERT_WORDS(x, hy & 0x80000000, 1); // return +-minsubnormal
+ t = x*x;
+ if(t==x) return t; else return x; // raise underflow flag
+ }
+ if(hx>=0) { // x > 0
+ if(hx>hy||((hx==hy)&&(lx>ly))) { // x > y, x -= ulp
+ if(lx==0) hx -= 1;
+ lx -= 1;
+ } else { // x < y, x += ulp
+ lx += 1;
+ if(lx==0) hx += 1;
+ }
+ } else { // x < 0
+ if(hy>=0||hx>hy||((hx==hy)&&(lx>ly))){// x < y, x -= ulp
+ if(lx==0) hx -= 1;
+ lx -= 1;
+ } else { // x > y, x += ulp
+ lx += 1;
+ if(lx==0) hx += 1;
+ }
+ }
+ hy = hx&0x7ff00000;
+ if(hy>=0x7ff00000) return x+x; // overflow
+ if(hy<0x00100000) { // underflow
+ t = x*x;
+ if(t!=x) { // raise underflow flag
+ GLM_INSERT_WORDS(y,hx,lx);
+ return y;
+ }
+ }
+ GLM_INSERT_WORDS(x,hx,lx);
+ return x;
+ }
+}//namespace detail
+}//namespace glm
+
+#if(GLM_COMPILER & GLM_COMPILER_VC)
+# define GLM_NEXT_AFTER_FLT(x, toward) glm::detail::nextafterf((x), (toward))
+# define GLM_NEXT_AFTER_DBL(x, toward) _nextafter((x), (toward))
+#else
+# define GLM_NEXT_AFTER_FLT(x, toward) nextafterf((x), (toward))
+# define GLM_NEXT_AFTER_DBL(x, toward) nextafter((x), (toward))
+#endif
+
+namespace glm{
+namespace gtx{
+namespace ulp
+{
+ GLM_FUNC_QUALIFIER float next_float(float const & x)
+ {
+ return GLM_NEXT_AFTER_FLT(x, std::numeric_limits<float>::max());
+ }
+
+ GLM_FUNC_QUALIFIER double next_float(double const & x)
+ {
+ return GLM_NEXT_AFTER_DBL(x, std::numeric_limits<double>::max());
+ }
+
+ template<typename T, template<typename> class vecType>
+ GLM_FUNC_QUALIFIER vecType<T> next_float(vecType<T> const & x)
+ {
+ vecType<T> Result;
+ for(std::size_t i = 0; i < Result.length(); ++i)
+ Result[i] = next_float(x[i]);
+ return Result;
+ }
+
+ GLM_FUNC_QUALIFIER float prev_float(float const & x)
+ {
+ return GLM_NEXT_AFTER_FLT(x, std::numeric_limits<float>::min());
+ }
+
+ GLM_FUNC_QUALIFIER double prev_float(double const & x)
+ {
+ return GLM_NEXT_AFTER_DBL(x, std::numeric_limits<double>::min());
+ }
+
+ template<typename T, template<typename> class vecType>
+ GLM_FUNC_QUALIFIER vecType<T> prev_float(vecType<T> const & x)
+ {
+ vecType<T> Result;
+ for(std::size_t i = 0; i < Result.length(); ++i)
+ Result[i] = prev_float(x[i]);
+ return Result;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER T next_float(T const & x, uint const & ulps)
+ {
+ T temp = x;
+ for(std::size_t i = 0; i < ulps; ++i)
+ temp = next_float(temp);
+ return temp;
+ }
+
+ template<typename T, template<typename> class vecType>
+ GLM_FUNC_QUALIFIER vecType<T> next_float(vecType<T> const & x, vecType<uint> const & ulps)
+ {
+ vecType<T> Result;
+ for(std::size_t i = 0; i < Result.length(); ++i)
+ Result[i] = next_float(x[i], ulps[i]);
+ return Result;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER T prev_float(T const & x, uint const & ulps)
+ {
+ T temp = x;
+ for(std::size_t i = 0; i < ulps; ++i)
+ temp = prev_float(temp);
+ return temp;
+ }
+
+ template<typename T, template<typename> class vecType>
+ GLM_FUNC_QUALIFIER vecType<T> prev_float(vecType<T> const & x, vecType<uint> const & ulps)
+ {
+ vecType<T> Result;
+ for(std::size_t i = 0; i < Result.length(); ++i)
+ Result[i] = prev_float(x[i], ulps[i]);
+ return Result;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER uint float_distance(T const & x, T const & y)
+ {
+ uint ulp = 0;
+
+ if(x < y)
+ {
+ T temp = x;
+ while(temp != y && ulp < std::numeric_limits<std::size_t>::max())
+ {
+ ++ulp;
+ temp = next_float(temp);
+ }
+ }
+ else if(y < x)
+ {
+ T temp = y;
+ while(temp != x && ulp < std::numeric_limits<std::size_t>::max())
+ {
+ ++ulp;
+ temp = next_float(temp);
+ }
+ }
+ else // ==
+ {
+
+ }
+
+ return ulp;
+ }
+
+ template<typename T, template<typename> class vecType>
+ GLM_FUNC_QUALIFIER vecType<uint> float_distance(vecType<T> const & x, vecType<T> const & y)
+ {
+ vecType<uint> Result;
+ for(std::size_t i = 0; i < Result.length(); ++i)
+ Result[i] = float_distance(x[i], y[i]);
+ return Result;
+ }
+/*
+ inline std::size_t ulp
+ (
+ detail::thalf const & a,
+ detail::thalf const & b
+ )
+ {
+ std::size_t Count = 0;
+ float TempA(a);
+ float TempB(b);
+ //while((TempA = _nextafterf(TempA, TempB)) != TempB)
+ ++Count;
+ return Count;
+ }
+
+ inline std::size_t ulp
+ (
+ float const & a,
+ float const & b
+ )
+ {
+ std::size_t Count = 0;
+ float Temp = a;
+ //while((Temp = _nextafterf(Temp, b)) != b)
+ {
+ std::cout << Temp << " " << b << std::endl;
+ ++Count;
+ }
+ return Count;
+ }
+
+ inline std::size_t ulp
+ (
+ double const & a,
+ double const & b
+ )
+ {
+ std::size_t Count = 0;
+ double Temp = a;
+ //while((Temp = _nextafter(Temp, b)) != b)
+ {
+ std::cout << Temp << " " << b << std::endl;
+ ++Count;
+ }
+ return Count;
+ }
+
+ template <typename T>
+ inline std::size_t ulp
+ (
+ detail::tvec2<T> const & a,
+ detail::tvec2<T> const & b
+ )
+ {
+ std::size_t ulps[] =
+ {
+ ulp(a[0], b[0]),
+ ulp(a[1], b[1])
+ };
+
+ return glm::max(ulps[0], ulps[1]);
+ }
+
+ template <typename T>
+ inline std::size_t ulp
+ (
+ detail::tvec3<T> const & a,
+ detail::tvec3<T> const & b
+ )
+ {
+ std::size_t ulps[] =
+ {
+ ulp(a[0], b[0]),
+ ulp(a[1], b[1]),
+ ulp(a[2], b[2])
+ };
+
+ return glm::max(glm::max(ulps[0], ulps[1]), ulps[2]);
+ }
+
+ template <typename T>
+ inline std::size_t ulp
+ (
+ detail::tvec4<T> const & a,
+ detail::tvec4<T> const & b
+ )
+ {
+ std::size_t ulps[] =
+ {
+ ulp(a[0], b[0]),
+ ulp(a[1], b[1]),
+ ulp(a[2], b[2]),
+ ulp(a[3], b[3])
+ };
+
+ return glm::max(glm::max(ulps[0], ulps[1]), glm::max(ulps[2], ulps[3]));
+ }
+*/
+}//namespace ulp
+}//namespace gtx
+}//namespace glm
diff --git a/src/glm/gtx/unsigned_int.hpp b/src/glm/gtx/unsigned_int.hpp
new file mode 100644
index 0000000..84a858c
--- /dev/null
+++ b/src/glm/gtx/unsigned_int.hpp
@@ -0,0 +1,59 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2005-12-24
+// Updated : 2008-10-07
+// Licence : This source is under MIT License
+// File : glm/gtx/unsigned_int.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+// - GLM_GTX_integer
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_gtx_unsigned_int
+#define glm_gtx_unsigned_int
+
+// Dependency:
+#include "../glm.hpp"
+#include "../gtx/integer.hpp"
+
+#if(defined(GLM_MESSAGES) && !defined(glm_ext))
+# pragma message("GLM: GLM_GTX_unsigned_int extension included")
+#endif
+
+namespace glm{
+namespace gtx{
+namespace unsigned_int ///< GLM_GTX_unsigned_int extension: Add support for unsigned integer for core functions
+{
+ using namespace gtx::integer;
+
+ /// \addtogroup gtx_unsigned_int
+ /// @{
+
+ //! 32bit signed integer.
+ //! From GLM_GTX_unsigned_int extension.
+ typedef signed int sint;
+
+ //! Returns x raised to the y power.
+ //! From GLM_GTX_unsigned_int extension.
+ uint pow(uint x, uint y);
+
+ //! Returns the positive square root of x.
+ //! From GLM_GTX_unsigned_int extension.
+ uint sqrt(uint x);
+
+ //! Modulus. Returns x - y * floor(x / y) for each component in x using the floating point value y.
+ //! From GLM_GTX_unsigned_int extension.
+ uint mod(uint x, uint y);
+
+ /// @}
+}//namespace unsigned_int
+}//namespace gtx
+}//namespace glm
+
+#include "unsigned_int.inl"
+
+namespace glm{using namespace gtx::unsigned_int;}
+
+#endif//glm_gtx_unsigned_int
diff --git a/src/glm/gtx/unsigned_int.inl b/src/glm/gtx/unsigned_int.inl
new file mode 100644
index 0000000..21aece7
--- /dev/null
+++ b/src/glm/gtx/unsigned_int.inl
@@ -0,0 +1,45 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2005-12-24
+// Updated : 2008-10-07
+// Licence : This source is under MIT License
+// File : glm/gtx/unsigned_int.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm{
+namespace gtx{
+namespace unsigned_int{
+
+GLM_FUNC_QUALIFIER uint pow(uint x, uint y)
+{
+ uint result = x;
+ for(uint i = 1; i < y; ++i)
+ result *= x;
+ return result;
+}
+
+GLM_FUNC_QUALIFIER uint sqrt(uint x)
+{
+ if(x <= 1) return x;
+
+ uint NextTrial = x >> 1;
+ uint CurrentAnswer;
+
+ do
+ {
+ CurrentAnswer = NextTrial;
+ NextTrial = (NextTrial + x / NextTrial) >> 1;
+ } while(NextTrial < CurrentAnswer);
+
+ return CurrentAnswer;
+}
+
+GLM_FUNC_QUALIFIER uint mod(uint x, uint y)
+{
+ return x - y * (x / y);
+}
+
+}//namespace unsigned_int
+}//namespace gtx
+}//namespace glm
diff --git a/src/glm/gtx/vec1.hpp b/src/glm/gtx/vec1.hpp
new file mode 100644
index 0000000..4eee090
--- /dev/null
+++ b/src/glm/gtx/vec1.hpp
@@ -0,0 +1,121 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2010-02-08
+// Updated : 2010-02-08
+// Licence : This source is under MIT License
+// File : glm/gtx/vec1.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_gtx_vec1
+#define glm_gtx_vec1
+
+// Dependency:
+#include "../glm.hpp"
+#include "../core/type_vec1.hpp"
+
+#if(defined(GLM_MESSAGES) && !defined(glm_ext))
+# pragma message("GLM: GLM_GTX_vec1 extension included")
+#endif
+
+namespace glm{
+namespace gtx{
+namespace vector1{ ///< GLM_GTX_vec1 extension: 1 component vector.
+namespace precision
+{
+ //! 1 component vector of high precision floating-point numbers.
+ //! There is no guarantee on the actual precision.
+ //! From GLM_GTX_vec1 extension.
+ typedef detail::highp_vec1_t highp_vec1;
+ //! 1 component vector of medium precision floating-point numbers.
+ //! There is no guarantee on the actual precision.
+ //! From GLM_GTX_vec1 extension.
+ typedef detail::mediump_vec1_t mediump_vec1;
+ //! 1 component vector of low precision floating-point numbers.
+ //! There is no guarantee on the actual precision.
+ //! From GLM_GTX_vec1 extension.
+ typedef detail::lowp_vec1_t lowp_vec1;
+
+ //! 1 component vector of high precision signed integer numbers.
+ //! There is no guarantee on the actual precision.
+ //! From GLM_GTX_vec1 extension.
+ typedef detail::highp_ivec1_t highp_ivec1;
+ //! 1 component vector of medium precision signed integer numbers.
+ //! There is no guarantee on the actual precision.
+ //! From GLM_GTX_vec1 extension.
+ typedef detail::mediump_ivec1_t mediump_ivec1;
+ //! 1 component vector of low precision signed integer numbers.
+ //! There is no guarantee on the actual precision.
+ //! From GLM_GTX_vec1 extension.
+ typedef detail::lowp_ivec1_t lowp_ivec1;
+
+ //! 1 component vector of high precision unsigned integer numbers.
+ //! There is no guarantee on the actual precision.
+ //! From GLM_GTX_vec1 extension.
+ typedef detail::highp_uvec1_t highp_uvec1;
+ //! 1 component vector of medium precision unsigned integer numbers.
+ //! There is no guarantee on the actual precision.
+ //! From GLM_GTX_vec1 extension.
+ typedef detail::mediump_uvec1_t mediump_uvec1;
+ //! 1 component vector of low precision unsigned integer numbers.
+ //! There is no guarantee on the actual precision.
+ //! From GLM_GTX_vec1 extension.
+ typedef detail::lowp_uvec1_t lowp_uvec1;
+}//namespace precision
+
+ //////////////////////////
+ // vec1 definition
+
+ //! 1 component vector of boolean.
+ //! From GLM_GTX_vec1 extension.
+ typedef detail::tvec1<bool> bvec1;
+
+#if(defined(GLM_PRECISION_HIGHP_FLOAT))
+ typedef precision::highp_vec1 vec1;
+#elif(defined(GLM_PRECISION_MEDIUMP_FLOAT))
+ typedef precision::mediump_vec1 vec1;
+#elif(defined(GLM_PRECISION_LOWP_FLOAT))
+ typedef precision::lowp_vec1 vec1;
+#else
+ //! 1 component vector of floating-point numbers.
+ //! From GLM_GTX_vec1 extension.
+ typedef precision::mediump_vec1 vec1;
+#endif//GLM_PRECISION
+
+#if(defined(GLM_PRECISION_HIGHP_INT))
+ typedef precision::highp_ivec1 ivec1;
+#elif(defined(GLM_PRECISION_MEDIUMP_INT))
+ typedef precision::mediump_ivec1 ivec1;
+#elif(defined(GLM_PRECISION_LOWP_INT))
+ typedef precision::lowp_ivec1 ivec1;
+#else
+ //! 1 component vector of signed integer numbers.
+ //! From GLM_GTX_vec1 extension.
+ typedef precision::mediump_ivec1 ivec1;
+#endif//GLM_PRECISION
+
+#if(defined(GLM_PRECISION_HIGHP_UINT))
+ typedef precision::highp_uvec1 uvec1;
+#elif(defined(GLM_PRECISION_MEDIUMP_UINT))
+ typedef precision::mediump_uvec1 uvec1;
+#elif(defined(GLM_PRECISION_LOWP_UINT))
+ typedef precision::lowp_uvec1 uvec1;
+#else
+ //! 1 component vector of unsigned integer numbers.
+ //! From GLM_GTX_vec1 extension.
+ typedef precision::mediump_uvec1 uvec1;
+#endif//GLM_PRECISION
+
+}// namespace vec1
+}// namespace gtx
+}// namespace glm
+
+#include "vec1.inl"
+
+namespace glm{using namespace gtx::vector1;}
+
+#endif//glm_gtx_vec1
+
diff --git a/src/glm/gtx/vec1.inl b/src/glm/gtx/vec1.inl
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/glm/gtx/vec1.inl
diff --git a/src/glm/gtx/vector_access.hpp b/src/glm/gtx/vector_access.hpp
new file mode 100644
index 0000000..d66cc3f
--- /dev/null
+++ b/src/glm/gtx/vector_access.hpp
@@ -0,0 +1,66 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2006-01-16
+// Updated : 2008-10-07
+// Licence : This source is under MIT License
+// File : glm/gtx/vector_access.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_gtx_vector_access
+#define glm_gtx_vector_access
+
+// Dependency:
+#include "../glm.hpp"
+
+#if(defined(GLM_MESSAGES) && !defined(glm_ext))
+# pragma message("GLM: GLM_GTX_vector_access extension included")
+#endif
+
+namespace glm{
+namespace gtx{
+namespace vector_access ///< GLM_GTX_vector_access extension: Function to set values to vectors
+{
+ /// \addtogroup gtx_vector_access
+ /// @{
+
+ //! Set values to a 2 components vector.
+ //! From GLM_GTX_vector_access extension.
+ template <typename valType>
+ void set(
+ detail::tvec2<valType> & v,
+ valType const & x,
+ valType const & y);
+
+ //! Set values to a 3 components vector.
+ //! From GLM_GTX_vector_access extension.
+ template <typename valType>
+ void set(
+ detail::tvec3<valType> & v,
+ valType const & x,
+ valType const & y,
+ valType const & z);
+
+ //! Set values to a 4 components vector.
+ //! From GLM_GTX_vector_access extension.
+ template <typename valType>
+ void set(
+ detail::tvec4<valType> & v,
+ valType const & x,
+ valType const & y,
+ valType const & z,
+ valType const & w);
+
+ /// @}
+}//namespace vector_access
+}//namespace gtx
+}//namespace glm
+
+#include "vector_access.inl"
+
+namespace glm{using namespace gtx::vector_access;}
+
+#endif//glm_gtx_vector_access
diff --git a/src/glm/gtx/vector_access.inl b/src/glm/gtx/vector_access.inl
new file mode 100644
index 0000000..e375400
--- /dev/null
+++ b/src/glm/gtx/vector_access.inl
@@ -0,0 +1,58 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2006-01-16
+// Updated : 2008-10-07
+// Licence : This source is under MIT License
+// File : glm/gtx/vector_access.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm{
+namespace gtx{
+namespace vector_access{
+
+template <typename valType>
+GLM_FUNC_QUALIFIER void set
+(
+ detail::tvec2<valType>& v,
+ valType const & x,
+ valType const & y
+)
+{
+ v.x = x;
+ v.y = y;
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER void set
+(
+ detail::tvec3<valType>& v,
+ valType const & x,
+ valType const & y,
+ valType const & z
+)
+{
+ v.x = x;
+ v.y = y;
+ v.z = z;
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER void set
+(
+ detail::tvec4<valType>& v,
+ valType const & x,
+ valType const & y,
+ valType const & z,
+ valType const & w
+)
+{
+ v.x = x;
+ v.y = y;
+ v.z = z;
+ v.w = w;
+}
+
+}//namespace vector_access
+}//namespace gtx
+}//namespace glm
diff --git a/src/glm/gtx/vector_angle.hpp b/src/glm/gtx/vector_angle.hpp
new file mode 100644
index 0000000..f244c57
--- /dev/null
+++ b/src/glm/gtx/vector_angle.hpp
@@ -0,0 +1,72 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2005-12-30
+// Updated : 2006-11-13
+// Licence : This source is under MIT License
+// File : glm/gtx/vector_angle.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+// - GLM_GTX_quaternion
+// - GLM_GTX_epsilon
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_gtx_vector_angle
+#define glm_gtx_vector_angle
+
+// Dependency:
+#include "../glm.hpp"
+#include "../gtx/epsilon.hpp"
+#include "../gtx/quaternion.hpp"
+#include "../gtx/rotate_vector.hpp"
+
+#if(defined(GLM_MESSAGES) && !defined(glm_ext))
+# pragma message("GLM: GLM_GTX_vector_angle extension included")
+#endif
+
+namespace glm{
+namespace gtx{
+namespace vector_angle ///< GLM_GTX_vector_angle extension: Compute angle between vectors
+{
+ using namespace quaternion;
+ using namespace epsilon;
+
+ /// \addtogroup gtx_vector_angle
+ ///@{
+
+ //! Returns the absolute angle between two vectors
+ //! Parameters need to be normalized.
+ //! From GLM_GTX_vector_angle extension
+ template <typename vecType>
+ GLM_FUNC_QUALIFIER typename vecType::value_type angle(
+ vecType const & x,
+ vecType const & y);
+
+ //! Returns the oriented angle between two 2d vectors
+ //! Parameters need to be normalized.
+ //! From GLM_GTX_vector_angle extension.
+ template <typename T>
+ GLM_FUNC_QUALIFIER T orientedAngle(
+ detail::tvec2<T> const & x,
+ detail::tvec2<T> const & y);
+
+ //! Returns the oriented angle between two 3d vectors based from a reference axis.
+ //! Parameters need to be normalized.
+ //! From GLM_GTX_vector_angle extension.
+ template <typename T>
+ GLM_FUNC_QUALIFIER T orientedAngle(
+ detail::tvec3<T> const & x,
+ detail::tvec3<T> const & y,
+ detail::tvec3<T> const & ref);
+
+ /// @}
+}// namespace vector_angle
+}// namespace gtx
+}// namespace glm
+
+#include "vector_angle.inl"
+
+namespace glm{using namespace gtx::vector_angle;}
+
+#endif//glm_gtx_vector_angle
diff --git a/src/glm/gtx/vector_angle.inl b/src/glm/gtx/vector_angle.inl
new file mode 100644
index 0000000..658d185
--- /dev/null
+++ b/src/glm/gtx/vector_angle.inl
@@ -0,0 +1,58 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2005-12-30
+// Updated : 2008-09-29
+// Licence : This source is under MIT License
+// File : glm/gtx/vector_angle.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm{
+namespace gtx{
+namespace vector_angle{
+
+template <typename genType>
+GLM_FUNC_QUALIFIER typename genType::value_type angle
+(
+ genType const & x,
+ genType const & y
+)
+{
+ return degrees(acos(dot(x, y)));
+}
+
+//! \todo epsilon is hard coded to 0.01
+template <typename valType>
+GLM_FUNC_QUALIFIER valType orientedAngle
+(
+ detail::tvec2<valType> const & x,
+ detail::tvec2<valType> const & y
+)
+{
+ valType Angle = glm::degrees(acos(dot(x, y)));
+ detail::tvec2<valType> TransformedVector = glm::gtx::rotate_vector::rotate(x, Angle);
+ if(all(equalEpsilon(y, TransformedVector, valType(0.01))))
+ return Angle;
+ else
+ return -Angle;
+}
+
+template <typename valType>
+GLM_FUNC_QUALIFIER valType orientedAngle
+(
+ detail::tvec3<valType> const & x,
+ detail::tvec3<valType> const & y,
+ detail::tvec3<valType> const & ref
+)
+{
+ valType Angle = glm::degrees(glm::acos(glm::dot(x, y)));
+
+ if(glm::dot(ref, glm::cross(x, y)) < valType(0))
+ return -Angle;
+ else
+ return Angle;
+}
+
+}//namespace vector_angle
+}//namespace gtx
+}//namespace glm
diff --git a/src/glm/gtx/vector_query.hpp b/src/glm/gtx/vector_query.hpp
new file mode 100644
index 0000000..f1e6d22
--- /dev/null
+++ b/src/glm/gtx/vector_query.hpp
@@ -0,0 +1,95 @@
+ ///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2007-03-05
+// Updated : 2007-03-05
+// Licence : This source is under MIT License
+// File : glm/gtx/vector_query.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_gtx_vector_query
+#define glm_gtx_vector_query
+
+// Dependency:
+#include "../glm.hpp"
+#include <cfloat>
+#include <limits>
+
+#if(defined(GLM_MESSAGES) && !defined(glm_ext))
+# pragma message("GLM: GLM_GTX_vector_query extension included")
+#endif
+
+namespace glm{
+namespace gtx{
+namespace vector_query ///< GLM_GTX_vector_query extension: Query informations of vector types
+{
+ /// \addtogroup gtx_vector_query
+ /// @{
+
+ //! Check if two vectors are collinears.
+ //! From GLM_GTX_vector_query extensions.
+ template <typename genType>
+ bool areCollinear(
+ genType const & v0,
+ genType const & v1,
+ typename genType::value_type const & epsilon = std::numeric_limits<typename genType::value_type>::epsilon());
+
+ //! Check if two vectors are opposites.
+ //! From GLM_GTX_vector_query extensions.
+ template <typename genType>
+ bool areOpposite(
+ genType const & v0,
+ genType const & v1,
+ typename genType::value_type const & epsilon = std::numeric_limits<typename genType::value_type>::epsilon());
+
+ //! Check if two vectors are orthogonals.
+ //! From GLM_GTX_vector_query extensions.
+ template <typename genType>
+ bool areOrthogonal(
+ genType const & v0,
+ genType const & v1,
+ typename genType::value_type const & epsilon = std::numeric_limits<typename genType::value_type>::epsilon());
+
+ //! Check if a vector is normalized.
+ //! From GLM_GTX_vector_query extensions.
+ template <typename genType>
+ bool isNormalized(
+ genType const & v,
+ typename genType::value_type const & epsilon = std::numeric_limits<typename genType::value_type>::epsilon());
+
+ //! Check if a vector is null.
+ //! From GLM_GTX_vector_query extensions.
+ template <typename genType>
+ bool isNull(
+ genType const & v,
+ typename genType::value_type const & epsilon = std::numeric_limits<typename genType::value_type>::epsilon());
+
+ //! Check if two vectors are orthonormal.
+ //! From GLM_GTX_vector_query extensions.
+ template <typename genType>
+ bool areOrthonormal(
+ genType const & v0,
+ genType const & v1,
+ typename genType::value_type const & epsilon = std::numeric_limits<typename genType::value_type>::epsilon());
+
+ //! Check if two vectors are similar.
+ //! From GLM_GTX_vector_query extensions.
+ template <typename genType>
+ bool areSimilar(
+ genType const & v0,
+ genType const & v1,
+ typename genType::value_type const & epsilon = std::numeric_limits<typename genType::value_type>::epsilon());
+
+ /// @}
+}// namespace vector_query
+}// namespace gtx
+}// namespace glm
+
+#include "vector_query.inl"
+
+namespace glm{using namespace gtx::vector_query;}
+
+#endif//glm_gtx_vector_query
diff --git a/src/glm/gtx/vector_query.inl b/src/glm/gtx/vector_query.inl
new file mode 100644
index 0000000..da96556
--- /dev/null
+++ b/src/glm/gtx/vector_query.inl
@@ -0,0 +1,174 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2007-03-05
+// Updated : 2010-02-16
+// Licence : This source is under MIT License
+// File : glm/gtx/vector_query.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#include <cassert>
+
+namespace glm{
+namespace gtx{
+namespace vector_query
+{
+ template <typename T>
+ GLM_FUNC_QUALIFIER bool areCollinear
+ (
+ detail::tvec2<T> const & v0,
+ detail::tvec2<T> const & v1,
+ T const & epsilon
+ )
+ {
+ return length(cross(detail::tvec3<T>(v0, T(0)), detail::tvec3<T>(v1, T(0)))) < epsilon;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER bool areCollinear
+ (
+ detail::tvec3<T> const & v0,
+ detail::tvec3<T> const & v1,
+ T const & epsilon
+ )
+ {
+ return length(cross(v0, v1)) < epsilon;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER bool areCollinear
+ (
+ detail::tvec4<T> const & v0,
+ detail::tvec4<T> const & v1,
+ T const & epsilon
+ )
+ {
+ return length(cross(detail::tvec3<T>(v0), detail::tvec3<T>(v1))) < epsilon;
+ }
+
+ template <typename genType>
+ GLM_FUNC_QUALIFIER bool areOpposite
+ (
+ genType const & v0,
+ genType const & v1,
+ typename genType::value_type const & epsilon
+ )
+ {
+ assert(isNormalized(v0) && isNormalized(v1));
+ return((typename genType::value_type(1) + dot(v0, v1)) <= epsilon);
+ }
+
+ template <typename genType>
+ GLM_FUNC_QUALIFIER bool areOrthogonal
+ (
+ genType const & v0,
+ genType const & v1,
+ typename genType::value_type const & epsilon
+ )
+ {
+ return abs(dot(v0, v1)) <= max(
+ typename genType::value_type(1),
+ length(v0)) * max(
+ typename genType::value_type(1),
+ length(v1)) * epsilon;
+ }
+
+ template <typename genType>
+ GLM_FUNC_QUALIFIER bool isNormalized
+ (
+ genType const & v,
+ typename genType::value_type const & epsilon
+ )
+ {
+ return abs(length(v) - typename genType::value_type(1)) <= typename genType::value_type(2) * epsilon;
+ }
+
+ template <typename genType>
+ GLM_FUNC_QUALIFIER bool isNull
+ (
+ genType const & v,
+ typename genType::value_type const & epsilon
+ )
+ {
+ return length(v) <= epsilon;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER bool isCompNull
+ (
+ T const & s,
+ T const & epsilon
+ )
+ {
+ return abs(s) < epsilon;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<bool> isCompNull
+ (
+ detail::tvec2<T> const & v,
+ T const & epsilon)
+ {
+ return detail::tvec2<bool>(
+ (abs(v.x) < epsilon),
+ (abs(v.y) < epsilon));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<bool> isCompNull
+ (
+ detail::tvec3<T> const & v,
+ T const & epsilon
+ )
+ {
+ return detail::tvec3<bool>(
+ abs(v.x) < epsilon,
+ abs(v.y) < epsilon,
+ abs(v.z) < epsilon);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<bool> isCompNull
+ (
+ detail::tvec4<T> const & v,
+ T const & epsilon
+ )
+ {
+ return detail::tvec4<bool>(
+ abs(v.x) < epsilon,
+ abs(v.y) < epsilon,
+ abs(v.z) < epsilon,
+ abs(v.w) < epsilon);
+ }
+
+ template <typename genType>
+ GLM_FUNC_QUALIFIER bool areOrthonormal
+ (
+ genType const & v0,
+ genType const & v1,
+ typename genType::value_type const & epsilon
+ )
+ {
+ return isNormalized(v0, epsilon) && isNormalized(v1, epsilon) && (abs(dot(v0, v1)) <= epsilon);
+ }
+
+ template <typename genType>
+ GLM_FUNC_QUALIFIER bool areSimilar
+ (
+ genType const & v0,
+ genType const & v1,
+ typename genType::value_type const & epsilon
+ )
+ {
+ bool similar = true;
+ for(typename genType::size_type i = 0; similar && i < genType::value_size(); i++)
+ similar = (abs(v0[i] - v1[i]) <= epsilon);
+ return similar;
+ }
+
+}//namespace vector_query
+}//namespace gtx
+}//namespace glm
diff --git a/src/glm/gtx/verbose_operator.hpp b/src/glm/gtx/verbose_operator.hpp
new file mode 100644
index 0000000..7411aeb
--- /dev/null
+++ b/src/glm/gtx/verbose_operator.hpp
@@ -0,0 +1,64 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2007-05-21
+// Updated : 2007-05-21
+// Licence : This source is under MIT License
+// File : glm/gtx/verbose_operator.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_gtx_verbose_operator
+#define glm_gtx_verbose_operator
+
+// Dependency:
+#include "../glm.hpp"
+
+#if(defined(GLM_MESSAGES) && !defined(glm_ext))
+# pragma message("GLM: GLM_GTX_verbose_operator extension included")
+#endif
+
+namespace glm{
+namespace gtx{
+namespace verbose_operator ///< GLM_GTX_verbose_operator extension: Use words to replace operators
+{
+ /// \addtogroup gtx_verbose_operator
+ /// @{
+
+ //! Addition of two values
+ //! From GLM_GTX_verbose_operator extension.
+ template <typename genTypeT, typename genTypeU>
+ genTypeT add(genTypeT const & a, genTypeU const & b);
+
+ //! Substration of two values
+ //! From GLM_GTX_verbose_operator extension.
+ template <typename genTypeT, typename genTypeU>
+ genTypeT sub(genTypeT const & a, genTypeU const & b);
+
+ //! Multiplication of two values
+ //! From GLM_GTX_verbose_operator extension.
+ template <typename genTypeT, typename genTypeU>
+ genTypeT mul(genTypeT const & a, genTypeU const & b);
+
+ //! Division of two values
+ //! From GLM_GTX_verbose_operator extension.
+ template <typename genTypeT, typename genTypeU>
+ genTypeT div(genTypeT const & a, genTypeU const & b);
+
+ //! Multiplication and addition of three values
+ //! From GLM_GTX_verbose_operator extension.
+ template <typename genTypeT, typename genTypeU, typename genTypeV>
+ genTypeT mad(genTypeT const & a, genTypeU const & b, genTypeV const & c);
+
+ /// @}
+}// namespace verbose_operator
+}// namespace gtx
+}// namespace glm
+
+#include "verbose_operator.inl"
+
+namespace glm{using namespace gtx::verbose_operator;}
+
+#endif//glm_gtx_verbose_operator
diff --git a/src/glm/gtx/verbose_operator.inl b/src/glm/gtx/verbose_operator.inl
new file mode 100644
index 0000000..205932b
--- /dev/null
+++ b/src/glm/gtx/verbose_operator.inl
@@ -0,0 +1,129 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2006-04-20
+// Updated : 2008-09-29
+// Licence : This source is under MIT License
+// File : glm/gtx/verbose_operator.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm{
+namespace gtx{
+namespace verbose_operator{
+
+template <typename genType>
+GLM_FUNC_QUALIFIER genType add(genType const & a, genType const & b)
+{
+ return a + b;
+}
+
+template <typename genType>
+GLM_FUNC_QUALIFIER genType sub(genType const & a, genType const & b)
+{
+ return a - b;
+}
+
+template <typename T>
+GLM_FUNC_QUALIFIER detail::tmat2x2<T> mul
+(
+ detail::tmat2x2<T> const & a,
+ detail::tmat2x2<T> const & b
+)
+{
+ return a * b;
+}
+
+template <typename T>
+GLM_FUNC_QUALIFIER detail::tmat3x3<T> mul
+(
+ detail::tmat3x3<T> const & a,
+ detail::tmat3x3<T> const & b
+)
+{
+ return a * b;
+}
+
+template <typename T>
+GLM_FUNC_QUALIFIER detail::tmat4x4<T> mul
+(
+ detail::tmat4x4<T> const & a,
+ detail::tmat4x4<T> const & b
+)
+{
+ return a * b;
+}
+
+template <typename T>
+GLM_FUNC_QUALIFIER detail::tvec2<T> mul
+(
+ detail::tmat2x2<T> const & m,
+ detail::tvec2<T> const & v
+)
+{
+ return m * v;
+}
+
+template <typename T>
+GLM_FUNC_QUALIFIER detail::tvec3<T> mul
+(
+ detail::tmat3x3<T> const & m,
+ detail::tvec3<T> const & v)
+{
+ return m * v;
+}
+
+template <typename T>
+GLM_FUNC_QUALIFIER detail::tvec4<T> mul
+(
+ detail::tmat4x4<T> const & m,
+ detail::tvec4<T> const & v
+)
+{
+ return m * v;
+}
+
+template <typename T>
+GLM_FUNC_QUALIFIER detail::tvec2<T> mul
+(
+ detail::tvec2<T> const & v,
+ detail::tmat2x2<T> const & m
+)
+{
+ return v * m;
+}
+
+template <typename T>
+GLM_FUNC_QUALIFIER detail::tvec3<T> mul
+(
+ detail::tvec3<T> const & v,
+ detail::tmat3x3<T> const & m
+)
+{
+ return v * m;
+}
+
+template <typename T>
+GLM_FUNC_QUALIFIER detail::tvec4<T> mul
+(
+ detail::tvec4<T> const & v,
+ detail::tmat4x4<T> const & m
+)
+{
+ return v * m;
+}
+
+template <typename genType>
+GLM_FUNC_QUALIFIER genType div(genType const & a, genType const & b)
+{
+ return a / b;
+}
+
+template <typename genTypeT, typename genTypeU, typename genTypeV>
+GLM_FUNC_QUALIFIER genTypeT mad(genTypeT const & a, genTypeU const & b, genTypeV const & c)
+{
+ return a * b + c;
+}
+
+}//namespace verbose_operator
+}//namespace gtx
+}//namespace glm
diff --git a/src/glm/gtx/wrap.hpp b/src/glm/gtx/wrap.hpp
new file mode 100644
index 0000000..1ca3a0a
--- /dev/null
+++ b/src/glm/gtx/wrap.hpp
@@ -0,0 +1,54 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2009-11-25
+// Updated : 2009-11-25
+// Licence : This source is under MIT License
+// File : glm/gtx/wrap.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_gtx_wrap
+#define glm_gtx_wrap
+
+// Dependency:
+#include "../glm.hpp"
+
+#if(defined(GLM_MESSAGES) && !defined(glm_ext))
+# pragma message("GLM: GLM_GTX_wrap extension included")
+#endif
+
+namespace glm{
+namespace gtx{
+namespace wrap ///< GLM_GTX_wrap: Wrapping mode using my texture samping.
+{
+ /// \addtogroup gtx_wrap
+ /// @{
+
+ //! Simulate GL_CLAMP OpenGL wrap mode
+ //! From GLM_GTX_wrap extension.
+ template <typename genType>
+ genType clamp(genType const & Texcoord);
+
+ //! Simulate GL_REPEAT OpenGL wrap mode
+ //! From GLM_GTX_wrap extension.
+ template <typename genType>
+ genType repeat(genType const & Texcoord);
+
+ //! Simulate GL_MIRROR_REPEAT OpenGL wrap mode
+ //! From GLM_GTX_wrap extension.
+ template <typename genType>
+ genType mirrorRepeat(genType const & Texcoord);
+
+ /// @}
+}// namespace wrap
+}// namespace gtx
+}// namespace glm
+
+#include "wrap.inl"
+
+namespace glm{using namespace gtx::wrap;}
+
+#endif//glm_img_wrap
diff --git a/src/glm/gtx/wrap.inl b/src/glm/gtx/wrap.inl
new file mode 100644
index 0000000..a687ded
--- /dev/null
+++ b/src/glm/gtx/wrap.inl
@@ -0,0 +1,173 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2009-11-25
+// Updated : 2010-02-13
+// Licence : This source is under MIT License
+// File : glm/gtx/wrap.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm{
+namespace gtx{
+namespace wrap
+{
+ ////////////////////////
+ // clamp
+
+ template <typename genType>
+ GLM_FUNC_QUALIFIER genType clamp
+ (
+ genType const & Texcoord
+ )
+ {
+ return glm::clamp(Texcoord, genType(0), genType(1));
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<T> clamp
+ (
+ detail::tvec2<T> const & Texcoord
+ )
+ {
+ detail::tvec2<T> Result;
+ for(typename detail::tvec2<T>::size_type i = 0; i < detail::tvec2<T>::value_size(); ++i)
+ Result[i] = clamp(Texcoord[i]);
+ return Result;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> clamp
+ (
+ detail::tvec3<T> const & Texcoord
+ )
+ {
+ detail::tvec3<T> Result;
+ for(typename detail::tvec3<T>::size_type i = 0; i < detail::tvec3<T>::value_size(); ++i)
+ Result[i] = clamp(Texcoord[i]);
+ return Result;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<T> clamp
+ (
+ detail::tvec4<T> const & Texcoord
+ )
+ {
+ detail::tvec4<T> Result;
+ for(typename detail::tvec4<T>::size_type i = 0; i < detail::tvec4<T>::value_size(); ++i)
+ Result[i] = clamp(Texcoord[i]);
+ return Result;
+ }
+
+ ////////////////////////
+ // repeat
+
+ template <typename genType>
+ GLM_FUNC_QUALIFIER genType repeat
+ (
+ genType const & Texcoord
+ )
+ {
+ return glm::fract(Texcoord);
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<T> repeat
+ (
+ detail::tvec2<T> const & Texcoord
+ )
+ {
+ detail::tvec2<T> Result;
+ for(typename detail::tvec2<T>::size_type i = 0; i < detail::tvec2<T>::value_size(); ++i)
+ Result[i] = repeat(Texcoord[i]);
+ return Result;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> repeat
+ (
+ detail::tvec3<T> const & Texcoord
+ )
+ {
+ detail::tvec3<T> Result;
+ for(typename detail::tvec3<T>::size_type i = 0; i < detail::tvec3<T>::value_size(); ++i)
+ Result[i] = repeat(Texcoord[i]);
+ return Result;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<T> repeat
+ (
+ detail::tvec4<T> const & Texcoord
+ )
+ {
+ detail::tvec4<T> Result;
+ for(typename detail::tvec4<T>::size_type i = 0; i < detail::tvec4<T>::value_size(); ++i)
+ Result[i] = repeat(Texcoord[i]);
+ return Result;
+ }
+
+ ////////////////////////
+ // mirrorRepeat
+
+ template <typename genType>
+ GLM_FUNC_QUALIFIER genType mirrorRepeat
+ (
+ genType const & Texcoord
+ )
+ {
+ genType const Clamp = genType(int(glm::floor(Texcoord)) % 2);
+ genType const Floor = glm::floor(Texcoord);
+ genType const Rest = Texcoord - Floor;
+ genType const Mirror = Clamp + Rest;
+
+ genType Out;
+ if(Mirror >= genType(1))
+ Out = genType(1) - Rest;
+ else
+ Out = Rest;
+ return Out;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec2<T> mirrorRepeat
+ (
+ detail::tvec2<T> const & Texcoord
+ )
+ {
+ detail::tvec2<T> Result;
+ for(typename detail::tvec2<T>::size_type i = 0; i < detail::tvec2<T>::value_size(); ++i)
+ Result[i] = mirrorRepeat(Texcoord[i]);
+ return Result;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec3<T> mirrorRepeat
+ (
+ detail::tvec3<T> const & Texcoord
+ )
+ {
+ detail::tvec3<T> Result;
+ for(typename detail::tvec3<T>::size_type i = 0; i < detail::tvec3<T>::value_size(); ++i)
+ Result[i] = mirrorRepeat(Texcoord[i]);
+ return Result;
+ }
+
+ template <typename T>
+ GLM_FUNC_QUALIFIER detail::tvec4<T> mirrorRepeat
+ (
+ detail::tvec4<T> const & Texcoord
+ )
+ {
+ detail::tvec4<T> Result;
+ for(typename detail::tvec4<T>::size_type i = 0; i < detail::tvec4<T>::value_size(); ++i)
+ Result[i] = mirrorRepeat(Texcoord[i]);
+ return Result;
+ }
+
+}//namespace wrap
+}//namespace gtx
+}//namespace glm
diff --git a/src/glm/virtrev/xstream.hpp b/src/glm/virtrev/xstream.hpp
new file mode 100644
index 0000000..2b8b95a
--- /dev/null
+++ b/src/glm/virtrev/xstream.hpp
@@ -0,0 +1,148 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+// Virtrev SDK copyright matrem (matrem84.free.fr)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2008-05-24
+// Updated : 2008-05-26
+// Licence : This source is under MIT License
+// File : glm/ext/virtrev/xstream.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+// - GLM_GTX_matrix_selection
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef GLM_EXT_VIRTREV_XSTREAM_HPP
+#define GLM_EXT_VIRTREV_XSTREAM_HPP
+
+#include "../glm.hpp"
+#include "../gtc/matrix_access.hpp"
+#include <iostream>
+
+#if(defined(GLM_MESSAGES) && !defined(glm_ext))
+# pragma message("GLM: GLM_VIRTREV_xstream extension included")
+#endif
+
+namespace glm
+{
+ namespace virtrev_glmext
+ {
+ //! GLM_VIRTREV_xstream extension: Streaming vector and matrix in a xml way
+ namespace xstream
+ {
+ template<typename T>
+ std::ostream & operator << (std::ostream & stream, glm::detail::tvec2<T> const & vec)
+ {
+ stream << "<glm_vec2 ";
+ stream << "x=\"" << vec.x << "\" ";
+ stream << "y=\"" << vec.y << "\" ";
+ stream << "/>";
+
+ return stream;
+ }
+
+ template<typename T>
+ std::ostream & operator << (std::ostream & stream, glm::detail::tvec3<T> const & vec)
+ {
+ stream << "<glm_vec3 ";
+ stream << "x=\"" << vec.x << "\" ";
+ stream << "y=\"" << vec.y << "\" ";
+ stream << "z=\"" << vec.z << "\" ";
+ stream << "/>";
+
+ return stream;
+ }
+
+ template<typename T>
+ std::ostream & operator << (std::ostream & stream, glm::detail::tvec4<T> const & vec)
+ {
+ stream << "<glm_vec4 ";
+ stream << "x=\"" << vec.x << "\" ";
+ stream << "y=\"" << vec.y << "\" ";
+ stream << "z=\"" << vec.z << "\" ";
+ stream << "w=\"" << vec.w << "\" ";
+ stream << "/>";
+
+ return stream;
+ }
+
+ template<typename T>
+ std::ostream & operator << (std::ostream & stream, glm::detail::tmat2x2<T> const & mat)
+ {
+ stream << "<glm_mat2>" << std::endl;
+ stream << "<row ";
+ stream << "x=\"" << glm::row(mat, 0)[0] << "\" ";
+ stream << "y=\"" << glm::row(mat, 0)[1] << "\" ";
+ stream << "/>" << std::endl;
+ stream << "<row ";
+ stream << "x=\"" << glm::row(mat, 1)[0] << "\" ";
+ stream << "y=\"" << glm::row(mat, 1)[1] << "\" ";
+ stream << "/>" << std::endl;
+ stream << "</glm_mat2>";
+
+ return stream;
+ }
+
+ template<typename T>
+ std::ostream & operator << (std::ostream & stream, glm::detail::tmat3x3<T> const & mat)
+ {
+ stream << "<glm_mat3>" << std::endl;
+ stream << "<row ";
+ stream << "x=\"" << glm::row(mat, 0)[0] << "\" ";
+ stream << "y=\"" << glm::row(mat, 0)[1] << "\" ";
+ stream << "z=\"" << glm::row(mat, 0)[2] << "\" ";
+ stream << "/>" << std::endl;
+ stream << "<row ";
+ stream << "x=\"" << glm::row(mat, 1)[0] << "\" ";
+ stream << "y=\"" << glm::row(mat, 1)[1] << "\" ";
+ stream << "z=\"" << glm::row(mat, 1)[2] << "\" ";
+ stream << "/>" << std::endl;
+ stream << "<row ";
+ stream << "x=\"" << glm::row(mat, 2)[0] << "\" ";
+ stream << "y=\"" << glm::row(mat, 2)[1] << "\" ";
+ stream << "z=\"" << glm::row(mat, 2)[2] << "\" ";
+ stream << "/>" << std::endl;
+ stream << "</glm_mat3>";
+
+ return stream;
+ }
+
+ template<typename T>
+ std::ostream & operator << (std::ostream & stream, glm::detail::tmat4x4<T> const & mat)
+ {
+ stream << "<glm_mat4>" << std::endl;
+ stream << "<row ";
+ stream << "x=\"" << glm::row(mat, 0)[0] << "\" ";
+ stream << "y=\"" << glm::row(mat, 0)[1] << "\" ";
+ stream << "z=\"" << glm::row(mat, 0)[2] << "\" ";
+ stream << "w=\"" << glm::row(mat, 0)[3] << "\" ";
+ stream << "/>" << std::endl;
+ stream << "<row ";
+ stream << "x=\"" << glm::row(mat, 1)[0] << "\" ";
+ stream << "y=\"" << glm::row(mat, 1)[1] << "\" ";
+ stream << "z=\"" << glm::row(mat, 1)[2] << "\" ";
+ stream << "w=\"" << glm::row(mat, 1)[3] << "\" ";
+ stream << "/>" << std::endl;
+ stream << "<row ";
+ stream << "x=\"" << glm::row(mat, 2)[0] << "\" ";
+ stream << "y=\"" << glm::row(mat, 2)[1] << "\" ";
+ stream << "z=\"" << glm::row(mat, 2)[2] << "\" ";
+ stream << "w=\"" << glm::row(mat, 2)[3] << "\" ";
+ stream << "/>" << std::endl;
+ stream << "<row ";
+ stream << "x=\"" << glm::row(mat, 3)[0] << "\" ";
+ stream << "y=\"" << glm::row(mat, 3)[1] << "\" ";
+ stream << "z=\"" << glm::row(mat, 3)[2] << "\" ";
+ stream << "w=\"" << glm::row(mat, 3)[3] << "\" ";
+ stream << "/>" << std::endl;
+ stream << "</glm_mat4>";
+
+ return stream;
+ }
+ }
+ }
+}
+
+namespace glm{using namespace glm::virtrev_glmext::xstream;}
+
+#endif//GLM_EXT_VIRTREV_XSTREAM_HPP
diff --git a/src/graphics/AppleDisplay.cpp b/src/graphics/AppleDisplay.cpp
new file mode 100644
index 0000000..eb8ab0c
--- /dev/null
+++ b/src/graphics/AppleDisplay.cpp
@@ -0,0 +1,75 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "AppleDisplay.h"
+#include "../base/Logger.h"
+
+#include <ApplicationServices/ApplicationServices.h>
+
+#include <iostream>
+
+using namespace std;
+
+namespace avg {
+
+AppleDisplay::AppleDisplay()
+{
+}
+
+AppleDisplay::~AppleDisplay()
+{
+}
+
+float AppleDisplay::queryPPMM()
+{
+ CGSize size = CGDisplayScreenSize(CGMainDisplayID());
+ return getScreenResolution().x/size.width;
+}
+
+float AppleDisplay::queryRefreshRate()
+{
+ float refreshRate;
+#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6
+ CGDisplayModeRef mode = CGDisplayCopyDisplayMode(CGMainDisplayID());
+ refreshRate = CGDisplayModeGetRefreshRate(mode);
+ if (refreshRate < 1.0) {
+ AVG_TRACE(Logger::category::CONFIG, Logger::severity::INFO,
+ "This seems to be a TFT screen, assuming 60 Hz refresh rate.");
+ refreshRate = 60;
+ }
+ CGDisplayModeRelease(mode);
+#else
+ CFDictionaryRef modeInfo = CGDisplayCurrentMode(CGMainDisplayID());
+ AVG_ASSERT(modeInfo);
+ CFNumberRef value = (CFNumberRef) CFDictionaryGetValue(modeInfo,
+ kCGDisplayRefreshRate);
+ AVG_ASSERT(value);
+ CFNumberGetValue(value, kCFNumberIntType, &refreshRate);
+ if (refreshRate < 1.0) {
+ AVG_TRACE(Logger::category::CONFIG, Logger::severity::INFO,
+ "This seems to be a TFT screen, assuming 60 Hz refresh rate.");
+ refreshRate = 60;
+ }
+#endif
+ return refreshRate;
+}
+
+}
diff --git a/src/graphics/AppleDisplay.h b/src/graphics/AppleDisplay.h
new file mode 100644
index 0000000..dcae299
--- /dev/null
+++ b/src/graphics/AppleDisplay.h
@@ -0,0 +1,46 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _AppleDisplay_H_
+#define _AppleDisplay_H_
+
+#include "../api.h"
+#include "../avgconfigwrapper.h"
+
+#include "Display.h"
+
+namespace avg {
+
+class AVG_API AppleDisplay: public Display
+{
+public:
+ AppleDisplay();
+ virtual ~AppleDisplay();
+
+protected:
+ virtual float queryPPMM();
+ virtual float queryRefreshRate();
+
+};
+
+}
+
+#endif
diff --git a/src/graphics/BCMDisplay.cpp b/src/graphics/BCMDisplay.cpp
new file mode 100644
index 0000000..917e0e6
--- /dev/null
+++ b/src/graphics/BCMDisplay.cpp
@@ -0,0 +1,142 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "BCMDisplay.h"
+
+#include "../base/Exception.h"
+
+#include <SDL/SDL.h>
+#include <SDL/SDL_syswm.h>
+
+#include <EGL/eglext_brcm.h>
+
+#include <iostream>
+
+using namespace std;
+
+namespace avg {
+
+IntPoint getX11WindowPosition(const SDL_SysWMinfo* pSDLWMInfo)
+{
+ int x, y;
+ Window dummy;
+ XWindowAttributes wAttribs;
+ pSDLWMInfo->info.x11.lock_func();
+ XGetWindowAttributes(pSDLWMInfo->info.x11.display, pSDLWMInfo->info.x11.window,
+ &wAttribs);
+ XTranslateCoordinates(pSDLWMInfo->info.x11.display, pSDLWMInfo->info.x11.window,
+ wAttribs.root, 0, 0, &x, &y, &dummy);
+ pSDLWMInfo->info.x11.unlock_func();
+ return IntPoint(x, y);
+}
+
+DISPMANX_DISPLAY_HANDLE_T getBCMDisplay(const SDL_SysWMinfo* pSDLWMInfo)
+{
+ bcm_host_init();
+
+ DISPMANX_DISPLAY_HANDLE_T display = vc_dispmanx_display_open(DISPMANX_ID_MAIN_LCD);
+ if (display == DISPMANX_NO_HANDLE) {
+ throw Exception(AVG_ERR_VIDEO_GENERAL, "No BCM display available.");
+ }
+ return display;
+}
+
+EGL_DISPMANX_WINDOW_T* createChildWindow(const SDL_SysWMinfo* pSDLWMInfo,
+ EGLNativeDisplayType bcmDisplay, const IntPoint& windowSize)
+{
+ // Create a child (yet toplevel) window with the required attributes to render into.
+ IntPoint windowPos = getX11WindowPosition(pSDLWMInfo);
+ VC_RECT_T dstRect;
+ dstRect.x = windowPos.x;
+ dstRect.y = windowPos.y;
+ dstRect.width = windowSize.x;
+ dstRect.height = windowSize.y;
+ VC_RECT_T srcRect;
+ srcRect.x = 0;
+ srcRect.y = 0;
+ srcRect.width = windowSize.x << 16;
+ srcRect.height = windowSize.y << 16;
+ // start display update
+ DISPMANX_UPDATE_HANDLE_T update = vc_dispmanx_update_start(0);
+ if (update == DISPMANX_NO_HANDLE) {
+ throw Exception(AVG_ERR_VIDEO_GENERAL, "Failed to start BCM display update.");
+ }
+ // add element to display
+ DISPMANX_ELEMENT_HANDLE_T element = vc_dispmanx_element_add(update,
+ (DISPMANX_DISPLAY_HANDLE_T)bcmDisplay,
+ 0 /* layer */, &dstRect, DISPMANX_NO_HANDLE /* src */, &srcRect,
+ (DISPMANX_PROTECTION_T) DISPMANX_PROTECTION_NONE,
+ 0 /* alpha */, 0 /* clamp */, DISPMANX_NO_ROTATE);
+ if (element == DISPMANX_NO_HANDLE) {
+ throw Exception(AVG_ERR_VIDEO_GENERAL, "Failed to add element to BCM display.");
+ }
+ // finish display update
+ if (vc_dispmanx_update_submit_sync(update)) {
+ throw Exception(AVG_ERR_VIDEO_GENERAL, "Failed to finish BCM display update.");
+ }
+
+ EGL_DISPMANX_WINDOW_T* pWin = new EGL_DISPMANX_WINDOW_T; // XXX: destroy
+ pWin->element = element;
+ pWin->width = windowSize.x;
+ pWin->height = windowSize.y;
+ return pWin;
+}
+
+EGLSurface createBCMPixmapSurface(EGLDisplay display, EGLConfig config)
+{
+ EGLint pixel_format = EGL_PIXEL_FORMAT_ARGB_8888_BRCM;
+ EGLint rt;
+ eglGetConfigAttrib(display, config, EGL_RENDERABLE_TYPE, &rt);
+
+ if (rt & EGL_OPENGL_ES_BIT) {
+ pixel_format |= EGL_PIXEL_FORMAT_RENDER_GLES_BRCM;
+ pixel_format |= EGL_PIXEL_FORMAT_GLES_TEXTURE_BRCM;
+ }
+ if (rt & EGL_OPENGL_ES2_BIT) {
+ pixel_format |= EGL_PIXEL_FORMAT_RENDER_GLES2_BRCM;
+ pixel_format |= EGL_PIXEL_FORMAT_GLES2_TEXTURE_BRCM;
+ }
+ if (rt & EGL_OPENVG_BIT) {
+ pixel_format |= EGL_PIXEL_FORMAT_RENDER_VG_BRCM;
+ pixel_format |= EGL_PIXEL_FORMAT_VG_IMAGE_BRCM;
+ }
+ if (rt & EGL_OPENGL_BIT) {
+ pixel_format |= EGL_PIXEL_FORMAT_RENDER_GL_BRCM;
+ }
+
+ EGLint pixmap[5];
+ pixmap[0] = 0;
+ pixmap[1] = 0;
+ pixmap[2] = 8;
+ pixmap[3] = 8;
+ pixmap[4] = pixel_format;
+
+ eglCreateGlobalImageBRCM(8, 8, pixel_format, 0, 8*4, pixmap);
+
+ EGLSurface surface = eglCreatePixmapSurface(display, config, pixmap, 0);
+ if ( surface == EGL_NO_SURFACE ) {
+ cerr << "Unable to create EGL surface (eglError: " << eglGetError() << ")" << endl;
+ }
+ return surface;
+
+}
+
+}
diff --git a/src/graphics/BCMDisplay.h b/src/graphics/BCMDisplay.h
new file mode 100644
index 0000000..4c750dd
--- /dev/null
+++ b/src/graphics/BCMDisplay.h
@@ -0,0 +1,45 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+#ifndef _BCMDisplay_H_
+#define _BCMDisplay_H_
+
+#include <bcm_host.h>
+
+#include "../api.h"
+
+#include "../base/GLMHelper.h"
+
+#include "OGLHelper.h"
+
+struct SDL_SysWMinfo;
+
+namespace avg {
+
+DISPMANX_DISPLAY_HANDLE_T getBCMDisplay(const SDL_SysWMinfo* pSDLWMInfo);
+
+EGL_DISPMANX_WINDOW_T* createChildWindow(const SDL_SysWMinfo* pSDLWMInfo,
+ EGLNativeDisplayType bcmDisplay, const IntPoint& windowSize);
+
+EGLSurface createBCMPixmapSurface(EGLDisplay display, EGLConfig config);
+
+}
+
+#endif
diff --git a/src/graphics/Bitmap.cpp b/src/graphics/Bitmap.cpp
new file mode 100644
index 0000000..63b4115
--- /dev/null
+++ b/src/graphics/Bitmap.cpp
@@ -0,0 +1,1814 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "Bitmap.h"
+#include "Pixel24.h"
+#include "Pixel16.h"
+#include "Pixel8.h"
+#include "Filter3x3.h"
+
+#include "../base/Exception.h"
+#include "../base/Logger.h"
+#include "../base/ObjectCounter.h"
+#include "../base/StringHelper.h"
+#include "../base/MathHelper.h"
+#include "../base/FileHelper.h"
+#include "../base/OSHelper.h"
+
+#include <gdk-pixbuf/gdk-pixbuf.h>
+
+#include <cstring>
+#include <iostream>
+#include <iomanip>
+#include <stdlib.h>
+
+using namespace std;
+
+namespace avg {
+
+template<class Pixel>
+void createTrueColorCopy(Bitmap& destBmp, const Bitmap & srcBmp);
+
+Bitmap::Bitmap(glm::vec2 size, PixelFormat pf, const UTF8String& sName, int stride)
+ : m_Size(size),
+ m_PF(pf),
+ m_pBits(0),
+ m_bOwnsBits(true),
+ m_sName(sName)
+{
+ ObjectCounter::get()->incRef(&typeid(*this));
+ allocBits(stride);
+}
+
+Bitmap::Bitmap(IntPoint size, PixelFormat pf, const UTF8String& sName, int stride)
+ : m_Size(size),
+ m_PF(pf),
+ m_pBits(0),
+ m_bOwnsBits(true),
+ m_sName(sName)
+{
+ ObjectCounter::get()->incRef(&typeid(*this));
+ allocBits(stride);
+}
+
+Bitmap::Bitmap(IntPoint size, PixelFormat pf, unsigned char* pBits,
+ int stride, bool bCopyBits, const UTF8String& sName)
+ : m_Size(size),
+ m_PF(pf),
+ m_pBits(0),
+ m_sName(sName)
+{
+ ObjectCounter::get()->incRef(&typeid(*this));
+ initWithData(pBits, stride, bCopyBits);
+}
+
+Bitmap::Bitmap(const Bitmap& origBmp)
+ : m_Size(origBmp.getSize()),
+ m_PF(origBmp.getPixelFormat()),
+ m_pBits(0),
+ m_bOwnsBits(origBmp.m_bOwnsBits),
+ m_sName(origBmp.getName()+" copy")
+{
+ ObjectCounter::get()->incRef(&typeid(*this));
+ initWithData(const_cast<unsigned char *>(origBmp.getPixels()), origBmp.getStride(),
+ m_bOwnsBits);
+}
+
+Bitmap::Bitmap(const Bitmap& origBmp, bool bOwnsBits)
+ : m_Size(origBmp.getSize()),
+ m_PF(origBmp.getPixelFormat()),
+ m_pBits(0),
+ m_bOwnsBits(bOwnsBits),
+ m_sName(origBmp.getName()+" copy")
+{
+ ObjectCounter::get()->incRef(&typeid(*this));
+ initWithData(const_cast<unsigned char *>(origBmp.getPixels()), origBmp.getStride(),
+ m_bOwnsBits);
+}
+
+// Creates a bitmap that is a rectangle in another bitmap. The pixels are
+// still owned by the original bitmap.
+Bitmap::Bitmap(Bitmap& origBmp, const IntRect& rect)
+ : m_Size(rect.size()),
+ m_PF(origBmp.getPixelFormat()),
+ m_pBits(0),
+ m_bOwnsBits(false)
+{
+ ObjectCounter::get()->incRef(&typeid(*this));
+ AVG_ASSERT(rect.br.x <= origBmp.getSize().x);
+ AVG_ASSERT(rect.br.y <= origBmp.getSize().y);
+ AVG_ASSERT(rect.tl.x >= 0 && rect.tl.y >= 0);
+ AVG_ASSERT(rect.width() > 0 && rect.height() > 0);
+ if (!origBmp.getName().empty()) {
+ m_sName = origBmp.getName()+" part";
+ } else {
+ m_sName = "";
+ }
+ unsigned char * pRegionStart = origBmp.getPixels()
+ + size_t(rect.tl.y)*origBmp.getStride() + rect.tl.x*getBytesPerPixel();
+ initWithData(pRegionStart, origBmp.getStride(), false);
+}
+
+Bitmap::~Bitmap()
+{
+ ObjectCounter::get()->decRef(&typeid(*this));
+ if (m_bOwnsBits) {
+ delete[] m_pBits;
+ m_pBits = 0;
+ }
+}
+
+Bitmap &Bitmap::operator =(const Bitmap& origBmp)
+{
+ if (this != &origBmp) {
+ if (m_bOwnsBits) {
+ delete[] m_pBits;
+ m_pBits = 0;
+ }
+ m_Size = origBmp.getSize();
+ m_PF = origBmp.getPixelFormat();
+ m_bOwnsBits = origBmp.m_bOwnsBits;
+ m_sName = origBmp.getName();
+ initWithData(const_cast<unsigned char *>(origBmp.getPixels()),
+ origBmp.getStride(), m_bOwnsBits);
+ }
+ return *this;
+}
+
+void Bitmap::copyPixels(const Bitmap& origBmp)
+{
+// cerr << "Bitmap::copyPixels(): " << getPixelFormatString(origBmp.getPixelFormat())
+// << "->" << getPixelFormatString(m_PF) << endl;
+ if (&origBmp == this || origBmp.getPixels() == m_pBits) {
+ return;
+ }
+ if (origBmp.getPixelFormat() == m_PF) {
+ const unsigned char * pSrc = origBmp.getPixels();
+ unsigned char * pDest = m_pBits;
+ int height = min(origBmp.getSize().y, m_Size.y);
+ int lineLen = min(origBmp.getLineLen(), getLineLen());
+ int srcStride = origBmp.getStride();
+ for (int y = 0; y < height; ++y) {
+ memcpy(pDest, pSrc, lineLen);
+ pDest += m_Stride;
+ pSrc += srcStride;
+ }
+ } else {
+ switch (origBmp.getPixelFormat()) {
+ case YCbCr422:
+ case YUYV422:
+ case YCbCr411:
+ switch(m_PF) {
+ case B8G8R8X8:
+ YCbCrtoBGR(origBmp);
+ break;
+ case I8:
+ case A8:
+ YCbCrtoI8(origBmp);
+ default: {
+ Bitmap TempBmp(getSize(), B8G8R8X8, "TempColorConversion");
+ TempBmp.YCbCrtoBGR(origBmp);
+ copyPixels(TempBmp);
+ }
+ break;
+ }
+ break;
+ case I16:
+ if (m_PF == I8 || m_PF == A8) {
+ I16toI8(origBmp);
+ } else {
+ Bitmap TempBmp(getSize(), I8, "TempColorConversion");
+ TempBmp.I16toI8(origBmp);
+ copyPixels(TempBmp);
+ }
+ break;
+ case I8:
+ case A8:
+ switch(m_PF) {
+ case I16:
+ I8toI16(origBmp);
+ break;
+ case B8G8R8X8:
+ case B8G8R8A8:
+ case R8G8B8X8:
+ case R8G8B8A8:
+ case B8G8R8:
+ case R8G8B8:
+ I8toRGB(origBmp);
+ break;
+ default:
+ // Unimplemented conversion.
+ AVG_ASSERT(false);
+ }
+ break;
+ case BAYER8_RGGB:
+ case BAYER8_GBRG:
+ case BAYER8_GRBG:
+ case BAYER8_BGGR:
+ switch(m_PF) {
+ case I8:
+ case A8:
+ {
+ // Bayer patterns are saved as I8 bitmaps.
+ // So simply copy that.
+ const unsigned char * pSrc = origBmp.getPixels();
+ unsigned char * pDest = m_pBits;
+ int height = min(origBmp.getSize().y, m_Size.y);
+ int lineLen = min(origBmp.getLineLen(), getLineLen());
+ int srcStride = origBmp.getStride();
+ for (int y = 0; y < height; ++y) {
+ memcpy(pDest, pSrc, lineLen);
+ pDest += m_Stride;
+ pSrc += srcStride;
+ }
+ }
+ break;
+ case B8G8R8X8:
+ case B8G8R8A8:
+ case R8G8B8X8:
+ case R8G8B8A8:
+ BY8toRGBBilinear(origBmp);
+ break;
+ default:
+ // Unimplemented conversion.
+ AVG_ASSERT(false);
+ }
+ break;
+ case R32G32B32A32F:
+ if (getBytesPerPixel() == 4) {
+ FloatRGBAtoByteRGBA(origBmp);
+ } else {
+ cerr << "Can't convert " << origBmp.getPixelFormat() << " to "
+ << getPixelFormat() << endl;
+ AVG_ASSERT(false);
+ }
+ break;
+ default:
+ switch(m_PF) {
+ case R32G32B32A32F:
+ if (origBmp.getBytesPerPixel() == 4) {
+ ByteRGBAtoFloatRGBA(origBmp);
+ } else {
+ cerr << "Can't convert " << origBmp.getPixelFormat() <<
+ " to " << getPixelFormat() << endl;
+ AVG_ASSERT(false);
+ }
+ break;
+ case B8G8R8A8:
+ case B8G8R8X8:
+ case A8B8G8R8:
+ case X8B8G8R8:
+ case R8G8B8A8:
+ case R8G8B8X8:
+ case A8R8G8B8:
+ case X8R8G8B8:
+ createTrueColorCopy<Pixel32>(*this, origBmp);
+ break;
+ case B8G8R8:
+ case R8G8B8:
+ createTrueColorCopy<Pixel24>(*this, origBmp);
+ break;
+ case B5G6R5:
+ case R5G6B5:
+ createTrueColorCopy<Pixel16>(*this, origBmp);
+ break;
+ case I8:
+ case A8:
+ createTrueColorCopy<Pixel8>(*this, origBmp);
+ break;
+ default:
+ // Unimplemented conversion.
+ cerr << "Can't convert " << origBmp.getPixelFormat() << " to " <<
+ getPixelFormat() << endl;
+ AVG_ASSERT(false);
+ }
+ }
+ }
+}
+
+#if defined(__SSE__) || defined(_WIN32)
+ostream& operator<<(ostream& os, const __m64 &val)
+{
+ unsigned char * pVal = (unsigned char *)(&val);
+ for (int i = 0; i < 8; ++i) {
+ os << hex << setw(2) << setfill('0') << int(pVal[i]);
+ if (i%2 == 1) {
+ os << " ";
+ }
+ if (i%4 == 3) {
+ os << " ";
+ }
+ }
+ return os;
+}
+#endif
+
+#define YUV_TO_RGB_UNPACK \
+ /* Input: r, g, b contain 4 words each of the u and v inputs for the color */ \
+ /* channels. ylo and yhi contain 4 words each of the y input. */ \
+\
+ /* duplicate u and v channels and add y \
+ * each of r,g, b in the form [s1(16), s2(16), s3(16), s4(16)] \
+ * first interleave, so tmp is [s1(16), s1(16), s2(16), s2(16)] \
+ * then add y, then interleave again \
+ * then pack with saturation, to get the desired output of \
+ * [s1(8), s1(8), s2(8), s2(8), s3(8), s3(8), s4(8), s4(8)] \
+ */ \
+ tmp = _m_punpckhwd(r, r); \
+ tmp = _m_paddsw(tmp, yhi); \
+ tmp2 = _m_punpcklwd(r, r); \
+ tmp2 = _m_paddsw(tmp2, ylo); \
+ r = _m_packuswb(tmp2, tmp); \
+ \
+ tmp = _m_punpckhwd(g, g); \
+ tmp2 = _m_punpcklwd(g, g); \
+ tmp = _m_paddsw(tmp, yhi); \
+ tmp2 = _m_paddsw(tmp2, ylo); \
+ g = _m_packuswb(tmp2, tmp); \
+ \
+ tmp = _m_punpckhwd(b, b); \
+ tmp2 = _m_punpcklwd(b, b); \
+ tmp = _m_paddsw(tmp, yhi); \
+ tmp2 = _m_paddsw(tmp2, ylo); \
+ b = _m_packuswb(tmp2, tmp); \
+ \
+ /* now we have 8 8-bit r, g and b samples. we want these to be packed \
+ * into 32-bit values. \
+ */ \
+ imm = _mm_set1_pi32(0xFFFFFFFF); \
+ tmp = _m_punpcklbw(b, r); \
+ tmp2 = _m_punpcklbw(g, imm); \
+ *o++ = _m_punpcklbw(tmp, tmp2); \
+ *o++ = _m_punpckhbw(tmp, tmp2); \
+ tmp = _m_punpckhbw(b, r); \
+ tmp2 = _m_punpckhbw(g, imm); \
+ *o++ = _m_punpcklbw(tmp, tmp2); \
+ *o++ = _m_punpckhbw(tmp, tmp2);
+
+
+void Bitmap::copyYUVPixels(const Bitmap& yBmp, const Bitmap& uBmp, const Bitmap& vBmp,
+ bool bJPEG)
+{
+ int height = min(yBmp.getSize().y, m_Size.y);
+ int width = min(yBmp.getSize().x, m_Size.x);
+
+ int yStride = yBmp.getStride();
+ int uStride = uBmp.getStride();
+ int vStride = vBmp.getStride();
+ int destStride = m_Stride/getBytesPerPixel();
+ Pixel32 * pDestLine = (Pixel32*)m_pBits;
+
+#if defined(__SSE__) || defined(_WIN32)
+#pragma pack(16)
+ // Original SSE conversion code taken from liboggplay: oggplay_sse_x86.c
+ int i;
+ const unsigned char * ptry;
+ const unsigned char * ptru;
+ const unsigned char * ptrv;
+
+ register __m64 *o;
+ register __m64 y, ylo, yhi;
+ register __m64 zero, ut, vt, imm;
+ register __m64 r, g, b;
+ register __m64 tmp, tmp2;
+
+ zero = _mm_setzero_si64();
+
+ ptry = yBmp.getPixels();
+ ptru = uBmp.getPixels();
+ ptrv = vBmp.getPixels();
+
+ for (i = 0; i < height; i++) {
+ int j;
+ o = (__m64*)pDestLine;
+ pDestLine += destStride;
+ if (bJPEG) {
+ for (j = 0; j < width; j += 8) {
+ // ylo and yhi contain 4 pixels each
+ y = *(__m64*)(&(ptry[j]));
+ ylo = _m_punpcklbw(y, zero);
+
+ yhi = _m_punpckhbw(y, zero);
+
+ ut = _m_from_int(*(int *)(ptru + j/2));
+ vt = _m_from_int(*(int *)(ptrv + j/2));
+
+ ut = _m_punpcklbw(ut, zero);
+ vt = _m_punpcklbw(vt, zero);
+
+ /* subtract 128 from u and v */
+ imm = _mm_set1_pi16(128);
+ ut = _m_psubw(ut, imm);
+ vt = _m_psubw(vt, imm);
+
+ /* transfer and multiply into r, g, b registers */
+ imm = _mm_set1_pi16(-44);
+ g = _m_pmullw(ut, imm);
+ imm = _mm_set1_pi16(113);
+ b = _m_pmullw(ut, imm);
+ imm = _mm_set1_pi16(179);
+ r = _m_pmullw(vt, imm);
+ imm = _mm_set1_pi16(-91);
+ imm = _m_pmullw(vt, imm);
+ g = _m_paddsw(g, imm);
+
+ /* shift r, g and b registers to the right */
+ r = _m_psrawi(r, 7);
+ g = _m_psrawi(g, 7);
+ b = _m_psrawi(b, 6);
+ YUV_TO_RGB_UNPACK
+
+ }
+ } else {
+ for (j = 0; j < width; j += 8) {
+
+ // y' = (298*(y-16))
+ // ylo and yhi contain 4 pixels each
+ y = *(__m64*)(&(ptry[j]));
+ ylo = _m_punpcklbw(y, zero);
+ imm = _mm_set1_pi16(16);
+ ylo = _m_psubusw(ylo, imm);
+ imm = _mm_set1_pi16(149);
+ ylo = _m_pmullw(ylo, imm);
+ ylo = _mm_srli_pi16(ylo, 7);
+
+ yhi = _m_punpckhbw(y, zero);
+ imm = _mm_set1_pi16(16);
+ yhi = _m_psubusw(yhi, imm);
+ imm = _mm_set1_pi16(149);
+ yhi = _m_pmullw(yhi, imm);
+ yhi = _mm_srli_pi16(yhi, 7);
+
+ ut = _m_from_int(*(int *)(ptru + j/2));
+ vt = _m_from_int(*(int *)(ptrv + j/2));
+
+ ut = _m_punpcklbw(ut, zero);
+ vt = _m_punpcklbw(vt, zero);
+
+ /* subtract 128 from u and v */
+ imm = _mm_set1_pi16(128);
+ ut = _m_psubw(ut, imm);
+ vt = _m_psubw(vt, imm);
+
+ /* transfer and multiply into r, g, b registers */
+ imm = _mm_set1_pi16(-50);
+ g = _m_pmullw(ut, imm);
+ imm = _mm_set1_pi16(129);
+ b = _m_pmullw(ut, imm);
+ imm = _mm_set1_pi16(204);
+ r = _m_pmullw(vt, imm);
+ imm = _mm_set1_pi16(-104);
+ imm = _m_pmullw(vt, imm);
+ g = _m_paddsw(g, imm);
+
+ /* shift r, g and b registers to the right */
+ r = _m_psrawi(r, 7);
+ g = _m_psrawi(g, 7);
+ b = _m_psrawi(b, 6);
+ YUV_TO_RGB_UNPACK
+ }
+ }
+ if (i & 0x1) {
+ ptru += uStride;
+ ptrv += vStride;
+ }
+ ptry += yStride;
+ }
+ _m_empty();
+#pragma pack()
+#else
+ AVG_ASSERT(m_PF==B8G8R8X8);
+ const unsigned char * pYSrc = yBmp.getPixels();
+ const unsigned char * pUSrc = uBmp.getPixels();
+ const unsigned char * pVSrc = vBmp.getPixels();
+
+ for (int y = 0; y < height; ++y) {
+ for (int x = 0; x < width; ++x) {
+ YUVtoBGR32Pixel(pDestLine + x, pYSrc[x], pUSrc[x/2], pVSrc[x/2]);
+ }
+ pDestLine += destStride;
+ pYSrc += yStride;
+ if (y % 2 == 1) {
+ pUSrc += uStride;
+ pVSrc += vStride;
+ }
+ }
+#endif
+}
+
+void Bitmap::save(const UTF8String& sFilename)
+{
+ Bitmap* pTempBmp;
+ switch (m_PF) {
+ case B8G8R8X8:
+ pTempBmp = new Bitmap(m_Size, R8G8B8);
+ for (size_t y = 0; y < size_t(m_Size.y); y++) {
+ unsigned char * pSrcLine = m_pBits + y*m_Stride;
+ unsigned char * pDestLine = pTempBmp->getPixels() +
+ y*pTempBmp->getStride();
+ for (size_t x = 0; x < size_t(m_Size.x); x++) {
+ pDestLine[x*3] = pSrcLine[x*4 + 2];
+ pDestLine[x*3 + 1] = pSrcLine[x*4 + 1];
+ pDestLine[x*3 + 2] = pSrcLine[x*4];
+ }
+ }
+ break;
+ case B8G8R8A8:
+ pTempBmp = new Bitmap(m_Size, R8G8B8A8);
+ for (size_t y = 0; y < size_t(m_Size.y); y++) {
+ unsigned char * pSrcLine = m_pBits+y * m_Stride;
+ unsigned char * pDestLine = pTempBmp->getPixels() +
+ y*pTempBmp->getStride();
+ for (size_t x = 0; x < size_t(m_Size.x); x++) {
+ pDestLine[x*4] = pSrcLine[x*4 + 2];
+ pDestLine[x*4 + 1] = pSrcLine[x*4 + 1];
+ pDestLine[x*4 + 2] = pSrcLine[x*4];
+ pDestLine[x*4 + 3] = pSrcLine[x*4+3];
+ }
+ }
+ break;
+ case B8G8R8:
+ pTempBmp = new Bitmap(m_Size, R8G8B8);
+ for (size_t y = 0; y < size_t(m_Size.y); y++) {
+ unsigned char * pSrcLine = m_pBits+y * m_Stride;
+ unsigned char * pDestLine = pTempBmp->getPixels() +
+ y*pTempBmp->getStride();
+ for (size_t x = 0; x < size_t(m_Size.x); x++) {
+ pDestLine[x*3] = pSrcLine[x*3 + 2];
+ pDestLine[x*3 + 1] = pSrcLine[x*3 + 1];
+ pDestLine[x*3 + 2] = pSrcLine[x*3];
+ }
+ }
+ break;
+ default:
+ if (hasAlpha()) {
+ pTempBmp = new Bitmap(m_Size, R8G8B8A8);
+ } else {
+ pTempBmp = new Bitmap(m_Size, R8G8B8);
+ }
+ pTempBmp->copyPixels(*this);
+ }
+ GdkPixbuf* pPixBuf = gdk_pixbuf_new_from_data(pTempBmp->getPixels(),
+ GDK_COLORSPACE_RGB, pTempBmp->hasAlpha(), 8, m_Size.x, m_Size.y,
+ pTempBmp->getStride(), 0, 0);
+
+ string sExt = getExtension(sFilename);
+ if (sExt == "jpg") {
+ sExt = "jpeg";
+ }
+
+ GError* pError = 0;
+ gboolean bOk = gdk_pixbuf_save(pPixBuf, sFilename.c_str(), sExt.c_str(), &pError,
+ NULL);
+ g_object_unref(pPixBuf);
+ if (!bOk) {
+ string sErr = pError->message;
+ g_error_free(pError);
+ throw Exception(AVG_ERR_FILEIO, sErr);
+ }
+
+ delete pTempBmp;
+}
+
+IntPoint Bitmap::getSize() const
+{
+ return m_Size;
+}
+
+int Bitmap::getStride() const
+{
+ return m_Stride;
+}
+
+PixelFormat Bitmap::getPixelFormat() const
+{
+ return m_PF;
+}
+
+void Bitmap::setPixelFormat(PixelFormat pf)
+{
+ m_PF = pf;
+}
+
+unsigned char * Bitmap::getPixels()
+{
+ return m_pBits;
+}
+
+const unsigned char * Bitmap::getPixels() const
+{
+ return m_pBits;
+}
+
+string Bitmap::getPixelsAsString() const
+{
+ return string((char*)m_pBits, getMemNeeded());
+}
+
+void Bitmap::setPixels(const unsigned char * pPixels)
+{
+ memcpy(m_pBits, pPixels, getMemNeeded());
+}
+
+void Bitmap::setPixelsFromString(const string& sPixels)
+{
+ memcpy(m_pBits, sPixels.c_str(), getMemNeeded());
+}
+
+
+const string& Bitmap::getName() const
+{
+ return m_sName;
+}
+
+bool Bitmap::ownsBits() const
+{
+ return m_bOwnsBits;
+}
+
+int Bitmap::getBytesPerPixel() const
+{
+ return avg::getBytesPerPixel(m_PF);
+}
+
+int Bitmap::getLineLen() const
+{
+ if (m_PF == YCbCr411) {
+ return int(m_Size.x*1.5);
+ } else {
+ return m_Size.x*getBytesPerPixel();
+ }
+}
+
+int Bitmap::getMemNeeded() const
+{
+ // This assumes a positive value for stride.
+ return m_Stride*m_Size.y;
+}
+
+bool Bitmap::hasAlpha() const
+{
+ return pixelFormatHasAlpha(m_PF);
+}
+
+HistogramPtr Bitmap::getHistogram(int stride) const
+{
+ AVG_ASSERT (getBytesPerPixel() == 1);
+ HistogramPtr pHist(new Histogram(256,0));
+ const unsigned char * pSrcLine = m_pBits;
+ for (int y = 0; y < m_Size.y; y += stride) {
+ const unsigned char * pSrc = pSrcLine;
+ for (int x = 0; x < m_Size.x; x += stride) {
+ (*pHist)[(*pSrc)]++;
+ pSrc += stride;
+ }
+ pSrcLine += m_Stride*stride;
+ }
+ return pHist;
+}
+
+void Bitmap::getMinMax(int stride, int& min, int& max) const
+{
+ AVG_ASSERT (getBytesPerPixel() == 1);
+ const unsigned char * pSrcLine = m_pBits;
+ min = 255;
+ max = 0;
+ for (int y = 0; y < m_Size.y; y += stride) {
+ const unsigned char * pSrc = pSrcLine;
+ for (int x = 0; x < m_Size.x; x += stride) {
+ if (*pSrc < min) {
+ min = *pSrc;
+ }
+ if (*pSrc > max) {
+ max = *pSrc;
+ }
+ pSrc += stride;
+ }
+ pSrcLine += m_Stride*stride;
+ }
+}
+
+void Bitmap::setAlpha(const Bitmap& alphaBmp)
+{
+ AVG_ASSERT(hasAlpha());
+ AVG_ASSERT(alphaBmp.getBytesPerPixel() == 1);
+ unsigned char * pLine = m_pBits;
+ const unsigned char * pAlphaLine = alphaBmp.getPixels();
+ for (int y = 0; y < m_Size.y; y++) {
+ unsigned char * pPixel = pLine;
+ const unsigned char * pAlphaPixel = pAlphaLine;
+ for (int x = 0; x < m_Size.x; x++) {
+ pPixel[ALPHAPOS] = *pAlphaPixel;
+ pPixel+=4;
+ pAlphaPixel++;
+ }
+ pLine += m_Stride;
+ pAlphaLine += alphaBmp.getStride();
+ }
+}
+
+Pixel32 Bitmap::getPythonPixel(const glm::vec2& pos)
+{
+ IntPoint intPos(pos);
+ if (intPos.x < 0 || intPos.y < 0 || intPos.x >= m_Size.x || intPos.y >= m_Size.y) {
+ stringstream ss;
+ ss << "Bitmap.getPixel(): intPos " << intPos <<
+ " is out of range. Bitmap size is " << m_Size << endl;
+ throw Exception(AVG_ERR_OUT_OF_RANGE, ss.str());
+ }
+ const unsigned char * pPixel = m_pBits+intPos.y*m_Stride+intPos.x*getBytesPerPixel();
+ switch(getPixelFormat()) {
+ case R8G8B8A8:
+ return Pixel32(pPixel[0], pPixel[1], pPixel[2], pPixel[3]);
+ case R8G8B8X8:
+ return Pixel32(pPixel[0], pPixel[1], pPixel[2], 255);
+ case R8G8B8:
+ return Pixel32(pPixel[0], pPixel[1], pPixel[2]);
+ case B8G8R8A8:
+ return Pixel32(pPixel[2], pPixel[1], pPixel[0], pPixel[3]);
+ case B8G8R8X8:
+ return Pixel32(pPixel[2], pPixel[1], pPixel[0], 255);
+ case B8G8R8:
+ return Pixel32(pPixel[2], pPixel[1], pPixel[0]);
+ case I8:
+ case A8:
+ return Pixel32(pPixel[0], pPixel[0], pPixel[0]);
+ default:
+ cerr << getPixelFormat() << endl;
+ AVG_ASSERT(false);
+ return Pixel32();
+ }
+}
+
+bool Bitmap::operator ==(const Bitmap& otherBmp)
+{
+ // We allow Name, Stride and bOwnsBits to be different here, since we're looking for
+ // equal value only.
+ if (m_Size != otherBmp.m_Size || m_PF != otherBmp.m_PF) {
+ return false;
+ }
+
+ const unsigned char * pSrc = otherBmp.getPixels();
+ unsigned char * pDest = m_pBits;
+ int lineLen = getLineLen();
+ for (int y = 0; y < getSize().y; ++y) {
+ switch(m_PF) {
+ case R8G8B8X8:
+ case B8G8R8X8:
+ for (int x = 0; x < getSize().x; ++x) {
+ const unsigned char * pSrcPixel = pSrc+x*getBytesPerPixel();
+ unsigned char * pDestPixel = pDest+x*getBytesPerPixel();
+ if (*((Pixel24*)(pDestPixel)) != *((Pixel24*)(pSrcPixel))) {
+ return false;
+ }
+ }
+ break;
+ default:
+ if (memcmp(pDest, pSrc, lineLen) != 0) {
+ return false;
+ }
+ }
+ pDest += m_Stride;
+ pSrc += otherBmp.getStride();
+ }
+ return true;
+}
+
+BitmapPtr Bitmap::subtract(const Bitmap& otherBmp)
+{
+ if (m_PF != otherBmp.getPixelFormat()) {
+ throw Exception(AVG_ERR_UNSUPPORTED,
+ string("Bitmap::subtract: pixel formats differ(")
+ + getPixelFormatString(m_PF)+", "
+ + getPixelFormatString(otherBmp.getPixelFormat())+")");
+ }
+ if (m_Size != otherBmp.getSize()) {
+ throw Exception(AVG_ERR_UNSUPPORTED,
+ string("Bitmap::subtract: bitmap sizes differ (this=")
+ + toString(m_Size) + ", other=" + toString(otherBmp.getSize()) + ")");
+ }
+ BitmapPtr pResultBmp = BitmapPtr(new Bitmap(m_Size, m_PF));
+ const unsigned char * pSrcLine1 = otherBmp.getPixels();
+ const unsigned char * pSrcLine2 = m_pBits;
+ unsigned char * pDestLine = pResultBmp->getPixels();
+ int stride = getStride();
+ int lineLen = getLineLen();
+
+ for (int y = 0; y < getSize().y; ++y) {
+ switch(m_PF) {
+ case I16:
+ {
+ const unsigned short * pSrc1 = (const unsigned short *)pSrcLine1;
+ const unsigned short * pSrc2 = (const unsigned short *)pSrcLine2;
+ unsigned short * pDest= (unsigned short *)pDestLine;
+ for (int x=0; x<m_Size.x; ++x) {
+ *pDest = abs(*pSrc1-*pSrc2);
+ pSrc1++;
+ pSrc2++;
+ pDest++;
+ }
+ }
+ break;
+ default:
+ {
+ const unsigned char * pSrc1 = pSrcLine1;
+ const unsigned char * pSrc2 = pSrcLine2;
+ unsigned char * pDest= pDestLine;
+ for (int x=0; x<lineLen; ++x) {
+ *pDest = abs(*pSrc1-*pSrc2);
+ pSrc1++;
+ pSrc2++;
+ pDest++;
+ }
+ }
+ }
+ pSrcLine1 += stride;
+ pSrcLine2 += stride;
+ pDestLine += stride;
+ }
+ return pResultBmp;
+}
+
+void Bitmap::blt(const Bitmap& otherBmp, const IntPoint& pos)
+{
+ AVG_ASSERT(getBytesPerPixel() == 4 || getBytesPerPixel() == 3);
+ AVG_ASSERT(otherBmp.getBytesPerPixel() == 4 || otherBmp.getBytesPerPixel() == 3);
+ if (pos.x < 0 || pos.y < 0) {
+ throw Exception(AVG_ERR_UNSUPPORTED,
+ string("Bitmap::blt: pos < 0 is not supported."));
+ }
+
+ IntRect destRect(pos.x, pos.y, pos.x+otherBmp.getSize().x,
+ pos.y+otherBmp.getSize().y);
+ destRect.intersect(IntRect(IntPoint(0,0), getSize()));
+ for (int y = 0; y < destRect.height(); y++) {
+ unsigned char * pSrcPixel = getPixels()+size_t(pos.y+y)*getStride()
+ +size_t(pos.x*getBytesPerPixel());
+ const unsigned char * pOtherPixel = otherBmp.getPixels()+
+ size_t(y*otherBmp.getStride());
+ if (getBytesPerPixel() == 4) {
+ if (otherBmp.hasAlpha()) {
+ for (int x = 0; x < destRect.width(); x++) {
+ int srcAlpha = 255-pOtherPixel[3];
+ pSrcPixel[0] =
+ (srcAlpha*pSrcPixel[0]+int(pOtherPixel[3])*pOtherPixel[0])/255;
+ pSrcPixel[1] =
+ (srcAlpha*pSrcPixel[1]+int(pOtherPixel[3])*pOtherPixel[1])/255;
+ pSrcPixel[2] =
+ (srcAlpha*pSrcPixel[2]+int(pOtherPixel[3])*pOtherPixel[2])/255;
+ pSrcPixel += 4;
+ pOtherPixel += 4;
+ }
+ } else {
+ for (int x = 0; x < destRect.width(); x++) {
+ *(Pixel32*)pSrcPixel = *(Pixel32*)pOtherPixel;
+ pSrcPixel[3] = 255;
+ pSrcPixel += 4;
+ pOtherPixel += 4;
+ }
+ }
+ } else {
+ if (otherBmp.getBytesPerPixel() == 4) {
+ // Incomplete: Missing alpha support.
+ for (int x = 0; x < destRect.width(); x++) {
+ *(Pixel24*)pSrcPixel = *(Pixel24*)pOtherPixel;
+ pSrcPixel += 3;
+ pOtherPixel += 4;
+ }
+ } else {
+ for (int x = 0; x < destRect.width(); x++) {
+ *(Pixel24*)pSrcPixel = *(Pixel24*)pOtherPixel;
+ pSrcPixel += 3;
+ pOtherPixel += 3;
+ }
+ }
+ }
+ }
+}
+
+float Bitmap::getAvg() const
+{
+ float sum = 0;
+ unsigned char * pSrc = m_pBits;
+ int componentsPerPixel = getBytesPerPixel();
+ for (int y = 0; y < getSize().y; ++y) {
+ switch(m_PF) {
+ case R8G8B8X8:
+ case B8G8R8X8:
+ {
+ Pixel32 * pSrcPixel = (Pixel32 *)pSrc;
+ for (int x = 0; x < m_Size.x; ++x) {
+ sum += pSrcPixel->getR()+pSrcPixel->getG()+pSrcPixel->getB();
+ pSrcPixel++;
+ }
+ componentsPerPixel = 3;
+ }
+ break;
+ case I16:
+ {
+ componentsPerPixel = 1;
+ unsigned short * pSrcPixel = (unsigned short *)pSrc;
+ for (int x = 0; x < m_Size.x; ++x) {
+ sum += *pSrcPixel;
+ pSrcPixel++;
+ }
+ }
+ break;
+ case R8G8B8A8:
+ case B8G8R8A8:
+ {
+ Pixel32 * pSrcPixel = (Pixel32 *)pSrc;
+ for (int x = 0; x < m_Size.x; ++x) {
+ int a = pSrcPixel->getA();
+ if (a > 0) {
+ sum += ((pSrcPixel->getR()+pSrcPixel->getG()+
+ pSrcPixel->getB())*a)/255+pSrcPixel->getA();
+ }
+ pSrcPixel++;
+ }
+ componentsPerPixel = 4;
+ }
+ break;
+ default:
+ {
+ unsigned char * pSrcComponent = pSrc;
+ for (int x = 0; x < getLineLen(); ++x) {
+ sum += *pSrcComponent;
+ pSrcComponent++;
+ }
+ }
+ }
+ pSrc += m_Stride;
+ }
+ sum /= componentsPerPixel;
+ return sum/(getSize().x*getSize().y);
+}
+
+float Bitmap::getChannelAvg(int channel) const
+{
+ AVG_ASSERT(!pixelFormatIsPlanar(m_PF) && !pixelFormatIsBayer(m_PF) && !(m_PF == I16));
+ int bytesPerPixel = getBytesPerPixel();
+ AVG_ASSERT(channel < bytesPerPixel);
+ float sum = 0;
+ unsigned char * pSrcLine = m_pBits;
+ for (int y = 0; y < getSize().y; ++y) {
+ unsigned char * pSrcPixel = pSrcLine;
+ for (int x = 0; x < m_Size.x; ++x) {
+ sum += *(pSrcPixel+channel);
+ pSrcPixel += bytesPerPixel;
+ }
+ pSrcLine += m_Stride;
+ }
+ return sum/(getSize().x*getSize().y);
+}
+
+float Bitmap::getStdDev() const
+{
+ float average = getAvg();
+ float sum = 0;
+
+ unsigned char * pSrc = m_pBits;
+ int componentsPerPixel = getBytesPerPixel();
+ for (int y = 0; y < getSize().y; ++y) {
+ switch(m_PF) {
+ case R8G8B8X8:
+ case B8G8R8X8:
+ {
+ componentsPerPixel = 3;
+ Pixel32 * pSrcPixel = (Pixel32 *)pSrc;
+ for (int x = 0; x < m_Size.x; ++x) {
+ sum += sqr(pSrcPixel->getR()-average);
+ sum += sqr(pSrcPixel->getG()-average);
+ sum += sqr(pSrcPixel->getB()-average);
+ pSrcPixel++;
+ }
+ }
+ break;
+ case R8G8B8A8:
+ case B8G8R8A8:
+ {
+ componentsPerPixel = 4;
+ Pixel32 * pSrcPixel = (Pixel32 *)pSrc;
+ for (int x = 0; x < m_Size.x; ++x) {
+ int a = pSrcPixel->getA();
+ if (a > 0) {
+ sum += sqr((pSrcPixel->getR()*a)/255-average);
+ sum += sqr((pSrcPixel->getG()*a)/255-average);
+ sum += sqr((pSrcPixel->getB()*a)/255-average);
+ sum += sqr(pSrcPixel->getA()-average);
+ }
+ pSrcPixel++;
+ }
+ }
+ break;
+ case I16:
+ {
+ componentsPerPixel = 1;
+ unsigned short * pSrcPixel = (unsigned short *)pSrc;
+ for (int x = 0; x < m_Size.x; ++x) {
+ sum += sqr(*pSrcPixel-average);
+ pSrcPixel++;
+ }
+ }
+ break;
+ default:
+ {
+ unsigned char * pSrcComponent = pSrc;
+ for (int x = 0; x < getLineLen(); ++x) {
+ sum += sqr(*pSrcComponent-average);
+ pSrcComponent++;
+ }
+ }
+ }
+ pSrc += m_Stride;
+ }
+ sum /= componentsPerPixel;
+ sum /= (getSize().x*getSize().y);
+ return sqrt(sum);
+}
+
+void Bitmap::dump(bool bDumpPixels) const
+{
+ cerr << "Bitmap: " << m_sName << endl;
+ cerr << " m_Size: " << m_Size.x << "x" << m_Size.y << endl;
+ cerr << " m_Stride: " << m_Stride << endl;
+ cerr << " m_PF: " << getPixelFormatString(m_PF) << endl;
+ cerr << " m_pBits: " << (void *)m_pBits << endl;
+ cerr << " m_bOwnsBits: " << m_bOwnsBits << endl;
+ IntPoint max;
+ if (bDumpPixels) {
+ max = m_Size;
+ } else {
+ max = IntPoint(16,1);
+ }
+ cerr << " Pixel data: " << endl;
+ for (int y = 0; y < max.y; ++y) {
+ unsigned char * pLine = m_pBits+m_Stride*y;
+ cerr << " ";
+ for (int x = 0; x < max.x; ++x) {
+ if (m_PF == R32G32B32A32F) {
+ float * pPixel = (float*)(pLine+getBytesPerPixel()*x);
+ cerr << "[";
+ for (int i = 0; i < 4; ++i) {
+ cerr << setw(4) << setprecision(2) << pPixel[i] << " ";
+ }
+ cerr << "]";
+ } else {
+ unsigned char * pPixel = pLine+getBytesPerPixel()*x;
+ cerr << "[";
+ for (int i = 0; i < getBytesPerPixel(); ++i) {
+ cerr << hex << setw(2) << (int)(pPixel[i]) << " ";
+ }
+ cerr << "]";
+ }
+ }
+ cerr << endl;
+ }
+ cerr << dec;
+}
+
+int Bitmap::getPreferredStride(int width, PixelFormat pf)
+{
+ return (((width*avg::getBytesPerPixel(pf))-1)/4+1)*4;
+}
+
+void Bitmap::initWithData(unsigned char * pBits, int stride, bool bCopyBits)
+{
+// cerr << "Bitmap::initWithData()" << endl;
+ if (m_PF == YCbCr422) {
+ if (m_Size.x%2 == 1) {
+ AVG_LOG_WARNING("Odd size for YCbCr bitmap.");
+ m_Size.x++;
+ }
+ if (m_Size.y%2 == 1) {
+ AVG_LOG_WARNING("Odd size for YCbCr bitmap.");
+ m_Size.y++;
+ }
+ if (m_Size.x%2 == 1 || m_Size.y%2 == 1) {
+ AVG_LOG_ERROR("Odd size for YCbCr bitmap.");
+ }
+ }
+ if (bCopyBits) {
+ allocBits();
+ if (m_Stride == stride && stride == (m_Size.x*getBytesPerPixel())) {
+ memcpy(m_pBits, pBits, stride*m_Size.y);
+ } else {
+ for (int y = 0; y < m_Size.y; ++y) {
+ memcpy(m_pBits+m_Stride*y, pBits+stride*y, m_Stride);
+ }
+ }
+ m_bOwnsBits = true;
+ } else {
+ m_pBits = pBits;
+ m_Stride = stride;
+ m_bOwnsBits = false;
+ }
+}
+
+void Bitmap::allocBits(int stride)
+{
+ AVG_ASSERT(!m_pBits);
+ AVG_ASSERT(!pixelFormatIsPlanar(m_PF));
+ AVG_ASSERT(m_Size.x > 0 && m_Size.y > 0);
+// cerr << "Bitmap::allocBits():" << m_Size << endl;
+ if (stride == 0) {
+ m_Stride = getPreferredStride(m_Size.x, m_PF);
+ } else {
+ m_Stride = stride;
+ }
+ if (m_PF == YCbCr422) {
+ if (m_Size.x%2 == 1) {
+ AVG_LOG_WARNING("Odd width for YCbCr bitmap.");
+ m_Size.x++;
+ }
+ if (m_Size.y%2 == 1) {
+ AVG_LOG_WARNING("Odd height for YCbCr bitmap.");
+ m_Size.y++;
+ }
+ //XXX: We allocate more than nessesary here because ffmpeg seems to
+ // overwrite memory after the bits - probably during yuv conversion.
+ // Yuck.
+ m_pBits = new unsigned char[size_t(m_Stride+1)*(m_Size.y+1)];
+ } else {
+ m_pBits = new unsigned char[size_t(m_Stride)*m_Size.y];
+ }
+}
+
+void YUYV422toBGR32Line(const unsigned char* pSrcLine, Pixel32* pDestLine, int width)
+{
+ Pixel32 * pDestPixel = pDestLine;
+
+ // We need the previous and next values to interpolate between the
+ // sampled u and v values.
+ int v = *(pSrcLine+3);
+ int v0; // Previous v
+ int u;
+ int u1; // Next u;
+ const unsigned char * pSrcPixels = pSrcLine;
+
+ for (int x = 0; x < width/2-1; x++) {
+ // Two pixels at a time.
+ // Source format is YUYV.
+ u = pSrcPixels[1];
+ v0 = v;
+ v = pSrcPixels[3];
+ u1 = pSrcPixels[5];
+
+ YUVtoBGR32Pixel(pDestPixel, pSrcPixels[0], u, (v0+v)/2);
+ YUVtoBGR32Pixel(pDestPixel+1, pSrcPixels[2], (u+u1)/2, v);
+
+ pSrcPixels+=4;
+ pDestPixel+=2;
+ }
+ // Last pixels.
+ u = pSrcPixels[1];
+ v0 = v;
+ v = pSrcPixels[3];
+ YUVtoBGR32Pixel(pDestPixel, pSrcPixels[0], u, v0/2+v/2);
+ YUVtoBGR32Pixel(pDestPixel+1, pSrcPixels[2], u, v);
+}
+
+void UYVY422toBGR32Line(const unsigned char* pSrcLine, Pixel32* pDestLine, int width)
+{
+ Pixel32 * pDestPixel = pDestLine;
+
+ // We need the previous and next values to interpolate between the
+ // sampled u and v values.
+ int v = *(pSrcLine+2);
+ int v0; // Previous v
+ int u;
+ int u1; // Next u;
+ const unsigned char * pSrcPixels = pSrcLine;
+
+ for (int x = 0; x < width/2-1; x++) {
+ // Two pixels at a time.
+ // Source format is UYVY.
+ u = pSrcPixels[0];
+ v0 = v;
+ v = pSrcPixels[2];
+ u1 = pSrcPixels[4];
+
+ YUVtoBGR32Pixel(pDestPixel, pSrcPixels[1], u, (v0+v)/2);
+ YUVtoBGR32Pixel(pDestPixel+1, pSrcPixels[3], (u+u1)/2, v);
+
+ pSrcPixels+=4;
+ pDestPixel+=2;
+ }
+ // Last pixels.
+ u = pSrcPixels[0];
+ v0 = v;
+ v = pSrcPixels[2];
+ YUVtoBGR32Pixel(pDestPixel, pSrcPixels[1], u, v0/2+v/2);
+ YUVtoBGR32Pixel(pDestPixel+1, pSrcPixels[3], u, v);
+}
+
+void YUV411toBGR32Line(const unsigned char* pSrcLine, Pixel32* pDestLine, int width)
+{
+ Pixel32 * pDestPixel = pDestLine;
+
+ // We need the previous and next values to interpolate between the
+ // sampled u and v values.
+ int v = *(pSrcLine+3);
+ int v0; // Previous v
+ int v1; // Next v;
+ int u;
+ int u1; // Next u;
+ const unsigned char * pSrcPixels = pSrcLine;
+
+ for (int x = 0; x < width/4; x++) {
+ // Four pixels at a time.
+ // Source format is UYYVYY.
+ u = pSrcPixels[0];
+ v0 = v;
+ v = pSrcPixels[3];
+
+ if (x < width/4-1) {
+ u1 = pSrcPixels[6];
+ v1 = pSrcPixels[9];
+ } else {
+ u1 = u;
+ v1 = v;
+ }
+
+ YUVtoBGR32Pixel(pDestPixel, pSrcPixels[1], u, v0/2+v/2);
+ YUVtoBGR32Pixel(pDestPixel+1, pSrcPixels[2], (u*3)/4+u1/4, v0/4+(v*3)/4);
+ YUVtoBGR32Pixel(pDestPixel+2, pSrcPixels[4], u/2+u1/2, v);
+ YUVtoBGR32Pixel(pDestPixel+3, pSrcPixels[5], u/4+(u1*3)/4, (v*3)/4+v1/4);
+
+ pSrcPixels+=6;
+ pDestPixel+=4;
+ }
+}
+
+void Bitmap::YCbCrtoBGR(const Bitmap& origBmp)
+{
+ AVG_ASSERT(m_PF==B8G8R8X8);
+ const unsigned char * pSrc = origBmp.getPixels();
+ Pixel32 * pDest = (Pixel32*)m_pBits;
+ int height = min(origBmp.getSize().y, m_Size.y);
+ int width = min(origBmp.getSize().x, m_Size.x);
+ int StrideInPixels = m_Stride/getBytesPerPixel();
+ switch(origBmp.m_PF) {
+ case YCbCr422:
+ for (int y = 0; y < height; ++y) {
+ UYVY422toBGR32Line(pSrc, pDest, width);
+ pDest += StrideInPixels;
+ pSrc += origBmp.getStride();
+ }
+ break;
+ case YUYV422:
+ for (int y = 0; y < height; ++y) {
+ YUYV422toBGR32Line(pSrc, pDest, width);
+ pDest += StrideInPixels;
+ pSrc += origBmp.getStride();
+ }
+ break;
+ case YCbCr411:
+ for (int y = 0; y < height; ++y) {
+ YUV411toBGR32Line(pSrc, pDest, width);
+ pDest += StrideInPixels;
+ pSrc += origBmp.getStride();
+ }
+ break;
+ default:
+ // This routine shouldn't be called with other pixel formats.
+ AVG_ASSERT(false);
+ }
+}
+
+void YUYV422toI8Line(const unsigned char* pSrcLine, unsigned char* pDestLine, int width)
+{
+ const unsigned char * pSrc = pSrcLine;
+ unsigned char * pDest = pDestLine;
+ for (int x = 0; x < width; x++) {
+ *pDest = *pSrc;
+ pDest++;
+ pSrc+=2;
+ }
+}
+
+void YUV411toI8Line(const unsigned char* pSrcLine, unsigned char* pDestLine, int width)
+{
+ const unsigned char * pSrc = pSrcLine;
+ unsigned char * pDest = pDestLine;
+ for (int x = 0; x < width/2; x++) {
+ *pDest++ = *pSrc++;
+ *pDest++ = *pSrc++;
+ pSrc++;
+ }
+}
+
+void Bitmap::YCbCrtoI8(const Bitmap& origBmp)
+{
+ AVG_ASSERT(origBmp.getBytesPerPixel() == 1);
+ const unsigned char * pSrc = origBmp.getPixels();
+ unsigned char * pDest = m_pBits;
+ int height = min(origBmp.getSize().y, m_Size.y);
+ int width = min(origBmp.getSize().x, m_Size.x);
+ switch(origBmp.m_PF) {
+ case YCbCr422:
+ for (int y = 0; y < height; ++y) {
+ // src shifted by one byte to account for UYVY to YUYV
+ // difference in pixel order.
+ YUYV422toI8Line(pSrc+1, pDest, width);
+ pDest += m_Stride;
+ pSrc += origBmp.getStride();
+ }
+ break;
+ case YUYV422:
+ for (int y = 0; y < height; ++y) {
+ YUYV422toI8Line(pSrc, pDest, width);
+ pDest += m_Stride;
+ pSrc += origBmp.getStride();
+ }
+ break;
+ case YCbCr411:
+ for (int y = 0; y < height; ++y) {
+ YUV411toI8Line(pSrc, pDest, width);
+ pDest += m_Stride;
+ pSrc += origBmp.getStride();
+ }
+ break;
+ default:
+ // This routine shouldn't be called with other pixel formats.
+ AVG_ASSERT(false);
+ }
+}
+
+void Bitmap::I16toI8(const Bitmap& origBmp)
+{
+ AVG_ASSERT(getBytesPerPixel() == 1);
+ AVG_ASSERT(origBmp.getPixelFormat() == I16);
+ const unsigned short * pSrc = (const unsigned short *)origBmp.getPixels();
+ unsigned char * pDest = m_pBits;
+ int height = min(origBmp.getSize().y, m_Size.y);
+ int width = min(origBmp.getSize().x, m_Size.x);
+ int srcStrideInPixels = origBmp.getStride()/origBmp.getBytesPerPixel();
+ for (int y = 0; y < height; ++y) {
+ const unsigned short * pSrcPixel = pSrc;
+ unsigned char * pDestPixel = pDest;
+ for (int x=0; x<width; ++x) {
+ *pDestPixel++ = *pSrcPixel++ >> 8;
+ }
+ pDest += m_Stride;
+ pSrc += srcStrideInPixels;
+ }
+}
+
+void Bitmap::I8toI16(const Bitmap& origBmp)
+{
+ AVG_ASSERT(m_PF == I16);
+ AVG_ASSERT(origBmp.getBytesPerPixel() == 1);
+ const unsigned char * pSrc = origBmp.getPixels();
+ unsigned short * pDest = (unsigned short *)m_pBits;
+ int height = min(origBmp.getSize().y, m_Size.y);
+ int width = min(origBmp.getSize().x, m_Size.x);
+ int destStrideInPixels = m_Stride/getBytesPerPixel();
+ for (int y=0; y<height; ++y) {
+ const unsigned char * pSrcPixel = pSrc;
+ unsigned short * pDestPixel = pDest;
+ for (int x=0; x<width; ++x) {
+ *pDestPixel++ = *pSrcPixel++ << 8;
+ }
+ pDest += destStrideInPixels;
+ pSrc += origBmp.getStride();
+ }
+}
+
+void Bitmap::I8toRGB(const Bitmap& origBmp)
+{
+ AVG_ASSERT(getBytesPerPixel() == 4 || getBytesPerPixel() == 3);
+ AVG_ASSERT(origBmp.getBytesPerPixel() == 1);
+ const unsigned char * pSrc = origBmp.getPixels();
+ int height = min(origBmp.getSize().y, m_Size.y);
+ int width = min(origBmp.getSize().x, m_Size.x);
+ if (getBytesPerPixel() == 4) {
+ unsigned int * pDest = (unsigned int *)m_pBits;
+ int destStrideInPixels = m_Stride/getBytesPerPixel();
+ for (int y = 0; y < height; ++y) {
+ const unsigned char * pSrcPixel = pSrc;
+ unsigned int * pDestPixel = pDest;
+ for (int x = 0; x < width; ++x) {
+ *pDestPixel = (((((255 << 8)+(*pSrcPixel)) << 8)+
+ *pSrcPixel) << 8) +(*pSrcPixel);
+ pDestPixel ++;
+ pSrcPixel++;
+ }
+ pDest += destStrideInPixels;
+ pSrc += origBmp.getStride();
+ }
+ } else {
+ unsigned char * pDest = m_pBits;
+ for (int y = 0; y < height; ++y) {
+ const unsigned char * pSrcPixel = pSrc;
+ unsigned char * pDestPixel = pDest;
+ for (int x = 0; x < width; ++x) {
+ *pDestPixel++ = *pSrcPixel;
+ *pDestPixel++ = *pSrcPixel;
+ *pDestPixel++ = *pSrcPixel;
+ pSrcPixel++;
+ }
+ pDest += getStride();
+ pSrc += origBmp.getStride();
+ }
+ }
+}
+
+void Bitmap::ByteRGBAtoFloatRGBA(const Bitmap& origBmp)
+{
+ AVG_ASSERT(getPixelFormat() == R32G32B32A32F);
+ AVG_ASSERT(origBmp.getBytesPerPixel() == 4);
+ const unsigned char * pSrc = origBmp.getPixels();
+ int height = min(origBmp.getSize().y, m_Size.y);
+ int width = min(origBmp.getSize().x, m_Size.x);
+ float * pDest = (float *)m_pBits;
+ for (int y = 0; y < height; ++y) {
+ const unsigned char * pSrcPixel = pSrc;
+ float * pDestPixel = pDest;
+ for (int x = 0; x < width*4; ++x) {
+ *pDestPixel = float(*pSrcPixel)/255;
+ pDestPixel ++;
+ pSrcPixel++;
+ }
+ pDest += m_Stride/sizeof(float);
+ pSrc += origBmp.getStride();
+ }
+}
+
+void Bitmap::FloatRGBAtoByteRGBA(const Bitmap& origBmp)
+{
+ AVG_ASSERT(getBytesPerPixel() == 4);
+ AVG_ASSERT(origBmp.getPixelFormat() == R32G32B32A32F);
+ const float * pSrc = (const float *)origBmp.getPixels();
+ int height = min(origBmp.getSize().y, m_Size.y);
+ int width = min(origBmp.getSize().x, m_Size.x);
+ unsigned char * pDest = m_pBits;
+ for (int y = 0; y < height; ++y) {
+ const float * pSrcPixel = pSrc;
+ unsigned char * pDestPixel = pDest;
+ for (int x = 0; x < width*4; ++x) {
+ *pDestPixel = (unsigned char)(*pSrcPixel*255+0.5);
+ pDestPixel++;
+ pSrcPixel++;
+ }
+ pDest += m_Stride;
+ pSrc += origBmp.getStride()/sizeof(float);
+ }
+}
+
+/*
+// Nearest Neighbour Bayer Pattern de-mosaicking
+// Code has been taken and adapted from libdc1394 Bayer conversion
+// TODO: adapt it for RGB24, not just for RGB32
+// TODO: add more CFA patterns (now only the GBRG is defined and used)
+void Bitmap::BY8toRGBNearest(const Bitmap& origBmp)
+{
+ AVG_ASSERT(getBytesPerPixel() == 4);
+ AVG_ASSERT(origBmp.getPixelFormat() == BAYER8_GBRG);
+
+ int height = min(origBmp.getSize().y, m_Size.y);
+ int width = min(origBmp.getSize().x, m_Size.x);
+
+ const int srcStride = width;
+ const int destStride = 4 * width;
+ int width = width;
+ int height = height;
+
+ // CFA Pattern selection: BGGR: blue=-1, swg=0; GRBG: blue=1, swg=1
+ // Assuming GBRG
+ int blue = 1;
+ int greenFirst = 1;
+
+ const unsigned char *pSrcPixel = origBmp.getPixels();
+ unsigned char *pDestPixel = (unsigned char *) getPixels();
+
+ pDestPixel += 1;
+ width -= 1;
+ height -= 1;
+
+ while (--height) {
+
+ const unsigned char *pSrcEndBoundary = pSrcPixel + width;
+
+ if (greenFirst) {
+ pDestPixel[-blue] = pSrcPixel[1];
+ pDestPixel[0] = pSrcPixel[srcStride + 1];
+ pDestPixel[blue] = pSrcPixel[srcStride];
+ pDestPixel[2] = 255; // Alpha channel
+ ++pSrcPixel;
+ pDestPixel += 4;
+ }
+
+ if (blue > 0) {
+ while (pSrcPixel <= pSrcEndBoundary - 2) {
+ pDestPixel[-1] = pSrcPixel[0];
+ pDestPixel[0] = pSrcPixel[1];
+ pDestPixel[1] = pSrcPixel[srcStride + 1];
+ pDestPixel[2] = 255; // Alpha channel
+
+ pDestPixel[3] = pSrcPixel[2];
+ pDestPixel[4] = pSrcPixel[srcStride + 2];
+ pDestPixel[5] = pSrcPixel[srcStride + 1];
+ pDestPixel[6] = 255; // Alpha channel
+
+ pSrcPixel += 2;
+ pDestPixel += 8;
+ }
+ } else {
+ while (pSrcPixel <= pSrcEndBoundary - 2) {
+ pDestPixel[1] = pSrcPixel[0];
+ pDestPixel[0] = pSrcPixel[1];
+ pDestPixel[-1] = pSrcPixel[srcStride + 1];
+
+ pDestPixel[6] = 255; // Alpha channel
+ pDestPixel[5] = pSrcPixel[2];
+ pDestPixel[4] = pSrcPixel[srcStride + 2];
+ pDestPixel[3] = pSrcPixel[srcStride + 1];
+ pDestPixel[2] = 255; // Alpha channel
+
+ pSrcPixel += 2;
+ pDestPixel += 8;
+ }
+ }
+
+ if (pSrcPixel < pSrcEndBoundary) {
+ pDestPixel[-blue] = pSrcPixel[0];
+ pDestPixel[0] = pSrcPixel[1];
+ pDestPixel[blue] = pSrcPixel[srcStride + 1];
+ pDestPixel[2] = 255; // Alpha channel
+ ++pSrcPixel;
+ pDestPixel += 4;
+ }
+
+ pSrcPixel -= width;
+ pDestPixel -= width * 4;
+
+ blue = -blue;
+ greenFirst = !greenFirst;
+
+ pSrcPixel += srcStride;
+ pDestPixel += destStride;
+ }
+}
+*/
+
+// Bilinear Bayer Pattern de-mosaicking
+// Code has been taken and adapted from libdc1394 Bayer conversion
+// Original source is OpenCV Bayer pattern decoding
+// TODO: adapt it for RGB24, not just for RGB32
+void Bitmap::BY8toRGBBilinear(const Bitmap& origBmp)
+{
+ AVG_ASSERT(getBytesPerPixel() == 4);
+ AVG_ASSERT(pixelFormatIsBayer(origBmp.getPixelFormat()));
+
+ int height = min(origBmp.getSize().y, m_Size.y);
+ int width = min(origBmp.getSize().x, m_Size.x);
+
+ const int srcStride = width;
+ const int doubleSrcStride = srcStride * 2;
+ const int destStride = 4 * width;
+
+ // CFA Pattern selection
+ PixelFormat pf = origBmp.getPixelFormat();
+ int blue;
+ int greenFirst;
+ if (pf == BAYER8_BGGR || pf == BAYER8_GBRG) {
+ blue = -1;
+ } else {
+ blue = 1;
+ }
+
+ if (pf == BAYER8_GBRG || pf == BAYER8_GRBG) {
+ greenFirst = 1;
+ } else {
+ greenFirst = 0;
+ }
+
+ const unsigned char *pSrcPixel = origBmp.getPixels();
+ unsigned char *pDestPixel = (unsigned char *) getPixels();
+
+ pDestPixel += destStride + 4 + 1;
+ height -= 2;
+ width -= 2;
+
+ while (height--) {
+ int t0, t1;
+ const unsigned char *pSrcEndBoundary = pSrcPixel + width;
+
+ if (greenFirst) {
+ t0 = (pSrcPixel[1] + pSrcPixel[doubleSrcStride + 1] + 1) >> 1;
+ t1 = (pSrcPixel[srcStride] + pSrcPixel[srcStride + 2] + 1) >> 1;
+ pDestPixel[-blue] = (unsigned char) t0;
+ pDestPixel[0] = pSrcPixel[srcStride + 1];
+ pDestPixel[blue] = (unsigned char) t1;
+ pDestPixel[2] = 255; // Alpha channel
+ ++pSrcPixel;
+ pDestPixel += 4;
+ }
+
+ if (blue > 0) {
+ while (pSrcPixel <= pSrcEndBoundary - 2) {
+ t0 = (pSrcPixel[0] + pSrcPixel[2] + pSrcPixel[doubleSrcStride] +
+ pSrcPixel[doubleSrcStride + 2] + 2) >> 2;
+ t1 = (pSrcPixel[1] + pSrcPixel[srcStride] +
+ pSrcPixel[srcStride + 2] + pSrcPixel[doubleSrcStride + 1] +
+ 2) >> 2;
+ pDestPixel[-1] = (unsigned char) t0;
+ pDestPixel[0] = (unsigned char) t1;
+ pDestPixel[1] = pSrcPixel[srcStride + 1];
+ pDestPixel[2] = 255; // Alpha channel
+
+ t0 = (pSrcPixel[2] + pSrcPixel[doubleSrcStride + 2] + 1) >> 1;
+ t1 = (pSrcPixel[srcStride + 1] + pSrcPixel[srcStride + 3] +
+ 1) >> 1;
+ pDestPixel[3] = (unsigned char) t0;
+ pDestPixel[4] = pSrcPixel[srcStride + 2];
+ pDestPixel[5] = (unsigned char) t1;
+ pDestPixel[6] = 255; // Alpha channel
+
+ pSrcPixel += 2;
+ pDestPixel += 8;
+ }
+ } else {
+ while (pSrcPixel <= pSrcEndBoundary - 2) {
+ t0 = (pSrcPixel[0] + pSrcPixel[2] + pSrcPixel[doubleSrcStride] +
+ pSrcPixel[doubleSrcStride + 2] + 2) >> 2;
+ t1 = (pSrcPixel[1] + pSrcPixel[srcStride] +
+ pSrcPixel[srcStride + 2] + pSrcPixel[doubleSrcStride + 1] +
+ 2) >> 2;
+ pDestPixel[1] = (unsigned char) t0;
+ pDestPixel[0] = (unsigned char) t1;
+ pDestPixel[-1] = pSrcPixel[srcStride + 1];
+ pDestPixel[2] = 255; // Alpha channel
+
+ t0 = (pSrcPixel[2] + pSrcPixel[doubleSrcStride + 2] + 1) >> 1;
+ t1 = (pSrcPixel[srcStride + 1] + pSrcPixel[srcStride + 3] +
+ 1) >> 1;
+ pDestPixel[5] = (unsigned char) t0;
+ pDestPixel[4] = pSrcPixel[srcStride + 2];
+ pDestPixel[3] = (unsigned char) t1;
+ pDestPixel[6] = 255; // Alpha channel
+
+ pSrcPixel += 2;
+ pDestPixel += 8;
+ }
+ }
+
+ if (pSrcPixel < pSrcEndBoundary) {
+ t0 = (pSrcPixel[0] + pSrcPixel[2] + pSrcPixel[doubleSrcStride] +
+ pSrcPixel[doubleSrcStride + 2] + 2) >> 2;
+ t1 = (pSrcPixel[1] + pSrcPixel[srcStride] +
+ pSrcPixel[srcStride + 2] + pSrcPixel[doubleSrcStride + 1] +
+ 2) >> 2;
+ pDestPixel[-blue] = (unsigned char) t0;
+ pDestPixel[0] = (unsigned char) t1;
+ pDestPixel[blue] = pSrcPixel[srcStride + 1];
+ pDestPixel[2] = 255; // Alpha channel
+ pSrcPixel++;
+ pDestPixel += 4;
+ }
+
+ pSrcPixel -= width;
+ pDestPixel -= width * 4;
+
+ blue = -blue;
+ greenFirst = !greenFirst;
+
+ pSrcPixel += srcStride;
+ pDestPixel += destStride;
+ }
+}
+
+template<class DESTPIXEL, class SRCPIXEL>
+void createTrueColorCopy(Bitmap& destBmp, const Bitmap& srcBmp)
+{
+ SRCPIXEL * pSrcLine = (SRCPIXEL*) srcBmp.getPixels();
+ DESTPIXEL * pDestLine = (DESTPIXEL*) destBmp.getPixels();
+ int height = min(srcBmp.getSize().y, destBmp.getSize().y);
+ int width = min(srcBmp.getSize().x, destBmp.getSize().x);
+ for (int y = 0; y < height; ++y) {
+ SRCPIXEL * pSrcPixel = pSrcLine;
+ DESTPIXEL * pDestPixel = pDestLine;
+ for (int x = 0; x < width; ++x) {
+ *pDestPixel = *pSrcPixel;
+ ++pSrcPixel;
+ ++pDestPixel;
+ }
+ pSrcLine = (SRCPIXEL *)((unsigned char *)pSrcLine + srcBmp.getStride());
+ pDestLine = (DESTPIXEL *)((unsigned char *)pDestLine + destBmp.getStride());
+ }
+}
+
+template<>
+void createTrueColorCopy<Pixel32, Pixel8>(Bitmap& destBmp, const Bitmap& srcBmp)
+{
+ const unsigned char * pSrcLine = srcBmp.getPixels();
+ unsigned char * pDestLine = destBmp.getPixels();
+ int height = min(srcBmp.getSize().y, destBmp.getSize().y);
+ int width = min(srcBmp.getSize().x, destBmp.getSize().x);
+ int srcStride = srcBmp.getStride();
+ int destStride = destBmp.getStride();
+ for (int y = 0; y < height; ++y) {
+ const unsigned char * pSrcPixel = pSrcLine;
+ unsigned char * pDestPixel = pDestLine;
+ for (int x = 0; x < width; ++x) {
+ pDestPixel[0] =
+ pDestPixel[1] =
+ pDestPixel[2] = *pSrcPixel;
+ pDestPixel[3] = 255;
+ ++pSrcPixel;
+ pDestPixel+=4;
+ }
+ pSrcLine = pSrcLine + srcStride;
+ pDestLine = pDestLine + destStride;
+ }
+}
+
+template<>
+void createTrueColorCopy<Pixel8, Pixel32>(Bitmap& destBmp, const Bitmap& srcBmp)
+{
+ const unsigned char * pSrcLine = srcBmp.getPixels();
+ unsigned char * pDestLine = destBmp.getPixels();
+ int height = min(srcBmp.getSize().y, destBmp.getSize().y);
+ int width = min(srcBmp.getSize().x, destBmp.getSize().x);
+ int srcStride = srcBmp.getStride();
+ int destStride = destBmp.getStride();
+ bool bRedFirst = (srcBmp.getPixelFormat() == R8G8B8A8) ||
+ (srcBmp.getPixelFormat() == R8G8B8X8);
+ for (int y = 0; y<height; ++y) {
+ const unsigned char * pSrcPixel = pSrcLine;
+ unsigned char * pDestPixel = pDestLine;
+ if (bRedFirst) {
+ for (int x = 0; x < width; ++x) {
+ *pDestPixel = ((pSrcPixel[0]*54+pSrcPixel[1]*183+pSrcPixel[2]*19)/256);
+ pSrcPixel+=4;
+ ++pDestPixel;
+ }
+ } else {
+ for (int x = 0; x < width; ++x) {
+ *pDestPixel = ((pSrcPixel[0]*19+pSrcPixel[1]*183+pSrcPixel[2]*54)/256);
+ pSrcPixel+=4;
+ ++pDestPixel;
+ }
+ }
+ pSrcLine = pSrcLine + srcStride;
+ pDestLine = pDestLine + destStride;
+ }
+}
+
+
+template<class PIXEL>
+void createTrueColorCopy(Bitmap& destBmp, const Bitmap& srcBmp)
+{
+ switch(srcBmp.getPixelFormat()) {
+ case B8G8R8A8:
+ case B8G8R8X8:
+ case A8B8G8R8:
+ case X8B8G8R8:
+ case R8G8B8A8:
+ case R8G8B8X8:
+ case A8R8G8B8:
+ case X8R8G8B8:
+ createTrueColorCopy<PIXEL, Pixel32>(destBmp, srcBmp);
+ break;
+ case B8G8R8:
+ case R8G8B8:
+ createTrueColorCopy<PIXEL, Pixel24>(destBmp, srcBmp);
+ break;
+ case B5G6R5:
+ case R5G6B5:
+ createTrueColorCopy<PIXEL, Pixel16>(destBmp, srcBmp);
+ break;
+ case I8:
+ case A8:
+ case BAYER8_RGGB:
+ case BAYER8_GBRG:
+ case BAYER8_GRBG:
+ case BAYER8_BGGR:
+ createTrueColorCopy<PIXEL, Pixel8>(destBmp, srcBmp);
+ break;
+ default:
+ // Unimplemented conversion.
+ AVG_ASSERT(false);
+ }
+}
+
+};
diff --git a/src/graphics/Bitmap.h b/src/graphics/Bitmap.h
new file mode 100644
index 0000000..8a46a99
--- /dev/null
+++ b/src/graphics/Bitmap.h
@@ -0,0 +1,186 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _Bitmap_H_
+#define _Bitmap_H_
+
+#include "../api.h"
+#include "Pixel32.h"
+#include "PixelFormat.h"
+
+#include "../base/Rect.h"
+#include "../base/GLMHelper.h"
+#include "../base/UTF8String.h"
+
+#include <boost/shared_ptr.hpp>
+
+#if defined(__SSE__) || defined(_WIN32)
+#include <xmmintrin.h>
+#endif
+
+#include <stdlib.h>
+#include <string>
+#include <vector>
+#include <algorithm>
+#include <iostream>
+
+namespace avg {
+
+typedef std::vector<int> Histogram;
+typedef boost::shared_ptr<Histogram> HistogramPtr;
+
+class Bitmap;
+typedef boost::shared_ptr<Bitmap> BitmapPtr;
+
+class AVG_API Bitmap
+{
+public:
+ Bitmap(glm::vec2 size, PixelFormat pf, const UTF8String& sName="", int stride=0);
+ Bitmap(IntPoint size, PixelFormat pf, const UTF8String& sName="", int stride=0);
+ Bitmap(IntPoint size, PixelFormat pf, unsigned char * pBits,
+ int stride, bool bCopyBits, const UTF8String& sName="");
+ Bitmap(const Bitmap& origBmp);
+ Bitmap(const Bitmap& origBmp, bool bOwnsBits);
+ Bitmap(Bitmap& origBmp, const IntRect& rect);
+ virtual ~Bitmap();
+
+ Bitmap &operator =(const Bitmap & origBmp);
+
+ // Does pixel format conversion if nessesary.
+ void copyPixels(const Bitmap& origBmp);
+ void copyYUVPixels(const Bitmap& yBmp, const Bitmap& uBmp, const Bitmap& vBmp,
+ bool bJPEG);
+ void save(const UTF8String& sName);
+
+ IntPoint getSize() const;
+ int getStride() const;
+ PixelFormat getPixelFormat() const;
+ void setPixelFormat(PixelFormat pf);
+ unsigned char* getPixels();
+ const unsigned char* getPixels() const;
+ std::string getPixelsAsString() const;
+ void setPixels(const unsigned char* pPixels);
+ void setPixelsFromString(const std::string& sPixels);
+ bool ownsBits() const;
+ const std::string& getName() const;
+ int getBytesPerPixel() const;
+ int getLineLen() const;
+ int getMemNeeded() const;
+ bool hasAlpha() const;
+ HistogramPtr getHistogram(int stride = 1) const;
+ void getMinMax(int stride, int& min, int& max) const;
+ void setAlpha(const Bitmap& alphaBmp);
+
+ Pixel32 getPythonPixel(const glm::vec2& pos);
+ template<class PIXEL>
+ void setPixel(const IntPoint& p, PIXEL color);
+ template<class PIXEL>
+ void drawLine(IntPoint p0, IntPoint p1, PIXEL color);
+
+ BitmapPtr subtract(const Bitmap& pOtherBmp);
+ void blt(const Bitmap& otherBmp, const IntPoint& pos);
+ float getAvg() const;
+ float getChannelAvg(int channel) const;
+ float getStdDev() const;
+
+ bool operator ==(const Bitmap& otherBmp);
+ void dump(bool bDumpPixels=false) const;
+
+ static int getPreferredStride(int width, PixelFormat pf);
+
+private:
+ void initWithData(unsigned char* pBits, int stride, bool bCopyBits);
+ void allocBits(int stride=0);
+ void YCbCrtoBGR(const Bitmap& origBmp);
+ void YCbCrtoI8(const Bitmap& origBmp);
+ void I8toI16(const Bitmap& origBmp);
+ void I8toRGB(const Bitmap& origBmp);
+ void I16toI8(const Bitmap& origBmp);
+ void BGRtoB5G6R5(const Bitmap& origBmp);
+ void ByteRGBAtoFloatRGBA(const Bitmap& origBmp);
+ void FloatRGBAtoByteRGBA(const Bitmap& origBmp);
+ void BY8toRGBNearest(const Bitmap& origBmp);
+ void BY8toRGBBilinear(const Bitmap& origBmp);
+
+ IntPoint m_Size;
+ int m_Stride;
+ PixelFormat m_PF;
+ unsigned char* m_pBits;
+ bool m_bOwnsBits;
+ UTF8String m_sName;
+
+ static bool s_bMagickInitialized;
+ static bool s_bGTKInitialized;
+};
+
+BitmapPtr YCbCr2RGBBitmap(BitmapPtr pYBmp, BitmapPtr pUBmp, BitmapPtr pVBmp);
+
+template<class PIXEL>
+void Bitmap::setPixel(const IntPoint& p, PIXEL color)
+{
+ *(PIXEL*)(&(m_pBits[p.y*m_Stride+p.x*getBytesPerPixel()])) = color;
+}
+
+// TODO: This is slow, and it clips incorrectly. Replace with external lib?
+template<class PIXEL>
+void Bitmap::drawLine(IntPoint p0, IntPoint p1, PIXEL color)
+{
+ IntRect BmpRect(IntPoint(0,0), m_Size);
+ p0 = BmpRect.cropPoint(p0);
+ p1 = BmpRect.cropPoint(p1);
+
+ bool bSteep = abs(p1.y - p0.y) > abs(p1.x - p0.x);
+ if (bSteep) {
+ std::swap(p0.x, p0.y);
+ std::swap(p1.x, p1.y);
+ }
+ if (p0.x > p1.x) {
+ std::swap(p0, p1);
+ }
+ int deltax = p1.x - p0.x;
+ int deltay = abs(p1.y - p0.y);
+ int error = -deltax/2;
+ int ystep;
+ int y = p0.y;
+ if (p0.y < p1.y) {
+ ystep = 1;
+ } else {
+ ystep = -1;
+ }
+ for (int x = p0.x; x <= p1.x; x++) {
+ if (bSteep) {
+ setPixel(IntPoint(y, x), color);
+ } else {
+ setPixel(IntPoint(x, y), color);
+ }
+ error += deltay;
+ if (error > 0) {
+ y += ystep;
+ error -= deltax;
+ }
+ }
+}
+#if defined(__SSE__) || defined(_WIN32)
+std::ostream& operator<<(std::ostream& os, const __m64 &val);
+#endif
+
+}
+#endif
diff --git a/src/graphics/BitmapLoader.cpp b/src/graphics/BitmapLoader.cpp
new file mode 100644
index 0000000..eeaa5a4
--- /dev/null
+++ b/src/graphics/BitmapLoader.cpp
@@ -0,0 +1,156 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "BitmapLoader.h"
+
+#include "PixelFormat.h"
+#include "Filterfliprgb.h"
+
+#include "../base/Exception.h"
+#include "../base/ScopeTimer.h"
+
+#include <gdk-pixbuf/gdk-pixbuf.h>
+#include <iostream>
+
+using namespace std;
+using namespace boost;
+
+namespace avg {
+
+BitmapLoader * BitmapLoader::s_pBitmapLoader = 0;
+
+void BitmapLoader::init(bool bBlueFirst)
+{
+#if (GLIB_MAJOR_VERSION <= 2 && GLIB_MINOR_VERSION < 36)
+ g_type_init();
+#endif
+// cerr << "BitmapLoader::init(" << bBlueFirst << ")" << endl;
+ if (s_pBitmapLoader != 0) {
+ delete s_pBitmapLoader;
+ }
+ s_pBitmapLoader = new BitmapLoader(bBlueFirst);
+}
+
+BitmapLoader* BitmapLoader::get()
+{
+ AVG_ASSERT(s_pBitmapLoader != 0);
+ return s_pBitmapLoader;
+}
+
+BitmapLoader::BitmapLoader(bool bBlueFirst)
+ : m_bBlueFirst(bBlueFirst)
+{
+}
+
+BitmapLoader::~BitmapLoader()
+{
+}
+
+bool BitmapLoader::isBlueFirst() const
+{
+ return m_bBlueFirst;
+}
+
+PixelFormat BitmapLoader::getDefaultPixelFormat(bool bAlpha)
+{
+ if (bAlpha) {
+ if (m_bBlueFirst) {
+ return B8G8R8A8;
+ } else {
+ return R8G8B8A8;
+ }
+ } else {
+ if (m_bBlueFirst) {
+ return B8G8R8X8;
+ } else {
+ return R8G8B8X8;
+ }
+ }
+}
+
+static ProfilingZoneID GDKPixbufProfilingZone("gdk_pixbuf load", true);
+static ProfilingZoneID ConvertProfilingZone("Format conversion", true);
+static ProfilingZoneID RGBFlipProfilingZone("RGB<->BGR flip", true);
+
+BitmapPtr BitmapLoader::load(const UTF8String& sFName, PixelFormat pf) const
+{
+ AVG_ASSERT(s_pBitmapLoader != 0);
+ GError* pError = 0;
+ GdkPixbuf* pPixBuf;
+ {
+ ScopeTimer timer(GDKPixbufProfilingZone);
+ pPixBuf = gdk_pixbuf_new_from_file(sFName.c_str(), &pError);
+ }
+ if (!pPixBuf) {
+ string sErr = pError->message;
+ g_error_free(pError);
+ throw Exception(AVG_ERR_FILEIO, sErr);
+ }
+ IntPoint size = IntPoint(gdk_pixbuf_get_width(pPixBuf),
+ gdk_pixbuf_get_height(pPixBuf));
+
+ PixelFormat srcPF;
+ if (gdk_pixbuf_get_has_alpha(pPixBuf)) {
+ srcPF = R8G8B8A8;
+ } else {
+ srcPF = R8G8B8;
+ }
+ if (pf == NO_PIXELFORMAT) {
+ if (m_bBlueFirst) {
+ if (srcPF == R8G8B8A8) {
+ pf = B8G8R8A8;
+ } else if (srcPF == R8G8B8) {
+ pf = B8G8R8X8;
+ }
+ } else {
+ if (srcPF == R8G8B8A8) {
+ pf = R8G8B8A8;
+ } else if (srcPF == R8G8B8) {
+ pf = R8G8B8X8;
+ }
+ }
+ }
+ BitmapPtr pBmp(new Bitmap(size, pf, sFName));
+ {
+ ScopeTimer timer(ConvertProfilingZone);
+
+ int stride = gdk_pixbuf_get_rowstride(pPixBuf);
+ guchar* pSrc = gdk_pixbuf_get_pixels(pPixBuf);
+ BitmapPtr pSrcBmp(new Bitmap(size, srcPF, pSrc, stride, false));
+ {
+ ScopeTimer timer(RGBFlipProfilingZone);
+ if (pixelFormatIsBlueFirst(pf) != pixelFormatIsBlueFirst(srcPF)) {
+ FilterFlipRGB().applyInPlace(pSrcBmp);
+ }
+ }
+ pBmp->copyPixels(*pSrcBmp);
+ }
+ g_object_unref(pPixBuf);
+ return pBmp;
+}
+
+BitmapPtr loadBitmap(const UTF8String& sFName, PixelFormat pf)
+{
+ return BitmapLoader::get()->load(sFName, pf);
+}
+
+}
+
diff --git a/src/graphics/BitmapLoader.h b/src/graphics/BitmapLoader.h
new file mode 100644
index 0000000..f834c9f
--- /dev/null
+++ b/src/graphics/BitmapLoader.h
@@ -0,0 +1,55 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _BitmapLoader_H_
+#define _BitmapLoader_H_
+
+#include "../api.h"
+#include "../avgconfigwrapper.h"
+
+#include "Bitmap.h"
+#include "PixelFormat.h"
+
+#include <string>
+
+namespace avg {
+
+class AVG_API BitmapLoader {
+public:
+ static void init(bool bBlueFirst);
+ static BitmapLoader* get();
+ bool isBlueFirst() const;
+ PixelFormat getDefaultPixelFormat(bool bAlpha);
+ BitmapPtr load(const UTF8String& sFName, PixelFormat pf=NO_PIXELFORMAT) const;
+
+private:
+ BitmapLoader(bool bBlueFirst);
+ virtual ~BitmapLoader();
+
+ bool m_bBlueFirst;
+ static BitmapLoader * s_pBitmapLoader;
+};
+
+BitmapPtr AVG_API loadBitmap(const UTF8String& sFName, PixelFormat pf=NO_PIXELFORMAT);
+
+}
+
+#endif
diff --git a/src/graphics/BmpTextureMover.cpp b/src/graphics/BmpTextureMover.cpp
new file mode 100644
index 0000000..dfb4f27
--- /dev/null
+++ b/src/graphics/BmpTextureMover.cpp
@@ -0,0 +1,111 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "BmpTextureMover.h"
+
+#include "Bitmap.h"
+#include "GLTexture.h"
+#include "FBO.h"
+#include "Filterfliprgb.h"
+
+#include "../base/Logger.h"
+#include "../base/Exception.h"
+
+#include "GLContext.h"
+
+#include <iostream>
+#include <cstring>
+
+using namespace std;
+using namespace boost;
+
+namespace avg {
+
+BmpTextureMover::BmpTextureMover(const IntPoint& size, PixelFormat pf)
+ : TextureMover(size, pf)
+{
+ m_pBmp = BitmapPtr(new Bitmap(size, pf));
+}
+
+BmpTextureMover::~BmpTextureMover()
+{
+}
+
+void BmpTextureMover::moveBmpToTexture(BitmapPtr pBmp, GLTexture& tex)
+{
+ AVG_ASSERT(pBmp->getSize() == tex.getSize());
+ AVG_ASSERT(getSize() == pBmp->getSize());
+ AVG_ASSERT(pBmp->getPixelFormat() == getPF());
+ tex.activate();
+ unsigned char * pStartPos = pBmp->getPixels();
+ IntPoint size = tex.getSize();
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, size.x, size.y,
+ tex.getGLFormat(getPF()), tex.getGLType(getPF()),
+ pStartPos);
+ tex.setDirty();
+ tex.generateMipmaps();
+ GLContext::checkError("BmpTextureMover::moveBmpToTexture: glTexSubImage2D()");
+}
+
+BitmapPtr BmpTextureMover::moveTextureToBmp(GLTexture& tex, int mipmapLevel)
+{
+ GLContext* pContext = GLContext::getCurrent();
+ unsigned fbo = pContext->genFBO();
+ glproc::BindFramebuffer(GL_FRAMEBUFFER, fbo);
+ glproc::FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
+ tex.getID(), mipmapLevel);
+ FBO::checkError("BmpTextureMover::moveTextureToBmp");
+ IntPoint size = tex.getMipmapSize(mipmapLevel);
+ BitmapPtr pBmp(new Bitmap(size, getPF()));
+ if (GLContext::getMain()->isGLES() && getPF() == B5G6R5) {
+ BitmapPtr pTmpBmp(new Bitmap(size, R8G8B8A8));
+ glReadPixels(0, 0, size.x, size.y, GL_RGBA, GL_UNSIGNED_BYTE, pTmpBmp->getPixels());
+ FilterFlipRGB().applyInPlace(pTmpBmp);
+ pBmp->copyPixels(*pTmpBmp);
+ } else {
+ int glPixelFormat = tex.getGLFormat(getPF());
+ glReadPixels(0, 0, size.x, size.y, glPixelFormat, tex.getGLType(getPF()),
+ pBmp->getPixels());
+ }
+ GLContext::checkError("BmpTextureMover::moveTextureToBmp: glReadPixels()");
+ glproc::FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
+ 0, 0);
+ pContext->returnFBOToCache(fbo);
+ glproc::BindFramebuffer(GL_FRAMEBUFFER, 0);
+ return pBmp;
+
+}
+
+BitmapPtr BmpTextureMover::lock()
+{
+ return m_pBmp;
+}
+
+void BmpTextureMover::unlock()
+{
+}
+
+void BmpTextureMover::moveToTexture(GLTexture& tex)
+{
+ moveBmpToTexture(m_pBmp, tex);
+}
+
+}
diff --git a/src/graphics/BmpTextureMover.h b/src/graphics/BmpTextureMover.h
new file mode 100644
index 0000000..f3d61e2
--- /dev/null
+++ b/src/graphics/BmpTextureMover.h
@@ -0,0 +1,54 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _BmpTextureMover_H_
+#define _BmpTextureMover_H_
+
+#include "../api.h"
+#include "TextureMover.h"
+
+#include <boost/shared_ptr.hpp>
+
+namespace avg {
+
+class AVG_API BmpTextureMover: public TextureMover {
+public:
+ BmpTextureMover(const IntPoint& size, PixelFormat pf);
+ virtual ~BmpTextureMover();
+
+ virtual void moveBmpToTexture(BitmapPtr pBmp, GLTexture& tex);
+ virtual BitmapPtr moveTextureToBmp(GLTexture& tex, int mipmapLevel=0);
+
+ virtual BitmapPtr lock();
+ virtual void unlock();
+ virtual void moveToTexture(GLTexture& tex);
+
+private:
+ BitmapPtr m_pBmp;
+};
+
+typedef boost::shared_ptr<BmpTextureMover> BmpTextureMoverPtr;
+
+}
+
+#endif
+
+
diff --git a/src/graphics/CGLContext.cpp b/src/graphics/CGLContext.cpp
new file mode 100644
index 0000000..f9f0471
--- /dev/null
+++ b/src/graphics/CGLContext.cpp
@@ -0,0 +1,114 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "CGLContext.h"
+
+#include "../base/Exception.h"
+#include "../base/Logger.h"
+
+#ifdef __APPLE__
+#include <ApplicationServices/ApplicationServices.h>
+#endif
+
+#include <SDL/SDL.h>
+#include <SDL/SDL_syswm.h>
+
+
+#include <iostream>
+
+
+namespace avg {
+
+using namespace std;
+using namespace boost;
+
+CGLContext::CGLContext(const GLConfig& glConfig, const IntPoint& windowSize,
+ const SDL_SysWMinfo* pSDLWMInfo)
+ : GLContext(windowSize, pSDLWMInfo)
+{
+ if (pSDLWMInfo) {
+ m_Context = CGLGetCurrentContext();
+ setCurrent();
+ } else {
+ CGLPixelFormatObj pixelFormatObj;
+ GLint numPixelFormats;
+
+ CGLPixelFormatAttribute attribs[] = {(CGLPixelFormatAttribute)NULL};
+ CGLChoosePixelFormat(attribs, &pixelFormatObj, &numPixelFormats);
+
+ CGLError err = CGLCreateContext(pixelFormatObj, 0, &m_Context);
+ if (err) {
+ cerr << CGLErrorString(err) << endl;
+ AVG_ASSERT(false);
+ }
+ CGLDestroyPixelFormat(pixelFormatObj);
+ }
+ init(glConfig, !pSDLWMInfo);
+}
+
+CGLContext::~CGLContext()
+{
+ deleteObjects();
+ if (m_Context && ownsContext()) {
+ CGLSetCurrentContext(0);
+ CGLDestroyContext(m_Context);
+ m_Context = 0;
+ }
+}
+
+void CGLContext::activate()
+{
+ CGLError err = CGLSetCurrentContext(m_Context);
+ AVG_ASSERT(err == kCGLNoError);
+ setCurrent();
+}
+
+bool CGLContext::initVBlank(int rate)
+{
+ if (rate > 0) {
+ initMacVBlank(rate);
+ return true;
+ } else {
+ initMacVBlank(0);
+ return false;
+ }
+}
+
+void CGLContext::initMacVBlank(int rate)
+{
+ CGLContextObj context = CGLGetCurrentContext();
+ AVG_ASSERT (context);
+#if MAC_OS_X_VERSION_10_5
+ GLint l = rate;
+#else
+ long l = rate;
+#endif
+ if (rate > 1) {
+ AVG_TRACE(Logger::category::CONFIG, Logger::severity::WARNING,
+ "VBlank rate set to " << rate
+ << " but Mac OS X only supports 1. Assuming 1.");
+ l = 1;
+ }
+ CGLError err = CGLSetParameter(context, kCGLCPSwapInterval, &l);
+ AVG_ASSERT(!err);
+}
+
+}
diff --git a/src/graphics/CGLContext.h b/src/graphics/CGLContext.h
new file mode 100644
index 0000000..951b481
--- /dev/null
+++ b/src/graphics/CGLContext.h
@@ -0,0 +1,56 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+#ifndef _CGLContext_H_
+#define _CGLContext_H_
+#include "../api.h"
+
+#include "GLContext.h"
+
+#include <OpenGL/OpenGL.h>
+#undef check // Conflicts with Boost
+
+#include <boost/shared_ptr.hpp>
+
+struct SDL_SysWMinfo;
+
+namespace avg {
+
+class AVG_API CGLContext: public GLContext
+{
+public:
+ CGLContext(const GLConfig& glConfig, const IntPoint& windowSize=IntPoint(0,0),
+ const SDL_SysWMinfo* pSDLWMInfo=0);
+ virtual ~CGLContext();
+
+ void activate();
+
+ bool initVBlank(int rate);
+
+private:
+ void initMacVBlank(int rate);
+
+ CGLContextObj m_Context;
+};
+
+}
+#endif
+
+
diff --git a/src/graphics/ContribDefs.h b/src/graphics/ContribDefs.h
new file mode 100644
index 0000000..8032aef
--- /dev/null
+++ b/src/graphics/ContribDefs.h
@@ -0,0 +1,75 @@
+// Fast and accurate bitmap scaling. Original code by Eran Yariv and Jake Montgomery,
+// posted on codeguru.com.
+
+#ifndef _ContribDefs_h_
+#define _ContribDefs_h_
+
+#include "../base/MathHelper.h"
+
+#include <math.h>
+
+namespace avg {
+
+class ContribDef
+{
+public:
+ ContribDef(float dWidth)
+ : m_dWidth (dWidth)
+ {}
+
+ virtual ~ContribDef() {}
+
+ float GetWidth() const
+ {
+ return m_dWidth;
+ }
+
+ void SetWidth(float dWidth)
+ {
+ m_dWidth = dWidth;
+ }
+
+ virtual float Filter(float dVal) const = 0;
+
+protected:
+ float m_dWidth;
+};
+
+class BilinearContribDef : public ContribDef
+{
+public:
+ BilinearContribDef(float dWidth = 1.0)
+ : ContribDef(dWidth)
+ {}
+
+ virtual ~BilinearContribDef() {}
+
+ virtual float Filter(float dVal) const
+ {
+ dVal = fabs(dVal);
+ return (dVal < m_dWidth ? m_dWidth - dVal : 0.0f);
+ }
+};
+
+class GaussianContribDef : public ContribDef
+{
+public:
+ GaussianContribDef(float dWidth = 3.0)
+ : ContribDef(dWidth)
+ {}
+
+ virtual ~GaussianContribDef() {}
+
+ virtual float Filter(float dVal) const
+ {
+ if (fabs (dVal) > m_dWidth)
+ {
+ return 0.0;
+ }
+ return float(exp(-dVal * dVal/m_dWidth-1) / sqrt(2*PI));
+ }
+};
+
+}
+
+#endif
diff --git a/src/graphics/Display.cpp b/src/graphics/Display.cpp
new file mode 100644
index 0000000..22d2c62
--- /dev/null
+++ b/src/graphics/Display.cpp
@@ -0,0 +1,136 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "Display.h"
+#ifdef __linux__
+#include "X11Display.h"
+#endif
+#ifdef __APPLE__
+#include "AppleDisplay.h"
+#endif
+#ifdef _WIN32
+#include "WinDisplay.h"
+#endif
+#include "Bitmap.h"
+
+#include "../base/Logger.h"
+
+#include <SDL/SDL.h>
+#include <SDL/SDL_syswm.h>
+
+#include <iostream>
+
+using namespace std;
+
+namespace avg {
+
+DisplayPtr Display::s_pInstance = DisplayPtr();
+
+DisplayPtr Display::get()
+{
+ if (!s_pInstance) {
+#ifdef __linux__
+ s_pInstance = DisplayPtr(new X11Display());
+#elif defined __APPLE__
+ s_pInstance = DisplayPtr(new AppleDisplay());
+#elif defined _WIN32
+ s_pInstance = DisplayPtr(new WinDisplay());
+#else
+ AVG_ASSERT(false);
+#endif
+ s_pInstance->init();
+ }
+ return s_pInstance;
+}
+
+bool Display::isInitialized()
+{
+ return s_pInstance;
+}
+
+Display::Display()
+ : m_bAutoPPMM(true),
+ m_RefreshRate(0.0f)
+{
+}
+
+Display::~Display()
+{
+}
+
+void Display::init()
+{
+ m_ScreenResolution = queryScreenResolution();
+ m_PPMM = queryPPMM();
+}
+
+void Display::rereadScreenResolution()
+{
+ m_ScreenResolution = queryScreenResolution();
+ if (m_bAutoPPMM) {
+ m_PPMM = queryPPMM();
+ }
+}
+
+IntPoint Display::getScreenResolution()
+{
+ return m_ScreenResolution;
+}
+
+float Display::getPixelsPerMM()
+{
+ return m_PPMM;
+}
+
+void Display::assumePixelsPerMM(float ppmm)
+{
+ if (ppmm != 0) {
+ m_PPMM = ppmm;
+ m_bAutoPPMM = false;
+ }
+}
+
+glm::vec2 Display::getPhysicalScreenDimensions()
+{
+ glm::vec2 size;
+ glm::vec2 screenRes = glm::vec2(getScreenResolution());
+ size.x = screenRes.x/m_PPMM;
+ size.y = screenRes.y/m_PPMM;
+ return size;
+}
+
+IntPoint Display::queryScreenResolution()
+{
+ const SDL_VideoInfo* pInfo = SDL_GetVideoInfo();
+ return IntPoint(pInfo->current_w, pInfo->current_h);
+}
+
+float Display::getRefreshRate()
+{
+ if (m_RefreshRate == 0.0) {
+ m_RefreshRate = queryRefreshRate();
+ AVG_TRACE(Logger::category::CONFIG, Logger::severity::INFO,
+ "Vertical Refresh Rate: " << m_RefreshRate);
+ }
+ return m_RefreshRate;
+}
+
+}
diff --git a/src/graphics/Display.h b/src/graphics/Display.h
new file mode 100644
index 0000000..e680936
--- /dev/null
+++ b/src/graphics/Display.h
@@ -0,0 +1,71 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _Display_H_
+#define _Display_H_
+
+#include "../api.h"
+#include "../avgconfigwrapper.h"
+
+#include "../base/GLMHelper.h"
+
+#include <boost/shared_ptr.hpp>
+
+namespace avg {
+
+class Display;
+typedef boost::shared_ptr<Display> DisplayPtr;
+
+class AVG_API Display
+{
+public:
+ static DisplayPtr get();
+ static bool isInitialized();
+ virtual ~Display();
+ void init();
+ void rereadScreenResolution();
+
+ IntPoint getScreenResolution();
+ float getPixelsPerMM();
+ void assumePixelsPerMM(float ppmm);
+ glm::vec2 getPhysicalScreenDimensions();
+ float getRefreshRate();
+
+protected:
+ Display();
+
+ virtual float queryPPMM()=0;
+ virtual IntPoint queryScreenResolution();
+ virtual float queryRefreshRate()=0;
+
+private:
+ IntPoint m_ScreenResolution;
+ float m_PPMM;
+ bool m_bAutoPPMM; // true if assumePixelsPerMM hasn't been called.
+
+ float m_RefreshRate;
+
+ static DisplayPtr s_pInstance;
+};
+
+}
+
+#endif
diff --git a/src/graphics/EGLContext.cpp b/src/graphics/EGLContext.cpp
new file mode 100644
index 0000000..dce62d9
--- /dev/null
+++ b/src/graphics/EGLContext.cpp
@@ -0,0 +1,202 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "EGLContext.h"
+#include "GLContextAttribs.h"
+#ifdef AVG_ENABLE_RPI
+ #include "BCMDisplay.h"
+#else
+ #include "X11Display.h"
+#endif
+
+#include "../base/Exception.h"
+#include "../base/StringHelper.h"
+
+#include <SDL/SDL_syswm.h>
+#include <EGL/egl.h>
+
+#include <iostream>
+
+namespace avg{
+
+using namespace std;
+
+EGLContext::EGLContext(const GLConfig& glConfig, const IntPoint& windowSize,
+ const SDL_SysWMinfo* pSDLWMInfo)
+ : GLContext(windowSize, pSDLWMInfo)
+{
+ createEGLContext(glConfig, windowSize, pSDLWMInfo);
+ init(glConfig, true);
+}
+
+EGLContext::~EGLContext()
+{
+ getVertexBufferCache().deleteBuffers();
+ getIndexBufferCache().deleteBuffers();
+ getPBOCache().deleteBuffers();
+ deleteObjects();
+ eglMakeCurrent(m_Display, EGL_NO_SURFACE, EGL_NO_SURFACE, 0);
+ eglDestroyContext(m_Display, m_Context);
+ eglDestroySurface(m_Display, m_Surface);
+ eglTerminate(m_Display);
+}
+
+void EGLContext::createEGLContext(const GLConfig& glConfig, const IntPoint& windowSize,
+ const SDL_SysWMinfo* pSDLWMInfo)
+{
+ bool bOk;
+
+#ifdef AVG_ENABLE_RPI
+ m_xDisplay = (EGLNativeDisplayType)getBCMDisplay(pSDLWMInfo);
+ m_Display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+#else
+ m_xDisplay = (EGLNativeDisplayType)getX11Display(pSDLWMInfo);
+ m_Display = eglGetDisplay(m_xDisplay);
+#endif
+ checkEGLError(m_Display == EGL_NO_DISPLAY, "No EGL display available");
+
+ bOk = eglInitialize(m_Display, NULL, NULL);
+ checkEGLError(!bOk, "eglInitialize failed");
+
+ GLContextAttribs fbAttrs;
+ fbAttrs.append(EGL_RED_SIZE, 1);
+ fbAttrs.append(EGL_GREEN_SIZE, 1);
+ fbAttrs.append(EGL_BLUE_SIZE, 1);
+ fbAttrs.append(EGL_DEPTH_SIZE, 0);
+ fbAttrs.append(EGL_STENCIL_SIZE, 1);
+ int alphaSize = 0;
+#ifdef AVG_ENABLE_RPI
+ if (!pSDLWMInfo) {
+ alphaSize = 1;
+ }
+#endif
+ fbAttrs.append(EGL_ALPHA_SIZE, alphaSize);
+ fbAttrs.append(EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT);
+ EGLint numFBConfig;
+ bOk = eglChooseConfig(m_Display, fbAttrs.get(), &m_Config, 1, &numFBConfig);
+ checkEGLError(!bOk, "Failed to choose EGL config");
+
+ EGLint vid;
+ bOk = eglGetConfigAttrib(m_Display, m_Config, EGL_NATIVE_VISUAL_ID, &vid);
+ AVG_ASSERT(bOk);
+
+#ifndef AVG_ENABLE_RPI
+ XVisualInfo visTemplate;
+ visTemplate.visualid = vid;
+ int num_visuals;
+ XVisualInfo* pVisualInfo = XGetVisualInfo((_XDisplay*)m_xDisplay, VisualIDMask, &visTemplate,
+ &num_visuals);
+ AVG_ASSERT(pVisualInfo);
+#endif
+
+ EGLNativeWindowType xWindow = 0;
+ if (pSDLWMInfo) {
+#ifdef AVG_ENABLE_RPI
+ xWindow = createChildWindow(pSDLWMInfo, m_xDisplay, windowSize);
+#else
+ Colormap colormap;
+ xWindow = (EGLNativeWindowType)createChildWindow(pSDLWMInfo, pVisualInfo, windowSize, colormap);
+#endif
+ }
+
+ if (!eglBindAPI(EGL_OPENGL_ES_API)) {
+ cerr << "Failed to bind GLES API to EGL\n";
+ return;
+ }
+
+ if (numFBConfig != 1) {
+ cerr << "Didn't get exactly one config, but " << numFBConfig << endl;
+ return;
+ }
+ if (xWindow) {
+ m_Surface = eglCreateWindowSurface(m_Display, m_Config, xWindow, NULL);
+ } else {
+#ifdef AVG_ENABLE_RPI
+ m_Surface = createBCMPixmapSurface(m_Display, m_Config);
+#else
+ XVisualInfo visTemplate, *results;
+ visTemplate.screen = 0;
+ int numVisuals;
+ results = XGetVisualInfo((_XDisplay*)m_xDisplay, VisualScreenMask,
+ &visTemplate, & numVisuals);
+
+ Pixmap pmp = XCreatePixmap((_XDisplay*)m_xDisplay,
+ RootWindow((_XDisplay*)m_xDisplay, results[0].screen), 8, 8, results[0].depth);
+ m_Surface = eglCreatePixmapSurface(m_Display, m_Config, (EGLNativePixmapType)pmp, NULL);
+#endif
+ }
+ AVG_ASSERT(m_Surface);
+
+ GLContextAttribs attrs;
+ attrs.append(EGL_CONTEXT_CLIENT_VERSION, 2);
+ m_Context = eglCreateContext(m_Display, m_Config, NULL, attrs.get());
+ checkEGLError(!m_Context, "Unable to create EGL context");
+// dumpEGLConfig();
+}
+
+bool EGLContext::initVBlank(int rate)
+{
+ return false;
+}
+
+void EGLContext::activate()
+{
+ eglMakeCurrent(m_Display, m_Surface, m_Surface, m_Context);
+ setCurrent();
+}
+
+void EGLContext::swapBuffers()
+{
+ eglSwapBuffers(m_Display, m_Surface);
+}
+
+void EGLContext::checkEGLError(bool bError, const std::string& sMsg)
+{
+ if (bError) {
+ throw Exception(AVG_ERR_VIDEO_INIT_FAILED, sMsg + " (EGL error: " +
+ toString(eglGetError()) + ")");
+ }
+}
+
+void EGLContext::dumpEGLConfig() const
+{
+ cout << "EGL configuration:" << endl;
+ dumpEGLConfigAttrib(EGL_RED_SIZE, "RED_SIZE");
+ dumpEGLConfigAttrib(EGL_GREEN_SIZE, "GREEN_SIZE");
+ dumpEGLConfigAttrib(EGL_BLUE_SIZE, "BLUE_SIZE");
+ dumpEGLConfigAttrib(EGL_ALPHA_SIZE, "ALPHA_SIZE");
+ dumpEGLConfigAttrib(EGL_BUFFER_SIZE, "BUFFER_SIZE");
+ dumpEGLConfigAttrib(EGL_DEPTH_SIZE, "DEPTH_SIZE");
+ dumpEGLConfigAttrib(EGL_STENCIL_SIZE, "STENCIL_SIZE");
+}
+
+void EGLContext::dumpEGLConfigAttrib(EGLint attrib, const string& name) const
+{
+ EGLint value;
+ if (eglGetConfigAttrib(m_Display, m_Config, attrib, &value)) {
+ cout << " " << name << ": " << value << endl;
+ }
+ else {
+ cerr << " Failed to get EGL config attribute " << name << endl;
+ }
+}
+
+}
diff --git a/src/graphics/EGLContext.h b/src/graphics/EGLContext.h
new file mode 100644
index 0000000..d6a2af4
--- /dev/null
+++ b/src/graphics/EGLContext.h
@@ -0,0 +1,61 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+#ifndef _EGLContext_H_
+#define _EGLContext_H_
+
+#include "../api.h"
+
+#include <EGL/egl.h>
+#include "GLContext.h"
+
+struct SDL_SysWMinfo;
+
+namespace avg {
+
+class AVG_API EGLContext: public GLContext
+{
+public:
+ EGLContext(const GLConfig& glConfig, const IntPoint& windowSize=IntPoint(0,0),
+ const SDL_SysWMinfo* pSDLWMInfo=0);
+ virtual ~EGLContext();
+
+ void activate();
+ bool initVBlank(int rate);
+ void swapBuffers();
+
+private:
+ void createEGLContext(const GLConfig& glConfig, const IntPoint& windowSize,
+ const SDL_SysWMinfo* pSDLWMInfo);
+ void checkEGLError(bool bError, const std::string& sMsg);
+
+ void dumpEGLConfig() const;
+ void dumpEGLConfigAttrib(EGLint attrib, const std::string& name) const;
+
+ EGLNativeDisplayType m_xDisplay;
+ EGLDisplay m_Display;
+ EGLConfig m_Config;
+ ::EGLContext m_Context;
+ EGLSurface m_Surface;
+};
+
+}
+
+#endif
diff --git a/src/graphics/FBO.cpp b/src/graphics/FBO.cpp
new file mode 100644
index 0000000..e7837b5
--- /dev/null
+++ b/src/graphics/FBO.cpp
@@ -0,0 +1,410 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "FBO.h"
+
+#include "OGLHelper.h"
+#include "GLContext.h"
+#include "Filterfliprgb.h"
+
+#include "../base/Exception.h"
+#include "../base/StringHelper.h"
+#include "../base/ObjectCounter.h"
+
+#include <stdio.h>
+
+using namespace std;
+using namespace boost;
+
+namespace avg {
+
+#ifndef GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS
+#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT
+#endif
+
+#ifdef AVG_ENABLE_EGL
+#define GL_DEPTH_STENCIL_EXT GL_DEPTH24_STENCIL8_OES
+#endif
+
+FBO::FBO(const IntPoint& size, PixelFormat pf, unsigned numTextures,
+ unsigned multisampleSamples, bool bUsePackedDepthStencil, bool bUseStencil,
+ bool bMipmap)
+ : m_Size(size),
+ m_PF(pf),
+ m_MultisampleSamples(multisampleSamples),
+ m_bUsePackedDepthStencil(bUsePackedDepthStencil),
+ m_bUseStencil(bUseStencil),
+ m_bMipmap(bMipmap)
+{
+ ObjectCounter::get()->incRef(&typeid(*this));
+ AVG_ASSERT(numTextures == 1 || multisampleSamples == 1);
+ if (multisampleSamples > 1 && !(isMultisampleFBOSupported())) {
+ throw Exception(AVG_ERR_UNSUPPORTED,
+ "Multisample offscreen rendering is not supported by this OpenGL driver/card combination.");
+ }
+ if (multisampleSamples < 1) {
+ throwMultisampleError();
+ }
+ for (unsigned i=0; i<numTextures; ++i) {
+ GLTexturePtr pTex = GLTexturePtr(new GLTexture(size, pf, bMipmap));
+ pTex->generateMipmaps();
+ GLContext::checkError("FBO::FBO: generateMipmaps");
+ m_pTextures.push_back(pTex);
+ }
+ init();
+}
+
+FBO::~FBO()
+{
+ ObjectCounter::get()->decRef(&typeid(*this));
+
+ unsigned oldFBOID;
+ glGetIntegerv(GL_FRAMEBUFFER_BINDING, (GLint*)&oldFBOID);
+ glproc::BindFramebuffer(GL_FRAMEBUFFER, m_FBO);
+
+ for (unsigned i=0; i<m_pTextures.size(); ++i) {
+ glproc::FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0+i,
+ GL_TEXTURE_2D, 0, 0);
+ }
+
+ GLContext* pContext = GLContext::getCurrent();
+ if (pContext) {
+ pContext->returnFBOToCache(m_FBO);
+ if (m_MultisampleSamples > 1) {
+ glproc::DeleteRenderbuffers(1, &m_ColorBuffer);
+ pContext->returnFBOToCache(m_OutputFBO);
+ }
+ if (m_bUsePackedDepthStencil && isPackedDepthStencilSupported()) {
+ glproc::DeleteRenderbuffers(1, &m_StencilBuffer);
+ glproc::FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
+ GL_RENDERBUFFER, 0);
+ glproc::FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
+ GL_RENDERBUFFER, 0);
+ if (m_MultisampleSamples > 1) {
+ glproc::BindFramebuffer(GL_FRAMEBUFFER, m_OutputFBO);
+ glproc::FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+ GL_TEXTURE_2D, 0, 0);
+ }
+ } else if (m_bUseStencil) {
+ glproc::DeleteRenderbuffers(1, &m_StencilBuffer);
+ glproc::FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
+ GL_RENDERBUFFER, 0);
+ }
+ glproc::BindFramebuffer(GL_FRAMEBUFFER, oldFBOID);
+ GLContext::checkError("~FBO");
+ }
+}
+
+void FBO::activate() const
+{
+ glproc::BindFramebuffer(GL_FRAMEBUFFER, m_FBO);
+ GLContext::checkError("FBO::activate: BindFramebuffer()");
+ checkError("activate");
+}
+
+PixelFormat FBO::getPF() const
+{
+ return m_PF;
+}
+
+unsigned FBO::getNumTextures() const
+{
+ return m_pTextures.size();
+}
+
+void FBO::copyToDestTexture() const
+{
+#ifndef AVG_ENABLE_EGL
+ if (m_MultisampleSamples != 1) {
+ // Copy Multisample FBO to destination fbo
+ glproc::BindFramebuffer(GL_READ_FRAMEBUFFER_EXT, m_FBO);
+ glproc::BindFramebuffer(GL_DRAW_FRAMEBUFFER_EXT, m_OutputFBO);
+ glproc::BlitFramebuffer(0, 0, m_Size.x, m_Size.y, 0, 0, m_Size.x, m_Size.y,
+ GL_COLOR_BUFFER_BIT, GL_LINEAR);
+ glproc::BindFramebuffer(GL_FRAMEBUFFER, 0);
+ }
+#endif
+ if (m_bMipmap) {
+ for (unsigned i=0; i< m_pTextures.size(); ++i) {
+ m_pTextures[i]->generateMipmaps();
+ }
+ }
+}
+
+BitmapPtr FBO::getImage(int i) const
+{
+ GLContext* pContext = GLContext::getCurrent();
+ if (pContext->getMemoryMode() == MM_PBO) {
+ moveToPBO(i);
+ return getImageFromPBO();
+ } else {
+ BitmapPtr pBmp(new Bitmap(m_Size, m_PF));
+ glproc::BindFramebuffer(GL_FRAMEBUFFER, m_OutputFBO);
+ glReadPixels(0, 0, m_Size.x, m_Size.y, GLTexture::getGLFormat(m_PF),
+ GLTexture::getGLType(m_PF), pBmp->getPixels());
+ GLContext::checkError("FBO::getImage ReadPixels()");
+ return pBmp;
+ }
+}
+
+void FBO::moveToPBO(int i) const
+{
+ AVG_ASSERT(GLContext::getCurrent()->getMemoryMode() == MM_PBO);
+#ifndef AVG_ENABLE_EGL
+ // Get data directly from the FBO using glReadBuffer. At least on NVidia/Linux, this
+ // is faster than reading stuff from the texture.
+ copyToDestTexture();
+ glproc::BindFramebuffer(GL_FRAMEBUFFER, m_OutputFBO);
+
+ m_pOutputPBO->activate();
+ GLContext::checkError("FBO::moveToPBO BindBuffer()");
+ glReadBuffer(GL_COLOR_ATTACHMENT0+i);
+ GLContext::checkError("FBO::moveToPBO ReadBuffer()");
+
+ glReadPixels(0, 0, m_Size.x, m_Size.y, GLTexture::getGLFormat(m_PF),
+ GLTexture::getGLType(m_PF), 0);
+ GLContext::checkError("FBO::moveToPBO ReadPixels()");
+#endif
+}
+
+BitmapPtr FBO::getImageFromPBO() const
+{
+#ifdef AVG_ENABLE_EGL
+ AVG_ASSERT(false);
+ return BitmapPtr();
+#else
+ AVG_ASSERT(GLContext::getCurrent()->getMemoryMode() == MM_PBO);
+ m_pOutputPBO->activate();
+ GLContext::checkError("FBO::getImageFromPBO BindBuffer()");
+
+ BitmapPtr pBmp(new Bitmap(m_Size, m_PF));
+ void * pPBOPixels = glproc::MapBuffer(GL_PIXEL_PACK_BUFFER_EXT, GL_READ_ONLY);
+ GLContext::checkError("FBO::getImageFromPBO MapBuffer()");
+ Bitmap PBOBitmap(m_Size, m_PF, (unsigned char *)pPBOPixels,
+ m_Size.x*getBytesPerPixel(m_PF), false);
+ pBmp->copyPixels(PBOBitmap);
+ glproc::UnmapBuffer(GL_PIXEL_PACK_BUFFER_EXT);
+ GLContext::checkError("FBO::getImageFromPBO UnmapBuffer()");
+ return pBmp;
+#endif
+}
+
+GLTexturePtr FBO::getTex(int i) const
+{
+ return m_pTextures[i];
+}
+
+const IntPoint& FBO::getSize() const
+{
+ return m_Size;
+}
+
+unsigned FBO::getID() const
+{
+ return m_FBO;
+}
+
+void FBO::init()
+{
+ GLContext* pContext = GLContext::getCurrent();
+ if (m_bUsePackedDepthStencil && !isPackedDepthStencilSupported()) {
+ throw Exception(AVG_ERR_UNSUPPORTED, "OpenGL implementation does not support offscreen cropping (GL_EXT_packed_depth_stencil).");
+ }
+ if (m_MultisampleSamples > 1 && !isMultisampleFBOSupported()) {
+ throw Exception(AVG_ERR_UNSUPPORTED, "OpenGL implementation does not support multisample offscreen rendering (GL_EXT_framebuffer_multisample).");
+ }
+#ifndef AVG_ENABLE_EGL
+ if (GLContext::getCurrent()->getMemoryMode() == MM_PBO) {
+ m_pOutputPBO = PBOPtr(new PBO(m_Size, m_PF, GL_STREAM_READ));
+ }
+#endif
+
+ m_FBO = pContext->genFBO();
+ GLContext::checkError("FBO::init: GenFramebuffers()");
+
+ glproc::BindFramebuffer(GL_FRAMEBUFFER, m_FBO);
+ GLContext::checkError("FBO::init: BindFramebuffer()");
+
+ IntPoint glSize = m_pTextures[0]->getGLSize();
+ if (m_MultisampleSamples == 1) {
+ for (unsigned i=0; i<m_pTextures.size(); ++i) {
+ glproc::FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0+i,
+ GL_TEXTURE_2D, m_pTextures[i]->getID(), 0);
+ GLContext::checkError("FBO: glFramebufferTexture2D()");
+ }
+ if (m_bUsePackedDepthStencil) {
+ glproc::GenRenderbuffers(1, &m_StencilBuffer);
+ glproc::BindRenderbuffer(GL_RENDERBUFFER, m_StencilBuffer);
+ glproc::RenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_STENCIL_EXT,
+ glSize.x, glSize.y);
+ glproc::FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
+ GL_RENDERBUFFER, m_StencilBuffer);
+ glproc::FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
+ GL_RENDERBUFFER, m_StencilBuffer);
+ GLContext::checkError("FBO::init: FramebufferRenderbuffer(DEPTH_STENCIL)");
+ } else if (m_bUseStencil) {
+ glproc::GenRenderbuffers(1, &m_StencilBuffer);
+ glproc::BindRenderbuffer(GL_RENDERBUFFER, m_StencilBuffer);
+ glproc::RenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8,
+ glSize.x, glSize.y);
+ glproc::FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
+ GL_RENDERBUFFER, m_StencilBuffer);
+ GLContext::checkError("FBO::init: FramebufferRenderbuffer(STENCIL)");
+ }
+ m_OutputFBO = m_FBO;
+ } else {
+#ifdef AVG_ENABLE_EGL
+ AVG_ASSERT(false);
+#else
+ glproc::GenRenderbuffers(1, &m_ColorBuffer);
+ glproc::BindRenderbuffer(GL_RENDERBUFFER, m_ColorBuffer);
+ GLContext::enableErrorLog(false);
+ glproc::RenderbufferStorageMultisample(GL_RENDERBUFFER, m_MultisampleSamples,
+ GL_RGBA8, glSize.x, glSize.y);
+ GLContext::enableErrorLog(true);
+ GLenum err = glGetError();
+ if (err == GL_INVALID_VALUE) {
+ glproc::BindFramebuffer(GL_FRAMEBUFFER, 0);
+ glproc::DeleteFramebuffers(1, &m_FBO);
+ glproc::DeleteRenderbuffers(1, &m_ColorBuffer);
+ m_pOutputPBO = PBOPtr();
+ throwMultisampleError();
+ }
+ GLContext::checkError("FBO::init: RenderbufferStorageMultisample");
+ glproc::FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+ GL_RENDERBUFFER, m_ColorBuffer);
+ GLContext::checkError("FBO::init: FramebufferRenderbuffer");
+ if (m_bUsePackedDepthStencil) {
+ glproc::GenRenderbuffers(1, &m_StencilBuffer);
+ glproc::BindRenderbuffer(GL_RENDERBUFFER, m_StencilBuffer);
+ glproc::RenderbufferStorageMultisample(GL_RENDERBUFFER,
+ m_MultisampleSamples, GL_DEPTH_STENCIL_EXT, glSize.x, glSize.y);
+ GLenum err = glGetError();
+ if (err == GL_INVALID_OPERATION) {
+ glproc::BindFramebuffer(GL_FRAMEBUFFER, 0);
+ glproc::DeleteFramebuffers(1, &m_FBO);
+ glproc::DeleteRenderbuffers(1, &m_ColorBuffer);
+ m_pOutputPBO = PBOPtr();
+ throwMultisampleError();
+ }
+ glproc::FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
+ GL_RENDERBUFFER, m_StencilBuffer);
+ glproc::FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
+ GL_RENDERBUFFER, m_StencilBuffer);
+ GLContext::checkError("FBO::init: FramebufferRenderbuffer(STENCIL)");
+ } else {
+ AVG_ASSERT_MSG(!m_bUseStencil,
+ "Multisample FBO with stencil & not depth buffers not implemented yet.");
+ }
+ checkError("init multisample");
+ m_OutputFBO = pContext->genFBO();
+ glproc::BindFramebuffer(GL_FRAMEBUFFER, m_OutputFBO);
+ glproc::FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+ GL_TEXTURE_2D, m_pTextures[0]->getID(), 0);
+
+ GLContext::checkError("FBO::init: Multisample init");
+#endif
+ }
+
+ checkError("init");
+ glproc::BindFramebuffer(GL_FRAMEBUFFER, 0);
+}
+
+void FBO::throwMultisampleError()
+{
+ throw(Exception(AVG_ERR_UNSUPPORTED,
+ string("Unsupported value for number of multisample samples (")
+ + toString(m_MultisampleSamples) + ")."));
+}
+
+bool FBO::isFBOSupported()
+{
+ return GLContext::getCurrent()->isGLES() ||
+ queryOGLExtension("GL_EXT_framebuffer_object");
+}
+
+bool FBO::isMultisampleFBOSupported()
+{
+#ifdef AVG_ENABLE_EGL
+ return false;
+#else
+ int maxSamples;
+ glGetIntegerv(GL_MAX_SAMPLES_EXT, &maxSamples);
+ GLenum err = glGetError();
+ if (err != GL_NO_ERROR) {
+ return false;
+ }
+ return queryOGLExtension("GL_EXT_framebuffer_multisample") &&
+ queryOGLExtension("GL_EXT_framebuffer_blit") && maxSamples > 1;
+#endif
+}
+
+bool FBO::isPackedDepthStencilSupported()
+{
+ return queryOGLExtension("GL_EXT_packed_depth_stencil") ||
+ queryOGLExtension("GL_OES_packed_depth_stencil");
+}
+
+void FBO::checkError(const string& sContext)
+{
+ GLenum status = glproc::CheckFramebufferStatus(GL_FRAMEBUFFER);
+ string sErr;
+ switch (status) {
+ case GL_FRAMEBUFFER_COMPLETE:
+ return;
+ case GL_FRAMEBUFFER_UNSUPPORTED:
+ sErr = "GL_FRAMEBUFFER_UNSUPPORTED";
+ throw Exception(AVG_ERR_UNSUPPORTED, string("Framebuffer error: ")+sErr);
+ break;
+ case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
+ sErr = "GL_INCOMPLETE_ATTACHMENT";
+ break;
+ case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
+ sErr = "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT";
+ break;
+ case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS:
+ sErr = "GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS";
+ break;
+#ifndef AVG_ENABLE_EGL
+ case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
+ sErr = "GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT";
+ break;
+ case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
+ sErr = "GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT";
+ break;
+ case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
+ sErr = "GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT";
+ break;
+ case GL_FRAMEBUFFER_BINDING_EXT:
+ sErr = "GL_FRAMEBUFFER_BINDING_EXT";
+ break;
+#endif
+ default:
+ sErr = "Unknown error";
+ break;
+ }
+ cerr << "Framebuffer error (" << sContext << "): " << sErr << endl;
+ AVG_ASSERT(false);
+}
+
+}
+
+
diff --git a/src/graphics/FBO.h b/src/graphics/FBO.h
new file mode 100644
index 0000000..5872beb
--- /dev/null
+++ b/src/graphics/FBO.h
@@ -0,0 +1,97 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _FBO_H_
+#define _FBO_H_
+
+#include "../api.h"
+
+#include "GLTexture.h"
+#ifndef AVG_ENABLE_EGL
+ #include "PBO.h"
+#endif
+#include "VertexArray.h"
+
+#include "../base/GLMHelper.h"
+
+#include <boost/shared_ptr.hpp>
+
+#include <vector>
+
+namespace avg {
+
+class AVG_API FBO
+{
+public:
+ FBO(const IntPoint& size, PixelFormat pf, unsigned numTextures=1,
+ unsigned multisampleSamples=1, bool bUsePackedDepthStencil=false,
+ bool bUseStencil=false, bool bMipmap=false);
+ virtual ~FBO();
+
+ void activate() const;
+ PixelFormat getPF() const;
+ unsigned getNumTextures() const;
+
+ void copyToDestTexture() const;
+ BitmapPtr getImage(int i=0) const;
+ void moveToPBO(int i=0) const;
+ BitmapPtr getImageFromPBO() const;
+ GLTexturePtr getTex(int i=0) const;
+ const IntPoint& getSize() const;
+ unsigned getID() const;
+
+ static bool isFBOSupported();
+ static bool isMultisampleFBOSupported();
+ static bool isPackedDepthStencilSupported();
+
+ void initCache();
+ static void deleteCache();
+ static void checkError(const std::string& sContext);
+
+private:
+ void init();
+ void throwMultisampleError();
+
+ IntPoint m_Size;
+ PixelFormat m_PF;
+ unsigned m_MultisampleSamples;
+ bool m_bUsePackedDepthStencil;
+ bool m_bUseStencil;
+ bool m_bMipmap;
+
+#ifndef AVG_ENABLE_EGL
+ PBOPtr m_pOutputPBO;
+#endif
+ unsigned m_FBO;
+ std::vector<GLTexturePtr> m_pTextures;
+ unsigned m_StencilBuffer;
+
+ // Multisample support
+ unsigned m_ColorBuffer;
+ unsigned m_OutputFBO;
+
+};
+
+typedef boost::shared_ptr<FBO> FBOPtr;
+
+}
+
+#endif
diff --git a/src/graphics/Filter.cpp b/src/graphics/Filter.cpp
new file mode 100644
index 0000000..ab9e9b3
--- /dev/null
+++ b/src/graphics/Filter.cpp
@@ -0,0 +1,55 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "Filter.h"
+#include "Bitmap.h"
+
+#include "../base/ObjectCounter.h"
+
+#include <iostream>
+
+using namespace std;
+
+namespace avg {
+
+Filter::Filter()
+{
+ ObjectCounter::get()->incRef(&typeid(*this));
+}
+
+Filter::~Filter()
+{
+ ObjectCounter::get()->decRef(&typeid(*this));
+}
+
+void Filter::applyInPlace(BitmapPtr pBmp)
+{
+ *pBmp = *(apply(pBmp));
+}
+
+BitmapPtr Filter::apply(BitmapPtr pBmpSource)
+{
+ BitmapPtr pBmpDest = BitmapPtr(new Bitmap(*pBmpSource));
+ applyInPlace(pBmpDest);
+ return pBmpDest;
+}
+
+}
diff --git a/src/graphics/Filter.h b/src/graphics/Filter.h
new file mode 100644
index 0000000..3fb5b00
--- /dev/null
+++ b/src/graphics/Filter.h
@@ -0,0 +1,56 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _Filter_H_
+#define _Filter_H_
+
+#include "../api.h"
+#include "Bitmap.h"
+
+#include <boost/shared_ptr.hpp>
+
+namespace avg {
+
+// Base class for filters that operate on bitmaps. Derived classes need
+// to override either the applyInPlace or the apply function. The base-class
+// versions of these functions simply implement one function in terms of the
+// other.
+class AVG_API Filter
+{
+public:
+ Filter();
+ virtual ~Filter();
+
+ // In-Place Apply. Applies the filter to pBmp. The base-class
+ // version copies the bitmap after calling Apply (pBmp, pTempBmp).
+ virtual void applyInPlace(BitmapPtr pBmp);
+
+ // Applies the Filter to pBmpSource and returns the result
+ // The base-class version copies the bitmap before calling
+ // applyInPlace.
+ virtual BitmapPtr apply(BitmapPtr pBmpSource);
+};
+
+typedef boost::shared_ptr<Filter> FilterPtr;
+
+}
+
+#endif
diff --git a/src/graphics/Filter3x3.cpp b/src/graphics/Filter3x3.cpp
new file mode 100644
index 0000000..592c19e
--- /dev/null
+++ b/src/graphics/Filter3x3.cpp
@@ -0,0 +1,68 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "Filter3x3.h"
+#include "Pixeldefs.h"
+
+#include "../base/Exception.h"
+
+
+namespace avg {
+
+Filter3x3::Filter3x3(float Mat[3][3])
+ : Filter()
+{
+ for (int y = 0; y < 3; y++) {
+ for (int x = 0; x < 3; x++) {
+ m_Mat[y][x] = Mat[y][x];
+ }
+ }
+}
+
+Filter3x3::~Filter3x3()
+{
+
+}
+
+BitmapPtr Filter3x3::apply(BitmapPtr pBmpSource)
+{
+ IntPoint newSize(pBmpSource->getSize().x-2, pBmpSource->getSize().y-2);
+ BitmapPtr pNewBmp(new Bitmap(newSize, pBmpSource->getPixelFormat(),
+ pBmpSource->getName()+"_filtered"));
+
+ for (int y = 0; y < newSize.y; y++) {
+ const unsigned char * pSrc = pBmpSource->getPixels()+y*pBmpSource->getStride();
+ unsigned char * pDest = pNewBmp->getPixels()+y*pNewBmp->getStride();
+ switch (pBmpSource->getBytesPerPixel()) {
+ case 4:
+ convolveLine<Pixel32>(pSrc, pDest, newSize.x, pBmpSource->getStride());
+ break;
+ case 3:
+ convolveLine<Pixel24>(pSrc, pDest, newSize.x, pBmpSource->getStride());
+ break;
+ default:
+ AVG_ASSERT(false);
+ }
+ }
+ return pNewBmp;
+}
+
+}
diff --git a/src/graphics/Filter3x3.h b/src/graphics/Filter3x3.h
new file mode 100644
index 0000000..0ec3881
--- /dev/null
+++ b/src/graphics/Filter3x3.h
@@ -0,0 +1,82 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _Filter3x3_H
+#define _Filter3x3_H
+
+#include "../api.h"
+#include "Filter.h"
+
+#include "Pixel8.h"
+#include "Pixel24.h"
+#include "Pixel32.h"
+
+#include <iostream>
+
+namespace avg {
+
+// Filter that applies a 3x3 kernel to the bitmap.
+class AVG_API Filter3x3 : public Filter
+{
+public:
+ Filter3x3(float Mat[3][3]);
+ virtual ~Filter3x3();
+ virtual BitmapPtr apply(BitmapPtr pBmpSource);
+
+private:
+ template<class PIXEL>
+ void convolveLine(const unsigned char * pSrc, unsigned char * pDest,
+ int lineLen, int stride) const;
+ float m_Mat[3][3];
+};
+
+template<class PIXEL>
+void Filter3x3::convolveLine(const unsigned char * pSrc, unsigned char * pDest,
+ int lineLen, int stride) const
+{
+ PIXEL * pSrcPixel = (PIXEL *)pSrc;
+ PIXEL * pDestPixel = (PIXEL *)pDest;
+ for (int x = 0; x < lineLen; ++x) {
+ float newR = 0;
+ float newG = 0;
+ float newB = 0;
+
+ for (int i = 0; i < 3; i++) {
+ unsigned char * pLineStart = (unsigned char *)pSrcPixel+i*stride;
+ for (int j = 0; j < 3; j++) {
+ PIXEL SrcPixel = *((PIXEL *)pLineStart+j);
+ newR += SrcPixel.getR()*m_Mat[i][j];
+ newG += SrcPixel.getG()*m_Mat[i][j];
+ newB += SrcPixel.getB()*m_Mat[i][j];
+ }
+ }
+ *pDestPixel = PIXEL((unsigned char)newR, (unsigned char)newG,
+ (unsigned char)newB);
+
+ pSrcPixel++;
+ pDestPixel++;
+ }
+}
+
+}
+
+#endif
+
diff --git a/src/graphics/FilterBandpass.cpp b/src/graphics/FilterBandpass.cpp
new file mode 100644
index 0000000..f4a3546
--- /dev/null
+++ b/src/graphics/FilterBandpass.cpp
@@ -0,0 +1,77 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "FilterBandpass.h"
+#include "Filterfill.h"
+#include "Pixel8.h"
+#include "Bitmap.h"
+
+#include <iostream>
+#include <math.h>
+
+using namespace std;
+
+namespace avg {
+
+FilterBandpass::FilterBandpass(float lowWidth, float highWidth)
+ : m_HighpassFilter(highWidth),
+ m_LowpassFilter(lowWidth)
+{
+ m_FilterWidthDiff = int(ceil(highWidth))-int(ceil(lowWidth));
+}
+
+FilterBandpass::~FilterBandpass()
+{
+}
+
+BitmapPtr FilterBandpass::apply(BitmapPtr pBmpSrc)
+{
+ BitmapPtr pLPBmp = m_LowpassFilter.apply(pBmpSrc);
+ BitmapPtr pHPBmp = m_HighpassFilter.apply(pBmpSrc);
+
+ IntPoint Size = pHPBmp->getSize();
+ BitmapPtr pDestBmp = BitmapPtr(new Bitmap(Size, I8, pBmpSrc->getName()));
+
+ int lpStride = pLPBmp->getStride();
+ int hpStride = pHPBmp->getStride();
+ int destStride = pDestBmp->getStride();
+ unsigned char * pLPLine = pLPBmp->getPixels()+m_FilterWidthDiff*lpStride;
+ unsigned char * pHPLine = pHPBmp->getPixels();
+ unsigned char * pDestLine = pDestBmp->getPixels();
+ for (int y = 0; y < Size.y; ++y) {
+ unsigned char * pLPPixel = pLPLine+m_FilterWidthDiff;
+ unsigned char * pHPPixel = pHPLine;
+ unsigned char * pDestPixel = pDestLine;
+ for (int x = 0; x < Size.x; ++x) {
+ *pDestPixel = (int(*pLPPixel)-*pHPPixel)+128;
+ ++pLPPixel;
+ ++pHPPixel;
+ ++pDestPixel;
+ }
+ pLPLine += lpStride;
+ pHPLine += hpStride;
+ pDestLine += destStride;
+ }
+ return pDestBmp;
+}
+
+
+}
diff --git a/src/graphics/FilterBandpass.h b/src/graphics/FilterBandpass.h
new file mode 100644
index 0000000..c36a159
--- /dev/null
+++ b/src/graphics/FilterBandpass.h
@@ -0,0 +1,52 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _FilterBandpass_H_
+#define _FilterBandpass_H_
+
+#include "../api.h"
+#include "Filter.h"
+#include "FilterGauss.h"
+#include "Bitmap.h"
+
+#include <boost/shared_ptr.hpp>
+
+namespace avg {
+
+// XXX: Warning, possibly buggy.
+class AVG_API FilterBandpass: public Filter {
+public:
+ FilterBandpass(float lowWidth, float highWidth);
+ virtual ~FilterBandpass();
+
+ virtual BitmapPtr apply(BitmapPtr pBmpSrc);
+
+private:
+ FilterGauss m_HighpassFilter;
+ FilterGauss m_LowpassFilter;
+ int m_FilterWidthDiff;
+};
+
+typedef boost::shared_ptr<FilterBandpass> FilterBandpassPtr;
+
+}
+
+#endif
diff --git a/src/graphics/FilterBlur.cpp b/src/graphics/FilterBlur.cpp
new file mode 100644
index 0000000..99f48e7
--- /dev/null
+++ b/src/graphics/FilterBlur.cpp
@@ -0,0 +1,69 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "FilterBlur.h"
+#include "Filterfill.h"
+#include "Pixel8.h"
+#include "Bitmap.h"
+
+#include "../base/Exception.h"
+
+#include <iostream>
+#include <math.h>
+
+using namespace std;
+
+namespace avg {
+
+FilterBlur::FilterBlur()
+{
+}
+
+FilterBlur::~FilterBlur()
+{
+}
+
+BitmapPtr FilterBlur::apply(BitmapPtr pBmpSrc)
+{
+ AVG_ASSERT(pBmpSrc->getPixelFormat() == I8);
+
+ IntPoint Size(pBmpSrc->getSize().x-2, pBmpSrc->getSize().y-2);
+ BitmapPtr pDestBmp = BitmapPtr(new Bitmap(Size, I8, pBmpSrc->getName()));
+ int srcStride = pBmpSrc->getStride();
+ int destStride = pDestBmp->getStride();
+ unsigned char * pSrcLine = pBmpSrc->getPixels()+srcStride+1;
+ unsigned char * pDestLine = pDestBmp->getPixels();
+ for (int y = 0; y < Size.y; ++y) {
+ unsigned char * pSrcPixel = pSrcLine;
+ unsigned char * pDestPixel = pDestLine;
+ for (int x = 0; x < Size.x; ++x) {
+ *pDestPixel = (*(pSrcPixel-1) + *(pSrcPixel)*4 + *(pSrcPixel+1)
+ +*(pSrcPixel-srcStride)+*(pSrcPixel+srcStride)+4)/8;
+ ++pSrcPixel;
+ ++pDestPixel;
+ }
+ pSrcLine += srcStride;
+ pDestLine += destStride;
+ }
+ return pDestBmp;
+}
+
+}
diff --git a/src/graphics/FilterBlur.h b/src/graphics/FilterBlur.h
new file mode 100644
index 0000000..f83e51a
--- /dev/null
+++ b/src/graphics/FilterBlur.h
@@ -0,0 +1,45 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _FilterBlur_H_
+#define _FilterBlur_H_
+
+#include "../api.h"
+#include "Filter.h"
+#include "Bitmap.h"
+
+#include <boost/shared_ptr.hpp>
+
+namespace avg {
+
+class AVG_API FilterBlur: public Filter {
+ public:
+ FilterBlur();
+ virtual ~FilterBlur();
+
+ virtual BitmapPtr apply(BitmapPtr pBmpSrc);
+
+ private:
+};
+
+typedef boost::shared_ptr<FilterBlur> FilterBlurPtr;
+}
+#endif
diff --git a/src/graphics/FilterConvol.h b/src/graphics/FilterConvol.h
new file mode 100644
index 0000000..18ebbd6
--- /dev/null
+++ b/src/graphics/FilterConvol.h
@@ -0,0 +1,141 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _FilterConvol_H
+#define _FilterConvol_H
+
+#include "../api.h"
+#include "Filter.h"
+
+#include "Pixel8.h"
+#include "Pixel24.h"
+#include "Pixel32.h"
+
+#include <iostream>
+
+namespace avg {
+
+// Filter that applies a 3x3 kernel to the bitmap.
+template<class Pixel>
+class AVG_API FilterConvol : public Filter
+{
+public:
+ FilterConvol(float *Mat,int n,int m, int offset=0);
+ virtual ~FilterConvol();
+ virtual BitmapPtr apply(BitmapPtr pBmpSource);
+
+private:
+ void convolveLine(const unsigned char* pSrc, unsigned char* pDest,
+ int lineLen, int stride, int offset = 0) const;
+ int m_N;
+ int m_M;
+ int m_Offset;
+ float *m_Mat;
+};
+template <class Pixel>
+void FilterConvol<Pixel>::convolveLine(const unsigned char* pSrc, unsigned char* pDest,
+ int lineLen, int stride, int offset) const
+{
+ Pixel * pSrcPixel = (Pixel *)pSrc;
+ Pixel * pDestPixel = (Pixel *)pDest;
+ for (int x=0; x<lineLen; ++x) {
+ float NewR = 0;
+ float NewG = 0;
+ float NewB = 0;
+
+ for (int i=0; i<m_N; i++) {
+ for (int j=0; j<m_N; j++) {
+ unsigned char * pLineStart = (unsigned char *)pSrcPixel+i*stride;
+ Pixel SrcPixel = *((Pixel *)pLineStart+j);
+ NewR += SrcPixel.getR()*m_Mat[m_N*i+j];
+ NewG += SrcPixel.getG()*m_Mat[m_N*i+j];
+ NewB += SrcPixel.getB()*m_Mat[m_N*i+j];
+ }
+ }
+ *pDestPixel = Pixel((unsigned char)(NewR+offset), (unsigned char)(NewG+offset),
+ (unsigned char)(NewB+offset));
+
+ pSrcPixel++;
+ pDestPixel++;
+ }
+}
+template <>
+void FilterConvol<Pixel8>::convolveLine(const unsigned char* pSrc, unsigned char* pDest,
+ int lineLen, int stride, int offset) const
+{
+ Pixel8 * pSrcPixel = (Pixel8 *)pSrc;
+ Pixel8 * pDestPixel = (Pixel8 *)pDest;
+ for (int x=0; x<lineLen; ++x) {
+ float New = 0;
+
+ for (int i=0; i<m_N; i++) {
+ for (int j=0; j<m_N; j++) {
+ unsigned char * pLineStart = (unsigned char *)pSrcPixel+i*stride;
+ Pixel8 SrcPixel = *((Pixel8 *)pLineStart+j);
+ New += SrcPixel.get()*m_Mat[m_N*i+j];
+ }
+ }
+ *pDestPixel = Pixel8((unsigned char)(New+offset));
+
+ pSrcPixel++;
+ pDestPixel++;
+ }
+}
+template <class Pixel>
+FilterConvol<Pixel>::FilterConvol(float *Mat, int n, int m, int offset)
+ : Filter(),
+ m_N(n),
+ m_M(m),
+ m_Offset(offset)
+{
+ m_Mat = new float[n*m];
+ for (int y=0; y<n; y++) {
+ for (int x=0; x<m; x++) {
+ m_Mat[m_N*y+x] = Mat[m_N*y+x];
+ }
+ }
+}
+template <class Pixel>
+FilterConvol<Pixel>::~FilterConvol()
+{
+ delete[] m_Mat;
+
+}
+template <class Pixel>
+BitmapPtr FilterConvol<Pixel>::apply(BitmapPtr pBmpSource)
+{
+ IntPoint NewSize(pBmpSource->getSize().x-m_N+1, pBmpSource->getSize().y-m_M+1);
+ BitmapPtr pNewBmp(new Bitmap(NewSize, pBmpSource->getPixelFormat(),
+ pBmpSource->getName()+"_filtered"));
+
+ for (int y = 0; y < NewSize.y; y++) {
+ const unsigned char * pSrc = pBmpSource->getPixels()+y*pBmpSource->getStride();
+ unsigned char * pDest = pNewBmp->getPixels()+y*pNewBmp->getStride();
+ convolveLine(pSrc, pDest, NewSize.x, pBmpSource->getStride(), m_Offset);
+ }
+ return pNewBmp;
+}
+
+
+}
+
+#endif
+
diff --git a/src/graphics/FilterDilation.cpp b/src/graphics/FilterDilation.cpp
new file mode 100644
index 0000000..11adaa2
--- /dev/null
+++ b/src/graphics/FilterDilation.cpp
@@ -0,0 +1,71 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "FilterDilation.h"
+
+#include "../base/Exception.h"
+
+#include <algorithm>
+
+using namespace std;
+
+namespace avg {
+
+FilterDilation::FilterDilation()
+ : Filter()
+{
+}
+
+FilterDilation::~FilterDilation()
+{
+
+}
+
+BitmapPtr FilterDilation::apply(BitmapPtr pSrcBmp)
+{
+ AVG_ASSERT(pSrcBmp->getPixelFormat() == I8);
+ IntPoint size = pSrcBmp->getSize();
+ BitmapPtr pDestBmp = BitmapPtr(new Bitmap(size, I8, pSrcBmp->getName()));
+ unsigned char * pSrcLine = pSrcBmp->getPixels();
+ unsigned char * pNextSrcLine;
+ unsigned char * pDestLine = pDestBmp->getPixels();
+ for (int y = 0; y < size.y; y++) {
+ pDestLine = pDestBmp->getPixels()+y*pDestBmp->getStride();
+ unsigned char * pLastSrcLine = pSrcLine;
+ pSrcLine = pSrcBmp->getPixels()+y*pSrcBmp->getStride();
+ if (y < size.y-1) {
+ pNextSrcLine = pSrcBmp->getPixels()+(y+1)*pSrcBmp->getStride();
+ } else {
+ pNextSrcLine = pSrcBmp->getPixels()+y*pSrcBmp->getStride();
+ }
+ pDestLine[0] = max(pSrcLine[0], max(pSrcLine[1],
+ max(pLastSrcLine[0], pNextSrcLine[0])));
+ for (int x = 1; x < size.x-1; x++) {
+ pDestLine[x] = max(pSrcLine[x], max(pSrcLine[x-1], max(pSrcLine[x+1],
+ max(pLastSrcLine[x], pNextSrcLine[x]))));
+ }
+ pDestLine[size.x-1] = max(pSrcLine[size.x-2], max(pSrcLine[size.x-1],
+ max(pLastSrcLine[size.x-1], pNextSrcLine[size.x-1])));
+ }
+ return pDestBmp;
+}
+
+} // namespace
diff --git a/src/graphics/FilterDilation.h b/src/graphics/FilterDilation.h
new file mode 100644
index 0000000..6ccb556
--- /dev/null
+++ b/src/graphics/FilterDilation.h
@@ -0,0 +1,45 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _FilterDilation_H_
+#define _FilterDilation_H_
+
+#include "../api.h"
+#include "Filter.h"
+
+namespace avg {
+
+// Grayscale 4-neighborhood dilation. Replaces each pixel with the maximum of
+// its neighbors.
+class AVG_API FilterDilation : public Filter
+{
+public:
+ FilterDilation();
+ virtual ~FilterDilation();
+ virtual BitmapPtr apply(BitmapPtr pBmp);
+
+private:
+};
+
+}
+
+#endif
+
diff --git a/src/graphics/FilterErosion.cpp b/src/graphics/FilterErosion.cpp
new file mode 100644
index 0000000..72818f6
--- /dev/null
+++ b/src/graphics/FilterErosion.cpp
@@ -0,0 +1,71 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "FilterErosion.h"
+
+#include "../base/Exception.h"
+
+#include <algorithm>
+
+using namespace std;
+
+namespace avg {
+
+FilterErosion::FilterErosion()
+ : Filter()
+{
+}
+
+FilterErosion::~FilterErosion()
+{
+
+}
+
+BitmapPtr FilterErosion::apply(BitmapPtr pSrcBmp)
+{
+ AVG_ASSERT(pSrcBmp->getPixelFormat() == I8);
+ IntPoint size = pSrcBmp->getSize();
+ BitmapPtr pDestBmp = BitmapPtr(new Bitmap(size, I8, pSrcBmp->getName()));
+ unsigned char * pSrcLine = pSrcBmp->getPixels();
+ unsigned char * pNextSrcLine;
+ unsigned char * pDestLine = pDestBmp->getPixels();
+ for (int y = 0; y < size.y; y++) {
+ pDestLine = pDestBmp->getPixels()+y*pDestBmp->getStride();
+ unsigned char * pLastSrcLine = pSrcLine;
+ pSrcLine = pSrcBmp->getPixels()+y*pSrcBmp->getStride();
+ if (y < size.y-1) {
+ pNextSrcLine = pSrcBmp->getPixels()+(y+1)*pSrcBmp->getStride();
+ } else {
+ pNextSrcLine = pSrcBmp->getPixels()+y*pSrcBmp->getStride();
+ }
+ pDestLine[0] = min(pSrcLine[0], min(pSrcLine[1],
+ min(pLastSrcLine[0], pNextSrcLine[0])));
+ for (int x = 1; x < size.x-1; x++) {
+ pDestLine[x] = min(pSrcLine[x], min(pSrcLine[x-1], min(pSrcLine[x+1],
+ min(pLastSrcLine[x], pNextSrcLine[x]))));
+ }
+ pDestLine[size.x-1] = min(pSrcLine[size.x-2], min(pSrcLine[size.x-1],
+ min(pLastSrcLine[size.x-1], pNextSrcLine[size.x-1])));
+ }
+ return pDestBmp;
+}
+
+} // namespace
diff --git a/src/graphics/FilterErosion.h b/src/graphics/FilterErosion.h
new file mode 100644
index 0000000..e3da478
--- /dev/null
+++ b/src/graphics/FilterErosion.h
@@ -0,0 +1,45 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _FilterErosion_H_
+#define _FilterErosion_H_
+
+#include "../api.h"
+#include "Filter.h"
+
+namespace avg {
+
+// Grayscale 4-neighborhood erosion. Replaces each pixel with the minimum of
+// its neighbors.
+class AVG_API FilterErosion : public Filter
+{
+public:
+ FilterErosion();
+ virtual ~FilterErosion();
+ virtual BitmapPtr apply(BitmapPtr pBmp);
+
+private:
+};
+
+}
+
+#endif
+
diff --git a/src/graphics/FilterFastBandpass.cpp b/src/graphics/FilterFastBandpass.cpp
new file mode 100644
index 0000000..0cf6fd2
--- /dev/null
+++ b/src/graphics/FilterFastBandpass.cpp
@@ -0,0 +1,92 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "FilterFastBandpass.h"
+#include "FilterBlur.h"
+#include "Filterfill.h"
+#include "Pixel8.h"
+#include "Bitmap.h"
+
+#include "../base/Exception.h"
+
+#include <cstring>
+#include <iostream>
+#include <sstream>
+
+using namespace std;
+
+namespace avg {
+
+FilterFastBandpass::FilterFastBandpass()
+{
+}
+
+FilterFastBandpass::~FilterFastBandpass()
+{
+}
+
+BitmapPtr FilterFastBandpass::apply(BitmapPtr pBmpSrc)
+{
+ AVG_ASSERT(pBmpSrc->getPixelFormat() == I8);
+ BitmapPtr pBmpDest = BitmapPtr(new Bitmap(pBmpSrc->getSize(), I8,
+ pBmpSrc->getName()));
+ int srcStride = pBmpSrc->getStride();
+ int destStride = pBmpDest->getStride();
+ unsigned char * pSrcLine = pBmpSrc->getPixels()+3*srcStride;
+ unsigned char * pDestLine = pBmpDest->getPixels()+3*destStride;
+ IntPoint size = pBmpDest->getSize();
+ for (int y = 3; y < size.y-3; ++y) {
+ unsigned char * pSrcPixel = pSrcLine+3;
+ unsigned char * pDstPixel = pDestLine;
+ *pDstPixel++ = 128;
+ *pDstPixel++ = 128;
+ *pDstPixel++ = 128;
+ for (int x = 3; x < size.x-3; ++x) {
+ // Convolution Matrix is
+ // 0 0 0 0 0 0 0
+ // 0 -2 0 0 0 -2 0
+ // 0 0 1 0 1 0 0
+ // 0 0 0 4 0 0 0
+ // 0 0 1 0 1 0 0
+ // 0 -2 0 0 0 -2 0
+ // 0 0 0 0 0 0 0
+ *pDstPixel = 128
+ - int(*(pSrcPixel-2*srcStride-2)*2 + *(pSrcPixel-2*srcStride+2)*2 -
+ *(pSrcPixel-srcStride-1) - *(pSrcPixel-1*srcStride+1) -
+ *(pSrcPixel+srcStride-1) - *(pSrcPixel+1*srcStride+1) +
+ *(pSrcPixel+2*srcStride-2)*2 + *(pSrcPixel+2*srcStride+2)*2+2)/4
+ + *pSrcPixel;
+ ++pSrcPixel;
+ ++pDstPixel;
+ }
+ *pDstPixel++ = 128;
+ *pDstPixel++ = 128;
+ *pDstPixel++ = 128;
+ pSrcLine += srcStride;
+ pDestLine += destStride;
+ }
+ // Set top and bottom borders.
+ memset(pBmpDest->getPixels(), 128, destStride*3);
+ memset(pBmpDest->getPixels()+destStride*(size.y-3), 128, destStride*3);
+ return pBmpDest;
+}
+
+}
diff --git a/src/graphics/FilterFastBandpass.h b/src/graphics/FilterFastBandpass.h
new file mode 100644
index 0000000..c3ec10e
--- /dev/null
+++ b/src/graphics/FilterFastBandpass.h
@@ -0,0 +1,46 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _FilterFastBandpass_H_
+#define _FilterFastBandpass_H_
+
+#include "../api.h"
+#include "Filter.h"
+#include "Bitmap.h"
+
+#include <boost/shared_ptr.hpp>
+
+namespace avg {
+
+// This is a fast and sloppy bandpass filter that uses a 7x7 kernel.
+class AVG_API FilterFastBandpass: public Filter{
+ public:
+ FilterFastBandpass();
+ virtual ~FilterFastBandpass();
+
+ virtual BitmapPtr apply(BitmapPtr pBmpSrc);
+
+ private:
+};
+
+typedef boost::shared_ptr<FilterFastBandpass> FilterFastBandpassPtr;
+}
+#endif
diff --git a/src/graphics/FilterFastDownscale.cpp b/src/graphics/FilterFastDownscale.cpp
new file mode 100644
index 0000000..9ed9900
--- /dev/null
+++ b/src/graphics/FilterFastDownscale.cpp
@@ -0,0 +1,98 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "FilterFastDownscale.h"
+#include "Pixeldefs.h"
+
+#include "../base/Exception.h"
+
+#include <iostream>
+
+namespace avg {
+
+using namespace std;
+
+FilterFastDownscale::FilterFastDownscale(int factor)
+ : Filter(),
+ m_Factor(factor)
+{
+}
+
+FilterFastDownscale::~FilterFastDownscale()
+{
+
+}
+
+BitmapPtr FilterFastDownscale::apply(BitmapPtr pBmpSrc)
+{
+ AVG_ASSERT(pBmpSrc->getPixelFormat() == I8);
+ BitmapPtr pBmpDest = BitmapPtr(new Bitmap(pBmpSrc->getSize()/m_Factor, I8,
+ pBmpSrc->getName()));
+ unsigned char * pSrcLine = pBmpSrc->getPixels();
+ unsigned char * pDestLine = pBmpDest->getPixels();
+ IntPoint size = pBmpDest->getSize();
+ int srcStride = pBmpSrc->getStride();
+ for (int y = 0; y < size.y; ++y) {
+ unsigned char * pSrcPixel = pSrcLine;
+ unsigned char * pDstPixel = pDestLine;
+ switch (m_Factor) {
+ case 2:
+ for (int x = 0; x < size.x; ++x) {
+ int dstPixel= int(*pSrcPixel)+int(*(pSrcPixel+1))
+ +int(*(pSrcPixel+srcStride))+int(*(pSrcPixel+srcStride+1));
+ *pDstPixel = (dstPixel+2)/4;
+ pSrcPixel += 2;
+ pDstPixel++;
+ }
+ break;
+ case 3:
+ for (int x = 0; x < size.x; ++x) {
+ int dstPixel= int(*pSrcPixel)+int(*(pSrcPixel+1))+int(*(pSrcPixel+2))
+ +int(*(pSrcPixel+srcStride))+int(*(pSrcPixel+srcStride+1))
+ +int(*(pSrcPixel+srcStride+2))
+ +int(*(pSrcPixel+srcStride*2))+int(*(pSrcPixel+srcStride*2+1))
+ +int(*(pSrcPixel+srcStride*2+2));
+ *pDstPixel = (dstPixel+4)/9;
+ pSrcPixel += 3;
+ pDstPixel++;
+ }
+ break;
+ default:
+ for (int x = 0; x < size.x; ++x) {
+ int dstPixel=0;
+ for (int y1 = 0; y1 < m_Factor; y1++) {
+ for (int x1 = 0; x1 < m_Factor; x1++) {
+ dstPixel+= (int)(*(pSrcPixel+srcStride*y1+x1));
+ }
+ }
+ *pDstPixel = (dstPixel+(m_Factor*m_Factor)/2)/(m_Factor*m_Factor);
+ pSrcPixel += m_Factor;
+ pDstPixel++;
+ }
+ break;
+ }
+ pSrcLine = pSrcLine + pBmpSrc->getStride()*m_Factor;
+ pDestLine = pDestLine + pBmpDest->getStride();
+ }
+ return pBmpDest;
+}
+
+} // namespace
diff --git a/src/graphics/FilterFastDownscale.h b/src/graphics/FilterFastDownscale.h
new file mode 100644
index 0000000..dc4ada8
--- /dev/null
+++ b/src/graphics/FilterFastDownscale.h
@@ -0,0 +1,47 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _FilterFastDownscale_H_
+#define _FilterFastDownscale_H_
+
+#include "../api.h"
+#include "Filter.h"
+#include "Bitmap.h"
+
+namespace avg {
+
+// Returns a bitmap that is scaled downward by Scale in both x and y directions
+// using simple box sampling.
+class AVG_API FilterFastDownscale : public Filter
+{
+public:
+ FilterFastDownscale(int Factor);
+ virtual ~FilterFastDownscale();
+ virtual BitmapPtr apply(BitmapPtr pBmpSource) ;
+
+private:
+ int m_Factor;
+};
+
+} // namespace
+
+#endif
+
diff --git a/src/graphics/FilterFloodfill.h b/src/graphics/FilterFloodfill.h
new file mode 100644
index 0000000..f4a7ebf
--- /dev/null
+++ b/src/graphics/FilterFloodfill.h
@@ -0,0 +1,165 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+
+#ifndef _FilterFloodfill_H_
+#define _FilterFloodfill_H_
+
+#include "../api.h"
+#include "Filter.h"
+
+#include "../base/GLMHelper.h"
+
+#include <stack>
+
+namespace avg {
+
+struct Segment {
+ Segment(int iy, int ix1, int ix2, int idy)
+ : y(iy),
+ x1(ix1),
+ x2(ix2),
+ dy(idy)
+ {}
+
+ int y;
+ int x1;
+ int x2;
+ int dy;
+};
+
+class ColorTester {
+public:
+ ColorTester(Pixel32 color)
+ : m_Color(color)
+ {
+ }
+
+ bool operator()(unsigned char * pPixel)
+ {
+ return *(Pixel32*)(pPixel) == m_Color;
+ }
+
+private:
+ Pixel32 m_Color;
+};
+
+// Flood fill filter. The comparison functor used to determine whether a pixel
+// belongs to the area is passed as template parameter. Pixels in the flooded area
+// are made transparent.
+template<class PixelTester>
+class AVG_TEMPLATE_API FilterFloodfill : public Filter
+{
+public:
+ FilterFloodfill(PixelTester tester, const IntPoint& pt);
+ virtual ~FilterFloodfill();
+
+ virtual void applyInPlace(BitmapPtr pBmp) ;
+
+private:
+ void pushSeg(BitmapPtr pBmp, std::stack<Segment>& segments,
+ int y, int x1, int x2, int dy);
+ void setTransparent(unsigned char* pPixel);
+
+ PixelTester m_Tester;
+ IntPoint m_Pt;
+};
+
+template<class PixelTester>
+FilterFloodfill<PixelTester>::FilterFloodfill(PixelTester tester, const IntPoint& pt)
+ : m_Tester(tester),
+ m_Pt(pt)
+{
+}
+
+template<class PixelTester>
+FilterFloodfill<PixelTester>::~FilterFloodfill()
+{
+}
+
+template<class PixelTester>
+void FilterFloodfill<PixelTester>::applyInPlace(BitmapPtr pBmp)
+{
+ // Algorithm from Graphics Gems I, pp 296ff.
+ std::stack<Segment> segments;
+ unsigned char * pPixels = (unsigned char *)(pBmp->getPixels());
+ int stride = pBmp->getStride();
+ pushSeg(pBmp, segments, m_Pt.y, m_Pt.x, m_Pt.x, 1);
+ pushSeg(pBmp, segments, m_Pt.y+1, m_Pt.x, m_Pt.x, -1);
+ int l;
+ while (!segments.empty()) {
+ Segment seg = segments.top();
+ seg.y += seg.dy;
+ segments.pop();
+ int x = seg.x1;
+ unsigned char * pCurPixel = pPixels+x*4+seg.y*stride;
+ for (; x>=0 && m_Tester(pCurPixel); x--) {
+ setTransparent(pCurPixel);
+ pCurPixel-=4;
+ }
+ if (x >= seg.x1) {
+ goto skip;
+ }
+ l = x+1;
+ if (l<seg.x1) {
+ pushSeg(pBmp, segments, seg.y, l, seg.x1-1, -seg.dy);
+ }
+ x = seg.x1+1;
+ do {
+ pCurPixel = pPixels+x*4+seg.y*stride;
+ for (; x<pBmp->getSize().x && m_Tester(pCurPixel); x++) {
+ setTransparent(pCurPixel);
+ pCurPixel+=4;
+ }
+ pushSeg(pBmp, segments, seg.y, l, x-1, seg.dy);
+ if (x>seg.x2+1) {
+ pushSeg(pBmp, segments, seg.y, seg.x2+1, x-1, -seg.dy);
+ }
+skip: x++;
+ pCurPixel = pPixels+x*4+seg.y*stride;
+ for (; x<=seg.x2 && !m_Tester(pCurPixel); x++) {
+ pCurPixel+=4;
+ }
+ l = x;
+ } while (x<=seg.x2);
+
+ }
+}
+
+template<class PixelTester>
+void FilterFloodfill<PixelTester>::pushSeg(BitmapPtr pBmp, std::stack<Segment>& segments,
+ int y, int x1, int x2, int dy)
+{
+ if (y+dy >= 0 && y+dy < pBmp->getSize().y) {
+ segments.push(Segment(y, x1, x2, dy));
+ }
+}
+
+template<class PixelTester>
+void FilterFloodfill<PixelTester>::setTransparent(unsigned char* pPixel)
+{
+ *(Pixel32*)(pPixel) = Pixel32(0,0,255,0);
+}
+
+
+}
+
+#endif
diff --git a/src/graphics/FilterGauss.cpp b/src/graphics/FilterGauss.cpp
new file mode 100644
index 0000000..ddfe086
--- /dev/null
+++ b/src/graphics/FilterGauss.cpp
@@ -0,0 +1,203 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "FilterGauss.h"
+#include "Filterfill.h"
+#include "Pixel8.h"
+#include "Bitmap.h"
+
+#include "../base/MathHelper.h"
+#include "../base/Exception.h"
+
+#include <iostream>
+#include <math.h>
+
+using namespace std;
+
+namespace avg {
+
+FilterGauss::FilterGauss(float radius)
+ : m_Radius(radius)
+{
+ calcKernel();
+}
+
+FilterGauss::~FilterGauss()
+{
+}
+
+BitmapPtr FilterGauss::apply(BitmapPtr pBmpSrc)
+{
+ AVG_ASSERT(pBmpSrc->getPixelFormat() == I8);
+ int intRadius = int(ceil(m_Radius));
+
+ // Convolve in x-direction
+ IntPoint tempSize(pBmpSrc->getSize().x-2*intRadius, pBmpSrc->getSize().y);
+ BitmapPtr pTempBmp = BitmapPtr(new Bitmap(tempSize, I8, pBmpSrc->getName()));
+ int srcStride = pBmpSrc->getStride();
+ int tempStride = pTempBmp->getStride();
+ unsigned char * pSrcLine = pBmpSrc->getPixels();
+ unsigned char * pTempLine = pTempBmp->getPixels();
+ for (int y = 0; y < tempSize.y; ++y) {
+ unsigned char * pSrcPixel = pSrcLine+intRadius;
+ unsigned char * pTempPixel = pTempLine;
+ switch (intRadius) {
+ case 3:
+ for (int x = 0; x < tempSize.x; ++x) {
+ *pTempPixel = (*(pSrcPixel-3)*m_Kernel[0] +
+ *(pSrcPixel-2)*m_Kernel[1] +
+ *(pSrcPixel-1)*m_Kernel[2] +
+ *(pSrcPixel)*m_Kernel[3] +
+ *(pSrcPixel+1)*m_Kernel[4] +
+ *(pSrcPixel+2)*m_Kernel[5] +
+ *(pSrcPixel+3)*m_Kernel[6])/256;
+ ++pSrcPixel;
+ ++pTempPixel;
+ }
+ break;
+ case 2:
+ for (int x = 0; x < tempSize.x; ++x) {
+ *pTempPixel = (*(pSrcPixel-2)*m_Kernel[0] +
+ *(pSrcPixel-1)*m_Kernel[1] +
+ *(pSrcPixel)*m_Kernel[2] +
+ *(pSrcPixel+1)*m_Kernel[3] +
+ *(pSrcPixel+2)*m_Kernel[4])/256;
+ ++pSrcPixel;
+ ++pTempPixel;
+ }
+ break;
+ case 1:
+ for (int x = 0; x < tempSize.x; ++x) {
+ *pTempPixel = (*(pSrcPixel-1)*m_Kernel[0] +
+ *(pSrcPixel)*m_Kernel[1] +
+ *(pSrcPixel+1)*m_Kernel[2])/256;
+ ++pSrcPixel;
+ ++pTempPixel;
+ }
+ break;
+ default:
+ // This is _really_ slow!
+ for (int x = 0; x < tempSize.x; ++x) {
+ *pTempPixel = 0;
+ unsigned char * pKernelPixel = pSrcPixel-intRadius;
+ for (int w=0; w <= intRadius*2; ++w) {
+ *pTempPixel += ((*pKernelPixel)*m_Kernel[w])/256;
+ pKernelPixel++;
+ }
+ ++pSrcPixel;
+ ++pTempPixel;
+ }
+ }
+ pSrcLine += srcStride;
+ pTempLine += tempStride;
+ }
+
+ // Convolve in y-direction
+ IntPoint destSize(tempSize.x, tempSize.y-2*intRadius);
+ BitmapPtr pDestBmp = BitmapPtr(new Bitmap(destSize, I8, pBmpSrc->getName()));
+ int destStride = pDestBmp->getStride();
+ pTempLine = pTempBmp->getPixels()+intRadius*tempStride;
+ unsigned char * pDestLine = pDestBmp->getPixels();
+ for (int y = 0; y < destSize.y; ++y) {
+ unsigned char * pTempPixel = pTempLine;
+ unsigned char * pDestPixel = pDestLine;
+ switch (intRadius) {
+ case 3:
+ for (int x = 0; x < destSize.x; ++x) {
+ *pDestPixel = (*(pTempPixel-3*tempStride)*m_Kernel[0] +
+ *(pTempPixel-2*tempStride)*m_Kernel[1] +
+ *(pTempPixel-1*tempStride)*m_Kernel[2] +
+ *(pTempPixel)*m_Kernel[3] +
+ *(pTempPixel+1*tempStride)*m_Kernel[4] +
+ *(pTempPixel+2*tempStride)*m_Kernel[5] +
+ *(pTempPixel+3*tempStride)*m_Kernel[6])/256;
+ ++pTempPixel;
+ ++pDestPixel;
+ }
+ break;
+ case 2:
+ for (int x = 0; x < destSize.x; ++x) {
+ *pDestPixel = (*(pTempPixel-2*tempStride)*m_Kernel[0] +
+ *(pTempPixel-1*tempStride)*m_Kernel[1] +
+ *(pTempPixel)*m_Kernel[2] +
+ *(pTempPixel+1*tempStride)*m_Kernel[3] +
+ *(pTempPixel+2*tempStride)*m_Kernel[4])/256;
+ ++pTempPixel;
+ ++pDestPixel;
+ }
+ break;
+ case 1:
+ for (int x = 0; x < destSize.x; ++x) {
+ *pDestPixel = (*(pTempPixel-1*tempStride)*m_Kernel[0] +
+ *(pTempPixel)*m_Kernel[1] +
+ *(pTempPixel+1*tempStride)*m_Kernel[2])/256;
+ ++pTempPixel;
+ ++pDestPixel;
+ }
+ break;
+ default:
+ // This is _really_ slow!
+ for (int x = 0; x < tempSize.x; ++x) {
+ *pDestPixel = 0;
+ unsigned char * pKernelPixel = pTempPixel-intRadius*tempStride;
+ for (int w = 0; w <= intRadius*2; ++w) {
+ *pDestPixel += (*pKernelPixel*m_Kernel[w])/256;
+ pKernelPixel += tempStride;
+ }
+ ++pTempPixel;
+ ++pDestPixel;
+ }
+ }
+ pTempLine += tempStride;
+ pDestLine += destStride;
+ }
+ return pDestBmp;
+}
+
+void FilterGauss::dumpKernel()
+{
+ cerr << "Gauss, radius " << m_Radius << endl;
+ cerr << " Kernel width: " << m_KernelWidth << endl;
+ for (int i = 0; i < m_KernelWidth; ++i) {
+ cerr << " " << m_Kernel[i] << endl;
+ }
+}
+
+void FilterGauss::calcKernel()
+{
+ float FloatKernel[15];
+ float Sum = 0;
+ int intRadius = int(ceil(m_Radius));
+ m_KernelWidth = intRadius*2+1;
+ for (int i = 0; i <= intRadius; ++i) {
+ FloatKernel[intRadius+i] = float(exp(-i*i/m_Radius-1)/sqrt(2*PI));
+ FloatKernel[intRadius-i] = FloatKernel[intRadius+i];
+ Sum += FloatKernel[intRadius+i];
+ if (i != 0) {
+ Sum += FloatKernel[intRadius-i];
+ }
+ }
+ for (int i = 0; i < m_KernelWidth; ++i) {
+ m_Kernel[i] = int(FloatKernel[i]*256/Sum+0.5);
+ }
+}
+
+}
diff --git a/src/graphics/FilterGauss.h b/src/graphics/FilterGauss.h
new file mode 100644
index 0000000..e06c96a
--- /dev/null
+++ b/src/graphics/FilterGauss.h
@@ -0,0 +1,52 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _FilterGauss_H_
+#define _FilterGauss_H_
+
+#include "../api.h"
+#include "Filter.h"
+#include "Bitmap.h"
+
+#include <boost/shared_ptr.hpp>
+
+namespace avg {
+
+class AVG_API FilterGauss: public Filter{
+ public:
+ FilterGauss(float Radius);
+ virtual ~FilterGauss();
+
+ virtual BitmapPtr apply(BitmapPtr pBmpSrc);
+
+ void dumpKernel();
+
+ private:
+ void calcKernel();
+
+ float m_Radius;
+ int m_KernelWidth;
+ int m_Kernel[15];
+};
+
+typedef boost::shared_ptr<FilterGauss> FilterGaussPtr;
+}
+#endif
diff --git a/src/graphics/FilterGetAlpha.cpp b/src/graphics/FilterGetAlpha.cpp
new file mode 100644
index 0000000..764c47d
--- /dev/null
+++ b/src/graphics/FilterGetAlpha.cpp
@@ -0,0 +1,66 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "FilterGetAlpha.h"
+#include "Pixeldefs.h"
+
+#include "../base/Exception.h"
+
+#include <iostream>
+
+namespace avg {
+
+using namespace std;
+
+FilterGetAlpha::FilterGetAlpha()
+ : Filter()
+{
+}
+
+FilterGetAlpha::~FilterGetAlpha()
+{
+
+}
+
+BitmapPtr FilterGetAlpha::apply(BitmapPtr pBmpSrc)
+{
+ PixelFormat pf = pBmpSrc->getPixelFormat();
+ AVG_ASSERT(pf == R8G8B8A8 || pf == B8G8R8A8);
+ BitmapPtr pBmpDest = BitmapPtr(new Bitmap(pBmpSrc->getSize(), I8,
+ pBmpSrc->getName()+"alpha"));
+ unsigned char * pSrcLine = pBmpSrc->getPixels();
+ unsigned char * pDestLine = pBmpDest->getPixels();
+ IntPoint size = pBmpDest->getSize();
+ for (int y = 0; y < size.y; ++y) {
+ unsigned char * pSrcPixel = pSrcLine;
+ unsigned char * pDstPixel = pDestLine;
+ for (int x = 0; x < size.x; ++x) {
+ *pDstPixel = pSrcPixel[ALPHAPOS];
+ pSrcPixel += 4;
+ ++pDstPixel;
+ }
+ pSrcLine = pSrcLine + pBmpSrc->getStride();
+ pDestLine = pDestLine + pBmpDest->getStride();
+ }
+ return pBmpDest;
+}
+
+}
diff --git a/src/graphics/FilterGetAlpha.h b/src/graphics/FilterGetAlpha.h
new file mode 100644
index 0000000..4782036
--- /dev/null
+++ b/src/graphics/FilterGetAlpha.h
@@ -0,0 +1,45 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _FilterGetAlpha_H_
+#define _FilterGetAlpha_H_
+
+#include "../api.h"
+#include "Filter.h"
+#include "Bitmap.h"
+
+namespace avg {
+
+// Extracts the alpha channel of a 32 bpp bitmap.
+class AVG_API FilterGetAlpha : public Filter
+{
+public:
+ FilterGetAlpha();
+ virtual ~FilterGetAlpha();
+ virtual BitmapPtr apply(BitmapPtr pBmpSource);
+
+private:
+};
+
+}
+
+#endif
+
diff --git a/src/graphics/FilterHighpass.cpp b/src/graphics/FilterHighpass.cpp
new file mode 100644
index 0000000..d2c2679
--- /dev/null
+++ b/src/graphics/FilterHighpass.cpp
@@ -0,0 +1,94 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "FilterHighpass.h"
+#include "Filterfill.h"
+#include "Pixel8.h"
+#include "Bitmap.h"
+
+#include "../base/Exception.h"
+
+#include <cstring>
+#include <iostream>
+#include <sstream>
+
+using namespace std;
+
+namespace avg {
+
+FilterHighpass::FilterHighpass()
+{
+}
+
+FilterHighpass::~FilterHighpass()
+{
+}
+
+BitmapPtr FilterHighpass::apply(BitmapPtr pBmpSrc)
+{
+ AVG_ASSERT(pBmpSrc->getPixelFormat() == I8);
+ BitmapPtr pBmpDest = BitmapPtr(new Bitmap(pBmpSrc->getSize(), I8,
+ pBmpSrc->getName()));
+ int srcStride = pBmpSrc->getStride();
+ int destStride = pBmpDest->getStride();
+ unsigned char * pSrcLine = pBmpSrc->getPixels()+3*srcStride;
+ unsigned char * pDestLine = pBmpDest->getPixels()+3*destStride;
+ IntPoint size = pBmpDest->getSize();
+ for (int y = 3; y < size.y-3; ++y) {
+ unsigned char * pSrcPixel = pSrcLine+3;
+ unsigned char * pDstPixel = pDestLine;
+ *pDstPixel++ = 128;
+ *pDstPixel++ = 128;
+ *pDstPixel++ = 128;
+ for (int x = 3; x < size.x-3; ++x) {
+ // Convolution Matrix is
+ // -1 0 0 0 -1
+ // 0 -1 0 -1 0
+ // 0 0 8 0 0
+ // 0 -1 0 -1 0
+ // -1 0 0 0 -1
+ // Actually, it's 7x7, but you get the idea.
+ *pDstPixel = 128 - int(*(pSrcPixel-3*srcStride-3)
+ + *(pSrcPixel-3*srcStride+3) + *(pSrcPixel+3*srcStride-3)
+ + *(pSrcPixel+3*srcStride+3))/16;
+ *pDstPixel +=
+ - int(*(pSrcPixel-2*srcStride-2) + *(pSrcPixel-2*srcStride+2) +
+ *(pSrcPixel-srcStride-1) + *(pSrcPixel-1*srcStride+1) +
+ *(pSrcPixel+srcStride-1) + *(pSrcPixel+1*srcStride+1) +
+ *(pSrcPixel+2*srcStride-2) + *(pSrcPixel+2*srcStride+2))/16
+ + *(pSrcPixel)*3/4;
+
+ ++pSrcPixel;
+ ++pDstPixel;
+ }
+ *pDstPixel++ = 128;
+ *pDstPixel++ = 128;
+ *pDstPixel++ = 128;
+ pSrcLine += srcStride;
+ pDestLine += destStride;
+ }
+ // Set top and bottom borders.
+ memset(pBmpDest->getPixels(), 128, destStride*3);
+ memset(pBmpDest->getPixels()+destStride*(size.y-3), 128, destStride*3);
+ return pBmpDest;
+}
+
+}
diff --git a/src/graphics/FilterHighpass.h b/src/graphics/FilterHighpass.h
new file mode 100644
index 0000000..5392e1c
--- /dev/null
+++ b/src/graphics/FilterHighpass.h
@@ -0,0 +1,46 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _FilterHighpass_H_
+#define _FilterHighpass_H_
+
+#include "../api.h"
+#include "Filter.h"
+#include "Bitmap.h"
+
+#include <boost/shared_ptr.hpp>
+
+namespace avg {
+
+// This is a highpass filter that uses a 7x7 kernel.
+class AVG_API FilterHighpass: public Filter{
+ public:
+ FilterHighpass();
+ virtual ~FilterHighpass();
+
+ virtual BitmapPtr apply(BitmapPtr pBmpSrc);
+
+ private:
+};
+
+typedef boost::shared_ptr<FilterHighpass> FilterHighpassPtr;
+}
+#endif
diff --git a/src/graphics/FilterIntensity.cpp b/src/graphics/FilterIntensity.cpp
new file mode 100644
index 0000000..3ffdd30
--- /dev/null
+++ b/src/graphics/FilterIntensity.cpp
@@ -0,0 +1,56 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "FilterIntensity.h"
+
+#include "../base/Exception.h"
+
+#include <math.h>
+
+namespace avg {
+
+FilterIntensity::FilterIntensity(int offset, float factor)
+ : m_Offset(offset),
+ m_Factor(factor)
+{
+}
+
+FilterIntensity::~FilterIntensity()
+{
+}
+
+void FilterIntensity::applyInPlace(BitmapPtr pBmp)
+{
+ AVG_ASSERT(pBmp->getPixelFormat() == I8);
+ unsigned char * pLine = pBmp->getPixels();
+ IntPoint size = pBmp->getSize();
+ for (int y = 0; y < size.y; ++y) {
+ unsigned char * pPixel = pLine;
+ for (int x = 0; x < size.x; ++x) {
+ *pPixel = (unsigned char)((*pPixel+m_Offset)*m_Factor);
+ ++pPixel;
+ }
+ pLine = pLine + pBmp->getStride();
+ }
+}
+
+}
+
diff --git a/src/graphics/FilterIntensity.h b/src/graphics/FilterIntensity.h
new file mode 100644
index 0000000..2428435
--- /dev/null
+++ b/src/graphics/FilterIntensity.h
@@ -0,0 +1,45 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _FilterIntensity_H_
+#define _FilterIntensity_H_
+
+#include "../api.h"
+#include "Filter.h"
+
+namespace avg {
+
+class AVG_API FilterIntensity : public Filter
+{
+public:
+ FilterIntensity(int offset, float factor);
+ virtual ~FilterIntensity();
+ virtual void applyInPlace(BitmapPtr pBmp) ;
+
+private:
+ int m_Offset;
+ float m_Factor;
+};
+
+} // namespace
+
+#endif
+
diff --git a/src/graphics/FilterMask.cpp b/src/graphics/FilterMask.cpp
new file mode 100644
index 0000000..d5fa6d0
--- /dev/null
+++ b/src/graphics/FilterMask.cpp
@@ -0,0 +1,84 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "FilterMask.h"
+#include "Pixeldefs.h"
+
+#include "../base/Exception.h"
+
+#include <stdio.h>
+
+namespace avg {
+
+using namespace std;
+
+FilterMask::FilterMask(BitmapPtr pMaskBmp)
+ : Filter(),
+ m_pMaskBmp(pMaskBmp)
+{
+ AVG_ASSERT(m_pMaskBmp->getPixelFormat() == I8);
+}
+
+FilterMask::~FilterMask()
+{
+
+}
+
+void FilterMask::applyInPlace(BitmapPtr pBmp)
+{
+ IntPoint size = pBmp->getSize();
+ AVG_ASSERT(size == m_pMaskBmp->getSize());
+ for (int y = 0; y < size.y; y++) {
+ unsigned char * pMaskLine = m_pMaskBmp->getPixels()+y*m_pMaskBmp->getStride();
+ unsigned char * pLine = pBmp->getPixels()+y*pBmp->getStride();
+ switch (pBmp->getBytesPerPixel()) {
+ case 4:
+ for (int x = 0; x < size.x; x++) {
+ unsigned char src = *(pMaskLine+x);
+ unsigned char * pPixel = pLine + x*4;
+ *pPixel = (*pPixel*src)/255;
+ *(pPixel+1) = (*(pPixel+1)*src)/255;
+ *(pPixel+2) = (*(pPixel+2)*src)/255;
+ }
+ break;
+ case 3:
+ for (int x = 0; x < size.x; x++) {
+ unsigned char src = *(pMaskLine+x);
+ unsigned char * pPixel = pLine + x*3;
+ *pPixel = (*pPixel*src)/255;
+ *(pPixel+1) = (*(pPixel+1)*src)/255;
+ *(pPixel+2) = (*(pPixel+2)*src)/255;
+ }
+ break;
+ case 1:
+ for (int x = 0; x < size.x; x++) {
+ unsigned char src = *(pMaskLine+x);
+ unsigned char * pPixel = pLine + x;
+ *pPixel = (*pPixel*src)/255;
+ }
+ break;
+ default:
+ AVG_ASSERT(false);
+ }
+ }
+}
+
+}
diff --git a/src/graphics/FilterMask.h b/src/graphics/FilterMask.h
new file mode 100644
index 0000000..226409f
--- /dev/null
+++ b/src/graphics/FilterMask.h
@@ -0,0 +1,45 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _FilterMask_H
+#define _FilterMask_H
+
+#include "../api.h"
+#include "Filter.h"
+
+namespace avg {
+
+// Filter that applies a greyscale mask to an image.
+class AVG_API FilterMask : public Filter
+{
+public:
+ FilterMask(BitmapPtr pMaskBmp);
+ virtual ~FilterMask();
+ virtual void applyInPlace(BitmapPtr pBmp) ;
+
+private:
+ BitmapPtr m_pMaskBmp;
+};
+
+}
+
+#endif
+
diff --git a/src/graphics/FilterNormalize.cpp b/src/graphics/FilterNormalize.cpp
new file mode 100644
index 0000000..7a27684
--- /dev/null
+++ b/src/graphics/FilterNormalize.cpp
@@ -0,0 +1,55 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "FilterNormalize.h"
+#include "FilterIntensity.h"
+
+#include <math.h>
+
+namespace avg {
+
+FilterNormalize::FilterNormalize(int stride)
+ : m_Stride(stride)
+{
+}
+
+FilterNormalize::~FilterNormalize()
+{
+}
+
+void FilterNormalize::applyInPlace(BitmapPtr pBmp)
+{
+ int min;
+ int max;
+ pBmp->getMinMax(m_Stride, min, max);
+ if (m_Stride > 1) {
+ min -= 2;
+ max += 2;
+ }
+ float factor = 255.f/(max-min);
+ if (factor > 10) {
+ factor = 10;
+ }
+ FilterIntensity(-min, factor).applyInPlace(pBmp);
+}
+
+}
+
diff --git a/src/graphics/FilterNormalize.h b/src/graphics/FilterNormalize.h
new file mode 100644
index 0000000..1947215
--- /dev/null
+++ b/src/graphics/FilterNormalize.h
@@ -0,0 +1,44 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _FilterNormalize_H_
+#define _FilterNormalize_H_
+
+#include "../api.h"
+#include "Filter.h"
+
+namespace avg {
+
+class AVG_API FilterNormalize : public Filter
+{
+public:
+ FilterNormalize(int stride);
+ virtual ~FilterNormalize();
+ virtual void applyInPlace(BitmapPtr pBmp) ;
+
+private:
+ int m_Stride;
+};
+
+} // namespace
+
+#endif
+
diff --git a/src/graphics/FilterResizeBilinear.cpp b/src/graphics/FilterResizeBilinear.cpp
new file mode 100644
index 0000000..750e07a
--- /dev/null
+++ b/src/graphics/FilterResizeBilinear.cpp
@@ -0,0 +1,77 @@
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "FilterResizeBilinear.h"
+#include "Bitmap.h"
+#include "TwoPassScale.h"
+
+#include "../base/Exception.h"
+
+namespace avg {
+
+FilterResizeBilinear::FilterResizeBilinear(const IntPoint& newSize)
+ : m_NewSize(newSize)
+{
+}
+
+BitmapPtr FilterResizeBilinear::apply(BitmapPtr pBmpSrc)
+{
+ int bpp = pBmpSrc->getBytesPerPixel();
+ AVG_ASSERT(bpp==4 || bpp==3 || bpp==1);
+
+ BitmapPtr pBmpDest = BitmapPtr(new Bitmap(m_NewSize,
+ pBmpSrc->getPixelFormat(), pBmpSrc->getName()+"_resized"));
+
+ BilinearContribDef f(0.64);
+ switch (bpp) {
+ case 4:
+ {
+ TwoPassScale<CDataRGBA_UBYTE> sS(f);
+ sS.Scale((CDataRGBA_UBYTE::PixelClass *) pBmpSrc->getPixels(),
+ pBmpSrc->getSize(), pBmpSrc->getStride(),
+ (CDataRGBA_UBYTE::PixelClass *) pBmpDest->getPixels(),
+ pBmpDest->getSize(), pBmpDest->getStride());
+ }
+ break;
+ case 3:
+ {
+ TwoPassScale <CDataRGB_UBYTE> sS(f);
+ sS.Scale((CDataRGB_UBYTE::PixelClass *) pBmpSrc->getPixels(),
+ pBmpSrc->getSize(), pBmpSrc->getStride(),
+ (CDataRGB_UBYTE::PixelClass *) pBmpDest->getPixels(),
+ pBmpDest->getSize(), pBmpDest->getStride());
+ }
+ break;
+ case 1:
+ {
+ TwoPassScale <CDataA_UBYTE> sS(f);
+ sS.Scale((CDataA_UBYTE::PixelClass *) pBmpSrc->getPixels(),
+ pBmpSrc->getSize(), pBmpSrc->getStride(),
+ (CDataA_UBYTE::PixelClass *) pBmpDest->getPixels(),
+ pBmpDest->getSize(), pBmpDest->getStride());
+ }
+ break;
+ default:
+ AVG_ASSERT(false);
+ }
+ return pBmpDest;
+}
+
+}
+
diff --git a/src/graphics/FilterResizeBilinear.h b/src/graphics/FilterResizeBilinear.h
new file mode 100644
index 0000000..11069d8
--- /dev/null
+++ b/src/graphics/FilterResizeBilinear.h
@@ -0,0 +1,39 @@
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _FilterResizeBilinear_h_
+#define _FilterResizeBilinear_h_
+
+#include "Filter.h"
+
+namespace avg {
+
+class AVG_API FilterResizeBilinear : public Filter
+{
+public:
+ FilterResizeBilinear(const IntPoint& newSize);
+ virtual BitmapPtr apply(BitmapPtr pBmpSrc);
+
+private:
+ IntPoint m_NewSize;
+};
+
+}
+
+#endif
diff --git a/src/graphics/FilterResizeGaussian.cpp b/src/graphics/FilterResizeGaussian.cpp
new file mode 100644
index 0000000..aae6416
--- /dev/null
+++ b/src/graphics/FilterResizeGaussian.cpp
@@ -0,0 +1,78 @@
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "FilterResizeGaussian.h"
+#include "Bitmap.h"
+#include "TwoPassScale.h"
+
+#include "../base/Exception.h"
+
+namespace avg {
+
+FilterResizeGaussian::FilterResizeGaussian(const IntPoint& newSize, float radius)
+ : m_NewSize(newSize),
+ m_Radius(radius)
+{
+}
+
+BitmapPtr FilterResizeGaussian::apply(BitmapPtr pBmpSrc)
+{
+ int bpp = pBmpSrc->getBytesPerPixel();
+ AVG_ASSERT(bpp==4 || bpp==3 || bpp==1);
+
+ BitmapPtr pBmpDest = BitmapPtr(new Bitmap(m_NewSize,
+ pBmpSrc->getPixelFormat(), pBmpSrc->getName()+"_resized"));
+
+ GaussianContribDef f(m_Radius);
+ switch (bpp) {
+ case 4:
+ {
+ TwoPassScale<CDataRGBA_UBYTE> sS(f);
+ sS.Scale((CDataRGBA_UBYTE::PixelClass *) pBmpSrc->getPixels(),
+ pBmpSrc->getSize(), pBmpSrc->getStride(),
+ (CDataRGBA_UBYTE::PixelClass *) pBmpDest->getPixels(),
+ pBmpDest->getSize(), pBmpDest->getStride());
+ }
+ break;
+ case 3:
+ {
+ TwoPassScale <CDataRGB_UBYTE> sS(f);
+ sS.Scale((CDataRGB_UBYTE::PixelClass *) pBmpSrc->getPixels(),
+ pBmpSrc->getSize(), pBmpSrc->getStride(),
+ (CDataRGB_UBYTE::PixelClass *) pBmpDest->getPixels(),
+ pBmpDest->getSize(), pBmpDest->getStride());
+ }
+ break;
+ case 1:
+ {
+ TwoPassScale <CDataA_UBYTE> sS(f);
+ sS.Scale((CDataA_UBYTE::PixelClass *) pBmpSrc->getPixels(),
+ pBmpSrc->getSize(), pBmpSrc->getStride(),
+ (CDataA_UBYTE::PixelClass *) pBmpDest->getPixels(),
+ pBmpDest->getSize(), pBmpDest->getStride());
+ }
+ break;
+ default:
+ AVG_ASSERT(false);
+ }
+ return pBmpDest;
+}
+
+}
+
diff --git a/src/graphics/FilterResizeGaussian.h b/src/graphics/FilterResizeGaussian.h
new file mode 100644
index 0000000..274aa30
--- /dev/null
+++ b/src/graphics/FilterResizeGaussian.h
@@ -0,0 +1,41 @@
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _FilterResizeGaussian_H_
+#define _FilterResizeGaussian_H_
+
+#include "Filter.h"
+#include "Bitmap.h"
+
+namespace avg {
+
+class AVG_API FilterResizeGaussian : public Filter
+{
+public:
+ FilterResizeGaussian(const IntPoint& newSize, float radius);
+ virtual BitmapPtr apply(BitmapPtr pBmpSrc);
+
+private:
+ IntPoint m_NewSize;
+ float m_Radius;
+};
+
+}
+#endif
+
diff --git a/src/graphics/FilterThreshold.cpp b/src/graphics/FilterThreshold.cpp
new file mode 100644
index 0000000..a6fddde
--- /dev/null
+++ b/src/graphics/FilterThreshold.cpp
@@ -0,0 +1,61 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "FilterThreshold.h"
+#include "Pixeldefs.h"
+
+#include "../base/Exception.h"
+
+#include <stdio.h>
+
+namespace avg {
+
+using namespace std;
+
+FilterThreshold::FilterThreshold(int threshold)
+ : Filter(),
+ m_Threshold(threshold)
+{
+}
+
+FilterThreshold::~FilterThreshold()
+{
+
+}
+
+void FilterThreshold::applyInPlace(BitmapPtr pBmp)
+{
+ IntPoint size = pBmp->getSize();
+ AVG_ASSERT(pBmp->getPixelFormat() == I8);
+ for (int y = 0; y < size.y; y++) {
+ unsigned char * pLine = pBmp->getPixels()+y*pBmp->getStride();
+ for (int x = 0; x < size.x; x++) {
+ unsigned char * pPixel = pLine + x;
+ if (*pPixel >= m_Threshold) {
+ *pPixel = 255;
+ } else {
+ *pPixel = 0;
+ }
+ }
+ }
+}
+
+}
diff --git a/src/graphics/FilterThreshold.h b/src/graphics/FilterThreshold.h
new file mode 100644
index 0000000..274fc94
--- /dev/null
+++ b/src/graphics/FilterThreshold.h
@@ -0,0 +1,44 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _FilterThreshold_H
+#define _FilterThreshold_H
+
+#include "../api.h"
+#include "Filter.h"
+
+namespace avg {
+
+class AVG_API FilterThreshold : public Filter
+{
+public:
+ FilterThreshold(int threshold);
+ virtual ~FilterThreshold();
+ virtual void applyInPlace(BitmapPtr pBmp) ;
+
+private:
+ int m_Threshold;
+};
+
+}
+
+#endif
+
diff --git a/src/graphics/FilterUnmultiplyAlpha.cpp b/src/graphics/FilterUnmultiplyAlpha.cpp
new file mode 100644
index 0000000..09bf2ff
--- /dev/null
+++ b/src/graphics/FilterUnmultiplyAlpha.cpp
@@ -0,0 +1,96 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "FilterUnmultiplyAlpha.h"
+#include "Pixeldefs.h"
+
+#include "../base/Exception.h"
+#include "../base/ScopeTimer.h"
+
+namespace avg {
+
+FilterUnmultiplyAlpha::FilterUnmultiplyAlpha()
+ : Filter()
+{
+}
+
+FilterUnmultiplyAlpha::~FilterUnmultiplyAlpha()
+{
+
+}
+
+static ProfilingZoneID ProfilingZone("FilterUnmultiplyAlpha");
+
+void FilterUnmultiplyAlpha::applyInPlace(BitmapPtr pBmp)
+{
+ ScopeTimer Timer(ProfilingZone);
+ AVG_ASSERT(pBmp->getBytesPerPixel() == 4);
+ IntPoint size = pBmp->getSize();
+ for (int y = 0; y < size.y; y++) {
+ unsigned char * pPixel = pBmp->getPixels() + y*pBmp->getStride();
+ for (int x = 0; x < size.x; x++) {
+ int alpha = *(pPixel+ALPHAPOS);
+ if (alpha != 0) {
+ *(pPixel+REDPOS) = (int(*(pPixel+REDPOS))*255)/alpha;
+ *(pPixel+GREENPOS) = (int(*(pPixel+GREENPOS))*255)/alpha;
+ *(pPixel+BLUEPOS) = (int(*(pPixel+BLUEPOS))*255)/alpha;
+ }
+ pPixel += 4;
+ }
+ }
+ // The color values of transparent pixels are used in bilinear texture
+ // filtering in certain conditions. To avoid artifacts, we transfer the
+ // color from a neighboring non-transparent pixel.
+ for (int y = 1; y < size.y-1; y++) {
+ int stride = pBmp->getStride();
+ unsigned char * pPixel = pBmp->getPixels() + y*stride;
+ for (int x = 1; x < size.x-1; x++) {
+ int alpha = *(pPixel+ALPHAPOS);
+ if (alpha == 0) {
+ unsigned char * pSrcPixel = pPixel;
+ if (*(pPixel+4+ALPHAPOS) != 0) {
+ pSrcPixel = pPixel+4;
+ } else if (*(pPixel+stride+4+ALPHAPOS) != 0) {
+ pSrcPixel = pPixel+stride+4;
+ } else if (*(pPixel+stride+ALPHAPOS) != 0) {
+ pSrcPixel = pPixel+stride;
+ } else if (*(pPixel+stride-4+ALPHAPOS) != 0) {
+ pSrcPixel = pPixel+stride-4;
+ } else if (*(pPixel-4+ALPHAPOS) != 0) {
+ pSrcPixel = pPixel-4;
+ } else if (*(pPixel-stride-4+ALPHAPOS) != 0) {
+ pSrcPixel = pPixel-stride-4;
+ } else if (*(pPixel-stride+ALPHAPOS) != 0) {
+ pSrcPixel = pPixel-stride;
+ } else if (*(pPixel-stride+4+ALPHAPOS) != 0) {
+ pSrcPixel = pPixel-stride+4;
+ }
+
+ *(pPixel+REDPOS) = *(pSrcPixel+REDPOS);
+ *(pPixel+GREENPOS) = *(pSrcPixel+GREENPOS);
+ *(pPixel+BLUEPOS) = *(pSrcPixel+BLUEPOS);
+ }
+ pPixel += 4;
+ }
+ }
+}
+
+}
diff --git a/src/graphics/FilterUnmultiplyAlpha.h b/src/graphics/FilterUnmultiplyAlpha.h
new file mode 100644
index 0000000..110785b
--- /dev/null
+++ b/src/graphics/FilterUnmultiplyAlpha.h
@@ -0,0 +1,43 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _FilterUnmultiplyAlpha_H
+#define _FilterUnmultiplyAlpha_H
+
+#include "../api.h"
+#include "Filter.h"
+
+namespace avg {
+
+class AVG_API FilterUnmultiplyAlpha : public Filter
+{
+public:
+ FilterUnmultiplyAlpha();
+ virtual ~FilterUnmultiplyAlpha();
+ virtual void applyInPlace(BitmapPtr pBmp) ;
+
+private:
+};
+
+}
+
+#endif
+
diff --git a/src/graphics/Filtercolorize.cpp b/src/graphics/Filtercolorize.cpp
new file mode 100644
index 0000000..c549f2d
--- /dev/null
+++ b/src/graphics/Filtercolorize.cpp
@@ -0,0 +1,145 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "Filtercolorize.h"
+#include "Filtergrayscale.h"
+#include "Pixel24.h"
+
+#include "../base/Exception.h"
+
+namespace avg {
+
+// From Foley, van Dam p. 596 incl. addendum fixes.
+unsigned char hls_value(float n1, float n2, float hue)
+{
+ if (hue>360)
+ hue-=360;
+ if (hue<0)
+ hue+=360;
+
+ float rv;
+ if (hue<60)
+ rv = n1+(n2-n1)*hue/60;
+ else if (hue<180)
+ rv = n2;
+ else if (hue<240)
+ rv = n1+(n2-n1)*(240-hue)/60;
+ else
+ rv = n1;
+
+ return (unsigned char)(rv*255);
+}
+
+Pixel24 hls2rgb (float h, float l, float s)
+{
+ float m1, m2;
+ l /= 255;
+ s /= 100;
+ // Warning: Foley, van Dam has a typo on the next line!
+ m2 = (l<=0.5f)?(l*(1.0f+s)):(l+s-l*s);
+ m1 = 2.0f*l-m2;
+ if (s<0.001f) {
+ return Pixel24((unsigned char)(l*255), (unsigned char)(l*255),
+ (unsigned char)(l*255));
+ } else {
+ return Pixel24(hls_value(m1,m2,h+120),
+ hls_value(m1,m2,h),
+ hls_value(m1,m2,h-120));
+ }
+}
+
+FilterColorize::FilterColorize(float hue, float saturation)
+ : m_Hue(hue),
+ m_Saturation(saturation)
+{
+}
+
+FilterColorize::~FilterColorize()
+{
+
+}
+
+void FilterColorize::applyInPlace(BitmapPtr pBmp)
+{
+ BitmapPtr pTempBmp (FilterGrayscale().apply(pBmp));
+ Pixel32 colorTable[256];
+ for (int i=0; i<256; i++) {
+ colorTable[i] = hls2rgb(m_Hue, float(i), m_Saturation);
+ }
+
+ unsigned char * pSrcLine = pTempBmp->getPixels();
+ unsigned char * pDestLine = pBmp->getPixels();
+ IntPoint size = pTempBmp->getSize();
+ for (int y = 0; y < size.y; ++y) {
+ unsigned char * pSrcPixel = pSrcLine;
+ switch (pBmp->getPixelFormat()) {
+ case R8G8B8A8:
+ case R8G8B8X8:
+ {
+ Pixel32 * pDestPixel = (Pixel32 *)pDestLine;
+ for (int x = 0; x < size.x; ++x) {
+ *pDestPixel = colorTable[*pSrcPixel];
+ ++pSrcPixel;
+ ++pDestPixel;
+ }
+ }
+ break;
+ case R8G8B8:
+ {
+ Pixel24 * pDestPixel = (Pixel24 *)pDestLine;
+ for (int x = 0; x < size.x; ++x) {
+ *pDestPixel = colorTable[*pSrcPixel];
+ ++pSrcPixel;
+ ++pDestPixel;
+ }
+ }
+ break;
+ case B8G8R8A8:
+ case B8G8R8X8:
+ {
+ Pixel32 * pDestPixel = (Pixel32 *)pDestLine;
+ for (int x = 0; x < size.x; ++x) {
+ *pDestPixel = colorTable[*pSrcPixel];
+ ++pSrcPixel;
+ ++pDestPixel;
+ }
+ }
+ break;
+ case B8G8R8:
+ {
+ Pixel24 * pDestPixel = (Pixel24 *)pDestLine;
+ for (int x = 0; x < size.x; ++x) {
+ *pDestPixel = colorTable[*pSrcPixel];
+ ++pSrcPixel;
+ ++pDestPixel;
+ }
+ }
+ break;
+ default:
+ AVG_ASSERT(false);
+ }
+ pSrcLine = pSrcLine + pTempBmp->getStride();
+ pDestLine = pDestLine + pBmp->getStride();
+ }
+}
+
+}
+
diff --git a/src/graphics/Filtercolorize.h b/src/graphics/Filtercolorize.h
new file mode 100644
index 0000000..6689dce
--- /dev/null
+++ b/src/graphics/Filtercolorize.h
@@ -0,0 +1,48 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _Filtercolorize_H_
+#define _Filtercolorize_H_
+
+#include "../api.h"
+#include "Filter.h"
+
+namespace avg {
+
+// Filter that colorizes a bitmap given a hue and saturation. Corresponds
+// loosely to the photoshop hue/saturation control when set to 'colorize'.
+// The range of hue is 0..359, the range of saturation is 0..100.
+class AVG_API FilterColorize : public Filter
+{
+public:
+ FilterColorize(float hue, float saturation);
+ virtual ~FilterColorize();
+ virtual void applyInPlace(BitmapPtr pBmp) ;
+
+private:
+ float m_Hue;
+ float m_Saturation;
+};
+
+} // namespace
+
+#endif
+
diff --git a/src/graphics/Filterfill.h b/src/graphics/Filterfill.h
new file mode 100644
index 0000000..5e9fdbe
--- /dev/null
+++ b/src/graphics/Filterfill.h
@@ -0,0 +1,68 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+
+#ifndef _Filterfill_H_
+#define _Filterfill_H_
+
+#include "../api.h"
+#include "Filter.h"
+#include "Filterfillrect.h"
+
+#include "../base/Rect.h"
+
+namespace avg {
+
+// Filter that fills a bitmap with a color.
+template<class PixelC>
+class AVG_TEMPLATE_API FilterFill : public Filter
+{
+public:
+ FilterFill (const PixelC& Color);
+ virtual ~FilterFill();
+ virtual void applyInPlace(BitmapPtr pBmp) ;
+
+private:
+ PixelC m_Color;
+};
+
+template<class PixelC>
+FilterFill<PixelC>::FilterFill(const PixelC& Color)
+ : m_Color (Color)
+{
+}
+
+template<class PixelC>
+FilterFill<PixelC>::~FilterFill()
+{
+}
+
+template<class PixelC>
+void FilterFill<PixelC>::applyInPlace(BitmapPtr pBmp)
+{
+ FilterFillRect<PixelC> RectFilter(
+ IntRect(0, 0, pBmp->getSize().x, pBmp->getSize().y), m_Color);
+ RectFilter.applyInPlace(pBmp);
+}
+
+}
+
+#endif
diff --git a/src/graphics/Filterfillrect.h b/src/graphics/Filterfillrect.h
new file mode 100644
index 0000000..c4614e8
--- /dev/null
+++ b/src/graphics/Filterfillrect.h
@@ -0,0 +1,75 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+
+#ifndef _Filterfillrect_H_
+#define _Filterfillrect_H_
+
+#include "../api.h"
+#include "Filter.h"
+#include "../base/Rect.h"
+
+namespace avg {
+
+// Filter that fills a rectangle in a Bitmap with a color.
+template<class PixelC>
+ class AVG_TEMPLATE_API FilterFillRect: public Filter
+{
+public:
+ FilterFillRect (IntRect Rect, const PixelC& Color);
+ virtual ~FilterFillRect();
+ virtual void applyInPlace(BitmapPtr pBmp) ;
+
+private:
+ PixelC m_Color;
+ IntRect m_Rect;
+};
+
+template<class PixelC>
+FilterFillRect<PixelC>::FilterFillRect (IntRect Rect, const PixelC& Color)
+{
+ m_Rect = Rect;
+ m_Color = Color;
+}
+
+template<class PixelC>
+FilterFillRect<PixelC>::~FilterFillRect ()
+{
+}
+
+template<class PixelC>
+void FilterFillRect<PixelC>::applyInPlace (BitmapPtr pBmp)
+{
+ int Stride = pBmp->getStride()/pBmp->getBytesPerPixel();
+ PixelC * pLine = (PixelC*)(pBmp->getPixels())+(m_Rect.tl.y*Stride);
+ PixelC * pPixel;
+ for (int y=m_Rect.tl.y; y<m_Rect.br.y; ++y) {
+ pPixel = pLine+m_Rect.tl.x;
+ for (int x=m_Rect.tl.x; x<m_Rect.br.x; ++x) {
+ *pPixel = m_Color;
+ pPixel++;
+ }
+ pLine += Stride;
+ }
+}
+
+}
+#endif
diff --git a/src/graphics/Filterflip.cpp b/src/graphics/Filterflip.cpp
new file mode 100644
index 0000000..d677270
--- /dev/null
+++ b/src/graphics/Filterflip.cpp
@@ -0,0 +1,54 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "Filterflip.h"
+
+#include <cstring>
+
+namespace avg {
+
+FilterFlip::FilterFlip() : Filter()
+{
+}
+
+FilterFlip::~FilterFlip()
+{
+}
+
+BitmapPtr FilterFlip::apply(BitmapPtr pBmpSource)
+{
+ IntPoint size = pBmpSource->getSize();
+ BitmapPtr pBmpDest(new Bitmap(size, pBmpSource->getPixelFormat(),
+ pBmpSource->getName()));
+
+ unsigned char* pSrcLine = pBmpSource->getPixels();
+ unsigned char* pDestLine = pBmpDest->getPixels()+(size.y-1)*pBmpDest->getStride();
+ int lineLen = pBmpSource->getBytesPerPixel()*size.x;
+
+ for (int y = 0; y < size.y; y++) {
+ memcpy(pDestLine, pSrcLine, lineLen);
+ pSrcLine += pBmpSource->getStride();
+ pDestLine -= pBmpDest->getStride();
+ }
+ return pBmpDest;
+}
+
+} // namespace
diff --git a/src/graphics/Filterflip.h b/src/graphics/Filterflip.h
new file mode 100644
index 0000000..775afa2
--- /dev/null
+++ b/src/graphics/Filterflip.h
@@ -0,0 +1,43 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+
+#ifndef _Filterflip_H_
+#define _Filterflip_H_
+
+#include "../api.h"
+#include "Filter.h"
+
+namespace avg {
+
+// Flips a bitmap upside-down
+class AVG_API FilterFlip: public Filter
+{
+public:
+ FilterFlip();
+ virtual ~FilterFlip();
+ virtual BitmapPtr apply(BitmapPtr pBmpSource) ;
+};
+
+} // namespace
+
+#endif
+
diff --git a/src/graphics/FilterflipX.cpp b/src/graphics/FilterflipX.cpp
new file mode 100644
index 0000000..f67b462
--- /dev/null
+++ b/src/graphics/FilterflipX.cpp
@@ -0,0 +1,78 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "FilterflipX.h"
+#include "Pixel32.h"
+
+#include "../base/Exception.h"
+
+namespace avg {
+
+FilterFlipX::FilterFlipX()
+ : Filter()
+{
+}
+
+FilterFlipX::~FilterFlipX()
+{
+}
+
+BitmapPtr FilterFlipX::apply(BitmapPtr pBmpSource)
+{
+ IntPoint Size = pBmpSource->getSize();
+ BitmapPtr pBmpDest(new Bitmap(Size, pBmpSource->getPixelFormat(),
+ pBmpSource->getName()));
+
+ unsigned char* pSrcLine = pBmpSource->getPixels();
+ unsigned char* pDestLine = pBmpDest->getPixels();
+
+ for (int y = 0; y < Size.y; y++) {
+ switch (pBmpSource->getBytesPerPixel()) {
+ case 1: {
+ unsigned char * pSrc = pSrcLine;
+ unsigned char * pDest = pDestLine+Size.x-1;
+ for (int x = 0; x < Size.x; x++) {
+ *pDest = *pSrc;
+ pSrc++;
+ pDest--;
+ }
+ }
+ break;
+ case 4: {
+ Pixel32 * pSrc = (Pixel32*)pSrcLine;
+ Pixel32 * pDest = (Pixel32*)pDestLine+Size.x-1;
+ for (int x = 0; x < Size.x; x++) {
+ *pDest = *pSrc;
+ pSrc++;
+ pDest--;
+ }
+ }
+ break;
+ default:
+ AVG_ASSERT(false);
+ }
+ pSrcLine += pBmpSource->getStride();
+ pDestLine += pBmpDest->getStride();
+ }
+ return pBmpDest;
+}
+
+}
diff --git a/src/graphics/FilterflipX.h b/src/graphics/FilterflipX.h
new file mode 100644
index 0000000..9e62023
--- /dev/null
+++ b/src/graphics/FilterflipX.h
@@ -0,0 +1,43 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+
+#ifndef _FilterflipX_H_
+#define _FilterflipX_H_
+
+#include "../api.h"
+#include "Filter.h"
+
+namespace avg {
+
+// Flips a bitmap right-left
+class AVG_API FilterFlipX: public Filter
+{
+public:
+ FilterFlipX();
+ virtual ~FilterFlipX();
+ virtual BitmapPtr apply(BitmapPtr pBmpSource);
+};
+
+}
+
+#endif
+
diff --git a/src/graphics/Filterfliprgb.cpp b/src/graphics/Filterfliprgb.cpp
new file mode 100644
index 0000000..8a0e8c3
--- /dev/null
+++ b/src/graphics/Filterfliprgb.cpp
@@ -0,0 +1,92 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "Filterfliprgb.h"
+#include "Pixeldefs.h"
+
+#include "../base/Exception.h"
+
+#include <iostream>
+
+using namespace std;
+
+namespace avg {
+
+FilterFlipRGB::FilterFlipRGB(bool bChangePF)
+ : Filter(),
+ m_bChangePF(bChangePF)
+{
+}
+
+FilterFlipRGB::~FilterFlipRGB()
+{
+
+}
+
+void FilterFlipRGB::applyInPlace(BitmapPtr pBmp)
+{
+ AVG_ASSERT(pBmp->getBytesPerPixel() >= 3);
+ PixelFormat PF = pBmp->getPixelFormat();
+ if (m_bChangePF) {
+ switch(PF) {
+ case B8G8R8A8:
+ pBmp->setPixelFormat(R8G8B8A8);
+ break;
+ case B8G8R8X8:
+ pBmp->setPixelFormat(R8G8B8X8);
+ break;
+ case R8G8B8A8:
+ pBmp->setPixelFormat(B8G8R8A8);
+ break;
+ case R8G8B8X8:
+ pBmp->setPixelFormat(B8G8R8X8);
+ break;
+ case R8G8B8:
+ pBmp->setPixelFormat(B8G8R8);
+ break;
+ case B8G8R8:
+ pBmp->setPixelFormat(R8G8B8);
+ break;
+ default:
+ // Only 24 and 32 bpp supported.
+ AVG_ASSERT(false);
+ }
+ }
+ IntPoint size = pBmp->getSize();
+ for (int y = 0; y < size.y; y++) {
+ unsigned char * pLine = pBmp->getPixels()+y*pBmp->getStride();
+ if (pBmp->getBytesPerPixel() == 4) {
+ for (int x = 0; x < size.x; x++) {
+ unsigned char tmp = pLine[x*4+REDPOS];
+ pLine[x*4+REDPOS] = pLine[x*4+BLUEPOS];
+ pLine[x*4+BLUEPOS] = tmp;
+ }
+ } else {
+ for (int x = 0; x < size.x; x++) {
+ unsigned char tmp = pLine[x*3+REDPOS];
+ pLine[x*3+REDPOS] = pLine[x*3+BLUEPOS];
+ pLine[x*3+BLUEPOS] = tmp;
+ }
+ }
+ }
+}
+
+} // namespace
diff --git a/src/graphics/Filterfliprgb.h b/src/graphics/Filterfliprgb.h
new file mode 100644
index 0000000..11e6640
--- /dev/null
+++ b/src/graphics/Filterfliprgb.h
@@ -0,0 +1,45 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _Filterfliprgb_H
+#define _Filterfliprgb_H
+
+#include "../api.h"
+#include "Filter.h"
+
+namespace avg {
+
+// Filter that flips the R and B components of a bitmap.
+class AVG_API FilterFlipRGB : public Filter
+{
+public:
+ FilterFlipRGB(bool bChangePF = true);
+ virtual ~FilterFlipRGB();
+ virtual void applyInPlace(BitmapPtr pBmp) ;
+
+private:
+ bool m_bChangePF;
+};
+
+}
+
+#endif
+
diff --git a/src/graphics/Filterfliprgba.cpp b/src/graphics/Filterfliprgba.cpp
new file mode 100644
index 0000000..6a92ec9
--- /dev/null
+++ b/src/graphics/Filterfliprgba.cpp
@@ -0,0 +1,56 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "Filterfliprgba.h"
+#include "Pixeldefs.h"
+
+#include "../base/Exception.h"
+
+namespace avg {
+
+FilterFlipRGBA::FilterFlipRGBA()
+ : Filter()
+{
+}
+
+FilterFlipRGBA::~FilterFlipRGBA()
+{
+
+}
+
+void FilterFlipRGBA::applyInPlace(BitmapPtr pBmp)
+{
+ AVG_ASSERT(pBmp->getBytesPerPixel() == 4);
+ IntPoint size = pBmp->getSize();
+ for (int y = 0; y < size.y; y++) {
+ unsigned char * pLine = pBmp->getPixels()+y*pBmp->getStride();
+ for (int x = 0; x < size.x; x++) {
+ unsigned char tmp = pLine[x*4+REDPOS];
+ pLine[x*4+REDPOS] = pLine[x*4+ALPHAPOS];
+ pLine[x*4+ALPHAPOS] = tmp;
+ tmp = pLine[x*4+BLUEPOS];
+ pLine[x*4+BLUEPOS] = pLine[x*4+GREENPOS];
+ pLine[x*4+GREENPOS] = tmp;
+ }
+ }
+}
+
+} // namespace
diff --git a/src/graphics/Filterfliprgba.h b/src/graphics/Filterfliprgba.h
new file mode 100644
index 0000000..9722eec
--- /dev/null
+++ b/src/graphics/Filterfliprgba.h
@@ -0,0 +1,44 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _Filterfliprgba_H
+#define _Filterfliprgba_H
+
+#include "../api.h"
+#include "Filter.h"
+
+namespace avg {
+
+// Filter that flips the R and B components of a bitmap.
+class AVG_API FilterFlipRGBA : public Filter
+{
+public:
+ FilterFlipRGBA();
+ virtual ~FilterFlipRGBA();
+ virtual void applyInPlace(BitmapPtr pBmp) ;
+
+private:
+};
+
+}
+
+#endif
+
diff --git a/src/graphics/Filterflipuv.cpp b/src/graphics/Filterflipuv.cpp
new file mode 100644
index 0000000..29aab89
--- /dev/null
+++ b/src/graphics/Filterflipuv.cpp
@@ -0,0 +1,53 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "Filterflipuv.h"
+#include "Pixeldefs.h"
+
+#include "../base/Exception.h"
+
+namespace avg {
+
+FilterFlipUV::FilterFlipUV()
+ : Filter()
+{
+}
+
+FilterFlipUV::~FilterFlipUV()
+{
+
+}
+
+void FilterFlipUV::applyInPlace(BitmapPtr pBmp)
+{
+ AVG_ASSERT(pBmp->getPixelFormat() == YCbCr422);
+ IntPoint size = pBmp->getSize();
+ for (int y = 0; y < size.y; y++) {
+ unsigned char * pLine = pBmp->getPixels()+y*pBmp->getStride();
+ for (int x = 0; x < size.x/2; x++) {
+ unsigned char tmp = pLine[x*4+1];
+ pLine[x*4+1] = pLine[x*4+3];
+ pLine[x*4+3] = tmp;
+ }
+ }
+}
+
+} // namespace
diff --git a/src/graphics/Filterflipuv.h b/src/graphics/Filterflipuv.h
new file mode 100644
index 0000000..2dcfa88
--- /dev/null
+++ b/src/graphics/Filterflipuv.h
@@ -0,0 +1,44 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _Filterflipuv_H
+#define _Filterflipuv_H
+
+#include "../api.h"
+#include "Filter.h"
+
+namespace avg {
+
+// Filter that flips the U and V components of a YCbCr422 bitmap.
+class AVG_API FilterFlipUV : public Filter
+{
+public:
+ FilterFlipUV();
+ virtual ~FilterFlipUV();
+ virtual void applyInPlace(BitmapPtr pBmp) ;
+
+private:
+};
+
+}
+
+#endif
+
diff --git a/src/graphics/Filtergrayscale.cpp b/src/graphics/Filtergrayscale.cpp
new file mode 100644
index 0000000..58a2336
--- /dev/null
+++ b/src/graphics/Filtergrayscale.cpp
@@ -0,0 +1,80 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "Filtergrayscale.h"
+
+#include "Pixeldefs.h"
+
+#include <iostream>
+
+namespace avg {
+
+using namespace std;
+
+FilterGrayscale::FilterGrayscale()
+ : Filter()
+{
+}
+
+FilterGrayscale::~FilterGrayscale()
+{
+
+}
+
+BitmapPtr FilterGrayscale::apply(BitmapPtr pBmpSrc)
+{
+ PixelFormat PF = pBmpSrc->getPixelFormat();
+ if (PF == I8) {
+ return BitmapPtr(new Bitmap(*pBmpSrc));
+ }
+ BitmapPtr pBmpDest = BitmapPtr(new Bitmap(pBmpSrc->getSize(), I8,
+ pBmpSrc->getName()));
+ unsigned char * pSrcLine = pBmpSrc->getPixels();
+ unsigned char * pDestLine = pBmpDest->getPixels();
+ IntPoint size = pBmpDest->getSize();
+ int bpp = pBmpSrc->getBytesPerPixel();
+ for (int y = 0; y<size.y; ++y) {
+ unsigned char * pSrcPixel = pSrcLine;
+ unsigned char * pDstPixel = pDestLine;
+ for (int x = 0; x < size.x; ++x) {
+ // For the coefficients used, see http://www.inforamp.net/~poynton/
+ // Appoximations curtesy of libpng :-).
+ if (PF == R8G8B8A8 || PF == R8G8B8X8 || PF == R8G8B8) {
+ *pDstPixel = (unsigned char)((pSrcPixel[REDPOS]*54+
+ pSrcPixel[GREENPOS]*183+
+ pSrcPixel[BLUEPOS]*19)/256);
+ pSrcPixel += bpp;
+ ++pDstPixel;
+ } else {
+ *pDstPixel = (unsigned char)((pSrcPixel[BLUEPOS]*54+
+ pSrcPixel[GREENPOS]*183+
+ pSrcPixel[REDPOS]*19)/256);
+ pSrcPixel += bpp;
+ ++pDstPixel;
+ }
+ }
+ pSrcLine = pSrcLine + pBmpSrc->getStride();
+ pDestLine = pDestLine + pBmpDest->getStride();
+ }
+ return pBmpDest;
+}
+
+}
diff --git a/src/graphics/Filtergrayscale.h b/src/graphics/Filtergrayscale.h
new file mode 100644
index 0000000..79e2ad6
--- /dev/null
+++ b/src/graphics/Filtergrayscale.h
@@ -0,0 +1,45 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _Filtergrayscale_H_
+#define _Filtergrayscale_H_
+
+#include "../api.h"
+#include "Filter.h"
+#include "Bitmap.h"
+
+namespace avg {
+
+// Creates a grayscale version of a 32 bpp bitmap.
+class AVG_API FilterGrayscale : public Filter
+{
+public:
+ FilterGrayscale();
+ virtual ~FilterGrayscale();
+ virtual BitmapPtr apply(BitmapPtr pBmpSource);
+
+private:
+};
+
+} // namespace
+
+#endif
+
diff --git a/src/graphics/GL/gl.h b/src/graphics/GL/gl.h
new file mode 100644
index 0000000..39ae7f3
--- /dev/null
+++ b/src/graphics/GL/gl.h
@@ -0,0 +1,2262 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.3
+ *
+ * Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef __gl_h_
+#define __gl_h_
+
+#if defined(USE_MGL_NAMESPACE)
+#include "../../api.h"
+#include "gl_mangle.h"
+#endif
+
+
+/**********************************************************************
+ * Begin system-specific stuff. Do not do any of this when building
+ * for SciTech SNAP, as this is all done before this header file is
+ * included.
+ */
+#if !defined(__SCITECH_SNAP__)
+
+#if defined(__BEOS__)
+#include <stdlib.h> /* to get some BeOS-isms */
+#endif
+
+#if !defined(OPENSTEP) && (defined(NeXT) || defined(NeXT_PDO))
+#define OPENSTEP
+#endif
+
+#if defined(_WIN32) && !defined(__WIN32__) && !defined(__CYGWIN__)
+#define __WIN32__
+#endif
+
+#if !defined(OPENSTEP) && (defined(__WIN32__) && !defined(__CYGWIN__))
+# if (defined(_MSC_VER) || defined(__MINGW32__)) && defined(BUILD_GL32) /* tag specify we're building mesa as a DLL */
+# define GLAPI __declspec(dllexport)
+# elif (defined(_MSC_VER) || defined(__MINGW32__)) && defined(_DLL) /* tag specifying we're building for DLL runtime support */
+# define GLAPI __declspec(dllimport)
+# else /* for use with static link lib build of Win32 edition only */
+# define GLAPI extern
+# endif /* _STATIC_MESA support */
+# define GLAPIENTRY __stdcall
+#elif defined(__CYGWIN__) && defined(USE_OPENGL32) /* use native windows opengl32 */
+# define GLAPI extern
+# define GLAPIENTRY __stdcall
+#elif defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 303
+# define GLAPI __attribute__((visibility("default")))
+# define GLAPIENTRY
+#endif /* WIN32 && !CYGWIN */
+
+#if (defined(__BEOS__) && defined(__POWERPC__)) || defined(__QUICKDRAW__)
+# define PRAGMA_EXPORT_SUPPORTED 1
+#endif
+
+/*
+ * WINDOWS: Include windows.h here to define APIENTRY.
+ * It is also useful when applications include this file by
+ * including only glut.h, since glut.h depends on windows.h.
+ * Applications needing to include windows.h with parms other
+ * than "WIN32_LEAN_AND_MEAN" may include windows.h before
+ * glut.h or gl.h.
+ */
+#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__)
+#define WIN32_LEAN_AND_MEAN 1
+#include <windows.h>
+#endif
+
+#if defined(_WIN32) && !defined(_WINGDI_) && !defined(_GNU_H_WINDOWS32_DEFINES) && !defined(OPENSTEP) && !defined(__CYGWIN__)
+#include <GL/mesa_wgl.h>
+#endif
+
+#if defined(macintosh) && PRAGMA_IMPORT_SUPPORTED
+#pragma import on
+#endif
+
+#ifndef GLAPI
+#define GLAPI extern
+#endif
+
+#ifndef GLAPIENTRY
+#define GLAPIENTRY
+#endif
+
+#ifndef APIENTRY
+#define APIENTRY GLAPIENTRY
+#endif
+
+/* "P" suffix to be used for a pointer to a function */
+#ifndef APIENTRYP
+#define APIENTRYP APIENTRY *
+#endif
+
+#ifndef GLAPIENTRYP
+#define GLAPIENTRYP GLAPIENTRY *
+#endif
+
+#ifdef CENTERLINE_CLPP
+#define signed
+#endif
+
+#if defined(PRAGMA_EXPORT_SUPPORTED)
+#pragma export on
+#endif
+
+#endif /* !__SCITECH_SNAP__ */
+/*
+ * End system-specific stuff.
+ **********************************************************************/
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+
+#define GL_VERSION_1_1 1
+#define GL_VERSION_1_2 1
+#define GL_VERSION_1_3 1
+#define GL_ARB_imaging 1
+
+
+/*
+ * Datatypes
+ */
+typedef unsigned int GLenum;
+typedef unsigned char GLboolean;
+typedef unsigned int GLbitfield;
+typedef void GLvoid;
+typedef signed char GLbyte; /* 1-byte signed */
+typedef short GLshort; /* 2-byte signed */
+typedef int GLint; /* 4-byte signed */
+typedef unsigned char GLubyte; /* 1-byte unsigned */
+typedef unsigned short GLushort; /* 2-byte unsigned */
+typedef unsigned int GLuint; /* 4-byte unsigned */
+typedef int GLsizei; /* 4-byte signed */
+typedef float GLfloat; /* single precision float */
+typedef float GLclampf; /* single precision float in [0,1] */
+typedef double GLdouble; /* double precision float */
+typedef double GLclampd; /* double precision float in [0,1] */
+
+
+
+/*
+ * Constants
+ */
+
+/* Boolean values */
+#define GL_FALSE 0x0
+#define GL_TRUE 0x1
+
+/* Data types */
+#define GL_BYTE 0x1400
+#define GL_UNSIGNED_BYTE 0x1401
+#define GL_SHORT 0x1402
+#define GL_UNSIGNED_SHORT 0x1403
+#define GL_INT 0x1404
+#define GL_UNSIGNED_INT 0x1405
+#define GL_FLOAT 0x1406
+#define GL_2_BYTES 0x1407
+#define GL_3_BYTES 0x1408
+#define GL_4_BYTES 0x1409
+#define GL_DOUBLE 0x140A
+
+/* Primitives */
+#define GL_POINTS 0x0000
+#define GL_LINES 0x0001
+#define GL_LINE_LOOP 0x0002
+#define GL_LINE_STRIP 0x0003
+#define GL_TRIANGLES 0x0004
+#define GL_TRIANGLE_STRIP 0x0005
+#define GL_TRIANGLE_FAN 0x0006
+#define GL_QUADS 0x0007
+#define GL_QUAD_STRIP 0x0008
+#define GL_POLYGON 0x0009
+
+/* Vertex Arrays */
+#define GL_VERTEX_ARRAY 0x8074
+#define GL_NORMAL_ARRAY 0x8075
+#define GL_COLOR_ARRAY 0x8076
+#define GL_INDEX_ARRAY 0x8077
+#define GL_TEXTURE_COORD_ARRAY 0x8078
+#define GL_EDGE_FLAG_ARRAY 0x8079
+#define GL_VERTEX_ARRAY_SIZE 0x807A
+#define GL_VERTEX_ARRAY_TYPE 0x807B
+#define GL_VERTEX_ARRAY_STRIDE 0x807C
+#define GL_NORMAL_ARRAY_TYPE 0x807E
+#define GL_NORMAL_ARRAY_STRIDE 0x807F
+#define GL_COLOR_ARRAY_SIZE 0x8081
+#define GL_COLOR_ARRAY_TYPE 0x8082
+#define GL_COLOR_ARRAY_STRIDE 0x8083
+#define GL_INDEX_ARRAY_TYPE 0x8085
+#define GL_INDEX_ARRAY_STRIDE 0x8086
+#define GL_TEXTURE_COORD_ARRAY_SIZE 0x8088
+#define GL_TEXTURE_COORD_ARRAY_TYPE 0x8089
+#define GL_TEXTURE_COORD_ARRAY_STRIDE 0x808A
+#define GL_EDGE_FLAG_ARRAY_STRIDE 0x808C
+#define GL_VERTEX_ARRAY_POINTER 0x808E
+#define GL_NORMAL_ARRAY_POINTER 0x808F
+#define GL_COLOR_ARRAY_POINTER 0x8090
+#define GL_INDEX_ARRAY_POINTER 0x8091
+#define GL_TEXTURE_COORD_ARRAY_POINTER 0x8092
+#define GL_EDGE_FLAG_ARRAY_POINTER 0x8093
+#define GL_V2F 0x2A20
+#define GL_V3F 0x2A21
+#define GL_C4UB_V2F 0x2A22
+#define GL_C4UB_V3F 0x2A23
+#define GL_C3F_V3F 0x2A24
+#define GL_N3F_V3F 0x2A25
+#define GL_C4F_N3F_V3F 0x2A26
+#define GL_T2F_V3F 0x2A27
+#define GL_T4F_V4F 0x2A28
+#define GL_T2F_C4UB_V3F 0x2A29
+#define GL_T2F_C3F_V3F 0x2A2A
+#define GL_T2F_N3F_V3F 0x2A2B
+#define GL_T2F_C4F_N3F_V3F 0x2A2C
+#define GL_T4F_C4F_N3F_V4F 0x2A2D
+
+/* Matrix Mode */
+#define GL_MATRIX_MODE 0x0BA0
+#define GL_MODELVIEW 0x1700
+#define GL_PROJECTION 0x1701
+#define GL_TEXTURE 0x1702
+
+/* Points */
+#define GL_POINT_SMOOTH 0x0B10
+#define GL_POINT_SIZE 0x0B11
+#define GL_POINT_SIZE_GRANULARITY 0x0B13
+#define GL_POINT_SIZE_RANGE 0x0B12
+
+/* Lines */
+#define GL_LINE_SMOOTH 0x0B20
+#define GL_LINE_STIPPLE 0x0B24
+#define GL_LINE_STIPPLE_PATTERN 0x0B25
+#define GL_LINE_STIPPLE_REPEAT 0x0B26
+#define GL_LINE_WIDTH 0x0B21
+#define GL_LINE_WIDTH_GRANULARITY 0x0B23
+#define GL_LINE_WIDTH_RANGE 0x0B22
+
+/* Polygons */
+#define GL_POINT 0x1B00
+#define GL_LINE 0x1B01
+#define GL_FILL 0x1B02
+#define GL_CW 0x0900
+#define GL_CCW 0x0901
+#define GL_FRONT 0x0404
+#define GL_BACK 0x0405
+#define GL_POLYGON_MODE 0x0B40
+#define GL_POLYGON_SMOOTH 0x0B41
+#define GL_POLYGON_STIPPLE 0x0B42
+#define GL_EDGE_FLAG 0x0B43
+#define GL_CULL_FACE 0x0B44
+#define GL_CULL_FACE_MODE 0x0B45
+#define GL_FRONT_FACE 0x0B46
+#define GL_POLYGON_OFFSET_FACTOR 0x8038
+#define GL_POLYGON_OFFSET_UNITS 0x2A00
+#define GL_POLYGON_OFFSET_POINT 0x2A01
+#define GL_POLYGON_OFFSET_LINE 0x2A02
+#define GL_POLYGON_OFFSET_FILL 0x8037
+
+/* Display Lists */
+#define GL_COMPILE 0x1300
+#define GL_COMPILE_AND_EXECUTE 0x1301
+#define GL_LIST_BASE 0x0B32
+#define GL_LIST_INDEX 0x0B33
+#define GL_LIST_MODE 0x0B30
+
+/* Depth buffer */
+#define GL_NEVER 0x0200
+#define GL_LESS 0x0201
+#define GL_EQUAL 0x0202
+#define GL_LEQUAL 0x0203
+#define GL_GREATER 0x0204
+#define GL_NOTEQUAL 0x0205
+#define GL_GEQUAL 0x0206
+#define GL_ALWAYS 0x0207
+#define GL_DEPTH_TEST 0x0B71
+#define GL_DEPTH_BITS 0x0D56
+#define GL_DEPTH_CLEAR_VALUE 0x0B73
+#define GL_DEPTH_FUNC 0x0B74
+#define GL_DEPTH_RANGE 0x0B70
+#define GL_DEPTH_WRITEMASK 0x0B72
+#define GL_DEPTH_COMPONENT 0x1902
+
+/* Lighting */
+#define GL_LIGHTING 0x0B50
+#define GL_LIGHT0 0x4000
+#define GL_LIGHT1 0x4001
+#define GL_LIGHT2 0x4002
+#define GL_LIGHT3 0x4003
+#define GL_LIGHT4 0x4004
+#define GL_LIGHT5 0x4005
+#define GL_LIGHT6 0x4006
+#define GL_LIGHT7 0x4007
+#define GL_SPOT_EXPONENT 0x1205
+#define GL_SPOT_CUTOFF 0x1206
+#define GL_CONSTANT_ATTENUATION 0x1207
+#define GL_LINEAR_ATTENUATION 0x1208
+#define GL_QUADRATIC_ATTENUATION 0x1209
+#define GL_AMBIENT 0x1200
+#define GL_DIFFUSE 0x1201
+#define GL_SPECULAR 0x1202
+#define GL_SHININESS 0x1601
+#define GL_EMISSION 0x1600
+#define GL_POSITION 0x1203
+#define GL_SPOT_DIRECTION 0x1204
+#define GL_AMBIENT_AND_DIFFUSE 0x1602
+#define GL_COLOR_INDEXES 0x1603
+#define GL_LIGHT_MODEL_TWO_SIDE 0x0B52
+#define GL_LIGHT_MODEL_LOCAL_VIEWER 0x0B51
+#define GL_LIGHT_MODEL_AMBIENT 0x0B53
+#define GL_FRONT_AND_BACK 0x0408
+#define GL_SHADE_MODEL 0x0B54
+#define GL_FLAT 0x1D00
+#define GL_SMOOTH 0x1D01
+#define GL_COLOR_MATERIAL 0x0B57
+#define GL_COLOR_MATERIAL_FACE 0x0B55
+#define GL_COLOR_MATERIAL_PARAMETER 0x0B56
+#define GL_NORMALIZE 0x0BA1
+
+/* User clipping planes */
+#define GL_CLIP_PLANE0 0x3000
+#define GL_CLIP_PLANE1 0x3001
+#define GL_CLIP_PLANE2 0x3002
+#define GL_CLIP_PLANE3 0x3003
+#define GL_CLIP_PLANE4 0x3004
+#define GL_CLIP_PLANE5 0x3005
+
+/* Accumulation buffer */
+#define GL_ACCUM_RED_BITS 0x0D58
+#define GL_ACCUM_GREEN_BITS 0x0D59
+#define GL_ACCUM_BLUE_BITS 0x0D5A
+#define GL_ACCUM_ALPHA_BITS 0x0D5B
+#define GL_ACCUM_CLEAR_VALUE 0x0B80
+#define GL_ACCUM 0x0100
+#define GL_ADD 0x0104
+#define GL_LOAD 0x0101
+#define GL_MULT 0x0103
+#define GL_RETURN 0x0102
+
+/* Alpha testing */
+#define GL_ALPHA_TEST 0x0BC0
+#define GL_ALPHA_TEST_REF 0x0BC2
+#define GL_ALPHA_TEST_FUNC 0x0BC1
+
+/* Blending */
+#define GL_BLEND 0x0BE2
+#define GL_BLEND_SRC 0x0BE1
+#define GL_BLEND_DST 0x0BE0
+#define GL_ZERO 0x0
+#define GL_ONE 0x1
+#define GL_SRC_COLOR 0x0300
+#define GL_ONE_MINUS_SRC_COLOR 0x0301
+#define GL_SRC_ALPHA 0x0302
+#define GL_ONE_MINUS_SRC_ALPHA 0x0303
+#define GL_DST_ALPHA 0x0304
+#define GL_ONE_MINUS_DST_ALPHA 0x0305
+#define GL_DST_COLOR 0x0306
+#define GL_ONE_MINUS_DST_COLOR 0x0307
+#define GL_SRC_ALPHA_SATURATE 0x0308
+
+/* Render Mode */
+#define GL_FEEDBACK 0x1C01
+#define GL_RENDER 0x1C00
+#define GL_SELECT 0x1C02
+
+/* Feedback */
+#define GL_2D 0x0600
+#define GL_3D 0x0601
+#define GL_3D_COLOR 0x0602
+#define GL_3D_COLOR_TEXTURE 0x0603
+#define GL_4D_COLOR_TEXTURE 0x0604
+#define GL_POINT_TOKEN 0x0701
+#define GL_LINE_TOKEN 0x0702
+#define GL_LINE_RESET_TOKEN 0x0707
+#define GL_POLYGON_TOKEN 0x0703
+#define GL_BITMAP_TOKEN 0x0704
+#define GL_DRAW_PIXEL_TOKEN 0x0705
+#define GL_COPY_PIXEL_TOKEN 0x0706
+#define GL_PASS_THROUGH_TOKEN 0x0700
+#define GL_FEEDBACK_BUFFER_POINTER 0x0DF0
+#define GL_FEEDBACK_BUFFER_SIZE 0x0DF1
+#define GL_FEEDBACK_BUFFER_TYPE 0x0DF2
+
+/* Selection */
+#define GL_SELECTION_BUFFER_POINTER 0x0DF3
+#define GL_SELECTION_BUFFER_SIZE 0x0DF4
+
+/* Fog */
+#define GL_FOG 0x0B60
+#define GL_FOG_MODE 0x0B65
+#define GL_FOG_DENSITY 0x0B62
+#define GL_FOG_COLOR 0x0B66
+#define GL_FOG_INDEX 0x0B61
+#define GL_FOG_START 0x0B63
+#define GL_FOG_END 0x0B64
+#define GL_LINEAR 0x2601
+#define GL_EXP 0x0800
+#define GL_EXP2 0x0801
+
+/* Logic Ops */
+#define GL_LOGIC_OP 0x0BF1
+#define GL_INDEX_LOGIC_OP 0x0BF1
+#define GL_COLOR_LOGIC_OP 0x0BF2
+#define GL_LOGIC_OP_MODE 0x0BF0
+#define GL_CLEAR 0x1500
+#define GL_SET 0x150F
+#define GL_COPY 0x1503
+#define GL_COPY_INVERTED 0x150C
+#define GL_NOOP 0x1505
+#define GL_INVERT 0x150A
+#define GL_AND 0x1501
+#define GL_NAND 0x150E
+#define GL_OR 0x1507
+#define GL_NOR 0x1508
+#define GL_XOR 0x1506
+#define GL_EQUIV 0x1509
+#define GL_AND_REVERSE 0x1502
+#define GL_AND_INVERTED 0x1504
+#define GL_OR_REVERSE 0x150B
+#define GL_OR_INVERTED 0x150D
+
+/* Stencil */
+#define GL_STENCIL_TEST 0x0B90
+#define GL_STENCIL_WRITEMASK 0x0B98
+#define GL_STENCIL_BITS 0x0D57
+#define GL_STENCIL_FUNC 0x0B92
+#define GL_STENCIL_VALUE_MASK 0x0B93
+#define GL_STENCIL_REF 0x0B97
+#define GL_STENCIL_FAIL 0x0B94
+#define GL_STENCIL_PASS_DEPTH_PASS 0x0B96
+#define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95
+#define GL_STENCIL_CLEAR_VALUE 0x0B91
+#define GL_STENCIL_INDEX 0x1901
+#define GL_KEEP 0x1E00
+#define GL_REPLACE 0x1E01
+#define GL_INCR 0x1E02
+#define GL_DECR 0x1E03
+
+/* Buffers, Pixel Drawing/Reading */
+#define GL_NONE 0x0
+#define GL_LEFT 0x0406
+#define GL_RIGHT 0x0407
+/*GL_FRONT 0x0404 */
+/*GL_BACK 0x0405 */
+/*GL_FRONT_AND_BACK 0x0408 */
+#define GL_FRONT_LEFT 0x0400
+#define GL_FRONT_RIGHT 0x0401
+#define GL_BACK_LEFT 0x0402
+#define GL_BACK_RIGHT 0x0403
+#define GL_AUX0 0x0409
+#define GL_AUX1 0x040A
+#define GL_AUX2 0x040B
+#define GL_AUX3 0x040C
+#define GL_COLOR_INDEX 0x1900
+#define GL_RED 0x1903
+#define GL_GREEN 0x1904
+#define GL_BLUE 0x1905
+#define GL_ALPHA 0x1906
+#define GL_LUMINANCE 0x1909
+#define GL_LUMINANCE_ALPHA 0x190A
+#define GL_ALPHA_BITS 0x0D55
+#define GL_RED_BITS 0x0D52
+#define GL_GREEN_BITS 0x0D53
+#define GL_BLUE_BITS 0x0D54
+#define GL_INDEX_BITS 0x0D51
+#define GL_SUBPIXEL_BITS 0x0D50
+#define GL_AUX_BUFFERS 0x0C00
+#define GL_READ_BUFFER 0x0C02
+#define GL_DRAW_BUFFER 0x0C01
+#define GL_DOUBLEBUFFER 0x0C32
+#define GL_STEREO 0x0C33
+#define GL_BITMAP 0x1A00
+#define GL_COLOR 0x1800
+#define GL_DEPTH 0x1801
+#define GL_STENCIL 0x1802
+#define GL_DITHER 0x0BD0
+#define GL_RGB 0x1907
+#define GL_RGBA 0x1908
+
+/* Implementation limits */
+#define GL_MAX_LIST_NESTING 0x0B31
+#define GL_MAX_ATTRIB_STACK_DEPTH 0x0D35
+#define GL_MAX_MODELVIEW_STACK_DEPTH 0x0D36
+#define GL_MAX_NAME_STACK_DEPTH 0x0D37
+#define GL_MAX_PROJECTION_STACK_DEPTH 0x0D38
+#define GL_MAX_TEXTURE_STACK_DEPTH 0x0D39
+#define GL_MAX_EVAL_ORDER 0x0D30
+#define GL_MAX_LIGHTS 0x0D31
+#define GL_MAX_CLIP_PLANES 0x0D32
+#define GL_MAX_TEXTURE_SIZE 0x0D33
+#define GL_MAX_PIXEL_MAP_TABLE 0x0D34
+#define GL_MAX_VIEWPORT_DIMS 0x0D3A
+#define GL_MAX_CLIENT_ATTRIB_STACK_DEPTH 0x0D3B
+
+/* Gets */
+#define GL_ATTRIB_STACK_DEPTH 0x0BB0
+#define GL_CLIENT_ATTRIB_STACK_DEPTH 0x0BB1
+#define GL_COLOR_CLEAR_VALUE 0x0C22
+#define GL_COLOR_WRITEMASK 0x0C23
+#define GL_CURRENT_INDEX 0x0B01
+#define GL_CURRENT_COLOR 0x0B00
+#define GL_CURRENT_NORMAL 0x0B02
+#define GL_CURRENT_RASTER_COLOR 0x0B04
+#define GL_CURRENT_RASTER_DISTANCE 0x0B09
+#define GL_CURRENT_RASTER_INDEX 0x0B05
+#define GL_CURRENT_RASTER_POSITION 0x0B07
+#define GL_CURRENT_RASTER_TEXTURE_COORDS 0x0B06
+#define GL_CURRENT_RASTER_POSITION_VALID 0x0B08
+#define GL_CURRENT_TEXTURE_COORDS 0x0B03
+#define GL_INDEX_CLEAR_VALUE 0x0C20
+#define GL_INDEX_MODE 0x0C30
+#define GL_INDEX_WRITEMASK 0x0C21
+#define GL_MODELVIEW_MATRIX 0x0BA6
+#define GL_MODELVIEW_STACK_DEPTH 0x0BA3
+#define GL_NAME_STACK_DEPTH 0x0D70
+#define GL_PROJECTION_MATRIX 0x0BA7
+#define GL_PROJECTION_STACK_DEPTH 0x0BA4
+#define GL_RENDER_MODE 0x0C40
+#define GL_RGBA_MODE 0x0C31
+#define GL_TEXTURE_MATRIX 0x0BA8
+#define GL_TEXTURE_STACK_DEPTH 0x0BA5
+#define GL_VIEWPORT 0x0BA2
+
+/* Evaluators */
+#define GL_AUTO_NORMAL 0x0D80
+#define GL_MAP1_COLOR_4 0x0D90
+#define GL_MAP1_INDEX 0x0D91
+#define GL_MAP1_NORMAL 0x0D92
+#define GL_MAP1_TEXTURE_COORD_1 0x0D93
+#define GL_MAP1_TEXTURE_COORD_2 0x0D94
+#define GL_MAP1_TEXTURE_COORD_3 0x0D95
+#define GL_MAP1_TEXTURE_COORD_4 0x0D96
+#define GL_MAP1_VERTEX_3 0x0D97
+#define GL_MAP1_VERTEX_4 0x0D98
+#define GL_MAP2_COLOR_4 0x0DB0
+#define GL_MAP2_INDEX 0x0DB1
+#define GL_MAP2_NORMAL 0x0DB2
+#define GL_MAP2_TEXTURE_COORD_1 0x0DB3
+#define GL_MAP2_TEXTURE_COORD_2 0x0DB4
+#define GL_MAP2_TEXTURE_COORD_3 0x0DB5
+#define GL_MAP2_TEXTURE_COORD_4 0x0DB6
+#define GL_MAP2_VERTEX_3 0x0DB7
+#define GL_MAP2_VERTEX_4 0x0DB8
+#define GL_MAP1_GRID_DOMAIN 0x0DD0
+#define GL_MAP1_GRID_SEGMENTS 0x0DD1
+#define GL_MAP2_GRID_DOMAIN 0x0DD2
+#define GL_MAP2_GRID_SEGMENTS 0x0DD3
+#define GL_COEFF 0x0A00
+#define GL_DOMAIN 0x0A02
+#define GL_ORDER 0x0A01
+
+/* Hints */
+#define GL_FOG_HINT 0x0C54
+#define GL_LINE_SMOOTH_HINT 0x0C52
+#define GL_PERSPECTIVE_CORRECTION_HINT 0x0C50
+#define GL_POINT_SMOOTH_HINT 0x0C51
+#define GL_POLYGON_SMOOTH_HINT 0x0C53
+#define GL_DONT_CARE 0x1100
+#define GL_FASTEST 0x1101
+#define GL_NICEST 0x1102
+
+/* Scissor box */
+#define GL_SCISSOR_TEST 0x0C11
+#define GL_SCISSOR_BOX 0x0C10
+
+/* Pixel Mode / Transfer */
+#define GL_MAP_COLOR 0x0D10
+#define GL_MAP_STENCIL 0x0D11
+#define GL_INDEX_SHIFT 0x0D12
+#define GL_INDEX_OFFSET 0x0D13
+#define GL_RED_SCALE 0x0D14
+#define GL_RED_BIAS 0x0D15
+#define GL_GREEN_SCALE 0x0D18
+#define GL_GREEN_BIAS 0x0D19
+#define GL_BLUE_SCALE 0x0D1A
+#define GL_BLUE_BIAS 0x0D1B
+#define GL_ALPHA_SCALE 0x0D1C
+#define GL_ALPHA_BIAS 0x0D1D
+#define GL_DEPTH_SCALE 0x0D1E
+#define GL_DEPTH_BIAS 0x0D1F
+#define GL_PIXEL_MAP_S_TO_S_SIZE 0x0CB1
+#define GL_PIXEL_MAP_I_TO_I_SIZE 0x0CB0
+#define GL_PIXEL_MAP_I_TO_R_SIZE 0x0CB2
+#define GL_PIXEL_MAP_I_TO_G_SIZE 0x0CB3
+#define GL_PIXEL_MAP_I_TO_B_SIZE 0x0CB4
+#define GL_PIXEL_MAP_I_TO_A_SIZE 0x0CB5
+#define GL_PIXEL_MAP_R_TO_R_SIZE 0x0CB6
+#define GL_PIXEL_MAP_G_TO_G_SIZE 0x0CB7
+#define GL_PIXEL_MAP_B_TO_B_SIZE 0x0CB8
+#define GL_PIXEL_MAP_A_TO_A_SIZE 0x0CB9
+#define GL_PIXEL_MAP_S_TO_S 0x0C71
+#define GL_PIXEL_MAP_I_TO_I 0x0C70
+#define GL_PIXEL_MAP_I_TO_R 0x0C72
+#define GL_PIXEL_MAP_I_TO_G 0x0C73
+#define GL_PIXEL_MAP_I_TO_B 0x0C74
+#define GL_PIXEL_MAP_I_TO_A 0x0C75
+#define GL_PIXEL_MAP_R_TO_R 0x0C76
+#define GL_PIXEL_MAP_G_TO_G 0x0C77
+#define GL_PIXEL_MAP_B_TO_B 0x0C78
+#define GL_PIXEL_MAP_A_TO_A 0x0C79
+#define GL_PACK_ALIGNMENT 0x0D05
+#define GL_PACK_LSB_FIRST 0x0D01
+#define GL_PACK_ROW_LENGTH 0x0D02
+#define GL_PACK_SKIP_PIXELS 0x0D04
+#define GL_PACK_SKIP_ROWS 0x0D03
+#define GL_PACK_SWAP_BYTES 0x0D00
+#define GL_UNPACK_ALIGNMENT 0x0CF5
+#define GL_UNPACK_LSB_FIRST 0x0CF1
+#define GL_UNPACK_ROW_LENGTH 0x0CF2
+#define GL_UNPACK_SKIP_PIXELS 0x0CF4
+#define GL_UNPACK_SKIP_ROWS 0x0CF3
+#define GL_UNPACK_SWAP_BYTES 0x0CF0
+#define GL_ZOOM_X 0x0D16
+#define GL_ZOOM_Y 0x0D17
+
+/* Texture mapping */
+#define GL_TEXTURE_ENV 0x2300
+#define GL_TEXTURE_ENV_MODE 0x2200
+#define GL_TEXTURE_1D 0x0DE0
+#define GL_TEXTURE_2D 0x0DE1
+#define GL_TEXTURE_WRAP_S 0x2802
+#define GL_TEXTURE_WRAP_T 0x2803
+#define GL_TEXTURE_MAG_FILTER 0x2800
+#define GL_TEXTURE_MIN_FILTER 0x2801
+#define GL_TEXTURE_ENV_COLOR 0x2201
+#define GL_TEXTURE_GEN_S 0x0C60
+#define GL_TEXTURE_GEN_T 0x0C61
+#define GL_TEXTURE_GEN_MODE 0x2500
+#define GL_TEXTURE_BORDER_COLOR 0x1004
+#define GL_TEXTURE_WIDTH 0x1000
+#define GL_TEXTURE_HEIGHT 0x1001
+#define GL_TEXTURE_BORDER 0x1005
+#define GL_TEXTURE_COMPONENTS 0x1003
+#define GL_TEXTURE_RED_SIZE 0x805C
+#define GL_TEXTURE_GREEN_SIZE 0x805D
+#define GL_TEXTURE_BLUE_SIZE 0x805E
+#define GL_TEXTURE_ALPHA_SIZE 0x805F
+#define GL_TEXTURE_LUMINANCE_SIZE 0x8060
+#define GL_TEXTURE_INTENSITY_SIZE 0x8061
+#define GL_NEAREST_MIPMAP_NEAREST 0x2700
+#define GL_NEAREST_MIPMAP_LINEAR 0x2702
+#define GL_LINEAR_MIPMAP_NEAREST 0x2701
+#define GL_LINEAR_MIPMAP_LINEAR 0x2703
+#define GL_OBJECT_LINEAR 0x2401
+#define GL_OBJECT_PLANE 0x2501
+#define GL_EYE_LINEAR 0x2400
+#define GL_EYE_PLANE 0x2502
+#define GL_SPHERE_MAP 0x2402
+#define GL_DECAL 0x2101
+#define GL_MODULATE 0x2100
+#define GL_NEAREST 0x2600
+#define GL_REPEAT 0x2901
+#define GL_CLAMP 0x2900
+#define GL_S 0x2000
+#define GL_T 0x2001
+#define GL_R 0x2002
+#define GL_Q 0x2003
+#define GL_TEXTURE_GEN_R 0x0C62
+#define GL_TEXTURE_GEN_Q 0x0C63
+
+/* Utility */
+#define GL_VENDOR 0x1F00
+#define GL_RENDERER 0x1F01
+#define GL_VERSION 0x1F02
+#define GL_EXTENSIONS 0x1F03
+
+/* Errors */
+#define GL_NO_ERROR 0x0
+#define GL_INVALID_VALUE 0x0501
+#define GL_INVALID_ENUM 0x0500
+#define GL_INVALID_OPERATION 0x0502
+#define GL_STACK_OVERFLOW 0x0503
+#define GL_STACK_UNDERFLOW 0x0504
+#define GL_OUT_OF_MEMORY 0x0505
+
+/* glPush/PopAttrib bits */
+#define GL_CURRENT_BIT 0x00000001
+#define GL_POINT_BIT 0x00000002
+#define GL_LINE_BIT 0x00000004
+#define GL_POLYGON_BIT 0x00000008
+#define GL_POLYGON_STIPPLE_BIT 0x00000010
+#define GL_PIXEL_MODE_BIT 0x00000020
+#define GL_LIGHTING_BIT 0x00000040
+#define GL_FOG_BIT 0x00000080
+#define GL_DEPTH_BUFFER_BIT 0x00000100
+#define GL_ACCUM_BUFFER_BIT 0x00000200
+#define GL_STENCIL_BUFFER_BIT 0x00000400
+#define GL_VIEWPORT_BIT 0x00000800
+#define GL_TRANSFORM_BIT 0x00001000
+#define GL_ENABLE_BIT 0x00002000
+#define GL_COLOR_BUFFER_BIT 0x00004000
+#define GL_HINT_BIT 0x00008000
+#define GL_EVAL_BIT 0x00010000
+#define GL_LIST_BIT 0x00020000
+#define GL_TEXTURE_BIT 0x00040000
+#define GL_SCISSOR_BIT 0x00080000
+#define GL_ALL_ATTRIB_BITS 0x000FFFFF
+
+
+/* OpenGL 1.1 */
+#define GL_PROXY_TEXTURE_1D 0x8063
+#define GL_PROXY_TEXTURE_2D 0x8064
+#define GL_TEXTURE_PRIORITY 0x8066
+#define GL_TEXTURE_RESIDENT 0x8067
+#define GL_TEXTURE_BINDING_1D 0x8068
+#define GL_TEXTURE_BINDING_2D 0x8069
+#define GL_TEXTURE_INTERNAL_FORMAT 0x1003
+#define GL_ALPHA4 0x803B
+#define GL_ALPHA8 0x803C
+#define GL_ALPHA12 0x803D
+#define GL_ALPHA16 0x803E
+#define GL_LUMINANCE4 0x803F
+#define GL_LUMINANCE8 0x8040
+#define GL_LUMINANCE12 0x8041
+#define GL_LUMINANCE16 0x8042
+#define GL_LUMINANCE4_ALPHA4 0x8043
+#define GL_LUMINANCE6_ALPHA2 0x8044
+#define GL_LUMINANCE8_ALPHA8 0x8045
+#define GL_LUMINANCE12_ALPHA4 0x8046
+#define GL_LUMINANCE12_ALPHA12 0x8047
+#define GL_LUMINANCE16_ALPHA16 0x8048
+#define GL_INTENSITY 0x8049
+#define GL_INTENSITY4 0x804A
+#define GL_INTENSITY8 0x804B
+#define GL_INTENSITY12 0x804C
+#define GL_INTENSITY16 0x804D
+#define GL_R3_G3_B2 0x2A10
+#define GL_RGB4 0x804F
+#define GL_RGB5 0x8050
+#define GL_RGB8 0x8051
+#define GL_RGB10 0x8052
+#define GL_RGB12 0x8053
+#define GL_RGB16 0x8054
+#define GL_RGBA2 0x8055
+#define GL_RGBA4 0x8056
+#define GL_RGB5_A1 0x8057
+#define GL_RGBA8 0x8058
+#define GL_RGB10_A2 0x8059
+#define GL_RGBA12 0x805A
+#define GL_RGBA16 0x805B
+#define GL_CLIENT_PIXEL_STORE_BIT 0x00000001
+#define GL_CLIENT_VERTEX_ARRAY_BIT 0x00000002
+#define GL_ALL_CLIENT_ATTRIB_BITS 0xFFFFFFFF
+#define GL_CLIENT_ALL_ATTRIB_BITS 0xFFFFFFFF
+
+
+
+/*
+ * Miscellaneous
+ */
+
+GLAPI void GLAPIENTRY glClearIndex( GLfloat c );
+
+GLAPI void GLAPIENTRY glClearColor( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha );
+
+GLAPI void GLAPIENTRY glClear( GLbitfield mask );
+
+GLAPI void GLAPIENTRY glIndexMask( GLuint mask );
+
+GLAPI void GLAPIENTRY glColorMask( GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha );
+
+GLAPI void GLAPIENTRY glAlphaFunc( GLenum func, GLclampf ref );
+
+GLAPI void GLAPIENTRY glBlendFunc( GLenum sfactor, GLenum dfactor );
+
+GLAPI void GLAPIENTRY glLogicOp( GLenum opcode );
+
+GLAPI void GLAPIENTRY glCullFace( GLenum mode );
+
+GLAPI void GLAPIENTRY glFrontFace( GLenum mode );
+
+GLAPI void GLAPIENTRY glPointSize( GLfloat size );
+
+GLAPI void GLAPIENTRY glLineWidth( GLfloat width );
+
+GLAPI void GLAPIENTRY glLineStipple( GLint factor, GLushort pattern );
+
+GLAPI void GLAPIENTRY glPolygonMode( GLenum face, GLenum mode );
+
+GLAPI void GLAPIENTRY glPolygonOffset( GLfloat factor, GLfloat units );
+
+GLAPI void GLAPIENTRY glPolygonStipple( const GLubyte *mask );
+
+GLAPI void GLAPIENTRY glGetPolygonStipple( GLubyte *mask );
+
+GLAPI void GLAPIENTRY glEdgeFlag( GLboolean flag );
+
+GLAPI void GLAPIENTRY glEdgeFlagv( const GLboolean *flag );
+
+GLAPI void GLAPIENTRY glScissor( GLint x, GLint y, GLsizei width, GLsizei height);
+
+GLAPI void GLAPIENTRY glClipPlane( GLenum plane, const GLdouble *equation );
+
+GLAPI void GLAPIENTRY glGetClipPlane( GLenum plane, GLdouble *equation );
+
+GLAPI void GLAPIENTRY glDrawBuffer( GLenum mode );
+
+GLAPI void GLAPIENTRY glReadBuffer( GLenum mode );
+
+GLAPI void GLAPIENTRY glEnable( GLenum cap );
+
+GLAPI void GLAPIENTRY glDisable( GLenum cap );
+
+GLAPI GLboolean GLAPIENTRY glIsEnabled( GLenum cap );
+
+
+GLAPI void GLAPIENTRY glEnableClientState( GLenum cap ); /* 1.1 */
+
+GLAPI void GLAPIENTRY glDisableClientState( GLenum cap ); /* 1.1 */
+
+
+GLAPI void GLAPIENTRY glGetBooleanv( GLenum pname, GLboolean *params );
+
+GLAPI void GLAPIENTRY glGetDoublev( GLenum pname, GLdouble *params );
+
+GLAPI void GLAPIENTRY glGetFloatv( GLenum pname, GLfloat *params );
+
+GLAPI void GLAPIENTRY glGetIntegerv( GLenum pname, GLint *params );
+
+
+GLAPI void GLAPIENTRY glPushAttrib( GLbitfield mask );
+
+GLAPI void GLAPIENTRY glPopAttrib( void );
+
+
+GLAPI void GLAPIENTRY glPushClientAttrib( GLbitfield mask ); /* 1.1 */
+
+GLAPI void GLAPIENTRY glPopClientAttrib( void ); /* 1.1 */
+
+
+GLAPI GLint GLAPIENTRY glRenderMode( GLenum mode );
+
+GLAPI GLenum GLAPIENTRY glGetError( void );
+
+GLAPI const GLubyte * GLAPIENTRY glGetString( GLenum name );
+
+GLAPI void GLAPIENTRY glFinish( void );
+
+GLAPI void GLAPIENTRY glFlush( void );
+
+GLAPI void GLAPIENTRY glHint( GLenum target, GLenum mode );
+
+
+/*
+ * Depth Buffer
+ */
+
+GLAPI void GLAPIENTRY glClearDepth( GLclampd depth );
+
+GLAPI void GLAPIENTRY glDepthFunc( GLenum func );
+
+GLAPI void GLAPIENTRY glDepthMask( GLboolean flag );
+
+GLAPI void GLAPIENTRY glDepthRange( GLclampd near_val, GLclampd far_val );
+
+
+/*
+ * Accumulation Buffer
+ */
+
+GLAPI void GLAPIENTRY glClearAccum( GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha );
+
+GLAPI void GLAPIENTRY glAccum( GLenum op, GLfloat value );
+
+
+/*
+ * Transformation
+ */
+
+GLAPI void GLAPIENTRY glMatrixMode( GLenum mode );
+
+GLAPI void GLAPIENTRY glOrtho( GLdouble left, GLdouble right,
+ GLdouble bottom, GLdouble top,
+ GLdouble near_val, GLdouble far_val );
+
+GLAPI void GLAPIENTRY glFrustum( GLdouble left, GLdouble right,
+ GLdouble bottom, GLdouble top,
+ GLdouble near_val, GLdouble far_val );
+
+GLAPI void GLAPIENTRY glViewport( GLint x, GLint y,
+ GLsizei width, GLsizei height );
+
+GLAPI void GLAPIENTRY glPushMatrix( void );
+
+GLAPI void GLAPIENTRY glPopMatrix( void );
+
+GLAPI void GLAPIENTRY glLoadIdentity( void );
+
+GLAPI void GLAPIENTRY glLoadMatrixd( const GLdouble *m );
+GLAPI void GLAPIENTRY glLoadMatrixf( const GLfloat *m );
+
+GLAPI void GLAPIENTRY glMultMatrixd( const GLdouble *m );
+GLAPI void GLAPIENTRY glMultMatrixf( const GLfloat *m );
+
+GLAPI void GLAPIENTRY glRotated( GLdouble angle,
+ GLdouble x, GLdouble y, GLdouble z );
+GLAPI void GLAPIENTRY glRotatef( GLfloat angle,
+ GLfloat x, GLfloat y, GLfloat z );
+
+GLAPI void GLAPIENTRY glScaled( GLdouble x, GLdouble y, GLdouble z );
+GLAPI void GLAPIENTRY glScalef( GLfloat x, GLfloat y, GLfloat z );
+
+GLAPI void GLAPIENTRY glTranslated( GLdouble x, GLdouble y, GLdouble z );
+GLAPI void GLAPIENTRY glTranslatef( GLfloat x, GLfloat y, GLfloat z );
+
+
+/*
+ * Display Lists
+ */
+
+GLAPI GLboolean GLAPIENTRY glIsList( GLuint list );
+
+GLAPI void GLAPIENTRY glDeleteLists( GLuint list, GLsizei range );
+
+GLAPI GLuint GLAPIENTRY glGenLists( GLsizei range );
+
+GLAPI void GLAPIENTRY glNewList( GLuint list, GLenum mode );
+
+GLAPI void GLAPIENTRY glEndList( void );
+
+GLAPI void GLAPIENTRY glCallList( GLuint list );
+
+GLAPI void GLAPIENTRY glCallLists( GLsizei n, GLenum type,
+ const GLvoid *lists );
+
+GLAPI void GLAPIENTRY glListBase( GLuint base );
+
+
+/*
+ * Drawing Functions
+ */
+
+GLAPI void GLAPIENTRY glBegin( GLenum mode );
+
+GLAPI void GLAPIENTRY glEnd( void );
+
+
+GLAPI void GLAPIENTRY glVertex2d( GLdouble x, GLdouble y );
+GLAPI void GLAPIENTRY glVertex2f( GLfloat x, GLfloat y );
+GLAPI void GLAPIENTRY glVertex2i( GLint x, GLint y );
+GLAPI void GLAPIENTRY glVertex2s( GLshort x, GLshort y );
+
+GLAPI void GLAPIENTRY glVertex3d( GLdouble x, GLdouble y, GLdouble z );
+GLAPI void GLAPIENTRY glVertex3f( GLfloat x, GLfloat y, GLfloat z );
+GLAPI void GLAPIENTRY glVertex3i( GLint x, GLint y, GLint z );
+GLAPI void GLAPIENTRY glVertex3s( GLshort x, GLshort y, GLshort z );
+
+GLAPI void GLAPIENTRY glVertex4d( GLdouble x, GLdouble y, GLdouble z, GLdouble w );
+GLAPI void GLAPIENTRY glVertex4f( GLfloat x, GLfloat y, GLfloat z, GLfloat w );
+GLAPI void GLAPIENTRY glVertex4i( GLint x, GLint y, GLint z, GLint w );
+GLAPI void GLAPIENTRY glVertex4s( GLshort x, GLshort y, GLshort z, GLshort w );
+
+GLAPI void GLAPIENTRY glVertex2dv( const GLdouble *v );
+GLAPI void GLAPIENTRY glVertex2fv( const GLfloat *v );
+GLAPI void GLAPIENTRY glVertex2iv( const GLint *v );
+GLAPI void GLAPIENTRY glVertex2sv( const GLshort *v );
+
+GLAPI void GLAPIENTRY glVertex3dv( const GLdouble *v );
+GLAPI void GLAPIENTRY glVertex3fv( const GLfloat *v );
+GLAPI void GLAPIENTRY glVertex3iv( const GLint *v );
+GLAPI void GLAPIENTRY glVertex3sv( const GLshort *v );
+
+GLAPI void GLAPIENTRY glVertex4dv( const GLdouble *v );
+GLAPI void GLAPIENTRY glVertex4fv( const GLfloat *v );
+GLAPI void GLAPIENTRY glVertex4iv( const GLint *v );
+GLAPI void GLAPIENTRY glVertex4sv( const GLshort *v );
+
+
+GLAPI void GLAPIENTRY glNormal3b( GLbyte nx, GLbyte ny, GLbyte nz );
+GLAPI void GLAPIENTRY glNormal3d( GLdouble nx, GLdouble ny, GLdouble nz );
+GLAPI void GLAPIENTRY glNormal3f( GLfloat nx, GLfloat ny, GLfloat nz );
+GLAPI void GLAPIENTRY glNormal3i( GLint nx, GLint ny, GLint nz );
+GLAPI void GLAPIENTRY glNormal3s( GLshort nx, GLshort ny, GLshort nz );
+
+GLAPI void GLAPIENTRY glNormal3bv( const GLbyte *v );
+GLAPI void GLAPIENTRY glNormal3dv( const GLdouble *v );
+GLAPI void GLAPIENTRY glNormal3fv( const GLfloat *v );
+GLAPI void GLAPIENTRY glNormal3iv( const GLint *v );
+GLAPI void GLAPIENTRY glNormal3sv( const GLshort *v );
+
+
+GLAPI void GLAPIENTRY glIndexd( GLdouble c );
+GLAPI void GLAPIENTRY glIndexf( GLfloat c );
+GLAPI void GLAPIENTRY glIndexi( GLint c );
+GLAPI void GLAPIENTRY glIndexs( GLshort c );
+GLAPI void GLAPIENTRY glIndexub( GLubyte c ); /* 1.1 */
+
+GLAPI void GLAPIENTRY glIndexdv( const GLdouble *c );
+GLAPI void GLAPIENTRY glIndexfv( const GLfloat *c );
+GLAPI void GLAPIENTRY glIndexiv( const GLint *c );
+GLAPI void GLAPIENTRY glIndexsv( const GLshort *c );
+GLAPI void GLAPIENTRY glIndexubv( const GLubyte *c ); /* 1.1 */
+
+GLAPI void GLAPIENTRY glColor3b( GLbyte red, GLbyte green, GLbyte blue );
+GLAPI void GLAPIENTRY glColor3d( GLdouble red, GLdouble green, GLdouble blue );
+GLAPI void GLAPIENTRY glColor3f( GLfloat red, GLfloat green, GLfloat blue );
+GLAPI void GLAPIENTRY glColor3i( GLint red, GLint green, GLint blue );
+GLAPI void GLAPIENTRY glColor3s( GLshort red, GLshort green, GLshort blue );
+GLAPI void GLAPIENTRY glColor3ub( GLubyte red, GLubyte green, GLubyte blue );
+GLAPI void GLAPIENTRY glColor3ui( GLuint red, GLuint green, GLuint blue );
+GLAPI void GLAPIENTRY glColor3us( GLushort red, GLushort green, GLushort blue );
+
+GLAPI void GLAPIENTRY glColor4b( GLbyte red, GLbyte green,
+ GLbyte blue, GLbyte alpha );
+GLAPI void GLAPIENTRY glColor4d( GLdouble red, GLdouble green,
+ GLdouble blue, GLdouble alpha );
+GLAPI void GLAPIENTRY glColor4f( GLfloat red, GLfloat green,
+ GLfloat blue, GLfloat alpha );
+GLAPI void GLAPIENTRY glColor4i( GLint red, GLint green,
+ GLint blue, GLint alpha );
+GLAPI void GLAPIENTRY glColor4s( GLshort red, GLshort green,
+ GLshort blue, GLshort alpha );
+GLAPI void GLAPIENTRY glColor4ub( GLubyte red, GLubyte green,
+ GLubyte blue, GLubyte alpha );
+GLAPI void GLAPIENTRY glColor4ui( GLuint red, GLuint green,
+ GLuint blue, GLuint alpha );
+GLAPI void GLAPIENTRY glColor4us( GLushort red, GLushort green,
+ GLushort blue, GLushort alpha );
+
+
+GLAPI void GLAPIENTRY glColor3bv( const GLbyte *v );
+GLAPI void GLAPIENTRY glColor3dv( const GLdouble *v );
+GLAPI void GLAPIENTRY glColor3fv( const GLfloat *v );
+GLAPI void GLAPIENTRY glColor3iv( const GLint *v );
+GLAPI void GLAPIENTRY glColor3sv( const GLshort *v );
+GLAPI void GLAPIENTRY glColor3ubv( const GLubyte *v );
+GLAPI void GLAPIENTRY glColor3uiv( const GLuint *v );
+GLAPI void GLAPIENTRY glColor3usv( const GLushort *v );
+
+GLAPI void GLAPIENTRY glColor4bv( const GLbyte *v );
+GLAPI void GLAPIENTRY glColor4dv( const GLdouble *v );
+GLAPI void GLAPIENTRY glColor4fv( const GLfloat *v );
+GLAPI void GLAPIENTRY glColor4iv( const GLint *v );
+GLAPI void GLAPIENTRY glColor4sv( const GLshort *v );
+GLAPI void GLAPIENTRY glColor4ubv( const GLubyte *v );
+GLAPI void GLAPIENTRY glColor4uiv( const GLuint *v );
+GLAPI void GLAPIENTRY glColor4usv( const GLushort *v );
+
+
+GLAPI void GLAPIENTRY glTexCoord1d( GLdouble s );
+GLAPI void GLAPIENTRY glTexCoord1f( GLfloat s );
+GLAPI void GLAPIENTRY glTexCoord1i( GLint s );
+GLAPI void GLAPIENTRY glTexCoord1s( GLshort s );
+
+GLAPI void GLAPIENTRY glTexCoord2d( GLdouble s, GLdouble t );
+GLAPI void GLAPIENTRY glTexCoord2f( GLfloat s, GLfloat t );
+GLAPI void GLAPIENTRY glTexCoord2i( GLint s, GLint t );
+GLAPI void GLAPIENTRY glTexCoord2s( GLshort s, GLshort t );
+
+GLAPI void GLAPIENTRY glTexCoord3d( GLdouble s, GLdouble t, GLdouble r );
+GLAPI void GLAPIENTRY glTexCoord3f( GLfloat s, GLfloat t, GLfloat r );
+GLAPI void GLAPIENTRY glTexCoord3i( GLint s, GLint t, GLint r );
+GLAPI void GLAPIENTRY glTexCoord3s( GLshort s, GLshort t, GLshort r );
+
+GLAPI void GLAPIENTRY glTexCoord4d( GLdouble s, GLdouble t, GLdouble r, GLdouble q );
+GLAPI void GLAPIENTRY glTexCoord4f( GLfloat s, GLfloat t, GLfloat r, GLfloat q );
+GLAPI void GLAPIENTRY glTexCoord4i( GLint s, GLint t, GLint r, GLint q );
+GLAPI void GLAPIENTRY glTexCoord4s( GLshort s, GLshort t, GLshort r, GLshort q );
+
+GLAPI void GLAPIENTRY glTexCoord1dv( const GLdouble *v );
+GLAPI void GLAPIENTRY glTexCoord1fv( const GLfloat *v );
+GLAPI void GLAPIENTRY glTexCoord1iv( const GLint *v );
+GLAPI void GLAPIENTRY glTexCoord1sv( const GLshort *v );
+
+GLAPI void GLAPIENTRY glTexCoord2dv( const GLdouble *v );
+GLAPI void GLAPIENTRY glTexCoord2fv( const GLfloat *v );
+GLAPI void GLAPIENTRY glTexCoord2iv( const GLint *v );
+GLAPI void GLAPIENTRY glTexCoord2sv( const GLshort *v );
+
+GLAPI void GLAPIENTRY glTexCoord3dv( const GLdouble *v );
+GLAPI void GLAPIENTRY glTexCoord3fv( const GLfloat *v );
+GLAPI void GLAPIENTRY glTexCoord3iv( const GLint *v );
+GLAPI void GLAPIENTRY glTexCoord3sv( const GLshort *v );
+
+GLAPI void GLAPIENTRY glTexCoord4dv( const GLdouble *v );
+GLAPI void GLAPIENTRY glTexCoord4fv( const GLfloat *v );
+GLAPI void GLAPIENTRY glTexCoord4iv( const GLint *v );
+GLAPI void GLAPIENTRY glTexCoord4sv( const GLshort *v );
+
+
+GLAPI void GLAPIENTRY glRasterPos2d( GLdouble x, GLdouble y );
+GLAPI void GLAPIENTRY glRasterPos2f( GLfloat x, GLfloat y );
+GLAPI void GLAPIENTRY glRasterPos2i( GLint x, GLint y );
+GLAPI void GLAPIENTRY glRasterPos2s( GLshort x, GLshort y );
+
+GLAPI void GLAPIENTRY glRasterPos3d( GLdouble x, GLdouble y, GLdouble z );
+GLAPI void GLAPIENTRY glRasterPos3f( GLfloat x, GLfloat y, GLfloat z );
+GLAPI void GLAPIENTRY glRasterPos3i( GLint x, GLint y, GLint z );
+GLAPI void GLAPIENTRY glRasterPos3s( GLshort x, GLshort y, GLshort z );
+
+GLAPI void GLAPIENTRY glRasterPos4d( GLdouble x, GLdouble y, GLdouble z, GLdouble w );
+GLAPI void GLAPIENTRY glRasterPos4f( GLfloat x, GLfloat y, GLfloat z, GLfloat w );
+GLAPI void GLAPIENTRY glRasterPos4i( GLint x, GLint y, GLint z, GLint w );
+GLAPI void GLAPIENTRY glRasterPos4s( GLshort x, GLshort y, GLshort z, GLshort w );
+
+GLAPI void GLAPIENTRY glRasterPos2dv( const GLdouble *v );
+GLAPI void GLAPIENTRY glRasterPos2fv( const GLfloat *v );
+GLAPI void GLAPIENTRY glRasterPos2iv( const GLint *v );
+GLAPI void GLAPIENTRY glRasterPos2sv( const GLshort *v );
+
+GLAPI void GLAPIENTRY glRasterPos3dv( const GLdouble *v );
+GLAPI void GLAPIENTRY glRasterPos3fv( const GLfloat *v );
+GLAPI void GLAPIENTRY glRasterPos3iv( const GLint *v );
+GLAPI void GLAPIENTRY glRasterPos3sv( const GLshort *v );
+
+GLAPI void GLAPIENTRY glRasterPos4dv( const GLdouble *v );
+GLAPI void GLAPIENTRY glRasterPos4fv( const GLfloat *v );
+GLAPI void GLAPIENTRY glRasterPos4iv( const GLint *v );
+GLAPI void GLAPIENTRY glRasterPos4sv( const GLshort *v );
+
+
+GLAPI void GLAPIENTRY glRectd( GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2 );
+GLAPI void GLAPIENTRY glRectf( GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2 );
+GLAPI void GLAPIENTRY glRecti( GLint x1, GLint y1, GLint x2, GLint y2 );
+GLAPI void GLAPIENTRY glRects( GLshort x1, GLshort y1, GLshort x2, GLshort y2 );
+
+
+GLAPI void GLAPIENTRY glRectdv( const GLdouble *v1, const GLdouble *v2 );
+GLAPI void GLAPIENTRY glRectfv( const GLfloat *v1, const GLfloat *v2 );
+GLAPI void GLAPIENTRY glRectiv( const GLint *v1, const GLint *v2 );
+GLAPI void GLAPIENTRY glRectsv( const GLshort *v1, const GLshort *v2 );
+
+
+/*
+ * Vertex Arrays (1.1)
+ */
+
+GLAPI void GLAPIENTRY glVertexPointer( GLint size, GLenum type,
+ GLsizei stride, const GLvoid *ptr );
+
+GLAPI void GLAPIENTRY glNormalPointer( GLenum type, GLsizei stride,
+ const GLvoid *ptr );
+
+GLAPI void GLAPIENTRY glColorPointer( GLint size, GLenum type,
+ GLsizei stride, const GLvoid *ptr );
+
+GLAPI void GLAPIENTRY glIndexPointer( GLenum type, GLsizei stride,
+ const GLvoid *ptr );
+
+GLAPI void GLAPIENTRY glTexCoordPointer( GLint size, GLenum type,
+ GLsizei stride, const GLvoid *ptr );
+
+GLAPI void GLAPIENTRY glEdgeFlagPointer( GLsizei stride, const GLvoid *ptr );
+
+GLAPI void GLAPIENTRY glGetPointerv( GLenum pname, GLvoid **params );
+
+GLAPI void GLAPIENTRY glArrayElement( GLint i );
+
+GLAPI void GLAPIENTRY glDrawArrays( GLenum mode, GLint first, GLsizei count );
+
+GLAPI void GLAPIENTRY glDrawElements( GLenum mode, GLsizei count,
+ GLenum type, const GLvoid *indices );
+
+GLAPI void GLAPIENTRY glInterleavedArrays( GLenum format, GLsizei stride,
+ const GLvoid *pointer );
+
+/*
+ * Lighting
+ */
+
+GLAPI void GLAPIENTRY glShadeModel( GLenum mode );
+
+GLAPI void GLAPIENTRY glLightf( GLenum light, GLenum pname, GLfloat param );
+GLAPI void GLAPIENTRY glLighti( GLenum light, GLenum pname, GLint param );
+GLAPI void GLAPIENTRY glLightfv( GLenum light, GLenum pname,
+ const GLfloat *params );
+GLAPI void GLAPIENTRY glLightiv( GLenum light, GLenum pname,
+ const GLint *params );
+
+GLAPI void GLAPIENTRY glGetLightfv( GLenum light, GLenum pname,
+ GLfloat *params );
+GLAPI void GLAPIENTRY glGetLightiv( GLenum light, GLenum pname,
+ GLint *params );
+
+GLAPI void GLAPIENTRY glLightModelf( GLenum pname, GLfloat param );
+GLAPI void GLAPIENTRY glLightModeli( GLenum pname, GLint param );
+GLAPI void GLAPIENTRY glLightModelfv( GLenum pname, const GLfloat *params );
+GLAPI void GLAPIENTRY glLightModeliv( GLenum pname, const GLint *params );
+
+GLAPI void GLAPIENTRY glMaterialf( GLenum face, GLenum pname, GLfloat param );
+GLAPI void GLAPIENTRY glMateriali( GLenum face, GLenum pname, GLint param );
+GLAPI void GLAPIENTRY glMaterialfv( GLenum face, GLenum pname, const GLfloat *params );
+GLAPI void GLAPIENTRY glMaterialiv( GLenum face, GLenum pname, const GLint *params );
+
+GLAPI void GLAPIENTRY glGetMaterialfv( GLenum face, GLenum pname, GLfloat *params );
+GLAPI void GLAPIENTRY glGetMaterialiv( GLenum face, GLenum pname, GLint *params );
+
+GLAPI void GLAPIENTRY glColorMaterial( GLenum face, GLenum mode );
+
+
+/*
+ * Raster functions
+ */
+
+GLAPI void GLAPIENTRY glPixelZoom( GLfloat xfactor, GLfloat yfactor );
+
+GLAPI void GLAPIENTRY glPixelStoref( GLenum pname, GLfloat param );
+GLAPI void GLAPIENTRY glPixelStorei( GLenum pname, GLint param );
+
+GLAPI void GLAPIENTRY glPixelTransferf( GLenum pname, GLfloat param );
+GLAPI void GLAPIENTRY glPixelTransferi( GLenum pname, GLint param );
+
+GLAPI void GLAPIENTRY glPixelMapfv( GLenum map, GLsizei mapsize,
+ const GLfloat *values );
+GLAPI void GLAPIENTRY glPixelMapuiv( GLenum map, GLsizei mapsize,
+ const GLuint *values );
+GLAPI void GLAPIENTRY glPixelMapusv( GLenum map, GLsizei mapsize,
+ const GLushort *values );
+
+GLAPI void GLAPIENTRY glGetPixelMapfv( GLenum map, GLfloat *values );
+GLAPI void GLAPIENTRY glGetPixelMapuiv( GLenum map, GLuint *values );
+GLAPI void GLAPIENTRY glGetPixelMapusv( GLenum map, GLushort *values );
+
+GLAPI void GLAPIENTRY glBitmap( GLsizei width, GLsizei height,
+ GLfloat xorig, GLfloat yorig,
+ GLfloat xmove, GLfloat ymove,
+ const GLubyte *bitmap );
+
+GLAPI void GLAPIENTRY glReadPixels( GLint x, GLint y,
+ GLsizei width, GLsizei height,
+ GLenum format, GLenum type,
+ GLvoid *pixels );
+
+GLAPI void GLAPIENTRY glDrawPixels( GLsizei width, GLsizei height,
+ GLenum format, GLenum type,
+ const GLvoid *pixels );
+
+GLAPI void GLAPIENTRY glCopyPixels( GLint x, GLint y,
+ GLsizei width, GLsizei height,
+ GLenum type );
+
+/*
+ * Stenciling
+ */
+
+GLAPI void GLAPIENTRY glStencilFunc( GLenum func, GLint ref, GLuint mask );
+
+GLAPI void GLAPIENTRY glStencilMask( GLuint mask );
+
+GLAPI void GLAPIENTRY glStencilOp( GLenum fail, GLenum zfail, GLenum zpass );
+
+GLAPI void GLAPIENTRY glClearStencil( GLint s );
+
+
+
+/*
+ * Texture mapping
+ */
+
+GLAPI void GLAPIENTRY glTexGend( GLenum coord, GLenum pname, GLdouble param );
+GLAPI void GLAPIENTRY glTexGenf( GLenum coord, GLenum pname, GLfloat param );
+GLAPI void GLAPIENTRY glTexGeni( GLenum coord, GLenum pname, GLint param );
+
+GLAPI void GLAPIENTRY glTexGendv( GLenum coord, GLenum pname, const GLdouble *params );
+GLAPI void GLAPIENTRY glTexGenfv( GLenum coord, GLenum pname, const GLfloat *params );
+GLAPI void GLAPIENTRY glTexGeniv( GLenum coord, GLenum pname, const GLint *params );
+
+GLAPI void GLAPIENTRY glGetTexGendv( GLenum coord, GLenum pname, GLdouble *params );
+GLAPI void GLAPIENTRY glGetTexGenfv( GLenum coord, GLenum pname, GLfloat *params );
+GLAPI void GLAPIENTRY glGetTexGeniv( GLenum coord, GLenum pname, GLint *params );
+
+
+GLAPI void GLAPIENTRY glTexEnvf( GLenum target, GLenum pname, GLfloat param );
+GLAPI void GLAPIENTRY glTexEnvi( GLenum target, GLenum pname, GLint param );
+
+GLAPI void GLAPIENTRY glTexEnvfv( GLenum target, GLenum pname, const GLfloat *params );
+GLAPI void GLAPIENTRY glTexEnviv( GLenum target, GLenum pname, const GLint *params );
+
+GLAPI void GLAPIENTRY glGetTexEnvfv( GLenum target, GLenum pname, GLfloat *params );
+GLAPI void GLAPIENTRY glGetTexEnviv( GLenum target, GLenum pname, GLint *params );
+
+
+GLAPI void GLAPIENTRY glTexParameterf( GLenum target, GLenum pname, GLfloat param );
+GLAPI void GLAPIENTRY glTexParameteri( GLenum target, GLenum pname, GLint param );
+
+GLAPI void GLAPIENTRY glTexParameterfv( GLenum target, GLenum pname,
+ const GLfloat *params );
+GLAPI void GLAPIENTRY glTexParameteriv( GLenum target, GLenum pname,
+ const GLint *params );
+
+GLAPI void GLAPIENTRY glGetTexParameterfv( GLenum target,
+ GLenum pname, GLfloat *params);
+GLAPI void GLAPIENTRY glGetTexParameteriv( GLenum target,
+ GLenum pname, GLint *params );
+
+GLAPI void GLAPIENTRY glGetTexLevelParameterfv( GLenum target, GLint level,
+ GLenum pname, GLfloat *params );
+GLAPI void GLAPIENTRY glGetTexLevelParameteriv( GLenum target, GLint level,
+ GLenum pname, GLint *params );
+
+
+GLAPI void GLAPIENTRY glTexImage1D( GLenum target, GLint level,
+ GLint internalFormat,
+ GLsizei width, GLint border,
+ GLenum format, GLenum type,
+ const GLvoid *pixels );
+
+GLAPI void GLAPIENTRY glTexImage2D( GLenum target, GLint level,
+ GLint internalFormat,
+ GLsizei width, GLsizei height,
+ GLint border, GLenum format, GLenum type,
+ const GLvoid *pixels );
+
+GLAPI void GLAPIENTRY glGetTexImage( GLenum target, GLint level,
+ GLenum format, GLenum type,
+ GLvoid *pixels );
+
+
+/* 1.1 functions */
+
+GLAPI void GLAPIENTRY glGenTextures( GLsizei n, GLuint *textures );
+
+GLAPI void GLAPIENTRY glDeleteTextures( GLsizei n, const GLuint *textures);
+
+GLAPI void GLAPIENTRY glBindTexture( GLenum target, GLuint texture );
+
+GLAPI void GLAPIENTRY glPrioritizeTextures( GLsizei n,
+ const GLuint *textures,
+ const GLclampf *priorities );
+
+GLAPI GLboolean GLAPIENTRY glAreTexturesResident( GLsizei n,
+ const GLuint *textures,
+ GLboolean *residences );
+
+GLAPI GLboolean GLAPIENTRY glIsTexture( GLuint texture );
+
+
+GLAPI void GLAPIENTRY glTexSubImage1D( GLenum target, GLint level,
+ GLint xoffset,
+ GLsizei width, GLenum format,
+ GLenum type, const GLvoid *pixels );
+
+
+GLAPI void GLAPIENTRY glTexSubImage2D( GLenum target, GLint level,
+ GLint xoffset, GLint yoffset,
+ GLsizei width, GLsizei height,
+ GLenum format, GLenum type,
+ const GLvoid *pixels );
+
+
+GLAPI void GLAPIENTRY glCopyTexImage1D( GLenum target, GLint level,
+ GLenum internalformat,
+ GLint x, GLint y,
+ GLsizei width, GLint border );
+
+
+GLAPI void GLAPIENTRY glCopyTexImage2D( GLenum target, GLint level,
+ GLenum internalformat,
+ GLint x, GLint y,
+ GLsizei width, GLsizei height,
+ GLint border );
+
+
+GLAPI void GLAPIENTRY glCopyTexSubImage1D( GLenum target, GLint level,
+ GLint xoffset, GLint x, GLint y,
+ GLsizei width );
+
+
+GLAPI void GLAPIENTRY glCopyTexSubImage2D( GLenum target, GLint level,
+ GLint xoffset, GLint yoffset,
+ GLint x, GLint y,
+ GLsizei width, GLsizei height );
+
+
+/*
+ * Evaluators
+ */
+
+GLAPI void GLAPIENTRY glMap1d( GLenum target, GLdouble u1, GLdouble u2,
+ GLint stride,
+ GLint order, const GLdouble *points );
+GLAPI void GLAPIENTRY glMap1f( GLenum target, GLfloat u1, GLfloat u2,
+ GLint stride,
+ GLint order, const GLfloat *points );
+
+GLAPI void GLAPIENTRY glMap2d( GLenum target,
+ GLdouble u1, GLdouble u2, GLint ustride, GLint uorder,
+ GLdouble v1, GLdouble v2, GLint vstride, GLint vorder,
+ const GLdouble *points );
+GLAPI void GLAPIENTRY glMap2f( GLenum target,
+ GLfloat u1, GLfloat u2, GLint ustride, GLint uorder,
+ GLfloat v1, GLfloat v2, GLint vstride, GLint vorder,
+ const GLfloat *points );
+
+GLAPI void GLAPIENTRY glGetMapdv( GLenum target, GLenum query, GLdouble *v );
+GLAPI void GLAPIENTRY glGetMapfv( GLenum target, GLenum query, GLfloat *v );
+GLAPI void GLAPIENTRY glGetMapiv( GLenum target, GLenum query, GLint *v );
+
+GLAPI void GLAPIENTRY glEvalCoord1d( GLdouble u );
+GLAPI void GLAPIENTRY glEvalCoord1f( GLfloat u );
+
+GLAPI void GLAPIENTRY glEvalCoord1dv( const GLdouble *u );
+GLAPI void GLAPIENTRY glEvalCoord1fv( const GLfloat *u );
+
+GLAPI void GLAPIENTRY glEvalCoord2d( GLdouble u, GLdouble v );
+GLAPI void GLAPIENTRY glEvalCoord2f( GLfloat u, GLfloat v );
+
+GLAPI void GLAPIENTRY glEvalCoord2dv( const GLdouble *u );
+GLAPI void GLAPIENTRY glEvalCoord2fv( const GLfloat *u );
+
+GLAPI void GLAPIENTRY glMapGrid1d( GLint un, GLdouble u1, GLdouble u2 );
+GLAPI void GLAPIENTRY glMapGrid1f( GLint un, GLfloat u1, GLfloat u2 );
+
+GLAPI void GLAPIENTRY glMapGrid2d( GLint un, GLdouble u1, GLdouble u2,
+ GLint vn, GLdouble v1, GLdouble v2 );
+GLAPI void GLAPIENTRY glMapGrid2f( GLint un, GLfloat u1, GLfloat u2,
+ GLint vn, GLfloat v1, GLfloat v2 );
+
+GLAPI void GLAPIENTRY glEvalPoint1( GLint i );
+
+GLAPI void GLAPIENTRY glEvalPoint2( GLint i, GLint j );
+
+GLAPI void GLAPIENTRY glEvalMesh1( GLenum mode, GLint i1, GLint i2 );
+
+GLAPI void GLAPIENTRY glEvalMesh2( GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2 );
+
+
+/*
+ * Fog
+ */
+
+GLAPI void GLAPIENTRY glFogf( GLenum pname, GLfloat param );
+
+GLAPI void GLAPIENTRY glFogi( GLenum pname, GLint param );
+
+GLAPI void GLAPIENTRY glFogfv( GLenum pname, const GLfloat *params );
+
+GLAPI void GLAPIENTRY glFogiv( GLenum pname, const GLint *params );
+
+
+/*
+ * Selection and Feedback
+ */
+
+GLAPI void GLAPIENTRY glFeedbackBuffer( GLsizei size, GLenum type, GLfloat *buffer );
+
+GLAPI void GLAPIENTRY glPassThrough( GLfloat token );
+
+GLAPI void GLAPIENTRY glSelectBuffer( GLsizei size, GLuint *buffer );
+
+GLAPI void GLAPIENTRY glInitNames( void );
+
+GLAPI void GLAPIENTRY glLoadName( GLuint name );
+
+GLAPI void GLAPIENTRY glPushName( GLuint name );
+
+GLAPI void GLAPIENTRY glPopName( void );
+
+
+
+/*
+ * OpenGL 1.2
+ */
+
+#define GL_RESCALE_NORMAL 0x803A
+#define GL_CLAMP_TO_EDGE 0x812F
+#define GL_MAX_ELEMENTS_VERTICES 0x80E8
+#define GL_MAX_ELEMENTS_INDICES 0x80E9
+#define GL_BGR 0x80E0
+#define GL_BGRA 0x80E1
+#define GL_UNSIGNED_BYTE_3_3_2 0x8032
+#define GL_UNSIGNED_BYTE_2_3_3_REV 0x8362
+#define GL_UNSIGNED_SHORT_5_6_5 0x8363
+#define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364
+#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033
+#define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365
+#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034
+#define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366
+#define GL_UNSIGNED_INT_8_8_8_8 0x8035
+#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367
+#define GL_UNSIGNED_INT_10_10_10_2 0x8036
+#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368
+#define GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8
+#define GL_SINGLE_COLOR 0x81F9
+#define GL_SEPARATE_SPECULAR_COLOR 0x81FA
+#define GL_TEXTURE_MIN_LOD 0x813A
+#define GL_TEXTURE_MAX_LOD 0x813B
+#define GL_TEXTURE_BASE_LEVEL 0x813C
+#define GL_TEXTURE_MAX_LEVEL 0x813D
+#define GL_SMOOTH_POINT_SIZE_RANGE 0x0B12
+#define GL_SMOOTH_POINT_SIZE_GRANULARITY 0x0B13
+#define GL_SMOOTH_LINE_WIDTH_RANGE 0x0B22
+#define GL_SMOOTH_LINE_WIDTH_GRANULARITY 0x0B23
+#define GL_ALIASED_POINT_SIZE_RANGE 0x846D
+#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E
+#define GL_PACK_SKIP_IMAGES 0x806B
+#define GL_PACK_IMAGE_HEIGHT 0x806C
+#define GL_UNPACK_SKIP_IMAGES 0x806D
+#define GL_UNPACK_IMAGE_HEIGHT 0x806E
+#define GL_TEXTURE_3D 0x806F
+#define GL_PROXY_TEXTURE_3D 0x8070
+#define GL_TEXTURE_DEPTH 0x8071
+#define GL_TEXTURE_WRAP_R 0x8072
+#define GL_MAX_3D_TEXTURE_SIZE 0x8073
+#define GL_TEXTURE_BINDING_3D 0x806A
+
+GLAPI void GLAPIENTRY glDrawRangeElements( GLenum mode, GLuint start,
+ GLuint end, GLsizei count, GLenum type, const GLvoid *indices );
+
+GLAPI void GLAPIENTRY glTexImage3D( GLenum target, GLint level,
+ GLint internalFormat,
+ GLsizei width, GLsizei height,
+ GLsizei depth, GLint border,
+ GLenum format, GLenum type,
+ const GLvoid *pixels );
+
+GLAPI void GLAPIENTRY glTexSubImage3D( GLenum target, GLint level,
+ GLint xoffset, GLint yoffset,
+ GLint zoffset, GLsizei width,
+ GLsizei height, GLsizei depth,
+ GLenum format,
+ GLenum type, const GLvoid *pixels);
+
+GLAPI void GLAPIENTRY glCopyTexSubImage3D( GLenum target, GLint level,
+ GLint xoffset, GLint yoffset,
+ GLint zoffset, GLint x,
+ GLint y, GLsizei width,
+ GLsizei height );
+
+typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices);
+typedef void (APIENTRYP PFNGLTEXIMAGE3DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (APIENTRYP PFNGLTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+
+
+/*
+ * GL_ARB_imaging
+ */
+
+#define GL_CONSTANT_COLOR 0x8001
+#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002
+#define GL_CONSTANT_ALPHA 0x8003
+#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004
+#define GL_COLOR_TABLE 0x80D0
+#define GL_POST_CONVOLUTION_COLOR_TABLE 0x80D1
+#define GL_POST_COLOR_MATRIX_COLOR_TABLE 0x80D2
+#define GL_PROXY_COLOR_TABLE 0x80D3
+#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE 0x80D4
+#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE 0x80D5
+#define GL_COLOR_TABLE_SCALE 0x80D6
+#define GL_COLOR_TABLE_BIAS 0x80D7
+#define GL_COLOR_TABLE_FORMAT 0x80D8
+#define GL_COLOR_TABLE_WIDTH 0x80D9
+#define GL_COLOR_TABLE_RED_SIZE 0x80DA
+#define GL_COLOR_TABLE_GREEN_SIZE 0x80DB
+#define GL_COLOR_TABLE_BLUE_SIZE 0x80DC
+#define GL_COLOR_TABLE_ALPHA_SIZE 0x80DD
+#define GL_COLOR_TABLE_LUMINANCE_SIZE 0x80DE
+#define GL_COLOR_TABLE_INTENSITY_SIZE 0x80DF
+#define GL_CONVOLUTION_1D 0x8010
+#define GL_CONVOLUTION_2D 0x8011
+#define GL_SEPARABLE_2D 0x8012
+#define GL_CONVOLUTION_BORDER_MODE 0x8013
+#define GL_CONVOLUTION_FILTER_SCALE 0x8014
+#define GL_CONVOLUTION_FILTER_BIAS 0x8015
+#define GL_REDUCE 0x8016
+#define GL_CONVOLUTION_FORMAT 0x8017
+#define GL_CONVOLUTION_WIDTH 0x8018
+#define GL_CONVOLUTION_HEIGHT 0x8019
+#define GL_MAX_CONVOLUTION_WIDTH 0x801A
+#define GL_MAX_CONVOLUTION_HEIGHT 0x801B
+#define GL_POST_CONVOLUTION_RED_SCALE 0x801C
+#define GL_POST_CONVOLUTION_GREEN_SCALE 0x801D
+#define GL_POST_CONVOLUTION_BLUE_SCALE 0x801E
+#define GL_POST_CONVOLUTION_ALPHA_SCALE 0x801F
+#define GL_POST_CONVOLUTION_RED_BIAS 0x8020
+#define GL_POST_CONVOLUTION_GREEN_BIAS 0x8021
+#define GL_POST_CONVOLUTION_BLUE_BIAS 0x8022
+#define GL_POST_CONVOLUTION_ALPHA_BIAS 0x8023
+#define GL_CONSTANT_BORDER 0x8151
+#define GL_REPLICATE_BORDER 0x8153
+#define GL_CONVOLUTION_BORDER_COLOR 0x8154
+#define GL_COLOR_MATRIX 0x80B1
+#define GL_COLOR_MATRIX_STACK_DEPTH 0x80B2
+#define GL_MAX_COLOR_MATRIX_STACK_DEPTH 0x80B3
+#define GL_POST_COLOR_MATRIX_RED_SCALE 0x80B4
+#define GL_POST_COLOR_MATRIX_GREEN_SCALE 0x80B5
+#define GL_POST_COLOR_MATRIX_BLUE_SCALE 0x80B6
+#define GL_POST_COLOR_MATRIX_ALPHA_SCALE 0x80B7
+#define GL_POST_COLOR_MATRIX_RED_BIAS 0x80B8
+#define GL_POST_COLOR_MATRIX_GREEN_BIAS 0x80B9
+#define GL_POST_COLOR_MATRIX_BLUE_BIAS 0x80BA
+#define GL_POST_COLOR_MATRIX_ALPHA_BIAS 0x80BB
+#define GL_HISTOGRAM 0x8024
+#define GL_PROXY_HISTOGRAM 0x8025
+#define GL_HISTOGRAM_WIDTH 0x8026
+#define GL_HISTOGRAM_FORMAT 0x8027
+#define GL_HISTOGRAM_RED_SIZE 0x8028
+#define GL_HISTOGRAM_GREEN_SIZE 0x8029
+#define GL_HISTOGRAM_BLUE_SIZE 0x802A
+#define GL_HISTOGRAM_ALPHA_SIZE 0x802B
+#define GL_HISTOGRAM_LUMINANCE_SIZE 0x802C
+#define GL_HISTOGRAM_SINK 0x802D
+#define GL_MINMAX 0x802E
+#define GL_MINMAX_FORMAT 0x802F
+#define GL_MINMAX_SINK 0x8030
+#define GL_TABLE_TOO_LARGE 0x8031
+#define GL_BLEND_EQUATION 0x8009
+#define GL_MIN 0x8007
+#define GL_MAX 0x8008
+#define GL_FUNC_ADD 0x8006
+#define GL_FUNC_SUBTRACT 0x800A
+#define GL_FUNC_REVERSE_SUBTRACT 0x800B
+#define GL_BLEND_COLOR 0x8005
+
+
+GLAPI void GLAPIENTRY glColorTable( GLenum target, GLenum internalformat,
+ GLsizei width, GLenum format,
+ GLenum type, const GLvoid *table );
+
+GLAPI void GLAPIENTRY glColorSubTable( GLenum target,
+ GLsizei start, GLsizei count,
+ GLenum format, GLenum type,
+ const GLvoid *data );
+
+GLAPI void GLAPIENTRY glColorTableParameteriv(GLenum target, GLenum pname,
+ const GLint *params);
+
+GLAPI void GLAPIENTRY glColorTableParameterfv(GLenum target, GLenum pname,
+ const GLfloat *params);
+
+GLAPI void GLAPIENTRY glCopyColorSubTable( GLenum target, GLsizei start,
+ GLint x, GLint y, GLsizei width );
+
+GLAPI void GLAPIENTRY glCopyColorTable( GLenum target, GLenum internalformat,
+ GLint x, GLint y, GLsizei width );
+
+GLAPI void GLAPIENTRY glGetColorTable( GLenum target, GLenum format,
+ GLenum type, GLvoid *table );
+
+GLAPI void GLAPIENTRY glGetColorTableParameterfv( GLenum target, GLenum pname,
+ GLfloat *params );
+
+GLAPI void GLAPIENTRY glGetColorTableParameteriv( GLenum target, GLenum pname,
+ GLint *params );
+
+GLAPI void GLAPIENTRY glBlendEquation( GLenum mode );
+
+GLAPI void GLAPIENTRY glBlendColor( GLclampf red, GLclampf green,
+ GLclampf blue, GLclampf alpha );
+
+GLAPI void GLAPIENTRY glHistogram( GLenum target, GLsizei width,
+ GLenum internalformat, GLboolean sink );
+
+GLAPI void GLAPIENTRY glResetHistogram( GLenum target );
+
+GLAPI void GLAPIENTRY glGetHistogram( GLenum target, GLboolean reset,
+ GLenum format, GLenum type,
+ GLvoid *values );
+
+GLAPI void GLAPIENTRY glGetHistogramParameterfv( GLenum target, GLenum pname,
+ GLfloat *params );
+
+GLAPI void GLAPIENTRY glGetHistogramParameteriv( GLenum target, GLenum pname,
+ GLint *params );
+
+GLAPI void GLAPIENTRY glMinmax( GLenum target, GLenum internalformat,
+ GLboolean sink );
+
+GLAPI void GLAPIENTRY glResetMinmax( GLenum target );
+
+GLAPI void GLAPIENTRY glGetMinmax( GLenum target, GLboolean reset,
+ GLenum format, GLenum types,
+ GLvoid *values );
+
+GLAPI void GLAPIENTRY glGetMinmaxParameterfv( GLenum target, GLenum pname,
+ GLfloat *params );
+
+GLAPI void GLAPIENTRY glGetMinmaxParameteriv( GLenum target, GLenum pname,
+ GLint *params );
+
+GLAPI void GLAPIENTRY glConvolutionFilter1D( GLenum target,
+ GLenum internalformat, GLsizei width, GLenum format, GLenum type,
+ const GLvoid *image );
+
+GLAPI void GLAPIENTRY glConvolutionFilter2D( GLenum target,
+ GLenum internalformat, GLsizei width, GLsizei height, GLenum format,
+ GLenum type, const GLvoid *image );
+
+GLAPI void GLAPIENTRY glConvolutionParameterf( GLenum target, GLenum pname,
+ GLfloat params );
+
+GLAPI void GLAPIENTRY glConvolutionParameterfv( GLenum target, GLenum pname,
+ const GLfloat *params );
+
+GLAPI void GLAPIENTRY glConvolutionParameteri( GLenum target, GLenum pname,
+ GLint params );
+
+GLAPI void GLAPIENTRY glConvolutionParameteriv( GLenum target, GLenum pname,
+ const GLint *params );
+
+GLAPI void GLAPIENTRY glCopyConvolutionFilter1D( GLenum target,
+ GLenum internalformat, GLint x, GLint y, GLsizei width );
+
+GLAPI void GLAPIENTRY glCopyConvolutionFilter2D( GLenum target,
+ GLenum internalformat, GLint x, GLint y, GLsizei width,
+ GLsizei height);
+
+GLAPI void GLAPIENTRY glGetConvolutionFilter( GLenum target, GLenum format,
+ GLenum type, GLvoid *image );
+
+GLAPI void GLAPIENTRY glGetConvolutionParameterfv( GLenum target, GLenum pname,
+ GLfloat *params );
+
+GLAPI void GLAPIENTRY glGetConvolutionParameteriv( GLenum target, GLenum pname,
+ GLint *params );
+
+GLAPI void GLAPIENTRY glSeparableFilter2D( GLenum target,
+ GLenum internalformat, GLsizei width, GLsizei height, GLenum format,
+ GLenum type, const GLvoid *row, const GLvoid *column );
+
+GLAPI void GLAPIENTRY glGetSeparableFilter( GLenum target, GLenum format,
+ GLenum type, GLvoid *row, GLvoid *column, GLvoid *span );
+
+typedef void (APIENTRYP PFNGLBLENDCOLORPROC) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+typedef void (APIENTRYP PFNGLBLENDEQUATIONPROC) (GLenum mode);
+typedef void (APIENTRYP PFNGLCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table);
+typedef void (APIENTRYP PFNGLCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLCOPYCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width);
+typedef void (APIENTRYP PFNGLGETCOLORTABLEPROC) (GLenum target, GLenum format, GLenum type, GLvoid *table);
+typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data);
+typedef void (APIENTRYP PFNGLCOPYCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width);
+typedef void (APIENTRYP PFNGLCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *image);
+typedef void (APIENTRYP PFNGLCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image);
+typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERFPROC) (GLenum target, GLenum pname, GLfloat params);
+typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERIPROC) (GLenum target, GLenum pname, GLint params);
+typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLCOPYCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width);
+typedef void (APIENTRYP PFNGLCOPYCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (APIENTRYP PFNGLGETCONVOLUTIONFILTERPROC) (GLenum target, GLenum format, GLenum type, GLvoid *image);
+typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETSEPARABLEFILTERPROC) (GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span);
+typedef void (APIENTRYP PFNGLSEPARABLEFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column);
+typedef void (APIENTRYP PFNGLGETHISTOGRAMPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values);
+typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETMINMAXPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values);
+typedef void (APIENTRYP PFNGLGETMINMAXPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETMINMAXPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLHISTOGRAMPROC) (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink);
+typedef void (APIENTRYP PFNGLMINMAXPROC) (GLenum target, GLenum internalformat, GLboolean sink);
+typedef void (APIENTRYP PFNGLRESETHISTOGRAMPROC) (GLenum target);
+typedef void (APIENTRYP PFNGLRESETMINMAXPROC) (GLenum target);
+
+
+
+/*
+ * OpenGL 1.3
+ */
+
+/* multitexture */
+#define GL_TEXTURE0 0x84C0
+#define GL_TEXTURE1 0x84C1
+#define GL_TEXTURE2 0x84C2
+#define GL_TEXTURE3 0x84C3
+#define GL_TEXTURE4 0x84C4
+#define GL_TEXTURE5 0x84C5
+#define GL_TEXTURE6 0x84C6
+#define GL_TEXTURE7 0x84C7
+#define GL_TEXTURE8 0x84C8
+#define GL_TEXTURE9 0x84C9
+#define GL_TEXTURE10 0x84CA
+#define GL_TEXTURE11 0x84CB
+#define GL_TEXTURE12 0x84CC
+#define GL_TEXTURE13 0x84CD
+#define GL_TEXTURE14 0x84CE
+#define GL_TEXTURE15 0x84CF
+#define GL_TEXTURE16 0x84D0
+#define GL_TEXTURE17 0x84D1
+#define GL_TEXTURE18 0x84D2
+#define GL_TEXTURE19 0x84D3
+#define GL_TEXTURE20 0x84D4
+#define GL_TEXTURE21 0x84D5
+#define GL_TEXTURE22 0x84D6
+#define GL_TEXTURE23 0x84D7
+#define GL_TEXTURE24 0x84D8
+#define GL_TEXTURE25 0x84D9
+#define GL_TEXTURE26 0x84DA
+#define GL_TEXTURE27 0x84DB
+#define GL_TEXTURE28 0x84DC
+#define GL_TEXTURE29 0x84DD
+#define GL_TEXTURE30 0x84DE
+#define GL_TEXTURE31 0x84DF
+#define GL_ACTIVE_TEXTURE 0x84E0
+#define GL_CLIENT_ACTIVE_TEXTURE 0x84E1
+#define GL_MAX_TEXTURE_UNITS 0x84E2
+/* texture_cube_map */
+#define GL_NORMAL_MAP 0x8511
+#define GL_REFLECTION_MAP 0x8512
+#define GL_TEXTURE_CUBE_MAP 0x8513
+#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A
+#define GL_PROXY_TEXTURE_CUBE_MAP 0x851B
+#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C
+/* texture_compression */
+#define GL_COMPRESSED_ALPHA 0x84E9
+#define GL_COMPRESSED_LUMINANCE 0x84EA
+#define GL_COMPRESSED_LUMINANCE_ALPHA 0x84EB
+#define GL_COMPRESSED_INTENSITY 0x84EC
+#define GL_COMPRESSED_RGB 0x84ED
+#define GL_COMPRESSED_RGBA 0x84EE
+#define GL_TEXTURE_COMPRESSION_HINT 0x84EF
+#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE 0x86A0
+#define GL_TEXTURE_COMPRESSED 0x86A1
+#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2
+#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3
+/* multisample */
+#define GL_MULTISAMPLE 0x809D
+#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E
+#define GL_SAMPLE_ALPHA_TO_ONE 0x809F
+#define GL_SAMPLE_COVERAGE 0x80A0
+#define GL_SAMPLE_BUFFERS 0x80A8
+#define GL_SAMPLES 0x80A9
+#define GL_SAMPLE_COVERAGE_VALUE 0x80AA
+#define GL_SAMPLE_COVERAGE_INVERT 0x80AB
+#define GL_MULTISAMPLE_BIT 0x20000000
+/* transpose_matrix */
+#define GL_TRANSPOSE_MODELVIEW_MATRIX 0x84E3
+#define GL_TRANSPOSE_PROJECTION_MATRIX 0x84E4
+#define GL_TRANSPOSE_TEXTURE_MATRIX 0x84E5
+#define GL_TRANSPOSE_COLOR_MATRIX 0x84E6
+/* texture_env_combine */
+#define GL_COMBINE 0x8570
+#define GL_COMBINE_RGB 0x8571
+#define GL_COMBINE_ALPHA 0x8572
+#define GL_SOURCE0_RGB 0x8580
+#define GL_SOURCE1_RGB 0x8581
+#define GL_SOURCE2_RGB 0x8582
+#define GL_SOURCE0_ALPHA 0x8588
+#define GL_SOURCE1_ALPHA 0x8589
+#define GL_SOURCE2_ALPHA 0x858A
+#define GL_OPERAND0_RGB 0x8590
+#define GL_OPERAND1_RGB 0x8591
+#define GL_OPERAND2_RGB 0x8592
+#define GL_OPERAND0_ALPHA 0x8598
+#define GL_OPERAND1_ALPHA 0x8599
+#define GL_OPERAND2_ALPHA 0x859A
+#define GL_RGB_SCALE 0x8573
+#define GL_ADD_SIGNED 0x8574
+#define GL_INTERPOLATE 0x8575
+#define GL_SUBTRACT 0x84E7
+#define GL_CONSTANT 0x8576
+#define GL_PRIMARY_COLOR 0x8577
+#define GL_PREVIOUS 0x8578
+/* texture_env_dot3 */
+#define GL_DOT3_RGB 0x86AE
+#define GL_DOT3_RGBA 0x86AF
+/* texture_border_clamp */
+#define GL_CLAMP_TO_BORDER 0x812D
+
+GLAPI void GLAPIENTRY glActiveTexture( GLenum texture );
+
+GLAPI void GLAPIENTRY glClientActiveTexture( GLenum texture );
+
+GLAPI void GLAPIENTRY glCompressedTexImage1D( GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data );
+
+GLAPI void GLAPIENTRY glCompressedTexImage2D( GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data );
+
+GLAPI void GLAPIENTRY glCompressedTexImage3D( GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data );
+
+GLAPI void GLAPIENTRY glCompressedTexSubImage1D( GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data );
+
+GLAPI void GLAPIENTRY glCompressedTexSubImage2D( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data );
+
+GLAPI void GLAPIENTRY glCompressedTexSubImage3D( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data );
+
+GLAPI void GLAPIENTRY glGetCompressedTexImage( GLenum target, GLint lod, GLvoid *img );
+
+GLAPI void GLAPIENTRY glMultiTexCoord1d( GLenum target, GLdouble s );
+
+GLAPI void GLAPIENTRY glMultiTexCoord1dv( GLenum target, const GLdouble *v );
+
+GLAPI void GLAPIENTRY glMultiTexCoord1f( GLenum target, GLfloat s );
+
+GLAPI void GLAPIENTRY glMultiTexCoord1fv( GLenum target, const GLfloat *v );
+
+GLAPI void GLAPIENTRY glMultiTexCoord1i( GLenum target, GLint s );
+
+GLAPI void GLAPIENTRY glMultiTexCoord1iv( GLenum target, const GLint *v );
+
+GLAPI void GLAPIENTRY glMultiTexCoord1s( GLenum target, GLshort s );
+
+GLAPI void GLAPIENTRY glMultiTexCoord1sv( GLenum target, const GLshort *v );
+
+GLAPI void GLAPIENTRY glMultiTexCoord2d( GLenum target, GLdouble s, GLdouble t );
+
+GLAPI void GLAPIENTRY glMultiTexCoord2dv( GLenum target, const GLdouble *v );
+
+GLAPI void GLAPIENTRY glMultiTexCoord2f( GLenum target, GLfloat s, GLfloat t );
+
+GLAPI void GLAPIENTRY glMultiTexCoord2fv( GLenum target, const GLfloat *v );
+
+GLAPI void GLAPIENTRY glMultiTexCoord2i( GLenum target, GLint s, GLint t );
+
+GLAPI void GLAPIENTRY glMultiTexCoord2iv( GLenum target, const GLint *v );
+
+GLAPI void GLAPIENTRY glMultiTexCoord2s( GLenum target, GLshort s, GLshort t );
+
+GLAPI void GLAPIENTRY glMultiTexCoord2sv( GLenum target, const GLshort *v );
+
+GLAPI void GLAPIENTRY glMultiTexCoord3d( GLenum target, GLdouble s, GLdouble t, GLdouble r );
+
+GLAPI void GLAPIENTRY glMultiTexCoord3dv( GLenum target, const GLdouble *v );
+
+GLAPI void GLAPIENTRY glMultiTexCoord3f( GLenum target, GLfloat s, GLfloat t, GLfloat r );
+
+GLAPI void GLAPIENTRY glMultiTexCoord3fv( GLenum target, const GLfloat *v );
+
+GLAPI void GLAPIENTRY glMultiTexCoord3i( GLenum target, GLint s, GLint t, GLint r );
+
+GLAPI void GLAPIENTRY glMultiTexCoord3iv( GLenum target, const GLint *v );
+
+GLAPI void GLAPIENTRY glMultiTexCoord3s( GLenum target, GLshort s, GLshort t, GLshort r );
+
+GLAPI void GLAPIENTRY glMultiTexCoord3sv( GLenum target, const GLshort *v );
+
+GLAPI void GLAPIENTRY glMultiTexCoord4d( GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q );
+
+GLAPI void GLAPIENTRY glMultiTexCoord4dv( GLenum target, const GLdouble *v );
+
+GLAPI void GLAPIENTRY glMultiTexCoord4f( GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q );
+
+GLAPI void GLAPIENTRY glMultiTexCoord4fv( GLenum target, const GLfloat *v );
+
+GLAPI void GLAPIENTRY glMultiTexCoord4i( GLenum target, GLint s, GLint t, GLint r, GLint q );
+
+GLAPI void GLAPIENTRY glMultiTexCoord4iv( GLenum target, const GLint *v );
+
+GLAPI void GLAPIENTRY glMultiTexCoord4s( GLenum target, GLshort s, GLshort t, GLshort r, GLshort q );
+
+GLAPI void GLAPIENTRY glMultiTexCoord4sv( GLenum target, const GLshort *v );
+
+
+GLAPI void GLAPIENTRY glLoadTransposeMatrixd( const GLdouble m[16] );
+
+GLAPI void GLAPIENTRY glLoadTransposeMatrixf( const GLfloat m[16] );
+
+GLAPI void GLAPIENTRY glMultTransposeMatrixd( const GLdouble m[16] );
+
+GLAPI void GLAPIENTRY glMultTransposeMatrixf( const GLfloat m[16] );
+
+GLAPI void GLAPIENTRY glSampleCoverage( GLclampf value, GLboolean invert );
+
+typedef void (APIENTRYP PFNGLACTIVETEXTUREPROC) (GLenum texture);
+typedef void (APIENTRYP PFNGLCLIENTACTIVETEXTUREPROC) (GLenum texture);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1DPROC) (GLenum target, GLdouble s);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1DVPROC) (GLenum target, const GLdouble *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1FPROC) (GLenum target, GLfloat s);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1FVPROC) (GLenum target, const GLfloat *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1IPROC) (GLenum target, GLint s);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1IVPROC) (GLenum target, const GLint *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1SPROC) (GLenum target, GLshort s);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1SVPROC) (GLenum target, const GLshort *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2DPROC) (GLenum target, GLdouble s, GLdouble t);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2DVPROC) (GLenum target, const GLdouble *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2FPROC) (GLenum target, GLfloat s, GLfloat t);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2FVPROC) (GLenum target, const GLfloat *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2IPROC) (GLenum target, GLint s, GLint t);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2IVPROC) (GLenum target, const GLint *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2SPROC) (GLenum target, GLshort s, GLshort t);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2SVPROC) (GLenum target, const GLshort *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3DPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3DVPROC) (GLenum target, const GLdouble *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3FPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3FVPROC) (GLenum target, const GLfloat *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3IPROC) (GLenum target, GLint s, GLint t, GLint r);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3IVPROC) (GLenum target, const GLint *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3SPROC) (GLenum target, GLshort s, GLshort t, GLshort r);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3SVPROC) (GLenum target, const GLshort *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4DPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4DVPROC) (GLenum target, const GLdouble *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4FPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4FVPROC) (GLenum target, const GLfloat *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4IPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4IVPROC) (GLenum target, const GLint *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4SPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4SVPROC) (GLenum target, const GLshort *v);
+typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXFPROC) (const GLfloat *m);
+typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXDPROC) (const GLdouble *m);
+typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXFPROC) (const GLfloat *m);
+typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXDPROC) (const GLdouble *m);
+typedef void (APIENTRYP PFNGLSAMPLECOVERAGEPROC) (GLclampf value, GLboolean invert);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE1DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data);
+typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXIMAGEPROC) (GLenum target, GLint level, void *img);
+
+
+/*
+ * GL_ARB_multitexture (ARB extension 1 and OpenGL 1.2.1)
+ */
+#ifndef GL_ARB_multitexture
+#define GL_ARB_multitexture 1
+
+#define GL_TEXTURE0_ARB 0x84C0
+#define GL_TEXTURE1_ARB 0x84C1
+#define GL_TEXTURE2_ARB 0x84C2
+#define GL_TEXTURE3_ARB 0x84C3
+#define GL_TEXTURE4_ARB 0x84C4
+#define GL_TEXTURE5_ARB 0x84C5
+#define GL_TEXTURE6_ARB 0x84C6
+#define GL_TEXTURE7_ARB 0x84C7
+#define GL_TEXTURE8_ARB 0x84C8
+#define GL_TEXTURE9_ARB 0x84C9
+#define GL_TEXTURE10_ARB 0x84CA
+#define GL_TEXTURE11_ARB 0x84CB
+#define GL_TEXTURE12_ARB 0x84CC
+#define GL_TEXTURE13_ARB 0x84CD
+#define GL_TEXTURE14_ARB 0x84CE
+#define GL_TEXTURE15_ARB 0x84CF
+#define GL_TEXTURE16_ARB 0x84D0
+#define GL_TEXTURE17_ARB 0x84D1
+#define GL_TEXTURE18_ARB 0x84D2
+#define GL_TEXTURE19_ARB 0x84D3
+#define GL_TEXTURE20_ARB 0x84D4
+#define GL_TEXTURE21_ARB 0x84D5
+#define GL_TEXTURE22_ARB 0x84D6
+#define GL_TEXTURE23_ARB 0x84D7
+#define GL_TEXTURE24_ARB 0x84D8
+#define GL_TEXTURE25_ARB 0x84D9
+#define GL_TEXTURE26_ARB 0x84DA
+#define GL_TEXTURE27_ARB 0x84DB
+#define GL_TEXTURE28_ARB 0x84DC
+#define GL_TEXTURE29_ARB 0x84DD
+#define GL_TEXTURE30_ARB 0x84DE
+#define GL_TEXTURE31_ARB 0x84DF
+#define GL_ACTIVE_TEXTURE_ARB 0x84E0
+#define GL_CLIENT_ACTIVE_TEXTURE_ARB 0x84E1
+#define GL_MAX_TEXTURE_UNITS_ARB 0x84E2
+
+GLAPI void GLAPIENTRY glActiveTextureARB(GLenum texture);
+GLAPI void GLAPIENTRY glClientActiveTextureARB(GLenum texture);
+GLAPI void GLAPIENTRY glMultiTexCoord1dARB(GLenum target, GLdouble s);
+GLAPI void GLAPIENTRY glMultiTexCoord1dvARB(GLenum target, const GLdouble *v);
+GLAPI void GLAPIENTRY glMultiTexCoord1fARB(GLenum target, GLfloat s);
+GLAPI void GLAPIENTRY glMultiTexCoord1fvARB(GLenum target, const GLfloat *v);
+GLAPI void GLAPIENTRY glMultiTexCoord1iARB(GLenum target, GLint s);
+GLAPI void GLAPIENTRY glMultiTexCoord1ivARB(GLenum target, const GLint *v);
+GLAPI void GLAPIENTRY glMultiTexCoord1sARB(GLenum target, GLshort s);
+GLAPI void GLAPIENTRY glMultiTexCoord1svARB(GLenum target, const GLshort *v);
+GLAPI void GLAPIENTRY glMultiTexCoord2dARB(GLenum target, GLdouble s, GLdouble t);
+GLAPI void GLAPIENTRY glMultiTexCoord2dvARB(GLenum target, const GLdouble *v);
+GLAPI void GLAPIENTRY glMultiTexCoord2fARB(GLenum target, GLfloat s, GLfloat t);
+GLAPI void GLAPIENTRY glMultiTexCoord2fvARB(GLenum target, const GLfloat *v);
+GLAPI void GLAPIENTRY glMultiTexCoord2iARB(GLenum target, GLint s, GLint t);
+GLAPI void GLAPIENTRY glMultiTexCoord2ivARB(GLenum target, const GLint *v);
+GLAPI void GLAPIENTRY glMultiTexCoord2sARB(GLenum target, GLshort s, GLshort t);
+GLAPI void GLAPIENTRY glMultiTexCoord2svARB(GLenum target, const GLshort *v);
+GLAPI void GLAPIENTRY glMultiTexCoord3dARB(GLenum target, GLdouble s, GLdouble t, GLdouble r);
+GLAPI void GLAPIENTRY glMultiTexCoord3dvARB(GLenum target, const GLdouble *v);
+GLAPI void GLAPIENTRY glMultiTexCoord3fARB(GLenum target, GLfloat s, GLfloat t, GLfloat r);
+GLAPI void GLAPIENTRY glMultiTexCoord3fvARB(GLenum target, const GLfloat *v);
+GLAPI void GLAPIENTRY glMultiTexCoord3iARB(GLenum target, GLint s, GLint t, GLint r);
+GLAPI void GLAPIENTRY glMultiTexCoord3ivARB(GLenum target, const GLint *v);
+GLAPI void GLAPIENTRY glMultiTexCoord3sARB(GLenum target, GLshort s, GLshort t, GLshort r);
+GLAPI void GLAPIENTRY glMultiTexCoord3svARB(GLenum target, const GLshort *v);
+GLAPI void GLAPIENTRY glMultiTexCoord4dARB(GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q);
+GLAPI void GLAPIENTRY glMultiTexCoord4dvARB(GLenum target, const GLdouble *v);
+GLAPI void GLAPIENTRY glMultiTexCoord4fARB(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q);
+GLAPI void GLAPIENTRY glMultiTexCoord4fvARB(GLenum target, const GLfloat *v);
+GLAPI void GLAPIENTRY glMultiTexCoord4iARB(GLenum target, GLint s, GLint t, GLint r, GLint q);
+GLAPI void GLAPIENTRY glMultiTexCoord4ivARB(GLenum target, const GLint *v);
+GLAPI void GLAPIENTRY glMultiTexCoord4sARB(GLenum target, GLshort s, GLshort t, GLshort r, GLshort q);
+GLAPI void GLAPIENTRY glMultiTexCoord4svARB(GLenum target, const GLshort *v);
+
+typedef void (APIENTRYP PFNGLACTIVETEXTUREARBPROC) (GLenum texture);
+typedef void (APIENTRYP PFNGLCLIENTACTIVETEXTUREARBPROC) (GLenum texture);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1DARBPROC) (GLenum target, GLdouble s);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1DVARBPROC) (GLenum target, const GLdouble *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1FARBPROC) (GLenum target, GLfloat s);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1FVARBPROC) (GLenum target, const GLfloat *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1IARBPROC) (GLenum target, GLint s);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1IVARBPROC) (GLenum target, const GLint *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1SARBPROC) (GLenum target, GLshort s);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1SVARBPROC) (GLenum target, const GLshort *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2DARBPROC) (GLenum target, GLdouble s, GLdouble t);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2DVARBPROC) (GLenum target, const GLdouble *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2FARBPROC) (GLenum target, GLfloat s, GLfloat t);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2FVARBPROC) (GLenum target, const GLfloat *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2IARBPROC) (GLenum target, GLint s, GLint t);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2IVARBPROC) (GLenum target, const GLint *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2SARBPROC) (GLenum target, GLshort s, GLshort t);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2SVARBPROC) (GLenum target, const GLshort *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3DVARBPROC) (GLenum target, const GLdouble *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3FVARBPROC) (GLenum target, const GLfloat *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3IARBPROC) (GLenum target, GLint s, GLint t, GLint r);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3IVARBPROC) (GLenum target, const GLint *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3SVARBPROC) (GLenum target, const GLshort *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4DVARBPROC) (GLenum target, const GLdouble *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4FVARBPROC) (GLenum target, const GLfloat *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4IARBPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4IVARBPROC) (GLenum target, const GLint *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4SVARBPROC) (GLenum target, const GLshort *v);
+
+#endif /* GL_ARB_multitexture */
+
+
+
+/*
+ * Define this token if you want "old-style" header file behaviour (extensions
+ * defined in gl.h). Otherwise, extensions will be included from glext.h.
+ */
+#if defined(GL_GLEXT_LEGACY)
+
+/* All extensions that used to be here are now found in glext.h */
+
+#else /* GL_GLEXT_LEGACY */
+
+#include "glext.h"
+
+#endif /* GL_GLEXT_LEGACY */
+
+
+
+/*
+ * ???. GL_MESA_trace
+ * XXX obsolete
+ */
+#ifndef GL_MESA_trace
+#define GL_MESA_trace 1
+
+#define GL_TRACE_ALL_BITS_MESA 0xFFFF
+#define GL_TRACE_OPERATIONS_BIT_MESA 0x0001
+#define GL_TRACE_PRIMITIVES_BIT_MESA 0x0002
+#define GL_TRACE_ARRAYS_BIT_MESA 0x0004
+#define GL_TRACE_TEXTURES_BIT_MESA 0x0008
+#define GL_TRACE_PIXELS_BIT_MESA 0x0010
+#define GL_TRACE_ERRORS_BIT_MESA 0x0020
+#define GL_TRACE_MASK_MESA 0x8755
+#define GL_TRACE_NAME_MESA 0x8756
+
+GLAPI void GLAPIENTRY glEnableTraceMESA( GLbitfield mask );
+GLAPI void GLAPIENTRY glDisableTraceMESA( GLbitfield mask );
+GLAPI void GLAPIENTRY glNewTraceMESA( GLbitfield mask, const GLubyte * traceName );
+GLAPI void GLAPIENTRY glEndTraceMESA( void );
+GLAPI void GLAPIENTRY glTraceAssertAttribMESA( GLbitfield attribMask );
+GLAPI void GLAPIENTRY glTraceCommentMESA( const GLubyte * comment );
+GLAPI void GLAPIENTRY glTraceTextureMESA( GLuint name, const GLubyte* comment );
+GLAPI void GLAPIENTRY glTraceListMESA( GLuint name, const GLubyte* comment );
+GLAPI void GLAPIENTRY glTracePointerMESA( GLvoid* pointer, const GLubyte* comment );
+GLAPI void GLAPIENTRY glTracePointerRangeMESA( const GLvoid* first, const GLvoid* last, const GLubyte* comment );
+
+#endif /* GL_MESA_trace */
+
+
+/*
+ * ???. GL_MESA_packed_depth_stencil
+ * XXX obsolete
+ */
+#ifndef GL_MESA_packed_depth_stencil
+#define GL_MESA_packed_depth_stencil 1
+
+#define GL_DEPTH_STENCIL_MESA 0x8750
+#define GL_UNSIGNED_INT_24_8_MESA 0x8751
+#define GL_UNSIGNED_INT_8_24_REV_MESA 0x8752
+#define GL_UNSIGNED_SHORT_15_1_MESA 0x8753
+#define GL_UNSIGNED_SHORT_1_15_REV_MESA 0x8754
+
+#endif /* GL_MESA_packed_depth_stencil */
+
+
+#ifndef GL_MESA_program_debug
+#define GL_MESA_program_debug 1
+
+#define GL_FRAGMENT_PROGRAM_POSITION_MESA 0x8bb0
+#define GL_FRAGMENT_PROGRAM_CALLBACK_MESA 0x8bb1
+#define GL_FRAGMENT_PROGRAM_CALLBACK_FUNC_MESA 0x8bb2
+#define GL_FRAGMENT_PROGRAM_CALLBACK_DATA_MESA 0x8bb3
+#define GL_VERTEX_PROGRAM_POSITION_MESA 0x8bb4
+#define GL_VERTEX_PROGRAM_CALLBACK_MESA 0x8bb5
+#define GL_VERTEX_PROGRAM_CALLBACK_FUNC_MESA 0x8bb6
+#define GL_VERTEX_PROGRAM_CALLBACK_DATA_MESA 0x8bb7
+
+typedef void (*GLprogramcallbackMESA)(GLenum target, GLvoid *data);
+
+GLAPI void GLAPIENTRY glProgramCallbackMESA(GLenum target, GLprogramcallbackMESA callback, GLvoid *data);
+
+GLAPI void GLAPIENTRY glGetProgramRegisterfvMESA(GLenum target, GLsizei len, const GLubyte *name, GLfloat *v);
+
+#endif /* GL_MESA_program_debug */
+
+
+#ifndef GL_ATI_blend_equation_separate
+#define GL_ATI_blend_equation_separate 1
+
+#define GL_ALPHA_BLEND_EQUATION_ATI 0x883D
+
+GLAPI void GLAPIENTRY glBlendEquationSeparateATI( GLenum modeRGB, GLenum modeA );
+typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEATIPROC) (GLenum modeRGB, GLenum modeA);
+
+#endif /* GL_ATI_blend_equation_separate */
+
+
+/**
+ ** NOTE!!!!! If you add new functions to this file, or update
+ ** glext.h be sure to regenerate the gl_mangle.h file. See comments
+ ** in that file for details.
+ **/
+
+
+
+/**********************************************************************
+ * Begin system-specific stuff
+ */
+#if defined(PRAGMA_EXPORT_SUPPORTED)
+#pragma export off
+#endif
+
+#if defined(macintosh) && PRAGMA_IMPORT_SUPPORTED
+#pragma import off
+#endif
+/*
+ * End system-specific stuff
+ **********************************************************************/
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __gl_h_ */
diff --git a/src/graphics/GL/glext.h b/src/graphics/GL/glext.h
new file mode 100644
index 0000000..90cac7c
--- /dev/null
+++ b/src/graphics/GL/glext.h
@@ -0,0 +1,11489 @@
+
+#ifndef __glext_h_
+#define __glext_h_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+** Copyright (c) 2007-2011 The Khronos Group Inc.
+**
+** Permission is hereby granted, free of charge, to any person obtaining a
+** copy of this software and/or associated documentation files (the
+** "Materials"), to deal in the Materials without restriction, including
+** without limitation the rights to use, copy, modify, merge, publish,
+** distribute, sublicense, and/or sell copies of the Materials, and to
+** permit persons to whom the Materials are furnished to do so, subject to
+** the following conditions:
+**
+** The above copyright notice and this permission notice shall be included
+** in all copies or substantial portions of the Materials.
+**
+** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+*/
+
+/* Header file version number, required by OpenGL ABI for Linux */
+/* glext.h last updated $Date$ */
+/* Current version at http://www.opengl.org/registry/ */
+#define GL_GLEXT_VERSION 72
+/* Function declaration macros - to move into glplatform.h */
+
+#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__)
+#define WIN32_LEAN_AND_MEAN 1
+#include <windows.h>
+#endif
+
+#ifndef APIENTRY
+#define APIENTRY
+#endif
+#ifndef APIENTRYP
+#define APIENTRYP APIENTRY *
+#endif
+#ifndef GLAPI
+#define GLAPI extern
+#endif
+
+/*************************************************************/
+
+#ifndef GL_VERSION_1_2
+#define GL_UNSIGNED_BYTE_3_3_2 0x8032
+#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033
+#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034
+#define GL_UNSIGNED_INT_8_8_8_8 0x8035
+#define GL_UNSIGNED_INT_10_10_10_2 0x8036
+#define GL_TEXTURE_BINDING_3D 0x806A
+#define GL_PACK_SKIP_IMAGES 0x806B
+#define GL_PACK_IMAGE_HEIGHT 0x806C
+#define GL_UNPACK_SKIP_IMAGES 0x806D
+#define GL_UNPACK_IMAGE_HEIGHT 0x806E
+#define GL_TEXTURE_3D 0x806F
+#define GL_PROXY_TEXTURE_3D 0x8070
+#define GL_TEXTURE_DEPTH 0x8071
+#define GL_TEXTURE_WRAP_R 0x8072
+#define GL_MAX_3D_TEXTURE_SIZE 0x8073
+#define GL_UNSIGNED_BYTE_2_3_3_REV 0x8362
+#define GL_UNSIGNED_SHORT_5_6_5 0x8363
+#define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364
+#define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365
+#define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366
+#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367
+#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368
+#define GL_BGR 0x80E0
+#define GL_BGRA 0x80E1
+#define GL_MAX_ELEMENTS_VERTICES 0x80E8
+#define GL_MAX_ELEMENTS_INDICES 0x80E9
+#define GL_CLAMP_TO_EDGE 0x812F
+#define GL_TEXTURE_MIN_LOD 0x813A
+#define GL_TEXTURE_MAX_LOD 0x813B
+#define GL_TEXTURE_BASE_LEVEL 0x813C
+#define GL_TEXTURE_MAX_LEVEL 0x813D
+#define GL_SMOOTH_POINT_SIZE_RANGE 0x0B12
+#define GL_SMOOTH_POINT_SIZE_GRANULARITY 0x0B13
+#define GL_SMOOTH_LINE_WIDTH_RANGE 0x0B22
+#define GL_SMOOTH_LINE_WIDTH_GRANULARITY 0x0B23
+#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E
+#endif
+
+#ifndef GL_VERSION_1_2_DEPRECATED
+#define GL_RESCALE_NORMAL 0x803A
+#define GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8
+#define GL_SINGLE_COLOR 0x81F9
+#define GL_SEPARATE_SPECULAR_COLOR 0x81FA
+#define GL_ALIASED_POINT_SIZE_RANGE 0x846D
+#endif
+
+#ifndef GL_ARB_imaging
+#define GL_CONSTANT_COLOR 0x8001
+#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002
+#define GL_CONSTANT_ALPHA 0x8003
+#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004
+#define GL_BLEND_COLOR 0x8005
+#define GL_FUNC_ADD 0x8006
+#define GL_MIN 0x8007
+#define GL_MAX 0x8008
+#define GL_BLEND_EQUATION 0x8009
+#define GL_FUNC_SUBTRACT 0x800A
+#define GL_FUNC_REVERSE_SUBTRACT 0x800B
+#endif
+
+#ifndef GL_ARB_imaging_DEPRECATED
+#define GL_CONVOLUTION_1D 0x8010
+#define GL_CONVOLUTION_2D 0x8011
+#define GL_SEPARABLE_2D 0x8012
+#define GL_CONVOLUTION_BORDER_MODE 0x8013
+#define GL_CONVOLUTION_FILTER_SCALE 0x8014
+#define GL_CONVOLUTION_FILTER_BIAS 0x8015
+#define GL_REDUCE 0x8016
+#define GL_CONVOLUTION_FORMAT 0x8017
+#define GL_CONVOLUTION_WIDTH 0x8018
+#define GL_CONVOLUTION_HEIGHT 0x8019
+#define GL_MAX_CONVOLUTION_WIDTH 0x801A
+#define GL_MAX_CONVOLUTION_HEIGHT 0x801B
+#define GL_POST_CONVOLUTION_RED_SCALE 0x801C
+#define GL_POST_CONVOLUTION_GREEN_SCALE 0x801D
+#define GL_POST_CONVOLUTION_BLUE_SCALE 0x801E
+#define GL_POST_CONVOLUTION_ALPHA_SCALE 0x801F
+#define GL_POST_CONVOLUTION_RED_BIAS 0x8020
+#define GL_POST_CONVOLUTION_GREEN_BIAS 0x8021
+#define GL_POST_CONVOLUTION_BLUE_BIAS 0x8022
+#define GL_POST_CONVOLUTION_ALPHA_BIAS 0x8023
+#define GL_HISTOGRAM 0x8024
+#define GL_PROXY_HISTOGRAM 0x8025
+#define GL_HISTOGRAM_WIDTH 0x8026
+#define GL_HISTOGRAM_FORMAT 0x8027
+#define GL_HISTOGRAM_RED_SIZE 0x8028
+#define GL_HISTOGRAM_GREEN_SIZE 0x8029
+#define GL_HISTOGRAM_BLUE_SIZE 0x802A
+#define GL_HISTOGRAM_ALPHA_SIZE 0x802B
+#define GL_HISTOGRAM_LUMINANCE_SIZE 0x802C
+#define GL_HISTOGRAM_SINK 0x802D
+#define GL_MINMAX 0x802E
+#define GL_MINMAX_FORMAT 0x802F
+#define GL_MINMAX_SINK 0x8030
+#define GL_TABLE_TOO_LARGE 0x8031
+#define GL_COLOR_MATRIX 0x80B1
+#define GL_COLOR_MATRIX_STACK_DEPTH 0x80B2
+#define GL_MAX_COLOR_MATRIX_STACK_DEPTH 0x80B3
+#define GL_POST_COLOR_MATRIX_RED_SCALE 0x80B4
+#define GL_POST_COLOR_MATRIX_GREEN_SCALE 0x80B5
+#define GL_POST_COLOR_MATRIX_BLUE_SCALE 0x80B6
+#define GL_POST_COLOR_MATRIX_ALPHA_SCALE 0x80B7
+#define GL_POST_COLOR_MATRIX_RED_BIAS 0x80B8
+#define GL_POST_COLOR_MATRIX_GREEN_BIAS 0x80B9
+#define GL_POST_COLOR_MATRIX_BLUE_BIAS 0x80BA
+#define GL_POST_COLOR_MATRIX_ALPHA_BIAS 0x80BB
+#define GL_COLOR_TABLE 0x80D0
+#define GL_POST_CONVOLUTION_COLOR_TABLE 0x80D1
+#define GL_POST_COLOR_MATRIX_COLOR_TABLE 0x80D2
+#define GL_PROXY_COLOR_TABLE 0x80D3
+#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE 0x80D4
+#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE 0x80D5
+#define GL_COLOR_TABLE_SCALE 0x80D6
+#define GL_COLOR_TABLE_BIAS 0x80D7
+#define GL_COLOR_TABLE_FORMAT 0x80D8
+#define GL_COLOR_TABLE_WIDTH 0x80D9
+#define GL_COLOR_TABLE_RED_SIZE 0x80DA
+#define GL_COLOR_TABLE_GREEN_SIZE 0x80DB
+#define GL_COLOR_TABLE_BLUE_SIZE 0x80DC
+#define GL_COLOR_TABLE_ALPHA_SIZE 0x80DD
+#define GL_COLOR_TABLE_LUMINANCE_SIZE 0x80DE
+#define GL_COLOR_TABLE_INTENSITY_SIZE 0x80DF
+#define GL_CONSTANT_BORDER 0x8151
+#define GL_REPLICATE_BORDER 0x8153
+#define GL_CONVOLUTION_BORDER_COLOR 0x8154
+#endif
+
+#ifndef GL_VERSION_1_3
+#define GL_TEXTURE0 0x84C0
+#define GL_TEXTURE1 0x84C1
+#define GL_TEXTURE2 0x84C2
+#define GL_TEXTURE3 0x84C3
+#define GL_TEXTURE4 0x84C4
+#define GL_TEXTURE5 0x84C5
+#define GL_TEXTURE6 0x84C6
+#define GL_TEXTURE7 0x84C7
+#define GL_TEXTURE8 0x84C8
+#define GL_TEXTURE9 0x84C9
+#define GL_TEXTURE10 0x84CA
+#define GL_TEXTURE11 0x84CB
+#define GL_TEXTURE12 0x84CC
+#define GL_TEXTURE13 0x84CD
+#define GL_TEXTURE14 0x84CE
+#define GL_TEXTURE15 0x84CF
+#define GL_TEXTURE16 0x84D0
+#define GL_TEXTURE17 0x84D1
+#define GL_TEXTURE18 0x84D2
+#define GL_TEXTURE19 0x84D3
+#define GL_TEXTURE20 0x84D4
+#define GL_TEXTURE21 0x84D5
+#define GL_TEXTURE22 0x84D6
+#define GL_TEXTURE23 0x84D7
+#define GL_TEXTURE24 0x84D8
+#define GL_TEXTURE25 0x84D9
+#define GL_TEXTURE26 0x84DA
+#define GL_TEXTURE27 0x84DB
+#define GL_TEXTURE28 0x84DC
+#define GL_TEXTURE29 0x84DD
+#define GL_TEXTURE30 0x84DE
+#define GL_TEXTURE31 0x84DF
+#define GL_ACTIVE_TEXTURE 0x84E0
+#define GL_MULTISAMPLE 0x809D
+#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E
+#define GL_SAMPLE_ALPHA_TO_ONE 0x809F
+#define GL_SAMPLE_COVERAGE 0x80A0
+#define GL_SAMPLE_BUFFERS 0x80A8
+#define GL_SAMPLES 0x80A9
+#define GL_SAMPLE_COVERAGE_VALUE 0x80AA
+#define GL_SAMPLE_COVERAGE_INVERT 0x80AB
+#define GL_TEXTURE_CUBE_MAP 0x8513
+#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A
+#define GL_PROXY_TEXTURE_CUBE_MAP 0x851B
+#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C
+#define GL_COMPRESSED_RGB 0x84ED
+#define GL_COMPRESSED_RGBA 0x84EE
+#define GL_TEXTURE_COMPRESSION_HINT 0x84EF
+#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE 0x86A0
+#define GL_TEXTURE_COMPRESSED 0x86A1
+#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2
+#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3
+#define GL_CLAMP_TO_BORDER 0x812D
+#endif
+
+#ifndef GL_VERSION_1_3_DEPRECATED
+#define GL_CLIENT_ACTIVE_TEXTURE 0x84E1
+#define GL_MAX_TEXTURE_UNITS 0x84E2
+#define GL_TRANSPOSE_MODELVIEW_MATRIX 0x84E3
+#define GL_TRANSPOSE_PROJECTION_MATRIX 0x84E4
+#define GL_TRANSPOSE_TEXTURE_MATRIX 0x84E5
+#define GL_TRANSPOSE_COLOR_MATRIX 0x84E6
+#define GL_MULTISAMPLE_BIT 0x20000000
+#define GL_NORMAL_MAP 0x8511
+#define GL_REFLECTION_MAP 0x8512
+#define GL_COMPRESSED_ALPHA 0x84E9
+#define GL_COMPRESSED_LUMINANCE 0x84EA
+#define GL_COMPRESSED_LUMINANCE_ALPHA 0x84EB
+#define GL_COMPRESSED_INTENSITY 0x84EC
+#define GL_COMBINE 0x8570
+#define GL_COMBINE_RGB 0x8571
+#define GL_COMBINE_ALPHA 0x8572
+#define GL_SOURCE0_RGB 0x8580
+#define GL_SOURCE1_RGB 0x8581
+#define GL_SOURCE2_RGB 0x8582
+#define GL_SOURCE0_ALPHA 0x8588
+#define GL_SOURCE1_ALPHA 0x8589
+#define GL_SOURCE2_ALPHA 0x858A
+#define GL_OPERAND0_RGB 0x8590
+#define GL_OPERAND1_RGB 0x8591
+#define GL_OPERAND2_RGB 0x8592
+#define GL_OPERAND0_ALPHA 0x8598
+#define GL_OPERAND1_ALPHA 0x8599
+#define GL_OPERAND2_ALPHA 0x859A
+#define GL_RGB_SCALE 0x8573
+#define GL_ADD_SIGNED 0x8574
+#define GL_INTERPOLATE 0x8575
+#define GL_SUBTRACT 0x84E7
+#define GL_CONSTANT 0x8576
+#define GL_PRIMARY_COLOR 0x8577
+#define GL_PREVIOUS 0x8578
+#define GL_DOT3_RGB 0x86AE
+#define GL_DOT3_RGBA 0x86AF
+#endif
+
+#ifndef GL_VERSION_1_4
+#define GL_BLEND_DST_RGB 0x80C8
+#define GL_BLEND_SRC_RGB 0x80C9
+#define GL_BLEND_DST_ALPHA 0x80CA
+#define GL_BLEND_SRC_ALPHA 0x80CB
+#define GL_POINT_FADE_THRESHOLD_SIZE 0x8128
+#define GL_DEPTH_COMPONENT16 0x81A5
+#define GL_DEPTH_COMPONENT24 0x81A6
+#define GL_DEPTH_COMPONENT32 0x81A7
+#define GL_MIRRORED_REPEAT 0x8370
+#define GL_MAX_TEXTURE_LOD_BIAS 0x84FD
+#define GL_TEXTURE_LOD_BIAS 0x8501
+#define GL_INCR_WRAP 0x8507
+#define GL_DECR_WRAP 0x8508
+#define GL_TEXTURE_DEPTH_SIZE 0x884A
+#define GL_TEXTURE_COMPARE_MODE 0x884C
+#define GL_TEXTURE_COMPARE_FUNC 0x884D
+#endif
+
+#ifndef GL_VERSION_1_4_DEPRECATED
+#define GL_POINT_SIZE_MIN 0x8126
+#define GL_POINT_SIZE_MAX 0x8127
+#define GL_POINT_DISTANCE_ATTENUATION 0x8129
+#define GL_GENERATE_MIPMAP 0x8191
+#define GL_GENERATE_MIPMAP_HINT 0x8192
+#define GL_FOG_COORDINATE_SOURCE 0x8450
+#define GL_FOG_COORDINATE 0x8451
+#define GL_FRAGMENT_DEPTH 0x8452
+#define GL_CURRENT_FOG_COORDINATE 0x8453
+#define GL_FOG_COORDINATE_ARRAY_TYPE 0x8454
+#define GL_FOG_COORDINATE_ARRAY_STRIDE 0x8455
+#define GL_FOG_COORDINATE_ARRAY_POINTER 0x8456
+#define GL_FOG_COORDINATE_ARRAY 0x8457
+#define GL_COLOR_SUM 0x8458
+#define GL_CURRENT_SECONDARY_COLOR 0x8459
+#define GL_SECONDARY_COLOR_ARRAY_SIZE 0x845A
+#define GL_SECONDARY_COLOR_ARRAY_TYPE 0x845B
+#define GL_SECONDARY_COLOR_ARRAY_STRIDE 0x845C
+#define GL_SECONDARY_COLOR_ARRAY_POINTER 0x845D
+#define GL_SECONDARY_COLOR_ARRAY 0x845E
+#define GL_TEXTURE_FILTER_CONTROL 0x8500
+#define GL_DEPTH_TEXTURE_MODE 0x884B
+#define GL_COMPARE_R_TO_TEXTURE 0x884E
+#endif
+
+#ifndef GL_VERSION_1_5
+#define GL_BUFFER_SIZE 0x8764
+#define GL_BUFFER_USAGE 0x8765
+#define GL_QUERY_COUNTER_BITS 0x8864
+#define GL_CURRENT_QUERY 0x8865
+#define GL_QUERY_RESULT 0x8866
+#define GL_QUERY_RESULT_AVAILABLE 0x8867
+#define GL_ARRAY_BUFFER 0x8892
+#define GL_ELEMENT_ARRAY_BUFFER 0x8893
+#define GL_ARRAY_BUFFER_BINDING 0x8894
+#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895
+#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F
+#define GL_READ_ONLY 0x88B8
+#define GL_WRITE_ONLY 0x88B9
+#define GL_READ_WRITE 0x88BA
+#define GL_BUFFER_ACCESS 0x88BB
+#define GL_BUFFER_MAPPED 0x88BC
+#define GL_BUFFER_MAP_POINTER 0x88BD
+#define GL_STREAM_DRAW 0x88E0
+#define GL_STREAM_READ 0x88E1
+#define GL_STREAM_COPY 0x88E2
+#define GL_STATIC_DRAW 0x88E4
+#define GL_STATIC_READ 0x88E5
+#define GL_STATIC_COPY 0x88E6
+#define GL_DYNAMIC_DRAW 0x88E8
+#define GL_DYNAMIC_READ 0x88E9
+#define GL_DYNAMIC_COPY 0x88EA
+#define GL_SAMPLES_PASSED 0x8914
+#endif
+
+#ifndef GL_VERSION_1_5_DEPRECATED
+#define GL_VERTEX_ARRAY_BUFFER_BINDING 0x8896
+#define GL_NORMAL_ARRAY_BUFFER_BINDING 0x8897
+#define GL_COLOR_ARRAY_BUFFER_BINDING 0x8898
+#define GL_INDEX_ARRAY_BUFFER_BINDING 0x8899
+#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING 0x889A
+#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING 0x889B
+#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING 0x889C
+#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING 0x889D
+#define GL_WEIGHT_ARRAY_BUFFER_BINDING 0x889E
+#define GL_FOG_COORD_SRC 0x8450
+#define GL_FOG_COORD 0x8451
+#define GL_CURRENT_FOG_COORD 0x8453
+#define GL_FOG_COORD_ARRAY_TYPE 0x8454
+#define GL_FOG_COORD_ARRAY_STRIDE 0x8455
+#define GL_FOG_COORD_ARRAY_POINTER 0x8456
+#define GL_FOG_COORD_ARRAY 0x8457
+#define GL_FOG_COORD_ARRAY_BUFFER_BINDING 0x889D
+#define GL_SRC0_RGB 0x8580
+#define GL_SRC1_RGB 0x8581
+#define GL_SRC2_RGB 0x8582
+#define GL_SRC0_ALPHA 0x8588
+#define GL_SRC1_ALPHA 0x8589
+#define GL_SRC2_ALPHA 0x858A
+#endif
+
+#ifndef GL_VERSION_2_0
+#define GL_BLEND_EQUATION_RGB 0x8009
+#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622
+#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623
+#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624
+#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625
+#define GL_CURRENT_VERTEX_ATTRIB 0x8626
+#define GL_VERTEX_PROGRAM_POINT_SIZE 0x8642
+#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645
+#define GL_STENCIL_BACK_FUNC 0x8800
+#define GL_STENCIL_BACK_FAIL 0x8801
+#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802
+#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803
+#define GL_MAX_DRAW_BUFFERS 0x8824
+#define GL_DRAW_BUFFER0 0x8825
+#define GL_DRAW_BUFFER1 0x8826
+#define GL_DRAW_BUFFER2 0x8827
+#define GL_DRAW_BUFFER3 0x8828
+#define GL_DRAW_BUFFER4 0x8829
+#define GL_DRAW_BUFFER5 0x882A
+#define GL_DRAW_BUFFER6 0x882B
+#define GL_DRAW_BUFFER7 0x882C
+#define GL_DRAW_BUFFER8 0x882D
+#define GL_DRAW_BUFFER9 0x882E
+#define GL_DRAW_BUFFER10 0x882F
+#define GL_DRAW_BUFFER11 0x8830
+#define GL_DRAW_BUFFER12 0x8831
+#define GL_DRAW_BUFFER13 0x8832
+#define GL_DRAW_BUFFER14 0x8833
+#define GL_DRAW_BUFFER15 0x8834
+#define GL_BLEND_EQUATION_ALPHA 0x883D
+#define GL_MAX_VERTEX_ATTRIBS 0x8869
+#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A
+#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872
+#define GL_FRAGMENT_SHADER 0x8B30
+#define GL_VERTEX_SHADER 0x8B31
+#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49
+#define GL_MAX_VERTEX_UNIFORM_COMPONENTS 0x8B4A
+#define GL_MAX_VARYING_FLOATS 0x8B4B
+#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C
+#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D
+#define GL_SHADER_TYPE 0x8B4F
+#define GL_FLOAT_VEC2 0x8B50
+#define GL_FLOAT_VEC3 0x8B51
+#define GL_FLOAT_VEC4 0x8B52
+#define GL_INT_VEC2 0x8B53
+#define GL_INT_VEC3 0x8B54
+#define GL_INT_VEC4 0x8B55
+#define GL_BOOL 0x8B56
+#define GL_BOOL_VEC2 0x8B57
+#define GL_BOOL_VEC3 0x8B58
+#define GL_BOOL_VEC4 0x8B59
+#define GL_FLOAT_MAT2 0x8B5A
+#define GL_FLOAT_MAT3 0x8B5B
+#define GL_FLOAT_MAT4 0x8B5C
+#define GL_SAMPLER_1D 0x8B5D
+#define GL_SAMPLER_2D 0x8B5E
+#define GL_SAMPLER_3D 0x8B5F
+#define GL_SAMPLER_CUBE 0x8B60
+#define GL_SAMPLER_1D_SHADOW 0x8B61
+#define GL_SAMPLER_2D_SHADOW 0x8B62
+#define GL_DELETE_STATUS 0x8B80
+#define GL_COMPILE_STATUS 0x8B81
+#define GL_LINK_STATUS 0x8B82
+#define GL_VALIDATE_STATUS 0x8B83
+#define GL_INFO_LOG_LENGTH 0x8B84
+#define GL_ATTACHED_SHADERS 0x8B85
+#define GL_ACTIVE_UNIFORMS 0x8B86
+#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87
+#define GL_SHADER_SOURCE_LENGTH 0x8B88
+#define GL_ACTIVE_ATTRIBUTES 0x8B89
+#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A
+#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B
+#define GL_SHADING_LANGUAGE_VERSION 0x8B8C
+#define GL_CURRENT_PROGRAM 0x8B8D
+#define GL_POINT_SPRITE_COORD_ORIGIN 0x8CA0
+#define GL_LOWER_LEFT 0x8CA1
+#define GL_UPPER_LEFT 0x8CA2
+#define GL_STENCIL_BACK_REF 0x8CA3
+#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4
+#define GL_STENCIL_BACK_WRITEMASK 0x8CA5
+#endif
+
+#ifndef GL_VERSION_2_0_DEPRECATED
+#define GL_VERTEX_PROGRAM_TWO_SIDE 0x8643
+#define GL_POINT_SPRITE 0x8861
+#define GL_COORD_REPLACE 0x8862
+#define GL_MAX_TEXTURE_COORDS 0x8871
+#endif
+
+#ifndef GL_VERSION_2_1
+#define GL_PIXEL_PACK_BUFFER 0x88EB
+#define GL_PIXEL_UNPACK_BUFFER 0x88EC
+#define GL_PIXEL_PACK_BUFFER_BINDING 0x88ED
+#define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF
+#define GL_FLOAT_MAT2x3 0x8B65
+#define GL_FLOAT_MAT2x4 0x8B66
+#define GL_FLOAT_MAT3x2 0x8B67
+#define GL_FLOAT_MAT3x4 0x8B68
+#define GL_FLOAT_MAT4x2 0x8B69
+#define GL_FLOAT_MAT4x3 0x8B6A
+#define GL_SRGB 0x8C40
+#define GL_SRGB8 0x8C41
+#define GL_SRGB_ALPHA 0x8C42
+#define GL_SRGB8_ALPHA8 0x8C43
+#define GL_COMPRESSED_SRGB 0x8C48
+#define GL_COMPRESSED_SRGB_ALPHA 0x8C49
+#endif
+
+#ifndef GL_VERSION_2_1_DEPRECATED
+#define GL_CURRENT_RASTER_SECONDARY_COLOR 0x845F
+#define GL_SLUMINANCE_ALPHA 0x8C44
+#define GL_SLUMINANCE8_ALPHA8 0x8C45
+#define GL_SLUMINANCE 0x8C46
+#define GL_SLUMINANCE8 0x8C47
+#define GL_COMPRESSED_SLUMINANCE 0x8C4A
+#define GL_COMPRESSED_SLUMINANCE_ALPHA 0x8C4B
+#endif
+
+#ifndef GL_VERSION_3_0
+#define GL_COMPARE_REF_TO_TEXTURE 0x884E
+#define GL_CLIP_DISTANCE0 0x3000
+#define GL_CLIP_DISTANCE1 0x3001
+#define GL_CLIP_DISTANCE2 0x3002
+#define GL_CLIP_DISTANCE3 0x3003
+#define GL_CLIP_DISTANCE4 0x3004
+#define GL_CLIP_DISTANCE5 0x3005
+#define GL_CLIP_DISTANCE6 0x3006
+#define GL_CLIP_DISTANCE7 0x3007
+#define GL_MAX_CLIP_DISTANCES 0x0D32
+#define GL_MAJOR_VERSION 0x821B
+#define GL_MINOR_VERSION 0x821C
+#define GL_NUM_EXTENSIONS 0x821D
+#define GL_CONTEXT_FLAGS 0x821E
+#define GL_DEPTH_BUFFER 0x8223
+#define GL_STENCIL_BUFFER 0x8224
+#define GL_COMPRESSED_RED 0x8225
+#define GL_COMPRESSED_RG 0x8226
+#define GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT 0x0001
+#define GL_RGBA32F 0x8814
+#define GL_RGB32F 0x8815
+#define GL_RGBA16F 0x881A
+#define GL_RGB16F 0x881B
+#define GL_VERTEX_ATTRIB_ARRAY_INTEGER 0x88FD
+#define GL_MAX_ARRAY_TEXTURE_LAYERS 0x88FF
+#define GL_MIN_PROGRAM_TEXEL_OFFSET 0x8904
+#define GL_MAX_PROGRAM_TEXEL_OFFSET 0x8905
+#define GL_CLAMP_READ_COLOR 0x891C
+#define GL_FIXED_ONLY 0x891D
+#define GL_MAX_VARYING_COMPONENTS 0x8B4B
+#define GL_TEXTURE_1D_ARRAY 0x8C18
+#define GL_PROXY_TEXTURE_1D_ARRAY 0x8C19
+#define GL_TEXTURE_2D_ARRAY 0x8C1A
+#define GL_PROXY_TEXTURE_2D_ARRAY 0x8C1B
+#define GL_TEXTURE_BINDING_1D_ARRAY 0x8C1C
+#define GL_TEXTURE_BINDING_2D_ARRAY 0x8C1D
+#define GL_R11F_G11F_B10F 0x8C3A
+#define GL_UNSIGNED_INT_10F_11F_11F_REV 0x8C3B
+#define GL_RGB9_E5 0x8C3D
+#define GL_UNSIGNED_INT_5_9_9_9_REV 0x8C3E
+#define GL_TEXTURE_SHARED_SIZE 0x8C3F
+#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH 0x8C76
+#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE 0x8C7F
+#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS 0x8C80
+#define GL_TRANSFORM_FEEDBACK_VARYINGS 0x8C83
+#define GL_TRANSFORM_FEEDBACK_BUFFER_START 0x8C84
+#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE 0x8C85
+#define GL_PRIMITIVES_GENERATED 0x8C87
+#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN 0x8C88
+#define GL_RASTERIZER_DISCARD 0x8C89
+#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS 0x8C8A
+#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS 0x8C8B
+#define GL_INTERLEAVED_ATTRIBS 0x8C8C
+#define GL_SEPARATE_ATTRIBS 0x8C8D
+#define GL_TRANSFORM_FEEDBACK_BUFFER 0x8C8E
+#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING 0x8C8F
+#define GL_RGBA32UI 0x8D70
+#define GL_RGB32UI 0x8D71
+#define GL_RGBA16UI 0x8D76
+#define GL_RGB16UI 0x8D77
+#define GL_RGBA8UI 0x8D7C
+#define GL_RGB8UI 0x8D7D
+#define GL_RGBA32I 0x8D82
+#define GL_RGB32I 0x8D83
+#define GL_RGBA16I 0x8D88
+#define GL_RGB16I 0x8D89
+#define GL_RGBA8I 0x8D8E
+#define GL_RGB8I 0x8D8F
+#define GL_RED_INTEGER 0x8D94
+#define GL_GREEN_INTEGER 0x8D95
+#define GL_BLUE_INTEGER 0x8D96
+#define GL_RGB_INTEGER 0x8D98
+#define GL_RGBA_INTEGER 0x8D99
+#define GL_BGR_INTEGER 0x8D9A
+#define GL_BGRA_INTEGER 0x8D9B
+#define GL_SAMPLER_1D_ARRAY 0x8DC0
+#define GL_SAMPLER_2D_ARRAY 0x8DC1
+#define GL_SAMPLER_1D_ARRAY_SHADOW 0x8DC3
+#define GL_SAMPLER_2D_ARRAY_SHADOW 0x8DC4
+#define GL_SAMPLER_CUBE_SHADOW 0x8DC5
+#define GL_UNSIGNED_INT_VEC2 0x8DC6
+#define GL_UNSIGNED_INT_VEC3 0x8DC7
+#define GL_UNSIGNED_INT_VEC4 0x8DC8
+#define GL_INT_SAMPLER_1D 0x8DC9
+#define GL_INT_SAMPLER_2D 0x8DCA
+#define GL_INT_SAMPLER_3D 0x8DCB
+#define GL_INT_SAMPLER_CUBE 0x8DCC
+#define GL_INT_SAMPLER_1D_ARRAY 0x8DCE
+#define GL_INT_SAMPLER_2D_ARRAY 0x8DCF
+#define GL_UNSIGNED_INT_SAMPLER_1D 0x8DD1
+#define GL_UNSIGNED_INT_SAMPLER_2D 0x8DD2
+#define GL_UNSIGNED_INT_SAMPLER_3D 0x8DD3
+#define GL_UNSIGNED_INT_SAMPLER_CUBE 0x8DD4
+#define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY 0x8DD6
+#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY 0x8DD7
+#define GL_QUERY_WAIT 0x8E13
+#define GL_QUERY_NO_WAIT 0x8E14
+#define GL_QUERY_BY_REGION_WAIT 0x8E15
+#define GL_QUERY_BY_REGION_NO_WAIT 0x8E16
+#define GL_BUFFER_ACCESS_FLAGS 0x911F
+#define GL_BUFFER_MAP_LENGTH 0x9120
+#define GL_BUFFER_MAP_OFFSET 0x9121
+/* Reuse tokens from ARB_depth_buffer_float */
+/* reuse GL_DEPTH_COMPONENT32F */
+/* reuse GL_DEPTH32F_STENCIL8 */
+/* reuse GL_FLOAT_32_UNSIGNED_INT_24_8_REV */
+/* Reuse tokens from ARB_framebuffer_object */
+/* reuse GL_INVALID_FRAMEBUFFER_OPERATION */
+/* reuse GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING */
+/* reuse GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE */
+/* reuse GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE */
+/* reuse GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE */
+/* reuse GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE */
+/* reuse GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE */
+/* reuse GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE */
+/* reuse GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE */
+/* reuse GL_FRAMEBUFFER_DEFAULT */
+/* reuse GL_FRAMEBUFFER_UNDEFINED */
+/* reuse GL_DEPTH_STENCIL_ATTACHMENT */
+/* reuse GL_INDEX */
+/* reuse GL_MAX_RENDERBUFFER_SIZE */
+/* reuse GL_DEPTH_STENCIL */
+/* reuse GL_UNSIGNED_INT_24_8 */
+/* reuse GL_DEPTH24_STENCIL8 */
+/* reuse GL_TEXTURE_STENCIL_SIZE */
+/* reuse GL_TEXTURE_RED_TYPE */
+/* reuse GL_TEXTURE_GREEN_TYPE */
+/* reuse GL_TEXTURE_BLUE_TYPE */
+/* reuse GL_TEXTURE_ALPHA_TYPE */
+/* reuse GL_TEXTURE_DEPTH_TYPE */
+/* reuse GL_UNSIGNED_NORMALIZED */
+/* reuse GL_FRAMEBUFFER_BINDING */
+/* reuse GL_DRAW_FRAMEBUFFER_BINDING */
+/* reuse GL_RENDERBUFFER_BINDING */
+/* reuse GL_READ_FRAMEBUFFER */
+/* reuse GL_DRAW_FRAMEBUFFER */
+/* reuse GL_READ_FRAMEBUFFER_BINDING */
+/* reuse GL_RENDERBUFFER_SAMPLES */
+/* reuse GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE */
+/* reuse GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME */
+/* reuse GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL */
+/* reuse GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE */
+/* reuse GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER */
+/* reuse GL_FRAMEBUFFER_COMPLETE */
+/* reuse GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT */
+/* reuse GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT */
+/* reuse GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER */
+/* reuse GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER */
+/* reuse GL_FRAMEBUFFER_UNSUPPORTED */
+/* reuse GL_MAX_COLOR_ATTACHMENTS */
+/* reuse GL_COLOR_ATTACHMENT0 */
+/* reuse GL_COLOR_ATTACHMENT1 */
+/* reuse GL_COLOR_ATTACHMENT2 */
+/* reuse GL_COLOR_ATTACHMENT3 */
+/* reuse GL_COLOR_ATTACHMENT4 */
+/* reuse GL_COLOR_ATTACHMENT5 */
+/* reuse GL_COLOR_ATTACHMENT6 */
+/* reuse GL_COLOR_ATTACHMENT7 */
+/* reuse GL_COLOR_ATTACHMENT8 */
+/* reuse GL_COLOR_ATTACHMENT9 */
+/* reuse GL_COLOR_ATTACHMENT10 */
+/* reuse GL_COLOR_ATTACHMENT11 */
+/* reuse GL_COLOR_ATTACHMENT12 */
+/* reuse GL_COLOR_ATTACHMENT13 */
+/* reuse GL_COLOR_ATTACHMENT14 */
+/* reuse GL_COLOR_ATTACHMENT15 */
+/* reuse GL_DEPTH_ATTACHMENT */
+/* reuse GL_STENCIL_ATTACHMENT */
+/* reuse GL_FRAMEBUFFER */
+/* reuse GL_RENDERBUFFER */
+/* reuse GL_RENDERBUFFER_WIDTH */
+/* reuse GL_RENDERBUFFER_HEIGHT */
+/* reuse GL_RENDERBUFFER_INTERNAL_FORMAT */
+/* reuse GL_STENCIL_INDEX1 */
+/* reuse GL_STENCIL_INDEX4 */
+/* reuse GL_STENCIL_INDEX8 */
+/* reuse GL_STENCIL_INDEX16 */
+/* reuse GL_RENDERBUFFER_RED_SIZE */
+/* reuse GL_RENDERBUFFER_GREEN_SIZE */
+/* reuse GL_RENDERBUFFER_BLUE_SIZE */
+/* reuse GL_RENDERBUFFER_ALPHA_SIZE */
+/* reuse GL_RENDERBUFFER_DEPTH_SIZE */
+/* reuse GL_RENDERBUFFER_STENCIL_SIZE */
+/* reuse GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE */
+/* reuse GL_MAX_SAMPLES */
+/* Reuse tokens from ARB_framebuffer_sRGB */
+/* reuse GL_FRAMEBUFFER_SRGB */
+/* Reuse tokens from ARB_half_float_vertex */
+/* reuse GL_HALF_FLOAT */
+/* Reuse tokens from ARB_map_buffer_range */
+/* reuse GL_MAP_READ_BIT */
+/* reuse GL_MAP_WRITE_BIT */
+/* reuse GL_MAP_INVALIDATE_RANGE_BIT */
+/* reuse GL_MAP_INVALIDATE_BUFFER_BIT */
+/* reuse GL_MAP_FLUSH_EXPLICIT_BIT */
+/* reuse GL_MAP_UNSYNCHRONIZED_BIT */
+/* Reuse tokens from ARB_texture_compression_rgtc */
+/* reuse GL_COMPRESSED_RED_RGTC1 */
+/* reuse GL_COMPRESSED_SIGNED_RED_RGTC1 */
+/* reuse GL_COMPRESSED_RG_RGTC2 */
+/* reuse GL_COMPRESSED_SIGNED_RG_RGTC2 */
+/* Reuse tokens from ARB_texture_rg */
+/* reuse GL_RG */
+/* reuse GL_RG_INTEGER */
+/* reuse GL_R8 */
+/* reuse GL_R16 */
+/* reuse GL_RG8 */
+/* reuse GL_RG16 */
+/* reuse GL_R16F */
+/* reuse GL_R32F */
+/* reuse GL_RG16F */
+/* reuse GL_RG32F */
+/* reuse GL_R8I */
+/* reuse GL_R8UI */
+/* reuse GL_R16I */
+/* reuse GL_R16UI */
+/* reuse GL_R32I */
+/* reuse GL_R32UI */
+/* reuse GL_RG8I */
+/* reuse GL_RG8UI */
+/* reuse GL_RG16I */
+/* reuse GL_RG16UI */
+/* reuse GL_RG32I */
+/* reuse GL_RG32UI */
+/* Reuse tokens from ARB_vertex_array_object */
+/* reuse GL_VERTEX_ARRAY_BINDING */
+#endif
+
+#ifndef GL_VERSION_3_0_DEPRECATED
+#define GL_CLAMP_VERTEX_COLOR 0x891A
+#define GL_CLAMP_FRAGMENT_COLOR 0x891B
+#define GL_ALPHA_INTEGER 0x8D97
+/* Reuse tokens from ARB_framebuffer_object */
+/* reuse GL_TEXTURE_LUMINANCE_TYPE */
+/* reuse GL_TEXTURE_INTENSITY_TYPE */
+#endif
+
+#ifndef GL_VERSION_3_1
+#define GL_SAMPLER_2D_RECT 0x8B63
+#define GL_SAMPLER_2D_RECT_SHADOW 0x8B64
+#define GL_SAMPLER_BUFFER 0x8DC2
+#define GL_INT_SAMPLER_2D_RECT 0x8DCD
+#define GL_INT_SAMPLER_BUFFER 0x8DD0
+#define GL_UNSIGNED_INT_SAMPLER_2D_RECT 0x8DD5
+#define GL_UNSIGNED_INT_SAMPLER_BUFFER 0x8DD8
+#define GL_TEXTURE_BUFFER 0x8C2A
+#define GL_MAX_TEXTURE_BUFFER_SIZE 0x8C2B
+#define GL_TEXTURE_BINDING_BUFFER 0x8C2C
+#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING 0x8C2D
+#define GL_TEXTURE_BUFFER_FORMAT 0x8C2E
+#define GL_TEXTURE_RECTANGLE 0x84F5
+#define GL_TEXTURE_BINDING_RECTANGLE 0x84F6
+#define GL_PROXY_TEXTURE_RECTANGLE 0x84F7
+#define GL_MAX_RECTANGLE_TEXTURE_SIZE 0x84F8
+#define GL_RED_SNORM 0x8F90
+#define GL_RG_SNORM 0x8F91
+#define GL_RGB_SNORM 0x8F92
+#define GL_RGBA_SNORM 0x8F93
+#define GL_R8_SNORM 0x8F94
+#define GL_RG8_SNORM 0x8F95
+#define GL_RGB8_SNORM 0x8F96
+#define GL_RGBA8_SNORM 0x8F97
+#define GL_R16_SNORM 0x8F98
+#define GL_RG16_SNORM 0x8F99
+#define GL_RGB16_SNORM 0x8F9A
+#define GL_RGBA16_SNORM 0x8F9B
+#define GL_SIGNED_NORMALIZED 0x8F9C
+#define GL_PRIMITIVE_RESTART 0x8F9D
+#define GL_PRIMITIVE_RESTART_INDEX 0x8F9E
+/* Reuse tokens from ARB_copy_buffer */
+/* reuse GL_COPY_READ_BUFFER */
+/* reuse GL_COPY_WRITE_BUFFER */
+/* Reuse tokens from ARB_draw_instanced (none) */
+/* Reuse tokens from ARB_uniform_buffer_object */
+/* reuse GL_UNIFORM_BUFFER */
+/* reuse GL_UNIFORM_BUFFER_BINDING */
+/* reuse GL_UNIFORM_BUFFER_START */
+/* reuse GL_UNIFORM_BUFFER_SIZE */
+/* reuse GL_MAX_VERTEX_UNIFORM_BLOCKS */
+/* reuse GL_MAX_FRAGMENT_UNIFORM_BLOCKS */
+/* reuse GL_MAX_COMBINED_UNIFORM_BLOCKS */
+/* reuse GL_MAX_UNIFORM_BUFFER_BINDINGS */
+/* reuse GL_MAX_UNIFORM_BLOCK_SIZE */
+/* reuse GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS */
+/* reuse GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS */
+/* reuse GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT */
+/* reuse GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH */
+/* reuse GL_ACTIVE_UNIFORM_BLOCKS */
+/* reuse GL_UNIFORM_TYPE */
+/* reuse GL_UNIFORM_SIZE */
+/* reuse GL_UNIFORM_NAME_LENGTH */
+/* reuse GL_UNIFORM_BLOCK_INDEX */
+/* reuse GL_UNIFORM_OFFSET */
+/* reuse GL_UNIFORM_ARRAY_STRIDE */
+/* reuse GL_UNIFORM_MATRIX_STRIDE */
+/* reuse GL_UNIFORM_IS_ROW_MAJOR */
+/* reuse GL_UNIFORM_BLOCK_BINDING */
+/* reuse GL_UNIFORM_BLOCK_DATA_SIZE */
+/* reuse GL_UNIFORM_BLOCK_NAME_LENGTH */
+/* reuse GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS */
+/* reuse GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES */
+/* reuse GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER */
+/* reuse GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER */
+/* reuse GL_INVALID_INDEX */
+#endif
+
+#ifndef GL_VERSION_3_2
+#define GL_CONTEXT_CORE_PROFILE_BIT 0x00000001
+#define GL_CONTEXT_COMPATIBILITY_PROFILE_BIT 0x00000002
+#define GL_LINES_ADJACENCY 0x000A
+#define GL_LINE_STRIP_ADJACENCY 0x000B
+#define GL_TRIANGLES_ADJACENCY 0x000C
+#define GL_TRIANGLE_STRIP_ADJACENCY 0x000D
+#define GL_PROGRAM_POINT_SIZE 0x8642
+#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS 0x8C29
+#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED 0x8DA7
+#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS 0x8DA8
+#define GL_GEOMETRY_SHADER 0x8DD9
+#define GL_GEOMETRY_VERTICES_OUT 0x8916
+#define GL_GEOMETRY_INPUT_TYPE 0x8917
+#define GL_GEOMETRY_OUTPUT_TYPE 0x8918
+#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS 0x8DDF
+#define GL_MAX_GEOMETRY_OUTPUT_VERTICES 0x8DE0
+#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS 0x8DE1
+#define GL_MAX_VERTEX_OUTPUT_COMPONENTS 0x9122
+#define GL_MAX_GEOMETRY_INPUT_COMPONENTS 0x9123
+#define GL_MAX_GEOMETRY_OUTPUT_COMPONENTS 0x9124
+#define GL_MAX_FRAGMENT_INPUT_COMPONENTS 0x9125
+#define GL_CONTEXT_PROFILE_MASK 0x9126
+/* reuse GL_MAX_VARYING_COMPONENTS */
+/* reuse GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER */
+/* Reuse tokens from ARB_depth_clamp */
+/* reuse GL_DEPTH_CLAMP */
+/* Reuse tokens from ARB_draw_elements_base_vertex (none) */
+/* Reuse tokens from ARB_fragment_coord_conventions (none) */
+/* Reuse tokens from ARB_provoking_vertex */
+/* reuse GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION */
+/* reuse GL_FIRST_VERTEX_CONVENTION */
+/* reuse GL_LAST_VERTEX_CONVENTION */
+/* reuse GL_PROVOKING_VERTEX */
+/* Reuse tokens from ARB_seamless_cube_map */
+/* reuse GL_TEXTURE_CUBE_MAP_SEAMLESS */
+/* Reuse tokens from ARB_sync */
+/* reuse GL_MAX_SERVER_WAIT_TIMEOUT */
+/* reuse GL_OBJECT_TYPE */
+/* reuse GL_SYNC_CONDITION */
+/* reuse GL_SYNC_STATUS */
+/* reuse GL_SYNC_FLAGS */
+/* reuse GL_SYNC_FENCE */
+/* reuse GL_SYNC_GPU_COMMANDS_COMPLETE */
+/* reuse GL_UNSIGNALED */
+/* reuse GL_SIGNALED */
+/* reuse GL_ALREADY_SIGNALED */
+/* reuse GL_TIMEOUT_EXPIRED */
+/* reuse GL_CONDITION_SATISFIED */
+/* reuse GL_WAIT_FAILED */
+/* reuse GL_TIMEOUT_IGNORED */
+/* reuse GL_SYNC_FLUSH_COMMANDS_BIT */
+/* reuse GL_TIMEOUT_IGNORED */
+/* Reuse tokens from ARB_texture_multisample */
+/* reuse GL_SAMPLE_POSITION */
+/* reuse GL_SAMPLE_MASK */
+/* reuse GL_SAMPLE_MASK_VALUE */
+/* reuse GL_MAX_SAMPLE_MASK_WORDS */
+/* reuse GL_TEXTURE_2D_MULTISAMPLE */
+/* reuse GL_PROXY_TEXTURE_2D_MULTISAMPLE */
+/* reuse GL_TEXTURE_2D_MULTISAMPLE_ARRAY */
+/* reuse GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY */
+/* reuse GL_TEXTURE_BINDING_2D_MULTISAMPLE */
+/* reuse GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY */
+/* reuse GL_TEXTURE_SAMPLES */
+/* reuse GL_TEXTURE_FIXED_SAMPLE_LOCATIONS */
+/* reuse GL_SAMPLER_2D_MULTISAMPLE */
+/* reuse GL_INT_SAMPLER_2D_MULTISAMPLE */
+/* reuse GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE */
+/* reuse GL_SAMPLER_2D_MULTISAMPLE_ARRAY */
+/* reuse GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY */
+/* reuse GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY */
+/* reuse GL_MAX_COLOR_TEXTURE_SAMPLES */
+/* reuse GL_MAX_DEPTH_TEXTURE_SAMPLES */
+/* reuse GL_MAX_INTEGER_SAMPLES */
+/* Don't need to reuse tokens from ARB_vertex_array_bgra since they're already in 1.2 core */
+#endif
+
+#ifndef GL_VERSION_3_3
+#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR 0x88FE
+/* Reuse tokens from ARB_blend_func_extended */
+/* reuse GL_SRC1_COLOR */
+/* reuse GL_ONE_MINUS_SRC1_COLOR */
+/* reuse GL_ONE_MINUS_SRC1_ALPHA */
+/* reuse GL_MAX_DUAL_SOURCE_DRAW_BUFFERS */
+/* Reuse tokens from ARB_explicit_attrib_location (none) */
+/* Reuse tokens from ARB_occlusion_query2 */
+/* reuse GL_ANY_SAMPLES_PASSED */
+/* Reuse tokens from ARB_sampler_objects */
+/* reuse GL_SAMPLER_BINDING */
+/* Reuse tokens from ARB_shader_bit_encoding (none) */
+/* Reuse tokens from ARB_texture_rgb10_a2ui */
+/* reuse GL_RGB10_A2UI */
+/* Reuse tokens from ARB_texture_swizzle */
+/* reuse GL_TEXTURE_SWIZZLE_R */
+/* reuse GL_TEXTURE_SWIZZLE_G */
+/* reuse GL_TEXTURE_SWIZZLE_B */
+/* reuse GL_TEXTURE_SWIZZLE_A */
+/* reuse GL_TEXTURE_SWIZZLE_RGBA */
+/* Reuse tokens from ARB_timer_query */
+/* reuse GL_TIME_ELAPSED */
+/* reuse GL_TIMESTAMP */
+/* Reuse tokens from ARB_vertex_type_2_10_10_10_rev */
+/* reuse GL_INT_2_10_10_10_REV */
+#endif
+
+#ifndef GL_VERSION_4_0
+#define GL_SAMPLE_SHADING 0x8C36
+#define GL_MIN_SAMPLE_SHADING_VALUE 0x8C37
+#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5E
+#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5F
+#define GL_TEXTURE_CUBE_MAP_ARRAY 0x9009
+#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY 0x900A
+#define GL_PROXY_TEXTURE_CUBE_MAP_ARRAY 0x900B
+#define GL_SAMPLER_CUBE_MAP_ARRAY 0x900C
+#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW 0x900D
+#define GL_INT_SAMPLER_CUBE_MAP_ARRAY 0x900E
+#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY 0x900F
+/* Reuse tokens from ARB_texture_query_lod (none) */
+/* Reuse tokens from ARB_draw_buffers_blend (none) */
+/* Reuse tokens from ARB_draw_indirect */
+/* reuse GL_DRAW_INDIRECT_BUFFER */
+/* reuse GL_DRAW_INDIRECT_BUFFER_BINDING */
+/* Reuse tokens from ARB_gpu_shader5 */
+/* reuse GL_GEOMETRY_SHADER_INVOCATIONS */
+/* reuse GL_MAX_GEOMETRY_SHADER_INVOCATIONS */
+/* reuse GL_MIN_FRAGMENT_INTERPOLATION_OFFSET */
+/* reuse GL_MAX_FRAGMENT_INTERPOLATION_OFFSET */
+/* reuse GL_FRAGMENT_INTERPOLATION_OFFSET_BITS */
+/* reuse GL_MAX_VERTEX_STREAMS */
+/* Reuse tokens from ARB_gpu_shader_fp64 */
+/* reuse GL_DOUBLE_VEC2 */
+/* reuse GL_DOUBLE_VEC3 */
+/* reuse GL_DOUBLE_VEC4 */
+/* reuse GL_DOUBLE_MAT2 */
+/* reuse GL_DOUBLE_MAT3 */
+/* reuse GL_DOUBLE_MAT4 */
+/* reuse GL_DOUBLE_MAT2x3 */
+/* reuse GL_DOUBLE_MAT2x4 */
+/* reuse GL_DOUBLE_MAT3x2 */
+/* reuse GL_DOUBLE_MAT3x4 */
+/* reuse GL_DOUBLE_MAT4x2 */
+/* reuse GL_DOUBLE_MAT4x3 */
+/* Reuse tokens from ARB_shader_subroutine */
+/* reuse GL_ACTIVE_SUBROUTINES */
+/* reuse GL_ACTIVE_SUBROUTINE_UNIFORMS */
+/* reuse GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS */
+/* reuse GL_ACTIVE_SUBROUTINE_MAX_LENGTH */
+/* reuse GL_ACTIVE_SUBROUTINE_UNIFORM_MAX_LENGTH */
+/* reuse GL_MAX_SUBROUTINES */
+/* reuse GL_MAX_SUBROUTINE_UNIFORM_LOCATIONS */
+/* reuse GL_NUM_COMPATIBLE_SUBROUTINES */
+/* reuse GL_COMPATIBLE_SUBROUTINES */
+/* Reuse tokens from ARB_tessellation_shader */
+/* reuse GL_PATCHES */
+/* reuse GL_PATCH_VERTICES */
+/* reuse GL_PATCH_DEFAULT_INNER_LEVEL */
+/* reuse GL_PATCH_DEFAULT_OUTER_LEVEL */
+/* reuse GL_TESS_CONTROL_OUTPUT_VERTICES */
+/* reuse GL_TESS_GEN_MODE */
+/* reuse GL_TESS_GEN_SPACING */
+/* reuse GL_TESS_GEN_VERTEX_ORDER */
+/* reuse GL_TESS_GEN_POINT_MODE */
+/* reuse GL_ISOLINES */
+/* reuse GL_FRACTIONAL_ODD */
+/* reuse GL_FRACTIONAL_EVEN */
+/* reuse GL_MAX_PATCH_VERTICES */
+/* reuse GL_MAX_TESS_GEN_LEVEL */
+/* reuse GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS */
+/* reuse GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS */
+/* reuse GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS */
+/* reuse GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS */
+/* reuse GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS */
+/* reuse GL_MAX_TESS_PATCH_COMPONENTS */
+/* reuse GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS */
+/* reuse GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS */
+/* reuse GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS */
+/* reuse GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS */
+/* reuse GL_MAX_TESS_CONTROL_INPUT_COMPONENTS */
+/* reuse GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS */
+/* reuse GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS */
+/* reuse GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS */
+/* reuse GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_CONTROL_SHADER */
+/* reuse GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_EVALUATION_SHADER */
+/* reuse GL_TESS_EVALUATION_SHADER */
+/* reuse GL_TESS_CONTROL_SHADER */
+/* Reuse tokens from ARB_texture_buffer_object_rgb32 (none) */
+/* Reuse tokens from ARB_transform_feedback2 */
+/* reuse GL_TRANSFORM_FEEDBACK */
+/* reuse GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED */
+/* reuse GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE */
+/* reuse GL_TRANSFORM_FEEDBACK_BINDING */
+/* Reuse tokens from ARB_transform_feedback3 */
+/* reuse GL_MAX_TRANSFORM_FEEDBACK_BUFFERS */
+/* reuse GL_MAX_VERTEX_STREAMS */
+#endif
+
+#ifndef GL_VERSION_4_1
+/* Reuse tokens from ARB_ES2_compatibility */
+/* reuse GL_FIXED */
+/* reuse GL_IMPLEMENTATION_COLOR_READ_TYPE */
+/* reuse GL_IMPLEMENTATION_COLOR_READ_FORMAT */
+/* reuse GL_LOW_FLOAT */
+/* reuse GL_MEDIUM_FLOAT */
+/* reuse GL_HIGH_FLOAT */
+/* reuse GL_LOW_INT */
+/* reuse GL_MEDIUM_INT */
+/* reuse GL_HIGH_INT */
+/* reuse GL_SHADER_COMPILER */
+/* reuse GL_NUM_SHADER_BINARY_FORMATS */
+/* reuse GL_MAX_VERTEX_UNIFORM_VECTORS */
+/* reuse GL_MAX_VARYING_VECTORS */
+/* reuse GL_MAX_FRAGMENT_UNIFORM_VECTORS */
+/* Reuse tokens from ARB_get_program_binary */
+/* reuse GL_PROGRAM_BINARY_RETRIEVABLE_HINT */
+/* reuse GL_PROGRAM_BINARY_LENGTH */
+/* reuse GL_NUM_PROGRAM_BINARY_FORMATS */
+/* reuse GL_PROGRAM_BINARY_FORMATS */
+/* Reuse tokens from ARB_separate_shader_objects */
+/* reuse GL_VERTEX_SHADER_BIT */
+/* reuse GL_FRAGMENT_SHADER_BIT */
+/* reuse GL_GEOMETRY_SHADER_BIT */
+/* reuse GL_TESS_CONTROL_SHADER_BIT */
+/* reuse GL_TESS_EVALUATION_SHADER_BIT */
+/* reuse GL_ALL_SHADER_BITS */
+/* reuse GL_PROGRAM_SEPARABLE */
+/* reuse GL_ACTIVE_PROGRAM */
+/* reuse GL_PROGRAM_PIPELINE_BINDING */
+/* Reuse tokens from ARB_shader_precision (none) */
+/* Reuse tokens from ARB_vertex_attrib_64bit - all are in GL 3.0 and 4.0 already */
+/* Reuse tokens from ARB_viewport_array - some are in GL 1.1 and ARB_provoking_vertex already */
+/* reuse GL_MAX_VIEWPORTS */
+/* reuse GL_VIEWPORT_SUBPIXEL_BITS */
+/* reuse GL_VIEWPORT_BOUNDS_RANGE */
+/* reuse GL_LAYER_PROVOKING_VERTEX */
+/* reuse GL_VIEWPORT_INDEX_PROVOKING_VERTEX */
+/* reuse GL_UNDEFINED_VERTEX */
+#endif
+
+#ifndef GL_VERSION_4_2
+/* Reuse tokens from ARB_base_instance (none) */
+/* Reuse tokens from ARB_shading_language_420pack (none) */
+/* Reuse tokens from ARB_transform_feedback_instanced (none) */
+/* Reuse tokens from ARB_compressed_texture_pixel_storage */
+/* reuse GL_UNPACK_COMPRESSED_BLOCK_WIDTH */
+/* reuse GL_UNPACK_COMPRESSED_BLOCK_HEIGHT */
+/* reuse GL_UNPACK_COMPRESSED_BLOCK_DEPTH */
+/* reuse GL_UNPACK_COMPRESSED_BLOCK_SIZE */
+/* reuse GL_PACK_COMPRESSED_BLOCK_WIDTH */
+/* reuse GL_PACK_COMPRESSED_BLOCK_HEIGHT */
+/* reuse GL_PACK_COMPRESSED_BLOCK_DEPTH */
+/* reuse GL_PACK_COMPRESSED_BLOCK_SIZE */
+/* Reuse tokens from ARB_conservative_depth (none) */
+/* Reuse tokens from ARB_internalformat_query */
+/* reuse GL_NUM_SAMPLE_COUNTS */
+/* Reuse tokens from ARB_map_buffer_alignment */
+/* reuse GL_MIN_MAP_BUFFER_ALIGNMENT */
+/* Reuse tokens from ARB_shader_atomic_counters */
+/* reuse GL_ATOMIC_COUNTER_BUFFER */
+/* reuse GL_ATOMIC_COUNTER_BUFFER_BINDING */
+/* reuse GL_ATOMIC_COUNTER_BUFFER_START */
+/* reuse GL_ATOMIC_COUNTER_BUFFER_SIZE */
+/* reuse GL_ATOMIC_COUNTER_BUFFER_DATA_SIZE */
+/* reuse GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTERS */
+/* reuse GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTER_INDICES */
+/* reuse GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_VERTEX_SHADER */
+/* reuse GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_CONTROL_SHADER */
+/* reuse GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_EVALUATION_SHADER */
+/* reuse GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_GEOMETRY_SHADER */
+/* reuse GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_FRAGMENT_SHADER */
+/* reuse GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS */
+/* reuse GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS */
+/* reuse GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS */
+/* reuse GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS */
+/* reuse GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS */
+/* reuse GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS */
+/* reuse GL_MAX_VERTEX_ATOMIC_COUNTERS */
+/* reuse GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS */
+/* reuse GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS */
+/* reuse GL_MAX_GEOMETRY_ATOMIC_COUNTERS */
+/* reuse GL_MAX_FRAGMENT_ATOMIC_COUNTERS */
+/* reuse GL_MAX_COMBINED_ATOMIC_COUNTERS */
+/* reuse GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE */
+/* reuse GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS */
+/* reuse GL_ACTIVE_ATOMIC_COUNTER_BUFFERS */
+/* reuse GL_UNIFORM_ATOMIC_COUNTER_BUFFER_INDEX */
+/* reuse GL_UNSIGNED_INT_ATOMIC_COUNTER */
+/* Reuse tokens from ARB_shader_image_load_store */
+/* reuse GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT */
+/* reuse GL_ELEMENT_ARRAY_BARRIER_BIT */
+/* reuse GL_UNIFORM_BARRIER_BIT */
+/* reuse GL_TEXTURE_FETCH_BARRIER_BIT */
+/* reuse GL_SHADER_IMAGE_ACCESS_BARRIER_BIT */
+/* reuse GL_COMMAND_BARRIER_BIT */
+/* reuse GL_PIXEL_BUFFER_BARRIER_BIT */
+/* reuse GL_TEXTURE_UPDATE_BARRIER_BIT */
+/* reuse GL_BUFFER_UPDATE_BARRIER_BIT */
+/* reuse GL_FRAMEBUFFER_BARRIER_BIT */
+/* reuse GL_TRANSFORM_FEEDBACK_BARRIER_BIT */
+/* reuse GL_ATOMIC_COUNTER_BARRIER_BIT */
+/* reuse GL_ALL_BARRIER_BITS */
+/* reuse GL_MAX_IMAGE_UNITS */
+/* reuse GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS */
+/* reuse GL_IMAGE_BINDING_NAME */
+/* reuse GL_IMAGE_BINDING_LEVEL */
+/* reuse GL_IMAGE_BINDING_LAYERED */
+/* reuse GL_IMAGE_BINDING_LAYER */
+/* reuse GL_IMAGE_BINDING_ACCESS */
+/* reuse GL_IMAGE_1D */
+/* reuse GL_IMAGE_2D */
+/* reuse GL_IMAGE_3D */
+/* reuse GL_IMAGE_2D_RECT */
+/* reuse GL_IMAGE_CUBE */
+/* reuse GL_IMAGE_BUFFER */
+/* reuse GL_IMAGE_1D_ARRAY */
+/* reuse GL_IMAGE_2D_ARRAY */
+/* reuse GL_IMAGE_CUBE_MAP_ARRAY */
+/* reuse GL_IMAGE_2D_MULTISAMPLE */
+/* reuse GL_IMAGE_2D_MULTISAMPLE_ARRAY */
+/* reuse GL_INT_IMAGE_1D */
+/* reuse GL_INT_IMAGE_2D */
+/* reuse GL_INT_IMAGE_3D */
+/* reuse GL_INT_IMAGE_2D_RECT */
+/* reuse GL_INT_IMAGE_CUBE */
+/* reuse GL_INT_IMAGE_BUFFER */
+/* reuse GL_INT_IMAGE_1D_ARRAY */
+/* reuse GL_INT_IMAGE_2D_ARRAY */
+/* reuse GL_INT_IMAGE_CUBE_MAP_ARRAY */
+/* reuse GL_INT_IMAGE_2D_MULTISAMPLE */
+/* reuse GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY */
+/* reuse GL_UNSIGNED_INT_IMAGE_1D */
+/* reuse GL_UNSIGNED_INT_IMAGE_2D */
+/* reuse GL_UNSIGNED_INT_IMAGE_3D */
+/* reuse GL_UNSIGNED_INT_IMAGE_2D_RECT */
+/* reuse GL_UNSIGNED_INT_IMAGE_CUBE */
+/* reuse GL_UNSIGNED_INT_IMAGE_BUFFER */
+/* reuse GL_UNSIGNED_INT_IMAGE_1D_ARRAY */
+/* reuse GL_UNSIGNED_INT_IMAGE_2D_ARRAY */
+/* reuse GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY */
+/* reuse GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE */
+/* reuse GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY */
+/* reuse GL_MAX_IMAGE_SAMPLES */
+/* reuse GL_IMAGE_BINDING_FORMAT */
+/* reuse GL_IMAGE_FORMAT_COMPATIBILITY_TYPE */
+/* reuse GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE */
+/* reuse GL_IMAGE_FORMAT_COMPATIBILITY_BY_CLASS */
+/* reuse GL_MAX_VERTEX_IMAGE_UNIFORMS */
+/* reuse GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS */
+/* reuse GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS */
+/* reuse GL_MAX_GEOMETRY_IMAGE_UNIFORMS */
+/* reuse GL_MAX_FRAGMENT_IMAGE_UNIFORMS */
+/* reuse GL_MAX_COMBINED_IMAGE_UNIFORMS */
+/* Reuse tokens from ARB_shading_language_packing (none) */
+/* Reuse tokens from ARB_texture_storage */
+/* reuse GL_TEXTURE_IMMUTABLE_FORMAT */
+#endif
+
+#ifndef GL_ARB_multitexture
+#define GL_TEXTURE0_ARB 0x84C0
+#define GL_TEXTURE1_ARB 0x84C1
+#define GL_TEXTURE2_ARB 0x84C2
+#define GL_TEXTURE3_ARB 0x84C3
+#define GL_TEXTURE4_ARB 0x84C4
+#define GL_TEXTURE5_ARB 0x84C5
+#define GL_TEXTURE6_ARB 0x84C6
+#define GL_TEXTURE7_ARB 0x84C7
+#define GL_TEXTURE8_ARB 0x84C8
+#define GL_TEXTURE9_ARB 0x84C9
+#define GL_TEXTURE10_ARB 0x84CA
+#define GL_TEXTURE11_ARB 0x84CB
+#define GL_TEXTURE12_ARB 0x84CC
+#define GL_TEXTURE13_ARB 0x84CD
+#define GL_TEXTURE14_ARB 0x84CE
+#define GL_TEXTURE15_ARB 0x84CF
+#define GL_TEXTURE16_ARB 0x84D0
+#define GL_TEXTURE17_ARB 0x84D1
+#define GL_TEXTURE18_ARB 0x84D2
+#define GL_TEXTURE19_ARB 0x84D3
+#define GL_TEXTURE20_ARB 0x84D4
+#define GL_TEXTURE21_ARB 0x84D5
+#define GL_TEXTURE22_ARB 0x84D6
+#define GL_TEXTURE23_ARB 0x84D7
+#define GL_TEXTURE24_ARB 0x84D8
+#define GL_TEXTURE25_ARB 0x84D9
+#define GL_TEXTURE26_ARB 0x84DA
+#define GL_TEXTURE27_ARB 0x84DB
+#define GL_TEXTURE28_ARB 0x84DC
+#define GL_TEXTURE29_ARB 0x84DD
+#define GL_TEXTURE30_ARB 0x84DE
+#define GL_TEXTURE31_ARB 0x84DF
+#define GL_ACTIVE_TEXTURE_ARB 0x84E0
+#define GL_CLIENT_ACTIVE_TEXTURE_ARB 0x84E1
+#define GL_MAX_TEXTURE_UNITS_ARB 0x84E2
+#endif
+
+#ifndef GL_ARB_transpose_matrix
+#define GL_TRANSPOSE_MODELVIEW_MATRIX_ARB 0x84E3
+#define GL_TRANSPOSE_PROJECTION_MATRIX_ARB 0x84E4
+#define GL_TRANSPOSE_TEXTURE_MATRIX_ARB 0x84E5
+#define GL_TRANSPOSE_COLOR_MATRIX_ARB 0x84E6
+#endif
+
+#ifndef GL_ARB_multisample
+#define GL_MULTISAMPLE_ARB 0x809D
+#define GL_SAMPLE_ALPHA_TO_COVERAGE_ARB 0x809E
+#define GL_SAMPLE_ALPHA_TO_ONE_ARB 0x809F
+#define GL_SAMPLE_COVERAGE_ARB 0x80A0
+#define GL_SAMPLE_BUFFERS_ARB 0x80A8
+#define GL_SAMPLES_ARB 0x80A9
+#define GL_SAMPLE_COVERAGE_VALUE_ARB 0x80AA
+#define GL_SAMPLE_COVERAGE_INVERT_ARB 0x80AB
+#define GL_MULTISAMPLE_BIT_ARB 0x20000000
+#endif
+
+#ifndef GL_ARB_texture_env_add
+#endif
+
+#ifndef GL_ARB_texture_cube_map
+#define GL_NORMAL_MAP_ARB 0x8511
+#define GL_REFLECTION_MAP_ARB 0x8512
+#define GL_TEXTURE_CUBE_MAP_ARB 0x8513
+#define GL_TEXTURE_BINDING_CUBE_MAP_ARB 0x8514
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x8515
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x8516
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x8517
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x8518
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x8519
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x851A
+#define GL_PROXY_TEXTURE_CUBE_MAP_ARB 0x851B
+#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB 0x851C
+#endif
+
+#ifndef GL_ARB_texture_compression
+#define GL_COMPRESSED_ALPHA_ARB 0x84E9
+#define GL_COMPRESSED_LUMINANCE_ARB 0x84EA
+#define GL_COMPRESSED_LUMINANCE_ALPHA_ARB 0x84EB
+#define GL_COMPRESSED_INTENSITY_ARB 0x84EC
+#define GL_COMPRESSED_RGB_ARB 0x84ED
+#define GL_COMPRESSED_RGBA_ARB 0x84EE
+#define GL_TEXTURE_COMPRESSION_HINT_ARB 0x84EF
+#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB 0x86A0
+#define GL_TEXTURE_COMPRESSED_ARB 0x86A1
+#define GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A2
+#define GL_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A3
+#endif
+
+#ifndef GL_ARB_texture_border_clamp
+#define GL_CLAMP_TO_BORDER_ARB 0x812D
+#endif
+
+#ifndef GL_ARB_point_parameters
+#define GL_POINT_SIZE_MIN_ARB 0x8126
+#define GL_POINT_SIZE_MAX_ARB 0x8127
+#define GL_POINT_FADE_THRESHOLD_SIZE_ARB 0x8128
+#define GL_POINT_DISTANCE_ATTENUATION_ARB 0x8129
+#endif
+
+#ifndef GL_ARB_vertex_blend
+#define GL_MAX_VERTEX_UNITS_ARB 0x86A4
+#define GL_ACTIVE_VERTEX_UNITS_ARB 0x86A5
+#define GL_WEIGHT_SUM_UNITY_ARB 0x86A6
+#define GL_VERTEX_BLEND_ARB 0x86A7
+#define GL_CURRENT_WEIGHT_ARB 0x86A8
+#define GL_WEIGHT_ARRAY_TYPE_ARB 0x86A9
+#define GL_WEIGHT_ARRAY_STRIDE_ARB 0x86AA
+#define GL_WEIGHT_ARRAY_SIZE_ARB 0x86AB
+#define GL_WEIGHT_ARRAY_POINTER_ARB 0x86AC
+#define GL_WEIGHT_ARRAY_ARB 0x86AD
+#define GL_MODELVIEW0_ARB 0x1700
+#define GL_MODELVIEW1_ARB 0x850A
+#define GL_MODELVIEW2_ARB 0x8722
+#define GL_MODELVIEW3_ARB 0x8723
+#define GL_MODELVIEW4_ARB 0x8724
+#define GL_MODELVIEW5_ARB 0x8725
+#define GL_MODELVIEW6_ARB 0x8726
+#define GL_MODELVIEW7_ARB 0x8727
+#define GL_MODELVIEW8_ARB 0x8728
+#define GL_MODELVIEW9_ARB 0x8729
+#define GL_MODELVIEW10_ARB 0x872A
+#define GL_MODELVIEW11_ARB 0x872B
+#define GL_MODELVIEW12_ARB 0x872C
+#define GL_MODELVIEW13_ARB 0x872D
+#define GL_MODELVIEW14_ARB 0x872E
+#define GL_MODELVIEW15_ARB 0x872F
+#define GL_MODELVIEW16_ARB 0x8730
+#define GL_MODELVIEW17_ARB 0x8731
+#define GL_MODELVIEW18_ARB 0x8732
+#define GL_MODELVIEW19_ARB 0x8733
+#define GL_MODELVIEW20_ARB 0x8734
+#define GL_MODELVIEW21_ARB 0x8735
+#define GL_MODELVIEW22_ARB 0x8736
+#define GL_MODELVIEW23_ARB 0x8737
+#define GL_MODELVIEW24_ARB 0x8738
+#define GL_MODELVIEW25_ARB 0x8739
+#define GL_MODELVIEW26_ARB 0x873A
+#define GL_MODELVIEW27_ARB 0x873B
+#define GL_MODELVIEW28_ARB 0x873C
+#define GL_MODELVIEW29_ARB 0x873D
+#define GL_MODELVIEW30_ARB 0x873E
+#define GL_MODELVIEW31_ARB 0x873F
+#endif
+
+#ifndef GL_ARB_matrix_palette
+#define GL_MATRIX_PALETTE_ARB 0x8840
+#define GL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB 0x8841
+#define GL_MAX_PALETTE_MATRICES_ARB 0x8842
+#define GL_CURRENT_PALETTE_MATRIX_ARB 0x8843
+#define GL_MATRIX_INDEX_ARRAY_ARB 0x8844
+#define GL_CURRENT_MATRIX_INDEX_ARB 0x8845
+#define GL_MATRIX_INDEX_ARRAY_SIZE_ARB 0x8846
+#define GL_MATRIX_INDEX_ARRAY_TYPE_ARB 0x8847
+#define GL_MATRIX_INDEX_ARRAY_STRIDE_ARB 0x8848
+#define GL_MATRIX_INDEX_ARRAY_POINTER_ARB 0x8849
+#endif
+
+#ifndef GL_ARB_texture_env_combine
+#define GL_COMBINE_ARB 0x8570
+#define GL_COMBINE_RGB_ARB 0x8571
+#define GL_COMBINE_ALPHA_ARB 0x8572
+#define GL_SOURCE0_RGB_ARB 0x8580
+#define GL_SOURCE1_RGB_ARB 0x8581
+#define GL_SOURCE2_RGB_ARB 0x8582
+#define GL_SOURCE0_ALPHA_ARB 0x8588
+#define GL_SOURCE1_ALPHA_ARB 0x8589
+#define GL_SOURCE2_ALPHA_ARB 0x858A
+#define GL_OPERAND0_RGB_ARB 0x8590
+#define GL_OPERAND1_RGB_ARB 0x8591
+#define GL_OPERAND2_RGB_ARB 0x8592
+#define GL_OPERAND0_ALPHA_ARB 0x8598
+#define GL_OPERAND1_ALPHA_ARB 0x8599
+#define GL_OPERAND2_ALPHA_ARB 0x859A
+#define GL_RGB_SCALE_ARB 0x8573
+#define GL_ADD_SIGNED_ARB 0x8574
+#define GL_INTERPOLATE_ARB 0x8575
+#define GL_SUBTRACT_ARB 0x84E7
+#define GL_CONSTANT_ARB 0x8576
+#define GL_PRIMARY_COLOR_ARB 0x8577
+#define GL_PREVIOUS_ARB 0x8578
+#endif
+
+#ifndef GL_ARB_texture_env_crossbar
+#endif
+
+#ifndef GL_ARB_texture_env_dot3
+#define GL_DOT3_RGB_ARB 0x86AE
+#define GL_DOT3_RGBA_ARB 0x86AF
+#endif
+
+#ifndef GL_ARB_texture_mirrored_repeat
+#define GL_MIRRORED_REPEAT_ARB 0x8370
+#endif
+
+#ifndef GL_ARB_depth_texture
+#define GL_DEPTH_COMPONENT16_ARB 0x81A5
+#define GL_DEPTH_COMPONENT24_ARB 0x81A6
+#define GL_DEPTH_COMPONENT32_ARB 0x81A7
+#define GL_TEXTURE_DEPTH_SIZE_ARB 0x884A
+#define GL_DEPTH_TEXTURE_MODE_ARB 0x884B
+#endif
+
+#ifndef GL_ARB_shadow
+#define GL_TEXTURE_COMPARE_MODE_ARB 0x884C
+#define GL_TEXTURE_COMPARE_FUNC_ARB 0x884D
+#define GL_COMPARE_R_TO_TEXTURE_ARB 0x884E
+#endif
+
+#ifndef GL_ARB_shadow_ambient
+#define GL_TEXTURE_COMPARE_FAIL_VALUE_ARB 0x80BF
+#endif
+
+#ifndef GL_ARB_window_pos
+#endif
+
+#ifndef GL_ARB_vertex_program
+#define GL_COLOR_SUM_ARB 0x8458
+#define GL_VERTEX_PROGRAM_ARB 0x8620
+#define GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB 0x8622
+#define GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB 0x8623
+#define GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB 0x8624
+#define GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB 0x8625
+#define GL_CURRENT_VERTEX_ATTRIB_ARB 0x8626
+#define GL_PROGRAM_LENGTH_ARB 0x8627
+#define GL_PROGRAM_STRING_ARB 0x8628
+#define GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB 0x862E
+#define GL_MAX_PROGRAM_MATRICES_ARB 0x862F
+#define GL_CURRENT_MATRIX_STACK_DEPTH_ARB 0x8640
+#define GL_CURRENT_MATRIX_ARB 0x8641
+#define GL_VERTEX_PROGRAM_POINT_SIZE_ARB 0x8642
+#define GL_VERTEX_PROGRAM_TWO_SIDE_ARB 0x8643
+#define GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB 0x8645
+#define GL_PROGRAM_ERROR_POSITION_ARB 0x864B
+#define GL_PROGRAM_BINDING_ARB 0x8677
+#define GL_MAX_VERTEX_ATTRIBS_ARB 0x8869
+#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB 0x886A
+#define GL_PROGRAM_ERROR_STRING_ARB 0x8874
+#define GL_PROGRAM_FORMAT_ASCII_ARB 0x8875
+#define GL_PROGRAM_FORMAT_ARB 0x8876
+#define GL_PROGRAM_INSTRUCTIONS_ARB 0x88A0
+#define GL_MAX_PROGRAM_INSTRUCTIONS_ARB 0x88A1
+#define GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A2
+#define GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A3
+#define GL_PROGRAM_TEMPORARIES_ARB 0x88A4
+#define GL_MAX_PROGRAM_TEMPORARIES_ARB 0x88A5
+#define GL_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A6
+#define GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A7
+#define GL_PROGRAM_PARAMETERS_ARB 0x88A8
+#define GL_MAX_PROGRAM_PARAMETERS_ARB 0x88A9
+#define GL_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AA
+#define GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AB
+#define GL_PROGRAM_ATTRIBS_ARB 0x88AC
+#define GL_MAX_PROGRAM_ATTRIBS_ARB 0x88AD
+#define GL_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AE
+#define GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AF
+#define GL_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B0
+#define GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B1
+#define GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B2
+#define GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B3
+#define GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB 0x88B4
+#define GL_MAX_PROGRAM_ENV_PARAMETERS_ARB 0x88B5
+#define GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB 0x88B6
+#define GL_TRANSPOSE_CURRENT_MATRIX_ARB 0x88B7
+#define GL_MATRIX0_ARB 0x88C0
+#define GL_MATRIX1_ARB 0x88C1
+#define GL_MATRIX2_ARB 0x88C2
+#define GL_MATRIX3_ARB 0x88C3
+#define GL_MATRIX4_ARB 0x88C4
+#define GL_MATRIX5_ARB 0x88C5
+#define GL_MATRIX6_ARB 0x88C6
+#define GL_MATRIX7_ARB 0x88C7
+#define GL_MATRIX8_ARB 0x88C8
+#define GL_MATRIX9_ARB 0x88C9
+#define GL_MATRIX10_ARB 0x88CA
+#define GL_MATRIX11_ARB 0x88CB
+#define GL_MATRIX12_ARB 0x88CC
+#define GL_MATRIX13_ARB 0x88CD
+#define GL_MATRIX14_ARB 0x88CE
+#define GL_MATRIX15_ARB 0x88CF
+#define GL_MATRIX16_ARB 0x88D0
+#define GL_MATRIX17_ARB 0x88D1
+#define GL_MATRIX18_ARB 0x88D2
+#define GL_MATRIX19_ARB 0x88D3
+#define GL_MATRIX20_ARB 0x88D4
+#define GL_MATRIX21_ARB 0x88D5
+#define GL_MATRIX22_ARB 0x88D6
+#define GL_MATRIX23_ARB 0x88D7
+#define GL_MATRIX24_ARB 0x88D8
+#define GL_MATRIX25_ARB 0x88D9
+#define GL_MATRIX26_ARB 0x88DA
+#define GL_MATRIX27_ARB 0x88DB
+#define GL_MATRIX28_ARB 0x88DC
+#define GL_MATRIX29_ARB 0x88DD
+#define GL_MATRIX30_ARB 0x88DE
+#define GL_MATRIX31_ARB 0x88DF
+#endif
+
+#ifndef GL_ARB_fragment_program
+#define GL_FRAGMENT_PROGRAM_ARB 0x8804
+#define GL_PROGRAM_ALU_INSTRUCTIONS_ARB 0x8805
+#define GL_PROGRAM_TEX_INSTRUCTIONS_ARB 0x8806
+#define GL_PROGRAM_TEX_INDIRECTIONS_ARB 0x8807
+#define GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x8808
+#define GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x8809
+#define GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x880A
+#define GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB 0x880B
+#define GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB 0x880C
+#define GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB 0x880D
+#define GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x880E
+#define GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x880F
+#define GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x8810
+#define GL_MAX_TEXTURE_COORDS_ARB 0x8871
+#define GL_MAX_TEXTURE_IMAGE_UNITS_ARB 0x8872
+#endif
+
+#ifndef GL_ARB_vertex_buffer_object
+#define GL_BUFFER_SIZE_ARB 0x8764
+#define GL_BUFFER_USAGE_ARB 0x8765
+#define GL_ARRAY_BUFFER_ARB 0x8892
+#define GL_ELEMENT_ARRAY_BUFFER_ARB 0x8893
+#define GL_ARRAY_BUFFER_BINDING_ARB 0x8894
+#define GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB 0x8895
+#define GL_VERTEX_ARRAY_BUFFER_BINDING_ARB 0x8896
+#define GL_NORMAL_ARRAY_BUFFER_BINDING_ARB 0x8897
+#define GL_COLOR_ARRAY_BUFFER_BINDING_ARB 0x8898
+#define GL_INDEX_ARRAY_BUFFER_BINDING_ARB 0x8899
+#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB 0x889A
+#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB 0x889B
+#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB 0x889C
+#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB 0x889D
+#define GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB 0x889E
+#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB 0x889F
+#define GL_READ_ONLY_ARB 0x88B8
+#define GL_WRITE_ONLY_ARB 0x88B9
+#define GL_READ_WRITE_ARB 0x88BA
+#define GL_BUFFER_ACCESS_ARB 0x88BB
+#define GL_BUFFER_MAPPED_ARB 0x88BC
+#define GL_BUFFER_MAP_POINTER_ARB 0x88BD
+#define GL_STREAM_DRAW_ARB 0x88E0
+#define GL_STREAM_READ_ARB 0x88E1
+#define GL_STREAM_COPY_ARB 0x88E2
+#define GL_STATIC_DRAW_ARB 0x88E4
+#define GL_STATIC_READ_ARB 0x88E5
+#define GL_STATIC_COPY_ARB 0x88E6
+#define GL_DYNAMIC_DRAW_ARB 0x88E8
+#define GL_DYNAMIC_READ_ARB 0x88E9
+#define GL_DYNAMIC_COPY_ARB 0x88EA
+#endif
+
+#ifndef GL_ARB_occlusion_query
+#define GL_QUERY_COUNTER_BITS_ARB 0x8864
+#define GL_CURRENT_QUERY_ARB 0x8865
+#define GL_QUERY_RESULT_ARB 0x8866
+#define GL_QUERY_RESULT_AVAILABLE_ARB 0x8867
+#define GL_SAMPLES_PASSED_ARB 0x8914
+#endif
+
+#ifndef GL_ARB_shader_objects
+#define GL_PROGRAM_OBJECT_ARB 0x8B40
+#define GL_SHADER_OBJECT_ARB 0x8B48
+#define GL_OBJECT_TYPE_ARB 0x8B4E
+#define GL_OBJECT_SUBTYPE_ARB 0x8B4F
+#define GL_FLOAT_VEC2_ARB 0x8B50
+#define GL_FLOAT_VEC3_ARB 0x8B51
+#define GL_FLOAT_VEC4_ARB 0x8B52
+#define GL_INT_VEC2_ARB 0x8B53
+#define GL_INT_VEC3_ARB 0x8B54
+#define GL_INT_VEC4_ARB 0x8B55
+#define GL_BOOL_ARB 0x8B56
+#define GL_BOOL_VEC2_ARB 0x8B57
+#define GL_BOOL_VEC3_ARB 0x8B58
+#define GL_BOOL_VEC4_ARB 0x8B59
+#define GL_FLOAT_MAT2_ARB 0x8B5A
+#define GL_FLOAT_MAT3_ARB 0x8B5B
+#define GL_FLOAT_MAT4_ARB 0x8B5C
+#define GL_SAMPLER_1D_ARB 0x8B5D
+#define GL_SAMPLER_2D_ARB 0x8B5E
+#define GL_SAMPLER_3D_ARB 0x8B5F
+#define GL_SAMPLER_CUBE_ARB 0x8B60
+#define GL_SAMPLER_1D_SHADOW_ARB 0x8B61
+#define GL_SAMPLER_2D_SHADOW_ARB 0x8B62
+#define GL_SAMPLER_2D_RECT_ARB 0x8B63
+#define GL_SAMPLER_2D_RECT_SHADOW_ARB 0x8B64
+#define GL_OBJECT_DELETE_STATUS_ARB 0x8B80
+#define GL_OBJECT_COMPILE_STATUS_ARB 0x8B81
+#define GL_OBJECT_LINK_STATUS_ARB 0x8B82
+#define GL_OBJECT_VALIDATE_STATUS_ARB 0x8B83
+#define GL_OBJECT_INFO_LOG_LENGTH_ARB 0x8B84
+#define GL_OBJECT_ATTACHED_OBJECTS_ARB 0x8B85
+#define GL_OBJECT_ACTIVE_UNIFORMS_ARB 0x8B86
+#define GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB 0x8B87
+#define GL_OBJECT_SHADER_SOURCE_LENGTH_ARB 0x8B88
+#endif
+
+#ifndef GL_ARB_vertex_shader
+#define GL_VERTEX_SHADER_ARB 0x8B31
+#define GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB 0x8B4A
+#define GL_MAX_VARYING_FLOATS_ARB 0x8B4B
+#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB 0x8B4C
+#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB 0x8B4D
+#define GL_OBJECT_ACTIVE_ATTRIBUTES_ARB 0x8B89
+#define GL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB 0x8B8A
+#endif
+
+#ifndef GL_ARB_fragment_shader
+#define GL_FRAGMENT_SHADER_ARB 0x8B30
+#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB 0x8B49
+#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB 0x8B8B
+#endif
+
+#ifndef GL_ARB_shading_language_100
+#define GL_SHADING_LANGUAGE_VERSION_ARB 0x8B8C
+#endif
+
+#ifndef GL_ARB_texture_non_power_of_two
+#endif
+
+#ifndef GL_ARB_point_sprite
+#define GL_POINT_SPRITE_ARB 0x8861
+#define GL_COORD_REPLACE_ARB 0x8862
+#endif
+
+#ifndef GL_ARB_fragment_program_shadow
+#endif
+
+#ifndef GL_ARB_draw_buffers
+#define GL_MAX_DRAW_BUFFERS_ARB 0x8824
+#define GL_DRAW_BUFFER0_ARB 0x8825
+#define GL_DRAW_BUFFER1_ARB 0x8826
+#define GL_DRAW_BUFFER2_ARB 0x8827
+#define GL_DRAW_BUFFER3_ARB 0x8828
+#define GL_DRAW_BUFFER4_ARB 0x8829
+#define GL_DRAW_BUFFER5_ARB 0x882A
+#define GL_DRAW_BUFFER6_ARB 0x882B
+#define GL_DRAW_BUFFER7_ARB 0x882C
+#define GL_DRAW_BUFFER8_ARB 0x882D
+#define GL_DRAW_BUFFER9_ARB 0x882E
+#define GL_DRAW_BUFFER10_ARB 0x882F
+#define GL_DRAW_BUFFER11_ARB 0x8830
+#define GL_DRAW_BUFFER12_ARB 0x8831
+#define GL_DRAW_BUFFER13_ARB 0x8832
+#define GL_DRAW_BUFFER14_ARB 0x8833
+#define GL_DRAW_BUFFER15_ARB 0x8834
+#endif
+
+#ifndef GL_ARB_texture_rectangle
+#define GL_TEXTURE_RECTANGLE_ARB 0x84F5
+#define GL_TEXTURE_BINDING_RECTANGLE_ARB 0x84F6
+#define GL_PROXY_TEXTURE_RECTANGLE_ARB 0x84F7
+#define GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB 0x84F8
+#endif
+
+#ifndef GL_ARB_color_buffer_float
+#define GL_RGBA_FLOAT_MODE_ARB 0x8820
+#define GL_CLAMP_VERTEX_COLOR_ARB 0x891A
+#define GL_CLAMP_FRAGMENT_COLOR_ARB 0x891B
+#define GL_CLAMP_READ_COLOR_ARB 0x891C
+#define GL_FIXED_ONLY_ARB 0x891D
+#endif
+
+#ifndef GL_ARB_half_float_pixel
+#define GL_HALF_FLOAT_ARB 0x140B
+#endif
+
+#ifndef GL_ARB_texture_float
+#define GL_TEXTURE_RED_TYPE_ARB 0x8C10
+#define GL_TEXTURE_GREEN_TYPE_ARB 0x8C11
+#define GL_TEXTURE_BLUE_TYPE_ARB 0x8C12
+#define GL_TEXTURE_ALPHA_TYPE_ARB 0x8C13
+#define GL_TEXTURE_LUMINANCE_TYPE_ARB 0x8C14
+#define GL_TEXTURE_INTENSITY_TYPE_ARB 0x8C15
+#define GL_TEXTURE_DEPTH_TYPE_ARB 0x8C16
+#define GL_UNSIGNED_NORMALIZED_ARB 0x8C17
+#define GL_RGBA32F_ARB 0x8814
+#define GL_RGB32F_ARB 0x8815
+#define GL_ALPHA32F_ARB 0x8816
+#define GL_INTENSITY32F_ARB 0x8817
+#define GL_LUMINANCE32F_ARB 0x8818
+#define GL_LUMINANCE_ALPHA32F_ARB 0x8819
+#define GL_RGBA16F_ARB 0x881A
+#define GL_RGB16F_ARB 0x881B
+#define GL_ALPHA16F_ARB 0x881C
+#define GL_INTENSITY16F_ARB 0x881D
+#define GL_LUMINANCE16F_ARB 0x881E
+#define GL_LUMINANCE_ALPHA16F_ARB 0x881F
+#endif
+
+#ifndef GL_ARB_pixel_buffer_object
+#define GL_PIXEL_PACK_BUFFER_ARB 0x88EB
+#define GL_PIXEL_UNPACK_BUFFER_ARB 0x88EC
+#define GL_PIXEL_PACK_BUFFER_BINDING_ARB 0x88ED
+#define GL_PIXEL_UNPACK_BUFFER_BINDING_ARB 0x88EF
+#endif
+
+#ifndef GL_ARB_depth_buffer_float
+#define GL_DEPTH_COMPONENT32F 0x8CAC
+#define GL_DEPTH32F_STENCIL8 0x8CAD
+#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV 0x8DAD
+#endif
+
+#ifndef GL_ARB_draw_instanced
+#endif
+
+#ifndef GL_ARB_framebuffer_object
+#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506
+#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING 0x8210
+#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE 0x8211
+#define GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE 0x8212
+#define GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE 0x8213
+#define GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE 0x8214
+#define GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE 0x8215
+#define GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE 0x8216
+#define GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE 0x8217
+#define GL_FRAMEBUFFER_DEFAULT 0x8218
+#define GL_FRAMEBUFFER_UNDEFINED 0x8219
+#define GL_DEPTH_STENCIL_ATTACHMENT 0x821A
+#define GL_MAX_RENDERBUFFER_SIZE 0x84E8
+#define GL_DEPTH_STENCIL 0x84F9
+#define GL_UNSIGNED_INT_24_8 0x84FA
+#define GL_DEPTH24_STENCIL8 0x88F0
+#define GL_TEXTURE_STENCIL_SIZE 0x88F1
+#define GL_TEXTURE_RED_TYPE 0x8C10
+#define GL_TEXTURE_GREEN_TYPE 0x8C11
+#define GL_TEXTURE_BLUE_TYPE 0x8C12
+#define GL_TEXTURE_ALPHA_TYPE 0x8C13
+#define GL_TEXTURE_DEPTH_TYPE 0x8C16
+#define GL_UNSIGNED_NORMALIZED 0x8C17
+#define GL_FRAMEBUFFER_BINDING 0x8CA6
+#define GL_DRAW_FRAMEBUFFER_BINDING GL_FRAMEBUFFER_BINDING
+#define GL_RENDERBUFFER_BINDING 0x8CA7
+#define GL_READ_FRAMEBUFFER 0x8CA8
+#define GL_DRAW_FRAMEBUFFER 0x8CA9
+#define GL_READ_FRAMEBUFFER_BINDING 0x8CAA
+#define GL_RENDERBUFFER_SAMPLES 0x8CAB
+#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0
+#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4
+#define GL_FRAMEBUFFER_COMPLETE 0x8CD5
+#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6
+#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7
+#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER 0x8CDB
+#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 0x8CDC
+#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD
+#define GL_MAX_COLOR_ATTACHMENTS 0x8CDF
+#define GL_COLOR_ATTACHMENT0 0x8CE0
+#define GL_COLOR_ATTACHMENT1 0x8CE1
+#define GL_COLOR_ATTACHMENT2 0x8CE2
+#define GL_COLOR_ATTACHMENT3 0x8CE3
+#define GL_COLOR_ATTACHMENT4 0x8CE4
+#define GL_COLOR_ATTACHMENT5 0x8CE5
+#define GL_COLOR_ATTACHMENT6 0x8CE6
+#define GL_COLOR_ATTACHMENT7 0x8CE7
+#define GL_COLOR_ATTACHMENT8 0x8CE8
+#define GL_COLOR_ATTACHMENT9 0x8CE9
+#define GL_COLOR_ATTACHMENT10 0x8CEA
+#define GL_COLOR_ATTACHMENT11 0x8CEB
+#define GL_COLOR_ATTACHMENT12 0x8CEC
+#define GL_COLOR_ATTACHMENT13 0x8CED
+#define GL_COLOR_ATTACHMENT14 0x8CEE
+#define GL_COLOR_ATTACHMENT15 0x8CEF
+#define GL_DEPTH_ATTACHMENT 0x8D00
+#define GL_STENCIL_ATTACHMENT 0x8D20
+#define GL_FRAMEBUFFER 0x8D40
+#define GL_RENDERBUFFER 0x8D41
+#define GL_RENDERBUFFER_WIDTH 0x8D42
+#define GL_RENDERBUFFER_HEIGHT 0x8D43
+#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44
+#define GL_STENCIL_INDEX1 0x8D46
+#define GL_STENCIL_INDEX4 0x8D47
+#define GL_STENCIL_INDEX8 0x8D48
+#define GL_STENCIL_INDEX16 0x8D49
+#define GL_RENDERBUFFER_RED_SIZE 0x8D50
+#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51
+#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52
+#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53
+#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54
+#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55
+#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56
+#define GL_MAX_SAMPLES 0x8D57
+#endif
+
+#ifndef GL_ARB_framebuffer_object_DEPRECATED
+#define GL_INDEX 0x8222
+#define GL_TEXTURE_LUMINANCE_TYPE 0x8C14
+#define GL_TEXTURE_INTENSITY_TYPE 0x8C15
+#endif
+
+#ifndef GL_ARB_framebuffer_sRGB
+#define GL_FRAMEBUFFER_SRGB 0x8DB9
+#endif
+
+#ifndef GL_ARB_geometry_shader4
+#define GL_LINES_ADJACENCY_ARB 0x000A
+#define GL_LINE_STRIP_ADJACENCY_ARB 0x000B
+#define GL_TRIANGLES_ADJACENCY_ARB 0x000C
+#define GL_TRIANGLE_STRIP_ADJACENCY_ARB 0x000D
+#define GL_PROGRAM_POINT_SIZE_ARB 0x8642
+#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_ARB 0x8C29
+#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_ARB 0x8DA7
+#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_ARB 0x8DA8
+#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_ARB 0x8DA9
+#define GL_GEOMETRY_SHADER_ARB 0x8DD9
+#define GL_GEOMETRY_VERTICES_OUT_ARB 0x8DDA
+#define GL_GEOMETRY_INPUT_TYPE_ARB 0x8DDB
+#define GL_GEOMETRY_OUTPUT_TYPE_ARB 0x8DDC
+#define GL_MAX_GEOMETRY_VARYING_COMPONENTS_ARB 0x8DDD
+#define GL_MAX_VERTEX_VARYING_COMPONENTS_ARB 0x8DDE
+#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_ARB 0x8DDF
+#define GL_MAX_GEOMETRY_OUTPUT_VERTICES_ARB 0x8DE0
+#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_ARB 0x8DE1
+/* reuse GL_MAX_VARYING_COMPONENTS */
+/* reuse GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER */
+#endif
+
+#ifndef GL_ARB_half_float_vertex
+#define GL_HALF_FLOAT 0x140B
+#endif
+
+#ifndef GL_ARB_instanced_arrays
+#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ARB 0x88FE
+#endif
+
+#ifndef GL_ARB_map_buffer_range
+#define GL_MAP_READ_BIT 0x0001
+#define GL_MAP_WRITE_BIT 0x0002
+#define GL_MAP_INVALIDATE_RANGE_BIT 0x0004
+#define GL_MAP_INVALIDATE_BUFFER_BIT 0x0008
+#define GL_MAP_FLUSH_EXPLICIT_BIT 0x0010
+#define GL_MAP_UNSYNCHRONIZED_BIT 0x0020
+#endif
+
+#ifndef GL_ARB_texture_buffer_object
+#define GL_TEXTURE_BUFFER_ARB 0x8C2A
+#define GL_MAX_TEXTURE_BUFFER_SIZE_ARB 0x8C2B
+#define GL_TEXTURE_BINDING_BUFFER_ARB 0x8C2C
+#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_ARB 0x8C2D
+#define GL_TEXTURE_BUFFER_FORMAT_ARB 0x8C2E
+#endif
+
+#ifndef GL_ARB_texture_compression_rgtc
+#define GL_COMPRESSED_RED_RGTC1 0x8DBB
+#define GL_COMPRESSED_SIGNED_RED_RGTC1 0x8DBC
+#define GL_COMPRESSED_RG_RGTC2 0x8DBD
+#define GL_COMPRESSED_SIGNED_RG_RGTC2 0x8DBE
+#endif
+
+#ifndef GL_ARB_texture_rg
+#define GL_RG 0x8227
+#define GL_RG_INTEGER 0x8228
+#define GL_R8 0x8229
+#define GL_R16 0x822A
+#define GL_RG8 0x822B
+#define GL_RG16 0x822C
+#define GL_R16F 0x822D
+#define GL_R32F 0x822E
+#define GL_RG16F 0x822F
+#define GL_RG32F 0x8230
+#define GL_R8I 0x8231
+#define GL_R8UI 0x8232
+#define GL_R16I 0x8233
+#define GL_R16UI 0x8234
+#define GL_R32I 0x8235
+#define GL_R32UI 0x8236
+#define GL_RG8I 0x8237
+#define GL_RG8UI 0x8238
+#define GL_RG16I 0x8239
+#define GL_RG16UI 0x823A
+#define GL_RG32I 0x823B
+#define GL_RG32UI 0x823C
+#endif
+
+#ifndef GL_ARB_vertex_array_object
+#define GL_VERTEX_ARRAY_BINDING 0x85B5
+#endif
+
+#ifndef GL_ARB_uniform_buffer_object
+#define GL_UNIFORM_BUFFER 0x8A11
+#define GL_UNIFORM_BUFFER_BINDING 0x8A28
+#define GL_UNIFORM_BUFFER_START 0x8A29
+#define GL_UNIFORM_BUFFER_SIZE 0x8A2A
+#define GL_MAX_VERTEX_UNIFORM_BLOCKS 0x8A2B
+#define GL_MAX_GEOMETRY_UNIFORM_BLOCKS 0x8A2C
+#define GL_MAX_FRAGMENT_UNIFORM_BLOCKS 0x8A2D
+#define GL_MAX_COMBINED_UNIFORM_BLOCKS 0x8A2E
+#define GL_MAX_UNIFORM_BUFFER_BINDINGS 0x8A2F
+#define GL_MAX_UNIFORM_BLOCK_SIZE 0x8A30
+#define GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS 0x8A31
+#define GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS 0x8A32
+#define GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS 0x8A33
+#define GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT 0x8A34
+#define GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH 0x8A35
+#define GL_ACTIVE_UNIFORM_BLOCKS 0x8A36
+#define GL_UNIFORM_TYPE 0x8A37
+#define GL_UNIFORM_SIZE 0x8A38
+#define GL_UNIFORM_NAME_LENGTH 0x8A39
+#define GL_UNIFORM_BLOCK_INDEX 0x8A3A
+#define GL_UNIFORM_OFFSET 0x8A3B
+#define GL_UNIFORM_ARRAY_STRIDE 0x8A3C
+#define GL_UNIFORM_MATRIX_STRIDE 0x8A3D
+#define GL_UNIFORM_IS_ROW_MAJOR 0x8A3E
+#define GL_UNIFORM_BLOCK_BINDING 0x8A3F
+#define GL_UNIFORM_BLOCK_DATA_SIZE 0x8A40
+#define GL_UNIFORM_BLOCK_NAME_LENGTH 0x8A41
+#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS 0x8A42
+#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES 0x8A43
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER 0x8A44
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER 0x8A45
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER 0x8A46
+#define GL_INVALID_INDEX 0xFFFFFFFFu
+#endif
+
+#ifndef GL_ARB_compatibility
+/* ARB_compatibility just defines tokens from core 3.0 */
+#endif
+
+#ifndef GL_ARB_copy_buffer
+#define GL_COPY_READ_BUFFER 0x8F36
+#define GL_COPY_WRITE_BUFFER 0x8F37
+#endif
+
+#ifndef GL_ARB_shader_texture_lod
+#endif
+
+#ifndef GL_ARB_depth_clamp
+#define GL_DEPTH_CLAMP 0x864F
+#endif
+
+#ifndef GL_ARB_draw_elements_base_vertex
+#endif
+
+#ifndef GL_ARB_fragment_coord_conventions
+#endif
+
+#ifndef GL_ARB_provoking_vertex
+#define GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION 0x8E4C
+#define GL_FIRST_VERTEX_CONVENTION 0x8E4D
+#define GL_LAST_VERTEX_CONVENTION 0x8E4E
+#define GL_PROVOKING_VERTEX 0x8E4F
+#endif
+
+#ifndef GL_ARB_seamless_cube_map
+#define GL_TEXTURE_CUBE_MAP_SEAMLESS 0x884F
+#endif
+
+#ifndef GL_ARB_sync
+#define GL_MAX_SERVER_WAIT_TIMEOUT 0x9111
+#define GL_OBJECT_TYPE 0x9112
+#define GL_SYNC_CONDITION 0x9113
+#define GL_SYNC_STATUS 0x9114
+#define GL_SYNC_FLAGS 0x9115
+#define GL_SYNC_FENCE 0x9116
+#define GL_SYNC_GPU_COMMANDS_COMPLETE 0x9117
+#define GL_UNSIGNALED 0x9118
+#define GL_SIGNALED 0x9119
+#define GL_ALREADY_SIGNALED 0x911A
+#define GL_TIMEOUT_EXPIRED 0x911B
+#define GL_CONDITION_SATISFIED 0x911C
+#define GL_WAIT_FAILED 0x911D
+#define GL_SYNC_FLUSH_COMMANDS_BIT 0x00000001
+#define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFFull
+#endif
+
+#ifndef GL_ARB_texture_multisample
+#define GL_SAMPLE_POSITION 0x8E50
+#define GL_SAMPLE_MASK 0x8E51
+#define GL_SAMPLE_MASK_VALUE 0x8E52
+#define GL_MAX_SAMPLE_MASK_WORDS 0x8E59
+#define GL_TEXTURE_2D_MULTISAMPLE 0x9100
+#define GL_PROXY_TEXTURE_2D_MULTISAMPLE 0x9101
+#define GL_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9102
+#define GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9103
+#define GL_TEXTURE_BINDING_2D_MULTISAMPLE 0x9104
+#define GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY 0x9105
+#define GL_TEXTURE_SAMPLES 0x9106
+#define GL_TEXTURE_FIXED_SAMPLE_LOCATIONS 0x9107
+#define GL_SAMPLER_2D_MULTISAMPLE 0x9108
+#define GL_INT_SAMPLER_2D_MULTISAMPLE 0x9109
+#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE 0x910A
+#define GL_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910B
+#define GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910C
+#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910D
+#define GL_MAX_COLOR_TEXTURE_SAMPLES 0x910E
+#define GL_MAX_DEPTH_TEXTURE_SAMPLES 0x910F
+#define GL_MAX_INTEGER_SAMPLES 0x9110
+#endif
+
+#ifndef GL_ARB_vertex_array_bgra
+/* reuse GL_BGRA */
+#endif
+
+#ifndef GL_ARB_draw_buffers_blend
+#endif
+
+#ifndef GL_ARB_sample_shading
+#define GL_SAMPLE_SHADING_ARB 0x8C36
+#define GL_MIN_SAMPLE_SHADING_VALUE_ARB 0x8C37
+#endif
+
+#ifndef GL_ARB_texture_cube_map_array
+#define GL_TEXTURE_CUBE_MAP_ARRAY_ARB 0x9009
+#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY_ARB 0x900A
+#define GL_PROXY_TEXTURE_CUBE_MAP_ARRAY_ARB 0x900B
+#define GL_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900C
+#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW_ARB 0x900D
+#define GL_INT_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900E
+#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900F
+#endif
+
+#ifndef GL_ARB_texture_gather
+#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET_ARB 0x8E5E
+#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET_ARB 0x8E5F
+#endif
+
+#ifndef GL_ARB_texture_query_lod
+#endif
+
+#ifndef GL_ARB_shading_language_include
+#define GL_SHADER_INCLUDE_ARB 0x8DAE
+#define GL_NAMED_STRING_LENGTH_ARB 0x8DE9
+#define GL_NAMED_STRING_TYPE_ARB 0x8DEA
+#endif
+
+#ifndef GL_ARB_texture_compression_bptc
+#define GL_COMPRESSED_RGBA_BPTC_UNORM_ARB 0x8E8C
+#define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB 0x8E8D
+#define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB 0x8E8E
+#define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB 0x8E8F
+#endif
+
+#ifndef GL_ARB_blend_func_extended
+#define GL_SRC1_COLOR 0x88F9
+/* reuse GL_SRC1_ALPHA */
+#define GL_ONE_MINUS_SRC1_COLOR 0x88FA
+#define GL_ONE_MINUS_SRC1_ALPHA 0x88FB
+#define GL_MAX_DUAL_SOURCE_DRAW_BUFFERS 0x88FC
+#endif
+
+#ifndef GL_ARB_explicit_attrib_location
+#endif
+
+#ifndef GL_ARB_occlusion_query2
+#define GL_ANY_SAMPLES_PASSED 0x8C2F
+#endif
+
+#ifndef GL_ARB_sampler_objects
+#define GL_SAMPLER_BINDING 0x8919
+#endif
+
+#ifndef GL_ARB_shader_bit_encoding
+#endif
+
+#ifndef GL_ARB_texture_rgb10_a2ui
+#define GL_RGB10_A2UI 0x906F
+#endif
+
+#ifndef GL_ARB_texture_swizzle
+#define GL_TEXTURE_SWIZZLE_R 0x8E42
+#define GL_TEXTURE_SWIZZLE_G 0x8E43
+#define GL_TEXTURE_SWIZZLE_B 0x8E44
+#define GL_TEXTURE_SWIZZLE_A 0x8E45
+#define GL_TEXTURE_SWIZZLE_RGBA 0x8E46
+#endif
+
+#ifndef GL_ARB_timer_query
+#define GL_TIME_ELAPSED 0x88BF
+#define GL_TIMESTAMP 0x8E28
+#endif
+
+#ifndef GL_ARB_vertex_type_2_10_10_10_rev
+/* reuse GL_UNSIGNED_INT_2_10_10_10_REV */
+#define GL_INT_2_10_10_10_REV 0x8D9F
+#endif
+
+#ifndef GL_ARB_draw_indirect
+#define GL_DRAW_INDIRECT_BUFFER 0x8F3F
+#define GL_DRAW_INDIRECT_BUFFER_BINDING 0x8F43
+#endif
+
+#ifndef GL_ARB_gpu_shader5
+#define GL_GEOMETRY_SHADER_INVOCATIONS 0x887F
+#define GL_MAX_GEOMETRY_SHADER_INVOCATIONS 0x8E5A
+#define GL_MIN_FRAGMENT_INTERPOLATION_OFFSET 0x8E5B
+#define GL_MAX_FRAGMENT_INTERPOLATION_OFFSET 0x8E5C
+#define GL_FRAGMENT_INTERPOLATION_OFFSET_BITS 0x8E5D
+/* reuse GL_MAX_VERTEX_STREAMS */
+#endif
+
+#ifndef GL_ARB_gpu_shader_fp64
+/* reuse GL_DOUBLE */
+#define GL_DOUBLE_VEC2 0x8FFC
+#define GL_DOUBLE_VEC3 0x8FFD
+#define GL_DOUBLE_VEC4 0x8FFE
+#define GL_DOUBLE_MAT2 0x8F46
+#define GL_DOUBLE_MAT3 0x8F47
+#define GL_DOUBLE_MAT4 0x8F48
+#define GL_DOUBLE_MAT2x3 0x8F49
+#define GL_DOUBLE_MAT2x4 0x8F4A
+#define GL_DOUBLE_MAT3x2 0x8F4B
+#define GL_DOUBLE_MAT3x4 0x8F4C
+#define GL_DOUBLE_MAT4x2 0x8F4D
+#define GL_DOUBLE_MAT4x3 0x8F4E
+#endif
+
+#ifndef GL_ARB_shader_subroutine
+#define GL_ACTIVE_SUBROUTINES 0x8DE5
+#define GL_ACTIVE_SUBROUTINE_UNIFORMS 0x8DE6
+#define GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS 0x8E47
+#define GL_ACTIVE_SUBROUTINE_MAX_LENGTH 0x8E48
+#define GL_ACTIVE_SUBROUTINE_UNIFORM_MAX_LENGTH 0x8E49
+#define GL_MAX_SUBROUTINES 0x8DE7
+#define GL_MAX_SUBROUTINE_UNIFORM_LOCATIONS 0x8DE8
+#define GL_NUM_COMPATIBLE_SUBROUTINES 0x8E4A
+#define GL_COMPATIBLE_SUBROUTINES 0x8E4B
+/* reuse GL_UNIFORM_SIZE */
+/* reuse GL_UNIFORM_NAME_LENGTH */
+#endif
+
+#ifndef GL_ARB_tessellation_shader
+#define GL_PATCHES 0x000E
+#define GL_PATCH_VERTICES 0x8E72
+#define GL_PATCH_DEFAULT_INNER_LEVEL 0x8E73
+#define GL_PATCH_DEFAULT_OUTER_LEVEL 0x8E74
+#define GL_TESS_CONTROL_OUTPUT_VERTICES 0x8E75
+#define GL_TESS_GEN_MODE 0x8E76
+#define GL_TESS_GEN_SPACING 0x8E77
+#define GL_TESS_GEN_VERTEX_ORDER 0x8E78
+#define GL_TESS_GEN_POINT_MODE 0x8E79
+/* reuse GL_TRIANGLES */
+/* reuse GL_QUADS */
+#define GL_ISOLINES 0x8E7A
+/* reuse GL_EQUAL */
+#define GL_FRACTIONAL_ODD 0x8E7B
+#define GL_FRACTIONAL_EVEN 0x8E7C
+/* reuse GL_CCW */
+/* reuse GL_CW */
+#define GL_MAX_PATCH_VERTICES 0x8E7D
+#define GL_MAX_TESS_GEN_LEVEL 0x8E7E
+#define GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E7F
+#define GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E80
+#define GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS 0x8E81
+#define GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS 0x8E82
+#define GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS 0x8E83
+#define GL_MAX_TESS_PATCH_COMPONENTS 0x8E84
+#define GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS 0x8E85
+#define GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS 0x8E86
+#define GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS 0x8E89
+#define GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS 0x8E8A
+#define GL_MAX_TESS_CONTROL_INPUT_COMPONENTS 0x886C
+#define GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS 0x886D
+#define GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E1E
+#define GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E1F
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_CONTROL_SHADER 0x84F0
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_EVALUATION_SHADER 0x84F1
+#define GL_TESS_EVALUATION_SHADER 0x8E87
+#define GL_TESS_CONTROL_SHADER 0x8E88
+#endif
+
+#ifndef GL_ARB_texture_buffer_object_rgb32
+/* reuse GL_RGB32F */
+/* reuse GL_RGB32UI */
+/* reuse GL_RGB32I */
+#endif
+
+#ifndef GL_ARB_transform_feedback2
+#define GL_TRANSFORM_FEEDBACK 0x8E22
+#define GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED 0x8E23
+#define GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE 0x8E24
+#define GL_TRANSFORM_FEEDBACK_BINDING 0x8E25
+#endif
+
+#ifndef GL_ARB_transform_feedback3
+#define GL_MAX_TRANSFORM_FEEDBACK_BUFFERS 0x8E70
+#define GL_MAX_VERTEX_STREAMS 0x8E71
+#endif
+
+#ifndef GL_ARB_ES2_compatibility
+#define GL_FIXED 0x140C
+#define GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A
+#define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B
+#define GL_LOW_FLOAT 0x8DF0
+#define GL_MEDIUM_FLOAT 0x8DF1
+#define GL_HIGH_FLOAT 0x8DF2
+#define GL_LOW_INT 0x8DF3
+#define GL_MEDIUM_INT 0x8DF4
+#define GL_HIGH_INT 0x8DF5
+#define GL_SHADER_COMPILER 0x8DFA
+#define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9
+#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB
+#define GL_MAX_VARYING_VECTORS 0x8DFC
+#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD
+#endif
+
+#ifndef GL_ARB_get_program_binary
+#define GL_PROGRAM_BINARY_RETRIEVABLE_HINT 0x8257
+#define GL_PROGRAM_BINARY_LENGTH 0x8741
+#define GL_NUM_PROGRAM_BINARY_FORMATS 0x87FE
+#define GL_PROGRAM_BINARY_FORMATS 0x87FF
+#endif
+
+#ifndef GL_ARB_separate_shader_objects
+#define GL_VERTEX_SHADER_BIT 0x00000001
+#define GL_FRAGMENT_SHADER_BIT 0x00000002
+#define GL_GEOMETRY_SHADER_BIT 0x00000004
+#define GL_TESS_CONTROL_SHADER_BIT 0x00000008
+#define GL_TESS_EVALUATION_SHADER_BIT 0x00000010
+#define GL_ALL_SHADER_BITS 0xFFFFFFFF
+#define GL_PROGRAM_SEPARABLE 0x8258
+#define GL_ACTIVE_PROGRAM 0x8259
+#define GL_PROGRAM_PIPELINE_BINDING 0x825A
+#endif
+
+#ifndef GL_ARB_shader_precision
+#endif
+
+#ifndef GL_ARB_vertex_attrib_64bit
+/* reuse GL_RGB32I */
+/* reuse GL_DOUBLE_VEC2 */
+/* reuse GL_DOUBLE_VEC3 */
+/* reuse GL_DOUBLE_VEC4 */
+/* reuse GL_DOUBLE_MAT2 */
+/* reuse GL_DOUBLE_MAT3 */
+/* reuse GL_DOUBLE_MAT4 */
+/* reuse GL_DOUBLE_MAT2x3 */
+/* reuse GL_DOUBLE_MAT2x4 */
+/* reuse GL_DOUBLE_MAT3x2 */
+/* reuse GL_DOUBLE_MAT3x4 */
+/* reuse GL_DOUBLE_MAT4x2 */
+/* reuse GL_DOUBLE_MAT4x3 */
+#endif
+
+#ifndef GL_ARB_viewport_array
+/* reuse GL_SCISSOR_BOX */
+/* reuse GL_VIEWPORT */
+/* reuse GL_DEPTH_RANGE */
+/* reuse GL_SCISSOR_TEST */
+#define GL_MAX_VIEWPORTS 0x825B
+#define GL_VIEWPORT_SUBPIXEL_BITS 0x825C
+#define GL_VIEWPORT_BOUNDS_RANGE 0x825D
+#define GL_LAYER_PROVOKING_VERTEX 0x825E
+#define GL_VIEWPORT_INDEX_PROVOKING_VERTEX 0x825F
+#define GL_UNDEFINED_VERTEX 0x8260
+/* reuse GL_FIRST_VERTEX_CONVENTION */
+/* reuse GL_LAST_VERTEX_CONVENTION */
+/* reuse GL_PROVOKING_VERTEX */
+#endif
+
+#ifndef GL_ARB_cl_event
+#define GL_SYNC_CL_EVENT_ARB 0x8240
+#define GL_SYNC_CL_EVENT_COMPLETE_ARB 0x8241
+#endif
+
+#ifndef GL_ARB_debug_output
+#define GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB 0x8242
+#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_ARB 0x8243
+#define GL_DEBUG_CALLBACK_FUNCTION_ARB 0x8244
+#define GL_DEBUG_CALLBACK_USER_PARAM_ARB 0x8245
+#define GL_DEBUG_SOURCE_API_ARB 0x8246
+#define GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB 0x8247
+#define GL_DEBUG_SOURCE_SHADER_COMPILER_ARB 0x8248
+#define GL_DEBUG_SOURCE_THIRD_PARTY_ARB 0x8249
+#define GL_DEBUG_SOURCE_APPLICATION_ARB 0x824A
+#define GL_DEBUG_SOURCE_OTHER_ARB 0x824B
+#define GL_DEBUG_TYPE_ERROR_ARB 0x824C
+#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB 0x824D
+#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB 0x824E
+#define GL_DEBUG_TYPE_PORTABILITY_ARB 0x824F
+#define GL_DEBUG_TYPE_PERFORMANCE_ARB 0x8250
+#define GL_DEBUG_TYPE_OTHER_ARB 0x8251
+#define GL_MAX_DEBUG_MESSAGE_LENGTH_ARB 0x9143
+#define GL_MAX_DEBUG_LOGGED_MESSAGES_ARB 0x9144
+#define GL_DEBUG_LOGGED_MESSAGES_ARB 0x9145
+#define GL_DEBUG_SEVERITY_HIGH_ARB 0x9146
+#define GL_DEBUG_SEVERITY_MEDIUM_ARB 0x9147
+#define GL_DEBUG_SEVERITY_LOW_ARB 0x9148
+#endif
+
+#ifndef GL_ARB_robustness
+/* reuse GL_NO_ERROR */
+#define GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT_ARB 0x00000004
+#define GL_LOSE_CONTEXT_ON_RESET_ARB 0x8252
+#define GL_GUILTY_CONTEXT_RESET_ARB 0x8253
+#define GL_INNOCENT_CONTEXT_RESET_ARB 0x8254
+#define GL_UNKNOWN_CONTEXT_RESET_ARB 0x8255
+#define GL_RESET_NOTIFICATION_STRATEGY_ARB 0x8256
+#define GL_NO_RESET_NOTIFICATION_ARB 0x8261
+#endif
+
+#ifndef GL_ARB_shader_stencil_export
+#endif
+
+#ifndef GL_ARB_base_instance
+#endif
+
+#ifndef GL_ARB_shading_language_420pack
+#endif
+
+#ifndef GL_ARB_transform_feedback_instanced
+#endif
+
+#ifndef GL_ARB_compressed_texture_pixel_storage
+#define GL_UNPACK_COMPRESSED_BLOCK_WIDTH 0x9127
+#define GL_UNPACK_COMPRESSED_BLOCK_HEIGHT 0x9128
+#define GL_UNPACK_COMPRESSED_BLOCK_DEPTH 0x9129
+#define GL_UNPACK_COMPRESSED_BLOCK_SIZE 0x912A
+#define GL_PACK_COMPRESSED_BLOCK_WIDTH 0x912B
+#define GL_PACK_COMPRESSED_BLOCK_HEIGHT 0x912C
+#define GL_PACK_COMPRESSED_BLOCK_DEPTH 0x912D
+#define GL_PACK_COMPRESSED_BLOCK_SIZE 0x912E
+#endif
+
+#ifndef GL_ARB_conservative_depth
+#endif
+
+#ifndef GL_ARB_internalformat_query
+#define GL_NUM_SAMPLE_COUNTS 0x9380
+#endif
+
+#ifndef GL_ARB_map_buffer_alignment
+#define GL_MIN_MAP_BUFFER_ALIGNMENT 0x90BC
+#endif
+
+#ifndef GL_ARB_shader_atomic_counters
+#define GL_ATOMIC_COUNTER_BUFFER 0x92C0
+#define GL_ATOMIC_COUNTER_BUFFER_BINDING 0x92C1
+#define GL_ATOMIC_COUNTER_BUFFER_START 0x92C2
+#define GL_ATOMIC_COUNTER_BUFFER_SIZE 0x92C3
+#define GL_ATOMIC_COUNTER_BUFFER_DATA_SIZE 0x92C4
+#define GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTERS 0x92C5
+#define GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTER_INDICES 0x92C6
+#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_VERTEX_SHADER 0x92C7
+#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_CONTROL_SHADER 0x92C8
+#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_EVALUATION_SHADER 0x92C9
+#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_GEOMETRY_SHADER 0x92CA
+#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_FRAGMENT_SHADER 0x92CB
+#define GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS 0x92CC
+#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS 0x92CD
+#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS 0x92CE
+#define GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS 0x92CF
+#define GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS 0x92D0
+#define GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS 0x92D1
+#define GL_MAX_VERTEX_ATOMIC_COUNTERS 0x92D2
+#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS 0x92D3
+#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS 0x92D4
+#define GL_MAX_GEOMETRY_ATOMIC_COUNTERS 0x92D5
+#define GL_MAX_FRAGMENT_ATOMIC_COUNTERS 0x92D6
+#define GL_MAX_COMBINED_ATOMIC_COUNTERS 0x92D7
+#define GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE 0x92D8
+#define GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS 0x92DC
+#define GL_ACTIVE_ATOMIC_COUNTER_BUFFERS 0x92D9
+#define GL_UNIFORM_ATOMIC_COUNTER_BUFFER_INDEX 0x92DA
+#define GL_UNSIGNED_INT_ATOMIC_COUNTER 0x92DB
+#endif
+
+#ifndef GL_ARB_shader_image_load_store
+#define GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT 0x00000001
+#define GL_ELEMENT_ARRAY_BARRIER_BIT 0x00000002
+#define GL_UNIFORM_BARRIER_BIT 0x00000004
+#define GL_TEXTURE_FETCH_BARRIER_BIT 0x00000008
+#define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT 0x00000020
+#define GL_COMMAND_BARRIER_BIT 0x00000040
+#define GL_PIXEL_BUFFER_BARRIER_BIT 0x00000080
+#define GL_TEXTURE_UPDATE_BARRIER_BIT 0x00000100
+#define GL_BUFFER_UPDATE_BARRIER_BIT 0x00000200
+#define GL_FRAMEBUFFER_BARRIER_BIT 0x00000400
+#define GL_TRANSFORM_FEEDBACK_BARRIER_BIT 0x00000800
+#define GL_ATOMIC_COUNTER_BARRIER_BIT 0x00001000
+#define GL_ALL_BARRIER_BITS 0xFFFFFFFF
+#define GL_MAX_IMAGE_UNITS 0x8F38
+#define GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS 0x8F39
+#define GL_IMAGE_BINDING_NAME 0x8F3A
+#define GL_IMAGE_BINDING_LEVEL 0x8F3B
+#define GL_IMAGE_BINDING_LAYERED 0x8F3C
+#define GL_IMAGE_BINDING_LAYER 0x8F3D
+#define GL_IMAGE_BINDING_ACCESS 0x8F3E
+#define GL_IMAGE_1D 0x904C
+#define GL_IMAGE_2D 0x904D
+#define GL_IMAGE_3D 0x904E
+#define GL_IMAGE_2D_RECT 0x904F
+#define GL_IMAGE_CUBE 0x9050
+#define GL_IMAGE_BUFFER 0x9051
+#define GL_IMAGE_1D_ARRAY 0x9052
+#define GL_IMAGE_2D_ARRAY 0x9053
+#define GL_IMAGE_CUBE_MAP_ARRAY 0x9054
+#define GL_IMAGE_2D_MULTISAMPLE 0x9055
+#define GL_IMAGE_2D_MULTISAMPLE_ARRAY 0x9056
+#define GL_INT_IMAGE_1D 0x9057
+#define GL_INT_IMAGE_2D 0x9058
+#define GL_INT_IMAGE_3D 0x9059
+#define GL_INT_IMAGE_2D_RECT 0x905A
+#define GL_INT_IMAGE_CUBE 0x905B
+#define GL_INT_IMAGE_BUFFER 0x905C
+#define GL_INT_IMAGE_1D_ARRAY 0x905D
+#define GL_INT_IMAGE_2D_ARRAY 0x905E
+#define GL_INT_IMAGE_CUBE_MAP_ARRAY 0x905F
+#define GL_INT_IMAGE_2D_MULTISAMPLE 0x9060
+#define GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY 0x9061
+#define GL_UNSIGNED_INT_IMAGE_1D 0x9062
+#define GL_UNSIGNED_INT_IMAGE_2D 0x9063
+#define GL_UNSIGNED_INT_IMAGE_3D 0x9064
+#define GL_UNSIGNED_INT_IMAGE_2D_RECT 0x9065
+#define GL_UNSIGNED_INT_IMAGE_CUBE 0x9066
+#define GL_UNSIGNED_INT_IMAGE_BUFFER 0x9067
+#define GL_UNSIGNED_INT_IMAGE_1D_ARRAY 0x9068
+#define GL_UNSIGNED_INT_IMAGE_2D_ARRAY 0x9069
+#define GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY 0x906A
+#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE 0x906B
+#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY 0x906C
+#define GL_MAX_IMAGE_SAMPLES 0x906D
+#define GL_IMAGE_BINDING_FORMAT 0x906E
+#define GL_IMAGE_FORMAT_COMPATIBILITY_TYPE 0x90C7
+#define GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE 0x90C8
+#define GL_IMAGE_FORMAT_COMPATIBILITY_BY_CLASS 0x90C9
+#define GL_MAX_VERTEX_IMAGE_UNIFORMS 0x90CA
+#define GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS 0x90CB
+#define GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS 0x90CC
+#define GL_MAX_GEOMETRY_IMAGE_UNIFORMS 0x90CD
+#define GL_MAX_FRAGMENT_IMAGE_UNIFORMS 0x90CE
+#define GL_MAX_COMBINED_IMAGE_UNIFORMS 0x90CF
+#endif
+
+#ifndef GL_ARB_shading_language_packing
+#endif
+
+#ifndef GL_ARB_texture_storage
+#define GL_TEXTURE_IMMUTABLE_FORMAT 0x912F
+#endif
+
+#ifndef GL_EXT_abgr
+#define GL_ABGR_EXT 0x8000
+#endif
+
+#ifndef GL_EXT_blend_color
+#define GL_CONSTANT_COLOR_EXT 0x8001
+#define GL_ONE_MINUS_CONSTANT_COLOR_EXT 0x8002
+#define GL_CONSTANT_ALPHA_EXT 0x8003
+#define GL_ONE_MINUS_CONSTANT_ALPHA_EXT 0x8004
+#define GL_BLEND_COLOR_EXT 0x8005
+#endif
+
+#ifndef GL_EXT_polygon_offset
+#define GL_POLYGON_OFFSET_EXT 0x8037
+#define GL_POLYGON_OFFSET_FACTOR_EXT 0x8038
+#define GL_POLYGON_OFFSET_BIAS_EXT 0x8039
+#endif
+
+#ifndef GL_EXT_texture
+#define GL_ALPHA4_EXT 0x803B
+#define GL_ALPHA8_EXT 0x803C
+#define GL_ALPHA12_EXT 0x803D
+#define GL_ALPHA16_EXT 0x803E
+#define GL_LUMINANCE4_EXT 0x803F
+#define GL_LUMINANCE8_EXT 0x8040
+#define GL_LUMINANCE12_EXT 0x8041
+#define GL_LUMINANCE16_EXT 0x8042
+#define GL_LUMINANCE4_ALPHA4_EXT 0x8043
+#define GL_LUMINANCE6_ALPHA2_EXT 0x8044
+#define GL_LUMINANCE8_ALPHA8_EXT 0x8045
+#define GL_LUMINANCE12_ALPHA4_EXT 0x8046
+#define GL_LUMINANCE12_ALPHA12_EXT 0x8047
+#define GL_LUMINANCE16_ALPHA16_EXT 0x8048
+#define GL_INTENSITY_EXT 0x8049
+#define GL_INTENSITY4_EXT 0x804A
+#define GL_INTENSITY8_EXT 0x804B
+#define GL_INTENSITY12_EXT 0x804C
+#define GL_INTENSITY16_EXT 0x804D
+#define GL_RGB2_EXT 0x804E
+#define GL_RGB4_EXT 0x804F
+#define GL_RGB5_EXT 0x8050
+#define GL_RGB8_EXT 0x8051
+#define GL_RGB10_EXT 0x8052
+#define GL_RGB12_EXT 0x8053
+#define GL_RGB16_EXT 0x8054
+#define GL_RGBA2_EXT 0x8055
+#define GL_RGBA4_EXT 0x8056
+#define GL_RGB5_A1_EXT 0x8057
+#define GL_RGBA8_EXT 0x8058
+#define GL_RGB10_A2_EXT 0x8059
+#define GL_RGBA12_EXT 0x805A
+#define GL_RGBA16_EXT 0x805B
+#define GL_TEXTURE_RED_SIZE_EXT 0x805C
+#define GL_TEXTURE_GREEN_SIZE_EXT 0x805D
+#define GL_TEXTURE_BLUE_SIZE_EXT 0x805E
+#define GL_TEXTURE_ALPHA_SIZE_EXT 0x805F
+#define GL_TEXTURE_LUMINANCE_SIZE_EXT 0x8060
+#define GL_TEXTURE_INTENSITY_SIZE_EXT 0x8061
+#define GL_REPLACE_EXT 0x8062
+#define GL_PROXY_TEXTURE_1D_EXT 0x8063
+#define GL_PROXY_TEXTURE_2D_EXT 0x8064
+#define GL_TEXTURE_TOO_LARGE_EXT 0x8065
+#endif
+
+#ifndef GL_EXT_texture3D
+#define GL_PACK_SKIP_IMAGES_EXT 0x806B
+#define GL_PACK_IMAGE_HEIGHT_EXT 0x806C
+#define GL_UNPACK_SKIP_IMAGES_EXT 0x806D
+#define GL_UNPACK_IMAGE_HEIGHT_EXT 0x806E
+#define GL_TEXTURE_3D_EXT 0x806F
+#define GL_PROXY_TEXTURE_3D_EXT 0x8070
+#define GL_TEXTURE_DEPTH_EXT 0x8071
+#define GL_TEXTURE_WRAP_R_EXT 0x8072
+#define GL_MAX_3D_TEXTURE_SIZE_EXT 0x8073
+#endif
+
+#ifndef GL_SGIS_texture_filter4
+#define GL_FILTER4_SGIS 0x8146
+#define GL_TEXTURE_FILTER4_SIZE_SGIS 0x8147
+#endif
+
+#ifndef GL_EXT_subtexture
+#endif
+
+#ifndef GL_EXT_copy_texture
+#endif
+
+#ifndef GL_EXT_histogram
+#define GL_HISTOGRAM_EXT 0x8024
+#define GL_PROXY_HISTOGRAM_EXT 0x8025
+#define GL_HISTOGRAM_WIDTH_EXT 0x8026
+#define GL_HISTOGRAM_FORMAT_EXT 0x8027
+#define GL_HISTOGRAM_RED_SIZE_EXT 0x8028
+#define GL_HISTOGRAM_GREEN_SIZE_EXT 0x8029
+#define GL_HISTOGRAM_BLUE_SIZE_EXT 0x802A
+#define GL_HISTOGRAM_ALPHA_SIZE_EXT 0x802B
+#define GL_HISTOGRAM_LUMINANCE_SIZE_EXT 0x802C
+#define GL_HISTOGRAM_SINK_EXT 0x802D
+#define GL_MINMAX_EXT 0x802E
+#define GL_MINMAX_FORMAT_EXT 0x802F
+#define GL_MINMAX_SINK_EXT 0x8030
+#define GL_TABLE_TOO_LARGE_EXT 0x8031
+#endif
+
+#ifndef GL_EXT_convolution
+#define GL_CONVOLUTION_1D_EXT 0x8010
+#define GL_CONVOLUTION_2D_EXT 0x8011
+#define GL_SEPARABLE_2D_EXT 0x8012
+#define GL_CONVOLUTION_BORDER_MODE_EXT 0x8013
+#define GL_CONVOLUTION_FILTER_SCALE_EXT 0x8014
+#define GL_CONVOLUTION_FILTER_BIAS_EXT 0x8015
+#define GL_REDUCE_EXT 0x8016
+#define GL_CONVOLUTION_FORMAT_EXT 0x8017
+#define GL_CONVOLUTION_WIDTH_EXT 0x8018
+#define GL_CONVOLUTION_HEIGHT_EXT 0x8019
+#define GL_MAX_CONVOLUTION_WIDTH_EXT 0x801A
+#define GL_MAX_CONVOLUTION_HEIGHT_EXT 0x801B
+#define GL_POST_CONVOLUTION_RED_SCALE_EXT 0x801C
+#define GL_POST_CONVOLUTION_GREEN_SCALE_EXT 0x801D
+#define GL_POST_CONVOLUTION_BLUE_SCALE_EXT 0x801E
+#define GL_POST_CONVOLUTION_ALPHA_SCALE_EXT 0x801F
+#define GL_POST_CONVOLUTION_RED_BIAS_EXT 0x8020
+#define GL_POST_CONVOLUTION_GREEN_BIAS_EXT 0x8021
+#define GL_POST_CONVOLUTION_BLUE_BIAS_EXT 0x8022
+#define GL_POST_CONVOLUTION_ALPHA_BIAS_EXT 0x8023
+#endif
+
+#ifndef GL_SGI_color_matrix
+#define GL_COLOR_MATRIX_SGI 0x80B1
+#define GL_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B2
+#define GL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B3
+#define GL_POST_COLOR_MATRIX_RED_SCALE_SGI 0x80B4
+#define GL_POST_COLOR_MATRIX_GREEN_SCALE_SGI 0x80B5
+#define GL_POST_COLOR_MATRIX_BLUE_SCALE_SGI 0x80B6
+#define GL_POST_COLOR_MATRIX_ALPHA_SCALE_SGI 0x80B7
+#define GL_POST_COLOR_MATRIX_RED_BIAS_SGI 0x80B8
+#define GL_POST_COLOR_MATRIX_GREEN_BIAS_SGI 0x80B9
+#define GL_POST_COLOR_MATRIX_BLUE_BIAS_SGI 0x80BA
+#define GL_POST_COLOR_MATRIX_ALPHA_BIAS_SGI 0x80BB
+#endif
+
+#ifndef GL_SGI_color_table
+#define GL_COLOR_TABLE_SGI 0x80D0
+#define GL_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D1
+#define GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D2
+#define GL_PROXY_COLOR_TABLE_SGI 0x80D3
+#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D4
+#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D5
+#define GL_COLOR_TABLE_SCALE_SGI 0x80D6
+#define GL_COLOR_TABLE_BIAS_SGI 0x80D7
+#define GL_COLOR_TABLE_FORMAT_SGI 0x80D8
+#define GL_COLOR_TABLE_WIDTH_SGI 0x80D9
+#define GL_COLOR_TABLE_RED_SIZE_SGI 0x80DA
+#define GL_COLOR_TABLE_GREEN_SIZE_SGI 0x80DB
+#define GL_COLOR_TABLE_BLUE_SIZE_SGI 0x80DC
+#define GL_COLOR_TABLE_ALPHA_SIZE_SGI 0x80DD
+#define GL_COLOR_TABLE_LUMINANCE_SIZE_SGI 0x80DE
+#define GL_COLOR_TABLE_INTENSITY_SIZE_SGI 0x80DF
+#endif
+
+#ifndef GL_SGIS_pixel_texture
+#define GL_PIXEL_TEXTURE_SGIS 0x8353
+#define GL_PIXEL_FRAGMENT_RGB_SOURCE_SGIS 0x8354
+#define GL_PIXEL_FRAGMENT_ALPHA_SOURCE_SGIS 0x8355
+#define GL_PIXEL_GROUP_COLOR_SGIS 0x8356
+#endif
+
+#ifndef GL_SGIX_pixel_texture
+#define GL_PIXEL_TEX_GEN_SGIX 0x8139
+#define GL_PIXEL_TEX_GEN_MODE_SGIX 0x832B
+#endif
+
+#ifndef GL_SGIS_texture4D
+#define GL_PACK_SKIP_VOLUMES_SGIS 0x8130
+#define GL_PACK_IMAGE_DEPTH_SGIS 0x8131
+#define GL_UNPACK_SKIP_VOLUMES_SGIS 0x8132
+#define GL_UNPACK_IMAGE_DEPTH_SGIS 0x8133
+#define GL_TEXTURE_4D_SGIS 0x8134
+#define GL_PROXY_TEXTURE_4D_SGIS 0x8135
+#define GL_TEXTURE_4DSIZE_SGIS 0x8136
+#define GL_TEXTURE_WRAP_Q_SGIS 0x8137
+#define GL_MAX_4D_TEXTURE_SIZE_SGIS 0x8138
+#define GL_TEXTURE_4D_BINDING_SGIS 0x814F
+#endif
+
+#ifndef GL_SGI_texture_color_table
+#define GL_TEXTURE_COLOR_TABLE_SGI 0x80BC
+#define GL_PROXY_TEXTURE_COLOR_TABLE_SGI 0x80BD
+#endif
+
+#ifndef GL_EXT_cmyka
+#define GL_CMYK_EXT 0x800C
+#define GL_CMYKA_EXT 0x800D
+#define GL_PACK_CMYK_HINT_EXT 0x800E
+#define GL_UNPACK_CMYK_HINT_EXT 0x800F
+#endif
+
+#ifndef GL_EXT_texture_object
+#define GL_TEXTURE_PRIORITY_EXT 0x8066
+#define GL_TEXTURE_RESIDENT_EXT 0x8067
+#define GL_TEXTURE_1D_BINDING_EXT 0x8068
+#define GL_TEXTURE_2D_BINDING_EXT 0x8069
+#define GL_TEXTURE_3D_BINDING_EXT 0x806A
+#endif
+
+#ifndef GL_SGIS_detail_texture
+#define GL_DETAIL_TEXTURE_2D_SGIS 0x8095
+#define GL_DETAIL_TEXTURE_2D_BINDING_SGIS 0x8096
+#define GL_LINEAR_DETAIL_SGIS 0x8097
+#define GL_LINEAR_DETAIL_ALPHA_SGIS 0x8098
+#define GL_LINEAR_DETAIL_COLOR_SGIS 0x8099
+#define GL_DETAIL_TEXTURE_LEVEL_SGIS 0x809A
+#define GL_DETAIL_TEXTURE_MODE_SGIS 0x809B
+#define GL_DETAIL_TEXTURE_FUNC_POINTS_SGIS 0x809C
+#endif
+
+#ifndef GL_SGIS_sharpen_texture
+#define GL_LINEAR_SHARPEN_SGIS 0x80AD
+#define GL_LINEAR_SHARPEN_ALPHA_SGIS 0x80AE
+#define GL_LINEAR_SHARPEN_COLOR_SGIS 0x80AF
+#define GL_SHARPEN_TEXTURE_FUNC_POINTS_SGIS 0x80B0
+#endif
+
+#ifndef GL_EXT_packed_pixels
+#define GL_UNSIGNED_BYTE_3_3_2_EXT 0x8032
+#define GL_UNSIGNED_SHORT_4_4_4_4_EXT 0x8033
+#define GL_UNSIGNED_SHORT_5_5_5_1_EXT 0x8034
+#define GL_UNSIGNED_INT_8_8_8_8_EXT 0x8035
+#define GL_UNSIGNED_INT_10_10_10_2_EXT 0x8036
+#endif
+
+#ifndef GL_SGIS_texture_lod
+#define GL_TEXTURE_MIN_LOD_SGIS 0x813A
+#define GL_TEXTURE_MAX_LOD_SGIS 0x813B
+#define GL_TEXTURE_BASE_LEVEL_SGIS 0x813C
+#define GL_TEXTURE_MAX_LEVEL_SGIS 0x813D
+#endif
+
+#ifndef GL_SGIS_multisample
+#define GL_MULTISAMPLE_SGIS 0x809D
+#define GL_SAMPLE_ALPHA_TO_MASK_SGIS 0x809E
+#define GL_SAMPLE_ALPHA_TO_ONE_SGIS 0x809F
+#define GL_SAMPLE_MASK_SGIS 0x80A0
+#define GL_1PASS_SGIS 0x80A1
+#define GL_2PASS_0_SGIS 0x80A2
+#define GL_2PASS_1_SGIS 0x80A3
+#define GL_4PASS_0_SGIS 0x80A4
+#define GL_4PASS_1_SGIS 0x80A5
+#define GL_4PASS_2_SGIS 0x80A6
+#define GL_4PASS_3_SGIS 0x80A7
+#define GL_SAMPLE_BUFFERS_SGIS 0x80A8
+#define GL_SAMPLES_SGIS 0x80A9
+#define GL_SAMPLE_MASK_VALUE_SGIS 0x80AA
+#define GL_SAMPLE_MASK_INVERT_SGIS 0x80AB
+#define GL_SAMPLE_PATTERN_SGIS 0x80AC
+#endif
+
+#ifndef GL_EXT_rescale_normal
+#define GL_RESCALE_NORMAL_EXT 0x803A
+#endif
+
+#ifndef GL_EXT_vertex_array
+#define GL_VERTEX_ARRAY_EXT 0x8074
+#define GL_NORMAL_ARRAY_EXT 0x8075
+#define GL_COLOR_ARRAY_EXT 0x8076
+#define GL_INDEX_ARRAY_EXT 0x8077
+#define GL_TEXTURE_COORD_ARRAY_EXT 0x8078
+#define GL_EDGE_FLAG_ARRAY_EXT 0x8079
+#define GL_VERTEX_ARRAY_SIZE_EXT 0x807A
+#define GL_VERTEX_ARRAY_TYPE_EXT 0x807B
+#define GL_VERTEX_ARRAY_STRIDE_EXT 0x807C
+#define GL_VERTEX_ARRAY_COUNT_EXT 0x807D
+#define GL_NORMAL_ARRAY_TYPE_EXT 0x807E
+#define GL_NORMAL_ARRAY_STRIDE_EXT 0x807F
+#define GL_NORMAL_ARRAY_COUNT_EXT 0x8080
+#define GL_COLOR_ARRAY_SIZE_EXT 0x8081
+#define GL_COLOR_ARRAY_TYPE_EXT 0x8082
+#define GL_COLOR_ARRAY_STRIDE_EXT 0x8083
+#define GL_COLOR_ARRAY_COUNT_EXT 0x8084
+#define GL_INDEX_ARRAY_TYPE_EXT 0x8085
+#define GL_INDEX_ARRAY_STRIDE_EXT 0x8086
+#define GL_INDEX_ARRAY_COUNT_EXT 0x8087
+#define GL_TEXTURE_COORD_ARRAY_SIZE_EXT 0x8088
+#define GL_TEXTURE_COORD_ARRAY_TYPE_EXT 0x8089
+#define GL_TEXTURE_COORD_ARRAY_STRIDE_EXT 0x808A
+#define GL_TEXTURE_COORD_ARRAY_COUNT_EXT 0x808B
+#define GL_EDGE_FLAG_ARRAY_STRIDE_EXT 0x808C
+#define GL_EDGE_FLAG_ARRAY_COUNT_EXT 0x808D
+#define GL_VERTEX_ARRAY_POINTER_EXT 0x808E
+#define GL_NORMAL_ARRAY_POINTER_EXT 0x808F
+#define GL_COLOR_ARRAY_POINTER_EXT 0x8090
+#define GL_INDEX_ARRAY_POINTER_EXT 0x8091
+#define GL_TEXTURE_COORD_ARRAY_POINTER_EXT 0x8092
+#define GL_EDGE_FLAG_ARRAY_POINTER_EXT 0x8093
+#endif
+
+#ifndef GL_EXT_misc_attribute
+#endif
+
+#ifndef GL_SGIS_generate_mipmap
+#define GL_GENERATE_MIPMAP_SGIS 0x8191
+#define GL_GENERATE_MIPMAP_HINT_SGIS 0x8192
+#endif
+
+#ifndef GL_SGIX_clipmap
+#define GL_LINEAR_CLIPMAP_LINEAR_SGIX 0x8170
+#define GL_TEXTURE_CLIPMAP_CENTER_SGIX 0x8171
+#define GL_TEXTURE_CLIPMAP_FRAME_SGIX 0x8172
+#define GL_TEXTURE_CLIPMAP_OFFSET_SGIX 0x8173
+#define GL_TEXTURE_CLIPMAP_VIRTUAL_DEPTH_SGIX 0x8174
+#define GL_TEXTURE_CLIPMAP_LOD_OFFSET_SGIX 0x8175
+#define GL_TEXTURE_CLIPMAP_DEPTH_SGIX 0x8176
+#define GL_MAX_CLIPMAP_DEPTH_SGIX 0x8177
+#define GL_MAX_CLIPMAP_VIRTUAL_DEPTH_SGIX 0x8178
+#define GL_NEAREST_CLIPMAP_NEAREST_SGIX 0x844D
+#define GL_NEAREST_CLIPMAP_LINEAR_SGIX 0x844E
+#define GL_LINEAR_CLIPMAP_NEAREST_SGIX 0x844F
+#endif
+
+#ifndef GL_SGIX_shadow
+#define GL_TEXTURE_COMPARE_SGIX 0x819A
+#define GL_TEXTURE_COMPARE_OPERATOR_SGIX 0x819B
+#define GL_TEXTURE_LEQUAL_R_SGIX 0x819C
+#define GL_TEXTURE_GEQUAL_R_SGIX 0x819D
+#endif
+
+#ifndef GL_SGIS_texture_edge_clamp
+#define GL_CLAMP_TO_EDGE_SGIS 0x812F
+#endif
+
+#ifndef GL_SGIS_texture_border_clamp
+#define GL_CLAMP_TO_BORDER_SGIS 0x812D
+#endif
+
+#ifndef GL_EXT_blend_minmax
+#define GL_FUNC_ADD_EXT 0x8006
+#define GL_MIN_EXT 0x8007
+#define GL_MAX_EXT 0x8008
+#define GL_BLEND_EQUATION_EXT 0x8009
+#endif
+
+#ifndef GL_EXT_blend_subtract
+#define GL_FUNC_SUBTRACT_EXT 0x800A
+#define GL_FUNC_REVERSE_SUBTRACT_EXT 0x800B
+#endif
+
+#ifndef GL_EXT_blend_logic_op
+#endif
+
+#ifndef GL_SGIX_interlace
+#define GL_INTERLACE_SGIX 0x8094
+#endif
+
+#ifndef GL_SGIX_pixel_tiles
+#define GL_PIXEL_TILE_BEST_ALIGNMENT_SGIX 0x813E
+#define GL_PIXEL_TILE_CACHE_INCREMENT_SGIX 0x813F
+#define GL_PIXEL_TILE_WIDTH_SGIX 0x8140
+#define GL_PIXEL_TILE_HEIGHT_SGIX 0x8141
+#define GL_PIXEL_TILE_GRID_WIDTH_SGIX 0x8142
+#define GL_PIXEL_TILE_GRID_HEIGHT_SGIX 0x8143
+#define GL_PIXEL_TILE_GRID_DEPTH_SGIX 0x8144
+#define GL_PIXEL_TILE_CACHE_SIZE_SGIX 0x8145
+#endif
+
+#ifndef GL_SGIS_texture_select
+#define GL_DUAL_ALPHA4_SGIS 0x8110
+#define GL_DUAL_ALPHA8_SGIS 0x8111
+#define GL_DUAL_ALPHA12_SGIS 0x8112
+#define GL_DUAL_ALPHA16_SGIS 0x8113
+#define GL_DUAL_LUMINANCE4_SGIS 0x8114
+#define GL_DUAL_LUMINANCE8_SGIS 0x8115
+#define GL_DUAL_LUMINANCE12_SGIS 0x8116
+#define GL_DUAL_LUMINANCE16_SGIS 0x8117
+#define GL_DUAL_INTENSITY4_SGIS 0x8118
+#define GL_DUAL_INTENSITY8_SGIS 0x8119
+#define GL_DUAL_INTENSITY12_SGIS 0x811A
+#define GL_DUAL_INTENSITY16_SGIS 0x811B
+#define GL_DUAL_LUMINANCE_ALPHA4_SGIS 0x811C
+#define GL_DUAL_LUMINANCE_ALPHA8_SGIS 0x811D
+#define GL_QUAD_ALPHA4_SGIS 0x811E
+#define GL_QUAD_ALPHA8_SGIS 0x811F
+#define GL_QUAD_LUMINANCE4_SGIS 0x8120
+#define GL_QUAD_LUMINANCE8_SGIS 0x8121
+#define GL_QUAD_INTENSITY4_SGIS 0x8122
+#define GL_QUAD_INTENSITY8_SGIS 0x8123
+#define GL_DUAL_TEXTURE_SELECT_SGIS 0x8124
+#define GL_QUAD_TEXTURE_SELECT_SGIS 0x8125
+#endif
+
+#ifndef GL_SGIX_sprite
+#define GL_SPRITE_SGIX 0x8148
+#define GL_SPRITE_MODE_SGIX 0x8149
+#define GL_SPRITE_AXIS_SGIX 0x814A
+#define GL_SPRITE_TRANSLATION_SGIX 0x814B
+#define GL_SPRITE_AXIAL_SGIX 0x814C
+#define GL_SPRITE_OBJECT_ALIGNED_SGIX 0x814D
+#define GL_SPRITE_EYE_ALIGNED_SGIX 0x814E
+#endif
+
+#ifndef GL_SGIX_texture_multi_buffer
+#define GL_TEXTURE_MULTI_BUFFER_HINT_SGIX 0x812E
+#endif
+
+#ifndef GL_EXT_point_parameters
+#define GL_POINT_SIZE_MIN_EXT 0x8126
+#define GL_POINT_SIZE_MAX_EXT 0x8127
+#define GL_POINT_FADE_THRESHOLD_SIZE_EXT 0x8128
+#define GL_DISTANCE_ATTENUATION_EXT 0x8129
+#endif
+
+#ifndef GL_SGIS_point_parameters
+#define GL_POINT_SIZE_MIN_SGIS 0x8126
+#define GL_POINT_SIZE_MAX_SGIS 0x8127
+#define GL_POINT_FADE_THRESHOLD_SIZE_SGIS 0x8128
+#define GL_DISTANCE_ATTENUATION_SGIS 0x8129
+#endif
+
+#ifndef GL_SGIX_instruments
+#define GL_INSTRUMENT_BUFFER_POINTER_SGIX 0x8180
+#define GL_INSTRUMENT_MEASUREMENTS_SGIX 0x8181
+#endif
+
+#ifndef GL_SGIX_texture_scale_bias
+#define GL_POST_TEXTURE_FILTER_BIAS_SGIX 0x8179
+#define GL_POST_TEXTURE_FILTER_SCALE_SGIX 0x817A
+#define GL_POST_TEXTURE_FILTER_BIAS_RANGE_SGIX 0x817B
+#define GL_POST_TEXTURE_FILTER_SCALE_RANGE_SGIX 0x817C
+#endif
+
+#ifndef GL_SGIX_framezoom
+#define GL_FRAMEZOOM_SGIX 0x818B
+#define GL_FRAMEZOOM_FACTOR_SGIX 0x818C
+#define GL_MAX_FRAMEZOOM_FACTOR_SGIX 0x818D
+#endif
+
+#ifndef GL_SGIX_tag_sample_buffer
+#endif
+
+#ifndef GL_FfdMaskSGIX
+#define GL_TEXTURE_DEFORMATION_BIT_SGIX 0x00000001
+#define GL_GEOMETRY_DEFORMATION_BIT_SGIX 0x00000002
+#endif
+
+#ifndef GL_SGIX_polynomial_ffd
+#define GL_GEOMETRY_DEFORMATION_SGIX 0x8194
+#define GL_TEXTURE_DEFORMATION_SGIX 0x8195
+#define GL_DEFORMATIONS_MASK_SGIX 0x8196
+#define GL_MAX_DEFORMATION_ORDER_SGIX 0x8197
+#endif
+
+#ifndef GL_SGIX_reference_plane
+#define GL_REFERENCE_PLANE_SGIX 0x817D
+#define GL_REFERENCE_PLANE_EQUATION_SGIX 0x817E
+#endif
+
+#ifndef GL_SGIX_flush_raster
+#endif
+
+#ifndef GL_SGIX_depth_texture
+#define GL_DEPTH_COMPONENT16_SGIX 0x81A5
+#define GL_DEPTH_COMPONENT24_SGIX 0x81A6
+#define GL_DEPTH_COMPONENT32_SGIX 0x81A7
+#endif
+
+#ifndef GL_SGIS_fog_function
+#define GL_FOG_FUNC_SGIS 0x812A
+#define GL_FOG_FUNC_POINTS_SGIS 0x812B
+#define GL_MAX_FOG_FUNC_POINTS_SGIS 0x812C
+#endif
+
+#ifndef GL_SGIX_fog_offset
+#define GL_FOG_OFFSET_SGIX 0x8198
+#define GL_FOG_OFFSET_VALUE_SGIX 0x8199
+#endif
+
+#ifndef GL_HP_image_transform
+#define GL_IMAGE_SCALE_X_HP 0x8155
+#define GL_IMAGE_SCALE_Y_HP 0x8156
+#define GL_IMAGE_TRANSLATE_X_HP 0x8157
+#define GL_IMAGE_TRANSLATE_Y_HP 0x8158
+#define GL_IMAGE_ROTATE_ANGLE_HP 0x8159
+#define GL_IMAGE_ROTATE_ORIGIN_X_HP 0x815A
+#define GL_IMAGE_ROTATE_ORIGIN_Y_HP 0x815B
+#define GL_IMAGE_MAG_FILTER_HP 0x815C
+#define GL_IMAGE_MIN_FILTER_HP 0x815D
+#define GL_IMAGE_CUBIC_WEIGHT_HP 0x815E
+#define GL_CUBIC_HP 0x815F
+#define GL_AVERAGE_HP 0x8160
+#define GL_IMAGE_TRANSFORM_2D_HP 0x8161
+#define GL_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP 0x8162
+#define GL_PROXY_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP 0x8163
+#endif
+
+#ifndef GL_HP_convolution_border_modes
+#define GL_IGNORE_BORDER_HP 0x8150
+#define GL_CONSTANT_BORDER_HP 0x8151
+#define GL_REPLICATE_BORDER_HP 0x8153
+#define GL_CONVOLUTION_BORDER_COLOR_HP 0x8154
+#endif
+
+#ifndef GL_INGR_palette_buffer
+#endif
+
+#ifndef GL_SGIX_texture_add_env
+#define GL_TEXTURE_ENV_BIAS_SGIX 0x80BE
+#endif
+
+#ifndef GL_EXT_color_subtable
+#endif
+
+#ifndef GL_PGI_vertex_hints
+#define GL_VERTEX_DATA_HINT_PGI 0x1A22A
+#define GL_VERTEX_CONSISTENT_HINT_PGI 0x1A22B
+#define GL_MATERIAL_SIDE_HINT_PGI 0x1A22C
+#define GL_MAX_VERTEX_HINT_PGI 0x1A22D
+#define GL_COLOR3_BIT_PGI 0x00010000
+#define GL_COLOR4_BIT_PGI 0x00020000
+#define GL_EDGEFLAG_BIT_PGI 0x00040000
+#define GL_INDEX_BIT_PGI 0x00080000
+#define GL_MAT_AMBIENT_BIT_PGI 0x00100000
+#define GL_MAT_AMBIENT_AND_DIFFUSE_BIT_PGI 0x00200000
+#define GL_MAT_DIFFUSE_BIT_PGI 0x00400000
+#define GL_MAT_EMISSION_BIT_PGI 0x00800000
+#define GL_MAT_COLOR_INDEXES_BIT_PGI 0x01000000
+#define GL_MAT_SHININESS_BIT_PGI 0x02000000
+#define GL_MAT_SPECULAR_BIT_PGI 0x04000000
+#define GL_NORMAL_BIT_PGI 0x08000000
+#define GL_TEXCOORD1_BIT_PGI 0x10000000
+#define GL_TEXCOORD2_BIT_PGI 0x20000000
+#define GL_TEXCOORD3_BIT_PGI 0x40000000
+#define GL_TEXCOORD4_BIT_PGI 0x80000000
+#define GL_VERTEX23_BIT_PGI 0x00000004
+#define GL_VERTEX4_BIT_PGI 0x00000008
+#endif
+
+#ifndef GL_PGI_misc_hints
+#define GL_PREFER_DOUBLEBUFFER_HINT_PGI 0x1A1F8
+#define GL_CONSERVE_MEMORY_HINT_PGI 0x1A1FD
+#define GL_RECLAIM_MEMORY_HINT_PGI 0x1A1FE
+#define GL_NATIVE_GRAPHICS_HANDLE_PGI 0x1A202
+#define GL_NATIVE_GRAPHICS_BEGIN_HINT_PGI 0x1A203
+#define GL_NATIVE_GRAPHICS_END_HINT_PGI 0x1A204
+#define GL_ALWAYS_FAST_HINT_PGI 0x1A20C
+#define GL_ALWAYS_SOFT_HINT_PGI 0x1A20D
+#define GL_ALLOW_DRAW_OBJ_HINT_PGI 0x1A20E
+#define GL_ALLOW_DRAW_WIN_HINT_PGI 0x1A20F
+#define GL_ALLOW_DRAW_FRG_HINT_PGI 0x1A210
+#define GL_ALLOW_DRAW_MEM_HINT_PGI 0x1A211
+#define GL_STRICT_DEPTHFUNC_HINT_PGI 0x1A216
+#define GL_STRICT_LIGHTING_HINT_PGI 0x1A217
+#define GL_STRICT_SCISSOR_HINT_PGI 0x1A218
+#define GL_FULL_STIPPLE_HINT_PGI 0x1A219
+#define GL_CLIP_NEAR_HINT_PGI 0x1A220
+#define GL_CLIP_FAR_HINT_PGI 0x1A221
+#define GL_WIDE_LINE_HINT_PGI 0x1A222
+#define GL_BACK_NORMALS_HINT_PGI 0x1A223
+#endif
+
+#ifndef GL_EXT_paletted_texture
+#define GL_COLOR_INDEX1_EXT 0x80E2
+#define GL_COLOR_INDEX2_EXT 0x80E3
+#define GL_COLOR_INDEX4_EXT 0x80E4
+#define GL_COLOR_INDEX8_EXT 0x80E5
+#define GL_COLOR_INDEX12_EXT 0x80E6
+#define GL_COLOR_INDEX16_EXT 0x80E7
+#define GL_TEXTURE_INDEX_SIZE_EXT 0x80ED
+#endif
+
+#ifndef GL_EXT_clip_volume_hint
+#define GL_CLIP_VOLUME_CLIPPING_HINT_EXT 0x80F0
+#endif
+
+#ifndef GL_SGIX_list_priority
+#define GL_LIST_PRIORITY_SGIX 0x8182
+#endif
+
+#ifndef GL_SGIX_ir_instrument1
+#define GL_IR_INSTRUMENT1_SGIX 0x817F
+#endif
+
+#ifndef GL_SGIX_calligraphic_fragment
+#define GL_CALLIGRAPHIC_FRAGMENT_SGIX 0x8183
+#endif
+
+#ifndef GL_SGIX_texture_lod_bias
+#define GL_TEXTURE_LOD_BIAS_S_SGIX 0x818E
+#define GL_TEXTURE_LOD_BIAS_T_SGIX 0x818F
+#define GL_TEXTURE_LOD_BIAS_R_SGIX 0x8190
+#endif
+
+#ifndef GL_SGIX_shadow_ambient
+#define GL_SHADOW_AMBIENT_SGIX 0x80BF
+#endif
+
+#ifndef GL_EXT_index_texture
+#endif
+
+#ifndef GL_EXT_index_material
+#define GL_INDEX_MATERIAL_EXT 0x81B8
+#define GL_INDEX_MATERIAL_PARAMETER_EXT 0x81B9
+#define GL_INDEX_MATERIAL_FACE_EXT 0x81BA
+#endif
+
+#ifndef GL_EXT_index_func
+#define GL_INDEX_TEST_EXT 0x81B5
+#define GL_INDEX_TEST_FUNC_EXT 0x81B6
+#define GL_INDEX_TEST_REF_EXT 0x81B7
+#endif
+
+#ifndef GL_EXT_index_array_formats
+#define GL_IUI_V2F_EXT 0x81AD
+#define GL_IUI_V3F_EXT 0x81AE
+#define GL_IUI_N3F_V2F_EXT 0x81AF
+#define GL_IUI_N3F_V3F_EXT 0x81B0
+#define GL_T2F_IUI_V2F_EXT 0x81B1
+#define GL_T2F_IUI_V3F_EXT 0x81B2
+#define GL_T2F_IUI_N3F_V2F_EXT 0x81B3
+#define GL_T2F_IUI_N3F_V3F_EXT 0x81B4
+#endif
+
+#ifndef GL_EXT_compiled_vertex_array
+#define GL_ARRAY_ELEMENT_LOCK_FIRST_EXT 0x81A8
+#define GL_ARRAY_ELEMENT_LOCK_COUNT_EXT 0x81A9
+#endif
+
+#ifndef GL_EXT_cull_vertex
+#define GL_CULL_VERTEX_EXT 0x81AA
+#define GL_CULL_VERTEX_EYE_POSITION_EXT 0x81AB
+#define GL_CULL_VERTEX_OBJECT_POSITION_EXT 0x81AC
+#endif
+
+#ifndef GL_SGIX_ycrcb
+#define GL_YCRCB_422_SGIX 0x81BB
+#define GL_YCRCB_444_SGIX 0x81BC
+#endif
+
+#ifndef GL_SGIX_fragment_lighting
+#define GL_FRAGMENT_LIGHTING_SGIX 0x8400
+#define GL_FRAGMENT_COLOR_MATERIAL_SGIX 0x8401
+#define GL_FRAGMENT_COLOR_MATERIAL_FACE_SGIX 0x8402
+#define GL_FRAGMENT_COLOR_MATERIAL_PARAMETER_SGIX 0x8403
+#define GL_MAX_FRAGMENT_LIGHTS_SGIX 0x8404
+#define GL_MAX_ACTIVE_LIGHTS_SGIX 0x8405
+#define GL_CURRENT_RASTER_NORMAL_SGIX 0x8406
+#define GL_LIGHT_ENV_MODE_SGIX 0x8407
+#define GL_FRAGMENT_LIGHT_MODEL_LOCAL_VIEWER_SGIX 0x8408
+#define GL_FRAGMENT_LIGHT_MODEL_TWO_SIDE_SGIX 0x8409
+#define GL_FRAGMENT_LIGHT_MODEL_AMBIENT_SGIX 0x840A
+#define GL_FRAGMENT_LIGHT_MODEL_NORMAL_INTERPOLATION_SGIX 0x840B
+#define GL_FRAGMENT_LIGHT0_SGIX 0x840C
+#define GL_FRAGMENT_LIGHT1_SGIX 0x840D
+#define GL_FRAGMENT_LIGHT2_SGIX 0x840E
+#define GL_FRAGMENT_LIGHT3_SGIX 0x840F
+#define GL_FRAGMENT_LIGHT4_SGIX 0x8410
+#define GL_FRAGMENT_LIGHT5_SGIX 0x8411
+#define GL_FRAGMENT_LIGHT6_SGIX 0x8412
+#define GL_FRAGMENT_LIGHT7_SGIX 0x8413
+#endif
+
+#ifndef GL_IBM_rasterpos_clip
+#define GL_RASTER_POSITION_UNCLIPPED_IBM 0x19262
+#endif
+
+#ifndef GL_HP_texture_lighting
+#define GL_TEXTURE_LIGHTING_MODE_HP 0x8167
+#define GL_TEXTURE_POST_SPECULAR_HP 0x8168
+#define GL_TEXTURE_PRE_SPECULAR_HP 0x8169
+#endif
+
+#ifndef GL_EXT_draw_range_elements
+#define GL_MAX_ELEMENTS_VERTICES_EXT 0x80E8
+#define GL_MAX_ELEMENTS_INDICES_EXT 0x80E9
+#endif
+
+#ifndef GL_WIN_phong_shading
+#define GL_PHONG_WIN 0x80EA
+#define GL_PHONG_HINT_WIN 0x80EB
+#endif
+
+#ifndef GL_WIN_specular_fog
+#define GL_FOG_SPECULAR_TEXTURE_WIN 0x80EC
+#endif
+
+#ifndef GL_EXT_light_texture
+#define GL_FRAGMENT_MATERIAL_EXT 0x8349
+#define GL_FRAGMENT_NORMAL_EXT 0x834A
+#define GL_FRAGMENT_COLOR_EXT 0x834C
+#define GL_ATTENUATION_EXT 0x834D
+#define GL_SHADOW_ATTENUATION_EXT 0x834E
+#define GL_TEXTURE_APPLICATION_MODE_EXT 0x834F
+#define GL_TEXTURE_LIGHT_EXT 0x8350
+#define GL_TEXTURE_MATERIAL_FACE_EXT 0x8351
+#define GL_TEXTURE_MATERIAL_PARAMETER_EXT 0x8352
+/* reuse GL_FRAGMENT_DEPTH_EXT */
+#endif
+
+#ifndef GL_SGIX_blend_alpha_minmax
+#define GL_ALPHA_MIN_SGIX 0x8320
+#define GL_ALPHA_MAX_SGIX 0x8321
+#endif
+
+#ifndef GL_SGIX_impact_pixel_texture
+#define GL_PIXEL_TEX_GEN_Q_CEILING_SGIX 0x8184
+#define GL_PIXEL_TEX_GEN_Q_ROUND_SGIX 0x8185
+#define GL_PIXEL_TEX_GEN_Q_FLOOR_SGIX 0x8186
+#define GL_PIXEL_TEX_GEN_ALPHA_REPLACE_SGIX 0x8187
+#define GL_PIXEL_TEX_GEN_ALPHA_NO_REPLACE_SGIX 0x8188
+#define GL_PIXEL_TEX_GEN_ALPHA_LS_SGIX 0x8189
+#define GL_PIXEL_TEX_GEN_ALPHA_MS_SGIX 0x818A
+#endif
+
+#ifndef GL_EXT_bgra
+#define GL_BGR_EXT 0x80E0
+#define GL_BGRA_EXT 0x80E1
+#endif
+
+#ifndef GL_SGIX_async
+#define GL_ASYNC_MARKER_SGIX 0x8329
+#endif
+
+#ifndef GL_SGIX_async_pixel
+#define GL_ASYNC_TEX_IMAGE_SGIX 0x835C
+#define GL_ASYNC_DRAW_PIXELS_SGIX 0x835D
+#define GL_ASYNC_READ_PIXELS_SGIX 0x835E
+#define GL_MAX_ASYNC_TEX_IMAGE_SGIX 0x835F
+#define GL_MAX_ASYNC_DRAW_PIXELS_SGIX 0x8360
+#define GL_MAX_ASYNC_READ_PIXELS_SGIX 0x8361
+#endif
+
+#ifndef GL_SGIX_async_histogram
+#define GL_ASYNC_HISTOGRAM_SGIX 0x832C
+#define GL_MAX_ASYNC_HISTOGRAM_SGIX 0x832D
+#endif
+
+#ifndef GL_INTEL_texture_scissor
+#endif
+
+#ifndef GL_INTEL_parallel_arrays
+#define GL_PARALLEL_ARRAYS_INTEL 0x83F4
+#define GL_VERTEX_ARRAY_PARALLEL_POINTERS_INTEL 0x83F5
+#define GL_NORMAL_ARRAY_PARALLEL_POINTERS_INTEL 0x83F6
+#define GL_COLOR_ARRAY_PARALLEL_POINTERS_INTEL 0x83F7
+#define GL_TEXTURE_COORD_ARRAY_PARALLEL_POINTERS_INTEL 0x83F8
+#endif
+
+#ifndef GL_HP_occlusion_test
+#define GL_OCCLUSION_TEST_HP 0x8165
+#define GL_OCCLUSION_TEST_RESULT_HP 0x8166
+#endif
+
+#ifndef GL_EXT_pixel_transform
+#define GL_PIXEL_TRANSFORM_2D_EXT 0x8330
+#define GL_PIXEL_MAG_FILTER_EXT 0x8331
+#define GL_PIXEL_MIN_FILTER_EXT 0x8332
+#define GL_PIXEL_CUBIC_WEIGHT_EXT 0x8333
+#define GL_CUBIC_EXT 0x8334
+#define GL_AVERAGE_EXT 0x8335
+#define GL_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8336
+#define GL_MAX_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8337
+#define GL_PIXEL_TRANSFORM_2D_MATRIX_EXT 0x8338
+#endif
+
+#ifndef GL_EXT_pixel_transform_color_table
+#endif
+
+#ifndef GL_EXT_shared_texture_palette
+#define GL_SHARED_TEXTURE_PALETTE_EXT 0x81FB
+#endif
+
+#ifndef GL_EXT_separate_specular_color
+#define GL_LIGHT_MODEL_COLOR_CONTROL_EXT 0x81F8
+#define GL_SINGLE_COLOR_EXT 0x81F9
+#define GL_SEPARATE_SPECULAR_COLOR_EXT 0x81FA
+#endif
+
+#ifndef GL_EXT_secondary_color
+#define GL_COLOR_SUM_EXT 0x8458
+#define GL_CURRENT_SECONDARY_COLOR_EXT 0x8459
+#define GL_SECONDARY_COLOR_ARRAY_SIZE_EXT 0x845A
+#define GL_SECONDARY_COLOR_ARRAY_TYPE_EXT 0x845B
+#define GL_SECONDARY_COLOR_ARRAY_STRIDE_EXT 0x845C
+#define GL_SECONDARY_COLOR_ARRAY_POINTER_EXT 0x845D
+#define GL_SECONDARY_COLOR_ARRAY_EXT 0x845E
+#endif
+
+#ifndef GL_EXT_texture_perturb_normal
+#define GL_PERTURB_EXT 0x85AE
+#define GL_TEXTURE_NORMAL_EXT 0x85AF
+#endif
+
+#ifndef GL_EXT_multi_draw_arrays
+#endif
+
+#ifndef GL_EXT_fog_coord
+#define GL_FOG_COORDINATE_SOURCE_EXT 0x8450
+#define GL_FOG_COORDINATE_EXT 0x8451
+#define GL_FRAGMENT_DEPTH_EXT 0x8452
+#define GL_CURRENT_FOG_COORDINATE_EXT 0x8453
+#define GL_FOG_COORDINATE_ARRAY_TYPE_EXT 0x8454
+#define GL_FOG_COORDINATE_ARRAY_STRIDE_EXT 0x8455
+#define GL_FOG_COORDINATE_ARRAY_POINTER_EXT 0x8456
+#define GL_FOG_COORDINATE_ARRAY_EXT 0x8457
+#endif
+
+#ifndef GL_REND_screen_coordinates
+#define GL_SCREEN_COORDINATES_REND 0x8490
+#define GL_INVERTED_SCREEN_W_REND 0x8491
+#endif
+
+#ifndef GL_EXT_coordinate_frame
+#define GL_TANGENT_ARRAY_EXT 0x8439
+#define GL_BINORMAL_ARRAY_EXT 0x843A
+#define GL_CURRENT_TANGENT_EXT 0x843B
+#define GL_CURRENT_BINORMAL_EXT 0x843C
+#define GL_TANGENT_ARRAY_TYPE_EXT 0x843E
+#define GL_TANGENT_ARRAY_STRIDE_EXT 0x843F
+#define GL_BINORMAL_ARRAY_TYPE_EXT 0x8440
+#define GL_BINORMAL_ARRAY_STRIDE_EXT 0x8441
+#define GL_TANGENT_ARRAY_POINTER_EXT 0x8442
+#define GL_BINORMAL_ARRAY_POINTER_EXT 0x8443
+#define GL_MAP1_TANGENT_EXT 0x8444
+#define GL_MAP2_TANGENT_EXT 0x8445
+#define GL_MAP1_BINORMAL_EXT 0x8446
+#define GL_MAP2_BINORMAL_EXT 0x8447
+#endif
+
+#ifndef GL_EXT_texture_env_combine
+#define GL_COMBINE_EXT 0x8570
+#define GL_COMBINE_RGB_EXT 0x8571
+#define GL_COMBINE_ALPHA_EXT 0x8572
+#define GL_RGB_SCALE_EXT 0x8573
+#define GL_ADD_SIGNED_EXT 0x8574
+#define GL_INTERPOLATE_EXT 0x8575
+#define GL_CONSTANT_EXT 0x8576
+#define GL_PRIMARY_COLOR_EXT 0x8577
+#define GL_PREVIOUS_EXT 0x8578
+#define GL_SOURCE0_RGB_EXT 0x8580
+#define GL_SOURCE1_RGB_EXT 0x8581
+#define GL_SOURCE2_RGB_EXT 0x8582
+#define GL_SOURCE0_ALPHA_EXT 0x8588
+#define GL_SOURCE1_ALPHA_EXT 0x8589
+#define GL_SOURCE2_ALPHA_EXT 0x858A
+#define GL_OPERAND0_RGB_EXT 0x8590
+#define GL_OPERAND1_RGB_EXT 0x8591
+#define GL_OPERAND2_RGB_EXT 0x8592
+#define GL_OPERAND0_ALPHA_EXT 0x8598
+#define GL_OPERAND1_ALPHA_EXT 0x8599
+#define GL_OPERAND2_ALPHA_EXT 0x859A
+#endif
+
+#ifndef GL_APPLE_specular_vector
+#define GL_LIGHT_MODEL_SPECULAR_VECTOR_APPLE 0x85B0
+#endif
+
+#ifndef GL_APPLE_transform_hint
+#define GL_TRANSFORM_HINT_APPLE 0x85B1
+#endif
+
+#ifndef GL_SGIX_fog_scale
+#define GL_FOG_SCALE_SGIX 0x81FC
+#define GL_FOG_SCALE_VALUE_SGIX 0x81FD
+#endif
+
+#ifndef GL_SUNX_constant_data
+#define GL_UNPACK_CONSTANT_DATA_SUNX 0x81D5
+#define GL_TEXTURE_CONSTANT_DATA_SUNX 0x81D6
+#endif
+
+#ifndef GL_SUN_global_alpha
+#define GL_GLOBAL_ALPHA_SUN 0x81D9
+#define GL_GLOBAL_ALPHA_FACTOR_SUN 0x81DA
+#endif
+
+#ifndef GL_SUN_triangle_list
+#define GL_RESTART_SUN 0x0001
+#define GL_REPLACE_MIDDLE_SUN 0x0002
+#define GL_REPLACE_OLDEST_SUN 0x0003
+#define GL_TRIANGLE_LIST_SUN 0x81D7
+#define GL_REPLACEMENT_CODE_SUN 0x81D8
+#define GL_REPLACEMENT_CODE_ARRAY_SUN 0x85C0
+#define GL_REPLACEMENT_CODE_ARRAY_TYPE_SUN 0x85C1
+#define GL_REPLACEMENT_CODE_ARRAY_STRIDE_SUN 0x85C2
+#define GL_REPLACEMENT_CODE_ARRAY_POINTER_SUN 0x85C3
+#define GL_R1UI_V3F_SUN 0x85C4
+#define GL_R1UI_C4UB_V3F_SUN 0x85C5
+#define GL_R1UI_C3F_V3F_SUN 0x85C6
+#define GL_R1UI_N3F_V3F_SUN 0x85C7
+#define GL_R1UI_C4F_N3F_V3F_SUN 0x85C8
+#define GL_R1UI_T2F_V3F_SUN 0x85C9
+#define GL_R1UI_T2F_N3F_V3F_SUN 0x85CA
+#define GL_R1UI_T2F_C4F_N3F_V3F_SUN 0x85CB
+#endif
+
+#ifndef GL_SUN_vertex
+#endif
+
+#ifndef GL_EXT_blend_func_separate
+#define GL_BLEND_DST_RGB_EXT 0x80C8
+#define GL_BLEND_SRC_RGB_EXT 0x80C9
+#define GL_BLEND_DST_ALPHA_EXT 0x80CA
+#define GL_BLEND_SRC_ALPHA_EXT 0x80CB
+#endif
+
+#ifndef GL_INGR_color_clamp
+#define GL_RED_MIN_CLAMP_INGR 0x8560
+#define GL_GREEN_MIN_CLAMP_INGR 0x8561
+#define GL_BLUE_MIN_CLAMP_INGR 0x8562
+#define GL_ALPHA_MIN_CLAMP_INGR 0x8563
+#define GL_RED_MAX_CLAMP_INGR 0x8564
+#define GL_GREEN_MAX_CLAMP_INGR 0x8565
+#define GL_BLUE_MAX_CLAMP_INGR 0x8566
+#define GL_ALPHA_MAX_CLAMP_INGR 0x8567
+#endif
+
+#ifndef GL_INGR_interlace_read
+#define GL_INTERLACE_READ_INGR 0x8568
+#endif
+
+#ifndef GL_EXT_stencil_wrap
+#define GL_INCR_WRAP_EXT 0x8507
+#define GL_DECR_WRAP_EXT 0x8508
+#endif
+
+#ifndef GL_EXT_422_pixels
+#define GL_422_EXT 0x80CC
+#define GL_422_REV_EXT 0x80CD
+#define GL_422_AVERAGE_EXT 0x80CE
+#define GL_422_REV_AVERAGE_EXT 0x80CF
+#endif
+
+#ifndef GL_NV_texgen_reflection
+#define GL_NORMAL_MAP_NV 0x8511
+#define GL_REFLECTION_MAP_NV 0x8512
+#endif
+
+#ifndef GL_EXT_texture_cube_map
+#define GL_NORMAL_MAP_EXT 0x8511
+#define GL_REFLECTION_MAP_EXT 0x8512
+#define GL_TEXTURE_CUBE_MAP_EXT 0x8513
+#define GL_TEXTURE_BINDING_CUBE_MAP_EXT 0x8514
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT 0x8515
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_EXT 0x8516
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_EXT 0x8517
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT 0x8518
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_EXT 0x8519
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT 0x851A
+#define GL_PROXY_TEXTURE_CUBE_MAP_EXT 0x851B
+#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_EXT 0x851C
+#endif
+
+#ifndef GL_SUN_convolution_border_modes
+#define GL_WRAP_BORDER_SUN 0x81D4
+#endif
+
+#ifndef GL_EXT_texture_env_add
+#endif
+
+#ifndef GL_EXT_texture_lod_bias
+#define GL_MAX_TEXTURE_LOD_BIAS_EXT 0x84FD
+#define GL_TEXTURE_FILTER_CONTROL_EXT 0x8500
+#define GL_TEXTURE_LOD_BIAS_EXT 0x8501
+#endif
+
+#ifndef GL_EXT_texture_filter_anisotropic
+#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE
+#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF
+#endif
+
+#ifndef GL_EXT_vertex_weighting
+#define GL_MODELVIEW0_STACK_DEPTH_EXT GL_MODELVIEW_STACK_DEPTH
+#define GL_MODELVIEW1_STACK_DEPTH_EXT 0x8502
+#define GL_MODELVIEW0_MATRIX_EXT GL_MODELVIEW_MATRIX
+#define GL_MODELVIEW1_MATRIX_EXT 0x8506
+#define GL_VERTEX_WEIGHTING_EXT 0x8509
+#define GL_MODELVIEW0_EXT GL_MODELVIEW
+#define GL_MODELVIEW1_EXT 0x850A
+#define GL_CURRENT_VERTEX_WEIGHT_EXT 0x850B
+#define GL_VERTEX_WEIGHT_ARRAY_EXT 0x850C
+#define GL_VERTEX_WEIGHT_ARRAY_SIZE_EXT 0x850D
+#define GL_VERTEX_WEIGHT_ARRAY_TYPE_EXT 0x850E
+#define GL_VERTEX_WEIGHT_ARRAY_STRIDE_EXT 0x850F
+#define GL_VERTEX_WEIGHT_ARRAY_POINTER_EXT 0x8510
+#endif
+
+#ifndef GL_NV_light_max_exponent
+#define GL_MAX_SHININESS_NV 0x8504
+#define GL_MAX_SPOT_EXPONENT_NV 0x8505
+#endif
+
+#ifndef GL_NV_vertex_array_range
+#define GL_VERTEX_ARRAY_RANGE_NV 0x851D
+#define GL_VERTEX_ARRAY_RANGE_LENGTH_NV 0x851E
+#define GL_VERTEX_ARRAY_RANGE_VALID_NV 0x851F
+#define GL_MAX_VERTEX_ARRAY_RANGE_ELEMENT_NV 0x8520
+#define GL_VERTEX_ARRAY_RANGE_POINTER_NV 0x8521
+#endif
+
+#ifndef GL_NV_register_combiners
+#define GL_REGISTER_COMBINERS_NV 0x8522
+#define GL_VARIABLE_A_NV 0x8523
+#define GL_VARIABLE_B_NV 0x8524
+#define GL_VARIABLE_C_NV 0x8525
+#define GL_VARIABLE_D_NV 0x8526
+#define GL_VARIABLE_E_NV 0x8527
+#define GL_VARIABLE_F_NV 0x8528
+#define GL_VARIABLE_G_NV 0x8529
+#define GL_CONSTANT_COLOR0_NV 0x852A
+#define GL_CONSTANT_COLOR1_NV 0x852B
+#define GL_PRIMARY_COLOR_NV 0x852C
+#define GL_SECONDARY_COLOR_NV 0x852D
+#define GL_SPARE0_NV 0x852E
+#define GL_SPARE1_NV 0x852F
+#define GL_DISCARD_NV 0x8530
+#define GL_E_TIMES_F_NV 0x8531
+#define GL_SPARE0_PLUS_SECONDARY_COLOR_NV 0x8532
+#define GL_UNSIGNED_IDENTITY_NV 0x8536
+#define GL_UNSIGNED_INVERT_NV 0x8537
+#define GL_EXPAND_NORMAL_NV 0x8538
+#define GL_EXPAND_NEGATE_NV 0x8539
+#define GL_HALF_BIAS_NORMAL_NV 0x853A
+#define GL_HALF_BIAS_NEGATE_NV 0x853B
+#define GL_SIGNED_IDENTITY_NV 0x853C
+#define GL_SIGNED_NEGATE_NV 0x853D
+#define GL_SCALE_BY_TWO_NV 0x853E
+#define GL_SCALE_BY_FOUR_NV 0x853F
+#define GL_SCALE_BY_ONE_HALF_NV 0x8540
+#define GL_BIAS_BY_NEGATIVE_ONE_HALF_NV 0x8541
+#define GL_COMBINER_INPUT_NV 0x8542
+#define GL_COMBINER_MAPPING_NV 0x8543
+#define GL_COMBINER_COMPONENT_USAGE_NV 0x8544
+#define GL_COMBINER_AB_DOT_PRODUCT_NV 0x8545
+#define GL_COMBINER_CD_DOT_PRODUCT_NV 0x8546
+#define GL_COMBINER_MUX_SUM_NV 0x8547
+#define GL_COMBINER_SCALE_NV 0x8548
+#define GL_COMBINER_BIAS_NV 0x8549
+#define GL_COMBINER_AB_OUTPUT_NV 0x854A
+#define GL_COMBINER_CD_OUTPUT_NV 0x854B
+#define GL_COMBINER_SUM_OUTPUT_NV 0x854C
+#define GL_MAX_GENERAL_COMBINERS_NV 0x854D
+#define GL_NUM_GENERAL_COMBINERS_NV 0x854E
+#define GL_COLOR_SUM_CLAMP_NV 0x854F
+#define GL_COMBINER0_NV 0x8550
+#define GL_COMBINER1_NV 0x8551
+#define GL_COMBINER2_NV 0x8552
+#define GL_COMBINER3_NV 0x8553
+#define GL_COMBINER4_NV 0x8554
+#define GL_COMBINER5_NV 0x8555
+#define GL_COMBINER6_NV 0x8556
+#define GL_COMBINER7_NV 0x8557
+/* reuse GL_TEXTURE0_ARB */
+/* reuse GL_TEXTURE1_ARB */
+/* reuse GL_ZERO */
+/* reuse GL_NONE */
+/* reuse GL_FOG */
+#endif
+
+#ifndef GL_NV_fog_distance
+#define GL_FOG_DISTANCE_MODE_NV 0x855A
+#define GL_EYE_RADIAL_NV 0x855B
+#define GL_EYE_PLANE_ABSOLUTE_NV 0x855C
+/* reuse GL_EYE_PLANE */
+#endif
+
+#ifndef GL_NV_texgen_emboss
+#define GL_EMBOSS_LIGHT_NV 0x855D
+#define GL_EMBOSS_CONSTANT_NV 0x855E
+#define GL_EMBOSS_MAP_NV 0x855F
+#endif
+
+#ifndef GL_NV_blend_square
+#endif
+
+#ifndef GL_NV_texture_env_combine4
+#define GL_COMBINE4_NV 0x8503
+#define GL_SOURCE3_RGB_NV 0x8583
+#define GL_SOURCE3_ALPHA_NV 0x858B
+#define GL_OPERAND3_RGB_NV 0x8593
+#define GL_OPERAND3_ALPHA_NV 0x859B
+#endif
+
+#ifndef GL_MESA_resize_buffers
+#endif
+
+#ifndef GL_MESA_window_pos
+#endif
+
+#ifndef GL_EXT_texture_compression_s3tc
+#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0
+#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1
+#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2
+#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3
+#endif
+
+#ifndef GL_IBM_cull_vertex
+#define GL_CULL_VERTEX_IBM 103050
+#endif
+
+#ifndef GL_IBM_multimode_draw_arrays
+#endif
+
+#ifndef GL_IBM_vertex_array_lists
+#define GL_VERTEX_ARRAY_LIST_IBM 103070
+#define GL_NORMAL_ARRAY_LIST_IBM 103071
+#define GL_COLOR_ARRAY_LIST_IBM 103072
+#define GL_INDEX_ARRAY_LIST_IBM 103073
+#define GL_TEXTURE_COORD_ARRAY_LIST_IBM 103074
+#define GL_EDGE_FLAG_ARRAY_LIST_IBM 103075
+#define GL_FOG_COORDINATE_ARRAY_LIST_IBM 103076
+#define GL_SECONDARY_COLOR_ARRAY_LIST_IBM 103077
+#define GL_VERTEX_ARRAY_LIST_STRIDE_IBM 103080
+#define GL_NORMAL_ARRAY_LIST_STRIDE_IBM 103081
+#define GL_COLOR_ARRAY_LIST_STRIDE_IBM 103082
+#define GL_INDEX_ARRAY_LIST_STRIDE_IBM 103083
+#define GL_TEXTURE_COORD_ARRAY_LIST_STRIDE_IBM 103084
+#define GL_EDGE_FLAG_ARRAY_LIST_STRIDE_IBM 103085
+#define GL_FOG_COORDINATE_ARRAY_LIST_STRIDE_IBM 103086
+#define GL_SECONDARY_COLOR_ARRAY_LIST_STRIDE_IBM 103087
+#endif
+
+#ifndef GL_SGIX_subsample
+#define GL_PACK_SUBSAMPLE_RATE_SGIX 0x85A0
+#define GL_UNPACK_SUBSAMPLE_RATE_SGIX 0x85A1
+#define GL_PIXEL_SUBSAMPLE_4444_SGIX 0x85A2
+#define GL_PIXEL_SUBSAMPLE_2424_SGIX 0x85A3
+#define GL_PIXEL_SUBSAMPLE_4242_SGIX 0x85A4
+#endif
+
+#ifndef GL_SGIX_ycrcb_subsample
+#endif
+
+#ifndef GL_SGIX_ycrcba
+#define GL_YCRCB_SGIX 0x8318
+#define GL_YCRCBA_SGIX 0x8319
+#endif
+
+#ifndef GL_SGI_depth_pass_instrument
+#define GL_DEPTH_PASS_INSTRUMENT_SGIX 0x8310
+#define GL_DEPTH_PASS_INSTRUMENT_COUNTERS_SGIX 0x8311
+#define GL_DEPTH_PASS_INSTRUMENT_MAX_SGIX 0x8312
+#endif
+
+#ifndef GL_3DFX_texture_compression_FXT1
+#define GL_COMPRESSED_RGB_FXT1_3DFX 0x86B0
+#define GL_COMPRESSED_RGBA_FXT1_3DFX 0x86B1
+#endif
+
+#ifndef GL_3DFX_multisample
+#define GL_MULTISAMPLE_3DFX 0x86B2
+#define GL_SAMPLE_BUFFERS_3DFX 0x86B3
+#define GL_SAMPLES_3DFX 0x86B4
+#define GL_MULTISAMPLE_BIT_3DFX 0x20000000
+#endif
+
+#ifndef GL_3DFX_tbuffer
+#endif
+
+#ifndef GL_EXT_multisample
+#define GL_MULTISAMPLE_EXT 0x809D
+#define GL_SAMPLE_ALPHA_TO_MASK_EXT 0x809E
+#define GL_SAMPLE_ALPHA_TO_ONE_EXT 0x809F
+#define GL_SAMPLE_MASK_EXT 0x80A0
+#define GL_1PASS_EXT 0x80A1
+#define GL_2PASS_0_EXT 0x80A2
+#define GL_2PASS_1_EXT 0x80A3
+#define GL_4PASS_0_EXT 0x80A4
+#define GL_4PASS_1_EXT 0x80A5
+#define GL_4PASS_2_EXT 0x80A6
+#define GL_4PASS_3_EXT 0x80A7
+#define GL_SAMPLE_BUFFERS_EXT 0x80A8
+#define GL_SAMPLES_EXT 0x80A9
+#define GL_SAMPLE_MASK_VALUE_EXT 0x80AA
+#define GL_SAMPLE_MASK_INVERT_EXT 0x80AB
+#define GL_SAMPLE_PATTERN_EXT 0x80AC
+#define GL_MULTISAMPLE_BIT_EXT 0x20000000
+#endif
+
+#ifndef GL_SGIX_vertex_preclip
+#define GL_VERTEX_PRECLIP_SGIX 0x83EE
+#define GL_VERTEX_PRECLIP_HINT_SGIX 0x83EF
+#endif
+
+#ifndef GL_SGIX_convolution_accuracy
+#define GL_CONVOLUTION_HINT_SGIX 0x8316
+#endif
+
+#ifndef GL_SGIX_resample
+#define GL_PACK_RESAMPLE_SGIX 0x842C
+#define GL_UNPACK_RESAMPLE_SGIX 0x842D
+#define GL_RESAMPLE_REPLICATE_SGIX 0x842E
+#define GL_RESAMPLE_ZERO_FILL_SGIX 0x842F
+#define GL_RESAMPLE_DECIMATE_SGIX 0x8430
+#endif
+
+#ifndef GL_SGIS_point_line_texgen
+#define GL_EYE_DISTANCE_TO_POINT_SGIS 0x81F0
+#define GL_OBJECT_DISTANCE_TO_POINT_SGIS 0x81F1
+#define GL_EYE_DISTANCE_TO_LINE_SGIS 0x81F2
+#define GL_OBJECT_DISTANCE_TO_LINE_SGIS 0x81F3
+#define GL_EYE_POINT_SGIS 0x81F4
+#define GL_OBJECT_POINT_SGIS 0x81F5
+#define GL_EYE_LINE_SGIS 0x81F6
+#define GL_OBJECT_LINE_SGIS 0x81F7
+#endif
+
+#ifndef GL_SGIS_texture_color_mask
+#define GL_TEXTURE_COLOR_WRITEMASK_SGIS 0x81EF
+#endif
+
+#ifndef GL_EXT_texture_env_dot3
+#define GL_DOT3_RGB_EXT 0x8740
+#define GL_DOT3_RGBA_EXT 0x8741
+#endif
+
+#ifndef GL_ATI_texture_mirror_once
+#define GL_MIRROR_CLAMP_ATI 0x8742
+#define GL_MIRROR_CLAMP_TO_EDGE_ATI 0x8743
+#endif
+
+#ifndef GL_NV_fence
+#define GL_ALL_COMPLETED_NV 0x84F2
+#define GL_FENCE_STATUS_NV 0x84F3
+#define GL_FENCE_CONDITION_NV 0x84F4
+#endif
+
+#ifndef GL_IBM_texture_mirrored_repeat
+#define GL_MIRRORED_REPEAT_IBM 0x8370
+#endif
+
+#ifndef GL_NV_evaluators
+#define GL_EVAL_2D_NV 0x86C0
+#define GL_EVAL_TRIANGULAR_2D_NV 0x86C1
+#define GL_MAP_TESSELLATION_NV 0x86C2
+#define GL_MAP_ATTRIB_U_ORDER_NV 0x86C3
+#define GL_MAP_ATTRIB_V_ORDER_NV 0x86C4
+#define GL_EVAL_FRACTIONAL_TESSELLATION_NV 0x86C5
+#define GL_EVAL_VERTEX_ATTRIB0_NV 0x86C6
+#define GL_EVAL_VERTEX_ATTRIB1_NV 0x86C7
+#define GL_EVAL_VERTEX_ATTRIB2_NV 0x86C8
+#define GL_EVAL_VERTEX_ATTRIB3_NV 0x86C9
+#define GL_EVAL_VERTEX_ATTRIB4_NV 0x86CA
+#define GL_EVAL_VERTEX_ATTRIB5_NV 0x86CB
+#define GL_EVAL_VERTEX_ATTRIB6_NV 0x86CC
+#define GL_EVAL_VERTEX_ATTRIB7_NV 0x86CD
+#define GL_EVAL_VERTEX_ATTRIB8_NV 0x86CE
+#define GL_EVAL_VERTEX_ATTRIB9_NV 0x86CF
+#define GL_EVAL_VERTEX_ATTRIB10_NV 0x86D0
+#define GL_EVAL_VERTEX_ATTRIB11_NV 0x86D1
+#define GL_EVAL_VERTEX_ATTRIB12_NV 0x86D2
+#define GL_EVAL_VERTEX_ATTRIB13_NV 0x86D3
+#define GL_EVAL_VERTEX_ATTRIB14_NV 0x86D4
+#define GL_EVAL_VERTEX_ATTRIB15_NV 0x86D5
+#define GL_MAX_MAP_TESSELLATION_NV 0x86D6
+#define GL_MAX_RATIONAL_EVAL_ORDER_NV 0x86D7
+#endif
+
+#ifndef GL_NV_packed_depth_stencil
+#define GL_DEPTH_STENCIL_NV 0x84F9
+#define GL_UNSIGNED_INT_24_8_NV 0x84FA
+#endif
+
+#ifndef GL_NV_register_combiners2
+#define GL_PER_STAGE_CONSTANTS_NV 0x8535
+#endif
+
+#ifndef GL_NV_texture_compression_vtc
+#endif
+
+#ifndef GL_NV_texture_rectangle
+#define GL_TEXTURE_RECTANGLE_NV 0x84F5
+#define GL_TEXTURE_BINDING_RECTANGLE_NV 0x84F6
+#define GL_PROXY_TEXTURE_RECTANGLE_NV 0x84F7
+#define GL_MAX_RECTANGLE_TEXTURE_SIZE_NV 0x84F8
+#endif
+
+#ifndef GL_NV_texture_shader
+#define GL_OFFSET_TEXTURE_RECTANGLE_NV 0x864C
+#define GL_OFFSET_TEXTURE_RECTANGLE_SCALE_NV 0x864D
+#define GL_DOT_PRODUCT_TEXTURE_RECTANGLE_NV 0x864E
+#define GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV 0x86D9
+#define GL_UNSIGNED_INT_S8_S8_8_8_NV 0x86DA
+#define GL_UNSIGNED_INT_8_8_S8_S8_REV_NV 0x86DB
+#define GL_DSDT_MAG_INTENSITY_NV 0x86DC
+#define GL_SHADER_CONSISTENT_NV 0x86DD
+#define GL_TEXTURE_SHADER_NV 0x86DE
+#define GL_SHADER_OPERATION_NV 0x86DF
+#define GL_CULL_MODES_NV 0x86E0
+#define GL_OFFSET_TEXTURE_MATRIX_NV 0x86E1
+#define GL_OFFSET_TEXTURE_SCALE_NV 0x86E2
+#define GL_OFFSET_TEXTURE_BIAS_NV 0x86E3
+#define GL_OFFSET_TEXTURE_2D_MATRIX_NV GL_OFFSET_TEXTURE_MATRIX_NV
+#define GL_OFFSET_TEXTURE_2D_SCALE_NV GL_OFFSET_TEXTURE_SCALE_NV
+#define GL_OFFSET_TEXTURE_2D_BIAS_NV GL_OFFSET_TEXTURE_BIAS_NV
+#define GL_PREVIOUS_TEXTURE_INPUT_NV 0x86E4
+#define GL_CONST_EYE_NV 0x86E5
+#define GL_PASS_THROUGH_NV 0x86E6
+#define GL_CULL_FRAGMENT_NV 0x86E7
+#define GL_OFFSET_TEXTURE_2D_NV 0x86E8
+#define GL_DEPENDENT_AR_TEXTURE_2D_NV 0x86E9
+#define GL_DEPENDENT_GB_TEXTURE_2D_NV 0x86EA
+#define GL_DOT_PRODUCT_NV 0x86EC
+#define GL_DOT_PRODUCT_DEPTH_REPLACE_NV 0x86ED
+#define GL_DOT_PRODUCT_TEXTURE_2D_NV 0x86EE
+#define GL_DOT_PRODUCT_TEXTURE_CUBE_MAP_NV 0x86F0
+#define GL_DOT_PRODUCT_DIFFUSE_CUBE_MAP_NV 0x86F1
+#define GL_DOT_PRODUCT_REFLECT_CUBE_MAP_NV 0x86F2
+#define GL_DOT_PRODUCT_CONST_EYE_REFLECT_CUBE_MAP_NV 0x86F3
+#define GL_HILO_NV 0x86F4
+#define GL_DSDT_NV 0x86F5
+#define GL_DSDT_MAG_NV 0x86F6
+#define GL_DSDT_MAG_VIB_NV 0x86F7
+#define GL_HILO16_NV 0x86F8
+#define GL_SIGNED_HILO_NV 0x86F9
+#define GL_SIGNED_HILO16_NV 0x86FA
+#define GL_SIGNED_RGBA_NV 0x86FB
+#define GL_SIGNED_RGBA8_NV 0x86FC
+#define GL_SIGNED_RGB_NV 0x86FE
+#define GL_SIGNED_RGB8_NV 0x86FF
+#define GL_SIGNED_LUMINANCE_NV 0x8701
+#define GL_SIGNED_LUMINANCE8_NV 0x8702
+#define GL_SIGNED_LUMINANCE_ALPHA_NV 0x8703
+#define GL_SIGNED_LUMINANCE8_ALPHA8_NV 0x8704
+#define GL_SIGNED_ALPHA_NV 0x8705
+#define GL_SIGNED_ALPHA8_NV 0x8706
+#define GL_SIGNED_INTENSITY_NV 0x8707
+#define GL_SIGNED_INTENSITY8_NV 0x8708
+#define GL_DSDT8_NV 0x8709
+#define GL_DSDT8_MAG8_NV 0x870A
+#define GL_DSDT8_MAG8_INTENSITY8_NV 0x870B
+#define GL_SIGNED_RGB_UNSIGNED_ALPHA_NV 0x870C
+#define GL_SIGNED_RGB8_UNSIGNED_ALPHA8_NV 0x870D
+#define GL_HI_SCALE_NV 0x870E
+#define GL_LO_SCALE_NV 0x870F
+#define GL_DS_SCALE_NV 0x8710
+#define GL_DT_SCALE_NV 0x8711
+#define GL_MAGNITUDE_SCALE_NV 0x8712
+#define GL_VIBRANCE_SCALE_NV 0x8713
+#define GL_HI_BIAS_NV 0x8714
+#define GL_LO_BIAS_NV 0x8715
+#define GL_DS_BIAS_NV 0x8716
+#define GL_DT_BIAS_NV 0x8717
+#define GL_MAGNITUDE_BIAS_NV 0x8718
+#define GL_VIBRANCE_BIAS_NV 0x8719
+#define GL_TEXTURE_BORDER_VALUES_NV 0x871A
+#define GL_TEXTURE_HI_SIZE_NV 0x871B
+#define GL_TEXTURE_LO_SIZE_NV 0x871C
+#define GL_TEXTURE_DS_SIZE_NV 0x871D
+#define GL_TEXTURE_DT_SIZE_NV 0x871E
+#define GL_TEXTURE_MAG_SIZE_NV 0x871F
+#endif
+
+#ifndef GL_NV_texture_shader2
+#define GL_DOT_PRODUCT_TEXTURE_3D_NV 0x86EF
+#endif
+
+#ifndef GL_NV_vertex_array_range2
+#define GL_VERTEX_ARRAY_RANGE_WITHOUT_FLUSH_NV 0x8533
+#endif
+
+#ifndef GL_NV_vertex_program
+#define GL_VERTEX_PROGRAM_NV 0x8620
+#define GL_VERTEX_STATE_PROGRAM_NV 0x8621
+#define GL_ATTRIB_ARRAY_SIZE_NV 0x8623
+#define GL_ATTRIB_ARRAY_STRIDE_NV 0x8624
+#define GL_ATTRIB_ARRAY_TYPE_NV 0x8625
+#define GL_CURRENT_ATTRIB_NV 0x8626
+#define GL_PROGRAM_LENGTH_NV 0x8627
+#define GL_PROGRAM_STRING_NV 0x8628
+#define GL_MODELVIEW_PROJECTION_NV 0x8629
+#define GL_IDENTITY_NV 0x862A
+#define GL_INVERSE_NV 0x862B
+#define GL_TRANSPOSE_NV 0x862C
+#define GL_INVERSE_TRANSPOSE_NV 0x862D
+#define GL_MAX_TRACK_MATRIX_STACK_DEPTH_NV 0x862E
+#define GL_MAX_TRACK_MATRICES_NV 0x862F
+#define GL_MATRIX0_NV 0x8630
+#define GL_MATRIX1_NV 0x8631
+#define GL_MATRIX2_NV 0x8632
+#define GL_MATRIX3_NV 0x8633
+#define GL_MATRIX4_NV 0x8634
+#define GL_MATRIX5_NV 0x8635
+#define GL_MATRIX6_NV 0x8636
+#define GL_MATRIX7_NV 0x8637
+#define GL_CURRENT_MATRIX_STACK_DEPTH_NV 0x8640
+#define GL_CURRENT_MATRIX_NV 0x8641
+#define GL_VERTEX_PROGRAM_POINT_SIZE_NV 0x8642
+#define GL_VERTEX_PROGRAM_TWO_SIDE_NV 0x8643
+#define GL_PROGRAM_PARAMETER_NV 0x8644
+#define GL_ATTRIB_ARRAY_POINTER_NV 0x8645
+#define GL_PROGRAM_TARGET_NV 0x8646
+#define GL_PROGRAM_RESIDENT_NV 0x8647
+#define GL_TRACK_MATRIX_NV 0x8648
+#define GL_TRACK_MATRIX_TRANSFORM_NV 0x8649
+#define GL_VERTEX_PROGRAM_BINDING_NV 0x864A
+#define GL_PROGRAM_ERROR_POSITION_NV 0x864B
+#define GL_VERTEX_ATTRIB_ARRAY0_NV 0x8650
+#define GL_VERTEX_ATTRIB_ARRAY1_NV 0x8651
+#define GL_VERTEX_ATTRIB_ARRAY2_NV 0x8652
+#define GL_VERTEX_ATTRIB_ARRAY3_NV 0x8653
+#define GL_VERTEX_ATTRIB_ARRAY4_NV 0x8654
+#define GL_VERTEX_ATTRIB_ARRAY5_NV 0x8655
+#define GL_VERTEX_ATTRIB_ARRAY6_NV 0x8656
+#define GL_VERTEX_ATTRIB_ARRAY7_NV 0x8657
+#define GL_VERTEX_ATTRIB_ARRAY8_NV 0x8658
+#define GL_VERTEX_ATTRIB_ARRAY9_NV 0x8659
+#define GL_VERTEX_ATTRIB_ARRAY10_NV 0x865A
+#define GL_VERTEX_ATTRIB_ARRAY11_NV 0x865B
+#define GL_VERTEX_ATTRIB_ARRAY12_NV 0x865C
+#define GL_VERTEX_ATTRIB_ARRAY13_NV 0x865D
+#define GL_VERTEX_ATTRIB_ARRAY14_NV 0x865E
+#define GL_VERTEX_ATTRIB_ARRAY15_NV 0x865F
+#define GL_MAP1_VERTEX_ATTRIB0_4_NV 0x8660
+#define GL_MAP1_VERTEX_ATTRIB1_4_NV 0x8661
+#define GL_MAP1_VERTEX_ATTRIB2_4_NV 0x8662
+#define GL_MAP1_VERTEX_ATTRIB3_4_NV 0x8663
+#define GL_MAP1_VERTEX_ATTRIB4_4_NV 0x8664
+#define GL_MAP1_VERTEX_ATTRIB5_4_NV 0x8665
+#define GL_MAP1_VERTEX_ATTRIB6_4_NV 0x8666
+#define GL_MAP1_VERTEX_ATTRIB7_4_NV 0x8667
+#define GL_MAP1_VERTEX_ATTRIB8_4_NV 0x8668
+#define GL_MAP1_VERTEX_ATTRIB9_4_NV 0x8669
+#define GL_MAP1_VERTEX_ATTRIB10_4_NV 0x866A
+#define GL_MAP1_VERTEX_ATTRIB11_4_NV 0x866B
+#define GL_MAP1_VERTEX_ATTRIB12_4_NV 0x866C
+#define GL_MAP1_VERTEX_ATTRIB13_4_NV 0x866D
+#define GL_MAP1_VERTEX_ATTRIB14_4_NV 0x866E
+#define GL_MAP1_VERTEX_ATTRIB15_4_NV 0x866F
+#define GL_MAP2_VERTEX_ATTRIB0_4_NV 0x8670
+#define GL_MAP2_VERTEX_ATTRIB1_4_NV 0x8671
+#define GL_MAP2_VERTEX_ATTRIB2_4_NV 0x8672
+#define GL_MAP2_VERTEX_ATTRIB3_4_NV 0x8673
+#define GL_MAP2_VERTEX_ATTRIB4_4_NV 0x8674
+#define GL_MAP2_VERTEX_ATTRIB5_4_NV 0x8675
+#define GL_MAP2_VERTEX_ATTRIB6_4_NV 0x8676
+#define GL_MAP2_VERTEX_ATTRIB7_4_NV 0x8677
+#define GL_MAP2_VERTEX_ATTRIB8_4_NV 0x8678
+#define GL_MAP2_VERTEX_ATTRIB9_4_NV 0x8679
+#define GL_MAP2_VERTEX_ATTRIB10_4_NV 0x867A
+#define GL_MAP2_VERTEX_ATTRIB11_4_NV 0x867B
+#define GL_MAP2_VERTEX_ATTRIB12_4_NV 0x867C
+#define GL_MAP2_VERTEX_ATTRIB13_4_NV 0x867D
+#define GL_MAP2_VERTEX_ATTRIB14_4_NV 0x867E
+#define GL_MAP2_VERTEX_ATTRIB15_4_NV 0x867F
+#endif
+
+#ifndef GL_SGIX_texture_coordinate_clamp
+#define GL_TEXTURE_MAX_CLAMP_S_SGIX 0x8369
+#define GL_TEXTURE_MAX_CLAMP_T_SGIX 0x836A
+#define GL_TEXTURE_MAX_CLAMP_R_SGIX 0x836B
+#endif
+
+#ifndef GL_SGIX_scalebias_hint
+#define GL_SCALEBIAS_HINT_SGIX 0x8322
+#endif
+
+#ifndef GL_OML_interlace
+#define GL_INTERLACE_OML 0x8980
+#define GL_INTERLACE_READ_OML 0x8981
+#endif
+
+#ifndef GL_OML_subsample
+#define GL_FORMAT_SUBSAMPLE_24_24_OML 0x8982
+#define GL_FORMAT_SUBSAMPLE_244_244_OML 0x8983
+#endif
+
+#ifndef GL_OML_resample
+#define GL_PACK_RESAMPLE_OML 0x8984
+#define GL_UNPACK_RESAMPLE_OML 0x8985
+#define GL_RESAMPLE_REPLICATE_OML 0x8986
+#define GL_RESAMPLE_ZERO_FILL_OML 0x8987
+#define GL_RESAMPLE_AVERAGE_OML 0x8988
+#define GL_RESAMPLE_DECIMATE_OML 0x8989
+#endif
+
+#ifndef GL_NV_copy_depth_to_color
+#define GL_DEPTH_STENCIL_TO_RGBA_NV 0x886E
+#define GL_DEPTH_STENCIL_TO_BGRA_NV 0x886F
+#endif
+
+#ifndef GL_ATI_envmap_bumpmap
+#define GL_BUMP_ROT_MATRIX_ATI 0x8775
+#define GL_BUMP_ROT_MATRIX_SIZE_ATI 0x8776
+#define GL_BUMP_NUM_TEX_UNITS_ATI 0x8777
+#define GL_BUMP_TEX_UNITS_ATI 0x8778
+#define GL_DUDV_ATI 0x8779
+#define GL_DU8DV8_ATI 0x877A
+#define GL_BUMP_ENVMAP_ATI 0x877B
+#define GL_BUMP_TARGET_ATI 0x877C
+#endif
+
+#ifndef GL_ATI_fragment_shader
+#define GL_FRAGMENT_SHADER_ATI 0x8920
+#define GL_REG_0_ATI 0x8921
+#define GL_REG_1_ATI 0x8922
+#define GL_REG_2_ATI 0x8923
+#define GL_REG_3_ATI 0x8924
+#define GL_REG_4_ATI 0x8925
+#define GL_REG_5_ATI 0x8926
+#define GL_REG_6_ATI 0x8927
+#define GL_REG_7_ATI 0x8928
+#define GL_REG_8_ATI 0x8929
+#define GL_REG_9_ATI 0x892A
+#define GL_REG_10_ATI 0x892B
+#define GL_REG_11_ATI 0x892C
+#define GL_REG_12_ATI 0x892D
+#define GL_REG_13_ATI 0x892E
+#define GL_REG_14_ATI 0x892F
+#define GL_REG_15_ATI 0x8930
+#define GL_REG_16_ATI 0x8931
+#define GL_REG_17_ATI 0x8932
+#define GL_REG_18_ATI 0x8933
+#define GL_REG_19_ATI 0x8934
+#define GL_REG_20_ATI 0x8935
+#define GL_REG_21_ATI 0x8936
+#define GL_REG_22_ATI 0x8937
+#define GL_REG_23_ATI 0x8938
+#define GL_REG_24_ATI 0x8939
+#define GL_REG_25_ATI 0x893A
+#define GL_REG_26_ATI 0x893B
+#define GL_REG_27_ATI 0x893C
+#define GL_REG_28_ATI 0x893D
+#define GL_REG_29_ATI 0x893E
+#define GL_REG_30_ATI 0x893F
+#define GL_REG_31_ATI 0x8940
+#define GL_CON_0_ATI 0x8941
+#define GL_CON_1_ATI 0x8942
+#define GL_CON_2_ATI 0x8943
+#define GL_CON_3_ATI 0x8944
+#define GL_CON_4_ATI 0x8945
+#define GL_CON_5_ATI 0x8946
+#define GL_CON_6_ATI 0x8947
+#define GL_CON_7_ATI 0x8948
+#define GL_CON_8_ATI 0x8949
+#define GL_CON_9_ATI 0x894A
+#define GL_CON_10_ATI 0x894B
+#define GL_CON_11_ATI 0x894C
+#define GL_CON_12_ATI 0x894D
+#define GL_CON_13_ATI 0x894E
+#define GL_CON_14_ATI 0x894F
+#define GL_CON_15_ATI 0x8950
+#define GL_CON_16_ATI 0x8951
+#define GL_CON_17_ATI 0x8952
+#define GL_CON_18_ATI 0x8953
+#define GL_CON_19_ATI 0x8954
+#define GL_CON_20_ATI 0x8955
+#define GL_CON_21_ATI 0x8956
+#define GL_CON_22_ATI 0x8957
+#define GL_CON_23_ATI 0x8958
+#define GL_CON_24_ATI 0x8959
+#define GL_CON_25_ATI 0x895A
+#define GL_CON_26_ATI 0x895B
+#define GL_CON_27_ATI 0x895C
+#define GL_CON_28_ATI 0x895D
+#define GL_CON_29_ATI 0x895E
+#define GL_CON_30_ATI 0x895F
+#define GL_CON_31_ATI 0x8960
+#define GL_MOV_ATI 0x8961
+#define GL_ADD_ATI 0x8963
+#define GL_MUL_ATI 0x8964
+#define GL_SUB_ATI 0x8965
+#define GL_DOT3_ATI 0x8966
+#define GL_DOT4_ATI 0x8967
+#define GL_MAD_ATI 0x8968
+#define GL_LERP_ATI 0x8969
+#define GL_CND_ATI 0x896A
+#define GL_CND0_ATI 0x896B
+#define GL_DOT2_ADD_ATI 0x896C
+#define GL_SECONDARY_INTERPOLATOR_ATI 0x896D
+#define GL_NUM_FRAGMENT_REGISTERS_ATI 0x896E
+#define GL_NUM_FRAGMENT_CONSTANTS_ATI 0x896F
+#define GL_NUM_PASSES_ATI 0x8970
+#define GL_NUM_INSTRUCTIONS_PER_PASS_ATI 0x8971
+#define GL_NUM_INSTRUCTIONS_TOTAL_ATI 0x8972
+#define GL_NUM_INPUT_INTERPOLATOR_COMPONENTS_ATI 0x8973
+#define GL_NUM_LOOPBACK_COMPONENTS_ATI 0x8974
+#define GL_COLOR_ALPHA_PAIRING_ATI 0x8975
+#define GL_SWIZZLE_STR_ATI 0x8976
+#define GL_SWIZZLE_STQ_ATI 0x8977
+#define GL_SWIZZLE_STR_DR_ATI 0x8978
+#define GL_SWIZZLE_STQ_DQ_ATI 0x8979
+#define GL_SWIZZLE_STRQ_ATI 0x897A
+#define GL_SWIZZLE_STRQ_DQ_ATI 0x897B
+#define GL_RED_BIT_ATI 0x00000001
+#define GL_GREEN_BIT_ATI 0x00000002
+#define GL_BLUE_BIT_ATI 0x00000004
+#define GL_2X_BIT_ATI 0x00000001
+#define GL_4X_BIT_ATI 0x00000002
+#define GL_8X_BIT_ATI 0x00000004
+#define GL_HALF_BIT_ATI 0x00000008
+#define GL_QUARTER_BIT_ATI 0x00000010
+#define GL_EIGHTH_BIT_ATI 0x00000020
+#define GL_SATURATE_BIT_ATI 0x00000040
+#define GL_COMP_BIT_ATI 0x00000002
+#define GL_NEGATE_BIT_ATI 0x00000004
+#define GL_BIAS_BIT_ATI 0x00000008
+#endif
+
+#ifndef GL_ATI_pn_triangles
+#define GL_PN_TRIANGLES_ATI 0x87F0
+#define GL_MAX_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F1
+#define GL_PN_TRIANGLES_POINT_MODE_ATI 0x87F2
+#define GL_PN_TRIANGLES_NORMAL_MODE_ATI 0x87F3
+#define GL_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F4
+#define GL_PN_TRIANGLES_POINT_MODE_LINEAR_ATI 0x87F5
+#define GL_PN_TRIANGLES_POINT_MODE_CUBIC_ATI 0x87F6
+#define GL_PN_TRIANGLES_NORMAL_MODE_LINEAR_ATI 0x87F7
+#define GL_PN_TRIANGLES_NORMAL_MODE_QUADRATIC_ATI 0x87F8
+#endif
+
+#ifndef GL_ATI_vertex_array_object
+#define GL_STATIC_ATI 0x8760
+#define GL_DYNAMIC_ATI 0x8761
+#define GL_PRESERVE_ATI 0x8762
+#define GL_DISCARD_ATI 0x8763
+#define GL_OBJECT_BUFFER_SIZE_ATI 0x8764
+#define GL_OBJECT_BUFFER_USAGE_ATI 0x8765
+#define GL_ARRAY_OBJECT_BUFFER_ATI 0x8766
+#define GL_ARRAY_OBJECT_OFFSET_ATI 0x8767
+#endif
+
+#ifndef GL_EXT_vertex_shader
+#define GL_VERTEX_SHADER_EXT 0x8780
+#define GL_VERTEX_SHADER_BINDING_EXT 0x8781
+#define GL_OP_INDEX_EXT 0x8782
+#define GL_OP_NEGATE_EXT 0x8783
+#define GL_OP_DOT3_EXT 0x8784
+#define GL_OP_DOT4_EXT 0x8785
+#define GL_OP_MUL_EXT 0x8786
+#define GL_OP_ADD_EXT 0x8787
+#define GL_OP_MADD_EXT 0x8788
+#define GL_OP_FRAC_EXT 0x8789
+#define GL_OP_MAX_EXT 0x878A
+#define GL_OP_MIN_EXT 0x878B
+#define GL_OP_SET_GE_EXT 0x878C
+#define GL_OP_SET_LT_EXT 0x878D
+#define GL_OP_CLAMP_EXT 0x878E
+#define GL_OP_FLOOR_EXT 0x878F
+#define GL_OP_ROUND_EXT 0x8790
+#define GL_OP_EXP_BASE_2_EXT 0x8791
+#define GL_OP_LOG_BASE_2_EXT 0x8792
+#define GL_OP_POWER_EXT 0x8793
+#define GL_OP_RECIP_EXT 0x8794
+#define GL_OP_RECIP_SQRT_EXT 0x8795
+#define GL_OP_SUB_EXT 0x8796
+#define GL_OP_CROSS_PRODUCT_EXT 0x8797
+#define GL_OP_MULTIPLY_MATRIX_EXT 0x8798
+#define GL_OP_MOV_EXT 0x8799
+#define GL_OUTPUT_VERTEX_EXT 0x879A
+#define GL_OUTPUT_COLOR0_EXT 0x879B
+#define GL_OUTPUT_COLOR1_EXT 0x879C
+#define GL_OUTPUT_TEXTURE_COORD0_EXT 0x879D
+#define GL_OUTPUT_TEXTURE_COORD1_EXT 0x879E
+#define GL_OUTPUT_TEXTURE_COORD2_EXT 0x879F
+#define GL_OUTPUT_TEXTURE_COORD3_EXT 0x87A0
+#define GL_OUTPUT_TEXTURE_COORD4_EXT 0x87A1
+#define GL_OUTPUT_TEXTURE_COORD5_EXT 0x87A2
+#define GL_OUTPUT_TEXTURE_COORD6_EXT 0x87A3
+#define GL_OUTPUT_TEXTURE_COORD7_EXT 0x87A4
+#define GL_OUTPUT_TEXTURE_COORD8_EXT 0x87A5
+#define GL_OUTPUT_TEXTURE_COORD9_EXT 0x87A6
+#define GL_OUTPUT_TEXTURE_COORD10_EXT 0x87A7
+#define GL_OUTPUT_TEXTURE_COORD11_EXT 0x87A8
+#define GL_OUTPUT_TEXTURE_COORD12_EXT 0x87A9
+#define GL_OUTPUT_TEXTURE_COORD13_EXT 0x87AA
+#define GL_OUTPUT_TEXTURE_COORD14_EXT 0x87AB
+#define GL_OUTPUT_TEXTURE_COORD15_EXT 0x87AC
+#define GL_OUTPUT_TEXTURE_COORD16_EXT 0x87AD
+#define GL_OUTPUT_TEXTURE_COORD17_EXT 0x87AE
+#define GL_OUTPUT_TEXTURE_COORD18_EXT 0x87AF
+#define GL_OUTPUT_TEXTURE_COORD19_EXT 0x87B0
+#define GL_OUTPUT_TEXTURE_COORD20_EXT 0x87B1
+#define GL_OUTPUT_TEXTURE_COORD21_EXT 0x87B2
+#define GL_OUTPUT_TEXTURE_COORD22_EXT 0x87B3
+#define GL_OUTPUT_TEXTURE_COORD23_EXT 0x87B4
+#define GL_OUTPUT_TEXTURE_COORD24_EXT 0x87B5
+#define GL_OUTPUT_TEXTURE_COORD25_EXT 0x87B6
+#define GL_OUTPUT_TEXTURE_COORD26_EXT 0x87B7
+#define GL_OUTPUT_TEXTURE_COORD27_EXT 0x87B8
+#define GL_OUTPUT_TEXTURE_COORD28_EXT 0x87B9
+#define GL_OUTPUT_TEXTURE_COORD29_EXT 0x87BA
+#define GL_OUTPUT_TEXTURE_COORD30_EXT 0x87BB
+#define GL_OUTPUT_TEXTURE_COORD31_EXT 0x87BC
+#define GL_OUTPUT_FOG_EXT 0x87BD
+#define GL_SCALAR_EXT 0x87BE
+#define GL_VECTOR_EXT 0x87BF
+#define GL_MATRIX_EXT 0x87C0
+#define GL_VARIANT_EXT 0x87C1
+#define GL_INVARIANT_EXT 0x87C2
+#define GL_LOCAL_CONSTANT_EXT 0x87C3
+#define GL_LOCAL_EXT 0x87C4
+#define GL_MAX_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87C5
+#define GL_MAX_VERTEX_SHADER_VARIANTS_EXT 0x87C6
+#define GL_MAX_VERTEX_SHADER_INVARIANTS_EXT 0x87C7
+#define GL_MAX_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87C8
+#define GL_MAX_VERTEX_SHADER_LOCALS_EXT 0x87C9
+#define GL_MAX_OPTIMIZED_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87CA
+#define GL_MAX_OPTIMIZED_VERTEX_SHADER_VARIANTS_EXT 0x87CB
+#define GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87CC
+#define GL_MAX_OPTIMIZED_VERTEX_SHADER_INVARIANTS_EXT 0x87CD
+#define GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCALS_EXT 0x87CE
+#define GL_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87CF
+#define GL_VERTEX_SHADER_VARIANTS_EXT 0x87D0
+#define GL_VERTEX_SHADER_INVARIANTS_EXT 0x87D1
+#define GL_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87D2
+#define GL_VERTEX_SHADER_LOCALS_EXT 0x87D3
+#define GL_VERTEX_SHADER_OPTIMIZED_EXT 0x87D4
+#define GL_X_EXT 0x87D5
+#define GL_Y_EXT 0x87D6
+#define GL_Z_EXT 0x87D7
+#define GL_W_EXT 0x87D8
+#define GL_NEGATIVE_X_EXT 0x87D9
+#define GL_NEGATIVE_Y_EXT 0x87DA
+#define GL_NEGATIVE_Z_EXT 0x87DB
+#define GL_NEGATIVE_W_EXT 0x87DC
+#define GL_ZERO_EXT 0x87DD
+#define GL_ONE_EXT 0x87DE
+#define GL_NEGATIVE_ONE_EXT 0x87DF
+#define GL_NORMALIZED_RANGE_EXT 0x87E0
+#define GL_FULL_RANGE_EXT 0x87E1
+#define GL_CURRENT_VERTEX_EXT 0x87E2
+#define GL_MVP_MATRIX_EXT 0x87E3
+#define GL_VARIANT_VALUE_EXT 0x87E4
+#define GL_VARIANT_DATATYPE_EXT 0x87E5
+#define GL_VARIANT_ARRAY_STRIDE_EXT 0x87E6
+#define GL_VARIANT_ARRAY_TYPE_EXT 0x87E7
+#define GL_VARIANT_ARRAY_EXT 0x87E8
+#define GL_VARIANT_ARRAY_POINTER_EXT 0x87E9
+#define GL_INVARIANT_VALUE_EXT 0x87EA
+#define GL_INVARIANT_DATATYPE_EXT 0x87EB
+#define GL_LOCAL_CONSTANT_VALUE_EXT 0x87EC
+#define GL_LOCAL_CONSTANT_DATATYPE_EXT 0x87ED
+#endif
+
+#ifndef GL_ATI_vertex_streams
+#define GL_MAX_VERTEX_STREAMS_ATI 0x876B
+#define GL_VERTEX_STREAM0_ATI 0x876C
+#define GL_VERTEX_STREAM1_ATI 0x876D
+#define GL_VERTEX_STREAM2_ATI 0x876E
+#define GL_VERTEX_STREAM3_ATI 0x876F
+#define GL_VERTEX_STREAM4_ATI 0x8770
+#define GL_VERTEX_STREAM5_ATI 0x8771
+#define GL_VERTEX_STREAM6_ATI 0x8772
+#define GL_VERTEX_STREAM7_ATI 0x8773
+#define GL_VERTEX_SOURCE_ATI 0x8774
+#endif
+
+#ifndef GL_ATI_element_array
+#define GL_ELEMENT_ARRAY_ATI 0x8768
+#define GL_ELEMENT_ARRAY_TYPE_ATI 0x8769
+#define GL_ELEMENT_ARRAY_POINTER_ATI 0x876A
+#endif
+
+#ifndef GL_SUN_mesh_array
+#define GL_QUAD_MESH_SUN 0x8614
+#define GL_TRIANGLE_MESH_SUN 0x8615
+#endif
+
+#ifndef GL_SUN_slice_accum
+#define GL_SLICE_ACCUM_SUN 0x85CC
+#endif
+
+#ifndef GL_NV_multisample_filter_hint
+#define GL_MULTISAMPLE_FILTER_HINT_NV 0x8534
+#endif
+
+#ifndef GL_NV_depth_clamp
+#define GL_DEPTH_CLAMP_NV 0x864F
+#endif
+
+#ifndef GL_NV_occlusion_query
+#define GL_PIXEL_COUNTER_BITS_NV 0x8864
+#define GL_CURRENT_OCCLUSION_QUERY_ID_NV 0x8865
+#define GL_PIXEL_COUNT_NV 0x8866
+#define GL_PIXEL_COUNT_AVAILABLE_NV 0x8867
+#endif
+
+#ifndef GL_NV_point_sprite
+#define GL_POINT_SPRITE_NV 0x8861
+#define GL_COORD_REPLACE_NV 0x8862
+#define GL_POINT_SPRITE_R_MODE_NV 0x8863
+#endif
+
+#ifndef GL_NV_texture_shader3
+#define GL_OFFSET_PROJECTIVE_TEXTURE_2D_NV 0x8850
+#define GL_OFFSET_PROJECTIVE_TEXTURE_2D_SCALE_NV 0x8851
+#define GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_NV 0x8852
+#define GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_SCALE_NV 0x8853
+#define GL_OFFSET_HILO_TEXTURE_2D_NV 0x8854
+#define GL_OFFSET_HILO_TEXTURE_RECTANGLE_NV 0x8855
+#define GL_OFFSET_HILO_PROJECTIVE_TEXTURE_2D_NV 0x8856
+#define GL_OFFSET_HILO_PROJECTIVE_TEXTURE_RECTANGLE_NV 0x8857
+#define GL_DEPENDENT_HILO_TEXTURE_2D_NV 0x8858
+#define GL_DEPENDENT_RGB_TEXTURE_3D_NV 0x8859
+#define GL_DEPENDENT_RGB_TEXTURE_CUBE_MAP_NV 0x885A
+#define GL_DOT_PRODUCT_PASS_THROUGH_NV 0x885B
+#define GL_DOT_PRODUCT_TEXTURE_1D_NV 0x885C
+#define GL_DOT_PRODUCT_AFFINE_DEPTH_REPLACE_NV 0x885D
+#define GL_HILO8_NV 0x885E
+#define GL_SIGNED_HILO8_NV 0x885F
+#define GL_FORCE_BLUE_TO_ONE_NV 0x8860
+#endif
+
+#ifndef GL_NV_vertex_program1_1
+#endif
+
+#ifndef GL_EXT_shadow_funcs
+#endif
+
+#ifndef GL_EXT_stencil_two_side
+#define GL_STENCIL_TEST_TWO_SIDE_EXT 0x8910
+#define GL_ACTIVE_STENCIL_FACE_EXT 0x8911
+#endif
+
+#ifndef GL_ATI_text_fragment_shader
+#define GL_TEXT_FRAGMENT_SHADER_ATI 0x8200
+#endif
+
+#ifndef GL_APPLE_client_storage
+#define GL_UNPACK_CLIENT_STORAGE_APPLE 0x85B2
+#endif
+
+#ifndef GL_APPLE_element_array
+#define GL_ELEMENT_ARRAY_APPLE 0x8A0C
+#define GL_ELEMENT_ARRAY_TYPE_APPLE 0x8A0D
+#define GL_ELEMENT_ARRAY_POINTER_APPLE 0x8A0E
+#endif
+
+#ifndef GL_APPLE_fence
+#define GL_DRAW_PIXELS_APPLE 0x8A0A
+#define GL_FENCE_APPLE 0x8A0B
+#endif
+
+#ifndef GL_APPLE_vertex_array_object
+#define GL_VERTEX_ARRAY_BINDING_APPLE 0x85B5
+#endif
+
+#ifndef GL_APPLE_vertex_array_range
+#define GL_VERTEX_ARRAY_RANGE_APPLE 0x851D
+#define GL_VERTEX_ARRAY_RANGE_LENGTH_APPLE 0x851E
+#define GL_VERTEX_ARRAY_STORAGE_HINT_APPLE 0x851F
+#define GL_VERTEX_ARRAY_RANGE_POINTER_APPLE 0x8521
+#define GL_STORAGE_CLIENT_APPLE 0x85B4
+#define GL_STORAGE_CACHED_APPLE 0x85BE
+#define GL_STORAGE_SHARED_APPLE 0x85BF
+#endif
+
+#ifndef GL_APPLE_ycbcr_422
+#define GL_YCBCR_422_APPLE 0x85B9
+#define GL_UNSIGNED_SHORT_8_8_APPLE 0x85BA
+#define GL_UNSIGNED_SHORT_8_8_REV_APPLE 0x85BB
+#endif
+
+#ifndef GL_S3_s3tc
+#define GL_RGB_S3TC 0x83A0
+#define GL_RGB4_S3TC 0x83A1
+#define GL_RGBA_S3TC 0x83A2
+#define GL_RGBA4_S3TC 0x83A3
+#endif
+
+#ifndef GL_ATI_draw_buffers
+#define GL_MAX_DRAW_BUFFERS_ATI 0x8824
+#define GL_DRAW_BUFFER0_ATI 0x8825
+#define GL_DRAW_BUFFER1_ATI 0x8826
+#define GL_DRAW_BUFFER2_ATI 0x8827
+#define GL_DRAW_BUFFER3_ATI 0x8828
+#define GL_DRAW_BUFFER4_ATI 0x8829
+#define GL_DRAW_BUFFER5_ATI 0x882A
+#define GL_DRAW_BUFFER6_ATI 0x882B
+#define GL_DRAW_BUFFER7_ATI 0x882C
+#define GL_DRAW_BUFFER8_ATI 0x882D
+#define GL_DRAW_BUFFER9_ATI 0x882E
+#define GL_DRAW_BUFFER10_ATI 0x882F
+#define GL_DRAW_BUFFER11_ATI 0x8830
+#define GL_DRAW_BUFFER12_ATI 0x8831
+#define GL_DRAW_BUFFER13_ATI 0x8832
+#define GL_DRAW_BUFFER14_ATI 0x8833
+#define GL_DRAW_BUFFER15_ATI 0x8834
+#endif
+
+#ifndef GL_ATI_pixel_format_float
+#define GL_TYPE_RGBA_FLOAT_ATI 0x8820
+#define GL_COLOR_CLEAR_UNCLAMPED_VALUE_ATI 0x8835
+#endif
+
+#ifndef GL_ATI_texture_env_combine3
+#define GL_MODULATE_ADD_ATI 0x8744
+#define GL_MODULATE_SIGNED_ADD_ATI 0x8745
+#define GL_MODULATE_SUBTRACT_ATI 0x8746
+#endif
+
+#ifndef GL_ATI_texture_float
+#define GL_RGBA_FLOAT32_ATI 0x8814
+#define GL_RGB_FLOAT32_ATI 0x8815
+#define GL_ALPHA_FLOAT32_ATI 0x8816
+#define GL_INTENSITY_FLOAT32_ATI 0x8817
+#define GL_LUMINANCE_FLOAT32_ATI 0x8818
+#define GL_LUMINANCE_ALPHA_FLOAT32_ATI 0x8819
+#define GL_RGBA_FLOAT16_ATI 0x881A
+#define GL_RGB_FLOAT16_ATI 0x881B
+#define GL_ALPHA_FLOAT16_ATI 0x881C
+#define GL_INTENSITY_FLOAT16_ATI 0x881D
+#define GL_LUMINANCE_FLOAT16_ATI 0x881E
+#define GL_LUMINANCE_ALPHA_FLOAT16_ATI 0x881F
+#endif
+
+#ifndef GL_NV_float_buffer
+#define GL_FLOAT_R_NV 0x8880
+#define GL_FLOAT_RG_NV 0x8881
+#define GL_FLOAT_RGB_NV 0x8882
+#define GL_FLOAT_RGBA_NV 0x8883
+#define GL_FLOAT_R16_NV 0x8884
+#define GL_FLOAT_R32_NV 0x8885
+#define GL_FLOAT_RG16_NV 0x8886
+#define GL_FLOAT_RG32_NV 0x8887
+#define GL_FLOAT_RGB16_NV 0x8888
+#define GL_FLOAT_RGB32_NV 0x8889
+#define GL_FLOAT_RGBA16_NV 0x888A
+#define GL_FLOAT_RGBA32_NV 0x888B
+#define GL_TEXTURE_FLOAT_COMPONENTS_NV 0x888C
+#define GL_FLOAT_CLEAR_COLOR_VALUE_NV 0x888D
+#define GL_FLOAT_RGBA_MODE_NV 0x888E
+#endif
+
+#ifndef GL_NV_fragment_program
+#define GL_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMETERS_NV 0x8868
+#define GL_FRAGMENT_PROGRAM_NV 0x8870
+#define GL_MAX_TEXTURE_COORDS_NV 0x8871
+#define GL_MAX_TEXTURE_IMAGE_UNITS_NV 0x8872
+#define GL_FRAGMENT_PROGRAM_BINDING_NV 0x8873
+#define GL_PROGRAM_ERROR_STRING_NV 0x8874
+#endif
+
+#ifndef GL_NV_half_float
+#define GL_HALF_FLOAT_NV 0x140B
+#endif
+
+#ifndef GL_NV_pixel_data_range
+#define GL_WRITE_PIXEL_DATA_RANGE_NV 0x8878
+#define GL_READ_PIXEL_DATA_RANGE_NV 0x8879
+#define GL_WRITE_PIXEL_DATA_RANGE_LENGTH_NV 0x887A
+#define GL_READ_PIXEL_DATA_RANGE_LENGTH_NV 0x887B
+#define GL_WRITE_PIXEL_DATA_RANGE_POINTER_NV 0x887C
+#define GL_READ_PIXEL_DATA_RANGE_POINTER_NV 0x887D
+#endif
+
+#ifndef GL_NV_primitive_restart
+#define GL_PRIMITIVE_RESTART_NV 0x8558
+#define GL_PRIMITIVE_RESTART_INDEX_NV 0x8559
+#endif
+
+#ifndef GL_NV_texture_expand_normal
+#define GL_TEXTURE_UNSIGNED_REMAP_MODE_NV 0x888F
+#endif
+
+#ifndef GL_NV_vertex_program2
+#endif
+
+#ifndef GL_ATI_map_object_buffer
+#endif
+
+#ifndef GL_ATI_separate_stencil
+#define GL_STENCIL_BACK_FUNC_ATI 0x8800
+#define GL_STENCIL_BACK_FAIL_ATI 0x8801
+#define GL_STENCIL_BACK_PASS_DEPTH_FAIL_ATI 0x8802
+#define GL_STENCIL_BACK_PASS_DEPTH_PASS_ATI 0x8803
+#endif
+
+#ifndef GL_ATI_vertex_attrib_array_object
+#endif
+
+#ifndef GL_OES_read_format
+#define GL_IMPLEMENTATION_COLOR_READ_TYPE_OES 0x8B9A
+#define GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES 0x8B9B
+#endif
+
+#ifndef GL_EXT_depth_bounds_test
+#define GL_DEPTH_BOUNDS_TEST_EXT 0x8890
+#define GL_DEPTH_BOUNDS_EXT 0x8891
+#endif
+
+#ifndef GL_EXT_texture_mirror_clamp
+#define GL_MIRROR_CLAMP_EXT 0x8742
+#define GL_MIRROR_CLAMP_TO_EDGE_EXT 0x8743
+#define GL_MIRROR_CLAMP_TO_BORDER_EXT 0x8912
+#endif
+
+#ifndef GL_EXT_blend_equation_separate
+#define GL_BLEND_EQUATION_RGB_EXT 0x8009
+#define GL_BLEND_EQUATION_ALPHA_EXT 0x883D
+#endif
+
+#ifndef GL_MESA_pack_invert
+#define GL_PACK_INVERT_MESA 0x8758
+#endif
+
+#ifndef GL_MESA_ycbcr_texture
+#define GL_UNSIGNED_SHORT_8_8_MESA 0x85BA
+#define GL_UNSIGNED_SHORT_8_8_REV_MESA 0x85BB
+#define GL_YCBCR_MESA 0x8757
+#endif
+
+#ifndef GL_EXT_pixel_buffer_object
+#define GL_PIXEL_PACK_BUFFER_EXT 0x88EB
+#define GL_PIXEL_UNPACK_BUFFER_EXT 0x88EC
+#define GL_PIXEL_PACK_BUFFER_BINDING_EXT 0x88ED
+#define GL_PIXEL_UNPACK_BUFFER_BINDING_EXT 0x88EF
+#endif
+
+#ifndef GL_NV_fragment_program_option
+#endif
+
+#ifndef GL_NV_fragment_program2
+#define GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV 0x88F4
+#define GL_MAX_PROGRAM_CALL_DEPTH_NV 0x88F5
+#define GL_MAX_PROGRAM_IF_DEPTH_NV 0x88F6
+#define GL_MAX_PROGRAM_LOOP_DEPTH_NV 0x88F7
+#define GL_MAX_PROGRAM_LOOP_COUNT_NV 0x88F8
+#endif
+
+#ifndef GL_NV_vertex_program2_option
+/* reuse GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV */
+/* reuse GL_MAX_PROGRAM_CALL_DEPTH_NV */
+#endif
+
+#ifndef GL_NV_vertex_program3
+/* reuse GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB */
+#endif
+
+#ifndef GL_EXT_framebuffer_object
+#define GL_INVALID_FRAMEBUFFER_OPERATION_EXT 0x0506
+#define GL_MAX_RENDERBUFFER_SIZE_EXT 0x84E8
+#define GL_FRAMEBUFFER_BINDING_EXT 0x8CA6
+#define GL_RENDERBUFFER_BINDING_EXT 0x8CA7
+#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT 0x8CD0
+#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT 0x8CD1
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT 0x8CD2
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT 0x8CD3
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT 0x8CD4
+#define GL_FRAMEBUFFER_COMPLETE_EXT 0x8CD5
+#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT 0x8CD6
+#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT 0x8CD7
+#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT 0x8CD9
+#define GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT 0x8CDA
+#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT 0x8CDB
+#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT 0x8CDC
+#define GL_FRAMEBUFFER_UNSUPPORTED_EXT 0x8CDD
+#define GL_MAX_COLOR_ATTACHMENTS_EXT 0x8CDF
+#define GL_COLOR_ATTACHMENT0_EXT 0x8CE0
+#define GL_COLOR_ATTACHMENT1_EXT 0x8CE1
+#define GL_COLOR_ATTACHMENT2_EXT 0x8CE2
+#define GL_COLOR_ATTACHMENT3_EXT 0x8CE3
+#define GL_COLOR_ATTACHMENT4_EXT 0x8CE4
+#define GL_COLOR_ATTACHMENT5_EXT 0x8CE5
+#define GL_COLOR_ATTACHMENT6_EXT 0x8CE6
+#define GL_COLOR_ATTACHMENT7_EXT 0x8CE7
+#define GL_COLOR_ATTACHMENT8_EXT 0x8CE8
+#define GL_COLOR_ATTACHMENT9_EXT 0x8CE9
+#define GL_COLOR_ATTACHMENT10_EXT 0x8CEA
+#define GL_COLOR_ATTACHMENT11_EXT 0x8CEB
+#define GL_COLOR_ATTACHMENT12_EXT 0x8CEC
+#define GL_COLOR_ATTACHMENT13_EXT 0x8CED
+#define GL_COLOR_ATTACHMENT14_EXT 0x8CEE
+#define GL_COLOR_ATTACHMENT15_EXT 0x8CEF
+#define GL_DEPTH_ATTACHMENT_EXT 0x8D00
+#define GL_STENCIL_ATTACHMENT_EXT 0x8D20
+#define GL_FRAMEBUFFER_EXT 0x8D40
+#define GL_RENDERBUFFER_EXT 0x8D41
+#define GL_RENDERBUFFER_WIDTH_EXT 0x8D42
+#define GL_RENDERBUFFER_HEIGHT_EXT 0x8D43
+#define GL_RENDERBUFFER_INTERNAL_FORMAT_EXT 0x8D44
+#define GL_STENCIL_INDEX1_EXT 0x8D46
+#define GL_STENCIL_INDEX4_EXT 0x8D47
+#define GL_STENCIL_INDEX8_EXT 0x8D48
+#define GL_STENCIL_INDEX16_EXT 0x8D49
+#define GL_RENDERBUFFER_RED_SIZE_EXT 0x8D50
+#define GL_RENDERBUFFER_GREEN_SIZE_EXT 0x8D51
+#define GL_RENDERBUFFER_BLUE_SIZE_EXT 0x8D52
+#define GL_RENDERBUFFER_ALPHA_SIZE_EXT 0x8D53
+#define GL_RENDERBUFFER_DEPTH_SIZE_EXT 0x8D54
+#define GL_RENDERBUFFER_STENCIL_SIZE_EXT 0x8D55
+#endif
+
+#ifndef GL_GREMEDY_string_marker
+#endif
+
+#ifndef GL_EXT_packed_depth_stencil
+#define GL_DEPTH_STENCIL_EXT 0x84F9
+#define GL_UNSIGNED_INT_24_8_EXT 0x84FA
+#define GL_DEPTH24_STENCIL8_EXT 0x88F0
+#define GL_TEXTURE_STENCIL_SIZE_EXT 0x88F1
+#endif
+
+#ifndef GL_EXT_stencil_clear_tag
+#define GL_STENCIL_TAG_BITS_EXT 0x88F2
+#define GL_STENCIL_CLEAR_TAG_VALUE_EXT 0x88F3
+#endif
+
+#ifndef GL_EXT_texture_sRGB
+#define GL_SRGB_EXT 0x8C40
+#define GL_SRGB8_EXT 0x8C41
+#define GL_SRGB_ALPHA_EXT 0x8C42
+#define GL_SRGB8_ALPHA8_EXT 0x8C43
+#define GL_SLUMINANCE_ALPHA_EXT 0x8C44
+#define GL_SLUMINANCE8_ALPHA8_EXT 0x8C45
+#define GL_SLUMINANCE_EXT 0x8C46
+#define GL_SLUMINANCE8_EXT 0x8C47
+#define GL_COMPRESSED_SRGB_EXT 0x8C48
+#define GL_COMPRESSED_SRGB_ALPHA_EXT 0x8C49
+#define GL_COMPRESSED_SLUMINANCE_EXT 0x8C4A
+#define GL_COMPRESSED_SLUMINANCE_ALPHA_EXT 0x8C4B
+#define GL_COMPRESSED_SRGB_S3TC_DXT1_EXT 0x8C4C
+#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT 0x8C4D
+#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT 0x8C4E
+#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT 0x8C4F
+#endif
+
+#ifndef GL_EXT_framebuffer_blit
+#define GL_READ_FRAMEBUFFER_EXT 0x8CA8
+#define GL_DRAW_FRAMEBUFFER_EXT 0x8CA9
+#define GL_DRAW_FRAMEBUFFER_BINDING_EXT GL_FRAMEBUFFER_BINDING_EXT
+#define GL_READ_FRAMEBUFFER_BINDING_EXT 0x8CAA
+#endif
+
+#ifndef GL_EXT_framebuffer_multisample
+#define GL_RENDERBUFFER_SAMPLES_EXT 0x8CAB
+#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT 0x8D56
+#define GL_MAX_SAMPLES_EXT 0x8D57
+#endif
+
+#ifndef GL_MESAX_texture_stack
+#define GL_TEXTURE_1D_STACK_MESAX 0x8759
+#define GL_TEXTURE_2D_STACK_MESAX 0x875A
+#define GL_PROXY_TEXTURE_1D_STACK_MESAX 0x875B
+#define GL_PROXY_TEXTURE_2D_STACK_MESAX 0x875C
+#define GL_TEXTURE_1D_STACK_BINDING_MESAX 0x875D
+#define GL_TEXTURE_2D_STACK_BINDING_MESAX 0x875E
+#endif
+
+#ifndef GL_EXT_timer_query
+#define GL_TIME_ELAPSED_EXT 0x88BF
+#endif
+
+#ifndef GL_EXT_gpu_program_parameters
+#endif
+
+#ifndef GL_APPLE_flush_buffer_range
+#define GL_BUFFER_SERIALIZED_MODIFY_APPLE 0x8A12
+#define GL_BUFFER_FLUSHING_UNMAP_APPLE 0x8A13
+#endif
+
+#ifndef GL_NV_gpu_program4
+#define GL_MIN_PROGRAM_TEXEL_OFFSET_NV 0x8904
+#define GL_MAX_PROGRAM_TEXEL_OFFSET_NV 0x8905
+#define GL_PROGRAM_ATTRIB_COMPONENTS_NV 0x8906
+#define GL_PROGRAM_RESULT_COMPONENTS_NV 0x8907
+#define GL_MAX_PROGRAM_ATTRIB_COMPONENTS_NV 0x8908
+#define GL_MAX_PROGRAM_RESULT_COMPONENTS_NV 0x8909
+#define GL_MAX_PROGRAM_GENERIC_ATTRIBS_NV 0x8DA5
+#define GL_MAX_PROGRAM_GENERIC_RESULTS_NV 0x8DA6
+#endif
+
+#ifndef GL_NV_geometry_program4
+#define GL_LINES_ADJACENCY_EXT 0x000A
+#define GL_LINE_STRIP_ADJACENCY_EXT 0x000B
+#define GL_TRIANGLES_ADJACENCY_EXT 0x000C
+#define GL_TRIANGLE_STRIP_ADJACENCY_EXT 0x000D
+#define GL_GEOMETRY_PROGRAM_NV 0x8C26
+#define GL_MAX_PROGRAM_OUTPUT_VERTICES_NV 0x8C27
+#define GL_MAX_PROGRAM_TOTAL_OUTPUT_COMPONENTS_NV 0x8C28
+#define GL_GEOMETRY_VERTICES_OUT_EXT 0x8DDA
+#define GL_GEOMETRY_INPUT_TYPE_EXT 0x8DDB
+#define GL_GEOMETRY_OUTPUT_TYPE_EXT 0x8DDC
+#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT 0x8C29
+#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT 0x8DA7
+#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT 0x8DA8
+#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_EXT 0x8DA9
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT 0x8CD4
+#define GL_PROGRAM_POINT_SIZE_EXT 0x8642
+#endif
+
+#ifndef GL_EXT_geometry_shader4
+#define GL_GEOMETRY_SHADER_EXT 0x8DD9
+/* reuse GL_GEOMETRY_VERTICES_OUT_EXT */
+/* reuse GL_GEOMETRY_INPUT_TYPE_EXT */
+/* reuse GL_GEOMETRY_OUTPUT_TYPE_EXT */
+/* reuse GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT */
+#define GL_MAX_GEOMETRY_VARYING_COMPONENTS_EXT 0x8DDD
+#define GL_MAX_VERTEX_VARYING_COMPONENTS_EXT 0x8DDE
+#define GL_MAX_VARYING_COMPONENTS_EXT 0x8B4B
+#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT 0x8DDF
+#define GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT 0x8DE0
+#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT 0x8DE1
+/* reuse GL_LINES_ADJACENCY_EXT */
+/* reuse GL_LINE_STRIP_ADJACENCY_EXT */
+/* reuse GL_TRIANGLES_ADJACENCY_EXT */
+/* reuse GL_TRIANGLE_STRIP_ADJACENCY_EXT */
+/* reuse GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT */
+/* reuse GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_EXT */
+/* reuse GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT */
+/* reuse GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT */
+/* reuse GL_PROGRAM_POINT_SIZE_EXT */
+#endif
+
+#ifndef GL_NV_vertex_program4
+#define GL_VERTEX_ATTRIB_ARRAY_INTEGER_NV 0x88FD
+#endif
+
+#ifndef GL_EXT_gpu_shader4
+#define GL_SAMPLER_1D_ARRAY_EXT 0x8DC0
+#define GL_SAMPLER_2D_ARRAY_EXT 0x8DC1
+#define GL_SAMPLER_BUFFER_EXT 0x8DC2
+#define GL_SAMPLER_1D_ARRAY_SHADOW_EXT 0x8DC3
+#define GL_SAMPLER_2D_ARRAY_SHADOW_EXT 0x8DC4
+#define GL_SAMPLER_CUBE_SHADOW_EXT 0x8DC5
+#define GL_UNSIGNED_INT_VEC2_EXT 0x8DC6
+#define GL_UNSIGNED_INT_VEC3_EXT 0x8DC7
+#define GL_UNSIGNED_INT_VEC4_EXT 0x8DC8
+#define GL_INT_SAMPLER_1D_EXT 0x8DC9
+#define GL_INT_SAMPLER_2D_EXT 0x8DCA
+#define GL_INT_SAMPLER_3D_EXT 0x8DCB
+#define GL_INT_SAMPLER_CUBE_EXT 0x8DCC
+#define GL_INT_SAMPLER_2D_RECT_EXT 0x8DCD
+#define GL_INT_SAMPLER_1D_ARRAY_EXT 0x8DCE
+#define GL_INT_SAMPLER_2D_ARRAY_EXT 0x8DCF
+#define GL_INT_SAMPLER_BUFFER_EXT 0x8DD0
+#define GL_UNSIGNED_INT_SAMPLER_1D_EXT 0x8DD1
+#define GL_UNSIGNED_INT_SAMPLER_2D_EXT 0x8DD2
+#define GL_UNSIGNED_INT_SAMPLER_3D_EXT 0x8DD3
+#define GL_UNSIGNED_INT_SAMPLER_CUBE_EXT 0x8DD4
+#define GL_UNSIGNED_INT_SAMPLER_2D_RECT_EXT 0x8DD5
+#define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY_EXT 0x8DD6
+#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY_EXT 0x8DD7
+#define GL_UNSIGNED_INT_SAMPLER_BUFFER_EXT 0x8DD8
+#endif
+
+#ifndef GL_EXT_draw_instanced
+#endif
+
+#ifndef GL_EXT_packed_float
+#define GL_R11F_G11F_B10F_EXT 0x8C3A
+#define GL_UNSIGNED_INT_10F_11F_11F_REV_EXT 0x8C3B
+#define GL_RGBA_SIGNED_COMPONENTS_EXT 0x8C3C
+#endif
+
+#ifndef GL_EXT_texture_array
+#define GL_TEXTURE_1D_ARRAY_EXT 0x8C18
+#define GL_PROXY_TEXTURE_1D_ARRAY_EXT 0x8C19
+#define GL_TEXTURE_2D_ARRAY_EXT 0x8C1A
+#define GL_PROXY_TEXTURE_2D_ARRAY_EXT 0x8C1B
+#define GL_TEXTURE_BINDING_1D_ARRAY_EXT 0x8C1C
+#define GL_TEXTURE_BINDING_2D_ARRAY_EXT 0x8C1D
+#define GL_MAX_ARRAY_TEXTURE_LAYERS_EXT 0x88FF
+#define GL_COMPARE_REF_DEPTH_TO_TEXTURE_EXT 0x884E
+/* reuse GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT */
+#endif
+
+#ifndef GL_EXT_texture_buffer_object
+#define GL_TEXTURE_BUFFER_EXT 0x8C2A
+#define GL_MAX_TEXTURE_BUFFER_SIZE_EXT 0x8C2B
+#define GL_TEXTURE_BINDING_BUFFER_EXT 0x8C2C
+#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_EXT 0x8C2D
+#define GL_TEXTURE_BUFFER_FORMAT_EXT 0x8C2E
+#endif
+
+#ifndef GL_EXT_texture_compression_latc
+#define GL_COMPRESSED_LUMINANCE_LATC1_EXT 0x8C70
+#define GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT 0x8C71
+#define GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT 0x8C72
+#define GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT 0x8C73
+#endif
+
+#ifndef GL_EXT_texture_compression_rgtc
+#define GL_COMPRESSED_RED_RGTC1_EXT 0x8DBB
+#define GL_COMPRESSED_SIGNED_RED_RGTC1_EXT 0x8DBC
+#define GL_COMPRESSED_RED_GREEN_RGTC2_EXT 0x8DBD
+#define GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT 0x8DBE
+#endif
+
+#ifndef GL_EXT_texture_shared_exponent
+#define GL_RGB9_E5_EXT 0x8C3D
+#define GL_UNSIGNED_INT_5_9_9_9_REV_EXT 0x8C3E
+#define GL_TEXTURE_SHARED_SIZE_EXT 0x8C3F
+#endif
+
+#ifndef GL_NV_depth_buffer_float
+#define GL_DEPTH_COMPONENT32F_NV 0x8DAB
+#define GL_DEPTH32F_STENCIL8_NV 0x8DAC
+#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV_NV 0x8DAD
+#define GL_DEPTH_BUFFER_FLOAT_MODE_NV 0x8DAF
+#endif
+
+#ifndef GL_NV_fragment_program4
+#endif
+
+#ifndef GL_NV_framebuffer_multisample_coverage
+#define GL_RENDERBUFFER_COVERAGE_SAMPLES_NV 0x8CAB
+#define GL_RENDERBUFFER_COLOR_SAMPLES_NV 0x8E10
+#define GL_MAX_MULTISAMPLE_COVERAGE_MODES_NV 0x8E11
+#define GL_MULTISAMPLE_COVERAGE_MODES_NV 0x8E12
+#endif
+
+#ifndef GL_EXT_framebuffer_sRGB
+#define GL_FRAMEBUFFER_SRGB_EXT 0x8DB9
+#define GL_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x8DBA
+#endif
+
+#ifndef GL_NV_geometry_shader4
+#endif
+
+#ifndef GL_NV_parameter_buffer_object
+#define GL_MAX_PROGRAM_PARAMETER_BUFFER_BINDINGS_NV 0x8DA0
+#define GL_MAX_PROGRAM_PARAMETER_BUFFER_SIZE_NV 0x8DA1
+#define GL_VERTEX_PROGRAM_PARAMETER_BUFFER_NV 0x8DA2
+#define GL_GEOMETRY_PROGRAM_PARAMETER_BUFFER_NV 0x8DA3
+#define GL_FRAGMENT_PROGRAM_PARAMETER_BUFFER_NV 0x8DA4
+#endif
+
+#ifndef GL_EXT_draw_buffers2
+#endif
+
+#ifndef GL_NV_transform_feedback
+#define GL_BACK_PRIMARY_COLOR_NV 0x8C77
+#define GL_BACK_SECONDARY_COLOR_NV 0x8C78
+#define GL_TEXTURE_COORD_NV 0x8C79
+#define GL_CLIP_DISTANCE_NV 0x8C7A
+#define GL_VERTEX_ID_NV 0x8C7B
+#define GL_PRIMITIVE_ID_NV 0x8C7C
+#define GL_GENERIC_ATTRIB_NV 0x8C7D
+#define GL_TRANSFORM_FEEDBACK_ATTRIBS_NV 0x8C7E
+#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE_NV 0x8C7F
+#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_NV 0x8C80
+#define GL_ACTIVE_VARYINGS_NV 0x8C81
+#define GL_ACTIVE_VARYING_MAX_LENGTH_NV 0x8C82
+#define GL_TRANSFORM_FEEDBACK_VARYINGS_NV 0x8C83
+#define GL_TRANSFORM_FEEDBACK_BUFFER_START_NV 0x8C84
+#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE_NV 0x8C85
+#define GL_TRANSFORM_FEEDBACK_RECORD_NV 0x8C86
+#define GL_PRIMITIVES_GENERATED_NV 0x8C87
+#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_NV 0x8C88
+#define GL_RASTERIZER_DISCARD_NV 0x8C89
+#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_ATTRIBS_NV 0x8C8A
+#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_NV 0x8C8B
+#define GL_INTERLEAVED_ATTRIBS_NV 0x8C8C
+#define GL_SEPARATE_ATTRIBS_NV 0x8C8D
+#define GL_TRANSFORM_FEEDBACK_BUFFER_NV 0x8C8E
+#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_NV 0x8C8F
+#define GL_LAYER_NV 0x8DAA
+#define GL_NEXT_BUFFER_NV -2
+#define GL_SKIP_COMPONENTS4_NV -3
+#define GL_SKIP_COMPONENTS3_NV -4
+#define GL_SKIP_COMPONENTS2_NV -5
+#define GL_SKIP_COMPONENTS1_NV -6
+#endif
+
+#ifndef GL_EXT_bindable_uniform
+#define GL_MAX_VERTEX_BINDABLE_UNIFORMS_EXT 0x8DE2
+#define GL_MAX_FRAGMENT_BINDABLE_UNIFORMS_EXT 0x8DE3
+#define GL_MAX_GEOMETRY_BINDABLE_UNIFORMS_EXT 0x8DE4
+#define GL_MAX_BINDABLE_UNIFORM_SIZE_EXT 0x8DED
+#define GL_UNIFORM_BUFFER_EXT 0x8DEE
+#define GL_UNIFORM_BUFFER_BINDING_EXT 0x8DEF
+#endif
+
+#ifndef GL_EXT_texture_integer
+#define GL_RGBA32UI_EXT 0x8D70
+#define GL_RGB32UI_EXT 0x8D71
+#define GL_ALPHA32UI_EXT 0x8D72
+#define GL_INTENSITY32UI_EXT 0x8D73
+#define GL_LUMINANCE32UI_EXT 0x8D74
+#define GL_LUMINANCE_ALPHA32UI_EXT 0x8D75
+#define GL_RGBA16UI_EXT 0x8D76
+#define GL_RGB16UI_EXT 0x8D77
+#define GL_ALPHA16UI_EXT 0x8D78
+#define GL_INTENSITY16UI_EXT 0x8D79
+#define GL_LUMINANCE16UI_EXT 0x8D7A
+#define GL_LUMINANCE_ALPHA16UI_EXT 0x8D7B
+#define GL_RGBA8UI_EXT 0x8D7C
+#define GL_RGB8UI_EXT 0x8D7D
+#define GL_ALPHA8UI_EXT 0x8D7E
+#define GL_INTENSITY8UI_EXT 0x8D7F
+#define GL_LUMINANCE8UI_EXT 0x8D80
+#define GL_LUMINANCE_ALPHA8UI_EXT 0x8D81
+#define GL_RGBA32I_EXT 0x8D82
+#define GL_RGB32I_EXT 0x8D83
+#define GL_ALPHA32I_EXT 0x8D84
+#define GL_INTENSITY32I_EXT 0x8D85
+#define GL_LUMINANCE32I_EXT 0x8D86
+#define GL_LUMINANCE_ALPHA32I_EXT 0x8D87
+#define GL_RGBA16I_EXT 0x8D88
+#define GL_RGB16I_EXT 0x8D89
+#define GL_ALPHA16I_EXT 0x8D8A
+#define GL_INTENSITY16I_EXT 0x8D8B
+#define GL_LUMINANCE16I_EXT 0x8D8C
+#define GL_LUMINANCE_ALPHA16I_EXT 0x8D8D
+#define GL_RGBA8I_EXT 0x8D8E
+#define GL_RGB8I_EXT 0x8D8F
+#define GL_ALPHA8I_EXT 0x8D90
+#define GL_INTENSITY8I_EXT 0x8D91
+#define GL_LUMINANCE8I_EXT 0x8D92
+#define GL_LUMINANCE_ALPHA8I_EXT 0x8D93
+#define GL_RED_INTEGER_EXT 0x8D94
+#define GL_GREEN_INTEGER_EXT 0x8D95
+#define GL_BLUE_INTEGER_EXT 0x8D96
+#define GL_ALPHA_INTEGER_EXT 0x8D97
+#define GL_RGB_INTEGER_EXT 0x8D98
+#define GL_RGBA_INTEGER_EXT 0x8D99
+#define GL_BGR_INTEGER_EXT 0x8D9A
+#define GL_BGRA_INTEGER_EXT 0x8D9B
+#define GL_LUMINANCE_INTEGER_EXT 0x8D9C
+#define GL_LUMINANCE_ALPHA_INTEGER_EXT 0x8D9D
+#define GL_RGBA_INTEGER_MODE_EXT 0x8D9E
+#endif
+
+#ifndef GL_GREMEDY_frame_terminator
+#endif
+
+#ifndef GL_NV_conditional_render
+#define GL_QUERY_WAIT_NV 0x8E13
+#define GL_QUERY_NO_WAIT_NV 0x8E14
+#define GL_QUERY_BY_REGION_WAIT_NV 0x8E15
+#define GL_QUERY_BY_REGION_NO_WAIT_NV 0x8E16
+#endif
+
+#ifndef GL_NV_present_video
+#define GL_FRAME_NV 0x8E26
+#define GL_FIELDS_NV 0x8E27
+#define GL_CURRENT_TIME_NV 0x8E28
+#define GL_NUM_FILL_STREAMS_NV 0x8E29
+#define GL_PRESENT_TIME_NV 0x8E2A
+#define GL_PRESENT_DURATION_NV 0x8E2B
+#endif
+
+#ifndef GL_EXT_transform_feedback
+#define GL_TRANSFORM_FEEDBACK_BUFFER_EXT 0x8C8E
+#define GL_TRANSFORM_FEEDBACK_BUFFER_START_EXT 0x8C84
+#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE_EXT 0x8C85
+#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_EXT 0x8C8F
+#define GL_INTERLEAVED_ATTRIBS_EXT 0x8C8C
+#define GL_SEPARATE_ATTRIBS_EXT 0x8C8D
+#define GL_PRIMITIVES_GENERATED_EXT 0x8C87
+#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_EXT 0x8C88
+#define GL_RASTERIZER_DISCARD_EXT 0x8C89
+#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_EXT 0x8C8A
+#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_EXT 0x8C8B
+#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_EXT 0x8C80
+#define GL_TRANSFORM_FEEDBACK_VARYINGS_EXT 0x8C83
+#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE_EXT 0x8C7F
+#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH_EXT 0x8C76
+#endif
+
+#ifndef GL_EXT_direct_state_access
+#define GL_PROGRAM_MATRIX_EXT 0x8E2D
+#define GL_TRANSPOSE_PROGRAM_MATRIX_EXT 0x8E2E
+#define GL_PROGRAM_MATRIX_STACK_DEPTH_EXT 0x8E2F
+#endif
+
+#ifndef GL_EXT_vertex_array_bgra
+/* reuse GL_BGRA */
+#endif
+
+#ifndef GL_EXT_texture_swizzle
+#define GL_TEXTURE_SWIZZLE_R_EXT 0x8E42
+#define GL_TEXTURE_SWIZZLE_G_EXT 0x8E43
+#define GL_TEXTURE_SWIZZLE_B_EXT 0x8E44
+#define GL_TEXTURE_SWIZZLE_A_EXT 0x8E45
+#define GL_TEXTURE_SWIZZLE_RGBA_EXT 0x8E46
+#endif
+
+#ifndef GL_NV_explicit_multisample
+#define GL_SAMPLE_POSITION_NV 0x8E50
+#define GL_SAMPLE_MASK_NV 0x8E51
+#define GL_SAMPLE_MASK_VALUE_NV 0x8E52
+#define GL_TEXTURE_BINDING_RENDERBUFFER_NV 0x8E53
+#define GL_TEXTURE_RENDERBUFFER_DATA_STORE_BINDING_NV 0x8E54
+#define GL_TEXTURE_RENDERBUFFER_NV 0x8E55
+#define GL_SAMPLER_RENDERBUFFER_NV 0x8E56
+#define GL_INT_SAMPLER_RENDERBUFFER_NV 0x8E57
+#define GL_UNSIGNED_INT_SAMPLER_RENDERBUFFER_NV 0x8E58
+#define GL_MAX_SAMPLE_MASK_WORDS_NV 0x8E59
+#endif
+
+#ifndef GL_NV_transform_feedback2
+#define GL_TRANSFORM_FEEDBACK_NV 0x8E22
+#define GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED_NV 0x8E23
+#define GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE_NV 0x8E24
+#define GL_TRANSFORM_FEEDBACK_BINDING_NV 0x8E25
+#endif
+
+#ifndef GL_ATI_meminfo
+#define GL_VBO_FREE_MEMORY_ATI 0x87FB
+#define GL_TEXTURE_FREE_MEMORY_ATI 0x87FC
+#define GL_RENDERBUFFER_FREE_MEMORY_ATI 0x87FD
+#endif
+
+#ifndef GL_AMD_performance_monitor
+#define GL_COUNTER_TYPE_AMD 0x8BC0
+#define GL_COUNTER_RANGE_AMD 0x8BC1
+#define GL_UNSIGNED_INT64_AMD 0x8BC2
+#define GL_PERCENTAGE_AMD 0x8BC3
+#define GL_PERFMON_RESULT_AVAILABLE_AMD 0x8BC4
+#define GL_PERFMON_RESULT_SIZE_AMD 0x8BC5
+#define GL_PERFMON_RESULT_AMD 0x8BC6
+#endif
+
+#ifndef GL_AMD_texture_texture4
+#endif
+
+#ifndef GL_AMD_vertex_shader_tesselator
+#define GL_SAMPLER_BUFFER_AMD 0x9001
+#define GL_INT_SAMPLER_BUFFER_AMD 0x9002
+#define GL_UNSIGNED_INT_SAMPLER_BUFFER_AMD 0x9003
+#define GL_TESSELLATION_MODE_AMD 0x9004
+#define GL_TESSELLATION_FACTOR_AMD 0x9005
+#define GL_DISCRETE_AMD 0x9006
+#define GL_CONTINUOUS_AMD 0x9007
+#endif
+
+#ifndef GL_EXT_provoking_vertex
+#define GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION_EXT 0x8E4C
+#define GL_FIRST_VERTEX_CONVENTION_EXT 0x8E4D
+#define GL_LAST_VERTEX_CONVENTION_EXT 0x8E4E
+#define GL_PROVOKING_VERTEX_EXT 0x8E4F
+#endif
+
+#ifndef GL_EXT_texture_snorm
+#define GL_ALPHA_SNORM 0x9010
+#define GL_LUMINANCE_SNORM 0x9011
+#define GL_LUMINANCE_ALPHA_SNORM 0x9012
+#define GL_INTENSITY_SNORM 0x9013
+#define GL_ALPHA8_SNORM 0x9014
+#define GL_LUMINANCE8_SNORM 0x9015
+#define GL_LUMINANCE8_ALPHA8_SNORM 0x9016
+#define GL_INTENSITY8_SNORM 0x9017
+#define GL_ALPHA16_SNORM 0x9018
+#define GL_LUMINANCE16_SNORM 0x9019
+#define GL_LUMINANCE16_ALPHA16_SNORM 0x901A
+#define GL_INTENSITY16_SNORM 0x901B
+/* reuse GL_RED_SNORM */
+/* reuse GL_RG_SNORM */
+/* reuse GL_RGB_SNORM */
+/* reuse GL_RGBA_SNORM */
+/* reuse GL_R8_SNORM */
+/* reuse GL_RG8_SNORM */
+/* reuse GL_RGB8_SNORM */
+/* reuse GL_RGBA8_SNORM */
+/* reuse GL_R16_SNORM */
+/* reuse GL_RG16_SNORM */
+/* reuse GL_RGB16_SNORM */
+/* reuse GL_RGBA16_SNORM */
+/* reuse GL_SIGNED_NORMALIZED */
+#endif
+
+#ifndef GL_AMD_draw_buffers_blend
+#endif
+
+#ifndef GL_APPLE_texture_range
+#define GL_TEXTURE_RANGE_LENGTH_APPLE 0x85B7
+#define GL_TEXTURE_RANGE_POINTER_APPLE 0x85B8
+#define GL_TEXTURE_STORAGE_HINT_APPLE 0x85BC
+#define GL_STORAGE_PRIVATE_APPLE 0x85BD
+/* reuse GL_STORAGE_CACHED_APPLE */
+/* reuse GL_STORAGE_SHARED_APPLE */
+#endif
+
+#ifndef GL_APPLE_float_pixels
+#define GL_HALF_APPLE 0x140B
+#define GL_RGBA_FLOAT32_APPLE 0x8814
+#define GL_RGB_FLOAT32_APPLE 0x8815
+#define GL_ALPHA_FLOAT32_APPLE 0x8816
+#define GL_INTENSITY_FLOAT32_APPLE 0x8817
+#define GL_LUMINANCE_FLOAT32_APPLE 0x8818
+#define GL_LUMINANCE_ALPHA_FLOAT32_APPLE 0x8819
+#define GL_RGBA_FLOAT16_APPLE 0x881A
+#define GL_RGB_FLOAT16_APPLE 0x881B
+#define GL_ALPHA_FLOAT16_APPLE 0x881C
+#define GL_INTENSITY_FLOAT16_APPLE 0x881D
+#define GL_LUMINANCE_FLOAT16_APPLE 0x881E
+#define GL_LUMINANCE_ALPHA_FLOAT16_APPLE 0x881F
+#define GL_COLOR_FLOAT_APPLE 0x8A0F
+#endif
+
+#ifndef GL_APPLE_vertex_program_evaluators
+#define GL_VERTEX_ATTRIB_MAP1_APPLE 0x8A00
+#define GL_VERTEX_ATTRIB_MAP2_APPLE 0x8A01
+#define GL_VERTEX_ATTRIB_MAP1_SIZE_APPLE 0x8A02
+#define GL_VERTEX_ATTRIB_MAP1_COEFF_APPLE 0x8A03
+#define GL_VERTEX_ATTRIB_MAP1_ORDER_APPLE 0x8A04
+#define GL_VERTEX_ATTRIB_MAP1_DOMAIN_APPLE 0x8A05
+#define GL_VERTEX_ATTRIB_MAP2_SIZE_APPLE 0x8A06
+#define GL_VERTEX_ATTRIB_MAP2_COEFF_APPLE 0x8A07
+#define GL_VERTEX_ATTRIB_MAP2_ORDER_APPLE 0x8A08
+#define GL_VERTEX_ATTRIB_MAP2_DOMAIN_APPLE 0x8A09
+#endif
+
+#ifndef GL_APPLE_aux_depth_stencil
+#define GL_AUX_DEPTH_STENCIL_APPLE 0x8A14
+#endif
+
+#ifndef GL_APPLE_object_purgeable
+#define GL_BUFFER_OBJECT_APPLE 0x85B3
+#define GL_RELEASED_APPLE 0x8A19
+#define GL_VOLATILE_APPLE 0x8A1A
+#define GL_RETAINED_APPLE 0x8A1B
+#define GL_UNDEFINED_APPLE 0x8A1C
+#define GL_PURGEABLE_APPLE 0x8A1D
+#endif
+
+#ifndef GL_APPLE_row_bytes
+#define GL_PACK_ROW_BYTES_APPLE 0x8A15
+#define GL_UNPACK_ROW_BYTES_APPLE 0x8A16
+#endif
+
+#ifndef GL_APPLE_rgb_422
+#define GL_RGB_422_APPLE 0x8A1F
+/* reuse GL_UNSIGNED_SHORT_8_8_APPLE */
+/* reuse GL_UNSIGNED_SHORT_8_8_REV_APPLE */
+#endif
+
+#ifndef GL_NV_video_capture
+#define GL_VIDEO_BUFFER_NV 0x9020
+#define GL_VIDEO_BUFFER_BINDING_NV 0x9021
+#define GL_FIELD_UPPER_NV 0x9022
+#define GL_FIELD_LOWER_NV 0x9023
+#define GL_NUM_VIDEO_CAPTURE_STREAMS_NV 0x9024
+#define GL_NEXT_VIDEO_CAPTURE_BUFFER_STATUS_NV 0x9025
+#define GL_VIDEO_CAPTURE_TO_422_SUPPORTED_NV 0x9026
+#define GL_LAST_VIDEO_CAPTURE_STATUS_NV 0x9027
+#define GL_VIDEO_BUFFER_PITCH_NV 0x9028
+#define GL_VIDEO_COLOR_CONVERSION_MATRIX_NV 0x9029
+#define GL_VIDEO_COLOR_CONVERSION_MAX_NV 0x902A
+#define GL_VIDEO_COLOR_CONVERSION_MIN_NV 0x902B
+#define GL_VIDEO_COLOR_CONVERSION_OFFSET_NV 0x902C
+#define GL_VIDEO_BUFFER_INTERNAL_FORMAT_NV 0x902D
+#define GL_PARTIAL_SUCCESS_NV 0x902E
+#define GL_SUCCESS_NV 0x902F
+#define GL_FAILURE_NV 0x9030
+#define GL_YCBYCR8_422_NV 0x9031
+#define GL_YCBAYCR8A_4224_NV 0x9032
+#define GL_Z6Y10Z6CB10Z6Y10Z6CR10_422_NV 0x9033
+#define GL_Z6Y10Z6CB10Z6A10Z6Y10Z6CR10Z6A10_4224_NV 0x9034
+#define GL_Z4Y12Z4CB12Z4Y12Z4CR12_422_NV 0x9035
+#define GL_Z4Y12Z4CB12Z4A12Z4Y12Z4CR12Z4A12_4224_NV 0x9036
+#define GL_Z4Y12Z4CB12Z4CR12_444_NV 0x9037
+#define GL_VIDEO_CAPTURE_FRAME_WIDTH_NV 0x9038
+#define GL_VIDEO_CAPTURE_FRAME_HEIGHT_NV 0x9039
+#define GL_VIDEO_CAPTURE_FIELD_UPPER_HEIGHT_NV 0x903A
+#define GL_VIDEO_CAPTURE_FIELD_LOWER_HEIGHT_NV 0x903B
+#define GL_VIDEO_CAPTURE_SURFACE_ORIGIN_NV 0x903C
+#endif
+
+#ifndef GL_NV_copy_image
+#endif
+
+#ifndef GL_EXT_separate_shader_objects
+#define GL_ACTIVE_PROGRAM_EXT 0x8B8D
+#endif
+
+#ifndef GL_NV_parameter_buffer_object2
+#endif
+
+#ifndef GL_NV_shader_buffer_load
+#define GL_BUFFER_GPU_ADDRESS_NV 0x8F1D
+#define GL_GPU_ADDRESS_NV 0x8F34
+#define GL_MAX_SHADER_BUFFER_ADDRESS_NV 0x8F35
+#endif
+
+#ifndef GL_NV_vertex_buffer_unified_memory
+#define GL_VERTEX_ATTRIB_ARRAY_UNIFIED_NV 0x8F1E
+#define GL_ELEMENT_ARRAY_UNIFIED_NV 0x8F1F
+#define GL_VERTEX_ATTRIB_ARRAY_ADDRESS_NV 0x8F20
+#define GL_VERTEX_ARRAY_ADDRESS_NV 0x8F21
+#define GL_NORMAL_ARRAY_ADDRESS_NV 0x8F22
+#define GL_COLOR_ARRAY_ADDRESS_NV 0x8F23
+#define GL_INDEX_ARRAY_ADDRESS_NV 0x8F24
+#define GL_TEXTURE_COORD_ARRAY_ADDRESS_NV 0x8F25
+#define GL_EDGE_FLAG_ARRAY_ADDRESS_NV 0x8F26
+#define GL_SECONDARY_COLOR_ARRAY_ADDRESS_NV 0x8F27
+#define GL_FOG_COORD_ARRAY_ADDRESS_NV 0x8F28
+#define GL_ELEMENT_ARRAY_ADDRESS_NV 0x8F29
+#define GL_VERTEX_ATTRIB_ARRAY_LENGTH_NV 0x8F2A
+#define GL_VERTEX_ARRAY_LENGTH_NV 0x8F2B
+#define GL_NORMAL_ARRAY_LENGTH_NV 0x8F2C
+#define GL_COLOR_ARRAY_LENGTH_NV 0x8F2D
+#define GL_INDEX_ARRAY_LENGTH_NV 0x8F2E
+#define GL_TEXTURE_COORD_ARRAY_LENGTH_NV 0x8F2F
+#define GL_EDGE_FLAG_ARRAY_LENGTH_NV 0x8F30
+#define GL_SECONDARY_COLOR_ARRAY_LENGTH_NV 0x8F31
+#define GL_FOG_COORD_ARRAY_LENGTH_NV 0x8F32
+#define GL_ELEMENT_ARRAY_LENGTH_NV 0x8F33
+#define GL_DRAW_INDIRECT_UNIFIED_NV 0x8F40
+#define GL_DRAW_INDIRECT_ADDRESS_NV 0x8F41
+#define GL_DRAW_INDIRECT_LENGTH_NV 0x8F42
+#endif
+
+#ifndef GL_NV_texture_barrier
+#endif
+
+#ifndef GL_AMD_shader_stencil_export
+#endif
+
+#ifndef GL_AMD_seamless_cubemap_per_texture
+/* reuse GL_TEXTURE_CUBE_MAP_SEAMLESS */
+#endif
+
+#ifndef GL_AMD_conservative_depth
+#endif
+
+#ifndef GL_EXT_shader_image_load_store
+#define GL_MAX_IMAGE_UNITS_EXT 0x8F38
+#define GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS_EXT 0x8F39
+#define GL_IMAGE_BINDING_NAME_EXT 0x8F3A
+#define GL_IMAGE_BINDING_LEVEL_EXT 0x8F3B
+#define GL_IMAGE_BINDING_LAYERED_EXT 0x8F3C
+#define GL_IMAGE_BINDING_LAYER_EXT 0x8F3D
+#define GL_IMAGE_BINDING_ACCESS_EXT 0x8F3E
+#define GL_IMAGE_1D_EXT 0x904C
+#define GL_IMAGE_2D_EXT 0x904D
+#define GL_IMAGE_3D_EXT 0x904E
+#define GL_IMAGE_2D_RECT_EXT 0x904F
+#define GL_IMAGE_CUBE_EXT 0x9050
+#define GL_IMAGE_BUFFER_EXT 0x9051
+#define GL_IMAGE_1D_ARRAY_EXT 0x9052
+#define GL_IMAGE_2D_ARRAY_EXT 0x9053
+#define GL_IMAGE_CUBE_MAP_ARRAY_EXT 0x9054
+#define GL_IMAGE_2D_MULTISAMPLE_EXT 0x9055
+#define GL_IMAGE_2D_MULTISAMPLE_ARRAY_EXT 0x9056
+#define GL_INT_IMAGE_1D_EXT 0x9057
+#define GL_INT_IMAGE_2D_EXT 0x9058
+#define GL_INT_IMAGE_3D_EXT 0x9059
+#define GL_INT_IMAGE_2D_RECT_EXT 0x905A
+#define GL_INT_IMAGE_CUBE_EXT 0x905B
+#define GL_INT_IMAGE_BUFFER_EXT 0x905C
+#define GL_INT_IMAGE_1D_ARRAY_EXT 0x905D
+#define GL_INT_IMAGE_2D_ARRAY_EXT 0x905E
+#define GL_INT_IMAGE_CUBE_MAP_ARRAY_EXT 0x905F
+#define GL_INT_IMAGE_2D_MULTISAMPLE_EXT 0x9060
+#define GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY_EXT 0x9061
+#define GL_UNSIGNED_INT_IMAGE_1D_EXT 0x9062
+#define GL_UNSIGNED_INT_IMAGE_2D_EXT 0x9063
+#define GL_UNSIGNED_INT_IMAGE_3D_EXT 0x9064
+#define GL_UNSIGNED_INT_IMAGE_2D_RECT_EXT 0x9065
+#define GL_UNSIGNED_INT_IMAGE_CUBE_EXT 0x9066
+#define GL_UNSIGNED_INT_IMAGE_BUFFER_EXT 0x9067
+#define GL_UNSIGNED_INT_IMAGE_1D_ARRAY_EXT 0x9068
+#define GL_UNSIGNED_INT_IMAGE_2D_ARRAY_EXT 0x9069
+#define GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY_EXT 0x906A
+#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_EXT 0x906B
+#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY_EXT 0x906C
+#define GL_MAX_IMAGE_SAMPLES_EXT 0x906D
+#define GL_IMAGE_BINDING_FORMAT_EXT 0x906E
+#define GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT_EXT 0x00000001
+#define GL_ELEMENT_ARRAY_BARRIER_BIT_EXT 0x00000002
+#define GL_UNIFORM_BARRIER_BIT_EXT 0x00000004
+#define GL_TEXTURE_FETCH_BARRIER_BIT_EXT 0x00000008
+#define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT_EXT 0x00000020
+#define GL_COMMAND_BARRIER_BIT_EXT 0x00000040
+#define GL_PIXEL_BUFFER_BARRIER_BIT_EXT 0x00000080
+#define GL_TEXTURE_UPDATE_BARRIER_BIT_EXT 0x00000100
+#define GL_BUFFER_UPDATE_BARRIER_BIT_EXT 0x00000200
+#define GL_FRAMEBUFFER_BARRIER_BIT_EXT 0x00000400
+#define GL_TRANSFORM_FEEDBACK_BARRIER_BIT_EXT 0x00000800
+#define GL_ATOMIC_COUNTER_BARRIER_BIT_EXT 0x00001000
+#define GL_ALL_BARRIER_BITS_EXT 0xFFFFFFFF
+#endif
+
+#ifndef GL_EXT_vertex_attrib_64bit
+/* reuse GL_DOUBLE */
+#define GL_DOUBLE_VEC2_EXT 0x8FFC
+#define GL_DOUBLE_VEC3_EXT 0x8FFD
+#define GL_DOUBLE_VEC4_EXT 0x8FFE
+#define GL_DOUBLE_MAT2_EXT 0x8F46
+#define GL_DOUBLE_MAT3_EXT 0x8F47
+#define GL_DOUBLE_MAT4_EXT 0x8F48
+#define GL_DOUBLE_MAT2x3_EXT 0x8F49
+#define GL_DOUBLE_MAT2x4_EXT 0x8F4A
+#define GL_DOUBLE_MAT3x2_EXT 0x8F4B
+#define GL_DOUBLE_MAT3x4_EXT 0x8F4C
+#define GL_DOUBLE_MAT4x2_EXT 0x8F4D
+#define GL_DOUBLE_MAT4x3_EXT 0x8F4E
+#endif
+
+#ifndef GL_NV_gpu_program5
+#define GL_MAX_GEOMETRY_PROGRAM_INVOCATIONS_NV 0x8E5A
+#define GL_MIN_FRAGMENT_INTERPOLATION_OFFSET_NV 0x8E5B
+#define GL_MAX_FRAGMENT_INTERPOLATION_OFFSET_NV 0x8E5C
+#define GL_FRAGMENT_PROGRAM_INTERPOLATION_OFFSET_BITS_NV 0x8E5D
+#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET_NV 0x8E5E
+#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET_NV 0x8E5F
+#define GL_MAX_PROGRAM_SUBROUTINE_PARAMETERS_NV 0x8F44
+#define GL_MAX_PROGRAM_SUBROUTINE_NUM_NV 0x8F45
+#endif
+
+#ifndef GL_NV_gpu_shader5
+#define GL_INT64_NV 0x140E
+#define GL_UNSIGNED_INT64_NV 0x140F
+#define GL_INT8_NV 0x8FE0
+#define GL_INT8_VEC2_NV 0x8FE1
+#define GL_INT8_VEC3_NV 0x8FE2
+#define GL_INT8_VEC4_NV 0x8FE3
+#define GL_INT16_NV 0x8FE4
+#define GL_INT16_VEC2_NV 0x8FE5
+#define GL_INT16_VEC3_NV 0x8FE6
+#define GL_INT16_VEC4_NV 0x8FE7
+#define GL_INT64_VEC2_NV 0x8FE9
+#define GL_INT64_VEC3_NV 0x8FEA
+#define GL_INT64_VEC4_NV 0x8FEB
+#define GL_UNSIGNED_INT8_NV 0x8FEC
+#define GL_UNSIGNED_INT8_VEC2_NV 0x8FED
+#define GL_UNSIGNED_INT8_VEC3_NV 0x8FEE
+#define GL_UNSIGNED_INT8_VEC4_NV 0x8FEF
+#define GL_UNSIGNED_INT16_NV 0x8FF0
+#define GL_UNSIGNED_INT16_VEC2_NV 0x8FF1
+#define GL_UNSIGNED_INT16_VEC3_NV 0x8FF2
+#define GL_UNSIGNED_INT16_VEC4_NV 0x8FF3
+#define GL_UNSIGNED_INT64_VEC2_NV 0x8FF5
+#define GL_UNSIGNED_INT64_VEC3_NV 0x8FF6
+#define GL_UNSIGNED_INT64_VEC4_NV 0x8FF7
+#define GL_FLOAT16_NV 0x8FF8
+#define GL_FLOAT16_VEC2_NV 0x8FF9
+#define GL_FLOAT16_VEC3_NV 0x8FFA
+#define GL_FLOAT16_VEC4_NV 0x8FFB
+/* reuse GL_PATCHES */
+#endif
+
+#ifndef GL_NV_shader_buffer_store
+#define GL_SHADER_GLOBAL_ACCESS_BARRIER_BIT_NV 0x00000010
+/* reuse GL_READ_WRITE */
+/* reuse GL_WRITE_ONLY */
+#endif
+
+#ifndef GL_NV_tessellation_program5
+#define GL_MAX_PROGRAM_PATCH_ATTRIBS_NV 0x86D8
+#define GL_TESS_CONTROL_PROGRAM_NV 0x891E
+#define GL_TESS_EVALUATION_PROGRAM_NV 0x891F
+#define GL_TESS_CONTROL_PROGRAM_PARAMETER_BUFFER_NV 0x8C74
+#define GL_TESS_EVALUATION_PROGRAM_PARAMETER_BUFFER_NV 0x8C75
+#endif
+
+#ifndef GL_NV_vertex_attrib_integer_64bit
+/* reuse GL_INT64_NV */
+/* reuse GL_UNSIGNED_INT64_NV */
+#endif
+
+#ifndef GL_NV_multisample_coverage
+#define GL_COVERAGE_SAMPLES_NV 0x80A9
+#define GL_COLOR_SAMPLES_NV 0x8E20
+#endif
+
+#ifndef GL_AMD_name_gen_delete
+#define GL_DATA_BUFFER_AMD 0x9151
+#define GL_PERFORMANCE_MONITOR_AMD 0x9152
+#define GL_QUERY_OBJECT_AMD 0x9153
+#define GL_VERTEX_ARRAY_OBJECT_AMD 0x9154
+#define GL_SAMPLER_OBJECT_AMD 0x9155
+#endif
+
+#ifndef GL_AMD_debug_output
+#define GL_MAX_DEBUG_LOGGED_MESSAGES_AMD 0x9144
+#define GL_DEBUG_LOGGED_MESSAGES_AMD 0x9145
+#define GL_DEBUG_SEVERITY_HIGH_AMD 0x9146
+#define GL_DEBUG_SEVERITY_MEDIUM_AMD 0x9147
+#define GL_DEBUG_SEVERITY_LOW_AMD 0x9148
+#define GL_DEBUG_CATEGORY_API_ERROR_AMD 0x9149
+#define GL_DEBUG_CATEGORY_WINDOW_SYSTEM_AMD 0x914A
+#define GL_DEBUG_CATEGORY_DEPRECATION_AMD 0x914B
+#define GL_DEBUG_CATEGORY_UNDEFINED_BEHAVIOR_AMD 0x914C
+#define GL_DEBUG_CATEGORY_PERFORMANCE_AMD 0x914D
+#define GL_DEBUG_CATEGORY_SHADER_COMPILER_AMD 0x914E
+#define GL_DEBUG_CATEGORY_APPLICATION_AMD 0x914F
+#define GL_DEBUG_CATEGORY_OTHER_AMD 0x9150
+#endif
+
+#ifndef GL_NV_vdpau_interop
+#define GL_SURFACE_STATE_NV 0x86EB
+#define GL_SURFACE_REGISTERED_NV 0x86FD
+#define GL_SURFACE_MAPPED_NV 0x8700
+#define GL_WRITE_DISCARD_NV 0x88BE
+#endif
+
+#ifndef GL_AMD_transform_feedback3_lines_triangles
+#endif
+
+#ifndef GL_AMD_depth_clamp_separate
+#define GL_DEPTH_CLAMP_NEAR_AMD 0x901E
+#define GL_DEPTH_CLAMP_FAR_AMD 0x901F
+#endif
+
+#ifndef GL_EXT_texture_sRGB_decode
+#define GL_TEXTURE_SRGB_DECODE_EXT 0x8A48
+#define GL_DECODE_EXT 0x8A49
+#define GL_SKIP_DECODE_EXT 0x8A4A
+#endif
+
+#ifndef GL_NV_texture_multisample
+#define GL_TEXTURE_COVERAGE_SAMPLES_NV 0x9045
+#define GL_TEXTURE_COLOR_SAMPLES_NV 0x9046
+#endif
+
+#ifndef GL_AMD_blend_minmax_factor
+#define GL_FACTOR_MIN_AMD 0x901C
+#define GL_FACTOR_MAX_AMD 0x901D
+#endif
+
+#ifndef GL_AMD_sample_positions
+#define GL_SUBSAMPLE_DISTANCE_AMD 0x883F
+#endif
+
+#ifndef GL_EXT_x11_sync_object
+#define GL_SYNC_X11_FENCE_EXT 0x90E1
+#endif
+
+#ifndef GL_AMD_multi_draw_indirect
+#endif
+
+#ifndef GL_EXT_framebuffer_multisample_blit_scaled
+#define GL_SCALED_RESOLVE_FASTEST_EXT 0x90BA
+#define GL_SCALED_RESOLVE_NICEST_EXT 0x90BB
+#endif
+
+
+/*************************************************************/
+
+#include <stddef.h>
+#ifndef GL_VERSION_2_0
+/* GL type for program/shader text */
+typedef char GLchar;
+#endif
+
+#ifndef GL_VERSION_1_5
+/* GL types for handling large vertex buffer objects */
+typedef ptrdiff_t GLintptr;
+typedef ptrdiff_t GLsizeiptr;
+#endif
+
+#ifndef GL_ARB_vertex_buffer_object
+/* GL types for handling large vertex buffer objects */
+typedef ptrdiff_t GLintptrARB;
+typedef ptrdiff_t GLsizeiptrARB;
+#endif
+
+#ifndef GL_ARB_shader_objects
+/* GL types for program/shader text and shader object handles */
+typedef char GLcharARB;
+typedef unsigned int GLhandleARB;
+#endif
+
+/* GL type for "half" precision (s10e5) float data in host memory */
+#ifndef GL_ARB_half_float_pixel
+typedef unsigned short GLhalfARB;
+#endif
+
+#ifndef GL_NV_half_float
+typedef unsigned short GLhalfNV;
+#endif
+
+#ifndef GLEXT_64_TYPES_DEFINED
+/* This code block is duplicated in glxext.h, so must be protected */
+#define GLEXT_64_TYPES_DEFINED
+/* Define int32_t, int64_t, and uint64_t types for UST/MSC */
+/* (as used in the GL_EXT_timer_query extension). */
+#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+#include <inttypes.h>
+#elif defined(__sun__) || defined(__digital__)
+#include <inttypes.h>
+#if defined(__STDC__)
+#if defined(__arch64__) || defined(_LP64)
+typedef long int int64_t;
+typedef unsigned long int uint64_t;
+#else
+typedef long long int int64_t;
+typedef unsigned long long int uint64_t;
+#endif /* __arch64__ */
+#endif /* __STDC__ */
+#elif defined( __VMS ) || defined(__sgi)
+#include <inttypes.h>
+#elif defined(__SCO__) || defined(__USLC__)
+#include <stdint.h>
+#elif defined(__UNIXOS2__) || defined(__SOL64__)
+typedef long int int32_t;
+typedef long long int int64_t;
+typedef unsigned long long int uint64_t;
+#elif defined(_WIN32) && defined(__GNUC__)
+#include <stdint.h>
+#elif defined(_WIN32)
+typedef __int32 int32_t;
+typedef __int64 int64_t;
+typedef unsigned __int64 uint64_t;
+#else
+/* Fallback if nothing above works */
+#include <inttypes.h>
+#endif
+#endif
+
+#ifndef GL_EXT_timer_query
+typedef int64_t GLint64EXT;
+typedef uint64_t GLuint64EXT;
+#endif
+
+#ifndef GL_ARB_sync
+typedef int64_t GLint64;
+typedef uint64_t GLuint64;
+typedef struct __GLsync *GLsync;
+#endif
+
+#ifndef GL_ARB_cl_event
+/* These incomplete types let us declare types compatible with OpenCL's cl_context and cl_event */
+struct _cl_context;
+struct _cl_event;
+#endif
+
+#ifndef GL_ARB_debug_output
+typedef void (APIENTRY *GLDEBUGPROCARB)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,GLvoid *userParam);
+#endif
+
+#ifndef GL_AMD_debug_output
+typedef void (APIENTRY *GLDEBUGPROCAMD)(GLuint id,GLenum category,GLenum severity,GLsizei length,const GLchar *message,GLvoid *userParam);
+#endif
+
+#ifndef GL_NV_vdpau_interop
+typedef GLintptr GLvdpauSurfaceNV;
+#endif
+
+#ifndef GL_VERSION_1_2
+#define GL_VERSION_1_2 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBlendColor (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+GLAPI void APIENTRY glBlendEquation (GLenum mode);
+GLAPI void APIENTRY glDrawRangeElements (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices);
+GLAPI void APIENTRY glTexImage3D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+GLAPI void APIENTRY glTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels);
+GLAPI void APIENTRY glCopyTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBLENDCOLORPROC) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+typedef void (APIENTRYP PFNGLBLENDEQUATIONPROC) (GLenum mode);
+typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices);
+typedef void (APIENTRYP PFNGLTEXIMAGE3DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (APIENTRYP PFNGLTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+#endif
+
+#ifndef GL_VERSION_1_2_DEPRECATED
+#define GL_VERSION_1_2_DEPRECATED 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glColorTable (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table);
+GLAPI void APIENTRY glColorTableParameterfv (GLenum target, GLenum pname, const GLfloat *params);
+GLAPI void APIENTRY glColorTableParameteriv (GLenum target, GLenum pname, const GLint *params);
+GLAPI void APIENTRY glCopyColorTable (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width);
+GLAPI void APIENTRY glGetColorTable (GLenum target, GLenum format, GLenum type, GLvoid *table);
+GLAPI void APIENTRY glGetColorTableParameterfv (GLenum target, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetColorTableParameteriv (GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glColorSubTable (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data);
+GLAPI void APIENTRY glCopyColorSubTable (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width);
+GLAPI void APIENTRY glConvolutionFilter1D (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *image);
+GLAPI void APIENTRY glConvolutionFilter2D (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image);
+GLAPI void APIENTRY glConvolutionParameterf (GLenum target, GLenum pname, GLfloat params);
+GLAPI void APIENTRY glConvolutionParameterfv (GLenum target, GLenum pname, const GLfloat *params);
+GLAPI void APIENTRY glConvolutionParameteri (GLenum target, GLenum pname, GLint params);
+GLAPI void APIENTRY glConvolutionParameteriv (GLenum target, GLenum pname, const GLint *params);
+GLAPI void APIENTRY glCopyConvolutionFilter1D (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width);
+GLAPI void APIENTRY glCopyConvolutionFilter2D (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height);
+GLAPI void APIENTRY glGetConvolutionFilter (GLenum target, GLenum format, GLenum type, GLvoid *image);
+GLAPI void APIENTRY glGetConvolutionParameterfv (GLenum target, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetConvolutionParameteriv (GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetSeparableFilter (GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span);
+GLAPI void APIENTRY glSeparableFilter2D (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column);
+GLAPI void APIENTRY glGetHistogram (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values);
+GLAPI void APIENTRY glGetHistogramParameterfv (GLenum target, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetHistogramParameteriv (GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetMinmax (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values);
+GLAPI void APIENTRY glGetMinmaxParameterfv (GLenum target, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetMinmaxParameteriv (GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glHistogram (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink);
+GLAPI void APIENTRY glMinmax (GLenum target, GLenum internalformat, GLboolean sink);
+GLAPI void APIENTRY glResetHistogram (GLenum target);
+GLAPI void APIENTRY glResetMinmax (GLenum target);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table);
+typedef void (APIENTRYP PFNGLCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLCOPYCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width);
+typedef void (APIENTRYP PFNGLGETCOLORTABLEPROC) (GLenum target, GLenum format, GLenum type, GLvoid *table);
+typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data);
+typedef void (APIENTRYP PFNGLCOPYCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width);
+typedef void (APIENTRYP PFNGLCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *image);
+typedef void (APIENTRYP PFNGLCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image);
+typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERFPROC) (GLenum target, GLenum pname, GLfloat params);
+typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERIPROC) (GLenum target, GLenum pname, GLint params);
+typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLCOPYCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width);
+typedef void (APIENTRYP PFNGLCOPYCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (APIENTRYP PFNGLGETCONVOLUTIONFILTERPROC) (GLenum target, GLenum format, GLenum type, GLvoid *image);
+typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETSEPARABLEFILTERPROC) (GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span);
+typedef void (APIENTRYP PFNGLSEPARABLEFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column);
+typedef void (APIENTRYP PFNGLGETHISTOGRAMPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values);
+typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETMINMAXPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values);
+typedef void (APIENTRYP PFNGLGETMINMAXPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETMINMAXPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLHISTOGRAMPROC) (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink);
+typedef void (APIENTRYP PFNGLMINMAXPROC) (GLenum target, GLenum internalformat, GLboolean sink);
+typedef void (APIENTRYP PFNGLRESETHISTOGRAMPROC) (GLenum target);
+typedef void (APIENTRYP PFNGLRESETMINMAXPROC) (GLenum target);
+#endif
+
+#ifndef GL_VERSION_1_3
+#define GL_VERSION_1_3 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glActiveTexture (GLenum texture);
+GLAPI void APIENTRY glSampleCoverage (GLclampf value, GLboolean invert);
+GLAPI void APIENTRY glCompressedTexImage3D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data);
+GLAPI void APIENTRY glCompressedTexImage2D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data);
+GLAPI void APIENTRY glCompressedTexImage1D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data);
+GLAPI void APIENTRY glCompressedTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data);
+GLAPI void APIENTRY glCompressedTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data);
+GLAPI void APIENTRY glCompressedTexSubImage1D (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data);
+GLAPI void APIENTRY glGetCompressedTexImage (GLenum target, GLint level, GLvoid *img);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLACTIVETEXTUREPROC) (GLenum texture);
+typedef void (APIENTRYP PFNGLSAMPLECOVERAGEPROC) (GLclampf value, GLboolean invert);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE1DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data);
+typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXIMAGEPROC) (GLenum target, GLint level, GLvoid *img);
+#endif
+
+#ifndef GL_VERSION_1_3_DEPRECATED
+#define GL_VERSION_1_3_DEPRECATED 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glClientActiveTexture (GLenum texture);
+GLAPI void APIENTRY glMultiTexCoord1d (GLenum target, GLdouble s);
+GLAPI void APIENTRY glMultiTexCoord1dv (GLenum target, const GLdouble *v);
+GLAPI void APIENTRY glMultiTexCoord1f (GLenum target, GLfloat s);
+GLAPI void APIENTRY glMultiTexCoord1fv (GLenum target, const GLfloat *v);
+GLAPI void APIENTRY glMultiTexCoord1i (GLenum target, GLint s);
+GLAPI void APIENTRY glMultiTexCoord1iv (GLenum target, const GLint *v);
+GLAPI void APIENTRY glMultiTexCoord1s (GLenum target, GLshort s);
+GLAPI void APIENTRY glMultiTexCoord1sv (GLenum target, const GLshort *v);
+GLAPI void APIENTRY glMultiTexCoord2d (GLenum target, GLdouble s, GLdouble t);
+GLAPI void APIENTRY glMultiTexCoord2dv (GLenum target, const GLdouble *v);
+GLAPI void APIENTRY glMultiTexCoord2f (GLenum target, GLfloat s, GLfloat t);
+GLAPI void APIENTRY glMultiTexCoord2fv (GLenum target, const GLfloat *v);
+GLAPI void APIENTRY glMultiTexCoord2i (GLenum target, GLint s, GLint t);
+GLAPI void APIENTRY glMultiTexCoord2iv (GLenum target, const GLint *v);
+GLAPI void APIENTRY glMultiTexCoord2s (GLenum target, GLshort s, GLshort t);
+GLAPI void APIENTRY glMultiTexCoord2sv (GLenum target, const GLshort *v);
+GLAPI void APIENTRY glMultiTexCoord3d (GLenum target, GLdouble s, GLdouble t, GLdouble r);
+GLAPI void APIENTRY glMultiTexCoord3dv (GLenum target, const GLdouble *v);
+GLAPI void APIENTRY glMultiTexCoord3f (GLenum target, GLfloat s, GLfloat t, GLfloat r);
+GLAPI void APIENTRY glMultiTexCoord3fv (GLenum target, const GLfloat *v);
+GLAPI void APIENTRY glMultiTexCoord3i (GLenum target, GLint s, GLint t, GLint r);
+GLAPI void APIENTRY glMultiTexCoord3iv (GLenum target, const GLint *v);
+GLAPI void APIENTRY glMultiTexCoord3s (GLenum target, GLshort s, GLshort t, GLshort r);
+GLAPI void APIENTRY glMultiTexCoord3sv (GLenum target, const GLshort *v);
+GLAPI void APIENTRY glMultiTexCoord4d (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q);
+GLAPI void APIENTRY glMultiTexCoord4dv (GLenum target, const GLdouble *v);
+GLAPI void APIENTRY glMultiTexCoord4f (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q);
+GLAPI void APIENTRY glMultiTexCoord4fv (GLenum target, const GLfloat *v);
+GLAPI void APIENTRY glMultiTexCoord4i (GLenum target, GLint s, GLint t, GLint r, GLint q);
+GLAPI void APIENTRY glMultiTexCoord4iv (GLenum target, const GLint *v);
+GLAPI void APIENTRY glMultiTexCoord4s (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q);
+GLAPI void APIENTRY glMultiTexCoord4sv (GLenum target, const GLshort *v);
+GLAPI void APIENTRY glLoadTransposeMatrixf (const GLfloat *m);
+GLAPI void APIENTRY glLoadTransposeMatrixd (const GLdouble *m);
+GLAPI void APIENTRY glMultTransposeMatrixf (const GLfloat *m);
+GLAPI void APIENTRY glMultTransposeMatrixd (const GLdouble *m);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLCLIENTACTIVETEXTUREPROC) (GLenum texture);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1DPROC) (GLenum target, GLdouble s);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1DVPROC) (GLenum target, const GLdouble *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1FPROC) (GLenum target, GLfloat s);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1FVPROC) (GLenum target, const GLfloat *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1IPROC) (GLenum target, GLint s);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1IVPROC) (GLenum target, const GLint *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1SPROC) (GLenum target, GLshort s);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1SVPROC) (GLenum target, const GLshort *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2DPROC) (GLenum target, GLdouble s, GLdouble t);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2DVPROC) (GLenum target, const GLdouble *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2FPROC) (GLenum target, GLfloat s, GLfloat t);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2FVPROC) (GLenum target, const GLfloat *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2IPROC) (GLenum target, GLint s, GLint t);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2IVPROC) (GLenum target, const GLint *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2SPROC) (GLenum target, GLshort s, GLshort t);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2SVPROC) (GLenum target, const GLshort *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3DPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3DVPROC) (GLenum target, const GLdouble *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3FPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3FVPROC) (GLenum target, const GLfloat *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3IPROC) (GLenum target, GLint s, GLint t, GLint r);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3IVPROC) (GLenum target, const GLint *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3SPROC) (GLenum target, GLshort s, GLshort t, GLshort r);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3SVPROC) (GLenum target, const GLshort *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4DPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4DVPROC) (GLenum target, const GLdouble *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4FPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4FVPROC) (GLenum target, const GLfloat *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4IPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4IVPROC) (GLenum target, const GLint *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4SPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4SVPROC) (GLenum target, const GLshort *v);
+typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXFPROC) (const GLfloat *m);
+typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXDPROC) (const GLdouble *m);
+typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXFPROC) (const GLfloat *m);
+typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXDPROC) (const GLdouble *m);
+#endif
+
+#ifndef GL_VERSION_1_4
+#define GL_VERSION_1_4 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBlendFuncSeparate (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);
+GLAPI void APIENTRY glMultiDrawArrays (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount);
+GLAPI void APIENTRY glMultiDrawElements (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount);
+GLAPI void APIENTRY glPointParameterf (GLenum pname, GLfloat param);
+GLAPI void APIENTRY glPointParameterfv (GLenum pname, const GLfloat *params);
+GLAPI void APIENTRY glPointParameteri (GLenum pname, GLint param);
+GLAPI void APIENTRY glPointParameteriv (GLenum pname, const GLint *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);
+typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSPROC) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount);
+typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSPROC) (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount);
+typedef void (APIENTRYP PFNGLPOINTPARAMETERFPROC) (GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLPOINTPARAMETERFVPROC) (GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLPOINTPARAMETERIPROC) (GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLPOINTPARAMETERIVPROC) (GLenum pname, const GLint *params);
+#endif
+
+#ifndef GL_VERSION_1_4_DEPRECATED
+#define GL_VERSION_1_4_DEPRECATED 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glFogCoordf (GLfloat coord);
+GLAPI void APIENTRY glFogCoordfv (const GLfloat *coord);
+GLAPI void APIENTRY glFogCoordd (GLdouble coord);
+GLAPI void APIENTRY glFogCoorddv (const GLdouble *coord);
+GLAPI void APIENTRY glFogCoordPointer (GLenum type, GLsizei stride, const GLvoid *pointer);
+GLAPI void APIENTRY glSecondaryColor3b (GLbyte red, GLbyte green, GLbyte blue);
+GLAPI void APIENTRY glSecondaryColor3bv (const GLbyte *v);
+GLAPI void APIENTRY glSecondaryColor3d (GLdouble red, GLdouble green, GLdouble blue);
+GLAPI void APIENTRY glSecondaryColor3dv (const GLdouble *v);
+GLAPI void APIENTRY glSecondaryColor3f (GLfloat red, GLfloat green, GLfloat blue);
+GLAPI void APIENTRY glSecondaryColor3fv (const GLfloat *v);
+GLAPI void APIENTRY glSecondaryColor3i (GLint red, GLint green, GLint blue);
+GLAPI void APIENTRY glSecondaryColor3iv (const GLint *v);
+GLAPI void APIENTRY glSecondaryColor3s (GLshort red, GLshort green, GLshort blue);
+GLAPI void APIENTRY glSecondaryColor3sv (const GLshort *v);
+GLAPI void APIENTRY glSecondaryColor3ub (GLubyte red, GLubyte green, GLubyte blue);
+GLAPI void APIENTRY glSecondaryColor3ubv (const GLubyte *v);
+GLAPI void APIENTRY glSecondaryColor3ui (GLuint red, GLuint green, GLuint blue);
+GLAPI void APIENTRY glSecondaryColor3uiv (const GLuint *v);
+GLAPI void APIENTRY glSecondaryColor3us (GLushort red, GLushort green, GLushort blue);
+GLAPI void APIENTRY glSecondaryColor3usv (const GLushort *v);
+GLAPI void APIENTRY glSecondaryColorPointer (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+GLAPI void APIENTRY glWindowPos2d (GLdouble x, GLdouble y);
+GLAPI void APIENTRY glWindowPos2dv (const GLdouble *v);
+GLAPI void APIENTRY glWindowPos2f (GLfloat x, GLfloat y);
+GLAPI void APIENTRY glWindowPos2fv (const GLfloat *v);
+GLAPI void APIENTRY glWindowPos2i (GLint x, GLint y);
+GLAPI void APIENTRY glWindowPos2iv (const GLint *v);
+GLAPI void APIENTRY glWindowPos2s (GLshort x, GLshort y);
+GLAPI void APIENTRY glWindowPos2sv (const GLshort *v);
+GLAPI void APIENTRY glWindowPos3d (GLdouble x, GLdouble y, GLdouble z);
+GLAPI void APIENTRY glWindowPos3dv (const GLdouble *v);
+GLAPI void APIENTRY glWindowPos3f (GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glWindowPos3fv (const GLfloat *v);
+GLAPI void APIENTRY glWindowPos3i (GLint x, GLint y, GLint z);
+GLAPI void APIENTRY glWindowPos3iv (const GLint *v);
+GLAPI void APIENTRY glWindowPos3s (GLshort x, GLshort y, GLshort z);
+GLAPI void APIENTRY glWindowPos3sv (const GLshort *v);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLFOGCOORDFPROC) (GLfloat coord);
+typedef void (APIENTRYP PFNGLFOGCOORDFVPROC) (const GLfloat *coord);
+typedef void (APIENTRYP PFNGLFOGCOORDDPROC) (GLdouble coord);
+typedef void (APIENTRYP PFNGLFOGCOORDDVPROC) (const GLdouble *coord);
+typedef void (APIENTRYP PFNGLFOGCOORDPOINTERPROC) (GLenum type, GLsizei stride, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BPROC) (GLbyte red, GLbyte green, GLbyte blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BVPROC) (const GLbyte *v);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DPROC) (GLdouble red, GLdouble green, GLdouble blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DVPROC) (const GLdouble *v);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FPROC) (GLfloat red, GLfloat green, GLfloat blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FVPROC) (const GLfloat *v);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IPROC) (GLint red, GLint green, GLint blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IVPROC) (const GLint *v);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SPROC) (GLshort red, GLshort green, GLshort blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SVPROC) (const GLshort *v);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBPROC) (GLubyte red, GLubyte green, GLubyte blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBVPROC) (const GLubyte *v);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIPROC) (GLuint red, GLuint green, GLuint blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIVPROC) (const GLuint *v);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USPROC) (GLushort red, GLushort green, GLushort blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USVPROC) (const GLushort *v);
+typedef void (APIENTRYP PFNGLSECONDARYCOLORPOINTERPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLWINDOWPOS2DPROC) (GLdouble x, GLdouble y);
+typedef void (APIENTRYP PFNGLWINDOWPOS2DVPROC) (const GLdouble *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS2FPROC) (GLfloat x, GLfloat y);
+typedef void (APIENTRYP PFNGLWINDOWPOS2FVPROC) (const GLfloat *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS2IPROC) (GLint x, GLint y);
+typedef void (APIENTRYP PFNGLWINDOWPOS2IVPROC) (const GLint *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS2SPROC) (GLshort x, GLshort y);
+typedef void (APIENTRYP PFNGLWINDOWPOS2SVPROC) (const GLshort *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS3DPROC) (GLdouble x, GLdouble y, GLdouble z);
+typedef void (APIENTRYP PFNGLWINDOWPOS3DVPROC) (const GLdouble *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS3FPROC) (GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLWINDOWPOS3FVPROC) (const GLfloat *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS3IPROC) (GLint x, GLint y, GLint z);
+typedef void (APIENTRYP PFNGLWINDOWPOS3IVPROC) (const GLint *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS3SPROC) (GLshort x, GLshort y, GLshort z);
+typedef void (APIENTRYP PFNGLWINDOWPOS3SVPROC) (const GLshort *v);
+#endif
+
+#ifndef GL_VERSION_1_5
+#define GL_VERSION_1_5 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGenQueries (GLsizei n, GLuint *ids);
+GLAPI void APIENTRY glDeleteQueries (GLsizei n, const GLuint *ids);
+GLAPI GLboolean APIENTRY glIsQuery (GLuint id);
+GLAPI void APIENTRY glBeginQuery (GLenum target, GLuint id);
+GLAPI void APIENTRY glEndQuery (GLenum target);
+GLAPI void APIENTRY glGetQueryiv (GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetQueryObjectiv (GLuint id, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetQueryObjectuiv (GLuint id, GLenum pname, GLuint *params);
+GLAPI void APIENTRY glBindBuffer (GLenum target, GLuint buffer);
+GLAPI void APIENTRY glDeleteBuffers (GLsizei n, const GLuint *buffers);
+GLAPI void APIENTRY glGenBuffers (GLsizei n, GLuint *buffers);
+GLAPI GLboolean APIENTRY glIsBuffer (GLuint buffer);
+GLAPI void APIENTRY glBufferData (GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage);
+GLAPI void APIENTRY glBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data);
+GLAPI void APIENTRY glGetBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, GLvoid *data);
+GLAPI GLvoid* APIENTRY glMapBuffer (GLenum target, GLenum access);
+GLAPI GLboolean APIENTRY glUnmapBuffer (GLenum target);
+GLAPI void APIENTRY glGetBufferParameteriv (GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetBufferPointerv (GLenum target, GLenum pname, GLvoid* *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLGENQUERIESPROC) (GLsizei n, GLuint *ids);
+typedef void (APIENTRYP PFNGLDELETEQUERIESPROC) (GLsizei n, const GLuint *ids);
+typedef GLboolean (APIENTRYP PFNGLISQUERYPROC) (GLuint id);
+typedef void (APIENTRYP PFNGLBEGINQUERYPROC) (GLenum target, GLuint id);
+typedef void (APIENTRYP PFNGLENDQUERYPROC) (GLenum target);
+typedef void (APIENTRYP PFNGLGETQUERYIVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETQUERYOBJECTIVPROC) (GLuint id, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETQUERYOBJECTUIVPROC) (GLuint id, GLenum pname, GLuint *params);
+typedef void (APIENTRYP PFNGLBINDBUFFERPROC) (GLenum target, GLuint buffer);
+typedef void (APIENTRYP PFNGLDELETEBUFFERSPROC) (GLsizei n, const GLuint *buffers);
+typedef void (APIENTRYP PFNGLGENBUFFERSPROC) (GLsizei n, GLuint *buffers);
+typedef GLboolean (APIENTRYP PFNGLISBUFFERPROC) (GLuint buffer);
+typedef void (APIENTRYP PFNGLBUFFERDATAPROC) (GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage);
+typedef void (APIENTRYP PFNGLBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data);
+typedef void (APIENTRYP PFNGLGETBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, GLvoid *data);
+typedef GLvoid* (APIENTRYP PFNGLMAPBUFFERPROC) (GLenum target, GLenum access);
+typedef GLboolean (APIENTRYP PFNGLUNMAPBUFFERPROC) (GLenum target);
+typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETBUFFERPOINTERVPROC) (GLenum target, GLenum pname, GLvoid* *params);
+#endif
+
+#ifndef GL_VERSION_2_0
+#define GL_VERSION_2_0 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBlendEquationSeparate (GLenum modeRGB, GLenum modeAlpha);
+GLAPI void APIENTRY glDrawBuffers (GLsizei n, const GLenum *bufs);
+GLAPI void APIENTRY glStencilOpSeparate (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass);
+GLAPI void APIENTRY glStencilFuncSeparate (GLenum face, GLenum func, GLint ref, GLuint mask);
+GLAPI void APIENTRY glStencilMaskSeparate (GLenum face, GLuint mask);
+GLAPI void APIENTRY glAttachShader (GLuint program, GLuint shader);
+GLAPI void APIENTRY glBindAttribLocation (GLuint program, GLuint index, const GLchar *name);
+GLAPI void APIENTRY glCompileShader (GLuint shader);
+GLAPI GLuint APIENTRY glCreateProgram (void);
+GLAPI GLuint APIENTRY glCreateShader (GLenum type);
+GLAPI void APIENTRY glDeleteProgram (GLuint program);
+GLAPI void APIENTRY glDeleteShader (GLuint shader);
+GLAPI void APIENTRY glDetachShader (GLuint program, GLuint shader);
+GLAPI void APIENTRY glDisableVertexAttribArray (GLuint index);
+GLAPI void APIENTRY glEnableVertexAttribArray (GLuint index);
+GLAPI void APIENTRY glGetActiveAttrib (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name);
+GLAPI void APIENTRY glGetActiveUniform (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name);
+GLAPI void APIENTRY glGetAttachedShaders (GLuint program, GLsizei maxCount, GLsizei *count, GLuint *obj);
+GLAPI GLint APIENTRY glGetAttribLocation (GLuint program, const GLchar *name);
+GLAPI void APIENTRY glGetProgramiv (GLuint program, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetProgramInfoLog (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
+GLAPI void APIENTRY glGetShaderiv (GLuint shader, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetShaderInfoLog (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
+GLAPI void APIENTRY glGetShaderSource (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source);
+GLAPI GLint APIENTRY glGetUniformLocation (GLuint program, const GLchar *name);
+GLAPI void APIENTRY glGetUniformfv (GLuint program, GLint location, GLfloat *params);
+GLAPI void APIENTRY glGetUniformiv (GLuint program, GLint location, GLint *params);
+GLAPI void APIENTRY glGetVertexAttribdv (GLuint index, GLenum pname, GLdouble *params);
+GLAPI void APIENTRY glGetVertexAttribfv (GLuint index, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetVertexAttribiv (GLuint index, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetVertexAttribPointerv (GLuint index, GLenum pname, GLvoid* *pointer);
+GLAPI GLboolean APIENTRY glIsProgram (GLuint program);
+GLAPI GLboolean APIENTRY glIsShader (GLuint shader);
+GLAPI void APIENTRY glLinkProgram (GLuint program);
+GLAPI void APIENTRY glShaderSource (GLuint shader, GLsizei count, const GLchar* *string, const GLint *length);
+GLAPI void APIENTRY glUseProgram (GLuint program);
+GLAPI void APIENTRY glUniform1f (GLint location, GLfloat v0);
+GLAPI void APIENTRY glUniform2f (GLint location, GLfloat v0, GLfloat v1);
+GLAPI void APIENTRY glUniform3f (GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
+GLAPI void APIENTRY glUniform4f (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
+GLAPI void APIENTRY glUniform1i (GLint location, GLint v0);
+GLAPI void APIENTRY glUniform2i (GLint location, GLint v0, GLint v1);
+GLAPI void APIENTRY glUniform3i (GLint location, GLint v0, GLint v1, GLint v2);
+GLAPI void APIENTRY glUniform4i (GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
+GLAPI void APIENTRY glUniform1fv (GLint location, GLsizei count, const GLfloat *value);
+GLAPI void APIENTRY glUniform2fv (GLint location, GLsizei count, const GLfloat *value);
+GLAPI void APIENTRY glUniform3fv (GLint location, GLsizei count, const GLfloat *value);
+GLAPI void APIENTRY glUniform4fv (GLint location, GLsizei count, const GLfloat *value);
+GLAPI void APIENTRY glUniform1iv (GLint location, GLsizei count, const GLint *value);
+GLAPI void APIENTRY glUniform2iv (GLint location, GLsizei count, const GLint *value);
+GLAPI void APIENTRY glUniform3iv (GLint location, GLsizei count, const GLint *value);
+GLAPI void APIENTRY glUniform4iv (GLint location, GLsizei count, const GLint *value);
+GLAPI void APIENTRY glUniformMatrix2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glUniformMatrix3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glUniformMatrix4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glValidateProgram (GLuint program);
+GLAPI void APIENTRY glVertexAttrib1d (GLuint index, GLdouble x);
+GLAPI void APIENTRY glVertexAttrib1dv (GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttrib1f (GLuint index, GLfloat x);
+GLAPI void APIENTRY glVertexAttrib1fv (GLuint index, const GLfloat *v);
+GLAPI void APIENTRY glVertexAttrib1s (GLuint index, GLshort x);
+GLAPI void APIENTRY glVertexAttrib1sv (GLuint index, const GLshort *v);
+GLAPI void APIENTRY glVertexAttrib2d (GLuint index, GLdouble x, GLdouble y);
+GLAPI void APIENTRY glVertexAttrib2dv (GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttrib2f (GLuint index, GLfloat x, GLfloat y);
+GLAPI void APIENTRY glVertexAttrib2fv (GLuint index, const GLfloat *v);
+GLAPI void APIENTRY glVertexAttrib2s (GLuint index, GLshort x, GLshort y);
+GLAPI void APIENTRY glVertexAttrib2sv (GLuint index, const GLshort *v);
+GLAPI void APIENTRY glVertexAttrib3d (GLuint index, GLdouble x, GLdouble y, GLdouble z);
+GLAPI void APIENTRY glVertexAttrib3dv (GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttrib3f (GLuint index, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glVertexAttrib3fv (GLuint index, const GLfloat *v);
+GLAPI void APIENTRY glVertexAttrib3s (GLuint index, GLshort x, GLshort y, GLshort z);
+GLAPI void APIENTRY glVertexAttrib3sv (GLuint index, const GLshort *v);
+GLAPI void APIENTRY glVertexAttrib4Nbv (GLuint index, const GLbyte *v);
+GLAPI void APIENTRY glVertexAttrib4Niv (GLuint index, const GLint *v);
+GLAPI void APIENTRY glVertexAttrib4Nsv (GLuint index, const GLshort *v);
+GLAPI void APIENTRY glVertexAttrib4Nub (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w);
+GLAPI void APIENTRY glVertexAttrib4Nubv (GLuint index, const GLubyte *v);
+GLAPI void APIENTRY glVertexAttrib4Nuiv (GLuint index, const GLuint *v);
+GLAPI void APIENTRY glVertexAttrib4Nusv (GLuint index, const GLushort *v);
+GLAPI void APIENTRY glVertexAttrib4bv (GLuint index, const GLbyte *v);
+GLAPI void APIENTRY glVertexAttrib4d (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+GLAPI void APIENTRY glVertexAttrib4dv (GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttrib4f (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+GLAPI void APIENTRY glVertexAttrib4fv (GLuint index, const GLfloat *v);
+GLAPI void APIENTRY glVertexAttrib4iv (GLuint index, const GLint *v);
+GLAPI void APIENTRY glVertexAttrib4s (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w);
+GLAPI void APIENTRY glVertexAttrib4sv (GLuint index, const GLshort *v);
+GLAPI void APIENTRY glVertexAttrib4ubv (GLuint index, const GLubyte *v);
+GLAPI void APIENTRY glVertexAttrib4uiv (GLuint index, const GLuint *v);
+GLAPI void APIENTRY glVertexAttrib4usv (GLuint index, const GLushort *v);
+GLAPI void APIENTRY glVertexAttribPointer (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEPROC) (GLenum modeRGB, GLenum modeAlpha);
+typedef void (APIENTRYP PFNGLDRAWBUFFERSPROC) (GLsizei n, const GLenum *bufs);
+typedef void (APIENTRYP PFNGLSTENCILOPSEPARATEPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass);
+typedef void (APIENTRYP PFNGLSTENCILFUNCSEPARATEPROC) (GLenum face, GLenum func, GLint ref, GLuint mask);
+typedef void (APIENTRYP PFNGLSTENCILMASKSEPARATEPROC) (GLenum face, GLuint mask);
+typedef void (APIENTRYP PFNGLATTACHSHADERPROC) (GLuint program, GLuint shader);
+typedef void (APIENTRYP PFNGLBINDATTRIBLOCATIONPROC) (GLuint program, GLuint index, const GLchar *name);
+typedef void (APIENTRYP PFNGLCOMPILESHADERPROC) (GLuint shader);
+typedef GLuint (APIENTRYP PFNGLCREATEPROGRAMPROC) (void);
+typedef GLuint (APIENTRYP PFNGLCREATESHADERPROC) (GLenum type);
+typedef void (APIENTRYP PFNGLDELETEPROGRAMPROC) (GLuint program);
+typedef void (APIENTRYP PFNGLDELETESHADERPROC) (GLuint shader);
+typedef void (APIENTRYP PFNGLDETACHSHADERPROC) (GLuint program, GLuint shader);
+typedef void (APIENTRYP PFNGLDISABLEVERTEXATTRIBARRAYPROC) (GLuint index);
+typedef void (APIENTRYP PFNGLENABLEVERTEXATTRIBARRAYPROC) (GLuint index);
+typedef void (APIENTRYP PFNGLGETACTIVEATTRIBPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name);
+typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name);
+typedef void (APIENTRYP PFNGLGETATTACHEDSHADERSPROC) (GLuint program, GLsizei maxCount, GLsizei *count, GLuint *obj);
+typedef GLint (APIENTRYP PFNGLGETATTRIBLOCATIONPROC) (GLuint program, const GLchar *name);
+typedef void (APIENTRYP PFNGLGETPROGRAMIVPROC) (GLuint program, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETPROGRAMINFOLOGPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
+typedef void (APIENTRYP PFNGLGETSHADERIVPROC) (GLuint shader, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETSHADERINFOLOGPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
+typedef void (APIENTRYP PFNGLGETSHADERSOURCEPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source);
+typedef GLint (APIENTRYP PFNGLGETUNIFORMLOCATIONPROC) (GLuint program, const GLchar *name);
+typedef void (APIENTRYP PFNGLGETUNIFORMFVPROC) (GLuint program, GLint location, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETUNIFORMIVPROC) (GLuint program, GLint location, GLint *params);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBDVPROC) (GLuint index, GLenum pname, GLdouble *params);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBFVPROC) (GLuint index, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIVPROC) (GLuint index, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVPROC) (GLuint index, GLenum pname, GLvoid* *pointer);
+typedef GLboolean (APIENTRYP PFNGLISPROGRAMPROC) (GLuint program);
+typedef GLboolean (APIENTRYP PFNGLISSHADERPROC) (GLuint shader);
+typedef void (APIENTRYP PFNGLLINKPROGRAMPROC) (GLuint program);
+typedef void (APIENTRYP PFNGLSHADERSOURCEPROC) (GLuint shader, GLsizei count, const GLchar* *string, const GLint *length);
+typedef void (APIENTRYP PFNGLUSEPROGRAMPROC) (GLuint program);
+typedef void (APIENTRYP PFNGLUNIFORM1FPROC) (GLint location, GLfloat v0);
+typedef void (APIENTRYP PFNGLUNIFORM2FPROC) (GLint location, GLfloat v0, GLfloat v1);
+typedef void (APIENTRYP PFNGLUNIFORM3FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
+typedef void (APIENTRYP PFNGLUNIFORM4FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
+typedef void (APIENTRYP PFNGLUNIFORM1IPROC) (GLint location, GLint v0);
+typedef void (APIENTRYP PFNGLUNIFORM2IPROC) (GLint location, GLint v0, GLint v1);
+typedef void (APIENTRYP PFNGLUNIFORM3IPROC) (GLint location, GLint v0, GLint v1, GLint v2);
+typedef void (APIENTRYP PFNGLUNIFORM4IPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
+typedef void (APIENTRYP PFNGLUNIFORM1FVPROC) (GLint location, GLsizei count, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORM2FVPROC) (GLint location, GLsizei count, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORM3FVPROC) (GLint location, GLsizei count, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORM4FVPROC) (GLint location, GLsizei count, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORM1IVPROC) (GLint location, GLsizei count, const GLint *value);
+typedef void (APIENTRYP PFNGLUNIFORM2IVPROC) (GLint location, GLsizei count, const GLint *value);
+typedef void (APIENTRYP PFNGLUNIFORM3IVPROC) (GLint location, GLsizei count, const GLint *value);
+typedef void (APIENTRYP PFNGLUNIFORM4IVPROC) (GLint location, GLsizei count, const GLint *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLVALIDATEPROGRAMPROC) (GLuint program);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1DPROC) (GLuint index, GLdouble x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1DVPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1FPROC) (GLuint index, GLfloat x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1FVPROC) (GLuint index, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1SPROC) (GLuint index, GLshort x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1SVPROC) (GLuint index, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2DPROC) (GLuint index, GLdouble x, GLdouble y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2DVPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2FPROC) (GLuint index, GLfloat x, GLfloat y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2FVPROC) (GLuint index, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2SPROC) (GLuint index, GLshort x, GLshort y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2SVPROC) (GLuint index, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3DVPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3FVPROC) (GLuint index, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3SPROC) (GLuint index, GLshort x, GLshort y, GLshort z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3SVPROC) (GLuint index, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4NBVPROC) (GLuint index, const GLbyte *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4NIVPROC) (GLuint index, const GLint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4NSVPROC) (GLuint index, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBVPROC) (GLuint index, const GLubyte *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUIVPROC) (GLuint index, const GLuint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUSVPROC) (GLuint index, const GLushort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4BVPROC) (GLuint index, const GLbyte *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4DVPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4FVPROC) (GLuint index, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4IVPROC) (GLuint index, const GLint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4SPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4SVPROC) (GLuint index, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBVPROC) (GLuint index, const GLubyte *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4UIVPROC) (GLuint index, const GLuint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4USVPROC) (GLuint index, const GLushort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer);
+#endif
+
+#ifndef GL_VERSION_2_1
+#define GL_VERSION_2_1 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glUniformMatrix2x3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glUniformMatrix3x2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glUniformMatrix2x4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glUniformMatrix4x2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glUniformMatrix3x4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glUniformMatrix4x3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+#endif
+
+#ifndef GL_VERSION_3_0
+#define GL_VERSION_3_0 1
+/* OpenGL 3.0 also reuses entry points from these extensions: */
+/* ARB_framebuffer_object */
+/* ARB_map_buffer_range */
+/* ARB_vertex_array_object */
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glColorMaski (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a);
+GLAPI void APIENTRY glGetBooleani_v (GLenum target, GLuint index, GLboolean *data);
+GLAPI void APIENTRY glGetIntegeri_v (GLenum target, GLuint index, GLint *data);
+GLAPI void APIENTRY glEnablei (GLenum target, GLuint index);
+GLAPI void APIENTRY glDisablei (GLenum target, GLuint index);
+GLAPI GLboolean APIENTRY glIsEnabledi (GLenum target, GLuint index);
+GLAPI void APIENTRY glBeginTransformFeedback (GLenum primitiveMode);
+GLAPI void APIENTRY glEndTransformFeedback (void);
+GLAPI void APIENTRY glBindBufferRange (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);
+GLAPI void APIENTRY glBindBufferBase (GLenum target, GLuint index, GLuint buffer);
+GLAPI void APIENTRY glTransformFeedbackVaryings (GLuint program, GLsizei count, const GLchar* *varyings, GLenum bufferMode);
+GLAPI void APIENTRY glGetTransformFeedbackVarying (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name);
+GLAPI void APIENTRY glClampColor (GLenum target, GLenum clamp);
+GLAPI void APIENTRY glBeginConditionalRender (GLuint id, GLenum mode);
+GLAPI void APIENTRY glEndConditionalRender (void);
+GLAPI void APIENTRY glVertexAttribIPointer (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+GLAPI void APIENTRY glGetVertexAttribIiv (GLuint index, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetVertexAttribIuiv (GLuint index, GLenum pname, GLuint *params);
+GLAPI void APIENTRY glVertexAttribI1i (GLuint index, GLint x);
+GLAPI void APIENTRY glVertexAttribI2i (GLuint index, GLint x, GLint y);
+GLAPI void APIENTRY glVertexAttribI3i (GLuint index, GLint x, GLint y, GLint z);
+GLAPI void APIENTRY glVertexAttribI4i (GLuint index, GLint x, GLint y, GLint z, GLint w);
+GLAPI void APIENTRY glVertexAttribI1ui (GLuint index, GLuint x);
+GLAPI void APIENTRY glVertexAttribI2ui (GLuint index, GLuint x, GLuint y);
+GLAPI void APIENTRY glVertexAttribI3ui (GLuint index, GLuint x, GLuint y, GLuint z);
+GLAPI void APIENTRY glVertexAttribI4ui (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
+GLAPI void APIENTRY glVertexAttribI1iv (GLuint index, const GLint *v);
+GLAPI void APIENTRY glVertexAttribI2iv (GLuint index, const GLint *v);
+GLAPI void APIENTRY glVertexAttribI3iv (GLuint index, const GLint *v);
+GLAPI void APIENTRY glVertexAttribI4iv (GLuint index, const GLint *v);
+GLAPI void APIENTRY glVertexAttribI1uiv (GLuint index, const GLuint *v);
+GLAPI void APIENTRY glVertexAttribI2uiv (GLuint index, const GLuint *v);
+GLAPI void APIENTRY glVertexAttribI3uiv (GLuint index, const GLuint *v);
+GLAPI void APIENTRY glVertexAttribI4uiv (GLuint index, const GLuint *v);
+GLAPI void APIENTRY glVertexAttribI4bv (GLuint index, const GLbyte *v);
+GLAPI void APIENTRY glVertexAttribI4sv (GLuint index, const GLshort *v);
+GLAPI void APIENTRY glVertexAttribI4ubv (GLuint index, const GLubyte *v);
+GLAPI void APIENTRY glVertexAttribI4usv (GLuint index, const GLushort *v);
+GLAPI void APIENTRY glGetUniformuiv (GLuint program, GLint location, GLuint *params);
+GLAPI void APIENTRY glBindFragDataLocation (GLuint program, GLuint color, const GLchar *name);
+GLAPI GLint APIENTRY glGetFragDataLocation (GLuint program, const GLchar *name);
+GLAPI void APIENTRY glUniform1ui (GLint location, GLuint v0);
+GLAPI void APIENTRY glUniform2ui (GLint location, GLuint v0, GLuint v1);
+GLAPI void APIENTRY glUniform3ui (GLint location, GLuint v0, GLuint v1, GLuint v2);
+GLAPI void APIENTRY glUniform4ui (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+GLAPI void APIENTRY glUniform1uiv (GLint location, GLsizei count, const GLuint *value);
+GLAPI void APIENTRY glUniform2uiv (GLint location, GLsizei count, const GLuint *value);
+GLAPI void APIENTRY glUniform3uiv (GLint location, GLsizei count, const GLuint *value);
+GLAPI void APIENTRY glUniform4uiv (GLint location, GLsizei count, const GLuint *value);
+GLAPI void APIENTRY glTexParameterIiv (GLenum target, GLenum pname, const GLint *params);
+GLAPI void APIENTRY glTexParameterIuiv (GLenum target, GLenum pname, const GLuint *params);
+GLAPI void APIENTRY glGetTexParameterIiv (GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetTexParameterIuiv (GLenum target, GLenum pname, GLuint *params);
+GLAPI void APIENTRY glClearBufferiv (GLenum buffer, GLint drawbuffer, const GLint *value);
+GLAPI void APIENTRY glClearBufferuiv (GLenum buffer, GLint drawbuffer, const GLuint *value);
+GLAPI void APIENTRY glClearBufferfv (GLenum buffer, GLint drawbuffer, const GLfloat *value);
+GLAPI void APIENTRY glClearBufferfi (GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);
+GLAPI const GLubyte * APIENTRY glGetStringi (GLenum name, GLuint index);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLCOLORMASKIPROC) (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a);
+typedef void (APIENTRYP PFNGLGETBOOLEANI_VPROC) (GLenum target, GLuint index, GLboolean *data);
+typedef void (APIENTRYP PFNGLGETINTEGERI_VPROC) (GLenum target, GLuint index, GLint *data);
+typedef void (APIENTRYP PFNGLENABLEIPROC) (GLenum target, GLuint index);
+typedef void (APIENTRYP PFNGLDISABLEIPROC) (GLenum target, GLuint index);
+typedef GLboolean (APIENTRYP PFNGLISENABLEDIPROC) (GLenum target, GLuint index);
+typedef void (APIENTRYP PFNGLBEGINTRANSFORMFEEDBACKPROC) (GLenum primitiveMode);
+typedef void (APIENTRYP PFNGLENDTRANSFORMFEEDBACKPROC) (void);
+typedef void (APIENTRYP PFNGLBINDBUFFERRANGEPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);
+typedef void (APIENTRYP PFNGLBINDBUFFERBASEPROC) (GLenum target, GLuint index, GLuint buffer);
+typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKVARYINGSPROC) (GLuint program, GLsizei count, const GLchar* *varyings, GLenum bufferMode);
+typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKVARYINGPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name);
+typedef void (APIENTRYP PFNGLCLAMPCOLORPROC) (GLenum target, GLenum clamp);
+typedef void (APIENTRYP PFNGLBEGINCONDITIONALRENDERPROC) (GLuint id, GLenum mode);
+typedef void (APIENTRYP PFNGLENDCONDITIONALRENDERPROC) (void);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBIPOINTERPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIIVPROC) (GLuint index, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIUIVPROC) (GLuint index, GLenum pname, GLuint *params);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IPROC) (GLuint index, GLint x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IPROC) (GLuint index, GLint x, GLint y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IPROC) (GLuint index, GLint x, GLint y, GLint z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IPROC) (GLuint index, GLint x, GLint y, GLint z, GLint w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIPROC) (GLuint index, GLuint x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIPROC) (GLuint index, GLuint x, GLuint y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIPROC) (GLuint index, GLuint x, GLuint y, GLuint z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIPROC) (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IVPROC) (GLuint index, const GLint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IVPROC) (GLuint index, const GLint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IVPROC) (GLuint index, const GLint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IVPROC) (GLuint index, const GLint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIVPROC) (GLuint index, const GLuint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIVPROC) (GLuint index, const GLuint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIVPROC) (GLuint index, const GLuint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIVPROC) (GLuint index, const GLuint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI4BVPROC) (GLuint index, const GLbyte *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI4SVPROC) (GLuint index, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UBVPROC) (GLuint index, const GLubyte *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI4USVPROC) (GLuint index, const GLushort *v);
+typedef void (APIENTRYP PFNGLGETUNIFORMUIVPROC) (GLuint program, GLint location, GLuint *params);
+typedef void (APIENTRYP PFNGLBINDFRAGDATALOCATIONPROC) (GLuint program, GLuint color, const GLchar *name);
+typedef GLint (APIENTRYP PFNGLGETFRAGDATALOCATIONPROC) (GLuint program, const GLchar *name);
+typedef void (APIENTRYP PFNGLUNIFORM1UIPROC) (GLint location, GLuint v0);
+typedef void (APIENTRYP PFNGLUNIFORM2UIPROC) (GLint location, GLuint v0, GLuint v1);
+typedef void (APIENTRYP PFNGLUNIFORM3UIPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2);
+typedef void (APIENTRYP PFNGLUNIFORM4UIPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+typedef void (APIENTRYP PFNGLUNIFORM1UIVPROC) (GLint location, GLsizei count, const GLuint *value);
+typedef void (APIENTRYP PFNGLUNIFORM2UIVPROC) (GLint location, GLsizei count, const GLuint *value);
+typedef void (APIENTRYP PFNGLUNIFORM3UIVPROC) (GLint location, GLsizei count, const GLuint *value);
+typedef void (APIENTRYP PFNGLUNIFORM4UIVPROC) (GLint location, GLsizei count, const GLuint *value);
+typedef void (APIENTRYP PFNGLTEXPARAMETERIIVPROC) (GLenum target, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLTEXPARAMETERIUIVPROC) (GLenum target, GLenum pname, const GLuint *params);
+typedef void (APIENTRYP PFNGLGETTEXPARAMETERIIVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETTEXPARAMETERIUIVPROC) (GLenum target, GLenum pname, GLuint *params);
+typedef void (APIENTRYP PFNGLCLEARBUFFERIVPROC) (GLenum buffer, GLint drawbuffer, const GLint *value);
+typedef void (APIENTRYP PFNGLCLEARBUFFERUIVPROC) (GLenum buffer, GLint drawbuffer, const GLuint *value);
+typedef void (APIENTRYP PFNGLCLEARBUFFERFVPROC) (GLenum buffer, GLint drawbuffer, const GLfloat *value);
+typedef void (APIENTRYP PFNGLCLEARBUFFERFIPROC) (GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);
+typedef const GLubyte * (APIENTRYP PFNGLGETSTRINGIPROC) (GLenum name, GLuint index);
+#endif
+
+#ifndef GL_VERSION_3_1
+#define GL_VERSION_3_1 1
+/* OpenGL 3.1 also reuses entry points from these extensions: */
+/* ARB_copy_buffer */
+/* ARB_uniform_buffer_object */
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDrawArraysInstanced (GLenum mode, GLint first, GLsizei count, GLsizei primcount);
+GLAPI void APIENTRY glDrawElementsInstanced (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount);
+GLAPI void APIENTRY glTexBuffer (GLenum target, GLenum internalformat, GLuint buffer);
+GLAPI void APIENTRY glPrimitiveRestartIndex (GLuint index);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount);
+typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount);
+typedef void (APIENTRYP PFNGLTEXBUFFERPROC) (GLenum target, GLenum internalformat, GLuint buffer);
+typedef void (APIENTRYP PFNGLPRIMITIVERESTARTINDEXPROC) (GLuint index);
+#endif
+
+#ifndef GL_VERSION_3_2
+#define GL_VERSION_3_2 1
+/* OpenGL 3.2 also reuses entry points from these extensions: */
+/* ARB_draw_elements_base_vertex */
+/* ARB_provoking_vertex */
+/* ARB_sync */
+/* ARB_texture_multisample */
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGetInteger64i_v (GLenum target, GLuint index, GLint64 *data);
+GLAPI void APIENTRY glGetBufferParameteri64v (GLenum target, GLenum pname, GLint64 *params);
+GLAPI void APIENTRY glFramebufferTexture (GLenum target, GLenum attachment, GLuint texture, GLint level);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLGETINTEGER64I_VPROC) (GLenum target, GLuint index, GLint64 *data);
+typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERI64VPROC) (GLenum target, GLenum pname, GLint64 *params);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level);
+#endif
+
+#ifndef GL_VERSION_3_3
+#define GL_VERSION_3_3 1
+/* OpenGL 3.3 also reuses entry points from these extensions: */
+/* ARB_blend_func_extended */
+/* ARB_sampler_objects */
+/* ARB_explicit_attrib_location, but it has none */
+/* ARB_occlusion_query2 (no entry points) */
+/* ARB_shader_bit_encoding (no entry points) */
+/* ARB_texture_rgb10_a2ui (no entry points) */
+/* ARB_texture_swizzle (no entry points) */
+/* ARB_timer_query */
+/* ARB_vertex_type_2_10_10_10_rev */
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glVertexAttribDivisor (GLuint index, GLuint divisor);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLVERTEXATTRIBDIVISORPROC) (GLuint index, GLuint divisor);
+#endif
+
+#ifndef GL_VERSION_4_0
+#define GL_VERSION_4_0 1
+/* OpenGL 4.0 also reuses entry points from these extensions: */
+/* ARB_texture_query_lod (no entry points) */
+/* ARB_draw_indirect */
+/* ARB_gpu_shader5 (no entry points) */
+/* ARB_gpu_shader_fp64 */
+/* ARB_shader_subroutine */
+/* ARB_tessellation_shader */
+/* ARB_texture_buffer_object_rgb32 (no entry points) */
+/* ARB_texture_cube_map_array (no entry points) */
+/* ARB_texture_gather (no entry points) */
+/* ARB_transform_feedback2 */
+/* ARB_transform_feedback3 */
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glMinSampleShading (GLclampf value);
+GLAPI void APIENTRY glBlendEquationi (GLuint buf, GLenum mode);
+GLAPI void APIENTRY glBlendEquationSeparatei (GLuint buf, GLenum modeRGB, GLenum modeAlpha);
+GLAPI void APIENTRY glBlendFunci (GLuint buf, GLenum src, GLenum dst);
+GLAPI void APIENTRY glBlendFuncSeparatei (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLMINSAMPLESHADINGPROC) (GLclampf value);
+typedef void (APIENTRYP PFNGLBLENDEQUATIONIPROC) (GLuint buf, GLenum mode);
+typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEIPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha);
+typedef void (APIENTRYP PFNGLBLENDFUNCIPROC) (GLuint buf, GLenum src, GLenum dst);
+typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEIPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+#endif
+
+#ifndef GL_VERSION_4_1
+#define GL_VERSION_4_1 1
+/* OpenGL 4.1 reuses entry points from these extensions: */
+/* ARB_ES2_compatibility */
+/* ARB_get_program_binary */
+/* ARB_separate_shader_objects */
+/* ARB_shader_precision (no entry points) */
+/* ARB_vertex_attrib_64bit */
+/* ARB_viewport_array */
+#endif
+
+#ifndef GL_VERSION_4_2
+#define GL_VERSION_4_2 1
+/* OpenGL 4.2 reuses entry points from these extensions: */
+/* ARB_base_instance */
+/* ARB_shading_language_420pack (no entry points) */
+/* ARB_transform_feedback_instanced */
+/* ARB_compressed_texture_pixel_storage (no entry points) */
+/* ARB_conservative_depth (no entry points) */
+/* ARB_internalformat_query */
+/* ARB_map_buffer_alignment (no entry points) */
+/* ARB_shader_atomic_counters */
+/* ARB_shader_image_load_store */
+/* ARB_shading_language_packing (no entry points) */
+/* ARB_texture_storage */
+#endif
+
+#ifndef GL_ARB_multitexture
+#define GL_ARB_multitexture 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glActiveTextureARB (GLenum texture);
+GLAPI void APIENTRY glClientActiveTextureARB (GLenum texture);
+GLAPI void APIENTRY glMultiTexCoord1dARB (GLenum target, GLdouble s);
+GLAPI void APIENTRY glMultiTexCoord1dvARB (GLenum target, const GLdouble *v);
+GLAPI void APIENTRY glMultiTexCoord1fARB (GLenum target, GLfloat s);
+GLAPI void APIENTRY glMultiTexCoord1fvARB (GLenum target, const GLfloat *v);
+GLAPI void APIENTRY glMultiTexCoord1iARB (GLenum target, GLint s);
+GLAPI void APIENTRY glMultiTexCoord1ivARB (GLenum target, const GLint *v);
+GLAPI void APIENTRY glMultiTexCoord1sARB (GLenum target, GLshort s);
+GLAPI void APIENTRY glMultiTexCoord1svARB (GLenum target, const GLshort *v);
+GLAPI void APIENTRY glMultiTexCoord2dARB (GLenum target, GLdouble s, GLdouble t);
+GLAPI void APIENTRY glMultiTexCoord2dvARB (GLenum target, const GLdouble *v);
+GLAPI void APIENTRY glMultiTexCoord2fARB (GLenum target, GLfloat s, GLfloat t);
+GLAPI void APIENTRY glMultiTexCoord2fvARB (GLenum target, const GLfloat *v);
+GLAPI void APIENTRY glMultiTexCoord2iARB (GLenum target, GLint s, GLint t);
+GLAPI void APIENTRY glMultiTexCoord2ivARB (GLenum target, const GLint *v);
+GLAPI void APIENTRY glMultiTexCoord2sARB (GLenum target, GLshort s, GLshort t);
+GLAPI void APIENTRY glMultiTexCoord2svARB (GLenum target, const GLshort *v);
+GLAPI void APIENTRY glMultiTexCoord3dARB (GLenum target, GLdouble s, GLdouble t, GLdouble r);
+GLAPI void APIENTRY glMultiTexCoord3dvARB (GLenum target, const GLdouble *v);
+GLAPI void APIENTRY glMultiTexCoord3fARB (GLenum target, GLfloat s, GLfloat t, GLfloat r);
+GLAPI void APIENTRY glMultiTexCoord3fvARB (GLenum target, const GLfloat *v);
+GLAPI void APIENTRY glMultiTexCoord3iARB (GLenum target, GLint s, GLint t, GLint r);
+GLAPI void APIENTRY glMultiTexCoord3ivARB (GLenum target, const GLint *v);
+GLAPI void APIENTRY glMultiTexCoord3sARB (GLenum target, GLshort s, GLshort t, GLshort r);
+GLAPI void APIENTRY glMultiTexCoord3svARB (GLenum target, const GLshort *v);
+GLAPI void APIENTRY glMultiTexCoord4dARB (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q);
+GLAPI void APIENTRY glMultiTexCoord4dvARB (GLenum target, const GLdouble *v);
+GLAPI void APIENTRY glMultiTexCoord4fARB (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q);
+GLAPI void APIENTRY glMultiTexCoord4fvARB (GLenum target, const GLfloat *v);
+GLAPI void APIENTRY glMultiTexCoord4iARB (GLenum target, GLint s, GLint t, GLint r, GLint q);
+GLAPI void APIENTRY glMultiTexCoord4ivARB (GLenum target, const GLint *v);
+GLAPI void APIENTRY glMultiTexCoord4sARB (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q);
+GLAPI void APIENTRY glMultiTexCoord4svARB (GLenum target, const GLshort *v);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLACTIVETEXTUREARBPROC) (GLenum texture);
+typedef void (APIENTRYP PFNGLCLIENTACTIVETEXTUREARBPROC) (GLenum texture);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1DARBPROC) (GLenum target, GLdouble s);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1DVARBPROC) (GLenum target, const GLdouble *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1FARBPROC) (GLenum target, GLfloat s);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1FVARBPROC) (GLenum target, const GLfloat *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1IARBPROC) (GLenum target, GLint s);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1IVARBPROC) (GLenum target, const GLint *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1SARBPROC) (GLenum target, GLshort s);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1SVARBPROC) (GLenum target, const GLshort *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2DARBPROC) (GLenum target, GLdouble s, GLdouble t);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2DVARBPROC) (GLenum target, const GLdouble *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2FARBPROC) (GLenum target, GLfloat s, GLfloat t);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2FVARBPROC) (GLenum target, const GLfloat *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2IARBPROC) (GLenum target, GLint s, GLint t);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2IVARBPROC) (GLenum target, const GLint *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2SARBPROC) (GLenum target, GLshort s, GLshort t);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2SVARBPROC) (GLenum target, const GLshort *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3DVARBPROC) (GLenum target, const GLdouble *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3FVARBPROC) (GLenum target, const GLfloat *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3IARBPROC) (GLenum target, GLint s, GLint t, GLint r);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3IVARBPROC) (GLenum target, const GLint *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3SVARBPROC) (GLenum target, const GLshort *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4DVARBPROC) (GLenum target, const GLdouble *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4FVARBPROC) (GLenum target, const GLfloat *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4IARBPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4IVARBPROC) (GLenum target, const GLint *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4SVARBPROC) (GLenum target, const GLshort *v);
+#endif
+
+#ifndef GL_ARB_transpose_matrix
+#define GL_ARB_transpose_matrix 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glLoadTransposeMatrixfARB (const GLfloat *m);
+GLAPI void APIENTRY glLoadTransposeMatrixdARB (const GLdouble *m);
+GLAPI void APIENTRY glMultTransposeMatrixfARB (const GLfloat *m);
+GLAPI void APIENTRY glMultTransposeMatrixdARB (const GLdouble *m);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXFARBPROC) (const GLfloat *m);
+typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXDARBPROC) (const GLdouble *m);
+typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXFARBPROC) (const GLfloat *m);
+typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXDARBPROC) (const GLdouble *m);
+#endif
+
+#ifndef GL_ARB_multisample
+#define GL_ARB_multisample 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glSampleCoverageARB (GLclampf value, GLboolean invert);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLSAMPLECOVERAGEARBPROC) (GLclampf value, GLboolean invert);
+#endif
+
+#ifndef GL_ARB_texture_env_add
+#define GL_ARB_texture_env_add 1
+#endif
+
+#ifndef GL_ARB_texture_cube_map
+#define GL_ARB_texture_cube_map 1
+#endif
+
+#ifndef GL_ARB_texture_compression
+#define GL_ARB_texture_compression 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glCompressedTexImage3DARB (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data);
+GLAPI void APIENTRY glCompressedTexImage2DARB (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data);
+GLAPI void APIENTRY glCompressedTexImage1DARB (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data);
+GLAPI void APIENTRY glCompressedTexSubImage3DARB (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data);
+GLAPI void APIENTRY glCompressedTexSubImage2DARB (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data);
+GLAPI void APIENTRY glCompressedTexSubImage1DARB (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data);
+GLAPI void APIENTRY glGetCompressedTexImageARB (GLenum target, GLint level, GLvoid *img);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE1DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data);
+typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXIMAGEARBPROC) (GLenum target, GLint level, GLvoid *img);
+#endif
+
+#ifndef GL_ARB_texture_border_clamp
+#define GL_ARB_texture_border_clamp 1
+#endif
+
+#ifndef GL_ARB_point_parameters
+#define GL_ARB_point_parameters 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glPointParameterfARB (GLenum pname, GLfloat param);
+GLAPI void APIENTRY glPointParameterfvARB (GLenum pname, const GLfloat *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPOINTPARAMETERFARBPROC) (GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLPOINTPARAMETERFVARBPROC) (GLenum pname, const GLfloat *params);
+#endif
+
+#ifndef GL_ARB_vertex_blend
+#define GL_ARB_vertex_blend 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glWeightbvARB (GLint size, const GLbyte *weights);
+GLAPI void APIENTRY glWeightsvARB (GLint size, const GLshort *weights);
+GLAPI void APIENTRY glWeightivARB (GLint size, const GLint *weights);
+GLAPI void APIENTRY glWeightfvARB (GLint size, const GLfloat *weights);
+GLAPI void APIENTRY glWeightdvARB (GLint size, const GLdouble *weights);
+GLAPI void APIENTRY glWeightubvARB (GLint size, const GLubyte *weights);
+GLAPI void APIENTRY glWeightusvARB (GLint size, const GLushort *weights);
+GLAPI void APIENTRY glWeightuivARB (GLint size, const GLuint *weights);
+GLAPI void APIENTRY glWeightPointerARB (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+GLAPI void APIENTRY glVertexBlendARB (GLint count);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLWEIGHTBVARBPROC) (GLint size, const GLbyte *weights);
+typedef void (APIENTRYP PFNGLWEIGHTSVARBPROC) (GLint size, const GLshort *weights);
+typedef void (APIENTRYP PFNGLWEIGHTIVARBPROC) (GLint size, const GLint *weights);
+typedef void (APIENTRYP PFNGLWEIGHTFVARBPROC) (GLint size, const GLfloat *weights);
+typedef void (APIENTRYP PFNGLWEIGHTDVARBPROC) (GLint size, const GLdouble *weights);
+typedef void (APIENTRYP PFNGLWEIGHTUBVARBPROC) (GLint size, const GLubyte *weights);
+typedef void (APIENTRYP PFNGLWEIGHTUSVARBPROC) (GLint size, const GLushort *weights);
+typedef void (APIENTRYP PFNGLWEIGHTUIVARBPROC) (GLint size, const GLuint *weights);
+typedef void (APIENTRYP PFNGLWEIGHTPOINTERARBPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLVERTEXBLENDARBPROC) (GLint count);
+#endif
+
+#ifndef GL_ARB_matrix_palette
+#define GL_ARB_matrix_palette 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glCurrentPaletteMatrixARB (GLint index);
+GLAPI void APIENTRY glMatrixIndexubvARB (GLint size, const GLubyte *indices);
+GLAPI void APIENTRY glMatrixIndexusvARB (GLint size, const GLushort *indices);
+GLAPI void APIENTRY glMatrixIndexuivARB (GLint size, const GLuint *indices);
+GLAPI void APIENTRY glMatrixIndexPointerARB (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLCURRENTPALETTEMATRIXARBPROC) (GLint index);
+typedef void (APIENTRYP PFNGLMATRIXINDEXUBVARBPROC) (GLint size, const GLubyte *indices);
+typedef void (APIENTRYP PFNGLMATRIXINDEXUSVARBPROC) (GLint size, const GLushort *indices);
+typedef void (APIENTRYP PFNGLMATRIXINDEXUIVARBPROC) (GLint size, const GLuint *indices);
+typedef void (APIENTRYP PFNGLMATRIXINDEXPOINTERARBPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+#endif
+
+#ifndef GL_ARB_texture_env_combine
+#define GL_ARB_texture_env_combine 1
+#endif
+
+#ifndef GL_ARB_texture_env_crossbar
+#define GL_ARB_texture_env_crossbar 1
+#endif
+
+#ifndef GL_ARB_texture_env_dot3
+#define GL_ARB_texture_env_dot3 1
+#endif
+
+#ifndef GL_ARB_texture_mirrored_repeat
+#define GL_ARB_texture_mirrored_repeat 1
+#endif
+
+#ifndef GL_ARB_depth_texture
+#define GL_ARB_depth_texture 1
+#endif
+
+#ifndef GL_ARB_shadow
+#define GL_ARB_shadow 1
+#endif
+
+#ifndef GL_ARB_shadow_ambient
+#define GL_ARB_shadow_ambient 1
+#endif
+
+#ifndef GL_ARB_window_pos
+#define GL_ARB_window_pos 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glWindowPos2dARB (GLdouble x, GLdouble y);
+GLAPI void APIENTRY glWindowPos2dvARB (const GLdouble *v);
+GLAPI void APIENTRY glWindowPos2fARB (GLfloat x, GLfloat y);
+GLAPI void APIENTRY glWindowPos2fvARB (const GLfloat *v);
+GLAPI void APIENTRY glWindowPos2iARB (GLint x, GLint y);
+GLAPI void APIENTRY glWindowPos2ivARB (const GLint *v);
+GLAPI void APIENTRY glWindowPos2sARB (GLshort x, GLshort y);
+GLAPI void APIENTRY glWindowPos2svARB (const GLshort *v);
+GLAPI void APIENTRY glWindowPos3dARB (GLdouble x, GLdouble y, GLdouble z);
+GLAPI void APIENTRY glWindowPos3dvARB (const GLdouble *v);
+GLAPI void APIENTRY glWindowPos3fARB (GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glWindowPos3fvARB (const GLfloat *v);
+GLAPI void APIENTRY glWindowPos3iARB (GLint x, GLint y, GLint z);
+GLAPI void APIENTRY glWindowPos3ivARB (const GLint *v);
+GLAPI void APIENTRY glWindowPos3sARB (GLshort x, GLshort y, GLshort z);
+GLAPI void APIENTRY glWindowPos3svARB (const GLshort *v);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLWINDOWPOS2DARBPROC) (GLdouble x, GLdouble y);
+typedef void (APIENTRYP PFNGLWINDOWPOS2DVARBPROC) (const GLdouble *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS2FARBPROC) (GLfloat x, GLfloat y);
+typedef void (APIENTRYP PFNGLWINDOWPOS2FVARBPROC) (const GLfloat *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS2IARBPROC) (GLint x, GLint y);
+typedef void (APIENTRYP PFNGLWINDOWPOS2IVARBPROC) (const GLint *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS2SARBPROC) (GLshort x, GLshort y);
+typedef void (APIENTRYP PFNGLWINDOWPOS2SVARBPROC) (const GLshort *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS3DARBPROC) (GLdouble x, GLdouble y, GLdouble z);
+typedef void (APIENTRYP PFNGLWINDOWPOS3DVARBPROC) (const GLdouble *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS3FARBPROC) (GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLWINDOWPOS3FVARBPROC) (const GLfloat *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS3IARBPROC) (GLint x, GLint y, GLint z);
+typedef void (APIENTRYP PFNGLWINDOWPOS3IVARBPROC) (const GLint *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS3SARBPROC) (GLshort x, GLshort y, GLshort z);
+typedef void (APIENTRYP PFNGLWINDOWPOS3SVARBPROC) (const GLshort *v);
+#endif
+
+#ifndef GL_ARB_vertex_program
+#define GL_ARB_vertex_program 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glVertexAttrib1dARB (GLuint index, GLdouble x);
+GLAPI void APIENTRY glVertexAttrib1dvARB (GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttrib1fARB (GLuint index, GLfloat x);
+GLAPI void APIENTRY glVertexAttrib1fvARB (GLuint index, const GLfloat *v);
+GLAPI void APIENTRY glVertexAttrib1sARB (GLuint index, GLshort x);
+GLAPI void APIENTRY glVertexAttrib1svARB (GLuint index, const GLshort *v);
+GLAPI void APIENTRY glVertexAttrib2dARB (GLuint index, GLdouble x, GLdouble y);
+GLAPI void APIENTRY glVertexAttrib2dvARB (GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttrib2fARB (GLuint index, GLfloat x, GLfloat y);
+GLAPI void APIENTRY glVertexAttrib2fvARB (GLuint index, const GLfloat *v);
+GLAPI void APIENTRY glVertexAttrib2sARB (GLuint index, GLshort x, GLshort y);
+GLAPI void APIENTRY glVertexAttrib2svARB (GLuint index, const GLshort *v);
+GLAPI void APIENTRY glVertexAttrib3dARB (GLuint index, GLdouble x, GLdouble y, GLdouble z);
+GLAPI void APIENTRY glVertexAttrib3dvARB (GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttrib3fARB (GLuint index, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glVertexAttrib3fvARB (GLuint index, const GLfloat *v);
+GLAPI void APIENTRY glVertexAttrib3sARB (GLuint index, GLshort x, GLshort y, GLshort z);
+GLAPI void APIENTRY glVertexAttrib3svARB (GLuint index, const GLshort *v);
+GLAPI void APIENTRY glVertexAttrib4NbvARB (GLuint index, const GLbyte *v);
+GLAPI void APIENTRY glVertexAttrib4NivARB (GLuint index, const GLint *v);
+GLAPI void APIENTRY glVertexAttrib4NsvARB (GLuint index, const GLshort *v);
+GLAPI void APIENTRY glVertexAttrib4NubARB (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w);
+GLAPI void APIENTRY glVertexAttrib4NubvARB (GLuint index, const GLubyte *v);
+GLAPI void APIENTRY glVertexAttrib4NuivARB (GLuint index, const GLuint *v);
+GLAPI void APIENTRY glVertexAttrib4NusvARB (GLuint index, const GLushort *v);
+GLAPI void APIENTRY glVertexAttrib4bvARB (GLuint index, const GLbyte *v);
+GLAPI void APIENTRY glVertexAttrib4dARB (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+GLAPI void APIENTRY glVertexAttrib4dvARB (GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttrib4fARB (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+GLAPI void APIENTRY glVertexAttrib4fvARB (GLuint index, const GLfloat *v);
+GLAPI void APIENTRY glVertexAttrib4ivARB (GLuint index, const GLint *v);
+GLAPI void APIENTRY glVertexAttrib4sARB (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w);
+GLAPI void APIENTRY glVertexAttrib4svARB (GLuint index, const GLshort *v);
+GLAPI void APIENTRY glVertexAttrib4ubvARB (GLuint index, const GLubyte *v);
+GLAPI void APIENTRY glVertexAttrib4uivARB (GLuint index, const GLuint *v);
+GLAPI void APIENTRY glVertexAttrib4usvARB (GLuint index, const GLushort *v);
+GLAPI void APIENTRY glVertexAttribPointerARB (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer);
+GLAPI void APIENTRY glEnableVertexAttribArrayARB (GLuint index);
+GLAPI void APIENTRY glDisableVertexAttribArrayARB (GLuint index);
+GLAPI void APIENTRY glProgramStringARB (GLenum target, GLenum format, GLsizei len, const GLvoid *string);
+GLAPI void APIENTRY glBindProgramARB (GLenum target, GLuint program);
+GLAPI void APIENTRY glDeleteProgramsARB (GLsizei n, const GLuint *programs);
+GLAPI void APIENTRY glGenProgramsARB (GLsizei n, GLuint *programs);
+GLAPI void APIENTRY glProgramEnvParameter4dARB (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+GLAPI void APIENTRY glProgramEnvParameter4dvARB (GLenum target, GLuint index, const GLdouble *params);
+GLAPI void APIENTRY glProgramEnvParameter4fARB (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+GLAPI void APIENTRY glProgramEnvParameter4fvARB (GLenum target, GLuint index, const GLfloat *params);
+GLAPI void APIENTRY glProgramLocalParameter4dARB (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+GLAPI void APIENTRY glProgramLocalParameter4dvARB (GLenum target, GLuint index, const GLdouble *params);
+GLAPI void APIENTRY glProgramLocalParameter4fARB (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+GLAPI void APIENTRY glProgramLocalParameter4fvARB (GLenum target, GLuint index, const GLfloat *params);
+GLAPI void APIENTRY glGetProgramEnvParameterdvARB (GLenum target, GLuint index, GLdouble *params);
+GLAPI void APIENTRY glGetProgramEnvParameterfvARB (GLenum target, GLuint index, GLfloat *params);
+GLAPI void APIENTRY glGetProgramLocalParameterdvARB (GLenum target, GLuint index, GLdouble *params);
+GLAPI void APIENTRY glGetProgramLocalParameterfvARB (GLenum target, GLuint index, GLfloat *params);
+GLAPI void APIENTRY glGetProgramivARB (GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetProgramStringARB (GLenum target, GLenum pname, GLvoid *string);
+GLAPI void APIENTRY glGetVertexAttribdvARB (GLuint index, GLenum pname, GLdouble *params);
+GLAPI void APIENTRY glGetVertexAttribfvARB (GLuint index, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetVertexAttribivARB (GLuint index, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetVertexAttribPointervARB (GLuint index, GLenum pname, GLvoid* *pointer);
+GLAPI GLboolean APIENTRY glIsProgramARB (GLuint program);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1DARBPROC) (GLuint index, GLdouble x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1DVARBPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1FARBPROC) (GLuint index, GLfloat x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1FVARBPROC) (GLuint index, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1SARBPROC) (GLuint index, GLshort x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1SVARBPROC) (GLuint index, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2DARBPROC) (GLuint index, GLdouble x, GLdouble y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2DVARBPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2FARBPROC) (GLuint index, GLfloat x, GLfloat y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2FVARBPROC) (GLuint index, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2SARBPROC) (GLuint index, GLshort x, GLshort y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2SVARBPROC) (GLuint index, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3DARBPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3DVARBPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3FARBPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3FVARBPROC) (GLuint index, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3SARBPROC) (GLuint index, GLshort x, GLshort y, GLshort z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3SVARBPROC) (GLuint index, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4NBVARBPROC) (GLuint index, const GLbyte *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4NIVARBPROC) (GLuint index, const GLint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4NSVARBPROC) (GLuint index, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBARBPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBVARBPROC) (GLuint index, const GLubyte *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUIVARBPROC) (GLuint index, const GLuint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUSVARBPROC) (GLuint index, const GLushort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4BVARBPROC) (GLuint index, const GLbyte *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4DARBPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4DVARBPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4FARBPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4FVARBPROC) (GLuint index, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4IVARBPROC) (GLuint index, const GLint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4SARBPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4SVARBPROC) (GLuint index, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBVARBPROC) (GLuint index, const GLubyte *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4UIVARBPROC) (GLuint index, const GLuint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4USVARBPROC) (GLuint index, const GLushort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERARBPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLENABLEVERTEXATTRIBARRAYARBPROC) (GLuint index);
+typedef void (APIENTRYP PFNGLDISABLEVERTEXATTRIBARRAYARBPROC) (GLuint index);
+typedef void (APIENTRYP PFNGLPROGRAMSTRINGARBPROC) (GLenum target, GLenum format, GLsizei len, const GLvoid *string);
+typedef void (APIENTRYP PFNGLBINDPROGRAMARBPROC) (GLenum target, GLuint program);
+typedef void (APIENTRYP PFNGLDELETEPROGRAMSARBPROC) (GLsizei n, const GLuint *programs);
+typedef void (APIENTRYP PFNGLGENPROGRAMSARBPROC) (GLsizei n, GLuint *programs);
+typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETER4DARBPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETER4DVARBPROC) (GLenum target, GLuint index, const GLdouble *params);
+typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETER4FARBPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETER4FVARBPROC) (GLenum target, GLuint index, const GLfloat *params);
+typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETER4DARBPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETER4DVARBPROC) (GLenum target, GLuint index, const GLdouble *params);
+typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETER4FARBPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETER4FVARBPROC) (GLenum target, GLuint index, const GLfloat *params);
+typedef void (APIENTRYP PFNGLGETPROGRAMENVPARAMETERDVARBPROC) (GLenum target, GLuint index, GLdouble *params);
+typedef void (APIENTRYP PFNGLGETPROGRAMENVPARAMETERFVARBPROC) (GLenum target, GLuint index, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC) (GLenum target, GLuint index, GLdouble *params);
+typedef void (APIENTRYP PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC) (GLenum target, GLuint index, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETPROGRAMIVARBPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETPROGRAMSTRINGARBPROC) (GLenum target, GLenum pname, GLvoid *string);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBDVARBPROC) (GLuint index, GLenum pname, GLdouble *params);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBFVARBPROC) (GLuint index, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIVARBPROC) (GLuint index, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVARBPROC) (GLuint index, GLenum pname, GLvoid* *pointer);
+typedef GLboolean (APIENTRYP PFNGLISPROGRAMARBPROC) (GLuint program);
+#endif
+
+#ifndef GL_ARB_fragment_program
+#define GL_ARB_fragment_program 1
+/* All ARB_fragment_program entry points are shared with ARB_vertex_program. */
+#endif
+
+#ifndef GL_ARB_vertex_buffer_object
+#define GL_ARB_vertex_buffer_object 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBindBufferARB (GLenum target, GLuint buffer);
+GLAPI void APIENTRY glDeleteBuffersARB (GLsizei n, const GLuint *buffers);
+GLAPI void APIENTRY glGenBuffersARB (GLsizei n, GLuint *buffers);
+GLAPI GLboolean APIENTRY glIsBufferARB (GLuint buffer);
+GLAPI void APIENTRY glBufferDataARB (GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage);
+GLAPI void APIENTRY glBufferSubDataARB (GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid *data);
+GLAPI void APIENTRY glGetBufferSubDataARB (GLenum target, GLintptrARB offset, GLsizeiptrARB size, GLvoid *data);
+GLAPI GLvoid* APIENTRY glMapBufferARB (GLenum target, GLenum access);
+GLAPI GLboolean APIENTRY glUnmapBufferARB (GLenum target);
+GLAPI void APIENTRY glGetBufferParameterivARB (GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetBufferPointervARB (GLenum target, GLenum pname, GLvoid* *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBINDBUFFERARBPROC) (GLenum target, GLuint buffer);
+typedef void (APIENTRYP PFNGLDELETEBUFFERSARBPROC) (GLsizei n, const GLuint *buffers);
+typedef void (APIENTRYP PFNGLGENBUFFERSARBPROC) (GLsizei n, GLuint *buffers);
+typedef GLboolean (APIENTRYP PFNGLISBUFFERARBPROC) (GLuint buffer);
+typedef void (APIENTRYP PFNGLBUFFERDATAARBPROC) (GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage);
+typedef void (APIENTRYP PFNGLBUFFERSUBDATAARBPROC) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid *data);
+typedef void (APIENTRYP PFNGLGETBUFFERSUBDATAARBPROC) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, GLvoid *data);
+typedef GLvoid* (APIENTRYP PFNGLMAPBUFFERARBPROC) (GLenum target, GLenum access);
+typedef GLboolean (APIENTRYP PFNGLUNMAPBUFFERARBPROC) (GLenum target);
+typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERIVARBPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETBUFFERPOINTERVARBPROC) (GLenum target, GLenum pname, GLvoid* *params);
+#endif
+
+#ifndef GL_ARB_occlusion_query
+#define GL_ARB_occlusion_query 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGenQueriesARB (GLsizei n, GLuint *ids);
+GLAPI void APIENTRY glDeleteQueriesARB (GLsizei n, const GLuint *ids);
+GLAPI GLboolean APIENTRY glIsQueryARB (GLuint id);
+GLAPI void APIENTRY glBeginQueryARB (GLenum target, GLuint id);
+GLAPI void APIENTRY glEndQueryARB (GLenum target);
+GLAPI void APIENTRY glGetQueryivARB (GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetQueryObjectivARB (GLuint id, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetQueryObjectuivARB (GLuint id, GLenum pname, GLuint *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLGENQUERIESARBPROC) (GLsizei n, GLuint *ids);
+typedef void (APIENTRYP PFNGLDELETEQUERIESARBPROC) (GLsizei n, const GLuint *ids);
+typedef GLboolean (APIENTRYP PFNGLISQUERYARBPROC) (GLuint id);
+typedef void (APIENTRYP PFNGLBEGINQUERYARBPROC) (GLenum target, GLuint id);
+typedef void (APIENTRYP PFNGLENDQUERYARBPROC) (GLenum target);
+typedef void (APIENTRYP PFNGLGETQUERYIVARBPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETQUERYOBJECTIVARBPROC) (GLuint id, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETQUERYOBJECTUIVARBPROC) (GLuint id, GLenum pname, GLuint *params);
+#endif
+
+#ifndef GL_ARB_shader_objects
+#define GL_ARB_shader_objects 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDeleteObjectARB (GLhandleARB obj);
+GLAPI GLhandleARB APIENTRY glGetHandleARB (GLenum pname);
+GLAPI void APIENTRY glDetachObjectARB (GLhandleARB containerObj, GLhandleARB attachedObj);
+GLAPI GLhandleARB APIENTRY glCreateShaderObjectARB (GLenum shaderType);
+GLAPI void APIENTRY glShaderSourceARB (GLhandleARB shaderObj, GLsizei count, const GLcharARB* *string, const GLint *length);
+GLAPI void APIENTRY glCompileShaderARB (GLhandleARB shaderObj);
+GLAPI GLhandleARB APIENTRY glCreateProgramObjectARB (void);
+GLAPI void APIENTRY glAttachObjectARB (GLhandleARB containerObj, GLhandleARB obj);
+GLAPI void APIENTRY glLinkProgramARB (GLhandleARB programObj);
+GLAPI void APIENTRY glUseProgramObjectARB (GLhandleARB programObj);
+GLAPI void APIENTRY glValidateProgramARB (GLhandleARB programObj);
+GLAPI void APIENTRY glUniform1fARB (GLint location, GLfloat v0);
+GLAPI void APIENTRY glUniform2fARB (GLint location, GLfloat v0, GLfloat v1);
+GLAPI void APIENTRY glUniform3fARB (GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
+GLAPI void APIENTRY glUniform4fARB (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
+GLAPI void APIENTRY glUniform1iARB (GLint location, GLint v0);
+GLAPI void APIENTRY glUniform2iARB (GLint location, GLint v0, GLint v1);
+GLAPI void APIENTRY glUniform3iARB (GLint location, GLint v0, GLint v1, GLint v2);
+GLAPI void APIENTRY glUniform4iARB (GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
+GLAPI void APIENTRY glUniform1fvARB (GLint location, GLsizei count, const GLfloat *value);
+GLAPI void APIENTRY glUniform2fvARB (GLint location, GLsizei count, const GLfloat *value);
+GLAPI void APIENTRY glUniform3fvARB (GLint location, GLsizei count, const GLfloat *value);
+GLAPI void APIENTRY glUniform4fvARB (GLint location, GLsizei count, const GLfloat *value);
+GLAPI void APIENTRY glUniform1ivARB (GLint location, GLsizei count, const GLint *value);
+GLAPI void APIENTRY glUniform2ivARB (GLint location, GLsizei count, const GLint *value);
+GLAPI void APIENTRY glUniform3ivARB (GLint location, GLsizei count, const GLint *value);
+GLAPI void APIENTRY glUniform4ivARB (GLint location, GLsizei count, const GLint *value);
+GLAPI void APIENTRY glUniformMatrix2fvARB (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glUniformMatrix3fvARB (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glUniformMatrix4fvARB (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glGetObjectParameterfvARB (GLhandleARB obj, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetObjectParameterivARB (GLhandleARB obj, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetInfoLogARB (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *infoLog);
+GLAPI void APIENTRY glGetAttachedObjectsARB (GLhandleARB containerObj, GLsizei maxCount, GLsizei *count, GLhandleARB *obj);
+GLAPI GLint APIENTRY glGetUniformLocationARB (GLhandleARB programObj, const GLcharARB *name);
+GLAPI void APIENTRY glGetActiveUniformARB (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name);
+GLAPI void APIENTRY glGetUniformfvARB (GLhandleARB programObj, GLint location, GLfloat *params);
+GLAPI void APIENTRY glGetUniformivARB (GLhandleARB programObj, GLint location, GLint *params);
+GLAPI void APIENTRY glGetShaderSourceARB (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *source);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLDELETEOBJECTARBPROC) (GLhandleARB obj);
+typedef GLhandleARB (APIENTRYP PFNGLGETHANDLEARBPROC) (GLenum pname);
+typedef void (APIENTRYP PFNGLDETACHOBJECTARBPROC) (GLhandleARB containerObj, GLhandleARB attachedObj);
+typedef GLhandleARB (APIENTRYP PFNGLCREATESHADEROBJECTARBPROC) (GLenum shaderType);
+typedef void (APIENTRYP PFNGLSHADERSOURCEARBPROC) (GLhandleARB shaderObj, GLsizei count, const GLcharARB* *string, const GLint *length);
+typedef void (APIENTRYP PFNGLCOMPILESHADERARBPROC) (GLhandleARB shaderObj);
+typedef GLhandleARB (APIENTRYP PFNGLCREATEPROGRAMOBJECTARBPROC) (void);
+typedef void (APIENTRYP PFNGLATTACHOBJECTARBPROC) (GLhandleARB containerObj, GLhandleARB obj);
+typedef void (APIENTRYP PFNGLLINKPROGRAMARBPROC) (GLhandleARB programObj);
+typedef void (APIENTRYP PFNGLUSEPROGRAMOBJECTARBPROC) (GLhandleARB programObj);
+typedef void (APIENTRYP PFNGLVALIDATEPROGRAMARBPROC) (GLhandleARB programObj);
+typedef void (APIENTRYP PFNGLUNIFORM1FARBPROC) (GLint location, GLfloat v0);
+typedef void (APIENTRYP PFNGLUNIFORM2FARBPROC) (GLint location, GLfloat v0, GLfloat v1);
+typedef void (APIENTRYP PFNGLUNIFORM3FARBPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
+typedef void (APIENTRYP PFNGLUNIFORM4FARBPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
+typedef void (APIENTRYP PFNGLUNIFORM1IARBPROC) (GLint location, GLint v0);
+typedef void (APIENTRYP PFNGLUNIFORM2IARBPROC) (GLint location, GLint v0, GLint v1);
+typedef void (APIENTRYP PFNGLUNIFORM3IARBPROC) (GLint location, GLint v0, GLint v1, GLint v2);
+typedef void (APIENTRYP PFNGLUNIFORM4IARBPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
+typedef void (APIENTRYP PFNGLUNIFORM1FVARBPROC) (GLint location, GLsizei count, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORM2FVARBPROC) (GLint location, GLsizei count, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORM3FVARBPROC) (GLint location, GLsizei count, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORM4FVARBPROC) (GLint location, GLsizei count, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORM1IVARBPROC) (GLint location, GLsizei count, const GLint *value);
+typedef void (APIENTRYP PFNGLUNIFORM2IVARBPROC) (GLint location, GLsizei count, const GLint *value);
+typedef void (APIENTRYP PFNGLUNIFORM3IVARBPROC) (GLint location, GLsizei count, const GLint *value);
+typedef void (APIENTRYP PFNGLUNIFORM4IVARBPROC) (GLint location, GLsizei count, const GLint *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX2FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX3FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX4FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLGETOBJECTPARAMETERFVARBPROC) (GLhandleARB obj, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETOBJECTPARAMETERIVARBPROC) (GLhandleARB obj, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETINFOLOGARBPROC) (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *infoLog);
+typedef void (APIENTRYP PFNGLGETATTACHEDOBJECTSARBPROC) (GLhandleARB containerObj, GLsizei maxCount, GLsizei *count, GLhandleARB *obj);
+typedef GLint (APIENTRYP PFNGLGETUNIFORMLOCATIONARBPROC) (GLhandleARB programObj, const GLcharARB *name);
+typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMARBPROC) (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name);
+typedef void (APIENTRYP PFNGLGETUNIFORMFVARBPROC) (GLhandleARB programObj, GLint location, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETUNIFORMIVARBPROC) (GLhandleARB programObj, GLint location, GLint *params);
+typedef void (APIENTRYP PFNGLGETSHADERSOURCEARBPROC) (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *source);
+#endif
+
+#ifndef GL_ARB_vertex_shader
+#define GL_ARB_vertex_shader 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBindAttribLocationARB (GLhandleARB programObj, GLuint index, const GLcharARB *name);
+GLAPI void APIENTRY glGetActiveAttribARB (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name);
+GLAPI GLint APIENTRY glGetAttribLocationARB (GLhandleARB programObj, const GLcharARB *name);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBINDATTRIBLOCATIONARBPROC) (GLhandleARB programObj, GLuint index, const GLcharARB *name);
+typedef void (APIENTRYP PFNGLGETACTIVEATTRIBARBPROC) (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name);
+typedef GLint (APIENTRYP PFNGLGETATTRIBLOCATIONARBPROC) (GLhandleARB programObj, const GLcharARB *name);
+#endif
+
+#ifndef GL_ARB_fragment_shader
+#define GL_ARB_fragment_shader 1
+#endif
+
+#ifndef GL_ARB_shading_language_100
+#define GL_ARB_shading_language_100 1
+#endif
+
+#ifndef GL_ARB_texture_non_power_of_two
+#define GL_ARB_texture_non_power_of_two 1
+#endif
+
+#ifndef GL_ARB_point_sprite
+#define GL_ARB_point_sprite 1
+#endif
+
+#ifndef GL_ARB_fragment_program_shadow
+#define GL_ARB_fragment_program_shadow 1
+#endif
+
+#ifndef GL_ARB_draw_buffers
+#define GL_ARB_draw_buffers 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDrawBuffersARB (GLsizei n, const GLenum *bufs);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLDRAWBUFFERSARBPROC) (GLsizei n, const GLenum *bufs);
+#endif
+
+#ifndef GL_ARB_texture_rectangle
+#define GL_ARB_texture_rectangle 1
+#endif
+
+#ifndef GL_ARB_color_buffer_float
+#define GL_ARB_color_buffer_float 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glClampColorARB (GLenum target, GLenum clamp);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLCLAMPCOLORARBPROC) (GLenum target, GLenum clamp);
+#endif
+
+#ifndef GL_ARB_half_float_pixel
+#define GL_ARB_half_float_pixel 1
+#endif
+
+#ifndef GL_ARB_texture_float
+#define GL_ARB_texture_float 1
+#endif
+
+#ifndef GL_ARB_pixel_buffer_object
+#define GL_ARB_pixel_buffer_object 1
+#endif
+
+#ifndef GL_ARB_depth_buffer_float
+#define GL_ARB_depth_buffer_float 1
+#endif
+
+#ifndef GL_ARB_draw_instanced
+#define GL_ARB_draw_instanced 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDrawArraysInstancedARB (GLenum mode, GLint first, GLsizei count, GLsizei primcount);
+GLAPI void APIENTRY glDrawElementsInstancedARB (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDARBPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount);
+typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDARBPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount);
+#endif
+
+#ifndef GL_ARB_framebuffer_object
+#define GL_ARB_framebuffer_object 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI GLboolean APIENTRY glIsRenderbuffer (GLuint renderbuffer);
+GLAPI void APIENTRY glBindRenderbuffer (GLenum target, GLuint renderbuffer);
+GLAPI void APIENTRY glDeleteRenderbuffers (GLsizei n, const GLuint *renderbuffers);
+GLAPI void APIENTRY glGenRenderbuffers (GLsizei n, GLuint *renderbuffers);
+GLAPI void APIENTRY glRenderbufferStorage (GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
+GLAPI void APIENTRY glGetRenderbufferParameteriv (GLenum target, GLenum pname, GLint *params);
+GLAPI GLboolean APIENTRY glIsFramebuffer (GLuint framebuffer);
+GLAPI void APIENTRY glBindFramebuffer (GLenum target, GLuint framebuffer);
+GLAPI void APIENTRY glDeleteFramebuffers (GLsizei n, const GLuint *framebuffers);
+GLAPI void APIENTRY glGenFramebuffers (GLsizei n, GLuint *framebuffers);
+GLAPI GLenum APIENTRY glCheckFramebufferStatus (GLenum target);
+GLAPI void APIENTRY glFramebufferTexture1D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+GLAPI void APIENTRY glFramebufferTexture2D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+GLAPI void APIENTRY glFramebufferTexture3D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset);
+GLAPI void APIENTRY glFramebufferRenderbuffer (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+GLAPI void APIENTRY glGetFramebufferAttachmentParameteriv (GLenum target, GLenum attachment, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGenerateMipmap (GLenum target);
+GLAPI void APIENTRY glBlitFramebuffer (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+GLAPI void APIENTRY glRenderbufferStorageMultisample (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+GLAPI void APIENTRY glFramebufferTextureLayer (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef GLboolean (APIENTRYP PFNGLISRENDERBUFFERPROC) (GLuint renderbuffer);
+typedef void (APIENTRYP PFNGLBINDRENDERBUFFERPROC) (GLenum target, GLuint renderbuffer);
+typedef void (APIENTRYP PFNGLDELETERENDERBUFFERSPROC) (GLsizei n, const GLuint *renderbuffers);
+typedef void (APIENTRYP PFNGLGENRENDERBUFFERSPROC) (GLsizei n, GLuint *renderbuffers);
+typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (APIENTRYP PFNGLGETRENDERBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef GLboolean (APIENTRYP PFNGLISFRAMEBUFFERPROC) (GLuint framebuffer);
+typedef void (APIENTRYP PFNGLBINDFRAMEBUFFERPROC) (GLenum target, GLuint framebuffer);
+typedef void (APIENTRYP PFNGLDELETEFRAMEBUFFERSPROC) (GLsizei n, const GLuint *framebuffers);
+typedef void (APIENTRYP PFNGLGENFRAMEBUFFERSPROC) (GLsizei n, GLuint *framebuffers);
+typedef GLenum (APIENTRYP PFNGLCHECKFRAMEBUFFERSTATUSPROC) (GLenum target);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE1DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE3DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERRENDERBUFFERPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+typedef void (APIENTRYP PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC) (GLenum target, GLenum attachment, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGENERATEMIPMAPPROC) (GLenum target);
+typedef void (APIENTRYP PFNGLBLITFRAMEBUFFERPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURELAYERPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer);
+#endif
+
+#ifndef GL_ARB_framebuffer_sRGB
+#define GL_ARB_framebuffer_sRGB 1
+#endif
+
+#ifndef GL_ARB_geometry_shader4
+#define GL_ARB_geometry_shader4 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glProgramParameteriARB (GLuint program, GLenum pname, GLint value);
+GLAPI void APIENTRY glFramebufferTextureARB (GLenum target, GLenum attachment, GLuint texture, GLint level);
+GLAPI void APIENTRY glFramebufferTextureLayerARB (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer);
+GLAPI void APIENTRY glFramebufferTextureFaceARB (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPROGRAMPARAMETERIARBPROC) (GLuint program, GLenum pname, GLint value);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREARBPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURELAYERARBPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREFACEARBPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face);
+#endif
+
+#ifndef GL_ARB_half_float_vertex
+#define GL_ARB_half_float_vertex 1
+#endif
+
+#ifndef GL_ARB_instanced_arrays
+#define GL_ARB_instanced_arrays 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glVertexAttribDivisorARB (GLuint index, GLuint divisor);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLVERTEXATTRIBDIVISORARBPROC) (GLuint index, GLuint divisor);
+#endif
+
+#ifndef GL_ARB_map_buffer_range
+#define GL_ARB_map_buffer_range 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI GLvoid* APIENTRY glMapBufferRange (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access);
+GLAPI void APIENTRY glFlushMappedBufferRange (GLenum target, GLintptr offset, GLsizeiptr length);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef GLvoid* (APIENTRYP PFNGLMAPBUFFERRANGEPROC) (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access);
+typedef void (APIENTRYP PFNGLFLUSHMAPPEDBUFFERRANGEPROC) (GLenum target, GLintptr offset, GLsizeiptr length);
+#endif
+
+#ifndef GL_ARB_texture_buffer_object
+#define GL_ARB_texture_buffer_object 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTexBufferARB (GLenum target, GLenum internalformat, GLuint buffer);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLTEXBUFFERARBPROC) (GLenum target, GLenum internalformat, GLuint buffer);
+#endif
+
+#ifndef GL_ARB_texture_compression_rgtc
+#define GL_ARB_texture_compression_rgtc 1
+#endif
+
+#ifndef GL_ARB_texture_rg
+#define GL_ARB_texture_rg 1
+#endif
+
+#ifndef GL_ARB_vertex_array_object
+#define GL_ARB_vertex_array_object 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBindVertexArray (GLuint array);
+GLAPI void APIENTRY glDeleteVertexArrays (GLsizei n, const GLuint *arrays);
+GLAPI void APIENTRY glGenVertexArrays (GLsizei n, GLuint *arrays);
+GLAPI GLboolean APIENTRY glIsVertexArray (GLuint array);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBINDVERTEXARRAYPROC) (GLuint array);
+typedef void (APIENTRYP PFNGLDELETEVERTEXARRAYSPROC) (GLsizei n, const GLuint *arrays);
+typedef void (APIENTRYP PFNGLGENVERTEXARRAYSPROC) (GLsizei n, GLuint *arrays);
+typedef GLboolean (APIENTRYP PFNGLISVERTEXARRAYPROC) (GLuint array);
+#endif
+
+#ifndef GL_ARB_uniform_buffer_object
+#define GL_ARB_uniform_buffer_object 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGetUniformIndices (GLuint program, GLsizei uniformCount, const GLchar* *uniformNames, GLuint *uniformIndices);
+GLAPI void APIENTRY glGetActiveUniformsiv (GLuint program, GLsizei uniformCount, const GLuint *uniformIndices, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetActiveUniformName (GLuint program, GLuint uniformIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformName);
+GLAPI GLuint APIENTRY glGetUniformBlockIndex (GLuint program, const GLchar *uniformBlockName);
+GLAPI void APIENTRY glGetActiveUniformBlockiv (GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetActiveUniformBlockName (GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName);
+GLAPI void APIENTRY glUniformBlockBinding (GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLGETUNIFORMINDICESPROC) (GLuint program, GLsizei uniformCount, const GLchar* *uniformNames, GLuint *uniformIndices);
+typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMSIVPROC) (GLuint program, GLsizei uniformCount, const GLuint *uniformIndices, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMNAMEPROC) (GLuint program, GLuint uniformIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformName);
+typedef GLuint (APIENTRYP PFNGLGETUNIFORMBLOCKINDEXPROC) (GLuint program, const GLchar *uniformBlockName);
+typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMBLOCKIVPROC) (GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC) (GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName);
+typedef void (APIENTRYP PFNGLUNIFORMBLOCKBINDINGPROC) (GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding);
+#endif
+
+#ifndef GL_ARB_compatibility
+#define GL_ARB_compatibility 1
+#endif
+
+#ifndef GL_ARB_copy_buffer
+#define GL_ARB_copy_buffer 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glCopyBufferSubData (GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLCOPYBUFFERSUBDATAPROC) (GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
+#endif
+
+#ifndef GL_ARB_shader_texture_lod
+#define GL_ARB_shader_texture_lod 1
+#endif
+
+#ifndef GL_ARB_depth_clamp
+#define GL_ARB_depth_clamp 1
+#endif
+
+#ifndef GL_ARB_draw_elements_base_vertex
+#define GL_ARB_draw_elements_base_vertex 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDrawElementsBaseVertex (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLint basevertex);
+GLAPI void APIENTRY glDrawRangeElementsBaseVertex (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices, GLint basevertex);
+GLAPI void APIENTRY glDrawElementsInstancedBaseVertex (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount, GLint basevertex);
+GLAPI void APIENTRY glMultiDrawElementsBaseVertex (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount, const GLint *basevertex);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLDRAWELEMENTSBASEVERTEXPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLint basevertex);
+typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices, GLint basevertex);
+typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount, GLint basevertex);
+typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC) (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount, const GLint *basevertex);
+#endif
+
+#ifndef GL_ARB_fragment_coord_conventions
+#define GL_ARB_fragment_coord_conventions 1
+#endif
+
+#ifndef GL_ARB_provoking_vertex
+#define GL_ARB_provoking_vertex 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glProvokingVertex (GLenum mode);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPROVOKINGVERTEXPROC) (GLenum mode);
+#endif
+
+#ifndef GL_ARB_seamless_cube_map
+#define GL_ARB_seamless_cube_map 1
+#endif
+
+#ifndef GL_ARB_sync
+#define GL_ARB_sync 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI GLsync APIENTRY glFenceSync (GLenum condition, GLbitfield flags);
+GLAPI GLboolean APIENTRY glIsSync (GLsync sync);
+GLAPI void APIENTRY glDeleteSync (GLsync sync);
+GLAPI GLenum APIENTRY glClientWaitSync (GLsync sync, GLbitfield flags, GLuint64 timeout);
+GLAPI void APIENTRY glWaitSync (GLsync sync, GLbitfield flags, GLuint64 timeout);
+GLAPI void APIENTRY glGetInteger64v (GLenum pname, GLint64 *params);
+GLAPI void APIENTRY glGetSynciv (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef GLsync (APIENTRYP PFNGLFENCESYNCPROC) (GLenum condition, GLbitfield flags);
+typedef GLboolean (APIENTRYP PFNGLISSYNCPROC) (GLsync sync);
+typedef void (APIENTRYP PFNGLDELETESYNCPROC) (GLsync sync);
+typedef GLenum (APIENTRYP PFNGLCLIENTWAITSYNCPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout);
+typedef void (APIENTRYP PFNGLWAITSYNCPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout);
+typedef void (APIENTRYP PFNGLGETINTEGER64VPROC) (GLenum pname, GLint64 *params);
+typedef void (APIENTRYP PFNGLGETSYNCIVPROC) (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values);
+#endif
+
+#ifndef GL_ARB_texture_multisample
+#define GL_ARB_texture_multisample 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTexImage2DMultisample (GLenum target, GLsizei samples, GLint internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations);
+GLAPI void APIENTRY glTexImage3DMultisample (GLenum target, GLsizei samples, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations);
+GLAPI void APIENTRY glGetMultisamplefv (GLenum pname, GLuint index, GLfloat *val);
+GLAPI void APIENTRY glSampleMaski (GLuint index, GLbitfield mask);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLTEXIMAGE2DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLint internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations);
+typedef void (APIENTRYP PFNGLTEXIMAGE3DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations);
+typedef void (APIENTRYP PFNGLGETMULTISAMPLEFVPROC) (GLenum pname, GLuint index, GLfloat *val);
+typedef void (APIENTRYP PFNGLSAMPLEMASKIPROC) (GLuint index, GLbitfield mask);
+#endif
+
+#ifndef GL_ARB_vertex_array_bgra
+#define GL_ARB_vertex_array_bgra 1
+#endif
+
+#ifndef GL_ARB_draw_buffers_blend
+#define GL_ARB_draw_buffers_blend 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBlendEquationiARB (GLuint buf, GLenum mode);
+GLAPI void APIENTRY glBlendEquationSeparateiARB (GLuint buf, GLenum modeRGB, GLenum modeAlpha);
+GLAPI void APIENTRY glBlendFunciARB (GLuint buf, GLenum src, GLenum dst);
+GLAPI void APIENTRY glBlendFuncSeparateiARB (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBLENDEQUATIONIARBPROC) (GLuint buf, GLenum mode);
+typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEIARBPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha);
+typedef void (APIENTRYP PFNGLBLENDFUNCIARBPROC) (GLuint buf, GLenum src, GLenum dst);
+typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEIARBPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+#endif
+
+#ifndef GL_ARB_sample_shading
+#define GL_ARB_sample_shading 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glMinSampleShadingARB (GLclampf value);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLMINSAMPLESHADINGARBPROC) (GLclampf value);
+#endif
+
+#ifndef GL_ARB_texture_cube_map_array
+#define GL_ARB_texture_cube_map_array 1
+#endif
+
+#ifndef GL_ARB_texture_gather
+#define GL_ARB_texture_gather 1
+#endif
+
+#ifndef GL_ARB_texture_query_lod
+#define GL_ARB_texture_query_lod 1
+#endif
+
+#ifndef GL_ARB_shading_language_include
+#define GL_ARB_shading_language_include 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glNamedStringARB (GLenum type, GLint namelen, const GLchar *name, GLint stringlen, const GLchar *string);
+GLAPI void APIENTRY glDeleteNamedStringARB (GLint namelen, const GLchar *name);
+GLAPI void APIENTRY glCompileShaderIncludeARB (GLuint shader, GLsizei count, const GLchar* *path, const GLint *length);
+GLAPI GLboolean APIENTRY glIsNamedStringARB (GLint namelen, const GLchar *name);
+GLAPI void APIENTRY glGetNamedStringARB (GLint namelen, const GLchar *name, GLsizei bufSize, GLint *stringlen, GLchar *string);
+GLAPI void APIENTRY glGetNamedStringivARB (GLint namelen, const GLchar *name, GLenum pname, GLint *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLNAMEDSTRINGARBPROC) (GLenum type, GLint namelen, const GLchar *name, GLint stringlen, const GLchar *string);
+typedef void (APIENTRYP PFNGLDELETENAMEDSTRINGARBPROC) (GLint namelen, const GLchar *name);
+typedef void (APIENTRYP PFNGLCOMPILESHADERINCLUDEARBPROC) (GLuint shader, GLsizei count, const GLchar* *path, const GLint *length);
+typedef GLboolean (APIENTRYP PFNGLISNAMEDSTRINGARBPROC) (GLint namelen, const GLchar *name);
+typedef void (APIENTRYP PFNGLGETNAMEDSTRINGARBPROC) (GLint namelen, const GLchar *name, GLsizei bufSize, GLint *stringlen, GLchar *string);
+typedef void (APIENTRYP PFNGLGETNAMEDSTRINGIVARBPROC) (GLint namelen, const GLchar *name, GLenum pname, GLint *params);
+#endif
+
+#ifndef GL_ARB_texture_compression_bptc
+#define GL_ARB_texture_compression_bptc 1
+#endif
+
+#ifndef GL_ARB_blend_func_extended
+#define GL_ARB_blend_func_extended 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBindFragDataLocationIndexed (GLuint program, GLuint colorNumber, GLuint index, const GLchar *name);
+GLAPI GLint APIENTRY glGetFragDataIndex (GLuint program, const GLchar *name);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBINDFRAGDATALOCATIONINDEXEDPROC) (GLuint program, GLuint colorNumber, GLuint index, const GLchar *name);
+typedef GLint (APIENTRYP PFNGLGETFRAGDATAINDEXPROC) (GLuint program, const GLchar *name);
+#endif
+
+#ifndef GL_ARB_explicit_attrib_location
+#define GL_ARB_explicit_attrib_location 1
+#endif
+
+#ifndef GL_ARB_occlusion_query2
+#define GL_ARB_occlusion_query2 1
+#endif
+
+#ifndef GL_ARB_sampler_objects
+#define GL_ARB_sampler_objects 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGenSamplers (GLsizei count, GLuint *samplers);
+GLAPI void APIENTRY glDeleteSamplers (GLsizei count, const GLuint *samplers);
+GLAPI GLboolean APIENTRY glIsSampler (GLuint sampler);
+GLAPI void APIENTRY glBindSampler (GLuint unit, GLuint sampler);
+GLAPI void APIENTRY glSamplerParameteri (GLuint sampler, GLenum pname, GLint param);
+GLAPI void APIENTRY glSamplerParameteriv (GLuint sampler, GLenum pname, const GLint *param);
+GLAPI void APIENTRY glSamplerParameterf (GLuint sampler, GLenum pname, GLfloat param);
+GLAPI void APIENTRY glSamplerParameterfv (GLuint sampler, GLenum pname, const GLfloat *param);
+GLAPI void APIENTRY glSamplerParameterIiv (GLuint sampler, GLenum pname, const GLint *param);
+GLAPI void APIENTRY glSamplerParameterIuiv (GLuint sampler, GLenum pname, const GLuint *param);
+GLAPI void APIENTRY glGetSamplerParameteriv (GLuint sampler, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetSamplerParameterIiv (GLuint sampler, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetSamplerParameterfv (GLuint sampler, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetSamplerParameterIuiv (GLuint sampler, GLenum pname, GLuint *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLGENSAMPLERSPROC) (GLsizei count, GLuint *samplers);
+typedef void (APIENTRYP PFNGLDELETESAMPLERSPROC) (GLsizei count, const GLuint *samplers);
+typedef GLboolean (APIENTRYP PFNGLISSAMPLERPROC) (GLuint sampler);
+typedef void (APIENTRYP PFNGLBINDSAMPLERPROC) (GLuint unit, GLuint sampler);
+typedef void (APIENTRYP PFNGLSAMPLERPARAMETERIPROC) (GLuint sampler, GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLSAMPLERPARAMETERIVPROC) (GLuint sampler, GLenum pname, const GLint *param);
+typedef void (APIENTRYP PFNGLSAMPLERPARAMETERFPROC) (GLuint sampler, GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLSAMPLERPARAMETERFVPROC) (GLuint sampler, GLenum pname, const GLfloat *param);
+typedef void (APIENTRYP PFNGLSAMPLERPARAMETERIIVPROC) (GLuint sampler, GLenum pname, const GLint *param);
+typedef void (APIENTRYP PFNGLSAMPLERPARAMETERIUIVPROC) (GLuint sampler, GLenum pname, const GLuint *param);
+typedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERIVPROC) (GLuint sampler, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERIIVPROC) (GLuint sampler, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERFVPROC) (GLuint sampler, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERIUIVPROC) (GLuint sampler, GLenum pname, GLuint *params);
+#endif
+
+#ifndef GL_ARB_shader_bit_encoding
+#define GL_ARB_shader_bit_encoding 1
+#endif
+
+#ifndef GL_ARB_texture_rgb10_a2ui
+#define GL_ARB_texture_rgb10_a2ui 1
+#endif
+
+#ifndef GL_ARB_texture_swizzle
+#define GL_ARB_texture_swizzle 1
+#endif
+
+#ifndef GL_ARB_timer_query
+#define GL_ARB_timer_query 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glQueryCounter (GLuint id, GLenum target);
+GLAPI void APIENTRY glGetQueryObjecti64v (GLuint id, GLenum pname, GLint64 *params);
+GLAPI void APIENTRY glGetQueryObjectui64v (GLuint id, GLenum pname, GLuint64 *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLQUERYCOUNTERPROC) (GLuint id, GLenum target);
+typedef void (APIENTRYP PFNGLGETQUERYOBJECTI64VPROC) (GLuint id, GLenum pname, GLint64 *params);
+typedef void (APIENTRYP PFNGLGETQUERYOBJECTUI64VPROC) (GLuint id, GLenum pname, GLuint64 *params);
+#endif
+
+#ifndef GL_ARB_vertex_type_2_10_10_10_rev
+#define GL_ARB_vertex_type_2_10_10_10_rev 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glVertexP2ui (GLenum type, GLuint value);
+GLAPI void APIENTRY glVertexP2uiv (GLenum type, const GLuint *value);
+GLAPI void APIENTRY glVertexP3ui (GLenum type, GLuint value);
+GLAPI void APIENTRY glVertexP3uiv (GLenum type, const GLuint *value);
+GLAPI void APIENTRY glVertexP4ui (GLenum type, GLuint value);
+GLAPI void APIENTRY glVertexP4uiv (GLenum type, const GLuint *value);
+GLAPI void APIENTRY glTexCoordP1ui (GLenum type, GLuint coords);
+GLAPI void APIENTRY glTexCoordP1uiv (GLenum type, const GLuint *coords);
+GLAPI void APIENTRY glTexCoordP2ui (GLenum type, GLuint coords);
+GLAPI void APIENTRY glTexCoordP2uiv (GLenum type, const GLuint *coords);
+GLAPI void APIENTRY glTexCoordP3ui (GLenum type, GLuint coords);
+GLAPI void APIENTRY glTexCoordP3uiv (GLenum type, const GLuint *coords);
+GLAPI void APIENTRY glTexCoordP4ui (GLenum type, GLuint coords);
+GLAPI void APIENTRY glTexCoordP4uiv (GLenum type, const GLuint *coords);
+GLAPI void APIENTRY glMultiTexCoordP1ui (GLenum texture, GLenum type, GLuint coords);
+GLAPI void APIENTRY glMultiTexCoordP1uiv (GLenum texture, GLenum type, const GLuint *coords);
+GLAPI void APIENTRY glMultiTexCoordP2ui (GLenum texture, GLenum type, GLuint coords);
+GLAPI void APIENTRY glMultiTexCoordP2uiv (GLenum texture, GLenum type, const GLuint *coords);
+GLAPI void APIENTRY glMultiTexCoordP3ui (GLenum texture, GLenum type, GLuint coords);
+GLAPI void APIENTRY glMultiTexCoordP3uiv (GLenum texture, GLenum type, const GLuint *coords);
+GLAPI void APIENTRY glMultiTexCoordP4ui (GLenum texture, GLenum type, GLuint coords);
+GLAPI void APIENTRY glMultiTexCoordP4uiv (GLenum texture, GLenum type, const GLuint *coords);
+GLAPI void APIENTRY glNormalP3ui (GLenum type, GLuint coords);
+GLAPI void APIENTRY glNormalP3uiv (GLenum type, const GLuint *coords);
+GLAPI void APIENTRY glColorP3ui (GLenum type, GLuint color);
+GLAPI void APIENTRY glColorP3uiv (GLenum type, const GLuint *color);
+GLAPI void APIENTRY glColorP4ui (GLenum type, GLuint color);
+GLAPI void APIENTRY glColorP4uiv (GLenum type, const GLuint *color);
+GLAPI void APIENTRY glSecondaryColorP3ui (GLenum type, GLuint color);
+GLAPI void APIENTRY glSecondaryColorP3uiv (GLenum type, const GLuint *color);
+GLAPI void APIENTRY glVertexAttribP1ui (GLuint index, GLenum type, GLboolean normalized, GLuint value);
+GLAPI void APIENTRY glVertexAttribP1uiv (GLuint index, GLenum type, GLboolean normalized, const GLuint *value);
+GLAPI void APIENTRY glVertexAttribP2ui (GLuint index, GLenum type, GLboolean normalized, GLuint value);
+GLAPI void APIENTRY glVertexAttribP2uiv (GLuint index, GLenum type, GLboolean normalized, const GLuint *value);
+GLAPI void APIENTRY glVertexAttribP3ui (GLuint index, GLenum type, GLboolean normalized, GLuint value);
+GLAPI void APIENTRY glVertexAttribP3uiv (GLuint index, GLenum type, GLboolean normalized, const GLuint *value);
+GLAPI void APIENTRY glVertexAttribP4ui (GLuint index, GLenum type, GLboolean normalized, GLuint value);
+GLAPI void APIENTRY glVertexAttribP4uiv (GLuint index, GLenum type, GLboolean normalized, const GLuint *value);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLVERTEXP2UIPROC) (GLenum type, GLuint value);
+typedef void (APIENTRYP PFNGLVERTEXP2UIVPROC) (GLenum type, const GLuint *value);
+typedef void (APIENTRYP PFNGLVERTEXP3UIPROC) (GLenum type, GLuint value);
+typedef void (APIENTRYP PFNGLVERTEXP3UIVPROC) (GLenum type, const GLuint *value);
+typedef void (APIENTRYP PFNGLVERTEXP4UIPROC) (GLenum type, GLuint value);
+typedef void (APIENTRYP PFNGLVERTEXP4UIVPROC) (GLenum type, const GLuint *value);
+typedef void (APIENTRYP PFNGLTEXCOORDP1UIPROC) (GLenum type, GLuint coords);
+typedef void (APIENTRYP PFNGLTEXCOORDP1UIVPROC) (GLenum type, const GLuint *coords);
+typedef void (APIENTRYP PFNGLTEXCOORDP2UIPROC) (GLenum type, GLuint coords);
+typedef void (APIENTRYP PFNGLTEXCOORDP2UIVPROC) (GLenum type, const GLuint *coords);
+typedef void (APIENTRYP PFNGLTEXCOORDP3UIPROC) (GLenum type, GLuint coords);
+typedef void (APIENTRYP PFNGLTEXCOORDP3UIVPROC) (GLenum type, const GLuint *coords);
+typedef void (APIENTRYP PFNGLTEXCOORDP4UIPROC) (GLenum type, GLuint coords);
+typedef void (APIENTRYP PFNGLTEXCOORDP4UIVPROC) (GLenum type, const GLuint *coords);
+typedef void (APIENTRYP PFNGLMULTITEXCOORDP1UIPROC) (GLenum texture, GLenum type, GLuint coords);
+typedef void (APIENTRYP PFNGLMULTITEXCOORDP1UIVPROC) (GLenum texture, GLenum type, const GLuint *coords);
+typedef void (APIENTRYP PFNGLMULTITEXCOORDP2UIPROC) (GLenum texture, GLenum type, GLuint coords);
+typedef void (APIENTRYP PFNGLMULTITEXCOORDP2UIVPROC) (GLenum texture, GLenum type, const GLuint *coords);
+typedef void (APIENTRYP PFNGLMULTITEXCOORDP3UIPROC) (GLenum texture, GLenum type, GLuint coords);
+typedef void (APIENTRYP PFNGLMULTITEXCOORDP3UIVPROC) (GLenum texture, GLenum type, const GLuint *coords);
+typedef void (APIENTRYP PFNGLMULTITEXCOORDP4UIPROC) (GLenum texture, GLenum type, GLuint coords);
+typedef void (APIENTRYP PFNGLMULTITEXCOORDP4UIVPROC) (GLenum texture, GLenum type, const GLuint *coords);
+typedef void (APIENTRYP PFNGLNORMALP3UIPROC) (GLenum type, GLuint coords);
+typedef void (APIENTRYP PFNGLNORMALP3UIVPROC) (GLenum type, const GLuint *coords);
+typedef void (APIENTRYP PFNGLCOLORP3UIPROC) (GLenum type, GLuint color);
+typedef void (APIENTRYP PFNGLCOLORP3UIVPROC) (GLenum type, const GLuint *color);
+typedef void (APIENTRYP PFNGLCOLORP4UIPROC) (GLenum type, GLuint color);
+typedef void (APIENTRYP PFNGLCOLORP4UIVPROC) (GLenum type, const GLuint *color);
+typedef void (APIENTRYP PFNGLSECONDARYCOLORP3UIPROC) (GLenum type, GLuint color);
+typedef void (APIENTRYP PFNGLSECONDARYCOLORP3UIVPROC) (GLenum type, const GLuint *color);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBP1UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBP1UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint *value);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBP2UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBP2UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint *value);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBP3UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBP3UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint *value);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBP4UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBP4UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint *value);
+#endif
+
+#ifndef GL_ARB_draw_indirect
+#define GL_ARB_draw_indirect 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDrawArraysIndirect (GLenum mode, const GLvoid *indirect);
+GLAPI void APIENTRY glDrawElementsIndirect (GLenum mode, GLenum type, const GLvoid *indirect);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLDRAWARRAYSINDIRECTPROC) (GLenum mode, const GLvoid *indirect);
+typedef void (APIENTRYP PFNGLDRAWELEMENTSINDIRECTPROC) (GLenum mode, GLenum type, const GLvoid *indirect);
+#endif
+
+#ifndef GL_ARB_gpu_shader5
+#define GL_ARB_gpu_shader5 1
+#endif
+
+#ifndef GL_ARB_gpu_shader_fp64
+#define GL_ARB_gpu_shader_fp64 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glUniform1d (GLint location, GLdouble x);
+GLAPI void APIENTRY glUniform2d (GLint location, GLdouble x, GLdouble y);
+GLAPI void APIENTRY glUniform3d (GLint location, GLdouble x, GLdouble y, GLdouble z);
+GLAPI void APIENTRY glUniform4d (GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+GLAPI void APIENTRY glUniform1dv (GLint location, GLsizei count, const GLdouble *value);
+GLAPI void APIENTRY glUniform2dv (GLint location, GLsizei count, const GLdouble *value);
+GLAPI void APIENTRY glUniform3dv (GLint location, GLsizei count, const GLdouble *value);
+GLAPI void APIENTRY glUniform4dv (GLint location, GLsizei count, const GLdouble *value);
+GLAPI void APIENTRY glUniformMatrix2dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glUniformMatrix3dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glUniformMatrix4dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glUniformMatrix2x3dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glUniformMatrix2x4dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glUniformMatrix3x2dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glUniformMatrix3x4dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glUniformMatrix4x2dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glUniformMatrix4x3dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glGetUniformdv (GLuint program, GLint location, GLdouble *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLUNIFORM1DPROC) (GLint location, GLdouble x);
+typedef void (APIENTRYP PFNGLUNIFORM2DPROC) (GLint location, GLdouble x, GLdouble y);
+typedef void (APIENTRYP PFNGLUNIFORM3DPROC) (GLint location, GLdouble x, GLdouble y, GLdouble z);
+typedef void (APIENTRYP PFNGLUNIFORM4DPROC) (GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (APIENTRYP PFNGLUNIFORM1DVPROC) (GLint location, GLsizei count, const GLdouble *value);
+typedef void (APIENTRYP PFNGLUNIFORM2DVPROC) (GLint location, GLsizei count, const GLdouble *value);
+typedef void (APIENTRYP PFNGLUNIFORM3DVPROC) (GLint location, GLsizei count, const GLdouble *value);
+typedef void (APIENTRYP PFNGLUNIFORM4DVPROC) (GLint location, GLsizei count, const GLdouble *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX2DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX3DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX4DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X3DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X4DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X2DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X4DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X2DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X3DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLGETUNIFORMDVPROC) (GLuint program, GLint location, GLdouble *params);
+#endif
+
+#ifndef GL_ARB_shader_subroutine
+#define GL_ARB_shader_subroutine 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI GLint APIENTRY glGetSubroutineUniformLocation (GLuint program, GLenum shadertype, const GLchar *name);
+GLAPI GLuint APIENTRY glGetSubroutineIndex (GLuint program, GLenum shadertype, const GLchar *name);
+GLAPI void APIENTRY glGetActiveSubroutineUniformiv (GLuint program, GLenum shadertype, GLuint index, GLenum pname, GLint *values);
+GLAPI void APIENTRY glGetActiveSubroutineUniformName (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei *length, GLchar *name);
+GLAPI void APIENTRY glGetActiveSubroutineName (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei *length, GLchar *name);
+GLAPI void APIENTRY glUniformSubroutinesuiv (GLenum shadertype, GLsizei count, const GLuint *indices);
+GLAPI void APIENTRY glGetUniformSubroutineuiv (GLenum shadertype, GLint location, GLuint *params);
+GLAPI void APIENTRY glGetProgramStageiv (GLuint program, GLenum shadertype, GLenum pname, GLint *values);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef GLint (APIENTRYP PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC) (GLuint program, GLenum shadertype, const GLchar *name);
+typedef GLuint (APIENTRYP PFNGLGETSUBROUTINEINDEXPROC) (GLuint program, GLenum shadertype, const GLchar *name);
+typedef void (APIENTRYP PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC) (GLuint program, GLenum shadertype, GLuint index, GLenum pname, GLint *values);
+typedef void (APIENTRYP PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC) (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei *length, GLchar *name);
+typedef void (APIENTRYP PFNGLGETACTIVESUBROUTINENAMEPROC) (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei *length, GLchar *name);
+typedef void (APIENTRYP PFNGLUNIFORMSUBROUTINESUIVPROC) (GLenum shadertype, GLsizei count, const GLuint *indices);
+typedef void (APIENTRYP PFNGLGETUNIFORMSUBROUTINEUIVPROC) (GLenum shadertype, GLint location, GLuint *params);
+typedef void (APIENTRYP PFNGLGETPROGRAMSTAGEIVPROC) (GLuint program, GLenum shadertype, GLenum pname, GLint *values);
+#endif
+
+#ifndef GL_ARB_tessellation_shader
+#define GL_ARB_tessellation_shader 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glPatchParameteri (GLenum pname, GLint value);
+GLAPI void APIENTRY glPatchParameterfv (GLenum pname, const GLfloat *values);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPATCHPARAMETERIPROC) (GLenum pname, GLint value);
+typedef void (APIENTRYP PFNGLPATCHPARAMETERFVPROC) (GLenum pname, const GLfloat *values);
+#endif
+
+#ifndef GL_ARB_texture_buffer_object_rgb32
+#define GL_ARB_texture_buffer_object_rgb32 1
+#endif
+
+#ifndef GL_ARB_transform_feedback2
+#define GL_ARB_transform_feedback2 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBindTransformFeedback (GLenum target, GLuint id);
+GLAPI void APIENTRY glDeleteTransformFeedbacks (GLsizei n, const GLuint *ids);
+GLAPI void APIENTRY glGenTransformFeedbacks (GLsizei n, GLuint *ids);
+GLAPI GLboolean APIENTRY glIsTransformFeedback (GLuint id);
+GLAPI void APIENTRY glPauseTransformFeedback (void);
+GLAPI void APIENTRY glResumeTransformFeedback (void);
+GLAPI void APIENTRY glDrawTransformFeedback (GLenum mode, GLuint id);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBINDTRANSFORMFEEDBACKPROC) (GLenum target, GLuint id);
+typedef void (APIENTRYP PFNGLDELETETRANSFORMFEEDBACKSPROC) (GLsizei n, const GLuint *ids);
+typedef void (APIENTRYP PFNGLGENTRANSFORMFEEDBACKSPROC) (GLsizei n, GLuint *ids);
+typedef GLboolean (APIENTRYP PFNGLISTRANSFORMFEEDBACKPROC) (GLuint id);
+typedef void (APIENTRYP PFNGLPAUSETRANSFORMFEEDBACKPROC) (void);
+typedef void (APIENTRYP PFNGLRESUMETRANSFORMFEEDBACKPROC) (void);
+typedef void (APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKPROC) (GLenum mode, GLuint id);
+#endif
+
+#ifndef GL_ARB_transform_feedback3
+#define GL_ARB_transform_feedback3 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDrawTransformFeedbackStream (GLenum mode, GLuint id, GLuint stream);
+GLAPI void APIENTRY glBeginQueryIndexed (GLenum target, GLuint index, GLuint id);
+GLAPI void APIENTRY glEndQueryIndexed (GLenum target, GLuint index);
+GLAPI void APIENTRY glGetQueryIndexediv (GLenum target, GLuint index, GLenum pname, GLint *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC) (GLenum mode, GLuint id, GLuint stream);
+typedef void (APIENTRYP PFNGLBEGINQUERYINDEXEDPROC) (GLenum target, GLuint index, GLuint id);
+typedef void (APIENTRYP PFNGLENDQUERYINDEXEDPROC) (GLenum target, GLuint index);
+typedef void (APIENTRYP PFNGLGETQUERYINDEXEDIVPROC) (GLenum target, GLuint index, GLenum pname, GLint *params);
+#endif
+
+#ifndef GL_ARB_ES2_compatibility
+#define GL_ARB_ES2_compatibility 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glReleaseShaderCompiler (void);
+GLAPI void APIENTRY glShaderBinary (GLsizei count, const GLuint *shaders, GLenum binaryformat, const GLvoid *binary, GLsizei length);
+GLAPI void APIENTRY glGetShaderPrecisionFormat (GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision);
+GLAPI void APIENTRY glDepthRangef (GLclampf n, GLclampf f);
+GLAPI void APIENTRY glClearDepthf (GLclampf d);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLRELEASESHADERCOMPILERPROC) (void);
+typedef void (APIENTRYP PFNGLSHADERBINARYPROC) (GLsizei count, const GLuint *shaders, GLenum binaryformat, const GLvoid *binary, GLsizei length);
+typedef void (APIENTRYP PFNGLGETSHADERPRECISIONFORMATPROC) (GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision);
+typedef void (APIENTRYP PFNGLDEPTHRANGEFPROC) (GLclampf n, GLclampf f);
+typedef void (APIENTRYP PFNGLCLEARDEPTHFPROC) (GLclampf d);
+#endif
+
+#ifndef GL_ARB_get_program_binary
+#define GL_ARB_get_program_binary 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGetProgramBinary (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, GLvoid *binary);
+GLAPI void APIENTRY glProgramBinary (GLuint program, GLenum binaryFormat, const GLvoid *binary, GLsizei length);
+GLAPI void APIENTRY glProgramParameteri (GLuint program, GLenum pname, GLint value);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLGETPROGRAMBINARYPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, GLvoid *binary);
+typedef void (APIENTRYP PFNGLPROGRAMBINARYPROC) (GLuint program, GLenum binaryFormat, const GLvoid *binary, GLsizei length);
+typedef void (APIENTRYP PFNGLPROGRAMPARAMETERIPROC) (GLuint program, GLenum pname, GLint value);
+#endif
+
+#ifndef GL_ARB_separate_shader_objects
+#define GL_ARB_separate_shader_objects 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glUseProgramStages (GLuint pipeline, GLbitfield stages, GLuint program);
+GLAPI void APIENTRY glActiveShaderProgram (GLuint pipeline, GLuint program);
+GLAPI GLuint APIENTRY glCreateShaderProgramv (GLenum type, GLsizei count, const GLchar* *strings);
+GLAPI void APIENTRY glBindProgramPipeline (GLuint pipeline);
+GLAPI void APIENTRY glDeleteProgramPipelines (GLsizei n, const GLuint *pipelines);
+GLAPI void APIENTRY glGenProgramPipelines (GLsizei n, GLuint *pipelines);
+GLAPI GLboolean APIENTRY glIsProgramPipeline (GLuint pipeline);
+GLAPI void APIENTRY glGetProgramPipelineiv (GLuint pipeline, GLenum pname, GLint *params);
+GLAPI void APIENTRY glProgramUniform1i (GLuint program, GLint location, GLint v0);
+GLAPI void APIENTRY glProgramUniform1iv (GLuint program, GLint location, GLsizei count, const GLint *value);
+GLAPI void APIENTRY glProgramUniform1f (GLuint program, GLint location, GLfloat v0);
+GLAPI void APIENTRY glProgramUniform1fv (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniform1d (GLuint program, GLint location, GLdouble v0);
+GLAPI void APIENTRY glProgramUniform1dv (GLuint program, GLint location, GLsizei count, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniform1ui (GLuint program, GLint location, GLuint v0);
+GLAPI void APIENTRY glProgramUniform1uiv (GLuint program, GLint location, GLsizei count, const GLuint *value);
+GLAPI void APIENTRY glProgramUniform2i (GLuint program, GLint location, GLint v0, GLint v1);
+GLAPI void APIENTRY glProgramUniform2iv (GLuint program, GLint location, GLsizei count, const GLint *value);
+GLAPI void APIENTRY glProgramUniform2f (GLuint program, GLint location, GLfloat v0, GLfloat v1);
+GLAPI void APIENTRY glProgramUniform2fv (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniform2d (GLuint program, GLint location, GLdouble v0, GLdouble v1);
+GLAPI void APIENTRY glProgramUniform2dv (GLuint program, GLint location, GLsizei count, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniform2ui (GLuint program, GLint location, GLuint v0, GLuint v1);
+GLAPI void APIENTRY glProgramUniform2uiv (GLuint program, GLint location, GLsizei count, const GLuint *value);
+GLAPI void APIENTRY glProgramUniform3i (GLuint program, GLint location, GLint v0, GLint v1, GLint v2);
+GLAPI void APIENTRY glProgramUniform3iv (GLuint program, GLint location, GLsizei count, const GLint *value);
+GLAPI void APIENTRY glProgramUniform3f (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
+GLAPI void APIENTRY glProgramUniform3fv (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniform3d (GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2);
+GLAPI void APIENTRY glProgramUniform3dv (GLuint program, GLint location, GLsizei count, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniform3ui (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2);
+GLAPI void APIENTRY glProgramUniform3uiv (GLuint program, GLint location, GLsizei count, const GLuint *value);
+GLAPI void APIENTRY glProgramUniform4i (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
+GLAPI void APIENTRY glProgramUniform4iv (GLuint program, GLint location, GLsizei count, const GLint *value);
+GLAPI void APIENTRY glProgramUniform4f (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
+GLAPI void APIENTRY glProgramUniform4fv (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniform4d (GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2, GLdouble v3);
+GLAPI void APIENTRY glProgramUniform4dv (GLuint program, GLint location, GLsizei count, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniform4ui (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+GLAPI void APIENTRY glProgramUniform4uiv (GLuint program, GLint location, GLsizei count, const GLuint *value);
+GLAPI void APIENTRY glProgramUniformMatrix2fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniformMatrix3fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniformMatrix4fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniformMatrix2dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniformMatrix3dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniformMatrix4dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniformMatrix2x3fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniformMatrix3x2fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniformMatrix2x4fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniformMatrix4x2fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniformMatrix3x4fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniformMatrix4x3fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniformMatrix2x3dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniformMatrix3x2dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniformMatrix2x4dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniformMatrix4x2dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniformMatrix3x4dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniformMatrix4x3dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glValidateProgramPipeline (GLuint pipeline);
+GLAPI void APIENTRY glGetProgramPipelineInfoLog (GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLUSEPROGRAMSTAGESPROC) (GLuint pipeline, GLbitfield stages, GLuint program);
+typedef void (APIENTRYP PFNGLACTIVESHADERPROGRAMPROC) (GLuint pipeline, GLuint program);
+typedef GLuint (APIENTRYP PFNGLCREATESHADERPROGRAMVPROC) (GLenum type, GLsizei count, const GLchar* *strings);
+typedef void (APIENTRYP PFNGLBINDPROGRAMPIPELINEPROC) (GLuint pipeline);
+typedef void (APIENTRYP PFNGLDELETEPROGRAMPIPELINESPROC) (GLsizei n, const GLuint *pipelines);
+typedef void (APIENTRYP PFNGLGENPROGRAMPIPELINESPROC) (GLsizei n, GLuint *pipelines);
+typedef GLboolean (APIENTRYP PFNGLISPROGRAMPIPELINEPROC) (GLuint pipeline);
+typedef void (APIENTRYP PFNGLGETPROGRAMPIPELINEIVPROC) (GLuint pipeline, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1IPROC) (GLuint program, GLint location, GLint v0);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1IVPROC) (GLuint program, GLint location, GLsizei count, const GLint *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1FPROC) (GLuint program, GLint location, GLfloat v0);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1DPROC) (GLuint program, GLint location, GLdouble v0);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UIPROC) (GLuint program, GLint location, GLuint v0);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2IPROC) (GLuint program, GLint location, GLint v0, GLint v1);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2IVPROC) (GLuint program, GLint location, GLsizei count, const GLint *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2FPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2DPROC) (GLuint program, GLint location, GLdouble v0, GLdouble v1);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UIPROC) (GLuint program, GLint location, GLuint v0, GLuint v1);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3IPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3IVPROC) (GLuint program, GLint location, GLsizei count, const GLint *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3FPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3DPROC) (GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UIPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4IPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4IVPROC) (GLuint program, GLint location, GLsizei count, const GLint *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4FPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4DPROC) (GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2, GLdouble v3);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UIPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLVALIDATEPROGRAMPIPELINEPROC) (GLuint pipeline);
+typedef void (APIENTRYP PFNGLGETPROGRAMPIPELINEINFOLOGPROC) (GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
+#endif
+
+#ifndef GL_ARB_vertex_attrib_64bit
+#define GL_ARB_vertex_attrib_64bit 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glVertexAttribL1d (GLuint index, GLdouble x);
+GLAPI void APIENTRY glVertexAttribL2d (GLuint index, GLdouble x, GLdouble y);
+GLAPI void APIENTRY glVertexAttribL3d (GLuint index, GLdouble x, GLdouble y, GLdouble z);
+GLAPI void APIENTRY glVertexAttribL4d (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+GLAPI void APIENTRY glVertexAttribL1dv (GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttribL2dv (GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttribL3dv (GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttribL4dv (GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttribLPointer (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+GLAPI void APIENTRY glGetVertexAttribLdv (GLuint index, GLenum pname, GLdouble *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL1DPROC) (GLuint index, GLdouble x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL2DPROC) (GLuint index, GLdouble x, GLdouble y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL3DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL4DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL1DVPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL2DVPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL3DVPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL4DVPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBLPOINTERPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBLDVPROC) (GLuint index, GLenum pname, GLdouble *params);
+#endif
+
+#ifndef GL_ARB_viewport_array
+#define GL_ARB_viewport_array 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glViewportArrayv (GLuint first, GLsizei count, const GLfloat *v);
+GLAPI void APIENTRY glViewportIndexedf (GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h);
+GLAPI void APIENTRY glViewportIndexedfv (GLuint index, const GLfloat *v);
+GLAPI void APIENTRY glScissorArrayv (GLuint first, GLsizei count, const GLint *v);
+GLAPI void APIENTRY glScissorIndexed (GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height);
+GLAPI void APIENTRY glScissorIndexedv (GLuint index, const GLint *v);
+GLAPI void APIENTRY glDepthRangeArrayv (GLuint first, GLsizei count, const GLclampd *v);
+GLAPI void APIENTRY glDepthRangeIndexed (GLuint index, GLclampd n, GLclampd f);
+GLAPI void APIENTRY glGetFloati_v (GLenum target, GLuint index, GLfloat *data);
+GLAPI void APIENTRY glGetDoublei_v (GLenum target, GLuint index, GLdouble *data);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLVIEWPORTARRAYVPROC) (GLuint first, GLsizei count, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVIEWPORTINDEXEDFPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h);
+typedef void (APIENTRYP PFNGLVIEWPORTINDEXEDFVPROC) (GLuint index, const GLfloat *v);
+typedef void (APIENTRYP PFNGLSCISSORARRAYVPROC) (GLuint first, GLsizei count, const GLint *v);
+typedef void (APIENTRYP PFNGLSCISSORINDEXEDPROC) (GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height);
+typedef void (APIENTRYP PFNGLSCISSORINDEXEDVPROC) (GLuint index, const GLint *v);
+typedef void (APIENTRYP PFNGLDEPTHRANGEARRAYVPROC) (GLuint first, GLsizei count, const GLclampd *v);
+typedef void (APIENTRYP PFNGLDEPTHRANGEINDEXEDPROC) (GLuint index, GLclampd n, GLclampd f);
+typedef void (APIENTRYP PFNGLGETFLOATI_VPROC) (GLenum target, GLuint index, GLfloat *data);
+typedef void (APIENTRYP PFNGLGETDOUBLEI_VPROC) (GLenum target, GLuint index, GLdouble *data);
+#endif
+
+#ifndef GL_ARB_cl_event
+#define GL_ARB_cl_event 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI GLsync APIENTRY glCreateSyncFromCLeventARB (struct _cl_context * context, struct _cl_event * event, GLbitfield flags);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef GLsync (APIENTRYP PFNGLCREATESYNCFROMCLEVENTARBPROC) (struct _cl_context * context, struct _cl_event * event, GLbitfield flags);
+#endif
+
+#ifndef GL_ARB_debug_output
+#define GL_ARB_debug_output 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDebugMessageControlARB (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled);
+GLAPI void APIENTRY glDebugMessageInsertARB (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf);
+GLAPI void APIENTRY glDebugMessageCallbackARB (GLDEBUGPROCARB callback, const GLvoid *userParam);
+GLAPI GLuint APIENTRY glGetDebugMessageLogARB (GLuint count, GLsizei bufsize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLDEBUGMESSAGECONTROLARBPROC) (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled);
+typedef void (APIENTRYP PFNGLDEBUGMESSAGEINSERTARBPROC) (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf);
+typedef void (APIENTRYP PFNGLDEBUGMESSAGECALLBACKARBPROC) (GLDEBUGPROCARB callback, const GLvoid *userParam);
+typedef GLuint (APIENTRYP PFNGLGETDEBUGMESSAGELOGARBPROC) (GLuint count, GLsizei bufsize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog);
+#endif
+
+#ifndef GL_ARB_robustness
+#define GL_ARB_robustness 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI GLenum APIENTRY glGetGraphicsResetStatusARB (void);
+GLAPI void APIENTRY glGetnMapdvARB (GLenum target, GLenum query, GLsizei bufSize, GLdouble *v);
+GLAPI void APIENTRY glGetnMapfvARB (GLenum target, GLenum query, GLsizei bufSize, GLfloat *v);
+GLAPI void APIENTRY glGetnMapivARB (GLenum target, GLenum query, GLsizei bufSize, GLint *v);
+GLAPI void APIENTRY glGetnPixelMapfvARB (GLenum map, GLsizei bufSize, GLfloat *values);
+GLAPI void APIENTRY glGetnPixelMapuivARB (GLenum map, GLsizei bufSize, GLuint *values);
+GLAPI void APIENTRY glGetnPixelMapusvARB (GLenum map, GLsizei bufSize, GLushort *values);
+GLAPI void APIENTRY glGetnPolygonStippleARB (GLsizei bufSize, GLubyte *pattern);
+GLAPI void APIENTRY glGetnColorTableARB (GLenum target, GLenum format, GLenum type, GLsizei bufSize, GLvoid *table);
+GLAPI void APIENTRY glGetnConvolutionFilterARB (GLenum target, GLenum format, GLenum type, GLsizei bufSize, GLvoid *image);
+GLAPI void APIENTRY glGetnSeparableFilterARB (GLenum target, GLenum format, GLenum type, GLsizei rowBufSize, GLvoid *row, GLsizei columnBufSize, GLvoid *column, GLvoid *span);
+GLAPI void APIENTRY glGetnHistogramARB (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, GLvoid *values);
+GLAPI void APIENTRY glGetnMinmaxARB (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, GLvoid *values);
+GLAPI void APIENTRY glGetnTexImageARB (GLenum target, GLint level, GLenum format, GLenum type, GLsizei bufSize, GLvoid *img);
+GLAPI void APIENTRY glReadnPixelsARB (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, GLvoid *data);
+GLAPI void APIENTRY glGetnCompressedTexImageARB (GLenum target, GLint lod, GLsizei bufSize, GLvoid *img);
+GLAPI void APIENTRY glGetnUniformfvARB (GLuint program, GLint location, GLsizei bufSize, GLfloat *params);
+GLAPI void APIENTRY glGetnUniformivARB (GLuint program, GLint location, GLsizei bufSize, GLint *params);
+GLAPI void APIENTRY glGetnUniformuivARB (GLuint program, GLint location, GLsizei bufSize, GLuint *params);
+GLAPI void APIENTRY glGetnUniformdvARB (GLuint program, GLint location, GLsizei bufSize, GLdouble *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef GLenum (APIENTRYP PFNGLGETGRAPHICSRESETSTATUSARBPROC) (void);
+typedef void (APIENTRYP PFNGLGETNMAPDVARBPROC) (GLenum target, GLenum query, GLsizei bufSize, GLdouble *v);
+typedef void (APIENTRYP PFNGLGETNMAPFVARBPROC) (GLenum target, GLenum query, GLsizei bufSize, GLfloat *v);
+typedef void (APIENTRYP PFNGLGETNMAPIVARBPROC) (GLenum target, GLenum query, GLsizei bufSize, GLint *v);
+typedef void (APIENTRYP PFNGLGETNPIXELMAPFVARBPROC) (GLenum map, GLsizei bufSize, GLfloat *values);
+typedef void (APIENTRYP PFNGLGETNPIXELMAPUIVARBPROC) (GLenum map, GLsizei bufSize, GLuint *values);
+typedef void (APIENTRYP PFNGLGETNPIXELMAPUSVARBPROC) (GLenum map, GLsizei bufSize, GLushort *values);
+typedef void (APIENTRYP PFNGLGETNPOLYGONSTIPPLEARBPROC) (GLsizei bufSize, GLubyte *pattern);
+typedef void (APIENTRYP PFNGLGETNCOLORTABLEARBPROC) (GLenum target, GLenum format, GLenum type, GLsizei bufSize, GLvoid *table);
+typedef void (APIENTRYP PFNGLGETNCONVOLUTIONFILTERARBPROC) (GLenum target, GLenum format, GLenum type, GLsizei bufSize, GLvoid *image);
+typedef void (APIENTRYP PFNGLGETNSEPARABLEFILTERARBPROC) (GLenum target, GLenum format, GLenum type, GLsizei rowBufSize, GLvoid *row, GLsizei columnBufSize, GLvoid *column, GLvoid *span);
+typedef void (APIENTRYP PFNGLGETNHISTOGRAMARBPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, GLvoid *values);
+typedef void (APIENTRYP PFNGLGETNMINMAXARBPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, GLvoid *values);
+typedef void (APIENTRYP PFNGLGETNTEXIMAGEARBPROC) (GLenum target, GLint level, GLenum format, GLenum type, GLsizei bufSize, GLvoid *img);
+typedef void (APIENTRYP PFNGLREADNPIXELSARBPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, GLvoid *data);
+typedef void (APIENTRYP PFNGLGETNCOMPRESSEDTEXIMAGEARBPROC) (GLenum target, GLint lod, GLsizei bufSize, GLvoid *img);
+typedef void (APIENTRYP PFNGLGETNUNIFORMFVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETNUNIFORMIVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLint *params);
+typedef void (APIENTRYP PFNGLGETNUNIFORMUIVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLuint *params);
+typedef void (APIENTRYP PFNGLGETNUNIFORMDVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLdouble *params);
+#endif
+
+#ifndef GL_ARB_shader_stencil_export
+#define GL_ARB_shader_stencil_export 1
+#endif
+
+#ifndef GL_ARB_base_instance
+#define GL_ARB_base_instance 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDrawArraysInstancedBaseInstance (GLenum mode, GLint first, GLsizei count, GLsizei primcount, GLuint baseinstance);
+GLAPI void APIENTRY glDrawElementsInstancedBaseInstance (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount, GLuint baseinstance);
+GLAPI void APIENTRY glDrawElementsInstancedBaseVertexBaseInstance (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount, GLint basevertex, GLuint baseinstance);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount, GLuint baseinstance);
+typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount, GLuint baseinstance);
+typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount, GLint basevertex, GLuint baseinstance);
+#endif
+
+#ifndef GL_ARB_shading_language_420pack
+#define GL_ARB_shading_language_420pack 1
+#endif
+
+#ifndef GL_ARB_transform_feedback_instanced
+#define GL_ARB_transform_feedback_instanced 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDrawTransformFeedbackInstanced (GLenum mode, GLuint id, GLsizei primcount);
+GLAPI void APIENTRY glDrawTransformFeedbackStreamInstanced (GLenum mode, GLuint id, GLuint stream, GLsizei primcount);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC) (GLenum mode, GLuint id, GLsizei primcount);
+typedef void (APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC) (GLenum mode, GLuint id, GLuint stream, GLsizei primcount);
+#endif
+
+#ifndef GL_ARB_compressed_texture_pixel_storage
+#define GL_ARB_compressed_texture_pixel_storage 1
+#endif
+
+#ifndef GL_ARB_conservative_depth
+#define GL_ARB_conservative_depth 1
+#endif
+
+#ifndef GL_ARB_internalformat_query
+#define GL_ARB_internalformat_query 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGetInternalformativ (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLGETINTERNALFORMATIVPROC) (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params);
+#endif
+
+#ifndef GL_ARB_map_buffer_alignment
+#define GL_ARB_map_buffer_alignment 1
+#endif
+
+#ifndef GL_ARB_shader_atomic_counters
+#define GL_ARB_shader_atomic_counters 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGetActiveAtomicCounterBufferiv (GLuint program, GLuint bufferIndex, GLenum pname, GLint *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC) (GLuint program, GLuint bufferIndex, GLenum pname, GLint *params);
+#endif
+
+#ifndef GL_ARB_shader_image_load_store
+#define GL_ARB_shader_image_load_store 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBindImageTexture (GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format);
+GLAPI void APIENTRY glMemoryBarrier (GLbitfield barriers);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBINDIMAGETEXTUREPROC) (GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format);
+typedef void (APIENTRYP PFNGLMEMORYBARRIERPROC) (GLbitfield barriers);
+#endif
+
+#ifndef GL_ARB_shading_language_packing
+#define GL_ARB_shading_language_packing 1
+#endif
+
+#ifndef GL_ARB_texture_storage
+#define GL_ARB_texture_storage 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTexStorage1D (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width);
+GLAPI void APIENTRY glTexStorage2D (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
+GLAPI void APIENTRY glTexStorage3D (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+GLAPI void APIENTRY glTextureStorage1DEXT (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width);
+GLAPI void APIENTRY glTextureStorage2DEXT (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
+GLAPI void APIENTRY glTextureStorage3DEXT (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLTEXSTORAGE1DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width);
+typedef void (APIENTRYP PFNGLTEXSTORAGE2DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (APIENTRYP PFNGLTEXSTORAGE3DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+typedef void (APIENTRYP PFNGLTEXTURESTORAGE1DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width);
+typedef void (APIENTRYP PFNGLTEXTURESTORAGE2DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (APIENTRYP PFNGLTEXTURESTORAGE3DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+#endif
+
+#ifndef GL_EXT_abgr
+#define GL_EXT_abgr 1
+#endif
+
+#ifndef GL_EXT_blend_color
+#define GL_EXT_blend_color 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBlendColorEXT (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBLENDCOLOREXTPROC) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+#endif
+
+#ifndef GL_EXT_polygon_offset
+#define GL_EXT_polygon_offset 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glPolygonOffsetEXT (GLfloat factor, GLfloat bias);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPOLYGONOFFSETEXTPROC) (GLfloat factor, GLfloat bias);
+#endif
+
+#ifndef GL_EXT_texture
+#define GL_EXT_texture 1
+#endif
+
+#ifndef GL_EXT_texture3D
+#define GL_EXT_texture3D 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTexImage3DEXT (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+GLAPI void APIENTRY glTexSubImage3DEXT (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLTEXIMAGE3DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (APIENTRYP PFNGLTEXSUBIMAGE3DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels);
+#endif
+
+#ifndef GL_SGIS_texture_filter4
+#define GL_SGIS_texture_filter4 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGetTexFilterFuncSGIS (GLenum target, GLenum filter, GLfloat *weights);
+GLAPI void APIENTRY glTexFilterFuncSGIS (GLenum target, GLenum filter, GLsizei n, const GLfloat *weights);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLGETTEXFILTERFUNCSGISPROC) (GLenum target, GLenum filter, GLfloat *weights);
+typedef void (APIENTRYP PFNGLTEXFILTERFUNCSGISPROC) (GLenum target, GLenum filter, GLsizei n, const GLfloat *weights);
+#endif
+
+#ifndef GL_EXT_subtexture
+#define GL_EXT_subtexture 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTexSubImage1DEXT (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels);
+GLAPI void APIENTRY glTexSubImage2DEXT (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLTEXSUBIMAGE1DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (APIENTRYP PFNGLTEXSUBIMAGE2DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
+#endif
+
+#ifndef GL_EXT_copy_texture
+#define GL_EXT_copy_texture 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glCopyTexImage1DEXT (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border);
+GLAPI void APIENTRY glCopyTexImage2DEXT (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
+GLAPI void APIENTRY glCopyTexSubImage1DEXT (GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width);
+GLAPI void APIENTRY glCopyTexSubImage2DEXT (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+GLAPI void APIENTRY glCopyTexSubImage3DEXT (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLCOPYTEXIMAGE1DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border);
+typedef void (APIENTRYP PFNGLCOPYTEXIMAGE2DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
+typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE1DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width);
+typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE2DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE3DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+#endif
+
+#ifndef GL_EXT_histogram
+#define GL_EXT_histogram 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGetHistogramEXT (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values);
+GLAPI void APIENTRY glGetHistogramParameterfvEXT (GLenum target, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetHistogramParameterivEXT (GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetMinmaxEXT (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values);
+GLAPI void APIENTRY glGetMinmaxParameterfvEXT (GLenum target, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetMinmaxParameterivEXT (GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glHistogramEXT (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink);
+GLAPI void APIENTRY glMinmaxEXT (GLenum target, GLenum internalformat, GLboolean sink);
+GLAPI void APIENTRY glResetHistogramEXT (GLenum target);
+GLAPI void APIENTRY glResetMinmaxEXT (GLenum target);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLGETHISTOGRAMEXTPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values);
+typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETMINMAXEXTPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values);
+typedef void (APIENTRYP PFNGLGETMINMAXPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETMINMAXPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLHISTOGRAMEXTPROC) (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink);
+typedef void (APIENTRYP PFNGLMINMAXEXTPROC) (GLenum target, GLenum internalformat, GLboolean sink);
+typedef void (APIENTRYP PFNGLRESETHISTOGRAMEXTPROC) (GLenum target);
+typedef void (APIENTRYP PFNGLRESETMINMAXEXTPROC) (GLenum target);
+#endif
+
+#ifndef GL_EXT_convolution
+#define GL_EXT_convolution 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glConvolutionFilter1DEXT (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *image);
+GLAPI void APIENTRY glConvolutionFilter2DEXT (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image);
+GLAPI void APIENTRY glConvolutionParameterfEXT (GLenum target, GLenum pname, GLfloat params);
+GLAPI void APIENTRY glConvolutionParameterfvEXT (GLenum target, GLenum pname, const GLfloat *params);
+GLAPI void APIENTRY glConvolutionParameteriEXT (GLenum target, GLenum pname, GLint params);
+GLAPI void APIENTRY glConvolutionParameterivEXT (GLenum target, GLenum pname, const GLint *params);
+GLAPI void APIENTRY glCopyConvolutionFilter1DEXT (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width);
+GLAPI void APIENTRY glCopyConvolutionFilter2DEXT (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height);
+GLAPI void APIENTRY glGetConvolutionFilterEXT (GLenum target, GLenum format, GLenum type, GLvoid *image);
+GLAPI void APIENTRY glGetConvolutionParameterfvEXT (GLenum target, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetConvolutionParameterivEXT (GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetSeparableFilterEXT (GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span);
+GLAPI void APIENTRY glSeparableFilter2DEXT (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLCONVOLUTIONFILTER1DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *image);
+typedef void (APIENTRYP PFNGLCONVOLUTIONFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image);
+typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERFEXTPROC) (GLenum target, GLenum pname, GLfloat params);
+typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERFVEXTPROC) (GLenum target, GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERIEXTPROC) (GLenum target, GLenum pname, GLint params);
+typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERIVEXTPROC) (GLenum target, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLCOPYCONVOLUTIONFILTER1DEXTPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width);
+typedef void (APIENTRYP PFNGLCOPYCONVOLUTIONFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (APIENTRYP PFNGLGETCONVOLUTIONFILTEREXTPROC) (GLenum target, GLenum format, GLenum type, GLvoid *image);
+typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETSEPARABLEFILTEREXTPROC) (GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span);
+typedef void (APIENTRYP PFNGLSEPARABLEFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column);
+#endif
+
+#ifndef GL_SGI_color_matrix
+#define GL_SGI_color_matrix 1
+#endif
+
+#ifndef GL_SGI_color_table
+#define GL_SGI_color_table 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glColorTableSGI (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table);
+GLAPI void APIENTRY glColorTableParameterfvSGI (GLenum target, GLenum pname, const GLfloat *params);
+GLAPI void APIENTRY glColorTableParameterivSGI (GLenum target, GLenum pname, const GLint *params);
+GLAPI void APIENTRY glCopyColorTableSGI (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width);
+GLAPI void APIENTRY glGetColorTableSGI (GLenum target, GLenum format, GLenum type, GLvoid *table);
+GLAPI void APIENTRY glGetColorTableParameterfvSGI (GLenum target, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetColorTableParameterivSGI (GLenum target, GLenum pname, GLint *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLCOLORTABLESGIPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table);
+typedef void (APIENTRYP PFNGLCOLORTABLEPARAMETERFVSGIPROC) (GLenum target, GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLCOLORTABLEPARAMETERIVSGIPROC) (GLenum target, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLCOPYCOLORTABLESGIPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width);
+typedef void (APIENTRYP PFNGLGETCOLORTABLESGIPROC) (GLenum target, GLenum format, GLenum type, GLvoid *table);
+typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERFVSGIPROC) (GLenum target, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERIVSGIPROC) (GLenum target, GLenum pname, GLint *params);
+#endif
+
+#ifndef GL_SGIX_pixel_texture
+#define GL_SGIX_pixel_texture 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glPixelTexGenSGIX (GLenum mode);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPIXELTEXGENSGIXPROC) (GLenum mode);
+#endif
+
+#ifndef GL_SGIS_pixel_texture
+#define GL_SGIS_pixel_texture 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glPixelTexGenParameteriSGIS (GLenum pname, GLint param);
+GLAPI void APIENTRY glPixelTexGenParameterivSGIS (GLenum pname, const GLint *params);
+GLAPI void APIENTRY glPixelTexGenParameterfSGIS (GLenum pname, GLfloat param);
+GLAPI void APIENTRY glPixelTexGenParameterfvSGIS (GLenum pname, const GLfloat *params);
+GLAPI void APIENTRY glGetPixelTexGenParameterivSGIS (GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetPixelTexGenParameterfvSGIS (GLenum pname, GLfloat *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPIXELTEXGENPARAMETERISGISPROC) (GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLPIXELTEXGENPARAMETERIVSGISPROC) (GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLPIXELTEXGENPARAMETERFSGISPROC) (GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLPIXELTEXGENPARAMETERFVSGISPROC) (GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLGETPIXELTEXGENPARAMETERIVSGISPROC) (GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETPIXELTEXGENPARAMETERFVSGISPROC) (GLenum pname, GLfloat *params);
+#endif
+
+#ifndef GL_SGIS_texture4D
+#define GL_SGIS_texture4D 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTexImage4DSGIS (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+GLAPI void APIENTRY glTexSubImage4DSGIS (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint woffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLenum format, GLenum type, const GLvoid *pixels);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLTEXIMAGE4DSGISPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (APIENTRYP PFNGLTEXSUBIMAGE4DSGISPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint woffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLenum format, GLenum type, const GLvoid *pixels);
+#endif
+
+#ifndef GL_SGI_texture_color_table
+#define GL_SGI_texture_color_table 1
+#endif
+
+#ifndef GL_EXT_cmyka
+#define GL_EXT_cmyka 1
+#endif
+
+#ifndef GL_EXT_texture_object
+#define GL_EXT_texture_object 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI GLboolean APIENTRY glAreTexturesResidentEXT (GLsizei n, const GLuint *textures, GLboolean *residences);
+GLAPI void APIENTRY glBindTextureEXT (GLenum target, GLuint texture);
+GLAPI void APIENTRY glDeleteTexturesEXT (GLsizei n, const GLuint *textures);
+GLAPI void APIENTRY glGenTexturesEXT (GLsizei n, GLuint *textures);
+GLAPI GLboolean APIENTRY glIsTextureEXT (GLuint texture);
+GLAPI void APIENTRY glPrioritizeTexturesEXT (GLsizei n, const GLuint *textures, const GLclampf *priorities);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef GLboolean (APIENTRYP PFNGLARETEXTURESRESIDENTEXTPROC) (GLsizei n, const GLuint *textures, GLboolean *residences);
+typedef void (APIENTRYP PFNGLBINDTEXTUREEXTPROC) (GLenum target, GLuint texture);
+typedef void (APIENTRYP PFNGLDELETETEXTURESEXTPROC) (GLsizei n, const GLuint *textures);
+typedef void (APIENTRYP PFNGLGENTEXTURESEXTPROC) (GLsizei n, GLuint *textures);
+typedef GLboolean (APIENTRYP PFNGLISTEXTUREEXTPROC) (GLuint texture);
+typedef void (APIENTRYP PFNGLPRIORITIZETEXTURESEXTPROC) (GLsizei n, const GLuint *textures, const GLclampf *priorities);
+#endif
+
+#ifndef GL_SGIS_detail_texture
+#define GL_SGIS_detail_texture 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDetailTexFuncSGIS (GLenum target, GLsizei n, const GLfloat *points);
+GLAPI void APIENTRY glGetDetailTexFuncSGIS (GLenum target, GLfloat *points);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLDETAILTEXFUNCSGISPROC) (GLenum target, GLsizei n, const GLfloat *points);
+typedef void (APIENTRYP PFNGLGETDETAILTEXFUNCSGISPROC) (GLenum target, GLfloat *points);
+#endif
+
+#ifndef GL_SGIS_sharpen_texture
+#define GL_SGIS_sharpen_texture 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glSharpenTexFuncSGIS (GLenum target, GLsizei n, const GLfloat *points);
+GLAPI void APIENTRY glGetSharpenTexFuncSGIS (GLenum target, GLfloat *points);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLSHARPENTEXFUNCSGISPROC) (GLenum target, GLsizei n, const GLfloat *points);
+typedef void (APIENTRYP PFNGLGETSHARPENTEXFUNCSGISPROC) (GLenum target, GLfloat *points);
+#endif
+
+#ifndef GL_EXT_packed_pixels
+#define GL_EXT_packed_pixels 1
+#endif
+
+#ifndef GL_SGIS_texture_lod
+#define GL_SGIS_texture_lod 1
+#endif
+
+#ifndef GL_SGIS_multisample
+#define GL_SGIS_multisample 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glSampleMaskSGIS (GLclampf value, GLboolean invert);
+GLAPI void APIENTRY glSamplePatternSGIS (GLenum pattern);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLSAMPLEMASKSGISPROC) (GLclampf value, GLboolean invert);
+typedef void (APIENTRYP PFNGLSAMPLEPATTERNSGISPROC) (GLenum pattern);
+#endif
+
+#ifndef GL_EXT_rescale_normal
+#define GL_EXT_rescale_normal 1
+#endif
+
+#ifndef GL_EXT_vertex_array
+#define GL_EXT_vertex_array 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glArrayElementEXT (GLint i);
+GLAPI void APIENTRY glColorPointerEXT (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer);
+GLAPI void APIENTRY glDrawArraysEXT (GLenum mode, GLint first, GLsizei count);
+GLAPI void APIENTRY glEdgeFlagPointerEXT (GLsizei stride, GLsizei count, const GLboolean *pointer);
+GLAPI void APIENTRY glGetPointervEXT (GLenum pname, GLvoid* *params);
+GLAPI void APIENTRY glIndexPointerEXT (GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer);
+GLAPI void APIENTRY glNormalPointerEXT (GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer);
+GLAPI void APIENTRY glTexCoordPointerEXT (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer);
+GLAPI void APIENTRY glVertexPointerEXT (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLARRAYELEMENTEXTPROC) (GLint i);
+typedef void (APIENTRYP PFNGLCOLORPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLDRAWARRAYSEXTPROC) (GLenum mode, GLint first, GLsizei count);
+typedef void (APIENTRYP PFNGLEDGEFLAGPOINTEREXTPROC) (GLsizei stride, GLsizei count, const GLboolean *pointer);
+typedef void (APIENTRYP PFNGLGETPOINTERVEXTPROC) (GLenum pname, GLvoid* *params);
+typedef void (APIENTRYP PFNGLINDEXPOINTEREXTPROC) (GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLNORMALPOINTEREXTPROC) (GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLTEXCOORDPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLVERTEXPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer);
+#endif
+
+#ifndef GL_EXT_misc_attribute
+#define GL_EXT_misc_attribute 1
+#endif
+
+#ifndef GL_SGIS_generate_mipmap
+#define GL_SGIS_generate_mipmap 1
+#endif
+
+#ifndef GL_SGIX_clipmap
+#define GL_SGIX_clipmap 1
+#endif
+
+#ifndef GL_SGIX_shadow
+#define GL_SGIX_shadow 1
+#endif
+
+#ifndef GL_SGIS_texture_edge_clamp
+#define GL_SGIS_texture_edge_clamp 1
+#endif
+
+#ifndef GL_SGIS_texture_border_clamp
+#define GL_SGIS_texture_border_clamp 1
+#endif
+
+#ifndef GL_EXT_blend_minmax
+#define GL_EXT_blend_minmax 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBlendEquationEXT (GLenum mode);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBLENDEQUATIONEXTPROC) (GLenum mode);
+#endif
+
+#ifndef GL_EXT_blend_subtract
+#define GL_EXT_blend_subtract 1
+#endif
+
+#ifndef GL_EXT_blend_logic_op
+#define GL_EXT_blend_logic_op 1
+#endif
+
+#ifndef GL_SGIX_interlace
+#define GL_SGIX_interlace 1
+#endif
+
+#ifndef GL_SGIX_pixel_tiles
+#define GL_SGIX_pixel_tiles 1
+#endif
+
+#ifndef GL_SGIX_texture_select
+#define GL_SGIX_texture_select 1
+#endif
+
+#ifndef GL_SGIX_sprite
+#define GL_SGIX_sprite 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glSpriteParameterfSGIX (GLenum pname, GLfloat param);
+GLAPI void APIENTRY glSpriteParameterfvSGIX (GLenum pname, const GLfloat *params);
+GLAPI void APIENTRY glSpriteParameteriSGIX (GLenum pname, GLint param);
+GLAPI void APIENTRY glSpriteParameterivSGIX (GLenum pname, const GLint *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLSPRITEPARAMETERFSGIXPROC) (GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLSPRITEPARAMETERFVSGIXPROC) (GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLSPRITEPARAMETERISGIXPROC) (GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLSPRITEPARAMETERIVSGIXPROC) (GLenum pname, const GLint *params);
+#endif
+
+#ifndef GL_SGIX_texture_multi_buffer
+#define GL_SGIX_texture_multi_buffer 1
+#endif
+
+#ifndef GL_EXT_point_parameters
+#define GL_EXT_point_parameters 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glPointParameterfEXT (GLenum pname, GLfloat param);
+GLAPI void APIENTRY glPointParameterfvEXT (GLenum pname, const GLfloat *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPOINTPARAMETERFEXTPROC) (GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLPOINTPARAMETERFVEXTPROC) (GLenum pname, const GLfloat *params);
+#endif
+
+#ifndef GL_SGIS_point_parameters
+#define GL_SGIS_point_parameters 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glPointParameterfSGIS (GLenum pname, GLfloat param);
+GLAPI void APIENTRY glPointParameterfvSGIS (GLenum pname, const GLfloat *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPOINTPARAMETERFSGISPROC) (GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLPOINTPARAMETERFVSGISPROC) (GLenum pname, const GLfloat *params);
+#endif
+
+#ifndef GL_SGIX_instruments
+#define GL_SGIX_instruments 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI GLint APIENTRY glGetInstrumentsSGIX (void);
+GLAPI void APIENTRY glInstrumentsBufferSGIX (GLsizei size, GLint *buffer);
+GLAPI GLint APIENTRY glPollInstrumentsSGIX (GLint *marker_p);
+GLAPI void APIENTRY glReadInstrumentsSGIX (GLint marker);
+GLAPI void APIENTRY glStartInstrumentsSGIX (void);
+GLAPI void APIENTRY glStopInstrumentsSGIX (GLint marker);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef GLint (APIENTRYP PFNGLGETINSTRUMENTSSGIXPROC) (void);
+typedef void (APIENTRYP PFNGLINSTRUMENTSBUFFERSGIXPROC) (GLsizei size, GLint *buffer);
+typedef GLint (APIENTRYP PFNGLPOLLINSTRUMENTSSGIXPROC) (GLint *marker_p);
+typedef void (APIENTRYP PFNGLREADINSTRUMENTSSGIXPROC) (GLint marker);
+typedef void (APIENTRYP PFNGLSTARTINSTRUMENTSSGIXPROC) (void);
+typedef void (APIENTRYP PFNGLSTOPINSTRUMENTSSGIXPROC) (GLint marker);
+#endif
+
+#ifndef GL_SGIX_texture_scale_bias
+#define GL_SGIX_texture_scale_bias 1
+#endif
+
+#ifndef GL_SGIX_framezoom
+#define GL_SGIX_framezoom 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glFrameZoomSGIX (GLint factor);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLFRAMEZOOMSGIXPROC) (GLint factor);
+#endif
+
+#ifndef GL_SGIX_tag_sample_buffer
+#define GL_SGIX_tag_sample_buffer 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTagSampleBufferSGIX (void);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLTAGSAMPLEBUFFERSGIXPROC) (void);
+#endif
+
+#ifndef GL_SGIX_polynomial_ffd
+#define GL_SGIX_polynomial_ffd 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDeformationMap3dSGIX (GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, GLdouble w1, GLdouble w2, GLint wstride, GLint worder, const GLdouble *points);
+GLAPI void APIENTRY glDeformationMap3fSGIX (GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, GLfloat w1, GLfloat w2, GLint wstride, GLint worder, const GLfloat *points);
+GLAPI void APIENTRY glDeformSGIX (GLbitfield mask);
+GLAPI void APIENTRY glLoadIdentityDeformationMapSGIX (GLbitfield mask);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLDEFORMATIONMAP3DSGIXPROC) (GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, GLdouble w1, GLdouble w2, GLint wstride, GLint worder, const GLdouble *points);
+typedef void (APIENTRYP PFNGLDEFORMATIONMAP3FSGIXPROC) (GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, GLfloat w1, GLfloat w2, GLint wstride, GLint worder, const GLfloat *points);
+typedef void (APIENTRYP PFNGLDEFORMSGIXPROC) (GLbitfield mask);
+typedef void (APIENTRYP PFNGLLOADIDENTITYDEFORMATIONMAPSGIXPROC) (GLbitfield mask);
+#endif
+
+#ifndef GL_SGIX_reference_plane
+#define GL_SGIX_reference_plane 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glReferencePlaneSGIX (const GLdouble *equation);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLREFERENCEPLANESGIXPROC) (const GLdouble *equation);
+#endif
+
+#ifndef GL_SGIX_flush_raster
+#define GL_SGIX_flush_raster 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glFlushRasterSGIX (void);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLFLUSHRASTERSGIXPROC) (void);
+#endif
+
+#ifndef GL_SGIX_depth_texture
+#define GL_SGIX_depth_texture 1
+#endif
+
+#ifndef GL_SGIS_fog_function
+#define GL_SGIS_fog_function 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glFogFuncSGIS (GLsizei n, const GLfloat *points);
+GLAPI void APIENTRY glGetFogFuncSGIS (GLfloat *points);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLFOGFUNCSGISPROC) (GLsizei n, const GLfloat *points);
+typedef void (APIENTRYP PFNGLGETFOGFUNCSGISPROC) (GLfloat *points);
+#endif
+
+#ifndef GL_SGIX_fog_offset
+#define GL_SGIX_fog_offset 1
+#endif
+
+#ifndef GL_HP_image_transform
+#define GL_HP_image_transform 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glImageTransformParameteriHP (GLenum target, GLenum pname, GLint param);
+GLAPI void APIENTRY glImageTransformParameterfHP (GLenum target, GLenum pname, GLfloat param);
+GLAPI void APIENTRY glImageTransformParameterivHP (GLenum target, GLenum pname, const GLint *params);
+GLAPI void APIENTRY glImageTransformParameterfvHP (GLenum target, GLenum pname, const GLfloat *params);
+GLAPI void APIENTRY glGetImageTransformParameterivHP (GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetImageTransformParameterfvHP (GLenum target, GLenum pname, GLfloat *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLIMAGETRANSFORMPARAMETERIHPPROC) (GLenum target, GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLIMAGETRANSFORMPARAMETERFHPPROC) (GLenum target, GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLIMAGETRANSFORMPARAMETERIVHPPROC) (GLenum target, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLIMAGETRANSFORMPARAMETERFVHPPROC) (GLenum target, GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLGETIMAGETRANSFORMPARAMETERIVHPPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETIMAGETRANSFORMPARAMETERFVHPPROC) (GLenum target, GLenum pname, GLfloat *params);
+#endif
+
+#ifndef GL_HP_convolution_border_modes
+#define GL_HP_convolution_border_modes 1
+#endif
+
+#ifndef GL_SGIX_texture_add_env
+#define GL_SGIX_texture_add_env 1
+#endif
+
+#ifndef GL_EXT_color_subtable
+#define GL_EXT_color_subtable 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glColorSubTableEXT (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data);
+GLAPI void APIENTRY glCopyColorSubTableEXT (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLCOLORSUBTABLEEXTPROC) (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data);
+typedef void (APIENTRYP PFNGLCOPYCOLORSUBTABLEEXTPROC) (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width);
+#endif
+
+#ifndef GL_PGI_vertex_hints
+#define GL_PGI_vertex_hints 1
+#endif
+
+#ifndef GL_PGI_misc_hints
+#define GL_PGI_misc_hints 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glHintPGI (GLenum target, GLint mode);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLHINTPGIPROC) (GLenum target, GLint mode);
+#endif
+
+#ifndef GL_EXT_paletted_texture
+#define GL_EXT_paletted_texture 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glColorTableEXT (GLenum target, GLenum internalFormat, GLsizei width, GLenum format, GLenum type, const GLvoid *table);
+GLAPI void APIENTRY glGetColorTableEXT (GLenum target, GLenum format, GLenum type, GLvoid *data);
+GLAPI void APIENTRY glGetColorTableParameterivEXT (GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetColorTableParameterfvEXT (GLenum target, GLenum pname, GLfloat *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLCOLORTABLEEXTPROC) (GLenum target, GLenum internalFormat, GLsizei width, GLenum format, GLenum type, const GLvoid *table);
+typedef void (APIENTRYP PFNGLGETCOLORTABLEEXTPROC) (GLenum target, GLenum format, GLenum type, GLvoid *data);
+typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params);
+#endif
+
+#ifndef GL_EXT_clip_volume_hint
+#define GL_EXT_clip_volume_hint 1
+#endif
+
+#ifndef GL_SGIX_list_priority
+#define GL_SGIX_list_priority 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGetListParameterfvSGIX (GLuint list, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetListParameterivSGIX (GLuint list, GLenum pname, GLint *params);
+GLAPI void APIENTRY glListParameterfSGIX (GLuint list, GLenum pname, GLfloat param);
+GLAPI void APIENTRY glListParameterfvSGIX (GLuint list, GLenum pname, const GLfloat *params);
+GLAPI void APIENTRY glListParameteriSGIX (GLuint list, GLenum pname, GLint param);
+GLAPI void APIENTRY glListParameterivSGIX (GLuint list, GLenum pname, const GLint *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLGETLISTPARAMETERFVSGIXPROC) (GLuint list, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETLISTPARAMETERIVSGIXPROC) (GLuint list, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLLISTPARAMETERFSGIXPROC) (GLuint list, GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLLISTPARAMETERFVSGIXPROC) (GLuint list, GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLLISTPARAMETERISGIXPROC) (GLuint list, GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLLISTPARAMETERIVSGIXPROC) (GLuint list, GLenum pname, const GLint *params);
+#endif
+
+#ifndef GL_SGIX_ir_instrument1
+#define GL_SGIX_ir_instrument1 1
+#endif
+
+#ifndef GL_SGIX_calligraphic_fragment
+#define GL_SGIX_calligraphic_fragment 1
+#endif
+
+#ifndef GL_SGIX_texture_lod_bias
+#define GL_SGIX_texture_lod_bias 1
+#endif
+
+#ifndef GL_SGIX_shadow_ambient
+#define GL_SGIX_shadow_ambient 1
+#endif
+
+#ifndef GL_EXT_index_texture
+#define GL_EXT_index_texture 1
+#endif
+
+#ifndef GL_EXT_index_material
+#define GL_EXT_index_material 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glIndexMaterialEXT (GLenum face, GLenum mode);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLINDEXMATERIALEXTPROC) (GLenum face, GLenum mode);
+#endif
+
+#ifndef GL_EXT_index_func
+#define GL_EXT_index_func 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glIndexFuncEXT (GLenum func, GLclampf ref);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLINDEXFUNCEXTPROC) (GLenum func, GLclampf ref);
+#endif
+
+#ifndef GL_EXT_index_array_formats
+#define GL_EXT_index_array_formats 1
+#endif
+
+#ifndef GL_EXT_compiled_vertex_array
+#define GL_EXT_compiled_vertex_array 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glLockArraysEXT (GLint first, GLsizei count);
+GLAPI void APIENTRY glUnlockArraysEXT (void);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLLOCKARRAYSEXTPROC) (GLint first, GLsizei count);
+typedef void (APIENTRYP PFNGLUNLOCKARRAYSEXTPROC) (void);
+#endif
+
+#ifndef GL_EXT_cull_vertex
+#define GL_EXT_cull_vertex 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glCullParameterdvEXT (GLenum pname, GLdouble *params);
+GLAPI void APIENTRY glCullParameterfvEXT (GLenum pname, GLfloat *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLCULLPARAMETERDVEXTPROC) (GLenum pname, GLdouble *params);
+typedef void (APIENTRYP PFNGLCULLPARAMETERFVEXTPROC) (GLenum pname, GLfloat *params);
+#endif
+
+#ifndef GL_SGIX_ycrcb
+#define GL_SGIX_ycrcb 1
+#endif
+
+#ifndef GL_SGIX_fragment_lighting
+#define GL_SGIX_fragment_lighting 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glFragmentColorMaterialSGIX (GLenum face, GLenum mode);
+GLAPI void APIENTRY glFragmentLightfSGIX (GLenum light, GLenum pname, GLfloat param);
+GLAPI void APIENTRY glFragmentLightfvSGIX (GLenum light, GLenum pname, const GLfloat *params);
+GLAPI void APIENTRY glFragmentLightiSGIX (GLenum light, GLenum pname, GLint param);
+GLAPI void APIENTRY glFragmentLightivSGIX (GLenum light, GLenum pname, const GLint *params);
+GLAPI void APIENTRY glFragmentLightModelfSGIX (GLenum pname, GLfloat param);
+GLAPI void APIENTRY glFragmentLightModelfvSGIX (GLenum pname, const GLfloat *params);
+GLAPI void APIENTRY glFragmentLightModeliSGIX (GLenum pname, GLint param);
+GLAPI void APIENTRY glFragmentLightModelivSGIX (GLenum pname, const GLint *params);
+GLAPI void APIENTRY glFragmentMaterialfSGIX (GLenum face, GLenum pname, GLfloat param);
+GLAPI void APIENTRY glFragmentMaterialfvSGIX (GLenum face, GLenum pname, const GLfloat *params);
+GLAPI void APIENTRY glFragmentMaterialiSGIX (GLenum face, GLenum pname, GLint param);
+GLAPI void APIENTRY glFragmentMaterialivSGIX (GLenum face, GLenum pname, const GLint *params);
+GLAPI void APIENTRY glGetFragmentLightfvSGIX (GLenum light, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetFragmentLightivSGIX (GLenum light, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetFragmentMaterialfvSGIX (GLenum face, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetFragmentMaterialivSGIX (GLenum face, GLenum pname, GLint *params);
+GLAPI void APIENTRY glLightEnviSGIX (GLenum pname, GLint param);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLFRAGMENTCOLORMATERIALSGIXPROC) (GLenum face, GLenum mode);
+typedef void (APIENTRYP PFNGLFRAGMENTLIGHTFSGIXPROC) (GLenum light, GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLFRAGMENTLIGHTFVSGIXPROC) (GLenum light, GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLFRAGMENTLIGHTISGIXPROC) (GLenum light, GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLFRAGMENTLIGHTIVSGIXPROC) (GLenum light, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLFRAGMENTLIGHTMODELFSGIXPROC) (GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLFRAGMENTLIGHTMODELFVSGIXPROC) (GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLFRAGMENTLIGHTMODELISGIXPROC) (GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLFRAGMENTLIGHTMODELIVSGIXPROC) (GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLFRAGMENTMATERIALFSGIXPROC) (GLenum face, GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLFRAGMENTMATERIALFVSGIXPROC) (GLenum face, GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLFRAGMENTMATERIALISGIXPROC) (GLenum face, GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLFRAGMENTMATERIALIVSGIXPROC) (GLenum face, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLGETFRAGMENTLIGHTFVSGIXPROC) (GLenum light, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETFRAGMENTLIGHTIVSGIXPROC) (GLenum light, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETFRAGMENTMATERIALFVSGIXPROC) (GLenum face, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETFRAGMENTMATERIALIVSGIXPROC) (GLenum face, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLLIGHTENVISGIXPROC) (GLenum pname, GLint param);
+#endif
+
+#ifndef GL_IBM_rasterpos_clip
+#define GL_IBM_rasterpos_clip 1
+#endif
+
+#ifndef GL_HP_texture_lighting
+#define GL_HP_texture_lighting 1
+#endif
+
+#ifndef GL_EXT_draw_range_elements
+#define GL_EXT_draw_range_elements 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDrawRangeElementsEXT (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSEXTPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices);
+#endif
+
+#ifndef GL_WIN_phong_shading
+#define GL_WIN_phong_shading 1
+#endif
+
+#ifndef GL_WIN_specular_fog
+#define GL_WIN_specular_fog 1
+#endif
+
+#ifndef GL_EXT_light_texture
+#define GL_EXT_light_texture 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glApplyTextureEXT (GLenum mode);
+GLAPI void APIENTRY glTextureLightEXT (GLenum pname);
+GLAPI void APIENTRY glTextureMaterialEXT (GLenum face, GLenum mode);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLAPPLYTEXTUREEXTPROC) (GLenum mode);
+typedef void (APIENTRYP PFNGLTEXTURELIGHTEXTPROC) (GLenum pname);
+typedef void (APIENTRYP PFNGLTEXTUREMATERIALEXTPROC) (GLenum face, GLenum mode);
+#endif
+
+#ifndef GL_SGIX_blend_alpha_minmax
+#define GL_SGIX_blend_alpha_minmax 1
+#endif
+
+#ifndef GL_EXT_bgra
+#define GL_EXT_bgra 1
+#endif
+
+#ifndef GL_SGIX_async
+#define GL_SGIX_async 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glAsyncMarkerSGIX (GLuint marker);
+GLAPI GLint APIENTRY glFinishAsyncSGIX (GLuint *markerp);
+GLAPI GLint APIENTRY glPollAsyncSGIX (GLuint *markerp);
+GLAPI GLuint APIENTRY glGenAsyncMarkersSGIX (GLsizei range);
+GLAPI void APIENTRY glDeleteAsyncMarkersSGIX (GLuint marker, GLsizei range);
+GLAPI GLboolean APIENTRY glIsAsyncMarkerSGIX (GLuint marker);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLASYNCMARKERSGIXPROC) (GLuint marker);
+typedef GLint (APIENTRYP PFNGLFINISHASYNCSGIXPROC) (GLuint *markerp);
+typedef GLint (APIENTRYP PFNGLPOLLASYNCSGIXPROC) (GLuint *markerp);
+typedef GLuint (APIENTRYP PFNGLGENASYNCMARKERSSGIXPROC) (GLsizei range);
+typedef void (APIENTRYP PFNGLDELETEASYNCMARKERSSGIXPROC) (GLuint marker, GLsizei range);
+typedef GLboolean (APIENTRYP PFNGLISASYNCMARKERSGIXPROC) (GLuint marker);
+#endif
+
+#ifndef GL_SGIX_async_pixel
+#define GL_SGIX_async_pixel 1
+#endif
+
+#ifndef GL_SGIX_async_histogram
+#define GL_SGIX_async_histogram 1
+#endif
+
+#ifndef GL_INTEL_parallel_arrays
+#define GL_INTEL_parallel_arrays 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glVertexPointervINTEL (GLint size, GLenum type, const GLvoid* *pointer);
+GLAPI void APIENTRY glNormalPointervINTEL (GLenum type, const GLvoid* *pointer);
+GLAPI void APIENTRY glColorPointervINTEL (GLint size, GLenum type, const GLvoid* *pointer);
+GLAPI void APIENTRY glTexCoordPointervINTEL (GLint size, GLenum type, const GLvoid* *pointer);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLVERTEXPOINTERVINTELPROC) (GLint size, GLenum type, const GLvoid* *pointer);
+typedef void (APIENTRYP PFNGLNORMALPOINTERVINTELPROC) (GLenum type, const GLvoid* *pointer);
+typedef void (APIENTRYP PFNGLCOLORPOINTERVINTELPROC) (GLint size, GLenum type, const GLvoid* *pointer);
+typedef void (APIENTRYP PFNGLTEXCOORDPOINTERVINTELPROC) (GLint size, GLenum type, const GLvoid* *pointer);
+#endif
+
+#ifndef GL_HP_occlusion_test
+#define GL_HP_occlusion_test 1
+#endif
+
+#ifndef GL_EXT_pixel_transform
+#define GL_EXT_pixel_transform 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glPixelTransformParameteriEXT (GLenum target, GLenum pname, GLint param);
+GLAPI void APIENTRY glPixelTransformParameterfEXT (GLenum target, GLenum pname, GLfloat param);
+GLAPI void APIENTRY glPixelTransformParameterivEXT (GLenum target, GLenum pname, const GLint *params);
+GLAPI void APIENTRY glPixelTransformParameterfvEXT (GLenum target, GLenum pname, const GLfloat *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPIXELTRANSFORMPARAMETERIEXTPROC) (GLenum target, GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLPIXELTRANSFORMPARAMETERFEXTPROC) (GLenum target, GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLPIXELTRANSFORMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLPIXELTRANSFORMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, const GLfloat *params);
+#endif
+
+#ifndef GL_EXT_pixel_transform_color_table
+#define GL_EXT_pixel_transform_color_table 1
+#endif
+
+#ifndef GL_EXT_shared_texture_palette
+#define GL_EXT_shared_texture_palette 1
+#endif
+
+#ifndef GL_EXT_separate_specular_color
+#define GL_EXT_separate_specular_color 1
+#endif
+
+#ifndef GL_EXT_secondary_color
+#define GL_EXT_secondary_color 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glSecondaryColor3bEXT (GLbyte red, GLbyte green, GLbyte blue);
+GLAPI void APIENTRY glSecondaryColor3bvEXT (const GLbyte *v);
+GLAPI void APIENTRY glSecondaryColor3dEXT (GLdouble red, GLdouble green, GLdouble blue);
+GLAPI void APIENTRY glSecondaryColor3dvEXT (const GLdouble *v);
+GLAPI void APIENTRY glSecondaryColor3fEXT (GLfloat red, GLfloat green, GLfloat blue);
+GLAPI void APIENTRY glSecondaryColor3fvEXT (const GLfloat *v);
+GLAPI void APIENTRY glSecondaryColor3iEXT (GLint red, GLint green, GLint blue);
+GLAPI void APIENTRY glSecondaryColor3ivEXT (const GLint *v);
+GLAPI void APIENTRY glSecondaryColor3sEXT (GLshort red, GLshort green, GLshort blue);
+GLAPI void APIENTRY glSecondaryColor3svEXT (const GLshort *v);
+GLAPI void APIENTRY glSecondaryColor3ubEXT (GLubyte red, GLubyte green, GLubyte blue);
+GLAPI void APIENTRY glSecondaryColor3ubvEXT (const GLubyte *v);
+GLAPI void APIENTRY glSecondaryColor3uiEXT (GLuint red, GLuint green, GLuint blue);
+GLAPI void APIENTRY glSecondaryColor3uivEXT (const GLuint *v);
+GLAPI void APIENTRY glSecondaryColor3usEXT (GLushort red, GLushort green, GLushort blue);
+GLAPI void APIENTRY glSecondaryColor3usvEXT (const GLushort *v);
+GLAPI void APIENTRY glSecondaryColorPointerEXT (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BEXTPROC) (GLbyte red, GLbyte green, GLbyte blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BVEXTPROC) (const GLbyte *v);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DEXTPROC) (GLdouble red, GLdouble green, GLdouble blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DVEXTPROC) (const GLdouble *v);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FEXTPROC) (GLfloat red, GLfloat green, GLfloat blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FVEXTPROC) (const GLfloat *v);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IEXTPROC) (GLint red, GLint green, GLint blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IVEXTPROC) (const GLint *v);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SEXTPROC) (GLshort red, GLshort green, GLshort blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SVEXTPROC) (const GLshort *v);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBEXTPROC) (GLubyte red, GLubyte green, GLubyte blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBVEXTPROC) (const GLubyte *v);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIEXTPROC) (GLuint red, GLuint green, GLuint blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIVEXTPROC) (const GLuint *v);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USEXTPROC) (GLushort red, GLushort green, GLushort blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USVEXTPROC) (const GLushort *v);
+typedef void (APIENTRYP PFNGLSECONDARYCOLORPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+#endif
+
+#ifndef GL_EXT_texture_perturb_normal
+#define GL_EXT_texture_perturb_normal 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTextureNormalEXT (GLenum mode);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLTEXTURENORMALEXTPROC) (GLenum mode);
+#endif
+
+#ifndef GL_EXT_multi_draw_arrays
+#define GL_EXT_multi_draw_arrays 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glMultiDrawArraysEXT (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount);
+GLAPI void APIENTRY glMultiDrawElementsEXT (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSEXTPROC) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount);
+typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSEXTPROC) (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount);
+#endif
+
+#ifndef GL_EXT_fog_coord
+#define GL_EXT_fog_coord 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glFogCoordfEXT (GLfloat coord);
+GLAPI void APIENTRY glFogCoordfvEXT (const GLfloat *coord);
+GLAPI void APIENTRY glFogCoorddEXT (GLdouble coord);
+GLAPI void APIENTRY glFogCoorddvEXT (const GLdouble *coord);
+GLAPI void APIENTRY glFogCoordPointerEXT (GLenum type, GLsizei stride, const GLvoid *pointer);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLFOGCOORDFEXTPROC) (GLfloat coord);
+typedef void (APIENTRYP PFNGLFOGCOORDFVEXTPROC) (const GLfloat *coord);
+typedef void (APIENTRYP PFNGLFOGCOORDDEXTPROC) (GLdouble coord);
+typedef void (APIENTRYP PFNGLFOGCOORDDVEXTPROC) (const GLdouble *coord);
+typedef void (APIENTRYP PFNGLFOGCOORDPOINTEREXTPROC) (GLenum type, GLsizei stride, const GLvoid *pointer);
+#endif
+
+#ifndef GL_REND_screen_coordinates
+#define GL_REND_screen_coordinates 1
+#endif
+
+#ifndef GL_EXT_coordinate_frame
+#define GL_EXT_coordinate_frame 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTangent3bEXT (GLbyte tx, GLbyte ty, GLbyte tz);
+GLAPI void APIENTRY glTangent3bvEXT (const GLbyte *v);
+GLAPI void APIENTRY glTangent3dEXT (GLdouble tx, GLdouble ty, GLdouble tz);
+GLAPI void APIENTRY glTangent3dvEXT (const GLdouble *v);
+GLAPI void APIENTRY glTangent3fEXT (GLfloat tx, GLfloat ty, GLfloat tz);
+GLAPI void APIENTRY glTangent3fvEXT (const GLfloat *v);
+GLAPI void APIENTRY glTangent3iEXT (GLint tx, GLint ty, GLint tz);
+GLAPI void APIENTRY glTangent3ivEXT (const GLint *v);
+GLAPI void APIENTRY glTangent3sEXT (GLshort tx, GLshort ty, GLshort tz);
+GLAPI void APIENTRY glTangent3svEXT (const GLshort *v);
+GLAPI void APIENTRY glBinormal3bEXT (GLbyte bx, GLbyte by, GLbyte bz);
+GLAPI void APIENTRY glBinormal3bvEXT (const GLbyte *v);
+GLAPI void APIENTRY glBinormal3dEXT (GLdouble bx, GLdouble by, GLdouble bz);
+GLAPI void APIENTRY glBinormal3dvEXT (const GLdouble *v);
+GLAPI void APIENTRY glBinormal3fEXT (GLfloat bx, GLfloat by, GLfloat bz);
+GLAPI void APIENTRY glBinormal3fvEXT (const GLfloat *v);
+GLAPI void APIENTRY glBinormal3iEXT (GLint bx, GLint by, GLint bz);
+GLAPI void APIENTRY glBinormal3ivEXT (const GLint *v);
+GLAPI void APIENTRY glBinormal3sEXT (GLshort bx, GLshort by, GLshort bz);
+GLAPI void APIENTRY glBinormal3svEXT (const GLshort *v);
+GLAPI void APIENTRY glTangentPointerEXT (GLenum type, GLsizei stride, const GLvoid *pointer);
+GLAPI void APIENTRY glBinormalPointerEXT (GLenum type, GLsizei stride, const GLvoid *pointer);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLTANGENT3BEXTPROC) (GLbyte tx, GLbyte ty, GLbyte tz);
+typedef void (APIENTRYP PFNGLTANGENT3BVEXTPROC) (const GLbyte *v);
+typedef void (APIENTRYP PFNGLTANGENT3DEXTPROC) (GLdouble tx, GLdouble ty, GLdouble tz);
+typedef void (APIENTRYP PFNGLTANGENT3DVEXTPROC) (const GLdouble *v);
+typedef void (APIENTRYP PFNGLTANGENT3FEXTPROC) (GLfloat tx, GLfloat ty, GLfloat tz);
+typedef void (APIENTRYP PFNGLTANGENT3FVEXTPROC) (const GLfloat *v);
+typedef void (APIENTRYP PFNGLTANGENT3IEXTPROC) (GLint tx, GLint ty, GLint tz);
+typedef void (APIENTRYP PFNGLTANGENT3IVEXTPROC) (const GLint *v);
+typedef void (APIENTRYP PFNGLTANGENT3SEXTPROC) (GLshort tx, GLshort ty, GLshort tz);
+typedef void (APIENTRYP PFNGLTANGENT3SVEXTPROC) (const GLshort *v);
+typedef void (APIENTRYP PFNGLBINORMAL3BEXTPROC) (GLbyte bx, GLbyte by, GLbyte bz);
+typedef void (APIENTRYP PFNGLBINORMAL3BVEXTPROC) (const GLbyte *v);
+typedef void (APIENTRYP PFNGLBINORMAL3DEXTPROC) (GLdouble bx, GLdouble by, GLdouble bz);
+typedef void (APIENTRYP PFNGLBINORMAL3DVEXTPROC) (const GLdouble *v);
+typedef void (APIENTRYP PFNGLBINORMAL3FEXTPROC) (GLfloat bx, GLfloat by, GLfloat bz);
+typedef void (APIENTRYP PFNGLBINORMAL3FVEXTPROC) (const GLfloat *v);
+typedef void (APIENTRYP PFNGLBINORMAL3IEXTPROC) (GLint bx, GLint by, GLint bz);
+typedef void (APIENTRYP PFNGLBINORMAL3IVEXTPROC) (const GLint *v);
+typedef void (APIENTRYP PFNGLBINORMAL3SEXTPROC) (GLshort bx, GLshort by, GLshort bz);
+typedef void (APIENTRYP PFNGLBINORMAL3SVEXTPROC) (const GLshort *v);
+typedef void (APIENTRYP PFNGLTANGENTPOINTEREXTPROC) (GLenum type, GLsizei stride, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLBINORMALPOINTEREXTPROC) (GLenum type, GLsizei stride, const GLvoid *pointer);
+#endif
+
+#ifndef GL_EXT_texture_env_combine
+#define GL_EXT_texture_env_combine 1
+#endif
+
+#ifndef GL_APPLE_specular_vector
+#define GL_APPLE_specular_vector 1
+#endif
+
+#ifndef GL_APPLE_transform_hint
+#define GL_APPLE_transform_hint 1
+#endif
+
+#ifndef GL_SGIX_fog_scale
+#define GL_SGIX_fog_scale 1
+#endif
+
+#ifndef GL_SUNX_constant_data
+#define GL_SUNX_constant_data 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glFinishTextureSUNX (void);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLFINISHTEXTURESUNXPROC) (void);
+#endif
+
+#ifndef GL_SUN_global_alpha
+#define GL_SUN_global_alpha 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGlobalAlphaFactorbSUN (GLbyte factor);
+GLAPI void APIENTRY glGlobalAlphaFactorsSUN (GLshort factor);
+GLAPI void APIENTRY glGlobalAlphaFactoriSUN (GLint factor);
+GLAPI void APIENTRY glGlobalAlphaFactorfSUN (GLfloat factor);
+GLAPI void APIENTRY glGlobalAlphaFactordSUN (GLdouble factor);
+GLAPI void APIENTRY glGlobalAlphaFactorubSUN (GLubyte factor);
+GLAPI void APIENTRY glGlobalAlphaFactorusSUN (GLushort factor);
+GLAPI void APIENTRY glGlobalAlphaFactoruiSUN (GLuint factor);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORBSUNPROC) (GLbyte factor);
+typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORSSUNPROC) (GLshort factor);
+typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORISUNPROC) (GLint factor);
+typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORFSUNPROC) (GLfloat factor);
+typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORDSUNPROC) (GLdouble factor);
+typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORUBSUNPROC) (GLubyte factor);
+typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORUSSUNPROC) (GLushort factor);
+typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORUISUNPROC) (GLuint factor);
+#endif
+
+#ifndef GL_SUN_triangle_list
+#define GL_SUN_triangle_list 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glReplacementCodeuiSUN (GLuint code);
+GLAPI void APIENTRY glReplacementCodeusSUN (GLushort code);
+GLAPI void APIENTRY glReplacementCodeubSUN (GLubyte code);
+GLAPI void APIENTRY glReplacementCodeuivSUN (const GLuint *code);
+GLAPI void APIENTRY glReplacementCodeusvSUN (const GLushort *code);
+GLAPI void APIENTRY glReplacementCodeubvSUN (const GLubyte *code);
+GLAPI void APIENTRY glReplacementCodePointerSUN (GLenum type, GLsizei stride, const GLvoid* *pointer);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUISUNPROC) (GLuint code);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUSSUNPROC) (GLushort code);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUBSUNPROC) (GLubyte code);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUIVSUNPROC) (const GLuint *code);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUSVSUNPROC) (const GLushort *code);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUBVSUNPROC) (const GLubyte *code);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEPOINTERSUNPROC) (GLenum type, GLsizei stride, const GLvoid* *pointer);
+#endif
+
+#ifndef GL_SUN_vertex
+#define GL_SUN_vertex 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glColor4ubVertex2fSUN (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y);
+GLAPI void APIENTRY glColor4ubVertex2fvSUN (const GLubyte *c, const GLfloat *v);
+GLAPI void APIENTRY glColor4ubVertex3fSUN (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glColor4ubVertex3fvSUN (const GLubyte *c, const GLfloat *v);
+GLAPI void APIENTRY glColor3fVertex3fSUN (GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glColor3fVertex3fvSUN (const GLfloat *c, const GLfloat *v);
+GLAPI void APIENTRY glNormal3fVertex3fSUN (GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glNormal3fVertex3fvSUN (const GLfloat *n, const GLfloat *v);
+GLAPI void APIENTRY glColor4fNormal3fVertex3fSUN (GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glColor4fNormal3fVertex3fvSUN (const GLfloat *c, const GLfloat *n, const GLfloat *v);
+GLAPI void APIENTRY glTexCoord2fVertex3fSUN (GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glTexCoord2fVertex3fvSUN (const GLfloat *tc, const GLfloat *v);
+GLAPI void APIENTRY glTexCoord4fVertex4fSUN (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+GLAPI void APIENTRY glTexCoord4fVertex4fvSUN (const GLfloat *tc, const GLfloat *v);
+GLAPI void APIENTRY glTexCoord2fColor4ubVertex3fSUN (GLfloat s, GLfloat t, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glTexCoord2fColor4ubVertex3fvSUN (const GLfloat *tc, const GLubyte *c, const GLfloat *v);
+GLAPI void APIENTRY glTexCoord2fColor3fVertex3fSUN (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glTexCoord2fColor3fVertex3fvSUN (const GLfloat *tc, const GLfloat *c, const GLfloat *v);
+GLAPI void APIENTRY glTexCoord2fNormal3fVertex3fSUN (GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glTexCoord2fNormal3fVertex3fvSUN (const GLfloat *tc, const GLfloat *n, const GLfloat *v);
+GLAPI void APIENTRY glTexCoord2fColor4fNormal3fVertex3fSUN (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glTexCoord2fColor4fNormal3fVertex3fvSUN (const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v);
+GLAPI void APIENTRY glTexCoord4fColor4fNormal3fVertex4fSUN (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+GLAPI void APIENTRY glTexCoord4fColor4fNormal3fVertex4fvSUN (const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v);
+GLAPI void APIENTRY glReplacementCodeuiVertex3fSUN (GLuint rc, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glReplacementCodeuiVertex3fvSUN (const GLuint *rc, const GLfloat *v);
+GLAPI void APIENTRY glReplacementCodeuiColor4ubVertex3fSUN (GLuint rc, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glReplacementCodeuiColor4ubVertex3fvSUN (const GLuint *rc, const GLubyte *c, const GLfloat *v);
+GLAPI void APIENTRY glReplacementCodeuiColor3fVertex3fSUN (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glReplacementCodeuiColor3fVertex3fvSUN (const GLuint *rc, const GLfloat *c, const GLfloat *v);
+GLAPI void APIENTRY glReplacementCodeuiNormal3fVertex3fSUN (GLuint rc, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glReplacementCodeuiNormal3fVertex3fvSUN (const GLuint *rc, const GLfloat *n, const GLfloat *v);
+GLAPI void APIENTRY glReplacementCodeuiColor4fNormal3fVertex3fSUN (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glReplacementCodeuiColor4fNormal3fVertex3fvSUN (const GLuint *rc, const GLfloat *c, const GLfloat *n, const GLfloat *v);
+GLAPI void APIENTRY glReplacementCodeuiTexCoord2fVertex3fSUN (GLuint rc, GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glReplacementCodeuiTexCoord2fVertex3fvSUN (const GLuint *rc, const GLfloat *tc, const GLfloat *v);
+GLAPI void APIENTRY glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN (GLuint rc, GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN (const GLuint *rc, const GLfloat *tc, const GLfloat *n, const GLfloat *v);
+GLAPI void APIENTRY glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN (GLuint rc, GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN (const GLuint *rc, const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLCOLOR4UBVERTEX2FSUNPROC) (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y);
+typedef void (APIENTRYP PFNGLCOLOR4UBVERTEX2FVSUNPROC) (const GLubyte *c, const GLfloat *v);
+typedef void (APIENTRYP PFNGLCOLOR4UBVERTEX3FSUNPROC) (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLCOLOR4UBVERTEX3FVSUNPROC) (const GLubyte *c, const GLfloat *v);
+typedef void (APIENTRYP PFNGLCOLOR3FVERTEX3FSUNPROC) (GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLCOLOR3FVERTEX3FVSUNPROC) (const GLfloat *c, const GLfloat *v);
+typedef void (APIENTRYP PFNGLNORMAL3FVERTEX3FSUNPROC) (GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *n, const GLfloat *v);
+typedef void (APIENTRYP PFNGLCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *c, const GLfloat *n, const GLfloat *v);
+typedef void (APIENTRYP PFNGLTEXCOORD2FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLTEXCOORD2FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *v);
+typedef void (APIENTRYP PFNGLTEXCOORD4FVERTEX4FSUNPROC) (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (APIENTRYP PFNGLTEXCOORD4FVERTEX4FVSUNPROC) (const GLfloat *tc, const GLfloat *v);
+typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR4UBVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR4UBVERTEX3FVSUNPROC) (const GLfloat *tc, const GLubyte *c, const GLfloat *v);
+typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR3FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *c, const GLfloat *v);
+typedef void (APIENTRYP PFNGLTEXCOORD2FNORMAL3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLTEXCOORD2FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *n, const GLfloat *v);
+typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v);
+typedef void (APIENTRYP PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FSUNPROC) (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (APIENTRYP PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FVSUNPROC) (const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUIVERTEX3FSUNPROC) (GLuint rc, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUIVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *v);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FSUNPROC) (GLuint rc, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FVSUNPROC) (const GLuint *rc, const GLubyte *c, const GLfloat *v);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FSUNPROC) (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *c, const GLfloat *v);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *n, const GLfloat *v);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *c, const GLfloat *n, const GLfloat *v);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *tc, const GLfloat *v);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *tc, const GLfloat *n, const GLfloat *v);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v);
+#endif
+
+#ifndef GL_EXT_blend_func_separate
+#define GL_EXT_blend_func_separate 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBlendFuncSeparateEXT (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEEXTPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);
+#endif
+
+#ifndef GL_INGR_blend_func_separate
+#define GL_INGR_blend_func_separate 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBlendFuncSeparateINGR (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEINGRPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);
+#endif
+
+#ifndef GL_INGR_color_clamp
+#define GL_INGR_color_clamp 1
+#endif
+
+#ifndef GL_INGR_interlace_read
+#define GL_INGR_interlace_read 1
+#endif
+
+#ifndef GL_EXT_stencil_wrap
+#define GL_EXT_stencil_wrap 1
+#endif
+
+#ifndef GL_EXT_422_pixels
+#define GL_EXT_422_pixels 1
+#endif
+
+#ifndef GL_NV_texgen_reflection
+#define GL_NV_texgen_reflection 1
+#endif
+
+#ifndef GL_SUN_convolution_border_modes
+#define GL_SUN_convolution_border_modes 1
+#endif
+
+#ifndef GL_EXT_texture_env_add
+#define GL_EXT_texture_env_add 1
+#endif
+
+#ifndef GL_EXT_texture_lod_bias
+#define GL_EXT_texture_lod_bias 1
+#endif
+
+#ifndef GL_EXT_texture_filter_anisotropic
+#define GL_EXT_texture_filter_anisotropic 1
+#endif
+
+#ifndef GL_EXT_vertex_weighting
+#define GL_EXT_vertex_weighting 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glVertexWeightfEXT (GLfloat weight);
+GLAPI void APIENTRY glVertexWeightfvEXT (const GLfloat *weight);
+GLAPI void APIENTRY glVertexWeightPointerEXT (GLsizei size, GLenum type, GLsizei stride, const GLvoid *pointer);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLVERTEXWEIGHTFEXTPROC) (GLfloat weight);
+typedef void (APIENTRYP PFNGLVERTEXWEIGHTFVEXTPROC) (const GLfloat *weight);
+typedef void (APIENTRYP PFNGLVERTEXWEIGHTPOINTEREXTPROC) (GLsizei size, GLenum type, GLsizei stride, const GLvoid *pointer);
+#endif
+
+#ifndef GL_NV_light_max_exponent
+#define GL_NV_light_max_exponent 1
+#endif
+
+#ifndef GL_NV_vertex_array_range
+#define GL_NV_vertex_array_range 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glFlushVertexArrayRangeNV (void);
+GLAPI void APIENTRY glVertexArrayRangeNV (GLsizei length, const GLvoid *pointer);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLFLUSHVERTEXARRAYRANGENVPROC) (void);
+typedef void (APIENTRYP PFNGLVERTEXARRAYRANGENVPROC) (GLsizei length, const GLvoid *pointer);
+#endif
+
+#ifndef GL_NV_register_combiners
+#define GL_NV_register_combiners 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glCombinerParameterfvNV (GLenum pname, const GLfloat *params);
+GLAPI void APIENTRY glCombinerParameterfNV (GLenum pname, GLfloat param);
+GLAPI void APIENTRY glCombinerParameterivNV (GLenum pname, const GLint *params);
+GLAPI void APIENTRY glCombinerParameteriNV (GLenum pname, GLint param);
+GLAPI void APIENTRY glCombinerInputNV (GLenum stage, GLenum portion, GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage);
+GLAPI void APIENTRY glCombinerOutputNV (GLenum stage, GLenum portion, GLenum abOutput, GLenum cdOutput, GLenum sumOutput, GLenum scale, GLenum bias, GLboolean abDotProduct, GLboolean cdDotProduct, GLboolean muxSum);
+GLAPI void APIENTRY glFinalCombinerInputNV (GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage);
+GLAPI void APIENTRY glGetCombinerInputParameterfvNV (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetCombinerInputParameterivNV (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetCombinerOutputParameterfvNV (GLenum stage, GLenum portion, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetCombinerOutputParameterivNV (GLenum stage, GLenum portion, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetFinalCombinerInputParameterfvNV (GLenum variable, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetFinalCombinerInputParameterivNV (GLenum variable, GLenum pname, GLint *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLCOMBINERPARAMETERFVNVPROC) (GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLCOMBINERPARAMETERFNVPROC) (GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLCOMBINERPARAMETERIVNVPROC) (GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLCOMBINERPARAMETERINVPROC) (GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLCOMBINERINPUTNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage);
+typedef void (APIENTRYP PFNGLCOMBINEROUTPUTNVPROC) (GLenum stage, GLenum portion, GLenum abOutput, GLenum cdOutput, GLenum sumOutput, GLenum scale, GLenum bias, GLboolean abDotProduct, GLboolean cdDotProduct, GLboolean muxSum);
+typedef void (APIENTRYP PFNGLFINALCOMBINERINPUTNVPROC) (GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage);
+typedef void (APIENTRYP PFNGLGETCOMBINERINPUTPARAMETERFVNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETCOMBINERINPUTPARAMETERIVNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC) (GLenum stage, GLenum portion, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC) (GLenum stage, GLenum portion, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC) (GLenum variable, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC) (GLenum variable, GLenum pname, GLint *params);
+#endif
+
+#ifndef GL_NV_fog_distance
+#define GL_NV_fog_distance 1
+#endif
+
+#ifndef GL_NV_texgen_emboss
+#define GL_NV_texgen_emboss 1
+#endif
+
+#ifndef GL_NV_blend_square
+#define GL_NV_blend_square 1
+#endif
+
+#ifndef GL_NV_texture_env_combine4
+#define GL_NV_texture_env_combine4 1
+#endif
+
+#ifndef GL_MESA_resize_buffers
+#define GL_MESA_resize_buffers 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glResizeBuffersMESA (void);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLRESIZEBUFFERSMESAPROC) (void);
+#endif
+
+#ifndef GL_MESA_window_pos
+#define GL_MESA_window_pos 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glWindowPos2dMESA (GLdouble x, GLdouble y);
+GLAPI void APIENTRY glWindowPos2dvMESA (const GLdouble *v);
+GLAPI void APIENTRY glWindowPos2fMESA (GLfloat x, GLfloat y);
+GLAPI void APIENTRY glWindowPos2fvMESA (const GLfloat *v);
+GLAPI void APIENTRY glWindowPos2iMESA (GLint x, GLint y);
+GLAPI void APIENTRY glWindowPos2ivMESA (const GLint *v);
+GLAPI void APIENTRY glWindowPos2sMESA (GLshort x, GLshort y);
+GLAPI void APIENTRY glWindowPos2svMESA (const GLshort *v);
+GLAPI void APIENTRY glWindowPos3dMESA (GLdouble x, GLdouble y, GLdouble z);
+GLAPI void APIENTRY glWindowPos3dvMESA (const GLdouble *v);
+GLAPI void APIENTRY glWindowPos3fMESA (GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glWindowPos3fvMESA (const GLfloat *v);
+GLAPI void APIENTRY glWindowPos3iMESA (GLint x, GLint y, GLint z);
+GLAPI void APIENTRY glWindowPos3ivMESA (const GLint *v);
+GLAPI void APIENTRY glWindowPos3sMESA (GLshort x, GLshort y, GLshort z);
+GLAPI void APIENTRY glWindowPos3svMESA (const GLshort *v);
+GLAPI void APIENTRY glWindowPos4dMESA (GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+GLAPI void APIENTRY glWindowPos4dvMESA (const GLdouble *v);
+GLAPI void APIENTRY glWindowPos4fMESA (GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+GLAPI void APIENTRY glWindowPos4fvMESA (const GLfloat *v);
+GLAPI void APIENTRY glWindowPos4iMESA (GLint x, GLint y, GLint z, GLint w);
+GLAPI void APIENTRY glWindowPos4ivMESA (const GLint *v);
+GLAPI void APIENTRY glWindowPos4sMESA (GLshort x, GLshort y, GLshort z, GLshort w);
+GLAPI void APIENTRY glWindowPos4svMESA (const GLshort *v);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLWINDOWPOS2DMESAPROC) (GLdouble x, GLdouble y);
+typedef void (APIENTRYP PFNGLWINDOWPOS2DVMESAPROC) (const GLdouble *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS2FMESAPROC) (GLfloat x, GLfloat y);
+typedef void (APIENTRYP PFNGLWINDOWPOS2FVMESAPROC) (const GLfloat *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS2IMESAPROC) (GLint x, GLint y);
+typedef void (APIENTRYP PFNGLWINDOWPOS2IVMESAPROC) (const GLint *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS2SMESAPROC) (GLshort x, GLshort y);
+typedef void (APIENTRYP PFNGLWINDOWPOS2SVMESAPROC) (const GLshort *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS3DMESAPROC) (GLdouble x, GLdouble y, GLdouble z);
+typedef void (APIENTRYP PFNGLWINDOWPOS3DVMESAPROC) (const GLdouble *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS3FMESAPROC) (GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLWINDOWPOS3FVMESAPROC) (const GLfloat *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS3IMESAPROC) (GLint x, GLint y, GLint z);
+typedef void (APIENTRYP PFNGLWINDOWPOS3IVMESAPROC) (const GLint *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS3SMESAPROC) (GLshort x, GLshort y, GLshort z);
+typedef void (APIENTRYP PFNGLWINDOWPOS3SVMESAPROC) (const GLshort *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS4DMESAPROC) (GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (APIENTRYP PFNGLWINDOWPOS4DVMESAPROC) (const GLdouble *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS4FMESAPROC) (GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (APIENTRYP PFNGLWINDOWPOS4FVMESAPROC) (const GLfloat *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS4IMESAPROC) (GLint x, GLint y, GLint z, GLint w);
+typedef void (APIENTRYP PFNGLWINDOWPOS4IVMESAPROC) (const GLint *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS4SMESAPROC) (GLshort x, GLshort y, GLshort z, GLshort w);
+typedef void (APIENTRYP PFNGLWINDOWPOS4SVMESAPROC) (const GLshort *v);
+#endif
+
+#ifndef GL_IBM_cull_vertex
+#define GL_IBM_cull_vertex 1
+#endif
+
+#ifndef GL_IBM_multimode_draw_arrays
+#define GL_IBM_multimode_draw_arrays 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glMultiModeDrawArraysIBM (const GLenum *mode, const GLint *first, const GLsizei *count, GLsizei primcount, GLint modestride);
+GLAPI void APIENTRY glMultiModeDrawElementsIBM (const GLenum *mode, const GLsizei *count, GLenum type, const GLvoid* const *indices, GLsizei primcount, GLint modestride);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLMULTIMODEDRAWARRAYSIBMPROC) (const GLenum *mode, const GLint *first, const GLsizei *count, GLsizei primcount, GLint modestride);
+typedef void (APIENTRYP PFNGLMULTIMODEDRAWELEMENTSIBMPROC) (const GLenum *mode, const GLsizei *count, GLenum type, const GLvoid* const *indices, GLsizei primcount, GLint modestride);
+#endif
+
+#ifndef GL_IBM_vertex_array_lists
+#define GL_IBM_vertex_array_lists 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glColorPointerListIBM (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride);
+GLAPI void APIENTRY glSecondaryColorPointerListIBM (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride);
+GLAPI void APIENTRY glEdgeFlagPointerListIBM (GLint stride, const GLboolean* *pointer, GLint ptrstride);
+GLAPI void APIENTRY glFogCoordPointerListIBM (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride);
+GLAPI void APIENTRY glIndexPointerListIBM (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride);
+GLAPI void APIENTRY glNormalPointerListIBM (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride);
+GLAPI void APIENTRY glTexCoordPointerListIBM (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride);
+GLAPI void APIENTRY glVertexPointerListIBM (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLCOLORPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride);
+typedef void (APIENTRYP PFNGLSECONDARYCOLORPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride);
+typedef void (APIENTRYP PFNGLEDGEFLAGPOINTERLISTIBMPROC) (GLint stride, const GLboolean* *pointer, GLint ptrstride);
+typedef void (APIENTRYP PFNGLFOGCOORDPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride);
+typedef void (APIENTRYP PFNGLINDEXPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride);
+typedef void (APIENTRYP PFNGLNORMALPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride);
+typedef void (APIENTRYP PFNGLTEXCOORDPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride);
+typedef void (APIENTRYP PFNGLVERTEXPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride);
+#endif
+
+#ifndef GL_SGIX_subsample
+#define GL_SGIX_subsample 1
+#endif
+
+#ifndef GL_SGIX_ycrcba
+#define GL_SGIX_ycrcba 1
+#endif
+
+#ifndef GL_SGIX_ycrcb_subsample
+#define GL_SGIX_ycrcb_subsample 1
+#endif
+
+#ifndef GL_SGIX_depth_pass_instrument
+#define GL_SGIX_depth_pass_instrument 1
+#endif
+
+#ifndef GL_3DFX_texture_compression_FXT1
+#define GL_3DFX_texture_compression_FXT1 1
+#endif
+
+#ifndef GL_3DFX_multisample
+#define GL_3DFX_multisample 1
+#endif
+
+#ifndef GL_3DFX_tbuffer
+#define GL_3DFX_tbuffer 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTbufferMask3DFX (GLuint mask);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLTBUFFERMASK3DFXPROC) (GLuint mask);
+#endif
+
+#ifndef GL_EXT_multisample
+#define GL_EXT_multisample 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glSampleMaskEXT (GLclampf value, GLboolean invert);
+GLAPI void APIENTRY glSamplePatternEXT (GLenum pattern);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLSAMPLEMASKEXTPROC) (GLclampf value, GLboolean invert);
+typedef void (APIENTRYP PFNGLSAMPLEPATTERNEXTPROC) (GLenum pattern);
+#endif
+
+#ifndef GL_SGIX_vertex_preclip
+#define GL_SGIX_vertex_preclip 1
+#endif
+
+#ifndef GL_SGIX_convolution_accuracy
+#define GL_SGIX_convolution_accuracy 1
+#endif
+
+#ifndef GL_SGIX_resample
+#define GL_SGIX_resample 1
+#endif
+
+#ifndef GL_SGIS_point_line_texgen
+#define GL_SGIS_point_line_texgen 1
+#endif
+
+#ifndef GL_SGIS_texture_color_mask
+#define GL_SGIS_texture_color_mask 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTextureColorMaskSGIS (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLTEXTURECOLORMASKSGISPROC) (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
+#endif
+
+#ifndef GL_SGIX_igloo_interface
+#define GL_SGIX_igloo_interface 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glIglooInterfaceSGIX (GLenum pname, const GLvoid *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLIGLOOINTERFACESGIXPROC) (GLenum pname, const GLvoid *params);
+#endif
+
+#ifndef GL_EXT_texture_env_dot3
+#define GL_EXT_texture_env_dot3 1
+#endif
+
+#ifndef GL_ATI_texture_mirror_once
+#define GL_ATI_texture_mirror_once 1
+#endif
+
+#ifndef GL_NV_fence
+#define GL_NV_fence 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDeleteFencesNV (GLsizei n, const GLuint *fences);
+GLAPI void APIENTRY glGenFencesNV (GLsizei n, GLuint *fences);
+GLAPI GLboolean APIENTRY glIsFenceNV (GLuint fence);
+GLAPI GLboolean APIENTRY glTestFenceNV (GLuint fence);
+GLAPI void APIENTRY glGetFenceivNV (GLuint fence, GLenum pname, GLint *params);
+GLAPI void APIENTRY glFinishFenceNV (GLuint fence);
+GLAPI void APIENTRY glSetFenceNV (GLuint fence, GLenum condition);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLDELETEFENCESNVPROC) (GLsizei n, const GLuint *fences);
+typedef void (APIENTRYP PFNGLGENFENCESNVPROC) (GLsizei n, GLuint *fences);
+typedef GLboolean (APIENTRYP PFNGLISFENCENVPROC) (GLuint fence);
+typedef GLboolean (APIENTRYP PFNGLTESTFENCENVPROC) (GLuint fence);
+typedef void (APIENTRYP PFNGLGETFENCEIVNVPROC) (GLuint fence, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLFINISHFENCENVPROC) (GLuint fence);
+typedef void (APIENTRYP PFNGLSETFENCENVPROC) (GLuint fence, GLenum condition);
+#endif
+
+#ifndef GL_NV_evaluators
+#define GL_NV_evaluators 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glMapControlPointsNV (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLint uorder, GLint vorder, GLboolean packed, const GLvoid *points);
+GLAPI void APIENTRY glMapParameterivNV (GLenum target, GLenum pname, const GLint *params);
+GLAPI void APIENTRY glMapParameterfvNV (GLenum target, GLenum pname, const GLfloat *params);
+GLAPI void APIENTRY glGetMapControlPointsNV (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLboolean packed, GLvoid *points);
+GLAPI void APIENTRY glGetMapParameterivNV (GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetMapParameterfvNV (GLenum target, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetMapAttribParameterivNV (GLenum target, GLuint index, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetMapAttribParameterfvNV (GLenum target, GLuint index, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glEvalMapsNV (GLenum target, GLenum mode);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLMAPCONTROLPOINTSNVPROC) (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLint uorder, GLint vorder, GLboolean packed, const GLvoid *points);
+typedef void (APIENTRYP PFNGLMAPPARAMETERIVNVPROC) (GLenum target, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLMAPPARAMETERFVNVPROC) (GLenum target, GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLGETMAPCONTROLPOINTSNVPROC) (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLboolean packed, GLvoid *points);
+typedef void (APIENTRYP PFNGLGETMAPPARAMETERIVNVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETMAPPARAMETERFVNVPROC) (GLenum target, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETMAPATTRIBPARAMETERIVNVPROC) (GLenum target, GLuint index, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETMAPATTRIBPARAMETERFVNVPROC) (GLenum target, GLuint index, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLEVALMAPSNVPROC) (GLenum target, GLenum mode);
+#endif
+
+#ifndef GL_NV_packed_depth_stencil
+#define GL_NV_packed_depth_stencil 1
+#endif
+
+#ifndef GL_NV_register_combiners2
+#define GL_NV_register_combiners2 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glCombinerStageParameterfvNV (GLenum stage, GLenum pname, const GLfloat *params);
+GLAPI void APIENTRY glGetCombinerStageParameterfvNV (GLenum stage, GLenum pname, GLfloat *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLCOMBINERSTAGEPARAMETERFVNVPROC) (GLenum stage, GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLGETCOMBINERSTAGEPARAMETERFVNVPROC) (GLenum stage, GLenum pname, GLfloat *params);
+#endif
+
+#ifndef GL_NV_texture_compression_vtc
+#define GL_NV_texture_compression_vtc 1
+#endif
+
+#ifndef GL_NV_texture_rectangle
+#define GL_NV_texture_rectangle 1
+#endif
+
+#ifndef GL_NV_texture_shader
+#define GL_NV_texture_shader 1
+#endif
+
+#ifndef GL_NV_texture_shader2
+#define GL_NV_texture_shader2 1
+#endif
+
+#ifndef GL_NV_vertex_array_range2
+#define GL_NV_vertex_array_range2 1
+#endif
+
+#ifndef GL_NV_vertex_program
+#define GL_NV_vertex_program 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI GLboolean APIENTRY glAreProgramsResidentNV (GLsizei n, const GLuint *programs, GLboolean *residences);
+GLAPI void APIENTRY glBindProgramNV (GLenum target, GLuint id);
+GLAPI void APIENTRY glDeleteProgramsNV (GLsizei n, const GLuint *programs);
+GLAPI void APIENTRY glExecuteProgramNV (GLenum target, GLuint id, const GLfloat *params);
+GLAPI void APIENTRY glGenProgramsNV (GLsizei n, GLuint *programs);
+GLAPI void APIENTRY glGetProgramParameterdvNV (GLenum target, GLuint index, GLenum pname, GLdouble *params);
+GLAPI void APIENTRY glGetProgramParameterfvNV (GLenum target, GLuint index, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetProgramivNV (GLuint id, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetProgramStringNV (GLuint id, GLenum pname, GLubyte *program);
+GLAPI void APIENTRY glGetTrackMatrixivNV (GLenum target, GLuint address, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetVertexAttribdvNV (GLuint index, GLenum pname, GLdouble *params);
+GLAPI void APIENTRY glGetVertexAttribfvNV (GLuint index, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetVertexAttribivNV (GLuint index, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetVertexAttribPointervNV (GLuint index, GLenum pname, GLvoid* *pointer);
+GLAPI GLboolean APIENTRY glIsProgramNV (GLuint id);
+GLAPI void APIENTRY glLoadProgramNV (GLenum target, GLuint id, GLsizei len, const GLubyte *program);
+GLAPI void APIENTRY glProgramParameter4dNV (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+GLAPI void APIENTRY glProgramParameter4dvNV (GLenum target, GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glProgramParameter4fNV (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+GLAPI void APIENTRY glProgramParameter4fvNV (GLenum target, GLuint index, const GLfloat *v);
+GLAPI void APIENTRY glProgramParameters4dvNV (GLenum target, GLuint index, GLsizei count, const GLdouble *v);
+GLAPI void APIENTRY glProgramParameters4fvNV (GLenum target, GLuint index, GLsizei count, const GLfloat *v);
+GLAPI void APIENTRY glRequestResidentProgramsNV (GLsizei n, const GLuint *programs);
+GLAPI void APIENTRY glTrackMatrixNV (GLenum target, GLuint address, GLenum matrix, GLenum transform);
+GLAPI void APIENTRY glVertexAttribPointerNV (GLuint index, GLint fsize, GLenum type, GLsizei stride, const GLvoid *pointer);
+GLAPI void APIENTRY glVertexAttrib1dNV (GLuint index, GLdouble x);
+GLAPI void APIENTRY glVertexAttrib1dvNV (GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttrib1fNV (GLuint index, GLfloat x);
+GLAPI void APIENTRY glVertexAttrib1fvNV (GLuint index, const GLfloat *v);
+GLAPI void APIENTRY glVertexAttrib1sNV (GLuint index, GLshort x);
+GLAPI void APIENTRY glVertexAttrib1svNV (GLuint index, const GLshort *v);
+GLAPI void APIENTRY glVertexAttrib2dNV (GLuint index, GLdouble x, GLdouble y);
+GLAPI void APIENTRY glVertexAttrib2dvNV (GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttrib2fNV (GLuint index, GLfloat x, GLfloat y);
+GLAPI void APIENTRY glVertexAttrib2fvNV (GLuint index, const GLfloat *v);
+GLAPI void APIENTRY glVertexAttrib2sNV (GLuint index, GLshort x, GLshort y);
+GLAPI void APIENTRY glVertexAttrib2svNV (GLuint index, const GLshort *v);
+GLAPI void APIENTRY glVertexAttrib3dNV (GLuint index, GLdouble x, GLdouble y, GLdouble z);
+GLAPI void APIENTRY glVertexAttrib3dvNV (GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttrib3fNV (GLuint index, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glVertexAttrib3fvNV (GLuint index, const GLfloat *v);
+GLAPI void APIENTRY glVertexAttrib3sNV (GLuint index, GLshort x, GLshort y, GLshort z);
+GLAPI void APIENTRY glVertexAttrib3svNV (GLuint index, const GLshort *v);
+GLAPI void APIENTRY glVertexAttrib4dNV (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+GLAPI void APIENTRY glVertexAttrib4dvNV (GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttrib4fNV (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+GLAPI void APIENTRY glVertexAttrib4fvNV (GLuint index, const GLfloat *v);
+GLAPI void APIENTRY glVertexAttrib4sNV (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w);
+GLAPI void APIENTRY glVertexAttrib4svNV (GLuint index, const GLshort *v);
+GLAPI void APIENTRY glVertexAttrib4ubNV (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w);
+GLAPI void APIENTRY glVertexAttrib4ubvNV (GLuint index, const GLubyte *v);
+GLAPI void APIENTRY glVertexAttribs1dvNV (GLuint index, GLsizei count, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttribs1fvNV (GLuint index, GLsizei count, const GLfloat *v);
+GLAPI void APIENTRY glVertexAttribs1svNV (GLuint index, GLsizei count, const GLshort *v);
+GLAPI void APIENTRY glVertexAttribs2dvNV (GLuint index, GLsizei count, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttribs2fvNV (GLuint index, GLsizei count, const GLfloat *v);
+GLAPI void APIENTRY glVertexAttribs2svNV (GLuint index, GLsizei count, const GLshort *v);
+GLAPI void APIENTRY glVertexAttribs3dvNV (GLuint index, GLsizei count, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttribs3fvNV (GLuint index, GLsizei count, const GLfloat *v);
+GLAPI void APIENTRY glVertexAttribs3svNV (GLuint index, GLsizei count, const GLshort *v);
+GLAPI void APIENTRY glVertexAttribs4dvNV (GLuint index, GLsizei count, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttribs4fvNV (GLuint index, GLsizei count, const GLfloat *v);
+GLAPI void APIENTRY glVertexAttribs4svNV (GLuint index, GLsizei count, const GLshort *v);
+GLAPI void APIENTRY glVertexAttribs4ubvNV (GLuint index, GLsizei count, const GLubyte *v);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef GLboolean (APIENTRYP PFNGLAREPROGRAMSRESIDENTNVPROC) (GLsizei n, const GLuint *programs, GLboolean *residences);
+typedef void (APIENTRYP PFNGLBINDPROGRAMNVPROC) (GLenum target, GLuint id);
+typedef void (APIENTRYP PFNGLDELETEPROGRAMSNVPROC) (GLsizei n, const GLuint *programs);
+typedef void (APIENTRYP PFNGLEXECUTEPROGRAMNVPROC) (GLenum target, GLuint id, const GLfloat *params);
+typedef void (APIENTRYP PFNGLGENPROGRAMSNVPROC) (GLsizei n, GLuint *programs);
+typedef void (APIENTRYP PFNGLGETPROGRAMPARAMETERDVNVPROC) (GLenum target, GLuint index, GLenum pname, GLdouble *params);
+typedef void (APIENTRYP PFNGLGETPROGRAMPARAMETERFVNVPROC) (GLenum target, GLuint index, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETPROGRAMIVNVPROC) (GLuint id, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETPROGRAMSTRINGNVPROC) (GLuint id, GLenum pname, GLubyte *program);
+typedef void (APIENTRYP PFNGLGETTRACKMATRIXIVNVPROC) (GLenum target, GLuint address, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBDVNVPROC) (GLuint index, GLenum pname, GLdouble *params);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBFVNVPROC) (GLuint index, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIVNVPROC) (GLuint index, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVNVPROC) (GLuint index, GLenum pname, GLvoid* *pointer);
+typedef GLboolean (APIENTRYP PFNGLISPROGRAMNVPROC) (GLuint id);
+typedef void (APIENTRYP PFNGLLOADPROGRAMNVPROC) (GLenum target, GLuint id, GLsizei len, const GLubyte *program);
+typedef void (APIENTRYP PFNGLPROGRAMPARAMETER4DNVPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (APIENTRYP PFNGLPROGRAMPARAMETER4DVNVPROC) (GLenum target, GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLPROGRAMPARAMETER4FNVPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (APIENTRYP PFNGLPROGRAMPARAMETER4FVNVPROC) (GLenum target, GLuint index, const GLfloat *v);
+typedef void (APIENTRYP PFNGLPROGRAMPARAMETERS4DVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLdouble *v);
+typedef void (APIENTRYP PFNGLPROGRAMPARAMETERS4FVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLfloat *v);
+typedef void (APIENTRYP PFNGLREQUESTRESIDENTPROGRAMSNVPROC) (GLsizei n, const GLuint *programs);
+typedef void (APIENTRYP PFNGLTRACKMATRIXNVPROC) (GLenum target, GLuint address, GLenum matrix, GLenum transform);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERNVPROC) (GLuint index, GLint fsize, GLenum type, GLsizei stride, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1DNVPROC) (GLuint index, GLdouble x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1DVNVPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1FNVPROC) (GLuint index, GLfloat x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1FVNVPROC) (GLuint index, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1SNVPROC) (GLuint index, GLshort x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1SVNVPROC) (GLuint index, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2DNVPROC) (GLuint index, GLdouble x, GLdouble y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2DVNVPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2FNVPROC) (GLuint index, GLfloat x, GLfloat y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2FVNVPROC) (GLuint index, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2SNVPROC) (GLuint index, GLshort x, GLshort y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2SVNVPROC) (GLuint index, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3DNVPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3DVNVPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3FNVPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3FVNVPROC) (GLuint index, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3SNVPROC) (GLuint index, GLshort x, GLshort y, GLshort z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3SVNVPROC) (GLuint index, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4DNVPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4DVNVPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4FNVPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4FVNVPROC) (GLuint index, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4SNVPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4SVNVPROC) (GLuint index, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBNVPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBVNVPROC) (GLuint index, const GLubyte *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS1DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS1FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS1SVNVPROC) (GLuint index, GLsizei count, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS2DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS2FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS2SVNVPROC) (GLuint index, GLsizei count, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS3DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS3FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS3SVNVPROC) (GLuint index, GLsizei count, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS4DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS4FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS4SVNVPROC) (GLuint index, GLsizei count, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS4UBVNVPROC) (GLuint index, GLsizei count, const GLubyte *v);
+#endif
+
+#ifndef GL_SGIX_texture_coordinate_clamp
+#define GL_SGIX_texture_coordinate_clamp 1
+#endif
+
+#ifndef GL_SGIX_scalebias_hint
+#define GL_SGIX_scalebias_hint 1
+#endif
+
+#ifndef GL_OML_interlace
+#define GL_OML_interlace 1
+#endif
+
+#ifndef GL_OML_subsample
+#define GL_OML_subsample 1
+#endif
+
+#ifndef GL_OML_resample
+#define GL_OML_resample 1
+#endif
+
+#ifndef GL_NV_copy_depth_to_color
+#define GL_NV_copy_depth_to_color 1
+#endif
+
+#ifndef GL_ATI_envmap_bumpmap
+#define GL_ATI_envmap_bumpmap 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTexBumpParameterivATI (GLenum pname, const GLint *param);
+GLAPI void APIENTRY glTexBumpParameterfvATI (GLenum pname, const GLfloat *param);
+GLAPI void APIENTRY glGetTexBumpParameterivATI (GLenum pname, GLint *param);
+GLAPI void APIENTRY glGetTexBumpParameterfvATI (GLenum pname, GLfloat *param);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLTEXBUMPPARAMETERIVATIPROC) (GLenum pname, const GLint *param);
+typedef void (APIENTRYP PFNGLTEXBUMPPARAMETERFVATIPROC) (GLenum pname, const GLfloat *param);
+typedef void (APIENTRYP PFNGLGETTEXBUMPPARAMETERIVATIPROC) (GLenum pname, GLint *param);
+typedef void (APIENTRYP PFNGLGETTEXBUMPPARAMETERFVATIPROC) (GLenum pname, GLfloat *param);
+#endif
+
+#ifndef GL_ATI_fragment_shader
+#define GL_ATI_fragment_shader 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI GLuint APIENTRY glGenFragmentShadersATI (GLuint range);
+GLAPI void APIENTRY glBindFragmentShaderATI (GLuint id);
+GLAPI void APIENTRY glDeleteFragmentShaderATI (GLuint id);
+GLAPI void APIENTRY glBeginFragmentShaderATI (void);
+GLAPI void APIENTRY glEndFragmentShaderATI (void);
+GLAPI void APIENTRY glPassTexCoordATI (GLuint dst, GLuint coord, GLenum swizzle);
+GLAPI void APIENTRY glSampleMapATI (GLuint dst, GLuint interp, GLenum swizzle);
+GLAPI void APIENTRY glColorFragmentOp1ATI (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod);
+GLAPI void APIENTRY glColorFragmentOp2ATI (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod);
+GLAPI void APIENTRY glColorFragmentOp3ATI (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod);
+GLAPI void APIENTRY glAlphaFragmentOp1ATI (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod);
+GLAPI void APIENTRY glAlphaFragmentOp2ATI (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod);
+GLAPI void APIENTRY glAlphaFragmentOp3ATI (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod);
+GLAPI void APIENTRY glSetFragmentShaderConstantATI (GLuint dst, const GLfloat *value);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef GLuint (APIENTRYP PFNGLGENFRAGMENTSHADERSATIPROC) (GLuint range);
+typedef void (APIENTRYP PFNGLBINDFRAGMENTSHADERATIPROC) (GLuint id);
+typedef void (APIENTRYP PFNGLDELETEFRAGMENTSHADERATIPROC) (GLuint id);
+typedef void (APIENTRYP PFNGLBEGINFRAGMENTSHADERATIPROC) (void);
+typedef void (APIENTRYP PFNGLENDFRAGMENTSHADERATIPROC) (void);
+typedef void (APIENTRYP PFNGLPASSTEXCOORDATIPROC) (GLuint dst, GLuint coord, GLenum swizzle);
+typedef void (APIENTRYP PFNGLSAMPLEMAPATIPROC) (GLuint dst, GLuint interp, GLenum swizzle);
+typedef void (APIENTRYP PFNGLCOLORFRAGMENTOP1ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod);
+typedef void (APIENTRYP PFNGLCOLORFRAGMENTOP2ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod);
+typedef void (APIENTRYP PFNGLCOLORFRAGMENTOP3ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod);
+typedef void (APIENTRYP PFNGLALPHAFRAGMENTOP1ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod);
+typedef void (APIENTRYP PFNGLALPHAFRAGMENTOP2ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod);
+typedef void (APIENTRYP PFNGLALPHAFRAGMENTOP3ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod);
+typedef void (APIENTRYP PFNGLSETFRAGMENTSHADERCONSTANTATIPROC) (GLuint dst, const GLfloat *value);
+#endif
+
+#ifndef GL_ATI_pn_triangles
+#define GL_ATI_pn_triangles 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glPNTrianglesiATI (GLenum pname, GLint param);
+GLAPI void APIENTRY glPNTrianglesfATI (GLenum pname, GLfloat param);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPNTRIANGLESIATIPROC) (GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLPNTRIANGLESFATIPROC) (GLenum pname, GLfloat param);
+#endif
+
+#ifndef GL_ATI_vertex_array_object
+#define GL_ATI_vertex_array_object 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI GLuint APIENTRY glNewObjectBufferATI (GLsizei size, const GLvoid *pointer, GLenum usage);
+GLAPI GLboolean APIENTRY glIsObjectBufferATI (GLuint buffer);
+GLAPI void APIENTRY glUpdateObjectBufferATI (GLuint buffer, GLuint offset, GLsizei size, const GLvoid *pointer, GLenum preserve);
+GLAPI void APIENTRY glGetObjectBufferfvATI (GLuint buffer, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetObjectBufferivATI (GLuint buffer, GLenum pname, GLint *params);
+GLAPI void APIENTRY glFreeObjectBufferATI (GLuint buffer);
+GLAPI void APIENTRY glArrayObjectATI (GLenum array, GLint size, GLenum type, GLsizei stride, GLuint buffer, GLuint offset);
+GLAPI void APIENTRY glGetArrayObjectfvATI (GLenum array, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetArrayObjectivATI (GLenum array, GLenum pname, GLint *params);
+GLAPI void APIENTRY glVariantArrayObjectATI (GLuint id, GLenum type, GLsizei stride, GLuint buffer, GLuint offset);
+GLAPI void APIENTRY glGetVariantArrayObjectfvATI (GLuint id, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetVariantArrayObjectivATI (GLuint id, GLenum pname, GLint *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef GLuint (APIENTRYP PFNGLNEWOBJECTBUFFERATIPROC) (GLsizei size, const GLvoid *pointer, GLenum usage);
+typedef GLboolean (APIENTRYP PFNGLISOBJECTBUFFERATIPROC) (GLuint buffer);
+typedef void (APIENTRYP PFNGLUPDATEOBJECTBUFFERATIPROC) (GLuint buffer, GLuint offset, GLsizei size, const GLvoid *pointer, GLenum preserve);
+typedef void (APIENTRYP PFNGLGETOBJECTBUFFERFVATIPROC) (GLuint buffer, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETOBJECTBUFFERIVATIPROC) (GLuint buffer, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLFREEOBJECTBUFFERATIPROC) (GLuint buffer);
+typedef void (APIENTRYP PFNGLARRAYOBJECTATIPROC) (GLenum array, GLint size, GLenum type, GLsizei stride, GLuint buffer, GLuint offset);
+typedef void (APIENTRYP PFNGLGETARRAYOBJECTFVATIPROC) (GLenum array, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETARRAYOBJECTIVATIPROC) (GLenum array, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLVARIANTARRAYOBJECTATIPROC) (GLuint id, GLenum type, GLsizei stride, GLuint buffer, GLuint offset);
+typedef void (APIENTRYP PFNGLGETVARIANTARRAYOBJECTFVATIPROC) (GLuint id, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETVARIANTARRAYOBJECTIVATIPROC) (GLuint id, GLenum pname, GLint *params);
+#endif
+
+#ifndef GL_EXT_vertex_shader
+#define GL_EXT_vertex_shader 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBeginVertexShaderEXT (void);
+GLAPI void APIENTRY glEndVertexShaderEXT (void);
+GLAPI void APIENTRY glBindVertexShaderEXT (GLuint id);
+GLAPI GLuint APIENTRY glGenVertexShadersEXT (GLuint range);
+GLAPI void APIENTRY glDeleteVertexShaderEXT (GLuint id);
+GLAPI void APIENTRY glShaderOp1EXT (GLenum op, GLuint res, GLuint arg1);
+GLAPI void APIENTRY glShaderOp2EXT (GLenum op, GLuint res, GLuint arg1, GLuint arg2);
+GLAPI void APIENTRY glShaderOp3EXT (GLenum op, GLuint res, GLuint arg1, GLuint arg2, GLuint arg3);
+GLAPI void APIENTRY glSwizzleEXT (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW);
+GLAPI void APIENTRY glWriteMaskEXT (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW);
+GLAPI void APIENTRY glInsertComponentEXT (GLuint res, GLuint src, GLuint num);
+GLAPI void APIENTRY glExtractComponentEXT (GLuint res, GLuint src, GLuint num);
+GLAPI GLuint APIENTRY glGenSymbolsEXT (GLenum datatype, GLenum storagetype, GLenum range, GLuint components);
+GLAPI void APIENTRY glSetInvariantEXT (GLuint id, GLenum type, const GLvoid *addr);
+GLAPI void APIENTRY glSetLocalConstantEXT (GLuint id, GLenum type, const GLvoid *addr);
+GLAPI void APIENTRY glVariantbvEXT (GLuint id, const GLbyte *addr);
+GLAPI void APIENTRY glVariantsvEXT (GLuint id, const GLshort *addr);
+GLAPI void APIENTRY glVariantivEXT (GLuint id, const GLint *addr);
+GLAPI void APIENTRY glVariantfvEXT (GLuint id, const GLfloat *addr);
+GLAPI void APIENTRY glVariantdvEXT (GLuint id, const GLdouble *addr);
+GLAPI void APIENTRY glVariantubvEXT (GLuint id, const GLubyte *addr);
+GLAPI void APIENTRY glVariantusvEXT (GLuint id, const GLushort *addr);
+GLAPI void APIENTRY glVariantuivEXT (GLuint id, const GLuint *addr);
+GLAPI void APIENTRY glVariantPointerEXT (GLuint id, GLenum type, GLuint stride, const GLvoid *addr);
+GLAPI void APIENTRY glEnableVariantClientStateEXT (GLuint id);
+GLAPI void APIENTRY glDisableVariantClientStateEXT (GLuint id);
+GLAPI GLuint APIENTRY glBindLightParameterEXT (GLenum light, GLenum value);
+GLAPI GLuint APIENTRY glBindMaterialParameterEXT (GLenum face, GLenum value);
+GLAPI GLuint APIENTRY glBindTexGenParameterEXT (GLenum unit, GLenum coord, GLenum value);
+GLAPI GLuint APIENTRY glBindTextureUnitParameterEXT (GLenum unit, GLenum value);
+GLAPI GLuint APIENTRY glBindParameterEXT (GLenum value);
+GLAPI GLboolean APIENTRY glIsVariantEnabledEXT (GLuint id, GLenum cap);
+GLAPI void APIENTRY glGetVariantBooleanvEXT (GLuint id, GLenum value, GLboolean *data);
+GLAPI void APIENTRY glGetVariantIntegervEXT (GLuint id, GLenum value, GLint *data);
+GLAPI void APIENTRY glGetVariantFloatvEXT (GLuint id, GLenum value, GLfloat *data);
+GLAPI void APIENTRY glGetVariantPointervEXT (GLuint id, GLenum value, GLvoid* *data);
+GLAPI void APIENTRY glGetInvariantBooleanvEXT (GLuint id, GLenum value, GLboolean *data);
+GLAPI void APIENTRY glGetInvariantIntegervEXT (GLuint id, GLenum value, GLint *data);
+GLAPI void APIENTRY glGetInvariantFloatvEXT (GLuint id, GLenum value, GLfloat *data);
+GLAPI void APIENTRY glGetLocalConstantBooleanvEXT (GLuint id, GLenum value, GLboolean *data);
+GLAPI void APIENTRY glGetLocalConstantIntegervEXT (GLuint id, GLenum value, GLint *data);
+GLAPI void APIENTRY glGetLocalConstantFloatvEXT (GLuint id, GLenum value, GLfloat *data);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBEGINVERTEXSHADEREXTPROC) (void);
+typedef void (APIENTRYP PFNGLENDVERTEXSHADEREXTPROC) (void);
+typedef void (APIENTRYP PFNGLBINDVERTEXSHADEREXTPROC) (GLuint id);
+typedef GLuint (APIENTRYP PFNGLGENVERTEXSHADERSEXTPROC) (GLuint range);
+typedef void (APIENTRYP PFNGLDELETEVERTEXSHADEREXTPROC) (GLuint id);
+typedef void (APIENTRYP PFNGLSHADEROP1EXTPROC) (GLenum op, GLuint res, GLuint arg1);
+typedef void (APIENTRYP PFNGLSHADEROP2EXTPROC) (GLenum op, GLuint res, GLuint arg1, GLuint arg2);
+typedef void (APIENTRYP PFNGLSHADEROP3EXTPROC) (GLenum op, GLuint res, GLuint arg1, GLuint arg2, GLuint arg3);
+typedef void (APIENTRYP PFNGLSWIZZLEEXTPROC) (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW);
+typedef void (APIENTRYP PFNGLWRITEMASKEXTPROC) (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW);
+typedef void (APIENTRYP PFNGLINSERTCOMPONENTEXTPROC) (GLuint res, GLuint src, GLuint num);
+typedef void (APIENTRYP PFNGLEXTRACTCOMPONENTEXTPROC) (GLuint res, GLuint src, GLuint num);
+typedef GLuint (APIENTRYP PFNGLGENSYMBOLSEXTPROC) (GLenum datatype, GLenum storagetype, GLenum range, GLuint components);
+typedef void (APIENTRYP PFNGLSETINVARIANTEXTPROC) (GLuint id, GLenum type, const GLvoid *addr);
+typedef void (APIENTRYP PFNGLSETLOCALCONSTANTEXTPROC) (GLuint id, GLenum type, const GLvoid *addr);
+typedef void (APIENTRYP PFNGLVARIANTBVEXTPROC) (GLuint id, const GLbyte *addr);
+typedef void (APIENTRYP PFNGLVARIANTSVEXTPROC) (GLuint id, const GLshort *addr);
+typedef void (APIENTRYP PFNGLVARIANTIVEXTPROC) (GLuint id, const GLint *addr);
+typedef void (APIENTRYP PFNGLVARIANTFVEXTPROC) (GLuint id, const GLfloat *addr);
+typedef void (APIENTRYP PFNGLVARIANTDVEXTPROC) (GLuint id, const GLdouble *addr);
+typedef void (APIENTRYP PFNGLVARIANTUBVEXTPROC) (GLuint id, const GLubyte *addr);
+typedef void (APIENTRYP PFNGLVARIANTUSVEXTPROC) (GLuint id, const GLushort *addr);
+typedef void (APIENTRYP PFNGLVARIANTUIVEXTPROC) (GLuint id, const GLuint *addr);
+typedef void (APIENTRYP PFNGLVARIANTPOINTEREXTPROC) (GLuint id, GLenum type, GLuint stride, const GLvoid *addr);
+typedef void (APIENTRYP PFNGLENABLEVARIANTCLIENTSTATEEXTPROC) (GLuint id);
+typedef void (APIENTRYP PFNGLDISABLEVARIANTCLIENTSTATEEXTPROC) (GLuint id);
+typedef GLuint (APIENTRYP PFNGLBINDLIGHTPARAMETEREXTPROC) (GLenum light, GLenum value);
+typedef GLuint (APIENTRYP PFNGLBINDMATERIALPARAMETEREXTPROC) (GLenum face, GLenum value);
+typedef GLuint (APIENTRYP PFNGLBINDTEXGENPARAMETEREXTPROC) (GLenum unit, GLenum coord, GLenum value);
+typedef GLuint (APIENTRYP PFNGLBINDTEXTUREUNITPARAMETEREXTPROC) (GLenum unit, GLenum value);
+typedef GLuint (APIENTRYP PFNGLBINDPARAMETEREXTPROC) (GLenum value);
+typedef GLboolean (APIENTRYP PFNGLISVARIANTENABLEDEXTPROC) (GLuint id, GLenum cap);
+typedef void (APIENTRYP PFNGLGETVARIANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data);
+typedef void (APIENTRYP PFNGLGETVARIANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data);
+typedef void (APIENTRYP PFNGLGETVARIANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data);
+typedef void (APIENTRYP PFNGLGETVARIANTPOINTERVEXTPROC) (GLuint id, GLenum value, GLvoid* *data);
+typedef void (APIENTRYP PFNGLGETINVARIANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data);
+typedef void (APIENTRYP PFNGLGETINVARIANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data);
+typedef void (APIENTRYP PFNGLGETINVARIANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data);
+typedef void (APIENTRYP PFNGLGETLOCALCONSTANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data);
+typedef void (APIENTRYP PFNGLGETLOCALCONSTANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data);
+typedef void (APIENTRYP PFNGLGETLOCALCONSTANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data);
+#endif
+
+#ifndef GL_ATI_vertex_streams
+#define GL_ATI_vertex_streams 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glVertexStream1sATI (GLenum stream, GLshort x);
+GLAPI void APIENTRY glVertexStream1svATI (GLenum stream, const GLshort *coords);
+GLAPI void APIENTRY glVertexStream1iATI (GLenum stream, GLint x);
+GLAPI void APIENTRY glVertexStream1ivATI (GLenum stream, const GLint *coords);
+GLAPI void APIENTRY glVertexStream1fATI (GLenum stream, GLfloat x);
+GLAPI void APIENTRY glVertexStream1fvATI (GLenum stream, const GLfloat *coords);
+GLAPI void APIENTRY glVertexStream1dATI (GLenum stream, GLdouble x);
+GLAPI void APIENTRY glVertexStream1dvATI (GLenum stream, const GLdouble *coords);
+GLAPI void APIENTRY glVertexStream2sATI (GLenum stream, GLshort x, GLshort y);
+GLAPI void APIENTRY glVertexStream2svATI (GLenum stream, const GLshort *coords);
+GLAPI void APIENTRY glVertexStream2iATI (GLenum stream, GLint x, GLint y);
+GLAPI void APIENTRY glVertexStream2ivATI (GLenum stream, const GLint *coords);
+GLAPI void APIENTRY glVertexStream2fATI (GLenum stream, GLfloat x, GLfloat y);
+GLAPI void APIENTRY glVertexStream2fvATI (GLenum stream, const GLfloat *coords);
+GLAPI void APIENTRY glVertexStream2dATI (GLenum stream, GLdouble x, GLdouble y);
+GLAPI void APIENTRY glVertexStream2dvATI (GLenum stream, const GLdouble *coords);
+GLAPI void APIENTRY glVertexStream3sATI (GLenum stream, GLshort x, GLshort y, GLshort z);
+GLAPI void APIENTRY glVertexStream3svATI (GLenum stream, const GLshort *coords);
+GLAPI void APIENTRY glVertexStream3iATI (GLenum stream, GLint x, GLint y, GLint z);
+GLAPI void APIENTRY glVertexStream3ivATI (GLenum stream, const GLint *coords);
+GLAPI void APIENTRY glVertexStream3fATI (GLenum stream, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glVertexStream3fvATI (GLenum stream, const GLfloat *coords);
+GLAPI void APIENTRY glVertexStream3dATI (GLenum stream, GLdouble x, GLdouble y, GLdouble z);
+GLAPI void APIENTRY glVertexStream3dvATI (GLenum stream, const GLdouble *coords);
+GLAPI void APIENTRY glVertexStream4sATI (GLenum stream, GLshort x, GLshort y, GLshort z, GLshort w);
+GLAPI void APIENTRY glVertexStream4svATI (GLenum stream, const GLshort *coords);
+GLAPI void APIENTRY glVertexStream4iATI (GLenum stream, GLint x, GLint y, GLint z, GLint w);
+GLAPI void APIENTRY glVertexStream4ivATI (GLenum stream, const GLint *coords);
+GLAPI void APIENTRY glVertexStream4fATI (GLenum stream, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+GLAPI void APIENTRY glVertexStream4fvATI (GLenum stream, const GLfloat *coords);
+GLAPI void APIENTRY glVertexStream4dATI (GLenum stream, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+GLAPI void APIENTRY glVertexStream4dvATI (GLenum stream, const GLdouble *coords);
+GLAPI void APIENTRY glNormalStream3bATI (GLenum stream, GLbyte nx, GLbyte ny, GLbyte nz);
+GLAPI void APIENTRY glNormalStream3bvATI (GLenum stream, const GLbyte *coords);
+GLAPI void APIENTRY glNormalStream3sATI (GLenum stream, GLshort nx, GLshort ny, GLshort nz);
+GLAPI void APIENTRY glNormalStream3svATI (GLenum stream, const GLshort *coords);
+GLAPI void APIENTRY glNormalStream3iATI (GLenum stream, GLint nx, GLint ny, GLint nz);
+GLAPI void APIENTRY glNormalStream3ivATI (GLenum stream, const GLint *coords);
+GLAPI void APIENTRY glNormalStream3fATI (GLenum stream, GLfloat nx, GLfloat ny, GLfloat nz);
+GLAPI void APIENTRY glNormalStream3fvATI (GLenum stream, const GLfloat *coords);
+GLAPI void APIENTRY glNormalStream3dATI (GLenum stream, GLdouble nx, GLdouble ny, GLdouble nz);
+GLAPI void APIENTRY glNormalStream3dvATI (GLenum stream, const GLdouble *coords);
+GLAPI void APIENTRY glClientActiveVertexStreamATI (GLenum stream);
+GLAPI void APIENTRY glVertexBlendEnviATI (GLenum pname, GLint param);
+GLAPI void APIENTRY glVertexBlendEnvfATI (GLenum pname, GLfloat param);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLVERTEXSTREAM1SATIPROC) (GLenum stream, GLshort x);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM1SVATIPROC) (GLenum stream, const GLshort *coords);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM1IATIPROC) (GLenum stream, GLint x);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM1IVATIPROC) (GLenum stream, const GLint *coords);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM1FATIPROC) (GLenum stream, GLfloat x);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM1FVATIPROC) (GLenum stream, const GLfloat *coords);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM1DATIPROC) (GLenum stream, GLdouble x);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM1DVATIPROC) (GLenum stream, const GLdouble *coords);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM2SATIPROC) (GLenum stream, GLshort x, GLshort y);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM2SVATIPROC) (GLenum stream, const GLshort *coords);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM2IATIPROC) (GLenum stream, GLint x, GLint y);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM2IVATIPROC) (GLenum stream, const GLint *coords);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM2FATIPROC) (GLenum stream, GLfloat x, GLfloat y);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM2FVATIPROC) (GLenum stream, const GLfloat *coords);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM2DATIPROC) (GLenum stream, GLdouble x, GLdouble y);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM2DVATIPROC) (GLenum stream, const GLdouble *coords);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM3SATIPROC) (GLenum stream, GLshort x, GLshort y, GLshort z);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM3SVATIPROC) (GLenum stream, const GLshort *coords);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM3IATIPROC) (GLenum stream, GLint x, GLint y, GLint z);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM3IVATIPROC) (GLenum stream, const GLint *coords);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM3FATIPROC) (GLenum stream, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM3FVATIPROC) (GLenum stream, const GLfloat *coords);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM3DATIPROC) (GLenum stream, GLdouble x, GLdouble y, GLdouble z);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM3DVATIPROC) (GLenum stream, const GLdouble *coords);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM4SATIPROC) (GLenum stream, GLshort x, GLshort y, GLshort z, GLshort w);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM4SVATIPROC) (GLenum stream, const GLshort *coords);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM4IATIPROC) (GLenum stream, GLint x, GLint y, GLint z, GLint w);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM4IVATIPROC) (GLenum stream, const GLint *coords);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM4FATIPROC) (GLenum stream, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM4FVATIPROC) (GLenum stream, const GLfloat *coords);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM4DATIPROC) (GLenum stream, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM4DVATIPROC) (GLenum stream, const GLdouble *coords);
+typedef void (APIENTRYP PFNGLNORMALSTREAM3BATIPROC) (GLenum stream, GLbyte nx, GLbyte ny, GLbyte nz);
+typedef void (APIENTRYP PFNGLNORMALSTREAM3BVATIPROC) (GLenum stream, const GLbyte *coords);
+typedef void (APIENTRYP PFNGLNORMALSTREAM3SATIPROC) (GLenum stream, GLshort nx, GLshort ny, GLshort nz);
+typedef void (APIENTRYP PFNGLNORMALSTREAM3SVATIPROC) (GLenum stream, const GLshort *coords);
+typedef void (APIENTRYP PFNGLNORMALSTREAM3IATIPROC) (GLenum stream, GLint nx, GLint ny, GLint nz);
+typedef void (APIENTRYP PFNGLNORMALSTREAM3IVATIPROC) (GLenum stream, const GLint *coords);
+typedef void (APIENTRYP PFNGLNORMALSTREAM3FATIPROC) (GLenum stream, GLfloat nx, GLfloat ny, GLfloat nz);
+typedef void (APIENTRYP PFNGLNORMALSTREAM3FVATIPROC) (GLenum stream, const GLfloat *coords);
+typedef void (APIENTRYP PFNGLNORMALSTREAM3DATIPROC) (GLenum stream, GLdouble nx, GLdouble ny, GLdouble nz);
+typedef void (APIENTRYP PFNGLNORMALSTREAM3DVATIPROC) (GLenum stream, const GLdouble *coords);
+typedef void (APIENTRYP PFNGLCLIENTACTIVEVERTEXSTREAMATIPROC) (GLenum stream);
+typedef void (APIENTRYP PFNGLVERTEXBLENDENVIATIPROC) (GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLVERTEXBLENDENVFATIPROC) (GLenum pname, GLfloat param);
+#endif
+
+#ifndef GL_ATI_element_array
+#define GL_ATI_element_array 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glElementPointerATI (GLenum type, const GLvoid *pointer);
+GLAPI void APIENTRY glDrawElementArrayATI (GLenum mode, GLsizei count);
+GLAPI void APIENTRY glDrawRangeElementArrayATI (GLenum mode, GLuint start, GLuint end, GLsizei count);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLELEMENTPOINTERATIPROC) (GLenum type, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLDRAWELEMENTARRAYATIPROC) (GLenum mode, GLsizei count);
+typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTARRAYATIPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count);
+#endif
+
+#ifndef GL_SUN_mesh_array
+#define GL_SUN_mesh_array 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDrawMeshArraysSUN (GLenum mode, GLint first, GLsizei count, GLsizei width);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLDRAWMESHARRAYSSUNPROC) (GLenum mode, GLint first, GLsizei count, GLsizei width);
+#endif
+
+#ifndef GL_SUN_slice_accum
+#define GL_SUN_slice_accum 1
+#endif
+
+#ifndef GL_NV_multisample_filter_hint
+#define GL_NV_multisample_filter_hint 1
+#endif
+
+#ifndef GL_NV_depth_clamp
+#define GL_NV_depth_clamp 1
+#endif
+
+#ifndef GL_NV_occlusion_query
+#define GL_NV_occlusion_query 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGenOcclusionQueriesNV (GLsizei n, GLuint *ids);
+GLAPI void APIENTRY glDeleteOcclusionQueriesNV (GLsizei n, const GLuint *ids);
+GLAPI GLboolean APIENTRY glIsOcclusionQueryNV (GLuint id);
+GLAPI void APIENTRY glBeginOcclusionQueryNV (GLuint id);
+GLAPI void APIENTRY glEndOcclusionQueryNV (void);
+GLAPI void APIENTRY glGetOcclusionQueryivNV (GLuint id, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetOcclusionQueryuivNV (GLuint id, GLenum pname, GLuint *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLGENOCCLUSIONQUERIESNVPROC) (GLsizei n, GLuint *ids);
+typedef void (APIENTRYP PFNGLDELETEOCCLUSIONQUERIESNVPROC) (GLsizei n, const GLuint *ids);
+typedef GLboolean (APIENTRYP PFNGLISOCCLUSIONQUERYNVPROC) (GLuint id);
+typedef void (APIENTRYP PFNGLBEGINOCCLUSIONQUERYNVPROC) (GLuint id);
+typedef void (APIENTRYP PFNGLENDOCCLUSIONQUERYNVPROC) (void);
+typedef void (APIENTRYP PFNGLGETOCCLUSIONQUERYIVNVPROC) (GLuint id, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETOCCLUSIONQUERYUIVNVPROC) (GLuint id, GLenum pname, GLuint *params);
+#endif
+
+#ifndef GL_NV_point_sprite
+#define GL_NV_point_sprite 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glPointParameteriNV (GLenum pname, GLint param);
+GLAPI void APIENTRY glPointParameterivNV (GLenum pname, const GLint *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPOINTPARAMETERINVPROC) (GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLPOINTPARAMETERIVNVPROC) (GLenum pname, const GLint *params);
+#endif
+
+#ifndef GL_NV_texture_shader3
+#define GL_NV_texture_shader3 1
+#endif
+
+#ifndef GL_NV_vertex_program1_1
+#define GL_NV_vertex_program1_1 1
+#endif
+
+#ifndef GL_EXT_shadow_funcs
+#define GL_EXT_shadow_funcs 1
+#endif
+
+#ifndef GL_EXT_stencil_two_side
+#define GL_EXT_stencil_two_side 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glActiveStencilFaceEXT (GLenum face);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLACTIVESTENCILFACEEXTPROC) (GLenum face);
+#endif
+
+#ifndef GL_ATI_text_fragment_shader
+#define GL_ATI_text_fragment_shader 1
+#endif
+
+#ifndef GL_APPLE_client_storage
+#define GL_APPLE_client_storage 1
+#endif
+
+#ifndef GL_APPLE_element_array
+#define GL_APPLE_element_array 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glElementPointerAPPLE (GLenum type, const GLvoid *pointer);
+GLAPI void APIENTRY glDrawElementArrayAPPLE (GLenum mode, GLint first, GLsizei count);
+GLAPI void APIENTRY glDrawRangeElementArrayAPPLE (GLenum mode, GLuint start, GLuint end, GLint first, GLsizei count);
+GLAPI void APIENTRY glMultiDrawElementArrayAPPLE (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount);
+GLAPI void APIENTRY glMultiDrawRangeElementArrayAPPLE (GLenum mode, GLuint start, GLuint end, const GLint *first, const GLsizei *count, GLsizei primcount);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLELEMENTPOINTERAPPLEPROC) (GLenum type, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLDRAWELEMENTARRAYAPPLEPROC) (GLenum mode, GLint first, GLsizei count);
+typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTARRAYAPPLEPROC) (GLenum mode, GLuint start, GLuint end, GLint first, GLsizei count);
+typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTARRAYAPPLEPROC) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount);
+typedef void (APIENTRYP PFNGLMULTIDRAWRANGEELEMENTARRAYAPPLEPROC) (GLenum mode, GLuint start, GLuint end, const GLint *first, const GLsizei *count, GLsizei primcount);
+#endif
+
+#ifndef GL_APPLE_fence
+#define GL_APPLE_fence 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGenFencesAPPLE (GLsizei n, GLuint *fences);
+GLAPI void APIENTRY glDeleteFencesAPPLE (GLsizei n, const GLuint *fences);
+GLAPI void APIENTRY glSetFenceAPPLE (GLuint fence);
+GLAPI GLboolean APIENTRY glIsFenceAPPLE (GLuint fence);
+GLAPI GLboolean APIENTRY glTestFenceAPPLE (GLuint fence);
+GLAPI void APIENTRY glFinishFenceAPPLE (GLuint fence);
+GLAPI GLboolean APIENTRY glTestObjectAPPLE (GLenum object, GLuint name);
+GLAPI void APIENTRY glFinishObjectAPPLE (GLenum object, GLint name);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLGENFENCESAPPLEPROC) (GLsizei n, GLuint *fences);
+typedef void (APIENTRYP PFNGLDELETEFENCESAPPLEPROC) (GLsizei n, const GLuint *fences);
+typedef void (APIENTRYP PFNGLSETFENCEAPPLEPROC) (GLuint fence);
+typedef GLboolean (APIENTRYP PFNGLISFENCEAPPLEPROC) (GLuint fence);
+typedef GLboolean (APIENTRYP PFNGLTESTFENCEAPPLEPROC) (GLuint fence);
+typedef void (APIENTRYP PFNGLFINISHFENCEAPPLEPROC) (GLuint fence);
+typedef GLboolean (APIENTRYP PFNGLTESTOBJECTAPPLEPROC) (GLenum object, GLuint name);
+typedef void (APIENTRYP PFNGLFINISHOBJECTAPPLEPROC) (GLenum object, GLint name);
+#endif
+
+#ifndef GL_APPLE_vertex_array_object
+#define GL_APPLE_vertex_array_object 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBindVertexArrayAPPLE (GLuint array);
+GLAPI void APIENTRY glDeleteVertexArraysAPPLE (GLsizei n, const GLuint *arrays);
+GLAPI void APIENTRY glGenVertexArraysAPPLE (GLsizei n, GLuint *arrays);
+GLAPI GLboolean APIENTRY glIsVertexArrayAPPLE (GLuint array);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBINDVERTEXARRAYAPPLEPROC) (GLuint array);
+typedef void (APIENTRYP PFNGLDELETEVERTEXARRAYSAPPLEPROC) (GLsizei n, const GLuint *arrays);
+typedef void (APIENTRYP PFNGLGENVERTEXARRAYSAPPLEPROC) (GLsizei n, GLuint *arrays);
+typedef GLboolean (APIENTRYP PFNGLISVERTEXARRAYAPPLEPROC) (GLuint array);
+#endif
+
+#ifndef GL_APPLE_vertex_array_range
+#define GL_APPLE_vertex_array_range 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glVertexArrayRangeAPPLE (GLsizei length, GLvoid *pointer);
+GLAPI void APIENTRY glFlushVertexArrayRangeAPPLE (GLsizei length, GLvoid *pointer);
+GLAPI void APIENTRY glVertexArrayParameteriAPPLE (GLenum pname, GLint param);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLVERTEXARRAYRANGEAPPLEPROC) (GLsizei length, GLvoid *pointer);
+typedef void (APIENTRYP PFNGLFLUSHVERTEXARRAYRANGEAPPLEPROC) (GLsizei length, GLvoid *pointer);
+typedef void (APIENTRYP PFNGLVERTEXARRAYPARAMETERIAPPLEPROC) (GLenum pname, GLint param);
+#endif
+
+#ifndef GL_APPLE_ycbcr_422
+#define GL_APPLE_ycbcr_422 1
+#endif
+
+#ifndef GL_S3_s3tc
+#define GL_S3_s3tc 1
+#endif
+
+#ifndef GL_ATI_draw_buffers
+#define GL_ATI_draw_buffers 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDrawBuffersATI (GLsizei n, const GLenum *bufs);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLDRAWBUFFERSATIPROC) (GLsizei n, const GLenum *bufs);
+#endif
+
+#ifndef GL_ATI_pixel_format_float
+#define GL_ATI_pixel_format_float 1
+/* This is really a WGL extension, but defines some associated GL enums.
+ * ATI does not export "GL_ATI_pixel_format_float" in the GL_EXTENSIONS string.
+ */
+#endif
+
+#ifndef GL_ATI_texture_env_combine3
+#define GL_ATI_texture_env_combine3 1
+#endif
+
+#ifndef GL_ATI_texture_float
+#define GL_ATI_texture_float 1
+#endif
+
+#ifndef GL_NV_float_buffer
+#define GL_NV_float_buffer 1
+#endif
+
+#ifndef GL_NV_fragment_program
+#define GL_NV_fragment_program 1
+/* Some NV_fragment_program entry points are shared with ARB_vertex_program. */
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glProgramNamedParameter4fNV (GLuint id, GLsizei len, const GLubyte *name, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+GLAPI void APIENTRY glProgramNamedParameter4dNV (GLuint id, GLsizei len, const GLubyte *name, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+GLAPI void APIENTRY glProgramNamedParameter4fvNV (GLuint id, GLsizei len, const GLubyte *name, const GLfloat *v);
+GLAPI void APIENTRY glProgramNamedParameter4dvNV (GLuint id, GLsizei len, const GLubyte *name, const GLdouble *v);
+GLAPI void APIENTRY glGetProgramNamedParameterfvNV (GLuint id, GLsizei len, const GLubyte *name, GLfloat *params);
+GLAPI void APIENTRY glGetProgramNamedParameterdvNV (GLuint id, GLsizei len, const GLubyte *name, GLdouble *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPROGRAMNAMEDPARAMETER4FNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (APIENTRYP PFNGLPROGRAMNAMEDPARAMETER4DNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (APIENTRYP PFNGLPROGRAMNAMEDPARAMETER4FVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, const GLfloat *v);
+typedef void (APIENTRYP PFNGLPROGRAMNAMEDPARAMETER4DVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, const GLdouble *v);
+typedef void (APIENTRYP PFNGLGETPROGRAMNAMEDPARAMETERFVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETPROGRAMNAMEDPARAMETERDVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLdouble *params);
+#endif
+
+#ifndef GL_NV_half_float
+#define GL_NV_half_float 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glVertex2hNV (GLhalfNV x, GLhalfNV y);
+GLAPI void APIENTRY glVertex2hvNV (const GLhalfNV *v);
+GLAPI void APIENTRY glVertex3hNV (GLhalfNV x, GLhalfNV y, GLhalfNV z);
+GLAPI void APIENTRY glVertex3hvNV (const GLhalfNV *v);
+GLAPI void APIENTRY glVertex4hNV (GLhalfNV x, GLhalfNV y, GLhalfNV z, GLhalfNV w);
+GLAPI void APIENTRY glVertex4hvNV (const GLhalfNV *v);
+GLAPI void APIENTRY glNormal3hNV (GLhalfNV nx, GLhalfNV ny, GLhalfNV nz);
+GLAPI void APIENTRY glNormal3hvNV (const GLhalfNV *v);
+GLAPI void APIENTRY glColor3hNV (GLhalfNV red, GLhalfNV green, GLhalfNV blue);
+GLAPI void APIENTRY glColor3hvNV (const GLhalfNV *v);
+GLAPI void APIENTRY glColor4hNV (GLhalfNV red, GLhalfNV green, GLhalfNV blue, GLhalfNV alpha);
+GLAPI void APIENTRY glColor4hvNV (const GLhalfNV *v);
+GLAPI void APIENTRY glTexCoord1hNV (GLhalfNV s);
+GLAPI void APIENTRY glTexCoord1hvNV (const GLhalfNV *v);
+GLAPI void APIENTRY glTexCoord2hNV (GLhalfNV s, GLhalfNV t);
+GLAPI void APIENTRY glTexCoord2hvNV (const GLhalfNV *v);
+GLAPI void APIENTRY glTexCoord3hNV (GLhalfNV s, GLhalfNV t, GLhalfNV r);
+GLAPI void APIENTRY glTexCoord3hvNV (const GLhalfNV *v);
+GLAPI void APIENTRY glTexCoord4hNV (GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q);
+GLAPI void APIENTRY glTexCoord4hvNV (const GLhalfNV *v);
+GLAPI void APIENTRY glMultiTexCoord1hNV (GLenum target, GLhalfNV s);
+GLAPI void APIENTRY glMultiTexCoord1hvNV (GLenum target, const GLhalfNV *v);
+GLAPI void APIENTRY glMultiTexCoord2hNV (GLenum target, GLhalfNV s, GLhalfNV t);
+GLAPI void APIENTRY glMultiTexCoord2hvNV (GLenum target, const GLhalfNV *v);
+GLAPI void APIENTRY glMultiTexCoord3hNV (GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r);
+GLAPI void APIENTRY glMultiTexCoord3hvNV (GLenum target, const GLhalfNV *v);
+GLAPI void APIENTRY glMultiTexCoord4hNV (GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q);
+GLAPI void APIENTRY glMultiTexCoord4hvNV (GLenum target, const GLhalfNV *v);
+GLAPI void APIENTRY glFogCoordhNV (GLhalfNV fog);
+GLAPI void APIENTRY glFogCoordhvNV (const GLhalfNV *fog);
+GLAPI void APIENTRY glSecondaryColor3hNV (GLhalfNV red, GLhalfNV green, GLhalfNV blue);
+GLAPI void APIENTRY glSecondaryColor3hvNV (const GLhalfNV *v);
+GLAPI void APIENTRY glVertexWeighthNV (GLhalfNV weight);
+GLAPI void APIENTRY glVertexWeighthvNV (const GLhalfNV *weight);
+GLAPI void APIENTRY glVertexAttrib1hNV (GLuint index, GLhalfNV x);
+GLAPI void APIENTRY glVertexAttrib1hvNV (GLuint index, const GLhalfNV *v);
+GLAPI void APIENTRY glVertexAttrib2hNV (GLuint index, GLhalfNV x, GLhalfNV y);
+GLAPI void APIENTRY glVertexAttrib2hvNV (GLuint index, const GLhalfNV *v);
+GLAPI void APIENTRY glVertexAttrib3hNV (GLuint index, GLhalfNV x, GLhalfNV y, GLhalfNV z);
+GLAPI void APIENTRY glVertexAttrib3hvNV (GLuint index, const GLhalfNV *v);
+GLAPI void APIENTRY glVertexAttrib4hNV (GLuint index, GLhalfNV x, GLhalfNV y, GLhalfNV z, GLhalfNV w);
+GLAPI void APIENTRY glVertexAttrib4hvNV (GLuint index, const GLhalfNV *v);
+GLAPI void APIENTRY glVertexAttribs1hvNV (GLuint index, GLsizei n, const GLhalfNV *v);
+GLAPI void APIENTRY glVertexAttribs2hvNV (GLuint index, GLsizei n, const GLhalfNV *v);
+GLAPI void APIENTRY glVertexAttribs3hvNV (GLuint index, GLsizei n, const GLhalfNV *v);
+GLAPI void APIENTRY glVertexAttribs4hvNV (GLuint index, GLsizei n, const GLhalfNV *v);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLVERTEX2HNVPROC) (GLhalfNV x, GLhalfNV y);
+typedef void (APIENTRYP PFNGLVERTEX2HVNVPROC) (const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLVERTEX3HNVPROC) (GLhalfNV x, GLhalfNV y, GLhalfNV z);
+typedef void (APIENTRYP PFNGLVERTEX3HVNVPROC) (const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLVERTEX4HNVPROC) (GLhalfNV x, GLhalfNV y, GLhalfNV z, GLhalfNV w);
+typedef void (APIENTRYP PFNGLVERTEX4HVNVPROC) (const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLNORMAL3HNVPROC) (GLhalfNV nx, GLhalfNV ny, GLhalfNV nz);
+typedef void (APIENTRYP PFNGLNORMAL3HVNVPROC) (const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLCOLOR3HNVPROC) (GLhalfNV red, GLhalfNV green, GLhalfNV blue);
+typedef void (APIENTRYP PFNGLCOLOR3HVNVPROC) (const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLCOLOR4HNVPROC) (GLhalfNV red, GLhalfNV green, GLhalfNV blue, GLhalfNV alpha);
+typedef void (APIENTRYP PFNGLCOLOR4HVNVPROC) (const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLTEXCOORD1HNVPROC) (GLhalfNV s);
+typedef void (APIENTRYP PFNGLTEXCOORD1HVNVPROC) (const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLTEXCOORD2HNVPROC) (GLhalfNV s, GLhalfNV t);
+typedef void (APIENTRYP PFNGLTEXCOORD2HVNVPROC) (const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLTEXCOORD3HNVPROC) (GLhalfNV s, GLhalfNV t, GLhalfNV r);
+typedef void (APIENTRYP PFNGLTEXCOORD3HVNVPROC) (const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLTEXCOORD4HNVPROC) (GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q);
+typedef void (APIENTRYP PFNGLTEXCOORD4HVNVPROC) (const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1HNVPROC) (GLenum target, GLhalfNV s);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1HVNVPROC) (GLenum target, const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2HNVPROC) (GLenum target, GLhalfNV s, GLhalfNV t);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2HVNVPROC) (GLenum target, const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3HNVPROC) (GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3HVNVPROC) (GLenum target, const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4HNVPROC) (GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4HVNVPROC) (GLenum target, const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLFOGCOORDHNVPROC) (GLhalfNV fog);
+typedef void (APIENTRYP PFNGLFOGCOORDHVNVPROC) (const GLhalfNV *fog);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3HNVPROC) (GLhalfNV red, GLhalfNV green, GLhalfNV blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3HVNVPROC) (const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLVERTEXWEIGHTHNVPROC) (GLhalfNV weight);
+typedef void (APIENTRYP PFNGLVERTEXWEIGHTHVNVPROC) (const GLhalfNV *weight);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1HNVPROC) (GLuint index, GLhalfNV x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1HVNVPROC) (GLuint index, const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2HNVPROC) (GLuint index, GLhalfNV x, GLhalfNV y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2HVNVPROC) (GLuint index, const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3HNVPROC) (GLuint index, GLhalfNV x, GLhalfNV y, GLhalfNV z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3HVNVPROC) (GLuint index, const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4HNVPROC) (GLuint index, GLhalfNV x, GLhalfNV y, GLhalfNV z, GLhalfNV w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4HVNVPROC) (GLuint index, const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS1HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS2HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS3HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS4HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v);
+#endif
+
+#ifndef GL_NV_pixel_data_range
+#define GL_NV_pixel_data_range 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glPixelDataRangeNV (GLenum target, GLsizei length, GLvoid *pointer);
+GLAPI void APIENTRY glFlushPixelDataRangeNV (GLenum target);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPIXELDATARANGENVPROC) (GLenum target, GLsizei length, GLvoid *pointer);
+typedef void (APIENTRYP PFNGLFLUSHPIXELDATARANGENVPROC) (GLenum target);
+#endif
+
+#ifndef GL_NV_primitive_restart
+#define GL_NV_primitive_restart 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glPrimitiveRestartNV (void);
+GLAPI void APIENTRY glPrimitiveRestartIndexNV (GLuint index);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPRIMITIVERESTARTNVPROC) (void);
+typedef void (APIENTRYP PFNGLPRIMITIVERESTARTINDEXNVPROC) (GLuint index);
+#endif
+
+#ifndef GL_NV_texture_expand_normal
+#define GL_NV_texture_expand_normal 1
+#endif
+
+#ifndef GL_NV_vertex_program2
+#define GL_NV_vertex_program2 1
+#endif
+
+#ifndef GL_ATI_map_object_buffer
+#define GL_ATI_map_object_buffer 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI GLvoid* APIENTRY glMapObjectBufferATI (GLuint buffer);
+GLAPI void APIENTRY glUnmapObjectBufferATI (GLuint buffer);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef GLvoid* (APIENTRYP PFNGLMAPOBJECTBUFFERATIPROC) (GLuint buffer);
+typedef void (APIENTRYP PFNGLUNMAPOBJECTBUFFERATIPROC) (GLuint buffer);
+#endif
+
+#ifndef GL_ATI_separate_stencil
+#define GL_ATI_separate_stencil 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glStencilOpSeparateATI (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass);
+GLAPI void APIENTRY glStencilFuncSeparateATI (GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLSTENCILOPSEPARATEATIPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass);
+typedef void (APIENTRYP PFNGLSTENCILFUNCSEPARATEATIPROC) (GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask);
+#endif
+
+#ifndef GL_ATI_vertex_attrib_array_object
+#define GL_ATI_vertex_attrib_array_object 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glVertexAttribArrayObjectATI (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLuint buffer, GLuint offset);
+GLAPI void APIENTRY glGetVertexAttribArrayObjectfvATI (GLuint index, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetVertexAttribArrayObjectivATI (GLuint index, GLenum pname, GLint *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLVERTEXATTRIBARRAYOBJECTATIPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLuint buffer, GLuint offset);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBARRAYOBJECTFVATIPROC) (GLuint index, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBARRAYOBJECTIVATIPROC) (GLuint index, GLenum pname, GLint *params);
+#endif
+
+#ifndef GL_OES_read_format
+#define GL_OES_read_format 1
+#endif
+
+#ifndef GL_EXT_depth_bounds_test
+#define GL_EXT_depth_bounds_test 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDepthBoundsEXT (GLclampd zmin, GLclampd zmax);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLDEPTHBOUNDSEXTPROC) (GLclampd zmin, GLclampd zmax);
+#endif
+
+#ifndef GL_EXT_texture_mirror_clamp
+#define GL_EXT_texture_mirror_clamp 1
+#endif
+
+#ifndef GL_EXT_blend_equation_separate
+#define GL_EXT_blend_equation_separate 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBlendEquationSeparateEXT (GLenum modeRGB, GLenum modeAlpha);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEEXTPROC) (GLenum modeRGB, GLenum modeAlpha);
+#endif
+
+#ifndef GL_MESA_pack_invert
+#define GL_MESA_pack_invert 1
+#endif
+
+#ifndef GL_MESA_ycbcr_texture
+#define GL_MESA_ycbcr_texture 1
+#endif
+
+#ifndef GL_EXT_pixel_buffer_object
+#define GL_EXT_pixel_buffer_object 1
+#endif
+
+#ifndef GL_NV_fragment_program_option
+#define GL_NV_fragment_program_option 1
+#endif
+
+#ifndef GL_NV_fragment_program2
+#define GL_NV_fragment_program2 1
+#endif
+
+#ifndef GL_NV_vertex_program2_option
+#define GL_NV_vertex_program2_option 1
+#endif
+
+#ifndef GL_NV_vertex_program3
+#define GL_NV_vertex_program3 1
+#endif
+
+#ifndef GL_EXT_framebuffer_object
+#define GL_EXT_framebuffer_object 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI GLboolean APIENTRY glIsRenderbufferEXT (GLuint renderbuffer);
+GLAPI void APIENTRY glBindRenderbufferEXT (GLenum target, GLuint renderbuffer);
+GLAPI void APIENTRY glDeleteRenderbuffersEXT (GLsizei n, const GLuint *renderbuffers);
+GLAPI void APIENTRY glGenRenderbuffersEXT (GLsizei n, GLuint *renderbuffers);
+GLAPI void APIENTRY glRenderbufferStorageEXT (GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
+GLAPI void APIENTRY glGetRenderbufferParameterivEXT (GLenum target, GLenum pname, GLint *params);
+GLAPI GLboolean APIENTRY glIsFramebufferEXT (GLuint framebuffer);
+GLAPI void APIENTRY glBindFramebufferEXT (GLenum target, GLuint framebuffer);
+GLAPI void APIENTRY glDeleteFramebuffersEXT (GLsizei n, const GLuint *framebuffers);
+GLAPI void APIENTRY glGenFramebuffersEXT (GLsizei n, GLuint *framebuffers);
+GLAPI GLenum APIENTRY glCheckFramebufferStatusEXT (GLenum target);
+GLAPI void APIENTRY glFramebufferTexture1DEXT (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+GLAPI void APIENTRY glFramebufferTexture2DEXT (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+GLAPI void APIENTRY glFramebufferTexture3DEXT (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset);
+GLAPI void APIENTRY glFramebufferRenderbufferEXT (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+GLAPI void APIENTRY glGetFramebufferAttachmentParameterivEXT (GLenum target, GLenum attachment, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGenerateMipmapEXT (GLenum target);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef GLboolean (APIENTRYP PFNGLISRENDERBUFFEREXTPROC) (GLuint renderbuffer);
+typedef void (APIENTRYP PFNGLBINDRENDERBUFFEREXTPROC) (GLenum target, GLuint renderbuffer);
+typedef void (APIENTRYP PFNGLDELETERENDERBUFFERSEXTPROC) (GLsizei n, const GLuint *renderbuffers);
+typedef void (APIENTRYP PFNGLGENRENDERBUFFERSEXTPROC) (GLsizei n, GLuint *renderbuffers);
+typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (APIENTRYP PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params);
+typedef GLboolean (APIENTRYP PFNGLISFRAMEBUFFEREXTPROC) (GLuint framebuffer);
+typedef void (APIENTRYP PFNGLBINDFRAMEBUFFEREXTPROC) (GLenum target, GLuint framebuffer);
+typedef void (APIENTRYP PFNGLDELETEFRAMEBUFFERSEXTPROC) (GLsizei n, const GLuint *framebuffers);
+typedef void (APIENTRYP PFNGLGENFRAMEBUFFERSEXTPROC) (GLsizei n, GLuint *framebuffers);
+typedef GLenum (APIENTRYP PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC) (GLenum target);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE1DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE3DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+typedef void (APIENTRYP PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC) (GLenum target, GLenum attachment, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGENERATEMIPMAPEXTPROC) (GLenum target);
+#endif
+
+#ifndef GL_GREMEDY_string_marker
+#define GL_GREMEDY_string_marker 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glStringMarkerGREMEDY (GLsizei len, const GLvoid *string);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLSTRINGMARKERGREMEDYPROC) (GLsizei len, const GLvoid *string);
+#endif
+
+#ifndef GL_EXT_packed_depth_stencil
+#define GL_EXT_packed_depth_stencil 1
+#endif
+
+#ifndef GL_EXT_stencil_clear_tag
+#define GL_EXT_stencil_clear_tag 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glStencilClearTagEXT (GLsizei stencilTagBits, GLuint stencilClearTag);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLSTENCILCLEARTAGEXTPROC) (GLsizei stencilTagBits, GLuint stencilClearTag);
+#endif
+
+#ifndef GL_EXT_texture_sRGB
+#define GL_EXT_texture_sRGB 1
+#endif
+
+#ifndef GL_EXT_framebuffer_blit
+#define GL_EXT_framebuffer_blit 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBlitFramebufferEXT (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBLITFRAMEBUFFEREXTPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+#endif
+
+#ifndef GL_EXT_framebuffer_multisample
+#define GL_EXT_framebuffer_multisample 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glRenderbufferStorageMultisampleEXT (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+#endif
+
+#ifndef GL_MESAX_texture_stack
+#define GL_MESAX_texture_stack 1
+#endif
+
+#ifndef GL_EXT_timer_query
+#define GL_EXT_timer_query 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGetQueryObjecti64vEXT (GLuint id, GLenum pname, GLint64EXT *params);
+GLAPI void APIENTRY glGetQueryObjectui64vEXT (GLuint id, GLenum pname, GLuint64EXT *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLGETQUERYOBJECTI64VEXTPROC) (GLuint id, GLenum pname, GLint64EXT *params);
+typedef void (APIENTRYP PFNGLGETQUERYOBJECTUI64VEXTPROC) (GLuint id, GLenum pname, GLuint64EXT *params);
+#endif
+
+#ifndef GL_EXT_gpu_program_parameters
+#define GL_EXT_gpu_program_parameters 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glProgramEnvParameters4fvEXT (GLenum target, GLuint index, GLsizei count, const GLfloat *params);
+GLAPI void APIENTRY glProgramLocalParameters4fvEXT (GLenum target, GLuint index, GLsizei count, const GLfloat *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERS4FVEXTPROC) (GLenum target, GLuint index, GLsizei count, const GLfloat *params);
+typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERS4FVEXTPROC) (GLenum target, GLuint index, GLsizei count, const GLfloat *params);
+#endif
+
+#ifndef GL_APPLE_flush_buffer_range
+#define GL_APPLE_flush_buffer_range 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBufferParameteriAPPLE (GLenum target, GLenum pname, GLint param);
+GLAPI void APIENTRY glFlushMappedBufferRangeAPPLE (GLenum target, GLintptr offset, GLsizeiptr size);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBUFFERPARAMETERIAPPLEPROC) (GLenum target, GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC) (GLenum target, GLintptr offset, GLsizeiptr size);
+#endif
+
+#ifndef GL_NV_gpu_program4
+#define GL_NV_gpu_program4 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glProgramLocalParameterI4iNV (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w);
+GLAPI void APIENTRY glProgramLocalParameterI4ivNV (GLenum target, GLuint index, const GLint *params);
+GLAPI void APIENTRY glProgramLocalParametersI4ivNV (GLenum target, GLuint index, GLsizei count, const GLint *params);
+GLAPI void APIENTRY glProgramLocalParameterI4uiNV (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
+GLAPI void APIENTRY glProgramLocalParameterI4uivNV (GLenum target, GLuint index, const GLuint *params);
+GLAPI void APIENTRY glProgramLocalParametersI4uivNV (GLenum target, GLuint index, GLsizei count, const GLuint *params);
+GLAPI void APIENTRY glProgramEnvParameterI4iNV (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w);
+GLAPI void APIENTRY glProgramEnvParameterI4ivNV (GLenum target, GLuint index, const GLint *params);
+GLAPI void APIENTRY glProgramEnvParametersI4ivNV (GLenum target, GLuint index, GLsizei count, const GLint *params);
+GLAPI void APIENTRY glProgramEnvParameterI4uiNV (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
+GLAPI void APIENTRY glProgramEnvParameterI4uivNV (GLenum target, GLuint index, const GLuint *params);
+GLAPI void APIENTRY glProgramEnvParametersI4uivNV (GLenum target, GLuint index, GLsizei count, const GLuint *params);
+GLAPI void APIENTRY glGetProgramLocalParameterIivNV (GLenum target, GLuint index, GLint *params);
+GLAPI void APIENTRY glGetProgramLocalParameterIuivNV (GLenum target, GLuint index, GLuint *params);
+GLAPI void APIENTRY glGetProgramEnvParameterIivNV (GLenum target, GLuint index, GLint *params);
+GLAPI void APIENTRY glGetProgramEnvParameterIuivNV (GLenum target, GLuint index, GLuint *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERI4INVPROC) (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w);
+typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERI4IVNVPROC) (GLenum target, GLuint index, const GLint *params);
+typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERSI4IVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLint *params);
+typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERI4UINVPROC) (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
+typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERI4UIVNVPROC) (GLenum target, GLuint index, const GLuint *params);
+typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERSI4UIVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLuint *params);
+typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERI4INVPROC) (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w);
+typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERI4IVNVPROC) (GLenum target, GLuint index, const GLint *params);
+typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERSI4IVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLint *params);
+typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERI4UINVPROC) (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
+typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERI4UIVNVPROC) (GLenum target, GLuint index, const GLuint *params);
+typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERSI4UIVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLuint *params);
+typedef void (APIENTRYP PFNGLGETPROGRAMLOCALPARAMETERIIVNVPROC) (GLenum target, GLuint index, GLint *params);
+typedef void (APIENTRYP PFNGLGETPROGRAMLOCALPARAMETERIUIVNVPROC) (GLenum target, GLuint index, GLuint *params);
+typedef void (APIENTRYP PFNGLGETPROGRAMENVPARAMETERIIVNVPROC) (GLenum target, GLuint index, GLint *params);
+typedef void (APIENTRYP PFNGLGETPROGRAMENVPARAMETERIUIVNVPROC) (GLenum target, GLuint index, GLuint *params);
+#endif
+
+#ifndef GL_NV_geometry_program4
+#define GL_NV_geometry_program4 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glProgramVertexLimitNV (GLenum target, GLint limit);
+GLAPI void APIENTRY glFramebufferTextureEXT (GLenum target, GLenum attachment, GLuint texture, GLint level);
+GLAPI void APIENTRY glFramebufferTextureLayerEXT (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer);
+GLAPI void APIENTRY glFramebufferTextureFaceEXT (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPROGRAMVERTEXLIMITNVPROC) (GLenum target, GLint limit);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREEXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREFACEEXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face);
+#endif
+
+#ifndef GL_EXT_geometry_shader4
+#define GL_EXT_geometry_shader4 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glProgramParameteriEXT (GLuint program, GLenum pname, GLint value);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPROGRAMPARAMETERIEXTPROC) (GLuint program, GLenum pname, GLint value);
+#endif
+
+#ifndef GL_NV_vertex_program4
+#define GL_NV_vertex_program4 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glVertexAttribI1iEXT (GLuint index, GLint x);
+GLAPI void APIENTRY glVertexAttribI2iEXT (GLuint index, GLint x, GLint y);
+GLAPI void APIENTRY glVertexAttribI3iEXT (GLuint index, GLint x, GLint y, GLint z);
+GLAPI void APIENTRY glVertexAttribI4iEXT (GLuint index, GLint x, GLint y, GLint z, GLint w);
+GLAPI void APIENTRY glVertexAttribI1uiEXT (GLuint index, GLuint x);
+GLAPI void APIENTRY glVertexAttribI2uiEXT (GLuint index, GLuint x, GLuint y);
+GLAPI void APIENTRY glVertexAttribI3uiEXT (GLuint index, GLuint x, GLuint y, GLuint z);
+GLAPI void APIENTRY glVertexAttribI4uiEXT (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
+GLAPI void APIENTRY glVertexAttribI1ivEXT (GLuint index, const GLint *v);
+GLAPI void APIENTRY glVertexAttribI2ivEXT (GLuint index, const GLint *v);
+GLAPI void APIENTRY glVertexAttribI3ivEXT (GLuint index, const GLint *v);
+GLAPI void APIENTRY glVertexAttribI4ivEXT (GLuint index, const GLint *v);
+GLAPI void APIENTRY glVertexAttribI1uivEXT (GLuint index, const GLuint *v);
+GLAPI void APIENTRY glVertexAttribI2uivEXT (GLuint index, const GLuint *v);
+GLAPI void APIENTRY glVertexAttribI3uivEXT (GLuint index, const GLuint *v);
+GLAPI void APIENTRY glVertexAttribI4uivEXT (GLuint index, const GLuint *v);
+GLAPI void APIENTRY glVertexAttribI4bvEXT (GLuint index, const GLbyte *v);
+GLAPI void APIENTRY glVertexAttribI4svEXT (GLuint index, const GLshort *v);
+GLAPI void APIENTRY glVertexAttribI4ubvEXT (GLuint index, const GLubyte *v);
+GLAPI void APIENTRY glVertexAttribI4usvEXT (GLuint index, const GLushort *v);
+GLAPI void APIENTRY glVertexAttribIPointerEXT (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+GLAPI void APIENTRY glGetVertexAttribIivEXT (GLuint index, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetVertexAttribIuivEXT (GLuint index, GLenum pname, GLuint *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IEXTPROC) (GLuint index, GLint x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IEXTPROC) (GLuint index, GLint x, GLint y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IEXTPROC) (GLuint index, GLint x, GLint y, GLint z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IEXTPROC) (GLuint index, GLint x, GLint y, GLint z, GLint w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIEXTPROC) (GLuint index, GLuint x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIEXTPROC) (GLuint index, GLuint x, GLuint y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIEXTPROC) (GLuint index, GLuint x, GLuint y, GLuint z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIEXTPROC) (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IVEXTPROC) (GLuint index, const GLint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IVEXTPROC) (GLuint index, const GLint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IVEXTPROC) (GLuint index, const GLint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IVEXTPROC) (GLuint index, const GLint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIVEXTPROC) (GLuint index, const GLuint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIVEXTPROC) (GLuint index, const GLuint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIVEXTPROC) (GLuint index, const GLuint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIVEXTPROC) (GLuint index, const GLuint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI4BVEXTPROC) (GLuint index, const GLbyte *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI4SVEXTPROC) (GLuint index, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UBVEXTPROC) (GLuint index, const GLubyte *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI4USVEXTPROC) (GLuint index, const GLushort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBIPOINTEREXTPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIIVEXTPROC) (GLuint index, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIUIVEXTPROC) (GLuint index, GLenum pname, GLuint *params);
+#endif
+
+#ifndef GL_EXT_gpu_shader4
+#define GL_EXT_gpu_shader4 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGetUniformuivEXT (GLuint program, GLint location, GLuint *params);
+GLAPI void APIENTRY glBindFragDataLocationEXT (GLuint program, GLuint color, const GLchar *name);
+GLAPI GLint APIENTRY glGetFragDataLocationEXT (GLuint program, const GLchar *name);
+GLAPI void APIENTRY glUniform1uiEXT (GLint location, GLuint v0);
+GLAPI void APIENTRY glUniform2uiEXT (GLint location, GLuint v0, GLuint v1);
+GLAPI void APIENTRY glUniform3uiEXT (GLint location, GLuint v0, GLuint v1, GLuint v2);
+GLAPI void APIENTRY glUniform4uiEXT (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+GLAPI void APIENTRY glUniform1uivEXT (GLint location, GLsizei count, const GLuint *value);
+GLAPI void APIENTRY glUniform2uivEXT (GLint location, GLsizei count, const GLuint *value);
+GLAPI void APIENTRY glUniform3uivEXT (GLint location, GLsizei count, const GLuint *value);
+GLAPI void APIENTRY glUniform4uivEXT (GLint location, GLsizei count, const GLuint *value);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLGETUNIFORMUIVEXTPROC) (GLuint program, GLint location, GLuint *params);
+typedef void (APIENTRYP PFNGLBINDFRAGDATALOCATIONEXTPROC) (GLuint program, GLuint color, const GLchar *name);
+typedef GLint (APIENTRYP PFNGLGETFRAGDATALOCATIONEXTPROC) (GLuint program, const GLchar *name);
+typedef void (APIENTRYP PFNGLUNIFORM1UIEXTPROC) (GLint location, GLuint v0);
+typedef void (APIENTRYP PFNGLUNIFORM2UIEXTPROC) (GLint location, GLuint v0, GLuint v1);
+typedef void (APIENTRYP PFNGLUNIFORM3UIEXTPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2);
+typedef void (APIENTRYP PFNGLUNIFORM4UIEXTPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+typedef void (APIENTRYP PFNGLUNIFORM1UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value);
+typedef void (APIENTRYP PFNGLUNIFORM2UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value);
+typedef void (APIENTRYP PFNGLUNIFORM3UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value);
+typedef void (APIENTRYP PFNGLUNIFORM4UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value);
+#endif
+
+#ifndef GL_EXT_draw_instanced
+#define GL_EXT_draw_instanced 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDrawArraysInstancedEXT (GLenum mode, GLint start, GLsizei count, GLsizei primcount);
+GLAPI void APIENTRY glDrawElementsInstancedEXT (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDEXTPROC) (GLenum mode, GLint start, GLsizei count, GLsizei primcount);
+typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDEXTPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount);
+#endif
+
+#ifndef GL_EXT_packed_float
+#define GL_EXT_packed_float 1
+#endif
+
+#ifndef GL_EXT_texture_array
+#define GL_EXT_texture_array 1
+#endif
+
+#ifndef GL_EXT_texture_buffer_object
+#define GL_EXT_texture_buffer_object 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTexBufferEXT (GLenum target, GLenum internalformat, GLuint buffer);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLTEXBUFFEREXTPROC) (GLenum target, GLenum internalformat, GLuint buffer);
+#endif
+
+#ifndef GL_EXT_texture_compression_latc
+#define GL_EXT_texture_compression_latc 1
+#endif
+
+#ifndef GL_EXT_texture_compression_rgtc
+#define GL_EXT_texture_compression_rgtc 1
+#endif
+
+#ifndef GL_EXT_texture_shared_exponent
+#define GL_EXT_texture_shared_exponent 1
+#endif
+
+#ifndef GL_NV_depth_buffer_float
+#define GL_NV_depth_buffer_float 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDepthRangedNV (GLdouble zNear, GLdouble zFar);
+GLAPI void APIENTRY glClearDepthdNV (GLdouble depth);
+GLAPI void APIENTRY glDepthBoundsdNV (GLdouble zmin, GLdouble zmax);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLDEPTHRANGEDNVPROC) (GLdouble zNear, GLdouble zFar);
+typedef void (APIENTRYP PFNGLCLEARDEPTHDNVPROC) (GLdouble depth);
+typedef void (APIENTRYP PFNGLDEPTHBOUNDSDNVPROC) (GLdouble zmin, GLdouble zmax);
+#endif
+
+#ifndef GL_NV_fragment_program4
+#define GL_NV_fragment_program4 1
+#endif
+
+#ifndef GL_NV_framebuffer_multisample_coverage
+#define GL_NV_framebuffer_multisample_coverage 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glRenderbufferStorageMultisampleCoverageNV (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLECOVERAGENVPROC) (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height);
+#endif
+
+#ifndef GL_EXT_framebuffer_sRGB
+#define GL_EXT_framebuffer_sRGB 1
+#endif
+
+#ifndef GL_NV_geometry_shader4
+#define GL_NV_geometry_shader4 1
+#endif
+
+#ifndef GL_NV_parameter_buffer_object
+#define GL_NV_parameter_buffer_object 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glProgramBufferParametersfvNV (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLfloat *params);
+GLAPI void APIENTRY glProgramBufferParametersIivNV (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLint *params);
+GLAPI void APIENTRY glProgramBufferParametersIuivNV (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLuint *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPROGRAMBUFFERPARAMETERSFVNVPROC) (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLfloat *params);
+typedef void (APIENTRYP PFNGLPROGRAMBUFFERPARAMETERSIIVNVPROC) (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLint *params);
+typedef void (APIENTRYP PFNGLPROGRAMBUFFERPARAMETERSIUIVNVPROC) (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLuint *params);
+#endif
+
+#ifndef GL_EXT_draw_buffers2
+#define GL_EXT_draw_buffers2 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glColorMaskIndexedEXT (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a);
+GLAPI void APIENTRY glGetBooleanIndexedvEXT (GLenum target, GLuint index, GLboolean *data);
+GLAPI void APIENTRY glGetIntegerIndexedvEXT (GLenum target, GLuint index, GLint *data);
+GLAPI void APIENTRY glEnableIndexedEXT (GLenum target, GLuint index);
+GLAPI void APIENTRY glDisableIndexedEXT (GLenum target, GLuint index);
+GLAPI GLboolean APIENTRY glIsEnabledIndexedEXT (GLenum target, GLuint index);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLCOLORMASKINDEXEDEXTPROC) (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a);
+typedef void (APIENTRYP PFNGLGETBOOLEANINDEXEDVEXTPROC) (GLenum target, GLuint index, GLboolean *data);
+typedef void (APIENTRYP PFNGLGETINTEGERINDEXEDVEXTPROC) (GLenum target, GLuint index, GLint *data);
+typedef void (APIENTRYP PFNGLENABLEINDEXEDEXTPROC) (GLenum target, GLuint index);
+typedef void (APIENTRYP PFNGLDISABLEINDEXEDEXTPROC) (GLenum target, GLuint index);
+typedef GLboolean (APIENTRYP PFNGLISENABLEDINDEXEDEXTPROC) (GLenum target, GLuint index);
+#endif
+
+#ifndef GL_NV_transform_feedback
+#define GL_NV_transform_feedback 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBeginTransformFeedbackNV (GLenum primitiveMode);
+GLAPI void APIENTRY glEndTransformFeedbackNV (void);
+GLAPI void APIENTRY glTransformFeedbackAttribsNV (GLuint count, const GLint *attribs, GLenum bufferMode);
+GLAPI void APIENTRY glBindBufferRangeNV (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);
+GLAPI void APIENTRY glBindBufferOffsetNV (GLenum target, GLuint index, GLuint buffer, GLintptr offset);
+GLAPI void APIENTRY glBindBufferBaseNV (GLenum target, GLuint index, GLuint buffer);
+GLAPI void APIENTRY glTransformFeedbackVaryingsNV (GLuint program, GLsizei count, const GLint *locations, GLenum bufferMode);
+GLAPI void APIENTRY glActiveVaryingNV (GLuint program, const GLchar *name);
+GLAPI GLint APIENTRY glGetVaryingLocationNV (GLuint program, const GLchar *name);
+GLAPI void APIENTRY glGetActiveVaryingNV (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name);
+GLAPI void APIENTRY glGetTransformFeedbackVaryingNV (GLuint program, GLuint index, GLint *location);
+GLAPI void APIENTRY glTransformFeedbackStreamAttribsNV (GLsizei count, const GLint *attribs, GLsizei nbuffers, const GLint *bufstreams, GLenum bufferMode);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBEGINTRANSFORMFEEDBACKNVPROC) (GLenum primitiveMode);
+typedef void (APIENTRYP PFNGLENDTRANSFORMFEEDBACKNVPROC) (void);
+typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKATTRIBSNVPROC) (GLuint count, const GLint *attribs, GLenum bufferMode);
+typedef void (APIENTRYP PFNGLBINDBUFFERRANGENVPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);
+typedef void (APIENTRYP PFNGLBINDBUFFEROFFSETNVPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset);
+typedef void (APIENTRYP PFNGLBINDBUFFERBASENVPROC) (GLenum target, GLuint index, GLuint buffer);
+typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKVARYINGSNVPROC) (GLuint program, GLsizei count, const GLint *locations, GLenum bufferMode);
+typedef void (APIENTRYP PFNGLACTIVEVARYINGNVPROC) (GLuint program, const GLchar *name);
+typedef GLint (APIENTRYP PFNGLGETVARYINGLOCATIONNVPROC) (GLuint program, const GLchar *name);
+typedef void (APIENTRYP PFNGLGETACTIVEVARYINGNVPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name);
+typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKVARYINGNVPROC) (GLuint program, GLuint index, GLint *location);
+typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKSTREAMATTRIBSNVPROC) (GLsizei count, const GLint *attribs, GLsizei nbuffers, const GLint *bufstreams, GLenum bufferMode);
+#endif
+
+#ifndef GL_EXT_bindable_uniform
+#define GL_EXT_bindable_uniform 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glUniformBufferEXT (GLuint program, GLint location, GLuint buffer);
+GLAPI GLint APIENTRY glGetUniformBufferSizeEXT (GLuint program, GLint location);
+GLAPI GLintptr APIENTRY glGetUniformOffsetEXT (GLuint program, GLint location);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLUNIFORMBUFFEREXTPROC) (GLuint program, GLint location, GLuint buffer);
+typedef GLint (APIENTRYP PFNGLGETUNIFORMBUFFERSIZEEXTPROC) (GLuint program, GLint location);
+typedef GLintptr (APIENTRYP PFNGLGETUNIFORMOFFSETEXTPROC) (GLuint program, GLint location);
+#endif
+
+#ifndef GL_EXT_texture_integer
+#define GL_EXT_texture_integer 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTexParameterIivEXT (GLenum target, GLenum pname, const GLint *params);
+GLAPI void APIENTRY glTexParameterIuivEXT (GLenum target, GLenum pname, const GLuint *params);
+GLAPI void APIENTRY glGetTexParameterIivEXT (GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetTexParameterIuivEXT (GLenum target, GLenum pname, GLuint *params);
+GLAPI void APIENTRY glClearColorIiEXT (GLint red, GLint green, GLint blue, GLint alpha);
+GLAPI void APIENTRY glClearColorIuiEXT (GLuint red, GLuint green, GLuint blue, GLuint alpha);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLTEXPARAMETERIIVEXTPROC) (GLenum target, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLTEXPARAMETERIUIVEXTPROC) (GLenum target, GLenum pname, const GLuint *params);
+typedef void (APIENTRYP PFNGLGETTEXPARAMETERIIVEXTPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETTEXPARAMETERIUIVEXTPROC) (GLenum target, GLenum pname, GLuint *params);
+typedef void (APIENTRYP PFNGLCLEARCOLORIIEXTPROC) (GLint red, GLint green, GLint blue, GLint alpha);
+typedef void (APIENTRYP PFNGLCLEARCOLORIUIEXTPROC) (GLuint red, GLuint green, GLuint blue, GLuint alpha);
+#endif
+
+#ifndef GL_GREMEDY_frame_terminator
+#define GL_GREMEDY_frame_terminator 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glFrameTerminatorGREMEDY (void);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLFRAMETERMINATORGREMEDYPROC) (void);
+#endif
+
+#ifndef GL_NV_conditional_render
+#define GL_NV_conditional_render 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBeginConditionalRenderNV (GLuint id, GLenum mode);
+GLAPI void APIENTRY glEndConditionalRenderNV (void);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBEGINCONDITIONALRENDERNVPROC) (GLuint id, GLenum mode);
+typedef void (APIENTRYP PFNGLENDCONDITIONALRENDERNVPROC) (void);
+#endif
+
+#ifndef GL_NV_present_video
+#define GL_NV_present_video 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glPresentFrameKeyedNV (GLuint video_slot, GLuint64EXT minPresentTime, GLuint beginPresentTimeId, GLuint presentDurationId, GLenum type, GLenum target0, GLuint fill0, GLuint key0, GLenum target1, GLuint fill1, GLuint key1);
+GLAPI void APIENTRY glPresentFrameDualFillNV (GLuint video_slot, GLuint64EXT minPresentTime, GLuint beginPresentTimeId, GLuint presentDurationId, GLenum type, GLenum target0, GLuint fill0, GLenum target1, GLuint fill1, GLenum target2, GLuint fill2, GLenum target3, GLuint fill3);
+GLAPI void APIENTRY glGetVideoivNV (GLuint video_slot, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetVideouivNV (GLuint video_slot, GLenum pname, GLuint *params);
+GLAPI void APIENTRY glGetVideoi64vNV (GLuint video_slot, GLenum pname, GLint64EXT *params);
+GLAPI void APIENTRY glGetVideoui64vNV (GLuint video_slot, GLenum pname, GLuint64EXT *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPRESENTFRAMEKEYEDNVPROC) (GLuint video_slot, GLuint64EXT minPresentTime, GLuint beginPresentTimeId, GLuint presentDurationId, GLenum type, GLenum target0, GLuint fill0, GLuint key0, GLenum target1, GLuint fill1, GLuint key1);
+typedef void (APIENTRYP PFNGLPRESENTFRAMEDUALFILLNVPROC) (GLuint video_slot, GLuint64EXT minPresentTime, GLuint beginPresentTimeId, GLuint presentDurationId, GLenum type, GLenum target0, GLuint fill0, GLenum target1, GLuint fill1, GLenum target2, GLuint fill2, GLenum target3, GLuint fill3);
+typedef void (APIENTRYP PFNGLGETVIDEOIVNVPROC) (GLuint video_slot, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETVIDEOUIVNVPROC) (GLuint video_slot, GLenum pname, GLuint *params);
+typedef void (APIENTRYP PFNGLGETVIDEOI64VNVPROC) (GLuint video_slot, GLenum pname, GLint64EXT *params);
+typedef void (APIENTRYP PFNGLGETVIDEOUI64VNVPROC) (GLuint video_slot, GLenum pname, GLuint64EXT *params);
+#endif
+
+#ifndef GL_EXT_transform_feedback
+#define GL_EXT_transform_feedback 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBeginTransformFeedbackEXT (GLenum primitiveMode);
+GLAPI void APIENTRY glEndTransformFeedbackEXT (void);
+GLAPI void APIENTRY glBindBufferRangeEXT (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);
+GLAPI void APIENTRY glBindBufferOffsetEXT (GLenum target, GLuint index, GLuint buffer, GLintptr offset);
+GLAPI void APIENTRY glBindBufferBaseEXT (GLenum target, GLuint index, GLuint buffer);
+GLAPI void APIENTRY glTransformFeedbackVaryingsEXT (GLuint program, GLsizei count, const GLchar* *varyings, GLenum bufferMode);
+GLAPI void APIENTRY glGetTransformFeedbackVaryingEXT (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBEGINTRANSFORMFEEDBACKEXTPROC) (GLenum primitiveMode);
+typedef void (APIENTRYP PFNGLENDTRANSFORMFEEDBACKEXTPROC) (void);
+typedef void (APIENTRYP PFNGLBINDBUFFERRANGEEXTPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);
+typedef void (APIENTRYP PFNGLBINDBUFFEROFFSETEXTPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset);
+typedef void (APIENTRYP PFNGLBINDBUFFERBASEEXTPROC) (GLenum target, GLuint index, GLuint buffer);
+typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKVARYINGSEXTPROC) (GLuint program, GLsizei count, const GLchar* *varyings, GLenum bufferMode);
+typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKVARYINGEXTPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name);
+#endif
+
+#ifndef GL_EXT_direct_state_access
+#define GL_EXT_direct_state_access 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glClientAttribDefaultEXT (GLbitfield mask);
+GLAPI void APIENTRY glPushClientAttribDefaultEXT (GLbitfield mask);
+GLAPI void APIENTRY glMatrixLoadfEXT (GLenum mode, const GLfloat *m);
+GLAPI void APIENTRY glMatrixLoaddEXT (GLenum mode, const GLdouble *m);
+GLAPI void APIENTRY glMatrixMultfEXT (GLenum mode, const GLfloat *m);
+GLAPI void APIENTRY glMatrixMultdEXT (GLenum mode, const GLdouble *m);
+GLAPI void APIENTRY glMatrixLoadIdentityEXT (GLenum mode);
+GLAPI void APIENTRY glMatrixRotatefEXT (GLenum mode, GLfloat angle, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glMatrixRotatedEXT (GLenum mode, GLdouble angle, GLdouble x, GLdouble y, GLdouble z);
+GLAPI void APIENTRY glMatrixScalefEXT (GLenum mode, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glMatrixScaledEXT (GLenum mode, GLdouble x, GLdouble y, GLdouble z);
+GLAPI void APIENTRY glMatrixTranslatefEXT (GLenum mode, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glMatrixTranslatedEXT (GLenum mode, GLdouble x, GLdouble y, GLdouble z);
+GLAPI void APIENTRY glMatrixFrustumEXT (GLenum mode, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar);
+GLAPI void APIENTRY glMatrixOrthoEXT (GLenum mode, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar);
+GLAPI void APIENTRY glMatrixPopEXT (GLenum mode);
+GLAPI void APIENTRY glMatrixPushEXT (GLenum mode);
+GLAPI void APIENTRY glMatrixLoadTransposefEXT (GLenum mode, const GLfloat *m);
+GLAPI void APIENTRY glMatrixLoadTransposedEXT (GLenum mode, const GLdouble *m);
+GLAPI void APIENTRY glMatrixMultTransposefEXT (GLenum mode, const GLfloat *m);
+GLAPI void APIENTRY glMatrixMultTransposedEXT (GLenum mode, const GLdouble *m);
+GLAPI void APIENTRY glTextureParameterfEXT (GLuint texture, GLenum target, GLenum pname, GLfloat param);
+GLAPI void APIENTRY glTextureParameterfvEXT (GLuint texture, GLenum target, GLenum pname, const GLfloat *params);
+GLAPI void APIENTRY glTextureParameteriEXT (GLuint texture, GLenum target, GLenum pname, GLint param);
+GLAPI void APIENTRY glTextureParameterivEXT (GLuint texture, GLenum target, GLenum pname, const GLint *params);
+GLAPI void APIENTRY glTextureImage1DEXT (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+GLAPI void APIENTRY glTextureImage2DEXT (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+GLAPI void APIENTRY glTextureSubImage1DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels);
+GLAPI void APIENTRY glTextureSubImage2DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
+GLAPI void APIENTRY glCopyTextureImage1DEXT (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border);
+GLAPI void APIENTRY glCopyTextureImage2DEXT (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
+GLAPI void APIENTRY glCopyTextureSubImage1DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width);
+GLAPI void APIENTRY glCopyTextureSubImage2DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+GLAPI void APIENTRY glGetTextureImageEXT (GLuint texture, GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels);
+GLAPI void APIENTRY glGetTextureParameterfvEXT (GLuint texture, GLenum target, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetTextureParameterivEXT (GLuint texture, GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetTextureLevelParameterfvEXT (GLuint texture, GLenum target, GLint level, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetTextureLevelParameterivEXT (GLuint texture, GLenum target, GLint level, GLenum pname, GLint *params);
+GLAPI void APIENTRY glTextureImage3DEXT (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+GLAPI void APIENTRY glTextureSubImage3DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels);
+GLAPI void APIENTRY glCopyTextureSubImage3DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+GLAPI void APIENTRY glMultiTexParameterfEXT (GLenum texunit, GLenum target, GLenum pname, GLfloat param);
+GLAPI void APIENTRY glMultiTexParameterfvEXT (GLenum texunit, GLenum target, GLenum pname, const GLfloat *params);
+GLAPI void APIENTRY glMultiTexParameteriEXT (GLenum texunit, GLenum target, GLenum pname, GLint param);
+GLAPI void APIENTRY glMultiTexParameterivEXT (GLenum texunit, GLenum target, GLenum pname, const GLint *params);
+GLAPI void APIENTRY glMultiTexImage1DEXT (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+GLAPI void APIENTRY glMultiTexImage2DEXT (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+GLAPI void APIENTRY glMultiTexSubImage1DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels);
+GLAPI void APIENTRY glMultiTexSubImage2DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
+GLAPI void APIENTRY glCopyMultiTexImage1DEXT (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border);
+GLAPI void APIENTRY glCopyMultiTexImage2DEXT (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
+GLAPI void APIENTRY glCopyMultiTexSubImage1DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width);
+GLAPI void APIENTRY glCopyMultiTexSubImage2DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+GLAPI void APIENTRY glGetMultiTexImageEXT (GLenum texunit, GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels);
+GLAPI void APIENTRY glGetMultiTexParameterfvEXT (GLenum texunit, GLenum target, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetMultiTexParameterivEXT (GLenum texunit, GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetMultiTexLevelParameterfvEXT (GLenum texunit, GLenum target, GLint level, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetMultiTexLevelParameterivEXT (GLenum texunit, GLenum target, GLint level, GLenum pname, GLint *params);
+GLAPI void APIENTRY glMultiTexImage3DEXT (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+GLAPI void APIENTRY glMultiTexSubImage3DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels);
+GLAPI void APIENTRY glCopyMultiTexSubImage3DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+GLAPI void APIENTRY glBindMultiTextureEXT (GLenum texunit, GLenum target, GLuint texture);
+GLAPI void APIENTRY glEnableClientStateIndexedEXT (GLenum array, GLuint index);
+GLAPI void APIENTRY glDisableClientStateIndexedEXT (GLenum array, GLuint index);
+GLAPI void APIENTRY glMultiTexCoordPointerEXT (GLenum texunit, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+GLAPI void APIENTRY glMultiTexEnvfEXT (GLenum texunit, GLenum target, GLenum pname, GLfloat param);
+GLAPI void APIENTRY glMultiTexEnvfvEXT (GLenum texunit, GLenum target, GLenum pname, const GLfloat *params);
+GLAPI void APIENTRY glMultiTexEnviEXT (GLenum texunit, GLenum target, GLenum pname, GLint param);
+GLAPI void APIENTRY glMultiTexEnvivEXT (GLenum texunit, GLenum target, GLenum pname, const GLint *params);
+GLAPI void APIENTRY glMultiTexGendEXT (GLenum texunit, GLenum coord, GLenum pname, GLdouble param);
+GLAPI void APIENTRY glMultiTexGendvEXT (GLenum texunit, GLenum coord, GLenum pname, const GLdouble *params);
+GLAPI void APIENTRY glMultiTexGenfEXT (GLenum texunit, GLenum coord, GLenum pname, GLfloat param);
+GLAPI void APIENTRY glMultiTexGenfvEXT (GLenum texunit, GLenum coord, GLenum pname, const GLfloat *params);
+GLAPI void APIENTRY glMultiTexGeniEXT (GLenum texunit, GLenum coord, GLenum pname, GLint param);
+GLAPI void APIENTRY glMultiTexGenivEXT (GLenum texunit, GLenum coord, GLenum pname, const GLint *params);
+GLAPI void APIENTRY glGetMultiTexEnvfvEXT (GLenum texunit, GLenum target, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetMultiTexEnvivEXT (GLenum texunit, GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetMultiTexGendvEXT (GLenum texunit, GLenum coord, GLenum pname, GLdouble *params);
+GLAPI void APIENTRY glGetMultiTexGenfvEXT (GLenum texunit, GLenum coord, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetMultiTexGenivEXT (GLenum texunit, GLenum coord, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetFloatIndexedvEXT (GLenum target, GLuint index, GLfloat *data);
+GLAPI void APIENTRY glGetDoubleIndexedvEXT (GLenum target, GLuint index, GLdouble *data);
+GLAPI void APIENTRY glGetPointerIndexedvEXT (GLenum target, GLuint index, GLvoid* *data);
+GLAPI void APIENTRY glCompressedTextureImage3DEXT (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *bits);
+GLAPI void APIENTRY glCompressedTextureImage2DEXT (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *bits);
+GLAPI void APIENTRY glCompressedTextureImage1DEXT (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *bits);
+GLAPI void APIENTRY glCompressedTextureSubImage3DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *bits);
+GLAPI void APIENTRY glCompressedTextureSubImage2DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *bits);
+GLAPI void APIENTRY glCompressedTextureSubImage1DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *bits);
+GLAPI void APIENTRY glGetCompressedTextureImageEXT (GLuint texture, GLenum target, GLint lod, GLvoid *img);
+GLAPI void APIENTRY glCompressedMultiTexImage3DEXT (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *bits);
+GLAPI void APIENTRY glCompressedMultiTexImage2DEXT (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *bits);
+GLAPI void APIENTRY glCompressedMultiTexImage1DEXT (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *bits);
+GLAPI void APIENTRY glCompressedMultiTexSubImage3DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *bits);
+GLAPI void APIENTRY glCompressedMultiTexSubImage2DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *bits);
+GLAPI void APIENTRY glCompressedMultiTexSubImage1DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *bits);
+GLAPI void APIENTRY glGetCompressedMultiTexImageEXT (GLenum texunit, GLenum target, GLint lod, GLvoid *img);
+GLAPI void APIENTRY glNamedProgramStringEXT (GLuint program, GLenum target, GLenum format, GLsizei len, const GLvoid *string);
+GLAPI void APIENTRY glNamedProgramLocalParameter4dEXT (GLuint program, GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+GLAPI void APIENTRY glNamedProgramLocalParameter4dvEXT (GLuint program, GLenum target, GLuint index, const GLdouble *params);
+GLAPI void APIENTRY glNamedProgramLocalParameter4fEXT (GLuint program, GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+GLAPI void APIENTRY glNamedProgramLocalParameter4fvEXT (GLuint program, GLenum target, GLuint index, const GLfloat *params);
+GLAPI void APIENTRY glGetNamedProgramLocalParameterdvEXT (GLuint program, GLenum target, GLuint index, GLdouble *params);
+GLAPI void APIENTRY glGetNamedProgramLocalParameterfvEXT (GLuint program, GLenum target, GLuint index, GLfloat *params);
+GLAPI void APIENTRY glGetNamedProgramivEXT (GLuint program, GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetNamedProgramStringEXT (GLuint program, GLenum target, GLenum pname, GLvoid *string);
+GLAPI void APIENTRY glNamedProgramLocalParameters4fvEXT (GLuint program, GLenum target, GLuint index, GLsizei count, const GLfloat *params);
+GLAPI void APIENTRY glNamedProgramLocalParameterI4iEXT (GLuint program, GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w);
+GLAPI void APIENTRY glNamedProgramLocalParameterI4ivEXT (GLuint program, GLenum target, GLuint index, const GLint *params);
+GLAPI void APIENTRY glNamedProgramLocalParametersI4ivEXT (GLuint program, GLenum target, GLuint index, GLsizei count, const GLint *params);
+GLAPI void APIENTRY glNamedProgramLocalParameterI4uiEXT (GLuint program, GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
+GLAPI void APIENTRY glNamedProgramLocalParameterI4uivEXT (GLuint program, GLenum target, GLuint index, const GLuint *params);
+GLAPI void APIENTRY glNamedProgramLocalParametersI4uivEXT (GLuint program, GLenum target, GLuint index, GLsizei count, const GLuint *params);
+GLAPI void APIENTRY glGetNamedProgramLocalParameterIivEXT (GLuint program, GLenum target, GLuint index, GLint *params);
+GLAPI void APIENTRY glGetNamedProgramLocalParameterIuivEXT (GLuint program, GLenum target, GLuint index, GLuint *params);
+GLAPI void APIENTRY glTextureParameterIivEXT (GLuint texture, GLenum target, GLenum pname, const GLint *params);
+GLAPI void APIENTRY glTextureParameterIuivEXT (GLuint texture, GLenum target, GLenum pname, const GLuint *params);
+GLAPI void APIENTRY glGetTextureParameterIivEXT (GLuint texture, GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetTextureParameterIuivEXT (GLuint texture, GLenum target, GLenum pname, GLuint *params);
+GLAPI void APIENTRY glMultiTexParameterIivEXT (GLenum texunit, GLenum target, GLenum pname, const GLint *params);
+GLAPI void APIENTRY glMultiTexParameterIuivEXT (GLenum texunit, GLenum target, GLenum pname, const GLuint *params);
+GLAPI void APIENTRY glGetMultiTexParameterIivEXT (GLenum texunit, GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetMultiTexParameterIuivEXT (GLenum texunit, GLenum target, GLenum pname, GLuint *params);
+GLAPI void APIENTRY glProgramUniform1fEXT (GLuint program, GLint location, GLfloat v0);
+GLAPI void APIENTRY glProgramUniform2fEXT (GLuint program, GLint location, GLfloat v0, GLfloat v1);
+GLAPI void APIENTRY glProgramUniform3fEXT (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
+GLAPI void APIENTRY glProgramUniform4fEXT (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
+GLAPI void APIENTRY glProgramUniform1iEXT (GLuint program, GLint location, GLint v0);
+GLAPI void APIENTRY glProgramUniform2iEXT (GLuint program, GLint location, GLint v0, GLint v1);
+GLAPI void APIENTRY glProgramUniform3iEXT (GLuint program, GLint location, GLint v0, GLint v1, GLint v2);
+GLAPI void APIENTRY glProgramUniform4iEXT (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
+GLAPI void APIENTRY glProgramUniform1fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniform2fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniform3fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniform4fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniform1ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value);
+GLAPI void APIENTRY glProgramUniform2ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value);
+GLAPI void APIENTRY glProgramUniform3ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value);
+GLAPI void APIENTRY glProgramUniform4ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value);
+GLAPI void APIENTRY glProgramUniformMatrix2fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniformMatrix3fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniformMatrix4fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniformMatrix2x3fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniformMatrix3x2fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniformMatrix2x4fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniformMatrix4x2fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniformMatrix3x4fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniformMatrix4x3fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniform1uiEXT (GLuint program, GLint location, GLuint v0);
+GLAPI void APIENTRY glProgramUniform2uiEXT (GLuint program, GLint location, GLuint v0, GLuint v1);
+GLAPI void APIENTRY glProgramUniform3uiEXT (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2);
+GLAPI void APIENTRY glProgramUniform4uiEXT (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+GLAPI void APIENTRY glProgramUniform1uivEXT (GLuint program, GLint location, GLsizei count, const GLuint *value);
+GLAPI void APIENTRY glProgramUniform2uivEXT (GLuint program, GLint location, GLsizei count, const GLuint *value);
+GLAPI void APIENTRY glProgramUniform3uivEXT (GLuint program, GLint location, GLsizei count, const GLuint *value);
+GLAPI void APIENTRY glProgramUniform4uivEXT (GLuint program, GLint location, GLsizei count, const GLuint *value);
+GLAPI void APIENTRY glNamedBufferDataEXT (GLuint buffer, GLsizeiptr size, const GLvoid *data, GLenum usage);
+GLAPI void APIENTRY glNamedBufferSubDataEXT (GLuint buffer, GLintptr offset, GLsizeiptr size, const GLvoid *data);
+GLAPI GLvoid* APIENTRY glMapNamedBufferEXT (GLuint buffer, GLenum access);
+GLAPI GLboolean APIENTRY glUnmapNamedBufferEXT (GLuint buffer);
+GLAPI GLvoid* APIENTRY glMapNamedBufferRangeEXT (GLuint buffer, GLintptr offset, GLsizeiptr length, GLbitfield access);
+GLAPI void APIENTRY glFlushMappedNamedBufferRangeEXT (GLuint buffer, GLintptr offset, GLsizeiptr length);
+GLAPI void APIENTRY glNamedCopyBufferSubDataEXT (GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
+GLAPI void APIENTRY glGetNamedBufferParameterivEXT (GLuint buffer, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetNamedBufferPointervEXT (GLuint buffer, GLenum pname, GLvoid* *params);
+GLAPI void APIENTRY glGetNamedBufferSubDataEXT (GLuint buffer, GLintptr offset, GLsizeiptr size, GLvoid *data);
+GLAPI void APIENTRY glTextureBufferEXT (GLuint texture, GLenum target, GLenum internalformat, GLuint buffer);
+GLAPI void APIENTRY glMultiTexBufferEXT (GLenum texunit, GLenum target, GLenum internalformat, GLuint buffer);
+GLAPI void APIENTRY glNamedRenderbufferStorageEXT (GLuint renderbuffer, GLenum internalformat, GLsizei width, GLsizei height);
+GLAPI void APIENTRY glGetNamedRenderbufferParameterivEXT (GLuint renderbuffer, GLenum pname, GLint *params);
+GLAPI GLenum APIENTRY glCheckNamedFramebufferStatusEXT (GLuint framebuffer, GLenum target);
+GLAPI void APIENTRY glNamedFramebufferTexture1DEXT (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+GLAPI void APIENTRY glNamedFramebufferTexture2DEXT (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+GLAPI void APIENTRY glNamedFramebufferTexture3DEXT (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset);
+GLAPI void APIENTRY glNamedFramebufferRenderbufferEXT (GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+GLAPI void APIENTRY glGetNamedFramebufferAttachmentParameterivEXT (GLuint framebuffer, GLenum attachment, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGenerateTextureMipmapEXT (GLuint texture, GLenum target);
+GLAPI void APIENTRY glGenerateMultiTexMipmapEXT (GLenum texunit, GLenum target);
+GLAPI void APIENTRY glFramebufferDrawBufferEXT (GLuint framebuffer, GLenum mode);
+GLAPI void APIENTRY glFramebufferDrawBuffersEXT (GLuint framebuffer, GLsizei n, const GLenum *bufs);
+GLAPI void APIENTRY glFramebufferReadBufferEXT (GLuint framebuffer, GLenum mode);
+GLAPI void APIENTRY glGetFramebufferParameterivEXT (GLuint framebuffer, GLenum pname, GLint *params);
+GLAPI void APIENTRY glNamedRenderbufferStorageMultisampleEXT (GLuint renderbuffer, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+GLAPI void APIENTRY glNamedRenderbufferStorageMultisampleCoverageEXT (GLuint renderbuffer, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height);
+GLAPI void APIENTRY glNamedFramebufferTextureEXT (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level);
+GLAPI void APIENTRY glNamedFramebufferTextureLayerEXT (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLint layer);
+GLAPI void APIENTRY glNamedFramebufferTextureFaceEXT (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLenum face);
+GLAPI void APIENTRY glTextureRenderbufferEXT (GLuint texture, GLenum target, GLuint renderbuffer);
+GLAPI void APIENTRY glMultiTexRenderbufferEXT (GLenum texunit, GLenum target, GLuint renderbuffer);
+GLAPI void APIENTRY glProgramUniform1dEXT (GLuint program, GLint location, GLdouble x);
+GLAPI void APIENTRY glProgramUniform2dEXT (GLuint program, GLint location, GLdouble x, GLdouble y);
+GLAPI void APIENTRY glProgramUniform3dEXT (GLuint program, GLint location, GLdouble x, GLdouble y, GLdouble z);
+GLAPI void APIENTRY glProgramUniform4dEXT (GLuint program, GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+GLAPI void APIENTRY glProgramUniform1dvEXT (GLuint program, GLint location, GLsizei count, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniform2dvEXT (GLuint program, GLint location, GLsizei count, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniform3dvEXT (GLuint program, GLint location, GLsizei count, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniform4dvEXT (GLuint program, GLint location, GLsizei count, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniformMatrix2dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniformMatrix3dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniformMatrix4dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniformMatrix2x3dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniformMatrix2x4dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniformMatrix3x2dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniformMatrix3x4dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniformMatrix4x2dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniformMatrix4x3dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLCLIENTATTRIBDEFAULTEXTPROC) (GLbitfield mask);
+typedef void (APIENTRYP PFNGLPUSHCLIENTATTRIBDEFAULTEXTPROC) (GLbitfield mask);
+typedef void (APIENTRYP PFNGLMATRIXLOADFEXTPROC) (GLenum mode, const GLfloat *m);
+typedef void (APIENTRYP PFNGLMATRIXLOADDEXTPROC) (GLenum mode, const GLdouble *m);
+typedef void (APIENTRYP PFNGLMATRIXMULTFEXTPROC) (GLenum mode, const GLfloat *m);
+typedef void (APIENTRYP PFNGLMATRIXMULTDEXTPROC) (GLenum mode, const GLdouble *m);
+typedef void (APIENTRYP PFNGLMATRIXLOADIDENTITYEXTPROC) (GLenum mode);
+typedef void (APIENTRYP PFNGLMATRIXROTATEFEXTPROC) (GLenum mode, GLfloat angle, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLMATRIXROTATEDEXTPROC) (GLenum mode, GLdouble angle, GLdouble x, GLdouble y, GLdouble z);
+typedef void (APIENTRYP PFNGLMATRIXSCALEFEXTPROC) (GLenum mode, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLMATRIXSCALEDEXTPROC) (GLenum mode, GLdouble x, GLdouble y, GLdouble z);
+typedef void (APIENTRYP PFNGLMATRIXTRANSLATEFEXTPROC) (GLenum mode, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLMATRIXTRANSLATEDEXTPROC) (GLenum mode, GLdouble x, GLdouble y, GLdouble z);
+typedef void (APIENTRYP PFNGLMATRIXFRUSTUMEXTPROC) (GLenum mode, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar);
+typedef void (APIENTRYP PFNGLMATRIXORTHOEXTPROC) (GLenum mode, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar);
+typedef void (APIENTRYP PFNGLMATRIXPOPEXTPROC) (GLenum mode);
+typedef void (APIENTRYP PFNGLMATRIXPUSHEXTPROC) (GLenum mode);
+typedef void (APIENTRYP PFNGLMATRIXLOADTRANSPOSEFEXTPROC) (GLenum mode, const GLfloat *m);
+typedef void (APIENTRYP PFNGLMATRIXLOADTRANSPOSEDEXTPROC) (GLenum mode, const GLdouble *m);
+typedef void (APIENTRYP PFNGLMATRIXMULTTRANSPOSEFEXTPROC) (GLenum mode, const GLfloat *m);
+typedef void (APIENTRYP PFNGLMATRIXMULTTRANSPOSEDEXTPROC) (GLenum mode, const GLdouble *m);
+typedef void (APIENTRYP PFNGLTEXTUREPARAMETERFEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLTEXTUREPARAMETERFVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLTEXTUREPARAMETERIEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLTEXTUREPARAMETERIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLTEXTUREIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (APIENTRYP PFNGLTEXTUREIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (APIENTRYP PFNGLTEXTURESUBIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (APIENTRYP PFNGLTEXTURESUBIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (APIENTRYP PFNGLCOPYTEXTUREIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border);
+typedef void (APIENTRYP PFNGLCOPYTEXTUREIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
+typedef void (APIENTRYP PFNGLCOPYTEXTURESUBIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width);
+typedef void (APIENTRYP PFNGLCOPYTEXTURESUBIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (APIENTRYP PFNGLGETTEXTUREIMAGEEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels);
+typedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERFVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETTEXTURELEVELPARAMETERFVEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETTEXTURELEVELPARAMETERIVEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLTEXTUREIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (APIENTRYP PFNGLTEXTURESUBIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (APIENTRYP PFNGLCOPYTEXTURESUBIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (APIENTRYP PFNGLMULTITEXPARAMETERFEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLMULTITEXPARAMETERFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLMULTITEXPARAMETERIEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLMULTITEXPARAMETERIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLMULTITEXIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (APIENTRYP PFNGLMULTITEXIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (APIENTRYP PFNGLMULTITEXSUBIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (APIENTRYP PFNGLMULTITEXSUBIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (APIENTRYP PFNGLCOPYMULTITEXIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border);
+typedef void (APIENTRYP PFNGLCOPYMULTITEXIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
+typedef void (APIENTRYP PFNGLCOPYMULTITEXSUBIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width);
+typedef void (APIENTRYP PFNGLCOPYMULTITEXSUBIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (APIENTRYP PFNGLGETMULTITEXIMAGEEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels);
+typedef void (APIENTRYP PFNGLGETMULTITEXPARAMETERFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETMULTITEXPARAMETERIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETMULTITEXLEVELPARAMETERFVEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETMULTITEXLEVELPARAMETERIVEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLMULTITEXIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (APIENTRYP PFNGLMULTITEXSUBIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (APIENTRYP PFNGLCOPYMULTITEXSUBIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (APIENTRYP PFNGLBINDMULTITEXTUREEXTPROC) (GLenum texunit, GLenum target, GLuint texture);
+typedef void (APIENTRYP PFNGLENABLECLIENTSTATEINDEXEDEXTPROC) (GLenum array, GLuint index);
+typedef void (APIENTRYP PFNGLDISABLECLIENTSTATEINDEXEDEXTPROC) (GLenum array, GLuint index);
+typedef void (APIENTRYP PFNGLMULTITEXCOORDPOINTEREXTPROC) (GLenum texunit, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLMULTITEXENVFEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLMULTITEXENVFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLMULTITEXENVIEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLMULTITEXENVIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLMULTITEXGENDEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLdouble param);
+typedef void (APIENTRYP PFNGLMULTITEXGENDVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, const GLdouble *params);
+typedef void (APIENTRYP PFNGLMULTITEXGENFEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLMULTITEXGENFVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLMULTITEXGENIEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLMULTITEXGENIVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLGETMULTITEXENVFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETMULTITEXENVIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETMULTITEXGENDVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLdouble *params);
+typedef void (APIENTRYP PFNGLGETMULTITEXGENFVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETMULTITEXGENIVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETFLOATINDEXEDVEXTPROC) (GLenum target, GLuint index, GLfloat *data);
+typedef void (APIENTRYP PFNGLGETDOUBLEINDEXEDVEXTPROC) (GLenum target, GLuint index, GLdouble *data);
+typedef void (APIENTRYP PFNGLGETPOINTERINDEXEDVEXTPROC) (GLenum target, GLuint index, GLvoid* *data);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTUREIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *bits);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTUREIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *bits);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTUREIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *bits);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTURESUBIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *bits);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTURESUBIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *bits);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTURESUBIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *bits);
+typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXTUREIMAGEEXTPROC) (GLuint texture, GLenum target, GLint lod, GLvoid *img);
+typedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *bits);
+typedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *bits);
+typedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *bits);
+typedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXSUBIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *bits);
+typedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXSUBIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *bits);
+typedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXSUBIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *bits);
+typedef void (APIENTRYP PFNGLGETCOMPRESSEDMULTITEXIMAGEEXTPROC) (GLenum texunit, GLenum target, GLint lod, GLvoid *img);
+typedef void (APIENTRYP PFNGLNAMEDPROGRAMSTRINGEXTPROC) (GLuint program, GLenum target, GLenum format, GLsizei len, const GLvoid *string);
+typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETER4DEXTPROC) (GLuint program, GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETER4DVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLdouble *params);
+typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETER4FEXTPROC) (GLuint program, GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETER4FVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLfloat *params);
+typedef void (APIENTRYP PFNGLGETNAMEDPROGRAMLOCALPARAMETERDVEXTPROC) (GLuint program, GLenum target, GLuint index, GLdouble *params);
+typedef void (APIENTRYP PFNGLGETNAMEDPROGRAMLOCALPARAMETERFVEXTPROC) (GLuint program, GLenum target, GLuint index, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETNAMEDPROGRAMIVEXTPROC) (GLuint program, GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETNAMEDPROGRAMSTRINGEXTPROC) (GLuint program, GLenum target, GLenum pname, GLvoid *string);
+typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERS4FVEXTPROC) (GLuint program, GLenum target, GLuint index, GLsizei count, const GLfloat *params);
+typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERI4IEXTPROC) (GLuint program, GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w);
+typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERI4IVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLint *params);
+typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERSI4IVEXTPROC) (GLuint program, GLenum target, GLuint index, GLsizei count, const GLint *params);
+typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIEXTPROC) (GLuint program, GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
+typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLuint *params);
+typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERSI4UIVEXTPROC) (GLuint program, GLenum target, GLuint index, GLsizei count, const GLuint *params);
+typedef void (APIENTRYP PFNGLGETNAMEDPROGRAMLOCALPARAMETERIIVEXTPROC) (GLuint program, GLenum target, GLuint index, GLint *params);
+typedef void (APIENTRYP PFNGLGETNAMEDPROGRAMLOCALPARAMETERIUIVEXTPROC) (GLuint program, GLenum target, GLuint index, GLuint *params);
+typedef void (APIENTRYP PFNGLTEXTUREPARAMETERIIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLTEXTUREPARAMETERIUIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLuint *params);
+typedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERIIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERIUIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLuint *params);
+typedef void (APIENTRYP PFNGLMULTITEXPARAMETERIIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLMULTITEXPARAMETERIUIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLuint *params);
+typedef void (APIENTRYP PFNGLGETMULTITEXPARAMETERIIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETMULTITEXPARAMETERIUIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLuint *params);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1FEXTPROC) (GLuint program, GLint location, GLfloat v0);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1IEXTPROC) (GLuint program, GLint location, GLint v0);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UIEXTPROC) (GLuint program, GLint location, GLuint v0);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value);
+typedef void (APIENTRYP PFNGLNAMEDBUFFERDATAEXTPROC) (GLuint buffer, GLsizeiptr size, const GLvoid *data, GLenum usage);
+typedef void (APIENTRYP PFNGLNAMEDBUFFERSUBDATAEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, const GLvoid *data);
+typedef GLvoid* (APIENTRYP PFNGLMAPNAMEDBUFFEREXTPROC) (GLuint buffer, GLenum access);
+typedef GLboolean (APIENTRYP PFNGLUNMAPNAMEDBUFFEREXTPROC) (GLuint buffer);
+typedef GLvoid* (APIENTRYP PFNGLMAPNAMEDBUFFERRANGEEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr length, GLbitfield access);
+typedef void (APIENTRYP PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr length);
+typedef void (APIENTRYP PFNGLNAMEDCOPYBUFFERSUBDATAEXTPROC) (GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
+typedef void (APIENTRYP PFNGLGETNAMEDBUFFERPARAMETERIVEXTPROC) (GLuint buffer, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETNAMEDBUFFERPOINTERVEXTPROC) (GLuint buffer, GLenum pname, GLvoid* *params);
+typedef void (APIENTRYP PFNGLGETNAMEDBUFFERSUBDATAEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, GLvoid *data);
+typedef void (APIENTRYP PFNGLTEXTUREBUFFEREXTPROC) (GLuint texture, GLenum target, GLenum internalformat, GLuint buffer);
+typedef void (APIENTRYP PFNGLMULTITEXBUFFEREXTPROC) (GLenum texunit, GLenum target, GLenum internalformat, GLuint buffer);
+typedef void (APIENTRYP PFNGLNAMEDRENDERBUFFERSTORAGEEXTPROC) (GLuint renderbuffer, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (APIENTRYP PFNGLGETNAMEDRENDERBUFFERPARAMETERIVEXTPROC) (GLuint renderbuffer, GLenum pname, GLint *params);
+typedef GLenum (APIENTRYP PFNGLCHECKNAMEDFRAMEBUFFERSTATUSEXTPROC) (GLuint framebuffer, GLenum target);
+typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTURE1DEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTURE2DEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTURE3DEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset);
+typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERRENDERBUFFEREXTPROC) (GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+typedef void (APIENTRYP PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGENERATETEXTUREMIPMAPEXTPROC) (GLuint texture, GLenum target);
+typedef void (APIENTRYP PFNGLGENERATEMULTITEXMIPMAPEXTPROC) (GLenum texunit, GLenum target);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERDRAWBUFFEREXTPROC) (GLuint framebuffer, GLenum mode);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERDRAWBUFFERSEXTPROC) (GLuint framebuffer, GLsizei n, const GLenum *bufs);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERREADBUFFEREXTPROC) (GLuint framebuffer, GLenum mode);
+typedef void (APIENTRYP PFNGLGETFRAMEBUFFERPARAMETERIVEXTPROC) (GLuint framebuffer, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) (GLuint renderbuffer, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (APIENTRYP PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLECOVERAGEEXTPROC) (GLuint renderbuffer, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTUREEXTPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level);
+typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTURELAYEREXTPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLint layer);
+typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTUREFACEEXTPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLenum face);
+typedef void (APIENTRYP PFNGLTEXTURERENDERBUFFEREXTPROC) (GLuint texture, GLenum target, GLuint renderbuffer);
+typedef void (APIENTRYP PFNGLMULTITEXRENDERBUFFEREXTPROC) (GLenum texunit, GLenum target, GLuint renderbuffer);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1DEXTPROC) (GLuint program, GLint location, GLdouble x);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2DEXTPROC) (GLuint program, GLint location, GLdouble x, GLdouble y);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3DEXTPROC) (GLuint program, GLint location, GLdouble x, GLdouble y, GLdouble z);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4DEXTPROC) (GLuint program, GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1DVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2DVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3DVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4DVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X3DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X4DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X2DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X4DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X2DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X3DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+#endif
+
+#ifndef GL_EXT_vertex_array_bgra
+#define GL_EXT_vertex_array_bgra 1
+#endif
+
+#ifndef GL_EXT_texture_swizzle
+#define GL_EXT_texture_swizzle 1
+#endif
+
+#ifndef GL_NV_explicit_multisample
+#define GL_NV_explicit_multisample 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGetMultisamplefvNV (GLenum pname, GLuint index, GLfloat *val);
+GLAPI void APIENTRY glSampleMaskIndexedNV (GLuint index, GLbitfield mask);
+GLAPI void APIENTRY glTexRenderbufferNV (GLenum target, GLuint renderbuffer);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLGETMULTISAMPLEFVNVPROC) (GLenum pname, GLuint index, GLfloat *val);
+typedef void (APIENTRYP PFNGLSAMPLEMASKINDEXEDNVPROC) (GLuint index, GLbitfield mask);
+typedef void (APIENTRYP PFNGLTEXRENDERBUFFERNVPROC) (GLenum target, GLuint renderbuffer);
+#endif
+
+#ifndef GL_NV_transform_feedback2
+#define GL_NV_transform_feedback2 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBindTransformFeedbackNV (GLenum target, GLuint id);
+GLAPI void APIENTRY glDeleteTransformFeedbacksNV (GLsizei n, const GLuint *ids);
+GLAPI void APIENTRY glGenTransformFeedbacksNV (GLsizei n, GLuint *ids);
+GLAPI GLboolean APIENTRY glIsTransformFeedbackNV (GLuint id);
+GLAPI void APIENTRY glPauseTransformFeedbackNV (void);
+GLAPI void APIENTRY glResumeTransformFeedbackNV (void);
+GLAPI void APIENTRY glDrawTransformFeedbackNV (GLenum mode, GLuint id);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBINDTRANSFORMFEEDBACKNVPROC) (GLenum target, GLuint id);
+typedef void (APIENTRYP PFNGLDELETETRANSFORMFEEDBACKSNVPROC) (GLsizei n, const GLuint *ids);
+typedef void (APIENTRYP PFNGLGENTRANSFORMFEEDBACKSNVPROC) (GLsizei n, GLuint *ids);
+typedef GLboolean (APIENTRYP PFNGLISTRANSFORMFEEDBACKNVPROC) (GLuint id);
+typedef void (APIENTRYP PFNGLPAUSETRANSFORMFEEDBACKNVPROC) (void);
+typedef void (APIENTRYP PFNGLRESUMETRANSFORMFEEDBACKNVPROC) (void);
+typedef void (APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKNVPROC) (GLenum mode, GLuint id);
+#endif
+
+#ifndef GL_ATI_meminfo
+#define GL_ATI_meminfo 1
+#endif
+
+#ifndef GL_AMD_performance_monitor
+#define GL_AMD_performance_monitor 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGetPerfMonitorGroupsAMD (GLint *numGroups, GLsizei groupsSize, GLuint *groups);
+GLAPI void APIENTRY glGetPerfMonitorCountersAMD (GLuint group, GLint *numCounters, GLint *maxActiveCounters, GLsizei counterSize, GLuint *counters);
+GLAPI void APIENTRY glGetPerfMonitorGroupStringAMD (GLuint group, GLsizei bufSize, GLsizei *length, GLchar *groupString);
+GLAPI void APIENTRY glGetPerfMonitorCounterStringAMD (GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, GLchar *counterString);
+GLAPI void APIENTRY glGetPerfMonitorCounterInfoAMD (GLuint group, GLuint counter, GLenum pname, GLvoid *data);
+GLAPI void APIENTRY glGenPerfMonitorsAMD (GLsizei n, GLuint *monitors);
+GLAPI void APIENTRY glDeletePerfMonitorsAMD (GLsizei n, GLuint *monitors);
+GLAPI void APIENTRY glSelectPerfMonitorCountersAMD (GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint *counterList);
+GLAPI void APIENTRY glBeginPerfMonitorAMD (GLuint monitor);
+GLAPI void APIENTRY glEndPerfMonitorAMD (GLuint monitor);
+GLAPI void APIENTRY glGetPerfMonitorCounterDataAMD (GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, GLint *bytesWritten);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLGETPERFMONITORGROUPSAMDPROC) (GLint *numGroups, GLsizei groupsSize, GLuint *groups);
+typedef void (APIENTRYP PFNGLGETPERFMONITORCOUNTERSAMDPROC) (GLuint group, GLint *numCounters, GLint *maxActiveCounters, GLsizei counterSize, GLuint *counters);
+typedef void (APIENTRYP PFNGLGETPERFMONITORGROUPSTRINGAMDPROC) (GLuint group, GLsizei bufSize, GLsizei *length, GLchar *groupString);
+typedef void (APIENTRYP PFNGLGETPERFMONITORCOUNTERSTRINGAMDPROC) (GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, GLchar *counterString);
+typedef void (APIENTRYP PFNGLGETPERFMONITORCOUNTERINFOAMDPROC) (GLuint group, GLuint counter, GLenum pname, GLvoid *data);
+typedef void (APIENTRYP PFNGLGENPERFMONITORSAMDPROC) (GLsizei n, GLuint *monitors);
+typedef void (APIENTRYP PFNGLDELETEPERFMONITORSAMDPROC) (GLsizei n, GLuint *monitors);
+typedef void (APIENTRYP PFNGLSELECTPERFMONITORCOUNTERSAMDPROC) (GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint *counterList);
+typedef void (APIENTRYP PFNGLBEGINPERFMONITORAMDPROC) (GLuint monitor);
+typedef void (APIENTRYP PFNGLENDPERFMONITORAMDPROC) (GLuint monitor);
+typedef void (APIENTRYP PFNGLGETPERFMONITORCOUNTERDATAAMDPROC) (GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, GLint *bytesWritten);
+#endif
+
+#ifndef GL_AMD_texture_texture4
+#define GL_AMD_texture_texture4 1
+#endif
+
+#ifndef GL_AMD_vertex_shader_tesselator
+#define GL_AMD_vertex_shader_tesselator 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTessellationFactorAMD (GLfloat factor);
+GLAPI void APIENTRY glTessellationModeAMD (GLenum mode);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLTESSELLATIONFACTORAMDPROC) (GLfloat factor);
+typedef void (APIENTRYP PFNGLTESSELLATIONMODEAMDPROC) (GLenum mode);
+#endif
+
+#ifndef GL_EXT_provoking_vertex
+#define GL_EXT_provoking_vertex 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glProvokingVertexEXT (GLenum mode);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPROVOKINGVERTEXEXTPROC) (GLenum mode);
+#endif
+
+#ifndef GL_EXT_texture_snorm
+#define GL_EXT_texture_snorm 1
+#endif
+
+#ifndef GL_AMD_draw_buffers_blend
+#define GL_AMD_draw_buffers_blend 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBlendFuncIndexedAMD (GLuint buf, GLenum src, GLenum dst);
+GLAPI void APIENTRY glBlendFuncSeparateIndexedAMD (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+GLAPI void APIENTRY glBlendEquationIndexedAMD (GLuint buf, GLenum mode);
+GLAPI void APIENTRY glBlendEquationSeparateIndexedAMD (GLuint buf, GLenum modeRGB, GLenum modeAlpha);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBLENDFUNCINDEXEDAMDPROC) (GLuint buf, GLenum src, GLenum dst);
+typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEINDEXEDAMDPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+typedef void (APIENTRYP PFNGLBLENDEQUATIONINDEXEDAMDPROC) (GLuint buf, GLenum mode);
+typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEINDEXEDAMDPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha);
+#endif
+
+#ifndef GL_APPLE_texture_range
+#define GL_APPLE_texture_range 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTextureRangeAPPLE (GLenum target, GLsizei length, const GLvoid *pointer);
+GLAPI void APIENTRY glGetTexParameterPointervAPPLE (GLenum target, GLenum pname, GLvoid* *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLTEXTURERANGEAPPLEPROC) (GLenum target, GLsizei length, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLGETTEXPARAMETERPOINTERVAPPLEPROC) (GLenum target, GLenum pname, GLvoid* *params);
+#endif
+
+#ifndef GL_APPLE_float_pixels
+#define GL_APPLE_float_pixels 1
+#endif
+
+#ifndef GL_APPLE_vertex_program_evaluators
+#define GL_APPLE_vertex_program_evaluators 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glEnableVertexAttribAPPLE (GLuint index, GLenum pname);
+GLAPI void APIENTRY glDisableVertexAttribAPPLE (GLuint index, GLenum pname);
+GLAPI GLboolean APIENTRY glIsVertexAttribEnabledAPPLE (GLuint index, GLenum pname);
+GLAPI void APIENTRY glMapVertexAttrib1dAPPLE (GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points);
+GLAPI void APIENTRY glMapVertexAttrib1fAPPLE (GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points);
+GLAPI void APIENTRY glMapVertexAttrib2dAPPLE (GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points);
+GLAPI void APIENTRY glMapVertexAttrib2fAPPLE (GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLENABLEVERTEXATTRIBAPPLEPROC) (GLuint index, GLenum pname);
+typedef void (APIENTRYP PFNGLDISABLEVERTEXATTRIBAPPLEPROC) (GLuint index, GLenum pname);
+typedef GLboolean (APIENTRYP PFNGLISVERTEXATTRIBENABLEDAPPLEPROC) (GLuint index, GLenum pname);
+typedef void (APIENTRYP PFNGLMAPVERTEXATTRIB1DAPPLEPROC) (GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points);
+typedef void (APIENTRYP PFNGLMAPVERTEXATTRIB1FAPPLEPROC) (GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points);
+typedef void (APIENTRYP PFNGLMAPVERTEXATTRIB2DAPPLEPROC) (GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points);
+typedef void (APIENTRYP PFNGLMAPVERTEXATTRIB2FAPPLEPROC) (GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points);
+#endif
+
+#ifndef GL_APPLE_aux_depth_stencil
+#define GL_APPLE_aux_depth_stencil 1
+#endif
+
+#ifndef GL_APPLE_object_purgeable
+#define GL_APPLE_object_purgeable 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI GLenum APIENTRY glObjectPurgeableAPPLE (GLenum objectType, GLuint name, GLenum option);
+GLAPI GLenum APIENTRY glObjectUnpurgeableAPPLE (GLenum objectType, GLuint name, GLenum option);
+GLAPI void APIENTRY glGetObjectParameterivAPPLE (GLenum objectType, GLuint name, GLenum pname, GLint *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef GLenum (APIENTRYP PFNGLOBJECTPURGEABLEAPPLEPROC) (GLenum objectType, GLuint name, GLenum option);
+typedef GLenum (APIENTRYP PFNGLOBJECTUNPURGEABLEAPPLEPROC) (GLenum objectType, GLuint name, GLenum option);
+typedef void (APIENTRYP PFNGLGETOBJECTPARAMETERIVAPPLEPROC) (GLenum objectType, GLuint name, GLenum pname, GLint *params);
+#endif
+
+#ifndef GL_APPLE_row_bytes
+#define GL_APPLE_row_bytes 1
+#endif
+
+#ifndef GL_APPLE_rgb_422
+#define GL_APPLE_rgb_422 1
+#endif
+
+#ifndef GL_NV_video_capture
+#define GL_NV_video_capture 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBeginVideoCaptureNV (GLuint video_capture_slot);
+GLAPI void APIENTRY glBindVideoCaptureStreamBufferNV (GLuint video_capture_slot, GLuint stream, GLenum frame_region, GLintptrARB offset);
+GLAPI void APIENTRY glBindVideoCaptureStreamTextureNV (GLuint video_capture_slot, GLuint stream, GLenum frame_region, GLenum target, GLuint texture);
+GLAPI void APIENTRY glEndVideoCaptureNV (GLuint video_capture_slot);
+GLAPI void APIENTRY glGetVideoCaptureivNV (GLuint video_capture_slot, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetVideoCaptureStreamivNV (GLuint video_capture_slot, GLuint stream, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetVideoCaptureStreamfvNV (GLuint video_capture_slot, GLuint stream, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetVideoCaptureStreamdvNV (GLuint video_capture_slot, GLuint stream, GLenum pname, GLdouble *params);
+GLAPI GLenum APIENTRY glVideoCaptureNV (GLuint video_capture_slot, GLuint *sequence_num, GLuint64EXT *capture_time);
+GLAPI void APIENTRY glVideoCaptureStreamParameterivNV (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLint *params);
+GLAPI void APIENTRY glVideoCaptureStreamParameterfvNV (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLfloat *params);
+GLAPI void APIENTRY glVideoCaptureStreamParameterdvNV (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLdouble *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBEGINVIDEOCAPTURENVPROC) (GLuint video_capture_slot);
+typedef void (APIENTRYP PFNGLBINDVIDEOCAPTURESTREAMBUFFERNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum frame_region, GLintptrARB offset);
+typedef void (APIENTRYP PFNGLBINDVIDEOCAPTURESTREAMTEXTURENVPROC) (GLuint video_capture_slot, GLuint stream, GLenum frame_region, GLenum target, GLuint texture);
+typedef void (APIENTRYP PFNGLENDVIDEOCAPTURENVPROC) (GLuint video_capture_slot);
+typedef void (APIENTRYP PFNGLGETVIDEOCAPTUREIVNVPROC) (GLuint video_capture_slot, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETVIDEOCAPTURESTREAMIVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETVIDEOCAPTURESTREAMFVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETVIDEOCAPTURESTREAMDVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, GLdouble *params);
+typedef GLenum (APIENTRYP PFNGLVIDEOCAPTURENVPROC) (GLuint video_capture_slot, GLuint *sequence_num, GLuint64EXT *capture_time);
+typedef void (APIENTRYP PFNGLVIDEOCAPTURESTREAMPARAMETERIVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLVIDEOCAPTURESTREAMPARAMETERFVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLVIDEOCAPTURESTREAMPARAMETERDVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLdouble *params);
+#endif
+
+#ifndef GL_NV_copy_image
+#define GL_NV_copy_image 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glCopyImageSubDataNV (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLCOPYIMAGESUBDATANVPROC) (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth);
+#endif
+
+#ifndef GL_EXT_separate_shader_objects
+#define GL_EXT_separate_shader_objects 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glUseShaderProgramEXT (GLenum type, GLuint program);
+GLAPI void APIENTRY glActiveProgramEXT (GLuint program);
+GLAPI GLuint APIENTRY glCreateShaderProgramEXT (GLenum type, const GLchar *string);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLUSESHADERPROGRAMEXTPROC) (GLenum type, GLuint program);
+typedef void (APIENTRYP PFNGLACTIVEPROGRAMEXTPROC) (GLuint program);
+typedef GLuint (APIENTRYP PFNGLCREATESHADERPROGRAMEXTPROC) (GLenum type, const GLchar *string);
+#endif
+
+#ifndef GL_NV_parameter_buffer_object2
+#define GL_NV_parameter_buffer_object2 1
+#endif
+
+#ifndef GL_NV_shader_buffer_load
+#define GL_NV_shader_buffer_load 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glMakeBufferResidentNV (GLenum target, GLenum access);
+GLAPI void APIENTRY glMakeBufferNonResidentNV (GLenum target);
+GLAPI GLboolean APIENTRY glIsBufferResidentNV (GLenum target);
+GLAPI void APIENTRY glMakeNamedBufferResidentNV (GLuint buffer, GLenum access);
+GLAPI void APIENTRY glMakeNamedBufferNonResidentNV (GLuint buffer);
+GLAPI GLboolean APIENTRY glIsNamedBufferResidentNV (GLuint buffer);
+GLAPI void APIENTRY glGetBufferParameterui64vNV (GLenum target, GLenum pname, GLuint64EXT *params);
+GLAPI void APIENTRY glGetNamedBufferParameterui64vNV (GLuint buffer, GLenum pname, GLuint64EXT *params);
+GLAPI void APIENTRY glGetIntegerui64vNV (GLenum value, GLuint64EXT *result);
+GLAPI void APIENTRY glUniformui64NV (GLint location, GLuint64EXT value);
+GLAPI void APIENTRY glUniformui64vNV (GLint location, GLsizei count, const GLuint64EXT *value);
+GLAPI void APIENTRY glGetUniformui64vNV (GLuint program, GLint location, GLuint64EXT *params);
+GLAPI void APIENTRY glProgramUniformui64NV (GLuint program, GLint location, GLuint64EXT value);
+GLAPI void APIENTRY glProgramUniformui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLMAKEBUFFERRESIDENTNVPROC) (GLenum target, GLenum access);
+typedef void (APIENTRYP PFNGLMAKEBUFFERNONRESIDENTNVPROC) (GLenum target);
+typedef GLboolean (APIENTRYP PFNGLISBUFFERRESIDENTNVPROC) (GLenum target);
+typedef void (APIENTRYP PFNGLMAKENAMEDBUFFERRESIDENTNVPROC) (GLuint buffer, GLenum access);
+typedef void (APIENTRYP PFNGLMAKENAMEDBUFFERNONRESIDENTNVPROC) (GLuint buffer);
+typedef GLboolean (APIENTRYP PFNGLISNAMEDBUFFERRESIDENTNVPROC) (GLuint buffer);
+typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERUI64VNVPROC) (GLenum target, GLenum pname, GLuint64EXT *params);
+typedef void (APIENTRYP PFNGLGETNAMEDBUFFERPARAMETERUI64VNVPROC) (GLuint buffer, GLenum pname, GLuint64EXT *params);
+typedef void (APIENTRYP PFNGLGETINTEGERUI64VNVPROC) (GLenum value, GLuint64EXT *result);
+typedef void (APIENTRYP PFNGLUNIFORMUI64NVPROC) (GLint location, GLuint64EXT value);
+typedef void (APIENTRYP PFNGLUNIFORMUI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT *value);
+typedef void (APIENTRYP PFNGLGETUNIFORMUI64VNVPROC) (GLuint program, GLint location, GLuint64EXT *params);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMUI64NVPROC) (GLuint program, GLint location, GLuint64EXT value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMUI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value);
+#endif
+
+#ifndef GL_NV_vertex_buffer_unified_memory
+#define GL_NV_vertex_buffer_unified_memory 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBufferAddressRangeNV (GLenum pname, GLuint index, GLuint64EXT address, GLsizeiptr length);
+GLAPI void APIENTRY glVertexFormatNV (GLint size, GLenum type, GLsizei stride);
+GLAPI void APIENTRY glNormalFormatNV (GLenum type, GLsizei stride);
+GLAPI void APIENTRY glColorFormatNV (GLint size, GLenum type, GLsizei stride);
+GLAPI void APIENTRY glIndexFormatNV (GLenum type, GLsizei stride);
+GLAPI void APIENTRY glTexCoordFormatNV (GLint size, GLenum type, GLsizei stride);
+GLAPI void APIENTRY glEdgeFlagFormatNV (GLsizei stride);
+GLAPI void APIENTRY glSecondaryColorFormatNV (GLint size, GLenum type, GLsizei stride);
+GLAPI void APIENTRY glFogCoordFormatNV (GLenum type, GLsizei stride);
+GLAPI void APIENTRY glVertexAttribFormatNV (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride);
+GLAPI void APIENTRY glVertexAttribIFormatNV (GLuint index, GLint size, GLenum type, GLsizei stride);
+GLAPI void APIENTRY glGetIntegerui64i_vNV (GLenum value, GLuint index, GLuint64EXT *result);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBUFFERADDRESSRANGENVPROC) (GLenum pname, GLuint index, GLuint64EXT address, GLsizeiptr length);
+typedef void (APIENTRYP PFNGLVERTEXFORMATNVPROC) (GLint size, GLenum type, GLsizei stride);
+typedef void (APIENTRYP PFNGLNORMALFORMATNVPROC) (GLenum type, GLsizei stride);
+typedef void (APIENTRYP PFNGLCOLORFORMATNVPROC) (GLint size, GLenum type, GLsizei stride);
+typedef void (APIENTRYP PFNGLINDEXFORMATNVPROC) (GLenum type, GLsizei stride);
+typedef void (APIENTRYP PFNGLTEXCOORDFORMATNVPROC) (GLint size, GLenum type, GLsizei stride);
+typedef void (APIENTRYP PFNGLEDGEFLAGFORMATNVPROC) (GLsizei stride);
+typedef void (APIENTRYP PFNGLSECONDARYCOLORFORMATNVPROC) (GLint size, GLenum type, GLsizei stride);
+typedef void (APIENTRYP PFNGLFOGCOORDFORMATNVPROC) (GLenum type, GLsizei stride);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBFORMATNVPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBIFORMATNVPROC) (GLuint index, GLint size, GLenum type, GLsizei stride);
+typedef void (APIENTRYP PFNGLGETINTEGERUI64I_VNVPROC) (GLenum value, GLuint index, GLuint64EXT *result);
+#endif
+
+#ifndef GL_NV_texture_barrier
+#define GL_NV_texture_barrier 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTextureBarrierNV (void);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLTEXTUREBARRIERNVPROC) (void);
+#endif
+
+#ifndef GL_AMD_shader_stencil_export
+#define GL_AMD_shader_stencil_export 1
+#endif
+
+#ifndef GL_AMD_seamless_cubemap_per_texture
+#define GL_AMD_seamless_cubemap_per_texture 1
+#endif
+
+#ifndef GL_AMD_conservative_depth
+#define GL_AMD_conservative_depth 1
+#endif
+
+#ifndef GL_EXT_shader_image_load_store
+#define GL_EXT_shader_image_load_store 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBindImageTextureEXT (GLuint index, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLint format);
+GLAPI void APIENTRY glMemoryBarrierEXT (GLbitfield barriers);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBINDIMAGETEXTUREEXTPROC) (GLuint index, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLint format);
+typedef void (APIENTRYP PFNGLMEMORYBARRIEREXTPROC) (GLbitfield barriers);
+#endif
+
+#ifndef GL_EXT_vertex_attrib_64bit
+#define GL_EXT_vertex_attrib_64bit 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glVertexAttribL1dEXT (GLuint index, GLdouble x);
+GLAPI void APIENTRY glVertexAttribL2dEXT (GLuint index, GLdouble x, GLdouble y);
+GLAPI void APIENTRY glVertexAttribL3dEXT (GLuint index, GLdouble x, GLdouble y, GLdouble z);
+GLAPI void APIENTRY glVertexAttribL4dEXT (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+GLAPI void APIENTRY glVertexAttribL1dvEXT (GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttribL2dvEXT (GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttribL3dvEXT (GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttribL4dvEXT (GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttribLPointerEXT (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+GLAPI void APIENTRY glGetVertexAttribLdvEXT (GLuint index, GLenum pname, GLdouble *params);
+GLAPI void APIENTRY glVertexArrayVertexAttribLOffsetEXT (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr offset);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL1DEXTPROC) (GLuint index, GLdouble x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL2DEXTPROC) (GLuint index, GLdouble x, GLdouble y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL3DEXTPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL4DEXTPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL1DVEXTPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL2DVEXTPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL3DVEXTPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL4DVEXTPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBLPOINTEREXTPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBLDVEXTPROC) (GLuint index, GLenum pname, GLdouble *params);
+typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXATTRIBLOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr offset);
+#endif
+
+#ifndef GL_NV_gpu_program5
+#define GL_NV_gpu_program5 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glProgramSubroutineParametersuivNV (GLenum target, GLsizei count, const GLuint *params);
+GLAPI void APIENTRY glGetProgramSubroutineParameteruivNV (GLenum target, GLuint index, GLuint *param);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPROGRAMSUBROUTINEPARAMETERSUIVNVPROC) (GLenum target, GLsizei count, const GLuint *params);
+typedef void (APIENTRYP PFNGLGETPROGRAMSUBROUTINEPARAMETERUIVNVPROC) (GLenum target, GLuint index, GLuint *param);
+#endif
+
+#ifndef GL_NV_gpu_shader5
+#define GL_NV_gpu_shader5 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glUniform1i64NV (GLint location, GLint64EXT x);
+GLAPI void APIENTRY glUniform2i64NV (GLint location, GLint64EXT x, GLint64EXT y);
+GLAPI void APIENTRY glUniform3i64NV (GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z);
+GLAPI void APIENTRY glUniform4i64NV (GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w);
+GLAPI void APIENTRY glUniform1i64vNV (GLint location, GLsizei count, const GLint64EXT *value);
+GLAPI void APIENTRY glUniform2i64vNV (GLint location, GLsizei count, const GLint64EXT *value);
+GLAPI void APIENTRY glUniform3i64vNV (GLint location, GLsizei count, const GLint64EXT *value);
+GLAPI void APIENTRY glUniform4i64vNV (GLint location, GLsizei count, const GLint64EXT *value);
+GLAPI void APIENTRY glUniform1ui64NV (GLint location, GLuint64EXT x);
+GLAPI void APIENTRY glUniform2ui64NV (GLint location, GLuint64EXT x, GLuint64EXT y);
+GLAPI void APIENTRY glUniform3ui64NV (GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z);
+GLAPI void APIENTRY glUniform4ui64NV (GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w);
+GLAPI void APIENTRY glUniform1ui64vNV (GLint location, GLsizei count, const GLuint64EXT *value);
+GLAPI void APIENTRY glUniform2ui64vNV (GLint location, GLsizei count, const GLuint64EXT *value);
+GLAPI void APIENTRY glUniform3ui64vNV (GLint location, GLsizei count, const GLuint64EXT *value);
+GLAPI void APIENTRY glUniform4ui64vNV (GLint location, GLsizei count, const GLuint64EXT *value);
+GLAPI void APIENTRY glGetUniformi64vNV (GLuint program, GLint location, GLint64EXT *params);
+GLAPI void APIENTRY glProgramUniform1i64NV (GLuint program, GLint location, GLint64EXT x);
+GLAPI void APIENTRY glProgramUniform2i64NV (GLuint program, GLint location, GLint64EXT x, GLint64EXT y);
+GLAPI void APIENTRY glProgramUniform3i64NV (GLuint program, GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z);
+GLAPI void APIENTRY glProgramUniform4i64NV (GLuint program, GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w);
+GLAPI void APIENTRY glProgramUniform1i64vNV (GLuint program, GLint location, GLsizei count, const GLint64EXT *value);
+GLAPI void APIENTRY glProgramUniform2i64vNV (GLuint program, GLint location, GLsizei count, const GLint64EXT *value);
+GLAPI void APIENTRY glProgramUniform3i64vNV (GLuint program, GLint location, GLsizei count, const GLint64EXT *value);
+GLAPI void APIENTRY glProgramUniform4i64vNV (GLuint program, GLint location, GLsizei count, const GLint64EXT *value);
+GLAPI void APIENTRY glProgramUniform1ui64NV (GLuint program, GLint location, GLuint64EXT x);
+GLAPI void APIENTRY glProgramUniform2ui64NV (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y);
+GLAPI void APIENTRY glProgramUniform3ui64NV (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z);
+GLAPI void APIENTRY glProgramUniform4ui64NV (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w);
+GLAPI void APIENTRY glProgramUniform1ui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value);
+GLAPI void APIENTRY glProgramUniform2ui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value);
+GLAPI void APIENTRY glProgramUniform3ui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value);
+GLAPI void APIENTRY glProgramUniform4ui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLUNIFORM1I64NVPROC) (GLint location, GLint64EXT x);
+typedef void (APIENTRYP PFNGLUNIFORM2I64NVPROC) (GLint location, GLint64EXT x, GLint64EXT y);
+typedef void (APIENTRYP PFNGLUNIFORM3I64NVPROC) (GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z);
+typedef void (APIENTRYP PFNGLUNIFORM4I64NVPROC) (GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w);
+typedef void (APIENTRYP PFNGLUNIFORM1I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT *value);
+typedef void (APIENTRYP PFNGLUNIFORM2I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT *value);
+typedef void (APIENTRYP PFNGLUNIFORM3I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT *value);
+typedef void (APIENTRYP PFNGLUNIFORM4I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT *value);
+typedef void (APIENTRYP PFNGLUNIFORM1UI64NVPROC) (GLint location, GLuint64EXT x);
+typedef void (APIENTRYP PFNGLUNIFORM2UI64NVPROC) (GLint location, GLuint64EXT x, GLuint64EXT y);
+typedef void (APIENTRYP PFNGLUNIFORM3UI64NVPROC) (GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z);
+typedef void (APIENTRYP PFNGLUNIFORM4UI64NVPROC) (GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w);
+typedef void (APIENTRYP PFNGLUNIFORM1UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT *value);
+typedef void (APIENTRYP PFNGLUNIFORM2UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT *value);
+typedef void (APIENTRYP PFNGLUNIFORM3UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT *value);
+typedef void (APIENTRYP PFNGLUNIFORM4UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT *value);
+typedef void (APIENTRYP PFNGLGETUNIFORMI64VNVPROC) (GLuint program, GLint location, GLint64EXT *params);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1I64NVPROC) (GLuint program, GLint location, GLint64EXT x);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2I64NVPROC) (GLuint program, GLint location, GLint64EXT x, GLint64EXT y);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3I64NVPROC) (GLuint program, GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4I64NVPROC) (GLuint program, GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value);
+#endif
+
+#ifndef GL_NV_shader_buffer_store
+#define GL_NV_shader_buffer_store 1
+#endif
+
+#ifndef GL_NV_tessellation_program5
+#define GL_NV_tessellation_program5 1
+#endif
+
+#ifndef GL_NV_vertex_attrib_integer_64bit
+#define GL_NV_vertex_attrib_integer_64bit 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glVertexAttribL1i64NV (GLuint index, GLint64EXT x);
+GLAPI void APIENTRY glVertexAttribL2i64NV (GLuint index, GLint64EXT x, GLint64EXT y);
+GLAPI void APIENTRY glVertexAttribL3i64NV (GLuint index, GLint64EXT x, GLint64EXT y, GLint64EXT z);
+GLAPI void APIENTRY glVertexAttribL4i64NV (GLuint index, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w);
+GLAPI void APIENTRY glVertexAttribL1i64vNV (GLuint index, const GLint64EXT *v);
+GLAPI void APIENTRY glVertexAttribL2i64vNV (GLuint index, const GLint64EXT *v);
+GLAPI void APIENTRY glVertexAttribL3i64vNV (GLuint index, const GLint64EXT *v);
+GLAPI void APIENTRY glVertexAttribL4i64vNV (GLuint index, const GLint64EXT *v);
+GLAPI void APIENTRY glVertexAttribL1ui64NV (GLuint index, GLuint64EXT x);
+GLAPI void APIENTRY glVertexAttribL2ui64NV (GLuint index, GLuint64EXT x, GLuint64EXT y);
+GLAPI void APIENTRY glVertexAttribL3ui64NV (GLuint index, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z);
+GLAPI void APIENTRY glVertexAttribL4ui64NV (GLuint index, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w);
+GLAPI void APIENTRY glVertexAttribL1ui64vNV (GLuint index, const GLuint64EXT *v);
+GLAPI void APIENTRY glVertexAttribL2ui64vNV (GLuint index, const GLuint64EXT *v);
+GLAPI void APIENTRY glVertexAttribL3ui64vNV (GLuint index, const GLuint64EXT *v);
+GLAPI void APIENTRY glVertexAttribL4ui64vNV (GLuint index, const GLuint64EXT *v);
+GLAPI void APIENTRY glGetVertexAttribLi64vNV (GLuint index, GLenum pname, GLint64EXT *params);
+GLAPI void APIENTRY glGetVertexAttribLui64vNV (GLuint index, GLenum pname, GLuint64EXT *params);
+GLAPI void APIENTRY glVertexAttribLFormatNV (GLuint index, GLint size, GLenum type, GLsizei stride);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL1I64NVPROC) (GLuint index, GLint64EXT x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL2I64NVPROC) (GLuint index, GLint64EXT x, GLint64EXT y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL3I64NVPROC) (GLuint index, GLint64EXT x, GLint64EXT y, GLint64EXT z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL4I64NVPROC) (GLuint index, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL1I64VNVPROC) (GLuint index, const GLint64EXT *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL2I64VNVPROC) (GLuint index, const GLint64EXT *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL3I64VNVPROC) (GLuint index, const GLint64EXT *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL4I64VNVPROC) (GLuint index, const GLint64EXT *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL1UI64NVPROC) (GLuint index, GLuint64EXT x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL2UI64NVPROC) (GLuint index, GLuint64EXT x, GLuint64EXT y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL3UI64NVPROC) (GLuint index, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL4UI64NVPROC) (GLuint index, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL1UI64VNVPROC) (GLuint index, const GLuint64EXT *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL2UI64VNVPROC) (GLuint index, const GLuint64EXT *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL3UI64VNVPROC) (GLuint index, const GLuint64EXT *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL4UI64VNVPROC) (GLuint index, const GLuint64EXT *v);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBLI64VNVPROC) (GLuint index, GLenum pname, GLint64EXT *params);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBLUI64VNVPROC) (GLuint index, GLenum pname, GLuint64EXT *params);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBLFORMATNVPROC) (GLuint index, GLint size, GLenum type, GLsizei stride);
+#endif
+
+#ifndef GL_NV_multisample_coverage
+#define GL_NV_multisample_coverage 1
+#endif
+
+#ifndef GL_AMD_name_gen_delete
+#define GL_AMD_name_gen_delete 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGenNamesAMD (GLenum identifier, GLuint num, GLuint *names);
+GLAPI void APIENTRY glDeleteNamesAMD (GLenum identifier, GLuint num, const GLuint *names);
+GLAPI GLboolean APIENTRY glIsNameAMD (GLenum identifier, GLuint name);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLGENNAMESAMDPROC) (GLenum identifier, GLuint num, GLuint *names);
+typedef void (APIENTRYP PFNGLDELETENAMESAMDPROC) (GLenum identifier, GLuint num, const GLuint *names);
+typedef GLboolean (APIENTRYP PFNGLISNAMEAMDPROC) (GLenum identifier, GLuint name);
+#endif
+
+#ifndef GL_AMD_debug_output
+#define GL_AMD_debug_output 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDebugMessageEnableAMD (GLenum category, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled);
+GLAPI void APIENTRY glDebugMessageInsertAMD (GLenum category, GLenum severity, GLuint id, GLsizei length, const GLchar *buf);
+GLAPI void APIENTRY glDebugMessageCallbackAMD (GLDEBUGPROCAMD callback, GLvoid *userParam);
+GLAPI GLuint APIENTRY glGetDebugMessageLogAMD (GLuint count, GLsizei bufsize, GLenum *categories, GLuint *severities, GLuint *ids, GLsizei *lengths, GLchar *message);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLDEBUGMESSAGEENABLEAMDPROC) (GLenum category, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled);
+typedef void (APIENTRYP PFNGLDEBUGMESSAGEINSERTAMDPROC) (GLenum category, GLenum severity, GLuint id, GLsizei length, const GLchar *buf);
+typedef void (APIENTRYP PFNGLDEBUGMESSAGECALLBACKAMDPROC) (GLDEBUGPROCAMD callback, GLvoid *userParam);
+typedef GLuint (APIENTRYP PFNGLGETDEBUGMESSAGELOGAMDPROC) (GLuint count, GLsizei bufsize, GLenum *categories, GLuint *severities, GLuint *ids, GLsizei *lengths, GLchar *message);
+#endif
+
+#ifndef GL_NV_vdpau_interop
+#define GL_NV_vdpau_interop 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glVDPAUInitNV (const GLvoid *vdpDevice, const GLvoid *getProcAddress);
+GLAPI void APIENTRY glVDPAUFiniNV (void);
+GLAPI GLvdpauSurfaceNV APIENTRY glVDPAURegisterVideoSurfaceNV (GLvoid *vdpSurface, GLenum target, GLsizei numTextureNames, const GLuint *textureNames);
+GLAPI GLvdpauSurfaceNV APIENTRY glVDPAURegisterOutputSurfaceNV (GLvoid *vdpSurface, GLenum target, GLsizei numTextureNames, const GLuint *textureNames);
+GLAPI void APIENTRY glVDPAUIsSurfaceNV (GLvdpauSurfaceNV surface);
+GLAPI void APIENTRY glVDPAUUnregisterSurfaceNV (GLvdpauSurfaceNV surface);
+GLAPI void APIENTRY glVDPAUGetSurfaceivNV (GLvdpauSurfaceNV surface, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values);
+GLAPI void APIENTRY glVDPAUSurfaceAccessNV (GLvdpauSurfaceNV surface, GLenum access);
+GLAPI void APIENTRY glVDPAUMapSurfacesNV (GLsizei numSurfaces, const GLvdpauSurfaceNV *surfaces);
+GLAPI void APIENTRY glVDPAUUnmapSurfacesNV (GLsizei numSurface, const GLvdpauSurfaceNV *surfaces);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLVDPAUINITNVPROC) (const GLvoid *vdpDevice, const GLvoid *getProcAddress);
+typedef void (APIENTRYP PFNGLVDPAUFININVPROC) (void);
+typedef GLvdpauSurfaceNV (APIENTRYP PFNGLVDPAUREGISTERVIDEOSURFACENVPROC) (GLvoid *vdpSurface, GLenum target, GLsizei numTextureNames, const GLuint *textureNames);
+typedef GLvdpauSurfaceNV (APIENTRYP PFNGLVDPAUREGISTEROUTPUTSURFACENVPROC) (GLvoid *vdpSurface, GLenum target, GLsizei numTextureNames, const GLuint *textureNames);
+typedef void (APIENTRYP PFNGLVDPAUISSURFACENVPROC) (GLvdpauSurfaceNV surface);
+typedef void (APIENTRYP PFNGLVDPAUUNREGISTERSURFACENVPROC) (GLvdpauSurfaceNV surface);
+typedef void (APIENTRYP PFNGLVDPAUGETSURFACEIVNVPROC) (GLvdpauSurfaceNV surface, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values);
+typedef void (APIENTRYP PFNGLVDPAUSURFACEACCESSNVPROC) (GLvdpauSurfaceNV surface, GLenum access);
+typedef void (APIENTRYP PFNGLVDPAUMAPSURFACESNVPROC) (GLsizei numSurfaces, const GLvdpauSurfaceNV *surfaces);
+typedef void (APIENTRYP PFNGLVDPAUUNMAPSURFACESNVPROC) (GLsizei numSurface, const GLvdpauSurfaceNV *surfaces);
+#endif
+
+#ifndef GL_AMD_transform_feedback3_lines_triangles
+#define GL_AMD_transform_feedback3_lines_triangles 1
+#endif
+
+#ifndef GL_AMD_depth_clamp_separate
+#define GL_AMD_depth_clamp_separate 1
+#endif
+
+#ifndef GL_EXT_texture_sRGB_decode
+#define GL_EXT_texture_sRGB_decode 1
+#endif
+
+#ifndef GL_NV_texture_multisample
+#define GL_NV_texture_multisample 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTexImage2DMultisampleCoverageNV (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations);
+GLAPI void APIENTRY glTexImage3DMultisampleCoverageNV (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations);
+GLAPI void APIENTRY glTextureImage2DMultisampleNV (GLuint texture, GLenum target, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations);
+GLAPI void APIENTRY glTextureImage3DMultisampleNV (GLuint texture, GLenum target, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations);
+GLAPI void APIENTRY glTextureImage2DMultisampleCoverageNV (GLuint texture, GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations);
+GLAPI void APIENTRY glTextureImage3DMultisampleCoverageNV (GLuint texture, GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLTEXIMAGE2DMULTISAMPLECOVERAGENVPROC) (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations);
+typedef void (APIENTRYP PFNGLTEXIMAGE3DMULTISAMPLECOVERAGENVPROC) (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations);
+typedef void (APIENTRYP PFNGLTEXTUREIMAGE2DMULTISAMPLENVPROC) (GLuint texture, GLenum target, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations);
+typedef void (APIENTRYP PFNGLTEXTUREIMAGE3DMULTISAMPLENVPROC) (GLuint texture, GLenum target, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations);
+typedef void (APIENTRYP PFNGLTEXTUREIMAGE2DMULTISAMPLECOVERAGENVPROC) (GLuint texture, GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations);
+typedef void (APIENTRYP PFNGLTEXTUREIMAGE3DMULTISAMPLECOVERAGENVPROC) (GLuint texture, GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations);
+#endif
+
+#ifndef GL_AMD_blend_minmax_factor
+#define GL_AMD_blend_minmax_factor 1
+#endif
+
+#ifndef GL_AMD_sample_positions
+#define GL_AMD_sample_positions 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glSetMultisamplefvAMD (GLenum pname, GLuint index, const GLfloat *val);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLSETMULTISAMPLEFVAMDPROC) (GLenum pname, GLuint index, const GLfloat *val);
+#endif
+
+#ifndef GL_EXT_x11_sync_object
+#define GL_EXT_x11_sync_object 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI GLsync APIENTRY glImportSyncEXT (GLenum external_sync_type, GLintptr external_sync, GLbitfield flags);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef GLsync (APIENTRYP PFNGLIMPORTSYNCEXTPROC) (GLenum external_sync_type, GLintptr external_sync, GLbitfield flags);
+#endif
+
+#ifndef GL_AMD_multi_draw_indirect
+#define GL_AMD_multi_draw_indirect 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glMultiDrawArraysIndirectAMD (GLenum mode, const GLvoid *indirect, GLsizei primcount, GLsizei stride);
+GLAPI void APIENTRY glMultiDrawElementsIndirectAMD (GLenum mode, GLenum type, const GLvoid *indirect, GLsizei primcount, GLsizei stride);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSINDIRECTAMDPROC) (GLenum mode, const GLvoid *indirect, GLsizei primcount, GLsizei stride);
+typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSINDIRECTAMDPROC) (GLenum mode, GLenum type, const GLvoid *indirect, GLsizei primcount, GLsizei stride);
+#endif
+
+#ifndef GL_EXT_framebuffer_multisample_blit_scaled
+#define GL_EXT_framebuffer_multisample_blit_scaled 1
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/graphics/GL/glu.h b/src/graphics/GL/glu.h
new file mode 100644
index 0000000..f386524
--- /dev/null
+++ b/src/graphics/GL/glu.h
@@ -0,0 +1,341 @@
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 1.1 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: This software was created using the
+** OpenGL(R) version 1.2.1 Sample Implementation published by SGI, but has
+** not been independently verified as being compliant with the OpenGL(R)
+** version 1.2.1 Specification.
+*/
+
+#ifndef __glu_h__
+#define __glu_h__
+
+#if defined(USE_MGL_NAMESPACE)
+#include "../../api.h"
+#include "glu_mangle.h"
+#endif
+
+#include "gl.h"
+
+#ifndef GLAPIENTRY
+#define GLAPIENTRY
+#endif
+
+#ifndef GLAPIENTRYP
+#define GLAPIENTRYP GLAPIENTRY *
+#endif
+
+#ifndef GLAPI
+#define GLAPI
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*************************************************************/
+
+/* Extensions */
+#define GLU_EXT_object_space_tess 1
+#define GLU_EXT_nurbs_tessellator 1
+
+/* Boolean */
+#define GLU_FALSE 0
+#define GLU_TRUE 1
+
+/* Version */
+#define GLU_VERSION_1_1 1
+#define GLU_VERSION_1_2 1
+#define GLU_VERSION_1_3 1
+
+/* StringName */
+#define GLU_VERSION 100800
+#define GLU_EXTENSIONS 100801
+
+/* ErrorCode */
+#define GLU_INVALID_ENUM 100900
+#define GLU_INVALID_VALUE 100901
+#define GLU_OUT_OF_MEMORY 100902
+#define GLU_INCOMPATIBLE_GL_VERSION 100903
+#define GLU_INVALID_OPERATION 100904
+
+/* NurbsDisplay */
+/* GLU_FILL */
+#define GLU_OUTLINE_POLYGON 100240
+#define GLU_OUTLINE_PATCH 100241
+
+/* NurbsCallback */
+#define GLU_NURBS_ERROR 100103
+#define GLU_ERROR 100103
+#define GLU_NURBS_BEGIN 100164
+#define GLU_NURBS_BEGIN_EXT 100164
+#define GLU_NURBS_VERTEX 100165
+#define GLU_NURBS_VERTEX_EXT 100165
+#define GLU_NURBS_NORMAL 100166
+#define GLU_NURBS_NORMAL_EXT 100166
+#define GLU_NURBS_COLOR 100167
+#define GLU_NURBS_COLOR_EXT 100167
+#define GLU_NURBS_TEXTURE_COORD 100168
+#define GLU_NURBS_TEX_COORD_EXT 100168
+#define GLU_NURBS_END 100169
+#define GLU_NURBS_END_EXT 100169
+#define GLU_NURBS_BEGIN_DATA 100170
+#define GLU_NURBS_BEGIN_DATA_EXT 100170
+#define GLU_NURBS_VERTEX_DATA 100171
+#define GLU_NURBS_VERTEX_DATA_EXT 100171
+#define GLU_NURBS_NORMAL_DATA 100172
+#define GLU_NURBS_NORMAL_DATA_EXT 100172
+#define GLU_NURBS_COLOR_DATA 100173
+#define GLU_NURBS_COLOR_DATA_EXT 100173
+#define GLU_NURBS_TEXTURE_COORD_DATA 100174
+#define GLU_NURBS_TEX_COORD_DATA_EXT 100174
+#define GLU_NURBS_END_DATA 100175
+#define GLU_NURBS_END_DATA_EXT 100175
+
+/* NurbsError */
+#define GLU_NURBS_ERROR1 100251
+#define GLU_NURBS_ERROR2 100252
+#define GLU_NURBS_ERROR3 100253
+#define GLU_NURBS_ERROR4 100254
+#define GLU_NURBS_ERROR5 100255
+#define GLU_NURBS_ERROR6 100256
+#define GLU_NURBS_ERROR7 100257
+#define GLU_NURBS_ERROR8 100258
+#define GLU_NURBS_ERROR9 100259
+#define GLU_NURBS_ERROR10 100260
+#define GLU_NURBS_ERROR11 100261
+#define GLU_NURBS_ERROR12 100262
+#define GLU_NURBS_ERROR13 100263
+#define GLU_NURBS_ERROR14 100264
+#define GLU_NURBS_ERROR15 100265
+#define GLU_NURBS_ERROR16 100266
+#define GLU_NURBS_ERROR17 100267
+#define GLU_NURBS_ERROR18 100268
+#define GLU_NURBS_ERROR19 100269
+#define GLU_NURBS_ERROR20 100270
+#define GLU_NURBS_ERROR21 100271
+#define GLU_NURBS_ERROR22 100272
+#define GLU_NURBS_ERROR23 100273
+#define GLU_NURBS_ERROR24 100274
+#define GLU_NURBS_ERROR25 100275
+#define GLU_NURBS_ERROR26 100276
+#define GLU_NURBS_ERROR27 100277
+#define GLU_NURBS_ERROR28 100278
+#define GLU_NURBS_ERROR29 100279
+#define GLU_NURBS_ERROR30 100280
+#define GLU_NURBS_ERROR31 100281
+#define GLU_NURBS_ERROR32 100282
+#define GLU_NURBS_ERROR33 100283
+#define GLU_NURBS_ERROR34 100284
+#define GLU_NURBS_ERROR35 100285
+#define GLU_NURBS_ERROR36 100286
+#define GLU_NURBS_ERROR37 100287
+
+/* NurbsProperty */
+#define GLU_AUTO_LOAD_MATRIX 100200
+#define GLU_CULLING 100201
+#define GLU_SAMPLING_TOLERANCE 100203
+#define GLU_DISPLAY_MODE 100204
+#define GLU_PARAMETRIC_TOLERANCE 100202
+#define GLU_SAMPLING_METHOD 100205
+#define GLU_U_STEP 100206
+#define GLU_V_STEP 100207
+#define GLU_NURBS_MODE 100160
+#define GLU_NURBS_MODE_EXT 100160
+#define GLU_NURBS_TESSELLATOR 100161
+#define GLU_NURBS_TESSELLATOR_EXT 100161
+#define GLU_NURBS_RENDERER 100162
+#define GLU_NURBS_RENDERER_EXT 100162
+
+/* NurbsSampling */
+#define GLU_OBJECT_PARAMETRIC_ERROR 100208
+#define GLU_OBJECT_PARAMETRIC_ERROR_EXT 100208
+#define GLU_OBJECT_PATH_LENGTH 100209
+#define GLU_OBJECT_PATH_LENGTH_EXT 100209
+#define GLU_PATH_LENGTH 100215
+#define GLU_PARAMETRIC_ERROR 100216
+#define GLU_DOMAIN_DISTANCE 100217
+
+/* NurbsTrim */
+#define GLU_MAP1_TRIM_2 100210
+#define GLU_MAP1_TRIM_3 100211
+
+/* QuadricDrawStyle */
+#define GLU_POINT 100010
+#define GLU_LINE 100011
+#define GLU_FILL 100012
+#define GLU_SILHOUETTE 100013
+
+/* QuadricCallback */
+/* GLU_ERROR */
+
+/* QuadricNormal */
+#define GLU_SMOOTH 100000
+#define GLU_FLAT 100001
+#define GLU_NONE 100002
+
+/* QuadricOrientation */
+#define GLU_OUTSIDE 100020
+#define GLU_INSIDE 100021
+
+/* TessCallback */
+#define GLU_TESS_BEGIN 100100
+#define GLU_BEGIN 100100
+#define GLU_TESS_VERTEX 100101
+#define GLU_VERTEX 100101
+#define GLU_TESS_END 100102
+#define GLU_END 100102
+#define GLU_TESS_ERROR 100103
+#define GLU_TESS_EDGE_FLAG 100104
+#define GLU_EDGE_FLAG 100104
+#define GLU_TESS_COMBINE 100105
+#define GLU_TESS_BEGIN_DATA 100106
+#define GLU_TESS_VERTEX_DATA 100107
+#define GLU_TESS_END_DATA 100108
+#define GLU_TESS_ERROR_DATA 100109
+#define GLU_TESS_EDGE_FLAG_DATA 100110
+#define GLU_TESS_COMBINE_DATA 100111
+
+/* TessContour */
+#define GLU_CW 100120
+#define GLU_CCW 100121
+#define GLU_INTERIOR 100122
+#define GLU_EXTERIOR 100123
+#define GLU_UNKNOWN 100124
+
+/* TessProperty */
+#define GLU_TESS_WINDING_RULE 100140
+#define GLU_TESS_BOUNDARY_ONLY 100141
+#define GLU_TESS_TOLERANCE 100142
+
+/* TessError */
+#define GLU_TESS_ERROR1 100151
+#define GLU_TESS_ERROR2 100152
+#define GLU_TESS_ERROR3 100153
+#define GLU_TESS_ERROR4 100154
+#define GLU_TESS_ERROR5 100155
+#define GLU_TESS_ERROR6 100156
+#define GLU_TESS_ERROR7 100157
+#define GLU_TESS_ERROR8 100158
+#define GLU_TESS_MISSING_BEGIN_POLYGON 100151
+#define GLU_TESS_MISSING_BEGIN_CONTOUR 100152
+#define GLU_TESS_MISSING_END_POLYGON 100153
+#define GLU_TESS_MISSING_END_CONTOUR 100154
+#define GLU_TESS_COORD_TOO_LARGE 100155
+#define GLU_TESS_NEED_COMBINE_CALLBACK 100156
+
+/* TessWinding */
+#define GLU_TESS_WINDING_ODD 100130
+#define GLU_TESS_WINDING_NONZERO 100131
+#define GLU_TESS_WINDING_POSITIVE 100132
+#define GLU_TESS_WINDING_NEGATIVE 100133
+#define GLU_TESS_WINDING_ABS_GEQ_TWO 100134
+
+/*************************************************************/
+
+
+#ifdef __cplusplus
+class GLUnurbs;
+class GLUquadric;
+class GLUtesselator;
+#else
+typedef struct GLUnurbs GLUnurbs;
+typedef struct GLUquadric GLUquadric;
+typedef struct GLUtesselator GLUtesselator;
+#endif
+
+typedef GLUnurbs GLUnurbsObj;
+typedef GLUquadric GLUquadricObj;
+typedef GLUtesselator GLUtesselatorObj;
+typedef GLUtesselator GLUtriangulatorObj;
+
+#define GLU_TESS_MAX_COORD 1.0e150
+
+/* Internal convenience typedefs */
+typedef void (GLAPIENTRYP _GLUfuncptr)();
+
+GLAPI void GLAPIENTRY gluBeginCurve (GLUnurbs* nurb);
+GLAPI void GLAPIENTRY gluBeginPolygon (GLUtesselator* tess);
+GLAPI void GLAPIENTRY gluBeginSurface (GLUnurbs* nurb);
+GLAPI void GLAPIENTRY gluBeginTrim (GLUnurbs* nurb);
+GLAPI GLint GLAPIENTRY gluBuild1DMipmapLevels (GLenum target, GLint internalFormat, GLsizei width, GLenum format, GLenum type, GLint level, GLint base, GLint max, const void *data);
+GLAPI GLint GLAPIENTRY gluBuild1DMipmaps (GLenum target, GLint internalFormat, GLsizei width, GLenum format, GLenum type, const void *data);
+GLAPI GLint GLAPIENTRY gluBuild2DMipmapLevels (GLenum target, GLint internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint level, GLint base, GLint max, const void *data);
+GLAPI GLint GLAPIENTRY gluBuild2DMipmaps (GLenum target, GLint internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *data);
+GLAPI GLint GLAPIENTRY gluBuild3DMipmapLevels (GLenum target, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLint level, GLint base, GLint max, const void *data);
+GLAPI GLint GLAPIENTRY gluBuild3DMipmaps (GLenum target, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *data);
+GLAPI GLboolean GLAPIENTRY gluCheckExtension (const GLubyte *extName, const GLubyte *extString);
+GLAPI void GLAPIENTRY gluCylinder (GLUquadric* quad, GLdouble base, GLdouble top, GLdouble height, GLint slices, GLint stacks);
+GLAPI void GLAPIENTRY gluDeleteNurbsRenderer (GLUnurbs* nurb);
+GLAPI void GLAPIENTRY gluDeleteQuadric (GLUquadric* quad);
+GLAPI void GLAPIENTRY gluDeleteTess (GLUtesselator* tess);
+GLAPI void GLAPIENTRY gluDisk (GLUquadric* quad, GLdouble inner, GLdouble outer, GLint slices, GLint loops);
+GLAPI void GLAPIENTRY gluEndCurve (GLUnurbs* nurb);
+GLAPI void GLAPIENTRY gluEndPolygon (GLUtesselator* tess);
+GLAPI void GLAPIENTRY gluEndSurface (GLUnurbs* nurb);
+GLAPI void GLAPIENTRY gluEndTrim (GLUnurbs* nurb);
+GLAPI const GLubyte * GLAPIENTRY gluErrorString (GLenum error);
+GLAPI void GLAPIENTRY gluGetNurbsProperty (GLUnurbs* nurb, GLenum property, GLfloat* data);
+GLAPI const GLubyte * GLAPIENTRY gluGetString (GLenum name);
+GLAPI void GLAPIENTRY gluGetTessProperty (GLUtesselator* tess, GLenum which, GLdouble* data);
+GLAPI void GLAPIENTRY gluLoadSamplingMatrices (GLUnurbs* nurb, const GLfloat *model, const GLfloat *perspective, const GLint *view);
+GLAPI void GLAPIENTRY gluLookAt (GLdouble eyeX, GLdouble eyeY, GLdouble eyeZ, GLdouble centerX, GLdouble centerY, GLdouble centerZ, GLdouble upX, GLdouble upY, GLdouble upZ);
+GLAPI GLUnurbs* GLAPIENTRY gluNewNurbsRenderer (void);
+GLAPI GLUquadric* GLAPIENTRY gluNewQuadric (void);
+GLAPI GLUtesselator* GLAPIENTRY gluNewTess (void);
+GLAPI void GLAPIENTRY gluNextContour (GLUtesselator* tess, GLenum type);
+GLAPI void GLAPIENTRY gluNurbsCallback (GLUnurbs* nurb, GLenum which, _GLUfuncptr CallBackFunc);
+GLAPI void GLAPIENTRY gluNurbsCallbackData (GLUnurbs* nurb, GLvoid* userData);
+GLAPI void GLAPIENTRY gluNurbsCallbackDataEXT (GLUnurbs* nurb, GLvoid* userData);
+GLAPI void GLAPIENTRY gluNurbsCurve (GLUnurbs* nurb, GLint knotCount, GLfloat *knots, GLint stride, GLfloat *control, GLint order, GLenum type);
+GLAPI void GLAPIENTRY gluNurbsProperty (GLUnurbs* nurb, GLenum property, GLfloat value);
+GLAPI void GLAPIENTRY gluNurbsSurface (GLUnurbs* nurb, GLint sKnotCount, GLfloat* sKnots, GLint tKnotCount, GLfloat* tKnots, GLint sStride, GLint tStride, GLfloat* control, GLint sOrder, GLint tOrder, GLenum type);
+GLAPI void GLAPIENTRY gluOrtho2D (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top);
+GLAPI void GLAPIENTRY gluPartialDisk (GLUquadric* quad, GLdouble inner, GLdouble outer, GLint slices, GLint loops, GLdouble start, GLdouble sweep);
+GLAPI void GLAPIENTRY gluPerspective (GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar);
+GLAPI void GLAPIENTRY gluPickMatrix (GLdouble x, GLdouble y, GLdouble delX, GLdouble delY, GLint *viewport);
+GLAPI GLint GLAPIENTRY gluProject (GLdouble objX, GLdouble objY, GLdouble objZ, const GLdouble *model, const GLdouble *proj, const GLint *view, GLdouble* winX, GLdouble* winY, GLdouble* winZ);
+GLAPI void GLAPIENTRY gluPwlCurve (GLUnurbs* nurb, GLint count, GLfloat* data, GLint stride, GLenum type);
+GLAPI void GLAPIENTRY gluQuadricCallback (GLUquadric* quad, GLenum which, _GLUfuncptr CallBackFunc);
+GLAPI void GLAPIENTRY gluQuadricDrawStyle (GLUquadric* quad, GLenum draw);
+GLAPI void GLAPIENTRY gluQuadricNormals (GLUquadric* quad, GLenum normal);
+GLAPI void GLAPIENTRY gluQuadricOrientation (GLUquadric* quad, GLenum orientation);
+GLAPI void GLAPIENTRY gluQuadricTexture (GLUquadric* quad, GLboolean texture);
+GLAPI GLint GLAPIENTRY gluScaleImage (GLenum format, GLsizei wIn, GLsizei hIn, GLenum typeIn, const void *dataIn, GLsizei wOut, GLsizei hOut, GLenum typeOut, GLvoid* dataOut);
+GLAPI void GLAPIENTRY gluSphere (GLUquadric* quad, GLdouble radius, GLint slices, GLint stacks);
+GLAPI void GLAPIENTRY gluTessBeginContour (GLUtesselator* tess);
+GLAPI void GLAPIENTRY gluTessBeginPolygon (GLUtesselator* tess, GLvoid* data);
+GLAPI void GLAPIENTRY gluTessCallback (GLUtesselator* tess, GLenum which, _GLUfuncptr CallBackFunc);
+GLAPI void GLAPIENTRY gluTessEndContour (GLUtesselator* tess);
+GLAPI void GLAPIENTRY gluTessEndPolygon (GLUtesselator* tess);
+GLAPI void GLAPIENTRY gluTessNormal (GLUtesselator* tess, GLdouble valueX, GLdouble valueY, GLdouble valueZ);
+GLAPI void GLAPIENTRY gluTessProperty (GLUtesselator* tess, GLenum which, GLdouble data);
+GLAPI void GLAPIENTRY gluTessVertex (GLUtesselator* tess, GLdouble *location, GLvoid* data);
+GLAPI GLint GLAPIENTRY gluUnProject (GLdouble winX, GLdouble winY, GLdouble winZ, const GLdouble *model, const GLdouble *proj, const GLint *view, GLdouble* objX, GLdouble* objY, GLdouble* objZ);
+GLAPI GLint GLAPIENTRY gluUnProject4 (GLdouble winX, GLdouble winY, GLdouble winZ, GLdouble clipW, const GLdouble *model, const GLdouble *proj, const GLint *view, GLdouble nearVal, GLdouble farVal, GLdouble* objX, GLdouble* objY, GLdouble* objZ, GLdouble* objW);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __glu_h__ */
diff --git a/src/graphics/GL/glx.h b/src/graphics/GL/glx.h
new file mode 100644
index 0000000..d261ed3
--- /dev/null
+++ b/src/graphics/GL/glx.h
@@ -0,0 +1,552 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.3
+ *
+ * Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef GLX_H
+#define GLX_H
+
+
+#ifdef __VMS
+#include "../../api.h"
+#include <GL/vms_x_fix.h>
+# ifdef __cplusplus
+/* VMS Xlib.h gives problems with C++.
+ * this avoids a bunch of trivial warnings */
+#pragma message disable nosimpint
+#endif
+#endif
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#ifdef __VMS
+# ifdef __cplusplus
+#pragma message enable nosimpint
+#endif
+#endif
+#include <GL/gl.h>
+
+
+#if defined(USE_MGL_NAMESPACE)
+#include "glx_mangle.h"
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#define GLX_VERSION_1_1 1
+#define GLX_VERSION_1_2 1
+#define GLX_VERSION_1_3 1
+#define GLX_VERSION_1_4 1
+
+#define GLX_EXTENSION_NAME "GLX"
+
+
+
+/*
+ * Tokens for glXChooseVisual and glXGetConfig:
+ */
+#define GLX_USE_GL 1
+#define GLX_BUFFER_SIZE 2
+#define GLX_LEVEL 3
+#define GLX_RGBA 4
+#define GLX_DOUBLEBUFFER 5
+#define GLX_STEREO 6
+#define GLX_AUX_BUFFERS 7
+#define GLX_RED_SIZE 8
+#define GLX_GREEN_SIZE 9
+#define GLX_BLUE_SIZE 10
+#define GLX_ALPHA_SIZE 11
+#define GLX_DEPTH_SIZE 12
+#define GLX_STENCIL_SIZE 13
+#define GLX_ACCUM_RED_SIZE 14
+#define GLX_ACCUM_GREEN_SIZE 15
+#define GLX_ACCUM_BLUE_SIZE 16
+#define GLX_ACCUM_ALPHA_SIZE 17
+
+
+/*
+ * Error codes returned by glXGetConfig:
+ */
+#define GLX_BAD_SCREEN 1
+#define GLX_BAD_ATTRIBUTE 2
+#define GLX_NO_EXTENSION 3
+#define GLX_BAD_VISUAL 4
+#define GLX_BAD_CONTEXT 5
+#define GLX_BAD_VALUE 6
+#define GLX_BAD_ENUM 7
+
+
+/*
+ * GLX 1.1 and later:
+ */
+#define GLX_VENDOR 1
+#define GLX_VERSION 2
+#define GLX_EXTENSIONS 3
+
+
+/*
+ * GLX 1.3 and later:
+ */
+#define GLX_CONFIG_CAVEAT 0x20
+#define GLX_DONT_CARE 0xFFFFFFFF
+#define GLX_X_VISUAL_TYPE 0x22
+#define GLX_TRANSPARENT_TYPE 0x23
+#define GLX_TRANSPARENT_INDEX_VALUE 0x24
+#define GLX_TRANSPARENT_RED_VALUE 0x25
+#define GLX_TRANSPARENT_GREEN_VALUE 0x26
+#define GLX_TRANSPARENT_BLUE_VALUE 0x27
+#define GLX_TRANSPARENT_ALPHA_VALUE 0x28
+#define GLX_WINDOW_BIT 0x00000001
+#define GLX_PIXMAP_BIT 0x00000002
+#define GLX_PBUFFER_BIT 0x00000004
+#define GLX_AUX_BUFFERS_BIT 0x00000010
+#define GLX_FRONT_LEFT_BUFFER_BIT 0x00000001
+#define GLX_FRONT_RIGHT_BUFFER_BIT 0x00000002
+#define GLX_BACK_LEFT_BUFFER_BIT 0x00000004
+#define GLX_BACK_RIGHT_BUFFER_BIT 0x00000008
+#define GLX_DEPTH_BUFFER_BIT 0x00000020
+#define GLX_STENCIL_BUFFER_BIT 0x00000040
+#define GLX_ACCUM_BUFFER_BIT 0x00000080
+#define GLX_NONE 0x8000
+#define GLX_SLOW_CONFIG 0x8001
+#define GLX_TRUE_COLOR 0x8002
+#define GLX_DIRECT_COLOR 0x8003
+#define GLX_PSEUDO_COLOR 0x8004
+#define GLX_STATIC_COLOR 0x8005
+#define GLX_GRAY_SCALE 0x8006
+#define GLX_STATIC_GRAY 0x8007
+#define GLX_TRANSPARENT_RGB 0x8008
+#define GLX_TRANSPARENT_INDEX 0x8009
+#define GLX_VISUAL_ID 0x800B
+#define GLX_SCREEN 0x800C
+#define GLX_NON_CONFORMANT_CONFIG 0x800D
+#define GLX_DRAWABLE_TYPE 0x8010
+#define GLX_RENDER_TYPE 0x8011
+#define GLX_X_RENDERABLE 0x8012
+#define GLX_FBCONFIG_ID 0x8013
+#define GLX_RGBA_TYPE 0x8014
+#define GLX_COLOR_INDEX_TYPE 0x8015
+#define GLX_MAX_PBUFFER_WIDTH 0x8016
+#define GLX_MAX_PBUFFER_HEIGHT 0x8017
+#define GLX_MAX_PBUFFER_PIXELS 0x8018
+#define GLX_PRESERVED_CONTENTS 0x801B
+#define GLX_LARGEST_PBUFFER 0x801C
+#define GLX_WIDTH 0x801D
+#define GLX_HEIGHT 0x801E
+#define GLX_EVENT_MASK 0x801F
+#define GLX_DAMAGED 0x8020
+#define GLX_SAVED 0x8021
+#define GLX_WINDOW 0x8022
+#define GLX_PBUFFER 0x8023
+#define GLX_PBUFFER_HEIGHT 0x8040
+#define GLX_PBUFFER_WIDTH 0x8041
+#define GLX_RGBA_BIT 0x00000001
+#define GLX_COLOR_INDEX_BIT 0x00000002
+#define GLX_PBUFFER_CLOBBER_MASK 0x08000000
+
+
+/*
+ * GLX 1.4 and later:
+ */
+#define GLX_SAMPLE_BUFFERS 0x186a0 /*100000*/
+#define GLX_SAMPLES 0x186a1 /*100001*/
+
+
+
+typedef struct __GLXcontextRec *GLXContext;
+typedef XID GLXPixmap;
+typedef XID GLXDrawable;
+/* GLX 1.3 and later */
+typedef struct __GLXFBConfigRec *GLXFBConfig;
+typedef XID GLXFBConfigID;
+typedef XID GLXContextID;
+typedef XID GLXWindow;
+typedef XID GLXPbuffer;
+
+
+
+extern XVisualInfo* glXChooseVisual( Display *dpy, int screen,
+ int *attribList );
+
+extern GLXContext glXCreateContext( Display *dpy, XVisualInfo *vis,
+ GLXContext shareList, Bool direct );
+
+extern void glXDestroyContext( Display *dpy, GLXContext ctx );
+
+extern Bool glXMakeCurrent( Display *dpy, GLXDrawable drawable,
+ GLXContext ctx);
+
+extern void glXCopyContext( Display *dpy, GLXContext src, GLXContext dst,
+ unsigned long mask );
+
+extern void glXSwapBuffers( Display *dpy, GLXDrawable drawable );
+
+extern GLXPixmap glXCreateGLXPixmap( Display *dpy, XVisualInfo *visual,
+ Pixmap pixmap );
+
+extern void glXDestroyGLXPixmap( Display *dpy, GLXPixmap pixmap );
+
+extern Bool glXQueryExtension( Display *dpy, int *errorb, int *event );
+
+extern Bool glXQueryVersion( Display *dpy, int *maj, int *min );
+
+extern Bool glXIsDirect( Display *dpy, GLXContext ctx );
+
+extern int glXGetConfig( Display *dpy, XVisualInfo *visual,
+ int attrib, int *value );
+
+extern GLXContext glXGetCurrentContext( void );
+
+extern GLXDrawable glXGetCurrentDrawable( void );
+
+extern void glXWaitGL( void );
+
+extern void glXWaitX( void );
+
+extern void glXUseXFont( Font font, int first, int count, int list );
+
+
+
+/* GLX 1.1 and later */
+extern const char *glXQueryExtensionsString( Display *dpy, int screen );
+
+extern const char *glXQueryServerString( Display *dpy, int screen, int name );
+
+extern const char *glXGetClientString( Display *dpy, int name );
+
+
+/* GLX 1.2 and later */
+extern Display *glXGetCurrentDisplay( void );
+
+
+/* GLX 1.3 and later */
+extern GLXFBConfig *glXChooseFBConfig( Display *dpy, int screen,
+ const int *attribList, int *nitems );
+
+extern int glXGetFBConfigAttrib( Display *dpy, GLXFBConfig config,
+ int attribute, int *value );
+
+extern GLXFBConfig *glXGetFBConfigs( Display *dpy, int screen,
+ int *nelements );
+
+extern XVisualInfo *glXGetVisualFromFBConfig( Display *dpy,
+ GLXFBConfig config );
+
+extern GLXWindow glXCreateWindow( Display *dpy, GLXFBConfig config,
+ Window win, const int *attribList );
+
+extern void glXDestroyWindow( Display *dpy, GLXWindow window );
+
+extern GLXPixmap glXCreatePixmap( Display *dpy, GLXFBConfig config,
+ Pixmap pixmap, const int *attribList );
+
+extern void glXDestroyPixmap( Display *dpy, GLXPixmap pixmap );
+
+extern GLXPbuffer glXCreatePbuffer( Display *dpy, GLXFBConfig config,
+ const int *attribList );
+
+extern void glXDestroyPbuffer( Display *dpy, GLXPbuffer pbuf );
+
+extern void glXQueryDrawable( Display *dpy, GLXDrawable draw, int attribute,
+ unsigned int *value );
+
+extern GLXContext glXCreateNewContext( Display *dpy, GLXFBConfig config,
+ int renderType, GLXContext shareList,
+ Bool direct );
+
+extern Bool glXMakeContextCurrent( Display *dpy, GLXDrawable draw,
+ GLXDrawable read, GLXContext ctx );
+
+extern GLXDrawable glXGetCurrentReadDrawable( void );
+
+extern int glXQueryContext( Display *dpy, GLXContext ctx, int attribute,
+ int *value );
+
+extern void glXSelectEvent( Display *dpy, GLXDrawable drawable,
+ unsigned long mask );
+
+extern void glXGetSelectedEvent( Display *dpy, GLXDrawable drawable,
+ unsigned long *mask );
+
+
+/* GLX 1.4 and later */
+extern void (*glXGetProcAddress(const GLubyte *procname))( void );
+
+
+#ifndef GLX_GLXEXT_LEGACY
+
+#include <GL/glxext.h>
+
+#else
+
+
+/*
+ * 28. GLX_EXT_visual_info extension
+ */
+#ifndef GLX_EXT_visual_info
+#define GLX_EXT_visual_info 1
+
+#define GLX_X_VISUAL_TYPE_EXT 0x22
+#define GLX_TRANSPARENT_TYPE_EXT 0x23
+#define GLX_TRANSPARENT_INDEX_VALUE_EXT 0x24
+#define GLX_TRANSPARENT_RED_VALUE_EXT 0x25
+#define GLX_TRANSPARENT_GREEN_VALUE_EXT 0x26
+#define GLX_TRANSPARENT_BLUE_VALUE_EXT 0x27
+#define GLX_TRANSPARENT_ALPHA_VALUE_EXT 0x28
+#define GLX_TRUE_COLOR_EXT 0x8002
+#define GLX_DIRECT_COLOR_EXT 0x8003
+#define GLX_PSEUDO_COLOR_EXT 0x8004
+#define GLX_STATIC_COLOR_EXT 0x8005
+#define GLX_GRAY_SCALE_EXT 0x8006
+#define GLX_STATIC_GRAY_EXT 0x8007
+#define GLX_NONE_EXT 0x8000
+#define GLX_TRANSPARENT_RGB_EXT 0x8008
+#define GLX_TRANSPARENT_INDEX_EXT 0x8009
+
+#endif /* 28. GLX_EXT_visual_info extension */
+
+
+
+/*
+ * 41. GLX_SGI_video_sync
+ */
+#ifndef GLX_SGI_video_sync
+#define GLX_SGI_video_sync 1
+
+extern int glXGetVideoSyncSGI(unsigned int *count);
+extern int glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count);
+
+#endif /* GLX_SGI_video_sync */
+
+
+
+/*
+ * 42. GLX_EXT_visual_rating
+ */
+#ifndef GLX_EXT_visual_rating
+#define GLX_EXT_visual_rating 1
+
+#define GLX_VISUAL_CAVEAT_EXT 0x20
+/*#define GLX_NONE_EXT 0x8000*/
+#define GLX_SLOW_VISUAL_EXT 0x8001
+#define GLX_NON_CONFORMANT_VISUAL_EXT 0x800D
+
+#endif /* GLX_EXT_visual_rating */
+
+
+
+/*
+ * 47. GLX_EXT_import_context
+ */
+#ifndef GLX_EXT_import_context
+#define GLX_EXT_import_context 1
+
+#define GLX_SHARE_CONTEXT_EXT 0x800A
+#define GLX_VISUAL_ID_EXT 0x800B
+#define GLX_SCREEN_EXT 0x800C
+
+extern void glXFreeContextEXT(Display *dpy, GLXContext context);
+
+extern GLXContextID glXGetContextIDEXT(const GLXContext context);
+
+extern Display *glXGetCurrentDisplayEXT(void);
+
+extern GLXContext glXImportContextEXT(Display *dpy, GLXContextID contextID);
+
+extern int glXQueryContextInfoEXT(Display *dpy, GLXContext context,
+ int attribute,int *value);
+
+#endif /* GLX_EXT_import_context */
+
+
+
+/*
+ * 215. GLX_MESA_copy_sub_buffer
+ */
+#ifndef GLX_MESA_copy_sub_buffer
+#define GLX_MESA_copy_sub_buffer 1
+
+extern void glXCopySubBufferMESA( Display *dpy, GLXDrawable drawable,
+ int x, int y, int width, int height );
+
+#endif
+
+
+
+/*
+ * 216. GLX_MESA_pixmap_colormap
+ */
+#ifndef GLX_MESA_pixmap_colormap
+#define GLX_MESA_pixmap_colormap 1
+
+extern GLXPixmap glXCreateGLXPixmapMESA( Display *dpy, XVisualInfo *visual,
+ Pixmap pixmap, Colormap cmap );
+
+#endif /* GLX_MESA_pixmap_colormap */
+
+
+
+/*
+ * 217. GLX_MESA_release_buffers
+ */
+#ifndef GLX_MESA_release_buffers
+#define GLX_MESA_release_buffers 1
+
+extern Bool glXReleaseBuffersMESA( Display *dpy, GLXDrawable d );
+
+#endif /* GLX_MESA_release_buffers */
+
+
+
+/*
+ * 218. GLX_MESA_set_3dfx_mode
+ */
+#ifndef GLX_MESA_set_3dfx_mode
+#define GLX_MESA_set_3dfx_mode 1
+
+#define GLX_3DFX_WINDOW_MODE_MESA 0x1
+#define GLX_3DFX_FULLSCREEN_MODE_MESA 0x2
+
+extern Bool glXSet3DfxModeMESA( int mode );
+
+#endif /* GLX_MESA_set_3dfx_mode */
+
+
+
+/*
+ * ARB 2. GLX_ARB_get_proc_address
+ */
+#ifndef GLX_ARB_get_proc_address
+#define GLX_ARB_get_proc_address 1
+
+extern void (*glXGetProcAddressARB(const GLubyte *procName))();
+
+#endif /* GLX_ARB_get_proc_address */
+
+
+
+#endif /* GLX_GLXEXT_LEGACY */
+
+
+/**
+ ** The following aren't in glxext.h yet.
+ **/
+
+
+/*
+ * ???. GLX_NV_vertex_array_range
+ */
+#ifndef GLX_NV_vertex_array_range
+#define GLX_NV_vertex_array_range
+
+extern void *glXAllocateMemoryNV(GLsizei size, GLfloat readfreq, GLfloat writefreq, GLfloat priority);
+extern void glXFreeMemoryNV(GLvoid *pointer);
+typedef void * ( * PFNGLXALLOCATEMEMORYNVPROC) (GLsizei size, GLfloat readfreq, GLfloat writefreq, GLfloat priority);
+typedef void ( * PFNGLXFREEMEMORYNVPROC) (GLvoid *pointer);
+
+#endif /* GLX_NV_vertex_array_range */
+
+
+
+/*
+ * ???. GLX_MESA_agp_offset
+ */
+#ifndef GLX_MESA_agp_offset
+#define GLX_MESA_agp_offset 1
+
+extern GLuint glXGetAGPOffsetMESA(const GLvoid *pointer);
+typedef GLuint (* PFNGLXGETAGPOFFSETMESAPROC) (const GLvoid *pointer);
+
+#endif /* GLX_MESA_agp_offset */
+
+
+/*
+ * ???. GLX_MESA_allocate_memory
+ */
+#ifndef GLX_MESA_allocate_memory
+#define GLX_MESA_allocate_memory 1
+
+extern void *glXAllocateMemoryMESA(Display *dpy, int scrn, size_t size, float readfreq, float writefreq, float priority);
+extern void glXFreeMemoryMESA(Display *dpy, int scrn, void *pointer);
+extern GLuint glXGetMemoryOffsetMESA(Display *dpy, int scrn, const void *pointer);
+typedef void * ( * PFNGLXALLOCATEMEMORYMESAPROC) (Display *dpy, int scrn, size_t size, float readfreq, float writefreq, float priority);
+typedef void ( * PFNGLXFREEMEMORYMESAPROC) (Display *dpy, int scrn, void *pointer);
+typedef GLuint (* PFNGLXGETMEMORYOFFSETMESAPROC) (Display *dpy, int scrn, const void *pointer);
+
+#endif /* GLX_MESA_allocate_memory */
+
+/*
+ * ARB ?. GLX_ARB_render_texture
+ */
+#ifndef GLX_ARB_render_texture
+#define GLX_ARB_render_texture 1
+
+extern Bool glXBindTexImageARB(Display *dpy, GLXPbuffer pbuffer, int buffer);
+extern Bool glXReleaseTexImageARB(Display *dpy, GLXPbuffer pbuffer, int buffer);
+extern Bool glXDrawableAttribARB(Display *dpy, GLXDrawable draw, const int *attribList);
+
+#endif /* GLX_ARB_render_texture */
+
+
+/*
+ * Remove this when glxext.h is updated.
+ */
+#ifndef GLX_NV_float_buffer
+#define GLX_NV_float_buffer 1
+
+#define GLX_FLOAT_COMPONENTS_NV 0x20B0
+
+#endif /* GLX_NV_float_buffer */
+
+
+/*** Should these go here, or in another header? */
+/*
+** GLX Events
+*/
+typedef struct {
+ int event_type; /* GLX_DAMAGED or GLX_SAVED */
+ int draw_type; /* GLX_WINDOW or GLX_PBUFFER */
+ unsigned long serial; /* # of last request processed by server */
+ Bool send_event; /* true if this came for SendEvent request */
+ Display *display; /* display the event was read from */
+ GLXDrawable drawable; /* XID of Drawable */
+ unsigned int buffer_mask; /* mask indicating which buffers are affected */
+ unsigned int aux_buffer; /* which aux buffer was affected */
+ int x, y;
+ int width, height;
+ int count; /* if nonzero, at least this many more */
+} GLXPbufferClobberEvent;
+
+typedef union __GLXEvent {
+ GLXPbufferClobberEvent glxpbufferclobber;
+ long pad[24];
+} GLXEvent;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/graphics/GL/wglext.h b/src/graphics/GL/wglext.h
new file mode 100644
index 0000000..b5dc7bf
--- /dev/null
+++ b/src/graphics/GL/wglext.h
@@ -0,0 +1,943 @@
+#ifndef __wglext_h_
+#define __wglext_h_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+** Copyright (c) 2007-2012 The Khronos Group Inc.
+**
+** Permission is hereby granted, free of charge, to any person obtaining a
+** copy of this software and/or associated documentation files (the
+** "Materials"), to deal in the Materials without restriction, including
+** without limitation the rights to use, copy, modify, merge, publish,
+** distribute, sublicense, and/or sell copies of the Materials, and to
+** permit persons to whom the Materials are furnished to do so, subject to
+** the following conditions:
+**
+** The above copyright notice and this permission notice shall be included
+** in all copies or substantial portions of the Materials.
+**
+** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+*/
+
+/* Function declaration macros - to move into glplatform.h */
+
+#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__)
+#define WIN32_LEAN_AND_MEAN 1
+#include <windows.h>
+#endif
+
+#ifndef APIENTRY
+#define APIENTRY
+#endif
+#ifndef APIENTRYP
+#define APIENTRYP APIENTRY *
+#endif
+#ifndef GLAPI
+#define GLAPI extern
+#endif
+
+/*************************************************************/
+
+/* Header file version number */
+/* wglext.h last updated 2012/01/04 */
+/* Current version at http://www.opengl.org/registry/ */
+#define WGL_WGLEXT_VERSION 24
+
+#ifndef WGL_ARB_buffer_region
+#define WGL_FRONT_COLOR_BUFFER_BIT_ARB 0x00000001
+#define WGL_BACK_COLOR_BUFFER_BIT_ARB 0x00000002
+#define WGL_DEPTH_BUFFER_BIT_ARB 0x00000004
+#define WGL_STENCIL_BUFFER_BIT_ARB 0x00000008
+#endif
+
+#ifndef WGL_ARB_multisample
+#define WGL_SAMPLE_BUFFERS_ARB 0x2041
+#define WGL_SAMPLES_ARB 0x2042
+#endif
+
+#ifndef WGL_ARB_extensions_string
+#endif
+
+#ifndef WGL_ARB_pixel_format
+#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000
+#define WGL_DRAW_TO_WINDOW_ARB 0x2001
+#define WGL_DRAW_TO_BITMAP_ARB 0x2002
+#define WGL_ACCELERATION_ARB 0x2003
+#define WGL_NEED_PALETTE_ARB 0x2004
+#define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005
+#define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006
+#define WGL_SWAP_METHOD_ARB 0x2007
+#define WGL_NUMBER_OVERLAYS_ARB 0x2008
+#define WGL_NUMBER_UNDERLAYS_ARB 0x2009
+#define WGL_TRANSPARENT_ARB 0x200A
+#define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037
+#define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038
+#define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039
+#define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A
+#define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B
+#define WGL_SHARE_DEPTH_ARB 0x200C
+#define WGL_SHARE_STENCIL_ARB 0x200D
+#define WGL_SHARE_ACCUM_ARB 0x200E
+#define WGL_SUPPORT_GDI_ARB 0x200F
+#define WGL_SUPPORT_OPENGL_ARB 0x2010
+#define WGL_DOUBLE_BUFFER_ARB 0x2011
+#define WGL_STEREO_ARB 0x2012
+#define WGL_PIXEL_TYPE_ARB 0x2013
+#define WGL_COLOR_BITS_ARB 0x2014
+#define WGL_RED_BITS_ARB 0x2015
+#define WGL_RED_SHIFT_ARB 0x2016
+#define WGL_GREEN_BITS_ARB 0x2017
+#define WGL_GREEN_SHIFT_ARB 0x2018
+#define WGL_BLUE_BITS_ARB 0x2019
+#define WGL_BLUE_SHIFT_ARB 0x201A
+#define WGL_ALPHA_BITS_ARB 0x201B
+#define WGL_ALPHA_SHIFT_ARB 0x201C
+#define WGL_ACCUM_BITS_ARB 0x201D
+#define WGL_ACCUM_RED_BITS_ARB 0x201E
+#define WGL_ACCUM_GREEN_BITS_ARB 0x201F
+#define WGL_ACCUM_BLUE_BITS_ARB 0x2020
+#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021
+#define WGL_DEPTH_BITS_ARB 0x2022
+#define WGL_STENCIL_BITS_ARB 0x2023
+#define WGL_AUX_BUFFERS_ARB 0x2024
+#define WGL_NO_ACCELERATION_ARB 0x2025
+#define WGL_GENERIC_ACCELERATION_ARB 0x2026
+#define WGL_FULL_ACCELERATION_ARB 0x2027
+#define WGL_SWAP_EXCHANGE_ARB 0x2028
+#define WGL_SWAP_COPY_ARB 0x2029
+#define WGL_SWAP_UNDEFINED_ARB 0x202A
+#define WGL_TYPE_RGBA_ARB 0x202B
+#define WGL_TYPE_COLORINDEX_ARB 0x202C
+#endif
+
+#ifndef WGL_ARB_make_current_read
+#define ERROR_INVALID_PIXEL_TYPE_ARB 0x2043
+#define ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB 0x2054
+#endif
+
+#ifndef WGL_ARB_pbuffer
+#define WGL_DRAW_TO_PBUFFER_ARB 0x202D
+#define WGL_MAX_PBUFFER_PIXELS_ARB 0x202E
+#define WGL_MAX_PBUFFER_WIDTH_ARB 0x202F
+#define WGL_MAX_PBUFFER_HEIGHT_ARB 0x2030
+#define WGL_PBUFFER_LARGEST_ARB 0x2033
+#define WGL_PBUFFER_WIDTH_ARB 0x2034
+#define WGL_PBUFFER_HEIGHT_ARB 0x2035
+#define WGL_PBUFFER_LOST_ARB 0x2036
+#endif
+
+#ifndef WGL_ARB_render_texture
+#define WGL_BIND_TO_TEXTURE_RGB_ARB 0x2070
+#define WGL_BIND_TO_TEXTURE_RGBA_ARB 0x2071
+#define WGL_TEXTURE_FORMAT_ARB 0x2072
+#define WGL_TEXTURE_TARGET_ARB 0x2073
+#define WGL_MIPMAP_TEXTURE_ARB 0x2074
+#define WGL_TEXTURE_RGB_ARB 0x2075
+#define WGL_TEXTURE_RGBA_ARB 0x2076
+#define WGL_NO_TEXTURE_ARB 0x2077
+#define WGL_TEXTURE_CUBE_MAP_ARB 0x2078
+#define WGL_TEXTURE_1D_ARB 0x2079
+#define WGL_TEXTURE_2D_ARB 0x207A
+#define WGL_MIPMAP_LEVEL_ARB 0x207B
+#define WGL_CUBE_MAP_FACE_ARB 0x207C
+#define WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x207D
+#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x207E
+#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x207F
+#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x2080
+#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x2081
+#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x2082
+#define WGL_FRONT_LEFT_ARB 0x2083
+#define WGL_FRONT_RIGHT_ARB 0x2084
+#define WGL_BACK_LEFT_ARB 0x2085
+#define WGL_BACK_RIGHT_ARB 0x2086
+#define WGL_AUX0_ARB 0x2087
+#define WGL_AUX1_ARB 0x2088
+#define WGL_AUX2_ARB 0x2089
+#define WGL_AUX3_ARB 0x208A
+#define WGL_AUX4_ARB 0x208B
+#define WGL_AUX5_ARB 0x208C
+#define WGL_AUX6_ARB 0x208D
+#define WGL_AUX7_ARB 0x208E
+#define WGL_AUX8_ARB 0x208F
+#define WGL_AUX9_ARB 0x2090
+#endif
+
+#ifndef WGL_ARB_pixel_format_float
+#define WGL_TYPE_RGBA_FLOAT_ARB 0x21A0
+#endif
+
+#ifndef WGL_ARB_framebuffer_sRGB
+#define WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20A9
+#endif
+
+#ifndef WGL_ARB_create_context
+#define WGL_CONTEXT_DEBUG_BIT_ARB 0x00000001
+#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002
+#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091
+#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092
+#define WGL_CONTEXT_LAYER_PLANE_ARB 0x2093
+#define WGL_CONTEXT_FLAGS_ARB 0x2094
+#define ERROR_INVALID_VERSION_ARB 0x2095
+#endif
+
+#ifndef WGL_ARB_create_context_profile
+#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126
+#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
+#define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
+#define ERROR_INVALID_PROFILE_ARB 0x2096
+#endif
+
+#ifndef WGL_ARB_create_context_robustness
+#define WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004
+#define WGL_LOSE_CONTEXT_ON_RESET_ARB 0x8252
+#define WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 0x8256
+#define WGL_NO_RESET_NOTIFICATION_ARB 0x8261
+#endif
+
+#ifndef WGL_EXT_make_current_read
+#define ERROR_INVALID_PIXEL_TYPE_EXT 0x2043
+#endif
+
+#ifndef WGL_EXT_pixel_format
+#define WGL_NUMBER_PIXEL_FORMATS_EXT 0x2000
+#define WGL_DRAW_TO_WINDOW_EXT 0x2001
+#define WGL_DRAW_TO_BITMAP_EXT 0x2002
+#define WGL_ACCELERATION_EXT 0x2003
+#define WGL_NEED_PALETTE_EXT 0x2004
+#define WGL_NEED_SYSTEM_PALETTE_EXT 0x2005
+#define WGL_SWAP_LAYER_BUFFERS_EXT 0x2006
+#define WGL_SWAP_METHOD_EXT 0x2007
+#define WGL_NUMBER_OVERLAYS_EXT 0x2008
+#define WGL_NUMBER_UNDERLAYS_EXT 0x2009
+#define WGL_TRANSPARENT_EXT 0x200A
+#define WGL_TRANSPARENT_VALUE_EXT 0x200B
+#define WGL_SHARE_DEPTH_EXT 0x200C
+#define WGL_SHARE_STENCIL_EXT 0x200D
+#define WGL_SHARE_ACCUM_EXT 0x200E
+#define WGL_SUPPORT_GDI_EXT 0x200F
+#define WGL_SUPPORT_OPENGL_EXT 0x2010
+#define WGL_DOUBLE_BUFFER_EXT 0x2011
+#define WGL_STEREO_EXT 0x2012
+#define WGL_PIXEL_TYPE_EXT 0x2013
+#define WGL_COLOR_BITS_EXT 0x2014
+#define WGL_RED_BITS_EXT 0x2015
+#define WGL_RED_SHIFT_EXT 0x2016
+#define WGL_GREEN_BITS_EXT 0x2017
+#define WGL_GREEN_SHIFT_EXT 0x2018
+#define WGL_BLUE_BITS_EXT 0x2019
+#define WGL_BLUE_SHIFT_EXT 0x201A
+#define WGL_ALPHA_BITS_EXT 0x201B
+#define WGL_ALPHA_SHIFT_EXT 0x201C
+#define WGL_ACCUM_BITS_EXT 0x201D
+#define WGL_ACCUM_RED_BITS_EXT 0x201E
+#define WGL_ACCUM_GREEN_BITS_EXT 0x201F
+#define WGL_ACCUM_BLUE_BITS_EXT 0x2020
+#define WGL_ACCUM_ALPHA_BITS_EXT 0x2021
+#define WGL_DEPTH_BITS_EXT 0x2022
+#define WGL_STENCIL_BITS_EXT 0x2023
+#define WGL_AUX_BUFFERS_EXT 0x2024
+#define WGL_NO_ACCELERATION_EXT 0x2025
+#define WGL_GENERIC_ACCELERATION_EXT 0x2026
+#define WGL_FULL_ACCELERATION_EXT 0x2027
+#define WGL_SWAP_EXCHANGE_EXT 0x2028
+#define WGL_SWAP_COPY_EXT 0x2029
+#define WGL_SWAP_UNDEFINED_EXT 0x202A
+#define WGL_TYPE_RGBA_EXT 0x202B
+#define WGL_TYPE_COLORINDEX_EXT 0x202C
+#endif
+
+#ifndef WGL_EXT_pbuffer
+#define WGL_DRAW_TO_PBUFFER_EXT 0x202D
+#define WGL_MAX_PBUFFER_PIXELS_EXT 0x202E
+#define WGL_MAX_PBUFFER_WIDTH_EXT 0x202F
+#define WGL_MAX_PBUFFER_HEIGHT_EXT 0x2030
+#define WGL_OPTIMAL_PBUFFER_WIDTH_EXT 0x2031
+#define WGL_OPTIMAL_PBUFFER_HEIGHT_EXT 0x2032
+#define WGL_PBUFFER_LARGEST_EXT 0x2033
+#define WGL_PBUFFER_WIDTH_EXT 0x2034
+#define WGL_PBUFFER_HEIGHT_EXT 0x2035
+#endif
+
+#ifndef WGL_EXT_depth_float
+#define WGL_DEPTH_FLOAT_EXT 0x2040
+#endif
+
+#ifndef WGL_3DFX_multisample
+#define WGL_SAMPLE_BUFFERS_3DFX 0x2060
+#define WGL_SAMPLES_3DFX 0x2061
+#endif
+
+#ifndef WGL_EXT_multisample
+#define WGL_SAMPLE_BUFFERS_EXT 0x2041
+#define WGL_SAMPLES_EXT 0x2042
+#endif
+
+#ifndef WGL_I3D_digital_video_control
+#define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_FRAMEBUFFER_I3D 0x2050
+#define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_VALUE_I3D 0x2051
+#define WGL_DIGITAL_VIDEO_CURSOR_INCLUDED_I3D 0x2052
+#define WGL_DIGITAL_VIDEO_GAMMA_CORRECTED_I3D 0x2053
+#endif
+
+#ifndef WGL_I3D_gamma
+#define WGL_GAMMA_TABLE_SIZE_I3D 0x204E
+#define WGL_GAMMA_EXCLUDE_DESKTOP_I3D 0x204F
+#endif
+
+#ifndef WGL_I3D_genlock
+#define WGL_GENLOCK_SOURCE_MULTIVIEW_I3D 0x2044
+#define WGL_GENLOCK_SOURCE_EXTENAL_SYNC_I3D 0x2045
+#define WGL_GENLOCK_SOURCE_EXTENAL_FIELD_I3D 0x2046
+#define WGL_GENLOCK_SOURCE_EXTENAL_TTL_I3D 0x2047
+#define WGL_GENLOCK_SOURCE_DIGITAL_SYNC_I3D 0x2048
+#define WGL_GENLOCK_SOURCE_DIGITAL_FIELD_I3D 0x2049
+#define WGL_GENLOCK_SOURCE_EDGE_FALLING_I3D 0x204A
+#define WGL_GENLOCK_SOURCE_EDGE_RISING_I3D 0x204B
+#define WGL_GENLOCK_SOURCE_EDGE_BOTH_I3D 0x204C
+#endif
+
+#ifndef WGL_I3D_image_buffer
+#define WGL_IMAGE_BUFFER_MIN_ACCESS_I3D 0x00000001
+#define WGL_IMAGE_BUFFER_LOCK_I3D 0x00000002
+#endif
+
+#ifndef WGL_I3D_swap_frame_lock
+#endif
+
+#ifndef WGL_NV_render_depth_texture
+#define WGL_BIND_TO_TEXTURE_DEPTH_NV 0x20A3
+#define WGL_BIND_TO_TEXTURE_RECTANGLE_DEPTH_NV 0x20A4
+#define WGL_DEPTH_TEXTURE_FORMAT_NV 0x20A5
+#define WGL_TEXTURE_DEPTH_COMPONENT_NV 0x20A6
+#define WGL_DEPTH_COMPONENT_NV 0x20A7
+#endif
+
+#ifndef WGL_NV_render_texture_rectangle
+#define WGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV 0x20A0
+#define WGL_BIND_TO_TEXTURE_RECTANGLE_RGBA_NV 0x20A1
+#define WGL_TEXTURE_RECTANGLE_NV 0x20A2
+#endif
+
+#ifndef WGL_ATI_pixel_format_float
+#define WGL_TYPE_RGBA_FLOAT_ATI 0x21A0
+#endif
+
+#ifndef WGL_NV_float_buffer
+#define WGL_FLOAT_COMPONENTS_NV 0x20B0
+#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_R_NV 0x20B1
+#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RG_NV 0x20B2
+#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV 0x20B3
+#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGBA_NV 0x20B4
+#define WGL_TEXTURE_FLOAT_R_NV 0x20B5
+#define WGL_TEXTURE_FLOAT_RG_NV 0x20B6
+#define WGL_TEXTURE_FLOAT_RGB_NV 0x20B7
+#define WGL_TEXTURE_FLOAT_RGBA_NV 0x20B8
+#endif
+
+#ifndef WGL_3DL_stereo_control
+#define WGL_STEREO_EMITTER_ENABLE_3DL 0x2055
+#define WGL_STEREO_EMITTER_DISABLE_3DL 0x2056
+#define WGL_STEREO_POLARITY_NORMAL_3DL 0x2057
+#define WGL_STEREO_POLARITY_INVERT_3DL 0x2058
+#endif
+
+#ifndef WGL_EXT_pixel_format_packed_float
+#define WGL_TYPE_RGBA_UNSIGNED_FLOAT_EXT 0x20A8
+#endif
+
+#ifndef WGL_EXT_framebuffer_sRGB
+#define WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x20A9
+#endif
+
+#ifndef WGL_NV_present_video
+#define WGL_NUM_VIDEO_SLOTS_NV 0x20F0
+#endif
+
+#ifndef WGL_NV_video_out
+#define WGL_BIND_TO_VIDEO_RGB_NV 0x20C0
+#define WGL_BIND_TO_VIDEO_RGBA_NV 0x20C1
+#define WGL_BIND_TO_VIDEO_RGB_AND_DEPTH_NV 0x20C2
+#define WGL_VIDEO_OUT_COLOR_NV 0x20C3
+#define WGL_VIDEO_OUT_ALPHA_NV 0x20C4
+#define WGL_VIDEO_OUT_DEPTH_NV 0x20C5
+#define WGL_VIDEO_OUT_COLOR_AND_ALPHA_NV 0x20C6
+#define WGL_VIDEO_OUT_COLOR_AND_DEPTH_NV 0x20C7
+#define WGL_VIDEO_OUT_FRAME 0x20C8
+#define WGL_VIDEO_OUT_FIELD_1 0x20C9
+#define WGL_VIDEO_OUT_FIELD_2 0x20CA
+#define WGL_VIDEO_OUT_STACKED_FIELDS_1_2 0x20CB
+#define WGL_VIDEO_OUT_STACKED_FIELDS_2_1 0x20CC
+#endif
+
+#ifndef WGL_NV_swap_group
+#endif
+
+#ifndef WGL_NV_gpu_affinity
+#define WGL_ERROR_INCOMPATIBLE_AFFINITY_MASKS_NV 0x20D0
+#define WGL_ERROR_MISSING_AFFINITY_MASK_NV 0x20D1
+#endif
+
+#ifndef WGL_AMD_gpu_association
+#define WGL_GPU_VENDOR_AMD 0x1F00
+#define WGL_GPU_RENDERER_STRING_AMD 0x1F01
+#define WGL_GPU_OPENGL_VERSION_STRING_AMD 0x1F02
+#define WGL_GPU_FASTEST_TARGET_GPUS_AMD 0x21A2
+#define WGL_GPU_RAM_AMD 0x21A3
+#define WGL_GPU_CLOCK_AMD 0x21A4
+#define WGL_GPU_NUM_PIPES_AMD 0x21A5
+#define WGL_GPU_NUM_SIMD_AMD 0x21A6
+#define WGL_GPU_NUM_RB_AMD 0x21A7
+#define WGL_GPU_NUM_SPI_AMD 0x21A8
+#endif
+
+#ifndef WGL_NV_video_capture
+#define WGL_UNIQUE_ID_NV 0x20CE
+#define WGL_NUM_VIDEO_CAPTURE_SLOTS_NV 0x20CF
+#endif
+
+#ifndef WGL_NV_copy_image
+#endif
+
+#ifndef WGL_NV_multisample_coverage
+#define WGL_COVERAGE_SAMPLES_NV 0x2042
+#define WGL_COLOR_SAMPLES_NV 0x20B9
+#endif
+
+#ifndef WGL_EXT_create_context_es2_profile
+#define WGL_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004
+#endif
+
+#ifndef WGL_NV_DX_interop
+#define WGL_ACCESS_READ_ONLY_NV 0x00000000
+#define WGL_ACCESS_READ_WRITE_NV 0x00000001
+#define WGL_ACCESS_WRITE_DISCARD_NV 0x00000002
+#endif
+
+#ifndef WGL_NV_DX_interop2
+#endif
+
+#ifndef WGL_EXT_swap_control_tear
+#endif
+
+
+/*************************************************************/
+
+#ifndef WGL_ARB_pbuffer
+DECLARE_HANDLE(HPBUFFERARB);
+#endif
+#ifndef WGL_EXT_pbuffer
+DECLARE_HANDLE(HPBUFFEREXT);
+#endif
+#ifndef WGL_NV_present_video
+DECLARE_HANDLE(HVIDEOOUTPUTDEVICENV);
+#endif
+#ifndef WGL_NV_video_output
+DECLARE_HANDLE(HPVIDEODEV);
+#endif
+#ifndef WGL_NV_gpu_affinity
+DECLARE_HANDLE(HPGPUNV);
+DECLARE_HANDLE(HGPUNV);
+
+typedef struct _GPU_DEVICE {
+ DWORD cb;
+ CHAR DeviceName[32];
+ CHAR DeviceString[128];
+ DWORD Flags;
+ RECT rcVirtualScreen;
+} GPU_DEVICE, *PGPU_DEVICE;
+#endif
+#ifndef WGL_NV_video_capture
+DECLARE_HANDLE(HVIDEOINPUTDEVICENV);
+#endif
+
+#ifndef WGL_ARB_buffer_region
+#define WGL_ARB_buffer_region 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern HANDLE WINAPI wglCreateBufferRegionARB (HDC hDC, int iLayerPlane, UINT uType);
+extern VOID WINAPI wglDeleteBufferRegionARB (HANDLE hRegion);
+extern BOOL WINAPI wglSaveBufferRegionARB (HANDLE hRegion, int x, int y, int width, int height);
+extern BOOL WINAPI wglRestoreBufferRegionARB (HANDLE hRegion, int x, int y, int width, int height, int xSrc, int ySrc);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef HANDLE (WINAPI * PFNWGLCREATEBUFFERREGIONARBPROC) (HDC hDC, int iLayerPlane, UINT uType);
+typedef VOID (WINAPI * PFNWGLDELETEBUFFERREGIONARBPROC) (HANDLE hRegion);
+typedef BOOL (WINAPI * PFNWGLSAVEBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height);
+typedef BOOL (WINAPI * PFNWGLRESTOREBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height, int xSrc, int ySrc);
+#endif
+
+#ifndef WGL_ARB_multisample
+#define WGL_ARB_multisample 1
+#endif
+
+#ifndef WGL_ARB_extensions_string
+#define WGL_ARB_extensions_string 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern const char * WINAPI wglGetExtensionsStringARB (HDC hdc);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef const char * (WINAPI * PFNWGLGETEXTENSIONSSTRINGARBPROC) (HDC hdc);
+#endif
+
+#ifndef WGL_ARB_pixel_format
+#define WGL_ARB_pixel_format 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglGetPixelFormatAttribivARB (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues);
+extern BOOL WINAPI wglGetPixelFormatAttribfvARB (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, FLOAT *pfValues);
+extern BOOL WINAPI wglChoosePixelFormatARB (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues);
+typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, FLOAT *pfValues);
+typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATARBPROC) (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats);
+#endif
+
+#ifndef WGL_ARB_make_current_read
+#define WGL_ARB_make_current_read 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglMakeContextCurrentARB (HDC hDrawDC, HDC hReadDC, HGLRC hglrc);
+extern HDC WINAPI wglGetCurrentReadDCARB (void);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLMAKECONTEXTCURRENTARBPROC) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc);
+typedef HDC (WINAPI * PFNWGLGETCURRENTREADDCARBPROC) (void);
+#endif
+
+#ifndef WGL_ARB_pbuffer
+#define WGL_ARB_pbuffer 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern HPBUFFERARB WINAPI wglCreatePbufferARB (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList);
+extern HDC WINAPI wglGetPbufferDCARB (HPBUFFERARB hPbuffer);
+extern int WINAPI wglReleasePbufferDCARB (HPBUFFERARB hPbuffer, HDC hDC);
+extern BOOL WINAPI wglDestroyPbufferARB (HPBUFFERARB hPbuffer);
+extern BOOL WINAPI wglQueryPbufferARB (HPBUFFERARB hPbuffer, int iAttribute, int *piValue);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef HPBUFFERARB (WINAPI * PFNWGLCREATEPBUFFERARBPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList);
+typedef HDC (WINAPI * PFNWGLGETPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer);
+typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer, HDC hDC);
+typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFERARBPROC) (HPBUFFERARB hPbuffer);
+typedef BOOL (WINAPI * PFNWGLQUERYPBUFFERARBPROC) (HPBUFFERARB hPbuffer, int iAttribute, int *piValue);
+#endif
+
+#ifndef WGL_ARB_render_texture
+#define WGL_ARB_render_texture 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglBindTexImageARB (HPBUFFERARB hPbuffer, int iBuffer);
+extern BOOL WINAPI wglReleaseTexImageARB (HPBUFFERARB hPbuffer, int iBuffer);
+extern BOOL WINAPI wglSetPbufferAttribARB (HPBUFFERARB hPbuffer, const int *piAttribList);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLBINDTEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer);
+typedef BOOL (WINAPI * PFNWGLRELEASETEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer);
+typedef BOOL (WINAPI * PFNWGLSETPBUFFERATTRIBARBPROC) (HPBUFFERARB hPbuffer, const int *piAttribList);
+#endif
+
+#ifndef WGL_ARB_pixel_format_float
+#define WGL_ARB_pixel_format_float 1
+#endif
+
+#ifndef WGL_ARB_framebuffer_sRGB
+#define WGL_ARB_framebuffer_sRGB 1
+#endif
+
+#ifndef WGL_ARB_create_context
+#define WGL_ARB_create_context 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern HGLRC WINAPI wglCreateContextAttribsARB (HDC hDC, HGLRC hShareContext, const int *attribList);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef HGLRC (WINAPI * PFNWGLCREATECONTEXTATTRIBSARBPROC) (HDC hDC, HGLRC hShareContext, const int *attribList);
+#endif
+
+#ifndef WGL_ARB_create_context_profile
+#define WGL_ARB_create_context_profile 1
+#endif
+
+#ifndef WGL_ARB_create_context_robustness
+#define WGL_ARB_create_context_robustness 1
+#endif
+
+#ifndef WGL_EXT_display_color_table
+#define WGL_EXT_display_color_table 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern GLboolean WINAPI wglCreateDisplayColorTableEXT (GLushort id);
+extern GLboolean WINAPI wglLoadDisplayColorTableEXT (const GLushort *table, GLuint length);
+extern GLboolean WINAPI wglBindDisplayColorTableEXT (GLushort id);
+extern VOID WINAPI wglDestroyDisplayColorTableEXT (GLushort id);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef GLboolean (WINAPI * PFNWGLCREATEDISPLAYCOLORTABLEEXTPROC) (GLushort id);
+typedef GLboolean (WINAPI * PFNWGLLOADDISPLAYCOLORTABLEEXTPROC) (const GLushort *table, GLuint length);
+typedef GLboolean (WINAPI * PFNWGLBINDDISPLAYCOLORTABLEEXTPROC) (GLushort id);
+typedef VOID (WINAPI * PFNWGLDESTROYDISPLAYCOLORTABLEEXTPROC) (GLushort id);
+#endif
+
+#ifndef WGL_EXT_extensions_string
+#define WGL_EXT_extensions_string 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern const char * WINAPI wglGetExtensionsStringEXT (void);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef const char * (WINAPI * PFNWGLGETEXTENSIONSSTRINGEXTPROC) (void);
+#endif
+
+#ifndef WGL_EXT_make_current_read
+#define WGL_EXT_make_current_read 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglMakeContextCurrentEXT (HDC hDrawDC, HDC hReadDC, HGLRC hglrc);
+extern HDC WINAPI wglGetCurrentReadDCEXT (void);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLMAKECONTEXTCURRENTEXTPROC) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc);
+typedef HDC (WINAPI * PFNWGLGETCURRENTREADDCEXTPROC) (void);
+#endif
+
+#ifndef WGL_EXT_pbuffer
+#define WGL_EXT_pbuffer 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern HPBUFFEREXT WINAPI wglCreatePbufferEXT (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList);
+extern HDC WINAPI wglGetPbufferDCEXT (HPBUFFEREXT hPbuffer);
+extern int WINAPI wglReleasePbufferDCEXT (HPBUFFEREXT hPbuffer, HDC hDC);
+extern BOOL WINAPI wglDestroyPbufferEXT (HPBUFFEREXT hPbuffer);
+extern BOOL WINAPI wglQueryPbufferEXT (HPBUFFEREXT hPbuffer, int iAttribute, int *piValue);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef HPBUFFEREXT (WINAPI * PFNWGLCREATEPBUFFEREXTPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList);
+typedef HDC (WINAPI * PFNWGLGETPBUFFERDCEXTPROC) (HPBUFFEREXT hPbuffer);
+typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCEXTPROC) (HPBUFFEREXT hPbuffer, HDC hDC);
+typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFEREXTPROC) (HPBUFFEREXT hPbuffer);
+typedef BOOL (WINAPI * PFNWGLQUERYPBUFFEREXTPROC) (HPBUFFEREXT hPbuffer, int iAttribute, int *piValue);
+#endif
+
+#ifndef WGL_EXT_pixel_format
+#define WGL_EXT_pixel_format 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglGetPixelFormatAttribivEXT (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, int *piValues);
+extern BOOL WINAPI wglGetPixelFormatAttribfvEXT (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, FLOAT *pfValues);
+extern BOOL WINAPI wglChoosePixelFormatEXT (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVEXTPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, int *piValues);
+typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVEXTPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, FLOAT *pfValues);
+typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATEXTPROC) (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats);
+#endif
+
+#ifndef WGL_EXT_swap_control
+#define WGL_EXT_swap_control 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglSwapIntervalEXT (int interval);
+extern int WINAPI wglGetSwapIntervalEXT (void);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC) (int interval);
+typedef int (WINAPI * PFNWGLGETSWAPINTERVALEXTPROC) (void);
+#endif
+
+#ifndef WGL_EXT_depth_float
+#define WGL_EXT_depth_float 1
+#endif
+
+#ifndef WGL_NV_vertex_array_range
+#define WGL_NV_vertex_array_range 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern void* WINAPI wglAllocateMemoryNV (GLsizei size, GLfloat readfreq, GLfloat writefreq, GLfloat priority);
+extern void WINAPI wglFreeMemoryNV (void *pointer);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef void* (WINAPI * PFNWGLALLOCATEMEMORYNVPROC) (GLsizei size, GLfloat readfreq, GLfloat writefreq, GLfloat priority);
+typedef void (WINAPI * PFNWGLFREEMEMORYNVPROC) (void *pointer);
+#endif
+
+#ifndef WGL_3DFX_multisample
+#define WGL_3DFX_multisample 1
+#endif
+
+#ifndef WGL_EXT_multisample
+#define WGL_EXT_multisample 1
+#endif
+
+#ifndef WGL_OML_sync_control
+#define WGL_OML_sync_control 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglGetSyncValuesOML (HDC hdc, INT64 *ust, INT64 *msc, INT64 *sbc);
+extern BOOL WINAPI wglGetMscRateOML (HDC hdc, INT32 *numerator, INT32 *denominator);
+extern INT64 WINAPI wglSwapBuffersMscOML (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder);
+extern INT64 WINAPI wglSwapLayerBuffersMscOML (HDC hdc, int fuPlanes, INT64 target_msc, INT64 divisor, INT64 remainder);
+extern BOOL WINAPI wglWaitForMscOML (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder, INT64 *ust, INT64 *msc, INT64 *sbc);
+extern BOOL WINAPI wglWaitForSbcOML (HDC hdc, INT64 target_sbc, INT64 *ust, INT64 *msc, INT64 *sbc);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLGETSYNCVALUESOMLPROC) (HDC hdc, INT64 *ust, INT64 *msc, INT64 *sbc);
+typedef BOOL (WINAPI * PFNWGLGETMSCRATEOMLPROC) (HDC hdc, INT32 *numerator, INT32 *denominator);
+typedef INT64 (WINAPI * PFNWGLSWAPBUFFERSMSCOMLPROC) (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder);
+typedef INT64 (WINAPI * PFNWGLSWAPLAYERBUFFERSMSCOMLPROC) (HDC hdc, int fuPlanes, INT64 target_msc, INT64 divisor, INT64 remainder);
+typedef BOOL (WINAPI * PFNWGLWAITFORMSCOMLPROC) (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder, INT64 *ust, INT64 *msc, INT64 *sbc);
+typedef BOOL (WINAPI * PFNWGLWAITFORSBCOMLPROC) (HDC hdc, INT64 target_sbc, INT64 *ust, INT64 *msc, INT64 *sbc);
+#endif
+
+#ifndef WGL_I3D_digital_video_control
+#define WGL_I3D_digital_video_control 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglGetDigitalVideoParametersI3D (HDC hDC, int iAttribute, int *piValue);
+extern BOOL WINAPI wglSetDigitalVideoParametersI3D (HDC hDC, int iAttribute, const int *piValue);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLGETDIGITALVIDEOPARAMETERSI3DPROC) (HDC hDC, int iAttribute, int *piValue);
+typedef BOOL (WINAPI * PFNWGLSETDIGITALVIDEOPARAMETERSI3DPROC) (HDC hDC, int iAttribute, const int *piValue);
+#endif
+
+#ifndef WGL_I3D_gamma
+#define WGL_I3D_gamma 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglGetGammaTableParametersI3D (HDC hDC, int iAttribute, int *piValue);
+extern BOOL WINAPI wglSetGammaTableParametersI3D (HDC hDC, int iAttribute, const int *piValue);
+extern BOOL WINAPI wglGetGammaTableI3D (HDC hDC, int iEntries, USHORT *puRed, USHORT *puGreen, USHORT *puBlue);
+extern BOOL WINAPI wglSetGammaTableI3D (HDC hDC, int iEntries, const USHORT *puRed, const USHORT *puGreen, const USHORT *puBlue);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLGETGAMMATABLEPARAMETERSI3DPROC) (HDC hDC, int iAttribute, int *piValue);
+typedef BOOL (WINAPI * PFNWGLSETGAMMATABLEPARAMETERSI3DPROC) (HDC hDC, int iAttribute, const int *piValue);
+typedef BOOL (WINAPI * PFNWGLGETGAMMATABLEI3DPROC) (HDC hDC, int iEntries, USHORT *puRed, USHORT *puGreen, USHORT *puBlue);
+typedef BOOL (WINAPI * PFNWGLSETGAMMATABLEI3DPROC) (HDC hDC, int iEntries, const USHORT *puRed, const USHORT *puGreen, const USHORT *puBlue);
+#endif
+
+#ifndef WGL_I3D_genlock
+#define WGL_I3D_genlock 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglEnableGenlockI3D (HDC hDC);
+extern BOOL WINAPI wglDisableGenlockI3D (HDC hDC);
+extern BOOL WINAPI wglIsEnabledGenlockI3D (HDC hDC, BOOL *pFlag);
+extern BOOL WINAPI wglGenlockSourceI3D (HDC hDC, UINT uSource);
+extern BOOL WINAPI wglGetGenlockSourceI3D (HDC hDC, UINT *uSource);
+extern BOOL WINAPI wglGenlockSourceEdgeI3D (HDC hDC, UINT uEdge);
+extern BOOL WINAPI wglGetGenlockSourceEdgeI3D (HDC hDC, UINT *uEdge);
+extern BOOL WINAPI wglGenlockSampleRateI3D (HDC hDC, UINT uRate);
+extern BOOL WINAPI wglGetGenlockSampleRateI3D (HDC hDC, UINT *uRate);
+extern BOOL WINAPI wglGenlockSourceDelayI3D (HDC hDC, UINT uDelay);
+extern BOOL WINAPI wglGetGenlockSourceDelayI3D (HDC hDC, UINT *uDelay);
+extern BOOL WINAPI wglQueryGenlockMaxSourceDelayI3D (HDC hDC, UINT *uMaxLineDelay, UINT *uMaxPixelDelay);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLENABLEGENLOCKI3DPROC) (HDC hDC);
+typedef BOOL (WINAPI * PFNWGLDISABLEGENLOCKI3DPROC) (HDC hDC);
+typedef BOOL (WINAPI * PFNWGLISENABLEDGENLOCKI3DPROC) (HDC hDC, BOOL *pFlag);
+typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEI3DPROC) (HDC hDC, UINT uSource);
+typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEI3DPROC) (HDC hDC, UINT *uSource);
+typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEEDGEI3DPROC) (HDC hDC, UINT uEdge);
+typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEEDGEI3DPROC) (HDC hDC, UINT *uEdge);
+typedef BOOL (WINAPI * PFNWGLGENLOCKSAMPLERATEI3DPROC) (HDC hDC, UINT uRate);
+typedef BOOL (WINAPI * PFNWGLGETGENLOCKSAMPLERATEI3DPROC) (HDC hDC, UINT *uRate);
+typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEDELAYI3DPROC) (HDC hDC, UINT uDelay);
+typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEDELAYI3DPROC) (HDC hDC, UINT *uDelay);
+typedef BOOL (WINAPI * PFNWGLQUERYGENLOCKMAXSOURCEDELAYI3DPROC) (HDC hDC, UINT *uMaxLineDelay, UINT *uMaxPixelDelay);
+#endif
+
+#ifndef WGL_I3D_image_buffer
+#define WGL_I3D_image_buffer 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern LPVOID WINAPI wglCreateImageBufferI3D (HDC hDC, DWORD dwSize, UINT uFlags);
+extern BOOL WINAPI wglDestroyImageBufferI3D (HDC hDC, LPVOID pAddress);
+extern BOOL WINAPI wglAssociateImageBufferEventsI3D (HDC hDC, const HANDLE *pEvent, const LPVOID *pAddress, const DWORD *pSize, UINT count);
+extern BOOL WINAPI wglReleaseImageBufferEventsI3D (HDC hDC, const LPVOID *pAddress, UINT count);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef LPVOID (WINAPI * PFNWGLCREATEIMAGEBUFFERI3DPROC) (HDC hDC, DWORD dwSize, UINT uFlags);
+typedef BOOL (WINAPI * PFNWGLDESTROYIMAGEBUFFERI3DPROC) (HDC hDC, LPVOID pAddress);
+typedef BOOL (WINAPI * PFNWGLASSOCIATEIMAGEBUFFEREVENTSI3DPROC) (HDC hDC, const HANDLE *pEvent, const LPVOID *pAddress, const DWORD *pSize, UINT count);
+typedef BOOL (WINAPI * PFNWGLRELEASEIMAGEBUFFEREVENTSI3DPROC) (HDC hDC, const LPVOID *pAddress, UINT count);
+#endif
+
+#ifndef WGL_I3D_swap_frame_lock
+#define WGL_I3D_swap_frame_lock 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglEnableFrameLockI3D (void);
+extern BOOL WINAPI wglDisableFrameLockI3D (void);
+extern BOOL WINAPI wglIsEnabledFrameLockI3D (BOOL *pFlag);
+extern BOOL WINAPI wglQueryFrameLockMasterI3D (BOOL *pFlag);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLENABLEFRAMELOCKI3DPROC) (void);
+typedef BOOL (WINAPI * PFNWGLDISABLEFRAMELOCKI3DPROC) (void);
+typedef BOOL (WINAPI * PFNWGLISENABLEDFRAMELOCKI3DPROC) (BOOL *pFlag);
+typedef BOOL (WINAPI * PFNWGLQUERYFRAMELOCKMASTERI3DPROC) (BOOL *pFlag);
+#endif
+
+#ifndef WGL_I3D_swap_frame_usage
+#define WGL_I3D_swap_frame_usage 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglGetFrameUsageI3D (float *pUsage);
+extern BOOL WINAPI wglBeginFrameTrackingI3D (void);
+extern BOOL WINAPI wglEndFrameTrackingI3D (void);
+extern BOOL WINAPI wglQueryFrameTrackingI3D (DWORD *pFrameCount, DWORD *pMissedFrames, float *pLastMissedUsage);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLGETFRAMEUSAGEI3DPROC) (float *pUsage);
+typedef BOOL (WINAPI * PFNWGLBEGINFRAMETRACKINGI3DPROC) (void);
+typedef BOOL (WINAPI * PFNWGLENDFRAMETRACKINGI3DPROC) (void);
+typedef BOOL (WINAPI * PFNWGLQUERYFRAMETRACKINGI3DPROC) (DWORD *pFrameCount, DWORD *pMissedFrames, float *pLastMissedUsage);
+#endif
+
+#ifndef WGL_ATI_pixel_format_float
+#define WGL_ATI_pixel_format_float 1
+#endif
+
+#ifndef WGL_NV_float_buffer
+#define WGL_NV_float_buffer 1
+#endif
+
+#ifndef WGL_3DL_stereo_control
+#define WGL_3DL_stereo_control 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglSetStereoEmitterState3DL (HDC hDC, UINT uState);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLSETSTEREOEMITTERSTATE3DLPROC) (HDC hDC, UINT uState);
+#endif
+
+#ifndef WGL_EXT_pixel_format_packed_float
+#define WGL_EXT_pixel_format_packed_float 1
+#endif
+
+#ifndef WGL_EXT_framebuffer_sRGB
+#define WGL_EXT_framebuffer_sRGB 1
+#endif
+
+#ifndef WGL_NV_present_video
+#define WGL_NV_present_video 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern int WINAPI wglEnumerateVideoDevicesNV (HDC hDC, HVIDEOOUTPUTDEVICENV *phDeviceList);
+extern BOOL WINAPI wglBindVideoDeviceNV (HDC hDC, unsigned int uVideoSlot, HVIDEOOUTPUTDEVICENV hVideoDevice, const int *piAttribList);
+extern BOOL WINAPI wglQueryCurrentContextNV (int iAttribute, int *piValue);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef int (WINAPI * PFNWGLENUMERATEVIDEODEVICESNVPROC) (HDC hDC, HVIDEOOUTPUTDEVICENV *phDeviceList);
+typedef BOOL (WINAPI * PFNWGLBINDVIDEODEVICENVPROC) (HDC hDC, unsigned int uVideoSlot, HVIDEOOUTPUTDEVICENV hVideoDevice, const int *piAttribList);
+typedef BOOL (WINAPI * PFNWGLQUERYCURRENTCONTEXTNVPROC) (int iAttribute, int *piValue);
+#endif
+
+#ifndef WGL_NV_video_output
+#define WGL_NV_video_output 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglGetVideoDeviceNV (HDC hDC, int numDevices, HPVIDEODEV *hVideoDevice);
+extern BOOL WINAPI wglReleaseVideoDeviceNV (HPVIDEODEV hVideoDevice);
+extern BOOL WINAPI wglBindVideoImageNV (HPVIDEODEV hVideoDevice, HPBUFFERARB hPbuffer, int iVideoBuffer);
+extern BOOL WINAPI wglReleaseVideoImageNV (HPBUFFERARB hPbuffer, int iVideoBuffer);
+extern BOOL WINAPI wglSendPbufferToVideoNV (HPBUFFERARB hPbuffer, int iBufferType, unsigned long *pulCounterPbuffer, BOOL bBlock);
+extern BOOL WINAPI wglGetVideoInfoNV (HPVIDEODEV hpVideoDevice, unsigned long *pulCounterOutputPbuffer, unsigned long *pulCounterOutputVideo);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLGETVIDEODEVICENVPROC) (HDC hDC, int numDevices, HPVIDEODEV *hVideoDevice);
+typedef BOOL (WINAPI * PFNWGLRELEASEVIDEODEVICENVPROC) (HPVIDEODEV hVideoDevice);
+typedef BOOL (WINAPI * PFNWGLBINDVIDEOIMAGENVPROC) (HPVIDEODEV hVideoDevice, HPBUFFERARB hPbuffer, int iVideoBuffer);
+typedef BOOL (WINAPI * PFNWGLRELEASEVIDEOIMAGENVPROC) (HPBUFFERARB hPbuffer, int iVideoBuffer);
+typedef BOOL (WINAPI * PFNWGLSENDPBUFFERTOVIDEONVPROC) (HPBUFFERARB hPbuffer, int iBufferType, unsigned long *pulCounterPbuffer, BOOL bBlock);
+typedef BOOL (WINAPI * PFNWGLGETVIDEOINFONVPROC) (HPVIDEODEV hpVideoDevice, unsigned long *pulCounterOutputPbuffer, unsigned long *pulCounterOutputVideo);
+#endif
+
+#ifndef WGL_NV_swap_group
+#define WGL_NV_swap_group 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglJoinSwapGroupNV (HDC hDC, GLuint group);
+extern BOOL WINAPI wglBindSwapBarrierNV (GLuint group, GLuint barrier);
+extern BOOL WINAPI wglQuerySwapGroupNV (HDC hDC, GLuint *group, GLuint *barrier);
+extern BOOL WINAPI wglQueryMaxSwapGroupsNV (HDC hDC, GLuint *maxGroups, GLuint *maxBarriers);
+extern BOOL WINAPI wglQueryFrameCountNV (HDC hDC, GLuint *count);
+extern BOOL WINAPI wglResetFrameCountNV (HDC hDC);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLJOINSWAPGROUPNVPROC) (HDC hDC, GLuint group);
+typedef BOOL (WINAPI * PFNWGLBINDSWAPBARRIERNVPROC) (GLuint group, GLuint barrier);
+typedef BOOL (WINAPI * PFNWGLQUERYSWAPGROUPNVPROC) (HDC hDC, GLuint *group, GLuint *barrier);
+typedef BOOL (WINAPI * PFNWGLQUERYMAXSWAPGROUPSNVPROC) (HDC hDC, GLuint *maxGroups, GLuint *maxBarriers);
+typedef BOOL (WINAPI * PFNWGLQUERYFRAMECOUNTNVPROC) (HDC hDC, GLuint *count);
+typedef BOOL (WINAPI * PFNWGLRESETFRAMECOUNTNVPROC) (HDC hDC);
+#endif
+
+#ifndef WGL_NV_gpu_affinity
+#define WGL_NV_gpu_affinity 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglEnumGpusNV (UINT iGpuIndex, HGPUNV *phGpu);
+extern BOOL WINAPI wglEnumGpuDevicesNV (HGPUNV hGpu, UINT iDeviceIndex, PGPU_DEVICE lpGpuDevice);
+extern HDC WINAPI wglCreateAffinityDCNV (const HGPUNV *phGpuList);
+extern BOOL WINAPI wglEnumGpusFromAffinityDCNV (HDC hAffinityDC, UINT iGpuIndex, HGPUNV *hGpu);
+extern BOOL WINAPI wglDeleteDCNV (HDC hdc);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLENUMGPUSNVPROC) (UINT iGpuIndex, HGPUNV *phGpu);
+typedef BOOL (WINAPI * PFNWGLENUMGPUDEVICESNVPROC) (HGPUNV hGpu, UINT iDeviceIndex, PGPU_DEVICE lpGpuDevice);
+typedef HDC (WINAPI * PFNWGLCREATEAFFINITYDCNVPROC) (const HGPUNV *phGpuList);
+typedef BOOL (WINAPI * PFNWGLENUMGPUSFROMAFFINITYDCNVPROC) (HDC hAffinityDC, UINT iGpuIndex, HGPUNV *hGpu);
+typedef BOOL (WINAPI * PFNWGLDELETEDCNVPROC) (HDC hdc);
+#endif
+
+#ifndef WGL_AMD_gpu_association
+#define WGL_AMD_gpu_association 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern UINT WINAPI wglGetGPUIDsAMD (UINT maxCount, UINT *ids);
+extern INT WINAPI wglGetGPUInfoAMD (UINT id, int property, GLenum dataType, UINT size, void *data);
+extern UINT WINAPI wglGetContextGPUIDAMD (HGLRC hglrc);
+extern HGLRC WINAPI wglCreateAssociatedContextAMD (UINT id);
+extern HGLRC WINAPI wglCreateAssociatedContextAttribsAMD (UINT id, HGLRC hShareContext, const int *attribList);
+extern BOOL WINAPI wglDeleteAssociatedContextAMD (HGLRC hglrc);
+extern BOOL WINAPI wglMakeAssociatedContextCurrentAMD (HGLRC hglrc);
+extern HGLRC WINAPI wglGetCurrentAssociatedContextAMD (void);
+extern VOID WINAPI wglBlitContextFramebufferAMD (HGLRC dstCtx, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef UINT (WINAPI * PFNWGLGETGPUIDSAMDPROC) (UINT maxCount, UINT *ids);
+typedef INT (WINAPI * PFNWGLGETGPUINFOAMDPROC) (UINT id, int property, GLenum dataType, UINT size, void *data);
+typedef UINT (WINAPI * PFNWGLGETCONTEXTGPUIDAMDPROC) (HGLRC hglrc);
+typedef HGLRC (WINAPI * PFNWGLCREATEASSOCIATEDCONTEXTAMDPROC) (UINT id);
+typedef HGLRC (WINAPI * PFNWGLCREATEASSOCIATEDCONTEXTATTRIBSAMDPROC) (UINT id, HGLRC hShareContext, const int *attribList);
+typedef BOOL (WINAPI * PFNWGLDELETEASSOCIATEDCONTEXTAMDPROC) (HGLRC hglrc);
+typedef BOOL (WINAPI * PFNWGLMAKEASSOCIATEDCONTEXTCURRENTAMDPROC) (HGLRC hglrc);
+typedef HGLRC (WINAPI * PFNWGLGETCURRENTASSOCIATEDCONTEXTAMDPROC) (void);
+typedef VOID (WINAPI * PFNWGLBLITCONTEXTFRAMEBUFFERAMDPROC) (HGLRC dstCtx, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+#endif
+
+#ifndef WGL_NV_video_capture
+#define WGL_NV_video_capture 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglBindVideoCaptureDeviceNV (UINT uVideoSlot, HVIDEOINPUTDEVICENV hDevice);
+extern UINT WINAPI wglEnumerateVideoCaptureDevicesNV (HDC hDc, HVIDEOINPUTDEVICENV *phDeviceList);
+extern BOOL WINAPI wglLockVideoCaptureDeviceNV (HDC hDc, HVIDEOINPUTDEVICENV hDevice);
+extern BOOL WINAPI wglQueryVideoCaptureDeviceNV (HDC hDc, HVIDEOINPUTDEVICENV hDevice, int iAttribute, int *piValue);
+extern BOOL WINAPI wglReleaseVideoCaptureDeviceNV (HDC hDc, HVIDEOINPUTDEVICENV hDevice);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLBINDVIDEOCAPTUREDEVICENVPROC) (UINT uVideoSlot, HVIDEOINPUTDEVICENV hDevice);
+typedef UINT (WINAPI * PFNWGLENUMERATEVIDEOCAPTUREDEVICESNVPROC) (HDC hDc, HVIDEOINPUTDEVICENV *phDeviceList);
+typedef BOOL (WINAPI * PFNWGLLOCKVIDEOCAPTUREDEVICENVPROC) (HDC hDc, HVIDEOINPUTDEVICENV hDevice);
+typedef BOOL (WINAPI * PFNWGLQUERYVIDEOCAPTUREDEVICENVPROC) (HDC hDc, HVIDEOINPUTDEVICENV hDevice, int iAttribute, int *piValue);
+typedef BOOL (WINAPI * PFNWGLRELEASEVIDEOCAPTUREDEVICENVPROC) (HDC hDc, HVIDEOINPUTDEVICENV hDevice);
+#endif
+
+#ifndef WGL_NV_copy_image
+#define WGL_NV_copy_image 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglCopyImageSubDataNV (HGLRC hSrcRC, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, HGLRC hDstRC, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLCOPYIMAGESUBDATANVPROC) (HGLRC hSrcRC, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, HGLRC hDstRC, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth);
+#endif
+
+#ifndef WGL_NV_multisample_coverage
+#define WGL_NV_multisample_coverage 1
+#endif
+
+#ifndef WGL_NV_DX_interop
+#define WGL_NV_DX_interop 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglDXSetResourceShareHandleNV (void *dxObject, HANDLE shareHandle);
+extern HANDLE WINAPI wglDXOpenDeviceNV (void *dxDevice);
+extern BOOL WINAPI wglDXCloseDeviceNV (HANDLE hDevice);
+extern HANDLE WINAPI wglDXRegisterObjectNV (HANDLE hDevice, void *dxObject, GLuint name, GLenum type, GLenum access);
+extern BOOL WINAPI wglDXUnregisterObjectNV (HANDLE hDevice, HANDLE hObject);
+extern BOOL WINAPI wglDXObjectAccessNV (HANDLE hObject, GLenum access);
+extern BOOL WINAPI wglDXLockObjectsNV (HANDLE hDevice, GLint count, HANDLE *hObjects);
+extern BOOL WINAPI wglDXUnlockObjectsNV (HANDLE hDevice, GLint count, HANDLE *hObjects);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLDXSETRESOURCESHAREHANDLENVPROC) (void *dxObject, HANDLE shareHandle);
+typedef HANDLE (WINAPI * PFNWGLDXOPENDEVICENVPROC) (void *dxDevice);
+typedef BOOL (WINAPI * PFNWGLDXCLOSEDEVICENVPROC) (HANDLE hDevice);
+typedef HANDLE (WINAPI * PFNWGLDXREGISTEROBJECTNVPROC) (HANDLE hDevice, void *dxObject, GLuint name, GLenum type, GLenum access);
+typedef BOOL (WINAPI * PFNWGLDXUNREGISTEROBJECTNVPROC) (HANDLE hDevice, HANDLE hObject);
+typedef BOOL (WINAPI * PFNWGLDXOBJECTACCESSNVPROC) (HANDLE hObject, GLenum access);
+typedef BOOL (WINAPI * PFNWGLDXLOCKOBJECTSNVPROC) (HANDLE hDevice, GLint count, HANDLE *hObjects);
+typedef BOOL (WINAPI * PFNWGLDXUNLOCKOBJECTSNVPROC) (HANDLE hDevice, GLint count, HANDLE *hObjects);
+#endif
+
+#ifndef WGL_NV_DX_interop2
+#define WGL_NV_DX_interop2 1
+#endif
+
+#ifndef WGL_EXT_swap_control_tear
+#define WGL_EXT_swap_control_tear 1
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/graphics/GLBufferCache.cpp b/src/graphics/GLBufferCache.cpp
new file mode 100644
index 0000000..5acd1ce
--- /dev/null
+++ b/src/graphics/GLBufferCache.cpp
@@ -0,0 +1,73 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "GLBufferCache.h"
+
+#include "GLContext.h"
+
+#include "../base/Exception.h"
+
+using namespace std;
+using namespace boost;
+
+namespace avg {
+
+GLBufferCache::GLBufferCache()
+{
+}
+
+GLBufferCache::~GLBufferCache()
+{
+ deleteBuffers();
+}
+
+unsigned int GLBufferCache::getBuffer()
+{
+ unsigned int bufferID;
+ if (m_BufferIDs.empty()) {
+ glproc::GenBuffers(1, &bufferID);
+ GLContext::checkError("PBO: GenBuffers()");
+ } else {
+ bufferID = m_BufferIDs.back();
+ m_BufferIDs.pop_back();
+ }
+ return bufferID;
+}
+
+void GLBufferCache::returnBuffer(unsigned int bufferID)
+{
+ m_BufferIDs.push_back(bufferID);
+}
+
+unsigned int GLBufferCache::getNumBuffers() const
+{
+ return m_BufferIDs.size();
+}
+
+void GLBufferCache::deleteBuffers()
+{
+ for (unsigned i=0; i<m_BufferIDs.size(); ++i) {
+ glproc::DeleteBuffers(1, &(m_BufferIDs[i]));
+ }
+ m_BufferIDs.clear();
+}
+
+}
diff --git a/src/graphics/GLBufferCache.h b/src/graphics/GLBufferCache.h
new file mode 100644
index 0000000..d357d07
--- /dev/null
+++ b/src/graphics/GLBufferCache.h
@@ -0,0 +1,55 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _GLBufferCache_H_
+#define _GLBufferCache_H_
+
+#include "../api.h"
+
+#include "../graphics/OGLHelper.h"
+
+#include <vector>
+
+#include <boost/shared_ptr.hpp>
+#include <boost/thread/tss.hpp>
+
+namespace avg {
+
+class AVG_API GLBufferCache {
+public:
+ GLBufferCache();
+ virtual ~GLBufferCache();
+
+ unsigned int getBuffer();
+ void returnBuffer(unsigned int);
+
+ unsigned int getNumBuffers() const;
+
+ void deleteBuffers();
+
+private:
+ std::vector<unsigned int> m_BufferIDs;
+};
+
+}
+
+#endif
+
diff --git a/src/graphics/GLConfig.cpp b/src/graphics/GLConfig.cpp
new file mode 100644
index 0000000..72cc61a
--- /dev/null
+++ b/src/graphics/GLConfig.cpp
@@ -0,0 +1,83 @@
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "GLConfig.h"
+
+#include "../base/Logger.h"
+#include "../base/Exception.h"
+
+#include <string>
+
+namespace avg {
+
+using namespace std;
+
+GLConfig::GLConfig()
+{
+}
+
+GLConfig::GLConfig(bool bGLES, bool bUsePOTTextures, bool bUsePixelBuffers,
+ int multiSampleSamples, ShaderUsage shaderUsage, bool bUseDebugContext)
+ : m_bGLES(bGLES),
+ m_bUsePOTTextures(bUsePOTTextures),
+ m_bUsePixelBuffers(bUsePixelBuffers),
+ m_MultiSampleSamples(multiSampleSamples),
+ m_ShaderUsage(shaderUsage),
+ m_bUseDebugContext(bUseDebugContext)
+{
+}
+
+void GLConfig::log()
+{
+ AVG_TRACE(Logger::category::CONFIG, Logger::severity::INFO,
+ " OpenGL flavor: " << (m_bGLES?"Mobile (ES)":"Desktop"));
+ AVG_TRACE(Logger::category::CONFIG, Logger::severity::INFO,
+ " Pixel buffers: " << (m_bUsePixelBuffers?"true":"false"));
+ AVG_TRACE(Logger::category::CONFIG, Logger::severity::INFO,
+ " Power of 2 textures: " << (m_bUsePOTTextures?"true":"false"));
+ if (m_MultiSampleSamples == 1) {
+ AVG_TRACE(Logger::category::CONFIG, Logger::severity::INFO, " No multisampling");
+ } else {
+ AVG_TRACE(Logger::category::CONFIG, Logger::severity::INFO,
+ " Multisampling with " << m_MultiSampleSamples << " samples");
+ }
+ string sShader = shaderUsageToString(m_ShaderUsage);
+ AVG_TRACE(Logger::category::CONFIG, Logger::severity::INFO,
+ " Shader usage: " << sShader);
+ AVG_TRACE(Logger::category::CONFIG, Logger::severity::INFO,
+ " Debug context: " << (m_bUseDebugContext?"true":"false"));
+}
+
+std::string GLConfig::shaderUsageToString(ShaderUsage su)
+{
+ switch(su) {
+ case FULL:
+ return "full";
+ case MINIMAL:
+ return "minimal";
+ case AUTO:
+ return "auto";
+ default:
+ AVG_ASSERT(false);
+ return "";
+ }
+}
+
+}
diff --git a/src/graphics/GLConfig.h b/src/graphics/GLConfig.h
new file mode 100644
index 0000000..7aaaa64
--- /dev/null
+++ b/src/graphics/GLConfig.h
@@ -0,0 +1,52 @@
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _GLConfig_H_
+#define _GLConfig_H_
+
+#include "../api.h"
+
+#include <string>
+
+namespace avg {
+
+struct AVG_API GLConfig {
+ enum ShaderUsage {FULL, MINIMAL, AUTO};
+
+ GLConfig();
+ GLConfig(bool bGLES, bool bUsePOTTextures, bool bUsePixelBuffers,
+ int multiSampleSamples, ShaderUsage shaderUsage, bool bUseDebugContext);
+
+ void log();
+
+ static std::string shaderUsageToString(ShaderUsage su);
+
+ bool m_bGLES;
+ bool m_bUsePOTTextures;
+ bool m_bUsePixelBuffers;
+ int m_MultiSampleSamples;
+ ShaderUsage m_ShaderUsage;
+ bool m_bUseDebugContext;
+};
+
+}
+
+#endif
+
diff --git a/src/graphics/GLContext.cpp b/src/graphics/GLContext.cpp
new file mode 100644
index 0000000..e5ed1ce
--- /dev/null
+++ b/src/graphics/GLContext.cpp
@@ -0,0 +1,656 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "GLContext.h"
+
+#include "ShaderRegistry.h"
+#include "StandardShader.h"
+
+#ifdef __APPLE__
+ #include "CGLContext.h"
+#elif defined linux
+ #ifdef AVG_ENABLE_EGL
+ #include "EGLContext.h"
+ #else
+ #include "GLXContext.h"
+ #endif
+#elif defined _WIN32
+ #include "WGLContext.h"
+#endif
+
+#include "../base/Backtrace.h"
+#include "../base/Exception.h"
+#include "../base/Logger.h"
+#include "../base/MathHelper.h"
+
+#include <iostream>
+#include <stdio.h>
+
+
+namespace avg {
+
+using namespace std;
+using namespace boost;
+
+thread_specific_ptr<GLContext*> GLContext::s_pCurrentContext;
+GLContext* GLContext::s_pMainContext = 0; // Optimized access to main context.
+bool GLContext::s_bErrorCheckEnabled = false;
+bool GLContext::s_bErrorLogEnabled = true;
+
+
+GLContext* GLContext::create(const GLConfig& glConfig, const IntPoint& windowSize,
+ const SDL_SysWMinfo* pSDLWMInfo)
+{
+ if (glConfig.m_bGLES) {
+ AVG_ASSERT(isGLESSupported());
+ }
+#ifdef __APPLE__
+ return new CGLContext(glConfig, windowSize, pSDLWMInfo);
+#elif defined linux
+ #ifdef AVG_ENABLE_EGL
+ GLConfig tempConfig = glConfig;
+ tempConfig.m_bGLES = true;
+ return new EGLContext(tempConfig, windowSize, pSDLWMInfo);
+ #else
+ return new GLXContext(glConfig, windowSize, pSDLWMInfo);
+ #endif
+#elif defined _WIN32
+ return new WGLContext(glConfig, windowSize, pSDLWMInfo);
+#else
+ AVG_ASSERT(false);
+ return GLContextPtr();
+#endif
+}
+
+GLContext::GLContext(const IntPoint& windowSize, const SDL_SysWMinfo* pSDLWMInfo)
+ : m_MaxTexSize(0),
+ m_bCheckedGPUMemInfoExtension(false),
+ m_bCheckedMemoryMode(false),
+ m_BlendColor(0.f, 0.f, 0.f, 0.f),
+ m_BlendMode(BLEND_ADD),
+ m_MajorGLVersion(-1)
+{
+ if (s_pCurrentContext.get() == 0) {
+ s_pCurrentContext.reset(new (GLContext*));
+ }
+}
+
+GLContext::~GLContext()
+{
+}
+
+void GLContext::init(const GLConfig& glConfig, bool bOwnsContext)
+{
+ m_GLConfig = glConfig;
+ m_bOwnsContext = bOwnsContext;
+ activate();
+ glproc::init();
+ if (m_GLConfig.m_bGLES) {
+ m_MajorGLVersion = 2;
+ m_MinorGLVersion = 0;
+ } else {
+ const char* pVersion = (const char*)glGetString(GL_VERSION);
+ sscanf(pVersion, "%d.%d", &m_MajorGLVersion, &m_MinorGLVersion);
+ }
+
+ if (m_GLConfig.m_bUseDebugContext) {
+ if (isDebugContextSupported()) {
+ glproc::DebugMessageCallback(GLContext::debugLogCallback, 0);
+ } else {
+ m_GLConfig.m_bUseDebugContext = false;
+ }
+ }
+#ifndef AVG_ENABLE_EGL
+ if (m_GLConfig.m_MultiSampleSamples > 1) {
+ glEnable(GL_MULTISAMPLE);
+ checkError("init: glEnable(GL_MULTISAMPLE)");
+ }
+#endif
+ m_pShaderRegistry = ShaderRegistryPtr(new ShaderRegistry());
+ if (useGPUYUVConversion()) {
+ m_pShaderRegistry->setPreprocessorDefine("ENABLE_YUV_CONVERSION", "");
+ }
+ setBlendMode(BLEND_BLEND, false);
+ if (!m_GLConfig.m_bUsePOTTextures) {
+ m_GLConfig.m_bUsePOTTextures =
+ !queryOGLExtension("GL_ARB_texture_non_power_of_two") && !isGLES();
+ }
+ if (m_GLConfig.m_ShaderUsage == GLConfig::AUTO) {
+ if (isGLES()) {
+ m_GLConfig.m_ShaderUsage = GLConfig::MINIMAL;
+ } else {
+ m_GLConfig.m_ShaderUsage = GLConfig::FULL;
+ }
+ }
+#ifdef __APPLE__
+ if (GLContext::isVendor("Intel")) {
+ // Bug #434: Some shaders cause hard lockups on Mac Book Air.
+ m_GLConfig.m_ShaderUsage = GLConfig::MINIMAL;
+ }
+#endif
+ for (int i=0; i<16; ++i) {
+ m_BoundTextures[i] = 0xFFFFFFFF;
+ }
+ if (!m_GLConfig.m_bGLES && !queryOGLExtension("GL_ARB_vertex_buffer_object")) {
+ throw Exception(AVG_ERR_UNSUPPORTED,
+ "Graphics driver lacks vertex buffer support, unable to initialize graphics.");
+ }
+ glEnable(GL_BLEND);
+ checkError("init: glEnable(GL_BLEND)");
+ glDisable(GL_DEPTH_TEST);
+ checkError("init: glDisable(GL_DEPTH_TEST)");
+ glEnable(GL_STENCIL_TEST);
+ checkError("init: glEnable(GL_STENCIL_TEST)");
+}
+
+void GLContext::deleteObjects()
+{
+ m_pStandardShader = StandardShaderPtr();
+ for (unsigned i=0; i<m_FBOIDs.size(); ++i) {
+ glproc::DeleteFramebuffers(1, &(m_FBOIDs[i]));
+ }
+ m_FBOIDs.clear();
+ if (*s_pCurrentContext == this) {
+ *s_pCurrentContext = 0;
+ }
+}
+
+void GLContext::getVersion(int& major, int& minor) const
+{
+ major = m_MajorGLVersion;
+ minor = m_MinorGLVersion;
+}
+
+bool GLContext::ownsContext() const
+{
+ return m_bOwnsContext;
+}
+
+void GLContext::setCurrent()
+{
+ *s_pCurrentContext = this;
+}
+
+ShaderRegistryPtr GLContext::getShaderRegistry() const
+{
+ return m_pShaderRegistry;
+}
+
+StandardShaderPtr GLContext::getStandardShader()
+{
+ if (m_pStandardShader == StandardShaderPtr()) {
+ m_pStandardShader = StandardShaderPtr(new StandardShader());
+ }
+ return m_pStandardShader;
+}
+
+bool GLContext::useGPUYUVConversion() const
+{
+ return (m_MajorGLVersion > 1) || isGLES();
+}
+
+GLConfig::ShaderUsage GLContext::getShaderUsage() const
+{
+ return m_GLConfig.m_ShaderUsage;
+}
+
+GLBufferCache& GLContext::getVertexBufferCache()
+{
+ return m_VertexBufferCache;
+}
+
+GLBufferCache& GLContext::getIndexBufferCache()
+{
+ return m_IndexBufferCache;
+}
+
+GLBufferCache& GLContext::getPBOCache()
+{
+ return m_PBOCache;
+}
+
+unsigned GLContext::genFBO()
+{
+ unsigned fboID;
+ if (m_FBOIDs.empty()) {
+ glproc::GenFramebuffers(1, &fboID);
+ } else {
+ fboID = m_FBOIDs.back();
+ m_FBOIDs.pop_back();
+ }
+ return fboID;
+}
+
+void GLContext::returnFBOToCache(unsigned fboID)
+{
+ m_FBOIDs.push_back(fboID);
+}
+
+void GLContext::setBlendColor(const glm::vec4& color)
+{
+ if (m_BlendColor != color) {
+ glproc::BlendColor(color[0], color[1], color[2], color[3]);
+ m_BlendColor = color;
+ }
+}
+
+void GLContext::setBlendMode(BlendMode mode, bool bPremultipliedAlpha)
+{
+ AVG_ASSERT(isBlendModeSupported(mode));
+ GLenum srcFunc;
+ if (bPremultipliedAlpha) {
+ srcFunc = GL_CONSTANT_ALPHA;
+ } else {
+ srcFunc = GL_SRC_ALPHA;
+ }
+ if (mode != m_BlendMode || m_bPremultipliedAlpha != bPremultipliedAlpha) {
+ switch (mode) {
+ case BLEND_BLEND:
+ glproc::BlendEquation(GL_FUNC_ADD);
+ glproc::BlendFuncSeparate(srcFunc, GL_ONE_MINUS_SRC_ALPHA,
+ GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+ checkError("setBlendMode: blend");
+ break;
+ case BLEND_ADD:
+ glproc::BlendEquation(GL_FUNC_ADD);
+ glproc::BlendFuncSeparate(srcFunc, GL_ONE, GL_ONE, GL_ONE);
+ checkError("setBlendMode: add");
+ break;
+ case BLEND_MIN:
+ glproc::BlendEquation(GL_MIN_EXT);
+ glproc::BlendFuncSeparate(srcFunc, GL_ONE_MINUS_SRC_ALPHA,
+ GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+ checkError("setBlendMode: min");
+ break;
+ case BLEND_MAX:
+ glproc::BlendEquation(GL_MAX_EXT);
+ glproc::BlendFuncSeparate(srcFunc, GL_ONE_MINUS_SRC_ALPHA,
+ GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+ checkError("setBlendMode: max");
+ break;
+ case BLEND_COPY:
+ glproc::BlendEquation(GL_FUNC_ADD);
+ glBlendFunc(GL_ONE, GL_ZERO);
+ checkError("setBlendMode: copy");
+ break;
+ default:
+ AVG_ASSERT(false);
+ }
+
+ m_BlendMode = mode;
+ m_bPremultipliedAlpha = bPremultipliedAlpha;
+ }
+}
+
+bool GLContext::isBlendModeSupported(BlendMode mode) const
+{
+ if (isGLES() && (mode == BLEND_MIN || mode == BLEND_MAX)) {
+ return queryOGLExtension("GL_EXT_blend_minmax");
+ } else {
+ return true;
+ }
+}
+
+void GLContext::bindTexture(unsigned unit, unsigned texID)
+{
+ if (m_BoundTextures[unit-GL_TEXTURE0] != texID) {
+ glproc::ActiveTexture(unit);
+ checkError("GLContext::bindTexture ActiveTexture()");
+ glBindTexture(GL_TEXTURE_2D, texID);
+ checkError("GLContext::bindTexture BindTexture()");
+ m_BoundTextures[unit-GL_TEXTURE0] = texID;
+ }
+}
+
+const GLConfig& GLContext::getConfig()
+{
+ return m_GLConfig;
+}
+
+void GLContext::logConfig()
+{
+ AVG_TRACE(Logger::category::CONFIG, Logger::severity::INFO, "OpenGL configuration: ");
+ AVG_TRACE(Logger::category::CONFIG, Logger::severity::INFO,
+ " OpenGL version: " << glGetString(GL_VERSION));
+ AVG_TRACE(Logger::category::CONFIG, Logger::severity::INFO,
+ " OpenGL vendor: " << glGetString(GL_VENDOR));
+ AVG_TRACE(Logger::category::CONFIG, Logger::severity::INFO,
+ " OpenGL renderer: " << glGetString(GL_RENDERER));
+ m_GLConfig.log();
+ switch (getMemoryMode()) {
+ case MM_PBO:
+ AVG_TRACE(Logger::category::CONFIG, Logger::severity::INFO,
+ " Using pixel buffer objects");
+ break;
+ case MM_OGL:
+ AVG_TRACE(Logger::category::CONFIG, Logger::severity::INFO,
+ " Not using GL memory extensions");
+ break;
+ }
+ AVG_TRACE(Logger::category::CONFIG, Logger::severity::INFO,
+ " Max. texture size: " << getMaxTexSize());
+ string s;
+ if (useGPUYUVConversion()) {
+ s = "yes";
+ } else {
+ s = "no";
+ }
+ AVG_TRACE(Logger::category::CONFIG, Logger::severity::INFO,
+ string(" GPU-based YUV-RGB conversion: ")+s+".");
+ try {
+ AVG_TRACE(Logger::category::CONFIG, Logger::severity::INFO,
+ " Dedicated video memory: " << getVideoMemInstalled()/(1024*1024)
+ << " MB");
+ AVG_TRACE(Logger::category::CONFIG, Logger::severity::INFO,
+ " Video memory used at start: " << getVideoMemUsed()/(1024*1024)
+ << " MB");
+ } catch (Exception) {
+ AVG_TRACE(Logger::category::CONFIG, Logger::severity::ERROR,
+ " Dedicated video memory: Unknown");
+ AVG_TRACE(Logger::category::CONFIG, Logger::severity::ERROR,
+ " Video memory used at start: Unknown");
+ }
+}
+
+size_t GLContext::getVideoMemInstalled()
+{
+ checkGPUMemInfoSupport();
+ int kbMemInstalled;
+ glGetIntegerv(GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX, &kbMemInstalled);
+ return (size_t)kbMemInstalled*1024;
+}
+
+size_t GLContext::getVideoMemUsed()
+{
+ checkGPUMemInfoSupport();
+ int kbMemAvailable;
+ glGetIntegerv(GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &kbMemAvailable);
+ return getVideoMemInstalled()-(size_t)kbMemAvailable*1024;
+}
+
+bool GLContext::usePOTTextures()
+{
+ return m_GLConfig.m_bUsePOTTextures;
+}
+
+bool GLContext::arePBOsSupported()
+{
+ if (isGLES()) {
+ return false;
+ } else {
+ return (queryOGLExtension("GL_ARB_pixel_buffer_object") ||
+ queryOGLExtension("GL_EXT_pixel_buffer_object"));
+ }
+}
+
+OGLMemoryMode GLContext::getMemoryMode()
+{
+ if (!m_bCheckedMemoryMode) {
+ if (arePBOsSupported() && m_GLConfig.m_bUsePixelBuffers) {
+ m_MemoryMode = MM_PBO;
+ } else {
+ m_MemoryMode = MM_OGL;
+ }
+ m_bCheckedMemoryMode = true;
+ }
+ return m_MemoryMode;
+}
+
+bool GLContext::isGLES() const
+{
+ return m_GLConfig.m_bGLES;
+}
+
+bool GLContext::isVendor(const string& sWantedVendor) const
+{
+ string sVendor((const char *)glGetString(GL_VENDOR));
+ return (sVendor.find(sWantedVendor) != string::npos);
+}
+
+bool GLContext::useDepthBuffer() const
+{
+ return !isGLES();
+}
+
+int GLContext::getMaxTexSize()
+{
+ if (m_MaxTexSize == 0) {
+ glGetIntegerv(GL_MAX_TEXTURE_SIZE, &m_MaxTexSize);
+ }
+ return m_MaxTexSize;
+}
+
+
+void GLContext::swapBuffers()
+{
+ AVG_ASSERT(false);
+}
+
+void GLContext::enableErrorChecks(bool bEnable)
+{
+ s_bErrorCheckEnabled = bEnable;
+}
+
+void GLContext::checkError(const char* pszWhere)
+{
+ if (s_bErrorCheckEnabled) {
+ mandatoryCheckError(pszWhere);
+ }
+}
+
+void GLContext::mandatoryCheckError(const char* pszWhere)
+{
+ GLenum err = glGetError();
+ if (err != GL_NO_ERROR) {
+ stringstream s;
+#ifndef AVG_ENABLE_EGL
+ s << "OpenGL error in " << pszWhere <<": " << gluErrorString(err)
+ << " (#" << err << ") ";
+#else
+ s << "OpenGL error in " << pszWhere <<": (#" << err << ") ";
+#endif
+ AVG_LOG_ERROR(s.str());
+ if (err != GL_INVALID_OPERATION) {
+ checkError(" --");
+ }
+ AVG_ASSERT(false);
+ }
+}
+
+void GLContext::ensureFullShaders(const string& sContext) const
+{
+ if (getShaderUsage() != GLConfig::FULL) {
+ throw Exception(AVG_ERR_UNSUPPORTED,
+ sContext + " not supported if ShaderUsage==MINIMAL");
+ }
+
+}
+
+GLContext::BlendMode GLContext::stringToBlendMode(const string& s)
+{
+ if (s == "blend") {
+ return GLContext::BLEND_BLEND;
+ } else if (s == "add") {
+ return GLContext::BLEND_ADD;
+ } else if (s == "min") {
+ return GLContext::BLEND_MIN;
+ } else if (s == "max") {
+ return GLContext::BLEND_MAX;
+ } else {
+ throw(Exception(AVG_ERR_UNSUPPORTED, "Blend mode "+s+" not supported."));
+ }
+}
+
+GLContext* GLContext::getCurrent()
+{
+ return *s_pCurrentContext;
+}
+
+GLContext* GLContext::getMain()
+{
+ return s_pMainContext;
+}
+
+void GLContext::setMain(GLContext * pMainContext)
+{
+ s_pMainContext = pMainContext;
+}
+
+int GLContext::nextMultiSampleValue(int curSamples)
+{
+ switch (curSamples) {
+ case 1:
+ return 0;
+ case 2:
+ return 1;
+ case 4:
+ return 2;
+ case 8:
+ return 4;
+ default:
+ return 8;
+ }
+}
+
+bool GLContext::isGLESSupported()
+{
+#if defined linux
+ #ifdef AVG_ENABLE_EGL
+ return true;
+ #else
+ return GLXContext::haveARBCreateContext();
+ #endif
+#else
+ return false;
+#endif
+}
+
+void GLContext::enableErrorLog(bool bEnable)
+{
+ s_bErrorLogEnabled = bEnable;
+}
+
+void GLContext::checkGPUMemInfoSupport()
+{
+ if (!m_bCheckedGPUMemInfoExtension) {
+ m_bGPUMemInfoSupported = queryOGLExtension("GL_NVX_gpu_memory_info");
+ m_bCheckedGPUMemInfoExtension = true;
+ }
+ if (!m_bGPUMemInfoSupported) {
+ throw Exception(AVG_ERR_UNSUPPORTED,
+ "Video memory query not supported on this system.");
+ }
+}
+
+bool GLContext::isDebugContextSupported() const
+{
+ if (queryOGLExtension("GL_ARB_debug_output") || queryOGLExtension("GL_KHR_debug")) {
+ return true;
+ }
+ if (isGLES() && isVendor("NVIDIA")) {
+ // There is no extension for debug output in gles 2.0, but Linux NVidia
+ // supports the functionality anyway. So we activate it :-).
+ return true;
+ }
+ return false;
+}
+
+void GLContext::debugLogCallback(GLenum source, GLenum type, GLuint id,
+ GLenum severity, GLsizei length, const GLchar* message, void* userParam)
+{
+/*
+ string sSource;
+ switch (source) {
+ case GL_DEBUG_SOURCE_API_ARB:
+ sSource = "API";
+ break;
+ case GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB:
+ sSource = "Window System";
+ break;
+ case GL_DEBUG_SOURCE_SHADER_COMPILER_ARB:
+ sSource = "Shader Compiler";
+ break;
+ case GL_DEBUG_SOURCE_THIRD_PARTY_ARB:
+ sSource = "Third Party";
+ break;
+ case GL_DEBUG_SOURCE_APPLICATION_ARB:
+ sSource = "Application";
+ break;
+ case GL_DEBUG_SOURCE_OTHER_ARB:
+ sSource = "Other";
+ break;
+ default:
+ AVG_ASSERT(false);
+ }
+
+ string sSeverity;
+ switch (severity) {
+ case GL_DEBUG_SEVERITY_HIGH_ARB:
+ sSeverity = "High";
+ break;
+ case GL_DEBUG_SEVERITY_MEDIUM_ARB:
+ sSeverity = "Medium";
+ break;
+ case GL_DEBUG_SEVERITY_LOW_ARB:
+ sSeverity = "Low";
+ break;
+ default:
+ AVG_ASSERT(false);
+ }
+
+ string sType;
+ switch (type) {
+ case GL_DEBUG_TYPE_ERROR_ARB:
+ sType = "Error";
+ break;
+ case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB:
+ sType = "Deprecated Behaviour";
+ break;
+ case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB:
+ sType = "Undefined Behaviour";
+ break;
+ case GL_DEBUG_TYPE_PORTABILITY_ARB:
+ sType = "Portability Issue";
+ break;
+ case GL_DEBUG_TYPE_PERFORMANCE_ARB:
+ sType = "Performance Issue";
+ break;
+ case GL_DEBUG_TYPE_OTHER_ARB:
+ sType = "Other";
+ break;
+ default:
+ AVG_ASSERT(false);
+ }
+*/
+
+ // XXX Temporary to clean up NVidia message spam.
+#ifndef AVG_ENABLE_EGL
+ if (type != GL_DEBUG_TYPE_PERFORMANCE_ARB && s_bErrorLogEnabled) {
+#endif
+ AVG_LOG_WARNING(message);
+ // dumpBacktrace();
+ // AVG_ASSERT(false);
+#ifndef AVG_ENABLE_EGL
+ }
+#endif
+}
+
+}
diff --git a/src/graphics/GLContext.h b/src/graphics/GLContext.h
new file mode 100644
index 0000000..5043f5f
--- /dev/null
+++ b/src/graphics/GLContext.h
@@ -0,0 +1,156 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+#ifndef _GLContext_H_
+#define _GLContext_H_
+
+#include "../api.h"
+
+#include "OGLHelper.h"
+#include "GLBufferCache.h"
+#include "GLConfig.h"
+
+#include "../base/GLMHelper.h"
+
+#include <boost/shared_ptr.hpp>
+#include <boost/thread/tss.hpp>
+
+struct SDL_SysWMinfo;
+
+namespace avg {
+
+class GLContext;
+typedef boost::shared_ptr<GLContext> GLContextPtr;
+class ShaderRegistry;
+typedef boost::shared_ptr<ShaderRegistry> ShaderRegistryPtr;
+class StandardShader;
+typedef boost::shared_ptr<StandardShader> StandardShaderPtr;
+
+class AVG_API GLContext
+{
+public:
+ static GLContext* create(const GLConfig& glConfig,
+ const IntPoint& windowSize=IntPoint(0,0), const SDL_SysWMinfo* pSDLWMInfo=0);
+
+ GLContext(const IntPoint& windowSize, const SDL_SysWMinfo* pSDLWMInfo);
+ virtual ~GLContext();
+
+ virtual void activate()=0;
+ ShaderRegistryPtr getShaderRegistry() const;
+ StandardShaderPtr getStandardShader();
+ bool useGPUYUVConversion() const;
+ GLConfig::ShaderUsage getShaderUsage() const;
+
+ // GL Object caching.
+ GLBufferCache& getVertexBufferCache();
+ GLBufferCache& getIndexBufferCache();
+ GLBufferCache& getPBOCache();
+ unsigned genFBO();
+ void returnFBOToCache(unsigned fboID);
+
+ // GL state cache.
+ void setBlendColor(const glm::vec4& color);
+ enum BlendMode {BLEND_BLEND, BLEND_ADD, BLEND_MIN, BLEND_MAX, BLEND_COPY};
+ void setBlendMode(BlendMode mode, bool bPremultipliedAlpha = false);
+ bool isBlendModeSupported(BlendMode mode) const;
+ void bindTexture(unsigned unit, unsigned texID);
+
+ const GLConfig& getConfig();
+ void logConfig();
+ size_t getVideoMemInstalled();
+ size_t getVideoMemUsed();
+ int getMaxTexSize();
+ bool usePOTTextures();
+ bool arePBOsSupported();
+ OGLMemoryMode getMemoryMode();
+ bool isGLES() const;
+ bool isVendor(const std::string& sWantedVendor) const;
+ virtual bool useDepthBuffer() const;
+
+ virtual bool initVBlank(int rate)=0;
+ virtual void swapBuffers();
+
+ static void enableErrorChecks(bool bEnable);
+ static void checkError(const char* pszWhere);
+ static void mandatoryCheckError(const char* pszWhere);
+ void ensureFullShaders(const std::string& sContext) const;
+
+ static BlendMode stringToBlendMode(const std::string& s);
+
+ static GLContext* getCurrent();
+ static GLContext* getMain();
+ static void setMain(GLContext * pMainContext);
+
+ static int nextMultiSampleValue(int curSamples);
+ static bool isGLESSupported();
+ static void enableErrorLog(bool bEnable);
+
+protected:
+ void init(const GLConfig& glConfig, bool bOwnsContext);
+ void deleteObjects();
+
+ void getVersion(int& major, int& minor) const;
+ bool ownsContext() const;
+
+ void setCurrent();
+
+private:
+ void checkGPUMemInfoSupport();
+ bool isDebugContextSupported() const;
+ static void APIENTRY debugLogCallback(GLenum source, GLenum type, GLuint id,
+ GLenum severity, GLsizei length, const GLchar* message, void* userParam);
+
+ bool m_bOwnsContext;
+
+ ShaderRegistryPtr m_pShaderRegistry;
+ StandardShaderPtr m_pStandardShader;
+
+ GLBufferCache m_VertexBufferCache;
+ GLBufferCache m_IndexBufferCache;
+ GLBufferCache m_PBOCache;
+ std::vector<unsigned int> m_FBOIDs;
+
+ int m_MaxTexSize;
+ GLConfig m_GLConfig;
+ bool m_bCheckedGPUMemInfoExtension;
+ bool m_bGPUMemInfoSupported;
+ bool m_bCheckedMemoryMode;
+ OGLMemoryMode m_MemoryMode;
+
+ // OpenGL state
+ glm::vec4 m_BlendColor;
+ BlendMode m_BlendMode;
+ bool m_bPremultipliedAlpha;
+ unsigned m_BoundTextures[16];
+
+ int m_MajorGLVersion;
+ int m_MinorGLVersion;
+
+ static bool s_bErrorCheckEnabled;
+ static bool s_bErrorLogEnabled;
+
+ static boost::thread_specific_ptr<GLContext*> s_pCurrentContext;
+ static GLContext* s_pMainContext;
+};
+
+}
+#endif
+
+
diff --git a/src/graphics/GLContextAttribs.cpp b/src/graphics/GLContextAttribs.cpp
new file mode 100644
index 0000000..402f574
--- /dev/null
+++ b/src/graphics/GLContextAttribs.cpp
@@ -0,0 +1,67 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "GLContextAttribs.h"
+#include "OGLHelper.h"
+
+#include "../base/Exception.h"
+
+namespace avg {
+
+GLContextAttribs::GLContextAttribs()
+{
+ m_pAttributes = new int[50];
+ m_NumAttributes = 0;
+#ifdef AVG_ENABLE_EGL
+ m_pAttributes[0] = EGL_NONE;
+#else
+ m_pAttributes[0] = 0;
+#endif
+}
+
+GLContextAttribs::~GLContextAttribs()
+{
+ delete[] m_pAttributes;
+}
+
+
+void GLContextAttribs::append(int newAttr, int newAttrVal)
+{
+ AVG_ASSERT(m_NumAttributes < 48);
+
+ m_pAttributes[m_NumAttributes++] = newAttr;
+ if (newAttrVal != -1) {
+ m_pAttributes[m_NumAttributes++] = newAttrVal;
+ }
+#ifdef AVG_ENABLE_EGL
+ m_pAttributes[m_NumAttributes] = EGL_NONE;
+#else
+ m_pAttributes[m_NumAttributes] = 0;
+#endif
+}
+
+const int* GLContextAttribs::get() const
+{
+ return m_pAttributes;
+}
+
+}
+
diff --git a/src/graphics/GLContextAttribs.h b/src/graphics/GLContextAttribs.h
new file mode 100644
index 0000000..5580f91
--- /dev/null
+++ b/src/graphics/GLContextAttribs.h
@@ -0,0 +1,44 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+#ifndef _GLContextAttribs_H_
+#define _GLContextAttribs_H_
+
+#include "../api.h"
+
+namespace avg {
+
+class AVG_API GLContextAttribs
+{
+public:
+ GLContextAttribs();
+ virtual ~GLContextAttribs();
+
+ void append(int newAttr, int newAttrVal=-1);
+
+ const int* get() const;
+
+private:
+ int * m_pAttributes;
+ int m_NumAttributes;
+};
+
+}
+#endif
diff --git a/src/graphics/GLShaderParam.cpp b/src/graphics/GLShaderParam.cpp
new file mode 100644
index 0000000..7a1b739
--- /dev/null
+++ b/src/graphics/GLShaderParam.cpp
@@ -0,0 +1,87 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "GLShaderParam.h"
+#include "OGLShader.h"
+#include <iostream>
+
+using namespace std;
+
+namespace avg {
+
+GLShaderParam::GLShaderParam(OGLShader* pShader, const std::string& sName)
+ : m_sName(sName)
+{
+ m_Location = glproc::GetUniformLocation(pShader->getProgram(), sName.c_str());
+ string sErr = std::string("Shader param '") + sName + "' not found in shader '" +
+ pShader->getName() + "'.";
+ AVG_ASSERT_MSG(m_Location != -1, sErr.c_str());
+ GLContext::checkError(sErr.c_str());
+};
+
+int GLShaderParam::getLocation() const
+{
+ return m_Location;
+}
+
+const string& GLShaderParam::getName() const
+{
+ return m_sName;
+}
+
+template<>
+void GLShaderParamTemplate<int>::uniformSet(unsigned location, const int& val)
+{
+ glproc::Uniform1i(location, val);
+}
+
+template<>
+void GLShaderParamTemplate<float>::uniformSet(unsigned location, const float& val)
+{
+ glproc::Uniform1f(location, val);
+}
+
+template<>
+void GLShaderParamTemplate<glm::vec2>::uniformSet(unsigned location, const glm::vec2& val)
+{
+ glproc::Uniform2f(location, val.x, val.y);
+}
+
+template<>
+void GLShaderParamTemplate<Pixel32>::uniformSet(unsigned location, const Pixel32& val)
+{
+ glproc::Uniform4f(location, val.getR()/255.f, val.getG()/255.f, val.getB()/255.f,
+ val.getA()/255.f);
+}
+
+template<>
+void GLShaderParamTemplate<glm::vec4>::uniformSet(unsigned location, const glm::vec4& val)
+{
+ glproc::Uniform4f(location, val[0], val[1], val[2], val[3]);
+}
+
+template<>
+void GLShaderParamTemplate<glm::mat4>::uniformSet(unsigned location, const glm::mat4& val)
+{
+ glproc::UniformMatrix4fv(location, 1, GL_FALSE, glm::value_ptr(val));
+}
+
+}
diff --git a/src/graphics/GLShaderParam.h b/src/graphics/GLShaderParam.h
new file mode 100644
index 0000000..40cec61
--- /dev/null
+++ b/src/graphics/GLShaderParam.h
@@ -0,0 +1,128 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _GLShaderParam_H_
+#define _GLShaderParam_H_
+
+#include "../api.h"
+#include "OGLHelper.h"
+#include "Pixel32.h"
+#include "GLContext.h"
+
+#include "../base/GLMHelper.h"
+#include "../base/Exception.h"
+
+#include <boost/shared_ptr.hpp>
+
+#include <string>
+
+namespace avg {
+
+class OGLShader;
+typedef boost::shared_ptr<OGLShader> OGLShaderPtr;
+
+class AVG_API GLShaderParam
+{
+public:
+ GLShaderParam(OGLShader* pShader, const std::string& sName);
+ virtual ~GLShaderParam() {};
+
+ const std::string& getName() const;
+
+protected:
+ int getLocation() const;
+
+private:
+ std::string m_sName;
+ int m_Location;
+};
+
+
+template<class VAL_TYPE>
+class AVG_TEMPLATE_API GLShaderParamTemplate: public GLShaderParam
+{
+public:
+ GLShaderParamTemplate(OGLShader* pShader, const std::string& sName)
+ : GLShaderParam(pShader, sName),
+ m_bValSet(false)
+ {};
+
+ void set(const VAL_TYPE& val)
+ {
+ if (!m_bValSet || m_Val != val) {
+ uniformSet(getLocation(), val);
+ GLContext::checkError("OGLShaderParam::set");
+ m_Val = val;
+ m_bValSet = true;
+ }
+ };
+
+private:
+ void uniformSet(unsigned location, const VAL_TYPE& val)
+ {
+ AVG_ASSERT_MSG(false,
+ getName()+"GLShaderParam::uniformSet() called for unsupported type.");
+ };
+
+ bool m_bValSet;
+ VAL_TYPE m_Val;
+};
+
+template<>
+void GLShaderParamTemplate<int>::uniformSet(unsigned location, const int& val);
+template<>
+void GLShaderParamTemplate<float>::uniformSet(unsigned location, const float& val);
+template<>
+void GLShaderParamTemplate<glm::vec2>::uniformSet(unsigned location,
+ const glm::vec2& val);
+template<>
+void GLShaderParamTemplate<Pixel32>::uniformSet(unsigned location, const Pixel32& val);
+template<>
+void GLShaderParamTemplate<glm::vec4>::uniformSet(unsigned location,
+ const glm::vec4& val);
+template<>
+void GLShaderParamTemplate<glm::mat4>::uniformSet(unsigned location,
+ const glm::mat4& val);
+
+typedef boost::shared_ptr<GLShaderParam> GLShaderParamPtr;
+
+typedef GLShaderParamTemplate<int> IntGLShaderParam;
+typedef boost::shared_ptr<IntGLShaderParam> IntGLShaderParamPtr;
+
+typedef GLShaderParamTemplate<float> FloatGLShaderParam;
+typedef boost::shared_ptr<FloatGLShaderParam> FloatGLShaderParamPtr;
+
+typedef GLShaderParamTemplate<glm::vec2> Vec2fGLShaderParam;
+typedef boost::shared_ptr<Vec2fGLShaderParam> Vec2fGLShaderParamPtr;
+
+typedef GLShaderParamTemplate<Pixel32> ColorGLShaderParam;
+typedef boost::shared_ptr<ColorGLShaderParam> ColorGLShaderParamPtr;
+
+typedef GLShaderParamTemplate<glm::vec4> Vec4fGLShaderParam;
+typedef boost::shared_ptr<Vec4fGLShaderParam> Vec4fGLShaderParamPtr;
+
+typedef GLShaderParamTemplate<glm::mat4> Mat4fGLShaderParam;
+typedef boost::shared_ptr<Mat4fGLShaderParam> Mat4fGLShaderParamPtr;
+
+}
+
+#endif
+
diff --git a/src/graphics/GLTexture.cpp b/src/graphics/GLTexture.cpp
new file mode 100644
index 0000000..e19c0d4
--- /dev/null
+++ b/src/graphics/GLTexture.cpp
@@ -0,0 +1,370 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "GLTexture.h"
+
+#include "../base/Exception.h"
+#include "../base/StringHelper.h"
+#include "../base/MathHelper.h"
+#include "../base/ObjectCounter.h"
+
+#include "GLContext.h"
+#include "TextureMover.h"
+#ifndef AVG_ENABLE_EGL
+ #include "PBO.h"
+#endif
+#include "FBO.h"
+
+#include <string.h>
+#include <iostream>
+
+namespace avg {
+
+using namespace std;
+
+// We assign our own texture ids and never reuse them instead of using glGenTextures.
+// That works very well, except that other components (e.g. Ogre3d) with shared gl
+// contexts don't know anything about our ids and thus use the same ones.
+// Somewhat hackish solution: Assign ids starting with a very high id, so the id ranges
+// don't overlap.
+unsigned GLTexture::s_LastTexID = 10000000;
+
+GLTexture::GLTexture(const IntPoint& size, PixelFormat pf, bool bMipmap,
+ int potBorderColor, unsigned wrapSMode, unsigned wrapTMode, bool bForcePOT)
+ : m_Size(size),
+ m_pf(pf),
+ m_bMipmap(bMipmap),
+ m_bDeleteTex(true),
+ m_bIsDirty(true)
+{
+ m_pGLContext = GLContext::getCurrent();
+ ObjectCounter::get()->incRef(&typeid(*this));
+ m_bUsePOT = m_pGLContext->usePOTTextures() || bForcePOT;
+ if (m_pGLContext->isGLES() && bMipmap) {
+ m_bUsePOT = true;
+ }
+ if (m_bUsePOT) {
+ m_GLSize.x = nextpow2(m_Size.x);
+ m_GLSize.y = nextpow2(m_Size.y);
+ } else {
+ m_GLSize = m_Size;
+ }
+
+ int maxTexSize = m_pGLContext->getMaxTexSize();
+ if (m_Size.x > maxTexSize || m_Size.y > maxTexSize) {
+ throw Exception(AVG_ERR_VIDEO_GENERAL, "Texture too large (" + toString(m_Size)
+ + "). Maximum supported by graphics card is "
+ + toString(maxTexSize));
+ }
+ if (getGLType(m_pf) == GL_FLOAT && !isFloatFormatSupported()) {
+ throw Exception(AVG_ERR_UNSUPPORTED,
+ "Float textures not supported by OpenGL configuration.");
+ }
+
+ s_LastTexID++;
+ m_TexID = s_LastTexID;
+ m_pGLContext->bindTexture(GL_TEXTURE0, m_TexID);
+
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapSMode);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapTMode);
+ glTexImage2D(GL_TEXTURE_2D, 0, getGLInternalFormat(), m_GLSize.x, m_GLSize.y, 0,
+ getGLFormat(m_pf), getGLType(m_pf), 0);
+ GLContext::checkError("GLTexture: glTexImage2D()");
+ if (bMipmap) {
+ glproc::GenerateMipmap(GL_TEXTURE_2D);
+ GLContext::checkError("GLTexture::GLTexture generateMipmap()");
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+ } else {
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ }
+
+ if (m_bUsePOT) {
+ // Make sure the texture is transparent and black before loading stuff
+ // into it to avoid garbage at the borders.
+ // In the case of UV textures, we set the border color to 128...
+ int TexMemNeeded = m_GLSize.x*m_GLSize.y*getBytesPerPixel(m_pf);
+ char * pPixels = new char[TexMemNeeded];
+ memset(pPixels, potBorderColor, TexMemNeeded);
+ glTexImage2D(GL_TEXTURE_2D, 0, getGLInternalFormat(), m_GLSize.x,
+ m_GLSize.y, 0, getGLFormat(m_pf), getGLType(m_pf),
+ pPixels);
+ GLContext::checkError("PBOTexture::createTexture: glTexImage2D()");
+ delete[] pPixels;
+ }
+// dump(wrapSMode, wrapTMode);
+}
+
+GLTexture::GLTexture(unsigned glTexID, const IntPoint& size, PixelFormat pf, bool bMipmap,
+ bool bDeleteTex)
+ : m_Size(size),
+ m_GLSize(size),
+ m_pf(pf),
+ m_bMipmap(bMipmap),
+ m_bDeleteTex(bDeleteTex),
+ m_bUsePOT(false),
+ m_TexID(glTexID),
+ m_bIsDirty(true)
+{
+ m_pGLContext = GLContext::getCurrent();
+ ObjectCounter::get()->incRef(&typeid(*this));
+}
+
+GLTexture::~GLTexture()
+{
+ if (m_bDeleteTex) {
+ glDeleteTextures(1, &m_TexID);
+ GLContext::checkError("GLTexture: DeleteTextures()");
+ }
+ ObjectCounter::get()->decRef(&typeid(*this));
+}
+
+void GLTexture::activate(int textureUnit)
+{
+ m_pGLContext->bindTexture(textureUnit, m_TexID);
+}
+
+void GLTexture::generateMipmaps()
+{
+ if (m_bMipmap) {
+ activate();
+ glproc::GenerateMipmap(GL_TEXTURE_2D);
+ GLContext::checkError("GLTexture::generateMipmap()");
+ }
+}
+
+void GLTexture::setWrapMode(unsigned wrapSMode, unsigned wrapTMode)
+{
+ activate();
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapSMode);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapTMode);
+}
+
+void GLTexture::enableStreaming()
+{
+ m_pMover = TextureMover::create(m_Size, m_pf, GL_STREAM_DRAW);
+}
+
+BitmapPtr GLTexture::lockStreamingBmp()
+{
+ AVG_ASSERT(m_pMover);
+ return m_pMover->lock();
+}
+
+void GLTexture::unlockStreamingBmp(bool bUpdated)
+{
+ AVG_ASSERT(m_pMover);
+ m_pMover->unlock();
+ if (bUpdated) {
+ m_pMover->moveToTexture(*this);
+ m_bIsDirty = true;
+ }
+}
+
+void GLTexture::moveBmpToTexture(BitmapPtr pBmp)
+{
+ TextureMoverPtr pMover = TextureMover::create(m_Size, m_pf, GL_DYNAMIC_DRAW);
+ pMover->moveBmpToTexture(pBmp, *this);
+ m_bIsDirty = true;
+}
+
+BitmapPtr GLTexture::moveTextureToBmp(int mipmapLevel)
+{
+ TextureMoverPtr pMover = TextureMover::create(m_GLSize, m_pf, GL_DYNAMIC_READ);
+ return pMover->moveTextureToBmp(*this, mipmapLevel);
+}
+
+const IntPoint& GLTexture::getSize() const
+{
+ return m_Size;
+}
+
+const IntPoint& GLTexture::getGLSize() const
+{
+ return m_GLSize;
+}
+
+PixelFormat GLTexture::getPF() const
+{
+ return m_pf;
+}
+
+unsigned GLTexture::getID() const
+{
+ return m_TexID;
+}
+
+IntPoint GLTexture::getMipmapSize(int level) const
+{
+ IntPoint size = m_Size;
+ for (int i=0; i<level; ++i) {
+ size.x = max(1, size.x >> 1);
+ size.y = max(1, size.y >> 1);
+ }
+ return size;
+}
+
+bool GLTexture::isFloatFormatSupported()
+{
+ return queryOGLExtension("GL_ARB_texture_float");
+}
+
+int GLTexture::getGLFormat(PixelFormat pf)
+{
+ switch (pf) {
+ case I8:
+ case I32F:
+ return GL_LUMINANCE;
+ case A8:
+ return GL_ALPHA;
+ case R8G8B8A8:
+ case R8G8B8X8:
+ return GL_RGBA;
+ case B8G8R8A8:
+ case B8G8R8X8:
+ AVG_ASSERT(!GLContext::getMain()->isGLES());
+ return GL_BGRA;
+#ifndef AVG_ENABLE_EGL
+ case R32G32B32A32F:
+ return GL_BGRA;
+#endif
+ case R8G8B8:
+ case B5G6R5:
+ return GL_RGB;
+ default:
+ AVG_ASSERT(false);
+ return 0;
+ }
+}
+
+int GLTexture::getGLType(PixelFormat pf)
+{
+ switch (pf) {
+ case I8:
+ case A8:
+ return GL_UNSIGNED_BYTE;
+ case R8G8B8A8:
+ case R8G8B8X8:
+ case B8G8R8A8:
+ case B8G8R8X8:
+#ifdef __APPLE__
+ return GL_UNSIGNED_INT_8_8_8_8_REV;
+#else
+ return GL_UNSIGNED_BYTE;
+#endif
+ case R32G32B32A32F:
+ case I32F:
+ return GL_FLOAT;
+ case R8G8B8:
+ return GL_UNSIGNED_BYTE;
+ case B5G6R5:
+ return GL_UNSIGNED_SHORT_5_6_5;
+ default:
+ AVG_ASSERT(false);
+ return 0;
+ }
+}
+
+int GLTexture::getGLInternalFormat() const
+{
+ switch (m_pf) {
+ case I8:
+ return GL_LUMINANCE;
+ case A8:
+ return GL_ALPHA;
+ case R8G8B8A8:
+ case R8G8B8X8:
+ return GL_RGBA;
+ case B8G8R8A8:
+ case B8G8R8X8:
+ AVG_ASSERT(!GLContext::getMain()->isGLES());
+ return GL_RGBA;
+#ifndef AVG_ENABLE_EGL
+ case R32G32B32A32F:
+ return GL_RGBA32F_ARB;
+ case I32F:
+ return GL_LUMINANCE32F_ARB;
+#endif
+ case R8G8B8:
+ case B5G6R5:
+ return GL_RGB;
+ default:
+ AVG_ASSERT(false);
+ return 0;
+ }
+}
+
+void GLTexture::setDirty()
+{
+ m_bIsDirty = true;
+}
+
+bool GLTexture::isDirty() const
+{
+ return m_bIsDirty;
+}
+
+void GLTexture::resetDirty()
+{
+ m_bIsDirty = false;
+}
+
+const string wrapModeToStr(unsigned wrapMode)
+{
+ string sWrapMode;
+ switch (wrapMode) {
+ case GL_CLAMP_TO_EDGE:
+ sWrapMode = "CLAMP_TO_EDGE";
+ break;
+#ifndef AVG_ENABLE_EGL
+ case GL_CLAMP:
+ sWrapMode = "CLAMP";
+ break;
+ case GL_CLAMP_TO_BORDER:
+ sWrapMode = "CLAMP_TO_BORDER";
+ break;
+#endif
+ case GL_REPEAT:
+ sWrapMode = "REPEAT";
+ break;
+ case GL_MIRRORED_REPEAT:
+ sWrapMode = "MIRRORED_REPEAT";
+ break;
+ default:
+ sWrapMode = "unknown";
+ }
+ return sWrapMode;
+}
+
+void GLTexture::dump(unsigned wrapSMode, unsigned wrapTMode) const
+{
+ cerr << "GLTexture" << endl;
+ cerr << "m_Size: " << m_Size << endl;
+ cerr << "m_GLSize: " << m_GLSize << endl;
+ cerr << "m_pf: " << m_pf << endl;
+ cerr << "m_bMipmap: " << m_bMipmap << endl;
+ if (wrapSMode != (unsigned)-1) {
+ cerr << "Wrap modes: " << \
+ wrapModeToStr(wrapSMode) << ", " << wrapModeToStr(wrapTMode) << endl;
+ }
+}
+
+}
diff --git a/src/graphics/GLTexture.h b/src/graphics/GLTexture.h
new file mode 100644
index 0000000..9f6877f
--- /dev/null
+++ b/src/graphics/GLTexture.h
@@ -0,0 +1,98 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _GLTexture_H_
+#define _GLTexture_H_
+
+#include "../api.h"
+#include "Bitmap.h"
+#include "OGLHelper.h"
+
+#include <boost/shared_ptr.hpp>
+
+namespace avg {
+
+class TextureMover;
+typedef boost::shared_ptr<TextureMover> TextureMoverPtr;
+class GLContext;
+
+class AVG_API GLTexture {
+
+public:
+ GLTexture(const IntPoint& size, PixelFormat pf, bool bMipmap=false,
+ int potBorderColor=0, unsigned wrapSMode=GL_CLAMP_TO_EDGE,
+ unsigned wrapTMode=GL_CLAMP_TO_EDGE, bool bForcePOT=false);
+ GLTexture(unsigned glTexID, const IntPoint& size, PixelFormat pf, bool bMipmap=false,
+ bool bDeleteTex=false);
+ virtual ~GLTexture();
+
+ void activate(int textureUnit=GL_TEXTURE0);
+ void generateMipmaps();
+ void setWrapMode(unsigned wrapSMode, unsigned wrapTMode);
+
+ void enableStreaming();
+ BitmapPtr lockStreamingBmp();
+ void unlockStreamingBmp(bool bUpdated);
+ void moveBmpToTexture(BitmapPtr pBmp);
+ BitmapPtr moveTextureToBmp(int mipmapLevel=0);
+
+ const IntPoint& getSize() const;
+ const IntPoint& getGLSize() const;
+ PixelFormat getPF() const;
+ unsigned getID() const;
+
+ IntPoint getMipmapSize(int level) const;
+
+ static bool isFloatFormatSupported();
+ static int getGLFormat(PixelFormat pf);
+ static int getGLType(PixelFormat pf);
+ int getGLInternalFormat() const;
+
+ void setDirty();
+ bool isDirty() const;
+ void resetDirty();
+
+ void dump(unsigned wrapSMode=-1, unsigned wrapTMode=-1) const;
+
+private:
+ IntPoint m_Size;
+ IntPoint m_GLSize;
+ PixelFormat m_pf;
+ bool m_bMipmap;
+ bool m_bDeleteTex;
+ bool m_bUsePOT;
+
+ static unsigned s_LastTexID;
+ unsigned m_TexID;
+ bool m_bIsDirty;
+ TextureMoverPtr m_pMover;
+
+ GLContext* m_pGLContext;
+};
+
+typedef boost::shared_ptr<GLTexture> GLTexturePtr;
+
+}
+
+#endif
+
+
+
diff --git a/src/graphics/GLXContext.cpp b/src/graphics/GLXContext.cpp
new file mode 100644
index 0000000..ff5477a
--- /dev/null
+++ b/src/graphics/GLXContext.cpp
@@ -0,0 +1,265 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "GLXContext.h"
+#include "GLContextAttribs.h"
+#include "X11Display.h"
+
+#include "../base/Exception.h"
+#include "../base/Logger.h"
+
+#include <SDL/SDL.h>
+#include <SDL/SDL_syswm.h>
+
+#include <X11/extensions/xf86vmode.h>
+
+#include <iostream>
+#include <stdlib.h>
+#include <limits>
+
+
+namespace avg {
+
+using namespace std;
+using namespace boost;
+
+GLXContext::GLXContext(const GLConfig& glConfig, const IntPoint& windowSize,
+ const SDL_SysWMinfo* pSDLWMInfo)
+ : GLContext(windowSize, pSDLWMInfo)
+{
+ GLConfig config = glConfig;
+ try {
+ createGLXContext(config, windowSize, pSDLWMInfo, true);
+ } catch (const Exception &e) {
+ if (e.getCode() == AVG_ERR_DEBUG_CONTEXT_FAILED) {
+ createGLXContext(config, windowSize, pSDLWMInfo, false);
+ } else {
+ exit(EXIT_FAILURE);
+ }
+ }
+ init(config, true);
+}
+
+static bool s_bX11Error;
+static bool s_bDumpX11ErrorMsg;
+static int (*s_DefaultErrorHandler) (::Display *, XErrorEvent *);
+
+int X11ErrorHandler(::Display * pDisplay, XErrorEvent * pErrEvent)
+{
+ if (s_bDumpX11ErrorMsg) {
+ char errorString[128];
+ XGetErrorText(pDisplay, pErrEvent->error_code, errorString, 128);
+ cerr << "X11 error creating GL context: " << errorString <<
+ "\n\tMajor opcode of failed request: " << (int)(pErrEvent->request_code) <<
+ "\n\tMinor opcode of failed request: " << (int)(pErrEvent->minor_code) <<
+ "\n";
+ }
+ s_bX11Error = true;
+ return 0;
+}
+
+void GLXContext::createGLXContext(GLConfig& glConfig, const IntPoint& windowSize,
+ const SDL_SysWMinfo* pSDLWMInfo, bool bUseDebugBit)
+{
+ Window win = 0;
+ s_bX11Error = false;
+ s_bDumpX11ErrorMsg = true;
+ s_DefaultErrorHandler = XSetErrorHandler(X11ErrorHandler);
+
+ m_pDisplay = getX11Display(pSDLWMInfo);
+
+ GLContextAttribs attrs;
+ attrs.append(GLX_X_RENDERABLE, 1);
+ attrs.append(GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT);
+ attrs.append(GLX_RENDER_TYPE, GLX_RGBA_BIT);
+ attrs.append(GLX_X_VISUAL_TYPE, GLX_TRUE_COLOR);
+ attrs.append(GLX_DEPTH_SIZE, 0);
+ attrs.append(GLX_STENCIL_SIZE, 8);
+ attrs.append(GLX_DOUBLEBUFFER, 1);
+ attrs.append(GLX_RED_SIZE, 8);
+ attrs.append(GLX_GREEN_SIZE, 8);
+ attrs.append(GLX_BLUE_SIZE, 8);
+ attrs.append(GLX_ALPHA_SIZE, 0);
+
+ int fbCount;
+ GLXFBConfig* pFBConfig = glXChooseFBConfig(m_pDisplay, DefaultScreen(m_pDisplay),
+ attrs.get(), &fbCount);
+ if (!pFBConfig) {
+ throw Exception(AVG_ERR_UNSUPPORTED, "Creating OpenGL context failed.");
+ }
+
+ // Find the config with the appropriate number of multisample samples.
+ int bestConfig = -1;
+ int bestSamples = -1;
+ int bestCaveat = std::numeric_limits<int>::max();
+ for (int i=0; i<fbCount; ++i) {
+ XVisualInfo* pVisualInfo = glXGetVisualFromFBConfig(m_pDisplay, pFBConfig[i]);
+ if (pVisualInfo && pVisualInfo->depth == 24) {
+ int numBuffers;
+ int numSamples;
+ int caveat;
+ glXGetFBConfigAttrib(m_pDisplay, pFBConfig[i], GLX_SAMPLE_BUFFERS,
+ &numBuffers);
+ glXGetFBConfigAttrib(m_pDisplay, pFBConfig[i], GLX_SAMPLES, &numSamples);
+ glXGetFBConfigAttrib(m_pDisplay, pFBConfig[i], GLX_CONFIG_CAVEAT, &caveat);
+ if (numSamples == 0) {
+ // Configs without multisampling have numBuffers == 0 and numSamples == 0,
+ // but the corresponding libavg config is multisamplesamples == 1.
+ numSamples = 1;
+ }
+ if ((numSamples > bestSamples && numSamples <= glConfig.m_MultiSampleSamples)
+ || (numSamples == bestSamples && caveat < bestCaveat))
+ {
+ // A config is better than the last one in two cases:
+ // 1) it has more samples per pixel (but not more than requested) or
+ // 2) it has the same number of samples per pixel but a better caveat
+ // value.
+ bestCaveat = caveat;
+ bestConfig = i;
+ bestSamples = numSamples;
+ }
+ XFree(pVisualInfo);
+ }
+ }
+
+ GLXFBConfig fbConfig = pFBConfig[bestConfig];
+ XFree(pFBConfig);
+ XVisualInfo* pVisualInfo = glXGetVisualFromFBConfig(m_pDisplay, fbConfig);
+
+ if (pSDLWMInfo) {
+ win = createChildWindow(pSDLWMInfo, pVisualInfo, windowSize, m_Colormap);
+ }
+
+ if (haveARBCreateContext()) {
+ GLContextAttribs attrs;
+ if (glConfig.m_bGLES) {
+ attrs.append(GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_ES2_PROFILE_BIT_EXT);
+ attrs.append(GLX_CONTEXT_MAJOR_VERSION_ARB, 2);
+ attrs.append(GLX_CONTEXT_MINOR_VERSION_ARB, 0);
+ }
+ if (glConfig.m_bUseDebugContext && bUseDebugBit) {
+ attrs.append(GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_DEBUG_BIT_ARB);
+ }
+ PFNGLXCREATECONTEXTATTRIBSARBPROC CreateContextAttribsARB =
+ (PFNGLXCREATECONTEXTATTRIBSARBPROC)
+ getglXProcAddress("glXCreateContextAttribsARB");
+
+ s_bDumpX11ErrorMsg = false;
+ m_Context = CreateContextAttribsARB(m_pDisplay, fbConfig, 0, 1, attrs.get());
+ s_bDumpX11ErrorMsg = true;
+ throwOnXError(AVG_ERR_DEBUG_CONTEXT_FAILED);
+ } else {
+ m_Context = glXCreateContext(m_pDisplay, pVisualInfo, 0, GL_TRUE);
+ }
+ AVG_ASSERT(m_Context);
+ if (pSDLWMInfo) {
+ setCurrent();
+ glXMakeCurrent(m_pDisplay, win, m_Context);
+ } else {
+ Pixmap pmp = XCreatePixmap(m_pDisplay,
+ RootWindow(m_pDisplay, pVisualInfo->screen), 8, 8, pVisualInfo->depth);
+ GLXPixmap pixmap = glXCreateGLXPixmap(m_pDisplay, pVisualInfo, pmp);
+
+ glXMakeCurrent(m_pDisplay, pixmap, m_Context);
+ }
+ XSetErrorHandler(s_DefaultErrorHandler);
+
+ throwOnXError();
+ glConfig.m_MultiSampleSamples = bestSamples;
+ m_Drawable = glXGetCurrentDrawable();
+}
+
+GLXContext::~GLXContext()
+{
+ deleteObjects();
+ if (m_Context && ownsContext()) {
+ glXMakeCurrent(m_pDisplay, 0, 0);
+ glXDestroyContext(m_pDisplay, m_Context);
+ m_Context = 0;
+ XDestroyWindow(m_pDisplay, m_Drawable);
+ XFreeColormap(m_pDisplay, m_Colormap);
+ }
+}
+
+void GLXContext::throwOnXError( int code)
+{
+ if (s_bX11Error) {
+ throw Exception(code, "X error creating OpenGL context.");
+ }
+}
+
+void GLXContext::activate()
+{
+ glXMakeCurrent(m_pDisplay, m_Drawable, m_Context);
+ setCurrent();
+}
+
+bool GLXContext::initVBlank(int rate)
+{
+ static bool s_bVBlankActive = false;
+ if (rate > 0) {
+ if (getenv("__GL_SYNC_TO_VBLANK") != 0) {
+ AVG_LOG_WARNING("__GL_SYNC_TO_VBLANK set. This interferes with libavg vblank handling.");
+ s_bVBlankActive = false;
+ return false;
+ }
+ if (!queryGLXExtension("GLX_EXT_swap_control")) {
+ AVG_LOG_WARNING("Linux VBlank setup failed: OpenGL Extension not supported.");
+ s_bVBlankActive = false;
+ return false;
+ }
+
+ glproc::SwapIntervalEXT(m_pDisplay, m_Drawable, rate);
+ s_bVBlankActive = true;
+ return true;
+
+ } else {
+ if (s_bVBlankActive) {
+ glproc::SwapIntervalEXT(m_pDisplay, m_Drawable, 0);
+ s_bVBlankActive = false;
+ }
+ return false;
+ }
+}
+
+bool GLXContext::useDepthBuffer() const
+{
+ // NVidia GLX GLES doesn't allow framebuffer stencil without depth.
+ return true;
+}
+
+void GLXContext::swapBuffers()
+{
+ glXSwapBuffers(m_pDisplay, m_Drawable);
+}
+
+bool GLXContext::haveARBCreateContext()
+{
+ static bool s_bExtensionChecked = false;
+ static bool s_bHaveExtension = false;
+ if (!s_bExtensionChecked) {
+ s_bExtensionChecked = true;
+ s_bHaveExtension = (queryGLXExtension("GLX_ARB_create_context"));
+ }
+ return s_bHaveExtension;
+}
+
+}
diff --git a/src/graphics/GLXContext.h b/src/graphics/GLXContext.h
new file mode 100644
index 0000000..e4f1d95
--- /dev/null
+++ b/src/graphics/GLXContext.h
@@ -0,0 +1,65 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+#ifndef _GLXContext_H_
+#define _GLXContext_H_
+#include "../api.h"
+
+#include "GLContext.h"
+
+#include "../base/Exception.h"
+
+#include <boost/shared_ptr.hpp>
+
+struct SDL_SysWMinfo;
+
+namespace avg {
+
+class AVG_API GLXContext: public GLContext
+{
+public:
+ GLXContext(const GLConfig& glConfig, const IntPoint& windowSize=IntPoint(0,0),
+ const SDL_SysWMinfo* pSDLWMInfo=0);
+ virtual ~GLXContext();
+
+ void activate();
+ bool initVBlank(int rate);
+ bool useDepthBuffer() const;
+ void swapBuffers();
+
+ static bool haveARBCreateContext();
+
+private:
+ void createGLXContext(GLConfig& glConfig, const IntPoint& windowSize,
+ const SDL_SysWMinfo* pSDLWMInfo, bool bUseDebugBit);
+
+ void throwOnXError(int code=AVG_ERR_VIDEO_GENERAL);
+
+ Display* m_pDisplay;
+ Colormap m_Colormap;
+ GLXDrawable m_Drawable;
+ ::GLXContext m_Context;
+
+};
+
+}
+#endif
+
+
diff --git a/src/graphics/GPUBandpassFilter.cpp b/src/graphics/GPUBandpassFilter.cpp
new file mode 100644
index 0000000..23171ec
--- /dev/null
+++ b/src/graphics/GPUBandpassFilter.cpp
@@ -0,0 +1,78 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "GPUBandpassFilter.h"
+#include "Bitmap.h"
+#include "ShaderRegistry.h"
+#include "OGLShader.h"
+
+#include "../base/ObjectCounter.h"
+#include "../base/Exception.h"
+
+#include <iostream>
+
+#define SHADERID "bandpass"
+
+using namespace std;
+
+namespace avg {
+
+GPUBandpassFilter::GPUBandpassFilter(const IntPoint& size, PixelFormat pfSrc,
+ float min, float max, float postScale, bool bInvert, bool bStandalone)
+ : GPUFilter(pfSrc, B8G8R8A8, bStandalone, SHADERID),
+ m_PostScale(postScale),
+ m_bInvert(bInvert),
+ m_MinFilter(size, pfSrc, R32G32B32A32F, min, true, false, true),
+ m_MaxFilter(size, pfSrc, R32G32B32A32F, max, true, false, true)
+{
+ ObjectCounter::get()->incRef(&typeid(*this));
+
+ GLContext::getCurrent()->ensureFullShaders("GPUBandpassFilter");
+
+ setDimensions(size);
+ OGLShaderPtr pShader = getShader();
+ m_pMinTexParam = pShader->getParam<int>("u_MinTex");
+ m_pMaxTexParam = pShader->getParam<int>("u_MaxTex");
+ m_pPostScaleParam = pShader->getParam<float>("u_PostScale");
+ m_pInvertParam = pShader->getParam<int>("u_bInvert");
+}
+
+GPUBandpassFilter::~GPUBandpassFilter()
+{
+ ObjectCounter::get()->decRef(&typeid(*this));
+}
+
+void GPUBandpassFilter::applyOnGPU(GLTexturePtr pSrcTex)
+{
+ m_MinFilter.apply(pSrcTex);
+ m_MaxFilter.apply(pSrcTex);
+
+ getFBO()->activate();
+ getShader()->activate();
+ m_pMinTexParam->set(0);
+ m_pMaxTexParam->set(1);
+ m_pPostScaleParam->set(float(m_PostScale));
+ m_pInvertParam->set(m_bInvert);
+ m_MaxFilter.getDestTex()->activate(GL_TEXTURE1);
+ draw(m_MinFilter.getDestTex());
+}
+
+}
diff --git a/src/graphics/GPUBandpassFilter.h b/src/graphics/GPUBandpassFilter.h
new file mode 100644
index 0000000..54f15a2
--- /dev/null
+++ b/src/graphics/GPUBandpassFilter.h
@@ -0,0 +1,56 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _GPUBandpassFilter_H_
+#define _GPUBandpassFilter_H_
+
+#include "../api.h"
+#include "GPUFilter.h"
+#include "GPUBlurFilter.h"
+#include "Bitmap.h"
+
+namespace avg {
+
+class AVG_API GPUBandpassFilter: public GPUFilter
+{
+public:
+ GPUBandpassFilter(const IntPoint& size, PixelFormat pfSrc, float min, float max,
+ float postScale, bool bInvert, bool bStandalone=true);
+ virtual ~GPUBandpassFilter();
+
+ virtual void applyOnGPU(GLTexturePtr pSrcTex);
+
+private:
+ float m_PostScale;
+ bool m_bInvert;
+
+ GPUBlurFilter m_MinFilter;
+ GPUBlurFilter m_MaxFilter;
+
+ IntGLShaderParamPtr m_pMinTexParam;
+ IntGLShaderParamPtr m_pMaxTexParam;
+ FloatGLShaderParamPtr m_pPostScaleParam;
+ IntGLShaderParamPtr m_pInvertParam;
+};
+
+}
+#endif
+
diff --git a/src/graphics/GPUBlurFilter.cpp b/src/graphics/GPUBlurFilter.cpp
new file mode 100644
index 0000000..1a6efa1
--- /dev/null
+++ b/src/graphics/GPUBlurFilter.cpp
@@ -0,0 +1,122 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "GPUBlurFilter.h"
+#include "Bitmap.h"
+#include "ShaderRegistry.h"
+#include "ImagingProjection.h"
+#include "OGLShader.h"
+
+#include "../base/ObjectCounter.h"
+#include "../base/MathHelper.h"
+#include "../base/Exception.h"
+
+#include <string.h>
+#include <iostream>
+
+#define SHADERID_HORIZ "horizblur"
+#define SHADERID_VERT "vertblur"
+
+using namespace std;
+
+namespace avg {
+
+GPUBlurFilter::GPUBlurFilter(const IntPoint& size, PixelFormat pfSrc, PixelFormat pfDest,
+ float stdDev, bool bClipBorders, bool bStandalone, bool bUseFloatKernel)
+ : GPUFilter(pfSrc, pfDest, bStandalone, SHADERID_HORIZ, 2),
+ m_bClipBorders(bClipBorders),
+ m_bUseFloatKernel(bUseFloatKernel)
+{
+ ObjectCounter::get()->incRef(&typeid(*this));
+
+ GLContext::getCurrent()->ensureFullShaders("GPUBlurFilter");
+
+ setDimensions(size, stdDev, bClipBorders);
+ createShader(SHADERID_VERT);
+ setStdDev(stdDev);
+
+ OGLShaderPtr pShader = getShader();
+ m_pHorizWidthParam = pShader->getParam<float>("u_Width");
+ m_pHorizRadiusParam = pShader->getParam<int>("u_Radius");
+ m_pHorizTextureParam = pShader->getParam<int>("u_Texture");
+ m_pHorizKernelTexParam = pShader->getParam<int>("u_KernelTex");
+
+ pShader = avg::getShader(SHADERID_VERT);
+ m_pVertWidthParam = pShader->getParam<float>("u_Width");
+ m_pVertRadiusParam = pShader->getParam<int>("u_Radius");
+ m_pVertTextureParam = pShader->getParam<int>("u_Texture");
+ m_pVertKernelTexParam = pShader->getParam<int>("u_KernelTex");
+}
+
+GPUBlurFilter::~GPUBlurFilter()
+{
+ ObjectCounter::get()->decRef(&typeid(*this));
+}
+
+void GPUBlurFilter::setStdDev(float stdDev)
+{
+ m_StdDev = stdDev;
+ m_pGaussCurveTex = calcBlurKernelTex(m_StdDev, 1, m_bUseFloatKernel);
+ setDimensions(getSrcSize(), stdDev, m_bClipBorders);
+ IntRect destRect2(IntPoint(0,0), getDestRect().size());
+ m_pProjection2 = ImagingProjectionPtr(new ImagingProjection(
+ getDestRect().size(), destRect2));
+}
+
+void GPUBlurFilter::applyOnGPU(GLTexturePtr pSrcTex)
+{
+ int kernelWidth = m_pGaussCurveTex->getSize().x;
+ getFBO(1)->activate();
+ getShader()->activate();
+ m_pHorizWidthParam->set(float(kernelWidth));
+ m_pHorizRadiusParam->set((kernelWidth-1)/2);
+ m_pHorizTextureParam->set(0);
+ m_pHorizKernelTexParam->set(1);
+ m_pGaussCurveTex->activate(GL_TEXTURE1);
+ draw(pSrcTex);
+
+ getFBO(0)->activate();
+ OGLShaderPtr pVShader = avg::getShader(SHADERID_VERT);
+ pVShader->activate();
+ m_pVertWidthParam->set(float(kernelWidth));
+ m_pVertRadiusParam->set((kernelWidth-1)/2);
+ m_pVertTextureParam->set(0);
+ m_pVertKernelTexParam->set(1);
+ getDestTex(1)->activate(GL_TEXTURE0);
+ m_pProjection2->draw(pVShader);
+}
+
+void GPUBlurFilter::setDimensions(IntPoint size, float stdDev, bool bClipBorders)
+{
+
+#ifndef AVG_ENABLE_EGL
+ if (bClipBorders) {
+ GPUFilter::setDimensions(size);
+ } else {
+ int radius = getBlurKernelRadius(stdDev);
+ IntPoint offset(radius, radius);
+ //TODO: TO_BORDER DOES NOT EXIST IN GLESV2
+ GPUFilter::setDimensions(size, IntRect(-offset, size+offset), GL_CLAMP_TO_BORDER);
+ }
+#endif
+}
+
+}
diff --git a/src/graphics/GPUBlurFilter.h b/src/graphics/GPUBlurFilter.h
new file mode 100644
index 0000000..77b8ae7
--- /dev/null
+++ b/src/graphics/GPUBlurFilter.h
@@ -0,0 +1,68 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _GPUBlurFilter_H_
+#define _GPUBlurFilter_H_
+
+#include "../api.h"
+#include "GPUFilter.h"
+#include "GLShaderParam.h"
+#include "GLTexture.h"
+
+namespace avg {
+
+class AVG_API GPUBlurFilter: public GPUFilter
+{
+public:
+ GPUBlurFilter(const IntPoint& size, PixelFormat pfSrc, PixelFormat pfDest,
+ float stdDev, bool bClipBorders, bool bStandalone=true,
+ bool bUseFloatKernel=false);
+ virtual ~GPUBlurFilter();
+
+ void setStdDev(float stdDev);
+ virtual void applyOnGPU(GLTexturePtr pSrcTex);
+
+private:
+ void setDimensions(IntPoint size, float stdDev, bool bClipBorders);
+
+ float m_StdDev;
+ bool m_bClipBorders;
+ bool m_bUseFloatKernel;
+
+ GLTexturePtr m_pGaussCurveTex;
+ ImagingProjectionPtr m_pProjection2;
+
+ FloatGLShaderParamPtr m_pHorizWidthParam;
+ IntGLShaderParamPtr m_pHorizRadiusParam;
+ IntGLShaderParamPtr m_pHorizTextureParam;
+ IntGLShaderParamPtr m_pHorizKernelTexParam;
+
+ FloatGLShaderParamPtr m_pVertWidthParam;
+ IntGLShaderParamPtr m_pVertRadiusParam;
+ IntGLShaderParamPtr m_pVertTextureParam;
+ IntGLShaderParamPtr m_pVertKernelTexParam;
+};
+
+typedef boost::shared_ptr<GPUBlurFilter> GPUBlurFilterPtr;
+
+}
+#endif
+
diff --git a/src/graphics/GPUBrightnessFilter.cpp b/src/graphics/GPUBrightnessFilter.cpp
new file mode 100644
index 0000000..a508cc1
--- /dev/null
+++ b/src/graphics/GPUBrightnessFilter.cpp
@@ -0,0 +1,64 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "GPUBrightnessFilter.h"
+#include "Bitmap.h"
+#include "ShaderRegistry.h"
+#include "OGLShader.h"
+
+#include "../base/ObjectCounter.h"
+#include "../base/Exception.h"
+
+#include <iostream>
+
+#define SHADERID "brightness"
+
+using namespace std;
+
+namespace avg {
+
+GPUBrightnessFilter::GPUBrightnessFilter(const IntPoint& size, bool bUseAlpha,
+ float alpha, bool bStandalone)
+ : GPUFilter(SHADERID, bUseAlpha, bStandalone),
+ m_Alpha(alpha)
+{
+ ObjectCounter::get()->incRef(&typeid(*this));
+ setDimensions(size);
+
+ OGLShaderPtr pShader = getShader();
+ m_pTextureParam = pShader->getParam<int>("u_Texture");
+ m_pAlphaParam = pShader->getParam<float>("u_Alpha");
+}
+
+GPUBrightnessFilter::~GPUBrightnessFilter()
+{
+ ObjectCounter::get()->decRef(&typeid(*this));
+}
+
+void GPUBrightnessFilter::applyOnGPU(GLTexturePtr pSrcTex)
+{
+ getShader()->activate();
+ m_pTextureParam->set(0);
+ m_pAlphaParam->set(m_Alpha);
+ draw(pSrcTex);
+}
+
+}
diff --git a/src/graphics/GPUBrightnessFilter.h b/src/graphics/GPUBrightnessFilter.h
new file mode 100644
index 0000000..87d0c5d
--- /dev/null
+++ b/src/graphics/GPUBrightnessFilter.h
@@ -0,0 +1,50 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _GPUBrightnessFilter_H_
+#define _GPUBrightnessFilter_H_
+
+#include "../api.h"
+#include "GPUFilter.h"
+#include "GLShaderParam.h"
+#include "Bitmap.h"
+
+namespace avg {
+
+class AVG_API GPUBrightnessFilter: public GPUFilter
+{
+public:
+ GPUBrightnessFilter(const IntPoint& size, bool bUseAlpha, float alpha,
+ bool bStandalone=true);
+ virtual ~GPUBrightnessFilter();
+
+ virtual void applyOnGPU(GLTexturePtr pSrcTex);
+
+private:
+ float m_Alpha;
+
+ IntGLShaderParamPtr m_pTextureParam;
+ FloatGLShaderParamPtr m_pAlphaParam;
+};
+
+}
+#endif
+
diff --git a/src/graphics/GPUChromaKeyFilter.cpp b/src/graphics/GPUChromaKeyFilter.cpp
new file mode 100644
index 0000000..a3ae188
--- /dev/null
+++ b/src/graphics/GPUChromaKeyFilter.cpp
@@ -0,0 +1,137 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "GPUChromaKeyFilter.h"
+#include "Bitmap.h"
+#include "ShaderRegistry.h"
+#include "OGLShader.h"
+#include "ImagingProjection.h"
+
+#include "../base/ObjectCounter.h"
+#include "../base/Exception.h"
+
+#include <iostream>
+
+#define SHADERID_CHROMAKEY "chromakey"
+#define SHADERID_EROSION "chromakey_erosion"
+
+using namespace std;
+
+namespace avg {
+
+GPUChromaKeyFilter::GPUChromaKeyFilter(const IntPoint& size, bool bStandalone)
+ : GPUFilter(SHADERID_CHROMAKEY, true, bStandalone, 2),
+ m_Color(0, 255, 0),
+ m_HTolerance(0.0),
+ m_STolerance(0.0),
+ m_LTolerance(0.0),
+ m_Softness(0.0),
+ m_Erosion(0),
+ m_SpillThreshold(0.0)
+{
+ ObjectCounter::get()->incRef(&typeid(*this));
+
+ GLContext::getCurrent()->ensureFullShaders("GPUChromaKeyFilter");
+
+ setDimensions(size);
+ OGLShaderPtr pShader = getShader();
+ m_pTextureParam = pShader->getParam<int>("u_Texture");
+
+ m_pHKeyParam = pShader->getParam<float>("u_HKey");
+ m_pHToleranceParam = pShader->getParam<float>("u_HTolerance");
+ m_pHSoftToleranceParam = pShader->getParam<float>("u_HSoftTolerance");
+
+ m_pSKeyParam = pShader->getParam<float>("u_SKey");
+ m_pSToleranceParam = pShader->getParam<float>("u_STolerance");
+ m_pSSoftToleranceParam = pShader->getParam<float>("u_SSoftTolerance");
+
+ m_pLKeyParam = pShader->getParam<float>("u_LKey");
+ m_pLToleranceParam = pShader->getParam<float>("u_LTolerance");
+ m_pLSoftToleranceParam = pShader->getParam<float>("u_LSoftTolerance");
+
+ m_pSpillThresholdParam = pShader->getParam<float>("u_SpillThreshold");
+ m_pIsLastParam = pShader->getParam<int>("u_bIsLast");
+
+ createShader(SHADERID_EROSION);
+ pShader = avg::getShader(SHADERID_EROSION);
+ m_pErosionTextureParam= pShader->getParam<int>("u_Texture");
+ m_pErosionIsLastParam = pShader->getParam<int>("u_bIsLast");
+
+ m_pProjection2 = ImagingProjectionPtr(new ImagingProjection(size));
+}
+
+GPUChromaKeyFilter::~GPUChromaKeyFilter()
+{
+ ObjectCounter::get()->decRef(&typeid(*this));
+}
+
+void GPUChromaKeyFilter::setParams(const Pixel32& color, float hTolerance,
+ float sTolerance, float lTolerance, float softness, int erosion,
+ float spillThreshold)
+{
+ m_Color = color;
+ m_HTolerance = hTolerance;
+ m_STolerance = sTolerance;
+ m_LTolerance = lTolerance;
+ m_Softness = softness;
+ m_Erosion = erosion;
+ m_SpillThreshold = spillThreshold;
+ if (m_SpillThreshold <= m_HTolerance) {
+ m_SpillThreshold = m_HTolerance;
+ }
+}
+
+void GPUChromaKeyFilter::applyOnGPU(GLTexturePtr pSrcTex)
+{
+ // Set up double-buffering
+ int curBufferIndex = m_Erosion%2;
+ getFBO(curBufferIndex)->activate();
+ getShader()->activate();
+ m_pTextureParam->set(0);
+
+ float h, s, l;
+ m_Color.toHSL(h, s, l);
+ m_pHKeyParam->set(h);
+ m_pHToleranceParam->set(m_HTolerance*360);
+ m_pHSoftToleranceParam->set((m_HTolerance+m_Softness)*360.0f);
+ m_pSKeyParam->set(s);
+ m_pSToleranceParam->set(m_STolerance);
+ m_pSSoftToleranceParam->set(m_STolerance+m_Softness);
+ m_pLKeyParam->set(l);
+ m_pLToleranceParam->set(m_LTolerance);
+ m_pLSoftToleranceParam->set(m_LTolerance+m_Softness);
+ m_pSpillThresholdParam->set(m_SpillThreshold*360);
+ m_pIsLastParam->set(int(m_Erosion==0));
+ draw(pSrcTex);
+
+ for (int i = 0; i < m_Erosion; ++i) {
+ curBufferIndex = (curBufferIndex+1)%2;
+ getFBO(curBufferIndex)->activate();
+ OGLShaderPtr pShader = avg::getShader(SHADERID_EROSION);
+ pShader->activate();
+ m_pErosionTextureParam->set(0);
+ m_pErosionIsLastParam->set(int(i==m_Erosion-1));
+ getDestTex((curBufferIndex+1)%2)->activate(GL_TEXTURE0);
+ m_pProjection2->draw(avg::getShader(SHADERID_EROSION));
+ }
+}
+
+}
diff --git a/src/graphics/GPUChromaKeyFilter.h b/src/graphics/GPUChromaKeyFilter.h
new file mode 100644
index 0000000..00024ee
--- /dev/null
+++ b/src/graphics/GPUChromaKeyFilter.h
@@ -0,0 +1,74 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _GPUChromaKeyFilter_H_
+#define _GPUChromaKeyFilter_H_
+
+#include "../api.h"
+#include "GPUFilter.h"
+#include "GLShaderParam.h"
+#include "Bitmap.h"
+
+namespace avg {
+
+class AVG_API GPUChromaKeyFilter: public GPUFilter
+{
+public:
+ GPUChromaKeyFilter(const IntPoint& size, bool bStandalone=true);
+ virtual ~GPUChromaKeyFilter();
+
+ void setParams(const Pixel32& color, float hTolerance, float sTolerance,
+ float lTolerance, float softness, int erosion, float spillThreshold);
+
+ virtual void applyOnGPU(GLTexturePtr pSrcTex);
+
+private:
+ Pixel32 m_Color;
+ float m_HTolerance;
+ float m_STolerance;
+ float m_LTolerance;
+ float m_Softness;
+ int m_Erosion;
+ float m_SpillThreshold;
+ ImagingProjectionPtr m_pProjection2;
+
+ IntGLShaderParamPtr m_pTextureParam;
+ FloatGLShaderParamPtr m_pHKeyParam;
+ FloatGLShaderParamPtr m_pHToleranceParam;
+ FloatGLShaderParamPtr m_pHSoftToleranceParam;
+ FloatGLShaderParamPtr m_pSKeyParam;
+ FloatGLShaderParamPtr m_pSToleranceParam;
+ FloatGLShaderParamPtr m_pSSoftToleranceParam;
+ FloatGLShaderParamPtr m_pLKeyParam;
+ FloatGLShaderParamPtr m_pLToleranceParam;
+ FloatGLShaderParamPtr m_pLSoftToleranceParam;
+ FloatGLShaderParamPtr m_pSpillThresholdParam;
+ IntGLShaderParamPtr m_pIsLastParam;
+
+ IntGLShaderParamPtr m_pErosionTextureParam;
+ IntGLShaderParamPtr m_pErosionIsLastParam;
+};
+
+typedef boost::shared_ptr<GPUChromaKeyFilter> GPUChromaKeyFilterPtr;
+
+}
+#endif
+
diff --git a/src/graphics/GPUFilter.cpp b/src/graphics/GPUFilter.cpp
new file mode 100644
index 0000000..36fe811
--- /dev/null
+++ b/src/graphics/GPUFilter.cpp
@@ -0,0 +1,287 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "GPUFilter.h"
+#include "Bitmap.h"
+
+#include "VertexArray.h"
+#include "ImagingProjection.h"
+#include "GLContext.h"
+#include "ShaderRegistry.h"
+#include "Filterfliprgb.h"
+#include "BitmapLoader.h"
+
+#include "../base/ObjectCounter.h"
+#include "../base/Exception.h"
+#include "../base/MathHelper.h"
+
+#include <iostream>
+#include <string.h>
+
+using namespace std;
+using namespace boost;
+
+namespace avg {
+
+GPUFilter::GPUFilter(const string& sShaderID, bool bUseAlpha,
+ bool bStandalone, unsigned numTextures, bool bMipmap)
+ : m_bStandalone(bStandalone),
+ m_NumTextures(numTextures),
+ m_bMipmap(bMipmap),
+ m_SrcSize(0,0),
+ m_DestRect(0,0,0,0)
+{
+ m_PFSrc = BitmapLoader::get()->getDefaultPixelFormat(bUseAlpha);
+ m_PFDest = m_PFSrc;
+ createShader(sShaderID);
+
+ m_pShader = avg::getShader(sShaderID);
+ ObjectCounter::get()->incRef(&typeid(*this));
+}
+
+GPUFilter::GPUFilter(PixelFormat pfSrc, PixelFormat pfDest, bool bStandalone,
+ const string& sShaderID, unsigned numTextures, bool bMipmap)
+ : m_PFSrc(pfSrc),
+ m_PFDest(pfDest),
+ m_bStandalone(bStandalone),
+ m_NumTextures(numTextures),
+ m_bMipmap(bMipmap),
+ m_SrcSize(0,0),
+ m_DestRect(0,0,0,0)
+{
+ createShader(sShaderID);
+ m_pShader = avg::getShader(sShaderID);
+ ObjectCounter::get()->incRef(&typeid(*this));
+}
+
+GPUFilter::~GPUFilter()
+{
+ ObjectCounter::get()->decRef(&typeid(*this));
+}
+
+BitmapPtr GPUFilter::apply(BitmapPtr pBmpSource)
+{
+ AVG_ASSERT(m_pSrcTex);
+ AVG_ASSERT(!(m_pFBOs.empty()));
+ m_pSrcMover->moveBmpToTexture(pBmpSource, *m_pSrcTex);
+ apply(m_pSrcTex);
+ BitmapPtr pFilteredBmp = m_pFBOs[0]->getImage();
+
+ BitmapPtr pTmpBmp;
+ if (pixelFormatIsBlueFirst(pFilteredBmp->getPixelFormat()) !=
+ pixelFormatIsBlueFirst(pBmpSource->getPixelFormat()) &&
+ pFilteredBmp->getBytesPerPixel() <= 4)
+ {
+ pTmpBmp = FilterFlipRGB().apply(pFilteredBmp);
+ } else {
+ pTmpBmp = pFilteredBmp;
+ }
+
+ BitmapPtr pDestBmp;
+ if (pTmpBmp->getPixelFormat() != pBmpSource->getPixelFormat()) {
+ pDestBmp = BitmapPtr(new Bitmap(m_DestRect.size(),
+ pBmpSource->getPixelFormat()));
+ pDestBmp->copyPixels(*pTmpBmp);
+ } else {
+ pDestBmp = pTmpBmp;
+ }
+ return pDestBmp;
+}
+
+void GPUFilter::apply(GLTexturePtr pSrcTex)
+{
+ m_pFBOs[0]->activate();
+ applyOnGPU(pSrcTex);
+ m_pFBOs[0]->copyToDestTexture();
+}
+
+GLTexturePtr GPUFilter::getDestTex(int i) const
+{
+ return m_pFBOs[i]->getTex();
+}
+
+BitmapPtr GPUFilter::getImage() const
+{
+ return m_pFBOs[0]->getImage();
+}
+
+FBOPtr GPUFilter::getFBO(int i)
+{
+ return m_pFBOs[i];
+}
+
+const IntRect& GPUFilter::getDestRect() const
+{
+ return m_DestRect;
+}
+
+const IntPoint& GPUFilter::getSrcSize() const
+{
+ return m_SrcSize;
+}
+
+FRect GPUFilter::getRelDestRect() const
+{
+ glm::vec2 srcSize(m_SrcSize);
+ return FRect(m_DestRect.tl.x/srcSize.x, m_DestRect.tl.y/srcSize.y,
+ m_DestRect.br.x/srcSize.x, m_DestRect.br.y/srcSize.y);
+}
+
+void GPUFilter::setDimensions(const IntPoint& srcSize)
+{
+ setDimensions(srcSize, IntRect(IntPoint(0,0), srcSize), GL_CLAMP_TO_EDGE);
+}
+
+void GPUFilter::setDimensions(const IntPoint& srcSize, const IntRect& destRect,
+ unsigned texMode)
+{
+ bool bProjectionChanged = false;
+ if (destRect != m_DestRect) {
+ m_pFBOs.clear();
+ for (unsigned i=0; i<m_NumTextures; ++i) {
+ FBOPtr pFBO = FBOPtr(new FBO(destRect.size(), m_PFDest, 1, 1, false,
+ m_bMipmap));
+ m_pFBOs.push_back(pFBO);
+ }
+ m_DestRect = destRect;
+ bProjectionChanged = true;
+ }
+ if (m_bStandalone && srcSize != m_SrcSize) {
+ m_pSrcTex = GLTexturePtr(new GLTexture(srcSize, m_PFSrc, false, 0, texMode,
+ texMode));
+ m_pSrcMover = TextureMover::create(srcSize, m_PFSrc, GL_STREAM_DRAW);
+ bProjectionChanged = true;
+ }
+ m_SrcSize = srcSize;
+ if (bProjectionChanged) {
+ m_pProjection = ImagingProjectionPtr(new ImagingProjection(srcSize, destRect));
+ }
+}
+
+const OGLShaderPtr& GPUFilter::getShader() const
+{
+ return m_pShader;
+}
+
+void GPUFilter::draw(GLTexturePtr pTex)
+{
+ pTex->activate(GL_TEXTURE0);
+ m_pProjection->draw(m_pShader);
+}
+
+void dumpKernel(int width, float* pKernel)
+{
+ cerr << " Kernel width: " << width << endl;
+ float sum = 0;
+ for (int i = 0; i < width; ++i) {
+ sum += pKernel[i];
+ cerr << " " << pKernel[i] << endl;
+ }
+ cerr << "Sum of coefficients: " << sum << endl;
+}
+
+int GPUFilter::getBlurKernelRadius(float stdDev) const
+{
+ return int(ceil(stdDev*3));
+}
+
+GLTexturePtr GPUFilter::calcBlurKernelTex(float stdDev, float opacity, bool bUseFloat)
+ const
+{
+ AVG_ASSERT(opacity != -1);
+ int kernelWidth;
+ float* pKernel;
+ if (stdDev == 0) {
+ kernelWidth = 1;
+ pKernel = new float[1];
+ pKernel[0] = float(opacity);
+ } else {
+ float tempCoeffs[1024];
+ int i=0;
+ float coeff;
+ do {
+ coeff = float(exp(-i*i/(2*stdDev*stdDev))/sqrt(2*PI*stdDev*stdDev))
+ *float(opacity);
+ tempCoeffs[i] = coeff;
+ i++;
+ } while (coeff > 0.003 && i < 1024);
+ if (i > 1) {
+ int kernelCenter = i - 2;
+ kernelWidth = kernelCenter*2+1;
+ pKernel = new float[kernelWidth];
+ float sum = 0;
+ for (int i = 0; i <= kernelCenter; ++i) {
+ pKernel[kernelCenter+i] = tempCoeffs[i];
+ sum += tempCoeffs[i];
+ if (i != 0) {
+ pKernel[kernelCenter-i] = tempCoeffs[i];
+ sum += tempCoeffs[i];
+ }
+ }
+ // Make sure the sum of coefficients is opacity despite the inaccuracies
+ // introduced by using a kernel of finite size.
+ for (int i = 0; i < kernelWidth; ++i) {
+ pKernel[i] *= float(opacity)/sum;
+ }
+ } else {
+ // Blur is so wide that all pixels would be black at 8-bit precision
+ kernelWidth = 1;
+ pKernel = new float[1];
+ pKernel[0] = 0.;
+ }
+ }
+// dumpKernel(kernelWidth, pKernel);
+
+ IntPoint size(kernelWidth, 1);
+ PixelFormat pf;
+ if (bUseFloat) {
+ pf = R32G32B32A32F;
+ } else {
+ pf = I8;
+ }
+ GLTexturePtr pTex(new GLTexture(size, pf));
+ TextureMoverPtr pKernelMover = TextureMover::create(size, pf, GL_STREAM_DRAW);
+ BitmapPtr pBmp = pKernelMover->lock();
+ void * pPixels = pBmp->getPixels();
+ GLContext::checkError("GPUFilter::calcBlurKernelTex MapBuffer()");
+ if (bUseFloat) {
+ float * pCurFloat = (float*)pPixels;
+ for (int i = 0; i < kernelWidth; ++i) {
+ for (int j = 0; j < 4; ++j) {
+ *pCurFloat = pKernel[i];
+ ++pCurFloat;
+ }
+ }
+ } else {
+ unsigned char * pCurPixel = (unsigned char *)pPixels;
+ for (int i = 0; i < kernelWidth; ++i) {
+ *pCurPixel = (unsigned char)(pKernel[i]*255+0.5);
+ ++pCurPixel;
+ }
+ }
+ pKernelMover->unlock();
+ pKernelMover->moveToTexture(*pTex);
+
+ delete[] pKernel;
+ return pTex;
+}
+
+}
diff --git a/src/graphics/GPUFilter.h b/src/graphics/GPUFilter.h
new file mode 100644
index 0000000..bcaa114
--- /dev/null
+++ b/src/graphics/GPUFilter.h
@@ -0,0 +1,89 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _GPUFilter_H_
+#define _GPUFilter_H_
+
+#include "../api.h"
+#include "Filter.h"
+#include "VertexArray.h"
+#include "Bitmap.h"
+#include "TextureMover.h"
+#include "FBO.h"
+
+namespace avg {
+
+class ImagingProjection;
+typedef boost::shared_ptr<ImagingProjection> ImagingProjectionPtr;
+class OGLShader;
+typedef boost::shared_ptr<OGLShader> OGLShaderPtr;
+
+class AVG_API GPUFilter: public Filter
+{
+public:
+ GPUFilter(const std::string& sShaderID, bool bUseAlpha, bool bStandalone=false,
+ unsigned numTextures=1, bool bMipmap=false);
+ GPUFilter(PixelFormat pfSrc, PixelFormat pfDest, bool bStandalone,
+ const std::string& sShaderID, unsigned numTextures=1, bool bMipmap=false);
+ virtual ~GPUFilter();
+
+ virtual BitmapPtr apply(BitmapPtr pBmpSource);
+ virtual void apply(GLTexturePtr pSrcTex);
+ virtual void applyOnGPU(GLTexturePtr pSrcTex) = 0;
+ GLTexturePtr getDestTex(int i=0) const;
+ BitmapPtr getImage() const;
+ FBOPtr getFBO(int i=0);
+
+ const IntRect& getDestRect() const;
+ const IntPoint& getSrcSize() const;
+ FRect getRelDestRect() const;
+
+protected:
+ void setDimensions(const IntPoint& srcSize);
+ void setDimensions(const IntPoint& srcSize, const IntRect& destRect,
+ unsigned texMode);
+ const OGLShaderPtr& getShader() const;
+
+ void draw(GLTexturePtr pTex);
+ int getBlurKernelRadius(float stdDev) const;
+ GLTexturePtr calcBlurKernelTex(float stdDev, float opacity, bool bUseFloat) const;
+
+private:
+ PixelFormat m_PFSrc;
+ PixelFormat m_PFDest;
+ bool m_bStandalone;
+ unsigned m_NumTextures;
+ bool m_bMipmap;
+
+ GLTexturePtr m_pSrcTex;
+ TextureMoverPtr m_pSrcMover;
+ std::vector<FBOPtr> m_pFBOs;
+ IntPoint m_SrcSize;
+ IntRect m_DestRect;
+ OGLShaderPtr m_pShader;
+ ImagingProjectionPtr m_pProjection;
+};
+
+typedef boost::shared_ptr<GPUFilter> GPUFilterPtr;
+
+}
+#endif
+
diff --git a/src/graphics/GPUHueSatFilter.cpp b/src/graphics/GPUHueSatFilter.cpp
new file mode 100644
index 0000000..4f1b46b
--- /dev/null
+++ b/src/graphics/GPUHueSatFilter.cpp
@@ -0,0 +1,77 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "GPUHueSatFilter.h"
+#include "ShaderRegistry.h"
+#include "OGLShader.h"
+
+#include "../base/ObjectCounter.h"
+#include "../base/Logger.h"
+
+#define SHADERID_HSL_COLOR "huesat"
+
+using namespace std;
+
+namespace avg {
+
+GPUHueSatFilter::GPUHueSatFilter(const IntPoint& size, bool bUseAlpha, bool bStandalone)
+ : GPUFilter(SHADERID_HSL_COLOR, bUseAlpha, bStandalone),
+ m_LightnessOffset(0.0),
+ m_Hue(0.0),
+ m_Saturation(0.0)
+{
+ ObjectCounter::get()->incRef(&typeid(*this));
+ setDimensions(size);
+ OGLShaderPtr pShader = getShader();
+ m_pHueParam = pShader->getParam<float>("u_Hue");
+ m_pSatParam = pShader->getParam<float>("u_Sat");
+ m_pLightnessParam = pShader->getParam<float>("u_LightnessOffset");
+ m_pColorizeParam = pShader->getParam<int>("u_bColorize");
+ m_pTextureParam = pShader->getParam<int>("u_Texture");
+}
+
+GPUHueSatFilter::~GPUHueSatFilter()
+{
+ ObjectCounter::get()->decRef(&typeid(*this));
+}
+
+void GPUHueSatFilter::setParams(int hue, int saturation,
+ int light_add, bool colorize)
+{
+ m_Hue = float(hue);
+ m_Saturation = saturation / 100.0f;
+ m_LightnessOffset = light_add / 100.0f;
+ m_bColorize = colorize;
+}
+
+void GPUHueSatFilter::applyOnGPU(GLTexturePtr pSrcTex)
+{
+ getShader()->activate();
+ m_pHueParam->set(m_Hue);
+ m_pSatParam->set(m_Saturation);
+ m_pLightnessParam->set(m_LightnessOffset);
+ m_pColorizeParam->set((int)(m_bColorize));
+ m_pTextureParam->set(0);
+ draw(pSrcTex);
+}
+
+}
+
diff --git a/src/graphics/GPUHueSatFilter.h b/src/graphics/GPUHueSatFilter.h
new file mode 100644
index 0000000..b712ce1
--- /dev/null
+++ b/src/graphics/GPUHueSatFilter.h
@@ -0,0 +1,59 @@
+//
+//// libavg - Media Playback Engine.
+//// Copyright (C) 2003-2011 Ulrich von Zadow
+////
+//// This library is free software; you can redistribute it and/or
+//// modify it under the terms of the GNU Lesser General Public
+//// License as published by the Free Software Foundation; either
+//// version 2 of the License, or (at your option) any later version.
+////
+//// This library is distributed in the hope that it will be useful,
+//// but WITHOUT ANY WARRANTY; without even the implied warranty of
+//// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+//// Lesser General Public License for more details.
+////
+//// You should have received a copy of the GNU Lesser General Public
+//// License along with this library; if not, write to the Free Software
+//// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+////
+//// Current versions can be found at www.libavg.de
+////
+//
+
+#ifndef _GPUHueSatFilter_H_
+#define _GPUHueSatFilter_H_
+
+#include "../api.h"
+
+#include "GPUFilter.h"
+#include "GLShaderParam.h"
+
+namespace avg {
+
+class AVG_API GPUHueSatFilter: public GPUFilter
+{
+public:
+ GPUHueSatFilter(const IntPoint& size, bool bUseAlpha, bool bStandalone=true);
+ virtual ~GPUHueSatFilter();
+
+ virtual void applyOnGPU(GLTexturePtr pSrcTex);
+ void setParams(int hue, int saturation=1, int lightness_offset=0,
+ bool colorize=false);
+
+private:
+ float m_LightnessOffset;
+ float m_Hue;
+ float m_Saturation;
+ bool m_bColorize;
+
+ FloatGLShaderParamPtr m_pHueParam;
+ FloatGLShaderParamPtr m_pSatParam;
+ FloatGLShaderParamPtr m_pLightnessParam;
+ IntGLShaderParamPtr m_pColorizeParam;
+ IntGLShaderParamPtr m_pTextureParam;
+};
+
+typedef boost::shared_ptr<GPUHueSatFilter> GPUHueSatFilterPtr;
+
+}
+#endif
diff --git a/src/graphics/GPUInvertFilter.cpp b/src/graphics/GPUInvertFilter.cpp
new file mode 100644
index 0000000..4f98050
--- /dev/null
+++ b/src/graphics/GPUInvertFilter.cpp
@@ -0,0 +1,56 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "GPUInvertFilter.h"
+#include "ShaderRegistry.h"
+#include "OGLShader.h"
+
+#include "../base/ObjectCounter.h"
+#include "../base/Logger.h"
+
+#define SHADERID_INVERT_COLOR "invert"
+
+using namespace std;
+
+namespace avg {
+
+GPUInvertFilter::GPUInvertFilter(const IntPoint& size, bool bUseAlpha, bool bStandalone)
+ : GPUFilter(SHADERID_INVERT_COLOR, bUseAlpha, bStandalone)
+{
+ ObjectCounter::get()->incRef(&typeid(*this));
+ setDimensions(size);
+ m_pTextureParam = getShader()->getParam<int>("u_Texture");
+}
+
+GPUInvertFilter::~GPUInvertFilter()
+{
+ ObjectCounter::get()->decRef(&typeid(*this));
+}
+
+void GPUInvertFilter::applyOnGPU(GLTexturePtr pSrcTex)
+{
+ getShader()->activate();
+ m_pTextureParam->set(0);
+ draw(pSrcTex);
+}
+
+}
+
diff --git a/src/graphics/GPUInvertFilter.h b/src/graphics/GPUInvertFilter.h
new file mode 100644
index 0000000..eb5f6f4
--- /dev/null
+++ b/src/graphics/GPUInvertFilter.h
@@ -0,0 +1,49 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+//
+
+#ifndef _GPUInvertFilter_H_
+#define _GPUInvertFilter_H_
+
+#include "../api.h"
+
+#include "GPUFilter.h"
+#include "GLShaderParam.h"
+
+namespace avg {
+
+class AVG_API GPUInvertFilter : public GPUFilter
+{
+public:
+ GPUInvertFilter(const IntPoint& size, bool bUseAlpha, bool bStandalone=true);
+ virtual ~GPUInvertFilter();
+
+ virtual void applyOnGPU(GLTexturePtr pSrcTex);
+ void initShader();
+
+private:
+ IntGLShaderParamPtr m_pTextureParam;
+};
+
+typedef boost::shared_ptr<GPUInvertFilter> GPUInvertFilterPtr;
+
+}
+#endif
diff --git a/src/graphics/GPUNullFilter.cpp b/src/graphics/GPUNullFilter.cpp
new file mode 100644
index 0000000..4a87c28
--- /dev/null
+++ b/src/graphics/GPUNullFilter.cpp
@@ -0,0 +1,61 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "GPUNullFilter.h"
+#include "Bitmap.h"
+#include "ShaderRegistry.h"
+#include "OGLShader.h"
+#include "BitmapLoader.h"
+
+#include "../base/ObjectCounter.h"
+#include "../base/Exception.h"
+
+#include <iostream>
+
+#define SHADERID "null"
+
+using namespace std;
+
+namespace avg {
+
+GPUNullFilter::GPUNullFilter(const IntPoint& size, bool bStandalone)
+ : GPUFilter(SHADERID, true, bStandalone)
+{
+ ObjectCounter::get()->incRef(&typeid(*this));
+
+ setDimensions(size);
+ m_pTextureParam = getShader()->getParam<int>("u_Texture");
+}
+
+GPUNullFilter::~GPUNullFilter()
+{
+ ObjectCounter::get()->decRef(&typeid(*this));
+}
+
+void GPUNullFilter::applyOnGPU(GLTexturePtr pSrcTex)
+{
+ getShader()->activate();
+ m_pTextureParam->set(0);
+ draw(pSrcTex);
+
+}
+
+}
diff --git a/src/graphics/GPUNullFilter.h b/src/graphics/GPUNullFilter.h
new file mode 100644
index 0000000..f120c0d
--- /dev/null
+++ b/src/graphics/GPUNullFilter.h
@@ -0,0 +1,48 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _GPUNullFilter_H_
+#define _GPUNullFilter_H_
+
+#include "../api.h"
+#include "GPUFilter.h"
+#include "GLShaderParam.h"
+#include "Bitmap.h"
+
+namespace avg {
+
+class AVG_API GPUNullFilter: public GPUFilter
+{
+public:
+ GPUNullFilter(const IntPoint& size, bool bStandalone=true);
+ virtual ~GPUNullFilter();
+
+ virtual void applyOnGPU(GLTexturePtr pSrcTex);
+
+private:
+ IntGLShaderParamPtr m_pTextureParam;
+};
+
+typedef boost::shared_ptr<GPUNullFilter> GPUNullFilterPtr;
+
+}
+#endif
+
diff --git a/src/graphics/GPURGB2YUVFilter.cpp b/src/graphics/GPURGB2YUVFilter.cpp
new file mode 100644
index 0000000..c40de13
--- /dev/null
+++ b/src/graphics/GPURGB2YUVFilter.cpp
@@ -0,0 +1,68 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "GPURGB2YUVFilter.h"
+#include "Bitmap.h"
+#include "ShaderRegistry.h"
+#include "OGLShader.h"
+#include "ImagingProjection.h"
+
+#include "../base/ObjectCounter.h"
+#include "../base/MathHelper.h"
+#include "../base/Exception.h"
+
+#include <string.h>
+#include <iostream>
+
+#define SHADERID "rgb2yuv"
+
+using namespace std;
+
+namespace avg {
+
+GPURGB2YUVFilter::GPURGB2YUVFilter(const IntPoint& size)
+ : GPUFilter(SHADERID, false, false)
+{
+ ObjectCounter::get()->incRef(&typeid(*this));
+
+ setDimensions(size);
+}
+
+GPURGB2YUVFilter::~GPURGB2YUVFilter()
+{
+ ObjectCounter::get()->decRef(&typeid(*this));
+}
+
+void GPURGB2YUVFilter::applyOnGPU(GLTexturePtr pSrcTex)
+{
+ getShader()->activate();
+ draw(pSrcTex);
+ GLContext::checkError("GPURGB2YUVFilter::applyOnGPU()");
+}
+
+BitmapPtr GPURGB2YUVFilter::getResults()
+{
+ BitmapPtr pBmp = getFBO()->getImage();
+
+ return pBmp;
+}
+
+}
diff --git a/src/graphics/GPURGB2YUVFilter.h b/src/graphics/GPURGB2YUVFilter.h
new file mode 100644
index 0000000..9e77ee8
--- /dev/null
+++ b/src/graphics/GPURGB2YUVFilter.h
@@ -0,0 +1,48 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _GPURGB2YUVFilter_H_
+#define _GPURGB2YUVFilter_H_
+
+#include "../api.h"
+#include "GPUFilter.h"
+#include "GLTexture.h"
+
+namespace avg {
+
+class AVG_API GPURGB2YUVFilter: public GPUFilter
+{
+public:
+ GPURGB2YUVFilter(const IntPoint& size);
+ virtual ~GPURGB2YUVFilter();
+
+ virtual void applyOnGPU(GLTexturePtr pSrcTex);
+
+ BitmapPtr getResults();
+
+private:
+};
+
+typedef boost::shared_ptr<GPURGB2YUVFilter> GPURGB2YUVFilterPtr;
+
+}
+#endif
+
diff --git a/src/graphics/GPUShadowFilter.cpp b/src/graphics/GPUShadowFilter.cpp
new file mode 100644
index 0000000..6c8f0ec
--- /dev/null
+++ b/src/graphics/GPUShadowFilter.cpp
@@ -0,0 +1,136 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "GPUShadowFilter.h"
+#include "Bitmap.h"
+#include "ShaderRegistry.h"
+#include "OGLShader.h"
+#include "ImagingProjection.h"
+
+#include "../base/ObjectCounter.h"
+#include "../base/MathHelper.h"
+#include "../base/Exception.h"
+
+#include <string.h>
+#include <iostream>
+
+#define SHADERID_HORIZ "horizshadow"
+#define SHADERID_VERT "vertshadow"
+
+using namespace std;
+
+namespace avg {
+
+GPUShadowFilter::GPUShadowFilter(const IntPoint& size, const glm::vec2& offset,
+ float stdDev, float opacity, const Pixel32& color)
+ : GPUFilter(SHADERID_HORIZ, true, false, 2)
+{
+ ObjectCounter::get()->incRef(&typeid(*this));
+
+ GLContext::getCurrent()->ensureFullShaders("GPUShadowFilter");
+
+ setDimensions(size, stdDev, offset);
+ createShader(SHADERID_VERT);
+ setParams(offset, stdDev, opacity, color);
+ OGLShaderPtr pShader = getShader();
+ m_pHorizWidthParam = pShader->getParam<float>("u_Width");
+ m_pHorizRadiusParam = pShader->getParam<int>("u_Radius");
+ m_pHorizTextureParam = pShader->getParam<int>("u_Texture");
+ m_pHorizKernelTexParam = pShader->getParam<int>("u_KernelTex");
+ m_pHorizOffsetParam = pShader->getParam<glm::vec2>("u_Offset");
+
+ pShader = avg::getShader(SHADERID_VERT);
+ m_pVertWidthParam = pShader->getParam<float>("u_Width");
+ m_pVertRadiusParam = pShader->getParam<int>("u_Radius");
+ m_pVertTextureParam = pShader->getParam<int>("u_HBlurTex");
+ m_pVertKernelTexParam = pShader->getParam<int>("u_KernelTex");
+ m_pVertColorParam = pShader->getParam<Pixel32>("u_Color");
+ m_pVertOrigTexParam = pShader->getParam<int>("u_OrigTex");
+ m_pVertDestPosParam = pShader->getParam<glm::vec2>("u_DestPos");
+ m_pVertDestSizeParam = pShader->getParam<glm::vec2>("u_DestSize");
+}
+
+GPUShadowFilter::~GPUShadowFilter()
+{
+ ObjectCounter::get()->decRef(&typeid(*this));
+}
+
+void GPUShadowFilter::setParams(const glm::vec2& offset, float stdDev, float opacity,
+ const Pixel32& color)
+{
+ m_Offset = offset;
+ m_StdDev = stdDev;
+ m_Opacity = opacity;
+ m_Color = color;
+ m_pGaussCurveTex = calcBlurKernelTex(m_StdDev, m_Opacity, false);
+ setDimensions(getSrcSize(), stdDev, offset);
+ IntRect destRect2(IntPoint(0,0), getDestRect().size());
+ m_pProjection2 = ImagingProjectionPtr(new ImagingProjection(
+ getDestRect().size(), destRect2));
+}
+
+void GPUShadowFilter::applyOnGPU(GLTexturePtr pSrcTex)
+{
+ int kernelWidth = m_pGaussCurveTex->getSize().x;
+ getFBO(1)->activate();
+ getShader()->activate();
+ m_pHorizWidthParam->set(float(kernelWidth));
+ m_pHorizRadiusParam->set((kernelWidth-1)/2);
+ m_pHorizTextureParam->set(0);
+ m_pHorizKernelTexParam->set(1);
+ IntPoint size = getSrcSize();
+ glm::vec2 texOffset(m_Offset.x/size.x, m_Offset.y/size.y);
+ m_pHorizOffsetParam->set(texOffset);
+ m_pGaussCurveTex->activate(GL_TEXTURE1);
+ draw(pSrcTex);
+
+ getFBO(0)->activate();
+ OGLShaderPtr pVShader = avg::getShader(SHADERID_VERT);
+ pVShader->activate();
+ m_pVertWidthParam->set(float(kernelWidth));
+ m_pVertRadiusParam->set((kernelWidth-1)/2);
+ m_pVertTextureParam->set(0);
+ m_pVertKernelTexParam->set(1);
+ m_pVertColorParam->set(m_Color);
+
+ pSrcTex->activate(GL_TEXTURE2);
+ m_pVertOrigTexParam->set(2);
+ FRect destRect = getRelDestRect();
+ m_pVertDestPosParam->set(destRect.tl);
+ m_pVertDestSizeParam->set(destRect.size());
+ getDestTex(1)->activate(GL_TEXTURE0);
+ m_pProjection2->draw(avg::getShader(SHADERID_VERT));
+}
+
+void GPUShadowFilter::setDimensions(IntPoint size, float stdDev, const glm::vec2& offset)
+{
+ int radius = getBlurKernelRadius(stdDev);
+ IntPoint radiusOffset(radius, radius);
+ IntPoint intOffset(offset);
+ IntRect destRect(intOffset-radiusOffset, intOffset+size+radiusOffset+IntPoint(1,1));
+ destRect.expand(IntRect(IntPoint(0,0), size));
+ //TODO FIX OPENGLESV2
+ #ifndef AVG_ENABLE_EGL
+ GPUFilter::setDimensions(size, destRect, GL_CLAMP_TO_BORDER);
+ #endif
+}
+
+}
diff --git a/src/graphics/GPUShadowFilter.h b/src/graphics/GPUShadowFilter.h
new file mode 100644
index 0000000..2e6a53f
--- /dev/null
+++ b/src/graphics/GPUShadowFilter.h
@@ -0,0 +1,76 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _GPUShadowFilter_H_
+#define _GPUShadowFilter_H_
+
+#include "../api.h"
+#include "GPUFilter.h"
+#include "GLShaderParam.h"
+#include "GLTexture.h"
+
+#include "../base/GLMHelper.h"
+
+namespace avg {
+
+class AVG_API GPUShadowFilter: public GPUFilter
+{
+public:
+ GPUShadowFilter(const IntPoint& size, const glm::vec2& offset, float stdDev,
+ float opacity, const Pixel32& color);
+ virtual ~GPUShadowFilter();
+
+ void setParams(const glm::vec2& offset, float stdDev, float opacity,
+ const Pixel32& color);
+ virtual void applyOnGPU(GLTexturePtr pSrcTex);
+
+private:
+ void setDimensions(IntPoint size, float stdDev, const glm::vec2& offset);
+
+ glm::vec2 m_Offset;
+ float m_StdDev;
+ float m_Opacity;
+ Pixel32 m_Color;
+
+ GLTexturePtr m_pGaussCurveTex;
+ ImagingProjectionPtr m_pProjection2;
+
+ FloatGLShaderParamPtr m_pHorizWidthParam;
+ IntGLShaderParamPtr m_pHorizRadiusParam;
+ IntGLShaderParamPtr m_pHorizTextureParam;
+ IntGLShaderParamPtr m_pHorizKernelTexParam;
+ Vec2fGLShaderParamPtr m_pHorizOffsetParam;
+
+ FloatGLShaderParamPtr m_pVertWidthParam;
+ IntGLShaderParamPtr m_pVertRadiusParam;
+ IntGLShaderParamPtr m_pVertTextureParam;
+ IntGLShaderParamPtr m_pVertKernelTexParam;
+ ColorGLShaderParamPtr m_pVertColorParam;
+ IntGLShaderParamPtr m_pVertOrigTexParam;
+ Vec2fGLShaderParamPtr m_pVertDestPosParam;
+ Vec2fGLShaderParamPtr m_pVertDestSizeParam;
+};
+
+typedef boost::shared_ptr<GPUShadowFilter> GPUShadowFilterPtr;
+
+}
+#endif
+
diff --git a/src/graphics/GraphicsTest.cpp b/src/graphics/GraphicsTest.cpp
new file mode 100644
index 0000000..9d517f5
--- /dev/null
+++ b/src/graphics/GraphicsTest.cpp
@@ -0,0 +1,142 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "GraphicsTest.h"
+#include "Bitmap.h"
+#include "BitmapLoader.h"
+#include "Filterfliprgb.h"
+#include "Filtergrayscale.h"
+
+#include "../base/Directory.h"
+#include "../base/Exception.h"
+
+#include <iostream>
+#include <sstream>
+#include <math.h>
+
+namespace avg {
+
+using namespace avg;
+using namespace std;
+
+GraphicsTest::GraphicsTest(const string& sName, int indentLevel)
+ : Test(sName, indentLevel)
+{
+}
+
+void GraphicsTest::createResultImgDir()
+{
+ Directory dir("resultimages");
+ int ok = dir.open(true);
+ if (ok == 0) {
+ dir.empty();
+ } else {
+ stringstream s;
+ s << "Could not create result image dir '" << dir.getName() << "'.";
+ cerr << s.str() << endl;
+ throw Exception(AVG_ERR_VIDEO_GENERAL, s.str());
+ }
+}
+
+BitmapPtr GraphicsTest::loadTestBmp(const std::string& sFName, PixelFormat pf)
+{
+ try {
+ string sFullName = getSrcDirName()+"../test/media/"+sFName+".png";
+ return loadBitmap(sFullName, pf);
+ } catch (Exception & ex) {
+ cerr << ex.getStr() << endl;
+ throw;
+ }
+}
+
+void GraphicsTest::testEqual(Bitmap& resultBmp, const string& sFName, PixelFormat pf,
+ float maxAverage, float maxStdDev)
+{
+ BitmapPtr pBaselineBmp;
+ try {
+ string sFullName = getSrcDirName()+"baseline/"+sFName+".png";
+ pBaselineBmp = loadBitmap(sFullName, pf);
+ } catch (Exception & ex) {
+ cerr << ex.getStr() << endl;
+ resultBmp.save("resultimages/"+sFName+".png");
+ throw;
+ }
+ testEqual(resultBmp, *pBaselineBmp, sFName, maxAverage, maxStdDev);
+}
+
+void GraphicsTest::testEqual(Bitmap& resultBmp, Bitmap& baselineBmp,
+ const string& sFName, float maxAverage, float maxStdDev)
+{
+ BitmapPtr pDiffBmp;
+ try {
+ pDiffBmp = resultBmp.subtract(baselineBmp);
+ } catch (Exception& e) {
+ TEST_FAILED("Error: " << e.getStr() << ". File: '" << sFName << "'.");
+ string sResultName = "resultimages/"+sFName;
+ resultBmp.save(sResultName+".png");
+ baselineBmp.save(sResultName+"_baseline.png");
+ }
+ if (pDiffBmp) {
+ float average = pDiffBmp->getAvg();
+ float stdDev = pDiffBmp->getStdDev();
+ if (average > maxAverage || stdDev > maxStdDev) {
+ TEST_FAILED("Error: Decoded image differs from baseline '" <<
+ sFName << "'. average=" << average << ", stdDev=" << stdDev);
+ // resultBmp.dump();
+ // baselineBmp.dump();
+ string sResultName = "resultimages/"+sFName;
+ resultBmp.save(sResultName+".png");
+ baselineBmp.save(sResultName+"_baseline.png");
+ BitmapPtr pDiffBmp = resultBmp.subtract(baselineBmp);
+ pDiffBmp->save(sResultName+"_diff.png");
+ }
+ }
+}
+
+void GraphicsTest::testEqualBrightness(Bitmap& resultBmp, Bitmap& baselineBmp,
+ float epsilon)
+{
+ float diff = fabs(resultBmp.getAvg()-baselineBmp.getAvg());
+ if (diff >= epsilon) {
+ TEST_FAILED("Error: Baseline brightness: " << baselineBmp.getAvg()
+ << ", Result brightness: " << resultBmp.getAvg() << ", difference: "
+ << diff);
+ }
+}
+
+int GraphicsTest::sumPixels(Bitmap& bmp)
+{
+ AVG_ASSERT(bmp.getBytesPerPixel() == 4);
+ int sum = 0;
+ IntPoint size = bmp.getSize();
+ for (int y = 0; y < size.y; y++) {
+ unsigned char * pLine = bmp.getPixels()+y*bmp.getStride();
+ for (int x = 0; x < size.x; x++) {
+ sum += pLine[x*4];
+ sum += pLine[x*4+1];
+ sum += pLine[x*4+2];
+ }
+ }
+ return sum;
+}
+
+};
+
diff --git a/src/graphics/GraphicsTest.h b/src/graphics/GraphicsTest.h
new file mode 100644
index 0000000..951bcef
--- /dev/null
+++ b/src/graphics/GraphicsTest.h
@@ -0,0 +1,52 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "../api.h"
+#include "Bitmap.h"
+
+#include "../base/Test.h"
+
+#include <string>
+
+namespace avg {
+
+class AVG_API GraphicsTest: public Test {
+public:
+ GraphicsTest(const std::string& sName, int indentLevel);
+
+ static void createResultImgDir();
+
+protected:
+ BitmapPtr loadTestBmp(const std::string& sFName, PixelFormat pf = NO_PIXELFORMAT);
+ virtual void testEqual(Bitmap& resultBmp, const std::string& sFName,
+ PixelFormat pf = NO_PIXELFORMAT, float maxAverage=0.01f,
+ float maxStdDev=0.05f);
+ virtual void testEqual(Bitmap& resultBmp, Bitmap& baselineBmp,
+ const std::string& sFName, float maxAverage=0.01f, float maxStdDev=0.05f);
+ void testEqualBrightness(Bitmap& resultBmp, Bitmap& baselineBmp, float epsilon);
+
+private:
+ int sumPixels(Bitmap& bmp);
+
+};
+
+
+}
diff --git a/src/graphics/HistoryPreProcessor.cpp b/src/graphics/HistoryPreProcessor.cpp
new file mode 100644
index 0000000..673df90
--- /dev/null
+++ b/src/graphics/HistoryPreProcessor.cpp
@@ -0,0 +1,157 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+// Original author of this file is igor@c-base.org.
+//
+
+#include "HistoryPreProcessor.h"
+
+#include "Bitmap.h"
+#include "Filterfill.h"
+
+#include "../base/Exception.h"
+
+#include <iostream>
+#include <sstream>
+
+using namespace std;
+
+#define FAST_HISTORY_SPEED 16
+
+namespace avg {
+
+HistoryPreProcessor::HistoryPreProcessor(IntPoint dimensions,
+ unsigned int updateInterval, bool bBrighter)
+ : m_FrameCounter(0),
+ m_UpdateInterval(updateInterval),
+ m_bBrighter(bBrighter)
+{
+ m_pHistoryBmp = BitmapPtr(new Bitmap(dimensions, I16));
+ reset();
+}
+
+HistoryPreProcessor::~HistoryPreProcessor()
+{
+}
+
+void HistoryPreProcessor::setInterval(unsigned int updateInterval)
+{
+ m_FrameCounter = 0;
+ m_UpdateInterval = updateInterval;
+}
+
+unsigned int HistoryPreProcessor::getInterval()
+{
+ return m_UpdateInterval;
+}
+
+void HistoryPreProcessor::reset()
+{
+ m_State = NO_IMAGE;
+}
+
+void HistoryPreProcessor::updateHistory(BitmapPtr pNewBmp)
+{
+ AVG_ASSERT(pNewBmp->getSize() == m_pHistoryBmp->getSize());
+ switch (m_State) {
+ case NO_IMAGE:
+ m_pHistoryBmp->copyPixels(*pNewBmp);
+ m_State = INITIALIZING;
+ m_NumInitImages = 0;
+ break;
+ case INITIALIZING:
+ calcAvg<FAST_HISTORY_SPEED>(pNewBmp);
+ m_NumInitImages++;
+ if (m_NumInitImages == FAST_HISTORY_SPEED*2) {
+ m_State = NORMAL;
+ }
+ break;
+ case NORMAL:
+ if (m_FrameCounter < m_UpdateInterval-1) {
+ m_FrameCounter++;
+ } else {
+ m_FrameCounter = 0;
+ calcAvg<256>(pNewBmp);
+ }
+ break;
+ }
+}
+
+void HistoryPreProcessor::applyInPlace(BitmapPtr pBmp)
+{
+ updateHistory(pBmp);
+ unsigned short * pSrc = (unsigned short*)m_pHistoryBmp->getPixels();
+ int srcStride = m_pHistoryBmp->getStride()/m_pHistoryBmp->getBytesPerPixel();
+ int destStride = pBmp->getStride();
+ unsigned char * pDest = pBmp->getPixels();
+ IntPoint size = pBmp->getSize();
+ for (int y = 0; y < size.y; y++) {
+ const unsigned short * pSrcPixel = pSrc;
+ unsigned char * pDestPixel = pDest;
+ if (m_bBrighter) {
+ for (int x = 0; x < size.x; x++) {
+ unsigned char Src = *pSrcPixel/256;
+ if ((*pDestPixel) > Src) {
+ *pDestPixel = *pDestPixel-Src;
+ } else {
+ *pDestPixel = 0;
+ }
+ pDestPixel++;
+ pSrcPixel++;
+ }
+ } else {
+ for (int x = 0; x < size.x; x++) {
+ unsigned char Src = *pSrcPixel/256;
+ if ((*pDestPixel) < Src) {
+ *pDestPixel = Src-*pDestPixel;
+ } else {
+ *pDestPixel = 0;
+ }
+ pDestPixel++;
+ pSrcPixel++;
+ }
+ }
+ pDest += destStride;
+ pSrc += srcStride;
+ }
+}
+
+// Fast pseudo-normalization with an integer factor.
+void HistoryPreProcessor::normalizeHistogram(BitmapPtr pBmp, unsigned char max)
+{
+ if (max < 128) {
+ max = 128;
+ }
+ int factor = int(256.0/max);
+ unsigned char * pLine = pBmp->getPixels();
+ IntPoint size = pBmp->getSize();
+ int stride = pBmp->getStride();
+ for (int y = 0; y < size.y; y++) {
+ unsigned char * pPixel = pLine;
+ for (int x = 0; x < size.x; x++) {
+ *pPixel *= factor;
+ pPixel++;
+ }
+ pLine += stride;
+ }
+}
+
+}
+
diff --git a/src/graphics/HistoryPreProcessor.h b/src/graphics/HistoryPreProcessor.h
new file mode 100644
index 0000000..f56a7a3
--- /dev/null
+++ b/src/graphics/HistoryPreProcessor.h
@@ -0,0 +1,89 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+// Original author of this file is igor@c-base.org.
+//
+
+#ifndef _HistoryPreProcessor_H_
+#define _HistoryPreProcessor_H_
+
+#include "../api.h"
+#include "Filter.h"
+#include "Bitmap.h"
+
+#include <boost/shared_ptr.hpp>
+
+namespace avg {
+
+class AVG_API HistoryPreProcessor: public Filter
+{
+ public:
+ HistoryPreProcessor(IntPoint dimensions, unsigned int updateInterval,
+ bool bBrighter);
+ virtual ~HistoryPreProcessor();
+ virtual void applyInPlace(BitmapPtr pBmp);
+ void setInterval(unsigned int updateInterval);
+ unsigned int getInterval();
+ void reset();
+
+ private:
+ HistoryPreProcessor(const HistoryPreProcessor&) {};
+ void updateHistory(BitmapPtr pNewBmp);
+ void normalizeHistogram(BitmapPtr pBmp, unsigned char Max);
+ template<int SPEED> void calcAvg(BitmapPtr pNewBmp);
+
+ BitmapPtr m_pHistoryBmp;
+ unsigned int m_FrameCounter;
+ unsigned int m_UpdateInterval;
+ typedef enum {NO_IMAGE, INITIALIZING, NORMAL} State;
+ State m_State;
+ int m_NumInitImages;
+ bool m_bBrighter;
+};
+
+template<int SPEED>
+void HistoryPreProcessor::calcAvg(BitmapPtr pNewBmp)
+{
+ const int SRC_NUMERATOR = SPEED-1;
+ const int SRC_DENOMINATOR = SPEED;
+ const int DEST_FACTOR = 256/SPEED;
+ const unsigned char * pSrc = pNewBmp->getPixels();
+ unsigned short * pDest = (unsigned short*)(m_pHistoryBmp->getPixels());
+ int destStride = m_pHistoryBmp->getStride()/m_pHistoryBmp->getBytesPerPixel();
+ IntPoint size = m_pHistoryBmp->getSize();
+ for (int y = 0; y < size.y; y++) {
+ const unsigned char * pSrcPixel = pSrc;
+ unsigned short * pDestPixel = pDest;
+ for (int x = 0; x < size.x; x++) {
+ int t = SRC_NUMERATOR*int(*pDestPixel)/SRC_DENOMINATOR;
+ *pDestPixel = (t) + int(*pSrcPixel)*DEST_FACTOR;
+ pDestPixel++;
+ pSrcPixel++;
+ }
+ pDest += destStride;
+ pSrc += pNewBmp->getStride();
+ }
+
+}
+
+typedef boost::shared_ptr<HistoryPreProcessor> HistoryPreProcessorPtr;
+
+}
+#endif
diff --git a/src/graphics/ImagingProjection.cpp b/src/graphics/ImagingProjection.cpp
new file mode 100644
index 0000000..1ab33b7
--- /dev/null
+++ b/src/graphics/ImagingProjection.cpp
@@ -0,0 +1,91 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "ImagingProjection.h"
+
+#include "GLContext.h"
+#include "OGLShader.h"
+
+#include "../base/Exception.h"
+
+namespace avg {
+
+ImagingProjection::ImagingProjection(IntPoint size)
+ : m_Color(0, 0, 0, 0),
+ m_pVA(new VertexArray)
+{
+ init(size, IntRect(IntPoint(0,0), size));
+}
+
+ImagingProjection::ImagingProjection(IntPoint srcSize, IntRect destRect)
+ : m_Color(0, 0, 0, 0),
+ m_pVA(new VertexArray)
+{
+ init(srcSize, destRect);
+}
+
+ImagingProjection::~ImagingProjection()
+{
+}
+
+void ImagingProjection::setColor(const Pixel32& color)
+{
+ if (color != m_Color) {
+ m_Color = color;
+ init(m_SrcSize, m_DestRect);
+ }
+}
+
+void ImagingProjection::draw(const OGLShaderPtr& pShader)
+{
+ IntPoint destSize = m_DestRect.size();
+ glViewport(0, 0, destSize.x, destSize.y);
+ pShader->setTransform(m_ProjMat);
+ m_pVA->draw();
+}
+
+void ImagingProjection::init(IntPoint srcSize, IntRect destRect)
+{
+ m_SrcSize = srcSize;
+ m_DestRect = destRect;
+ FRect dest = destRect;
+ glm::vec2 p1(dest.tl.x/srcSize.x, dest.tl.y/srcSize.y);
+ glm::vec2 p3(dest.br.x/srcSize.x, dest.br.y/srcSize.y);
+ glm::vec2 p2(p1.x, p3.y);
+ glm::vec2 p4(p3.x, p1.y);
+ m_pVA->reset();
+ m_pVA->appendPos(p1, p1, m_Color);
+ m_pVA->appendPos(p2, p2, m_Color);
+ m_pVA->appendPos(p3, p3, m_Color);
+ m_pVA->appendPos(p4, p4, m_Color);
+ m_pVA->appendQuadIndexes(1,0,2,3);
+
+ IntPoint destSize = m_DestRect.size();
+ glm::mat4 projMat(glm::ortho(0.f, float(destSize.x), 0.f, float(destSize.y)));
+
+ glm::vec3 offset(-m_DestRect.tl.x, -m_DestRect.tl.y, 0);
+ glm::mat4 transform = glm::translate(projMat, offset);
+ glm::vec3 size(m_SrcSize.x, m_SrcSize.y, 1);
+ m_ProjMat = glm::scale(transform, size);
+}
+
+}
+
diff --git a/src/graphics/ImagingProjection.h b/src/graphics/ImagingProjection.h
new file mode 100644
index 0000000..b378bd9
--- /dev/null
+++ b/src/graphics/ImagingProjection.h
@@ -0,0 +1,66 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _ImagingProjection_H_
+#define _ImagingProjection_H_
+
+#include "../api.h"
+
+#include "VertexArray.h"
+#include "GLShaderParam.h"
+
+#include "../base/Rect.h"
+
+namespace avg {
+
+class OGLShader;
+typedef boost::shared_ptr<OGLShader> OGLShaderPtr;
+
+class AVG_API ImagingProjection
+{
+public:
+ ImagingProjection(IntPoint size);
+ ImagingProjection(IntPoint srcSize, IntRect destRect);
+ virtual ~ImagingProjection();
+
+ void setColor(const Pixel32& color);
+ void draw(const OGLShaderPtr& pShader);
+
+private:
+ void init(IntPoint srcSize, IntRect destRect);
+
+ IntPoint m_SrcSize;
+ IntRect m_DestRect;
+ IntPoint m_Offset;
+ Pixel32 m_Color;
+ VertexArrayPtr m_pVA;
+ Mat4fGLShaderParamPtr m_pTransformParam;
+ glm::mat4 m_ProjMat;
+};
+
+typedef boost::shared_ptr<ImagingProjection> ImagingProjectionPtr;
+
+}
+
+
+#endif
+
+
diff --git a/src/graphics/Makefile.am b/src/graphics/Makefile.am
new file mode 100644
index 0000000..62220b3
--- /dev/null
+++ b/src/graphics/Makefile.am
@@ -0,0 +1,95 @@
+SUBDIRS = shaders
+
+AM_CPPFLAGS = -I.. @GL_CFLAGS@ @GDK_PIXBUF_CFLAGS@
+
+if APPLE
+ GL_SOURCES = CGLContext.cpp PBO.cpp AppleDisplay.cpp
+ GL_INCLUDES = CGLContext.h PBO.h AppleDisplay.h
+else
+if ENABLE_RPI
+ GL_SOURCES = EGLContext.cpp BCMDisplay.cpp X11Display.cpp
+ GL_INCLUDES = EGLContext.h BCMDisplay.h X11Display.h
+else
+if ENABLE_EGL
+ GL_SOURCES = EGLContext.cpp X11Display.cpp
+ GL_INCLUDES = EGLContext.h X11Display.h
+else
+ GL_SOURCES = GLXContext.cpp PBO.cpp X11Display.cpp
+ GL_INCLUDES = GLXContext.h PBO.h X11Display.h
+endif
+endif
+endif
+
+ALL_H = Bitmap.h Filter.h GLContext.h GLContextAttribs.h \
+ Pixel32.h Pixel24.h Pixel16.h Pixel8.h Pixeldefs.h PixelFormat.h \
+ Filtercolorize.h Filterfill.h Filterfillrect.h Filterflip.h FilterflipX.h \
+ Filterfliprgb.h Filterflipuv.h Filtergrayscale.h Filter3x3.h \
+ HistoryPreProcessor.h FilterConvol.h FilterHighpass.h \
+ FilterFastBandpass.h Filterfliprgba.h FilterFastDownscale.h \
+ FilterGauss.h FilterBandpass.h FilterBlur.h FilterMask.h \
+ OGLHelper.h OGLShader.h GL/gl.h GL/glext.h GL/glu.h GL/glx.h \
+ VertexArray.h GPUNullFilter.h GPUChromaKeyFilter.h Display.h \
+ GPUBrightnessFilter.h GPUBlurFilter.h GPUShadowFilter.h GraphicsTest.h\
+ GPUFilter.h GPUBandpassFilter.h GPUHueSatFilter.h GPUInvertFilter.h \
+ FilterIntensity.h FilterNormalize.h FilterFloodfill.h FilterDilation.h \
+ FilterErosion.h FilterGetAlpha.h FBO.h GLTexture.h TextureMover.h\
+ ContribDefs.h TwoPassScale.h FilterResizeBilinear.h FilterThreshold.h \
+ FilterResizeGaussian.h FilterUnmultiplyAlpha.h ShaderRegistry.h \
+ ImagingProjection.h GLBufferCache.h GLConfig.h BmpTextureMover.h \
+ GPURGB2YUVFilter.h GLShaderParam.h StandardShader.h SubVertexArray.h \
+ VertexData.h BitmapLoader.h $(GL_INCLUDES)
+ALL_CPP = Bitmap.cpp Filter.cpp Pixel32.cpp Filtergrayscale.cpp PixelFormat.cpp \
+ Filtercolorize.cpp Filterflip.cpp FilterflipX.cpp Filterfliprgb.cpp \
+ Filterflipuv.cpp Filter3x3.cpp HistoryPreProcessor.cpp FilterHighpass.cpp \
+ FilterFastBandpass.cpp Filterfliprgba.cpp FilterFastDownscale.cpp \
+ FilterGauss.cpp FilterBandpass.cpp FilterBlur.cpp FilterMask.cpp \
+ OGLHelper.cpp OGLShader.cpp GPUNullFilter.cpp GPUChromaKeyFilter.cpp \
+ Display.cpp \
+ GPUHueSatFilter.cpp GPUInvertFilter.cpp VertexArray.cpp GLContextAttribs.cpp \
+ GPUBrightnessFilter.cpp GPUBlurFilter.cpp GPUShadowFilter.cpp GraphicsTest.cpp \
+ GPUFilter.cpp GPUBandpassFilter.cpp FilterIntensity.cpp GLContext.cpp \
+ FilterNormalize.cpp FilterDilation.cpp FilterErosion.cpp \
+ FilterGetAlpha.cpp FBO.cpp GLTexture.cpp TextureMover.cpp \
+ FilterResizeBilinear.cpp FilterResizeGaussian.cpp FilterThreshold.cpp \
+ FilterUnmultiplyAlpha.cpp ShaderRegistry.cpp \
+ ImagingProjection.cpp GLBufferCache.cpp GLConfig.cpp BmpTextureMover.cpp \
+ GPURGB2YUVFilter.cpp GLShaderParam.cpp StandardShader.cpp SubVertexArray.cpp \
+ VertexData.cpp BitmapLoader.cpp $(GL_SOURCES)
+
+if APPLE
+ X_LIBS =
+else
+if ENABLE_RPI
+ X_LIBS = -lXxf86vm -lX11 -lGLESv2 -lEGL
+else
+if ENABLE_EGL
+ X_LIBS = -lXxf86vm -lX11 -lGLESv2 -lEGL
+else
+ X_LIBS = -lXxf86vm -lX11
+endif
+endif
+endif
+
+TESTS = testgraphics testgpu
+
+EXTRA_DIST = $(wildcard baseline/*.png)
+
+noinst_LTLIBRARIES = libgraphics.la
+noinst_PROGRAMS = testgraphics testgpu benchmarkgraphics
+libgraphics_la_SOURCES = $(ALL_CPP) $(ALL_H)
+testgraphics_SOURCES = testgraphics.cpp $(ALL_H)
+testgraphics_LDADD = libgraphics.la ../base/libbase.la \
+ ../base/triangulate/libtriangulate.la \
+ @XML2_LIBS@ @BOOST_THREAD_LIBS@ @PTHREAD_LIBS@ $(X_LIBS) @GDK_PIXBUF_LIBS@
+
+benchmarkgraphics_SOURCES = benchmarkgraphics.cpp $(ALL_H)
+benchmarkgraphics_LDADD = libgraphics.la ../base/libbase.la \
+ ../base/triangulate/libtriangulate.la \
+ @XML2_LIBS@ @BOOST_THREAD_LIBS@ @PTHREAD_LIBS@ @GDK_PIXBUF_LIBS@
+
+testgpu_SOURCES = testgpu.cpp $(ALL_H)
+testgpu_LDADD = libgraphics.la ../base/libbase.la -ldl \
+ ../base/triangulate/libtriangulate.la \
+ @XML2_LIBS@ @BOOST_THREAD_LIBS@ @PTHREAD_LIBS@ $(X_LIBS) \
+ @GL_LIBS@ @GLU_LIBS@ @SDL_LIBS@ \
+ @GDK_PIXBUF_LIBS@
diff --git a/src/graphics/OGLHelper.cpp b/src/graphics/OGLHelper.cpp
new file mode 100644
index 0000000..3f8b537
--- /dev/null
+++ b/src/graphics/OGLHelper.cpp
@@ -0,0 +1,440 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "OGLHelper.h"
+
+#include "../base/Logger.h"
+#include "../base/Exception.h"
+
+#include "GLContext.h"
+
+#ifndef _WIN32
+#include <dlfcn.h>
+#endif
+
+#include <cstdio>
+#include <iostream>
+#include <sstream>
+#include <cstring>
+#include <cstdlib>
+#include <assert.h>
+
+#if defined(__APPLE__)
+#include <OpenGL/OpenGL.h>
+#endif
+
+using namespace std;
+
+namespace avg {
+
+namespace glproc {
+#ifndef AVG_ENABLE_EGL
+ PFNGLBUFFERSUBDATAPROC BufferSubData;
+ PFNGLGETBUFFERSUBDATAPROC GetBufferSubData;
+ PFNGLBLITFRAMEBUFFERPROC BlitFramebuffer;
+ PFNGLDRAWBUFFERSPROC DrawBuffers;
+ PFNGLDRAWRANGEELEMENTSPROC DrawRangeElements;
+ PFNGLGETOBJECTPARAMETERIVARBPROC GetObjectParameteriv;
+#endif
+ PFNGLGENBUFFERSPROC GenBuffers;
+ PFNGLBUFFERDATAPROC BufferData;
+ PFNGLDEBUGMESSAGECALLBACKPROC DebugMessageCallback;
+ PFNGLDELETEBUFFERSPROC DeleteBuffers;
+ PFNGLBINDBUFFERPROC BindBuffer;
+ PFNGLMAPBUFFERPROC MapBuffer;
+ PFNGLUNMAPBUFFERPROC UnmapBuffer;
+
+ PFNGLCREATESHADERPROC CreateShader;
+ PFNGLSHADERSOURCEPROC ShaderSource;
+ PFNGLCOMPILESHADERPROC CompileShader;
+ PFNGLCREATEPROGRAMPROC CreateProgram;
+ PFNGLATTACHSHADERPROC AttachShader;
+ PFNGLLINKPROGRAMPROC LinkProgram;
+ PFNGLGETSHADERIVPROC GetShaderiv;
+ PFNGLGETPROGRAMIVPROC GetProgramiv;
+ PFNGLGETSHADERINFOLOGPROC GetShaderInfoLog;
+ PFNGLGETPROGRAMINFOLOGPROC GetProgramInfoLog;
+ PFNGLUSEPROGRAMPROC UseProgram;
+ PFNGLGETUNIFORMLOCATIONPROC GetUniformLocation;
+ PFNGLUNIFORM1IPROC Uniform1i;
+ PFNGLUNIFORM1FPROC Uniform1f;
+ PFNGLUNIFORM2FPROC Uniform2f;
+ PFNGLUNIFORM3FPROC Uniform3f;
+ PFNGLUNIFORM4FPROC Uniform4f;
+ PFNGLUNIFORM1FVPROC Uniform1fv;
+ PFNGLUNIFORMMATRIX4FVPROC UniformMatrix4fv;
+
+ PFNGLBLENDFUNCSEPARATEPROC BlendFuncSeparate;
+ PFNGLBLENDEQUATIONPROC BlendEquation;
+ PFNGLBLENDCOLORPROC BlendColor;
+ PFNGLACTIVETEXTUREPROC ActiveTexture;
+ PFNGLGENERATEMIPMAPPROC GenerateMipmap;
+
+ PFNGLCHECKFRAMEBUFFERSTATUSPROC CheckFramebufferStatus;
+ PFNGLGENFRAMEBUFFERSPROC GenFramebuffers;
+ PFNGLBINDFRAMEBUFFERPROC BindFramebuffer;
+ PFNGLFRAMEBUFFERTEXTURE2DPROC FramebufferTexture2D;
+ PFNGLDELETEFRAMEBUFFERSPROC DeleteFramebuffers;
+ PFNGLGENRENDERBUFFERSPROC GenRenderbuffers;
+ PFNGLBINDRENDERBUFFERPROC BindRenderbuffer;
+ PFNGLRENDERBUFFERSTORAGEPROC RenderbufferStorage;
+ PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC RenderbufferStorageMultisample;
+ PFNGLFRAMEBUFFERRENDERBUFFERPROC FramebufferRenderbuffer;
+ PFNGLDELETERENDERBUFFERSPROC DeleteRenderbuffers;
+ PFNGLVERTEXATTRIBPOINTERPROC VertexAttribPointer;
+ PFNGLENABLEVERTEXATTRIBARRAYPROC EnableVertexAttribArray;
+ PFNGLBINDATTRIBLOCATIONPROC BindAttribLocation;
+#if defined(linux) && !defined(AVG_ENABLE_EGL)
+ PFNGLXSWAPINTERVALEXTPROC SwapIntervalEXT;
+#endif
+#ifdef _WIN32
+ PFNWGLGETEXTENSIONSSTRINGARBPROC GetExtensionsStringARB;
+ PFNWGLGETSWAPINTERVALEXTPROC GetSwapIntervalEXT;
+ PFNWGLSWAPINTERVALEXTPROC SwapIntervalEXT;
+#endif
+
+ void * s_hGLLib = 0;
+}
+
+bool queryOGLExtension(const char *extName)
+{
+ char *p;
+ size_t extNameLen = strlen(extName);
+
+ p = (char *)glGetString(GL_EXTENSIONS);
+ AVG_ASSERT(p != 0);
+ char * end = p + strlen(p);
+ while (p < end) {
+ size_t n = strcspn(p, " ");
+ if ((extNameLen == n) && (strncmp(extName, p, n) == 0)) {
+ return true;
+ }
+ p += (n + 1);
+ }
+ return false;
+}
+
+bool queryGLXExtension(const char *extName)
+{
+#if (defined __APPLE__) || (defined _WIN32) || (defined AVG_ENABLE_EGL)
+ return false;
+#else
+ int extNameLen = strlen(extName);
+
+ Display * display = XOpenDisplay(0);
+ char * p = (char *)glXQueryExtensionsString(display, DefaultScreen(display));
+ if (NULL == p) {
+ throw Exception(AVG_ERR_VIDEO_GENERAL, "Couldn't get GLX extension string.");
+ }
+
+ char * end = p + strlen(p);
+
+ while (p < end) {
+ int n = strcspn(p, " ");
+ if ((extNameLen == n) && (strncmp(extName, p, n) == 0)) {
+// If we close the display connection on some drivers (at least fglrx/Ubuntu 11.04),
+// libavg crashes soon afterwards.
+// XCloseDisplay(display);
+ return true;
+ }
+ p += (n + 1);
+ }
+// XCloseDisplay(display);
+ return false;
+#endif
+}
+
+string AVG_API oglModeToString(int mode)
+{
+ switch (mode) {
+ case GL_ALPHA:
+ return "GL_ALPHA";
+ case GL_RGB:
+ return "GL_RGB";
+ case GL_RGBA:
+ return "GL_RGBA";
+#ifdef AVG_ENABLE_EGL
+ case GL_BGRA_EXT:
+ return "GL_BGRA_EXT";
+#else
+ case GL_BGR:
+ return "GL_BGR";
+ case GL_BGRA:
+ return "GL_BGRA";
+#endif
+ default:
+ return "UNKNOWN";
+ }
+}
+
+#ifdef _WIN32
+#define GL_ALL_CLIENT_ATTRIB_BITS GL_CLIENT_ALL_ATTRIB_BITS
+#endif
+
+string oglMemoryMode2String(OGLMemoryMode mode)
+{
+ switch (mode) {
+ case MM_PBO:
+ return "PBO";
+ case MM_OGL:
+ return "OGL";
+ default:
+ return "invalid gl mem mode";
+ }
+}
+
+void AVG_API clearGLBuffers(GLbitfield mask, bool bOpaque)
+{
+ float alpha;
+ if (bOpaque) {
+ alpha = 1.0;
+ } else {
+ alpha = 0.0;
+ }
+ glClearColor(0.0, 0.0, 0.0, alpha);
+ if (mask & GL_STENCIL_BUFFER_BIT) {
+ glStencilMask(~0);
+ glClearStencil(0);
+ }
+ glClear(mask);
+ GLContext::checkError("clearGLBuffers()");
+ if (mask & GL_STENCIL_BUFFER_BIT) {
+ glStencilMask(0);
+ }
+}
+
+void invalidGLCall()
+{
+ assert(false);
+}
+
+void loadGLLibrary()
+{
+#ifdef _WIN32
+ const char * pszFName = "OPENGL32.DLL";
+ char szErr[512];
+
+ glproc::s_hGLLib = (void *)LoadLibrary(pszFName);
+
+ if (glproc::s_hGLLib == 0) {
+ FormatMessage((FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM),
+ 0, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ szErr, 512, 0);
+ throw Exception(AVG_ERR_VIDEO_GENERAL, string("Loading ") + pszFName + "failed: "
+ + szErr);
+ }
+#else
+#ifdef __APPLE__
+ const char * pszFName = "/System/Library/Frameworks/OpenGL.framework/OpenGL";
+#else
+#ifdef AVG_ENABLE_EGL
+ const char * pszFName = "libGLESv2.so";
+#else
+ const char * pszFName = "libGL.so.1";
+#endif
+#endif
+ glproc::s_hGLLib = dlopen(pszFName, RTLD_NOW);
+ if (glproc::s_hGLLib == 0) {
+ const char * pszErr = (char *)dlerror();
+ throw Exception(AVG_ERR_VIDEO_GENERAL, string("Loading ") + pszFName + "failed: "
+ + pszErr);
+ }
+#endif
+}
+
+GLfunction getProcAddress(const string& sName)
+{
+ AVG_ASSERT(glproc::s_hGLLib);
+#ifdef _WIN32
+ GLfunction pProc = (GLfunction)wglGetProcAddress(sName.c_str());
+/*
+ if (!pProc) {
+ char szErr[512];
+ FormatMessage((FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM),
+ 0, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ szErr, 512, 0);
+ throw Exception(AVG_ERR_VIDEO_GENERAL,
+ string("wglGetProcAddress("+sName+") failed: ") + szErr);
+ }
+*/
+#else
+ GLfunction pProc = (GLfunction)dlsym(glproc::s_hGLLib, sName.c_str());
+ if (!pProc) {
+ // If the name didn't work, try using an underscore :-).
+ string sName_ = string("_")+sName;
+ pProc = (GLfunction)dlsym(glproc::s_hGLLib, sName_.c_str());
+ }
+#endif
+ return(pProc);
+}
+
+GLfunction getFuzzyProcAddress(const char * psz)
+{
+ GLfunction pProc = getProcAddress(psz);
+ if (!pProc) {
+ string s = string(psz)+"EXT";
+ pProc = getProcAddress(s);
+ }
+ if (!pProc) {
+ string s = string(psz)+"ARB";
+ pProc = getProcAddress(s);
+ }
+ if (!pProc) {
+ string s = string(psz)+"OES";
+ pProc = getProcAddress(s);
+ }
+ if (!pProc) {
+ pProc = invalidGLCall;
+ }
+ return pProc;
+}
+
+#if defined(linux) && !defined(AVG_ENABLE_EGL)
+GLfunction getglXProcAddress(const char * psz)
+{
+ GLfunction pProc = (GLfunction)glXGetProcAddress((const GLubyte *)psz);
+ if (!pProc) {
+ pProc = invalidGLCall;
+ }
+ return pProc;
+}
+#endif
+
+#ifdef _WIN32
+GLfunction getwglProcAddress(const char * psz)
+{
+ GLfunction pProc = (GLfunction)wglGetProcAddress((LPCSTR)psz);
+ if (!pProc) {
+ pProc = invalidGLCall;
+ }
+ return pProc;
+}
+#endif
+
+namespace glproc {
+
+ void init() {
+ static bool s_bInitialized = false;
+ if (s_bInitialized) {
+ return;
+ }
+ s_bInitialized = true;
+ loadGLLibrary();
+
+ GenBuffers = (PFNGLGENBUFFERSPROC)getFuzzyProcAddress("glGenBuffers");
+ BufferData = (PFNGLBUFFERDATAPROC)getFuzzyProcAddress("glBufferData");
+ DeleteBuffers = (PFNGLDELETEBUFFERSPROC)getFuzzyProcAddress("glDeleteBuffers");
+ BindBuffer = (PFNGLBINDBUFFERPROC)getFuzzyProcAddress("glBindBuffer");
+ MapBuffer = (PFNGLMAPBUFFERPROC)getFuzzyProcAddress("glMapBuffer");
+ UnmapBuffer = (PFNGLUNMAPBUFFERPROC)getFuzzyProcAddress("glUnmapBuffer");
+
+ CreateShader = (PFNGLCREATESHADERPROC)getFuzzyProcAddress("glCreateShader");
+ ShaderSource = (PFNGLSHADERSOURCEPROC)getFuzzyProcAddress("glShaderSource");
+ CompileShader = (PFNGLCOMPILESHADERPROC)getFuzzyProcAddress("glCompileShader");
+ CreateProgram= (PFNGLCREATEPROGRAMPROC)getFuzzyProcAddress("glCreateProgram");
+ AttachShader = (PFNGLATTACHSHADERPROC)getFuzzyProcAddress("glAttachShader");
+ LinkProgram = (PFNGLLINKPROGRAMPROC)getFuzzyProcAddress("glLinkProgram");
+ GetShaderiv = (PFNGLGETSHADERIVPROC)getFuzzyProcAddress("glGetShaderiv");
+ GetProgramiv = (PFNGLGETPROGRAMIVPROC)getFuzzyProcAddress("glGetProgramiv");
+ GetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC)
+ getFuzzyProcAddress("glGetShaderInfoLog");
+ GetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC)
+ getFuzzyProcAddress("glGetProgramInfoLog");
+ UseProgram =(PFNGLUSEPROGRAMPROC) getFuzzyProcAddress("glUseProgram");
+ GetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC)
+ getFuzzyProcAddress("glGetUniformLocation");
+ Uniform1i = (PFNGLUNIFORM1IPROC)getFuzzyProcAddress("glUniform1i");
+ Uniform1f = (PFNGLUNIFORM1FPROC)getFuzzyProcAddress("glUniform1f");
+ Uniform2f = (PFNGLUNIFORM2FPROC)getFuzzyProcAddress("glUniform2f");
+ Uniform3f = (PFNGLUNIFORM3FPROC)getFuzzyProcAddress("glUniform3f");
+ Uniform4f = (PFNGLUNIFORM4FPROC)getFuzzyProcAddress("glUniform4f");
+ Uniform1fv = (PFNGLUNIFORM1FVPROC)getFuzzyProcAddress("glUniform1fv");
+ UniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC)
+ getFuzzyProcAddress("glUniformMatrix4fv");
+
+ BlendFuncSeparate = (PFNGLBLENDFUNCSEPARATEPROC)
+ getFuzzyProcAddress("glBlendFuncSeparate");
+ BlendEquation = (PFNGLBLENDEQUATIONPROC)getFuzzyProcAddress("glBlendEquation");
+ BlendColor = (PFNGLBLENDCOLORPROC)getFuzzyProcAddress("glBlendColor");
+ ActiveTexture = (PFNGLACTIVETEXTUREPROC)getFuzzyProcAddress("glActiveTexture");
+ GenerateMipmap = (PFNGLGENERATEMIPMAPPROC)getFuzzyProcAddress
+ ("glGenerateMipmap");
+
+ CheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC)
+ getFuzzyProcAddress("glCheckFramebufferStatus");
+ GenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC)
+ getFuzzyProcAddress("glGenFramebuffers");
+ BindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC)
+ getFuzzyProcAddress("glBindFramebuffer");
+ FramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC)
+ getFuzzyProcAddress("glFramebufferTexture2D");
+ DeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC)
+ getFuzzyProcAddress("glDeleteFramebuffers");
+ GenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC)
+ getFuzzyProcAddress("glGenRenderbuffers");
+ BindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC)
+ getFuzzyProcAddress("glBindRenderbuffer");
+ RenderbufferStorage= (PFNGLRENDERBUFFERSTORAGEPROC)
+ getFuzzyProcAddress("glRenderbufferStorage");
+ RenderbufferStorageMultisample = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC)
+ getFuzzyProcAddress("glRenderbufferStorageMultisample");
+ FramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC)
+ getFuzzyProcAddress("glFramebufferRenderbuffer");
+
+ DeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC)
+ getFuzzyProcAddress("glDeleteRenderbuffers");
+#ifndef AVG_ENABLE_EGL
+ BufferSubData = (PFNGLBUFFERSUBDATAPROC)getFuzzyProcAddress("glBufferSubData");
+ GetBufferSubData = (PFNGLGETBUFFERSUBDATAPROC)getFuzzyProcAddress
+ ("glGetBufferSubData");
+ GetObjectParameteriv = (PFNGLGETOBJECTPARAMETERIVARBPROC)
+ getFuzzyProcAddress("glGetObjectParameteriv");
+
+ BlitFramebuffer = (PFNGLBLITFRAMEBUFFERPROC)
+ getFuzzyProcAddress("glBlitFramebuffer");
+ DrawBuffers = (PFNGLDRAWBUFFERSPROC)getFuzzyProcAddress("glDrawBuffers");
+ DrawRangeElements = (PFNGLDRAWRANGEELEMENTSPROC)
+ getFuzzyProcAddress("glDrawRangeElements");
+ DebugMessageCallback = (PFNGLDEBUGMESSAGECALLBACKARBPROC)
+ getFuzzyProcAddress("glDebugMessageCallback");
+#endif
+ VertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC)
+ getFuzzyProcAddress("glVertexAttribPointer");
+ EnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC)
+ getFuzzyProcAddress("glEnableVertexAttribArray");
+ BindAttribLocation = (PFNGLBINDATTRIBLOCATIONPROC)
+ getFuzzyProcAddress("glBindAttribLocation");
+#if defined(linux) && !defined(AVG_ENABLE_EGL)
+ SwapIntervalEXT = (PFNGLXSWAPINTERVALEXTPROC)
+ getglXProcAddress("glXSwapIntervalEXT");
+#endif
+#ifdef _WIN32
+ GetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)
+ getwglProcAddress("wglGetExtensionsStringARB");
+ GetSwapIntervalEXT = (PFNWGLGETSWAPINTERVALEXTPROC)
+ getwglProcAddress("wglGetSwapIntervalEXT");
+ SwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)
+ getwglProcAddress("wglSwapIntervalEXT");
+#endif
+ }
+}
+
+}
diff --git a/src/graphics/OGLHelper.h b/src/graphics/OGLHelper.h
new file mode 100644
index 0000000..25531d6
--- /dev/null
+++ b/src/graphics/OGLHelper.h
@@ -0,0 +1,253 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _OGLHelper_H_
+#define _OGLHelper_H_
+
+#include "../api.h"
+#include "../avgconfigwrapper.h"
+
+#ifdef _WIN32
+ #include <windows.h>
+ #undef ERROR
+ #undef WARNING
+ #include <GL/gl.h>
+ #include <GL/glu.h>
+ #include "GL/glext.h"
+ #include "GL/wglext.h"
+#else
+ #ifdef AVG_ENABLE_EGL
+ #define EGL_EGLEXT_PROTOTYPES
+ #include <EGL/egl.h>
+ #include <GLES2/gl2.h>
+ #include <GLES2/gl2ext.h>
+ #else
+ #include "GL/gl.h"
+ #include "GL/glu.h"
+ #include "GL/glext.h"
+ #endif
+#endif
+#if defined(linux) && !defined(AVG_ENABLE_EGL)
+ #define GLX_GLXEXT_PROTOTYPES
+ #ifndef __GLXextFuncPtr
+ typedef void (*__GLXextFuncPtr)(void);
+ #endif
+ #include "GL/glx.h"
+#endif
+
+#ifdef linux
+ #ifndef GLX_CONTEXT_ES2_PROFILE_BIT_EXT
+ #define GLX_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004
+ #endif
+#endif
+
+// For NVX_gpu_memory_info
+#ifndef GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX
+ #define GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX 0x9047
+ #define GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX 0x9048
+ #define GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX 0x9049
+ #define GPU_MEMORY_INFO_EVICTION_COUNT_NVX 0x904A
+ #define GPU_MEMORY_INFO_EVICTED_MEMORY_NVX 0x904B
+#endif
+
+#include <string>
+
+#ifndef APIENTRY
+#define APIENTRY
+#endif
+
+namespace avg {
+
+bool AVG_API queryOGLExtension(const char* extName);
+bool AVG_API queryGLXExtension(const char* extName);
+std::string AVG_API oglModeToString(int mode);
+
+enum OGLMemoryMode {
+ MM_OGL, // Standard OpenGL
+ MM_PBO // pixel buffer objects
+};
+
+std::string oglMemoryMode2String(OGLMemoryMode mode);
+
+void AVG_API clearGLBuffers(GLbitfield mask, bool bOpaque);
+
+typedef void (*GLfunction)();
+GLfunction AVG_API getFuzzyProcAddress(const char * psz);
+#ifdef linux
+GLfunction getglXProcAddress(const char * psz);
+#endif
+
+#ifdef AVG_ENABLE_EGL
+#define GL_WRITE_ONLY GL_WRITE_ONLY_OES
+#define GL_DYNAMIC_READ 0x88E9
+#define GL_BGRA 0x80E1
+
+typedef void (GL_APIENTRYP PFNGLGENBUFFERSPROC) (GLsizei n, GLuint *buffers);
+typedef void (GL_APIENTRYP PFNGLBUFFERDATAPROC) (GLenum target, GLsizeiptr size,
+ const GLvoid* data, GLenum usage);
+typedef void (APIENTRY* DEBUGCALLBACKPROC) (GLenum source, GLenum type, GLuint id,
+ GLenum severity, GLsizei length, const GLchar* message, GLvoid* userParam);
+typedef void (GL_APIENTRYP PFNGLDEBUGMESSAGECALLBACKPROC) (DEBUGCALLBACKPROC callback,
+ void* userParam);
+typedef void (GL_APIENTRYP PFNGLDELETEBUFFERSPROC) (GLsizei n, const GLuint* buffers);
+typedef void (GL_APIENTRYP PFNGLBINDBUFFERPROC) (GLenum target, GLuint buffer);
+typedef void* (GL_APIENTRYP PFNGLMAPBUFFERPROC) (GLenum target, GLenum access);
+typedef GLboolean (GL_APIENTRYP PFNGLUNMAPBUFFERPROC) (GLenum target);
+typedef GLuint (GL_APIENTRYP PFNGLCREATESHADERPROC) (GLenum type);
+typedef void (GL_APIENTRYP PFNGLSHADERSOURCEPROC) (GLuint shader, GLsizei count,
+ const GLchar** string, const GLint* length);
+typedef void (GL_APIENTRYP PFNGLCOMPILESHADERPROC) (GLuint shader);
+typedef GLuint (GL_APIENTRYP PFNGLCREATEPROGRAMPROC) (void);
+typedef void (GL_APIENTRYP PFNGLATTACHSHADERPROC) (GLuint program, GLuint shader);
+typedef void (GL_APIENTRYP PFNGLLINKPROGRAMPROC) (GLuint program);
+typedef void (GL_APIENTRYP PFNGLGETSHADERIVPROC) (GLuint shader, GLenum pname,
+ GLint* params);
+typedef void (GL_APIENTRYP PFNGLGETPROGRAMIVPROC) (GLuint program, GLenum pname,
+ GLint* params);
+typedef void (GL_APIENTRYP PFNGLGETSHADERINFOLOGPROC) (GLuint shader, GLsizei bufsize,
+ GLsizei* length, GLchar* infolog);
+typedef void (GL_APIENTRYP PFNGLGETPROGRAMINFOLOGPROC) (GLuint shader, GLsizei bufsize,
+ GLsizei* length, GLchar* infolog);
+typedef void (GL_APIENTRYP PFNGLUSEPROGRAMPROC) (GLuint program);
+typedef int (GL_APIENTRYP PFNGLGETUNIFORMLOCATIONPROC) (GLuint program,
+ const GLchar* name);
+typedef void (GL_APIENTRYP PFNGLUNIFORM1IPROC) (GLint location, GLint x);
+typedef void (GL_APIENTRYP PFNGLUNIFORM1FPROC) (GLint location, GLfloat x);
+typedef void (GL_APIENTRYP PFNGLUNIFORM2FPROC) (GLint location, GLfloat x, GLfloat y);
+typedef void (GL_APIENTRYP PFNGLUNIFORM3FPROC) (GLint location, GLfloat x, GLfloat y,
+ GLfloat z);
+typedef void (GL_APIENTRYP PFNGLUNIFORM4FPROC) (GLint location, GLfloat x, GLfloat y,
+ GLfloat z, GLfloat w);
+typedef void (GL_APIENTRYP PFNGLUNIFORM1FVPROC) (GLint location, GLsizei count,
+ const GLfloat* v);
+typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX4FVPROC) (GLint location, GLsizei count,
+ GLboolean transpose, const GLfloat* value);
+typedef void (GL_APIENTRYP PFNGLBLENDFUNCSEPARATEPROC) (GLenum srcRGB, GLenum dstRGB,
+ GLenum srcAlpha, GLenum dstAlpha);
+typedef void (GL_APIENTRYP PFNGLBLENDEQUATIONPROC) ( GLenum mode );
+typedef void (GL_APIENTRYP PFNGLBLENDCOLORPROC) (GLclampf red, GLclampf green,
+ GLclampf blue, GLclampf alpha);
+typedef void (GL_APIENTRYP PFNGLACTIVETEXTUREPROC) (GLenum texture);
+typedef void (GL_APIENTRYP PFNGLGENERATEMIPMAPPROC) (GLenum target);
+typedef GLenum (GL_APIENTRYP PFNGLCHECKFRAMEBUFFERSTATUSPROC) (GLenum target);
+typedef void (GL_APIENTRYP PFNGLGENFRAMEBUFFERSPROC) (GLsizei n, GLuint* framebuffers);
+typedef void (GL_APIENTRYP PFNGLBINDFRAMEBUFFERPROC) (GLenum target, GLuint framebuffer);
+typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DPROC) (GLenum target,
+ GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+typedef void (GL_APIENTRYP PFNGLDELETEFRAMEBUFFERSPROC) (GLsizei n,
+ const GLuint* framebuffers);
+typedef void (GL_APIENTRYP PFNGLGENRENDERBUFFERSPROC) (GLsizei n, GLuint* renderbuffers);
+typedef void (GL_APIENTRYP PFNGLBINDRENDERBUFFERPROC) (GLenum target,
+ GLuint renderbuffer);
+typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEPROC) (GLenum target,
+ GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC) (GLenum target,
+ GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERRENDERBUFFERPROC) (GLenum target,
+ GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+//TODO: BLITFRAMEBUFFER
+typedef void (GL_APIENTRYP PFNGLDELETERENDERBUFFERSPROC) (GLsizei n,
+ const GLuint* renderbuffers);
+typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBPOINTERPROC) (GLuint indx, GLint size,
+ GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr);
+typedef void (GL_APIENTRYP PFNGLENABLEVERTEXATTRIBARRAYPROC) (GLuint index);
+typedef void (GL_APIENTRYP PFNGLBINDATTRIBLOCATIONPROC) (GLuint program, GLuint index,
+ const GLchar* name);
+#else
+#define PFNGLDEBUGMESSAGECALLBACKPROC PFNGLDEBUGMESSAGECALLBACKARBPROC
+#endif
+
+namespace glproc {
+ extern AVG_API PFNGLGENBUFFERSPROC GenBuffers;
+ extern AVG_API PFNGLBUFFERDATAPROC BufferData;
+#ifndef AVG_ENABLE_EGL
+ extern AVG_API PFNGLBUFFERSUBDATAPROC BufferSubData;
+ extern AVG_API PFNGLGETBUFFERSUBDATAPROC GetBufferSubData;
+ extern AVG_API PFNGLDRAWBUFFERSPROC DrawBuffers;
+ extern AVG_API PFNGLDRAWRANGEELEMENTSPROC DrawRangeElements;
+ extern AVG_API PFNGLBLITFRAMEBUFFERPROC BlitFramebuffer;
+ extern AVG_API PFNGLGETOBJECTPARAMETERIVARBPROC GetObjectParameteriv;
+#endif
+ extern AVG_API PFNGLDEBUGMESSAGECALLBACKPROC DebugMessageCallback;
+ extern AVG_API PFNGLDELETEBUFFERSPROC DeleteBuffers;
+ extern AVG_API PFNGLBINDBUFFERPROC BindBuffer;
+ extern AVG_API PFNGLMAPBUFFERPROC MapBuffer;
+ extern AVG_API PFNGLUNMAPBUFFERPROC UnmapBuffer;
+
+ extern AVG_API PFNGLCREATESHADERPROC CreateShader;
+ extern AVG_API PFNGLSHADERSOURCEPROC ShaderSource;
+ extern AVG_API PFNGLCOMPILESHADERPROC CompileShader;
+ extern AVG_API PFNGLCREATEPROGRAMPROC CreateProgram;
+ extern AVG_API PFNGLATTACHSHADERPROC AttachShader;
+ extern AVG_API PFNGLLINKPROGRAMPROC LinkProgram;
+ extern AVG_API PFNGLGETSHADERIVPROC GetShaderiv;
+ extern AVG_API PFNGLGETPROGRAMIVPROC GetProgramiv;
+ extern AVG_API PFNGLGETSHADERINFOLOGPROC GetShaderInfoLog;
+ extern AVG_API PFNGLGETPROGRAMINFOLOGPROC GetProgramInfoLog;
+ extern AVG_API PFNGLUSEPROGRAMPROC UseProgram;
+ extern AVG_API PFNGLGETUNIFORMLOCATIONPROC GetUniformLocation;
+ extern AVG_API PFNGLUNIFORM1IPROC Uniform1i;
+ extern AVG_API PFNGLUNIFORM1FPROC Uniform1f;
+ extern AVG_API PFNGLUNIFORM2FPROC Uniform2f;
+ extern AVG_API PFNGLUNIFORM3FPROC Uniform3f;
+ extern AVG_API PFNGLUNIFORM4FPROC Uniform4f;
+ extern AVG_API PFNGLUNIFORM1FVPROC Uniform1fv;
+ extern AVG_API PFNGLUNIFORMMATRIX4FVPROC UniformMatrix4fv;
+
+ extern AVG_API PFNGLBLENDFUNCSEPARATEPROC BlendFuncSeparate;
+ extern AVG_API PFNGLBLENDEQUATIONPROC BlendEquation;
+ extern AVG_API PFNGLBLENDCOLORPROC BlendColor;
+ extern AVG_API PFNGLACTIVETEXTUREPROC ActiveTexture;
+ extern AVG_API PFNGLGENERATEMIPMAPPROC GenerateMipmap;
+
+ extern AVG_API PFNGLCHECKFRAMEBUFFERSTATUSPROC CheckFramebufferStatus;
+ extern AVG_API PFNGLGENFRAMEBUFFERSPROC GenFramebuffers;
+ extern AVG_API PFNGLBINDFRAMEBUFFERPROC BindFramebuffer;
+ extern AVG_API PFNGLFRAMEBUFFERTEXTURE2DPROC FramebufferTexture2D;
+ extern AVG_API PFNGLDELETEFRAMEBUFFERSPROC DeleteFramebuffers;
+ extern AVG_API PFNGLGENRENDERBUFFERSPROC GenRenderbuffers;
+ extern AVG_API PFNGLBINDRENDERBUFFERPROC BindRenderbuffer;
+ extern AVG_API PFNGLRENDERBUFFERSTORAGEPROC RenderbufferStorage;
+ extern AVG_API PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC
+ RenderbufferStorageMultisample;
+ extern AVG_API PFNGLFRAMEBUFFERRENDERBUFFERPROC FramebufferRenderbuffer;
+ extern AVG_API PFNGLDELETERENDERBUFFERSPROC DeleteRenderbuffers;
+
+ extern AVG_API PFNGLVERTEXATTRIBPOINTERPROC VertexAttribPointer;
+ extern AVG_API PFNGLENABLEVERTEXATTRIBARRAYPROC EnableVertexAttribArray;
+ extern AVG_API PFNGLBINDATTRIBLOCATIONPROC BindAttribLocation;
+#if defined(linux) && !defined(AVG_ENABLE_EGL)
+ extern PFNGLXSWAPINTERVALEXTPROC SwapIntervalEXT;
+#endif
+#ifdef _WIN32
+ extern AVG_API PFNWGLGETEXTENSIONSSTRINGARBPROC GetExtensionsStringARB;
+ extern AVG_API PFNWGLGETSWAPINTERVALEXTPROC GetSwapIntervalEXT;
+ extern AVG_API PFNWGLSWAPINTERVALEXTPROC SwapIntervalEXT;
+#endif
+ void init();
+
+ extern void * s_hGLLib;
+}
+
+}
+
+#endif
+
diff --git a/src/graphics/OGLShader.cpp b/src/graphics/OGLShader.cpp
new file mode 100644
index 0000000..3abc40d
--- /dev/null
+++ b/src/graphics/OGLShader.cpp
@@ -0,0 +1,206 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "OGLShader.h"
+#include "ShaderRegistry.h"
+
+#include "../base/Logger.h"
+#include "../base/Exception.h"
+#include "../base/OSHelper.h"
+
+#include "../graphics/VertexArray.h"
+
+#include <iostream>
+#include <sstream>
+
+using namespace std;
+
+namespace avg {
+
+OGLShader::OGLShader(const string& sName, const string& sVertProgram,
+ const string& sFragProgram, const string& sVertPrefix, const string& sFragPrefix)
+ : m_sName(sName),
+ m_sVertProgram(sVertProgram),
+ m_sFragProgram(sFragProgram)
+{
+ m_hProgram = glproc::CreateProgram();
+ if (sVertProgram == "") {
+ m_hVertexShader = 0;
+ } else {
+ glproc::BindAttribLocation(m_hProgram, VertexArray::TEX_INDEX, "a_TexCoord");
+ glproc::BindAttribLocation(m_hProgram, VertexArray::COLOR_INDEX, "a_Color");
+ glproc::BindAttribLocation(m_hProgram, VertexArray::POS_INDEX, "a_Pos");
+ m_hVertexShader = compileShader(GL_VERTEX_SHADER, sVertProgram, sVertPrefix);
+ glproc::AttachShader(m_hProgram, m_hVertexShader);
+ }
+ m_hFragmentShader = compileShader(GL_FRAGMENT_SHADER, sFragProgram, sFragPrefix);
+
+ glproc::AttachShader(m_hProgram, m_hFragmentShader);
+ glproc::LinkProgram(m_hProgram);
+ GLContext::checkError("OGLShader::OGLShader: glLinkProgram()");
+
+ GLint bLinked;
+ glproc::GetProgramiv(m_hProgram, GL_LINK_STATUS, &bLinked);
+ if (!bLinked) {
+ AVG_LOG_ERROR("Linking shader program '"+sName+"' failed. Aborting.");
+ dumpInfoLog(m_hVertexShader, Logger::severity::ERROR);
+ dumpInfoLog(m_hFragmentShader, Logger::severity::ERROR);
+ dumpInfoLog(m_hProgram, Logger::severity::ERROR, true);
+ exit(-1);
+ } else {
+ AVG_TRACE(Logger::category::SHADER, Logger::severity::INFO,
+ "Linking shader program '"+sName+"'.");
+ dumpInfoLog(m_hVertexShader, Logger::severity::INFO);
+ dumpInfoLog(m_hFragmentShader, Logger::severity::INFO);
+ dumpInfoLog(m_hProgram, Logger::severity::INFO, true);
+ }
+ m_pShaderRegistry = &*ShaderRegistry::get();
+ if (m_hVertexShader) {
+ m_pTransformParam = getParam<glm::mat4>("transform");
+ }
+}
+
+OGLShader::~OGLShader()
+{
+}
+
+bool isMountainLion()
+{
+#ifdef __APPLE__
+ return getOSXMajorVersion() >= 12;
+#else
+ return false;
+#endif
+}
+
+void OGLShader::activate()
+{
+ // If we're running on OS X mountain lion, we need to disable shader activation
+ // caching (See bug #355).
+ OGLShaderPtr pCurShader = m_pShaderRegistry->getCurShader();
+ if (isMountainLion() || !pCurShader || &*pCurShader != this) {
+ glproc::UseProgram(m_hProgram);
+ m_pShaderRegistry->setCurShader(m_sName);
+ GLContext::checkError("OGLShader::activate: glUseProgram()");
+ }
+}
+
+GLuint OGLShader::getProgram()
+{
+ return m_hProgram;
+}
+
+const std::string OGLShader::getName() const
+{
+ return m_sName;
+}
+
+void OGLShader::setTransform(const glm::mat4& transform)
+{
+ if (m_hVertexShader) {
+ m_pTransformParam->set(transform);
+ } else {
+#ifdef AVG_ENABLE_EGL
+ // No fixed-function vertex shader in gles
+ AVG_ASSERT(false);
+#else
+ glLoadMatrixf(glm::value_ptr(transform));
+#endif
+ }
+}
+
+GLuint OGLShader::compileShader(GLenum shaderType, const std::string& sProgram,
+ const std::string& sPrefix)
+{
+ const char * pProgramStrs[2];
+ pProgramStrs[0] = sPrefix.c_str();
+ pProgramStrs[1] = sProgram.c_str();
+ GLuint hShader = glproc::CreateShader(shaderType);
+ glproc::ShaderSource(hShader, 2, pProgramStrs, 0);
+ glproc::CompileShader(hShader);
+ GLContext::checkError("OGLShader::compileShader()");
+ return hShader;
+}
+
+bool OGLShader::findParam(const std::string& sName, unsigned& pos)
+{
+ GLShaderParamPtr pParam;
+ bool bFound = false;
+ pos = 0;
+ while (!bFound && pos<m_pParams.size() && m_pParams[pos]->getName() <= sName) {
+ if (m_pParams[pos]->getName() == sName) {
+ bFound = true;
+ } else {
+ ++pos;
+ }
+ }
+ return bFound;
+}
+
+void OGLShader::dumpInfoLog(GLuint hObj, long level, bool bIsProgram)
+{
+ int infoLogLength;
+ GLchar * pInfoLog;
+
+ if (!hObj) {
+ return;
+ }
+
+ if (bIsProgram) {
+ glproc::GetProgramiv(hObj, GL_INFO_LOG_LENGTH, &infoLogLength);
+ } else {
+ glproc::GetShaderiv(hObj, GL_INFO_LOG_LENGTH, &infoLogLength);
+ }
+ GLContext::checkError("OGLShader::dumpInfoLog: glGetShaderiv()");
+ if (infoLogLength > 1) {
+ pInfoLog = (GLchar*)malloc(infoLogLength);
+ int charsWritten;
+ if (bIsProgram) {
+ glproc::GetProgramInfoLog(hObj, infoLogLength, &charsWritten, pInfoLog);
+ } else {
+ glproc::GetShaderInfoLog(hObj, infoLogLength, &charsWritten, pInfoLog);
+ }
+ string sLog = removeATIInfoLogSpam(pInfoLog);
+ GLContext::checkError("OGLShader::dumpInfoLog: glGetShaderInfoLog()");
+ if (sLog.size() > 3) {
+ AVG_TRACE(Logger::category::SHADER, level, sLog);
+ }
+ free(pInfoLog);
+ }
+}
+
+string OGLShader::removeATIInfoLogSpam(const string& sOrigLog)
+{
+ istringstream stream(sOrigLog);
+ string sLog;
+ string sCurLine;
+ while(getline(stream, sCurLine)) {
+ bool bLineBroken = (sCurLine.find(
+ "shader was successfully compiled to run on hardware.") != string::npos)
+ || (sCurLine.find("shader(s) linked.") != string::npos);
+ if (!bLineBroken) {
+ sLog.append(sCurLine+"\n");
+ }
+ }
+ return sLog;
+}
+
+}
diff --git a/src/graphics/OGLShader.h b/src/graphics/OGLShader.h
new file mode 100644
index 0000000..9167f03
--- /dev/null
+++ b/src/graphics/OGLShader.h
@@ -0,0 +1,101 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _OGLShader_H_
+#define _OGLShader_H_
+
+#include "../api.h"
+#include "OGLHelper.h"
+#include "GLShaderParam.h"
+#include "Pixel32.h"
+
+#include "../base/GLMHelper.h"
+
+#include <boost/shared_ptr.hpp>
+
+#include <string>
+#include <vector>
+
+namespace avg {
+
+class ShaderRegistry;
+typedef boost::shared_ptr<ShaderRegistry> ShaderRegistryPtr;
+
+class AVG_API OGLShader {
+ public:
+ virtual ~OGLShader();
+
+ void activate();
+ GLuint getProgram();
+ const std::string getName() const;
+
+ void setTransform(const glm::mat4& transform);
+
+ template<class VAL_TYPE>
+ boost::shared_ptr<GLShaderParamTemplate<VAL_TYPE> > getParam(
+ const std::string& sName)
+ {
+ unsigned pos;
+ bool bFound = findParam(sName, pos);
+ GLShaderParamPtr pParam;
+ if (bFound) {
+ pParam = m_pParams[pos];
+ } else {
+ pParam = GLShaderParamPtr(
+ new GLShaderParamTemplate<VAL_TYPE>(this, sName));
+ m_pParams.insert(m_pParams.begin()+pos, pParam);
+ }
+ return boost::dynamic_pointer_cast<
+ GLShaderParamTemplate<VAL_TYPE> >(pParam);
+ }
+
+ private:
+ OGLShader(const std::string& sName, const std::string& sVertProgram,
+ const std::string& sFragProgram, const std::string& sVertPrefix,
+ const std::string& sFragPrefix);
+ friend class ShaderRegistry;
+
+ GLuint compileShader(GLenum shaderType, const std::string& sProgram,
+ const std::string& sPrefix);
+ bool findParam(const std::string& sName, unsigned& pos);
+ void dumpInfoLog(GLuint hObj, long severity, bool bIsProgram=false);
+ std::string removeATIInfoLogSpam(const std::string& sLog);
+
+ std::string m_sName;
+ GLuint m_hVertexShader;
+ GLuint m_hFragmentShader;
+ GLuint m_hProgram;
+ std::string m_sVertProgram;
+ std::string m_sFragProgram;
+
+ std::vector<GLShaderParamPtr> m_pParams;
+ Mat4fGLShaderParamPtr m_pTransformParam;
+
+ // Dumb pointer for speed reasons.
+ ShaderRegistry* m_pShaderRegistry;
+};
+
+typedef boost::shared_ptr<OGLShader> OGLShaderPtr;
+
+}
+
+#endif
+
diff --git a/src/graphics/PBO.cpp b/src/graphics/PBO.cpp
new file mode 100644
index 0000000..64967de
--- /dev/null
+++ b/src/graphics/PBO.cpp
@@ -0,0 +1,245 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "PBO.h"
+#include "GLContext.h"
+
+#include "../base/Logger.h"
+#include "../base/Exception.h"
+#include "../base/ObjectCounter.h"
+
+#include <iostream>
+#include <cstring>
+
+using namespace std;
+using namespace boost;
+
+namespace avg {
+
+PBO::PBO(const IntPoint& size, PixelFormat pf, unsigned usage)
+ : TextureMover(size, pf),
+ m_Usage(usage)
+{
+ ObjectCounter::get()->incRef(&typeid(*this));
+ m_PBOID = GLContext::getCurrent()->getPBOCache().getBuffer();
+
+ unsigned target = getTarget();
+ glproc::BindBuffer(target, m_PBOID);
+ GLContext::checkError("PBO: BindBuffer()");
+ glproc::BufferData(target, getMemNeeded(), 0, usage);
+ GLContext::checkError("PBO: BufferData()");
+ glproc::BindBuffer(target, 0);
+}
+
+PBO::~PBO()
+{
+ glproc::BindBuffer(getTarget(), m_PBOID);
+ glproc::BufferData(getTarget(), 0, 0, m_Usage);
+ GLContext* pContext = GLContext::getCurrent();
+ if (pContext) {
+ pContext->getPBOCache().returnBuffer(m_PBOID);
+ }
+ glproc::BindBuffer(getTarget(), 0);
+ GLContext::checkError("PBO: DeleteBuffers()");
+ ObjectCounter::get()->decRef(&typeid(*this));
+}
+
+void PBO::activate()
+{
+ glproc::BindBuffer(getTarget(), m_PBOID);
+ GLContext::checkError("PBO::activate()");
+}
+
+int PBO::getID() const
+{
+ return m_PBOID;
+}
+
+void PBO::moveBmpToTexture(BitmapPtr pBmp, GLTexture& tex)
+{
+ AVG_ASSERT(pBmp->getSize() == tex.getSize());
+ AVG_ASSERT(getSize() == pBmp->getSize());
+ AVG_ASSERT(pBmp->getPixelFormat() == getPF());
+ AVG_ASSERT(tex.getPF() == getPF());
+ AVG_ASSERT(!isReadPBO());
+ glproc::BindBuffer(GL_PIXEL_UNPACK_BUFFER_EXT, m_PBOID);
+ GLContext::checkError("PBO::moveBmpToTexture BindBuffer()");
+ void * pPBOPixels = glproc::MapBuffer(GL_PIXEL_UNPACK_BUFFER_EXT, GL_WRITE_ONLY);
+ GLContext::checkError("PBO::moveBmpToTexture MapBuffer()");
+ Bitmap PBOBitmap(getSize(), getPF(), (unsigned char *)pPBOPixels, getStride(), false);
+ PBOBitmap.copyPixels(*pBmp);
+ glproc::UnmapBuffer(GL_PIXEL_UNPACK_BUFFER_EXT);
+ GLContext::checkError("PBO::setImage: UnmapBuffer()");
+
+ tex.setDirty();
+ moveToTexture(tex);
+}
+
+BitmapPtr PBO::moveTextureToBmp(GLTexture& tex, int mipmapLevel)
+{
+ moveTextureToPBO(tex, mipmapLevel);
+ return movePBOToBmp();
+}
+
+void PBO::moveTextureToPBO(GLTexture& tex, int mipmapLevel)
+{
+ AVG_ASSERT(isReadPBO());
+ AVG_ASSERT(getSize() == tex.getGLSize());
+ AVG_ASSERT(getPF() == tex.getPF());
+ glproc::BindBuffer(GL_PIXEL_PACK_BUFFER_EXT, m_PBOID);
+ GLContext::checkError("PBO::getImage BindBuffer()");
+
+ tex.activate(GL_TEXTURE0);
+
+ glGetTexImage(GL_TEXTURE_2D, mipmapLevel, GLTexture::getGLFormat(getPF()),
+ GLTexture::getGLType(getPF()), 0);
+ GLContext::checkError("PBO::getImage: glGetTexImage()");
+ if (mipmapLevel == 0) {
+ m_ActiveSize = tex.getSize();
+ m_BufferStride = tex.getGLSize().x;
+ } else {
+ m_ActiveSize = tex.getMipmapSize(mipmapLevel);
+ m_BufferStride = tex.getMipmapSize(mipmapLevel).x;
+ }
+}
+
+BitmapPtr PBO::movePBOToBmp() const
+{
+ AVG_ASSERT(isReadPBO());
+ glproc::BindBuffer(GL_PIXEL_PACK_BUFFER_EXT, m_PBOID);
+ GLContext::checkError("PBO::getImage BindBuffer()");
+ void * pPBOPixels = glproc::MapBuffer(GL_PIXEL_PACK_BUFFER_EXT, GL_READ_ONLY);
+ GLContext::checkError("PBO::getImage MapBuffer()");
+ Bitmap PBOBitmap(m_ActiveSize, getPF(), (unsigned char *)pPBOPixels,
+ m_BufferStride*getBytesPerPixel(getPF()), false);
+ BitmapPtr pBmp(new Bitmap(m_ActiveSize, getPF()));
+ pBmp->copyPixels(PBOBitmap);
+ glproc::UnmapBuffer(GL_PIXEL_PACK_BUFFER_EXT);
+ GLContext::checkError("PBO::getImage: UnmapBuffer()");
+ glproc::BindBuffer(GL_PIXEL_PACK_BUFFER_EXT, 0);
+
+ return pBmp;
+}
+
+BitmapPtr PBO::lock()
+{
+ AVG_ASSERT(!isReadPBO());
+ BitmapPtr pBmp;
+ glproc::BindBuffer(GL_PIXEL_UNPACK_BUFFER_EXT, m_PBOID);
+ GLContext::checkError("PBOTexture::lockBmp: glBindBuffer()");
+ glproc::BufferData(GL_PIXEL_UNPACK_BUFFER_EXT, getMemNeeded(), 0, m_Usage);
+ GLContext::checkError("PBOTexture::lockBmp: glBufferData()");
+ unsigned char * pBuffer = (unsigned char *)
+ glproc::MapBuffer(GL_PIXEL_UNPACK_BUFFER_EXT, GL_WRITE_ONLY);
+ GLContext::checkError("PBOTexture::lockBmp: glMapBuffer()");
+ glproc::BindBuffer(GL_PIXEL_UNPACK_BUFFER_EXT, 0);
+ GLContext::checkError("PBOTexture::lockBmp: glBindBuffer(0)");
+
+ pBmp = BitmapPtr(new Bitmap(getSize(), getPF(), pBuffer, getStride(), false));
+ return pBmp;
+}
+
+void PBO::unlock()
+{
+ AVG_ASSERT(!isReadPBO());
+ glproc::BindBuffer(GL_PIXEL_UNPACK_BUFFER_EXT, m_PBOID);
+ GLContext::checkError("PBOTexture::unlockBmp: glBindBuffer()");
+ glproc::UnmapBuffer(GL_PIXEL_UNPACK_BUFFER_EXT);
+ GLContext::checkError("PBOTexture::unlockBmp: glUnmapBuffer()");
+ glproc::BindBuffer(GL_PIXEL_UNPACK_BUFFER_EXT, 0);
+ GLContext::checkError("PBOTexture::unlockBmp: glBindBuffer(0)");
+}
+
+void PBO::moveToTexture(GLTexture& tex)
+{
+ AVG_ASSERT(!isReadPBO());
+ IntPoint size = tex.getSize();
+ if (size.x > getSize().x) {
+ size.x = getSize().x;
+ }
+ if (size.y > getSize().y) {
+ size.y = getSize().y;
+ }
+ glproc::BindBuffer(GL_PIXEL_UNPACK_BUFFER_EXT, m_PBOID);
+ GLContext::checkError("PBOTexture::lockBmp: glBindBuffer()");
+ tex.activate(GL_TEXTURE0);
+#ifdef __APPLE__
+ // See getStride()
+ if (getPF() == A8) {
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ } else {
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
+ }
+#endif
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, size.x, size.y,
+ GLTexture::getGLFormat(getPF()), GLTexture::getGLType(getPF()), 0);
+ GLContext::checkError("PBO::setImage: glTexSubImage2D()");
+ glproc::BindBuffer(GL_PIXEL_UNPACK_BUFFER_EXT, 0);
+ tex.setDirty();
+ tex.generateMipmaps();
+}
+
+bool PBO::isReadPBO() const
+{
+ switch (m_Usage) {
+ case GL_STATIC_DRAW:
+ case GL_DYNAMIC_DRAW:
+ case GL_STREAM_DRAW:
+ return false;
+ case GL_STATIC_READ:
+ case GL_DYNAMIC_READ:
+ case GL_STREAM_READ:
+ return true;
+ default:
+ AVG_ASSERT(false);
+ return false;
+ }
+}
+
+unsigned PBO::getMemNeeded() const
+{
+ return getStride()*getSize().y;
+}
+
+unsigned PBO::getStride() const
+{
+ IntPoint size = getSize();
+ unsigned stride = Bitmap::getPreferredStride(size.x, getPF());
+#ifdef __APPLE__
+ if (getPF() == A8) {
+ // Workaround for apparent bug in Apple/NVidia drivers (Verified on OS X 10.6.8,
+ // MBP early 2011): GL_UNPACK_ALIGNMENT != 1 causes broken A8 textures.
+ stride = size.x;
+ }
+#endif
+ return stride;
+}
+
+unsigned PBO::getTarget() const
+{
+ if (isReadPBO()) {
+ return GL_PIXEL_PACK_BUFFER_EXT;
+ } else {
+ return GL_PIXEL_UNPACK_BUFFER_EXT;
+ }
+}
+
+}
diff --git a/src/graphics/PBO.h b/src/graphics/PBO.h
new file mode 100644
index 0000000..51896a4
--- /dev/null
+++ b/src/graphics/PBO.h
@@ -0,0 +1,74 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _PBO_H_
+#define _PBO_H_
+
+#include "../api.h"
+#include "TextureMover.h"
+
+#include "Bitmap.h"
+#include "OGLHelper.h"
+#include "GLTexture.h"
+
+#include "../base/GLMHelper.h"
+
+#include <boost/shared_ptr.hpp>
+
+namespace avg {
+
+class AVG_API PBO: public TextureMover {
+public:
+ PBO(const IntPoint& size, PixelFormat pf, unsigned usage);
+ virtual ~PBO();
+
+ void activate();
+
+ void moveBmpToTexture(BitmapPtr pBmp, GLTexture& tex);
+ virtual BitmapPtr moveTextureToBmp(GLTexture& tex, int mipmapLevel=0);
+
+ BitmapPtr lock();
+ void unlock();
+ void moveToTexture(GLTexture& tex);
+ void moveTextureToPBO(GLTexture& tex, int mipmapLevel=0);
+ BitmapPtr movePBOToBmp() const;
+
+ bool isReadPBO() const;
+ int getID() const;
+
+private:
+ unsigned getMemNeeded() const;
+ unsigned getStride() const;
+ unsigned getTarget() const;
+
+ unsigned m_Usage;
+ unsigned m_PBOID;
+ IntPoint m_ActiveSize;
+ int m_BufferStride;
+};
+
+typedef boost::shared_ptr<PBO> PBOPtr;
+
+}
+
+#endif
+
+
diff --git a/src/graphics/Pixel16.h b/src/graphics/Pixel16.h
new file mode 100644
index 0000000..cca4f73
--- /dev/null
+++ b/src/graphics/Pixel16.h
@@ -0,0 +1,180 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _Pixel16_H_
+#define _Pixel16_H_
+
+#include "../api.h"
+#include "Pixeldefs.h"
+#include "Pixel24.h"
+#include "Pixel32.h"
+
+#include <stdlib.h>
+#include <math.h>
+
+namespace avg {
+
+// 16 bit pixel class. A pixel in this class contains 5 bits of
+// red, 6 of green and 5 of blue (in that order).
+class AVG_API Pixel16
+{
+ public:
+ Pixel16 ();
+ Pixel16 (unsigned char r, unsigned char g, unsigned char b);
+ void Set (unsigned char r, unsigned char g, unsigned char b);
+ void SetR (unsigned char r);
+ void SetG (unsigned char g);
+ void SetB (unsigned char b);
+ unsigned char getR () const;
+ unsigned char getG () const;
+ unsigned char getB () const;
+
+ Pixel16 operator = (const Pixel32& Pix);
+ operator Pixel32 () const;
+ Pixel16 operator = (const Pixel24& Pix);
+ operator Pixel24 () const;
+
+ bool operator ==(const Pixel16 Pix) const;
+
+ bool operator !=(const Pixel16 Pix) const;
+
+ // Simple and fast 'distance' between two pixels. Just adds the
+ // distances between the color components and treats colors
+ // equally.
+ int BoxDist (const Pixel16 Pix) const;
+
+ private:
+ unsigned short m_Data;
+};
+
+inline Pixel16::Pixel16()
+{
+}
+
+
+inline Pixel16::Pixel16(unsigned char r, unsigned char g, unsigned char b)
+{
+ Set (r, g, b);
+}
+
+
+inline void Pixel16::Set (unsigned char r, unsigned char g, unsigned char b)
+{
+#ifdef PIXEL_BGRA_ORDER
+ m_Data = ((r&0xF8) << 8) | ((g&0xFC) << 3) | (b>>3);
+#else
+ m_Data = (b&0xF8) << 8 | ((g&0xFC) << 3) | (r>>3);
+#endif
+}
+
+inline void Pixel16::SetR(unsigned char r)
+{
+#ifdef PIXEL_BGRA_ORDER
+ m_Data = (m_Data&0x07FF)|((r&0xF8)<<8);
+#else
+ m_Data = (m_Data&0xFFE0)|(r>>3);
+#endif
+}
+
+inline void Pixel16::SetG(unsigned char g)
+{
+ m_Data = (m_Data&0xF81F)|((g&0xFC)<<3);
+}
+
+
+inline void Pixel16::SetB(unsigned char b)
+{
+#ifdef PIXEL_BGRA_ORDER
+ m_Data = (m_Data&0xFFE0)|(b>>3);
+#else
+ m_Data = (m_Data&0x07FF)|((b&0xF8)<<8);
+#endif
+}
+
+inline unsigned char Pixel16::getR() const
+{
+#ifdef PIXEL_BGRA_ORDER
+ return (m_Data&0xF800)>>8;
+#else
+ return (m_Data&0x001F)<<3;
+#endif
+}
+
+
+inline unsigned char Pixel16::getG() const
+{
+ return (m_Data&0x07E0)>>3;
+}
+
+inline unsigned char Pixel16::getB() const
+{
+#ifdef PIXEL_BGRA_ORDER
+ return (m_Data&0x001F)<<3;
+#else
+ return (m_Data&0xF800)>>8;
+#endif
+}
+
+inline Pixel16 Pixel16::operator = (const Pixel32& Pix)
+{
+ Set (Pix.getR(), Pix.getG(), Pix.getB());
+ return *this;
+}
+
+inline Pixel16::operator Pixel32 () const
+{
+ // TODO: Make faster.
+ return Pixel32 (getR(), getG(), getB(), 255);
+}
+
+inline Pixel16 Pixel16::operator = (const Pixel24& Pix)
+{
+ Set (Pix.getR(), Pix.getG(), Pix.getB());
+
+ return *this;
+}
+
+inline Pixel16::operator Pixel24 () const
+{
+ // TODO: Make faster.
+ return Pixel24 (getR(), getG(), getB());
+}
+
+inline int Pixel16::BoxDist (const Pixel16 Pix) const
+{
+ return (abs ((int)getR()-Pix.getR()) +
+ abs ((int)getG()-Pix.getG()) +
+ abs ((int)getB()-Pix.getB()));
+}
+
+inline bool Pixel16::operator ==(const Pixel16 Pix) const
+{
+ return (*(const short *)this == *(const short*)&Pix);
+}
+
+inline bool Pixel16::operator !=(const Pixel16 Pix) const
+{
+ return (!(*this == Pix));
+}
+
+
+}
+#endif
diff --git a/src/graphics/Pixel24.h b/src/graphics/Pixel24.h
new file mode 100644
index 0000000..7ae0717
--- /dev/null
+++ b/src/graphics/Pixel24.h
@@ -0,0 +1,190 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _Pixel24_H_
+#define _Pixel24_H_
+
+#include "../api.h"
+#include "Pixeldefs.h"
+#include "Pixel32.h"
+#include "Pixel8.h"
+
+#include "../base/Exception.h"
+
+#include <stdlib.h>
+
+namespace avg {
+
+class AVG_API Pixel24
+{
+ public:
+ Pixel24 ();
+ Pixel24 (unsigned char r, unsigned char g, unsigned char b);
+ void set (unsigned char r, unsigned char g, unsigned char b);
+ void setR (unsigned char r);
+ void setG (unsigned char g);
+ void setB (unsigned char b);
+ unsigned char getR () const;
+ unsigned char getG () const;
+ unsigned char getB () const;
+ void flipRB();
+
+ template<class SrcPixel>
+ Pixel24 operator = (const SrcPixel& Pix)
+ {
+ setR (Pix.getR());
+ setG (Pix.getG());
+ setB (Pix.getB());
+
+ return *this;
+ }
+
+ Pixel24 operator = (const Pixel8& Pix)
+ {
+ m_Data[0] = Pix.get();
+ m_Data[1] = m_Data[0];
+ m_Data[2] = m_Data[0];
+ return *this;
+ }
+
+
+ operator Pixel32 () const;
+
+ bool operator ==(const Pixel24&) const;
+ bool operator !=(const Pixel24&) const;
+ void operator +=(const Pixel24&);
+ void operator -=(const Pixel24&);
+
+ // Simple and fast 'distance' between two pixels. Just adds the
+ // distances between the color components and treats colors
+ // equally.
+ int boxDist (const Pixel24 Pix) const;
+
+ // Returns a weighed average between two pixels. Factor must be
+ // between 0 and 256. Factor=256 means Pix1 is the result, Factor=0
+ // means Pix2 is the result.
+ static Pixel24 Blend (int Factor, const Pixel24 Pix1,
+ const Pixel24 Pix2);
+
+ private:
+ unsigned char m_Data[3];
+};
+
+inline Pixel24::Pixel24()
+{
+}
+
+inline Pixel24::Pixel24(unsigned char r, unsigned char g, unsigned char b)
+{
+ set (r, g, b);
+}
+
+inline void Pixel24::set(unsigned char r, unsigned char g, unsigned char b)
+{
+ m_Data[REDPOS] = r;
+ m_Data[GREENPOS] = g;
+ m_Data[BLUEPOS] = b;
+}
+
+inline void Pixel24::setR(unsigned char r)
+{
+ m_Data[REDPOS] = r;
+}
+
+inline void Pixel24::setG(unsigned char g)
+{
+ m_Data[GREENPOS] = g;
+}
+
+inline void Pixel24::setB(unsigned char b)
+{
+ m_Data[BLUEPOS] = b;
+}
+
+inline unsigned char Pixel24::getR() const
+{
+ return m_Data[REDPOS];
+}
+
+inline unsigned char Pixel24::getG() const
+{
+ return m_Data[GREENPOS];
+}
+
+inline unsigned char Pixel24::getB() const
+{
+ return m_Data[BLUEPOS];
+}
+
+inline void Pixel24::flipRB()
+{
+ unsigned char tmp = m_Data[BLUEPOS];
+ m_Data[BLUEPOS] = m_Data[REDPOS];
+ m_Data[REDPOS] = tmp;
+}
+
+inline int Pixel24::boxDist (const Pixel24 Pix) const
+{
+ return (abs ((int)getR()-Pix.getR()) +
+ abs ((int)getG()-Pix.getG()) +
+ abs ((int)getB()-Pix.getB()));
+}
+
+inline Pixel24 Pixel24::Blend (int Factor, const Pixel24 Pix1, const Pixel24 Pix2)
+{
+ AVG_ASSERT(Factor >= 0 && Factor <= 256);
+
+ return Pixel24 ((Pix1.getR()*Factor+Pix2.getR()*(256-Factor))>>8,
+ (Pix1.getG()*Factor+Pix2.getG()*(256-Factor))>>8,
+ (Pix1.getB()*Factor+Pix2.getB()*(256-Factor))>>8);
+}
+
+inline Pixel24::operator Pixel32 () const
+{
+ return Pixel32 (getR(), getG(), getB(), 255);
+}
+
+inline bool Pixel24::operator ==(const Pixel24& Pix) const
+{
+ return (getR() == Pix.getR() && getG() == Pix.getG() && getB() == Pix.getB());
+}
+
+inline bool Pixel24::operator !=(const Pixel24& Pix) const
+{
+ return (!(*this == Pix));
+}
+
+inline void Pixel24::operator += (const Pixel24& Pix)
+{
+ m_Data[0] += Pix.m_Data[0];
+ m_Data[1] += Pix.m_Data[1];
+ m_Data[2] += Pix.m_Data[2];
+}
+
+inline void Pixel24::operator -= (const Pixel24& Pix)
+{
+ m_Data[0] -= Pix.m_Data[0];
+ m_Data[1] -= Pix.m_Data[1];
+ m_Data[2] -= Pix.m_Data[2];
+}
+
+}
+#endif
diff --git a/src/graphics/Pixel32.cpp b/src/graphics/Pixel32.cpp
new file mode 100644
index 0000000..f1a3e40
--- /dev/null
+++ b/src/graphics/Pixel32.cpp
@@ -0,0 +1,134 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "Pixel32.h"
+
+#include "../base/Exception.h"
+
+#include <string>
+#include <sstream>
+#include <iostream>
+#include <iomanip>
+#include <algorithm>
+#include <stdio.h>
+
+namespace avg {
+
+using namespace std;
+
+void Pixel32::toHSL(float& h, float& s, float& l)
+{
+ float r = float(m_Data[REDPOS])/255.f;
+ float g = float(m_Data[GREENPOS])/255.f;
+ float b = float(m_Data[BLUEPOS])/255.f;
+ float maxComp = max(r, max(g, b));
+ float minComp = min(r, min(g, b));
+ l = (maxComp+minComp)/2;
+ if (maxComp == minComp) {
+ s = 0;
+ h = 0;
+ } else {
+ float delta = maxComp-minComp;
+ if (l < 0.5f) {
+ s = delta/(maxComp+minComp);
+ } else {
+ s = delta/(2-(maxComp+minComp));
+ }
+ if (r > g && r > b) {
+ h = (g-b)/delta;
+ if (h < 0.0f) {
+ h += 6;
+ }
+ } else if (g > b) {
+ h = 2+(b-r)/delta;
+ } else {
+ h = 4+(r-g)/delta;
+ }
+ h *= 60;
+ }
+}
+
+std::string Pixel32::getColorString() const
+{
+ stringstream s;
+ s.fill('0');
+ s << hex << setw(2) << (int)(m_Data[0]) << setw(2) << (int)(m_Data[1]) <<
+ setw(2) << (int)(m_Data[2]) << setw(2) << (int)(m_Data[3]);
+ return s.str();
+}
+
+Pixel32 colorStringToColor(const UTF8String& s)
+{
+ int r, g, b;
+ int numChars;
+ int numItems = sscanf(s.c_str(), "%2x%2x%2x%n", &r, &g, &b, &numChars);
+ if (s.length() != 6 || numChars != 6 || numItems != 3) {
+ throw(Exception (AVG_ERR_INVALID_ARGS, "colorstring cannot be parsed."));
+ }
+ return Pixel32(r, g, b);
+}
+
+void YUVtoBGR32Pixel(Pixel32* pDest, int y, int u, int v)
+{
+ // u = Cb, v = Cr
+ int u1 = u - 128;
+ int v1 = v - 128;
+ int tempy = 298*(y-16);
+ int b = (tempy + 516 * u1 ) >> 8;
+ int g = (tempy - 100 * u1 - 208 * v1) >> 8;
+ int r = (tempy + 409 * v1) >> 8;
+
+ if (b<0) b = 0;
+ if (b>255) b= 255;
+ if (g<0) g = 0;
+ if (g>255) g= 255;
+ if (r<0) r = 0;
+ if (r>255) r= 255;
+ pDest->set(b,g,r,255);
+}
+
+void YUVJtoBGR32Pixel(Pixel32* pDest, int y, int u, int v)
+{
+ // u = Cb, v = Cr
+ int u1 = u - 128;
+ int v1 = v - 128;
+ int tempy = 256*y;
+ int b = (tempy + 452 * u1 ) >> 8;
+ int g = (tempy - 88 * u1 - 182 * v1) >> 8;
+ int r = (tempy + 358 * v1) >> 8;
+
+ if (b<0) b = 0;
+ if (b>255) b= 255;
+ if (g<0) g = 0;
+ if (g>255) g= 255;
+ if (r<0) r = 0;
+ if (r>255) r= 255;
+ pDest->set(b,g,r,255);
+}
+
+std::ostream& operator <<(std::ostream& os, const Pixel32& pix)
+{
+ os << pix.getColorString();
+ return os;
+}
+
+
+}
diff --git a/src/graphics/Pixel32.h b/src/graphics/Pixel32.h
new file mode 100644
index 0000000..7ec6e98
--- /dev/null
+++ b/src/graphics/Pixel32.h
@@ -0,0 +1,208 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _Pixel32_H_
+#define _Pixel32_H_
+
+#include "../api.h"
+#include "../base/UTF8String.h"
+
+#include "Pixeldefs.h"
+
+#include <string>
+#include <math.h>
+#include <stdlib.h>
+
+namespace avg {
+
+class Pixel32
+{
+
+public:
+ Pixel32();
+ Pixel32(unsigned char r, unsigned char g, unsigned char b, unsigned char a);
+ Pixel32(unsigned char r, unsigned char g, unsigned char b);
+ void set(unsigned char r, unsigned char g, unsigned char b, unsigned char a);
+ void set(unsigned char r, unsigned char g, unsigned char b);
+ void setR(unsigned char r);
+ void setG(unsigned char g);
+ void setB(unsigned char b);
+ void setA(unsigned char a);
+ unsigned char getR() const;
+ unsigned char getG() const;
+ unsigned char getB() const;
+ unsigned char getA() const;
+ void flipRB();
+ void toHSL(float& h, float& s, float& l);
+
+ bool operator ==(const Pixel32 pix) const;
+ bool operator !=(const Pixel32 pix) const;
+ void operator +=(const Pixel32 pix);
+ void operator -=(const Pixel32 pix);
+ Pixel32 operator *(float f) const;
+
+ // Simple and fast 'distance' between two pixels. Just adds the
+ // distances between the color components and treats colors
+ // equally.
+ int boxDist(const Pixel32 pix) const;
+
+ std::string AVG_API getColorString() const;
+
+ private:
+ unsigned char m_Data[4];
+};
+
+AVG_API std::ostream& operator <<(std::ostream& os, const Pixel32& pix);
+
+AVG_API Pixel32 colorStringToColor(const UTF8String& s);
+
+void YUVtoBGR32Pixel(Pixel32* pDest, int y, int u, int v);
+void YUVJtoBGR32Pixel(Pixel32* pDest, int y, int u, int v);
+
+inline Pixel32::Pixel32()
+{
+}
+
+
+inline Pixel32::Pixel32(unsigned char r, unsigned char g, unsigned char b,
+ unsigned char a)
+{
+ set (r, g, b, a);
+}
+
+
+inline Pixel32::Pixel32(unsigned char r, unsigned char g, unsigned char b)
+{
+ set (r, g, b, 255);
+}
+
+
+inline void Pixel32::set(unsigned char r, unsigned char g, unsigned char b,
+ unsigned char a)
+{
+ m_Data[REDPOS] = r;
+ m_Data[GREENPOS] = g;
+ m_Data[BLUEPOS] = b;
+ m_Data[ALPHAPOS] = a;
+}
+
+inline void Pixel32::set(unsigned char r, unsigned char g, unsigned char b)
+{
+ m_Data[REDPOS] = r;
+ m_Data[GREENPOS] = g;
+ m_Data[BLUEPOS] = b;
+}
+
+inline void Pixel32::setR(unsigned char r)
+{
+ m_Data[REDPOS] = r;
+}
+
+
+inline void Pixel32::setG(unsigned char g)
+{
+ m_Data[GREENPOS] = g;
+}
+
+
+inline void Pixel32::setB(unsigned char b)
+{
+ m_Data[BLUEPOS] = b;
+}
+
+inline void Pixel32::setA(unsigned char a)
+{
+ m_Data[ALPHAPOS] = a;
+}
+
+
+inline unsigned char Pixel32::getR() const
+{
+ return m_Data[REDPOS];
+}
+
+
+inline unsigned char Pixel32::getG() const
+{
+ return m_Data[GREENPOS];
+}
+
+
+inline unsigned char Pixel32::getB() const
+{
+ return m_Data[BLUEPOS];
+}
+
+
+inline unsigned char Pixel32::getA() const
+{
+ return m_Data[ALPHAPOS];
+}
+
+inline void Pixel32::flipRB()
+{
+ unsigned char tmp = m_Data[BLUEPOS];
+ m_Data[BLUEPOS] = m_Data[REDPOS];
+ m_Data[REDPOS] = tmp;
+}
+
+inline int Pixel32::boxDist(const Pixel32 pix) const
+{
+ return (abs ((int)getR()-pix.getR()) +
+ abs ((int)getG()-pix.getG()) +
+ abs ((int)getB()-pix.getB()));
+}
+
+inline bool Pixel32::operator ==(const Pixel32 pix) const
+{
+ return (*(const int *)this == *(const int*)&pix);
+}
+
+inline bool Pixel32::operator !=(const Pixel32 pix) const
+{
+ return (!(*this == pix));
+}
+
+inline void Pixel32::operator +=(const Pixel32 pix)
+{
+ m_Data[0] += pix.m_Data[0];
+ m_Data[1] += pix.m_Data[1];
+ m_Data[2] += pix.m_Data[2];
+}
+
+inline void Pixel32::operator -=(const Pixel32 pix)
+{
+ m_Data[0] -= pix.m_Data[0];
+ m_Data[1] -= pix.m_Data[1];
+ m_Data[2] -= pix.m_Data[2];
+}
+
+inline Pixel32 Pixel32::operator *(float f) const
+{
+ return Pixel32((unsigned char)(f*getR()),
+ (unsigned char)(f*getG()),
+ (unsigned char)(f*getB()));
+}
+
+
+
+}
+#endif
diff --git a/src/graphics/Pixel8.h b/src/graphics/Pixel8.h
new file mode 100644
index 0000000..1d07037
--- /dev/null
+++ b/src/graphics/Pixel8.h
@@ -0,0 +1,150 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _Pixel8_H_
+#define _Pixel8_H_
+
+#include "../api.h"
+#include "Pixeldefs.h"
+#include "Pixel32.h"
+
+#include <stdlib.h>
+
+namespace avg {
+
+class AVG_API Pixel8
+{
+ public:
+ Pixel8 ();
+ Pixel8 (unsigned char i);
+ void set (unsigned char i);
+ unsigned char get () const;
+ unsigned char getR () const;
+ unsigned char getG () const;
+ unsigned char getB () const;
+ void flipRB();
+
+ template<class SrcPixel>
+ Pixel8 operator = (const SrcPixel& Pix)
+ {
+ set ((Pix.getR()*54+Pix.getG()*183+Pix.getB()*19)/256);
+ return *this;
+ }
+
+ Pixel8 operator = (const Pixel8& Pix)
+ {
+ set (Pix.get());
+ return *this;
+ }
+
+ operator Pixel32 () const;
+
+ bool operator ==(const Pixel8&) const;
+ bool operator !=(const Pixel8&) const;
+ void operator +=(const Pixel8&);
+ void operator -=(const Pixel8&);
+
+ // Simple and fast 'distance' between two pixels. Just adds the
+ // distances between the color components and treats colors
+ // equally.
+ int boxDist (const Pixel8 Pix) const;
+
+ // Returns a weighed average between two pixels. Factor must be
+ // between 0 and 256. Factor=256 means Pix1 is the result, Factor=0
+ // means Pix2 is the result.
+ static Pixel8 Blend (int Factor, const Pixel8 Pix1,
+ const Pixel8 Pix2);
+
+ private:
+ unsigned char m_i;
+};
+
+inline Pixel8::Pixel8()
+{
+}
+
+inline Pixel8::Pixel8(unsigned char i)
+{
+ set (i);
+}
+
+inline void Pixel8::set(unsigned char i)
+{
+ m_i = i;
+}
+
+inline unsigned char Pixel8::get() const
+{
+ return m_i;
+}
+
+inline unsigned char Pixel8::getR() const
+{
+ return m_i;
+}
+
+inline unsigned char Pixel8::getG() const
+{
+ return m_i;
+}
+
+inline unsigned char Pixel8::getB() const
+{
+ return m_i;
+}
+
+inline int Pixel8::boxDist (const Pixel8 Pix) const
+{
+ return (abs ((int)get()-Pix.get()));
+}
+
+inline Pixel8 Pixel8::Blend (int Factor, const Pixel8 Pix1, const Pixel8 Pix2)
+{
+ return Pixel8 ((Pix1.get()*Factor+Pix2.get()*(256-Factor))>>8);
+}
+
+inline Pixel8::operator Pixel32 () const
+{
+ return Pixel32 (m_i, m_i, m_i, 255);
+}
+
+inline bool Pixel8::operator ==(const Pixel8& Pix) const
+{
+ return (get() == Pix.get());
+}
+
+inline bool Pixel8::operator !=(const Pixel8& Pix) const
+{
+ return (!(*this == Pix));
+}
+
+inline void Pixel8::operator += (const Pixel8& Pix)
+{
+ m_i += Pix.m_i;
+}
+
+inline void Pixel8::operator -= (const Pixel8& Pix)
+{
+ m_i -= Pix.m_i;
+}
+
+}
+#endif
diff --git a/src/graphics/PixelFormat.cpp b/src/graphics/PixelFormat.cpp
new file mode 100644
index 0000000..c550b62
--- /dev/null
+++ b/src/graphics/PixelFormat.cpp
@@ -0,0 +1,288 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "PixelFormat.h"
+
+#include "../base/StringHelper.h"
+#include "../base/Exception.h"
+#include "../base/Logger.h"
+
+#include <ostream>
+
+using namespace std;
+
+namespace avg {
+
+std::ostream& operator <<(std::ostream& os, PixelFormat pf)
+{
+ os << getPixelFormatString(pf);
+ return os;
+}
+
+string getPixelFormatString(PixelFormat pf)
+{
+ switch (pf) {
+ case B5G6R5:
+ return "B5G6R5";
+ case B8G8R8:
+ return "B8G8R8";
+ case B8G8R8A8:
+ return "B8G8R8A8";
+ case B8G8R8X8:
+ return "B8G8R8X8";
+ case A8B8G8R8:
+ return "A8B8G8R8";
+ case X8B8G8R8:
+ return "X8B8G8R8";
+ case R5G6B5:
+ return "R5G6B5";
+ case R8G8B8:
+ return "R8G8B8";
+ case R8G8B8A8:
+ return "R8G8B8A8";
+ case R8G8B8X8:
+ return "R8G8B8X8";
+ case A8R8G8B8:
+ return "A8R8G8B8";
+ case X8R8G8B8:
+ return "X8R8G8B8";
+ case I8:
+ return "I8";
+ case I16:
+ return "I16";
+ case A8:
+ return "A8";
+ case YCbCr411:
+ return "YCbCr411";
+ case YCbCr422:
+ return "YCbCr422";
+ case YUYV422:
+ return "YUYV422";
+ case YCbCr420p:
+ return "YCbCr420p";
+ case YCbCrJ420p:
+ return "YCbCrJ420p";
+ case YCbCrA420p:
+ return "YCbCrA420p";
+ case BAYER8:
+ return "BAYER8";
+ case BAYER8_RGGB:
+ return "BAYER8_RGGB";
+ case BAYER8_GBRG:
+ return "BAYER8_GBRG";
+ case BAYER8_GRBG:
+ return "BAYER8_GRBG";
+ case BAYER8_BGGR:
+ return "BAYER8_BGGR";
+ case R32G32B32A32F:
+ return "R32G32B32A32F";
+ case I32F:
+ return "I32F";
+ case NO_PIXELFORMAT:
+ return "NO_PIXELFORMAT";
+ default:
+ return "Unknown " + toString(int(pf));
+ }
+}
+
+PixelFormat stringToPixelFormat(const string& s)
+{
+ if (s == "B5G6R5") {
+ return B5G6R5;
+ }
+ if (s == "B8G8R8") {
+ return B8G8R8;
+ }
+ if (s == "B8G8R8A8") {
+ return B8G8R8A8;
+ }
+ if (s == "B8G8R8X8") {
+ return B8G8R8X8;
+ }
+ if (s == "A8B8G8R8") {
+ return A8B8G8R8;
+ }
+ if (s == "X8B8G8R8") {
+ return X8B8G8R8;
+ }
+ if (s == "R5G6B5") {
+ return R5G6B5;
+ }
+ if (s == "R8G8B8") {
+ return R8G8B8;
+ }
+ if (s == "R8G8B8A8") {
+ return R8G8B8A8;
+ }
+ if (s == "R8G8B8X8") {
+ return R8G8B8X8;
+ }
+ if (s == "A8R8G8B8") {
+ return A8R8G8B8;
+ }
+ if (s == "X8R8G8B8") {
+ return X8R8G8B8;
+ }
+ if (s == "I8") {
+ return I8;
+ }
+ if (s == "I16") {
+ return I16;
+ }
+ if (s == "A8") {
+ return A8;
+ }
+ if (s == "YCbCr411") {
+ return YCbCr411;
+ }
+ if (s == "YCbCr422") {
+ return YCbCr422;
+ }
+ if (s == "YUYV422") {
+ return YUYV422;
+ }
+ if (s == "YCbCr420p") {
+ return YCbCr420p;
+ }
+ if (s == "YCbCrJ420p") {
+ return YCbCrJ420p;
+ }
+ if (s == "YCbCrA420p") {
+ return YCbCrA420p;
+ }
+ if (s == "BAYER8") {
+ return BAYER8;
+ }
+ if (s == "BAYER8_RGGB") {
+ return BAYER8_RGGB;
+ }
+ if (s == "BAYER8_GBRG") {
+ return BAYER8_GBRG;
+ }
+ if (s == "BAYER8_GRBG") {
+ return BAYER8_GRBG;
+ }
+ if (s == "BAYER8_BGGR") {
+ return BAYER8_BGGR;
+ }
+ if (s == "R32G32B32A32F") {
+ return R32G32B32A32F;
+ }
+ if (s == "I32F") {
+ return I32F;
+ }
+ return NO_PIXELFORMAT;
+}
+
+std::vector<std::string> getSupportedPixelFormats()
+{
+ std::vector<std::string> pixelFormatsVector;
+ int itPixelFormat = 0;
+ while((PixelFormat)itPixelFormat != NO_PIXELFORMAT){
+ std::string format = getPixelFormatString((PixelFormat)itPixelFormat);
+ pixelFormatsVector.push_back(format);
+ itPixelFormat++;
+ }
+ return pixelFormatsVector;
+}
+
+bool pixelFormatIsColored(PixelFormat pf)
+{
+ return (pf != I8 && pf != I16 && pf != I32F);
+}
+
+bool pixelFormatIsBayer(PixelFormat pf)
+{
+ return (pf == BAYER8 || pf == BAYER8_RGGB || pf == BAYER8_GBRG
+ || pf == BAYER8_GRBG || pf == BAYER8_BGGR);
+}
+
+bool pixelFormatHasAlpha(PixelFormat pf)
+{
+ return pf == B8G8R8A8 || pf == A8B8G8R8 || pf == R8G8B8A8 || pf == A8R8G8B8 ||
+ pf == YCbCrA420p;
+}
+
+bool pixelFormatIsPlanar(PixelFormat pf)
+{
+ return pf == YCbCr420p || pf == YCbCrJ420p || pf == YCbCrA420p;
+}
+
+bool AVG_API pixelFormatIsBlueFirst(PixelFormat pf)
+{
+ return pf == B5G6R5 || pf == B8G8R8 || pf == B8G8R8X8 || pf == B8G8R8A8;
+}
+
+unsigned getNumPixelFormatPlanes(PixelFormat pf)
+{
+ switch (pf) {
+ case YCbCr420p:
+ case YCbCrJ420p:
+ return 3;
+ case YCbCrA420p:
+ return 4;
+ default:
+ return 1;
+ }
+}
+
+unsigned getBytesPerPixel(PixelFormat pf)
+{
+ switch (pf) {
+ case R32G32B32A32F:
+ return 16;
+ case A8B8G8R8:
+ case X8B8G8R8:
+ case A8R8G8B8:
+ case X8R8G8B8:
+ case B8G8R8A8:
+ case B8G8R8X8:
+ case R8G8B8A8:
+ case R8G8B8X8:
+ case I32F:
+ return 4;
+ case R8G8B8:
+ case B8G8R8:
+ return 3;
+ case B5G6R5:
+ case R5G6B5:
+ case I16:
+ return 2;
+ case I8:
+ case A8:
+ case BAYER8:
+ case BAYER8_RGGB:
+ case BAYER8_GBRG:
+ case BAYER8_GRBG:
+ case BAYER8_BGGR:
+ return 1;
+ case YUYV422:
+ case YCbCr422:
+ return 2;
+ default:
+ AVG_LOG_ERROR("getBytesPerPixel(): Unknown format " <<
+ getPixelFormatString(pf) << ".");
+ AVG_ASSERT(false);
+ return 0;
+ }
+}
+
+}
diff --git a/src/graphics/PixelFormat.h b/src/graphics/PixelFormat.h
new file mode 100644
index 0000000..54d94b7
--- /dev/null
+++ b/src/graphics/PixelFormat.h
@@ -0,0 +1,66 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _PixelFormat_H_
+#define _PixelFormat_H_
+
+#include "../api.h"
+#include <string>
+#include <vector>
+
+namespace avg {
+
+typedef enum {
+ B5G6R5, B8G8R8, B8G8R8A8, B8G8R8X8, A8B8G8R8, X8B8G8R8,
+ R5G6B5, R8G8B8, R8G8B8A8, R8G8B8X8, A8R8G8B8, X8R8G8B8,
+ I8, I16,
+ A8,
+ YCbCr411,
+ YCbCr422,
+ YUYV422,
+ YCbCr420p,
+ YCbCrJ420p,
+ YCbCrA420p,
+ BAYER8,
+ BAYER8_RGGB,
+ BAYER8_GBRG,
+ BAYER8_GRBG,
+ BAYER8_BGGR,
+ R32G32B32A32F, // 32bit per channel float rgba
+ I32F,
+ NO_PIXELFORMAT
+} PixelFormat;
+
+AVG_API std::ostream& operator <<(std::ostream& os, PixelFormat pf);
+
+std::string AVG_API getPixelFormatString(PixelFormat pf);
+PixelFormat AVG_API stringToPixelFormat(const std::string& s);
+std::vector<std::string> AVG_API getSupportedPixelFormats();
+bool AVG_API pixelFormatIsColored(PixelFormat pf);
+bool AVG_API pixelFormatIsBayer(PixelFormat pf);
+bool AVG_API pixelFormatHasAlpha(PixelFormat pf);
+bool AVG_API pixelFormatIsPlanar(PixelFormat pf);
+bool AVG_API pixelFormatIsBlueFirst(PixelFormat pf);
+unsigned AVG_API getNumPixelFormatPlanes(PixelFormat pf);
+unsigned AVG_API getBytesPerPixel(PixelFormat pf);
+
+}
+#endif
diff --git a/src/graphics/Pixeldefs.h b/src/graphics/Pixeldefs.h
new file mode 100644
index 0000000..361b7e8
--- /dev/null
+++ b/src/graphics/Pixeldefs.h
@@ -0,0 +1,29 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _Pixeldefs_H_
+#define _Pixeldefs_H_
+
+#define PIXEL_RGBA_ORDER
+
+enum {REDPOS=0, GREENPOS=1, BLUEPOS=2, ALPHAPOS=3};
+
+#endif
diff --git a/src/graphics/ShaderRegistry.cpp b/src/graphics/ShaderRegistry.cpp
new file mode 100644
index 0000000..529482f
--- /dev/null
+++ b/src/graphics/ShaderRegistry.cpp
@@ -0,0 +1,193 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "ShaderRegistry.h"
+
+#include "GLContext.h"
+#include "OGLShader.h"
+
+#include "../base/Logger.h"
+#include "../base/Exception.h"
+#include "../base/OSHelper.h"
+#include "../base/FileHelper.h"
+#include "../base/StringHelper.h"
+
+#include <iostream>
+
+using namespace std;
+using namespace boost;
+
+namespace avg {
+
+std::string ShaderRegistry::s_sLibPath;
+
+ShaderRegistryPtr ShaderRegistry::get()
+{
+ return GLContext::getCurrent()->getShaderRegistry();
+}
+
+ShaderRegistry::ShaderRegistry()
+{
+ if (s_sLibPath == "") {
+ setShaderPath(getPath(getAvgLibPath())+"shaders");
+ }
+}
+
+ShaderRegistry::~ShaderRegistry()
+{
+}
+
+void ShaderRegistry::setShaderPath(const string& sLibPath)
+{
+ s_sLibPath = sLibPath;
+#ifdef __linux
+ // XXX: If we're running make distcheck, the shaders are in a different place than
+ // usual. Grrr.
+ char * pszSrcDir = getenv("srcdir");
+ if (pszSrcDir && string(pszSrcDir) != ".") {
+ s_sLibPath = string(pszSrcDir) + "/../graphics/shaders";
+ }
+#endif
+ AVG_TRACE(Logger::category::CONFIG, Logger::severity::INFO,
+ "Loading shaders from "+s_sLibPath);
+}
+
+void ShaderRegistry::setPreprocessorDefine(const string& sName, const string& sValue)
+{
+ m_PreprocessorDefinesMap[sName] = sValue;
+}
+
+void ShaderRegistry::createShader(const std::string& sID)
+{
+ OGLShaderPtr pShader = getShader(sID);
+ if (!pShader) {
+ string sShaderCode;
+ string sVertPreprocessed;
+ loadShaderString(s_sLibPath+"/standard.vert", sVertPreprocessed);
+ string sFilename = s_sLibPath+"/"+sID+".frag";
+ string sFragPreprocessed;
+ loadShaderString(sFilename, sFragPreprocessed);
+ string sVertPrefix = createPrefixString(false);
+ string sFragPrefix = createPrefixString(true);
+ m_ShaderMap[sID] = OGLShaderPtr(
+ new OGLShader(sID, sVertPreprocessed, sFragPreprocessed, sVertPrefix,
+ sFragPrefix));
+ }
+}
+
+OGLShaderPtr ShaderRegistry::getShader(const std::string& sID) const
+{
+ ShaderMap::const_iterator it = m_ShaderMap.find(sID);
+ if (it == m_ShaderMap.end()) {
+ return OGLShaderPtr();
+ } else {
+ return it->second;
+ }
+}
+
+OGLShaderPtr ShaderRegistry::getCurShader() const
+{
+ return m_pCurShader;
+}
+
+void ShaderRegistry::setCurShader(const std::string& sID)
+{
+ if (sID == "") {
+ m_pCurShader = OGLShaderPtr();
+ } else {
+ m_pCurShader = getShader(sID);
+ }
+}
+
+void ShaderRegistry::loadShaderString(const string& sFilename, string& sPreprocessed)
+{
+ string sShaderCode;
+ readWholeFile(sFilename, sShaderCode);
+ preprocess(sShaderCode, sFilename, sPreprocessed);
+}
+
+void ShaderRegistry::preprocess(const string& sShaderCode, const string& sFileName,
+ string& sProcessed)
+{
+ sProcessed.append("#line 0\n");
+ istringstream stream(sShaderCode);
+ string sCurLine;
+ int curLine = 0;
+ while(getline(stream, sCurLine)) {
+ curLine++;
+ string sStripped = removeStartEndSpaces(sCurLine);
+ if (sStripped.substr(0, 8) == "#include") {
+ size_t startPos = sStripped.find('"');
+ size_t endPos = sStripped.find('"', startPos+1);
+ if (startPos == string::npos || endPos == string::npos) {
+ throwParseError(sFileName, curLine);
+ }
+ string sIncFileName = sStripped.substr(startPos+1, endPos-startPos-1);
+ sIncFileName = s_sLibPath+"/"+sIncFileName;
+ string sIncludedFile;
+ readWholeFile(sIncFileName, sIncludedFile);
+ string sProcessedIncludedFile;
+ preprocess(sIncludedFile, sIncFileName, sProcessedIncludedFile);
+ sProcessed.append(sProcessedIncludedFile);
+ sProcessed.append("#line "+toString(curLine)+"\n");
+ } else {
+ sProcessed.append(sCurLine+"\n");
+ }
+ }
+}
+
+string ShaderRegistry::createPrefixString(bool bFragment)
+{
+ stringstream ss;
+ std::map<std::string, std::string>::iterator it;
+ for (it = m_PreprocessorDefinesMap.begin(); it != m_PreprocessorDefinesMap.end();
+ ++it)
+ {
+ ss << "#define " << it->first << " " << it->second << endl;
+ }
+ if (GLContext::getCurrent()->isGLES()) {
+ ss << endl;
+ if (bFragment) {
+ ss << "#extension GL_OES_standard_derivatives : enable" << endl;
+ }
+ ss << "precision mediump float;" << endl;
+ }
+ return ss.str();
+}
+
+void ShaderRegistry::throwParseError(const string& sFileName, int curLine)
+{
+ throw Exception(AVG_ERR_VIDEO_GENERAL, "File '"+sFileName+"', Line "+
+ toString(curLine)+": Syntax error.");
+}
+
+void createShader(const std::string& sID)
+{
+ return ShaderRegistry::get()->createShader(sID);
+}
+
+OGLShaderPtr getShader(const std::string& sID)
+{
+ return ShaderRegistry::get()->getShader(sID);
+}
+
+}
+
diff --git a/src/graphics/ShaderRegistry.h b/src/graphics/ShaderRegistry.h
new file mode 100644
index 0000000..5bc25a8
--- /dev/null
+++ b/src/graphics/ShaderRegistry.h
@@ -0,0 +1,73 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _ShaderRegistry_H_
+#define _ShaderRegistry_H_
+
+#include "../api.h"
+
+#include <boost/shared_ptr.hpp>
+
+#include <map>
+
+namespace avg {
+
+class ShaderRegistry;
+typedef boost::shared_ptr<ShaderRegistry> ShaderRegistryPtr;
+class OGLShader;
+typedef boost::shared_ptr<OGLShader> OGLShaderPtr;
+
+class AVG_API ShaderRegistry {
+public:
+ static ShaderRegistryPtr get();
+ ShaderRegistry();
+ virtual ~ShaderRegistry();
+
+ void setShaderPath(const std::string& sLibPath);
+ void setPreprocessorDefine(const std::string& sName, const std::string& sValue);
+
+ void createShader(const std::string& sID);
+ OGLShaderPtr getShader(const std::string& sID) const;
+
+ OGLShaderPtr getCurShader() const;
+ void setCurShader(const std::string& sID);
+
+private:
+ void loadShaderString(const std::string& sFilename, std::string& sPreprocessed);
+ void preprocess(const std::string& sShaderCode, const std::string& sFileName,
+ std::string& sProcessed);
+ std::string createPrefixString(bool bFragment);
+ void throwParseError(const std::string& sFileName, int curLine);
+ typedef std::map<std::string, OGLShaderPtr> ShaderMap;
+ ShaderMap m_ShaderMap;
+ OGLShaderPtr m_pCurShader;
+ std::map<std::string, std::string> m_PreprocessorDefinesMap;
+
+ static std::string s_sLibPath;
+};
+
+void createShader(const std::string& sID);
+OGLShaderPtr getShader(const std::string& sID);
+
+
+}
+
+#endif
diff --git a/src/graphics/StandardShader.cpp b/src/graphics/StandardShader.cpp
new file mode 100644
index 0000000..3fcd93a
--- /dev/null
+++ b/src/graphics/StandardShader.cpp
@@ -0,0 +1,216 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "StandardShader.h"
+
+#include "GLContext.h"
+#include "ShaderRegistry.h"
+
+#include "../base/Logger.h"
+#include "../base/Exception.h"
+
+#include <iostream>
+
+using namespace std;
+
+#define STANDARD_SHADER "standard"
+#define MINIMAL_SHADER "minimal"
+
+namespace avg {
+
+StandardShaderPtr StandardShader::get()
+{
+ return GLContext::getMain()->getStandardShader();
+}
+
+StandardShader::StandardShader()
+{
+ avg::createShader(STANDARD_SHADER);
+ m_pShader = avg::getShader(STANDARD_SHADER);
+ m_pColorModelParam = m_pShader->getParam<int>("u_ColorModel");
+ m_pAlphaParam = m_pShader->getParam<float>("u_Alpha");
+ m_pColorCoeff0Param = m_pShader->getParam<glm::vec4>("u_ColorCoeff0");
+ m_pColorCoeff1Param = m_pShader->getParam<glm::vec4>("u_ColorCoeff1");
+ m_pColorCoeff2Param = m_pShader->getParam<glm::vec4>("u_ColorCoeff2");
+ m_pColorCoeff3Param = m_pShader->getParam<glm::vec4>("u_ColorCoeff3");
+ m_pGammaParam = m_pShader->getParam<glm::vec4>("u_Gamma");
+
+ m_pUseColorCoeffParam = m_pShader->getParam<int>("u_bUseColorCoeff");
+ m_pPremultipliedAlphaParam = m_pShader->getParam<int>("u_bPremultipliedAlpha");
+ m_pUseMaskParam = m_pShader->getParam<int>("u_bUseMask");
+ m_pMaskPosParam = m_pShader->getParam<glm::vec2>("u_MaskPos");
+ m_pMaskSizeParam = m_pShader->getParam<glm::vec2>("u_MaskSize");
+
+ m_pShader->activate();
+ m_pShader->getParam<int>("u_Texture")->set(0);
+ if (GLContext::getMain()->useGPUYUVConversion()) {
+ m_pShader->getParam<int>("u_CBTexture")->set(1);
+ m_pShader->getParam<int>("u_CRTexture")->set(2);
+ m_pShader->getParam<int>("u_ATexture")->set(3);
+ }
+ m_pShader->getParam<int>("u_MaskTexture")->set(4);
+
+ if (GLContext::getMain()->getShaderUsage() != GLConfig::FULL) {
+ avg::createShader(MINIMAL_SHADER);
+ m_pMinimalShader = avg::getShader(MINIMAL_SHADER);
+ m_pMinimalShader->activate();
+ m_pMinimalShader->getParam<int>("u_Texture")->set(0);
+ m_pMinimalAlphaParam = m_pMinimalShader->getParam<float>("u_Alpha");
+ }
+
+ generateWhiteTexture();
+}
+
+StandardShader::~StandardShader()
+{
+}
+
+void StandardShader::activate()
+{
+ if (useMinimalShader()) {
+ m_pMinimalShader->activate();
+ m_pMinimalShader->setTransform(m_Transform);
+ m_pMinimalAlphaParam->set(m_Alpha);
+ } else {
+ m_pShader->activate();
+ m_pShader->setTransform(m_Transform);
+ m_pColorModelParam->set(m_ColorModel);
+ m_pAlphaParam->set(m_Alpha);
+
+ m_pUseColorCoeffParam->set(m_bUseColorCoeff);
+ const glm::mat4& mat = m_ColorMatrix;
+ m_pColorCoeff0Param->set(glm::vec4(mat[0][0], mat[0][1], mat[0][2], 0));
+ m_pColorCoeff1Param->set(glm::vec4(mat[1][0], mat[1][1], mat[1][2], 0));
+ m_pColorCoeff2Param->set(glm::vec4(mat[2][0], mat[2][1], mat[2][2], 0));
+ m_pColorCoeff3Param->set(glm::vec4(mat[3][0], mat[3][1], mat[3][2], 1));
+ m_pGammaParam->set(m_Gamma);
+
+ m_pPremultipliedAlphaParam->set(m_bPremultipliedAlpha);
+
+ m_pUseMaskParam->set(m_bUseMask);
+ if (m_bUseMask) {
+ m_pMaskPosParam->set(m_MaskPos);
+ m_pMaskSizeParam->set(m_MaskSize);
+ }
+ }
+}
+
+void StandardShader::setTransform(const glm::mat4& transform)
+{
+ m_Transform = transform;
+}
+
+void StandardShader::setColorModel(int model)
+{
+ m_ColorModel = model;
+}
+
+void StandardShader::setAlpha(float alpha)
+{
+ m_Alpha = alpha;
+}
+
+void StandardShader::setUntextured()
+{
+ // Activate an internal 1x1 A8 texture.
+ m_ColorModel = 2;
+ m_pWhiteTex->activate(GL_TEXTURE0);
+ disableColorspaceMatrix();
+ setGamma(glm::vec4(1.f,1.f,1.f,1.f));
+ setPremultipliedAlpha(false);
+ setMask(false);
+}
+
+void StandardShader::setColorspaceMatrix(const glm::mat4& mat)
+{
+ m_bUseColorCoeff = true;
+ m_ColorMatrix = mat;
+}
+
+void StandardShader::disableColorspaceMatrix()
+{
+ m_bUseColorCoeff = false;
+}
+
+void StandardShader::setGamma(const glm::vec4& gamma)
+{
+ m_Gamma = gamma;
+}
+
+void StandardShader::setPremultipliedAlpha(bool bPremultipliedAlpha)
+{
+ m_bPremultipliedAlpha = bPremultipliedAlpha;
+}
+
+void StandardShader::setMask(bool bUseMask, const glm::vec2& maskPos,
+ const glm::vec2& maskSize)
+{
+ m_bUseMask = bUseMask;
+ m_MaskPos = maskPos;
+ m_MaskSize = maskSize;
+}
+
+const OGLShaderPtr& StandardShader::getShader() const
+{
+ if (useMinimalShader()) {
+ return m_pMinimalShader;
+ } else {
+ return m_pShader;
+ }
+}
+
+void StandardShader::dump() const
+{
+ cerr << "---------Standard shader--------" << endl;
+ cerr << " m_Transform: " << m_Transform << endl;
+ cerr << " m_ColorModel: " << m_ColorModel << endl;
+ cerr << " m_Alpha: " << m_Alpha << endl;
+ cerr << " m_bUseColorCoeff: " << m_bUseColorCoeff << endl;
+ cerr << " m_ColorMatrix: " << m_ColorMatrix << endl;
+ cerr << " m_Gamma: " << m_Gamma << endl;
+ cerr << " m_bPremultipliedAlpha: " << m_bPremultipliedAlpha << endl;
+ cerr << " m_bUseMask: " << m_bUseMask << endl;
+ cerr << " m_MaskPos: " << m_MaskPos << endl;
+ cerr << " m_MaskSize: " << m_MaskSize << endl;
+ cerr << endl;
+}
+
+void StandardShader::generateWhiteTexture()
+{
+ BitmapPtr pBmp(new Bitmap(glm::vec2(1,1), I8));
+ *(pBmp->getPixels()) = 255;
+ m_pWhiteTex = GLTexturePtr(new GLTexture(IntPoint(1,1), I8));
+ m_pWhiteTex->moveBmpToTexture(pBmp);
+}
+
+bool StandardShader::useMinimalShader() const
+{
+ bool bActivateMinimal = false;
+ if (GLContext::getMain()->getShaderUsage() != GLConfig::FULL) {
+ bool bGammaIsModified = (!almostEqual(m_Gamma, glm::vec4(1.0f,1.0f,1.0f,1.0f)));
+ if (m_ColorModel == 0 && !m_bUseColorCoeff && !bGammaIsModified && !m_bUseMask) {
+ bActivateMinimal = true;
+ }
+ }
+ return bActivateMinimal;
+}
+
+}
diff --git a/src/graphics/StandardShader.h b/src/graphics/StandardShader.h
new file mode 100644
index 0000000..b22bd0a
--- /dev/null
+++ b/src/graphics/StandardShader.h
@@ -0,0 +1,106 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _StandardShader_H_
+#define _StandardShader_H_
+
+#include "../api.h"
+#include "OGLHelper.h"
+#include "OGLShader.h"
+#include "GLShaderParam.h"
+#include "GLTexture.h"
+
+#include "../base/GLMHelper.h"
+
+#include <boost/shared_ptr.hpp>
+
+#include <string>
+
+namespace avg {
+
+class StandardShader;
+typedef boost::shared_ptr<StandardShader> StandardShaderPtr;
+
+class AVG_API StandardShader {
+public:
+ static StandardShaderPtr get();
+ StandardShader();
+ virtual ~StandardShader();
+
+ void activate();
+
+ void setTransform(const glm::mat4& transform);
+ void setColorModel(int model);
+ void setAlpha(float alpha);
+ void setUntextured();
+ void setColorspaceMatrix(const glm::mat4& mat);
+ void disableColorspaceMatrix();
+ void setGamma(const glm::vec4& gamma);
+ void setPremultipliedAlpha(bool bPremultipliedAlpha);
+ void setMask(bool bUseMask, const glm::vec2& maskPos = glm::vec2(0,0),
+ const glm::vec2& maskSize = glm::vec2(0,0));
+
+ const OGLShaderPtr& getShader() const;
+
+ void dump() const;
+
+private:
+ void generateWhiteTexture();
+ bool useMinimalShader() const;
+
+ GLTexturePtr m_pWhiteTex;
+
+ glm::mat4 m_Transform;
+ int m_ColorModel;
+ float m_Alpha;
+ bool m_bUseColorCoeff;
+ glm::mat4 m_ColorMatrix;
+ glm::vec4 m_Gamma;
+ bool m_bPremultipliedAlpha;
+ bool m_bUseMask;
+ glm::vec2 m_MaskPos;
+ glm::vec2 m_MaskSize;
+
+ OGLShaderPtr m_pShader;
+ OGLShaderPtr m_pMinimalShader;
+
+ IntGLShaderParamPtr m_pColorModelParam;
+ FloatGLShaderParamPtr m_pAlphaParam;
+
+ Vec4fGLShaderParamPtr m_pColorCoeff0Param;
+ Vec4fGLShaderParamPtr m_pColorCoeff1Param;
+ Vec4fGLShaderParamPtr m_pColorCoeff2Param;
+ Vec4fGLShaderParamPtr m_pColorCoeff3Param;
+ Vec4fGLShaderParamPtr m_pGammaParam;
+
+ IntGLShaderParamPtr m_pUseColorCoeffParam;
+ IntGLShaderParamPtr m_pPremultipliedAlphaParam;
+ IntGLShaderParamPtr m_pUseMaskParam;
+ Vec2fGLShaderParamPtr m_pMaskPosParam;
+ Vec2fGLShaderParamPtr m_pMaskSizeParam;
+
+ FloatGLShaderParamPtr m_pMinimalAlphaParam;
+};
+
+}
+
+#endif
+
diff --git a/src/graphics/SubVertexArray.cpp b/src/graphics/SubVertexArray.cpp
new file mode 100644
index 0000000..157d6a4
--- /dev/null
+++ b/src/graphics/SubVertexArray.cpp
@@ -0,0 +1,103 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "SubVertexArray.h"
+
+#include "VertexArray.h"
+#include "GLContext.h"
+
+#include "../base/Exception.h"
+#include "../base/WideLine.h"
+#include "../base/ObjectCounter.h"
+
+#include <iostream>
+#include <stddef.h>
+#include <string.h>
+
+using namespace std;
+using namespace boost;
+
+namespace avg {
+
+SubVertexArray::SubVertexArray()
+{
+}
+
+SubVertexArray::~SubVertexArray()
+{
+}
+
+void SubVertexArray::init(VertexArray* pVertexArray, unsigned startVertex,
+ unsigned startIndex)
+{
+ m_pVA = pVertexArray;
+ m_StartVertex = startVertex;
+ m_StartIndex = startIndex;
+ m_NumVerts = 0;
+ m_NumIndexes = 0;
+}
+
+void SubVertexArray::appendTriIndexes(int v0, int v1, int v2)
+{
+ m_pVA->appendTriIndexes(v0+m_StartVertex, v1+m_StartVertex, v2+m_StartVertex);
+ m_NumIndexes += 3;
+}
+
+void SubVertexArray::appendQuadIndexes(int v0, int v1, int v2, int v3)
+{
+ m_pVA->appendQuadIndexes(v0+m_StartVertex, v1+m_StartVertex, v2+m_StartVertex,
+ v3+m_StartVertex);
+ m_NumIndexes += 6;
+}
+
+void SubVertexArray::addLineData(Pixel32 color, const glm::vec2& p1, const glm::vec2& p2,
+ float width, float tc1, float tc2)
+{
+ m_pVA->addLineData(color, p1, p2, width, tc1, tc2);
+ m_NumIndexes += 6;
+}
+
+void SubVertexArray::appendVertexData(VertexDataPtr pVertexes)
+{
+ m_pVA->appendVertexData(pVertexes);
+ m_NumVerts += pVertexes->getNumVerts();
+ m_NumIndexes += pVertexes->getNumIndexes();
+}
+
+int SubVertexArray::getNumVerts() const
+{
+ return m_NumVerts;
+}
+
+void SubVertexArray::draw()
+{
+ m_pVA->draw(m_StartIndex, m_NumIndexes, m_StartVertex, m_StartIndex);
+}
+
+void SubVertexArray::dump() const
+{
+ cerr << "SubVertexArray: m_StartVertex=" << m_StartVertex << ", "
+ << ", m_StartIndex=" << m_StartIndex << endl;
+ m_pVA->dump(m_StartVertex, m_NumVerts, m_StartIndex, m_NumIndexes);
+}
+
+}
+
diff --git a/src/graphics/SubVertexArray.h b/src/graphics/SubVertexArray.h
new file mode 100644
index 0000000..893b27d
--- /dev/null
+++ b/src/graphics/SubVertexArray.h
@@ -0,0 +1,75 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _SubVertexArray_H_
+#define _SubVertexArray_H_
+
+#include "../api.h"
+
+#include "VertexArray.h"
+#include "Pixel32.h"
+#include "OGLHelper.h"
+
+#include "../base/GLMHelper.h"
+
+#include <boost/shared_ptr.hpp>
+
+namespace avg {
+
+class AVG_API SubVertexArray {
+public:
+ SubVertexArray();
+ ~SubVertexArray();
+ void init(VertexArray* pVertexArray, unsigned startVertex, unsigned startIndex);
+
+ void appendPos(const glm::vec2& pos,
+ const glm::vec2& texPos, const Pixel32& color = Pixel32(0,0,0,0));
+ void appendTriIndexes(int v0, int v1, int v2);
+ void appendQuadIndexes(int v0, int v1, int v2, int v3);
+ void addLineData(Pixel32 color, const glm::vec2& p1, const glm::vec2& p2,
+ float width, float tc1=0, float tc2=1);
+ void appendVertexData(VertexDataPtr pVertexes);
+ int getNumVerts() const;
+
+ void draw();
+ void dump() const;
+
+private:
+ VertexArray* m_pVA;
+
+ unsigned m_StartVertex;
+ unsigned m_StartIndex;
+ int m_NumVerts;
+ int m_NumIndexes;
+};
+
+inline void SubVertexArray::appendPos(const glm::vec2& pos,
+ const glm::vec2& texPos, const Pixel32& color)
+{
+ m_pVA->appendPos(pos, texPos, color);
+ m_NumVerts++;
+}
+
+typedef boost::shared_ptr<SubVertexArray> SubVertexArrayPtr;
+
+}
+
+#endif
diff --git a/src/graphics/TextureMover.cpp b/src/graphics/TextureMover.cpp
new file mode 100644
index 0000000..f74fbf1
--- /dev/null
+++ b/src/graphics/TextureMover.cpp
@@ -0,0 +1,79 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "TextureMover.h"
+#include "PBO.h"
+#include "BmpTextureMover.h"
+#include "GLContext.h"
+
+#include "../base/Exception.h"
+
+#include <iostream>
+#include <cstring>
+
+using namespace std;
+using namespace boost;
+
+namespace avg {
+
+TextureMoverPtr TextureMover::create(OGLMemoryMode memoryMode, IntPoint size,
+ PixelFormat pf, unsigned usage)
+{
+ switch (memoryMode) {
+#ifndef AVG_ENABLE_EGL
+ case MM_PBO:
+ return TextureMoverPtr(new PBO(size, pf, usage));
+#endif
+ case MM_OGL:
+ return TextureMoverPtr(new BmpTextureMover(size, pf));
+ default:
+ AVG_ASSERT(false);
+ return TextureMoverPtr();
+ }
+}
+
+TextureMoverPtr TextureMover::create(IntPoint size, PixelFormat pf, unsigned usage)
+{
+ OGLMemoryMode memMode = GLContext::getCurrent()->getMemoryMode();
+ return create(memMode, size, pf, usage);
+}
+
+TextureMover::TextureMover(const IntPoint& size, PixelFormat pf)
+ : m_Size(size),
+ m_pf(pf)
+{
+}
+
+TextureMover::~TextureMover()
+{
+}
+
+PixelFormat TextureMover::getPF() const
+{
+ return m_pf;
+}
+
+const IntPoint& TextureMover::getSize() const
+{
+ return m_Size;
+}
+
+}
diff --git a/src/graphics/TextureMover.h b/src/graphics/TextureMover.h
new file mode 100644
index 0000000..8435e2d
--- /dev/null
+++ b/src/graphics/TextureMover.h
@@ -0,0 +1,71 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _TextureMover_H_
+#define _TextureMover_H_
+
+#include "../api.h"
+#include "PixelFormat.h"
+#include "OGLHelper.h"
+
+#include "../base/GLMHelper.h"
+
+#include <boost/shared_ptr.hpp>
+
+namespace avg {
+
+class Bitmap;
+typedef boost::shared_ptr<Bitmap> BitmapPtr;
+class GLTexture;
+typedef boost::shared_ptr<GLTexture> GLTexturePtr;
+
+class TextureMover;
+typedef boost::shared_ptr<TextureMover> TextureMoverPtr;
+
+class AVG_API TextureMover {
+public:
+ static TextureMoverPtr create(OGLMemoryMode memoryMode, IntPoint size, PixelFormat pf,
+ unsigned usage);
+ static TextureMoverPtr create(IntPoint size, PixelFormat pf, unsigned usage);
+
+ TextureMover(const IntPoint& size, PixelFormat pf);
+ virtual ~TextureMover();
+
+ virtual void moveBmpToTexture(BitmapPtr pBmp, GLTexture& tex) = 0;
+ virtual BitmapPtr moveTextureToBmp(GLTexture& tex, int mipmapLevel=0) = 0;
+
+ virtual BitmapPtr lock() = 0;
+ virtual void unlock() = 0;
+ virtual void moveToTexture(GLTexture& tex) = 0;
+
+ PixelFormat getPF() const;
+ const IntPoint& getSize() const;
+
+private:
+ IntPoint m_Size;
+ PixelFormat m_pf;
+};
+
+}
+
+#endif
+
+
diff --git a/src/graphics/TwoPassScale.h b/src/graphics/TwoPassScale.h
new file mode 100644
index 0000000..89bf993
--- /dev/null
+++ b/src/graphics/TwoPassScale.h
@@ -0,0 +1,355 @@
+// Fast and accurate bitmap scaling. Original code by Eran Yariv and Jake Montgomery,
+// posted on codeguru.com.
+
+#ifndef _TwoPassScale_h_
+#define _TwoPassScale_h_
+
+#include "ContribDefs.h"
+
+#include "../base/Exception.h"
+
+#include <math.h>
+#include <algorithm>
+#include <cstring>
+
+namespace avg {
+
+typedef struct
+{
+ int *Weights; // Normalized weights of neighboring pixels
+ int Left,Right; // Bounds of source pixels window
+} ContributionType; // Contirbution information for a single pixel
+
+typedef struct
+{
+ ContributionType *ContribRow; // Row (or column) of contribution weights
+ int WindowSize, // Filter window size (of affecting source pixels)
+ LineLength; // Length of line (no. or rows / cols)
+} LineContribType; // Contribution information for an entire line (row or column)
+
+class CDataA_UBYTE
+{
+public:
+ typedef unsigned char PixelClass;
+ class _Accumulator {
+ public:
+ _Accumulator ()
+ {
+ val = 0;
+ };
+ void Accumulate (int Weight, PixelClass &value)
+ {
+ val += (Weight * value);
+ };
+
+ void Store (PixelClass* value)
+ {
+ *value = (unsigned char) ((val + 128)/256);
+ };
+ int val;
+ };
+};
+
+class CDataRGB_UBYTE
+{
+public:
+ typedef unsigned char PixelClass[3];
+ class _Accumulator {
+ public:
+ _Accumulator ()
+ {
+ val [0] = val [1] = val [2] = 0;
+ };
+ void Accumulate (int Weight, PixelClass &value)
+ {
+ val [0] += (Weight * value [0]);
+ val [1] += (Weight * value [1]);
+ val [2] += (Weight * value [2]);
+ };
+
+ void Store (PixelClass* value)
+ {
+ (*value) [0] = (unsigned char) ((val [0] + 128)/256);
+ (*value) [1] = (unsigned char) ((val [1] + 128)/256);
+ (*value) [2] = (unsigned char) ((val [2] + 128)/256);
+ };
+ int val [3];
+ };
+};
+
+class CDataRGBA_UBYTE {
+public:
+ typedef unsigned char PixelClass[4];
+ class _Accumulator {
+ public:
+ _Accumulator ()
+ {
+ val [0] = val [1] = val [2] = val [3] = 0;
+ };
+ void Accumulate (int dWeight, PixelClass &value)
+ {
+ val [0] += (dWeight * (value [0]));
+ val [1] += (dWeight * (value [1]));
+ val [2] += (dWeight * (value [2]));
+ val [3] += (dWeight * (value [3]));
+ };
+
+ void Store (PixelClass* value)
+ {
+ (*value) [0] = (unsigned char) ((val [0] + 128)/256);
+ (*value) [1] = (unsigned char) ((val [1] + 128)/256);
+ (*value) [2] = (unsigned char) ((val [2] + 128)/256);
+ (*value) [3] = (unsigned char) ((val [3] + 128)/256);
+ };
+ int val [4];
+ };
+};
+
+template <class DataClass>
+class TwoPassScale
+{
+public:
+ typedef typename DataClass::PixelClass PixelClass;
+
+ TwoPassScale (const ContribDef& contribDef)
+ : m_ContribDef (contribDef)
+ {};
+
+ virtual ~TwoPassScale() {};
+
+ void Scale(PixelClass * pSrcData, const IntPoint& srcSize, int srcStride,
+ PixelClass *pDstData, const IntPoint& dstSize, int dstStride);
+
+private:
+ LineContribType *AllocContributions (unsigned uLineLength,
+ unsigned uWindowSize);
+
+ void FreeContributions (LineContribType * p);
+
+ LineContribType *CalcContributions (unsigned uLineSize,
+ unsigned uSrcSize);
+
+ void ScaleRow(PixelClass *pSrc, int uSrcWidth, PixelClass *pDest, int uResWidth,
+ LineContribType *pContrib);
+
+ void HorizScale(PixelClass * pSrcData, const IntPoint& srcSize, int srcStride,
+ PixelClass *pDestData, const IntPoint& destSize, int destStride);
+
+ void VertScale(PixelClass *pSrcData, const IntPoint& srcSize, int srcStride,
+ PixelClass *pDestData, const IntPoint& destSize, int destStride);
+
+ const ContribDef& m_ContribDef;
+};
+
+template <class DataClass>
+LineContribType *
+TwoPassScale<DataClass>::AllocContributions (unsigned uLineLength, unsigned uWindowSize)
+{
+ LineContribType *res = new LineContribType;
+ // Init structure header
+ res->WindowSize = uWindowSize;
+ res->LineLength = uLineLength;
+ // Allocate list of contributions
+ res->ContribRow = new ContributionType[uLineLength];
+ for (unsigned u = 0 ; u < uLineLength ; u++)
+ {
+ // Allocate contributions for every pixel
+ res->ContribRow[u].Weights = new int[uWindowSize];
+ }
+ return res;
+}
+
+template <class DataClass>
+void
+TwoPassScale<DataClass>::FreeContributions (LineContribType * p)
+{
+ for (int u = 0; u < p->LineLength; u++)
+ {
+ // Free contribs for every pixel
+ delete [] p->ContribRow[u].Weights;
+ }
+ delete [] p->ContribRow; // Free list of pixels contribs
+ delete p; // Free contribs header
+}
+
+template <class DataClass>
+LineContribType *
+TwoPassScale<DataClass>::CalcContributions(unsigned uLineSize, unsigned uSrcSize)
+{
+ float dScale = float(uLineSize)/uSrcSize;
+ float dWidth;
+ float dFScale = 1.0;
+ float dFilterWidth = m_ContribDef.GetWidth();
+
+ if (dScale < 1.0) {
+ // Minification
+ dWidth = dFilterWidth / dScale;
+ dFScale = dScale;
+ } else {
+ // Magnification
+ dWidth= dFilterWidth;
+ }
+
+ // Window size is the number of sampled pixels
+ int iWindowSize = 2 * (int)ceil(dWidth) + 1;
+
+ // Allocate a new line contributions strucutre
+ LineContribType *res = AllocContributions (uLineSize, iWindowSize);
+
+ for (unsigned u = 0; u < uLineSize; u++) {
+ // Scan through line of contributions
+ float dCenter = (u+0.5f)/dScale-0.5f; // Reverse mapping
+ // Find the significant edge points that affect the pixel
+ int iLeft = std::max (0, (int)floor (dCenter - dWidth));
+ int iRight = std::min ((int)ceil (dCenter + dWidth), int(uSrcSize) - 1);
+
+ // Cut edge points to fit in filter window in case of spill-off
+ if (iRight - iLeft + 1 > iWindowSize) {
+ if (iLeft < (int(uSrcSize) - 1 / 2)) {
+ iLeft++;
+ } else {
+ iRight--;
+ }
+ }
+ res->ContribRow[u].Left = iLeft;
+ res->ContribRow[u].Right = iRight;
+
+ int dTotalWeight = 0; // Zero sum of weights
+ for (int iSrc = iLeft; iSrc <= iRight; iSrc++) {
+ // Calculate weights
+ int CurWeight = int (dFScale * (m_ContribDef.Filter (dFScale *
+ (dCenter - (float)iSrc)))*256);
+ res->ContribRow[u].Weights[iSrc-iLeft] = CurWeight;
+ dTotalWeight += CurWeight;
+ }
+ AVG_ASSERT(dTotalWeight >= 0); // An error in the filter function can cause this
+ int UsedWeight = 0;
+ if (dTotalWeight > 0) {
+ // Normalize weight of neighbouring points
+ for (int iSrc = iLeft; iSrc < iRight; iSrc++) {
+ // Normalize point
+ int CurWeight = (res->ContribRow[u].Weights[iSrc-iLeft]*256)/dTotalWeight;
+ res->ContribRow[u].Weights[iSrc-iLeft] = CurWeight;
+ UsedWeight += CurWeight;
+ }
+ // The last point gets everything that's left over so the sum is
+ // always correct.
+ res->ContribRow[u].Weights[iRight-iLeft] = 256 - UsedWeight;
+ }
+ }
+ return res;
+}
+
+template <class DataClass>
+void
+TwoPassScale<DataClass>::ScaleRow(PixelClass *pSrc, int uSrcWidth,
+ PixelClass *pDest, int uResWidth, LineContribType *pContrib)
+{
+ PixelClass * pDestPixel = pDest;
+ for (int x = 0; x < uResWidth; x++) {
+ typename DataClass::_Accumulator a;
+ int iLeft = pContrib->ContribRow[x].Left; // Retrieve left boundries
+ int iRight = pContrib->ContribRow[x].Right; // Retrieve right boundries
+ int * Weights = pContrib->ContribRow[x].Weights;
+ for (int i = iLeft; i <= iRight; i++) {
+ // Scan between boundries
+ // Accumulate weighted effect of each neighboring pixel
+ a.Accumulate(Weights[i-iLeft], pSrc[i]);
+ }
+ a.Store(pDestPixel);
+ pDestPixel++;
+ }
+}
+
+template <class DataClass>
+void TwoPassScale<DataClass>::HorizScale(PixelClass * pSrcData, const IntPoint& srcSize,
+ int srcStride, PixelClass *pDestData, const IntPoint& destSize, int destStride)
+{
+ PixelClass * pSrc = pSrcData;
+ PixelClass * pDest = pDestData;
+ if (srcSize.x == destSize.x) {
+ // No scaling required, just copy
+ for (int y = 0; y < destSize.y; y++) {
+ memcpy(pDest, pSrc, sizeof (PixelClass) * srcSize.x);
+ pSrc = (PixelClass*)((char*)(pSrc)+srcStride);
+ pDest = (PixelClass*)((char*)(pDest)+destStride);
+ }
+ } else {
+ LineContribType * pContrib = CalcContributions(destSize.x, srcSize.x);
+ for (int y = 0; y < destSize.y; y++) {
+ ScaleRow(pSrc, srcSize.x, pDest, destSize.x, pContrib);
+ pSrc = (PixelClass*)((char*)(pSrc)+srcStride);
+ pDest = (PixelClass*)((char*)(pDest)+destStride);
+ }
+ FreeContributions(pContrib); // Free contributions structure
+ }
+}
+
+
+template <class DataClass>
+void TwoPassScale<DataClass>::VertScale(PixelClass *pSrcData, const IntPoint& srcSize,
+ int srcStride, PixelClass *pDestData, const IntPoint& destSize, int destStride)
+{
+ PixelClass * pSrc = pSrcData;
+ PixelClass * pDest = pDestData;
+ if (srcSize.y == destSize.y) {
+ // No scaling required, just copy
+ for (int y = 0; y < destSize.y; y++) {
+ memcpy(pDest, pSrc, sizeof (PixelClass) * srcSize.x);
+ pSrc = (PixelClass*)((char*)(pSrc)+srcStride);
+ pDest = (PixelClass*)((char*)(pDest)+destStride);
+ }
+ } else {
+ LineContribType * pContrib = CalcContributions(destSize.y, srcSize.y);
+ for (int y = 0; y < destSize.y; y++) {
+ PixelClass * pDestPixel = pDest;
+ int * pWeights = pContrib->ContribRow[y].Weights;
+ int iLeft = pContrib->ContribRow[y].Left;
+ int iRight = pContrib->ContribRow[y].Right;
+ PixelClass* pSrcPixelBase = (PixelClass*)((char*)(pSrc)
+ + size_t(iLeft)*srcStride);
+ for (int x = 0; x < destSize.x; x++) {
+ typename DataClass::_Accumulator a;
+ int * pWeight = pWeights;
+ PixelClass * pSrcPixel = pSrcPixelBase;
+ pSrcPixelBase++;
+ for (int i = iLeft; i <= iRight; i++) {
+ // Scan between boundries
+ // Accumulate weighted effect of each neighboring pixel
+ a.Accumulate(*pWeight, *pSrcPixel);
+ pWeight++;
+ pSrcPixel = (PixelClass*)((char*)(pSrcPixel)+srcStride);
+ }
+ a.Store(pDestPixel);
+ pDestPixel++;
+ }
+ pDest = (PixelClass*)((char*)(pDest)+destStride);
+ }
+ FreeContributions(pContrib); // Free contributions structure
+ }
+}
+
+
+template <class DataClass>
+void TwoPassScale<DataClass>::Scale(PixelClass * pSrcData, const IntPoint& srcSize,
+ int srcStride, PixelClass *pDstData, const IntPoint& dstSize, int dstStride)
+{
+ // Allocate temp image
+ PixelClass *pTempData = new PixelClass[srcSize.y*dstSize.x];
+ IntPoint tempSize(dstSize.x, srcSize.y);
+ int tempStride = dstSize.x*sizeof(PixelClass);
+
+ // Scale source image horizontally into temporary image
+ HorizScale(pSrcData, srcSize, srcStride,
+ pTempData, tempSize, tempStride);
+
+ // Scale temporary image vertically into result image
+ VertScale (pTempData, tempSize, tempStride,
+ pDstData, dstSize, dstStride);
+ delete [] pTempData;
+}
+
+}
+
+#endif
+
diff --git a/src/graphics/VertexArray.cpp b/src/graphics/VertexArray.cpp
new file mode 100644
index 0000000..45da798
--- /dev/null
+++ b/src/graphics/VertexArray.cpp
@@ -0,0 +1,159 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "VertexArray.h"
+
+#include "GLContext.h"
+#include "SubVertexArray.h"
+
+#include "../base/Exception.h"
+#include "../base/WideLine.h"
+#include "../base/ObjectCounter.h"
+
+#include <iostream>
+#include <stddef.h>
+#include <string.h>
+
+using namespace std;
+using namespace boost;
+
+namespace avg {
+
+const unsigned VertexArray::TEX_INDEX = 0;
+const unsigned VertexArray::POS_INDEX = 1;
+const unsigned VertexArray::COLOR_INDEX = 2;
+
+VertexArray::VertexArray(int reserveVerts, int reserveIndexes)
+ : VertexData(reserveVerts, reserveIndexes)
+{
+ GLContext* pContext = GLContext::getCurrent();
+ if (getReserveVerts() != MIN_VERTEXES || getReserveIndexes() != MIN_INDEXES) {
+ glproc::GenBuffers(1, &m_GLVertexBufferID);
+ glproc::GenBuffers(1, &m_GLIndexBufferID);
+ } else {
+ m_GLVertexBufferID = pContext->getVertexBufferCache().getBuffer();
+ m_GLIndexBufferID = pContext->getIndexBufferCache().getBuffer();
+ }
+ m_bUseMapBuffer = (!pContext->isGLES());
+}
+
+VertexArray::~VertexArray()
+{
+ GLContext* pContext = GLContext::getCurrent();
+ if (pContext) {
+ if (getReserveVerts() == MIN_VERTEXES) {
+ pContext->getVertexBufferCache().returnBuffer(m_GLVertexBufferID);
+ } else {
+ glproc::DeleteBuffers(1, &m_GLVertexBufferID);
+ }
+ if (getReserveIndexes() == MIN_INDEXES) {
+ pContext->getIndexBufferCache().returnBuffer(m_GLIndexBufferID);
+ } else {
+ glproc::DeleteBuffers(1, &m_GLIndexBufferID);
+ }
+ }
+}
+
+void VertexArray::update()
+{
+ if (hasDataChanged()) {
+ transferBuffer(GL_ARRAY_BUFFER, m_GLVertexBufferID,
+ getReserveVerts()*sizeof(Vertex),
+ getNumVerts()*sizeof(Vertex), getVertexPointer());
+#ifdef AVG_ENABLE_EGL
+ transferBuffer(GL_ELEMENT_ARRAY_BUFFER, m_GLIndexBufferID,
+ getReserveIndexes()*sizeof(unsigned short),
+ getNumIndexes()*sizeof(unsigned short), getIndexPointer());
+#else
+ transferBuffer(GL_ELEMENT_ARRAY_BUFFER, m_GLIndexBufferID,
+ getReserveIndexes()*sizeof(unsigned int),
+ getNumIndexes()*sizeof(unsigned int), getIndexPointer());
+#endif
+ GLContext::checkError("VertexArray::update()");
+ }
+ resetDataChanged();
+}
+
+void VertexArray::activate()
+{
+ glproc::BindBuffer(GL_ARRAY_BUFFER, m_GLVertexBufferID);
+ glproc::BindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_GLIndexBufferID);
+ glproc::VertexAttribPointer(TEX_INDEX, 2, GL_SHORT, GL_FALSE,
+ sizeof(Vertex), (void *)(offsetof(Vertex, m_Tex)));
+ glproc::VertexAttribPointer(POS_INDEX, 2, GL_FLOAT, GL_FALSE,
+ sizeof(Vertex), (void *)(offsetof(Vertex, m_Pos)));
+ glproc::VertexAttribPointer(COLOR_INDEX, 4, GL_UNSIGNED_BYTE, GL_TRUE,
+ sizeof(Vertex), (void *)(offsetof(Vertex, m_Color)));
+ glproc::EnableVertexAttribArray(TEX_INDEX);
+ glproc::EnableVertexAttribArray(POS_INDEX);
+ glproc::EnableVertexAttribArray(COLOR_INDEX);
+ GLContext::checkError("VertexArray::activate()");
+}
+
+void VertexArray::draw()
+{
+ update();
+ activate();
+#ifdef AVG_ENABLE_EGL
+ glDrawElements(GL_TRIANGLES, getNumIndexes(), GL_UNSIGNED_SHORT, 0);
+#else
+ glDrawElements(GL_TRIANGLES, getNumIndexes(), GL_UNSIGNED_INT, 0);
+#endif
+ GLContext::checkError("VertexArray::draw()");
+}
+
+void VertexArray::draw(unsigned startIndex, unsigned numIndexes, unsigned startVertex,
+ unsigned numVertexes)
+{
+#ifdef AVG_ENABLE_EGL
+ glDrawElements(GL_TRIANGLES, numIndexes, GL_UNSIGNED_SHORT,
+ (void *)(startIndex*sizeof(unsigned short)));
+#else
+ glDrawElements(GL_TRIANGLES, numIndexes, GL_UNSIGNED_INT,
+ (void *)(startIndex*sizeof(unsigned int)));
+#endif
+// XXX: Theoretically faster, but broken on Linux/Intel N10 graphics, Ubuntu 12/04
+// glproc::DrawRangeElements(GL_TRIANGLES, startVertex, startVertex+numVertexes,
+// numIndexes, GL_UNSIGNED_SHORT, (void *)(startIndex*sizeof(unsigned short)));
+ GLContext::checkError("VertexArray::draw()");
+}
+
+void VertexArray::startSubVA(SubVertexArray& subVA)
+{
+ subVA.init(this, getNumVerts(), getNumIndexes());
+}
+
+void VertexArray::transferBuffer(GLenum target, unsigned bufferID, unsigned reservedSize,
+ unsigned usedSize, const void* pData)
+{
+ glproc::BindBuffer(target, bufferID);
+ if (m_bUseMapBuffer) {
+ glproc::BufferData(target, reservedSize, 0, GL_STREAM_DRAW);
+ void * pBuffer = glproc::MapBuffer(target, GL_WRITE_ONLY);
+ memcpy(pBuffer, pData, usedSize);
+ glproc::UnmapBuffer(target);
+ } else {
+ glproc::BufferData(target, usedSize, pData, GL_STREAM_DRAW);
+ }
+}
+
+}
+
diff --git a/src/graphics/VertexArray.h b/src/graphics/VertexArray.h
new file mode 100644
index 0000000..194072b
--- /dev/null
+++ b/src/graphics/VertexArray.h
@@ -0,0 +1,69 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _VertexArray_H_
+#define _VertexArray_H_
+
+#include "../api.h"
+#include "VertexData.h"
+#include "Pixel32.h"
+#include "OGLHelper.h"
+
+#include "../base/GLMHelper.h"
+
+#include <boost/shared_ptr.hpp>
+
+namespace avg {
+
+class SubVertexArray;
+
+class AVG_API VertexArray: public VertexData {
+public:
+ static const unsigned TEX_INDEX;
+ static const unsigned POS_INDEX;
+ static const unsigned COLOR_INDEX;
+
+ VertexArray(int reserveVerts = 0, int reserveIndexes = 0);
+ virtual ~VertexArray();
+
+ void update();
+ void activate();
+ void draw();
+ void draw(unsigned startIndex, unsigned numIndexes, unsigned startVertex,
+ unsigned numVertexes);
+
+ void startSubVA(SubVertexArray& subVA);
+
+private:
+ void transferBuffer(GLenum target, unsigned bufferID, unsigned reservedSize,
+ unsigned usedSize, const void* pData);
+
+ unsigned m_GLVertexBufferID;
+ unsigned m_GLIndexBufferID;
+
+ bool m_bUseMapBuffer;
+};
+
+typedef boost::shared_ptr<VertexArray> VertexArrayPtr;
+
+}
+
+#endif
diff --git a/src/graphics/VertexData.cpp b/src/graphics/VertexData.cpp
new file mode 100644
index 0000000..8548e46
--- /dev/null
+++ b/src/graphics/VertexData.cpp
@@ -0,0 +1,253 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "VertexData.h"
+
+#include "GLContext.h"
+
+#include "../base/Exception.h"
+#include "../base/WideLine.h"
+#include "../base/ObjectCounter.h"
+
+#include <iostream>
+#include <stddef.h>
+#include <string.h>
+
+using namespace std;
+using namespace boost;
+
+namespace avg {
+
+const int VertexData::MIN_VERTEXES = 100;
+const int VertexData::MIN_INDEXES = 100;
+
+VertexData::VertexData(int reserveVerts, int reserveIndexes)
+ : m_NumVerts(0),
+ m_NumIndexes(0),
+ m_ReserveVerts(reserveVerts),
+ m_ReserveIndexes(reserveIndexes),
+ m_bDataChanged(true)
+{
+ ObjectCounter::get()->incRef(&typeid(*this));
+ if (m_ReserveVerts < MIN_VERTEXES) {
+ m_ReserveVerts = MIN_VERTEXES;
+ }
+ if (m_ReserveIndexes < MIN_INDEXES) {
+ m_ReserveIndexes = MIN_INDEXES;
+ }
+
+ m_pVertexData = new Vertex[m_ReserveVerts];
+ m_pIndexData = new GL_INDEX_TYPE[m_ReserveIndexes];
+
+}
+
+VertexData::~VertexData()
+{
+ delete[] m_pVertexData;
+ delete[] m_pIndexData;
+ ObjectCounter::get()->decRef(&typeid(*this));
+}
+
+void VertexData::appendPos(const glm::vec2& pos, const glm::vec2& texPos,
+ const Pixel32& color)
+{
+ if (m_NumVerts >= m_ReserveVerts-1) {
+ grow();
+ }
+ Vertex* pVertex = &(m_pVertexData[m_NumVerts]);
+ pVertex->m_Pos[0] = (GLfloat)(pos.x);
+ pVertex->m_Pos[1] = (GLfloat)(pos.y);
+ pVertex->m_Tex[0] = (GLshort)(texPos.x*4096.f);
+ pVertex->m_Tex[1] = (GLshort)(texPos.y*4096.f);
+ pVertex->m_Color = color;
+ m_bDataChanged = true;
+ m_NumVerts++;
+}
+
+void VertexData::appendTriIndexes(int v0, int v1, int v2)
+{
+ if (m_NumIndexes >= m_ReserveIndexes-3) {
+ grow();
+ }
+ m_pIndexData[m_NumIndexes] = v0;
+ m_pIndexData[m_NumIndexes+1] = v1;
+ m_pIndexData[m_NumIndexes+2] = v2;
+ m_NumIndexes += 3;
+}
+
+void VertexData::appendQuadIndexes(int v0, int v1, int v2, int v3)
+{
+ if (m_NumIndexes >= m_ReserveIndexes-6) {
+ grow();
+ }
+ m_pIndexData[m_NumIndexes] = v0;
+ m_pIndexData[m_NumIndexes+1] = v1;
+ m_pIndexData[m_NumIndexes+2] = v2;
+ m_pIndexData[m_NumIndexes+3] = v1;
+ m_pIndexData[m_NumIndexes+4] = v2;
+ m_pIndexData[m_NumIndexes+5] = v3;
+ m_NumIndexes += 6;
+}
+
+void VertexData::addLineData(Pixel32 color, const glm::vec2& p1, const glm::vec2& p2,
+ float width, float tc1, float tc2)
+{
+ WideLine wl(p1, p2, width);
+ int curVertex = getNumVerts();
+ appendPos(wl.pl0, glm::vec2(tc1, 1), color);
+ appendPos(wl.pr0, glm::vec2(tc1, 0), color);
+ appendPos(wl.pl1, glm::vec2(tc2, 1), color);
+ appendPos(wl.pr1, glm::vec2(tc2, 0), color);
+ appendQuadIndexes(curVertex+1, curVertex, curVertex+3, curVertex+2);
+}
+
+void VertexData::appendVertexData(const VertexDataPtr& pVertexes)
+{
+ int oldNumVerts = m_NumVerts;
+ int oldNumIndexes = m_NumIndexes;
+ m_NumVerts += pVertexes->getNumVerts();
+ m_NumIndexes += pVertexes->getNumIndexes();
+ if (m_NumVerts > m_ReserveVerts || m_NumIndexes > m_ReserveIndexes) {
+ grow();
+ }
+
+ memcpy(&(m_pVertexData[oldNumVerts]), pVertexes->m_pVertexData,
+ pVertexes->getNumVerts()*sizeof(Vertex));
+ int numIndexes = pVertexes->getNumIndexes();
+ for (int i=0; i<numIndexes; ++i) {
+ m_pIndexData[oldNumIndexes+i] = pVertexes->m_pIndexData[i] + oldNumVerts;
+ }
+ m_bDataChanged = true;
+}
+
+bool VertexData::hasDataChanged() const
+{
+ return m_bDataChanged;
+}
+
+void VertexData::resetDataChanged()
+{
+ m_bDataChanged = false;
+}
+
+void VertexData::reset()
+{
+ m_NumVerts = 0;
+ m_NumIndexes = 0;
+}
+
+int VertexData::getNumVerts() const
+{
+ return m_NumVerts;
+}
+
+int VertexData::getNumIndexes() const
+{
+ return m_NumIndexes;
+}
+
+void VertexData::dump() const
+{
+ dump(0, m_NumVerts, 0, m_NumIndexes);
+}
+
+void VertexData::dump(unsigned startVertex, int numVerts, unsigned startIndex,
+ int numIndexes) const
+{
+ cerr << numVerts << " vertexes: ";
+ for (unsigned i=startVertex; i<startVertex+numVerts; ++i) {
+ cerr << m_pVertexData[i] << endl;
+ }
+ cerr << endl;
+ cerr << numIndexes << " indexes: ";
+ for (unsigned i=startIndex; i<startIndex+numIndexes; ++i) {
+ cerr << m_pIndexData[i] << " ";
+ }
+ cerr << endl;
+}
+
+void VertexData::grow()
+{
+ bool bChanged = false;
+ if (m_NumVerts >= m_ReserveVerts-1) {
+ bChanged = true;
+ int oldReserveVerts = m_ReserveVerts;
+ m_ReserveVerts = int(m_ReserveVerts*1.5);
+#ifdef AVG_ENABLE_EGL
+ if (m_ReserveVerts > 65535) {
+ throw Exception(AVG_ERR_UNSUPPORTED,
+ "Global maximum number of vertexes reached (65535).");
+ }
+#endif
+ if (m_ReserveVerts < m_NumVerts) {
+ m_ReserveVerts = m_NumVerts;
+ }
+ Vertex* pVertexData = m_pVertexData;
+ m_pVertexData = new Vertex[m_ReserveVerts];
+ memcpy(m_pVertexData, pVertexData, sizeof(Vertex)*oldReserveVerts);
+ delete[] pVertexData;
+ }
+ if (m_NumIndexes >= m_ReserveIndexes-6) {
+ bChanged = true;
+ int oldReserveIndexes = m_ReserveIndexes;
+ m_ReserveIndexes = int(m_ReserveIndexes*1.5);
+ if (m_ReserveIndexes < m_NumIndexes) {
+ m_ReserveIndexes = m_NumIndexes;
+ }
+ GL_INDEX_TYPE * pIndexData = m_pIndexData;
+ m_pIndexData = new GL_INDEX_TYPE[m_ReserveIndexes];
+ memcpy(m_pIndexData, pIndexData, sizeof(GL_INDEX_TYPE)*oldReserveIndexes);
+ delete[] pIndexData;
+ }
+ if (bChanged) {
+ m_bDataChanged = true;
+ }
+}
+
+int VertexData::getReserveVerts() const
+{
+ return m_ReserveVerts;
+}
+
+int VertexData::getReserveIndexes() const
+{
+ return m_ReserveIndexes;
+}
+
+const Vertex * VertexData::getVertexPointer() const
+{
+ return m_pVertexData;
+}
+
+const GL_INDEX_TYPE * VertexData::getIndexPointer() const
+{
+ return m_pIndexData;
+}
+
+std::ostream& operator<<(std::ostream& os, const Vertex& v)
+{
+ os << " ((" << v.m_Pos[0] << ", " << v.m_Pos[1] << "), ("
+ << v.m_Tex[0] << ", " << v.m_Tex[1] << "))";
+ return os;
+}
+
+}
+
diff --git a/src/graphics/VertexData.h b/src/graphics/VertexData.h
new file mode 100644
index 0000000..79316b8
--- /dev/null
+++ b/src/graphics/VertexData.h
@@ -0,0 +1,100 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _VertexData_H_
+#define _VertexData_H_
+
+#include "../api.h"
+
+#include "Pixel32.h"
+#include "OGLHelper.h"
+
+#include "../base/GLMHelper.h"
+
+#include <boost/shared_ptr.hpp>
+
+namespace avg {
+
+struct Vertex {
+ GLshort m_Tex[2]; // 4.12 fixed point.
+ GLfloat m_Pos[2];
+ Pixel32 m_Color;
+};
+
+class VertexData;
+typedef boost::shared_ptr<VertexData> VertexDataPtr;
+
+#ifdef AVG_ENABLE_EGL
+#define GL_INDEX_TYPE unsigned short
+#else
+#define GL_INDEX_TYPE unsigned int
+#endif
+
+class AVG_API VertexData {
+public:
+ VertexData(int reserveVerts = 0, int reserveIndexes = 0);
+ virtual ~VertexData();
+
+ void appendPos(const glm::vec2& pos,
+ const glm::vec2& texPos, const Pixel32& color = Pixel32(0,0,0,0));
+ void appendTriIndexes(int v0, int v1, int v2);
+ void appendQuadIndexes(int v0, int v1, int v2, int v3);
+ void addLineData(Pixel32 color, const glm::vec2& p1, const glm::vec2& p2,
+ float width, float tc1=0, float tc2=1);
+ void appendVertexData(const VertexDataPtr& pVertexes);
+ bool hasDataChanged() const;
+ void resetDataChanged();
+ void reset();
+
+ int getNumVerts() const;
+ int getNumIndexes() const;
+ void dump() const;
+ void dump(unsigned startVertex, int numVerts, unsigned startIndex, int numIndexes)
+ const;
+
+protected:
+ int getReserveVerts() const;
+ int getReserveIndexes() const;
+
+ const Vertex * getVertexPointer() const;
+ const GL_INDEX_TYPE * getIndexPointer() const;
+
+ static const int MIN_VERTEXES;
+ static const int MIN_INDEXES;
+
+private:
+ void grow();
+
+ int m_NumVerts;
+ int m_NumIndexes;
+ int m_ReserveVerts;
+ int m_ReserveIndexes;
+ Vertex * m_pVertexData;
+ GL_INDEX_TYPE * m_pIndexData;
+
+ bool m_bDataChanged;
+};
+
+std::ostream& operator<<(std::ostream& os, const Vertex& v);
+
+}
+
+#endif
diff --git a/src/graphics/WGLContext.cpp b/src/graphics/WGLContext.cpp
new file mode 100644
index 0000000..865f11f
--- /dev/null
+++ b/src/graphics/WGLContext.cpp
@@ -0,0 +1,184 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "WGLContext.h"
+
+#include "../base/Exception.h"
+#include "../base/Logger.h"
+
+#include <SDL/SDL.h>
+#undef WIN32_LEAN_AND_MEAN
+#include <SDL/SDL_syswm.h>
+
+#include <iostream>
+
+
+namespace avg {
+
+using namespace std;
+using namespace boost;
+
+LONG WINAPI imagingWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ return DefWindowProc(hwnd, msg, wParam, lParam);
+}
+
+void registerWindowClass()
+{
+ static char * pClassName;
+ if (pClassName) {
+ return;
+ }
+ pClassName = "GL";
+
+ HINSTANCE hInstance = GetModuleHandle(NULL);
+ WNDCLASS wc;
+ memset(&wc, 0, sizeof(WNDCLASS));
+ wc.style = CS_OWNDC;
+ wc.lpfnWndProc = (WNDPROC)imagingWindowProc;
+ wc.hInstance = hInstance;
+ wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);
+ wc.hCursor = LoadCursor(hInstance, IDC_ARROW);
+ wc.hbrBackground = NULL;
+ wc.lpszMenuName = NULL;
+ wc.lpszClassName = pClassName;
+
+ BOOL bOK = RegisterClass(&wc);
+ AVG_ASSERT(bOK);
+}
+
+WGLContext::WGLContext(const GLConfig& glConfig, const IntPoint& windowSize,
+ const SDL_SysWMinfo* pSDLWMInfo)
+ : GLContext(windowSize, pSDLWMInfo)
+{
+ bool bOwnsContext;
+ if (pSDLWMInfo) {
+ m_hDC = wglGetCurrentDC();
+ m_Context = wglGetCurrentContext();
+ setCurrent();
+ bOwnsContext = false;
+ } else {
+ registerWindowClass();
+ m_hwnd = CreateWindow("GL", "GL",
+ WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
+ 0, 0, 500, 300, 0, 0, GetModuleHandle(NULL), 0);
+ checkWinError(m_hwnd != 0, "CreateWindow");
+
+ m_hDC = GetDC(m_hwnd);
+ checkWinError(m_hDC != 0, "GetDC");
+
+ PIXELFORMATDESCRIPTOR pfd;
+ ZeroMemory(&pfd, sizeof(pfd));
+ pfd.nSize = sizeof(pfd);
+ pfd.nVersion = 1;
+ pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW;
+ pfd.iPixelType = PFD_TYPE_RGBA;
+ pfd.cColorBits = 32;
+ pfd.cDepthBits = 32;
+ pfd.iLayerType = PFD_MAIN_PLANE;
+
+ int iFormat = ChoosePixelFormat(m_hDC, &pfd);
+ checkWinError(iFormat != 0, "ChoosePixelFormat");
+ SetPixelFormat(m_hDC, iFormat, &pfd);
+ m_Context = wglCreateContext(m_hDC);
+ checkWinError(m_Context != 0, "wglCreateContext");
+ bOwnsContext = true;
+ }
+
+ init(glConfig, bOwnsContext);
+}
+
+WGLContext::~WGLContext()
+{
+ deleteObjects();
+ if (m_Context && ownsContext()) {
+ wglDeleteContext(m_Context);
+ DeleteDC(m_hDC);
+ DestroyWindow(m_hwnd);
+ }
+}
+
+void WGLContext::activate()
+{
+ BOOL bOk = wglMakeCurrent(m_hDC, m_Context);
+ checkWinError(bOk, "wglMakeCurrent");
+ setCurrent();
+}
+
+bool WGLContext::initVBlank(int rate)
+{
+ static bool s_bVBlankActive = false;
+ if (rate > 0) {
+ if (!queryOGLExtension("WGL_EXT_swap_control")
+ && !queryWGLExtension("WGL_EXT_swap_control")) {
+ AVG_LOG_WARNING(
+ "Windows VBlank setup failed: OpenGL Extension not supported.");
+ s_bVBlankActive = false;
+ return false;
+ }
+ glproc::SwapIntervalEXT(rate);
+ s_bVBlankActive = true;
+ return true;
+ } else {
+ if (s_bVBlankActive) {
+ glproc::SwapIntervalEXT(0);
+ s_bVBlankActive = false;
+ }
+ return false;
+ }
+}
+
+bool WGLContext::queryWGLExtension(const char *extName)
+{
+ if (glproc::GetExtensionsStringARB == NULL) {
+ return false;
+ }
+
+ char *p;
+ size_t extNameLen = strlen(extName);
+
+ p = (char *)glproc::GetExtensionsStringARB(m_hDC);
+ AVG_ASSERT(p != 0);
+ char * end = p + strlen(p);
+
+ while (p < end) {
+ size_t n = strcspn(p, " ");
+ if ((extNameLen == n) && (strncmp(extName, p, n) == 0)) {
+ return true;
+ }
+ p += (n + 1);
+ }
+ return false;
+}
+
+void WGLContext::checkWinError(BOOL bOK, const string& sWhere)
+{
+ if (!bOK) {
+ char szErr[512];
+ FormatMessage((FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM),
+ 0, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ szErr, 512, 0);
+ AVG_LOG_ERROR(sWhere+":"+szErr);
+ AVG_ASSERT(false);
+ }
+}
+
+}
diff --git a/src/graphics/WGLContext.h b/src/graphics/WGLContext.h
new file mode 100644
index 0000000..073d387
--- /dev/null
+++ b/src/graphics/WGLContext.h
@@ -0,0 +1,56 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+#ifndef _WGLContext_H_
+#define _WGLContext_H_
+#include "../api.h"
+
+#include "GLContext.h"
+
+#include <boost/shared_ptr.hpp>
+
+struct SDL_SysWMinfo;
+
+namespace avg {
+
+class AVG_API WGLContext: public GLContext
+{
+public:
+ WGLContext(const GLConfig& glConfig, const IntPoint& windowSize=IntPoint(0,0),
+ const SDL_SysWMinfo* pSDLWMInfo=0);
+ virtual ~WGLContext();
+
+ void activate();
+
+ bool initVBlank(int rate);
+
+private:
+ bool queryWGLExtension(const char* extName);
+ void checkWinError(BOOL bOK, const std::string& sWhere);
+
+ HWND m_hwnd;
+ HDC m_hDC;
+ HGLRC m_Context;
+};
+
+}
+#endif
+
+
diff --git a/src/graphics/WinDisplay.cpp b/src/graphics/WinDisplay.cpp
new file mode 100644
index 0000000..6388dd0
--- /dev/null
+++ b/src/graphics/WinDisplay.cpp
@@ -0,0 +1,61 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "WinDisplay.h"
+
+#include <windows.h>
+
+using namespace std;
+
+namespace avg {
+
+
+
+WinDisplay::WinDisplay()
+{
+}
+
+WinDisplay::~WinDisplay()
+{
+}
+
+
+
+float WinDisplay::queryPPMM()
+{
+ HDC hdc = CreateDC("DISPLAY", NULL, NULL, NULL);
+ return GetDeviceCaps(hdc, LOGPIXELSX)/25.4f;
+}
+
+float WinDisplay::queryRefreshRate()
+{
+ float refreshRate;
+ // This isn't correct for multi-monitor systems.
+ HDC hDC = CreateDC("DISPLAY", NULL, NULL, NULL);
+ refreshRate = float(GetDeviceCaps(hDC, VREFRESH));
+ if (refreshRate < 2) {
+ refreshRate = 60;
+ }
+ DeleteDC(hDC);
+ return refreshRate;
+}
+
+}
diff --git a/src/graphics/WinDisplay.h b/src/graphics/WinDisplay.h
new file mode 100644
index 0000000..debb2ca
--- /dev/null
+++ b/src/graphics/WinDisplay.h
@@ -0,0 +1,45 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _WinDisplay_H_
+#define _WinDisplay_H_
+
+#include "../api.h"
+#include "../avgconfigwrapper.h"
+
+#include "Display.h"
+
+namespace avg {
+
+class AVG_API WinDisplay: public Display
+{
+public:
+ WinDisplay();
+ virtual ~WinDisplay();
+
+protected:
+ virtual float queryPPMM();
+ virtual float queryRefreshRate();
+};
+
+}
+
+#endif
diff --git a/src/graphics/X11Display.cpp b/src/graphics/X11Display.cpp
new file mode 100644
index 0000000..b6a3510
--- /dev/null
+++ b/src/graphics/X11Display.cpp
@@ -0,0 +1,124 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "X11Display.h"
+
+#include "../base/Exception.h"
+#include "../base/Logger.h"
+
+#include <SDL/SDL.h>
+#include <SDL/SDL_syswm.h>
+
+#include <boost/math/special_functions/fpclassify.hpp>
+
+
+namespace avg {
+
+X11Display::X11Display()
+{
+}
+
+X11Display::~X11Display()
+{
+}
+
+float X11Display::queryPPMM()
+{
+ ::Display * pDisplay = XOpenDisplay(0);
+ float ppmm = getScreenResolution().x/float(DisplayWidthMM(pDisplay, 0));
+ XCloseDisplay(pDisplay);
+ return ppmm;
+}
+
+IntPoint X11Display::queryScreenResolution()
+{
+ IntPoint size;
+ // Xinerama query has been removed from here in order to fix #431
+ ::Display * pDisplay = XOpenDisplay(0);
+
+ Screen* pScreen = DefaultScreenOfDisplay(pDisplay);
+ AVG_ASSERT(pScreen);
+ size = IntPoint(pScreen->width, pScreen->height);
+
+ XCloseDisplay(pDisplay);
+ return size;
+}
+
+float X11Display::queryRefreshRate()
+{
+ ::Display * pDisplay = XOpenDisplay(0);
+ int pixelClock;
+ XF86VidModeModeLine modeLine;
+ bool bOK = XF86VidModeGetModeLine(pDisplay, DefaultScreen(pDisplay),
+ &pixelClock, &modeLine);
+ if (!bOK) {
+ AVG_LOG_WARNING(
+ "Could not get current refresh rate (XF86VidModeGetModeLine failed).");
+ AVG_LOG_WARNING("Defaulting to 60 Hz refresh rate.");
+ return 60;
+ }
+ float hSyncRate = (pixelClock * 1000.0) / modeLine.htotal;
+ float refreshRate = hSyncRate / modeLine.vtotal;
+ XCloseDisplay(pDisplay);
+ if ( refreshRate < 20 || refreshRate > 200 || !(boost::math::isnormal(refreshRate))){
+ AVG_LOG_WARNING("Could not get valid refresh rate");
+ AVG_LOG_WARNING("Defaulting to 60 Hz refresh rate.");
+ return 60;
+ }
+ return refreshRate;
+}
+
+::Display* getX11Display(const SDL_SysWMinfo* pSDLWMInfo)
+{
+ ::Display* pDisplay;
+ if (pSDLWMInfo) {
+ // SDL window exists, use it.
+ pDisplay = pSDLWMInfo->info.x11.display;
+ } else {
+ pDisplay = XOpenDisplay(0);
+ }
+ if (!pDisplay) {
+ throw Exception(AVG_ERR_VIDEO_GENERAL, "No X windows display available.");
+ }
+ return pDisplay;
+}
+
+Window createChildWindow(const SDL_SysWMinfo* pSDLWMInfo, XVisualInfo* pVisualInfo,
+ const IntPoint& windowSize, Colormap& colormap)
+
+{
+ // Create a child window with the required attributes to render into.
+ XSetWindowAttributes swa;
+ ::Display* pDisplay = pSDLWMInfo->info.x11.display;
+ colormap = XCreateColormap(pDisplay, RootWindow(pDisplay, pVisualInfo->screen),
+ pVisualInfo->visual, AllocNone);
+ swa.colormap = colormap;
+ swa.background_pixmap = None;
+ swa.event_mask = StructureNotifyMask;
+ Window win = XCreateWindow(pDisplay, pSDLWMInfo->info.x11.window,
+ 0, 0, windowSize.x, windowSize.y, 0, pVisualInfo->depth, InputOutput,
+ pVisualInfo->visual, CWColormap|CWEventMask, &swa);
+ AVG_ASSERT(win);
+ XMapWindow(pDisplay, win);
+ return win;
+}
+
+}
diff --git a/src/graphics/X11Display.h b/src/graphics/X11Display.h
new file mode 100644
index 0000000..50de9cc
--- /dev/null
+++ b/src/graphics/X11Display.h
@@ -0,0 +1,59 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+#ifndef _X11Display_H_
+#define _X11Display_H_
+#include "../api.h"
+
+#include "Display.h"
+
+#include "../base/GLMHelper.h"
+
+#include "OGLHelper.h"
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/extensions/xf86vmode.h>
+
+struct SDL_SysWMinfo;
+
+namespace avg {
+
+class AVG_API X11Display: public Display
+{
+public:
+ X11Display();
+ virtual ~X11Display();
+
+protected:
+ virtual float queryPPMM();
+ virtual IntPoint queryScreenResolution();
+ virtual float queryRefreshRate();
+};
+
+::Display* getX11Display(const SDL_SysWMinfo* pSDLWMInfo);
+
+Window createChildWindow(const SDL_SysWMinfo* pSDLWMInfo, XVisualInfo* pVisualInfo,
+ const IntPoint& windowSize, Colormap& colormap);
+
+}
+#endif
+
+
diff --git a/src/graphics/baseline/BandpassResult.png b/src/graphics/baseline/BandpassResult.png
new file mode 100644
index 0000000..d931127
--- /dev/null
+++ b/src/graphics/baseline/BandpassResult.png
Binary files differ
diff --git a/src/graphics/baseline/BlurResult.png b/src/graphics/baseline/BlurResult.png
new file mode 100644
index 0000000..2875491
--- /dev/null
+++ b/src/graphics/baseline/BlurResult.png
Binary files differ
diff --git a/src/graphics/baseline/ChromaKeyMedianResult.png b/src/graphics/baseline/ChromaKeyMedianResult.png
new file mode 100644
index 0000000..3de9221
--- /dev/null
+++ b/src/graphics/baseline/ChromaKeyMedianResult.png
Binary files differ
diff --git a/src/graphics/baseline/ChromaKeyResult0.png b/src/graphics/baseline/ChromaKeyResult0.png
new file mode 100644
index 0000000..e78bd88
--- /dev/null
+++ b/src/graphics/baseline/ChromaKeyResult0.png
Binary files differ
diff --git a/src/graphics/baseline/ChromaKeyResult1.png b/src/graphics/baseline/ChromaKeyResult1.png
new file mode 100644
index 0000000..79e6be9
--- /dev/null
+++ b/src/graphics/baseline/ChromaKeyResult1.png
Binary files differ
diff --git a/src/graphics/baseline/ChromaKeyResult2.png b/src/graphics/baseline/ChromaKeyResult2.png
new file mode 100644
index 0000000..4c08c24
--- /dev/null
+++ b/src/graphics/baseline/ChromaKeyResult2.png
Binary files differ
diff --git a/src/graphics/baseline/ChromaKeySpillResult1.png b/src/graphics/baseline/ChromaKeySpillResult1.png
new file mode 100644
index 0000000..bbafa78
--- /dev/null
+++ b/src/graphics/baseline/ChromaKeySpillResult1.png
Binary files differ
diff --git a/src/graphics/baseline/ChromaKeySpillResult2.png b/src/graphics/baseline/ChromaKeySpillResult2.png
new file mode 100644
index 0000000..71b65cf
--- /dev/null
+++ b/src/graphics/baseline/ChromaKeySpillResult2.png
Binary files differ
diff --git a/src/graphics/baseline/ChromaKeySpillResult3.png b/src/graphics/baseline/ChromaKeySpillResult3.png
new file mode 100644
index 0000000..65f7ab7
--- /dev/null
+++ b/src/graphics/baseline/ChromaKeySpillResult3.png
Binary files differ
diff --git a/src/graphics/baseline/DilationResult.png b/src/graphics/baseline/DilationResult.png
new file mode 100644
index 0000000..bfa45d8
--- /dev/null
+++ b/src/graphics/baseline/DilationResult.png
Binary files differ
diff --git a/src/graphics/baseline/ErosionResult.png b/src/graphics/baseline/ErosionResult.png
new file mode 100644
index 0000000..5b8042d
--- /dev/null
+++ b/src/graphics/baseline/ErosionResult.png
Binary files differ
diff --git a/src/graphics/baseline/FastBandpassResult.png b/src/graphics/baseline/FastBandpassResult.png
new file mode 100644
index 0000000..048e358
--- /dev/null
+++ b/src/graphics/baseline/FastBandpassResult.png
Binary files differ
diff --git a/src/graphics/baseline/FastDownscaleResult.png b/src/graphics/baseline/FastDownscaleResult.png
new file mode 100644
index 0000000..bf11cf6
--- /dev/null
+++ b/src/graphics/baseline/FastDownscaleResult.png
Binary files differ
diff --git a/src/graphics/baseline/FloodfillResult.png b/src/graphics/baseline/FloodfillResult.png
new file mode 100644
index 0000000..2a6fd14
--- /dev/null
+++ b/src/graphics/baseline/FloodfillResult.png
Binary files differ
diff --git a/src/graphics/baseline/Gauss15Result.png b/src/graphics/baseline/Gauss15Result.png
new file mode 100644
index 0000000..6d90b6e
--- /dev/null
+++ b/src/graphics/baseline/Gauss15Result.png
Binary files differ
diff --git a/src/graphics/baseline/Gauss1Result.png b/src/graphics/baseline/Gauss1Result.png
new file mode 100644
index 0000000..595fd37
--- /dev/null
+++ b/src/graphics/baseline/Gauss1Result.png
Binary files differ
diff --git a/src/graphics/baseline/Gauss3Result.png b/src/graphics/baseline/Gauss3Result.png
new file mode 100644
index 0000000..7e07df3
--- /dev/null
+++ b/src/graphics/baseline/Gauss3Result.png
Binary files differ
diff --git a/src/graphics/baseline/Gauss5Result.png b/src/graphics/baseline/Gauss5Result.png
new file mode 100644
index 0000000..2e9693d
--- /dev/null
+++ b/src/graphics/baseline/Gauss5Result.png
Binary files differ
diff --git a/src/graphics/baseline/GetAlphaResult.png b/src/graphics/baseline/GetAlphaResult.png
new file mode 100644
index 0000000..1b5d9bf
--- /dev/null
+++ b/src/graphics/baseline/GetAlphaResult.png
Binary files differ
diff --git a/src/graphics/baseline/HighpassResult.png b/src/graphics/baseline/HighpassResult.png
new file mode 100644
index 0000000..dd84a51
--- /dev/null
+++ b/src/graphics/baseline/HighpassResult.png
Binary files differ
diff --git a/src/graphics/baseline/HslColorizeResult0.png b/src/graphics/baseline/HslColorizeResult0.png
new file mode 100644
index 0000000..adc6596
--- /dev/null
+++ b/src/graphics/baseline/HslColorizeResult0.png
Binary files differ
diff --git a/src/graphics/baseline/HslColorizeResult1.png b/src/graphics/baseline/HslColorizeResult1.png
new file mode 100644
index 0000000..51ead87
--- /dev/null
+++ b/src/graphics/baseline/HslColorizeResult1.png
Binary files differ
diff --git a/src/graphics/baseline/HslColorizeResult2.png b/src/graphics/baseline/HslColorizeResult2.png
new file mode 100644
index 0000000..02c9b0a
--- /dev/null
+++ b/src/graphics/baseline/HslColorizeResult2.png
Binary files differ
diff --git a/src/graphics/baseline/HslHueResult0.png b/src/graphics/baseline/HslHueResult0.png
new file mode 100644
index 0000000..9621451
--- /dev/null
+++ b/src/graphics/baseline/HslHueResult0.png
Binary files differ
diff --git a/src/graphics/baseline/HslHueResult1.png b/src/graphics/baseline/HslHueResult1.png
new file mode 100644
index 0000000..ac2e3f8
--- /dev/null
+++ b/src/graphics/baseline/HslHueResult1.png
Binary files differ
diff --git a/src/graphics/baseline/HslHueResult2.png b/src/graphics/baseline/HslHueResult2.png
new file mode 100644
index 0000000..015d3b3
--- /dev/null
+++ b/src/graphics/baseline/HslHueResult2.png
Binary files differ
diff --git a/src/graphics/baseline/LineResultB8G8R8.png b/src/graphics/baseline/LineResultB8G8R8.png
new file mode 100644
index 0000000..0b49fba
--- /dev/null
+++ b/src/graphics/baseline/LineResultB8G8R8.png
Binary files differ
diff --git a/src/graphics/baseline/LineResultB8G8R8A8.png b/src/graphics/baseline/LineResultB8G8R8A8.png
new file mode 100644
index 0000000..198295a
--- /dev/null
+++ b/src/graphics/baseline/LineResultB8G8R8A8.png
Binary files differ
diff --git a/src/graphics/baseline/LineResultI8.png b/src/graphics/baseline/LineResultI8.png
new file mode 100644
index 0000000..f6756a1
--- /dev/null
+++ b/src/graphics/baseline/LineResultI8.png
Binary files differ
diff --git a/src/graphics/baseline/MaskResultB8G8R8.png b/src/graphics/baseline/MaskResultB8G8R8.png
new file mode 100644
index 0000000..308dc09
--- /dev/null
+++ b/src/graphics/baseline/MaskResultB8G8R8.png
Binary files differ
diff --git a/src/graphics/baseline/MaskResultB8G8R8X8.png b/src/graphics/baseline/MaskResultB8G8R8X8.png
new file mode 100644
index 0000000..308dc09
--- /dev/null
+++ b/src/graphics/baseline/MaskResultB8G8R8X8.png
Binary files differ
diff --git a/src/graphics/baseline/MaskResultI8.png b/src/graphics/baseline/MaskResultI8.png
new file mode 100644
index 0000000..2e00267
--- /dev/null
+++ b/src/graphics/baseline/MaskResultI8.png
Binary files differ
diff --git a/src/graphics/baseline/ResizeBilinearResultB8G8R8.png b/src/graphics/baseline/ResizeBilinearResultB8G8R8.png
new file mode 100644
index 0000000..6a1d7b7
--- /dev/null
+++ b/src/graphics/baseline/ResizeBilinearResultB8G8R8.png
Binary files differ
diff --git a/src/graphics/baseline/ResizeBilinearResultB8G8R8A8.png b/src/graphics/baseline/ResizeBilinearResultB8G8R8A8.png
new file mode 100644
index 0000000..8a536aa
--- /dev/null
+++ b/src/graphics/baseline/ResizeBilinearResultB8G8R8A8.png
Binary files differ
diff --git a/src/graphics/baseline/ResizeBilinearResultB8G8R8X8.png b/src/graphics/baseline/ResizeBilinearResultB8G8R8X8.png
new file mode 100644
index 0000000..8debdce
--- /dev/null
+++ b/src/graphics/baseline/ResizeBilinearResultB8G8R8X8.png
Binary files differ
diff --git a/src/graphics/baseline/ThresholdResult.png b/src/graphics/baseline/ThresholdResult.png
new file mode 100644
index 0000000..afd19c4
--- /dev/null
+++ b/src/graphics/baseline/ThresholdResult.png
Binary files differ
diff --git a/src/graphics/baseline/YUV2RGBResult1.png b/src/graphics/baseline/YUV2RGBResult1.png
new file mode 100644
index 0000000..5e4821c
--- /dev/null
+++ b/src/graphics/baseline/YUV2RGBResult1.png
Binary files differ
diff --git a/src/graphics/baseline/bandpass_i8-64x64.png b/src/graphics/baseline/bandpass_i8-64x64.png
new file mode 100644
index 0000000..ffa4953
--- /dev/null
+++ b/src/graphics/baseline/bandpass_i8-64x64.png
Binary files differ
diff --git a/src/graphics/baseline/bandpass_spike.png b/src/graphics/baseline/bandpass_spike.png
new file mode 100644
index 0000000..00048ae
--- /dev/null
+++ b/src/graphics/baseline/bandpass_spike.png
Binary files differ
diff --git a/src/graphics/baseline/blur05_flat.png b/src/graphics/baseline/blur05_flat.png
new file mode 100644
index 0000000..79c5ff8
--- /dev/null
+++ b/src/graphics/baseline/blur05_flat.png
Binary files differ
diff --git a/src/graphics/baseline/blur05_spike.png b/src/graphics/baseline/blur05_spike.png
new file mode 100644
index 0000000..1bb2eb9
--- /dev/null
+++ b/src/graphics/baseline/blur05_spike.png
Binary files differ
diff --git a/src/graphics/baseline/blur1_spike.png b/src/graphics/baseline/blur1_spike.png
new file mode 100644
index 0000000..3446bcc
--- /dev/null
+++ b/src/graphics/baseline/blur1_spike.png
Binary files differ
diff --git a/src/graphics/baseline/blur3_spike.png b/src/graphics/baseline/blur3_spike.png
new file mode 100644
index 0000000..e0dd5ee
--- /dev/null
+++ b/src/graphics/baseline/blur3_spike.png
Binary files differ
diff --git a/src/graphics/baseline/blur_rgb24-64x64.png b/src/graphics/baseline/blur_rgb24-64x64.png
new file mode 100644
index 0000000..1114b79
--- /dev/null
+++ b/src/graphics/baseline/blur_rgb24-64x64.png
Binary files differ
diff --git a/src/graphics/baseline/blur_rgb24alpha-64x64.png b/src/graphics/baseline/blur_rgb24alpha-64x64.png
new file mode 100644
index 0000000..24c9687
--- /dev/null
+++ b/src/graphics/baseline/blur_rgb24alpha-64x64.png
Binary files differ
diff --git a/src/graphics/baseline/copyPixels_B8G8R8X8_I8.png b/src/graphics/baseline/copyPixels_B8G8R8X8_I8.png
new file mode 100644
index 0000000..59d5c74
--- /dev/null
+++ b/src/graphics/baseline/copyPixels_B8G8R8X8_I8.png
Binary files differ
diff --git a/src/graphics/baseline/copyPixels_R8G8B8X8_I8.png b/src/graphics/baseline/copyPixels_R8G8B8X8_I8.png
new file mode 100644
index 0000000..a59d0bf
--- /dev/null
+++ b/src/graphics/baseline/copyPixels_R8G8B8X8_I8.png
Binary files differ
diff --git a/src/graphics/baseline/invert_rgb24-64x64.png b/src/graphics/baseline/invert_rgb24-64x64.png
new file mode 100644
index 0000000..7e05dc2
--- /dev/null
+++ b/src/graphics/baseline/invert_rgb24-64x64.png
Binary files differ
diff --git a/src/graphics/benchmarkgraphics.cpp b/src/graphics/benchmarkgraphics.cpp
new file mode 100644
index 0000000..8520033
--- /dev/null
+++ b/src/graphics/benchmarkgraphics.cpp
@@ -0,0 +1,255 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+
+#include "Bitmap.h"
+#include "BitmapLoader.h"
+#include "Pixel32.h"
+#include "Pixel24.h"
+#include "Pixel16.h"
+#include "Filtergrayscale.h"
+#include "Filterfill.h"
+#include "Filterflip.h"
+#include "Filterfliprgb.h"
+#include "Filterflipuv.h"
+#include "Filter3x3.h"
+#include "FilterConvol.h"
+#include "HistoryPreProcessor.h"
+#include "FilterHighpass.h"
+#include "FilterGauss.h"
+#include "FilterBlur.h"
+#include "FilterBandpass.h"
+
+#include "../base/TimeSource.h"
+
+#include <iostream>
+#include <stdio.h>
+#include <stdlib.h>
+
+using namespace avg;
+using namespace std;
+
+template<class TEST>
+void runPerformanceTest(int numRuns=500)
+{
+ TEST PerfTest;
+ long long StartTime = TimeSource::get()->getCurrentMicrosecs();
+ for (int i = 0; i < numRuns; ++i) {
+ PerfTest.run();
+ }
+ float ActiveTime = (TimeSource::get()->getCurrentMicrosecs()-StartTime)/1000.;
+ cerr << PerfTest.getName() << ": " << ActiveTime/numRuns << " ms" << endl;
+
+}
+
+class PerfTestBase {
+public:
+ PerfTestBase(string sName)
+ : m_sName(sName)
+ {
+ }
+
+ std::string getName()
+ {
+ return m_sName;
+ }
+
+private:
+ std::string m_sName;
+};
+
+class LoadPNGPerfTest: public PerfTestBase {
+public:
+ LoadPNGPerfTest()
+ : PerfTestBase("LoadPNGPerfTest")
+ {
+ }
+
+ void run()
+ {
+ BitmapPtr pBmp = loadBitmap("../test/media/rgb24alpha-64x64.png");
+ }
+};
+
+class FillI8PerfTest: public PerfTestBase {
+public:
+ FillI8PerfTest()
+ : PerfTestBase("FillI8PerfTest")
+ {
+ m_pBmp = BitmapPtr(new Bitmap(IntPoint(1024,1024), I8));
+ }
+
+ void run()
+ {
+ FilterFill<Pixel8> Filter = FilterFill<Pixel8>(Pixel8(0));
+ Filter.applyInPlace(m_pBmp);
+ }
+
+private:
+ BitmapPtr m_pBmp;
+};
+
+class FillRGBPerfTest: public PerfTestBase {
+public:
+ FillRGBPerfTest()
+ : PerfTestBase("FillRGBPerfTest")
+ {
+ m_pBmp = BitmapPtr(new Bitmap(IntPoint(1024,1024), R8G8B8));
+ }
+
+ void run()
+ {
+ FilterFill<Pixel24> Filter = FilterFill<Pixel24>(Pixel24(0,0,0));
+ Filter.applyInPlace(m_pBmp);
+ }
+
+private:
+ BitmapPtr m_pBmp;
+};
+
+class FillRGBAPerfTest: public PerfTestBase {
+public:
+ FillRGBAPerfTest()
+ : PerfTestBase("FillRGBAPerfTest")
+ {
+ m_pBmp = BitmapPtr(new Bitmap(IntPoint(1024,1024), R8G8B8A8));
+ }
+
+ void run()
+ {
+ FilterFill<Pixel32> Filter = FilterFill<Pixel32>(Pixel32(0,0,0,0));
+ Filter.applyInPlace(m_pBmp);
+ }
+
+private:
+ BitmapPtr m_pBmp;
+};
+
+class EqualityI8PerfTest: public PerfTestBase {
+public:
+ EqualityI8PerfTest()
+ : PerfTestBase("EqualityI8PerfTest")
+ {
+ m_pBmp = BitmapPtr(new Bitmap(IntPoint(1024,1024), I8));
+ }
+
+ void run()
+ {
+ Bitmap CopyBmp = *m_pBmp;
+ }
+
+private:
+ BitmapPtr m_pBmp;
+};
+
+class CopyI8PerfTest: public PerfTestBase {
+public:
+ CopyI8PerfTest()
+ : PerfTestBase("CopyI8PerfTest")
+ {
+ m_pBmp = BitmapPtr(new Bitmap(IntPoint(1024,1024), I8));
+ }
+
+ void run()
+ {
+ Bitmap CopyBmp(*m_pBmp);
+ }
+
+private:
+ BitmapPtr m_pBmp;
+};
+
+class CopyRGBPerfTest: public PerfTestBase {
+public:
+ CopyRGBPerfTest()
+ : PerfTestBase("CopyRGBPerfTest")
+ {
+ m_pBmp = BitmapPtr(new Bitmap(IntPoint(1024,1024), R8G8B8));
+ }
+
+ void run()
+ {
+ Bitmap CopyBmp(*m_pBmp);
+ }
+
+private:
+ BitmapPtr m_pBmp;
+};
+
+class CopyRGBAPerfTest: public PerfTestBase {
+public:
+ CopyRGBAPerfTest()
+ : PerfTestBase("CopyRGBAPerfTest")
+ {
+ m_pBmp = BitmapPtr(new Bitmap(IntPoint(1024,1024), R8G8B8A8));
+ }
+
+ void run()
+ {
+ Bitmap CopyBmp(*m_pBmp);
+ }
+
+private:
+ BitmapPtr m_pBmp;
+};
+
+class YUV2RGBPerfTest: public PerfTestBase {
+public:
+ YUV2RGBPerfTest()
+ : PerfTestBase("YUV2RGBPerfTest")
+ {
+ m_pYBmp = BitmapPtr(new Bitmap(IntPoint(1024, 1024), I8));
+ m_pUBmp = BitmapPtr(new Bitmap(IntPoint(512, 512), I8));
+ m_pVBmp = BitmapPtr(new Bitmap(IntPoint(512, 512), I8));
+ }
+
+ void run()
+ {
+ Bitmap RGBBmp(IntPoint(1024, 1024), B8G8R8X8);
+ RGBBmp.copyYUVPixels(*m_pYBmp, *m_pUBmp, *m_pVBmp, false);
+ }
+
+private:
+ BitmapPtr m_pYBmp;
+ BitmapPtr m_pUBmp;
+ BitmapPtr m_pVBmp;
+
+};
+
+void runPerformanceTests()
+{
+ runPerformanceTest<LoadPNGPerfTest>();
+ runPerformanceTest<FillI8PerfTest>();
+ runPerformanceTest<FillRGBPerfTest>();
+ runPerformanceTest<FillRGBAPerfTest>();
+ runPerformanceTest<EqualityI8PerfTest>();
+ runPerformanceTest<CopyI8PerfTest>();
+ runPerformanceTest<CopyRGBPerfTest>();
+ runPerformanceTest<CopyRGBAPerfTest>();
+ runPerformanceTest<YUV2RGBPerfTest>(200);
+}
+
+int main(int nargs, char** args)
+{
+ BitmapLoader::init(true);
+ runPerformanceTests();
+}
+
diff --git a/src/graphics/shaders/Makefile.am b/src/graphics/shaders/Makefile.am
new file mode 100644
index 0000000..f968ab0
--- /dev/null
+++ b/src/graphics/shaders/Makefile.am
@@ -0,0 +1,3 @@
+EXTRA_DIST = $(wildcard *.frag) $(wildcard *.vert)
+datadir = $(pkgpyexecdir)/shaders
+data_DATA = $(wildcard *.frag) $(wildcard *.vert)
diff --git a/src/graphics/shaders/bandpass.frag b/src/graphics/shaders/bandpass.frag
new file mode 100644
index 0000000..b52d1df
--- /dev/null
+++ b/src/graphics/shaders/bandpass.frag
@@ -0,0 +1,42 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2011 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+uniform sampler2D u_MinTex;
+uniform sampler2D u_MaxTex;
+uniform float u_PostScale;
+uniform bool u_bInvert;
+
+#ifndef FRAGMENT_ONLY
+varying vec2 v_TexCoord;
+varying vec4 v_Color;
+#endif
+
+void main(void)
+{
+ vec4 min = texture2D(u_MinTex, v_TexCoord);
+ vec4 max = texture2D(u_MaxTex, v_TexCoord);
+ gl_FragColor = vec4(0.502, 0.502, 0.502, 0) + (max-min)*u_PostScale;
+ if (u_bInvert) {
+ gl_FragColor = vec4(1.004,1.004,1.004,1) - gl_FragColor;
+ }
+ gl_FragColor.a = 1.0;
+}
+
diff --git a/src/graphics/shaders/brightness.frag b/src/graphics/shaders/brightness.frag
new file mode 100644
index 0000000..787c7ae
--- /dev/null
+++ b/src/graphics/shaders/brightness.frag
@@ -0,0 +1,35 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2011 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+uniform float u_Alpha;
+uniform sampler2D u_Texture;
+
+#ifndef FRAGMENT_ONLY
+varying vec2 v_TexCoord;
+varying vec4 v_Color;
+#endif
+
+void main(void)
+{
+ vec4 tex = texture2D(u_Texture, v_TexCoord);
+ gl_FragColor.rgb = tex.rgb*u_Alpha;
+ gl_FragColor.a = tex.a;
+}
diff --git a/src/graphics/shaders/chromakey.frag b/src/graphics/shaders/chromakey.frag
new file mode 100644
index 0000000..f1fecad
--- /dev/null
+++ b/src/graphics/shaders/chromakey.frag
@@ -0,0 +1,134 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2011 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+uniform sampler2D u_Texture;
+uniform float u_HKey;
+uniform float u_HTolerance;
+uniform float u_HSoftTolerance;
+uniform float u_SKey;
+uniform float u_STolerance;
+uniform float u_SSoftTolerance;
+uniform float u_LKey;
+uniform float u_LTolerance;
+uniform float u_LSoftTolerance;
+uniform float u_SpillThreshold;
+uniform bool u_bIsLast;
+
+#include "helper.frag"
+
+#ifndef FRAGMENT_ONLY
+varying vec2 v_TexCoord;
+varying vec4 v_Color;
+#endif
+
+vec4 alphaMin(vec4 v1, vec4 v2)
+{
+ if (v1.a < v2.a) {
+ return v1;
+ } else {
+ return v2;
+ }
+}
+
+vec4 alphaMax(vec4 v1, vec4 v2)
+{
+ if (v1.a < v2.a) {
+ return v2;
+ } else {
+ return v1;
+ }
+}
+
+#define s2(a, b) temp = a; a = alphaMin(a, b); b = alphaMax(temp, b);
+#define mn3(a, b, c) s2(a, b); s2(a, c);
+#define mx3(a, b, c) s2(b, c); s2(a, c);
+
+#define mnmx3(a, b, c) mx3(a, b, c); s2(a, b);
+#define mnmx4(a, b, c, d) s2(a, b); s2(c, d); s2(a, c); s2(b, d);
+
+// Based on McGuire, A fast, small-radius GPU median filter, in ShaderX6,
+// February 2008. http://graphics.cs.williams.edu/papers/MedianShaderX6/
+vec4 getMedian(vec2 texCoord)
+{
+ vec4 v[5];
+ float dx = dFdx(texCoord.x);
+ float dy = dFdy(texCoord.y);
+ v[0] = texture2D(u_Texture, texCoord);
+ v[1] = texture2D(u_Texture, texCoord+vec2(0,-dy));
+ v[2] = texture2D(u_Texture, texCoord+vec2(0,dy));
+ v[3] = texture2D(u_Texture, texCoord+vec2(-dx,0));
+ v[4] = texture2D(u_Texture, texCoord+vec2(dx,0));
+ for (int i = 0; i < 5; ++i) {
+ v[i].a = 0.2989 * v[i].r + 0.5870 * v[i].g + 0.1140 * v[i].b;
+ }
+
+ vec4 temp;
+ mnmx4(v[0], v[1], v[2], v[3]);
+ mnmx3(v[1], v[2], v[4]);
+ return v[2];
+}
+
+void main(void)
+{
+ vec4 tex = getMedian(v_TexCoord);
+ float h;
+ float s;
+ float l;
+ float alpha;
+ rgb2hsl(tex, h, s, l);
+ float hDiff = abs(h-u_HKey);
+ float sDiff = abs(s-u_SKey);
+ float lDiff = abs(l-u_LKey);
+ if (hDiff < u_HSoftTolerance && sDiff < u_SSoftTolerance
+ && lDiff < u_LSoftTolerance)
+ {
+ alpha = 0.0;
+ if (hDiff > u_HTolerance) {
+ alpha = (hDiff-u_HTolerance)/(u_HSoftTolerance-u_HTolerance);
+ }
+ if (sDiff > u_STolerance) {
+ alpha = max(alpha,
+ (sDiff-u_STolerance)/(u_SSoftTolerance-u_STolerance));
+ }
+ if (lDiff > u_LTolerance) {
+ alpha = max(alpha,
+ (lDiff-u_LTolerance)/(u_LSoftTolerance-u_LTolerance));
+ }
+ } else {
+ alpha = 1.0;
+ }
+ tex = texture2D(u_Texture, v_TexCoord);
+ if (alpha > 0.0 && hDiff < u_SpillThreshold) {
+ rgb2hsl(tex, h, s, l);
+ if (u_SpillThreshold > u_HTolerance) {
+ float factor = max(0.0, 1.0-(u_SpillThreshold-hDiff)
+ /(u_SpillThreshold-u_HTolerance));
+ s = s*factor;
+ }
+ tex.rgb = hsl2rgb(h, s, l);
+ }
+ if (u_bIsLast) {
+ gl_FragColor = vec4(tex.rgb*alpha, alpha);
+ } else {
+ gl_FragColor = vec4(tex.rgb, alpha);
+ }
+}
+
diff --git a/src/graphics/shaders/chromakey_erosion.frag b/src/graphics/shaders/chromakey_erosion.frag
new file mode 100644
index 0000000..485d141
--- /dev/null
+++ b/src/graphics/shaders/chromakey_erosion.frag
@@ -0,0 +1,47 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2011 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+uniform sampler2D u_Texture;
+uniform bool u_bIsLast;
+
+#ifndef FRAGMENT_ONLY
+varying vec2 v_TexCoord;
+varying vec4 v_Color;
+#endif
+
+void main(void)
+{
+ float minAlpha = 1.0;
+ float dx = dFdx(v_TexCoord.x);
+ float dy = dFdy(v_TexCoord.y);
+ for (float y = -1.0; y <= 1.0; ++y) {
+ for (float x = -1.0; x <= 1.0; ++x) {
+ float a = texture2D(u_Texture, v_TexCoord+vec2(x*dx,y*dy)).a;
+ minAlpha = min(minAlpha, a);
+ }
+ }
+ vec4 tex = texture2D(u_Texture, v_TexCoord);
+ if (u_bIsLast) {
+ gl_FragColor = vec4(tex.rgb*minAlpha, minAlpha);
+ } else {
+ gl_FragColor = vec4(tex.rgb, minAlpha);
+ }
+}
diff --git a/src/graphics/shaders/helper.frag b/src/graphics/shaders/helper.frag
new file mode 100644
index 0000000..9fdb59a
--- /dev/null
+++ b/src/graphics/shaders/helper.frag
@@ -0,0 +1,109 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2011 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+void unPreMultiplyAlpha(inout vec4 color)
+{
+ if (color.a > 0.0) {
+ color.rgb /= color.a;
+ }
+}
+
+void preMultiplyAlpha(inout vec4 color)
+{
+ color.rgb *= color.a;
+}
+
+void rgb2hsl(vec4 rgba, out float h, out float s, out float l)
+{
+ float maxComp = max(rgba.r, max(rgba.g, rgba.b));
+ float minComp = min(rgba.r, min(rgba.g, rgba.b));
+ l = (maxComp+minComp)/2.0;
+ if (maxComp == minComp) {
+ s = 0.0;
+ h = 0.0;
+ } else {
+ float delta = maxComp-minComp;
+ if (l < 0.5) {
+ s = delta/(maxComp+minComp);
+ } else {
+ s = delta/(2.0-(maxComp+minComp));
+ }
+ if (rgba.r == maxComp) {
+ h = (rgba.g-rgba.b)/delta;
+ if (h < 0.0) {
+ h += 6.0;
+ }
+ } else if (rgba.g == maxComp) {
+ h = 2.0+(rgba.b-rgba.r)/delta;
+ } else {
+ h = 4.0+(rgba.r-rgba.g)/delta;
+ }
+ h *= 60.0;
+ }
+}
+
+vec3 hsl2rgb(float h, float s, float l)
+{
+ vec3 rgb = vec3(0.0, 0.0, 0.0);
+ float v;
+ if (l <= 0.5) {
+ v = l*(1.0+s);
+ } else {
+ v = l+s-l*s;
+ }
+ if (v > 0.0) {
+ float m = 2.0*l-v;
+ float sv = (v-m)/v;
+ h /= 60.0;
+ int sextant = int(h);
+ float fract = h-float(sextant);
+ float vsf = v * sv * fract;
+ float mid1 = m + vsf;
+ float mid2 = v - vsf;
+ if (sextant == 0) {
+ rgb.r = v;
+ rgb.g = mid1;
+ rgb.b = m;
+ } else if (sextant == 1) {
+ rgb.r = mid2;
+ rgb.g = v;
+ rgb.b = m;
+ } else if (sextant == 2) {
+ rgb.r = m;
+ rgb.g = v;
+ rgb.b = mid1;
+ } else if (sextant == 3) {
+ rgb.r = m;
+ rgb.g = mid2;
+ rgb.b = v;
+ } else if (sextant == 4) {
+ rgb.r = mid1;
+ rgb.g = m;
+ rgb.b = v;
+ } else if (sextant == 5) {
+ rgb.r = v;
+ rgb.g = m;
+ rgb.b = mid2;
+ }
+ }
+ return rgb;
+}
+
diff --git a/src/graphics/shaders/horizblur.frag b/src/graphics/shaders/horizblur.frag
new file mode 100644
index 0000000..fa78b21
--- /dev/null
+++ b/src/graphics/shaders/horizblur.frag
@@ -0,0 +1,43 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2011 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+uniform sampler2D u_Texture;
+uniform float u_Width;
+uniform int u_Radius;
+uniform sampler2D u_KernelTex;
+
+#ifndef FRAGMENT_ONLY
+varying vec2 v_TexCoord;
+varying vec4 v_Color;
+#endif
+
+void main(void)
+{
+ vec4 sum = vec4(0,0,0,0);
+ float dx = dFdx(v_TexCoord.x);
+ for (int i=-u_Radius; i<=u_Radius; ++i) {
+ vec4 tex = texture2D(u_Texture, v_TexCoord+vec2(float(i)*dx,0));
+ float coeff = texture2D(u_KernelTex, vec2((float(i+u_Radius)+0.5)/u_Width,0)).r;
+ sum += tex*coeff;
+ }
+ gl_FragColor = sum;
+}
+
diff --git a/src/graphics/shaders/horizshadow.frag b/src/graphics/shaders/horizshadow.frag
new file mode 100644
index 0000000..c9e512d
--- /dev/null
+++ b/src/graphics/shaders/horizshadow.frag
@@ -0,0 +1,44 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2011 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+uniform float u_Width;
+uniform int u_Radius;
+uniform sampler2D u_KernelTex;
+uniform sampler2D u_Texture;
+uniform vec2 u_Offset;
+
+#ifndef FRAGMENT_ONLY
+varying vec2 v_TexCoord;
+varying vec4 v_Color;
+#endif
+
+void main(void)
+{
+ float sum = 0.;
+ float dx = dFdx(v_TexCoord.x);
+ for (int i=-u_Radius; i<=u_Radius; ++i) {
+ float a = texture2D(u_Texture,
+ v_TexCoord-u_Offset+vec2(float(i)*dx,0)).a;
+ float coeff = texture2D(u_KernelTex, vec2((float(i+u_Radius)+0.5)/u_Width,0)).r;
+ sum += a*coeff;
+ }
+ gl_FragColor = vec4(sum, sum, sum, sum);
+}
diff --git a/src/graphics/shaders/huesat.frag b/src/graphics/shaders/huesat.frag
new file mode 100644
index 0000000..381b5b2
--- /dev/null
+++ b/src/graphics/shaders/huesat.frag
@@ -0,0 +1,72 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2011 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+const vec3 lumCoeff = vec3(0.2125, 0.7154, 0.0721);
+const vec3 white = vec3(1.0, 1.0, 1.0);
+const vec3 black = vec3(0.0, 0.0, 0.0);
+
+uniform sampler2D u_Texture;
+uniform float u_Hue;
+uniform float u_Sat;
+uniform float u_LightnessOffset;
+uniform bool u_bColorize;
+
+#ifndef FRAGMENT_ONLY
+varying vec2 v_TexCoord;
+varying vec4 v_Color;
+#endif
+
+#include "helper.frag"
+
+void main(void)
+{
+ float tmp;
+ float s;
+ float l;
+ float h;
+ vec4 tex = texture2D(u_Texture, v_TexCoord);
+ unPreMultiplyAlpha(tex);
+ rgb2hsl(tex, tmp, s, l);
+ if (u_bColorize) {
+ h = u_Hue;
+ s = u_Sat;
+ } else {
+ h = u_Hue+tmp;
+ }
+ vec4 rgbTex = vec4(hsl2rgb(mod(h, 360.0), s, l), tex.a);
+
+ // Saturate in rgb - space to imitate photoshop filter
+ if (!u_bColorize) {
+ s = clamp(u_Sat+s, 0.0, 2.0);
+ vec3 intensity = vec3(dot(rgbTex.rgb, lumCoeff));
+ rgbTex.rgb = mix(intensity, rgbTex.rgb, s);
+ }
+
+ // Brightness with black/white pixels to imitate photoshop lightness-offset
+ if (u_LightnessOffset >= 0.0) {
+ rgbTex = vec4(mix(rgbTex.rgb, white, u_LightnessOffset), tex.a);
+ } else if (u_LightnessOffset < 0.0) {
+ rgbTex = vec4(mix(rgbTex.rgb, black, -u_LightnessOffset), tex.a);
+ }
+
+ preMultiplyAlpha(rgbTex);
+ gl_FragColor = rgbTex;
+}
diff --git a/src/graphics/shaders/invert.frag b/src/graphics/shaders/invert.frag
new file mode 100644
index 0000000..36f49c7
--- /dev/null
+++ b/src/graphics/shaders/invert.frag
@@ -0,0 +1,41 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2011 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+uniform sampler2D u_Texture;
+
+#include "helper.frag"
+
+#ifndef FRAGMENT_ONLY
+varying vec2 v_TexCoord;
+varying vec4 v_Color;
+#endif
+
+void main(void)
+{
+ float hue, s, l;
+ vec4 tex = texture2D(u_Texture, v_TexCoord);
+ unPreMultiplyAlpha(tex);
+ rgb2hsl(tex, hue, s, l);
+ vec4 result = vec4(hsl2rgb(hue, s, 1.0-l), tex.a);
+ preMultiplyAlpha(result);
+ gl_FragColor = result;
+}
+
diff --git a/src/graphics/shaders/minimal.frag b/src/graphics/shaders/minimal.frag
new file mode 100644
index 0000000..acfbf2d
--- /dev/null
+++ b/src/graphics/shaders/minimal.frag
@@ -0,0 +1,37 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2011 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+uniform sampler2D u_Texture;
+uniform float u_Alpha;
+
+#ifndef FRAGMENT_ONLY
+varying vec2 v_TexCoord;
+varying vec4 v_Color;
+#endif
+
+// A minimal shader for use on low-end systems where the standard shader hurts
+// performance.
+void main(void)
+{
+ vec4 rgba = texture2D(u_Texture, v_TexCoord);
+ rgba.a *= u_Alpha;
+ gl_FragColor = rgba;
+}
diff --git a/src/graphics/shaders/null.frag b/src/graphics/shaders/null.frag
new file mode 100644
index 0000000..30b2627
--- /dev/null
+++ b/src/graphics/shaders/null.frag
@@ -0,0 +1,33 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2011 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+uniform sampler2D u_Texture;
+
+#ifndef FRAGMENT_ONLY
+varying vec2 v_TexCoord;
+varying vec4 v_Color;
+#endif
+
+void main(void)
+{
+ vec4 tex = texture2D(u_Texture, v_TexCoord);
+ gl_FragColor = tex;
+}
diff --git a/src/graphics/shaders/rgb2yuv.frag b/src/graphics/shaders/rgb2yuv.frag
new file mode 100644
index 0000000..351d3b2
--- /dev/null
+++ b/src/graphics/shaders/rgb2yuv.frag
@@ -0,0 +1,38 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2011 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+uniform sampler2D u_Texture;
+
+#ifndef FRAGMENT_ONLY
+varying vec2 v_TexCoord;
+varying vec4 v_Color;
+#endif
+
+void main(void)
+{
+ // Uses jpeg coefficients.
+ vec4 tex = texture2D(u_Texture, v_TexCoord);
+ float y = 0.299*tex.r + 0.587*tex.g + 0.114*tex.b;
+ float u = -0.168*tex.r - 0.330*tex.g + 0.498*tex.b + 0.5;
+ float v = 0.498*tex.r - 0.417*tex.g - 0.081*tex.b + 0.5;
+ gl_FragColor = vec4(v,u,y,1);
+}
+
diff --git a/src/graphics/shaders/standard.frag b/src/graphics/shaders/standard.frag
new file mode 100644
index 0000000..d77e835
--- /dev/null
+++ b/src/graphics/shaders/standard.frag
@@ -0,0 +1,101 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2011 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+uniform sampler2D u_Texture;
+uniform sampler2D u_CBTexture;
+uniform sampler2D u_CRTexture;
+uniform sampler2D u_ATexture;
+uniform sampler2D u_MaskTexture;
+uniform int u_ColorModel; // 0=rgb, 1=yuv, 2=alpha, 3=yuva
+uniform float u_Alpha;
+uniform vec4 u_ColorCoeff0;
+uniform vec4 u_ColorCoeff1;
+uniform vec4 u_ColorCoeff2;
+uniform vec4 u_ColorCoeff3;
+uniform bool u_bUseColorCoeff;
+uniform vec4 u_Gamma;
+uniform bool u_bPremultipliedAlpha;
+uniform bool u_bUseMask;
+uniform vec2 u_MaskPos;
+uniform vec2 u_MaskSize;
+
+#ifndef FRAGMENT_ONLY
+varying vec2 v_TexCoord;
+varying vec4 v_Color;
+#endif
+
+
+vec4 convertYCbCr(mat4 colorCoeff, vec4 tex)
+{
+ vec4 yuv;
+ yuv = vec4(tex.r,
+ texture2D(u_CBTexture, v_TexCoord).r,
+ texture2D(u_CRTexture, v_TexCoord).r,
+ 1.0);
+ vec4 rgb;
+ rgb = colorCoeff*yuv;
+ return vec4(rgb.rgb, u_Alpha);
+}
+
+void main(void)
+{
+ vec4 rgba;
+ mat4 colorCoeff;
+ colorCoeff[0] = u_ColorCoeff0;
+ colorCoeff[1] = u_ColorCoeff1;
+ colorCoeff[2] = u_ColorCoeff2;
+ colorCoeff[3] = u_ColorCoeff3;
+ vec4 tex = texture2D(u_Texture, v_TexCoord);
+ if (u_ColorModel == 0 || u_ColorModel == 2) {
+ float a;
+ if (u_ColorModel == 0) { // 0 = rgb
+ rgba = tex;
+ a = u_Alpha;
+ } else { // 2 = alpha
+ rgba = v_Color;
+ a = tex.a*u_Alpha;
+ }
+ if (u_bUseColorCoeff) {
+ rgba = colorCoeff*rgba;
+ }
+ rgba.a *= a;
+#ifdef ENABLE_YUV_CONVERSION
+ } else if (u_ColorModel == 1) { // yuv
+ rgba = convertYCbCr(colorCoeff, tex);
+ } else if (u_ColorModel == 3) { // yuva
+ rgba = convertYCbCr(colorCoeff, tex);
+ rgba.a *= texture2D(u_ATexture, v_TexCoord).r;
+#endif
+ } else {
+ rgba = vec4(1,1,1,1);
+ }
+ rgba = max(rgba, vec4(0.,0.,0.,0.));
+ rgba = pow(rgba, u_Gamma);
+ if (u_bUseMask) {
+ float mask = texture2D(u_MaskTexture, (v_TexCoord/u_MaskSize)-u_MaskPos).r;
+ if (u_bPremultipliedAlpha) {
+ rgba.rgb *= mask;
+ }
+ rgba.a *= mask;
+ }
+ gl_FragColor = rgba;
+}
+
diff --git a/src/graphics/shaders/standard.vert b/src/graphics/shaders/standard.vert
new file mode 100644
index 0000000..ce3ba77
--- /dev/null
+++ b/src/graphics/shaders/standard.vert
@@ -0,0 +1,36 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2011 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+uniform mat4 transform;
+attribute vec4 a_Color;
+attribute vec2 a_TexCoord;
+attribute vec2 a_Pos;
+
+varying vec2 v_TexCoord;
+varying vec4 v_Color;
+
+void main(void)
+{
+ gl_Position = transform * vec4(a_Pos, 0, 1);
+ v_TexCoord = a_TexCoord/4096.;
+ v_Color = a_Color;
+}
+
diff --git a/src/graphics/shaders/vertblur.frag b/src/graphics/shaders/vertblur.frag
new file mode 100644
index 0000000..167ef80
--- /dev/null
+++ b/src/graphics/shaders/vertblur.frag
@@ -0,0 +1,42 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2011 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+uniform sampler2D u_Texture;
+uniform float u_Width;
+uniform int u_Radius;
+uniform sampler2D u_KernelTex;
+
+#ifndef FRAGMENT_ONLY
+varying vec2 v_TexCoord;
+varying vec4 v_Color;
+#endif
+
+void main(void)
+{
+ vec4 sum = vec4(0,0,0,0);
+ float dy = dFdy(v_TexCoord.y);
+ for (int i=-u_Radius; i<=u_Radius; ++i) {
+ vec4 tex = texture2D(u_Texture, v_TexCoord+vec2(0,float(i)*dy));
+ float coeff = texture2D(u_KernelTex, vec2((float(i+u_Radius)+0.5)/u_Width,0)).r;
+ sum += tex*coeff;
+ }
+ gl_FragColor = sum;
+}
diff --git a/src/graphics/shaders/vertshadow.frag b/src/graphics/shaders/vertshadow.frag
new file mode 100644
index 0000000..bed8376
--- /dev/null
+++ b/src/graphics/shaders/vertshadow.frag
@@ -0,0 +1,54 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2011 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+uniform float u_Width;
+uniform int u_Radius;
+uniform sampler2D u_KernelTex;
+uniform sampler2D u_HBlurTex;
+uniform sampler2D u_OrigTex;
+uniform vec4 u_Color;
+uniform vec2 u_DestPos;
+uniform vec2 u_DestSize;
+
+#ifndef FRAGMENT_ONLY
+varying vec2 v_TexCoord;
+varying vec4 v_Color;
+#endif
+
+void main(void)
+{
+ float sum = 0.;
+ float dy = dFdy(v_TexCoord.y);
+ for (int i=-u_Radius; i<=u_Radius; ++i) {
+ float a = texture2D(u_HBlurTex,
+ v_TexCoord+vec2(0,float(i)*dy)).a;
+ float coeff =
+ texture2D(u_KernelTex, vec2((float(i+u_Radius)+0.5)/u_Width,0)).r;
+ sum += a*coeff;
+ }
+ sum = min(1., sum);
+ vec2 origCoord = v_TexCoord;
+ origCoord = u_DestPos +
+ vec2(origCoord.s*u_DestSize.x, origCoord.t*u_DestSize.y);
+ vec4 origCol = texture2D(u_OrigTex, origCoord);
+ gl_FragColor = origCol+(1.-origCol.a)*u_Color*sum;
+}
+
diff --git a/src/graphics/testgpu.cpp b/src/graphics/testgpu.cpp
new file mode 100644
index 0000000..ee322e8
--- /dev/null
+++ b/src/graphics/testgpu.cpp
@@ -0,0 +1,530 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "GraphicsTest.h"
+#include "GLTexture.h"
+#include "BitmapLoader.h"
+#include "GPUBrightnessFilter.h"
+#include "GPUBlurFilter.h"
+#include "GPUBandpassFilter.h"
+#include "GPUChromaKeyFilter.h"
+#include "GPUHueSatFilter.h"
+#include "GPUInvertFilter.h"
+#include "GPURGB2YUVFilter.h"
+#include "FilterResizeBilinear.h"
+#include "GLContext.h"
+#include "ShaderRegistry.h"
+#include "BmpTextureMover.h"
+#include "PBO.h"
+
+#include "../base/TestSuite.h"
+#include "../base/Exception.h"
+#include "../base/Test.h"
+#include "../base/StringHelper.h"
+
+#include <math.h>
+#include <iostream>
+
+#include <glib-object.h>
+
+using namespace avg;
+using namespace std;
+
+
+class BandpassFilterTest: public GraphicsTest {
+public:
+ BandpassFilterTest()
+ : GraphicsTest("BandpassFilterTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+ runImageTests("spike", B8G8R8X8);
+ runImageTests("i8-64x64", I8);
+ }
+
+private:
+ void runImageTests(const string& sFName, PixelFormat pf)
+ {
+ cerr << " Testing " << sFName << endl;
+ BitmapPtr pBmp = loadTestBmp(sFName, pf);
+ GPUBandpassFilter f(pBmp->getSize(), pf, 0.5, 1.5, 1, false);
+ BitmapPtr pDestBmp = f.apply(pBmp);
+ TEST(fabs(pDestBmp->getAvg() -128) < 0.06);
+ testEqual(*pDestBmp, "bandpass_"+sFName, pf, 0.2, 0.5);
+ TEST(pDestBmp->getPixelFormat() == pf);
+ }
+};
+
+
+class BlurFilterTest: public GraphicsTest {
+public:
+ BlurFilterTest()
+ : GraphicsTest("BlurFilterTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+/*
+ // This has the effect of printing out all the brightness differences for
+ //different kernel sizes.
+ BitmapPtr pDestBmp;
+ pBmp = loadTestBmp("spike");
+ for (float stddev = 0.5f; stddev < 5; stddev += 0.25f) {
+ pDestBmp = GPUBlurFilter(pBmp->getSize(), pBmp->getPixelFormat(), stddev)
+ .apply(pBmp);
+ testEqualBrightness(*pDestBmp, *pBmp, 1);
+ }
+*/
+ runFilterTests(false);
+ if (GLTexture::isFloatFormatSupported()) {
+ runFilterTests(true);
+ }
+ }
+
+private:
+ void runFilterTests(bool bUseFloat)
+ {
+ BitmapPtr pBmp;
+ GPUBlurFilterPtr pFilter;
+ pBmp = loadTestBmp("spike");
+ PixelFormat destPF;
+ if (bUseFloat) {
+ destPF = R32G32B32A32F;
+ } else {
+ destPF = B8G8R8A8;
+ }
+ pFilter = GPUBlurFilterPtr(new GPUBlurFilter(pBmp->getSize(),
+ pBmp->getPixelFormat(), destPF, 0.5f, false));
+ runImageTest(pBmp, pFilter, 0.5f, "blur05_spike");
+ runImageTest(pBmp, pFilter, 1, "blur1_spike");
+ runImageTest(pBmp, pFilter, 3, "blur3_spike");
+
+ pBmp = loadTestBmp("flat");
+ pFilter = GPUBlurFilterPtr(new GPUBlurFilter(pBmp->getSize(),
+ pBmp->getPixelFormat(), destPF, 5, false));
+ runImageTest(pBmp, pFilter, 5, "blur05_flat", true);
+
+ runImageTest("rgb24-64x64", destPF);
+ runImageTest("rgb24alpha-64x64", destPF);
+
+ }
+
+ void runImageTest(const string& sFName, PixelFormat destPF)
+ {
+ BitmapPtr pBmp = loadTestBmp(sFName);
+ GPUBlurFilterPtr pFilter(new GPUBlurFilter(pBmp->getSize(),
+ pBmp->getPixelFormat(), destPF, 2, false));
+ runImageTest(pBmp, pFilter, 2, string("blur_")+sFName, true);
+ }
+
+ void runImageTest(BitmapPtr pBmp, GPUBlurFilterPtr pFilter, float stdDev,
+ string sBmpName, bool bIgnoreBrightness = false)
+ {
+ cerr << " Testing " << sBmpName << ", stddev " << stdDev << endl;
+ pFilter->setStdDev(stdDev);
+ BitmapPtr pDestBmp = pFilter->apply(pBmp);
+ if (!bIgnoreBrightness) {
+ testEqualBrightness(*pDestBmp, *pBmp, 0.03);
+ }
+ testEqual(*pDestBmp, sBmpName, pDestBmp->getPixelFormat(), 0.1, 0.3);
+ }
+
+};
+
+
+class BrightnessFilterTest: public GraphicsTest {
+public:
+ BrightnessFilterTest()
+ : GraphicsTest("BrightnessFilterTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+ runImageTests("rgb24-64x64");
+ runImageTests("rgb24alpha-64x64");
+ }
+
+private:
+ void runImageTests(const string& sFName)
+ {
+ cerr << " Testing " << sFName << endl;
+ BitmapPtr pBmp = loadTestBmp(sFName);
+ PixelFormat pf = pBmp->getPixelFormat();
+ cerr << " Source Bmp: " << pf << endl;
+ BitmapPtr pDestBmp;
+ pDestBmp = GPUBrightnessFilter(pBmp->getSize(), pixelFormatHasAlpha(pf), 1)
+ .apply(pBmp);
+ float maxAverage, maxStdDev;
+ if (GLContext::getCurrent()->isGLES()) {
+ // less strict (lower floating point precision?)
+ maxAverage = 0.5;
+ maxStdDev = 1.5;
+ }
+ else {
+ maxAverage = 0.2;
+ maxStdDev = 0.5;
+ }
+ testEqual(*pDestBmp, *pBmp, string("brightness_")+sFName, maxAverage, maxStdDev);
+ }
+};
+
+
+class ChromaKeyFilterTest: public GraphicsTest {
+public:
+ ChromaKeyFilterTest()
+ : GraphicsTest("ChromaKeyFilterTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+ BitmapPtr pBmp = loadTestBmp("chromakey");
+ BitmapPtr pDestBmp;
+ GPUChromaKeyFilter filter(pBmp->getSize());
+ for (int erosion = 0; erosion < 3; ++erosion) {
+ filter.setParams(Pixel32(0,255,0), 0.1, 0.2, 0.1, 0.1, erosion, 0);
+ pDestBmp = filter.apply(pBmp);
+ testEqual(*pDestBmp, "ChromaKeyResult"+toString(erosion), B8G8R8A8, 0.3,
+ 0.7);
+ }
+ filter.setParams(Pixel32(0,255,0), 0.0, 0.0, 0.0, 0.0, 0, 0.1);
+ pDestBmp = filter.apply(pBmp);
+ testEqual(*pDestBmp, "ChromaKeySpillResult1", B8G8R8A8, 0.3, 0.7);
+ filter.setParams(Pixel32(0,255,0), 0.1, 0.1, 0.1, 0.0, 0, 0.1);
+ pDestBmp = filter.apply(pBmp);
+ testEqual(*pDestBmp, "ChromaKeySpillResult2", B8G8R8A8, 0.3, 0.7);
+ filter.setParams(Pixel32(0,255,0), 0.1, 0.1, 0.1, 0.0, 0, 0.2);
+ pDestBmp = filter.apply(pBmp);
+ testEqual(*pDestBmp, "ChromaKeySpillResult3", B8G8R8A8, 0.3, 0.7);
+
+ pBmp = loadTestBmp("chromakey-median");
+ filter.setParams(Pixel32(0,255,0), 0.1, 0.1, 0.1, 0.0, 0, 0.0);
+ pDestBmp = filter.apply(pBmp);
+ testEqual(*pDestBmp, "ChromaKeyMedianResult", B8G8R8A8, 1, 6);
+ }
+};
+
+
+class HueSatFilterTest: public GraphicsTest {
+public:
+ HueSatFilterTest()
+ : GraphicsTest("HueSatFilterTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+ BitmapPtr pBmp = loadTestBmp("hsl");
+ BitmapPtr pDestBmp;
+ GPUHueSatFilter filter(pBmp->getSize(), true);
+ //Test hue functionality
+ for (int run = 0; run < 3; run++) {
+ filter.setParams(run*90);
+ pDestBmp = filter.apply(pBmp);
+ testEqual(*pDestBmp, "HslHueResult"+toString(run), NO_PIXELFORMAT, 0, 0);
+ }
+ //Test colorize functionality
+ for (int run = 0; run < 3; run++) {
+ filter.setParams(run*90, 1, 0, true);
+ pDestBmp = filter.apply(pBmp);
+ testEqual(*pDestBmp, "HslColorizeResult"+toString(run), NO_PIXELFORMAT, 0, 0);
+ }
+ }
+};
+
+
+class InvertFilterTest: public GraphicsTest {
+public:
+ InvertFilterTest()
+ : GraphicsTest("InvertFilterTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+ runImageTests("rgb24-64x64");
+ }
+
+private:
+ void runImageTests(const string& sFName)
+ {
+ cerr << " Testing " << sFName << endl;
+ BitmapPtr pBmp = loadTestBmp(sFName);
+ BitmapPtr pDestBmp;
+ pDestBmp = GPUInvertFilter(pBmp->getSize(), false).apply(pBmp);
+ float maxAverage, maxStdDev;
+ if (GLContext::getCurrent()->isGLES()) {
+ // less strict (lower floating point precision?)
+ maxAverage = 0.6;
+ maxStdDev = 2.0;
+ }
+ else {
+ maxAverage = 0.0;
+ maxStdDev = 0.0;
+ }
+ testEqual(*pDestBmp, string("invert_")+sFName, pBmp->getPixelFormat(),
+ maxAverage, maxStdDev);
+ }
+};
+
+
+class RGB2YUVFilterTest: public GraphicsTest {
+public:
+ RGB2YUVFilterTest()
+ : GraphicsTest("RGB2YUVFilterTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+ BitmapPtr pOrigBmp = loadTestBmp("rgb24-64x64");
+ GLTexturePtr pTex = GLTexturePtr(new GLTexture(pOrigBmp->getSize(),
+ pOrigBmp->getPixelFormat()));
+ pTex->moveBmpToTexture(pOrigBmp);
+ GPURGB2YUVFilter f(pOrigBmp->getSize());
+ f.apply(pTex);
+ BitmapPtr pResultBmp = f.getResults();
+ pResultBmp = convertYUVX444ToRGB(pResultBmp);
+ testEqual(*pResultBmp, *pOrigBmp, "RGB2YUV", 1, 2);
+ }
+
+ BitmapPtr convertYUVX444ToRGB(const BitmapPtr& pYUVBmp)
+ {
+ // This is a weird pixel format that's not used anywhere else, so support
+ // hasn't been moved to the Bitmap class.
+ BitmapPtr pRGBBmp(new Bitmap(pYUVBmp->getSize(), B8G8R8X8));
+ int height = pRGBBmp->getSize().y;
+ int width = pRGBBmp->getSize().y;
+ int strideInPixels = pRGBBmp->getStride()/4;
+
+ for (int y = 0; y < height; ++y) {
+ const unsigned char * pSrc = pYUVBmp->getPixels() + pYUVBmp->getStride()*y;
+ Pixel32 * pDest = (Pixel32*)pRGBBmp->getPixels() + strideInPixels*y;
+ for (int x = 0; x < width; x++) {
+ YUVJtoBGR32Pixel(pDest, pSrc[0], pSrc[1], pSrc[2]);
+ pSrc += 4;
+ pDest ++;
+ }
+ }
+ return pRGBBmp;
+ }
+};
+
+
+class TextureMoverTest: public GraphicsTest {
+public:
+ TextureMoverTest()
+ : GraphicsTest("TextureMoverTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+ for (int i=1; i<2; ++i) {
+ bool bPOT = (i==1);
+ if (GLContext::getCurrent()->arePBOsSupported()) {
+ runImageTest(bPOT, MM_PBO, "rgb24-65x65");
+ runImageTest(bPOT, MM_PBO, "rgb24alpha-64x64");
+ }
+ runImageTest(bPOT, MM_OGL, "rgb24-65x65");
+ runImageTest(bPOT, MM_OGL, "rgb24alpha-64x64");
+ }
+ runCompressionTest(MM_OGL, "rgb24-65x65");
+ if (GLContext::getCurrent()->arePBOsSupported()) {
+ runCompressionTest(MM_PBO, "rgb24-65x65");
+ runMipmapTest(MM_PBO, "rgb24alpha-64x64");
+ runMipmapTest(MM_PBO, "rgb24-65x65");
+ }
+ runMipmapTest(MM_OGL, "rgb24-64x64");
+ runMipmapTest(MM_OGL, "rgb24alpha-64x64");
+ runMipmapTest(MM_OGL, "rgb24-65x65");
+ }
+
+private:
+ void runImageTest(bool bPOT, OGLMemoryMode memoryMode, const string& sFName)
+ {
+ string sResultFName = sFName + "-" + oglMemoryMode2String(memoryMode) + "-";
+ if (bPOT) {
+ sResultFName += "pot";
+ } else {
+ sResultFName += "npot";
+ }
+ cerr << " Testing " << sResultFName << endl;
+ BitmapPtr pOrigBmp = loadTestBmp(sFName);
+ {
+ cerr << " move functions." << endl;
+ GLTexturePtr pTex = GLTexturePtr(new GLTexture(pOrigBmp->getSize(),
+ pOrigBmp->getPixelFormat(), false, 0, GL_CLAMP_TO_EDGE,
+ GL_CLAMP_TO_EDGE, bPOT));
+ TextureMoverPtr pWriteMover = TextureMover::create(memoryMode,
+ pOrigBmp->getSize(), pOrigBmp->getPixelFormat(), GL_DYNAMIC_DRAW);
+ pWriteMover->moveBmpToTexture(pOrigBmp, *pTex);
+ BitmapPtr pDestBmp = pTex->moveTextureToBmp();
+ testEqual(*pDestBmp, *pOrigBmp, sResultFName+"-move", 0.01, 0.1);
+ }
+ {
+ cerr << " lock functions." << endl;
+ GLTexturePtr pTex = GLTexturePtr(new GLTexture(pOrigBmp->getSize(),
+ pOrigBmp->getPixelFormat(), false, 0, GL_CLAMP_TO_EDGE,
+ GL_CLAMP_TO_EDGE, bPOT));
+ TextureMoverPtr pMover = TextureMover::create(memoryMode,
+ pOrigBmp->getSize(), pOrigBmp->getPixelFormat(), GL_DYNAMIC_DRAW);
+ BitmapPtr pTransferBmp = pMover->lock();
+ pTransferBmp->copyPixels(*pOrigBmp);
+ pMover->unlock();
+ pMover->moveToTexture(*pTex);
+ BitmapPtr pDestBmp = pTex->moveTextureToBmp();
+ testEqual(*pDestBmp, *pOrigBmp, sResultFName+"-lock", 0.01, 0.1);
+ }
+ }
+
+ void runMipmapTest(OGLMemoryMode memoryMode, const string& sFName)
+ {
+ cerr << " Testing mipmap support, " << sFName << ", " <<
+ oglMemoryMode2String(memoryMode) << endl;
+ BitmapPtr pOrigBmp = loadTestBmp(sFName);
+ GLTexturePtr pTex = GLTexturePtr(new GLTexture(pOrigBmp->getSize(),
+ pOrigBmp->getPixelFormat(), true));
+ pTex->moveBmpToTexture(pOrigBmp);
+ pTex->generateMipmaps();
+
+ if (GLContext::getCurrent()->isGLES()) {
+ // GLES doesn't support attaching texture mipmap levels other than 0 to
+ // FBOs, so moveTextureToBmp() will fail. Skip result image comparison.
+ return;
+ }
+ BitmapPtr pResultBmp = pTex->moveTextureToBmp(1);
+ IntPoint newSize(pOrigBmp->getSize()/2);
+ TEST(pResultBmp->getSize() == newSize);
+ FilterResizeBilinear resizer(newSize);
+ BitmapPtr pBaselineBmp = resizer.apply(pOrigBmp);
+ string sName;
+ if (memoryMode == MM_PBO) {
+ sName = "pbo-mipmap";
+ } else {
+ sName = "ogl-mipmap";
+ }
+ testEqual(*pResultBmp, *pBaselineBmp, sName, 7, 15);
+ }
+
+ void runCompressionTest(OGLMemoryMode memoryMode, const string& sFName)
+ {
+ cerr << " Testing B5G6R5 compression, " << sFName << ", " <<
+ oglMemoryMode2String(memoryMode) << endl;
+ BitmapPtr pOrigBmp = loadTestBmp(sFName);
+ TextureMoverPtr pMover = TextureMover::create(memoryMode, pOrigBmp->getSize(),
+ B5G6R5, GL_STATIC_DRAW);
+ BitmapPtr pMoverBmp = pMover->lock();
+ pMoverBmp->copyPixels(*pOrigBmp);
+ pMover->unlock();
+ GLTexturePtr pTex = GLTexturePtr(new GLTexture(pMoverBmp->getSize(),
+ pMoverBmp->getPixelFormat(), false, 0, GL_CLAMP_TO_EDGE,
+ GL_CLAMP_TO_EDGE, false));
+ pMover->moveToTexture(*pTex);
+ BitmapPtr pDestBmp = pTex->moveTextureToBmp();
+ }
+};
+
+
+class GPUTestSuite: public TestSuite {
+public:
+ GPUTestSuite(const string& sVariant)
+ : TestSuite("GPUTestSuite ("+sVariant+")")
+ {
+ addTest(TestPtr(new TextureMoverTest));
+ addTest(TestPtr(new BrightnessFilterTest));
+ addTest(TestPtr(new HueSatFilterTest));
+ addTest(TestPtr(new InvertFilterTest));
+ if (GLContext::getCurrent()->getShaderUsage() == GLConfig::FULL) {
+ addTest(TestPtr(new RGB2YUVFilterTest));
+ addTest(TestPtr(new ChromaKeyFilterTest));
+ addTest(TestPtr(new BlurFilterTest));
+ if (GLTexture::isFloatFormatSupported()) {
+ addTest(TestPtr(new BandpassFilterTest));
+ }
+ }
+ }
+};
+
+
+bool runTests(bool bGLES, GLConfig::ShaderUsage su)
+{
+ string sVariant = string("GLES: ") + toString(bGLES) + ", ShaderUsage: " +
+ GLConfig::shaderUsageToString(su);
+ cerr << "---------------------------------------------------" << endl;
+ cerr << sVariant << endl;
+ cerr << "---------------------------------------------------" << endl;
+ GLContext* pContext = GLContext::create(GLConfig(bGLES, false, true, 1, su, true));
+ GLContext::setMain(pContext);
+ pContext->enableErrorChecks(true);
+ glDisable(GL_BLEND);
+ GLContext::checkError("glDisable(GL_BLEND)");
+ ShaderRegistry::get()->setShaderPath("./shaders");
+ try {
+ GPUTestSuite suite(sVariant);
+ suite.runTests();
+ delete pContext;
+ return suite.isOk();
+ } catch (Exception& ex) {
+ cerr << "Exception: " << ex.getStr() << endl;
+ delete pContext;
+ return false;
+ }
+}
+
+
+int main(int nargs, char** args)
+{
+ bool bOK = true;
+ try {
+#ifndef AVG_ENABLE_EGL
+ BitmapLoader::init(true);
+ bOK = runTests(false, GLConfig::FULL);
+ bOK &= runTests(false, GLConfig::MINIMAL);
+#endif
+ if (GLContext::isGLESSupported()) {
+ BitmapLoader::init(false);
+ bOK &= runTests(true, GLConfig::MINIMAL);
+ }
+ } catch (Exception& ex) {
+ if (ex.getCode() == AVG_ERR_ASSERT_FAILED) {
+ cerr << ex.getStr() << endl;
+ bOK = false;
+ } else {
+ cerr << "Skipping GPU imaging test." << endl;
+ cerr << "Reason: " << ex.getStr() << endl;
+ bOK = true;
+ }
+ }
+
+ if (bOK) {
+ cerr << "testgpu succeeded" << endl;
+ return 0;
+ } else {
+ cerr << "testgpu failed" << endl;
+ return 1;
+ }
+}
+
diff --git a/src/graphics/testgraphics.cpp b/src/graphics/testgraphics.cpp
new file mode 100644
index 0000000..f6874b6
--- /dev/null
+++ b/src/graphics/testgraphics.cpp
@@ -0,0 +1,1057 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "GraphicsTest.h"
+#include "Bitmap.h"
+#include "BitmapLoader.h"
+#include "Pixel32.h"
+#include "Pixel24.h"
+#include "Pixel16.h"
+#include "Filtercolorize.h"
+#include "Filtergrayscale.h"
+#include "Filterfill.h"
+#include "Filterflip.h"
+#include "Filterfliprgb.h"
+#include "Filterflipuv.h"
+#include "Filter3x3.h"
+#include "FilterConvol.h"
+#include "HistoryPreProcessor.h"
+#include "FilterHighpass.h"
+#include "FilterFastBandpass.h"
+#include "FilterGauss.h"
+#include "FilterBlur.h"
+#include "FilterBandpass.h"
+#include "FilterFastDownscale.h"
+#include "FilterMask.h"
+#include "FilterThreshold.h"
+#include "FilterFloodfill.h"
+#include "FilterDilation.h"
+#include "FilterErosion.h"
+#include "FilterGetAlpha.h"
+#include "FilterResizeBilinear.h"
+#include "FilterUnmultiplyAlpha.h"
+
+#include "../base/TestSuite.h"
+#include "../base/Exception.h"
+#include "../base/MathHelper.h"
+
+#ifdef _WIN32
+#pragma warning(push)
+#pragma warning(disable: 4251)
+#endif
+#ifdef _WIN32
+#pragma warning(pop)
+#endif
+
+#include <cstring>
+#include <iostream>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <glib-object.h>
+
+using namespace avg;
+using namespace std;
+
+BitmapPtr initBmp(PixelFormat pf)
+{
+ int height;
+ if (pf == YCbCr422) {
+ height = 10;
+ } else {
+ height = 7;
+
+ }
+ BitmapPtr pBmp(new Bitmap(IntPoint(4, height), pf));
+ int bpp = pBmp->getBytesPerPixel();
+ for (int y = 0; y < height; ++y) {
+ for (int x = 0; x < 4; ++x) {
+ unsigned char * pPixel =
+ pBmp->getPixels()+y*pBmp->getStride()+x*pBmp->getBytesPerPixel();
+ *(pPixel) = x;
+ if (bpp > 1) {
+ *(pPixel+1) = 0;
+ }
+ if (bpp > 2) {
+ *(pPixel+2) = x;
+ *(pPixel) = 16*y;
+ }
+ if (bpp > 3) {
+ *(pPixel+3) = 0x80;
+ }
+ }
+ }
+ return pBmp;
+}
+
+// TODO: This is very incomplete!
+class PixelTest: public GraphicsTest {
+public:
+ PixelTest()
+ : GraphicsTest("PixelTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+ float h, s, l;
+ Pixel32(255, 0, 0).toHSL(h, s, l);
+ TEST(h == 0 && almostEqual(s, 1.0f) && almostEqual(l, 0.5f));
+ Pixel32(0, 255, 0).toHSL(h, s, l);
+ TEST(h == 120 && almostEqual(s, 1.0f) && almostEqual(l, 0.5f));
+ Pixel32(0, 0, 255).toHSL(h, s, l);
+ TEST(h == 240 && almostEqual(s, 1.0f) && almostEqual(l, 0.5f));
+ Pixel32(255, 255, 0).toHSL(h, s, l);
+ TEST(h == 60 && almostEqual(s, 1.0f) && almostEqual(l, 0.5f));
+ Pixel32(255, 0, 255).toHSL(h, s, l);
+ TEST(h == 300 && almostEqual(s, 1.0f) && almostEqual(l, 0.5f));
+ Pixel32(0, 255, 255).toHSL(h, s, l);
+ TEST(h == 180 && almostEqual(s, 1.0f) && almostEqual(l, 0.5f));
+ Pixel32(0, 0, 0).toHSL(h, s, l);
+ TEST(s == 0.0f && l == 0.0f);
+ Pixel32(255, 255, 255).toHSL(h, s, l);
+ TEST(s == 0.0f && l == 1.0f);
+ Pixel32(128, 128, 128).toHSL(h, s, l);
+ TEST(s == 0.0f && almostEqual(l, 0.5f, 0.02f));
+ }
+};
+
+class BitmapTest: public GraphicsTest {
+public:
+ BitmapTest()
+ : GraphicsTest("BitmapTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+ runPFTests(B8G8R8A8);
+ runPFTests(R8G8B8A8);
+ runPFTests(R8G8B8X8);
+ runPFTests(R8G8B8);
+ runPFTests(I8);
+ runPFTests(I16);
+ runPFTests(YCbCr422);
+ runLineTest(B8G8R8A8, Pixel32(0,0,255,255));
+ runLineTest(B8G8R8, Pixel24(0,0,255));
+ runLineTest(I8, Pixel8(255));
+
+ cerr << " Testing OwnsBits." << endl;
+ unsigned char pData[4*7*3];
+ for (int i = 0; i < 4*7*3; ++i) {
+ pData[i] = i;
+ }
+ Bitmap Bmp1 = Bitmap(IntPoint(4,7), R8G8B8, pData, 12, true, "");
+ Bitmap Bmp2 = Bitmap(IntPoint(4,7), R8G8B8, pData, 12, false, "");
+ testEqual(Bmp1, Bmp2, "BmpOwnsBits");
+ {
+ cerr << " Testing copyPixels - R8G8B8X8->R8G8B8->R8G8B8X8." << endl;
+ BitmapPtr pBmp = initBmp(R8G8B8X8);
+ Bitmap Bmp1(IntPoint(4,7), R8G8B8);
+ Bmp1.copyPixels(*pBmp);
+ Bitmap Bmp2(IntPoint(4,7), R8G8B8X8);
+ Bmp2.copyPixels(Bmp1);
+ for(int y = 0; y < 7; ++y) {
+ for (int x = 0; x < 4; ++x) {
+ *(Bmp2.getPixels()+y*Bmp2.getStride()+x
+ *Bmp2.getBytesPerPixel()+3) = 0x80;
+ }
+ }
+ testEqual(Bmp2, *pBmp, "BmpCopyPixels_1");
+ }
+ {
+ cerr << " Testing copyPixels - R8G8B8A8->R8G8B8->R8G8B8A8." << endl;
+ BitmapPtr pBmp = initBmp(R8G8B8A8);
+ BitmapPtr pBaselineBmp = initBmp(R8G8B8A8);
+ BitmapPtr pCopyBmp = BitmapPtr(new Bitmap(IntPoint(4,7), R8G8B8));
+ pCopyBmp->copyPixels(*pBmp);
+ pBmp->copyPixels(*pCopyBmp);
+ for(int y = 0; y < 7; ++y) {
+ for (int x = 0; x < 4; ++x) {
+ *(pBmp->getPixels()+y*pBmp->getStride()+x
+ *pBmp->getBytesPerPixel()+3) = 0x80;
+ }
+ }
+ testEqual(*pBmp, *pBaselineBmp, "BmpCopyPixels_2");
+ }
+ {
+ cerr << " Testing copyPixels - I8->I16->I8." << endl;
+ BitmapPtr pBmp = initBmp(I8);
+ BitmapPtr pBaselineBmp = initBmp(I8);
+ BitmapPtr pCopyBmp = BitmapPtr(new Bitmap(IntPoint(4,7), I16));
+ pCopyBmp->copyPixels(*pBmp);
+ pBmp->copyPixels(*pCopyBmp);
+ testEqual(*pBmp, *pBaselineBmp, "BmpCopyPixels_3");
+ }
+ {
+ cerr << " Testing copyPixels - R8G8B8A8->R32G32B32A32F->R8G8B8A8." << endl;
+ BitmapPtr pBmp = initBmp(R8G8B8A8);
+ BitmapPtr pBaselineBmp = initBmp(R8G8B8A8);
+ BitmapPtr pCopyBmp = BitmapPtr(new Bitmap(IntPoint(4,7), R32G32B32A32F));
+ pCopyBmp->copyPixels(*pBmp);
+ pBmp->copyPixels(*pCopyBmp);
+ testEqual(*pBmp, *pBaselineBmp, "BmpCopyPixels_3");
+ }
+ {
+ cerr << " Testing copyPixels - B5G6R5->B8G8R8->B5G6R5." << endl;
+ BitmapPtr pBmp = initBmp(B5G6R5);
+ BitmapPtr pBaselineBmp = initBmp(B5G6R5);
+ BitmapPtr pCopyBmp = BitmapPtr(new Bitmap(IntPoint(4,7), B8G8R8));
+ pCopyBmp->copyPixels(*pBmp);
+ pBmp->copyPixels(*pCopyBmp);
+ testEqual(*pBmp, *pBaselineBmp, "BmpCopyPixels_4");
+ }
+ testCopyToGreyscale(R8G8B8X8);
+ testCopyToGreyscale(B8G8R8X8);
+ testSubtract();
+ {
+ cerr << " Testing statistics." << endl;
+ cerr << " I8" << endl;
+ testStatistics(I8, Pixel8(0), Pixel8(0), Pixel8(2), Pixel8(2));
+ cerr << " R8G8B8A8" << endl;
+ testStatistics(R8G8B8A8, Pixel32(0,0,0,0), Pixel32(0,0,0,0),
+ Pixel32(255,255,255,255), Pixel32(255,255,255,255), 127.5, 90.1561);
+ cerr << " R8G8B8X8" << endl;
+ testStatistics(R8G8B8X8, Pixel32(0,0,0,255), Pixel32(0,0,0,255),
+ Pixel32(2,2,2,255), Pixel32(2,2,2,255));
+ cerr << " R8G8B8" << endl;
+ testStatistics(R8G8B8, Pixel24(0,0,0), Pixel24(0,0,0),
+ Pixel24(2,2,2), Pixel24(2,2,2));
+ cerr << " ChannelAvg" << endl;
+ testChannelAvg();
+ }
+ {
+ cerr << " Testing YUV->RGB conversion." << endl;
+ testYUV2RGB();
+ }
+ runSaveTest(B8G8R8A8);
+ runSaveTest(B8G8R8X8);
+ }
+
+private:
+ void runPFTests(PixelFormat pf)
+ {
+ cerr << " Testing " << pf << endl;
+ BitmapPtr pBmp = initBmp(pf);
+ {
+ cerr << " Testing size." <<endl;
+ if (pf == YCbCr422) {
+ TEST(pBmp->getSize() == IntPoint(4,10));
+ } else {
+ TEST(pBmp->getSize() == IntPoint(4,7));
+ }
+ }
+ {
+ cerr << " Testing copy constructor." << endl;
+ Bitmap bmpCopy1(*pBmp);
+ testEqual(bmpCopy1, *pBmp, "BmpCopyConstructor");
+ }
+ {
+ cerr << " Testing assignment operator." << endl;
+ Bitmap bmpCopy2 = *pBmp;
+ testEqual(bmpCopy2, *pBmp, "BmpAssignment");
+ }
+ {
+ cerr << " Testing sub-bitmap constructor." << endl;
+ Bitmap bmpCopy3 (*pBmp, IntRect(IntPoint(0,0), pBmp->getSize()));
+ testEqual(bmpCopy3, *pBmp, "BmpSubBmpCtor");
+ }
+ if (pf == I8) {
+ cerr << " Testing getHistogram." << endl;
+ HistogramPtr pHist = pBmp->getHistogram();
+ TEST((*pHist)[0] == 7);
+ TEST((*pHist)[1] == 7);
+ TEST((*pHist)[2] == 7);
+ TEST((*pHist)[3] == 7);
+ bool bOk = true;
+ for (int i = 4; i < 256; ++i) {
+ if (bOk) {
+ bOk = ((*pHist)[i] == 0);
+ }
+ }
+ TEST(bOk);
+ }
+ }
+
+ void runSaveTest(PixelFormat pf)
+ {
+ cerr << " Testing save for " << pf << endl;
+ BitmapPtr pBmp = initBmp(pf);
+ pBmp->save("test.png");
+ BitmapPtr pLoadedBmp = loadBitmap("test.png");
+ ::remove("test.png");
+ testEqual(*pLoadedBmp, *pBmp, "BmpSave");
+ }
+
+ template<class PIXEL>
+ void runLineTest(PixelFormat pf, PIXEL color)
+ {
+ cerr << " Testing line drawing for " << pf << endl;
+ Bitmap bmp(IntPoint(15, 15), pf);
+ memset(bmp.getPixels(), 0, bmp.getStride()*15);
+ bmp.drawLine(IntPoint(7,7), IntPoint( 0, 2), color);
+ bmp.drawLine(IntPoint(7,7), IntPoint( 0,12), color);
+ bmp.drawLine(IntPoint(7,7), IntPoint( 2, 0), color);
+ bmp.drawLine(IntPoint(7,7), IntPoint( 2,14), color);
+ bmp.drawLine(IntPoint(7,7), IntPoint(12, 0), color);
+ bmp.drawLine(IntPoint(7,7), IntPoint(12,14), color);
+ bmp.drawLine(IntPoint(7,7), IntPoint(14, 2), color);
+ bmp.drawLine(IntPoint(7,7), IntPoint(14,12), color);
+ string sFName = getSrcDirName() + "baseline/LineResult" + getPixelFormatString(pf)
+ + ".png";
+ BitmapPtr pBaselineBmp = loadBitmap(sFName, pf);
+ testEqual(bmp, *pBaselineBmp, "BmpLineDraw");
+ }
+
+ void testCopyToGreyscale(PixelFormat pf)
+ {
+ cerr << " Testing copyPixels - " << pf << "->I8." << endl;
+ BitmapPtr pBmp(new Bitmap(IntPoint(4,4), pf));
+ for (int y=0; y<4; ++y) {
+ for (int x=0; x<4; ++x) {
+ unsigned char * pPixel =
+ pBmp->getPixels()+y*pBmp->getStride()+x*pBmp->getBytesPerPixel();
+ pPixel[0] = x*64;
+ pPixel[1] = 128;
+ pPixel[2] = y*64;
+ pPixel[3] = 255;
+ }
+ }
+ BitmapPtr pCopyBmp = BitmapPtr(new Bitmap(IntPoint(4,4), I8));
+ pCopyBmp->copyPixels(*pBmp);
+ testEqual(*pCopyBmp, string("copyPixels_")+getPixelFormatString(pf)+"_I8",
+ I8, 0.5, 0.5);
+ }
+
+ void testSubtract()
+ {
+ BitmapPtr pBmp1(new Bitmap(IntPoint(4,1), I8));
+ BitmapPtr pBmp2(new Bitmap(IntPoint(4,1), I8));
+ for (int x=0; x<4; ++x) {
+ pBmp1->getPixels()[x] = x;
+ pBmp2->getPixels()[x] = 0;
+ }
+ BitmapPtr pDiffBmp = pBmp1->subtract(*pBmp2);
+ testEqual(*pDiffBmp, *pBmp1, "BmpSubtract1");
+ pDiffBmp = pBmp2->subtract(*pBmp1);
+ testEqual(*pDiffBmp, *pBmp1, "BmpSubtract2");
+ }
+
+ template<class PIXEL>
+ void testStatistics(PixelFormat pf, const PIXEL& p00, const PIXEL& p01,
+ const PIXEL& p10, const PIXEL& p11, float avg=1, float stdDev=1)
+ {
+ BitmapPtr pBmp = BitmapPtr(new Bitmap(IntPoint(2,2), pf));
+ pBmp->setPixel(IntPoint(0,0), p00);
+ pBmp->setPixel(IntPoint(0,1), p01);
+ pBmp->setPixel(IntPoint(1,0), p10);
+ pBmp->setPixel(IntPoint(1,1), p11);
+ TEST(almostEqual(pBmp->getAvg(), avg, 0.001));
+ TEST(almostEqual(pBmp->getStdDev(), stdDev, 0.001));
+ }
+
+ void testChannelAvg()
+ {
+ BitmapPtr pBmp = BitmapPtr(new Bitmap(IntPoint(2,2), R8G8B8));
+ pBmp->setPixel(IntPoint(0,0), Pixel24(0,0,0));
+ pBmp->setPixel(IntPoint(0,1), Pixel24(128,0,0));
+ pBmp->setPixel(IntPoint(1,0), Pixel24(128,128,0));
+ pBmp->setPixel(IntPoint(1,1), Pixel24(128,128,128));
+ TEST(almostEqual(pBmp->getChannelAvg(0), 96));
+ TEST(almostEqual(pBmp->getChannelAvg(1), 64));
+ TEST(almostEqual(pBmp->getChannelAvg(2), 32));
+ }
+
+ void testYUV2RGB()
+ {
+ BitmapPtr pYBmp = BitmapPtr(new Bitmap(IntPoint(16, 16), I8));
+ for (int x=0; x<16; ++x) {
+ FilterFillRect<Pixel8>(IntRect(x, 0, x+1, 16), 255-x*16).applyInPlace(pYBmp);
+ }
+ BitmapPtr pUBmp = BitmapPtr(new Bitmap(IntPoint(8, 8), I8));
+ BitmapPtr pVBmp = BitmapPtr(new Bitmap(IntPoint(8, 8), I8));
+ FilterFillRect<Pixel8>(IntRect(0, 0, 8, 4), 128).applyInPlace(pUBmp);
+ FilterFillRect<Pixel8>(IntRect(0, 0, 8, 4), 128).applyInPlace(pVBmp);
+ for (int y=4; y<8; ++y) {
+ FilterFillRect<Pixel8>(IntRect(0, y, 8, y+1), y*64).applyInPlace(pUBmp);
+ FilterFillRect<Pixel8>(IntRect(0, y, 8, y+1), 255-y*64).applyInPlace(pVBmp);
+ }
+ BitmapPtr pRGBBmp = BitmapPtr(new Bitmap(IntPoint(16, 16), B8G8R8X8));
+ FilterFill<Pixel32>(Pixel32(255,0,0,255)).applyInPlace(pRGBBmp);
+ pRGBBmp->copyYUVPixels(*pYBmp, *pUBmp, *pVBmp, false);
+ testEqual(*pRGBBmp, "YUV2RGBResult1", B8G8R8X8, 0.5, 0.5);
+ }
+
+};
+
+class FilterColorizeTest: public GraphicsTest {
+public:
+ FilterColorizeTest()
+ : GraphicsTest("FilterColorizeTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+ runPFTests(R8G8B8A8);
+ runPFTests(R8G8B8);
+ }
+
+private:
+ void runPFTests(PixelFormat pf) {
+ BitmapPtr pBmp = initBmp(pf);
+ FilterColorize(15, 0).applyInPlace(pBmp);
+ FilterColorize(100, 50).applyInPlace(pBmp);
+ FilterColorize(50, 100).applyInPlace(pBmp);
+ }
+};
+
+class FilterGrayscaleTest: public GraphicsTest {
+public:
+ FilterGrayscaleTest()
+ : GraphicsTest("FilterGrayscaleTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+ runPFTests(R8G8B8A8);
+ runPFTests(R8G8B8);
+ runPFTests(I8);
+ }
+
+private:
+ void runPFTests(PixelFormat pf) {
+ BitmapPtr pBmp = initBmp(pf);
+ FilterGrayscale().applyInPlace(pBmp);
+ }
+};
+
+class FilterFillTest: public GraphicsTest {
+public:
+ FilterFillTest()
+ : GraphicsTest("FilterFillTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+ runPFTests<Pixel32>(R8G8B8A8, Pixel32(255,80,0,255));
+ runPFTests<Pixel24>(R8G8B8, Pixel24(255,80,0));
+ }
+
+private:
+ template<class PixelC>
+ void runPFTests(PixelFormat pf, PixelC color) {
+ BitmapPtr pBmp = initBmp(pf);
+ FilterFill<PixelC>(color).applyInPlace(pBmp);
+ }
+};
+
+class FilterFlipTest: public GraphicsTest {
+public:
+ FilterFlipTest()
+ : GraphicsTest("FilterFlipTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+ runPFTests(R8G8B8A8);
+ runPFTests(B8G8R8X8);
+ runPFTests(R8G8B8);
+ runPFTests(I8);
+ }
+
+private:
+ void runPFTests(PixelFormat pf) {
+ BitmapPtr pBmp = initBmp(pf);
+ {
+ BitmapPtr pBmp1 = FilterFlip().apply(pBmp);
+ BitmapPtr pBmp2 = FilterFlip().apply(pBmp1);
+ TEST(*pBmp == *pBmp2);
+ }
+ pBmp = initBmp(pf);
+ {
+ Bitmap baselineBmp = *pBmp;
+ FilterFlip().applyInPlace(pBmp);
+ FilterFlip().applyInPlace(pBmp);
+ TEST(*pBmp == baselineBmp);
+ }
+ }
+};
+
+class FilterFlipRGBTest: public GraphicsTest {
+public:
+ FilterFlipRGBTest()
+ : GraphicsTest("FilterFlipRGBTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+ runPFTests(B8G8R8A8);
+ runPFTests(R8G8B8A8);
+ runPFTests(R8G8B8);
+ }
+
+private:
+ void runPFTests(PixelFormat pf) {
+ BitmapPtr pBmp = initBmp(pf);
+ {
+ BitmapPtr pBmp1 = FilterFlipRGB().apply(pBmp);
+ BitmapPtr pBmp2 = FilterFlipRGB().apply(pBmp1);
+ TEST(*pBmp == *pBmp2);
+ }
+ {
+ Bitmap baselineBmp = *pBmp;
+ FilterFlipRGB().applyInPlace(pBmp);
+ FilterFlipRGB().applyInPlace(pBmp);
+ TEST(*pBmp == baselineBmp);
+ }
+ }
+};
+
+class FilterFlipUVTest: public GraphicsTest {
+public:
+ FilterFlipUVTest()
+ : GraphicsTest("FilterFlipUVTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+ BitmapPtr pBmp = initBmp(YCbCr422);
+ {
+ BitmapPtr pBmp1 = FilterFlipUV().apply(pBmp);
+ BitmapPtr pBmp2 = FilterFlipUV().apply(pBmp1);
+ TEST(*pBmp == *pBmp2);
+ }
+ {
+ Bitmap baselineBmp = *pBmp;
+ FilterFlipUV().applyInPlace(pBmp);
+ FilterFlipUV().applyInPlace(pBmp);
+ TEST(*pBmp == baselineBmp);
+ }
+ }
+};
+
+class FilterComboTest: public GraphicsTest {
+public:
+ FilterComboTest()
+ : GraphicsTest("FilterComboTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+ try {
+ char * pSrcDir = getenv("srcdir");
+ string sFilename;
+ if (pSrcDir) {
+ sFilename = (string)pSrcDir+"/";
+ }
+ sFilename += "../test/media/rgb24-64x64.png";
+ BitmapPtr pBmp = loadBitmap(sFilename, R8G8B8);
+ FilterColorize(15, 50).applyInPlace(pBmp);
+ FilterFlipRGB().applyInPlace(pBmp);
+ } catch (Exception & ex) {
+ cerr << ex.getStr() << endl;
+ setFailed();
+ }
+ }
+
+private:
+ BitmapPtr createBmp(const IntPoint& size, PixelFormat pf)
+ {
+ BitmapPtr pBmp;
+ pBmp = BitmapPtr(new Bitmap(size, pf));
+ return pBmp;
+ }
+};
+
+class FilterConvolTest: public GraphicsTest {
+public:
+ FilterConvolTest()
+ : GraphicsTest("FilterConvolTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+ runPFTests<Pixel24>(R8G8B8);
+ runPFTests<Pixel32>(R8G8B8X8);
+ //FIXME runPFTests<Pixel8>(I8);
+ }
+
+private:
+ template<class PIXEL>
+ void runPFTests(PixelFormat pf)
+ {
+ BitmapPtr pBmp(new Bitmap(IntPoint(4, 4), pf));
+ initBmp<PIXEL>(pBmp);
+ float mat[9] =
+ {1,0,2,
+ 0,1,0,
+ 3,0,4};
+ BitmapPtr pNewBmp = FilterConvol<PIXEL>(&(mat[0]),3,3).apply(pBmp);
+ TEST(pNewBmp->getSize() == IntPoint(2,2));
+ unsigned char * pLine0 = pNewBmp->getPixels();
+ TEST(*(PIXEL*)pLine0 == PIXEL(1,0,0));
+ TEST(*(((PIXEL*)pLine0)+1) == PIXEL(4,0,0));
+ unsigned char * pLine1 = pNewBmp->getPixels()+pNewBmp->getStride();
+ TEST(*(PIXEL*)(pLine1) == PIXEL(0,0,9));
+ TEST(*((PIXEL*)(pLine1)+1) == PIXEL(0,0,16));
+
+ }
+
+ template<class PIXEL>
+ void initBmp(BitmapPtr pBmp)
+ {
+ PIXEL * pPixels = (PIXEL *)(pBmp->getPixels());
+ PIXEL color = PIXEL(0,0,0);
+ FilterFill<PIXEL>(color).applyInPlace(pBmp);
+ pPixels[0] = PIXEL(1,0,0);
+ pPixels[3] = PIXEL(2,0,0);
+ pPixels = (PIXEL*)((char *)pPixels+3*pBmp->getStride());
+ pPixels[0] = PIXEL(0,0,3);
+ pPixels[3] = PIXEL(0,0,4);
+ }
+};
+
+class Filter3x3Test: public GraphicsTest {
+public:
+ Filter3x3Test()
+ : GraphicsTest("Filter3x3Test", 2)
+ {
+ }
+
+ void runTests()
+ {
+ runPFTests<Pixel24>(R8G8B8);
+ runPFTests<Pixel32>(R8G8B8X8);
+ }
+
+private:
+ template<class PIXEL>
+ void runPFTests(PixelFormat pf)
+ {
+ BitmapPtr pBmp(new Bitmap(IntPoint(4, 4), pf));
+ initBmp<PIXEL>(pBmp);
+ float mat[3][3] =
+ {{1,0,2},
+ {0,1,0},
+ {3,0,4}};
+ BitmapPtr pNewBmp = Filter3x3(mat).apply(pBmp);
+ TEST(pNewBmp->getSize() == IntPoint(2,2));
+ unsigned char * pLine0 = pNewBmp->getPixels();
+ TEST(*(PIXEL*)pLine0 == PIXEL(1,0,0));
+ TEST(*(((PIXEL*)pLine0)+1) == PIXEL(4,0,0));
+ unsigned char * pLine1 = pNewBmp->getPixels()+pNewBmp->getStride();
+ TEST(*(PIXEL*)(pLine1) == PIXEL(0,0,9));
+ TEST(*((PIXEL*)(pLine1)+1) == PIXEL(0,0,16));
+
+ }
+
+ template<class PIXEL>
+ void initBmp(BitmapPtr pBmp)
+ {
+ PIXEL * pPixels = (PIXEL *)(pBmp->getPixels());
+ PIXEL color = PIXEL(0,0,0);
+ FilterFill<PIXEL>(color).applyInPlace(pBmp);
+ pPixels[0] = PIXEL(1,0,0);
+ pPixels[3] = PIXEL(2,0,0);
+ pPixels = (PIXEL*)((char *)pPixels+3*pBmp->getStride());
+ pPixels[0] = PIXEL(0,0,3);
+ pPixels[3] = PIXEL(0,0,4);
+ }
+};
+
+class HistoryPreProcessorTest: public GraphicsTest {
+public:
+ HistoryPreProcessorTest()
+ : GraphicsTest("HistoryPreProcessor", 2)
+ {
+ }
+
+ void runTests()
+ {
+ BitmapPtr pBaseBmp = initBmp(I8);
+ BitmapPtr pBmp = BitmapPtr(new Bitmap(*pBaseBmp));
+ BitmapPtr nullBmp = FilterFill<Pixel8>(0).apply(pBmp);
+ pBmp->copyPixels(*pBaseBmp);
+ HistoryPreProcessor filt(pBaseBmp->getSize(), 1, true);
+ pBmp = filt.apply(pBaseBmp);
+ testEqual(*pBmp, *nullBmp, "HistoryPreprocessor1");
+ for(int i=0;i<1;i++){
+ pBmp = filt.apply(pBaseBmp);
+ testEqual(*pBmp, *nullBmp, "HistoryPreprocessor2");
+ }
+ }
+
+};
+
+class FilterFastBandpassTest: public GraphicsTest {
+public:
+ FilterFastBandpassTest()
+ : GraphicsTest("FilterFastBandpassTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+ BitmapPtr pBmp = BitmapPtr(new Bitmap(IntPoint(16,16), I8));
+ FilterFill<Pixel8>(0).applyInPlace(pBmp);
+ *(pBmp->getPixels()+pBmp->getStride()*7+7) = 255;
+ BitmapPtr pDestBmp = FilterFastBandpass().apply(pBmp);
+ testEqual(*pDestBmp, "FastBandpassResult", I8);
+ }
+};
+
+
+class FilterHighpassTest: public GraphicsTest {
+public:
+ FilterHighpassTest()
+ : GraphicsTest("FilterHighpassTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+ BitmapPtr pBmp = BitmapPtr(new Bitmap(IntPoint(16,16), I8));
+ FilterFill<Pixel8>(0).applyInPlace(pBmp);
+ *(pBmp->getPixels()+pBmp->getStride()*7+7) = 255;
+ BitmapPtr pDestBmp = FilterHighpass().apply(pBmp);
+ testEqual(*pDestBmp, "HighpassResult", I8);
+ }
+};
+
+
+class FilterGaussTest: public GraphicsTest {
+public:
+ FilterGaussTest()
+ : GraphicsTest("FilterGaussTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+ BitmapPtr pBmp = BitmapPtr(new Bitmap(IntPoint(16,16), I8));
+ FilterFill<Pixel8>(0).applyInPlace(pBmp);
+ *(pBmp->getPixels()+pBmp->getStride()*7+7) = 255;
+ BitmapPtr pDestBmp = FilterGauss(3).apply(pBmp);
+ testEqual(*pDestBmp, "Gauss3Result", I8);
+ pDestBmp = FilterGauss(1).apply(pBmp);
+ testEqual(*pDestBmp, "Gauss1Result", I8);
+ pDestBmp = FilterGauss(1.5).apply(pBmp);
+ testEqual(*pDestBmp, "Gauss15Result", I8);
+ pDestBmp = FilterGauss(5).apply(pBmp);
+ testEqual(*pDestBmp, "Gauss5Result", I8);
+ }
+};
+
+
+class FilterBlurTest: public GraphicsTest {
+public:
+ FilterBlurTest()
+ : GraphicsTest("FilterBlurTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+ BitmapPtr pBmp = BitmapPtr(new Bitmap(IntPoint(16,16), I8));
+ FilterFill<Pixel8>(0).applyInPlace(pBmp);
+ *(pBmp->getPixels()+pBmp->getStride()*7+7) = 255;
+ BitmapPtr pDestBmp = FilterBlur().apply(pBmp);
+ testEqual(*pDestBmp, "BlurResult", I8);
+ }
+};
+
+
+class FilterBandpassTest: public GraphicsTest {
+public:
+ FilterBandpassTest()
+ : GraphicsTest("FilterBandpassTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+ BitmapPtr pBmp = BitmapPtr(new Bitmap(IntPoint(16,16), I8));
+ FilterFill<Pixel8>(0).applyInPlace(pBmp);
+ *(pBmp->getPixels()+pBmp->getStride()*7+7) = 255;
+
+ BitmapPtr pDestBmp = FilterBandpass(1.9,3).apply(pBmp);
+ testEqual(*pDestBmp, "BandpassResult", I8);
+ }
+};
+
+class FilterFastDownscaleTest: public GraphicsTest {
+public:
+ FilterFastDownscaleTest()
+ : GraphicsTest("FilterFastDownscaleTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+ BitmapPtr pBmp = BitmapPtr(new Bitmap(IntPoint(4,4), I8));
+ FilterFill<Pixel8>(0).applyInPlace(pBmp);
+ *(pBmp->getPixels()+pBmp->getStride()*3+3) = 252;
+
+ BitmapPtr pDestBmp = FilterFastDownscale(2).apply(pBmp);
+ testEqual(*pDestBmp, "FastDownscaleResult", I8);
+ }
+};
+
+class FilterMaskTest: public GraphicsTest {
+public:
+ FilterMaskTest()
+ : GraphicsTest("FilterMaskTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+ runTestsWithBmp(initBmp(I8), "I8");
+ runTestsWithBmp(initBmp(B8G8R8), "B8G8R8");
+ runTestsWithBmp(initBmp(B8G8R8X8), "B8G8R8X8");
+ }
+
+private:
+ void runTestsWithBmp(BitmapPtr pBmp, const string& sName)
+ {
+ BitmapPtr pMaskBmp = BitmapPtr(new Bitmap(pBmp->getSize(), I8));
+ FilterFill<Pixel8>(0).applyInPlace(pMaskBmp);
+ for (int y = 0; y < pBmp->getSize().y; y++) {
+ pMaskBmp->setPixel(IntPoint(1, y), Pixel8(128));
+ pMaskBmp->setPixel(IntPoint(2, y), Pixel8(255));
+ pMaskBmp->setPixel(IntPoint(3, y), Pixel8(255));
+ }
+
+ BitmapPtr pDestBmp = FilterMask(pMaskBmp).apply(pBmp);
+ string sFName = string("baseline/MaskResult")+sName+".png";
+// pDestBmp->save(sFName);
+ sFName = getSrcDirName()+sFName;
+ BitmapPtr pBaselineBmp = loadBitmap(sFName, pBmp->getPixelFormat());
+ TEST(*pDestBmp == *pBaselineBmp);
+ }
+};
+
+class FilterThresholdTest: public GraphicsTest {
+public:
+ FilterThresholdTest()
+ : GraphicsTest("FilterThresholdTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+ BitmapPtr pBmp(initBmp(I8));
+ BitmapPtr pDestBmp = FilterThreshold(1).apply(pBmp);
+ string sFName = "baseline/ThresholdResult.png";
+// pDestBmp->save(sFName);
+ sFName = getSrcDirName()+sFName;
+ BitmapPtr pBaselineBmp = loadBitmap(sFName, pBmp->getPixelFormat());
+ TEST(*pDestBmp == *pBaselineBmp);
+ }
+};
+
+class FilterFloodfillTest: public GraphicsTest {
+public:
+ FilterFloodfillTest()
+ : GraphicsTest("FilterFloodfillTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+ BitmapPtr pBmp = loadTestBmp("floodfill");
+ BitmapPtr pDestBmp = FilterFloodfill<ColorTester>(
+ ColorTester(Pixel32(255,255,255,255)), IntPoint(4,3)).apply(pBmp);
+ testEqual(*pDestBmp, "FloodfillResult", B8G8R8A8, 0, 0);
+ }
+
+};
+
+class FilterDilationTest: public GraphicsTest {
+public:
+ FilterDilationTest()
+ : GraphicsTest("FilterDilationTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+ BitmapPtr pBmp = loadTestBmp("dilation", I8);
+ BitmapPtr pDestBmp = FilterDilation().apply(pBmp);
+ testEqual(*pDestBmp, "DilationResult", I8, 0, 0);
+ }
+
+};
+
+class FilterErosionTest: public GraphicsTest {
+public:
+ FilterErosionTest()
+ : GraphicsTest("FilterErosionTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+ BitmapPtr pBmp = loadTestBmp("erosion", I8);
+ BitmapPtr pDestBmp = FilterErosion().apply(pBmp);
+ testEqual(*pDestBmp, "ErosionResult", I8, 0, 0);
+ }
+
+};
+
+class FilterAlphaTest: public GraphicsTest {
+public:
+ FilterAlphaTest()
+ : GraphicsTest("FilterAlphaTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+ BitmapPtr pBmp = loadTestBmp("rgb24alpha-64x64", R8G8B8A8);
+ BitmapPtr pAlphaBmp = FilterGetAlpha().apply(pBmp);
+ testEqual(*pAlphaBmp, "GetAlphaResult", I8, 0, 0);
+ BitmapPtr pDestBmp(new Bitmap(*pBmp));
+ pDestBmp->setAlpha(*pAlphaBmp);
+ testEqual(*pDestBmp, *pBmp, "SetAlphaResult", 0, 0);
+ }
+
+};
+
+class FilterResizeBilinearTest: public GraphicsTest {
+public:
+ FilterResizeBilinearTest()
+ : GraphicsTest("FilterResizeBilinearTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+ BitmapPtr pBmp = loadTestBmp("rgb24alpha-64x64", B8G8R8A8);
+ runTestWithBitmap(pBmp);
+ pBmp = loadTestBmp("rgb24-64x64", B8G8R8X8);
+ runTestWithBitmap(pBmp);
+ pBmp = loadTestBmp("rgb24-65x65", B8G8R8);
+ runTestWithBitmap(pBmp);
+ }
+
+private:
+ void runTestWithBitmap(BitmapPtr pBmp)
+ {
+ BitmapPtr pDestBmp = FilterResizeBilinear(IntPoint(32,32)).apply(pBmp);
+ string sName = string("ResizeBilinearResult")
+ +getPixelFormatString(pBmp->getPixelFormat());
+ testEqual(*pDestBmp, sName, pBmp->getPixelFormat());
+ }
+
+};
+
+class FilterUnmultiplyAlphaTest: public GraphicsTest {
+public:
+ FilterUnmultiplyAlphaTest()
+ : GraphicsTest("FilterUnmultiplyAlphaTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+ BitmapPtr pBmp(new Bitmap(IntPoint(16, 1), B8G8R8A8));
+ for (int x = 0; x < 16; ++x) {
+ unsigned char * pPixel = pBmp->getPixels()+x*4;
+ unsigned char val = 17*x;
+ *(pPixel+REDPOS) = val;
+ *(pPixel+GREENPOS) = val;
+ *(pPixel+BLUEPOS) = val;
+ *(pPixel+ALPHAPOS) = val;
+ }
+ FilterUnmultiplyAlpha().applyInPlace(pBmp);
+ QUIET_TEST(*(pBmp->getPixels()+ALPHAPOS) == 0);
+ for (int x = 1; x < 16; ++x) {
+ unsigned char * pPixel = pBmp->getPixels()+x*4;
+ QUIET_TEST(*(pPixel+REDPOS) == 255);
+ QUIET_TEST(*(pPixel+GREENPOS) == 255);
+ QUIET_TEST(*(pPixel+BLUEPOS) == 255);
+ QUIET_TEST(*(pPixel+ALPHAPOS) == 17*x);
+ }
+ }
+
+private:
+
+};
+
+class GraphicsTestSuite: public TestSuite {
+public:
+ GraphicsTestSuite()
+ : TestSuite("GraphicsTestSuite")
+ {
+ addTest(TestPtr(new PixelTest));
+ addTest(TestPtr(new BitmapTest));
+ addTest(TestPtr(new Filter3x3Test));
+ addTest(TestPtr(new FilterConvolTest));
+ addTest(TestPtr(new FilterColorizeTest));
+ addTest(TestPtr(new FilterGrayscaleTest));
+ addTest(TestPtr(new FilterFillTest));
+ addTest(TestPtr(new FilterFlipTest));
+ addTest(TestPtr(new FilterFlipRGBTest));
+ addTest(TestPtr(new FilterFlipUVTest));
+ addTest(TestPtr(new FilterComboTest));
+ addTest(TestPtr(new HistoryPreProcessorTest));
+ addTest(TestPtr(new FilterHighpassTest));
+ addTest(TestPtr(new FilterGaussTest));
+ addTest(TestPtr(new FilterBlurTest));
+ addTest(TestPtr(new FilterBandpassTest));
+ addTest(TestPtr(new FilterFastBandpassTest));
+ addTest(TestPtr(new FilterFastDownscaleTest));
+ addTest(TestPtr(new FilterMaskTest));
+ addTest(TestPtr(new FilterThresholdTest));
+ addTest(TestPtr(new FilterFloodfillTest));
+ addTest(TestPtr(new FilterDilationTest));
+ addTest(TestPtr(new FilterErosionTest));
+ addTest(TestPtr(new FilterAlphaTest));
+ addTest(TestPtr(new FilterResizeBilinearTest));
+ addTest(TestPtr(new FilterUnmultiplyAlphaTest));
+ }
+};
+
+
+int main(int nargs, char** args)
+{
+ BitmapLoader::init(true);
+ GraphicsTest::createResultImgDir();
+ GraphicsTestSuite suite;
+ suite.runTests();
+ bool bOK = suite.isOk();
+
+ if (bOK) {
+ return 0;
+ } else {
+ return 1;
+ }
+}
+
diff --git a/src/imaging/Blob.cpp b/src/imaging/Blob.cpp
new file mode 100644
index 0000000..b4d5777
--- /dev/null
+++ b/src/imaging/Blob.cpp
@@ -0,0 +1,616 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+// Original author of this file is igor@c-base.org
+//
+
+#include "Blob.h"
+
+#include "../base/ObjectCounter.h"
+#include "../base/Exception.h"
+
+#include "../graphics/Filterfill.h"
+#include "../graphics/Pixel8.h"
+
+#include <stdlib.h>
+#include <math.h>
+
+#include <climits>
+#include <iostream>
+#include <algorithm>
+
+using namespace std;
+
+namespace avg {
+
+Blob::Blob(const Run& run)
+{
+ ObjectCounter::get()->incRef(&typeid(*this));
+ m_Runs.reserve(50);
+ m_Runs.push_back(run);
+ m_pParent = BlobPtr();
+
+ m_bStatsAvailable = false;
+}
+
+Blob::~Blob()
+{
+ ObjectCounter::get()->decRef(&typeid(*this));
+}
+
+RunArray *Blob::getRuns()
+{
+ return &m_Runs;
+}
+
+void Blob::addRun(const Run& run)
+{
+ AVG_ASSERT((m_Runs.end()-1)->m_Row <= run.m_Row);
+ m_Runs.push_back(run);
+}
+
+
+void Blob::merge(const BlobPtr& pOtherBlob)
+{
+ AVG_ASSERT(pOtherBlob);
+ RunArray * pOtherRuns = pOtherBlob->getRuns();
+ m_Runs.insert(m_Runs.end(), pOtherRuns->begin(), pOtherRuns->end());
+ pOtherRuns->clear();
+}
+
+void Blob::render(BitmapPtr pSrcBmp, BitmapPtr pDestBmp, Pixel32 color,
+ int min, int max, bool bFinger, bool bMarkCenter, Pixel32 centerColor)
+{
+ AVG_ASSERT(pSrcBmp);
+ AVG_ASSERT(pDestBmp);
+ AVG_ASSERT(pSrcBmp->getBytesPerPixel() == 1);
+ AVG_ASSERT(pDestBmp->getBytesPerPixel() == 4);
+ AVG_ASSERT(pSrcBmp->getSize() == pDestBmp->getSize());
+ unsigned char *pSrc;
+ unsigned char *pDest;
+ unsigned char *pColor = (unsigned char *)(&color);
+ int intensityScale = 2*256/(std::max(max-min, 1));
+ for (RunArray::iterator it = m_Runs.begin(); it != m_Runs.end(); ++it) {
+ AVG_ASSERT(it->m_Row < pSrcBmp->getSize().y);
+ AVG_ASSERT(it->m_StartCol >= 0);
+ AVG_ASSERT(it->m_EndCol <= pSrcBmp->getSize().x);
+ pSrc = pSrcBmp->getPixels()+it->m_Row*pSrcBmp->getStride();
+ pDest = pDestBmp->getPixels()+it->m_Row*pDestBmp->getStride();
+ int x = it->m_StartCol;
+ pSrc += x;
+ pDest+= x*4;
+ while (x < it->m_EndCol) {
+ int factor = (*pSrc-min)*intensityScale;
+ if (factor < 0) {
+ factor = 0;
+ }
+ if (factor > 255) {
+ factor = 255;
+ }
+ *(pDest++) = ((*pColor)*factor) >> 8;
+ *(pDest++) = ((*(pColor+1))*factor) >> 8;
+ *(pDest++) = ((*(pColor+2))*factor) >> 8;
+ *(pDest++) = ((*(pColor+3))*factor) >> 8;
+ pSrc++;
+ x++;
+ }
+ }
+ AVG_ASSERT(m_bStatsAvailable);
+ if (bMarkCenter) {
+ IntPoint center = IntPoint(int(m_Center.x+0.5), int(m_Center.y+0.5));
+
+ IntPoint end0 = IntPoint(m_ScaledBasis[0])+center;
+ pDestBmp->drawLine(center, end0, centerColor);
+ IntPoint end1 = IntPoint(m_ScaledBasis[1])+center;
+ pDestBmp->drawLine(center, end1, centerColor);
+
+ if (bFinger && m_RelatedBlobs.size() > 0) {
+ // Draw finger direction
+ BlobPtr pHandBlob = (m_RelatedBlobs)[0].lock();
+ if (pHandBlob) {
+ pDestBmp->drawLine(center, IntPoint(pHandBlob->getCenter()),
+ Pixel32(0xD7, 0xC9, 0x56, 0xFF));
+ }
+ }
+ if (!m_Contour.empty()) {
+ for (vector<IntPoint>::iterator it = m_Contour.begin()+1;
+ it != m_Contour.end(); ++it)
+ {
+ IntPoint pt1 = *(it-1);
+ IntPoint pt2 = *it;
+ pDestBmp->drawLine(pt1, pt2, centerColor);
+ }
+ pDestBmp->drawLine(*(m_Contour.end()-1), *m_Contour.begin(), centerColor);
+ }
+ }
+}
+
+bool Blob::contains(IntPoint pt)
+{
+ for (RunArray::iterator it = m_Runs.begin(); it != m_Runs.end(); ++it) {
+ if (it->m_Row == pt.y && it->m_StartCol <= pt.x && it->m_EndCol > pt.x) {
+ return true;
+ }
+ }
+ return false;
+}
+
+void Blob::calcStats()
+{
+ m_Center = calcCenter();
+ m_EstimatedNextCenter = m_Center;
+ m_Area = float(calcArea());
+ m_BoundingBox = calcBBox();
+ /*
+ more useful numbers that can be calculated from c
+ see e.g.
+ <http://www.cs.cf.ac.uk/Dave/Vision_lecture/node36.html#SECTION00173000000000000000>
+
+ Orientation = tan−1(2(c_xy)/(c_xx − c_yy)) /2
+ Inertia = c_xx + c_yy
+ Eccentricity = ...
+ */
+ float c_xx = 0; // Variance in x direction
+ float c_yy =0; // Variance in y direction
+ float c_xy = 0; // Covariance
+ float ll=0;
+ float l1;
+ float l2;
+ float tmp_x;
+ float tmp_y;
+ float mag;
+ for (RunArray::iterator r = m_Runs.begin(); r != m_Runs.end();++r) {
+ //This is the evaluated expression for the variance when using runs...
+ ll = float(r->length());
+ c_yy += ll* (r->m_Row- m_Center.y)*(r->m_Row- m_Center.y);
+ c_xx += ( (r->m_EndCol-1) * r->m_EndCol * (2*r->m_EndCol-1)
+ - (r->m_StartCol-1) * r->m_StartCol * (2*r->m_StartCol -1))/6.f
+ - m_Center.x * ((r->m_EndCol-1)*r->m_EndCol-(r->m_StartCol-1)*r->m_StartCol)
+ + ll* m_Center.x*m_Center.x;
+ c_xy += (r->m_Row-m_Center.y)*0.5f*( (r->m_EndCol-1)*r->m_EndCol
+ - (r->m_StartCol-1)*r->m_StartCol)
+ + ll *(m_Center.x*m_Center.y - m_Center.x*r->m_Row);
+ }
+
+ c_xx /= m_Area;
+ c_yy /= m_Area;
+ c_xy /= m_Area;
+
+ m_Inertia = c_xx + c_yy;
+
+ float T = sqrt( (c_xx - c_yy) * (c_xx - c_yy) + 4*c_xy*c_xy);
+ m_Eccentricity = ((c_xx + c_yy) + T)/((c_xx+c_yy) - T);
+ m_Orientation = 0.5f*atan2(2*c_xy,c_xx-c_yy);
+ // The l_i are variances (unit L^2) so to arrive at numbers that
+ // correspond to lengths in the picture we use sqrt
+ // Ensure that eigenvectors always have standard orientation, i.e. the determinant
+ // of the matrix with the eigenvectors as columns is >0
+ // E_1.x E_2.y - E_1.y E_2.x > 0
+ if (fabs(c_xy) > 1e-30) {
+ //FIXME. check l1!=0 l2!=0. li=0 happens for line-like components
+ l1 = 0.5f * ((c_xx+c_yy) + sqrt((c_xx+c_yy)*(c_xx+c_yy)-4*(c_xx*c_yy-c_xy*c_xy)));
+ l2 = 0.5f * ((c_xx+c_yy) - sqrt((c_xx+c_yy)*(c_xx+c_yy)-4*(c_xx*c_yy-c_xy*c_xy)));
+ tmp_x = c_xy/l1 - c_xx*c_yy/(c_xy*l1)+ (c_xx/c_xy);
+ tmp_y = 1.;
+ mag = sqrt(tmp_x*tmp_x + tmp_y*tmp_y);
+ m_EigenVector[0].x = tmp_x/mag;
+ m_EigenVector[0].y = tmp_y/mag;
+ m_EigenValues.x = l1;
+ tmp_x = c_xy/l2 - c_xx*c_yy/(c_xy*l2)+ (c_xx/c_xy);
+ tmp_y = 1.;
+ mag = sqrt(tmp_x*tmp_x + tmp_y*tmp_y);
+ m_EigenVector[1].x = tmp_x/mag;
+ m_EigenVector[1].y = tmp_y/mag;
+ m_EigenValues.y = l2;
+ if (m_EigenVector[0].x*m_EigenVector[1].y - m_EigenVector[0].y*m_EigenVector[1].x
+ < 0)
+ {
+ m_EigenVector[0] *= -1;
+ }
+ } else {
+ //matrix already diagonal
+ if (c_xx > c_yy) {
+ m_EigenVector[0].x = 1;
+ m_EigenVector[0].y = 0;
+ m_EigenVector[1].x = 0;
+ m_EigenVector[1].y = 1;
+ m_EigenValues.x = c_xx;
+ m_EigenValues.y = c_yy;
+ } else {
+ m_EigenVector[0].x = 0;
+ m_EigenVector[0].y = -1;
+ m_EigenVector[1].x = 1;
+ m_EigenVector[1].y = 0;
+ m_EigenValues.x = c_yy;
+ m_EigenValues.y = c_xx;
+ }
+ }
+ m_ScaledBasis[0].x = m_EigenVector[0].x*sqrt(m_EigenValues.x);
+ m_ScaledBasis[0].y = m_EigenVector[0].y*sqrt(m_EigenValues.x);
+ m_ScaledBasis[1].x = m_EigenVector[1].x*sqrt(m_EigenValues.y);
+ m_ScaledBasis[1].y = m_EigenVector[1].y*sqrt(m_EigenValues.y);
+
+ m_bStatsAvailable = true;
+}
+
+const glm::vec2& Blob::getCenter() const
+{
+ return m_Center;
+}
+
+const glm::vec2& Blob::getEstimatedNextCenter() const
+{
+ return m_EstimatedNextCenter;
+}
+
+float Blob::getArea() const
+{
+ return m_Area;
+}
+
+const IntRect& Blob::getBoundingBox() const
+{
+ return m_BoundingBox;
+}
+
+float Blob::getEccentricity() const
+{
+ return m_Eccentricity;
+}
+
+float Blob::getInertia() const
+{
+ return m_Inertia;
+}
+
+float Blob::getOrientation() const
+{
+ return m_Orientation;
+}
+
+const glm::vec2 & Blob::getScaledBasis(int i) const
+{
+ return m_ScaledBasis[i];
+}
+
+const glm::vec2 & Blob::getEigenVector(int i) const
+{
+ return m_EigenVector[i];
+}
+
+const glm::vec2 & Blob::getEigenValues() const
+{
+ return m_EigenValues;
+}
+
+void Blob::calcNextCenter(glm::vec2 oldCenter)
+{
+ m_EstimatedNextCenter = m_Center + (m_Center - oldCenter);
+}
+
+void Blob::clearRelated()
+{
+ m_RelatedBlobs.clear();
+}
+
+void Blob::addRelated(BlobPtr pBlob)
+{
+ m_RelatedBlobs.push_back(pBlob);
+}
+
+const BlobPtr Blob::getFirstRelated()
+{
+ if (m_RelatedBlobs.empty()) {
+ return BlobPtr();
+ } else {
+ return m_RelatedBlobs[0].lock();
+ }
+}
+
+glm::vec2 Blob::calcCenter()
+{
+ glm::vec2 center(0,0);
+ float c = 0;
+ for (RunArray::iterator r = m_Runs.begin(); r != m_Runs.end(); ++r) {
+ center += r->m_Center * float(r->length());
+ c += r->length();
+ }
+ center = center/c;
+ return center;
+}
+
+IntRect Blob::calcBBox()
+{
+ int x1 = INT_MAX;
+ int y1 = INT_MAX;
+ int x2 = 0;
+ int y2 = 0;
+ for (RunArray::iterator r = m_Runs.begin(); r!=m_Runs.end(); ++r) {
+ x1 = std::min(x1, r->m_StartCol);
+ y1 = std::min(y1, r->m_Row);
+ x2 = std::max(x2, r->m_EndCol);
+ y2 = std::max(y2, r->m_Row);
+ }
+ return IntRect(x1, y1, x2, y2);
+}
+
+int Blob::calcArea()
+{
+ int res = 0;
+ for (RunArray::iterator r = m_Runs.begin(); r != m_Runs.end(); ++r) {
+ res+= r->length();
+ }
+ return res;
+}
+
+void Blob::initRowPositions()
+{
+ int offset = m_BoundingBox.tl.y;
+ RunArray::iterator it = m_Runs.begin();
+ for (int i = 0; i < m_BoundingBox.height(); i++) {
+ while (it->m_Row-offset < i) {
+ it++;
+ }
+ m_RowPositions.push_back(it);
+ }
+}
+
+IntPoint getNeighbor(const IntPoint& pt, int dir)
+{
+ IntPoint neighborPt(pt);
+ // dir encoding:
+ // 3 2 1
+ // 4 pt 0
+ // 5 6 7
+ switch(dir) {
+ case 0:
+ case 1:
+ case 7:
+ neighborPt.x++;
+ break;
+ case 3:
+ case 4:
+ case 5:
+ neighborPt.x--;
+ break;
+ default:
+ break;
+ };
+ switch(dir) {
+ case 1:
+ case 2:
+ case 3:
+ neighborPt.y--;
+ break;
+ case 5:
+ case 6:
+ case 7:
+ neighborPt.y++;
+ break;
+ default:
+ break;
+ };
+ return neighborPt;
+}
+
+IntPoint Blob::findNeighborInside(const IntPoint& pt, int& dir)
+{
+ if (dir & 1) {
+ dir += 2;
+ } else {
+ dir++;
+ }
+ if (dir > 7) {
+ dir -= 8;
+ }
+
+ for (int i = 0; i < 8; i++) {
+ IntPoint curPt = getNeighbor(pt, dir);
+ if (ptIsInBlob(curPt)) {
+ return curPt;
+ } else {
+ dir--;
+ if (dir < 0) {
+ dir += 8;
+ }
+ }
+ }
+ AVG_ASSERT(false);
+ return pt;
+}
+
+bool runIsLess(const Run& r1, const Run& r2)
+{
+ return r1.m_Row < r2.m_Row;
+}
+
+void Blob::calcContour(int precision)
+{
+ sort(m_Runs.begin(), m_Runs.end(), runIsLess);
+ initRowPositions();
+
+ // Moore Neighbor Tracing.
+ IntPoint boundaryPt(m_Runs[0].m_StartCol, m_Runs[0].m_Row);
+ IntPoint firstPt(boundaryPt);
+ int i = precision;
+ int dir = 1;
+ do {
+ i++;
+ if (i >= precision) {
+ m_Contour.push_back(boundaryPt);
+ i = 0;
+ }
+ boundaryPt = findNeighborInside(boundaryPt, dir);
+ } while (firstPt != boundaryPt);
+}
+
+ContourSeq Blob::getContour()
+{
+ return m_Contour;
+}
+
+bool Blob::ptIsInBlob(const IntPoint& pt)
+{
+ if (m_BoundingBox.contains(pt)) {
+ RunArray::iterator it = m_RowPositions[pt.y-m_BoundingBox.tl.y];
+ while (it->m_Row == pt.y) {
+ if (pt.x >= it->m_StartCol && pt.x < it->m_EndCol) {
+ return true;
+ }
+ it++;
+ }
+ }
+ return false;
+}
+
+bool areConnected(const Run & run1, const Run & run2)
+{
+ if (run1.m_StartCol > run2.m_StartCol) {
+ return run2.m_EndCol > run1.m_StartCol;
+ } else {
+ return run1.m_EndCol > run2.m_StartCol;
+ }
+}
+
+void storeRuns(BlobVectorPtr pBlobs, RunArray* pUpperRuns, RunArray* pLowerRuns)
+{
+ for (RunArray::iterator run1_it = pUpperRuns->begin(); run1_it != pUpperRuns->end();
+ ++run1_it)
+ {
+ for (RunArray::iterator run2_it = pLowerRuns->begin();
+ run2_it != pLowerRuns->end(); ++run2_it)
+ {
+ if (run2_it->m_StartCol > run1_it->m_EndCol) {
+ break;
+ }
+ if (areConnected(*run1_it, *run2_it)) {
+ BlobPtr pBlob = run1_it->m_pBlob.lock();
+ while (pBlob->m_pParent) {
+ pBlob = pBlob->m_pParent;
+ }
+ if (!(run2_it->m_pBlob.expired())) {
+ BlobPtr c_blob = run2_it->m_pBlob.lock();
+ while (c_blob->m_pParent) {
+ c_blob = c_blob->m_pParent;
+ }
+ if (c_blob != pBlob) {
+ // When we merge, make sure the smaller blob is merged
+ // into the bigger one to avoid a speed hit.
+ if (pBlob->getRuns()->size() > c_blob->getRuns()->size()) {
+ pBlob->merge(c_blob); //destroys c_blobs runs_list
+ c_blob->m_pParent = pBlob;
+ } else {
+ c_blob->merge(pBlob);
+ pBlob->m_pParent = c_blob;
+ }
+ }
+ } else {
+ run2_it->m_pBlob = pBlob;
+ pBlob->addRun(*run2_it);
+ }
+ }
+ }
+ }
+ for (RunArray::iterator run2_it = pLowerRuns->begin(); run2_it != pLowerRuns->end();
+ ++run2_it)
+ {
+ if (run2_it->m_pBlob.expired()) {
+ BlobPtr pBlob = BlobPtr(new Blob(*run2_it));
+ pBlobs->push_back(pBlob);
+ run2_it->m_pBlob = pBlob;
+ }
+ }
+}
+
+void findRunsInLine(BitmapPtr pBmp, int y, RunArray* pRuns, unsigned char threshold)
+{
+ int runStart=0;
+ int runStop=0;
+ const unsigned char * pPixel = pBmp->getPixels()+y*pBmp->getStride();
+ bool bIsInRun = *pPixel > threshold;
+
+ int width = pBmp->getSize().x;
+ for (int x = 0; x < width; x++) {
+ bool bPixelInRun = *pPixel > threshold;
+ if (bIsInRun != bPixelInRun) {
+ if (bIsInRun) {
+ // Only if the run is longer than one pixel.
+ if (x-runStart > 1) {
+ runStop = x;
+ pRuns->push_back(Run(y, runStart, runStop));
+ runStart = x;
+ }
+ } else {
+ runStop = x - 1;
+ if (runStop-runStart == 0 && !pRuns->empty()) {
+ // Single dark pixel: ignore the pixel, revive the last run.
+ runStart = pRuns->back().m_StartCol;
+ pRuns->pop_back();
+ } else {
+ runStart = x;
+ }
+ }
+ bIsInRun = bPixelInRun;
+ }
+ pPixel++;
+ }
+ if (bIsInRun) {
+ pRuns->push_back(Run(y, runStart, width));
+ }
+}
+
+BlobVectorPtr findConnectedComponents(BitmapPtr pBmp, unsigned char threshold)
+{
+ AVG_ASSERT(pBmp->getPixelFormat() == I8);
+ BlobVectorPtr pBlobs = BlobVectorPtr(new BlobVector);
+ IntPoint size = pBmp->getSize();
+ RunArray* pUpperRuns = new RunArray();
+ RunArray* pLowerRuns = new RunArray();
+
+ int y = 0;
+ findRunsInLine(pBmp, 0, pUpperRuns, threshold);
+ for (RunArray::iterator it = pUpperRuns->begin(); it!=pUpperRuns->end(); ++it) {
+ BlobPtr pBlob = BlobPtr(new Blob(*it));
+ pBlobs->push_back(pBlob);
+ it->m_pBlob = pBlob;
+ }
+
+ for (y = 1; y < size.y; y++) {
+ findRunsInLine(pBmp, y, pLowerRuns, threshold);
+ storeRuns(pBlobs, pUpperRuns, pLowerRuns);
+ RunArray* pTmpRuns = pUpperRuns;
+ pUpperRuns = pLowerRuns;
+ pLowerRuns = pTmpRuns;
+ pLowerRuns->clear();
+ }
+ BlobVectorPtr pResultBlobs = BlobVectorPtr(new BlobVector);
+ for (BlobVector::iterator it = pBlobs->begin(); it != pBlobs->end(); ++it) {
+ if (!(*it)->m_pParent) {
+ pResultBlobs->push_back(*it);
+ (*it)->calcStats();
+ }
+ }
+ delete pUpperRuns;
+ delete pLowerRuns;
+ return pResultBlobs;
+}
+
+
+}
diff --git a/src/imaging/Blob.h b/src/imaging/Blob.h
new file mode 100644
index 0000000..aff1994
--- /dev/null
+++ b/src/imaging/Blob.h
@@ -0,0 +1,120 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+// Original author of this file is igor@c-base.org
+//
+
+#ifndef _ConnectedComps_H_
+#define _ConnectedComps_H_
+
+#include "../api.h"
+#include "Run.h"
+
+#include "../graphics/Bitmap.h"
+#include "../graphics/Pixel32.h"
+
+#include "../base/GLMHelper.h"
+
+#include <vector>
+
+#include <boost/shared_ptr.hpp>
+#include <boost/weak_ptr.hpp>
+
+namespace avg {
+
+class Blob;
+typedef boost::shared_ptr<class Blob> BlobPtr;
+typedef boost::weak_ptr<class Blob> BlobWeakPtr;
+typedef std::vector<BlobPtr> BlobVector;
+typedef std::vector<BlobWeakPtr> BlobWeakPtrVector;
+typedef boost::shared_ptr<BlobVector> BlobVectorPtr;
+typedef std::vector<IntPoint> ContourSeq;
+
+class AVG_API Blob
+{
+ public:
+ Blob(const Run& run);
+ ~Blob();
+
+ void addRun(const Run& run);
+ void merge(const BlobPtr& other);
+ RunArray* getRuns();
+ void render(BitmapPtr pSrcBmp, BitmapPtr pDestBmp, Pixel32 Color,
+ int Min, int Max, bool bFinger, bool bMarkCenter,
+ Pixel32 CenterColor= Pixel32(0x00, 0x00, 0xFF, 0xFF));
+ bool contains(IntPoint pt);
+
+ void calcStats();
+ void calcContour(int Precision);
+ ContourSeq getContour();
+
+ const glm::vec2& getCenter() const;
+ const glm::vec2& getEstimatedNextCenter() const;
+ float getArea() const;
+ const IntRect & getBoundingBox() const;
+ float getEccentricity() const;
+ float getInertia() const;
+ float getOrientation() const;
+ const glm::vec2& getScaledBasis(int i) const;
+ const glm::vec2& getEigenVector(int i) const;
+ const glm::vec2& getEigenValues() const;
+
+ void calcNextCenter(glm::vec2 oldCenter);
+ void clearRelated();
+ void addRelated(BlobPtr pBlob);
+ const BlobPtr getFirstRelated();
+
+ BlobPtr m_pParent;
+
+ private:
+ Blob(const Blob &);
+ glm::vec2 calcCenter();
+ IntRect calcBBox();
+ int calcArea();
+ void initRowPositions();
+ IntPoint findNeighborInside(const IntPoint& Pt, int& Dir);
+ bool ptIsInBlob(const IntPoint& Pt);
+
+ RunArray m_Runs; // This array is unsorted until contours are calculated.
+ std::vector<RunArray::iterator> m_RowPositions;
+ BlobWeakPtrVector m_RelatedBlobs; // For fingers, this contains the hand.
+ // For hands, this contains the fingers.
+
+ bool m_bStatsAvailable;
+ glm::vec2 m_EstimatedNextCenter;
+ glm::vec2 m_Center;
+ float m_Area;
+ IntRect m_BoundingBox;
+ float m_Eccentricity;
+ float m_Inertia;
+ float m_Orientation;
+ glm::vec2 m_ScaledBasis[2];
+ glm::vec2 m_EigenVector[2];
+ glm::vec2 m_EigenValues;
+
+ ContourSeq m_Contour;
+};
+
+BlobVectorPtr AVG_API findConnectedComponents(BitmapPtr pBmp,
+ unsigned char threshold);
+
+}
+
+#endif
diff --git a/src/imaging/CMUCamera.cpp b/src/imaging/CMUCamera.cpp
new file mode 100644
index 0000000..6c68c5f
--- /dev/null
+++ b/src/imaging/CMUCamera.cpp
@@ -0,0 +1,466 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+// Original author of this file is Nick Hebner (hebnern@gmail.com).
+//
+
+#include "CMUCamera.h"
+#include "CMUCameraUtils.h"
+
+#include "../base/Exception.h"
+#include "../base/Logger.h"
+#include "../base/OSHelper.h"
+#include "../base/StringHelper.h"
+
+#include <windows.h>
+#include <1394Camera.h>
+
+using namespace std;
+
+namespace avg {
+
+CMUCamera::CMUCamera(long long guid, bool bFW800, IntPoint size,
+ PixelFormat camPF, PixelFormat destPF, float frameRate)
+ : Camera(camPF, destPF, size, frameRate),
+ m_WhitebalanceU(-1),
+ m_WhitebalanceV(-1),
+ m_pCamera(0)
+{
+ m_pCamera = new C1394Camera();
+ int err;
+ unsigned long videoFormat, videoMode;
+ getVideoFormatAndMode(getImgSize(), getCamPF(), &videoFormat, &videoMode);
+
+ // Find and open camera
+ if (m_pCamera->RefreshCameraList() <= 0) {
+ throw Exception(AVG_ERR_CAMERA_NONFATAL, "No Firewire cameras found");
+ }
+ int i = getCamIndex(guid);
+ err = m_pCamera->SelectCamera(i);
+ err = m_pCamera->InitCamera(TRUE);
+ AVG_ASSERT(err == CAM_SUCCESS);
+
+ if (bFW800) {
+ m_pCamera->Set1394b(true);
+ }
+
+ // Setup video format and rate
+ err = m_pCamera->SetVideoFormat(videoFormat);
+ checkCMUError(err, AVG_ERR_CAMERA_NONFATAL,
+ string("CMUCamera: Error setting video format ") + toString(videoFormat) +
+ ", mode: " + toString(videoMode));
+ err = m_pCamera->SetVideoMode(videoMode);
+ checkCMUError(err, AVG_ERR_CAMERA_NONFATAL,
+ string("CMUCamera: Error setting video mode ") + toString(videoMode) +
+ ", format: " + toString(videoFormat));
+ err = m_pCamera->SetVideoFrameRate(getFrameRateConst(getFrameRate()));
+ checkCMUError(err, AVG_ERR_CAMERA_NONFATAL, "Error setting frame rate");
+
+ // Start capturing images
+ err = m_pCamera->StartImageAcquisition();
+ if (err != CAM_SUCCESS) {
+ throw Exception(AVG_ERR_CAMERA_NONFATAL,
+ "CMUCamera: Could not start image acquisition. " +
+ CMUErrorToString(err));
+ }
+
+ // Set camera features
+ for (FeatureMap::iterator it=m_Features.begin(); it != m_Features.end(); it++) {
+ setFeature(it->first, it->second, true);
+ }
+ setWhitebalance(m_WhitebalanceU, m_WhitebalanceV, true);
+
+ if (camPF == BAYER8) {
+ char sModel[256], sVendor[256];
+ m_pCamera->GetCameraName(sModel, 256);
+ m_pCamera->GetCameraVendor(sVendor, 256);
+
+ if (strcmp(sModel, "DFx 31BF03") == 0) {
+ AVG_TRACE(Logger::category::CONFIG, Logger::severity::INFO,
+ "Applying bayer pattern fixup for IS DFx31BF03 camera");
+ setCamPF(BAYER8_GRBG);
+ } else if (strcmp(sVendor, "Point Grey Research") == 0) {
+ AVG_TRACE(Logger::category::CONFIG, Logger::severity::INFO,
+ "Applying bayer pattern fixup for PointGrey cameras");
+ enablePtGreyBayer();
+ }
+
+ }
+}
+
+CMUCamera::~CMUCamera()
+{
+ m_pCamera->StopImageAcquisition();
+ delete m_pCamera;
+}
+
+BitmapPtr CMUCamera::getImage(bool bWait)
+{
+ if (bWait) {
+ unsigned rc = WaitForSingleObject(m_pCamera->GetFrameEvent(), INFINITE);
+ AVG_ASSERT(rc == WAIT_OBJECT_0);
+ } else {
+ unsigned rc = WaitForSingleObject(m_pCamera->GetFrameEvent(), 0);
+ if (rc == WAIT_TIMEOUT) {
+ // No frame yet
+ return BitmapPtr();
+ }
+ AVG_ASSERT(rc == WAIT_OBJECT_0);
+ }
+ int rc2 = m_pCamera->AcquireImageEx(FALSE, NULL);
+ if (rc2 != CAM_SUCCESS) {
+ throw Exception(AVG_ERR_CAMERA_NONFATAL,
+ "CMUCamera: Could not acquire image from camera. " +
+ CMUErrorToString(rc2));
+ }
+ unsigned long captureBufferLength;
+ unsigned char* pCaptureBuffer = m_pCamera->GetRawData(&captureBufferLength);
+
+ BitmapPtr pCamBmp(new Bitmap(getImgSize(), getCamPF(), pCaptureBuffer,
+ captureBufferLength / getImgSize().y, false, "TempCameraBmp"));
+ return convertCamFrameToDestPF(pCamBmp);
+}
+
+
+const string& CMUCamera::getDevice() const
+{
+ return m_sDevice;
+}
+
+const std::string& CMUCamera::getDriverName() const
+{
+ static string sDriverName = "CMU 1394 Digital Camera Driver";
+ return sDriverName;
+}
+
+int CMUCamera::getFeature(CameraFeature Feature) const
+{
+ unsigned short val1;
+ unsigned short val2;
+ internalGetFeature(Feature, &val1, &val2);
+ return val1;
+}
+
+void CMUCamera::setFeature(CameraFeature Feature, int Value, bool bIgnoreOldValue)
+{
+ if (bIgnoreOldValue || m_Features[Feature] != Value) {
+ m_Features[Feature] = Value;
+ if (Feature == CAM_FEATURE_STROBE_DURATION) {
+ if (m_pCamera->HasStrobe()) {
+ C1394CameraControlStrobe* pControl = m_pCamera->GetStrobeControl(0);
+ int err = pControl->SetValue(Value);
+ checkCMUWarning(err == CAM_SUCCESS, "Error setting camera strobe.");
+ } else {
+ AVG_LOG_WARNING("Camera does not support strobe.");
+ }
+ } else {
+ CAMERA_FEATURE cmuFeature = getFeatureID(Feature);
+ if (m_pCamera->HasFeature(cmuFeature)) {
+ bool bAuto = (Value == -1);
+
+ C1394CameraControl* pControl = m_pCamera->GetCameraControl(cmuFeature);
+ int err1 = pControl->SetAutoMode(bAuto);
+ int err2 = CAM_SUCCESS;
+ if (!bAuto) {
+ err2 = pControl->SetValue(Value);
+ }
+ checkCMUWarning(err1 == CAM_SUCCESS && err2 == CAM_SUCCESS,
+ string("Error setting camera feature: ") +
+ cameraFeatureToString(Feature));
+ } else {
+ AVG_LOG_WARNING(string("Camera does not support feature: ") +
+ cameraFeatureToString(Feature));
+ }
+ }
+ }
+}
+
+void CMUCamera::setFeatureOneShot(CameraFeature Feature)
+{
+ CAMERA_FEATURE cmuFeature = getFeatureID(Feature);
+ if (cmuFeature != FEATURE_INVALID_FEATURE && m_pCamera->HasFeature(cmuFeature)) {
+ C1394CameraControl* pControl = m_pCamera->GetCameraControl(cmuFeature);
+ int err1 = pControl->SetOnOff(false);
+ int err2 = pControl->SetAutoMode(false);
+ int err3 = pControl->SetOnePush(true);
+ checkCMUWarning(err1 == CAM_SUCCESS && err2 == CAM_SUCCESS
+ && err3 == CAM_SUCCESS,
+ string("Error setting feature: ") + cameraFeatureToString(Feature));
+ } else {
+ AVG_LOG_WARNING(string("Camera does not support feature: ") +
+ cameraFeatureToString(Feature));
+ }
+}
+
+int CMUCamera::getWhitebalanceU() const
+{
+ unsigned short val1;
+ unsigned short val2;
+ internalGetFeature(CAM_FEATURE_WHITE_BALANCE, &val1, &val2);
+ return val1;
+}
+
+int CMUCamera::getWhitebalanceV() const
+{
+ unsigned short val1;
+ unsigned short val2;
+ internalGetFeature(CAM_FEATURE_WHITE_BALANCE, &val1, &val2);
+ return val2;
+}
+
+void CMUCamera::setWhitebalance(int u, int v, bool bIgnoreOldValue)
+{
+ if (bIgnoreOldValue || m_WhitebalanceU != u || m_WhitebalanceV != v) {
+ m_WhitebalanceU = u;
+ m_WhitebalanceV = v;
+ CAMERA_FEATURE cmuFeature = getFeatureID(CAM_FEATURE_WHITE_BALANCE);
+ if (m_pCamera->HasFeature(FEATURE_WHITE_BALANCE)) {
+ bool bAuto = (u == -1);
+
+ C1394CameraControl* pControl = m_pCamera->GetCameraControl(cmuFeature);
+ int err1 = pControl->SetAutoMode(bAuto);
+ int err2 = CAM_SUCCESS;
+ if (!bAuto) {
+ err2 = pControl->SetValue(u, v);
+ }
+ checkCMUWarning(err1 == CAM_SUCCESS && err2 == CAM_SUCCESS,
+ string("Error setting camera feature: ") +
+ cameraFeatureToString(CAM_FEATURE_WHITE_BALANCE));
+ } else {
+ AVG_LOG_WARNING(string("Camera does not support feature: ") +
+ cameraFeatureToString(CAM_FEATURE_WHITE_BALANCE));
+ }
+ }
+}
+
+int CMUCamera::countCameras()
+{
+ C1394Camera* pCamera = new C1394Camera();
+ if (pCamera->RefreshCameraList() <= 0) {
+ return 0;
+ }
+ int numCameras = pCamera->GetNumberCameras();
+ return numCameras;
+}
+
+CameraInfo* CMUCamera::getCameraInfos(int deviceNumber)
+{
+#ifdef AVG_ENABLE_CMU1394
+ C1394Camera* pCamera = new C1394Camera();
+ int err = pCamera->RefreshCameraList();
+ if (err <= 0) {
+ return 0;
+ }
+
+ err = pCamera->SelectCamera(deviceNumber);
+ if (err != CAM_SUCCESS) {
+ AVG_ASSERT(false);
+ }
+ pCamera->InitCamera(true);
+
+ long long uniqueID;
+ pCamera->GetCameraUniqueID((PLARGE_INTEGER)&uniqueID);
+ stringstream deviceID;
+ deviceID << uniqueID;
+
+ CameraInfo* pCamInfo = new CameraInfo("Firewire", deviceID.str());
+ getCameraImageFormats(pCamera, pCamInfo);
+ getCameraControls(pCamera, pCamInfo);
+
+ delete pCamera;
+ return pCamInfo;
+#endif
+ return NULL;
+}
+
+void CMUCamera::getCameraImageFormats(C1394Camera* pCamera, CameraInfo* pCamInfo)
+{
+ //Iterate over formats (up to 3 formats are supported)
+ for (int format = 0; format <= 2; format++) {
+ BOOL hasFormat = false;
+ hasFormat = pCamera->HasVideoFormat(format);
+ if(!hasFormat){
+ continue;
+ }
+ //Iterate over modes (up to 8 modes are supported)
+ for (int mode = 0; mode <= 7; mode++) {
+ BOOL hasMode = false;
+ hasMode = pCamera->HasVideoMode(format, mode);
+ if (!hasMode) {
+ continue;
+ }
+ //Ignore not libavg supported formats
+ if (mode == 0 && format == 0) {
+ continue;
+ }
+
+ IntPoint size;
+ PixelFormat pixelFormat;
+ FrameratesVector framerates;
+
+ getImageSizeAndPF(format, mode, size, pixelFormat);
+ getCameraFramerates(pCamera, format, mode, framerates);
+
+ CameraImageFormat imageFormat = CameraImageFormat(size, pixelFormat, framerates);
+ pCamInfo->addImageFormat(imageFormat);
+ }
+ }
+}
+
+void CMUCamera::getCameraFramerates(C1394Camera* pCamera, unsigned long videoFormat, unsigned long videoMode, FrameratesVector &framerates)
+{
+ for (int itFramerate = 0; itFramerate <= 7; itFramerate++) {
+ BOOL hasFramerate = false;
+ hasFramerate = pCamera->HasVideoFrameRate(videoFormat, videoMode, itFramerate);
+ if (!hasFramerate) {
+ continue;
+ }
+
+ float framerate = getFrameRateFloat(itFramerate);
+ framerates.push_back(framerate);
+ }
+}
+
+void CMUCamera::getCameraControls(C1394Camera* pCamera, CameraInfo* pCamInfo)
+{
+ //Iterate over amount of possible Features (up to 24 in CMU1394 DCD 6.4.5.240)
+ for (int indexFeature = 0; indexFeature <= 23; indexFeature++) {
+ C1394CameraControl* feature = pCamera->GetCameraControl((CAMERA_FEATURE)indexFeature);
+ if (feature == NULL) {
+ continue;
+ }
+ bool hasFeature = pCamera->HasFeature((CAMERA_FEATURE)indexFeature);
+ if (!hasFeature) {
+ continue;
+ }
+ //FrameRate (also known as TransferRate) is not supported
+ if (feature->GetFeatureID() == FEATURE_FRAME_RATE) {
+ continue;
+ }
+
+ std::string featureName = feature->GetName();
+ unsigned short min = -1;
+ unsigned short max = -1;
+ feature->GetRange(&min, &max);
+ unsigned short value_low = -1;
+ unsigned short value_high = -1; //TODO: For Whitebalance or Temperature etc.
+ feature->GetValue(&value_low, &value_high);
+ CameraControl camControl = CameraControl(featureName, (int)min, (int)max, (int)value_low);
+ pCamInfo->addControl(camControl);
+ }
+}
+
+int CMUCamera::getCamIndex(long long guid)
+{
+ if (guid == 0) {
+ return 0;
+ } else {
+ for (int i=0; i<m_pCamera->GetNumberCameras(); ++i) {
+ m_pCamera->SelectCamera(i);
+ long long camGuid;
+ m_pCamera->GetCameraUniqueID((PLARGE_INTEGER)&camGuid);
+ if (camGuid == guid) {
+ return i;
+ }
+ }
+ AVG_LOG_WARNING(string("Camera with guid ") + toString(guid)
+ + " not present. Using first camera.");
+ return 0;
+ }
+}
+
+void CMUCamera::internalGetFeature(CameraFeature Feature, unsigned short* val1,
+ unsigned short* val2) const
+{
+ *val1 = -1;
+ *val2 = -1;
+ CAMERA_FEATURE cmuFeature = getFeatureID(Feature);
+ if (m_pCamera->HasFeature(cmuFeature)) {
+ C1394CameraControl* pControl = m_pCamera->GetCameraControl(cmuFeature);
+ pControl->Status();
+ pControl->GetValue(val1, val2);
+ } else {
+ AVG_LOG_WARNING(string("Error reading camera feature: ") +
+ cameraFeatureToString(Feature));
+ }
+}
+
+void CMUCamera::enablePtGreyBayer()
+{
+ int err;
+ unsigned long advOffset = m_pCamera->GetAdvancedFeatureOffset();
+
+ unsigned long imageDataFormat;
+ err = m_pCamera->ReadQuadlet(advOffset+0x48, &imageDataFormat);
+ AVG_ASSERT(err == CAM_SUCCESS);
+ if (imageDataFormat & 0x80000000) {
+ err = m_pCamera->WriteQuadlet(advOffset+0x48, 0x80000081);
+ AVG_ASSERT(err == CAM_SUCCESS);
+ unsigned long bayerFormat;
+ err = m_pCamera->ReadQuadlet(advOffset+0x40, &bayerFormat);
+ AVG_ASSERT(err == CAM_SUCCESS);
+ PixelFormat exactPF = fwBayerStringToPF(bayerFormat);
+ setCamPF(exactPF);
+ } else {
+ AVG_LOG_ERROR("imageDataFormat not supported.");
+ }
+}
+
+void CMUCamera::checkCMUError(int code, int type, const string & sMsg) const
+{
+ if (code != CAM_SUCCESS) {
+ throw Exception(type, sMsg);
+ }
+}
+
+void CMUCamera::checkCMUWarning(bool bOk, const string& sMsg) const
+{
+ if (!bOk) {
+ AVG_LOG_WARNING(sMsg);
+ }
+}
+
+string CMUCamera::CMUErrorToString(int code)
+{
+ if (code == CAM_ERROR) {
+ return "WinI/O returned: " + getWinErrMsg(GetLastError());
+ }
+ string msg = "1394Camera returned: ";
+ switch (code) {
+ case CAM_ERROR_UNSUPPORTED:
+ return msg + "CAM_ERROR_UNSUPPORTED.";
+ case CAM_ERROR_NOT_INITIALIZED:
+ return msg + "CAM_ERROR_NOT_INITIALIZED.";
+ case CAM_ERROR_INVALID_VIDEO_SETTINGS:
+ return msg + "CAM_ERROR_INVALID_VIDEO_SETTINGS.";
+ case CAM_ERROR_BUSY:
+ return msg + "CAM_ERROR_BUSY.";
+ case CAM_ERROR_INSUFFICIENT_RESOURCES:
+ return msg + "CAM_ERROR_INSUFFICIENT_RESOURCES.";
+ case CAM_ERROR_PARAM_OUT_OF_RANGE:
+ return msg + "CAM_ERROR_PARAM_OUT_OF_RANGE.";
+ case CAM_ERROR_FRAME_TIMEOUT:
+ return msg + "CAM_ERROR_FRAME_TIMEOUT.";
+ default:
+ return msg + "unknown error.";
+ }
+}
+
+}
diff --git a/src/imaging/CMUCamera.h b/src/imaging/CMUCamera.h
new file mode 100644
index 0000000..a2f31e0
--- /dev/null
+++ b/src/imaging/CMUCamera.h
@@ -0,0 +1,82 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+// Original author of this file is Nick Hebner (hebnern@gmail.com).
+//
+
+#ifndef _CMUCamera_H_
+#define _CMUCamera_H_
+
+#include "../api.h"
+#include "Camera.h"
+
+#include <string>
+
+class C1394Camera;
+
+namespace avg {
+
+class AVG_API CMUCamera : public Camera {
+public:
+ CMUCamera(long long guid, bool bFW800, IntPoint Size, PixelFormat camPF,
+ PixelFormat destPF, float FrameRate);
+ virtual ~CMUCamera();
+
+ virtual BitmapPtr getImage(bool bWait);
+
+ virtual const std::string& getDevice() const;
+ virtual const std::string& getDriverName() const;
+
+ virtual int getFeature(CameraFeature Feature) const;
+ virtual void setFeature(CameraFeature Feature, int Value, bool bIgnoreOldValue=false);
+ virtual void setFeatureOneShot(CameraFeature Feature);
+ virtual int getWhitebalanceU() const;
+ virtual int getWhitebalanceV() const;
+ virtual void setWhitebalance(int u, int v, bool bIgnoreOldValue=false);
+
+ static void dumpCameras();
+ static int countCameras();
+ static CameraInfo* getCameraInfos(int deviceNumber);
+
+private:
+ int getCamIndex(long long guid);
+ void internalGetFeature(CameraFeature Feature, unsigned short* val1,
+ unsigned short* val2) const;
+ void enablePtGreyBayer();
+ void checkCMUError(int code, int type, const std::string& sMsg) const;
+ void checkCMUWarning(bool bOk, const std::string& sMsg) const;
+ std::string CMUErrorToString(int code);
+
+ static void getCameraControls(C1394Camera* pCamera, CameraInfo* camInfo);
+ static void getCameraImageFormats(C1394Camera* pCamera, CameraInfo* pCamInfo);
+ static void getCameraFramerates(C1394Camera* pCamera, unsigned long videoFormat,
+ unsigned long videoMode, FrameratesVector &framerates);
+
+ std::string m_sDevice;
+
+ mutable C1394Camera * m_pCamera; // The CMU1394 lib is not const-correct.
+ FeatureMap m_Features;
+ int m_WhitebalanceU;
+ int m_WhitebalanceV;
+};
+
+}
+
+#endif
diff --git a/src/imaging/CMUCameraUtils.cpp b/src/imaging/CMUCameraUtils.cpp
new file mode 100644
index 0000000..3e10570
--- /dev/null
+++ b/src/imaging/CMUCameraUtils.cpp
@@ -0,0 +1,369 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+// Original author of this file is Nick Hebner (hebnern@gmail.com).
+//
+
+#include "CMUCameraUtils.h"
+
+#include "../base/Logger.h"
+#include "../base/Exception.h"
+#include "../base/StringHelper.h"
+
+namespace avg {
+
+using namespace std;
+
+#define FORMAT_0 0
+// Format 0 Modes
+#define MODE_160_120_YUV444 0
+#define MODE_320x240_YUV422 1
+#define MODE_640x480_YUV411 2
+#define MODE_640x480_YUV422 3
+#define MODE_640x480_RGB 4
+#define MODE_640x480_MONO 5
+#define MODE_640x480_MONO16 6
+
+#define FORMAT_1 1
+// Format 1 Modes
+#define MODE_800x600_YUV422 0
+#define MODE_800x600_RGB 1
+#define MODE_800x600_MONO 2
+#define MODE_1024x768_YUV422 3
+#define MODE_1024x768_RGB 4
+#define MODE_1024x768_MONO 5
+#define MODE_800x600_MONO16 6
+#define MODE_1024x768_MONO16 7
+
+#define FORMAT_2 2
+#define MODE_1280x960_YUV422 0
+#define MODE_1280x960_RGB 1
+#define MODE_1280x960_MONO 2
+#define MODE_1600x1200_YUV422 3
+#define MODE_1600x1200_RGB 4
+#define MODE_1600x1200_MONO 5
+#define MODE_1280x960_MONO16 6
+#define MODE_1600x1200_MONO16 7
+
+// Framerates
+#define FRAMERATE_1_875 0
+#define FRAMERATE_3_75 1
+#define FRAMERATE_7_5 2
+#define FRAMERATE_15 3
+#define FRAMERATE_30 4
+#define FRAMERATE_60 5
+#define FRAMERATE_120 6
+#define FRAMERATE_240 7
+
+void getVideoFormatAndMode(IntPoint& Size, PixelFormat pf,
+ unsigned long* pVideoFormat, unsigned long* pVideoMode)
+{
+ *pVideoMode = -1;
+ *pVideoFormat = -1;
+ if (Size.x == 320 && Size.y == 240) {
+ *pVideoFormat = FORMAT_0;
+ if (pf == YCbCr422) {
+ *pVideoMode = MODE_320x240_YUV422;
+ }
+ } else if (Size.x == 640 && Size.y == 480) {
+ *pVideoFormat = FORMAT_0;
+ if (pf == I8 || pf == BAYER8) {
+ *pVideoMode = MODE_640x480_MONO;
+ } else if (pf == I16) {
+ *pVideoMode = MODE_640x480_MONO16;
+ } else if (pf == YCbCr411) {
+ *pVideoMode = MODE_640x480_YUV411;
+ } else if (pf == YCbCr422) {
+ *pVideoMode = MODE_640x480_YUV422;
+ } else if (pf == R8G8B8 || pf == B8G8R8) {
+ *pVideoMode = MODE_640x480_RGB;
+ }
+ } else if (Size.x == 800 && Size.y == 600) {
+ *pVideoFormat = FORMAT_1;
+ if (pf == I8 || pf == BAYER8) {
+ *pVideoMode = MODE_800x600_MONO;
+ } else if (pf == I16) {
+ *pVideoMode = MODE_800x600_MONO16;
+ } else if (pf == YCbCr422) {
+ *pVideoMode = MODE_800x600_YUV422;
+ } else if (pf == R8G8B8 || pf == B8G8R8) {
+ *pVideoMode = MODE_800x600_RGB;
+ }
+ } else if (Size.x == 1024 && Size.y == 768) {
+ *pVideoFormat = FORMAT_1;
+ if (pf == I8 || pf == BAYER8) {
+ *pVideoMode = MODE_1024x768_MONO;
+ } else if (pf == I16) {
+ *pVideoMode = MODE_1024x768_MONO16;
+ } else if (pf == YCbCr422) {
+ *pVideoMode = MODE_1024x768_YUV422;
+ } else if (pf == R8G8B8 || pf == B8G8R8) {
+ *pVideoMode = MODE_1024x768_RGB;
+ }
+ } else if (Size.x == 1280 && Size.y == 960) {
+ *pVideoFormat = FORMAT_2;
+ if (pf == I8 || pf == BAYER8) {
+ *pVideoMode = MODE_1280x960_MONO;
+ } else if (pf == I16) {
+ *pVideoMode = MODE_1280x960_MONO16;
+ } else if (pf == YCbCr422) {
+ *pVideoMode = MODE_1280x960_YUV422;
+ } else if (pf == R8G8B8 || pf == B8G8R8) {
+ *pVideoMode = MODE_1280x960_RGB;
+ }
+ } else if (Size.x == 1600 && Size.y == 1200) {
+ *pVideoFormat = FORMAT_2;
+ if (pf == I8 || pf == BAYER8) {
+ *pVideoMode = MODE_1600x1200_MONO;
+ } else if (pf == I16) {
+ *pVideoMode = MODE_1600x1200_MONO16;
+ } else if (pf == YCbCr422) {
+ *pVideoMode = MODE_1600x1200_YUV422;
+ } else if (pf == R8G8B8 || pf == B8G8R8) {
+ *pVideoMode = MODE_1600x1200_RGB;
+ }
+ }
+ if (*pVideoMode == -1 || *pVideoFormat == -1) {
+ throw Exception(AVG_ERR_INVALID_ARGS,
+ "Unsupported or illegal camera mode ("+toString(Size.x)+", "+toString(Size.y)+
+ "), "+getPixelFormatString(pf)+".");
+ }
+}
+
+unsigned long getFrameRateConst(float frameRate)
+{
+ if (frameRate == 1.875f) {
+ return FRAMERATE_1_875;
+ } else if (frameRate == 3.75f) {
+ return FRAMERATE_3_75;
+ } else if (frameRate == 7.5f) {
+ return FRAMERATE_7_5;
+ } else if (frameRate == 15) {
+ return FRAMERATE_15;
+ } else if (frameRate == 30) {
+ return FRAMERATE_30;
+ } else if (frameRate == 60) {
+ return FRAMERATE_60;
+ } else if (frameRate == 120) {
+ return FRAMERATE_120;
+ } else if (frameRate == 240) {
+ return FRAMERATE_240;
+ } else {
+ throw Exception(AVG_ERR_INVALID_ARGS,
+ "Unsupported or illegal value ("+toString(frameRate)+
+ ") for camera framerate.");
+ }
+}
+
+float getFrameRateFloat(unsigned long frameRate)
+{
+ if(frameRate == FRAMERATE_1_875){
+ return 1.875;
+ } else if (frameRate == FRAMERATE_3_75){
+ return 3.75;
+ } else if (frameRate == FRAMERATE_7_5){
+ return 7.5;
+ } else if (frameRate == FRAMERATE_15){
+ return 15;
+ } else if (frameRate == FRAMERATE_30){
+ return 30;
+ } else if (frameRate == FRAMERATE_60){
+ return 60;
+ } else if (frameRate == FRAMERATE_120){
+ return 120;
+ } else if (frameRate == FRAMERATE_240){
+ return 240;
+ } else {
+ throw Exception(AVG_ERR_INVALID_ARGS,
+ "Unsupported or illegal value ("+toString(frameRate)+
+ ") as camera framerate.");
+ }
+}
+
+CAMERA_FEATURE getFeatureID(CameraFeature Feature)
+{
+ switch(Feature) {
+ case CAM_FEATURE_BRIGHTNESS:
+ return FEATURE_BRIGHTNESS;
+ case CAM_FEATURE_EXPOSURE:
+ return FEATURE_AUTO_EXPOSURE;
+ case CAM_FEATURE_SHARPNESS:
+ return FEATURE_SHARPNESS;
+ case CAM_FEATURE_WHITE_BALANCE:
+ return FEATURE_WHITE_BALANCE;
+ case CAM_FEATURE_HUE:
+ return FEATURE_HUE;
+ case CAM_FEATURE_SATURATION:
+ return FEATURE_SATURATION;
+ case CAM_FEATURE_GAMMA:
+ return FEATURE_GAMMA;
+ case CAM_FEATURE_SHUTTER:
+ return FEATURE_SHUTTER;
+ case CAM_FEATURE_GAIN:
+ return FEATURE_GAIN;
+ case CAM_FEATURE_IRIS:
+ return FEATURE_IRIS;
+ case CAM_FEATURE_FOCUS:
+ return FEATURE_FOCUS;
+ case CAM_FEATURE_TEMPERATURE:
+ return FEATURE_TEMPERATURE;
+ case CAM_FEATURE_TRIGGER:
+ return FEATURE_TRIGGER_MODE;
+ case CAM_FEATURE_ZOOM:
+ return FEATURE_ZOOM;
+ case CAM_FEATURE_PAN:
+ return FEATURE_PAN;
+ case CAM_FEATURE_TILT:
+ return FEATURE_TILT;
+ case CAM_FEATURE_OPTICAL_FILTER:
+ return FEATURE_OPTICAL_FILTER;
+ case CAM_FEATURE_CAPTURE_SIZE:
+ return FEATURE_CAPTURE_SIZE;
+ case CAM_FEATURE_CAPTURE_QUALITY:
+ return FEATURE_CAPTURE_QUALITY;
+ default:
+ return FEATURE_INVALID_FEATURE;
+ }
+}
+
+void getImageSizeAndPF(unsigned long videoFormat, unsigned long videoMode,
+ IntPoint &pSize, PixelFormat &pPixelFormat)
+{
+ int format = (int) videoFormat;
+ int mode = (int) videoMode;
+ switch(format) {
+ case FORMAT_0: {
+ if (mode == MODE_160_120_YUV444) {
+ pSize = IntPoint(160,120);
+ pPixelFormat = PixelFormat(NO_PIXELFORMAT); //Not supported by libavg
+ return;
+ } else if (mode == MODE_320x240_YUV422) {
+ pSize = IntPoint(320,240);
+ pPixelFormat = PixelFormat(YCbCr422);
+ return;
+ } else if (mode == MODE_640x480_YUV411) {
+ pSize = IntPoint(640,480);
+ pPixelFormat = PixelFormat(YCbCr411);
+ return;
+ } else if (mode == MODE_640x480_YUV422) {
+ pSize = IntPoint(640,480);
+ pPixelFormat = PixelFormat(YCbCr422);
+ return;
+ } else if (mode == MODE_640x480_RGB) {
+ pSize = IntPoint(640,480);
+ pPixelFormat = PixelFormat(R8G8B8);
+ return;
+ } else if (mode == MODE_640x480_MONO) {
+ pSize = IntPoint(640,480);
+ pPixelFormat = PixelFormat(I8);
+ return;
+ } else if (mode == MODE_640x480_MONO16) {
+ pSize = IntPoint(640,480);
+ pPixelFormat = PixelFormat(I16);
+ return;
+ } else {
+ AVG_ASSERT(false);
+ return;
+ }
+ break;
+ } case FORMAT_1: {
+ if (mode == MODE_800x600_YUV422) {
+ pSize = IntPoint(800,600);
+ pPixelFormat = PixelFormat(YCbCr422);
+ return;
+ } else if (mode == MODE_800x600_RGB) {
+ pSize = IntPoint(800,600);
+ pPixelFormat = PixelFormat(R8G8B8);
+ return;
+ } else if (mode == MODE_800x600_MONO) {
+ pSize = IntPoint(800,600);
+ pPixelFormat = PixelFormat(I8);
+ return;
+ } else if (mode == MODE_1024x768_YUV422) {
+ pSize = IntPoint(1024,768);
+ pPixelFormat = PixelFormat(YCbCr422);
+ return;
+ } else if (mode == MODE_1024x768_RGB) {
+ pSize = IntPoint(1024,768);
+ pPixelFormat = PixelFormat(R8G8B8);
+ return;
+ } else if (mode == MODE_1024x768_MONO) {
+ pSize = IntPoint(1024,768);
+ pPixelFormat = PixelFormat(I8);
+ return;
+ } else if (mode == MODE_800x600_MONO16) {
+ pSize = IntPoint(800,600);
+ pPixelFormat = PixelFormat(I16);
+ return;
+ } else if (mode == MODE_1024x768_MONO16) {
+ pSize = IntPoint(1024,768);
+ pPixelFormat = PixelFormat(I16);
+ return;
+ } else {
+ AVG_ASSERT(false);
+ return;
+ }
+ break;
+ } case FORMAT_2: {
+ if (mode == MODE_1280x960_YUV422) {
+ pSize = IntPoint(1280,960);
+ pPixelFormat = PixelFormat(YCbCr422);
+ return;
+ } else if (mode == MODE_1280x960_RGB) {
+ pSize = IntPoint(1280,960);
+ pPixelFormat = PixelFormat(R8G8B8);
+ return;
+ } else if (mode == MODE_1280x960_MONO) {
+ pSize = IntPoint(1280,960);
+ pPixelFormat = PixelFormat(I8);
+ return;
+ } else if (mode == MODE_1600x1200_YUV422) {
+ pSize = IntPoint(1600,1200);
+ pPixelFormat = PixelFormat(YCbCr422);
+ return;
+ } else if (mode == MODE_1600x1200_RGB) {
+ pSize = IntPoint(1600,1200);
+ pPixelFormat = PixelFormat(R8G8B8);
+ return;
+ } else if (mode == MODE_1600x1200_MONO) {
+ pSize = IntPoint(1600,1200);
+ pPixelFormat = PixelFormat(I8);
+ return;
+ } else if (mode == MODE_1280x960_MONO16) {
+ pSize = IntPoint(1280,960);
+ pPixelFormat = PixelFormat(I16);
+ return;
+ } else if (mode == MODE_1600x1200_MONO16) {
+ pSize = IntPoint(1600,1200);
+ pPixelFormat = PixelFormat(I16);
+ return;
+ } else {
+ AVG_ASSERT(false);
+ return;
+ }
+ break;
+ } default: {
+ AVG_ASSERT(false);
+ return;
+ }
+ }
+}
+
+}
diff --git a/src/imaging/CMUCameraUtils.h b/src/imaging/CMUCameraUtils.h
new file mode 100644
index 0000000..0d00c9f
--- /dev/null
+++ b/src/imaging/CMUCameraUtils.h
@@ -0,0 +1,46 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+// Original author of this file is Nick Hebner (hebnern@gmail.com).
+//
+
+#ifndef _CMUCameraUtils_H_
+#define _CMUCameraUtils_H_
+
+#include "../api.h"
+#include "Camera.h"
+
+#include <windows.h>
+#include <1394Camera.h>
+
+#include <string>
+
+namespace avg {
+
+void getVideoFormatAndMode(IntPoint& Size, PixelFormat pf,
+ unsigned long* pVideoFormat, unsigned long* pVideoMode);
+unsigned long getFrameRateConst(float FrameRate);
+float getFrameRateFloat(unsigned long FrameRate);
+CAMERA_FEATURE getFeatureID(CameraFeature Feature);
+void getImageSizeAndPF(unsigned long videoFormat, unsigned long videoMode,
+ IntPoint &pSize, PixelFormat &pPixelFormat);
+}
+
+#endif
diff --git a/src/imaging/Camera.cpp b/src/imaging/Camera.cpp
new file mode 100644
index 0000000..51d778e
--- /dev/null
+++ b/src/imaging/Camera.cpp
@@ -0,0 +1,301 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "Camera.h"
+
+#include "../base/Logger.h"
+#include "../base/Exception.h"
+#include "../base/ScopeTimer.h"
+#include "../graphics/Filterfliprgb.h"
+
+#if defined(AVG_ENABLE_1394_2)
+#include "../imaging/FWCamera.h"
+#endif
+#ifdef AVG_ENABLE_V4L2
+#include "../imaging/V4LCamera.h"
+#endif
+#ifdef AVG_ENABLE_CMU1394
+#include "../imaging/CMUCamera.h"
+#endif
+#ifdef AVG_ENABLE_DSHOW
+#include "../imaging/DSCamera.h"
+#endif
+#include "../imaging/FakeCamera.h"
+
+#include <cstdlib>
+#include <string.h>
+
+#ifdef WIN32
+#define strtoll(p, e, b) _strtoi64(p, e, b)
+#endif
+
+namespace avg {
+
+using namespace std;
+
+Camera::Camera(PixelFormat camPF, PixelFormat destPF, IntPoint size, float frameRate)
+ : m_CamPF(camPF),
+ m_DestPF(destPF),
+ m_Size(size),
+ m_FrameRate(frameRate)
+{
+// cerr << "Camera: " << getPixelFormatString(camPF) << "-->"
+// << getPixelFormatString(destPF) << endl;
+}
+
+PixelFormat Camera::getCamPF() const
+{
+ return m_CamPF;
+}
+
+void Camera::setCamPF(PixelFormat pf)
+{
+ m_CamPF = pf;
+}
+
+PixelFormat Camera::getDestPF() const
+{
+ return m_DestPF;
+}
+
+static ProfilingZoneID CameraConvertProfilingZone("Camera format conversion", true);
+
+BitmapPtr Camera::convertCamFrameToDestPF(BitmapPtr pCamBmp)
+{
+ ScopeTimer Timer(CameraConvertProfilingZone);
+ BitmapPtr pDestBmp = BitmapPtr(new Bitmap(pCamBmp->getSize(), m_DestPF));
+ pDestBmp->copyPixels(*pCamBmp);
+ if (m_CamPF == R8G8B8 && m_DestPF == B8G8R8X8) {
+ pDestBmp->setPixelFormat(R8G8B8X8);
+ FilterFlipRGB().applyInPlace(pDestBmp);
+ }
+ if (m_CamPF != R8G8B8 && m_DestPF == R8G8B8X8) {
+ pDestBmp->setPixelFormat(B8G8R8X8);
+ FilterFlipRGB().applyInPlace(pDestBmp);
+ }
+
+ return pDestBmp;
+}
+
+IntPoint Camera::getImgSize()
+{
+ return m_Size;
+}
+
+float Camera::getFrameRate() const
+{
+ return m_FrameRate;
+}
+
+PixelFormat Camera::fwBayerStringToPF(unsigned long reg)
+{
+ string sBayerFormat((char*)&reg, 4);
+ if (sBayerFormat == "RGGB") {
+ return BAYER8_RGGB;
+ } else if (sBayerFormat == "GBRG") {
+ return BAYER8_GBRG;
+ } else if (sBayerFormat == "GRBG") {
+ return BAYER8_GRBG;
+ } else if (sBayerFormat == "BGGR") {
+ return BAYER8_BGGR;
+ } else if (sBayerFormat == "YYYY") {
+ return I8;
+ } else {
+ AVG_ASSERT(false);
+ return I8;
+ }
+}
+
+void Camera::setImgSize(const IntPoint& size)
+{
+ m_Size = size;
+}
+
+string cameraFeatureToString(CameraFeature feature)
+{
+ switch (feature) {
+ case CAM_FEATURE_BRIGHTNESS:
+ return "brightness";
+ case CAM_FEATURE_EXPOSURE:
+ return "exposure";
+ case CAM_FEATURE_SHARPNESS:
+ return "sharpness";
+ case CAM_FEATURE_WHITE_BALANCE:
+ return "white balance";
+ case CAM_FEATURE_HUE:
+ return "hue";
+ case CAM_FEATURE_SATURATION:
+ return "saturation";
+ case CAM_FEATURE_GAMMA:
+ return "gamma";
+ case CAM_FEATURE_SHUTTER:
+ return "shutter";
+ case CAM_FEATURE_GAIN:
+ return "gain";
+ case CAM_FEATURE_IRIS:
+ return "iris";
+ case CAM_FEATURE_FOCUS:
+ return "focus";
+ case CAM_FEATURE_TEMPERATURE:
+ return "temperature";
+ case CAM_FEATURE_TRIGGER:
+ return "trigger";
+ case CAM_FEATURE_TRIGGER_DELAY:
+ return "trigger delay";
+ case CAM_FEATURE_WHITE_SHADING:
+ return "white shading";
+ case CAM_FEATURE_ZOOM:
+ return "zoom";
+ case CAM_FEATURE_PAN:
+ return "pan";
+ case CAM_FEATURE_TILT:
+ return "tilt";
+ case CAM_FEATURE_OPTICAL_FILTER:
+ return "optical filter";
+ case CAM_FEATURE_CAPTURE_SIZE:
+ return "capture size";
+ case CAM_FEATURE_CAPTURE_QUALITY:
+ return "capture quality";
+ case CAM_FEATURE_CONTRAST:
+ return "contrast";
+ case CAM_FEATURE_STROBE_DURATION:
+ return "strobe duration";
+ default:
+ return "unknown";
+ }
+}
+
+CameraPtr createCamera(const string& sDriver, const string& sDevice, int unit,
+ bool bFW800, const IntPoint& captureSize, PixelFormat camPF, PixelFormat destPF,
+ float frameRate)
+{
+ CameraPtr pCamera;
+ try {
+ if (sDriver == "firewire") {
+ char * pszErr;
+ long long guid = strtoll(sDevice.c_str(), &pszErr, 16);
+ if (strlen(pszErr)) {
+ throw Exception(AVG_ERR_INVALID_ARGS, "'"+sDevice
+ +"' is not a valid GUID.");
+ }
+#if defined(AVG_ENABLE_1394_2)
+ pCamera = CameraPtr(new FWCamera(guid, unit, bFW800, captureSize, camPF,
+ destPF, frameRate));
+#elif defined(AVG_ENABLE_CMU1394)
+ if (unit != -1) {
+ throw Exception(AVG_ERR_INVALID_ARGS,
+ "camera 'unit' attribute is not supported when using the cmu firewire driver.");
+ }
+ pCamera = CameraPtr(new CMUCamera(guid, bFW800, captureSize, camPF, destPF,
+ frameRate));
+#else
+ (void)guid; // Silence compiler warning
+ AVG_LOG_WARNING("Firewire camera specified, but firewire "
+ "support not compiled in.");
+#endif
+ } else if (sDriver == "video4linux") {
+#if defined(AVG_ENABLE_V4L2)
+ pCamera = CameraPtr(new V4LCamera(sDevice, unit, captureSize, camPF,
+ destPF, frameRate));
+#else
+ AVG_LOG_WARNING("Video4Linux camera specified, but "
+ "Video4Linux support not compiled in.");
+#endif
+ } else if (sDriver == "directshow") {
+#if defined(AVG_ENABLE_DSHOW)
+ if (unit != -1) {
+ throw Exception(AVG_ERR_INVALID_ARGS,
+ "camera 'unit' attribute is not supported when using the directshow driver.");
+ }
+ pCamera = CameraPtr(new DSCamera(sDevice, captureSize, camPF, destPF,
+ frameRate));
+#else
+ AVG_LOG_WARNING("DirectShow camera specified, but "
+ "DirectShow is only available under windows.");
+#endif
+ } else {
+ throw Exception(AVG_ERR_INVALID_ARGS,
+ "Unable to set up camera. Camera source '"+sDriver+"' unknown.");
+ }
+ } catch (const Exception& e) {
+ if (e.getCode() == AVG_ERR_CAMERA_NONFATAL) {
+ AVG_LOG_WARNING(e.getStr());
+ } else {
+ throw;
+ }
+
+ }
+ if (!pCamera) {
+ pCamera = CameraPtr(new FakeCamera(camPF, destPF));
+ }
+ return pCamera;
+
+}
+
+std::vector<CameraInfo> getCamerasInfos()
+{
+ std::vector<CameraInfo> camerasInfo;
+
+#ifdef AVG_ENABLE_1394_2
+ int amountFWCameras = FWCamera::countCameras();
+ for (int i = 0; i < amountFWCameras; i++) {
+ CameraInfo* camInfo = FWCamera::getCameraInfos(i);
+ if (camInfo != NULL) {
+ camInfo->checkAddBayer8();
+ camerasInfo.push_back(*camInfo);
+ }
+ }
+#endif
+#ifdef AVG_ENABLE_CMU1394
+ int amountCMUCameras = CMUCamera::countCameras();
+ for (int i = 0; i < amountCMUCameras; i++) {
+ CameraInfo* camInfo = CMUCamera::getCameraInfos(i);
+ if (camInfo != NULL) {
+ camInfo->checkAddBayer8();
+ camerasInfo.push_back(*camInfo);
+ }
+ }
+#endif
+#ifdef AVG_ENABLE_DSHOW
+ int amountDSCameras = DSCamera::countCameras();
+ for (int i = 0; i < amountDSCameras; i++) {
+ CameraInfo* camInfo = DSCamera::getCameraInfos(i);
+ if (camInfo != NULL) {
+ camInfo->checkAddBayer8();
+ camerasInfo.push_back(*camInfo);
+ }
+ }
+#endif
+#ifdef AVG_ENABLE_V4L2
+ int amountV4LCameras = V4LCamera::countCameras();
+ for (int i = 0; i < amountV4LCameras; i++) {
+ CameraInfo* camInfo = V4LCamera::getCameraInfos(i);
+ if (camInfo != NULL) {
+ camInfo->checkAddBayer8();
+ camerasInfo.push_back(*camInfo);
+ }
+ }
+#endif
+ return camerasInfo;
+}
+
+
+}
diff --git a/src/imaging/Camera.h b/src/imaging/Camera.h
new file mode 100644
index 0000000..9d41574
--- /dev/null
+++ b/src/imaging/Camera.h
@@ -0,0 +1,120 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _Camera_H_
+#define _Camera_H_
+
+#include "../avgconfigwrapper.h"
+#include "../graphics/Bitmap.h"
+
+#include <boost/shared_ptr.hpp>
+#include "CameraInfo.h"
+
+#include <string>
+#include <list>
+#include <map>
+
+namespace avg {
+
+enum CameraFeature {
+ CAM_FEATURE_BRIGHTNESS,
+ CAM_FEATURE_EXPOSURE,
+ CAM_FEATURE_SHARPNESS,
+ CAM_FEATURE_WHITE_BALANCE,
+ CAM_FEATURE_HUE,
+ CAM_FEATURE_SATURATION,
+ CAM_FEATURE_GAMMA,
+ CAM_FEATURE_SHUTTER,
+ CAM_FEATURE_GAIN,
+ CAM_FEATURE_IRIS,
+ CAM_FEATURE_FOCUS,
+ CAM_FEATURE_TEMPERATURE,
+ CAM_FEATURE_TRIGGER,
+ CAM_FEATURE_TRIGGER_DELAY,
+ CAM_FEATURE_WHITE_SHADING,
+ CAM_FEATURE_ZOOM,
+ CAM_FEATURE_PAN,
+ CAM_FEATURE_TILT,
+ CAM_FEATURE_OPTICAL_FILTER,
+ CAM_FEATURE_CAPTURE_SIZE,
+ CAM_FEATURE_CAPTURE_QUALITY,
+ CAM_FEATURE_CONTRAST,
+ CAM_FEATURE_STROBE_DURATION,
+ CAM_FEATURE_UNSUPPORTED
+};
+
+class AVG_API Camera
+{
+public:
+ Camera(PixelFormat camPF, PixelFormat destPF, IntPoint size, float frameRate);
+ virtual ~Camera() {};
+ virtual void startCapture() {};
+
+ PixelFormat getCamPF() const;
+ void setCamPF(PixelFormat pf);
+ PixelFormat getDestPF() const;
+ BitmapPtr convertCamFrameToDestPF(BitmapPtr pCamBmp);
+
+ IntPoint getImgSize();
+ float getFrameRate() const;
+ virtual BitmapPtr getImage(bool bWait) = 0;
+
+ virtual const std::string& getDevice() const = 0;
+ virtual const std::string& getDriverName() const = 0;
+
+ virtual int getFeature(CameraFeature feature) const = 0;
+ virtual void setFeature(CameraFeature feature, int Value,
+ bool bIgnoreOldValue=false) = 0;
+ virtual void setFeatureOneShot(CameraFeature feature) = 0;
+ virtual int getWhitebalanceU() const = 0;
+ virtual int getWhitebalanceV() const = 0;
+ virtual void setWhitebalance(int u, int v, bool bIgnoreOldValue=false) = 0;
+
+protected:
+ PixelFormat fwBayerStringToPF(unsigned long reg);
+ void setImgSize(const IntPoint& size);
+
+private:
+ Camera();
+ PixelFormat m_CamPF;
+ PixelFormat m_DestPF;
+
+ IntPoint m_Size;
+ float m_FrameRate;
+};
+
+
+
+std::string cameraFeatureToString(CameraFeature feature);
+
+typedef boost::shared_ptr<Camera> CameraPtr;
+typedef std::map<CameraFeature, int> FeatureMap;
+
+AVG_API CameraPtr createCamera(const std::string& sDriver, const std::string& sDevice,
+ int unit, bool bFW800, const IntPoint& captureSize, PixelFormat camPF,
+ PixelFormat destPF, float frameRate);
+
+AVG_API std::vector<CameraInfo> getCamerasInfos();
+
+}
+
+#endif
+
diff --git a/src/imaging/CameraInfo.cpp b/src/imaging/CameraInfo.cpp
new file mode 100644
index 0000000..b33789f
--- /dev/null
+++ b/src/imaging/CameraInfo.cpp
@@ -0,0 +1,159 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+// V4L2/libavg compliance by 02L > Outside Standing Level
+
+#include "CameraInfo.h"
+
+namespace avg {
+
+CameraImageFormat::CameraImageFormat(IntPoint size, PixelFormat pixelFormat,
+ FrameratesVector framerates)
+{
+ m_Size = size;
+ m_PixelFormat = pixelFormat;
+ m_Framerates = framerates;
+}
+
+CameraImageFormat::~CameraImageFormat()
+{
+
+}
+
+IntPoint CameraImageFormat::getSize()
+{
+ return m_Size;
+}
+
+PixelFormat CameraImageFormat::getPixelFormat()
+{
+ return m_PixelFormat;
+}
+
+FrameratesVector CameraImageFormat::getFramerates()
+{
+ return m_Framerates;
+}
+
+
+CameraControl::CameraControl(const std::string& sControlName, int min, int max,
+ int defaultValue)
+{
+ m_sControlName = sControlName;
+ m_Min = min;
+ m_Max = max;
+ m_DefaultValue = defaultValue;
+}
+
+CameraControl::~CameraControl()
+{
+
+}
+
+std::string CameraControl::getControlName()
+{
+ return m_sControlName;
+}
+
+int CameraControl::getMin()
+{
+ return m_Min;
+}
+
+int CameraControl::getMax()
+{
+ return m_Max;
+}
+
+int CameraControl::getDefault()
+{
+ return m_DefaultValue;
+}
+
+
+CameraInfo::CameraInfo(const std::string& sDriver, const std::string& sDeviceID)
+{
+ m_sDriver = sDriver;
+ m_sDeviceID = sDeviceID;
+}
+
+CameraInfo::~CameraInfo()
+{
+
+}
+
+void CameraInfo::addControl(CameraControl control)
+{
+ m_Controls.push_back(control);
+}
+
+void CameraInfo::addImageFormat(CameraImageFormat format)
+{
+ m_Formats.push_back(format);
+}
+
+std::string CameraInfo::getDriver()
+{
+ return m_sDriver;
+}
+
+std::string CameraInfo::getDeviceID()
+{
+ return m_sDeviceID;
+}
+
+CameraImageFormatsVector CameraInfo::getImageFormats()
+{
+ return m_Formats;
+}
+
+CameraControlsVector CameraInfo::getControls()
+{
+ return m_Controls;
+}
+
+void CameraInfo::checkAddBayer8()
+{
+ CameraImageFormatsVector::iterator it = m_Formats.begin();
+ CameraImageFormatsVector i8ImageFormats;
+ bool hasColor = false;
+ for (; it!=m_Formats.end(); it++) {
+ PixelFormat pf = (*it).getPixelFormat();
+ if (pf == I8) {
+ i8ImageFormats.push_back(*it);
+ }
+ if (hasColor == false) {
+ hasColor = pixelFormatIsColored(pf);
+ }
+ }
+ if (hasColor) {
+ it = i8ImageFormats.begin();
+ for (; it!=i8ImageFormats.end(); it++) {
+ PixelFormat format = BAYER8;
+ IntPoint size = (*it).getSize();
+ FrameratesVector framerates = (*it).getFramerates();
+ CameraImageFormat bayerImageFormat = CameraImageFormat(size, format,
+ framerates);
+ m_Formats.push_back(bayerImageFormat);
+ }
+ }
+}
+
+}
diff --git a/src/imaging/CameraInfo.h b/src/imaging/CameraInfo.h
new file mode 100644
index 0000000..0c5a75b
--- /dev/null
+++ b/src/imaging/CameraInfo.h
@@ -0,0 +1,100 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef CameraInfo_H_
+#define CameraInfo_H_
+
+#include "../api.h"
+#include "../graphics/PixelFormat.h"
+#include "../base/GLMHelper.h"
+
+#include <string>
+#include <list>
+#include <map>
+
+namespace avg{
+
+typedef std::vector<float> FrameratesVector;
+
+class AVG_API CameraImageFormat
+{
+ public:
+ CameraImageFormat(IntPoint size, PixelFormat pixelFormat,
+ FrameratesVector framerates);
+ ~CameraImageFormat();
+
+ IntPoint getSize();
+ PixelFormat getPixelFormat();
+ FrameratesVector getFramerates();
+
+ private:
+ IntPoint m_Size;
+ PixelFormat m_PixelFormat;
+ FrameratesVector m_Framerates;
+};
+
+class AVG_API CameraControl
+{
+ public:
+ CameraControl(const std::string& sControlName, int min, int max,
+ int defaultValue);
+ ~CameraControl();
+
+ std::string getControlName();
+ int getMin();
+ int getMax();
+ int getDefault();
+
+ private:
+ std::string m_sControlName;
+ int m_Min;
+ int m_Max;
+ int m_DefaultValue;
+};
+
+typedef std::vector<CameraImageFormat> CameraImageFormatsVector;
+typedef std::vector<CameraControl> CameraControlsVector;
+
+class AVG_API CameraInfo
+{
+ public:
+ CameraInfo(const std::string& sDriver, const std::string& sDeviceID);
+ ~CameraInfo();
+
+ void addControl(CameraControl control);
+ void addImageFormat(CameraImageFormat format);
+
+ std::string getDriver();
+ std::string getDeviceID();
+ CameraImageFormatsVector getImageFormats();
+ CameraControlsVector getControls();
+ void checkAddBayer8();
+
+ private:
+ std::string m_sDriver;
+ std::string m_sDeviceID;
+ CameraImageFormatsVector m_Formats;
+ CameraControlsVector m_Controls;
+};
+
+}
+
+#endif /* CAMERAINFO_H_ */
diff --git a/src/imaging/CoordTransformer.cpp b/src/imaging/CoordTransformer.cpp
new file mode 100644
index 0000000..b4d7489
--- /dev/null
+++ b/src/imaging/CoordTransformer.cpp
@@ -0,0 +1,37 @@
+
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+// Original author of this file is igor@c-base.org
+//
+
+#include "CoordTransformer.h"
+
+namespace avg {
+
+CoordTransformer::CoordTransformer()
+{
+}
+
+CoordTransformer::~CoordTransformer()
+{
+}
+
+}
diff --git a/src/imaging/CoordTransformer.h b/src/imaging/CoordTransformer.h
new file mode 100644
index 0000000..b9ce97d
--- /dev/null
+++ b/src/imaging/CoordTransformer.h
@@ -0,0 +1,45 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _CoordTransformer_H_
+#define _CoordTransformer_H_
+
+#include "../api.h"
+#include "../base/GLMHelper.h"
+
+#include <boost/shared_ptr.hpp>
+
+namespace avg {
+
+class AVG_API CoordTransformer
+{
+public:
+ CoordTransformer();
+ virtual ~CoordTransformer();
+
+ virtual glm::dvec2 transform_point(const glm::dvec2 & pt) = 0;
+ virtual glm::dvec2 inverse_transform_point(const glm::dvec2 & pt) = 0;
+};
+
+typedef boost::shared_ptr<CoordTransformer> CoordTransformerPtr;
+
+}
+#endif
diff --git a/src/imaging/DSCamera.cpp b/src/imaging/DSCamera.cpp
new file mode 100644
index 0000000..e9e3b3b
--- /dev/null
+++ b/src/imaging/DSCamera.cpp
@@ -0,0 +1,733 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include <InitGuid.h>
+
+#include "DSHelper.h"
+#include "DSCamera.h"
+#include "DSSampleGrabber.h"
+
+#include "../base/Logger.h"
+#include "../base/Exception.h"
+#include "../base/ScopeTimer.h"
+#include "../graphics/FilterFlip.h"
+#include "../graphics/Filtergrayscale.h"
+
+#include <oleauto.h>
+
+#include <math.h>
+
+#include <sstream>
+
+namespace avg {
+
+using namespace std;
+
+DSCamera::DSCamera(std::string sDevice, IntPoint size, PixelFormat camPF,
+ PixelFormat destPF, float frameRate)
+ : Camera(camPF, destPF, size, frameRate),
+ m_sDevice(sDevice),
+ m_pGraph(0),
+ m_pCapture(0),
+ m_pCameraPropControl(0)
+{
+ open();
+}
+
+DSCamera::~DSCamera()
+{
+ close();
+}
+
+void DSCamera::open()
+{
+ initGraphBuilder();
+ findCaptureDevice(&m_pSrcFilter);
+ if (m_pSrcFilter) {
+ HRESULT hr;
+ hr = m_pGraph->AddFilter(m_pSrcFilter, L"Video Capture");
+ checkForDShowError(hr, "DSCamera::open()::Add capture filter");
+
+ // Create and configure the sample grabber that delivers the frames to the app.
+ m_pGrabFilter = new CSampleGrabber(NULL, &hr);
+ m_pGrabFilter->AddRef();
+ checkForDShowError(hr, "DSCamera::open()::Create SampleGrabber");
+ hr = m_pGrabFilter->QueryInterface(IID_IlibavgGrabber,
+ (void **)&m_pSampleGrabber);
+ checkForDShowError(hr, "DSCamera::open()::Create SampleGrabber 2");
+
+ hr = m_pSrcFilter->QueryInterface(IID_IAMVideoProcAmp,
+ (void **)&m_pCameraPropControl);
+ checkForDShowError(hr, "DSCamera::open()::get IAMVideoProcAmp");
+ hr = m_pSrcFilter->QueryInterface(IID_IAMCameraControl,
+ (void **)&m_pAMCameraControl);
+ checkForDShowError(hr, "DSCamera::open()::get IAMCameraControl");
+
+ hr = m_pGraph->AddFilter(m_pGrabFilter, L"Sample Grabber");
+ checkForDShowError(hr, "DSCamera::open()::Add Grabber");
+ setCaptureFormat();
+
+ checkForDShowError(hr, "DSCamera::open()::SetMediaType");
+
+ m_pSampleGrabber->SetCallback(this);
+
+ IBaseFilter * pNull;
+ hr = CoCreateInstance(CLSID_NullRenderer, NULL, CLSCTX_INPROC_SERVER,
+ IID_IBaseFilter, (LPVOID*) &pNull);
+ checkForDShowError(hr, "DSCamera::open()::Create null filter");
+ m_pGraph->AddFilter(pNull, L"NullRender");
+ pNull->Release();
+
+ connectFilters(m_pGraph, m_pSrcFilter, m_pGrabFilter);
+ connectFilters(m_pGraph, m_pGrabFilter, pNull);
+
+ // Add our graph to the running object table, which will allow
+ // the GraphEdit application to "spy" on our graph.
+ hr = AddGraphToRot(m_pGraph, &m_GraphRegisterID);
+ checkForDShowError(hr, "DSCamera::open()::AddGraphToRot");
+
+ } else {
+ throw (Exception(AVG_ERR_CAMERA_NONFATAL, "DS Camera unavailable"));
+ }
+}
+
+void DSCamera::startCapture()
+{
+ HRESULT hr = m_pMediaControl->Run();
+ checkForDShowError(hr, "DSCamera::open()::Run");
+}
+
+void DSCamera::close()
+{
+ if (m_pAMCameraControl) {
+ m_pAMCameraControl->Release();
+ }
+ m_pMediaControl->Stop();
+ RemoveGraphFromRot(m_GraphRegisterID);
+ m_pGraph->Release();
+ m_pCapture->Release();
+ m_pMediaControl->Release();
+ if (m_pCameraPropControl) {
+ m_pCameraPropControl->Release();
+ }
+ m_pSrcFilter->Release();
+ m_pGrabFilter->Release();
+ m_pSampleGrabber->Release();
+}
+
+BitmapPtr DSCamera::getImage(bool bWait)
+{
+ BitmapPtr pBmp;
+ try {
+ pBmp = m_BitmapQ.pop(bWait);
+ } catch (Exception&) {
+ return BitmapPtr();
+ }
+
+ return pBmp;
+}
+
+void DSCamera::setCaptureFormat()
+{
+ IAMStreamConfig *pSC;
+ HRESULT hr = m_pCapture->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video,
+ m_pSrcFilter, IID_IAMStreamConfig, (void **)&pSC);
+ checkForDShowError(hr, "DSCamera::setCaptureFormat::FindInterface");
+
+ int numCaps = 0;
+ int capsSize = 0;
+ hr = pSC->GetNumberOfCapabilities(&numCaps, &capsSize);
+ checkForDShowError(hr, "DSCamera::dumpMediaTypes::GetNumberOfCapabilities");
+
+ AVG_ASSERT(capsSize == sizeof(VIDEO_STREAM_CONFIG_CAPS));
+ bool bFormatFound = false;
+ bool bCloseFormatFound = false;
+ AM_MEDIA_TYPE* pmtConfig;
+ AM_MEDIA_TYPE* pmtCloseConfig;
+ vector<string> sImageFormats;
+ VIDEOINFOHEADER* pvih;
+ BITMAPINFOHEADER bih;
+ PixelFormat capsPF;
+ for (int i = 0; i < numCaps; i++) {
+ VIDEO_STREAM_CONFIG_CAPS scc;
+ hr = pSC->GetStreamCaps(i, &pmtConfig, (BYTE*)&scc);
+ checkForDShowError(hr, "DSCamera::dumpMediaTypes::GetStreamCaps");
+ pvih = (VIDEOINFOHEADER*)(pmtConfig->pbFormat);
+ bih = pvih->bmiHeader;
+ float frameRate = float(10000000L/pvih->AvgTimePerFrame);
+ capsPF = mediaSubtypeToPixelFormat(pmtConfig->subtype);
+
+ if (capsPF != NO_PIXELFORMAT && bih.biWidth != 0) {
+ sImageFormats.push_back(camImageFormatToString(pmtConfig));
+ }
+
+ bool bFormatUsed = false;
+ int height = bih.biHeight;
+ if (height < 0) {
+ height = -height;
+ }
+ if (bih.biWidth == getImgSize().x && height == getImgSize().y &&
+ (getCamPF() == capsPF || (getCamPF() == BAYER8_GBRG && capsPF == I8)))
+ {
+ if (fabs(getFrameRate()-frameRate) < 0.001) {
+ bFormatFound = true;
+ break;
+ } else if (!bCloseFormatFound) {
+ // The current format fits everything but the framerate.
+ // Not all framerates are reported, so we're going to try this one as
+ // well.
+ bCloseFormatFound = true;
+ bFormatUsed = true;
+ pmtCloseConfig = pmtConfig;
+ }
+ }
+ if (!bFormatUsed) {
+ CoTaskMemFree((PVOID)pmtConfig->pbFormat);
+ CoTaskMemFree(pmtConfig);
+ }
+ }
+ if (bFormatFound) {
+ AVG_TRACE(Logger::category::CONFIG, Logger::severity::INFO,
+ "Camera image format: " << camImageFormatToString(pmtConfig));
+ int height = ((VIDEOINFOHEADER*)(pmtConfig->pbFormat))->bmiHeader.biHeight;
+ m_bUpsideDown = (height > 0);
+ hr = pSC->SetFormat(pmtConfig);
+ checkForDShowError(hr, "DSCamera::dumpMediaTypes::SetFormat");
+ CoTaskMemFree((PVOID)pmtConfig->pbFormat);
+ CoTaskMemFree(pmtConfig);
+ } else {
+ if (bCloseFormatFound) {
+ // Set the framerate manually.
+ pvih = (VIDEOINFOHEADER*)(pmtCloseConfig->pbFormat);
+ pvih->AvgTimePerFrame = REFERENCE_TIME(10000000/getFrameRate());
+ int height = pvih->bmiHeader.biHeight;
+ m_bUpsideDown = (height > 0);
+ hr = pSC->SetFormat(pmtCloseConfig);
+ checkForDShowError(hr, "DSCamera::dumpMediaTypes::SetFormat");
+ AVG_TRACE(Logger::category::CONFIG, Logger::severity::INFO,
+ "Camera image format: " << camImageFormatToString(pmtCloseConfig));
+ CoTaskMemFree((PVOID)pmtCloseConfig->pbFormat);
+ CoTaskMemFree(pmtCloseConfig);
+
+ // TODO: Check if framerate is actually attained.
+ } else {
+ AVG_LOG_WARNING("Possibly incomplete list of camera image formats: ");
+ for (unsigned i = 0; i < sImageFormats.size(); i++) {
+ AVG_LOG_WARNING(" " << sImageFormats[i]);
+ }
+ throw Exception(AVG_ERR_CAMERA_NONFATAL,
+ "Could not find requested camera image format.");
+ }
+ }
+ pSC->Release();
+}
+
+
+const string& DSCamera::getDevice() const
+{
+ return m_sDevice;
+}
+
+const std::string& DSCamera::getDriverName() const
+{
+ static string sDriverName = "directshow";
+ return sDriverName;
+}
+
+int DSCamera::getFeature(CameraFeature feature) const
+{
+ long prop = getDSFeatureID(feature);
+ long val;
+ long flags;
+ HRESULT hr;
+ if (isDSFeatureCamControl(feature)) {
+ hr = m_pAMCameraControl->Get(prop, &val, &flags);
+ } else {
+ hr = m_pCameraPropControl->Get(prop, &val, &flags);
+ }
+ if (!SUCCEEDED(hr)) {
+ AVG_LOG_WARNING("DSCamera::getFeature " + cameraFeatureToString(feature)+
+ " failed.");
+ return 0;
+ }
+ return val;
+}
+
+void DSCamera::setFeature(CameraFeature feature, int value, bool bIgnoreOldValue)
+{
+ long prop = getDSFeatureID(feature);
+ if (!m_pCameraPropControl) {
+ return;
+ }
+ long flags;
+ if (value == -1) {
+ flags = VideoProcAmp_Flags_Auto;
+ } else {
+ flags = VideoProcAmp_Flags_Manual;
+ }
+ HRESULT hr;
+ if (isDSFeatureCamControl(feature)) {
+ hr = m_pAMCameraControl->Set(prop, value, flags);
+ } else {
+ hr = m_pCameraPropControl->Set(prop, value, flags);
+ }
+ switch (hr) {
+ case E_INVALIDARG:
+ // TODO: Throw exception
+ AVG_LOG_ERROR("DSCamera::setFeature(" << cameraFeatureToString(feature) <<
+ ", " << value << ") failed.");
+ break;
+ case E_PROP_ID_UNSUPPORTED:
+ case E_PROP_SET_UNSUPPORTED:
+ AVG_LOG_ERROR("DSCamera::setFeature(" << cameraFeatureToString(feature)
+ << ") failed: Feature not supported by camera.");
+ break;
+ default:
+ checkForDShowError(hr, "DSCamera::setFeature()::Set value");
+ }
+}
+
+void DSCamera::setFeatureOneShot(CameraFeature feature)
+{
+ AVG_LOG_WARNING(
+ "OneShot feature setting not implemented for DirectShow camera driver.");
+}
+
+int DSCamera::getWhitebalanceU() const
+{
+ AVG_LOG_WARNING(
+ "Whitebalance not implemented for DirectShow camera driver.");
+ return 0;
+}
+
+int DSCamera::getWhitebalanceV() const
+{
+ AVG_LOG_WARNING(
+ "Whitebalance not implemented for DirectShow camera driver.");
+ return 0;
+}
+
+void DSCamera::setWhitebalance(int u, int v, bool bIgnoreOldValue)
+{
+ AVG_LOG_WARNING(
+ "Whitebalance not implemented for DirectShow camera driver.");
+}
+
+void DSCamera::onSample(IMediaSample * pSample)
+{
+ unsigned char * pData;
+
+ // Get the current image.
+ pSample->GetPointer(&pData);
+
+ int stride = getImgSize().x*getBytesPerPixel(getCamPF());
+ Bitmap camBmp(getImgSize(), getCamPF(), pData, stride, false, "CameraImage");
+ // Copy over to bitmap queue, doing pixel format conversion if necessary.
+ BitmapPtr pDestBmp = BitmapPtr(new Bitmap(getImgSize(), getDestPF(),
+ "ConvertedCameraImage"));
+ pDestBmp->copyPixels(camBmp);
+
+ if (m_bUpsideDown) {
+ FilterFlip().applyInPlace(pDestBmp);
+ }
+
+ m_BitmapQ.push(pDestBmp);
+}
+
+int DSCamera::countCameras()
+{
+ int count = 0;
+ HRESULT hr = S_OK;
+ hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
+ checkForDShowError(hr, "DSCamera::countCameras()::CoInitializeEx");
+
+ ICreateDevEnum *pDevEnum =NULL;
+ hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC,
+ IID_ICreateDevEnum, (void **) &pDevEnum);
+ checkForDShowError(hr, "DSCamera::countCameras()::CreateDevEnum");
+
+ IEnumMoniker *pClassEnum = NULL;
+ hr = pDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pClassEnum, 0);
+ checkForDShowError(hr, "DSCamera::countCameras()::CreateClassEnumerator");
+
+ if (pClassEnum == NULL) {
+ pDevEnum->Release();
+ return count;
+ }
+ IMoniker* pMoniker = NULL;
+ while (pClassEnum->Next(1, &pMoniker, NULL) == S_OK) {
+ count += 1;
+ }
+ pMoniker->Release();
+ pClassEnum->Release();
+ pDevEnum->Release();
+ return count;
+}
+
+CameraInfo* DSCamera::getCameraInfos(int deviceNumber)
+{
+#ifdef AVG_ENABLE_DSHOW
+ HRESULT hr = S_OK;
+ // Create apartment for Thread
+ hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
+ checkForDShowError(hr, "DSCamera::getCameraInfos()::CoInitializeEx");
+ // Create the system device enumerator
+ ICreateDevEnum *pDevEnum =NULL;
+ hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC,
+ IID_ICreateDevEnum, (void **) &pDevEnum);
+ checkForDShowError(hr, "DSCamera::getCameraInfos()::CreateDevEnum");
+ // Create an enumerator for the video capture devices
+ IEnumMoniker *pClassEnum = NULL;
+ hr = pDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pClassEnum, 0);
+ checkForDShowError(hr, "DSCamera::getCameraInfos()::CreateClassEnumerator");
+ if (pClassEnum == NULL) {
+ pClassEnum->Release();
+ pDevEnum->Release();
+ return NULL;
+ }
+ IMoniker* pMoniker = NULL;
+ pClassEnum->Skip(deviceNumber);
+ hr = pClassEnum->Next(1, &pMoniker, NULL);
+ if (hr != S_OK) {
+ pClassEnum->Release();
+ pDevEnum->Release();
+ pMoniker->Release();
+ return NULL;
+ }
+ IPropertyBag* pPropBag;
+ hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void**)(&pPropBag));
+ checkForDShowError(hr, "DSCamera::getCameraInfos()::BindToStorage");
+
+ std::string deviceID = getStringProp(pPropBag, L"DevicePath");
+ if (deviceID.empty()) {
+ deviceID = getStringProp(pPropBag, L"Description");
+ if (deviceID.empty()) {
+ deviceID = getStringProp(pPropBag, L"FriendlyName");
+ }
+ }
+ CameraInfo* pCamInfo = new CameraInfo("DirectShow", deviceID);
+
+ getCameraImageFormats(pMoniker, pCamInfo);
+ getCameraControls(pMoniker, pCamInfo);
+
+ pPropBag->Release();
+ pMoniker->Release();
+ pClassEnum->Release();
+ pDevEnum->Release();
+ return pCamInfo;
+#endif
+ return NULL;
+}
+
+void DSCamera::getCameraImageFormats(IMoniker* pMoniker, CameraInfo* pCamInfo)
+{
+ HRESULT hr = S_OK;
+ IAMStreamConfig* pSC;
+ ICaptureGraphBuilder2* pCapture;
+ IBaseFilter* pSrcFilter;
+ // locates the object identified by pMoniker and
+ // returns a pointer to its filter interface
+ hr = pMoniker->BindToObject(0,0,IID_IBaseFilter, (void**) &pSrcFilter);
+ checkForDShowError(hr, "DSCamera::getImageFormats()::BindToObject");
+ if (pSrcFilter == NULL) {
+ return;
+ }
+ // Creates an uninitialized instance and returns a pointer to
+ // the IID_ICaptureGraphBuilder2 interface
+ hr = CoCreateInstance (CLSID_CaptureGraphBuilder2 , NULL, CLSCTX_INPROC,
+ IID_ICaptureGraphBuilder2, (void **) &pCapture);
+ checkForDShowError(hr, "DSCamera::getImageFormats()::CaptureGraphBuilder2");
+ // searches the graph for a IID_IAMStreamConfig interface, returns a pointer
+ hr = pCapture->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video,
+ pSrcFilter, IID_IAMStreamConfig, (void **)&pSC);
+ checkForDShowError(hr, "DSCamera::getImageFormats()::FindInterface");
+ int numCaps = 0;
+ int capsSize = 0;
+ hr = pSC->GetNumberOfCapabilities(&numCaps, &capsSize);
+ checkForDShowError(hr, "DSCamera::getImageFormats()::GetNumberOfCapabilities");
+ AM_MEDIA_TYPE* pmtConfig;
+ vector<string> sImageFormats;
+ VIDEOINFOHEADER* pvih;
+ BITMAPINFOHEADER bih;
+ PixelFormat capsPF;
+ for (int i = 0; i < numCaps; i++) {
+ VIDEO_STREAM_CONFIG_CAPS scc;
+ hr = pSC->GetStreamCaps(i, &pmtConfig, (BYTE*)&scc);
+ checkForDShowError(hr, "DSCamera::getImageFormats()::GetStreamCaps");
+ pvih = (VIDEOINFOHEADER*)(pmtConfig->pbFormat);
+ bih = pvih->bmiHeader;
+ capsPF = mediaSubtypeToPixelFormat(pmtConfig->subtype);
+
+ if (capsPF != NO_PIXELFORMAT && bih.biWidth != 0) {
+ IntPoint size;
+ if (bih.biHeight >= 0) {
+ size = IntPoint(bih.biWidth, bih.biHeight);
+ } else {
+ size = IntPoint(bih.biWidth, -bih.biHeight);
+ }
+
+ std::vector<float> framerates;
+ float minFramerate = (float)(10000000 / scc.MinFrameInterval);
+ float maxFramerate = (float)(10000000 / scc.MaxFrameInterval);
+ float averageFramerate = (float)(10000000 / pvih->AvgTimePerFrame);
+ if (maxFramerate != 0.) {
+ framerates.push_back(maxFramerate);
+ }
+ if (averageFramerate != maxFramerate && averageFramerate != minFramerate) {
+ framerates.push_back(averageFramerate);
+ }
+ if (minFramerate != 0. && minFramerate != maxFramerate) {
+ framerates.push_back(minFramerate);
+ }
+ CameraImageFormat imageFormat = CameraImageFormat(size, capsPF, framerates);
+ pCamInfo->addImageFormat(imageFormat);
+ }
+ }
+ pCapture->Release();
+ pSrcFilter->Release();
+}
+
+void DSCamera::getCameraControls(IMoniker* pMoniker, CameraInfo* pCamInfo)
+{
+ HRESULT hr = S_OK;
+ IBaseFilter * pSrcFilter;
+ // locates the object identified by pMoniker and
+ // returns a pointer to its filter interface
+ hr = pMoniker->BindToObject(0,0,IID_IBaseFilter, (void**) &pSrcFilter);
+ checkForDShowError(hr, "DSCamera::dumpImageFormats()::BindToObject");
+ if (pSrcFilter == NULL) {
+ return;
+ }
+ IAMCameraControl* pAMCameraControl;
+ pSrcFilter->QueryInterface(IID_IAMCameraControl,
+ (void **)&pAMCameraControl);
+ if (pAMCameraControl != NULL) {
+ // DirectShow has 7 supported CameraControlProperties
+ for (int indexControl = 0; indexControl <= 6; indexControl++) {
+ long value = -999;
+ long flags = -999;
+ pAMCameraControl->Get((CameraControlProperty)indexControl, &value, &flags);
+ long min = -999;
+ long max = -999;
+ long delta = -999;
+ long defaultValue = -999;
+ flags = -999;
+ pAMCameraControl->GetRange((CameraControlProperty)indexControl, &min, &max,
+ &delta, &defaultValue, &flags);
+
+ CameraFeature feature = getCameraFeatureID_CCP((CameraControlProperty)indexControl);
+ if (min != -999 && max != -999 && defaultValue != -999
+ && feature != CAM_FEATURE_UNSUPPORTED) {
+ std::string featureName = cameraFeatureToString(feature);
+ CameraControl control = CameraControl(featureName,min,max,defaultValue);
+ pCamInfo->addControl(control);
+ }
+ }
+ }
+ IAMVideoProcAmp* pCameraPropControl;
+ pSrcFilter->QueryInterface(IID_IAMVideoProcAmp,
+ (void **)&pCameraPropControl);
+ if (pCameraPropControl != NULL) {
+ // DirectShow has 10 supported VideoProcAmpProperties
+ for (int indexPropControl = 0; indexPropControl <= 9; indexPropControl++) {
+ long value = -999;
+ long flags = -999;
+ pCameraPropControl->Get((VideoProcAmpProperty)indexPropControl, &value,
+ &flags);
+ long min = -999;
+ long max = -999;
+ long delta = -999;
+ long defaultValue = -999;
+ flags = -999;
+ pCameraPropControl->GetRange((VideoProcAmpProperty)indexPropControl, &min,
+ &max, &delta, &defaultValue, &flags);
+
+ CameraFeature feature = getCameraFeatureID_VPAP((VideoProcAmpProperty)indexPropControl);
+ if (min != -999 && max != -999 && defaultValue != -999
+ && feature != CAM_FEATURE_UNSUPPORTED) {
+ std::string featureName = cameraFeatureToString(feature);
+ CameraControl control = CameraControl(featureName,min,max,defaultValue);
+ pCamInfo->addControl(control);
+ }
+ }
+ }
+}
+
+
+void DSCamera::initGraphBuilder()
+{
+ HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
+ checkForDShowError(hr, "DSCamera::initGraphBuilder()::CoInitializeEx");
+
+ // Create the filter graph
+ hr = CoCreateInstance (CLSID_FilterGraph, NULL, CLSCTX_INPROC, IID_IGraphBuilder,
+ (void **) &m_pGraph);
+ checkForDShowError(hr, "DSCamera::initGraphBuilder()::GraphBuilder");
+ // Create the capture graph builder
+ hr = CoCreateInstance (CLSID_CaptureGraphBuilder2 , NULL, CLSCTX_INPROC,
+ IID_ICaptureGraphBuilder2, (void **) &m_pCapture);
+ checkForDShowError(hr, "DSCamera::initGraphBuilder()::CaptureGraphBuilder2");
+
+ hr = m_pCapture->SetFiltergraph(m_pGraph);
+ checkForDShowError(hr, "DSCamera::initGraphBuilder()::SetFilterGraph");
+
+ m_pGraph->QueryInterface(IID_IMediaControl,(void**)&m_pMediaControl);
+}
+
+void DSCamera::findCaptureDevice(IBaseFilter ** ppSrcFilter)
+{
+ HRESULT hr = S_OK;
+ IBaseFilter * pSrc = NULL;
+ IMoniker* pMoniker = NULL;
+ ICreateDevEnum *pDevEnum = NULL;
+ IEnumMoniker *pClassEnum = NULL;
+
+ // Create the system device enumerator
+ hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC,
+ IID_ICreateDevEnum, (void **) &pDevEnum);
+ checkForDShowError(hr, "DSCamera::findCaptureDevice()::CreateDevEnum");
+
+ // Create an enumerator for the video capture devices
+ hr = pDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pClassEnum,
+ 0);
+ checkForDShowError(hr, "DSCamera::findCaptureDevice()::CreateClassEnumerator");
+
+ // If there are no enumerators for the requested type, then
+ // CreateClassEnumerator will succeed, but pClassEnum will be NULL.
+ if (pClassEnum == NULL) {
+ *ppSrcFilter = 0;
+ throw(Exception(AVG_ERR_CAMERA_NONFATAL, "No DirectShow Capture Device found"));
+ }
+
+ bool bFound = false;
+ while (!bFound && pClassEnum->Next(1, &pMoniker, NULL) == S_OK) {
+ IPropertyBag *pPropBag;
+ hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void**)(&pPropBag));
+ checkForDShowError(hr, "DSCamera::findCaptureDevice()::BindToStorage");
+
+ string sDescription = getStringProp(pPropBag, L"Description");
+ string sFriendlyName = getStringProp(pPropBag, L"FriendlyName");
+ string sDevicePath = getStringProp(pPropBag, L"DevicePath");
+
+ if (m_sDevice == sDescription || m_sDevice == sFriendlyName ||
+ sDevicePath.find(m_sDevice) != -1 || m_sDevice == "")
+ {
+ bFound = true;
+ } else {
+ pMoniker->Release();
+ }
+ pPropBag->Release();
+ }
+ if (!bFound) {
+ pClassEnum->Reset();
+ if (pClassEnum->Next(1, &pMoniker, NULL) == S_OK) {
+ AVG_LOG_WARNING(string("Camera ") + m_sDevice
+ + " not found. Using first camera.");
+ bFound = true;
+ IPropertyBag *pPropBag;
+ hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void**)(&pPropBag));
+ m_sDevice = getStringProp(pPropBag, L"FriendlyName");
+ checkForDShowError(hr, "DSCamera::findCaptureDevice()::BindToStorage");
+ pPropBag->Release();
+ } else {
+ throw(Exception(AVG_ERR_CAMERA_NONFATAL,
+ "No DirectShow Capture Device found"));
+ }
+ }
+
+ // Bind Moniker to a filter object
+ hr = pMoniker->BindToObject(0,0,IID_IBaseFilter, (void**)&pSrc);
+ checkForDShowError(hr, "DSCamera::findCaptureDevice()::BindToObject");
+
+ // Copy the found filter pointer to the output parameter.
+ *ppSrcFilter = pSrc;
+ (*ppSrcFilter)->AddRef();
+
+ pSrc->Release();
+ pMoniker->Release();
+ pDevEnum->Release();
+ pClassEnum->Release();
+}
+
+
+void DSCamera::connectFilters(IGraphBuilder *pGraph, IBaseFilter *pSrc,
+ IBaseFilter *pDest)
+{
+ IPin *pOut = 0;
+ getUnconnectedPin(pSrc, PINDIR_OUTPUT, &pOut);
+
+ IPin *pIn = 0;
+ getUnconnectedPin(pDest, PINDIR_INPUT, &pIn);
+
+ HRESULT hr = pGraph->ConnectDirect(pOut, pIn, 0);
+ checkForDShowError(hr, "DSCamera::ConnectFilters::Connect");
+ pOut->Release();
+ pIn->Release();
+}
+
+void DSCamera::getUnconnectedPin(IBaseFilter *pFilter, PIN_DIRECTION pinDir, IPin **ppPin)
+{
+ *ppPin = 0;
+ IEnumPins *pEnum = 0;
+ IPin *pPin = 0;
+ HRESULT hr = pFilter->EnumPins(&pEnum);
+ checkForDShowError(hr, "DSCamera::ConnectFilters::Connect");
+ while (pEnum->Next(1, &pPin, NULL) == S_OK)
+ {
+ PIN_DIRECTION thisPinDir;
+ pPin->QueryDirection(&thisPinDir);
+ if (thisPinDir == pinDir) {
+ IPin* pTmp = 0;
+ hr = pPin->ConnectedTo(&pTmp);
+ if (SUCCEEDED(hr)) { // Already connected, not the pin we want.
+ pTmp->Release();
+ } else { // Unconnected, this is the pin we want.
+ pEnum->Release();
+ *ppPin = pPin;
+ return;
+ }
+ }
+ pPin->Release();
+ }
+ pEnum->Release();
+ // Did not find a matching pin.
+ AVG_ASSERT(false);
+}
+
+#pragma warning(disable : 4995)
+void DSCamera::checkForDShowError(HRESULT hr, const string& sLocation)
+{
+ if (SUCCEEDED(hr)) {
+ return;
+ }
+ if (HRESULT_FACILITY(hr) == FACILITY_WINDOWS) {
+ hr = HRESULT_CODE(hr);
+ }
+ char szErr[MAX_ERROR_TEXT_LEN];
+ DWORD res = AMGetErrorText(hr, szErr, MAX_ERROR_TEXT_LEN);
+ if (res == 0) {
+ wsprintf(szErr, "Unknown Error: 0x%2x", hr);
+ }
+ cerr << sLocation << ": " << szErr << endl;
+}
+
+
+}
diff --git a/src/imaging/DSCamera.h b/src/imaging/DSCamera.h
new file mode 100644
index 0000000..3602a62
--- /dev/null
+++ b/src/imaging/DSCamera.h
@@ -0,0 +1,105 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _DSCamera_H_
+#define _DSCamera_H_
+
+#include "IDSSampleCallback.h"
+
+#include "../avgconfigwrapper.h"
+
+#include "Camera.h"
+
+#include "../graphics/Bitmap.h"
+#include "../graphics/Pixel24.h"
+
+#include "../base/GLMHelper.h"
+#include "../base/Queue.h"
+
+#include <string>
+#define _WIN32_DCOM
+#include <windows.h>
+#include <dshow.h>
+#include "Qedit.h"
+
+namespace avg {
+
+struct IlibavgGrabber;
+
+class DSCamera: public Camera, IDSSampleCallback
+{
+public:
+ DSCamera(std::string sDevice, IntPoint size, PixelFormat camPF, PixelFormat destPF,
+ float frameRate);
+ virtual ~DSCamera();
+ virtual void startCapture();
+
+ virtual BitmapPtr getImage(bool bWait);
+
+ virtual const std::string& getDevice() const;
+ virtual const std::string& getDriverName() const;
+
+ virtual int getFeature(CameraFeature feature) const;
+ virtual void setFeature(CameraFeature feature, int value,
+ bool bIgnoreOldValue=false);
+ virtual void setFeatureOneShot(CameraFeature feature);
+ virtual int getWhitebalanceU() const;
+ virtual int getWhitebalanceV() const;
+ virtual void setWhitebalance(int u, int v, bool bIgnoreOldValue=false);
+
+ virtual void onSample(IMediaSample * pSample);
+
+ static int countCameras();
+ static CameraInfo* getCameraInfos(int deviceNumber);
+
+private:
+ virtual void open();
+ virtual void close();
+ void initGraphBuilder();
+ void findCaptureDevice(IBaseFilter ** ppSrcFilter);
+
+ void setCaptureFormat();
+ void connectFilters(IGraphBuilder *pGraph, IBaseFilter *pSrc, IBaseFilter *pDest);
+ void getUnconnectedPin(IBaseFilter *pFilter, PIN_DIRECTION pinDir, IPin **ppPin);
+ static void checkForDShowError(HRESULT hr, const std::string & sAppMsg);
+ static void getCameraImageFormats(IMoniker* pMoniker, CameraInfo* pCamInfo);
+ static void getCameraControls(IMoniker* pMoniker, CameraInfo* pCamInfo);
+
+ std::string m_sDevice;
+
+ IGraphBuilder * m_pGraph;
+ ICaptureGraphBuilder2 * m_pCapture;
+ IMediaControl * m_pMediaControl;
+ IBaseFilter * m_pSrcFilter;
+ IBaseFilter * m_pGrabFilter;
+ IlibavgGrabber * m_pSampleGrabber;
+ IAMVideoProcAmp * m_pCameraPropControl;
+ IAMCameraControl * m_pAMCameraControl;
+
+ Queue<Bitmap> m_BitmapQ;
+
+ DWORD m_GraphRegisterID;
+ bool m_bUpsideDown;
+};
+
+}
+
+#endif
diff --git a/src/imaging/DSHelper.cpp b/src/imaging/DSHelper.cpp
new file mode 100644
index 0000000..d8880fb
--- /dev/null
+++ b/src/imaging/DSHelper.cpp
@@ -0,0 +1,311 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "DSHelper.h"
+
+#include "../base/Exception.h"
+#include "../base/Logger.h"
+
+#include <stdio.h>
+#include <oleauto.h>
+
+#include <string>
+
+using namespace std;
+
+namespace avg {
+
+#pragma warning(disable : 4995)
+HRESULT AddGraphToRot(IUnknown *pUnkGraph, DWORD *pdwRegister)
+{
+ IMoniker * pMoniker;
+ IRunningObjectTable *pROT;
+ WCHAR wsz[128];
+ HRESULT hr;
+
+ if (!pUnkGraph || !pdwRegister) {
+ return E_POINTER;
+ }
+
+ if (FAILED(GetRunningObjectTable(0, &pROT))) {
+ return E_FAIL;
+ }
+
+ hr = swprintf(wsz, NUMELMS(wsz), L"FilterGraph %08x pid %08x\0",
+ (DWORD_PTR)pUnkGraph, GetCurrentProcessId());
+
+ hr = CreateItemMoniker(L"!", wsz, &pMoniker);
+ if (SUCCEEDED(hr)) {
+ hr = pROT->Register(ROTFLAGS_REGISTRATIONKEEPSALIVE, pUnkGraph, pMoniker,
+ pdwRegister);
+ pMoniker->Release();
+ }
+
+ pROT->Release();
+ return hr;
+}
+
+void RemoveGraphFromRot(DWORD pdwRegister)
+{
+ IRunningObjectTable *pROT;
+
+ if (SUCCEEDED(GetRunningObjectTable(0, &pROT))) {
+ pROT->Revoke(pdwRegister);
+ pROT->Release();
+ }
+}
+
+string getStringProp(IPropertyBag *pPropBag, LPCOLESTR pszPropName)
+{
+ VARIANT varName;
+ VariantInit(&varName);
+ HRESULT hr = pPropBag->Read(pszPropName, &varName, 0);
+ if (FAILED(hr)) {
+ return "";
+ }
+// checkForDShowError(hr, string("DSHelper::getStringProp(")+pszPropName+")::Read PropBag");
+
+ string s;
+ int lenWStr = SysStringLen(varName.bstrVal);
+ int lenAStr = WideCharToMultiByte(CP_ACP, 0, varName.bstrVal, lenWStr, 0, 0, NULL, NULL);
+ if (lenAStr > 0) {
+ char* pAStr = new char[lenAStr + 1];
+ WideCharToMultiByte(CP_ACP, 0, varName.bstrVal, lenWStr, pAStr, lenAStr, NULL, NULL);
+ pAStr[lenAStr] = 0;
+ s = pAStr;
+ delete[] pAStr;
+ }
+
+ VariantClear(&varName);
+ return s;
+}
+
+PixelFormat mediaSubtypeToPixelFormat(const GUID& subtype)
+{
+ if (subtype == MEDIASUBTYPE_RGB24) {
+ return B8G8R8;
+ } else if (subtype == MEDIASUBTYPE_RGB32) {
+ return B8G8R8X8;
+ } else if (subtype == MEDIASUBTYPE_RGB8) {
+ return I8;
+ } else if (subtype == MEDIASUBTYPE_UYVY) {
+ return YCbCr422;
+ } else if (subtype == MEDIASUBTYPE_YUY2) {
+ return YUYV422;
+ } else if (subtype == MEDIASUBTYPE_RGB565) {
+ return B5G6R5;
+// } else if (Subtype == MEDIASUBTYPE_Y800 && DesiredPF == "BY8_GBRG") {
+// return BAYER8_GBRG;
+ } else if (subtype == MEDIASUBTYPE_Y800) {
+ return I8;
+ } else {
+ return NO_PIXELFORMAT;
+ }
+}
+
+std::string mediaTypeToString(const GUID& type)
+{
+ if (type == MEDIATYPE_Video) {
+ return "MEDIATYPE_Video";
+ } else if (type == GUID_NULL) {
+ return "GUID_NULL";
+ } else {
+ return "Unknown";
+ }
+}
+
+string mediaSubtypeToString(const GUID & subtype)
+{
+ if (subtype == MEDIASUBTYPE_RGB24) {
+ return "MEDIASUBTYPE_RGB24";
+ } else if (subtype == MEDIASUBTYPE_RGB32) {
+ return "MEDIASUBTYPE_RGB32";
+ } else if (subtype == MEDIASUBTYPE_RGB8) {
+ return "MEDIASUBTYPE_RGB8";
+ } else if (subtype == MEDIASUBTYPE_UYVY) {
+ return "MEDIASUBTYPE_UYVY";
+ } else if (subtype == MEDIASUBTYPE_YUY2) {
+ return "MEDIASUBTYPE_YUY2";
+ } else if (subtype == MEDIASUBTYPE_MJPG) {
+ return "MEDIASUBTYPE_MJPG";
+ } else if (subtype == MEDIASUBTYPE_RGB555) {
+ return "MEDIASUBTYPE_RGB555";
+ } else if (subtype == MEDIASUBTYPE_RGB565) {
+ return "MEDIASUBTYPE_RGB565";
+ } else if (subtype == MEDIASUBTYPE_Y800) {
+ return "MEDIASUBTYPE_Y800";
+ } else if (subtype == GUID_NULL) {
+ return "GUID_NULL";
+ } else {
+ return "Unknown";
+ }
+}
+
+string mediaFormattypeToString(const GUID& formattype)
+{
+ if (formattype == FORMAT_None) {
+ return "FORMAT_None";
+ } else if (formattype == FORMAT_VideoInfo) {
+ return "FORMAT_VideoInfo";
+ } else if (formattype == FORMAT_VideoInfo2) {
+ return "FORMAT_VideoInfo2";
+ } else if (formattype == GUID_NULL) {
+ return "GUID_NULL";
+ } else {
+ return "Unknown";
+ }
+}
+
+string camImageFormatToString(const AM_MEDIA_TYPE* pMediaType)
+{
+ stringstream ss;
+ VIDEOINFOHEADER* pVideoInfo = (VIDEOINFOHEADER*)(pMediaType->pbFormat);
+ BITMAPINFOHEADER* pBitmapInfo = &pVideoInfo->bmiHeader;
+ PixelFormat pf = mediaSubtypeToPixelFormat(pMediaType->subtype);
+ int height = abs(pBitmapInfo->biHeight);
+ ss << pf << " " << "(" << pBitmapInfo->biWidth << ", " << height << ")"
+ << " " << 10000000./pVideoInfo->AvgTimePerFrame << " fps.";
+ return ss.str();
+}
+
+bool isDSFeatureCamControl(CameraFeature feature)
+{
+ switch(feature) {
+ case CAM_FEATURE_BRIGHTNESS:
+ case CAM_FEATURE_SHARPNESS:
+ case CAM_FEATURE_WHITE_BALANCE:
+ case CAM_FEATURE_HUE:
+ case CAM_FEATURE_SATURATION:
+ case CAM_FEATURE_GAMMA:
+ case CAM_FEATURE_GAIN:
+ return false;
+ case CAM_FEATURE_EXPOSURE:
+ case CAM_FEATURE_IRIS:
+ case CAM_FEATURE_FOCUS:
+ case CAM_FEATURE_ZOOM:
+ case CAM_FEATURE_PAN:
+ case CAM_FEATURE_TILT:
+ return true;
+ case CAM_FEATURE_SHUTTER:
+ case CAM_FEATURE_TEMPERATURE:
+ case CAM_FEATURE_TRIGGER:
+ case CAM_FEATURE_OPTICAL_FILTER:
+ case CAM_FEATURE_CAPTURE_SIZE:
+ case CAM_FEATURE_CAPTURE_QUALITY:
+ case CAM_FEATURE_CONTRAST:
+ AVG_LOG_WARNING("isDSFeatureCamControl: " + cameraFeatureToString(feature) +
+ " not supported by DirectShow.");
+ return false;
+ default:
+ AVG_LOG_WARNING("isDSFeatureCamControl: " + cameraFeatureToString(feature) +
+ " unknown.");
+ return false;
+ }
+}
+
+long getDSFeatureID(CameraFeature feature)
+{
+ switch(feature) {
+ case CAM_FEATURE_BRIGHTNESS:
+ return VideoProcAmp_Brightness;
+ case CAM_FEATURE_SHARPNESS:
+ return VideoProcAmp_Sharpness;
+ case CAM_FEATURE_WHITE_BALANCE:
+ return VideoProcAmp_WhiteBalance;
+ case CAM_FEATURE_HUE:
+ return VideoProcAmp_Hue;
+ case CAM_FEATURE_SATURATION:
+ return VideoProcAmp_Saturation;
+ case CAM_FEATURE_GAMMA:
+ return VideoProcAmp_Gamma;
+ case CAM_FEATURE_GAIN:
+ return VideoProcAmp_Gain;
+ case CAM_FEATURE_EXPOSURE:
+ return CameraControl_Exposure;
+ case CAM_FEATURE_IRIS:
+ return CameraControl_Iris;
+ case CAM_FEATURE_FOCUS:
+ return CameraControl_Focus;
+ case CAM_FEATURE_ZOOM:
+ return CameraControl_Zoom;
+ case CAM_FEATURE_PAN:
+ return CameraControl_Pan;
+ case CAM_FEATURE_TILT:
+ return CameraControl_Tilt;
+ case CAM_FEATURE_SHUTTER:
+ case CAM_FEATURE_TEMPERATURE:
+ case CAM_FEATURE_TRIGGER:
+ case CAM_FEATURE_OPTICAL_FILTER:
+ case CAM_FEATURE_CAPTURE_SIZE:
+ case CAM_FEATURE_CAPTURE_QUALITY:
+ case CAM_FEATURE_CONTRAST:
+
+ AVG_LOG_WARNING("getDSFeatureID: "+cameraFeatureToString(feature)
+ +" not supported by DirectShow.");
+ return 0;
+ default:
+ AVG_LOG_WARNING("getDSFeatureID: "+cameraFeatureToString(feature)+" unknown.");
+ return -1;
+ }
+}
+
+CameraFeature getCameraFeatureID_VPAP(long videoProcAmpProperty)
+{
+ switch(videoProcAmpProperty) {
+ case VideoProcAmp_Brightness:
+ return CAM_FEATURE_BRIGHTNESS;
+ case VideoProcAmp_Sharpness:
+ return CAM_FEATURE_SHARPNESS;
+ case VideoProcAmp_WhiteBalance:
+ return CAM_FEATURE_WHITE_BALANCE;
+ case VideoProcAmp_Hue:
+ return CAM_FEATURE_HUE;
+ case VideoProcAmp_Saturation:
+ return CAM_FEATURE_SATURATION;
+ case VideoProcAmp_Gamma:
+ return CAM_FEATURE_GAMMA;
+ case VideoProcAmp_Gain:
+ return CAM_FEATURE_GAIN;
+ default:
+ return CAM_FEATURE_UNSUPPORTED;
+ }
+}
+CameraFeature getCameraFeatureID_CCP(long cameraControlProperty)
+{
+ switch(cameraControlProperty) {
+ case CameraControl_Exposure:
+ return CAM_FEATURE_EXPOSURE;
+ case CameraControl_Iris:
+ return CAM_FEATURE_IRIS;
+ case CameraControl_Focus:
+ return CAM_FEATURE_FOCUS;
+ case CameraControl_Zoom:
+ return CAM_FEATURE_ZOOM;
+ case CameraControl_Pan:
+ return CAM_FEATURE_PAN;
+ case CameraControl_Tilt:
+ return CAM_FEATURE_TILT;
+ default:
+ return CAM_FEATURE_UNSUPPORTED;
+ }
+}
+
+}
diff --git a/src/imaging/DSHelper.h b/src/imaging/DSHelper.h
new file mode 100644
index 0000000..a8c6edb
--- /dev/null
+++ b/src/imaging/DSHelper.h
@@ -0,0 +1,63 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _DSHelper_H_
+#define _DSHelper_H_
+
+#include "Camera.h"
+
+#include "../graphics/Bitmap.h"
+
+#include <string>
+
+#define _WIN32_DCOM
+#include <windows.h>
+#include <dshow.h>
+#include "Qedit.h"
+
+
+static const GUID MEDIASUBTYPE_Y800 =
+ {0x30303859, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
+
+static const GUID MEDIASUBTYPE_Y160 =
+ {0x30363159, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
+
+namespace avg {
+
+HRESULT AddGraphToRot(IUnknown* pUnkGraph, DWORD* pdwRegister);
+void RemoveGraphFromRot(DWORD pdwRegister);
+
+std::string getStringProp(IPropertyBag* pPropBag, LPCOLESTR pszPropName);
+
+PixelFormat mediaSubtypeToPixelFormat(const GUID& subtype);
+
+std::string mediaTypeToString(const GUID& type);
+std::string mediaSubtypeToString(const GUID& subtype);
+std::string mediaFormattypeToString(const GUID& formattype);
+std::string camImageFormatToString(const AM_MEDIA_TYPE* pMediaType);
+
+bool isDSFeatureCamControl(CameraFeature feature);
+long getDSFeatureID(CameraFeature feature);
+CameraFeature getCameraFeatureID_VPAP(long videoProcAmpProperty);
+CameraFeature getCameraFeatureID_CCP(long cameraControlProperty);
+}
+
+#endif
diff --git a/src/imaging/DSSampleGrabber.cpp b/src/imaging/DSSampleGrabber.cpp
new file mode 100644
index 0000000..1a62c2d
--- /dev/null
+++ b/src/imaging/DSSampleGrabber.cpp
@@ -0,0 +1,220 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "DSSampleGrabber.h"
+
+#include <initguid.h>
+
+#pragma warning(disable: 4800)
+
+// {455A53B7-FC34-4960-94CE-A17A0B23F807}
+DEFINE_GUID(CLSID_libavgGrabber,
+0x455a53b7, 0xfc34, 0x4960, 0x94, 0xce, 0xa1, 0x7a, 0xb, 0x23, 0xf8, 0x7);
+
+namespace avg {
+
+class CSampleGrabberAllocator : public CMemAllocator
+{
+public:
+ CSampleGrabberAllocator(CSampleGrabberInPin* pParent, HRESULT* phr);
+ ~CSampleGrabberAllocator();
+
+ HRESULT Alloc();
+ void ReallyFree();
+ STDMETHODIMP SetProperties(ALLOCATOR_PROPERTIES* pRequest,
+ ALLOCATOR_PROPERTIES* pActual);
+
+protected:
+ CSampleGrabberInPin * m_pPin;
+
+private:
+ friend class CSampleGrabberInPin;
+ friend class CSampleGrabber;
+};
+
+class CSampleGrabberInPin : public CTransInPlaceInputPin
+{
+public:
+ CSampleGrabberInPin(CTransInPlaceFilter* pFilter, HRESULT* pHr);
+ ~CSampleGrabberInPin();
+
+ HRESULT GetMediaType(int iPosition, CMediaType* pMediaType);
+
+ // override this or GetMediaType is never called
+ STDMETHODIMP EnumMediaTypes(IEnumMediaTypes** ppEnum);
+
+ // we override this to tell whoever's upstream of us what kind of
+ // properties we're going to demand to have
+ STDMETHODIMP GetAllocatorRequirements(ALLOCATOR_PROPERTIES *pProps);
+
+private:
+ friend class CSampleGrabberAllocator;
+ friend class CSampleGrabber;
+
+ CSampleGrabberAllocator* m_pPrivateAllocator;
+ ALLOCATOR_PROPERTIES m_allocprops;
+ BYTE* m_pBuffer;
+ BOOL m_bMediaTypeChanged;
+};
+
+CSampleGrabber::CSampleGrabber(IUnknown * pOuter, HRESULT * phr)
+ : CTransInPlaceFilter(TEXT("libavg sample grabber"), (IUnknown*) pOuter,
+ CLSID_libavgGrabber, phr, false),
+ m_pCallback(NULL)
+{
+ m_pInput = (CTransInPlaceInputPin*) new CSampleGrabberInPin(this, phr);
+
+ IPin *pOutput = GetPin(1);
+}
+
+STDMETHODIMP CSampleGrabber::NonDelegatingQueryInterface(REFIID riid, void** ppv)
+{
+ AVG_ASSERT(ppv);
+
+ if (riid == IID_IlibavgGrabber) {
+ return GetInterface((IlibavgGrabber *)this, ppv);
+ } else {
+ return CTransInPlaceFilter::NonDelegatingQueryInterface(riid, ppv);
+ }
+}
+
+HRESULT CSampleGrabber::CheckInputType(const CMediaType* pmt)
+{
+ AVG_ASSERT(pmt);
+ CAutoLock lock(&m_Lock);
+
+ if (MEDIATYPE_Video == *pmt->Type( )) {
+ return NOERROR;
+ } else {
+ return VFW_E_INVALID_MEDIA_TYPE;
+ }
+}
+
+HRESULT CSampleGrabber::Receive(IMediaSample * pms)
+{
+ AVG_ASSERT(pms);
+
+ HRESULT hr;
+ AM_SAMPLE2_PROPERTIES * const pProps = m_pInput->SampleProps();
+
+ if (pProps->dwStreamId != AM_STREAM_MEDIA) {
+ if (m_pOutput->IsConnected()) {
+ return m_pOutput->Deliver(pms);
+ } else {
+ return NOERROR;
+ }
+ }
+ if (UsingDifferentAllocators()) {
+ pms = Copy(pms);
+ AVG_ASSERT(pms);
+ }
+
+ hr = Transform(pms);
+ AVG_ASSERT(!FAILED(hr));
+ hr = m_pOutput->Deliver(pms);
+ if (UsingDifferentAllocators()) {
+ pms->Release();
+ }
+ return hr;
+}
+
+HRESULT CSampleGrabber::Transform(IMediaSample* pms)
+{
+ AVG_ASSERT(pms);
+ CAutoLock lock(&m_Lock);
+
+ if (m_pCallback) {
+ REFERENCE_TIME StartTime;
+ REFERENCE_TIME StopTime;
+ pms->GetTime( &StartTime, &StopTime);
+
+ StartTime += m_pInput->CurrentStartTime();
+ StopTime += m_pInput->CurrentStartTime();
+
+ m_pCallback->onSample(pms);
+ }
+ return NOERROR;
+}
+
+void STDMETHODCALLTYPE CSampleGrabber::SetCallback(IDSSampleCallback* pCallback)
+{
+ CAutoLock lock( &m_Lock );
+ m_pCallback = pCallback;
+}
+
+CSampleGrabberInPin::CSampleGrabberInPin(CTransInPlaceFilter* pFilter, HRESULT* pHr)
+ : CTransInPlaceInputPin(TEXT("SampleGrabberInputPin\0"), pFilter, pHr, L"Input\0"),
+ m_pPrivateAllocator(NULL),
+ m_pBuffer(NULL),
+ m_bMediaTypeChanged(FALSE)
+{
+ memset(&m_allocprops, 0, sizeof(m_allocprops));
+}
+
+CSampleGrabberInPin::~CSampleGrabberInPin()
+{
+ if (m_pPrivateAllocator) {
+ delete m_pPrivateAllocator;
+ }
+}
+
+HRESULT CSampleGrabberInPin::GetMediaType(int iPosition, CMediaType* pMediaType)
+{
+ AVG_ASSERT(pMediaType);
+ AVG_ASSERT(iPosition >= 0);
+ if (iPosition > 0) {
+ return VFW_S_NO_MORE_ITEMS;
+ }
+
+ *pMediaType = CMediaType();
+ pMediaType->SetType(&MEDIATYPE_Video);
+
+ return S_OK;
+}
+
+STDMETHODIMP CSampleGrabberInPin::EnumMediaTypes(IEnumMediaTypes** ppEnum)
+{
+ AVG_ASSERT(ppEnum);
+ ValidateReadWritePtr(ppEnum, sizeof(IEnumMediaTypes *));
+
+ if(!((CSampleGrabber*)m_pTIPFilter)->OutputPin()->IsConnected())
+ {
+ *ppEnum = new CEnumMediaTypes(this, NULL);
+ return NOERROR;
+ }
+
+ return ((CSampleGrabber*)m_pTIPFilter)->OutputPin()->GetConnected()
+ ->EnumMediaTypes(ppEnum);
+}
+
+HRESULT CSampleGrabberInPin::GetAllocatorRequirements(ALLOCATOR_PROPERTIES *pProps)
+{
+ AVG_ASSERT(pProps);
+
+ if (m_pPrivateAllocator) {
+ *pProps = m_allocprops;
+ return S_OK;
+ } else {
+ return CTransInPlaceInputPin::GetAllocatorRequirements(pProps);
+ }
+}
+
+} \ No newline at end of file
diff --git a/src/imaging/DSSampleGrabber.h b/src/imaging/DSSampleGrabber.h
new file mode 100644
index 0000000..8c3ba5e
--- /dev/null
+++ b/src/imaging/DSSampleGrabber.h
@@ -0,0 +1,91 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _DSSampleGrabber_H_
+#define _DSSampleGrabber_H_
+
+#include "IDSSampleCallback.h"
+
+#include "../base/Exception.h"
+
+#include <Guiddef.h>
+#define _WIN32_DCOM
+#include <windows.h>
+#include <dshow.h>
+#include <dshowbase/mtype.h>
+#include <dshowbase/wxdebug.h>
+#include <dshowbase/combase.h>
+#include <dshowbase/reftime.h>
+#include <dshowbase/wxutil.h>
+#include <dshowbase/wxlist.h>
+#include <dshowbase/amfilter.h>
+#include <dshowbase/transfrm.h>
+#include <dshowbase/transip.h>
+
+// {87F09DC5-12BC-479d-A20F-21133C613037}
+DEFINE_GUID(IID_IlibavgGrabber,
+0x87f09dc5, 0x12bc, 0x479d, 0xa2, 0xf, 0x21, 0x13, 0x3c, 0x61, 0x30, 0x37);
+
+namespace avg {
+
+MIDL_INTERFACE("6B652FFF-11FE-4FCE-92AD-0266B5D7C78F")
+IlibavgGrabber : public IUnknown
+{
+public:
+ virtual void STDMETHODCALLTYPE SetCallback(IDSSampleCallback* pCallback) = 0;
+};
+
+class CSampleGrabberInPin;
+
+class CSampleGrabber : public CTransInPlaceFilter, IlibavgGrabber
+{
+public:
+ CSampleGrabber(IUnknown* pOuter, HRESULT* pHr);
+
+ STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void** ppv);
+ DECLARE_IUNKNOWN;
+
+ // IlibavgGrabber
+ void STDMETHODCALLTYPE SetCallback(IDSSampleCallback* pCallback);
+
+protected:
+ IDSSampleCallback* m_pCallback;
+ CCritSec m_Lock; // serialize access to our data
+
+ HRESULT CheckInputType(const CMediaType* pmt);
+ HRESULT Transform(IMediaSample* pms);
+
+ // override this so we can return S_FALSE directly.
+ // The base class CTransInPlace
+ // Transform( ) method is called by it's
+ // Receive( ) method. There is no way
+ // to get Transform( ) to return an S_FALSE value
+ // (which means "stop giving me data"),
+ // to Receive( ) and get Receive( ) to return S_FALSE as well.
+ HRESULT Receive(IMediaSample* pms);
+
+private:
+ friend class CSampleGrabberInPin;
+};
+
+};
+
+#endif \ No newline at end of file
diff --git a/src/imaging/DeDistort.cpp b/src/imaging/DeDistort.cpp
new file mode 100644
index 0000000..5fec652
--- /dev/null
+++ b/src/imaging/DeDistort.cpp
@@ -0,0 +1,306 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+// Original author of this file is igor@c-base.org
+//
+
+#include "DeDistort.h"
+#include "TrackerConfig.h"
+
+#include "../base/StringHelper.h"
+#include "../base/MathHelper.h"
+#include "../glm/gtx/rotate_vector.hpp"
+#include <cstring>
+#include <iostream>
+#include <math.h>
+
+const double sqrt3 = sqrt(3.f);
+
+using namespace std;
+
+namespace avg {
+
+// This transformation is based on the undistort code found at
+// http://www.math.rutgers.edu/~ojanen/undistort/index.html.
+// a lot of parameters enter here, some of which can be calculated/set manually,
+// some of which need to be determined via an optimization procedure
+//
+// * m_CamExtents is the size of the camera image. This is used to transform the
+// coordinates of the image so they fall in the range (-1,-1)-(1,1)
+// * m_pDistortionParams OPT see paper
+// * m_Angle corrects rotation of camera OPT
+// * m_DisplayScale convert back from standard coords to display
+// * m_DisplayOffset correct the offset of the display from the center of the table
+//
+
+DeDistort::DeDistort()
+ : m_CamExtents(1,1),
+ m_Angle(0.0),
+ m_TrapezoidFactor(0),
+ m_DisplayOffset(0,0),
+ m_DisplayScale(1,1)
+{
+ m_DistortionParams.push_back(0);
+ m_DistortionParams.push_back(0);
+ m_RescaleFactor = calc_rescale();
+}
+
+DeDistort::DeDistort(const glm::vec2& camExtents, const glm::vec2& displayExtents)
+ : m_Angle(0.0),
+ m_TrapezoidFactor(0),
+ m_DisplayOffset(0,0)
+{
+ m_CamExtents = glm::vec2(camExtents);
+ m_DistortionParams.push_back(0);
+ m_DistortionParams.push_back(0);
+ m_DisplayScale.x = displayExtents.x/camExtents.x;
+ m_DisplayScale.y = displayExtents.y/camExtents.y;
+ m_RescaleFactor = calc_rescale();
+}
+
+DeDistort::DeDistort(const glm::vec2& camExtents, const vector<double>& distortionParams,
+ double angle, double trapezoidFactor, const glm::dvec2& displayOffset,
+ const glm::dvec2& displayScale)
+ : m_CamExtents(camExtents),
+ m_DistortionParams(distortionParams),
+ m_Angle(angle),
+ m_TrapezoidFactor(trapezoidFactor),
+ m_DisplayOffset(displayOffset),
+ m_DisplayScale(displayScale)
+{
+ m_RescaleFactor = calc_rescale();
+}
+
+DeDistort::~DeDistort()
+{
+}
+
+FRect DeDistort::getDisplayArea(const glm::vec2& displayExtents)
+{
+ return getActiveBlobArea(FRect(glm::vec2(0,0), displayExtents));
+}
+
+FRect DeDistort::getActiveBlobArea(const FRect& displayROI)
+{
+ FRect activeRect;
+ activeRect.tl = transformScreenToBlob(glm::dvec2(displayROI.tl));
+ activeRect.br = transformScreenToBlob(glm::dvec2(displayROI.br));
+ if (activeRect.height() < 1) {
+ float temp = activeRect.tl.y;
+ activeRect.tl.y = activeRect.br.y;
+ activeRect.br.y = temp;
+ }
+ if (activeRect.width() < 1) {
+ float temp = activeRect.tl.x;
+ activeRect.tl.x = activeRect.br.x;
+ activeRect.br.x = temp;
+ }
+ return activeRect;
+}
+
+void DeDistort::load(const glm::vec2& camExtents, const TrackerConfig& config)
+{
+ m_CamExtents = glm::dvec2(camExtents);
+ m_DistortionParams.clear();
+ m_DistortionParams.push_back(double(config.getFloatParam
+ ("/transform/distortionparams/@p2")));
+ m_DistortionParams.push_back(double(config.getFloatParam
+ ("/transform/distortionparams/@p3")));
+ m_TrapezoidFactor = config.getFloatParam("/transform/trapezoid/@value");
+ m_Angle = config.getFloatParam("/transform/angle/@value");
+ m_DisplayOffset = config.getPointParam("/transform/displaydisplacement/");
+ m_DisplayScale = config.getPointParam("/transform/displayscale/");
+
+ m_RescaleFactor = calc_rescale();
+}
+
+void DeDistort::save(TrackerConfig& config)
+{
+ config.setParam("/transform/distortionparams/@p2",
+ toString(m_DistortionParams[0]));
+ config.setParam("/transform/distortionparams/@p3",
+ toString(m_DistortionParams[1]));
+ config.setParam("/transform/trapezoid/@value",
+ toString(m_TrapezoidFactor));
+ config.setParam("/transform/angle/@value",
+ toString(m_Angle));
+ config.setParam("/transform/displaydisplacement/@x",
+ toString(m_DisplayOffset.x));
+ config.setParam("/transform/displaydisplacement/@y",
+ toString(m_DisplayOffset.y));
+ config.setParam("/transform/displayscale/@x",
+ toString(m_DisplayScale.x));
+ config.setParam("/transform/displayscale/@y",
+ toString(m_DisplayScale.y));
+}
+
+bool DeDistort::operator ==(const DeDistort& other) const
+{
+ return (m_CamExtents == other.m_CamExtents &&
+ m_DistortionParams == other.m_DistortionParams &&
+ m_Angle == other.m_Angle &&
+ m_TrapezoidFactor == other.m_TrapezoidFactor &&
+ m_DisplayOffset == other.m_DisplayOffset &&
+ m_DisplayScale == other.m_DisplayScale &&
+ m_RescaleFactor == other.m_RescaleFactor);
+}
+
+void DeDistort::dump() const
+{
+ cerr << " Transform:" << endl;
+ cerr << " CamExtents: " << m_CamExtents << endl;
+ cerr << " DistortionParams: " << m_DistortionParams[0] << ", "
+ << m_DistortionParams[1] << m_DistortionParams[2] << endl;
+ cerr << " Trapezoid: " << m_TrapezoidFactor << endl;
+ cerr << " Angle: " << m_Angle << endl;
+ cerr << " DisplayOffset: " << m_DisplayOffset << endl;
+ cerr << " DisplayScale: " << m_DisplayScale << endl;
+}
+
+glm::dvec2 DeDistort::transformScreenToBlob(const glm::dvec2& pt)
+{
+ // scale to blob image resolution and translate 0,0 to upper left corner.
+ glm::dvec2 DestPt = pt-m_DisplayOffset;
+ DestPt = glm::dvec2(DestPt.x/m_DisplayScale.x, DestPt.y/m_DisplayScale.y);
+ return DestPt;
+}
+
+glm::dvec2 DeDistort::inverse_transform_point(const glm::dvec2& pt)
+{
+ glm::dvec2 destPt = pt - m_CamExtents/2.;
+ destPt = glm::dvec2(2*destPt.x/m_CamExtents.x, 2*destPt.y/m_CamExtents.y);
+ destPt = inv_trapezoid(m_TrapezoidFactor, destPt);
+ destPt = glm::rotate(destPt, -m_Angle*180/M_PI);
+ destPt *= m_RescaleFactor;
+ destPt = inverse_undistort(m_DistortionParams, destPt);
+ destPt = glm::dvec2(destPt.x*m_CamExtents.x/2, destPt.y*m_CamExtents.y/2);
+ destPt += m_CamExtents/2.;
+ return destPt;
+}
+
+glm::dvec2 DeDistort::transformBlobToScreen(const glm::dvec2& pt)
+{
+ glm::dvec2 destPt(m_DisplayScale.x*pt.x, m_DisplayScale.y*pt.y);
+ destPt += m_DisplayOffset;
+ return destPt;
+}
+
+glm::dvec2 DeDistort::transform_point(const glm::dvec2& pt)
+{
+ glm::dvec2 destPt = pt-m_CamExtents/2.;
+ destPt = glm::dvec2(2*destPt.x/m_CamExtents.x, 2*destPt.y/m_CamExtents.y);
+ destPt = undistort(m_DistortionParams, destPt);
+ destPt /= m_RescaleFactor;
+ destPt = glm::rotate(destPt, m_Angle*180/M_PI);
+ destPt = trapezoid(m_TrapezoidFactor, destPt);
+ destPt = glm::dvec2(destPt.x*m_CamExtents.x/2, destPt.y*m_CamExtents.y/2);
+ destPt += m_CamExtents/2.;
+ return destPt;
+}
+
+glm::dvec2 DeDistort::inv_trapezoid(const double trapezoid_factor, const glm::dvec2& pt)
+{
+ // stretch x coord
+ double yn = pt.y;
+ return glm::dvec2(pt.x/(1+yn*trapezoid_factor), pt.y);
+}
+
+glm::dvec2 DeDistort::trapezoid(const double trapezoid_factor, const glm::dvec2& pt)
+{
+ // stretch x coord
+ double yn = pt.y;
+ return glm::dvec2(pt.x*(1+yn*trapezoid_factor), pt.y);
+}
+
+double distort_map(const vector<double>& params, double r)
+{
+ double S = 0;
+ int counter = 2;
+ std::vector<double>::const_iterator v;
+ for(v=params.begin(); v!=params.end(); ++v){
+ S += (*v) * pow(r, counter);
+ ++counter;
+ }
+ return r+S;
+}
+
+double DeDistort::calc_rescale()
+{
+ //make sure that the undistort transformation stays within the normalized box
+ double scale = distort_map(m_DistortionParams, sqrt(2.0));
+ return scale/sqrt(2.0);
+}
+
+double inv_distort_map(const vector<double>& params, double r)
+{
+ double r1,r2,r3,f1,f2;
+ r1 = r;
+ r2 = r+.001;
+ f1 = distort_map(params, r1)-r;
+ f2 = distort_map(params, r2)-r;
+ while (fabs(f2) > 0.0001) {
+ r3 = (r1*f2-r2*f1)/(f2-f1);
+ r1 = r2;
+ r2 = r3;
+ f1 = f2;
+ f2 = distort_map(params, r2)-r;
+ }
+ return r2;
+}
+
+#define EPSILON 0.00001
+glm::dvec2 DeDistort::inverse_undistort(const vector<double> &params,
+ const glm::dvec2 &pt)
+{
+ if (params.empty()) {
+ return pt;
+ }
+ glm::dvec2 pt_norm = pt;
+ double r_d = sqrt(pt_norm.x*pt_norm.x + pt_norm.y*pt_norm.y);
+ double S;
+ if (r_d < EPSILON) {
+ S=0;
+ } else {
+ S = inv_distort_map(params, r_d)/r_d;
+ }
+ glm::dvec2 result = pt_norm*(S);
+ return result;
+}
+
+glm::dvec2 DeDistort::undistort(const vector<double>& params, const glm::dvec2 &pt)
+{
+ std::vector<double>::const_iterator v = params.begin();
+ if (v == params.end()) {
+ return pt;
+ }
+ glm::dvec2 pt_norm = pt;
+ double r_d = sqrt(pt_norm.x*pt_norm.x + pt_norm.y*pt_norm.y);
+ double S;
+ if (r_d < EPSILON) {
+ S=0;
+ } else {
+ S = distort_map(params, r_d)/r_d;
+ }
+
+ glm::dvec2 result = pt_norm*(S);
+ return result;
+}
+
+}
diff --git a/src/imaging/DeDistort.h b/src/imaging/DeDistort.h
new file mode 100644
index 0000000..1c2edc5
--- /dev/null
+++ b/src/imaging/DeDistort.h
@@ -0,0 +1,88 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _DeDistort_H_
+#define _DeDistort_H_
+
+#include "../api.h"
+#include "CoordTransformer.h"
+
+#include "../base/GLMHelper.h"
+#include "../base/Rect.h"
+
+#include <boost/shared_ptr.hpp>
+
+#include <libxml/parser.h>
+#include <libxml/xmlwriter.h>
+
+#include <vector>
+#include <string>
+
+namespace avg {
+
+class TrackerConfig;
+
+class AVG_API DeDistort: public CoordTransformer {
+ public:
+ DeDistort();
+ DeDistort(const glm::vec2& camExtents, const glm::vec2& displayExtents);
+ DeDistort(const glm::vec2& camExtents,
+ const std::vector<double>& distortionParams, double angle,
+ double trapezoidFactor, const glm::dvec2& displayOffset,
+ const glm::dvec2& displayScale);
+ virtual ~DeDistort();
+
+ glm::dvec2 transformBlobToScreen(const glm::dvec2& pt);
+ glm::dvec2 transformScreenToBlob(const glm::dvec2& pt);
+ virtual glm::dvec2 transform_point(const glm::dvec2& pt);
+ virtual glm::dvec2 inverse_transform_point(const glm::dvec2& pt);
+ FRect getDisplayArea(const glm::vec2& displayExtents);
+ FRect getActiveBlobArea(const FRect& displayROI);
+
+ void load(const glm::vec2 &CameraExtents, const TrackerConfig& config);
+ void save(TrackerConfig& config);
+
+ bool operator ==(const DeDistort& other) const;
+
+ void dump() const;
+
+ private:
+ double calc_rescale();
+ glm::dvec2 inverse_undistort(const std::vector<double>& params,
+ const glm::dvec2& pt);
+ glm::dvec2 undistort(const std::vector<double>& params, const glm::dvec2& pt);
+ glm::dvec2 trapezoid(const double trapezoid_factor, const glm::dvec2& pt);
+ glm::dvec2 inv_trapezoid(const double trapezoid_factor, const glm::dvec2& pt);
+
+ glm::dvec2 m_CamExtents;
+ std::vector<double> m_DistortionParams;
+ double m_Angle;
+ double m_TrapezoidFactor;
+ glm::dvec2 m_DisplayOffset;
+ glm::dvec2 m_DisplayScale;
+
+ double m_RescaleFactor;
+};
+
+typedef boost::shared_ptr<DeDistort> DeDistortPtr;
+
+}
+#endif
diff --git a/src/imaging/FWCamera.cpp b/src/imaging/FWCamera.cpp
new file mode 100644
index 0000000..1fc62ff
--- /dev/null
+++ b/src/imaging/FWCamera.cpp
@@ -0,0 +1,671 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "FWCamera.h"
+#ifdef AVG_ENABLE_1394_2
+#include "FWCameraUtils.h"
+#endif
+
+#include "../base/Logger.h"
+#include "../base/Exception.h"
+#include "../base/ScopeTimer.h"
+#include "../base/StringHelper.h"
+
+#include <string.h>
+#include <sstream>
+#include <iomanip>
+
+namespace avg {
+
+using namespace std;
+
+FWCamera::FWCamera(unsigned long long guid, int unit, bool bFW800, IntPoint size,
+ PixelFormat camPF, PixelFormat destPF, float frameRate)
+ : Camera(camPF, destPF, size, frameRate),
+ m_WhitebalanceU(-1),
+ m_WhitebalanceV(-1)
+{
+#ifdef AVG_ENABLE_1394_2
+ m_FrameRateConstant = getFrameRateConst(getFrameRate());
+ if (camPF == I16) {
+ throw Exception(AVG_ERR_CAMERA_NONFATAL,
+ "I16 pixel format is not supported for firewire cameras.");
+ }
+ m_Mode = getCamMode(size, camPF);
+ dc1394camera_list_t * pCameraList;
+
+ m_pDC1394 = dc1394_new();
+ if (m_pDC1394 == 0) {
+ throw Exception(AVG_ERR_CAMERA_NONFATAL,
+ "Failed to initialize firewire subsystem");
+ }
+ int err = dc1394_camera_enumerate(m_pDC1394, &pCameraList);
+
+ if (err != DC1394_SUCCESS) {
+ AVG_LOG_ERROR("Unable to look for cameras");
+#ifdef linux
+ AVG_LOG_ERROR("Please check");
+ AVG_LOG_ERROR(" - if the kernel modules `ieee1394',`raw1394' and \
+ `ohci1394' are loaded");
+ AVG_LOG_ERROR(" - if you have read/write access to /dev/raw1394.");
+#endif
+ dc1394_free(m_pDC1394);
+ throw Exception(AVG_ERR_CAMERA_NONFATAL,"Firewire failure");
+ }
+
+ if (pCameraList->num == 0) {
+ dc1394_camera_free_list(pCameraList);
+ dc1394_free(m_pDC1394);
+ throw Exception(AVG_ERR_CAMERA_NONFATAL,"No firewire cameras found.");
+ }
+ int id_to_use = -1;
+ if (guid != 0) {
+ for (unsigned i = 0; i < pCameraList->num; ++i) {
+ if (pCameraList->ids[i].guid == guid) {
+ id_to_use = i;
+ }
+ }
+ if (id_to_use == -1) {
+ AVG_LOG_WARNING("Firewire GUID=" << hex << guid << dec
+ << " requested but not found on bus. Using first camera");
+ id_to_use = 0;
+ }
+ } else {
+ id_to_use = 0;
+ }
+ if (unit != -1) {
+ m_pCamera = dc1394_camera_new_unit(m_pDC1394, pCameraList->ids[id_to_use].guid,
+ unit);
+ } else {
+ m_pCamera = dc1394_camera_new(m_pDC1394, pCameraList->ids[id_to_use].guid);
+ }
+ if (!m_pCamera) {
+ dc1394_camera_free_list(pCameraList);
+ dc1394_free(m_pDC1394);
+ throw Exception(AVG_ERR_CAMERA_FATAL,"Failed to initialize camera");
+ }
+
+ dc1394_camera_free_list(pCameraList);
+
+ if (bFW800) {
+ dc1394_video_set_operation_mode(m_pCamera, DC1394_OPERATION_MODE_1394B);
+ err = dc1394_video_set_iso_speed(m_pCamera, DC1394_ISO_SPEED_800);
+ } else {
+ err = dc1394_video_set_iso_speed(m_pCamera, DC1394_ISO_SPEED_400);
+ }
+ AVG_ASSERT(err == DC1394_SUCCESS);
+ err = dc1394_video_set_mode(m_pCamera, m_Mode);
+ AVG_ASSERT(err == DC1394_SUCCESS);
+
+ dc1394framerates_t frameRates;
+ err = dc1394_video_get_supported_framerates(m_pCamera, m_Mode, &frameRates);
+ AVG_ASSERT(err == DC1394_SUCCESS);
+ bool bFrameRateSupported = false;
+ for (unsigned int i = 0; i < frameRates.num; i++) {
+ if (frameRates.framerates[i] == m_FrameRateConstant) {
+ bFrameRateSupported = true;
+ break;
+ }
+ }
+ if (!bFrameRateSupported) {
+ AVG_LOG_ERROR("Camera does not support framerate " << getFrameRate()
+ << " in the current video mode.");
+ dc1394_capture_stop(m_pCamera);
+ dc1394_video_set_transmission(m_pCamera, DC1394_OFF);
+ dc1394_camera_free(m_pCamera);
+ dc1394_free(m_pDC1394);
+ throw Exception(AVG_ERR_CAMERA_NONFATAL,
+ string("Camera does not support framerate ")+toString(getFrameRate())+
+ " in the current video mode.");
+ }
+
+ err = dc1394_video_set_framerate(m_pCamera, m_FrameRateConstant);
+ AVG_ASSERT(err == DC1394_SUCCESS);
+
+ err = dc1394_capture_setup(m_pCamera,8, DC1394_CAPTURE_FLAGS_DEFAULT);
+ if (err != DC1394_SUCCESS) {
+ AVG_LOG_ERROR("Unable to setup camera. Make sure that");
+ AVG_LOG_ERROR("video mode and framerate (" << getFrameRate() << ") are");
+ AVG_LOG_ERROR("supported by your camera.");
+ dc1394_capture_stop(m_pCamera);
+ dc1394_video_set_transmission(m_pCamera, DC1394_OFF);
+ dc1394_camera_free(m_pCamera);
+ dc1394_free(m_pDC1394);
+ throw Exception(AVG_ERR_CAMERA_NONFATAL, "Failed to initialize camera");
+ }
+#else
+ AVG_ASSERT(false);
+#endif
+}
+
+FWCamera::~FWCamera()
+{
+#ifdef AVG_ENABLE_1394_2
+ dc1394_video_set_transmission(m_pCamera, DC1394_OFF);
+ dc1394_capture_stop(m_pCamera);
+ dc1394_camera_free(m_pCamera);
+ dc1394_free(m_pDC1394);
+#endif
+ AVG_TRACE(Logger::category::CONFIG, Logger::severity::INFO, "Firewire camera closed.");
+}
+
+void FWCamera::startCapture()
+{
+#ifdef AVG_ENABLE_1394_2
+ int err = dc1394_video_set_transmission(m_pCamera, DC1394_ON);
+ AVG_ASSERT(err == DC1394_SUCCESS);
+
+ dc1394switch_t status = DC1394_OFF;
+
+ int i = 0;
+ while (status == DC1394_OFF && i++ < 5) {
+ usleep(50000);
+ err = dc1394_video_get_transmission(m_pCamera, &status);
+ AVG_ASSERT(err == DC1394_SUCCESS);
+ }
+
+ if (i == 5) {
+ AVG_ASSERT(false);
+ }
+ // Default to turning off any camera sharpness manipulation.
+ setFeature(CAM_FEATURE_SHARPNESS, 0);
+
+ // Turn off possible auto exposure.
+ dc1394_feature_set_mode(m_pCamera, DC1394_FEATURE_EXPOSURE,
+ DC1394_FEATURE_MODE_MANUAL);
+ dc1394_feature_set_power(m_pCamera, DC1394_FEATURE_EXPOSURE, DC1394_OFF);
+
+ AVG_TRACE(Logger::category::CONFIG, Logger::severity::INFO, "Firewire camera opened.");
+ for (FeatureMap::iterator it=m_Features.begin(); it != m_Features.end(); it++) {
+ setFeature(it->first, it->second, true);
+ }
+ setWhitebalance(m_WhitebalanceU, m_WhitebalanceV, true);
+
+ if (getCamPF() == BAYER8) {
+ if (strcmp(m_pCamera->model, "DFx 31BF03") == 0) {
+ AVG_TRACE(Logger::category::CONFIG, Logger::severity::INFO,
+ "Applying bayer pattern fixup for IS DFx31BF03 camera");
+ setCamPF(BAYER8_GRBG);
+ } else if (strcmp(m_pCamera->vendor, "Point Grey Research") == 0) {
+ AVG_TRACE(Logger::category::CONFIG, Logger::severity::INFO,
+ "Applying bayer pattern fixup for PointGrey cameras");
+ enablePtGreyBayer();
+ }
+ }
+#endif
+}
+
+BitmapPtr FWCamera::getImage(bool bWait)
+{
+#ifdef AVG_ENABLE_1394_2
+ bool bGotFrame = false;
+ unsigned char * pCaptureBuffer = 0;
+ dc1394video_frame_t * pFrame;
+ dc1394error_t err;
+ if (bWait) {
+ err = dc1394_capture_dequeue(m_pCamera, DC1394_CAPTURE_POLICY_WAIT, &pFrame);
+ } else {
+ err = dc1394_capture_dequeue(m_pCamera, DC1394_CAPTURE_POLICY_POLL, &pFrame);
+ }
+ if (err == DC1394_SUCCESS && pFrame) {
+ bGotFrame = true;
+ pCaptureBuffer = pFrame->image;
+ }
+ if (bGotFrame) {
+ int lineLen;
+ if (getCamPF() == YCbCr411) {
+ lineLen = getImgSize().x*1.5;
+ } else {
+ lineLen = getImgSize().x*getBytesPerPixel(getCamPF());
+ }
+ BitmapPtr pCamBmp(new Bitmap(getImgSize(), getCamPF(), pCaptureBuffer, lineLen,
+ false, "TempCameraBmp"));
+ BitmapPtr pDestBmp = convertCamFrameToDestPF(pCamBmp);
+// cerr << "CamBmp: " << pCamBmp->getPixelFormat() << ", DestBmp: "
+// << pDestBmp->getPixelFormat() << endl;
+ dc1394_capture_enqueue(m_pCamera, pFrame);
+ return pDestBmp;
+ } else {
+ return BitmapPtr();
+ }
+#else
+ return BitmapPtr();
+#endif
+}
+
+
+const string& FWCamera::getDevice() const
+{
+ static string deviceInfo;
+ stringstream ss;
+#ifdef AVG_ENABLE_1394_2
+ ss << m_pCamera->vendor << " " << m_pCamera->model << " (guid=" << m_pCamera->guid
+ << ", unit=" << m_pCamera->unit << ")";
+#endif
+ deviceInfo = ss.str();
+ return deviceInfo;
+}
+
+const std::string& FWCamera::getDriverName() const
+{
+#ifdef AVG_ENABLE_1394_2
+ static string sDriverName = "libdc1394 v2";
+#else
+ static string sDriverName = "";
+#endif
+ return sDriverName;
+}
+
+int FWCamera::getFeature(CameraFeature feature) const
+{
+#ifdef AVG_ENABLE_1394_2
+ FeatureMap::const_iterator it = m_Features.find(feature);
+ if (it == m_Features.end()) {
+ return 0;
+ } else {
+ return it->second;
+ }
+#else
+ return 0;
+#endif
+}
+
+bool FWCamera::hasFeature(CameraFeature feature)
+{
+#ifdef AVG_ENABLE_1394_2
+ if (feature == CAM_FEATURE_STROBE_DURATION) {
+ // FIXME
+ return true;
+ } else {
+ dc1394feature_t featureID = getFeatureID(feature);
+ dc1394bool_t bAvailable;
+ dc1394_feature_is_present(m_pCamera, featureID, &bAvailable);
+ return bAvailable;
+ }
+#else
+ return false;
+#endif
+}
+
+void FWCamera::setFeature(CameraFeature feature, int value, bool bIgnoreOldValue)
+{
+#ifdef AVG_ENABLE_1394_2
+ if (hasFeature(feature)) {
+ if (bIgnoreOldValue || m_Features[feature] != value) {
+ m_Features[feature] = value;
+ if (feature == CAM_FEATURE_STROBE_DURATION) {
+ try {
+ setStrobeDuration(value);
+ } catch (Exception& e) {
+ AVG_LOG_WARNING(string("Camera: Setting strobe duration failed. ") +
+ e.getStr());
+ }
+ } else {
+ dc1394feature_t featureID = getFeatureID(feature);
+ setFeature(featureID, value);
+ // dumpCameraInfo();
+ }
+ }
+ }
+#endif
+}
+
+void FWCamera::setFeatureOneShot(CameraFeature feature)
+{
+#ifdef AVG_ENABLE_1394_2
+ dc1394feature_t featureID = getFeatureID(feature);
+ dc1394error_t err = dc1394_feature_set_mode(m_pCamera, featureID,
+ DC1394_FEATURE_MODE_ONE_PUSH_AUTO);
+ if (err != DC1394_SUCCESS) {
+ AVG_LOG_WARNING("Camera: Unable to set one-shot for "
+ << cameraFeatureToString(feature) << ". Error was " << err);
+ }
+#endif
+}
+
+int FWCamera::getWhitebalanceU() const
+{
+ int u;
+ int v;
+ getWhitebalance(&u, &v);
+ return u;
+}
+
+int FWCamera::getWhitebalanceV() const
+{
+ int u;
+ int v;
+ getWhitebalance(&u, &v);
+ return v;
+}
+
+void FWCamera::setWhitebalance(int u, int v, bool bIgnoreOldValue)
+{
+#ifdef AVG_ENABLE_1394_2
+ if (hasFeature(CAM_FEATURE_WHITE_BALANCE)) {
+ if (bIgnoreOldValue || u != m_WhitebalanceU || v != m_WhitebalanceV) {
+ m_WhitebalanceU = u;
+ m_WhitebalanceV = v;
+ dc1394error_t err;
+ if (u == -1) {
+ err = dc1394_feature_set_mode(m_pCamera, DC1394_FEATURE_WHITE_BALANCE,
+ DC1394_FEATURE_MODE_AUTO);
+ } else {
+ err = dc1394_feature_set_mode(m_pCamera, DC1394_FEATURE_WHITE_BALANCE,
+ DC1394_FEATURE_MODE_MANUAL);
+ err = dc1394_feature_whitebalance_set_value(m_pCamera, u, v);
+ }
+ if (err != DC1394_SUCCESS) {
+ AVG_LOG_WARNING("Camera: Unable to set whitebalance. Error was " << err);
+ }
+ }
+ }
+#endif
+}
+
+void FWCamera::setFeature(dc1394feature_t feature, int value)
+{
+#ifdef AVG_ENABLE_1394_2
+ dc1394error_t err;
+ if (value == -1) {
+ err = dc1394_feature_set_mode(m_pCamera, feature, DC1394_FEATURE_MODE_AUTO);
+ err = dc1394_feature_set_power(m_pCamera, feature, DC1394_OFF);
+ } else {
+ dc1394_feature_set_mode(m_pCamera, feature, DC1394_FEATURE_MODE_MANUAL);
+ err = dc1394_feature_set_power(m_pCamera, feature, DC1394_ON);
+ err = dc1394_feature_set_value(m_pCamera, feature, value);
+ }
+ if (err != DC1394_SUCCESS) {
+ AVG_LOG_WARNING("Camera: Unable to set " << feature << ". Error was " << err);
+ }
+/*
+ dc1394feature_info_t featureInfo;
+ featureInfo.id = feature;
+ err = dc1394_feature_get(m_pCamera, &featureInfo);
+ dc1394_feature_print(&featureInfo, stdout);
+*/
+#endif
+}
+
+void FWCamera::setStrobeDuration(int microsecs)
+{
+#ifdef AVG_ENABLE_1394_2
+ dc1394error_t err;
+ uint32_t durationRegValue;
+ if (microsecs >= 63930 || microsecs < -1) {
+ throw Exception(AVG_ERR_CAMERA_FATAL, string("Illegal value ")
+ +toString(microsecs)+" for strobe duration.");
+ }
+ if (microsecs == -1) {
+ // Turn off strobe. No error checking done here (if the camera doesn't support
+ // strobe, setting the register will fail. But there is really no error, because
+ // we're turning the feature off anyway.)
+ uint32_t strobeRegValue = 0x81000000;
+ err = dc1394_set_strobe_register(m_pCamera, 0x200, strobeRegValue);
+ } else {
+ if (microsecs < 0x400) {
+ durationRegValue = microsecs;
+ } else {
+ // Wierd calculations: IIDC register values for time are non-linear. Translate
+ // the method parameter in microseconds to appropriate register values.
+ float targetMillisecs = microsecs/1000.f;
+ const float realTimes[] = {1,2,4,6,8,12,16,24,32,48,63.93};
+ const uint32_t regValues[] =
+ {0x400, 0x600, 0x800, 0x900, 0xA00, 0xB00, 0xC00, 0xD00,
+ 0xE00, 0xF00, 0xFFF};
+ int len = sizeof(regValues)/sizeof(*regValues);
+ AVG_ASSERT(len == sizeof(realTimes)/sizeof(*realTimes));
+ int i;
+ for (i = 1; realTimes[i] < targetMillisecs; ++i) {
+ }
+ float ratio = (targetMillisecs-realTimes[i])/(realTimes[i-1]-realTimes[i]);
+ durationRegValue = ratio*regValues[i-1]+(1-ratio)*regValues[i];
+ }
+
+ err = dc1394_set_PIO_register(m_pCamera, 0x08, 0xC0000000);
+ AVG_ASSERT(err == DC1394_SUCCESS);
+
+ uint32_t strobeRegValue = 0x83001000+durationRegValue;
+ err = dc1394_set_strobe_register(m_pCamera, 0x200, strobeRegValue);
+ AVG_ASSERT(err == DC1394_SUCCESS);
+ }
+#endif
+}
+
+void FWCamera::getWhitebalance(int* pU, int* pV) const
+{
+#ifdef AVG_ENABLE_1394_2
+ dc1394error_t err = dc1394_feature_whitebalance_get_value(m_pCamera,
+ (uint32_t*)pU, (uint32_t*)pV);
+ if (err != DC1394_SUCCESS) {
+ AVG_LOG_WARNING("Camera: Unable to get whitebalance setting. Error was " << err);
+ }
+#endif
+}
+
+void FWCamera::enablePtGreyBayer()
+{
+#ifdef AVG_ENABLE_1394_2
+ dc1394error_t err;
+ uint32_t imageDataFormat;
+ err = dc1394_get_adv_control_register(m_pCamera, 0x48, &imageDataFormat);
+ AVG_ASSERT(err == DC1394_SUCCESS);
+ if (imageDataFormat & 0x80000000) {
+ err = dc1394_set_adv_control_register(m_pCamera, 0x48, 0x80000081);
+ AVG_ASSERT(err == DC1394_SUCCESS);
+ uint32_t bayerFormat;
+ err = dc1394_get_adv_control_register(m_pCamera, 0x40, &bayerFormat);
+ AVG_ASSERT(err == DC1394_SUCCESS);
+ PixelFormat exactPF = fwBayerStringToPF(bayerFormat);
+ if (exactPF == I8) {
+ throw(Exception(AVG_ERR_CAMERA_NONFATAL,
+ "Greyscale camera doesn't support bayer pattern."));
+ }
+ setCamPF(exactPF);
+ }
+#endif
+}
+
+int FWCamera::countCameras()
+{
+#ifdef AVG_ENABLE_1394_2
+ dc1394_t* pDC1394 = dc1394_new();
+ if (pDC1394 == 0) {
+ return 0;
+ }
+ dc1394camera_list_t * pCameraList;
+ int err=dc1394_camera_enumerate(pDC1394, &pCameraList);
+ if (err == DC1394_SUCCESS) {
+ int numCameras = pCameraList->num;
+ return numCameras;
+ }
+#endif
+ return 0;
+}
+
+CameraInfo* FWCamera::getCameraInfos(int deviceNumber)
+{
+#ifdef AVG_ENABLE_1394_2
+ dc1394_t* pDC1394 = dc1394_new();
+ if (pDC1394 == 0) {
+ AVG_ASSERT(false);
+ return NULL;
+ }
+ dc1394camera_list_t * pCameraList;
+ int err=dc1394_camera_enumerate(pDC1394, &pCameraList);
+ if (err != DC1394_SUCCESS) {
+ AVG_ASSERT(false);
+ return NULL;
+ }
+ if (pCameraList->num != 0) {
+ dc1394camera_id_t id = pCameraList->ids[deviceNumber];
+ dc1394camera_t * pCamera = dc1394_camera_new_unit(pDC1394, id.guid,
+ id.unit);
+ if (pCamera) {
+ stringstream deviceID;
+ deviceID << hex << id.guid;//pCamera->guid;
+ CameraInfo* camInfo = new CameraInfo("Firewire", deviceID.str());
+
+ getCameraControls(pCamera, camInfo);
+ getCameraImageFormats(pCamera, camInfo);
+
+ dc1394_camera_free(pCamera);
+ dc1394_camera_free_list(pCameraList);
+ dc1394_free(pDC1394);
+ return camInfo;
+ }
+ }
+#endif
+ return NULL;
+}
+
+#ifdef AVG_ENABLE_1394_2
+void FWCamera::getCameraImageFormats(dc1394camera_t* pCamera, CameraInfo* camInfo)
+{
+ dc1394video_modes_t videoModes;
+ dc1394framerates_t framerates;
+ dc1394error_t err = dc1394_video_get_supported_modes(pCamera, &videoModes);
+ if (err != DC1394_SUCCESS) {
+ AVG_ASSERT(false);
+ return;
+ }
+ for (unsigned i = 0; i < videoModes.num; i++) {
+ //Covers only libavg supported formats, other capabilities are ignored
+ if (videoModes.modes[i] >= DC1394_VIDEO_MODE_320x240_YUV422
+ && videoModes.modes[i] <= DC1394_VIDEO_MODE_1600x1200_MONO16){
+ PixelFormat pixFormat = getPFFromVideoMode(videoModes.modes[i]);
+ IntPoint size = getFrameSizeFromVideoMode(videoModes.modes[i]);
+ FrameratesVector framerateList;
+ err = dc1394_video_get_supported_framerates(pCamera, videoModes.modes[i],
+ &framerates);
+ if (err != DC1394_SUCCESS) {
+ AVG_LOG_WARNING("Camera: No framerates. Error was: " << err);
+ } else {
+ for (unsigned j = 0; j < framerates.num; j++)
+ {
+ float rate = framerateToFloat(framerates.framerates[j]);
+ framerateList.push_back(rate);
+ }
+ }
+ CameraImageFormat format = CameraImageFormat(size,pixFormat,framerateList);
+ camInfo->addImageFormat(format);
+ }
+ }
+}
+
+void FWCamera::getCameraControls(dc1394camera_t* pCamera, CameraInfo* camInfo)
+{
+ dc1394featureset_t featureSet;
+ int err = dc1394_feature_get_all(pCamera, &featureSet);
+ if (err != DC1394_SUCCESS) {
+ AVG_ASSERT(false);
+ return;
+ }
+
+ for (int i = DC1394_FEATURE_MIN; i <= DC1394_FEATURE_MAX; i++) {
+ dc1394feature_info_t featureInfo = featureSet.feature[i - DC1394_FEATURE_MIN];
+
+ dc1394bool_t bool_t;
+ dc1394_feature_is_present(pCamera,featureInfo.id, &bool_t);
+ if (bool_t != DC1394_TRUE) {
+ continue;
+ }
+
+ uint32_t min = -1;
+ uint32_t max = -1;
+ uint32_t actValue = -1;
+
+ //TODO: 428 (TRIGGER) doesnt have min max
+ err = dc1394_feature_get_boundaries(pCamera, featureInfo.id, &min, &max);
+ if (err != DC1394_SUCCESS) {
+ continue;
+ }
+
+ switch(featureInfo.id) {
+ case DC1394_FEATURE_TEMPERATURE: {
+ uint32_t targetTemp = -1;
+ uint32_t currentTemp = -1;
+ err = dc1394_feature_temperature_get_value(pCamera,&targetTemp,&currentTemp);
+ if (err != DC1394_SUCCESS) {
+ continue;
+ }
+ actValue = currentTemp;
+ break;
+ }
+ //TODO: Think about a way to get this information into CameraInfo
+ case DC1394_FEATURE_WHITE_BALANCE: {
+ uint32_t ubValue = -1;
+ uint32_t vrValue = -1;
+ err = dc1394_feature_whitebalance_get_value(pCamera,&ubValue,&vrValue);
+ if (err != DC1394_SUCCESS) {
+ continue;
+ }
+ //actValue = ubValue; //vrValue;
+ //cout <<"UBlue Value: " << ubValue << " VRed Value: " << vrValue << endl;
+ break;
+ }
+ default: {
+ err = dc1394_feature_get_value(pCamera,featureInfo.id, &actValue);
+ if (err != DC1394_SUCCESS) {
+ continue;
+ }
+ break;
+ }
+ }
+ CameraFeature enumFeature = featureIDToEnum(featureInfo.id);
+ if (enumFeature == CAM_FEATURE_UNSUPPORTED) {
+ continue;
+ }
+ std::string controlName = cameraFeatureToString(enumFeature);
+
+ CameraControl control = CameraControl(controlName,
+ (int) min,
+ (int) max,
+ (int) actValue ); //TODO: isnt really a default value!?
+ camInfo->addControl(control);
+ }
+}
+#endif
+
+void FWCamera::resetBus()
+{
+#ifdef AVG_ENABLE_1394_2
+ dc1394_t* pDC1394 = dc1394_new();
+ if (pDC1394 == 0) {
+ return;
+ }
+ dc1394camera_list_t * pCameraList;
+ int err=dc1394_camera_enumerate(pDC1394, &pCameraList);
+ if (err == DC1394_SUCCESS) {
+ if (pCameraList->num != 0) {
+ dc1394camera_t * pCam = dc1394_camera_new(pDC1394, pCameraList->ids[0].guid);
+ if (pCam) {
+ dc1394_reset_bus(pCam);
+ dc1394_camera_free(pCam);
+ }
+ }
+ dc1394_camera_free_list(pCameraList);
+ }
+ dc1394_free(pDC1394);
+#endif
+}
+
+}
diff --git a/src/imaging/FWCamera.h b/src/imaging/FWCamera.h
new file mode 100644
index 0000000..c7badc0
--- /dev/null
+++ b/src/imaging/FWCamera.h
@@ -0,0 +1,94 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _FWCamera_H_
+#define _FWCamera_H_
+
+#include "../avgconfigwrapper.h"
+
+#include "Camera.h"
+
+#include "../graphics/Bitmap.h"
+#include "../graphics/Pixel24.h"
+
+#include "../base/GLMHelper.h"
+
+#ifdef AVG_ENABLE_1394_2
+#include <dc1394/control.h>
+#include <dc1394/register.h>
+#endif
+#ifndef AVG_ENABLE_1394_2
+typedef unsigned int dc1394feature_t;
+#endif
+
+#include <string>
+#include <map>
+
+namespace avg {
+
+class AVG_API FWCamera: public Camera {
+public:
+ FWCamera(unsigned long long guid, int unit, bool bFW800, IntPoint size,
+ PixelFormat camPF, PixelFormat destPF, float frameRate);
+ virtual ~FWCamera();
+ virtual void startCapture();
+
+ virtual BitmapPtr getImage(bool bWait);
+
+ virtual const std::string& getDevice() const;
+ virtual const std::string& getDriverName() const;
+
+ virtual int getFeature(CameraFeature feature) const;
+ bool hasFeature(CameraFeature feature);
+ virtual void setFeature(CameraFeature feature, int value, bool bIgnoreOldValue=false);
+ virtual void setFeatureOneShot(CameraFeature feature);
+ virtual int getWhitebalanceU() const;
+ virtual int getWhitebalanceV() const;
+ virtual void setWhitebalance(int u, int v, bool bIgnoreOldValue=false);
+
+ static int countCameras();
+ static CameraInfo* getCameraInfos(int deviceNumber);
+ static void resetBus();
+
+private:
+ void setFeature(dc1394feature_t feature, int value);
+ void setStrobeDuration(int microsecs);
+ void getWhitebalance(int* pU, int* pV) const;
+ void enablePtGreyBayer();
+
+#ifdef AVG_ENABLE_1394_2
+ static void getCameraImageFormats(dc1394camera_t* pCamera, CameraInfo* camInfo);
+ static void getCameraControls(dc1394camera_t* pCamera, CameraInfo* camInfo);
+
+ dc1394_t * m_pDC1394;
+ dc1394camera_t * m_pCamera;
+ dc1394framerate_t m_FrameRateConstant;
+ dc1394video_mode_t m_Mode;
+#endif
+
+ FeatureMap m_Features;
+ int m_WhitebalanceU;
+ int m_WhitebalanceV;
+};
+
+}
+
+#endif
diff --git a/src/imaging/FWCameraUtils.cpp b/src/imaging/FWCameraUtils.cpp
new file mode 100644
index 0000000..e8f37b8
--- /dev/null
+++ b/src/imaging/FWCameraUtils.cpp
@@ -0,0 +1,366 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "FWCameraUtils.h"
+
+#include "../base/Logger.h"
+#include "../base/Exception.h"
+#include "../base/StringHelper.h"
+
+namespace avg {
+
+using namespace std;
+
+dc1394video_mode_t getCamMode(IntPoint size, PixelFormat pf)
+{
+ if (size.x == 320 && size.y == 240 && pf == YCbCr422) {
+ return DC1394_VIDEO_MODE_320x240_YUV422;
+ } else if (size.x == 640 && size.y == 480) {
+ switch (pf) {
+ case I8:
+ case BAYER8:
+ return DC1394_VIDEO_MODE_640x480_MONO8;
+ case I16:
+ return DC1394_VIDEO_MODE_640x480_MONO16;
+ case YCbCr411:
+ return DC1394_VIDEO_MODE_640x480_YUV411;
+ case YCbCr422:
+ return DC1394_VIDEO_MODE_640x480_YUV422;
+ case R8G8B8:
+ return DC1394_VIDEO_MODE_640x480_RGB8;
+ default:
+ break;
+ }
+ } else if (size.x == 800 && size.y == 600) {
+ switch (pf) {
+ case I8:
+ case BAYER8:
+ return DC1394_VIDEO_MODE_800x600_MONO8;
+ case I16:
+ return DC1394_VIDEO_MODE_800x600_MONO16;
+ case YCbCr422:
+ return DC1394_VIDEO_MODE_800x600_YUV422;
+ case R8G8B8:
+ return DC1394_VIDEO_MODE_800x600_RGB8;
+ default:
+ break;
+ }
+ } else if (size.x == 1024 && size.y == 768) {
+ switch (pf) {
+ case I8:
+ case BAYER8:
+ return DC1394_VIDEO_MODE_1024x768_MONO8;
+ case I16:
+ return DC1394_VIDEO_MODE_1024x768_MONO16;
+ case YCbCr422:
+ return DC1394_VIDEO_MODE_1024x768_YUV422;
+ case R8G8B8:
+ return DC1394_VIDEO_MODE_1024x768_RGB8;
+ default:
+ break;
+ }
+ } else if (size.x == 1280 && size.y == 960) {
+ switch (pf) {
+ case I8:
+ case BAYER8:
+ return DC1394_VIDEO_MODE_1280x960_MONO8;
+ case I16:
+ return DC1394_VIDEO_MODE_1280x960_MONO16;
+ case YCbCr422:
+ return DC1394_VIDEO_MODE_1280x960_YUV422;
+ case R8G8B8:
+ return DC1394_VIDEO_MODE_1280x960_RGB8;
+ default:
+ break;
+ }
+ } else if (size.x == 1600 && size.y == 1200) {
+ switch (pf) {
+ case I8:
+ case BAYER8:
+ return DC1394_VIDEO_MODE_1600x1200_MONO8;
+ case I16:
+ return DC1394_VIDEO_MODE_1600x1200_MONO16;
+ case YCbCr422:
+ return DC1394_VIDEO_MODE_1600x1200_YUV422;
+ case R8G8B8:
+ return DC1394_VIDEO_MODE_1600x1200_RGB8;
+ default:
+ break;
+ }
+ }
+ throw Exception(AVG_ERR_CAMERA_FATAL,
+ "Unsupported or illegal value ("+toString(size.x)+", "+toString(size.y)+
+ "), "+getPixelFormatString(pf)+"\" for camera mode.");
+}
+
+dc1394framerate_t getFrameRateConst(float frameRate)
+{
+ if (frameRate == 1.875f) {
+ return DC1394_FRAMERATE_1_875;
+ } else if (frameRate == 3.75f) {
+ return DC1394_FRAMERATE_3_75;
+ } else if (frameRate == 7.5f) {
+ return DC1394_FRAMERATE_7_5;
+ } else if (frameRate == 15) {
+ return DC1394_FRAMERATE_15;
+ } else if (frameRate == 30) {
+ return DC1394_FRAMERATE_30;
+ } else if (frameRate == 60) {
+ return DC1394_FRAMERATE_60;
+ } else if (frameRate == 120) {
+ return DC1394_FRAMERATE_120;
+ } else if (frameRate == 240) {
+ return DC1394_FRAMERATE_240;
+ } else {
+ throw Exception(AVG_ERR_CAMERA_FATAL, string("Illegal value ")
+ +toString(frameRate)+" for camera framerate.");
+ }
+}
+CameraFeature featureIDToEnum(dc1394feature_t feature)
+{
+ switch (feature) {
+ case DC1394_FEATURE_BRIGHTNESS:
+ return CAM_FEATURE_BRIGHTNESS;
+ case DC1394_FEATURE_EXPOSURE:
+ return CAM_FEATURE_EXPOSURE;
+ case DC1394_FEATURE_SHARPNESS:
+ return CAM_FEATURE_SHARPNESS;
+ case DC1394_FEATURE_WHITE_BALANCE:
+ return CAM_FEATURE_WHITE_BALANCE;
+ case DC1394_FEATURE_HUE:
+ return CAM_FEATURE_HUE;
+ case DC1394_FEATURE_SATURATION:
+ return CAM_FEATURE_SATURATION;
+ case DC1394_FEATURE_GAMMA:
+ return CAM_FEATURE_GAMMA;
+ case DC1394_FEATURE_SHUTTER:
+ return CAM_FEATURE_SHUTTER;
+ case DC1394_FEATURE_GAIN:
+ return CAM_FEATURE_GAIN;
+ case DC1394_FEATURE_IRIS:
+ return CAM_FEATURE_IRIS;
+ case DC1394_FEATURE_FOCUS:
+ return CAM_FEATURE_FOCUS;
+ case DC1394_FEATURE_TEMPERATURE:
+ return CAM_FEATURE_TEMPERATURE;
+ case DC1394_FEATURE_TRIGGER:
+ return CAM_FEATURE_TRIGGER;
+ case DC1394_FEATURE_TRIGGER_DELAY:
+ return CAM_FEATURE_TRIGGER_DELAY;
+ case DC1394_FEATURE_WHITE_SHADING:
+ return CAM_FEATURE_WHITE_SHADING;
+ case DC1394_FEATURE_ZOOM:
+ return CAM_FEATURE_ZOOM;
+ case DC1394_FEATURE_PAN:
+ return CAM_FEATURE_PAN;
+ case DC1394_FEATURE_TILT:
+ return CAM_FEATURE_TILT;
+ case DC1394_FEATURE_OPTICAL_FILTER:
+ return CAM_FEATURE_OPTICAL_FILTER;
+ case DC1394_FEATURE_CAPTURE_SIZE:
+ return CAM_FEATURE_CAPTURE_SIZE;
+ case DC1394_FEATURE_CAPTURE_QUALITY:
+ return CAM_FEATURE_CAPTURE_QUALITY;
+ default:
+ return CAM_FEATURE_UNSUPPORTED;
+ }
+}
+
+dc1394feature_t getFeatureID(CameraFeature feature)
+{
+ switch (feature) {
+ case CAM_FEATURE_BRIGHTNESS:
+ return DC1394_FEATURE_BRIGHTNESS;
+ case CAM_FEATURE_EXPOSURE:
+ return DC1394_FEATURE_EXPOSURE;
+ case CAM_FEATURE_SHARPNESS:
+ return DC1394_FEATURE_SHARPNESS;
+ case CAM_FEATURE_WHITE_BALANCE:
+ return DC1394_FEATURE_WHITE_BALANCE;
+ case CAM_FEATURE_HUE:
+ return DC1394_FEATURE_HUE;
+ case CAM_FEATURE_SATURATION:
+ return DC1394_FEATURE_SATURATION;
+ case CAM_FEATURE_GAMMA:
+ return DC1394_FEATURE_GAMMA;
+ case CAM_FEATURE_SHUTTER:
+ return DC1394_FEATURE_SHUTTER;
+ case CAM_FEATURE_GAIN:
+ return DC1394_FEATURE_GAIN;
+ case CAM_FEATURE_IRIS:
+ return DC1394_FEATURE_IRIS;
+ case CAM_FEATURE_FOCUS:
+ return DC1394_FEATURE_FOCUS;
+ case CAM_FEATURE_TEMPERATURE:
+ return DC1394_FEATURE_TEMPERATURE;
+ case CAM_FEATURE_TRIGGER:
+ return DC1394_FEATURE_TRIGGER;
+ case CAM_FEATURE_TRIGGER_DELAY:
+ return DC1394_FEATURE_TRIGGER_DELAY;
+ case CAM_FEATURE_WHITE_SHADING:
+ return DC1394_FEATURE_WHITE_SHADING;
+ case CAM_FEATURE_ZOOM:
+ return DC1394_FEATURE_ZOOM;
+ case CAM_FEATURE_PAN:
+ return DC1394_FEATURE_PAN;
+ case CAM_FEATURE_TILT:
+ return DC1394_FEATURE_TILT;
+ case CAM_FEATURE_OPTICAL_FILTER:
+ return DC1394_FEATURE_OPTICAL_FILTER;
+ case CAM_FEATURE_CAPTURE_SIZE:
+ return DC1394_FEATURE_CAPTURE_SIZE;
+ case CAM_FEATURE_CAPTURE_QUALITY:
+ return DC1394_FEATURE_CAPTURE_QUALITY;
+ default:
+ AVG_ASSERT(false);
+ return dc1394feature_t(0);
+ }
+}
+
+IntPoint getFrameSizeFromVideoMode(dc1394video_mode_t mode)
+{
+ IntPoint point = IntPoint();
+ point.x = -1;
+ point.y = -1;
+ switch (mode) {
+ case DC1394_VIDEO_MODE_160x120_YUV444: {
+ point.x = 160;
+ point.y = 120;
+ return point;
+ }
+ case DC1394_VIDEO_MODE_320x240_YUV422: {
+ point.x = 320;
+ point.y = 240;
+ return point;
+ }
+ case DC1394_VIDEO_MODE_640x480_YUV411:
+ case DC1394_VIDEO_MODE_640x480_YUV422:
+ case DC1394_VIDEO_MODE_640x480_RGB8:
+ case DC1394_VIDEO_MODE_640x480_MONO8:
+ case DC1394_VIDEO_MODE_640x480_MONO16: {
+ point.x = 640;
+ point.y = 480;
+ return point;
+ }
+ case DC1394_VIDEO_MODE_800x600_YUV422:
+ case DC1394_VIDEO_MODE_800x600_RGB8:
+ case DC1394_VIDEO_MODE_800x600_MONO8:
+ case DC1394_VIDEO_MODE_800x600_MONO16: {
+ point.x = 800;
+ point.y = 600;
+ return point;
+ }
+ case DC1394_VIDEO_MODE_1024x768_YUV422:
+ case DC1394_VIDEO_MODE_1024x768_RGB8:
+ case DC1394_VIDEO_MODE_1024x768_MONO8:
+ case DC1394_VIDEO_MODE_1024x768_MONO16: {
+ point.x = 1024;
+ point.y = 768;
+ return point;
+ }
+
+
+ case DC1394_VIDEO_MODE_1280x960_YUV422:
+ case DC1394_VIDEO_MODE_1280x960_RGB8:
+ case DC1394_VIDEO_MODE_1280x960_MONO8:
+ case DC1394_VIDEO_MODE_1280x960_MONO16: {
+ point.x = 1280;
+ point.y = 960;
+ return point;
+ }
+ case DC1394_VIDEO_MODE_1600x1200_YUV422:
+ case DC1394_VIDEO_MODE_1600x1200_RGB8:
+ case DC1394_VIDEO_MODE_1600x1200_MONO8:
+ case DC1394_VIDEO_MODE_1600x1200_MONO16: {
+ point.x = 1600;
+ point.y = 1200;
+ return point;
+ }
+ default:
+ AVG_ASSERT(false);
+ return point;
+ }
+}
+
+PixelFormat getPFFromVideoMode(dc1394video_mode_t mode)
+{
+ switch (mode) {
+ case DC1394_VIDEO_MODE_640x480_YUV411:
+ return YCbCr411;
+ case DC1394_VIDEO_MODE_320x240_YUV422:
+ case DC1394_VIDEO_MODE_640x480_YUV422:
+ case DC1394_VIDEO_MODE_800x600_YUV422:
+ case DC1394_VIDEO_MODE_1024x768_YUV422:
+ case DC1394_VIDEO_MODE_1280x960_YUV422:
+ case DC1394_VIDEO_MODE_1600x1200_YUV422:
+ return YCbCr422;
+ case DC1394_VIDEO_MODE_640x480_RGB8:
+ case DC1394_VIDEO_MODE_800x600_RGB8:
+ case DC1394_VIDEO_MODE_1024x768_RGB8:
+ case DC1394_VIDEO_MODE_1280x960_RGB8:
+ case DC1394_VIDEO_MODE_1600x1200_RGB8:
+ return R8G8B8;
+ case DC1394_VIDEO_MODE_640x480_MONO8:
+ case DC1394_VIDEO_MODE_800x600_MONO8:
+ case DC1394_VIDEO_MODE_1024x768_MONO8:
+ case DC1394_VIDEO_MODE_1280x960_MONO8:
+ case DC1394_VIDEO_MODE_1600x1200_MONO8:
+ return I8;
+ case DC1394_VIDEO_MODE_640x480_MONO16:
+ case DC1394_VIDEO_MODE_800x600_MONO16:
+ case DC1394_VIDEO_MODE_1024x768_MONO16:
+ case DC1394_VIDEO_MODE_1280x960_MONO16:
+ case DC1394_VIDEO_MODE_1600x1200_MONO16:
+ return I16;
+ default:
+ AVG_ASSERT(false);
+ return PixelFormat(0);
+ }
+}
+
+float framerateToFloat(dc1394framerate_t framerate)
+{
+ switch (framerate) {
+ case DC1394_FRAMERATE_1_875:
+ return 1.875;
+ case DC1394_FRAMERATE_3_75:
+ return 3.75;
+ case DC1394_FRAMERATE_7_5:
+ return 7.5;
+ case DC1394_FRAMERATE_15:
+ return 15;
+ case DC1394_FRAMERATE_30:
+ return 30;
+ case DC1394_FRAMERATE_60:
+ return 60;
+ case DC1394_FRAMERATE_120:
+ return 120;
+ case DC1394_FRAMERATE_240:
+ return 240;
+ default:{
+ AVG_ASSERT(false);
+ return -1;
+ }
+ }
+}
+
+
+}
diff --git a/src/imaging/FWCameraUtils.h b/src/imaging/FWCameraUtils.h
new file mode 100644
index 0000000..668f5bb
--- /dev/null
+++ b/src/imaging/FWCameraUtils.h
@@ -0,0 +1,48 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _FWCameraUtils_H_
+#define _FWCameraUtils_H_
+
+#include "../api.h"
+#include "Camera.h"
+
+#include "../avgconfigwrapper.h"
+
+#include "../base/GLMHelper.h"
+
+#include <dc1394/control.h>
+
+#include <string>
+
+namespace avg {
+
+dc1394video_mode_t getCamMode(IntPoint size, PixelFormat pf);
+dc1394framerate_t getFrameRateConst(float frameRate);
+CameraFeature featureIDToEnum(dc1394feature_t feature);
+dc1394feature_t getFeatureID(CameraFeature feature);
+IntPoint getFrameSizeFromVideoMode(dc1394video_mode_t mode);
+PixelFormat getPFFromVideoMode(dc1394video_mode_t mode);
+float framerateToFloat(dc1394framerate_t framerate);
+
+}
+
+#endif
diff --git a/src/imaging/FakeCamera.cpp b/src/imaging/FakeCamera.cpp
new file mode 100644
index 0000000..ffb1cb3
--- /dev/null
+++ b/src/imaging/FakeCamera.cpp
@@ -0,0 +1,149 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "FakeCamera.h"
+
+#include "../graphics/Pixel8.h"
+#include "../graphics/Filterfill.h"
+#include "../graphics/Filterfillrect.h"
+#include "../graphics/Filtergrayscale.h"
+#include "../graphics/BitmapLoader.h"
+
+#include "../base/TimeSource.h"
+#include "../base/Exception.h"
+#include "../base/Logger.h"
+
+
+using namespace std;
+
+namespace avg {
+
+FakeCamera::FakeCamera(PixelFormat camPF, PixelFormat destPF)
+ : Camera(camPF, destPF, IntPoint(640, 480), 60),
+ m_pBmpQ(new std::queue<BitmapPtr>()),
+ m_bIsOpen(false)
+{
+}
+
+FakeCamera::FakeCamera(std::vector<std::string>& pictures)
+ : Camera(I8, I8, IntPoint(640,480), 60),
+ m_pBmpQ(new std::queue<BitmapPtr>()),
+ m_bIsOpen(false)
+{
+ for (vector<string>::iterator it = pictures.begin(); it != pictures.end(); ++it) {
+ try {
+ BitmapPtr pBmp = loadBitmap(*it);
+ FilterGrayscale().applyInPlace(pBmp);
+ setImgSize(pBmp->getSize());
+ m_pBmpQ->push(pBmp);
+ } catch (Exception& ex) {
+ AVG_LOG_ERROR(ex.getStr());
+ throw;
+ }
+ }
+}
+
+FakeCamera::~FakeCamera()
+{
+}
+
+void FakeCamera::open()
+{
+ m_bIsOpen = true;
+}
+
+void FakeCamera::close()
+{
+ m_bIsOpen = false;
+}
+
+
+BitmapPtr FakeCamera::getImage(bool bWait)
+{
+ if (bWait) {
+ msleep(100);
+ }
+ if (!m_bIsOpen || !bWait || m_pBmpQ->empty()) {
+ return BitmapPtr();
+ } else {
+ BitmapPtr pBmp = m_pBmpQ->front();
+ m_pBmpQ->pop();
+ return pBmp;
+ }
+}
+
+bool FakeCamera::isCameraAvailable()
+{
+ return true;
+}
+
+
+const string& FakeCamera::getDevice() const
+{
+ static string sDeviceName = "FakeCamera";
+ return sDeviceName;
+}
+
+const std::string& FakeCamera::getDriverName() const
+{
+ static string sDriverName = "FakeCameraDriver";
+ return sDriverName;
+}
+
+const string& FakeCamera::getMode() const
+{
+ static string sMode = "FakeCamera";
+ return sMode;
+}
+
+
+int FakeCamera::getFeature(CameraFeature feature) const
+{
+ return 0;
+}
+
+void FakeCamera::setFeature(CameraFeature feature, int value, bool bIgnoreOldValue)
+{
+}
+
+void FakeCamera::setFeatureOneShot(CameraFeature feature)
+{
+}
+
+int FakeCamera::getWhitebalanceU() const
+{
+ return 0;
+}
+
+int FakeCamera::getWhitebalanceV() const
+{
+ return 0;
+}
+
+void FakeCamera::setWhitebalance(int u, int v, bool bIgnoreOldValue)
+{
+}
+
+}
+
+
+
+
diff --git a/src/imaging/FakeCamera.h b/src/imaging/FakeCamera.h
new file mode 100644
index 0000000..4128043
--- /dev/null
+++ b/src/imaging/FakeCamera.h
@@ -0,0 +1,69 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _FakeCamera_H_
+#define _FakeCamera_H_
+
+#include "../api.h"
+#include "Camera.h"
+
+#include <boost/shared_ptr.hpp>
+
+#include <string>
+#include <queue>
+
+namespace avg {
+
+typedef boost::shared_ptr<std::queue<BitmapPtr> > BitmapQueuePtr;
+
+class AVG_API FakeCamera: public Camera
+{
+public:
+ FakeCamera(PixelFormat camPF, PixelFormat destPF);
+ FakeCamera(std::vector<std::string>& pictures);
+ virtual ~FakeCamera();
+ virtual void open();
+ virtual void close();
+
+ virtual BitmapPtr getImage(bool bWait);
+ virtual bool isCameraAvailable();
+
+ virtual const std::string& getDevice() const;
+ virtual const std::string& getDriverName() const;
+ virtual const std::string& getMode() const;
+
+ virtual int getFeature(CameraFeature feature) const;
+ virtual void setFeature(CameraFeature feature, int Value, bool bIgnoreOldValue=false);
+ virtual void setFeatureOneShot(CameraFeature feature);
+ virtual int getWhitebalanceU() const;
+ virtual int getWhitebalanceV() const;
+ virtual void setWhitebalance(int u, int v, bool bIgnoreOldValue=false);
+
+private:
+ BitmapQueuePtr m_pBmpQ;
+ bool m_bIsOpen;
+};
+
+}
+
+#endif
+
+
diff --git a/src/imaging/FilterClearBorder.cpp b/src/imaging/FilterClearBorder.cpp
new file mode 100644
index 0000000..dba7c8b
--- /dev/null
+++ b/src/imaging/FilterClearBorder.cpp
@@ -0,0 +1,67 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "FilterClearBorder.h"
+
+#include "../base/Exception.h"
+
+#include <iostream>
+#include <math.h>
+#include <string.h>
+
+using namespace std;
+
+namespace avg {
+
+FilterClearBorder::FilterClearBorder(int numPixels)
+ : m_NumPixels(numPixels)
+{
+}
+
+FilterClearBorder::~FilterClearBorder()
+{
+}
+
+void FilterClearBorder::applyInPlace(BitmapPtr pBmp)
+{
+ AVG_ASSERT(pBmp->getPixelFormat() == I8);
+ AVG_ASSERT(m_NumPixels < pBmp->getSize().x);
+ AVG_ASSERT(m_NumPixels < pBmp->getSize().y);
+ if (m_NumPixels != 0) {
+ int stride = pBmp->getStride();
+ unsigned char * pPixels = pBmp->getPixels();
+ IntPoint size = pBmp->getSize();
+ IntPoint activeSize = pBmp->getSize()-IntPoint(2*m_NumPixels, 2*m_NumPixels);
+ for (int y=m_NumPixels-1; y >= 0; --y) {
+ memset(pPixels+stride*y+m_NumPixels, 0, activeSize.x);
+ }
+ for (int y=size.y-m_NumPixels; y < size.y; ++y) {
+ memset(pPixels+stride*y+m_NumPixels, 0, activeSize.x);
+ }
+
+ for (int y = 0; y < size.y; ++y) {
+ memset(pPixels+stride*y, 0, m_NumPixels);
+ memset(pPixels+stride*y+size.x-m_NumPixels, 0, m_NumPixels);
+ }
+ }
+}
+
+}
diff --git a/src/imaging/FilterClearBorder.h b/src/imaging/FilterClearBorder.h
new file mode 100644
index 0000000..80c700b
--- /dev/null
+++ b/src/imaging/FilterClearBorder.h
@@ -0,0 +1,51 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _FilterClearBorder_H_
+#define _FilterClearBorder_H_
+
+#include "../api.h"
+#include "CoordTransformer.h"
+
+#include "../graphics/Filter.h"
+
+#include "../base/GLMHelper.h"
+#include "../base/Rect.h"
+
+#include <boost/shared_ptr.hpp>
+
+namespace avg {
+
+class AVG_API FilterClearBorder: public Filter
+{
+ public:
+ FilterClearBorder(int numPixels);
+ virtual ~FilterClearBorder();
+ virtual void applyInPlace(BitmapPtr pBmp);
+ private:
+ int m_NumPixels;
+};
+
+typedef boost::shared_ptr<FilterClearBorder> FilterClearBorderPtr;
+
+}
+
+#endif
diff --git a/src/imaging/FilterDistortion.cpp b/src/imaging/FilterDistortion.cpp
new file mode 100644
index 0000000..08b55bb
--- /dev/null
+++ b/src/imaging/FilterDistortion.cpp
@@ -0,0 +1,83 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+// Original author of this file is igor@c-base.org.
+//
+
+#include "FilterDistortion.h"
+
+#include <iostream>
+#include <math.h>
+
+using namespace std;
+
+namespace avg {
+
+FilterDistortion::FilterDistortion(const IntPoint& srcSize,
+ CoordTransformerPtr pTransformer)
+ : m_SrcSize(srcSize),
+ m_pTransformer(pTransformer)
+{
+ // We use the same dimensions for both of src and dest and just crop.
+ // for each pixel at (x,y) in the dest, m_pMap[x][y] contains an IntPoint that gives
+ // the coords in the src Bitmap.
+ m_pMap = new IntPoint[m_SrcSize.y*m_SrcSize.x];
+ for (int y = 0; y < m_SrcSize.y; ++y) {
+ for (int x = 0; x < m_SrcSize.x; ++x) {
+ glm::dvec2 tmp = m_pTransformer->inverse_transform_point(glm::dvec2(x,y));
+ IntPoint tmp2(int(tmp.x+0.5),int(tmp.y+0.5));
+ if (tmp2.x < m_SrcSize.x && tmp2.y < m_SrcSize.y &&
+ tmp2.x >= 0 && tmp2.y >= 0)
+ {
+ m_pMap[y*m_SrcSize.x+x] = tmp2;
+ } else {
+ m_pMap[y*m_SrcSize.x+x] = IntPoint(0,0);
+ }
+ }
+ }
+}
+
+FilterDistortion::~FilterDistortion()
+{
+ delete[] m_pMap;
+}
+
+BitmapPtr FilterDistortion::apply(BitmapPtr pBmpSource)
+{
+ BitmapPtr pDestBmp = BitmapPtr(new Bitmap(m_SrcSize, I8));
+ unsigned char* pDestLine = pDestBmp->getPixels();
+ unsigned char* pSrcPixels = pBmpSource->getPixels();
+ unsigned char* pDestPixel = pDestLine;
+ int destStride = pDestBmp->getStride();
+ int srcStride = pBmpSource->getStride();
+ IntPoint * pMapPos = m_pMap;
+ for (int y = 0; y < m_SrcSize.y; ++y) {
+ for(int x = 0; x < m_SrcSize.x; ++x) {
+ *pDestPixel = pSrcPixels[pMapPos->x + srcStride*pMapPos->y];
+ pDestPixel++;
+ pMapPos++;
+ }
+ pDestLine+=destStride;
+ pDestPixel = pDestLine;
+ }
+ return pDestBmp;
+}
+
+}
diff --git a/src/imaging/FilterDistortion.h b/src/imaging/FilterDistortion.h
new file mode 100644
index 0000000..25de14e
--- /dev/null
+++ b/src/imaging/FilterDistortion.h
@@ -0,0 +1,56 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+// Original author of this file is igor@c-base.org
+//
+
+#ifndef _FilterDistortion_H_
+#define _FilterDistortion_H_
+
+#include "../api.h"
+#include "CoordTransformer.h"
+
+#include "../graphics/Filter.h"
+
+#include "../base/GLMHelper.h"
+#include "../base/Rect.h"
+
+#include <boost/shared_ptr.hpp>
+
+namespace avg {
+
+// TODO: This class doesn't have a unit test.
+class AVG_API FilterDistortion: public Filter
+{
+ public:
+ FilterDistortion(const IntPoint& srcSize, CoordTransformerPtr pTransformer);
+ virtual ~FilterDistortion();
+ BitmapPtr apply(BitmapPtr pBmpSource);
+ private:
+ IntPoint m_SrcSize;
+ CoordTransformerPtr m_pTransformer;
+ IntPoint* m_pMap;
+};
+
+typedef boost::shared_ptr<FilterDistortion> FilterDistortionPtr;
+
+}
+
+#endif
diff --git a/src/imaging/FilterWipeBorder.cpp b/src/imaging/FilterWipeBorder.cpp
new file mode 100644
index 0000000..dd09068
--- /dev/null
+++ b/src/imaging/FilterWipeBorder.cpp
@@ -0,0 +1,70 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "FilterWipeBorder.h"
+
+#include "../base/Exception.h"
+
+#include <iostream>
+#include <math.h>
+#include <string.h>
+
+using namespace std;
+
+namespace avg {
+
+FilterWipeBorder::FilterWipeBorder(int numPixels)
+ : m_NumPixels(numPixels)
+{
+}
+
+FilterWipeBorder::~FilterWipeBorder()
+{
+}
+
+void FilterWipeBorder::applyInPlace(BitmapPtr pBmp)
+{
+ AVG_ASSERT(pBmp->getPixelFormat() == I8);
+ if (m_NumPixels != 0) {
+ int stride = pBmp->getStride();
+ unsigned char * pPixels = pBmp->getPixels();
+ IntPoint size = pBmp->getSize();
+ IntPoint activeSize = pBmp->getSize()-IntPoint(2*m_NumPixels, 2*m_NumPixels);
+
+ unsigned char * pSrcLine = pPixels+stride*m_NumPixels+m_NumPixels;
+ for (int y = m_NumPixels-1; y >= 0; --y) {
+ memcpy(pPixels+stride*y+m_NumPixels, pSrcLine, activeSize.x);
+ }
+ pSrcLine = pPixels+stride*(size.y-m_NumPixels-1)+m_NumPixels;
+ for (int y = size.y-m_NumPixels; y < size.y; ++y) {
+ memcpy(pPixels+stride*y+m_NumPixels, pSrcLine, activeSize.x);
+ }
+
+ for (int y = 0; y < size.y; ++y) {
+ unsigned char src = *(pPixels+stride*y+m_NumPixels);
+ memset(pPixels+stride*y, src, m_NumPixels);
+ src = *(pPixels+stride*y+size.x-m_NumPixels-1);
+ memset(pPixels+stride*y+size.x-m_NumPixels, src, m_NumPixels);
+ }
+ }
+}
+
+}
diff --git a/src/imaging/FilterWipeBorder.h b/src/imaging/FilterWipeBorder.h
new file mode 100644
index 0000000..7804560
--- /dev/null
+++ b/src/imaging/FilterWipeBorder.h
@@ -0,0 +1,50 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _FilterWipeBorder_H_
+#define _FilterWipeBorder_H_
+
+#include "../api.h"
+#include "CoordTransformer.h"
+
+#include "../graphics/Filter.h"
+
+#include "../base/Rect.h"
+
+#include <boost/shared_ptr.hpp>
+
+namespace avg {
+
+class AVG_API FilterWipeBorder: public Filter
+{
+ public:
+ FilterWipeBorder(int numPixels);
+ virtual ~FilterWipeBorder();
+ virtual void applyInPlace(BitmapPtr pBmp);
+ private:
+ int m_NumPixels;
+};
+
+typedef boost::shared_ptr<FilterWipeBorder> FilterWipeBorderPtr;
+
+}
+
+#endif
diff --git a/src/imaging/IDSSampleCallback.h b/src/imaging/IDSSampleCallback.h
new file mode 100644
index 0000000..78e8889
--- /dev/null
+++ b/src/imaging/IDSSampleCallback.h
@@ -0,0 +1,37 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _IDSSampleCallback_H_
+#define _IDSSampleCallback_H_
+
+struct IMediaSample;
+
+namespace avg {
+
+class IDSSampleCallback
+{
+public:
+ virtual void onSample(IMediaSample * pSample)=0;
+};
+
+};
+
+#endif \ No newline at end of file
diff --git a/src/imaging/Makefile.am b/src/imaging/Makefile.am
new file mode 100644
index 0000000..93d1562
--- /dev/null
+++ b/src/imaging/Makefile.am
@@ -0,0 +1,41 @@
+AM_CPPFLAGS = -I.. @PTHREAD_CFLAGS@ @XML2_CFLAGS@ @GDK_PIXBUF_CFLAGS@
+
+if ENABLE_V4L2
+ V4L2_SOURCES = V4LCamera.cpp
+ V4L2_INCLUDES = V4LCamera.h
+else
+ V4L2_SOURCES =
+ V4L2_INCLUDES =
+endif
+
+if ENABLE_1394_2
+ DC1394_SOURCES = FWCameraUtils.cpp
+ DC1394_INCLUDES = FWCameraUtils.h
+else
+ DC1394_SOURCES =
+ DC1394_INCLUDES =
+endif
+
+ALL_H = Camera.h TrackerThread.h TrackerConfig.h Blob.h FWCamera.h Run.h \
+ FakeCamera.h CoordTransformer.h FilterDistortion.h $(DC1394_INCLUDES) \
+ DeDistort.h trackerconfigdtd.h FilterWipeBorder.h FilterClearBorder.h \
+ $(V4L2_INCLUDES) CameraInfo.h
+ALL_CPP = Camera.cpp TrackerThread.cpp TrackerConfig.cpp Blob.cpp FWCamera.cpp Run.cpp \
+ FakeCamera.cpp CoordTransformer.cpp FilterDistortion.cpp $(DC1394_SOURCES) \
+ DeDistort.cpp trackerconfigdtd.cpp FilterWipeBorder.cpp FilterClearBorder.cpp \
+ $(V4L2_SOURCES) CameraInfo.cpp
+
+TESTS = testimaging
+
+EXTRA_DIST = avgtrackerrc.minimal $(wildcard baseline/*.png) $(wildcard testfiles/*.png) \
+ CMUCamera.h CMUCamera.cpp DSCamera.cpp DSCamera.h DSHelper.h DSHelper.cpp \
+ DSSampleGrabber.h DSSampleGrabber.cpp CMUCameraUtils.h CMUCameraUtils.cpp
+
+noinst_LTLIBRARIES = libimaging.la
+libimaging_la_SOURCES = $(ALL_CPP) $(ALL_H)
+
+noinst_PROGRAMS = testimaging
+testimaging_SOURCES = testimaging.cpp $(ALL_H)
+testimaging_LDADD = ./libimaging.la ../graphics/libgraphics.la ../base/libbase.la \
+ ../base/triangulate/libtriangulate.la \
+ @XML2_LIBS@ @BOOST_THREAD_LIBS@ @PTHREAD_LIBS@ @GDK_PIXBUF_LIBS@
diff --git a/src/imaging/Run.cpp b/src/imaging/Run.cpp
new file mode 100644
index 0000000..37cc97d
--- /dev/null
+++ b/src/imaging/Run.cpp
@@ -0,0 +1,36 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+// Original author of this file is igor@c-base.org
+//
+
+#include "Run.h"
+
+namespace avg {
+
+Run::Run(int row, int startCol, int endCol)
+{
+ m_Row = row;
+ m_StartCol = startCol;
+ m_EndCol = endCol;
+ m_Center = glm::vec2((m_StartCol + m_EndCol-1)/2., m_Row);
+}
+
+}
diff --git a/src/imaging/Run.h b/src/imaging/Run.h
new file mode 100644
index 0000000..f3375f2
--- /dev/null
+++ b/src/imaging/Run.h
@@ -0,0 +1,56 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+// Original author of this file is igor@c-base.org
+//
+
+#ifndef _Run_H_
+#define _Run_H_
+
+#include "../api.h"
+#include "../base/GLMHelper.h"
+
+#include <boost/weak_ptr.hpp>
+
+#include <vector>
+
+namespace avg {
+
+class Blob;
+typedef boost::weak_ptr<class Blob> BlobWeakPtr;
+
+struct Run
+{
+ Run(int row, int startCol, int end_col);
+ int m_Row;
+ int m_StartCol;
+ int m_EndCol;
+ glm::vec2 m_Center;
+ int length() {
+ return m_EndCol-m_StartCol;
+ };
+ BlobWeakPtr m_pBlob;
+};
+
+typedef std::vector<Run> RunArray;
+
+}
+
+#endif
diff --git a/src/imaging/TrackerConfig.cpp b/src/imaging/TrackerConfig.cpp
new file mode 100644
index 0000000..be4c758
--- /dev/null
+++ b/src/imaging/TrackerConfig.cpp
@@ -0,0 +1,268 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+
+#include "TrackerConfig.h"
+#include "trackerconfigdtd.h"
+#include "DeDistort.h"
+
+#include "../base/XMLHelper.h"
+#include "../base/Logger.h"
+#include "../base/FileHelper.h"
+#include "../base/Exception.h"
+#include "../base/StringHelper.h"
+#include "../base/ConfigMgr.h"
+
+#include <libxml/parser.h>
+#include <libxml/xmlwriter.h>
+#include <libxml/xmlstring.h>
+
+#include <cstring>
+#include <sstream>
+#include <iostream>
+
+using namespace std;
+
+namespace avg {
+
+TrackerConfig::TrackerConfig()
+ : m_Doc(0)
+{
+}
+
+TrackerConfig::TrackerConfig(const TrackerConfig& other)
+{
+ m_Doc = 0;
+ if (other.m_Doc) {
+ m_Doc = xmlCopyDoc(other.m_Doc, true);
+ m_sFilename = other.m_sFilename;
+ m_pRoot = xmlDocGetRootElement(m_Doc);
+ }
+}
+
+TrackerConfig::~TrackerConfig()
+{
+ xmlFreeDoc(m_Doc);
+}
+
+void TrackerConfig::loadConfigFile(const string& sFilename)
+{
+ // TODO: There is duplicated code here and in Player::loadFile which belongs
+ // in a lower-level xml handling class.
+ registerDTDEntityLoader("trackerconfig.dtd", g_pTrackerConfigDTD);
+ xmlDtdPtr dtd;
+ string sDTDFName = "trackerconfig.dtd";
+ dtd = xmlParseDTD(NULL, (const xmlChar*) sDTDFName.c_str());
+ if (!dtd) {
+ AVG_LOG_WARNING("DTD not found at " << sDTDFName
+ << ". Not validating trackerconfig files.");
+ }
+
+ // xmlParseFile crashes for some reason under Lion.
+ string sFileContents;
+ readWholeFile(sFilename, sFileContents);
+ m_Doc = xmlParseMemory(sFileContents.c_str(), sFileContents.length());
+ if (!m_Doc) {
+ AVG_LOG_ERROR("Could not open tracker config file " << sFilename <<
+ ". Using defaults which will probably not work.");
+ return;
+ }
+
+ xmlValidCtxtPtr cvp = xmlNewValidCtxt();
+ cvp->error = xmlParserValidityError;
+ cvp->warning = xmlParserValidityWarning;
+ int isValid = xmlValidateDtd(cvp, m_Doc, dtd);
+ xmlFreeValidCtxt(cvp);
+ if (!isValid) {
+ throw (Exception(AVG_ERR_XML_PARSE, sFilename + " does not validate."));
+ }
+
+ m_pRoot = xmlDocGetRootElement(m_Doc);
+ xmlFreeDtd(dtd);
+ m_sFilename = sFilename;
+
+ AVG_TRACE(Logger::category::CONFIG, Logger::severity::INFO,
+ "Reading Tracker config file from " << sFilename);
+}
+
+void TrackerConfig::load()
+{
+ // Give precedence to local configuration
+ string sFName = "avgtrackerrc";
+ if (fileExists(sFName) || !fileExists(getGlobalConfigDir() + sFName)) {
+ loadConfigFile(sFName);
+ } else {
+ loadConfigFile(getGlobalConfigDir() + sFName);
+ }
+}
+
+xmlXPathObjectPtr TrackerConfig::findConfigNodes(const string& sXPathExpr) const
+{
+ string sFullPath = string("/trackerconfig"+sXPathExpr);
+ xmlXPathContextPtr xpCtx;
+ xmlXPathObjectPtr xpElement;
+
+ xpCtx = xmlXPathNewContext(m_Doc);
+ if(!xpCtx) {
+ AVG_LOG_ERROR("Unable to create new XPath context");
+ return NULL;
+ }
+
+ xpElement = xmlXPathEvalExpression(BAD_CAST sFullPath.c_str(), xpCtx);
+ if(!xpElement) {
+ AVG_LOG_ERROR("Unable to evaluate XPath expression '"
+ << sFullPath << "'");
+ xmlXPathFreeContext(xpCtx);
+ return NULL;
+ }
+
+ xmlXPathFreeContext(xpCtx);
+
+ return xpElement;
+}
+
+void TrackerConfig::setParam(const string& sXPathExpr, const string& sValue)
+{
+ xmlXPathObjectPtr xpElement = findConfigNodes(sXPathExpr);
+ xmlNodeSetPtr nodes = xpElement->nodesetval;
+
+ if (!nodes || nodes->nodeNr == 0)
+ throw (Exception(AVG_ERR_OPTION_UNKNOWN,
+ string("setParam(): cannot find requested element ")+sXPathExpr));
+
+ for (int i = nodes->nodeNr-1; i >= 0; i--) {
+ AVG_ASSERT(nodes->nodeTab[i]);
+
+ xmlNodeSetContent(nodes->nodeTab[i], BAD_CAST sValue.c_str());
+ if (nodes->nodeTab[i]->type != XML_NAMESPACE_DECL)
+ nodes->nodeTab[i] = NULL;
+ }
+
+ xmlXPathFreeObject(xpElement);
+}
+
+string TrackerConfig::getParam(const string& sXPathExpr) const
+{
+ xmlXPathObjectPtr xpElement = findConfigNodes(sXPathExpr);
+ xmlNodeSetPtr nodes = xpElement->nodesetval;
+
+ if (!nodes || nodes->nodeNr == 0) {
+ throw (Exception(AVG_ERR_OPTION_UNKNOWN,
+ string("getParam(): cannot find requested element ")+sXPathExpr));
+ } else if (nodes->nodeNr > 1) {
+ AVG_LOG_WARNING(
+ "getParam(): expression selects more than one node. Returning the first.");
+ }
+
+ xmlChar* xsRc = xmlNodeGetContent(nodes->nodeTab[0]);
+ string sValue((char *)xsRc);
+
+ xmlFree(xsRc);
+ xmlXPathFreeObject(xpElement);
+
+ return sValue;
+}
+
+bool TrackerConfig::getBoolParam(const std::string& sXPathExpr) const
+{
+ return stringToBool(getParam(sXPathExpr));
+}
+
+int TrackerConfig::getIntParam(const std::string& sXPathExpr) const
+{
+ return stringToInt(getParam(sXPathExpr));
+}
+
+float TrackerConfig::getFloatParam(const std::string& sXPathExpr) const
+{
+ return stringToFloat(getParam(sXPathExpr));
+}
+
+glm::vec2 TrackerConfig::getPointParam(const std::string& sXPathExpr) const
+{
+ return glm::vec2(getFloatParam(sXPathExpr+"@x"), getFloatParam(sXPathExpr+"@y"));
+}
+
+FRect TrackerConfig::getRectParam(const std::string& sXPathExpr) const
+{
+ glm::vec2 pos1 = glm::vec2(getFloatParam(sXPathExpr+"@x1"),
+ getFloatParam(sXPathExpr+"@y1"));
+ glm::vec2 pos2 = glm::vec2(getFloatParam(sXPathExpr+"@x2"),
+ getFloatParam(sXPathExpr+"@y2"));
+ return FRect(pos1, pos2);
+}
+
+xmlNodePtr TrackerConfig::getXmlNode(const std::string& sXPathExpr) const
+{
+ xmlXPathObjectPtr xpElement = findConfigNodes(sXPathExpr);
+ xmlNodeSetPtr nodes = xpElement->nodesetval;
+
+ if (!nodes || nodes->nodeNr == 0) {
+ throw (Exception(AVG_ERR_OPTION_UNKNOWN,
+ string("getParam(): cannot find requested element ")+sXPathExpr));
+ } else if (nodes->nodeNr > 1) {
+ AVG_LOG_WARNING(
+ "getXmlNode(): expression selects more than one node. Returning the first.");
+ }
+ return nodes->nodeTab[0];
+}
+
+DeDistortPtr TrackerConfig::getTransform() const
+{
+ glm::vec2 CameraExtents = getPointParam("/camera/size/");
+ DeDistortPtr pDD(new DeDistort);
+ pDD->load(CameraExtents, *this);
+ return pDD;
+}
+
+void TrackerConfig::setTransform(DeDistortPtr pDeDistort)
+{
+ pDeDistort->save(*this);
+}
+
+void TrackerConfig::dump() const
+{
+ string s;
+ xmlBufferPtr pBuffer = xmlBufferCreate();
+ xmlNodeDump(pBuffer, m_Doc, m_pRoot, 0, 0);
+ cerr << xmlBufferContent(pBuffer) << endl;
+}
+
+void TrackerConfig::save()
+{
+ AVG_TRACE(Logger::category::CONFIG, Logger::severity::INFO,
+ "Saving tracker configuration to " << m_sFilename << ".");
+
+ if (m_Doc) {
+ if (fileExists(m_sFilename)) {
+ string sBakFile = m_sFilename + ".bak";
+ unlink(sBakFile.c_str());
+ if (rename(m_sFilename.c_str(), sBakFile.c_str())) {
+ AVG_LOG_WARNING("Cannot create tracker config backup. Backing "
+ "it up on current workdir.");
+ copyFile(m_sFilename, "avgtrackerrc.bak");
+ }
+ }
+ xmlSaveFileEnc(m_sFilename.c_str(), m_Doc, "utf-8");
+ } else
+ throw (Exception(AVG_ERR_FILEIO,
+ "save(): tracker configuration not initialized"));
+}
+
+}
diff --git a/src/imaging/TrackerConfig.h b/src/imaging/TrackerConfig.h
new file mode 100644
index 0000000..557f78a
--- /dev/null
+++ b/src/imaging/TrackerConfig.h
@@ -0,0 +1,75 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+// Original author of this file is igor@c-base.org.
+//
+
+#ifndef _TrackerConfig_H_
+#define _TrackerConfig_H_
+
+#include "../api.h"
+#include "../base/Rect.h"
+
+#include <boost/shared_ptr.hpp>
+#include <string>
+
+#include <libxml/xpath.h>
+
+namespace avg {
+
+class DeDistort;
+typedef boost::shared_ptr<DeDistort> DeDistortPtr;
+
+class AVG_API TrackerConfig
+{
+public:
+ TrackerConfig();
+ TrackerConfig(const TrackerConfig& other);
+ virtual ~TrackerConfig();
+
+ void load();
+ void save();
+ void setParam(const std::string& sXPathExpr, const std::string& sValue);
+ std::string getParam(const std::string& sXPathExpr) const;
+ bool getBoolParam(const std::string& sXPathExpr) const;
+ int getIntParam(const std::string& sXPathExpr) const;
+ float getFloatParam(const std::string& sXPathExpr) const;
+ glm::vec2 getPointParam(const std::string& sXPathExpr) const;
+ FRect getRectParam(const std::string& sXPathExpr) const;
+ xmlNodePtr getXmlNode(const std::string& sXPathExpr) const;
+
+ DeDistortPtr getTransform() const;
+ void setTransform(DeDistortPtr pDeDistort);
+
+ void dump() const;
+
+private:
+ xmlXPathObjectPtr findConfigNodes(const std::string& sXPathExpr) const;
+
+ xmlDocPtr m_Doc;
+ xmlNodePtr m_pRoot;
+
+ std::string m_sFilename;
+ void loadConfigFile(const std::string& sFilename);
+};
+typedef boost::shared_ptr<TrackerConfig> TrackerConfigPtr;
+
+}
+#endif
diff --git a/src/imaging/TrackerThread.cpp b/src/imaging/TrackerThread.cpp
new file mode 100644
index 0000000..079a8d6
--- /dev/null
+++ b/src/imaging/TrackerThread.cpp
@@ -0,0 +1,548 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+
+#include "TrackerThread.h"
+#include "FilterDistortion.h"
+#include "FilterWipeBorder.h"
+
+#include "../base/Logger.h"
+#include "../base/ProfilingZoneID.h"
+#include "../base/TimeSource.h"
+#include "../base/ScopeTimer.h"
+#include "../base/Exception.h"
+
+#include "../graphics/Filter.h"
+#include "../graphics/Filterfill.h"
+#include "../graphics/FilterHighpass.h"
+#include "../graphics/FilterFastBandpass.h"
+#include "../graphics/FilterFastDownscale.h"
+#include "../graphics/FilterNormalize.h"
+#include "../graphics/FilterBlur.h"
+#include "../graphics/FilterGauss.h"
+#include "../graphics/FilterMask.h"
+#include "../graphics/GLContext.h"
+#include "../graphics/GPUBandpassFilter.h"
+#include "../graphics/GPUBlurFilter.h"
+#include "../graphics/BitmapLoader.h"
+
+#include <iostream>
+#include <stdlib.h>
+
+using namespace std;
+
+namespace avg {
+
+static ProfilingZoneID ProfilingZoneCapture("Capture");
+static ProfilingZoneID ProfilingZoneMask("Mask");
+static ProfilingZoneID ProfilingZoneTracker("Tracker");
+static ProfilingZoneID ProfilingZoneHistory("History");
+static ProfilingZoneID ProfilingZoneDistort("Distort");
+static ProfilingZoneID ProfilingZoneHistogram("Histogram");
+static ProfilingZoneID ProfilingZoneDownscale("Downscale");
+static ProfilingZoneID ProfilingZoneBandpass("Bandpass");
+static ProfilingZoneID ProfilingZoneComps("ConnectedComps");
+static ProfilingZoneID ProfilingZoneUpdate("Update");
+static ProfilingZoneID ProfilingZoneDraw("Draw");
+
+TrackerThread::TrackerThread(IntRect roi, CameraPtr pCamera,
+ BitmapPtr ppBitmaps[NUM_TRACKER_IMAGES], MutexPtr pMutex, CQueue& cmdQ,
+ IBlobTarget *pTarget, bool bSubtractHistory, TrackerConfig& config)
+ : WorkerThread<TrackerThread>("Tracker", cmdQ),
+ m_TouchThreshold(0),
+ m_TrackThreshold(0),
+ m_HistoryDelay(-1),
+ m_StartTime(0),
+ m_pMutex(pMutex),
+ m_pCamera(pCamera),
+ m_pTarget(pTarget),
+ m_pTrafo(new DeDistort()),
+ m_bCreateDebugImages(false),
+ m_bCreateFingerImage(false),
+ m_NumFrames(0),
+ m_NumCamFramesDiscarded(0),
+ m_pImagingContext(0)
+{
+ m_bTrackBrighter = config.getBoolParam("/tracker/brighterregions/@value");
+ if (bSubtractHistory) {
+ m_pHistoryPreProcessor = HistoryPreProcessorPtr(
+ new HistoryPreProcessor(ppBitmaps[1]->getSize(), 1,
+ m_bTrackBrighter));
+ }
+ m_Prescale = config.getIntParam("/tracker/prescale/@value");
+ setBitmaps(roi, ppBitmaps);
+
+ DeDistortPtr pDeDistort = config.getTransform();
+ m_pDistorter = FilterDistortionPtr(new FilterDistortion(
+ m_pBitmaps[TRACKER_IMG_CAMERA]->getSize()/m_Prescale, pDeDistort));
+
+ m_pConfig = TrackerConfigPtr(new TrackerConfig(config));
+ m_pCamera->startCapture();
+}
+
+TrackerThread::~TrackerThread()
+{
+}
+
+bool TrackerThread::init()
+{
+ try {
+ m_pImagingContext = GLContext::create(
+ GLConfig(false, false, true, 1, GLConfig::AUTO, false));
+ createBandpassFilter();
+ AVG_TRACE(Logger::category::CONFIG, Logger::severity::INFO,
+ "Using fragment shaders for imaging operations.");
+ } catch (Exception& e) {
+ AVG_LOG_WARNING(e.getStr());
+ AVG_TRACE(Logger::category::CONFIG, Logger::severity::WARNING,
+ "Using CPU for imaging operations (slow and inaccurate).");
+ m_pImagingContext = 0;
+ m_pBandpassFilter = FilterPtr(new FilterFastBandpass());
+ }
+ try {
+ m_StartTime = TimeSource::get()->getCurrentMillisecs();
+ m_HistoryDelay = m_pConfig->getIntParam("/tracker/historydelay/@value");
+ } catch (Exception& e) {
+ AVG_LOG_WARNING(e.getStr());
+ }
+
+ // Done in TrackerInputDevice::ctor to work around Leopard/libdc1394 threading issue.
+ // m_pCamera->open();
+ return true;
+}
+
+bool TrackerThread::work()
+{
+ if ((m_HistoryDelay + m_StartTime) < TimeSource::get()->getCurrentMillisecs()
+ && m_HistoryDelay != -1)
+ {
+ resetHistory();
+ m_HistoryDelay = -1;
+ }
+
+ BitmapPtr pCamBmp;
+ {
+ ScopeTimer timer(ProfilingZoneCapture);
+ pCamBmp = m_pCamera->getImage(true);
+ BitmapPtr pTempBmp1;
+ while ((pTempBmp1 = m_pCamera->getImage(false))) {
+ m_NumCamFramesDiscarded++;
+ m_NumFrames++;
+ pCamBmp = pTempBmp1;
+ }
+ }
+ long long time = TimeSource::get()->getCurrentMillisecs();
+ if (pCamBmp) {
+ m_NumFrames++;
+ ScopeTimer timer(ProfilingZoneTracker);
+ if (m_pCameraMaskBmp) {
+ ScopeTimer timer(ProfilingZoneMask);
+ FilterMask(m_pCameraMaskBmp).applyInPlace(pCamBmp);
+ }
+ if (m_bCreateDebugImages) {
+ lock_guard lock(*m_pMutex);
+ *(m_pBitmaps[TRACKER_IMG_CAMERA]) = *pCamBmp;
+ ScopeTimer timer(ProfilingZoneHistogram);
+ drawHistogram(m_pBitmaps[TRACKER_IMG_HISTOGRAM], pCamBmp);
+ }
+ {
+ if (m_Prescale != 1) {
+ ScopeTimer timer(ProfilingZoneDownscale);
+ FilterFastDownscale(m_Prescale).applyInPlace(pCamBmp);
+ }
+ }
+ BitmapPtr pDistortedBmp;
+ {
+ ScopeTimer timer(ProfilingZoneDistort);
+ pDistortedBmp = m_pDistorter->apply(pCamBmp);
+ }
+ BitmapPtr pCroppedBmp(new Bitmap(*pDistortedBmp, m_ROI));
+ if (m_bCreateDebugImages) {
+ lock_guard lock(*m_pMutex);
+ m_pBitmaps[TRACKER_IMG_DISTORTED]->copyPixels(*pCroppedBmp);
+ }
+ if (m_pHistoryPreProcessor) {
+ ScopeTimer timer(ProfilingZoneHistory);
+ m_pHistoryPreProcessor->applyInPlace(pCroppedBmp);
+ }
+ if (m_bCreateDebugImages) {
+ lock_guard lock(*m_pMutex);
+ m_pBitmaps[TRACKER_IMG_NOHISTORY]->copyPixels(*pCroppedBmp);
+ FilterNormalize(2).applyInPlace(m_pBitmaps[TRACKER_IMG_NOHISTORY]);
+ }
+ {
+ BitmapPtr pBmpBandpass;
+ if (m_TouchThreshold != 0) {
+ {
+ ScopeTimer timer(ProfilingZoneBandpass);
+ pBmpBandpass = m_pBandpassFilter->apply(pCroppedBmp);
+ }
+ if (m_bCreateDebugImages) {
+ lock_guard lock(*m_pMutex);
+ *(m_pBitmaps[TRACKER_IMG_HIGHPASS]) = *pBmpBandpass;
+ }
+ }
+ calcBlobs(pCroppedBmp, pBmpBandpass, time);
+ }
+ ThreadProfiler::get()->reset();
+ }
+ return true;
+}
+
+void TrackerThread::deinit()
+{
+ m_pCamera = CameraPtr();
+ AVG_TRACE(Logger::category::PROFILE, Logger::severity::INFO,
+ "Total camera frames: " << m_NumFrames);
+ AVG_TRACE(Logger::category::PROFILE, Logger::severity::INFO,
+ "Camera frames discarded: " << m_NumCamFramesDiscarded);
+ if (m_pBandpassFilter) {
+ m_pBandpassFilter.reset();
+ }
+ if (m_pImagingContext) {
+ delete m_pImagingContext;
+ }
+}
+
+void TrackerThread::setConfig(TrackerConfig config, IntRect roi,
+ BitmapPtr ppBitmaps[NUM_TRACKER_IMAGES])
+{
+ lock_guard lock(*m_pMutex);
+ try {
+ m_TouchThreshold = config.getIntParam("/tracker/touch/threshold/@value");
+ } catch (Exception&) {
+ m_TouchThreshold = 0;
+ }
+ m_bTrackBrighter = config.getBoolParam("/tracker/brighterregions/@value");
+ try {
+ m_TrackThreshold = config.getIntParam("/tracker/track/threshold/@value");
+ } catch (Exception&) {
+ m_TrackThreshold = 0;
+ }
+ m_Prescale = config.getIntParam("/tracker/prescale/@value");
+ if(m_pHistoryPreProcessor) {
+ m_pHistoryPreProcessor->setInterval(config.getIntParam
+ ("/tracker/historyupdateinterval/@value"));
+ }
+ DeDistortPtr pDeDistort = config.getTransform();
+ if (!(*m_pTrafo == *pDeDistort)) {
+ m_pDistorter = FilterDistortionPtr(new FilterDistortion(
+ m_pBitmaps[TRACKER_IMG_CAMERA]->getSize()/m_Prescale, pDeDistort));
+ *m_pTrafo = *pDeDistort;
+ }
+ int brightness = config.getIntParam("/camera/brightness/@value");
+ int exposure = config.getIntParam("/camera/exposure/@value");
+ int gamma = config.getIntParam("/camera/gamma/@value");
+ int gain = config.getIntParam("/camera/gain/@value");
+ int shutter = config.getIntParam("/camera/shutter/@value");
+ int strobeDuration = config.getIntParam("/camera/strobeduration/@value");
+ string sCameraMaskFName = config.getParam("/tracker/mask/@value");
+ bool bNewCameraMask = ((m_pCameraMaskBmp == BitmapPtr() && sCameraMaskFName != "") ||
+ m_pConfig->getParam("/tracker/mask/@value") != sCameraMaskFName);
+ if (int(m_pCamera->getFeature(CAM_FEATURE_BRIGHTNESS)) != brightness ||
+ int(m_pCamera->getFeature(CAM_FEATURE_GAMMA)) != gamma ||
+ int(m_pCamera->getFeature(CAM_FEATURE_EXPOSURE)) != exposure ||
+ int(m_pCamera->getFeature(CAM_FEATURE_GAIN)) != gain ||
+ int(m_pCamera->getFeature(CAM_FEATURE_SHUTTER)) != shutter ||
+ int(m_pCamera->getFeature(CAM_FEATURE_STROBE_DURATION)) != strobeDuration ||
+ bNewCameraMask)
+ {
+ m_pHistoryPreProcessor->reset();
+ }
+
+ m_pCamera->setFeature(CAM_FEATURE_BRIGHTNESS, brightness);
+ m_pCamera->setFeature(CAM_FEATURE_GAMMA, gamma);
+// m_pCamera->setFeature(CAM_FEATURE_EXPOSURE, exposure);
+ m_pCamera->setFeature(CAM_FEATURE_GAIN, gain);
+ m_pCamera->setFeature(CAM_FEATURE_SHUTTER, shutter);
+ m_pCamera->setFeature(CAM_FEATURE_STROBE_DURATION, strobeDuration, true);
+
+ if (bNewCameraMask) {
+ if (sCameraMaskFName == "") {
+ m_pCameraMaskBmp = BitmapPtr();
+ } else {
+ BitmapPtr pRGBXCameraMaskBmp = loadBitmap(sCameraMaskFName, I8);
+ }
+ }
+ m_pConfig = TrackerConfigPtr(new TrackerConfig(config));
+
+ setBitmaps(roi, ppBitmaps);
+ createBandpassFilter();
+}
+
+void TrackerThread::setDebugImages(bool bImg, bool bFinger)
+{
+ m_bCreateDebugImages = bImg;
+ m_bCreateFingerImage = bFinger;
+}
+
+void TrackerThread::setBitmaps(IntRect roi, BitmapPtr ppBitmaps[NUM_TRACKER_IMAGES])
+{
+ m_ROI = roi;
+ for (int i=0; i<NUM_TRACKER_IMAGES; i++) {
+ m_pBitmaps[i] = ppBitmaps[i];
+ }
+ if (m_pHistoryPreProcessor) {
+ m_pHistoryPreProcessor = HistoryPreProcessorPtr(
+ new HistoryPreProcessor(roi.size(),
+ m_pHistoryPreProcessor->getInterval(), m_bTrackBrighter));
+ }
+ if (m_pBandpassFilter) {
+ createBandpassFilter();
+ }
+}
+
+void TrackerThread::createBandpassFilter()
+{
+ if (m_TouchThreshold != 0) {
+ float bandpassMin = m_pConfig->getFloatParam("/tracker/touch/bandpass/@min");
+ float bandpassMax = m_pConfig->getFloatParam("/tracker/touch/bandpass/@max");
+ float bandpassPostMult =
+ m_pConfig->getFloatParam("/tracker/touch/bandpasspostmult/@value");
+ if (m_pImagingContext) {
+ m_pBandpassFilter = FilterPtr(new GPUBandpassFilter(m_ROI.size(), I8,
+ bandpassMin, bandpassMax, bandpassPostMult, m_bTrackBrighter));
+ }
+ }
+}
+
+void TrackerThread::resetHistory()
+{
+ if (m_pHistoryPreProcessor) {
+ m_pHistoryPreProcessor->reset();
+ }
+}
+
+void TrackerThread::drawHistogram(BitmapPtr pDestBmp, BitmapPtr pSrcBmp)
+{
+ HistogramPtr pHist = pSrcBmp->getHistogram(4);
+ AVG_ASSERT(pDestBmp->getPixelFormat() == I8);
+ // Normalize Histogram to 0..255
+ int max1 = 0;
+ int max2 = 0;
+ for (int i = 0; i < 256; ++i) {
+ if ((*pHist)[i] > max1) {
+ max2 = max1;
+ max1 = (*pHist)[i];
+ } else if ((*pHist)[i] > max2) {
+ max2 = (*pHist)[i];
+ }
+ }
+ if (max2 == 0) {
+ max2= 1;
+ }
+ for (int i = 0; i < 256; ++i) {
+ (*pHist)[i] = int((*pHist)[i]*256.0/max2)+1;
+ }
+
+ FilterFill<Pixel8>(0).applyInPlace(pDestBmp);
+ int stride = pDestBmp->getStride();
+ int endRow = 256;
+ if (pDestBmp->getSize().y < 256) {
+ endRow = pDestBmp->getSize().y;
+ }
+ int width = pDestBmp->getSize().x;
+ for (int i = 0; i < endRow; ++i) {
+ int endCol =(*pHist)[i];
+ if (endCol > width) {
+ endCol = width;
+ }
+ unsigned char * pDest = pDestBmp->getPixels()+stride*i;
+ memset(pDest, 255, endCol);
+ }
+}
+
+inline bool isInbetween(float x, float min, float max)
+{
+ return x >= min && x <= max;
+}
+
+bool TrackerThread::isRelevant(BlobPtr pBlob, int minArea, int maxArea,
+ float minEccentricity, float maxEccentricity)
+{
+ bool res;
+ res = isInbetween(pBlob->getArea(), float(minArea), float(maxArea)) &&
+ isInbetween(pBlob->getEccentricity(), minEccentricity, maxEccentricity);
+ return res;
+}
+
+BlobVectorPtr TrackerThread::findRelevantBlobs(BlobVectorPtr pBlobs, bool bTouch)
+{
+ string sConfigPrefix;
+ if (bTouch) {
+ sConfigPrefix = "/tracker/touch/";
+ } else {
+ sConfigPrefix = "/tracker/track/";
+ }
+ int minArea = m_pConfig->getIntParam(sConfigPrefix+"areabounds/@min");
+ int maxArea = m_pConfig->getIntParam(sConfigPrefix+"areabounds/@max");
+ float minEccentricity = m_pConfig->getFloatParam(sConfigPrefix+
+ "eccentricitybounds/@min");
+ float maxEccentricity = m_pConfig->getFloatParam(sConfigPrefix+
+ "eccentricitybounds/@max");
+
+ BlobVectorPtr pRelevantBlobs(new BlobVector());
+ for(BlobVector::iterator it = pBlobs->begin(); it != pBlobs->end(); ++it) {
+ if (isRelevant(*it, minArea, maxArea, minEccentricity, maxEccentricity)) {
+ pRelevantBlobs->push_back(*it);
+ }
+ if (pRelevantBlobs->size() > 50) {
+ break;
+ }
+ }
+ return pRelevantBlobs;
+}
+
+void TrackerThread::drawBlobs(BlobVectorPtr pBlobs, BitmapPtr pSrcBmp,
+ BitmapPtr pDestBmp, int Offset, bool bTouch)
+{
+ if (!pDestBmp) {
+ return;
+ }
+ ScopeTimer timer(ProfilingZoneDraw);
+ string sConfigPrefix;
+ if (bTouch) {
+ sConfigPrefix = "/tracker/touch/";
+ } else {
+ sConfigPrefix = "/tracker/track/";
+ }
+ int minArea = m_pConfig->getIntParam(sConfigPrefix+"areabounds/@min");
+ int maxArea = m_pConfig->getIntParam(sConfigPrefix+"areabounds/@max");
+ float minEccentricity = m_pConfig->getFloatParam(
+ sConfigPrefix+"eccentricitybounds/@min");
+ float maxEccentricity = m_pConfig->getFloatParam(
+ sConfigPrefix+"eccentricitybounds/@max");
+
+ // Get max. pixel value in Bitmap
+ int max = 0;
+ HistogramPtr pHist = pSrcBmp->getHistogram(4);
+ int i;
+ for (i = 255; i >= 0; i--) {
+ if ((*pHist)[i] != 0) {
+ max = i;
+ i = 0;
+ }
+ }
+
+ for (BlobVector::iterator it2 = pBlobs->begin(); it2 != pBlobs->end(); ++it2) {
+ if (isRelevant(*it2, minArea, maxArea, minEccentricity, maxEccentricity)) {
+ if (bTouch) {
+ (*it2)->render(pSrcBmp, pDestBmp,
+ Pixel32(0xFF, 0xFF, 0xFF, 0xFF), Offset, max, bTouch, true,
+ Pixel32(0x00, 0x00, 0xFF, 0xFF));
+ } else {
+ (*it2)->render(pSrcBmp, pDestBmp,
+ Pixel32(0xFF, 0xFF, 0x00, 0x80), Offset, max, bTouch, true,
+ Pixel32(0x00, 0x00, 0xFF, 0xFF));
+ }
+ } else {
+ if (bTouch) {
+ (*it2)->render(pSrcBmp, pDestBmp,
+ Pixel32(0xFF, 0x00, 0x00, 0xFF), Offset, max, bTouch, false);
+ } else {
+ (*it2)->render(pSrcBmp, pDestBmp,
+ Pixel32(0x80, 0x80, 0x00, 0x80), Offset, max, bTouch, false);
+ }
+ }
+ }
+}
+
+void TrackerThread::calcContours(BlobVectorPtr pBlobs)
+{
+ ScopeTimer timer(ProfilingZoneDraw);
+ string sConfigPrefix;
+ sConfigPrefix = "/tracker/track/";
+ int minArea = m_pConfig->getIntParam(sConfigPrefix+"areabounds/@min");
+ int maxArea = m_pConfig->getIntParam(sConfigPrefix+"areabounds/@max");
+ float minEccentricity = m_pConfig->getFloatParam(
+ sConfigPrefix+"eccentricitybounds/@min");
+ float maxEccentricity = m_pConfig->getFloatParam(
+ sConfigPrefix+"eccentricitybounds/@max");
+
+ int ContourPrecision = m_pConfig->getIntParam("/tracker/contourprecision/@value");
+ if (ContourPrecision != 0) {
+ for (BlobVector::iterator it = pBlobs->begin(); it != pBlobs->end(); ++it) {
+ if (isRelevant(*it, minArea, maxArea, minEccentricity, maxEccentricity)) {
+ (*it)->calcContour(ContourPrecision);
+ }
+ }
+ }
+}
+
+void TrackerThread::correlateHands(BlobVectorPtr pTrackBlobs, BlobVectorPtr pTouchBlobs)
+{
+ if (!pTrackBlobs || !pTouchBlobs) {
+ return;
+ }
+ for (BlobVector::iterator it1 = pTouchBlobs->begin(); it1 != pTouchBlobs->end();
+ ++it1)
+ {
+ BlobPtr pTouchBlob = *it1;
+ IntPoint touchCenter = (IntPoint)(pTouchBlob->getCenter());
+ for (BlobVector::iterator it2 = pTrackBlobs->begin(); it2 != pTrackBlobs->end();
+ ++it2)
+ {
+ BlobPtr pTrackBlob = *it2;
+ if (pTrackBlob->contains(touchCenter)) {
+ pTouchBlob->addRelated(pTrackBlob);
+ pTrackBlob->addRelated(pTouchBlob);
+ break;
+ }
+ }
+ }
+}
+
+void TrackerThread::calcBlobs(BitmapPtr pTrackBmp, BitmapPtr pTouchBmp, long long time)
+{
+ BlobVectorPtr pTrackComps;
+ BlobVectorPtr pTouchComps;
+ {
+ ScopeTimer timer(ProfilingZoneComps);
+ lock_guard lock(*m_pMutex);
+ BitmapPtr pDestBmp;
+ if (m_bCreateFingerImage) {
+ Pixel32 Black(0x00, 0x00, 0x00, 0x00);
+ FilterFill<Pixel32>(Black).applyInPlace(
+ m_pBitmaps[TRACKER_IMG_FINGERS]);
+ pDestBmp = m_pBitmaps[TRACKER_IMG_FINGERS];
+ }
+ {
+ if (m_TrackThreshold != 0) {
+ pTrackComps = findConnectedComponents(pTrackBmp, m_TrackThreshold);
+ calcContours(pTrackComps);
+ drawBlobs(pTrackComps, pTrackBmp, pDestBmp, m_TrackThreshold, false);
+ pTrackComps = findRelevantBlobs(pTrackComps, false);
+ }
+ if (m_TouchThreshold != 0) {
+ pTouchComps = findConnectedComponents(pTouchBmp, m_TouchThreshold);
+ pTouchComps = findRelevantBlobs(pTouchComps, true);
+ correlateHands(pTrackComps, pTouchComps);
+ drawBlobs(pTouchComps, pTouchBmp, pDestBmp, m_TouchThreshold, true);
+ }
+ }
+ // Send the blobs to the BlobTarget.
+ {
+ ScopeTimer timer(ProfilingZoneUpdate);
+ m_pTarget->update(pTrackComps, pTouchComps, time);
+ }
+ }
+
+}
+
+}
diff --git a/src/imaging/TrackerThread.h b/src/imaging/TrackerThread.h
new file mode 100644
index 0000000..27d91ff
--- /dev/null
+++ b/src/imaging/TrackerThread.h
@@ -0,0 +1,135 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+
+#ifndef _TrackerThread_H_
+#define _TrackerThread_H_
+
+#include "../api.h"
+#include "TrackerConfig.h"
+#include "Camera.h"
+#include "Blob.h"
+#include "FilterDistortion.h"
+#include "DeDistort.h"
+
+#include "../base/WorkerThread.h"
+#include "../base/Command.h"
+
+#include "../graphics/HistoryPreProcessor.h"
+#include "../graphics/Bitmap.h"
+#include "../graphics/Pixel8.h"
+#include "../graphics/Filter.h"
+
+#include <boost/thread.hpp>
+
+#include <string>
+#include <list>
+
+namespace avg {
+
+typedef enum {
+ TRACKER_IMG_CAMERA,
+ TRACKER_IMG_DISTORTED,
+ TRACKER_IMG_NOHISTORY,
+ TRACKER_IMG_HISTOGRAM,
+ TRACKER_IMG_HIGHPASS,
+ TRACKER_IMG_FINGERS,
+ NUM_TRACKER_IMAGES
+} TrackerImageID;
+
+typedef boost::shared_ptr<boost::mutex> MutexPtr;
+class GLContext;
+
+class AVG_API IBlobTarget {
+ public:
+ virtual ~IBlobTarget() {};
+ // Note that this function is called by TrackerThread in it's own thread!
+ virtual void update(BlobVectorPtr pTrackBlobs, BlobVectorPtr pTouchBlobs,
+ long long time) = 0;
+};
+
+
+class AVG_API TrackerThread: public WorkerThread<TrackerThread>
+{
+ public:
+ TrackerThread(IntRect roi, CameraPtr pCamera,
+ BitmapPtr ppBitmaps[NUM_TRACKER_IMAGES], MutexPtr pMutex, CQueue& cmdQ,
+ IBlobTarget* pTarget, bool bSubtractHistory, TrackerConfig& config);
+ virtual ~TrackerThread();
+
+ bool init();
+ bool work();
+ void deinit();
+
+ void setConfig(TrackerConfig config, IntRect roi,
+ BitmapPtr ppBitmaps[NUM_TRACKER_IMAGES]);
+ void setDebugImages(bool bImg, bool bFinger);
+ void resetHistory();
+
+ private:
+ void setBitmaps(IntRect roi, BitmapPtr ppBitmaps[NUM_TRACKER_IMAGES]);
+ void createBandpassFilter();
+ void checkMessages();
+ void calcHistory();
+ void drawHistogram(BitmapPtr pDestBmp, BitmapPtr pSrcBmp);
+ void calcBlobs(BitmapPtr pTrackBmp, BitmapPtr pTouchBmp, long long time);
+ bool isRelevant(BlobPtr pBlob, int minArea, int maxArea,
+ float minEccentricity, float maxEccentricity);
+ BlobVectorPtr findRelevantBlobs(BlobVectorPtr pBlobs, bool bTouch);
+ void drawBlobs(BlobVectorPtr pBlobs, BitmapPtr pSrcBmp, BitmapPtr pDestBmp,
+ int Offset, bool bTouch);
+ void calcContours(BlobVectorPtr pBlobs);
+ void correlateHands(BlobVectorPtr pTrackBlobs, BlobVectorPtr pTouchBlobs);
+
+ std::string m_sDevice;
+ std::string m_sMode;
+
+ TrackerConfigPtr m_pConfig;
+ BitmapPtr m_pCameraMaskBmp;
+
+ int m_TouchThreshold; // 0 => no touch events.
+ int m_TrackThreshold; // 0 => no generic tracking events.
+ int m_Prescale;
+ long long m_HistoryDelay;
+ long long m_StartTime;
+ bool m_bTrackBrighter;
+
+ BlobVectorPtr m_pBlobVector;
+ IntRect m_ROI;
+ BitmapPtr m_pBitmaps[NUM_TRACKER_IMAGES];
+ MutexPtr m_pMutex;
+
+ CameraPtr m_pCamera;
+ IBlobTarget *m_pTarget;
+ HistoryPreProcessorPtr m_pHistoryPreProcessor;
+ FilterDistortionPtr m_pDistorter;
+ DeDistortPtr m_pTrafo;
+ bool m_bCreateDebugImages;
+ bool m_bCreateFingerImage;
+ int m_NumFrames;
+ int m_NumCamFramesDiscarded;
+
+ GLContext* m_pImagingContext;
+ FilterPtr m_pBandpassFilter;
+};
+
+}
+
+#endif
+
diff --git a/src/imaging/V4LCamera.cpp b/src/imaging/V4LCamera.cpp
new file mode 100644
index 0000000..85d7d41
--- /dev/null
+++ b/src/imaging/V4LCamera.cpp
@@ -0,0 +1,713 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+// V4L2/libavg compliance by 02L > Outside Standing Level
+
+#include "V4LCamera.h"
+
+#include "../base/ScopeTimer.h"
+#include "../base/TimeSource.h"
+#include "../base/Logger.h"
+#include "../base/Exception.h"
+#include "../base/StringHelper.h"
+#include "../base/GLMHelper.h"
+
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#include <linux/videodev2.h>
+
+#include <stdio.h>
+#include <sys/time.h>
+#include <unistd.h>
+#include <iostream>
+#include <cstring>
+
+#define CLEAR(x) memset (&(x), 0, sizeof (x))
+
+using namespace avg;
+using namespace std;
+
+// anonymous namespace holding private (C-static-like) functions
+namespace {
+ int xioctl(int fd, int request, void * arg)
+ {
+ int rc;
+
+ do {
+ rc = ioctl(fd, request, arg);
+ } while (rc == -1 && EINTR == errno);
+
+ return rc;
+ }
+}
+
+namespace avg {
+
+V4LCamera::V4LCamera(string sDevice, int channel, IntPoint size, PixelFormat camPF,
+ PixelFormat destPF, float frameRate)
+ : Camera(camPF, destPF, size, frameRate),
+ m_Fd(-1),
+ m_Channel(channel),
+ m_sDevice(sDevice)
+{
+ m_v4lPF = getV4LPF(camPF);
+ if (m_sDevice == "") {
+ m_sDevice = "/dev/video0";
+ }
+ if (m_Channel == -1) {
+ m_Channel = 0;
+ }
+
+ m_FeaturesNames[V4L2_CID_BRIGHTNESS] = "brightness";
+ m_FeaturesNames[V4L2_CID_CONTRAST] = "contrast";
+ m_FeaturesNames[V4L2_CID_GAIN] = "gain";
+ m_FeaturesNames[V4L2_CID_EXPOSURE] = "exposure";
+ m_FeaturesNames[V4L2_CID_WHITENESS] = "whiteness";
+ m_FeaturesNames[V4L2_CID_GAMMA] = "gamma";
+ m_FeaturesNames[V4L2_CID_SATURATION] = "saturation";
+
+ struct stat st;
+ if (stat(m_sDevice.c_str(), &st) == -1) {
+ AVG_ASSERT_MSG(false, (string("Unable to access v4l2 device '" +
+ m_sDevice + "'.").c_str()));
+ }
+
+ if (!S_ISCHR (st.st_mode)) {
+ AVG_ASSERT_MSG(false, (string("'" + m_sDevice +
+ " is not a v4l2 device.").c_str()));
+ }
+
+ m_Fd = ::open(m_sDevice.c_str(), O_RDWR /* required */ | O_NONBLOCK, 0);
+
+ if (m_Fd == -1) {
+ AVG_ASSERT_MSG(false, (string("Unable to open v4l2 device '" + m_sDevice
+ + "'.").c_str()));
+ }
+
+ initDevice();
+ AVG_TRACE(Logger::category::CONFIG, Logger::severity::INFO, "V4L2 Camera opened");
+}
+
+V4LCamera::~V4LCamera()
+{
+ close();
+}
+
+void V4LCamera::close()
+{
+ enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ int rc = xioctl(m_Fd, VIDIOC_STREAMOFF, &type);
+ if (rc == -1) {
+ AVG_LOG_ERROR("VIDIOC_STREAMOFF");
+ }
+ vector<Buffer>::iterator it;
+ for (it = m_vBuffers.begin(); it != m_vBuffers.end(); ++it) {
+ int err = munmap(it->start, it->length);
+ AVG_ASSERT (err != -1);
+ }
+ m_vBuffers.clear();
+
+ ::close(m_Fd);
+ AVG_TRACE(Logger::category::CONFIG, Logger::severity::INFO, "V4L2 Camera closed");
+
+ m_Fd = -1;
+}
+
+int V4LCamera::getV4LPF(PixelFormat pf)
+{
+ switch (pf) {
+ case I8:
+ return V4L2_PIX_FMT_GREY;
+ case BAYER8:
+ case BAYER8_BGGR:
+ case BAYER8_GBRG:
+ case BAYER8_GRBG:
+ case BAYER8_RGGB:
+ return V4L2_PIX_FMT_GREY;
+ case YCbCr411:
+ return V4L2_PIX_FMT_Y41P;
+ case YCbCr422:
+ return V4L2_PIX_FMT_UYVY;
+ case YUYV422:
+ return V4L2_PIX_FMT_YUYV;
+ case YCbCr420p:
+ return V4L2_PIX_FMT_YUV420;
+ case R8G8B8:
+ return V4L2_PIX_FMT_BGR24;
+ default:
+ throw Exception(AVG_ERR_INVALID_ARGS,
+ "Unsupported or illegal value for camera pixel format '"
+ + getPixelFormatString(pf) + "'.");
+ }
+}
+
+BitmapPtr V4LCamera::getImage(bool bWait)
+{
+ struct v4l2_buffer buf;
+ CLEAR(buf);
+
+ // wait for incoming data blocking, timeout 2s
+ if (bWait) {
+ fd_set fds;
+ struct timeval tv;
+ int rc;
+
+ FD_ZERO(&fds);
+ FD_SET(m_Fd, &fds);
+
+ /* Timeout. */
+ tv.tv_sec = 2;
+ tv.tv_usec = 0;
+
+ rc = select (m_Fd+1, &fds, NULL, NULL, &tv);
+
+ // caught signal or something else
+ if (rc == -1) {
+ AVG_LOG_WARNING("V4L2: select failed.");
+ return BitmapPtr();
+ }
+ // timeout
+ if (rc == 0) {
+ AVG_LOG_WARNING("V4L2: Timeout while waiting for image data");
+ return BitmapPtr();
+ }
+ }
+
+ buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ buf.memory = V4L2_MEMORY_MMAP;
+
+ // dequeue filled buffer
+ if (xioctl (m_Fd, VIDIOC_DQBUF, &buf) == -1) {
+ if (errno == EAGAIN) {
+ return BitmapPtr();
+ } else {
+ cerr << strerror(errno) << endl;
+ AVG_ASSERT(false);
+ }
+ }
+
+ unsigned char * pCaptureBuffer = (unsigned char*)m_vBuffers[buf.index].start;
+
+ float lineLen;
+ switch (getCamPF()) {
+ case YCbCr411:
+ lineLen = getImgSize().x*1.5f;
+ break;
+ case YCbCr420p:
+ lineLen = getImgSize().x;
+ break;
+ default:
+ lineLen = getImgSize().x*getBytesPerPixel(getCamPF());
+ }
+ BitmapPtr pCamBmp(new Bitmap(getImgSize(), getCamPF(), pCaptureBuffer, lineLen,
+ false, "TempCameraBmp"));
+
+ BitmapPtr pDestBmp = convertCamFrameToDestPF(pCamBmp);
+
+ // enqueues free buffer for mmap
+ if (-1 == xioctl (m_Fd, VIDIOC_QBUF, &buf)) {
+ AVG_ASSERT_MSG(false, "V4L Camera: failed to enqueue image buffer.");
+ }
+
+ return pDestBmp;
+}
+
+bool V4LCamera::isCameraAvailable()
+{
+ return m_bCameraAvailable;
+}
+
+const string& V4LCamera::getDevice() const
+{
+ return m_sDevice;
+}
+
+const string& V4LCamera::getDriverName() const
+{
+ return m_sDriverName;
+}
+
+string V4LCamera::getFeatureName(V4LCID_t v4lFeature)
+{
+ string sName = m_FeaturesNames[v4lFeature];
+ if (sName == "") {
+ sName = "UNKNOWN";
+ }
+
+ return sName;
+}
+
+V4LCID_t V4LCamera::getFeatureID(CameraFeature feature) const
+{
+ V4LCID_t v4lFeature;
+ if (feature == CAM_FEATURE_BRIGHTNESS) {
+ v4lFeature = V4L2_CID_BRIGHTNESS;
+ } else if (feature == CAM_FEATURE_CONTRAST) {
+ v4lFeature = V4L2_CID_CONTRAST;
+ } else if (feature == CAM_FEATURE_GAIN) {
+ v4lFeature = V4L2_CID_GAIN;
+ } else if (feature == CAM_FEATURE_EXPOSURE) {
+ v4lFeature = V4L2_CID_EXPOSURE;
+ } else if (feature == CAM_FEATURE_GAMMA) {
+ v4lFeature = V4L2_CID_GAMMA;
+ } else if (feature == CAM_FEATURE_SATURATION) {
+ v4lFeature = V4L2_CID_SATURATION;
+ } else {
+ AVG_LOG_WARNING("feature " << cameraFeatureToString(feature)
+ << " not supported for V4L2.");
+ return -1;
+ }
+
+ return v4lFeature;
+}
+
+bool V4LCamera::isFeatureSupported(V4LCID_t v4lFeature) const
+{
+ struct v4l2_queryctrl queryCtrl;
+
+ CLEAR(queryCtrl);
+ queryCtrl.id = v4lFeature;
+
+ if (ioctl (m_Fd, VIDIOC_QUERYCTRL, &queryCtrl) == -1) {
+ if (errno != EINVAL) {
+ cerr << "Got " << strerror(errno) << endl;
+ AVG_ASSERT(false);
+ return false;
+ } else {
+ return false;
+ }
+ } else if (queryCtrl.flags & V4L2_CTRL_FLAG_DISABLED) {
+ return false;
+ } else {
+ return true;
+ }
+}
+
+int V4LCamera::getFeature(CameraFeature feature) const
+{
+ V4LCID_t v4lFeature = getFeatureID(feature);
+
+ FeatureMap::const_iterator it = m_Features.find(v4lFeature);
+
+ if (it == m_Features.end()) {
+ return 0;
+ } else {
+ return it->second;
+ }
+}
+
+void V4LCamera::setFeature(V4LCID_t v4lFeature, int value)
+{
+ if (!m_bCameraAvailable) {
+ AVG_LOG_WARNING("setFeature() called before opening device: ignored");
+ return;
+ }
+
+ if (!isFeatureSupported(v4lFeature)) {
+ AVG_LOG_WARNING("Camera feature " << getFeatureName(v4lFeature) <<
+ " is not supported by hardware");
+ return;
+ }
+
+ struct v4l2_control control;
+
+ CLEAR(control);
+ control.id = v4lFeature;
+ control.value = value;
+
+// AVG_TRACE(Logger::category::APP, "Setting feature " << getFeatureName(v4lFeature) <<
+// " to "<< value);
+
+ if (ioctl(m_Fd, VIDIOC_S_CTRL, &control) == -1) {
+ AVG_LOG_ERROR("Cannot set feature " << m_FeaturesNames[v4lFeature]);
+ }
+}
+
+void V4LCamera::setFeatureOneShot(CameraFeature feature)
+{
+ AVG_LOG_WARNING("setFeatureOneShot is not supported by V4L cameras.");
+}
+
+int V4LCamera::getWhitebalanceU() const
+{
+ AVG_LOG_WARNING("getWhitebalance is not supported by V4L cameras.");
+ return 0;
+}
+
+int V4LCamera::getWhitebalanceV() const
+{
+ AVG_LOG_WARNING("getWhitebalance is not supported by V4L cameras.");
+ return 0;
+}
+
+void V4LCamera::setWhitebalance(int u, int v, bool bIgnoreOldValue)
+{
+ setFeature(V4L2_CID_RED_BALANCE, u);
+ setFeature(V4L2_CID_BLUE_BALANCE, v);
+}
+
+int V4LCamera::checkCamera(int j)
+{
+ stringstream minorDeviceNumber;
+ minorDeviceNumber << j;
+ string address = "/dev/video";
+ string result = address + minorDeviceNumber.str();
+ int fd = ::open(result.c_str(), O_RDWR /* required */ | O_NONBLOCK, 0);
+ return fd;
+}
+
+v4l2_capability getCamCapabilities(int fd)
+{
+ v4l2_capability capability;
+ memset(&capability, 0, sizeof(capability));
+ ioctl(fd, VIDIOC_QUERYCAP, &capability);
+ return capability;
+}
+
+PixelFormat V4LCamera::intToPixelFormat(unsigned int pixelformat)
+{
+ switch (pixelformat) {
+ case v4l2_fourcc('Y','U','Y','V'):
+ return YUYV422;
+ case v4l2_fourcc('U','Y','V','Y'):
+ return YCbCr422;
+ case v4l2_fourcc('G','R','E','Y'):
+ return I8;
+ case v4l2_fourcc('Y','1','6',' '):
+ return I16;
+ case v4l2_fourcc('R','G','B','3'):
+ return R8G8B8;
+ case v4l2_fourcc('B','G','R','3'):
+ return B8G8R8;
+ default:
+ return NO_PIXELFORMAT;
+ }
+}
+
+int V4LCamera::countCameras()
+{
+ int numberOfCameras = 0;
+ for (int j = 0; j < 256; j++) {
+ int fd = checkCamera(j);
+ if (fd != -1) {
+ numberOfCameras++;
+ }
+ }
+ return numberOfCameras;
+}
+
+CameraInfo* V4LCamera::getCameraInfos(int deviceNumber)
+{
+ int fd = checkCamera(deviceNumber);
+ if (fd == -1) {
+ AVG_ASSERT(false);
+ return NULL;
+ }
+ stringstream ss;
+ ss << "/dev/video" << deviceNumber;
+ CameraInfo* camInfo = new CameraInfo("video4linux", ss.str());
+ v4l2_capability capability = getCamCapabilities(fd);
+ if (capability.capabilities & V4L2_CAP_VIDEO_CAPTURE) {
+ getCameraImageFormats(fd, camInfo);
+ getCameraControls(fd, camInfo);
+ }
+ return camInfo;
+}
+
+void V4LCamera::getCameraImageFormats(int fd, CameraInfo* camInfo)
+{
+ for (int i = 0;; i++) {
+// cerr << i << endl;
+ v4l2_fmtdesc fmtDesc;
+ memset(&fmtDesc, 0, sizeof(fmtDesc));
+ fmtDesc.index = i;
+ fmtDesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ int rc = ioctl(fd, VIDIOC_ENUM_FMT, &fmtDesc);
+ if (rc == -1) {
+ break;
+ }
+ v4l2_frmsizeenum frmSizeEnum;
+ memset(&frmSizeEnum, 0, sizeof (frmSizeEnum));
+ frmSizeEnum.index = 0;
+ frmSizeEnum.pixel_format = fmtDesc.pixelformat;
+ while (ioctl(fd, VIDIOC_ENUM_FRAMESIZES, &frmSizeEnum) == 0) {
+/* fprintf(stdout, " pixelformat :%c%c%c%c\\n",
+ fmtDesc.pixelformat & 0xFF,
+ (fmtDesc.pixelformat >> 8) & 0xFF,
+ (fmtDesc.pixelformat >> 16) & 0xFF,
+ (fmtDesc.pixelformat >> 24) & 0xFF);
+*/
+ PixelFormat pixFormat = intToPixelFormat(fmtDesc.pixelformat);
+ if (pixFormat != NO_PIXELFORMAT) {
+ v4l2_frmivalenum frmIvalEnum;
+ memset (&frmIvalEnum, 0, sizeof (frmIvalEnum));
+ frmIvalEnum.index = 0;
+ frmIvalEnum.pixel_format = frmSizeEnum.pixel_format;
+ frmIvalEnum.width = frmSizeEnum.discrete.width;
+ frmIvalEnum.height = frmSizeEnum.discrete.height;
+ IntPoint size;
+ size.x = frmSizeEnum.discrete.width;
+ size.y = frmSizeEnum.discrete.height;
+ std::vector<float> framerates;
+ while (ioctl(fd, VIDIOC_ENUM_FRAMEINTERVALS, &frmIvalEnum) == 0) {
+ framerates.push_back(frmIvalEnum.discrete.denominator);
+ frmIvalEnum.index++;
+ }
+ CameraImageFormat camImFormat = CameraImageFormat(size, pixFormat,
+ framerates);
+ camInfo->addImageFormat(camImFormat);
+ }
+ frmSizeEnum.index++;
+ }
+ }
+}
+
+void V4LCamera::getCameraControls(int fd, CameraInfo* camInfo)
+{
+ v4l2_queryctrl queryCtrl;
+ for (queryCtrl.id = V4L2_CID_BASE; queryCtrl.id < V4L2_CID_LASTP1; queryCtrl.id++) {
+ int rc = ioctl (fd, VIDIOC_QUERYCTRL, &queryCtrl);
+ if (rc == -1) {
+ continue;
+ }
+ if (queryCtrl.flags & V4L2_CTRL_FLAG_DISABLED) {
+ continue;
+ }
+ stringstream ss;
+ ss << queryCtrl.name;
+ std::string sControlName = ss.str();
+ int min = queryCtrl.minimum;
+ int max = queryCtrl.maximum;
+ int defaultValue = queryCtrl.default_value;
+ CameraControl camControl = CameraControl(sControlName, min, max, defaultValue);
+ camInfo->addControl(camControl);
+ }
+}
+
+void V4LCamera::setFeature(CameraFeature feature, int value, bool bIgnoreOldValue)
+{
+ // ignore -1 coming from default unbiased cameranode parameters
+ if (value < 0) {
+ return;
+ }
+
+ V4LCID_t v4lFeature = getFeatureID(feature);
+ m_Features[v4lFeature] = value;
+
+ if (m_bCameraAvailable) {
+ setFeature(v4lFeature, value);
+ }
+}
+
+void V4LCamera::startCapture()
+{
+// AVG_TRACE(Logger::category::APP, "Entering startCapture()...");
+
+ unsigned int i;
+ enum v4l2_buf_type type;
+
+ for (i = 0; i < m_vBuffers.size(); ++i) {
+ struct v4l2_buffer buf;
+
+ CLEAR(buf);
+
+ buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ buf.memory = V4L2_MEMORY_MMAP;
+ buf.index = i;
+
+ int err = xioctl(m_Fd, VIDIOC_QBUF, &buf);
+ AVG_ASSERT(err != -1);
+ }
+
+ type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ int err= xioctl (m_Fd, VIDIOC_STREAMON, &type);
+ AVG_ASSERT(err != -1);
+}
+
+void V4LCamera::initDevice()
+{
+// AVG_TRACE(Logger::category::APP, "Entering initDevice()...");
+
+ struct v4l2_capability cap;
+ struct v4l2_cropcap CropCap;
+ struct v4l2_crop Crop;
+ struct v4l2_format fmt;
+ struct v4l2_streamparm StreamParam;
+
+ if (xioctl(m_Fd, VIDIOC_QUERYCAP, &cap) == -1) {
+ close();
+ AVG_ASSERT_MSG(false, (m_sDevice + " is not a valid V4L2 device.").c_str());
+ }
+
+ if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {
+ close();
+ AVG_ASSERT_MSG(false, (m_sDevice + " does not support capturing").c_str());
+ }
+
+ if (!(cap.capabilities & V4L2_CAP_STREAMING)) {
+ close();
+ AVG_ASSERT_MSG(false, (m_sDevice + " does not support streaming i/os").c_str());
+ }
+ m_sDriverName = (const char *)cap.driver;
+
+ /* Select video input, video standard and tune here. */
+ CLEAR(CropCap);
+ CropCap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+ if (xioctl(m_Fd, VIDIOC_CROPCAP, &CropCap) == 0) {
+ Crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ Crop.c = CropCap.defrect; /* reset to default */
+
+ if (-1 == xioctl(m_Fd, VIDIOC_S_CROP, &Crop)) {
+ switch (errno) {
+ case EINVAL:
+ /* Cropping not supported. */
+ break;
+ default:
+ /* Errors ignored. */
+ break;
+ }
+ }
+ } else {
+ /* Errors ignored. */
+ }
+
+ CLEAR(fmt);
+
+ fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ fmt.fmt.pix.width = getImgSize().x;
+ fmt.fmt.pix.height = getImgSize().y;
+ fmt.fmt.pix.pixelformat = m_v4lPF;
+ fmt.fmt.pix.field = V4L2_FIELD_ANY;
+ int rc = xioctl(m_Fd, VIDIOC_S_FMT, &fmt);
+ if (int(fmt.fmt.pix.width) != getImgSize().x ||
+ int(fmt.fmt.pix.height) != getImgSize().y || rc == -1)
+ {
+ throw(Exception(AVG_ERR_CAMERA_NONFATAL,
+ string("Unable to set V4L camera image format: '")
+ +strerror(errno)
+ +"'. Try using avg_showcamera.py --list to find out what the device supports."));
+ }
+
+ CLEAR(StreamParam);
+ StreamParam.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ rc = xioctl(m_Fd, VIDIOC_G_PARM, &StreamParam);
+
+ if(StreamParam.parm.capture.capability == V4L2_CAP_TIMEPERFRAME) {
+ CLEAR(StreamParam);
+
+ StreamParam.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ StreamParam.parm.capture.timeperframe.numerator = 1;
+ StreamParam.parm.capture.timeperframe.denominator = (int)getFrameRate();
+ rc = xioctl(m_Fd, VIDIOC_S_PARM, &StreamParam);
+ if (getFrameRate() != StreamParam.parm.capture.timeperframe.denominator ||
+ rc == -1)
+ {
+ throw(Exception(AVG_ERR_CAMERA_NONFATAL,
+ string("Unable to set V4L camera framerate: '")
+ +strerror(errno)
+ +"'. Try using avg_showcamera.py --list to find out what the device supports."));
+ }
+ }
+
+ initMMap();
+
+ // TODO: string channel instead of numeric
+ // select channel
+ if (xioctl(m_Fd, VIDIOC_S_INPUT, &m_Channel) == -1) {
+ close();
+ AVG_ASSERT_MSG(false, (string("Cannot set MUX channel " +
+ toString(m_Channel))).c_str());
+ }
+
+ m_bCameraAvailable = true;
+
+ for (FeatureMap::iterator it=m_Features.begin(); it != m_Features.end(); it++) {
+ setFeature(it->first, it->second);
+ }
+
+
+}
+
+void V4LCamera::initMMap()
+{
+ struct v4l2_requestbuffers req;
+ CLEAR(req);
+
+ req.count = 4;
+ req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ req.memory = V4L2_MEMORY_MMAP;
+
+ if (xioctl(m_Fd, VIDIOC_REQBUFS, &req) == -1) {
+ if (EINVAL == errno) {
+ close();
+ AVG_ASSERT_MSG(false, (m_sDevice +
+ " does not support memory mapping").c_str());
+ } else {
+ cerr << "errno: " << strerror(errno);
+ AVG_ASSERT(false);
+ }
+ }
+
+ if (req.count < 2) {
+ cerr << "Insufficient buffer memory on " << m_sDevice;
+ AVG_ASSERT(false);
+ }
+
+ m_vBuffers.clear();
+
+ for (int i = 0; i < int(req.count); ++i) {
+ Buffer tmp;
+ struct v4l2_buffer buf;
+
+ CLEAR (buf);
+
+ buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ buf.memory = V4L2_MEMORY_MMAP;
+ buf.index = i;
+
+ if (xioctl(m_Fd, VIDIOC_QUERYBUF, &buf) == -1) {
+ AVG_ASSERT(false);
+ }
+
+ tmp.length = buf.length;
+
+ tmp.start = mmap (NULL /* start anywhere */,
+ buf.length,
+ PROT_READ | PROT_WRITE /* required */,
+ MAP_SHARED /* recommended */,
+ m_Fd, buf.m.offset);
+
+ if (MAP_FAILED == tmp.start) {
+ AVG_ASSERT(false);
+ }
+
+ m_vBuffers.push_back(tmp);
+ }
+}
+}
+
+
+
diff --git a/src/imaging/V4LCamera.h b/src/imaging/V4LCamera.h
new file mode 100644
index 0000000..b779e8e
--- /dev/null
+++ b/src/imaging/V4LCamera.h
@@ -0,0 +1,100 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _V4LCamera_H_
+#define _V4LCamera_H_
+
+#include "../api.h"
+#include "../avgconfigwrapper.h"
+
+#include "Camera.h"
+#include <string>
+#include <vector>
+
+namespace avg {
+
+typedef unsigned int V4LCID_t;
+
+class AVG_API V4LCamera: public Camera {
+
+ struct Buffer {
+ void * start;
+ size_t length;
+ };
+
+public:
+ V4LCamera(std::string sDevice, int channel, IntPoint size, PixelFormat camPF,
+ PixelFormat destPF, float frameRate);
+ virtual ~V4LCamera();
+
+ virtual BitmapPtr getImage(bool bWait);
+ virtual bool isCameraAvailable();
+
+ virtual const std::string& getDevice() const;
+ virtual const std::string& getDriverName() const;
+
+ virtual int getFeature(CameraFeature feature) const;
+ virtual void setFeature(CameraFeature feature, int value,
+ bool bIgnoreOldValue=false);
+ virtual void setFeatureOneShot(CameraFeature feature);
+ virtual int getWhitebalanceU() const;
+ virtual int getWhitebalanceV() const;
+ virtual void setWhitebalance(int u, int v, bool bIgnoreOldValue=false);
+
+ static CameraInfo* getCameraInfos(int deviceNumber);
+ static int countCameras();
+
+private:
+ void initDevice();
+ void startCapture();
+ void initMMap();
+ virtual void close();
+
+ int getV4LPF(PixelFormat pf);
+ static int checkCamera(int j);
+ static PixelFormat intToPixelFormat(unsigned int pixelformat);
+
+ static void getCameraImageFormats(int fd, CameraInfo* camInfo);
+ static void getCameraControls(int deviceNumber, CameraInfo* camInfo);
+
+ void setFeature(V4LCID_t v4lFeature, int value);
+ V4LCID_t getFeatureID(CameraFeature feature) const;
+ std::string getFeatureName(V4LCID_t v4lFeature);
+ bool isFeatureSupported(V4LCID_t v4lFeature) const;
+ typedef std::map<V4LCID_t, unsigned int> FeatureMap;
+ typedef std::map<int, std::string> FeatureNamesMap;
+ FeatureMap m_Features;
+ // TODO: Feature strings should really be handled by
+ // Camera::cameraFeatureToString
+ FeatureNamesMap m_FeaturesNames;
+
+ int m_Fd;
+ int m_Channel;
+ std::string m_sDevice;
+ std::string m_sDriverName;
+ std::vector<Buffer> m_vBuffers;
+ bool m_bCameraAvailable;
+ int m_v4lPF;
+};
+
+}
+
+#endif
diff --git a/src/imaging/avgtrackerrc.minimal b/src/imaging/avgtrackerrc.minimal
new file mode 100644
index 0000000..f2bef02
--- /dev/null
+++ b/src/imaging/avgtrackerrc.minimal
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="utf-8"?>
+<trackerconfig>
+ <camera>
+ <driver value="firewire"/>
+ <device value=""/>
+ <fw800 value="false"/>
+ <format value="I8"/>
+ <size x="640" y="480"/>
+ <framerate value="60"/>
+ <brightness value="1"/>
+ <gamma value="0"/>
+ <exposure value="-1"/>
+ <gain value="16"/>
+ <shutter value="75"/>
+ <strobeduration value="-1"/>
+ </camera>
+ <tracker>
+ <prescale value="1"/>
+ <historyupdateinterval value="25"/>
+ <brighterregions value="true"/>
+ <contourprecision value="0"/>
+ <historydelay value="2200"/>
+ <mask value=""/>
+ <findfingertips value="true"/>
+ <track>
+ <threshold value="16"/>
+ <similarity value="100"/>
+ <areabounds min="700" max="1000000"/>
+ <eccentricitybounds min="1" max="80"/>
+ </track>
+ <touch>
+ <threshold value="148"/>
+ <similarity value="50"/>
+ <areabounds min="16" max="200000"/>
+ <eccentricitybounds min="1" max="800"/>
+ <bandpass min="1.6" max="2.4"/>
+ <bandpasspostmult value="30.0"/>
+ </touch>
+ </tracker>
+ <transform>
+ <distortionparams p2="0.697166" p3="0.0"/>
+ <trapezoid value="0.151537"/>
+ <angle value="0.00224421"/>
+ <displaydisplacement x="-174.966" y="-145.974"/>
+ <displayscale x="2.52439" y="2.55685"/>
+ <activedisplaysize x="1280" y="800"/>
+ <displayroi x1="0" y1="0" x2="1280" y2="800"/>
+ </transform>
+</trackerconfig>
diff --git a/src/imaging/baseline/FilterClearBorderResult1.png b/src/imaging/baseline/FilterClearBorderResult1.png
new file mode 100644
index 0000000..96d610a
--- /dev/null
+++ b/src/imaging/baseline/FilterClearBorderResult1.png
Binary files differ
diff --git a/src/imaging/baseline/FilterClearBorderResult3.png b/src/imaging/baseline/FilterClearBorderResult3.png
new file mode 100644
index 0000000..09943e3
--- /dev/null
+++ b/src/imaging/baseline/FilterClearBorderResult3.png
Binary files differ
diff --git a/src/imaging/baseline/FilterWipeBorderResult1.png b/src/imaging/baseline/FilterWipeBorderResult1.png
new file mode 100644
index 0000000..bf22671
--- /dev/null
+++ b/src/imaging/baseline/FilterWipeBorderResult1.png
Binary files differ
diff --git a/src/imaging/baseline/FilterWipeBorderResult3.png b/src/imaging/baseline/FilterWipeBorderResult3.png
new file mode 100644
index 0000000..4e8eb1d
--- /dev/null
+++ b/src/imaging/baseline/FilterWipeBorderResult3.png
Binary files differ
diff --git a/src/imaging/checktracking.cpp b/src/imaging/checktracking.cpp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/imaging/checktracking.cpp
diff --git a/src/imaging/qedit.h b/src/imaging/qedit.h
new file mode 100644
index 0000000..63d31ea
--- /dev/null
+++ b/src/imaging/qedit.h
@@ -0,0 +1,9914 @@
+
+#pragma warning( disable: 4049 ) /* more than 64k source lines */
+
+/* this ALWAYS GENERATED file contains the definitions for the interfaces */
+
+
+ /* File created by MIDL compiler version 6.00.0338 */
+/* Compiler settings for qedit.idl:
+ Oicf, W1, Zp8, env=Win32 (32b run)
+ protocol : dce , ms_ext, c_ext
+ error checks: allocation ref bounds_check enum stub_data
+ VC __declspec() decoration level:
+ __declspec(uuid()), __declspec(selectany), __declspec(novtable)
+ DECLSPEC_UUID(), MIDL_INTERFACE()
+*/
+//@@MIDL_FILE_HEADING( )
+
+#define __IDxtCompositor_INTERFACE_DEFINED__
+#define __IDxtAlphaSetter_INTERFACE_DEFINED__
+#define __IDxtJpeg_INTERFACE_DEFINED__
+#define __IDxtKey_INTERFACE_DEFINED__
+
+/* verify that the <rpcndr.h> version is high enough to compile this file*/
+#ifndef __REQUIRED_RPCNDR_H_VERSION__
+#define __REQUIRED_RPCNDR_H_VERSION__ 440
+#endif
+
+#include "rpc.h"
+#include "rpcndr.h"
+
+#ifndef __RPCNDR_H_VERSION__
+#error this stub requires an updated version of <rpcndr.h>
+#endif // __RPCNDR_H_VERSION__
+
+#ifndef COM_NO_WINDOWS_H
+#include "windows.h"
+#include "ole2.h"
+#endif /*COM_NO_WINDOWS_H*/
+
+#ifndef __qedit_h__
+#define __qedit_h__
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once
+#endif
+
+/* Forward Declarations */
+
+#ifndef __IPropertySetter_FWD_DEFINED__
+#define __IPropertySetter_FWD_DEFINED__
+typedef interface IPropertySetter IPropertySetter;
+#endif /* __IPropertySetter_FWD_DEFINED__ */
+
+
+#ifndef __IDxtCompositor_FWD_DEFINED__
+#define __IDxtCompositor_FWD_DEFINED__
+typedef interface IDxtCompositor IDxtCompositor;
+#endif /* __IDxtCompositor_FWD_DEFINED__ */
+
+
+#ifndef __IDxtAlphaSetter_FWD_DEFINED__
+#define __IDxtAlphaSetter_FWD_DEFINED__
+typedef interface IDxtAlphaSetter IDxtAlphaSetter;
+#endif /* __IDxtAlphaSetter_FWD_DEFINED__ */
+
+
+#ifndef __IDxtJpeg_FWD_DEFINED__
+#define __IDxtJpeg_FWD_DEFINED__
+typedef interface IDxtJpeg IDxtJpeg;
+#endif /* __IDxtJpeg_FWD_DEFINED__ */
+
+
+#ifndef __IDxtKey_FWD_DEFINED__
+#define __IDxtKey_FWD_DEFINED__
+typedef interface IDxtKey IDxtKey;
+#endif /* __IDxtKey_FWD_DEFINED__ */
+
+
+#ifndef __IMediaLocator_FWD_DEFINED__
+#define __IMediaLocator_FWD_DEFINED__
+typedef interface IMediaLocator IMediaLocator;
+#endif /* __IMediaLocator_FWD_DEFINED__ */
+
+
+#ifndef __IMediaDet_FWD_DEFINED__
+#define __IMediaDet_FWD_DEFINED__
+typedef interface IMediaDet IMediaDet;
+#endif /* __IMediaDet_FWD_DEFINED__ */
+
+
+#ifndef __IGrfCache_FWD_DEFINED__
+#define __IGrfCache_FWD_DEFINED__
+typedef interface IGrfCache IGrfCache;
+#endif /* __IGrfCache_FWD_DEFINED__ */
+
+
+#ifndef __IRenderEngine_FWD_DEFINED__
+#define __IRenderEngine_FWD_DEFINED__
+typedef interface IRenderEngine IRenderEngine;
+#endif /* __IRenderEngine_FWD_DEFINED__ */
+
+
+#ifndef __IFindCompressorCB_FWD_DEFINED__
+#define __IFindCompressorCB_FWD_DEFINED__
+typedef interface IFindCompressorCB IFindCompressorCB;
+#endif /* __IFindCompressorCB_FWD_DEFINED__ */
+
+
+#ifndef __ISmartRenderEngine_FWD_DEFINED__
+#define __ISmartRenderEngine_FWD_DEFINED__
+typedef interface ISmartRenderEngine ISmartRenderEngine;
+#endif /* __ISmartRenderEngine_FWD_DEFINED__ */
+
+
+#ifndef __IAMTimelineObj_FWD_DEFINED__
+#define __IAMTimelineObj_FWD_DEFINED__
+typedef interface IAMTimelineObj IAMTimelineObj;
+#endif /* __IAMTimelineObj_FWD_DEFINED__ */
+
+
+#ifndef __IAMTimelineEffectable_FWD_DEFINED__
+#define __IAMTimelineEffectable_FWD_DEFINED__
+typedef interface IAMTimelineEffectable IAMTimelineEffectable;
+#endif /* __IAMTimelineEffectable_FWD_DEFINED__ */
+
+
+#ifndef __IAMTimelineEffect_FWD_DEFINED__
+#define __IAMTimelineEffect_FWD_DEFINED__
+typedef interface IAMTimelineEffect IAMTimelineEffect;
+#endif /* __IAMTimelineEffect_FWD_DEFINED__ */
+
+
+#ifndef __IAMTimelineTransable_FWD_DEFINED__
+#define __IAMTimelineTransable_FWD_DEFINED__
+typedef interface IAMTimelineTransable IAMTimelineTransable;
+#endif /* __IAMTimelineTransable_FWD_DEFINED__ */
+
+
+#ifndef __IAMTimelineSplittable_FWD_DEFINED__
+#define __IAMTimelineSplittable_FWD_DEFINED__
+typedef interface IAMTimelineSplittable IAMTimelineSplittable;
+#endif /* __IAMTimelineSplittable_FWD_DEFINED__ */
+
+
+#ifndef __IAMTimelineTrans_FWD_DEFINED__
+#define __IAMTimelineTrans_FWD_DEFINED__
+typedef interface IAMTimelineTrans IAMTimelineTrans;
+#endif /* __IAMTimelineTrans_FWD_DEFINED__ */
+
+
+#ifndef __IAMTimelineSrc_FWD_DEFINED__
+#define __IAMTimelineSrc_FWD_DEFINED__
+typedef interface IAMTimelineSrc IAMTimelineSrc;
+#endif /* __IAMTimelineSrc_FWD_DEFINED__ */
+
+
+#ifndef __IAMTimelineTrack_FWD_DEFINED__
+#define __IAMTimelineTrack_FWD_DEFINED__
+typedef interface IAMTimelineTrack IAMTimelineTrack;
+#endif /* __IAMTimelineTrack_FWD_DEFINED__ */
+
+
+#ifndef __IAMTimelineVirtualTrack_FWD_DEFINED__
+#define __IAMTimelineVirtualTrack_FWD_DEFINED__
+typedef interface IAMTimelineVirtualTrack IAMTimelineVirtualTrack;
+#endif /* __IAMTimelineVirtualTrack_FWD_DEFINED__ */
+
+
+#ifndef __IAMTimelineComp_FWD_DEFINED__
+#define __IAMTimelineComp_FWD_DEFINED__
+typedef interface IAMTimelineComp IAMTimelineComp;
+#endif /* __IAMTimelineComp_FWD_DEFINED__ */
+
+
+#ifndef __IAMTimelineGroup_FWD_DEFINED__
+#define __IAMTimelineGroup_FWD_DEFINED__
+typedef interface IAMTimelineGroup IAMTimelineGroup;
+#endif /* __IAMTimelineGroup_FWD_DEFINED__ */
+
+
+#ifndef __IAMTimeline_FWD_DEFINED__
+#define __IAMTimeline_FWD_DEFINED__
+typedef interface IAMTimeline IAMTimeline;
+#endif /* __IAMTimeline_FWD_DEFINED__ */
+
+
+#ifndef __IXml2Dex_FWD_DEFINED__
+#define __IXml2Dex_FWD_DEFINED__
+typedef interface IXml2Dex IXml2Dex;
+#endif /* __IXml2Dex_FWD_DEFINED__ */
+
+
+#ifndef __IAMErrorLog_FWD_DEFINED__
+#define __IAMErrorLog_FWD_DEFINED__
+typedef interface IAMErrorLog IAMErrorLog;
+#endif /* __IAMErrorLog_FWD_DEFINED__ */
+
+
+#ifndef __IAMSetErrorLog_FWD_DEFINED__
+#define __IAMSetErrorLog_FWD_DEFINED__
+typedef interface IAMSetErrorLog IAMSetErrorLog;
+#endif /* __IAMSetErrorLog_FWD_DEFINED__ */
+
+
+#ifndef __ISampleGrabberCB_FWD_DEFINED__
+#define __ISampleGrabberCB_FWD_DEFINED__
+typedef interface ISampleGrabberCB ISampleGrabberCB;
+#endif /* __ISampleGrabberCB_FWD_DEFINED__ */
+
+
+#ifndef __ISampleGrabber_FWD_DEFINED__
+#define __ISampleGrabber_FWD_DEFINED__
+typedef interface ISampleGrabber ISampleGrabber;
+#endif /* __ISampleGrabber_FWD_DEFINED__ */
+
+
+#ifndef __AMTimeline_FWD_DEFINED__
+#define __AMTimeline_FWD_DEFINED__
+
+#ifdef __cplusplus
+typedef class AMTimeline AMTimeline;
+#else
+typedef struct AMTimeline AMTimeline;
+#endif /* __cplusplus */
+
+#endif /* __AMTimeline_FWD_DEFINED__ */
+
+
+#ifndef __AMTimelineObj_FWD_DEFINED__
+#define __AMTimelineObj_FWD_DEFINED__
+
+#ifdef __cplusplus
+typedef class AMTimelineObj AMTimelineObj;
+#else
+typedef struct AMTimelineObj AMTimelineObj;
+#endif /* __cplusplus */
+
+#endif /* __AMTimelineObj_FWD_DEFINED__ */
+
+
+#ifndef __AMTimelineSrc_FWD_DEFINED__
+#define __AMTimelineSrc_FWD_DEFINED__
+
+#ifdef __cplusplus
+typedef class AMTimelineSrc AMTimelineSrc;
+#else
+typedef struct AMTimelineSrc AMTimelineSrc;
+#endif /* __cplusplus */
+
+#endif /* __AMTimelineSrc_FWD_DEFINED__ */
+
+
+#ifndef __AMTimelineTrack_FWD_DEFINED__
+#define __AMTimelineTrack_FWD_DEFINED__
+
+#ifdef __cplusplus
+typedef class AMTimelineTrack AMTimelineTrack;
+#else
+typedef struct AMTimelineTrack AMTimelineTrack;
+#endif /* __cplusplus */
+
+#endif /* __AMTimelineTrack_FWD_DEFINED__ */
+
+
+#ifndef __AMTimelineComp_FWD_DEFINED__
+#define __AMTimelineComp_FWD_DEFINED__
+
+#ifdef __cplusplus
+typedef class AMTimelineComp AMTimelineComp;
+#else
+typedef struct AMTimelineComp AMTimelineComp;
+#endif /* __cplusplus */
+
+#endif /* __AMTimelineComp_FWD_DEFINED__ */
+
+
+#ifndef __AMTimelineGroup_FWD_DEFINED__
+#define __AMTimelineGroup_FWD_DEFINED__
+
+#ifdef __cplusplus
+typedef class AMTimelineGroup AMTimelineGroup;
+#else
+typedef struct AMTimelineGroup AMTimelineGroup;
+#endif /* __cplusplus */
+
+#endif /* __AMTimelineGroup_FWD_DEFINED__ */
+
+
+#ifndef __AMTimelineTrans_FWD_DEFINED__
+#define __AMTimelineTrans_FWD_DEFINED__
+
+#ifdef __cplusplus
+typedef class AMTimelineTrans AMTimelineTrans;
+#else
+typedef struct AMTimelineTrans AMTimelineTrans;
+#endif /* __cplusplus */
+
+#endif /* __AMTimelineTrans_FWD_DEFINED__ */
+
+
+#ifndef __AMTimelineEffect_FWD_DEFINED__
+#define __AMTimelineEffect_FWD_DEFINED__
+
+#ifdef __cplusplus
+typedef class AMTimelineEffect AMTimelineEffect;
+#else
+typedef struct AMTimelineEffect AMTimelineEffect;
+#endif /* __cplusplus */
+
+#endif /* __AMTimelineEffect_FWD_DEFINED__ */
+
+
+#ifndef __RenderEngine_FWD_DEFINED__
+#define __RenderEngine_FWD_DEFINED__
+
+#ifdef __cplusplus
+typedef class RenderEngine RenderEngine;
+#else
+typedef struct RenderEngine RenderEngine;
+#endif /* __cplusplus */
+
+#endif /* __RenderEngine_FWD_DEFINED__ */
+
+
+#ifndef __SmartRenderEngine_FWD_DEFINED__
+#define __SmartRenderEngine_FWD_DEFINED__
+
+#ifdef __cplusplus
+typedef class SmartRenderEngine SmartRenderEngine;
+#else
+typedef struct SmartRenderEngine SmartRenderEngine;
+#endif /* __cplusplus */
+
+#endif /* __SmartRenderEngine_FWD_DEFINED__ */
+
+
+#ifndef __AudMixer_FWD_DEFINED__
+#define __AudMixer_FWD_DEFINED__
+
+#ifdef __cplusplus
+typedef class AudMixer AudMixer;
+#else
+typedef struct AudMixer AudMixer;
+#endif /* __cplusplus */
+
+#endif /* __AudMixer_FWD_DEFINED__ */
+
+
+#ifndef __Xml2Dex_FWD_DEFINED__
+#define __Xml2Dex_FWD_DEFINED__
+
+#ifdef __cplusplus
+typedef class Xml2Dex Xml2Dex;
+#else
+typedef struct Xml2Dex Xml2Dex;
+#endif /* __cplusplus */
+
+#endif /* __Xml2Dex_FWD_DEFINED__ */
+
+
+#ifndef __MediaLocator_FWD_DEFINED__
+#define __MediaLocator_FWD_DEFINED__
+
+#ifdef __cplusplus
+typedef class MediaLocator MediaLocator;
+#else
+typedef struct MediaLocator MediaLocator;
+#endif /* __cplusplus */
+
+#endif /* __MediaLocator_FWD_DEFINED__ */
+
+
+#ifndef __PropertySetter_FWD_DEFINED__
+#define __PropertySetter_FWD_DEFINED__
+
+#ifdef __cplusplus
+typedef class PropertySetter PropertySetter;
+#else
+typedef struct PropertySetter PropertySetter;
+#endif /* __cplusplus */
+
+#endif /* __PropertySetter_FWD_DEFINED__ */
+
+
+#ifndef __MediaDet_FWD_DEFINED__
+#define __MediaDet_FWD_DEFINED__
+
+#ifdef __cplusplus
+typedef class MediaDet MediaDet;
+#else
+typedef struct MediaDet MediaDet;
+#endif /* __cplusplus */
+
+#endif /* __MediaDet_FWD_DEFINED__ */
+
+
+#ifndef __SampleGrabber_FWD_DEFINED__
+#define __SampleGrabber_FWD_DEFINED__
+
+#ifdef __cplusplus
+typedef class SampleGrabber SampleGrabber;
+#else
+typedef struct SampleGrabber SampleGrabber;
+#endif /* __cplusplus */
+
+#endif /* __SampleGrabber_FWD_DEFINED__ */
+
+
+#ifndef __NullRenderer_FWD_DEFINED__
+#define __NullRenderer_FWD_DEFINED__
+
+#ifdef __cplusplus
+typedef class NullRenderer NullRenderer;
+#else
+typedef struct NullRenderer NullRenderer;
+#endif /* __cplusplus */
+
+#endif /* __NullRenderer_FWD_DEFINED__ */
+
+
+#ifndef __DxtCompositor_FWD_DEFINED__
+#define __DxtCompositor_FWD_DEFINED__
+
+#ifdef __cplusplus
+typedef class DxtCompositor DxtCompositor;
+#else
+typedef struct DxtCompositor DxtCompositor;
+#endif /* __cplusplus */
+
+#endif /* __DxtCompositor_FWD_DEFINED__ */
+
+
+#ifndef __DxtAlphaSetter_FWD_DEFINED__
+#define __DxtAlphaSetter_FWD_DEFINED__
+
+#ifdef __cplusplus
+typedef class DxtAlphaSetter DxtAlphaSetter;
+#else
+typedef struct DxtAlphaSetter DxtAlphaSetter;
+#endif /* __cplusplus */
+
+#endif /* __DxtAlphaSetter_FWD_DEFINED__ */
+
+
+#ifndef __DxtJpeg_FWD_DEFINED__
+#define __DxtJpeg_FWD_DEFINED__
+
+#ifdef __cplusplus
+typedef class DxtJpeg DxtJpeg;
+#else
+typedef struct DxtJpeg DxtJpeg;
+#endif /* __cplusplus */
+
+#endif /* __DxtJpeg_FWD_DEFINED__ */
+
+
+#ifndef __ColorSource_FWD_DEFINED__
+#define __ColorSource_FWD_DEFINED__
+
+#ifdef __cplusplus
+typedef class ColorSource ColorSource;
+#else
+typedef struct ColorSource ColorSource;
+#endif /* __cplusplus */
+
+#endif /* __ColorSource_FWD_DEFINED__ */
+
+
+#ifndef __DxtKey_FWD_DEFINED__
+#define __DxtKey_FWD_DEFINED__
+
+#ifdef __cplusplus
+typedef class DxtKey DxtKey;
+#else
+typedef struct DxtKey DxtKey;
+#endif /* __cplusplus */
+
+#endif /* __DxtKey_FWD_DEFINED__ */
+
+
+/* header files for imported files */
+#include "oaidl.h"
+#include "ocidl.h"
+// #include "dxtrans.h"
+#include "amstream.h"
+
+#ifdef __cplusplus
+extern "C"{
+#endif
+
+void * __RPC_USER MIDL_user_allocate(size_t);
+void __RPC_USER MIDL_user_free( void * );
+
+/* interface __MIDL_itf_qedit_0000 */
+/* [local] */
+
+
+
+
+
+
+
+
+
+
+typedef /* [public] */
+enum __MIDL___MIDL_itf_qedit_0000_0001
+ { DEXTERF_JUMP = 0,
+ DEXTERF_INTERPOLATE = DEXTERF_JUMP + 1
+ } DEXTERF;
+
+typedef /* [public][public][public][public] */ struct __MIDL___MIDL_itf_qedit_0000_0002
+ {
+ BSTR Name;
+ DISPID dispID;
+ LONG nValues;
+ } DEXTER_PARAM;
+
+typedef /* [public][public][public][public] */ struct __MIDL___MIDL_itf_qedit_0000_0003
+ {
+ VARIANT v;
+ REFERENCE_TIME rt;
+ DWORD dwInterp;
+ } DEXTER_VALUE;
+
+
+enum __MIDL___MIDL_itf_qedit_0000_0004
+ { DEXTER_AUDIO_JUMP = 0,
+ DEXTER_AUDIO_INTERPOLATE = DEXTER_AUDIO_JUMP + 1
+ } ;
+typedef /* [public] */ struct __MIDL___MIDL_itf_qedit_0000_0005
+ {
+ REFERENCE_TIME rtEnd;
+ double dLevel;
+ BOOL bMethod;
+ } DEXTER_AUDIO_VOLUMEENVELOPE;
+
+
+enum __MIDL___MIDL_itf_qedit_0000_0006
+ { TIMELINE_INSERT_MODE_INSERT = 1,
+ TIMELINE_INSERT_MODE_OVERLAY = 2
+ } ;
+typedef /* [public][public][public][public][public][public][public][public] */
+enum __MIDL___MIDL_itf_qedit_0000_0007
+ { TIMELINE_MAJOR_TYPE_COMPOSITE = 1,
+ TIMELINE_MAJOR_TYPE_TRACK = 2,
+ TIMELINE_MAJOR_TYPE_SOURCE = 4,
+ TIMELINE_MAJOR_TYPE_TRANSITION = 8,
+ TIMELINE_MAJOR_TYPE_EFFECT = 16,
+ TIMELINE_MAJOR_TYPE_GROUP = 128
+ } TIMELINE_MAJOR_TYPE;
+
+typedef /* [public] */
+enum __MIDL___MIDL_itf_qedit_0000_0008
+ { DEXTERF_BOUNDING = -1,
+ DEXTERF_EXACTLY_AT = 0,
+ DEXTERF_FORWARDS = 1
+ } DEXTERF_TRACK_SEARCH_FLAGS;
+
+typedef struct _SCompFmt0
+ {
+ long nFormatId;
+ AM_MEDIA_TYPE MediaType;
+ } SCompFmt0;
+
+
+enum __MIDL___MIDL_itf_qedit_0000_0009
+ { RESIZEF_STRETCH = 0,
+ RESIZEF_CROP = RESIZEF_STRETCH + 1,
+ RESIZEF_PRESERVEASPECTRATIO = RESIZEF_CROP + 1,
+ RESIZEF_PRESERVEASPECTRATIO_NOLETTERBOX = RESIZEF_PRESERVEASPECTRATIO + 1
+ } ;
+
+enum __MIDL___MIDL_itf_qedit_0000_0010
+ { CONNECTF_DYNAMIC_NONE = 0,
+ CONNECTF_DYNAMIC_SOURCES = 0x1,
+ CONNECTF_DYNAMIC_EFFECTS = 0x2
+ } ;
+
+enum __MIDL___MIDL_itf_qedit_0000_0011
+ { SFN_VALIDATEF_CHECK = 0x1,
+ SFN_VALIDATEF_POPUP = 0x2,
+ SFN_VALIDATEF_TELLME = 0x4,
+ SFN_VALIDATEF_REPLACE = 0x8,
+ SFN_VALIDATEF_USELOCAL = 0x10,
+ SFN_VALIDATEF_NOFIND = 0x20,
+ SFN_VALIDATEF_IGNOREMUTED = 0x40,
+ SFN_VALIDATEF_END = SFN_VALIDATEF_IGNOREMUTED + 1
+ } ;
+
+enum __MIDL___MIDL_itf_qedit_0000_0012
+ { DXTKEY_RGB = 0,
+ DXTKEY_NONRED = DXTKEY_RGB + 1,
+ DXTKEY_LUMINANCE = DXTKEY_NONRED + 1,
+ DXTKEY_ALPHA = DXTKEY_LUMINANCE + 1,
+ DXTKEY_HUE = DXTKEY_ALPHA + 1
+ } ;
+
+
+extern RPC_IF_HANDLE __MIDL_itf_qedit_0000_v0_0_c_ifspec;
+extern RPC_IF_HANDLE __MIDL_itf_qedit_0000_v0_0_s_ifspec;
+
+#ifndef __IPropertySetter_INTERFACE_DEFINED__
+#define __IPropertySetter_INTERFACE_DEFINED__
+
+/* interface IPropertySetter */
+/* [unique][helpstring][uuid][object] */
+
+
+EXTERN_C const IID IID_IPropertySetter;
+
+#if defined(__cplusplus) && !defined(CINTERFACE)
+
+ MIDL_INTERFACE("AE9472BD-B0C3-11D2-8D24-00A0C9441E20")
+ IPropertySetter : public IUnknown
+ {
+ public:
+ virtual HRESULT STDMETHODCALLTYPE LoadXML(
+ /* [in] */ IUnknown *pxml) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE PrintXML(
+ /* [out] */ char *pszXML,
+ /* [in] */ int cbXML,
+ /* [out] */ int *pcbPrinted,
+ /* [in] */ int indent) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE CloneProps(
+ /* [out] */ IPropertySetter **ppSetter,
+ /* [in] */ REFERENCE_TIME rtStart,
+ /* [in] */ REFERENCE_TIME rtStop) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE AddProp(
+ /* [in] */ DEXTER_PARAM Param,
+ /* [in] */ DEXTER_VALUE *paValue) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE GetProps(
+ /* [out] */ LONG *pcParams,
+ /* [out] */ DEXTER_PARAM **paParam,
+ /* [out] */ DEXTER_VALUE **paValue) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE FreeProps(
+ /* [in] */ LONG cParams,
+ /* [in] */ DEXTER_PARAM *paParam,
+ /* [in] */ DEXTER_VALUE *paValue) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE ClearProps( void) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE SaveToBlob(
+ /* [out] */ LONG *pcSize,
+ /* [out] */ BYTE **ppb) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE LoadFromBlob(
+ /* [in] */ LONG cSize,
+ /* [in] */ BYTE *pb) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE SetProps(
+ /* [in] */ IUnknown *pTarget,
+ /* [in] */ REFERENCE_TIME rtNow) = 0;
+
+ };
+
+#else /* C style interface */
+
+ typedef struct IPropertySetterVtbl
+ {
+ BEGIN_INTERFACE
+
+ HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
+ IPropertySetter * This,
+ /* [in] */ REFIID riid,
+ /* [iid_is][out] */ void **ppvObject);
+
+ ULONG ( STDMETHODCALLTYPE *AddRef )(
+ IPropertySetter * This);
+
+ ULONG ( STDMETHODCALLTYPE *Release )(
+ IPropertySetter * This);
+
+ HRESULT ( STDMETHODCALLTYPE *LoadXML )(
+ IPropertySetter * This,
+ /* [in] */ IUnknown *pxml);
+
+ HRESULT ( STDMETHODCALLTYPE *PrintXML )(
+ IPropertySetter * This,
+ /* [out] */ char *pszXML,
+ /* [in] */ int cbXML,
+ /* [out] */ int *pcbPrinted,
+ /* [in] */ int indent);
+
+ HRESULT ( STDMETHODCALLTYPE *CloneProps )(
+ IPropertySetter * This,
+ /* [out] */ IPropertySetter **ppSetter,
+ /* [in] */ REFERENCE_TIME rtStart,
+ /* [in] */ REFERENCE_TIME rtStop);
+
+ HRESULT ( STDMETHODCALLTYPE *AddProp )(
+ IPropertySetter * This,
+ /* [in] */ DEXTER_PARAM Param,
+ /* [in] */ DEXTER_VALUE *paValue);
+
+ HRESULT ( STDMETHODCALLTYPE *GetProps )(
+ IPropertySetter * This,
+ /* [out] */ LONG *pcParams,
+ /* [out] */ DEXTER_PARAM **paParam,
+ /* [out] */ DEXTER_VALUE **paValue);
+
+ HRESULT ( STDMETHODCALLTYPE *FreeProps )(
+ IPropertySetter * This,
+ /* [in] */ LONG cParams,
+ /* [in] */ DEXTER_PARAM *paParam,
+ /* [in] */ DEXTER_VALUE *paValue);
+
+ HRESULT ( STDMETHODCALLTYPE *ClearProps )(
+ IPropertySetter * This);
+
+ HRESULT ( STDMETHODCALLTYPE *SaveToBlob )(
+ IPropertySetter * This,
+ /* [out] */ LONG *pcSize,
+ /* [out] */ BYTE **ppb);
+
+ HRESULT ( STDMETHODCALLTYPE *LoadFromBlob )(
+ IPropertySetter * This,
+ /* [in] */ LONG cSize,
+ /* [in] */ BYTE *pb);
+
+ HRESULT ( STDMETHODCALLTYPE *SetProps )(
+ IPropertySetter * This,
+ /* [in] */ IUnknown *pTarget,
+ /* [in] */ REFERENCE_TIME rtNow);
+
+ END_INTERFACE
+ } IPropertySetterVtbl;
+
+ interface IPropertySetter
+ {
+ CONST_VTBL struct IPropertySetterVtbl *lpVtbl;
+ };
+
+
+
+#ifdef COBJMACROS
+
+
+#define IPropertySetter_QueryInterface(This,riid,ppvObject) \
+ (This)->lpVtbl -> QueryInterface(This,riid,ppvObject)
+
+#define IPropertySetter_AddRef(This) \
+ (This)->lpVtbl -> AddRef(This)
+
+#define IPropertySetter_Release(This) \
+ (This)->lpVtbl -> Release(This)
+
+
+#define IPropertySetter_LoadXML(This,pxml) \
+ (This)->lpVtbl -> LoadXML(This,pxml)
+
+#define IPropertySetter_PrintXML(This,pszXML,cbXML,pcbPrinted,indent) \
+ (This)->lpVtbl -> PrintXML(This,pszXML,cbXML,pcbPrinted,indent)
+
+#define IPropertySetter_CloneProps(This,ppSetter,rtStart,rtStop) \
+ (This)->lpVtbl -> CloneProps(This,ppSetter,rtStart,rtStop)
+
+#define IPropertySetter_AddProp(This,Param,paValue) \
+ (This)->lpVtbl -> AddProp(This,Param,paValue)
+
+#define IPropertySetter_GetProps(This,pcParams,paParam,paValue) \
+ (This)->lpVtbl -> GetProps(This,pcParams,paParam,paValue)
+
+#define IPropertySetter_FreeProps(This,cParams,paParam,paValue) \
+ (This)->lpVtbl -> FreeProps(This,cParams,paParam,paValue)
+
+#define IPropertySetter_ClearProps(This) \
+ (This)->lpVtbl -> ClearProps(This)
+
+#define IPropertySetter_SaveToBlob(This,pcSize,ppb) \
+ (This)->lpVtbl -> SaveToBlob(This,pcSize,ppb)
+
+#define IPropertySetter_LoadFromBlob(This,cSize,pb) \
+ (This)->lpVtbl -> LoadFromBlob(This,cSize,pb)
+
+#define IPropertySetter_SetProps(This,pTarget,rtNow) \
+ (This)->lpVtbl -> SetProps(This,pTarget,rtNow)
+
+#endif /* COBJMACROS */
+
+
+#endif /* C style interface */
+
+
+
+HRESULT STDMETHODCALLTYPE IPropertySetter_LoadXML_Proxy(
+ IPropertySetter * This,
+ /* [in] */ IUnknown *pxml);
+
+
+void __RPC_STUB IPropertySetter_LoadXML_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+HRESULT STDMETHODCALLTYPE IPropertySetter_PrintXML_Proxy(
+ IPropertySetter * This,
+ /* [out] */ char *pszXML,
+ /* [in] */ int cbXML,
+ /* [out] */ int *pcbPrinted,
+ /* [in] */ int indent);
+
+
+void __RPC_STUB IPropertySetter_PrintXML_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+HRESULT STDMETHODCALLTYPE IPropertySetter_CloneProps_Proxy(
+ IPropertySetter * This,
+ /* [out] */ IPropertySetter **ppSetter,
+ /* [in] */ REFERENCE_TIME rtStart,
+ /* [in] */ REFERENCE_TIME rtStop);
+
+
+void __RPC_STUB IPropertySetter_CloneProps_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+HRESULT STDMETHODCALLTYPE IPropertySetter_AddProp_Proxy(
+ IPropertySetter * This,
+ /* [in] */ DEXTER_PARAM Param,
+ /* [in] */ DEXTER_VALUE *paValue);
+
+
+void __RPC_STUB IPropertySetter_AddProp_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+HRESULT STDMETHODCALLTYPE IPropertySetter_GetProps_Proxy(
+ IPropertySetter * This,
+ /* [out] */ LONG *pcParams,
+ /* [out] */ DEXTER_PARAM **paParam,
+ /* [out] */ DEXTER_VALUE **paValue);
+
+
+void __RPC_STUB IPropertySetter_GetProps_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+HRESULT STDMETHODCALLTYPE IPropertySetter_FreeProps_Proxy(
+ IPropertySetter * This,
+ /* [in] */ LONG cParams,
+ /* [in] */ DEXTER_PARAM *paParam,
+ /* [in] */ DEXTER_VALUE *paValue);
+
+
+void __RPC_STUB IPropertySetter_FreeProps_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+HRESULT STDMETHODCALLTYPE IPropertySetter_ClearProps_Proxy(
+ IPropertySetter * This);
+
+
+void __RPC_STUB IPropertySetter_ClearProps_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+HRESULT STDMETHODCALLTYPE IPropertySetter_SaveToBlob_Proxy(
+ IPropertySetter * This,
+ /* [out] */ LONG *pcSize,
+ /* [out] */ BYTE **ppb);
+
+
+void __RPC_STUB IPropertySetter_SaveToBlob_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+HRESULT STDMETHODCALLTYPE IPropertySetter_LoadFromBlob_Proxy(
+ IPropertySetter * This,
+ /* [in] */ LONG cSize,
+ /* [in] */ BYTE *pb);
+
+
+void __RPC_STUB IPropertySetter_LoadFromBlob_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+HRESULT STDMETHODCALLTYPE IPropertySetter_SetProps_Proxy(
+ IPropertySetter * This,
+ /* [in] */ IUnknown *pTarget,
+ /* [in] */ REFERENCE_TIME rtNow);
+
+
+void __RPC_STUB IPropertySetter_SetProps_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+
+#endif /* __IPropertySetter_INTERFACE_DEFINED__ */
+
+
+#ifndef __IDxtCompositor_INTERFACE_DEFINED__
+#define __IDxtCompositor_INTERFACE_DEFINED__
+
+/* interface IDxtCompositor */
+/* [unique][helpstring][dual][uuid][object] */
+
+
+EXTERN_C const IID IID_IDxtCompositor;
+
+#if defined(__cplusplus) && !defined(CINTERFACE)
+
+ MIDL_INTERFACE("BB44391E-6ABD-422f-9E2E-385C9DFF51FC")
+ IDxtCompositor : public IDXEffect
+ {
+ public:
+ virtual /* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE get_OffsetX(
+ /* [retval][out] */ long *pVal) = 0;
+
+ virtual /* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE put_OffsetX(
+ /* [in] */ long newVal) = 0;
+
+ virtual /* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE get_OffsetY(
+ /* [retval][out] */ long *pVal) = 0;
+
+ virtual /* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE put_OffsetY(
+ /* [in] */ long newVal) = 0;
+
+ virtual /* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE get_Width(
+ /* [retval][out] */ long *pVal) = 0;
+
+ virtual /* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE put_Width(
+ /* [in] */ long newVal) = 0;
+
+ virtual /* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE get_Height(
+ /* [retval][out] */ long *pVal) = 0;
+
+ virtual /* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE put_Height(
+ /* [in] */ long newVal) = 0;
+
+ virtual /* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE get_SrcOffsetX(
+ /* [retval][out] */ long *pVal) = 0;
+
+ virtual /* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE put_SrcOffsetX(
+ /* [in] */ long newVal) = 0;
+
+ virtual /* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE get_SrcOffsetY(
+ /* [retval][out] */ long *pVal) = 0;
+
+ virtual /* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE put_SrcOffsetY(
+ /* [in] */ long newVal) = 0;
+
+ virtual /* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE get_SrcWidth(
+ /* [retval][out] */ long *pVal) = 0;
+
+ virtual /* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE put_SrcWidth(
+ /* [in] */ long newVal) = 0;
+
+ virtual /* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE get_SrcHeight(
+ /* [retval][out] */ long *pVal) = 0;
+
+ virtual /* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE put_SrcHeight(
+ /* [in] */ long newVal) = 0;
+
+ };
+
+#else /* C style interface */
+
+ typedef struct IDxtCompositorVtbl
+ {
+ BEGIN_INTERFACE
+
+ HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
+ IDxtCompositor * This,
+ /* [in] */ REFIID riid,
+ /* [iid_is][out] */ void **ppvObject);
+
+ ULONG ( STDMETHODCALLTYPE *AddRef )(
+ IDxtCompositor * This);
+
+ ULONG ( STDMETHODCALLTYPE *Release )(
+ IDxtCompositor * This);
+
+ HRESULT ( STDMETHODCALLTYPE *GetTypeInfoCount )(
+ IDxtCompositor * This,
+ /* [out] */ UINT *pctinfo);
+
+ HRESULT ( STDMETHODCALLTYPE *GetTypeInfo )(
+ IDxtCompositor * This,
+ /* [in] */ UINT iTInfo,
+ /* [in] */ LCID lcid,
+ /* [out] */ ITypeInfo **ppTInfo);
+
+ HRESULT ( STDMETHODCALLTYPE *GetIDsOfNames )(
+ IDxtCompositor * This,
+ /* [in] */ REFIID riid,
+ /* [size_is][in] */ LPOLESTR *rgszNames,
+ /* [in] */ UINT cNames,
+ /* [in] */ LCID lcid,
+ /* [size_is][out] */ DISPID *rgDispId);
+
+ /* [local] */ HRESULT ( STDMETHODCALLTYPE *Invoke )(
+ IDxtCompositor * This,
+ /* [in] */ DISPID dispIdMember,
+ /* [in] */ REFIID riid,
+ /* [in] */ LCID lcid,
+ /* [in] */ WORD wFlags,
+ /* [out][in] */ DISPPARAMS *pDispParams,
+ /* [out] */ VARIANT *pVarResult,
+ /* [out] */ EXCEPINFO *pExcepInfo,
+ /* [out] */ UINT *puArgErr);
+
+ /* [id][propget] */ HRESULT ( STDMETHODCALLTYPE *get_Capabilities )(
+ IDxtCompositor * This,
+ /* [retval][out] */ long *pVal);
+
+ /* [id][propget] */ HRESULT ( STDMETHODCALLTYPE *get_Progress )(
+ IDxtCompositor * This,
+ /* [retval][out] */ float *pVal);
+
+ /* [id][propput] */ HRESULT ( STDMETHODCALLTYPE *put_Progress )(
+ IDxtCompositor * This,
+ /* [in] */ float newVal);
+
+ /* [id][propget] */ HRESULT ( STDMETHODCALLTYPE *get_StepResolution )(
+ IDxtCompositor * This,
+ /* [retval][out] */ float *pVal);
+
+ /* [id][propget] */ HRESULT ( STDMETHODCALLTYPE *get_Duration )(
+ IDxtCompositor * This,
+ /* [retval][out] */ float *pVal);
+
+ /* [id][propput] */ HRESULT ( STDMETHODCALLTYPE *put_Duration )(
+ IDxtCompositor * This,
+ /* [in] */ float newVal);
+
+ /* [helpstring][id][propget] */ HRESULT ( STDMETHODCALLTYPE *get_OffsetX )(
+ IDxtCompositor * This,
+ /* [retval][out] */ long *pVal);
+
+ /* [helpstring][id][propput] */ HRESULT ( STDMETHODCALLTYPE *put_OffsetX )(
+ IDxtCompositor * This,
+ /* [in] */ long newVal);
+
+ /* [helpstring][id][propget] */ HRESULT ( STDMETHODCALLTYPE *get_OffsetY )(
+ IDxtCompositor * This,
+ /* [retval][out] */ long *pVal);
+
+ /* [helpstring][id][propput] */ HRESULT ( STDMETHODCALLTYPE *put_OffsetY )(
+ IDxtCompositor * This,
+ /* [in] */ long newVal);
+
+ /* [helpstring][id][propget] */ HRESULT ( STDMETHODCALLTYPE *get_Width )(
+ IDxtCompositor * This,
+ /* [retval][out] */ long *pVal);
+
+ /* [helpstring][id][propput] */ HRESULT ( STDMETHODCALLTYPE *put_Width )(
+ IDxtCompositor * This,
+ /* [in] */ long newVal);
+
+ /* [helpstring][id][propget] */ HRESULT ( STDMETHODCALLTYPE *get_Height )(
+ IDxtCompositor * This,
+ /* [retval][out] */ long *pVal);
+
+ /* [helpstring][id][propput] */ HRESULT ( STDMETHODCALLTYPE *put_Height )(
+ IDxtCompositor * This,
+ /* [in] */ long newVal);
+
+ /* [helpstring][id][propget] */ HRESULT ( STDMETHODCALLTYPE *get_SrcOffsetX )(
+ IDxtCompositor * This,
+ /* [retval][out] */ long *pVal);
+
+ /* [helpstring][id][propput] */ HRESULT ( STDMETHODCALLTYPE *put_SrcOffsetX )(
+ IDxtCompositor * This,
+ /* [in] */ long newVal);
+
+ /* [helpstring][id][propget] */ HRESULT ( STDMETHODCALLTYPE *get_SrcOffsetY )(
+ IDxtCompositor * This,
+ /* [retval][out] */ long *pVal);
+
+ /* [helpstring][id][propput] */ HRESULT ( STDMETHODCALLTYPE *put_SrcOffsetY )(
+ IDxtCompositor * This,
+ /* [in] */ long newVal);
+
+ /* [helpstring][id][propget] */ HRESULT ( STDMETHODCALLTYPE *get_SrcWidth )(
+ IDxtCompositor * This,
+ /* [retval][out] */ long *pVal);
+
+ /* [helpstring][id][propput] */ HRESULT ( STDMETHODCALLTYPE *put_SrcWidth )(
+ IDxtCompositor * This,
+ /* [in] */ long newVal);
+
+ /* [helpstring][id][propget] */ HRESULT ( STDMETHODCALLTYPE *get_SrcHeight )(
+ IDxtCompositor * This,
+ /* [retval][out] */ long *pVal);
+
+ /* [helpstring][id][propput] */ HRESULT ( STDMETHODCALLTYPE *put_SrcHeight )(
+ IDxtCompositor * This,
+ /* [in] */ long newVal);
+
+ END_INTERFACE
+ } IDxtCompositorVtbl;
+
+ interface IDxtCompositor
+ {
+ CONST_VTBL struct IDxtCompositorVtbl *lpVtbl;
+ };
+
+
+
+#ifdef COBJMACROS
+
+
+#define IDxtCompositor_QueryInterface(This,riid,ppvObject) \
+ (This)->lpVtbl -> QueryInterface(This,riid,ppvObject)
+
+#define IDxtCompositor_AddRef(This) \
+ (This)->lpVtbl -> AddRef(This)
+
+#define IDxtCompositor_Release(This) \
+ (This)->lpVtbl -> Release(This)
+
+
+#define IDxtCompositor_GetTypeInfoCount(This,pctinfo) \
+ (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo)
+
+#define IDxtCompositor_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \
+ (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo)
+
+#define IDxtCompositor_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \
+ (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId)
+
+#define IDxtCompositor_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \
+ (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr)
+
+
+#define IDxtCompositor_get_Capabilities(This,pVal) \
+ (This)->lpVtbl -> get_Capabilities(This,pVal)
+
+#define IDxtCompositor_get_Progress(This,pVal) \
+ (This)->lpVtbl -> get_Progress(This,pVal)
+
+#define IDxtCompositor_put_Progress(This,newVal) \
+ (This)->lpVtbl -> put_Progress(This,newVal)
+
+#define IDxtCompositor_get_StepResolution(This,pVal) \
+ (This)->lpVtbl -> get_StepResolution(This,pVal)
+
+#define IDxtCompositor_get_Duration(This,pVal) \
+ (This)->lpVtbl -> get_Duration(This,pVal)
+
+#define IDxtCompositor_put_Duration(This,newVal) \
+ (This)->lpVtbl -> put_Duration(This,newVal)
+
+
+#define IDxtCompositor_get_OffsetX(This,pVal) \
+ (This)->lpVtbl -> get_OffsetX(This,pVal)
+
+#define IDxtCompositor_put_OffsetX(This,newVal) \
+ (This)->lpVtbl -> put_OffsetX(This,newVal)
+
+#define IDxtCompositor_get_OffsetY(This,pVal) \
+ (This)->lpVtbl -> get_OffsetY(This,pVal)
+
+#define IDxtCompositor_put_OffsetY(This,newVal) \
+ (This)->lpVtbl -> put_OffsetY(This,newVal)
+
+#define IDxtCompositor_get_Width(This,pVal) \
+ (This)->lpVtbl -> get_Width(This,pVal)
+
+#define IDxtCompositor_put_Width(This,newVal) \
+ (This)->lpVtbl -> put_Width(This,newVal)
+
+#define IDxtCompositor_get_Height(This,pVal) \
+ (This)->lpVtbl -> get_Height(This,pVal)
+
+#define IDxtCompositor_put_Height(This,newVal) \
+ (This)->lpVtbl -> put_Height(This,newVal)
+
+#define IDxtCompositor_get_SrcOffsetX(This,pVal) \
+ (This)->lpVtbl -> get_SrcOffsetX(This,pVal)
+
+#define IDxtCompositor_put_SrcOffsetX(This,newVal) \
+ (This)->lpVtbl -> put_SrcOffsetX(This,newVal)
+
+#define IDxtCompositor_get_SrcOffsetY(This,pVal) \
+ (This)->lpVtbl -> get_SrcOffsetY(This,pVal)
+
+#define IDxtCompositor_put_SrcOffsetY(This,newVal) \
+ (This)->lpVtbl -> put_SrcOffsetY(This,newVal)
+
+#define IDxtCompositor_get_SrcWidth(This,pVal) \
+ (This)->lpVtbl -> get_SrcWidth(This,pVal)
+
+#define IDxtCompositor_put_SrcWidth(This,newVal) \
+ (This)->lpVtbl -> put_SrcWidth(This,newVal)
+
+#define IDxtCompositor_get_SrcHeight(This,pVal) \
+ (This)->lpVtbl -> get_SrcHeight(This,pVal)
+
+#define IDxtCompositor_put_SrcHeight(This,newVal) \
+ (This)->lpVtbl -> put_SrcHeight(This,newVal)
+
+#endif /* COBJMACROS */
+
+
+#endif /* C style interface */
+
+
+
+/* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE IDxtCompositor_get_OffsetX_Proxy(
+ IDxtCompositor * This,
+ /* [retval][out] */ long *pVal);
+
+
+void __RPC_STUB IDxtCompositor_get_OffsetX_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE IDxtCompositor_put_OffsetX_Proxy(
+ IDxtCompositor * This,
+ /* [in] */ long newVal);
+
+
+void __RPC_STUB IDxtCompositor_put_OffsetX_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE IDxtCompositor_get_OffsetY_Proxy(
+ IDxtCompositor * This,
+ /* [retval][out] */ long *pVal);
+
+
+void __RPC_STUB IDxtCompositor_get_OffsetY_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE IDxtCompositor_put_OffsetY_Proxy(
+ IDxtCompositor * This,
+ /* [in] */ long newVal);
+
+
+void __RPC_STUB IDxtCompositor_put_OffsetY_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE IDxtCompositor_get_Width_Proxy(
+ IDxtCompositor * This,
+ /* [retval][out] */ long *pVal);
+
+
+void __RPC_STUB IDxtCompositor_get_Width_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE IDxtCompositor_put_Width_Proxy(
+ IDxtCompositor * This,
+ /* [in] */ long newVal);
+
+
+void __RPC_STUB IDxtCompositor_put_Width_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE IDxtCompositor_get_Height_Proxy(
+ IDxtCompositor * This,
+ /* [retval][out] */ long *pVal);
+
+
+void __RPC_STUB IDxtCompositor_get_Height_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE IDxtCompositor_put_Height_Proxy(
+ IDxtCompositor * This,
+ /* [in] */ long newVal);
+
+
+void __RPC_STUB IDxtCompositor_put_Height_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE IDxtCompositor_get_SrcOffsetX_Proxy(
+ IDxtCompositor * This,
+ /* [retval][out] */ long *pVal);
+
+
+void __RPC_STUB IDxtCompositor_get_SrcOffsetX_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE IDxtCompositor_put_SrcOffsetX_Proxy(
+ IDxtCompositor * This,
+ /* [in] */ long newVal);
+
+
+void __RPC_STUB IDxtCompositor_put_SrcOffsetX_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE IDxtCompositor_get_SrcOffsetY_Proxy(
+ IDxtCompositor * This,
+ /* [retval][out] */ long *pVal);
+
+
+void __RPC_STUB IDxtCompositor_get_SrcOffsetY_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE IDxtCompositor_put_SrcOffsetY_Proxy(
+ IDxtCompositor * This,
+ /* [in] */ long newVal);
+
+
+void __RPC_STUB IDxtCompositor_put_SrcOffsetY_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE IDxtCompositor_get_SrcWidth_Proxy(
+ IDxtCompositor * This,
+ /* [retval][out] */ long *pVal);
+
+
+void __RPC_STUB IDxtCompositor_get_SrcWidth_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE IDxtCompositor_put_SrcWidth_Proxy(
+ IDxtCompositor * This,
+ /* [in] */ long newVal);
+
+
+void __RPC_STUB IDxtCompositor_put_SrcWidth_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE IDxtCompositor_get_SrcHeight_Proxy(
+ IDxtCompositor * This,
+ /* [retval][out] */ long *pVal);
+
+
+void __RPC_STUB IDxtCompositor_get_SrcHeight_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE IDxtCompositor_put_SrcHeight_Proxy(
+ IDxtCompositor * This,
+ /* [in] */ long newVal);
+
+
+void __RPC_STUB IDxtCompositor_put_SrcHeight_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+
+#endif /* __IDxtCompositor_INTERFACE_DEFINED__ */
+
+
+#ifndef __IDxtAlphaSetter_INTERFACE_DEFINED__
+#define __IDxtAlphaSetter_INTERFACE_DEFINED__
+
+/* interface IDxtAlphaSetter */
+/* [unique][helpstring][dual][uuid][object] */
+
+
+EXTERN_C const IID IID_IDxtAlphaSetter;
+
+#if defined(__cplusplus) && !defined(CINTERFACE)
+
+ MIDL_INTERFACE("4EE9EAD9-DA4D-43d0-9383-06B90C08B12B")
+ IDxtAlphaSetter : public IDXEffect
+ {
+ public:
+ virtual /* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE get_Alpha(
+ /* [retval][out] */ long *pVal) = 0;
+
+ virtual /* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE put_Alpha(
+ /* [in] */ long newVal) = 0;
+
+ virtual /* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE get_AlphaRamp(
+ /* [retval][out] */ double *pVal) = 0;
+
+ virtual /* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE put_AlphaRamp(
+ /* [in] */ double newVal) = 0;
+
+ };
+
+#else /* C style interface */
+
+ typedef struct IDxtAlphaSetterVtbl
+ {
+ BEGIN_INTERFACE
+
+ HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
+ IDxtAlphaSetter * This,
+ /* [in] */ REFIID riid,
+ /* [iid_is][out] */ void **ppvObject);
+
+ ULONG ( STDMETHODCALLTYPE *AddRef )(
+ IDxtAlphaSetter * This);
+
+ ULONG ( STDMETHODCALLTYPE *Release )(
+ IDxtAlphaSetter * This);
+
+ HRESULT ( STDMETHODCALLTYPE *GetTypeInfoCount )(
+ IDxtAlphaSetter * This,
+ /* [out] */ UINT *pctinfo);
+
+ HRESULT ( STDMETHODCALLTYPE *GetTypeInfo )(
+ IDxtAlphaSetter * This,
+ /* [in] */ UINT iTInfo,
+ /* [in] */ LCID lcid,
+ /* [out] */ ITypeInfo **ppTInfo);
+
+ HRESULT ( STDMETHODCALLTYPE *GetIDsOfNames )(
+ IDxtAlphaSetter * This,
+ /* [in] */ REFIID riid,
+ /* [size_is][in] */ LPOLESTR *rgszNames,
+ /* [in] */ UINT cNames,
+ /* [in] */ LCID lcid,
+ /* [size_is][out] */ DISPID *rgDispId);
+
+ /* [local] */ HRESULT ( STDMETHODCALLTYPE *Invoke )(
+ IDxtAlphaSetter * This,
+ /* [in] */ DISPID dispIdMember,
+ /* [in] */ REFIID riid,
+ /* [in] */ LCID lcid,
+ /* [in] */ WORD wFlags,
+ /* [out][in] */ DISPPARAMS *pDispParams,
+ /* [out] */ VARIANT *pVarResult,
+ /* [out] */ EXCEPINFO *pExcepInfo,
+ /* [out] */ UINT *puArgErr);
+
+ /* [id][propget] */ HRESULT ( STDMETHODCALLTYPE *get_Capabilities )(
+ IDxtAlphaSetter * This,
+ /* [retval][out] */ long *pVal);
+
+ /* [id][propget] */ HRESULT ( STDMETHODCALLTYPE *get_Progress )(
+ IDxtAlphaSetter * This,
+ /* [retval][out] */ float *pVal);
+
+ /* [id][propput] */ HRESULT ( STDMETHODCALLTYPE *put_Progress )(
+ IDxtAlphaSetter * This,
+ /* [in] */ float newVal);
+
+ /* [id][propget] */ HRESULT ( STDMETHODCALLTYPE *get_StepResolution )(
+ IDxtAlphaSetter * This,
+ /* [retval][out] */ float *pVal);
+
+ /* [id][propget] */ HRESULT ( STDMETHODCALLTYPE *get_Duration )(
+ IDxtAlphaSetter * This,
+ /* [retval][out] */ float *pVal);
+
+ /* [id][propput] */ HRESULT ( STDMETHODCALLTYPE *put_Duration )(
+ IDxtAlphaSetter * This,
+ /* [in] */ float newVal);
+
+ /* [helpstring][id][propget] */ HRESULT ( STDMETHODCALLTYPE *get_Alpha )(
+ IDxtAlphaSetter * This,
+ /* [retval][out] */ long *pVal);
+
+ /* [helpstring][id][propput] */ HRESULT ( STDMETHODCALLTYPE *put_Alpha )(
+ IDxtAlphaSetter * This,
+ /* [in] */ long newVal);
+
+ /* [helpstring][id][propget] */ HRESULT ( STDMETHODCALLTYPE *get_AlphaRamp )(
+ IDxtAlphaSetter * This,
+ /* [retval][out] */ double *pVal);
+
+ /* [helpstring][id][propput] */ HRESULT ( STDMETHODCALLTYPE *put_AlphaRamp )(
+ IDxtAlphaSetter * This,
+ /* [in] */ double newVal);
+
+ END_INTERFACE
+ } IDxtAlphaSetterVtbl;
+
+ interface IDxtAlphaSetter
+ {
+ CONST_VTBL struct IDxtAlphaSetterVtbl *lpVtbl;
+ };
+
+
+
+#ifdef COBJMACROS
+
+
+#define IDxtAlphaSetter_QueryInterface(This,riid,ppvObject) \
+ (This)->lpVtbl -> QueryInterface(This,riid,ppvObject)
+
+#define IDxtAlphaSetter_AddRef(This) \
+ (This)->lpVtbl -> AddRef(This)
+
+#define IDxtAlphaSetter_Release(This) \
+ (This)->lpVtbl -> Release(This)
+
+
+#define IDxtAlphaSetter_GetTypeInfoCount(This,pctinfo) \
+ (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo)
+
+#define IDxtAlphaSetter_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \
+ (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo)
+
+#define IDxtAlphaSetter_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \
+ (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId)
+
+#define IDxtAlphaSetter_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \
+ (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr)
+
+
+#define IDxtAlphaSetter_get_Capabilities(This,pVal) \
+ (This)->lpVtbl -> get_Capabilities(This,pVal)
+
+#define IDxtAlphaSetter_get_Progress(This,pVal) \
+ (This)->lpVtbl -> get_Progress(This,pVal)
+
+#define IDxtAlphaSetter_put_Progress(This,newVal) \
+ (This)->lpVtbl -> put_Progress(This,newVal)
+
+#define IDxtAlphaSetter_get_StepResolution(This,pVal) \
+ (This)->lpVtbl -> get_StepResolution(This,pVal)
+
+#define IDxtAlphaSetter_get_Duration(This,pVal) \
+ (This)->lpVtbl -> get_Duration(This,pVal)
+
+#define IDxtAlphaSetter_put_Duration(This,newVal) \
+ (This)->lpVtbl -> put_Duration(This,newVal)
+
+
+#define IDxtAlphaSetter_get_Alpha(This,pVal) \
+ (This)->lpVtbl -> get_Alpha(This,pVal)
+
+#define IDxtAlphaSetter_put_Alpha(This,newVal) \
+ (This)->lpVtbl -> put_Alpha(This,newVal)
+
+#define IDxtAlphaSetter_get_AlphaRamp(This,pVal) \
+ (This)->lpVtbl -> get_AlphaRamp(This,pVal)
+
+#define IDxtAlphaSetter_put_AlphaRamp(This,newVal) \
+ (This)->lpVtbl -> put_AlphaRamp(This,newVal)
+
+#endif /* COBJMACROS */
+
+
+#endif /* C style interface */
+
+
+
+/* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE IDxtAlphaSetter_get_Alpha_Proxy(
+ IDxtAlphaSetter * This,
+ /* [retval][out] */ long *pVal);
+
+
+void __RPC_STUB IDxtAlphaSetter_get_Alpha_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE IDxtAlphaSetter_put_Alpha_Proxy(
+ IDxtAlphaSetter * This,
+ /* [in] */ long newVal);
+
+
+void __RPC_STUB IDxtAlphaSetter_put_Alpha_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE IDxtAlphaSetter_get_AlphaRamp_Proxy(
+ IDxtAlphaSetter * This,
+ /* [retval][out] */ double *pVal);
+
+
+void __RPC_STUB IDxtAlphaSetter_get_AlphaRamp_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE IDxtAlphaSetter_put_AlphaRamp_Proxy(
+ IDxtAlphaSetter * This,
+ /* [in] */ double newVal);
+
+
+void __RPC_STUB IDxtAlphaSetter_put_AlphaRamp_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+
+#endif /* __IDxtAlphaSetter_INTERFACE_DEFINED__ */
+
+
+#ifndef __IDxtJpeg_INTERFACE_DEFINED__
+#define __IDxtJpeg_INTERFACE_DEFINED__
+
+/* interface IDxtJpeg */
+/* [unique][helpstring][dual][uuid][object] */
+
+
+EXTERN_C const IID IID_IDxtJpeg;
+
+#if defined(__cplusplus) && !defined(CINTERFACE)
+
+ MIDL_INTERFACE("DE75D011-7A65-11D2-8CEA-00A0C9441E20")
+ IDxtJpeg : public IDXEffect
+ {
+ public:
+ virtual /* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE get_MaskNum(
+ /* [retval][out] */ long *__MIDL_0018) = 0;
+
+ virtual /* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE put_MaskNum(
+ /* [in] */ long __MIDL_0019) = 0;
+
+ virtual /* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE get_MaskName(
+ /* [retval][out] */ BSTR *pVal) = 0;
+
+ virtual /* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE put_MaskName(
+ /* [in] */ BSTR newVal) = 0;
+
+ virtual /* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE get_ScaleX(
+ /* [retval][out] */ double *__MIDL_0020) = 0;
+
+ virtual /* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE put_ScaleX(
+ /* [in] */ double __MIDL_0021) = 0;
+
+ virtual /* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE get_ScaleY(
+ /* [retval][out] */ double *__MIDL_0022) = 0;
+
+ virtual /* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE put_ScaleY(
+ /* [in] */ double __MIDL_0023) = 0;
+
+ virtual /* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE get_OffsetX(
+ /* [retval][out] */ long *__MIDL_0024) = 0;
+
+ virtual /* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE put_OffsetX(
+ /* [in] */ long __MIDL_0025) = 0;
+
+ virtual /* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE get_OffsetY(
+ /* [retval][out] */ long *__MIDL_0026) = 0;
+
+ virtual /* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE put_OffsetY(
+ /* [in] */ long __MIDL_0027) = 0;
+
+ virtual /* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE get_ReplicateX(
+ /* [retval][out] */ long *pVal) = 0;
+
+ virtual /* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE put_ReplicateX(
+ /* [in] */ long newVal) = 0;
+
+ virtual /* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE get_ReplicateY(
+ /* [retval][out] */ long *pVal) = 0;
+
+ virtual /* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE put_ReplicateY(
+ /* [in] */ long newVal) = 0;
+
+ virtual /* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE get_BorderColor(
+ /* [retval][out] */ long *pVal) = 0;
+
+ virtual /* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE put_BorderColor(
+ /* [in] */ long newVal) = 0;
+
+ virtual /* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE get_BorderWidth(
+ /* [retval][out] */ long *pVal) = 0;
+
+ virtual /* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE put_BorderWidth(
+ /* [in] */ long newVal) = 0;
+
+ virtual /* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE get_BorderSoftness(
+ /* [retval][out] */ long *pVal) = 0;
+
+ virtual /* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE put_BorderSoftness(
+ /* [in] */ long newVal) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE ApplyChanges( void) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE LoadDefSettings( void) = 0;
+
+ };
+
+#else /* C style interface */
+
+ typedef struct IDxtJpegVtbl
+ {
+ BEGIN_INTERFACE
+
+ HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
+ IDxtJpeg * This,
+ /* [in] */ REFIID riid,
+ /* [iid_is][out] */ void **ppvObject);
+
+ ULONG ( STDMETHODCALLTYPE *AddRef )(
+ IDxtJpeg * This);
+
+ ULONG ( STDMETHODCALLTYPE *Release )(
+ IDxtJpeg * This);
+
+ HRESULT ( STDMETHODCALLTYPE *GetTypeInfoCount )(
+ IDxtJpeg * This,
+ /* [out] */ UINT *pctinfo);
+
+ HRESULT ( STDMETHODCALLTYPE *GetTypeInfo )(
+ IDxtJpeg * This,
+ /* [in] */ UINT iTInfo,
+ /* [in] */ LCID lcid,
+ /* [out] */ ITypeInfo **ppTInfo);
+
+ HRESULT ( STDMETHODCALLTYPE *GetIDsOfNames )(
+ IDxtJpeg * This,
+ /* [in] */ REFIID riid,
+ /* [size_is][in] */ LPOLESTR *rgszNames,
+ /* [in] */ UINT cNames,
+ /* [in] */ LCID lcid,
+ /* [size_is][out] */ DISPID *rgDispId);
+
+ /* [local] */ HRESULT ( STDMETHODCALLTYPE *Invoke )(
+ IDxtJpeg * This,
+ /* [in] */ DISPID dispIdMember,
+ /* [in] */ REFIID riid,
+ /* [in] */ LCID lcid,
+ /* [in] */ WORD wFlags,
+ /* [out][in] */ DISPPARAMS *pDispParams,
+ /* [out] */ VARIANT *pVarResult,
+ /* [out] */ EXCEPINFO *pExcepInfo,
+ /* [out] */ UINT *puArgErr);
+
+ /* [id][propget] */ HRESULT ( STDMETHODCALLTYPE *get_Capabilities )(
+ IDxtJpeg * This,
+ /* [retval][out] */ long *pVal);
+
+ /* [id][propget] */ HRESULT ( STDMETHODCALLTYPE *get_Progress )(
+ IDxtJpeg * This,
+ /* [retval][out] */ float *pVal);
+
+ /* [id][propput] */ HRESULT ( STDMETHODCALLTYPE *put_Progress )(
+ IDxtJpeg * This,
+ /* [in] */ float newVal);
+
+ /* [id][propget] */ HRESULT ( STDMETHODCALLTYPE *get_StepResolution )(
+ IDxtJpeg * This,
+ /* [retval][out] */ float *pVal);
+
+ /* [id][propget] */ HRESULT ( STDMETHODCALLTYPE *get_Duration )(
+ IDxtJpeg * This,
+ /* [retval][out] */ float *pVal);
+
+ /* [id][propput] */ HRESULT ( STDMETHODCALLTYPE *put_Duration )(
+ IDxtJpeg * This,
+ /* [in] */ float newVal);
+
+ /* [helpstring][id][propget] */ HRESULT ( STDMETHODCALLTYPE *get_MaskNum )(
+ IDxtJpeg * This,
+ /* [retval][out] */ long *__MIDL_0018);
+
+ /* [helpstring][id][propput] */ HRESULT ( STDMETHODCALLTYPE *put_MaskNum )(
+ IDxtJpeg * This,
+ /* [in] */ long __MIDL_0019);
+
+ /* [helpstring][id][propget] */ HRESULT ( STDMETHODCALLTYPE *get_MaskName )(
+ IDxtJpeg * This,
+ /* [retval][out] */ BSTR *pVal);
+
+ /* [helpstring][id][propput] */ HRESULT ( STDMETHODCALLTYPE *put_MaskName )(
+ IDxtJpeg * This,
+ /* [in] */ BSTR newVal);
+
+ /* [helpstring][id][propget] */ HRESULT ( STDMETHODCALLTYPE *get_ScaleX )(
+ IDxtJpeg * This,
+ /* [retval][out] */ double *__MIDL_0020);
+
+ /* [helpstring][id][propput] */ HRESULT ( STDMETHODCALLTYPE *put_ScaleX )(
+ IDxtJpeg * This,
+ /* [in] */ double __MIDL_0021);
+
+ /* [helpstring][id][propget] */ HRESULT ( STDMETHODCALLTYPE *get_ScaleY )(
+ IDxtJpeg * This,
+ /* [retval][out] */ double *__MIDL_0022);
+
+ /* [helpstring][id][propput] */ HRESULT ( STDMETHODCALLTYPE *put_ScaleY )(
+ IDxtJpeg * This,
+ /* [in] */ double __MIDL_0023);
+
+ /* [helpstring][id][propget] */ HRESULT ( STDMETHODCALLTYPE *get_OffsetX )(
+ IDxtJpeg * This,
+ /* [retval][out] */ long *__MIDL_0024);
+
+ /* [helpstring][id][propput] */ HRESULT ( STDMETHODCALLTYPE *put_OffsetX )(
+ IDxtJpeg * This,
+ /* [in] */ long __MIDL_0025);
+
+ /* [helpstring][id][propget] */ HRESULT ( STDMETHODCALLTYPE *get_OffsetY )(
+ IDxtJpeg * This,
+ /* [retval][out] */ long *__MIDL_0026);
+
+ /* [helpstring][id][propput] */ HRESULT ( STDMETHODCALLTYPE *put_OffsetY )(
+ IDxtJpeg * This,
+ /* [in] */ long __MIDL_0027);
+
+ /* [helpstring][id][propget] */ HRESULT ( STDMETHODCALLTYPE *get_ReplicateX )(
+ IDxtJpeg * This,
+ /* [retval][out] */ long *pVal);
+
+ /* [helpstring][id][propput] */ HRESULT ( STDMETHODCALLTYPE *put_ReplicateX )(
+ IDxtJpeg * This,
+ /* [in] */ long newVal);
+
+ /* [helpstring][id][propget] */ HRESULT ( STDMETHODCALLTYPE *get_ReplicateY )(
+ IDxtJpeg * This,
+ /* [retval][out] */ long *pVal);
+
+ /* [helpstring][id][propput] */ HRESULT ( STDMETHODCALLTYPE *put_ReplicateY )(
+ IDxtJpeg * This,
+ /* [in] */ long newVal);
+
+ /* [helpstring][id][propget] */ HRESULT ( STDMETHODCALLTYPE *get_BorderColor )(
+ IDxtJpeg * This,
+ /* [retval][out] */ long *pVal);
+
+ /* [helpstring][id][propput] */ HRESULT ( STDMETHODCALLTYPE *put_BorderColor )(
+ IDxtJpeg * This,
+ /* [in] */ long newVal);
+
+ /* [helpstring][id][propget] */ HRESULT ( STDMETHODCALLTYPE *get_BorderWidth )(
+ IDxtJpeg * This,
+ /* [retval][out] */ long *pVal);
+
+ /* [helpstring][id][propput] */ HRESULT ( STDMETHODCALLTYPE *put_BorderWidth )(
+ IDxtJpeg * This,
+ /* [in] */ long newVal);
+
+ /* [helpstring][id][propget] */ HRESULT ( STDMETHODCALLTYPE *get_BorderSoftness )(
+ IDxtJpeg * This,
+ /* [retval][out] */ long *pVal);
+
+ /* [helpstring][id][propput] */ HRESULT ( STDMETHODCALLTYPE *put_BorderSoftness )(
+ IDxtJpeg * This,
+ /* [in] */ long newVal);
+
+ HRESULT ( STDMETHODCALLTYPE *ApplyChanges )(
+ IDxtJpeg * This);
+
+ HRESULT ( STDMETHODCALLTYPE *LoadDefSettings )(
+ IDxtJpeg * This);
+
+ END_INTERFACE
+ } IDxtJpegVtbl;
+
+ interface IDxtJpeg
+ {
+ CONST_VTBL struct IDxtJpegVtbl *lpVtbl;
+ };
+
+
+
+#ifdef COBJMACROS
+
+
+#define IDxtJpeg_QueryInterface(This,riid,ppvObject) \
+ (This)->lpVtbl -> QueryInterface(This,riid,ppvObject)
+
+#define IDxtJpeg_AddRef(This) \
+ (This)->lpVtbl -> AddRef(This)
+
+#define IDxtJpeg_Release(This) \
+ (This)->lpVtbl -> Release(This)
+
+
+#define IDxtJpeg_GetTypeInfoCount(This,pctinfo) \
+ (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo)
+
+#define IDxtJpeg_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \
+ (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo)
+
+#define IDxtJpeg_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \
+ (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId)
+
+#define IDxtJpeg_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \
+ (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr)
+
+
+#define IDxtJpeg_get_Capabilities(This,pVal) \
+ (This)->lpVtbl -> get_Capabilities(This,pVal)
+
+#define IDxtJpeg_get_Progress(This,pVal) \
+ (This)->lpVtbl -> get_Progress(This,pVal)
+
+#define IDxtJpeg_put_Progress(This,newVal) \
+ (This)->lpVtbl -> put_Progress(This,newVal)
+
+#define IDxtJpeg_get_StepResolution(This,pVal) \
+ (This)->lpVtbl -> get_StepResolution(This,pVal)
+
+#define IDxtJpeg_get_Duration(This,pVal) \
+ (This)->lpVtbl -> get_Duration(This,pVal)
+
+#define IDxtJpeg_put_Duration(This,newVal) \
+ (This)->lpVtbl -> put_Duration(This,newVal)
+
+
+#define IDxtJpeg_get_MaskNum(This,__MIDL_0018) \
+ (This)->lpVtbl -> get_MaskNum(This,__MIDL_0018)
+
+#define IDxtJpeg_put_MaskNum(This,__MIDL_0019) \
+ (This)->lpVtbl -> put_MaskNum(This,__MIDL_0019)
+
+#define IDxtJpeg_get_MaskName(This,pVal) \
+ (This)->lpVtbl -> get_MaskName(This,pVal)
+
+#define IDxtJpeg_put_MaskName(This,newVal) \
+ (This)->lpVtbl -> put_MaskName(This,newVal)
+
+#define IDxtJpeg_get_ScaleX(This,__MIDL_0020) \
+ (This)->lpVtbl -> get_ScaleX(This,__MIDL_0020)
+
+#define IDxtJpeg_put_ScaleX(This,__MIDL_0021) \
+ (This)->lpVtbl -> put_ScaleX(This,__MIDL_0021)
+
+#define IDxtJpeg_get_ScaleY(This,__MIDL_0022) \
+ (This)->lpVtbl -> get_ScaleY(This,__MIDL_0022)
+
+#define IDxtJpeg_put_ScaleY(This,__MIDL_0023) \
+ (This)->lpVtbl -> put_ScaleY(This,__MIDL_0023)
+
+#define IDxtJpeg_get_OffsetX(This,__MIDL_0024) \
+ (This)->lpVtbl -> get_OffsetX(This,__MIDL_0024)
+
+#define IDxtJpeg_put_OffsetX(This,__MIDL_0025) \
+ (This)->lpVtbl -> put_OffsetX(This,__MIDL_0025)
+
+#define IDxtJpeg_get_OffsetY(This,__MIDL_0026) \
+ (This)->lpVtbl -> get_OffsetY(This,__MIDL_0026)
+
+#define IDxtJpeg_put_OffsetY(This,__MIDL_0027) \
+ (This)->lpVtbl -> put_OffsetY(This,__MIDL_0027)
+
+#define IDxtJpeg_get_ReplicateX(This,pVal) \
+ (This)->lpVtbl -> get_ReplicateX(This,pVal)
+
+#define IDxtJpeg_put_ReplicateX(This,newVal) \
+ (This)->lpVtbl -> put_ReplicateX(This,newVal)
+
+#define IDxtJpeg_get_ReplicateY(This,pVal) \
+ (This)->lpVtbl -> get_ReplicateY(This,pVal)
+
+#define IDxtJpeg_put_ReplicateY(This,newVal) \
+ (This)->lpVtbl -> put_ReplicateY(This,newVal)
+
+#define IDxtJpeg_get_BorderColor(This,pVal) \
+ (This)->lpVtbl -> get_BorderColor(This,pVal)
+
+#define IDxtJpeg_put_BorderColor(This,newVal) \
+ (This)->lpVtbl -> put_BorderColor(This,newVal)
+
+#define IDxtJpeg_get_BorderWidth(This,pVal) \
+ (This)->lpVtbl -> get_BorderWidth(This,pVal)
+
+#define IDxtJpeg_put_BorderWidth(This,newVal) \
+ (This)->lpVtbl -> put_BorderWidth(This,newVal)
+
+#define IDxtJpeg_get_BorderSoftness(This,pVal) \
+ (This)->lpVtbl -> get_BorderSoftness(This,pVal)
+
+#define IDxtJpeg_put_BorderSoftness(This,newVal) \
+ (This)->lpVtbl -> put_BorderSoftness(This,newVal)
+
+#define IDxtJpeg_ApplyChanges(This) \
+ (This)->lpVtbl -> ApplyChanges(This)
+
+#define IDxtJpeg_LoadDefSettings(This) \
+ (This)->lpVtbl -> LoadDefSettings(This)
+
+#endif /* COBJMACROS */
+
+
+#endif /* C style interface */
+
+
+
+/* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE IDxtJpeg_get_MaskNum_Proxy(
+ IDxtJpeg * This,
+ /* [retval][out] */ long *__MIDL_0018);
+
+
+void __RPC_STUB IDxtJpeg_get_MaskNum_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE IDxtJpeg_put_MaskNum_Proxy(
+ IDxtJpeg * This,
+ /* [in] */ long __MIDL_0019);
+
+
+void __RPC_STUB IDxtJpeg_put_MaskNum_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE IDxtJpeg_get_MaskName_Proxy(
+ IDxtJpeg * This,
+ /* [retval][out] */ BSTR *pVal);
+
+
+void __RPC_STUB IDxtJpeg_get_MaskName_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE IDxtJpeg_put_MaskName_Proxy(
+ IDxtJpeg * This,
+ /* [in] */ BSTR newVal);
+
+
+void __RPC_STUB IDxtJpeg_put_MaskName_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE IDxtJpeg_get_ScaleX_Proxy(
+ IDxtJpeg * This,
+ /* [retval][out] */ double *__MIDL_0020);
+
+
+void __RPC_STUB IDxtJpeg_get_ScaleX_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE IDxtJpeg_put_ScaleX_Proxy(
+ IDxtJpeg * This,
+ /* [in] */ double __MIDL_0021);
+
+
+void __RPC_STUB IDxtJpeg_put_ScaleX_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE IDxtJpeg_get_ScaleY_Proxy(
+ IDxtJpeg * This,
+ /* [retval][out] */ double *__MIDL_0022);
+
+
+void __RPC_STUB IDxtJpeg_get_ScaleY_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE IDxtJpeg_put_ScaleY_Proxy(
+ IDxtJpeg * This,
+ /* [in] */ double __MIDL_0023);
+
+
+void __RPC_STUB IDxtJpeg_put_ScaleY_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE IDxtJpeg_get_OffsetX_Proxy(
+ IDxtJpeg * This,
+ /* [retval][out] */ long *__MIDL_0024);
+
+
+void __RPC_STUB IDxtJpeg_get_OffsetX_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE IDxtJpeg_put_OffsetX_Proxy(
+ IDxtJpeg * This,
+ /* [in] */ long __MIDL_0025);
+
+
+void __RPC_STUB IDxtJpeg_put_OffsetX_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE IDxtJpeg_get_OffsetY_Proxy(
+ IDxtJpeg * This,
+ /* [retval][out] */ long *__MIDL_0026);
+
+
+void __RPC_STUB IDxtJpeg_get_OffsetY_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE IDxtJpeg_put_OffsetY_Proxy(
+ IDxtJpeg * This,
+ /* [in] */ long __MIDL_0027);
+
+
+void __RPC_STUB IDxtJpeg_put_OffsetY_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE IDxtJpeg_get_ReplicateX_Proxy(
+ IDxtJpeg * This,
+ /* [retval][out] */ long *pVal);
+
+
+void __RPC_STUB IDxtJpeg_get_ReplicateX_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE IDxtJpeg_put_ReplicateX_Proxy(
+ IDxtJpeg * This,
+ /* [in] */ long newVal);
+
+
+void __RPC_STUB IDxtJpeg_put_ReplicateX_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE IDxtJpeg_get_ReplicateY_Proxy(
+ IDxtJpeg * This,
+ /* [retval][out] */ long *pVal);
+
+
+void __RPC_STUB IDxtJpeg_get_ReplicateY_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE IDxtJpeg_put_ReplicateY_Proxy(
+ IDxtJpeg * This,
+ /* [in] */ long newVal);
+
+
+void __RPC_STUB IDxtJpeg_put_ReplicateY_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE IDxtJpeg_get_BorderColor_Proxy(
+ IDxtJpeg * This,
+ /* [retval][out] */ long *pVal);
+
+
+void __RPC_STUB IDxtJpeg_get_BorderColor_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE IDxtJpeg_put_BorderColor_Proxy(
+ IDxtJpeg * This,
+ /* [in] */ long newVal);
+
+
+void __RPC_STUB IDxtJpeg_put_BorderColor_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE IDxtJpeg_get_BorderWidth_Proxy(
+ IDxtJpeg * This,
+ /* [retval][out] */ long *pVal);
+
+
+void __RPC_STUB IDxtJpeg_get_BorderWidth_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE IDxtJpeg_put_BorderWidth_Proxy(
+ IDxtJpeg * This,
+ /* [in] */ long newVal);
+
+
+void __RPC_STUB IDxtJpeg_put_BorderWidth_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE IDxtJpeg_get_BorderSoftness_Proxy(
+ IDxtJpeg * This,
+ /* [retval][out] */ long *pVal);
+
+
+void __RPC_STUB IDxtJpeg_get_BorderSoftness_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE IDxtJpeg_put_BorderSoftness_Proxy(
+ IDxtJpeg * This,
+ /* [in] */ long newVal);
+
+
+void __RPC_STUB IDxtJpeg_put_BorderSoftness_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+HRESULT STDMETHODCALLTYPE IDxtJpeg_ApplyChanges_Proxy(
+ IDxtJpeg * This);
+
+
+void __RPC_STUB IDxtJpeg_ApplyChanges_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+HRESULT STDMETHODCALLTYPE IDxtJpeg_LoadDefSettings_Proxy(
+ IDxtJpeg * This);
+
+
+void __RPC_STUB IDxtJpeg_LoadDefSettings_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+
+#endif /* __IDxtJpeg_INTERFACE_DEFINED__ */
+
+
+#ifndef __IDxtKey_INTERFACE_DEFINED__
+#define __IDxtKey_INTERFACE_DEFINED__
+
+/* interface IDxtKey */
+/* [unique][helpstring][dual][uuid][object] */
+
+
+EXTERN_C const IID IID_IDxtKey;
+
+#if defined(__cplusplus) && !defined(CINTERFACE)
+
+ MIDL_INTERFACE("3255de56-38fb-4901-b980-94b438010d7b")
+ IDxtKey : public IDXEffect
+ {
+ public:
+ virtual /* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE get_KeyType(
+ /* [retval][out] */ int *__MIDL_0028) = 0;
+
+ virtual /* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE put_KeyType(
+ /* [in] */ int __MIDL_0029) = 0;
+
+ virtual /* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE get_Hue(
+ /* [retval][out] */ int *__MIDL_0030) = 0;
+
+ virtual /* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE put_Hue(
+ /* [in] */ int __MIDL_0031) = 0;
+
+ virtual /* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE get_Luminance(
+ /* [retval][out] */ int *__MIDL_0032) = 0;
+
+ virtual /* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE put_Luminance(
+ /* [in] */ int __MIDL_0033) = 0;
+
+ virtual /* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE get_RGB(
+ /* [retval][out] */ DWORD *__MIDL_0034) = 0;
+
+ virtual /* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE put_RGB(
+ /* [in] */ DWORD __MIDL_0035) = 0;
+
+ virtual /* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE get_Similarity(
+ /* [retval][out] */ int *__MIDL_0036) = 0;
+
+ virtual /* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE put_Similarity(
+ /* [in] */ int __MIDL_0037) = 0;
+
+ virtual /* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE get_Invert(
+ /* [retval][out] */ BOOL *__MIDL_0038) = 0;
+
+ virtual /* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE put_Invert(
+ /* [in] */ BOOL __MIDL_0039) = 0;
+
+ };
+
+#else /* C style interface */
+
+ typedef struct IDxtKeyVtbl
+ {
+ BEGIN_INTERFACE
+
+ HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
+ IDxtKey * This,
+ /* [in] */ REFIID riid,
+ /* [iid_is][out] */ void **ppvObject);
+
+ ULONG ( STDMETHODCALLTYPE *AddRef )(
+ IDxtKey * This);
+
+ ULONG ( STDMETHODCALLTYPE *Release )(
+ IDxtKey * This);
+
+ HRESULT ( STDMETHODCALLTYPE *GetTypeInfoCount )(
+ IDxtKey * This,
+ /* [out] */ UINT *pctinfo);
+
+ HRESULT ( STDMETHODCALLTYPE *GetTypeInfo )(
+ IDxtKey * This,
+ /* [in] */ UINT iTInfo,
+ /* [in] */ LCID lcid,
+ /* [out] */ ITypeInfo **ppTInfo);
+
+ HRESULT ( STDMETHODCALLTYPE *GetIDsOfNames )(
+ IDxtKey * This,
+ /* [in] */ REFIID riid,
+ /* [size_is][in] */ LPOLESTR *rgszNames,
+ /* [in] */ UINT cNames,
+ /* [in] */ LCID lcid,
+ /* [size_is][out] */ DISPID *rgDispId);
+
+ /* [local] */ HRESULT ( STDMETHODCALLTYPE *Invoke )(
+ IDxtKey * This,
+ /* [in] */ DISPID dispIdMember,
+ /* [in] */ REFIID riid,
+ /* [in] */ LCID lcid,
+ /* [in] */ WORD wFlags,
+ /* [out][in] */ DISPPARAMS *pDispParams,
+ /* [out] */ VARIANT *pVarResult,
+ /* [out] */ EXCEPINFO *pExcepInfo,
+ /* [out] */ UINT *puArgErr);
+
+ /* [id][propget] */ HRESULT ( STDMETHODCALLTYPE *get_Capabilities )(
+ IDxtKey * This,
+ /* [retval][out] */ long *pVal);
+
+ /* [id][propget] */ HRESULT ( STDMETHODCALLTYPE *get_Progress )(
+ IDxtKey * This,
+ /* [retval][out] */ float *pVal);
+
+ /* [id][propput] */ HRESULT ( STDMETHODCALLTYPE *put_Progress )(
+ IDxtKey * This,
+ /* [in] */ float newVal);
+
+ /* [id][propget] */ HRESULT ( STDMETHODCALLTYPE *get_StepResolution )(
+ IDxtKey * This,
+ /* [retval][out] */ float *pVal);
+
+ /* [id][propget] */ HRESULT ( STDMETHODCALLTYPE *get_Duration )(
+ IDxtKey * This,
+ /* [retval][out] */ float *pVal);
+
+ /* [id][propput] */ HRESULT ( STDMETHODCALLTYPE *put_Duration )(
+ IDxtKey * This,
+ /* [in] */ float newVal);
+
+ /* [helpstring][id][propget] */ HRESULT ( STDMETHODCALLTYPE *get_KeyType )(
+ IDxtKey * This,
+ /* [retval][out] */ int *__MIDL_0028);
+
+ /* [helpstring][id][propput] */ HRESULT ( STDMETHODCALLTYPE *put_KeyType )(
+ IDxtKey * This,
+ /* [in] */ int __MIDL_0029);
+
+ /* [helpstring][id][propget] */ HRESULT ( STDMETHODCALLTYPE *get_Hue )(
+ IDxtKey * This,
+ /* [retval][out] */ int *__MIDL_0030);
+
+ /* [helpstring][id][propput] */ HRESULT ( STDMETHODCALLTYPE *put_Hue )(
+ IDxtKey * This,
+ /* [in] */ int __MIDL_0031);
+
+ /* [helpstring][id][propget] */ HRESULT ( STDMETHODCALLTYPE *get_Luminance )(
+ IDxtKey * This,
+ /* [retval][out] */ int *__MIDL_0032);
+
+ /* [helpstring][id][propput] */ HRESULT ( STDMETHODCALLTYPE *put_Luminance )(
+ IDxtKey * This,
+ /* [in] */ int __MIDL_0033);
+
+ /* [helpstring][id][propget] */ HRESULT ( STDMETHODCALLTYPE *get_RGB )(
+ IDxtKey * This,
+ /* [retval][out] */ DWORD *__MIDL_0034);
+
+ /* [helpstring][id][propput] */ HRESULT ( STDMETHODCALLTYPE *put_RGB )(
+ IDxtKey * This,
+ /* [in] */ DWORD __MIDL_0035);
+
+ /* [helpstring][id][propget] */ HRESULT ( STDMETHODCALLTYPE *get_Similarity )(
+ IDxtKey * This,
+ /* [retval][out] */ int *__MIDL_0036);
+
+ /* [helpstring][id][propput] */ HRESULT ( STDMETHODCALLTYPE *put_Similarity )(
+ IDxtKey * This,
+ /* [in] */ int __MIDL_0037);
+
+ /* [helpstring][id][propget] */ HRESULT ( STDMETHODCALLTYPE *get_Invert )(
+ IDxtKey * This,
+ /* [retval][out] */ BOOL *__MIDL_0038);
+
+ /* [helpstring][id][propput] */ HRESULT ( STDMETHODCALLTYPE *put_Invert )(
+ IDxtKey * This,
+ /* [in] */ BOOL __MIDL_0039);
+
+ END_INTERFACE
+ } IDxtKeyVtbl;
+
+ interface IDxtKey
+ {
+ CONST_VTBL struct IDxtKeyVtbl *lpVtbl;
+ };
+
+
+
+#ifdef COBJMACROS
+
+
+#define IDxtKey_QueryInterface(This,riid,ppvObject) \
+ (This)->lpVtbl -> QueryInterface(This,riid,ppvObject)
+
+#define IDxtKey_AddRef(This) \
+ (This)->lpVtbl -> AddRef(This)
+
+#define IDxtKey_Release(This) \
+ (This)->lpVtbl -> Release(This)
+
+
+#define IDxtKey_GetTypeInfoCount(This,pctinfo) \
+ (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo)
+
+#define IDxtKey_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \
+ (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo)
+
+#define IDxtKey_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \
+ (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId)
+
+#define IDxtKey_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \
+ (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr)
+
+
+#define IDxtKey_get_Capabilities(This,pVal) \
+ (This)->lpVtbl -> get_Capabilities(This,pVal)
+
+#define IDxtKey_get_Progress(This,pVal) \
+ (This)->lpVtbl -> get_Progress(This,pVal)
+
+#define IDxtKey_put_Progress(This,newVal) \
+ (This)->lpVtbl -> put_Progress(This,newVal)
+
+#define IDxtKey_get_StepResolution(This,pVal) \
+ (This)->lpVtbl -> get_StepResolution(This,pVal)
+
+#define IDxtKey_get_Duration(This,pVal) \
+ (This)->lpVtbl -> get_Duration(This,pVal)
+
+#define IDxtKey_put_Duration(This,newVal) \
+ (This)->lpVtbl -> put_Duration(This,newVal)
+
+
+#define IDxtKey_get_KeyType(This,__MIDL_0028) \
+ (This)->lpVtbl -> get_KeyType(This,__MIDL_0028)
+
+#define IDxtKey_put_KeyType(This,__MIDL_0029) \
+ (This)->lpVtbl -> put_KeyType(This,__MIDL_0029)
+
+#define IDxtKey_get_Hue(This,__MIDL_0030) \
+ (This)->lpVtbl -> get_Hue(This,__MIDL_0030)
+
+#define IDxtKey_put_Hue(This,__MIDL_0031) \
+ (This)->lpVtbl -> put_Hue(This,__MIDL_0031)
+
+#define IDxtKey_get_Luminance(This,__MIDL_0032) \
+ (This)->lpVtbl -> get_Luminance(This,__MIDL_0032)
+
+#define IDxtKey_put_Luminance(This,__MIDL_0033) \
+ (This)->lpVtbl -> put_Luminance(This,__MIDL_0033)
+
+#define IDxtKey_get_RGB(This,__MIDL_0034) \
+ (This)->lpVtbl -> get_RGB(This,__MIDL_0034)
+
+#define IDxtKey_put_RGB(This,__MIDL_0035) \
+ (This)->lpVtbl -> put_RGB(This,__MIDL_0035)
+
+#define IDxtKey_get_Similarity(This,__MIDL_0036) \
+ (This)->lpVtbl -> get_Similarity(This,__MIDL_0036)
+
+#define IDxtKey_put_Similarity(This,__MIDL_0037) \
+ (This)->lpVtbl -> put_Similarity(This,__MIDL_0037)
+
+#define IDxtKey_get_Invert(This,__MIDL_0038) \
+ (This)->lpVtbl -> get_Invert(This,__MIDL_0038)
+
+#define IDxtKey_put_Invert(This,__MIDL_0039) \
+ (This)->lpVtbl -> put_Invert(This,__MIDL_0039)
+
+#endif /* COBJMACROS */
+
+
+#endif /* C style interface */
+
+
+
+/* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE IDxtKey_get_KeyType_Proxy(
+ IDxtKey * This,
+ /* [retval][out] */ int *__MIDL_0028);
+
+
+void __RPC_STUB IDxtKey_get_KeyType_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE IDxtKey_put_KeyType_Proxy(
+ IDxtKey * This,
+ /* [in] */ int __MIDL_0029);
+
+
+void __RPC_STUB IDxtKey_put_KeyType_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE IDxtKey_get_Hue_Proxy(
+ IDxtKey * This,
+ /* [retval][out] */ int *__MIDL_0030);
+
+
+void __RPC_STUB IDxtKey_get_Hue_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE IDxtKey_put_Hue_Proxy(
+ IDxtKey * This,
+ /* [in] */ int __MIDL_0031);
+
+
+void __RPC_STUB IDxtKey_put_Hue_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE IDxtKey_get_Luminance_Proxy(
+ IDxtKey * This,
+ /* [retval][out] */ int *__MIDL_0032);
+
+
+void __RPC_STUB IDxtKey_get_Luminance_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE IDxtKey_put_Luminance_Proxy(
+ IDxtKey * This,
+ /* [in] */ int __MIDL_0033);
+
+
+void __RPC_STUB IDxtKey_put_Luminance_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE IDxtKey_get_RGB_Proxy(
+ IDxtKey * This,
+ /* [retval][out] */ DWORD *__MIDL_0034);
+
+
+void __RPC_STUB IDxtKey_get_RGB_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE IDxtKey_put_RGB_Proxy(
+ IDxtKey * This,
+ /* [in] */ DWORD __MIDL_0035);
+
+
+void __RPC_STUB IDxtKey_put_RGB_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE IDxtKey_get_Similarity_Proxy(
+ IDxtKey * This,
+ /* [retval][out] */ int *__MIDL_0036);
+
+
+void __RPC_STUB IDxtKey_get_Similarity_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE IDxtKey_put_Similarity_Proxy(
+ IDxtKey * This,
+ /* [in] */ int __MIDL_0037);
+
+
+void __RPC_STUB IDxtKey_put_Similarity_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE IDxtKey_get_Invert_Proxy(
+ IDxtKey * This,
+ /* [retval][out] */ BOOL *__MIDL_0038);
+
+
+void __RPC_STUB IDxtKey_get_Invert_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE IDxtKey_put_Invert_Proxy(
+ IDxtKey * This,
+ /* [in] */ BOOL __MIDL_0039);
+
+
+void __RPC_STUB IDxtKey_put_Invert_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+
+#endif /* __IDxtKey_INTERFACE_DEFINED__ */
+
+
+#ifndef __IMediaLocator_INTERFACE_DEFINED__
+#define __IMediaLocator_INTERFACE_DEFINED__
+
+/* interface IMediaLocator */
+/* [unique][helpstring][uuid][object] */
+
+
+EXTERN_C const IID IID_IMediaLocator;
+
+#if defined(__cplusplus) && !defined(CINTERFACE)
+
+ MIDL_INTERFACE("288581E0-66CE-11d2-918F-00C0DF10D434")
+ IMediaLocator : public IUnknown
+ {
+ public:
+ virtual HRESULT STDMETHODCALLTYPE FindMediaFile(
+ BSTR Input,
+ BSTR FilterString,
+ BSTR *pOutput,
+ long Flags) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE AddFoundLocation(
+ BSTR DirectoryName) = 0;
+
+ };
+
+#else /* C style interface */
+
+ typedef struct IMediaLocatorVtbl
+ {
+ BEGIN_INTERFACE
+
+ HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
+ IMediaLocator * This,
+ /* [in] */ REFIID riid,
+ /* [iid_is][out] */ void **ppvObject);
+
+ ULONG ( STDMETHODCALLTYPE *AddRef )(
+ IMediaLocator * This);
+
+ ULONG ( STDMETHODCALLTYPE *Release )(
+ IMediaLocator * This);
+
+ HRESULT ( STDMETHODCALLTYPE *FindMediaFile )(
+ IMediaLocator * This,
+ BSTR Input,
+ BSTR FilterString,
+ BSTR *pOutput,
+ long Flags);
+
+ HRESULT ( STDMETHODCALLTYPE *AddFoundLocation )(
+ IMediaLocator * This,
+ BSTR DirectoryName);
+
+ END_INTERFACE
+ } IMediaLocatorVtbl;
+
+ interface IMediaLocator
+ {
+ CONST_VTBL struct IMediaLocatorVtbl *lpVtbl;
+ };
+
+
+
+#ifdef COBJMACROS
+
+
+#define IMediaLocator_QueryInterface(This,riid,ppvObject) \
+ (This)->lpVtbl -> QueryInterface(This,riid,ppvObject)
+
+#define IMediaLocator_AddRef(This) \
+ (This)->lpVtbl -> AddRef(This)
+
+#define IMediaLocator_Release(This) \
+ (This)->lpVtbl -> Release(This)
+
+
+#define IMediaLocator_FindMediaFile(This,Input,FilterString,pOutput,Flags) \
+ (This)->lpVtbl -> FindMediaFile(This,Input,FilterString,pOutput,Flags)
+
+#define IMediaLocator_AddFoundLocation(This,DirectoryName) \
+ (This)->lpVtbl -> AddFoundLocation(This,DirectoryName)
+
+#endif /* COBJMACROS */
+
+
+#endif /* C style interface */
+
+
+
+HRESULT STDMETHODCALLTYPE IMediaLocator_FindMediaFile_Proxy(
+ IMediaLocator * This,
+ BSTR Input,
+ BSTR FilterString,
+ BSTR *pOutput,
+ long Flags);
+
+
+void __RPC_STUB IMediaLocator_FindMediaFile_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+HRESULT STDMETHODCALLTYPE IMediaLocator_AddFoundLocation_Proxy(
+ IMediaLocator * This,
+ BSTR DirectoryName);
+
+
+void __RPC_STUB IMediaLocator_AddFoundLocation_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+
+#endif /* __IMediaLocator_INTERFACE_DEFINED__ */
+
+
+#ifndef __IMediaDet_INTERFACE_DEFINED__
+#define __IMediaDet_INTERFACE_DEFINED__
+
+/* interface IMediaDet */
+/* [unique][helpstring][uuid][object] */
+
+
+EXTERN_C const IID IID_IMediaDet;
+
+#if defined(__cplusplus) && !defined(CINTERFACE)
+
+ MIDL_INTERFACE("65BD0710-24D2-4ff7-9324-ED2E5D3ABAFA")
+ IMediaDet : public IUnknown
+ {
+ public:
+ virtual /* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE get_Filter(
+ /* [retval][out] */ IUnknown **pVal) = 0;
+
+ virtual /* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE put_Filter(
+ /* [in] */ IUnknown *newVal) = 0;
+
+ virtual /* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE get_OutputStreams(
+ /* [retval][out] */ long *pVal) = 0;
+
+ virtual /* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE get_CurrentStream(
+ /* [retval][out] */ long *pVal) = 0;
+
+ virtual /* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE put_CurrentStream(
+ /* [in] */ long newVal) = 0;
+
+ virtual /* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE get_StreamType(
+ /* [retval][out] */ GUID *pVal) = 0;
+
+ virtual /* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE get_StreamTypeB(
+ /* [retval][out] */ BSTR *pVal) = 0;
+
+ virtual /* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE get_StreamLength(
+ /* [retval][out] */ double *pVal) = 0;
+
+ virtual /* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE get_Filename(
+ /* [retval][out] */ BSTR *pVal) = 0;
+
+ virtual /* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE put_Filename(
+ /* [in] */ BSTR newVal) = 0;
+
+ virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE GetBitmapBits(
+ double StreamTime,
+ long *pBufferSize,
+ char *pBuffer,
+ long Width,
+ long Height) = 0;
+
+ virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE WriteBitmapBits(
+ double StreamTime,
+ long Width,
+ long Height,
+ BSTR Filename) = 0;
+
+ virtual /* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE get_StreamMediaType(
+ /* [retval][out] */ AM_MEDIA_TYPE *pVal) = 0;
+
+ virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE GetSampleGrabber(
+ /* [out] */ ISampleGrabber **ppVal) = 0;
+
+ virtual /* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE get_FrameRate(
+ /* [retval][out] */ double *pVal) = 0;
+
+ virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE EnterBitmapGrabMode(
+ double SeekTime) = 0;
+
+ };
+
+#else /* C style interface */
+
+ typedef struct IMediaDetVtbl
+ {
+ BEGIN_INTERFACE
+
+ HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
+ IMediaDet * This,
+ /* [in] */ REFIID riid,
+ /* [iid_is][out] */ void **ppvObject);
+
+ ULONG ( STDMETHODCALLTYPE *AddRef )(
+ IMediaDet * This);
+
+ ULONG ( STDMETHODCALLTYPE *Release )(
+ IMediaDet * This);
+
+ /* [helpstring][id][propget] */ HRESULT ( STDMETHODCALLTYPE *get_Filter )(
+ IMediaDet * This,
+ /* [retval][out] */ IUnknown **pVal);
+
+ /* [helpstring][id][propput] */ HRESULT ( STDMETHODCALLTYPE *put_Filter )(
+ IMediaDet * This,
+ /* [in] */ IUnknown *newVal);
+
+ /* [helpstring][id][propget] */ HRESULT ( STDMETHODCALLTYPE *get_OutputStreams )(
+ IMediaDet * This,
+ /* [retval][out] */ long *pVal);
+
+ /* [helpstring][id][propget] */ HRESULT ( STDMETHODCALLTYPE *get_CurrentStream )(
+ IMediaDet * This,
+ /* [retval][out] */ long *pVal);
+
+ /* [helpstring][id][propput] */ HRESULT ( STDMETHODCALLTYPE *put_CurrentStream )(
+ IMediaDet * This,
+ /* [in] */ long newVal);
+
+ /* [helpstring][id][propget] */ HRESULT ( STDMETHODCALLTYPE *get_StreamType )(
+ IMediaDet * This,
+ /* [retval][out] */ GUID *pVal);
+
+ /* [helpstring][id][propget] */ HRESULT ( STDMETHODCALLTYPE *get_StreamTypeB )(
+ IMediaDet * This,
+ /* [retval][out] */ BSTR *pVal);
+
+ /* [helpstring][id][propget] */ HRESULT ( STDMETHODCALLTYPE *get_StreamLength )(
+ IMediaDet * This,
+ /* [retval][out] */ double *pVal);
+
+ /* [helpstring][id][propget] */ HRESULT ( STDMETHODCALLTYPE *get_Filename )(
+ IMediaDet * This,
+ /* [retval][out] */ BSTR *pVal);
+
+ /* [helpstring][id][propput] */ HRESULT ( STDMETHODCALLTYPE *put_Filename )(
+ IMediaDet * This,
+ /* [in] */ BSTR newVal);
+
+ /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *GetBitmapBits )(
+ IMediaDet * This,
+ double StreamTime,
+ long *pBufferSize,
+ char *pBuffer,
+ long Width,
+ long Height);
+
+ /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *WriteBitmapBits )(
+ IMediaDet * This,
+ double StreamTime,
+ long Width,
+ long Height,
+ BSTR Filename);
+
+ /* [helpstring][id][propget] */ HRESULT ( STDMETHODCALLTYPE *get_StreamMediaType )(
+ IMediaDet * This,
+ /* [retval][out] */ AM_MEDIA_TYPE *pVal);
+
+ /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *GetSampleGrabber )(
+ IMediaDet * This,
+ /* [out] */ ISampleGrabber **ppVal);
+
+ /* [helpstring][id][propget] */ HRESULT ( STDMETHODCALLTYPE *get_FrameRate )(
+ IMediaDet * This,
+ /* [retval][out] */ double *pVal);
+
+ /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *EnterBitmapGrabMode )(
+ IMediaDet * This,
+ double SeekTime);
+
+ END_INTERFACE
+ } IMediaDetVtbl;
+
+ interface IMediaDet
+ {
+ CONST_VTBL struct IMediaDetVtbl *lpVtbl;
+ };
+
+
+
+#ifdef COBJMACROS
+
+
+#define IMediaDet_QueryInterface(This,riid,ppvObject) \
+ (This)->lpVtbl -> QueryInterface(This,riid,ppvObject)
+
+#define IMediaDet_AddRef(This) \
+ (This)->lpVtbl -> AddRef(This)
+
+#define IMediaDet_Release(This) \
+ (This)->lpVtbl -> Release(This)
+
+
+#define IMediaDet_get_Filter(This,pVal) \
+ (This)->lpVtbl -> get_Filter(This,pVal)
+
+#define IMediaDet_put_Filter(This,newVal) \
+ (This)->lpVtbl -> put_Filter(This,newVal)
+
+#define IMediaDet_get_OutputStreams(This,pVal) \
+ (This)->lpVtbl -> get_OutputStreams(This,pVal)
+
+#define IMediaDet_get_CurrentStream(This,pVal) \
+ (This)->lpVtbl -> get_CurrentStream(This,pVal)
+
+#define IMediaDet_put_CurrentStream(This,newVal) \
+ (This)->lpVtbl -> put_CurrentStream(This,newVal)
+
+#define IMediaDet_get_StreamType(This,pVal) \
+ (This)->lpVtbl -> get_StreamType(This,pVal)
+
+#define IMediaDet_get_StreamTypeB(This,pVal) \
+ (This)->lpVtbl -> get_StreamTypeB(This,pVal)
+
+#define IMediaDet_get_StreamLength(This,pVal) \
+ (This)->lpVtbl -> get_StreamLength(This,pVal)
+
+#define IMediaDet_get_Filename(This,pVal) \
+ (This)->lpVtbl -> get_Filename(This,pVal)
+
+#define IMediaDet_put_Filename(This,newVal) \
+ (This)->lpVtbl -> put_Filename(This,newVal)
+
+#define IMediaDet_GetBitmapBits(This,StreamTime,pBufferSize,pBuffer,Width,Height) \
+ (This)->lpVtbl -> GetBitmapBits(This,StreamTime,pBufferSize,pBuffer,Width,Height)
+
+#define IMediaDet_WriteBitmapBits(This,StreamTime,Width,Height,Filename) \
+ (This)->lpVtbl -> WriteBitmapBits(This,StreamTime,Width,Height,Filename)
+
+#define IMediaDet_get_StreamMediaType(This,pVal) \
+ (This)->lpVtbl -> get_StreamMediaType(This,pVal)
+
+#define IMediaDet_GetSampleGrabber(This,ppVal) \
+ (This)->lpVtbl -> GetSampleGrabber(This,ppVal)
+
+#define IMediaDet_get_FrameRate(This,pVal) \
+ (This)->lpVtbl -> get_FrameRate(This,pVal)
+
+#define IMediaDet_EnterBitmapGrabMode(This,SeekTime) \
+ (This)->lpVtbl -> EnterBitmapGrabMode(This,SeekTime)
+
+#endif /* COBJMACROS */
+
+
+#endif /* C style interface */
+
+
+
+/* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE IMediaDet_get_Filter_Proxy(
+ IMediaDet * This,
+ /* [retval][out] */ IUnknown **pVal);
+
+
+void __RPC_STUB IMediaDet_get_Filter_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE IMediaDet_put_Filter_Proxy(
+ IMediaDet * This,
+ /* [in] */ IUnknown *newVal);
+
+
+void __RPC_STUB IMediaDet_put_Filter_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE IMediaDet_get_OutputStreams_Proxy(
+ IMediaDet * This,
+ /* [retval][out] */ long *pVal);
+
+
+void __RPC_STUB IMediaDet_get_OutputStreams_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE IMediaDet_get_CurrentStream_Proxy(
+ IMediaDet * This,
+ /* [retval][out] */ long *pVal);
+
+
+void __RPC_STUB IMediaDet_get_CurrentStream_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE IMediaDet_put_CurrentStream_Proxy(
+ IMediaDet * This,
+ /* [in] */ long newVal);
+
+
+void __RPC_STUB IMediaDet_put_CurrentStream_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE IMediaDet_get_StreamType_Proxy(
+ IMediaDet * This,
+ /* [retval][out] */ GUID *pVal);
+
+
+void __RPC_STUB IMediaDet_get_StreamType_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE IMediaDet_get_StreamTypeB_Proxy(
+ IMediaDet * This,
+ /* [retval][out] */ BSTR *pVal);
+
+
+void __RPC_STUB IMediaDet_get_StreamTypeB_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE IMediaDet_get_StreamLength_Proxy(
+ IMediaDet * This,
+ /* [retval][out] */ double *pVal);
+
+
+void __RPC_STUB IMediaDet_get_StreamLength_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE IMediaDet_get_Filename_Proxy(
+ IMediaDet * This,
+ /* [retval][out] */ BSTR *pVal);
+
+
+void __RPC_STUB IMediaDet_get_Filename_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE IMediaDet_put_Filename_Proxy(
+ IMediaDet * This,
+ /* [in] */ BSTR newVal);
+
+
+void __RPC_STUB IMediaDet_put_Filename_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IMediaDet_GetBitmapBits_Proxy(
+ IMediaDet * This,
+ double StreamTime,
+ long *pBufferSize,
+ char *pBuffer,
+ long Width,
+ long Height);
+
+
+void __RPC_STUB IMediaDet_GetBitmapBits_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IMediaDet_WriteBitmapBits_Proxy(
+ IMediaDet * This,
+ double StreamTime,
+ long Width,
+ long Height,
+ BSTR Filename);
+
+
+void __RPC_STUB IMediaDet_WriteBitmapBits_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE IMediaDet_get_StreamMediaType_Proxy(
+ IMediaDet * This,
+ /* [retval][out] */ AM_MEDIA_TYPE *pVal);
+
+
+void __RPC_STUB IMediaDet_get_StreamMediaType_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IMediaDet_GetSampleGrabber_Proxy(
+ IMediaDet * This,
+ /* [out] */ ISampleGrabber **ppVal);
+
+
+void __RPC_STUB IMediaDet_GetSampleGrabber_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE IMediaDet_get_FrameRate_Proxy(
+ IMediaDet * This,
+ /* [retval][out] */ double *pVal);
+
+
+void __RPC_STUB IMediaDet_get_FrameRate_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IMediaDet_EnterBitmapGrabMode_Proxy(
+ IMediaDet * This,
+ double SeekTime);
+
+
+void __RPC_STUB IMediaDet_EnterBitmapGrabMode_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+
+#endif /* __IMediaDet_INTERFACE_DEFINED__ */
+
+
+#ifndef __IGrfCache_INTERFACE_DEFINED__
+#define __IGrfCache_INTERFACE_DEFINED__
+
+/* interface IGrfCache */
+/* [unique][helpstring][uuid][object] */
+
+
+EXTERN_C const IID IID_IGrfCache;
+
+#if defined(__cplusplus) && !defined(CINTERFACE)
+
+ MIDL_INTERFACE("AE9472BE-B0C3-11D2-8D24-00A0C9441E20")
+ IGrfCache : public IDispatch
+ {
+ public:
+ virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE AddFilter(
+ IGrfCache *ChainedCache,
+ LONGLONG ID,
+ const IBaseFilter *pFilter,
+ LPCWSTR pName) = 0;
+
+ virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE ConnectPins(
+ IGrfCache *ChainedCache,
+ LONGLONG PinID1,
+ const IPin *pPin1,
+ LONGLONG PinID2,
+ const IPin *pPin2) = 0;
+
+ virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE SetGraph(
+ const IGraphBuilder *pGraph) = 0;
+
+ virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE DoConnectionsNow( void) = 0;
+
+ };
+
+#else /* C style interface */
+
+ typedef struct IGrfCacheVtbl
+ {
+ BEGIN_INTERFACE
+
+ HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
+ IGrfCache * This,
+ /* [in] */ REFIID riid,
+ /* [iid_is][out] */ void **ppvObject);
+
+ ULONG ( STDMETHODCALLTYPE *AddRef )(
+ IGrfCache * This);
+
+ ULONG ( STDMETHODCALLTYPE *Release )(
+ IGrfCache * This);
+
+ HRESULT ( STDMETHODCALLTYPE *GetTypeInfoCount )(
+ IGrfCache * This,
+ /* [out] */ UINT *pctinfo);
+
+ HRESULT ( STDMETHODCALLTYPE *GetTypeInfo )(
+ IGrfCache * This,
+ /* [in] */ UINT iTInfo,
+ /* [in] */ LCID lcid,
+ /* [out] */ ITypeInfo **ppTInfo);
+
+ HRESULT ( STDMETHODCALLTYPE *GetIDsOfNames )(
+ IGrfCache * This,
+ /* [in] */ REFIID riid,
+ /* [size_is][in] */ LPOLESTR *rgszNames,
+ /* [in] */ UINT cNames,
+ /* [in] */ LCID lcid,
+ /* [size_is][out] */ DISPID *rgDispId);
+
+ /* [local] */ HRESULT ( STDMETHODCALLTYPE *Invoke )(
+ IGrfCache * This,
+ /* [in] */ DISPID dispIdMember,
+ /* [in] */ REFIID riid,
+ /* [in] */ LCID lcid,
+ /* [in] */ WORD wFlags,
+ /* [out][in] */ DISPPARAMS *pDispParams,
+ /* [out] */ VARIANT *pVarResult,
+ /* [out] */ EXCEPINFO *pExcepInfo,
+ /* [out] */ UINT *puArgErr);
+
+ /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *AddFilter )(
+ IGrfCache * This,
+ IGrfCache *ChainedCache,
+ LONGLONG ID,
+ const IBaseFilter *pFilter,
+ LPCWSTR pName);
+
+ /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *ConnectPins )(
+ IGrfCache * This,
+ IGrfCache *ChainedCache,
+ LONGLONG PinID1,
+ const IPin *pPin1,
+ LONGLONG PinID2,
+ const IPin *pPin2);
+
+ /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *SetGraph )(
+ IGrfCache * This,
+ const IGraphBuilder *pGraph);
+
+ /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *DoConnectionsNow )(
+ IGrfCache * This);
+
+ END_INTERFACE
+ } IGrfCacheVtbl;
+
+ interface IGrfCache
+ {
+ CONST_VTBL struct IGrfCacheVtbl *lpVtbl;
+ };
+
+
+
+#ifdef COBJMACROS
+
+
+#define IGrfCache_QueryInterface(This,riid,ppvObject) \
+ (This)->lpVtbl -> QueryInterface(This,riid,ppvObject)
+
+#define IGrfCache_AddRef(This) \
+ (This)->lpVtbl -> AddRef(This)
+
+#define IGrfCache_Release(This) \
+ (This)->lpVtbl -> Release(This)
+
+
+#define IGrfCache_GetTypeInfoCount(This,pctinfo) \
+ (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo)
+
+#define IGrfCache_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \
+ (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo)
+
+#define IGrfCache_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \
+ (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId)
+
+#define IGrfCache_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \
+ (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr)
+
+
+#define IGrfCache_AddFilter(This,ChainedCache,ID,pFilter,pName) \
+ (This)->lpVtbl -> AddFilter(This,ChainedCache,ID,pFilter,pName)
+
+#define IGrfCache_ConnectPins(This,ChainedCache,PinID1,pPin1,PinID2,pPin2) \
+ (This)->lpVtbl -> ConnectPins(This,ChainedCache,PinID1,pPin1,PinID2,pPin2)
+
+#define IGrfCache_SetGraph(This,pGraph) \
+ (This)->lpVtbl -> SetGraph(This,pGraph)
+
+#define IGrfCache_DoConnectionsNow(This) \
+ (This)->lpVtbl -> DoConnectionsNow(This)
+
+#endif /* COBJMACROS */
+
+
+#endif /* C style interface */
+
+
+
+/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IGrfCache_AddFilter_Proxy(
+ IGrfCache * This,
+ IGrfCache *ChainedCache,
+ LONGLONG ID,
+ const IBaseFilter *pFilter,
+ LPCWSTR pName);
+
+
+void __RPC_STUB IGrfCache_AddFilter_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IGrfCache_ConnectPins_Proxy(
+ IGrfCache * This,
+ IGrfCache *ChainedCache,
+ LONGLONG PinID1,
+ const IPin *pPin1,
+ LONGLONG PinID2,
+ const IPin *pPin2);
+
+
+void __RPC_STUB IGrfCache_ConnectPins_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IGrfCache_SetGraph_Proxy(
+ IGrfCache * This,
+ const IGraphBuilder *pGraph);
+
+
+void __RPC_STUB IGrfCache_SetGraph_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IGrfCache_DoConnectionsNow_Proxy(
+ IGrfCache * This);
+
+
+void __RPC_STUB IGrfCache_DoConnectionsNow_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+
+#endif /* __IGrfCache_INTERFACE_DEFINED__ */
+
+
+#ifndef __IRenderEngine_INTERFACE_DEFINED__
+#define __IRenderEngine_INTERFACE_DEFINED__
+
+/* interface IRenderEngine */
+/* [unique][helpstring][uuid][object] */
+
+
+EXTERN_C const IID IID_IRenderEngine;
+
+#if defined(__cplusplus) && !defined(CINTERFACE)
+
+ MIDL_INTERFACE("6BEE3A81-66C9-11d2-918F-00C0DF10D434")
+ IRenderEngine : public IUnknown
+ {
+ public:
+ virtual HRESULT STDMETHODCALLTYPE SetTimelineObject(
+ IAMTimeline *pTimeline) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE GetTimelineObject(
+ /* [out] */ IAMTimeline **ppTimeline) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE GetFilterGraph(
+ /* [out] */ IGraphBuilder **ppFG) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE SetFilterGraph(
+ IGraphBuilder *pFG) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE SetInterestRange(
+ REFERENCE_TIME Start,
+ REFERENCE_TIME Stop) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE SetInterestRange2(
+ double Start,
+ double Stop) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE SetRenderRange(
+ REFERENCE_TIME Start,
+ REFERENCE_TIME Stop) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE SetRenderRange2(
+ double Start,
+ double Stop) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE GetGroupOutputPin(
+ long Group,
+ /* [out] */ IPin **ppRenderPin) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE ScrapIt( void) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE RenderOutputPins( void) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE GetVendorString(
+ /* [retval][out] */ BSTR *pVendorID) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE ConnectFrontEnd( void) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE SetSourceConnectCallback(
+ IGrfCache *pCallback) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE SetDynamicReconnectLevel(
+ long Level) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE DoSmartRecompression( void) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE UseInSmartRecompressionGraph( void) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE SetSourceNameValidation(
+ BSTR FilterString,
+ IMediaLocator *pOverride,
+ LONG Flags) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE Commit( void) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE Decommit( void) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE GetCaps(
+ long Index,
+ long *pReturn) = 0;
+
+ };
+
+#else /* C style interface */
+
+ typedef struct IRenderEngineVtbl
+ {
+ BEGIN_INTERFACE
+
+ HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
+ IRenderEngine * This,
+ /* [in] */ REFIID riid,
+ /* [iid_is][out] */ void **ppvObject);
+
+ ULONG ( STDMETHODCALLTYPE *AddRef )(
+ IRenderEngine * This);
+
+ ULONG ( STDMETHODCALLTYPE *Release )(
+ IRenderEngine * This);
+
+ HRESULT ( STDMETHODCALLTYPE *SetTimelineObject )(
+ IRenderEngine * This,
+ IAMTimeline *pTimeline);
+
+ HRESULT ( STDMETHODCALLTYPE *GetTimelineObject )(
+ IRenderEngine * This,
+ /* [out] */ IAMTimeline **ppTimeline);
+
+ HRESULT ( STDMETHODCALLTYPE *GetFilterGraph )(
+ IRenderEngine * This,
+ /* [out] */ IGraphBuilder **ppFG);
+
+ HRESULT ( STDMETHODCALLTYPE *SetFilterGraph )(
+ IRenderEngine * This,
+ IGraphBuilder *pFG);
+
+ HRESULT ( STDMETHODCALLTYPE *SetInterestRange )(
+ IRenderEngine * This,
+ REFERENCE_TIME Start,
+ REFERENCE_TIME Stop);
+
+ HRESULT ( STDMETHODCALLTYPE *SetInterestRange2 )(
+ IRenderEngine * This,
+ double Start,
+ double Stop);
+
+ HRESULT ( STDMETHODCALLTYPE *SetRenderRange )(
+ IRenderEngine * This,
+ REFERENCE_TIME Start,
+ REFERENCE_TIME Stop);
+
+ HRESULT ( STDMETHODCALLTYPE *SetRenderRange2 )(
+ IRenderEngine * This,
+ double Start,
+ double Stop);
+
+ HRESULT ( STDMETHODCALLTYPE *GetGroupOutputPin )(
+ IRenderEngine * This,
+ long Group,
+ /* [out] */ IPin **ppRenderPin);
+
+ HRESULT ( STDMETHODCALLTYPE *ScrapIt )(
+ IRenderEngine * This);
+
+ HRESULT ( STDMETHODCALLTYPE *RenderOutputPins )(
+ IRenderEngine * This);
+
+ HRESULT ( STDMETHODCALLTYPE *GetVendorString )(
+ IRenderEngine * This,
+ /* [retval][out] */ BSTR *pVendorID);
+
+ HRESULT ( STDMETHODCALLTYPE *ConnectFrontEnd )(
+ IRenderEngine * This);
+
+ HRESULT ( STDMETHODCALLTYPE *SetSourceConnectCallback )(
+ IRenderEngine * This,
+ IGrfCache *pCallback);
+
+ HRESULT ( STDMETHODCALLTYPE *SetDynamicReconnectLevel )(
+ IRenderEngine * This,
+ long Level);
+
+ HRESULT ( STDMETHODCALLTYPE *DoSmartRecompression )(
+ IRenderEngine * This);
+
+ HRESULT ( STDMETHODCALLTYPE *UseInSmartRecompressionGraph )(
+ IRenderEngine * This);
+
+ HRESULT ( STDMETHODCALLTYPE *SetSourceNameValidation )(
+ IRenderEngine * This,
+ BSTR FilterString,
+ IMediaLocator *pOverride,
+ LONG Flags);
+
+ HRESULT ( STDMETHODCALLTYPE *Commit )(
+ IRenderEngine * This);
+
+ HRESULT ( STDMETHODCALLTYPE *Decommit )(
+ IRenderEngine * This);
+
+ HRESULT ( STDMETHODCALLTYPE *GetCaps )(
+ IRenderEngine * This,
+ long Index,
+ long *pReturn);
+
+ END_INTERFACE
+ } IRenderEngineVtbl;
+
+ interface IRenderEngine
+ {
+ CONST_VTBL struct IRenderEngineVtbl *lpVtbl;
+ };
+
+
+
+#ifdef COBJMACROS
+
+
+#define IRenderEngine_QueryInterface(This,riid,ppvObject) \
+ (This)->lpVtbl -> QueryInterface(This,riid,ppvObject)
+
+#define IRenderEngine_AddRef(This) \
+ (This)->lpVtbl -> AddRef(This)
+
+#define IRenderEngine_Release(This) \
+ (This)->lpVtbl -> Release(This)
+
+
+#define IRenderEngine_SetTimelineObject(This,pTimeline) \
+ (This)->lpVtbl -> SetTimelineObject(This,pTimeline)
+
+#define IRenderEngine_GetTimelineObject(This,ppTimeline) \
+ (This)->lpVtbl -> GetTimelineObject(This,ppTimeline)
+
+#define IRenderEngine_GetFilterGraph(This,ppFG) \
+ (This)->lpVtbl -> GetFilterGraph(This,ppFG)
+
+#define IRenderEngine_SetFilterGraph(This,pFG) \
+ (This)->lpVtbl -> SetFilterGraph(This,pFG)
+
+#define IRenderEngine_SetInterestRange(This,Start,Stop) \
+ (This)->lpVtbl -> SetInterestRange(This,Start,Stop)
+
+#define IRenderEngine_SetInterestRange2(This,Start,Stop) \
+ (This)->lpVtbl -> SetInterestRange2(This,Start,Stop)
+
+#define IRenderEngine_SetRenderRange(This,Start,Stop) \
+ (This)->lpVtbl -> SetRenderRange(This,Start,Stop)
+
+#define IRenderEngine_SetRenderRange2(This,Start,Stop) \
+ (This)->lpVtbl -> SetRenderRange2(This,Start,Stop)
+
+#define IRenderEngine_GetGroupOutputPin(This,Group,ppRenderPin) \
+ (This)->lpVtbl -> GetGroupOutputPin(This,Group,ppRenderPin)
+
+#define IRenderEngine_ScrapIt(This) \
+ (This)->lpVtbl -> ScrapIt(This)
+
+#define IRenderEngine_RenderOutputPins(This) \
+ (This)->lpVtbl -> RenderOutputPins(This)
+
+#define IRenderEngine_GetVendorString(This,pVendorID) \
+ (This)->lpVtbl -> GetVendorString(This,pVendorID)
+
+#define IRenderEngine_ConnectFrontEnd(This) \
+ (This)->lpVtbl -> ConnectFrontEnd(This)
+
+#define IRenderEngine_SetSourceConnectCallback(This,pCallback) \
+ (This)->lpVtbl -> SetSourceConnectCallback(This,pCallback)
+
+#define IRenderEngine_SetDynamicReconnectLevel(This,Level) \
+ (This)->lpVtbl -> SetDynamicReconnectLevel(This,Level)
+
+#define IRenderEngine_DoSmartRecompression(This) \
+ (This)->lpVtbl -> DoSmartRecompression(This)
+
+#define IRenderEngine_UseInSmartRecompressionGraph(This) \
+ (This)->lpVtbl -> UseInSmartRecompressionGraph(This)
+
+#define IRenderEngine_SetSourceNameValidation(This,FilterString,pOverride,Flags) \
+ (This)->lpVtbl -> SetSourceNameValidation(This,FilterString,pOverride,Flags)
+
+#define IRenderEngine_Commit(This) \
+ (This)->lpVtbl -> Commit(This)
+
+#define IRenderEngine_Decommit(This) \
+ (This)->lpVtbl -> Decommit(This)
+
+#define IRenderEngine_GetCaps(This,Index,pReturn) \
+ (This)->lpVtbl -> GetCaps(This,Index,pReturn)
+
+#endif /* COBJMACROS */
+
+
+#endif /* C style interface */
+
+
+
+HRESULT STDMETHODCALLTYPE IRenderEngine_SetTimelineObject_Proxy(
+ IRenderEngine * This,
+ IAMTimeline *pTimeline);
+
+
+void __RPC_STUB IRenderEngine_SetTimelineObject_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+HRESULT STDMETHODCALLTYPE IRenderEngine_GetTimelineObject_Proxy(
+ IRenderEngine * This,
+ /* [out] */ IAMTimeline **ppTimeline);
+
+
+void __RPC_STUB IRenderEngine_GetTimelineObject_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+HRESULT STDMETHODCALLTYPE IRenderEngine_GetFilterGraph_Proxy(
+ IRenderEngine * This,
+ /* [out] */ IGraphBuilder **ppFG);
+
+
+void __RPC_STUB IRenderEngine_GetFilterGraph_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+HRESULT STDMETHODCALLTYPE IRenderEngine_SetFilterGraph_Proxy(
+ IRenderEngine * This,
+ IGraphBuilder *pFG);
+
+
+void __RPC_STUB IRenderEngine_SetFilterGraph_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+HRESULT STDMETHODCALLTYPE IRenderEngine_SetInterestRange_Proxy(
+ IRenderEngine * This,
+ REFERENCE_TIME Start,
+ REFERENCE_TIME Stop);
+
+
+void __RPC_STUB IRenderEngine_SetInterestRange_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+HRESULT STDMETHODCALLTYPE IRenderEngine_SetInterestRange2_Proxy(
+ IRenderEngine * This,
+ double Start,
+ double Stop);
+
+
+void __RPC_STUB IRenderEngine_SetInterestRange2_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+HRESULT STDMETHODCALLTYPE IRenderEngine_SetRenderRange_Proxy(
+ IRenderEngine * This,
+ REFERENCE_TIME Start,
+ REFERENCE_TIME Stop);
+
+
+void __RPC_STUB IRenderEngine_SetRenderRange_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+HRESULT STDMETHODCALLTYPE IRenderEngine_SetRenderRange2_Proxy(
+ IRenderEngine * This,
+ double Start,
+ double Stop);
+
+
+void __RPC_STUB IRenderEngine_SetRenderRange2_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+HRESULT STDMETHODCALLTYPE IRenderEngine_GetGroupOutputPin_Proxy(
+ IRenderEngine * This,
+ long Group,
+ /* [out] */ IPin **ppRenderPin);
+
+
+void __RPC_STUB IRenderEngine_GetGroupOutputPin_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+HRESULT STDMETHODCALLTYPE IRenderEngine_ScrapIt_Proxy(
+ IRenderEngine * This);
+
+
+void __RPC_STUB IRenderEngine_ScrapIt_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+HRESULT STDMETHODCALLTYPE IRenderEngine_RenderOutputPins_Proxy(
+ IRenderEngine * This);
+
+
+void __RPC_STUB IRenderEngine_RenderOutputPins_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+HRESULT STDMETHODCALLTYPE IRenderEngine_GetVendorString_Proxy(
+ IRenderEngine * This,
+ /* [retval][out] */ BSTR *pVendorID);
+
+
+void __RPC_STUB IRenderEngine_GetVendorString_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+HRESULT STDMETHODCALLTYPE IRenderEngine_ConnectFrontEnd_Proxy(
+ IRenderEngine * This);
+
+
+void __RPC_STUB IRenderEngine_ConnectFrontEnd_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+HRESULT STDMETHODCALLTYPE IRenderEngine_SetSourceConnectCallback_Proxy(
+ IRenderEngine * This,
+ IGrfCache *pCallback);
+
+
+void __RPC_STUB IRenderEngine_SetSourceConnectCallback_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+HRESULT STDMETHODCALLTYPE IRenderEngine_SetDynamicReconnectLevel_Proxy(
+ IRenderEngine * This,
+ long Level);
+
+
+void __RPC_STUB IRenderEngine_SetDynamicReconnectLevel_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+HRESULT STDMETHODCALLTYPE IRenderEngine_DoSmartRecompression_Proxy(
+ IRenderEngine * This);
+
+
+void __RPC_STUB IRenderEngine_DoSmartRecompression_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+HRESULT STDMETHODCALLTYPE IRenderEngine_UseInSmartRecompressionGraph_Proxy(
+ IRenderEngine * This);
+
+
+void __RPC_STUB IRenderEngine_UseInSmartRecompressionGraph_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+HRESULT STDMETHODCALLTYPE IRenderEngine_SetSourceNameValidation_Proxy(
+ IRenderEngine * This,
+ BSTR FilterString,
+ IMediaLocator *pOverride,
+ LONG Flags);
+
+
+void __RPC_STUB IRenderEngine_SetSourceNameValidation_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+HRESULT STDMETHODCALLTYPE IRenderEngine_Commit_Proxy(
+ IRenderEngine * This);
+
+
+void __RPC_STUB IRenderEngine_Commit_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+HRESULT STDMETHODCALLTYPE IRenderEngine_Decommit_Proxy(
+ IRenderEngine * This);
+
+
+void __RPC_STUB IRenderEngine_Decommit_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+HRESULT STDMETHODCALLTYPE IRenderEngine_GetCaps_Proxy(
+ IRenderEngine * This,
+ long Index,
+ long *pReturn);
+
+
+void __RPC_STUB IRenderEngine_GetCaps_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+
+#endif /* __IRenderEngine_INTERFACE_DEFINED__ */
+
+
+#ifndef __IFindCompressorCB_INTERFACE_DEFINED__
+#define __IFindCompressorCB_INTERFACE_DEFINED__
+
+/* interface IFindCompressorCB */
+/* [unique][helpstring][uuid][object] */
+
+
+EXTERN_C const IID IID_IFindCompressorCB;
+
+#if defined(__cplusplus) && !defined(CINTERFACE)
+
+ MIDL_INTERFACE("F03FA8DE-879A-4d59-9B2C-26BB1CF83461")
+ IFindCompressorCB : public IUnknown
+ {
+ public:
+ virtual HRESULT STDMETHODCALLTYPE GetCompressor(
+ AM_MEDIA_TYPE *pType,
+ AM_MEDIA_TYPE *pCompType,
+ /* [out] */ IBaseFilter **ppFilter) = 0;
+
+ };
+
+#else /* C style interface */
+
+ typedef struct IFindCompressorCBVtbl
+ {
+ BEGIN_INTERFACE
+
+ HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
+ IFindCompressorCB * This,
+ /* [in] */ REFIID riid,
+ /* [iid_is][out] */ void **ppvObject);
+
+ ULONG ( STDMETHODCALLTYPE *AddRef )(
+ IFindCompressorCB * This);
+
+ ULONG ( STDMETHODCALLTYPE *Release )(
+ IFindCompressorCB * This);
+
+ HRESULT ( STDMETHODCALLTYPE *GetCompressor )(
+ IFindCompressorCB * This,
+ AM_MEDIA_TYPE *pType,
+ AM_MEDIA_TYPE *pCompType,
+ /* [out] */ IBaseFilter **ppFilter);
+
+ END_INTERFACE
+ } IFindCompressorCBVtbl;
+
+ interface IFindCompressorCB
+ {
+ CONST_VTBL struct IFindCompressorCBVtbl *lpVtbl;
+ };
+
+
+
+#ifdef COBJMACROS
+
+
+#define IFindCompressorCB_QueryInterface(This,riid,ppvObject) \
+ (This)->lpVtbl -> QueryInterface(This,riid,ppvObject)
+
+#define IFindCompressorCB_AddRef(This) \
+ (This)->lpVtbl -> AddRef(This)
+
+#define IFindCompressorCB_Release(This) \
+ (This)->lpVtbl -> Release(This)
+
+
+#define IFindCompressorCB_GetCompressor(This,pType,pCompType,ppFilter) \
+ (This)->lpVtbl -> GetCompressor(This,pType,pCompType,ppFilter)
+
+#endif /* COBJMACROS */
+
+
+#endif /* C style interface */
+
+
+
+HRESULT STDMETHODCALLTYPE IFindCompressorCB_GetCompressor_Proxy(
+ IFindCompressorCB * This,
+ AM_MEDIA_TYPE *pType,
+ AM_MEDIA_TYPE *pCompType,
+ /* [out] */ IBaseFilter **ppFilter);
+
+
+void __RPC_STUB IFindCompressorCB_GetCompressor_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+
+#endif /* __IFindCompressorCB_INTERFACE_DEFINED__ */
+
+
+#ifndef __ISmartRenderEngine_INTERFACE_DEFINED__
+#define __ISmartRenderEngine_INTERFACE_DEFINED__
+
+/* interface ISmartRenderEngine */
+/* [unique][helpstring][uuid][object] */
+
+
+EXTERN_C const IID IID_ISmartRenderEngine;
+
+#if defined(__cplusplus) && !defined(CINTERFACE)
+
+ MIDL_INTERFACE("F03FA8CE-879A-4d59-9B2C-26BB1CF83461")
+ ISmartRenderEngine : public IUnknown
+ {
+ public:
+ virtual HRESULT STDMETHODCALLTYPE SetGroupCompressor(
+ long Group,
+ IBaseFilter *pCompressor) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE GetGroupCompressor(
+ long Group,
+ IBaseFilter **pCompressor) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE SetFindCompressorCB(
+ IFindCompressorCB *pCallback) = 0;
+
+ };
+
+#else /* C style interface */
+
+ typedef struct ISmartRenderEngineVtbl
+ {
+ BEGIN_INTERFACE
+
+ HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
+ ISmartRenderEngine * This,
+ /* [in] */ REFIID riid,
+ /* [iid_is][out] */ void **ppvObject);
+
+ ULONG ( STDMETHODCALLTYPE *AddRef )(
+ ISmartRenderEngine * This);
+
+ ULONG ( STDMETHODCALLTYPE *Release )(
+ ISmartRenderEngine * This);
+
+ HRESULT ( STDMETHODCALLTYPE *SetGroupCompressor )(
+ ISmartRenderEngine * This,
+ long Group,
+ IBaseFilter *pCompressor);
+
+ HRESULT ( STDMETHODCALLTYPE *GetGroupCompressor )(
+ ISmartRenderEngine * This,
+ long Group,
+ IBaseFilter **pCompressor);
+
+ HRESULT ( STDMETHODCALLTYPE *SetFindCompressorCB )(
+ ISmartRenderEngine * This,
+ IFindCompressorCB *pCallback);
+
+ END_INTERFACE
+ } ISmartRenderEngineVtbl;
+
+ interface ISmartRenderEngine
+ {
+ CONST_VTBL struct ISmartRenderEngineVtbl *lpVtbl;
+ };
+
+
+
+#ifdef COBJMACROS
+
+
+#define ISmartRenderEngine_QueryInterface(This,riid,ppvObject) \
+ (This)->lpVtbl -> QueryInterface(This,riid,ppvObject)
+
+#define ISmartRenderEngine_AddRef(This) \
+ (This)->lpVtbl -> AddRef(This)
+
+#define ISmartRenderEngine_Release(This) \
+ (This)->lpVtbl -> Release(This)
+
+
+#define ISmartRenderEngine_SetGroupCompressor(This,Group,pCompressor) \
+ (This)->lpVtbl -> SetGroupCompressor(This,Group,pCompressor)
+
+#define ISmartRenderEngine_GetGroupCompressor(This,Group,pCompressor) \
+ (This)->lpVtbl -> GetGroupCompressor(This,Group,pCompressor)
+
+#define ISmartRenderEngine_SetFindCompressorCB(This,pCallback) \
+ (This)->lpVtbl -> SetFindCompressorCB(This,pCallback)
+
+#endif /* COBJMACROS */
+
+
+#endif /* C style interface */
+
+
+
+HRESULT STDMETHODCALLTYPE ISmartRenderEngine_SetGroupCompressor_Proxy(
+ ISmartRenderEngine * This,
+ long Group,
+ IBaseFilter *pCompressor);
+
+
+void __RPC_STUB ISmartRenderEngine_SetGroupCompressor_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+HRESULT STDMETHODCALLTYPE ISmartRenderEngine_GetGroupCompressor_Proxy(
+ ISmartRenderEngine * This,
+ long Group,
+ IBaseFilter **pCompressor);
+
+
+void __RPC_STUB ISmartRenderEngine_GetGroupCompressor_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+HRESULT STDMETHODCALLTYPE ISmartRenderEngine_SetFindCompressorCB_Proxy(
+ ISmartRenderEngine * This,
+ IFindCompressorCB *pCallback);
+
+
+void __RPC_STUB ISmartRenderEngine_SetFindCompressorCB_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+
+#endif /* __ISmartRenderEngine_INTERFACE_DEFINED__ */
+
+
+#ifndef __IAMTimelineObj_INTERFACE_DEFINED__
+#define __IAMTimelineObj_INTERFACE_DEFINED__
+
+/* interface IAMTimelineObj */
+/* [unique][helpstring][uuid][local][object] */
+
+
+EXTERN_C const IID IID_IAMTimelineObj;
+
+#if defined(__cplusplus) && !defined(CINTERFACE)
+
+ MIDL_INTERFACE("78530B77-61F9-11D2-8CAD-00A024580902")
+ IAMTimelineObj : public IUnknown
+ {
+ public:
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetStartStop(
+ REFERENCE_TIME *pStart,
+ REFERENCE_TIME *pStop) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetStartStop2(
+ REFTIME *pStart,
+ REFTIME *pStop) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE FixTimes(
+ REFERENCE_TIME *pStart,
+ REFERENCE_TIME *pStop) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE FixTimes2(
+ REFTIME *pStart,
+ REFTIME *pStop) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetStartStop(
+ REFERENCE_TIME Start,
+ REFERENCE_TIME Stop) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetStartStop2(
+ REFTIME Start,
+ REFTIME Stop) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetPropertySetter(
+ /* [retval][out] */ IPropertySetter **pVal) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetPropertySetter(
+ IPropertySetter *newVal) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetSubObject(
+ /* [retval][out] */ IUnknown **pVal) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetSubObject(
+ IUnknown *newVal) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetSubObjectGUID(
+ GUID newVal) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetSubObjectGUIDB(
+ BSTR newVal) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetSubObjectGUID(
+ GUID *pVal) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetSubObjectGUIDB(
+ /* [retval][out] */ BSTR *pVal) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetSubObjectLoaded(
+ BOOL *pVal) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetTimelineType(
+ TIMELINE_MAJOR_TYPE *pVal) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetTimelineType(
+ TIMELINE_MAJOR_TYPE newVal) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetUserID(
+ long *pVal) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetUserID(
+ long newVal) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetGenID(
+ long *pVal) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetUserName(
+ /* [retval][out] */ BSTR *pVal) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetUserName(
+ BSTR newVal) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetUserData(
+ BYTE *pData,
+ long *pSize) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetUserData(
+ BYTE *pData,
+ long Size) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetMuted(
+ BOOL *pVal) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetMuted(
+ BOOL newVal) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetLocked(
+ BOOL *pVal) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetLocked(
+ BOOL newVal) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetDirtyRange(
+ REFERENCE_TIME *pStart,
+ REFERENCE_TIME *pStop) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetDirtyRange2(
+ REFTIME *pStart,
+ REFTIME *pStop) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetDirtyRange(
+ REFERENCE_TIME Start,
+ REFERENCE_TIME Stop) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetDirtyRange2(
+ REFTIME Start,
+ REFTIME Stop) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE ClearDirty( void) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE Remove( void) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE RemoveAll( void) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE GetTimelineNoRef(
+ IAMTimeline **ppResult) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE GetGroupIBelongTo(
+ /* [out] */ IAMTimelineGroup **ppGroup) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE GetEmbedDepth(
+ long *pVal) = 0;
+
+ };
+
+#else /* C style interface */
+
+ typedef struct IAMTimelineObjVtbl
+ {
+ BEGIN_INTERFACE
+
+ HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
+ IAMTimelineObj * This,
+ /* [in] */ REFIID riid,
+ /* [iid_is][out] */ void **ppvObject);
+
+ ULONG ( STDMETHODCALLTYPE *AddRef )(
+ IAMTimelineObj * This);
+
+ ULONG ( STDMETHODCALLTYPE *Release )(
+ IAMTimelineObj * This);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetStartStop )(
+ IAMTimelineObj * This,
+ REFERENCE_TIME *pStart,
+ REFERENCE_TIME *pStop);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetStartStop2 )(
+ IAMTimelineObj * This,
+ REFTIME *pStart,
+ REFTIME *pStop);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *FixTimes )(
+ IAMTimelineObj * This,
+ REFERENCE_TIME *pStart,
+ REFERENCE_TIME *pStop);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *FixTimes2 )(
+ IAMTimelineObj * This,
+ REFTIME *pStart,
+ REFTIME *pStop);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *SetStartStop )(
+ IAMTimelineObj * This,
+ REFERENCE_TIME Start,
+ REFERENCE_TIME Stop);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *SetStartStop2 )(
+ IAMTimelineObj * This,
+ REFTIME Start,
+ REFTIME Stop);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetPropertySetter )(
+ IAMTimelineObj * This,
+ /* [retval][out] */ IPropertySetter **pVal);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *SetPropertySetter )(
+ IAMTimelineObj * This,
+ IPropertySetter *newVal);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetSubObject )(
+ IAMTimelineObj * This,
+ /* [retval][out] */ IUnknown **pVal);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *SetSubObject )(
+ IAMTimelineObj * This,
+ IUnknown *newVal);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *SetSubObjectGUID )(
+ IAMTimelineObj * This,
+ GUID newVal);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *SetSubObjectGUIDB )(
+ IAMTimelineObj * This,
+ BSTR newVal);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetSubObjectGUID )(
+ IAMTimelineObj * This,
+ GUID *pVal);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetSubObjectGUIDB )(
+ IAMTimelineObj * This,
+ /* [retval][out] */ BSTR *pVal);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetSubObjectLoaded )(
+ IAMTimelineObj * This,
+ BOOL *pVal);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetTimelineType )(
+ IAMTimelineObj * This,
+ TIMELINE_MAJOR_TYPE *pVal);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *SetTimelineType )(
+ IAMTimelineObj * This,
+ TIMELINE_MAJOR_TYPE newVal);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetUserID )(
+ IAMTimelineObj * This,
+ long *pVal);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *SetUserID )(
+ IAMTimelineObj * This,
+ long newVal);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetGenID )(
+ IAMTimelineObj * This,
+ long *pVal);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetUserName )(
+ IAMTimelineObj * This,
+ /* [retval][out] */ BSTR *pVal);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *SetUserName )(
+ IAMTimelineObj * This,
+ BSTR newVal);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetUserData )(
+ IAMTimelineObj * This,
+ BYTE *pData,
+ long *pSize);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *SetUserData )(
+ IAMTimelineObj * This,
+ BYTE *pData,
+ long Size);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetMuted )(
+ IAMTimelineObj * This,
+ BOOL *pVal);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *SetMuted )(
+ IAMTimelineObj * This,
+ BOOL newVal);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetLocked )(
+ IAMTimelineObj * This,
+ BOOL *pVal);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *SetLocked )(
+ IAMTimelineObj * This,
+ BOOL newVal);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetDirtyRange )(
+ IAMTimelineObj * This,
+ REFERENCE_TIME *pStart,
+ REFERENCE_TIME *pStop);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetDirtyRange2 )(
+ IAMTimelineObj * This,
+ REFTIME *pStart,
+ REFTIME *pStop);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *SetDirtyRange )(
+ IAMTimelineObj * This,
+ REFERENCE_TIME Start,
+ REFERENCE_TIME Stop);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *SetDirtyRange2 )(
+ IAMTimelineObj * This,
+ REFTIME Start,
+ REFTIME Stop);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *ClearDirty )(
+ IAMTimelineObj * This);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *Remove )(
+ IAMTimelineObj * This);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *RemoveAll )(
+ IAMTimelineObj * This);
+
+ HRESULT ( STDMETHODCALLTYPE *GetTimelineNoRef )(
+ IAMTimelineObj * This,
+ IAMTimeline **ppResult);
+
+ HRESULT ( STDMETHODCALLTYPE *GetGroupIBelongTo )(
+ IAMTimelineObj * This,
+ /* [out] */ IAMTimelineGroup **ppGroup);
+
+ HRESULT ( STDMETHODCALLTYPE *GetEmbedDepth )(
+ IAMTimelineObj * This,
+ long *pVal);
+
+ END_INTERFACE
+ } IAMTimelineObjVtbl;
+
+ interface IAMTimelineObj
+ {
+ CONST_VTBL struct IAMTimelineObjVtbl *lpVtbl;
+ };
+
+
+
+#ifdef COBJMACROS
+
+
+#define IAMTimelineObj_QueryInterface(This,riid,ppvObject) \
+ (This)->lpVtbl -> QueryInterface(This,riid,ppvObject)
+
+#define IAMTimelineObj_AddRef(This) \
+ (This)->lpVtbl -> AddRef(This)
+
+#define IAMTimelineObj_Release(This) \
+ (This)->lpVtbl -> Release(This)
+
+
+#define IAMTimelineObj_GetStartStop(This,pStart,pStop) \
+ (This)->lpVtbl -> GetStartStop(This,pStart,pStop)
+
+#define IAMTimelineObj_GetStartStop2(This,pStart,pStop) \
+ (This)->lpVtbl -> GetStartStop2(This,pStart,pStop)
+
+#define IAMTimelineObj_FixTimes(This,pStart,pStop) \
+ (This)->lpVtbl -> FixTimes(This,pStart,pStop)
+
+#define IAMTimelineObj_FixTimes2(This,pStart,pStop) \
+ (This)->lpVtbl -> FixTimes2(This,pStart,pStop)
+
+#define IAMTimelineObj_SetStartStop(This,Start,Stop) \
+ (This)->lpVtbl -> SetStartStop(This,Start,Stop)
+
+#define IAMTimelineObj_SetStartStop2(This,Start,Stop) \
+ (This)->lpVtbl -> SetStartStop2(This,Start,Stop)
+
+#define IAMTimelineObj_GetPropertySetter(This,pVal) \
+ (This)->lpVtbl -> GetPropertySetter(This,pVal)
+
+#define IAMTimelineObj_SetPropertySetter(This,newVal) \
+ (This)->lpVtbl -> SetPropertySetter(This,newVal)
+
+#define IAMTimelineObj_GetSubObject(This,pVal) \
+ (This)->lpVtbl -> GetSubObject(This,pVal)
+
+#define IAMTimelineObj_SetSubObject(This,newVal) \
+ (This)->lpVtbl -> SetSubObject(This,newVal)
+
+#define IAMTimelineObj_SetSubObjectGUID(This,newVal) \
+ (This)->lpVtbl -> SetSubObjectGUID(This,newVal)
+
+#define IAMTimelineObj_SetSubObjectGUIDB(This,newVal) \
+ (This)->lpVtbl -> SetSubObjectGUIDB(This,newVal)
+
+#define IAMTimelineObj_GetSubObjectGUID(This,pVal) \
+ (This)->lpVtbl -> GetSubObjectGUID(This,pVal)
+
+#define IAMTimelineObj_GetSubObjectGUIDB(This,pVal) \
+ (This)->lpVtbl -> GetSubObjectGUIDB(This,pVal)
+
+#define IAMTimelineObj_GetSubObjectLoaded(This,pVal) \
+ (This)->lpVtbl -> GetSubObjectLoaded(This,pVal)
+
+#define IAMTimelineObj_GetTimelineType(This,pVal) \
+ (This)->lpVtbl -> GetTimelineType(This,pVal)
+
+#define IAMTimelineObj_SetTimelineType(This,newVal) \
+ (This)->lpVtbl -> SetTimelineType(This,newVal)
+
+#define IAMTimelineObj_GetUserID(This,pVal) \
+ (This)->lpVtbl -> GetUserID(This,pVal)
+
+#define IAMTimelineObj_SetUserID(This,newVal) \
+ (This)->lpVtbl -> SetUserID(This,newVal)
+
+#define IAMTimelineObj_GetGenID(This,pVal) \
+ (This)->lpVtbl -> GetGenID(This,pVal)
+
+#define IAMTimelineObj_GetUserName(This,pVal) \
+ (This)->lpVtbl -> GetUserName(This,pVal)
+
+#define IAMTimelineObj_SetUserName(This,newVal) \
+ (This)->lpVtbl -> SetUserName(This,newVal)
+
+#define IAMTimelineObj_GetUserData(This,pData,pSize) \
+ (This)->lpVtbl -> GetUserData(This,pData,pSize)
+
+#define IAMTimelineObj_SetUserData(This,pData,Size) \
+ (This)->lpVtbl -> SetUserData(This,pData,Size)
+
+#define IAMTimelineObj_GetMuted(This,pVal) \
+ (This)->lpVtbl -> GetMuted(This,pVal)
+
+#define IAMTimelineObj_SetMuted(This,newVal) \
+ (This)->lpVtbl -> SetMuted(This,newVal)
+
+#define IAMTimelineObj_GetLocked(This,pVal) \
+ (This)->lpVtbl -> GetLocked(This,pVal)
+
+#define IAMTimelineObj_SetLocked(This,newVal) \
+ (This)->lpVtbl -> SetLocked(This,newVal)
+
+#define IAMTimelineObj_GetDirtyRange(This,pStart,pStop) \
+ (This)->lpVtbl -> GetDirtyRange(This,pStart,pStop)
+
+#define IAMTimelineObj_GetDirtyRange2(This,pStart,pStop) \
+ (This)->lpVtbl -> GetDirtyRange2(This,pStart,pStop)
+
+#define IAMTimelineObj_SetDirtyRange(This,Start,Stop) \
+ (This)->lpVtbl -> SetDirtyRange(This,Start,Stop)
+
+#define IAMTimelineObj_SetDirtyRange2(This,Start,Stop) \
+ (This)->lpVtbl -> SetDirtyRange2(This,Start,Stop)
+
+#define IAMTimelineObj_ClearDirty(This) \
+ (This)->lpVtbl -> ClearDirty(This)
+
+#define IAMTimelineObj_Remove(This) \
+ (This)->lpVtbl -> Remove(This)
+
+#define IAMTimelineObj_RemoveAll(This) \
+ (This)->lpVtbl -> RemoveAll(This)
+
+#define IAMTimelineObj_GetTimelineNoRef(This,ppResult) \
+ (This)->lpVtbl -> GetTimelineNoRef(This,ppResult)
+
+#define IAMTimelineObj_GetGroupIBelongTo(This,ppGroup) \
+ (This)->lpVtbl -> GetGroupIBelongTo(This,ppGroup)
+
+#define IAMTimelineObj_GetEmbedDepth(This,pVal) \
+ (This)->lpVtbl -> GetEmbedDepth(This,pVal)
+
+#endif /* COBJMACROS */
+
+
+#endif /* C style interface */
+
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineObj_GetStartStop_Proxy(
+ IAMTimelineObj * This,
+ REFERENCE_TIME *pStart,
+ REFERENCE_TIME *pStop);
+
+
+void __RPC_STUB IAMTimelineObj_GetStartStop_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineObj_GetStartStop2_Proxy(
+ IAMTimelineObj * This,
+ REFTIME *pStart,
+ REFTIME *pStop);
+
+
+void __RPC_STUB IAMTimelineObj_GetStartStop2_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineObj_FixTimes_Proxy(
+ IAMTimelineObj * This,
+ REFERENCE_TIME *pStart,
+ REFERENCE_TIME *pStop);
+
+
+void __RPC_STUB IAMTimelineObj_FixTimes_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineObj_FixTimes2_Proxy(
+ IAMTimelineObj * This,
+ REFTIME *pStart,
+ REFTIME *pStop);
+
+
+void __RPC_STUB IAMTimelineObj_FixTimes2_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineObj_SetStartStop_Proxy(
+ IAMTimelineObj * This,
+ REFERENCE_TIME Start,
+ REFERENCE_TIME Stop);
+
+
+void __RPC_STUB IAMTimelineObj_SetStartStop_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineObj_SetStartStop2_Proxy(
+ IAMTimelineObj * This,
+ REFTIME Start,
+ REFTIME Stop);
+
+
+void __RPC_STUB IAMTimelineObj_SetStartStop2_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineObj_GetPropertySetter_Proxy(
+ IAMTimelineObj * This,
+ /* [retval][out] */ IPropertySetter **pVal);
+
+
+void __RPC_STUB IAMTimelineObj_GetPropertySetter_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineObj_SetPropertySetter_Proxy(
+ IAMTimelineObj * This,
+ IPropertySetter *newVal);
+
+
+void __RPC_STUB IAMTimelineObj_SetPropertySetter_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineObj_GetSubObject_Proxy(
+ IAMTimelineObj * This,
+ /* [retval][out] */ IUnknown **pVal);
+
+
+void __RPC_STUB IAMTimelineObj_GetSubObject_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineObj_SetSubObject_Proxy(
+ IAMTimelineObj * This,
+ IUnknown *newVal);
+
+
+void __RPC_STUB IAMTimelineObj_SetSubObject_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineObj_SetSubObjectGUID_Proxy(
+ IAMTimelineObj * This,
+ GUID newVal);
+
+
+void __RPC_STUB IAMTimelineObj_SetSubObjectGUID_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineObj_SetSubObjectGUIDB_Proxy(
+ IAMTimelineObj * This,
+ BSTR newVal);
+
+
+void __RPC_STUB IAMTimelineObj_SetSubObjectGUIDB_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineObj_GetSubObjectGUID_Proxy(
+ IAMTimelineObj * This,
+ GUID *pVal);
+
+
+void __RPC_STUB IAMTimelineObj_GetSubObjectGUID_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineObj_GetSubObjectGUIDB_Proxy(
+ IAMTimelineObj * This,
+ /* [retval][out] */ BSTR *pVal);
+
+
+void __RPC_STUB IAMTimelineObj_GetSubObjectGUIDB_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineObj_GetSubObjectLoaded_Proxy(
+ IAMTimelineObj * This,
+ BOOL *pVal);
+
+
+void __RPC_STUB IAMTimelineObj_GetSubObjectLoaded_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineObj_GetTimelineType_Proxy(
+ IAMTimelineObj * This,
+ TIMELINE_MAJOR_TYPE *pVal);
+
+
+void __RPC_STUB IAMTimelineObj_GetTimelineType_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineObj_SetTimelineType_Proxy(
+ IAMTimelineObj * This,
+ TIMELINE_MAJOR_TYPE newVal);
+
+
+void __RPC_STUB IAMTimelineObj_SetTimelineType_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineObj_GetUserID_Proxy(
+ IAMTimelineObj * This,
+ long *pVal);
+
+
+void __RPC_STUB IAMTimelineObj_GetUserID_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineObj_SetUserID_Proxy(
+ IAMTimelineObj * This,
+ long newVal);
+
+
+void __RPC_STUB IAMTimelineObj_SetUserID_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineObj_GetGenID_Proxy(
+ IAMTimelineObj * This,
+ long *pVal);
+
+
+void __RPC_STUB IAMTimelineObj_GetGenID_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineObj_GetUserName_Proxy(
+ IAMTimelineObj * This,
+ /* [retval][out] */ BSTR *pVal);
+
+
+void __RPC_STUB IAMTimelineObj_GetUserName_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineObj_SetUserName_Proxy(
+ IAMTimelineObj * This,
+ BSTR newVal);
+
+
+void __RPC_STUB IAMTimelineObj_SetUserName_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineObj_GetUserData_Proxy(
+ IAMTimelineObj * This,
+ BYTE *pData,
+ long *pSize);
+
+
+void __RPC_STUB IAMTimelineObj_GetUserData_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineObj_SetUserData_Proxy(
+ IAMTimelineObj * This,
+ BYTE *pData,
+ long Size);
+
+
+void __RPC_STUB IAMTimelineObj_SetUserData_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineObj_GetMuted_Proxy(
+ IAMTimelineObj * This,
+ BOOL *pVal);
+
+
+void __RPC_STUB IAMTimelineObj_GetMuted_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineObj_SetMuted_Proxy(
+ IAMTimelineObj * This,
+ BOOL newVal);
+
+
+void __RPC_STUB IAMTimelineObj_SetMuted_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineObj_GetLocked_Proxy(
+ IAMTimelineObj * This,
+ BOOL *pVal);
+
+
+void __RPC_STUB IAMTimelineObj_GetLocked_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineObj_SetLocked_Proxy(
+ IAMTimelineObj * This,
+ BOOL newVal);
+
+
+void __RPC_STUB IAMTimelineObj_SetLocked_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineObj_GetDirtyRange_Proxy(
+ IAMTimelineObj * This,
+ REFERENCE_TIME *pStart,
+ REFERENCE_TIME *pStop);
+
+
+void __RPC_STUB IAMTimelineObj_GetDirtyRange_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineObj_GetDirtyRange2_Proxy(
+ IAMTimelineObj * This,
+ REFTIME *pStart,
+ REFTIME *pStop);
+
+
+void __RPC_STUB IAMTimelineObj_GetDirtyRange2_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineObj_SetDirtyRange_Proxy(
+ IAMTimelineObj * This,
+ REFERENCE_TIME Start,
+ REFERENCE_TIME Stop);
+
+
+void __RPC_STUB IAMTimelineObj_SetDirtyRange_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineObj_SetDirtyRange2_Proxy(
+ IAMTimelineObj * This,
+ REFTIME Start,
+ REFTIME Stop);
+
+
+void __RPC_STUB IAMTimelineObj_SetDirtyRange2_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineObj_ClearDirty_Proxy(
+ IAMTimelineObj * This);
+
+
+void __RPC_STUB IAMTimelineObj_ClearDirty_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineObj_Remove_Proxy(
+ IAMTimelineObj * This);
+
+
+void __RPC_STUB IAMTimelineObj_Remove_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineObj_RemoveAll_Proxy(
+ IAMTimelineObj * This);
+
+
+void __RPC_STUB IAMTimelineObj_RemoveAll_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+HRESULT STDMETHODCALLTYPE IAMTimelineObj_GetTimelineNoRef_Proxy(
+ IAMTimelineObj * This,
+ IAMTimeline **ppResult);
+
+
+void __RPC_STUB IAMTimelineObj_GetTimelineNoRef_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+HRESULT STDMETHODCALLTYPE IAMTimelineObj_GetGroupIBelongTo_Proxy(
+ IAMTimelineObj * This,
+ /* [out] */ IAMTimelineGroup **ppGroup);
+
+
+void __RPC_STUB IAMTimelineObj_GetGroupIBelongTo_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+HRESULT STDMETHODCALLTYPE IAMTimelineObj_GetEmbedDepth_Proxy(
+ IAMTimelineObj * This,
+ long *pVal);
+
+
+void __RPC_STUB IAMTimelineObj_GetEmbedDepth_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+
+#endif /* __IAMTimelineObj_INTERFACE_DEFINED__ */
+
+
+#ifndef __IAMTimelineEffectable_INTERFACE_DEFINED__
+#define __IAMTimelineEffectable_INTERFACE_DEFINED__
+
+/* interface IAMTimelineEffectable */
+/* [unique][helpstring][uuid][object] */
+
+
+EXTERN_C const IID IID_IAMTimelineEffectable;
+
+#if defined(__cplusplus) && !defined(CINTERFACE)
+
+ MIDL_INTERFACE("EAE58537-622E-11d2-8CAD-00A024580902")
+ IAMTimelineEffectable : public IUnknown
+ {
+ public:
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE EffectInsBefore(
+ IAMTimelineObj *pFX,
+ long priority) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE EffectSwapPriorities(
+ long PriorityA,
+ long PriorityB) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE EffectGetCount(
+ long *pCount) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetEffect(
+ /* [out] */ IAMTimelineObj **ppFx,
+ long Which) = 0;
+
+ };
+
+#else /* C style interface */
+
+ typedef struct IAMTimelineEffectableVtbl
+ {
+ BEGIN_INTERFACE
+
+ HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
+ IAMTimelineEffectable * This,
+ /* [in] */ REFIID riid,
+ /* [iid_is][out] */ void **ppvObject);
+
+ ULONG ( STDMETHODCALLTYPE *AddRef )(
+ IAMTimelineEffectable * This);
+
+ ULONG ( STDMETHODCALLTYPE *Release )(
+ IAMTimelineEffectable * This);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *EffectInsBefore )(
+ IAMTimelineEffectable * This,
+ IAMTimelineObj *pFX,
+ long priority);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *EffectSwapPriorities )(
+ IAMTimelineEffectable * This,
+ long PriorityA,
+ long PriorityB);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *EffectGetCount )(
+ IAMTimelineEffectable * This,
+ long *pCount);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetEffect )(
+ IAMTimelineEffectable * This,
+ /* [out] */ IAMTimelineObj **ppFx,
+ long Which);
+
+ END_INTERFACE
+ } IAMTimelineEffectableVtbl;
+
+ interface IAMTimelineEffectable
+ {
+ CONST_VTBL struct IAMTimelineEffectableVtbl *lpVtbl;
+ };
+
+
+
+#ifdef COBJMACROS
+
+
+#define IAMTimelineEffectable_QueryInterface(This,riid,ppvObject) \
+ (This)->lpVtbl -> QueryInterface(This,riid,ppvObject)
+
+#define IAMTimelineEffectable_AddRef(This) \
+ (This)->lpVtbl -> AddRef(This)
+
+#define IAMTimelineEffectable_Release(This) \
+ (This)->lpVtbl -> Release(This)
+
+
+#define IAMTimelineEffectable_EffectInsBefore(This,pFX,priority) \
+ (This)->lpVtbl -> EffectInsBefore(This,pFX,priority)
+
+#define IAMTimelineEffectable_EffectSwapPriorities(This,PriorityA,PriorityB) \
+ (This)->lpVtbl -> EffectSwapPriorities(This,PriorityA,PriorityB)
+
+#define IAMTimelineEffectable_EffectGetCount(This,pCount) \
+ (This)->lpVtbl -> EffectGetCount(This,pCount)
+
+#define IAMTimelineEffectable_GetEffect(This,ppFx,Which) \
+ (This)->lpVtbl -> GetEffect(This,ppFx,Which)
+
+#endif /* COBJMACROS */
+
+
+#endif /* C style interface */
+
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineEffectable_EffectInsBefore_Proxy(
+ IAMTimelineEffectable * This,
+ IAMTimelineObj *pFX,
+ long priority);
+
+
+void __RPC_STUB IAMTimelineEffectable_EffectInsBefore_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineEffectable_EffectSwapPriorities_Proxy(
+ IAMTimelineEffectable * This,
+ long PriorityA,
+ long PriorityB);
+
+
+void __RPC_STUB IAMTimelineEffectable_EffectSwapPriorities_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineEffectable_EffectGetCount_Proxy(
+ IAMTimelineEffectable * This,
+ long *pCount);
+
+
+void __RPC_STUB IAMTimelineEffectable_EffectGetCount_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineEffectable_GetEffect_Proxy(
+ IAMTimelineEffectable * This,
+ /* [out] */ IAMTimelineObj **ppFx,
+ long Which);
+
+
+void __RPC_STUB IAMTimelineEffectable_GetEffect_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+
+#endif /* __IAMTimelineEffectable_INTERFACE_DEFINED__ */
+
+
+#ifndef __IAMTimelineEffect_INTERFACE_DEFINED__
+#define __IAMTimelineEffect_INTERFACE_DEFINED__
+
+/* interface IAMTimelineEffect */
+/* [unique][helpstring][uuid][object] */
+
+
+EXTERN_C const IID IID_IAMTimelineEffect;
+
+#if defined(__cplusplus) && !defined(CINTERFACE)
+
+ MIDL_INTERFACE("BCE0C264-622D-11d2-8CAD-00A024580902")
+ IAMTimelineEffect : public IUnknown
+ {
+ public:
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE EffectGetPriority(
+ long *pVal) = 0;
+
+ };
+
+#else /* C style interface */
+
+ typedef struct IAMTimelineEffectVtbl
+ {
+ BEGIN_INTERFACE
+
+ HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
+ IAMTimelineEffect * This,
+ /* [in] */ REFIID riid,
+ /* [iid_is][out] */ void **ppvObject);
+
+ ULONG ( STDMETHODCALLTYPE *AddRef )(
+ IAMTimelineEffect * This);
+
+ ULONG ( STDMETHODCALLTYPE *Release )(
+ IAMTimelineEffect * This);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *EffectGetPriority )(
+ IAMTimelineEffect * This,
+ long *pVal);
+
+ END_INTERFACE
+ } IAMTimelineEffectVtbl;
+
+ interface IAMTimelineEffect
+ {
+ CONST_VTBL struct IAMTimelineEffectVtbl *lpVtbl;
+ };
+
+
+
+#ifdef COBJMACROS
+
+
+#define IAMTimelineEffect_QueryInterface(This,riid,ppvObject) \
+ (This)->lpVtbl -> QueryInterface(This,riid,ppvObject)
+
+#define IAMTimelineEffect_AddRef(This) \
+ (This)->lpVtbl -> AddRef(This)
+
+#define IAMTimelineEffect_Release(This) \
+ (This)->lpVtbl -> Release(This)
+
+
+#define IAMTimelineEffect_EffectGetPriority(This,pVal) \
+ (This)->lpVtbl -> EffectGetPriority(This,pVal)
+
+#endif /* COBJMACROS */
+
+
+#endif /* C style interface */
+
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineEffect_EffectGetPriority_Proxy(
+ IAMTimelineEffect * This,
+ long *pVal);
+
+
+void __RPC_STUB IAMTimelineEffect_EffectGetPriority_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+
+#endif /* __IAMTimelineEffect_INTERFACE_DEFINED__ */
+
+
+#ifndef __IAMTimelineTransable_INTERFACE_DEFINED__
+#define __IAMTimelineTransable_INTERFACE_DEFINED__
+
+/* interface IAMTimelineTransable */
+/* [unique][helpstring][uuid][object] */
+
+
+EXTERN_C const IID IID_IAMTimelineTransable;
+
+#if defined(__cplusplus) && !defined(CINTERFACE)
+
+ MIDL_INTERFACE("378FA386-622E-11d2-8CAD-00A024580902")
+ IAMTimelineTransable : public IUnknown
+ {
+ public:
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE TransAdd(
+ IAMTimelineObj *pTrans) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE TransGetCount(
+ long *pCount) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetNextTrans(
+ /* [out] */ IAMTimelineObj **ppTrans,
+ REFERENCE_TIME *pInOut) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetNextTrans2(
+ /* [out] */ IAMTimelineObj **ppTrans,
+ REFTIME *pInOut) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetTransAtTime(
+ /* [out] */ IAMTimelineObj **ppObj,
+ REFERENCE_TIME Time,
+ long SearchDirection) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetTransAtTime2(
+ /* [out] */ IAMTimelineObj **ppObj,
+ REFTIME Time,
+ long SearchDirection) = 0;
+
+ };
+
+#else /* C style interface */
+
+ typedef struct IAMTimelineTransableVtbl
+ {
+ BEGIN_INTERFACE
+
+ HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
+ IAMTimelineTransable * This,
+ /* [in] */ REFIID riid,
+ /* [iid_is][out] */ void **ppvObject);
+
+ ULONG ( STDMETHODCALLTYPE *AddRef )(
+ IAMTimelineTransable * This);
+
+ ULONG ( STDMETHODCALLTYPE *Release )(
+ IAMTimelineTransable * This);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *TransAdd )(
+ IAMTimelineTransable * This,
+ IAMTimelineObj *pTrans);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *TransGetCount )(
+ IAMTimelineTransable * This,
+ long *pCount);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetNextTrans )(
+ IAMTimelineTransable * This,
+ /* [out] */ IAMTimelineObj **ppTrans,
+ REFERENCE_TIME *pInOut);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetNextTrans2 )(
+ IAMTimelineTransable * This,
+ /* [out] */ IAMTimelineObj **ppTrans,
+ REFTIME *pInOut);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetTransAtTime )(
+ IAMTimelineTransable * This,
+ /* [out] */ IAMTimelineObj **ppObj,
+ REFERENCE_TIME Time,
+ long SearchDirection);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetTransAtTime2 )(
+ IAMTimelineTransable * This,
+ /* [out] */ IAMTimelineObj **ppObj,
+ REFTIME Time,
+ long SearchDirection);
+
+ END_INTERFACE
+ } IAMTimelineTransableVtbl;
+
+ interface IAMTimelineTransable
+ {
+ CONST_VTBL struct IAMTimelineTransableVtbl *lpVtbl;
+ };
+
+
+
+#ifdef COBJMACROS
+
+
+#define IAMTimelineTransable_QueryInterface(This,riid,ppvObject) \
+ (This)->lpVtbl -> QueryInterface(This,riid,ppvObject)
+
+#define IAMTimelineTransable_AddRef(This) \
+ (This)->lpVtbl -> AddRef(This)
+
+#define IAMTimelineTransable_Release(This) \
+ (This)->lpVtbl -> Release(This)
+
+
+#define IAMTimelineTransable_TransAdd(This,pTrans) \
+ (This)->lpVtbl -> TransAdd(This,pTrans)
+
+#define IAMTimelineTransable_TransGetCount(This,pCount) \
+ (This)->lpVtbl -> TransGetCount(This,pCount)
+
+#define IAMTimelineTransable_GetNextTrans(This,ppTrans,pInOut) \
+ (This)->lpVtbl -> GetNextTrans(This,ppTrans,pInOut)
+
+#define IAMTimelineTransable_GetNextTrans2(This,ppTrans,pInOut) \
+ (This)->lpVtbl -> GetNextTrans2(This,ppTrans,pInOut)
+
+#define IAMTimelineTransable_GetTransAtTime(This,ppObj,Time,SearchDirection) \
+ (This)->lpVtbl -> GetTransAtTime(This,ppObj,Time,SearchDirection)
+
+#define IAMTimelineTransable_GetTransAtTime2(This,ppObj,Time,SearchDirection) \
+ (This)->lpVtbl -> GetTransAtTime2(This,ppObj,Time,SearchDirection)
+
+#endif /* COBJMACROS */
+
+
+#endif /* C style interface */
+
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineTransable_TransAdd_Proxy(
+ IAMTimelineTransable * This,
+ IAMTimelineObj *pTrans);
+
+
+void __RPC_STUB IAMTimelineTransable_TransAdd_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineTransable_TransGetCount_Proxy(
+ IAMTimelineTransable * This,
+ long *pCount);
+
+
+void __RPC_STUB IAMTimelineTransable_TransGetCount_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineTransable_GetNextTrans_Proxy(
+ IAMTimelineTransable * This,
+ /* [out] */ IAMTimelineObj **ppTrans,
+ REFERENCE_TIME *pInOut);
+
+
+void __RPC_STUB IAMTimelineTransable_GetNextTrans_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineTransable_GetNextTrans2_Proxy(
+ IAMTimelineTransable * This,
+ /* [out] */ IAMTimelineObj **ppTrans,
+ REFTIME *pInOut);
+
+
+void __RPC_STUB IAMTimelineTransable_GetNextTrans2_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineTransable_GetTransAtTime_Proxy(
+ IAMTimelineTransable * This,
+ /* [out] */ IAMTimelineObj **ppObj,
+ REFERENCE_TIME Time,
+ long SearchDirection);
+
+
+void __RPC_STUB IAMTimelineTransable_GetTransAtTime_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineTransable_GetTransAtTime2_Proxy(
+ IAMTimelineTransable * This,
+ /* [out] */ IAMTimelineObj **ppObj,
+ REFTIME Time,
+ long SearchDirection);
+
+
+void __RPC_STUB IAMTimelineTransable_GetTransAtTime2_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+
+#endif /* __IAMTimelineTransable_INTERFACE_DEFINED__ */
+
+
+#ifndef __IAMTimelineSplittable_INTERFACE_DEFINED__
+#define __IAMTimelineSplittable_INTERFACE_DEFINED__
+
+/* interface IAMTimelineSplittable */
+/* [unique][helpstring][uuid][object] */
+
+
+EXTERN_C const IID IID_IAMTimelineSplittable;
+
+#if defined(__cplusplus) && !defined(CINTERFACE)
+
+ MIDL_INTERFACE("A0F840A0-D590-11d2-8D55-00A0C9441E20")
+ IAMTimelineSplittable : public IUnknown
+ {
+ public:
+ virtual HRESULT STDMETHODCALLTYPE SplitAt(
+ REFERENCE_TIME Time) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE SplitAt2(
+ REFTIME Time) = 0;
+
+ };
+
+#else /* C style interface */
+
+ typedef struct IAMTimelineSplittableVtbl
+ {
+ BEGIN_INTERFACE
+
+ HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
+ IAMTimelineSplittable * This,
+ /* [in] */ REFIID riid,
+ /* [iid_is][out] */ void **ppvObject);
+
+ ULONG ( STDMETHODCALLTYPE *AddRef )(
+ IAMTimelineSplittable * This);
+
+ ULONG ( STDMETHODCALLTYPE *Release )(
+ IAMTimelineSplittable * This);
+
+ HRESULT ( STDMETHODCALLTYPE *SplitAt )(
+ IAMTimelineSplittable * This,
+ REFERENCE_TIME Time);
+
+ HRESULT ( STDMETHODCALLTYPE *SplitAt2 )(
+ IAMTimelineSplittable * This,
+ REFTIME Time);
+
+ END_INTERFACE
+ } IAMTimelineSplittableVtbl;
+
+ interface IAMTimelineSplittable
+ {
+ CONST_VTBL struct IAMTimelineSplittableVtbl *lpVtbl;
+ };
+
+
+
+#ifdef COBJMACROS
+
+
+#define IAMTimelineSplittable_QueryInterface(This,riid,ppvObject) \
+ (This)->lpVtbl -> QueryInterface(This,riid,ppvObject)
+
+#define IAMTimelineSplittable_AddRef(This) \
+ (This)->lpVtbl -> AddRef(This)
+
+#define IAMTimelineSplittable_Release(This) \
+ (This)->lpVtbl -> Release(This)
+
+
+#define IAMTimelineSplittable_SplitAt(This,Time) \
+ (This)->lpVtbl -> SplitAt(This,Time)
+
+#define IAMTimelineSplittable_SplitAt2(This,Time) \
+ (This)->lpVtbl -> SplitAt2(This,Time)
+
+#endif /* COBJMACROS */
+
+
+#endif /* C style interface */
+
+
+
+HRESULT STDMETHODCALLTYPE IAMTimelineSplittable_SplitAt_Proxy(
+ IAMTimelineSplittable * This,
+ REFERENCE_TIME Time);
+
+
+void __RPC_STUB IAMTimelineSplittable_SplitAt_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+HRESULT STDMETHODCALLTYPE IAMTimelineSplittable_SplitAt2_Proxy(
+ IAMTimelineSplittable * This,
+ REFTIME Time);
+
+
+void __RPC_STUB IAMTimelineSplittable_SplitAt2_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+
+#endif /* __IAMTimelineSplittable_INTERFACE_DEFINED__ */
+
+
+#ifndef __IAMTimelineTrans_INTERFACE_DEFINED__
+#define __IAMTimelineTrans_INTERFACE_DEFINED__
+
+/* interface IAMTimelineTrans */
+/* [unique][helpstring][uuid][object] */
+
+
+EXTERN_C const IID IID_IAMTimelineTrans;
+
+#if defined(__cplusplus) && !defined(CINTERFACE)
+
+ MIDL_INTERFACE("BCE0C265-622D-11d2-8CAD-00A024580902")
+ IAMTimelineTrans : public IUnknown
+ {
+ public:
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetCutPoint(
+ REFERENCE_TIME *pTLTime) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetCutPoint2(
+ REFTIME *pTLTime) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetCutPoint(
+ REFERENCE_TIME TLTime) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetCutPoint2(
+ REFTIME TLTime) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetSwapInputs(
+ BOOL *pVal) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetSwapInputs(
+ BOOL pVal) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetCutsOnly(
+ BOOL *pVal) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetCutsOnly(
+ BOOL pVal) = 0;
+
+ };
+
+#else /* C style interface */
+
+ typedef struct IAMTimelineTransVtbl
+ {
+ BEGIN_INTERFACE
+
+ HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
+ IAMTimelineTrans * This,
+ /* [in] */ REFIID riid,
+ /* [iid_is][out] */ void **ppvObject);
+
+ ULONG ( STDMETHODCALLTYPE *AddRef )(
+ IAMTimelineTrans * This);
+
+ ULONG ( STDMETHODCALLTYPE *Release )(
+ IAMTimelineTrans * This);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetCutPoint )(
+ IAMTimelineTrans * This,
+ REFERENCE_TIME *pTLTime);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetCutPoint2 )(
+ IAMTimelineTrans * This,
+ REFTIME *pTLTime);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *SetCutPoint )(
+ IAMTimelineTrans * This,
+ REFERENCE_TIME TLTime);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *SetCutPoint2 )(
+ IAMTimelineTrans * This,
+ REFTIME TLTime);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetSwapInputs )(
+ IAMTimelineTrans * This,
+ BOOL *pVal);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *SetSwapInputs )(
+ IAMTimelineTrans * This,
+ BOOL pVal);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetCutsOnly )(
+ IAMTimelineTrans * This,
+ BOOL *pVal);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *SetCutsOnly )(
+ IAMTimelineTrans * This,
+ BOOL pVal);
+
+ END_INTERFACE
+ } IAMTimelineTransVtbl;
+
+ interface IAMTimelineTrans
+ {
+ CONST_VTBL struct IAMTimelineTransVtbl *lpVtbl;
+ };
+
+
+
+#ifdef COBJMACROS
+
+
+#define IAMTimelineTrans_QueryInterface(This,riid,ppvObject) \
+ (This)->lpVtbl -> QueryInterface(This,riid,ppvObject)
+
+#define IAMTimelineTrans_AddRef(This) \
+ (This)->lpVtbl -> AddRef(This)
+
+#define IAMTimelineTrans_Release(This) \
+ (This)->lpVtbl -> Release(This)
+
+
+#define IAMTimelineTrans_GetCutPoint(This,pTLTime) \
+ (This)->lpVtbl -> GetCutPoint(This,pTLTime)
+
+#define IAMTimelineTrans_GetCutPoint2(This,pTLTime) \
+ (This)->lpVtbl -> GetCutPoint2(This,pTLTime)
+
+#define IAMTimelineTrans_SetCutPoint(This,TLTime) \
+ (This)->lpVtbl -> SetCutPoint(This,TLTime)
+
+#define IAMTimelineTrans_SetCutPoint2(This,TLTime) \
+ (This)->lpVtbl -> SetCutPoint2(This,TLTime)
+
+#define IAMTimelineTrans_GetSwapInputs(This,pVal) \
+ (This)->lpVtbl -> GetSwapInputs(This,pVal)
+
+#define IAMTimelineTrans_SetSwapInputs(This,pVal) \
+ (This)->lpVtbl -> SetSwapInputs(This,pVal)
+
+#define IAMTimelineTrans_GetCutsOnly(This,pVal) \
+ (This)->lpVtbl -> GetCutsOnly(This,pVal)
+
+#define IAMTimelineTrans_SetCutsOnly(This,pVal) \
+ (This)->lpVtbl -> SetCutsOnly(This,pVal)
+
+#endif /* COBJMACROS */
+
+
+#endif /* C style interface */
+
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineTrans_GetCutPoint_Proxy(
+ IAMTimelineTrans * This,
+ REFERENCE_TIME *pTLTime);
+
+
+void __RPC_STUB IAMTimelineTrans_GetCutPoint_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineTrans_GetCutPoint2_Proxy(
+ IAMTimelineTrans * This,
+ REFTIME *pTLTime);
+
+
+void __RPC_STUB IAMTimelineTrans_GetCutPoint2_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineTrans_SetCutPoint_Proxy(
+ IAMTimelineTrans * This,
+ REFERENCE_TIME TLTime);
+
+
+void __RPC_STUB IAMTimelineTrans_SetCutPoint_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineTrans_SetCutPoint2_Proxy(
+ IAMTimelineTrans * This,
+ REFTIME TLTime);
+
+
+void __RPC_STUB IAMTimelineTrans_SetCutPoint2_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineTrans_GetSwapInputs_Proxy(
+ IAMTimelineTrans * This,
+ BOOL *pVal);
+
+
+void __RPC_STUB IAMTimelineTrans_GetSwapInputs_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineTrans_SetSwapInputs_Proxy(
+ IAMTimelineTrans * This,
+ BOOL pVal);
+
+
+void __RPC_STUB IAMTimelineTrans_SetSwapInputs_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineTrans_GetCutsOnly_Proxy(
+ IAMTimelineTrans * This,
+ BOOL *pVal);
+
+
+void __RPC_STUB IAMTimelineTrans_GetCutsOnly_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineTrans_SetCutsOnly_Proxy(
+ IAMTimelineTrans * This,
+ BOOL pVal);
+
+
+void __RPC_STUB IAMTimelineTrans_SetCutsOnly_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+
+#endif /* __IAMTimelineTrans_INTERFACE_DEFINED__ */
+
+
+#ifndef __IAMTimelineSrc_INTERFACE_DEFINED__
+#define __IAMTimelineSrc_INTERFACE_DEFINED__
+
+/* interface IAMTimelineSrc */
+/* [unique][helpstring][uuid][object] */
+
+
+EXTERN_C const IID IID_IAMTimelineSrc;
+
+#if defined(__cplusplus) && !defined(CINTERFACE)
+
+ MIDL_INTERFACE("78530B79-61F9-11D2-8CAD-00A024580902")
+ IAMTimelineSrc : public IUnknown
+ {
+ public:
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetMediaTimes(
+ REFERENCE_TIME *pStart,
+ REFERENCE_TIME *pStop) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetMediaTimes2(
+ REFTIME *pStart,
+ REFTIME *pStop) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE ModifyStopTime(
+ REFERENCE_TIME Stop) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE ModifyStopTime2(
+ REFTIME Stop) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE FixMediaTimes(
+ REFERENCE_TIME *pStart,
+ REFERENCE_TIME *pStop) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE FixMediaTimes2(
+ REFTIME *pStart,
+ REFTIME *pStop) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetMediaTimes(
+ REFERENCE_TIME Start,
+ REFERENCE_TIME Stop) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetMediaTimes2(
+ REFTIME Start,
+ REFTIME Stop) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetMediaLength(
+ REFERENCE_TIME Length) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetMediaLength2(
+ REFTIME Length) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetMediaLength(
+ REFERENCE_TIME *pLength) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetMediaLength2(
+ REFTIME *pLength) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetMediaName(
+ /* [retval][out] */ BSTR *pVal) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetMediaName(
+ BSTR newVal) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SpliceWithNext(
+ IAMTimelineObj *pNext) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetStreamNumber(
+ long *pVal) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetStreamNumber(
+ long Val) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE IsNormalRate(
+ BOOL *pVal) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetDefaultFPS(
+ double *pFPS) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetDefaultFPS(
+ double FPS) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetStretchMode(
+ int *pnStretchMode) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetStretchMode(
+ int nStretchMode) = 0;
+
+ };
+
+#else /* C style interface */
+
+ typedef struct IAMTimelineSrcVtbl
+ {
+ BEGIN_INTERFACE
+
+ HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
+ IAMTimelineSrc * This,
+ /* [in] */ REFIID riid,
+ /* [iid_is][out] */ void **ppvObject);
+
+ ULONG ( STDMETHODCALLTYPE *AddRef )(
+ IAMTimelineSrc * This);
+
+ ULONG ( STDMETHODCALLTYPE *Release )(
+ IAMTimelineSrc * This);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetMediaTimes )(
+ IAMTimelineSrc * This,
+ REFERENCE_TIME *pStart,
+ REFERENCE_TIME *pStop);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetMediaTimes2 )(
+ IAMTimelineSrc * This,
+ REFTIME *pStart,
+ REFTIME *pStop);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *ModifyStopTime )(
+ IAMTimelineSrc * This,
+ REFERENCE_TIME Stop);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *ModifyStopTime2 )(
+ IAMTimelineSrc * This,
+ REFTIME Stop);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *FixMediaTimes )(
+ IAMTimelineSrc * This,
+ REFERENCE_TIME *pStart,
+ REFERENCE_TIME *pStop);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *FixMediaTimes2 )(
+ IAMTimelineSrc * This,
+ REFTIME *pStart,
+ REFTIME *pStop);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *SetMediaTimes )(
+ IAMTimelineSrc * This,
+ REFERENCE_TIME Start,
+ REFERENCE_TIME Stop);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *SetMediaTimes2 )(
+ IAMTimelineSrc * This,
+ REFTIME Start,
+ REFTIME Stop);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *SetMediaLength )(
+ IAMTimelineSrc * This,
+ REFERENCE_TIME Length);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *SetMediaLength2 )(
+ IAMTimelineSrc * This,
+ REFTIME Length);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetMediaLength )(
+ IAMTimelineSrc * This,
+ REFERENCE_TIME *pLength);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetMediaLength2 )(
+ IAMTimelineSrc * This,
+ REFTIME *pLength);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetMediaName )(
+ IAMTimelineSrc * This,
+ /* [retval][out] */ BSTR *pVal);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *SetMediaName )(
+ IAMTimelineSrc * This,
+ BSTR newVal);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *SpliceWithNext )(
+ IAMTimelineSrc * This,
+ IAMTimelineObj *pNext);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetStreamNumber )(
+ IAMTimelineSrc * This,
+ long *pVal);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *SetStreamNumber )(
+ IAMTimelineSrc * This,
+ long Val);
+
+ HRESULT ( STDMETHODCALLTYPE *IsNormalRate )(
+ IAMTimelineSrc * This,
+ BOOL *pVal);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetDefaultFPS )(
+ IAMTimelineSrc * This,
+ double *pFPS);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *SetDefaultFPS )(
+ IAMTimelineSrc * This,
+ double FPS);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetStretchMode )(
+ IAMTimelineSrc * This,
+ int *pnStretchMode);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *SetStretchMode )(
+ IAMTimelineSrc * This,
+ int nStretchMode);
+
+ END_INTERFACE
+ } IAMTimelineSrcVtbl;
+
+ interface IAMTimelineSrc
+ {
+ CONST_VTBL struct IAMTimelineSrcVtbl *lpVtbl;
+ };
+
+
+
+#ifdef COBJMACROS
+
+
+#define IAMTimelineSrc_QueryInterface(This,riid,ppvObject) \
+ (This)->lpVtbl -> QueryInterface(This,riid,ppvObject)
+
+#define IAMTimelineSrc_AddRef(This) \
+ (This)->lpVtbl -> AddRef(This)
+
+#define IAMTimelineSrc_Release(This) \
+ (This)->lpVtbl -> Release(This)
+
+
+#define IAMTimelineSrc_GetMediaTimes(This,pStart,pStop) \
+ (This)->lpVtbl -> GetMediaTimes(This,pStart,pStop)
+
+#define IAMTimelineSrc_GetMediaTimes2(This,pStart,pStop) \
+ (This)->lpVtbl -> GetMediaTimes2(This,pStart,pStop)
+
+#define IAMTimelineSrc_ModifyStopTime(This,Stop) \
+ (This)->lpVtbl -> ModifyStopTime(This,Stop)
+
+#define IAMTimelineSrc_ModifyStopTime2(This,Stop) \
+ (This)->lpVtbl -> ModifyStopTime2(This,Stop)
+
+#define IAMTimelineSrc_FixMediaTimes(This,pStart,pStop) \
+ (This)->lpVtbl -> FixMediaTimes(This,pStart,pStop)
+
+#define IAMTimelineSrc_FixMediaTimes2(This,pStart,pStop) \
+ (This)->lpVtbl -> FixMediaTimes2(This,pStart,pStop)
+
+#define IAMTimelineSrc_SetMediaTimes(This,Start,Stop) \
+ (This)->lpVtbl -> SetMediaTimes(This,Start,Stop)
+
+#define IAMTimelineSrc_SetMediaTimes2(This,Start,Stop) \
+ (This)->lpVtbl -> SetMediaTimes2(This,Start,Stop)
+
+#define IAMTimelineSrc_SetMediaLength(This,Length) \
+ (This)->lpVtbl -> SetMediaLength(This,Length)
+
+#define IAMTimelineSrc_SetMediaLength2(This,Length) \
+ (This)->lpVtbl -> SetMediaLength2(This,Length)
+
+#define IAMTimelineSrc_GetMediaLength(This,pLength) \
+ (This)->lpVtbl -> GetMediaLength(This,pLength)
+
+#define IAMTimelineSrc_GetMediaLength2(This,pLength) \
+ (This)->lpVtbl -> GetMediaLength2(This,pLength)
+
+#define IAMTimelineSrc_GetMediaName(This,pVal) \
+ (This)->lpVtbl -> GetMediaName(This,pVal)
+
+#define IAMTimelineSrc_SetMediaName(This,newVal) \
+ (This)->lpVtbl -> SetMediaName(This,newVal)
+
+#define IAMTimelineSrc_SpliceWithNext(This,pNext) \
+ (This)->lpVtbl -> SpliceWithNext(This,pNext)
+
+#define IAMTimelineSrc_GetStreamNumber(This,pVal) \
+ (This)->lpVtbl -> GetStreamNumber(This,pVal)
+
+#define IAMTimelineSrc_SetStreamNumber(This,Val) \
+ (This)->lpVtbl -> SetStreamNumber(This,Val)
+
+#define IAMTimelineSrc_IsNormalRate(This,pVal) \
+ (This)->lpVtbl -> IsNormalRate(This,pVal)
+
+#define IAMTimelineSrc_GetDefaultFPS(This,pFPS) \
+ (This)->lpVtbl -> GetDefaultFPS(This,pFPS)
+
+#define IAMTimelineSrc_SetDefaultFPS(This,FPS) \
+ (This)->lpVtbl -> SetDefaultFPS(This,FPS)
+
+#define IAMTimelineSrc_GetStretchMode(This,pnStretchMode) \
+ (This)->lpVtbl -> GetStretchMode(This,pnStretchMode)
+
+#define IAMTimelineSrc_SetStretchMode(This,nStretchMode) \
+ (This)->lpVtbl -> SetStretchMode(This,nStretchMode)
+
+#endif /* COBJMACROS */
+
+
+#endif /* C style interface */
+
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineSrc_GetMediaTimes_Proxy(
+ IAMTimelineSrc * This,
+ REFERENCE_TIME *pStart,
+ REFERENCE_TIME *pStop);
+
+
+void __RPC_STUB IAMTimelineSrc_GetMediaTimes_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineSrc_GetMediaTimes2_Proxy(
+ IAMTimelineSrc * This,
+ REFTIME *pStart,
+ REFTIME *pStop);
+
+
+void __RPC_STUB IAMTimelineSrc_GetMediaTimes2_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineSrc_ModifyStopTime_Proxy(
+ IAMTimelineSrc * This,
+ REFERENCE_TIME Stop);
+
+
+void __RPC_STUB IAMTimelineSrc_ModifyStopTime_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineSrc_ModifyStopTime2_Proxy(
+ IAMTimelineSrc * This,
+ REFTIME Stop);
+
+
+void __RPC_STUB IAMTimelineSrc_ModifyStopTime2_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineSrc_FixMediaTimes_Proxy(
+ IAMTimelineSrc * This,
+ REFERENCE_TIME *pStart,
+ REFERENCE_TIME *pStop);
+
+
+void __RPC_STUB IAMTimelineSrc_FixMediaTimes_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineSrc_FixMediaTimes2_Proxy(
+ IAMTimelineSrc * This,
+ REFTIME *pStart,
+ REFTIME *pStop);
+
+
+void __RPC_STUB IAMTimelineSrc_FixMediaTimes2_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineSrc_SetMediaTimes_Proxy(
+ IAMTimelineSrc * This,
+ REFERENCE_TIME Start,
+ REFERENCE_TIME Stop);
+
+
+void __RPC_STUB IAMTimelineSrc_SetMediaTimes_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineSrc_SetMediaTimes2_Proxy(
+ IAMTimelineSrc * This,
+ REFTIME Start,
+ REFTIME Stop);
+
+
+void __RPC_STUB IAMTimelineSrc_SetMediaTimes2_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineSrc_SetMediaLength_Proxy(
+ IAMTimelineSrc * This,
+ REFERENCE_TIME Length);
+
+
+void __RPC_STUB IAMTimelineSrc_SetMediaLength_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineSrc_SetMediaLength2_Proxy(
+ IAMTimelineSrc * This,
+ REFTIME Length);
+
+
+void __RPC_STUB IAMTimelineSrc_SetMediaLength2_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineSrc_GetMediaLength_Proxy(
+ IAMTimelineSrc * This,
+ REFERENCE_TIME *pLength);
+
+
+void __RPC_STUB IAMTimelineSrc_GetMediaLength_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineSrc_GetMediaLength2_Proxy(
+ IAMTimelineSrc * This,
+ REFTIME *pLength);
+
+
+void __RPC_STUB IAMTimelineSrc_GetMediaLength2_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineSrc_GetMediaName_Proxy(
+ IAMTimelineSrc * This,
+ /* [retval][out] */ BSTR *pVal);
+
+
+void __RPC_STUB IAMTimelineSrc_GetMediaName_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineSrc_SetMediaName_Proxy(
+ IAMTimelineSrc * This,
+ BSTR newVal);
+
+
+void __RPC_STUB IAMTimelineSrc_SetMediaName_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineSrc_SpliceWithNext_Proxy(
+ IAMTimelineSrc * This,
+ IAMTimelineObj *pNext);
+
+
+void __RPC_STUB IAMTimelineSrc_SpliceWithNext_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineSrc_GetStreamNumber_Proxy(
+ IAMTimelineSrc * This,
+ long *pVal);
+
+
+void __RPC_STUB IAMTimelineSrc_GetStreamNumber_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineSrc_SetStreamNumber_Proxy(
+ IAMTimelineSrc * This,
+ long Val);
+
+
+void __RPC_STUB IAMTimelineSrc_SetStreamNumber_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+HRESULT STDMETHODCALLTYPE IAMTimelineSrc_IsNormalRate_Proxy(
+ IAMTimelineSrc * This,
+ BOOL *pVal);
+
+
+void __RPC_STUB IAMTimelineSrc_IsNormalRate_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineSrc_GetDefaultFPS_Proxy(
+ IAMTimelineSrc * This,
+ double *pFPS);
+
+
+void __RPC_STUB IAMTimelineSrc_GetDefaultFPS_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineSrc_SetDefaultFPS_Proxy(
+ IAMTimelineSrc * This,
+ double FPS);
+
+
+void __RPC_STUB IAMTimelineSrc_SetDefaultFPS_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineSrc_GetStretchMode_Proxy(
+ IAMTimelineSrc * This,
+ int *pnStretchMode);
+
+
+void __RPC_STUB IAMTimelineSrc_GetStretchMode_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineSrc_SetStretchMode_Proxy(
+ IAMTimelineSrc * This,
+ int nStretchMode);
+
+
+void __RPC_STUB IAMTimelineSrc_SetStretchMode_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+
+#endif /* __IAMTimelineSrc_INTERFACE_DEFINED__ */
+
+
+#ifndef __IAMTimelineTrack_INTERFACE_DEFINED__
+#define __IAMTimelineTrack_INTERFACE_DEFINED__
+
+/* interface IAMTimelineTrack */
+/* [unique][helpstring][uuid][object] */
+
+
+EXTERN_C const IID IID_IAMTimelineTrack;
+
+#if defined(__cplusplus) && !defined(CINTERFACE)
+
+ MIDL_INTERFACE("EAE58538-622E-11d2-8CAD-00A024580902")
+ IAMTimelineTrack : public IUnknown
+ {
+ public:
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SrcAdd(
+ IAMTimelineObj *pSource) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetNextSrc(
+ /* [out] */ IAMTimelineObj **ppSrc,
+ REFERENCE_TIME *pInOut) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetNextSrc2(
+ /* [out] */ IAMTimelineObj **ppSrc,
+ REFTIME *pInOut) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE MoveEverythingBy(
+ REFERENCE_TIME Start,
+ REFERENCE_TIME MoveBy) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE MoveEverythingBy2(
+ REFTIME Start,
+ REFTIME MoveBy) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetSourcesCount(
+ long *pVal) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE AreYouBlank(
+ long *pVal) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetSrcAtTime(
+ /* [out] */ IAMTimelineObj **ppSrc,
+ REFERENCE_TIME Time,
+ long SearchDirection) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetSrcAtTime2(
+ /* [out] */ IAMTimelineObj **ppSrc,
+ REFTIME Time,
+ long SearchDirection) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE InsertSpace(
+ REFERENCE_TIME rtStart,
+ REFERENCE_TIME rtEnd) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE InsertSpace2(
+ REFTIME rtStart,
+ REFTIME rtEnd) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE ZeroBetween(
+ REFERENCE_TIME rtStart,
+ REFERENCE_TIME rtEnd) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE ZeroBetween2(
+ REFTIME rtStart,
+ REFTIME rtEnd) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE GetNextSrcEx(
+ IAMTimelineObj *pLast,
+ /* [out] */ IAMTimelineObj **ppNext) = 0;
+
+ };
+
+#else /* C style interface */
+
+ typedef struct IAMTimelineTrackVtbl
+ {
+ BEGIN_INTERFACE
+
+ HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
+ IAMTimelineTrack * This,
+ /* [in] */ REFIID riid,
+ /* [iid_is][out] */ void **ppvObject);
+
+ ULONG ( STDMETHODCALLTYPE *AddRef )(
+ IAMTimelineTrack * This);
+
+ ULONG ( STDMETHODCALLTYPE *Release )(
+ IAMTimelineTrack * This);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *SrcAdd )(
+ IAMTimelineTrack * This,
+ IAMTimelineObj *pSource);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetNextSrc )(
+ IAMTimelineTrack * This,
+ /* [out] */ IAMTimelineObj **ppSrc,
+ REFERENCE_TIME *pInOut);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetNextSrc2 )(
+ IAMTimelineTrack * This,
+ /* [out] */ IAMTimelineObj **ppSrc,
+ REFTIME *pInOut);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *MoveEverythingBy )(
+ IAMTimelineTrack * This,
+ REFERENCE_TIME Start,
+ REFERENCE_TIME MoveBy);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *MoveEverythingBy2 )(
+ IAMTimelineTrack * This,
+ REFTIME Start,
+ REFTIME MoveBy);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetSourcesCount )(
+ IAMTimelineTrack * This,
+ long *pVal);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *AreYouBlank )(
+ IAMTimelineTrack * This,
+ long *pVal);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetSrcAtTime )(
+ IAMTimelineTrack * This,
+ /* [out] */ IAMTimelineObj **ppSrc,
+ REFERENCE_TIME Time,
+ long SearchDirection);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetSrcAtTime2 )(
+ IAMTimelineTrack * This,
+ /* [out] */ IAMTimelineObj **ppSrc,
+ REFTIME Time,
+ long SearchDirection);
+
+ HRESULT ( STDMETHODCALLTYPE *InsertSpace )(
+ IAMTimelineTrack * This,
+ REFERENCE_TIME rtStart,
+ REFERENCE_TIME rtEnd);
+
+ HRESULT ( STDMETHODCALLTYPE *InsertSpace2 )(
+ IAMTimelineTrack * This,
+ REFTIME rtStart,
+ REFTIME rtEnd);
+
+ HRESULT ( STDMETHODCALLTYPE *ZeroBetween )(
+ IAMTimelineTrack * This,
+ REFERENCE_TIME rtStart,
+ REFERENCE_TIME rtEnd);
+
+ HRESULT ( STDMETHODCALLTYPE *ZeroBetween2 )(
+ IAMTimelineTrack * This,
+ REFTIME rtStart,
+ REFTIME rtEnd);
+
+ HRESULT ( STDMETHODCALLTYPE *GetNextSrcEx )(
+ IAMTimelineTrack * This,
+ IAMTimelineObj *pLast,
+ /* [out] */ IAMTimelineObj **ppNext);
+
+ END_INTERFACE
+ } IAMTimelineTrackVtbl;
+
+ interface IAMTimelineTrack
+ {
+ CONST_VTBL struct IAMTimelineTrackVtbl *lpVtbl;
+ };
+
+
+
+#ifdef COBJMACROS
+
+
+#define IAMTimelineTrack_QueryInterface(This,riid,ppvObject) \
+ (This)->lpVtbl -> QueryInterface(This,riid,ppvObject)
+
+#define IAMTimelineTrack_AddRef(This) \
+ (This)->lpVtbl -> AddRef(This)
+
+#define IAMTimelineTrack_Release(This) \
+ (This)->lpVtbl -> Release(This)
+
+
+#define IAMTimelineTrack_SrcAdd(This,pSource) \
+ (This)->lpVtbl -> SrcAdd(This,pSource)
+
+#define IAMTimelineTrack_GetNextSrc(This,ppSrc,pInOut) \
+ (This)->lpVtbl -> GetNextSrc(This,ppSrc,pInOut)
+
+#define IAMTimelineTrack_GetNextSrc2(This,ppSrc,pInOut) \
+ (This)->lpVtbl -> GetNextSrc2(This,ppSrc,pInOut)
+
+#define IAMTimelineTrack_MoveEverythingBy(This,Start,MoveBy) \
+ (This)->lpVtbl -> MoveEverythingBy(This,Start,MoveBy)
+
+#define IAMTimelineTrack_MoveEverythingBy2(This,Start,MoveBy) \
+ (This)->lpVtbl -> MoveEverythingBy2(This,Start,MoveBy)
+
+#define IAMTimelineTrack_GetSourcesCount(This,pVal) \
+ (This)->lpVtbl -> GetSourcesCount(This,pVal)
+
+#define IAMTimelineTrack_AreYouBlank(This,pVal) \
+ (This)->lpVtbl -> AreYouBlank(This,pVal)
+
+#define IAMTimelineTrack_GetSrcAtTime(This,ppSrc,Time,SearchDirection) \
+ (This)->lpVtbl -> GetSrcAtTime(This,ppSrc,Time,SearchDirection)
+
+#define IAMTimelineTrack_GetSrcAtTime2(This,ppSrc,Time,SearchDirection) \
+ (This)->lpVtbl -> GetSrcAtTime2(This,ppSrc,Time,SearchDirection)
+
+#define IAMTimelineTrack_InsertSpace(This,rtStart,rtEnd) \
+ (This)->lpVtbl -> InsertSpace(This,rtStart,rtEnd)
+
+#define IAMTimelineTrack_InsertSpace2(This,rtStart,rtEnd) \
+ (This)->lpVtbl -> InsertSpace2(This,rtStart,rtEnd)
+
+#define IAMTimelineTrack_ZeroBetween(This,rtStart,rtEnd) \
+ (This)->lpVtbl -> ZeroBetween(This,rtStart,rtEnd)
+
+#define IAMTimelineTrack_ZeroBetween2(This,rtStart,rtEnd) \
+ (This)->lpVtbl -> ZeroBetween2(This,rtStart,rtEnd)
+
+#define IAMTimelineTrack_GetNextSrcEx(This,pLast,ppNext) \
+ (This)->lpVtbl -> GetNextSrcEx(This,pLast,ppNext)
+
+#endif /* COBJMACROS */
+
+
+#endif /* C style interface */
+
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineTrack_SrcAdd_Proxy(
+ IAMTimelineTrack * This,
+ IAMTimelineObj *pSource);
+
+
+void __RPC_STUB IAMTimelineTrack_SrcAdd_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineTrack_GetNextSrc_Proxy(
+ IAMTimelineTrack * This,
+ /* [out] */ IAMTimelineObj **ppSrc,
+ REFERENCE_TIME *pInOut);
+
+
+void __RPC_STUB IAMTimelineTrack_GetNextSrc_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineTrack_GetNextSrc2_Proxy(
+ IAMTimelineTrack * This,
+ /* [out] */ IAMTimelineObj **ppSrc,
+ REFTIME *pInOut);
+
+
+void __RPC_STUB IAMTimelineTrack_GetNextSrc2_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineTrack_MoveEverythingBy_Proxy(
+ IAMTimelineTrack * This,
+ REFERENCE_TIME Start,
+ REFERENCE_TIME MoveBy);
+
+
+void __RPC_STUB IAMTimelineTrack_MoveEverythingBy_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineTrack_MoveEverythingBy2_Proxy(
+ IAMTimelineTrack * This,
+ REFTIME Start,
+ REFTIME MoveBy);
+
+
+void __RPC_STUB IAMTimelineTrack_MoveEverythingBy2_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineTrack_GetSourcesCount_Proxy(
+ IAMTimelineTrack * This,
+ long *pVal);
+
+
+void __RPC_STUB IAMTimelineTrack_GetSourcesCount_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineTrack_AreYouBlank_Proxy(
+ IAMTimelineTrack * This,
+ long *pVal);
+
+
+void __RPC_STUB IAMTimelineTrack_AreYouBlank_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineTrack_GetSrcAtTime_Proxy(
+ IAMTimelineTrack * This,
+ /* [out] */ IAMTimelineObj **ppSrc,
+ REFERENCE_TIME Time,
+ long SearchDirection);
+
+
+void __RPC_STUB IAMTimelineTrack_GetSrcAtTime_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineTrack_GetSrcAtTime2_Proxy(
+ IAMTimelineTrack * This,
+ /* [out] */ IAMTimelineObj **ppSrc,
+ REFTIME Time,
+ long SearchDirection);
+
+
+void __RPC_STUB IAMTimelineTrack_GetSrcAtTime2_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+HRESULT STDMETHODCALLTYPE IAMTimelineTrack_InsertSpace_Proxy(
+ IAMTimelineTrack * This,
+ REFERENCE_TIME rtStart,
+ REFERENCE_TIME rtEnd);
+
+
+void __RPC_STUB IAMTimelineTrack_InsertSpace_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+HRESULT STDMETHODCALLTYPE IAMTimelineTrack_InsertSpace2_Proxy(
+ IAMTimelineTrack * This,
+ REFTIME rtStart,
+ REFTIME rtEnd);
+
+
+void __RPC_STUB IAMTimelineTrack_InsertSpace2_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+HRESULT STDMETHODCALLTYPE IAMTimelineTrack_ZeroBetween_Proxy(
+ IAMTimelineTrack * This,
+ REFERENCE_TIME rtStart,
+ REFERENCE_TIME rtEnd);
+
+
+void __RPC_STUB IAMTimelineTrack_ZeroBetween_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+HRESULT STDMETHODCALLTYPE IAMTimelineTrack_ZeroBetween2_Proxy(
+ IAMTimelineTrack * This,
+ REFTIME rtStart,
+ REFTIME rtEnd);
+
+
+void __RPC_STUB IAMTimelineTrack_ZeroBetween2_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+HRESULT STDMETHODCALLTYPE IAMTimelineTrack_GetNextSrcEx_Proxy(
+ IAMTimelineTrack * This,
+ IAMTimelineObj *pLast,
+ /* [out] */ IAMTimelineObj **ppNext);
+
+
+void __RPC_STUB IAMTimelineTrack_GetNextSrcEx_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+
+#endif /* __IAMTimelineTrack_INTERFACE_DEFINED__ */
+
+
+#ifndef __IAMTimelineVirtualTrack_INTERFACE_DEFINED__
+#define __IAMTimelineVirtualTrack_INTERFACE_DEFINED__
+
+/* interface IAMTimelineVirtualTrack */
+/* [unique][helpstring][uuid][object] */
+
+
+EXTERN_C const IID IID_IAMTimelineVirtualTrack;
+
+#if defined(__cplusplus) && !defined(CINTERFACE)
+
+ MIDL_INTERFACE("A8ED5F80-C2C7-11d2-8D39-00A0C9441E20")
+ IAMTimelineVirtualTrack : public IUnknown
+ {
+ public:
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE TrackGetPriority(
+ long *pPriority) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetTrackDirty( void) = 0;
+
+ };
+
+#else /* C style interface */
+
+ typedef struct IAMTimelineVirtualTrackVtbl
+ {
+ BEGIN_INTERFACE
+
+ HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
+ IAMTimelineVirtualTrack * This,
+ /* [in] */ REFIID riid,
+ /* [iid_is][out] */ void **ppvObject);
+
+ ULONG ( STDMETHODCALLTYPE *AddRef )(
+ IAMTimelineVirtualTrack * This);
+
+ ULONG ( STDMETHODCALLTYPE *Release )(
+ IAMTimelineVirtualTrack * This);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *TrackGetPriority )(
+ IAMTimelineVirtualTrack * This,
+ long *pPriority);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *SetTrackDirty )(
+ IAMTimelineVirtualTrack * This);
+
+ END_INTERFACE
+ } IAMTimelineVirtualTrackVtbl;
+
+ interface IAMTimelineVirtualTrack
+ {
+ CONST_VTBL struct IAMTimelineVirtualTrackVtbl *lpVtbl;
+ };
+
+
+
+#ifdef COBJMACROS
+
+
+#define IAMTimelineVirtualTrack_QueryInterface(This,riid,ppvObject) \
+ (This)->lpVtbl -> QueryInterface(This,riid,ppvObject)
+
+#define IAMTimelineVirtualTrack_AddRef(This) \
+ (This)->lpVtbl -> AddRef(This)
+
+#define IAMTimelineVirtualTrack_Release(This) \
+ (This)->lpVtbl -> Release(This)
+
+
+#define IAMTimelineVirtualTrack_TrackGetPriority(This,pPriority) \
+ (This)->lpVtbl -> TrackGetPriority(This,pPriority)
+
+#define IAMTimelineVirtualTrack_SetTrackDirty(This) \
+ (This)->lpVtbl -> SetTrackDirty(This)
+
+#endif /* COBJMACROS */
+
+
+#endif /* C style interface */
+
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineVirtualTrack_TrackGetPriority_Proxy(
+ IAMTimelineVirtualTrack * This,
+ long *pPriority);
+
+
+void __RPC_STUB IAMTimelineVirtualTrack_TrackGetPriority_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineVirtualTrack_SetTrackDirty_Proxy(
+ IAMTimelineVirtualTrack * This);
+
+
+void __RPC_STUB IAMTimelineVirtualTrack_SetTrackDirty_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+
+#endif /* __IAMTimelineVirtualTrack_INTERFACE_DEFINED__ */
+
+
+#ifndef __IAMTimelineComp_INTERFACE_DEFINED__
+#define __IAMTimelineComp_INTERFACE_DEFINED__
+
+/* interface IAMTimelineComp */
+/* [unique][helpstring][uuid][object] */
+
+
+EXTERN_C const IID IID_IAMTimelineComp;
+
+#if defined(__cplusplus) && !defined(CINTERFACE)
+
+ MIDL_INTERFACE("EAE58536-622E-11d2-8CAD-00A024580902")
+ IAMTimelineComp : public IUnknown
+ {
+ public:
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE VTrackInsBefore(
+ IAMTimelineObj *pVirtualTrack,
+ long Priority) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE VTrackSwapPriorities(
+ long VirtualTrackA,
+ long VirtualTrackB) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE VTrackGetCount(
+ long *pVal) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetVTrack(
+ /* [out] */ IAMTimelineObj **ppVirtualTrack,
+ long Which) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetCountOfType(
+ long *pVal,
+ long *pValWithComps,
+ TIMELINE_MAJOR_TYPE MajorType) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetRecursiveLayerOfType(
+ /* [out] */ IAMTimelineObj **ppVirtualTrack,
+ long WhichLayer,
+ TIMELINE_MAJOR_TYPE Type) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetRecursiveLayerOfTypeI(
+ /* [out] */ IAMTimelineObj **ppVirtualTrack,
+ /* [out][in] */ long *pWhichLayer,
+ TIMELINE_MAJOR_TYPE Type) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE GetNextVTrack(
+ IAMTimelineObj *pVirtualTrack,
+ /* [out] */ IAMTimelineObj **ppNextVirtualTrack) = 0;
+
+ };
+
+#else /* C style interface */
+
+ typedef struct IAMTimelineCompVtbl
+ {
+ BEGIN_INTERFACE
+
+ HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
+ IAMTimelineComp * This,
+ /* [in] */ REFIID riid,
+ /* [iid_is][out] */ void **ppvObject);
+
+ ULONG ( STDMETHODCALLTYPE *AddRef )(
+ IAMTimelineComp * This);
+
+ ULONG ( STDMETHODCALLTYPE *Release )(
+ IAMTimelineComp * This);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *VTrackInsBefore )(
+ IAMTimelineComp * This,
+ IAMTimelineObj *pVirtualTrack,
+ long Priority);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *VTrackSwapPriorities )(
+ IAMTimelineComp * This,
+ long VirtualTrackA,
+ long VirtualTrackB);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *VTrackGetCount )(
+ IAMTimelineComp * This,
+ long *pVal);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetVTrack )(
+ IAMTimelineComp * This,
+ /* [out] */ IAMTimelineObj **ppVirtualTrack,
+ long Which);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetCountOfType )(
+ IAMTimelineComp * This,
+ long *pVal,
+ long *pValWithComps,
+ TIMELINE_MAJOR_TYPE MajorType);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetRecursiveLayerOfType )(
+ IAMTimelineComp * This,
+ /* [out] */ IAMTimelineObj **ppVirtualTrack,
+ long WhichLayer,
+ TIMELINE_MAJOR_TYPE Type);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetRecursiveLayerOfTypeI )(
+ IAMTimelineComp * This,
+ /* [out] */ IAMTimelineObj **ppVirtualTrack,
+ /* [out][in] */ long *pWhichLayer,
+ TIMELINE_MAJOR_TYPE Type);
+
+ HRESULT ( STDMETHODCALLTYPE *GetNextVTrack )(
+ IAMTimelineComp * This,
+ IAMTimelineObj *pVirtualTrack,
+ /* [out] */ IAMTimelineObj **ppNextVirtualTrack);
+
+ END_INTERFACE
+ } IAMTimelineCompVtbl;
+
+ interface IAMTimelineComp
+ {
+ CONST_VTBL struct IAMTimelineCompVtbl *lpVtbl;
+ };
+
+
+
+#ifdef COBJMACROS
+
+
+#define IAMTimelineComp_QueryInterface(This,riid,ppvObject) \
+ (This)->lpVtbl -> QueryInterface(This,riid,ppvObject)
+
+#define IAMTimelineComp_AddRef(This) \
+ (This)->lpVtbl -> AddRef(This)
+
+#define IAMTimelineComp_Release(This) \
+ (This)->lpVtbl -> Release(This)
+
+
+#define IAMTimelineComp_VTrackInsBefore(This,pVirtualTrack,Priority) \
+ (This)->lpVtbl -> VTrackInsBefore(This,pVirtualTrack,Priority)
+
+#define IAMTimelineComp_VTrackSwapPriorities(This,VirtualTrackA,VirtualTrackB) \
+ (This)->lpVtbl -> VTrackSwapPriorities(This,VirtualTrackA,VirtualTrackB)
+
+#define IAMTimelineComp_VTrackGetCount(This,pVal) \
+ (This)->lpVtbl -> VTrackGetCount(This,pVal)
+
+#define IAMTimelineComp_GetVTrack(This,ppVirtualTrack,Which) \
+ (This)->lpVtbl -> GetVTrack(This,ppVirtualTrack,Which)
+
+#define IAMTimelineComp_GetCountOfType(This,pVal,pValWithComps,MajorType) \
+ (This)->lpVtbl -> GetCountOfType(This,pVal,pValWithComps,MajorType)
+
+#define IAMTimelineComp_GetRecursiveLayerOfType(This,ppVirtualTrack,WhichLayer,Type) \
+ (This)->lpVtbl -> GetRecursiveLayerOfType(This,ppVirtualTrack,WhichLayer,Type)
+
+#define IAMTimelineComp_GetRecursiveLayerOfTypeI(This,ppVirtualTrack,pWhichLayer,Type) \
+ (This)->lpVtbl -> GetRecursiveLayerOfTypeI(This,ppVirtualTrack,pWhichLayer,Type)
+
+#define IAMTimelineComp_GetNextVTrack(This,pVirtualTrack,ppNextVirtualTrack) \
+ (This)->lpVtbl -> GetNextVTrack(This,pVirtualTrack,ppNextVirtualTrack)
+
+#endif /* COBJMACROS */
+
+
+#endif /* C style interface */
+
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineComp_VTrackInsBefore_Proxy(
+ IAMTimelineComp * This,
+ IAMTimelineObj *pVirtualTrack,
+ long Priority);
+
+
+void __RPC_STUB IAMTimelineComp_VTrackInsBefore_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineComp_VTrackSwapPriorities_Proxy(
+ IAMTimelineComp * This,
+ long VirtualTrackA,
+ long VirtualTrackB);
+
+
+void __RPC_STUB IAMTimelineComp_VTrackSwapPriorities_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineComp_VTrackGetCount_Proxy(
+ IAMTimelineComp * This,
+ long *pVal);
+
+
+void __RPC_STUB IAMTimelineComp_VTrackGetCount_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineComp_GetVTrack_Proxy(
+ IAMTimelineComp * This,
+ /* [out] */ IAMTimelineObj **ppVirtualTrack,
+ long Which);
+
+
+void __RPC_STUB IAMTimelineComp_GetVTrack_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineComp_GetCountOfType_Proxy(
+ IAMTimelineComp * This,
+ long *pVal,
+ long *pValWithComps,
+ TIMELINE_MAJOR_TYPE MajorType);
+
+
+void __RPC_STUB IAMTimelineComp_GetCountOfType_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineComp_GetRecursiveLayerOfType_Proxy(
+ IAMTimelineComp * This,
+ /* [out] */ IAMTimelineObj **ppVirtualTrack,
+ long WhichLayer,
+ TIMELINE_MAJOR_TYPE Type);
+
+
+void __RPC_STUB IAMTimelineComp_GetRecursiveLayerOfType_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineComp_GetRecursiveLayerOfTypeI_Proxy(
+ IAMTimelineComp * This,
+ /* [out] */ IAMTimelineObj **ppVirtualTrack,
+ /* [out][in] */ long *pWhichLayer,
+ TIMELINE_MAJOR_TYPE Type);
+
+
+void __RPC_STUB IAMTimelineComp_GetRecursiveLayerOfTypeI_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+HRESULT STDMETHODCALLTYPE IAMTimelineComp_GetNextVTrack_Proxy(
+ IAMTimelineComp * This,
+ IAMTimelineObj *pVirtualTrack,
+ /* [out] */ IAMTimelineObj **ppNextVirtualTrack);
+
+
+void __RPC_STUB IAMTimelineComp_GetNextVTrack_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+
+#endif /* __IAMTimelineComp_INTERFACE_DEFINED__ */
+
+
+#ifndef __IAMTimelineGroup_INTERFACE_DEFINED__
+#define __IAMTimelineGroup_INTERFACE_DEFINED__
+
+/* interface IAMTimelineGroup */
+/* [unique][helpstring][uuid][object] */
+
+
+EXTERN_C const IID IID_IAMTimelineGroup;
+
+#if defined(__cplusplus) && !defined(CINTERFACE)
+
+ MIDL_INTERFACE("9EED4F00-B8A6-11d2-8023-00C0DF10D434")
+ IAMTimelineGroup : public IUnknown
+ {
+ public:
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetTimeline(
+ IAMTimeline *pTimeline) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetTimeline(
+ /* [out] */ IAMTimeline **ppTimeline) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetPriority(
+ long *pPriority) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetMediaType(
+ /* [out] */ AM_MEDIA_TYPE *__MIDL_0040) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetMediaType(
+ /* [in] */ AM_MEDIA_TYPE *__MIDL_0041) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetOutputFPS(
+ double FPS) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetOutputFPS(
+ double *pFPS) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetGroupName(
+ BSTR pGroupName) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetGroupName(
+ /* [retval][out] */ BSTR *pGroupName) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetPreviewMode(
+ BOOL fPreview) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetPreviewMode(
+ BOOL *pfPreview) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetMediaTypeForVB(
+ /* [in] */ long Val) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetOutputBuffering(
+ /* [out] */ int *pnBuffer) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetOutputBuffering(
+ /* [in] */ int nBuffer) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE SetSmartRecompressFormat(
+ long *pFormat) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE GetSmartRecompressFormat(
+ long **ppFormat) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE IsSmartRecompressFormatSet(
+ BOOL *pVal) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE IsRecompressFormatDirty(
+ BOOL *pVal) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE ClearRecompressFormatDirty( void) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE SetRecompFormatFromSource(
+ IAMTimelineSrc *pSource) = 0;
+
+ };
+
+#else /* C style interface */
+
+ typedef struct IAMTimelineGroupVtbl
+ {
+ BEGIN_INTERFACE
+
+ HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
+ IAMTimelineGroup * This,
+ /* [in] */ REFIID riid,
+ /* [iid_is][out] */ void **ppvObject);
+
+ ULONG ( STDMETHODCALLTYPE *AddRef )(
+ IAMTimelineGroup * This);
+
+ ULONG ( STDMETHODCALLTYPE *Release )(
+ IAMTimelineGroup * This);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *SetTimeline )(
+ IAMTimelineGroup * This,
+ IAMTimeline *pTimeline);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetTimeline )(
+ IAMTimelineGroup * This,
+ /* [out] */ IAMTimeline **ppTimeline);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetPriority )(
+ IAMTimelineGroup * This,
+ long *pPriority);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetMediaType )(
+ IAMTimelineGroup * This,
+ /* [out] */ AM_MEDIA_TYPE *__MIDL_0040);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *SetMediaType )(
+ IAMTimelineGroup * This,
+ /* [in] */ AM_MEDIA_TYPE *__MIDL_0041);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *SetOutputFPS )(
+ IAMTimelineGroup * This,
+ double FPS);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetOutputFPS )(
+ IAMTimelineGroup * This,
+ double *pFPS);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *SetGroupName )(
+ IAMTimelineGroup * This,
+ BSTR pGroupName);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetGroupName )(
+ IAMTimelineGroup * This,
+ /* [retval][out] */ BSTR *pGroupName);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *SetPreviewMode )(
+ IAMTimelineGroup * This,
+ BOOL fPreview);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetPreviewMode )(
+ IAMTimelineGroup * This,
+ BOOL *pfPreview);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *SetMediaTypeForVB )(
+ IAMTimelineGroup * This,
+ /* [in] */ long Val);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetOutputBuffering )(
+ IAMTimelineGroup * This,
+ /* [out] */ int *pnBuffer);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *SetOutputBuffering )(
+ IAMTimelineGroup * This,
+ /* [in] */ int nBuffer);
+
+ HRESULT ( STDMETHODCALLTYPE *SetSmartRecompressFormat )(
+ IAMTimelineGroup * This,
+ long *pFormat);
+
+ HRESULT ( STDMETHODCALLTYPE *GetSmartRecompressFormat )(
+ IAMTimelineGroup * This,
+ long **ppFormat);
+
+ HRESULT ( STDMETHODCALLTYPE *IsSmartRecompressFormatSet )(
+ IAMTimelineGroup * This,
+ BOOL *pVal);
+
+ HRESULT ( STDMETHODCALLTYPE *IsRecompressFormatDirty )(
+ IAMTimelineGroup * This,
+ BOOL *pVal);
+
+ HRESULT ( STDMETHODCALLTYPE *ClearRecompressFormatDirty )(
+ IAMTimelineGroup * This);
+
+ HRESULT ( STDMETHODCALLTYPE *SetRecompFormatFromSource )(
+ IAMTimelineGroup * This,
+ IAMTimelineSrc *pSource);
+
+ END_INTERFACE
+ } IAMTimelineGroupVtbl;
+
+ interface IAMTimelineGroup
+ {
+ CONST_VTBL struct IAMTimelineGroupVtbl *lpVtbl;
+ };
+
+
+
+#ifdef COBJMACROS
+
+
+#define IAMTimelineGroup_QueryInterface(This,riid,ppvObject) \
+ (This)->lpVtbl -> QueryInterface(This,riid,ppvObject)
+
+#define IAMTimelineGroup_AddRef(This) \
+ (This)->lpVtbl -> AddRef(This)
+
+#define IAMTimelineGroup_Release(This) \
+ (This)->lpVtbl -> Release(This)
+
+
+#define IAMTimelineGroup_SetTimeline(This,pTimeline) \
+ (This)->lpVtbl -> SetTimeline(This,pTimeline)
+
+#define IAMTimelineGroup_GetTimeline(This,ppTimeline) \
+ (This)->lpVtbl -> GetTimeline(This,ppTimeline)
+
+#define IAMTimelineGroup_GetPriority(This,pPriority) \
+ (This)->lpVtbl -> GetPriority(This,pPriority)
+
+#define IAMTimelineGroup_GetMediaType(This,__MIDL_0040) \
+ (This)->lpVtbl -> GetMediaType(This,__MIDL_0040)
+
+#define IAMTimelineGroup_SetMediaType(This,__MIDL_0041) \
+ (This)->lpVtbl -> SetMediaType(This,__MIDL_0041)
+
+#define IAMTimelineGroup_SetOutputFPS(This,FPS) \
+ (This)->lpVtbl -> SetOutputFPS(This,FPS)
+
+#define IAMTimelineGroup_GetOutputFPS(This,pFPS) \
+ (This)->lpVtbl -> GetOutputFPS(This,pFPS)
+
+#define IAMTimelineGroup_SetGroupName(This,pGroupName) \
+ (This)->lpVtbl -> SetGroupName(This,pGroupName)
+
+#define IAMTimelineGroup_GetGroupName(This,pGroupName) \
+ (This)->lpVtbl -> GetGroupName(This,pGroupName)
+
+#define IAMTimelineGroup_SetPreviewMode(This,fPreview) \
+ (This)->lpVtbl -> SetPreviewMode(This,fPreview)
+
+#define IAMTimelineGroup_GetPreviewMode(This,pfPreview) \
+ (This)->lpVtbl -> GetPreviewMode(This,pfPreview)
+
+#define IAMTimelineGroup_SetMediaTypeForVB(This,Val) \
+ (This)->lpVtbl -> SetMediaTypeForVB(This,Val)
+
+#define IAMTimelineGroup_GetOutputBuffering(This,pnBuffer) \
+ (This)->lpVtbl -> GetOutputBuffering(This,pnBuffer)
+
+#define IAMTimelineGroup_SetOutputBuffering(This,nBuffer) \
+ (This)->lpVtbl -> SetOutputBuffering(This,nBuffer)
+
+#define IAMTimelineGroup_SetSmartRecompressFormat(This,pFormat) \
+ (This)->lpVtbl -> SetSmartRecompressFormat(This,pFormat)
+
+#define IAMTimelineGroup_GetSmartRecompressFormat(This,ppFormat) \
+ (This)->lpVtbl -> GetSmartRecompressFormat(This,ppFormat)
+
+#define IAMTimelineGroup_IsSmartRecompressFormatSet(This,pVal) \
+ (This)->lpVtbl -> IsSmartRecompressFormatSet(This,pVal)
+
+#define IAMTimelineGroup_IsRecompressFormatDirty(This,pVal) \
+ (This)->lpVtbl -> IsRecompressFormatDirty(This,pVal)
+
+#define IAMTimelineGroup_ClearRecompressFormatDirty(This) \
+ (This)->lpVtbl -> ClearRecompressFormatDirty(This)
+
+#define IAMTimelineGroup_SetRecompFormatFromSource(This,pSource) \
+ (This)->lpVtbl -> SetRecompFormatFromSource(This,pSource)
+
+#endif /* COBJMACROS */
+
+
+#endif /* C style interface */
+
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineGroup_SetTimeline_Proxy(
+ IAMTimelineGroup * This,
+ IAMTimeline *pTimeline);
+
+
+void __RPC_STUB IAMTimelineGroup_SetTimeline_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineGroup_GetTimeline_Proxy(
+ IAMTimelineGroup * This,
+ /* [out] */ IAMTimeline **ppTimeline);
+
+
+void __RPC_STUB IAMTimelineGroup_GetTimeline_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineGroup_GetPriority_Proxy(
+ IAMTimelineGroup * This,
+ long *pPriority);
+
+
+void __RPC_STUB IAMTimelineGroup_GetPriority_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineGroup_GetMediaType_Proxy(
+ IAMTimelineGroup * This,
+ /* [out] */ AM_MEDIA_TYPE *__MIDL_0040);
+
+
+void __RPC_STUB IAMTimelineGroup_GetMediaType_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineGroup_SetMediaType_Proxy(
+ IAMTimelineGroup * This,
+ /* [in] */ AM_MEDIA_TYPE *__MIDL_0041);
+
+
+void __RPC_STUB IAMTimelineGroup_SetMediaType_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineGroup_SetOutputFPS_Proxy(
+ IAMTimelineGroup * This,
+ double FPS);
+
+
+void __RPC_STUB IAMTimelineGroup_SetOutputFPS_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineGroup_GetOutputFPS_Proxy(
+ IAMTimelineGroup * This,
+ double *pFPS);
+
+
+void __RPC_STUB IAMTimelineGroup_GetOutputFPS_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineGroup_SetGroupName_Proxy(
+ IAMTimelineGroup * This,
+ BSTR pGroupName);
+
+
+void __RPC_STUB IAMTimelineGroup_SetGroupName_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineGroup_GetGroupName_Proxy(
+ IAMTimelineGroup * This,
+ /* [retval][out] */ BSTR *pGroupName);
+
+
+void __RPC_STUB IAMTimelineGroup_GetGroupName_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineGroup_SetPreviewMode_Proxy(
+ IAMTimelineGroup * This,
+ BOOL fPreview);
+
+
+void __RPC_STUB IAMTimelineGroup_SetPreviewMode_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineGroup_GetPreviewMode_Proxy(
+ IAMTimelineGroup * This,
+ BOOL *pfPreview);
+
+
+void __RPC_STUB IAMTimelineGroup_GetPreviewMode_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineGroup_SetMediaTypeForVB_Proxy(
+ IAMTimelineGroup * This,
+ /* [in] */ long Val);
+
+
+void __RPC_STUB IAMTimelineGroup_SetMediaTypeForVB_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineGroup_GetOutputBuffering_Proxy(
+ IAMTimelineGroup * This,
+ /* [out] */ int *pnBuffer);
+
+
+void __RPC_STUB IAMTimelineGroup_GetOutputBuffering_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimelineGroup_SetOutputBuffering_Proxy(
+ IAMTimelineGroup * This,
+ /* [in] */ int nBuffer);
+
+
+void __RPC_STUB IAMTimelineGroup_SetOutputBuffering_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+HRESULT STDMETHODCALLTYPE IAMTimelineGroup_SetSmartRecompressFormat_Proxy(
+ IAMTimelineGroup * This,
+ long *pFormat);
+
+
+void __RPC_STUB IAMTimelineGroup_SetSmartRecompressFormat_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+HRESULT STDMETHODCALLTYPE IAMTimelineGroup_GetSmartRecompressFormat_Proxy(
+ IAMTimelineGroup * This,
+ long **ppFormat);
+
+
+void __RPC_STUB IAMTimelineGroup_GetSmartRecompressFormat_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+HRESULT STDMETHODCALLTYPE IAMTimelineGroup_IsSmartRecompressFormatSet_Proxy(
+ IAMTimelineGroup * This,
+ BOOL *pVal);
+
+
+void __RPC_STUB IAMTimelineGroup_IsSmartRecompressFormatSet_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+HRESULT STDMETHODCALLTYPE IAMTimelineGroup_IsRecompressFormatDirty_Proxy(
+ IAMTimelineGroup * This,
+ BOOL *pVal);
+
+
+void __RPC_STUB IAMTimelineGroup_IsRecompressFormatDirty_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+HRESULT STDMETHODCALLTYPE IAMTimelineGroup_ClearRecompressFormatDirty_Proxy(
+ IAMTimelineGroup * This);
+
+
+void __RPC_STUB IAMTimelineGroup_ClearRecompressFormatDirty_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+HRESULT STDMETHODCALLTYPE IAMTimelineGroup_SetRecompFormatFromSource_Proxy(
+ IAMTimelineGroup * This,
+ IAMTimelineSrc *pSource);
+
+
+void __RPC_STUB IAMTimelineGroup_SetRecompFormatFromSource_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+
+#endif /* __IAMTimelineGroup_INTERFACE_DEFINED__ */
+
+
+#ifndef __IAMTimeline_INTERFACE_DEFINED__
+#define __IAMTimeline_INTERFACE_DEFINED__
+
+/* interface IAMTimeline */
+/* [unique][helpstring][uuid][object] */
+
+
+EXTERN_C const IID IID_IAMTimeline;
+
+#if defined(__cplusplus) && !defined(CINTERFACE)
+
+ MIDL_INTERFACE("78530B74-61F9-11D2-8CAD-00A024580902")
+ IAMTimeline : public IUnknown
+ {
+ public:
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE CreateEmptyNode(
+ /* [out] */ IAMTimelineObj **ppObj,
+ TIMELINE_MAJOR_TYPE Type) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE AddGroup(
+ IAMTimelineObj *pGroup) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE RemGroupFromList(
+ IAMTimelineObj *pGroup) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE GetGroup(
+ /* [out] */ IAMTimelineObj **ppGroup,
+ long WhichGroup) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE GetGroupCount(
+ long *pCount) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE ClearAllGroups( void) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE GetInsertMode(
+ long *pMode) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetInsertMode(
+ long Mode) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE EnableTransitions(
+ BOOL fEnabled) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE TransitionsEnabled(
+ BOOL *pfEnabled) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE EnableEffects(
+ BOOL fEnabled) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE EffectsEnabled(
+ BOOL *pfEnabled) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetInterestRange(
+ REFERENCE_TIME Start,
+ REFERENCE_TIME Stop) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetDuration(
+ REFERENCE_TIME *pDuration) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetDuration2(
+ double *pDuration) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetDefaultFPS(
+ double FPS) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetDefaultFPS(
+ double *pFPS) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE IsDirty(
+ BOOL *pDirty) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetDirtyRange(
+ REFERENCE_TIME *pStart,
+ REFERENCE_TIME *pStop) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetCountOfType(
+ long Group,
+ long *pVal,
+ long *pValWithComps,
+ TIMELINE_MAJOR_TYPE MajorType) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE ValidateSourceNames(
+ long ValidateFlags,
+ IMediaLocator *pOverride,
+ LONG_PTR NotifyEventHandle) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE SetDefaultTransition(
+ GUID *pGuid) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE GetDefaultTransition(
+ GUID *pGuid) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE SetDefaultEffect(
+ GUID *pGuid) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE GetDefaultEffect(
+ GUID *pGuid) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE SetDefaultTransitionB(
+ BSTR pGuid) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE GetDefaultTransitionB(
+ /* [retval][out] */ BSTR *pGuid) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE SetDefaultEffectB(
+ BSTR pGuid) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE GetDefaultEffectB(
+ /* [retval][out] */ BSTR *pGuid) = 0;
+
+ };
+
+#else /* C style interface */
+
+ typedef struct IAMTimelineVtbl
+ {
+ BEGIN_INTERFACE
+
+ HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
+ IAMTimeline * This,
+ /* [in] */ REFIID riid,
+ /* [iid_is][out] */ void **ppvObject);
+
+ ULONG ( STDMETHODCALLTYPE *AddRef )(
+ IAMTimeline * This);
+
+ ULONG ( STDMETHODCALLTYPE *Release )(
+ IAMTimeline * This);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *CreateEmptyNode )(
+ IAMTimeline * This,
+ /* [out] */ IAMTimelineObj **ppObj,
+ TIMELINE_MAJOR_TYPE Type);
+
+ HRESULT ( STDMETHODCALLTYPE *AddGroup )(
+ IAMTimeline * This,
+ IAMTimelineObj *pGroup);
+
+ HRESULT ( STDMETHODCALLTYPE *RemGroupFromList )(
+ IAMTimeline * This,
+ IAMTimelineObj *pGroup);
+
+ HRESULT ( STDMETHODCALLTYPE *GetGroup )(
+ IAMTimeline * This,
+ /* [out] */ IAMTimelineObj **ppGroup,
+ long WhichGroup);
+
+ HRESULT ( STDMETHODCALLTYPE *GetGroupCount )(
+ IAMTimeline * This,
+ long *pCount);
+
+ HRESULT ( STDMETHODCALLTYPE *ClearAllGroups )(
+ IAMTimeline * This);
+
+ HRESULT ( STDMETHODCALLTYPE *GetInsertMode )(
+ IAMTimeline * This,
+ long *pMode);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *SetInsertMode )(
+ IAMTimeline * This,
+ long Mode);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *EnableTransitions )(
+ IAMTimeline * This,
+ BOOL fEnabled);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *TransitionsEnabled )(
+ IAMTimeline * This,
+ BOOL *pfEnabled);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *EnableEffects )(
+ IAMTimeline * This,
+ BOOL fEnabled);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *EffectsEnabled )(
+ IAMTimeline * This,
+ BOOL *pfEnabled);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *SetInterestRange )(
+ IAMTimeline * This,
+ REFERENCE_TIME Start,
+ REFERENCE_TIME Stop);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetDuration )(
+ IAMTimeline * This,
+ REFERENCE_TIME *pDuration);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetDuration2 )(
+ IAMTimeline * This,
+ double *pDuration);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *SetDefaultFPS )(
+ IAMTimeline * This,
+ double FPS);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetDefaultFPS )(
+ IAMTimeline * This,
+ double *pFPS);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *IsDirty )(
+ IAMTimeline * This,
+ BOOL *pDirty);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetDirtyRange )(
+ IAMTimeline * This,
+ REFERENCE_TIME *pStart,
+ REFERENCE_TIME *pStop);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetCountOfType )(
+ IAMTimeline * This,
+ long Group,
+ long *pVal,
+ long *pValWithComps,
+ TIMELINE_MAJOR_TYPE MajorType);
+
+ HRESULT ( STDMETHODCALLTYPE *ValidateSourceNames )(
+ IAMTimeline * This,
+ long ValidateFlags,
+ IMediaLocator *pOverride,
+ LONG_PTR NotifyEventHandle);
+
+ HRESULT ( STDMETHODCALLTYPE *SetDefaultTransition )(
+ IAMTimeline * This,
+ GUID *pGuid);
+
+ HRESULT ( STDMETHODCALLTYPE *GetDefaultTransition )(
+ IAMTimeline * This,
+ GUID *pGuid);
+
+ HRESULT ( STDMETHODCALLTYPE *SetDefaultEffect )(
+ IAMTimeline * This,
+ GUID *pGuid);
+
+ HRESULT ( STDMETHODCALLTYPE *GetDefaultEffect )(
+ IAMTimeline * This,
+ GUID *pGuid);
+
+ HRESULT ( STDMETHODCALLTYPE *SetDefaultTransitionB )(
+ IAMTimeline * This,
+ BSTR pGuid);
+
+ HRESULT ( STDMETHODCALLTYPE *GetDefaultTransitionB )(
+ IAMTimeline * This,
+ /* [retval][out] */ BSTR *pGuid);
+
+ HRESULT ( STDMETHODCALLTYPE *SetDefaultEffectB )(
+ IAMTimeline * This,
+ BSTR pGuid);
+
+ HRESULT ( STDMETHODCALLTYPE *GetDefaultEffectB )(
+ IAMTimeline * This,
+ /* [retval][out] */ BSTR *pGuid);
+
+ END_INTERFACE
+ } IAMTimelineVtbl;
+
+ interface IAMTimeline
+ {
+ CONST_VTBL struct IAMTimelineVtbl *lpVtbl;
+ };
+
+
+
+#ifdef COBJMACROS
+
+
+#define IAMTimeline_QueryInterface(This,riid,ppvObject) \
+ (This)->lpVtbl -> QueryInterface(This,riid,ppvObject)
+
+#define IAMTimeline_AddRef(This) \
+ (This)->lpVtbl -> AddRef(This)
+
+#define IAMTimeline_Release(This) \
+ (This)->lpVtbl -> Release(This)
+
+
+#define IAMTimeline_CreateEmptyNode(This,ppObj,Type) \
+ (This)->lpVtbl -> CreateEmptyNode(This,ppObj,Type)
+
+#define IAMTimeline_AddGroup(This,pGroup) \
+ (This)->lpVtbl -> AddGroup(This,pGroup)
+
+#define IAMTimeline_RemGroupFromList(This,pGroup) \
+ (This)->lpVtbl -> RemGroupFromList(This,pGroup)
+
+#define IAMTimeline_GetGroup(This,ppGroup,WhichGroup) \
+ (This)->lpVtbl -> GetGroup(This,ppGroup,WhichGroup)
+
+#define IAMTimeline_GetGroupCount(This,pCount) \
+ (This)->lpVtbl -> GetGroupCount(This,pCount)
+
+#define IAMTimeline_ClearAllGroups(This) \
+ (This)->lpVtbl -> ClearAllGroups(This)
+
+#define IAMTimeline_GetInsertMode(This,pMode) \
+ (This)->lpVtbl -> GetInsertMode(This,pMode)
+
+#define IAMTimeline_SetInsertMode(This,Mode) \
+ (This)->lpVtbl -> SetInsertMode(This,Mode)
+
+#define IAMTimeline_EnableTransitions(This,fEnabled) \
+ (This)->lpVtbl -> EnableTransitions(This,fEnabled)
+
+#define IAMTimeline_TransitionsEnabled(This,pfEnabled) \
+ (This)->lpVtbl -> TransitionsEnabled(This,pfEnabled)
+
+#define IAMTimeline_EnableEffects(This,fEnabled) \
+ (This)->lpVtbl -> EnableEffects(This,fEnabled)
+
+#define IAMTimeline_EffectsEnabled(This,pfEnabled) \
+ (This)->lpVtbl -> EffectsEnabled(This,pfEnabled)
+
+#define IAMTimeline_SetInterestRange(This,Start,Stop) \
+ (This)->lpVtbl -> SetInterestRange(This,Start,Stop)
+
+#define IAMTimeline_GetDuration(This,pDuration) \
+ (This)->lpVtbl -> GetDuration(This,pDuration)
+
+#define IAMTimeline_GetDuration2(This,pDuration) \
+ (This)->lpVtbl -> GetDuration2(This,pDuration)
+
+#define IAMTimeline_SetDefaultFPS(This,FPS) \
+ (This)->lpVtbl -> SetDefaultFPS(This,FPS)
+
+#define IAMTimeline_GetDefaultFPS(This,pFPS) \
+ (This)->lpVtbl -> GetDefaultFPS(This,pFPS)
+
+#define IAMTimeline_IsDirty(This,pDirty) \
+ (This)->lpVtbl -> IsDirty(This,pDirty)
+
+#define IAMTimeline_GetDirtyRange(This,pStart,pStop) \
+ (This)->lpVtbl -> GetDirtyRange(This,pStart,pStop)
+
+#define IAMTimeline_GetCountOfType(This,Group,pVal,pValWithComps,MajorType) \
+ (This)->lpVtbl -> GetCountOfType(This,Group,pVal,pValWithComps,MajorType)
+
+#define IAMTimeline_ValidateSourceNames(This,ValidateFlags,pOverride,NotifyEventHandle) \
+ (This)->lpVtbl -> ValidateSourceNames(This,ValidateFlags,pOverride,NotifyEventHandle)
+
+#define IAMTimeline_SetDefaultTransition(This,pGuid) \
+ (This)->lpVtbl -> SetDefaultTransition(This,pGuid)
+
+#define IAMTimeline_GetDefaultTransition(This,pGuid) \
+ (This)->lpVtbl -> GetDefaultTransition(This,pGuid)
+
+#define IAMTimeline_SetDefaultEffect(This,pGuid) \
+ (This)->lpVtbl -> SetDefaultEffect(This,pGuid)
+
+#define IAMTimeline_GetDefaultEffect(This,pGuid) \
+ (This)->lpVtbl -> GetDefaultEffect(This,pGuid)
+
+#define IAMTimeline_SetDefaultTransitionB(This,pGuid) \
+ (This)->lpVtbl -> SetDefaultTransitionB(This,pGuid)
+
+#define IAMTimeline_GetDefaultTransitionB(This,pGuid) \
+ (This)->lpVtbl -> GetDefaultTransitionB(This,pGuid)
+
+#define IAMTimeline_SetDefaultEffectB(This,pGuid) \
+ (This)->lpVtbl -> SetDefaultEffectB(This,pGuid)
+
+#define IAMTimeline_GetDefaultEffectB(This,pGuid) \
+ (This)->lpVtbl -> GetDefaultEffectB(This,pGuid)
+
+#endif /* COBJMACROS */
+
+
+#endif /* C style interface */
+
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimeline_CreateEmptyNode_Proxy(
+ IAMTimeline * This,
+ /* [out] */ IAMTimelineObj **ppObj,
+ TIMELINE_MAJOR_TYPE Type);
+
+
+void __RPC_STUB IAMTimeline_CreateEmptyNode_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+HRESULT STDMETHODCALLTYPE IAMTimeline_AddGroup_Proxy(
+ IAMTimeline * This,
+ IAMTimelineObj *pGroup);
+
+
+void __RPC_STUB IAMTimeline_AddGroup_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+HRESULT STDMETHODCALLTYPE IAMTimeline_RemGroupFromList_Proxy(
+ IAMTimeline * This,
+ IAMTimelineObj *pGroup);
+
+
+void __RPC_STUB IAMTimeline_RemGroupFromList_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+HRESULT STDMETHODCALLTYPE IAMTimeline_GetGroup_Proxy(
+ IAMTimeline * This,
+ /* [out] */ IAMTimelineObj **ppGroup,
+ long WhichGroup);
+
+
+void __RPC_STUB IAMTimeline_GetGroup_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+HRESULT STDMETHODCALLTYPE IAMTimeline_GetGroupCount_Proxy(
+ IAMTimeline * This,
+ long *pCount);
+
+
+void __RPC_STUB IAMTimeline_GetGroupCount_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+HRESULT STDMETHODCALLTYPE IAMTimeline_ClearAllGroups_Proxy(
+ IAMTimeline * This);
+
+
+void __RPC_STUB IAMTimeline_ClearAllGroups_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+HRESULT STDMETHODCALLTYPE IAMTimeline_GetInsertMode_Proxy(
+ IAMTimeline * This,
+ long *pMode);
+
+
+void __RPC_STUB IAMTimeline_GetInsertMode_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimeline_SetInsertMode_Proxy(
+ IAMTimeline * This,
+ long Mode);
+
+
+void __RPC_STUB IAMTimeline_SetInsertMode_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimeline_EnableTransitions_Proxy(
+ IAMTimeline * This,
+ BOOL fEnabled);
+
+
+void __RPC_STUB IAMTimeline_EnableTransitions_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimeline_TransitionsEnabled_Proxy(
+ IAMTimeline * This,
+ BOOL *pfEnabled);
+
+
+void __RPC_STUB IAMTimeline_TransitionsEnabled_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimeline_EnableEffects_Proxy(
+ IAMTimeline * This,
+ BOOL fEnabled);
+
+
+void __RPC_STUB IAMTimeline_EnableEffects_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimeline_EffectsEnabled_Proxy(
+ IAMTimeline * This,
+ BOOL *pfEnabled);
+
+
+void __RPC_STUB IAMTimeline_EffectsEnabled_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimeline_SetInterestRange_Proxy(
+ IAMTimeline * This,
+ REFERENCE_TIME Start,
+ REFERENCE_TIME Stop);
+
+
+void __RPC_STUB IAMTimeline_SetInterestRange_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimeline_GetDuration_Proxy(
+ IAMTimeline * This,
+ REFERENCE_TIME *pDuration);
+
+
+void __RPC_STUB IAMTimeline_GetDuration_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimeline_GetDuration2_Proxy(
+ IAMTimeline * This,
+ double *pDuration);
+
+
+void __RPC_STUB IAMTimeline_GetDuration2_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimeline_SetDefaultFPS_Proxy(
+ IAMTimeline * This,
+ double FPS);
+
+
+void __RPC_STUB IAMTimeline_SetDefaultFPS_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimeline_GetDefaultFPS_Proxy(
+ IAMTimeline * This,
+ double *pFPS);
+
+
+void __RPC_STUB IAMTimeline_GetDefaultFPS_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimeline_IsDirty_Proxy(
+ IAMTimeline * This,
+ BOOL *pDirty);
+
+
+void __RPC_STUB IAMTimeline_IsDirty_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimeline_GetDirtyRange_Proxy(
+ IAMTimeline * This,
+ REFERENCE_TIME *pStart,
+ REFERENCE_TIME *pStop);
+
+
+void __RPC_STUB IAMTimeline_GetDirtyRange_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMTimeline_GetCountOfType_Proxy(
+ IAMTimeline * This,
+ long Group,
+ long *pVal,
+ long *pValWithComps,
+ TIMELINE_MAJOR_TYPE MajorType);
+
+
+void __RPC_STUB IAMTimeline_GetCountOfType_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+HRESULT STDMETHODCALLTYPE IAMTimeline_ValidateSourceNames_Proxy(
+ IAMTimeline * This,
+ long ValidateFlags,
+ IMediaLocator *pOverride,
+ LONG_PTR NotifyEventHandle);
+
+
+void __RPC_STUB IAMTimeline_ValidateSourceNames_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+HRESULT STDMETHODCALLTYPE IAMTimeline_SetDefaultTransition_Proxy(
+ IAMTimeline * This,
+ GUID *pGuid);
+
+
+void __RPC_STUB IAMTimeline_SetDefaultTransition_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+HRESULT STDMETHODCALLTYPE IAMTimeline_GetDefaultTransition_Proxy(
+ IAMTimeline * This,
+ GUID *pGuid);
+
+
+void __RPC_STUB IAMTimeline_GetDefaultTransition_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+HRESULT STDMETHODCALLTYPE IAMTimeline_SetDefaultEffect_Proxy(
+ IAMTimeline * This,
+ GUID *pGuid);
+
+
+void __RPC_STUB IAMTimeline_SetDefaultEffect_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+HRESULT STDMETHODCALLTYPE IAMTimeline_GetDefaultEffect_Proxy(
+ IAMTimeline * This,
+ GUID *pGuid);
+
+
+void __RPC_STUB IAMTimeline_GetDefaultEffect_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+HRESULT STDMETHODCALLTYPE IAMTimeline_SetDefaultTransitionB_Proxy(
+ IAMTimeline * This,
+ BSTR pGuid);
+
+
+void __RPC_STUB IAMTimeline_SetDefaultTransitionB_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+HRESULT STDMETHODCALLTYPE IAMTimeline_GetDefaultTransitionB_Proxy(
+ IAMTimeline * This,
+ /* [retval][out] */ BSTR *pGuid);
+
+
+void __RPC_STUB IAMTimeline_GetDefaultTransitionB_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+HRESULT STDMETHODCALLTYPE IAMTimeline_SetDefaultEffectB_Proxy(
+ IAMTimeline * This,
+ BSTR pGuid);
+
+
+void __RPC_STUB IAMTimeline_SetDefaultEffectB_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+HRESULT STDMETHODCALLTYPE IAMTimeline_GetDefaultEffectB_Proxy(
+ IAMTimeline * This,
+ /* [retval][out] */ BSTR *pGuid);
+
+
+void __RPC_STUB IAMTimeline_GetDefaultEffectB_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+
+#endif /* __IAMTimeline_INTERFACE_DEFINED__ */
+
+
+#ifndef __IXml2Dex_INTERFACE_DEFINED__
+#define __IXml2Dex_INTERFACE_DEFINED__
+
+/* interface IXml2Dex */
+/* [unique][helpstring][uuid][object] */
+
+
+EXTERN_C const IID IID_IXml2Dex;
+
+#if defined(__cplusplus) && !defined(CINTERFACE)
+
+ MIDL_INTERFACE("18C628ED-962A-11D2-8D08-00A0C9441E20")
+ IXml2Dex : public IDispatch
+ {
+ public:
+ virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE CreateGraphFromFile(
+ /* [out] */ IUnknown **ppGraph,
+ IUnknown *pTimeline,
+ BSTR Filename) = 0;
+
+ virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE WriteGrfFile(
+ IUnknown *pGraph,
+ BSTR FileName) = 0;
+
+ virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE WriteXMLFile(
+ IUnknown *pTimeline,
+ BSTR FileName) = 0;
+
+ virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE ReadXMLFile(
+ IUnknown *pTimeline,
+ BSTR XMLName) = 0;
+
+ virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE Delete(
+ IUnknown *pTimeline,
+ double dStart,
+ double dEnd) = 0;
+
+ virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE WriteXMLPart(
+ IUnknown *pTimeline,
+ double dStart,
+ double dEnd,
+ BSTR FileName) = 0;
+
+ virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE PasteXMLFile(
+ IUnknown *pTimeline,
+ double dStart,
+ BSTR FileName) = 0;
+
+ virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE CopyXML(
+ IUnknown *pTimeline,
+ double dStart,
+ double dEnd) = 0;
+
+ virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE PasteXML(
+ IUnknown *pTimeline,
+ double dStart) = 0;
+
+ virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE Reset( void) = 0;
+
+ virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE ReadXML(
+ IUnknown *pTimeline,
+ IUnknown *pXML) = 0;
+
+ virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE WriteXML(
+ IUnknown *pTimeline,
+ BSTR *pbstrXML) = 0;
+
+ };
+
+#else /* C style interface */
+
+ typedef struct IXml2DexVtbl
+ {
+ BEGIN_INTERFACE
+
+ HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
+ IXml2Dex * This,
+ /* [in] */ REFIID riid,
+ /* [iid_is][out] */ void **ppvObject);
+
+ ULONG ( STDMETHODCALLTYPE *AddRef )(
+ IXml2Dex * This);
+
+ ULONG ( STDMETHODCALLTYPE *Release )(
+ IXml2Dex * This);
+
+ HRESULT ( STDMETHODCALLTYPE *GetTypeInfoCount )(
+ IXml2Dex * This,
+ /* [out] */ UINT *pctinfo);
+
+ HRESULT ( STDMETHODCALLTYPE *GetTypeInfo )(
+ IXml2Dex * This,
+ /* [in] */ UINT iTInfo,
+ /* [in] */ LCID lcid,
+ /* [out] */ ITypeInfo **ppTInfo);
+
+ HRESULT ( STDMETHODCALLTYPE *GetIDsOfNames )(
+ IXml2Dex * This,
+ /* [in] */ REFIID riid,
+ /* [size_is][in] */ LPOLESTR *rgszNames,
+ /* [in] */ UINT cNames,
+ /* [in] */ LCID lcid,
+ /* [size_is][out] */ DISPID *rgDispId);
+
+ /* [local] */ HRESULT ( STDMETHODCALLTYPE *Invoke )(
+ IXml2Dex * This,
+ /* [in] */ DISPID dispIdMember,
+ /* [in] */ REFIID riid,
+ /* [in] */ LCID lcid,
+ /* [in] */ WORD wFlags,
+ /* [out][in] */ DISPPARAMS *pDispParams,
+ /* [out] */ VARIANT *pVarResult,
+ /* [out] */ EXCEPINFO *pExcepInfo,
+ /* [out] */ UINT *puArgErr);
+
+ /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *CreateGraphFromFile )(
+ IXml2Dex * This,
+ /* [out] */ IUnknown **ppGraph,
+ IUnknown *pTimeline,
+ BSTR Filename);
+
+ /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *WriteGrfFile )(
+ IXml2Dex * This,
+ IUnknown *pGraph,
+ BSTR FileName);
+
+ /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *WriteXMLFile )(
+ IXml2Dex * This,
+ IUnknown *pTimeline,
+ BSTR FileName);
+
+ /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *ReadXMLFile )(
+ IXml2Dex * This,
+ IUnknown *pTimeline,
+ BSTR XMLName);
+
+ /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *Delete )(
+ IXml2Dex * This,
+ IUnknown *pTimeline,
+ double dStart,
+ double dEnd);
+
+ /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *WriteXMLPart )(
+ IXml2Dex * This,
+ IUnknown *pTimeline,
+ double dStart,
+ double dEnd,
+ BSTR FileName);
+
+ /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *PasteXMLFile )(
+ IXml2Dex * This,
+ IUnknown *pTimeline,
+ double dStart,
+ BSTR FileName);
+
+ /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *CopyXML )(
+ IXml2Dex * This,
+ IUnknown *pTimeline,
+ double dStart,
+ double dEnd);
+
+ /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *PasteXML )(
+ IXml2Dex * This,
+ IUnknown *pTimeline,
+ double dStart);
+
+ /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *Reset )(
+ IXml2Dex * This);
+
+ /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *ReadXML )(
+ IXml2Dex * This,
+ IUnknown *pTimeline,
+ IUnknown *pXML);
+
+ /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *WriteXML )(
+ IXml2Dex * This,
+ IUnknown *pTimeline,
+ BSTR *pbstrXML);
+
+ END_INTERFACE
+ } IXml2DexVtbl;
+
+ interface IXml2Dex
+ {
+ CONST_VTBL struct IXml2DexVtbl *lpVtbl;
+ };
+
+
+
+#ifdef COBJMACROS
+
+
+#define IXml2Dex_QueryInterface(This,riid,ppvObject) \
+ (This)->lpVtbl -> QueryInterface(This,riid,ppvObject)
+
+#define IXml2Dex_AddRef(This) \
+ (This)->lpVtbl -> AddRef(This)
+
+#define IXml2Dex_Release(This) \
+ (This)->lpVtbl -> Release(This)
+
+
+#define IXml2Dex_GetTypeInfoCount(This,pctinfo) \
+ (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo)
+
+#define IXml2Dex_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \
+ (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo)
+
+#define IXml2Dex_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \
+ (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId)
+
+#define IXml2Dex_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \
+ (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr)
+
+
+#define IXml2Dex_CreateGraphFromFile(This,ppGraph,pTimeline,Filename) \
+ (This)->lpVtbl -> CreateGraphFromFile(This,ppGraph,pTimeline,Filename)
+
+#define IXml2Dex_WriteGrfFile(This,pGraph,FileName) \
+ (This)->lpVtbl -> WriteGrfFile(This,pGraph,FileName)
+
+#define IXml2Dex_WriteXMLFile(This,pTimeline,FileName) \
+ (This)->lpVtbl -> WriteXMLFile(This,pTimeline,FileName)
+
+#define IXml2Dex_ReadXMLFile(This,pTimeline,XMLName) \
+ (This)->lpVtbl -> ReadXMLFile(This,pTimeline,XMLName)
+
+#define IXml2Dex_Delete(This,pTimeline,dStart,dEnd) \
+ (This)->lpVtbl -> Delete(This,pTimeline,dStart,dEnd)
+
+#define IXml2Dex_WriteXMLPart(This,pTimeline,dStart,dEnd,FileName) \
+ (This)->lpVtbl -> WriteXMLPart(This,pTimeline,dStart,dEnd,FileName)
+
+#define IXml2Dex_PasteXMLFile(This,pTimeline,dStart,FileName) \
+ (This)->lpVtbl -> PasteXMLFile(This,pTimeline,dStart,FileName)
+
+#define IXml2Dex_CopyXML(This,pTimeline,dStart,dEnd) \
+ (This)->lpVtbl -> CopyXML(This,pTimeline,dStart,dEnd)
+
+#define IXml2Dex_PasteXML(This,pTimeline,dStart) \
+ (This)->lpVtbl -> PasteXML(This,pTimeline,dStart)
+
+#define IXml2Dex_Reset(This) \
+ (This)->lpVtbl -> Reset(This)
+
+#define IXml2Dex_ReadXML(This,pTimeline,pXML) \
+ (This)->lpVtbl -> ReadXML(This,pTimeline,pXML)
+
+#define IXml2Dex_WriteXML(This,pTimeline,pbstrXML) \
+ (This)->lpVtbl -> WriteXML(This,pTimeline,pbstrXML)
+
+#endif /* COBJMACROS */
+
+
+#endif /* C style interface */
+
+
+
+/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IXml2Dex_CreateGraphFromFile_Proxy(
+ IXml2Dex * This,
+ /* [out] */ IUnknown **ppGraph,
+ IUnknown *pTimeline,
+ BSTR Filename);
+
+
+void __RPC_STUB IXml2Dex_CreateGraphFromFile_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IXml2Dex_WriteGrfFile_Proxy(
+ IXml2Dex * This,
+ IUnknown *pGraph,
+ BSTR FileName);
+
+
+void __RPC_STUB IXml2Dex_WriteGrfFile_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IXml2Dex_WriteXMLFile_Proxy(
+ IXml2Dex * This,
+ IUnknown *pTimeline,
+ BSTR FileName);
+
+
+void __RPC_STUB IXml2Dex_WriteXMLFile_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IXml2Dex_ReadXMLFile_Proxy(
+ IXml2Dex * This,
+ IUnknown *pTimeline,
+ BSTR XMLName);
+
+
+void __RPC_STUB IXml2Dex_ReadXMLFile_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IXml2Dex_Delete_Proxy(
+ IXml2Dex * This,
+ IUnknown *pTimeline,
+ double dStart,
+ double dEnd);
+
+
+void __RPC_STUB IXml2Dex_Delete_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IXml2Dex_WriteXMLPart_Proxy(
+ IXml2Dex * This,
+ IUnknown *pTimeline,
+ double dStart,
+ double dEnd,
+ BSTR FileName);
+
+
+void __RPC_STUB IXml2Dex_WriteXMLPart_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IXml2Dex_PasteXMLFile_Proxy(
+ IXml2Dex * This,
+ IUnknown *pTimeline,
+ double dStart,
+ BSTR FileName);
+
+
+void __RPC_STUB IXml2Dex_PasteXMLFile_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IXml2Dex_CopyXML_Proxy(
+ IXml2Dex * This,
+ IUnknown *pTimeline,
+ double dStart,
+ double dEnd);
+
+
+void __RPC_STUB IXml2Dex_CopyXML_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IXml2Dex_PasteXML_Proxy(
+ IXml2Dex * This,
+ IUnknown *pTimeline,
+ double dStart);
+
+
+void __RPC_STUB IXml2Dex_PasteXML_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IXml2Dex_Reset_Proxy(
+ IXml2Dex * This);
+
+
+void __RPC_STUB IXml2Dex_Reset_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IXml2Dex_ReadXML_Proxy(
+ IXml2Dex * This,
+ IUnknown *pTimeline,
+ IUnknown *pXML);
+
+
+void __RPC_STUB IXml2Dex_ReadXML_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IXml2Dex_WriteXML_Proxy(
+ IXml2Dex * This,
+ IUnknown *pTimeline,
+ BSTR *pbstrXML);
+
+
+void __RPC_STUB IXml2Dex_WriteXML_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+
+#endif /* __IXml2Dex_INTERFACE_DEFINED__ */
+
+
+#ifndef __IAMErrorLog_INTERFACE_DEFINED__
+#define __IAMErrorLog_INTERFACE_DEFINED__
+
+/* interface IAMErrorLog */
+/* [unique][helpstring][uuid][object] */
+
+
+EXTERN_C const IID IID_IAMErrorLog;
+
+#if defined(__cplusplus) && !defined(CINTERFACE)
+
+ MIDL_INTERFACE("E43E73A2-0EFA-11d3-9601-00A0C9441E20")
+ IAMErrorLog : public IUnknown
+ {
+ public:
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE LogError(
+ long Severity,
+ BSTR pErrorString,
+ long ErrorCode,
+ long hresult,
+ /* [in] */ VARIANT *pExtraInfo) = 0;
+
+ };
+
+#else /* C style interface */
+
+ typedef struct IAMErrorLogVtbl
+ {
+ BEGIN_INTERFACE
+
+ HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
+ IAMErrorLog * This,
+ /* [in] */ REFIID riid,
+ /* [iid_is][out] */ void **ppvObject);
+
+ ULONG ( STDMETHODCALLTYPE *AddRef )(
+ IAMErrorLog * This);
+
+ ULONG ( STDMETHODCALLTYPE *Release )(
+ IAMErrorLog * This);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *LogError )(
+ IAMErrorLog * This,
+ long Severity,
+ BSTR pErrorString,
+ long ErrorCode,
+ long hresult,
+ /* [in] */ VARIANT *pExtraInfo);
+
+ END_INTERFACE
+ } IAMErrorLogVtbl;
+
+ interface IAMErrorLog
+ {
+ CONST_VTBL struct IAMErrorLogVtbl *lpVtbl;
+ };
+
+
+
+#ifdef COBJMACROS
+
+
+#define IAMErrorLog_QueryInterface(This,riid,ppvObject) \
+ (This)->lpVtbl -> QueryInterface(This,riid,ppvObject)
+
+#define IAMErrorLog_AddRef(This) \
+ (This)->lpVtbl -> AddRef(This)
+
+#define IAMErrorLog_Release(This) \
+ (This)->lpVtbl -> Release(This)
+
+
+#define IAMErrorLog_LogError(This,Severity,pErrorString,ErrorCode,hresult,pExtraInfo) \
+ (This)->lpVtbl -> LogError(This,Severity,pErrorString,ErrorCode,hresult,pExtraInfo)
+
+#endif /* COBJMACROS */
+
+
+#endif /* C style interface */
+
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IAMErrorLog_LogError_Proxy(
+ IAMErrorLog * This,
+ long Severity,
+ BSTR pErrorString,
+ long ErrorCode,
+ long hresult,
+ /* [in] */ VARIANT *pExtraInfo);
+
+
+void __RPC_STUB IAMErrorLog_LogError_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+
+#endif /* __IAMErrorLog_INTERFACE_DEFINED__ */
+
+
+#ifndef __IAMSetErrorLog_INTERFACE_DEFINED__
+#define __IAMSetErrorLog_INTERFACE_DEFINED__
+
+/* interface IAMSetErrorLog */
+/* [unique][helpstring][uuid][object] */
+
+
+EXTERN_C const IID IID_IAMSetErrorLog;
+
+#if defined(__cplusplus) && !defined(CINTERFACE)
+
+ MIDL_INTERFACE("963566DA-BE21-4eaf-88E9-35704F8F52A1")
+ IAMSetErrorLog : public IUnknown
+ {
+ public:
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_ErrorLog(
+ /* [retval][out] */ IAMErrorLog **pVal) = 0;
+
+ virtual /* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_ErrorLog(
+ /* [in] */ IAMErrorLog *newVal) = 0;
+
+ };
+
+#else /* C style interface */
+
+ typedef struct IAMSetErrorLogVtbl
+ {
+ BEGIN_INTERFACE
+
+ HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
+ IAMSetErrorLog * This,
+ /* [in] */ REFIID riid,
+ /* [iid_is][out] */ void **ppvObject);
+
+ ULONG ( STDMETHODCALLTYPE *AddRef )(
+ IAMSetErrorLog * This);
+
+ ULONG ( STDMETHODCALLTYPE *Release )(
+ IAMSetErrorLog * This);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_ErrorLog )(
+ IAMSetErrorLog * This,
+ /* [retval][out] */ IAMErrorLog **pVal);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE *put_ErrorLog )(
+ IAMSetErrorLog * This,
+ /* [in] */ IAMErrorLog *newVal);
+
+ END_INTERFACE
+ } IAMSetErrorLogVtbl;
+
+ interface IAMSetErrorLog
+ {
+ CONST_VTBL struct IAMSetErrorLogVtbl *lpVtbl;
+ };
+
+
+
+#ifdef COBJMACROS
+
+
+#define IAMSetErrorLog_QueryInterface(This,riid,ppvObject) \
+ (This)->lpVtbl -> QueryInterface(This,riid,ppvObject)
+
+#define IAMSetErrorLog_AddRef(This) \
+ (This)->lpVtbl -> AddRef(This)
+
+#define IAMSetErrorLog_Release(This) \
+ (This)->lpVtbl -> Release(This)
+
+
+#define IAMSetErrorLog_get_ErrorLog(This,pVal) \
+ (This)->lpVtbl -> get_ErrorLog(This,pVal)
+
+#define IAMSetErrorLog_put_ErrorLog(This,newVal) \
+ (This)->lpVtbl -> put_ErrorLog(This,newVal)
+
+#endif /* COBJMACROS */
+
+
+#endif /* C style interface */
+
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IAMSetErrorLog_get_ErrorLog_Proxy(
+ IAMSetErrorLog * This,
+ /* [retval][out] */ IAMErrorLog **pVal);
+
+
+void __RPC_STUB IAMSetErrorLog_get_ErrorLog_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE IAMSetErrorLog_put_ErrorLog_Proxy(
+ IAMSetErrorLog * This,
+ /* [in] */ IAMErrorLog *newVal);
+
+
+void __RPC_STUB IAMSetErrorLog_put_ErrorLog_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+
+#endif /* __IAMSetErrorLog_INTERFACE_DEFINED__ */
+
+
+#ifndef __ISampleGrabberCB_INTERFACE_DEFINED__
+#define __ISampleGrabberCB_INTERFACE_DEFINED__
+
+/* interface ISampleGrabberCB */
+/* [unique][helpstring][local][uuid][object] */
+
+
+EXTERN_C const IID IID_ISampleGrabberCB;
+
+#if defined(__cplusplus) && !defined(CINTERFACE)
+
+ MIDL_INTERFACE("0579154A-2B53-4994-B0D0-E773148EFF85")
+ ISampleGrabberCB : public IUnknown
+ {
+ public:
+ virtual HRESULT STDMETHODCALLTYPE SampleCB(
+ double SampleTime,
+ IMediaSample *pSample) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE BufferCB(
+ double SampleTime,
+ BYTE *pBuffer,
+ long BufferLen) = 0;
+
+ };
+
+#else /* C style interface */
+
+ typedef struct ISampleGrabberCBVtbl
+ {
+ BEGIN_INTERFACE
+
+ HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
+ ISampleGrabberCB * This,
+ /* [in] */ REFIID riid,
+ /* [iid_is][out] */ void **ppvObject);
+
+ ULONG ( STDMETHODCALLTYPE *AddRef )(
+ ISampleGrabberCB * This);
+
+ ULONG ( STDMETHODCALLTYPE *Release )(
+ ISampleGrabberCB * This);
+
+ HRESULT ( STDMETHODCALLTYPE *SampleCB )(
+ ISampleGrabberCB * This,
+ double SampleTime,
+ IMediaSample *pSample);
+
+ HRESULT ( STDMETHODCALLTYPE *BufferCB )(
+ ISampleGrabberCB * This,
+ double SampleTime,
+ BYTE *pBuffer,
+ long BufferLen);
+
+ END_INTERFACE
+ } ISampleGrabberCBVtbl;
+
+ interface ISampleGrabberCB
+ {
+ CONST_VTBL struct ISampleGrabberCBVtbl *lpVtbl;
+ };
+
+
+
+#ifdef COBJMACROS
+
+
+#define ISampleGrabberCB_QueryInterface(This,riid,ppvObject) \
+ (This)->lpVtbl -> QueryInterface(This,riid,ppvObject)
+
+#define ISampleGrabberCB_AddRef(This) \
+ (This)->lpVtbl -> AddRef(This)
+
+#define ISampleGrabberCB_Release(This) \
+ (This)->lpVtbl -> Release(This)
+
+
+#define ISampleGrabberCB_SampleCB(This,SampleTime,pSample) \
+ (This)->lpVtbl -> SampleCB(This,SampleTime,pSample)
+
+#define ISampleGrabberCB_BufferCB(This,SampleTime,pBuffer,BufferLen) \
+ (This)->lpVtbl -> BufferCB(This,SampleTime,pBuffer,BufferLen)
+
+#endif /* COBJMACROS */
+
+
+#endif /* C style interface */
+
+
+
+HRESULT STDMETHODCALLTYPE ISampleGrabberCB_SampleCB_Proxy(
+ ISampleGrabberCB * This,
+ double SampleTime,
+ IMediaSample *pSample);
+
+
+void __RPC_STUB ISampleGrabberCB_SampleCB_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+HRESULT STDMETHODCALLTYPE ISampleGrabberCB_BufferCB_Proxy(
+ ISampleGrabberCB * This,
+ double SampleTime,
+ BYTE *pBuffer,
+ long BufferLen);
+
+
+void __RPC_STUB ISampleGrabberCB_BufferCB_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+
+#endif /* __ISampleGrabberCB_INTERFACE_DEFINED__ */
+
+
+#ifndef __ISampleGrabber_INTERFACE_DEFINED__
+#define __ISampleGrabber_INTERFACE_DEFINED__
+
+/* interface ISampleGrabber */
+/* [unique][helpstring][local][uuid][object] */
+
+
+EXTERN_C const IID IID_ISampleGrabber;
+
+#if defined(__cplusplus) && !defined(CINTERFACE)
+
+ MIDL_INTERFACE("6B652FFF-11FE-4fce-92AD-0266B5D7C78F")
+ ISampleGrabber : public IUnknown
+ {
+ public:
+ virtual HRESULT STDMETHODCALLTYPE SetOneShot(
+ BOOL OneShot) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE SetMediaType(
+ const AM_MEDIA_TYPE *pType) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE GetConnectedMediaType(
+ AM_MEDIA_TYPE *pType) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE SetBufferSamples(
+ BOOL BufferThem) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE GetCurrentBuffer(
+ /* [out][in] */ long *pBufferSize,
+ /* [out] */ long *pBuffer) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE GetCurrentSample(
+ /* [retval][out] */ IMediaSample **ppSample) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE SetCallback(
+ ISampleGrabberCB *pCallback,
+ long WhichMethodToCallback) = 0;
+
+ };
+
+#else /* C style interface */
+
+ typedef struct ISampleGrabberVtbl
+ {
+ BEGIN_INTERFACE
+
+ HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
+ ISampleGrabber * This,
+ /* [in] */ REFIID riid,
+ /* [iid_is][out] */ void **ppvObject);
+
+ ULONG ( STDMETHODCALLTYPE *AddRef )(
+ ISampleGrabber * This);
+
+ ULONG ( STDMETHODCALLTYPE *Release )(
+ ISampleGrabber * This);
+
+ HRESULT ( STDMETHODCALLTYPE *SetOneShot )(
+ ISampleGrabber * This,
+ BOOL OneShot);
+
+ HRESULT ( STDMETHODCALLTYPE *SetMediaType )(
+ ISampleGrabber * This,
+ const AM_MEDIA_TYPE *pType);
+
+ HRESULT ( STDMETHODCALLTYPE *GetConnectedMediaType )(
+ ISampleGrabber * This,
+ AM_MEDIA_TYPE *pType);
+
+ HRESULT ( STDMETHODCALLTYPE *SetBufferSamples )(
+ ISampleGrabber * This,
+ BOOL BufferThem);
+
+ HRESULT ( STDMETHODCALLTYPE *GetCurrentBuffer )(
+ ISampleGrabber * This,
+ /* [out][in] */ long *pBufferSize,
+ /* [out] */ long *pBuffer);
+
+ HRESULT ( STDMETHODCALLTYPE *GetCurrentSample )(
+ ISampleGrabber * This,
+ /* [retval][out] */ IMediaSample **ppSample);
+
+ HRESULT ( STDMETHODCALLTYPE *SetCallback )(
+ ISampleGrabber * This,
+ ISampleGrabberCB *pCallback,
+ long WhichMethodToCallback);
+
+ END_INTERFACE
+ } ISampleGrabberVtbl;
+
+ interface ISampleGrabber
+ {
+ CONST_VTBL struct ISampleGrabberVtbl *lpVtbl;
+ };
+
+
+
+#ifdef COBJMACROS
+
+
+#define ISampleGrabber_QueryInterface(This,riid,ppvObject) \
+ (This)->lpVtbl -> QueryInterface(This,riid,ppvObject)
+
+#define ISampleGrabber_AddRef(This) \
+ (This)->lpVtbl -> AddRef(This)
+
+#define ISampleGrabber_Release(This) \
+ (This)->lpVtbl -> Release(This)
+
+
+#define ISampleGrabber_SetOneShot(This,OneShot) \
+ (This)->lpVtbl -> SetOneShot(This,OneShot)
+
+#define ISampleGrabber_SetMediaType(This,pType) \
+ (This)->lpVtbl -> SetMediaType(This,pType)
+
+#define ISampleGrabber_GetConnectedMediaType(This,pType) \
+ (This)->lpVtbl -> GetConnectedMediaType(This,pType)
+
+#define ISampleGrabber_SetBufferSamples(This,BufferThem) \
+ (This)->lpVtbl -> SetBufferSamples(This,BufferThem)
+
+#define ISampleGrabber_GetCurrentBuffer(This,pBufferSize,pBuffer) \
+ (This)->lpVtbl -> GetCurrentBuffer(This,pBufferSize,pBuffer)
+
+#define ISampleGrabber_GetCurrentSample(This,ppSample) \
+ (This)->lpVtbl -> GetCurrentSample(This,ppSample)
+
+#define ISampleGrabber_SetCallback(This,pCallback,WhichMethodToCallback) \
+ (This)->lpVtbl -> SetCallback(This,pCallback,WhichMethodToCallback)
+
+#endif /* COBJMACROS */
+
+
+#endif /* C style interface */
+
+
+
+HRESULT STDMETHODCALLTYPE ISampleGrabber_SetOneShot_Proxy(
+ ISampleGrabber * This,
+ BOOL OneShot);
+
+
+void __RPC_STUB ISampleGrabber_SetOneShot_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+HRESULT STDMETHODCALLTYPE ISampleGrabber_SetMediaType_Proxy(
+ ISampleGrabber * This,
+ const AM_MEDIA_TYPE *pType);
+
+
+void __RPC_STUB ISampleGrabber_SetMediaType_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+HRESULT STDMETHODCALLTYPE ISampleGrabber_GetConnectedMediaType_Proxy(
+ ISampleGrabber * This,
+ AM_MEDIA_TYPE *pType);
+
+
+void __RPC_STUB ISampleGrabber_GetConnectedMediaType_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+HRESULT STDMETHODCALLTYPE ISampleGrabber_SetBufferSamples_Proxy(
+ ISampleGrabber * This,
+ BOOL BufferThem);
+
+
+void __RPC_STUB ISampleGrabber_SetBufferSamples_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+HRESULT STDMETHODCALLTYPE ISampleGrabber_GetCurrentBuffer_Proxy(
+ ISampleGrabber * This,
+ /* [out][in] */ long *pBufferSize,
+ /* [out] */ long *pBuffer);
+
+
+void __RPC_STUB ISampleGrabber_GetCurrentBuffer_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+HRESULT STDMETHODCALLTYPE ISampleGrabber_GetCurrentSample_Proxy(
+ ISampleGrabber * This,
+ /* [retval][out] */ IMediaSample **ppSample);
+
+
+void __RPC_STUB ISampleGrabber_GetCurrentSample_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+HRESULT STDMETHODCALLTYPE ISampleGrabber_SetCallback_Proxy(
+ ISampleGrabber * This,
+ ISampleGrabberCB *pCallback,
+ long WhichMethodToCallback);
+
+
+void __RPC_STUB ISampleGrabber_SetCallback_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+
+#endif /* __ISampleGrabber_INTERFACE_DEFINED__ */
+
+
+
+#ifndef __DexterLib_LIBRARY_DEFINED__
+#define __DexterLib_LIBRARY_DEFINED__
+
+/* library DexterLib */
+/* [helpstring][version][uuid] */
+
+
+EXTERN_C const IID LIBID_DexterLib;
+
+EXTERN_C const CLSID CLSID_AMTimeline;
+
+#ifdef __cplusplus
+
+class DECLSPEC_UUID("78530B75-61F9-11D2-8CAD-00A024580902")
+AMTimeline;
+#endif
+
+EXTERN_C const CLSID CLSID_AMTimelineObj;
+
+#ifdef __cplusplus
+
+class DECLSPEC_UUID("78530B78-61F9-11D2-8CAD-00A024580902")
+AMTimelineObj;
+#endif
+
+EXTERN_C const CLSID CLSID_AMTimelineSrc;
+
+#ifdef __cplusplus
+
+class DECLSPEC_UUID("78530B7A-61F9-11D2-8CAD-00A024580902")
+AMTimelineSrc;
+#endif
+
+EXTERN_C const CLSID CLSID_AMTimelineTrack;
+
+#ifdef __cplusplus
+
+class DECLSPEC_UUID("8F6C3C50-897B-11d2-8CFB-00A0C9441E20")
+AMTimelineTrack;
+#endif
+
+EXTERN_C const CLSID CLSID_AMTimelineComp;
+
+#ifdef __cplusplus
+
+class DECLSPEC_UUID("74D2EC80-6233-11d2-8CAD-00A024580902")
+AMTimelineComp;
+#endif
+
+EXTERN_C const CLSID CLSID_AMTimelineGroup;
+
+#ifdef __cplusplus
+
+class DECLSPEC_UUID("F6D371E1-B8A6-11d2-8023-00C0DF10D434")
+AMTimelineGroup;
+#endif
+
+EXTERN_C const CLSID CLSID_AMTimelineTrans;
+
+#ifdef __cplusplus
+
+class DECLSPEC_UUID("74D2EC81-6233-11d2-8CAD-00A024580902")
+AMTimelineTrans;
+#endif
+
+EXTERN_C const CLSID CLSID_AMTimelineEffect;
+
+#ifdef __cplusplus
+
+class DECLSPEC_UUID("74D2EC82-6233-11d2-8CAD-00A024580902")
+AMTimelineEffect;
+#endif
+
+EXTERN_C const CLSID CLSID_RenderEngine;
+
+#ifdef __cplusplus
+
+class DECLSPEC_UUID("64D8A8E0-80A2-11d2-8CF3-00A0C9441E20")
+RenderEngine;
+#endif
+
+EXTERN_C const CLSID CLSID_SmartRenderEngine;
+
+#ifdef __cplusplus
+
+class DECLSPEC_UUID("498B0949-BBE9-4072-98BE-6CCAEB79DC6F")
+SmartRenderEngine;
+#endif
+
+EXTERN_C const CLSID CLSID_AudMixer;
+
+#ifdef __cplusplus
+
+class DECLSPEC_UUID("036A9790-C153-11d2-9EF7-006008039E37")
+AudMixer;
+#endif
+
+EXTERN_C const CLSID CLSID_Xml2Dex;
+
+#ifdef __cplusplus
+
+class DECLSPEC_UUID("18C628EE-962A-11D2-8D08-00A0C9441E20")
+Xml2Dex;
+#endif
+
+EXTERN_C const CLSID CLSID_MediaLocator;
+
+#ifdef __cplusplus
+
+class DECLSPEC_UUID("CC1101F2-79DC-11D2-8CE6-00A0C9441E20")
+MediaLocator;
+#endif
+
+EXTERN_C const CLSID CLSID_PropertySetter;
+
+#ifdef __cplusplus
+
+class DECLSPEC_UUID("ADF95821-DED7-11d2-ACBE-0080C75E246E")
+PropertySetter;
+#endif
+
+EXTERN_C const CLSID CLSID_MediaDet;
+
+#ifdef __cplusplus
+
+class DECLSPEC_UUID("65BD0711-24D2-4ff7-9324-ED2E5D3ABAFA")
+MediaDet;
+#endif
+
+EXTERN_C const CLSID CLSID_SampleGrabber;
+
+#ifdef __cplusplus
+
+class DECLSPEC_UUID("C1F400A0-3F08-11d3-9F0B-006008039E37")
+SampleGrabber;
+#endif
+
+EXTERN_C const CLSID CLSID_NullRenderer;
+
+#ifdef __cplusplus
+
+class DECLSPEC_UUID("C1F400A4-3F08-11d3-9F0B-006008039E37")
+NullRenderer;
+#endif
+
+EXTERN_C const CLSID CLSID_DxtCompositor;
+
+#ifdef __cplusplus
+
+class DECLSPEC_UUID("BB44391D-6ABD-422f-9E2E-385C9DFF51FC")
+DxtCompositor;
+#endif
+
+EXTERN_C const CLSID CLSID_DxtAlphaSetter;
+
+#ifdef __cplusplus
+
+class DECLSPEC_UUID("506D89AE-909A-44f7-9444-ABD575896E35")
+DxtAlphaSetter;
+#endif
+
+EXTERN_C const CLSID CLSID_DxtJpeg;
+
+#ifdef __cplusplus
+
+class DECLSPEC_UUID("DE75D012-7A65-11D2-8CEA-00A0C9441E20")
+DxtJpeg;
+#endif
+
+EXTERN_C const CLSID CLSID_ColorSource;
+
+#ifdef __cplusplus
+
+class DECLSPEC_UUID("0cfdd070-581a-11d2-9ee6-006008039e37")
+ColorSource;
+#endif
+
+EXTERN_C const CLSID CLSID_DxtKey;
+
+#ifdef __cplusplus
+
+class DECLSPEC_UUID("C5B19592-145E-11d3-9F04-006008039E37")
+DxtKey;
+#endif
+#endif /* __DexterLib_LIBRARY_DEFINED__ */
+
+/* interface __MIDL_itf_qedit_0450 */
+/* [local] */
+
+
+enum __MIDL___MIDL_itf_qedit_0450_0001
+ { E_NOTINTREE = 0x80040400,
+ E_RENDER_ENGINE_IS_BROKEN = 0x80040401,
+ E_MUST_INIT_RENDERER = 0x80040402,
+ E_NOTDETERMINED = 0x80040403,
+ E_NO_TIMELINE = 0x80040404,
+ S_WARN_OUTPUTRESET = 40404
+ } ;
+#define DEX_IDS_BAD_SOURCE_NAME 1400
+#define DEX_IDS_BAD_SOURCE_NAME2 1401
+#define DEX_IDS_MISSING_SOURCE_NAME 1402
+#define DEX_IDS_UNKNOWN_SOURCE 1403
+#define DEX_IDS_INSTALL_PROBLEM 1404
+#define DEX_IDS_NO_SOURCE_NAMES 1405
+#define DEX_IDS_BAD_MEDIATYPE 1406
+#define DEX_IDS_STREAM_NUMBER 1407
+#define DEX_IDS_OUTOFMEMORY 1408
+#define DEX_IDS_DIBSEQ_NOTALLSAME 1409
+#define DEX_IDS_CLIPTOOSHORT 1410
+#define DEX_IDS_INVALID_DXT 1411
+#define DEX_IDS_INVALID_DEFAULT_DXT 1412
+#define DEX_IDS_NO_3D 1413
+#define DEX_IDS_BROKEN_DXT 1414
+#define DEX_IDS_NO_SUCH_PROPERTY 1415
+#define DEX_IDS_ILLEGAL_PROPERTY_VAL 1416
+#define DEX_IDS_INVALID_XML 1417
+#define DEX_IDS_CANT_FIND_FILTER 1418
+#define DEX_IDS_DISK_WRITE_ERROR 1419
+#define DEX_IDS_INVALID_AUDIO_FX 1420
+#define DEX_IDS_CANT_FIND_COMPRESSOR 1421
+#define DEX_IDS_TIMELINE_PARSE 1426
+#define DEX_IDS_GRAPH_ERROR 1427
+#define DEX_IDS_GRID_ERROR 1428
+#define DEX_IDS_INTERFACE_ERROR 1429
+EXTERN_GUID(CLSID_VideoEffects1Category, 0xcc7bfb42, 0xf175, 0x11d1, 0xa3, 0x92, 0x0, 0xe0, 0x29, 0x1f, 0x39, 0x59);
+EXTERN_GUID(CLSID_VideoEffects2Category, 0xcc7bfb43, 0xf175, 0x11d1, 0xa3, 0x92, 0x0, 0xe0, 0x29, 0x1f, 0x39, 0x59);
+EXTERN_GUID(CLSID_AudioEffects1Category, 0xcc7bfb44, 0xf175, 0x11d1, 0xa3, 0x92, 0x0, 0xe0, 0x29, 0x1f, 0x39, 0x59);
+EXTERN_GUID(CLSID_AudioEffects2Category, 0xcc7bfb45, 0xf175, 0x11d1, 0xa3, 0x92, 0x0, 0xe0, 0x29, 0x1f, 0x39, 0x59);
+
+
+extern RPC_IF_HANDLE __MIDL_itf_qedit_0450_v0_0_c_ifspec;
+extern RPC_IF_HANDLE __MIDL_itf_qedit_0450_v0_0_s_ifspec;
+
+/* Additional Prototypes for ALL interfaces */
+
+unsigned long __RPC_USER BSTR_UserSize( unsigned long *, unsigned long , BSTR * );
+unsigned char * __RPC_USER BSTR_UserMarshal( unsigned long *, unsigned char *, BSTR * );
+unsigned char * __RPC_USER BSTR_UserUnmarshal(unsigned long *, unsigned char *, BSTR * );
+void __RPC_USER BSTR_UserFree( unsigned long *, BSTR * );
+
+unsigned long __RPC_USER VARIANT_UserSize( unsigned long *, unsigned long , VARIANT * );
+unsigned char * __RPC_USER VARIANT_UserMarshal( unsigned long *, unsigned char *, VARIANT * );
+unsigned char * __RPC_USER VARIANT_UserUnmarshal(unsigned long *, unsigned char *, VARIANT * );
+void __RPC_USER VARIANT_UserFree( unsigned long *, VARIANT * );
+
+/* end of Additional Prototypes */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
diff --git a/src/imaging/test_comp.png b/src/imaging/test_comp.png
new file mode 100644
index 0000000..35d498e
--- /dev/null
+++ b/src/imaging/test_comp.png
Binary files differ
diff --git a/src/imaging/testimaging.cpp b/src/imaging/testimaging.cpp
new file mode 100644
index 0000000..9877c12
--- /dev/null
+++ b/src/imaging/testimaging.cpp
@@ -0,0 +1,239 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "FakeCamera.h"
+#include "TrackerThread.h"
+#include "TrackerConfig.h"
+#include "DeDistort.h"
+#include "FilterWipeBorder.h"
+#include "FilterClearBorder.h"
+
+#include "../graphics/GraphicsTest.h"
+#include "../graphics/Filtergrayscale.h"
+#include "../graphics/BitmapLoader.h"
+
+#include "../base/TestSuite.h"
+#include "../base/Exception.h"
+#include "../base/FileHelper.h"
+#include "../base/MathHelper.h"
+
+#include <boost/thread/thread.hpp>
+#include <boost/bind.hpp>
+
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sstream>
+
+#include <glib-object.h>
+
+using namespace avg;
+using namespace std;
+
+class FilterWipeBorderTest: public GraphicsTest
+{
+public:
+ FilterWipeBorderTest()
+ : GraphicsTest("FilterWipeBorderTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+ BitmapPtr pBmp = loadTestBmp("filterwipeborder", I8);
+ BitmapPtr pDestBmp = FilterWipeBorder(0).apply(pBmp);
+ testEqual(*pDestBmp, *pBmp, "FilterWipeBorderResult0", 0, 0);
+ pDestBmp = FilterWipeBorder(1).apply(pBmp);
+ testEqual(*pDestBmp, "FilterWipeBorderResult1", I8);
+ pDestBmp = FilterWipeBorder(3).apply(pBmp);
+ testEqual(*pDestBmp, "FilterWipeBorderResult3", I8);
+ }
+};
+
+class FilterClearBorderTest: public GraphicsTest
+{
+public:
+ FilterClearBorderTest()
+ : GraphicsTest("FilterClearBorderTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+ BitmapPtr pBmp = loadTestBmp("filterwipeborder", I8);
+ BitmapPtr pDestBmp = FilterClearBorder(0).apply(pBmp);
+ testEqual(*pDestBmp, *pBmp, "FilterClearBorderResult0", 0, 0);
+ pDestBmp = FilterClearBorder(1).apply(pBmp);
+ testEqual(*pDestBmp, "FilterClearBorderResult1", I8);
+ pDestBmp = FilterClearBorder(3).apply(pBmp);
+ testEqual(*pDestBmp, "FilterClearBorderResult3", I8);
+ }
+};
+
+class DeDistortTest: public Test
+{
+public:
+ DeDistortTest()
+ : Test("DeDistortTest", 2)
+ {}
+
+ void runTests()
+ {
+ vector<double> params;
+ params.push_back(0);
+ params.push_back(0);
+ DeDistort IdentityDistort = DeDistort(glm::vec2(1,1),
+ params, 0.0, 0.0, glm::dvec2(0,0), glm::dvec2(1,1));
+ TEST(almostEqual(IdentityDistort.transform_point(glm::dvec2(0,0)),
+ glm::dvec2(0,0)));
+ TEST(almostEqual(IdentityDistort.transform_point(glm::dvec2(1,2)),
+ glm::dvec2(1,2)));
+ TEST(almostEqual(IdentityDistort.transformBlobToScreen(glm::dvec2(0,0)),
+ glm::dvec2(0,0)));
+ TEST(almostEqual(IdentityDistort.transformBlobToScreen(glm::dvec2(1,2)),
+ glm::dvec2(1,2)));
+ TEST(almostEqual(IdentityDistort.inverse_transform_point(glm::dvec2(0,0)),
+ glm::dvec2(0,0)));
+ TEST(almostEqual(IdentityDistort.inverse_transform_point(glm::dvec2(1,2)),
+ glm::dvec2(1,2)));
+ TEST(almostEqual(IdentityDistort.transformScreenToBlob(glm::dvec2(0,0)),
+ glm::dvec2(0,0)));
+ TEST(almostEqual(IdentityDistort.transformScreenToBlob(glm::dvec2(1,2)),
+ glm::dvec2(1,2)));
+ TEST(IdentityDistort.getDisplayArea(glm::vec2(1280,720)) == FRect(0,0,1280,720));
+
+ DeDistort scaler = DeDistort(glm::vec2(1,1), params, 0, 0.0, glm::dvec2(0,0),
+ glm::dvec2(2,2));
+ TEST(almostEqual(scaler.transform_point(glm::dvec2(0,0)), glm::dvec2(0,0)));
+ TEST(almostEqual(scaler.transformBlobToScreen(glm::dvec2(1,2)), glm::dvec2(2,4)));
+ TEST(almostEqual(scaler.inverse_transform_point(glm::dvec2(0,0)), glm::dvec2(0,0)));
+ TEST(almostEqual(scaler.transformScreenToBlob(glm::dvec2(1,2)), glm::dvec2(0.5,1)));
+
+ DeDistort shifter = DeDistort(glm::vec2(1,1), params, 0, 0.0, glm::dvec2(1,1),
+ glm::dvec2(1,1));
+ TEST(almostEqual(shifter.transformBlobToScreen(glm::dvec2(0,0)), glm::dvec2(1,1)));
+ TEST(almostEqual(shifter.transformBlobToScreen(glm::dvec2(1,2)), glm::dvec2(2,3)));
+ TEST(almostEqual(shifter.transformScreenToBlob(glm::dvec2(0,0)),
+ glm::dvec2(-1,-1)));
+ TEST(almostEqual(shifter.transformScreenToBlob(glm::dvec2(1,2)), glm::dvec2(0,1)));
+ TEST(shifter.getDisplayArea(glm::vec2(1,1)) == FRect(-1, -1, 0, 0));
+
+ vector<double> cubed;
+ cubed.push_back(0);
+ cubed.push_back(1);
+ DeDistort barreler = DeDistort(glm::vec2(1,1), cubed, 0, 0.0, glm::dvec2(0,0),
+ glm::dvec2(1,1));
+ for (double xp = 0; xp < 10; xp++) {
+ for(double yp = 0; yp < 10; yp++) {
+ QUIET_TEST(almostEqual(barreler.inverse_transform_point(
+ barreler.transform_point(glm::dvec2(xp,yp))), glm::dvec2(xp,yp)));
+ }
+ }
+ TEST(almostEqual(barreler.transform_point(glm::dvec2(1,1)), glm::dvec2(1,1)));
+
+ DeDistort rotator = DeDistort(glm::vec2(1,1), params, 0, M_PI/2, glm::dvec2(0,0),
+ glm::dvec2(1,1));
+ for (double xp = 0; xp < 10; xp++) {
+ for(double yp = 0; yp < 10; yp++) {
+ QUIET_TEST(almostEqual(rotator.inverse_transform_point(
+ rotator.transform_point(glm::dvec2(xp,yp))), glm::dvec2(xp,yp)));
+ }
+ }
+
+ DeDistort shifterScaler = DeDistort(glm::vec2(1,1), params, 0, 0.0,
+ glm::dvec2(1,1), glm::dvec2(2,2));
+ for (double xp = 0; xp < 10; xp++) {
+ for(double yp = 0; yp < 10; yp++) {
+ QUIET_TEST(almostEqual(shifterScaler.inverse_transform_point(
+ shifterScaler.transform_point(glm::dvec2(xp,yp))),
+ glm::dvec2(xp,yp)));
+ }
+ }
+ }
+};
+
+#ifdef _WIN32
+#pragma warning(disable: 4996)
+#endif
+class SerializeTest: public Test
+{
+public:
+ SerializeTest()
+ : Test("SerializeTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+ TrackerConfig Config;
+ copyFile(getSrcDirName()+"avgtrackerrc.minimal", "avgtrackerrc");
+ Config.load();
+
+ Config.setParam("/transform/distortionparams/@p2", "0");
+ Config.setParam("/transform/distortionparams/@p3", "0");
+ Config.setParam("/transform/trapezoid/@value", "0");
+ Config.setParam("/transform/angle/@value", "0");
+ Config.setParam("/transform/displaydisplacement/@x", "0");
+ Config.setParam("/transform/displaydisplacement/@y", "0");
+ Config.setParam("/transform/displayscale/@x", "2");
+ Config.setParam("/transform/displayscale/@y", "2");
+
+ if (getSrcDirName() == "./") {
+ Config.save();
+
+ TrackerConfig loadedConfig;
+ loadedConfig.load();
+ glm::vec2 scale = loadedConfig.getPointParam("/transform/displayscale/");
+ TEST(almostEqual(scale, glm::vec2(2,2)));
+ unlink("avgtrackerrc.bak");
+ }
+ unlink("avgtrackerrc");
+ }
+};
+
+class ImagingTestSuite: public TestSuite
+{
+public:
+ ImagingTestSuite()
+ : TestSuite("ImagingTestSuite")
+ {
+ addTest(TestPtr(new FilterWipeBorderTest));
+ addTest(TestPtr(new FilterClearBorderTest));
+ addTest(TestPtr(new DeDistortTest));
+ addTest(TestPtr(new SerializeTest));
+ }
+};
+
+
+int main(int nargs, char** args)
+{
+ ImagingTestSuite Suite;
+ BitmapLoader::init(true);
+ Suite.runTests();
+ bool bOK = Suite.isOk();
+
+ if (bOK) {
+ return 0;
+ } else {
+ return 1;
+ }
+}
+
diff --git a/src/imaging/trackerconfigdtd.cpp b/src/imaging/trackerconfigdtd.cpp
new file mode 100644
index 0000000..d4185de
--- /dev/null
+++ b/src/imaging/trackerconfigdtd.cpp
@@ -0,0 +1,175 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+const char * g_pTrackerConfigDTD =
+"<!ENTITY % minmaxAttrs\n"
+" \"min CDATA #REQUIRED\n"
+" max CDATA #REQUIRED\" >\n"
+
+"<!ENTITY % posAttrs\n"
+" \"x CDATA #REQUIRED\n"
+" y CDATA #REQUIRED\" >\n"
+
+"<!ELEMENT trackerconfig (camera|tracker|transform)* >\n"
+"<!ELEMENT camera (driver|device|fw800|format|size|framerate|brightness|gamma|exposure|"
+" gain|shutter|strobeduration)* >\n"
+"<!ELEMENT tracker (mask|prescale|historyupdateinterval|brighterregions|"
+" contourprecision|historydelay|touch|track|findfingertips)* >\n"
+"<!ELEMENT touch (threshold|similarity|areabounds|eccentricitybounds|bandpass|"
+" bandpasspostmult)* >\n"
+"<!ELEMENT track (threshold|similarity|areabounds|eccentricitybounds)* >\n"
+"<!ELEMENT transform (cameradisplacement|camerascale|distortionparams|trapezoid|"
+" angle|displaydisplacement|displayscale|activedisplaysize|displayroi)* >\n"
+
+"<!ELEMENT driver EMPTY>\n"
+"<!ATTLIST driver\n"
+" value CDATA #REQUIRED >\n"
+
+"<!ELEMENT device EMPTY>\n"
+"<!ATTLIST device\n"
+" value CDATA #REQUIRED >\n"
+
+"<!ELEMENT fw800 EMPTY>\n"
+"<!ATTLIST fw800\n"
+" value CDATA #REQUIRED >\n"
+
+"<!ELEMENT format EMPTY>\n"
+"<!ATTLIST format\n"
+" value CDATA #REQUIRED >\n"
+
+"<!ELEMENT size EMPTY>\n"
+"<!ATTLIST size\n"
+" %posAttrs; >\n"
+
+"<!ELEMENT framerate EMPTY>\n"
+"<!ATTLIST framerate\n"
+" value CDATA #REQUIRED >\n"
+
+"<!ELEMENT brightness EMPTY>\n"
+"<!ATTLIST brightness\n"
+" value CDATA #REQUIRED >\n"
+
+"<!ELEMENT gamma EMPTY>\n"
+"<!ATTLIST gamma\n"
+" value CDATA #REQUIRED >\n"
+
+"<!ELEMENT exposure EMPTY>\n"
+"<!ATTLIST exposure\n"
+" value CDATA #REQUIRED >\n"
+
+"<!ELEMENT gain EMPTY>\n"
+"<!ATTLIST gain\n"
+" value CDATA #REQUIRED >\n"
+
+"<!ELEMENT shutter EMPTY>\n"
+"<!ATTLIST shutter\n"
+" value CDATA #REQUIRED >\n"
+
+"<!ELEMENT strobeduration EMPTY>\n"
+"<!ATTLIST strobeduration\n"
+" value CDATA #REQUIRED >\n"
+
+"<!ELEMENT brighterregions EMPTY>\n"
+"<!ATTLIST brighterregions\n"
+" value CDATA #REQUIRED >\n"
+
+"<!ELEMENT threshold EMPTY>\n"
+"<!ATTLIST threshold\n"
+" value CDATA #REQUIRED >\n"
+
+"<!ELEMENT mask EMPTY>\n"
+"<!ATTLIST mask\n"
+" value CDATA #REQUIRED >\n"
+
+"<!ELEMENT findfingertips EMPTY>\n"
+"<!ATTLIST findfingertips\n"
+" value CDATA #REQUIRED >\n"
+
+"<!ELEMENT prescale EMPTY>\n"
+"<!ATTLIST prescale\n"
+" value CDATA #REQUIRED >\n"
+
+"<!ELEMENT historyupdateinterval EMPTY>\n"
+"<!ATTLIST historyupdateinterval\n"
+" value CDATA #REQUIRED >\n"
+
+"<!ELEMENT contourprecision EMPTY>\n"
+"<!ATTLIST contourprecision\n"
+" value CDATA #REQUIRED >\n"
+
+"<!ELEMENT historydelay EMPTY>\n"
+"<!ATTLIST historydelay\n"
+" value CDATA #REQUIRED >\n"
+
+"<!ELEMENT similarity EMPTY>\n"
+"<!ATTLIST similarity\n"
+" value CDATA #REQUIRED >\n"
+
+"<!ELEMENT areabounds EMPTY>\n"
+"<!ATTLIST areabounds\n"
+" %minmaxAttrs; >\n"
+
+"<!ELEMENT eccentricitybounds EMPTY>\n"
+"<!ATTLIST eccentricitybounds\n"
+" %minmaxAttrs; >\n"
+
+"<!ELEMENT bandpass EMPTY>\n"
+"<!ATTLIST bandpass\n"
+" %minmaxAttrs; >\n"
+
+"<!ELEMENT bandpasspostmult EMPTY>\n"
+"<!ATTLIST bandpasspostmult\n"
+" value CDATA #REQUIRED >\n"
+
+"<!ELEMENT distortionparams EMPTY>\n"
+"<!ATTLIST distortionparams\n"
+" p2 CDATA #REQUIRED\n"
+" p3 CDATA #REQUIRED >\n"
+
+"<!ELEMENT trapezoid EMPTY>\n"
+"<!ATTLIST trapezoid\n"
+" value CDATA #REQUIRED >\n"
+
+"<!ELEMENT angle EMPTY>\n"
+"<!ATTLIST angle\n"
+" value CDATA #REQUIRED >\n"
+
+"<!ELEMENT displaydisplacement EMPTY>\n"
+"<!ATTLIST displaydisplacement\n"
+" %posAttrs; >\n"
+
+"<!ELEMENT displayscale EMPTY>\n"
+"<!ATTLIST displayscale\n"
+" %posAttrs; >\n"
+
+"<!ELEMENT activedisplaysize EMPTY>\n"
+"<!ATTLIST activedisplaysize\n"
+" %posAttrs; >\n"
+
+"<!ELEMENT displayroi EMPTY>\n"
+"<!ATTLIST displayroi\n"
+" x1 CDATA #REQUIRED\n"
+" y1 CDATA #REQUIRED\n"
+" x2 CDATA #REQUIRED\n"
+" y2 CDATA #REQUIRED >\n"
+
+;
+
diff --git a/src/imaging/trackerconfigdtd.h b/src/imaging/trackerconfigdtd.h
new file mode 100644
index 0000000..366b8d4
--- /dev/null
+++ b/src/imaging/trackerconfigdtd.h
@@ -0,0 +1,27 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _avgdtd_H_
+
+extern const char * g_pTrackerConfigDTD;
+
+#endif
+
diff --git a/src/lmfit/Makefile.am b/src/lmfit/Makefile.am
new file mode 100644
index 0000000..29a7361
--- /dev/null
+++ b/src/lmfit/Makefile.am
@@ -0,0 +1,7 @@
+AM_CPPFLAGS = -I.
+CPPFLAGS = -DBUG
+
+ALL_H = lmmin.h lm_eval.h
+noinst_LTLIBRARIES = liblmfit.la
+liblmfit_la_SOURCES = lmmin.c lm_eval.c $(ALL_H)
+liblmfit_a_CXXFLAGS = -Wno-format-y2k
diff --git a/src/lmfit/lm_eval.c b/src/lmfit/lm_eval.c
new file mode 100644
index 0000000..7a1b971
--- /dev/null
+++ b/src/lmfit/lm_eval.c
@@ -0,0 +1,81 @@
+#include "lmmin.h"
+#include "lm_eval.h"
+#include <stdio.h>
+
+/*
+ * This file contains default implementation of the evaluate and printout
+ * routines. In most cases, customization of lmfit can be done by modifying
+ * these two routines. Either modify them here, or copy and rename them.
+ */
+
+void lm_evaluate_default( double* par, int m_dat, double* fvec,
+ void *data, int *info )
+/*
+ * par is an input array. At the end of the minimization, it contains
+ * the approximate solution vector.
+ *
+ * m_dat is a positive integer input variable set to the number
+ * of functions.
+ *
+ * fvec is an output array of length m_dat which contains the function
+ * values the square sum of which ought to be minimized.
+ *
+ * data is a read-only pointer to lm_data_type, as specified by lmuse.h.
+ *
+ * info is an integer output variable. If set to a negative value, the
+ * minimization procedure will stop.
+ */
+{
+ int i;
+ lm_data_type *mydata;
+ mydata = (lm_data_type*)data;
+
+ for (i=0; i<m_dat; i++)
+ fvec[i] = mydata->user_y[i]
+ - mydata->user_func( mydata->user_t[i], par);
+
+ *info = *info; /* to prevent a 'unused variable' warning */
+ /* if <parameters drifted away> { *info = -1; } */
+}
+
+void lm_print_default( int n_par, double* par, int m_dat, double* fvec,
+ void *data, int iflag, int iter, int nfev )
+/*
+ * data : for soft control of printout behaviour, add control
+ * variables to the data struct
+ * iflag : 0 (init) 1 (outer loop) 2(inner loop) -1(terminated)
+ * iter : outer loop counter
+ * nfev : number of calls to *evaluate
+ */
+{
+ double f, y, t;
+ int i;
+ lm_data_type *mydata;
+ mydata = (lm_data_type*)data;
+
+ if (iflag==2) {
+ printf ("trying step in gradient direction\n");
+ } else if (iflag==1) {
+ printf ("determining gradient (iteration %d)\n", iter);
+ } else if (iflag==0) {
+ printf ("starting minimization\n");
+ } else if (iflag==-1) {
+ printf ("terminated after %d evaluations\n", nfev);
+ }
+
+ printf( " par: " );
+ for( i=0; i<n_par; ++i )
+ printf( " %12g", par[i] );
+ printf ( " => norm: %12g\n", lm_enorm( m_dat, fvec ) );
+
+ if ( iflag == -1 ) {
+ printf( " fitting data as follows:\n" );
+ for( i=0; i<m_dat; ++i ) {
+ t = (mydata->user_t)[i];
+ y = (mydata->user_y)[i];
+ f = mydata->user_func( t, par );
+ printf( " t[%2d]=%12g y=%12g fit=%12g residue=%12g\n",
+ i, t, y, f, y-f );
+ }
+ }
+}
diff --git a/src/lmfit/lm_eval.h b/src/lmfit/lm_eval.h
new file mode 100644
index 0000000..331a8f2
--- /dev/null
+++ b/src/lmfit/lm_eval.h
@@ -0,0 +1,11 @@
+typedef struct {
+ double* user_t;
+ double* user_y;
+ double (*user_func)( double user_t_point, double* par );
+} lm_data_type;
+
+void lm_evaluate_default( double* par, int m_dat, double* fvec,
+ void *data, int *info );
+
+void lm_print_default( int n_par, double* par, int m_dat, double* fvec,
+ void *data, int iflag, int iter, int nfev );
diff --git a/src/lmfit/lmmin.c b/src/lmfit/lmmin.c
new file mode 100644
index 0000000..fdf634e
--- /dev/null
+++ b/src/lmfit/lmmin.c
@@ -0,0 +1,1320 @@
+/*
+ * lmfit
+ *
+ * Solves or minimizes the sum of squares of m nonlinear
+ * functions of n variables.
+ *
+ * From public domain Fortran version
+ * of Argonne National Laboratories MINPACK
+ * argonne national laboratory. minpack project. march 1980.
+ * burton s. garbow, kenneth e. hillstrom, jorge j. more
+ * C translation by Steve Moshier
+ * Joachim Wuttke converted the source into C++ compatible ANSI style
+ * and provided a simplified interface
+ */
+
+
+#include <stdlib.h>
+#include <math.h>
+#include "lmmin.h"
+#define _LMDIF
+
+/* *********************** high-level interface **************************** */
+
+
+void lm_initialize_control( lm_control_type *control )
+{
+ control->maxcall = 100;
+ control->epsilon = 1.e-14;
+ control->stepbound = 100.;
+ control->ftol = 1.e-14;
+ control->xtol = 1.e-14;
+ control->gtol = 1.e-14;
+}
+
+void lm_minimize( int m_dat, int n_par, double* par,
+ lm_evaluate_ftype *evaluate, lm_print_ftype *printout,
+ void *data, lm_control_type *control )
+{
+
+// *** allocate work space.
+
+ double *fvec, *diag, *fjac, *qtf, *wa1, *wa2, *wa3, *wa4;
+ int *ipvt;
+
+ int n = n_par;
+ int m = m_dat;
+
+ if (!(fvec = (double*) malloc( m*sizeof(double))) ||
+ !(diag = (double*) malloc(n* sizeof(double))) ||
+ !(qtf = (double*) malloc(n* sizeof(double))) ||
+ !(fjac = (double*) malloc(n*m*sizeof(double))) ||
+ !(wa1 = (double*) malloc(n* sizeof(double))) ||
+ !(wa2 = (double*) malloc(n* sizeof(double))) ||
+ !(wa3 = (double*) malloc(n* sizeof(double))) ||
+ !(wa4 = (double*) malloc( m*sizeof(double))) ||
+ !(ipvt = (int*) malloc(n* sizeof(int)))) {
+ control->info = 9;
+ return;
+ }
+
+// *** perform fit.
+
+ control->info = 0;
+ control->nfev = 0;
+
+ // this goes through the modified legacy interface:
+ lm_lmdif( m, n, par, fvec, control->ftol, control->xtol, control->gtol,
+ control->maxcall*(n+1), control->epsilon, diag, 1,
+ control->stepbound, &(control->info),
+ &(control->nfev), fjac, ipvt, qtf, wa1, wa2, wa3, wa4,
+ evaluate, printout, data );
+
+ (*printout)( n, par, m, fvec, data, -1, 0, control->nfev );
+ control->fnorm = lm_enorm(m, fvec);
+ if (control->info < 0 ) control->info = 10;
+
+// *** clean up.
+
+ free(fvec);
+ free(diag);
+ free(qtf);
+ free(fjac);
+ free(wa1);
+ free(wa2);
+ free(wa3 );
+ free(wa4);
+ free(ipvt);
+}
+
+
+// ***** the following messages are referenced by the variable info.
+
+char *lm_infmsg[] = {
+ "improper input parameters",
+ "the relative error in the sum of squares is at most tol",
+ "the relative error between x and the solution is at most tol",
+ "both errors are at most tol",
+ "fvec is orthogonal to the columns of the jacobian to machine precision",
+ "number of calls to fcn has reached or exceeded 200*(n+1)",
+ "ftol is too small. no further reduction in the sum of squares is possible",
+ "xtol too small. no further improvement in approximate solution x possible",
+ "gtol too small. no further improvement in approximate solution x possible",
+ "not enough memory",
+ "break requested within function evaluation"
+};
+
+char *lm_shortmsg[] = {
+ "invalid input",
+ "success (f)",
+ "success (p)",
+ "success (f,p)",
+ "degenerate",
+ "call limit",
+ "failed (f)",
+ "failed (p)",
+ "failed (o)",
+ "no memory",
+ "user break"
+};
+
+
+/* ************************** implementation ******************************* */
+
+
+#undef BUG
+#if BUG
+#include <stdio.h>
+#endif
+
+// the following values seem good for an x86:
+#define LM_MACHEP .555e-16 /* resolution of arithmetic */
+#define LM_DWARF 9.9e-324 /* smallest nonzero number */
+// the follwoing values should work on any machine:
+// #define LM_MACHEP 1.2e-16
+// #define LM_DWARF 1.0e-38
+
+// the squares of the following constants shall not under/overflow:
+// these values seem good for an x86:
+#define LM_SQRT_DWARF 1.e-160
+#define LM_SQRT_GIANT 1.e150
+// the following values should work on any machine:
+// #define LM_SQRT_DWARF 3.834e-20
+// #define LM_SQRT_GIANT 1.304e19
+
+
+void lm_qrfac( int m, int n, double* a, int pivot, int* ipvt,
+ double* rdiag, double* acnorm, double* wa);
+void lm_qrsolv(int n, double* r, int ldr, int* ipvt, double* diag,
+ double* qtb, double* x, double* sdiag, double* wa);
+void lm_lmpar( int n, double* r, int ldr, int* ipvt, double* diag, double* qtb,
+ double delta, double* par, double* x, double* sdiag,
+ double* wa1, double* wa2);
+
+#define MIN(a,b) (((a)<=(b)) ? (a) : (b))
+#define MAX(a,b) (((a)>=(b)) ? (a) : (b))
+#define SQR(x) (x)*(x)
+
+
+// ***** the low-level legacy interface for full control.
+
+void lm_lmdif( int m, int n, double* x, double* fvec, double ftol, double xtol,
+ double gtol, int maxfev, double epsfcn, double* diag, int mode,
+ double factor, int *info, int *nfev,
+ double* fjac, int* ipvt, double* qtf,
+ double* wa1, double* wa2, double* wa3, double* wa4,
+ lm_evaluate_ftype *evaluate, lm_print_ftype *printout,
+ void *data )
+{
+/*
+ * the purpose of lmdif is to minimize the sum of the squares of
+ * m nonlinear functions in n variables by a modification of
+ * the levenberg-marquardt algorithm. the user must provide a
+ * subroutine evaluate which calculates the functions. the jacobian
+ * is then calculated by a forward-difference approximation.
+ *
+ * the multi-parameter interface lm_lmdif is for users who want
+ * full control and flexibility. most users will be better off using
+ * the simpler interface lmfit provided above.
+ *
+ * the parameters are the same as in the legacy FORTRAN implementation,
+ * with the following exceptions:
+ * the old parameter ldfjac which gave leading dimension of fjac has
+ * been deleted because this C translation makes no use of two-
+ * dimensional arrays;
+ * the old parameter nprint has been deleted; printout is now controlled
+ * by the user-supplied routine *printout;
+ * the parameter field *data and the function parameters *evaluate and
+ * *printout have been added; they help avoiding global variables.
+ *
+ * parameters:
+ *
+ * m is a positive integer input variable set to the number
+ * of functions.
+ *
+ * n is a positive integer input variable set to the number
+ * of variables. n must not exceed m.
+ *
+ * x is an array of length n. on input x must contain
+ * an initial estimate of the solution vector. on output x
+ * contains the final estimate of the solution vector.
+ *
+ * fvec is an output array of length m which contains
+ * the functions evaluated at the output x.
+ *
+ * ftol is a nonnegative input variable. termination
+ * occurs when both the actual and predicted relative
+ * reductions in the sum of squares are at most ftol.
+ * therefore, ftol measures the relative error desired
+ * in the sum of squares.
+ *
+ * xtol is a nonnegative input variable. termination
+ * occurs when the relative error between two consecutive
+ * iterates is at most xtol. therefore, xtol measures the
+ * relative error desired in the approximate solution.
+ *
+ * gtol is a nonnegative input variable. termination
+ * occurs when the cosine of the angle between fvec and
+ * any column of the jacobian is at most gtol in absolute
+ * value. therefore, gtol measures the orthogonality
+ * desired between the function vector and the columns
+ * of the jacobian.
+ *
+ * maxfev is a positive integer input variable. termination
+ * occurs when the number of calls to lm_fcn is at least
+ * maxfev by the end of an iteration.
+ *
+ * epsfcn is an input variable used in determining a suitable
+ * step length for the forward-difference approximation. this
+ * approximation assumes that the relative errors in the
+ * functions are of the order of epsfcn. if epsfcn is less
+ * than the machine precision, it is assumed that the relative
+ * errors in the functions are of the order of the machine
+ * precision.
+ *
+ * diag is an array of length n. if mode = 1 (see below), diag is
+ * internally set. if mode = 2, diag must contain positive entries
+ * that serve as multiplicative scale factors for the variables.
+ *
+ * mode is an integer input variable. if mode = 1, the
+ * variables will be scaled internally. if mode = 2,
+ * the scaling is specified by the input diag. other
+ * values of mode are equivalent to mode = 1.
+ *
+ * factor is a positive input variable used in determining the
+ * initial step bound. this bound is set to the product of
+ * factor and the euclidean norm of diag*x if nonzero, or else
+ * to factor itself. in most cases factor should lie in the
+ * interval (.1,100.). 100. is a generally recommended value.
+ *
+ * info is an integer output variable that indicates the termination
+ * status of lm_lmdif as follows:
+ *
+ * info < 0 termination requested by user-supplied routine *evaluate;
+ *
+ * info = 0 improper input parameters;
+ *
+ * info = 1 both actual and predicted relative reductions
+ * in the sum of squares are at most ftol;
+ *
+ * info = 2 relative error between two consecutive iterates
+ * is at most xtol;
+ *
+ * info = 3 conditions for info = 1 and info = 2 both hold;
+ *
+ * info = 4 the cosine of the angle between fvec and any
+ * column of the jacobian is at most gtol in
+ * absolute value;
+ *
+ * info = 5 number of calls to lm_fcn has reached or
+ * exceeded maxfev;
+ *
+ * info = 6 ftol is too small. no further reduction in
+ * the sum of squares is possible;
+ *
+ * info = 7 xtol is too small. no further improvement in
+ * the approximate solution x is possible;
+ *
+ * info = 8 gtol is too small. fvec is orthogonal to the
+ * columns of the jacobian to machine precision;
+ *
+ * nfev is an output variable set to the number of calls to the
+ * user-supplied routine *evaluate.
+ *
+ * fjac is an output m by n array. the upper n by n submatrix
+ * of fjac contains an upper triangular matrix r with
+ * diagonal elements of nonincreasing magnitude such that
+ *
+ * t t t
+ * p *(jac *jac)*p = r *r,
+ *
+ * where p is a permutation matrix and jac is the final
+ * calculated jacobian. column j of p is column ipvt(j)
+ * (see below) of the identity matrix. the lower trapezoidal
+ * part of fjac contains information generated during
+ * the computation of r.
+ *
+ * ipvt is an integer output array of length n. ipvt
+ * defines a permutation matrix p such that jac*p = q*r,
+ * where jac is the final calculated jacobian, q is
+ * orthogonal (not stored), and r is upper triangular
+ * with diagonal elements of nonincreasing magnitude.
+ * column j of p is column ipvt(j) of the identity matrix.
+ *
+ * qtf is an output array of length n which contains
+ * the first n elements of the vector (q transpose)*fvec.
+ *
+ * wa1, wa2, and wa3 are work arrays of length n.
+ *
+ * wa4 is a work array of length m.
+ *
+ * the following parameters are newly introduced in this C translation:
+ *
+ * evaluate is the name of the subroutine which calculates the functions.
+ * a default implementation lm_evaluate_default is provided in lm_eval.c;
+ * alternatively, evaluate can be provided by a user calling program.
+ * it should be written as follows:
+ *
+ * void evaluate ( double* par, int m_dat, double* fvec,
+ * void *data, int *info )
+ * {
+ * // for ( i=0; i<m_dat; ++i )
+ * // calculate fvec[i] for given parameters par;
+ * // to stop the minimization,
+ * // set *info to a negative integer.
+ * }
+ *
+ * printout is the name of the subroutine which nforms about fit progress.
+ * a default implementation lm_print_default is provided in lm_eval.c;
+ * alternatively, printout can be provided by a user calling program.
+ * it should be written as follows:
+ *
+ * void printout ( int n_par, double* par, int m_dat, double* fvec,
+ * void *data, int iflag, int iter, int nfev )
+ * {
+ * // iflag : 0 (init) 1 (outer loop) 2(inner loop) -1(terminated)
+ * // iter : outer loop counter
+ * // nfev : number of calls to *evaluate
+ * }
+ *
+ * data is an input pointer to an arbitrary structure that is passed to
+ * evaluate. typically, it contains experimental data to be fitted.
+ *
+ */
+ int i, iter, j;
+ double actred, delta, dirder, eps, fnorm, fnorm1, gnorm, par, pnorm,
+ prered, ratio, step, sum, temp, temp1, temp2, temp3, xnorm;
+ static double p1 = 0.1;
+ static double p5 = 0.5;
+ static double p25 = 0.25;
+ static double p75 = 0.75;
+ static double p0001 = 1.0e-4;
+
+ *nfev = 0; // function evaluation counter
+ iter = 1; // outer loop counter
+ par = 0; // levenberg-marquardt parameter
+ delta = 0; // just to prevent a warning (initialization within if-clause)
+ xnorm = 0; // dito
+
+ temp = MAX(epsfcn,LM_MACHEP);
+ eps = sqrt(temp); // used in calculating the Jacobian by forward differences
+
+// *** check the input parameters for errors.
+
+ if ( (n <= 0) || (m < n) || (ftol < 0.)
+ || (xtol < 0.) || (gtol < 0.) || (maxfev <= 0) || (factor <= 0.) )
+ {
+ *info = 0; // invalid parameter
+ return;
+ }
+ if ( mode == 2 ) /* scaling by diag[] */
+ {
+ for ( j=0; j<n; j++ ) /* check for nonpositive elements */
+ {
+ if ( diag[j] <= 0.0 )
+ {
+ *info = 0; // invalid parameter
+ return;
+ }
+ }
+ }
+#if BUG
+ printf( "lmdif\n" );
+#endif
+
+// *** evaluate the function at the starting point and calculate its norm.
+
+ *info = 0;
+ (*evaluate)( x, m, fvec, data, info );
+ (*printout)( n, x, m, fvec, data, 0, 0, ++(*nfev) );
+ if ( *info < 0 ) return;
+ fnorm = lm_enorm(m,fvec);
+
+// *** the outer loop.
+
+ do {
+#if BUG
+ printf( "lmdif/ outer loop iter=%d nfev=%d fnorm=%.10e\n",
+ iter, *nfev, fnorm );
+#endif
+
+// O** calculate the jacobian matrix.
+
+ for ( j=0; j<n; j++ )
+ {
+ temp = x[j];
+ step = eps * fabs(temp);
+ if (step == 0.) step = eps;
+ x[j] = temp + step;
+ *info = 0;
+ (*evaluate)( x, m, wa4, data, info );
+ (*printout)( n, x, m, wa4, data, 1, iter, ++(*nfev) );
+ if ( *info < 0 ) return; // user requested break
+ x[j] = temp;
+ for ( i=0; i<m; i++ )
+ fjac[j*m+i] = (wa4[i] - fvec[i]) / step;
+ }
+#if BUG>1
+ // DEBUG: print the entire matrix
+ for ( i=0; i<m; i++ )
+ {
+ for ( j=0; j<n; j++ )
+ printf( "%.5e ", y[j*m+i] );
+ printf( "\n" );
+ }
+#endif
+
+// O** compute the qr factorization of the jacobian.
+
+ lm_qrfac( m, n, fjac, 1, ipvt, wa1, wa2, wa3);
+
+// O** on the first iteration ...
+
+ if (iter == 1)
+ {
+ if (mode != 2)
+// ... scale according to the norms of the columns of the initial jacobian.
+ {
+ for ( j=0; j<n; j++ )
+ {
+ diag[j] = wa2[j];
+ if ( wa2[j] == 0. )
+ diag[j] = 1.;
+ }
+ }
+
+// ... calculate the norm of the scaled x and
+// initialize the step bound delta.
+
+ for ( j=0; j<n; j++ )
+ wa3[j] = diag[j] * x[j];
+
+ xnorm = lm_enorm( n, wa3 );
+ delta = factor*xnorm;
+ if (delta == 0.)
+ delta = factor;
+ }
+
+// O** form (q transpose)*fvec and store the first n components in qtf.
+
+ for ( i=0; i<m; i++ )
+ wa4[i] = fvec[i];
+
+ for ( j=0; j<n; j++ )
+ {
+ temp3 = fjac[j*m+j];
+ if (temp3 != 0.)
+ {
+ sum = 0;
+ for ( i=j; i<m; i++ )
+ sum += fjac[j*m+i] * wa4[i];
+ temp = -sum / temp3;
+ for ( i=j; i<m; i++ )
+ wa4[i] += fjac[j*m+i] * temp;
+ }
+ fjac[j*m+j] = wa1[j];
+ qtf[j] = wa4[j];
+ }
+
+// O** compute the norm of the scaled gradient and test for convergence.
+
+ gnorm = 0;
+ if ( fnorm != 0 )
+ {
+ for ( j=0; j<n; j++ )
+ {
+ if ( wa2[ ipvt[j] ] == 0 ) continue;
+
+ sum = 0.;
+ for ( i=0; i<=j; i++ )
+ sum += fjac[j*m+i] * qtf[i] / fnorm;
+ gnorm = MAX( gnorm, fabs(sum/wa2[ ipvt[j] ]) );
+ }
+ }
+
+ if ( gnorm <= gtol )
+ {
+ *info = 4;
+ return;
+ }
+
+// O** rescale if necessary.
+
+ if ( mode != 2 )
+ {
+ for ( j=0; j<n; j++ )
+ diag[j] = MAX(diag[j],wa2[j]);
+ }
+
+// O** the inner loop.
+
+ do {
+#if BUG
+ printf( "lmdif/ inner loop iter=%d nfev=%d\n", iter, *nfev );
+#endif
+
+// OI* determine the levenberg-marquardt parameter.
+
+ lm_lmpar( n,fjac,m,ipvt,diag,qtf,delta,&par,wa1,wa2,wa3,wa4 );
+
+// OI* store the direction p and x + p. calculate the norm of p.
+
+ for ( j=0; j<n; j++ )
+ {
+ wa1[j] = -wa1[j];
+ wa2[j] = x[j] + wa1[j];
+ wa3[j] = diag[j]*wa1[j];
+ }
+ pnorm = lm_enorm(n,wa3);
+
+// OI* on the first iteration, adjust the initial step bound.
+
+ if ( *nfev<= 1+n ) // bug corrected by J. Wuttke in 2004
+ delta = MIN(delta,pnorm);
+
+// OI* evaluate the function at x + p and calculate its norm.
+
+ *info = 0;
+ (*evaluate)( wa2, m, wa4, data, info );
+ (*printout)( n, x, m, wa4, data, 2, iter, ++(*nfev) );
+ if ( *info < 0 ) return; // user requested break
+
+ fnorm1 = lm_enorm(m,wa4);
+#if BUG
+ printf( "lmdif/ pnorm %.10e fnorm1 %.10e fnorm %.10e"
+ " delta=%.10e par=%.10e\n",
+ pnorm, fnorm1, fnorm, delta, par );
+#endif
+
+// OI* compute the scaled actual reduction.
+
+ if ( p1*fnorm1 < fnorm )
+ actred = 1 - SQR( fnorm1/fnorm );
+ else
+ actred = -1;
+
+// OI* compute the scaled predicted reduction and
+// the scaled directional derivative.
+
+ for ( j=0; j<n; j++ )
+ {
+ wa3[j] = 0;
+ for ( i=0; i<=j; i++ )
+ wa3[i] += fjac[j*m+i]*wa1[ ipvt[j] ];
+ }
+ temp1 = lm_enorm(n,wa3) / fnorm;
+ temp2 = sqrt(par) * pnorm / fnorm;
+ prered = SQR(temp1) + 2 * SQR(temp2);
+ dirder = - ( SQR(temp1) + SQR(temp2) );
+
+// OI* compute the ratio of the actual to the predicted reduction.
+
+ ratio = prered!=0 ? actred/prered : 0;
+#if BUG
+ printf( "lmdif/ actred=%.10e prered=%.10e ratio=%.10e"
+ " sq(1)=%.10e sq(2)=%.10e dd=%.10e\n",
+ actred, prered, prered!=0 ? ratio : 0.,
+ SQR(temp1), SQR(temp2), dirder );
+#endif
+
+// OI* update the step bound.
+
+ if (ratio <= p25)
+ {
+ if (actred >= 0.)
+ temp = p5;
+ else
+ temp = p5*dirder/(dirder + p5*actred);
+ if ( p1*fnorm1 >= fnorm || temp < p1 )
+ temp = p1;
+ delta = temp * MIN(delta,pnorm/p1);
+ par /= temp;
+ }
+ else if ( par == 0. || ratio >= p75 )
+ {
+ delta = pnorm/p5;
+ par *= p5;
+ }
+
+// OI* test for successful iteration...
+
+ if (ratio >= p0001)
+ {
+
+// ... successful iteration. update x, fvec, and their norms.
+
+ for ( j=0; j<n; j++ )
+ {
+ x[j] = wa2[j];
+ wa2[j] = diag[j]*x[j];
+ }
+ for ( i=0; i<m; i++ )
+ fvec[i] = wa4[i];
+ xnorm = lm_enorm(n,wa2);
+ fnorm = fnorm1;
+ iter++;
+ }
+#if BUG
+ else {
+ printf( "ATTN: iteration considered unsuccessful\n" );
+ }
+#endif
+
+// OI* tests for convergence ( otherwise *info = 1, 2, or 3 )
+
+ *info = 0; // do not terminate (unless overwritten by nonzero value)
+ if ( fabs(actred) <= ftol && prered <= ftol && p5*ratio <= 1 )
+ *info = 1;
+ if (delta <= xtol*xnorm)
+ *info += 2;
+ if ( *info != 0)
+ return;
+
+// OI* tests for termination and stringent tolerances.
+
+ if ( *nfev >= maxfev)
+ *info = 5;
+ if ( fabs(actred) <= LM_MACHEP &&
+ prered <= LM_MACHEP && p5*ratio <= 1 )
+ *info = 6;
+ if (delta <= LM_MACHEP*xnorm)
+ *info = 7;
+ if (gnorm <= LM_MACHEP)
+ *info = 8;
+ if ( *info != 0)
+ return;
+
+// OI* end of the inner loop. repeat if iteration unsuccessful.
+
+ } while (ratio < p0001);
+
+// O** end of the outer loop.
+
+ } while (1);
+
+}
+
+
+
+void lm_lmpar(int n, double* r, int ldr, int* ipvt, double* diag, double* qtb,
+ double delta, double* par, double* x, double* sdiag,
+ double* wa1, double* wa2)
+{
+/* given an m by n matrix a, an n by n nonsingular diagonal
+ * matrix d, an m-vector b, and a positive number delta,
+ * the problem is to determine a value for the parameter
+ * par such that if x solves the system
+ *
+ * a*x = b , sqrt(par)*d*x = 0 ,
+ *
+ * in the least squares sense, and dxnorm is the euclidean
+ * norm of d*x, then either par is 0. and
+ *
+ * (dxnorm-delta) .le. 0.1*delta ,
+ *
+ * or par is positive and
+ *
+ * abs(dxnorm-delta) .le. 0.1*delta .
+ *
+ * this subroutine completes the solution of the problem
+ * if it is provided with the necessary information from the
+ * qr factorization, with column pivoting, of a. that is, if
+ * a*p = q*r, where p is a permutation matrix, q has orthogonal
+ * columns, and r is an upper triangular matrix with diagonal
+ * elements of nonincreasing magnitude, then lmpar expects
+ * the full upper triangle of r, the permutation matrix p,
+ * and the first n components of (q transpose)*b. on output
+ * lmpar also provides an upper triangular matrix s such that
+ *
+ * t t t
+ * p *(a *a + par*d*d)*p = s *s .
+ *
+ * s is employed within lmpar and may be of separate interest.
+ *
+ * only a few iterations are generally needed for convergence
+ * of the algorithm. if, however, the limit of 10 iterations
+ * is reached, then the output par will contain the best
+ * value obtained so far.
+ *
+ * parameters:
+ *
+ * n is a positive integer input variable set to the order of r.
+ *
+ * r is an n by n array. on input the full upper triangle
+ * must contain the full upper triangle of the matrix r.
+ * on output the full upper triangle is unaltered, and the
+ * strict lower triangle contains the strict upper triangle
+ * (transposed) of the upper triangular matrix s.
+ *
+ * ldr is a positive integer input variable not less than n
+ * which specifies the leading dimension of the array r.
+ *
+ * ipvt is an integer input array of length n which defines the
+ * permutation matrix p such that a*p = q*r. column j of p
+ * is column ipvt(j) of the identity matrix.
+ *
+ * diag is an input array of length n which must contain the
+ * diagonal elements of the matrix d.
+ *
+ * qtb is an input array of length n which must contain the first
+ * n elements of the vector (q transpose)*b.
+ *
+ * delta is a positive input variable which specifies an upper
+ * bound on the euclidean norm of d*x.
+ *
+ * par is a nonnegative variable. on input par contains an
+ * initial estimate of the levenberg-marquardt parameter.
+ * on output par contains the final estimate.
+ *
+ * x is an output array of length n which contains the least
+ * squares solution of the system a*x = b, sqrt(par)*d*x = 0,
+ * for the output par.
+ *
+ * sdiag is an output array of length n which contains the
+ * diagonal elements of the upper triangular matrix s.
+ *
+ * wa1 and wa2 are work arrays of length n.
+ *
+ */
+ int i, iter, j, nsing;
+ double dxnorm, fp, fp_old, gnorm, parc, parl, paru;
+ double sum, temp;
+ static double p1 = 0.1;
+ static double p001 = 0.001;
+
+#if BUG
+ printf( "lmpar\n" );
+#endif
+
+// *** compute and store in x the gauss-newton direction. if the
+// jacobian is rank-deficient, obtain a least squares solution.
+
+ nsing = n;
+ for ( j=0; j<n; j++ )
+ {
+ wa1[j] = qtb[j];
+ if ( r[j*ldr+j] == 0 && nsing == n )
+ nsing = j;
+ if (nsing < n)
+ wa1[j] = 0;
+ }
+#if BUG
+ printf( "nsing %d ", nsing );
+#endif
+ for ( j=nsing-1; j>=0; j-- )
+ {
+ wa1[j] = wa1[j]/r[j+ldr*j];
+ temp = wa1[j];
+ for ( i=0; i<j; i++ )
+ wa1[i] -= r[j*ldr+i]*temp;
+ }
+
+ for ( j=0; j<n; j++ )
+ x[ ipvt[j] ] = wa1[j];
+
+// *** initialize the iteration counter.
+// evaluate the function at the origin, and test
+// for acceptance of the gauss-newton direction.
+
+ iter = 0;
+ for ( j=0; j<n; j++ )
+ wa2[j] = diag[j]*x[j];
+ dxnorm = lm_enorm(n,wa2);
+ fp = dxnorm - delta;
+ if (fp <= p1*delta)
+ {
+#if BUG
+ printf( "lmpar/ terminate (fp<delta/10\n" );
+#endif
+ *par = 0;
+ return;
+ }
+
+// *** if the jacobian is not rank deficient, the newton
+// step provides a lower bound, parl, for the 0. of
+// the function. otherwise set this bound to 0..
+
+ parl = 0;
+ if (nsing >= n)
+ {
+ for ( j=0; j<n; j++ )
+ wa1[j] = diag[ ipvt[j] ] * wa2[ ipvt[j] ] / dxnorm;
+
+ for ( j=0; j<n; j++ )
+ {
+ sum = 0.;
+ for ( i=0; i<j; i++ )
+ sum += r[j*ldr+i]*wa1[i];
+ wa1[j] = (wa1[j] - sum)/r[j+ldr*j];
+ }
+ temp = lm_enorm(n,wa1);
+ parl = fp/delta/temp/temp;
+ }
+
+// *** calculate an upper bound, paru, for the 0. of the function.
+
+ for ( j=0; j<n; j++ )
+ {
+ sum = 0;
+ for ( i=0; i<=j; i++ )
+ sum += r[j*ldr+i]*qtb[i];
+ wa1[j] = sum/diag[ ipvt[j] ];
+ }
+ gnorm = lm_enorm(n,wa1);
+ paru = gnorm/delta;
+ if (paru == 0.)
+ paru = LM_DWARF/MIN(delta,p1);
+
+// *** if the input par lies outside of the interval (parl,paru),
+// set par to the closer endpoint.
+
+ *par = MAX( *par,parl);
+ *par = MIN( *par,paru);
+ if ( *par == 0.)
+ *par = gnorm/dxnorm;
+#if BUG
+ printf( "lmpar/ parl %.4e par %.4e paru %.4e\n", parl, *par, paru );
+#endif
+
+// *** iterate.
+
+ for ( ; ; iter++ ) {
+
+// *** evaluate the function at the current value of par.
+
+ if ( *par == 0.)
+ *par = MAX(LM_DWARF,p001*paru);
+ temp = sqrt( *par );
+ for ( j=0; j<n; j++ )
+ wa1[j] = temp*diag[j];
+ lm_qrsolv( n, r, ldr, ipvt, wa1, qtb, x, sdiag, wa2);
+ for ( j=0; j<n; j++ )
+ wa2[j] = diag[j]*x[j];
+ dxnorm = lm_enorm(n,wa2);
+ fp_old = fp;
+ fp = dxnorm - delta;
+
+// *** if the function is small enough, accept the current value
+// of par. also test for the exceptional cases where parl
+// is 0. or the number of iterations has reached 10.
+
+ if ( fabs(fp) <= p1*delta
+ || (parl == 0. && fp <= fp_old && fp_old < 0.)
+ || iter == 10 )
+ break; // the only exit from this loop
+
+// *** compute the Newton correction.
+
+ for ( j=0; j<n; j++ )
+ wa1[j] = diag[ ipvt[j] ] * wa2[ ipvt[j] ] / dxnorm;
+
+ for ( j=0; j<n; j++ )
+ {
+ wa1[j] = wa1[j]/sdiag[j];
+ for ( i=j+1; i<n; i++ )
+ wa1[i] -= r[j*ldr+i]*wa1[j];
+ }
+ temp = lm_enorm( n, wa1);
+ parc = fp/delta/temp/temp;
+
+// *** depending on the sign of the function, update parl or paru.
+
+ if (fp > 0)
+ parl = MAX(parl, *par);
+ else if (fp < 0)
+ paru = MIN(paru, *par);
+ // the case fp==0 is precluded by the break condition
+
+// *** compute an improved estimate for par.
+
+ *par = MAX(parl, *par + parc);
+
+ }
+
+}
+
+
+
+void lm_qrfac(int m, int n, double* a, int pivot, int* ipvt,
+ double* rdiag, double* acnorm, double* wa)
+{
+/*
+ * this subroutine uses householder transformations with column
+ * pivoting (optional) to compute a qr factorization of the
+ * m by n matrix a. that is, qrfac determines an orthogonal
+ * matrix q, a permutation matrix p, and an upper trapezoidal
+ * matrix r with diagonal elements of nonincreasing magnitude,
+ * such that a*p = q*r. the householder transformation for
+ * column k, k = 1,2,...,min(m,n), is of the form
+ *
+ * t
+ * i - (1/u(k))*u*u
+ *
+ * where u has 0.s in the first k-1 positions. the form of
+ * this transformation and the method of pivoting first
+ * appeared in the corresponding linpack subroutine.
+ *
+ * parameters:
+ *
+ * m is a positive integer input variable set to the number
+ * of rows of a.
+ *
+ * n is a positive integer input variable set to the number
+ * of columns of a.
+ *
+ * a is an m by n array. on input a contains the matrix for
+ * which the qr factorization is to be computed. on output
+ * the strict upper trapezoidal part of a contains the strict
+ * upper trapezoidal part of r, and the lower trapezoidal
+ * part of a contains a factored form of q (the non-trivial
+ * elements of the u vectors described above).
+ *
+ * pivot is a logical input variable. if pivot is set true,
+ * then column pivoting is enforced. if pivot is set false,
+ * then no column pivoting is done.
+ *
+ * ipvt is an integer output array of length lipvt. ipvt
+ * defines the permutation matrix p such that a*p = q*r.
+ * column j of p is column ipvt(j) of the identity matrix.
+ * if pivot is false, ipvt is not referenced.
+ *
+ * rdiag is an output array of length n which contains the
+ * diagonal elements of r.
+ *
+ * acnorm is an output array of length n which contains the
+ * norms of the corresponding columns of the input matrix a.
+ * if this information is not needed, then acnorm can coincide
+ * with rdiag.
+ *
+ * wa is a work array of length n. if pivot is false, then wa
+ * can coincide with rdiag.
+ *
+ */
+ int i, j, k, kmax, minmn;
+ double ajnorm, sum, temp;
+ static double p05 = 0.05;
+
+// *** compute the initial column norms and initialize several arrays.
+
+ for ( j=0; j<n; j++ )
+ {
+ acnorm[j] = lm_enorm(m, &a[j*m]);
+ rdiag[j] = acnorm[j];
+ wa[j] = rdiag[j];
+ if ( pivot )
+ ipvt[j] = j;
+ }
+#if BUG
+ printf( "qrfac\n" );
+#endif
+
+// *** reduce a to r with householder transformations.
+
+ minmn = MIN(m,n);
+ for ( j=0; j<minmn; j++ )
+ {
+ if ( !pivot ) goto pivot_ok;
+
+// *** bring the column of largest norm into the pivot position.
+
+ kmax = j;
+ for ( k=j+1; k<n; k++ )
+ if (rdiag[k] > rdiag[kmax])
+ kmax = k;
+ if (kmax == j) goto pivot_ok; // bug fixed in rel 2.1
+
+ for ( i=0; i<m; i++ )
+ {
+ temp = a[j*m+i];
+ a[j*m+i] = a[kmax*m+i];
+ a[kmax*m+i] = temp;
+ }
+ rdiag[kmax] = rdiag[j];
+ wa[kmax] = wa[j];
+ k = ipvt[j];
+ ipvt[j] = ipvt[kmax];
+ ipvt[kmax] = k;
+
+ pivot_ok:
+
+// *** compute the Householder transformation to reduce the
+// j-th column of a to a multiple of the j-th unit vector.
+
+ ajnorm = lm_enorm( m-j, &a[j*m+j] );
+ if (ajnorm == 0.)
+ {
+ rdiag[j] = 0;
+ continue;
+ }
+
+ if (a[j*m+j] < 0.)
+ ajnorm = -ajnorm;
+ for ( i=j; i<m; i++ )
+ a[j*m+i] /= ajnorm;
+ a[j*m+j] += 1;
+
+// *** apply the transformation to the remaining columns
+// and update the norms.
+
+ for ( k=j+1; k<n; k++ )
+ {
+ sum = 0;
+
+ for ( i=j; i<m; i++ )
+ sum += a[j*m+i]*a[k*m+i];
+
+ temp = sum/a[j+m*j];
+
+ for ( i=j; i<m; i++ )
+ a[k*m+i] -= temp * a[j*m+i];
+
+ if ( pivot && rdiag[k] != 0. )
+ {
+ temp = a[m*k+j]/rdiag[k];
+ temp = MAX( 0., 1-temp*temp );
+ rdiag[k] *= sqrt(temp);
+ temp = rdiag[k]/wa[k];
+ if ( p05*SQR(temp) <= LM_MACHEP )
+ {
+ rdiag[k] = lm_enorm( m-j-1, &a[m*k+j+1]);
+ wa[k] = rdiag[k];
+ }
+ }
+ }
+
+ rdiag[j] = -ajnorm;
+ }
+}
+
+
+
+void lm_qrsolv(int n, double* r, int ldr, int* ipvt, double* diag,
+ double* qtb, double* x, double* sdiag, double* wa)
+{
+/*
+ * given an m by n matrix a, an n by n diagonal matrix d,
+ * and an m-vector b, the problem is to determine an x which
+ * solves the system
+ *
+ * a*x = b , d*x = 0 ,
+ *
+ * in the least squares sense.
+ *
+ * this subroutine completes the solution of the problem
+ * if it is provided with the necessary information from the
+ * qr factorization, with column pivoting, of a. that is, if
+ * a*p = q*r, where p is a permutation matrix, q has orthogonal
+ * columns, and r is an upper triangular matrix with diagonal
+ * elements of nonincreasing magnitude, then qrsolv expects
+ * the full upper triangle of r, the permutation matrix p,
+ * and the first n components of (q transpose)*b. the system
+ * a*x = b, d*x = 0, is then equivalent to
+ *
+ * t t
+ * r*z = q *b , p *d*p*z = 0 ,
+ *
+ * where x = p*z. if this system does not have full rank,
+ * then a least squares solution is obtained. on output qrsolv
+ * also provides an upper triangular matrix s such that
+ *
+ * t t t
+ * p *(a *a + d*d)*p = s *s .
+ *
+ * s is computed within qrsolv and may be of separate interest.
+ *
+ * parameters
+ *
+ * n is a positive integer input variable set to the order of r.
+ *
+ * r is an n by n array. on input the full upper triangle
+ * must contain the full upper triangle of the matrix r.
+ * on output the full upper triangle is unaltered, and the
+ * strict lower triangle contains the strict upper triangle
+ * (transposed) of the upper triangular matrix s.
+ *
+ * ldr is a positive integer input variable not less than n
+ * which specifies the leading dimension of the array r.
+ *
+ * ipvt is an integer input array of length n which defines the
+ * permutation matrix p such that a*p = q*r. column j of p
+ * is column ipvt(j) of the identity matrix.
+ *
+ * diag is an input array of length n which must contain the
+ * diagonal elements of the matrix d.
+ *
+ * qtb is an input array of length n which must contain the first
+ * n elements of the vector (q transpose)*b.
+ *
+ * x is an output array of length n which contains the least
+ * squares solution of the system a*x = b, d*x = 0.
+ *
+ * sdiag is an output array of length n which contains the
+ * diagonal elements of the upper triangular matrix s.
+ *
+ * wa is a work array of length n.
+ *
+ */
+ int i, kk, j, k, nsing;
+ double qtbpj, sum, temp;
+ double sin, cos, tan, cotan; // these are local variables, not functions
+ static double p25 = 0.25;
+ static double p5 = 0.5;
+
+// *** copy r and (q transpose)*b to preserve input and initialize s.
+// in particular, save the diagonal elements of r in x.
+
+ for ( j=0; j<n; j++ )
+ {
+ for ( i=j; i<n; i++ )
+ r[j*ldr+i] = r[i*ldr+j];
+ x[j] = r[j*ldr+j];
+ wa[j] = qtb[j];
+ }
+#if BUG
+ printf( "qrsolv\n" );
+#endif
+
+// *** eliminate the diagonal matrix d using a givens rotation.
+
+ for ( j=0; j<n; j++ )
+ {
+
+// *** prepare the row of d to be eliminated, locating the
+// diagonal element using p from the qr factorization.
+
+ if (diag[ ipvt[j] ] == 0.)
+ goto L90;
+ for ( k=j; k<n; k++ )
+ sdiag[k] = 0.;
+ sdiag[j] = diag[ ipvt[j] ];
+
+// *** the transformations to eliminate the row of d
+// modify only a single element of (q transpose)*b
+// beyond the first n, which is initially 0..
+
+ qtbpj = 0.;
+ for ( k=j; k<n; k++ )
+ {
+
+// determine a givens rotation which eliminates the
+// appropriate element in the current row of d.
+
+ if (sdiag[k] == 0.)
+ continue;
+ kk = k + ldr * k; // <! keep this shorthand !>
+ if ( fabs(r[kk]) < fabs(sdiag[k]) )
+ {
+ cotan = r[kk]/sdiag[k];
+ sin = p5/sqrt(p25+p25*SQR(cotan));
+ cos = sin*cotan;
+ }
+ else
+ {
+ tan = sdiag[k]/r[kk];
+ cos = p5/sqrt(p25+p25*SQR(tan));
+ sin = cos*tan;
+ }
+
+// *** compute the modified diagonal element of r and
+// the modified element of ((q transpose)*b,0).
+
+ r[kk] = cos*r[kk] + sin*sdiag[k];
+ temp = cos*wa[k] + sin*qtbpj;
+ qtbpj = -sin*wa[k] + cos*qtbpj;
+ wa[k] = temp;
+
+// *** accumulate the tranformation in the row of s.
+
+ for ( i=k+1; i<n; i++ )
+ {
+ temp = cos*r[k*ldr+i] + sin*sdiag[i];
+ sdiag[i] = -sin*r[k*ldr+i] + cos*sdiag[i];
+ r[k*ldr+i] = temp;
+ }
+ }
+ L90:
+
+// *** store the diagonal element of s and restore
+// the corresponding diagonal element of r.
+
+ sdiag[j] = r[j*ldr+j];
+ r[j*ldr+j] = x[j];
+ }
+
+// *** solve the triangular system for z. if the system is
+// singular, then obtain a least squares solution.
+
+ nsing = n;
+ for ( j=0; j<n; j++ )
+ {
+ if ( sdiag[j] == 0. && nsing == n )
+ nsing = j;
+ if (nsing < n)
+ wa[j] = 0;
+ }
+
+ for ( j=nsing-1; j>=0; j-- )
+ {
+ sum = 0;
+ for ( i=j+1; i<nsing; i++ )
+ sum += r[j*ldr+i]*wa[i];
+ wa[j] = (wa[j] - sum)/sdiag[j];
+ }
+
+// *** permute the components of z back to components of x.
+
+ for ( j=0; j<n; j++ )
+ x[ ipvt[j] ] = wa[j];
+}
+
+
+
+double lm_enorm( int n, double *x )
+{
+/* given an n-vector x, this function calculates the
+ * euclidean norm of x.
+ *
+ * the euclidean norm is computed by accumulating the sum of
+ * squares in three different sums. the sums of squares for the
+ * small and large components are scaled so that no overflows
+ * occur. non-destructive underflows are permitted. underflows
+ * and overflows do not occur in the computation of the unscaled
+ * sum of squares for the intermediate components.
+ * the definitions of small, intermediate and large components
+ * depend on two constants, LM_SQRT_DWARF and LM_SQRT_GIANT. the main
+ * restrictions on these constants are that LM_SQRT_DWARF**2 not
+ * underflow and LM_SQRT_GIANT**2 not overflow.
+ *
+ * parameters
+ *
+ * n is a positive integer input variable.
+ *
+ * x is an input array of length n.
+ */
+ int i;
+ double agiant, s1, s2, s3, xabs, x1max, x3max, temp;
+
+ s1 = 0;
+ s2 = 0;
+ s3 = 0;
+ x1max = 0;
+ x3max = 0;
+ agiant = LM_SQRT_GIANT/( (double) n);
+
+ for ( i=0; i<n; i++ )
+ {
+ xabs = fabs(x[i]);
+ if ( xabs > LM_SQRT_DWARF && xabs < agiant )
+ {
+// ** sum for intermediate components.
+ s2 += xabs*xabs;
+ continue;
+ }
+
+ if ( xabs > LM_SQRT_DWARF )
+ {
+// ** sum for large components.
+ if (xabs > x1max)
+ {
+ temp = x1max/xabs;
+ s1 = 1 + s1*SQR(temp);
+ x1max = xabs;
+ }
+ else
+ {
+ temp = xabs/x1max;
+ s1 += SQR(temp);
+ }
+ continue;
+ }
+// ** sum for small components.
+ if (xabs > x3max)
+ {
+ temp = x3max/xabs;
+ s3 = 1 + s3*SQR(temp);
+ x3max = xabs;
+ }
+ else
+ {
+ if (xabs != 0.)
+ {
+ temp = xabs/x3max;
+ s3 += SQR(temp);
+ }
+ }
+ }
+
+// *** calculation of norm.
+
+ if (s1 != 0)
+ return x1max*sqrt(s1 + (s2/x1max)/x1max);
+ if (s2 != 0)
+ {
+ if (s2 >= x3max)
+ return sqrt( s2*(1+(x3max/s2)*(x3max*s3)) );
+ else
+ return sqrt( x3max*((s2/x3max)+(x3max*s3)) );
+ }
+
+ return x3max*sqrt(s3);
+}
diff --git a/src/lmfit/lmmin.h b/src/lmfit/lmmin.h
new file mode 100644
index 0000000..1a90f13
--- /dev/null
+++ b/src/lmfit/lmmin.h
@@ -0,0 +1,52 @@
+// parameters for calling the high-level interface lmfit
+// ( lmfit.c provides lm_initialize_control which sets default values ):
+typedef struct {
+ double ftol; // relative error desired in the sum of squares.
+ double xtol; // relative error between last two approximations.
+ double gtol; // orthogonality desired between fvec and its derivs.
+ double epsilon; // step used to calculate the jacobian.
+ double stepbound; // initial bound to steps in the outer loop.
+ double fnorm; // norm of the residue vector fvec.
+ int maxcall; // maximum number of iterations.
+ int nfev; // actual number of iterations.
+ int info; // status of minimization.
+} lm_control_type;
+
+
+// the subroutine that calculates fvec:
+typedef void (lm_evaluate_ftype) (
+ double* par, int m_dat, double* fvec, void *data, int *info );
+// default implementation therof, provided by lm_eval.c:
+void lm_evaluate_default (
+ double* par, int m_dat, double* fvec, void *data, int *info );
+
+// the subroutine that informs about fit progress:
+typedef void (lm_print_ftype) (
+ int n_par, double* par, int m_dat, double* fvec, void *data,
+ int iflag, int iter, int nfev );
+// default implementation therof, provided by lm_eval.c:
+void lm_print_default (
+ int n_par, double* par, int m_dat, double* fvec, void *data,
+ int iflag, int iter, int nfev );
+
+// compact high-level interface:
+void lm_initialize_control( lm_control_type *control );
+void lm_minimize ( int m_dat, int n_par, double* par,
+ lm_evaluate_ftype *evaluate, lm_print_ftype *printout,
+ void *data, lm_control_type *control );
+double lm_enorm( int, double* );
+
+// low-level interface for full control:
+void lm_lmdif( int m, int n, double* x, double* fvec, double ftol, double xtol,
+ double gtol, int maxfev, double epsfcn, double* diag, int mode,
+ double factor, int *info, int *nfev,
+ double* fjac, int* ipvt, double* qtf,
+ double* wa1, double* wa2, double* wa3, double* wa4,
+ lm_evaluate_ftype *evaluate, lm_print_ftype *printout,
+ void *data );
+
+
+#ifndef _LMDIF
+extern char *lm_infmsg[];
+extern char *lm_shortmsg[];
+#endif
diff --git a/src/oscpack/CHANGES b/src/oscpack/CHANGES
new file mode 100644
index 0000000..804df95
--- /dev/null
+++ b/src/oscpack/CHANGES
@@ -0,0 +1,68 @@
+September 28, 2005
+------------------
+
+Compared to the previous official snapshot (November 2004) the
+current version of oscpack includes a re-written set of network
+classes and some changes to the syntax of the networking code. It no
+longer uses threads, which means that you don't need to use sleep()
+if you are writing a simple single-threaded server, or you need to
+spawn your own threads in a more complex application.
+
+The list below summarises the changes if you are porting code from
+the previous release.
+
+ - there are no longer any threads in oscpack. if you need to
+ set up an asynchronous listener you can create your own thread
+ and call Run on an instance of SocketReceiveMultiplexer or
+ UdpListeningReceiveSocket (see ip/UdpSocket.h) yourself.
+
+ - host byte order is now used for network (IP) addresses
+
+ - functions which used to take two parameters <address, port>
+ now take an instance of IpEndpointName (see
+ ip/IpEndpointName.h) this class has a number of convenient
+ constructors for converting numbers and strings to internet
+ addresses. For example there is one which takes a string and
+ another that take the dotted address components as separate
+ parameters.
+
+ - The UdpTransmitPort class, formerly in UdpTransmitPort.h, is
+ now called UdpTransmitSocket, which is simply a convenience
+ class derived from UdpSocket (see ip/UdpSocket.h). Where you
+ used to use the constructor UdpTransmitPort( address, port) now
+ you can use UdpTransmitSocket( IpEndpointName( address, port )
+ ) or you can any of the other possible ctors to IpEndpointName
+ () (see above). The Send() method is unchanged.
+
+ - The packet listener base class is now located in
+ ip/PacketListener.h instead of PacketListenerPort.h. The
+ ProcessPacket method now has an additional parameter indicating
+ the remote endpoint
+
+ - The preferred way to set up listeners is with
+ SocketReceiveMultiplexer (in ip/UdpSocket.h), this also allows
+ attaching periodic timers. For simple applications which only
+ listen to a single socket with no timers you can use
+ UdpListeningReceiveSocket (also in UdpSocket.h) See
+ osc/OscReceiveTest.cpp or osc/OscDump.cpp for examples of this.
+ This is more or less equivalent to the UdpPacketListenerPort
+ object in the old oscpack versions except that you need to
+ explicitly call Run() before it will start receiving packets
+ and it runs in the same thread, not a separate thread so Run()
+ won't usually return.
+
+ - Explicit calls to InitializeNetworking() and
+ TerminateNetworking() are no longer required for simple
+ applications (more complex windows applications should
+ instantiate NetworkInitializer in main() or WinMain (see
+ ip/NetworkingUtils.h/.cpp)
+
+ - The OscPacketListener base class (OscPacketListener.h) was
+ added to make traversing OSC packets easier, it handles bundle
+ traversal automatically so you only need to process messages in
+ your derived classes.
+
+ - On Windows be sure to link with ws2_32.lib or you will see
+ a linker error about WSAEventSelect not being found. Also you
+ will need to link with winmm.lib for timeGetTime()
+
diff --git a/src/oscpack/IpEndpointName.cpp b/src/oscpack/IpEndpointName.cpp
new file mode 100644
index 0000000..77740d0
--- /dev/null
+++ b/src/oscpack/IpEndpointName.cpp
@@ -0,0 +1,81 @@
+/*
+ oscpack -- Open Sound Control packet manipulation library
+ http://www.audiomulch.com/~rossb/oscpack
+
+ Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files
+ (the "Software"), to deal in the Software without restriction,
+ including without limitation the rights to use, copy, modify, merge,
+ publish, distribute, sublicense, and/or sell copies of the Software,
+ and to permit persons to whom the Software is furnished to do so,
+ subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ Any person wishing to distribute modifications to the Software is
+ requested to send the modifications to the original developer so that
+ they can be incorporated into the canonical version.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+#include "IpEndpointName.h"
+
+#include <stdio.h>
+
+#include "NetworkingUtils.h"
+
+
+unsigned long IpEndpointName::GetHostByName( const char *s )
+{
+ return ::GetHostByName(s);
+}
+
+
+void IpEndpointName::AddressAsString( char *s ) const
+{
+ if( address == ANY_ADDRESS ){
+ sprintf( s, "<any>" );
+ }else{
+ sprintf( s, "%d.%d.%d.%d",
+ (int)((address >> 24) & 0xFF),
+ (int)((address >> 16) & 0xFF),
+ (int)((address >> 8) & 0xFF),
+ (int)(address & 0xFF) );
+ }
+}
+
+
+void IpEndpointName::AddressAndPortAsString( char *s ) const
+{
+ if( port == ANY_PORT ){
+ if( address == ANY_ADDRESS ){
+ sprintf( s, "<any>:<any>" );
+ }else{
+ sprintf( s, "%d.%d.%d.%d:<any>",
+ (int)((address >> 24) & 0xFF),
+ (int)((address >> 16) & 0xFF),
+ (int)((address >> 8) & 0xFF),
+ (int)(address & 0xFF) );
+ }
+ }else{
+ if( address == ANY_ADDRESS ){
+ sprintf( s, "<any>:%d", port );
+ }else{
+ sprintf( s, "%d.%d.%d.%d:%d",
+ (int)((address >> 24) & 0xFF),
+ (int)((address >> 16) & 0xFF),
+ (int)((address >> 8) & 0xFF),
+ (int)(address & 0xFF),
+ (int)port );
+ }
+ }
+}
diff --git a/src/oscpack/IpEndpointName.h b/src/oscpack/IpEndpointName.h
new file mode 100644
index 0000000..af10e72
--- /dev/null
+++ b/src/oscpack/IpEndpointName.h
@@ -0,0 +1,74 @@
+/*
+ oscpack -- Open Sound Control packet manipulation library
+ http://www.audiomulch.com/~rossb/oscpack
+
+ Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files
+ (the "Software"), to deal in the Software without restriction,
+ including without limitation the rights to use, copy, modify, merge,
+ publish, distribute, sublicense, and/or sell copies of the Software,
+ and to permit persons to whom the Software is furnished to do so,
+ subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ Any person wishing to distribute modifications to the Software is
+ requested to send the modifications to the original developer so that
+ they can be incorporated into the canonical version.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+#ifndef INCLUDED_IPENDPOINTNAME_H
+#define INCLUDED_IPENDPOINTNAME_H
+
+
+class IpEndpointName{
+ static unsigned long GetHostByName( const char *s );
+public:
+ static const unsigned long ANY_ADDRESS = 0xFFFFFFFF;
+ static const int ANY_PORT = -1;
+
+ IpEndpointName()
+ : address( ANY_ADDRESS ), port( ANY_PORT ) {}
+ IpEndpointName( int port_ )
+ : address( ANY_ADDRESS ), port( port_ ) {}
+ IpEndpointName( unsigned long ipAddress_, int port_ )
+ : address( ipAddress_ ), port( port_ ) {}
+ IpEndpointName( const char *addressName, int port_=ANY_PORT )
+ : address( GetHostByName( addressName ) )
+ , port( port_ ) {}
+ IpEndpointName( int addressA, int addressB, int addressC, int addressD, int port_=ANY_PORT )
+ : address( ( (addressA << 24) | (addressB << 16) | (addressC << 8) | addressD ) )
+ , port( port_ ) {}
+
+ // address and port are maintained in host byte order here
+ unsigned long address;
+ int port;
+
+ enum { ADDRESS_STRING_LENGTH=17 };
+ void AddressAsString( char *s ) const;
+
+ enum { ADDRESS_AND_PORT_STRING_LENGTH=23};
+ void AddressAndPortAsString( char *s ) const;
+};
+
+inline bool operator==( const IpEndpointName& lhs, const IpEndpointName& rhs )
+{
+ return (lhs.address == rhs.address && lhs.port == rhs.port );
+}
+
+inline bool operator!=( const IpEndpointName& lhs, const IpEndpointName& rhs )
+{
+ return !(lhs == rhs);
+}
+
+#endif /* INCLUDED_IPENDPOINTNAME_H */
diff --git a/src/oscpack/LICENSE b/src/oscpack/LICENSE
new file mode 100644
index 0000000..23c9609
--- /dev/null
+++ b/src/oscpack/LICENSE
@@ -0,0 +1,28 @@
+oscpack -- Open Sound Control packet manipulation library
+http://www.audiomulch.com/~rossb/code/oscpack
+
+Copyright (c) 2004 Ross Bencina <rossb@audiomulch.com>
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files
+(the "Software"), to deal in the Software without restriction,
+including without limitation the rights to use, copy, modify, merge,
+publish, distribute, sublicense, and/or sell copies of the Software,
+and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+Any person wishing to distribute modifications to the Software is
+requested to send the modifications to the original developer so that
+they can be incorporated into the canonical version.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
diff --git a/src/oscpack/Makefile.am b/src/oscpack/Makefile.am
new file mode 100644
index 0000000..8408070
--- /dev/null
+++ b/src/oscpack/Makefile.am
@@ -0,0 +1,12 @@
+ALL_H = IpEndpointName.h NetworkingUtils.h PacketListener.h TimerListener.h UdpSocket.h \
+ MessageMappingOscPacketListener.h OscPacketListener.h OscException.h \
+ OscPrintReceivedElements.h OscHostEndianness.h OscReceivedElements.h \
+ OscOutboundPacketStream.h OscTypes.h
+ALL_CPP = IpEndpointName.cpp NetworkingUtils.cpp UdpSocket.cpp \
+ OscOutboundPacketStream.cpp OscReceivedElements.cpp \
+ OscPrintReceivedElements.cpp OscTypes.cpp
+
+EXTRA_DIST = CHANGES LICENSE README TODO
+
+noinst_LTLIBRARIES = liboscpack.la
+liboscpack_la_SOURCES = $(ALL_CPP) $(ALL_H)
diff --git a/src/oscpack/MessageMappingOscPacketListener.h b/src/oscpack/MessageMappingOscPacketListener.h
new file mode 100644
index 0000000..0df0a4d
--- /dev/null
+++ b/src/oscpack/MessageMappingOscPacketListener.h
@@ -0,0 +1,73 @@
+/*
+ oscpack -- Open Sound Control packet manipulation library
+ http://www.audiomulch.com/~rossb/oscpack
+
+ Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files
+ (the "Software"), to deal in the Software without restriction,
+ including without limitation the rights to use, copy, modify, merge,
+ publish, distribute, sublicense, and/or sell copies of the Software,
+ and to permit persons to whom the Software is furnished to do so,
+ subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ Any person wishing to distribute modifications to the Software is
+ requested to send the modifications to the original developer so that
+ they can be incorporated into the canonical version.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+#ifndef INCLUDED_MESSAGEMAPPINGOSCPACKETLISTENER_H
+#define INCLUDED_MESSAGEMAPPINGOSCPACKETLISTENER_H
+
+#include <string.h>
+#include <map>
+
+#include "OscPacketListener.h"
+
+
+
+namespace osc{
+
+template< class T >
+class MessageMappingOscPacketListener : public OscPacketListener{
+public:
+ typedef void (T::*function_type)(const osc::ReceivedMessage&, const IpEndpointName&);
+
+protected:
+ void RegisterMessageFunction( const char *addressPattern, function_type f )
+ {
+ functions_.insert( std::make_pair( addressPattern, f ) );
+ }
+
+ virtual void ProcessMessage( const osc::ReceivedMessage& m,
+ const IpEndpointName& remoteEndpoint )
+ {
+ typename function_map_type::iterator i = functions_.find( m.AddressPattern() );
+ if( i != functions_.end() )
+ (dynamic_cast<T*>(this)->*(i->second))( m, remoteEndpoint );
+ }
+
+private:
+ struct cstr_compare{
+ bool operator()( const char *lhs, const char *rhs ) const
+ { return strcmp( lhs, rhs ) < 0; }
+ };
+
+ typedef std::map<const char*, function_type, cstr_compare> function_map_type;
+ function_map_type functions_;
+};
+
+} // namespace osc
+
+#endif /* INCLUDED_MESSAGEMAPPINGOSCPACKETLISTENER_H */
diff --git a/src/oscpack/NetworkingUtils.cpp b/src/oscpack/NetworkingUtils.cpp
new file mode 100644
index 0000000..e6a7a54
--- /dev/null
+++ b/src/oscpack/NetworkingUtils.cpp
@@ -0,0 +1,98 @@
+/*
+ oscpack -- Open Sound Control packet manipulation library
+ http://www.audiomulch.com/~rossb/oscpack
+
+ Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files
+ (the "Software"), to deal in the Software without restriction,
+ including without limitation the rights to use, copy, modify, merge,
+ publish, distribute, sublicense, and/or sell copies of the Software,
+ and to permit persons to whom the Software is furnished to do so,
+ subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ Any person wishing to distribute modifications to the Software is
+ requested to send the modifications to the original developer so that
+ they can be incorporated into the canonical version.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+#include "NetworkingUtils.h"
+
+#ifdef WIN32
+#include <winsock2.h> // this must come first to prevent errors with MSVC7
+#include <windows.h>
+#include <stdlib.h>
+
+static LONG initCount_ = 0;
+static bool winsockInitialized_ = false;
+#else
+#include <netdb.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <string.h>
+#endif
+
+#include <stdio.h>
+
+NetworkInitializer::NetworkInitializer()
+{
+#ifdef WIN32
+ if( InterlockedIncrement( &initCount_ ) == 1 ){
+ // there is a race condition here if one thread tries to access
+ // the library while another is still initializing it.
+ // i can't think of an easy way to fix it so i'm telling you here
+ // incase you need to init the library from two threads at once.
+ // this is why the header file advises to instantiate one of these
+ // in main() so that the initialization happens globally
+
+ // initialize winsock
+ WSAData wsaData;
+ int nCode = WSAStartup(MAKEWORD(1, 1), &wsaData);
+ if( nCode != 0 ){
+ //std::cout << "WSAStartup() failed with error code " << nCode << "\n";
+ }else{
+ winsockInitialized_ = true;
+ }
+ }
+#endif
+}
+
+NetworkInitializer::~NetworkInitializer()
+{
+#ifdef WIN32
+ if( InterlockedDecrement( &initCount_ ) == 0 ){
+ if( winsockInitialized_ ){
+ WSACleanup();
+ winsockInitialized_ = false;
+ }
+ }
+#endif
+}
+
+
+unsigned long GetHostByName( const char *name )
+{
+ NetworkInitializer networkInitializer;
+
+ unsigned long result = 0;
+
+ struct hostent *h = gethostbyname( name );
+ if( h ){
+ struct in_addr a;
+ memcpy( &a, h->h_addr_list[0], h->h_length );
+ result = ntohl(a.s_addr);
+ }
+
+ return result;
+}
diff --git a/src/oscpack/NetworkingUtils.h b/src/oscpack/NetworkingUtils.h
new file mode 100644
index 0000000..d76807b
--- /dev/null
+++ b/src/oscpack/NetworkingUtils.h
@@ -0,0 +1,49 @@
+/*
+ oscpack -- Open Sound Control packet manipulation library
+ http://www.audiomulch.com/~rossb/oscpack
+
+ Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files
+ (the "Software"), to deal in the Software without restriction,
+ including without limitation the rights to use, copy, modify, merge,
+ publish, distribute, sublicense, and/or sell copies of the Software,
+ and to permit persons to whom the Software is furnished to do so,
+ subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ Any person wishing to distribute modifications to the Software is
+ requested to send the modifications to the original developer so that
+ they can be incorporated into the canonical version.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+#ifndef INCLUDED_NETWORKINGUTILS_H
+#define INCLUDED_NETWORKINGUTILS_H
+
+
+// in general NetworkInitializer is only used internally, but if you're
+// application creates multiple sockets from different threads at runtime you
+// should instantiate one of these in main just to make sure the networking
+// layer is initialized.
+class NetworkInitializer{
+public:
+ NetworkInitializer();
+ ~NetworkInitializer();
+};
+
+
+// return ip address of host name in host byte order
+unsigned long GetHostByName( const char *name );
+
+
+#endif /* INCLUDED_NETWORKINGUTILS_H */
diff --git a/src/oscpack/OscException.h b/src/oscpack/OscException.h
new file mode 100644
index 0000000..78cc2db
--- /dev/null
+++ b/src/oscpack/OscException.h
@@ -0,0 +1,54 @@
+/*
+ oscpack -- Open Sound Control packet manipulation library
+ http://www.audiomulch.com/~rossb/oscpack
+
+ Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files
+ (the "Software"), to deal in the Software without restriction,
+ including without limitation the rights to use, copy, modify, merge,
+ publish, distribute, sublicense, and/or sell copies of the Software,
+ and to permit persons to whom the Software is furnished to do so,
+ subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ Any person wishing to distribute modifications to the Software is
+ requested to send the modifications to the original developer so that
+ they can be incorporated into the canonical version.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+#ifndef INCLUDED_OSC_EXCEPTION_H
+#define INCLUDED_OSC_EXCEPTION_H
+
+#include <exception>
+
+namespace osc{
+
+class Exception : public std::exception {
+ const char *what_;
+
+public:
+ Exception() throw() {}
+ Exception( const Exception& src ) throw()
+ : what_( src.what_ ) {}
+ Exception( const char *w ) throw()
+ : what_( w ) {}
+ Exception& operator=( const Exception& src ) throw()
+ { what_ = src.what_; return *this; }
+ virtual ~Exception() throw() {}
+ virtual const char* what() const throw() { return what_; }
+};
+
+} // namespace osc
+
+#endif /* INCLUDED_OSC_EXCEPTION_H */
diff --git a/src/oscpack/OscHostEndianness.h b/src/oscpack/OscHostEndianness.h
new file mode 100644
index 0000000..bb811c2
--- /dev/null
+++ b/src/oscpack/OscHostEndianness.h
@@ -0,0 +1,70 @@
+/*
+ oscpack -- Open Sound Control packet manipulation library
+ http://www.audiomulch.com/~rossb/oscpack
+
+ Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files
+ (the "Software"), to deal in the Software without restriction,
+ including without limitation the rights to use, copy, modify, merge,
+ publish, distribute, sublicense, and/or sell copies of the Software,
+ and to permit persons to whom the Software is furnished to do so,
+ subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ Any person wishing to distribute modifications to the Software is
+ requested to send the modifications to the original developer so that
+ they can be incorporated into the canonical version.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+#ifndef OSC_HOSTENDIANNESS_H
+#define OSC_HOSTENDIANNESS_H
+
+/*
+ Make sure either OSC_HOST_LITTLE_ENDIAN or OSC_HOST_BIG_ENDIAN is defined
+
+ If you know a way to enhance the detection below for Linux and/or MacOSX
+ please let me know! I've tried a few things which don't work.
+*/
+
+#if defined(OSC_HOST_LITTLE_ENDIAN) || defined(OSC_HOST_BIG_ENDIAN)
+
+// you can define one of the above symbols from the command line
+// then you don't have to edit this file.
+
+#elif defined(__WIN32__) || defined(WIN32)
+
+// assume that __WIN32__ is only defined on little endian systems
+
+#define OSC_HOST_LITTLE_ENDIAN 1
+#undef OSC_HOST_BIG_ENDIAN
+
+#elif defined(__APPLE__)
+
+#if defined(__LITTLE_ENDIAN__)
+#define OSC_HOST_LITTLE_ENDIAN 1
+#undef OSC_HOST_BIG_ENDIAN
+#else
+#define OSC_HOST_BIG_ENDIAN 1
+#undef OSC_HOST_LITTLE_ENDIAN
+#endif
+
+#else
+
+#define OSC_HOST_LITTLE_ENDIAN 1
+#undef OSC_HOST_BIG_ENDIAN
+
+#endif
+
+#endif /* OSC_HOSTENDIANNESS_H */
+
diff --git a/src/oscpack/OscOutboundPacketStream.cpp b/src/oscpack/OscOutboundPacketStream.cpp
new file mode 100644
index 0000000..a91d10a
--- /dev/null
+++ b/src/oscpack/OscOutboundPacketStream.cpp
@@ -0,0 +1,639 @@
+/*
+ oscpack -- Open Sound Control packet manipulation library
+ http://www.audiomulch.com/~rossb/oscpack
+
+ Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files
+ (the "Software"), to deal in the Software without restriction,
+ including without limitation the rights to use, copy, modify, merge,
+ publish, distribute, sublicense, and/or sell copies of the Software,
+ and to permit persons to whom the Software is furnished to do so,
+ subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ Any person wishing to distribute modifications to the Software is
+ requested to send the modifications to the original developer so that
+ they can be incorporated into the canonical version.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+#include "OscOutboundPacketStream.h"
+
+#include <string.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#if defined(__WIN32__) || defined(WIN32)
+#include <malloc.h> // for alloca
+#endif
+
+#include "OscHostEndianness.h"
+
+
+namespace osc{
+
+static void FromInt32( char *p, int32 x )
+{
+#ifdef OSC_HOST_LITTLE_ENDIAN
+ union{
+ osc::int32 i;
+ char c[4];
+ } u;
+
+ u.i = x;
+
+ p[3] = u.c[0];
+ p[2] = u.c[1];
+ p[1] = u.c[2];
+ p[0] = u.c[3];
+#else
+ *reinterpret_cast<int32*>(p) = x;
+#endif
+}
+
+
+static void FromUInt32( char *p, uint32 x )
+{
+#ifdef OSC_HOST_LITTLE_ENDIAN
+ union{
+ osc::uint32 i;
+ char c[4];
+ } u;
+
+ u.i = x;
+
+ p[3] = u.c[0];
+ p[2] = u.c[1];
+ p[1] = u.c[2];
+ p[0] = u.c[3];
+#else
+ *reinterpret_cast<uint32*>(p) = x;
+#endif
+}
+
+
+static void FromInt64( char *p, int64 x )
+{
+#ifdef OSC_HOST_LITTLE_ENDIAN
+ union{
+ osc::int64 i;
+ char c[8];
+ } u;
+
+ u.i = x;
+
+ p[7] = u.c[0];
+ p[6] = u.c[1];
+ p[5] = u.c[2];
+ p[4] = u.c[3];
+ p[3] = u.c[4];
+ p[2] = u.c[5];
+ p[1] = u.c[6];
+ p[0] = u.c[7];
+#else
+ *reinterpret_cast<int64*>(p) = x;
+#endif
+}
+
+
+static void FromUInt64( char *p, uint64 x )
+{
+#ifdef OSC_HOST_LITTLE_ENDIAN
+ union{
+ osc::uint64 i;
+ char c[8];
+ } u;
+
+ u.i = x;
+
+ p[7] = u.c[0];
+ p[6] = u.c[1];
+ p[5] = u.c[2];
+ p[4] = u.c[3];
+ p[3] = u.c[4];
+ p[2] = u.c[5];
+ p[1] = u.c[6];
+ p[0] = u.c[7];
+#else
+ *reinterpret_cast<uint64*>(p) = x;
+#endif
+}
+
+
+static inline long RoundUp4( long x )
+{
+ return ((x-1) & (~0x03L)) + 4;
+}
+
+
+OutboundPacketStream::OutboundPacketStream( char *buffer, unsigned long capacity )
+ : data_( buffer )
+ , end_( data_ + capacity )
+ , typeTagsCurrent_( end_ )
+ , messageCursor_( data_ )
+ , argumentCurrent_( data_ )
+ , elementSizePtr_( 0 )
+ , messageIsInProgress_( false )
+{
+
+}
+
+
+OutboundPacketStream::~OutboundPacketStream()
+{
+
+}
+
+
+char *OutboundPacketStream::BeginElement( char *beginPtr )
+{
+ if( elementSizePtr_ == 0 ){
+
+ elementSizePtr_ = reinterpret_cast<uint32*>(data_);
+
+ return beginPtr;
+
+ }else{
+ // store an offset to the old element size ptr in the element size slot
+ // we store an offset rather than the actual pointer to be 64 bit clean.
+ *reinterpret_cast<uint32*>(beginPtr) =
+ (uint32)(reinterpret_cast<char*>(elementSizePtr_) - data_);
+
+ elementSizePtr_ = reinterpret_cast<uint32*>(beginPtr);
+
+ return beginPtr + 4;
+ }
+}
+
+
+void OutboundPacketStream::EndElement( char *endPtr )
+{
+ assert( elementSizePtr_ != 0 );
+
+ if( elementSizePtr_ == reinterpret_cast<uint32*>(data_) ){
+
+ elementSizePtr_ = 0;
+
+ }else{
+ // while building an element, an offset to the containing element's
+ // size slot is stored in the elements size slot (or a ptr to data_
+ // if there is no containing element). We retrieve that here
+ uint32 *previousElementSizePtr =
+ (uint32*)(data_ + *reinterpret_cast<uint32*>(elementSizePtr_));
+
+ // then we store the element size in the slot, note that the element
+ // size does not include the size slot, hence the - 4 below.
+ uint32 elementSize =
+ (endPtr - reinterpret_cast<char*>(elementSizePtr_)) - 4;
+ FromUInt32( reinterpret_cast<char*>(elementSizePtr_), elementSize );
+
+ // finally, we reset the element size ptr to the containing element
+ elementSizePtr_ = previousElementSizePtr;
+ }
+}
+
+
+bool OutboundPacketStream::ElementSizeSlotRequired() const
+{
+ return (elementSizePtr_ != 0);
+}
+
+
+void OutboundPacketStream::CheckForAvailableBundleSpace()
+{
+ unsigned long required = Size() + ((ElementSizeSlotRequired())?4:0) + 16;
+
+ if( required > Capacity() )
+ throw OutOfBufferMemoryException();
+}
+
+
+void OutboundPacketStream::CheckForAvailableMessageSpace( const char *addressPattern )
+{
+ // plus 4 for at least four bytes of type tag
+ unsigned long required = Size() + ((ElementSizeSlotRequired())?4:0)
+ + RoundUp4(strlen(addressPattern) + 1) + 4;
+
+ if( required > Capacity() )
+ throw OutOfBufferMemoryException();
+}
+
+
+void OutboundPacketStream::CheckForAvailableArgumentSpace( long argumentLength )
+{
+ // plus three for extra type tag, comma and null terminator
+ unsigned long required = (argumentCurrent_ - data_) + argumentLength
+ + RoundUp4( (end_ - typeTagsCurrent_) + 3 );
+
+ if( required > Capacity() )
+ throw OutOfBufferMemoryException();
+}
+
+
+void OutboundPacketStream::Clear()
+{
+ typeTagsCurrent_ = end_;
+ messageCursor_ = data_;
+ argumentCurrent_ = data_;
+ elementSizePtr_ = 0;
+ messageIsInProgress_ = false;
+}
+
+
+unsigned int OutboundPacketStream::Capacity() const
+{
+ return end_ - data_;
+}
+
+
+unsigned int OutboundPacketStream::Size() const
+{
+ unsigned int result = argumentCurrent_ - data_;
+ if( IsMessageInProgress() ){
+ // account for the length of the type tag string. the total type tag
+ // includes an initial comma, plus at least one terminating \0
+ result += RoundUp4( (end_ - typeTagsCurrent_) + 2 );
+ }
+
+ return result;
+}
+
+
+const char *OutboundPacketStream::Data() const
+{
+ return data_;
+}
+
+
+bool OutboundPacketStream::IsReady() const
+{
+ return (!IsMessageInProgress() && !IsBundleInProgress());
+}
+
+
+bool OutboundPacketStream::IsMessageInProgress() const
+{
+ return messageIsInProgress_;
+}
+
+
+bool OutboundPacketStream::IsBundleInProgress() const
+{
+ return (elementSizePtr_ != 0);
+}
+
+
+OutboundPacketStream& OutboundPacketStream::operator<<( const BundleInitiator& rhs )
+{
+ if( IsMessageInProgress() )
+ throw MessageInProgressException();
+
+ CheckForAvailableBundleSpace();
+
+ messageCursor_ = BeginElement( messageCursor_ );
+
+ memcpy( messageCursor_, "#bundle\0", 8 );
+ FromUInt64( messageCursor_ + 8, rhs.timeTag );
+
+ messageCursor_ += 16;
+ argumentCurrent_ = messageCursor_;
+
+ return *this;
+}
+
+
+OutboundPacketStream& OutboundPacketStream::operator<<( const BundleTerminator& rhs )
+{
+ (void) rhs;
+
+ if( !IsBundleInProgress() )
+ throw BundleNotInProgressException();
+ if( IsMessageInProgress() )
+ throw MessageInProgressException();
+
+ EndElement( messageCursor_ );
+
+ return *this;
+}
+
+
+OutboundPacketStream& OutboundPacketStream::operator<<( const BeginMessage& rhs )
+{
+ if( IsMessageInProgress() )
+ throw MessageInProgressException();
+
+ CheckForAvailableMessageSpace( rhs.addressPattern );
+
+ messageCursor_ = BeginElement( messageCursor_ );
+
+ strcpy( messageCursor_, rhs.addressPattern );
+ unsigned long rhsLength = strlen(rhs.addressPattern);
+ messageCursor_ += rhsLength + 1;
+
+ // zero pad to 4-byte boundary
+ unsigned long i = rhsLength + 1;
+ while( i & 0x3 ){
+ *messageCursor_++ = '\0';
+ ++i;
+ }
+
+ argumentCurrent_ = messageCursor_;
+ typeTagsCurrent_ = end_;
+
+ messageIsInProgress_ = true;
+
+ return *this;
+}
+
+
+OutboundPacketStream& OutboundPacketStream::operator<<( const MessageTerminator& rhs )
+{
+ (void) rhs;
+
+ if( !IsMessageInProgress() )
+ throw MessageNotInProgressException();
+
+ int typeTagsCount = end_ - typeTagsCurrent_;
+
+ if( typeTagsCount ){
+
+ char *tempTypeTags = (char*)alloca(typeTagsCount);
+ memcpy( tempTypeTags, typeTagsCurrent_, typeTagsCount );
+
+ // slot size includes comma and null terminator
+ int typeTagSlotSize = RoundUp4( typeTagsCount + 2 );
+
+ uint32 argumentsSize = argumentCurrent_ - messageCursor_;
+
+ memmove( messageCursor_ + typeTagSlotSize, messageCursor_, argumentsSize );
+
+ messageCursor_[0] = ',';
+ // copy type tags in reverse (really forward) order
+ for( int i=0; i < typeTagsCount; ++i )
+ messageCursor_[i+1] = tempTypeTags[ (typeTagsCount-1) - i ];
+
+ char *p = messageCursor_ + 1 + typeTagsCount;
+ for( int i=0; i < (typeTagSlotSize - (typeTagsCount + 1)); ++i )
+ *p++ = '\0';
+
+ typeTagsCurrent_ = end_;
+
+ // advance messageCursor_ for next message
+ messageCursor_ += typeTagSlotSize + argumentsSize;
+
+ }else{
+ // send an empty type tags string
+ memcpy( messageCursor_, ",\0\0\0", 4 );
+
+ // advance messageCursor_ for next message
+ messageCursor_ += 4;
+ }
+
+ argumentCurrent_ = messageCursor_;
+
+ EndElement( messageCursor_ );
+
+ messageIsInProgress_ = false;
+
+ return *this;
+}
+
+
+OutboundPacketStream& OutboundPacketStream::operator<<( bool rhs )
+{
+ CheckForAvailableArgumentSpace(0);
+
+ *(--typeTagsCurrent_) = (char)((rhs) ? TRUE_TYPE_TAG : FALSE_TYPE_TAG);
+
+ return *this;
+}
+
+
+OutboundPacketStream& OutboundPacketStream::operator<<( const NilType& rhs )
+{
+ (void) rhs;
+ CheckForAvailableArgumentSpace(0);
+
+ *(--typeTagsCurrent_) = NIL_TYPE_TAG;
+
+ return *this;
+}
+
+
+OutboundPacketStream& OutboundPacketStream::operator<<( const InfinitumType& rhs )
+{
+ (void) rhs;
+ CheckForAvailableArgumentSpace(0);
+
+ *(--typeTagsCurrent_) = INFINITUM_TYPE_TAG;
+
+ return *this;
+}
+
+
+OutboundPacketStream& OutboundPacketStream::operator<<( int32 rhs )
+{
+ CheckForAvailableArgumentSpace(4);
+
+ *(--typeTagsCurrent_) = INT32_TYPE_TAG;
+ FromInt32( argumentCurrent_, rhs );
+ argumentCurrent_ += 4;
+
+ return *this;
+}
+
+
+OutboundPacketStream& OutboundPacketStream::operator<<( float rhs )
+{
+ CheckForAvailableArgumentSpace(4);
+
+ *(--typeTagsCurrent_) = FLOAT_TYPE_TAG;
+
+#ifdef OSC_HOST_LITTLE_ENDIAN
+ union{
+ float f;
+ char c[4];
+ } u;
+
+ u.f = rhs;
+
+ argumentCurrent_[3] = u.c[0];
+ argumentCurrent_[2] = u.c[1];
+ argumentCurrent_[1] = u.c[2];
+ argumentCurrent_[0] = u.c[3];
+#else
+ *reinterpret_cast<float*>(argumentCurrent_) = rhs;
+#endif
+
+ argumentCurrent_ += 4;
+
+ return *this;
+}
+
+
+OutboundPacketStream& OutboundPacketStream::operator<<( char rhs )
+{
+ CheckForAvailableArgumentSpace(4);
+
+ *(--typeTagsCurrent_) = CHAR_TYPE_TAG;
+ FromInt32( argumentCurrent_, rhs );
+ argumentCurrent_ += 4;
+
+ return *this;
+}
+
+
+OutboundPacketStream& OutboundPacketStream::operator<<( const RgbaColor& rhs )
+{
+ CheckForAvailableArgumentSpace(4);
+
+ *(--typeTagsCurrent_) = RGBA_COLOR_TYPE_TAG;
+ FromUInt32( argumentCurrent_, rhs );
+ argumentCurrent_ += 4;
+
+ return *this;
+}
+
+
+OutboundPacketStream& OutboundPacketStream::operator<<( const MidiMessage& rhs )
+{
+ CheckForAvailableArgumentSpace(4);
+
+ *(--typeTagsCurrent_) = MIDI_MESSAGE_TYPE_TAG;
+ FromUInt32( argumentCurrent_, rhs );
+ argumentCurrent_ += 4;
+
+ return *this;
+}
+
+
+OutboundPacketStream& OutboundPacketStream::operator<<( int64 rhs )
+{
+ CheckForAvailableArgumentSpace(8);
+
+ *(--typeTagsCurrent_) = INT64_TYPE_TAG;
+ FromInt64( argumentCurrent_, rhs );
+ argumentCurrent_ += 8;
+
+ return *this;
+}
+
+
+OutboundPacketStream& OutboundPacketStream::operator<<( const TimeTag& rhs )
+{
+ CheckForAvailableArgumentSpace(8);
+
+ *(--typeTagsCurrent_) = TIME_TAG_TYPE_TAG;
+ FromUInt64( argumentCurrent_, rhs );
+ argumentCurrent_ += 8;
+
+ return *this;
+}
+
+
+OutboundPacketStream& OutboundPacketStream::operator<<( double rhs )
+{
+ CheckForAvailableArgumentSpace(8);
+
+ *(--typeTagsCurrent_) = DOUBLE_TYPE_TAG;
+
+#ifdef OSC_HOST_LITTLE_ENDIAN
+ union{
+ double f;
+ char c[8];
+ } u;
+
+ u.f = rhs;
+
+ argumentCurrent_[7] = u.c[0];
+ argumentCurrent_[6] = u.c[1];
+ argumentCurrent_[5] = u.c[2];
+ argumentCurrent_[4] = u.c[3];
+ argumentCurrent_[3] = u.c[4];
+ argumentCurrent_[2] = u.c[5];
+ argumentCurrent_[1] = u.c[6];
+ argumentCurrent_[0] = u.c[7];
+#else
+ *reinterpret_cast<double*>(argumentCurrent_) = rhs;
+#endif
+
+ argumentCurrent_ += 8;
+
+ return *this;
+}
+
+
+OutboundPacketStream& OutboundPacketStream::operator<<( const char *rhs )
+{
+ CheckForAvailableArgumentSpace( RoundUp4(strlen(rhs) + 1) );
+
+ *(--typeTagsCurrent_) = STRING_TYPE_TAG;
+ strcpy( argumentCurrent_, rhs );
+ unsigned long rhsLength = strlen(rhs);
+ argumentCurrent_ += rhsLength + 1;
+
+ // zero pad to 4-byte boundary
+ unsigned long i = rhsLength + 1;
+ while( i & 0x3 ){
+ *argumentCurrent_++ = '\0';
+ ++i;
+ }
+
+ return *this;
+}
+
+
+OutboundPacketStream& OutboundPacketStream::operator<<( const Symbol& rhs )
+{
+ CheckForAvailableArgumentSpace( RoundUp4(strlen(rhs) + 1) );
+
+ *(--typeTagsCurrent_) = SYMBOL_TYPE_TAG;
+ strcpy( argumentCurrent_, rhs );
+ unsigned long rhsLength = strlen(rhs);
+ argumentCurrent_ += rhsLength + 1;
+
+ // zero pad to 4-byte boundary
+ unsigned long i = rhsLength + 1;
+ while( i & 0x3 ){
+ *argumentCurrent_++ = '\0';
+ ++i;
+ }
+
+ return *this;
+}
+
+
+OutboundPacketStream& OutboundPacketStream::operator<<( const Blob& rhs )
+{
+ CheckForAvailableArgumentSpace( 4 + RoundUp4(rhs.size) );
+
+ *(--typeTagsCurrent_) = BLOB_TYPE_TAG;
+ FromUInt32( argumentCurrent_, rhs.size );
+ argumentCurrent_ += 4;
+
+ memcpy( argumentCurrent_, rhs.data, rhs.size );
+ argumentCurrent_ += rhs.size;
+
+ // zero pad to 4-byte boundary
+ unsigned long i = rhs.size;
+ while( i & 0x3 ){
+ *argumentCurrent_++ = '\0';
+ ++i;
+ }
+
+ return *this;
+}
+
+} // namespace osc
+
+
diff --git a/src/oscpack/OscOutboundPacketStream.h b/src/oscpack/OscOutboundPacketStream.h
new file mode 100644
index 0000000..5afbaa6
--- /dev/null
+++ b/src/oscpack/OscOutboundPacketStream.h
@@ -0,0 +1,142 @@
+/*
+ oscpack -- Open Sound Control packet manipulation library
+ http://www.audiomulch.com/~rossb/oscpack
+
+ Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files
+ (the "Software"), to deal in the Software without restriction,
+ including without limitation the rights to use, copy, modify, merge,
+ publish, distribute, sublicense, and/or sell copies of the Software,
+ and to permit persons to whom the Software is furnished to do so,
+ subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ Any person wishing to distribute modifications to the Software is
+ requested to send the modifications to the original developer so that
+ they can be incorporated into the canonical version.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+#ifndef INCLUDED_OSCOUTBOUNDPACKET_H
+#define INCLUDED_OSCOUTBOUNDPACKET_H
+
+#include "OscTypes.h"
+#include "OscException.h"
+
+
+namespace osc{
+
+class OutOfBufferMemoryException : public Exception{
+public:
+ OutOfBufferMemoryException( const char *w="out of buffer memory" )
+ : Exception( w ) {}
+};
+
+class BundleNotInProgressException : public Exception{
+public:
+ BundleNotInProgressException(
+ const char *w="call to EndBundle when bundle is not in progress" )
+ : Exception( w ) {}
+};
+
+class MessageInProgressException : public Exception{
+public:
+ MessageInProgressException(
+ const char *w="opening or closing bundle or message while message is in progress" )
+ : Exception( w ) {}
+};
+
+class MessageNotInProgressException : public Exception{
+public:
+ MessageNotInProgressException(
+ const char *w="call to EndMessage when message is not in progress" )
+ : Exception( w ) {}
+};
+
+
+class OutboundPacketStream{
+public:
+ OutboundPacketStream( char *buffer, unsigned long capacity );
+ ~OutboundPacketStream();
+
+ void Clear();
+
+ unsigned int Capacity() const;
+
+ // invariant: size() is valid even while building a message.
+ unsigned int Size() const;
+
+ const char *Data() const;
+
+ // indicates that all messages have been closed with a matching EndMessage
+ // and all bundles have been closed with a matching EndBundle
+ bool IsReady() const;
+
+ bool IsMessageInProgress() const;
+ bool IsBundleInProgress() const;
+
+ OutboundPacketStream& operator<<( const BundleInitiator& rhs );
+ OutboundPacketStream& operator<<( const BundleTerminator& rhs );
+
+ OutboundPacketStream& operator<<( const BeginMessage& rhs );
+ OutboundPacketStream& operator<<( const MessageTerminator& rhs );
+
+ OutboundPacketStream& operator<<( bool rhs );
+ OutboundPacketStream& operator<<( const NilType& rhs );
+ OutboundPacketStream& operator<<( const InfinitumType& rhs );
+ OutboundPacketStream& operator<<( int32 rhs );
+
+#if !(defined(__x86_64__)) && !(defined(__APPLE__))
+ OutboundPacketStream& operator<<( int rhs )
+ { *this << (int32)rhs; return *this; }
+#endif
+
+ OutboundPacketStream& operator<<( float rhs );
+ OutboundPacketStream& operator<<( char rhs );
+ OutboundPacketStream& operator<<( const RgbaColor& rhs );
+ OutboundPacketStream& operator<<( const MidiMessage& rhs );
+ OutboundPacketStream& operator<<( int64 rhs );
+ OutboundPacketStream& operator<<( const TimeTag& rhs );
+ OutboundPacketStream& operator<<( double rhs );
+ OutboundPacketStream& operator<<( const char* rhs );
+ OutboundPacketStream& operator<<( const Symbol& rhs );
+ OutboundPacketStream& operator<<( const Blob& rhs );
+
+private:
+
+ char *BeginElement( char *beginPtr );
+ void EndElement( char *endPtr );
+
+ bool ElementSizeSlotRequired() const;
+ void CheckForAvailableBundleSpace();
+ void CheckForAvailableMessageSpace( const char *addressPattern );
+ void CheckForAvailableArgumentSpace( long argumentLength );
+
+ char *data_;
+ char *end_;
+
+ char *typeTagsCurrent_; // stored in reverse order
+ char *messageCursor_;
+ char *argumentCurrent_;
+
+ // elementSizePtr_ has two special values: 0 indicates that a bundle
+ // isn't open, and elementSizePtr_==data_ indicates that a bundle is
+ // open but that it doesn't have a size slot (ie the outermost bundle)
+ uint32 *elementSizePtr_;
+
+ bool messageIsInProgress_;
+};
+
+} // namespace osc
+
+#endif /* INCLUDED_OSC_OUTBOUND_PACKET_H */
diff --git a/src/oscpack/OscPacketListener.h b/src/oscpack/OscPacketListener.h
new file mode 100644
index 0000000..7ffbc0e
--- /dev/null
+++ b/src/oscpack/OscPacketListener.h
@@ -0,0 +1,72 @@
+/*
+ oscpack -- Open Sound Control packet manipulation library
+ http://www.audiomulch.com/~rossb/oscpack
+
+ Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files
+ (the "Software"), to deal in the Software without restriction,
+ including without limitation the rights to use, copy, modify, merge,
+ publish, distribute, sublicense, and/or sell copies of the Software,
+ and to permit persons to whom the Software is furnished to do so,
+ subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ Any person wishing to distribute modifications to the Software is
+ requested to send the modifications to the original developer so that
+ they can be incorporated into the canonical version.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+#ifndef INCLUDED_OSCPACKETLISTENER_H
+#define INCLUDED_OSCPACKETLISTENER_H
+
+#include "OscReceivedElements.h"
+#include "PacketListener.h"
+
+
+namespace osc{
+
+class OscPacketListener : public PacketListener{
+protected:
+ virtual void ProcessBundle( const osc::ReceivedBundle& b,
+ const IpEndpointName& remoteEndpoint )
+ {
+ // ignore bundle time tag for now
+
+ for( ReceivedBundle::const_iterator i = b.ElementsBegin();
+ i != b.ElementsEnd(); ++i ){
+ if( i->IsBundle() )
+ ProcessBundle( ReceivedBundle(*i), remoteEndpoint );
+ else
+ ProcessMessage( ReceivedMessage(*i), remoteEndpoint );
+ }
+ }
+
+ virtual void ProcessMessage( const osc::ReceivedMessage& m,
+ const IpEndpointName& remoteEndpoint ) = 0;
+
+public:
+ virtual void ProcessPacket( const char *data, int size,
+ const IpEndpointName& remoteEndpoint )
+ {
+ osc::ReceivedPacket p( data, size );
+ if( p.IsBundle() )
+ ProcessBundle( ReceivedBundle(p), remoteEndpoint );
+ else
+ ProcessMessage( ReceivedMessage(p), remoteEndpoint );
+ }
+};
+
+} // namespace osc
+
+#endif /* INCLUDED_OSCPACKETLISTENER_H */
diff --git a/src/oscpack/OscPrintReceivedElements.cpp b/src/oscpack/OscPrintReceivedElements.cpp
new file mode 100644
index 0000000..8c3722d
--- /dev/null
+++ b/src/oscpack/OscPrintReceivedElements.cpp
@@ -0,0 +1,240 @@
+/*
+ oscpack -- Open Sound Control packet manipulation library
+ http://www.audiomulch.com/~rossb/oscpack
+
+ Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files
+ (the "Software"), to deal in the Software without restriction,
+ including without limitation the rights to use, copy, modify, merge,
+ publish, distribute, sublicense, and/or sell copies of the Software,
+ and to permit persons to whom the Software is furnished to do so,
+ subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ Any person wishing to distribute modifications to the Software is
+ requested to send the modifications to the original developer so that
+ they can be incorporated into the canonical version.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+#include "OscPrintReceivedElements.h"
+
+#include <iostream>
+#include <iomanip>
+#include <ctime>
+#include <string.h>
+
+namespace osc{
+
+
+std::ostream& operator<<( std::ostream & os,
+ const ReceivedMessageArgument& arg )
+{
+ switch( arg.TypeTag() ){
+ case TRUE_TYPE_TAG:
+ os << "bool:true";
+ break;
+
+ case FALSE_TYPE_TAG:
+ os << "bool:false";
+ break;
+
+ case NIL_TYPE_TAG:
+ os << "(Nil)";
+ break;
+
+ case INFINITUM_TYPE_TAG:
+ os << "(Infinitum)";
+ break;
+
+ case INT32_TYPE_TAG:
+ os << "int32:" << arg.AsInt32Unchecked();
+ break;
+
+ case FLOAT_TYPE_TAG:
+ os << "float32:" << arg.AsFloatUnchecked();
+ break;
+
+ case CHAR_TYPE_TAG:
+ {
+ char s[2] = {0};
+ s[0] = arg.AsCharUnchecked();
+ os << "char:'" << s << "'";
+ }
+ break;
+
+ case RGBA_COLOR_TYPE_TAG:
+ {
+ uint32 color = arg.AsRgbaColorUnchecked();
+
+ os << "RGBA:0x"
+ << std::hex << std::setfill('0')
+ << std::setw(2) << (int)((color>>24) & 0xFF)
+ << std::setw(2) << (int)((color>>16) & 0xFF)
+ << std::setw(2) << (int)((color>>8) & 0xFF)
+ << std::setw(2) << (int)(color & 0xFF)
+ << std::setfill(' ');
+ os.unsetf(std::ios::basefield);
+ }
+ break;
+
+ case MIDI_MESSAGE_TYPE_TAG:
+ {
+ uint32 m = arg.AsMidiMessageUnchecked();
+ os << "midi (port, status, data1, data2):<<"
+ << std::hex << std::setfill('0')
+ << "0x" << std::setw(2) << (int)((m>>24) & 0xFF)
+ << " 0x" << std::setw(2) << (int)((m>>16) & 0xFF)
+ << " 0x" << std::setw(2) << (int)((m>>8) & 0xFF)
+ << " 0x" << std::setw(2) << (int)(m & 0xFF)
+ << std::setfill(' ') << ">>";
+ os.unsetf(std::ios::basefield);
+ }
+ break;
+
+ case INT64_TYPE_TAG:
+ os << "int64:" << arg.AsInt64Unchecked();
+ break;
+
+ case TIME_TAG_TYPE_TAG:
+ {
+ os << "OSC-timetag:" << arg.AsTimeTagUnchecked();
+
+ std::time_t t =
+ (unsigned long)( arg.AsTimeTagUnchecked() >> 32 );
+
+ // strip trailing newline from string returned by ctime
+ const char *timeString = std::ctime( &t );
+ size_t len = strlen( timeString );
+ char *s = new char[ len + 1 ];
+ strcpy( s, timeString );
+ if( len )
+ s[ len - 1 ] = '\0';
+
+ os << " " << s;
+ }
+ break;
+
+ case DOUBLE_TYPE_TAG:
+ os << "double:" << arg.AsDoubleUnchecked();
+ break;
+
+ case STRING_TYPE_TAG:
+ os << "OSC-string:`" << arg.AsStringUnchecked() << "'";
+ break;
+
+ case SYMBOL_TYPE_TAG:
+ os << "OSC-string (symbol):`" << arg.AsSymbolUnchecked() << "'";
+ break;
+
+ case BLOB_TYPE_TAG:
+ {
+ unsigned long size;
+ const void *data;
+ arg.AsBlobUnchecked( data, size );
+ os << "OSC-blob:<<" << std::hex << std::setfill('0');
+ unsigned char *p = (unsigned char*)data;
+ for( unsigned long i = 0; i < size; ++i ){
+ os << "0x" << std::setw(2) << int(p[i]);
+ if( i != size-1 )
+ os << ' ';
+ }
+ os.unsetf(std::ios::basefield);
+ os << ">>" << std::setfill(' ');
+ }
+ break;
+
+ default:
+ os << "unknown";
+ }
+
+ return os;
+}
+
+
+std::ostream& operator<<( std::ostream & os, const ReceivedMessage& m )
+{
+
+ os << "[" << m.AddressPattern();
+ bool first = true;
+
+ for( ReceivedMessage::const_iterator i = m.ArgumentsBegin();
+ i != m.ArgumentsEnd(); ++i ){
+ if( first ){
+ os << " ";
+ first = false;
+ }else{
+ os << ", ";
+ }
+
+ os << *i;
+ }
+
+ os << "]";
+
+ return os;
+}
+
+
+std::ostream& operator<<( std::ostream & os, const ReceivedBundle& b )
+{
+ static int indent = 0;
+
+ for( int j=0; j < indent; ++j )
+ os << " ";
+ os << "{ ( ";
+ if( b.TimeTag() == 1 )
+ os << "immediate";
+ else
+ os << b.TimeTag();
+ os << " )\n";
+
+ ++indent;
+
+ for( ReceivedBundle::const_iterator i = b.ElementsBegin();
+ i != b.ElementsEnd(); ++i ){
+ if( i->IsBundle() ){
+ ReceivedBundle b(*i);
+ os << b << "\n";
+ }else{
+ ReceivedMessage m(*i);
+ for( int j=0; j < indent; ++j )
+ os << " ";
+ os << m << "\n";
+ }
+ }
+
+ --indent;
+
+ for( int j=0; j < indent; ++j )
+ os << " ";
+ os << "}";
+
+ return os;
+}
+
+
+std::ostream& operator<<( std::ostream & os, const ReceivedPacket& p )
+{
+ if( p.IsBundle() ){
+ ReceivedBundle b(p);
+ os << b << "\n";
+ }else{
+ ReceivedMessage m(p);
+ os << m << "\n";
+ }
+
+ return os;
+}
+
+} // namespace osc
diff --git a/src/oscpack/OscPrintReceivedElements.h b/src/oscpack/OscPrintReceivedElements.h
new file mode 100644
index 0000000..956524d
--- /dev/null
+++ b/src/oscpack/OscPrintReceivedElements.h
@@ -0,0 +1,49 @@
+/*
+ oscpack -- Open Sound Control packet manipulation library
+ http://www.audiomulch.com/~rossb/oscpack
+
+ Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files
+ (the "Software"), to deal in the Software without restriction,
+ including without limitation the rights to use, copy, modify, merge,
+ publish, distribute, sublicense, and/or sell copies of the Software,
+ and to permit persons to whom the Software is furnished to do so,
+ subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ Any person wishing to distribute modifications to the Software is
+ requested to send the modifications to the original developer so that
+ they can be incorporated into the canonical version.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+#ifndef INCLUDED_OSCPRINTRECEIVEDELEMENTS_H
+#define INCLUDED_OSCPRINTRECEIVEDELEMENTS_H
+
+#include <iosfwd>
+
+#ifndef INCLUDED_OSCRECEIVEDELEMENTS_H
+#include "OscReceivedElements.h"
+#endif /* INCLUDED_OSCRECEIVEDELEMENTS_H */
+
+
+namespace osc{
+
+std::ostream& operator<<( std::ostream & os, const ReceivedPacket& p );
+std::ostream& operator<<( std::ostream & os, const ReceivedMessageArgument& arg );
+std::ostream& operator<<( std::ostream & os, const ReceivedMessage& m );
+std::ostream& operator<<( std::ostream & os, const ReceivedBundle& b );
+
+} // namespace osc
+
+#endif /* INCLUDED_OSCPRINTRECEIVEDELEMENTS_H */
diff --git a/src/oscpack/OscReceivedElements.cpp b/src/oscpack/OscReceivedElements.cpp
new file mode 100644
index 0000000..e28eb55
--- /dev/null
+++ b/src/oscpack/OscReceivedElements.cpp
@@ -0,0 +1,722 @@
+/*
+ oscpack -- Open Sound Control packet manipulation library
+ http://www.audiomulch.com/~rossb/oscpack
+
+ Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files
+ (the "Software"), to deal in the Software without restriction,
+ including without limitation the rights to use, copy, modify, merge,
+ publish, distribute, sublicense, and/or sell copies of the Software,
+ and to permit persons to whom the Software is furnished to do so,
+ subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ Any person wishing to distribute modifications to the Software is
+ requested to send the modifications to the original developer so that
+ they can be incorporated into the canonical version.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+#include "OscReceivedElements.h"
+
+#include <cassert>
+
+#include "OscHostEndianness.h"
+
+
+namespace osc{
+
+
+// return the first 4 byte boundary after the end of a str4
+// be careful about calling this version if you don't know whether
+// the string is terminated correctly.
+static inline const char* FindStr4End( const char *p )
+{
+ if( p[0] == '\0' ) // special case for SuperCollider integer address pattern
+ return p + 4;
+
+ p += 3;
+
+ while( *p )
+ p += 4;
+
+ return p + 1;
+}
+
+
+// return the first 4 byte boundary after the end of a str4
+// returns 0 if p == end or if the string is unterminated
+static inline const char* FindStr4End( const char *p, const char *end )
+{
+ if( p >= end )
+ return 0;
+
+ if( p[0] == '\0' ) // special case for SuperCollider integer address pattern
+ return p + 4;
+
+ p += 3;
+ end -= 1;
+
+ while( p < end && *p )
+ p += 4;
+
+ if( *p )
+ return 0;
+ else
+ return p + 1;
+}
+
+
+static inline unsigned long RoundUp4( unsigned long x )
+{
+ unsigned long remainder = x & 0x3UL;
+ if( remainder )
+ return x + (4 - remainder);
+ else
+ return x;
+}
+
+
+static inline int32 ToInt32( const char *p )
+{
+#ifdef OSC_HOST_LITTLE_ENDIAN
+ union{
+ osc::int32 i;
+ char c[4];
+ } u;
+
+ u.c[0] = p[3];
+ u.c[1] = p[2];
+ u.c[2] = p[1];
+ u.c[3] = p[0];
+
+ return u.i;
+#else
+ return *(int32*)p;
+#endif
+}
+
+
+static inline uint32 ToUInt32( const char *p )
+{
+#ifdef OSC_HOST_LITTLE_ENDIAN
+ union{
+ osc::uint32 i;
+ char c[4];
+ } u;
+
+ u.c[0] = p[3];
+ u.c[1] = p[2];
+ u.c[2] = p[1];
+ u.c[3] = p[0];
+
+ return u.i;
+#else
+ return *(uint32*)p;
+#endif
+}
+
+
+int64 ToInt64( const char *p )
+{
+#ifdef OSC_HOST_LITTLE_ENDIAN
+ union{
+ osc::int64 i;
+ char c[8];
+ } u;
+
+ u.c[0] = p[7];
+ u.c[1] = p[6];
+ u.c[2] = p[5];
+ u.c[3] = p[4];
+ u.c[4] = p[3];
+ u.c[5] = p[2];
+ u.c[6] = p[1];
+ u.c[7] = p[0];
+
+ return u.i;
+#else
+ return *(int64*)p;
+#endif
+}
+
+
+uint64 ToUInt64( const char *p )
+{
+#ifdef OSC_HOST_LITTLE_ENDIAN
+ union{
+ osc::uint64 i;
+ char c[8];
+ } u;
+
+ u.c[0] = p[7];
+ u.c[1] = p[6];
+ u.c[2] = p[5];
+ u.c[3] = p[4];
+ u.c[4] = p[3];
+ u.c[5] = p[2];
+ u.c[6] = p[1];
+ u.c[7] = p[0];
+
+ return u.i;
+#else
+ return *(uint64*)p;
+#endif
+}
+
+//------------------------------------------------------------------------------
+
+bool ReceivedPacket::IsBundle() const
+{
+ return (Size() > 0 && Contents()[0] == '#');
+}
+
+//------------------------------------------------------------------------------
+
+bool ReceivedBundleElement::IsBundle() const
+{
+ return (Size() > 0 && Contents()[0] == '#');
+}
+
+
+int32 ReceivedBundleElement::Size() const
+{
+ return ToUInt32( size_ );
+}
+
+//------------------------------------------------------------------------------
+
+bool ReceivedMessageArgument::AsBool() const
+{
+ if( !typeTag_ )
+ throw MissingArgumentException();
+ else if( *typeTag_ == TRUE_TYPE_TAG )
+ return true;
+ else if( *typeTag_ == FALSE_TYPE_TAG )
+ return false;
+ else
+ throw WrongArgumentTypeException();
+}
+
+
+bool ReceivedMessageArgument::AsBoolUnchecked() const
+{
+ if( !typeTag_ )
+ throw MissingArgumentException();
+ else if( *typeTag_ == TRUE_TYPE_TAG )
+ return true;
+ else
+ return false;
+}
+
+
+int32 ReceivedMessageArgument::AsInt32() const
+{
+ if( !typeTag_ )
+ throw MissingArgumentException();
+ else if( *typeTag_ == INT32_TYPE_TAG )
+ return AsInt32Unchecked();
+ else
+ throw WrongArgumentTypeException();
+}
+
+
+int32 ReceivedMessageArgument::AsInt32Unchecked() const
+{
+#ifdef OSC_HOST_LITTLE_ENDIAN
+ union{
+ osc::int32 i;
+ char c[4];
+ } u;
+
+ u.c[0] = argument_[3];
+ u.c[1] = argument_[2];
+ u.c[2] = argument_[1];
+ u.c[3] = argument_[0];
+
+ return u.i;
+#else
+ return *(int32*)argument_;
+#endif
+}
+
+
+float ReceivedMessageArgument::AsFloat() const
+{
+ if( !typeTag_ )
+ throw MissingArgumentException();
+ else if( *typeTag_ == FLOAT_TYPE_TAG )
+ return AsFloatUnchecked();
+ else
+ throw WrongArgumentTypeException();
+}
+
+
+float ReceivedMessageArgument::AsFloatUnchecked() const
+{
+#ifdef OSC_HOST_LITTLE_ENDIAN
+ union{
+ float f;
+ char c[4];
+ } u;
+
+ u.c[0] = argument_[3];
+ u.c[1] = argument_[2];
+ u.c[2] = argument_[1];
+ u.c[3] = argument_[0];
+
+ return u.f;
+#else
+ return *(float*)argument_;
+#endif
+}
+
+
+char ReceivedMessageArgument::AsChar() const
+{
+ if( !typeTag_ )
+ throw MissingArgumentException();
+ else if( *typeTag_ == CHAR_TYPE_TAG )
+ return AsCharUnchecked();
+ else
+ throw WrongArgumentTypeException();
+}
+
+
+char ReceivedMessageArgument::AsCharUnchecked() const
+{
+ return (char)ToInt32( argument_ );
+}
+
+
+uint32 ReceivedMessageArgument::AsRgbaColor() const
+{
+ if( !typeTag_ )
+ throw MissingArgumentException();
+ else if( *typeTag_ == RGBA_COLOR_TYPE_TAG )
+ return AsRgbaColorUnchecked();
+ else
+ throw WrongArgumentTypeException();
+}
+
+
+uint32 ReceivedMessageArgument::AsRgbaColorUnchecked() const
+{
+ return ToUInt32( argument_ );
+}
+
+
+uint32 ReceivedMessageArgument::AsMidiMessage() const
+{
+ if( !typeTag_ )
+ throw MissingArgumentException();
+ else if( *typeTag_ == MIDI_MESSAGE_TYPE_TAG )
+ return AsMidiMessageUnchecked();
+ else
+ throw WrongArgumentTypeException();
+}
+
+
+uint32 ReceivedMessageArgument::AsMidiMessageUnchecked() const
+{
+ return ToUInt32( argument_ );
+}
+
+
+int64 ReceivedMessageArgument::AsInt64() const
+{
+ if( !typeTag_ )
+ throw MissingArgumentException();
+ else if( *typeTag_ == INT64_TYPE_TAG )
+ return AsInt64Unchecked();
+ else
+ throw WrongArgumentTypeException();
+}
+
+
+int64 ReceivedMessageArgument::AsInt64Unchecked() const
+{
+ return ToInt64( argument_ );
+}
+
+
+uint64 ReceivedMessageArgument::AsTimeTag() const
+{
+ if( !typeTag_ )
+ throw MissingArgumentException();
+ else if( *typeTag_ == TIME_TAG_TYPE_TAG )
+ return AsTimeTagUnchecked();
+ else
+ throw WrongArgumentTypeException();
+}
+
+
+uint64 ReceivedMessageArgument::AsTimeTagUnchecked() const
+{
+ return ToUInt64( argument_ );
+}
+
+
+double ReceivedMessageArgument::AsDouble() const
+{
+ if( !typeTag_ )
+ throw MissingArgumentException();
+ else if( *typeTag_ == DOUBLE_TYPE_TAG )
+ return AsDoubleUnchecked();
+ else
+ throw WrongArgumentTypeException();
+}
+
+
+double ReceivedMessageArgument::AsDoubleUnchecked() const
+{
+#ifdef OSC_HOST_LITTLE_ENDIAN
+ union{
+ double d;
+ char c[8];
+ } u;
+
+ u.c[0] = argument_[7];
+ u.c[1] = argument_[6];
+ u.c[2] = argument_[5];
+ u.c[3] = argument_[4];
+ u.c[4] = argument_[3];
+ u.c[5] = argument_[2];
+ u.c[6] = argument_[1];
+ u.c[7] = argument_[0];
+
+ return u.d;
+#else
+ return *(double*)argument_;
+#endif
+}
+
+
+const char* ReceivedMessageArgument::AsString() const
+{
+ if( !typeTag_ )
+ throw MissingArgumentException();
+ else if( *typeTag_ == STRING_TYPE_TAG )
+ return argument_;
+ else
+ throw WrongArgumentTypeException();
+}
+
+
+const char* ReceivedMessageArgument::AsSymbol() const
+{
+ if( !typeTag_ )
+ throw MissingArgumentException();
+ else if( *typeTag_ == SYMBOL_TYPE_TAG )
+ return argument_;
+ else
+ throw WrongArgumentTypeException();
+}
+
+
+void ReceivedMessageArgument::AsBlob( const void*& data, unsigned long& size ) const
+{
+ if( !typeTag_ )
+ throw MissingArgumentException();
+ else if( *typeTag_ == BLOB_TYPE_TAG )
+ AsBlobUnchecked( data, size );
+ else
+ throw WrongArgumentTypeException();
+}
+
+
+void ReceivedMessageArgument::AsBlobUnchecked( const void*& data, unsigned long& size ) const
+{
+ size = ToUInt32( argument_ );
+ data = (void*)(argument_+4);
+}
+
+//------------------------------------------------------------------------------
+
+void ReceivedMessageArgumentIterator::Advance()
+{
+ if( !value_.typeTag_ )
+ return;
+
+ switch( *value_.typeTag_++ ){
+ case '\0':
+ // don't advance past end
+ --value_.typeTag_;
+ break;
+
+ case TRUE_TYPE_TAG:
+ case FALSE_TYPE_TAG:
+ case NIL_TYPE_TAG:
+ case INFINITUM_TYPE_TAG:
+
+ // zero length
+ break;
+
+ case INT32_TYPE_TAG:
+ case FLOAT_TYPE_TAG:
+ case CHAR_TYPE_TAG:
+ case RGBA_COLOR_TYPE_TAG:
+ case MIDI_MESSAGE_TYPE_TAG:
+
+ value_.argument_ += 4;
+ break;
+
+ case INT64_TYPE_TAG:
+ case TIME_TAG_TYPE_TAG:
+ case DOUBLE_TYPE_TAG:
+
+ value_.argument_ += 8;
+ break;
+
+ case STRING_TYPE_TAG:
+ case SYMBOL_TYPE_TAG:
+
+ // we use the unsafe function FindStr4End(char*) here because all of
+ // the arguments have already been validated in
+ // ReceivedMessage::Init() below.
+
+ value_.argument_ = FindStr4End( value_.argument_ );
+ break;
+
+ case BLOB_TYPE_TAG:
+ {
+ uint32 blobSize = ToUInt32( value_.argument_ );
+ value_.argument_ = value_.argument_ + 4 + RoundUp4( blobSize );
+ }
+ break;
+
+ default: // unknown type tag
+ // don't advance
+ --value_.typeTag_;
+ break;
+
+
+ // not handled:
+ // [ Indicates the beginning of an array. The tags following are for
+ // data in the Array until a close brace tag is reached.
+ // ] Indicates the end of an array.
+ }
+}
+
+//------------------------------------------------------------------------------
+
+ReceivedMessage::ReceivedMessage( const ReceivedPacket& packet )
+ : addressPattern_( packet.Contents() )
+{
+ Init( packet.Contents(), packet.Size() );
+}
+
+
+ReceivedMessage::ReceivedMessage( const ReceivedBundleElement& bundleElement )
+ : addressPattern_( bundleElement.Contents() )
+{
+ Init( bundleElement.Contents(), bundleElement.Size() );
+}
+
+
+bool ReceivedMessage::AddressPatternIsUInt32() const
+{
+ return (addressPattern_[0] == '\0');
+}
+
+
+uint32 ReceivedMessage::AddressPatternAsUInt32() const
+{
+ return ToUInt32( addressPattern_ );
+}
+
+
+void ReceivedMessage::Init( const char *message, unsigned long size )
+{
+ if( size == 0 )
+ throw MalformedMessageException( "zero length messages not permitted" );
+
+ if( (size & 0x03L) != 0 )
+ throw MalformedMessageException( "message size must be multiple of four" );
+
+ const char *end = message + size;
+
+ typeTagsBegin_ = FindStr4End( addressPattern_, end );
+ if( typeTagsBegin_ == 0 ){
+ // address pattern was not terminated before end
+ throw MalformedMessageException( "unterminated address pattern" );
+ }
+
+ if( typeTagsBegin_ == end ){
+ // message consists of only the address pattern - no arguments or type tags.
+ typeTagsBegin_ = 0;
+ typeTagsEnd_ = 0;
+ arguments_ = 0;
+
+ }else{
+ if( *typeTagsBegin_ != ',' )
+ throw MalformedMessageException( "type tags not present" );
+
+ if( *(typeTagsBegin_ + 1) == '\0' ){
+ // zero length type tags
+ typeTagsBegin_ = 0;
+ typeTagsEnd_ = 0;
+ arguments_ = 0;
+
+ }else{
+ // check that all arguments are present and well formed
+
+ arguments_ = FindStr4End( typeTagsBegin_, end );
+ if( arguments_ == 0 ){
+ throw MalformedMessageException( "type tags were not terminated before end of message" );
+ }
+
+ ++typeTagsBegin_; // advance past initial ','
+
+ const char *typeTag = typeTagsBegin_;
+ const char *argument = arguments_;
+
+ do{
+ switch( *typeTag ){
+ case TRUE_TYPE_TAG:
+ case FALSE_TYPE_TAG:
+ case NIL_TYPE_TAG:
+ case INFINITUM_TYPE_TAG:
+
+ // zero length
+ break;
+
+ case INT32_TYPE_TAG:
+ case FLOAT_TYPE_TAG:
+ case CHAR_TYPE_TAG:
+ case RGBA_COLOR_TYPE_TAG:
+ case MIDI_MESSAGE_TYPE_TAG:
+
+ if( argument == end )
+ throw MalformedMessageException( "arguments exceed message size" );
+ argument += 4;
+ if( argument > end )
+ throw MalformedMessageException( "arguments exceed message size" );
+ break;
+
+ case INT64_TYPE_TAG:
+ case TIME_TAG_TYPE_TAG:
+ case DOUBLE_TYPE_TAG:
+
+ if( argument == end )
+ throw MalformedMessageException( "arguments exceed message size" );
+ argument += 8;
+ if( argument > end )
+ throw MalformedMessageException( "arguments exceed message size" );
+ break;
+
+ case STRING_TYPE_TAG:
+ case SYMBOL_TYPE_TAG:
+
+ if( argument == end )
+ throw MalformedMessageException( "arguments exceed message size" );
+ argument = FindStr4End( argument, end );
+ if( argument == 0 )
+ throw MalformedMessageException( "unterminated string argument" );
+ break;
+
+ case BLOB_TYPE_TAG:
+ {
+ if( argument + 4 > end )
+ MalformedMessageException( "arguments exceed message size" );
+
+ uint32 blobSize = ToUInt32( argument );
+ argument = argument + 4 + RoundUp4( blobSize );
+ if( argument > end )
+ MalformedMessageException( "arguments exceed message size" );
+ }
+ break;
+
+ default:
+ throw MalformedMessageException( "unknown type tag" );
+
+ // not handled:
+ // [ Indicates the beginning of an array. The tags following are for
+ // data in the Array until a close brace tag is reached.
+ // ] Indicates the end of an array.
+ }
+
+ }while( *++typeTag != '\0' );
+ typeTagsEnd_ = typeTag;
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+
+ReceivedBundle::ReceivedBundle( const ReceivedPacket& packet )
+ : elementCount_( 0 )
+{
+ Init( packet.Contents(), packet.Size() );
+}
+
+
+ReceivedBundle::ReceivedBundle( const ReceivedBundleElement& bundleElement )
+ : elementCount_( 0 )
+{
+ Init( bundleElement.Contents(), bundleElement.Size() );
+}
+
+
+void ReceivedBundle::Init( const char *bundle, unsigned long size )
+{
+ if( size < 16 )
+ throw MalformedBundleException( "packet too short for bundle" );
+
+ if( (size & 0x03L) != 0 )
+ throw MalformedBundleException( "bundle size must be multiple of four" );
+
+ if( bundle[0] != '#'
+ || bundle[1] != 'b'
+ || bundle[2] != 'u'
+ || bundle[3] != 'n'
+ || bundle[4] != 'd'
+ || bundle[5] != 'l'
+ || bundle[6] != 'e'
+ || bundle[7] != '\0' )
+ throw MalformedBundleException( "bad bundle address pattern" );
+
+ end_ = bundle + size;
+
+ timeTag_ = bundle + 8;
+
+ const char *p = timeTag_ + 8;
+
+ while( p < end_ ){
+ if( p + 4 > end_ )
+ throw MalformedBundleException( "packet too short for elementSize" );
+
+ uint32 elementSize = ToUInt32( p );
+ if( (elementSize & 0x03L) != 0 )
+ throw MalformedBundleException( "bundle element size must be multiple of four" );
+
+ p += 4 + elementSize;
+ if( p > end_ )
+ throw MalformedBundleException( "packet too short for bundle element" );
+
+ ++elementCount_;
+ }
+
+ if( p != end_ )
+ throw MalformedBundleException( "bundle contents " );
+}
+
+
+uint64 ReceivedBundle::TimeTag() const
+{
+ return ToUInt64( timeTag_ );
+}
+
+
+} // namespace osc
+
diff --git a/src/oscpack/OscReceivedElements.h b/src/oscpack/OscReceivedElements.h
new file mode 100644
index 0000000..1a81f6d
--- /dev/null
+++ b/src/oscpack/OscReceivedElements.h
@@ -0,0 +1,486 @@
+/*
+ oscpack -- Open Sound Control packet manipulation library
+ http://www.audiomulch.com/~rossb/oscpack
+
+ Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files
+ (the "Software"), to deal in the Software without restriction,
+ including without limitation the rights to use, copy, modify, merge,
+ publish, distribute, sublicense, and/or sell copies of the Software,
+ and to permit persons to whom the Software is furnished to do so,
+ subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ Any person wishing to distribute modifications to the Software is
+ requested to send the modifications to the original developer so that
+ they can be incorporated into the canonical version.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+#ifndef INCLUDED_OSCRECEIVEDELEMENTS_H
+#define INCLUDED_OSCRECEIVEDELEMENTS_H
+
+#include "OscTypes.h"
+#include "OscException.h"
+
+
+namespace osc{
+
+
+class MalformedMessageException : public Exception{
+public:
+ MalformedMessageException( const char *w="malformed message" )
+ : Exception( w ) {}
+};
+
+class MalformedBundleException : public Exception{
+public:
+ MalformedBundleException( const char *w="malformed bundle" )
+ : Exception( w ) {}
+};
+
+class WrongArgumentTypeException : public Exception{
+public:
+ WrongArgumentTypeException( const char *w="wrong argument type" )
+ : Exception( w ) {}
+};
+
+class MissingArgumentException : public Exception{
+public:
+ MissingArgumentException( const char *w="missing argument" )
+ : Exception( w ) {}
+};
+
+class ExcessArgumentException : public Exception{
+public:
+ ExcessArgumentException( const char *w="too many arguments" )
+ : Exception( w ) {}
+};
+
+
+class ReceivedPacket{
+public:
+ ReceivedPacket( const char *contents, int32 size )
+ : contents_( contents )
+ , size_( size ) {}
+
+ bool IsMessage() const { return !IsBundle(); }
+ bool IsBundle() const;
+
+ int32 Size() const { return size_; }
+ const char *Contents() const { return contents_; }
+
+private:
+ const char *contents_;
+ int32 size_;
+};
+
+
+class ReceivedBundleElement{
+public:
+ ReceivedBundleElement( const char *size )
+ : size_( size ) {}
+
+ friend class ReceivedBundleElementIterator;
+
+ bool IsMessage() const { return !IsBundle(); }
+ bool IsBundle() const;
+
+ int32 Size() const;
+ const char *Contents() const { return size_ + 4; }
+
+private:
+ const char *size_;
+};
+
+
+class ReceivedBundleElementIterator{
+public:
+ ReceivedBundleElementIterator( const char *sizePtr )
+ : value_( sizePtr ) {}
+
+ ReceivedBundleElementIterator operator++()
+ {
+ Advance();
+ return *this;
+ }
+
+ ReceivedBundleElementIterator operator++(int)
+ {
+ ReceivedBundleElementIterator old( *this );
+ Advance();
+ return old;
+ }
+
+ const ReceivedBundleElement& operator*() const { return value_; }
+
+ const ReceivedBundleElement* operator->() const { return &value_; }
+
+ friend bool operator==(const ReceivedBundleElementIterator& lhs,
+ const ReceivedBundleElementIterator& rhs );
+
+private:
+ ReceivedBundleElement value_;
+
+ void Advance() { value_.size_ = value_.Contents() + value_.Size(); }
+
+ bool IsEqualTo( const ReceivedBundleElementIterator& rhs ) const
+ {
+ return value_.size_ == rhs.value_.size_;
+ }
+};
+
+inline bool operator==(const ReceivedBundleElementIterator& lhs,
+ const ReceivedBundleElementIterator& rhs )
+{
+ return lhs.IsEqualTo( rhs );
+}
+
+inline bool operator!=(const ReceivedBundleElementIterator& lhs,
+ const ReceivedBundleElementIterator& rhs )
+{
+ return !( lhs == rhs );
+}
+
+
+class ReceivedMessageArgument{
+public:
+ ReceivedMessageArgument( const char *typeTag, const char *argument )
+ : typeTag_( typeTag )
+ , argument_( argument ) {}
+
+ friend class ReceivedMessageArgumentIterator;
+
+ const char TypeTag() const { return *typeTag_; }
+
+ // the unchecked methods below don't check whether the argument actually
+ // is of the specified type. they should only be used if you've already
+ // checked the type tag or the associated IsType() method.
+
+ bool IsBool() const
+ { return *typeTag_ == TRUE_TYPE_TAG || *typeTag_ == FALSE_TYPE_TAG; }
+ bool AsBool() const;
+ bool AsBoolUnchecked() const;
+
+ bool IsNil() const { return *typeTag_ == NIL_TYPE_TAG; }
+ bool IsInfinitum() const { return *typeTag_ == INFINITUM_TYPE_TAG; }
+
+ bool IsInt32() const { return *typeTag_ == INT32_TYPE_TAG; }
+ int32 AsInt32() const;
+ int32 AsInt32Unchecked() const;
+
+ bool IsFloat() const { return *typeTag_ == FLOAT_TYPE_TAG; }
+ float AsFloat() const;
+ float AsFloatUnchecked() const;
+
+ bool IsChar() const { return *typeTag_ == CHAR_TYPE_TAG; }
+ char AsChar() const;
+ char AsCharUnchecked() const;
+
+ bool IsRgbaColor() const { return *typeTag_ == RGBA_COLOR_TYPE_TAG; }
+ uint32 AsRgbaColor() const;
+ uint32 AsRgbaColorUnchecked() const;
+
+ bool IsMidiMessage() const { return *typeTag_ == MIDI_MESSAGE_TYPE_TAG; }
+ uint32 AsMidiMessage() const;
+ uint32 AsMidiMessageUnchecked() const;
+
+ bool IsInt64() const { return *typeTag_ == INT64_TYPE_TAG; }
+ int64 AsInt64() const;
+ int64 AsInt64Unchecked() const;
+
+ bool IsTimeTag() const { return *typeTag_ == TIME_TAG_TYPE_TAG; }
+ uint64 AsTimeTag() const;
+ uint64 AsTimeTagUnchecked() const;
+
+ bool IsDouble() const { return *typeTag_ == DOUBLE_TYPE_TAG; }
+ double AsDouble() const;
+ double AsDoubleUnchecked() const;
+
+ bool IsString() const { return *typeTag_ == STRING_TYPE_TAG; }
+ const char* AsString() const;
+ const char* AsStringUnchecked() const { return argument_; }
+
+ bool IsSymbol() const { return *typeTag_ == SYMBOL_TYPE_TAG; }
+ const char* AsSymbol() const;
+ const char* AsSymbolUnchecked() const { return argument_; }
+
+ bool IsBlob() const { return *typeTag_ == BLOB_TYPE_TAG; }
+ void AsBlob( const void*& data, unsigned long& size ) const;
+ void AsBlobUnchecked( const void*& data, unsigned long& size ) const;
+
+private:
+ const char *typeTag_;
+ const char *argument_;
+};
+
+
+class ReceivedMessageArgumentIterator{
+public:
+ ReceivedMessageArgumentIterator( const char *typeTags, const char *arguments )
+ : value_( typeTags, arguments ) {}
+
+ ReceivedMessageArgumentIterator operator++()
+ {
+ Advance();
+ return *this;
+ }
+
+ ReceivedMessageArgumentIterator operator++(int)
+ {
+ ReceivedMessageArgumentIterator old( *this );
+ Advance();
+ return old;
+ }
+
+ const ReceivedMessageArgument& operator*() const { return value_; }
+
+ const ReceivedMessageArgument* operator->() const { return &value_; }
+
+ friend bool operator==(const ReceivedMessageArgumentIterator& lhs,
+ const ReceivedMessageArgumentIterator& rhs );
+
+private:
+ ReceivedMessageArgument value_;
+
+ void Advance();
+
+ bool IsEqualTo( const ReceivedMessageArgumentIterator& rhs ) const
+ {
+ return value_.typeTag_ == rhs.value_.typeTag_;
+ }
+};
+
+inline bool operator==(const ReceivedMessageArgumentIterator& lhs,
+ const ReceivedMessageArgumentIterator& rhs )
+{
+ return lhs.IsEqualTo( rhs );
+}
+
+inline bool operator!=(const ReceivedMessageArgumentIterator& lhs,
+ const ReceivedMessageArgumentIterator& rhs )
+{
+ return !( lhs == rhs );
+}
+
+
+class ReceivedMessageArgumentStream{
+ friend class ReceivedMessage;
+ ReceivedMessageArgumentStream( const ReceivedMessageArgumentIterator& begin,
+ const ReceivedMessageArgumentIterator& end )
+ : p_( begin )
+ , end_( end ) {}
+
+ ReceivedMessageArgumentIterator p_, end_;
+
+public:
+
+ // end of stream
+ bool Eos() const { return p_ == end_; }
+
+ ReceivedMessageArgumentStream& operator>>( bool& rhs )
+ {
+ if( Eos() )
+ throw MissingArgumentException();
+
+ rhs = (*p_++).AsBool();
+ return *this;
+ }
+
+ // not sure if it would be useful to stream Nil and Infinitum
+ // for now it's not possible
+
+ ReceivedMessageArgumentStream& operator>>( int32& rhs )
+ {
+ if( Eos() )
+ throw MissingArgumentException();
+
+ rhs = (*p_++).AsInt32();
+ return *this;
+ }
+
+ ReceivedMessageArgumentStream& operator>>( float& rhs )
+ {
+ if( Eos() )
+ throw MissingArgumentException();
+
+ rhs = (*p_++).AsFloat();
+ return *this;
+ }
+
+ ReceivedMessageArgumentStream& operator>>( char& rhs )
+ {
+ if( Eos() )
+ throw MissingArgumentException();
+
+ rhs = (*p_++).AsChar();
+ return *this;
+ }
+
+ ReceivedMessageArgumentStream& operator>>( RgbaColor& rhs )
+ {
+ if( Eos() )
+ throw MissingArgumentException();
+
+ rhs.value = (*p_++).AsRgbaColor();
+ return *this;
+ }
+
+ ReceivedMessageArgumentStream& operator>>( MidiMessage& rhs )
+ {
+ if( Eos() )
+ throw MissingArgumentException();
+
+ rhs.value = (*p_++).AsMidiMessage();
+ return *this;
+ }
+
+ ReceivedMessageArgumentStream& operator>>( int64& rhs )
+ {
+ if( Eos() )
+ throw MissingArgumentException();
+
+ rhs = (*p_++).AsInt64();
+ return *this;
+ }
+
+ ReceivedMessageArgumentStream& operator>>( TimeTag& rhs )
+ {
+ if( Eos() )
+ throw MissingArgumentException();
+
+ rhs.value = (*p_++).AsTimeTag();
+ return *this;
+ }
+
+ ReceivedMessageArgumentStream& operator>>( double& rhs )
+ {
+ if( Eos() )
+ throw MissingArgumentException();
+
+ rhs = (*p_++).AsDouble();
+ return *this;
+ }
+
+ ReceivedMessageArgumentStream& operator>>( Blob& rhs )
+ {
+ if( Eos() )
+ throw MissingArgumentException();
+
+ (*p_++).AsBlob( rhs.data, rhs.size );
+ return *this;
+ }
+
+ ReceivedMessageArgumentStream& operator>>( const char*& rhs )
+ {
+ if( Eos() )
+ throw MissingArgumentException();
+
+ rhs = (*p_++).AsString();
+ return *this;
+ }
+
+ ReceivedMessageArgumentStream& operator>>( Symbol& rhs )
+ {
+ if( Eos() )
+ throw MissingArgumentException();
+
+ rhs.value = (*p_++).AsSymbol();
+ return *this;
+ }
+
+ ReceivedMessageArgumentStream& operator>>( MessageTerminator& rhs )
+ {
+ if( !Eos() )
+ throw ExcessArgumentException();
+
+ return *this;
+ }
+};
+
+
+class ReceivedMessage{
+ void Init( const char *bundle, unsigned long size );
+public:
+ explicit ReceivedMessage( const ReceivedPacket& packet );
+ explicit ReceivedMessage( const ReceivedBundleElement& bundleElement );
+
+ const char *AddressPattern() const { return addressPattern_; }
+
+ // Support for non-standad SuperCollider integer address patterns:
+ bool AddressPatternIsUInt32() const;
+ uint32 AddressPatternAsUInt32() const;
+
+ unsigned long ArgumentCount() const { return static_cast<unsigned long>(typeTagsEnd_ - typeTagsBegin_); }
+
+ const char *TypeTags() const { return typeTagsBegin_; }
+
+
+ typedef ReceivedMessageArgumentIterator const_iterator;
+
+ ReceivedMessageArgumentIterator ArgumentsBegin() const
+ {
+ return ReceivedMessageArgumentIterator( typeTagsBegin_, arguments_ );
+ }
+
+ ReceivedMessageArgumentIterator ArgumentsEnd() const
+ {
+ return ReceivedMessageArgumentIterator( typeTagsEnd_, 0 );
+ }
+
+ ReceivedMessageArgumentStream ArgumentStream() const
+ {
+ return ReceivedMessageArgumentStream( ArgumentsBegin(), ArgumentsEnd() );
+ }
+
+private:
+ const char *addressPattern_;
+ const char *typeTagsBegin_;
+ const char *typeTagsEnd_;
+ const char *arguments_;
+};
+
+
+class ReceivedBundle{
+ void Init( const char *message, unsigned long size );
+public:
+ explicit ReceivedBundle( const ReceivedPacket& packet );
+ explicit ReceivedBundle( const ReceivedBundleElement& bundleElement );
+
+ uint64 TimeTag() const;
+
+ unsigned long ElementCount() const { return elementCount_; }
+
+ typedef ReceivedBundleElementIterator const_iterator;
+
+ ReceivedBundleElementIterator ElementsBegin() const
+ {
+ return ReceivedBundleElementIterator( timeTag_ + 8 );
+ }
+
+ ReceivedBundleElementIterator ElementsEnd() const
+ {
+ return ReceivedBundleElementIterator( end_ );
+ }
+
+private:
+ const char *timeTag_;
+ const char *end_;
+ unsigned long elementCount_;
+};
+
+
+} // namespace osc
+
+
+#endif /* INCLUDED_OSCRECEIVEDELEMENTS_H */
diff --git a/src/oscpack/OscTypes.cpp b/src/oscpack/OscTypes.cpp
new file mode 100644
index 0000000..bb3159d
--- /dev/null
+++ b/src/oscpack/OscTypes.cpp
@@ -0,0 +1,40 @@
+/*
+ oscpack -- Open Sound Control packet manipulation library
+ http://www.audiomulch.com/~rossb/oscpack
+
+ Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files
+ (the "Software"), to deal in the Software without restriction,
+ including without limitation the rights to use, copy, modify, merge,
+ publish, distribute, sublicense, and/or sell copies of the Software,
+ and to permit persons to whom the Software is furnished to do so,
+ subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ Any person wishing to distribute modifications to the Software is
+ requested to send the modifications to the original developer so that
+ they can be incorporated into the canonical version.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+#include "OscTypes.h"
+
+namespace osc{
+
+BundleInitiator BeginBundleImmediate(1);
+BundleTerminator EndBundle;
+MessageTerminator EndMessage;
+NilType Nil;
+InfinitumType Infinitum;
+
+} // namespace osc
diff --git a/src/oscpack/OscTypes.h b/src/oscpack/OscTypes.h
new file mode 100644
index 0000000..0aeebb7
--- /dev/null
+++ b/src/oscpack/OscTypes.h
@@ -0,0 +1,178 @@
+/*
+ oscpack -- Open Sound Control packet manipulation library
+ http://www.audiomulch.com/~rossb/oscpack
+
+ Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files
+ (the "Software"), to deal in the Software without restriction,
+ including without limitation the rights to use, copy, modify, merge,
+ publish, distribute, sublicense, and/or sell copies of the Software,
+ and to permit persons to whom the Software is furnished to do so,
+ subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ Any person wishing to distribute modifications to the Software is
+ requested to send the modifications to the original developer so that
+ they can be incorporated into the canonical version.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+#ifndef INCLUDED_OSCTYPES_H
+#define INCLUDED_OSCTYPES_H
+
+
+namespace osc{
+
+// basic types
+
+#if defined(__BORLANDC__) || defined(_MSC_VER)
+
+typedef __int64 int64;
+typedef unsigned __int64 uint64;
+
+#else
+
+typedef long long int64;
+typedef unsigned long long uint64;
+
+#endif
+
+
+
+#if defined(__x86_64__) || defined(__APPLE__)
+
+typedef signed int int32;
+typedef unsigned int uint32;
+
+#else
+
+typedef signed long int32;
+typedef unsigned long uint32;
+
+#endif
+
+
+
+enum TypeTagValues {
+ TRUE_TYPE_TAG = 'T',
+ FALSE_TYPE_TAG = 'F',
+ NIL_TYPE_TAG = 'N',
+ INFINITUM_TYPE_TAG = 'I',
+ INT32_TYPE_TAG = 'i',
+ FLOAT_TYPE_TAG = 'f',
+ CHAR_TYPE_TAG = 'c',
+ RGBA_COLOR_TYPE_TAG = 'r',
+ MIDI_MESSAGE_TYPE_TAG = 'm',
+ INT64_TYPE_TAG = 'h',
+ TIME_TAG_TYPE_TAG = 't',
+ DOUBLE_TYPE_TAG = 'd',
+ STRING_TYPE_TAG = 's',
+ SYMBOL_TYPE_TAG = 'S',
+ BLOB_TYPE_TAG = 'b'
+};
+
+
+
+// i/o manipulators used for streaming interfaces
+
+struct BundleInitiator{
+ explicit BundleInitiator( uint64 timeTag_ ) : timeTag( timeTag_ ) {}
+ uint64 timeTag;
+};
+
+extern BundleInitiator BeginBundleImmediate;
+
+inline BundleInitiator BeginBundle( uint64 timeTag=1 )
+{
+ return BundleInitiator(timeTag);
+}
+
+
+struct BundleTerminator{
+};
+
+extern BundleTerminator EndBundle;
+
+struct BeginMessage{
+ explicit BeginMessage( const char *addressPattern_ ) : addressPattern( addressPattern_ ) {}
+ const char *addressPattern;
+};
+
+struct MessageTerminator{
+};
+
+extern MessageTerminator EndMessage;
+
+
+// osc specific types. they are defined as structs so they can be used
+// as separately identifiable types with the streaming operators.
+
+struct NilType{
+};
+
+extern NilType Nil;
+
+
+struct InfinitumType{
+};
+
+extern InfinitumType Infinitum;
+
+struct RgbaColor{
+ RgbaColor() {}
+ explicit RgbaColor( uint32 value_ ) : value( value_ ) {}
+ uint32 value;
+
+ operator uint32() const { return value; }
+};
+
+
+struct MidiMessage{
+ MidiMessage() {}
+ explicit MidiMessage( uint32 value_ ) : value( value_ ) {}
+ uint32 value;
+
+ operator uint32() const { return value; }
+};
+
+
+struct TimeTag{
+ TimeTag() {}
+ explicit TimeTag( uint64 value_ ) : value( value_ ) {}
+ uint64 value;
+
+ operator uint64() const { return value; }
+};
+
+
+struct Symbol{
+ Symbol() {}
+ explicit Symbol( const char* value_ ) : value( value_ ) {}
+ const char* value;
+
+ operator const char *() const { return value; }
+};
+
+
+struct Blob{
+ Blob() {}
+ explicit Blob( const void* data_, unsigned long size_ )
+ : data( data_ ), size( size_ ) {}
+ const void* data;
+ unsigned long size;
+};
+
+} // namespace osc
+
+
+#endif /* INCLUDED_OSCTYPES_H */
diff --git a/src/oscpack/PacketListener.h b/src/oscpack/PacketListener.h
new file mode 100644
index 0000000..5c210f3
--- /dev/null
+++ b/src/oscpack/PacketListener.h
@@ -0,0 +1,44 @@
+/*
+ oscpack -- Open Sound Control packet manipulation library
+ http://www.audiomulch.com/~rossb/oscpack
+
+ Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files
+ (the "Software"), to deal in the Software without restriction,
+ including without limitation the rights to use, copy, modify, merge,
+ publish, distribute, sublicense, and/or sell copies of the Software,
+ and to permit persons to whom the Software is furnished to do so,
+ subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ Any person wishing to distribute modifications to the Software is
+ requested to send the modifications to the original developer so that
+ they can be incorporated into the canonical version.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+#ifndef INCLUDED_PACKETLISTENER_H
+#define INCLUDED_PACKETLISTENER_H
+
+#include "../api.h"
+
+class IpEndpointName;
+
+class AVG_API PacketListener{
+public:
+ virtual ~PacketListener() {}
+ virtual void ProcessPacket( const char *data, int size,
+ const IpEndpointName& remoteEndpoint ) = 0;
+};
+
+#endif /* INCLUDED_PACKETLISTENER_H */
diff --git a/src/oscpack/README b/src/oscpack/README
new file mode 100644
index 0000000..61964ce
--- /dev/null
+++ b/src/oscpack/README
@@ -0,0 +1,80 @@
+oscpack -- Open Sound Control packet manipulation library
+http://www.audiomulch.com/~rossb/code/oscpack
+
+Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
+
+A simple C++ library for packing and unpacking OSC packets.
+
+
+Oscpack is simply a set of C++ classes for packing and unpacking OSC packets.
+Oscpack includes a minimal set of UDP networking classes for windows and posix
+which are sufficient for writing many OSC applications and servers, but you are
+encouraged to use another networking framework if it better suits your needs.
+Oscpack is not an OSC application framework, it doesn't include infrastructure for
+constructing or routing OSC namespaces, just classes for easily constructing,
+sending, receiving and parsing OSC packets. The library should also be easy to use
+for other transport methods (eg serial).
+
+The key goals of the oscpack library are:
+
+ - to be a simple and complete implementation of OSC
+ - to be portable to a wide variety of platforms
+ - to allow easy development of robust OSC applications
+ (for example it should be impossible to crash a server
+ by sending it malformed packets, and difficult to
+ create malformed packets.)
+
+Here's a summary of the key files:
+
+osc/OscReceivedElements -- classes for parsing a packet
+osc/OscPrintRecievedElements -- iostream << operators for printing packet elements
+osc/OscOutboundPacket -- a class for packing messages into a packet
+osc/OscPacketListener -- base class for listening to OSC packets on a UdpSocket
+tests/OscUnitTests -- unit test program for the OSC modules
+tests/OscSendTests -- examples of how to send messages
+tests/OscReceiveTest -- example of how to receive the messages sent by OSCSendTests
+examples/OscDump -- a program that prints received OSC packets
+
+
+
+Building
+--------
+
+In general the idea is that you will embed this source code in your projects as you
+see fit. The Makefile has an install rule for building a shared library and
+installing headers in usr/local.
+
+The Makefile works for Linux and MaxOS X except that if you are on a big endian
+machine such as PowerPC Macintosh you need to edit the line which sets the
+endianness to OSC_HOST_BIG_ENDIAN (see the makefile comment for details) or it won't
+work. If you want to build and install liboscpack as a library on OS X you also need
+to edit the $(LIBFILENAME) rule by commenting out the Linux case and uncommenting
+the OS X case since OS X uses different gcc flags for shared libraries.
+
+On Windows there is a batch file for doing a simple test build with MinGW gcc called
+make.MinGW32.bat. This will build the test executables and oscdump in ./bin and run
+the unit tests.
+
+--
+
+
+If you fix anything or write a set of TCP send/recieve classes
+please consider sending me a patch. Thanks :)
+
+For more information about Open Sound Control, see:
+http://www.cnmat.berkeley.edu/OpenSoundControl/
+
+
+Thanks to Till Bovermann for helping with POSIX networking code and
+Mac compatibility, and to Martin Kaltenbrunner and the rest of the
+reacTable team for giving me a reason to finish this library. Thanks
+to Merlijn Blaauw for reviewing the interfaces. Thanks to Xavier Oliver
+for additional help with Linux builds and POSIX implementation details.
+
+Portions developed at the Music Technology Group, Audiovisual Institute,
+University Pompeu Fabra, Barcelona, during my stay as a visiting
+researcher, November 2004 - September 2005.
+
+See the file LICENSE for information about distributing and using this code.
+
+
diff --git a/src/oscpack/TODO b/src/oscpack/TODO
new file mode 100644
index 0000000..309ae68
--- /dev/null
+++ b/src/oscpack/TODO
@@ -0,0 +1,55 @@
+TODO:
+
+ - consider adding the local endpoint name to PacketListener::PacketReceived() params
+
+ - consider adding ListenerThread class to support old seperate thread listener functionality, something like:
+
+ class UdpSocketListenerThread{
+ public:
+ UdpSocketListenerThread( UdpSocket& socket, Listener *listener );
+ UdpSocketListenerThread( UdpSocketReceiveMultiplexer *mux );
+ ~UdpSocketListenerThread();
+
+ void Run();
+ void Stop();
+ };
+
+ - provide some kind of automatic endianness configuration (hopefully there
+ are gcc symbols for this)
+
+ - work out a way to make the parsing classes totally safe. at a minimum this
+ means adding functions to test for invalid float/doublevalues,
+ making sure the iterators never pass the end of the message, ...
+ (passing end of message can happen if:
+ - too many args in type tags
+ a. typetags overflow message size
+ b. args fulfilling typetags overflow message size
+ - strings too long or not terminated correctly
+ - blobs too long or not terminated correctly
+
+ if the message was fully checked during construction, the end() iterator
+ could be moved back until only arguments which fit withing size() may
+ be interated (this could be none). A flag could be set to indicate that
+ something was wrong.
+
+ - other packet badness could include:
+ - time tags too far into the future (the scheduler should deal with
+ that i guess).
+ - message address patterns which aren't correctly terminated
+
+ - improve the ability to parse messages without tags (SC uses methods which
+ get the data and advance the iterator in one step.)
+ - Check* could be modified to do this - ie if typetags are not present
+ it could check that reading the field won't escape the message size
+ and return the data, or return false if some consistency
+ constraint is violated.
+ (or alternately drop support for messages without type tags)
+
+
+ - add a method to discard an inprogress message if it gets half
+ constructed and the buffer is full in OutboundPacket
+
+ - write a stress testing app which can send garbage packets to try to flush out other bugs in the parsing code.
+
+
+
diff --git a/src/oscpack/TimerListener.h b/src/oscpack/TimerListener.h
new file mode 100644
index 0000000..502b321
--- /dev/null
+++ b/src/oscpack/TimerListener.h
@@ -0,0 +1,40 @@
+/*
+ oscpack -- Open Sound Control packet manipulation library
+ http://www.audiomulch.com/~rossb/oscpack
+
+ Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files
+ (the "Software"), to deal in the Software without restriction,
+ including without limitation the rights to use, copy, modify, merge,
+ publish, distribute, sublicense, and/or sell copies of the Software,
+ and to permit persons to whom the Software is furnished to do so,
+ subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ Any person wishing to distribute modifications to the Software is
+ requested to send the modifications to the original developer so that
+ they can be incorporated into the canonical version.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+#ifndef INCLUDED_TIMERLISTENER_H
+#define INCLUDED_TIMERLISTENER_H
+
+
+class TimerListener{
+public:
+ virtual ~TimerListener() {}
+ virtual void TimerExpired() = 0;
+};
+
+#endif /* INCLUDED_TIMERLISTENER_H */
diff --git a/src/oscpack/UdpSocket.cpp b/src/oscpack/UdpSocket.cpp
new file mode 100644
index 0000000..44f266e
--- /dev/null
+++ b/src/oscpack/UdpSocket.cpp
@@ -0,0 +1,1039 @@
+/*
+ oscpack -- Open Sound Control packet manipulation library
+ http://www.audiomulch.com/~rossb/oscpack
+
+ Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files
+ (the "Software"), to deal in the Software without restriction,
+ including without limitation the rights to use, copy, modify, merge,
+ publish, distribute, sublicense, and/or sell copies of the Software,
+ and to permit persons to whom the Software is furnished to do so,
+ subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ Any person wishing to distribute modifications to the Software is
+ requested to send the modifications to the original developer so that
+ they can be incorporated into the canonical version.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+#include "UdpSocket.h"
+
+#ifdef WIN32
+#include <winsock2.h> // this must come first to prevent errors with MSVC7
+#include <windows.h>
+#include <mmsystem.h> // for timeGetTime()
+
+#include <vector>
+#include <algorithm>
+#include <stdexcept>
+#include <assert.h>
+#include <signal.h>
+
+#include "NetworkingUtils.h"
+#include "PacketListener.h"
+#include "TimerListener.h"
+
+
+typedef int socklen_t;
+
+
+static void SockaddrFromIpEndpointName( struct sockaddr_in& sockAddr, const IpEndpointName& endpoint )
+{
+ memset( (char *)&sockAddr, 0, sizeof(sockAddr ) );
+ sockAddr.sin_family = AF_INET;
+
+ sockAddr.sin_addr.s_addr =
+ (endpoint.address == IpEndpointName::ANY_ADDRESS)
+ ? INADDR_ANY
+ : htonl( endpoint.address );
+
+ sockAddr.sin_port =
+ (endpoint.port == IpEndpointName::ANY_PORT)
+ ? (short)0
+ : htons( (short)endpoint.port );
+}
+
+
+static IpEndpointName IpEndpointNameFromSockaddr( const struct sockaddr_in& sockAddr )
+{
+ return IpEndpointName(
+ (sockAddr.sin_addr.s_addr == INADDR_ANY)
+ ? IpEndpointName::ANY_ADDRESS
+ : ntohl( sockAddr.sin_addr.s_addr ),
+ (sockAddr.sin_port == 0)
+ ? IpEndpointName::ANY_PORT
+ : ntohs( sockAddr.sin_port )
+ );
+}
+
+
+class UdpSocket::Implementation{
+ NetworkInitializer networkInitializer_;
+
+ bool isBound_;
+ bool isConnected_;
+
+ SOCKET socket_;
+ struct sockaddr_in connectedAddr_;
+ struct sockaddr_in sendToAddr_;
+
+public:
+
+ Implementation()
+ : isBound_( false )
+ , isConnected_( false )
+ , socket_( INVALID_SOCKET )
+ {
+ if( (socket_ = socket( AF_INET, SOCK_DGRAM, 0 )) == INVALID_SOCKET ){
+ throw std::runtime_error("unable to create udp socket\n");
+ }
+
+ memset( &sendToAddr_, 0, sizeof(sendToAddr_) );
+ sendToAddr_.sin_family = AF_INET;
+ }
+
+ ~Implementation()
+ {
+ if (socket_ != INVALID_SOCKET) closesocket(socket_);
+ }
+
+ IpEndpointName LocalEndpointFor( const IpEndpointName& remoteEndpoint ) const
+ {
+ assert( isBound_ );
+
+ // first connect the socket to the remote server
+
+ struct sockaddr_in connectSockAddr;
+ SockaddrFromIpEndpointName( connectSockAddr, remoteEndpoint );
+
+ if (connect(socket_, (struct sockaddr *)&connectSockAddr, sizeof(connectSockAddr)) < 0) {
+ throw std::runtime_error("unable to connect udp socket\n");
+ }
+
+ // get the address
+
+ struct sockaddr_in sockAddr;
+ memset( (char *)&sockAddr, 0, sizeof(sockAddr ) );
+ socklen_t length = sizeof(sockAddr);
+ if (getsockname(socket_, (struct sockaddr *)&sockAddr, &length) < 0) {
+ throw std::runtime_error("unable to getsockname\n");
+ }
+
+ if( isConnected_ ){
+ // reconnect to the connected address
+
+ if (connect(socket_, (struct sockaddr *)&connectedAddr_, sizeof(connectedAddr_)) < 0) {
+ throw std::runtime_error("unable to connect udp socket\n");
+ }
+
+ }else{
+ // unconnect from the remote address
+
+ struct sockaddr_in unconnectSockAddr;
+ SockaddrFromIpEndpointName( unconnectSockAddr, IpEndpointName() );
+
+ if( connect(socket_, (struct sockaddr *)&unconnectSockAddr, sizeof(unconnectSockAddr)) < 0
+ && WSAGetLastError() != WSAEADDRNOTAVAIL ){
+ throw std::runtime_error("unable to un-connect udp socket\n");
+ }
+ }
+
+ return IpEndpointNameFromSockaddr( sockAddr );
+ }
+
+ void Connect( const IpEndpointName& remoteEndpoint )
+ {
+ SockaddrFromIpEndpointName( connectedAddr_, remoteEndpoint );
+
+ if (connect(socket_, (struct sockaddr *)&connectedAddr_, sizeof(connectedAddr_)) < 0) {
+ throw std::runtime_error("unable to connect udp socket\n");
+ }
+
+ isConnected_ = true;
+ }
+
+ void Send( const char *data, int size )
+ {
+ assert( isConnected_ );
+
+ send( socket_, data, size, 0 );
+ }
+
+ void SendTo( const IpEndpointName& remoteEndpoint, const char *data, int size )
+ {
+ sendToAddr_.sin_addr.s_addr = htonl( remoteEndpoint.address );
+ sendToAddr_.sin_port = htons( (short)remoteEndpoint.port );
+
+ sendto( socket_, data, size, 0, (sockaddr*)&sendToAddr_, sizeof(sendToAddr_) );
+ }
+
+ void Bind( const IpEndpointName& localEndpoint )
+ {
+ struct sockaddr_in bindSockAddr;
+ SockaddrFromIpEndpointName( bindSockAddr, localEndpoint );
+
+ if (bind(socket_, (struct sockaddr *)&bindSockAddr, sizeof(bindSockAddr)) < 0) {
+ throw std::runtime_error("unable to bind udp socket\n");
+ }
+
+ isBound_ = true;
+ }
+
+ bool IsBound() const { return isBound_; }
+
+ int ReceiveFrom( IpEndpointName& remoteEndpoint, char *data, int size )
+ {
+ assert( isBound_ );
+
+ struct sockaddr_in fromAddr;
+ socklen_t fromAddrLen = sizeof(fromAddr);
+
+ int result = recvfrom(socket_, data, size, 0,
+ (struct sockaddr *) &fromAddr, (socklen_t*)&fromAddrLen);
+ if( result < 0 )
+ return 0;
+
+ remoteEndpoint.address = ntohl(fromAddr.sin_addr.s_addr);
+ remoteEndpoint.port = ntohs(fromAddr.sin_port);
+
+ return result;
+ }
+
+ SOCKET& Socket() { return socket_; }
+};
+
+UdpSocket::UdpSocket()
+{
+ impl_ = new Implementation();
+}
+
+UdpSocket::~UdpSocket()
+{
+ delete impl_;
+}
+
+IpEndpointName UdpSocket::LocalEndpointFor( const IpEndpointName& remoteEndpoint ) const
+{
+ return impl_->LocalEndpointFor( remoteEndpoint );
+}
+
+void UdpSocket::Connect( const IpEndpointName& remoteEndpoint )
+{
+ impl_->Connect( remoteEndpoint );
+}
+
+void UdpSocket::Send( const char *data, int size )
+{
+ impl_->Send( data, size );
+}
+
+void UdpSocket::SendTo( const IpEndpointName& remoteEndpoint, const char *data, int size )
+{
+ impl_->SendTo( remoteEndpoint, data, size );
+}
+
+void UdpSocket::Bind( const IpEndpointName& localEndpoint )
+{
+ impl_->Bind( localEndpoint );
+}
+
+bool UdpSocket::IsBound() const
+{
+ return impl_->IsBound();
+}
+
+int UdpSocket::ReceiveFrom( IpEndpointName& remoteEndpoint, char *data, int size )
+{
+ return impl_->ReceiveFrom( remoteEndpoint, data, size );
+}
+
+
+struct AttachedTimerListener{
+ AttachedTimerListener( int id, int p, TimerListener *tl )
+ : initialDelayMs( id )
+ , periodMs( p )
+ , listener( tl ) {}
+ int initialDelayMs;
+ int periodMs;
+ TimerListener *listener;
+};
+
+
+static bool CompareScheduledTimerCalls(
+ const std::pair< double, AttachedTimerListener > & lhs, const std::pair< double, AttachedTimerListener > & rhs )
+{
+ return lhs.first < rhs.first;
+}
+
+
+SocketReceiveMultiplexer *multiplexerInstanceToAbortWithSigInt_ = 0;
+
+extern "C" /*static*/ void InterruptSignalHandler( int );
+/*static*/ void InterruptSignalHandler( int )
+{
+ multiplexerInstanceToAbortWithSigInt_->AsynchronousBreak();
+ signal( SIGINT, SIG_DFL );
+}
+
+
+class SocketReceiveMultiplexer::Implementation{
+ NetworkInitializer networkInitializer_;
+
+ std::vector< std::pair< PacketListener*, UdpSocket* > > socketListeners_;
+ std::vector< AttachedTimerListener > timerListeners_;
+
+ volatile bool break_;
+ HANDLE breakEvent_;
+
+ double GetCurrentTimeMs() const
+ {
+ return timeGetTime(); // FIXME: bad choice if you want to run for more than 40 days
+ }
+
+public:
+ Implementation()
+ {
+ breakEvent_ = CreateEvent( NULL, FALSE, FALSE, NULL );
+ }
+
+ ~Implementation()
+ {
+ CloseHandle( breakEvent_ );
+ }
+
+ void AttachSocketListener( UdpSocket *socket, PacketListener *listener )
+ {
+ assert( std::find( socketListeners_.begin(), socketListeners_.end(), std::make_pair(listener, socket) ) == socketListeners_.end() );
+ // we don't check that the same socket has been added multiple times, even though this is an error
+ socketListeners_.push_back( std::make_pair( listener, socket ) );
+ }
+
+ void DetachSocketListener( UdpSocket *socket, PacketListener *listener )
+ {
+ std::vector< std::pair< PacketListener*, UdpSocket* > >::iterator i =
+ std::find( socketListeners_.begin(), socketListeners_.end(), std::make_pair(listener, socket) );
+ assert( i != socketListeners_.end() );
+
+ socketListeners_.erase( i );
+ }
+
+ void AttachPeriodicTimerListener( int periodMilliseconds, TimerListener *listener )
+ {
+ timerListeners_.push_back( AttachedTimerListener( periodMilliseconds, periodMilliseconds, listener ) );
+ }
+
+ void AttachPeriodicTimerListener( int initialDelayMilliseconds, int periodMilliseconds, TimerListener *listener )
+ {
+ timerListeners_.push_back( AttachedTimerListener( initialDelayMilliseconds, periodMilliseconds, listener ) );
+ }
+
+ void DetachPeriodicTimerListener( TimerListener *listener )
+ {
+ std::vector< AttachedTimerListener >::iterator i = timerListeners_.begin();
+ while( i != timerListeners_.end() ){
+ if( i->listener == listener )
+ break;
+ ++i;
+ }
+
+ assert( i != timerListeners_.end() );
+
+ timerListeners_.erase( i );
+ }
+
+ void Run()
+ {
+ break_ = false;
+
+ // prepare the window events which we use to wake up on incoming data
+ // we use this instead of select() primarily to support the AsyncBreak()
+ // mechanism.
+
+ std::vector<HANDLE> events( socketListeners_.size() + 1, 0 );
+ int j=0;
+ for( std::vector< std::pair< PacketListener*, UdpSocket* > >::iterator i = socketListeners_.begin();
+ i != socketListeners_.end(); ++i, ++j ){
+
+ HANDLE event = CreateEvent( NULL, FALSE, FALSE, NULL );
+ WSAEventSelect( i->second->impl_->Socket(), event, FD_READ ); // note that this makes the socket non-blocking which is why we can safely call RecieveFrom() on all sockets below
+ events[j] = event;
+ }
+
+
+ events[ socketListeners_.size() ] = breakEvent_; // last event in the collection is the break event
+
+
+ // configure the timer queue
+ double currentTimeMs = GetCurrentTimeMs();
+
+ // expiry time ms, listener
+ std::vector< std::pair< double, AttachedTimerListener > > timerQueue_;
+ for( std::vector< AttachedTimerListener >::iterator i = timerListeners_.begin();
+ i != timerListeners_.end(); ++i )
+ timerQueue_.push_back( std::make_pair( currentTimeMs + i->initialDelayMs, *i ) );
+ std::sort( timerQueue_.begin(), timerQueue_.end(), CompareScheduledTimerCalls );
+
+ const int MAX_BUFFER_SIZE = 4098;
+ char *data = new char[ MAX_BUFFER_SIZE ];
+ IpEndpointName remoteEndpoint;
+
+ while( !break_ ){
+
+ double currentTimeMs = GetCurrentTimeMs();
+
+ DWORD waitTime = INFINITE;
+ if( !timerQueue_.empty() ){
+
+ waitTime = (DWORD)( timerQueue_.front().first >= currentTimeMs
+ ? timerQueue_.front().first - currentTimeMs
+ : 0 );
+ }
+
+ DWORD waitResult = WaitForMultipleObjects( (DWORD)socketListeners_.size() + 1, &events[0], FALSE, waitTime );
+ if( break_ )
+ break;
+
+ if( waitResult != WAIT_TIMEOUT ){
+ for( int i = waitResult - WAIT_OBJECT_0; i < (int)socketListeners_.size(); ++i ){
+ int size = socketListeners_[i].second->ReceiveFrom( remoteEndpoint, data, MAX_BUFFER_SIZE );
+ if( size > 0 ){
+ socketListeners_[i].first->ProcessPacket( data, size, remoteEndpoint );
+ if( break_ )
+ break;
+ }
+ }
+ }
+
+ // execute any expired timers
+ currentTimeMs = GetCurrentTimeMs();
+ bool resort = false;
+ for( std::vector< std::pair< double, AttachedTimerListener > >::iterator i = timerQueue_.begin();
+ i != timerQueue_.end() && i->first <= currentTimeMs; ++i ){
+
+ i->second.listener->TimerExpired();
+ if( break_ )
+ break;
+
+ i->first += i->second.periodMs;
+ resort = true;
+ }
+ if( resort )
+ std::sort( timerQueue_.begin(), timerQueue_.end(), CompareScheduledTimerCalls );
+ }
+
+ delete [] data;
+
+ // free events
+ j = 0;
+ for( std::vector< std::pair< PacketListener*, UdpSocket* > >::iterator i = socketListeners_.begin();
+ i != socketListeners_.end(); ++i, ++j ){
+
+ WSAEventSelect( i->second->impl_->Socket(), events[j], 0 ); // remove association between socket and event
+ CloseHandle( events[j] );
+ unsigned long enableNonblocking = 0;
+ ioctlsocket( i->second->impl_->Socket(), FIONBIO, &enableNonblocking ); // make the socket blocking again
+ }
+ }
+
+ void Break()
+ {
+ break_ = true;
+ }
+
+ void AsynchronousBreak()
+ {
+ break_ = true;
+ SetEvent( breakEvent_ );
+ }
+};
+
+
+
+SocketReceiveMultiplexer::SocketReceiveMultiplexer()
+{
+ impl_ = new Implementation();
+}
+
+SocketReceiveMultiplexer::~SocketReceiveMultiplexer()
+{
+ delete impl_;
+}
+
+void SocketReceiveMultiplexer::AttachSocketListener( UdpSocket *socket, PacketListener *listener )
+{
+ impl_->AttachSocketListener( socket, listener );
+}
+
+void SocketReceiveMultiplexer::DetachSocketListener( UdpSocket *socket, PacketListener *listener )
+{
+ impl_->DetachSocketListener( socket, listener );
+}
+
+void SocketReceiveMultiplexer::AttachPeriodicTimerListener( int periodMilliseconds, TimerListener *listener )
+{
+ impl_->AttachPeriodicTimerListener( periodMilliseconds, listener );
+}
+
+void SocketReceiveMultiplexer::AttachPeriodicTimerListener( int initialDelayMilliseconds, int periodMilliseconds, TimerListener *listener )
+{
+ impl_->AttachPeriodicTimerListener( initialDelayMilliseconds, periodMilliseconds, listener );
+}
+
+void SocketReceiveMultiplexer::DetachPeriodicTimerListener( TimerListener *listener )
+{
+ impl_->DetachPeriodicTimerListener( listener );
+}
+
+void SocketReceiveMultiplexer::Run()
+{
+ impl_->Run();
+}
+
+void SocketReceiveMultiplexer::RunUntilSigInt()
+{
+ assert( multiplexerInstanceToAbortWithSigInt_ == 0 ); /* at present we support only one multiplexer instance running until sig int */
+ multiplexerInstanceToAbortWithSigInt_ = this;
+ signal( SIGINT, InterruptSignalHandler );
+ impl_->Run();
+ signal( SIGINT, SIG_DFL );
+ multiplexerInstanceToAbortWithSigInt_ = 0;
+}
+
+void SocketReceiveMultiplexer::Break()
+{
+ impl_->Break();
+}
+
+void SocketReceiveMultiplexer::AsynchronousBreak()
+{
+ impl_->AsynchronousBreak();
+}
+
+#else
+
+#include <vector>
+#include <algorithm>
+#include <stdexcept>
+#include <assert.h>
+#include <signal.h>
+#include <math.h>
+#include <errno.h>
+#include <string.h> // for memset
+
+#include <pthread.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <netdb.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <netinet/in.h> // for sockaddr_in
+
+#include "PacketListener.h"
+#include "TimerListener.h"
+
+
+#if defined(__APPLE__) && !defined(_SOCKLEN_T)
+// pre system 10.3 didn have socklen_t
+typedef ssize_t socklen_t;
+#endif
+
+
+static void SockaddrFromIpEndpointName( struct sockaddr_in& sockAddr, const IpEndpointName& endpoint )
+{
+ memset( (char *)&sockAddr, 0, sizeof(sockAddr ) );
+ sockAddr.sin_family = AF_INET;
+
+ sockAddr.sin_addr.s_addr =
+ (endpoint.address == IpEndpointName::ANY_ADDRESS)
+ ? INADDR_ANY
+ : htonl( endpoint.address );
+
+ sockAddr.sin_port =
+ (endpoint.port == IpEndpointName::ANY_PORT)
+ ? 0
+ : htons( endpoint.port );
+}
+
+
+static IpEndpointName IpEndpointNameFromSockaddr( const struct sockaddr_in& sockAddr )
+{
+ return IpEndpointName(
+ (sockAddr.sin_addr.s_addr == INADDR_ANY)
+ ? IpEndpointName::ANY_ADDRESS
+ : ntohl( sockAddr.sin_addr.s_addr ),
+ (sockAddr.sin_port == 0)
+ ? IpEndpointName::ANY_PORT
+ : ntohs( sockAddr.sin_port )
+ );
+}
+
+
+class UdpSocket::Implementation{
+ bool isBound_;
+ bool isConnected_;
+
+ int socket_;
+ struct sockaddr_in connectedAddr_;
+ struct sockaddr_in sendToAddr_;
+
+public:
+
+ Implementation()
+ : isBound_( false )
+ , isConnected_( false )
+ , socket_( -1 )
+ {
+ if( (socket_ = socket( AF_INET, SOCK_DGRAM, 0 )) == -1 ){
+ throw std::runtime_error("unable to create udp socket\n");
+ }
+
+ memset( &sendToAddr_, 0, sizeof(sendToAddr_) );
+ sendToAddr_.sin_family = AF_INET;
+ }
+
+ ~Implementation()
+ {
+ if (socket_ != -1) close(socket_);
+ }
+
+ IpEndpointName LocalEndpointFor( const IpEndpointName& remoteEndpoint ) const
+ {
+ assert( isBound_ );
+
+ // first connect the socket to the remote server
+
+ struct sockaddr_in connectSockAddr;
+ SockaddrFromIpEndpointName( connectSockAddr, remoteEndpoint );
+
+ if (connect(socket_, (struct sockaddr *)&connectSockAddr, sizeof(connectSockAddr)) < 0) {
+ throw std::runtime_error("unable to connect udp socket\n");
+ }
+
+ // get the address
+
+ struct sockaddr_in sockAddr;
+ memset( (char *)&sockAddr, 0, sizeof(sockAddr ) );
+ socklen_t length = sizeof(sockAddr);
+ if (getsockname(socket_, (struct sockaddr *)&sockAddr, &length) < 0) {
+ throw std::runtime_error("unable to getsockname\n");
+ }
+
+ if( isConnected_ ){
+ // reconnect to the connected address
+
+ if (connect(socket_, (struct sockaddr *)&connectedAddr_, sizeof(connectedAddr_)) < 0) {
+ throw std::runtime_error("unable to connect udp socket\n");
+ }
+
+ }else{
+ // unconnect from the remote address
+
+ struct sockaddr_in unconnectSockAddr;
+ memset( (char *)&unconnectSockAddr, 0, sizeof(unconnectSockAddr ) );
+ unconnectSockAddr.sin_family = AF_UNSPEC;
+ // address fields are zero
+ int connectResult = connect(socket_, (struct sockaddr *)&unconnectSockAddr, sizeof(unconnectSockAddr));
+ if ( connectResult < 0 && errno != EAFNOSUPPORT ) {
+ throw std::runtime_error("unable to un-connect udp socket\n");
+ }
+ }
+
+ return IpEndpointNameFromSockaddr( sockAddr );
+ }
+
+ void Connect( const IpEndpointName& remoteEndpoint )
+ {
+ SockaddrFromIpEndpointName( connectedAddr_, remoteEndpoint );
+
+ if (connect(socket_, (struct sockaddr *)&connectedAddr_, sizeof(connectedAddr_)) < 0) {
+ throw std::runtime_error("unable to connect udp socket\n");
+ }
+
+ isConnected_ = true;
+ }
+
+ void Send( const char *data, int size )
+ {
+ assert( isConnected_ );
+
+ send( socket_, data, size, 0 );
+ }
+
+ void SendTo( const IpEndpointName& remoteEndpoint, const char *data, int size )
+ {
+ sendToAddr_.sin_addr.s_addr = htonl( remoteEndpoint.address );
+ sendToAddr_.sin_port = htons( remoteEndpoint.port );
+
+ sendto( socket_, data, size, 0, (sockaddr*)&sendToAddr_, sizeof(sendToAddr_) );
+ }
+
+ void Bind( const IpEndpointName& localEndpoint )
+ {
+ struct sockaddr_in bindSockAddr;
+ SockaddrFromIpEndpointName( bindSockAddr, localEndpoint );
+
+ if (bind(socket_, (struct sockaddr *)&bindSockAddr, sizeof(bindSockAddr)) < 0) {
+ throw std::runtime_error("unable to bind udp socket\n");
+ }
+
+ isBound_ = true;
+ }
+
+ bool IsBound() const { return isBound_; }
+
+ int ReceiveFrom( IpEndpointName& remoteEndpoint, char *data, int size )
+ {
+ assert( isBound_ );
+
+ struct sockaddr_in fromAddr;
+ socklen_t fromAddrLen = sizeof(fromAddr);
+
+ int result = recvfrom(socket_, data, size, 0,
+ (struct sockaddr *) &fromAddr, (socklen_t*)&fromAddrLen);
+ if( result < 0 )
+ return 0;
+
+ remoteEndpoint.address = ntohl(fromAddr.sin_addr.s_addr);
+ remoteEndpoint.port = ntohs(fromAddr.sin_port);
+
+ return result;
+ }
+
+ int Socket() { return socket_; }
+};
+
+UdpSocket::UdpSocket()
+{
+ impl_ = new Implementation();
+}
+
+UdpSocket::~UdpSocket()
+{
+ delete impl_;
+}
+
+IpEndpointName UdpSocket::LocalEndpointFor( const IpEndpointName& remoteEndpoint ) const
+{
+ return impl_->LocalEndpointFor( remoteEndpoint );
+}
+
+void UdpSocket::Connect( const IpEndpointName& remoteEndpoint )
+{
+ impl_->Connect( remoteEndpoint );
+}
+
+void UdpSocket::Send( const char *data, int size )
+{
+ impl_->Send( data, size );
+}
+
+void UdpSocket::SendTo( const IpEndpointName& remoteEndpoint, const char *data, int size )
+{
+ impl_->SendTo( remoteEndpoint, data, size );
+}
+
+void UdpSocket::Bind( const IpEndpointName& localEndpoint )
+{
+ impl_->Bind( localEndpoint );
+}
+
+bool UdpSocket::IsBound() const
+{
+ return impl_->IsBound();
+}
+
+int UdpSocket::ReceiveFrom( IpEndpointName& remoteEndpoint, char *data, int size )
+{
+ return impl_->ReceiveFrom( remoteEndpoint, data, size );
+}
+
+
+struct AttachedTimerListener{
+ AttachedTimerListener( int id, int p, TimerListener *tl )
+ : initialDelayMs( id )
+ , periodMs( p )
+ , listener( tl ) {}
+ int initialDelayMs;
+ int periodMs;
+ TimerListener *listener;
+};
+
+
+static bool CompareScheduledTimerCalls(
+ const std::pair< double, AttachedTimerListener > & lhs, const std::pair< double, AttachedTimerListener > & rhs )
+{
+ return lhs.first < rhs.first;
+}
+
+
+SocketReceiveMultiplexer *multiplexerInstanceToAbortWithSigInt_ = 0;
+
+extern "C" /*static*/ void InterruptSignalHandler( int );
+/*static*/ void InterruptSignalHandler( int )
+{
+ multiplexerInstanceToAbortWithSigInt_->AsynchronousBreak();
+ signal( SIGINT, SIG_DFL );
+}
+
+
+class SocketReceiveMultiplexer::Implementation{
+ std::vector< std::pair< PacketListener*, UdpSocket* > > socketListeners_;
+ std::vector< AttachedTimerListener > timerListeners_;
+
+ volatile bool break_;
+ int breakPipe_[2]; // [0] is the reader descriptor and [1] the writer
+
+ double GetCurrentTimeMs() const
+ {
+ struct timeval t;
+
+ gettimeofday( &t, 0 );
+
+ return ((double)t.tv_sec*1000.) + ((double)t.tv_usec / 1000.);
+ }
+
+public:
+ Implementation()
+ {
+ if( pipe(breakPipe_) != 0 )
+ throw std::runtime_error( "creation of asynchronous break pipes failed\n" );
+ }
+
+ ~Implementation()
+ {
+ close( breakPipe_[0] );
+ close( breakPipe_[1] );
+ }
+
+ void AttachSocketListener( UdpSocket *socket, PacketListener *listener )
+ {
+ assert( std::find( socketListeners_.begin(), socketListeners_.end(), std::make_pair(listener, socket) ) == socketListeners_.end() );
+ // we don't check that the same socket has been added multiple times, even though this is an error
+ socketListeners_.push_back( std::make_pair( listener, socket ) );
+ }
+
+ void DetachSocketListener( UdpSocket *socket, PacketListener *listener )
+ {
+ std::vector< std::pair< PacketListener*, UdpSocket* > >::iterator i =
+ std::find( socketListeners_.begin(), socketListeners_.end(), std::make_pair(listener, socket) );
+ assert( i != socketListeners_.end() );
+
+ socketListeners_.erase( i );
+ }
+
+ void AttachPeriodicTimerListener( int periodMilliseconds, TimerListener *listener )
+ {
+ timerListeners_.push_back( AttachedTimerListener( periodMilliseconds, periodMilliseconds, listener ) );
+ }
+
+ void AttachPeriodicTimerListener( int initialDelayMilliseconds, int periodMilliseconds, TimerListener *listener )
+ {
+ timerListeners_.push_back( AttachedTimerListener( initialDelayMilliseconds, periodMilliseconds, listener ) );
+ }
+
+ void DetachPeriodicTimerListener( TimerListener *listener )
+ {
+ std::vector< AttachedTimerListener >::iterator i = timerListeners_.begin();
+ while( i != timerListeners_.end() ){
+ if( i->listener == listener )
+ break;
+ ++i;
+ }
+
+ assert( i != timerListeners_.end() );
+
+ timerListeners_.erase( i );
+ }
+
+ void Run()
+ {
+ break_ = false;
+
+ // configure the master fd_set for select()
+
+ fd_set masterfds, tempfds;
+ FD_ZERO( &masterfds );
+ FD_ZERO( &tempfds );
+
+ // in addition to listening to the inbound sockets we
+ // also listen to the asynchronous break pipe, so that AsynchronousBreak()
+ // can break us out of select() from another thread.
+ FD_SET( breakPipe_[0], &masterfds );
+ int fdmax = breakPipe_[0];
+
+ for( std::vector< std::pair< PacketListener*, UdpSocket* > >::iterator i = socketListeners_.begin();
+ i != socketListeners_.end(); ++i ){
+
+ if( fdmax < i->second->impl_->Socket() )
+ fdmax = i->second->impl_->Socket();
+ FD_SET( i->second->impl_->Socket(), &masterfds );
+ }
+
+
+ // configure the timer queue
+ double currentTimeMs = GetCurrentTimeMs();
+
+ // expiry time ms, listener
+ std::vector< std::pair< double, AttachedTimerListener > > timerQueue_;
+ for( std::vector< AttachedTimerListener >::iterator i = timerListeners_.begin();
+ i != timerListeners_.end(); ++i )
+ timerQueue_.push_back( std::make_pair( currentTimeMs + i->initialDelayMs, *i ) );
+ std::sort( timerQueue_.begin(), timerQueue_.end(), CompareScheduledTimerCalls );
+
+ const int MAX_BUFFER_SIZE = 4098;
+ char *data = new char[ MAX_BUFFER_SIZE ];
+ IpEndpointName remoteEndpoint;
+
+ struct timeval timeout;
+
+ while( !break_ ){
+ tempfds = masterfds;
+
+ struct timeval *timeoutPtr = 0;
+ if( !timerQueue_.empty() ){
+ double timeoutMs = timerQueue_.front().first - GetCurrentTimeMs();
+ if( timeoutMs < 0 )
+ timeoutMs = 0;
+
+ // 1000000 microseconds in a second
+ timeout.tv_sec = (long)(timeoutMs * .001);
+ timeout.tv_usec = (long)((timeoutMs - (timeout.tv_sec * 1000)) * 1000);
+ timeoutPtr = &timeout;
+ }
+
+ if( select( fdmax + 1, &tempfds, 0, 0, timeoutPtr ) < 0 && errno != EINTR ){
+ throw std::runtime_error("select failed\n");
+ }
+
+ if ( FD_ISSET( breakPipe_[0], &tempfds ) ){
+ // clear pending data from the asynchronous break pipe
+ char c;
+ if (read( breakPipe_[0], &c, 1 )) {};
+ }
+
+ if( break_ )
+ break;
+
+ for( std::vector< std::pair< PacketListener*, UdpSocket* > >::iterator i = socketListeners_.begin();
+ i != socketListeners_.end(); ++i ){
+
+ if( FD_ISSET( i->second->impl_->Socket(), &tempfds ) ){
+
+ int size = i->second->ReceiveFrom( remoteEndpoint, data, MAX_BUFFER_SIZE );
+ if( size > 0 ){
+ i->first->ProcessPacket( data, size, remoteEndpoint );
+ if( break_ )
+ break;
+ }
+ }
+ }
+
+ // execute any expired timers
+ currentTimeMs = GetCurrentTimeMs();
+ bool resort = false;
+ for( std::vector< std::pair< double, AttachedTimerListener > >::iterator i = timerQueue_.begin();
+ i != timerQueue_.end() && i->first <= currentTimeMs; ++i ){
+
+ i->second.listener->TimerExpired();
+ if( break_ )
+ break;
+
+ i->first += i->second.periodMs;
+ resort = true;
+ }
+ if( resort )
+ std::sort( timerQueue_.begin(), timerQueue_.end(), CompareScheduledTimerCalls );
+ }
+
+ delete [] data;
+ }
+
+ void Break()
+ {
+ break_ = true;
+ }
+
+ void AsynchronousBreak()
+ {
+ break_ = true;
+
+ // Send a termination message to the asynchronous break pipe, so select() will return
+ if (write( breakPipe_[1], "!", 1 )) {};
+ }
+};
+
+
+
+SocketReceiveMultiplexer::SocketReceiveMultiplexer()
+{
+ impl_ = new Implementation();
+}
+
+SocketReceiveMultiplexer::~SocketReceiveMultiplexer()
+{
+ delete impl_;
+}
+
+void SocketReceiveMultiplexer::AttachSocketListener( UdpSocket *socket, PacketListener *listener )
+{
+ impl_->AttachSocketListener( socket, listener );
+}
+
+void SocketReceiveMultiplexer::DetachSocketListener( UdpSocket *socket, PacketListener *listener )
+{
+ impl_->DetachSocketListener( socket, listener );
+}
+
+void SocketReceiveMultiplexer::AttachPeriodicTimerListener( int periodMilliseconds, TimerListener *listener )
+{
+ impl_->AttachPeriodicTimerListener( periodMilliseconds, listener );
+}
+
+void SocketReceiveMultiplexer::AttachPeriodicTimerListener( int initialDelayMilliseconds, int periodMilliseconds, TimerListener *listener )
+{
+ impl_->AttachPeriodicTimerListener( initialDelayMilliseconds, periodMilliseconds, listener );
+}
+
+void SocketReceiveMultiplexer::DetachPeriodicTimerListener( TimerListener *listener )
+{
+ impl_->DetachPeriodicTimerListener( listener );
+}
+
+void SocketReceiveMultiplexer::Run()
+{
+ impl_->Run();
+}
+
+void SocketReceiveMultiplexer::RunUntilSigInt()
+{
+ assert( multiplexerInstanceToAbortWithSigInt_ == 0 ); /* at present we support only one multiplexer instance running until sig int */
+ multiplexerInstanceToAbortWithSigInt_ = this;
+ signal( SIGINT, InterruptSignalHandler );
+ impl_->Run();
+ signal( SIGINT, SIG_DFL );
+ multiplexerInstanceToAbortWithSigInt_ = 0;
+}
+
+void SocketReceiveMultiplexer::Break()
+{
+ impl_->Break();
+}
+
+void SocketReceiveMultiplexer::AsynchronousBreak()
+{
+ impl_->AsynchronousBreak();
+}
+#endif
diff --git a/src/oscpack/UdpSocket.h b/src/oscpack/UdpSocket.h
new file mode 100644
index 0000000..b9ec5db
--- /dev/null
+++ b/src/oscpack/UdpSocket.h
@@ -0,0 +1,158 @@
+/*
+ oscpack -- Open Sound Control packet manipulation library
+ http://www.audiomulch.com/~rossb/oscpack
+
+ Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files
+ (the "Software"), to deal in the Software without restriction,
+ including without limitation the rights to use, copy, modify, merge,
+ publish, distribute, sublicense, and/or sell copies of the Software,
+ and to permit persons to whom the Software is furnished to do so,
+ subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ Any person wishing to distribute modifications to the Software is
+ requested to send the modifications to the original developer so that
+ they can be incorporated into the canonical version.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+#ifndef INCLUDED_UDPSOCKET_H
+#define INCLUDED_UDPSOCKET_H
+
+#ifndef INCLUDED_NETWORKINGUTILITIES_H
+#include "NetworkingUtils.h"
+#endif /* INCLUDED_NETWORKINGUTILITIES_H */
+
+#ifndef INCLUDED_IPENDPOINTNAME_H
+#include "IpEndpointName.h"
+#endif /* INCLUDED_IPENDPOINTNAME_H */
+
+
+class PacketListener;
+class TimerListener;
+
+class UdpSocket;
+
+class SocketReceiveMultiplexer{
+ class Implementation;
+ Implementation *impl_;
+
+ friend class UdpSocket;
+
+public:
+ SocketReceiveMultiplexer();
+ ~SocketReceiveMultiplexer();
+
+ // only call the attach/detach methods _before_ calling Run
+
+ // only one listener per socket, each socket at most once
+ void AttachSocketListener( UdpSocket *socket, PacketListener *listener );
+ void DetachSocketListener( UdpSocket *socket, PacketListener *listener );
+
+ void AttachPeriodicTimerListener( int periodMilliseconds, TimerListener *listener );
+ void AttachPeriodicTimerListener(
+ int initialDelayMilliseconds, int periodMilliseconds, TimerListener *listener );
+ void DetachPeriodicTimerListener( TimerListener *listener );
+
+ void Run(); // loop and block processing messages indefinitely
+ void RunUntilSigInt();
+ void Break(); // call this from a listener to exit once the listener returns
+ void AsynchronousBreak(); // call this from another thread or signal handler to exit the Run() state
+};
+
+
+class UdpSocket{
+ class Implementation;
+ Implementation *impl_;
+
+ friend class SocketReceiveMultiplexer::Implementation;
+
+public:
+
+ // ctor throws std::runtime_error if there's a problem
+ // initializing the socket.
+ UdpSocket();
+ virtual ~UdpSocket();
+
+ // the socket is created in an unbound, unconnected state
+ // such a socket can only be used to send to an arbitrary
+ // address using SendTo(). To use Send() you need to first
+ // connect to a remote endpoint using Connect(). To use
+ // ReceiveFrom you need to first bind to a local endpoint
+ // using Bind().
+
+ // retrieve the local endpoint name when sending to 'to'
+ IpEndpointName LocalEndpointFor( const IpEndpointName& remoteEndpoint ) const;
+
+ // Connect to a remote endpoint which is used as the target
+ // for calls to Send()
+ void Connect( const IpEndpointName& remoteEndpoint );
+ void Send( const char *data, int size );
+ void SendTo( const IpEndpointName& remoteEndpoint, const char *data, int size );
+
+
+ // Bind a local endpoint to receive incoming data. Endpoint
+ // can be 'any' for the system to choose an endpoint
+ void Bind( const IpEndpointName& localEndpoint );
+ bool IsBound() const;
+
+ int ReceiveFrom( IpEndpointName& remoteEndpoint, char *data, int size );
+};
+
+
+// convenience classes for transmitting and receiving
+// they just call Connect and/or Bind in the ctor.
+// note that you can still use a receive socket
+// for transmitting etc
+
+class UdpTransmitSocket : public UdpSocket{
+public:
+ UdpTransmitSocket( const IpEndpointName& remoteEndpoint )
+ { Connect( remoteEndpoint ); }
+};
+
+
+class UdpReceiveSocket : public UdpSocket{
+public:
+ UdpReceiveSocket( const IpEndpointName& localEndpoint )
+ { Bind( localEndpoint ); }
+};
+
+
+// UdpListeningReceiveSocket provides a simple way to bind one listener
+// to a single socket without having to manually set up a SocketReceiveMultiplexer
+
+class UdpListeningReceiveSocket : public UdpSocket{
+ SocketReceiveMultiplexer mux_;
+ PacketListener *listener_;
+public:
+ UdpListeningReceiveSocket( const IpEndpointName& localEndpoint, PacketListener *listener )
+ : listener_( listener )
+ {
+ Bind( localEndpoint );
+ mux_.AttachSocketListener( this, listener_ );
+ }
+
+ ~UdpListeningReceiveSocket()
+ { mux_.DetachSocketListener( this, listener_ ); }
+
+ // see SocketReceiveMultiplexer above for the behaviour of these methods...
+ void Run() { mux_.Run(); }
+ void RunUntilSigInt() { mux_.RunUntilSigInt(); }
+ void Break() { mux_.Break(); }
+ void AsynchronousBreak() { mux_.AsynchronousBreak(); }
+};
+
+
+#endif /* INCLUDED_UDPSOCKET_H */
diff --git a/src/player/AVGNode.cpp b/src/player/AVGNode.cpp
new file mode 100644
index 0000000..e7c94bc
--- /dev/null
+++ b/src/player/AVGNode.cpp
@@ -0,0 +1,53 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "AVGNode.h"
+#include "Player.h"
+
+#include "TypeDefinition.h"
+#include "KeyEvent.h"
+
+#include "../base/FileHelper.h"
+
+#include <iostream>
+
+using namespace std;
+
+namespace avg {
+
+void AVGNode::registerType()
+{
+ TypeDefinition def = TypeDefinition("avg", "canvasbase",
+ ExportedObject::buildObject<AVGNode>);
+ TypeRegistry::get()->registerType(def);
+}
+
+AVGNode::AVGNode(const ArgList& args)
+ : CanvasNode(args)
+{
+ args.setMembers(this);
+}
+
+AVGNode::~AVGNode()
+{
+}
+
+}
diff --git a/src/player/AVGNode.h b/src/player/AVGNode.h
new file mode 100644
index 0000000..fead377
--- /dev/null
+++ b/src/player/AVGNode.h
@@ -0,0 +1,45 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _AVGNode_H_
+#define _AVGNode_H_
+
+#include "../api.h"
+#include "CanvasNode.h"
+
+#include <string>
+
+namespace avg {
+
+class AVG_API AVGNode : public CanvasNode
+{
+ public:
+ static void registerType();
+
+ AVGNode(const ArgList& args);
+ virtual ~AVGNode();
+};
+
+typedef boost::shared_ptr<AVGNode> AVGNodePtr;
+
+}
+
+#endif
diff --git a/src/player/AppleTrackpadInputDevice.cpp b/src/player/AppleTrackpadInputDevice.cpp
new file mode 100644
index 0000000..63059ae
--- /dev/null
+++ b/src/player/AppleTrackpadInputDevice.cpp
@@ -0,0 +1,116 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "AppleTrackpadInputDevice.h"
+#include "TouchEvent.h"
+#include "Player.h"
+#include "AVGNode.h"
+#include "TouchStatus.h"
+
+#include "../base/Logger.h"
+#include "../base/ObjectCounter.h"
+#include "../base/Exception.h"
+
+#include <CoreFoundation/CoreFoundation.h>
+
+using namespace std;
+
+namespace avg {
+
+AppleTrackpadInputDevice* AppleTrackpadInputDevice::s_pInstance(0);
+
+AppleTrackpadInputDevice::AppleTrackpadInputDevice()
+ : m_LastID(0)
+{
+ s_pInstance = this;
+}
+
+AppleTrackpadInputDevice::~AppleTrackpadInputDevice()
+{
+ MTDeviceStop(m_Device);
+ MTUnregisterContactFrameCallback(m_Device, callback);
+ MTDeviceRelease(m_Device);
+ s_pInstance = 0;
+}
+
+void AppleTrackpadInputDevice::start()
+{
+ MultitouchInputDevice::start();
+ m_Device = MTDeviceCreateDefault();
+ MTRegisterContactFrameCallback(m_Device, callback);
+ MTDeviceStart(m_Device, 0);
+ AVG_TRACE(Logger::category::CONFIG, Logger::severity::INFO,
+ "Apple Trackpad Multitouch event source created.");
+}
+
+void AppleTrackpadInputDevice::onData(int device, Finger* pFingers, int numFingers,
+ float timestamp, int frame)
+{
+ lock_guard lock(getMutex());
+ for (int i = 0; i < numFingers; i++) {
+ Finger* pFinger = &pFingers[i];
+ TouchStatusPtr pTouchStatus = getTouchStatus(pFinger->identifier);
+ if (!pTouchStatus) {
+ m_LastID++;
+ TouchEventPtr pEvent = createEvent(m_LastID, pFinger, Event::CURSOR_DOWN);
+ addTouchStatus(pFinger->identifier, pEvent);
+ } else {
+ Event::Type eventType;
+ if (pFinger->state == 7) {
+ eventType = Event::CURSOR_UP;
+ removeTouchStatus(pFinger->identifier);
+ } else {
+ eventType = Event::CURSOR_MOTION;
+ }
+ TouchEventPtr pEvent = createEvent(0, pFinger, eventType);
+ pTouchStatus->pushEvent(pEvent);
+ }
+ }
+}
+
+int AppleTrackpadInputDevice::callback(int device, Finger *data, int nFingers,
+ double timestamp, int frame)
+{
+ AVG_ASSERT(s_pInstance != 0);
+ s_pInstance->onData(device, data, nFingers, timestamp, frame);
+ return 0;
+}
+
+TouchEventPtr AppleTrackpadInputDevice::createEvent(int avgID, Finger* pFinger,
+ Event::Type eventType)
+{
+ glm::vec2 size = getTouchArea();
+ IntPoint pos = getScreenPos(glm::vec2(pFinger->normalized.pos.x,
+ 1-pFinger->normalized.pos.y));
+ glm::vec2 speed(pFinger->normalized.vel.x*size.x, pFinger->normalized.vel.y*size.y);
+ float eccentricity = pFinger->majorAxis/pFinger->minorAxis;
+ glm::vec2 majorAxis = fromPolar(pFinger->angle, pFinger->majorAxis);
+ majorAxis.y = -majorAxis.y;
+ glm::vec2 minorAxis = fromPolar(pFinger->angle+1.57, pFinger->minorAxis);
+ minorAxis.y = -minorAxis.y;
+
+ TouchEventPtr pEvent(new TouchEvent(avgID, eventType, pos, Event::TOUCH,
+ speed, pFinger->angle, pFinger->size, eccentricity, majorAxis,
+ minorAxis));
+ return pEvent;
+}
+
+}
diff --git a/src/player/AppleTrackpadInputDevice.h b/src/player/AppleTrackpadInputDevice.h
new file mode 100644
index 0000000..ce33ce4
--- /dev/null
+++ b/src/player/AppleTrackpadInputDevice.h
@@ -0,0 +1,85 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _AppleTrackpadInputDevice_H_
+#define _AppleTrackpadInputDevice_H_
+
+#include "../api.h"
+#include "MultitouchInputDevice.h"
+#include "Event.h"
+
+extern "C" {
+
+typedef struct { float x,y; } mtPoint;
+typedef struct { mtPoint pos,vel; } mtReadout;
+
+typedef struct {
+ int frame;
+ double timestamp;
+ int identifier, state, foo3, foo4;
+ mtReadout normalized;
+ float size;
+ int zero1;
+ float angle, majorAxis, minorAxis; // ellipsoid
+ mtReadout mm;
+ int zero2[2];
+ float unk2;
+} Finger;
+
+typedef void *MTDeviceRef;
+typedef int (*MTContactCallbackFunction)(int,Finger*,int,double,int);
+
+MTDeviceRef MTDeviceCreateDefault();
+void MTRegisterContactFrameCallback(MTDeviceRef, MTContactCallbackFunction);
+void MTUnregisterContactFrameCallback(MTDeviceRef, MTContactCallbackFunction);
+void MTDeviceStart(MTDeviceRef, int);
+void MTDeviceStop(MTDeviceRef);
+void MTDeviceRelease(MTDeviceRef);
+
+}
+
+namespace avg {
+
+class AVG_API AppleTrackpadInputDevice: public MultitouchInputDevice
+{
+public:
+ AppleTrackpadInputDevice();
+ virtual ~AppleTrackpadInputDevice();
+ virtual void start();
+
+private:
+ void onData(int device, Finger *data, int nFingers, float timestamp, int frame);
+ static int callback(int device, Finger *data, int nFingers, double timestamp,
+ int frame);
+ TouchEventPtr createEvent(int avgID, Finger* pFinger, Event::Type eventType);
+
+ MTDeviceRef m_Device;
+ static AppleTrackpadInputDevice* s_pInstance;
+
+ int m_LastID;
+};
+
+typedef boost::shared_ptr<AppleTrackpadInputDevice> AppleTrackpadInputDevicePtr;
+
+}
+
+#endif
+
diff --git a/src/player/AreaNode.cpp b/src/player/AreaNode.cpp
new file mode 100644
index 0000000..b09f4a6
--- /dev/null
+++ b/src/player/AreaNode.cpp
@@ -0,0 +1,350 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "AreaNode.h"
+
+#include "Event.h"
+#include "CursorEvent.h"
+#include "MouseEvent.h"
+#include "DivNode.h"
+#include "ArgList.h"
+#include "TypeDefinition.h"
+#include "TypeRegistry.h"
+#include "BoostPython.h"
+
+#include "../base/MathHelper.h"
+#include "../base/Logger.h"
+#include "../base/Exception.h"
+#include "../base/ObjectCounter.h"
+
+#include "../graphics/GLContext.h"
+
+#include <object.h>
+#include <compile.h>
+#include <eval.h>
+
+#include <iostream>
+
+using namespace boost;
+
+using namespace std;
+
+namespace avg {
+
+void AreaNode::registerType()
+{
+ TypeDefinition def = TypeDefinition("areanode", "node")
+ .addArg(Arg<float>("x", 0.0, false, offsetof(AreaNode, m_RelViewport.tl.x)))
+ .addArg(Arg<float>("y", 0.0, false, offsetof(AreaNode, m_RelViewport.tl.y)))
+ .addArg(Arg<glm::vec2>("pos", glm::vec2(0.0, 0.0)))
+ .addArg(Arg<float>("width", 0.0, false, offsetof(AreaNode, m_UserSize.x)))
+ .addArg(Arg<float>("height", 0.0, false, offsetof(AreaNode, m_UserSize.y)))
+ .addArg(Arg<glm::vec2>("size", glm::vec2(0.0, 0.0)))
+ .addArg(Arg<float>("angle", 0.0, false, offsetof(AreaNode, m_Angle)))
+ .addArg(Arg<glm::vec2>("pivot", glm::vec2(-32767, -32767), false,
+ offsetof(AreaNode, m_Pivot)))
+ .addArg(Arg<string>("elementoutlinecolor", "", false,
+ offsetof(AreaNode, m_sElementOutlineColor)));
+ TypeRegistry::get()->registerType(def);
+}
+
+AreaNode::AreaNode()
+ : m_RelViewport(0,0,0,0),
+ m_Transform(glm::mat4(0)),
+ m_bTransformChanged(true)
+{
+ ObjectCounter::get()->incRef(&typeid(*this));
+}
+
+AreaNode::~AreaNode()
+{
+ ObjectCounter::get()->decRef(&typeid(*this));
+}
+
+void AreaNode::setArgs(const ArgList& args)
+{
+ Node::setArgs(args);
+ args.getOverlayedArgVal(&m_RelViewport.tl, "pos", "x", "y", getID());
+ args.getOverlayedArgVal(&m_UserSize, "size", "width", "height", getID());
+ m_RelViewport.setWidth(m_UserSize.x);
+ m_RelViewport.setHeight(m_UserSize.y);
+ m_bHasCustomPivot = ((m_Pivot.x != -32767) && (m_Pivot.y != -32767));
+ setElementOutlineColor(m_sElementOutlineColor);
+}
+
+void AreaNode::connectDisplay()
+{
+ IntPoint MediaSize = getMediaSize();
+ if (m_UserSize.x == 0.0) {
+ m_RelViewport.setWidth(float(MediaSize.x));
+ } else {
+ m_RelViewport.setWidth(float(m_UserSize.x));
+ }
+ if (m_UserSize.y == 0.0) {
+ m_RelViewport.setHeight(float(MediaSize.y));
+ } else {
+ m_RelViewport.setHeight(float(m_UserSize.y));
+ }
+ if (m_UserSize.x == 0.0 || m_UserSize.y == 0) {
+ notifySubscribers("SIZE_CHANGED", m_RelViewport.size());
+ }
+ m_bTransformChanged = true;
+ Node::connectDisplay();
+}
+
+float AreaNode::getX() const
+{
+ return m_RelViewport.tl.x;
+}
+
+void AreaNode::setX(float x)
+{
+ setViewport(x, -32767, -32767, -32767);
+}
+
+float AreaNode::getY() const
+{
+ return m_RelViewport.tl.y;
+}
+
+void AreaNode::setY(float y)
+{
+ setViewport(-32767, y, -32767, -32767);
+}
+
+const glm::vec2& AreaNode::getPos() const
+{
+ return m_RelViewport.tl;
+}
+
+void AreaNode::setPos(const glm::vec2& pt)
+{
+ setViewport(pt.x, pt.y, -32767, -32767);
+}
+
+float AreaNode::getWidth() const
+{
+ return getRelViewport().width();
+}
+
+void AreaNode::setWidth(float width)
+{
+ m_UserSize.x = width;
+ setViewport(-32767, -32767, -32767, -32767);
+}
+
+float AreaNode::getHeight() const
+{
+ return getRelViewport().height();
+}
+
+void AreaNode::setHeight(float height)
+{
+ m_UserSize.y = height;
+ setViewport(-32767, -32767, -32767, -32767);
+}
+
+glm::vec2 AreaNode::getSize() const
+{
+ return getRelViewport().size();
+}
+
+void AreaNode::setSize(const glm::vec2& pt)
+{
+ m_UserSize = pt;
+ setViewport(-32767, -32767, -32767, -32767);
+}
+
+float AreaNode::getAngle() const
+{
+ return m_Angle;
+}
+
+void AreaNode::setAngle(float angle)
+{
+ m_Angle = fmod(angle, 2*PI);
+ m_bTransformChanged = true;
+}
+
+glm::vec2 AreaNode::getPivot() const
+{
+ if (m_bHasCustomPivot) {
+ return m_Pivot;
+ } else {
+ return getSize()/2.f;
+ }
+}
+
+void AreaNode::setPivot(const glm::vec2& pt)
+{
+ m_Pivot.x = pt.x;
+ m_Pivot.y = pt.y;
+ m_bHasCustomPivot = true;
+ m_bTransformChanged = true;
+}
+
+const std::string& AreaNode::getElementOutlineColor() const
+{
+ return m_sElementOutlineColor;
+}
+
+void AreaNode::setElementOutlineColor(const std::string& sColor)
+{
+ m_sElementOutlineColor = sColor;
+ if (sColor == "") {
+ m_ElementOutlineColor = Pixel32(0,0,0,0);
+ } else {
+ m_ElementOutlineColor = colorStringToColor(m_sElementOutlineColor);
+ }
+}
+
+glm::vec2 AreaNode::toLocal(const glm::vec2& globalPos) const
+{
+ glm::vec2 localPos = globalPos-m_RelViewport.tl;
+ return getRotatedPivot(localPos, -getAngle(), getPivot());
+}
+
+glm::vec2 AreaNode::toGlobal(const glm::vec2& localPos) const
+{
+ glm::vec2 globalPos = getRotatedPivot(localPos, getAngle(), getPivot());
+ return globalPos+m_RelViewport.tl;
+}
+
+void AreaNode::getElementsByPos(const glm::vec2& pos, vector<NodePtr>& pElements)
+{
+ if (pos.x >= 0 && pos.y >= 0 && pos.x < getSize().x && pos.y < getSize().y &&
+ reactsToMouseEvents())
+ {
+ pElements.push_back(getSharedThis());
+ }
+}
+
+void AreaNode::maybeRender(const glm::mat4& parentTransform)
+{
+ AVG_ASSERT(getState() == NS_CANRENDER);
+ if (isVisible()) {
+ calcTransform();
+ m_Transform = parentTransform*m_LocalTransform;
+ render();
+ }
+}
+
+void AreaNode::renderOutlines(const VertexArrayPtr& pVA, Pixel32 parentColor)
+{
+ Pixel32 effColor = getEffectiveOutlineColor(parentColor);
+ if (effColor != Pixel32(0,0,0,0)) {
+ glm::vec2 size = getSize();
+ glm::vec2 p0 = getAbsPos(glm::vec2(0.5, 0.5));
+ glm::vec2 p1 = getAbsPos(glm::vec2(size.x+0.5,0.5));
+ glm::vec2 p2 = getAbsPos(glm::vec2(size.x+0.5,size.y+0.5));
+ glm::vec2 p3 = getAbsPos(glm::vec2(0.5,size.y+0.5));
+ pVA->addLineData(effColor, p0, p1, 1);
+ pVA->addLineData(effColor, p1, p2, 1);
+ pVA->addLineData(effColor, p2, p3, 1);
+ pVA->addLineData(effColor, p3, p0, 1);
+ }
+}
+
+void AreaNode::setViewport(float x, float y, float width, float height)
+{
+ glm::vec2 oldSize = getRelViewport().size();
+ if (x == -32767) {
+ x = getRelViewport().tl.x;
+ }
+ if (y == -32767) {
+ y = getRelViewport().tl.y;
+ }
+ glm::vec2 mediaSize = glm::vec2(getMediaSize());
+ if (width == -32767) {
+ if (m_UserSize.x == 0.0) {
+ width = mediaSize.x;
+ } else {
+ width = m_UserSize.x;
+ }
+ }
+ if (height == -32767) {
+ if (m_UserSize.y == 0.0) {
+ height = mediaSize.y;
+ } else {
+ height = m_UserSize.y;
+ }
+ }
+ if (width < 0 || height < 0) {
+ throw Exception(AVG_ERR_OUT_OF_RANGE, "Negative size for a node.");
+ }
+ m_RelViewport = FRect(x, y, x+width, y+height);
+ if (oldSize != m_RelViewport.size()) {
+ notifySubscribers("SIZE_CHANGED", m_RelViewport.size());
+ }
+ m_bTransformChanged = true;
+}
+
+const FRect& AreaNode::getRelViewport() const
+{
+// cerr << "Node " << getID() << ": " << m_RelViewport << endl;
+ return m_RelViewport;
+}
+
+string AreaNode::dump(int indent)
+{
+ string dumpStr = Node::dump(indent);
+ char sz[256];
+ sprintf (sz, ", x=%.1f, y=%.1f, width=%.1f, height=%.1f\n",
+ m_RelViewport.tl.x, m_RelViewport.tl.y,
+ m_RelViewport.width(), m_RelViewport.height());
+ dumpStr += sz;
+
+ return dumpStr;
+}
+
+const glm::mat4& AreaNode::getTransform() const
+{
+ return m_Transform;
+}
+
+glm::vec2 AreaNode::getUserSize() const
+{
+ return m_UserSize;
+}
+
+Pixel32 AreaNode::getEffectiveOutlineColor(Pixel32 parentColor) const
+{
+ if (m_ElementOutlineColor == Pixel32(0,0,0,0)) {
+ return parentColor;
+ } else {
+ return m_ElementOutlineColor;
+ }
+}
+
+void AreaNode::calcTransform()
+{
+ if (m_bTransformChanged) {
+ glm::vec3 pos(m_RelViewport.tl.x, m_RelViewport.tl.y, 0);
+ glm::vec3 pivot(getPivot().x, getPivot().y, 0);
+ glm::mat4 transform = glm::translate(glm::mat4(1.0f), pos);
+ transform = glm::translate(transform, pivot);
+ transform = glm::rotate(transform, (180.f/PI)*m_Angle, glm::vec3(0,0,1));
+ m_LocalTransform = glm::translate(transform, -pivot);
+ m_bTransformChanged = false;
+ }
+}
+
+}
diff --git a/src/player/AreaNode.h b/src/player/AreaNode.h
new file mode 100644
index 0000000..7a65c52
--- /dev/null
+++ b/src/player/AreaNode.h
@@ -0,0 +1,132 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _AreaNode_H_
+#define _AreaNode_H_
+
+#include "../api.h"
+
+#include "Node.h"
+
+#include "../base/GLMHelper.h"
+#include "../base/Rect.h"
+
+#include "../graphics/OGLShader.h"
+
+#include <boost/shared_ptr.hpp>
+#include <boost/weak_ptr.hpp>
+
+#include <string>
+#include <map>
+
+namespace avg {
+
+class AreaNode;
+class DivNode;
+class ArgList;
+
+typedef boost::shared_ptr<AreaNode> AreaNodePtr;
+
+class AVG_API AreaNode: public Node
+{
+ public:
+ template<class NodeType>
+ static NodePtr buildNode(const ArgList& args)
+ {
+ return NodePtr(new NodeType(args));
+ }
+ static void registerType();
+
+ virtual ~AreaNode() = 0;
+ virtual void setArgs(const ArgList& args);
+ virtual void connectDisplay();
+
+ float getX() const;
+ void setX(float x);
+
+ float getY() const;
+ void setY(float Y);
+
+ const glm::vec2& getPos() const;
+ void setPos(const glm::vec2& pt);
+
+ virtual float getWidth() const;
+ virtual void setWidth(float width);
+
+ virtual float getHeight() const;
+ virtual void setHeight(float height);
+
+ virtual glm::vec2 getSize() const;
+ virtual void setSize(const glm::vec2& pt);
+
+ float getAngle() const;
+ void setAngle(float angle);
+
+ virtual glm::vec2 getPivot() const;
+ void setPivot(const glm::vec2& pt);
+
+ const std::string& getElementOutlineColor() const;
+ void setElementOutlineColor(const std::string& sColor);
+
+ virtual glm::vec2 toLocal(const glm::vec2& globalPos) const;
+ virtual glm::vec2 toGlobal(const glm::vec2& localPos) const;
+
+ virtual void getElementsByPos(const glm::vec2& pos,
+ std::vector<NodePtr>& pElements);
+
+ virtual void maybeRender(const glm::mat4& parentTransform);
+ virtual void renderOutlines(const VertexArrayPtr& pVA, Pixel32 parentColor);
+ virtual void setViewport(float x, float y, float width, float height);
+ virtual const FRect& getRelViewport() const;
+
+ virtual std::string dump(int indent = 0);
+
+ virtual void checkReload() {};
+
+ virtual IntPoint getMediaSize()
+ { return IntPoint(0,0); };
+ const glm::mat4& getTransform() const;
+
+ protected:
+ AreaNode();
+ glm::vec2 getUserSize() const;
+ Pixel32 getEffectiveOutlineColor(Pixel32 parentColor) const;
+
+ private:
+ void calcTransform();
+
+ FRect m_RelViewport; // In coordinates relative to the parent.
+ float m_Angle;
+ glm::vec2 m_Pivot;
+ bool m_bHasCustomPivot;
+ std::string m_sElementOutlineColor;
+ Pixel32 m_ElementOutlineColor;
+
+ glm::vec2 m_UserSize;
+ glm::mat4 m_Transform;
+ glm::mat4 m_LocalTransform;
+ bool m_bTransformChanged;
+};
+
+}
+
+#endif
+
diff --git a/src/player/Arg.cpp b/src/player/Arg.cpp
new file mode 100644
index 0000000..1518164
--- /dev/null
+++ b/src/player/Arg.cpp
@@ -0,0 +1,47 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+// Original author of this file is Jan Boelsche (regular.gonzales@googlemail.com).
+//
+
+#include "Arg.h"
+#include "FontStyle.h"
+
+#include <string>
+
+using namespace std;
+
+namespace avg {
+// Explicit template instantiation. See Arg.h for comments.
+#ifndef _WIN32
+template class Arg<int>;
+template class Arg<bool>;
+template class Arg<float>;
+template class Arg<string>;
+template class Arg<glm::vec2>;
+template class Arg<glm::vec3>;
+template class Arg<glm::ivec3>;
+template class Arg<std::vector<float> >;
+template class Arg<std::vector<int> >;
+template class Arg<vector<glm::vec2> >;
+template class Arg<vector<glm::ivec3> >;
+template class Arg<FontStyle>;
+#endif
+}
diff --git a/src/player/Arg.h b/src/player/Arg.h
new file mode 100644
index 0000000..be441e3
--- /dev/null
+++ b/src/player/Arg.h
@@ -0,0 +1,119 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+// Original author of this file is Nick Hebner (hebnern@gmail.com).
+//
+
+#ifndef _Arg_H_
+#define _Arg_H_
+
+#include "../api.h"
+#include "../base/GLMHelper.h"
+
+#include "ArgBase.h"
+
+#include <string>
+#include <vector>
+
+namespace avg {
+
+class ExportedObject;
+
+template<class T>
+class AVG_TEMPLATE_API Arg: public ArgBase
+{
+public:
+ Arg(std::string sName, const T& Value, bool bRequired = false,
+ ptrdiff_t MemberOffset = -1);
+ virtual ~Arg();
+
+ void setValue(const T& Value);
+ const T& getValue() const;
+ virtual void setMember(ExportedObject * pObj) const;
+ virtual ArgBase* createCopy() const;
+
+private:
+ T m_Value;
+};
+
+template<class T>
+Arg<T>::Arg(std::string sName, const T& Value, bool bRequired,
+ ptrdiff_t MemberOffset)
+ : ArgBase(sName, bRequired, MemberOffset),
+ m_Value(Value)
+{
+}
+
+template<class T>
+Arg<T>::~Arg()
+{
+}
+
+template<class T>
+const T& Arg<T>::getValue() const
+{
+ return m_Value;
+}
+
+template<class T>
+void Arg<T>::setValue(const T& Value)
+{
+ m_Value = Value;
+ m_bDefault = false;
+}
+
+template<class T>
+void Arg<T>::setMember(ExportedObject * pObj) const
+{
+ if (getMemberOffset() != -1) {
+ T* pMember = (T*)((char*)pObj+getMemberOffset());
+ *pMember = m_Value;
+ }
+}
+
+template<class T>
+ArgBase* Arg<T>::createCopy() const
+{
+ return new Arg<T>(*this);
+}
+
+#ifdef AVG_PLUGIN
+#ifndef _WIN32
+// Under Linux, templates used by plugins need to be instantiated explicitly if
+// RTTI is needed. Templates instantiated implicitly get instantiated again in the
+// plugin with a different typeid.
+extern template class Arg<int>;
+extern template class Arg<bool>;
+extern template class Arg<float>;
+extern template class Arg<std::string>;
+extern template class Arg<glm::vec2>;
+extern template class Arg<glm::vec3>;
+extern template class Arg<glm::ivec3>;
+extern template class Arg<std::vector<float> >;
+extern template class Arg<std::vector<int> >;
+extern template class Arg<std::vector<glm::vec2> >;
+extern template class Arg<std::vector<glm::ivec2> >;
+#endif
+#endif
+
+}
+
+#endif
+
diff --git a/src/player/ArgBase.cpp b/src/player/ArgBase.cpp
new file mode 100644
index 0000000..9409f45
--- /dev/null
+++ b/src/player/ArgBase.cpp
@@ -0,0 +1,66 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+// Original author of this file is Nick Hebner (hebnern@gmail.com).
+//
+
+#include "ArgBase.h"
+
+#include "../base/Exception.h"
+
+#include <stdlib.h>
+
+using namespace std;
+
+namespace avg {
+
+ArgBase::ArgBase(string sName, bool bRequired, ptrdiff_t memberOffset)
+ : m_sName(sName),
+ m_bRequired(bRequired),
+ m_MemberOffset(memberOffset)
+{
+ m_bDefault = true;
+}
+
+ArgBase::~ArgBase()
+{
+}
+
+string ArgBase::getName() const
+{
+ return m_sName;
+}
+
+bool ArgBase::isDefault() const
+{
+ return m_bDefault;
+}
+
+bool ArgBase::isRequired() const
+{
+ return m_bRequired;
+}
+
+ptrdiff_t ArgBase::getMemberOffset() const
+{
+ return m_MemberOffset;
+}
+
+}
diff --git a/src/player/ArgBase.h b/src/player/ArgBase.h
new file mode 100644
index 0000000..fff8969
--- /dev/null
+++ b/src/player/ArgBase.h
@@ -0,0 +1,65 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+// Original author of this file is Nick Hebner (hebnern@gmail.com).
+//
+
+#ifndef _ArgBase_H_
+#define _ArgBase_H_
+
+#include "../api.h"
+
+#include <string>
+
+#include <boost/shared_ptr.hpp>
+
+namespace avg {
+
+class ExportedObject;
+
+class AVG_API ArgBase
+{
+public:
+ ArgBase(std::string sName, bool bRequired, ptrdiff_t memberOffset);
+ virtual ~ArgBase();
+
+ std::string getName() const;
+ bool isDefault() const;
+ bool isRequired() const;
+
+ virtual void setMember(ExportedObject * pObj) const = 0;
+
+ virtual ArgBase* createCopy() const = 0;
+
+protected:
+ ptrdiff_t getMemberOffset() const;
+ bool m_bDefault;
+
+private:
+ std::string m_sName;
+ bool m_bRequired;
+ ptrdiff_t m_MemberOffset;
+};
+
+typedef boost::shared_ptr<ArgBase> ArgBasePtr;
+
+}
+
+#endif
diff --git a/src/player/ArgList.cpp b/src/player/ArgList.cpp
new file mode 100644
index 0000000..5abe78c
--- /dev/null
+++ b/src/player/ArgList.cpp
@@ -0,0 +1,278 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+// Original author of this file is Nick Hebner (hebnern@gmail.com).
+//
+
+#include "ArgList.h"
+
+#include "ExportedObject.h"
+#include "FontStyle.h"
+
+#include "../base/Logger.h"
+#include "../base/Exception.h"
+#include "../base/StringHelper.h"
+#include "../base/UTF8String.h"
+
+#include <sstream>
+
+using namespace std;
+
+namespace avg {
+
+typedef std::vector<std::vector<glm::vec2> > CollVec2Vector;
+
+ArgList::ArgList()
+{
+}
+
+ArgList::ArgList(const ArgList& argTemplates, const xmlNodePtr xmlNode)
+{
+ copyArgsFrom(argTemplates);
+
+ for (xmlAttrPtr prop = xmlNode->properties; prop; prop = prop->next)
+ {
+ string name = (char*)prop->name;
+ string value = (char*)prop->children->content;
+ setArgValue(name, value);
+ }
+}
+
+ArgList::ArgList(const ArgList& argTemplates, const py::dict& PyDict)
+{
+ // TODO: Check if all required args are being set.
+ copyArgsFrom(argTemplates);
+ py::list keys = PyDict.keys();
+ int nKeys = py::len(keys);
+ for (int i = 0; i < nKeys; i++)
+ {
+ py::object keyObj = keys[i];
+ py::object valObj = PyDict[keyObj];
+
+ py::extract<string> keyStrProxy(keyObj);
+ if (!keyStrProxy.check()) {
+ throw Exception(AVG_ERR_INVALID_ARGS, "Argument name must be a string.");
+ }
+ string keyStr = keyStrProxy();
+
+ setArgValue(keyStr, valObj);
+ }
+}
+
+ArgList::~ArgList()
+{
+}
+
+bool ArgList::hasArg(const std::string& sName) const
+{
+ ArgMap::const_iterator it = m_Args.find(sName);
+ return (it != m_Args.end() && !(it->second->isDefault()));
+}
+
+const ArgBasePtr ArgList::getArg(const string& sName) const
+{
+ ArgMap::const_iterator valIt = m_Args.find(sName);
+ if (valIt == m_Args.end()) {
+ // TODO: The error message should mention line number and node type.
+ throw Exception(AVG_ERR_INVALID_ARGS, string("Argument ")+sName+" is not valid.");
+ }
+ return valIt->second;
+}
+
+void ArgList::getOverlayedArgVal(glm::vec2* pResult, const string& sName,
+ const string& sOverlay1, const string& sOverlay2, const string& sID) const
+{
+ if (hasArg(sName)) {
+ if (hasArg(sOverlay1) || hasArg(sOverlay2)) {
+ throw (Exception(AVG_ERR_INVALID_ARGS,
+ string("Duplicate node arguments (")+sName+" and "+
+ sOverlay1+","+sOverlay2+") for node '"+sID+"'"));
+ }
+ *pResult = getArgVal<glm::vec2>(sName);
+ }
+}
+
+const ArgMap& ArgList::getArgMap() const
+{
+ return m_Args;
+}
+
+void ArgList::setArg(const ArgBase& newArg)
+{
+ m_Args[newArg.getName()] = ArgBasePtr(newArg.createCopy());
+}
+
+void ArgList::setArgs(const ArgList& args)
+{
+ for (ArgMap::const_iterator it = args.m_Args.begin(); it != args.m_Args.end(); it++) {
+ m_Args.insert(*it);
+ }
+}
+
+void ArgList::setMembers(ExportedObject * pObj) const
+{
+ for (ArgMap::const_iterator it = m_Args.begin(); it != m_Args.end(); it++) {
+ const ArgBasePtr pCurArg = it->second;
+ pCurArg->setMember(pObj);
+ }
+ pObj->setArgs(*this);
+}
+
+template<class T>
+void setArgValue(Arg<T>* pArg, const std::string & sName, const py::object& value)
+{
+ py::extract<T> valProxy(value);
+ if (!valProxy.check()) {
+ string sTypeName = getFriendlyTypeName(pArg->getValue());
+ throw Exception(AVG_ERR_INVALID_ARGS, "Type error in argument "+sName+": "
+ +sTypeName+" expected.");
+ }
+ pArg->setValue(valProxy());
+}
+
+void ArgList::setArgValue(const std::string & sName, const py::object& value)
+{
+ ArgBasePtr pArg = getArg(sName);
+ Arg<string>* pStringArg = dynamic_cast<Arg<string>* >(&*pArg);
+ Arg<UTF8String>* pUTF8StringArg = dynamic_cast<Arg<UTF8String>* >(&*pArg);
+ Arg<int>* pIntArg = dynamic_cast<Arg<int>* >(&*pArg);
+ Arg<float>* pFloatArg = dynamic_cast<Arg<float>* >(&*pArg);
+ Arg<bool>* pBoolArg = dynamic_cast<Arg<bool>* >(&*pArg);
+ Arg<glm::vec2>* pVec2Arg = dynamic_cast<Arg<glm::vec2>* >(&*pArg);
+ Arg<glm::vec3>* pVec3Arg = dynamic_cast<Arg<glm::vec3>* >(&*pArg);
+ Arg<glm::ivec3>* pIVec3Arg = dynamic_cast<Arg<glm::ivec3>* >(&*pArg);
+ Arg<vector<float> >* pFVectorArg = dynamic_cast<Arg<vector<float> >* >(&*pArg);
+ Arg<vector<int> >* pIVectorArg = dynamic_cast<Arg<vector<int> >* >(&*pArg);
+ Arg<vector<glm::vec2> >* pVec2VectorArg =
+ dynamic_cast<Arg<vector<glm::vec2> >* >(&*pArg);
+ Arg<vector<glm::ivec3> >* pIVec3VectorArg =
+ dynamic_cast<Arg<vector<glm::ivec3> >* >(&*pArg);
+ Arg<CollVec2Vector>* pCollVec2VectorArg =
+ dynamic_cast<Arg<CollVec2Vector>* >(&*pArg);
+ Arg<FontStyle>* pFontStyleArg = dynamic_cast<Arg<FontStyle>* >(&*pArg);
+ Arg<FontStylePtr>* pFontStylePtrArg = dynamic_cast<Arg<FontStylePtr>* >(&*pArg);
+ if(pStringArg) {
+ avg::setArgValue(pStringArg, sName, value);
+ } else if (pUTF8StringArg) {
+ avg::setArgValue(pUTF8StringArg, sName, value);
+ } else if (pIntArg) {
+ avg::setArgValue(pIntArg, sName, value);
+ } else if (pFloatArg) {
+ avg::setArgValue(pFloatArg, sName, value);
+ } else if (pBoolArg) {
+ avg::setArgValue(pBoolArg, sName, value);
+ } else if (pVec2Arg) {
+ avg::setArgValue(pVec2Arg, sName, value);
+ } else if (pVec3Arg) {
+ avg::setArgValue(pVec3Arg, sName, value);
+ } else if (pIVec3Arg) {
+ avg::setArgValue(pIVec3Arg, sName, value);
+ } else if (pFVectorArg) {
+ avg::setArgValue(pFVectorArg, sName, value);
+ } else if (pIVectorArg) {
+ avg::setArgValue(pIVectorArg, sName, value);
+ } else if (pVec2VectorArg) {
+ avg::setArgValue(pVec2VectorArg, sName, value);
+ } else if (pIVec3VectorArg) {
+ avg::setArgValue(pIVec3VectorArg, sName, value);
+ } else if (pCollVec2VectorArg) {
+ avg::setArgValue(pCollVec2VectorArg, sName, value);
+ } else if (pFontStyleArg) {
+ avg::setArgValue(pFontStyleArg, sName, value);
+ } else if (pFontStylePtrArg) {
+ avg::setArgValue(pFontStylePtrArg, sName, value);
+ } else {
+ AVG_ASSERT(false);
+ }
+}
+
+void ArgList::setArgValue(const std::string & sName, const std::string & sValue)
+{
+ ArgBasePtr pArg = getArg(sName);
+ Arg<string>* pStringArg = dynamic_cast<Arg<string>* >(&*pArg);
+ Arg<UTF8String>* pUTF8StringArg = dynamic_cast<Arg<UTF8String>* >(&*pArg);
+ Arg<int>* pIntArg = dynamic_cast<Arg<int>* >(&*pArg);
+ Arg<float>* pFloatArg = dynamic_cast<Arg<float>* >(&*pArg);
+ Arg<bool>* pBoolArg = dynamic_cast<Arg<bool>* >(&*pArg);
+ Arg<glm::vec2>* pVec2Arg = dynamic_cast<Arg<glm::vec2>* >(&*pArg);
+ Arg<glm::vec3>* pVec3Arg = dynamic_cast<Arg<glm::vec3>* >(&*pArg);
+ Arg<glm::ivec3>* pIVec3Arg = dynamic_cast<Arg<glm::ivec3>* >(&*pArg);
+ Arg<vector<float> >* pFVectorArg = dynamic_cast<Arg<vector<float> >* >(&*pArg);
+ Arg<vector<int> >* pIVectorArg = dynamic_cast<Arg<vector<int> >* >(&*pArg);
+ Arg<vector<glm::vec2> >* pVec2VectorArg =
+ dynamic_cast<Arg<vector<glm::vec2> >* >(&*pArg);
+ Arg<vector<glm::ivec3> >* pIVec3VectorArg =
+ dynamic_cast<Arg<vector<glm::ivec3> >* >(&*pArg);
+ Arg<CollVec2Vector>* pCollVec2VectorArg =
+ dynamic_cast<Arg<CollVec2Vector>* >(&*pArg);
+ if (pStringArg) {
+ pStringArg->setValue(sValue);
+ } else if (pUTF8StringArg) {
+ pUTF8StringArg->setValue(sValue);
+ } else if (pIntArg) {
+ pIntArg->setValue(stringToInt(sValue));
+ } else if (pFloatArg) {
+ pFloatArg->setValue(stringToFloat(sValue));
+ } else if (pBoolArg) {
+ pBoolArg->setValue(stringToBool(sValue));
+ } else if (pVec2Arg) {
+ pVec2Arg->setValue(stringToVec2(sValue));
+ } else if (pVec3Arg) {
+ pVec3Arg->setValue(stringToVec3(sValue));
+ } else if (pIVec3Arg) {
+ pIVec3Arg->setValue(stringToIVec3(sValue));
+ } else if (pFVectorArg) {
+ vector<float> v;
+ fromString(sValue, v);
+ pFVectorArg->setValue(v);
+ } else if (pIVectorArg) {
+ vector<int> v;
+ fromString(sValue, v);
+ pIVectorArg->setValue(v);
+ } else if (pVec2VectorArg) {
+ vector<glm::vec2> v;
+ fromString(sValue, v);
+ pVec2VectorArg->setValue(v);
+ } else if (pIVec3VectorArg) {
+ vector<glm::ivec3> v;
+ fromString(sValue, v);
+ pIVec3VectorArg->setValue(v);
+ } else if (pCollVec2VectorArg) {
+ CollVec2Vector v;
+ fromString(sValue, v);
+ pCollVec2VectorArg->setValue(v);
+ } else {
+ AVG_ASSERT(false);
+ }
+}
+
+void ArgList::copyArgsFrom(const ArgList& argTemplates)
+{
+ for (ArgMap::const_iterator it = argTemplates.m_Args.begin();
+ it != argTemplates.m_Args.end(); it++)
+ {
+ string sKey = it->first;
+ ArgBasePtr pArg = ArgBasePtr(it->second->createCopy());
+ m_Args[sKey] = pArg;
+ }
+}
+
+}
+
diff --git a/src/player/ArgList.h b/src/player/ArgList.h
new file mode 100644
index 0000000..5f78114
--- /dev/null
+++ b/src/player/ArgList.h
@@ -0,0 +1,84 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+// Original author of this file is Nick Hebner (hebnern@gmail.com).
+//
+
+#ifndef _ArgList_H_
+#define _ArgList_H_
+
+#include "../api.h"
+
+#include "BoostPython.h"
+#include "Arg.h"
+
+#include <libxml/parser.h>
+
+#include <string>
+#include <map>
+
+namespace avg {
+
+typedef std::map<std::string, ArgBasePtr> ArgMap;
+
+class ExportedObject;
+
+class AVG_API ArgList
+{
+public:
+ ArgList();
+ ArgList(const ArgList& argTemplates, const xmlNodePtr xmlNode);
+ ArgList(const ArgList& argTemplates, const py::dict& PyDict);
+ virtual ~ArgList();
+
+ bool hasArg(const std::string& sName) const;
+ const ArgBasePtr getArg(const std::string& sName) const;
+
+ template<class T>
+ const T& getArgVal(const std::string& sName) const;
+
+ void getOverlayedArgVal(glm::vec2* pResult, const std::string& sName,
+ const std::string& sOverlay1, const std::string& sOverlay2,
+ const std::string& sID) const;
+
+ const ArgMap& getArgMap() const;
+
+ void setArg(const ArgBase& newArg);
+ void setArgs(const ArgList& args);
+ void setMembers(ExportedObject * pObj) const;
+
+ void copyArgsFrom(const ArgList& argTemplates);
+
+private:
+ void setArgValue(const std::string & sName, const py::object& value);
+ void setArgValue(const std::string & sName, const std::string & sValue);
+ ArgMap m_Args;
+};
+
+template<class T>
+const T& ArgList::getArgVal(const std::string& sName) const
+{
+ return (dynamic_cast<Arg<T>* >(&*getArg(sName)))->getValue();
+}
+
+
+}
+
+#endif
diff --git a/src/player/BitmapManager.cpp b/src/player/BitmapManager.cpp
new file mode 100644
index 0000000..6151f1e
--- /dev/null
+++ b/src/player/BitmapManager.cpp
@@ -0,0 +1,147 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "BitmapManager.h"
+#include "IBitmapLoadedListener.h"
+
+#ifdef WIN32
+#include <io.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "../base/OSHelper.h"
+
+using namespace std;
+
+namespace avg {
+
+BitmapManager * BitmapManager::s_pBitmapManager=0;
+
+BitmapManager::BitmapManager()
+{
+ if (s_pBitmapManager) {
+ throw Exception(AVG_ERR_UNKNOWN, "BitmapMananger has already been instantiated.");
+ }
+
+ m_pCmdQueue = BitmapManagerThread::CQueuePtr(new BitmapManagerThread::CQueue);
+ m_pMsgQueue = BitmapManagerMsgQueuePtr(new BitmapManagerMsgQueue(8));
+
+ startThreads(1);
+
+ s_pBitmapManager = this;
+}
+
+BitmapManager::~BitmapManager()
+{
+ while (!m_pCmdQueue->empty()) {
+ m_pCmdQueue->pop();
+ }
+ while (!m_pMsgQueue->empty()) {
+ m_pMsgQueue->pop();
+ }
+ stopThreads();
+ s_pBitmapManager = 0;
+}
+
+BitmapManager* BitmapManager::get()
+{
+ if (!s_pBitmapManager) {
+ s_pBitmapManager = new BitmapManager();
+ }
+ return s_pBitmapManager;
+}
+
+void BitmapManager::loadBitmapPy(const UTF8String& sUtf8FileName,
+ const boost::python::object& pyFunc, PixelFormat pf)
+{
+ std::string sFileName = convertUTF8ToFilename(sUtf8FileName);
+ BitmapManagerMsgPtr pMsg = BitmapManagerMsgPtr(
+ new BitmapManagerMsg(sUtf8FileName, pyFunc, pf));
+ internalLoadBitmap(pMsg);
+}
+
+void BitmapManager::loadBitmap(const UTF8String& sUtf8FileName,
+ IBitmapLoadedListener* pLoadedListener, PixelFormat pf)
+{
+ std::string sFileName = convertUTF8ToFilename(sUtf8FileName);
+ BitmapManagerMsgPtr pMsg = BitmapManagerMsgPtr(
+ new BitmapManagerMsg(sUtf8FileName, pLoadedListener, pf));
+ internalLoadBitmap(pMsg);
+}
+
+void BitmapManager::setNumThreads(int numThreads)
+{
+ stopThreads();
+ startThreads(numThreads);
+}
+
+void BitmapManager::onFrameEnd()
+{
+ while (!m_pMsgQueue->empty()) {
+ BitmapManagerMsgPtr pMsg = m_pMsgQueue->pop();
+ pMsg->executeCallback();
+ }
+}
+
+void BitmapManager::internalLoadBitmap(BitmapManagerMsgPtr pMsg)
+{
+#ifdef WIN32
+ int rc = _access(pMsg->getFilename().c_str(), 04);
+#else
+ int rc = access(pMsg->getFilename().c_str(), R_OK);
+#endif
+
+ if (rc != 0) {
+ pMsg->setError(Exception(AVG_ERR_FILEIO,
+ std::string("BitmapManager can't open output file '") +
+ pMsg->getFilename() + "'. Reason: " +
+ strerror(errno)));
+ m_pMsgQueue->push(pMsg);
+ } else {
+ m_pCmdQueue->pushCmd(boost::bind(&BitmapManagerThread::loadBitmap, _1, pMsg));
+ }
+}
+
+void BitmapManager::startThreads(int numThreads)
+{
+ for (int i=0; i<numThreads; ++i) {
+ boost::thread* pThread = new boost::thread(
+ BitmapManagerThread(*m_pCmdQueue, *m_pMsgQueue));
+ m_pBitmapManagerThreads.push_back(pThread);
+ }
+}
+
+void BitmapManager::stopThreads()
+{
+ int numThreads = m_pBitmapManagerThreads.size();
+ for (int i=0; i<numThreads; ++i) {
+ m_pCmdQueue->pushCmd(boost::bind(&BitmapManagerThread::stop, _1));
+ }
+ for (int i=0; i<numThreads; ++i) {
+ boost::thread* pThread = m_pBitmapManagerThreads[i];
+ pThread->join();
+ delete pThread;
+ }
+ m_pBitmapManagerThreads.clear();
+}
+
+}
diff --git a/src/player/BitmapManager.h b/src/player/BitmapManager.h
new file mode 100644
index 0000000..64f8ba5
--- /dev/null
+++ b/src/player/BitmapManager.h
@@ -0,0 +1,66 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _BitmapManager_H_
+#define _BitmapManager_H_
+
+#include "BitmapManagerThread.h"
+#include "BitmapManagerMsg.h"
+
+#include "../api.h"
+#include "../base/Queue.h"
+#include "../base/IFrameEndListener.h"
+
+#include <boost/thread.hpp>
+
+#include <vector>
+
+namespace avg {
+
+class AVG_API BitmapManager : public IFrameEndListener
+{
+ public:
+ BitmapManager();
+ ~BitmapManager();
+ static BitmapManager* get();
+ void loadBitmapPy(const UTF8String& sUtf8FileName,
+ const boost::python::object& pyFunc, PixelFormat pf=NO_PIXELFORMAT);
+ void loadBitmap(const UTF8String& sUtf8FileName,
+ IBitmapLoadedListener* pLoadedListener, PixelFormat pf=NO_PIXELFORMAT);
+ void setNumThreads(int numThreads);
+
+ virtual void onFrameEnd();
+
+ private:
+ void internalLoadBitmap(BitmapManagerMsgPtr pMsg);
+ void startThreads(int numThreads);
+ void stopThreads();
+
+ static BitmapManager * s_pBitmapManager;
+
+ std::vector<boost::thread*> m_pBitmapManagerThreads;
+ BitmapManagerThread::CQueuePtr m_pCmdQueue;
+ BitmapManagerMsgQueuePtr m_pMsgQueue;
+};
+
+}
+
+#endif
diff --git a/src/player/BitmapManagerMsg.cpp b/src/player/BitmapManagerMsg.cpp
new file mode 100644
index 0000000..f9dfc53
--- /dev/null
+++ b/src/player/BitmapManagerMsg.cpp
@@ -0,0 +1,121 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "BitmapManagerMsg.h"
+#include "IBitmapLoadedListener.h"
+
+#include "../base/ObjectCounter.h"
+#include "../base/Exception.h"
+#include "../base/TimeSource.h"
+
+
+namespace avg {
+
+BitmapManagerMsg::BitmapManagerMsg(const UTF8String& sFilename,
+ const boost::python::object& onLoadedCb, PixelFormat pf)
+{
+ ObjectCounter::get()->incRef(&typeid(*this));
+ init(sFilename, pf);
+ m_OnLoadedCb = onLoadedCb;
+ m_pLoadedListener = 0;
+}
+
+BitmapManagerMsg::BitmapManagerMsg(const UTF8String& sFilename,
+ IBitmapLoadedListener* pLoadedListener, PixelFormat pf)
+{
+ ObjectCounter::get()->incRef(&typeid(*this));
+ init(sFilename, pf);
+ m_OnLoadedCb = boost::python::object();
+ m_pLoadedListener = pLoadedListener;
+}
+
+BitmapManagerMsg::~BitmapManagerMsg()
+{
+ if (m_pEx) {
+ delete m_pEx;
+ }
+ ObjectCounter::get()->decRef(&typeid(*this));
+}
+
+void BitmapManagerMsg::init(const UTF8String& sFilename, PixelFormat pf)
+{
+ m_sFilename = sFilename;
+ m_StartTime = TimeSource::get()->getCurrentMicrosecs()/1000.0f;
+ m_PF = pf;
+ m_MsgType = REQUEST;
+ m_pEx = 0;
+}
+
+void BitmapManagerMsg::executeCallback()
+{
+ switch (m_MsgType) {
+ case BITMAP:
+ if (m_pLoadedListener) {
+ m_pLoadedListener->onBitmapLoaded(m_pBmp);
+ } else {
+ boost::python::call<void>(m_OnLoadedCb.ptr(), m_pBmp);
+ }
+ break;
+ case ERROR:
+ if (m_pLoadedListener) {
+ m_pLoadedListener->onBitmapLoadError(m_pEx);
+ } else {
+ boost::python::call<void>(m_OnLoadedCb.ptr(), m_pEx);
+ }
+ break;
+
+ default:
+ AVG_ASSERT(false);
+ }
+}
+
+const UTF8String BitmapManagerMsg::getFilename()
+{
+ return m_sFilename;
+}
+
+float BitmapManagerMsg::getStartTime()
+{
+ AVG_ASSERT(m_MsgType == REQUEST);
+ return m_StartTime;
+}
+
+PixelFormat BitmapManagerMsg::getPixelFormat()
+{
+ AVG_ASSERT(m_MsgType == REQUEST);
+ return m_PF;
+}
+
+void BitmapManagerMsg::setBitmap(BitmapPtr pBmp)
+{
+ AVG_ASSERT(m_MsgType == REQUEST);
+ m_pBmp = pBmp;
+ m_MsgType = BITMAP;
+}
+
+void BitmapManagerMsg::setError(const Exception& ex)
+{
+ AVG_ASSERT(m_MsgType == REQUEST);
+ m_MsgType = ERROR;
+ m_pEx = new Exception(ex);
+}
+
+}
diff --git a/src/player/BitmapManagerMsg.h b/src/player/BitmapManagerMsg.h
new file mode 100644
index 0000000..47ba785
--- /dev/null
+++ b/src/player/BitmapManagerMsg.h
@@ -0,0 +1,76 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _BitmapManagerMsg_H_
+#define _BitmapManagerMsg_H_
+
+#include "WrapPython.h"
+
+#include "../api.h"
+#include "../base/Queue.h"
+#include "../graphics/Bitmap.h"
+
+#include <boost/shared_ptr.hpp>
+#include <boost/python.hpp>
+
+
+namespace avg {
+
+class IBitmapLoadedListener;
+
+class AVG_API BitmapManagerMsg
+{
+public:
+ enum MsgType {REQUEST, BITMAP, ERROR};
+
+ BitmapManagerMsg(const UTF8String& sFilename,
+ const boost::python::object& onLoadedCb, PixelFormat pf);
+ BitmapManagerMsg(const UTF8String& sFilename,
+ IBitmapLoadedListener* pLoadedListener, PixelFormat pf);
+ virtual ~BitmapManagerMsg();
+ void init(const UTF8String& sFilename, PixelFormat pf);
+
+ void executeCallback();
+ const UTF8String getFilename();
+ float getStartTime();
+ PixelFormat getPixelFormat();
+ void setBitmap(BitmapPtr pBmp);
+ void setError(const Exception& ex);
+
+ MsgType getType() { return m_MsgType; };
+
+private:
+ UTF8String m_sFilename;
+ float m_StartTime;
+ BitmapPtr m_pBmp;
+ boost::python::object m_OnLoadedCb;
+ IBitmapLoadedListener* m_pLoadedListener;
+ PixelFormat m_PF;
+ MsgType m_MsgType;
+ Exception* m_pEx;
+};
+
+typedef boost::shared_ptr<BitmapManagerMsg> BitmapManagerMsgPtr;
+typedef Queue<BitmapManagerMsg> BitmapManagerMsgQueue;
+typedef boost::shared_ptr<BitmapManagerMsgQueue> BitmapManagerMsgQueuePtr;
+}
+
+#endif
diff --git a/src/player/BitmapManagerThread.cpp b/src/player/BitmapManagerThread.cpp
new file mode 100644
index 0000000..42372a6
--- /dev/null
+++ b/src/player/BitmapManagerThread.cpp
@@ -0,0 +1,78 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "BitmapManagerThread.h"
+
+#include "../base/Exception.h"
+#include "../base/ScopeTimer.h"
+#include "../base/TimeSource.h"
+
+#include "../graphics/BitmapLoader.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+namespace avg {
+
+BitmapManagerThread::BitmapManagerThread(CQueue& cmdQ, BitmapManagerMsgQueue& MsgQueue)
+ : WorkerThread<BitmapManagerThread>("BitmapManager", cmdQ),
+ m_MsgQueue(MsgQueue),
+ m_TotalLatency(0),
+ m_NumBmpsLoaded(0)
+{
+}
+
+bool BitmapManagerThread::work()
+{
+ waitForCommand();
+ return true;
+}
+
+void BitmapManagerThread::deinit()
+{
+ if (m_NumBmpsLoaded > 0) {
+ AVG_TRACE(Logger::category::PROFILE, Logger::severity::INFO,
+ "Average latency for async bitmap loads: " << m_TotalLatency/m_NumBmpsLoaded
+ << " ms");
+ }
+}
+
+static ProfilingZoneID LoaderProfilingZone("loadBitmap", true);
+
+void BitmapManagerThread::loadBitmap(BitmapManagerMsgPtr pRequest)
+{
+ BitmapPtr pBmp;
+ ScopeTimer timer(LoaderProfilingZone);
+ float startTime = pRequest->getStartTime();
+ try {
+ pBmp = avg::loadBitmap(pRequest->getFilename(), pRequest->getPixelFormat());
+ pRequest->setBitmap(pBmp);
+ } catch (const Exception& ex) {
+ pRequest->setError(ex);
+ }
+ m_MsgQueue.push(pRequest);
+ m_NumBmpsLoaded++;
+ float curLatency = TimeSource::get()->getCurrentMicrosecs()/1000 - startTime;
+ m_TotalLatency += curLatency;
+ ThreadProfiler::get()->reset();
+}
+
+}
diff --git a/src/player/BitmapManagerThread.h b/src/player/BitmapManagerThread.h
new file mode 100644
index 0000000..fbc5c56
--- /dev/null
+++ b/src/player/BitmapManagerThread.h
@@ -0,0 +1,55 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _BitmapManagerThread_H_
+#define _BitmapManagerThread_H_
+
+#include "../api.h"
+
+#include "BitmapManagerMsg.h"
+
+#include "../base/WorkerThread.h"
+#include "../graphics/Bitmap.h"
+
+#include <boost/thread.hpp>
+
+
+namespace avg {
+
+class AVG_API BitmapManagerThread : public WorkerThread<BitmapManagerThread>
+{
+ public:
+ BitmapManagerThread(CQueue& cmdQ, BitmapManagerMsgQueue& MsgQueue);
+
+ void loadBitmap(BitmapManagerMsgPtr pRequest);
+
+ private:
+ virtual bool work();
+ virtual void deinit();
+ BitmapManagerMsgQueue& m_MsgQueue;
+
+ float m_TotalLatency;
+ int m_NumBmpsLoaded;
+};
+
+}
+
+#endif
diff --git a/src/player/BlurFXNode.cpp b/src/player/BlurFXNode.cpp
new file mode 100644
index 0000000..16583a8
--- /dev/null
+++ b/src/player/BlurFXNode.cpp
@@ -0,0 +1,79 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "BlurFXNode.h"
+
+#include "../base/ObjectCounter.h"
+#include "../base/Exception.h"
+
+#include <string>
+
+using namespace std;
+
+namespace avg {
+
+BlurFXNode::BlurFXNode(float radius)
+ : FXNode(false),
+ m_StdDev(radius)
+{
+ ObjectCounter::get()->incRef(&typeid(*this));
+}
+
+BlurFXNode::~BlurFXNode()
+{
+ ObjectCounter::get()->decRef(&typeid(*this));
+}
+
+void BlurFXNode::connect()
+{
+ setDirty();
+ FXNode::connect();
+}
+
+void BlurFXNode::disconnect()
+{
+ m_pFilter = GPUBlurFilterPtr();
+ FXNode::disconnect();
+}
+
+void BlurFXNode::setRadius(float stdDev)
+{
+ m_StdDev = stdDev;
+ if (m_pFilter) {
+ m_pFilter->setStdDev(stdDev);
+ }
+ setDirty();
+}
+
+float BlurFXNode::getRadius() const
+{
+ return m_StdDev;
+}
+
+GPUFilterPtr BlurFXNode::createFilter(const IntPoint& size)
+{
+ m_pFilter = GPUBlurFilterPtr(new GPUBlurFilter(size, B8G8R8A8, B8G8R8A8, m_StdDev,
+ false, false));
+ return m_pFilter;
+}
+
+}
+
diff --git a/src/player/BlurFXNode.h b/src/player/BlurFXNode.h
new file mode 100644
index 0000000..24b5f8c
--- /dev/null
+++ b/src/player/BlurFXNode.h
@@ -0,0 +1,58 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _BlurFXNode_H_
+#define _BlurFXNode_H_
+
+#include "../api.h"
+
+#include "FXNode.h"
+#include "../graphics/GPUBlurFilter.h"
+
+#include <boost/shared_ptr.hpp>
+
+namespace avg {
+
+class AVG_API BlurFXNode: public FXNode {
+public:
+ BlurFXNode(float radius=1.f);
+ virtual ~BlurFXNode();
+
+ void connect();
+ virtual void disconnect();
+
+ void setRadius(float stdDev);
+ float getRadius() const;
+
+private:
+ virtual GPUFilterPtr createFilter(const IntPoint& size);
+
+ GPUBlurFilterPtr m_pFilter;
+
+ float m_StdDev;
+};
+
+typedef boost::shared_ptr<BlurFXNode> BlurFXNodePtr;
+
+}
+
+#endif
+
diff --git a/src/player/BoostPython.h b/src/player/BoostPython.h
new file mode 100644
index 0000000..6fdc141
--- /dev/null
+++ b/src/player/BoostPython.h
@@ -0,0 +1,35 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifdef _WIN32
+#pragma warning(push)
+#pragma warning(disable: 4267)
+#pragma warning(disable: 4244)
+#endif
+
+#include "../api.h"
+#include <boost/python.hpp>
+
+namespace py = boost::python;
+
+#ifdef _WIN32
+#pragma warning(pop)
+#endif
diff --git a/src/player/CameraNode.cpp b/src/player/CameraNode.cpp
new file mode 100644
index 0000000..c091a4e
--- /dev/null
+++ b/src/player/CameraNode.cpp
@@ -0,0 +1,414 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "CameraNode.h"
+#include "OGLSurface.h"
+#include "TypeDefinition.h"
+
+#include "../base/Logger.h"
+#include "../base/Exception.h"
+#include "../base/ScopeTimer.h"
+#include "../base/XMLHelper.h"
+
+#include "../graphics/Filterfill.h"
+#include "../graphics/TextureMover.h"
+#include "../graphics/GLTexture.h"
+#include "../graphics/BitmapLoader.h"
+
+#include "../imaging/Camera.h"
+#include "../imaging/FWCamera.h"
+#include "../imaging/FakeCamera.h"
+
+#include <iostream>
+#include <sstream>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+using namespace std;
+
+namespace avg {
+
+void CameraNode::registerType()
+{
+ TypeDefinition def = TypeDefinition("camera", "rasternode",
+ ExportedObject::buildObject<CameraNode>)
+ .addArg(Arg<string>("driver", "firewire"))
+ .addArg(Arg<string>("device", ""))
+ .addArg(Arg<int>("unit", -1))
+ .addArg(Arg<bool>("fw800", false))
+ .addArg(Arg<float>("framerate", 15))
+ .addArg(Arg<int>("capturewidth", 640))
+ .addArg(Arg<int>("captureheight", 480))
+ .addArg(Arg<string>("pixelformat", "RGB"))
+ .addArg(Arg<int>("brightness", -1))
+ .addArg(Arg<int>("exposure", -1))
+ .addArg(Arg<int>("sharpness", -1))
+ .addArg(Arg<int>("saturation", -1))
+ .addArg(Arg<int>("camgamma", -1))
+ .addArg(Arg<int>("shutter", -1))
+ .addArg(Arg<int>("gain", -1))
+ .addArg(Arg<int>("strobeduration", -1));
+ TypeRegistry::get()->registerType(def);
+}
+
+CameraNode::CameraNode(const ArgList& args)
+ : m_bIsPlaying(false),
+ m_FrameNum(0),
+ m_bIsAutoUpdateCameraImage(true),
+ m_bNewBmp(false)
+{
+ args.setMembers(this);
+ string sDriver = args.getArgVal<string>("driver");
+ string sDevice = args.getArgVal<string>("device");
+ int unit = args.getArgVal<int>("unit");
+ bool bFW800 = args.getArgVal<bool>("fw800");
+ float frameRate = args.getArgVal<float>("framerate");
+ int width = args.getArgVal<int>("capturewidth");
+ int height = args.getArgVal<int>("captureheight");
+ string sPF = args.getArgVal<string>("pixelformat");
+
+ PixelFormat camPF = stringToPixelFormat(sPF);
+ if (camPF == NO_PIXELFORMAT) {
+ throw Exception(AVG_ERR_INVALID_ARGS, "Unknown camera pixel format "+sPF+".");
+ }
+ PixelFormat destPF;
+ if (pixelFormatIsColored(camPF)) {
+ if (BitmapLoader::get()->isBlueFirst()) {
+ destPF = B8G8R8X8;
+ } else {
+ destPF = R8G8B8X8;
+ }
+ } else {
+ destPF = I8;
+ }
+// cerr << "CameraNode ctor: " << camPF << "-->" << destPF << endl;
+
+ m_pCamera = createCamera(sDriver, sDevice, unit, bFW800, IntPoint(width, height),
+ camPF, destPF, frameRate);
+ AVG_TRACE(Logger::category::CONFIG,Logger::severity::INFO, "Got Camera " <<
+ m_pCamera->getDevice() << " from driver: " << m_pCamera->getDriverName());
+
+ m_pCamera->setFeature(CAM_FEATURE_BRIGHTNESS, args.getArgVal<int>("brightness"));
+ m_pCamera->setFeature(CAM_FEATURE_EXPOSURE, args.getArgVal<int>("exposure"));
+ m_pCamera->setFeature(CAM_FEATURE_SHARPNESS, args.getArgVal<int>("sharpness"));
+ m_pCamera->setFeature(CAM_FEATURE_SATURATION, args.getArgVal<int>("saturation"));
+ m_pCamera->setFeature(CAM_FEATURE_GAMMA, args.getArgVal<int>("camgamma"));
+ m_pCamera->setFeature(CAM_FEATURE_SHUTTER, args.getArgVal<int>("shutter"));
+ m_pCamera->setFeature(CAM_FEATURE_GAIN, args.getArgVal<int>("gain"));
+ m_pCamera->setFeature(CAM_FEATURE_STROBE_DURATION,
+ args.getArgVal<int>("strobeduration"));
+}
+
+CameraNode::~CameraNode()
+{
+ m_pCamera = CameraPtr();
+}
+
+void CameraNode::connectDisplay()
+{
+ RasterNode::connectDisplay();
+ if (m_bIsPlaying) {
+ open();
+ }
+}
+
+void CameraNode::connect(CanvasPtr pCanvas)
+{
+ if (!m_pCamera) {
+ throw Exception(AVG_ERR_UNSUPPORTED,
+ "Can't use camera node after disconnect(True).");
+ }
+ RasterNode::connect(pCanvas);
+}
+
+void CameraNode::disconnect(bool bKill)
+{
+ if (bKill) {
+ m_pCamera = CameraPtr();
+ }
+ RasterNode::disconnect(bKill);
+}
+
+void CameraNode::play()
+{
+ if (getState() == NS_CANRENDER) {
+ open();
+ }
+ m_bIsPlaying = true;
+}
+
+void CameraNode::stop()
+{
+ m_bIsPlaying = false;
+}
+
+bool CameraNode::isAvailable()
+{
+ if (!m_pCamera || boost::dynamic_pointer_cast<FakeCamera>(m_pCamera)) {
+ return false;
+ } else {
+ return true;
+ }
+}
+
+int CameraNode::getBrightness() const
+{
+ return getFeature(CAM_FEATURE_BRIGHTNESS);
+}
+
+void CameraNode::setBrightness(int value)
+{
+ setFeature(CAM_FEATURE_BRIGHTNESS, value);
+}
+
+int CameraNode::getSharpness() const
+{
+ return getFeature(CAM_FEATURE_SHARPNESS);
+}
+
+void CameraNode::setSharpness(int value)
+{
+ setFeature(CAM_FEATURE_SHARPNESS, value);
+}
+
+int CameraNode::getSaturation() const
+{
+ return getFeature(CAM_FEATURE_SATURATION);
+}
+
+void CameraNode::setSaturation(int value)
+{
+ setFeature(CAM_FEATURE_SATURATION, value);
+}
+
+int CameraNode::getCamGamma() const
+{
+ return getFeature(CAM_FEATURE_GAMMA);
+}
+
+void CameraNode::setCamGamma(int value)
+{
+ setFeature(CAM_FEATURE_GAMMA, value);
+}
+
+int CameraNode::getShutter() const
+{
+ return getFeature(CAM_FEATURE_SHUTTER);
+}
+
+void CameraNode::setShutter(int value)
+{
+ setFeature(CAM_FEATURE_SHUTTER, value);
+}
+
+int CameraNode::getGain() const
+{
+ return getFeature(CAM_FEATURE_GAIN);
+}
+
+void CameraNode::setGain(int value)
+{
+ setFeature(CAM_FEATURE_GAIN, value);
+}
+
+int CameraNode::getWhitebalanceU() const
+{
+ return m_pCamera->getWhitebalanceU();
+}
+
+int CameraNode::getWhitebalanceV() const
+{
+ return m_pCamera->getWhitebalanceV();
+}
+
+void CameraNode::setWhitebalance(int u, int v)
+{
+ m_pCamera->setWhitebalance(u, v);
+}
+
+void CameraNode::doOneShotWhitebalance()
+{
+ // The first line turns off auto white balance.
+ m_pCamera->setWhitebalance(m_pCamera->getWhitebalanceU(),
+ m_pCamera->getWhitebalanceV());
+ m_pCamera->setFeatureOneShot(CAM_FEATURE_WHITE_BALANCE);
+}
+
+int CameraNode::getStrobeDuration() const
+{
+ return getFeature(CAM_FEATURE_STROBE_DURATION);
+}
+
+void CameraNode::setStrobeDuration(int value)
+{
+ setFeature(CAM_FEATURE_STROBE_DURATION, value);
+}
+
+
+IntPoint CameraNode::getMediaSize()
+{
+ return m_pCamera->getImgSize();
+}
+
+BitmapPtr CameraNode::getBitmap()
+{
+ if (m_pCurBmp) {
+ return m_pCurBmp;
+ } else {
+ throw Exception(AVG_ERR_CAMERA_NONFATAL,
+ "CameraNode.getBitmap: No camera image available.");
+ }
+}
+
+CamerasInfosVector CameraNode::getCamerasInfos()
+{
+ CamerasInfosVector camInfos = avg::getCamerasInfos();
+ return camInfos;
+}
+
+void CameraNode::resetFirewireBus()
+{
+ FWCamera::resetBus();
+}
+
+float CameraNode::getFPS() const
+{
+ return m_pCamera->getFrameRate();
+}
+
+void CameraNode::open()
+{
+ m_pCamera->startCapture();
+ setViewport(-32767, -32767, -32767, -32767);
+ PixelFormat pf = getPixelFormat();
+ IntPoint size = getMediaSize();
+ bool bMipmap = getMaterial().getUseMipmaps();
+ m_pTex = GLTexturePtr(new GLTexture(size, pf, bMipmap));
+ m_pTex->enableStreaming();
+ getSurface()->create(pf, m_pTex);
+ newSurface();
+
+ BitmapPtr pBmp = m_pTex->lockStreamingBmp();
+ if (pf == B8G8R8X8 || pf == B8G8R8A8) {
+ FilterFill<Pixel32> Filter(Pixel32(0,0,0,255));
+ Filter.applyInPlace(pBmp);
+ } else if (pf == I8) {
+ FilterFill<Pixel8> Filter(0);
+ Filter.applyInPlace(pBmp);
+ }
+ m_pTex->unlockStreamingBmp(true);
+ setupFX(true);
+}
+
+int CameraNode::getFeature(CameraFeature feature) const
+{
+ return m_pCamera->getFeature(feature);
+}
+
+void CameraNode::setFeature(CameraFeature feature, int value)
+{
+ m_pCamera->setFeature(feature, value);
+}
+
+int CameraNode::getFrameNum() const
+{
+ return m_FrameNum;
+}
+
+static ProfilingZoneID CameraFetchImage("Camera fetch image");
+static ProfilingZoneID CameraDownloadProfilingZone("Camera tex download");
+
+void CameraNode::preRender(const VertexArrayPtr& pVA, bool bIsParentActive,
+ float parentEffectiveOpacity)
+{
+ Node::preRender(pVA, bIsParentActive, parentEffectiveOpacity);
+ if (isAutoUpdateCameraImage()) {
+ ScopeTimer Timer(CameraFetchImage);
+ updateToLatestCameraImage();
+ }
+ if (m_bNewBmp && isVisible()) {
+ ScopeTimer Timer(CameraDownloadProfilingZone);
+ m_FrameNum++;
+ BitmapPtr pBmp = m_pTex->lockStreamingBmp();
+ if (pBmp->getPixelFormat() != m_pCurBmp->getPixelFormat()) {
+ cerr << "Surface: " << pBmp->getPixelFormat() << ", CamDest: "
+ << m_pCurBmp->getPixelFormat() << endl;
+ }
+ AVG_ASSERT(pBmp->getPixelFormat() == m_pCurBmp->getPixelFormat());
+ pBmp->copyPixels(*m_pCurBmp);
+ m_pTex->unlockStreamingBmp(true);
+ renderFX(getSize(), Pixel32(255, 255, 255, 255), false);
+ m_bNewBmp = false;
+ }
+ calcVertexArray(pVA);
+}
+
+static ProfilingZoneID CameraProfilingZone("Camera::render");
+
+void CameraNode::render()
+{
+ if (m_bIsPlaying) {
+ ScopeTimer Timer(CameraProfilingZone);
+ blt32(getTransform(), getSize(), getEffectiveOpacity(), getBlendMode());
+ }
+}
+
+PixelFormat CameraNode::getPixelFormat()
+{
+ return m_pCamera->getDestPF();
+}
+
+void CameraNode::updateToLatestCameraImage()
+{
+ BitmapPtr pTmpBmp = m_pCamera->getImage(false);
+ while (pTmpBmp) {
+ m_bNewBmp = true;
+ m_pCurBmp = pTmpBmp;
+ pTmpBmp = m_pCamera->getImage(false);
+ }
+}
+
+void CameraNode::updateCameraImage()
+{
+ if (!isAutoUpdateCameraImage()) {
+ m_pCurBmp = m_pCamera->getImage(false);
+ blt32(getTransform(), getSize(), getEffectiveOpacity(), getBlendMode());
+ }
+}
+
+bool CameraNode::isAutoUpdateCameraImage() const
+{
+ return m_bIsAutoUpdateCameraImage;
+}
+
+void CameraNode::setAutoUpdateCameraImage(bool bVal)
+{
+ m_bIsAutoUpdateCameraImage = bVal;
+}
+
+bool CameraNode::isImageAvailable() const
+{
+ return m_pCurBmp.get() != NULL;
+}
+
+
+}
diff --git a/src/player/CameraNode.h b/src/player/CameraNode.h
new file mode 100644
index 0000000..1aef572
--- /dev/null
+++ b/src/player/CameraNode.h
@@ -0,0 +1,135 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _CameraNode_H_
+#define _CameraNode_H_
+
+#include "../api.h"
+#include "../avgconfigwrapper.h"
+
+#include "RasterNode.h"
+
+#include "../imaging/Camera.h"
+#include "../imaging/CameraInfo.h"
+
+#include <boost/thread/thread.hpp>
+
+#include <string>
+#include <map>
+
+namespace avg {
+
+class TextureMover;
+typedef boost::shared_ptr<TextureMover> TextureMoverPtr;
+typedef std::vector<CameraInfo> CamerasInfosVector;
+
+class AVG_API CameraNode : public RasterNode
+{
+ public:
+ static void registerType();
+
+ CameraNode(const ArgList& args);
+ virtual ~CameraNode();
+
+ virtual void connectDisplay();
+ virtual void connect(CanvasPtr pCanvas);
+ virtual void disconnect(bool bKill);
+
+ void play();
+ void stop();
+ bool isAvailable();
+
+ const std::string& getDevice() const
+ {
+ return m_pCamera->getDevice();
+ }
+
+ const std::string& getDriverName() const
+ {
+ return m_pCamera->getDriverName();
+ }
+
+ float getFrameRate() const
+ {
+ return m_pCamera->getFrameRate();
+ }
+
+ int getBrightness() const;
+ void setBrightness(int value);
+ int getSharpness() const;
+ void setSharpness(int value);
+ int getSaturation() const;
+ void setSaturation(int value);
+ int getCamGamma() const;
+ void setCamGamma(int value);
+ int getShutter() const;
+ void setShutter(int value);
+ int getGain() const;
+ void setGain(int value);
+ int getWhitebalanceU() const;
+ int getWhitebalanceV() const;
+ void setWhitebalance(int u, int v);
+ void doOneShotWhitebalance();
+ int getStrobeDuration() const;
+ void setStrobeDuration(int value);
+
+ void updateCameraImage();
+ bool isAutoUpdateCameraImage() const;
+ void setAutoUpdateCameraImage(bool bVal);
+ bool isImageAvailable() const;
+
+ virtual void preRender(const VertexArrayPtr& pVA, bool bIsParentActive,
+ float parentEffectiveOpacity);
+ virtual void render();
+
+ int getFrameNum() const;
+ IntPoint getMediaSize();
+ virtual BitmapPtr getBitmap();
+
+ static CamerasInfosVector getCamerasInfos();
+ static void resetFirewireBus();
+
+ private:
+ int getFeature (CameraFeature feature) const;
+ void setFeature (CameraFeature feature, int value);
+
+ virtual float getFPS() const;
+ virtual void open();
+ virtual PixelFormat getPixelFormat();
+ void setFeature(int FeatureID);
+
+ void updateToLatestCameraImage();
+
+ bool m_bIsPlaying;
+
+ CameraPtr m_pCamera;
+ int m_FrameNum;
+ BitmapPtr m_pCurBmp;
+ bool m_bIsAutoUpdateCameraImage;
+ bool m_bNewBmp;
+
+ GLTexturePtr m_pTex;
+};
+
+}
+
+#endif
+
diff --git a/src/player/Canvas.cpp b/src/player/Canvas.cpp
new file mode 100644
index 0000000..ae0723e
--- /dev/null
+++ b/src/player/Canvas.cpp
@@ -0,0 +1,325 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "Canvas.h"
+
+#include "Player.h"
+#include "AVGNode.h"
+#include "Shape.h"
+#include "OffscreenCanvas.h"
+
+#include "../base/Exception.h"
+#include "../base/Logger.h"
+#include "../base/ScopeTimer.h"
+
+#include "../graphics/StandardShader.h"
+
+#include <iostream>
+
+using namespace std;
+using namespace boost;
+
+namespace avg {
+
+Canvas::Canvas(Player * pPlayer)
+ : m_pPlayer(pPlayer),
+ m_bIsPlaying(false),
+ m_PlaybackEndSignal(&IPlaybackEndListener::onPlaybackEnd),
+ m_FrameEndSignal(&IFrameEndListener::onFrameEnd),
+ m_PreRenderSignal(&IPreRenderListener::onPreRender),
+ m_ClipLevel(0)
+{
+}
+
+Canvas::~Canvas()
+{
+}
+
+void Canvas::setRoot(NodePtr pRootNode)
+{
+ assert(!m_pRootNode);
+ m_pRootNode = dynamic_pointer_cast<CanvasNode>(pRootNode);
+ CanvasPtr pThis = dynamic_pointer_cast<Canvas>(shared_from_this());
+ m_pRootNode->setParent(0, Node::NS_CONNECTED, pThis);
+ registerNode(m_pRootNode);
+}
+
+void Canvas::initPlayback(int multiSampleSamples)
+{
+ m_bIsPlaying = true;
+ m_pRootNode->connectDisplay();
+ m_MultiSampleSamples = multiSampleSamples;
+ m_pVertexArray = VertexArrayPtr(new VertexArray(2000, 3000));
+}
+
+void Canvas::stopPlayback(bool bIsAbort)
+{
+ if (m_bIsPlaying) {
+ if (!bIsAbort) {
+ m_PlaybackEndSignal.emit();
+ }
+ m_pRootNode->disconnect(true);
+ m_pRootNode = CanvasNodePtr();
+ m_IDMap.clear();
+ m_bIsPlaying = false;
+ m_pVertexArray = VertexArrayPtr();
+ }
+}
+
+NodePtr Canvas::getElementByID(const std::string& id)
+{
+ if (m_IDMap.find(id) != m_IDMap.end()) {
+ return m_IDMap.find(id)->second;
+ } else {
+ return NodePtr();
+ }
+}
+
+void Canvas::registerNode(NodePtr pNode)
+{
+ addNodeID(pNode);
+ DivNodePtr pDivNode = boost::dynamic_pointer_cast<DivNode>(pNode);
+ if (pDivNode) {
+ for (unsigned i=0; i<pDivNode->getNumChildren(); i++) {
+ registerNode(pDivNode->getChild(i));
+ }
+ }
+}
+
+void Canvas::addNodeID(NodePtr pNode)
+{
+ const string& id = pNode->getID();
+ if (id != "") {
+ if (m_IDMap.find(id) != m_IDMap.end() &&
+ m_IDMap.find(id)->second != pNode)
+ {
+ throw (Exception (AVG_ERR_XML_DUPLICATE_ID,
+ string("Error: duplicate id ")+id));
+ }
+ m_IDMap.insert(NodeIDMap::value_type(id, pNode));
+ }
+}
+
+void Canvas::removeNodeID(const string& id)
+{
+ if (id != "") {
+ map<string, NodePtr>::iterator it;
+ it = m_IDMap.find(id);
+ if (it != m_IDMap.end()) {
+ m_IDMap.erase(it);
+ } else {
+ cerr << "removeNodeID(\"" << id << "\") failed." << endl;
+ AVG_ASSERT(false);
+ }
+ }
+}
+
+CanvasNodePtr Canvas::getRootNode() const
+{
+ return m_pRootNode;
+}
+
+static ProfilingZoneID RenderProfilingZone("Render");
+
+void Canvas::doFrame(bool bPythonAvailable)
+{
+ emitPreRenderSignal();
+ if (!m_pPlayer->isStopping()) {
+ ScopeTimer Timer(RenderProfilingZone);
+ Player::get()->startTraversingTree();
+ if (bPythonAvailable) {
+ Py_BEGIN_ALLOW_THREADS;
+ try {
+ renderTree();
+ } catch(...) {
+ Py_BLOCK_THREADS;
+ Player::get()->endTraversingTree();
+ throw;
+ }
+ Py_END_ALLOW_THREADS;
+ } else {
+ renderTree();
+ }
+ Player::get()->endTraversingTree();
+ }
+ emitFrameEndSignal();
+}
+
+IntPoint Canvas::getSize() const
+{
+ return IntPoint(m_pRootNode->getSize());
+}
+static ProfilingZoneID PushClipRectProfilingZone("pushClipRect");
+
+void Canvas::pushClipRect(const glm::mat4& transform, SubVertexArray& va)
+{
+ ScopeTimer timer(PushClipRectProfilingZone);
+ m_ClipLevel++;
+ clip(transform, va, GL_INCR);
+}
+
+static ProfilingZoneID PopClipRectProfilingZone("popClipRect");
+
+void Canvas::popClipRect(const glm::mat4& transform, SubVertexArray& va)
+{
+ ScopeTimer timer(PopClipRectProfilingZone);
+ m_ClipLevel--;
+ clip(transform, va, GL_DECR);
+}
+
+void Canvas::registerPlaybackEndListener(IPlaybackEndListener* pListener)
+{
+ m_PlaybackEndSignal.connect(pListener);
+}
+
+void Canvas::unregisterPlaybackEndListener(IPlaybackEndListener* pListener)
+{
+ m_PlaybackEndSignal.disconnect(pListener);
+}
+
+void Canvas::registerFrameEndListener(IFrameEndListener* pListener)
+{
+ m_FrameEndSignal.connect(pListener);
+}
+
+void Canvas::unregisterFrameEndListener(IFrameEndListener* pListener)
+{
+ m_FrameEndSignal.disconnect(pListener);
+}
+
+void Canvas::registerPreRenderListener(IPreRenderListener* pListener)
+{
+ m_PreRenderSignal.connect(pListener);
+}
+
+void Canvas::unregisterPreRenderListener(IPreRenderListener* pListener)
+{
+ m_PreRenderSignal.disconnect(pListener);
+}
+
+Player* Canvas::getPlayer() const
+{
+ return m_pPlayer;
+}
+
+vector<NodePtr> Canvas::getElementsByPos(const glm::vec2& pos) const
+{
+ vector<NodePtr> elements;
+ m_pRootNode->getElementsByPos(pos, elements);
+ return elements;
+}
+
+static ProfilingZoneID PreRenderProfilingZone("PreRender");
+static ProfilingZoneID VATransferProfilingZone("VA Transfer");
+
+void Canvas::preRender()
+{
+ ScopeTimer Timer(PreRenderProfilingZone);
+ m_pVertexArray->reset();
+ m_pRootNode->preRender(m_pVertexArray, true, 1.0f);
+ {
+ ScopeTimer Timer(VATransferProfilingZone);
+ m_pVertexArray->update();
+ }
+}
+
+void Canvas::render(IntPoint windowSize, bool bOffscreen)
+{
+ clearGLBuffers(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT,
+ !bOffscreen);
+ glViewport(0, 0, windowSize.x, windowSize.y);
+ GLContext::checkError("Canvas::render: glViewport()");
+ glm::vec2 size = m_pRootNode->getSize();
+ glm::mat4 projMat;
+ if (bOffscreen) {
+ projMat = glm::ortho(0.f, size.x, 0.f, size.y);
+ } else {
+ projMat = glm::ortho(0.f, size.x, size.y, 0.f);
+ }
+ m_pVertexArray->activate();
+ m_pRootNode->maybeRender(projMat);
+
+ renderOutlines(projMat);
+}
+
+void Canvas::renderOutlines(const glm::mat4& transform)
+{
+ GLContext* pContext = GLContext::getMain();
+ VertexArrayPtr pVA(new VertexArray);
+ pContext->setBlendMode(GLContext::BLEND_BLEND, false);
+ m_pRootNode->renderOutlines(pVA, Pixel32(0,0,0,0));
+ StandardShaderPtr pShader = pContext->getStandardShader();
+ pShader->setTransform(transform);
+ pShader->setUntextured();
+ pShader->setAlpha(0.5f);
+ pShader->activate();
+ if (pVA->getNumVerts() != 0) {
+ pVA->update();
+ pVA->draw();
+ }
+}
+
+void Canvas::clip(const glm::mat4& transform, SubVertexArray& va, GLenum stencilOp)
+{
+ // Disable drawing to color buffer
+ glColorMask(0, 0, 0, 0);
+
+ // Enable drawing to stencil buffer
+ glStencilMask(~0);
+
+ // Draw clip rectangle into stencil buffer
+ glStencilFunc(GL_ALWAYS, 0, 0);
+ glStencilOp(stencilOp, stencilOp, stencilOp);
+
+ StandardShaderPtr pShader = GLContext::getMain()->getStandardShader();
+ pShader->setUntextured();
+ pShader->setTransform(transform);
+ pShader->activate();
+ va.draw();
+
+ // Set stencil test to only let
+ glStencilFunc(GL_LEQUAL, m_ClipLevel, ~0);
+ glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
+
+ // Disable drawing to stencil buffer
+ glStencilMask(0);
+
+ // Enable drawing to color buffer
+ glColorMask(~0, ~0, ~0, ~0);
+}
+
+static ProfilingZoneID PreRenderSignalProfilingZone("PreRender signal");
+
+void Canvas::emitPreRenderSignal()
+{
+ ScopeTimer Timer(PreRenderSignalProfilingZone);
+ m_PreRenderSignal.emit();
+}
+
+static ProfilingZoneID FrameEndProfilingZone("OnFrameEnd");
+
+void Canvas::emitFrameEndSignal()
+{
+ ScopeTimer Timer(FrameEndProfilingZone);
+ m_FrameEndSignal.emit();
+}
+
+}
diff --git a/src/player/Canvas.h b/src/player/Canvas.h
new file mode 100644
index 0000000..38259a5
--- /dev/null
+++ b/src/player/Canvas.h
@@ -0,0 +1,124 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _Canvas_H_
+#define _Canvas_H_
+
+#include "../api.h"
+
+#include "FontStyle.h"
+
+#include "../base/IPlaybackEndListener.h"
+#include "../base/IFrameEndListener.h"
+#include "../base/IPreRenderListener.h"
+#include "../base/Signal.h"
+#include "../base/GLMHelper.h"
+
+#include "../graphics/OGLHelper.h"
+#include "../graphics/Bitmap.h"
+
+#include <map>
+#include <string>
+#include <vector>
+#include <boost/enable_shared_from_this.hpp>
+
+namespace avg {
+
+class Player;
+class Node;
+class CanvasNode;
+class AudioEngine;
+class TestHelper;
+class ProfilingZoneID;
+class Canvas;
+class FBO;
+class VertexArray;
+class SubVertexArray;
+
+typedef boost::shared_ptr<Node> NodePtr;
+typedef boost::shared_ptr<CanvasNode> CanvasNodePtr;
+typedef boost::shared_ptr<FBO> FBOPtr;
+typedef boost::shared_ptr<VertexArray> VertexArrayPtr;
+
+class Canvas;
+typedef boost::shared_ptr<Canvas> CanvasPtr;
+typedef boost::weak_ptr<Canvas> CanvasWeakPtr;
+
+class AVG_API Canvas: public ExportedObject
+{
+ public:
+ Canvas(Player * pPlayer);
+ virtual ~Canvas();
+ virtual void setRoot(NodePtr pRootNode);
+ void initPlayback(int multiSampleSamples);
+ virtual void stopPlayback(bool bIsAbort);
+
+ CanvasNodePtr getRootNode() const;
+ NodePtr getElementByID(const std::string& id);
+ void registerNode(NodePtr pNode);
+ void addNodeID(NodePtr pNode);
+ void removeNodeID(const std::string& id);
+ virtual void doFrame(bool bPythonAvailable);
+ IntPoint getSize() const;
+ virtual BitmapPtr screenshot() const = 0;
+ virtual void pushClipRect(const glm::mat4& transform, SubVertexArray& va);
+ virtual void popClipRect(const glm::mat4& transform, SubVertexArray& va);
+
+ void registerPlaybackEndListener(IPlaybackEndListener* pListener);
+ void unregisterPlaybackEndListener(IPlaybackEndListener* pListener);
+ void registerFrameEndListener(IFrameEndListener* pListener);
+ void unregisterFrameEndListener(IFrameEndListener* pListener);
+ void registerPreRenderListener(IPreRenderListener* pListener);
+ void unregisterPreRenderListener(IPreRenderListener* pListener);
+
+ std::vector<NodePtr> getElementsByPos(const glm::vec2& Pos) const;
+
+ virtual void render(IntPoint windowSize, bool bOffscreen);
+
+ protected:
+ Player * getPlayer() const;
+ void preRender();
+ void emitPreRenderSignal();
+ void emitFrameEndSignal();
+
+ private:
+ virtual void renderTree()=0;
+ void renderOutlines(const glm::mat4& transform);
+
+ void clip(const glm::mat4& transform, SubVertexArray& va, GLenum stencilOp);
+ Player * m_pPlayer;
+ CanvasNodePtr m_pRootNode;
+ bool m_bIsPlaying;
+ VertexArrayPtr m_pVertexArray;
+
+ typedef std::map<std::string, NodePtr> NodeIDMap;
+ NodeIDMap m_IDMap;
+
+ Signal<IPlaybackEndListener> m_PlaybackEndSignal;
+ Signal<IFrameEndListener> m_FrameEndSignal;
+ Signal<IPreRenderListener> m_PreRenderSignal;
+
+ int m_MultiSampleSamples;
+ int m_ClipLevel;
+};
+
+}
+#endif
diff --git a/src/player/CanvasNode.cpp b/src/player/CanvasNode.cpp
new file mode 100644
index 0000000..3c267d3
--- /dev/null
+++ b/src/player/CanvasNode.cpp
@@ -0,0 +1,67 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "CanvasNode.h"
+#include "Player.h"
+
+#include "TypeDefinition.h"
+
+#include "../base/FileHelper.h"
+#include "../base/Exception.h"
+
+using namespace std;
+
+namespace avg {
+
+void CanvasNode::registerType()
+{
+ TypeDefinition def = TypeDefinition("canvasbase", "div",
+ ExportedObject::buildObject<CanvasNode>);
+ TypeRegistry::get()->registerType(def);
+}
+
+CanvasNode::CanvasNode(const ArgList& args)
+ : DivNode(args)
+{
+ args.setMembers(this);
+ if (getSize() == glm::vec2(0, 0)) {
+ throw (Exception(AVG_ERR_OUT_OF_RANGE,
+ "<avg> and <canvas> node width and height attributes are mandatory."));
+ }
+}
+
+CanvasNode::~CanvasNode()
+{
+}
+
+string CanvasNode::getEffectiveMediaDir()
+{
+ string sMediaDir = getMediaDir();
+ if (!isAbsPath(sMediaDir)) {
+ sMediaDir = Player::get()->getCurDirName()+sMediaDir;
+ }
+ if (sMediaDir[sMediaDir.length()-1] != '/') {
+ sMediaDir += '/';
+ }
+ return sMediaDir;
+}
+
+}
diff --git a/src/player/CanvasNode.h b/src/player/CanvasNode.h
new file mode 100644
index 0000000..b336a4a
--- /dev/null
+++ b/src/player/CanvasNode.h
@@ -0,0 +1,48 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _CanvasNode_H_
+#define _CanvasNode_H_
+
+#include "../api.h"
+#include "DivNode.h"
+
+#include <string>
+
+namespace avg {
+
+class AVG_API CanvasNode : public DivNode
+{
+ public:
+ static void registerType();
+
+ CanvasNode(const ArgList& args);
+ virtual ~CanvasNode();
+
+ virtual std::string getEffectiveMediaDir();
+
+};
+
+typedef boost::shared_ptr<CanvasNode> CanvasNodePtr;
+
+}
+
+#endif
diff --git a/src/player/ChromaKeyFXNode.cpp b/src/player/ChromaKeyFXNode.cpp
new file mode 100644
index 0000000..4e70454
--- /dev/null
+++ b/src/player/ChromaKeyFXNode.cpp
@@ -0,0 +1,154 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "ChromaKeyFXNode.h"
+
+#include "../base/ObjectCounter.h"
+
+#include <string>
+
+using namespace std;
+
+namespace avg {
+
+ChromaKeyFXNode::ChromaKeyFXNode()
+ : FXNode(false),
+ m_sColorName("00FF00"),
+ m_Color(0, 255, 0),
+ m_HTolerance(0.0),
+ m_STolerance(0.0),
+ m_LTolerance(0.0),
+ m_Softness(0.0),
+ m_Erosion(0),
+ m_SpillThreshold(0.0)
+{
+ ObjectCounter::get()->incRef(&typeid(*this));
+}
+
+ChromaKeyFXNode::~ChromaKeyFXNode()
+{
+ ObjectCounter::get()->decRef(&typeid(*this));
+}
+
+void ChromaKeyFXNode::disconnect()
+{
+ m_pFilter = GPUChromaKeyFilterPtr();
+ FXNode::disconnect();
+}
+
+
+void ChromaKeyFXNode::setColor(const std::string& sColorName)
+{
+ m_sColorName = sColorName;
+ m_Color = colorStringToColor(m_sColorName);
+ updateFilter();
+}
+
+const std::string& ChromaKeyFXNode::getColor() const
+{
+ return m_sColorName;
+}
+
+void ChromaKeyFXNode::setHTolerance(float tolerance)
+{
+ m_HTolerance = tolerance;
+ updateFilter();
+}
+
+float ChromaKeyFXNode::getHTolerance() const
+{
+ return m_HTolerance;
+}
+
+void ChromaKeyFXNode::setSTolerance(float tolerance)
+{
+ m_STolerance = tolerance;
+ updateFilter();
+}
+
+float ChromaKeyFXNode::getSTolerance() const
+{
+ return m_STolerance;
+}
+
+void ChromaKeyFXNode::setLTolerance(float tolerance)
+{
+ m_LTolerance = tolerance;
+ updateFilter();
+}
+
+float ChromaKeyFXNode::getLTolerance() const
+{
+ return m_LTolerance;
+}
+
+void ChromaKeyFXNode::setSoftness(float softness)
+{
+ m_Softness = softness;
+ updateFilter();
+}
+
+float ChromaKeyFXNode::getSoftness() const
+{
+ return m_Softness;
+}
+
+void ChromaKeyFXNode::setErosion(int erosion)
+{
+ m_Erosion = erosion;
+ updateFilter();
+}
+
+int ChromaKeyFXNode::getErosion() const
+{
+ return m_Erosion;
+}
+
+void ChromaKeyFXNode::setSpillThreshold(float spillThreshold)
+{
+ m_SpillThreshold = spillThreshold;
+ updateFilter();
+}
+
+float ChromaKeyFXNode::getSpillThreshold() const
+{
+ return m_SpillThreshold;
+}
+
+GPUFilterPtr ChromaKeyFXNode::createFilter(const IntPoint& size)
+{
+ m_pFilter = GPUChromaKeyFilterPtr(new GPUChromaKeyFilter(size, false));
+ m_pFilter->setParams(m_Color, m_HTolerance, m_STolerance, m_LTolerance, m_Softness,
+ m_Erosion, m_SpillThreshold);
+ setDirty();
+ return m_pFilter;
+}
+
+void ChromaKeyFXNode::updateFilter()
+{
+ if (m_pFilter) {
+ m_pFilter->setParams(m_Color, m_HTolerance, m_STolerance, m_LTolerance,
+ m_Softness, m_Erosion, m_SpillThreshold);
+ setDirty();
+ }
+}
+
+}
diff --git a/src/player/ChromaKeyFXNode.h b/src/player/ChromaKeyFXNode.h
new file mode 100644
index 0000000..3653448
--- /dev/null
+++ b/src/player/ChromaKeyFXNode.h
@@ -0,0 +1,77 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _ChromaKeyFXNode_H_
+#define _ChromaKeyFXNode_H_
+
+#include "../api.h"
+
+#include "FXNode.h"
+#include "../graphics/GPUChromaKeyFilter.h"
+
+#include <boost/shared_ptr.hpp>
+
+namespace avg {
+
+class AVG_API ChromaKeyFXNode: public FXNode {
+public:
+ ChromaKeyFXNode();
+ virtual ~ChromaKeyFXNode();
+
+ virtual void disconnect();
+
+ void setColor(const std::string& sColorName);
+ const std::string& getColor() const;
+ void setHTolerance(float tolerance);
+ float getHTolerance() const;
+ void setSTolerance(float tolerance);
+ float getSTolerance() const;
+ void setLTolerance(float tolerance);
+ float getLTolerance() const;
+ void setSoftness(float softness);
+ float getSoftness() const;
+ void setErosion(int erosion);
+ int getErosion() const;
+ void setSpillThreshold(float spillThreshold);
+ float getSpillThreshold() const;
+
+private:
+ virtual GPUFilterPtr createFilter(const IntPoint& size);
+ void updateFilter();
+
+ GPUChromaKeyFilterPtr m_pFilter;
+
+ std::string m_sColorName;
+ Pixel32 m_Color;
+ float m_HTolerance;
+ float m_STolerance;
+ float m_LTolerance;
+ float m_Softness;
+ int m_Erosion;
+ float m_SpillThreshold;
+};
+
+typedef boost::shared_ptr<ChromaKeyFXNode> ChromaKeyFXNodePtr;
+
+}
+
+#endif
+
diff --git a/src/player/CircleNode.cpp b/src/player/CircleNode.cpp
new file mode 100644
index 0000000..8d00a8e
--- /dev/null
+++ b/src/player/CircleNode.cpp
@@ -0,0 +1,291 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "CircleNode.h"
+
+#include "TypeDefinition.h"
+
+#include "../base/Exception.h"
+#include "../base/MathHelper.h"
+
+#include <iostream>
+#include <sstream>
+
+using namespace std;
+
+namespace avg {
+
+void CircleNode::registerType()
+{
+ TypeDefinition def = TypeDefinition("circle", "filledvectornode",
+ ExportedObject::buildObject<CircleNode>)
+ .addArg(Arg<glm::vec2>("pos", glm::vec2(0,0), false, offsetof(CircleNode, m_Pos)))
+ .addArg(Arg<float>("r", 1, false, offsetof(CircleNode, m_Radius)))
+ .addArg(Arg<float>("texcoord1", 0, false, offsetof(CircleNode, m_TC1)))
+ .addArg(Arg<float>("texcoord2", 1, false, offsetof(CircleNode, m_TC2)))
+ ;
+ TypeRegistry::get()->registerType(def);
+}
+
+CircleNode::CircleNode(const ArgList& args)
+ : FilledVectorNode(args)
+{
+ args.setMembers(this);
+}
+
+CircleNode::~CircleNode()
+{
+}
+
+const glm::vec2& CircleNode::getPos() const
+{
+ return m_Pos;
+}
+
+void CircleNode::setPos(const glm::vec2& pt)
+{
+ m_Pos = pt;
+ setDrawNeeded();
+}
+
+float CircleNode::getR() const
+{
+ return m_Radius;
+}
+
+void CircleNode::setR(float r)
+{
+ if (int(r) <= 0) {
+ throw Exception(AVG_ERR_OUT_OF_RANGE, "Circle radius must be a positive number.");
+ }
+ m_Radius = r;
+ setDrawNeeded();
+}
+
+float CircleNode::getTexCoord1() const
+{
+ return m_TC1;
+}
+
+void CircleNode::setTexCoord1(float tc)
+{
+ m_TC1 = tc;
+ setDrawNeeded();
+}
+
+float CircleNode::getTexCoord2() const
+{
+ return m_TC2;
+}
+
+void CircleNode::setTexCoord2(float tc)
+{
+ m_TC2 = tc;
+ setDrawNeeded();
+}
+
+void CircleNode::getElementsByPos(const glm::vec2& pos, vector<NodePtr>& pElements)
+{
+ if (glm::length(pos-m_Pos) <= m_Radius && reactsToMouseEvents()) {
+ pElements.push_back(getSharedThis());
+ }
+}
+
+void CircleNode::calcVertexes(const VertexDataPtr& pVertexData, Pixel32 color)
+{
+ // TODO: This gets called whenever the circle position changes and is quite
+ // expensive. Should be optimized away.
+ glm::vec2 firstPt1 = getCirclePt(0, m_Radius+getStrokeWidth()/2)+m_Pos;
+ glm::vec2 firstPt2 = getCirclePt(0, m_Radius-getStrokeWidth()/2)+m_Pos;
+ int curVertex = 0;
+ pVertexData->appendPos(firstPt1, glm::vec2(m_TC1, 0), color);
+ pVertexData->appendPos(firstPt2, glm::vec2(m_TC1, 1), color);
+ vector<glm::vec2> innerCircle;
+ getEigthCirclePoints(innerCircle, m_Radius-getStrokeWidth()/2);
+ vector<glm::vec2> outerCircle;
+ getEigthCirclePoints(outerCircle, m_Radius+getStrokeWidth()/2);
+
+ typedef vector<glm::vec2>::iterator Vec2It;
+ typedef vector<glm::vec2>::reverse_iterator Vec2RIt;
+ int i = 0;
+ for (Vec2It iit = innerCircle.begin()+1, oit = outerCircle.begin()+1;
+ iit != innerCircle.end(); ++iit, ++oit)
+ {
+ appendCirclePoint(pVertexData, *iit, *oit, color, i, curVertex);
+ }
+ for (Vec2RIt iit = innerCircle.rbegin()+1, oit = outerCircle.rbegin()+1;
+ iit != innerCircle.rend(); ++iit, ++oit)
+ {
+ glm::vec2 iPt = glm::vec2(-iit->y, -iit->x);
+ glm::vec2 oPt = glm::vec2(-oit->y, -oit->x);
+ appendCirclePoint(pVertexData, iPt, oPt, color, i, curVertex);
+ }
+ for (Vec2It iit = innerCircle.begin()+1, oit = outerCircle.begin()+1;
+ iit != innerCircle.end(); ++iit, ++oit)
+ {
+ glm::vec2 iPt = glm::vec2(-iit->y, iit->x);
+ glm::vec2 oPt = glm::vec2(-oit->y, oit->x);
+ appendCirclePoint(pVertexData, iPt, oPt, color, i, curVertex);
+ }
+ for (Vec2RIt iit = innerCircle.rbegin()+1, oit = outerCircle.rbegin()+1;
+ iit !=innerCircle.rend(); ++iit, ++oit)
+ {
+ glm::vec2 iPt = glm::vec2(iit->x, -iit->y);
+ glm::vec2 oPt = glm::vec2(oit->x, -oit->y);
+ appendCirclePoint(pVertexData, iPt, oPt, color, i, curVertex);
+ }
+ for (Vec2It iit = innerCircle.begin()+1, oit = outerCircle.begin()+1;
+ iit != innerCircle.end(); ++iit, ++oit)
+ {
+ glm::vec2 iPt = glm::vec2(-iit->x, -iit->y);
+ glm::vec2 oPt = glm::vec2(-oit->x, -oit->y);
+ appendCirclePoint(pVertexData, iPt, oPt, color, i, curVertex);
+ }
+ for (Vec2RIt iit = innerCircle.rbegin()+1, oit = outerCircle.rbegin()+1;
+ iit != innerCircle.rend(); ++iit, ++oit)
+ {
+ glm::vec2 iPt = glm::vec2(iit->y, iit->x);
+ glm::vec2 oPt = glm::vec2(oit->y, oit->x);
+ appendCirclePoint(pVertexData, iPt, oPt, color, i, curVertex);
+ }
+ for (Vec2It iit = innerCircle.begin()+1, oit = outerCircle.begin()+1;
+ iit != innerCircle.end(); ++iit, ++oit)
+ {
+ glm::vec2 iPt = glm::vec2(iit->y, -iit->x);
+ glm::vec2 oPt = glm::vec2(oit->y, -oit->x);
+ appendCirclePoint(pVertexData, iPt, oPt, color, i, curVertex);
+ }
+ for (Vec2RIt iit = innerCircle.rbegin()+1, oit = outerCircle.rbegin()+1;
+ iit != innerCircle.rend(); ++iit, ++oit)
+ {
+ glm::vec2 iPt = glm::vec2(-iit->x, iit->y);
+ glm::vec2 oPt = glm::vec2(-oit->x, oit->y);
+ appendCirclePoint(pVertexData, iPt, oPt, color, i, curVertex);
+ }
+}
+
+void CircleNode::calcFillVertexes(const VertexDataPtr& pVertexData, Pixel32 color)
+{
+ glm::vec2 minPt = m_Pos-glm::vec2(m_Radius, m_Radius);
+ glm::vec2 maxPt = m_Pos+glm::vec2(m_Radius, m_Radius);
+ glm::vec2 centerTexCoord = calcFillTexCoord(m_Pos, minPt, maxPt);
+ pVertexData->appendPos(m_Pos, centerTexCoord, color);
+ int curVertex = 1;
+ glm::vec2 firstPt = getCirclePt(0, m_Radius)+m_Pos;
+ glm::vec2 firstTexCoord = calcFillTexCoord(firstPt, minPt, maxPt);
+ pVertexData->appendPos(firstPt, firstTexCoord, color);
+ vector<glm::vec2> circlePoints;
+ getEigthCirclePoints(circlePoints, m_Radius);
+
+ for (vector<glm::vec2>::iterator it = circlePoints.begin()+1;
+ it != circlePoints.end(); ++it)
+ {
+ glm::vec2 curPt = *it+m_Pos;
+ appendFillCirclePoint(pVertexData, curPt, minPt, maxPt, color, curVertex);
+ }
+ for (vector<glm::vec2>::reverse_iterator it = circlePoints.rbegin()+1;
+ it != circlePoints.rend(); ++it)
+ {
+ glm::vec2 curPt = glm::vec2(-it->y, -it->x)+m_Pos;
+ appendFillCirclePoint(pVertexData, curPt, minPt, maxPt, color, curVertex);
+ }
+ for (vector<glm::vec2>::iterator it = circlePoints.begin()+1;
+ it != circlePoints.end(); ++it)
+ {
+ glm::vec2 curPt = glm::vec2(-it->y, it->x)+m_Pos;
+ appendFillCirclePoint(pVertexData, curPt, minPt, maxPt, color, curVertex);
+ }
+ for (vector<glm::vec2>::reverse_iterator it = circlePoints.rbegin()+1;
+ it != circlePoints.rend(); ++it)
+ {
+ glm::vec2 curPt = glm::vec2(it->x, -it->y)+m_Pos;
+ appendFillCirclePoint(pVertexData, curPt, minPt, maxPt, color, curVertex);
+ }
+ for (vector<glm::vec2>::iterator it = circlePoints.begin()+1;
+ it != circlePoints.end(); ++it)
+ {
+ glm::vec2 curPt = glm::vec2(-it->x, -it->y)+m_Pos;
+ appendFillCirclePoint(pVertexData, curPt, minPt, maxPt, color, curVertex);
+ }
+ for (vector<glm::vec2>::reverse_iterator it = circlePoints.rbegin()+1;
+ it != circlePoints.rend(); ++it)
+ {
+ glm::vec2 curPt = glm::vec2(it->y, it->x)+m_Pos;
+ appendFillCirclePoint(pVertexData, curPt, minPt, maxPt, color, curVertex);
+ }
+ for (vector<glm::vec2>::iterator it = circlePoints.begin()+1;
+ it != circlePoints.end(); ++it)
+ {
+ glm::vec2 curPt = glm::vec2(it->y, -it->x)+m_Pos;
+ appendFillCirclePoint(pVertexData, curPt, minPt, maxPt, color, curVertex);
+ }
+ for (vector<glm::vec2>::reverse_iterator it = circlePoints.rbegin()+1;
+ it != circlePoints.rend(); ++it)
+ {
+ glm::vec2 curPt = glm::vec2(-it->x, it->y)+m_Pos;
+ appendFillCirclePoint(pVertexData, curPt, minPt, maxPt, color, curVertex);
+ }
+}
+
+void CircleNode::appendCirclePoint(const VertexDataPtr& pVertexData,
+ const glm::vec2& iPt, const glm::vec2& oPt, Pixel32 color, int& i,
+ int& curVertex)
+{
+ i++;
+ float ratio = (float(i)/getNumCircumferencePoints());
+ float curTC = (1-ratio)*m_TC1+ratio*m_TC2;
+ pVertexData->appendPos(oPt+m_Pos, glm::vec2(curTC, 0), color);
+ pVertexData->appendPos(iPt+m_Pos, glm::vec2(curTC, 1), color);
+ pVertexData->appendQuadIndexes(curVertex+1, curVertex, curVertex+3, curVertex+2);
+ curVertex += 2;
+}
+
+void CircleNode::appendFillCirclePoint(const VertexDataPtr& pVertexData,
+ const glm::vec2& curPt, const glm::vec2& minPt, const glm::vec2& maxPt,
+ Pixel32 color, int& curVertex)
+{
+ glm::vec2 curTexCoord = calcFillTexCoord(curPt, minPt, maxPt);
+ pVertexData->appendPos(curPt, curTexCoord, color);
+ pVertexData->appendTriIndexes(0, curVertex, curVertex+1);
+ curVertex++;
+}
+
+int CircleNode::getNumCircumferencePoints()
+{
+ return int(ceil((m_Radius*3)/8)*8);
+}
+
+void CircleNode::getEigthCirclePoints(vector<glm::vec2>& pts, float radius)
+{
+ int numPts = getNumCircumferencePoints();
+ for (int i = 0; i <= numPts/8; ++i) {
+ float ratio = (float(i)/numPts);
+ float angle = ratio*2*PI;
+ pts.push_back(getCirclePt(angle, radius));
+ }
+}
+
+glm::vec2 CircleNode::getCirclePt(float angle, float radius)
+{
+ return glm::vec2(sin(angle)*radius, -cos(angle)*radius);
+}
+
+}
diff --git a/src/player/CircleNode.h b/src/player/CircleNode.h
new file mode 100644
index 0000000..afc4160
--- /dev/null
+++ b/src/player/CircleNode.h
@@ -0,0 +1,77 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _CircleNode_H_
+#define _CircleNode_H_
+
+#include "../api.h"
+#include "FilledVectorNode.h"
+
+#include "../graphics/Pixel32.h"
+
+namespace avg {
+
+class AVG_API CircleNode : public FilledVectorNode
+{
+ public:
+ static void registerType();
+
+ CircleNode(const ArgList& args);
+ virtual ~CircleNode();
+
+ const glm::vec2& getPos() const;
+ void setPos(const glm::vec2& pt);
+
+ float getR() const;
+ void setR(float r);
+
+ float getTexCoord1() const;
+ void setTexCoord1(float tc);
+
+ float getTexCoord2() const;
+ void setTexCoord2(float tc);
+
+ void getElementsByPos(const glm::vec2& pos, std::vector<NodePtr>& pElements);
+ virtual void calcVertexes(const VertexDataPtr& pVertexData, Pixel32 color);
+ virtual void calcFillVertexes(const VertexDataPtr& pVertexData, Pixel32 color);
+
+ private:
+ void appendCirclePoint(const VertexDataPtr& pVertexData, const glm::vec2& iPt,
+ const glm::vec2& oPt, Pixel32 color, int& i, int& curVertex);
+ void appendFillCirclePoint(const VertexDataPtr& pVertexData,
+ const glm::vec2& curPt, const glm::vec2& minPt, const glm::vec2& maxPt,
+ Pixel32 color, int& curVertex);
+ int getNumCircumferencePoints();
+ void getEigthCirclePoints(std::vector<glm::vec2>& pts, float radius);
+ glm::vec2 getCirclePt(float angle, float radius);
+ glm::vec2 calcTexCoord(const glm::vec2& pt, const glm::vec2& minPt,
+ const glm::vec2& maxPt);
+
+ glm::vec2 m_Pos;
+ float m_Radius;
+ float m_TC1;
+ float m_TC2;
+};
+
+}
+
+#endif
+
diff --git a/src/player/Contact.cpp b/src/player/Contact.cpp
new file mode 100644
index 0000000..b80615a
--- /dev/null
+++ b/src/player/Contact.cpp
@@ -0,0 +1,239 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "Contact.h"
+
+#include "CursorEvent.h"
+#include "BoostPython.h"
+#include "Player.h"
+#include "PublisherDefinition.h"
+
+#include "../base/Exception.h"
+#include "../base/StringHelper.h"
+#include "../base/Logger.h"
+
+#include <iostream>
+
+using namespace std;
+
+namespace avg {
+
+int Contact::s_LastListenerID = 0;
+
+void Contact::registerType()
+{
+ PublisherDefinitionPtr pPubDef = PublisherDefinition::create("Contact");
+ pPubDef->addMessage("CURSOR_MOTION");
+ pPubDef->addMessage("CURSOR_UP");
+}
+
+Contact::Contact(CursorEventPtr pEvent)
+ : Publisher("Contact"),
+ m_bSendingEvents(false),
+ m_bCurListenerIsDead(false),
+ m_CursorID(pEvent->getCursorID()),
+ m_DistanceTravelled(0)
+{
+ m_Events.push_back(pEvent);
+}
+
+Contact::~Contact()
+{
+}
+
+int Contact::connectListener(PyObject* pMotionCallback, PyObject* pUpCallback)
+{
+ avgDeprecationWarning("1.8", "Contact.connectListener()", "Contact.subscribe()");
+ s_LastListenerID++;
+ pair<int, Listener> val =
+ pair<int, Listener>(s_LastListenerID, Listener(pMotionCallback, pUpCallback));
+ m_ListenerMap.insert(val);
+ return s_LastListenerID;
+}
+
+void Contact::disconnectListener(int id)
+{
+ avgDeprecationWarning("1.8", "Contact.disconnectListener()",
+ "Contact.unsubscribe()");
+ map<int, Listener>::iterator it = m_ListenerMap.find(id);
+ if (it == m_ListenerMap.end() || (m_CurListenerID == id && m_bCurListenerIsDead)) {
+ throw Exception(AVG_ERR_INVALID_ARGS,
+ "Contact.disconnectListener: id " + toString(id) + " is not connected.");
+ }
+ if (m_bSendingEvents && m_CurListenerID == id) {
+ m_bCurListenerIsDead = true;
+ } else {
+ m_ListenerMap.erase(it);
+ }
+}
+
+long long Contact::getAge() const
+{
+ return m_Events.back()->getWhen() - m_Events[0]->getWhen();
+}
+
+float Contact::getDistanceFromStart() const
+{
+ return glm::length(getMotionVec());
+}
+
+float Contact::getMotionAngle() const
+{
+ glm::vec2 motion = getMotionVec();
+ if (motion == glm::vec2(0,0)) {
+ return 0;
+ } else {
+ return getAngle(motion);
+ }
+}
+
+glm::vec2 Contact::getMotionVec() const
+{
+ return m_Events.back()->getPos() - m_Events[0]->getPos();
+}
+
+float Contact::getDistanceTravelled() const
+{
+ return m_DistanceTravelled;
+}
+
+vector<CursorEventPtr> Contact::getEvents() const
+{
+ return m_Events;
+}
+
+void Contact::addEvent(CursorEventPtr pEvent)
+{
+ pEvent->setCursorID(m_CursorID);
+ pEvent->setContact(boost::dynamic_pointer_cast<Contact>(shared_from_this()));
+ calcSpeed(pEvent, m_Events.back());
+ updateDistanceTravelled(m_Events.back(), pEvent);
+ m_Events.back()->removeBlob();
+ m_Events.back()->setNode(NodePtr());
+ m_Events.push_back(pEvent);
+}
+
+void Contact::sendEventToListeners(CursorEventPtr pCursorEvent)
+{
+ switch (pCursorEvent->getType()) {
+ case Event::CURSOR_DOWN:
+ break;
+ case Event::CURSOR_MOTION:
+ notifySubscribers("CURSOR_MOTION", pCursorEvent);
+ break;
+ case Event::CURSOR_UP:
+ notifySubscribers("CURSOR_UP", pCursorEvent);
+ removeSubscribers();
+ break;
+ default:
+ AVG_ASSERT_MSG(false, pCursorEvent->typeStr().c_str());
+ }
+ m_bSendingEvents = true;
+ AVG_ASSERT(pCursorEvent->getContact() == shared_from_this());
+ m_bCurListenerIsDead = false;
+ for (map<int, Listener>::iterator it = m_ListenerMap.begin();
+ it != m_ListenerMap.end();)
+ {
+ Listener listener = it->second;
+ m_CurListenerID = it->first;
+ m_bCurListenerIsDead = false;
+ switch (pCursorEvent->getType()) {
+ case Event::CURSOR_MOTION:
+ if (listener.m_pMotionCallback != Py_None) {
+ py::call<void>(listener.m_pMotionCallback, pCursorEvent);
+ }
+ break;
+ case Event::CURSOR_UP:
+ if (listener.m_pUpCallback != Py_None) {
+ py::call<void>(listener.m_pUpCallback, pCursorEvent);
+ }
+ break;
+ default:
+ AVG_ASSERT(false);
+ }
+ map<int, Listener>::iterator lastIt = it;
+ ++it;
+ if (m_bCurListenerIsDead) {
+ m_ListenerMap.erase(lastIt);
+ m_bCurListenerIsDead = false;
+ }
+ }
+ m_bSendingEvents = false;
+}
+
+int Contact::getID() const
+{
+ return m_CursorID;
+}
+
+void Contact::calcSpeed(CursorEventPtr pEvent, CursorEventPtr pOldEvent)
+{
+ if (pEvent->getSpeed() == glm::vec2(0,0)) {
+ glm::vec2 posDiff = pEvent->getPos() - pOldEvent->getPos();
+ long long timeDiff = pEvent->getWhen() - pOldEvent->getWhen();
+ if (timeDiff != 0) {
+ pEvent->setSpeed(posDiff/float(timeDiff));
+ }
+ }
+}
+
+void Contact::updateDistanceTravelled(CursorEventPtr pEvent1, CursorEventPtr pEvent2)
+{
+ float dist = glm::length(pEvent2->getPos() - pEvent1->getPos());
+ m_DistanceTravelled += dist;
+}
+
+void Contact::dumpListeners(string sFuncName)
+{
+ cerr << " " << sFuncName << ": ";
+ for (map<int, Listener>::iterator it = m_ListenerMap.begin();
+ it != m_ListenerMap.end(); ++it)
+ {
+ cerr << it->first << ", ";
+ }
+ cerr << endl;
+}
+
+Contact::Listener::Listener(PyObject * pMotionCallback, PyObject * pUpCallback)
+{
+ Py_INCREF(pMotionCallback);
+ m_pMotionCallback = pMotionCallback;
+ Py_INCREF(pUpCallback);
+ m_pUpCallback = pUpCallback;
+}
+
+Contact::Listener::Listener(const Listener& other)
+{
+ Py_INCREF(other.m_pMotionCallback);
+ m_pMotionCallback = other.m_pMotionCallback;
+ Py_INCREF(other.m_pUpCallback);
+ m_pUpCallback = other.m_pUpCallback;
+}
+
+Contact::Listener::~Listener()
+{
+ Py_DECREF(m_pMotionCallback);
+ Py_DECREF(m_pUpCallback);
+}
+
+
+}
+
diff --git a/src/player/Contact.h b/src/player/Contact.h
new file mode 100644
index 0000000..846b422
--- /dev/null
+++ b/src/player/Contact.h
@@ -0,0 +1,96 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _Contact_H_
+#define _Contact_H_
+
+#include "Publisher.h"
+
+#include "../base/GLMHelper.h"
+
+#include <boost/shared_ptr.hpp>
+#include <boost/weak_ptr.hpp>
+
+// Python docs say python.h should be included before any standard headers (!)
+#include "WrapPython.h"
+
+#include <vector>
+#include <map>
+#include <set>
+#include <boost/enable_shared_from_this.hpp>
+
+namespace avg {
+
+class CursorEvent;
+typedef boost::shared_ptr<class CursorEvent> CursorEventPtr;
+class Contact;
+typedef boost::shared_ptr<class Contact> ContactPtr;
+
+class AVG_API Contact: public Publisher {
+public:
+ static void registerType();
+ Contact(CursorEventPtr pEvent);
+ virtual ~Contact();
+
+ int connectListener(PyObject* pMotionCallback, PyObject* pUpCallback);
+ void disconnectListener(int id);
+
+ long long getAge() const;
+ float getDistanceFromStart() const;
+ float getMotionAngle() const;
+ glm::vec2 getMotionVec() const;
+ float getDistanceTravelled() const;
+ std::vector<CursorEventPtr> getEvents() const;
+
+ void addEvent(CursorEventPtr pEvent);
+ void sendEventToListeners(CursorEventPtr pCursorEvent);
+
+ int getID() const;
+
+private:
+ void calcSpeed(CursorEventPtr pEvent, CursorEventPtr pOldEvent);
+ void updateDistanceTravelled(CursorEventPtr pEvent1, CursorEventPtr pEvent2);
+ void dumpListeners(std::string sFuncName);
+
+ std::vector<CursorEventPtr> m_Events;
+
+ bool m_bSendingEvents;
+
+ struct Listener
+ {
+ Listener(PyObject * pMotionCallback, PyObject * pUpCallback);
+ Listener(const Listener& other);
+ ~Listener();
+ PyObject* m_pMotionCallback;
+ PyObject* m_pUpCallback;
+ };
+
+ static int s_LastListenerID;
+ std::map<int, Listener> m_ListenerMap;
+ int m_CurListenerID;
+ bool m_bCurListenerIsDead;
+ int m_CursorID;
+ float m_DistanceTravelled;
+};
+
+}
+
+#endif
diff --git a/src/player/CursorEvent.cpp b/src/player/CursorEvent.cpp
new file mode 100644
index 0000000..ee4ba92
--- /dev/null
+++ b/src/player/CursorEvent.cpp
@@ -0,0 +1,136 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+// Original author of this file is igor@c-base.org
+//
+
+#include "CursorEvent.h"
+
+#include "Node.h"
+#include "Contact.h"
+
+#include "../base/Exception.h"
+#include "../base/Logger.h"
+
+#include <iostream>
+
+using namespace std;
+
+namespace avg {
+
+CursorEvent::CursorEvent(int id, Type eventType, const IntPoint& position, Source source,
+ int when)
+ : Event(eventType, source, when),
+ m_Position(position),
+ m_ID(id),
+ m_Speed(0,0)
+{
+}
+
+CursorEvent::~CursorEvent()
+{
+}
+
+CursorEventPtr CursorEvent::cloneAs(Type eventType) const
+{
+ CursorEventPtr pClone(new CursorEvent(*this));
+ pClone->m_Type = eventType;
+ return pClone;
+}
+
+void CursorEvent::setPos(const glm::vec2& pos)
+{
+ m_Position = IntPoint(pos);
+}
+
+glm::vec2 CursorEvent::getPos() const
+{
+ return glm::vec2(m_Position);
+}
+
+int CursorEvent::getXPosition() const
+{
+ return m_Position.x;
+}
+
+int CursorEvent::getYPosition() const
+{
+ return m_Position.y;
+}
+
+void CursorEvent::setCursorID(int id)
+{
+ m_ID = id;
+}
+
+int CursorEvent::getCursorID() const
+{
+ return m_ID;
+}
+
+void CursorEvent::setNode(NodePtr pNode)
+{
+ m_pNode = pNode;
+}
+
+NodePtr CursorEvent::getNode() const
+{
+ return m_pNode;
+}
+
+void CursorEvent::setSpeed(glm::vec2 speed)
+{
+ m_Speed = speed;
+}
+
+const glm::vec2& CursorEvent::getSpeed() const
+{
+ return m_Speed;
+}
+
+void CursorEvent::setContact(ContactPtr pContact)
+{
+ m_pContact = pContact;
+}
+
+ContactPtr CursorEvent::getContact() const
+{
+ return m_pContact.lock();
+}
+
+bool operator ==(const CursorEvent& event1, const CursorEvent& event2)
+{
+ return (event1.m_Position == event2.m_Position &&
+ event1.getWhen() == event2.getWhen());
+}
+
+void CursorEvent::trace()
+{
+ string sType = typeStr();
+ if (!m_pNode) {
+ AVG_TRACE(Logger::category::EVENTS, Logger::severity::DEBUG, sType);
+ } else {
+ AVG_TRACE(Logger::category::EVENTS, Logger::severity::DEBUG,
+ m_pNode->getID()+", "+sType);
+ }
+}
+
+}
+
diff --git a/src/player/CursorEvent.h b/src/player/CursorEvent.h
new file mode 100644
index 0000000..e84272a
--- /dev/null
+++ b/src/player/CursorEvent.h
@@ -0,0 +1,87 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+// Original author of this file is igor@c-base.org
+//
+
+#ifndef _CursorEvent_h_
+#define _CursorEvent_h_
+
+#include "../api.h"
+#include "Event.h"
+
+#include "../base/GLMHelper.h"
+
+#include <boost/shared_ptr.hpp>
+#include <boost/weak_ptr.hpp>
+
+namespace avg {
+
+const int MOUSECURSORID=-1;
+
+class AVG_API CursorEvent;
+typedef boost::shared_ptr<class CursorEvent> CursorEventPtr;
+
+class AVG_API Contact;
+typedef boost::shared_ptr<class Contact> ContactPtr;
+typedef boost::weak_ptr<class Contact> ContactWeakPtr;
+
+class Node;
+typedef boost::shared_ptr<class Node> NodePtr;
+typedef boost::weak_ptr<class Node> NodeWeakPtr;
+
+class AVG_API CursorEvent: public Event
+{
+ public:
+ CursorEvent(int id, Type eventType, const IntPoint& position, Source source,
+ int when=-1);
+ virtual ~CursorEvent();
+ virtual CursorEventPtr cloneAs(Type eventType) const;
+ void setPos(const glm::vec2& pos);
+ glm::vec2 getPos() const;
+ int getXPosition() const;
+ int getYPosition() const;
+ void setCursorID(int id);
+ int getCursorID() const;
+ void setNode(NodePtr pNode);
+ NodePtr getNode() const;
+ void setSpeed(glm::vec2 speed);
+ virtual const glm::vec2& getSpeed() const;
+
+ void setContact(ContactPtr pContact);
+ ContactPtr getContact() const;
+ virtual void removeBlob() {};
+
+ friend bool operator ==(const CursorEvent& event1, const CursorEvent& event2);
+ virtual void trace();
+
+ private:
+ IntPoint m_Position;
+ int m_ID;
+ ContactWeakPtr m_pContact;
+ NodePtr m_pNode;
+ glm::vec2 m_Speed;
+};
+
+bool operator ==(const CursorEvent& event1, const CursorEvent& event2);
+
+}
+
+#endif
diff --git a/src/player/CursorState.cpp b/src/player/CursorState.cpp
new file mode 100644
index 0000000..4408946
--- /dev/null
+++ b/src/player/CursorState.cpp
@@ -0,0 +1,58 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "CursorState.h"
+#include "Node.h"
+
+using namespace std;
+
+namespace avg {
+
+CursorState::CursorState(const CursorEventPtr pEvent,
+ const vector<NodePtr>& pNodes)
+ : m_pNodes(pNodes)
+{
+ m_pLastEvent = pEvent;
+}
+
+CursorState::~CursorState()
+{
+}
+
+void CursorState::setInfo(const CursorEventPtr pEvent,
+ const vector<NodePtr>& pNodes)
+{
+ m_pLastEvent = pEvent;
+ m_pNodes = pNodes;
+}
+
+const vector<NodePtr>& CursorState::getNodes() const
+{
+ return m_pNodes;
+}
+
+CursorEventPtr CursorState::getLastEvent() const
+{
+ return m_pLastEvent;
+}
+
+}
+
diff --git a/src/player/CursorState.h b/src/player/CursorState.h
new file mode 100644
index 0000000..8cec4c7
--- /dev/null
+++ b/src/player/CursorState.h
@@ -0,0 +1,56 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _CursorState_H_
+#define _CursorState_H_
+
+#include "../api.h"
+
+#include <vector>
+#include <boost/shared_ptr.hpp>
+
+namespace avg {
+
+class Node;
+typedef boost::shared_ptr<Node> NodePtr;
+class CursorEvent;
+typedef boost::shared_ptr<CursorEvent> CursorEventPtr;
+
+class AVG_API CursorState {
+public:
+ CursorState(const CursorEventPtr pEvent, const std::vector<NodePtr>& pNodes);
+ ~CursorState();
+
+ void setInfo(const CursorEventPtr pEvent, const std::vector<NodePtr>& pNodes);
+ const std::vector<NodePtr>& getNodes() const;
+ CursorEventPtr getLastEvent() const;
+
+private:
+ CursorState(const CursorState&);
+
+ std::vector<NodePtr> m_pNodes;
+ CursorEventPtr m_pLastEvent;
+};
+
+typedef boost::shared_ptr<CursorState> CursorStatePtr;
+
+}
+#endif
diff --git a/src/player/CurveNode.cpp b/src/player/CurveNode.cpp
new file mode 100644
index 0000000..7a685f5
--- /dev/null
+++ b/src/player/CurveNode.cpp
@@ -0,0 +1,183 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "CurveNode.h"
+
+#include "TypeDefinition.h"
+
+#include "../graphics/VertexArray.h"
+#include "../base/Exception.h"
+#include "../base/MathHelper.h"
+#include "../base/BezierCurve.h"
+
+#include <math.h>
+#include <float.h>
+#include <iostream>
+#include <sstream>
+
+using namespace std;
+
+namespace avg {
+
+void CurveNode::registerType()
+{
+ TypeDefinition def = TypeDefinition("curve", "vectornode",
+ ExportedObject::buildObject<CurveNode>)
+ .addArg(Arg<glm::vec2>("pos1", glm::vec2(0,0), false, offsetof(CurveNode, m_P1)))
+ .addArg(Arg<glm::vec2>("pos2", glm::vec2(0,0), false, offsetof(CurveNode, m_P2)))
+ .addArg(Arg<glm::vec2>("pos3", glm::vec2(0,0), false, offsetof(CurveNode, m_P3)))
+ .addArg(Arg<glm::vec2>("pos4", glm::vec2(0,0), false, offsetof(CurveNode, m_P4)))
+ .addArg(Arg<float>("texcoord1", 0, true, offsetof(CurveNode, m_TC1)))
+ .addArg(Arg<float>("texcoord2", 1, true, offsetof(CurveNode, m_TC2)));
+ TypeRegistry::get()->registerType(def);
+}
+
+CurveNode::CurveNode(const ArgList& args)
+ : VectorNode(args)
+{
+ args.setMembers(this);
+}
+
+CurveNode::~CurveNode()
+{
+}
+
+const glm::vec2& CurveNode::getPos1() const
+{
+ return m_P1;
+}
+
+void CurveNode::setPos1(const glm::vec2& pt)
+{
+ m_P1 = pt;
+ setDrawNeeded();
+}
+
+const glm::vec2& CurveNode::getPos2() const
+{
+ return m_P2;
+}
+
+void CurveNode::setPos2(const glm::vec2& pt)
+{
+ m_P2 = pt;
+ setDrawNeeded();
+}
+
+const glm::vec2& CurveNode::getPos3() const
+{
+ return m_P3;
+}
+
+void CurveNode::setPos3(const glm::vec2& pt)
+{
+ m_P3 = pt;
+ setDrawNeeded();
+}
+
+const glm::vec2& CurveNode::getPos4() const
+{
+ return m_P4;
+}
+
+void CurveNode::setPos4(const glm::vec2& pt)
+{
+ m_P4 = pt;
+ setDrawNeeded();
+}
+
+float CurveNode::getTexCoord1() const
+{
+ return m_TC1;
+}
+
+void CurveNode::setTexCoord1(float tc)
+{
+ m_TC1 = tc;
+ setDrawNeeded();
+}
+
+float CurveNode::getTexCoord2() const
+{
+ return m_TC2;
+}
+
+void CurveNode::setTexCoord2(float tc)
+{
+ m_TC2 = tc;
+ setDrawNeeded();
+}
+
+int CurveNode::getCurveLen() const
+{
+ // Calc. upper bound for spline length.
+ float curveLen = glm::length(m_P2-m_P1) + glm::length(m_P3 - m_P2)
+ + glm::length(m_P4-m_P3);
+ return int(curveLen);
+}
+
+glm::vec2 CurveNode::getPtOnCurve(float t) const
+{
+ BezierCurve curve(m_P1, m_P2, m_P3, m_P4);
+ return curve.interpolate(t);
+}
+
+void CurveNode::calcVertexes(const VertexDataPtr& pVertexData, Pixel32 color)
+{
+ updateLines();
+
+ pVertexData->appendPos(m_LeftCurve[0], glm::vec2(m_TC1,1), color);
+ pVertexData->appendPos(m_RightCurve[0], glm::vec2(m_TC2,0), color);
+ for (unsigned i = 0; i < m_LeftCurve.size()-1; ++i) {
+ float ratio = i/float(m_LeftCurve.size());
+ float tc = (1-ratio)*m_TC1+ratio*m_TC2;
+ pVertexData->appendPos(m_LeftCurve[i+1], glm::vec2(tc,1), color);
+ pVertexData->appendPos(m_RightCurve[i+1], glm::vec2(tc,0), color);
+ pVertexData->appendQuadIndexes((i+1)*2, i*2, (i+1)*2+1, i*2+1);
+ }
+}
+
+void CurveNode::updateLines()
+{
+ BezierCurve curve(m_P1, m_P2, m_P3, m_P4);
+
+ float len = float(getCurveLen());
+ m_LeftCurve.clear();
+ m_RightCurve.clear();
+ m_LeftCurve.reserve(int(len+1.5f));
+ m_RightCurve.reserve(int(len+1.5f));
+
+ for (unsigned i = 0; i < len; ++i) {
+ float t = i/len;
+ addLRCurvePoint(curve.interpolate(t), curve.getDeriv(t));
+ }
+ addLRCurvePoint(curve.interpolate(1), curve.getDeriv(1));
+}
+
+void CurveNode::addLRCurvePoint(const glm::vec2& pos, const glm::vec2& deriv)
+{
+ glm::vec2 m = glm::normalize(deriv);
+ glm::vec2 w = glm::vec2(m.y, -m.x)*float(getStrokeWidth()/2);
+ m_LeftCurve.push_back(pos-w);
+ m_RightCurve.push_back(pos+w);
+}
+
+}
diff --git a/src/player/CurveNode.h b/src/player/CurveNode.h
new file mode 100644
index 0000000..45efc05
--- /dev/null
+++ b/src/player/CurveNode.h
@@ -0,0 +1,80 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _CurveNode_H_
+#define _CurveNode_H_
+
+#include "../api.h"
+#include "VectorNode.h"
+
+#include "../graphics/Pixel32.h"
+
+namespace avg {
+
+class AVG_API CurveNode : public VectorNode
+{
+ public:
+ static void registerType();
+
+ CurveNode(const ArgList& args);
+ virtual ~CurveNode();
+
+ const glm::vec2& getPos1() const;
+ void setPos1(const glm::vec2& pt);
+
+ const glm::vec2& getPos2() const;
+ void setPos2(const glm::vec2& pt);
+
+ const glm::vec2& getPos3() const;
+ void setPos3(const glm::vec2& pt);
+
+ const glm::vec2& getPos4() const;
+ void setPos4(const glm::vec2& pt);
+
+ float getTexCoord1() const;
+ void setTexCoord1(float tc);
+
+ float getTexCoord2() const;
+ void setTexCoord2(float tc);
+
+ int getCurveLen() const;
+ glm::vec2 getPtOnCurve(float t) const;
+
+ virtual void calcVertexes(const VertexDataPtr& pVertexData, Pixel32 color);
+
+ private:
+ void updateLines();
+ void addLRCurvePoint(const glm::vec2& pos, const glm::vec2& deriv);
+ glm::vec2 m_P1;
+ glm::vec2 m_P2;
+ glm::vec2 m_P3;
+ glm::vec2 m_P4;
+ float m_TC1;
+ float m_TC2;
+
+ std::vector<glm::vec2> m_LeftCurve;
+ std::vector<glm::vec2> m_RightCurve;
+};
+
+}
+
+#endif
+
diff --git a/src/player/DisplayEngine.cpp b/src/player/DisplayEngine.cpp
new file mode 100644
index 0000000..7144e36
--- /dev/null
+++ b/src/player/DisplayEngine.cpp
@@ -0,0 +1,187 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "DisplayEngine.h"
+
+#include "../base/Logger.h"
+#include "../base/ScopeTimer.h"
+#include "../base/TimeSource.h"
+#include "../base/Exception.h"
+
+#include "../graphics/GLContext.h"
+#include "../graphics/Display.h"
+
+using namespace std;
+
+namespace avg {
+
+DisplayEngine::DisplayEngine()
+ : m_NumFrames(0),
+ m_VBRate(0),
+ m_Framerate(60),
+ m_bInitialized(false),
+ m_EffFramerate(0)
+{
+}
+
+DisplayEngine::~DisplayEngine()
+{
+}
+
+
+void DisplayEngine::initRender()
+{
+ m_NumFrames = 0;
+ m_FramesTooLate = 0;
+ m_TimeSpentWaiting = 0;
+ m_StartTime = TimeSource::get()->getCurrentMicrosecs();
+ m_LastFrameTime = m_StartTime;
+ m_bInitialized = true;
+ if (m_VBRate != 0) {
+ setVBlankRate(m_VBRate);
+ } else {
+ setFramerate(m_Framerate);
+ }
+}
+
+void DisplayEngine::deinitRender()
+{
+ AVG_TRACE(Logger::category::PROFILE, Logger::severity::INFO,
+ "Framerate statistics: ");
+ AVG_TRACE(Logger::category::PROFILE, Logger::severity::INFO,
+ " Total frames: " <<m_NumFrames);
+ float TotalTime = float(TimeSource::get()->getCurrentMicrosecs()
+ -m_StartTime)/1000000;
+ AVG_TRACE(Logger::category::PROFILE, Logger::severity::INFO,
+ " Total time: " << TotalTime << " seconds");
+ float actualFramerate = (m_NumFrames+1)/TotalTime;
+ AVG_TRACE(Logger::category::PROFILE, Logger::severity::INFO,
+ " Framerate achieved: " << actualFramerate);
+ AVG_TRACE(Logger::category::PROFILE, Logger::severity::INFO,
+ " Frames too late: " << m_FramesTooLate);
+ AVG_TRACE(Logger::category::PROFILE, Logger::severity::INFO,
+ " Percent of time spent waiting: "
+ << float (m_TimeSpentWaiting)/(10000*TotalTime));
+ if (m_Framerate != 0) {
+ AVG_TRACE(Logger::category::PROFILE, Logger::severity::INFO,
+ " Framerate goal was: " << m_Framerate);
+ if (m_Framerate*2 < actualFramerate && m_NumFrames > 10) {
+ AVG_LOG_WARNING("Actual framerate was a lot higher than framerate goal.\
+ Is vblank sync forced off?");
+ }
+ }
+ m_bInitialized = false;
+}
+
+void DisplayEngine::setFramerate(float rate)
+{
+ if (rate != 0 && m_bInitialized) {
+ GLContext::getMain()->initVBlank(0);
+ }
+ m_Framerate = rate;
+ m_VBRate = 0;
+}
+
+float DisplayEngine::getFramerate()
+{
+ return m_Framerate;
+}
+
+float DisplayEngine::getEffectiveFramerate()
+{
+ return m_EffFramerate;
+}
+
+void DisplayEngine::setVBlankRate(int rate)
+{
+ m_VBRate = rate;
+ if (m_bInitialized) {
+ bool bOK = GLContext::getMain()->initVBlank(rate);
+ m_Framerate = Display::get()->getRefreshRate()/m_VBRate;
+ if (!bOK || rate == 0) {
+ AVG_LOG_WARNING("Using framerate of " << m_Framerate <<
+ " instead of VBRate of " << m_VBRate);
+ m_VBRate = 0;
+ }
+ }
+}
+
+bool DisplayEngine::wasFrameLate()
+{
+ return m_bFrameLate;
+}
+
+static ProfilingZoneID WaitProfilingZone("Render - wait");
+
+void DisplayEngine::frameWait()
+{
+ ScopeTimer Timer(WaitProfilingZone);
+
+ m_NumFrames++;
+
+ m_FrameWaitStartTime = TimeSource::get()->getCurrentMicrosecs();
+ m_TargetTime = m_LastFrameTime+(long long)(1000000/m_Framerate);
+ m_bFrameLate = false;
+ if (m_VBRate == 0) {
+ if (m_FrameWaitStartTime <= m_TargetTime) {
+ long long WaitTime = (m_TargetTime-m_FrameWaitStartTime)/1000;
+ if (WaitTime > 5000) {
+ AVG_LOG_WARNING("DisplayEngine: waiting " << WaitTime << " ms.");
+ }
+ TimeSource::get()->sleepUntil(m_TargetTime/1000);
+ }
+ }
+}
+
+long long DisplayEngine::getDisplayTime()
+{
+ return (m_LastFrameTime-m_StartTime)/1000;
+}
+
+void DisplayEngine::checkJitter()
+{
+ if (m_LastFrameTime == 0) {
+ m_EffFramerate = 0;
+ } else {
+ long long CurIntervalTime = TimeSource::get()->getCurrentMicrosecs()
+ -m_LastFrameTime;
+ m_EffFramerate = 1000000.0f/CurIntervalTime;
+ }
+
+ long long frameTime = TimeSource::get()->getCurrentMicrosecs();
+ int maxDelay;
+ if (m_VBRate == 0) {
+ maxDelay = 2;
+ } else {
+ maxDelay = 6;
+ }
+ if ((frameTime - m_TargetTime)/1000 > maxDelay || m_bFrameLate) {
+ m_bFrameLate = true;
+ m_FramesTooLate++;
+ }
+
+ m_LastFrameTime = frameTime;
+ m_TimeSpentWaiting += m_LastFrameTime-m_FrameWaitStartTime;
+// cerr << m_LastFrameTime << ", m_FrameWaitStartTime=" << m_FrameWaitStartTime << endl;
+// cerr << m_TimeSpentWaiting << endl;
+}
+
+}
diff --git a/src/player/DisplayEngine.h b/src/player/DisplayEngine.h
new file mode 100644
index 0000000..9b53e45
--- /dev/null
+++ b/src/player/DisplayEngine.h
@@ -0,0 +1,93 @@
+
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _DisplayEngine_H_
+#define _DisplayEngine_H_
+
+#include "../api.h"
+#include "DisplayParams.h"
+
+#include "../graphics/Pixel32.h"
+#include "../graphics/Bitmap.h"
+
+#include "../base/Rect.h"
+
+#include <boost/shared_ptr.hpp>
+
+#include <string>
+
+namespace avg {
+
+class Region;
+
+class AVG_API DisplayEngine
+{
+ public:
+ DisplayEngine();
+ virtual ~DisplayEngine();
+ virtual void teardown() = 0;
+ void initRender();
+ void deinitRender();
+ void setFramerate(float rate);
+ float getFramerate();
+ float getEffectiveFramerate();
+ void setVBlankRate(int rate);
+ bool wasFrameLate();
+ virtual void setGamma(float Red, float Green, float Blue) = 0;
+ virtual void setMousePos(const IntPoint& pos) = 0;
+ virtual int getKeyModifierState() const = 0;
+
+ void frameWait();
+ virtual void swapBuffers() = 0;
+ void checkJitter();
+ long long getDisplayTime();
+
+ virtual IntPoint getSize() = 0;
+
+ virtual void showCursor(bool bShow) = 0;
+
+ virtual BitmapPtr screenshot(int buffer=0) = 0;
+
+ protected:
+
+ private:
+ int m_NumFrames;
+ int m_FramesTooLate;
+ long long m_StartTime;
+ long long m_TimeSpentWaiting;
+
+ // Per-Frame timings.
+ long long m_LastFrameTime;
+ long long m_FrameWaitStartTime;
+ long long m_TargetTime;
+ int m_VBRate;
+ float m_Framerate;
+ bool m_bInitialized;
+ bool m_bFrameLate;
+
+ float m_EffFramerate;
+};
+
+typedef boost::shared_ptr<DisplayEngine> DisplayEnginePtr;
+
+}
+
+#endif //_DisplayEngine_H_
diff --git a/src/player/DisplayParams.cpp b/src/player/DisplayParams.cpp
new file mode 100644
index 0000000..096da33
--- /dev/null
+++ b/src/player/DisplayParams.cpp
@@ -0,0 +1,64 @@
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "DisplayParams.h"
+
+#include <iostream>
+
+using namespace std;
+
+namespace avg {
+
+DisplayParams::DisplayParams()
+ : m_Pos(-1, -1),
+ m_Size(0, 0),
+ m_bFullscreen(false),
+ m_BPP(24),
+ m_WindowSize(0, 0),
+ m_bShowCursor(true),
+ m_VBRate(1),
+ m_Framerate(0),
+ m_bHasWindowFrame(true)
+{
+ m_Gamma[0] = -1.0f;
+ m_Gamma[1] = -1.0f;
+ m_Gamma[2] = -1.0f;
+}
+
+DisplayParams::~DisplayParams()
+{
+}
+
+void DisplayParams::dump() const
+{
+ cerr << "DisplayParams: " << endl;
+ cerr << " pos: " << m_Pos << endl;
+ cerr << " size: " << m_Size << endl;
+ cerr << " fullscreen: " << m_bFullscreen << endl;
+ cerr << " bpp: " << m_BPP << endl;
+ cerr << " window size: " << m_WindowSize << endl;
+ cerr << " show cursor: " << m_bShowCursor << endl;
+ cerr << " vbrate: " << m_VBRate << endl;
+ cerr << " framerate: " << m_Framerate << endl;
+ cerr << " has window frame: " << m_bHasWindowFrame << endl;
+}
+
+}
+
diff --git a/src/player/DisplayParams.h b/src/player/DisplayParams.h
new file mode 100644
index 0000000..178abbf
--- /dev/null
+++ b/src/player/DisplayParams.h
@@ -0,0 +1,52 @@
+
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _DisplayParams_H_
+#define _DisplayParams_H_
+
+#include "../api.h"
+
+#include "../base/GLMHelper.h"
+
+namespace avg {
+
+struct AVG_API DisplayParams {
+ DisplayParams();
+ virtual ~DisplayParams();
+
+ void dump() const;
+
+ IntPoint m_Pos;
+ IntPoint m_Size;
+ bool m_bFullscreen;
+ int m_BPP;
+ IntPoint m_WindowSize;
+ bool m_bShowCursor;
+ int m_VBRate;
+ float m_Framerate;
+ bool m_bHasWindowFrame;
+
+ float m_Gamma[3];
+};
+
+}
+
+#endif
diff --git a/src/player/DivNode.cpp b/src/player/DivNode.cpp
new file mode 100644
index 0000000..7397c10
--- /dev/null
+++ b/src/player/DivNode.cpp
@@ -0,0 +1,392 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "DivNode.h"
+#include "Player.h"
+#include "TypeDefinition.h"
+#include "Canvas.h"
+
+#include "../base/Exception.h"
+#include "../base/Logger.h"
+#include "../base/StringHelper.h"
+#include "../base/FileHelper.h"
+#include "../base/MathHelper.h"
+#include "../base/ObjectCounter.h"
+
+#include <iostream>
+#include <sstream>
+#include <limits>
+
+using namespace std;
+using namespace boost;
+
+namespace avg {
+
+
+void DivNode::registerType()
+{
+ string sChildArray[] = {"image", "div", "canvas", "words", "video", "camera",
+ "panoimage", "sound", "line", "rect", "curve", "polyline", "polygon",
+ "circle", "mesh"};
+ vector<string> sChildren = vectorFromCArray(
+ sizeof(sChildArray) / sizeof(*sChildArray), sChildArray);
+ TypeDefinition def = TypeDefinition("div", "areanode",
+ ExportedObject::buildObject<DivNode>)
+ .addChildren(sChildren)
+ .addArg(Arg<bool>("crop", false, false, offsetof(DivNode, m_bCrop)))
+ .addArg(Arg<UTF8String>("mediadir", "", false, offsetof(DivNode, m_sMediaDir)));
+ TypeRegistry::get()->registerType(def);
+}
+
+DivNode::DivNode(const ArgList& args)
+{
+ args.setMembers(this);
+ ObjectCounter::get()->incRef(&typeid(*this));
+}
+
+DivNode::~DivNode()
+{
+ for (unsigned i = 0; i < getNumChildren(); ++i) {
+ getChild(i)->removeParent();
+ }
+ ObjectCounter::get()->decRef(&typeid(*this));
+}
+
+void DivNode::connectDisplay()
+{
+ AreaNode::connectDisplay();
+ for (unsigned i = 0; i < getNumChildren(); ++i) {
+ getChild(i)->connectDisplay();
+ }
+}
+
+void DivNode::connect(CanvasPtr pCanvas)
+{
+ AreaNode::connect(pCanvas);
+ for (unsigned i = 0; i < getNumChildren(); ++i) {
+ getChild(i)->connect(pCanvas);
+ }
+}
+
+void DivNode::disconnect(bool bKill)
+{
+ for (unsigned i = 0; i < getNumChildren(); ++i) {
+ getChild(i)->disconnect(bKill);
+ }
+ AreaNode::disconnect(bKill);
+}
+
+glm::vec2 DivNode::getPivot() const
+{
+ glm::vec2 pivot = AreaNode::getPivot();
+ return pivot;
+}
+
+unsigned DivNode::getNumChildren()
+{
+ return m_Children.size();
+}
+
+const NodePtr& DivNode::getChild(unsigned i)
+{
+ if (i >= m_Children.size()) {
+ stringstream s;
+ s << "Index " << i << " is out of range in Node::getChild()";
+ throw(Exception(AVG_ERR_OUT_OF_RANGE, s.str()));
+ }
+ return m_Children[i];
+}
+
+void DivNode::appendChild(NodePtr pNewNode)
+{
+ insertChild(pNewNode, unsigned(m_Children.size()));
+}
+
+void DivNode::insertChildBefore(NodePtr pNewNode, NodePtr pOldChild)
+{
+ if (!pOldChild) {
+ throw Exception(AVG_ERR_NO_NODE,
+ getID()+"::insertChildBefore called without a node.");
+ }
+ unsigned i = indexOf(pOldChild);
+ insertChild(pNewNode, i);
+}
+
+void DivNode::insertChildAfter(NodePtr pNewNode, NodePtr pOldChild)
+{
+ if (!pOldChild) {
+ throw Exception(AVG_ERR_NO_NODE,
+ getID()+"::insertChildBefore called without a node.");
+ }
+ unsigned i = indexOf(pOldChild);
+ insertChild(pNewNode, i+1);
+}
+
+void DivNode::insertChild(NodePtr pChild, unsigned i)
+{
+ if (!pChild) {
+ throw Exception(AVG_ERR_NO_NODE,
+ getID()+"::insertChild called without a node.");
+ }
+ if (pChild->getState() == NS_CONNECTED || pChild->getState() == NS_CANRENDER) {
+ throw(Exception(AVG_ERR_ALREADY_CONNECTED,
+ "Can't connect node with id "+pChild->getID()+
+ ": already connected."));
+ }
+ if (getState() == NS_CONNECTED || getState() == NS_CANRENDER) {
+ getCanvas()->registerNode(pChild);
+ }
+ pChild->checkSetParentError(this);
+ if (!isChildTypeAllowed(pChild->getTypeStr())) {
+ throw(Exception(AVG_ERR_ALREADY_CONNECTED,
+ "Can't insert a node of type "+pChild->getTypeStr()+
+ " into a node of type "+getTypeStr()+"."));
+ }
+ if (i > m_Children.size()) {
+ throw(Exception(AVG_ERR_OUT_OF_RANGE,
+ pChild->getID()+"::insertChild: index out of bounds."));
+ }
+ std::vector<NodePtr>::iterator pos = m_Children.begin()+i;
+ m_Children.insert(pos, pChild);
+ try {
+ pChild->setParent(this, getState(), getCanvas());
+ } catch (Exception&) {
+ m_Children.erase(m_Children.begin()+i);
+ throw;
+ }
+ if (getState() == NS_CANRENDER) {
+ pChild->connectDisplay();
+ }
+}
+
+void DivNode::reorderChild(NodePtr pChild, unsigned j)
+{
+ if (j > m_Children.size()-1) {
+ throw(Exception(AVG_ERR_OUT_OF_RANGE,
+ getID()+"::reorderChild: index "+toString(j)+" out of bounds."));
+ }
+ int i = indexOf(pChild);
+ m_Children.erase(m_Children.begin()+i);
+ std::vector<NodePtr>::iterator pos = m_Children.begin()+j;
+ m_Children.insert(pos, pChild);
+}
+
+void DivNode::reorderChild(unsigned i, unsigned j)
+{
+ if (i > m_Children.size()-1 || j > m_Children.size()-1) {
+ throw(Exception(AVG_ERR_OUT_OF_RANGE,
+ getID()+"::reorderChild: index out of bounds."));
+ }
+ NodePtr pChild = getChild(i);
+ m_Children.erase(m_Children.begin()+i);
+ std::vector<NodePtr>::iterator pos = m_Children.begin()+j;
+ m_Children.insert(pos, pChild);
+}
+
+unsigned DivNode::indexOf(NodePtr pChild)
+{
+ if (!pChild) {
+ throw Exception(AVG_ERR_NO_NODE,
+ getID()+"::indexOf called without a node.");
+ }
+ for (unsigned i = 0; i < m_Children.size(); ++i) {
+ if (m_Children[i] == pChild) {
+ return i;
+ }
+ }
+ throw(Exception(AVG_ERR_OUT_OF_RANGE,
+ "indexOf: node '"+pChild->getID()+"' is not a child of node '"
+ +getID()+"'"));
+}
+
+void DivNode::removeChild(NodePtr pChild)
+{
+ removeChild(pChild, false);
+}
+
+void DivNode::removeChild(unsigned i)
+{
+ removeChild(i, false);
+}
+
+void DivNode::removeChild(NodePtr pChild, bool bKill)
+{
+ pChild->removeParent();
+ if (pChild->getState() != NS_UNCONNECTED) {
+ pChild->disconnect(bKill);
+ }
+ unsigned i = indexOf(pChild);
+ if (i > m_Children.size()-1) {
+ throw(Exception(AVG_ERR_OUT_OF_RANGE,
+ getID()+"::removeChild: index "+toString(i)+" out of bounds."));
+ }
+ m_Children.erase(m_Children.begin()+i);
+}
+
+void DivNode::removeChild(unsigned i, bool bKill)
+{
+ NodePtr pChild = getChild(i);
+ removeChild(pChild, bKill);
+}
+
+bool DivNode::getCrop() const
+{
+ return m_bCrop;
+}
+
+void DivNode::setCrop(bool bCrop)
+{
+ m_bCrop = bCrop;
+}
+
+const UTF8String& DivNode::getMediaDir() const
+{
+ return m_sMediaDir;
+}
+
+void DivNode::setMediaDir(const UTF8String& sMediaDir)
+{
+// avgDeprecationWarning("1.7", "DivNode.mediadir", "");
+ m_sMediaDir = sMediaDir;
+ checkReload();
+}
+
+void DivNode::getElementsByPos(const glm::vec2& pos, vector<NodePtr>& pElements)
+{
+ if (reactsToMouseEvents() &&
+ ((getSize() == glm::vec2(0,0) ||
+ (pos.x >= 0 && pos.y >= 0 && pos.x < getSize().x && pos.y < getSize().y))))
+ {
+ for (int i = getNumChildren()-1; i >= 0; i--) {
+ NodePtr pCurChild = getChild(i);
+ glm::vec2 relPos = pCurChild->toLocal(pos);
+ pCurChild->getElementsByPos(relPos, pElements);
+ if (!pElements.empty()) {
+ pElements.push_back(getSharedThis());
+ return;
+ }
+ }
+ // pos isn't in any of the children.
+ if (getSize() != glm::vec2(0,0)) {
+ // Explicit width/height given for div - div reacts on its own.
+ pElements.push_back(getSharedThis());
+ }
+ }
+}
+
+void DivNode::preRender(const VertexArrayPtr& pVA, bool bIsParentActive,
+ float parentEffectiveOpacity)
+{
+ Node::preRender(pVA, bIsParentActive, parentEffectiveOpacity);
+ if (getCrop() && getSize() != glm::vec2(0,0)) {
+ pVA->startSubVA(m_ClipVA);
+ glm::vec2 viewport = getSize();
+ m_ClipVA.appendPos(glm::vec2(0,0), glm::vec2(0,0), Pixel32(0,0,0,0));
+ m_ClipVA.appendPos(glm::vec2(0,viewport.y), glm::vec2(0,0), Pixel32(0,0,0,0));
+ m_ClipVA.appendPos(glm::vec2(viewport.x,0), glm::vec2(0,0), Pixel32(0,0,0,0));
+ m_ClipVA.appendPos(viewport, glm::vec2(0,0), Pixel32(0,0,0,0));
+ m_ClipVA.appendQuadIndexes(0, 1, 2, 3);
+ }
+ for (unsigned i = 0; i < getNumChildren(); i++) {
+ getChild(i)->preRender(pVA, bIsParentActive, getEffectiveOpacity());
+ }
+}
+
+void DivNode::render()
+{
+ const glm::mat4& transform = getTransform();
+ if (getCrop() && getSize() != glm::vec2(0,0)) {
+ getCanvas()->pushClipRect(transform, m_ClipVA);
+ }
+ for (unsigned i = 0; i < getNumChildren(); i++) {
+ getChild(i)->maybeRender(transform);
+ }
+ if (getCrop() && getSize() != glm::vec2(0,0)) {
+ getCanvas()->popClipRect(transform, m_ClipVA);
+ }
+}
+
+void DivNode::renderOutlines(const VertexArrayPtr& pVA, Pixel32 parentColor)
+{
+ Pixel32 effColor = getEffectiveOutlineColor(parentColor);
+ if (effColor != Pixel32(0,0,0,0)) {
+ glm::vec2 size = getSize();
+ if (size == glm::vec2(0,0)) {
+ glm::vec2 p0 = getAbsPos(glm::vec2(-4, 0.5));
+ glm::vec2 p1 = getAbsPos(glm::vec2(5, 0.5));
+ glm::vec2 p2 = getAbsPos(glm::vec2(0.5, -4));
+ glm::vec2 p3 = getAbsPos(glm::vec2(0.5, 5));
+ pVA->addLineData(effColor, p0, p1, 1);
+ pVA->addLineData(effColor, p2, p3, 1);
+ } else {
+ AreaNode::renderOutlines(pVA, parentColor);
+ }
+ }
+ for (unsigned i = 0; i < getNumChildren(); i++) {
+ getChild(i)->renderOutlines(pVA, effColor);
+ }
+}
+
+string DivNode::getEffectiveMediaDir()
+{
+ // TODO: There is no test for this function.
+ string sMediaDir = m_sMediaDir;
+ if (!isAbsPath(sMediaDir)) {
+ if (getParent()) {
+ sMediaDir = getParent()->getEffectiveMediaDir()+m_sMediaDir;
+ } else {
+ sMediaDir = Player::get()->getRootMediaDir()+m_sMediaDir;
+ }
+ }
+ if (sMediaDir[sMediaDir.length()-1] != '/') {
+ sMediaDir += '/';
+ }
+ return sMediaDir;
+}
+
+void DivNode::checkReload()
+{
+ for(unsigned i = 0; i < getNumChildren(); ++i) {
+ getChild(i)->checkReload();
+ }
+}
+
+string DivNode::dump(int indent)
+{
+ string dumpStr = AreaNode::dump () + "\n";
+ vector<NodePtr>::iterator it;
+ for(unsigned i = 0; i < getNumChildren(); ++i) {
+ getChild(i)->dump(indent+2)+"\n";
+ }
+ return dumpStr;
+}
+
+IntPoint DivNode::getMediaSize()
+{
+ return IntPoint(0, 0);
+}
+
+bool DivNode::isChildTypeAllowed(const string& sType)
+{
+ return getDefinition()->isChildAllowed(sType);
+}
+
+}
diff --git a/src/player/DivNode.h b/src/player/DivNode.h
new file mode 100644
index 0000000..080bf56
--- /dev/null
+++ b/src/player/DivNode.h
@@ -0,0 +1,94 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _DivNode_H_
+#define _DivNode_H_
+
+#include "../api.h"
+#include "AreaNode.h"
+
+#include "../graphics/SubVertexArray.h"
+
+#include "../base/UTF8String.h"
+
+#include <string>
+
+namespace avg {
+
+class AVG_API DivNode : public AreaNode
+{
+ public:
+ static void registerType();
+
+ DivNode(const ArgList& args);
+ virtual ~DivNode();
+ virtual void connectDisplay();
+ virtual void connect(CanvasPtr pCanvas);
+ virtual void disconnect(bool bKill);
+
+ unsigned getNumChildren();
+ const NodePtr& getChild(unsigned i);
+ void appendChild(NodePtr pNewNode);
+ void insertChildBefore(NodePtr pNewNode, NodePtr pOldChild);
+ void insertChildAfter(NodePtr pNewNode, NodePtr pOldChild);
+ virtual void insertChild(NodePtr pNewNode, unsigned i);
+ void reorderChild(NodePtr pNode, unsigned j);
+ void reorderChild(unsigned i, unsigned j);
+ unsigned indexOf(NodePtr pChild);
+ void removeChild(NodePtr pNode);
+ void removeChild(unsigned i);
+ void removeChild(NodePtr pNode, bool bKill);
+ void removeChild(unsigned i, bool bKill);
+
+ virtual glm::vec2 getPivot() const;
+
+ bool getCrop() const;
+ void setCrop(bool bCrop);
+
+ const UTF8String& getMediaDir() const;
+ void setMediaDir(const UTF8String& mediaDir);
+
+ void getElementsByPos(const glm::vec2& pos, std::vector<NodePtr>& pElements);
+ virtual void preRender(const VertexArrayPtr& pVA, bool bIsParentActive,
+ float parentEffectiveOpacity);
+ virtual void render();
+ virtual void renderOutlines(const VertexArrayPtr& pVA, Pixel32 color);
+
+ virtual std::string getEffectiveMediaDir();
+ virtual void checkReload();
+
+ virtual std::string dump(int indent = 0);
+ IntPoint getMediaSize();
+
+ private:
+ bool isChildTypeAllowed(const std::string& sType);
+
+ UTF8String m_sMediaDir;
+ bool m_bCrop;
+
+ SubVertexArray m_ClipVA;
+
+ std::vector<NodePtr> m_Children;
+};
+
+}
+
+#endif
diff --git a/src/player/Event.cpp b/src/player/Event.cpp
new file mode 100644
index 0000000..07d274b
--- /dev/null
+++ b/src/player/Event.cpp
@@ -0,0 +1,139 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "Event.h"
+#include "IInputDevice.h"
+#include "Player.h"
+
+#include "../base/TimeSource.h"
+#include "../base/Logger.h"
+#include "../base/ObjectCounter.h"
+
+#include <iostream>
+#include <sstream>
+
+using namespace std;
+
+namespace avg {
+
+int Event::s_CurCounter = 0;
+
+Event::Event(Type type, Source source, int when)
+ : m_Type(type),
+ m_Source(source),
+ m_pInputDevice()
+{
+ ObjectCounter::get()->incRef(&typeid(*this));
+ if (when == -1) {
+ m_When = Player::get()->getFrameTime();
+ } else {
+ m_When = when;
+ }
+ // Make sure two events with the same timestamp are ordered correctly.
+ s_CurCounter++;
+ m_Counter = s_CurCounter;
+}
+
+Event::Event(const Event& e)
+{
+ ObjectCounter::get()->incRef(&typeid(*this));
+ *this = e;
+}
+
+Event::~Event()
+{
+ ObjectCounter::get()->decRef(&typeid(*this));
+}
+
+long long Event::getWhen() const
+{
+ return m_When;
+}
+
+Event::Type Event::getType() const
+{
+ return m_Type;
+}
+
+Event::Source Event::getSource() const
+{
+ return m_Source;
+}
+
+IInputDevicePtr Event::getInputDevice() const
+{
+ return m_pInputDevice.lock();
+}
+
+bool Event::hasInputDevice() const
+{
+ return !m_pInputDevice.expired();
+}
+
+void Event::setInputDevice(IInputDevicePtr pInputDevice)
+{
+ m_pInputDevice = pInputDevice;
+}
+
+const std::string& Event::getInputDeviceName() const
+{
+ return m_pInputDevice.lock()->getName();
+}
+
+string Event::typeStr() const
+{
+ return typeStr(m_Type);
+}
+
+string Event::typeStr(Event::Type type)
+{
+ switch(type) {
+ case KEY_UP:
+ return "KEY_UP";
+ case KEY_DOWN:
+ return "KEY_DOWN";
+ case CURSOR_MOTION:
+ return "CURSOR_MOTION";
+ case CURSOR_UP:
+ return "CURSOR_UP";
+ case CURSOR_DOWN:
+ return "CURSOR_DOWN";
+ case CURSOR_OVER:
+ return "CURSOR_OVER";
+ case CURSOR_OUT:
+ return "CURSOR_OUT";
+ case CUSTOM_EVENT:
+ return "CUSTOM_EVENT";
+ case QUIT:
+ return "QUIT";
+ default:
+ return "UNKNOWN";
+ }
+
+}
+
+void Event::trace()
+{
+ string sType = typeStr();
+ AVG_TRACE(Logger::category::EVENTS,Logger::severity::INFO, sType);
+}
+
+}
diff --git a/src/player/Event.h b/src/player/Event.h
new file mode 100644
index 0000000..d1b6d9f
--- /dev/null
+++ b/src/player/Event.h
@@ -0,0 +1,99 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _Event_H_
+#define _Event_H_
+
+#include "../api.h"
+#include <functional>
+#include <string>
+#include <boost/shared_ptr.hpp>
+#include <boost/weak_ptr.hpp>
+
+#undef _POSIX_C_SOURCE
+
+namespace avg {
+
+class IInputDevice;
+typedef boost::shared_ptr<class IInputDevice> IInputDevicePtr;
+typedef boost::weak_ptr<class IInputDevice> IInputDeviceWeakPtr;
+
+class AVG_API Event {
+ public:
+ enum Type {
+ // XXX: Hack to make sure this enum can't be passed to Node.subscribe.
+ KEY_UP = 10000,
+ KEY_DOWN,
+ CURSOR_MOTION,
+ CURSOR_UP,
+ CURSOR_DOWN,
+ CURSOR_OVER,
+ CURSOR_OUT,
+ CUSTOM_EVENT,
+ QUIT
+ };
+ enum Source {MOUSE=1, TOUCH=2, TRACK=4, CUSTOM=8, NONE=16};
+
+ Event(Type type, Source source=NONE, int when=-1);
+ Event(const Event& e);
+ virtual ~Event();
+
+ long long getWhen() const;
+ Type getType() const;
+ Event::Source getSource() const;
+ IInputDevicePtr getInputDevice() const;
+ void setInputDevice(IInputDevicePtr pInputDevice);
+ bool hasInputDevice() const;
+ const std::string& getInputDeviceName() const;
+
+ std::string typeStr() const;
+ static std::string typeStr(Event::Type type);
+
+ virtual void trace();
+
+ friend struct isEventAfter;
+
+ protected:
+ Type m_Type;
+
+ private:
+ long long m_When;
+ int m_Counter;
+ Source m_Source;
+
+ IInputDeviceWeakPtr m_pInputDevice;
+ static int s_CurCounter;
+};
+
+typedef boost::shared_ptr<class Event> EventPtr;
+
+// Functor to compare two EventPtrs chronologically
+struct isEventAfter:std::binary_function<EventPtr, EventPtr, bool> {
+ bool operator()(const EventPtr & x, const EventPtr & y) const {
+ if (x->getWhen() == y->getWhen()) {
+ return x->m_Counter > y->m_Counter;
+ }
+ return x->getWhen() > y->getWhen();
+ }
+};
+
+}
+#endif //_Event_H_
diff --git a/src/player/EventDispatcher.cpp b/src/player/EventDispatcher.cpp
new file mode 100644
index 0000000..23caff2
--- /dev/null
+++ b/src/player/EventDispatcher.cpp
@@ -0,0 +1,184 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "EventDispatcher.h"
+#include "Event.h"
+#include "Player.h"
+#include "Contact.h"
+#include "CursorEvent.h"
+
+#include "../base/Exception.h"
+#include "../base/OSHelper.h"
+
+#include <string>
+
+using namespace std;
+using namespace boost;
+
+namespace avg {
+
+EventDispatcher::EventDispatcher(Player* pPlayer, bool bMouseEnabled)
+ : m_pPlayer(pPlayer),
+ m_NumMouseButtonsDown(0),
+ m_bMouseEnabled(bMouseEnabled)
+{
+}
+
+EventDispatcher::~EventDispatcher()
+{
+}
+
+void EventDispatcher::dispatch()
+{
+ vector<EventPtr> events;
+
+ for (unsigned int i = 0; i < m_InputDevices.size(); ++i) {
+ IInputDevicePtr pCurInputDevice = m_InputDevices[i];
+
+ vector<EventPtr> curEvents = pCurInputDevice->pollEvents();
+ vector<EventPtr>::iterator eventIt = curEvents.begin();
+ events.insert(events.end(), curEvents.begin(), curEvents.end());
+
+ for ( ; eventIt != curEvents.end(); eventIt++) {
+ (*eventIt)->setInputDevice(pCurInputDevice);
+ }
+ }
+
+ vector<EventPtr>::iterator it;
+ for (it = events.begin(); it != events.end(); ++it) {
+ EventPtr pEvent = *it;
+ bool bHookEatsEvent = processEventHook(pEvent);
+ if (!(!m_bMouseEnabled && pEvent->getSource() == Event::MOUSE) &&
+ !bHookEatsEvent) {
+ testAddContact(pEvent);
+ handleEvent(*it);
+ testRemoveContact(pEvent);
+ }
+ }
+}
+
+void EventDispatcher::addInputDevice(IInputDevicePtr pInputDevice)
+{
+ m_InputDevices.push_back(pInputDevice);
+}
+
+void EventDispatcher::sendEvent(EventPtr pEvent)
+{
+ handleEvent(pEvent);
+}
+
+void EventDispatcher::enableMouse(bool bEnabled)
+{
+ m_bMouseEnabled = bEnabled;
+}
+
+ContactPtr EventDispatcher::getContact(int id)
+{
+ std::map<int, ContactPtr>::iterator it = m_ContactMap.find(id);
+ if (it == m_ContactMap.end()) {
+ return ContactPtr();
+ } else {
+ return it->second;
+ }
+}
+
+void EventDispatcher::handleEvent(EventPtr pEvent)
+{
+ m_pPlayer->handleEvent(pEvent);
+}
+
+bool EventDispatcher::processEventHook(EventPtr pEvent)
+{
+ PyObject * pEventHook = m_pPlayer->getEventHook();
+ if (pEventHook != Py_None) {
+ // If the hook returns true, stop processing the event
+ if (py::call<bool>(pEventHook, pEvent)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+void EventDispatcher::testAddContact(EventPtr pEvent)
+{
+ ContactPtr pContact;
+ CursorEventPtr pCursorEvent = dynamic_pointer_cast<CursorEvent>(pEvent);
+ if (pCursorEvent) {
+ switch (pCursorEvent->getType()) {
+ case Event::CURSOR_DOWN:
+ if (pCursorEvent->getSource() == Event::MOUSE) {
+ m_NumMouseButtonsDown++;
+ if (m_NumMouseButtonsDown == 1) {
+ AVG_ASSERT(!getContact(MOUSECURSORID));
+ pContact = ContactPtr(new Contact(pCursorEvent));
+ m_ContactMap[MOUSECURSORID] = pContact;
+ }
+ } else {
+ pContact = ContactPtr(new Contact(pCursorEvent));
+ m_ContactMap[pCursorEvent->getCursorID()] = pContact;
+ }
+ break;
+ case Event::CURSOR_MOTION:
+ case Event::CURSOR_UP: {
+ pContact = getContact(pCursorEvent->getCursorID());
+ AVG_ASSERT(pContact || (
+ pCursorEvent->getSource() == Event::MOUSE &&
+ m_NumMouseButtonsDown == 0));
+ if (pContact) {
+ pContact->addEvent(pCursorEvent);
+ }
+ }
+ break;
+ case Event::CUSTOM_EVENT:
+ break;
+ default:
+ cerr << pCursorEvent->typeStr() << endl;
+ AVG_ASSERT(false);
+ break;
+ }
+ if (pContact) {
+ pCursorEvent->setContact(pContact);
+ }
+ }
+}
+
+void EventDispatcher::testRemoveContact(EventPtr pEvent)
+{
+ if (pEvent->getType() == Event::CURSOR_UP) {
+ if (pEvent->getSource() == Event::MOUSE) {
+ // The following if is only false if the CURSOR_DOWN wasn't registered because
+ // it was outside the application window (or on the window border).
+ if (m_NumMouseButtonsDown > 0) {
+ m_NumMouseButtonsDown--;
+ if (m_NumMouseButtonsDown == 0) {
+ int rc = m_ContactMap.erase(MOUSECURSORID);
+ AVG_ASSERT(rc == 1);
+ }
+ }
+ } else {
+ int rc = m_ContactMap.erase(
+ dynamic_pointer_cast<CursorEvent>(pEvent)->getCursorID());
+ AVG_ASSERT(rc == 1);
+ }
+ }
+}
+
+}
diff --git a/src/player/EventDispatcher.h b/src/player/EventDispatcher.h
new file mode 100644
index 0000000..19c3f78
--- /dev/null
+++ b/src/player/EventDispatcher.h
@@ -0,0 +1,68 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _EventDispatcher_h_
+#define _EventDispatcher_h_
+
+#include "../api.h"
+#include "IInputDevice.h"
+
+#include <vector>
+#include <map>
+
+namespace avg {
+
+class Event;
+typedef boost::shared_ptr<class Event> EventPtr;
+class Contact;
+typedef boost::shared_ptr<class Contact> ContactPtr;
+class Player;
+
+class AVG_API EventDispatcher {
+ public:
+ EventDispatcher(Player* pPlayer, bool bMouseEnabled);
+ virtual ~EventDispatcher();
+ void dispatch();
+
+ void addInputDevice(IInputDevicePtr pInputDevice);
+
+ void sendEvent(EventPtr pEvent);
+ void enableMouse(bool bEnabled);
+ ContactPtr getContact(int id);
+
+ private:
+ void handleEvent(EventPtr pEvent);
+ bool processEventHook(EventPtr pEvent);
+ void testAddContact(EventPtr pEvent);
+ void testRemoveContact(EventPtr pEvent);
+
+ std::vector<IInputDevicePtr> m_InputDevices;
+ Player* m_pPlayer;
+ std::map<int, ContactPtr> m_ContactMap;
+ int m_NumMouseButtonsDown;
+ bool m_bMouseEnabled;
+};
+typedef boost::shared_ptr<EventDispatcher> EventDispatcherPtr;
+
+}
+
+#endif
+
diff --git a/src/player/ExportedObject.cpp b/src/player/ExportedObject.cpp
new file mode 100644
index 0000000..b50a72a
--- /dev/null
+++ b/src/player/ExportedObject.cpp
@@ -0,0 +1,105 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "ExportedObject.h"
+#include "TypeDefinition.h"
+#include "Arg.h"
+
+#include "../base/Exception.h"
+#include "../base/Logger.h"
+#include "../base/ObjectCounter.h"
+
+#include <string>
+
+using namespace std;
+
+namespace avg {
+
+ExportedObject::ExportedObject()
+ : m_pSelf(0)
+{
+ ObjectCounter::get()->incRef(&typeid(*this));
+}
+
+ExportedObject::ExportedObject(const ExportedObject& other)
+ : m_pSelf(0)
+{
+ AVG_ASSERT(!other.m_pSelf);
+ m_pDefinition = other.m_pDefinition;
+ ObjectCounter::get()->incRef(&typeid(*this));
+}
+
+ExportedObject::~ExportedObject()
+{
+ ObjectCounter::get()->decRef(&typeid(*this));
+}
+
+void ExportedObject::registerInstance(PyObject* pSelf)
+{
+ m_pSelf = pSelf;
+}
+
+ExportedObjectPtr ExportedObject::getSharedThis()
+{
+ // Just using shared_from_this causes strange behaviour when derived classes
+ // are written in python: The pointer returned by shared_from_this doesn't know
+ // about the python part of the object and cuts it off. Because of this, we remember
+ // a pointer to the python object in m_pSelf and use that to create a functioning
+ // and complete ExportedObjectPtr if there is a python derived class.
+ if (m_pSelf) {
+ return py::extract<ExportedObjectPtr>(m_pSelf);
+ } else {
+ return shared_from_this();
+ }
+}
+
+void ExportedObject::setTypeInfo(const TypeDefinition * pDefinition)
+{
+ m_pDefinition = pDefinition;
+}
+
+const TypeDefinition* ExportedObject::getDefinition() const
+{
+ return m_pDefinition;
+}
+
+string ExportedObject::getTypeStr() const
+{
+ return m_pDefinition->getName();
+}
+
+bool ExportedObject::operator ==(const ExportedObject& other) const
+{
+ return this == &other;
+}
+
+bool ExportedObject::operator !=(const ExportedObject& other) const
+{
+ return this != &other;
+}
+
+long ExportedObject::getHash() const
+{
+ return long(this);
+}
+
+
+}
diff --git a/src/player/ExportedObject.h b/src/player/ExportedObject.h
new file mode 100644
index 0000000..810e787
--- /dev/null
+++ b/src/player/ExportedObject.h
@@ -0,0 +1,73 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _ExportedObject_H_
+#define _ExportedObject_H_
+
+#include "../api.h"
+
+#include <boost/shared_ptr.hpp>
+#include <boost/enable_shared_from_this.hpp>
+
+// Python docs say python.h should be included before any standard headers (!)
+#include "WrapPython.h"
+
+namespace avg {
+
+class TypeDefinition;
+class ArgList;
+
+class ExportedObject;
+typedef boost::shared_ptr<ExportedObject> ExportedObjectPtr;
+
+class AVG_API ExportedObject: public boost::enable_shared_from_this<ExportedObject>
+{
+ public:
+ ExportedObject();
+ ExportedObject(const ExportedObject& other);
+ virtual ~ExportedObject()=0;
+
+ void registerInstance(PyObject* pSelf);
+ ExportedObjectPtr getSharedThis();
+
+ template<class Type>
+ static ExportedObjectPtr buildObject(const ArgList& Args)
+ {
+ return ExportedObjectPtr(new Type(Args));
+ }
+ virtual void setTypeInfo(const TypeDefinition * pDefinition);
+
+ virtual void setArgs(const ArgList& args) {};
+ std::string getTypeStr() const;
+ virtual const TypeDefinition* getDefinition() const;
+
+ bool operator ==(const ExportedObject& other) const;
+ bool operator !=(const ExportedObject& other) const;
+ long getHash() const;
+
+ private:
+ const TypeDefinition* m_pDefinition;
+ PyObject* m_pSelf;
+};
+
+}
+
+#endif
diff --git a/src/player/FXNode.cpp b/src/player/FXNode.cpp
new file mode 100644
index 0000000..9aa2fde
--- /dev/null
+++ b/src/player/FXNode.cpp
@@ -0,0 +1,117 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "FXNode.h"
+#include "Player.h"
+
+#include "../base/ObjectCounter.h"
+#include "../graphics/GLContext.h"
+
+namespace avg {
+
+using namespace std;
+
+FXNode::FXNode(bool bSupportsGLES)
+ : m_Size(0, 0),
+ m_bSupportsGLES(bSupportsGLES),
+ m_bDirty(true)
+{
+ ObjectCounter::get()->incRef(&typeid(*this));
+}
+
+FXNode::~FXNode()
+{
+ ObjectCounter::get()->decRef(&typeid(*this));
+}
+
+void FXNode::connect()
+{
+ checkGLES();
+ if (m_Size != IntPoint(0,0)) {
+ m_pFilter = createFilter(m_Size);
+ }
+}
+
+void FXNode::disconnect()
+{
+ m_pFilter = GPUFilterPtr();
+}
+
+void FXNode::setSize(const IntPoint& newSize)
+{
+ if (newSize != m_Size) {
+ m_Size = newSize;
+ if (m_pFilter) {
+ m_pFilter = createFilter(m_Size);
+ }
+ }
+}
+
+void FXNode::apply(GLTexturePtr pSrcTex)
+{
+ // blt overwrites everything, so no glClear necessary before.
+ GLContext::getMain()->setBlendMode(GLContext::BLEND_COPY);
+ m_pFilter->apply(pSrcTex);
+}
+
+GLTexturePtr FXNode::getTex()
+{
+ return m_pFilter->getDestTex();
+}
+
+BitmapPtr FXNode::getImage()
+{
+ return m_pFilter->getImage();
+}
+
+FRect FXNode::getRelDestRect() const
+{
+ return m_pFilter->getRelDestRect();
+}
+
+bool FXNode::isDirty() const
+{
+ return m_bDirty;
+}
+
+void FXNode::resetDirty()
+{
+ m_bDirty = false;
+}
+
+FBOPtr FXNode::getFBO()
+{
+ return m_pFilter->getFBO();
+}
+
+void FXNode::setDirty()
+{
+ m_bDirty = true;
+}
+
+void FXNode::checkGLES() const
+{
+ if (!m_bSupportsGLES && GLContext::getCurrent()->isGLES()) {
+ throw Exception(AVG_ERR_UNSUPPORTED, "This effect is unsupported under OpenGL ES.");
+ }
+}
+
+}
diff --git a/src/player/FXNode.h b/src/player/FXNode.h
new file mode 100644
index 0000000..05a902e
--- /dev/null
+++ b/src/player/FXNode.h
@@ -0,0 +1,71 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _FXNode_H_
+#define _FXNode_H_
+
+#include "../api.h"
+
+#include "../graphics/GPUFilter.h"
+
+#include <boost/shared_ptr.hpp>
+
+namespace avg {
+
+class AVG_API FXNode {
+public:
+ FXNode(bool bSupportsGLES=true);
+ virtual ~FXNode();
+
+ virtual void connect();
+ virtual void disconnect();
+ virtual void setSize(const IntPoint& newSize);
+
+ virtual void apply(GLTexturePtr pSrcTex);
+
+ GLTexturePtr getTex();
+ BitmapPtr getImage();
+ FRect getRelDestRect() const;
+
+ bool isDirty() const;
+ void resetDirty();
+
+protected:
+ FBOPtr getFBO();
+ void setDirty();
+
+private:
+ virtual GPUFilterPtr createFilter(const IntPoint& size) = 0;
+ void checkGLES() const;
+
+ IntPoint m_Size;
+ GPUFilterPtr m_pFilter;
+
+ bool m_bSupportsGLES;
+ bool m_bDirty;
+};
+
+typedef boost::shared_ptr<FXNode> FXNodePtr;
+
+}
+
+#endif
+
diff --git a/src/player/FilledVectorNode.cpp b/src/player/FilledVectorNode.cpp
new file mode 100644
index 0000000..a804958
--- /dev/null
+++ b/src/player/FilledVectorNode.cpp
@@ -0,0 +1,215 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "FilledVectorNode.h"
+
+#include "TypeDefinition.h"
+#include "Image.h"
+#include "DivNode.h"
+
+#include "../base/ScopeTimer.h"
+#include "../base/Logger.h"
+#include "../base/Exception.h"
+
+using namespace std;
+using namespace boost;
+
+namespace avg {
+
+void FilledVectorNode::registerType()
+{
+ TypeDefinition def = TypeDefinition("filledvectornode", "vectornode")
+ .addArg(Arg<UTF8String>("filltexhref", "", false,
+ offsetof(FilledVectorNode, m_FillTexHRef)))
+ .addArg(Arg<float>("fillopacity", 0, false,
+ offsetof(FilledVectorNode, m_FillOpacity)))
+ .addArg(Arg<UTF8String>("fillcolor", "FFFFFF", false,
+ offsetof(FilledVectorNode, m_sFillColorName)))
+ .addArg(Arg<glm::vec2>("filltexcoord1", glm::vec2(0,0), false,
+ offsetof(FilledVectorNode, m_FillTexCoord1)))
+ .addArg(Arg<glm::vec2>("filltexcoord2", glm::vec2(1,1), false,
+ offsetof(FilledVectorNode, m_FillTexCoord2)))
+ ;
+ TypeRegistry::get()->registerType(def);
+}
+
+FilledVectorNode::FilledVectorNode(const ArgList& args)
+ : VectorNode(args),
+ m_pFillShape(new Shape(MaterialInfo(GL_REPEAT, GL_REPEAT, false)))
+{
+ m_FillTexHRef = args.getArgVal<UTF8String>("filltexhref");
+ setFillTexHRef(m_FillTexHRef);
+ m_sFillColorName = args.getArgVal<UTF8String>("fillcolor");
+ m_FillColor = colorStringToColor(m_sFillColorName);
+}
+
+FilledVectorNode::~FilledVectorNode()
+{
+}
+
+void FilledVectorNode::connectDisplay()
+{
+ VectorNode::connectDisplay();
+ m_FillColor = colorStringToColor(m_sFillColorName);
+ m_pFillShape->moveToGPU();
+ m_OldOpacity = -1;
+}
+
+void FilledVectorNode::disconnect(bool bKill)
+{
+ if (bKill) {
+ m_pFillShape->discard();
+ } else {
+ m_pFillShape->moveToCPU();
+ }
+ VectorNode::disconnect(bKill);
+}
+
+void FilledVectorNode::checkReload()
+{
+ Node::checkReload(m_FillTexHRef, m_pFillShape->getImage());
+ if (getState() == Node::NS_CANRENDER) {
+ m_pFillShape->moveToGPU();
+ setDrawNeeded();
+ }
+ VectorNode::checkReload();
+}
+
+const UTF8String& FilledVectorNode::getFillTexHRef() const
+{
+ return m_FillTexHRef;
+}
+
+void FilledVectorNode::setFillTexHRef(const UTF8String& href)
+{
+ m_FillTexHRef = href;
+ checkReload();
+ setDrawNeeded();
+}
+
+void FilledVectorNode::setFillBitmap(BitmapPtr pBmp)
+{
+ m_FillTexHRef = "";
+ m_pFillShape->setBitmap(pBmp);
+ setDrawNeeded();
+}
+
+const glm::vec2& FilledVectorNode::getFillTexCoord1() const
+{
+ return m_FillTexCoord1;
+}
+
+void FilledVectorNode::setFillTexCoord1(const glm::vec2& pt)
+{
+ m_FillTexCoord1 = pt;
+ setDrawNeeded();
+}
+
+const glm::vec2& FilledVectorNode::getFillTexCoord2() const
+{
+ return m_FillTexCoord2;
+}
+
+void FilledVectorNode::setFillTexCoord2(const glm::vec2& pt)
+{
+ m_FillTexCoord2 = pt;
+ setDrawNeeded();
+}
+
+float FilledVectorNode::getFillOpacity() const
+{
+ return m_FillOpacity;
+}
+
+void FilledVectorNode::setFillOpacity(float opacity)
+{
+ m_FillOpacity = opacity;
+ setDrawNeeded();
+}
+
+void FilledVectorNode::preRender(const VertexArrayPtr& pVA, bool bIsParentActive,
+ float parentEffectiveOpacity)
+{
+ Node::preRender(pVA, bIsParentActive, parentEffectiveOpacity);
+ float curOpacity = parentEffectiveOpacity*m_FillOpacity;
+
+ VertexDataPtr pShapeVD = m_pFillShape->getVertexData();
+ if (isDrawNeeded() || curOpacity != m_OldOpacity) {
+ pShapeVD->reset();
+ Pixel32 color = getFillColorVal();
+ calcFillVertexes(pShapeVD, color);
+ m_OldOpacity = curOpacity;
+ }
+ if (isVisible()) {
+ m_pFillShape->setVertexArray(pVA);
+ }
+ VectorNode::preRender(pVA, bIsParentActive, parentEffectiveOpacity);
+}
+
+static ProfilingZoneID RenderProfilingZone("FilledVectorNode::render");
+
+void FilledVectorNode::render()
+{
+ ScopeTimer Timer(RenderProfilingZone);
+ float curOpacity = getParent()->getEffectiveOpacity()*m_FillOpacity;
+ if (curOpacity > 0.01) {
+ m_pFillShape->draw(getTransform(), curOpacity);
+ }
+ VectorNode::render();
+}
+
+void FilledVectorNode::setFillColor(const UTF8String& sColor)
+{
+ if (m_sFillColorName != sColor) {
+ m_sFillColorName = sColor;
+ m_FillColor = colorStringToColor(m_sFillColorName);
+ setDrawNeeded();
+ }
+}
+
+const UTF8String& FilledVectorNode::getFillColor() const
+{
+ return m_sFillColorName;
+}
+
+Pixel32 FilledVectorNode::getFillColorVal() const
+{
+ return m_FillColor;
+}
+
+glm::vec2 FilledVectorNode::calcFillTexCoord(const glm::vec2& pt, const glm::vec2& minPt,
+ const glm::vec2& maxPt)
+{
+ glm::vec2 texPt;
+ texPt.x = (m_FillTexCoord2.x-m_FillTexCoord1.x)*(pt.x-minPt.x)/(maxPt.x-minPt.x)
+ +m_FillTexCoord1.x;
+ texPt.y = (m_FillTexCoord2.y-m_FillTexCoord1.y)*(pt.y-minPt.y)/(maxPt.y-minPt.y)
+ +m_FillTexCoord1.y;
+ return texPt;
+}
+
+bool FilledVectorNode::isVisible() const
+{
+ return getEffectiveActive() && (getEffectiveOpacity() > 0.01 ||
+ getParent()->getEffectiveOpacity()*m_FillOpacity > 0.01);
+}
+
+}
diff --git a/src/player/FilledVectorNode.h b/src/player/FilledVectorNode.h
new file mode 100644
index 0000000..ae98595
--- /dev/null
+++ b/src/player/FilledVectorNode.h
@@ -0,0 +1,88 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _FilledVectorNode_H_
+#define _FilledVectorNode_H_
+
+#include "../api.h"
+#include "VectorNode.h"
+
+#include "../base/UTF8String.h"
+
+namespace avg {
+
+class AVG_API FilledVectorNode : public VectorNode
+{
+ public:
+ static void registerType();
+
+ FilledVectorNode(const ArgList& args);
+ virtual ~FilledVectorNode();
+ virtual void connectDisplay();
+ virtual void disconnect(bool bKill);
+ virtual void checkReload();
+
+ const UTF8String& getFillTexHRef() const;
+ void setFillTexHRef(const UTF8String& href);
+ void setFillBitmap(BitmapPtr pBmp);
+
+ const glm::vec2& getFillTexCoord1() const;
+ void setFillTexCoord1(const glm::vec2& pt);
+ const glm::vec2& getFillTexCoord2() const;
+ void setFillTexCoord2(const glm::vec2& pt);
+
+ void setFillColor(const UTF8String& sColor);
+ const UTF8String& getFillColor() const;
+
+ float getFillOpacity() const;
+ void setFillOpacity(float opacity);
+
+ virtual void preRender(const VertexArrayPtr& pVA, bool bIsParentActive,
+ float parentEffectiveOpacity);
+ virtual void render();
+
+ virtual void calcFillVertexes(
+ const VertexDataPtr& pVertexData, Pixel32 color) = 0;
+
+ protected:
+ Pixel32 getFillColorVal() const;
+ glm::vec2 calcFillTexCoord(const glm::vec2& pt, const glm::vec2& minPt,
+ const glm::vec2& maxPt);
+ virtual bool isVisible() const;
+
+ private:
+ float m_OldOpacity;
+
+ UTF8String m_FillTexHRef;
+ glm::vec2 m_FillTexCoord1;
+ glm::vec2 m_FillTexCoord2;
+ ShapePtr m_pFillShape;
+ float m_FillOpacity;
+ UTF8String m_sFillColorName;
+ Pixel32 m_FillColor;
+};
+
+typedef boost::shared_ptr<FilledVectorNode> FilledVectorNodePtr;
+
+}
+
+#endif
+
diff --git a/src/player/FontStyle.cpp b/src/player/FontStyle.cpp
new file mode 100644
index 0000000..2980aa3
--- /dev/null
+++ b/src/player/FontStyle.cpp
@@ -0,0 +1,315 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "FontStyle.h"
+
+#include "../base/ObjectCounter.h"
+#include "../base/Exception.h"
+
+#include "TypeDefinition.h"
+#include "Arg.h"
+
+using namespace std;
+
+namespace avg {
+
+void FontStyle::registerType()
+{
+ TypeDefinition def = TypeDefinition("fontstyle", "",
+ ExportedObject::buildObject<FontStyle>)
+ .addArg(Arg<string>("font", "sans", false, offsetof(FontStyle, m_sName)))
+ .addArg(Arg<string>("variant", "", false, offsetof(FontStyle, m_sVariant)))
+ .addArg(Arg<string>("color", "FFFFFF", false, offsetof(FontStyle, m_sColorName)))
+ .addArg(Arg<float>("aagamma", 1.0f, false, offsetof(FontStyle, m_AAGamma)))
+ .addArg(Arg<float>("fontsize", 15, false, offsetof(FontStyle, m_Size)))
+ .addArg(Arg<int>("indent", 0, false, offsetof(FontStyle, m_Indent)))
+ .addArg(Arg<float>("linespacing", 0, false, offsetof(FontStyle, m_LineSpacing)))
+ .addArg(Arg<string>("alignment", "left"))
+ .addArg(Arg<string>("wrapmode", "word"))
+ .addArg(Arg<bool>("justify", false, false, offsetof(FontStyle, m_bJustify)))
+ .addArg(Arg<float>("letterspacing", 0, false,
+ offsetof(FontStyle, m_LetterSpacing)))
+ .addArg(Arg<bool>("hint", true, false, offsetof(FontStyle, m_bHint)))
+ .addArg(Arg<FontStylePtr>("basestyle", FontStylePtr()))
+ ;
+ TypeRegistry::get()->registerType(def);
+}
+
+FontStyle::FontStyle(const ArgList& args)
+{
+ args.setMembers(this);
+ setAlignment(args.getArgVal<string>("alignment"));
+ setWrapMode(args.getArgVal<string>("wrapmode"));
+ m_Color = colorStringToColor(m_sColorName);
+ if (args.getArgVal<FontStylePtr>("basestyle") != 0) {
+ applyBaseStyle(*(args.getArgVal<FontStylePtr>("basestyle")), args);
+ }
+}
+
+FontStyle::FontStyle()
+{
+ const ArgList& args = TypeRegistry::get()->getTypeDef("fontstyle").getDefaultArgs();
+ args.setMembers(this);
+ setAlignment(args.getArgVal<string>("alignment"));
+ setWrapMode(args.getArgVal<string>("wrapmode"));
+ m_Color = colorStringToColor(m_sColorName);
+}
+
+FontStyle::~FontStyle()
+{
+}
+
+template<class ATTR>
+void setDefaultedAttr(ATTR& member, const string& sName, const ArgList& args,
+ const ATTR& attr)
+{
+ if (args.getArg(sName)->isDefault()) {
+ member = attr;
+ }
+}
+
+void FontStyle::applyBaseStyle(const FontStyle& baseStyle, const ArgList& args)
+{
+ setDefaultedAttr(m_sName, "font", args, baseStyle.getFont());
+ setDefaultedAttr(m_sVariant, "variant", args, baseStyle.getFontVariant());
+ setDefaultedAttr(m_sColorName, "color", args, baseStyle.getColor());
+ m_Color = colorStringToColor(m_sColorName);
+ setDefaultedAttr(m_AAGamma, "aagamma", args, baseStyle.getAAGamma());
+ setDefaultedAttr(m_Size, "fontsize", args, baseStyle.getFontSize());
+ setDefaultedAttr(m_Indent, "indent", args, baseStyle.getIndent());
+ setDefaultedAttr(m_LineSpacing, "linespacing", args, baseStyle.getLineSpacing());
+ setDefaultedAttr(m_Alignment, "alignment", args, baseStyle.getAlignmentVal());
+ setDefaultedAttr(m_WrapMode, "wrapmode", args, baseStyle.getWrapModeVal());
+ setDefaultedAttr(m_bJustify, "justify", args, baseStyle.getJustify());
+ setDefaultedAttr(m_LetterSpacing, "letterspacing", args,
+ baseStyle.getLetterSpacing());
+ setDefaultedAttr(m_bHint, "hint", args, baseStyle.getHint());
+}
+
+template<class ARG>
+void setDefaultedArg(ARG& member, const string& sName, const ArgList& args)
+{
+ if (!args.getArg(sName)->isDefault()) {
+ member = args.getArgVal<ARG>(sName);
+ }
+}
+
+void FontStyle::setDefaultedArgs(const ArgList& args)
+{
+ // Warning: The ArgList here contains args that are for a different class originally,
+ // so the member offsets are wrong.
+ setDefaultedArg(m_sName, "font", args);
+ setDefaultedArg(m_sVariant, "variant", args);
+ setDefaultedArg(m_sColorName, "color", args);
+ setColor(m_sColorName);
+ setDefaultedArg(m_AAGamma, "aagamma", args);
+ setDefaultedArg(m_Size, "fontsize", args);
+ setDefaultedArg(m_Indent, "indent", args);
+ setDefaultedArg(m_LineSpacing, "linespacing", args);
+ string s = getAlignment();
+ setDefaultedArg(s, "alignment", args);
+ setAlignment(s);
+ s = getWrapMode();
+ setDefaultedArg(s, "wrapmode", args);
+ setWrapMode(s);
+ setDefaultedArg(m_bJustify, "justify", args);
+ setDefaultedArg(m_LetterSpacing, "letterspacing", args);
+ setDefaultedArg(m_bHint, "hint", args);
+}
+
+const std::string& FontStyle::getFont() const
+{
+ return m_sName;
+}
+
+void FontStyle::setFont(const string& sName)
+{
+ m_sName = sName;
+}
+
+const std::string& FontStyle::getFontVariant() const
+{
+ return m_sVariant;
+}
+
+void FontStyle::setFontVariant(const std::string& sVariant)
+{
+ m_sVariant = sVariant;
+}
+
+const std::string& FontStyle::getColor() const
+{
+ return m_sColorName;
+}
+
+void FontStyle::setColor(const string& sColor)
+{
+ m_sColorName = sColor;
+ m_Color = colorStringToColor(m_sColorName);
+}
+
+float FontStyle::getAAGamma() const
+{
+ return m_AAGamma;
+}
+
+void FontStyle::setAAGamma(float gamma)
+{
+ m_AAGamma = gamma;
+}
+
+float FontStyle::getFontSize() const
+{
+ return m_Size;
+}
+
+void FontStyle::setFontSize(float size)
+{
+ if (size <= 1) {
+ throw Exception(AVG_ERR_INVALID_ARGS, "Font size < 1 is illegal.");
+ }
+ m_Size = size;
+}
+
+int FontStyle::getIndent() const
+{
+ return m_Indent;
+}
+
+void FontStyle::setIndent(int indent)
+{
+ m_Indent = indent;
+}
+
+float FontStyle::getLineSpacing() const
+{
+ return m_LineSpacing;
+}
+
+void FontStyle::setLineSpacing(float lineSpacing)
+{
+ m_LineSpacing = lineSpacing;
+}
+
+string FontStyle::getAlignment() const
+{
+ switch(m_Alignment) {
+ case PANGO_ALIGN_LEFT:
+ return "left";
+ case PANGO_ALIGN_CENTER:
+ return "center";
+ case PANGO_ALIGN_RIGHT:
+ return "right";
+ default:
+ AVG_ASSERT(false);
+ return "";
+ }
+}
+
+void FontStyle::setAlignment(const string& sAlign)
+{
+ if (sAlign == "left") {
+ m_Alignment = PANGO_ALIGN_LEFT;
+ } else if (sAlign == "center") {
+ m_Alignment = PANGO_ALIGN_CENTER;
+ } else if (sAlign == "right") {
+ m_Alignment = PANGO_ALIGN_RIGHT;
+ } else {
+ throw(Exception(AVG_ERR_UNSUPPORTED,
+ "Alignment "+sAlign+" not supported."));
+ }
+}
+
+void FontStyle::setWrapMode(const string& sWrapMode)
+{
+ if (sWrapMode == "word") {
+ m_WrapMode = PANGO_WRAP_WORD;
+ } else if (sWrapMode == "char") {
+ m_WrapMode = PANGO_WRAP_CHAR;
+ } else if (sWrapMode == "wordchar") {
+ m_WrapMode = PANGO_WRAP_WORD_CHAR;
+ } else {
+ throw(Exception(AVG_ERR_UNSUPPORTED,
+ "FontStyle wrapping mode "+sWrapMode+" not supported."));
+ }
+}
+
+string FontStyle::getWrapMode() const
+{
+ switch(m_WrapMode) {
+ case PANGO_WRAP_WORD:
+ return "word";
+ case PANGO_WRAP_CHAR:
+ return "char";
+ case PANGO_WRAP_WORD_CHAR:
+ return "wordchar";
+ default:
+ AVG_ASSERT(false);
+ return "";
+ }
+}
+
+bool FontStyle::getJustify() const
+{
+ return m_bJustify;
+}
+
+void FontStyle::setJustify(bool bJustify)
+{
+ m_bJustify = bJustify;
+}
+
+float FontStyle::getLetterSpacing() const
+{
+ return m_LetterSpacing;
+}
+
+void FontStyle::setLetterSpacing(float letterSpacing)
+{
+ m_LetterSpacing = letterSpacing;
+}
+
+bool FontStyle::getHint() const
+{
+ return m_bHint;
+}
+
+void FontStyle::setHint(bool bHint)
+{
+ m_bHint = bHint;
+}
+
+PangoAlignment FontStyle::getAlignmentVal() const
+{
+ return m_Alignment;
+}
+
+PangoWrapMode FontStyle::getWrapModeVal() const
+{
+ return m_WrapMode;
+}
+
+Pixel32 FontStyle::getColorVal() const
+{
+ return m_Color;
+}
+
+}
diff --git a/src/player/FontStyle.h b/src/player/FontStyle.h
new file mode 100644
index 0000000..513aa14
--- /dev/null
+++ b/src/player/FontStyle.h
@@ -0,0 +1,114 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _FontStyle_H_
+#define _FontStyle_H_
+
+#include "../api.h"
+
+#include "ExportedObject.h"
+
+#include "../graphics/Pixel32.h"
+
+#include <pango/pango.h>
+#include <boost/shared_ptr.hpp>
+
+#include <string>
+
+namespace avg {
+
+class FontStyle;
+typedef boost::shared_ptr<class FontStyle> FontStylePtr;
+
+class AVG_API FontStyle: public ExportedObject
+{
+ public:
+ static void registerType();
+
+ FontStyle(const ArgList& args);
+ FontStyle();
+ virtual ~FontStyle();
+
+ void setDefaultedArgs(const ArgList& args);
+
+ const std::string& getFont() const;
+ void setFont(const std::string& sName);
+
+ const std::string& getFontVariant() const;
+ void setFontVariant(const std::string& sVariant);
+
+ const std::string& getColor() const;
+ void setColor(const std::string& sColor);
+
+ virtual float getAAGamma() const;
+ virtual void setAAGamma(float gamma);
+
+ float getFontSize() const;
+ void setFontSize(float size);
+
+ int getIndent() const;
+ void setIndent(int indent);
+
+ float getLineSpacing() const;
+ void setLineSpacing(float lineSpacing);
+
+ std::string getAlignment() const;
+ void setAlignment(const std::string& sAlignment);
+
+ std::string getWrapMode() const;
+ void setWrapMode(const std::string& sWrapMode);
+
+ bool getJustify() const;
+ void setJustify(bool bJustify);
+
+ float getLetterSpacing() const;
+ void setLetterSpacing(float letterSpacing);
+
+ bool getHint() const;
+ void setHint(bool bHint);
+
+ PangoAlignment getAlignmentVal() const;
+ PangoWrapMode getWrapModeVal() const;
+ Pixel32 getColorVal() const;
+
+ private:
+ void applyBaseStyle(const FontStyle& baseStyle, const ArgList& args);
+
+ std::string m_sName;
+ std::string m_sVariant;
+ std::string m_sColorName;
+ Pixel32 m_Color;
+ float m_AAGamma;
+ float m_Size;
+ int m_Indent;
+ float m_LineSpacing;
+ PangoAlignment m_Alignment;
+ PangoWrapMode m_WrapMode;
+ bool m_bJustify;
+ float m_LetterSpacing;
+ bool m_bHint;
+
+};
+
+typedef boost::shared_ptr<class FontStyle> FontStylePtr;
+
+}
+#endif
diff --git a/src/player/HueSatFXNode.cpp b/src/player/HueSatFXNode.cpp
new file mode 100644
index 0000000..b15f333
--- /dev/null
+++ b/src/player/HueSatFXNode.cpp
@@ -0,0 +1,153 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+
+#include "HueSatFXNode.h"
+
+#include "../base/ObjectCounter.h"
+#include "../base/Logger.h"
+
+#include "../graphics/BitmapLoader.h"
+
+#include<sstream>
+
+using namespace std;
+
+namespace avg {
+
+HueSatFXNode::HueSatFXNode(int hue, int saturation, int lightness, bool bColorize)
+ : FXNode(),
+ m_fHue(hue),
+ m_fLightnessOffset(lightness),
+ m_fSaturation(saturation),
+ m_bColorize(bColorize)
+{
+ ObjectCounter::get()->incRef(&typeid(*this));
+}
+
+HueSatFXNode::~HueSatFXNode()
+{
+ ObjectCounter::get()->decRef(&typeid(*this));
+}
+
+void HueSatFXNode::disconnect()
+{
+ filterPtr = GPUHueSatFilterPtr();
+ FXNode::disconnect();
+}
+
+int HueSatFXNode::getHue()
+{
+ if (m_bColorize) {
+ if (m_fHue < 0) {
+ return 360 + m_fHue;
+ }
+ return m_fHue;
+ }
+
+ if (m_fHue/180.0 > 1.0) {
+ return -360+m_fHue;
+ } else if (m_fHue/180.0 < -1.0) {
+ return 360+m_fHue;
+ }
+ return m_fHue;
+}
+
+int HueSatFXNode::getSaturation()
+{
+ return m_fSaturation;
+}
+
+int HueSatFXNode::getLightnessOffset()
+{
+ return m_fLightnessOffset;
+}
+
+bool HueSatFXNode::isColorizing()
+{
+ return m_bColorize;
+}
+
+void HueSatFXNode::setHue(int hue)
+{
+ m_fHue = hue % 360;
+ setFilterParams();
+}
+
+void HueSatFXNode::setSaturation(int saturation)
+{
+ if (m_bColorize) {
+ m_fSaturation = clamp(saturation, 0, 100);
+ } else {
+ m_fSaturation = clamp(saturation, -100, 100);
+ }
+ setFilterParams();
+}
+
+void HueSatFXNode::setLightnessOffset(int lightnessOffset)
+{
+ m_fLightnessOffset = clamp(lightnessOffset, -100, 100);
+ setFilterParams();
+}
+
+void HueSatFXNode::setColorizing(bool colorize)
+{
+ m_bColorize = colorize;
+ setFilterParams();
+}
+
+GPUFilterPtr HueSatFXNode::createFilter(const IntPoint& size)
+{
+ filterPtr = GPUHueSatFilterPtr(new GPUHueSatFilter(size, true, false));
+ setFilterParams();
+ return filterPtr;
+}
+
+void HueSatFXNode::setFilterParams()
+{
+ if (filterPtr) {
+ filterPtr->setParams(m_fHue, m_fSaturation, m_fLightnessOffset, m_bColorize);
+ setDirty();
+ }
+}
+
+std::string HueSatFXNode::toString()
+{
+ stringstream s;
+ s << "HueSatFXNode( Hue: " << m_fHue << ", Saturation: " << m_fSaturation <<
+ ", Lightness: " << m_fLightnessOffset << ", Colorize: " << m_bColorize <<
+ " )";
+ return s.str();
+}
+
+int HueSatFXNode::clamp(int val, int min, int max)
+{
+ int result = val;
+ if (val < min) {
+ result = min;
+ } else if (val > max) {
+ result = max;
+ }
+ return result;
+}
+
+}
+
diff --git a/src/player/HueSatFXNode.h b/src/player/HueSatFXNode.h
new file mode 100644
index 0000000..410a7ec
--- /dev/null
+++ b/src/player/HueSatFXNode.h
@@ -0,0 +1,72 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _HueSatFXNode_H_
+#define _HueSatFXNode_H_
+
+#include "../api.h"
+
+#include "FXNode.h"
+#include "../graphics/GPUHueSatFilter.h"
+
+#include <boost/shared_ptr.hpp>
+#include <boost/python.hpp>
+#include <string>
+
+using namespace std;
+
+namespace avg {
+
+class AVG_API HueSatFXNode : public FXNode {
+public:
+ HueSatFXNode(int hue=0, int saturation=0, int lightness=0, bool bColorize=false);
+ virtual ~HueSatFXNode();
+ virtual void disconnect();
+
+ void setHue(int hue);
+ void setSaturation(int saturation);
+ void setLightnessOffset(int lightnessOffset);
+ void setColorizing(bool colorize);
+ int getHue();
+ int getSaturation();
+ int getLightnessOffset();
+ bool isColorizing();
+
+ std::string toString();
+
+private:
+ virtual GPUFilterPtr createFilter(const IntPoint& size);
+ void setFilterParams();
+ int clamp(int val, int min, int max);
+
+ GPUHueSatFilterPtr filterPtr;
+
+ int m_fHue;
+ int m_fLightnessOffset;
+ int m_fSaturation;
+ bool m_bColorize;
+};
+
+typedef boost::shared_ptr<HueSatFXNode> HueSatFXNodePtr;
+}
+
+#endif
+
diff --git a/src/player/IBitmapLoadedListener.h b/src/player/IBitmapLoadedListener.h
new file mode 100644
index 0000000..da32f8b
--- /dev/null
+++ b/src/player/IBitmapLoadedListener.h
@@ -0,0 +1,44 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _IBitmapLoadedListener_H_
+#define _IBitmapLoadedListener_H_
+
+#include "../api.h"
+
+#include <boost/shared_ptr.hpp>
+
+namespace avg {
+
+class Bitmap;
+typedef boost::shared_ptr<Bitmap> BitmapPtr;
+class Exception;
+
+class AVG_API IBitmapLoadedListener {
+public:
+ virtual ~IBitmapLoadedListener() {};
+ virtual void onBitmapLoaded(BitmapPtr pBmp) = 0;
+ virtual void onBitmapLoadError(const Exception* e) = 0;
+};
+
+}
+
+#endif
diff --git a/src/player/IInputDevice.h b/src/player/IInputDevice.h
new file mode 100644
index 0000000..b155efe
--- /dev/null
+++ b/src/player/IInputDevice.h
@@ -0,0 +1,82 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _IInputDevice_H_
+#define _IInputDevice_H_
+
+#include "../api.h"
+#include "DivNode.h"
+#include <boost/shared_ptr.hpp>
+#include <vector>
+#include <string>
+
+#define EXTRACT_INPUTDEVICE_CLASSNAME( classType ) (#classType)
+
+namespace avg {
+
+class Event;
+typedef boost::shared_ptr<Event> EventPtr;
+typedef boost::shared_ptr<DivNode> DivNodePtr;
+
+class AVG_API IInputDevice {
+ public:
+ IInputDevice(const std::string& name,
+ const DivNodePtr& pEventReceiverNode=DivNodePtr())
+ : m_sName(name),
+ m_pEventReceiverNode(pEventReceiverNode)
+ {
+ }
+
+ virtual ~IInputDevice()
+ {
+ };
+
+ virtual void start()
+ {
+ };
+
+ virtual std::vector<EventPtr> pollEvents() = 0;
+
+ const DivNodePtr& getEventReceiverNode() const
+ {
+ return m_pEventReceiverNode;
+ }
+
+ void setEventReceiverNode(const DivNodePtr pEventReceiverNode)
+ {
+ m_pEventReceiverNode = pEventReceiverNode;
+ }
+
+ const std::string& getName() const
+ {
+ return m_sName;
+ }
+
+ private:
+ std::string m_sName;
+ DivNodePtr m_pEventReceiverNode;
+};
+
+typedef boost::shared_ptr<IInputDevice> IInputDevicePtr;
+
+}
+
+#endif
diff --git a/src/player/Image.cpp b/src/player/Image.cpp
new file mode 100644
index 0000000..5ac5fb9
--- /dev/null
+++ b/src/player/Image.cpp
@@ -0,0 +1,399 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "Image.h"
+
+#include "../base/Logger.h"
+#include "../base/Exception.h"
+#include "../base/ObjectCounter.h"
+
+#include "../graphics/Filterfliprgb.h"
+#include "../graphics/TextureMover.h"
+#include "../graphics/BitmapLoader.h"
+
+#include "OGLSurface.h"
+#include "OffscreenCanvas.h"
+
+#include <iostream>
+#include <sstream>
+
+using namespace std;
+
+namespace avg {
+
+Image::Image(OGLSurface * pSurface, const MaterialInfo& material)
+ : m_sFilename(""),
+ m_pSurface(pSurface),
+ m_State(CPU),
+ m_Source(NONE),
+ m_Material(material)
+{
+ ObjectCounter::get()->incRef(&typeid(*this));
+ assertValid();
+}
+
+Image::~Image()
+{
+ if (m_State == GPU && m_Source != NONE) {
+ m_pSurface->destroy();
+ }
+ ObjectCounter::get()->decRef(&typeid(*this));
+}
+
+void Image::moveToGPU()
+{
+ assertValid();
+ if (m_State == CPU) {
+ switch (m_Source) {
+ case FILE:
+ case BITMAP:
+ setupSurface();
+ break;
+ case SCENE:
+ m_pSurface->create(B8G8R8X8, m_pCanvas->getTex());
+ break;
+ case NONE:
+ break;
+ default:
+ AVG_ASSERT(false);
+ }
+ m_State = GPU;
+ }
+ assertValid();
+}
+
+void Image::moveToCPU()
+{
+ assertValid();
+ if (m_State == GPU) {
+ switch (m_Source) {
+ case FILE:
+ case BITMAP:
+ m_pBmp = m_pSurface->getTex()->moveTextureToBmp();
+ break;
+ case SCENE:
+ break;
+ case NONE:
+ break;
+ default:
+ AVG_ASSERT(false);
+ return;
+ }
+ m_State = CPU;
+ m_pSurface->destroy();
+ }
+ assertValid();
+}
+
+void Image::discard()
+{
+ assertValid();
+ setEmpty();
+ m_State = CPU;
+ assertValid();
+}
+
+void Image::setEmpty()
+{
+ assertValid();
+ if (m_State == GPU) {
+ m_pSurface->destroy();
+ }
+ changeSource(NONE);
+ assertValid();
+}
+
+void Image::setFilename(const std::string& sFilename, TextureCompression comp)
+{
+ assertValid();
+ AVG_TRACE(Logger::category::MEMORY, Logger::severity::INFO, "Loading " << sFilename);
+ BitmapPtr pBmp = loadBitmap(sFilename);
+ if (comp == TEXTURECOMPRESSION_B5G6R5 && pBmp->hasAlpha()) {
+ throw Exception(AVG_ERR_UNSUPPORTED,
+ "B5G6R5-compressed textures with an alpha channel are not supported.");
+ }
+ changeSource(FILE);
+ m_pBmp = pBmp;
+
+ m_sFilename = sFilename;
+
+ switch (comp) {
+ case TEXTURECOMPRESSION_B5G6R5:
+ m_pBmp = BitmapPtr(new Bitmap(pBmp->getSize(), B5G6R5, sFilename));
+ if (!BitmapLoader::get()->isBlueFirst()) {
+ FilterFlipRGB().applyInPlace(pBmp);
+ }
+ m_pBmp->copyPixels(*pBmp);
+ break;
+ case TEXTURECOMPRESSION_NONE:
+ break;
+ default:
+ assert(false);
+ }
+
+ if (m_State == GPU) {
+ m_pSurface->destroy();
+ setupSurface();
+ }
+ assertValid();
+}
+
+void Image::setBitmap(BitmapPtr pBmp, TextureCompression comp)
+{
+ assertValid();
+ if (!pBmp) {
+ throw Exception(AVG_ERR_UNSUPPORTED, "setBitmap(): bitmap must not be None!");
+ }
+ if (comp == TEXTURECOMPRESSION_B5G6R5 && pBmp->hasAlpha()) {
+ throw Exception(AVG_ERR_UNSUPPORTED,
+ "B5G6R5-compressed textures with an alpha channel are not supported.");
+ }
+ bool bSourceChanged = changeSource(BITMAP);
+ PixelFormat pf;
+ switch (comp) {
+ case TEXTURECOMPRESSION_NONE:
+ pf = pBmp->getPixelFormat();
+ break;
+ case TEXTURECOMPRESSION_B5G6R5:
+ pf = B5G6R5;
+ if (!BitmapLoader::get()->isBlueFirst()) {
+ FilterFlipRGB().applyInPlace(pBmp);
+ }
+ break;
+ default:
+ assert(false);
+ }
+ if (m_State == GPU) {
+ GLTexturePtr pTex = m_pSurface->getTex();
+ if (bSourceChanged || m_pSurface->getSize() != pBmp->getSize() ||
+ m_pSurface->getPixelFormat() != pf)
+ {
+ pTex = GLTexturePtr(new GLTexture(pBmp->getSize(), pf,
+ m_Material.getUseMipmaps(), 0, m_Material.getWrapSMode(),
+ m_Material.getWrapTMode()));
+ m_pSurface->create(pf, pTex);
+ }
+ TextureMoverPtr pMover = TextureMover::create(pBmp->getSize(), pf,
+ GL_STATIC_DRAW);
+ BitmapPtr pMoverBmp = pMover->lock();
+ pMoverBmp->copyPixels(*pBmp);
+ pMover->unlock();
+ pMover->moveToTexture(*pTex);
+ m_pBmp = BitmapPtr();
+ } else {
+ m_pBmp = BitmapPtr(new Bitmap(pBmp->getSize(), pf, ""));
+ m_pBmp->copyPixels(*pBmp);
+ }
+ assertValid();
+}
+
+void Image::setCanvas(OffscreenCanvasPtr pCanvas)
+{
+ assertValid();
+ if (m_Source == SCENE && pCanvas == m_pCanvas) {
+ return;
+ }
+ changeSource(SCENE);
+ m_pCanvas = pCanvas;
+ if (m_State == GPU) {
+ m_pSurface->create(B8G8R8X8, m_pCanvas->getTex());
+ }
+ assertValid();
+}
+
+OffscreenCanvasPtr Image::getCanvas() const
+{
+ return m_pCanvas;
+}
+
+const string& Image::getFilename() const
+{
+ return m_sFilename;
+}
+
+BitmapPtr Image::getBitmap()
+{
+ if (m_Source == NONE) {
+ return BitmapPtr();
+ } else {
+ switch (m_State) {
+ case CPU:
+ if (m_Source == SCENE) {
+ return BitmapPtr();
+ } else {
+ return BitmapPtr(new Bitmap(*m_pBmp));
+ }
+ case GPU:
+ return m_pSurface->getTex()->moveTextureToBmp();
+ default:
+ AVG_ASSERT(false);
+ return BitmapPtr();
+ }
+ }
+}
+
+IntPoint Image::getSize()
+{
+ if (m_Source == NONE) {
+ return IntPoint(0,0);
+ } else {
+ switch (m_State) {
+ case CPU:
+ if (m_Source == SCENE) {
+ return m_pCanvas->getSize();
+ } else {
+ return m_pBmp->getSize();
+ }
+ case GPU:
+ return m_pSurface->getSize();
+ default:
+ AVG_ASSERT(false);
+ return IntPoint(0,0);
+ }
+ }
+}
+
+PixelFormat Image::getPixelFormat()
+{
+ PixelFormat pf;
+ if (BitmapLoader::get()->isBlueFirst()) {
+ pf = B8G8R8X8;
+ } else {
+ pf = R8G8B8X8;
+ }
+ if (m_Source != NONE) {
+ switch (m_State) {
+ case CPU:
+ if (m_Source != SCENE) {
+ pf = m_pBmp->getPixelFormat();
+ }
+ case GPU:
+ pf = m_pSurface->getPixelFormat();
+ default:
+ AVG_ASSERT(false);
+ }
+ }
+ return pf;
+}
+
+OGLSurface* Image::getSurface()
+{
+ AVG_ASSERT(m_State == GPU);
+ return m_pSurface;
+}
+
+Image::State Image::getState()
+{
+ return m_State;
+}
+
+Image::Source Image::getSource()
+{
+ return m_Source;
+}
+
+Image::TextureCompression Image::string2compression(const string& s)
+{
+ if (s == "none") {
+ return Image::TEXTURECOMPRESSION_NONE;
+ } else if (s == "B5G6R5") {
+ return Image::TEXTURECOMPRESSION_B5G6R5;
+ } else {
+ throw(Exception(AVG_ERR_UNSUPPORTED,
+ "Image compression "+s+" not supported."));
+ }
+}
+
+string Image::compression2String(TextureCompression compression)
+{
+ switch(compression) {
+ case Image::TEXTURECOMPRESSION_NONE:
+ return "none";
+ case Image::TEXTURECOMPRESSION_B5G6R5:
+ return "B5G6R5";
+ default:
+ AVG_ASSERT(false);
+ return 0;
+ }
+}
+
+void Image::setupSurface()
+{
+ PixelFormat pf = m_pBmp->getPixelFormat();
+// cerr << "setupSurface: " << pf << endl;
+ GLTexturePtr pTex(new GLTexture(m_pBmp->getSize(), pf, m_Material.getUseMipmaps(),
+ 0, m_Material.getWrapSMode(), m_Material.getWrapTMode()));
+ m_pSurface->create(pf, pTex);
+ TextureMoverPtr pMover = TextureMover::create(m_pBmp->getSize(), pf, GL_STATIC_DRAW);
+ pMover->moveBmpToTexture(m_pBmp, *pTex);
+ m_pBmp = BitmapPtr();
+}
+
+bool Image::changeSource(Source newSource)
+{
+ if (newSource != m_Source) {
+ switch (m_Source) {
+ case NONE:
+ break;
+ case FILE:
+ case BITMAP:
+ if (m_State == CPU) {
+ m_pBmp = BitmapPtr();
+ }
+ m_sFilename = "";
+ break;
+ case SCENE:
+ m_pCanvas = OffscreenCanvasPtr();
+ break;
+ default:
+ AVG_ASSERT(false);
+ }
+ m_Source = newSource;
+ return true;
+ } else {
+ return false;
+ }
+}
+
+void Image::assertValid() const
+{
+ AVG_ASSERT(m_pSurface);
+ AVG_ASSERT((m_Source == FILE) == (m_sFilename != ""));
+ AVG_ASSERT((m_Source == SCENE) == bool(m_pCanvas));
+ switch (m_State) {
+ case CPU:
+ AVG_ASSERT((m_Source == FILE || m_Source == BITMAP) == bool(m_pBmp));
+ AVG_ASSERT(!(m_pSurface->isCreated()));
+ break;
+ case GPU:
+ AVG_ASSERT(!m_pBmp);
+ if (m_Source != NONE) {
+ AVG_ASSERT(m_pSurface->isCreated());
+ } else {
+ AVG_ASSERT(!m_pSurface->isCreated());
+ }
+ break;
+ default:
+ AVG_ASSERT(false);
+ }
+}
+
+}
diff --git a/src/player/Image.h b/src/player/Image.h
new file mode 100644
index 0000000..6b6ad83
--- /dev/null
+++ b/src/player/Image.h
@@ -0,0 +1,97 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _Image_H_
+#define _Image_H_
+
+#include "../api.h"
+
+#include "MaterialInfo.h"
+
+#include "../base/GLMHelper.h"
+#include "../graphics/Bitmap.h"
+
+#include <boost/shared_ptr.hpp>
+#include <string>
+
+namespace avg {
+
+class OGLSurface;
+class OffscreenCanvas;
+typedef boost::shared_ptr<OffscreenCanvas> OffscreenCanvasPtr;
+
+class AVG_API Image
+{
+ public:
+ enum State {CPU, GPU};
+ enum Source {NONE, FILE, BITMAP, SCENE};
+ enum TextureCompression {
+ TEXTURECOMPRESSION_NONE,
+ TEXTURECOMPRESSION_B5G6R5
+ };
+
+ Image(OGLSurface * pSurface, const MaterialInfo& material);
+ virtual ~Image();
+
+ virtual void moveToGPU();
+ virtual void moveToCPU();
+
+ void discard();
+ void setEmpty();
+ void setFilename(const std::string& sFilename,
+ TextureCompression comp = TEXTURECOMPRESSION_NONE);
+ void setBitmap(BitmapPtr pBmp,
+ TextureCompression comp = TEXTURECOMPRESSION_NONE);
+ void setCanvas(OffscreenCanvasPtr pCanvas);
+ OffscreenCanvasPtr getCanvas() const;
+ const std::string& getFilename() const;
+
+ BitmapPtr getBitmap();
+ IntPoint getSize();
+ PixelFormat getPixelFormat();
+ OGLSurface* getSurface();
+ State getState();
+ Source getSource();
+
+ static TextureCompression string2compression(const std::string& s);
+ static std::string compression2String(TextureCompression compression);
+
+ private:
+ void setupSurface();
+ bool changeSource(Source newSource);
+ void assertValid() const;
+
+ std::string m_sFilename;
+ BitmapPtr m_pBmp;
+ OGLSurface * m_pSurface;
+ OffscreenCanvasPtr m_pCanvas;
+
+ State m_State;
+ Source m_Source;
+ MaterialInfo m_Material;
+};
+
+typedef boost::shared_ptr<Image> ImagePtr;
+
+}
+
+#endif
+
diff --git a/src/player/ImageNode.cpp b/src/player/ImageNode.cpp
new file mode 100644
index 0000000..18543c2
--- /dev/null
+++ b/src/player/ImageNode.cpp
@@ -0,0 +1,241 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "ImageNode.h"
+
+#include "TypeDefinition.h"
+#include "OGLSurface.h"
+#include "Player.h"
+#include "OffscreenCanvas.h"
+
+#include "../base/Logger.h"
+#include "../base/ScopeTimer.h"
+#include "../base/XMLHelper.h"
+#include "../base/Exception.h"
+#include "../base/ObjectCounter.h"
+
+#include "../graphics/Filterfliprgb.h"
+
+#include <iostream>
+#include <sstream>
+
+using namespace std;
+
+namespace avg {
+
+void ImageNode::registerType()
+{
+ TypeDefinition def = TypeDefinition("image", "rasternode",
+ ExportedObject::buildObject<ImageNode>)
+ .addArg(Arg<UTF8String>("href", "", false, offsetof(ImageNode, m_href)))
+ .addArg(Arg<string>("compression", "none"));
+ TypeRegistry::get()->registerType(def);
+}
+
+ImageNode::ImageNode(const ArgList& args)
+ : m_Compression(Image::TEXTURECOMPRESSION_NONE)
+{
+ args.setMembers(this);
+ m_pImage = ImagePtr(new Image(getSurface(), getMaterial()));
+ m_Compression = Image::string2compression(args.getArgVal<string>("compression"));
+ setHRef(m_href);
+ ObjectCounter::get()->incRef(&typeid(*this));
+}
+
+ImageNode::~ImageNode()
+{
+ // XXX: The following assert checks that disconnect(true) has been called.
+ // However, if connect() has been called but rendering never started,
+ // disconnect isn't called either.
+// AVG_ASSERT(!m_pImage->getCanvas());
+ ObjectCounter::get()->decRef(&typeid(*this));
+}
+
+void ImageNode::connectDisplay()
+{
+ if (m_pImage->getSource() == Image::SCENE) {
+ checkCanvasValid(m_pImage->getCanvas());
+ }
+ m_pImage->moveToGPU();
+ RasterNode::connectDisplay();
+ if (m_pImage->getSource() == Image::SCENE) {
+ m_pImage->getCanvas()->addDependentCanvas(getCanvas());
+ }
+}
+
+void ImageNode::connect(CanvasPtr pCanvas)
+{
+ RasterNode::connect(pCanvas);
+ checkReload();
+}
+
+void ImageNode::disconnect(bool bKill)
+{
+ OffscreenCanvasPtr pCanvas = m_pImage->getCanvas();
+ if (pCanvas) {
+ pCanvas->removeDependentCanvas(getCanvas());
+ }
+ if (bKill) {
+ RasterNode::disconnect(bKill);
+ m_pImage = ImagePtr(new Image(getSurface(), getMaterial()));
+ m_href = "";
+ } else {
+ m_pImage->moveToCPU();
+ RasterNode::disconnect(bKill);
+ }
+}
+
+const UTF8String& ImageNode::getHRef() const
+{
+ return m_href;
+}
+
+void ImageNode::setHRef(const UTF8String& href)
+{
+ m_href = href;
+ if (m_pImage->getSource() == Image::SCENE && getState() == Node::NS_CANRENDER)
+ {
+ m_pImage->getCanvas()->removeDependentCanvas(getCanvas());
+ }
+ try {
+ if (href == "") {
+ m_pImage->setEmpty();
+ } else {
+ checkReload();
+ }
+ } catch (const Exception&) {
+ m_href = "";
+ m_pImage->setEmpty();
+ throw;
+ }
+}
+
+const string ImageNode::getCompression() const
+{
+ return Image::compression2String(m_Compression);
+}
+
+void ImageNode::setBitmap(BitmapPtr pBmp)
+{
+ if (m_pImage->getSource() == Image::SCENE && getState() == Node::NS_CANRENDER) {
+ m_pImage->getCanvas()->removeDependentCanvas(getCanvas());
+ }
+ m_pImage->setBitmap(pBmp, m_Compression);
+ if (getState() == Node::NS_CANRENDER) {
+ newSurface();
+ }
+ m_href = "";
+ setViewport(-32767, -32767, -32767, -32767);
+}
+
+static ProfilingZoneID PrerenderProfilingZone("ImageNode::prerender");
+
+void ImageNode::preRender(const VertexArrayPtr& pVA, bool bIsParentActive,
+ float parentEffectiveOpacity)
+{
+ ScopeTimer timer(PrerenderProfilingZone);
+ Node::preRender(pVA, bIsParentActive, parentEffectiveOpacity);
+ if (isVisible()) {
+ bool bHasCanvas = bool(m_pImage->getCanvas());
+ if (m_pImage->getSource() != Image::NONE) {
+ renderFX(getSize(), Pixel32(255, 255, 255, 255), bHasCanvas, bHasCanvas);
+ }
+ }
+ calcVertexArray(pVA);
+}
+
+static ProfilingZoneID RenderProfilingZone("ImageNode::render");
+
+void ImageNode::render()
+{
+ ScopeTimer Timer(RenderProfilingZone);
+ if (m_pImage->getSource() != Image::NONE) {
+ blt32(getTransform(), getSize(), getEffectiveOpacity(), getBlendMode(),
+ bool(m_pImage->getCanvas()));
+ }
+}
+
+IntPoint ImageNode::getMediaSize()
+{
+ return m_pImage->getSize();
+}
+
+void ImageNode::checkReload()
+{
+ if (isCanvasURL(m_href)) {
+ if (m_Compression != Image::TEXTURECOMPRESSION_NONE) {
+ throw Exception(AVG_ERR_UNSUPPORTED,
+ "Texture compression can't be used with canvas hrefs.");
+ }
+ OffscreenCanvasPtr pCanvas = Player::get()->getCanvasFromURL(m_href);
+ checkCanvasValid(pCanvas);
+ m_pImage->setCanvas(pCanvas);
+ if (getState() == NS_CANRENDER) {
+ pCanvas->addDependentCanvas(getCanvas());
+ }
+ newSurface();
+ } else {
+ bool bNewImage = Node::checkReload(m_href, m_pImage, m_Compression);
+ if (bNewImage) {
+ newSurface();
+ }
+ }
+ setViewport(-32767, -32767, -32767, -32767);
+ RasterNode::checkReload();
+}
+
+void ImageNode::getElementsByPos(const glm::vec2& pos, vector<NodePtr>& pElements)
+{
+ if (reactsToMouseEvents()) {
+ OffscreenCanvasPtr pCanvas = m_pImage->getCanvas();
+ if (pCanvas && pCanvas->getHandleEvents()) {
+ glm::vec2 nodeSize(getSize());
+ glm::vec2 canvasSize(pCanvas->getSize());
+ glm::vec2 localPos(pos.x*(canvasSize.x/nodeSize.x),
+ pos.y*(canvasSize.y/nodeSize.y));
+ pCanvas->getRootNode()->getElementsByPos(localPos, pElements);
+ } else {
+ RasterNode::getElementsByPos(pos, pElements);
+ }
+ }
+}
+
+BitmapPtr ImageNode::getBitmap()
+{
+ return m_pImage->getBitmap();
+}
+
+bool ImageNode::isCanvasURL(const std::string& sURL)
+{
+ return sURL.find("canvas:") == 0;
+}
+
+void ImageNode::checkCanvasValid(const CanvasPtr& pCanvas)
+{
+ if (pCanvas == getCanvas()) {
+ m_href = "";
+ m_pImage->setEmpty();
+ throw Exception(AVG_ERR_INVALID_ARGS,
+ "Circular dependency between canvases.");
+ }
+}
+
+}
diff --git a/src/player/ImageNode.h b/src/player/ImageNode.h
new file mode 100644
index 0000000..fce7d71
--- /dev/null
+++ b/src/player/ImageNode.h
@@ -0,0 +1,76 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _ImageNode_H_
+#define _ImageNode_H_
+
+#include "../api.h"
+#include "RasterNode.h"
+#include "Image.h"
+
+#include "../graphics/Bitmap.h"
+#include "../base/UTF8String.h"
+
+#include <string>
+
+namespace avg {
+
+class AVG_API ImageNode : public RasterNode
+{
+ public:
+ static void registerType();
+
+ ImageNode(const ArgList& args);
+ virtual ~ImageNode();
+ virtual void connectDisplay();
+ virtual void connect(CanvasPtr pCanvas);
+ virtual void disconnect(bool bKill);
+ virtual void checkReload();
+
+ const UTF8String& getHRef() const;
+ void setHRef(const UTF8String& href);
+ const std::string getCompression() const;
+ void setBitmap(BitmapPtr pBmp);
+
+ virtual void preRender(const VertexArrayPtr& pVA, bool bIsParentActive,
+ float parentEffectiveOpacity);
+ virtual void render();
+
+ void getElementsByPos(const glm::vec2& pos, std::vector<NodePtr>& pElements);
+
+ virtual BitmapPtr getBitmap();
+ virtual IntPoint getMediaSize();
+
+ private:
+ bool isCanvasURL(const std::string& sURL);
+ void checkCanvasValid(const CanvasPtr& pCanvas);
+
+ UTF8String m_href;
+ Image::TextureCompression m_Compression;
+ ImagePtr m_pImage;
+};
+
+typedef boost::shared_ptr<ImageNode> ImageNodePtr;
+
+}
+
+#endif
+
diff --git a/src/player/InvertFXNode.cpp b/src/player/InvertFXNode.cpp
new file mode 100644
index 0000000..c99cfa0
--- /dev/null
+++ b/src/player/InvertFXNode.cpp
@@ -0,0 +1,67 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "InvertFXNode.h"
+
+#include "../base/ObjectCounter.h"
+#include "../base/Logger.h"
+
+#include "../graphics/BitmapLoader.h"
+
+#include <sstream>
+
+using namespace std;
+
+namespace avg {
+
+InvertFXNode::InvertFXNode()
+ : FXNode()
+{
+ ObjectCounter::get()->incRef(&typeid(*this));
+}
+
+InvertFXNode::~InvertFXNode()
+{
+ ObjectCounter::get()->decRef(&typeid(*this));
+}
+
+void InvertFXNode::disconnect()
+{
+ filterPtr = GPUInvertFilterPtr();
+ FXNode::disconnect();
+}
+
+GPUFilterPtr InvertFXNode::createFilter(const IntPoint& size)
+{
+ filterPtr = GPUInvertFilterPtr(new GPUInvertFilter(size, true, false));
+ setDirty();
+ return filterPtr;
+}
+
+std::string InvertFXNode::toString()
+{
+ stringstream s;
+ s << "InvertFXNode" << std::endl;
+ return s.str();
+}
+
+}
+
diff --git a/src/player/InvertFXNode.h b/src/player/InvertFXNode.h
new file mode 100644
index 0000000..53a6973
--- /dev/null
+++ b/src/player/InvertFXNode.h
@@ -0,0 +1,57 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _InvertFXNode_H_
+#define _InvertFXNode_H_
+
+#include "../api.h"
+
+#include "FXNode.h"
+#include "../graphics/GPUInvertFilter.h"
+
+#include <boost/shared_ptr.hpp>
+#include <boost/python.hpp>
+#include <string>
+
+using namespace std;
+
+namespace avg {
+
+class AVG_API InvertFXNode : public FXNode {
+public:
+ InvertFXNode();
+ virtual ~InvertFXNode();
+ virtual void disconnect();
+
+ std::string toString();
+
+private:
+ virtual GPUFilterPtr createFilter(const IntPoint& size);
+
+ GPUInvertFilterPtr filterPtr;
+
+};
+
+typedef boost::shared_ptr<InvertFXNode> InvertFXNodePtr;
+} //end namespace avg
+
+#endif
+
diff --git a/src/player/KeyEvent.cpp b/src/player/KeyEvent.cpp
new file mode 100644
index 0000000..5ff8ce3
--- /dev/null
+++ b/src/player/KeyEvent.cpp
@@ -0,0 +1,80 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "KeyEvent.h"
+#include "../base/Logger.h"
+
+#include <iostream>
+#include <sstream>
+
+using namespace std;
+
+namespace avg {
+
+KeyEvent::KeyEvent(Type eventType, unsigned char scanCode, int keyCode,
+ const string& keyString, int unicode, int modifiers)
+ : Event(eventType)
+{
+ m_ScanCode = scanCode;
+ m_KeyCode = keyCode;
+ m_KeyString = keyString;
+ m_Unicode = unicode;
+ m_Modifiers = modifiers;
+}
+
+KeyEvent::~KeyEvent()
+{
+}
+
+unsigned char KeyEvent::getScanCode() const
+{
+ return m_ScanCode;
+}
+
+int KeyEvent::getKeyCode() const
+{
+ return m_KeyCode;
+}
+
+const std::string& KeyEvent::getKeyString() const
+{
+ return m_KeyString;
+}
+
+int KeyEvent::getUnicode() const
+{
+ return m_Unicode;
+}
+
+int KeyEvent::getModifiers() const
+{
+ return m_Modifiers;
+}
+
+void KeyEvent::trace()
+{
+ Event::trace();
+ AVG_TRACE(Logger::category::EVENTS, Logger::severity::DEBUG,
+ "Scancode: " << m_ScanCode << ", Keycode: " << m_KeyCode << ", KeyString: "
+ << m_KeyString << ", Modifiers: " << m_Modifiers);
+}
+
+}
diff --git a/src/player/KeyEvent.h b/src/player/KeyEvent.h
new file mode 100644
index 0000000..84ef8cf
--- /dev/null
+++ b/src/player/KeyEvent.h
@@ -0,0 +1,335 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _KeyEvent_h_
+#define _KeyEvent_h_
+
+#include "../api.h"
+#include "Event.h"
+
+#include <string>
+
+namespace avg {
+
+class AVG_API KeyEvent : public Event {
+ public:
+ KeyEvent(Type eventType, unsigned char scanCode, int keyCode,
+ const std::string& keyString, int unicode, int modifiers);
+ virtual ~KeyEvent();
+
+ unsigned char getScanCode() const;
+ int getKeyCode() const;
+ const std::string& getKeyString() const;
+ int getUnicode() const;
+ int getModifiers() const;
+
+ void trace();
+
+ private:
+ int m_ScanCode;
+ int m_KeyCode;
+ std::string m_KeyString;
+ int m_Unicode;
+ int m_Modifiers;
+};
+
+typedef boost::shared_ptr<class KeyEvent> KeyEventPtr;
+
+ namespace key {
+ // Plattform independent key codes and modifiers follow.
+ // The constants are borrowed from SDL.
+
+ // Enumeration of valid key mods (possibly OR'd together).
+ const long KEYMOD_NONE = 0x0000;
+ const long KEYMOD_LSHIFT= 0x0001;
+ const long KEYMOD_RSHIFT= 0x0002;
+ const long KEYMOD_LCTRL = 0x0040;
+ const long KEYMOD_RCTRL = 0x0080;
+ const long KEYMOD_LALT = 0x0100;
+ const long KEYMOD_RALT = 0x0200;
+ const long KEYMOD_LMETA = 0x0400;
+ const long KEYMOD_RMETA = 0x0800;
+ const long KEYMOD_NUM = 0x1000;
+ const long KEYMOD_CAPS = 0x2000;
+ const long KEYMOD_MODE = 0x4000;
+ const long KEYMOD_RESERVED = 0x8000;
+
+ const long KEYMOD_CTRL = (KEYMOD_LCTRL|KEYMOD_RCTRL);
+ const long KEYMOD_SHIFT = (KEYMOD_LSHIFT|KEYMOD_RSHIFT);
+ const long KEYMOD_ALT = (KEYMOD_LALT|KEYMOD_RALT);
+ const long KEYMOD_META = (KEYMOD_LMETA|KEYMOD_RMETA);
+
+
+ // Key syms. 'cleverly chosen to map to ASCII', sais SDL.
+ const long KEY_UNKNOWN = 0;
+ const long KEY_FIRST = 0;
+ const long KEY_BACKSPACE = 8;
+ const long KEY_TAB = 9;
+ const long KEY_CLEAR = 12;
+ const long KEY_RETURN = 13;
+ const long KEY_PAUSE = 19;
+ const long KEY_ESCAPE = 27;
+ const long KEY_SPACE = 32;
+ const long KEY_EXCLAIM = 33;
+ const long KEY_QUOTEDBL = 34;
+ const long KEY_HASH = 35;
+ const long KEY_DOLLAR = 36;
+ const long KEY_AMPERSAND = 38;
+ const long KEY_QUOTE = 39;
+ const long KEY_LEFTPAREN = 40;
+ const long KEY_RIGHTPAREN = 41;
+ const long KEY_ASTERISK = 42;
+ const long KEY_PLUS = 43;
+ const long KEY_COMMA = 44;
+ const long KEY_MINUS = 45;
+ const long KEY_PERIOD = 46;
+ const long KEY_SLASH = 47;
+ const long KEY_0 = 48;
+ const long KEY_1 = 49;
+ const long KEY_2 = 50;
+ const long KEY_3 = 51;
+ const long KEY_4 = 52;
+ const long KEY_5 = 53;
+ const long KEY_6 = 54;
+ const long KEY_7 = 55;
+ const long KEY_8 = 56;
+ const long KEY_9 = 57;
+ const long KEY_COLON = 58;
+ const long KEY_SEMICOLON = 59;
+ const long KEY_LESS = 60;
+ const long KEY_EQUALS = 61;
+ const long KEY_GREATER = 62;
+ const long KEY_QUESTION = 63;
+ const long KEY_AT = 64;
+ // Skip uppercase letters
+ const long KEY_LEFTBRACKET = 91;
+ const long KEY_BACKSLASH = 92;
+ const long KEY_RIGHTBRACKET = 93;
+ const long KEY_CARET = 94;
+ const long KEY_UNDERSCORE = 95;
+ const long KEY_BACKQUOTE = 96;
+ const long KEY_a = 97;
+ const long KEY_b = 98;
+ const long KEY_c = 99;
+ const long KEY_d = 100;
+ const long KEY_e = 101;
+ const long KEY_f = 102;
+ const long KEY_g = 103;
+ const long KEY_h = 104;
+ const long KEY_i = 105;
+ const long KEY_j = 106;
+ const long KEY_k = 107;
+ const long KEY_l = 108;
+ const long KEY_m = 109;
+ const long KEY_n = 110;
+ const long KEY_o = 111;
+ const long KEY_p = 112;
+ const long KEY_q = 113;
+ const long KEY_r = 114;
+ const long KEY_s = 115;
+ const long KEY_t = 116;
+ const long KEY_u = 117;
+ const long KEY_v = 118;
+ const long KEY_w = 119;
+ const long KEY_x = 120;
+ const long KEY_y = 121;
+ const long KEY_z = 122;
+ const long KEY_DELETE = 127;
+ // End of ASCII mapped keysyms
+
+ // International keyboard syms
+ const long KEY_WORLD_0 = 160; /* 0xA0 */
+ const long KEY_WORLD_1 = 161;
+ const long KEY_WORLD_2 = 162;
+ const long KEY_WORLD_3 = 163;
+ const long KEY_WORLD_4 = 164;
+ const long KEY_WORLD_5 = 165;
+ const long KEY_WORLD_6 = 166;
+ const long KEY_WORLD_7 = 167;
+ const long KEY_WORLD_8 = 168;
+ const long KEY_WORLD_9 = 169;
+ const long KEY_WORLD_10 = 170;
+ const long KEY_WORLD_11 = 171;
+ const long KEY_WORLD_12 = 172;
+ const long KEY_WORLD_13 = 173;
+ const long KEY_WORLD_14 = 174;
+ const long KEY_WORLD_15 = 175;
+ const long KEY_WORLD_16 = 176;
+ const long KEY_WORLD_17 = 177;
+ const long KEY_WORLD_18 = 178;
+ const long KEY_WORLD_19 = 179;
+ const long KEY_WORLD_20 = 180;
+ const long KEY_WORLD_21 = 181;
+ const long KEY_WORLD_22 = 182;
+ const long KEY_WORLD_23 = 183;
+ const long KEY_WORLD_24 = 184;
+ const long KEY_WORLD_25 = 185;
+ const long KEY_WORLD_26 = 186;
+ const long KEY_WORLD_27 = 187;
+ const long KEY_WORLD_28 = 188;
+ const long KEY_WORLD_29 = 189;
+ const long KEY_WORLD_30 = 190;
+ const long KEY_WORLD_31 = 191;
+ const long KEY_WORLD_32 = 192;
+ const long KEY_WORLD_33 = 193;
+ const long KEY_WORLD_34 = 194;
+ const long KEY_WORLD_35 = 195;
+ const long KEY_WORLD_36 = 196;
+ const long KEY_WORLD_37 = 197;
+ const long KEY_WORLD_38 = 198;
+ const long KEY_WORLD_39 = 199;
+ const long KEY_WORLD_40 = 200;
+ const long KEY_WORLD_41 = 201;
+ const long KEY_WORLD_42 = 202;
+ const long KEY_WORLD_43 = 203;
+ const long KEY_WORLD_44 = 204;
+ const long KEY_WORLD_45 = 205;
+ const long KEY_WORLD_46 = 206;
+ const long KEY_WORLD_47 = 207;
+ const long KEY_WORLD_48 = 208;
+ const long KEY_WORLD_49 = 209;
+ const long KEY_WORLD_50 = 210;
+ const long KEY_WORLD_51 = 211;
+ const long KEY_WORLD_52 = 212;
+ const long KEY_WORLD_53 = 213;
+ const long KEY_WORLD_54 = 214;
+ const long KEY_WORLD_55 = 215;
+ const long KEY_WORLD_56 = 216;
+ const long KEY_WORLD_57 = 217;
+ const long KEY_WORLD_58 = 218;
+ const long KEY_WORLD_59 = 219;
+ const long KEY_WORLD_60 = 220;
+ const long KEY_WORLD_61 = 221;
+ const long KEY_WORLD_62 = 222;
+ const long KEY_WORLD_63 = 223;
+ const long KEY_WORLD_64 = 224;
+ const long KEY_WORLD_65 = 225;
+ const long KEY_WORLD_66 = 226;
+ const long KEY_WORLD_67 = 227;
+ const long KEY_WORLD_68 = 228;
+ const long KEY_WORLD_69 = 229;
+ const long KEY_WORLD_70 = 230;
+ const long KEY_WORLD_71 = 231;
+ const long KEY_WORLD_72 = 232;
+ const long KEY_WORLD_73 = 233;
+ const long KEY_WORLD_74 = 234;
+ const long KEY_WORLD_75 = 235;
+ const long KEY_WORLD_76 = 236;
+ const long KEY_WORLD_77 = 237;
+ const long KEY_WORLD_78 = 238;
+ const long KEY_WORLD_79 = 239;
+ const long KEY_WORLD_80 = 240;
+ const long KEY_WORLD_81 = 241;
+ const long KEY_WORLD_82 = 242;
+ const long KEY_WORLD_83 = 243;
+ const long KEY_WORLD_84 = 244;
+ const long KEY_WORLD_85 = 245;
+ const long KEY_WORLD_86 = 246;
+ const long KEY_WORLD_87 = 247;
+ const long KEY_WORLD_88 = 248;
+ const long KEY_WORLD_89 = 249;
+ const long KEY_WORLD_90 = 250;
+ const long KEY_WORLD_91 = 251;
+ const long KEY_WORLD_92 = 252;
+ const long KEY_WORLD_93 = 253;
+ const long KEY_WORLD_94 = 254;
+ const long KEY_WORLD_95 = 255;
+
+ // Numeric keypad
+ const long KEY_KP0 = 256;
+ const long KEY_KP1 = 257;
+ const long KEY_KP2 = 258;
+ const long KEY_KP3 = 259;
+ const long KEY_KP4 = 260;
+ const long KEY_KP5 = 261;
+ const long KEY_KP6 = 262;
+ const long KEY_KP7 = 263;
+ const long KEY_KP8 = 264;
+ const long KEY_KP9 = 265;
+ const long KEY_KP_PERIOD = 266;
+ const long KEY_KP_DIVIDE = 267;
+ const long KEY_KP_MULTIPLY = 268;
+ const long KEY_KP_MINUS = 269;
+ const long KEY_KP_PLUS = 270;
+ const long KEY_KP_ENTER = 271;
+ const long KEY_KP_EQUALS = 272;
+
+ // Arrows + Home/End pad
+ const long KEY_UP = 273;
+ const long KEY_DOWN = 274;
+ const long KEY_RIGHT = 275;
+ const long KEY_LEFT = 276;
+ const long KEY_INSERT = 277;
+ const long KEY_HOME = 278;
+ const long KEY_END = 279;
+ const long KEY_PAGEUP = 280;
+ const long KEY_PAGEDOWN = 281;
+
+ // Function keys
+ const long KEY_F1 = 282;
+ const long KEY_F2 = 283;
+ const long KEY_F3 = 284;
+ const long KEY_F4 = 285;
+ const long KEY_F5 = 286;
+ const long KEY_F6 = 287;
+ const long KEY_F7 = 288;
+ const long KEY_F8 = 289;
+ const long KEY_F9 = 290;
+ const long KEY_F10 = 291;
+ const long KEY_F11 = 292;
+ const long KEY_F12 = 293;
+ const long KEY_F13 = 294;
+ const long KEY_F14 = 295;
+ const long KEY_F15 = 296;
+
+ // Key state modifier keys
+ const long KEY_NUMLOCK = 300;
+ const long KEY_CAPSLOCK = 301;
+ const long KEY_SCROLLOCK = 302;
+ const long KEY_RSHIFT = 303;
+ const long KEY_LSHIFT = 304;
+ const long KEY_RCTRL = 305;
+ const long KEY_LCTRL = 306;
+ const long KEY_RALT = 307;
+ const long KEY_LALT = 308;
+ const long KEY_RMETA = 309;
+ const long KEY_LMETA = 310;
+ const long KEY_LSUPER = 311; /* Left "Windows" key */
+ const long KEY_RSUPER = 312; /* Right "Windows" key */
+ const long KEY_MODE = 313; /* "Alt Gr" key */
+ const long KEY_COMPOSE = 314; /* Multi-key compose key */
+
+ // Miscellaneous function keys
+ const long KEY_HELP = 315;
+ const long KEY_PRINT = 316;
+ const long KEY_SYSREQ = 317;
+ const long KEY_BREAK = 318;
+ const long KEY_MENU = 319;
+ const long KEY_POWER = 320; /* Power Macintosh power key */
+ const long KEY_EURO = 321; /* Some european keyboards */
+ const long KEY_UNDO = 322; /* Atari keyboard has Undo */
+ // Add any other keys here
+ }
+
+}
+
+#endif
+
diff --git a/src/player/LibMTDevInputDevice.cpp b/src/player/LibMTDevInputDevice.cpp
new file mode 100644
index 0000000..edfd061
--- /dev/null
+++ b/src/player/LibMTDevInputDevice.cpp
@@ -0,0 +1,190 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "LibMTDevInputDevice.h"
+
+#include "TouchEvent.h"
+#include "Player.h"
+#include "AVGNode.h"
+#include "TouchStatus.h"
+
+#include "../base/Logger.h"
+#include "../base/ObjectCounter.h"
+#include "../base/Exception.h"
+#include "../base/OSHelper.h"
+
+#include <linux/input.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+extern "C" {
+#include <mtdev.h>
+#include <mtdev-mapping.h>
+}
+
+using namespace std;
+
+namespace avg {
+
+LibMTDevInputDevice::LibMTDevInputDevice()
+ : m_LastID(0),
+ m_pMTDevice(0)
+{
+}
+
+LibMTDevInputDevice::~LibMTDevInputDevice()
+{
+ if (m_pMTDevice) {
+ mtdev_close(m_pMTDevice);
+ delete m_pMTDevice;
+ }
+}
+
+void LibMTDevInputDevice::start()
+{
+ string sDevice("/dev/input/event3");
+ getEnv("AVG_LINUX_MULTITOUCH_DEVICE", sDevice);
+ m_DeviceFD = ::open(sDevice.c_str(), O_RDONLY | O_NONBLOCK);
+ if (m_DeviceFD == -1) {
+ throw Exception(AVG_ERR_MT_INIT,
+ string("Linux multitouch event source: Could not open device file '")+
+ sDevice+"'. "+strerror(errno)+".");
+ }
+ m_pMTDevice = new mtdev;
+ int err = mtdev_open(m_pMTDevice, m_DeviceFD);
+ if (err == -1) {
+ throw Exception(AVG_ERR_MT_INIT,
+ string("Linux multitouch event source: Could not open mtdev '")+
+ sDevice+"'. "+strerror(errno)+".");
+ }
+ input_absinfo* pAbsInfo;
+ pAbsInfo = &(m_pMTDevice->caps.abs[MTDEV_POSITION_X]);
+ m_Dimensions.tl.x = pAbsInfo->minimum;
+ m_Dimensions.br.x = pAbsInfo->maximum;
+ pAbsInfo = &(m_pMTDevice->caps.abs[MTDEV_POSITION_Y]);
+ m_Dimensions.tl.y = pAbsInfo->minimum;
+ m_Dimensions.br.y = pAbsInfo->maximum;
+
+ MultitouchInputDevice::start();
+ AVG_TRACE(Logger::category::CONFIG, Logger::severity::INFO,
+ "Linux MTDev Multitouch event source created.");
+}
+
+std::vector<EventPtr> LibMTDevInputDevice::pollEvents()
+{
+ struct input_event event;
+ static int curSlot = 0;
+
+ set<int> changedIDs;
+ while (mtdev_get(m_pMTDevice, m_DeviceFD, &event, 1) > 0) {
+ if (event.type == EV_SYN && event.code == SYN_REPORT) {
+// cerr << ">> SYN_REPORT" << endl;
+ processEvents(changedIDs);
+ changedIDs.clear();
+ } else if (event.type == EV_ABS && event.code == ABS_MT_SLOT) {
+// cerr << ">> slot " << event.value << endl;
+ curSlot = event.value;
+ } else {
+ TouchData* pTouch;
+ switch (event.code) {
+ case ABS_MT_TRACKING_ID:
+// cerr << ">> ABS_MT_TRACKING_ID: " << event.value << endl;
+ pTouch = &(m_Slots[curSlot]);
+ if (event.value == -1) {
+ TouchStatusPtr pTouchStatus = getTouchStatus(pTouch->id);
+// cerr << "up " << pTouch->id << endl;
+ if (pTouchStatus) {
+// cerr << " --> remove" << endl;
+ TouchEventPtr pOldEvent = pTouchStatus->getLastEvent();
+ TouchEventPtr pUpEvent =
+ boost::dynamic_pointer_cast<TouchEvent>(
+ pOldEvent->cloneAs(Event::CURSOR_UP));
+ pTouchStatus->pushEvent(pUpEvent);
+ removeTouchStatus(pTouch->id);
+ }
+ pTouch->id = -1;
+ } else {
+ pTouch->id = event.value;
+ changedIDs.insert(curSlot);
+ }
+ break;
+ case ABS_MT_POSITION_X:
+// cerr << ">> ABS_MT_POSITION_X: " << event.value << endl;
+ pTouch = &(m_Slots[curSlot]);
+ pTouch->pos.x = event.value;
+ changedIDs.insert(curSlot);
+ break;
+ case ABS_MT_POSITION_Y:
+// cerr << ">> ABS_MT_POSITION_Y: " << event.value << endl;
+ pTouch = &(m_Slots[curSlot]);
+ pTouch->pos.y = event.value;
+ changedIDs.insert(curSlot);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ return MultitouchInputDevice::pollEvents();
+}
+
+void LibMTDevInputDevice::processEvents(const set<int>& changedIDs)
+{
+ for (set<int>::iterator it = changedIDs.begin(); it != changedIDs.end(); ++it) {
+ map<int, TouchData>::iterator it2 = m_Slots.find(*it);
+ if (it2 != m_Slots.end()) {
+ const TouchData& touch = it2->second;
+// cerr << "slot: " << *it << ", id: " << touch.id << ", pos: " << touch.pos
+// << endl;
+// AVG_ASSERT(touch.pos.x != 0);
+ if (touch.id != -1) {
+ TouchStatusPtr pTouchStatus = getTouchStatus(touch.id);
+ if (!pTouchStatus) {
+ // Down
+ m_LastID++;
+ TouchEventPtr pEvent = createEvent(m_LastID, Event::CURSOR_DOWN,
+ touch.pos);
+// cerr << "down <" << touch.id << "> --> [" << m_LastID << "]" << endl;
+ addTouchStatus((long)touch.id, pEvent);
+ } else {
+// cerr << "move <" << touch.id << "> --> " << touch.pos << endl;
+ // Move
+ TouchEventPtr pEvent = createEvent(0, Event::CURSOR_MOTION,
+ touch.pos);
+ pTouchStatus->pushEvent(pEvent);
+ }
+ }
+ }
+ }
+}
+
+TouchEventPtr LibMTDevInputDevice::createEvent(int id, Event::Type type, IntPoint pos)
+{
+ glm::vec2 size(Player::get()->getScreenResolution());
+ glm::vec2 normPos(float(pos.x-m_Dimensions.tl.x)/m_Dimensions.width(),
+ float(pos.y-m_Dimensions.tl.y)/m_Dimensions.height());
+ IntPoint screenPos(int(normPos.x*size.x+0.5), int(normPos.y*size.y+0.5));
+ return TouchEventPtr(new TouchEvent(id, type, screenPos, Event::TOUCH));
+}
+
+}
diff --git a/src/player/LibMTDevInputDevice.h b/src/player/LibMTDevInputDevice.h
new file mode 100644
index 0000000..d8417c1
--- /dev/null
+++ b/src/player/LibMTDevInputDevice.h
@@ -0,0 +1,73 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _LibMTDevInputDevice_H_
+#define _LibMTDevInputDevice_H_
+
+#include "../api.h"
+#include "MultitouchInputDevice.h"
+#include "Event.h"
+
+#include "../base/Rect.h"
+
+#include <vector>
+#include <set>
+#include <map>
+
+struct mtdev;
+
+namespace avg {
+
+class AVG_API LibMTDevInputDevice: public MultitouchInputDevice
+{
+public:
+ LibMTDevInputDevice();
+ virtual ~LibMTDevInputDevice();
+ virtual void start();
+
+ std::vector<EventPtr> pollEvents();
+
+private:
+ void processEvents(const std::set<int>& changedIDs);
+ TouchEventPtr createEvent(int id, Event::Type type, IntPoint pos);
+
+ int m_DeviceFD;
+ int m_LastID;
+ mtdev* m_pMTDevice;
+ IntRect m_Dimensions;
+
+ struct TouchData
+ {
+ TouchData() { id = -1; }
+ int id;
+ bool bUp;
+ IntPoint pos;
+ };
+ std::map<int, TouchData> m_Slots;
+
+};
+
+typedef boost::shared_ptr<LibMTDevInputDevice> LibMTDevInputDevicePtr;
+
+}
+
+#endif
+
diff --git a/src/player/LineNode.cpp b/src/player/LineNode.cpp
new file mode 100644
index 0000000..39a1b57
--- /dev/null
+++ b/src/player/LineNode.cpp
@@ -0,0 +1,106 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "LineNode.h"
+
+#include "TypeDefinition.h"
+
+#include "../base/Exception.h"
+
+#include <iostream>
+#include <sstream>
+
+using namespace std;
+
+namespace avg {
+
+void LineNode::registerType()
+{
+ TypeDefinition def = TypeDefinition("line", "vectornode",
+ ExportedObject::buildObject<LineNode>)
+ .addArg(Arg<glm::vec2>("pos1", glm::vec2(0,0), false, offsetof(LineNode, m_P1)))
+ .addArg(Arg<glm::vec2>("pos2", glm::vec2(0,0), false, offsetof(LineNode, m_P2)))
+ .addArg(Arg<float>("texcoord1", 0, false, offsetof(LineNode, m_TC1)))
+ .addArg(Arg<float>("texcoord2", 1, false, offsetof(LineNode, m_TC2)))
+ ;
+ TypeRegistry::get()->registerType(def);
+}
+
+LineNode::LineNode(const ArgList& args)
+ : VectorNode(args)
+{
+ args.setMembers(this);
+}
+
+LineNode::~LineNode()
+{
+}
+
+const glm::vec2& LineNode::getPos1() const
+{
+ return m_P1;
+}
+
+void LineNode::setPos1(const glm::vec2& pt)
+{
+ m_P1 = pt;
+ setDrawNeeded();
+}
+
+const glm::vec2& LineNode::getPos2() const
+{
+ return m_P2;
+}
+
+void LineNode::setPos2(const glm::vec2& pt)
+{
+ m_P2 = pt;
+ setDrawNeeded();
+}
+
+float LineNode::getTexCoord1() const
+{
+ return m_TC1;
+}
+
+void LineNode::setTexCoord1(float tc)
+{
+ m_TC1 = tc;
+ setDrawNeeded();
+}
+
+float LineNode::getTexCoord2() const
+{
+ return m_TC2;
+}
+
+void LineNode::setTexCoord2(float tc)
+{
+ m_TC2 = tc;
+ setDrawNeeded();
+}
+
+void LineNode::calcVertexes(const VertexDataPtr& pVertexData, Pixel32 color)
+{
+ pVertexData->addLineData(color, m_P1, m_P2, getStrokeWidth(), m_TC1, m_TC2);
+}
+
+}
diff --git a/src/player/LineNode.h b/src/player/LineNode.h
new file mode 100644
index 0000000..2843b48
--- /dev/null
+++ b/src/player/LineNode.h
@@ -0,0 +1,64 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _LineNode_H_
+#define _LineNode_H_
+
+#include "../api.h"
+#include "VectorNode.h"
+
+#include "../graphics/Pixel32.h"
+
+namespace avg {
+
+class AVG_API LineNode : public VectorNode
+{
+ public:
+ static void registerType();
+
+ LineNode(const ArgList& args);
+ virtual ~LineNode();
+
+ const glm::vec2& getPos1() const;
+ void setPos1(const glm::vec2& pt);
+
+ const glm::vec2& getPos2() const;
+ void setPos2(const glm::vec2& pt);
+
+ float getTexCoord1() const;
+ void setTexCoord1(float tc);
+
+ float getTexCoord2() const;
+ void setTexCoord2(float tc);
+
+ virtual void calcVertexes(const VertexDataPtr& pVertexData, Pixel32 color);
+
+ private:
+ glm::vec2 m_P1;
+ glm::vec2 m_P2;
+ float m_TC1;
+ float m_TC2;
+};
+
+}
+
+#endif
+
diff --git a/src/player/MainCanvas.cpp b/src/player/MainCanvas.cpp
new file mode 100644
index 0000000..2af29fc
--- /dev/null
+++ b/src/player/MainCanvas.cpp
@@ -0,0 +1,87 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "MainCanvas.h"
+
+#include "Player.h"
+#include "SDLDisplayEngine.h"
+#include "AVGNode.h"
+
+#include "../base/Exception.h"
+#include "../base/ScopeTimer.h"
+#include "../base/Logger.h"
+
+#include "../graphics/GLContext.h"
+
+#include <vector>
+
+using namespace boost;
+using namespace std;
+
+namespace avg {
+
+MainCanvas::MainCanvas(Player * pPlayer)
+ : Canvas(pPlayer)
+{
+}
+
+MainCanvas::~MainCanvas()
+{
+}
+
+void MainCanvas::setRoot(NodePtr pRootNode)
+{
+ Canvas::setRoot(pRootNode);
+ if (!dynamic_pointer_cast<AVGNode>(pRootNode)) {
+ throw (Exception(AVG_ERR_XML_PARSE,
+ "Root node of an avg tree needs to be an <avg> node."));
+ }
+}
+
+void MainCanvas::initPlayback(const SDLDisplayEnginePtr& pDisplayEngine)
+{
+ m_pDisplayEngine = pDisplayEngine;
+ Canvas::initPlayback(GLContext::getMain()->getConfig().m_MultiSampleSamples);
+}
+
+BitmapPtr MainCanvas::screenshot() const
+{
+ if (!m_pDisplayEngine) {
+ throw(Exception(AVG_ERR_UNSUPPORTED,
+ "MainCanvas::screenshot(): Canvas is not being rendered. No screenshot available."));
+ }
+ return m_pDisplayEngine->screenshot();
+}
+
+static ProfilingZoneID RootRenderProfilingZone("Render MainCanvas");
+
+void MainCanvas::renderTree()
+{
+ preRender();
+ glproc::BindFramebuffer(GL_FRAMEBUFFER, 0);
+ GLContext::checkError("Canvas::renderTree: BindFramebuffer()");
+ {
+ ScopeTimer Timer(RootRenderProfilingZone);
+ Canvas::render(m_pDisplayEngine->getWindowSize(), false);
+ }
+}
+
+}
diff --git a/src/player/MainCanvas.h b/src/player/MainCanvas.h
new file mode 100644
index 0000000..55f68d6
--- /dev/null
+++ b/src/player/MainCanvas.h
@@ -0,0 +1,51 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _MainCanvas_H_
+#define _MainCanvas_H_
+
+#include "../api.h"
+#include "Canvas.h"
+
+namespace avg {
+
+class SDLDisplayEngine;
+typedef boost::shared_ptr<SDLDisplayEngine> SDLDisplayEnginePtr;
+
+class AVG_API MainCanvas: public Canvas
+{
+ public:
+ MainCanvas(Player * pPlayer);
+ virtual ~MainCanvas();
+ virtual void setRoot(NodePtr pRootNode);
+ void initPlayback(const SDLDisplayEnginePtr& pDisplayEngine);
+
+ virtual BitmapPtr screenshot() const;
+
+ private:
+ virtual void renderTree();
+
+ SDLDisplayEnginePtr m_pDisplayEngine;
+};
+
+}
+#endif
+
diff --git a/src/player/Makefile.am b/src/player/Makefile.am
new file mode 100644
index 0000000..a483037
--- /dev/null
+++ b/src/player/Makefile.am
@@ -0,0 +1,121 @@
+AM_CPPFLAGS = -I.. @XML2_CFLAGS@ @FREETYPE_CFLAGS@ \
+ @PANGOFT2_CFLAGS@ @PYTHON_CPPFLAGS@ @GL_CFLAGS@ \
+ @DC1394_2_CFLAGS@ @LIBRSVG_CFLAGS@ @FONTCONFIG_CFLAGS@ \
+ $(MTDEV_CFLAGS)
+
+if APPLE
+ APPLE_SOURCES = SDLMain.m AppleTrackpadInputDevice.cpp
+ APPLE_LINKFLAGS = -read_only_relocs suppress -F/System/Library/PrivateFrameworks \
+ -framework MultitouchSupport
+ XGL_LIBS =
+else
+ APPLE_SOURCES =
+ APPLE_LINKFLAGS =
+if ENABLE_RPI
+ XGL_LIBS = -lXxf86vm -lX11 -lGLESv2 -lEGL
+else
+if ENABLE_EGL
+ XGL_LIBS = -lXxf86vm -lX11 -lGLESv2 -lEGL
+else
+ XGL_LIBS = -lXxf86vm -lX11
+endif
+endif
+endif
+
+if ENABLE_MTDEV
+ MTDEV_SOURCES = LibMTDevInputDevice.cpp
+ MTDEV_INCLUDES = LibMTDevInputDevice.h
+else
+ MTDEV_SOURCES =
+ MTDEV_INCLUDES =
+endif
+
+if HAVE_XI2_1
+ XINPUT2_SOURCES = XInputMTInputDevice.cpp
+ XINPUT2_INCLUDES = XInputMTInputDevice.h
+else
+if HAVE_XI2_2
+ XINPUT2_SOURCES = XInputMTInputDevice.cpp
+ XINPUT2_INCLUDES = XInputMTInputDevice.h
+else
+ XINPUT2_SOURCES =
+ XINPUT2_INCLUDES =
+endif
+endif
+
+GL_SOURCES = OGLSurface.cpp SDLDisplayEngine.cpp
+GL_INCLUDES = OGLSurface.h SDLDisplayEngine.h
+
+ALL_GL_LIBS = @GL_LIBS@ @SDL_LIBS@ $(XGL_LIBS)
+
+ALL_H = Player.h PluginManager.h IInputDevice.h VideoNode.h ExportedObject.h \
+ DisplayEngine.h TypeRegistry.h Arg.h ArgBase.h ArgList.h \
+ Node.h AreaNode.h DisplayParams.h TypeDefinition.h TextEngine.h \
+ AVGNode.h DivNode.h CursorState.h MaterialInfo.h Canvas.h MainCanvas.h \
+ Image.h ImageNode.h Timeout.h WordsNode.h WrapPython.h OffscreenCanvas.h \
+ EventDispatcher.h CursorEvent.h MouseEvent.h \
+ Event.h KeyEvent.h TestHelper.h CanvasNode.h \
+ OffscreenCanvasNode.h MultitouchInputDevice.h \
+ RasterNode.h CameraNode.h TrackerInputDevice.h TrackerCalibrator.h \
+ TouchEvent.h Contact.h TouchStatus.h TrackerTouchStatus.h BoostPython.h \
+ SoundNode.h FontStyle.h \
+ VectorNode.h FilledVectorNode.h LineNode.h PolyLineNode.h RectNode.h \
+ CurveNode.h PolygonNode.h CircleNode.h Shape.h MeshNode.h FXNode.h \
+ NullFXNode.h BlurFXNode.h ShadowFXNode.h ChromaKeyFXNode.h HueSatFXNode.h \
+ InvertFXNode.h TUIOInputDevice.h VideoWriter.h VideoWriterThread.h \
+ SVG.h SVGElement.h Publisher.h SubscriberInfo.h PublisherDefinition.h \
+ PublisherDefinitionRegistry.h MessageID.h VersionInfo.h \
+ PythonLogSink.h BitmapManager.h BitmapManagerThread.h IBitmapLoadedListener.h \
+ BitmapManagerMsg.h \
+ $(MTDEV_INCLUDES) $(GL_INCLUDES) $(XINPUT2_INCLUDES)
+
+TESTS = testcalibrator testplayer
+
+EXTRA_DIST = SDLMain.h
+
+noinst_LTLIBRARIES = libplayer.la
+noinst_PROGRAMS = testcalibrator testplayer
+testplayer_SOURCES = testplayer.cpp
+testplayer_LDADD = libplayer.la ../video/libvideo.la ../audio/libaudio.la \
+ ../base/triangulate/libtriangulate.la \
+ ../imaging/libimaging.la ../graphics/libgraphics.la ../base/libbase.la \
+ ../lmfit/liblmfit.la ../oscpack/liboscpack.la \
+ @XML2_LIBS@ @BOOST_THREAD_LIBS@ @PTHREAD_CFLAGS@ @PTHREAD_LIBS@ @PANGOFT2_LIBS@ \
+ @LIBRSVG_LIBS@ \
+ @DC1394_2_LIBS@ @GLU_LIBS@ $(ALL_GL_LIBS) $(XI2_1_LIBS) $(XI2_2_LIBS) \
+ @LIBFFMPEG@ @LIBAVRESAMPLE@ $(BOOST_PYTHON_LIBS) $(PYTHON_LDFLAGS) @GDK_PIXBUF_LIBS@ \
+ @FONTCONFIG_LIBS@
+
+testplayer_LDFLAGS = $(APPLE_LINKFLAGS) -module -XCClinker
+
+testcalibrator_SOURCES = testcalibrator.cpp
+testcalibrator_LDADD = libplayer.la ../video/libvideo.la ../audio/libaudio.la \
+ ../base/triangulate/libtriangulate.la \
+ ../imaging/libimaging.la ../graphics/libgraphics.la ../base/libbase.la \
+ ../lmfit/liblmfit.la ../oscpack/liboscpack.la \
+ @XML2_LIBS@ @BOOST_THREAD_LIBS@ @PTHREAD_CFLAGS@ @PTHREAD_LIBS@ @LIBRSVG_LIBS@ \
+ @GDK_PIXBUF_LIBS@
+
+libplayer_la_LIBADD = $(BOOST_PYTHON_LIBS) $(PYTHON_LDFLAGS) $(MTDEV_LIBS)
+libplayer_la_SOURCES = $(GL_SOURCES) \
+ Arg.cpp AreaNode.cpp RasterNode.cpp DivNode.cpp VideoNode.cpp ExportedObject.cpp \
+ Player.cpp PluginManager.cpp TypeRegistry.cpp ArgBase.cpp ArgList.cpp \
+ DisplayEngine.cpp Canvas.cpp CanvasNode.cpp OffscreenCanvasNode.cpp \
+ MainCanvas.cpp Node.cpp MultitouchInputDevice.cpp WrapPython.cpp \
+ WordsNode.cpp CameraNode.cpp TypeDefinition.cpp TextEngine.cpp \
+ Timeout.cpp Event.cpp DisplayParams.cpp CursorState.cpp MaterialInfo.cpp \
+ Image.cpp ImageNode.cpp EventDispatcher.cpp KeyEvent.cpp CursorEvent.cpp \
+ MouseEvent.cpp TouchEvent.cpp AVGNode.cpp TestHelper.cpp \
+ TrackerInputDevice.cpp TrackerTouchStatus.cpp TrackerCalibrator.cpp \
+ SoundNode.cpp FontStyle.cpp \
+ VectorNode.cpp FilledVectorNode.cpp LineNode.cpp PolyLineNode.cpp \
+ RectNode.cpp CurveNode.cpp PolygonNode.cpp CircleNode.cpp Shape.cpp MeshNode.cpp \
+ Contact.cpp TouchStatus.cpp OffscreenCanvas.cpp FXNode.cpp TUIOInputDevice.cpp \
+ NullFXNode.cpp BlurFXNode.cpp ShadowFXNode.cpp ChromaKeyFXNode.cpp \
+ InvertFXNode.cpp HueSatFXNode.cpp VideoWriter.cpp VideoWriterThread.cpp \
+ SVG.cpp SVGElement.cpp Publisher.cpp SubscriberInfo.cpp PublisherDefinition.cpp \
+ PublisherDefinitionRegistry.cpp MessageID.cpp VersionInfo.cpp \
+ PythonLogSink.cpp BitmapManager.cpp BitmapManagerThread.cpp \
+ BitmapManagerMsg.cpp \
+ $(MTDEV_SOURCES) $(XINPUT2_SOURCES) $(APPLE_SOURCES) $(ALL_H)
+libplayer_a_CXXFLAGS = -DPREFIXDIR=\"$(prefix)\"
diff --git a/src/player/MaterialInfo.cpp b/src/player/MaterialInfo.cpp
new file mode 100644
index 0000000..2b25b48
--- /dev/null
+++ b/src/player/MaterialInfo.cpp
@@ -0,0 +1,53 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "MaterialInfo.h"
+
+#include "../base/Exception.h"
+
+#include <iostream>
+
+using namespace std;
+
+namespace avg {
+
+MaterialInfo::MaterialInfo(int wrapSMode, int wrapTMode, bool bUseMipmaps)
+ : m_WrapSMode(wrapSMode),
+ m_WrapTMode(wrapTMode),
+ m_bUseMipmaps(bUseMipmaps)
+{}
+
+int MaterialInfo::getWrapSMode() const
+{
+ return m_WrapSMode;
+}
+
+int MaterialInfo::getWrapTMode() const
+{
+ return m_WrapTMode;
+}
+
+bool MaterialInfo::getUseMipmaps() const
+{
+ return m_bUseMipmaps;
+}
+
+}
diff --git a/src/player/MaterialInfo.h b/src/player/MaterialInfo.h
new file mode 100644
index 0000000..7f1d987
--- /dev/null
+++ b/src/player/MaterialInfo.h
@@ -0,0 +1,47 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _MaterialInfo_H_
+#define _MaterialInfo_H_
+
+#include "../api.h"
+
+namespace avg {
+
+class AVG_API MaterialInfo {
+public:
+ MaterialInfo(int wrapSMode, int wrapTMode, bool bUseMipmaps);
+
+ int getWrapSMode() const;
+ int getWrapTMode() const;
+ bool getUseMipmaps() const;
+
+private:
+ int m_WrapSMode;
+ int m_WrapTMode;
+ bool m_bUseMipmaps;
+};
+
+}
+
+#endif
+
+
diff --git a/src/player/MeshNode.cpp b/src/player/MeshNode.cpp
new file mode 100644
index 0000000..09e577f
--- /dev/null
+++ b/src/player/MeshNode.cpp
@@ -0,0 +1,164 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "MeshNode.h"
+
+#include "../base/Logger.h"
+#include "../base/Exception.h"
+
+#include "TypeDefinition.h"
+#include "VectorNode.h"
+
+#include <cstdlib>
+#include <string>
+#include <iostream>
+
+using namespace std;
+
+namespace avg {
+
+void MeshNode::registerType()
+{
+ vector<glm::vec2> vVert;
+ vector<glm::vec2> vTex;
+ vector<glm::ivec3> vTriangle;
+
+ TypeDefinition def = TypeDefinition("mesh", "vectornode",
+ ExportedObject::buildObject<MeshNode>)
+ .addArg(Arg<vector<glm::vec2> >("vertexcoords", vVert, false,
+ offsetof(MeshNode, m_VertexCoords)))
+ .addArg(Arg<vector<glm::vec2> >("texcoords", vTex, false,
+ offsetof(MeshNode, m_TexCoords)))
+ .addArg(Arg<vector<glm::ivec3> >("triangles", vTriangle, false,
+ offsetof(MeshNode, m_Triangles)))
+ .addArg(Arg<bool>("backfacecull", false, false,
+ offsetof(MeshNode, m_bBackfaceCull)))
+ ;
+ TypeRegistry::get()->registerType(def);
+}
+
+MeshNode::MeshNode(const ArgList& args)
+ : VectorNode(args)
+{
+ args.setMembers(this);
+ isValid(m_TexCoords);
+}
+
+MeshNode::~MeshNode()
+{
+}
+
+void MeshNode::isValid(const vector<glm::vec2>& coords)
+{
+ if (coords.size() != m_VertexCoords.size()) {
+ throw(Exception(AVG_ERR_OUT_OF_RANGE,
+ "Coordinates Out of Range"));
+ }
+}
+
+const vector<glm::vec2>& MeshNode::getVertexCoords() const
+{
+ return m_VertexCoords;
+}
+
+void MeshNode::setVertexCoords(const vector<glm::vec2>& coords)
+{
+ isValid(coords);
+ m_VertexCoords = coords;
+ setDrawNeeded();
+}
+
+const vector<glm::vec2>& MeshNode::getTexCoords() const
+{
+ return m_TexCoords;
+}
+
+void MeshNode::setTexCoords(const vector<glm::vec2>& coords)
+{
+ isValid(coords);
+ m_TexCoords = coords;
+ setDrawNeeded();
+}
+
+const vector<glm::ivec3>& MeshNode::getTriangles() const
+{
+ return m_Triangles;
+}
+
+
+void MeshNode::setTriangles(const vector<glm::ivec3>& triangles)
+{
+ for (unsigned int i = 0; i < triangles.size(); i++) {
+
+ if (triangles[i].x < 0 || triangles[i].y < 0 || triangles[i].z < 0)
+ {
+ throw(Exception(AVG_ERR_OUT_OF_RANGE,
+ "Triangle Index Out of Range < 0"));
+ }
+
+ if (static_cast<unsigned int>(triangles[i].x) > m_VertexCoords.size() ||
+ static_cast<unsigned int>(triangles[i].y) > m_VertexCoords.size() ||
+ static_cast<unsigned int>(triangles[i].z) > m_VertexCoords.size())
+ {
+ throw(Exception(AVG_ERR_OUT_OF_RANGE,
+ "Triangle Index Out of Range > max triangles"));
+ }
+ }
+ m_Triangles = triangles;
+ setDrawNeeded();
+}
+
+bool MeshNode::getBackfaceCull() const
+{
+ return m_bBackfaceCull;
+}
+
+void MeshNode::setBackfaceCull(const bool bBackfaceCull)
+{
+ m_bBackfaceCull = bBackfaceCull;
+}
+
+void MeshNode::calcVertexes(const VertexDataPtr& pVertexData, Pixel32 color)
+{
+ for (unsigned int i = 0; i < m_VertexCoords.size(); i++) {
+ pVertexData->appendPos(m_VertexCoords[i],m_TexCoords[i], color);
+ }
+
+ for (unsigned int i = 0; i < m_Triangles.size(); i++) {
+ pVertexData->appendTriIndexes(m_Triangles[i].x, m_Triangles[i].y,
+ m_Triangles[i].z);
+ }
+}
+
+void MeshNode::render()
+{
+ if (m_bBackfaceCull) {
+ glEnable(GL_CULL_FACE);
+ }
+
+ VectorNode::render();
+
+ if (m_bBackfaceCull) {
+ glDisable(GL_CULL_FACE);
+ }
+}
+
+}
diff --git a/src/player/MeshNode.h b/src/player/MeshNode.h
new file mode 100644
index 0000000..e921c12
--- /dev/null
+++ b/src/player/MeshNode.h
@@ -0,0 +1,71 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+
+#ifndef _MeshNode_H_
+#define _MeshNode_H_
+
+#include "../api.h"
+#include "VectorNode.h"
+
+#include "../base/GLMHelper.h"
+#include "../graphics/Pixel32.h"
+
+#include <vector>
+
+namespace avg {
+
+class AVG_API MeshNode : public VectorNode
+{
+ public:
+ static void registerType();
+
+ MeshNode(const ArgList& args);
+ virtual ~MeshNode();
+
+ void isValid(const std::vector<glm::vec2>& coords);
+
+ const std::vector<glm::vec2>& getVertexCoords() const;
+ void setVertexCoords(const std::vector<glm::vec2>& coords);
+
+ const std::vector<glm::vec2>& getTexCoords() const;
+ void setTexCoords(const std::vector<glm::vec2>& coords);
+
+ const std::vector<glm::ivec3>& getTriangles() const;
+ void setTriangles(const std::vector<glm::ivec3>& pts);
+
+ bool getBackfaceCull() const;
+ void setBackfaceCull(const bool bBackfaceCull);
+
+ virtual void calcVertexes(const VertexDataPtr& pVertexData, Pixel32 color);
+
+ virtual void render();
+
+ private:
+ std::vector<glm::vec2> m_TexCoords;
+ std::vector<glm::vec2> m_VertexCoords;
+ std::vector<glm::ivec3> m_Triangles;
+
+ bool m_bBackfaceCull;
+};
+}
+#endif
+
diff --git a/src/player/MessageID.cpp b/src/player/MessageID.cpp
new file mode 100644
index 0000000..6617e0e
--- /dev/null
+++ b/src/player/MessageID.cpp
@@ -0,0 +1,62 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "MessageID.h"
+
+#include "../base/StringHelper.h"
+
+using namespace std;
+
+namespace avg {
+
+MessageID::MessageID(const string& sName, int id)
+ : m_sName(sName),
+ m_ID(id)
+{
+}
+
+bool MessageID::operator < (const MessageID& other) const
+{
+ return m_ID < other.m_ID;
+}
+
+bool MessageID::operator == (const MessageID& other) const
+{
+ return m_ID == other.m_ID;
+}
+
+std::string MessageID::getRepr()
+{
+ if (m_sName != "") {
+ return m_sName;
+ } else {
+ return toString(m_ID);
+ }
+}
+
+std::ostream& operator <<(ostream& os, const MessageID& id)
+{
+ os << "(" << id.m_sName << ", " << id.m_ID << ")";
+ return os;
+}
+
+}
+
diff --git a/src/player/MessageID.h b/src/player/MessageID.h
new file mode 100644
index 0000000..f7ec6d6
--- /dev/null
+++ b/src/player/MessageID.h
@@ -0,0 +1,48 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _MessageID_H_
+#define _MessageID_H_
+
+#include "../api.h"
+
+#include <string>
+#include <iostream>
+
+namespace avg {
+
+struct MessageID {
+ MessageID(const std::string& sName, int id);
+
+ bool operator < (const MessageID& other) const;
+ bool operator == (const MessageID& other) const;
+
+ std::string getRepr();
+
+ std::string m_sName;
+ int m_ID;
+};
+
+std::ostream& operator <<(std::ostream& os, const MessageID& id);
+
+}
+
+#endif
diff --git a/src/player/MouseEvent.cpp b/src/player/MouseEvent.cpp
new file mode 100644
index 0000000..c56dd8c
--- /dev/null
+++ b/src/player/MouseEvent.cpp
@@ -0,0 +1,89 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "MouseEvent.h"
+
+#include "../base/Logger.h"
+#include "../base/Exception.h"
+
+#include <iostream>
+#include <sstream>
+
+using namespace std;
+
+namespace avg {
+
+MouseEvent::MouseEvent(Event::Type eventType,
+ bool leftButtonState, bool middleButtonState, bool rightButtonState,
+ const IntPoint& pos, int button, const glm::vec2& speed, int when)
+ : CursorEvent(MOUSECURSORID, eventType, pos, MOUSE, when)
+{
+ m_LeftButtonState = leftButtonState;
+ m_MiddleButtonState = middleButtonState;
+ m_RightButtonState = rightButtonState;
+ m_Button = button;
+ setSpeed(speed);
+}
+
+MouseEvent::~MouseEvent()
+{
+}
+
+int MouseEvent::getButton() const
+{
+ return m_Button;
+}
+
+bool MouseEvent::getLeftButtonState() const
+{
+ return m_LeftButtonState;
+}
+
+bool MouseEvent::getMiddleButtonState() const
+{
+ return m_MiddleButtonState;
+}
+
+bool MouseEvent::getRightButtonState() const
+{
+ return m_RightButtonState;
+}
+
+bool MouseEvent::isAnyButtonPressed() const
+{
+ return m_LeftButtonState || m_MiddleButtonState || m_RightButtonState;
+}
+
+void MouseEvent::trace()
+{
+ CursorEvent::trace();
+ AVG_TRACE(Logger::category::EVENTS, Logger::severity::DEBUG, "pos: " << getPos()
+ << ", button: " << m_Button);
+}
+
+CursorEventPtr MouseEvent::cloneAs(Type EventType) const
+{
+ MouseEventPtr pClone(new MouseEvent(*this));
+ pClone->m_Type = EventType;
+ return pClone;
+}
+
+}
diff --git a/src/player/MouseEvent.h b/src/player/MouseEvent.h
new file mode 100644
index 0000000..fb67dde
--- /dev/null
+++ b/src/player/MouseEvent.h
@@ -0,0 +1,66 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _MouseEvent_h_
+#define _MouseEvent_h_
+
+#include "../api.h"
+#include "Event.h"
+#include "CursorEvent.h"
+
+namespace avg {
+
+class AVG_API MouseEvent : public CursorEvent {
+ public:
+ MouseEvent(Event::Type eventType,
+ bool leftButtonState, bool middleButtonState, bool rightButtonState,
+ const IntPoint& pos, int button, const glm::vec2& speed=glm::vec2(0,0),
+ int when=-1);
+ virtual ~MouseEvent();
+
+ //REFACTORME: get*ButtonState -> getButtonState(num=*)
+ bool getLeftButtonState() const;
+ bool getMiddleButtonState() const;
+ bool getRightButtonState() const;
+ bool isAnyButtonPressed() const;
+ int getButton() const;
+ virtual CursorEventPtr cloneAs(Type EventType) const;
+ virtual void trace();
+ static const long NO_BUTTON=0;
+ static const long LEFT_BUTTON=1;
+ static const long RIGHT_BUTTON=2;
+ static const long MIDDLE_BUTTON=3;
+ static const long WHEELUP_BUTTON=4;
+ static const long WHEELDOWN_BUTTON=5;
+
+ private:
+ bool m_LeftButtonState;
+ bool m_MiddleButtonState;
+ bool m_RightButtonState;
+ int m_Button;
+};
+
+typedef boost::shared_ptr<class MouseEvent> MouseEventPtr;
+
+}
+
+#endif
+
diff --git a/src/player/MultitouchInputDevice.cpp b/src/player/MultitouchInputDevice.cpp
new file mode 100644
index 0000000..507f3fb
--- /dev/null
+++ b/src/player/MultitouchInputDevice.cpp
@@ -0,0 +1,136 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "MultitouchInputDevice.h"
+#include "TouchEvent.h"
+#include "Player.h"
+#include "AVGNode.h"
+#include "TouchStatus.h"
+
+#include "../base/Logger.h"
+#include "../base/ObjectCounter.h"
+#include "../base/Exception.h"
+
+using namespace std;
+
+namespace avg {
+
+MultitouchInputDevice::MultitouchInputDevice()
+ : IInputDevice(EXTRACT_INPUTDEVICE_CLASSNAME(MultitouchInputDevice))
+{
+ m_TouchArea = ConfigMgr::get()->getSizeOption("touch", "area");
+ if (m_TouchArea.x == 0) {
+ m_TouchArea = Player::get()->getScreenResolution();
+ }
+ m_TouchOffset = ConfigMgr::get()->getSizeOption("touch", "offset");
+}
+
+MultitouchInputDevice::~MultitouchInputDevice()
+{
+}
+
+void MultitouchInputDevice::start()
+{
+ m_pMutex = MutexPtr(new boost::mutex);
+}
+
+vector<EventPtr> MultitouchInputDevice::pollEvents()
+{
+ lock_guard lock(*m_pMutex);
+
+ vector<EventPtr> events;
+ vector<TouchStatusPtr>::iterator it;
+// cerr << "--------poll---------" << endl;
+ for (it = m_Touches.begin(); it != m_Touches.end(); ) {
+// cerr << (*it)->getID() << " ";
+ CursorEventPtr pEvent = (*it)->pollEvent();
+ if (pEvent) {
+ events.push_back(pEvent);
+ if (pEvent->getType() == Event::CURSOR_UP) {
+ it = m_Touches.erase(it);
+ } else {
+ ++it;
+ }
+ } else {
+ ++it;
+ }
+ }
+// cerr << endl;
+ return events;
+}
+
+int MultitouchInputDevice::getNumTouches() const
+{
+ return m_TouchIDMap.size();
+}
+
+TouchStatusPtr MultitouchInputDevice::getTouchStatus(int id)
+{
+ map<int, TouchStatusPtr>::iterator it = m_TouchIDMap.find(id);
+ if (it == m_TouchIDMap.end()) {
+ return TouchStatusPtr();
+ } else {
+ return it->second;
+ }
+}
+
+void MultitouchInputDevice::addTouchStatus(int id, TouchEventPtr pInitialEvent)
+{
+ TouchStatusPtr pTouchStatus(new TouchStatus(pInitialEvent));
+ m_TouchIDMap[id] = pTouchStatus;
+ m_Touches.push_back(pTouchStatus);
+}
+
+void MultitouchInputDevice::removeTouchStatus(int id)
+{
+ unsigned numRemoved = m_TouchIDMap.erase(id);
+ AVG_ASSERT(numRemoved == 1);
+}
+
+void MultitouchInputDevice::getDeadIDs(const set<int>& liveIDs, set<int>& deadIDs)
+{
+ map<int, TouchStatusPtr>::iterator it;
+ for (it = m_TouchIDMap.begin(); it != m_TouchIDMap.end(); ++it) {
+ int id = it->first;
+ set<int>::const_iterator foundIt = liveIDs.find(id);
+ if (foundIt == liveIDs.end()) {
+ deadIDs.insert(id);
+ }
+ }
+}
+
+glm::vec2 MultitouchInputDevice::getTouchArea() const
+{
+ return m_TouchArea;
+}
+
+IntPoint MultitouchInputDevice::getScreenPos(const glm::vec2& pos) const
+{
+ return IntPoint(int(pos.x * m_TouchArea.x + m_TouchOffset.x + 0.5),
+ int(pos.y * m_TouchArea.y + m_TouchOffset.y) + 0.5);
+}
+
+boost::mutex& MultitouchInputDevice::getMutex()
+{
+ return *m_pMutex;
+}
+
+}
diff --git a/src/player/MultitouchInputDevice.h b/src/player/MultitouchInputDevice.h
new file mode 100644
index 0000000..7ccbfe5
--- /dev/null
+++ b/src/player/MultitouchInputDevice.h
@@ -0,0 +1,79 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _MultitouchInputDevice_H_
+#define _MultitouchInputDevice_H_
+
+#include "../api.h"
+#include "IInputDevice.h"
+
+#include "../base/GLMHelper.h"
+#include "../base/ConfigMgr.h"
+
+#include <boost/thread.hpp>
+#include <map>
+#include <set>
+
+typedef boost::shared_ptr<boost::mutex> MutexPtr;
+
+namespace avg {
+
+class TouchStatus;
+typedef boost::shared_ptr<class TouchStatus> TouchStatusPtr;
+class TouchEvent;
+typedef boost::shared_ptr<class TouchEvent> TouchEventPtr;
+class Event;
+typedef boost::shared_ptr<Event> EventPtr;
+
+class AVG_API MultitouchInputDevice: public IInputDevice
+{
+public:
+ MultitouchInputDevice();
+ virtual ~MultitouchInputDevice() = 0;
+ virtual void start();
+
+ std::vector<EventPtr> pollEvents();
+
+protected:
+ int getNumTouches() const;
+ // Note that the id used here is not the libavg cursor id but a touch-driver-specific
+ // id handed up from the driver level.
+ TouchStatusPtr getTouchStatus(int id);
+ void addTouchStatus(int id, TouchEventPtr pInitialEvent);
+ void removeTouchStatus(int id);
+ void getDeadIDs(const std::set<int>& liveIDs, std::set<int>& deadIDs);
+ glm::vec2 getTouchArea() const;
+ IntPoint getScreenPos(const glm::vec2& pos) const;
+ boost::mutex& getMutex();
+
+private:
+ std::map<int, TouchStatusPtr> m_TouchIDMap;
+ std::vector<TouchStatusPtr> m_Touches;
+ MutexPtr m_pMutex;
+ glm::vec2 m_TouchArea;
+ glm::vec2 m_TouchOffset;
+};
+
+typedef boost::shared_ptr<MultitouchInputDevice> MultitouchInputDevicePtr;
+
+}
+
+#endif
diff --git a/src/player/Node.cpp b/src/player/Node.cpp
new file mode 100644
index 0000000..4f1f6c6
--- /dev/null
+++ b/src/player/Node.cpp
@@ -0,0 +1,624 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "Node.h"
+
+#include "TypeDefinition.h"
+#include "Arg.h"
+#include "Canvas.h"
+#include "DivNode.h"
+#include "Player.h"
+#include "CursorEvent.h"
+#include "PublisherDefinition.h"
+
+#include "../base/Exception.h"
+#include "../base/Logger.h"
+#include "../base/ObjectCounter.h"
+#include "../base/StringHelper.h"
+#include "../base/OSHelper.h"
+
+#include <string>
+
+using namespace std;
+using namespace boost;
+
+namespace avg {
+
+void Node::registerType()
+{
+ PublisherDefinitionPtr pPubDef = PublisherDefinition::create("Node");
+ pPubDef->addMessage("CURSOR_DOWN");
+ pPubDef->addMessage("CURSOR_MOTION");
+ pPubDef->addMessage("CURSOR_UP");
+ pPubDef->addMessage("CURSOR_OVER");
+ pPubDef->addMessage("CURSOR_OUT");
+ pPubDef->addMessage("HOVER_DOWN");
+ pPubDef->addMessage("HOVER_MOTION");
+ pPubDef->addMessage("HOVER_UP");
+ pPubDef->addMessage("HOVER_OVER");
+ pPubDef->addMessage("HOVER_OUT");
+ pPubDef->addMessage("END_OF_FILE");
+ pPubDef->addMessage("SIZE_CHANGED");
+
+ TypeDefinition def = TypeDefinition("node")
+ .addArg(Arg<string>("id", "", false, offsetof(Node, m_ID)))
+ .addArg(Arg<bool>("active", true, false, offsetof(Node, m_bActive)))
+ .addArg(Arg<bool>("sensitive", true, false, offsetof(Node, m_bSensitive)))
+ .addArg(Arg<float>("opacity", 1.0, false, offsetof(Node, m_Opacity)));
+ TypeRegistry::get()->registerType(def);
+}
+
+Node::Node(const std::string& sPublisherName)
+ : Publisher(sPublisherName),
+ m_pParent(0),
+ m_pCanvas(),
+ m_State(NS_UNCONNECTED)
+{
+ ObjectCounter::get()->incRef(&typeid(*this));
+}
+
+Node::~Node()
+{
+ m_EventHandlerMap.clear();
+ ObjectCounter::get()->decRef(&typeid(*this));
+}
+
+void Node::registerInstance(PyObject* pSelf, const DivNodePtr& pParent)
+{
+ ExportedObject::registerInstance(pSelf);
+ if (pParent) {
+ pParent->appendChild(getSharedThis());
+ }
+}
+
+void Node::checkSetParentError(DivNode* pParent)
+{
+ if (getParent() && pParent != 0) {
+ throw(Exception(AVG_ERR_UNSUPPORTED,
+ string("Can't change parent of node (") + getID() + ")."));
+ }
+ if (getSharedThis() == NodePtr()) {
+ throw(Exception(AVG_ERR_UNSUPPORTED,
+ "Node not registered. Please use Node.registerInstance() when deriving from libavg Nodes in python."));
+ }
+}
+
+void Node::setParent(DivNode* pParent, NodeState parentState, CanvasPtr pCanvas)
+{
+ AVG_ASSERT(getState() == NS_UNCONNECTED);
+ checkSetParentError(pParent);
+ m_pParent = pParent;
+ if (parentState != NS_UNCONNECTED) {
+ connect(pCanvas);
+ }
+}
+
+void Node::removeParent()
+{
+ m_pParent = 0;
+}
+
+DivNodePtr Node::getParent() const
+{
+ if (m_pParent == 0) {
+ return DivNodePtr();
+ } else {
+ NodePtr pParent = m_pParent->getSharedThis();
+ return boost::dynamic_pointer_cast<DivNode>(pParent);
+ }
+}
+
+vector<NodePtr> Node::getParentChain()
+{
+ vector<NodePtr> pNodes;
+ NodePtr pCurNode = getSharedThis();
+ while (pCurNode) {
+ pNodes.push_back(pCurNode);
+ pCurNode = pCurNode->getParent();
+ }
+ return pNodes;
+}
+
+void Node::connectDisplay()
+{
+ AVG_ASSERT(getState() == NS_CONNECTED);
+ setState(NS_CANRENDER);
+}
+
+void Node::connect(CanvasPtr pCanvas)
+{
+ m_pCanvas = pCanvas;
+ setState(NS_CONNECTED);
+}
+
+void Node::disconnect(bool bKill)
+{
+ AVG_ASSERT(getState() != NS_UNCONNECTED);
+ m_pCanvas.lock()->removeNodeID(getID());
+ setState(NS_UNCONNECTED);
+ if (bKill) {
+ m_EventHandlerMap.clear();
+ }
+}
+
+void Node::unlink(bool bKill)
+{
+ DivNodePtr pParent = getParent();
+ if (pParent != DivNodePtr()) {
+ pParent->removeChild(getSharedThis(), bKill);
+ }
+}
+
+const string& Node::getID() const
+{
+ return m_ID;
+}
+
+void Node::setID(const std::string& id)
+{
+ if (getState() != NS_UNCONNECTED) {
+ throw Exception(AVG_ERR_UNSUPPORTED, "Node with ID "+getID()
+ +" is connected. setID invalid.");
+ }
+ m_ID = id;
+}
+
+float Node::getOpacity() const
+{
+ return m_Opacity;
+}
+
+void Node::setOpacity(float opacity)
+{
+ m_Opacity = opacity;
+ if (m_Opacity < 0.0) {
+ m_Opacity = 0.0;
+ } else if (m_Opacity > 1.0) {
+ m_Opacity = 1.0;
+ }
+}
+
+bool Node::getActive() const
+{
+ return m_bActive;
+}
+
+void Node::setActive(bool bActive)
+{
+ if (bActive != m_bActive) {
+ m_bActive = bActive;
+ }
+}
+
+bool Node::getSensitive() const
+{
+ return m_bSensitive;
+}
+
+void Node::setSensitive(bool bSensitive)
+{
+ m_bSensitive = bSensitive;
+}
+
+void Node::setMouseEventCapture()
+{
+ setEventCapture(MOUSECURSORID);
+}
+
+void Node::releaseMouseEventCapture()
+{
+ releaseEventCapture(MOUSECURSORID);
+}
+
+void Node::setEventCapture(int cursorID)
+{
+ Player::get()->setEventCapture(getSharedThis(), cursorID);
+}
+
+void Node::releaseEventCapture(int cursorID)
+{
+ Player::get()->releaseEventCapture(cursorID);
+}
+
+void Node::setEventHandler(Event::Type type, int sources, PyObject * pFunc)
+{
+ avgDeprecationWarning("1.7", "Node.setEventHandler()", "Node.subscribe()");
+ for (int source = 1; source <= Event::NONE; source *= 2) {
+ if (source & sources) {
+ EventID id(type, (Event::Source)source);
+ EventHandlerMap::iterator it = m_EventHandlerMap.find(id);
+ if (it != m_EventHandlerMap.end()) {
+ m_EventHandlerMap.erase(it);
+ }
+ if (pFunc != Py_None) {
+ connectOneEventHandler(id, Py_None, pFunc);
+ }
+ }
+ }
+}
+
+void Node::connectEventHandler(Event::Type type, int sources,
+ PyObject * pObj, PyObject * pFunc)
+{
+ avgDeprecationWarning("1.8", "Node.connectEventHandler()", "Node.subscribe()");
+ for (int source = 1; source <= Event::NONE; source *= 2) {
+ if (source & sources) {
+ EventID id(type, (Event::Source)source);
+ connectOneEventHandler(id, pObj, pFunc);
+ }
+ }
+// cerr << "connectEventHandler" << endl;
+// dumpEventHandlers();
+}
+
+void Node::disconnectEventHandler(PyObject * pObj, PyObject * pFunc)
+{
+ avgDeprecationWarning("1.8", "Node.disconnectEventHandler()", "Node.unsubscribe()");
+ int numDisconnected = 0;
+ EventHandlerMap::iterator it;
+ for (it = m_EventHandlerMap.begin(); it != m_EventHandlerMap.end();) {
+ EventHandlerArrayPtr pEventHandlers = it->second;
+ EventHandlerArray::iterator listIt;
+ for (listIt = pEventHandlers->begin(); listIt != pEventHandlers->end();)
+ {
+ EventHandler& eventHandler = *listIt;
+ if (eventHandler.m_pObj == pObj &&
+ (pFunc == 0 ||
+ PyObject_RichCompareBool(eventHandler.m_pMethod, pFunc, Py_EQ)))
+ {
+ listIt = pEventHandlers->erase(listIt);
+ numDisconnected++;
+ } else {
+ ++listIt;
+ }
+ }
+
+ if (pEventHandlers->empty()) {
+ EventHandlerMap::iterator itErase = it;
+ ++it;
+ m_EventHandlerMap.erase(itErase);
+ } else {
+ ++it;
+ }
+ }
+// cerr << "disconnectEventHandler" << endl;
+// dumpEventHandlers();
+}
+
+bool Node::reactsToMouseEvents()
+{
+ return m_bActive && m_bSensitive;
+}
+
+glm::vec2 Node::getRelPos(const glm::vec2& absPos) const
+{
+ glm::vec2 parentPos;
+ if (m_pParent == 0) {
+ parentPos = absPos;
+ } else {
+ parentPos = m_pParent->getSharedThis()->getRelPos(absPos);
+ }
+ return toLocal(parentPos);
+}
+
+glm::vec2 Node::getAbsPos(const glm::vec2& relPos) const
+{
+ glm::vec2 thisPos = toGlobal(relPos);
+ glm::vec2 parentPos;
+ if (m_pParent == 0) {
+ parentPos = thisPos;
+ } else {
+ parentPos = m_pParent->getSharedThis()->getAbsPos(thisPos);
+ }
+ return parentPos;
+}
+
+glm::vec2 Node::toLocal(const glm::vec2& globalPos) const
+{
+ return globalPos;
+}
+
+glm::vec2 Node::toGlobal(const glm::vec2& localPos) const
+{
+ return localPos;
+}
+
+NodePtr Node::getElementByPos(const glm::vec2& pos)
+{
+ vector<NodePtr> elements;
+ getElementsByPos(pos, elements);
+ if (elements.empty()) {
+ return NodePtr();
+ } else {
+ return elements[0];
+ }
+}
+
+void Node::getElementsByPos(const glm::vec2& pos, vector<NodePtr>& pElements)
+{
+}
+
+void Node::preRender(const VertexArrayPtr& pVA, bool bIsParentActive,
+ float parentEffectiveOpacity)
+{
+ m_EffectiveOpacity = m_Opacity*parentEffectiveOpacity;
+ m_bEffectiveActive = bIsParentActive && m_bActive;
+}
+
+Node::NodeState Node::getState() const
+{
+ return m_State;
+}
+
+CanvasPtr Node::getCanvas() const
+{
+ return m_pCanvas.lock();
+}
+
+bool Node::handleEvent(EventPtr pEvent)
+{
+ if (pEvent->getSource() != Event::NONE && pEvent->getSource() != Event::CUSTOM) {
+ string messageID = getEventMessageID(pEvent);
+ notifySubscribers(messageID, pEvent);
+ }
+
+ EventID id(pEvent->getType(), pEvent->getSource());
+ EventHandlerMap::iterator it = m_EventHandlerMap.find(id);
+ if (it != m_EventHandlerMap.end()) {
+ bool bHandled = false;
+ // We need to copy the array because python code in callbacks can
+ /// connect and disconnect event handlers.
+ EventHandlerArray eventHandlers = *(it->second);
+ EventHandlerArray::iterator listIt;
+ for (listIt = eventHandlers.begin(); listIt != eventHandlers.end(); ++listIt) {
+ bHandled = callPython(listIt->m_pMethod, pEvent);
+ }
+ return bHandled;
+ } else {
+ return false;
+ }
+}
+
+float Node::getEffectiveOpacity() const
+{
+ return m_EffectiveOpacity;
+}
+
+string Node::dump(int indent)
+{
+ string dumpStr = string(indent, ' ') + getTypeStr() + ": m_ID=" + getID() +
+ "m_Opacity=" + toString(m_Opacity);
+ return dumpStr;
+}
+
+void Node::setState(Node::NodeState state)
+{
+/*
+ cerr << m_ID << " state: ";
+ switch(state) {
+ case NS_UNCONNECTED:
+ cerr << "unconnected" << endl;
+ break;
+ case NS_CONNECTED:
+ cerr << "connected" << endl;
+ break;
+ case NS_CANRENDER:
+ cerr << "canrender" << endl;
+ break;
+ }
+*/
+ if (m_State == NS_UNCONNECTED) {
+ AVG_ASSERT(state != NS_CANRENDER);
+ }
+ if (m_State == NS_CANRENDER) {
+ AVG_ASSERT(state != NS_CONNECTED);
+ }
+
+ m_State = state;
+}
+
+void Node::initFilename(string& sFilename)
+{
+ if (sFilename != "") {
+ bool bAbsDir = sFilename[0] == '/';
+#ifdef _WIN32
+ if (!bAbsDir) {
+ bAbsDir = (sFilename[0] == '\\' || sFilename[1] == ':');
+ }
+#endif
+ if (!bAbsDir) {
+ DivNodePtr pParent = getParent();
+ if (!pParent) {
+ sFilename = Player::get()->getRootMediaDir()+sFilename;
+ } else {
+ sFilename = pParent->getEffectiveMediaDir()+sFilename;
+ }
+ }
+ }
+}
+
+bool Node::checkReload(const std::string& sHRef, const ImagePtr& pImage,
+ Image::TextureCompression comp)
+{
+ string sLastFilename = pImage->getFilename();
+ string sFilename = sHRef;
+ initFilename(sFilename);
+ if (sLastFilename != sFilename) {
+ try {
+ sFilename = convertUTF8ToFilename(sFilename);
+ if (sHRef == "") {
+ pImage->setEmpty();
+ } else {
+ pImage->setFilename(sFilename, comp);
+ }
+ } catch (Exception& ex) {
+ pImage->setEmpty();
+ logFileNotFoundWarning(ex.getStr());
+ }
+ return true;
+ } else {
+ return false;
+ }
+}
+
+bool Node::isVisible() const
+{
+ return getEffectiveActive() && getEffectiveOpacity() > 0.01;
+}
+
+bool Node::getEffectiveActive() const
+{
+ return m_bEffectiveActive;
+}
+
+NodePtr Node::getSharedThis()
+{
+ return dynamic_pointer_cast<Node>(ExportedObject::getSharedThis());
+}
+
+void Node::logFileNotFoundWarning(const string& sWarn) const
+{
+ unsigned int sev;
+ if (getState() != Node::NS_UNCONNECTED) {
+ sev = Logger::severity::WARNING;
+ } else {
+ sev = Logger::severity::INFO;
+ }
+ AVG_TRACE(Logger::category::MEMORY, sev, sWarn);
+}
+
+void Node::connectOneEventHandler(const EventID& id, PyObject * pObj,
+ PyObject * pFunc)
+{
+ EventHandlerMap::iterator it = m_EventHandlerMap.find(id);
+ EventHandlerArrayPtr pEventHandlers;
+ if (it == m_EventHandlerMap.end()) {
+ pEventHandlers = EventHandlerArrayPtr(new EventHandlerArray);
+ m_EventHandlerMap[id] = pEventHandlers;
+ } else {
+ pEventHandlers = it->second;
+ }
+ pEventHandlers->push_back(EventHandler(pObj, pFunc));
+}
+
+void Node::dumpEventHandlers()
+{
+ EventHandlerMap::iterator it;
+ cerr << "-----" << endl;
+ for (it = m_EventHandlerMap.begin(); it != m_EventHandlerMap.end(); ++it) {
+ EventID id = it->first;
+ EventHandlerArrayPtr pEventHandlers = it->second;
+ cerr << "type: " << id.m_Type << ", source: " << id.m_Source << endl;
+ EventHandlerArray::iterator listIt;
+ for (listIt = pEventHandlers->begin(); listIt != pEventHandlers->end(); ++listIt)
+ {
+ EventHandler& handler = *listIt;
+ cerr << " " << handler.m_pObj << ", " << handler.m_pMethod
+ << endl;
+ }
+ }
+ cerr << "-----" << endl;
+}
+
+string Node::getEventMessageID(const EventPtr& pEvent)
+{
+ Event::Source source = pEvent->getSource();
+ if (source == Event::MOUSE || source == Event::TOUCH) {
+ switch (pEvent->getType()) {
+ case Event::CURSOR_DOWN:
+ return "CURSOR_DOWN";
+ case Event::CURSOR_MOTION:
+ return "CURSOR_MOTION";
+ case Event::CURSOR_UP:
+ return "CURSOR_UP";
+ case Event::CURSOR_OVER:
+ return "CURSOR_OVER";
+ case Event::CURSOR_OUT:
+ return "CURSOR_OUT";
+ default:
+ AVG_ASSERT_MSG(false,
+ (string("Unknown message type ")+pEvent->typeStr()).c_str());
+ return "";
+ }
+ } else {
+ switch (pEvent->getType()) {
+ case Event::CURSOR_DOWN:
+ return "HOVER_DOWN";
+ case Event::CURSOR_MOTION:
+ return "HOVER_MOTION";
+ case Event::CURSOR_UP:
+ return "HOVER_UP";
+ case Event::CURSOR_OVER:
+ return "HOVER_OVER";
+ case Event::CURSOR_OUT:
+ return "HOVER_OUT";
+ default:
+ AVG_ASSERT_MSG(false,
+ (string("Unknown message type ")+pEvent->typeStr()).c_str());
+ return "";
+ }
+ }
+}
+
+bool Node::callPython(PyObject * pFunc, EventPtr pEvent)
+{
+ bool bOk = py::call<bool>(pFunc, pEvent);
+ return bOk;
+}
+
+Node::EventID::EventID(Event::Type eventType, Event::Source source)
+ : m_Type(eventType),
+ m_Source(source)
+{
+}
+
+bool Node::EventID::operator < (const EventID& other) const
+{
+ if (m_Type == other.m_Type) {
+ return m_Source < other.m_Source;
+ } else {
+ return m_Type < other.m_Type;
+ }
+}
+
+Node::EventHandler::EventHandler(PyObject * pObj, PyObject * pMethod)
+{
+ Py_INCREF(pObj);
+ m_pObj = pObj;
+ Py_INCREF(pMethod);
+ m_pMethod = pMethod;
+}
+
+Node::EventHandler::EventHandler(const EventHandler& other)
+{
+ Py_INCREF(other.m_pObj);
+ m_pObj = other.m_pObj;
+ Py_INCREF(other.m_pMethod);
+ m_pMethod = other.m_pMethod;
+}
+
+Node::EventHandler::~EventHandler()
+{
+ Py_DECREF(m_pObj);
+ Py_DECREF(m_pMethod);
+}
+
+}
diff --git a/src/player/Node.h b/src/player/Node.h
new file mode 100644
index 0000000..4ba99ec
--- /dev/null
+++ b/src/player/Node.h
@@ -0,0 +1,195 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _Node_H_
+#define _Node_H_
+
+#include "../api.h"
+
+#include "Publisher.h"
+#include "Event.h"
+#include "Image.h"
+
+#include "../base/Rect.h"
+#include "../graphics/Pixel32.h"
+
+#include <boost/shared_ptr.hpp>
+#include <boost/weak_ptr.hpp>
+
+// Python docs say python.h should be included before any standard headers (!)
+#include "WrapPython.h"
+
+#include <string>
+#include <vector>
+#include <list>
+#include <map>
+
+namespace avg {
+
+class Node;
+typedef boost::shared_ptr<Node> NodePtr;
+class DivNode;
+typedef boost::shared_ptr<DivNode> DivNodePtr;
+class ArgList;
+class TypeDefinition;
+
+class CanvasNode;
+typedef boost::shared_ptr<CanvasNode> CanvasNodePtr;
+class AVGNode;
+typedef boost::shared_ptr<AVGNode> AVGNodePtr;
+class Image;
+typedef boost::shared_ptr<Image> ImagePtr;
+class VertexArray;
+typedef boost::shared_ptr<VertexArray> VertexArrayPtr;
+class Canvas;
+typedef boost::shared_ptr<Canvas> CanvasPtr;
+typedef boost::weak_ptr<Canvas> CanvasWeakPtr;
+
+class AVG_API Node: public Publisher
+{
+ public:
+ enum NodeState {NS_UNCONNECTED, NS_CONNECTED, NS_CANRENDER};
+
+ static void registerType();
+ void registerInstance(PyObject* pSelf, const DivNodePtr& pParent);
+
+ virtual ~Node();
+ virtual void setParent(DivNode* pParent, NodeState parentState,
+ CanvasPtr pCanvas);
+ virtual void removeParent();
+ void checkSetParentError(DivNode* pParent);
+ DivNodePtr getParent() const;
+ std::vector<NodePtr> getParentChain();
+
+ virtual void connectDisplay();
+ virtual void connect(CanvasPtr pCanvas);
+ virtual void disconnect(bool bKill);
+ void unlink(bool bKill=false);
+
+ virtual void checkReload() {};
+
+ virtual void setID(const std::string& ID);
+
+ float getOpacity() const;
+ void setOpacity(float opacity);
+
+ bool getActive() const;
+ void setActive(bool bActive);
+
+ bool getSensitive() const;
+ void setSensitive(bool bSensitive);
+
+ void setMouseEventCapture();
+ void releaseMouseEventCapture();
+ void setEventCapture(int cursorID);
+ void releaseEventCapture(int cursorID);
+ void setEventHandler(Event::Type Type, int Sources, PyObject * pFunc);
+ void connectEventHandler(Event::Type type, int sources,
+ PyObject * pObj, PyObject * pFunc);
+ void disconnectEventHandler(PyObject * pObj, PyObject * pFunc=0);
+
+ glm::vec2 getRelPos(const glm::vec2& absPos) const;
+ glm::vec2 getAbsPos(const glm::vec2& relPos) const;
+ virtual glm::vec2 toLocal(const glm::vec2& pos) const;
+ virtual glm::vec2 toGlobal(const glm::vec2& pos) const;
+ NodePtr getElementByPos(const glm::vec2& pos);
+ virtual void getElementsByPos(const glm::vec2& pos,
+ std::vector<NodePtr>& pElements);
+
+ virtual void preRender(const VertexArrayPtr& pVA, bool bIsParentActive,
+ float parentEffectiveOpacity);
+ virtual void maybeRender(const glm::mat4& parentTransform) {};
+ virtual void render() {};
+ virtual void renderOutlines(const VertexArrayPtr& pVA, Pixel32 color) {};
+
+ float getEffectiveOpacity() const;
+ virtual std::string dump(int indent = 0);
+
+ NodeState getState() const;
+ CanvasPtr getCanvas() const;
+
+ virtual bool handleEvent(EventPtr pEvent);
+
+ virtual const std::string& getID() const;
+
+ protected:
+ Node(const std::string& sPublisherName="Node");
+
+ bool reactsToMouseEvents();
+
+ void setState(NodeState state);
+ void initFilename(std::string& sFilename);
+ bool checkReload(const std::string& sHRef, const ImagePtr& pImage,
+ Image::TextureCompression comp = Image::TEXTURECOMPRESSION_NONE);
+ virtual bool isVisible() const;
+ bool getEffectiveActive() const;
+ NodePtr getSharedThis();
+
+ void logFileNotFoundWarning(const std::string& sWarn) const;
+
+ private:
+ std::string m_ID;
+
+ DivNode* m_pParent;
+
+ struct EventID {
+ EventID(Event::Type eventType, Event::Source source);
+
+ bool operator < (const EventID& other) const;
+
+ Event::Type m_Type;
+ Event::Source m_Source;
+ };
+
+ struct EventHandler {
+ EventHandler(PyObject * pObj, PyObject * pMethod);
+ EventHandler(const EventHandler& other);
+ ~EventHandler();
+
+ PyObject * m_pObj;
+ PyObject * m_pMethod;
+ };
+
+ typedef std::list<EventHandler> EventHandlerArray;
+ typedef boost::shared_ptr<EventHandlerArray> EventHandlerArrayPtr;
+ typedef std::map<EventID, EventHandlerArrayPtr> EventHandlerMap;
+
+ void connectOneEventHandler(const EventID& id, PyObject * pObj, PyObject * pFunc);
+ void dumpEventHandlers();
+ std::string getEventMessageID(const EventPtr& pEvent);
+ bool callPython(PyObject * pFunc, avg::EventPtr pEvent);
+
+ EventHandlerMap m_EventHandlerMap;
+
+ CanvasWeakPtr m_pCanvas;
+
+ float m_Opacity;
+ NodeState m_State;
+
+ bool m_bActive;
+ bool m_bSensitive;
+ float m_EffectiveOpacity;
+ bool m_bEffectiveActive;
+};
+
+}
+
+#endif
diff --git a/src/player/NullFXNode.cpp b/src/player/NullFXNode.cpp
new file mode 100644
index 0000000..d0d943d
--- /dev/null
+++ b/src/player/NullFXNode.cpp
@@ -0,0 +1,61 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "NullFXNode.h"
+
+#include "../base/ObjectCounter.h"
+
+#include <string>
+
+using namespace std;
+
+namespace avg {
+
+NullFXNode::NullFXNode()
+ : FXNode()
+{
+ ObjectCounter::get()->incRef(&typeid(*this));
+}
+
+NullFXNode::~NullFXNode()
+{
+ ObjectCounter::get()->decRef(&typeid(*this));
+}
+
+void NullFXNode::connect()
+{
+ FXNode::connect();
+}
+
+void NullFXNode::disconnect()
+{
+ m_pFilter = GPUNullFilterPtr();
+ FXNode::disconnect();
+}
+
+GPUFilterPtr NullFXNode::createFilter(const IntPoint& size)
+{
+ m_pFilter = GPUNullFilterPtr(new GPUNullFilter(size, false));
+ setDirty();
+ return m_pFilter;
+}
+
+}
diff --git a/src/player/NullFXNode.h b/src/player/NullFXNode.h
new file mode 100644
index 0000000..107ce4b
--- /dev/null
+++ b/src/player/NullFXNode.h
@@ -0,0 +1,53 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _NullFXNode_H_
+#define _NullFXNode_H_
+
+#include "../api.h"
+
+#include "FXNode.h"
+#include "../graphics/GPUNullFilter.h"
+
+#include <boost/shared_ptr.hpp>
+
+namespace avg {
+
+class AVG_API NullFXNode: public FXNode {
+public:
+ NullFXNode();
+ virtual ~NullFXNode();
+
+ virtual void connect();
+ virtual void disconnect();
+
+private:
+ virtual GPUFilterPtr createFilter(const IntPoint& size);
+
+ GPUNullFilterPtr m_pFilter;
+};
+
+typedef boost::shared_ptr<NullFXNode> NullFXNodePtr;
+
+}
+
+#endif
+
diff --git a/src/player/OGLSurface.cpp b/src/player/OGLSurface.cpp
new file mode 100644
index 0000000..b0aa58e
--- /dev/null
+++ b/src/player/OGLSurface.cpp
@@ -0,0 +1,262 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "OGLSurface.h"
+
+#include "../base/MathHelper.h"
+#include "../base/Logger.h"
+#include "../base/Exception.h"
+#include "../base/ScopeTimer.h"
+#include "../base/ObjectCounter.h"
+
+#include "../graphics/GLContext.h"
+#include "../graphics/GLTexture.h"
+
+#include <iostream>
+#include <sstream>
+
+#include "../glm/gtc/matrix_transform.hpp"
+
+using namespace std;
+
+static glm::mat4 yuvCoeff(
+ 1.0f, 1.0f, 1.0f, 0.0f,
+ 0.0f, -0.34f, 1.77f, 0.0f,
+ 1.40f, -0.71f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 1.0f);
+
+namespace avg {
+
+OGLSurface::OGLSurface()
+ : m_Size(-1,-1),
+ m_Gamma(1,1,1),
+ m_Brightness(1,1,1),
+ m_Contrast(1,1,1),
+ m_AlphaGamma(1),
+ m_bIsDirty(true)
+{
+ ObjectCounter::get()->incRef(&typeid(*this));
+}
+
+OGLSurface::~OGLSurface()
+{
+ ObjectCounter::get()->decRef(&typeid(*this));
+}
+
+void OGLSurface::create(PixelFormat pf, GLTexturePtr pTex0, GLTexturePtr pTex1,
+ GLTexturePtr pTex2, GLTexturePtr pTex3)
+{
+ m_pf = pf;
+ m_Size = pTex0->getSize();
+ m_pTextures[0] = pTex0;
+ m_pTextures[1] = pTex1;
+ m_pTextures[2] = pTex2;
+ m_pTextures[3] = pTex3;
+ m_bIsDirty = true;
+
+ // Make sure pixel format and number of textures line up.
+ if (pixelFormatIsPlanar(pf)) {
+ AVG_ASSERT(m_pTextures[2]);
+ if (pixelFormatHasAlpha(m_pf)) {
+ AVG_ASSERT(m_pTextures[3]);
+ } else {
+ AVG_ASSERT(!m_pTextures[3]);
+ }
+ } else {
+ AVG_ASSERT(!m_pTextures[1]);
+ }
+}
+
+void OGLSurface::setMask(GLTexturePtr pTex)
+{
+ m_pMaskTexture = pTex;
+ m_bIsDirty = true;
+}
+
+void OGLSurface::destroy()
+{
+ m_pTextures[0] = GLTexturePtr();
+ m_pTextures[1] = GLTexturePtr();
+ m_pTextures[2] = GLTexturePtr();
+ m_pTextures[3] = GLTexturePtr();
+}
+
+void OGLSurface::activate(const IntPoint& logicalSize, bool bPremultipliedAlpha) const
+{
+ StandardShaderPtr pShader = StandardShader::get();
+
+ GLContext::checkError("OGLSurface::activate()");
+ switch (m_pf) {
+ case YCbCr420p:
+ case YCbCrJ420p:
+ pShader->setColorModel(1);
+ break;
+ case YCbCrA420p:
+ pShader->setColorModel(3);
+ break;
+ case A8:
+ pShader->setColorModel(2);
+ break;
+ default:
+ pShader->setColorModel(0);
+ }
+
+ m_pTextures[0]->activate(GL_TEXTURE0);
+
+ if (pixelFormatIsPlanar(m_pf)) {
+ m_pTextures[1]->activate(GL_TEXTURE1);
+ m_pTextures[2]->activate(GL_TEXTURE2);
+ if (m_pf == YCbCrA420p) {
+ m_pTextures[3]->activate(GL_TEXTURE3);
+ }
+ }
+ if (pixelFormatIsPlanar(m_pf) || colorIsModified()) {
+ glm::mat4 mat = calcColorspaceMatrix();
+ pShader->setColorspaceMatrix(mat);
+ } else {
+ pShader->disableColorspaceMatrix();
+ }
+ pShader->setGamma(glm::vec4(1/m_Gamma.x, 1/m_Gamma.y, 1/m_Gamma.z,
+ 1./m_AlphaGamma));
+
+ pShader->setPremultipliedAlpha(bPremultipliedAlpha);
+ if (m_pMaskTexture) {
+ m_pMaskTexture->activate(GL_TEXTURE4);
+ // Special case for pot textures:
+ // The tex coords in the vertex array are scaled to fit the image texture. We
+ // need to undo this and fit to the mask texture. In the npot case, everything
+ // evaluates to (1,1);
+ glm::vec2 texSize = glm::vec2(m_pTextures[0]->getGLSize());
+ glm::vec2 imgSize = glm::vec2(m_pTextures[0]->getSize());
+ glm::vec2 maskTexSize = glm::vec2(m_pMaskTexture->getGLSize());
+ glm::vec2 maskImgSize = glm::vec2(m_pMaskTexture->getSize());
+ glm::vec2 maskScale = glm::vec2(maskTexSize.x/maskImgSize.x,
+ maskTexSize.y/maskImgSize.y);
+ glm::vec2 imgScale = glm::vec2(texSize.x/imgSize.x, texSize.y/imgSize.y);
+ glm::vec2 maskPos = m_MaskPos/maskScale;
+ // Special case for words nodes.
+ if (logicalSize != IntPoint(0,0)) {
+ maskScale *= glm::vec2((float)logicalSize.x/m_Size.x,
+ (float)logicalSize.y/m_Size.y);
+ }
+ pShader->setMask(true, maskPos, m_MaskSize*maskScale/imgScale);
+ } else {
+ pShader->setMask(false);
+ }
+ pShader->activate();
+ GLContext::checkError("OGLSurface::activate");
+}
+
+GLTexturePtr OGLSurface::getTex(int i) const
+{
+ return m_pTextures[i];
+}
+
+void OGLSurface::setMaskCoords(glm::vec2 maskPos, glm::vec2 maskSize)
+{
+ m_MaskPos = maskPos;
+ m_MaskSize = maskSize;
+ m_bIsDirty = true;
+}
+
+PixelFormat OGLSurface::getPixelFormat()
+{
+ return m_pf;
+}
+
+IntPoint OGLSurface::getSize()
+{
+ return m_Size;
+}
+
+IntPoint OGLSurface::getTextureSize()
+{
+ return m_pTextures[0]->getGLSize();
+}
+
+bool OGLSurface::isCreated() const
+{
+ return m_pTextures[0];
+}
+
+void OGLSurface::setColorParams(const glm::vec3& gamma, const glm::vec3& brightness,
+ const glm::vec3& contrast)
+{
+ m_Gamma = gamma;
+ m_Brightness = brightness;
+ m_Contrast = contrast;
+ m_bIsDirty = true;
+}
+
+void OGLSurface::setAlphaGamma(float gamma)
+{
+ m_AlphaGamma = gamma;
+ m_bIsDirty = true;
+}
+
+bool OGLSurface::isDirty() const
+{
+ bool bIsDirty = m_bIsDirty;
+ for (unsigned i=0; i<getNumPixelFormatPlanes(m_pf); ++i) {
+ if (m_pTextures[i]->isDirty()) {
+ bIsDirty = true;
+ }
+ }
+ return bIsDirty;
+}
+
+void OGLSurface::resetDirty()
+{
+ m_bIsDirty = false;
+ for (unsigned i=0; i<getNumPixelFormatPlanes(m_pf); ++i) {
+ m_pTextures[i]->resetDirty();
+ }
+}
+
+glm::mat4 OGLSurface::calcColorspaceMatrix() const
+{
+ glm::mat4 mat;
+ if (colorIsModified()) {
+ mat = glm::scale(mat, m_Brightness);
+ glm::vec3 contrast = glm::vec3(0.5f, 0.5f, 0.5f) - m_Contrast/2.f;
+ mat = glm::translate(mat, contrast);
+ mat = glm::scale(mat, m_Contrast);
+ }
+ if (m_pf == YCbCr420p || m_pf == YCbCrJ420p || m_pf == YCbCrA420p) {
+ mat *= yuvCoeff;
+ mat = glm::translate(mat, glm::vec3(0.0, -0.5, -0.5));
+ if (m_pf == YCbCr420p || m_pf == YCbCrA420p) {
+ mat = glm::scale(mat,
+ glm::vec3(255.0f/(235-16), 255.0f/(235-16), 255.0f/(235-16)));
+ mat = glm::translate(mat, glm::vec3(-16.0f/255, -16.0f/255, -16.0f/255));
+ }
+ }
+ return mat;
+}
+
+bool OGLSurface::colorIsModified() const
+{
+ return (fabs(m_Brightness.x-1.0) > 0.00001 || fabs(m_Brightness.y-1.0) > 0.00001 ||
+ fabs(m_Brightness.z-1.0) > 0.00001 || fabs(m_Contrast.x-1.0) > 0.00001 ||
+ fabs(m_Contrast.y-1.0) > 0.00001 || fabs(m_Contrast.z-1.0) > 0.00001);
+}
+
+}
diff --git a/src/player/OGLSurface.h b/src/player/OGLSurface.h
new file mode 100644
index 0000000..38e6ef4
--- /dev/null
+++ b/src/player/OGLSurface.h
@@ -0,0 +1,93 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _OGLSurface_H_
+#define _OGLSurface_H_
+
+#include "../api.h"
+
+#include "../base/GLMHelper.h"
+
+#include "../graphics/Bitmap.h"
+#include "../graphics/OGLHelper.h"
+#include "../graphics/StandardShader.h"
+
+#include <vector>
+#include <string>
+
+namespace avg {
+
+class GLTexture;
+typedef boost::shared_ptr<GLTexture> GLTexturePtr;
+
+
+class AVG_API OGLSurface {
+public:
+ OGLSurface();
+ virtual ~OGLSurface();
+
+ virtual void create(PixelFormat pf, GLTexturePtr pTex0,
+ GLTexturePtr pTex1 = GLTexturePtr(), GLTexturePtr pTex2 = GLTexturePtr(),
+ GLTexturePtr pTex3 = GLTexturePtr());
+ void setMask(GLTexturePtr pTex);
+ virtual void destroy();
+ void activate(const IntPoint& logicalSize = IntPoint(1,1),
+ bool bPremultipliedAlpha = false) const;
+ GLTexturePtr getTex(int i=0) const;
+
+ void setMaskCoords(glm::vec2 maskPos, glm::vec2 maskSize);
+
+ PixelFormat getPixelFormat();
+ IntPoint getSize();
+ IntPoint getTextureSize();
+ bool isCreated() const;
+
+ void setColorParams(const glm::vec3& gamma, const glm::vec3& brightness,
+ const glm::vec3& contrast);
+ void setAlphaGamma(float gamma);
+
+ bool isDirty() const;
+ void resetDirty();
+
+private:
+ glm::mat4 calcColorspaceMatrix() const;
+ bool colorIsModified() const;
+
+ GLTexturePtr m_pTextures[4];
+ IntPoint m_Size;
+ PixelFormat m_pf;
+ GLTexturePtr m_pMaskTexture;
+ glm::vec2 m_MaskPos;
+ glm::vec2 m_MaskSize;
+
+ glm::vec3 m_Gamma;
+ glm::vec3 m_Brightness;
+ glm::vec3 m_Contrast;
+ float m_AlphaGamma;
+
+ bool m_bIsDirty;
+
+};
+
+}
+
+#endif
+
diff --git a/src/player/OffscreenCanvas.cpp b/src/player/OffscreenCanvas.cpp
new file mode 100644
index 0000000..758bf43
--- /dev/null
+++ b/src/player/OffscreenCanvas.cpp
@@ -0,0 +1,271 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "OffscreenCanvas.h"
+
+#include "CanvasNode.h"
+#include "Player.h"
+
+#include "../base/Exception.h"
+#include "../base/ProfilingZoneID.h"
+#include "../base/ObjectCounter.h"
+#include "../base/ScopeTimer.h"
+
+#include "../graphics/FilterUnmultiplyAlpha.h"
+#include "../graphics/BitmapLoader.h"
+
+#include <iostream>
+
+using namespace boost;
+using namespace std;
+
+namespace avg {
+
+OffscreenCanvas::OffscreenCanvas(Player * pPlayer)
+ : Canvas(pPlayer),
+ m_bIsRendered(false),
+ m_pCameraNodeRef(0)
+{
+ ObjectCounter::get()->incRef(&typeid(*this));
+}
+
+OffscreenCanvas::~OffscreenCanvas()
+{
+ ObjectCounter::get()->decRef(&typeid(*this));
+}
+
+void OffscreenCanvas::setRoot(NodePtr pRootNode)
+{
+ Canvas::setRoot(pRootNode);
+ if (!getRootNode()) {
+ throw (Exception(AVG_ERR_XML_PARSE,
+ "Root node of a canvas tree needs to be a <canvas> node."));
+ }
+}
+
+void OffscreenCanvas::initPlayback()
+{
+ m_bUseMipmaps = getMipmap();
+ PixelFormat pf;
+ if (BitmapLoader::get()->isBlueFirst()) {
+ pf = B8G8R8A8;
+ } else {
+ pf = R8G8B8A8;
+ }
+ bool bUseDepthBuffer = GLContext::getMain()->useDepthBuffer();
+ m_pFBO = FBOPtr(new FBO(getSize(), pf, 1, getMultiSampleSamples(), bUseDepthBuffer,
+ true, m_bUseMipmaps));
+ Canvas::initPlayback(getMultiSampleSamples());
+ m_bIsRendered = false;
+}
+
+void OffscreenCanvas::stopPlayback(bool bIsAbort)
+{
+ m_pFBO = FBOPtr();
+ Canvas::stopPlayback(bIsAbort);
+ m_bIsRendered = false;
+}
+
+BitmapPtr OffscreenCanvas::screenshot() const
+{
+ BitmapPtr pBmp = screenshotIgnoreAlpha();
+ FilterUnmultiplyAlpha().applyInPlace(pBmp);
+ return pBmp;
+}
+
+BitmapPtr OffscreenCanvas::screenshotIgnoreAlpha() const
+{
+ if (!isRunning() || !m_bIsRendered) {
+ throw(Exception(AVG_ERR_UNSUPPORTED,
+ "OffscreenCanvas::screenshot(): Canvas has not been rendered. No screenshot available"));
+ }
+ BitmapPtr pBmp = m_pFBO->getImage(0);
+ return pBmp;
+}
+
+bool OffscreenCanvas::getHandleEvents() const
+{
+ return dynamic_pointer_cast<OffscreenCanvasNode>(getRootNode())->getHandleEvents();
+}
+
+int OffscreenCanvas::getMultiSampleSamples() const
+{
+ return dynamic_pointer_cast<OffscreenCanvasNode>(
+ getRootNode())->getMultiSampleSamples();
+}
+
+bool OffscreenCanvas::getMipmap() const
+{
+ return dynamic_pointer_cast<OffscreenCanvasNode>(getRootNode())->getMipmap();
+}
+
+bool OffscreenCanvas::getAutoRender() const
+{
+ return dynamic_pointer_cast<OffscreenCanvasNode>(getRootNode())->getAutoRender();
+}
+
+void OffscreenCanvas::setAutoRender(bool bAutoRender)
+{
+ dynamic_pointer_cast<OffscreenCanvasNode>(getRootNode())->setAutoRender(bAutoRender);
+}
+
+void OffscreenCanvas::manualRender()
+{
+ emitPreRenderSignal();
+ renderTree();
+ emitFrameEndSignal();
+}
+
+std::string OffscreenCanvas::getID() const
+{
+ return getRootNode()->getID();
+}
+
+bool OffscreenCanvas::isRunning() const
+{
+ return (m_pFBO != FBOPtr());
+}
+
+GLTexturePtr OffscreenCanvas::getTex() const
+{
+ AVG_ASSERT(isRunning());
+ return m_pFBO->getTex();
+}
+
+FBOPtr OffscreenCanvas::getFBO() const
+{
+ AVG_ASSERT(isRunning());
+ return m_pFBO;
+}
+
+void OffscreenCanvas::registerCameraNode(CameraNode* pCameraNode)
+{
+ m_pCameraNodeRef = pCameraNode;
+ m_pCameraNodeRef->setAutoUpdateCameraImage(false);
+}
+
+void OffscreenCanvas::unregisterCameraNode()
+{
+ m_pCameraNodeRef->setAutoUpdateCameraImage(true);
+ m_pCameraNodeRef = NULL;
+}
+
+void OffscreenCanvas::updateCameraImage()
+{
+ m_pCameraNodeRef->updateCameraImage();
+}
+
+bool OffscreenCanvas::hasRegisteredCamera() const
+{
+ return m_pCameraNodeRef != NULL;
+}
+
+bool OffscreenCanvas::isCameraImageAvailable() const
+{
+ if (!hasRegisteredCamera()) {
+ return false;
+ }
+ return m_pCameraNodeRef->isImageAvailable();
+}
+
+void OffscreenCanvas::addDependentCanvas(CanvasPtr pCanvas)
+{
+ m_pDependentCanvases.push_back(pCanvas);
+ try {
+ Player::get()->newCanvasDependency();
+ } catch (Exception&) {
+ m_pDependentCanvases.pop_back();
+ throw;
+ }
+}
+
+void OffscreenCanvas::removeDependentCanvas(CanvasPtr pCanvas)
+{
+ for (unsigned i = 0; i < m_pDependentCanvases.size(); ++i) {
+ if (pCanvas == m_pDependentCanvases[i]) {
+ m_pDependentCanvases.erase(m_pDependentCanvases.begin()+i);
+// dump();
+ return;
+ }
+ }
+ AVG_ASSERT(false);
+}
+
+const vector<CanvasPtr>& OffscreenCanvas::getDependentCanvases() const
+{
+ return m_pDependentCanvases;
+}
+
+unsigned OffscreenCanvas::getNumDependentCanvases() const
+{
+ return m_pDependentCanvases.size();
+}
+
+bool OffscreenCanvas::isSupported()
+{
+ if (!Player::get()->isPlaying()) {
+ throw(Exception(AVG_ERR_UNSUPPORTED,
+ "OffscreenCanvas::isSupported(): Player.play() needs to be called before support can be queried."));
+ }
+ if (GLContext::getMain()->isGLES()) {
+ return true;
+ } else {
+ return FBO::isFBOSupported() && FBO::isPackedDepthStencilSupported();
+ }
+}
+
+bool OffscreenCanvas::isMultisampleSupported()
+{
+ if (!Player::get()->isPlaying()) {
+ throw(Exception(AVG_ERR_UNSUPPORTED,
+ "OffscreenCanvas::isMultisampleSupported(): Player.play() needs to be called before multisample support can be queried."));
+ }
+
+ return FBO::isMultisampleFBOSupported();
+}
+
+void OffscreenCanvas::dump() const
+{
+ cerr << "Canvas: " << getRootNode()->getID() << endl;
+ for (unsigned i = 0; i < m_pDependentCanvases.size(); ++i) {
+ cerr << " " << m_pDependentCanvases[i]->getRootNode()->getID() << endl;
+ }
+}
+
+static ProfilingZoneID OffscreenRenderProfilingZone("Render OffscreenCanvas");
+
+void OffscreenCanvas::renderTree()
+{
+ if (!isRunning()) {
+ throw(Exception(AVG_ERR_UNSUPPORTED,
+ "OffscreenCanvas::renderTree(): Player.play() needs to be called before rendering offscreen canvases."));
+ }
+ preRender();
+ m_pFBO->activate();
+ {
+ ScopeTimer Timer(OffscreenRenderProfilingZone);
+ Canvas::render(IntPoint(getRootNode()->getSize()), true);
+ }
+ m_pFBO->copyToDestTexture();
+ m_bIsRendered = true;
+}
+
+}
diff --git a/src/player/OffscreenCanvas.h b/src/player/OffscreenCanvas.h
new file mode 100644
index 0000000..4d740b6
--- /dev/null
+++ b/src/player/OffscreenCanvas.h
@@ -0,0 +1,91 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _OffscreenCanvas_H_
+#define _OffscreenCanvas_H_
+
+#include "../api.h"
+#include "Canvas.h"
+#include "OffscreenCanvasNode.h"
+
+#include "CameraNode.h"
+
+#include "../graphics/FBO.h"
+
+#include <string>
+
+namespace avg {
+
+class AVG_API OffscreenCanvas: public Canvas
+{
+ public:
+ OffscreenCanvas(Player * pPlayer);
+ virtual ~OffscreenCanvas();
+ virtual void setRoot(NodePtr pRootNode);
+ virtual void initPlayback();
+ virtual void stopPlayback(bool bIsAbort);
+
+ virtual BitmapPtr screenshot() const;
+ virtual BitmapPtr screenshotIgnoreAlpha() const;
+ bool getHandleEvents() const;
+ int getMultiSampleSamples() const;
+ bool getMipmap() const;
+ bool getAutoRender() const;
+ void setAutoRender(bool bAutoRender);
+ void manualRender(); // This is the render that can be called from python.
+
+ std::string getID() const;
+ bool isRunning() const;
+ GLTexturePtr getTex() const;
+ FBOPtr getFBO() const;
+
+ void registerCameraNode(CameraNode* pCameraNode);
+ void unregisterCameraNode();
+ void updateCameraImage();
+ bool hasRegisteredCamera() const;
+ bool isCameraImageAvailable() const;
+
+ void addDependentCanvas(CanvasPtr pCanvas);
+ void removeDependentCanvas(CanvasPtr pCanvas);
+ const std::vector<CanvasPtr>& getDependentCanvases() const;
+ unsigned getNumDependentCanvases() const;
+
+ static bool isSupported();
+ static bool isMultisampleSupported();
+ void dump() const;
+
+ protected:
+ virtual void renderTree();
+
+ private:
+ FBOPtr m_pFBO;
+ bool m_bUseMipmaps;
+ std::vector<CanvasPtr> m_pDependentCanvases;
+
+ bool m_bIsRendered;
+ CameraNode* m_pCameraNodeRef;
+};
+
+typedef boost::shared_ptr<OffscreenCanvas> OffscreenCanvasPtr;
+
+}
+#endif
+
diff --git a/src/player/OffscreenCanvasNode.cpp b/src/player/OffscreenCanvasNode.cpp
new file mode 100644
index 0000000..8f712c3
--- /dev/null
+++ b/src/player/OffscreenCanvasNode.cpp
@@ -0,0 +1,83 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "OffscreenCanvasNode.h"
+#include "Player.h"
+
+#include "TypeDefinition.h"
+
+#include "../base/FileHelper.h"
+
+using namespace std;
+
+namespace avg {
+
+void OffscreenCanvasNode::registerType()
+{
+ TypeDefinition def = TypeDefinition("canvas", "canvasbase",
+ ExportedObject::buildObject<OffscreenCanvasNode>)
+ .addArg(Arg<bool>("handleevents", false, false,
+ offsetof(OffscreenCanvasNode, m_bHandleEvents)))
+ .addArg(Arg<int>("multisamplesamples", 1, false,
+ offsetof(OffscreenCanvasNode, m_MultiSampleSamples)))
+ .addArg(Arg<bool>("mipmap", false, false,
+ offsetof(OffscreenCanvasNode, m_bMipmap)))
+ .addArg(Arg<bool>("autorender", true, false,
+ offsetof(OffscreenCanvasNode, m_bAutoRender)));
+ TypeRegistry::get()->registerType(def);
+}
+
+OffscreenCanvasNode::OffscreenCanvasNode(const ArgList& args)
+ : CanvasNode(args)
+{
+ args.setMembers(this);
+}
+
+OffscreenCanvasNode::~OffscreenCanvasNode()
+{
+}
+
+bool OffscreenCanvasNode::getHandleEvents() const
+{
+ return m_bHandleEvents;
+}
+
+int OffscreenCanvasNode::getMultiSampleSamples() const
+{
+ return m_MultiSampleSamples;
+}
+
+bool OffscreenCanvasNode::getMipmap() const
+{
+ return m_bMipmap;
+}
+
+bool OffscreenCanvasNode::getAutoRender() const
+{
+ return m_bAutoRender;
+}
+
+void OffscreenCanvasNode::setAutoRender(bool bAutoRender)
+{
+ m_bAutoRender = bAutoRender;
+}
+
+}
diff --git a/src/player/OffscreenCanvasNode.h b/src/player/OffscreenCanvasNode.h
new file mode 100644
index 0000000..9d2e850
--- /dev/null
+++ b/src/player/OffscreenCanvasNode.h
@@ -0,0 +1,57 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _OffscreenCanvasNode_H_
+#define _OffscreenCanvasNode_H_
+
+#include "../api.h"
+#include "CanvasNode.h"
+
+#include <string>
+
+namespace avg {
+
+class AVG_API OffscreenCanvasNode : public CanvasNode
+{
+ public:
+ static void registerType();
+
+ OffscreenCanvasNode(const ArgList& args);
+ virtual ~OffscreenCanvasNode();
+
+ bool getHandleEvents() const;
+ int getMultiSampleSamples() const;
+ bool getMipmap() const;
+ bool getAutoRender() const;
+ void setAutoRender(bool bAutoRender);
+
+ private:
+ bool m_bHandleEvents;
+ int m_MultiSampleSamples;
+ bool m_bMipmap;
+ bool m_bAutoRender;
+};
+
+typedef boost::shared_ptr<OffscreenCanvasNode> OffscreenCanvasNodePtr;
+
+}
+
+#endif
diff --git a/src/player/Player.cpp b/src/player/Player.cpp
new file mode 100644
index 0000000..77f27d0
--- /dev/null
+++ b/src/player/Player.cpp
@@ -0,0 +1,1835 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "Player.h"
+
+#include "../avgconfigwrapper.h"
+
+#include "AVGNode.h"
+#include "DivNode.h"
+#include "WordsNode.h"
+#include "VideoNode.h"
+#include "CameraNode.h"
+#include "ImageNode.h"
+#include "SoundNode.h"
+#include "LineNode.h"
+#include "RectNode.h"
+#include "CurveNode.h"
+#include "PolyLineNode.h"
+#include "PolygonNode.h"
+#include "CircleNode.h"
+#include "MeshNode.h"
+#include "FontStyle.h"
+#include "PluginManager.h"
+#include "TextEngine.h"
+#include "TestHelper.h"
+#include "MainCanvas.h"
+#include "OffscreenCanvas.h"
+#include "TrackerInputDevice.h"
+#include "SDLDisplayEngine.h"
+#include "MultitouchInputDevice.h"
+#include "TUIOInputDevice.h"
+#include "OGLSurface.h"
+#ifdef __APPLE__
+ #include "AppleTrackpadInputDevice.h"
+#endif
+#if defined(_WIN32) && defined(SM_DIGITIZER)
+ #include "Win7TouchInputDevice.h"
+#endif
+#ifdef AVG_ENABLE_MTDEV
+ #include "LibMTDevInputDevice.h"
+#endif
+#if defined(HAVE_XI2_1) || defined(HAVE_XI2_2)
+ #include "XInputMTInputDevice.h"
+#endif
+#include "Contact.h"
+#include "KeyEvent.h"
+#include "MouseEvent.h"
+#include "EventDispatcher.h"
+#include "PublisherDefinition.h"
+#include "BitmapManager.h"
+
+#include "../base/FileHelper.h"
+#include "../base/StringHelper.h"
+#include "../base/OSHelper.h"
+#include "../base/Exception.h"
+#include "../base/Logger.h"
+#include "../base/ConfigMgr.h"
+#include "../base/XMLHelper.h"
+#include "../base/ScopeTimer.h"
+#include "../base/WorkerThread.h"
+#include "../base/DAG.h"
+
+#include "../graphics/BitmapLoader.h"
+#include "../graphics/ShaderRegistry.h"
+#include "../graphics/Display.h"
+
+#include "../imaging/Camera.h"
+
+#include "../audio/AudioEngine.h"
+
+#include <libxml/xmlmemory.h>
+
+#ifdef _WIN32
+#include <direct.h>
+#define getcwd _getcwd
+#endif
+
+#include <iostream>
+
+#ifdef __linux
+#include <fenv.h>
+#endif
+
+#include <glib-object.h>
+#include <typeinfo>
+
+using namespace std;
+using namespace boost;
+
+namespace avg {
+
+Player * Player::s_pPlayer=0;
+
+Player::Player()
+ : Publisher("Player"),
+ m_pDisplayEngine(),
+ m_bDisplayEngineBroken(false),
+ m_bIsTraversingTree(false),
+ m_pMultitouchInputDevice(),
+ m_bInHandleTimers(false),
+ m_bCurrentTimeoutDeleted(false),
+ m_bKeepWindowOpen(false),
+ m_bStopOnEscape(true),
+ m_bIsPlaying(false),
+ m_bFakeFPS(false),
+ m_FakeFPS(0),
+ m_FrameTime(0),
+ m_Volume(1),
+ m_bPythonAvailable(true),
+ m_pLastMouseEvent(new MouseEvent(Event::CURSOR_MOTION, false, false, false,
+ IntPoint(-1, -1), MouseEvent::NO_BUTTON, glm::vec2(-1, -1), 0)),
+ m_EventHookPyFunc(Py_None),
+ m_bMouseEnabled(true)
+{
+ string sDummy;
+#ifdef _WIN32
+ if (getEnv("AVG_WIN_CRASH_SILENTLY", sDummy)) {
+ DWORD dwMode = SetErrorMode(SEM_NOGPFAULTERRORBOX);
+ SetErrorMode(dwMode | SEM_NOGPFAULTERRORBOX);
+ }
+#endif
+#ifdef __linux
+// Turning this on causes fp exceptions in the linux nvidia drivers.
+// feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW);
+#endif
+ setAffinityMask(true);
+
+ if (s_pPlayer) {
+ throw Exception(AVG_ERR_UNKNOWN, "Player has already been instantiated.");
+ }
+ ThreadProfiler* pProfiler = ThreadProfiler::get();
+ pProfiler->setName("main");
+
+ SDLDisplayEngine::initSDL();
+ initConfig();
+
+ FontStyle::registerType();
+ Node::registerType();
+ AreaNode::registerType();
+ RasterNode::registerType();
+ VectorNode::registerType();
+ FilledVectorNode::registerType();
+
+ DivNode::registerType();
+ CanvasNode::registerType();
+ OffscreenCanvasNode::registerType();
+ AVGNode::registerType();
+ ImageNode::registerType();
+ WordsNode::registerType();
+ VideoNode::registerType();
+ CameraNode::registerType();
+ SoundNode::registerType();
+ LineNode::registerType();
+ RectNode::registerType();
+ CurveNode::registerType();
+ PolyLineNode::registerType();
+ PolygonNode::registerType();
+ CircleNode::registerType();
+ MeshNode::registerType();
+
+ Contact::registerType();
+
+ m_pTestHelper = TestHelperPtr(new TestHelper());
+
+ s_pPlayer = this;
+
+ m_CurDirName = getCWD();
+ if (getEnv("AVG_BREAK_ON_IMPORT", sDummy)) {
+ debugBreak();
+ }
+}
+
+void deletePlayer()
+{
+ delete Player::s_pPlayer;
+ Player::s_pPlayer = 0;
+}
+
+Player::~Player()
+{
+ m_pMainCanvas = MainCanvasPtr();
+ if (m_pDisplayEngine) {
+ m_pDisplayEngine->teardown();
+ }
+ SDLDisplayEngine::quitSDL();
+}
+
+Player* Player::get()
+{
+ if (!s_pPlayer) {
+ s_pPlayer = new Player();
+ atexit(deletePlayer);
+ }
+ return s_pPlayer;
+}
+
+bool Player::exists()
+{
+ return s_pPlayer != 0;
+}
+
+void Player::setResolution(bool bFullscreen, int width, int height, int bpp)
+{
+ errorIfPlaying("Player.setResolution");
+ m_DP.m_bFullscreen = bFullscreen;
+ if (bpp) {
+ m_DP.m_BPP = bpp;
+ }
+ if (width) {
+ m_DP.m_WindowSize.x = width;
+ }
+ if (height) {
+ m_DP.m_WindowSize.y = height;
+ }
+}
+
+bool Player::isFullscreen()
+{
+ return m_DP.m_bFullscreen;
+}
+
+void Player::setWindowFrame(bool bHasWindowFrame)
+{
+ errorIfPlaying("Player.setWindowFrame");
+ m_DP.m_bHasWindowFrame = bHasWindowFrame;
+}
+
+void Player::setWindowPos(int x, int y)
+{
+ errorIfPlaying("Player.setWindowPos");
+ m_DP.m_Pos.x = x;
+ m_DP.m_Pos.y = y;
+}
+
+void Player::setWindowTitle(const string& sTitle)
+{
+ m_pDisplayEngine->setWindowTitle(sTitle);
+}
+
+void Player::useGLES(bool bGLES)
+{
+ errorIfPlaying("Player.useGLES");
+ m_GLConfig.m_bGLES = bGLES;
+#ifdef AVG_ENABLE_EGL
+ m_GLConfig.m_bGLES = true;
+#endif
+ BitmapLoader::init(!m_GLConfig.m_bGLES);
+}
+
+void Player::setOGLOptions(bool bUsePOTTextures, bool bUsePixelBuffers,
+ int multiSampleSamples, GLConfig::ShaderUsage shaderUsage,
+ bool bUseDebugContext)
+{
+ errorIfPlaying("Player.setOGLOptions");
+ m_GLConfig.m_bUsePOTTextures = bUsePOTTextures;
+ m_GLConfig.m_bUsePixelBuffers = bUsePixelBuffers;
+ setMultiSampleSamples(multiSampleSamples);
+ m_GLConfig.m_ShaderUsage = shaderUsage;
+ m_GLConfig.m_bUseDebugContext = bUseDebugContext;
+}
+
+void Player::setMultiSampleSamples(int multiSampleSamples)
+{
+ errorIfPlaying("Player.setMultiSampleSamples");
+ if (multiSampleSamples < 1) {
+ throw Exception(AVG_ERR_OUT_OF_RANGE,
+ "MultiSampleSamples must be 1 or greater (was " +
+ toString(multiSampleSamples) + ").");
+ }
+ m_GLConfig.m_MultiSampleSamples = multiSampleSamples;
+}
+
+void Player::setAudioOptions(int samplerate, int channels)
+{
+ errorIfPlaying("Player.setAudioOptions");
+ m_AP.m_SampleRate = samplerate;
+ m_AP.m_Channels = channels;
+}
+
+void Player::enableGLErrorChecks(bool bEnable)
+{
+ GLContext::enableErrorChecks(bEnable);
+}
+
+glm::vec2 Player::getScreenResolution()
+{
+ return glm::vec2(Display::get()->getScreenResolution());
+}
+
+float Player::getPixelsPerMM()
+{
+ return Display::get()->getPixelsPerMM();
+}
+
+glm::vec2 Player::getPhysicalScreenDimensions()
+{
+ return Display::get()->getPhysicalScreenDimensions();
+}
+
+void Player::assumePixelsPerMM(float ppmm)
+{
+ Display::get()->assumePixelsPerMM(ppmm);
+}
+
+CanvasPtr Player::loadFile(const string& sFilename)
+{
+ errorIfPlaying("Player.loadFile");
+ NodePtr pNode = loadMainNodeFromFile(sFilename);
+ if (m_pMainCanvas) {
+ cleanup(false);
+ }
+
+ initMainCanvas(pNode);
+
+ return m_pMainCanvas;
+}
+
+CanvasPtr Player::loadString(const string& sAVG)
+{
+ errorIfPlaying("Player.loadString");
+ if (m_pMainCanvas) {
+ cleanup(false);
+ }
+
+ NodePtr pNode = loadMainNodeFromString(sAVG);
+ initMainCanvas(pNode);
+
+ return m_pMainCanvas;
+}
+
+OffscreenCanvasPtr Player::loadCanvasFile(const string& sFilename)
+{
+ NodePtr pNode = loadMainNodeFromFile(sFilename);
+ return registerOffscreenCanvas(pNode);
+}
+
+OffscreenCanvasPtr Player::loadCanvasString(const string& sAVG)
+{
+ NodePtr pNode = loadMainNodeFromString(sAVG);
+ return registerOffscreenCanvas(pNode);
+}
+
+CanvasPtr Player::createMainCanvas(const py::dict& params)
+{
+ errorIfPlaying("Player.createMainCanvas");
+ if (m_pMainCanvas) {
+ cleanup(false);
+ }
+
+ NodePtr pNode = createNode("avg", params);
+ initMainCanvas(pNode);
+
+ return m_pMainCanvas;
+}
+
+OffscreenCanvasPtr Player::createCanvas(const py::dict& params)
+{
+ NodePtr pNode = createNode("canvas", params);
+ return registerOffscreenCanvas(pNode);
+}
+
+void Player::deleteCanvas(const string& sID)
+{
+ vector<OffscreenCanvasPtr>::iterator it;
+ for (it = m_pCanvases.begin(); it != m_pCanvases.end(); ++it) {
+ if ((*it)->getID() == sID) {
+ if ((*it)->getNumDependentCanvases() > 0) {
+ throw (Exception(AVG_ERR_INVALID_ARGS,
+ string("deleteCanvas: Canvas with id ")+sID
+ +" is still referenced."));
+ }
+ (*it)->stopPlayback(false);
+ m_pCanvases.erase(it);
+ return;
+ }
+ }
+ throw(Exception(AVG_ERR_OUT_OF_RANGE,
+ string("deleteCanvas: Canvas with id ")+sID+" does not exist."));
+}
+
+CanvasPtr Player::getMainCanvas() const
+{
+ return m_pMainCanvas;
+}
+
+OffscreenCanvasPtr Player::getCanvas(const string& sID) const
+{
+ OffscreenCanvasPtr pCanvas = findCanvas(sID);
+ if (pCanvas) {
+ return pCanvas;
+ } else {
+ throw (Exception(AVG_ERR_INVALID_ARGS,
+ string("Player::getCanvas(): No canvas with id '")+sID+"' exists."));
+ }
+}
+
+void Player::newCanvasDependency()
+{
+ DAG dag;
+ for (unsigned i = 0; i < m_pCanvases.size(); ++i) {
+ set<long> dependentCanvasSet;
+ OffscreenCanvasPtr pCanvas = m_pCanvases[i];
+ const vector<CanvasPtr>& pDependents = pCanvas->getDependentCanvases();
+ for (unsigned j = 0; j < pDependents.size(); ++j) {
+ dependentCanvasSet.insert(pDependents[j]->getHash());
+ }
+ dag.addNode(pCanvas->getHash(), dependentCanvasSet);
+ }
+ dag.addNode(m_pMainCanvas->getHash(), set<long>());
+
+ vector<long> sortedCanvasIDs;
+ try {
+ dag.sort(sortedCanvasIDs);
+ } catch (Exception&) {
+ throw Exception(AVG_ERR_INVALID_ARGS, "Circular dependency between canvases.");
+ }
+
+ vector<OffscreenCanvasPtr> pTempCanvases = m_pCanvases;
+ m_pCanvases.clear();
+ for (unsigned i = 0; i < sortedCanvasIDs.size(); ++i) {
+ long canvasID = sortedCanvasIDs[i];
+ for (unsigned j = 0; j < pTempCanvases.size(); ++j) {
+ OffscreenCanvasPtr pCandidateCanvas = pTempCanvases[j];
+ if (pCandidateCanvas->getHash() == canvasID) {
+ m_pCanvases.push_back(pCandidateCanvas);
+ break;
+ }
+ }
+ }
+}
+
+NodePtr Player::loadMainNodeFromFile(const string& sFilename)
+{
+ string sRealFilename;
+ AVG_TRACE(Logger::category::MEMORY, Logger::severity::INFO,
+ "Player::loadFile(" << sFilename << ")");
+
+ // When loading an avg file, assets are loaded from a directory relative
+ // to the file.
+ char szBuf[1024];
+ char * pBuf = getcwd(szBuf, 1024);
+ if (sFilename[0] == '/') {
+ sRealFilename = sFilename;
+ } else {
+ m_CurDirName = string(pBuf)+"/";
+ sRealFilename = m_CurDirName+sFilename;
+ }
+ m_CurDirName = sRealFilename.substr(0, sRealFilename.rfind('/')+1);
+
+ string sAVG;
+ readWholeFile(sRealFilename, sAVG);
+ NodePtr pNode = internalLoad(sAVG, sRealFilename);
+
+ // Reset the directory to load assets from to the current dir.
+ m_CurDirName = string(pBuf)+"/";
+ return pNode;
+}
+
+NodePtr Player::loadMainNodeFromString(const string& sAVG)
+{
+ AVG_TRACE(Logger::category::MEMORY, Logger::severity::INFO, "Player::loadString()");
+
+ string sEffectiveDoc = removeStartEndSpaces(sAVG);
+ NodePtr pNode = internalLoad(sEffectiveDoc, "");
+ return pNode;
+}
+
+void Player::play()
+{
+ try {
+ if (!m_pMainCanvas) {
+ throw Exception(AVG_ERR_NO_NODE, "Play called, but no xml file loaded.");
+ }
+ initPlayback();
+ notifySubscribers("PLAYBACK_START");
+ try {
+ ThreadProfiler::get()->start();
+ doFrame(true);
+ while (!m_bStopping) {
+ doFrame(false);
+ }
+ notifySubscribers("PLAYBACK_END");
+ } catch (...) {
+ cleanup(true);
+ m_bDisplayEngineBroken = true;
+ throw;
+ }
+ cleanup(false);
+ AVG_TRACE(Logger::category::PLAYER, Logger::severity::INFO, "Playback ended.");
+ } catch (Exception& ex) {
+ m_bIsPlaying = false;
+ AVG_LOG_ERROR(ex.getStr());
+ throw;
+ }
+}
+
+void Player::stop()
+{
+ if (m_bIsPlaying) {
+ m_bStopping = true;
+ } else {
+ cleanup(false);
+ }
+}
+
+bool Player::isStopping()
+{
+ return m_bStopping;
+}
+
+void Player::initPlayback(const std::string& sShaderPath)
+{
+ m_bIsPlaying = true;
+ AVG_TRACE(Logger::category::PLAYER, Logger::severity::INFO, "Playback started.");
+ initGraphics(sShaderPath);
+ initAudio();
+ try {
+ for (unsigned i = 0; i < m_pCanvases.size(); ++i) {
+ m_pCanvases[i]->initPlayback();
+ }
+ m_pMainCanvas->initPlayback(m_pDisplayEngine);
+ } catch (Exception&) {
+ cleanup(true);
+ m_bDisplayEngineBroken = true;
+ throw;
+ }
+ m_pEventDispatcher->addInputDevice(
+ boost::dynamic_pointer_cast<IInputDevice>(m_pDisplayEngine));
+ m_pEventDispatcher->addInputDevice(m_pTestHelper);
+
+ m_pDisplayEngine->initRender();
+ Display::get()->rereadScreenResolution();
+ m_bStopping = false;
+ if (m_pMultitouchInputDevice) {
+ m_pMultitouchInputDevice->start();
+ }
+
+ m_FrameTime = 0;
+ m_NumFrames = 0;
+}
+
+bool Player::isPlaying()
+{
+ return m_bIsPlaying;
+}
+
+void Player::setFramerate(float rate)
+{
+ if (m_bIsPlaying) {
+ m_pDisplayEngine->setFramerate(rate);
+ }
+ m_DP.m_Framerate = rate;
+ m_DP.m_VBRate = 0;
+}
+
+void Player::setVBlankFramerate(int rate)
+{
+ if (m_bIsPlaying) {
+ m_pDisplayEngine->setVBlankRate(rate);
+ }
+ m_DP.m_Framerate = 0;
+ m_DP.m_VBRate = rate;
+}
+
+float Player::getEffectiveFramerate()
+{
+ if (m_bIsPlaying) {
+ if (m_bFakeFPS) {
+ return m_FakeFPS;
+ } else {
+ return m_pDisplayEngine->getEffectiveFramerate();
+ }
+ } else {
+ return 0;
+ }
+}
+
+TestHelper * Player::getTestHelper()
+{
+ return m_pTestHelper.get();
+}
+
+void Player::setFakeFPS(float fps)
+{
+ if (fabs(fps + 1.0) < 0.0001) {
+ // fps = -1
+ m_bFakeFPS = false;
+ } else {
+ m_bFakeFPS = true;
+ m_FakeFPS = fps;
+ }
+
+ if (AudioEngine::get()) {
+ AudioEngine::get()->setAudioEnabled(!m_bFakeFPS);
+ }
+}
+
+void Player::addInputDevice(IInputDevicePtr pSource)
+{
+ if (!m_pEventDispatcher) {
+ throw Exception(AVG_ERR_UNSUPPORTED,
+ "You must use loadFile() before addInputDevice().");
+ }
+ m_pEventDispatcher->addInputDevice(pSource);
+}
+
+long long Player::getFrameTime()
+{
+ return m_FrameTime;
+}
+
+float Player::getFrameDuration()
+{
+ if (!m_bIsPlaying) {
+ throw Exception(AVG_ERR_UNSUPPORTED,
+ "Must call Player.play() before getFrameDuration().");
+ }
+ if (m_bFakeFPS) {
+ return 1000.0f/m_FakeFPS;
+ } else {
+ float framerate = m_pDisplayEngine->getEffectiveFramerate();
+ if (framerate > 0) {
+ return 1000.f/framerate;
+ } else {
+ return 0;
+ }
+ }
+}
+
+TrackerInputDevice * Player::getTracker()
+{
+ TrackerInputDevice* pTracker = dynamic_cast<TrackerInputDevice*>(
+ m_pMultitouchInputDevice.get());
+ return pTracker;
+}
+
+void Player::enableMultitouch()
+{
+ if (!m_bIsPlaying) {
+ throw Exception(AVG_ERR_UNSUPPORTED,
+ "Must call Player.play() before enableMultitouch().");
+ }
+
+ string sDriver;
+ getEnv("AVG_MULTITOUCH_DRIVER", sDriver);
+ if (sDriver == "") {
+#if defined(_WIN32) && defined(SM_DIGITIZER)
+ sDriver = "WIN7TOUCH";
+#elif defined(HAVE_XI2_1) || defined(HAVE_XI2_2)
+ sDriver = "XINPUT";
+#elif defined (AVG_ENABLE_MTDEV)
+ sDriver = "LINUXMTDEV";
+#else
+ AVG_LOG_WARNING("Valid values for AVG_MULTITOUCH_DRIVER are WIN7TOUCH, XINPUT, LINUXMTDEV, TRACKER, TUIO and APPLETRACKPAD.");
+ throw Exception(AVG_ERR_MT_INIT,
+ "Multitouch support: No default driver available. Set AVG_MULTITOUCH_DRIVER.");
+#endif
+ }
+ if (sDriver == "TUIO") {
+ m_pMultitouchInputDevice = IInputDevicePtr(new TUIOInputDevice);
+#if defined(_WIN32) && defined(SM_DIGITIZER)
+ } else if (sDriver == "WIN7TOUCH") {
+ m_pMultitouchInputDevice = IInputDevicePtr(new Win7TouchInputDevice);
+#endif
+ } else if (sDriver == "XINPUT" || sDriver == "XINPUT21") {
+#if defined(HAVE_XI2_1) || defined(HAVE_XI2_2)
+ m_pMultitouchInputDevice = IInputDevicePtr(new XInputMTInputDevice);
+#else
+ throw Exception(AVG_ERR_MT_INIT,
+ "XInput multitouch event source: Support not configured.'");
+#endif
+#ifdef AVG_ENABLE_MTDEV
+ } else if (sDriver == "LINUXMTDEV") {
+ m_pMultitouchInputDevice = IInputDevicePtr(new LibMTDevInputDevice);
+#endif
+#ifdef __APPLE__
+ } else if (sDriver == "APPLETRACKPAD") {
+ m_pMultitouchInputDevice = IInputDevicePtr(new AppleTrackpadInputDevice);
+#endif
+ } else if (sDriver == "TRACKER") {
+ m_pMultitouchInputDevice = IInputDevicePtr(new TrackerInputDevice);
+ } else {
+ AVG_LOG_WARNING("Valid values for AVG_MULTITOUCH_DRIVER are WIN7TOUCH, XINPUT, LINUXMTDEV, TRACKER, TUIO and APPLETRACKPAD.");
+ throw Exception(AVG_ERR_UNSUPPORTED, string("Unsupported multitouch driver '")+
+ sDriver +"'.");
+ }
+ if (m_bIsPlaying) {
+ try {
+ m_pMultitouchInputDevice->start();
+ } catch (Exception&) {
+ m_pMultitouchInputDevice = IInputDevicePtr();
+ throw;
+ }
+ }
+ addInputDevice(m_pMultitouchInputDevice);
+}
+
+void Player::enableMouse(bool enabled)
+{
+ m_bMouseEnabled = enabled;
+
+ if (m_pEventDispatcher) {
+ m_pEventDispatcher->enableMouse(enabled);
+ }
+}
+
+bool Player::isMultitouchAvailable() const
+{
+ if (m_bIsPlaying) {
+ return m_pMultitouchInputDevice != 0;
+ } else {
+ throw Exception(AVG_ERR_UNSUPPORTED,
+ "Must call Player.play() before isMultitouchAvailable().");
+ }
+}
+
+void Player::setEventCapture(NodePtr pNode, int cursorID=MOUSECURSORID)
+{
+ std::map<int, EventCaptureInfoPtr>::iterator it =
+ m_EventCaptureInfoMap.find(cursorID);
+ if (it != m_EventCaptureInfoMap.end()) {
+ EventCaptureInfoPtr pCaptureInfo = it->second;
+ NodePtr pOldNode = pCaptureInfo->m_pNode;
+ if (pOldNode->getState() != Node::NS_UNCONNECTED) {
+ if (pOldNode == pNode) {
+ pCaptureInfo->m_CaptureCount++;
+ } else {
+ throw Exception(AVG_ERR_INVALID_CAPTURE, "setEventCapture called for '"
+ + pNode->getID() + "', but cursor already captured by '"
+ + pOldNode->getID() + "'.");
+ }
+ }
+ } else {
+ m_EventCaptureInfoMap[cursorID] = EventCaptureInfoPtr(
+ new EventCaptureInfo(pNode));
+ }
+}
+
+void Player::releaseEventCapture(int cursorID)
+{
+ std::map<int, EventCaptureInfoPtr>::iterator it =
+ m_EventCaptureInfoMap.find(cursorID);
+ if (it == m_EventCaptureInfoMap.end() ||
+ (it->second->m_pNode->getState() == Node::NS_UNCONNECTED))
+ {
+ throw Exception(AVG_ERR_INVALID_CAPTURE,
+ "releaseEventCapture called, but cursor not captured.");
+ } else {
+ it->second->m_CaptureCount--;
+ if (it->second->m_CaptureCount == 0) {
+ m_EventCaptureInfoMap.erase(cursorID);
+ }
+ }
+}
+
+bool Player::isCaptured(int cursorID)
+{
+ std::map<int, EventCaptureInfoPtr>::iterator it =
+ m_EventCaptureInfoMap.find(cursorID);
+ return (it != m_EventCaptureInfoMap.end());
+}
+
+void Player::removeDeadEventCaptures()
+{
+ std::map<int, EventCaptureInfoPtr>::iterator it;
+ for (it = m_EventCaptureInfoMap.begin(); it != m_EventCaptureInfoMap.end();) {
+ std::map<int, EventCaptureInfoPtr>::iterator lastIt = it;
+ it++;
+ if (lastIt->second->m_pNode->getState() == Node::NS_UNCONNECTED) {
+ m_EventCaptureInfoMap.erase(lastIt);
+ }
+ }
+}
+
+int Player::setInterval(int time, PyObject * pyfunc)
+{
+ return internalSetTimeout(time, pyfunc, true);
+}
+
+int Player::setTimeout(int time, PyObject * pyfunc)
+{
+ return internalSetTimeout(time, pyfunc, false);
+}
+
+int Player::setOnFrameHandler(PyObject * pyfunc)
+{
+ avgDeprecationWarning("1.8", "Player.setOnFrameHandler",
+ "Player.subscribe(Player.ON_FRAME)");
+ return internalSetTimeout(0, pyfunc, true);
+}
+
+bool Player::clearInterval(int id)
+{
+ vector<Timeout*>::iterator it;
+ for (it = m_PendingTimeouts.begin(); it != m_PendingTimeouts.end(); it++) {
+ if (id == (*it)->getID()) {
+ if (it == m_PendingTimeouts.begin() && m_bInHandleTimers) {
+ m_bCurrentTimeoutDeleted = true;
+ }
+ delete *it;
+ m_PendingTimeouts.erase(it);
+ return true;
+ }
+ }
+ for (it = m_NewTimeouts.begin(); it != m_NewTimeouts.end(); it++) {
+ if (id == (*it)->getID()) {
+ delete *it;
+ m_NewTimeouts.erase(it);
+ return true;
+ }
+ }
+ return false;
+}
+
+void Player::callFromThread(PyObject * pyfunc)
+{
+ lock_guard lock(m_AsyncCallMutex);
+ Timeout* pTimeout = new Timeout(0, pyfunc, false, getFrameTime());
+ m_AsyncCalls.push_back(pTimeout);
+}
+
+MouseEventPtr Player::getMouseState() const
+{
+ return m_pLastMouseEvent;
+}
+
+EventPtr Player::getCurrentEvent() const
+{
+ if (!m_pCurrentEvent) {
+ throw Exception(AVG_ERR_UNSUPPORTED, "No current event.");
+ }
+ return m_pCurrentEvent;
+}
+
+void Player::setMousePos(const IntPoint& pos)
+{
+ m_pDisplayEngine->setMousePos(pos);
+}
+
+int Player::getKeyModifierState() const
+{
+ return m_pDisplayEngine->getKeyModifierState();
+}
+
+BitmapPtr Player::screenshot()
+{
+ if (!m_bIsPlaying) {
+ throw Exception(AVG_ERR_UNSUPPORTED,
+ "Must call Player.play() before screenshot().");
+ }
+ if (GLContext::getMain()->isGLES()) {
+ // Some GLES implementations invalidate the buffer after eglSwapBuffers.
+ // The only way we can get at the contents at this point is to rerender them.
+ m_pMainCanvas->render(m_pDisplayEngine->getWindowSize(), false);
+ }
+ return m_pDisplayEngine->screenshot();
+}
+
+void Player::showCursor(bool bShow)
+{
+ if (m_pDisplayEngine) {
+ m_pDisplayEngine->showCursor(bShow);
+ }
+ m_DP.m_bShowCursor = bShow;
+}
+
+bool Player::isCursorShown()
+{
+ return m_DP.m_bShowCursor;
+}
+
+void Player::setCursor(const Bitmap* pBmp, IntPoint hotSpot)
+{
+ IntPoint size = pBmp->getSize();
+ if (size.x % 8 != 0 || size.y % 8 != 0 || pBmp->getPixelFormat() != R8G8B8A8) {
+ throw Exception(AVG_ERR_INVALID_ARGS,
+ "setCursor: Bitmap size must be divisible by 8 and in RGBA format.");
+ }
+ int i = -1;
+ unsigned char * pData = new unsigned char[size.x*size.y/8];
+ unsigned char * pMask = new unsigned char[size.x*size.y/8];
+ Pixel32 * pLine = (Pixel32*)(pBmp->getPixels());
+ int stride = pBmp->getStride()/4;
+ for (int y = 0; y < size.y; ++y) {
+ Pixel32 * pPixel = pLine;
+ for (int x = 0; x < size.x; ++x) {
+ if (x % 8 == 0) {
+ i++;
+ pData[i] = 0;
+ pMask[i] = 0;
+ } else {
+ pData[i] <<= 1;
+ pMask[i] <<= 1;
+ }
+ if (pPixel->getA() > 127) {
+ pMask[i] |= 0x01;
+ if (pPixel->getR() < 128) {
+ // Black Pixel
+ pData[i] |= 0x01;
+ }
+ }
+ pPixel++;
+ }
+ pLine += stride;
+ }
+ SDL_Cursor * pCursor = SDL_CreateCursor(pData, pMask, size.x, size.y,
+ hotSpot.x, hotSpot.y);
+ SDL_SetCursor(pCursor);
+ delete[] pData;
+ delete[] pMask;
+}
+
+NodePtr Player::getElementByID(const std::string& sID)
+{
+ if (m_pMainCanvas) {
+ return m_pMainCanvas->getElementByID(sID);
+ } else {
+ return NodePtr();
+ }
+}
+
+AVGNodePtr Player::getRootNode()
+{
+ if (m_pMainCanvas) {
+ return dynamic_pointer_cast<AVGNode>(m_pMainCanvas->getRootNode());
+ } else {
+ return AVGNodePtr();
+ }
+}
+
+string Player::getCurDirName()
+{
+ return m_CurDirName;
+}
+
+std::string Player::getRootMediaDir()
+{
+ string sMediaDir;
+ if (m_pMainCanvas) {
+ sMediaDir = m_pMainCanvas->getRootNode()->getEffectiveMediaDir();
+ } else {
+ sMediaDir = m_CurDirName;
+ }
+ return sMediaDir;
+}
+
+void Player::disablePython()
+{
+ m_bPythonAvailable = false;
+}
+
+void Player::startTraversingTree()
+{
+ AVG_ASSERT(!m_bIsTraversingTree);
+ m_bIsTraversingTree = true;
+}
+
+void Player::endTraversingTree()
+{
+ AVG_ASSERT(m_bIsTraversingTree);
+ m_bIsTraversingTree = false;
+}
+
+bool Player::isTraversingTree() const
+{
+ return m_bIsTraversingTree;
+}
+
+void Player::registerFrameEndListener(IFrameEndListener* pListener)
+{
+ AVG_ASSERT(m_pMainCanvas);
+ m_pMainCanvas->registerFrameEndListener(pListener);
+}
+
+void Player::unregisterFrameEndListener(IFrameEndListener* pListener)
+{
+ if (m_pMainCanvas) {
+ m_pMainCanvas->unregisterFrameEndListener(pListener);
+ }
+}
+
+void Player::registerPlaybackEndListener(IPlaybackEndListener* pListener)
+{
+ AVG_ASSERT(m_pMainCanvas);
+ m_pMainCanvas->registerPlaybackEndListener(pListener);
+}
+
+void Player::unregisterPlaybackEndListener(IPlaybackEndListener* pListener)
+{
+ if (m_pMainCanvas) {
+ m_pMainCanvas->unregisterPlaybackEndListener(pListener);
+ }
+}
+
+void Player::registerPreRenderListener(IPreRenderListener* pListener)
+{
+ AVG_ASSERT(m_pMainCanvas);
+ m_pMainCanvas->registerPreRenderListener(pListener);
+}
+
+void Player::unregisterPreRenderListener(IPreRenderListener* pListener)
+{
+ if (m_pMainCanvas) {
+ m_pMainCanvas->unregisterPreRenderListener(pListener);
+ }
+}
+
+bool Player::handleEvent(EventPtr pEvent)
+{
+ AVG_ASSERT(pEvent);
+ EventPtr pLastEvent = m_pCurrentEvent;
+ m_pCurrentEvent = pEvent;
+ if (MouseEventPtr pMouseEvent = boost::dynamic_pointer_cast<MouseEvent>(pEvent)) {
+ m_pLastMouseEvent = pMouseEvent;
+ }
+
+ if (CursorEventPtr pCursorEvent = boost::dynamic_pointer_cast<CursorEvent>(pEvent)) {
+ if (pEvent->getType() == Event::CURSOR_OUT ||
+ pEvent->getType() == Event::CURSOR_OVER)
+ {
+ pEvent->trace();
+ pCursorEvent->getNode()->handleEvent(pEvent);
+ } else {
+ handleCursorEvent(pCursorEvent);
+ }
+ }
+ else if (KeyEventPtr pKeyEvent = boost::dynamic_pointer_cast<KeyEvent>(pEvent))
+ {
+ pEvent->trace();
+ switch (pEvent->getType()) {
+ case Event::KEY_DOWN:
+ notifySubscribers("KEY_DOWN", pEvent);
+ break;
+ case Event::KEY_UP:
+ notifySubscribers("KEY_UP", pEvent);
+ break;
+ default:
+ AVG_ASSERT(false);
+ }
+ getRootNode()->handleEvent(pKeyEvent);
+ if (getStopOnEscape() && pEvent->getType() == Event::KEY_DOWN
+ && pKeyEvent->getKeyCode() == avg::key::KEY_ESCAPE)
+ {
+ stop();
+ }
+ }
+ else {
+ if (pEvent->getType() != Event::QUIT) {
+ pEvent->trace();
+ getRootNode()->handleEvent(pEvent);
+ }
+ else {
+ stop();
+ }
+ }
+ m_pCurrentEvent = pLastEvent;
+ return true;
+}
+
+static ProfilingZoneID MainProfilingZone("Player - Total frame time");
+static ProfilingZoneID TimersProfilingZone("Player - handleTimers");
+static ProfilingZoneID EventsProfilingZone("Dispatch events");
+static ProfilingZoneID MainCanvasProfilingZone("Main canvas rendering");
+static ProfilingZoneID OffscreenProfilingZone("Offscreen rendering");
+
+void Player::doFrame(bool bFirstFrame)
+{
+ {
+ ScopeTimer Timer(MainProfilingZone);
+ if (!bFirstFrame) {
+ m_NumFrames++;
+ if (m_bFakeFPS) {
+ m_FrameTime = (long long)((m_NumFrames*1000.0)/m_FakeFPS);
+ } else {
+ m_FrameTime = m_pDisplayEngine->getDisplayTime();
+ }
+ {
+ ScopeTimer Timer(TimersProfilingZone);
+ handleTimers();
+ }
+ {
+ ScopeTimer Timer(EventsProfilingZone);
+ m_pEventDispatcher->dispatch();
+ sendFakeEvents();
+ removeDeadEventCaptures();
+ }
+ }
+ for (unsigned i = 0; i < m_pCanvases.size(); ++i) {
+ ScopeTimer Timer(OffscreenProfilingZone);
+ dispatchOffscreenRendering(m_pCanvases[i].get());
+ }
+ {
+ ScopeTimer Timer(MainCanvasProfilingZone);
+ m_pMainCanvas->doFrame(m_bPythonAvailable);
+ }
+ GLContext::mandatoryCheckError("End of frame");
+ if (m_bPythonAvailable) {
+ Py_BEGIN_ALLOW_THREADS;
+ try {
+ endFrame();
+ } catch(...) {
+ Py_BLOCK_THREADS;
+ throw;
+ }
+ Py_END_ALLOW_THREADS;
+ } else {
+ endFrame();
+ }
+ }
+ ThreadProfiler::get()->reset();
+ if (m_NumFrames == 5) {
+ ThreadProfiler::get()->restart();
+ }
+}
+
+void Player::endFrame()
+{
+ m_pDisplayEngine->frameWait();
+ m_pDisplayEngine->swapBuffers();
+ m_pDisplayEngine->checkJitter();
+}
+
+float Player::getFramerate()
+{
+ if (!m_pDisplayEngine) {
+ return m_DP.m_Framerate;
+ }
+ return m_pDisplayEngine->getFramerate();
+}
+
+float Player::getVideoRefreshRate()
+{
+ return Display::get()->getRefreshRate();
+}
+
+size_t Player::getVideoMemInstalled()
+{
+ if (!m_pDisplayEngine) {
+ throw Exception(AVG_ERR_UNSUPPORTED,
+ "Player.getVideoMemInstalled must be called after Player.play().");
+ }
+ return GLContext::getMain()->getVideoMemInstalled();
+}
+
+size_t Player::getVideoMemUsed()
+{
+ if (!m_pDisplayEngine) {
+ throw Exception(AVG_ERR_UNSUPPORTED,
+ "Player.getVideoMemUsed must be called after Player.play().");
+ }
+ return GLContext::getMain()->getVideoMemUsed();
+}
+
+void Player::setGamma(float red, float green, float blue)
+{
+ if (m_pDisplayEngine) {
+ m_pDisplayEngine->setGamma(red, green, blue);
+ }
+ m_DP.m_Gamma[0] = red;
+ m_DP.m_Gamma[1] = green;
+ m_DP.m_Gamma[2] = blue;
+}
+
+void Player::initConfig()
+{
+ // Get data from config files.
+ ConfigMgr* pMgr = ConfigMgr::get();
+
+ m_DP.m_BPP = atoi(pMgr->getOption("scr", "bpp")->c_str());
+ if (m_DP.m_BPP != 15 && m_DP.m_BPP != 16 && m_DP.m_BPP != 24 && m_DP.m_BPP != 32) {
+ AVG_LOG_ERROR("BPP must be 15, 16, 24 or 32. Current value is "
+ << m_DP.m_BPP << ". Aborting." );
+ exit(-1);
+ }
+ m_DP.m_bFullscreen = pMgr->getBoolOption("scr", "fullscreen", false);
+
+ m_DP.m_WindowSize.x = atoi(pMgr->getOption("scr", "windowwidth")->c_str());
+ m_DP.m_WindowSize.y = atoi(pMgr->getOption("scr", "windowheight")->c_str());
+
+ if (m_DP.m_bFullscreen && (m_DP.m_WindowSize != IntPoint(0, 0))) {
+ AVG_LOG_ERROR("Can't set fullscreen and window size at once. Aborting.");
+ exit(-1);
+ }
+ if (m_DP.m_WindowSize.x != 0 && m_DP.m_WindowSize.y != 0) {
+ AVG_LOG_ERROR("Can't set window width and height at once");
+ AVG_LOG_ERROR("(aspect ratio is determined by avg file). Aborting.");
+ exit(-1);
+ }
+
+ m_AP.m_Channels = atoi(pMgr->getOption("aud", "channels")->c_str());
+ m_AP.m_SampleRate = atoi(pMgr->getOption("aud", "samplerate")->c_str());
+ m_AP.m_OutputBufferSamples =
+ atoi(pMgr->getOption("aud", "outputbuffersamples")->c_str());
+
+ m_GLConfig.m_bGLES = pMgr->getBoolOption("scr", "gles", false);
+ m_GLConfig.m_bUsePOTTextures = pMgr->getBoolOption("scr", "usepow2textures", false);
+
+ m_GLConfig.m_bUsePixelBuffers = pMgr->getBoolOption("scr", "usepixelbuffers", true);
+ int multiSampleSamples = pMgr->getIntOption("scr", "multisamplesamples", 8);
+ if (multiSampleSamples < 1) {
+ AVG_LOG_ERROR("multisamplesamples must be >= 1. Aborting")
+ exit(-1);
+ }
+ m_GLConfig.m_MultiSampleSamples = multiSampleSamples;
+
+ string sShaderUsage;
+ pMgr->getStringOption("scr", "shaderusage", "auto", sShaderUsage);
+ if (sShaderUsage == "full") {
+ m_GLConfig.m_ShaderUsage = GLConfig::FULL;
+ } else if (sShaderUsage == "minimal") {
+ m_GLConfig.m_ShaderUsage = GLConfig::MINIMAL;
+ } else if (sShaderUsage == "auto") {
+ m_GLConfig.m_ShaderUsage = GLConfig::AUTO;
+ } else {
+ throw Exception(AVG_ERR_OUT_OF_RANGE,
+ "avgrc parameter shaderusage must be full, minimal, fragmentonly or auto");
+ }
+ string sDummy;
+ m_GLConfig.m_bUseDebugContext = getEnv("AVG_USE_DEBUG_GL_CONTEXT", sDummy);
+#ifdef AVG_ENABLE_EGL
+ m_GLConfig.m_bGLES = true;
+#endif
+ BitmapLoader::init(!m_GLConfig.m_bGLES);
+
+ pMgr->getGammaOption("scr", "gamma", m_DP.m_Gamma);
+}
+
+void Player::initGraphics(const string& sShaderPath)
+{
+ if (!Display::isInitialized()) {
+ ConfigMgr* pMgr = ConfigMgr::get();
+ float dotsPerMM = float(atof(pMgr->getOption("scr", "dotspermm")->c_str()));
+ Display::get()->assumePixelsPerMM(dotsPerMM);
+ }
+ // Init display configuration.
+ AVG_TRACE(Logger::category::CONFIG, Logger::severity::INFO,
+ "Display bpp: " << m_DP.m_BPP);
+
+ if (m_bDisplayEngineBroken) {
+ m_bDisplayEngineBroken = false;
+ m_pDisplayEngine->teardown();
+ m_pDisplayEngine = SDLDisplayEnginePtr();
+ }
+
+ if (!m_pDisplayEngine) {
+ m_pDisplayEngine = SDLDisplayEnginePtr(new SDLDisplayEngine());
+ }
+ AVG_TRACE(Logger::category::CONFIG, Logger::severity::INFO,
+ "Requested OpenGL configuration: ");
+ m_GLConfig.log();
+ m_DP.m_WindowSize = m_pDisplayEngine->calcWindowSize(m_DP);
+ if (m_pDisplayEngine->getWindowSize() != m_DP.m_WindowSize ||
+ m_pDisplayEngine->isFullscreen() == true)
+ {
+ m_pDisplayEngine->teardown();
+ m_pDisplayEngine->init(m_DP, m_GLConfig);
+ }
+ AVG_TRACE(Logger::category::CONFIG, Logger::severity::INFO,
+ "Pixels per mm: " << Display::get()->getPixelsPerMM());
+ if (sShaderPath != "") {
+ ShaderRegistry::get()->setShaderPath(sShaderPath);
+ }
+ m_pDisplayEngine->setGamma(1.0, 1.0, 1.0);
+ m_GLConfig = GLContext::getCurrent()->getConfig();
+}
+
+void Player::initAudio()
+{
+ AudioEngine* pAudioEngine = AudioEngine::get();
+ if (!pAudioEngine) {
+ pAudioEngine = new AudioEngine();
+ }
+ pAudioEngine->init(m_AP, m_Volume);
+ pAudioEngine->setAudioEnabled(!m_bFakeFPS);
+ pAudioEngine->play();
+}
+
+void Player::initMainCanvas(NodePtr pRootNode)
+{
+ m_pEventDispatcher = EventDispatcherPtr(new EventDispatcher(this, m_bMouseEnabled));
+ m_pMainCanvas = MainCanvasPtr(new MainCanvas(this));
+ m_pMainCanvas->setRoot(pRootNode);
+ m_DP.m_Size = m_pMainCanvas->getSize();
+
+ registerFrameEndListener(BitmapManager::get());
+}
+
+NodePtr Player::internalLoad(const string& sAVG, const string& sFilename)
+{
+ XMLParser parser;
+ parser.setDTD(TypeRegistry::get()->getDTD(), "avg.dtd");
+ parser.parse(sAVG, sFilename);
+ xmlNodePtr xmlNode = parser.getRootNode();
+ NodePtr pNode = createNodeFromXml(parser.getDoc(), xmlNode);
+ if (!pNode) {
+ throw (Exception(AVG_ERR_XML_PARSE,
+ "Root node of an avg tree needs to be an <avg> node."));
+ }
+ return pNode;
+}
+
+SDLDisplayEnginePtr Player::safeGetDisplayEngine()
+{
+ if (!m_pDisplayEngine) {
+ m_pDisplayEngine = SDLDisplayEnginePtr(new SDLDisplayEngine());
+ }
+ return m_pDisplayEngine;
+
+}
+
+NodePtr Player::createNode(const string& sType,
+ const py::dict& params, const boost::python::object& self)
+{
+ DivNodePtr pParentNode;
+ py::dict attrs = params;
+ py::object parent;
+ if (params.has_key("parent")) {
+ parent = params["parent"];
+ attrs.attr("__delitem__")("parent");
+ pParentNode = py::extract<DivNodePtr>(parent);
+ }
+ NodePtr pNode = dynamic_pointer_cast<Node>(
+ TypeRegistry::get()->createObject(sType, attrs));
+
+ // See if the class names of self and pNode match. If they don't, there is a
+ // python derived class that's being constructed and we can't set parent here.
+ string sSelfClassName = py::extract<string>(
+ self.attr("__class__").attr("__name__"));
+ py::object pythonClassName =
+ (py::object(pNode).attr("__class__").attr("__name__"));
+ string sThisClassName = py::extract<string>(pythonClassName);
+ bool bHasDerivedClass = sSelfClassName != sThisClassName &&
+ sSelfClassName != "NoneType";
+ if (bHasDerivedClass) {
+ if (pParentNode) {
+ throw Exception(AVG_ERR_UNSUPPORTED,
+ "Can't pass 'parent' parameter to C++ class constructor if there is a derived python class. Use Node.registerInstance() instead.");
+ }
+ pNode->registerInstance(self.ptr(), pParentNode);
+ } else {
+ pNode->registerInstance(0, pParentNode);
+ }
+ if (parent) {
+ attrs["parent"] = parent;
+ }
+ return pNode;
+}
+
+NodePtr Player::createNodeFromXmlString(const string& sXML)
+{
+ xmlPedanticParserDefault(1);
+ xmlDoValidityCheckingDefaultValue =0;
+
+ XMLParser parser;
+ parser.setDTD(TypeRegistry::get()->getDTD(), "avg.dtd");
+ parser.parse(sXML, "");
+
+// cvp->error = xmlParserValidityError;
+// cvp->warning = xmlParserValidityWarning;
+ xmlNodePtr xmlNode = parser.getRootNode();
+ NodePtr pNode = createNodeFromXml(parser.getDoc(), xmlNode);
+
+ return pNode;
+}
+
+NodePtr Player::createNodeFromXml(const xmlDocPtr xmlDoc,
+ const xmlNodePtr xmlNode)
+{
+ const char * nodeType = (const char *)xmlNode->name;
+
+ if (!strcmp (nodeType, "text") || !strcmp (nodeType, "comment")) {
+ // Ignore whitespace & comments
+ return NodePtr();
+ }
+ NodePtr pCurNode = dynamic_pointer_cast<Node>(
+ TypeRegistry::get()->createObject(nodeType, xmlNode));
+ if (!strcmp(nodeType, "words")) {
+ // TODO: This is an end-run around the generic serialization mechanism
+ // that will probably break at some point.
+ string s = getXmlChildrenAsString(xmlDoc, xmlNode);
+ boost::dynamic_pointer_cast<WordsNode>(pCurNode)->setTextFromNodeValue(s);
+ } else {
+ // If this is a container, recurse into children
+ if (pCurNode->getDefinition()->hasChildren()) {
+ xmlNodePtr curXmlChild = xmlNode->xmlChildrenNode;
+ while (curXmlChild) {
+ NodePtr curChild = createNodeFromXml(xmlDoc, curXmlChild);
+ if (curChild) {
+ DivNodePtr pDivNode = boost::dynamic_pointer_cast<DivNode>(pCurNode);
+ pDivNode->appendChild(curChild);
+ }
+ curXmlChild = curXmlChild->next;
+ }
+ }
+ }
+ return pCurNode;
+}
+
+OffscreenCanvasPtr Player::registerOffscreenCanvas(NodePtr pNode)
+{
+ OffscreenCanvasPtr pCanvas(new OffscreenCanvas(this));
+ pCanvas->setRoot(pNode);
+ if (findCanvas(pCanvas->getID())) {
+ throw (Exception(AVG_ERR_INVALID_ARGS,
+ string("Duplicate canvas id ")+pCanvas->getID()));
+ }
+ m_pCanvases.push_back(pCanvas);
+ if (m_bIsPlaying) {
+ try {
+ pCanvas->initPlayback();
+ } catch (...) {
+ m_pCanvases.pop_back();
+ throw;
+ }
+ }
+ return pCanvas;
+}
+
+OffscreenCanvasPtr Player::findCanvas(const string& sID) const
+{
+ for (unsigned i=0; i<m_pCanvases.size(); ++i) {
+ if (m_pCanvases[i]->getID() == sID) {
+ return m_pCanvases[i];
+ }
+ }
+ return OffscreenCanvasPtr();
+}
+
+void Player::sendFakeEvents()
+{
+ std::map<int, CursorStatePtr>::iterator it;
+ for (it = m_pLastCursorStates.begin(); it != m_pLastCursorStates.end(); ++it) {
+ CursorStatePtr pState = it->second;
+ handleCursorEvent(pState->getLastEvent(), true);
+ }
+}
+
+void Player::sendOver(const CursorEventPtr pOtherEvent, Event::Type type,
+ NodePtr pNode)
+{
+ if (pNode) {
+ CursorEventPtr pNewEvent = pOtherEvent->cloneAs(type);
+ pNewEvent->setNode(pNode);
+ m_pEventDispatcher->sendEvent(pNewEvent);
+ }
+}
+
+void Player::handleCursorEvent(CursorEventPtr pEvent, bool bOnlyCheckCursorOver)
+{
+ // Find all nodes under the cursor.
+ vector<NodePtr> pCursorNodes;
+ DivNodePtr pEventReceiverNode = pEvent->getInputDevice()->getEventReceiverNode();
+ if (!pEventReceiverNode) {
+ pEventReceiverNode = getRootNode();
+ }
+ pEventReceiverNode->getElementsByPos(pEvent->getPos(), pCursorNodes);
+ ContactPtr pContact = pEvent->getContact();
+ if (pContact && !bOnlyCheckCursorOver) {
+ if (!pCursorNodes.empty()) {
+ NodePtr pNode = *(pCursorNodes.begin());
+ pEvent->setNode(pNode);
+ }
+ pContact->sendEventToListeners(pEvent);
+ }
+
+ int cursorID = pEvent->getCursorID();
+
+ // Determine the nodes the event should be sent to.
+ vector<NodePtr> pDestNodes = pCursorNodes;
+ if (m_EventCaptureInfoMap.find(cursorID) != m_EventCaptureInfoMap.end()) {
+ NodeWeakPtr pEventCaptureNode =
+ m_EventCaptureInfoMap[cursorID]->m_pNode;
+ if (pEventCaptureNode.expired()) {
+ m_EventCaptureInfoMap.erase(cursorID);
+ } else {
+ pDestNodes = pEventCaptureNode.lock()->getParentChain();
+ }
+ }
+
+ vector<NodePtr> pLastCursorNodes;
+ {
+ map<int, CursorStatePtr>::iterator it;
+ it = m_pLastCursorStates.find(cursorID);
+ if (it != m_pLastCursorStates.end()) {
+ pLastCursorNodes = it->second->getNodes();
+ }
+ }
+
+ // Send out events.
+ vector<NodePtr>::const_iterator itLast;
+ vector<NodePtr>::iterator itCur;
+ for (itLast = pLastCursorNodes.begin(); itLast != pLastCursorNodes.end();
+ ++itLast)
+ {
+ NodePtr pLastNode = *itLast;
+ for (itCur = pCursorNodes.begin(); itCur != pCursorNodes.end(); ++itCur) {
+ if (*itCur == pLastNode) {
+ break;
+ }
+ }
+ if (itCur == pCursorNodes.end()) {
+ sendOver(pEvent, Event::CURSOR_OUT, pLastNode);
+ }
+ }
+
+ // Send over events.
+ for (itCur = pCursorNodes.begin(); itCur != pCursorNodes.end(); ++itCur) {
+ NodePtr pCurNode = *itCur;
+ for (itLast = pLastCursorNodes.begin(); itLast != pLastCursorNodes.end();
+ ++itLast)
+ {
+ if (*itLast == pCurNode) {
+ break;
+ }
+ }
+ if (itLast == pLastCursorNodes.end()) {
+ sendOver(pEvent, Event::CURSOR_OVER, pCurNode);
+ }
+ }
+
+ if (!bOnlyCheckCursorOver) {
+ // Iterate through the nodes and send the event to all of them.
+ vector<NodePtr>::iterator it;
+ for (it = pDestNodes.begin(); it != pDestNodes.end(); ++it) {
+ NodePtr pNode = *it;
+ if (pNode->getState() != Node::NS_UNCONNECTED) {
+ pEvent->setNode(pNode);
+ if (pEvent->getType() != Event::CURSOR_MOTION) {
+ pEvent->trace();
+ }
+ if (pNode->handleEvent(pEvent) == true) {
+ // stop bubbling
+ break;
+ }
+ }
+ }
+ }
+
+ if (pEvent->getType() == Event::CURSOR_UP && pEvent->getSource() != Event::MOUSE) {
+ // Cursor has disappeared: send out events.
+ vector<NodePtr>::iterator it;
+ for (it = pCursorNodes.begin(); it != pCursorNodes.end(); ++it) {
+ NodePtr pNode = *it;
+ sendOver(pEvent, Event::CURSOR_OUT, pNode);
+ }
+ m_pLastCursorStates.erase(cursorID);
+ } else {
+ // Update list of nodes under cursor
+ if (m_pLastCursorStates.find(cursorID) != m_pLastCursorStates.end()) {
+ m_pLastCursorStates[cursorID]->setInfo(pEvent, pCursorNodes);
+ } else {
+ m_pLastCursorStates[cursorID] =
+ CursorStatePtr(new CursorState(pEvent, pCursorNodes));
+ }
+ }
+}
+
+void Player::dispatchOffscreenRendering(OffscreenCanvas* pOffscreenCanvas)
+{
+ if (!pOffscreenCanvas->getAutoRender()) {
+ return;
+ }
+ if (pOffscreenCanvas->hasRegisteredCamera()) {
+ pOffscreenCanvas->updateCameraImage();
+ while (pOffscreenCanvas->isCameraImageAvailable()) {
+ pOffscreenCanvas->doFrame(m_bPythonAvailable);
+ pOffscreenCanvas->updateCameraImage();
+ }
+ } else {
+ pOffscreenCanvas->doFrame(m_bPythonAvailable);
+ return;
+ }
+}
+
+void Player::errorIfPlaying(const std::string& sFunc) const
+{
+ if (m_bIsPlaying) {
+ throw Exception(AVG_ERR_UNSUPPORTED,
+ sFunc + " must be called before Player.play().");
+ }
+}
+
+void Player::handleTimers()
+{
+ vector<Timeout *>::iterator it;
+ m_bInHandleTimers = true;
+
+ it = m_PendingTimeouts.begin();
+ while (it != m_PendingTimeouts.end() && (*it)->isReady(getFrameTime())
+ && !m_bStopping)
+ {
+ (*it)->fire(getFrameTime());
+ if (m_bCurrentTimeoutDeleted) {
+ it = m_PendingTimeouts.begin();
+ } else {
+ if ((*it)->isInterval()) {
+ Timeout* pTempTimeout = *it;
+ it = m_PendingTimeouts.erase(it);
+ m_NewTimeouts.insert(m_NewTimeouts.begin(), pTempTimeout);
+ } else {
+ delete *it;
+ it = m_PendingTimeouts.erase(it);
+ }
+ }
+ m_bCurrentTimeoutDeleted = false;
+ }
+ for (it = m_NewTimeouts.begin(); it != m_NewTimeouts.end(); ++it) {
+ addTimeout(*it);
+ }
+ m_NewTimeouts.clear();
+
+ notifySubscribers("ON_FRAME");
+
+ m_bInHandleTimers = false;
+
+ if (m_bPythonAvailable) {
+ std::vector<Timeout *> tempAsyncCalls;
+ Py_BEGIN_ALLOW_THREADS;
+ {
+ lock_guard lock(m_AsyncCallMutex);
+ tempAsyncCalls = m_AsyncCalls;
+ m_AsyncCalls.clear();
+ }
+ Py_END_ALLOW_THREADS;
+ for (it = tempAsyncCalls.begin(); it != tempAsyncCalls.end(); ++it) {
+ (*it)->fire(getFrameTime());
+ delete *it;
+ }
+ }
+}
+
+SDLDisplayEngine * Player::getDisplayEngine() const
+{
+ return m_pDisplayEngine.get();
+}
+
+void Player::keepWindowOpen()
+{
+ m_bKeepWindowOpen = true;
+}
+
+void Player::setStopOnEscape(bool bStop)
+{
+ m_bStopOnEscape = bStop;
+}
+
+bool Player::getStopOnEscape() const
+{
+ return m_bStopOnEscape;
+}
+
+void Player::setVolume(float volume)
+{
+ m_Volume = volume;
+ if (AudioEngine::get()) {
+ AudioEngine::get()->setVolume(m_Volume);
+ }
+}
+
+float Player::getVolume() const
+{
+ return m_Volume;
+}
+
+string Player::getConfigOption(const string& sSubsys, const string& sName) const
+{
+ const string* psValue = ConfigMgr::get()->getOption(sSubsys, sName);
+ if (!psValue) {
+ throw Exception(AVG_ERR_INVALID_ARGS, string("Unknown config option ") + sSubsys
+ + ":" + sName);
+ } else {
+ return *psValue;
+ }
+}
+
+bool Player::isUsingGLES() const
+{
+ return m_GLConfig.m_bGLES;
+}
+
+bool Player::areFullShadersSupported() const
+{
+ if (!m_bIsPlaying) {
+ throw Exception(AVG_ERR_UNSUPPORTED,
+ "Must call Player.play() before areFullShadersSupported().");
+ }
+ return (m_GLConfig.m_ShaderUsage == GLConfig::FULL);
+}
+
+OffscreenCanvasPtr Player::getCanvasFromURL(const std::string& sURL)
+{
+ if (sURL.substr(0, 7) != "canvas:") {
+ throw Exception(AVG_ERR_CANT_PARSE_STRING,
+ string("Invalid canvas url :'")+sURL+"'");
+ }
+ string sCanvasID = sURL.substr(7);
+ for (unsigned i=0; i < m_pCanvases.size(); ++i) {
+ if (m_pCanvases[i]->getID() == sCanvasID) {
+ return m_pCanvases[i];
+ }
+ }
+ throw Exception(AVG_ERR_CANT_PARSE_STRING,
+ string("Canvas with url '")+sURL+"' not found.");
+}
+
+void Player::cleanup(bool bIsAbort)
+{
+ // Kill all timeouts.
+ vector<Timeout*>::iterator it;
+ for (it = m_PendingTimeouts.begin(); it != m_PendingTimeouts.end(); it++) {
+ delete *it;
+ }
+ m_PendingTimeouts.clear();
+ m_EventCaptureInfoMap.clear();
+ m_pLastCursorStates.clear();
+ m_pTestHelper->reset();
+ ThreadProfiler::get()->dumpStatistics();
+ if (m_pMainCanvas) {
+ unregisterFrameEndListener(BitmapManager::get());
+ delete BitmapManager::get();
+ m_pMainCanvas->stopPlayback(bIsAbort);
+ m_pMainCanvas = MainCanvasPtr();
+ }
+
+ if (m_pMultitouchInputDevice) {
+ m_pMultitouchInputDevice = IInputDevicePtr();
+ }
+ for (unsigned i = 0; i < m_pCanvases.size(); ++i) {
+ m_pCanvases[i]->stopPlayback(bIsAbort);
+ }
+ m_pCanvases.clear();
+
+ if (m_pDisplayEngine) {
+ m_DP.m_WindowSize = IntPoint(0,0);
+ if (!m_bKeepWindowOpen) {
+ m_pDisplayEngine->deinitRender();
+ m_pDisplayEngine->teardown();
+ m_pDisplayEngine = SDLDisplayEnginePtr();
+ }
+ }
+ if (AudioEngine::get()) {
+ AudioEngine::get()->teardown();
+ }
+ m_pEventDispatcher = EventDispatcherPtr();
+ m_pLastMouseEvent = MouseEventPtr(new MouseEvent(Event::CURSOR_MOTION, false, false,
+ false, IntPoint(-1, -1), MouseEvent::NO_BUTTON, glm::vec2(-1, -1), 0));
+
+ m_FrameTime = 0;
+ m_bIsPlaying = false;
+
+ m_CurDirName = getCWD();
+
+ removeSubscribers();
+}
+
+int Player::internalSetTimeout(int time, PyObject * pyfunc, bool bIsInterval)
+{
+ Timeout* pTimeout = new Timeout(time, pyfunc, bIsInterval, getFrameTime());
+ if (m_bInHandleTimers) {
+ m_NewTimeouts.push_back(pTimeout);
+ } else {
+ addTimeout(pTimeout);
+ }
+ return pTimeout->getID();
+}
+
+
+int Player::addTimeout(Timeout* pTimeout)
+{
+ vector<Timeout*>::iterator it = m_PendingTimeouts.begin();
+ while (it != m_PendingTimeouts.end() && (**it)<*pTimeout) {
+ it++;
+ }
+ m_PendingTimeouts.insert(it, pTimeout);
+ return pTimeout->getID();
+}
+
+void Player::setPluginPath(const string& newPath)
+{
+ PluginManager::get().setSearchPath(newPath);
+}
+
+string Player::getPluginPath() const
+{
+ return PluginManager::get().getSearchPath();
+}
+
+py::object Player::loadPlugin(const std::string& name)
+{
+ return PluginManager::get().loadPlugin(name);
+}
+
+void Player::setEventHook(PyObject * pyfunc)
+{
+ if (m_EventHookPyFunc != Py_None) {
+ Py_DECREF(m_EventHookPyFunc);
+ }
+
+ if (pyfunc != Py_None) {
+ Py_INCREF(pyfunc);
+ }
+
+ m_EventHookPyFunc = pyfunc;
+}
+
+PyObject * Player::getEventHook() const
+{
+ return m_EventHookPyFunc;
+}
+
+Player::EventCaptureInfo::EventCaptureInfo(const NodeWeakPtr& pNode)
+ : m_pNode(pNode),
+ m_CaptureCount(1)
+{
+}
+
+}
diff --git a/src/player/Player.h b/src/player/Player.h
new file mode 100644
index 0000000..32d0da5
--- /dev/null
+++ b/src/player/Player.h
@@ -0,0 +1,299 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _Player_H_
+#define _Player_H_
+
+#include "../api.h"
+#include "Publisher.h"
+#include "Timeout.h"
+#include "TypeRegistry.h"
+#include "DisplayParams.h"
+#include "CursorState.h"
+#include "TestHelper.h"
+#include "BoostPython.h"
+
+#include "../audio/AudioParams.h"
+#include "../graphics/GLConfig.h"
+
+#include <libxml/parser.h>
+#include <boost/shared_ptr.hpp>
+#include <boost/thread/thread.hpp>
+
+#include <string>
+#include <vector>
+#include <set>
+
+namespace avg {
+
+class AudioEngine;
+class Node;
+class Canvas;
+class MainCanvas;
+class OffscreenCanvas;
+class TrackerInputDevice;
+class MultitouchInputDevice;
+class IFrameEndListener;
+class IPlaybackEndListener;
+class IPreRenderListener;
+class Contact;
+class EventDispatcher;
+class MouseEvent;
+class CursorEvent;
+class SDLDisplayEngine;
+class Display;
+
+typedef boost::shared_ptr<Node> NodePtr;
+typedef boost::weak_ptr<Node> NodeWeakPtr;
+typedef boost::shared_ptr<Canvas> CanvasPtr;
+typedef boost::shared_ptr<MainCanvas> MainCanvasPtr;
+typedef boost::shared_ptr<OffscreenCanvas> OffscreenCanvasPtr;
+typedef boost::shared_ptr<class Contact> ContactPtr;
+typedef boost::shared_ptr<EventDispatcher> EventDispatcherPtr;
+typedef boost::shared_ptr<MouseEvent> MouseEventPtr;
+typedef boost::shared_ptr<CursorEvent> CursorEventPtr;
+typedef boost::shared_ptr<SDLDisplayEngine> SDLDisplayEnginePtr;
+typedef boost::shared_ptr<Display> DisplayPtr;
+
+class AVG_API Player: public Publisher
+{
+ public:
+ Player();
+ virtual ~Player();
+ static Player* get();
+ static bool exists();
+
+ void setResolution(bool bFullscreen,
+ int width=0, int height=0, int bpp=0);
+ bool isFullscreen();
+ void setWindowFrame(bool bHasWindowFrame);
+ void setWindowPos(int x=0, int y=0);
+ void setWindowTitle(const std::string& sTitle);
+ void useGLES(bool bGLES);
+ void setOGLOptions(bool bUsePOTTextures, bool bUsePixelBuffers,
+ int multiSampleSamples, GLConfig::ShaderUsage shaderUsage,
+ bool bUseDebugContext);
+ void setMultiSampleSamples(int multiSampleSamples);
+ void setAudioOptions(int samplerate, int channels);
+ void enableGLErrorChecks(bool bEnable);
+ glm::vec2 getScreenResolution();
+ float getPixelsPerMM();
+ glm::vec2 getPhysicalScreenDimensions();
+ void assumePixelsPerMM(float ppmm);
+
+ CanvasPtr loadFile(const std::string& sFilename);
+ CanvasPtr loadString(const std::string& sAVG);
+
+ OffscreenCanvasPtr loadCanvasFile(const std::string& sFilename);
+ OffscreenCanvasPtr loadCanvasString(const std::string& sAVG);
+ CanvasPtr createMainCanvas(const py::dict& params);
+ OffscreenCanvasPtr createCanvas(const py::dict& params);
+ void deleteCanvas(const std::string& sID);
+ CanvasPtr getMainCanvas() const;
+ OffscreenCanvasPtr getCanvas(const std::string& sID) const;
+ void newCanvasDependency();
+
+ void play();
+ void stop();
+ bool isStopping();
+ void initPlayback(const std::string& sShaderPath = "");
+ void cleanup(bool bIsAbort);
+ bool isPlaying();
+ void setFramerate(float rate);
+ void setVBlankFramerate(int rate);
+ float getEffectiveFramerate();
+ TestHelper * getTestHelper();
+ void setFakeFPS(float fps);
+ long long getFrameTime();
+ float getFrameDuration();
+
+ NodePtr createNode(const std::string& sType, const py::dict& PyDict,
+ const py::object& self=py::object());
+ NodePtr createNodeFromXmlString(const std::string& sXML);
+
+ int setInterval(int time, PyObject * pyfunc);
+ int setTimeout(int time, PyObject * pyfunc);
+ int setOnFrameHandler(PyObject * pyfunc);
+ bool clearInterval(int id);
+ void callFromThread(PyObject * pyfunc);
+
+ void addInputDevice(IInputDevicePtr pSource);
+ MouseEventPtr getMouseState() const;
+ EventPtr getCurrentEvent() const;
+ TrackerInputDevice * getTracker();
+ void enableMultitouch();
+ void enableMouse(bool enabled);
+ bool isMultitouchAvailable() const;
+ void setEventCapture(NodePtr pNode, int cursorID);
+ void releaseEventCapture(int cursorID);
+ bool isCaptured(int cursorID);
+ void removeDeadEventCaptures();
+ EventPtr getCurEvent() const;
+ void setMousePos(const IntPoint& pos);
+ int getKeyModifierState() const;
+
+ BitmapPtr screenshot();
+ void setCursor(const Bitmap* pBmp, IntPoint hotSpot);
+ void showCursor(bool bShow);
+ bool isCursorShown();
+
+ NodePtr getElementByID(const std::string& id);
+ AVGNodePtr getRootNode();
+ void doFrame(bool bFirstFrame);
+ float getFramerate();
+ float getVideoRefreshRate();
+ size_t getVideoMemInstalled();
+ size_t getVideoMemUsed();
+ void setGamma(float red, float green, float blue);
+ SDLDisplayEngine * getDisplayEngine() const;
+ void keepWindowOpen();
+ void setStopOnEscape(bool bStop);
+ bool getStopOnEscape() const;
+ void setVolume(float volume);
+ float getVolume() const;
+ std::string getConfigOption(const std::string& sSubsys, const std::string& sName)
+ const;
+ bool isUsingGLES() const;
+ bool areFullShadersSupported() const;
+
+ OffscreenCanvasPtr getCanvasFromURL(const std::string& sURL);
+
+ std::string getCurDirName();
+ std::string getRootMediaDir();
+
+ void disablePython();
+ void startTraversingTree();
+ void endTraversingTree();
+ bool isTraversingTree() const;
+
+ py::object loadPlugin(const std::string& name);
+ void setPluginPath(const std::string& newPath);
+ std::string getPluginPath() const;
+
+ void setEventHook(PyObject * pyfunc);
+ PyObject * getEventHook() const;
+
+ void registerFrameEndListener(IFrameEndListener* pListener);
+ void unregisterFrameEndListener(IFrameEndListener* pListener);
+ void registerPlaybackEndListener(IPlaybackEndListener* pListener);
+ void unregisterPlaybackEndListener(IPlaybackEndListener* pListener);
+ void registerPreRenderListener(IPreRenderListener* pListener);
+ void unregisterPreRenderListener(IPreRenderListener* pListener);
+
+ bool handleEvent(EventPtr pEvent);
+
+ private:
+ void initConfig();
+ void initGraphics(const std::string& sShaderPath);
+ void initAudio();
+ void initMainCanvas(NodePtr pRootNode);
+
+ NodePtr loadMainNodeFromFile(const std::string& sFilename);
+ NodePtr loadMainNodeFromString(const std::string& sAVG);
+ NodePtr internalLoad(const std::string& sAVG, const std::string& sFilename);
+ SDLDisplayEnginePtr safeGetDisplayEngine();
+
+ NodePtr createNodeFromXml(const xmlDocPtr xmlDoc,
+ const xmlNodePtr xmlNode);
+ OffscreenCanvasPtr registerOffscreenCanvas(NodePtr pNode);
+ OffscreenCanvasPtr findCanvas(const std::string& sID) const;
+ void endFrame();
+
+ void sendFakeEvents();
+ void sendOver(CursorEventPtr pOtherEvent, Event::Type type, NodePtr pNode);
+ void handleCursorEvent(CursorEventPtr pEvent, bool bOnlyCheckCursorOver=false);
+
+ void dispatchOffscreenRendering(OffscreenCanvas* pOffscreenCanvas);
+
+ void errorIfPlaying(const std::string& sFunc) const;
+
+ MainCanvasPtr m_pMainCanvas;
+
+ SDLDisplayEnginePtr m_pDisplayEngine;
+ bool m_bDisplayEngineBroken;
+ TestHelperPtr m_pTestHelper;
+
+ std::string m_CurDirName;
+ bool m_bIsTraversingTree;
+ bool m_bStopping;
+
+ IInputDevicePtr m_pMultitouchInputDevice;
+
+ // Timeout handling
+ int internalSetTimeout(int time, PyObject * pyfunc, bool bIsInterval);
+ int addTimeout(Timeout* pTimeout);
+ void handleTimers();
+ bool m_bInHandleTimers;
+ bool m_bCurrentTimeoutDeleted;
+
+ std::vector<Timeout *> m_PendingTimeouts;
+ std::vector<Timeout *> m_NewTimeouts; // Timeouts to be added this frame.
+ std::vector<Timeout *> m_AsyncCalls;
+ boost::mutex m_AsyncCallMutex;
+
+ // Configuration variables.
+ DisplayParams m_DP;
+ AudioParams m_AP;
+ GLConfig m_GLConfig;
+
+ bool m_bKeepWindowOpen;
+ bool m_bStopOnEscape;
+ bool m_bIsPlaying;
+
+ // Time calculation
+ bool m_bFakeFPS;
+ float m_FakeFPS;
+ long long m_FrameTime;
+ long long m_PlayStartTime;
+ long long m_NumFrames;
+
+ float m_Volume;
+
+ bool m_bPythonAvailable;
+
+ std::vector<OffscreenCanvasPtr> m_pCanvases;
+
+ static Player * s_pPlayer;
+ friend void deletePlayer();
+
+ EventDispatcherPtr m_pEventDispatcher;
+ struct EventCaptureInfo {
+ EventCaptureInfo(const NodeWeakPtr& pNode);
+
+ NodePtr m_pNode;
+ int m_CaptureCount;
+ };
+ typedef boost::shared_ptr<EventCaptureInfo> EventCaptureInfoPtr;
+
+ std::map<int, EventCaptureInfoPtr> m_EventCaptureInfoMap;
+
+ MouseEventPtr m_pLastMouseEvent;
+ EventPtr m_pCurrentEvent;
+
+ // The indexes of this map are cursorids.
+ std::map<int, CursorStatePtr> m_pLastCursorStates;
+
+ PyObject * m_EventHookPyFunc;
+ bool m_bMouseEnabled;
+};
+
+}
+#endif
diff --git a/src/player/PluginManager.cpp b/src/player/PluginManager.cpp
new file mode 100644
index 0000000..57d33f0
--- /dev/null
+++ b/src/player/PluginManager.cpp
@@ -0,0 +1,187 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+// Original author of this file is Jan Boelsche (regular.gonzales@googlemail.com).
+//
+
+#include "PluginManager.h"
+
+#include "../base/DlfcnWrapper.h"
+#include "../base/FileHelper.h"
+#include "../base/Logger.h"
+#include "../base/OSHelper.h"
+
+#include <iostream>
+#include <string>
+
+using namespace std;
+using namespace avg;
+
+#ifdef _WIN32
+#define PATH_DELIMITER ";"
+#define PLUGIN_EXTENSION ".dll"
+#else
+#define PATH_DELIMITER ":"
+#define PLUGIN_EXTENSION ".so"
+#endif
+
+PluginManager::PluginNotFound::PluginNotFound(const string& sMessage) :
+ Exception(AVG_ERR_FILEIO, sMessage) {}
+
+PluginManager::PluginCorrupted::PluginCorrupted(const string& sMessage) :
+ Exception(AVG_ERR_CORRUPT_PLUGIN, sMessage) {}
+
+PluginManager& PluginManager::get()
+{
+ static PluginManager s_Instance;
+ return s_Instance;
+}
+
+PluginManager::PluginManager()
+{
+ setSearchPath(string("."PATH_DELIMITER) +
+ "./plugin"PATH_DELIMITER +
+ "./plugin/.libs"PATH_DELIMITER +
+ getPath(getAvgLibPath()) + "plugin");
+}
+
+void PluginManager::setSearchPath(const string& sNewPath)
+{
+ m_sCurrentSearchPath = sNewPath;
+ parsePath(m_sCurrentSearchPath);
+}
+
+string PluginManager::getSearchPath() const
+{
+ return m_sCurrentSearchPath;
+}
+
+py::object PluginManager::loadPlugin(const std::string& sPluginName)
+{
+ // is it loaded aready?
+ PluginMap::iterator i = m_LoadedPlugins.find(sPluginName);
+ if (i == m_LoadedPlugins.end()) {
+ // no, let's try to load it!
+ string sFullpath = locateSharedObject(sPluginName+PLUGIN_EXTENSION);
+ void *handle = internalLoadPlugin(sFullpath);
+ // add to map of loaded plugins
+ m_LoadedPlugins[sPluginName] = make_pair(handle, 1);
+ } else {
+ // yes, just increase the reference count
+ int referenceCount = i->second.second;
+ ++referenceCount;
+ m_LoadedPlugins[sPluginName] = make_pair(i->second.first, referenceCount);
+ }
+ py::object sysModule(py::handle<>(PyImport_ImportModule("sys")));
+ return sysModule.attr("modules")[sPluginName];
+}
+
+string PluginManager::locateSharedObject(const string& sFilename)
+{
+ vector<string>::iterator i = m_PathComponents.begin();
+ string sFullpath;
+ while (i != m_PathComponents.end()) {
+ sFullpath = *i + sFilename;
+ if (fileExists(sFullpath)) {
+ return sFullpath;
+ }
+ ++i;
+ }
+ string sMessage = "Unable to locate plugin file '" + sFilename
+ + "'. Was looking in " + m_sCurrentSearchPath;
+ AVG_TRACE(Logger::category::PLUGIN, Logger::severity::INFO, sMessage);
+ throw PluginNotFound(sMessage);
+}
+
+string PluginManager::checkDirectory(const string& sDirectory)
+{
+ string sFixedDirectory;
+ char lastChar = *sDirectory.rbegin();
+ if (lastChar != '/' && lastChar != '\\') {
+ sFixedDirectory = sDirectory + "/";
+ } else {
+ sFixedDirectory = sDirectory;
+ }
+ return sFixedDirectory;
+}
+
+void PluginManager::parsePath(const string& sPath)
+{
+ // break the string into colon separated components
+ // and make sure each component has a trailing slash
+ // warn about non-existing directories
+
+ m_PathComponents.clear();
+ string sRemaining = sPath;
+ string::size_type i;
+ do {
+ i = sRemaining.find(PATH_DELIMITER);
+ string sDirectory;
+ if (i == string::npos) {
+ sDirectory = sRemaining;
+ sRemaining = "";
+ } else {
+ sDirectory = sRemaining.substr(0, i);
+ sRemaining = sRemaining.substr(i+1);
+ }
+ sDirectory = checkDirectory(sDirectory);
+
+ m_PathComponents.push_back(sDirectory);
+ } while (!sRemaining.empty());
+ AVG_TRACE(Logger::category::PLUGIN, Logger::severity::INFO,
+ "Plugin search path set to '" << sPath << "'");
+}
+
+void* PluginManager::internalLoadPlugin(const string& sFullpath)
+{
+ void *handle = dlopen(sFullpath.c_str(), RTLD_LOCAL | RTLD_NOW);
+ if (!handle) {
+ string sMessage(dlerror());
+ AVG_TRACE(Logger::category::PLUGIN, Logger::severity::ERROR,
+ "Could not load plugin. dlopen failed with message '"
+ << sMessage << "'");
+ throw PluginCorrupted(sMessage);
+ }
+ try {
+ registerPlugin(handle);
+ } catch(PluginCorrupted& e) {
+ dlclose(handle);
+ throw e;
+ }
+ AVG_TRACE(Logger::category::PLUGIN,Logger::severity::INFO,
+ "Loaded plugin '" << sFullpath << "'");
+ return handle;
+}
+
+void PluginManager::registerPlugin(void* handle)
+{
+ typedef void (*RegisterPluginPtr)();
+ RegisterPluginPtr registerPlugin =
+ reinterpret_cast<RegisterPluginPtr>(dlsym(handle, "registerPlugin"));
+
+ if (registerPlugin) {
+ registerPlugin();
+ } else {
+ AVG_TRACE(Logger::category::PLUGIN, Logger::severity::ERROR,
+ "No plugin registration function detected");
+ throw PluginCorrupted("No plugin registration function detected");
+ }
+}
+
diff --git a/src/player/PluginManager.h b/src/player/PluginManager.h
new file mode 100644
index 0000000..37a5d23
--- /dev/null
+++ b/src/player/PluginManager.h
@@ -0,0 +1,76 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+// Original author of this file is Jan Boelsche (regular.gonzales@googlemail.com).
+//
+#ifndef _PluginManager_H_
+#define _PluginManager_H_
+
+#include "../api.h"
+
+#include "BoostPython.h"
+
+#include "../base/Exception.h"
+
+#include <map>
+#include <vector>
+#include <memory>
+
+namespace avg {
+
+class AVG_API PluginManager
+{
+public:
+ class AVG_API PluginNotFound : public Exception {
+ public:
+ PluginNotFound(const std::string& sMessage);
+ };
+ class AVG_API PluginCorrupted : public Exception {
+ public:
+ PluginCorrupted(const std::string& sMessage);
+ };
+
+ static PluginManager& get();
+
+ void setSearchPath(const std::string& aNewPath);
+ std::string getSearchPath() const;
+
+ py::object loadPlugin(const std::string& aPluginName);
+
+private:
+ PluginManager();
+
+ std::string checkDirectory(const std::string& sDirectory);
+ void parsePath(const std::string& sPath);
+ std::string locateSharedObject(const std::string& sPluginName);
+ void* internalLoadPlugin(const std::string& sPluginName);
+ void registerPlugin(void* pHandle);
+
+ // maps module names to a pair of handle and reference count
+ typedef std::map<std::string, std::pair<void*, int> > PluginMap;
+ PluginMap m_LoadedPlugins;
+ std::vector<std::string> m_PathComponents;
+ std::string m_sCurrentSearchPath;
+};
+
+}
+
+#endif
+
diff --git a/src/player/PolyLineNode.cpp b/src/player/PolyLineNode.cpp
new file mode 100644
index 0000000..16899f7
--- /dev/null
+++ b/src/player/PolyLineNode.cpp
@@ -0,0 +1,118 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "PolyLineNode.h"
+
+#include "TypeDefinition.h"
+
+#include "../graphics/VertexArray.h"
+#include "../base/Exception.h"
+
+#include <iostream>
+#include <sstream>
+
+using namespace std;
+
+namespace avg {
+
+void PolyLineNode::registerType()
+{
+ vector<glm::vec2> v;
+ vector<float> vd;
+ TypeDefinition def = TypeDefinition("polyline", "vectornode",
+ ExportedObject::buildObject<PolyLineNode>)
+ .addArg(Arg<string>("linejoin", "bevel"))
+ .addArg(Arg<vector<glm::vec2> >("pos", v, false, offsetof(PolyLineNode, m_Pts)))
+ .addArg(Arg<vector<float> >("texcoords", vd, false,
+ offsetof(PolyLineNode, m_TexCoords)))
+ ;
+ TypeRegistry::get()->registerType(def);
+}
+
+PolyLineNode::PolyLineNode(const ArgList& args)
+ : VectorNode(args)
+{
+ args.setMembers(this);
+ if (m_TexCoords.size() > m_Pts.size()) {
+ throw(Exception(AVG_ERR_OUT_OF_RANGE,
+ "Too many texture coordinates in polyline"));
+ }
+ setLineJoin(args.getArgVal<string>("linejoin"));
+ calcPolyLineCumulDist(m_CumulDist, m_Pts, false);
+}
+
+PolyLineNode::~PolyLineNode()
+{
+}
+
+const vector<glm::vec2>& PolyLineNode::getPos() const
+{
+ return m_Pts;
+}
+
+void PolyLineNode::setPos(const vector<glm::vec2>& pts)
+{
+ m_Pts = pts;
+ m_TexCoords.clear();
+ m_EffTexCoords.clear();
+ calcPolyLineCumulDist(m_CumulDist, m_Pts, false);
+ setDrawNeeded();
+}
+
+const vector<float>& PolyLineNode::getTexCoords() const
+{
+ return m_TexCoords;
+}
+
+void PolyLineNode::setTexCoords(const vector<float>& coords)
+{
+ if (coords.size() > m_Pts.size()) {
+ throw(Exception(AVG_ERR_OUT_OF_RANGE,
+ "Too many texture coordinates in polyline"));
+ }
+ m_EffTexCoords.clear();
+ m_TexCoords = coords;
+ setDrawNeeded();
+}
+
+string PolyLineNode::getLineJoin() const
+{
+ return lineJoin2String(m_LineJoin);
+}
+
+void PolyLineNode::setLineJoin(const string& s)
+{
+ m_LineJoin = string2LineJoin(s);
+ setDrawNeeded();
+}
+
+void PolyLineNode::calcVertexes(const VertexDataPtr& pVertexData, Pixel32 color)
+{
+ if (getNumDifferentPts(m_Pts) < 2) {
+ return;
+ }
+ if (m_EffTexCoords.empty()) {
+ calcEffPolyLineTexCoords(m_EffTexCoords, m_TexCoords, m_CumulDist);
+ }
+ calcPolyLine(m_Pts, m_EffTexCoords, false, m_LineJoin, pVertexData, color);
+}
+
+}
diff --git a/src/player/PolyLineNode.h b/src/player/PolyLineNode.h
new file mode 100644
index 0000000..41ee162
--- /dev/null
+++ b/src/player/PolyLineNode.h
@@ -0,0 +1,65 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _PolyLineNode_H_
+#define _PolyLineNode_H_
+
+#include "../api.h"
+#include "VectorNode.h"
+
+#include "../graphics/Pixel32.h"
+#include "../base/WideLine.h"
+
+#include <vector>
+
+namespace avg {
+
+class AVG_API PolyLineNode : public VectorNode
+{
+ public:
+ static void registerType();
+
+ PolyLineNode(const ArgList& args);
+ virtual ~PolyLineNode();
+
+ const std::vector<glm::vec2>& getPos() const;
+ void setPos(const std::vector<glm::vec2>& pts);
+
+ const std::vector<float>& getTexCoords() const;
+ void setTexCoords(const std::vector<float>& coords);
+
+ std::string getLineJoin() const;
+ void setLineJoin(const std::string& s);
+
+ virtual void calcVertexes(const VertexDataPtr& pVertexData, Pixel32 color);
+
+ private:
+ std::vector<glm::vec2> m_Pts;
+ std::vector<float> m_CumulDist;
+ std::vector<float> m_TexCoords;
+ std::vector<float> m_EffTexCoords;
+ LineJoin m_LineJoin;
+};
+
+}
+
+#endif
+
diff --git a/src/player/PolygonNode.cpp b/src/player/PolygonNode.cpp
new file mode 100644
index 0000000..6e81b9b
--- /dev/null
+++ b/src/player/PolygonNode.cpp
@@ -0,0 +1,219 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "PolygonNode.h"
+
+#include "TypeDefinition.h"
+
+#include "../graphics/VertexArray.h"
+#include "../base/Exception.h"
+#include "../base/GeomHelper.h"
+#include "../base/triangulate/Triangulate.h"
+
+#include "../glm/gtx/norm.hpp"
+
+#include <iostream>
+#include <sstream>
+
+using namespace std;
+
+namespace avg {
+
+void PolygonNode::registerType()
+{
+ VectorVec2Vector cv;
+ vector<glm::vec2> v;
+ vector<float> vd;
+ TypeDefinition def = TypeDefinition("polygon", "filledvectornode",
+ ExportedObject::buildObject<PolygonNode>)
+ .addArg(Arg<string>("linejoin", "bevel"))
+ .addArg(Arg<vector<glm::vec2> >("pos", v, false, offsetof(PolygonNode, m_Pts)))
+ .addArg(Arg<vector<float> >("texcoords", vd, false,
+ offsetof(PolygonNode, m_TexCoords)))
+ .addArg(Arg<VectorVec2Vector>("holes", cv, false, offsetof(PolygonNode, m_Holes)))
+ ;
+ TypeRegistry::get()->registerType(def);
+}
+
+PolygonNode::PolygonNode(const ArgList& args)
+ : FilledVectorNode(args)
+{
+ args.setMembers(this);
+ if (m_TexCoords.size() > m_Pts.size()+1) {
+ throw(Exception(AVG_ERR_OUT_OF_RANGE,
+ "Too many texture coordinates in polygon"));
+ }
+ if (m_Pts.size() != 0 && m_Pts.size() < 3) {
+ throw(Exception(AVG_ERR_UNSUPPORTED,
+ "A polygon must have min. tree points."));
+ }
+ if (m_Holes.size() > 0) {
+ for (unsigned int i = 0; i < m_Holes.size(); i++) {
+ if (m_Holes[i].size() < 3) {
+ throw(Exception(AVG_ERR_UNSUPPORTED,
+ "A hole of a polygon must have min. tree points."));
+ }
+ }
+ }
+ setLineJoin(args.getArgVal<string>("linejoin"));
+ calcPolyLineCumulDist(m_CumulDist, m_Pts, true);
+}
+
+PolygonNode::~PolygonNode()
+{
+}
+
+const vector<glm::vec2>& PolygonNode::getPos() const
+{
+ return m_Pts;
+}
+
+void PolygonNode::setPos(const vector<glm::vec2>& pts)
+{
+ m_Pts.clear();
+ m_Pts = pts;
+ m_TexCoords.clear();
+ m_EffTexCoords.clear();
+ calcPolyLineCumulDist(m_CumulDist, m_Pts, true);
+ setDrawNeeded();
+}
+
+const vector<float>& PolygonNode::getTexCoords() const
+{
+ return m_TexCoords;
+}
+
+const VectorVec2Vector& PolygonNode::getHoles() const
+{
+ return m_Holes;
+}
+
+void PolygonNode::setHoles(const VectorVec2Vector& holes)
+{
+ m_Holes = holes;
+ m_TexCoords.clear();
+ m_EffTexCoords.clear();
+ setDrawNeeded();
+}
+
+void PolygonNode::setTexCoords(const vector<float>& coords)
+{
+ if (coords.size() > m_Pts.size()+1) {
+ throw(Exception(AVG_ERR_OUT_OF_RANGE,
+ "Too many texture coordinates in polygon"));
+ }
+ m_EffTexCoords.clear();
+ m_TexCoords = coords;
+ setDrawNeeded();
+}
+
+string PolygonNode::getLineJoin() const
+{
+ return lineJoin2String(m_LineJoin);
+}
+
+void PolygonNode::setLineJoin(const string& s)
+{
+ m_LineJoin = string2LineJoin(s);
+ setDrawNeeded();
+}
+
+void PolygonNode::getElementsByPos(const glm::vec2& pos, vector<NodePtr>& pElements)
+{
+ if (reactsToMouseEvents() && pointInPolygon(pos, m_Pts)) {
+ pElements.push_back(getSharedThis());
+ }
+}
+
+void PolygonNode::calcVertexes(const VertexDataPtr& pVertexData, Pixel32 color)
+{
+ if (getNumDifferentPts(m_Pts) < 3) {
+ return;
+ }
+ if (m_EffTexCoords.empty()) {
+ calcEffPolyLineTexCoords(m_EffTexCoords, m_TexCoords, m_CumulDist);
+ }
+ calcPolyLine(m_Pts, m_EffTexCoords, true, m_LineJoin, pVertexData, color);
+
+ for (unsigned i = 0; i < m_Holes.size(); i++) {
+ calcPolyLine(m_Holes[i], m_EffTexCoords, true, m_LineJoin, pVertexData, color);
+ }
+}
+
+void PolygonNode::calcFillVertexes(const VertexDataPtr& pVertexData, Pixel32 color)
+{
+ if (getNumDifferentPts(m_Pts) < 3) {
+ return;
+ }
+ // Remove duplicate points
+ vector<glm::vec2> pts;
+ vector<unsigned int> holeIndexes;
+ pts.reserve(m_Pts.size());
+
+ if (glm::distance2(m_Pts[0], m_Pts[m_Pts.size()-1]) > 0.1) {
+ pts.push_back(m_Pts[0]);
+ }
+ for (unsigned i = 1; i < m_Pts.size(); ++i) {
+ if (glm::distance2(m_Pts[i], m_Pts[i-1]) > 0.1) {
+ pts.push_back(m_Pts[i]);
+ }
+ }
+
+ if (m_Holes.size() > 0) {
+ for (unsigned int i = 0; i < m_Holes.size(); i++) { //loop over collection
+ holeIndexes.push_back(pts.size());
+ for (unsigned int j = 0; j < m_Holes[i].size(); j++) { //loop over vector
+ pts.push_back(m_Holes[i][j]);
+ }
+ }
+ }
+ if (color.getA() > 0) {
+ glm::vec2 minCoord = pts[0];
+ glm::vec2 maxCoord = pts[0];
+ for (unsigned i = 1; i < pts.size(); ++i) {
+ if (pts[i].x < minCoord.x) {
+ minCoord.x = pts[i].x;
+ }
+ if (pts[i].x > maxCoord.x) {
+ maxCoord.x = pts[i].x;
+ }
+ if (pts[i].y < minCoord.y) {
+ minCoord.y = pts[i].y;
+ }
+ if (pts[i].y > maxCoord.y) {
+ maxCoord.y = pts[i].y;
+ }
+ }
+ vector<unsigned int> triIndexes;
+ triangulatePolygon(triIndexes, pts, holeIndexes);
+
+ for (unsigned i = 0; i < pts.size(); ++i) {
+ glm::vec2 texCoord = calcFillTexCoord(pts[i], minCoord, maxCoord);
+ pVertexData->appendPos(pts[i], texCoord, color);
+ }
+ for (unsigned i = 0; i < triIndexes.size(); i+=3) {
+ pVertexData->appendTriIndexes(triIndexes[i], triIndexes[i+1],
+ triIndexes[i+2]);
+ }
+ }
+}
+
+}
diff --git a/src/player/PolygonNode.h b/src/player/PolygonNode.h
new file mode 100644
index 0000000..850f88f
--- /dev/null
+++ b/src/player/PolygonNode.h
@@ -0,0 +1,74 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _PolygonNode_H_
+#define _PolygonNode_H_
+
+#include "../api.h"
+#include "FilledVectorNode.h"
+
+#include "../graphics/Pixel32.h"
+#include "../base/WideLine.h"
+
+#include <vector>
+
+namespace avg {
+
+typedef std::vector<std::vector<glm::vec2> > VectorVec2Vector;
+
+class AVG_API PolygonNode : public FilledVectorNode
+{
+ public:
+ static void registerType();
+
+ PolygonNode(const ArgList& args);
+ virtual ~PolygonNode();
+
+ const std::vector<glm::vec2>& getPos() const;
+ void setPos(const std::vector<glm::vec2>& pts);
+
+ const std::vector<float>& getTexCoords() const;
+ void setTexCoords(const std::vector<float>& coords);
+
+ const VectorVec2Vector& getHoles() const;
+ void setHoles(const VectorVec2Vector& holes);
+
+ std::string getLineJoin() const;
+ void setLineJoin(const std::string& s);
+
+ void getElementsByPos(const glm::vec2& pos, std::vector<NodePtr>& pElements);
+
+ virtual void calcVertexes(const VertexDataPtr& pVertexData, Pixel32 color);
+ virtual void calcFillVertexes(const VertexDataPtr& pVertexData, Pixel32 color);
+
+ private:
+ std::vector<glm::vec2> m_Pts;
+ std::vector<float> m_CumulDist;
+ std::vector<float> m_TexCoords;
+ std::vector<float> m_EffTexCoords;
+ VectorVec2Vector m_Holes;
+ LineJoin m_LineJoin;
+};
+
+}
+
+#endif
+
diff --git a/src/player/Publisher.cpp b/src/player/Publisher.cpp
new file mode 100644
index 0000000..01bbea3
--- /dev/null
+++ b/src/player/Publisher.cpp
@@ -0,0 +1,248 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "Publisher.h"
+
+#include "SubscriberInfo.h"
+#include "PublisherDefinitionRegistry.h"
+#include "Player.h"
+
+#include "../base/Exception.h"
+#include "../base/StringHelper.h"
+
+using namespace std;
+
+namespace avg {
+
+int Publisher::s_LastSubscriberID = 0;
+
+Publisher::Publisher()
+{
+ m_pPublisherDef = PublisherDefinition::create("");
+}
+
+Publisher::Publisher(const string& sTypeName)
+{
+ m_pPublisherDef = PublisherDefinitionRegistry::get()->getDefinition(sTypeName);
+ vector<MessageID> messageIDs = m_pPublisherDef->getMessageIDs();
+ for (unsigned i=0; i<messageIDs.size(); ++i) {
+ m_SignalMap[messageIDs[i]] = list<SubscriberInfoPtr>();
+ }
+}
+
+Publisher::~Publisher()
+{
+}
+
+int Publisher::subscribe(MessageID messageID, const py::object& callable)
+{
+ SubscriberInfoList& subscribers = safeFindSubscribers(messageID);
+ int subscriberID = s_LastSubscriberID;
+ s_LastSubscriberID++;
+// cerr << this << " subscribe " << messageID << ", " << subscriberID << endl;
+ subscribers.push_front(SubscriberInfoPtr(new SubscriberInfo(subscriberID, callable)));
+ return subscriberID;
+}
+
+void Publisher::unsubscribe(MessageID messageID, int subscriberID)
+{
+// cerr << this << " unsubscribe " << messageID << ", " << subscriberID << endl;
+// cerr << " ";
+// dumpSubscribers(messageID);
+ SubscriberInfoList& subscribers = safeFindSubscribers(messageID);
+ SubscriberInfoList::iterator it;
+ for (it = subscribers.begin(); it != subscribers.end(); it++) {
+ if ((*it)->getID() == subscriberID) {
+ unsubscribeIterator(messageID, it);
+ return;
+ }
+ }
+// cerr << " End of unsubscribe: ";
+// dumpSubscribers(messageID);
+ throwSubscriberNotFound(messageID, subscriberID);
+}
+
+void Publisher::unsubscribe1(int subscriberID)
+{
+ SignalMap::iterator it;
+ for (it = m_SignalMap.begin(); it != m_SignalMap.end(); ++it) {
+ SubscriberInfoList& subscribers = it->second;
+ SubscriberInfoList::iterator it2;
+ for (it2 = subscribers.begin(); it2 != subscribers.end(); it2++) {
+ if ((*it2)->getID() == subscriberID) {
+ MessageID messageID = it->first;
+ unsubscribeIterator(messageID, it2);
+ return;
+ }
+ }
+ }
+ throw Exception(AVG_ERR_INVALID_ARGS,
+ "Subscriber with ID "+toString(subscriberID)+" not found.");
+}
+
+void Publisher::unsubscribeCallable(MessageID messageID, const py::object& callable)
+{
+ SubscriberInfoList& subscribers = safeFindSubscribers(messageID);
+ SubscriberInfoList::iterator it;
+ for (it = subscribers.begin(); it != subscribers.end(); it++) {
+ if ((*it)->isCallable(callable)) {
+ unsubscribeIterator(messageID, it);
+ return;
+ }
+ }
+ throwSubscriberNotFound(messageID, -1);
+}
+
+int Publisher::getNumSubscribers(MessageID messageID)
+{
+ SubscriberInfoList& subscribers = safeFindSubscribers(messageID);
+ return subscribers.size();
+}
+
+bool Publisher::isSubscribed(MessageID messageID, int subscriberID)
+{
+ SubscriberInfoList& subscribers = safeFindSubscribers(messageID);
+ SubscriberInfoList::iterator it;
+ for (it = subscribers.begin(); it != subscribers.end(); it++) {
+ if ((*it)->getID() == subscriberID) {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool Publisher::isSubscribedCallable(MessageID messageID, const py::object& callable)
+{
+ SubscriberInfoList& subscribers = safeFindSubscribers(messageID);
+ SubscriberInfoList::iterator it;
+ for (it = subscribers.begin(); it != subscribers.end(); it++) {
+ if ((*it)->isCallable(callable)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+void Publisher::publish(MessageID messageID)
+{
+ if (m_SignalMap.find(messageID) != m_SignalMap.end()) {
+ throw Exception(AVG_ERR_INVALID_ARGS, "Signal with ID "+toString(messageID)+
+ "already registered.");
+ }
+ m_SignalMap[messageID] = SubscriberInfoList();
+}
+
+void Publisher::removeSubscribers()
+{
+ SignalMap::iterator it;
+ for (it = m_SignalMap.begin(); it != m_SignalMap.end(); ++it) {
+ it->second = SubscriberInfoList();
+ }
+}
+
+void Publisher::notifySubscribers(MessageID messageID)
+{
+ SubscriberInfoList& subscribers = safeFindSubscribers(messageID);
+ if (!subscribers.empty()) {
+ py::list args;
+ notifySubscribersPy(messageID, args);
+ }
+}
+
+void Publisher::notifySubscribers(const string& sMsgName)
+{
+ MessageID messageID = m_pPublisherDef->getMessageID(sMsgName);
+ notifySubscribers(messageID);
+}
+
+void Publisher::notifySubscribersPy(MessageID messageID, const py::list& args)
+{
+// cerr << this << " notifySubscribers " << messageID << endl;
+// cerr << " ";
+// dumpSubscribers(messageID);
+ AVG_ASSERT(!(Player::get()->isTraversingTree()));
+ SubscriberInfoList& subscribers = safeFindSubscribers(messageID);
+ WeakSubscriberInfoList subRefs;
+ for (SubscriberInfoList::iterator it = subscribers.begin(); it != subscribers.end();
+ ++it)
+ {
+ subRefs.push_back(*it);
+ }
+ WeakSubscriberInfoList::iterator it;
+ for (it = subRefs.begin(); it != subRefs.end(); ++it) {
+// cerr << " next" << endl;
+ if (!(*it).expired()) {
+ SubscriberInfoPtr pSub = (*it).lock();
+ if (pSub->hasExpired()) {
+ // Python subscriber doesn't exist anymore -> auto-unsubscribe.
+ unsubscribe(messageID, pSub->getID());
+ } else {
+// cerr << " invoke: " << (*it)->getID() << endl;
+ pSub->invoke(args);
+ }
+ }
+ }
+// cerr << " end notify" << endl;
+}
+
+MessageID Publisher::genMessageID()
+{
+ return PublisherDefinitionRegistry::get()->genMessageID();
+}
+
+void Publisher::unsubscribeIterator(MessageID messageID, SubscriberInfoList::iterator it)
+{
+ m_SignalMap[messageID].erase(it);
+}
+
+
+Publisher::SubscriberInfoList& Publisher::safeFindSubscribers(MessageID messageID)
+{
+ if (m_SignalMap.find(messageID) == m_SignalMap.end()) {
+ throw Exception(AVG_ERR_INVALID_ARGS, "No signal with ID "+toString(messageID));
+ }
+ SubscriberInfoList& subscribers = m_SignalMap[messageID];
+ return subscribers;
+}
+
+void Publisher::throwSubscriberNotFound(MessageID messageID, int subscriberID)
+{
+ if (subscriberID == -1) {
+ throw Exception(AVG_ERR_INVALID_ARGS, "Signal with ID "+toString(messageID)+
+ " doesn't have a subscriber with the given callable.");
+ } else {
+ throw Exception(AVG_ERR_INVALID_ARGS, "Signal with ID "+toString(messageID)+
+ " doesn't have a subscriber with ID "+toString(subscriberID));
+ }
+}
+
+void Publisher::dumpSubscribers(MessageID messageID)
+{
+ SubscriberInfoList& subscribers = safeFindSubscribers(messageID);
+ SubscriberInfoList::iterator it;
+ for (it = subscribers.begin(); it != subscribers.end(); it++) {
+ cerr << (*it)->getID() << " ";
+ }
+ cerr << endl;
+}
+
+
+}
diff --git a/src/player/Publisher.h b/src/player/Publisher.h
new file mode 100644
index 0000000..1270544
--- /dev/null
+++ b/src/player/Publisher.h
@@ -0,0 +1,113 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _Publisher_H_
+#define _Publisher_H_
+
+#include "../api.h"
+
+#include "ExportedObject.h"
+#include "BoostPython.h"
+#include "PublisherDefinition.h"
+#include "MessageID.h"
+
+#include <boost/shared_ptr.hpp>
+
+// Python docs say python.h should be included before any standard headers (!)
+#include "WrapPython.h"
+
+#include <list>
+#include <map>
+
+namespace avg {
+
+class SubscriberInfo;
+typedef boost::shared_ptr<SubscriberInfo> SubscriberInfoPtr;
+typedef boost::weak_ptr<SubscriberInfo> SubscriberInfoWeakPtr;
+
+class Publisher;
+typedef boost::shared_ptr<Publisher> PublisherPtr;
+
+class AVG_API Publisher: public ExportedObject
+{
+public:
+ Publisher();
+ Publisher(const std::string& sTypeName);
+ virtual ~Publisher();
+
+ int subscribe(MessageID messageID, const py::object& callable);
+ void unsubscribe(MessageID messageID, int subscriberID);
+ void unsubscribe1(int subscriberID);
+ void unsubscribeCallable(MessageID messageID, const py::object& callable);
+ int getNumSubscribers(MessageID messageID);
+ bool isSubscribed(MessageID messageID, int subscriberID);
+ bool isSubscribedCallable(MessageID messageID, const py::object& callable);
+
+ // The following methods should really be protected, but python derived classes need
+ // to call them too.
+ void publish(MessageID messageID);
+
+ void notifySubscribers(MessageID messageID);
+ void notifySubscribers(const std::string& sMsgName);
+ template<class ARG_TYPE>
+ void notifySubscribers(const std::string& sMsgName, const ARG_TYPE& arg);
+ void notifySubscribersPy(MessageID messageID, const py::list& args);
+
+ static MessageID genMessageID();
+
+protected:
+ void removeSubscribers();
+
+private:
+ typedef std::list<SubscriberInfoWeakPtr> WeakSubscriberInfoList;
+ typedef std::list<SubscriberInfoPtr> SubscriberInfoList;
+ typedef std::map<MessageID, SubscriberInfoList> SignalMap;
+
+ void unsubscribeIterator(MessageID messageID, SubscriberInfoList::iterator it);
+ SubscriberInfoList& safeFindSubscribers(MessageID messageID);
+ void throwSubscriberNotFound(MessageID messageID, int subscriberID);
+ void dumpSubscribers(MessageID messageID);
+
+ PublisherDefinitionPtr m_pPublisherDef;
+ SignalMap m_SignalMap;
+ static int s_LastSubscriberID;
+
+ typedef std::pair<MessageID, int> UnsubscribeDescription;
+};
+
+template<class ARG_TYPE>
+void Publisher::notifySubscribers(const std::string& sMsgName, const ARG_TYPE& arg)
+{
+ MessageID messageID = m_pPublisherDef->getMessageID(sMsgName);
+ SubscriberInfoList& subscribers = safeFindSubscribers(messageID);
+ if (!subscribers.empty()) {
+ py::list args;
+ py::object pyArg(arg);
+ args.append(pyArg);
+ notifySubscribersPy(messageID, args);
+ }
+}
+
+
+}
+
+#endif
+
diff --git a/src/player/PublisherDefinition.cpp b/src/player/PublisherDefinition.cpp
new file mode 100644
index 0000000..33fddf0
--- /dev/null
+++ b/src/player/PublisherDefinition.cpp
@@ -0,0 +1,90 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "PublisherDefinition.h"
+
+#include "PublisherDefinitionRegistry.h"
+
+#include "../base/Exception.h"
+
+using namespace std;
+
+namespace avg {
+
+PublisherDefinition::PublisherDefinition(const string& sName, const string& sBaseName)
+ : m_sName(sName)
+{
+ if (sBaseName != "") {
+ PublisherDefinitionPtr pBaseDef =
+ PublisherDefinitionRegistry::get()->getDefinition(sBaseName);
+ m_MessageIDs = pBaseDef->m_MessageIDs;
+ }
+}
+
+PublisherDefinition::~PublisherDefinition()
+{
+}
+
+PublisherDefinitionPtr PublisherDefinition::create(const std::string& sName,
+ const std::string& sBaseName)
+{
+ PublisherDefinitionPtr pDef(new PublisherDefinition(sName, sBaseName));
+ PublisherDefinitionRegistry::get()->registerDefinition(pDef);
+ return pDef;
+}
+
+void PublisherDefinition::addMessage(const std::string& sName)
+{
+ m_MessageIDs.push_back(PublisherDefinitionRegistry::get()->genMessageID(sName));
+}
+
+const MessageID& PublisherDefinition::getMessageID(const std::string& sName) const
+{
+ for (unsigned i=0; i<m_MessageIDs.size(); ++i) {
+ if (m_MessageIDs[i].m_sName == sName) {
+ return m_MessageIDs[i];
+ }
+ }
+ AVG_ASSERT_MSG(false, (string("Message named '")+sName+("' unknown.")).c_str());
+ // Avoid compiler warning.
+ static MessageID nullMsg("", -1);
+ return nullMsg;
+}
+
+const std::vector<MessageID>& PublisherDefinition::getMessageIDs() const
+{
+ return m_MessageIDs;
+}
+
+const std::string& PublisherDefinition::getName() const
+{
+ return m_sName;
+}
+
+void PublisherDefinition::dump() const
+{
+ cerr << m_sName << endl;
+ for (unsigned i=0; i<m_MessageIDs.size(); ++i) {
+ cerr << " " << m_MessageIDs[i].m_sName << ": " << m_MessageIDs[i].m_ID << endl;
+ }
+}
+
+}
diff --git a/src/player/PublisherDefinition.h b/src/player/PublisherDefinition.h
new file mode 100644
index 0000000..a8d5e7e
--- /dev/null
+++ b/src/player/PublisherDefinition.h
@@ -0,0 +1,62 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _PublisherDefinition_H_
+#define _PublisherDefinition_H_
+
+#include "../api.h"
+
+#include "MessageID.h"
+
+#include <boost/shared_ptr.hpp>
+#include <vector>
+#include <string>
+
+namespace avg {
+
+class PublisherDefinition;
+typedef boost::shared_ptr<PublisherDefinition> PublisherDefinitionPtr;
+
+class AVG_API PublisherDefinition
+{
+public:
+ virtual ~PublisherDefinition();
+ static PublisherDefinitionPtr create(const std::string& sName,
+ const std::string& sBaseName="");
+
+ void addMessage(const std::string& sName);
+ const MessageID& getMessageID(const std::string& sName) const;
+ const std::vector<MessageID> & getMessageIDs() const;
+
+ const std::string& getName() const;
+ void dump() const;
+
+private:
+ PublisherDefinition(const std::string& sName, const std::string& sBaseName);
+
+ std::string m_sName;
+ std::vector<MessageID> m_MessageIDs;
+};
+
+}
+
+#endif
+
diff --git a/src/player/PublisherDefinitionRegistry.cpp b/src/player/PublisherDefinitionRegistry.cpp
new file mode 100644
index 0000000..3972a32
--- /dev/null
+++ b/src/player/PublisherDefinitionRegistry.cpp
@@ -0,0 +1,90 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "PublisherDefinitionRegistry.h"
+
+#include "PublisherDefinition.h"
+
+#include "../base/Exception.h"
+
+using namespace std;
+
+
+namespace avg {
+
+PublisherDefinitionRegistry* PublisherDefinitionRegistry::s_pInstance = 0;
+
+PublisherDefinitionRegistry::PublisherDefinitionRegistry()
+ : m_LastMessageID(-1)
+{
+ s_pInstance = this;
+ // The following should really happen in the player constructor, but the entries
+ // need to exist for the player to be constructed.
+ PublisherDefinitionPtr pPlayerDef = PublisherDefinition::create("Player");
+ pPlayerDef->addMessage("KEY_DOWN");
+ pPlayerDef->addMessage("KEY_UP");
+ pPlayerDef->addMessage("PLAYBACK_START");
+ pPlayerDef->addMessage("PLAYBACK_END");
+ pPlayerDef->addMessage("ON_FRAME");
+}
+
+PublisherDefinitionRegistry::~PublisherDefinitionRegistry()
+{
+}
+
+PublisherDefinitionRegistry* PublisherDefinitionRegistry::get()
+{
+ if (!s_pInstance) {
+ new PublisherDefinitionRegistry();
+ }
+ return s_pInstance;
+}
+
+void PublisherDefinitionRegistry::registerDefinition(PublisherDefinitionPtr def)
+{
+ m_Definitions.push_back(def);
+}
+
+PublisherDefinitionPtr PublisherDefinitionRegistry::getDefinition(const string& sName)
+ const
+{
+ for (unsigned i=0; i<m_Definitions.size(); ++i) {
+ if (m_Definitions[i]->getName() == sName) {
+ return m_Definitions[i];
+ }
+ }
+ AVG_ASSERT_MSG(false, (string("Can't find PublisherDefinition ")+sName).c_str());
+ return PublisherDefinitionPtr();
+}
+
+void PublisherDefinitionRegistry::dump() const
+{
+ for (unsigned i=0; i<m_Definitions.size(); ++i) {
+ m_Definitions[i]->dump();
+ }
+}
+
+MessageID PublisherDefinitionRegistry::genMessageID(const string& sName)
+{
+ return MessageID(sName, ++m_LastMessageID);
+}
+
+}
diff --git a/src/player/PublisherDefinitionRegistry.h b/src/player/PublisherDefinitionRegistry.h
new file mode 100644
index 0000000..8d3acac
--- /dev/null
+++ b/src/player/PublisherDefinitionRegistry.h
@@ -0,0 +1,63 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _PublisherDefinitionRegistry_H_
+#define _PublisherDefinitionRegistry_H_
+
+#include "../api.h"
+
+#include "MessageID.h"
+
+#include <boost/shared_ptr.hpp>
+#include <vector>
+#include <string>
+
+namespace avg {
+
+class PublisherDefinition;
+typedef boost::shared_ptr<PublisherDefinition> PublisherDefinitionPtr;
+
+class AVG_API PublisherDefinitionRegistry
+{
+public:
+ static PublisherDefinitionRegistry* get();
+ virtual ~PublisherDefinitionRegistry();
+
+ void registerDefinition(PublisherDefinitionPtr def);
+ PublisherDefinitionPtr getDefinition(const std::string& sName) const;
+
+ void dump() const;
+
+ MessageID genMessageID(const std::string& sName="");
+
+private:
+ PublisherDefinitionRegistry();
+ std::vector<PublisherDefinitionPtr> m_Definitions;
+ int m_LastMessageID;
+
+ static PublisherDefinitionRegistry* s_pInstance;
+};
+
+}
+
+#endif
+
+
diff --git a/src/player/PythonLogSink.cpp b/src/player/PythonLogSink.cpp
new file mode 100644
index 0000000..5da5829
--- /dev/null
+++ b/src/player/PythonLogSink.cpp
@@ -0,0 +1,90 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+
+#include "PythonLogSink.h"
+#include "WrapPython.h"
+#include "../base/Logger.h"
+
+#include <iostream>
+#include <boost/algorithm/string.hpp>
+#include <boost/python/errors.hpp>
+
+namespace avg
+{
+
+PythonLogSink::PythonLogSink(PyObject *pyLogger):
+ m_pyLogger(pyLogger)
+{
+ Py_INCREF(pyLogger);
+ assert(pyLogger);
+}
+
+PythonLogSink::~PythonLogSink()
+{
+ Py_DecRef(m_pyLogger);
+}
+
+const char * PythonLogSink::LogSeverityToPythonString(severity_t severity)
+{
+ if(severity == Logger::severity::CRITICAL) {
+ return "critical";
+ } else if(severity == Logger::severity::ERROR) {
+ return "error";
+ } else if(severity == Logger::severity::WARNING) {
+ return "warning";
+ } else if(severity == Logger::severity::INFO) {
+ return "info";
+ } else if(severity == Logger::severity::DEBUG) {
+ return "debug";
+ }
+ throw Exception(AVG_ERR_UNKNOWN, "Unkown log severity");
+}
+
+void PythonLogSink::logMessage(const tm* pTime, unsigned millis,
+ const category_t& category, severity_t severity, const UTF8String& sMsg)
+{
+ try {
+ aquirePyGIL aquireGil;
+ PyObject * extra = PyDict_New();
+ PyObject * pyCat = PyString_FromString(category.c_str());
+
+ PyDict_SetItemString(extra, "category", pyCat);
+
+ PyObject * pyMsg = PyString_FromString(sMsg.c_str());
+ PyObject * args = PyTuple_New(1);
+ PyObject * kwargs = PyDict_New();
+ PyDict_SetItemString(kwargs, "extra", extra);
+ PyTuple_SetItem(args, 0, pyMsg);
+
+ PyObject_Call(PyObject_GetAttrString(m_pyLogger,
+ LogSeverityToPythonString(severity)), args, kwargs);
+
+ Py_DECREF(extra);
+ Py_DECREF(pyCat);
+ Py_DECREF(args);
+ Py_DECREF(kwargs);
+ } catch (const boost::python::error_already_set &) {
+ std::cerr << "PythonLogSink: Python raised exception\n";
+ } catch (const exception &) {
+ std::cerr << "PythonLogSink: Couldn't log to python logger.\n";
+ }
+}
+
+}
diff --git a/src/player/PythonLogSink.h b/src/player/PythonLogSink.h
new file mode 100644
index 0000000..045eb4e
--- /dev/null
+++ b/src/player/PythonLogSink.h
@@ -0,0 +1,46 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+
+#ifndef _PYTHONLOGHANDLER_H_
+#define _PYTHONLOGHANDLER_H_
+
+#include "../base/ILogSink.h"
+#include "../player/WrapPython.h"
+
+namespace avg
+{
+class PythonLogSink: public ILogSink
+{
+public:
+ PythonLogSink(PyObject *pyLogger);
+ virtual ~PythonLogSink ();
+
+ virtual void logMessage(const tm* pTime, unsigned millis, const category_t& category,
+ severity_t severity, const UTF8String& sMsg);
+
+private:
+
+ PyObject *m_pyLogger;
+ static const char * LogSeverityToPythonString(severity_t severity);
+};
+
+}
+
+#endif
diff --git a/src/player/RasterNode.cpp b/src/player/RasterNode.cpp
new file mode 100644
index 0000000..b24fe31
--- /dev/null
+++ b/src/player/RasterNode.cpp
@@ -0,0 +1,599 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "RasterNode.h"
+
+#include "TypeDefinition.h"
+#include "OGLSurface.h"
+#include "FXNode.h"
+
+#include "../graphics/ImagingProjection.h"
+#include "../graphics/ShaderRegistry.h"
+#include "../graphics/BitmapLoader.h"
+
+#include "../base/MathHelper.h"
+#include "../base/Logger.h"
+#include "../base/XMLHelper.h"
+#include "../base/Exception.h"
+#include "../base/ScopeTimer.h"
+
+using namespace std;
+
+namespace avg {
+
+void RasterNode::registerType()
+{
+ TypeDefinition def = TypeDefinition("rasternode", "areanode")
+ .addArg(Arg<int>("maxtilewidth", -1, false,
+ offsetof(RasterNode, m_MaxTileSize.x)))
+ .addArg(Arg<int>("maxtileheight", -1, false,
+ offsetof(RasterNode, m_MaxTileSize.y)))
+ .addArg(Arg<string>("blendmode", "blend", false,
+ offsetof(RasterNode, m_sBlendMode)))
+ .addArg(Arg<bool>("mipmap", false))
+ .addArg(Arg<UTF8String>("maskhref", "", false, offsetof(RasterNode, m_sMaskHref)))
+ .addArg(Arg<glm::vec2>("maskpos", glm::vec2(0,0), false,
+ offsetof(RasterNode, m_MaskPos)))
+ .addArg(Arg<glm::vec2>("masksize", glm::vec2(0,0), false,
+ offsetof(RasterNode, m_MaskSize)))
+ .addArg(Arg<glm::vec3>("gamma", glm::vec3(1.0f,1.0f,1.0f), false,
+ offsetof(RasterNode, m_Gamma)))
+ .addArg(Arg<glm::vec3>("contrast", glm::vec3(1.0f,1.0f,1.0f), false,
+ offsetof(RasterNode, m_Contrast)))
+ .addArg(Arg<glm::vec3>("intensity", glm::vec3(1.0f,1.0f,1.0f), false,
+ offsetof(RasterNode, m_Intensity)));
+ TypeRegistry::get()->registerType(def);
+}
+
+RasterNode::RasterNode()
+ : m_pSurface(0),
+ m_Material(GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, false),
+ m_TileSize(-1,-1),
+ m_bFXDirty(true)
+{
+}
+
+RasterNode::~RasterNode()
+{
+ if (m_pSurface) {
+ delete m_pSurface;
+ m_pSurface = 0;
+ }
+}
+
+void RasterNode::setArgs(const ArgList& args)
+{
+ AreaNode::setArgs(args);
+ if ((!ispow2(m_MaxTileSize.x) && m_MaxTileSize.x != -1)
+ || (!ispow2(m_MaxTileSize.y) && m_MaxTileSize.y != -1))
+ {
+ throw Exception(AVG_ERR_OUT_OF_RANGE,
+ "maxtilewidth and maxtileheight must be powers of two.");
+ }
+ bool bMipmap = args.getArgVal<bool>("mipmap");
+ m_Material = MaterialInfo(GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, bMipmap);
+ m_pSurface = new OGLSurface();
+}
+
+void RasterNode::connectDisplay()
+{
+ AreaNode::connectDisplay();
+
+ if (m_MaxTileSize != IntPoint(-1, -1)) {
+ m_TileSize = m_MaxTileSize;
+ }
+ newSurface();
+ setBlendModeStr(m_sBlendMode);
+ if (m_pMaskBmp) {
+ downloadMask();
+ setMaskCoords();
+ }
+ m_pSurface->setColorParams(m_Gamma, m_Intensity, m_Contrast);
+ setupFX(true);
+}
+
+void RasterNode::disconnect(bool bKill)
+{
+ if (m_pSurface) {
+ m_pSurface->destroy();
+ }
+ m_pFBO = FBOPtr();
+ m_pImagingProjection = ImagingProjectionPtr();
+ if (bKill) {
+ m_pFXNode = FXNodePtr();
+ } else {
+ if (m_pFXNode) {
+ m_pFXNode->disconnect();
+ }
+ }
+ AreaNode::disconnect(bKill);
+}
+
+void RasterNode::checkReload()
+{
+ string sLastMaskFilename = m_sMaskFilename;
+ string sMaskFilename = m_sMaskHref;
+ initFilename(sMaskFilename);
+ if (sLastMaskFilename != sMaskFilename) {
+ m_sMaskFilename = sMaskFilename;
+ try {
+ if (m_sMaskFilename != "") {
+ AVG_TRACE(Logger::category::MEMORY, Logger::severity::INFO,
+ "Loading " << m_sMaskFilename);
+ m_pMaskBmp = loadBitmap(m_sMaskFilename, I8);
+ setMaskCoords();
+ }
+ } catch (Exception & ex) {
+ if (ex.getCode() == AVG_ERR_VIDEO_GENERAL) {
+ throw;
+ }
+ m_sMaskFilename = "";
+ logFileNotFoundWarning(ex.getStr());
+ }
+ if (m_sMaskFilename == "") {
+ m_pMaskBmp = BitmapPtr();
+ getSurface()->setMask(GLTexturePtr());
+ }
+ if (getState() == Node::NS_CANRENDER && m_pMaskBmp) {
+ downloadMask();
+ }
+ } else {
+ setMaskCoords();
+ }
+}
+
+VertexGrid RasterNode::getOrigVertexCoords()
+{
+ checkDisplayAvailable("getOrigVertexCoords");
+ VertexGrid grid;
+ calcVertexGrid(grid);
+ return grid;
+}
+
+VertexGrid RasterNode::getWarpedVertexCoords()
+{
+ checkDisplayAvailable("getWarpedVertexCoords");
+ return m_TileVertices;
+}
+
+void RasterNode::setWarpedVertexCoords(const VertexGrid& grid)
+{
+ checkDisplayAvailable("setWarpedVertexCoords");
+ bool bGridOK = true;
+ IntPoint numTiles = getNumTiles();
+ if (grid.size() != (unsigned)(numTiles.y+1)) {
+ bGridOK = false;
+ }
+ for (unsigned i = 0; i < grid.size(); ++i) {
+ if (grid[i].size() != (unsigned)(numTiles.x+1)) {
+ bGridOK = false;
+ }
+ }
+ if (!bGridOK) {
+ throw Exception(AVG_ERR_OUT_OF_RANGE,
+ "setWarpedVertexCoords() called with incorrect grid size.");
+ }
+ m_TileVertices = grid;
+}
+
+int RasterNode::getMaxTileWidth() const
+{
+ return m_MaxTileSize.x;
+}
+
+int RasterNode::getMaxTileHeight() const
+{
+ return m_MaxTileSize.y;
+}
+
+bool RasterNode::getMipmap() const
+{
+ return m_Material.getUseMipmaps();
+}
+
+const std::string& RasterNode::getBlendModeStr() const
+{
+ return m_sBlendMode;
+}
+
+void RasterNode::setBlendModeStr(const string& sBlendMode)
+{
+ GLContext::BlendMode blendMode = GLContext::stringToBlendMode(sBlendMode);
+ if (!GLContext::getMain()->isBlendModeSupported(blendMode)) {
+ m_sBlendMode = "blend";
+ m_BlendMode = GLContext::BLEND_BLEND;
+ throw Exception(AVG_ERR_UNSUPPORTED,
+ "Min and max blend modes are not supported in this OpenGL configuration.");
+ }
+ m_sBlendMode = sBlendMode;
+ m_BlendMode = blendMode;
+}
+
+const UTF8String& RasterNode::getMaskHRef() const
+{
+ return m_sMaskHref;
+}
+
+void RasterNode::setMaskHRef(const UTF8String& sHref)
+{
+ m_sMaskHref = sHref;
+ checkReload();
+}
+
+const glm::vec2& RasterNode::getMaskPos() const
+{
+ return m_MaskPos;
+}
+
+void RasterNode::setMaskPos(const glm::vec2& pos)
+{
+ m_MaskPos = pos;
+ setMaskCoords();
+}
+
+const glm::vec2& RasterNode::getMaskSize() const
+{
+ return m_MaskSize;
+}
+
+void RasterNode::setMaskSize(const glm::vec2& size)
+{
+ m_MaskSize = size;
+ setMaskCoords();
+}
+
+void RasterNode::getElementsByPos(const glm::vec2& pos, vector<NodePtr>& pElements)
+{
+ // Node isn't pickable if it's warped.
+ if (m_MaxTileSize == IntPoint(-1, -1)) {
+ AreaNode::getElementsByPos(pos, pElements);
+ }
+}
+
+glm::vec3 RasterNode::getGamma() const
+{
+ return m_Gamma;
+}
+
+void RasterNode::setGamma(const glm::vec3& gamma)
+{
+ m_Gamma = gamma;
+ if (getState() == Node::NS_CANRENDER) {
+ m_pSurface->setColorParams(m_Gamma, m_Intensity, m_Contrast);
+ }
+}
+
+glm::vec3 RasterNode::getIntensity() const
+{
+ return m_Intensity;
+}
+
+void RasterNode::setIntensity(const glm::vec3& intensity)
+{
+ m_Intensity = intensity;
+ if (getState() == Node::NS_CANRENDER) {
+ m_pSurface->setColorParams(m_Gamma, m_Intensity, m_Contrast);
+ }
+}
+
+glm::vec3 RasterNode::getContrast() const
+{
+ return m_Contrast;
+}
+
+void RasterNode::setContrast(const glm::vec3& contrast)
+{
+ m_Contrast = contrast;
+ if (getState() == Node::NS_CANRENDER) {
+ m_pSurface->setColorParams(m_Gamma, m_Intensity, m_Contrast);
+ }
+}
+
+void RasterNode::setEffect(FXNodePtr pFXNode)
+{
+ if (m_pFXNode && m_pFXNode != pFXNode) {
+ m_pFXNode->disconnect();
+ }
+ if (m_pFXNode && !pFXNode) {
+ m_pFBO = FBOPtr();
+ }
+ m_pFXNode = pFXNode;
+ if (getState() == NS_CANRENDER) {
+ setupFX(true);
+ }
+}
+
+void RasterNode::calcVertexArray(const VertexArrayPtr& pVA, const Pixel32& color)
+{
+ if (isVisible() && m_pSurface->isCreated()) {
+ pVA->startSubVA(m_SubVA);
+ for (unsigned y = 0; y < m_TileVertices.size()-1; y++) {
+ for (unsigned x = 0; x < m_TileVertices[0].size()-1; x++) {
+ int curVertex = m_SubVA.getNumVerts();
+ m_SubVA.appendPos(m_TileVertices[y][x], m_TexCoords[y][x], color);
+ m_SubVA.appendPos(m_TileVertices[y][x+1], m_TexCoords[y][x+1], color);
+ m_SubVA.appendPos(m_TileVertices[y+1][x+1], m_TexCoords[y+1][x+1], color);
+ m_SubVA.appendPos(m_TileVertices[y+1][x], m_TexCoords[y+1][x], color);
+ m_SubVA.appendQuadIndexes(
+ curVertex+1, curVertex, curVertex+2, curVertex+3);
+ }
+ }
+ }
+}
+
+void RasterNode::blt32(const glm::mat4& transform, const glm::vec2& destSize,
+ float opacity, GLContext::BlendMode mode, bool bPremultipliedAlpha)
+{
+ blt(transform, destSize, mode, opacity, Pixel32(255, 255, 255, 255),
+ bPremultipliedAlpha);
+}
+
+void RasterNode::blta8(const glm::mat4& transform, const glm::vec2& destSize,
+ float opacity, const Pixel32& color, GLContext::BlendMode mode)
+{
+ blt(transform, destSize, mode, opacity, color, false);
+}
+
+GLContext::BlendMode RasterNode::getBlendMode() const
+{
+ return m_BlendMode;
+}
+
+OGLSurface * RasterNode::getSurface()
+{
+ return m_pSurface;
+}
+
+const MaterialInfo& RasterNode::getMaterial() const
+{
+ return m_Material;
+}
+
+bool RasterNode::hasMask() const
+{
+ return m_sMaskFilename != "";
+}
+
+void RasterNode::setMaskCoords()
+{
+ if (m_sMaskFilename != "") {
+ calcMaskCoords();
+ }
+}
+
+void RasterNode::calcMaskCoords()
+{
+ glm::vec2 maskSize;
+ glm::vec2 mediaSize = glm::vec2(getMediaSize());
+ if (m_MaskSize == glm::vec2(0,0)) {
+ maskSize = glm::vec2(1,1);
+ } else {
+ maskSize = glm::vec2(m_MaskSize.x/mediaSize.x, m_MaskSize.y/mediaSize.y);
+ }
+ glm::vec2 maskPos = glm::vec2(m_MaskPos.x/mediaSize.x, m_MaskPos.y/mediaSize.y);
+ m_pSurface->setMaskCoords(maskPos, maskSize);
+}
+
+void RasterNode::downloadMask()
+{
+ GLTexturePtr pTex(new GLTexture(m_pMaskBmp->getSize(), I8,
+ m_Material.getUseMipmaps()));
+ pTex->moveBmpToTexture(m_pMaskBmp);
+ m_pSurface->setMask(pTex);
+}
+
+static ProfilingZoneID FXProfilingZone("RasterNode::renderFX");
+
+void RasterNode::renderFX(const glm::vec2& destSize, const Pixel32& color,
+ bool bPremultipliedAlpha, bool bForceRender)
+{
+ setupFX(false);
+ if (m_pFXNode && (m_bFXDirty || m_pSurface->isDirty() || m_pFXNode->isDirty() ||
+ bForceRender))
+ {
+ ScopeTimer Timer(FXProfilingZone);
+ GLContext* pContext = GLContext::getMain();
+ StandardShader::get()->setAlpha(1.0f);
+ m_pSurface->activate(getMediaSize());
+
+ m_pFBO->activate();
+ clearGLBuffers(GL_COLOR_BUFFER_BIT, false);
+
+ if (bPremultipliedAlpha) {
+ glproc::BlendColor(1.0f, 1.0f, 1.0f, 1.0f);
+ }
+ pContext->setBlendMode(GLContext::BLEND_BLEND, bPremultipliedAlpha);
+ m_pImagingProjection->setColor(color);
+ m_pImagingProjection->draw(StandardShader::get()->getShader());
+
+/*
+ static int i=0;
+ stringstream ss;
+ ss << "node" << i << ".png";
+ BitmapPtr pBmp = m_pFBO->getImage(0);
+ pBmp->save(ss.str());
+*/
+ m_pFXNode->apply(m_pFBO->getTex());
+
+/*
+ stringstream ss1;
+ ss1 << "nodefx" << i << ".png";
+ i++;
+ m_pFXNode->getImage()->save(ss1.str());
+*/
+ m_bFXDirty = false;
+ m_pSurface->resetDirty();
+ m_pFXNode->resetDirty();
+ }
+}
+
+void RasterNode::checkDisplayAvailable(std::string sMsg)
+{
+ if (!(getState() == Node::NS_CANRENDER)) {
+ throw Exception(AVG_ERR_UNSUPPORTED,
+ string(sMsg) + ": cannot access vertex coordinates before node is bound.");
+ }
+ if (!m_pSurface->isCreated()) {
+ throw Exception(AVG_ERR_UNSUPPORTED,
+ string(sMsg) + ": Surface not available.");
+ }
+}
+
+void RasterNode::newSurface()
+{
+ if (m_pSurface->isCreated()) {
+ calcVertexGrid(m_TileVertices);
+ calcTexCoords();
+ }
+}
+
+void RasterNode::setupFX(bool bNewFX)
+{
+ if (m_pSurface && m_pSurface->getSize() != IntPoint(-1, -1) && m_pFXNode) {
+ if (bNewFX || !m_pFBO || m_pFBO->getSize() != m_pSurface->getSize()) {
+ m_pFXNode->setSize(m_pSurface->getSize());
+ m_pFXNode->connect();
+ m_bFXDirty = true;
+ }
+ if (!m_pFBO || m_pFBO->getSize() != m_pSurface->getSize()) {
+ PixelFormat pf = BitmapLoader::get()->getDefaultPixelFormat(true);
+ m_pFBO = FBOPtr(new FBO(IntPoint(m_pSurface->getSize()), pf, 1, 1, false,
+ getMipmap()));
+ GLTexturePtr pTex = m_pFBO->getTex();
+ #ifndef AVG_ENABLE_EGL
+ pTex->setWrapMode(GL_CLAMP_TO_BORDER, GL_CLAMP_TO_BORDER);
+ #endif
+ m_pImagingProjection = ImagingProjectionPtr(new ImagingProjection(
+ m_pSurface->getSize()));
+ }
+ }
+}
+
+void RasterNode::blt(const glm::mat4& transform, const glm::vec2& destSize,
+ GLContext::BlendMode mode, float opacity, const Pixel32& color,
+ bool bPremultipliedAlpha)
+{
+ GLContext* pContext = GLContext::getMain();
+ FRect destRect;
+
+ StandardShaderPtr pShader = pContext->getStandardShader();
+ pContext->setBlendColor(glm::vec4(1.0f, 1.0f, 1.0f, opacity));
+ pShader->setAlpha(opacity);
+ if (m_pFXNode) {
+ pContext->setBlendMode(mode, true);
+ m_pFXNode->getTex()->activate(GL_TEXTURE0);
+ pShader->setColorModel(0);
+ pShader->disableColorspaceMatrix();
+ pShader->setGamma(glm::vec4(1.0f, 1.0f, 1.0f, 1.0f));
+ pShader->setPremultipliedAlpha(true);
+ pShader->setMask(false);
+
+ FRect relDestRect = m_pFXNode->getRelDestRect();
+ destRect = FRect(relDestRect.tl.x*destSize.x, relDestRect.tl.y*destSize.y,
+ relDestRect.br.x*destSize.x, relDestRect.br.y*destSize.y);
+ } else {
+ m_pSurface->activate(getMediaSize(), bPremultipliedAlpha);
+ pContext->setBlendMode(mode, bPremultipliedAlpha);
+ destRect = FRect(glm::vec2(0,0), destSize);
+ }
+ glm::vec3 pos(destRect.tl.x, destRect.tl.y, 0);
+ glm::vec3 scaleVec(destRect.size().x, destRect.size().y, 1);
+ glm::mat4 localTransform = glm::translate(transform, pos);
+ localTransform = glm::scale(localTransform, scaleVec);
+ pShader->setTransform(localTransform);
+ pShader->activate();
+
+ m_SubVA.draw();
+}
+
+IntPoint RasterNode::getNumTiles()
+{
+ IntPoint size = m_pSurface->getSize();
+ if (m_TileSize.x == -1) {
+ return IntPoint(1,1);
+ } else {
+ return IntPoint(safeCeil(float(size.x)/m_TileSize.x),
+ safeCeil(float(size.y)/m_TileSize.y));
+ }
+}
+
+void RasterNode::calcVertexGrid(VertexGrid& grid)
+{
+ IntPoint numTiles = getNumTiles();
+ std::vector<glm::vec2> TileVerticesLine(numTiles.x+1);
+ grid = std::vector<std::vector<glm::vec2> > (numTiles.y+1, TileVerticesLine);
+ for (unsigned y = 0; y < grid.size(); y++) {
+ for (unsigned x = 0; x < grid[y].size(); x++) {
+ calcTileVertex(x, y, grid[y][x]);
+ }
+ }
+}
+
+void RasterNode::calcTileVertex(int x, int y, glm::vec2& Vertex)
+{
+ IntPoint numTiles = getNumTiles();
+ if (x < numTiles.x) {
+ Vertex.x = float(m_TileSize.x*x) / m_pSurface->getSize().x;
+ } else {
+ Vertex.x = 1;
+ }
+ if (y < numTiles.y) {
+ Vertex.y = float(m_TileSize.y*y) / m_pSurface->getSize().y;
+ } else {
+ Vertex.y = 1;
+ }
+}
+
+void RasterNode::calcTexCoords()
+{
+ glm::vec2 textureSize = glm::vec2(m_pSurface->getTextureSize());
+ glm::vec2 imageSize = glm::vec2(m_pSurface->getSize());
+ glm::vec2 texCoordExtents = glm::vec2(imageSize.x/textureSize.x,
+ imageSize.y/textureSize.y);
+
+ glm::vec2 texSizePerTile;
+ if (m_TileSize.x == -1) {
+ texSizePerTile = texCoordExtents;
+ } else {
+ texSizePerTile = glm::vec2(float(m_TileSize.x)/imageSize.x*texCoordExtents.x,
+ float(m_TileSize.y)/imageSize.y*texCoordExtents.y);
+ }
+
+ IntPoint numTiles = getNumTiles();
+ vector<glm::vec2> texCoordLine(numTiles.x+1);
+ m_TexCoords = std::vector<std::vector<glm::vec2> >
+ (numTiles.y+1, texCoordLine);
+ for (unsigned y = 0; y < m_TexCoords.size(); y++) {
+ for (unsigned x = 0; x < m_TexCoords[y].size(); x++) {
+ if (y == m_TexCoords.size()-1) {
+ m_TexCoords[y][x].y = texCoordExtents.y;
+ } else {
+ m_TexCoords[y][x].y = texSizePerTile.y*y;
+ }
+ if (x == m_TexCoords[y].size()-1) {
+ m_TexCoords[y][x].x = texCoordExtents.x;
+ } else {
+ m_TexCoords[y][x].x = texSizePerTile.x*x;
+ }
+ }
+ }
+}
+}
diff --git a/src/player/RasterNode.h b/src/player/RasterNode.h
new file mode 100644
index 0000000..1e86e17
--- /dev/null
+++ b/src/player/RasterNode.h
@@ -0,0 +1,159 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _RasterNode_H_
+#define _RasterNode_H_
+
+#include "../api.h"
+#include "AreaNode.h"
+#include "MaterialInfo.h"
+
+#include "../avgconfigwrapper.h"
+#include "../base/GLMHelper.h"
+#include "../base/UTF8String.h"
+#include "../graphics/GLContext.h"
+#include "../graphics/SubVertexArray.h"
+
+#include <string>
+
+namespace avg {
+
+class OGLSurface;
+class ImagingProjection;
+typedef boost::shared_ptr<ImagingProjection> ImagingProjectionPtr;
+class FBO;
+typedef boost::shared_ptr<FBO> FBOPtr;
+class GLTexture;
+typedef boost::shared_ptr<GLTexture> GLTexturePtr;
+class FXNode;
+typedef boost::shared_ptr<FXNode> FXNodePtr;
+
+typedef std::vector<std::vector<glm::vec2> > VertexGrid;
+
+class AVG_API RasterNode: public AreaNode
+{
+ public:
+ static void registerType();
+
+ virtual ~RasterNode ();
+ virtual void connectDisplay();
+ virtual void setArgs(const ArgList& args);
+ virtual void disconnect(bool bKill);
+ virtual void checkReload();
+
+ // Warping support.
+ VertexGrid getOrigVertexCoords();
+ VertexGrid getWarpedVertexCoords();
+ void setWarpedVertexCoords(const VertexGrid& Grid);
+
+ int getMaxTileWidth() const;
+ int getMaxTileHeight() const;
+ bool getMipmap() const;
+
+ const std::string& getBlendModeStr() const;
+ void setBlendModeStr(const std::string& sBlendMode);
+ GLContext::BlendMode getBlendMode() const;
+
+ const UTF8String& getMaskHRef() const;
+ void setMaskHRef(const UTF8String& sHref);
+
+ const glm::vec2& getMaskPos() const;
+ void setMaskPos(const glm::vec2& pos);
+
+ const glm::vec2& getMaskSize() const;
+ void setMaskSize(const glm::vec2& size);
+
+ void getElementsByPos(const glm::vec2& pos, std::vector<NodePtr>& pElements);
+
+ glm::vec3 getGamma() const;
+ void setGamma(const glm::vec3& gamma);
+ glm::vec3 getIntensity() const;
+ void setIntensity(const glm::vec3& intensity);
+ glm::vec3 getContrast() const;
+ void setContrast(const glm::vec3& contrast);
+
+ void setEffect(FXNodePtr pFXNode);
+
+ protected:
+ RasterNode();
+
+ void calcVertexArray(const VertexArrayPtr& pVA,
+ const Pixel32& color = Pixel32(0,0,0,0));
+ void blt32(const glm::mat4& transform, const glm::vec2& destSize, float opacity,
+ GLContext::BlendMode mode, bool bPremultipliedAlpha = false);
+ void blta8(const glm::mat4& transform, const glm::vec2& destSize, float opacity,
+ const Pixel32& color, GLContext::BlendMode mode);
+
+ virtual OGLSurface * getSurface();
+ const MaterialInfo& getMaterial() const;
+ bool hasMask() const;
+ void setMaskCoords();
+ void renderFX(const glm::vec2& destSize, const Pixel32& color,
+ bool bPremultipliedAlpha, bool bForceRender=false);
+
+ protected:
+ void newSurface();
+ void setupFX(bool bNewFX);
+
+ private:
+ void downloadMask();
+ virtual void calcMaskCoords();
+ void checkDisplayAvailable(std::string sMsg);
+ void blt(const glm::mat4& transform, const glm::vec2& destSize,
+ GLContext::BlendMode mode, float opacity, const Pixel32& color,
+ bool bPremultipliedAlpha);
+
+ IntPoint getNumTiles();
+ void calcVertexGrid(VertexGrid& grid);
+ void calcTileVertex(int x, int y, glm::vec2& Vertex);
+ void calcTexCoords();
+
+ OGLSurface * m_pSurface;
+
+ IntPoint m_MaxTileSize;
+ std::string m_sBlendMode;
+ GLContext::BlendMode m_BlendMode;
+ MaterialInfo m_Material;
+
+ UTF8String m_sMaskHref;
+ std::string m_sMaskFilename;
+ BitmapPtr m_pMaskBmp;
+ glm::vec2 m_MaskPos;
+ glm::vec2 m_MaskSize;
+
+ IntPoint m_TileSize;
+ VertexGrid m_TileVertices;
+ SubVertexArray m_SubVA;
+ std::vector<std::vector<glm::vec2> > m_TexCoords;
+
+ glm::vec3 m_Gamma;
+ glm::vec3 m_Intensity;
+ glm::vec3 m_Contrast;
+
+ FBOPtr m_pFBO;
+ FXNodePtr m_pFXNode;
+ bool m_bFXDirty;
+ ImagingProjectionPtr m_pImagingProjection;
+};
+
+}
+
+#endif
diff --git a/src/player/RectNode.cpp b/src/player/RectNode.cpp
new file mode 100644
index 0000000..980a957
--- /dev/null
+++ b/src/player/RectNode.cpp
@@ -0,0 +1,178 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "RectNode.h"
+
+#include "TypeDefinition.h"
+
+#include "../graphics/VertexArray.h"
+#include "../base/Exception.h"
+#include "../base/MathHelper.h"
+
+#include <iostream>
+#include <sstream>
+
+using namespace std;
+
+namespace avg {
+
+void RectNode::registerType()
+{
+ float texCoords[] = {0, 0.25f, 0.5f, 0.75f, 1};
+ TypeDefinition def = TypeDefinition("rect", "filledvectornode",
+ ExportedObject::buildObject<RectNode>)
+ .addArg(Arg<glm::vec2>("pos", glm::vec2(0,0), false,
+ offsetof(RectNode, m_Rect.tl)))
+ .addArg(Arg<glm::vec2>("size", glm::vec2(0,0)))
+ .addArg(Arg<float>("angle", 0.0f, false, offsetof(RectNode, m_Angle)))
+ .addArg(Arg<vector<float> >("texcoords", vectorFromCArray(5, texCoords), false,
+ offsetof(RectNode, m_TexCoords)))
+ ;
+ TypeRegistry::get()->registerType(def);
+}
+
+RectNode::RectNode(const ArgList& args)
+ : FilledVectorNode(args)
+{
+ args.setMembers(this);
+ setSize(args.getArgVal<glm::vec2>("size"));
+}
+
+RectNode::~RectNode()
+{
+}
+
+const glm::vec2& RectNode::getPos() const
+{
+ return m_Rect.tl;
+}
+
+void RectNode::setPos(const glm::vec2& pt)
+{
+ float w = m_Rect.width();
+ float h = m_Rect.height();
+ m_Rect.tl = pt;
+ m_Rect.setWidth(w);
+ m_Rect.setHeight(h);
+ setDrawNeeded();
+}
+
+glm::vec2 RectNode::getSize() const
+{
+ return m_Rect.size();
+}
+
+void RectNode::setSize(const glm::vec2& pt)
+{
+ m_Rect.setWidth(pt.x);
+ m_Rect.setHeight(pt.y);
+ notifySubscribers("SIZE_CHANGED", m_Rect.size());
+ setDrawNeeded();
+}
+
+const vector<float>& RectNode::getTexCoords() const
+{
+ return m_TexCoords;
+}
+
+void RectNode::setTexCoords(const vector<float>& coords)
+{
+ if (coords.size() != 5) {
+ throw(Exception(AVG_ERR_OUT_OF_RANGE,
+ "Number of texture coordinates for a rectangle must be 5."));
+ }
+ m_TexCoords = coords;
+ setDrawNeeded();
+}
+
+float RectNode::getAngle() const
+{
+ return m_Angle;
+}
+
+void RectNode::setAngle(float angle)
+{
+ m_Angle = fmod(angle, 2*PI);
+ setDrawNeeded();
+}
+
+glm::vec2 RectNode::toLocal(const glm::vec2& globalPos) const
+{
+ glm::vec2 localPos = globalPos - m_Rect.tl;
+ glm::vec2 pivot = m_Rect.size()/2.f;
+ return getRotatedPivot(localPos, -m_Angle, pivot);
+}
+
+glm::vec2 RectNode::toGlobal(const glm::vec2& localPos) const
+{
+ glm::vec2 pivot = m_Rect.tl + m_Rect.size()/2.f;
+ glm::vec2 globalPos = getRotatedPivot(localPos, m_Angle, pivot);
+ return globalPos + m_Rect.tl;
+}
+
+void RectNode::getElementsByPos(const glm::vec2& pos, vector<NodePtr>& pElements)
+{
+ if (pos.x >= 0 && pos.y >= 0 && pos.x < m_Rect.size().x && pos.y < m_Rect.size().y
+ && reactsToMouseEvents())
+ {
+ pElements.push_back(getSharedThis());
+ }
+}
+
+void RectNode::calcVertexes(const VertexDataPtr& pVertexData, Pixel32 color)
+{
+ glm::vec2 pivot = m_Rect.tl+m_Rect.size()/2.f;
+
+ glm::vec2 p1 = m_Rect.tl;
+ glm::vec2 p2(m_Rect.tl.x, m_Rect.br.y);
+ glm::vec2 p3 = m_Rect.br;
+ glm::vec2 p4(m_Rect.br.x, m_Rect.tl.y);
+
+ vector<glm::vec2> pts;
+ pts.push_back(getRotatedPivot(p1, m_Angle, pivot));
+ pts.push_back(getRotatedPivot(p2, m_Angle, pivot));
+ pts.push_back(getRotatedPivot(p3, m_Angle, pivot));
+ pts.push_back(getRotatedPivot(p4, m_Angle, pivot));
+ calcPolyLine(pts, m_TexCoords, true, LJ_MITER, pVertexData, color);
+}
+
+void RectNode::calcFillVertexes(const VertexDataPtr& pVertexData, Pixel32 color)
+{
+ glm::vec2 pivot = m_Rect.tl+m_Rect.size()/2.f;
+
+ glm::vec2 p1 = m_Rect.tl;
+ glm::vec2 p2(m_Rect.tl.x, m_Rect.br.y);
+ glm::vec2 p3 = m_Rect.br;
+ glm::vec2 p4(m_Rect.br.x, m_Rect.tl.y);
+ glm::vec2 rp1 = getRotatedPivot(p1, m_Angle, pivot);
+ glm::vec2 rp2 = getRotatedPivot(p2, m_Angle, pivot);
+ glm::vec2 rp3 = getRotatedPivot(p3, m_Angle, pivot);
+ glm::vec2 rp4 = getRotatedPivot(p4, m_Angle, pivot);
+ pVertexData->appendPos(rp1, getFillTexCoord1(), color);
+ glm::vec2 blTexCoord = glm::vec2(getFillTexCoord1().x, getFillTexCoord2().y);
+ pVertexData->appendPos(rp2, blTexCoord, color);
+ pVertexData->appendPos(rp3, getFillTexCoord2(), color);
+ glm::vec2 trTexCoord = glm::vec2(getFillTexCoord2().x, getFillTexCoord1().y);
+ pVertexData->appendPos(rp4, trTexCoord, color);
+ pVertexData->appendQuadIndexes(1, 0, 2, 3);
+}
+
+}
diff --git a/src/player/RectNode.h b/src/player/RectNode.h
new file mode 100644
index 0000000..f1a3c4e
--- /dev/null
+++ b/src/player/RectNode.h
@@ -0,0 +1,69 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _RectNode_H_
+#define _RectNode_H_
+
+#include "../api.h"
+#include "FilledVectorNode.h"
+
+#include "../graphics/Pixel32.h"
+
+namespace avg {
+
+class AVG_API RectNode : public FilledVectorNode
+{
+ public:
+ static void registerType();
+
+ RectNode(const ArgList& args);
+ virtual ~RectNode();
+
+ const glm::vec2& getPos() const;
+ void setPos(const glm::vec2& pt);
+
+ glm::vec2 getSize() const;
+ void setSize(const glm::vec2& pt);
+
+ const std::vector<float>& getTexCoords() const;
+ void setTexCoords(const std::vector<float>& coords);
+
+ float getAngle() const;
+ void setAngle(float angle);
+
+ glm::vec2 toLocal(const glm::vec2& globalPos) const;
+ glm::vec2 toGlobal(const glm::vec2& localPos) const;
+ void getElementsByPos(const glm::vec2& pos, std::vector<NodePtr>& pElements);
+
+ virtual void calcVertexes(const VertexDataPtr& pVertexData, Pixel32 color);
+ virtual void calcFillVertexes(const VertexDataPtr& pVertexData, Pixel32 color);
+
+ private:
+ FRect m_Rect;
+ std::vector<float> m_TexCoords;
+
+ float m_Angle;
+};
+
+}
+
+#endif
+
diff --git a/src/player/SDLDisplayEngine.cpp b/src/player/SDLDisplayEngine.cpp
new file mode 100644
index 0000000..74a3698
--- /dev/null
+++ b/src/player/SDLDisplayEngine.cpp
@@ -0,0 +1,865 @@
+
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+
+#include "SDLDisplayEngine.h"
+#include "../avgconfigwrapper.h"
+
+#ifdef __APPLE__
+#include "SDLMain.h"
+#endif
+
+#include "Shape.h"
+
+#include "Event.h"
+#include "MouseEvent.h"
+#include "KeyEvent.h"
+#if defined(HAVE_XI2_1) || defined(HAVE_XI2_2)
+#include "XInputMTInputDevice.h"
+#endif
+#include "../base/MathHelper.h"
+#include "../base/Exception.h"
+#include "../base/Logger.h"
+#include "../base/ScopeTimer.h"
+#include "../base/OSHelper.h"
+#include "../base/StringHelper.h"
+
+#include "../graphics/GLContext.h"
+#include "../graphics/Filterflip.h"
+#include "../graphics/Filterfliprgb.h"
+#include "../graphics/Display.h"
+
+#include "../video/VideoDecoder.h"
+
+#include "OGLSurface.h"
+#include "OffscreenCanvas.h"
+
+#ifdef __APPLE__
+#include <ApplicationServices/ApplicationServices.h>
+#endif
+
+#include <SDL/SDL.h>
+#include <SDL/SDL_syswm.h>
+
+#ifdef __APPLE__
+#include <OpenGL/OpenGL.h>
+#endif
+
+#ifdef linux
+#include <sys/ioctl.h>
+#include <sys/fcntl.h>
+#endif
+#ifdef AVG_ENABLE_XINERAMA
+#include <X11/extensions/Xinerama.h>
+#endif
+
+#include <signal.h>
+#include <iostream>
+#include <sstream>
+#include <math.h>
+
+#ifdef _WIN32
+#include <windows.h>
+#else
+#include <unistd.h>
+#endif
+
+using namespace std;
+
+namespace avg {
+
+void SDLDisplayEngine::initSDL()
+{
+#ifdef __APPLE__
+ static bool bSDLInitialized = false;
+ if (!bSDLInitialized) {
+ CustomSDLMain();
+ bSDLInitialized = true;
+ }
+#endif
+#ifdef linux
+ // Disable all other video drivers (DirectFB, libcaca, ...) to avoid confusing
+ // error messages.
+ SDL_putenv((char*)"SDL_VIDEODRIVER=x11");
+#endif
+ int err = SDL_InitSubSystem(SDL_INIT_VIDEO);
+ if (err == -1) {
+ throw Exception(AVG_ERR_VIDEO_INIT_FAILED, SDL_GetError());
+ }
+}
+
+void SDLDisplayEngine::quitSDL()
+{
+#ifndef _WIN32
+ SDL_QuitSubSystem(SDL_INIT_VIDEO);
+#endif
+}
+
+SDLDisplayEngine::SDLDisplayEngine()
+ : IInputDevice(EXTRACT_INPUTDEVICE_CLASSNAME(SDLDisplayEngine)),
+ m_WindowSize(0,0),
+ m_pScreen(0),
+ m_pLastMouseEvent(new MouseEvent(Event::CURSOR_MOTION, false, false, false,
+ IntPoint(-1, -1), MouseEvent::NO_BUTTON, glm::vec2(-1, -1), 0)),
+ m_pGLContext(0)
+{
+ initSDL();
+
+ m_Gamma[0] = 1.0;
+ m_Gamma[1] = 1.0;
+ m_Gamma[2] = 1.0;
+ initTranslationTable();
+}
+
+SDLDisplayEngine::~SDLDisplayEngine()
+{
+}
+
+void SDLDisplayEngine::init(const DisplayParams& dp, GLConfig glConfig)
+{
+ // This "fixes" the default behaviour of SDL under x11, avoiding it
+ // to report relative mouse coordinates when going fullscreen and
+ // the mouse cursor is hidden (grabbed). So far libavg and apps based
+ // on it don't use relative coordinates.
+ setEnv("SDL_MOUSE_RELATIVE", "0");
+
+ if (m_Gamma[0] != 1.0f || m_Gamma[1] != 1.0f || m_Gamma[2] != 1.0f) {
+ internalSetGamma(1.0f, 1.0f, 1.0f);
+ }
+ stringstream ss;
+ if (dp.m_Pos.x != -1) {
+ ss << dp.m_Pos.x << "," << dp.m_Pos.y;
+ setEnv("SDL_VIDEO_WINDOW_POS", ss.str().c_str());
+ }
+ m_WindowSize = dp.m_WindowSize;
+ unsigned int Flags = 0;
+ if (dp.m_bFullscreen) {
+ Flags |= SDL_FULLSCREEN;
+ }
+ m_bIsFullscreen = dp.m_bFullscreen;
+
+ if (!dp.m_bHasWindowFrame) {
+ Flags |= SDL_NOFRAME;
+ }
+
+#ifndef linux
+ if (glConfig.m_bUseDebugContext) {
+ glConfig.m_bUseDebugContext = false;
+ }
+ switch (dp.m_BPP) {
+ case 24:
+ SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, 24);
+ break;
+ case 16:
+ SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
+ SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 6);
+ SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);
+ SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, 16);
+ break;
+ default:
+ AVG_LOG_ERROR("Unsupported bpp " << dp.m_BPP <<
+ "in SDLDisplayEngine::init()");
+ exit(-1);
+ }
+ SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 0);
+ SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
+ SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL , 0);
+ Flags |= SDL_OPENGL;
+
+ m_pScreen = 0;
+ while (glConfig.m_MultiSampleSamples && !m_pScreen) {
+ if (glConfig.m_MultiSampleSamples > 1) {
+ SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
+ SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES,
+ glConfig.m_MultiSampleSamples);
+ } else {
+ SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0);
+ SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 0);
+ }
+ m_pScreen = SDL_SetVideoMode(m_WindowSize.x, m_WindowSize.y, dp.m_BPP, Flags);
+ if (!m_pScreen) {
+ glConfig.m_MultiSampleSamples = GLContext::nextMultiSampleValue(
+ glConfig.m_MultiSampleSamples);
+ }
+ }
+#else
+ // Linux version: Context created manually, not by SDL
+ m_pScreen = SDL_SetVideoMode(m_WindowSize.x, m_WindowSize.y, dp.m_BPP, Flags);
+#endif
+ if (!m_pScreen) {
+ throw Exception(AVG_ERR_UNSUPPORTED, string("Setting SDL video mode failed: ")
+ + SDL_GetError() + ". (size=" + toString(m_WindowSize) + ", bpp=" +
+ toString(dp.m_BPP) + ").");
+ }
+ SDL_SysWMinfo info;
+ SDL_VERSION(&info.version);
+ int rc = SDL_GetWMInfo(&info);
+ AVG_ASSERT(rc != -1);
+ m_pGLContext = GLContext::create(glConfig, m_WindowSize, &info);
+ GLContext::setMain(m_pGLContext);
+
+#if defined(HAVE_XI2_1) || defined(HAVE_XI2_2)
+ SDL_EventState(SDL_SYSWMEVENT, SDL_ENABLE);
+ m_pXIMTInputDevice = 0;
+#endif
+ SDL_WM_SetCaption("libavg", 0);
+ Display::get()->getRefreshRate();
+
+ setGamma(dp.m_Gamma[0], dp.m_Gamma[1], dp.m_Gamma[2]);
+ showCursor(dp.m_bShowCursor);
+ if (dp.m_Framerate == 0) {
+ setVBlankRate(dp.m_VBRate);
+ } else {
+ setFramerate(dp.m_Framerate);
+ }
+
+ m_Size = dp.m_Size;
+ // SDL sets up a signal handler we really don't want.
+ signal(SIGSEGV, SIG_DFL);
+ m_pGLContext->logConfig();
+ VideoDecoder::logConfig();
+
+ SDL_EnableUNICODE(1);
+}
+
+IntPoint SDLDisplayEngine::calcWindowSize(const DisplayParams& dp) const
+{
+ float aspectRatio = float(dp.m_Size.x)/float(dp.m_Size.y);
+ IntPoint windowSize;
+ if (dp.m_WindowSize == IntPoint(0, 0)) {
+ windowSize = dp.m_Size;
+ } else if (dp.m_WindowSize.x == 0) {
+ windowSize.x = int(dp.m_WindowSize.y*aspectRatio);
+ windowSize.y = dp.m_WindowSize.y;
+ } else {
+ windowSize.x = dp.m_WindowSize.x;
+ windowSize.y = int(dp.m_WindowSize.x/aspectRatio);
+ }
+ AVG_ASSERT(windowSize.x != 0 && windowSize.y != 0);
+ return windowSize;
+}
+
+void SDLDisplayEngine::setWindowTitle(const string& sTitle)
+{
+ SDL_WM_SetCaption(sTitle.c_str(), 0);
+}
+
+#ifdef _WIN32
+#pragma warning(disable: 4996)
+#endif
+void SDLDisplayEngine::teardown()
+{
+ if (m_pScreen) {
+#ifdef linux
+ // Workaround for broken mouse cursor on exit under Ubuntu 8.04.
+ SDL_ShowCursor(SDL_ENABLE);
+#endif
+ m_pScreen = 0;
+ if (m_pGLContext) {
+ delete m_pGLContext;
+ m_pGLContext = 0;
+ }
+ GLContext::setMain(0);
+ }
+}
+
+void SDLDisplayEngine::setGamma(float red, float green, float blue)
+{
+ if (red > 0) {
+ bool bOk = internalSetGamma(red, green, blue);
+ m_Gamma[0] = red;
+ m_Gamma[1] = green;
+ m_Gamma[2] = blue;
+ if (!bOk) {
+ AVG_LOG_WARNING("Unable to set display gamma.");
+ }
+ }
+}
+
+void SDLDisplayEngine::setMousePos(const IntPoint& pos)
+{
+ SDL_WarpMouse(pos.x, pos.y);
+}
+
+int SDLDisplayEngine::getKeyModifierState() const
+{
+ return SDL_GetModState();
+}
+
+bool SDLDisplayEngine::internalSetGamma(float red, float green, float blue)
+{
+#ifdef __APPLE__
+ // Workaround for broken SDL_SetGamma for libSDL 1.2.15 under Lion
+ CGError err = CGSetDisplayTransferByFormula(kCGDirectMainDisplay, 0, 1, 1/red,
+ 0, 1, 1/green, 0, 1, 1/blue);
+ return (err == CGDisplayNoErr);
+#else
+ int err = SDL_SetGamma(float(red), float(green), float(blue));
+ return (err != -1);
+#endif
+}
+
+static ProfilingZoneID SwapBufferProfilingZone("Render - swap buffers");
+
+void SDLDisplayEngine::swapBuffers()
+{
+ ScopeTimer timer(SwapBufferProfilingZone);
+#ifdef linux
+ m_pGLContext->swapBuffers();
+#else
+ SDL_GL_SwapBuffers();
+#endif
+ GLContext::checkError("swapBuffers()");
+}
+
+void SDLDisplayEngine::showCursor(bool bShow)
+{
+#ifdef _WIN32
+#define MAX_CORE_POINTERS 6
+ // Hack to fix a pointer issue with fullscreen, SDL and touchscreens
+ // Refer to Mantis bug #140
+ for (int i = 0; i < MAX_CORE_POINTERS; ++i) {
+ ShowCursor(bShow);
+ }
+#else
+ if (bShow) {
+ SDL_ShowCursor(SDL_ENABLE);
+ } else {
+ SDL_ShowCursor(SDL_DISABLE);
+ }
+#endif
+}
+
+BitmapPtr SDLDisplayEngine::screenshot(int buffer)
+{
+ BitmapPtr pBmp;
+ glproc::BindFramebuffer(GL_FRAMEBUFFER, 0);
+ if (m_pGLContext->isGLES()) {
+ pBmp = BitmapPtr(new Bitmap(m_WindowSize, R8G8B8X8, "screenshot"));
+ glReadPixels(0, 0, m_WindowSize.x, m_WindowSize.y, GL_RGBA, GL_UNSIGNED_BYTE,
+ pBmp->getPixels());
+ GLContext::checkError("SDLDisplayEngine::screenshot:glReadPixels()");
+ } else {
+#ifndef AVG_ENABLE_EGL
+ pBmp = BitmapPtr(new Bitmap(m_WindowSize, B8G8R8X8, "screenshot"));
+ string sTmp;
+ bool bBroken = getEnv("AVG_BROKEN_READBUFFER", sTmp);
+ GLenum buf = buffer;
+ if (!buffer) {
+ if (bBroken) {
+ // Workaround for buggy GL_FRONT on some machines.
+ buf = GL_BACK;
+ } else {
+ buf = GL_FRONT;
+ }
+ }
+ glReadBuffer(buf);
+ GLContext::checkError("SDLDisplayEngine::screenshot:glReadBuffer()");
+ glproc::BindBuffer(GL_PIXEL_PACK_BUFFER, 0);
+ glReadPixels(0, 0, m_WindowSize.x, m_WindowSize.y, GL_BGRA, GL_UNSIGNED_BYTE,
+ pBmp->getPixels());
+ GLContext::checkError("SDLDisplayEngine::screenshot:glReadPixels()");
+#endif
+ }
+ FilterFlip().applyInPlace(pBmp);
+ return pBmp;
+}
+
+IntPoint SDLDisplayEngine::getSize()
+{
+ return m_Size;
+}
+
+vector<long> SDLDisplayEngine::KeyCodeTranslationTable(SDLK_LAST, key::KEY_UNKNOWN);
+
+const char * getEventTypeName(unsigned char type)
+{
+ switch (type) {
+ case SDL_ACTIVEEVENT:
+ return "SDL_ACTIVEEVENT";
+ case SDL_KEYDOWN:
+ return "SDL_KEYDOWN";
+ case SDL_KEYUP:
+ return "SDL_KEYUP";
+ case SDL_MOUSEMOTION:
+ return "SDL_MOUSEMOTION";
+ case SDL_MOUSEBUTTONDOWN:
+ return "SDL_MOUSEBUTTONDOWN";
+ case SDL_MOUSEBUTTONUP:
+ return "SDL_MOUSEBUTTONUP";
+ case SDL_JOYAXISMOTION:
+ return "SDL_JOYAXISMOTION";
+ case SDL_JOYBUTTONDOWN:
+ return "SDL_JOYBUTTONDOWN";
+ case SDL_JOYBUTTONUP:
+ return "SDL_JOYBUTTONUP";
+ case SDL_VIDEORESIZE:
+ return "SDL_VIDEORESIZE";
+ case SDL_VIDEOEXPOSE:
+ return "SDL_VIDEOEXPOSE";
+ case SDL_QUIT:
+ return "SDL_QUIT";
+ case SDL_USEREVENT:
+ return "SDL_USEREVENT";
+ case SDL_SYSWMEVENT:
+ return "SDL_SYSWMEVENT";
+ default:
+ return "Unknown SDL event type";
+ }
+}
+
+vector<EventPtr> SDLDisplayEngine::pollEvents()
+{
+ SDL_Event sdlEvent;
+ vector<EventPtr> events;
+
+ int numEvents = 0;
+ while (SDL_PollEvent(&sdlEvent)) {
+ numEvents++;
+ EventPtr pNewEvent;
+ switch (sdlEvent.type) {
+ case SDL_MOUSEMOTION:
+ {
+ pNewEvent = createMouseEvent(Event::CURSOR_MOTION, sdlEvent,
+ MouseEvent::NO_BUTTON);
+ CursorEventPtr pNewCursorEvent =
+ boost::dynamic_pointer_cast<CursorEvent>(pNewEvent);
+ if (!events.empty()) {
+ CursorEventPtr pLastEvent =
+ boost::dynamic_pointer_cast<CursorEvent>(events.back());
+ if (pLastEvent && *pNewCursorEvent == *pLastEvent) {
+ pNewEvent = EventPtr();
+ }
+ }
+ }
+ break;
+ case SDL_MOUSEBUTTONDOWN:
+ pNewEvent = createMouseButtonEvent(Event::CURSOR_DOWN, sdlEvent);
+ break;
+ case SDL_MOUSEBUTTONUP:
+ pNewEvent = createMouseButtonEvent(Event::CURSOR_UP, sdlEvent);
+ break;
+ case SDL_JOYAXISMOTION:
+// pNewEvent = createAxisEvent(sdlEvent));
+ break;
+ case SDL_JOYBUTTONDOWN:
+// pNewEvent = createButtonEvent(Event::BUTTON_DOWN, sdlEvent));
+ break;
+ case SDL_JOYBUTTONUP:
+// pNewEvent = createButtonEvent(Event::BUTTON_UP, sdlEvent));
+ break;
+ case SDL_KEYDOWN:
+ pNewEvent = createKeyEvent(Event::KEY_DOWN, sdlEvent);
+ break;
+ case SDL_KEYUP:
+ pNewEvent = createKeyEvent(Event::KEY_UP, sdlEvent);
+ break;
+ case SDL_QUIT:
+ pNewEvent = EventPtr(new Event(Event::QUIT, Event::NONE));
+ break;
+ case SDL_VIDEORESIZE:
+ break;
+ case SDL_SYSWMEVENT:
+ {
+#if defined(HAVE_XI2_1) || defined(HAVE_XI2_2)
+ SDL_SysWMmsg* pMsg = sdlEvent.syswm.msg;
+ AVG_ASSERT(pMsg->subsystem == SDL_SYSWM_X11);
+ if (m_pXIMTInputDevice) {
+ m_pXIMTInputDevice->handleXIEvent(pMsg->event.xevent);
+ }
+#endif
+ }
+ break;
+ default:
+ // Ignore unknown events.
+ break;
+ }
+ if (pNewEvent) {
+ events.push_back(pNewEvent);
+ }
+ }
+ if (numEvents > 124) {
+ AVG_TRACE(Logger::category::EVENTS, Logger::severity::WARNING,
+ "SDL Event queue full, dropping events.");
+ }
+ return events;
+}
+
+void SDLDisplayEngine::setXIMTInputDevice(XInputMTInputDevice* pInputDevice)
+{
+ AVG_ASSERT(!m_pXIMTInputDevice);
+ m_pXIMTInputDevice = pInputDevice;
+}
+
+EventPtr SDLDisplayEngine::createMouseEvent(Event::Type type, const SDL_Event& sdlEvent,
+ long button)
+{
+ int x, y;
+ Uint8 buttonState = SDL_GetMouseState(&x, &y);
+ x = int((x*m_Size.x)/m_WindowSize.x);
+ y = int((y*m_Size.y)/m_WindowSize.y);
+ glm::vec2 lastMousePos = m_pLastMouseEvent->getPos();
+ glm::vec2 speed;
+ if (lastMousePos.x == -1) {
+ speed = glm::vec2(0,0);
+ } else {
+ float lastFrameTime = 1000/getEffectiveFramerate();
+ speed = glm::vec2(x-lastMousePos.x, y-lastMousePos.y)/lastFrameTime;
+ }
+ MouseEventPtr pEvent(new MouseEvent(type, (buttonState & SDL_BUTTON(1)) != 0,
+ (buttonState & SDL_BUTTON(2)) != 0, (buttonState & SDL_BUTTON(3)) != 0,
+ IntPoint(x, y), button, speed));
+
+ m_pLastMouseEvent = pEvent;
+ return pEvent;
+}
+
+EventPtr SDLDisplayEngine::createMouseButtonEvent(Event::Type type,
+ const SDL_Event& sdlEvent)
+{
+ long button = 0;
+ switch (sdlEvent.button.button) {
+ case SDL_BUTTON_LEFT:
+ button = MouseEvent::LEFT_BUTTON;
+ break;
+ case SDL_BUTTON_MIDDLE:
+ button = MouseEvent::MIDDLE_BUTTON;
+ break;
+ case SDL_BUTTON_RIGHT:
+ button = MouseEvent::RIGHT_BUTTON;
+ break;
+ case SDL_BUTTON_WHEELUP:
+ button = MouseEvent::WHEELUP_BUTTON;
+ break;
+ case SDL_BUTTON_WHEELDOWN:
+ button = MouseEvent::WHEELDOWN_BUTTON;
+ break;
+ }
+ return createMouseEvent(type, sdlEvent, button);
+
+}
+
+/*
+EventPtr SDLDisplayEngine::createAxisEvent(const SDL_Event & sdlEvent)
+{
+ return new AxisEvent(sdlEvent.jaxis.which, sdlEvent.jaxis.axis,
+ sdlEvent.jaxis.value);
+}
+
+
+EventPtr SDLDisplayEngine::createButtonEvent
+ (Event::Type type, const SDL_Event & sdlEvent)
+{
+ return new ButtonEvent(type, sdlEvent.jbutton.which,
+ sdlEvent.jbutton.button));
+}
+*/
+
+EventPtr SDLDisplayEngine::createKeyEvent(Event::Type type, const SDL_Event& sdlEvent)
+{
+ long keyCode = KeyCodeTranslationTable[sdlEvent.key.keysym.sym];
+ unsigned int modifiers = key::KEYMOD_NONE;
+
+ if (sdlEvent.key.keysym.mod & KMOD_LSHIFT)
+ { modifiers |= key::KEYMOD_LSHIFT; }
+ if (sdlEvent.key.keysym.mod & KMOD_RSHIFT)
+ { modifiers |= key::KEYMOD_RSHIFT; }
+ if (sdlEvent.key.keysym.mod & KMOD_LCTRL)
+ { modifiers |= key::KEYMOD_LCTRL; }
+ if (sdlEvent.key.keysym.mod & KMOD_RCTRL)
+ { modifiers |= key::KEYMOD_RCTRL; }
+ if (sdlEvent.key.keysym.mod & KMOD_LALT)
+ { modifiers |= key::KEYMOD_LALT; }
+ if (sdlEvent.key.keysym.mod & KMOD_RALT)
+ { modifiers |= key::KEYMOD_RALT; }
+ if (sdlEvent.key.keysym.mod & KMOD_LMETA)
+ { modifiers |= key::KEYMOD_LMETA; }
+ if (sdlEvent.key.keysym.mod & KMOD_RMETA)
+ { modifiers |= key::KEYMOD_RMETA; }
+ if (sdlEvent.key.keysym.mod & KMOD_NUM)
+ { modifiers |= key::KEYMOD_NUM; }
+ if (sdlEvent.key.keysym.mod & KMOD_CAPS)
+ { modifiers |= key::KEYMOD_CAPS; }
+ if (sdlEvent.key.keysym.mod & KMOD_MODE)
+ { modifiers |= key::KEYMOD_MODE; }
+ if (sdlEvent.key.keysym.mod & KMOD_RESERVED)
+ { modifiers |= key::KEYMOD_RESERVED; }
+
+ KeyEventPtr pEvent(new KeyEvent(type,
+ sdlEvent.key.keysym.scancode, keyCode,
+ SDL_GetKeyName(sdlEvent.key.keysym.sym), sdlEvent.key.keysym.unicode,
+ modifiers));
+ return pEvent;
+}
+
+void SDLDisplayEngine::initTranslationTable()
+{
+#define TRANSLATION_ENTRY(x) KeyCodeTranslationTable[SDLK_##x] = key::KEY_##x;
+
+ TRANSLATION_ENTRY(UNKNOWN);
+ TRANSLATION_ENTRY(BACKSPACE);
+ TRANSLATION_ENTRY(TAB);
+ TRANSLATION_ENTRY(CLEAR);
+ TRANSLATION_ENTRY(RETURN);
+ TRANSLATION_ENTRY(PAUSE);
+ TRANSLATION_ENTRY(ESCAPE);
+ TRANSLATION_ENTRY(SPACE);
+ TRANSLATION_ENTRY(EXCLAIM);
+ TRANSLATION_ENTRY(QUOTEDBL);
+ TRANSLATION_ENTRY(HASH);
+ TRANSLATION_ENTRY(DOLLAR);
+ TRANSLATION_ENTRY(AMPERSAND);
+ TRANSLATION_ENTRY(QUOTE);
+ TRANSLATION_ENTRY(LEFTPAREN);
+ TRANSLATION_ENTRY(RIGHTPAREN);
+ TRANSLATION_ENTRY(ASTERISK);
+ TRANSLATION_ENTRY(PLUS);
+ TRANSLATION_ENTRY(COMMA);
+ TRANSLATION_ENTRY(MINUS);
+ TRANSLATION_ENTRY(PERIOD);
+ TRANSLATION_ENTRY(SLASH);
+ TRANSLATION_ENTRY(0);
+ TRANSLATION_ENTRY(1);
+ TRANSLATION_ENTRY(2);
+ TRANSLATION_ENTRY(3);
+ TRANSLATION_ENTRY(4);
+ TRANSLATION_ENTRY(5);
+ TRANSLATION_ENTRY(6);
+ TRANSLATION_ENTRY(7);
+ TRANSLATION_ENTRY(8);
+ TRANSLATION_ENTRY(9);
+ TRANSLATION_ENTRY(COLON);
+ TRANSLATION_ENTRY(SEMICOLON);
+ TRANSLATION_ENTRY(LESS);
+ TRANSLATION_ENTRY(EQUALS);
+ TRANSLATION_ENTRY(GREATER);
+ TRANSLATION_ENTRY(QUESTION);
+ TRANSLATION_ENTRY(AT);
+ TRANSLATION_ENTRY(LEFTBRACKET);
+ TRANSLATION_ENTRY(BACKSLASH);
+ TRANSLATION_ENTRY(RIGHTBRACKET);
+ TRANSLATION_ENTRY(CARET);
+ TRANSLATION_ENTRY(UNDERSCORE);
+ TRANSLATION_ENTRY(BACKQUOTE);
+ TRANSLATION_ENTRY(a);
+ TRANSLATION_ENTRY(b);
+ TRANSLATION_ENTRY(c);
+ TRANSLATION_ENTRY(d);
+ TRANSLATION_ENTRY(e);
+ TRANSLATION_ENTRY(f);
+ TRANSLATION_ENTRY(g);
+ TRANSLATION_ENTRY(h);
+ TRANSLATION_ENTRY(i);
+ TRANSLATION_ENTRY(j);
+ TRANSLATION_ENTRY(k);
+ TRANSLATION_ENTRY(l);
+ TRANSLATION_ENTRY(m);
+ TRANSLATION_ENTRY(n);
+ TRANSLATION_ENTRY(o);
+ TRANSLATION_ENTRY(p);
+ TRANSLATION_ENTRY(q);
+ TRANSLATION_ENTRY(r);
+ TRANSLATION_ENTRY(s);
+ TRANSLATION_ENTRY(t);
+ TRANSLATION_ENTRY(u);
+ TRANSLATION_ENTRY(v);
+ TRANSLATION_ENTRY(w);
+ TRANSLATION_ENTRY(x);
+ TRANSLATION_ENTRY(y);
+ TRANSLATION_ENTRY(z);
+ TRANSLATION_ENTRY(DELETE);
+ TRANSLATION_ENTRY(WORLD_0);
+ TRANSLATION_ENTRY(WORLD_1);
+ TRANSLATION_ENTRY(WORLD_2);
+ TRANSLATION_ENTRY(WORLD_3);
+ TRANSLATION_ENTRY(WORLD_4);
+ TRANSLATION_ENTRY(WORLD_5);
+ TRANSLATION_ENTRY(WORLD_6);
+ TRANSLATION_ENTRY(WORLD_7);
+ TRANSLATION_ENTRY(WORLD_8);
+ TRANSLATION_ENTRY(WORLD_9);
+ TRANSLATION_ENTRY(WORLD_10);
+ TRANSLATION_ENTRY(WORLD_11);
+ TRANSLATION_ENTRY(WORLD_12);
+ TRANSLATION_ENTRY(WORLD_13);
+ TRANSLATION_ENTRY(WORLD_14);
+ TRANSLATION_ENTRY(WORLD_15);
+ TRANSLATION_ENTRY(WORLD_16);
+ TRANSLATION_ENTRY(WORLD_17);
+ TRANSLATION_ENTRY(WORLD_18);
+ TRANSLATION_ENTRY(WORLD_19);
+ TRANSLATION_ENTRY(WORLD_20);
+ TRANSLATION_ENTRY(WORLD_21);
+ TRANSLATION_ENTRY(WORLD_22);
+ TRANSLATION_ENTRY(WORLD_23);
+ TRANSLATION_ENTRY(WORLD_24);
+ TRANSLATION_ENTRY(WORLD_25);
+ TRANSLATION_ENTRY(WORLD_26);
+ TRANSLATION_ENTRY(WORLD_27);
+ TRANSLATION_ENTRY(WORLD_28);
+ TRANSLATION_ENTRY(WORLD_29);
+ TRANSLATION_ENTRY(WORLD_30);
+ TRANSLATION_ENTRY(WORLD_31);
+ TRANSLATION_ENTRY(WORLD_32);
+ TRANSLATION_ENTRY(WORLD_33);
+ TRANSLATION_ENTRY(WORLD_34);
+ TRANSLATION_ENTRY(WORLD_35);
+ TRANSLATION_ENTRY(WORLD_36);
+ TRANSLATION_ENTRY(WORLD_37);
+ TRANSLATION_ENTRY(WORLD_38);
+ TRANSLATION_ENTRY(WORLD_39);
+ TRANSLATION_ENTRY(WORLD_40);
+ TRANSLATION_ENTRY(WORLD_41);
+ TRANSLATION_ENTRY(WORLD_42);
+ TRANSLATION_ENTRY(WORLD_43);
+ TRANSLATION_ENTRY(WORLD_44);
+ TRANSLATION_ENTRY(WORLD_45);
+ TRANSLATION_ENTRY(WORLD_46);
+ TRANSLATION_ENTRY(WORLD_47);
+ TRANSLATION_ENTRY(WORLD_48);
+ TRANSLATION_ENTRY(WORLD_49);
+ TRANSLATION_ENTRY(WORLD_50);
+ TRANSLATION_ENTRY(WORLD_51);
+ TRANSLATION_ENTRY(WORLD_52);
+ TRANSLATION_ENTRY(WORLD_53);
+ TRANSLATION_ENTRY(WORLD_54);
+ TRANSLATION_ENTRY(WORLD_55);
+ TRANSLATION_ENTRY(WORLD_56);
+ TRANSLATION_ENTRY(WORLD_57);
+ TRANSLATION_ENTRY(WORLD_58);
+ TRANSLATION_ENTRY(WORLD_59);
+ TRANSLATION_ENTRY(WORLD_60);
+ TRANSLATION_ENTRY(WORLD_61);
+ TRANSLATION_ENTRY(WORLD_62);
+ TRANSLATION_ENTRY(WORLD_63);
+ TRANSLATION_ENTRY(WORLD_64);
+ TRANSLATION_ENTRY(WORLD_65);
+ TRANSLATION_ENTRY(WORLD_66);
+ TRANSLATION_ENTRY(WORLD_67);
+ TRANSLATION_ENTRY(WORLD_68);
+ TRANSLATION_ENTRY(WORLD_69);
+ TRANSLATION_ENTRY(WORLD_70);
+ TRANSLATION_ENTRY(WORLD_71);
+ TRANSLATION_ENTRY(WORLD_72);
+ TRANSLATION_ENTRY(WORLD_73);
+ TRANSLATION_ENTRY(WORLD_74);
+ TRANSLATION_ENTRY(WORLD_75);
+ TRANSLATION_ENTRY(WORLD_76);
+ TRANSLATION_ENTRY(WORLD_77);
+ TRANSLATION_ENTRY(WORLD_78);
+ TRANSLATION_ENTRY(WORLD_79);
+ TRANSLATION_ENTRY(WORLD_80);
+ TRANSLATION_ENTRY(WORLD_81);
+ TRANSLATION_ENTRY(WORLD_82);
+ TRANSLATION_ENTRY(WORLD_83);
+ TRANSLATION_ENTRY(WORLD_84);
+ TRANSLATION_ENTRY(WORLD_85);
+ TRANSLATION_ENTRY(WORLD_86);
+ TRANSLATION_ENTRY(WORLD_87);
+ TRANSLATION_ENTRY(WORLD_88);
+ TRANSLATION_ENTRY(WORLD_89);
+ TRANSLATION_ENTRY(WORLD_90);
+ TRANSLATION_ENTRY(WORLD_91);
+ TRANSLATION_ENTRY(WORLD_92);
+ TRANSLATION_ENTRY(WORLD_93);
+ TRANSLATION_ENTRY(WORLD_94);
+ TRANSLATION_ENTRY(WORLD_95);
+ TRANSLATION_ENTRY(KP0);
+ TRANSLATION_ENTRY(KP1);
+ TRANSLATION_ENTRY(KP2);
+ TRANSLATION_ENTRY(KP3);
+ TRANSLATION_ENTRY(KP4);
+ TRANSLATION_ENTRY(KP5);
+ TRANSLATION_ENTRY(KP6);
+ TRANSLATION_ENTRY(KP7);
+ TRANSLATION_ENTRY(KP8);
+ TRANSLATION_ENTRY(KP9);
+ TRANSLATION_ENTRY(KP_PERIOD);
+ TRANSLATION_ENTRY(KP_DIVIDE);
+ TRANSLATION_ENTRY(KP_MULTIPLY);
+ TRANSLATION_ENTRY(KP_MINUS);
+ TRANSLATION_ENTRY(KP_PLUS);
+ TRANSLATION_ENTRY(KP_ENTER);
+ TRANSLATION_ENTRY(KP_EQUALS);
+ TRANSLATION_ENTRY(UP);
+ TRANSLATION_ENTRY(DOWN);
+ TRANSLATION_ENTRY(RIGHT);
+ TRANSLATION_ENTRY(LEFT);
+ TRANSLATION_ENTRY(INSERT);
+ TRANSLATION_ENTRY(HOME);
+ TRANSLATION_ENTRY(END);
+ TRANSLATION_ENTRY(PAGEUP);
+ TRANSLATION_ENTRY(PAGEDOWN);
+ TRANSLATION_ENTRY(F1);
+ TRANSLATION_ENTRY(F2);
+ TRANSLATION_ENTRY(F3);
+ TRANSLATION_ENTRY(F4);
+ TRANSLATION_ENTRY(F5);
+ TRANSLATION_ENTRY(F6);
+ TRANSLATION_ENTRY(F7);
+ TRANSLATION_ENTRY(F8);
+ TRANSLATION_ENTRY(F9);
+ TRANSLATION_ENTRY(F10);
+ TRANSLATION_ENTRY(F11);
+ TRANSLATION_ENTRY(F12);
+ TRANSLATION_ENTRY(F13);
+ TRANSLATION_ENTRY(F14);
+ TRANSLATION_ENTRY(F15);
+ TRANSLATION_ENTRY(NUMLOCK);
+ TRANSLATION_ENTRY(CAPSLOCK);
+ TRANSLATION_ENTRY(SCROLLOCK);
+ TRANSLATION_ENTRY(RSHIFT);
+ TRANSLATION_ENTRY(LSHIFT);
+ TRANSLATION_ENTRY(RCTRL);
+ TRANSLATION_ENTRY(LCTRL);
+ TRANSLATION_ENTRY(RALT);
+ TRANSLATION_ENTRY(LALT);
+ TRANSLATION_ENTRY(RMETA);
+ TRANSLATION_ENTRY(LMETA);
+ TRANSLATION_ENTRY(LSUPER);
+ TRANSLATION_ENTRY(RSUPER);
+ TRANSLATION_ENTRY(MODE);
+ TRANSLATION_ENTRY(COMPOSE);
+ TRANSLATION_ENTRY(HELP);
+ TRANSLATION_ENTRY(PRINT);
+ TRANSLATION_ENTRY(SYSREQ);
+ TRANSLATION_ENTRY(BREAK);
+ TRANSLATION_ENTRY(MENU);
+ TRANSLATION_ENTRY(POWER);
+ TRANSLATION_ENTRY(EURO);
+ TRANSLATION_ENTRY(UNDO);
+}
+
+const IntPoint& SDLDisplayEngine::getWindowSize() const
+{
+ return m_WindowSize;
+}
+
+bool SDLDisplayEngine::isFullscreen() const
+{
+ return m_bIsFullscreen;
+}
+
+}
diff --git a/src/player/SDLDisplayEngine.h b/src/player/SDLDisplayEngine.h
new file mode 100644
index 0000000..90f31ed
--- /dev/null
+++ b/src/player/SDLDisplayEngine.h
@@ -0,0 +1,109 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _SDLDisplayEngine_H_
+#define _SDLDisplayEngine_H_
+
+#include "../api.h"
+#include "IInputDevice.h"
+#include "DisplayEngine.h"
+
+#include "../graphics/GLConfig.h"
+#include "../graphics/Bitmap.h"
+#include "../graphics/Pixel32.h"
+#include "../graphics/OGLHelper.h"
+#include "../graphics/FBO.h"
+
+#include <string>
+#include <vector>
+
+struct SDL_Surface;
+union SDL_Event;
+
+namespace avg {
+
+class XInputMTInputDevice;
+class MouseEvent;
+typedef boost::shared_ptr<class MouseEvent> MouseEventPtr;
+class GLContext;
+
+class AVG_API SDLDisplayEngine: public DisplayEngine, public IInputDevice
+{
+ public:
+ static void initSDL();
+ static void quitSDL();
+ SDLDisplayEngine();
+ virtual ~SDLDisplayEngine();
+ virtual void init(const DisplayParams& dp, GLConfig glConfig);
+ IntPoint calcWindowSize(const DisplayParams& dp) const;
+
+ void setWindowTitle(const std::string& sTitle);
+
+ // From DisplayEngine
+ virtual void teardown();
+ virtual void setGamma(float red, float green, float blue);
+ virtual void setMousePos(const IntPoint& pos);
+ virtual int getKeyModifierState() const;
+
+ virtual IntPoint getSize();
+
+ virtual void showCursor(bool bShow);
+ virtual BitmapPtr screenshot(int buffer=0);
+
+ // From IInputDevice
+ virtual std::vector<EventPtr> pollEvents();
+ void setXIMTInputDevice(XInputMTInputDevice* pInputDevice);
+
+ const IntPoint& getWindowSize() const;
+ bool isFullscreen() const;
+ virtual void swapBuffers();
+
+ private:
+ void initTranslationTable();
+
+ bool internalSetGamma(float red, float green, float blue);
+
+ EventPtr createMouseEvent
+ (Event::Type Type, const SDL_Event & SDLEvent, long Button);
+ EventPtr createMouseButtonEvent(Event::Type Type, const SDL_Event & SDLEvent);
+ EventPtr createKeyEvent(Event::Type Type, const SDL_Event & SDLEvent);
+
+ IntPoint m_Size;
+ bool m_bIsFullscreen;
+ IntPoint m_WindowSize;
+
+ SDL_Surface * m_pScreen;
+
+ // Event handling.
+ MouseEventPtr m_pLastMouseEvent;
+ static std::vector<long> KeyCodeTranslationTable;
+ XInputMTInputDevice * m_pXIMTInputDevice;
+
+ GLContext* m_pGLContext;
+
+ float m_Gamma[3];
+};
+
+typedef boost::shared_ptr<SDLDisplayEngine> SDLDisplayEnginePtr;
+
+}
+
+#endif
diff --git a/src/player/SDLMain.h b/src/player/SDLMain.h
new file mode 100644
index 0000000..8df5895
--- /dev/null
+++ b/src/player/SDLMain.h
@@ -0,0 +1,14 @@
+
+#ifndef __SDLMain_h__
+#define __SDLMain_h__
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+void CustomSDLMain();
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/player/SDLMain.m b/src/player/SDLMain.m
new file mode 100644
index 0000000..bec828d
--- /dev/null
+++ b/src/player/SDLMain.m
@@ -0,0 +1,32 @@
+#import <SDL/SDL.h>
+#import "SDLMain.h"
+
+#import <Cocoa/Cocoa.h>
+
+/* Portions of CPS.h */
+typedef struct CPSProcessSerNum
+{
+ UInt32 lo;
+ UInt32 hi;
+} CPSProcessSerNum;
+
+extern OSErr CPSGetCurrentProcess( CPSProcessSerNum *psn);
+extern OSErr CPSEnableForegroundOperation( CPSProcessSerNum *psn, UInt32 _arg2, UInt32 _arg3, UInt32 _arg4, UInt32 _arg5);
+extern OSErr CPSSetFrontProcess( CPSProcessSerNum *psn);
+
+void CustomSDLMain()
+{
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ [ NSApplication sharedApplication ];
+ [ NSApp setMainMenu:[[NSMenu alloc] init] ];
+
+ {
+ CPSProcessSerNum PSN;
+ /* Tell the dock about us */
+ if (!CPSGetCurrentProcess(&PSN))
+ if (!CPSEnableForegroundOperation(&PSN,0x03,0x3C,0x2C,0x1103))
+ if (!CPSSetFrontProcess(&PSN))
+ [NSApplication sharedApplication];
+ }
+}
+
diff --git a/src/player/SVG.cpp b/src/player/SVG.cpp
new file mode 100644
index 0000000..9e778fa
--- /dev/null
+++ b/src/player/SVG.cpp
@@ -0,0 +1,180 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "SVG.h"
+
+#include "../base/Exception.h"
+#include "../base/ObjectCounter.h"
+#include "../base/ScopeTimer.h"
+#include "../base/OSHelper.h"
+#include "../base/StringHelper.h"
+#include "../base/Logger.h"
+
+#include "../graphics/PixelFormat.h"
+#include "../graphics/Filterfill.h"
+#include "../graphics/Filterfliprgb.h"
+#include "../graphics/FilterUnmultiplyAlpha.h"
+#include "../graphics/BitmapLoader.h"
+
+#include "OGLSurface.h"
+#include "Player.h"
+#include "ImageNode.h"
+
+#include <glib-object.h>
+
+#ifndef RSVG_CAIRO_H
+#include <librsvg/rsvg-cairo.h>
+#endif
+
+#include <cairo.h>
+
+#include <iostream>
+
+using namespace std;
+
+
+namespace avg {
+
+SVG::SVG(const UTF8String& sFilename, bool bUnescapeIllustratorIDs)
+ : m_sFilename(sFilename),
+ m_bUnescapeIllustratorIDs(bUnescapeIllustratorIDs)
+{
+ GError* pErr = 0;
+ m_pRSVG = rsvg_handle_new_from_file(m_sFilename.c_str(), &pErr);
+ if (!m_pRSVG) {
+ throw Exception(AVG_ERR_INVALID_ARGS,
+ string("Could not open svg file: ") + m_sFilename);
+ g_error_free(pErr);
+ }
+}
+
+SVG::~SVG()
+{
+ g_object_unref(m_pRSVG);
+}
+
+BitmapPtr SVG::renderElement(const UTF8String& sElementID)
+{
+ return renderElement(sElementID, 1);
+}
+
+BitmapPtr SVG::renderElement(const UTF8String& sElementID, const glm::vec2& size)
+{
+ SVGElementPtr pElement = getElement(sElementID);
+ glm::vec2 elementSize = pElement->getSize();
+ return internalRenderElement(pElement, size, elementSize);
+}
+
+BitmapPtr SVG::renderElement(const UTF8String& sElementID, float scale)
+{
+ SVGElementPtr pElement = getElement(sElementID);
+ glm::vec2 size = pElement->getSize();
+ glm::vec2 renderSize = size * scale;
+ return internalRenderElement(pElement, renderSize, size);
+}
+
+NodePtr SVG::createImageNode(const UTF8String& sElementID, const py::dict& nodeAttrs)
+{
+ BitmapPtr pBmp = renderElement(sElementID);
+ return createImageNodeFromBitmap(pBmp, nodeAttrs);
+}
+
+NodePtr SVG::createImageNode(const UTF8String& sElementID, const py::dict& nodeAttrs,
+ const glm::vec2& renderSize)
+{
+ BitmapPtr pBmp = renderElement(sElementID, renderSize);
+ return createImageNodeFromBitmap(pBmp, nodeAttrs);
+}
+
+NodePtr SVG::createImageNode(const UTF8String& sElementID, const py::dict& nodeAttrs,
+ float scale)
+{
+ BitmapPtr pBmp = renderElement(sElementID, scale);
+ return createImageNodeFromBitmap(pBmp, nodeAttrs);
+}
+
+glm::vec2 SVG::getElementPos(const UTF8String& sElementID)
+{
+ SVGElementPtr pElement = getElement(sElementID);
+ return pElement->getPos();
+}
+
+glm::vec2 SVG::getElementSize(const UTF8String& sElementID)
+{
+ SVGElementPtr pElement = getElement(sElementID);
+ return pElement->getSize();
+}
+
+BitmapPtr SVG::internalRenderElement(const SVGElementPtr& pElement,
+ const glm::vec2& renderSize, const glm::vec2& size)
+{
+ glm::vec2 pos = pElement->getPos();
+ glm::vec2 scale(renderSize.x/size.x, renderSize.y/size.y);
+ IntPoint boundingBox = IntPoint(renderSize) +
+ IntPoint(int(scale.x+0.5), int(scale.y+0.5));
+ BitmapPtr pBmp(new Bitmap(boundingBox, B8G8R8A8));
+ FilterFill<Pixel32>(Pixel32(0,0,0,0)).applyInPlace(pBmp);
+
+ cairo_surface_t* pSurface;
+ cairo_t* pCairo;
+ pSurface = cairo_image_surface_create_for_data(pBmp->getPixels(),
+ CAIRO_FORMAT_ARGB32, boundingBox.x, boundingBox.y,
+ pBmp->getStride());
+ pCairo = cairo_create(pSurface);
+ cairo_scale(pCairo, scale.x, scale.y);
+ cairo_translate(pCairo, -pos.x, -pos.y);
+ rsvg_handle_render_cairo_sub(m_pRSVG, pCairo, pElement->getUnescapedID().c_str());
+
+ FilterUnmultiplyAlpha().applyInPlace(pBmp);
+
+ cairo_surface_destroy(pSurface);
+ cairo_destroy(pCairo);
+
+ if (!BitmapLoader::get()->isBlueFirst()) {
+ FilterFlipRGB().applyInPlace(pBmp);
+ }
+
+ return pBmp;
+}
+
+NodePtr SVG::createImageNodeFromBitmap(BitmapPtr pBmp, const py::dict& nodeAttrs)
+{
+ ImageNodePtr pNode = boost::dynamic_pointer_cast<ImageNode>(
+ Player::get()->createNode("image", nodeAttrs));
+ pNode->setBitmap(pBmp);
+ return pNode;
+}
+
+SVGElementPtr SVG::getElement(const UTF8String& sElementID)
+{
+ map<UTF8String, SVGElementPtr>::iterator pos = m_ElementMap.find(sElementID);
+ if (pos == m_ElementMap.end()) {
+ SVGElementPtr pElement(new SVGElement(m_pRSVG, m_sFilename, sElementID,
+ m_bUnescapeIllustratorIDs));
+ m_ElementMap[sElementID] = pElement;
+ return pElement;
+ } else {
+ return pos->second;
+ }
+}
+
+}
+
diff --git a/src/player/SVG.h b/src/player/SVG.h
new file mode 100644
index 0000000..73f0d55
--- /dev/null
+++ b/src/player/SVG.h
@@ -0,0 +1,78 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _SVG_H_
+#define _SVG_H_
+
+#include "WrapPython.h"
+
+#include "../api.h"
+
+#include "../base/UTF8String.h"
+#include "../graphics/Bitmap.h"
+#include "BoostPython.h"
+#include "SVGElement.h"
+
+#include <librsvg/rsvg.h>
+#include <boost/shared_ptr.hpp>
+
+#include <string>
+
+namespace avg {
+
+class Node;
+typedef boost::shared_ptr<Node> NodePtr;
+
+class SVG
+{
+public:
+ SVG(const UTF8String& sFilename, bool bUnescapeIllustratorIDs=false);
+ virtual ~SVG();
+
+ BitmapPtr renderElement(const UTF8String& sElementID);
+ BitmapPtr renderElement(const UTF8String& sElementID, const glm::vec2& size);
+ BitmapPtr renderElement(const UTF8String& sElementID, float scale);
+ NodePtr createImageNode(const UTF8String& sElementID,
+ const py::dict& nodeAttrs);
+ NodePtr createImageNode(const UTF8String& sElementID,
+ const py::dict& nodeAttrs, const glm::vec2& renderSize);
+ NodePtr createImageNode(const UTF8String& sElementID,
+ const py::dict& nodeAttrs, float scale);
+ glm::vec2 getElementPos(const UTF8String& sElementID);
+ glm::vec2 getElementSize(const UTF8String& sElementID);
+
+private:
+ BitmapPtr internalRenderElement(const SVGElementPtr& pElement,
+ const glm::vec2& renderSize, const glm::vec2& size);
+ NodePtr createImageNodeFromBitmap(BitmapPtr pBmp,
+ const py::dict& nodeAttrs);
+ SVGElementPtr getElement(const UTF8String& sElementID);
+
+ std::map<UTF8String, SVGElementPtr> m_ElementMap;
+ UTF8String m_sFilename;
+ bool m_bUnescapeIllustratorIDs;
+ RsvgHandle* m_pRSVG;
+};
+
+}
+
+#endif
+
diff --git a/src/player/SVGElement.cpp b/src/player/SVGElement.cpp
new file mode 100644
index 0000000..dc0ba28
--- /dev/null
+++ b/src/player/SVGElement.cpp
@@ -0,0 +1,116 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "SVGElement.h"
+
+#include "../base/StringHelper.h"
+#include "../base/Exception.h"
+#include "../base/Logger.h"
+
+using namespace std;
+
+namespace avg {
+
+SVGElement::SVGElement(RsvgHandle* pRSVG, const UTF8String& sFilename,
+ const UTF8String& sElementID, bool bUnescapeIllustratorIDs)
+{
+ m_sUnescapedID = unescapeID(pRSVG, sFilename, sElementID, bUnescapeIllustratorIDs);
+
+ RsvgPositionData pos;
+ rsvg_handle_get_position_sub(pRSVG, &pos, m_sUnescapedID.c_str());
+ m_Pos = glm::vec2(pos.x, pos.y);
+
+ RsvgDimensionData dim;
+ rsvg_handle_get_dimensions_sub(pRSVG, &dim, m_sUnescapedID.c_str());
+ m_Size = glm::vec2(dim.width+1, dim.height+1);
+}
+
+const UTF8String& SVGElement::getUnescapedID() const
+{
+ return m_sUnescapedID;
+}
+
+const glm::vec2& SVGElement::getPos() const
+{
+ return m_Pos;
+}
+
+const glm::vec2& SVGElement::getSize() const
+{
+ return m_Size;
+}
+
+UTF8String SVGElement::unescapeID(RsvgHandle* pRSVG, const UTF8String& sFilename,
+ const UTF8String& sElementID, bool bUnescapeIllustratorIDs)
+{
+ UTF8String sResult(string("#") + sElementID);
+ if (bUnescapeIllustratorIDs) {
+ vector<string> sPossibleIDs;
+ sPossibleIDs.push_back(sResult);
+ string::size_type pos = sResult.find("_");
+ if (pos != UTF8String::npos) {
+ while (pos != UTF8String::npos) {
+ sResult.replace(pos, 1, "_x5F_");
+ pos = sResult.find("_", pos+5);
+ }
+ sPossibleIDs.push_back(sResult);
+ }
+ // Illustrator adds suffixes to IDs to get rid of duplicates. Even after the
+ // duplicates are removed, the suffixes remain :-(.
+ // We handle two cases here:
+ // 1) If there is only one version with a suffix, we take that version.
+ // 2) If there are duplicate IDs, we warn.
+ for (int i=1; i<30; ++i) {
+ string sTempID = sResult + "_" + toString(i) + "_";
+ sPossibleIDs.push_back(sTempID);
+ }
+ int numFound = 0;
+ for (int i=0; i<30; ++i) {
+ string sTempID = sPossibleIDs[i];
+ if (rsvg_handle_has_sub(pRSVG, sTempID.c_str())) {
+ sResult = sTempID;
+ numFound += 1;
+ }
+ }
+ if (numFound == 0) {
+ throwIDNotFound(sFilename, sElementID);
+ }
+ if (numFound > 1) {
+ AVG_LOG_WARNING("svg file '" << sFilename <<
+ "' has more than one element with id '" << sElementID << "'.");
+ }
+ } else {
+ if (!rsvg_handle_has_sub(pRSVG, sResult.c_str())) {
+ throwIDNotFound(sFilename, sElementID);
+ }
+ }
+ return sResult;
+}
+
+void SVGElement::throwIDNotFound(const UTF8String& sFilename,
+ const UTF8String& sElementID)
+{
+ throw Exception(AVG_ERR_INVALID_ARGS,
+ string("svg file '") + sFilename + "' does not have an element with id '" +
+ sElementID + "'.");
+}
+
+}
diff --git a/src/player/SVGElement.h b/src/player/SVGElement.h
new file mode 100644
index 0000000..280df6b
--- /dev/null
+++ b/src/player/SVGElement.h
@@ -0,0 +1,62 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _SVGElement_H_
+#define _SVGElement_H_
+
+#include "../api.h"
+
+#include "../base/UTF8String.h"
+#include "../base/GLMHelper.h"
+
+#include <librsvg/rsvg.h>
+#include <boost/shared_ptr.hpp>
+
+#include <map>
+
+namespace avg {
+
+class SVGElement
+{
+public:
+ SVGElement(RsvgHandle* pRSVG, const UTF8String& sFilename,
+ const UTF8String& sElementID, bool bUnescapeIllustratorIDs);
+
+ const UTF8String& getUnescapedID() const;
+ const glm::vec2& getPos() const;
+ const glm::vec2& getSize() const;
+
+private:
+ UTF8String unescapeID(RsvgHandle* pRSVG, const UTF8String& sFilename,
+ const UTF8String& sElementID, bool bUnescapeIllustratorIDs);
+ void throwIDNotFound(const UTF8String& sFilename, const UTF8String& sElementID);
+
+ UTF8String m_sUnescapedID;
+ glm::vec2 m_Pos;
+ glm::vec2 m_Size;
+};
+
+typedef boost::shared_ptr<SVGElement> SVGElementPtr;
+
+}
+
+#endif
+
diff --git a/src/player/ShadowFXNode.cpp b/src/player/ShadowFXNode.cpp
new file mode 100644
index 0000000..30ef766
--- /dev/null
+++ b/src/player/ShadowFXNode.cpp
@@ -0,0 +1,122 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "ShadowFXNode.h"
+
+#include "../base/ObjectCounter.h"
+#include "../base/Exception.h"
+
+#include <string>
+
+using namespace std;
+
+namespace avg {
+
+ShadowFXNode::ShadowFXNode(glm::vec2 offset, float radius, float opacity, string sColor)
+ : FXNode(false),
+ m_Offset(offset),
+ m_StdDev(radius),
+ m_Opacity(opacity)
+{
+ m_sColorName = sColor;
+ m_Color = colorStringToColor(sColor);
+ ObjectCounter::get()->incRef(&typeid(*this));
+}
+
+ShadowFXNode::~ShadowFXNode()
+{
+ ObjectCounter::get()->decRef(&typeid(*this));
+}
+
+void ShadowFXNode::connect()
+{
+ FXNode::connect();
+}
+
+void ShadowFXNode::disconnect()
+{
+ m_pFilter = GPUShadowFilterPtr();
+ FXNode::disconnect();
+}
+
+void ShadowFXNode::setOffset(const glm::vec2& offset)
+{
+ m_Offset = offset;
+ updateFilter();
+}
+
+glm::vec2 ShadowFXNode::getOffset() const
+{
+ return m_Offset;
+}
+
+void ShadowFXNode::setRadius(float radius)
+{
+ m_StdDev = radius;
+ updateFilter();
+}
+
+float ShadowFXNode::getRadius() const
+{
+ return m_StdDev;
+}
+
+void ShadowFXNode::setOpacity(float opacity)
+{
+ m_Opacity = opacity;
+ updateFilter();
+}
+
+float ShadowFXNode::getOpacity() const
+{
+ return m_Opacity;
+}
+
+void ShadowFXNode::setColor(const std::string& sColor)
+{
+ m_sColorName = sColor;
+ m_Color = colorStringToColor(sColor);
+ updateFilter();
+}
+
+std::string ShadowFXNode::getColor() const
+{
+ return m_sColorName;
+}
+
+GPUFilterPtr ShadowFXNode::createFilter(const IntPoint& size)
+{
+ m_pFilter = GPUShadowFilterPtr(new GPUShadowFilter(size, m_Offset, m_StdDev,
+ m_Opacity, m_Color));
+ setDirty();
+ return m_pFilter;
+}
+
+void ShadowFXNode::updateFilter()
+{
+ if (m_pFilter) {
+ m_pFilter->setParams(m_Offset, m_StdDev, m_Opacity, m_Color);
+ setDirty();
+ }
+}
+
+}
+
diff --git a/src/player/ShadowFXNode.h b/src/player/ShadowFXNode.h
new file mode 100644
index 0000000..e0bd77a
--- /dev/null
+++ b/src/player/ShadowFXNode.h
@@ -0,0 +1,72 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _ShadowFXNode_H_
+#define _ShadowFXNode_H_
+
+#include "../api.h"
+
+#include "FXNode.h"
+#include "../graphics/GPUShadowFilter.h"
+#include "../base/GLMHelper.h"
+
+#include <boost/shared_ptr.hpp>
+#include <string>
+
+namespace avg {
+
+class AVG_API ShadowFXNode: public FXNode {
+public:
+ ShadowFXNode(glm::vec2 offset=glm::vec2(0,0), float radius=1.f, float opacity=1.f,
+ std::string sColor="FFFFFF");
+ virtual ~ShadowFXNode();
+
+ virtual void connect();
+ virtual void disconnect();
+
+ void setOffset(const glm::vec2& offset);
+ glm::vec2 getOffset() const;
+ void setRadius(float radius);
+ float getRadius() const;
+ void setOpacity(float opacity);
+ float getOpacity() const;
+ void setColor(const std::string& sColor);
+ std::string getColor() const;
+
+private:
+ virtual GPUFilterPtr createFilter(const IntPoint& size);
+ void updateFilter();
+
+ GPUShadowFilterPtr m_pFilter;
+
+ glm::vec2 m_Offset;
+ float m_StdDev;
+ float m_Opacity;
+ std::string m_sColorName;
+ Pixel32 m_Color;
+};
+
+typedef boost::shared_ptr<ShadowFXNode> ShadowFXNodePtr;
+
+}
+
+#endif
+
diff --git a/src/player/Shape.cpp b/src/player/Shape.cpp
new file mode 100644
index 0000000..a40f01b
--- /dev/null
+++ b/src/player/Shape.cpp
@@ -0,0 +1,129 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "Shape.h"
+
+#include "../base/Logger.h"
+#include "../base/Exception.h"
+
+#include "../graphics/Filterfliprgb.h"
+#include "../graphics/GLContext.h"
+#include "../graphics/OGLShader.h"
+
+#include "OGLSurface.h"
+
+#include <iostream>
+#include <sstream>
+
+using namespace std;
+
+namespace avg {
+
+Shape::Shape(const MaterialInfo& material)
+{
+ m_pSurface = new OGLSurface();
+ m_pImage = ImagePtr(new Image(m_pSurface, material));
+}
+
+Shape::~Shape()
+{
+ delete m_pSurface;
+}
+
+void Shape::setBitmap(BitmapPtr pBmp)
+{
+ Image::State prevState = m_pImage->getState();
+ if (pBmp) {
+ m_pImage->setBitmap(pBmp);
+ } else {
+ m_pImage->setEmpty();
+ }
+ if (m_pImage->getState() == Image::GPU) {
+ if (prevState != Image::GPU) {
+ // TODO: This shouldn't happen.
+ m_pVertexData = VertexDataPtr(new VertexData());
+ }
+ }
+}
+
+void Shape::moveToGPU()
+{
+ m_pImage->moveToGPU();
+ m_pVertexData = VertexDataPtr(new VertexData());
+}
+
+void Shape::moveToCPU()
+{
+ m_pVertexData = VertexDataPtr();
+ m_pImage->moveToCPU();
+}
+
+ImagePtr Shape::getImage()
+{
+ return m_pImage;
+}
+
+bool Shape::isTextured() const
+{
+ return m_pImage->getSource() != Image::NONE;
+}
+
+VertexDataPtr Shape::getVertexData()
+{
+ return m_pVertexData;
+}
+
+void Shape::setVertexArray(const VertexArrayPtr& pVA)
+{
+ pVA->startSubVA(m_SubVA);
+ m_SubVA.appendVertexData(m_pVertexData);
+/*
+ cerr << endl;
+ cerr << "Global VA: " << endl;
+ pVA->dump();
+ cerr << "Local vertex data: " << endl;
+ m_pVertexData->dump();
+*/
+}
+
+void Shape::draw(const glm::mat4& transform, float opacity)
+{
+ bool bIsTextured = isTextured();
+ GLContext* pContext = GLContext::getMain();
+ StandardShaderPtr pShader = pContext->getStandardShader();
+ pShader->setTransform(transform);
+ pShader->setAlpha(opacity);
+ if (bIsTextured) {
+ m_pSurface->activate();
+ } else {
+ pShader->setUntextured();
+ pShader->activate();
+ }
+ m_SubVA.draw();
+}
+
+void Shape::discard()
+{
+ m_pVertexData = VertexDataPtr();
+ m_pImage->discard();
+}
+
+}
diff --git a/src/player/Shape.h b/src/player/Shape.h
new file mode 100644
index 0000000..4cbb390
--- /dev/null
+++ b/src/player/Shape.h
@@ -0,0 +1,70 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _Shape_H_
+#define _Shape_H_
+
+#include "../api.h"
+#include "Image.h"
+#include "MaterialInfo.h"
+
+#include "../base/GLMHelper.h"
+#include "../graphics/Bitmap.h"
+#include "../graphics/SubVertexArray.h"
+
+#include <boost/shared_ptr.hpp>
+#include <string>
+
+namespace avg {
+
+class AVG_API Shape
+{
+ public:
+ Shape(const MaterialInfo& material);
+ virtual ~Shape();
+
+ void setBitmap(BitmapPtr pBmp);
+
+ virtual void moveToGPU();
+ virtual void moveToCPU();
+
+ ImagePtr getImage();
+ VertexDataPtr getVertexData();
+ void setVertexArray(const VertexArrayPtr& pVA);
+ void draw(const glm::mat4& transform, float opacity);
+
+ void discard();
+
+ private:
+ bool isTextured() const;
+
+ VertexDataPtr m_pVertexData;
+ SubVertexArray m_SubVA;
+ OGLSurface * m_pSurface;
+ ImagePtr m_pImage;
+};
+
+typedef boost::shared_ptr<Shape> ShapePtr;
+
+}
+
+#endif
+
diff --git a/src/player/SoundNode.cpp b/src/player/SoundNode.cpp
new file mode 100644
index 0000000..3bb089c
--- /dev/null
+++ b/src/player/SoundNode.cpp
@@ -0,0 +1,354 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+#include "SoundNode.h"
+#include "Player.h"
+#include "TypeDefinition.h"
+#include "Canvas.h"
+
+#include "../base/Exception.h"
+#include "../base/Logger.h"
+#include "../base/ScopeTimer.h"
+#include "../base/XMLHelper.h"
+#include "../base/ObjectCounter.h"
+
+#include "../audio/AudioEngine.h"
+
+#include "../video/AsyncVideoDecoder.h"
+
+#include <iostream>
+#include <sstream>
+
+#ifndef _WIN32
+#include <unistd.h>
+#endif
+
+using namespace boost;
+using namespace std;
+
+namespace avg {
+
+void SoundNode::registerType()
+{
+ TypeDefinition def = TypeDefinition("sound", "areanode",
+ ExportedObject::buildObject<SoundNode>)
+ .addArg(Arg<UTF8String>("href", "", false, offsetof(SoundNode, m_href)))
+ .addArg(Arg<bool>("loop", false, false, offsetof(SoundNode, m_bLoop)))
+ .addArg(Arg<float>("volume", 1.0, false, offsetof(SoundNode, m_Volume)))
+ ;
+ TypeRegistry::get()->registerType(def);
+}
+
+SoundNode::SoundNode(const ArgList& args)
+ : m_Filename(""),
+ m_pEOFCallback(0),
+ m_SeekBeforeCanRenderTime(0),
+ m_pDecoder(0),
+ m_Volume(1.0),
+ m_State(Unloaded),
+ m_AudioID(-1)
+{
+ args.setMembers(this);
+ m_Filename = m_href;
+ initFilename(m_Filename);
+ m_pDecoder = new AsyncVideoDecoder(8);
+
+ ObjectCounter::get()->incRef(&typeid(*this));
+}
+
+SoundNode::~SoundNode()
+{
+ if (m_pDecoder) {
+ delete m_pDecoder;
+ m_pDecoder = 0;
+ }
+ if (m_pEOFCallback) {
+ Py_DECREF(m_pEOFCallback);
+ }
+ ObjectCounter::get()->decRef(&typeid(*this));
+}
+
+long long SoundNode::getDuration() const
+{
+ exceptionIfUnloaded("getDuration");
+ return (long long)(m_pDecoder->getVideoInfo().m_Duration*1000);
+}
+
+std::string SoundNode::getAudioCodec() const
+{
+ exceptionIfUnloaded("getAudioCodec");
+ return m_pDecoder->getVideoInfo().m_sACodec;
+}
+
+int SoundNode::getAudioSampleRate() const
+{
+ exceptionIfUnloaded("getAudioSampleRate");
+ return m_pDecoder->getVideoInfo().m_SampleRate;
+}
+
+int SoundNode::getNumAudioChannels() const
+{
+ exceptionIfUnloaded("getNumAudioChannels");
+ return m_pDecoder->getVideoInfo().m_NumAudioChannels;
+}
+
+long long SoundNode::getCurTime() const
+{
+ exceptionIfUnloaded("getCurTime");
+ return (long long)(m_pDecoder->getCurTime()*1000);
+}
+
+void SoundNode::seekToTime(long long Time)
+{
+ exceptionIfUnloaded("seekToTime");
+ seek(Time);
+}
+
+bool SoundNode::getLoop() const
+{
+ return m_bLoop;
+}
+
+void SoundNode::setEOFCallback(PyObject * pEOFCallback)
+{
+ if (m_pEOFCallback) {
+ Py_DECREF(m_pEOFCallback);
+ }
+ if (pEOFCallback == Py_None) {
+ m_pEOFCallback = 0;
+ } else {
+ avgDeprecationWarning("1.8", "SoundNode.setEOFCallback()",
+ "Node.subscribe(END_OF_FILE)");
+ Py_INCREF(pEOFCallback);
+ m_pEOFCallback = pEOFCallback;
+ }
+}
+
+void SoundNode::connectDisplay()
+{
+ if (!AudioEngine::get()) {
+ throw Exception(AVG_ERR_UNSUPPORTED,
+ "Sound nodes can only be created if audio is not disabled.");
+ }
+ checkReload();
+ AreaNode::connectDisplay();
+ long long curTime = Player::get()->getFrameTime();
+ if (m_State != Unloaded) {
+ startDecoding();
+ m_StartTime = curTime;
+ m_PauseTime = 0;
+ }
+ if (m_State == Paused) {
+ m_PauseStartTime = curTime;
+ }
+}
+
+void SoundNode::connect(CanvasPtr pCanvas)
+{
+ checkReload();
+ AreaNode::connect(pCanvas);
+ pCanvas->registerFrameEndListener(this);
+}
+
+void SoundNode::disconnect(bool bKill)
+{
+ changeSoundState(Unloaded);
+ getCanvas()->unregisterFrameEndListener(this);
+ if (bKill) {
+ setEOFCallback(Py_None);
+ }
+ AreaNode::disconnect(bKill);
+}
+
+void SoundNode::play()
+{
+ changeSoundState(Playing);
+}
+
+void SoundNode::stop()
+{
+ changeSoundState(Unloaded);
+}
+
+void SoundNode::pause()
+{
+ changeSoundState(Paused);
+}
+
+const UTF8String& SoundNode::getHRef() const
+{
+ return m_href;
+}
+
+void SoundNode::setHRef(const UTF8String& href)
+{
+ m_href = href;
+ checkReload();
+}
+
+float SoundNode::getVolume()
+{
+ return m_Volume;
+}
+
+void SoundNode::setVolume(float volume)
+{
+ if (volume < 0) {
+ volume = 0;
+ }
+ m_Volume = volume;
+ if (m_AudioID != -1) {
+ AudioEngine::get()->setSourceVolume(m_AudioID, volume);
+ }
+}
+
+void SoundNode::checkReload()
+{
+ string fileName (m_href);
+ if (m_href != "") {
+ initFilename(fileName);
+ if (fileName != m_Filename && m_State != Unloaded) {
+ changeSoundState(Unloaded);
+ m_Filename = fileName;
+ changeSoundState(Paused);
+ } else {
+ m_Filename = fileName;
+ }
+ } else {
+ changeSoundState(Unloaded);
+ m_Filename = "";
+ }
+}
+
+void SoundNode::onFrameEnd()
+{
+ if (m_State == Playing) {
+ m_pDecoder->updateAudioStatus();
+ }
+ if (m_State == Playing && m_pDecoder->isEOF()) {
+ NodePtr pTempThis = getSharedThis();
+ onEOF();
+ }
+}
+
+void SoundNode::changeSoundState(SoundState newSoundState)
+{
+ if (newSoundState == m_State) {
+ return;
+ }
+ if (m_State == Unloaded) {
+ open();
+ }
+ if (newSoundState == Unloaded) {
+ close();
+ }
+ if (getState() == NS_CANRENDER) {
+ long long curTime = Player::get()->getFrameTime();
+ if (m_State == Unloaded) {
+ startDecoding();
+ m_StartTime = curTime;
+ m_PauseTime = 0;
+ }
+ if (newSoundState == Paused) {
+ m_PauseStartTime = curTime;
+ AudioEngine::get()->pauseSource(m_AudioID);
+ } else if (newSoundState == Playing && m_State == Paused) {
+ m_PauseTime += curTime-m_PauseStartTime;
+ AudioEngine::get()->playSource(m_AudioID);
+ }
+ }
+ m_State = newSoundState;
+}
+
+void SoundNode::seek(long long destTime)
+{
+ if (getState() == NS_CANRENDER) {
+ AudioEngine::get()->notifySeek(m_AudioID);
+ m_pDecoder->seek(float(destTime)/1000);
+ m_StartTime = Player::get()->getFrameTime() - destTime;
+ m_PauseTime = 0;
+ m_PauseStartTime = Player::get()->getFrameTime();
+ } else {
+ // If we get a seek command before decoding has really started, we need to defer
+ // the actual seek until the decoder is ready.
+ m_SeekBeforeCanRenderTime = destTime;
+ }
+}
+
+void SoundNode::open()
+{
+ m_pDecoder->open(m_Filename, false, true);
+ VideoInfo videoInfo = m_pDecoder->getVideoInfo();
+ if (!videoInfo.m_bHasAudio) {
+ throw Exception(AVG_ERR_VIDEO_GENERAL,
+ string("SoundNode: Opening "+m_Filename
+ +" failed. No audio stream found."));
+ }
+}
+
+void SoundNode::startDecoding()
+{
+ AudioEngine* pEngine = AudioEngine::get();
+ m_pDecoder->startDecoding(false, pEngine->getParams());
+ m_AudioID = pEngine->addSource(*m_pDecoder->getAudioMsgQ(),
+ *m_pDecoder->getAudioStatusQ());
+ pEngine->setSourceVolume(m_AudioID, m_Volume);
+ if (m_SeekBeforeCanRenderTime != 0) {
+ seek(m_SeekBeforeCanRenderTime);
+ m_SeekBeforeCanRenderTime = 0;
+ }
+}
+
+void SoundNode::close()
+{
+ if (m_AudioID != -1) {
+ AudioEngine::get()->removeSource(m_AudioID);
+ m_AudioID = -1;
+ }
+ m_pDecoder->close();
+}
+
+void SoundNode::exceptionIfUnloaded(const std::string& sFuncName) const
+{
+ if (m_State == Unloaded) {
+ throw Exception(AVG_ERR_VIDEO_GENERAL,
+ string("SoundNode.")+sFuncName+" failed: sound not loaded.");
+ }
+}
+
+void SoundNode::onEOF()
+{
+ seek(0);
+ if (!m_bLoop) {
+ changeSoundState(Paused);
+ }
+ if (m_pEOFCallback) {
+ PyObject * arglist = Py_BuildValue("()");
+ PyObject * result = PyEval_CallObject(m_pEOFCallback, arglist);
+ Py_DECREF(arglist);
+ if (!result) {
+ throw py::error_already_set();
+ }
+ Py_DECREF(result);
+ }
+ notifySubscribers("END_OF_FILE");
+}
+
+}
diff --git a/src/player/SoundNode.h b/src/player/SoundNode.h
new file mode 100644
index 0000000..66f9308
--- /dev/null
+++ b/src/player/SoundNode.h
@@ -0,0 +1,100 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _SoundNode_H_
+#define _SoundNode_H_
+
+#include "../api.h"
+
+#include "AreaNode.h"
+
+#include "../base/IFrameEndListener.h"
+#include "../base/UTF8String.h"
+
+namespace avg {
+
+class AsyncVideoDecoder;
+
+class AVG_API SoundNode : public AreaNode, IFrameEndListener
+{
+ public:
+ static void registerType();
+
+ SoundNode(const ArgList& args);
+ virtual ~SoundNode();
+
+ virtual void connectDisplay();
+ virtual void connect(CanvasPtr pCanvas);
+ virtual void disconnect(bool bKill);
+
+ void play();
+ void stop();
+ void pause();
+
+ const UTF8String& getHRef() const;
+ void setHRef(const UTF8String& href);
+ float getVolume();
+ void setVolume(float volume);
+ void checkReload();
+
+ long long getDuration() const;
+ std::string getAudioCodec() const;
+ int getAudioSampleRate() const;
+ int getNumAudioChannels() const;
+
+ long long getCurTime() const;
+ void seekToTime(long long Time);
+ bool getLoop() const;
+ void setEOFCallback(PyObject * pEOFCallback);
+
+ virtual void onFrameEnd();
+
+ private:
+ void seek(long long destTime);
+ void onEOF();
+
+ enum SoundState {Unloaded, Paused, Playing};
+ void changeSoundState(SoundState newSoundState);
+ void open();
+ void startDecoding();
+ void close();
+ void exceptionIfUnloaded(const std::string& sFuncName) const;
+
+ UTF8String m_href;
+ std::string m_Filename;
+ bool m_bLoop;
+ PyObject * m_pEOFCallback;
+ long long m_SeekBeforeCanRenderTime;
+
+ long long m_StartTime;
+ long long m_PauseTime;
+ long long m_PauseStartTime;
+
+ AsyncVideoDecoder* m_pDecoder;
+ float m_Volume;
+ SoundState m_State;
+ int m_AudioID;
+};
+
+}
+
+#endif
+
diff --git a/src/player/SubscriberInfo.cpp b/src/player/SubscriberInfo.cpp
new file mode 100644
index 0000000..85c0da2
--- /dev/null
+++ b/src/player/SubscriberInfo.cpp
@@ -0,0 +1,85 @@
+
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "SubscriberInfo.h"
+
+#include "../base/Exception.h"
+#include "../base/ObjectCounter.h"
+#include "../base/ScopeTimer.h"
+
+#include <boost/python/slice.hpp>
+
+using namespace std;
+
+namespace avg {
+
+py::object SubscriberInfo::s_MethodrefModule;
+
+SubscriberInfo::SubscriberInfo(int id, const py::object& callable)
+ : m_ID(id)
+{
+ ObjectCounter::get()->incRef(&typeid(*this));
+ if (s_MethodrefModule.ptr() == py::object().ptr()) {
+ s_MethodrefModule = py::import("libavg.methodref");
+ }
+ // Use the methodref module to manage the lifetime of the callables. This makes
+ // sure that we can delete bound-method callbacks when the object they are bound
+ // to disappears.
+ m_Callable = py::object(s_MethodrefModule.attr("methodref")(callable));
+}
+
+SubscriberInfo::~SubscriberInfo()
+{
+ ObjectCounter::get()->decRef(&typeid(*this));
+}
+
+bool SubscriberInfo::hasExpired() const
+{
+ py::object func = m_Callable();
+ return (func.ptr() == py::object().ptr());
+}
+
+static ProfilingZoneID InvokeSubscriberProfilingZone("SubscriberInfo: invoke");
+
+void SubscriberInfo::invoke(py::list args) const
+{
+ ScopeTimer timer(InvokeSubscriberProfilingZone);
+ py::object func = m_Callable();
+ py::tuple argsTuple(args);
+ py::object pyResult = func(*argsTuple);
+ if (pyResult.ptr() == 0) {
+ throw py::error_already_set();
+ }
+}
+
+int SubscriberInfo::getID() const
+{
+ return m_ID;
+}
+
+bool SubscriberInfo::isCallable(const py::object& callable) const
+{
+ bool bResult = py::call_method<bool>(m_Callable.ptr(), "isSameFunc", callable);
+ return bResult;
+}
+
+}
diff --git a/src/player/SubscriberInfo.h b/src/player/SubscriberInfo.h
new file mode 100644
index 0000000..a8dc388
--- /dev/null
+++ b/src/player/SubscriberInfo.h
@@ -0,0 +1,58 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _SubscriberInfo_H_
+#define _SubscriberInfo_H_
+
+#include "../api.h"
+
+#include "BoostPython.h"
+#include <boost/shared_ptr.hpp>
+
+// Python docs say python.h should be included before any standard headers (!)
+#include "WrapPython.h"
+
+#include <vector>
+
+namespace avg {
+
+class SubscriberInfo {
+public:
+ SubscriberInfo(int id, const py::object& callable);
+ virtual ~SubscriberInfo();
+
+ bool hasExpired() const;
+ void invoke(py::list args) const;
+ int getID() const;
+ bool isCallable(const py::object& callable) const;
+
+private:
+ int m_ID;
+ py::object m_Callable;
+ static py::object s_MethodrefModule;
+};
+
+typedef boost::shared_ptr<SubscriberInfo> SubscriberInfoPtr;
+}
+
+#endif
+
+
diff --git a/src/player/TUIOInputDevice.cpp b/src/player/TUIOInputDevice.cpp
new file mode 100644
index 0000000..f6f3f08
--- /dev/null
+++ b/src/player/TUIOInputDevice.cpp
@@ -0,0 +1,216 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "TUIOInputDevice.h"
+#include "TouchEvent.h"
+#include "Player.h"
+#include "AVGNode.h"
+#include "TouchStatus.h"
+
+#include "../base/Logger.h"
+#include "../base/StringHelper.h"
+#include "../base/OSHelper.h"
+#include "../base/ObjectCounter.h"
+#include "../base/Exception.h"
+
+using namespace std;
+using namespace osc;
+
+namespace avg {
+
+#ifndef WIN32
+void* TUIOInputDevice::threadFunc(void* p)
+#else
+DWORD WINAPI TUIOInputDevice::threadFunc(LPVOID p)
+#endif
+{
+ TUIOInputDevice* pThis = (TUIOInputDevice*)p;
+ pThis->m_pSocket->Run();
+ return 0;
+};
+
+TUIOInputDevice::TUIOInputDevice()
+ : m_pSocket(0),
+ m_LastID(0)
+{
+}
+
+TUIOInputDevice::~TUIOInputDevice()
+{
+ if (m_pSocket) {
+ m_pSocket->Break();
+ }
+}
+
+void TUIOInputDevice::start()
+{
+ string sPort("3333");
+ getEnv("AVG_TUIO_PORT", sPort);
+ int port;
+ try {
+ port = stringToInt(sPort);
+ } catch (Exception&) {
+ throw Exception(AVG_ERR_TYPE,
+ string("TUIO event source: AVG_TUIO_PORT set to invalid value '")
+ + sPort + "'");
+ }
+ MultitouchInputDevice::start();
+ try {
+ m_pSocket = new UdpListeningReceiveSocket(IpEndpointName(
+ IpEndpointName::ANY_ADDRESS, port), this);
+ } catch (std::exception &e) {
+ throw Exception(AVG_ERR_MT_INIT,
+ string("TUIO event source: Can't initialize networking. ") + e.what());
+ }
+ if (!m_pSocket->IsBound()) {
+ throw Exception(AVG_ERR_MT_INIT, "TUIO event source: Socket not bound.");
+ }
+ AVG_TRACE(Logger::category::CONFIG,Logger::severity::INFO,
+ "TUIO multitouch event source created, listening on port " << port);
+
+#ifndef WIN32
+ pthread_create(&m_Thread, NULL, threadFunc, this);
+#else
+ DWORD threadId;
+ m_Thread = CreateThread(0, 0, threadFunc, this, 0, &threadId);
+#endif
+}
+
+void TUIOInputDevice::ProcessPacket(const char* pData, int size,
+ const IpEndpointName& remoteEndpoint)
+{
+ lock_guard lock(getMutex());
+ try {
+ ReceivedPacket packet(pData, size);
+ if (packet.IsBundle()) {
+ processBundle(ReceivedBundle(packet), remoteEndpoint);
+ } else {
+ processMessage(ReceivedMessage(packet), remoteEndpoint);
+ }
+ } catch (osc::Exception& e) {
+ AVG_LOG_WARNING("OSC exception: " << e.what());
+ }
+}
+
+void TUIOInputDevice::processBundle(const ReceivedBundle& bundle,
+ const IpEndpointName& remoteEndpoint)
+{
+ try {
+ for (ReceivedBundle::const_iterator it = bundle.ElementsBegin();
+ it != bundle.ElementsEnd(); ++it)
+ {
+ if (it->IsBundle()) {
+ processBundle(ReceivedBundle(*it), remoteEndpoint);
+ } else {
+ processMessage(ReceivedMessage(*it), remoteEndpoint);
+ }
+ }
+ } catch (osc::Exception& e) {
+ AVG_LOG_WARNING("OSC exception: " << e.what());
+ }
+}
+
+void TUIOInputDevice::processMessage(const ReceivedMessage& msg,
+ const IpEndpointName& remoteEndpoint)
+{
+// cerr << msg << endl;
+ try {
+ ReceivedMessageArgumentStream args = msg.ArgumentStream();
+
+ if (strcmp(msg.AddressPattern(), "/tuio/2Dcur") == 0) {
+ const char* cmd;
+ args >> cmd;
+
+ if (strcmp(cmd,"set")==0) {
+ processSet(args);
+ } else if (strcmp(cmd,"alive")==0) {
+ processAlive(args);
+ } else if (strcmp(cmd, "fseq") == 0 ) {
+ int32 fseq;
+ args >> fseq;
+ }
+ }
+ } catch (osc::Exception& e) {
+ AVG_LOG_WARNING("Error parsing TUIO message: " << e.what()
+ << ". Message was " << msg);
+ }
+}
+
+void TUIOInputDevice::processSet(ReceivedMessageArgumentStream& args)
+{
+ osc::int32 tuioID;
+ float xpos, ypos;
+ float xspeed, yspeed;
+ float accel;
+ args >> tuioID >> xpos >> ypos >> xspeed >> yspeed >> accel;
+ glm::vec2 pos(xpos, ypos);
+ glm::vec2 speed(xspeed, yspeed);
+// cerr << "Set: ID: " << tuioID << ", pos: " << pos << ", speed: " << speed
+// << ", accel: " << accel << endl;
+ TouchStatusPtr pTouchStatus = getTouchStatus(tuioID);
+ if (!pTouchStatus) {
+ // Down
+ m_LastID++;
+ TouchEventPtr pEvent = createEvent(m_LastID, Event::CURSOR_DOWN, pos, speed);
+ addTouchStatus((long)tuioID, pEvent);
+ } else {
+ // Move
+ TouchEventPtr pEvent = createEvent(0, Event::CURSOR_MOTION, pos, speed);
+ pTouchStatus->pushEvent(pEvent);
+ }
+}
+
+void TUIOInputDevice::processAlive(ReceivedMessageArgumentStream& args)
+{
+ m_LiveTUIOIDs.clear();
+ int32 tuioID;
+ while (!args.Eos()) {
+ args >> tuioID;
+ m_LiveTUIOIDs.insert(tuioID);
+ }
+
+ // Create up events for all ids not in live list.
+ set<int> deadTUIOIDs;
+ getDeadIDs(m_LiveTUIOIDs, deadTUIOIDs);
+ set<int>::iterator it;
+ for (it = deadTUIOIDs.begin(); it != deadTUIOIDs.end(); ++it) {
+ int id = *it;
+ TouchStatusPtr pTouchStatus = getTouchStatus(id);
+ TouchEventPtr pOldEvent = pTouchStatus->getLastEvent();
+ TouchEventPtr pUpEvent = boost::dynamic_pointer_cast<TouchEvent>(
+ pOldEvent->cloneAs(Event::CURSOR_UP));
+ pTouchStatus->pushEvent(pUpEvent);
+ removeTouchStatus(id);
+ }
+}
+
+TouchEventPtr TUIOInputDevice::createEvent(int id, Event::Type type, glm::vec2 pos,
+ glm::vec2 speed)
+{
+ const glm::vec2 size = getTouchArea();
+ IntPoint screenPos = getScreenPos(pos);
+ glm::vec2 screenSpeed(int(speed.x*size.x+0.5), int(speed.y*size.y+0.5));
+ TouchEventPtr pEvent(new TouchEvent(id, type, screenPos, Event::TOUCH));
+ pEvent->setSpeed(screenSpeed/1000.f);
+ return pEvent;
+}
+
+}
diff --git a/src/player/TUIOInputDevice.h b/src/player/TUIOInputDevice.h
new file mode 100644
index 0000000..7315345
--- /dev/null
+++ b/src/player/TUIOInputDevice.h
@@ -0,0 +1,80 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _TUIOInputDevice_H_
+#define _TUIOInputDevice_H_
+
+#include "../api.h"
+#include "MultitouchInputDevice.h"
+#include "Event.h"
+#include "../oscpack/UdpSocket.h"
+#include "../oscpack/PacketListener.h"
+#include "../oscpack/OscReceivedElements.h"
+#include "../oscpack/OscPrintReceivedElements.h"
+
+#ifdef WIN32
+#include <windows.h>
+#endif
+
+#include <set>
+
+namespace avg {
+
+class AVG_API TUIOInputDevice: public MultitouchInputDevice, PacketListener
+{
+public:
+ TUIOInputDevice();
+ virtual ~TUIOInputDevice();
+ virtual void start();
+
+ virtual void ProcessPacket(const char* pData, int size,
+ const IpEndpointName& remoteEndpoint);
+
+private:
+#ifndef WIN32
+ static void* threadFunc(void* p);
+#else
+ static DWORD WINAPI threadFunc(LPVOID p);
+#endif
+ void processBundle(const osc::ReceivedBundle& bundle,
+ const IpEndpointName& remoteEndpoint);
+ void processMessage(const osc::ReceivedMessage& msg,
+ const IpEndpointName& remoteEndpoint);
+ void processSet(osc::ReceivedMessageArgumentStream& args);
+ void processAlive(osc::ReceivedMessageArgumentStream& args);
+ TouchEventPtr createEvent(int id, Event::Type type, glm::vec2 pos, glm::vec2 speed);
+
+ UdpListeningReceiveSocket* m_pSocket;
+ int m_LastID;
+ std::set<int> m_LiveTUIOIDs;
+#ifndef WIN32
+ pthread_t m_Thread;
+#else
+ HANDLE m_Thread;
+#endif
+};
+
+typedef boost::shared_ptr<TUIOInputDevice> TUIOInputDevicePtr;
+
+}
+
+#endif
+
diff --git a/src/player/TestHelper.cpp b/src/player/TestHelper.cpp
new file mode 100644
index 0000000..342e7fd
--- /dev/null
+++ b/src/player/TestHelper.cpp
@@ -0,0 +1,152 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "TestHelper.h"
+#include "Player.h"
+#include "MouseEvent.h"
+#include "TouchEvent.h"
+#include "KeyEvent.h"
+#include "TouchStatus.h"
+
+#include "../base/Exception.h"
+#include "../base/ObjectCounter.h"
+
+#include <iostream>
+#ifdef WIN32
+#undef max
+#endif
+#include <limits>
+
+using namespace std;
+
+namespace avg {
+
+TestHelper::TestHelper()
+ : IInputDevice(EXTRACT_INPUTDEVICE_CLASSNAME(TestHelper))
+{
+}
+
+TestHelper::~TestHelper()
+{
+}
+
+void TestHelper::reset()
+{
+ m_Touches.clear();
+}
+
+void TestHelper::fakeMouseEvent(Event::Type eventType,
+ bool leftButtonState, bool middleButtonState,
+ bool rightButtonState,
+ int xPosition, int yPosition, int button)
+{
+ checkEventType(eventType);
+ MouseEventPtr pEvent(new MouseEvent(eventType, leftButtonState,
+ middleButtonState, rightButtonState, IntPoint(xPosition, yPosition), button));
+ m_Events.push_back(pEvent);
+}
+
+void TestHelper::fakeTouchEvent(int id, Event::Type eventType,
+ Event::Source source, const glm::vec2& pos, const glm::vec2& speed)
+{
+ checkEventType(eventType);
+ // The id is modified to avoid collisions with real touch events.
+ TouchEventPtr pEvent(new TouchEvent(id+std::numeric_limits<int>::max()/2, eventType,
+ IntPoint(pos), source, speed));
+ map<int, TouchStatusPtr>::iterator it = m_Touches.find(pEvent->getCursorID());
+ switch (pEvent->getType()) {
+ case Event::CURSOR_DOWN: {
+ AVG_ASSERT(it == m_Touches.end());
+ TouchStatusPtr pTouchStatus(new TouchStatus(pEvent));
+ m_Touches[pEvent->getCursorID()] = pTouchStatus;
+ }
+ break;
+ case Event::CURSOR_MOTION:
+ case Event::CURSOR_UP: {
+ if (it == m_Touches.end()) {
+ cerr << "borked: " << pEvent->getCursorID() << ", " <<
+ pEvent->typeStr() << endl;
+ }
+ AVG_ASSERT(it != m_Touches.end());
+ TouchStatusPtr pTouchStatus = (*it).second;
+ pTouchStatus->pushEvent(pEvent);
+ }
+ break;
+ default:
+ AVG_ASSERT(false);
+ break;
+ }
+}
+
+void TestHelper::fakeKeyEvent(Event::Type eventType,
+ unsigned char scanCode, int keyCode,
+ const string& keyString, int unicode, int modifiers)
+{
+ KeyEventPtr pEvent(new KeyEvent(eventType, scanCode, keyCode,
+ keyString, unicode, modifiers));
+ m_Events.push_back(pEvent);
+}
+
+void TestHelper::dumpObjects()
+{
+ cerr << ObjectCounter::get()->dump();
+}
+
+TypeMap TestHelper::getObjectCount()
+{
+ return ObjectCounter::get()->getObjectCount();
+}
+
+// From IInputDevice
+std::vector<EventPtr> TestHelper::pollEvents()
+{
+ vector<EventPtr> events = m_Events;
+ map<int, TouchStatusPtr>::iterator it;
+ for (it = m_Touches.begin(); it != m_Touches.end(); ) {
+ TouchStatusPtr pTouchStatus = it->second;
+ CursorEventPtr pEvent = pTouchStatus->pollEvent();
+ if (pEvent) {
+ events.push_back(pEvent);
+ if (pEvent->getType() == Event::CURSOR_UP) {
+ m_Touches.erase(it++);
+ } else {
+ ++it;
+ }
+ } else {
+ ++it;
+ }
+ }
+
+ m_Events.clear();
+ return events;
+}
+
+void TestHelper::checkEventType(Event::Type eventType)
+{
+ if (eventType == Event::CURSOR_OVER || eventType == Event::CURSOR_OUT) {
+ throw Exception(AVG_ERR_UNSUPPORTED, "TestHelper::fakeXxxEvent: Can't send "
+ "CURSOR_OVER and CURSOR_OUT events directly. They are generated "
+ "internally.");
+ }
+}
+
+}
+
diff --git a/src/player/TestHelper.h b/src/player/TestHelper.h
new file mode 100644
index 0000000..f0741e9
--- /dev/null
+++ b/src/player/TestHelper.h
@@ -0,0 +1,76 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _TestHelper_H_
+#define _TestHelper_H_
+
+#include "../api.h"
+#include "../base/ObjectCounter.h"
+#include "../graphics/Bitmap.h"
+#include "Event.h"
+#include "IInputDevice.h"
+
+#include <boost/shared_ptr.hpp>
+
+#include <vector>
+#include <map>
+
+namespace avg {
+
+class TouchStatus;
+typedef boost::shared_ptr<class TouchStatus> TouchStatusPtr;
+class CursorEvent;
+typedef boost::shared_ptr<class CursorEvent> CursorEventPtr;
+
+class AVG_API TestHelper : public IInputDevice
+{
+ public:
+ TestHelper();
+ virtual ~TestHelper();
+ void reset();
+
+ void fakeMouseEvent(Event::Type eventType,
+ bool leftButtonState, bool middleButtonState,
+ bool rightButtonState,
+ int xPosition, int yPosition, int button);
+ void fakeTouchEvent(int id, Event::Type eventType, Event::Source source,
+ const glm::vec2& pos, const glm::vec2& speed=glm::vec2(0, 0));
+ void fakeKeyEvent(Event::Type eventType,
+ unsigned char scanCode, int keyCode,
+ const std::string& keyString, int unicode, int modifiers);
+ void dumpObjects();
+ TypeMap getObjectCount();
+
+ // From IInputDevice
+ virtual std::vector<EventPtr> pollEvents();
+
+ private:
+ void checkEventType(Event::Type eventType);
+
+ std::vector<EventPtr> m_Events;
+ std::map<int, TouchStatusPtr> m_Touches;
+};
+
+typedef boost::shared_ptr<TestHelper> TestHelperPtr;
+}
+
+#endif
+
diff --git a/src/player/TextEngine.cpp b/src/player/TextEngine.cpp
new file mode 100644
index 0000000..226b0de
--- /dev/null
+++ b/src/player/TextEngine.cpp
@@ -0,0 +1,313 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "TextEngine.h"
+
+#include "../base/Logger.h"
+#include "../base/OSHelper.h"
+#include "../base/Exception.h"
+#include "../base/FileHelper.h"
+#include "../base/StringHelper.h"
+
+#include <algorithm>
+
+namespace avg {
+
+using namespace std;
+
+static void
+text_subst_func_hint(FcPattern *pattern, gpointer data)
+{
+ FcPatternAddBool(pattern, FC_HINTING, true);
+ FcPatternAddInteger(pattern, FC_HINT_STYLE, FC_HINT_MEDIUM);
+ FcPatternAddInteger(pattern, FC_RGBA, FC_RGBA_NONE);
+ FcPatternAddBool(pattern, FC_ANTIALIAS, true);
+}
+
+static void
+text_subst_func_nohint(FcPattern *pattern, gpointer data)
+{
+ FcPatternAddBool(pattern, FC_HINTING, false);
+ FcPatternAddBool(pattern, FC_AUTOHINT, false);
+ FcPatternAddInteger(pattern, FC_HINT_STYLE, FC_HINT_NONE);
+ FcPatternAddInteger(pattern, FC_RGBA, FC_RGBA_NONE);
+ FcPatternAddBool(pattern, FC_ANTIALIAS, true);
+}
+
+TextEngine& TextEngine::get(bool bHint)
+{
+ if (bHint) {
+ static TextEngine s_Instance(true);
+ return s_Instance;
+ } else {
+ static TextEngine s_Instance(false);
+ return s_Instance;
+ }
+}
+
+
+TextEngine::TextEngine(bool bHint)
+ : m_bHint(bHint)
+{
+ m_sFontDirs.push_back("fonts/");
+ init();
+}
+
+TextEngine::~TextEngine()
+{
+ deinit();
+}
+
+void TextEngine::init()
+{
+ m_pFontMap = PANGO_FT2_FONT_MAP(pango_ft2_font_map_new());
+ pango_ft2_font_map_set_resolution(m_pFontMap, 72, 72);
+ if (m_bHint) {
+ pango_ft2_font_map_set_default_substitute(m_pFontMap, text_subst_func_hint,
+ 0, 0);
+ } else {
+ pango_ft2_font_map_set_default_substitute(m_pFontMap, text_subst_func_nohint,
+ 0, 0);
+ }
+#if PANGO_VERSION > PANGO_VERSION_ENCODE(1,22,0)
+ m_pPangoContext = pango_font_map_create_context(PANGO_FONT_MAP(m_pFontMap));
+#else
+ m_pPangoContext = pango_ft2_font_map_create_context(m_pFontMap);
+#endif
+
+ pango_context_set_language(m_pPangoContext,
+ pango_language_from_string ("en_US"));
+ pango_context_set_base_dir(m_pPangoContext, PANGO_DIRECTION_LTR);
+
+ initFonts();
+
+ string sOldLang = "";
+ getEnv("LC_CTYPE", sOldLang);
+ setEnv("LC_CTYPE", "en-us");
+ pango_font_map_list_families(PANGO_FONT_MAP(m_pFontMap), &m_ppFontFamilies,
+ &m_NumFontFamilies);
+ setEnv("LC_CTYPE", sOldLang);
+ for (int i = 0; i < m_NumFontFamilies; ++i) {
+ m_sFonts.push_back(pango_font_family_get_name(m_ppFontFamilies[i]));
+ }
+ sort(m_sFonts.begin(), m_sFonts.end());
+}
+
+void TextEngine::deinit()
+{
+ g_object_unref(m_pFontMap);
+ g_free(m_ppFontFamilies);
+ g_object_unref(m_pPangoContext);
+ m_sFonts.clear();
+}
+
+void TextEngine::addFontDir(const std::string& sDir)
+{
+ deinit();
+ m_sFontDirs.push_back(sDir);
+ init();
+}
+
+PangoContext * TextEngine::getPangoContext()
+{
+ return m_pPangoContext;
+}
+
+const vector<string>& TextEngine::getFontFamilies()
+{
+ return m_sFonts;
+}
+
+const vector<string>& TextEngine::getFontVariants(const string& sFontName)
+{
+ PangoFontFamily * pCurFamily = getFontFamily(sFontName);
+ PangoFontFace ** ppFaces;
+ int numFaces;
+ pango_font_family_list_faces (pCurFamily, &ppFaces, &numFaces);
+ static vector<string> sVariants;
+ for (int i = 0; i < numFaces; ++i) {
+ sVariants.push_back(pango_font_face_get_face_name(ppFaces[i]));
+ }
+ g_free(ppFaces);
+ return sVariants;
+}
+
+PangoFontDescription * TextEngine::getFontDescription(const string& sFamily,
+ const string& sVariant)
+{
+ PangoFontDescription* pDescription;
+ FontDescriptionCache::iterator it;
+ it = m_FontDescriptionCache.find(pair<string, string>(sFamily, sVariant));
+ if (it == m_FontDescriptionCache.end()) {
+ PangoFontFamily * pFamily;
+ bool bFamilyFound = true;
+ try {
+ pFamily = getFontFamily(sFamily);
+ } catch (Exception&) {
+ if (m_sFontsNotFound.find(sFamily) == m_sFontsNotFound.end()) {
+ AVG_LOG_WARNING("Could not find font face " << sFamily <<
+ ". Using sans instead.");
+ m_sFontsNotFound.insert(sFamily);
+ }
+ bFamilyFound = false;
+ pFamily = getFontFamily("sans");
+ }
+ PangoFontFace ** ppFaces;
+ int numFaces;
+ pango_font_family_list_faces(pFamily, &ppFaces, &numFaces);
+ PangoFontFace * pFace = 0;
+ if (sVariant == "") {
+ pFace = ppFaces[0];
+ } else {
+ for (int i = 0; i < numFaces; ++i) {
+ if (equalIgnoreCase(pango_font_face_get_face_name(ppFaces[i]), sVariant)) {
+ pFace = ppFaces[i];
+ }
+ }
+ }
+ if (!pFace) {
+ pFace = ppFaces[0];
+ if (bFamilyFound) {
+ pair<string, string> variant(sFamily, sVariant);
+ if (m_VariantsNotFound.find(variant) == m_VariantsNotFound.end()) {
+ m_VariantsNotFound.insert(variant);
+ AVG_LOG_WARNING("Could not find font variant "
+ << sFamily << ":" << sVariant << ". Using " <<
+ pango_font_face_get_face_name(pFace) << " instead.");
+ }
+ }
+ }
+ g_free(ppFaces);
+ pDescription = pango_font_face_describe(pFace);
+ m_FontDescriptionCache[pair<string, string>(sFamily, sVariant)] =
+ pDescription;
+ } else {
+ pDescription = it->second;
+ }
+ return pango_font_description_copy(pDescription);
+}
+
+void GLibLogFunc(const gchar *log_domain, GLogLevelFlags log_level,
+ const gchar *message, gpointer unused_data)
+{
+//TODO: Make this use correct AVG_LOG_LEVEL function
+#ifndef WIN32
+ string s = "Pango ";
+ if (log_level & G_LOG_LEVEL_ERROR) {
+ s += message;
+ AVG_LOG_ERROR(s);
+ return;
+ } else if (log_level & G_LOG_LEVEL_CRITICAL) {
+ s += message;
+ AVG_LOG_ERROR(s);
+ AVG_ASSERT(false);
+ } else if (log_level & G_LOG_LEVEL_WARNING) {
+ s += message;
+ AVG_LOG_WARNING(s);
+ return;
+ } else if (log_level & G_LOG_LEVEL_MESSAGE) {
+ s += (string("message: ") + message);
+ AVG_LOG_INFO(s);
+ return;
+ } else if (log_level & G_LOG_LEVEL_INFO) {
+ s += message;
+ AVG_LOG_INFO(s);
+ return;
+ } else if (log_level & G_LOG_LEVEL_DEBUG) {
+ s += message;
+ AVG_TRACE(Logger::category::NONE, Logger::severity::DEBUG, s);
+ return;
+ }
+ s += message;
+ AVG_LOG_WARNING(s);
+#endif
+}
+
+void TextEngine::initFonts()
+{
+ std::vector<std::string> fontConfPathPrefixList;
+#ifndef WIN32
+ fontConfPathPrefixList.push_back("/");
+ fontConfPathPrefixList.push_back("/usr/local/");
+ fontConfPathPrefixList.push_back("/opt/local/");
+#endif
+ fontConfPathPrefixList.push_back(getAvgLibPath());
+
+ std::string sFontConfPath;
+ for (size_t i = 0; i < fontConfPathPrefixList.size(); ++i) {
+ sFontConfPath = fontConfPathPrefixList[i] + "etc/fonts/fonts.conf";
+ if (fileExists(sFontConfPath)) {
+ break;
+ }
+ }
+
+ FcConfig * pConfig = FcConfigCreate();
+ int ok = (int)FcConfigParseAndLoad(pConfig,
+ (const FcChar8 *)(sFontConfPath.c_str()), true);
+ checkFontError(ok, string("Font error: could not load config file ")+sFontConfPath);
+ ok = (int)FcConfigBuildFonts(pConfig);
+ checkFontError(ok, string("Font error: FcConfigBuildFonts failed."));
+ ok = (int)FcConfigSetCurrent(pConfig);
+ checkFontError(ok, string("Font error: FcConfigSetCurrent failed."));
+ for(std::vector<std::string>::const_iterator it = m_sFontDirs.begin();
+ it != m_sFontDirs.end(); ++it)
+ {
+ ok = (int)FcConfigAppFontAddDir(pConfig, (const FcChar8 *)it->c_str());
+ checkFontError(ok, string("Font error: FcConfigAppFontAddDir("
+ + *it + ") failed."));
+ }
+ /*
+ FcStrList * pCacheDirs = FcConfigGetCacheDirs(pConfig);
+ FcChar8 * pDir;
+ do {
+ pDir = FcStrListNext(pCacheDirs);
+ if (pDir) {
+ cerr << pDir << endl;
+ }
+ } while (pDir);
+ */
+ g_log_set_default_handler(GLibLogFunc, 0);
+}
+
+PangoFontFamily * TextEngine::getFontFamily(const string& sFamily)
+{
+ PangoFontFamily * pFamily = 0;
+ AVG_ASSERT(m_NumFontFamilies != 0);
+ for (int i=0; i<m_NumFontFamilies; ++i) {
+ if (equalIgnoreCase(pango_font_family_get_name(m_ppFontFamilies[i]), sFamily)) {
+ pFamily = m_ppFontFamilies[i];
+ }
+ }
+ if (!pFamily) {
+ throw(Exception(AVG_ERR_INVALID_ARGS,
+ "getFontFamily: Font family "+sFamily+" not found."));
+ }
+ return pFamily;
+}
+
+void TextEngine::checkFontError(int ok, const string& sMsg)
+{
+ if (ok == 0) {
+ throw Exception(AVG_ERR_FONT_INIT_FAILED, sMsg);
+ }
+}
+
+}
diff --git a/src/player/TextEngine.h b/src/player/TextEngine.h
new file mode 100644
index 0000000..4fef426
--- /dev/null
+++ b/src/player/TextEngine.h
@@ -0,0 +1,76 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _TextEngine_H_
+#define _TextEngine_H_
+
+#include <pango/pango.h>
+#include <pango/pangoft2.h>
+#include <fontconfig/fontconfig.h>
+
+#include <vector>
+#include <string>
+#include <set>
+#include <map>
+
+namespace avg {
+
+class TextEngine {
+public:
+ static TextEngine& get(bool bHint);
+ virtual ~TextEngine();
+
+ PangoContext * getPangoContext();
+
+ const std::vector<std::string>& getFontFamilies();
+ const std::vector<std::string>& getFontVariants(const std::string& sFontName);
+ void addFontDir(const std::string& sDir);
+
+ PangoFontDescription * getFontDescription(const std::string& sFamily,
+ const std::string& sVariant);
+ void FT2SubstituteFunc(FcPattern *pattern, gpointer data);
+
+private:
+ TextEngine(bool bHint);
+ void init();
+ void deinit();
+ void initFonts();
+ PangoFontFamily * getFontFamily(const std::string& sFamily);
+
+ void checkFontError(int Ok, const std::string& sMsg);
+
+ bool m_bHint;
+ PangoContext * m_pPangoContext;
+ PangoFT2FontMap * m_pFontMap;
+ std::set<std::string> m_sFontsNotFound;
+ std::set<std::pair<std::string, std::string> > m_VariantsNotFound;
+ int m_NumFontFamilies;
+ std::vector<std::string> m_sFonts;
+ typedef std::map<std::pair<std::string, std::string>, PangoFontDescription* >
+ FontDescriptionCache;
+ FontDescriptionCache m_FontDescriptionCache;
+ PangoFontFamily** m_ppFontFamilies;
+ std::vector<std::string> m_sFontDirs;
+
+};
+
+}
+#endif
diff --git a/src/player/Timeout.cpp b/src/player/Timeout.cpp
new file mode 100644
index 0000000..9820699
--- /dev/null
+++ b/src/player/Timeout.cpp
@@ -0,0 +1,93 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "Timeout.h"
+
+#include "BoostPython.h"
+
+#include "../base/Exception.h"
+#include "../base/ObjectCounter.h"
+
+#include <iostream>
+
+using namespace std;
+
+namespace avg {
+
+// Hack to make sure ids don't overlap with publisher/subsriber ids
+int Timeout::s_LastID = 100000;
+
+Timeout::Timeout(int time, PyObject * pyfunc, bool isInterval, long long startTime)
+ : m_Interval(time),
+ m_PyFunc(pyfunc),
+ m_IsInterval(isInterval)
+{
+ ObjectCounter::get()->incRef(&typeid(*this));
+ m_NextTimeout = m_Interval+startTime;
+ s_LastID++;
+ m_ID = s_LastID;
+
+ Py_INCREF(m_PyFunc);
+}
+
+Timeout::~Timeout()
+{
+ Py_DECREF(m_PyFunc);
+ ObjectCounter::get()->decRef(&typeid(*this));
+}
+
+bool Timeout::isReady(long long time) const
+{
+ return m_NextTimeout <= time;
+}
+
+bool Timeout::isInterval() const
+{
+ return m_IsInterval;
+}
+
+void Timeout::fire(long long curTime)
+{
+ if (m_IsInterval) {
+ m_NextTimeout = m_Interval + curTime;
+ }
+ PyObject * arglist = Py_BuildValue("()");
+ PyObject * result = PyEval_CallObject(m_PyFunc, arglist);
+ // XXX: After the call to python, this might have been deleted
+ // by a call to clearTimeout()!
+ Py_DECREF(arglist);
+ if (!result) {
+ throw py::error_already_set();
+ }
+ Py_DECREF(result);
+}
+
+int Timeout::getID() const
+{
+ return m_ID;
+}
+
+bool Timeout::operator <(const Timeout& other) const
+{
+ return m_NextTimeout < other.m_NextTimeout;
+}
+
+}
diff --git a/src/player/Timeout.h b/src/player/Timeout.h
new file mode 100644
index 0000000..9682d76
--- /dev/null
+++ b/src/player/Timeout.h
@@ -0,0 +1,54 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _Timeout_H_
+#define _Timeout_H_
+
+// Python docs say python.h should be included before any standard headers (!)
+#include "WrapPython.h"
+#include "../api.h"
+
+namespace avg {
+
+class AVG_API Timeout
+{
+ public:
+ Timeout (int time, PyObject * pyfunc, bool isInterval, long long startTime);
+ virtual ~Timeout ();
+
+ bool isReady(long long time) const;
+ bool isInterval() const;
+ void fire(long long curTime);
+ int getID() const;
+ bool operator <(const Timeout& other) const;
+
+ private:
+ long long m_Interval;
+ long long m_NextTimeout;
+ PyObject * m_PyFunc;
+ bool m_IsInterval;
+ int m_ID;
+ static int s_LastID;
+};
+
+}
+
+#endif //_Timeout_H_
diff --git a/src/player/TouchEvent.cpp b/src/player/TouchEvent.cpp
new file mode 100644
index 0000000..c2541df
--- /dev/null
+++ b/src/player/TouchEvent.cpp
@@ -0,0 +1,202 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+// Original author of this file is igor@c-base.org
+//
+
+#include "TouchEvent.h"
+
+#include "Player.h"
+#include "AVGNode.h"
+
+#include "../graphics/Bitmap.h"
+#include "../graphics/Filterfill.h"
+#include "../graphics/Pixel8.h"
+#include "../base/Exception.h"
+
+#include "../base/Logger.h"
+
+using namespace std;
+
+namespace avg {
+
+TouchEvent::TouchEvent(int id, Type eventType, BlobPtr pBlob, const IntPoint& pos,
+ Source source, const glm::vec2& speed)
+ : CursorEvent(id, eventType, pos, source),
+ m_pBlob(pBlob),
+ m_bHasHandOrientation(false)
+{
+ setSpeed(speed);
+ if (pBlob) {
+ m_Orientation = pBlob->getOrientation();
+ m_Area = pBlob->getArea();
+ m_Center = pBlob->getCenter();
+ m_Eccentricity = pBlob->getEccentricity();
+ const glm::vec2& axis0 = m_pBlob->getScaledBasis(0);
+ const glm::vec2& axis1 = m_pBlob->getScaledBasis(1);
+ if (glm::length(axis0) > glm::length(axis1)) {
+ m_MajorAxis = axis0;
+ m_MinorAxis = axis1;
+ } else {
+ m_MajorAxis = axis1;
+ m_MinorAxis = axis0;
+ }
+ } else {
+ m_Orientation = 0;
+ m_Area = 20;
+ m_Center = glm::vec2(0, 0);
+ m_Eccentricity = 0;
+ m_MajorAxis = glm::vec2(5, 0);
+ m_MinorAxis = glm::vec2(0, 5);
+ }
+}
+
+TouchEvent::TouchEvent(int id, Type eventType, const IntPoint& pos, Source source,
+ const glm::vec2& speed, float orientation, float area, float eccentricity,
+ glm::vec2 majorAxis, glm::vec2 minorAxis)
+ : CursorEvent(id, eventType, pos, source),
+ m_Orientation(orientation),
+ m_Area(area),
+ m_Eccentricity(eccentricity),
+ m_MajorAxis(majorAxis),
+ m_MinorAxis(minorAxis)
+{
+ setSpeed(speed);
+}
+
+TouchEvent::TouchEvent(int id, Type eventType, const IntPoint& pos, Source source,
+ const glm::vec2& speed)
+ : CursorEvent(id, eventType, pos, source),
+ m_Orientation(0),
+ m_Area(20),
+ m_Eccentricity(0),
+ m_MajorAxis(5, 0),
+ m_MinorAxis(0, 5)
+{
+ setSpeed(speed);
+}
+
+TouchEvent::~TouchEvent()
+{
+}
+
+CursorEventPtr TouchEvent::cloneAs(Type eventType) const
+{
+ TouchEventPtr pClone(new TouchEvent(*this));
+ pClone->m_Type = eventType;
+ return pClone;
+}
+
+float TouchEvent::getOrientation() const
+{
+ return m_Orientation;
+}
+
+float TouchEvent::getArea() const
+{
+ return m_Area;
+}
+
+const glm::vec2 & TouchEvent::getCenter() const
+{
+ return m_Center;
+}
+
+float TouchEvent::getEccentricity() const
+{
+ return m_Eccentricity;
+}
+
+const glm::vec2 & TouchEvent::getMajorAxis() const
+{
+ return m_MajorAxis;
+}
+
+const glm::vec2 & TouchEvent::getMinorAxis() const
+{
+ return m_MinorAxis;
+}
+
+const BlobPtr TouchEvent::getBlob() const
+{
+ return m_pBlob;
+}
+
+ContourSeq TouchEvent::getContour()
+{
+ if (m_pBlob) {
+ return m_pBlob->getContour();
+ } else {
+ throw Exception(AVG_ERR_UNSUPPORTED,
+ "TouchEvent::getContour: No contour available.");
+ }
+}
+
+float TouchEvent::getHandOrientation() const
+{
+ if (getSource() == Event::TOUCH) {
+ if (m_bHasHandOrientation) {
+ return m_HandOrientation;
+ } else {
+ glm::vec2 screenCenter = Player::get()->getRootNode()->getSize()/2.f;
+ return getAngle(getPos()-screenCenter);
+ }
+ } else {
+ throw Exception(AVG_ERR_UNSUPPORTED,
+ "TouchEvent::getHandOrientation: Only supported for touch events.");
+ }
+}
+
+void TouchEvent::addRelatedEvent(TouchEventPtr pEvent)
+{
+ m_RelatedEvents.push_back(pEvent);
+ if (getSource() == Event::TOUCH && m_RelatedEvents.size() == 1) {
+ TouchEventPtr pHandEvent = m_RelatedEvents.begin()->lock();
+ m_HandOrientation = getAngle(pHandEvent->getPos()-getPos());
+ m_bHasHandOrientation = true;
+ }
+}
+
+vector<TouchEventPtr> TouchEvent::getRelatedEvents() const
+{
+ vector<TouchEventPtr> pRelatedEvents;
+ vector<TouchEventWeakPtr>::const_iterator it;
+ for (it = m_RelatedEvents.begin(); it != m_RelatedEvents.end(); ++it) {
+ pRelatedEvents.push_back((*it).lock());
+ }
+ return pRelatedEvents;
+}
+
+void TouchEvent::removeBlob()
+{
+ m_pBlob = BlobPtr();
+}
+
+void TouchEvent::trace()
+{
+ CursorEvent::trace();
+ AVG_TRACE(Logger::category::EVENTS,Logger::severity::DEBUG, "pos: " << getPos()
+ << ", ID: " << getCursorID()
+ << ", Area: " << m_Area
+ << ", Eccentricity: " << m_Eccentricity);
+}
+
+}
+
diff --git a/src/player/TouchEvent.h b/src/player/TouchEvent.h
new file mode 100644
index 0000000..730883a
--- /dev/null
+++ b/src/player/TouchEvent.h
@@ -0,0 +1,87 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+// Original author of this file is igor@c-base.org
+//
+
+#ifndef _TouchEvent_H_
+#define _TouchEvent_H_
+
+#include "../api.h"
+#include "CursorEvent.h"
+
+#include "../imaging/Blob.h"
+#include "../base/GLMHelper.h"
+
+#include <math.h>
+#include <boost/weak_ptr.hpp>
+
+namespace avg {
+
+class TouchEvent;
+typedef boost::shared_ptr<class TouchEvent> TouchEventPtr;
+typedef boost::weak_ptr<class TouchEvent> TouchEventWeakPtr;
+
+class AVG_API TouchEvent: public CursorEvent
+{
+ public:
+ TouchEvent(int id, Type eventType, BlobPtr pBlob, const IntPoint& pos,
+ Source source, const glm::vec2& speed=glm::vec2(0,0));
+ TouchEvent(int id, Type eventType, const IntPoint& pos, Source source,
+ const glm::vec2& speed, float orientation, float area,
+ float eccentricity, glm::vec2 majorAxis, glm::vec2 minorAxis);
+ TouchEvent(int id, Type eventType, const IntPoint& pos, Source source,
+ const glm::vec2& speed=glm::vec2(0, 0));
+ virtual ~TouchEvent();
+ virtual CursorEventPtr cloneAs(Type eventType) const;
+
+ float getOrientation() const;
+ float getArea() const;
+ const glm::vec2 & getCenter() const;
+ float getEccentricity() const;
+ const glm::vec2 & getMajorAxis() const;
+ const glm::vec2 & getMinorAxis() const;
+
+ const BlobPtr getBlob() const;
+ ContourSeq getContour();
+ float getHandOrientation() const;
+
+ void addRelatedEvent(TouchEventPtr pEvent);
+ std::vector<TouchEventPtr> getRelatedEvents() const;
+
+ void removeBlob();
+
+ virtual void trace();
+
+ private:
+ BlobPtr m_pBlob;
+ float m_Orientation;
+ float m_Area;
+ glm::vec2 m_Center;
+ float m_Eccentricity;
+ glm::vec2 m_MajorAxis;
+ glm::vec2 m_MinorAxis;
+ std::vector<TouchEventWeakPtr> m_RelatedEvents;
+ bool m_bHasHandOrientation;
+ float m_HandOrientation;
+};
+
+}
+#endif
diff --git a/src/player/TouchStatus.cpp b/src/player/TouchStatus.cpp
new file mode 100644
index 0000000..ff08bc9
--- /dev/null
+++ b/src/player/TouchStatus.cpp
@@ -0,0 +1,109 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "TouchStatus.h"
+
+#include "TouchEvent.h"
+#include "BoostPython.h"
+#include "Player.h"
+
+#include "../base/Exception.h"
+#include "../base/StringHelper.h"
+
+#include <iostream>
+
+using namespace std;
+
+namespace avg {
+
+TouchStatus::TouchStatus(TouchEventPtr pEvent)
+ : m_bFirstFrame(true),
+ m_CursorID(pEvent->getCursorID())
+{
+ m_pNewEvents.push_back(pEvent);
+ m_pLastEvent = pEvent;
+}
+
+TouchStatus::~TouchStatus()
+{
+}
+
+void TouchStatus::pushEvent(TouchEventPtr pEvent, bool bCheckMotion)
+{
+ AVG_ASSERT(pEvent);
+ pEvent->setCursorID(m_CursorID);
+
+ if (m_bFirstFrame) {
+ // Ignore unless cursorup.
+ if (pEvent->getType() == Event::CURSOR_UP) {
+ // Down and up in the first frame. To avoid inconsistencies, both
+ // messages must be delivered. This is the only time that m_pNewEvents
+ // has more than one entry.
+ m_pNewEvents.push_back(pEvent);
+ }
+ } else {
+ if (bCheckMotion && pEvent->getType() == Event::CURSOR_MOTION &&
+ getLastEvent()->getPos() == pEvent->getPos())
+ {
+ // Ignore motion events without motion.
+ return;
+ } else {
+ if (m_pNewEvents.empty()) {
+ // No pending events: schedule for delivery.
+ m_pNewEvents.push_back(pEvent);
+ } else {
+ // More than one event per poll: Deliver only the last one.
+ m_pNewEvents[0] = pEvent;
+ }
+ }
+ }
+}
+
+TouchEventPtr TouchStatus::pollEvent()
+{
+ if (m_pNewEvents.empty()) {
+ return TouchEventPtr();
+ } else {
+ TouchEventPtr pEvent = m_pNewEvents[0];
+ m_pNewEvents.erase(m_pNewEvents.begin());
+ m_bFirstFrame = false;
+ m_pLastEvent = pEvent;
+ return pEvent;
+ }
+}
+
+TouchEventPtr TouchStatus::getLastEvent()
+{
+ if (m_pNewEvents.empty()) {
+ AVG_ASSERT(m_pLastEvent);
+ return m_pLastEvent;
+ } else {
+ return m_pNewEvents.back();
+ }
+}
+
+int TouchStatus::getID() const
+{
+ return m_CursorID;
+}
+
+}
+
diff --git a/src/player/TouchStatus.h b/src/player/TouchStatus.h
new file mode 100644
index 0000000..ffe3e7f
--- /dev/null
+++ b/src/player/TouchStatus.h
@@ -0,0 +1,59 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _TouchStatus_H_
+#define _TouchStatus_H_
+
+#include "../api.h"
+
+#include <boost/shared_ptr.hpp>
+
+#include <vector>
+
+namespace avg {
+
+class TouchEvent;
+typedef boost::shared_ptr<class TouchEvent> TouchEventPtr;
+
+class AVG_API TouchStatus {
+public:
+ TouchStatus(TouchEventPtr pEvent);
+ virtual ~TouchStatus();
+
+ void pushEvent(TouchEventPtr pEvent, bool bCheckMotion=true);
+ TouchEventPtr pollEvent();
+ TouchEventPtr getLastEvent();
+
+ int getID() const;
+
+private:
+ TouchEventPtr m_pLastEvent;
+ std::vector<TouchEventPtr> m_pNewEvents;
+
+ bool m_bFirstFrame;
+ int m_CursorID;
+};
+
+typedef boost::shared_ptr<class TouchStatus> TouchStatusPtr;
+
+}
+
+#endif
diff --git a/src/player/TrackerCalibrator.cpp b/src/player/TrackerCalibrator.cpp
new file mode 100644
index 0000000..4bc13b9
--- /dev/null
+++ b/src/player/TrackerCalibrator.cpp
@@ -0,0 +1,236 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "TrackerCalibrator.h"
+#include "TrackerInputDevice.h"
+
+#include "../base/ObjectCounter.h"
+#include "../base/Exception.h"
+
+#include "../imaging/DeDistort.h"
+
+extern "C" {
+#include "../lmfit/lmmin.h"
+#include "../lmfit/lm_eval.h"
+}
+
+using namespace std;
+
+#define NUM_POINTS 4
+#define MIN_DIST_FROM_BORDER 30
+//#define DEBUG_FIT 1
+#define MAX_ITERATIONS 50000
+
+namespace avg {
+
+enum Params { DISPSCALE_X, DISPSCALE_Y, DISPOFFSET_X, DISPOFFSET_Y, DIST_2,
+ ANGLE, TRAPEZ, NUM_PARAMS};
+
+void lm_print_tracker( int n_par, double* p, int m_dat, double* fvec,
+ void *data, int iflag, int iter, int nfev )
+/*
+ * data : for soft control of printout behaviour, add control
+ * variables to the data struct
+ * iflag : 0 (init) 1 (outer loop) 2(inner loop) -1(terminated)
+ * iter : outer loop counter
+ * nfev : number of calls to *evaluate
+ */
+{
+ TrackerCalibrator *mydata;
+ mydata = static_cast<TrackerCalibrator*>(data);
+ mydata->print_tracker(n_par, p, m_dat, fvec, iflag, iter, nfev);
+
+}
+
+void lm_evaluate_tracker(double* p, int m_dat, double* fvec,
+ void *data, int *info)
+{
+ TrackerCalibrator *mydata = static_cast<TrackerCalibrator*>(data);
+ mydata->evaluate_tracker(p, m_dat, fvec, info);
+
+}
+
+TrackerCalibrator::TrackerCalibrator(const IntPoint& CamExtents,
+ const IntPoint& DisplayExtents)
+ : m_CurPoint(0),
+ m_CamExtents(CamExtents),
+ m_DisplayExtents(DisplayExtents),
+ m_bCurPointSet(false)
+{
+ ObjectCounter::get()->incRef(&typeid(*this));
+ IntPoint OffsetPerPoint((DisplayExtents.x-MIN_DIST_FROM_BORDER*2)/(NUM_POINTS-1),
+ (DisplayExtents.y-MIN_DIST_FROM_BORDER*2)/(NUM_POINTS-1));
+ for (int y=0; y<NUM_POINTS; y++) {
+ for (int x=0; x<NUM_POINTS; x++) {
+ m_DisplayPoints.push_back(
+ IntPoint(OffsetPerPoint.x*x+MIN_DIST_FROM_BORDER,
+ OffsetPerPoint.y*y+MIN_DIST_FROM_BORDER));
+ m_CamPoints.push_back(glm::dvec2(0,0));
+ }
+ }
+}
+
+TrackerCalibrator::~TrackerCalibrator()
+{
+ ObjectCounter::get()->decRef(&typeid(*this));
+}
+
+
+bool TrackerCalibrator::nextPoint()
+{
+ if (!m_bCurPointSet) {
+ // There is no data for the previous point, so delete it.
+ m_DisplayPoints.erase(m_DisplayPoints.begin()+m_CurPoint);
+ m_CamPoints.erase(m_CamPoints.begin()+m_CurPoint);
+ } else {
+ m_CurPoint++;
+ }
+ m_bCurPointSet = false;
+ if (m_CurPoint < m_DisplayPoints.size()) {
+ return true;
+ } else {
+ return false;
+ }
+}
+
+IntPoint TrackerCalibrator::getDisplayPoint()
+{
+ return m_DisplayPoints[m_CurPoint];
+}
+
+void TrackerCalibrator::setCamPoint(const glm::vec2& pt)
+{
+ m_CamPoints[m_CurPoint] = pt;
+ m_bCurPointSet = true;
+}
+
+DeDistortPtr TrackerCalibrator::makeTransformer()
+{
+ lm_control_type control;
+ lm_initialize_control( &control );
+ control.maxcall=MAX_ITERATIONS;
+ // control.epsilon=1e-8;
+ // control.ftol = 1e-4;
+ // control.xtol = 1e-4;
+ // control.gtol = 1e-4;
+
+ int dat = int(m_DisplayPoints.size());
+ AVG_ASSERT(dat == int(m_CamPoints.size()));
+
+ //fill in reasonable defaults
+ m_DistortParams.clear();
+ m_DistortParams.push_back(0);
+ m_Angle = 0;
+ m_TrapezoidFactor = 0.0;
+ m_DisplayOffset= glm::vec2(0,0);
+ m_DisplayScale = glm::vec2(2,2);
+
+ int n_p = NUM_PARAMS;
+ //should really match the Params enum!!!!
+ double p[] = {
+ m_DisplayScale.x,
+ m_DisplayScale.y,
+ m_DisplayOffset.x,
+ m_DisplayOffset.y,
+ m_DistortParams[0],
+ m_Angle,
+ m_TrapezoidFactor
+ };
+ initThisFromDouble(p);
+ lm_minimize(dat, n_p, p, lm_evaluate_tracker, lm_print_tracker,
+ this, &control );
+ initThisFromDouble(p);
+/*
+ for(int i=0;i<NUM_POINTS*NUM_POINTS;i++) {
+ glm::vec2 screenPoint = m_CurrentTrafo->transformBlobToScreen(
+ m_CurrentTrafo->transform_point(m_CamPoints[i]));
+ cerr << "sample value of trafo of (cam) "
+ << m_CamPoints[i]<<" : (transformed) "
+ << screenPoint
+ << "== (display)"
+ << glm::vec2(m_DisplayPoints[i])
+ << " dist="
+ << calcDist(glm::vec2(m_DisplayPoints[i]), screenPoint)
+ << endl;
+ }
+ cerr<<" DisplayScale = "<<m_DisplayScale << endl;
+ cerr<<" DisplayOffset= "<<m_DisplayOffset << endl;
+ cerr<<" unDistortionParams = "<<m_DistortParams[0] << ", " << m_DistortParams[1]
+ << ", " << m_DistortParams[2] << endl;
+ cerr<<" Trapezoid = "<<m_TrapezoidFactor << endl;
+ cerr<<" angle = "<<m_Angle << endl;
+*/
+ return m_CurrentTrafo;
+}
+
+void TrackerCalibrator::initThisFromDouble(double *p)
+{
+ m_DisplayOffset.x = p[DISPOFFSET_X];
+ m_DisplayOffset.y = p[DISPOFFSET_Y];
+ m_DisplayScale.x = p[DISPSCALE_X];
+ m_DisplayScale.y = p[DISPSCALE_Y];
+ m_DistortParams.clear();
+ m_DistortParams.push_back( p[DIST_2]);
+ m_Angle = p[ANGLE];
+ m_TrapezoidFactor = p[TRAPEZ];
+ m_CurrentTrafo = DeDistortPtr(
+ new DeDistort(glm::vec2(m_CamExtents),
+ m_DistortParams,
+ m_Angle,
+ m_TrapezoidFactor,
+ m_DisplayOffset,
+ m_DisplayScale
+ )
+ );
+}
+
+void TrackerCalibrator::evaluate_tracker(double *p, int m_dat, double* fvec, int* info)
+{
+ initThisFromDouble(p);
+
+ for (int i=0; i<m_dat; i++) {
+ glm::dvec2 resultPt = m_CurrentTrafo->transformBlobToScreen(
+ m_CurrentTrafo->transform_point(m_CamPoints[i]));
+ fvec[i] = glm::length(resultPt - glm::dvec2(m_DisplayPoints[i]));
+ }
+ *info = *info; /* to prevent a 'unused variable' warning */
+ /* if <parameters drifted away> { *info = -1; } */
+}
+
+void TrackerCalibrator::print_tracker(int n_par, double *p, int m_dat,
+ double *fvec, int iflag, int iter, int nfev)
+{
+#ifdef DEBUG_FIT
+ initThisFromDouble(p);
+ if (iflag==2) {
+ printf ("trying step in gradient direction\n");
+ } else if (iflag==1) {
+ printf ("determining gradient (iteration %d)\n", iter);
+ } else if (iflag==0) {
+ printf ("starting minimization\n");
+ } else if (iflag==-1) {
+ printf ("terminated after %d evaluations\n", nfev);
+ }
+#endif
+ AVG_ASSERT(n_par == NUM_PARAMS);
+}
+
+}
diff --git a/src/player/TrackerCalibrator.h b/src/player/TrackerCalibrator.h
new file mode 100644
index 0000000..93779a6
--- /dev/null
+++ b/src/player/TrackerCalibrator.h
@@ -0,0 +1,75 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _TrackerCalibrator_H_
+#define _TrackerCalibrator_H_
+
+#include "../api.h"
+#include "../imaging/DeDistort.h"
+#include "../base/GLMHelper.h"
+
+#include <vector>
+
+namespace avg {
+
+class AVG_API TrackerCalibrator {
+
+public:
+ friend void lm_evaluate_tracker(double* p, int m_dat, double* fvec,
+ void *data, int *info);
+ friend void lm_print_tracker(int n_par, double* p, int m_dat, double* fvec,
+ void *data, int iflag, int iter, int nfev);
+
+ TrackerCalibrator(const IntPoint& CamExtents, const IntPoint& DisplayExtents);
+ virtual ~TrackerCalibrator();
+
+ bool nextPoint();
+ IntPoint getDisplayPoint();
+ void setCamPoint(const glm::vec2& pt);
+
+ DeDistortPtr makeTransformer();
+
+private:
+ void initThisFromDouble(double *p);
+
+ void evaluate_tracker(double *p, int m_dat, double *fvec, int* info);
+ void print_tracker(int n_par, double *p, int m_dat,
+ double *fvec, int iflag, int iter, int nfev);
+
+ std::vector<double> m_DistortParams;
+ double m_Angle;
+ glm::dvec2 m_DisplayScale;
+ glm::dvec2 m_DisplayOffset;
+ double m_TrapezoidFactor;
+ DeDistortPtr m_CurrentTrafo;
+ unsigned int m_CurPoint;
+ std::vector<IntPoint> m_DisplayPoints;
+ std::vector<glm::dvec2> m_CamPoints;
+
+ IntPoint m_CamExtents;
+ IntPoint m_DisplayExtents;
+
+ bool m_bCurPointSet;
+};
+
+}
+
+#endif
diff --git a/src/player/TrackerInputDevice.cpp b/src/player/TrackerInputDevice.cpp
new file mode 100644
index 0000000..88e6baa
--- /dev/null
+++ b/src/player/TrackerInputDevice.cpp
@@ -0,0 +1,493 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+// Original author of this file is igor@c-base.org
+//
+
+#include "TrackerInputDevice.h"
+#include "TouchEvent.h"
+#include "TrackerTouchStatus.h"
+
+#include "../base/Logger.h"
+#include "../base/ObjectCounter.h"
+#include "../base/ScopeTimer.h"
+#include "../base/Exception.h"
+
+#include "../graphics/HistoryPreProcessor.h"
+#include "../graphics/Filterfill.h"
+#include "../graphics/Pixel8.h"
+
+#include "../imaging/DeDistort.h"
+#include "../imaging/CoordTransformer.h"
+
+#include "../glm/gtx/norm.hpp"
+
+#include "Player.h"
+#include "AVGNode.h"
+
+#include <boost/thread/thread.hpp>
+#include <boost/bind.hpp>
+
+#include <map>
+#include <list>
+#include <vector>
+#include <queue>
+#include <set>
+#include <iostream>
+
+using namespace std;
+
+namespace avg {
+
+TrackerInputDevice::TrackerInputDevice()
+ : IInputDevice(EXTRACT_INPUTDEVICE_CLASSNAME(TrackerInputDevice)),
+ m_pTrackerThread(0),
+ m_bSubtractHistory(true),
+ m_pCalibrator(0)
+{
+ ObjectCounter::get()->incRef(&typeid(*this));
+
+ m_TrackerConfig.load();
+
+ string sDriver = m_TrackerConfig.getParam("/camera/driver/@value");
+ string sDevice = m_TrackerConfig.getParam("/camera/device/@value");
+ bool bFW800 = m_TrackerConfig.getBoolParam("/camera/fw800/@value");
+ IntPoint captureSize(m_TrackerConfig.getPointParam("/camera/size/"));
+ string sCaptureFormat = m_TrackerConfig.getParam("/camera/format/@value");
+ float frameRate = m_TrackerConfig.getFloatParam("/camera/framerate/@value");
+
+ PixelFormat camPF = stringToPixelFormat(sCaptureFormat);
+ if (camPF == NO_PIXELFORMAT) {
+ throw Exception(AVG_ERR_INVALID_ARGS,
+ "Unknown camera pixel format "+sCaptureFormat+".");
+ }
+
+ AVG_TRACE(Logger::category::CONFIG, Logger::severity::INFO,
+ "Trying to create a Tracker for " << sDriver
+ << " Camera: " << sDevice << " Size: " << captureSize << "format: "
+ << sCaptureFormat);
+ m_pCamera = createCamera(sDriver, sDevice, -1, bFW800, captureSize, camPF, I8,
+ frameRate);
+ AVG_TRACE(Logger::category::CONFIG, Logger::severity::INFO,
+ "Got Camera " << m_pCamera->getDevice() << " from driver: "
+ << m_pCamera->getDriverName());
+
+ IntPoint imgSize = m_pCamera->getImgSize();
+ m_pBitmaps[0] = BitmapPtr(new Bitmap(imgSize, I8));
+ m_pMutex = MutexPtr(new boost::mutex);
+ m_pCmdQueue = TrackerThread::CQueuePtr(new TrackerThread::CQueue);
+ m_pDeDistort = m_TrackerConfig.getTransform();
+ try {
+ m_ActiveDisplaySize = IntPoint(
+ m_TrackerConfig.getPointParam("/transform/activedisplaysize/"));
+ } catch (Exception) {
+ m_ActiveDisplaySize = IntPoint(Player::get()->getRootNode()->getSize());
+ }
+ try {
+ m_DisplayROI = m_TrackerConfig.getRectParam("/transform/displayroi/");
+ } catch (Exception) {
+ m_DisplayROI = FRect(glm::vec2(0,0), glm::vec2(m_ActiveDisplaySize));
+ }
+
+ IntRect roi = m_pDeDistort->getActiveBlobArea(m_DisplayROI);
+ if (roi.tl.x < 0 || roi.tl.y < 0 ||
+ roi.br.x > imgSize.x || roi.br.y > imgSize.y)
+ {
+ AVG_LOG_ERROR("Impossible tracker configuration: Region of interest is "
+ << roi << ", camera image size is " << imgSize << ". Aborting.");
+ exit(5);
+ }
+ m_InitialROI = roi;
+ createBitmaps(roi);
+ setDebugImages(false, false);
+
+ try {
+ m_bFindFingertips = m_TrackerConfig.getBoolParam(
+ "/tracker/findfingertips/@value");
+ } catch(Exception) {
+ m_bFindFingertips = false;
+ }
+
+}
+
+TrackerInputDevice::~TrackerInputDevice()
+{
+ m_pCmdQueue->pushCmd(boost::bind(&TrackerThread::stop, _1));
+ if (m_pTrackerThread) {
+ m_pTrackerThread->join();
+ delete m_pTrackerThread;
+ }
+ ObjectCounter::get()->decRef(&typeid(*this));
+}
+
+void TrackerInputDevice::start()
+{
+ m_pTrackerThread = new boost::thread(
+ TrackerThread(
+ m_InitialROI,
+ m_pCamera,
+ m_pBitmaps,
+ m_pMutex,
+ *m_pCmdQueue,
+ this,
+ m_bSubtractHistory,
+ m_TrackerConfig
+ )
+ );
+ setConfig();
+}
+
+void TrackerInputDevice::setParam(const string& sElement, const string& sValue)
+{
+ string sOldParamVal = m_TrackerConfig.getParam(sElement);
+ m_TrackerConfig.setParam(sElement, sValue);
+
+ // Test if active area is outside camera.
+ FRect area = m_pDeDistort->getActiveBlobArea(m_DisplayROI);
+ glm::vec2 size = m_TrackerConfig.getPointParam("/camera/size/");
+ int prescale = m_TrackerConfig.getIntParam("/tracker/prescale/@value");
+ if (area.br.x > size.x/prescale || area.br.y > size.y/prescale ||
+ area.tl.x < 0 || area.tl.y < 0)
+ {
+ m_TrackerConfig.setParam(sElement, sOldParamVal);
+ } else {
+ setConfig();
+ }
+// m_TrackerConfig.dump();
+}
+
+string TrackerInputDevice::getParam(const string& sElement)
+{
+ return m_TrackerConfig.getParam(sElement);
+}
+
+void TrackerInputDevice::setDebugImages(bool bImg, bool bFinger)
+{
+ m_pCmdQueue->pushCmd(boost::bind(&TrackerThread::setDebugImages, _1, bImg,
+ bFinger));
+}
+
+void TrackerInputDevice::resetHistory()
+{
+ m_pCmdQueue->pushCmd(boost::bind(&TrackerThread::resetHistory, _1));
+}
+
+void TrackerInputDevice::saveConfig()
+{
+ m_TrackerConfig.save();
+}
+
+void TrackerInputDevice::setConfig()
+{
+ m_pDeDistort = m_TrackerConfig.getTransform();
+ FRect area = m_pDeDistort->getActiveBlobArea(m_DisplayROI);
+ createBitmaps(area);
+ m_pCmdQueue->pushCmd(boost::bind(&TrackerThread::setConfig, _1, m_TrackerConfig,
+ area, m_pBitmaps));
+}
+
+void TrackerInputDevice::createBitmaps(const IntRect& area)
+{
+ lock_guard lock(*m_pMutex);
+ for (int i=1; i<NUM_TRACKER_IMAGES; i++) {
+ switch (i) {
+ case TRACKER_IMG_HISTOGRAM:
+ m_pBitmaps[TRACKER_IMG_HISTOGRAM] =
+ BitmapPtr(new Bitmap(IntPoint(256, 256), I8));
+ FilterFill<Pixel8>(Pixel8(0)).
+ applyInPlace(m_pBitmaps[TRACKER_IMG_HISTOGRAM]);
+ break;
+ case TRACKER_IMG_FINGERS:
+ m_pBitmaps[TRACKER_IMG_FINGERS] =
+ BitmapPtr(new Bitmap(area.size(), B8G8R8A8));
+ FilterFill<Pixel32>(Pixel32(0,0,0,0)).
+ applyInPlace(m_pBitmaps[TRACKER_IMG_FINGERS]);
+ break;
+ default:
+ m_pBitmaps[i] = BitmapPtr(new Bitmap(area.size(), I8));
+ FilterFill<Pixel8>(Pixel8(0)).applyInPlace(m_pBitmaps[i]);
+ }
+ }
+}
+
+Bitmap * TrackerInputDevice::getImage(TrackerImageID imageID) const
+{
+ lock_guard lock(*m_pMutex);
+ return new Bitmap(*m_pBitmaps[imageID]);
+}
+
+glm::vec2 TrackerInputDevice::getDisplayROIPos() const
+{
+ return m_DisplayROI.tl;
+}
+
+glm::vec2 TrackerInputDevice::getDisplayROISize() const
+{
+ return m_DisplayROI.size();
+}
+
+static ProfilingZoneID ProfilingZoneCalcTrack("trackBlobIDs(track)");
+static ProfilingZoneID ProfilingZoneCalcTouch("trackBlobIDs(touch)");
+
+void TrackerInputDevice::update(BlobVectorPtr pTrackBlobs,
+ BlobVectorPtr pTouchBlobs, long long time)
+{
+ if (pTrackBlobs) {
+ ScopeTimer Timer(ProfilingZoneCalcTrack);
+ trackBlobIDs(pTrackBlobs, time, false);
+ }
+ if (pTouchBlobs) {
+ ScopeTimer Timer(ProfilingZoneCalcTouch);
+ trackBlobIDs(pTouchBlobs, time, true);
+ }
+}
+
+// Temporary structure to be put into heap of blob distances. Used only in
+// trackBlobIDs.
+struct BlobDistEntry {
+ BlobDistEntry(float dist, BlobPtr pNewBlob, BlobPtr pOldBlob)
+ : m_Dist(dist),
+ m_pNewBlob(pNewBlob),
+ m_pOldBlob(pOldBlob)
+ {
+ }
+
+ float m_Dist;
+ BlobPtr m_pNewBlob;
+ BlobPtr m_pOldBlob;
+};
+typedef boost::shared_ptr<struct BlobDistEntry> BlobDistEntryPtr;
+
+// The heap is sorted by least distance, so this operator does the
+// _opposite_ of what is expected!
+bool operator < (const BlobDistEntryPtr& e1, const BlobDistEntryPtr& e2)
+{
+ return e1->m_Dist > e2->m_Dist;
+}
+
+void TrackerInputDevice::trackBlobIDs(BlobVectorPtr pNewBlobs, long long time,
+ bool bTouch)
+{
+ TouchStatusMap * pEvents;
+ string sConfigPath;
+ Event::Source source;
+ if (bTouch) {
+ sConfigPath = "/tracker/touch/";
+ pEvents = &m_TouchEvents;
+ source = Event::TOUCH;
+ } else {
+ sConfigPath = "/tracker/track/";
+ pEvents = &m_TrackEvents;
+ source = Event::TRACK;
+ }
+ BlobVector oldBlobs;
+ for (TouchStatusMap::iterator it = pEvents->begin(); it != pEvents->end(); ++it) {
+ (*it).second->setStale();
+ oldBlobs.push_back((*it).first);
+ }
+ // Create a heap that contains all distances of old to new blobs < MaxDist
+ float MaxDist = m_TrackerConfig.getFloatParam(sConfigPath+"similarity/@value");
+ float MaxDistSquared = MaxDist*MaxDist;
+ priority_queue<BlobDistEntryPtr> distHeap;
+ for (BlobVector::iterator it = pNewBlobs->begin(); it != pNewBlobs->end(); ++it) {
+ BlobPtr pNewBlob = *it;
+ for(BlobVector::iterator it2 = oldBlobs.begin(); it2 != oldBlobs.end(); ++it2) {
+ BlobPtr pOldBlob = *it2;
+ float distSquared = glm::distance2(pNewBlob->getCenter(),
+ pOldBlob->getEstimatedNextCenter());
+ if (distSquared <= MaxDistSquared) {
+ BlobDistEntryPtr pEntry = BlobDistEntryPtr(
+ new BlobDistEntry(distSquared, pNewBlob, pOldBlob));
+ distHeap.push(pEntry);
+ }
+ }
+ }
+ // Match up the closest blobs.
+ set<BlobPtr> matchedNewBlobs;
+ set<BlobPtr> matchedOldBlobs;
+ int numMatchedBlobs = 0;
+ while (!distHeap.empty()) {
+ BlobDistEntryPtr pEntry = distHeap.top();
+ distHeap.pop();
+ if (matchedNewBlobs.find(pEntry->m_pNewBlob) == matchedNewBlobs.end() &&
+ matchedOldBlobs.find(pEntry->m_pOldBlob) == matchedOldBlobs.end())
+ {
+ // Found a pair of matched blobs.
+ numMatchedBlobs++;
+ BlobPtr pNewBlob = pEntry->m_pNewBlob;
+ BlobPtr pOldBlob = pEntry->m_pOldBlob;
+ matchedNewBlobs.insert(pNewBlob);
+ matchedOldBlobs.insert(pOldBlob);
+ AVG_ASSERT (pEvents->find(pOldBlob) != pEvents->end());
+ TrackerTouchStatusPtr pTouchStatus;
+ pTouchStatus = pEvents->find(pOldBlob)->second;
+ // Make sure we don't discard any events that have related info.
+ bool bKeepAllEvents = pNewBlob->getFirstRelated() && !bTouch;
+ pTouchStatus->blobChanged(pNewBlob, time, bKeepAllEvents);
+ pNewBlob->calcNextCenter(pOldBlob->getCenter());
+ // Update the mapping.
+ (*pEvents)[pNewBlob] = pTouchStatus;
+ pEvents->erase(pOldBlob);
+ }
+ }
+ // Blobs have been matched. Left-overs are new blobs.
+ for (BlobVector::iterator it = pNewBlobs->begin(); it != pNewBlobs->end(); ++it) {
+ if (matchedNewBlobs.find(*it) == matchedNewBlobs.end()) {
+ TrackerTouchStatusPtr pTouchStatus = TrackerTouchStatusPtr(
+ new TrackerTouchStatus(*it, time, m_pDeDistort, m_DisplayROI,
+ source));
+ (*pEvents)[(*it)] = pTouchStatus;
+ }
+ }
+
+ // All event streams that are still stale haven't been updated: blob is gone,
+ // set the sentinel for this.
+ for(TouchStatusMap::iterator it=pEvents->begin(); it!=pEvents->end(); ++it) {
+ if ((*it).second->isStale()) {
+ (*it).second->blobGone();
+ }
+ }
+};
+
+TrackerCalibrator* TrackerInputDevice::startCalibration()
+{
+ AVG_ASSERT(!m_pCalibrator);
+ m_pOldTransformer = m_TrackerConfig.getTransform();
+ m_OldDisplayROI = m_DisplayROI;
+ m_DisplayROI = FRect(glm::vec2(0,0), glm::vec2(m_ActiveDisplaySize));
+ m_TrackerConfig.setTransform(DeDistortPtr(new DeDistort(
+ glm::vec2(m_pBitmaps[0]->getSize()), glm::vec2(m_ActiveDisplaySize))));
+ setConfig();
+ m_pCalibrator = new TrackerCalibrator(m_pBitmaps[0]->getSize(),
+ m_ActiveDisplaySize);
+ return m_pCalibrator;
+}
+
+void TrackerInputDevice::endCalibration()
+{
+ AVG_ASSERT(m_pCalibrator);
+ m_TrackerConfig.setTransform(m_pCalibrator->makeTransformer());
+ m_DisplayROI = m_OldDisplayROI;
+ FRect area = m_TrackerConfig.getTransform()->getActiveBlobArea(m_DisplayROI);
+ if (area.size().x*area.size().y > 1024*1024*8) {
+ AVG_LOG_WARNING("Ignoring calibration - resulting area would be " << area);
+ m_TrackerConfig.setTransform(m_pOldTransformer);
+ }
+ setConfig();
+ delete m_pCalibrator;
+ m_pCalibrator = 0;
+ m_pOldTransformer = DeDistortPtr();
+}
+
+void TrackerInputDevice::abortCalibration()
+{
+ AVG_ASSERT(m_pCalibrator);
+ m_TrackerConfig.setTransform(m_pOldTransformer);
+ setConfig();
+ m_pOldTransformer = DeDistortPtr();
+ delete m_pCalibrator;
+ m_pCalibrator = 0;
+}
+
+vector<EventPtr> TrackerInputDevice::pollEvents()
+{
+ lock_guard lock(*m_pMutex);
+ vector<EventPtr> pTouchEvents;
+ vector<EventPtr> pTrackEvents;
+ pollEventType(pTouchEvents, m_TouchEvents, CursorEvent::TOUCH);
+ pollEventType(pTrackEvents, m_TrackEvents, CursorEvent::TRACK);
+ copyRelatedInfo(pTouchEvents, pTrackEvents);
+ if (m_bFindFingertips) {
+ findFingertips(pTouchEvents);
+ }
+ pTouchEvents.insert(pTouchEvents.end(),
+ pTrackEvents.begin(), pTrackEvents.end());
+ return pTouchEvents;
+}
+
+void TrackerInputDevice::pollEventType(vector<EventPtr>& res, TouchStatusMap& Events,
+ CursorEvent::Source source)
+{
+ EventPtr pEvent;
+ for (TouchStatusMap::iterator it = Events.begin(); it!= Events.end();) {
+ TrackerTouchStatusPtr pTouchStatus = (*it).second;
+ pEvent = pTouchStatus->pollEvent();
+ if (pEvent) {
+ res.push_back(pEvent);
+ if (pEvent->getType() == Event::CURSOR_UP) {
+ Events.erase(it++);
+ } else {
+ ++it;
+ }
+ } else {
+ ++it;
+ }
+ }
+}
+
+void TrackerInputDevice::copyRelatedInfo(vector<EventPtr> pTouchEvents,
+ vector<EventPtr> pTrackEvents)
+{
+ // Copy related blobs to related events.
+ // Yuck.
+ vector<EventPtr>::iterator it;
+ for (it = pTouchEvents.begin(); it != pTouchEvents.end(); ++it) {
+ TouchEventPtr pTouchEvent = boost::dynamic_pointer_cast<TouchEvent>(*it);
+ BlobPtr pTouchBlob = pTouchEvent->getBlob();
+ BlobPtr pRelatedBlob = pTouchBlob->getFirstRelated();
+ if (pRelatedBlob) {
+ vector<EventPtr>::iterator it2;
+ TouchEventPtr pTrackEvent;
+ BlobPtr pTrackBlob;
+ for (it2 = pTrackEvents.begin();
+ pTrackBlob != pRelatedBlob && it2 != pTrackEvents.end();
+ ++it2)
+ {
+ pTrackEvent = boost::dynamic_pointer_cast<TouchEvent>(*it2);
+ pTrackBlob = pTrackEvent->getBlob();
+ }
+ if (pTrackBlob == pRelatedBlob) {
+ pTouchEvent->addRelatedEvent(pTrackEvent);
+ pTrackEvent->addRelatedEvent(pTouchEvent);
+ }
+ }
+ }
+}
+
+void TrackerInputDevice::findFingertips(std::vector<EventPtr>& pTouchEvents)
+{
+ vector<EventPtr>::iterator it;
+ for (it = pTouchEvents.begin(); it != pTouchEvents.end(); ++it) {
+ TouchEventPtr pTouchEvent = boost::dynamic_pointer_cast<TouchEvent>(*it);
+ vector<TouchEventPtr> pTrackEvents = pTouchEvent->getRelatedEvents();
+ if (pTrackEvents.size() > 0) {
+ float handAngle = pTouchEvent->getHandOrientation();
+ float dist = glm::length(pTouchEvent->getMajorAxis())*2;
+ glm::vec2 tweakVec = fromPolar(handAngle, dist);
+ glm::vec2 newPos = pTouchEvent->getPos()-tweakVec;
+ newPos.x = max(0.0f, min(newPos.x, float(m_ActiveDisplaySize.x)));
+ newPos.y = max(0.0f, min(newPos.y, float(m_ActiveDisplaySize.y)));
+ pTouchEvent->setPos(newPos);
+ }
+ }
+}
+
+}
+
diff --git a/src/player/TrackerInputDevice.h b/src/player/TrackerInputDevice.h
new file mode 100644
index 0000000..eda8a8d
--- /dev/null
+++ b/src/player/TrackerInputDevice.h
@@ -0,0 +1,122 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _TrackerInputDevice_H_
+#define _TrackerInputDevice_H_
+
+#include "../api.h"
+#include "CursorEvent.h"
+#include "IInputDevice.h"
+#include "TrackerCalibrator.h"
+
+#include "../imaging/TrackerThread.h"
+#include "../imaging/Blob.h"
+
+#include "../graphics/Bitmap.h"
+#include "../graphics/Filter.h"
+
+#include "../base/Rect.h"
+
+#include <string>
+#include <map>
+#include <list>
+#include <vector>
+#include <utility>
+
+namespace avg {
+
+class TrackerTouchStatus;
+typedef boost::shared_ptr<TrackerTouchStatus> TrackerTouchStatusPtr;
+
+class AVG_API TrackerInputDevice: public IBlobTarget, public IInputDevice
+{
+ typedef std::map<BlobPtr, TrackerTouchStatusPtr> TouchStatusMap;
+
+ public:
+ TrackerInputDevice();
+ virtual ~TrackerInputDevice();
+ void start();
+
+ void setParam(const std::string& sElement, const std::string& sValue);
+ std::string getParam(const std::string& sElement);
+
+ void resetHistory();
+ void setDebugImages(bool bImg, bool bFinger);
+ void saveConfig();
+ Bitmap * getImage(TrackerImageID imageID) const;
+ glm::vec2 getDisplayROIPos() const;
+ glm::vec2 getDisplayROISize() const;
+
+ std::vector<EventPtr> pollEvents(); //main thread
+
+ // implement IBlobTarget
+ // Called from Tracker Thread!
+ virtual void update(BlobVectorPtr pTrackBlobs, BlobVectorPtr pTouchBlobs,
+ long long time);
+
+ TrackerCalibrator* startCalibration();
+ void endCalibration();
+ void abortCalibration();
+
+ private:
+ void setConfig();
+ void createBitmaps(const IntRect& area);
+
+ boost::thread* m_pTrackerThread;
+
+ // Used by main thread
+ void pollEventType(std::vector<EventPtr>& res, TouchStatusMap& events,
+ CursorEvent::Source source);
+ void copyRelatedInfo(std::vector<EventPtr> pTouchEvents,
+ std::vector<EventPtr> pTrackEvents);
+ void findFingertips(std::vector<EventPtr>& pTouchEvents);
+
+ IntRect m_InitialROI;
+ CameraPtr m_pCamera;
+ bool m_bSubtractHistory;
+ DeDistortPtr m_pDeDistort;
+ DeDistortPtr m_pOldTransformer;
+ IntPoint m_ActiveDisplaySize;
+ FRect m_DisplayROI;
+ FRect m_OldDisplayROI;
+ TrackerCalibrator * m_pCalibrator;
+ bool m_bFindFingertips;
+
+ // Used by tracker thread
+ void trackBlobIDs(BlobVectorPtr new_blobs, long long time, bool bTouch);
+
+ // Used by both threads
+ TouchStatusMap m_TouchEvents;
+ TouchStatusMap m_TrackEvents;
+ TrackerConfig m_TrackerConfig;
+
+ MutexPtr m_pMutex;
+ BitmapPtr m_pBitmaps[NUM_TRACKER_IMAGES];
+
+ TrackerThread::CQueuePtr m_pCmdQueue;
+};
+
+typedef boost::shared_ptr<TrackerInputDevice> TrackerInputDevicePtr;
+
+}
+
+#endif
+
diff --git a/src/player/TrackerTouchStatus.cpp b/src/player/TrackerTouchStatus.cpp
new file mode 100644
index 0000000..f52bd3b
--- /dev/null
+++ b/src/player/TrackerTouchStatus.cpp
@@ -0,0 +1,120 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "TrackerTouchStatus.h"
+#include "TouchEvent.h"
+
+#include "../base/Logger.h"
+#include "../base/ObjectCounter.h"
+#include "../base/Exception.h"
+
+#include <math.h>
+
+using namespace std;
+
+namespace avg {
+
+int TrackerTouchStatus::s_LastID = 0;
+
+TrackerTouchStatus::TrackerTouchStatus(BlobPtr pFirstBlob, long long time,
+ DeDistortPtr pDeDistort, const FRect& displayROI, Event::Source source)
+ : TouchStatus(createEvent(source, Event::CURSOR_DOWN, ++s_LastID, pFirstBlob, time,
+ pDeDistort, displayROI)),
+ m_Source(source),
+ m_pDeDistort(pDeDistort),
+ m_DisplayROI(displayROI),
+ m_Stale(false),
+ m_bGone(false),
+ m_ID(s_LastID),
+ m_pBlob(pFirstBlob),
+ m_LastTime(time),
+ m_LastCenter(pFirstBlob->getCenter())
+{
+ AVG_ASSERT(m_Source == Event::TOUCH || m_Source == Event::TRACK);
+ ObjectCounter::get()->incRef(&typeid(*this));
+}
+
+TrackerTouchStatus::~TrackerTouchStatus()
+{
+ ObjectCounter::get()->decRef(&typeid(*this));
+}
+
+void TrackerTouchStatus::blobChanged(BlobPtr pNewBlob, long long time, bool bKeepEvent)
+{
+ AVG_ASSERT(m_pBlob);
+ AVG_ASSERT(pNewBlob);
+ if (!m_bGone) {
+ glm::vec2 c = pNewBlob->getCenter();
+ bool bPosChanged;
+ if (bKeepEvent) {
+ bPosChanged = true;
+ } else {
+ bPosChanged = (glm::length(c-m_LastCenter) > 1);
+ }
+ if (bPosChanged) {
+ m_LastCenter = pNewBlob->getCenter();
+ TouchEventPtr pEvent = createEvent(Event::CURSOR_MOTION, pNewBlob, time);
+ pushEvent(pEvent, false);
+ }
+ m_pBlob = pNewBlob;
+ m_Stale = false;
+ m_LastTime = time;
+ }
+};
+
+void TrackerTouchStatus::blobGone()
+{
+ if (!m_bGone) {
+ TouchEventPtr pEvent = createEvent(Event::CURSOR_UP, m_pBlob, m_LastTime+1);
+ pushEvent(pEvent, false);
+ m_bGone = true;
+ }
+}
+
+void TrackerTouchStatus::setStale()
+{
+ m_Stale = true;
+}
+
+bool TrackerTouchStatus::isStale()
+{
+ return m_Stale;
+}
+
+TouchEventPtr TrackerTouchStatus::createEvent(Event::Source source, Event::Type type,
+ int id, BlobPtr pBlob, long long time, DeDistortPtr pDeDistort,
+ const FRect& displayROI)
+{
+ glm::vec2 blobOffset = pDeDistort->getActiveBlobArea(displayROI).tl;
+ glm::vec2 pt = pBlob->getCenter() + blobOffset;
+ glm::dvec2 screenpos(pDeDistort->transformBlobToScreen(glm::dvec2(pt)));
+ IntPoint pos(int(screenpos.x+0.5), int(screenpos.y+0.5));
+
+ return TouchEventPtr(new TouchEvent(id, type, pBlob, pos, source));
+}
+
+TouchEventPtr TrackerTouchStatus::createEvent(Event::Type type, BlobPtr pBlob,
+ long long time)
+{
+ return createEvent(m_Source, type, m_ID, pBlob, time, m_pDeDistort, m_DisplayROI);
+}
+
+}
diff --git a/src/player/TrackerTouchStatus.h b/src/player/TrackerTouchStatus.h
new file mode 100644
index 0000000..5d75f5d
--- /dev/null
+++ b/src/player/TrackerTouchStatus.h
@@ -0,0 +1,70 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _TrackerTouchStatus_H_
+#define _TrackerTouchStatus_H_
+
+#include "../api.h"
+#include "Event.h"
+#include "TouchStatus.h"
+
+#include "../base/GLMHelper.h"
+
+#include "../imaging/Blob.h"
+#include "../imaging/DeDistort.h"
+
+#include <string>
+
+namespace avg {
+
+class AVG_API TrackerTouchStatus: public TouchStatus
+{
+ public:
+ TrackerTouchStatus(BlobPtr pFirstBlob, long long time, DeDistortPtr pDeDistort,
+ const FRect& displayROI, Event::Source source);
+ virtual ~TrackerTouchStatus();
+ void blobChanged(BlobPtr pNewBlob, long long time, bool bKeepEvent);
+ void blobGone();
+ void setStale();
+ bool isStale();
+
+ private:
+ TouchEventPtr createEvent(Event::Source source, Event::Type type, int id,
+ BlobPtr pBlob, long long time, DeDistortPtr pDeDistort,
+ const FRect& displayROI);
+ TouchEventPtr createEvent(Event::Type type, BlobPtr pBlob, long long time);
+
+ Event::Source m_Source;
+ DeDistortPtr m_pDeDistort;
+ FRect m_DisplayROI;
+ bool m_Stale;
+ bool m_bGone;
+ int m_ID;
+ BlobPtr m_pBlob;
+ long long m_LastTime;
+ glm::vec2 m_LastCenter;
+
+ static int s_LastID;
+};
+
+}
+
+#endif
diff --git a/src/player/TypeDefinition.cpp b/src/player/TypeDefinition.cpp
new file mode 100644
index 0000000..f2d5ec5
--- /dev/null
+++ b/src/player/TypeDefinition.cpp
@@ -0,0 +1,130 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "TypeDefinition.h"
+
+#include "../base/Logger.h"
+
+using namespace std;
+
+namespace avg {
+
+TypeDefinition::TypeDefinition() :
+ m_pBuilder(0)
+{
+}
+
+TypeDefinition::TypeDefinition(const string& sName, const string& sBaseName,
+ ObjectBuilder pBuilder)
+ : m_sName(sName),
+ m_pBuilder(pBuilder)
+{
+ if (sBaseName != "") {
+ TypeDefinition baseDef = TypeRegistry::get()->getTypeDef(sBaseName);
+ m_Args.copyArgsFrom(baseDef.m_Args);
+ m_sChildren = baseDef.m_sChildren;
+ }
+}
+
+TypeDefinition::~TypeDefinition()
+{
+}
+
+const std::string& TypeDefinition::getName() const
+{
+ return m_sName;
+}
+
+ObjectBuilder TypeDefinition::getBuilder() const
+{
+ return m_pBuilder;
+}
+
+const ArgList& TypeDefinition::getDefaultArgs() const
+{
+ return m_Args;
+}
+
+const string& TypeDefinition::getDTDElements() const
+{
+ return m_sDTDElements;
+}
+
+string TypeDefinition::getDTDChildrenString() const
+{
+ if (m_sChildren.empty()) {
+ return "EMPTY";
+ } else {
+ string sChildren = "(";
+
+ for (unsigned i=0; i<m_sChildren.size()-1; ++i) {
+ sChildren += m_sChildren[i]+"|";
+ }
+ sChildren += m_sChildren[m_sChildren.size()-1]+")*";
+ return sChildren;
+ }
+}
+
+bool TypeDefinition::isChildAllowed(const string& sChild) const
+{
+ for (unsigned i=0; i<m_sChildren.size(); ++i) {
+ if (m_sChildren[i] == sChild) {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool TypeDefinition::hasChildren() const
+{
+ return !m_sChildren.empty();
+}
+
+bool TypeDefinition::isAbstract() const
+{
+ return m_pBuilder == 0;
+}
+
+TypeDefinition& TypeDefinition::addArg(const ArgBase& newArg)
+{
+ m_Args.setArg(newArg);
+ return *this;
+}
+
+TypeDefinition& TypeDefinition::addDTDElements(const string& s)
+{
+ m_sDTDElements = s;
+ return *this;
+}
+
+TypeDefinition& TypeDefinition::addChildren(const vector<string>& sChildren)
+{
+ m_sChildren.insert(m_sChildren.end(), sChildren.begin(), sChildren.end());
+ return *this;
+}
+
+TypeDefinition& TypeDefinition::addChild(const string& sChild)
+{
+ m_sChildren.push_back(sChild);
+ return *this;
+}
+
+}
diff --git a/src/player/TypeDefinition.h b/src/player/TypeDefinition.h
new file mode 100644
index 0000000..e1275f4
--- /dev/null
+++ b/src/player/TypeDefinition.h
@@ -0,0 +1,75 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _TypeDefinition_H_
+#define _TypeDefinition_H_
+
+#include "../api.h"
+
+#include "ArgList.h"
+#include "TypeRegistry.h"
+
+#include <map>
+#include <string>
+
+namespace avg {
+
+class ExportedObject;
+typedef boost::shared_ptr<ExportedObject> ExportedObjectPtr;
+class TypeDefinition;
+
+typedef ExportedObjectPtr (*ObjectBuilder)(const ArgList& Args);
+typedef std::map<std::string, TypeDefinition> ChildMap;
+
+class AVG_API TypeDefinition
+{
+public:
+ TypeDefinition();
+ TypeDefinition(const std::string& sName, const std::string& sBaseName="",
+ ObjectBuilder pBuilder = 0);
+ virtual ~TypeDefinition();
+
+ const std::string& getName() const;
+ ObjectBuilder getBuilder() const;
+ const ArgList& getDefaultArgs() const;
+ const std::string& getDTDElements() const;
+ std::string getDTDChildrenString() const;
+ bool isChildAllowed(const std::string& sChild) const;
+ bool hasChildren() const;
+ bool isAbstract() const;
+
+ TypeDefinition& addArg(const ArgBase& newArg);
+ TypeDefinition& addDTDElements(const std::string& s);
+ TypeDefinition& addChildren(const std::vector<std::string>& sChildren);
+ TypeDefinition& addChild(const std::string& sChild);
+
+private:
+ std::string m_sName;
+ ObjectBuilder m_pBuilder;
+ ArgList m_Args;
+ std::string m_sDTDElements;
+ std::vector<std::string> m_sChildren;
+
+};
+
+}
+
+#endif
diff --git a/src/player/TypeRegistry.cpp b/src/player/TypeRegistry.cpp
new file mode 100644
index 0000000..0de3609
--- /dev/null
+++ b/src/player/TypeRegistry.cpp
@@ -0,0 +1,159 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+// Original author of this file is Nick Hebner (hebnern@gmail.com).
+//
+
+#include "TypeRegistry.h"
+#include "TypeDefinition.h"
+
+#include "../base/MathHelper.h"
+#include "../base/Exception.h"
+
+#include <set>
+
+using namespace std;
+
+namespace avg {
+
+TypeRegistry* TypeRegistry::s_pInstance = 0;
+
+TypeRegistry::TypeRegistry()
+{
+}
+
+TypeRegistry::~TypeRegistry()
+{
+}
+
+TypeRegistry* TypeRegistry::get()
+{
+ if (!s_pInstance) {
+ s_pInstance = new TypeRegistry();
+ }
+ return s_pInstance;
+}
+
+void TypeRegistry::registerType(const TypeDefinition& def, const char* pParentNames[])
+{
+ m_TypeDefs.insert(TypeDefMap::value_type(def.getName(), def));
+
+ if (pParentNames) {
+ string sChildArray[1];
+ sChildArray[0] = def.getName();
+ vector<string> sChildren = vectorFromCArray(1, sChildArray);
+ const char **ppCurParentName = pParentNames;
+
+ while (*ppCurParentName) {
+ TypeDefinition def = getTypeDef(*ppCurParentName);
+ def.addChildren(sChildren);
+ updateDefinition(def);
+
+ ++ppCurParentName;
+ }
+ }
+}
+
+void TypeRegistry::updateDefinition(const TypeDefinition& def)
+{
+ m_TypeDefs[def.getName()] = def;
+}
+
+ExportedObjectPtr TypeRegistry::createObject(const string& sType,
+ const xmlNodePtr xmlNode)
+{
+ const TypeDefinition& def = getTypeDef(sType);
+ ArgList args(def.getDefaultArgs(), xmlNode);
+ ObjectBuilder builder = def.getBuilder();
+ ExportedObjectPtr pObj = builder(args);
+ pObj->setTypeInfo(&def);
+ return pObj;
+}
+
+ExportedObjectPtr TypeRegistry::createObject(const string& sType, const py::dict& pyDict)
+{
+ const TypeDefinition& def = getTypeDef(sType);
+ py::dict effParams;
+ effParams = pyDict;
+ ArgList args(def.getDefaultArgs(), effParams);
+ ObjectBuilder builder = def.getBuilder();
+ ExportedObjectPtr pObj = builder(args);
+ pObj->setTypeInfo(&def);
+ return pObj;
+}
+
+string TypeRegistry::getDTD() const
+{
+ if (m_TypeDefs.empty()) {
+ return string("");
+ }
+
+ stringstream ss;
+
+ for (TypeDefMap::const_iterator defIt = m_TypeDefs.begin();
+ defIt != m_TypeDefs.end(); defIt++)
+ {
+ const TypeDefinition& def = defIt->second;
+ if (!def.isAbstract()) {
+ writeTypeDTD(def, ss);
+ }
+ }
+
+ for (TypeDefMap::const_iterator defIt = m_TypeDefs.begin();
+ defIt != m_TypeDefs.end(); defIt++)
+ {
+ const TypeDefinition& def = defIt->second;
+ if (!def.isAbstract()) {
+ ss << def.getDTDElements();
+ }
+ }
+
+ return ss.str();
+}
+
+TypeDefinition& TypeRegistry::getTypeDef(const string& sType)
+{
+ TypeDefMap::iterator it = m_TypeDefs.find(sType);
+ if (it == m_TypeDefs.end()) {
+ throw (Exception (AVG_ERR_XML_NODE_UNKNOWN,
+ string("Unknown node type ") + sType + " encountered."));
+ }
+ return it->second;
+}
+
+void TypeRegistry::writeTypeDTD(const TypeDefinition& def, stringstream& ss) const
+{
+ ss << "<!ELEMENT " << def.getName() << " " << def.getDTDChildrenString() << " >\n";
+ if (!def.getDefaultArgs().getArgMap().empty()) {
+ ss << "<!ATTLIST " << def.getName();
+ for (ArgMap::const_iterator argIt = def.getDefaultArgs().getArgMap().begin();
+ argIt != def.getDefaultArgs().getArgMap().end(); argIt++)
+ {
+ string argName = argIt->first;
+ string argType = (argName == "id") ? "ID" : "CDATA";
+ string argRequired = def.getDefaultArgs().getArg(argName)->isRequired() ?
+ "#REQUIRED" : "#IMPLIED";
+ ss << "\n " << argName << " " << argType << " " << argRequired;
+ }
+ ss << " >\n";
+ }
+}
+
+}
diff --git a/src/player/TypeRegistry.h b/src/player/TypeRegistry.h
new file mode 100644
index 0000000..3b38018
--- /dev/null
+++ b/src/player/TypeRegistry.h
@@ -0,0 +1,65 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+// Original author of this file is Nick Hebner (hebnern@gmail.com).
+//
+
+#ifndef _TypeRegistry_H_
+#define _TypeRegistry_H_
+
+#include "../api.h"
+#include "WrapPython.h"
+#include "Node.h"
+#include "ArgList.h"
+#include "TypeDefinition.h"
+
+#include <map>
+#include <string>
+#include <sstream>
+
+namespace avg {
+
+class AVG_API TypeRegistry
+{
+public:
+ virtual ~TypeRegistry();
+ static TypeRegistry* get();
+
+ void registerType(const TypeDefinition& def, const char* pParentNames[] = 0);
+ void updateDefinition(const TypeDefinition& def);
+ TypeDefinition& getTypeDef(const std::string& Type);
+ ExportedObjectPtr createObject(const std::string& Type, const xmlNodePtr xmlNode);
+ ExportedObjectPtr createObject(const std::string& Type, const py::dict& PyDict);
+
+ std::string getDTD() const;
+
+private:
+ TypeRegistry();
+ void writeTypeDTD(const TypeDefinition& def, std::stringstream& ss) const;
+
+ typedef std::map<std::string, TypeDefinition> TypeDefMap;
+ TypeDefMap m_TypeDefs;
+
+ static TypeRegistry* s_pInstance;
+};
+
+}
+
+#endif
diff --git a/src/player/VectorNode.cpp b/src/player/VectorNode.cpp
new file mode 100644
index 0000000..f484a3b
--- /dev/null
+++ b/src/player/VectorNode.cpp
@@ -0,0 +1,524 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "VectorNode.h"
+
+#include "TypeDefinition.h"
+#include "OGLSurface.h"
+#include "Image.h"
+
+#include "../base/Exception.h"
+#include "../base/Logger.h"
+#include "../base/ScopeTimer.h"
+#include "../base/Exception.h"
+#include "../base/WideLine.h"
+#include "../base/GeomHelper.h"
+#include "../base/Triangle.h"
+#include "../base/ObjectCounter.h"
+
+#include "../graphics/VertexArray.h"
+#include "../graphics/Filterfliprgb.h"
+
+#include "../glm/gtx/norm.hpp"
+
+#include <iostream>
+#include <sstream>
+
+using namespace std;
+using namespace boost;
+
+namespace avg {
+
+void VectorNode::registerType()
+{
+ TypeDefinition def = TypeDefinition("vectornode", "node")
+ .addArg(Arg<string>("color", "FFFFFF", false, offsetof(VectorNode, m_sColorName)))
+ .addArg(Arg<float>("strokewidth", 1, false, offsetof(VectorNode, m_StrokeWidth)))
+ .addArg(Arg<UTF8String>("texhref", "", false, offsetof(VectorNode, m_TexHRef)))
+ .addArg(Arg<string>("blendmode", "blend", false,
+ offsetof(VectorNode, m_sBlendMode)))
+ ;
+ TypeRegistry::get()->registerType(def);
+}
+
+VectorNode::VectorNode(const ArgList& args)
+ : m_Transform(glm::mat4(0))
+{
+ m_pShape = ShapePtr(createDefaultShape());
+
+ ObjectCounter::get()->incRef(&typeid(*this));
+ m_TexHRef = args.getArgVal<UTF8String>("texhref");
+ setTexHRef(m_TexHRef);
+ m_sColorName = args.getArgVal<string>("color");
+ m_Color = colorStringToColor(m_sColorName);
+}
+
+VectorNode::~VectorNode()
+{
+ ObjectCounter::get()->decRef(&typeid(*this));
+}
+
+void VectorNode::connectDisplay()
+{
+ setDrawNeeded();
+ m_Color = colorStringToColor(m_sColorName);
+ Node::connectDisplay();
+ m_pShape->moveToGPU();
+ setBlendModeStr(m_sBlendMode);
+}
+
+void VectorNode::connect(CanvasPtr pCanvas)
+{
+ Node::connect(pCanvas);
+ checkReload();
+}
+
+void VectorNode::disconnect(bool bKill)
+{
+ if (bKill) {
+ m_pShape->discard();
+ } else {
+ m_pShape->moveToCPU();
+ }
+ Node::disconnect(bKill);
+}
+
+void VectorNode::checkReload()
+{
+ Node::checkReload(m_TexHRef, m_pShape->getImage());
+ if (getState() == Node::NS_CANRENDER) {
+ m_pShape->moveToGPU();
+ setDrawNeeded();
+ }
+}
+
+const UTF8String& VectorNode::getTexHRef() const
+{
+ return m_TexHRef;
+}
+
+void VectorNode::setTexHRef(const UTF8String& href)
+{
+ m_TexHRef = href;
+ checkReload();
+ setDrawNeeded();
+}
+
+void VectorNode::setBitmap(BitmapPtr pBmp)
+{
+ m_TexHRef = "";
+ m_pShape->setBitmap(pBmp);
+ setDrawNeeded();
+}
+
+const string& VectorNode::getBlendModeStr() const
+{
+ return m_sBlendMode;
+}
+
+void VectorNode::setBlendModeStr(const string& sBlendMode)
+{
+ m_sBlendMode = sBlendMode;
+ m_BlendMode = GLContext::stringToBlendMode(sBlendMode);
+}
+
+static ProfilingZoneID PrerenderProfilingZone("VectorNode::prerender");
+
+void VectorNode::preRender(const VertexArrayPtr& pVA, bool bIsParentActive,
+ float parentEffectiveOpacity)
+{
+ Node::preRender(pVA, bIsParentActive, parentEffectiveOpacity);
+ {
+ ScopeTimer timer(PrerenderProfilingZone);
+ VertexDataPtr pShapeVD = m_pShape->getVertexData();
+ if (m_bDrawNeeded) {
+ pShapeVD->reset();
+ Pixel32 color = getColorVal();
+ calcVertexes(pShapeVD, color);
+ m_bDrawNeeded = false;
+ }
+ if (isVisible()) {
+ m_pShape->setVertexArray(pVA);
+ }
+ }
+}
+
+void VectorNode::maybeRender(const glm::mat4& parentTransform)
+{
+ AVG_ASSERT(getState() == NS_CANRENDER);
+ if (isVisible()) {
+ m_Transform = parentTransform;
+ GLContext::getMain()->setBlendMode(m_BlendMode);
+ render();
+ }
+}
+
+static ProfilingZoneID RenderProfilingZone("VectorNode::render");
+
+void VectorNode::render()
+{
+ ScopeTimer timer(RenderProfilingZone);
+ float curOpacity = getEffectiveOpacity();
+ if (curOpacity > 0.01) {
+ m_pShape->draw(m_Transform, curOpacity);
+ }
+}
+
+void VectorNode::setColor(const string& sColor)
+{
+ if (m_sColorName != sColor) {
+ m_sColorName = sColor;
+ m_Color = colorStringToColor(m_sColorName);
+ m_bDrawNeeded = true;
+ }
+}
+
+const string& VectorNode::getColor() const
+{
+ return m_sColorName;
+}
+
+void VectorNode::setStrokeWidth(float width)
+{
+ if (width != m_StrokeWidth) {
+ m_bDrawNeeded = true;
+ m_StrokeWidth = width;
+ }
+}
+
+float VectorNode::getStrokeWidth() const
+{
+ return m_StrokeWidth;
+}
+
+Pixel32 VectorNode::getColorVal() const
+{
+ return m_Color;
+}
+
+GLContext::BlendMode VectorNode::getBlendMode() const
+{
+ return m_BlendMode;
+}
+
+VectorNode::LineJoin VectorNode::string2LineJoin(const string& s)
+{
+ if (s == "miter") {
+ return LJ_MITER;
+ } else if (s == "bevel") {
+ return LJ_BEVEL;
+ } else {
+ throw(Exception(AVG_ERR_UNSUPPORTED,
+ "Vector linejoin "+s+" not supported."));
+ }
+}
+
+string VectorNode::lineJoin2String(LineJoin lineJoin)
+{
+ switch(lineJoin) {
+ case LJ_MITER:
+ return "miter";
+ case LJ_BEVEL:
+ return "bevel";
+ default:
+ AVG_ASSERT(false);
+ return 0;
+ }
+}
+
+void VectorNode::setDrawNeeded()
+{
+ m_bDrawNeeded = true;
+}
+
+bool VectorNode::isDrawNeeded()
+{
+ return m_bDrawNeeded;
+}
+
+void VectorNode::calcPolyLineCumulDist(vector<float>& cumulDists,
+ const vector<glm::vec2>& pts, bool bIsClosed)
+{
+ cumulDists.clear();
+ cumulDists.reserve(pts.size());
+ if (!pts.empty()) {
+ vector<float> distances;
+ distances.reserve(pts.size());
+ float totalDist = 0;
+ for (unsigned i = 1; i < pts.size(); ++i) {
+ float dist = glm::length(pts[i] - pts[i-1]);
+ distances.push_back(dist);
+ totalDist += dist;
+ }
+ if (bIsClosed) {
+ float dist = glm::length(pts[pts.size()-1] - pts[0]);
+ distances.push_back(dist);
+ totalDist += dist;
+ }
+
+ float cumulDist = 0;
+ cumulDists.push_back(0);
+ for (unsigned i = 0; i < distances.size(); ++i) {
+ cumulDist += distances[i]/totalDist;
+ cumulDists.push_back(cumulDist);
+ }
+ }
+}
+
+void VectorNode::calcEffPolyLineTexCoords(vector<float>& effTC,
+ const vector<float>& tc, const vector<float>& cumulDist)
+{
+ if (tc.empty()) {
+ effTC = cumulDist;
+ } else if (tc.size() == cumulDist.size()) {
+ effTC = tc;
+ } else {
+ effTC.reserve(cumulDist.size());
+ effTC = tc;
+ float minGivenTexCoord = tc[0];
+ float maxGivenTexCoord = tc[tc.size()-1];
+ float maxCumulDist = cumulDist[tc.size()-1];
+ int baselineDist = 0;
+ for (unsigned i = tc.size(); i < cumulDist.size(); ++i) {
+ int repeatFactor = int(cumulDist[i]/maxCumulDist);
+ float effCumulDist = fmod(cumulDist[i], maxCumulDist);
+ while (cumulDist[baselineDist+1] < effCumulDist) {
+ baselineDist++;
+ }
+ float ratio = (effCumulDist-cumulDist[baselineDist])/
+ (cumulDist[baselineDist+1]-cumulDist[baselineDist]);
+ float rawTexCoord = (1-ratio)*tc[baselineDist] +ratio*tc[baselineDist+1];
+ float texCoord = rawTexCoord
+ +repeatFactor*(maxGivenTexCoord-minGivenTexCoord);
+ effTC.push_back(texCoord);
+ }
+ }
+
+}
+
+void VectorNode::calcPolyLine(const vector<glm::vec2>& origPts,
+ const vector<float>& origTexCoords, bool bIsClosed, LineJoin lineJoin,
+ const VertexDataPtr& pVertexData, Pixel32 color)
+{
+ vector<glm::vec2> pts;
+ pts.reserve(origPts.size());
+ vector<float> texCoords;
+ texCoords.reserve(origPts.size());
+
+ pts.push_back(origPts[0]);
+ texCoords.push_back(origTexCoords[0]);
+ for (unsigned i = 1; i < origPts.size(); ++i) {
+ if (glm::distance2(origPts[i], origPts[i-1]) > 0.1) {
+ pts.push_back(origPts[i]);
+ texCoords.push_back(origTexCoords[i]);
+ }
+ }
+ if (bIsClosed) {
+ texCoords.push_back(origTexCoords[origTexCoords.size()-1]);
+ }
+
+ int numPts = pts.size();
+
+ // Create array of wide lines.
+ vector<WideLine> lines;
+ lines.reserve(numPts-1);
+ for (int i = 0; i < numPts-1; ++i) {
+ lines.push_back(WideLine(pts[i], pts[i+1], m_StrokeWidth));
+ }
+ if (bIsClosed) {
+ lines.push_back(WideLine(pts[numPts-1], pts[0], m_StrokeWidth));
+ }
+ // First points
+ if (bIsClosed) {
+ WideLine lastLine = lines[lines.size()-1];
+ glm::vec2 pli = getLineLineIntersection(lastLine.pl0, lastLine.dir,
+ lines[0].pl0, lines[0].dir);
+ glm::vec2 pri = getLineLineIntersection(lastLine.pr0, lastLine.dir,
+ lines[0].pr0, lines[0].dir);
+ Triangle tri(lastLine.pl1, lines[0].pl0, pri);
+ if (tri.isClockwise()) {
+ if (!LineSegment(lastLine.pr0, lastLine.pr1).isPointOver(pri) &&
+ !LineSegment(lines[0].pr0, lines[0].pr1).isPointOver(pri))
+ {
+ pri = lines[0].pr1;
+ }
+ } else {
+ if (!LineSegment(lastLine.pl0, lastLine.pl1).isPointOver(pli) &&
+ !LineSegment(lines[0].pl0, lines[0].pl1).isPointOver(pli))
+ {
+ pli = lines[0].pl1;
+ }
+ }
+
+ float curTC = texCoords[0];
+ switch (lineJoin) {
+ case LJ_MITER:
+ pVertexData->appendPos(pli, glm::vec2(curTC,1), color);
+ pVertexData->appendPos(pri, glm::vec2(curTC,0), color);
+ break;
+ case LJ_BEVEL: {
+ if (tri.isClockwise()) {
+ pVertexData->appendPos(lines[0].pl0, glm::vec2(curTC,1), color);
+ pVertexData->appendPos(pri, glm::vec2(curTC,0), color);
+ } else {
+ pVertexData->appendPos(pli, glm::vec2(curTC,1), color);
+ pVertexData->appendPos(lines[0].pr0, glm::vec2(curTC,0), color);
+ }
+ }
+ break;
+ default:
+ AVG_ASSERT(false);
+ break;
+ }
+ } else {
+ pVertexData->appendPos(lines[0].pl0, glm::vec2(texCoords[0],1), color);
+ pVertexData->appendPos(lines[0].pr0, glm::vec2(texCoords[0],0), color);
+ }
+
+ // All complete line segments
+ unsigned numNormalSegments;
+ if (bIsClosed) {
+ numNormalSegments = pts.size();
+ } else {
+ numNormalSegments = pts.size()-2;
+ }
+ for (unsigned i = 0; i < numNormalSegments; ++i) {
+ const WideLine* pLine1 = &(lines[i]);
+ const WideLine* pLine2;
+ if (i == pts.size()-1) {
+ pLine2 = &(lines[0]);
+ } else {
+ pLine2 = &(lines[i+1]);
+ }
+ glm::vec2 pli = getLineLineIntersection(pLine1->pl0, pLine1->dir, pLine2->pl0,
+ pLine2->dir);
+ glm::vec2 pri = getLineLineIntersection(pLine1->pr0, pLine1->dir, pLine2->pr0,
+ pLine2->dir);
+ Triangle tri(pLine1->pl1, pLine2->pl0, pri);
+ if (tri.isClockwise()) {
+ if (!LineSegment(pLine1->pr0, pLine1->pr1).isPointOver(pri) &&
+ !LineSegment(pLine2->pr0, pLine2->pr1).isPointOver(pri))
+ {
+ pri = pLine2->pr1;
+ }
+ } else {
+ if (!LineSegment(pLine1->pl0, pLine1->pl1).isPointOver(pli) &&
+ !LineSegment(pLine2->pl0, pLine2->pl1).isPointOver(pli))
+ {
+ pli = pLine2->pl1;
+ }
+ }
+
+ int curVertex = pVertexData->getNumVerts();
+ float curTC = texCoords[i+1];
+ switch (lineJoin) {
+ case LJ_MITER:
+ pVertexData->appendPos(pli, glm::vec2(curTC,1), color);
+ pVertexData->appendPos(pri, glm::vec2(curTC,0), color);
+ pVertexData->appendQuadIndexes(
+ curVertex-1, curVertex-2, curVertex+1, curVertex);
+ break;
+ case LJ_BEVEL:
+ {
+ float TC0;
+ float TC1;
+ if (tri.isClockwise()) {
+ calcBevelTC(*pLine1, *pLine2, true, texCoords, i+1, TC0, TC1);
+ pVertexData->appendPos(pLine1->pl1, glm::vec2(TC0,1), color);
+ pVertexData->appendPos(pLine2->pl0, glm::vec2(TC1,1), color);
+ pVertexData->appendPos(pri, glm::vec2(curTC,0), color);
+ pVertexData->appendQuadIndexes(
+ curVertex-1, curVertex-2, curVertex+2, curVertex);
+ pVertexData->appendTriIndexes(
+ curVertex, curVertex+1, curVertex+2);
+ } else {
+ calcBevelTC(*pLine1, *pLine2, false, texCoords, i+1, TC0, TC1);
+ pVertexData->appendPos(pLine1->pr1, glm::vec2(TC0,0), color);
+ pVertexData->appendPos(pli, glm::vec2(curTC,1), color);
+ pVertexData->appendPos(pLine2->pr0, glm::vec2(TC1,0), color);
+ pVertexData->appendQuadIndexes(
+ curVertex-2, curVertex-1, curVertex+1, curVertex);
+ pVertexData->appendTriIndexes(
+ curVertex, curVertex+1, curVertex+2);
+ }
+ }
+ break;
+ default:
+ AVG_ASSERT(false);
+ }
+ }
+
+ // Last segment (PolyLine only)
+ if (!bIsClosed) {
+ int curVertex = pVertexData->getNumVerts();
+ float curTC = texCoords[numPts-1];
+ pVertexData->appendPos(lines[numPts-2].pl1, glm::vec2(curTC,1), color);
+ pVertexData->appendPos(lines[numPts-2].pr1, glm::vec2(curTC,0), color);
+ pVertexData->appendQuadIndexes(curVertex-1, curVertex-2, curVertex+1, curVertex);
+ }
+}
+
+void VectorNode::calcBevelTC(const WideLine& line1, const WideLine& line2,
+ bool bIsLeft, const vector<float>& texCoords, unsigned i,
+ float& TC0, float& TC1)
+{
+ float line1Len = line1.getLen();
+ float line2Len = line2.getLen();
+ float triLen;
+ if (bIsLeft) {
+ triLen = glm::length(line1.pl1 - line2.pl0);
+ } else {
+ triLen = glm::length(line1.pr1 - line2.pr0);
+ }
+ float ratio0 = line1Len/(line1Len+triLen/2);
+ TC0 = (1-ratio0)*texCoords[i-1]+ratio0*texCoords[i];
+ float nextTexCoord;
+ if (i == texCoords.size()-1) {
+ nextTexCoord = texCoords[i];
+ } else {
+ nextTexCoord = texCoords[i+1];
+ }
+ float ratio1 = line2Len/(line2Len+triLen/2);
+ TC1 = ratio1*texCoords[i]+(1-ratio1)*nextTexCoord;
+}
+
+int VectorNode::getNumDifferentPts(const vector<glm::vec2>& pts)
+{
+ int numPts = pts.size();
+ for (unsigned i=1; i<pts.size(); ++i) {
+ if (glm::distance2(pts[i], pts[i-1])<0.1) {
+ numPts--;
+ }
+ }
+ return numPts;
+}
+
+const glm::mat4& VectorNode::getTransform() const
+{
+ return m_Transform;
+}
+
+Shape* VectorNode::createDefaultShape() const
+{
+ return new Shape(MaterialInfo(GL_REPEAT, GL_CLAMP_TO_EDGE, false));
+}
+
+}
diff --git a/src/player/VectorNode.h b/src/player/VectorNode.h
new file mode 100644
index 0000000..4568342
--- /dev/null
+++ b/src/player/VectorNode.h
@@ -0,0 +1,120 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _VectorNode_H_
+#define _VectorNode_H_
+
+#include "../api.h"
+#include "Node.h"
+#include "Shape.h"
+
+#include "../base/UTF8String.h"
+#include "../graphics/Pixel32.h"
+#include "../graphics/VertexArray.h"
+#include "../graphics/GLContext.h"
+
+namespace avg {
+
+struct WideLine;
+
+class AVG_API VectorNode : public Node
+{
+ public:
+ enum LineJoin {LJ_MITER, LJ_BEVEL};
+
+ static void registerType();
+
+ VectorNode(const ArgList& args);
+ virtual ~VectorNode();
+ virtual void connectDisplay();
+ virtual void connect(CanvasPtr pCanvas);
+ virtual void disconnect(bool bKill);
+ virtual void checkReload();
+
+ const UTF8String& getTexHRef() const;
+ void setTexHRef(const UTF8String& href);
+ void setBitmap(BitmapPtr pBmp);
+
+ const std::string& getBlendModeStr() const;
+ void setBlendModeStr(const std::string& sBlendMode);
+
+ virtual void preRender(const VertexArrayPtr& pVA, bool bIsParentActive,
+ float parentEffectiveOpacity);
+ virtual void maybeRender(const glm::mat4& parentTransform);
+ virtual void render();
+
+ virtual void calcVertexes(const VertexDataPtr& pVertexData, Pixel32 color) = 0;
+
+ void setColor(const std::string& sColor);
+ const std::string& getColor() const;
+
+ void setStrokeWidth(float width);
+ float getStrokeWidth() const;
+
+ static LineJoin string2LineJoin(const std::string& s);
+ static std::string lineJoin2String(LineJoin lineJoin);
+
+ protected:
+ Pixel32 getColorVal() const;
+ GLContext::BlendMode getBlendMode() const;
+
+ void setDrawNeeded();
+ bool isDrawNeeded();
+ bool hasVASizeChanged();
+ void calcPolyLineCumulDist(std::vector<float>& cumulDist,
+ const std::vector<glm::vec2>& pts, bool bIsClosed);
+ void calcEffPolyLineTexCoords(std::vector<float>& effTC,
+ const std::vector<float>& tc, const std::vector<float>& cumulDist);
+
+ void calcPolyLine(const std::vector<glm::vec2>& origPts,
+ const std::vector<float>& origTexCoords, bool bIsClosed,
+ LineJoin lineJoin, const VertexDataPtr& pVertexData, Pixel32 color);
+ void calcBevelTC(const WideLine& line1, const WideLine& line2,
+ bool bIsLeft, const std::vector<float>& texCoords, unsigned i,
+ float& TC0, float& TC1);
+ int getNumDifferentPts(const std::vector<glm::vec2>& pts);
+
+ protected:
+ const glm::mat4& getTransform() const;
+
+ private:
+ Shape* createDefaultShape() const;
+
+ std::string m_sColorName;
+ Pixel32 m_Color;
+ float m_StrokeWidth;
+ UTF8String m_TexHRef;
+ std::string m_sBlendMode;
+
+ bool m_bDrawNeeded;
+ bool m_bVASizeChanged;
+
+ glm::mat4 m_Transform;
+ ShapePtr m_pShape;
+ GLContext::BlendMode m_BlendMode;
+};
+
+typedef boost::shared_ptr<VectorNode> VectorNodePtr;
+
+}
+
+#endif
+
diff --git a/src/player/VersionInfo.cpp b/src/player/VersionInfo.cpp
new file mode 100644
index 0000000..3ab861b
--- /dev/null
+++ b/src/player/VersionInfo.cpp
@@ -0,0 +1,72 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "VersionInfo.h"
+#include "../version.h"
+
+namespace avg {
+
+const std::string VersionInfo::getFull()
+{
+ return std::string(AVG_VERSION_FULL);
+}
+
+const std::string VersionInfo::getRelease()
+{
+ return std::string(AVG_VERSION_RELEASE);
+}
+
+const std::string VersionInfo::getBranchUrl()
+{
+ return std::string(AVG_VERSION_BRANCH_URL);
+}
+
+const std::string VersionInfo::getBuilder()
+{
+ return std::string(AVG_VERSION_BUILDER);
+}
+
+const std::string VersionInfo::getBuildTime()
+{
+ return std::string(AVG_VERSION_BUILDTIME);
+}
+
+const std::string VersionInfo::getMajor()
+{
+ return AVG_VERSION_MAJOR;
+}
+
+const std::string VersionInfo::getMinor()
+{
+ return AVG_VERSION_MINOR;
+}
+
+const std::string VersionInfo::getMicro()
+{
+ return AVG_VERSION_MICRO;
+}
+
+int VersionInfo::getRevision()
+{
+ return AVG_VERSION_REVISION;
+}
+
+}
diff --git a/src/player/VersionInfo.h b/src/player/VersionInfo.h
new file mode 100644
index 0000000..5a01e7e
--- /dev/null
+++ b/src/player/VersionInfo.h
@@ -0,0 +1,47 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _VersionInfo_H_
+#define _VersionInfo_H_
+
+#include "../api.h"
+#include <string>
+
+namespace avg {
+
+class AVG_API VersionInfo
+{
+ public:
+ const std::string getFull();
+ const std::string getRelease();
+ const std::string getBranchUrl();
+ const std::string getBuilder();
+ const std::string getBuildTime();
+ const std::string getMajor();
+ const std::string getMinor();
+ const std::string getMicro();
+ int getRevision();
+};
+
+}
+
+#endif
+
diff --git a/src/player/VideoNode.cpp b/src/player/VideoNode.cpp
new file mode 100644
index 0000000..75b2ccc
--- /dev/null
+++ b/src/player/VideoNode.cpp
@@ -0,0 +1,812 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+#include "VideoNode.h"
+#include "Player.h"
+#include "OGLSurface.h"
+#include "TypeDefinition.h"
+#include "Canvas.h"
+
+#include "../base/Exception.h"
+#include "../base/Logger.h"
+#include "../base/ScopeTimer.h"
+#include "../base/XMLHelper.h"
+#include "../base/ObjectCounter.h"
+
+#include "../graphics/Filterfill.h"
+#include "../graphics/GLTexture.h"
+#include "../graphics/TextureMover.h"
+
+#include "../audio/AudioEngine.h"
+
+#include "../video/AsyncVideoDecoder.h"
+#include "../video/SyncVideoDecoder.h"
+#ifdef AVG_ENABLE_VDPAU
+#include "../video/VDPAUDecoder.h"
+#endif
+
+#include <iostream>
+#include <sstream>
+
+#ifndef _WIN32
+#include <unistd.h>
+#endif
+
+using namespace boost;
+using namespace std;
+
+namespace avg {
+
+void VideoNode::registerType()
+{
+ TypeDefinition def = TypeDefinition("video", "rasternode",
+ ExportedObject::buildObject<VideoNode>)
+ .addArg(Arg<UTF8String>("href", "", false, offsetof(VideoNode, m_href)))
+ .addArg(Arg<bool>("loop", false, false, offsetof(VideoNode, m_bLoop)))
+ .addArg(Arg<bool>("threaded", true, false, offsetof(VideoNode, m_bThreaded)))
+ .addArg(Arg<float>("fps", 0.0, false, offsetof(VideoNode, m_FPS)))
+ .addArg(Arg<int>("queuelength", 8, false,
+ offsetof(VideoNode, m_QueueLength)))
+ .addArg(Arg<float>("volume", 1.0, false, offsetof(VideoNode, m_Volume)))
+ .addArg(Arg<bool>("accelerated", false, false,
+ offsetof(VideoNode, m_bUsesHardwareAcceleration)))
+ .addArg(Arg<bool>("enablesound", true, false,
+ offsetof(VideoNode, m_bEnableSound)))
+ ;
+ TypeRegistry::get()->registerType(def);
+}
+
+VideoNode::VideoNode(const ArgList& args)
+ : m_VideoState(Unloaded),
+ m_bFrameAvailable(false),
+ m_bFirstFrameDecoded(false),
+ m_Filename(""),
+ m_bEOFPending(false),
+ m_pEOFCallback(0),
+ m_FramesTooLate(0),
+ m_FramesPlayed(0),
+ m_SeekBeforeCanRenderTime(0),
+ m_pDecoder(0),
+ m_Volume(1.0),
+ m_bUsesHardwareAcceleration(false),
+ m_bEnableSound(true),
+ m_AudioID(-1)
+{
+ args.setMembers(this);
+ m_Filename = m_href;
+ initFilename(m_Filename);
+ if (!m_bThreaded && m_QueueLength != 8) {
+ throw Exception(AVG_ERR_INVALID_ARGS,
+ "Can't set queue length for unthreaded videos because there is no decoder queue in this case.");
+ }
+ if (m_bThreaded) {
+ m_pDecoder = new AsyncVideoDecoder(m_QueueLength);
+ } else {
+ m_pDecoder = new SyncVideoDecoder();
+ }
+
+ ObjectCounter::get()->incRef(&typeid(*this));
+}
+
+VideoNode::~VideoNode()
+{
+ if (m_pDecoder) {
+ delete m_pDecoder;
+ m_pDecoder = 0;
+ }
+ if (m_pEOFCallback) {
+ Py_DECREF(m_pEOFCallback);
+ }
+ ObjectCounter::get()->decRef(&typeid(*this));
+}
+
+void VideoNode::connectDisplay()
+{
+ checkReload();
+ RasterNode::connectDisplay();
+ long long CurTime = Player::get()->getFrameTime();
+ if (m_VideoState != Unloaded) {
+ startDecoding();
+ }
+ if (m_VideoState == Paused) {
+ m_PauseStartTime = CurTime;
+ }
+}
+
+void VideoNode::connect(CanvasPtr pCanvas)
+{
+ pCanvas->registerFrameEndListener(this);
+ checkReload();
+ RasterNode::connect(pCanvas);
+}
+
+void VideoNode::disconnect(bool bKill)
+{
+ getCanvas()->unregisterFrameEndListener(this);
+ if (bKill) {
+ setEOFCallback(Py_None);
+ }
+ changeVideoState(Unloaded);
+ RasterNode::disconnect(bKill);
+}
+
+void VideoNode::play()
+{
+ changeVideoState(Playing);
+}
+
+void VideoNode::stop()
+{
+ changeVideoState(Unloaded);
+}
+
+void VideoNode::pause()
+{
+ changeVideoState(Paused);
+}
+
+int VideoNode::getNumFrames() const
+{
+ exceptionIfUnloaded("getNumFrames");
+ return m_pDecoder->getVideoInfo().m_NumFrames;
+}
+
+int VideoNode::getCurFrame() const
+{
+ exceptionIfUnloaded("getCurFrame");
+ int curFrame = m_pDecoder->getCurFrame();
+ if (curFrame > 0) {
+ return curFrame;
+ } else {
+ return 0;
+ }
+}
+
+int VideoNode::getNumFramesQueued() const
+{
+ exceptionIfUnloaded("getNumFramesQueued");
+ return m_pDecoder->getNumFramesQueued();
+}
+
+void VideoNode::seekToFrame(int frameNum)
+{
+ if (frameNum < 0) {
+ throw Exception(AVG_ERR_OUT_OF_RANGE,
+ "Can't seek to a negative frame in a video.");
+ }
+ exceptionIfUnloaded("seekToFrame");
+ if (getCurFrame() != frameNum) {
+ long long destTime = (long long)(frameNum*1000.0/m_pDecoder->getStreamFPS());
+ seek(destTime);
+ }
+}
+
+std::string VideoNode::getStreamPixelFormat() const
+{
+ exceptionIfUnloaded("getStreamPixelFormat");
+ return m_pDecoder->getVideoInfo().m_sPixelFormat;
+}
+
+long long VideoNode::getDuration() const
+{
+ exceptionIfUnloaded("getDuration");
+ return (long long)(m_pDecoder->getVideoInfo().m_Duration*1000);
+}
+
+long long VideoNode::getVideoDuration() const
+{
+ exceptionIfUnloaded("getVideoDuration");
+ return (long long)(m_pDecoder->getVideoInfo().m_VideoDuration*1000);
+}
+
+long long VideoNode::getAudioDuration() const
+{
+ exceptionIfUnloaded("getAudioDuration");
+ if (!hasAudio()) {
+ throw Exception(AVG_ERR_INVALID_ARGS, "Video has no audio track.");
+ }
+
+ return (long long)(m_pDecoder->getVideoInfo().m_AudioDuration*1000);
+}
+
+int VideoNode::getBitrate() const
+{
+ exceptionIfUnloaded("getBitrate");
+ return m_pDecoder->getVideoInfo().m_Bitrate;
+}
+std::string VideoNode::getContainerFormat() const
+{
+ exceptionIfUnloaded("getContainerFormat");
+ return m_pDecoder->getVideoInfo().m_sContainerFormat;
+}
+
+string VideoNode::getVideoCodec() const
+{
+ exceptionIfUnloaded("getVideoCodec");
+ return m_pDecoder->getVideoInfo().m_sVCodec;
+}
+
+std::string VideoNode::getAudioCodec() const
+{
+ exceptionIfNoAudio("getAudioCodec");
+ return m_pDecoder->getVideoInfo().m_sACodec;
+}
+
+int VideoNode::getAudioSampleRate() const
+{
+ exceptionIfNoAudio("getAudioSampleRate");
+ return m_pDecoder->getVideoInfo().m_SampleRate;
+}
+
+int VideoNode::getNumAudioChannels() const
+{
+ exceptionIfNoAudio("getNumAudioChannels");
+ return m_pDecoder->getVideoInfo().m_NumAudioChannels;
+}
+
+long long VideoNode::getCurTime() const
+{
+ if (m_VideoState == Unloaded) {
+ return 0;
+ } else {
+ long long curTime = (long long)(m_pDecoder->getCurTime()*1000);
+ if (curTime > 0) {
+ return curTime;
+ } else {
+ return 0;
+ }
+ }
+}
+
+void VideoNode::seekToTime(long long time)
+{
+ if (time < 0) {
+ throw Exception(AVG_ERR_OUT_OF_RANGE,
+ "Can't seek to a negative time in a video.");
+ }
+ exceptionIfUnloaded("seekToTime");
+ seek(time);
+ m_bSeekPending = true;
+}
+
+bool VideoNode::getLoop() const
+{
+ return m_bLoop;
+}
+
+bool VideoNode::isThreaded() const
+{
+ return m_bThreaded;
+}
+
+bool VideoNode::hasAudio() const
+{
+ exceptionIfUnloaded("hasAudio");
+ return m_pDecoder->getVideoInfo().m_bHasAudio;
+}
+
+bool VideoNode::hasAlpha() const
+{
+ exceptionIfUnloaded("hasAlpha");
+ PixelFormat pf = getPixelFormat();
+ return pixelFormatHasAlpha(pf);
+}
+
+void VideoNode::setEOFCallback(PyObject * pEOFCallback)
+{
+ if (m_pEOFCallback) {
+ Py_DECREF(m_pEOFCallback);
+ }
+ if (pEOFCallback == Py_None) {
+ m_pEOFCallback = 0;
+ } else {
+ avgDeprecationWarning("1.8", "VideoNode.setEOFCallback()",
+ "Node.subscribe(END_OF_FILE)");
+ Py_INCREF(pEOFCallback);
+ m_pEOFCallback = pEOFCallback;
+ }
+}
+
+bool VideoNode::isAccelerated() const
+{
+ exceptionIfUnloaded("isAccelerated");
+ return m_bUsesHardwareAcceleration;
+}
+
+const UTF8String& VideoNode::getHRef() const
+{
+ return m_href;
+}
+
+void VideoNode::setHRef(const UTF8String& href)
+{
+ m_href = href;
+ checkReload();
+}
+
+float VideoNode::getVolume()
+{
+ return m_Volume;
+}
+
+void VideoNode::setVolume(float volume)
+{
+ if (volume < 0) {
+ volume = 0;
+ }
+ m_Volume = volume;
+ if (m_AudioID != -1) {
+ AudioEngine::get()->setSourceVolume(m_AudioID, volume);
+ }
+}
+
+void VideoNode::checkReload()
+{
+ string fileName (m_href);
+ if (m_href != "") {
+ initFilename(fileName);
+ if (fileName != m_Filename && m_VideoState != Unloaded) {
+ changeVideoState(Unloaded);
+ m_Filename = fileName;
+ changeVideoState(Paused);
+ } else {
+ m_Filename = fileName;
+ }
+ } else {
+ changeVideoState(Unloaded);
+ m_Filename = "";
+ }
+ RasterNode::checkReload();
+}
+
+void VideoNode::onFrameEnd()
+{
+ AsyncVideoDecoder* pAsyncDecoder = dynamic_cast<AsyncVideoDecoder*>(m_pDecoder);
+ if (pAsyncDecoder && (m_VideoState == Playing || m_VideoState == Paused)) {
+ pAsyncDecoder->updateAudioStatus();
+ }
+ if (m_bEOFPending) {
+ // If the VideoNode is unlinked by python in onEOF, the following line prevents
+ // the object from being deleted until we return from this function.
+ NodePtr pTempThis = getSharedThis();
+ m_bEOFPending = false;
+ onEOF();
+ }
+}
+
+void VideoNode::changeVideoState(VideoState newVideoState)
+{
+ long long curTime = Player::get()->getFrameTime();
+ if (m_VideoState == newVideoState) {
+ return;
+ }
+ if (m_VideoState == Unloaded) {
+ m_PauseStartTime = curTime;
+ open();
+ }
+ if (newVideoState == Unloaded) {
+ close();
+ }
+ if (getState() == NS_CANRENDER) {
+ if (m_VideoState == Unloaded) {
+ startDecoding();
+ }
+ if (newVideoState == Paused) {
+ m_PauseStartTime = curTime;
+ if (m_AudioID != -1) {
+ AudioEngine::get()->pauseSource(m_AudioID);
+ }
+ } else if (newVideoState == Playing && m_VideoState == Paused) {
+/*
+ cerr << "Play after pause:" << endl;
+ cerr << " getFrameTime()=" << curTime << endl;
+ cerr << " m_PauseStartTime=" << m_PauseStartTime << endl;
+ cerr << " offset=" << (1000.0/m_pDecoder->getFPS()) << endl;
+*/
+ if (m_AudioID != -1) {
+ AudioEngine::get()->playSource(m_AudioID);
+ }
+ m_PauseTime += (curTime-m_PauseStartTime
+ - (long long)(1000.0/m_pDecoder->getFPS()));
+ }
+ }
+ m_VideoState = newVideoState;
+}
+
+void VideoNode::seek(long long destTime)
+{
+ if (getState() == NS_CANRENDER) {
+ if (m_AudioID != -1) {
+ AudioEngine::get()->notifySeek(m_AudioID);
+ }
+ m_pDecoder->seek(float(destTime)/1000.0f);
+ m_StartTime = Player::get()->getFrameTime() - destTime;
+ m_JitterCompensation = 0.5;
+ m_PauseTime = 0;
+ m_PauseStartTime = Player::get()->getFrameTime();
+ m_bFrameAvailable = false;
+ m_bSeekPending = true;
+ } else {
+ // If we get a seek command before decoding has really started, we need to defer
+ // the actual seek until the decoder is ready.
+ m_SeekBeforeCanRenderTime = destTime;
+ }
+}
+
+void VideoNode::open()
+{
+ m_FramesTooLate = 0;
+ m_FramesInRowTooLate = 0;
+ m_FramesPlayed = 0;
+ m_pDecoder->open(m_Filename, m_bUsesHardwareAcceleration, m_bEnableSound);
+ VideoInfo videoInfo = m_pDecoder->getVideoInfo();
+ if (!videoInfo.m_bHasVideo) {
+ m_pDecoder->close();
+ throw Exception(AVG_ERR_VIDEO_GENERAL,
+ string("Video: Opening "+m_Filename+" failed. No video stream found."));
+ }
+ m_StartTime = Player::get()->getFrameTime();
+ m_JitterCompensation = 0.5;
+ m_PauseTime = 0;
+
+ m_bSeekPending = false;
+ m_bFirstFrameDecoded = false;
+ m_bFrameAvailable = false;
+ m_bUsesHardwareAcceleration = videoInfo.m_bUsesVDPAU;
+ setViewport(-32767, -32767, -32767, -32767);
+}
+
+void VideoNode::startDecoding()
+{
+ const AudioParams * pAP = 0;
+ AudioEngine* pAudioEngine = AudioEngine::get();
+ if (pAudioEngine) {
+ pAP = pAudioEngine->getParams();
+ }
+ m_pDecoder->startDecoding(GLContext::getMain()->useGPUYUVConversion(), pAP);
+ VideoInfo videoInfo = m_pDecoder->getVideoInfo();
+ if (m_FPS != 0.0) {
+ if (videoInfo.m_bHasAudio) {
+ AVG_LOG_WARNING(getID() + ": Can't set FPS if video contains audio. Ignored.");
+ } else {
+ m_pDecoder->setFPS(m_FPS);
+ }
+ }
+ if (videoInfo.m_bHasAudio && pAudioEngine) {
+ AsyncVideoDecoder* pAsyncDecoder =
+ dynamic_cast<AsyncVideoDecoder*>(m_pDecoder);
+ m_AudioID = pAudioEngine->addSource(*pAsyncDecoder->getAudioMsgQ(),
+ *pAsyncDecoder->getAudioStatusQ());
+ pAudioEngine->setSourceVolume(m_AudioID, m_Volume);
+ }
+ m_bSeekPending = true;
+
+ createTextures(videoInfo.m_Size);
+
+ if (m_SeekBeforeCanRenderTime != 0) {
+ seek(m_SeekBeforeCanRenderTime);
+ m_SeekBeforeCanRenderTime = 0;
+ }
+}
+
+void VideoNode::createTextures(IntPoint size)
+{
+ PixelFormat pf = getPixelFormat();
+ bool bMipmap = getMaterial().getUseMipmaps();
+ if (pixelFormatIsPlanar(pf)) {
+ m_pTextures[0] = GLTexturePtr(new GLTexture(size, I8, bMipmap));
+ IntPoint halfSize(size.x/2, size.y/2);
+ m_pTextures[1] = GLTexturePtr(new GLTexture(halfSize, I8, bMipmap, 128));
+ m_pTextures[2] = GLTexturePtr(new GLTexture(halfSize, I8, bMipmap, 128));
+ if (pixelFormatHasAlpha(pf)) {
+ m_pTextures[3] = GLTexturePtr(new GLTexture(size, I8, bMipmap));
+ }
+ } else {
+ m_pTextures[0] = GLTexturePtr(new GLTexture(size, pf, bMipmap));
+ }
+ for (unsigned i=0; i<getNumPixelFormatPlanes(pf); ++i) {
+ m_pTextures[i]->enableStreaming();
+ }
+ if (pf == B8G8R8X8 || pf == B8G8R8A8) {
+ FilterFill<Pixel32> Filter(Pixel32(0,0,0,255));
+ BitmapPtr pBmp = m_pTextures[0]->lockStreamingBmp();
+ Filter.applyInPlace(pBmp);
+ m_pTextures[0]->unlockStreamingBmp(true);
+ }
+ if (pixelFormatIsPlanar(pf)) {
+ if (pixelFormatHasAlpha(pf)) {
+ getSurface()->create(pf, m_pTextures[0], m_pTextures[1], m_pTextures[2],
+ m_pTextures[3]);
+ } else {
+ getSurface()->create(pf, m_pTextures[0], m_pTextures[1], m_pTextures[2]);
+ }
+ } else {
+ getSurface()->create(pf, m_pTextures[0]);
+ }
+ newSurface();
+}
+
+void VideoNode::close()
+{
+ AudioEngine* pAudioEngine = AudioEngine::get();
+ if (m_AudioID != -1) {
+ pAudioEngine->removeSource(m_AudioID);
+ m_AudioID = -1;
+ }
+ m_pDecoder->close();
+ if (m_FramesTooLate > 0) {
+ string sID;
+ if (getID() == "") {
+ sID = m_href;
+ } else {
+ sID = getID();
+ }
+ AVG_TRACE(Logger::category::PROFILE_VIDEO, Logger::severity::INFO,
+ "Missed video frames for '" << sID << "': " << m_FramesTooLate <<
+ " of " << m_FramesPlayed);
+ m_FramesTooLate = 0;
+ }
+}
+
+PixelFormat VideoNode::getPixelFormat() const
+{
+ return m_pDecoder->getPixelFormat();
+}
+
+IntPoint VideoNode::getMediaSize()
+{
+ if (m_pDecoder && m_pDecoder->getState() != VideoDecoder::CLOSED) {
+ return m_pDecoder->getSize();
+ } else {
+ return IntPoint(0,0);
+ }
+}
+
+float VideoNode::getFPS() const
+{
+ return m_pDecoder->getFPS();
+}
+
+int VideoNode::getQueueLength() const
+{
+ return m_QueueLength;
+}
+
+long long VideoNode::getNextFrameTime() const
+{
+ switch (m_VideoState) {
+ case Unloaded:
+ return 0;
+ case Paused:
+ AVG_ASSERT(m_PauseStartTime-m_StartTime >= 0);
+ return m_PauseStartTime-m_StartTime;
+ case Playing:
+ {
+ if (Player::get()->getFrameTime()-m_StartTime-m_PauseTime < 0) {
+ cerr << "getNextFrameTime < 0" << endl;
+ cerr << "getFrameTime(): " << Player::get()->getFrameTime() << endl;
+ cerr << "m_StartTime: " << m_StartTime << endl;
+ cerr << "m_PauseTime: " << m_PauseTime << endl;
+ }
+ long long nextFrameTime = Player::get()->getFrameTime()-m_StartTime
+ -m_PauseTime
+ -(long long)(m_JitterCompensation*1000.0/
+ Player::get()->getFramerate());
+ if (nextFrameTime < 0) {
+ nextFrameTime = 0;
+ }
+ return nextFrameTime;
+ }
+ default:
+ AVG_ASSERT(false);
+ return 0;
+ }
+}
+
+void VideoNode::exceptionIfNoAudio(const std::string& sFuncName) const
+{
+ exceptionIfUnloaded(sFuncName);
+ if (!hasAudio()) {
+ throw Exception(AVG_ERR_VIDEO_GENERAL,
+ string("VideoNode.")+sFuncName+" failed: no audio stream.");
+ }
+}
+
+void VideoNode::exceptionIfUnloaded(const std::string& sFuncName) const
+{
+ if (m_VideoState == Unloaded) {
+ throw Exception(AVG_ERR_VIDEO_GENERAL,
+ string("VideoNode.")+sFuncName+" failed: video not loaded.");
+ }
+}
+
+static ProfilingZoneID PrerenderProfilingZone("VideoNode::prerender");
+
+void VideoNode::preRender(const VertexArrayPtr& pVA, bool bIsParentActive,
+ float parentEffectiveOpacity)
+{
+ ScopeTimer timer(PrerenderProfilingZone);
+ Node::preRender(pVA, bIsParentActive, parentEffectiveOpacity);
+ if (isVisible()) {
+ if (m_VideoState != Unloaded) {
+ if (m_VideoState == Playing) {
+ bool bNewFrame = renderFrame();
+ m_bFrameAvailable |= bNewFrame;
+ } else { // Paused
+ if (!m_bFrameAvailable) {
+ m_bFrameAvailable = renderFrame();
+ }
+ }
+ m_bFirstFrameDecoded |= m_bFrameAvailable;
+ if (m_bFirstFrameDecoded) {
+ renderFX(getSize(), Pixel32(255, 255, 255, 255), false);
+ }
+ }
+ } else {
+ if (m_VideoState != Unloaded && m_bSeekPending && m_bFirstFrameDecoded) {
+ renderFrame();
+ }
+ if (m_VideoState == Playing) {
+ // Throw away frames that are not visible to make sure the video
+ // stays in sync.
+ m_pDecoder->throwAwayFrame(getNextFrameTime()/1000.0f);
+
+ if (m_pDecoder->isEOF()) {
+ updateStatusDueToDecoderEOF();
+ }
+ }
+ }
+ calcVertexArray(pVA);
+}
+
+static ProfilingZoneID RenderProfilingZone("VideoNode::render");
+
+void VideoNode::render()
+{
+ ScopeTimer timer(RenderProfilingZone);
+ if (m_VideoState != Unloaded && m_bFirstFrameDecoded) {
+ blt32(getTransform(), getSize(), getEffectiveOpacity(), getBlendMode());
+ }
+}
+
+VideoNode::VideoAccelType VideoNode::getVideoAccelConfig()
+{
+#ifdef AVG_ENABLE_VDPAU
+ if (VDPAUDecoder::isAvailable()) {
+ return VDPAU;
+ }
+#endif
+ return NONE;
+}
+
+bool VideoNode::renderFrame()
+{
+ FrameAvailableCode frameAvailable =
+ m_pDecoder->renderToTexture(m_pTextures, getNextFrameTime()/1000.0f);
+
+ // Even with vsync, frame duration has a bit of jitter. If the video frames rendered
+ // are at the border of a frame's time, this can cause irregular display times.
+ // So, if we detect this condition, we adjust the frame time by a small fraction
+ // to move it towards the center of the time slot.
+ long long jitter = (long long)(getNextFrameTime()-m_pDecoder->getCurTime()*1000);
+ if (jitter > (long long)(0.4*(1000/m_pDecoder->getFPS()))) {
+ m_JitterCompensation += 0.05;
+ if (m_JitterCompensation > 1) {
+ m_JitterCompensation -= 1;
+ }
+ }
+
+ if (m_pDecoder->isEOF()) {
+ updateStatusDueToDecoderEOF();
+ if (m_bLoop) {
+ frameAvailable =
+ m_pDecoder->renderToTexture(m_pTextures, getNextFrameTime()/1000.0f);
+ }
+ }
+
+ switch (frameAvailable) {
+ case FA_NEW_FRAME:
+ m_FramesPlayed++;
+ m_FramesInRowTooLate = 0;
+ m_bSeekPending = false;
+ setMaskCoords();
+// AVG_TRACE(Logger::category::PROFILE, "New frame.");
+ break;
+ case FA_STILL_DECODING:
+ {
+ m_FramesPlayed++;
+ m_FramesTooLate++;
+ m_FramesInRowTooLate++;
+ float framerate = Player::get()->getEffectiveFramerate();
+ long long frameTime = Player::get()->getFrameTime();
+ if (m_VideoState == Playing) {
+ if (m_FramesInRowTooLate > 3 && framerate != 0) {
+ // Heuristic: If we've missed more than 3 frames in a row, we stop
+ // advancing movie time until the decoder has caught up.
+ m_PauseTime += (long long)(1000/framerate);
+ }
+ if (m_bSeekPending) {
+ // The movie time also stays still while waiting for a seek to
+ // complete.
+ m_PauseTime = frameTime-m_PauseStartTime;
+ }
+ long long curMovieTime =
+ Player::get()->getFrameTime()-m_StartTime-m_PauseTime;
+ if (curMovieTime < 0) {
+ cerr << "----------- curTime < 0 -------------" << endl;
+ cerr << "FramesPlayed=" << m_FramesPlayed << endl;
+ cerr << "getFrameTime()=" << Player::get()->getFrameTime()
+ << endl;
+ cerr << "m_StartTime=" << m_StartTime << endl;
+ cerr << "m_PauseTime=" << m_PauseTime << endl;
+ m_PauseTime = Player::get()->getFrameTime()-m_StartTime;
+ }
+ }
+ }
+// AVG_TRACE(Logger::category::PROFILE, "Missed video frame.");
+ break;
+ case FA_USE_LAST_FRAME:
+ m_FramesInRowTooLate = 0;
+ m_bSeekPending = false;
+// AVG_TRACE(Logger::category::PROFILE, "Video frame reused.");
+ break;
+ default:
+ AVG_ASSERT(false);
+ }
+
+ return (frameAvailable == FA_NEW_FRAME);
+}
+
+void VideoNode::onEOF()
+{
+ if (m_pEOFCallback) {
+ PyObject * arglist = Py_BuildValue("()");
+ PyObject * result = PyEval_CallObject(m_pEOFCallback, arglist);
+ Py_DECREF(arglist);
+ if (!result) {
+ throw py::error_already_set();
+ }
+ Py_DECREF(result);
+ }
+ notifySubscribers("END_OF_FILE");
+}
+
+void VideoNode::updateStatusDueToDecoderEOF()
+{
+ m_bEOFPending = true;
+ if (m_bLoop) {
+ m_StartTime = Player::get()->getFrameTime();
+ m_PauseStartTime = Player::get()->getFrameTime();
+ m_JitterCompensation = 0.5;
+ m_PauseTime = 0;
+ m_FramesInRowTooLate = 0;
+ m_bFrameAvailable = false;
+ if (m_AudioID != -1) {
+ AudioEngine::get()->notifySeek(m_AudioID);
+ }
+ m_pDecoder->loop();
+ } else {
+ changeVideoState(Paused);
+ }
+}
+
+
+}
+
diff --git a/src/player/VideoNode.h b/src/player/VideoNode.h
new file mode 100644
index 0000000..2ae2caf
--- /dev/null
+++ b/src/player/VideoNode.h
@@ -0,0 +1,157 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _VideoNode_H_
+#define _VideoNode_H_
+
+// Python docs say python.h should be included before any standard headers (!)
+#include "../api.h"
+#include "WrapPython.h"
+
+#include "Node.h"
+#include "RasterNode.h"
+
+#include "../base/GLMHelper.h"
+#include "../base/IFrameEndListener.h"
+#include "../base/UTF8String.h"
+
+#include "../video/VideoDecoder.h"
+
+namespace avg {
+
+class VideoDecoder;
+class TextureMover;
+typedef boost::shared_ptr<TextureMover> TextureMoverPtr;
+
+class AVG_API VideoNode: public RasterNode, IFrameEndListener
+{
+ public:
+ enum VideoAccelType {NONE, VDPAU};
+
+ static void registerType();
+
+ VideoNode(const ArgList& args);
+ virtual ~VideoNode();
+
+ virtual void connectDisplay();
+ virtual void connect(CanvasPtr pCanvas);
+ virtual void disconnect(bool bKill);
+
+ void play();
+ void stop();
+ void pause();
+
+ const UTF8String& getHRef() const;
+ void setHRef(const UTF8String& href);
+ float getVolume();
+ void setVolume(float volume);
+ float getFPS() const;
+ int getQueueLength() const;
+ void checkReload();
+
+ int getNumFrames() const;
+ int getCurFrame() const;
+ int getNumFramesQueued() const;
+ void seekToFrame(int frameNum);
+ std::string getStreamPixelFormat() const;
+ long long getDuration() const;
+ long long getVideoDuration() const;
+ long long getAudioDuration() const;
+ int getBitrate() const;
+ std::string getContainerFormat() const;
+ std::string getVideoCodec() const;
+ std::string getAudioCodec() const;
+ int getAudioSampleRate() const;
+ int getNumAudioChannels() const;
+
+ long long getCurTime() const;
+ void seekToTime(long long time);
+ bool getLoop() const;
+ bool isThreaded() const;
+ bool hasAudio() const;
+ bool hasAlpha() const;
+ void setEOFCallback(PyObject * pEOFCallback);
+ bool isAccelerated() const;
+
+ virtual void preRender(const VertexArrayPtr& pVA, bool bIsParentActive,
+ float parentEffectiveOpacity);
+ virtual void render();
+ virtual void onFrameEnd();
+
+ virtual IntPoint getMediaSize();
+
+ static VideoAccelType getVideoAccelConfig();
+
+ private:
+ bool renderFrame();
+ void seek(long long destTime);
+ void onEOF();
+ void updateStatusDueToDecoderEOF();
+ void dumpFramesTooLate();
+
+ void open();
+ void startDecoding();
+ void createTextures(IntPoint size);
+ void close();
+ enum VideoState {Unloaded, Paused, Playing};
+ void changeVideoState(VideoState NewVideoState);
+ PixelFormat getPixelFormat() const;
+ long long getNextFrameTime() const;
+ void exceptionIfNoAudio(const std::string& sFuncName) const;
+ void exceptionIfUnloaded(const std::string& sFuncName) const;
+
+ VideoState m_VideoState;
+
+ bool m_bFrameAvailable;
+ bool m_bFirstFrameDecoded;
+
+ UTF8String m_href;
+ std::string m_Filename;
+ bool m_bLoop;
+ bool m_bThreaded;
+ float m_FPS;
+ int m_QueueLength;
+ bool m_bEOFPending;
+ PyObject * m_pEOFCallback;
+ int m_FramesTooLate;
+ int m_FramesInRowTooLate;
+ int m_FramesPlayed;
+ bool m_bSeekPending;
+ long long m_SeekBeforeCanRenderTime;
+
+ long long m_StartTime;
+ long long m_PauseTime;
+ long long m_PauseStartTime;
+ float m_JitterCompensation;
+
+ VideoDecoder * m_pDecoder;
+ float m_Volume;
+ bool m_bUsesHardwareAcceleration;
+ bool m_bEnableSound;
+ int m_AudioID;
+
+ GLTexturePtr m_pTextures[4];
+};
+
+}
+
+#endif
+
diff --git a/src/player/VideoWriter.cpp b/src/player/VideoWriter.cpp
new file mode 100644
index 0000000..e91db38
--- /dev/null
+++ b/src/player/VideoWriter.cpp
@@ -0,0 +1,260 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "VideoWriter.h"
+#include "OffscreenCanvas.h"
+#include "Player.h"
+#include "SDLDisplayEngine.h"
+
+#include "../graphics/FBO.h"
+#include "../graphics/GPURGB2YUVFilter.h"
+#include "../graphics/Filterfill.h"
+#include "../base/StringHelper.h"
+
+#include <boost/bind.hpp>
+
+#include <fcntl.h>
+#include <stdio.h>
+
+using namespace std;
+using namespace boost;
+
+namespace avg {
+
+VideoWriter::VideoWriter(CanvasPtr pCanvas, const string& sOutFileName, int frameRate,
+ int qMin, int qMax, bool bSyncToPlayback)
+ : m_pCanvas(pCanvas),
+ m_sOutFileName(sOutFileName),
+ m_FrameRate(frameRate),
+ m_QMin(qMin),
+ m_QMax(qMax),
+ m_bHasValidData(false),
+ m_bSyncToPlayback(bSyncToPlayback),
+ m_bPaused(false),
+ m_PauseTime(0),
+ m_bStopped(false),
+ m_CurFrame(0),
+ m_StartTime(-1),
+ m_bFramePending(false)
+{
+ if (!pCanvas) {
+ throw Exception(AVG_ERR_INVALID_ARGS, "VideoWriter needs a canvas to write to.");
+ }
+ if (GLContext::getCurrent()->isGLES()) {
+ throw Exception(AVG_ERR_UNSUPPORTED, "VideoWriter not supported under GLES.");
+ }
+#ifdef WIN32
+ int fd = _open(m_sOutFileName.c_str(), O_RDWR | O_CREAT, _S_IREAD | _S_IWRITE);
+#elif defined linux
+ int fd = open64(m_sOutFileName.c_str(), O_RDWR | O_CREAT, S_IRWXU);
+#else
+ int fd = open(m_sOutFileName.c_str(), O_RDWR | O_CREAT, S_IRWXU);
+#endif
+ if (fd == -1) {
+ throw Exception(AVG_ERR_VIDEO_INIT_FAILED,
+ string("Could not open output file '") + m_sOutFileName + "'. Reason: " +
+ strerror(errno));
+ }
+#ifdef WIN32
+ _close(fd);
+#else
+ close(fd);
+#endif
+ remove(m_sOutFileName.c_str());
+ CanvasPtr pMainCanvas = Player::get()->getMainCanvas();
+ if (pMainCanvas == m_pCanvas) {
+ m_FrameSize = Player::get()->getDisplayEngine()->getWindowSize();
+ } else {
+ m_FrameSize = m_pCanvas->getSize();
+ m_pFBO = dynamic_pointer_cast<OffscreenCanvas>(m_pCanvas)->getFBO();
+ if (GLContext::getMain()->useGPUYUVConversion()) {
+ m_pFilter = GPURGB2YUVFilterPtr(new GPURGB2YUVFilter(m_FrameSize));
+ }
+ }
+ VideoWriterThread writer(m_CmdQueue, m_sOutFileName, m_FrameSize, m_FrameRate,
+ qMin, qMax);
+ m_pThread = new boost::thread(writer);
+ m_pCanvas->registerPlaybackEndListener(this);
+ m_pCanvas->registerFrameEndListener(this);
+}
+
+VideoWriter::~VideoWriter()
+{
+ stop();
+ if (m_pThread) {
+ m_pThread->join();
+ delete m_pThread;
+ }
+}
+
+void VideoWriter::stop()
+{
+ if (!m_bStopped) {
+ getFrameFromPBO();
+ if (!m_bHasValidData) {
+ writeDummyFrame();
+ }
+
+ m_bStopped = true;
+ m_CmdQueue.pushCmd(boost::bind(&VideoWriterThread::stop, _1));
+
+ m_pCanvas->unregisterFrameEndListener(this);
+ m_pCanvas->unregisterPlaybackEndListener(this);
+ }
+}
+
+void VideoWriter::pause()
+{
+ if (m_bPaused) {
+ throw Exception(AVG_ERR_UNSUPPORTED, "VideoWriter::pause() called when paused.");
+ }
+ if (m_bStopped) {
+ throw Exception(AVG_ERR_UNSUPPORTED, "VideoWriter::pause() called when stopped.");
+ }
+ m_bPaused = true;
+ m_PauseStartTime = Player::get()->getFrameTime();
+}
+
+void VideoWriter::play()
+{
+ if (!m_bPaused) {
+ throw Exception(AVG_ERR_UNSUPPORTED,
+ "VideoWriter::play() called when not paused.");
+ }
+ m_bPaused = false;
+ m_PauseTime += (Player::get()->getFrameTime() - m_PauseStartTime);
+}
+
+std::string VideoWriter::getFileName() const
+{
+ return m_sOutFileName;
+}
+
+int VideoWriter::getFramerate() const
+{
+ return m_FrameRate;
+}
+
+int VideoWriter::getQMin() const
+{
+ return m_QMin;
+}
+
+int VideoWriter::getQMax() const
+{
+ return m_QMax;
+}
+
+void VideoWriter::onFrameEnd()
+{
+ // The VideoWriter handles OffscreenCanvas and MainCanvas differently:
+ // For MainCanvas, it simply does a screenshot onFrameEnd and sends that to the
+ // VideoWriterThread immediately.
+ // For OffscreenCanvas, an asynchronous PBO readback is started in onFrameEnd.
+ // In the next frame's onFrameEnd, the data is read into a bitmap and sent to
+ // the VideoWriterThread.
+ if (m_pFBO) {
+ // Read last frame's bitmap.
+ getFrameFromPBO();
+ }
+ if (m_StartTime == -1) {
+ m_StartTime = Player::get()->getFrameTime();
+ }
+ if (!m_bPaused) {
+ if (m_bSyncToPlayback) {
+ getFrameFromFBO();
+ } else {
+ long long movieTime = Player::get()->getFrameTime() - m_StartTime
+ - m_PauseTime;
+ float timePerFrame = 1000.f/m_FrameRate;
+ int wantedFrame = int(movieTime/timePerFrame+0.1);
+ if (wantedFrame > m_CurFrame) {
+ getFrameFromFBO();
+ if (wantedFrame > m_CurFrame + 1) {
+ m_CurFrame = wantedFrame - 1;
+ }
+ }
+ }
+ }
+
+ if (!m_pFBO) {
+ getFrameFromPBO();
+ }
+}
+
+void VideoWriter::getFrameFromFBO()
+{
+ if (m_pFBO) {
+ if (m_pFilter) {
+ m_pFilter->apply(m_pFBO->getTex());
+ FBOPtr pYUVFBO = m_pFilter->getFBO();
+ pYUVFBO->moveToPBO();
+ } else {
+ m_pFBO->moveToPBO();
+ }
+ m_bFramePending = true;
+ } else {
+ BitmapPtr pBmp = Player::get()->getDisplayEngine()->screenshot(GL_BACK);
+ sendFrameToEncoder(pBmp);
+ }
+}
+
+void VideoWriter::getFrameFromPBO()
+{
+ if (m_bFramePending) {
+ BitmapPtr pBmp;
+ if (m_pFilter) {
+ pBmp = m_pFilter->getFBO()->getImageFromPBO();
+ } else {
+ pBmp = m_pFBO->getImageFromPBO();
+ }
+ sendFrameToEncoder(pBmp);
+ m_bFramePending = false;
+ }
+}
+
+void VideoWriter::sendFrameToEncoder(BitmapPtr pBitmap)
+{
+ m_CurFrame++;
+ m_bHasValidData = true;
+ if (m_pFilter) {
+ m_CmdQueue.pushCmd(boost::bind(&VideoWriterThread::encodeYUVFrame, _1, pBitmap));
+ } else {
+ m_CmdQueue.pushCmd(boost::bind(&VideoWriterThread::encodeFrame, _1, pBitmap));
+ }
+}
+
+void VideoWriter::onPlaybackEnd()
+{
+ stop();
+ m_pThread->join();
+ delete m_pThread;
+ m_pThread = 0;
+}
+
+void VideoWriter::writeDummyFrame()
+{
+ BitmapPtr pBmp = BitmapPtr(new Bitmap(m_FrameSize, B8G8R8X8));
+ FilterFill<Pixel32>(Pixel32(0,0,0,255)).applyInPlace(pBmp);
+ sendFrameToEncoder(pBmp);
+}
+
+}
diff --git a/src/player/VideoWriter.h b/src/player/VideoWriter.h
new file mode 100644
index 0000000..ef3f724
--- /dev/null
+++ b/src/player/VideoWriter.h
@@ -0,0 +1,99 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _VideoWriter_H_
+#define _VideoWriter_H_
+
+#include "../api.h"
+
+#include "VideoWriterThread.h"
+
+#include "../base/IFrameEndListener.h"
+#include "../base/IPlaybackEndListener.h"
+#include "../base/GLMHelper.h"
+
+#include <boost/shared_ptr.hpp>
+#include <boost/thread.hpp>
+
+#include <string>
+
+namespace avg {
+
+class Canvas;
+typedef boost::shared_ptr<Canvas> CanvasPtr;
+class FBO;
+typedef boost::shared_ptr<FBO> FBOPtr;
+class GPURGB2YUVFilter;
+typedef boost::shared_ptr<GPURGB2YUVFilter> GPURGB2YUVFilterPtr;
+
+class AVG_API VideoWriter : public IFrameEndListener, IPlaybackEndListener
+{
+ public:
+ VideoWriter(CanvasPtr pCanvas, const std::string& sOutFileName,
+ int frameRate=30, int qMin=3, int qMax=5, bool bSyncToPlayback=true);
+ virtual ~VideoWriter();
+ void stop();
+ void pause();
+ void play();
+
+ std::string getFileName() const;
+ int getFramerate() const;
+ int getQMin() const;
+ int getQMax() const;
+
+ virtual void onFrameEnd();
+ virtual void onPlaybackEnd();
+
+ private:
+ void getFrameFromFBO();
+ void getFrameFromPBO();
+
+ void sendFrameToEncoder(BitmapPtr pBitmap);
+ void writeDummyFrame();
+
+ CanvasPtr m_pCanvas;
+ FBOPtr m_pFBO;
+ GPURGB2YUVFilterPtr m_pFilter;
+ std::string m_sOutFileName;
+ int m_FrameRate;
+ int m_QMin;
+ int m_QMax;
+ IntPoint m_FrameSize;
+
+ bool m_bHasValidData;
+
+ VideoWriterThread::CQueue m_CmdQueue;
+ boost::thread* m_pThread;
+ bool m_bSyncToPlayback;
+
+ bool m_bPaused;
+ long long m_PauseStartTime;
+ long long m_PauseTime;
+
+ bool m_bStopped;
+
+ int m_CurFrame;
+ long long m_StartTime;
+ bool m_bFramePending;
+};
+
+}
+#endif
diff --git a/src/player/VideoWriterThread.cpp b/src/player/VideoWriterThread.cpp
new file mode 100644
index 0000000..5ebb654
--- /dev/null
+++ b/src/player/VideoWriterThread.cpp
@@ -0,0 +1,347 @@
+
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "VideoWriterThread.h"
+
+#include "../base/ProfilingZoneID.h"
+#include "../base/ScopeTimer.h"
+#include "../base/StringHelper.h"
+
+#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(55, 18, 102)
+ typedef CodecID AVCodecID;
+#endif
+
+using namespace std;
+
+namespace avg {
+
+const unsigned int VIDEO_BUFFER_SIZE = 400000;
+const AVPixelFormat STREAM_PIXEL_FORMAT = ::PIX_FMT_YUVJ420P;
+
+VideoWriterThread::VideoWriterThread(CQueue& cmdQueue, const string& sFilename,
+ IntPoint size, int frameRate, int qMin, int qMax)
+ : WorkerThread<VideoWriterThread>(sFilename, cmdQueue, Logger::category::PROFILE),
+ m_sFilename(sFilename),
+ m_Size(size),
+ m_FrameRate(frameRate),
+ m_QMin(qMin),
+ m_QMax(qMax),
+ m_pOutputFormatContext()
+{
+}
+
+VideoWriterThread::~VideoWriterThread()
+{
+}
+
+static ProfilingZoneID ProfilingZoneEncodeFrame("Encode frame", true);
+
+void VideoWriterThread::encodeYUVFrame(BitmapPtr pBmp)
+{
+ ScopeTimer timer(ProfilingZoneEncodeFrame);
+ convertYUVImage(pBmp);
+ writeFrame(m_pConvertedFrame);
+ ThreadProfiler::get()->reset();
+}
+
+void VideoWriterThread::encodeFrame(BitmapPtr pBmp)
+{
+ ScopeTimer timer(ProfilingZoneEncodeFrame);
+ convertRGBImage(pBmp);
+ writeFrame(m_pConvertedFrame);
+ ThreadProfiler::get()->reset();
+}
+
+void VideoWriterThread::close()
+{
+ if (m_pOutputFormatContext) {
+ av_write_trailer(m_pOutputFormatContext);
+ avcodec_close(m_pVideoStream->codec);
+
+ for (unsigned int i=0; i<m_pOutputFormatContext->nb_streams; i++) {
+ AVStream* pStream = m_pOutputFormatContext->streams[i];
+
+ pStream->discard = AVDISCARD_ALL;
+ av_freep(&m_pOutputFormatContext->streams[i]->codec);
+ av_freep(&m_pOutputFormatContext->streams[i]);
+ }
+
+ if (!(m_pOutputFormat->flags & AVFMT_NOFILE)) {
+#if LIBAVCODEC_VERSION_INT > AV_VERSION_INT(53, 8, 0)
+ avio_close(m_pOutputFormatContext->pb);
+#else
+ url_fclose(m_pOutputFormatContext->pb);
+#endif
+ }
+
+ av_free(m_pOutputFormatContext);
+ av_free(m_pVideoBuffer);
+ av_free(m_pConvertedFrame);
+ av_free(m_pPictureBuffer);
+ sws_freeContext(m_pFrameConversionContext);
+ m_pOutputFormatContext = 0;
+ }
+}
+
+bool VideoWriterThread::init()
+{
+ open();
+ return true;
+}
+
+bool VideoWriterThread::work()
+{
+ waitForCommand();
+ return true;
+}
+
+void VideoWriterThread::deinit()
+{
+ close();
+}
+
+void VideoWriterThread::open()
+{
+ av_register_all(); // TODO: make sure this is only done once.
+// av_log_set_level(AV_LOG_DEBUG);
+#if LIBAVFORMAT_VERSION_MAJOR > 52
+ m_pOutputFormat = av_guess_format(0, m_sFilename.c_str(), 0);
+#else
+ m_pOutputFormat = guess_format(0, m_sFilename.c_str(), 0);
+#endif
+ m_pOutputFormat->video_codec = AV_CODEC_ID_MJPEG;
+
+#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(52, 24, 0)
+ m_pOutputFormatContext = avformat_alloc_context();
+#else
+ m_pOutputFormatContext = av_alloc_format_context();
+#endif
+ m_pOutputFormatContext->oformat = m_pOutputFormat;
+
+ strncpy(m_pOutputFormatContext->filename, m_sFilename.c_str(),
+ sizeof(m_pOutputFormatContext->filename));
+
+ if (m_pOutputFormat->video_codec != AV_CODEC_ID_NONE) {
+ setupVideoStream();
+ }
+#if LIBAVFORMAT_VERSION_MAJOR < 52
+ av_set_parameters(m_pOutputFormatContext, NULL);
+#endif
+
+ float muxMaxDelay = 0.7;
+ m_pOutputFormatContext->max_delay = int(muxMaxDelay * AV_TIME_BASE);
+
+// av_dump_format(m_pOutputFormatContext, 0, m_sFilename.c_str(), 1);
+
+ openVideoCodec();
+
+ m_pVideoBuffer = NULL;
+ if (!(m_pOutputFormatContext->oformat->flags & AVFMT_RAWPICTURE)) {
+ m_pVideoBuffer = (unsigned char*)(av_malloc(VIDEO_BUFFER_SIZE));
+ }
+
+ if (!(m_pOutputFormat->flags & AVFMT_NOFILE)) {
+#if LIBAVCODEC_VERSION_INT > AV_VERSION_INT(53, 8, 0)
+ int retVal = avio_open(&m_pOutputFormatContext->pb, m_sFilename.c_str(),
+ URL_WRONLY);
+#else
+ int retVal = url_fopen(&m_pOutputFormatContext->pb, m_sFilename.c_str(),
+ URL_WRONLY);
+#endif
+ if (retVal < 0) {
+ throw Exception(AVG_ERR_VIDEO_INIT_FAILED,
+ string("Could not open output file: '") + m_sFilename + "'");
+ }
+ }
+
+ m_pFrameConversionContext = sws_getContext(m_Size.x, m_Size.y,
+ ::PIX_FMT_RGB32, m_Size.x, m_Size.y, STREAM_PIXEL_FORMAT,
+ SWS_BILINEAR, NULL, NULL, NULL);
+
+ m_pConvertedFrame = createFrame(STREAM_PIXEL_FORMAT, m_Size);
+
+#if LIBAVFORMAT_VERSION_MAJOR > 52
+ avformat_write_header(m_pOutputFormatContext, 0);
+#else
+ av_write_header(m_pOutputFormatContext);
+#endif
+}
+
+void VideoWriterThread::setupVideoStream()
+{
+#if LIBAVCODEC_VERSION_INT > AV_VERSION_INT(53, 21, 0)
+ m_pVideoStream = avformat_new_stream(m_pOutputFormatContext, 0);
+#else
+ m_pVideoStream = av_new_stream(m_pOutputFormatContext, 0);
+#endif
+
+ AVCodecContext* pCodecContext = m_pVideoStream->codec;
+ pCodecContext->codec_id = static_cast<AVCodecID>(m_pOutputFormat->video_codec);
+ pCodecContext->codec_type = AVMEDIA_TYPE_VIDEO;
+
+ /* put sample parameters */
+ pCodecContext->bit_rate = 400000;
+ /* resolution must be a multiple of two */
+ pCodecContext->width = m_Size.x;
+ pCodecContext->height = m_Size.y;
+ /* time base: this is the fundamental unit of time (in seconds) in terms
+ of which frame timestamps are represented. for fixed-fps content,
+ timebase should be 1/framerate and timestamp increments should be
+ identically 1. */
+ pCodecContext->time_base.den = m_FrameRate;
+ pCodecContext->time_base.num = 1;
+// pCodecContext->gop_size = 12; /* emit one intra frame every twelve frames at most */
+ pCodecContext->pix_fmt = STREAM_PIXEL_FORMAT;
+ // Quality of quantization
+ pCodecContext->qmin = m_QMin;
+ pCodecContext->qmax = m_QMax;
+ // some formats want stream headers to be separate
+ if (m_pOutputFormatContext->oformat->flags & AVFMT_GLOBALHEADER) {
+ pCodecContext->flags |= CODEC_FLAG_GLOBAL_HEADER;
+ }
+ m_FramesWritten = 0;
+}
+
+void VideoWriterThread::openVideoCodec()
+{
+ AVCodec* videoCodec = avcodec_find_encoder(m_pVideoStream->codec->codec_id);
+ AVG_ASSERT(videoCodec);
+
+ int rc = avcodec_open2(m_pVideoStream->codec, videoCodec, 0);
+ AVG_ASSERT(rc == 0);
+}
+
+AVFrame* VideoWriterThread::createFrame(AVPixelFormat pixelFormat, IntPoint size)
+{
+ AVFrame* pPicture;
+
+ pPicture = avcodec_alloc_frame();
+
+ int memNeeded = avpicture_get_size(pixelFormat, size.x, size.y);
+ m_pPictureBuffer = static_cast<unsigned char*>(av_malloc(memNeeded));
+ avpicture_fill(reinterpret_cast<AVPicture*>(pPicture),
+ m_pPictureBuffer, pixelFormat, size.x, size.y);
+
+ return pPicture;
+}
+
+static ProfilingZoneID ProfilingZoneConvertImage(" Convert image", true);
+
+void VideoWriterThread::convertRGBImage(BitmapPtr pSrcBmp)
+{
+ ScopeTimer timer(ProfilingZoneConvertImage);
+ unsigned char* rgbData[3] = {pSrcBmp->getPixels(), NULL, NULL};
+ int rgbStride[3] = {pSrcBmp->getLineLen(), 0, 0};
+
+ sws_scale(m_pFrameConversionContext, rgbData, rgbStride,
+ 0, m_Size.y, m_pConvertedFrame->data, m_pConvertedFrame->linesize);
+}
+
+void VideoWriterThread::convertYUVImage(BitmapPtr pSrcBmp)
+{
+ ScopeTimer timer(ProfilingZoneConvertImage);
+ IntPoint size = pSrcBmp->getSize();
+ BitmapPtr pYBmp(new Bitmap(size, I8, m_pConvertedFrame->data[0],
+ m_pConvertedFrame->linesize[0], false));
+ BitmapPtr pUBmp(new Bitmap(size/2, I8, m_pConvertedFrame->data[1],
+ m_pConvertedFrame->linesize[1], false));
+ BitmapPtr pVBmp(new Bitmap(size/2, I8, m_pConvertedFrame->data[2],
+ m_pConvertedFrame->linesize[2], false));
+ for (int y=0; y<size.y/2; ++y) {
+ int srcStride = pSrcBmp->getStride();
+ const unsigned char * pSrc = pSrcBmp->getPixels() + y*srcStride*2;
+ int yStride = pYBmp->getStride();
+ unsigned char * pYDest = pYBmp->getPixels() + y*yStride*2;
+ unsigned char * pUDest = pUBmp->getPixels() + y*pUBmp->getStride();
+ unsigned char * pVDest = pVBmp->getPixels() + y*pVBmp->getStride();
+ for (int x=0; x<size.x/2; ++x) {
+ *pYDest = *pSrc;
+ *(pYDest+1) = *(pSrc+4);
+ *(pYDest+yStride) = *(pSrc+srcStride);
+ *(pYDest+yStride+1) = *(pSrc+srcStride+4);
+
+ *pUDest = ((int)*(pSrc+1) + *(pSrc+5) +
+ *(pSrc+srcStride+1) + *(pSrc+srcStride+5) + 2)/4;
+
+ *pVDest = ((int)*(pSrc+2) + *(pSrc+6) +
+ *(pSrc+srcStride+2) + *(pSrc+srcStride+6) + 2)/4;
+
+ pSrc += 8;
+ pYDest += 2;
+ pUDest += 1;
+ pVDest += 1;
+ }
+ }
+// pSrcBmp->save("src"+toString(m_FramesWritten)+".png");
+// pUBmp->save("foo"+toString(m_FramesWritten)+".png");
+}
+
+static ProfilingZoneID ProfilingZoneWriteFrame(" Write frame", true);
+
+void VideoWriterThread::writeFrame(AVFrame* pFrame)
+{
+ ScopeTimer timer(ProfilingZoneWriteFrame);
+ m_FramesWritten++;
+ AVCodecContext* pCodecContext = m_pVideoStream->codec;
+ AVPacket packet = { 0 };
+ int ret, out_size = 0;
+
+ #if LIBAVCODEC_VERSION_INT > AV_VERSION_INT(54, 0, 0)
+ int got_output = 0;
+ ret = avcodec_encode_video2(pCodecContext, &packet, pFrame, &got_output);
+ if(ret < 0) {
+ av_free_packet(&packet);
+ AVG_ASSERT(false);
+ }
+ out_size = packet.size;
+ #else
+ out_size = avcodec_encode_video(pCodecContext, m_pVideoBuffer,
+ VIDEO_BUFFER_SIZE, pFrame);
+ if(out_size > 0) {
+ av_init_packet(&packet);
+
+ if ((pCodecContext->coded_frame->pts) != (long long)AV_NOPTS_VALUE) {
+ packet.pts = av_rescale_q(pCodecContext->coded_frame->pts,
+ pCodecContext->time_base, m_pVideoStream->time_base);
+ }
+
+ if (pCodecContext->coded_frame->key_frame) {
+ packet.flags |= AV_PKT_FLAG_KEY;
+ }
+ packet.stream_index = m_pVideoStream->index;
+ packet.data = m_pVideoBuffer;
+ packet.size = out_size;
+ }
+ #endif
+
+ ///* if zero size, it means the image was buffered */
+ if (out_size > 0) {
+ /* write the compressed frame in the media file */
+ ret = av_interleaved_write_frame(m_pOutputFormatContext, &packet);
+ av_free_packet(&packet);
+ AVG_ASSERT(ret == 0);
+ }
+
+}
+
+}
+
diff --git a/src/player/VideoWriterThread.h b/src/player/VideoWriterThread.h
new file mode 100644
index 0000000..4cefa1e
--- /dev/null
+++ b/src/player/VideoWriterThread.h
@@ -0,0 +1,83 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _VideoWriterThread_H_
+#define _VideoWriterThread_H_
+
+#include "../api.h"
+
+#include "../base/WorkerThread.h"
+#include "../graphics/Bitmap.h"
+#include "../video/WrapFFMpeg.h"
+
+#include <boost/shared_ptr.hpp>
+#include <boost/thread.hpp>
+
+
+#include <string>
+
+namespace avg {
+
+class AVG_API VideoWriterThread : public WorkerThread<VideoWriterThread> {
+ public:
+ VideoWriterThread(CQueue& cmdQueue, const std::string& sFilename, IntPoint size,
+ int frameRate, int qMin, int qMax);
+ virtual ~VideoWriterThread();
+
+ void encodeYUVFrame(BitmapPtr pBmp);
+ void encodeFrame(BitmapPtr pBmp);
+ void close();
+
+ private:
+ bool init();
+ void open();
+
+ // Called by base class
+ virtual bool work();
+ virtual void deinit();
+
+ void setupVideoStream();
+ void openVideoCodec();
+
+ AVFrame* createFrame(AVPixelFormat pixelFormat, IntPoint size);
+
+ void convertRGBImage(BitmapPtr pSrcBmp);
+ void convertYUVImage(BitmapPtr pSrcBmp);
+ void writeFrame(AVFrame* pFrame);
+
+ std::string m_sFilename;
+ IntPoint m_Size;
+ int m_FrameRate;
+ int m_QMin;
+ int m_QMax;
+
+ AVOutputFormat* m_pOutputFormat;
+ AVFormatContext* m_pOutputFormatContext;
+ AVStream* m_pVideoStream;
+ SwsContext* m_pFrameConversionContext;
+ AVFrame* m_pConvertedFrame;
+ unsigned char* m_pPictureBuffer;
+ unsigned char* m_pVideoBuffer;
+ int m_FramesWritten;
+};
+
+}
+#endif
diff --git a/src/player/Win7TouchInputDevice.cpp b/src/player/Win7TouchInputDevice.cpp
new file mode 100644
index 0000000..b7a5691
--- /dev/null
+++ b/src/player/Win7TouchInputDevice.cpp
@@ -0,0 +1,186 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "Win7TouchInputDevice.h"
+#include "TouchEvent.h"
+#include "Player.h"
+#include "AVGNode.h"
+#include "TouchStatus.h"
+#include "TouchEvent.h"
+#include "SDLDisplayEngine.h"
+
+#include "../base/Logger.h"
+#include "../base/ObjectCounter.h"
+#include "../base/Exception.h"
+
+using namespace std;
+
+namespace avg {
+
+Win7TouchInputDevice* Win7TouchInputDevice::s_pInstance(0);
+
+Win7TouchInputDevice::Win7TouchInputDevice()
+ : m_LastID(0)
+{
+ s_pInstance = this;
+}
+
+Win7TouchInputDevice::~Win7TouchInputDevice()
+{
+ SetWindowLong(m_Hwnd, GWL_WNDPROC, (LONG)m_OldWndProc);
+ s_pInstance = 0;
+}
+
+typedef bool (WINAPI* PRTWPROC)(HWND, ULONG);
+
+void Win7TouchInputDevice::start()
+{
+#ifdef SM_DIGITIZER
+ AVG_TRACE(Logger::category::CONFIG, Logger::severity::INFO,
+ "Using Windows 7 Touch driver.");
+ // We need to do runtime dynamic linking for the Win7 touch functions because they
+ // aren't present on pre-Win7 systems.
+ HMODULE hUser32 = GetModuleHandle(TEXT("user32.dll"));
+ PRTWPROC pRegisterTouchWindowProc = (PRTWPROC) GetProcAddress(hUser32,
+ "RegisterTouchWindow");
+ if (!pRegisterTouchWindowProc) {
+ throw Exception(AVG_ERR_UNSUPPORTED,
+ "This version of windows does not support Multitouch input.");
+ }
+ m_pGetTouchInputInfoProc = (GTIIPROC) GetProcAddress(hUser32, "GetTouchInputInfo");
+ m_pCloseTouchInputHandleProc = (CTIHPROC) GetProcAddress(hUser32,
+ "CloseTouchInputHandle");
+
+ int multitouchCaps = GetSystemMetrics(SM_DIGITIZER);
+ if (multitouchCaps & NID_MULTI_INPUT) {
+ MultitouchInputDevice::start();
+ SDL_SysWMinfo info;
+ SDL_VERSION(&info.version);
+ int err = SDL_GetWMInfo(&info);
+ AVG_ASSERT(err == 1);
+ m_Hwnd = info.window;
+ bool bOk = pRegisterTouchWindowProc(m_Hwnd, TWF_FINETOUCH | TWF_WANTPALM);
+ AVG_ASSERT(bOk);
+ m_OldWndProc = (WNDPROC)SetWindowLong(m_Hwnd, GWL_WNDPROC, (LONG)touchWndSubclassProc);
+ m_ClientAreaOffset = calcClientAreaOffset();
+ } else {
+ throw Exception(AVG_ERR_UNSUPPORTED, "No windows 7 multitouch device connected.");
+ }
+#else
+ throw Exception(AVG_ERR_UNSUPPORTED,
+ "Windows multitouch not supported by this version of libavg.");
+#endif
+}
+
+#define MOUSEEVENTF_FROMTOUCH 0xFF515700
+
+LRESULT APIENTRY Win7TouchInputDevice::touchWndSubclassProc(HWND hwnd, UINT uMsg,
+ WPARAM wParam, LPARAM lParam)
+{
+#ifdef SM_DIGITIZER
+ Win7TouchInputDevice * pThis = Win7TouchInputDevice::s_pInstance;
+ bool bIgnore = false;
+ switch(uMsg) {
+ case WM_TOUCH:
+ pThis->onTouch(hwnd, wParam, lParam);
+ break;
+ case WM_LBUTTONDOWN:
+ case WM_LBUTTONUP:
+ if (GetMessageExtraInfo() & MOUSEEVENTF_FROMTOUCH) {
+ // Click was generated by wisptis / Windows Touch
+ bIgnore = true;
+ }
+ break;
+ case WM_MOUSEMOVE:
+ // Workaround for Win7 bug: There is no way to figure out if a WM_MOUSEMOVE
+ // originates from a touch, so we ignore all mousemove events as long as
+ // something is touching the screen.
+ bIgnore = (pThis->getNumTouches() > 0);
+ break;
+ default:
+ break;
+ }
+ if (!bIgnore) {
+ return CallWindowProc(pThis->m_OldWndProc, hwnd, uMsg, wParam, lParam);
+ } else {
+ return 0;
+ }
+#else
+ return 0;
+#endif
+}
+
+void Win7TouchInputDevice::onTouch(HWND hWnd, WPARAM wParam, LPARAM lParam)
+{
+#ifdef SM_DIGITIZER
+ unsigned numInputs = LOWORD(wParam);
+ PTOUCHINPUT pInputs = new TOUCHINPUT[numInputs];
+ BOOL bOk = m_pGetTouchInputInfoProc((HTOUCHINPUT)lParam, numInputs, pInputs,
+ sizeof(TOUCHINPUT));
+ AVG_ASSERT(bOk);
+ RECT winRect;
+ bOk = GetWindowRect(m_Hwnd, &winRect);
+ AVG_ASSERT(bOk);
+ for (unsigned i = 0; i < numInputs; i++) {
+ TOUCHINPUT *pTouchInput = &(pInputs[i]);
+ IntPoint pos(int(pTouchInput->x/100+0.5), int(pTouchInput->y/100+0.5));
+ if (!(Player::get()->getDisplayEngine())->isFullscreen()) {
+ pos -= IntPoint(winRect.left, winRect.top)+m_ClientAreaOffset;
+ IntPoint winSize = IntPoint(Player::get()->getRootNode()->getSize());
+ // Restrict coords to be inside window.
+ pos.x = min(max(pos.x, 0), winSize.x-1);
+ pos.y = min(max(pos.y, 0), winSize.y-1);
+ }
+
+ if (pTouchInput->dwFlags & TOUCHEVENTF_DOWN) {
+// cerr << "down: " << pos << endl;
+ m_LastID++;
+ TouchEventPtr pEvent (new TouchEvent(m_LastID, Event::CURSOR_DOWN, pos,
+ Event::TOUCH));
+ addTouchStatus((long)pTouchInput->dwID, pEvent);
+ } else if (pTouchInput->dwFlags & TOUCHEVENTF_UP) {
+// cerr << "up: " << pos << endl;
+ TouchStatusPtr pTouchStatus = getTouchStatus(pTouchInput->dwID);
+ TouchEventPtr pOldEvent = pTouchStatus->getLastEvent();
+ TouchEventPtr pUpEvent(new TouchEvent(pOldEvent->getCursorID(),
+ Event::CURSOR_UP, pos, Event::TOUCH));
+ pTouchStatus->pushEvent(pUpEvent);
+ } else if (pTouchInput->dwFlags & TOUCHEVENTF_MOVE) {
+// cerr << "motion: " << pos << endl;
+ TouchEventPtr pEvent(new TouchEvent(0, Event::CURSOR_MOTION, pos,
+ Event::TOUCH));
+ TouchStatusPtr pTouchStatus = getTouchStatus((long)pTouchInput->dwID);
+ AVG_ASSERT(pTouchStatus);
+ pTouchStatus->pushEvent(pEvent);
+ }
+ }
+ delete [] pInputs;
+ m_pCloseTouchInputHandleProc((HTOUCHINPUT)lParam);
+#endif
+}
+
+IntPoint Win7TouchInputDevice::calcClientAreaOffset() const
+{
+ // TODO: This might work for now, but the x offset should probably be SM_CXBORDER.
+ return IntPoint(GetSystemMetrics(SM_CYBORDER)+2, GetSystemMetrics(SM_CYCAPTION)+3);
+}
+
+}
diff --git a/src/player/Win7TouchInputDevice.h b/src/player/Win7TouchInputDevice.h
new file mode 100644
index 0000000..d795e11
--- /dev/null
+++ b/src/player/Win7TouchInputDevice.h
@@ -0,0 +1,69 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _Win7TouchInputDevice_H_
+#define _Win7TouchInputDevice_H_
+
+#include "../api.h"
+#include "MultitouchInputDevice.h"
+
+#undef WIN32_LEAN_AND_MEAN
+#include <SDL/SDL_syswm.h>
+
+namespace avg {
+
+#ifdef SM_DIGITIZER
+typedef bool (WINAPI* GTIIPROC)(HTOUCHINPUT, UINT, PTOUCHINPUT, int);
+typedef bool (WINAPI* CTIHPROC)(HTOUCHINPUT);
+#endif
+
+class AVG_API Win7TouchInputDevice: public MultitouchInputDevice
+{
+public:
+ Win7TouchInputDevice();
+ virtual ~Win7TouchInputDevice();
+ virtual void start();
+
+private:
+ static LRESULT APIENTRY touchWndSubclassProc(HWND hwnd, UINT uMsg,
+ WPARAM wParam, LPARAM lParam);
+ void onTouch(HWND hWnd, WPARAM wParam, LPARAM lParam);
+ IntPoint calcClientAreaOffset() const;
+
+ static Win7TouchInputDevice* s_pInstance;
+
+ HWND m_Hwnd;
+ WNDPROC m_OldWndProc;
+ int m_LastID;
+ IntPoint m_ClientAreaOffset;
+
+#ifdef SM_DIGITIZER
+ GTIIPROC m_pGetTouchInputInfoProc;
+ CTIHPROC m_pCloseTouchInputHandleProc;
+#endif
+};
+
+typedef boost::shared_ptr<Win7TouchInputDevice> Win7TouchInputDevicePtr;
+
+}
+
+#endif
+
diff --git a/src/player/WordsNode.cpp b/src/player/WordsNode.cpp
new file mode 100644
index 0000000..ba67720
--- /dev/null
+++ b/src/player/WordsNode.cpp
@@ -0,0 +1,816 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "WordsNode.h"
+#include "OGLSurface.h"
+#include "TypeDefinition.h"
+#include "TextEngine.h"
+
+#include "../base/Logger.h"
+#include "../base/Exception.h"
+#include "../base/ScopeTimer.h"
+#include "../base/XMLHelper.h"
+#include "../base/StringHelper.h"
+#include "../base/MathHelper.h"
+#include "../base/ObjectCounter.h"
+
+#include "../graphics/Filterfill.h"
+#include "../graphics/GLContext.h"
+#include "../graphics/GLTexture.h"
+#include "../graphics/TextureMover.h"
+
+#include <pango/pangoft2.h>
+
+#include <iostream>
+#include <algorithm>
+
+using namespace std;
+
+namespace avg {
+
+void WordsNode::registerType()
+{
+ static const string sDTDElements =
+ "<!ELEMENT span (#PCDATA|span|b|big|i|s|sub|sup|small|tt|u)*>\n"
+ "<!ATTLIST span\n"
+ " font_desc CDATA #IMPLIED\n"
+ " font_family CDATA #IMPLIED\n"
+ " face CDATA #IMPLIED\n"
+ " size CDATA #IMPLIED\n"
+ " style CDATA #IMPLIED\n"
+ " weight CDATA #IMPLIED\n"
+ " variant CDATA #IMPLIED\n"
+ " stretch CDATA #IMPLIED\n"
+ " foreground CDATA #IMPLIED\n"
+ " background CDATA #IMPLIED\n"
+ " underline CDATA #IMPLIED\n"
+ " rise CDATA #IMPLIED\n"
+ " strikethrough CDATA #IMPLIED\n"
+ " fallback CDATA #IMPLIED\n"
+ " lang CDATA #IMPLIED\n"
+ " letter_spacing CDATA #IMPLIED\n"
+ " rawtextmode CDATA #IMPLIED >\n"
+
+ "<!ELEMENT b (#PCDATA|span|b|big|i|s|sub|sup|small|tt|u)*>\n"
+ "<!ELEMENT big (#PCDATA|span|b|big|i|s|sub|sup|small|tt|u)*>\n"
+ "<!ELEMENT i (#PCDATA|span|b|big|i|s|sub|sup|small|tt|u)*>\n"
+ "<!ELEMENT s (#PCDATA|span|b|big|i|s|sub|sup|small|tt|u)*>\n"
+ "<!ELEMENT sub (#PCDATA|span|b|big|i|s|sub|sup|small|tt|u)*>\n"
+ "<!ELEMENT sup (#PCDATA|span|b|big|i|s|sub|sup|small|tt|u)*>\n"
+ "<!ELEMENT small (#PCDATA|span|b|big|i|s|sub|sup|small|tt|u)*>\n"
+ "<!ELEMENT tt (#PCDATA|span|b|big|i|s|sub|sup|small|tt|u)*>\n"
+ "<!ELEMENT u (#PCDATA|span|b|big|i|s|sub|sup|small|tt|u)*>\n"
+ "<!ELEMENT br (#PCDATA)*>\n";
+
+ string sChildArray[] = {"#PCDATA", "span", "b", "big", "i", "s", "sup", "sub",
+ "small", "tt", "u", "br"};
+ vector<string> sChildren = vectorFromCArray(sizeof(sChildArray)/sizeof(*sChildArray),
+ sChildArray);
+ TypeDefinition def = TypeDefinition("words", "rasternode",
+ ExportedObject::buildObject<WordsNode>)
+ .addChildren(sChildren)
+ .addDTDElements(sDTDElements)
+ .addArg(Arg<string>("font", "sans"))
+ .addArg(Arg<string>("variant", ""))
+ .addArg(Arg<UTF8String>("text", ""))
+ .addArg(Arg<string>("color", "FFFFFF"))
+ .addArg(Arg<float>("aagamma", 1.0f))
+ .addArg(Arg<float>("fontsize", 15))
+ .addArg(Arg<int>("indent", 0, false))
+ .addArg(Arg<float>("linespacing", 0))
+ .addArg(Arg<string>("alignment", "left"))
+ .addArg(Arg<string>("wrapmode", "word"))
+ .addArg(Arg<bool>("justify", false))
+ .addArg(Arg<bool>("rawtextmode", false, false,
+ offsetof(WordsNode, m_bRawTextMode)))
+ .addArg(Arg<float>("letterspacing", 0))
+ .addArg(Arg<bool>("hint", true))
+ .addArg(Arg<FontStyle>("fontstyle", FontStyle()))
+ ;
+ TypeRegistry::get()->registerType(def);
+}
+
+WordsNode::WordsNode(const ArgList& args)
+ : m_LogicalSize(0,0),
+ m_pFontDescription(0),
+ m_pLayout(0),
+ m_bRenderNeeded(true)
+{
+ m_bParsedText = false;
+ args.setMembers(this);
+
+ m_FontStyle = args.getArgVal<FontStyle>("fontstyle");
+ m_FontStyle.setDefaultedArgs(args);
+#ifdef _WIN32
+ if (m_FontStyle.getFont() == "sans") {
+ m_FontStyle.setFont("Arial");
+ m_FontStyle.setFontVariant("Regular");
+ }
+#endif
+ updateFont();
+ setText(args.getArgVal<UTF8String>("text"));
+
+ ObjectCounter::get()->incRef(&typeid(*this));
+}
+
+WordsNode::~WordsNode()
+{
+ if (m_pFontDescription) {
+ pango_font_description_free(m_pFontDescription);
+ }
+ if (m_pLayout) {
+ g_object_unref(m_pLayout);
+ }
+ ObjectCounter::get()->decRef(&typeid(*this));
+}
+
+void WordsNode::setTextFromNodeValue(const string& sText)
+{
+ // Gives priority to Node Values only if they aren't empty
+ UTF8String sTemp = removeExcessSpaces(sText);
+ if (sTemp.length() != 0) {
+ setText(sText);
+ }
+}
+
+void WordsNode::connectDisplay()
+{
+ RasterNode::connectDisplay();
+ getSurface()->setAlphaGamma(m_FontStyle.getAAGamma());
+}
+
+void WordsNode::connect(CanvasPtr pCanvas)
+{
+ RasterNode::connect(pCanvas);
+ checkReload();
+}
+
+void WordsNode::disconnect(bool bKill)
+{
+ if (m_pFontDescription) {
+ pango_font_description_free(m_pFontDescription);
+ m_pFontDescription = 0;
+ updateFont();
+ }
+ RasterNode::disconnect(bKill);
+}
+
+string WordsNode::getAlignment() const
+{
+ return m_FontStyle.getAlignment();
+}
+
+void WordsNode::setAlignment(const string& sAlign)
+{
+ m_FontStyle.setAlignment(sAlign);
+ updateLayout();
+}
+
+bool WordsNode::getJustify() const
+{
+ return m_FontStyle.getJustify();
+}
+
+void WordsNode::setJustify(bool bJustify)
+{
+ m_FontStyle.setJustify(bJustify);
+ updateLayout();
+}
+
+float WordsNode::getLetterSpacing() const
+{
+ return m_FontStyle.getLetterSpacing();
+}
+
+void WordsNode::setLetterSpacing(float letterSpacing)
+{
+ m_FontStyle.setLetterSpacing(letterSpacing);
+ updateLayout();
+}
+
+bool WordsNode::getHint() const
+{
+ return m_FontStyle.getHint();
+}
+
+void WordsNode::setHint(bool bHint)
+{
+ m_FontStyle.setHint(bHint);
+ updateLayout();
+}
+
+float WordsNode::getWidth() const
+{
+ return AreaNode::getWidth();
+}
+
+void WordsNode::setWidth(float width)
+{
+ AreaNode::setWidth(width);
+ updateLayout();
+}
+
+float WordsNode::getHeight() const
+{
+ return AreaNode::getHeight();
+}
+
+void WordsNode::setHeight(float width)
+{
+ AreaNode::setHeight(width);
+ updateLayout();
+}
+
+glm::vec2 WordsNode::getSize() const
+{
+ return AreaNode::getSize();
+}
+
+void WordsNode::setSize(const glm::vec2& pt)
+{
+ AreaNode::setSize(pt);
+ updateLayout();
+}
+
+glm::vec2 WordsNode::toLocal(const glm::vec2& globalPos) const
+{
+ glm::vec2 localPos = globalPos - getRelViewport().tl - glm::vec2(m_AlignOffset, 0);
+ return getRotatedPivot(localPos, -getAngle(), getPivot());
+}
+
+glm::vec2 WordsNode::toGlobal(const glm::vec2& localPos) const
+{
+ glm::vec2 alignPos = localPos + glm::vec2(m_AlignOffset, 0);
+ glm::vec2 globalPos = getRotatedPivot(alignPos, getAngle(), getPivot());
+ return globalPos + getRelViewport().tl;
+}
+
+const FontStyle& WordsNode::getFontStyle() const
+{
+ return m_FontStyle;
+}
+
+void WordsNode::setFontStyle(const FontStyle& fontStyle)
+{
+ m_FontStyle = fontStyle;
+ updateFont();
+}
+
+const std::string& WordsNode::getFont() const
+{
+ return m_FontStyle.getFont();
+}
+
+void WordsNode::setFont(const std::string& sName)
+{
+ m_FontStyle.setFont(sName);
+ updateFont();
+}
+
+const std::string& WordsNode::getFontVariant() const
+{
+ return m_FontStyle.getFontVariant();
+}
+
+void WordsNode::addFontDir(const std::string& sDir)
+{
+ TextEngine::get(true).addFontDir(sDir);
+ TextEngine::get(false).addFontDir(sDir);
+}
+
+void WordsNode::setFontVariant(const std::string& sVariant)
+{
+ m_FontStyle.setFontVariant(sVariant);
+ updateFont();
+}
+
+const UTF8String& WordsNode::getText() const
+{
+ return m_sRawText;
+}
+
+void WordsNode::setText(const UTF8String& sText)
+{
+ if (sText.length() > 32767) {
+ throw(Exception(AVG_ERR_INVALID_ARGS,
+ string("WordsNode::setText: string too long (")
+ + toString(sText.length()) + ")"));
+ }
+ if (m_sRawText != sText) {
+ m_sRawText = sText;
+ m_sText = m_sRawText;
+ if (m_bRawTextMode) {
+ m_bParsedText = false;
+ updateLayout();
+ } else {
+ setParsedText(sText);
+ }
+ }
+}
+
+const std::string& WordsNode::getColor() const
+{
+ return m_FontStyle.getColor();
+}
+
+void WordsNode::setColor(const string& sColor)
+{
+ m_FontStyle.setColor(sColor);
+}
+
+float WordsNode::getAAGamma() const
+{
+ return m_FontStyle.getAAGamma();
+}
+
+void WordsNode::setAAGamma(float gamma)
+{
+ m_FontStyle.setAAGamma(gamma);
+ if (getState() == Node::NS_CANRENDER) {
+ getSurface()->setAlphaGamma(gamma);
+ }
+}
+
+float WordsNode::getFontSize() const
+{
+ return m_FontStyle.getFontSize();
+}
+
+void WordsNode::setFontSize(float size)
+{
+ m_FontStyle.setFontSize(size);
+ updateFont();
+}
+
+int WordsNode::getIndent() const
+{
+ return m_FontStyle.getIndent();
+}
+
+void WordsNode::setIndent(int indent)
+{
+ m_FontStyle.setIndent(indent);
+ updateLayout();
+}
+
+float WordsNode::getLineSpacing() const
+{
+ return m_FontStyle.getLineSpacing();
+}
+
+void WordsNode::setLineSpacing(float lineSpacing)
+{
+ m_FontStyle.setLineSpacing(lineSpacing);
+ updateLayout();
+}
+
+bool WordsNode::getRawTextMode() const
+{
+ return m_bRawTextMode;
+}
+
+void WordsNode::setRawTextMode(bool rawTextMode)
+{
+ if (rawTextMode != m_bRawTextMode) {
+ m_sText = m_sRawText;
+ if (rawTextMode) {
+ m_bParsedText = false;
+ } else {
+ setParsedText(m_sText);
+ }
+ m_bRawTextMode = rawTextMode;
+ updateLayout();
+ }
+}
+
+glm::vec2 WordsNode::getGlyphPos(int i)
+{
+ PangoRectangle rect = getGlyphRect(i);
+ return glm::vec2(float(rect.x)/PANGO_SCALE, float(rect.y)/PANGO_SCALE);
+}
+
+glm::vec2 WordsNode::getGlyphSize(int i)
+{
+ PangoRectangle rect = getGlyphRect(i);
+ return glm::vec2(float(rect.width)/PANGO_SCALE, float(rect.height)/PANGO_SCALE);
+}
+
+int WordsNode::getNumLines()
+{
+ if(m_sText.length() != 0) {
+ return pango_layout_get_line_count(m_pLayout);
+ }
+ return 0;
+}
+
+PyObject* WordsNode::getCharIndexFromPos(glm::vec2 p)
+{
+ int index;
+ int trailing;
+ gboolean bXyToIndex = pango_layout_xy_to_index(m_pLayout,
+ int(p.x*PANGO_SCALE), int(p.y*PANGO_SCALE), &index, &trailing);
+ if (bXyToIndex) {
+ const char* pText = pango_layout_get_text(m_pLayout);
+ return Py_BuildValue("l",(g_utf8_pointer_to_offset(pText,pText+index)));
+ } else {
+ return Py_BuildValue("");
+ }
+}
+
+std::string WordsNode::getTextAsDisplayed()
+{
+ return pango_layout_get_text(m_pLayout);
+}
+
+glm::vec2 WordsNode::getLineExtents(int line)
+{
+ if (line < 0 || line >= getNumLines()) {
+ throw Exception(AVG_ERR_OUT_OF_RANGE, "WordsNode.getLineExtents: line index "
+ +toString(line)+" is out of range.");
+ }
+ PangoRectangle logical_rect;
+ PangoRectangle ink_rect;
+ PangoLayoutLine *layoutLine = pango_layout_get_line_readonly(m_pLayout, line);
+ pango_layout_line_get_pixel_extents(layoutLine, &ink_rect, &logical_rect);
+ return glm::vec2(float(logical_rect.width), float(logical_rect.height));
+}
+
+void WordsNode::setWrapMode(const string& sWrapMode)
+{
+ m_FontStyle.setWrapMode(sWrapMode);
+ updateLayout();
+}
+
+string WordsNode::getWrapMode() const
+{
+ return m_FontStyle.getWrapMode();
+}
+
+void WordsNode::parseString(PangoAttrList** ppAttrList, char** ppText)
+{
+ UTF8String sTextWithoutBreaks = applyBR(m_sText);
+ bool bOk;
+ GError * pError = 0;
+ bOk = (pango_parse_markup(sTextWithoutBreaks.c_str(),
+ int(sTextWithoutBreaks.length()), 0,
+ ppAttrList, ppText, 0, &pError) != 0);
+ if (!bOk) {
+ string sError;
+ if (getID() != "") {
+ sError = string("Can't parse string in node with id '")+getID()+"' ("
+ +pError->message+")";
+ } else {
+ sError = string("Can't parse string '")+m_sRawText+"' ("+pError->message+")";
+ }
+ throw Exception(AVG_ERR_CANT_PARSE_STRING, sError);
+ }
+
+}
+
+void WordsNode::calcMaskCoords()
+{
+ // Calculate texture coordinates for the mask texture, normalized to
+ // the extents of the text.
+ glm::vec2 normMaskSize;
+ glm::vec2 normMaskPos;
+ glm::vec2 mediaSize = glm::vec2(getMediaSize());
+ glm::vec2 effMaskPos = getMaskPos()-glm::vec2(m_InkOffset);
+ glm::vec2 maskSize = getMaskSize();
+
+ if (maskSize == glm::vec2(0,0)) {
+ normMaskSize = glm::vec2(getSize().x/mediaSize.x, getSize().y/mediaSize.y);
+ normMaskPos = glm::vec2(effMaskPos.x/getSize().x, effMaskPos.y/getSize().y);
+ } else {
+ normMaskSize = glm::vec2(maskSize.x/mediaSize.x, maskSize.y/mediaSize.y);
+ normMaskPos = glm::vec2(effMaskPos.x/getMaskSize().x,
+ effMaskPos.y/getMaskSize().y);
+ }
+/*
+ cerr << "calcMaskCoords" << endl;
+ cerr << " mediaSize: " << getMediaSize() << endl;
+ cerr << " effMaskPos: " << effMaskPos << endl;
+ cerr << " m_AlignOffset: " << m_AlignOffset << endl;
+ cerr << " maskSize: " << maskSize << endl;
+ cerr << " normMaskSize: " << normMaskSize << endl;
+ cerr << " normMaskPos: " << normMaskPos << endl;
+*/
+ getSurface()->setMaskCoords(normMaskPos, normMaskSize);
+}
+
+static ProfilingZoneID UpdateFontProfilingZone("WordsNode: Update font");
+
+void WordsNode::updateFont()
+{
+ {
+ ScopeTimer timer(UpdateFontProfilingZone);
+
+ if (m_pFontDescription) {
+ pango_font_description_free(m_pFontDescription);
+ }
+ TextEngine& engine = TextEngine::get(m_FontStyle.getHint());
+ m_pFontDescription = engine.getFontDescription(m_FontStyle.getFont(),
+ m_FontStyle.getFontVariant());
+ pango_font_description_set_absolute_size(m_pFontDescription,
+ (int)(m_FontStyle.getFontSize() * PANGO_SCALE));
+ }
+ updateLayout();
+}
+
+static ProfilingZoneID UpdateLayoutProfilingZone("WordsNode: Update layout");
+
+void WordsNode::updateLayout()
+{
+ ScopeTimer timer(UpdateLayoutProfilingZone);
+
+ if (m_sText.length() == 0) {
+ m_LogicalSize = IntPoint(0,0);
+ m_bRenderNeeded = true;
+ } else {
+ TextEngine& engine = TextEngine::get(m_FontStyle.getHint());
+ PangoContext* pContext = engine.getPangoContext();
+ pango_context_set_font_description(pContext, m_pFontDescription);
+
+ if (m_pLayout) {
+ g_object_unref(m_pLayout);
+ }
+ m_pLayout = pango_layout_new(pContext);
+
+ PangoAttrList * pAttrList = 0;
+#if PANGO_VERSION > PANGO_VERSION_ENCODE(1,18,2)
+ PangoAttribute * pLetterSpacing = pango_attr_letter_spacing_new
+ (int(m_FontStyle.getLetterSpacing()*1024));
+#endif
+ if (m_bParsedText) {
+ char * pText = 0;
+ parseString(&pAttrList, &pText);
+#if PANGO_VERSION > PANGO_VERSION_ENCODE(1,18,2)
+ // Workaround for pango bug.
+ pango_attr_list_insert_before(pAttrList, pLetterSpacing);
+#endif
+ pango_layout_set_text(m_pLayout, pText, -1);
+ g_free(pText);
+ } else {
+ pAttrList = pango_attr_list_new();
+#if PANGO_VERSION > PANGO_VERSION_ENCODE(1,18,2)
+ pango_attr_list_insert_before(pAttrList, pLetterSpacing);
+#endif
+ pango_layout_set_text(m_pLayout, m_sText.c_str(), -1);
+ }
+ pango_layout_set_attributes(m_pLayout, pAttrList);
+ pango_attr_list_unref(pAttrList);
+
+ pango_layout_set_wrap(m_pLayout, m_FontStyle.getWrapModeVal());
+ pango_layout_set_alignment(m_pLayout, m_FontStyle.getAlignmentVal());
+ pango_layout_set_justify(m_pLayout, m_FontStyle.getJustify());
+ if (getUserSize().x != 0) {
+ pango_layout_set_width(m_pLayout, int(getUserSize().x * PANGO_SCALE));
+ }
+ int indent = m_FontStyle.getIndent() * PANGO_SCALE;
+ pango_layout_set_indent(m_pLayout, indent);
+ if (indent < 0) {
+ // For hanging indentation, we add a tabstop to support lists
+ PangoTabArray* pTabs = pango_tab_array_new_with_positions(1, false,
+ PANGO_TAB_LEFT, -indent);
+ pango_layout_set_tabs(m_pLayout, pTabs);
+ pango_tab_array_free(pTabs);
+ }
+ pango_layout_set_spacing(m_pLayout,
+ (int)(m_FontStyle.getLineSpacing()*PANGO_SCALE));
+ PangoRectangle logical_rect;
+ PangoRectangle ink_rect;
+ pango_layout_get_pixel_extents(m_pLayout, &ink_rect, &logical_rect);
+
+ /*
+ cerr << getID() << endl;
+ cerr << "Ink: " << ink_rect.x << ", " << ink_rect.y << ", "
+ << ink_rect.width << ", " << ink_rect.height << endl;
+ cerr << "Logical: " << logical_rect.x << ", " << logical_rect.y << ", "
+ << logical_rect.width << ", " << logical_rect.height << endl;
+ cerr << "User Size: " << getUserSize() << endl;
+ */
+ m_InkSize.y = ink_rect.height;
+ if (getUserSize().x == 0) {
+ m_InkSize.x = ink_rect.width;
+ } else {
+ m_InkSize.x = int(getUserSize().x);
+ }
+ if (m_InkSize.x == 0) {
+ m_InkSize.x = 1;
+ }
+ if (m_InkSize.y == 0) {
+ m_InkSize.y = 1;
+ }
+ m_LogicalSize.y = logical_rect.height;
+ m_LogicalSize.x = logical_rect.width;
+ m_InkOffset = IntPoint(ink_rect.x-logical_rect.x, ink_rect.y-logical_rect.y);
+ m_bRenderNeeded = true;
+ setViewport(-32767, -32767, -32767, -32767);
+ }
+}
+
+static ProfilingZoneID RenderTextProfilingZone("WordsNode: render text");
+
+void WordsNode::renderText()
+{
+ if (!(getState() == NS_CANRENDER)) {
+ return;
+ }
+ if (m_bRenderNeeded) {
+ if (m_sText.length() != 0) {
+ ScopeTimer timer(RenderTextProfilingZone);
+ TextEngine& engine = TextEngine::get(m_FontStyle.getHint());
+ PangoContext* pContext = engine.getPangoContext();
+ pango_context_set_font_description(pContext, m_pFontDescription);
+ int maxTexSize = GLContext::getMain()->getMaxTexSize();
+ if (m_InkSize.x > maxTexSize || m_InkSize.y > maxTexSize) {
+ throw Exception(AVG_ERR_UNSUPPORTED,
+ "WordsNode size exceeded maximum (Size="
+ + toString(m_InkSize) + ", max=" + toString(maxTexSize) + ")");
+ }
+ GLTexturePtr pTex(new GLTexture(m_InkSize, A8));
+ getSurface()->create(A8, pTex);
+ TextureMoverPtr pMover = TextureMover::create(m_InkSize, A8, GL_DYNAMIC_DRAW);
+
+ BitmapPtr pBmp = pMover->lock();
+ FilterFill<unsigned char>(0).applyInPlace(pBmp);
+ FT_Bitmap bitmap;
+ bitmap.rows = m_InkSize.y;
+ bitmap.width = m_InkSize.x;
+ unsigned char * pLines = pBmp->getPixels();
+ bitmap.pitch = pBmp->getStride();
+ bitmap.buffer = pLines;
+ bitmap.num_grays = 256;
+ bitmap.pixel_mode = ft_pixel_mode_grays;
+
+ PangoRectangle logical_rect;
+ PangoRectangle ink_rect;
+ pango_layout_get_pixel_extents(m_pLayout, &ink_rect, &logical_rect);
+ pango_ft2_render_layout(&bitmap, m_pLayout, -ink_rect.x, -ink_rect.y);
+ switch (m_FontStyle.getAlignmentVal()) {
+ case PANGO_ALIGN_LEFT:
+ m_AlignOffset = 0;
+ break;
+ case PANGO_ALIGN_CENTER:
+ m_AlignOffset = -logical_rect.width/2;
+ break;
+ case PANGO_ALIGN_RIGHT:
+ m_AlignOffset = -logical_rect.width;
+ break;
+ default:
+ AVG_ASSERT(false);
+ }
+
+ pMover->unlock();
+ pMover->moveToTexture(*pTex);
+ newSurface();
+ }
+ m_bRenderNeeded = false;
+ }
+}
+
+void WordsNode::redraw()
+{
+ AVG_ASSERT(m_sText.length() < 32767);
+
+ renderText();
+}
+
+void WordsNode::preRender(const VertexArrayPtr& pVA, bool bIsParentActive,
+ float parentEffectiveOpacity)
+{
+ Node::preRender(pVA, bIsParentActive, parentEffectiveOpacity);
+ if (isVisible()) {
+ redraw();
+ }
+ Pixel32 color = m_FontStyle.getColorVal();
+ if (m_sText.length() != 0 && isVisible()) {
+ renderFX(getSize(), color, false);
+ }
+ calcVertexArray(pVA, color);
+}
+
+static ProfilingZoneID RenderProfilingZone("WordsNode::render");
+
+void WordsNode::render()
+{
+ ScopeTimer timer(RenderProfilingZone);
+ if (m_sText.length() != 0 && isVisible()) {
+ IntPoint offset = m_InkOffset + IntPoint(m_AlignOffset, 0);
+ glm::mat4 transform;
+ if (offset == IntPoint(0,0)) {
+ transform = getTransform();
+ } else {
+ transform = glm::translate(getTransform(), glm::vec3(offset.x, offset.y, 0));
+ }
+ blta8(transform, glm::vec2(getSurface()->getSize()), getEffectiveOpacity(),
+ m_FontStyle.getColorVal(), getBlendMode());
+ }
+}
+
+IntPoint WordsNode::getMediaSize()
+{
+ return m_LogicalSize;
+}
+
+const vector<string>& WordsNode::getFontFamilies()
+{
+ return TextEngine::get(true).getFontFamilies();
+}
+
+const vector<string>& WordsNode::getFontVariants(const string& sFontName)
+{
+ return TextEngine::get(true).getFontVariants(sFontName);
+}
+
+string WordsNode::removeExcessSpaces(const string & sText)
+{
+ string s = sText;
+ string::size_type lastPos = s.npos;
+ string::size_type pos = s.find_first_of(" \n\r");
+ while (pos != s.npos) {
+ s[pos] = ' ';
+ if (pos == lastPos+1) {
+ s.erase(pos, 1);
+ pos--;
+ }
+ lastPos = pos;
+ pos = s.find_first_of(" \n\r", pos+1);
+ }
+ return s;
+}
+
+PangoRectangle WordsNode::getGlyphRect(int i)
+{
+
+ if (i >= int(g_utf8_strlen(m_sText.c_str(), -1)) || i < 0) {
+ throw(Exception(AVG_ERR_INVALID_ARGS,
+ string("getGlyphRect: Index ") + toString(i) + " out of range."));
+ }
+ const char* pText = pango_layout_get_text(m_pLayout);
+ char * pChar = g_utf8_offset_to_pointer(pText, i);
+ int byteOffset = pChar-pText;
+ PangoRectangle rect;
+
+ if (m_pLayout) {
+ pango_layout_index_to_pos(m_pLayout, byteOffset, &rect);
+ } else {
+ rect.x = 0;
+ rect.y = 0;
+ rect.width = 0;
+ rect.height = 0;
+ }
+ return rect;
+}
+
+void WordsNode::setParsedText(const UTF8String& sText)
+{
+ m_sText = removeExcessSpaces(sText);
+
+ // This just does a syntax check and throws an exception if appropriate.
+ // The results are discarded.
+ PangoAttrList * pAttrList = 0;
+ char * pText = 0;
+ parseString(&pAttrList, &pText);
+ pango_attr_list_unref(pAttrList);
+ g_free(pText);
+ m_bParsedText = true;
+ updateLayout();
+}
+
+UTF8String WordsNode::applyBR(const UTF8String& sText)
+{
+ UTF8String sResult(sText);
+ UTF8String sLowerText = toLowerCase(sResult);
+ string::size_type pos=sLowerText.find("<br/>");
+ while (pos != string::npos) {
+ sResult.replace(pos, 5, "\n");
+ sLowerText.replace(pos, 5, "\n");
+ if (sLowerText[pos+1] == ' ') {
+ sLowerText.erase(pos+1, 1);
+ sResult.erase(pos+1, 1);
+ }
+ pos=sLowerText.find("<br/>");
+ }
+ return sResult;
+}
+
+}
+
diff --git a/src/player/WordsNode.h b/src/player/WordsNode.h
new file mode 100644
index 0000000..c189e9f
--- /dev/null
+++ b/src/player/WordsNode.h
@@ -0,0 +1,158 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _WordsNode_H_
+#define _WordsNode_H_
+
+#include "../api.h"
+#include "RasterNode.h"
+#include "FontStyle.h"
+#include "../graphics/Pixel32.h"
+#include "../base/UTF8String.h"
+
+#include <pango/pango.h>
+
+#include <string>
+#include <vector>
+
+namespace avg {
+
+class AVG_API WordsNode : public RasterNode
+{
+ public:
+ static void registerType();
+
+ WordsNode(const ArgList& args);
+ virtual ~WordsNode();
+
+ virtual void connectDisplay();
+ virtual void connect(CanvasPtr pCanvas);
+ virtual void disconnect(bool bKill);
+ virtual void preRender(const VertexArrayPtr& pVA, bool bIsParentActive,
+ float parentEffectiveOpacity);
+ virtual void render();
+
+ virtual float getWidth() const;
+ virtual void setWidth(float width);
+
+ virtual float getHeight() const;
+ virtual void setHeight(float width);
+
+ virtual glm::vec2 getSize() const;
+ virtual void setSize(const glm::vec2& pt);
+
+ glm::vec2 toLocal(const glm::vec2& globalPos) const;
+ glm::vec2 toGlobal(const glm::vec2& localPos) const;
+
+ void setTextFromNodeValue(const std::string& sText);
+
+ const FontStyle& getFontStyle() const;
+ void setFontStyle(const FontStyle& fontStyle);
+
+ const std::string& getFont() const;
+ void setFont(const std::string& sName);
+
+ const std::string& getFontVariant() const;
+ void setFontVariant(const std::string& sVariant);
+
+ const UTF8String& getText() const;
+ void setText(const UTF8String& sText);
+
+ const std::string& getColor() const;
+ void setColor(const std::string& sColor);
+
+ virtual float getAAGamma() const;
+ virtual void setAAGamma(float gamma);
+
+ float getFontSize() const;
+ void setFontSize(float size);
+
+ int getIndent() const;
+ void setIndent(int indent);
+
+ float getLineSpacing() const;
+ void setLineSpacing(float lineSpacing);
+
+ bool getRawTextMode() const;
+ void setRawTextMode(bool rawTextMode);
+
+ std::string getAlignment() const;
+ void setAlignment(const std::string& sAlignment);
+
+ std::string getWrapMode() const;
+ void setWrapMode(const std::string& sWrapMode);
+
+ bool getJustify() const;
+ void setJustify(bool bJustify);
+
+ float getLetterSpacing() const;
+ void setLetterSpacing(float letterSpacing);
+
+ bool getHint() const;
+ void setHint(bool bHint);
+
+ glm::vec2 getGlyphPos(int i);
+ glm::vec2 getGlyphSize(int i);
+ virtual IntPoint getMediaSize();
+
+ int getNumLines();
+ PyObject* getCharIndexFromPos(glm::vec2 p);
+ std::string getTextAsDisplayed();
+ glm::vec2 getLineExtents(int line);
+
+ static const std::vector<std::string>& getFontFamilies();
+ static const std::vector<std::string>& getFontVariants(
+ const std::string& sFontName);
+ static void addFontDir(const std::string& sDir);
+
+ private:
+ virtual void calcMaskCoords();
+ void updateFont();
+ void updateLayout();
+ void renderText();
+ void redraw();
+ void parseString(PangoAttrList** ppAttrList, char** ppText);
+ void setParsedText(const UTF8String& sText);
+ UTF8String applyBR(const UTF8String& sText);
+ std::string removeExcessSpaces(const std::string & sText);
+ PangoRectangle getGlyphRect(int i);
+
+ // Exposed Attributes
+ FontStyle m_FontStyle;
+ UTF8String m_sText;
+ UTF8String m_sRawText;
+
+ bool m_bParsedText;
+ bool m_bRawTextMode;
+ IntPoint m_LogicalSize;
+ IntPoint m_InkOffset;
+ IntPoint m_InkSize;
+ int m_AlignOffset;
+ PangoFontDescription * m_pFontDescription;
+ PangoLayout * m_pLayout;
+
+ bool m_bRenderNeeded;
+};
+
+}
+
+#endif
+
diff --git a/src/player/WrapPython.cpp b/src/player/WrapPython.cpp
new file mode 100644
index 0000000..e0eb9bc
--- /dev/null
+++ b/src/player/WrapPython.cpp
@@ -0,0 +1,72 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "WrapPython.h"
+
+#include "../base/Logger.h"
+#include "../base/StringHelper.h"
+#include "../base/FileHelper.h"
+
+#include <frameobject.h>
+
+using namespace std;
+
+namespace avg {
+
+aquirePyGIL::aquirePyGIL()
+{
+ m_pyGilState = PyGILState_Ensure();
+}
+aquirePyGIL::~aquirePyGIL()
+{
+ PyGILState_Release(m_pyGilState);
+}
+
+void avgDeprecationWarning(const string& sVersion, const string& sOldEntryPoint,
+ const string& sNewEntryPoint)
+{
+ static vector<string> sWarningsIssued;
+ bool bWarned = false;
+ for (vector<string>::iterator it = sWarningsIssued.begin();
+ it != sWarningsIssued.end(); ++it)
+ {
+ if (*it == sOldEntryPoint) {
+ return;
+ }
+ }
+ if (!bWarned) {
+ sWarningsIssued.push_back(sOldEntryPoint);
+
+ PyFrameObject* pFrame = PyEval_GetFrame();
+ int lineNo = PyCode_Addr2Line(pFrame->f_code, pFrame->f_lasti);
+ // lineNo = PyFrame_GetLineNumber(pFrame);
+ string sFName = getFilenamePart(PyString_AS_STRING(pFrame->f_code->co_filename));
+ string sMsg = sFName + ":" + toString(lineNo) + ": ";
+ sMsg += string(sOldEntryPoint) + " deprecated since version " +
+ string(sVersion)+".";
+ if (sNewEntryPoint != string("")) {
+ sMsg += " Use "+string(sNewEntryPoint) + " instead.";
+ }
+ AVG_TRACE(Logger::category::DEPRECATION, Logger::severity::WARNING, sMsg);
+ }
+}
+
+}
diff --git a/src/player/WrapPython.h b/src/player/WrapPython.h
new file mode 100644
index 0000000..20ce764
--- /dev/null
+++ b/src/player/WrapPython.h
@@ -0,0 +1,70 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _WrapPython_H_
+#define _WrapPython_H_
+
+#include "../api.h"
+
+#ifdef _DEBUG
+# undef _DEBUG // Don't let Python force the debug library just because we're debugging.
+# define DEBUG_UNDEFINED_FROM_WRAPPYTHON_H
+#endif
+
+// libstdc++ and python headers both define _XOPEN_SOURCE (Ubuntu 9.10, gcc 4.4,
+// python 2.6.4)
+#undef _POSIX_C_SOURCE
+#undef _XOPEN_SOURCE
+#include <Python.h>
+#include <string>
+
+#undef HAVE_STAT
+#undef HAVE_TEMPNAM
+#undef PACKAGE
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#ifdef DEBUG_UNDEFINED_FROM_WRAPPYTHON_H
+# undef DEBUG_UNDEFINED_FROM_WRAPPYTHON_H
+# define _DEBUG
+#endif
+
+namespace avg {
+
+class aquirePyGIL
+{
+public:
+ aquirePyGIL();
+ virtual ~aquirePyGIL();
+
+private:
+ PyGILState_STATE m_pyGilState;
+};
+
+void avgDeprecationWarning(const std::string& sVersion, const std::string& sOldEntryPoint,
+ const std::string& sNewEntryPoint);
+
+}
+
+#endif
diff --git a/src/player/XInputMTInputDevice.cpp b/src/player/XInputMTInputDevice.cpp
new file mode 100644
index 0000000..3a260d3
--- /dev/null
+++ b/src/player/XInputMTInputDevice.cpp
@@ -0,0 +1,379 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "XInputMTInputDevice.h"
+
+#include "TouchEvent.h"
+#include "Player.h"
+#include "AVGNode.h"
+#include "TouchStatus.h"
+#include "SDLDisplayEngine.h"
+
+#include "../base/Logger.h"
+#include "../base/ObjectCounter.h"
+#include "../base/Exception.h"
+#include "../base/OSHelper.h"
+#include "../base/StringHelper.h"
+
+#include <SDL/SDL_syswm.h>
+#include <SDL/SDL.h>
+
+#include <X11/extensions/XInput.h>
+#include <X11/extensions/XInput2.h>
+
+using namespace std;
+
+namespace avg {
+
+::Display* XInputMTInputDevice::s_pDisplay = 0;
+
+const char* cookieTypeToName(int evtype);
+string xEventTypeToName(int evtype);
+
+XInputMTInputDevice::XInputMTInputDevice()
+ : m_LastID(0),
+ m_DeviceID(-1)
+{
+}
+
+XInputMTInputDevice::~XInputMTInputDevice()
+{
+ if (m_DeviceID != -1 && m_OldMasterDeviceID != -1) {
+ XIAttachSlaveInfo atInfo;
+ atInfo.type = XIAttachSlave;
+ atInfo.deviceid = m_DeviceID;
+ atInfo.new_master = m_OldMasterDeviceID;
+ XIChangeHierarchy(s_pDisplay, (XIAnyHierarchyChangeInfo *)&atInfo, 1);
+ }
+}
+
+void XInputMTInputDevice::start()
+{
+
+ Status status;
+ SDLDisplayEngine * pEngine = Player::get()->getDisplayEngine();
+ glm::vec2 size(pEngine->getSize());
+ glm::vec2 windowSize(pEngine->getWindowSize());
+ m_DisplayScale.x = size.x/windowSize.x;
+ m_DisplayScale.y = size.y/windowSize.y;
+
+ SDL_SysWMinfo info;
+ SDL_VERSION(&info.version);
+ int rc = SDL_GetWMInfo(&info);
+ AVG_ASSERT(rc != -1);
+ s_pDisplay = info.info.x11.display;
+ m_SDLLockFunc = info.info.x11.lock_func;
+ m_SDLUnlockFunc = info.info.x11.unlock_func;
+
+ m_SDLLockFunc();
+ // XInput Extension available?
+ int event, error;
+ bool bOk = XQueryExtension(s_pDisplay, "XInputExtension", &m_XIOpcode,
+ &event, &error);
+ if (!bOk) {
+ throw Exception(AVG_ERR_MT_INIT,
+ "XInput multitouch event source: X Input extension not available.");
+ }
+
+ // Which version of XI2?
+ int major=2;
+ int minor=1;
+ status = XIQueryVersion(s_pDisplay, &major, &minor);
+ if (status == BadRequest) {
+ throw Exception(AVG_ERR_MT_INIT,
+ "XInput 2.1 multitouch event source: Server does not support XI2");
+ }
+ if (major < 2 || minor < 1) {
+ throw Exception(AVG_ERR_MT_INIT,
+ "XInput multitouch event source: Supported version is "
+ +toString(major)+"."+toString(minor)+". At least 2.1 is needed.");
+ }
+ findMTDevice();
+
+ // SDL grabs the pointer in full screen mode. This breaks touchscreen usage.
+ // Can't use SDL_WM_GrabInput(SDL_GRAB_OFF) because it doesn't work in full
+ // screen mode. Get the display connection and do it manually.
+ XUngrabPointer(info.info.x11.display, CurrentTime);
+
+ XIEventMask mask;
+ mask.deviceid = m_DeviceID;
+ mask.mask_len = XIMaskLen(XI_LASTEVENT);
+ mask.mask = (unsigned char *)calloc(mask.mask_len, sizeof(char));
+ memset(mask.mask, 0, mask.mask_len);
+ XISetMask(mask.mask, XI_TouchBegin);
+ XISetMask(mask.mask, XI_TouchUpdate);
+ XISetMask(mask.mask, XI_TouchEnd);
+
+ status = XISelectEvents(s_pDisplay, info.info.x11.window, &mask, 1);
+ AVG_ASSERT(status == Success);
+
+ m_SDLUnlockFunc();
+
+ SDL_SetEventFilter(XInputMTInputDevice::filterEvent);
+
+
+ XIDetachSlaveInfo detInfo;
+ detInfo.type = XIDetachSlave;
+ detInfo.deviceid = m_DeviceID;
+ XIChangeHierarchy(s_pDisplay, (XIAnyHierarchyChangeInfo *)&detInfo, 1);
+
+ pEngine->setXIMTInputDevice(this);
+ MultitouchInputDevice::start();
+ AVG_TRACE(Logger::category::CONFIG, Logger::severity::INFO,
+ "XInput Multitouch event source created.");
+}
+
+void XInputMTInputDevice::handleXIEvent(const XEvent& xEvent)
+{
+ m_SDLLockFunc();
+ XGenericEventCookie* pCookie = (XGenericEventCookie*)&xEvent.xcookie;
+ if (pCookie->type == GenericEvent && pCookie->extension == m_XIOpcode) {
+ XIDeviceEvent* pDevEvent = (XIDeviceEvent*)(pCookie->data);
+ IntPoint pos(pDevEvent->event_x, pDevEvent->event_y);
+ int xid = pDevEvent->detail;
+ switch (pCookie->evtype) {
+ case XI_TouchBegin:
+ {
+// cerr << "TouchBegin " << xid << ", " << pos << endl;
+ m_LastID++;
+ TouchEventPtr pEvent = createEvent(m_LastID, Event::CURSOR_DOWN, pos);
+ addTouchStatus(xid, pEvent);
+ }
+ break;
+ case XI_TouchUpdate:
+ {
+// cerr << "TouchUpdate " << xid << ", " << pos << endl;
+ TouchEventPtr pEvent = createEvent(0, Event::CURSOR_MOTION, pos);
+ TouchStatusPtr pTouchStatus = getTouchStatus(xid);
+ AVG_ASSERT(pTouchStatus);
+ pTouchStatus->pushEvent(pEvent);
+ }
+ break;
+ case XI_TouchEnd:
+ {
+// cerr << "TouchEnd " << xid << ", " << pos << endl;
+ TouchStatusPtr pTouchStatus = getTouchStatus(xid);
+ AVG_ASSERT(pTouchStatus);
+ TouchEventPtr pEvent = createEvent(0, Event::CURSOR_UP, pos);
+ pTouchStatus->pushEvent(pEvent);
+ }
+ break;
+ default:
+ ;
+// cerr << "Unhandled XInput event, type: "
+// << cookieTypeToName(pCookie->evtype) << endl;
+ }
+ } else {
+// cerr << "Unhandled X11 Event: " << xEvent.type << endl;
+ }
+
+ XFreeEventData(s_pDisplay, pCookie);
+ m_SDLUnlockFunc();
+}
+
+std::vector<EventPtr> XInputMTInputDevice::pollEvents()
+{
+
+ return MultitouchInputDevice::pollEvents();
+}
+
+void XInputMTInputDevice::findMTDevice()
+{
+ int ndevices;
+ XIDeviceInfo* pDevices;
+ XIDeviceInfo* pDevice;
+
+ pDevices = XIQueryDevice(s_pDisplay, XIAllDevices, &ndevices);
+
+ XITouchClassInfo* pTouchClass = 0;
+ for (int i = 0; i < ndevices && !pTouchClass; ++i) {
+ pDevice = &pDevices[i];
+// cerr << "Device " << pDevice->name << "(id: " << pDevice->deviceid << ")."
+// << endl;
+ if (pDevice->use == XISlavePointer || pDevice->use == XIFloatingSlave) {
+ for (int j = 0; j < pDevice->num_classes; ++j) {
+ XIAnyClassInfo * pClass = pDevice->classes[j];
+ if (pClass->type == XITouchClass) {
+ XITouchClassInfo* pTempTouchClass = (XITouchClassInfo *)pClass;
+ if (pTempTouchClass->mode == XIDirectTouch) {
+ pTouchClass = pTempTouchClass;
+ m_sDeviceName = pDevice->name;
+ m_DeviceID = pDevice->deviceid;
+ if (pDevice->use == XISlavePointer) {
+ m_OldMasterDeviceID = pDevice->attachment;
+ } else {
+ m_OldMasterDeviceID = -1;
+ }
+ break;
+ }
+ }
+ }
+ }
+ }
+ if (pTouchClass) {
+ AVG_TRACE(Logger::category::CONFIG,Logger::severity::INFO,
+ "Using multitouch input device " << m_sDeviceName << ", max touches: " <<
+ pTouchClass->num_touches);
+ } else {
+ throw Exception(AVG_ERR_MT_INIT,
+ "XInput multitouch event source: No multitouch device found.");
+ }
+ XIFreeDeviceInfo(pDevices);
+}
+
+TouchEventPtr XInputMTInputDevice::createEvent(int id, Event::Type type, IntPoint pos)
+{
+ pos.x *= m_DisplayScale.x;
+ pos.y *= m_DisplayScale.y;
+ return TouchEventPtr(new TouchEvent(id, type, pos, Event::TOUCH));
+}
+
+int XInputMTInputDevice::filterEvent(const SDL_Event * pEvent)
+{
+ // This is a hook into libsdl event processing. Since libsdl doesn't know about
+ // XInput 2, it doesn't call XGetEventData either. By the time the event arrives
+ // in handleXIEvent(), other events may have arrived and XGetEventData can't be
+ // called anymore. Hence this function, which calls XGetEventData for each event
+ // that has a cookie.
+ if (pEvent->type == SDL_SYSWMEVENT) {
+ SDL_SysWMmsg* pMsg = pEvent->syswm.msg;
+ AVG_ASSERT(pMsg->subsystem == SDL_SYSWM_X11);
+ XEvent* pXEvent = &pMsg->event.xevent;
+ XGenericEventCookie* pCookie = (XGenericEventCookie*)&(pXEvent->xcookie);
+// cerr << "---- filter xinput event: " << xEventTypeToName(pXEvent->type) << ", "
+// << cookieTypeToName(pCookie->evtype) << endl;
+ XGetEventData(s_pDisplay, pCookie);
+ } else {
+// cerr << "---- filter: " << int(pEvent->type) << endl;
+ }
+ return 1;
+}
+
+// From xinput/test_xi2.c
+const char* cookieTypeToName(int evtype)
+{
+ const char *name;
+ switch(evtype) {
+ case XI_DeviceChanged: name = "DeviceChanged"; break;
+ case XI_KeyPress: name = "KeyPress"; break;
+ case XI_KeyRelease: name = "KeyRelease"; break;
+ case XI_ButtonPress: name = "ButtonPress"; break;
+ case XI_ButtonRelease: name = "ButtonRelease"; break;
+ case XI_Motion: name = "Motion"; break;
+ case XI_Enter: name = "Enter"; break;
+ case XI_Leave: name = "Leave"; break;
+ case XI_FocusIn: name = "FocusIn"; break;
+ case XI_FocusOut: name = "FocusOut"; break;
+ case XI_HierarchyChanged: name = "HierarchyChanged"; break;
+ case XI_PropertyEvent: name = "PropertyEvent"; break;
+ case XI_RawKeyPress: name = "RawKeyPress"; break;
+ case XI_RawKeyRelease: name = "RawKeyRelease"; break;
+ case XI_RawButtonPress: name = "RawButtonPress"; break;
+ case XI_RawButtonRelease: name = "RawButtonRelease"; break;
+ case XI_RawMotion: name = "RawMotion"; break;
+ case XI_TouchBegin: name = "TouchBegin"; break;
+ case XI_TouchEnd: name = "TouchEnd"; break;
+ case XI_TouchUpdate: name = "TouchUpdate"; break;
+#ifdef HAVE_XI2_1
+ case XI_TouchUpdateUnowned: name = "TouchUpdateUnowned"; break;
+#endif
+ default: name = "unknown event type"; break;
+ }
+ return name;
+}
+
+string xEventTypeToName(int evtype)
+{
+ switch(evtype) {
+ case KeyPress:
+ return "KeyPress";
+ case KeyRelease:
+ return "KeyRelease";
+ case ButtonPress:
+ return "ButtonPress";
+ case ButtonRelease:
+ return "ButtonRelease";
+ case MotionNotify:
+ return "MotionNotify";
+ case EnterNotify:
+ return "EnterNotify";
+ case LeaveNotify:
+ return "LeaveNotify";
+ case FocusIn:
+ return "FocusIn";
+ case FocusOut:
+ return "FocusOut";
+ case KeymapNotify:
+ return "KeymapNotify";
+ case Expose:
+ return "Expose";
+ case GraphicsExpose:
+ return "GraphicsExpose";
+ case NoExpose:
+ return "NoExpose";
+ case VisibilityNotify:
+ return "VisibilityNotify";
+ case CreateNotify:
+ return "CreateNotify";
+ case DestroyNotify:
+ return "DestroyNotify";
+ case UnmapNotify:
+ return "UnmapNotify";
+ case MapNotify:
+ return "MapNotify";
+ case MapRequest:
+ return "MapRequest";
+ case ReparentNotify:
+ return "ReparentNotify";
+ case ConfigureNotify:
+ return "ConfigureNotify";
+ case ConfigureRequest:
+ return "ConfigureRequest";
+ case GravityNotify:
+ return "GravityNotify";
+ case ResizeRequest:
+ return "ResizeRequest";
+ case CirculateNotify:
+ return "CirculateNotify";
+ case CirculateRequest:
+ return "CirculateRequest";
+ case PropertyNotify:
+ return "PropertyNotify";
+ case SelectionClear:
+ return "SelectionClear";
+ case SelectionRequest:
+ return "SelectionRequest";
+ case SelectionNotify:
+ return "SelectionNotify";
+ case ColormapNotify:
+ return "ColormapNotify";
+ case ClientMessage:
+ return "ClientMessage";
+ case MappingNotify:
+ return "MappingNotify";
+ case GenericEvent:
+ return "GenericEvent";
+ default:
+ return "Unknown event type";
+ }
+}
+
+}
diff --git a/src/player/XInputMTInputDevice.h b/src/player/XInputMTInputDevice.h
new file mode 100644
index 0000000..d395884
--- /dev/null
+++ b/src/player/XInputMTInputDevice.h
@@ -0,0 +1,77 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _XInputMTInputDevice_H_
+#define _XInputMTInputDevice_H_
+
+#include "../api.h"
+#include "../avgconfig.h"
+
+#include "MultitouchInputDevice.h"
+#include "Event.h"
+
+#include "../base/GLMHelper.h"
+
+#include <X11/Xlib.h>
+#include <vector>
+#include <string>
+
+union SDL_Event;
+
+namespace avg {
+
+class AVG_API XInputMTInputDevice: public MultitouchInputDevice
+{
+public:
+ XInputMTInputDevice();
+ virtual ~XInputMTInputDevice();
+ virtual void start();
+
+ void handleXIEvent(const XEvent& xEvent);
+ std::vector<EventPtr> pollEvents();
+
+private:
+ void findMTDevice();
+ TouchEventPtr createEvent(int id, Event::Type type, IntPoint pos);
+
+ static int filterEvent(const SDL_Event * pEvent);
+
+ int m_LastID;
+
+ static ::Display* s_pDisplay;
+ void (*m_SDLLockFunc)(void);
+ void (*m_SDLUnlockFunc)(void);
+
+ int m_XIOpcode;
+
+ std::string m_sDeviceName;
+ int m_DeviceID;
+
+ int m_OldMasterDeviceID;
+ glm::vec2 m_DisplayScale;
+};
+
+typedef boost::shared_ptr<XInputMTInputDevice> XInputMTInputDevicePtr;
+
+}
+
+#endif
+
diff --git a/src/player/testcalibrator.cpp b/src/player/testcalibrator.cpp
new file mode 100644
index 0000000..a9898f5
--- /dev/null
+++ b/src/player/testcalibrator.cpp
@@ -0,0 +1,120 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "TrackerCalibrator.h"
+
+#include "../base/GLMHelper.h"
+
+#include "../base/TestSuite.h"
+#include "../base/Exception.h"
+#include "../base/Logger.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+
+using namespace avg;
+using namespace std;
+
+class CalibratorTest: public Test {
+public:
+ CalibratorTest()
+ : Test("CalibratorTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+ DeDistortPtr pTrafo;
+ {
+ TrackerCalibrator calibrator(IntPoint(640, 480), IntPoint(640,480));
+ bool bDone = false;
+ while (!bDone) {
+ IntPoint displayPoint(calibrator.getDisplayPoint());
+ calibrator.setCamPoint(glm::vec2(displayPoint));
+ bDone = !calibrator.nextPoint();
+ }
+ pTrafo = calibrator.makeTransformer();
+ TEST(glm::length(pTrafo->transformBlobToScreen(glm::dvec2(1.00,1.00)) -
+ glm::dvec2(1.00,1.00)) < 1);
+ TEST(checkTransform(pTrafo, glm::dvec2(0,0), glm::dvec2(0,0)));
+ TEST(checkTransform(pTrafo, glm::dvec2(640, 480), glm::dvec2(640, 480)));
+ }
+ {
+ TrackerCalibrator calibrator(IntPoint(640, 480), IntPoint(1280,720));
+ bool bDone = false;
+ while (!bDone) {
+ IntPoint displayPoint(calibrator.getDisplayPoint());
+ calibrator.setCamPoint(glm::vec2(displayPoint.x/2, displayPoint.y/1.5));
+ bDone = !calibrator.nextPoint();
+ }
+ pTrafo = calibrator.makeTransformer();
+ TEST(glm::length(pTrafo->transformBlobToScreen(glm::dvec2(1.00,1.00)) -
+ glm::dvec2(2.00,1.50)) < 1);
+ TEST(checkTransform(pTrafo, glm::dvec2(0,0), glm::dvec2(0,0)));
+ TEST(checkTransform(pTrafo, glm::dvec2(640, 480), glm::dvec2(640, 480)));
+ TEST(checkBlobToScreen(pTrafo, glm::dvec2(0,0), glm::dvec2(0,0)));
+ TEST(checkBlobToScreen(pTrafo, glm::dvec2(640, 480), glm::dvec2(1280, 720)));
+ }
+ }
+
+ bool checkTransform(CoordTransformerPtr pTrafo, const glm::dvec2& srcPt,
+ const glm::dvec2& destPt)
+ {
+ glm::dvec2 ResultPt = pTrafo->transform_point(srcPt);
+// cerr << srcPt << " -> " << ResultPt << ", expected " << destPt << endl;
+ return ((fabs(ResultPt.x-destPt.x) < 0.1) && (fabs(ResultPt.y-destPt.y) < 0.1));
+ }
+
+ bool checkBlobToScreen(DeDistortPtr pTrafo,
+ const glm::dvec2& srcPt, const glm::dvec2& destPt)
+ {
+ glm::dvec2 ResultPt =
+ pTrafo->transformBlobToScreen(pTrafo->transform_point(srcPt));
+// cerr << srcPt << " -> " << ResultPt << ", expected " << destPt << endl;
+ return ((fabs(ResultPt.x-destPt.x) < 1) && (fabs(ResultPt.y-destPt.y) < 1));
+ }
+
+};
+
+class CalibratorTestSuite: public TestSuite {
+public:
+ CalibratorTestSuite()
+ : TestSuite("CalibratorTestSuite")
+ {
+ addTest(TestPtr(new CalibratorTest));
+ }
+};
+
+
+int main(int nargs, char** args)
+{
+ CalibratorTestSuite suite;
+ suite.runTests();
+ bool bOK = suite.isOk();
+
+ if (bOK) {
+ return 0;
+ } else {
+ return 1;
+ }
+}
+
diff --git a/src/player/testplayer.cpp b/src/player/testplayer.cpp
new file mode 100644
index 0000000..aa0bef9
--- /dev/null
+++ b/src/player/testplayer.cpp
@@ -0,0 +1,101 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "Player.h"
+
+#include "../base/TestSuite.h"
+#include "../base/Exception.h"
+#include "../base/Logger.h"
+
+#include "../graphics/GLConfig.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <string>
+
+#ifdef WIN32
+#include <direct.h>
+#endif
+
+using namespace avg;
+using namespace std;
+
+class PlayerTest: public Test {
+public:
+ PlayerTest()
+ : Test("PlayerTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+ Player player;
+ player.loadString(
+ " <?xml version=\"1.0\"?>"
+ " <avg width=\"160\" height=\"120\">"
+ " <words text=\"foo\"/>"
+ " </avg>"
+ );
+ player.setOGLOptions(false, true, 1, GLConfig::AUTO, true);
+ GLContext::enableErrorChecks(true);
+ player.disablePython();
+ if (!getenv("AVG_CONSOLE_TEST")) {
+#ifdef WIN32
+ char sz[1024];
+ _getcwd(sz, 1024);
+ cerr << "Current directory: " << sz << endl;
+#endif
+ player.initPlayback("../graphics/shaders/");
+ player.doFrame(false);
+ player.cleanup(false);
+ }
+ try {
+ throw bad_cast();
+ } catch (bad_cast&) {
+
+ }
+ }
+};
+
+class PlayerTestSuite: public TestSuite {
+public:
+ PlayerTestSuite()
+ : TestSuite("PlayerTestSuite")
+ {
+ addTest(TestPtr(new PlayerTest));
+ }
+};
+
+
+int main(int nargs, char** args)
+{
+ PlayerTestSuite suite;
+ suite.runTests();
+ bool bOK = suite.isOk();
+
+ if (bOK) {
+ return 0;
+ } else {
+ return 1;
+ }
+}
+
diff --git a/src/python/Makefile.am b/src/python/Makefile.am
new file mode 100644
index 0000000..0ec168f
--- /dev/null
+++ b/src/python/Makefile.am
@@ -0,0 +1,6 @@
+SUBDIRS = widget data app
+pkgpyexec_PYTHON = enumcompat.py camcalibrator.py textarea.py \
+ mathutil.py avgapp.py appstarter.py utils.py filter.py \
+ mtemu.py geom.py parsecamargs.py apphelpers.py methodref.py \
+ statemachine.py coordcalibrator.py graph.py __init__.py gesture.py \
+ persist.py
diff --git a/src/python/__init__.py b/src/python/__init__.py
new file mode 100644
index 0000000..5d0d2cf
--- /dev/null
+++ b/src/python/__init__.py
@@ -0,0 +1,29 @@
+'''
+libavg is a high-level development platform for media-centric applications.
+https://www.libavg.de
+'''
+
+# Work around libstdc++ Mesa bug
+# (https://bugs.launchpad.net/ubuntu/+source/mesa/+bug/259219)
+from platform import system
+if system() == 'Linux':
+ from ctypes import cdll
+ cdll.LoadLibrary("libpixman-1.so.0")
+ cdll.LoadLibrary("libstdc++.so.6")
+del system
+
+from avg import *
+player = avg.Player.get()
+
+from enumcompat import *
+
+import textarea
+import statemachine
+from avgapp import AVGApp
+from appstarter import AVGAppStarter, AVGMTAppStarter, AppStarter
+import utils, methodref
+import gesture
+import filter
+import persist
+import app
+
diff --git a/src/python/app/Makefile.am b/src/python/app/Makefile.am
new file mode 100644
index 0000000..8c78161
--- /dev/null
+++ b/src/python/app/Makefile.am
@@ -0,0 +1,3 @@
+pkgwidgetdir = $(pkgpyexecdir)/app
+pkgwidget_PYTHON = __init__.py app.py settings.py flashmessage.py keyboardmanager.py \
+ debugpanel.py touchvisualization.py
diff --git a/src/python/app/__init__.py b/src/python/app/__init__.py
new file mode 100644
index 0000000..32d41e0
--- /dev/null
+++ b/src/python/app/__init__.py
@@ -0,0 +1,29 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+# libavg - Media Playback Engine.
+# Copyright (C) 2003-2014 Ulrich von Zadow
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Current versions can be found at www.libavg.de
+#
+# Original author of this file is OXullo Interecans <x at brainrapers dot org>
+
+from app import App
+from app import MainDiv
+
+instance = None
+
diff --git a/src/python/app/app.py b/src/python/app/app.py
new file mode 100644
index 0000000..8c7ddda
--- /dev/null
+++ b/src/python/app/app.py
@@ -0,0 +1,385 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+# libavg - Media Playback Engine.
+# Copyright (C) 2003-2014 Ulrich von Zadow
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Current versions can be found at www.libavg.de
+#
+# Original author of this file is OXullo Interecans <x at brainrapers dot org>
+
+
+import os
+import math
+import time
+
+import libavg
+from libavg import avg, Point2D, mtemu
+
+import settings
+from settings import Option
+import keyboardmanager
+import debugpanel
+import flashmessage
+
+
+class MainDiv(libavg.avg.DivNode):
+ VERSION = 'undef'
+
+ def __init__(self, **kargs):
+ assert not 'parent' in kargs
+ super(MainDiv, self).__init__(**kargs)
+ self.registerInstance(self, None)
+
+ def onArgvParserCreated(self, parser):
+ pass
+
+ def onArgvParsed(self, options, args, parser):
+ pass
+
+ def onStartup(self):
+ pass
+
+ def onInit(self):
+ pass
+
+ def onExit(self):
+ pass
+
+ def onFrame(self):
+ pass
+
+
+class App(object):
+ def __init__(self):
+ self._setupInstance()
+
+ self._mainDiv = None
+ self._appParent = None
+ self._debugPanel = None
+ self._overlayPanel = None
+ self._resolution = None
+ self._windowSize = None
+ self._mtEmu = None
+
+ self.__lastFrameTimestamp = 0
+
+ self._setupSettings()
+
+ def run(self, mainDiv, **kargs):
+ assert isinstance(mainDiv, MainDiv)
+ self._mainDiv = mainDiv
+
+ self.mainDiv.settings = self._settings
+ self._applySettingsExtenders(kargs)
+ self._setupLogging()
+
+ mainDiv.onStartup()
+
+ self._setupResolution()
+ self._setupRootNode()
+ self._setupMouse()
+ pos, size, angle = self._getAppParentGeometry()
+ self._setupAppParent(pos, size, angle)
+ self._setupMainDiv()
+ self._setupTopPanel()
+
+ self._setupDebugPanel()
+ self._setupKeyboardManager()
+ self._setupDebuggingWidgets()
+ self._applyResolution()
+ self._setupOnInit()
+
+ self.onBeforeLaunch()
+
+ self.__lastFrameTimestamp = time.time()
+
+ try:
+ self._runLoop()
+ except Exception, e:
+ self._teardownKeyboardManager()
+ raise
+
+ mainDiv.onExit()
+
+ self._teardownKeyboardManager()
+
+ return 0
+
+ @property
+ def mainDiv(self):
+ return self._mainDiv
+
+ @property
+ def debugPanel(self):
+ return self._debugPanel
+
+ @property
+ def overlayPanel(self):
+ return self._overlayPanel
+
+ @property
+ def settings(self):
+ return self._settings
+
+ def onBeforeLaunch(self):
+ pass
+
+ def takeScreenshot(self, targetFolder='.'):
+ screenBmp = libavg.player.screenshot()
+
+ filenameTemplate = os.path.join(targetFolder, '%s-%03d.png')
+
+ i = 1
+ while i < 1000:
+ filename = filenameTemplate % (self.__class__.__name__, i)
+ if os.path.exists(filename):
+ i += 1
+ else:
+ break
+
+ if i == 1000:
+ flashmessage.FlashMessage('Maximum number of screenshots reached',
+ parent=self._appParent, isError=True)
+ else:
+ screenBmp.save(filename)
+ flashmessage.FlashMessage('Screenshot saved as %s' % filename,
+ parent=self._appParent)
+
+ def dumpTextObjectCount(self):
+ objects = libavg.player.getTestHelper().getObjectCount()
+ savedSeverity = libavg.logger.getCategories()[libavg.logger.Category.APP]
+ libavg.logger.configureCategory(libavg.logger.Category.APP,
+ libavg.logger.Severity.INFO)
+ libavg.logger.info('Dumping objects count')
+ for key, value in objects.iteritems():
+ libavg.logger.info(' %-25s: %s' % (key, value))
+
+ libavg.logger.configureCategory(libavg.logger.Category.APP, savedSeverity)
+
+ def _setupInstance(self):
+ import libavg.app
+
+ if libavg.app.instance is not None:
+ raise RuntimeError('%s has been already instantiated' %
+ self.__class__.__name__)
+
+ libavg.app.instance = self
+
+ def _setupSettings(self):
+ self._settings = settings.Settings()
+ self._settings.addOption(Option('app_resolution', '640x480'))
+ self._settings.addOption(Option('app_window_size', ''))
+ self._settings.addOption(Option('app_fullscreen', 'false'))
+ self._settings.addOption(Option('app_show_cursor', 'true'))
+ self._settings.addOption(Option('app_rotation', 'normal'))
+ self._settings.addOption(Option('app_panel_fontsize', '10'))
+ self._settings.addOption(Option('app_mouse_enabled', 'true'))
+ self._settings.addOption(Option('multitouch_enabled', 'false'))
+ self._settings.addOption(Option('multitouch_driver', ''))
+ self._settings.addOption(Option('multitouch_tuio_port', ''))
+ self._settings.addOption(Option('multitouch_mtdev_device', ''))
+ self._settings.addOption(Option('log_avg_categories', ''))
+
+ def _applySettingsExtenders(self, kargs):
+ self.settings.applyExtender(settings.KargsExtender(kargs))
+ argvExtender = settings.ArgvExtender(self.mainDiv.VERSION)
+ self.mainDiv.onArgvParserCreated(argvExtender.parser)
+ self.settings.applyExtender(argvExtender)
+ self.mainDiv.onArgvParsed(argvExtender.parsedArgs[0], argvExtender.parsedArgs[1],
+ argvExtender.parser)
+
+ def _setupLogging(self):
+ catMap = self.settings.get('log_avg_categories').strip()
+ if catMap:
+ for catPair in catMap.split(' '):
+ cat, strLevel = catPair.split(':')
+ level = getattr(avg.logger.Severity, strLevel)
+
+ libavg.avg.logger.configureCategory(cat, level)
+
+ def _setupRootNode(self):
+ libavg.player.loadString('''<?xml version="1.0"?>
+ <!DOCTYPE avg SYSTEM "../../libavg/doc/avg.dtd">
+ <avg width="%s" height="%s">
+ </avg>''' % tuple(self._resolution))
+
+ def _setupMouse(self):
+ libavg.player.enableMouse(self.settings.getBoolean('app_mouse_enabled'))
+
+ def _setupMultitouch(self):
+ if self.settings.getBoolean('multitouch_enabled'):
+ driver = self.settings.get('multitouch_driver').upper()
+ if driver:
+ os.putenv('AVG_MULTITOUCH_DRIVER', driver)
+
+ tuio_port = self.settings.get('multitouch_tuio_port').upper()
+ if tuio_port:
+ os.putenv('AVG_TUIO_PORT', tuio_port)
+
+ mtdev_device = self.settings.get('multitouch_mtdev_device').upper()
+ if mtdev_device:
+ os.putenv('AVG_LINUX_MULTITOUCH_DEVICE', mtdev_device)
+
+ libavg.player.enableMultitouch()
+
+ def _getAppParentGeometry(self):
+ rotation = self.settings.get('app_rotation').lower()
+ size = self._resolution
+ pos = (0, 0)
+ angle = 0
+
+ if rotation == 'left':
+ angle = -math.pi / 2
+ size = (self._resolution.y, self._resolution.x)
+ pos = ((self._resolution.x - self._resolution.y) / 2,
+ (self._resolution.y - self._resolution.x) / 2)
+ elif rotation == 'right':
+ angle = math.pi / 2
+ size = (self._resolution.y, self._resolution.x)
+ pos = ((self._resolution.x - self._resolution.y) / 2,
+ (self._resolution.y - self._resolution.x) / 2)
+ elif rotation == 'inverted':
+ angle = math.pi
+ elif rotation != 'normal':
+ raise TypeError('Invalid rotation %s' % rotation)
+
+ return (pos, size, angle)
+
+ def _setupAppParent(self, pos, size, angle):
+ self._appParent = libavg.avg.DivNode(parent=libavg.player.getRootNode(),
+ pos=pos, size=size, angle=angle)
+
+ def _setupMainDiv(self):
+ self._appParent.appendChild(self.mainDiv)
+ self.mainDiv.size = self._appParent.size
+
+ def _setupTopPanel(self):
+ self._overlayPanel = libavg.avg.DivNode(parent=self._appParent, id='overlayPanel')
+
+ def _setupDebugPanel(self):
+ self._debugPanel = debugpanel.DebugPanel(parent=self._appParent,
+ size=self._appParent.size, id='debugPanel',
+ fontsize=self.settings.getFloat('app_panel_fontsize'))
+
+ def _setupDebuggingWidgets(self):
+ pass
+
+ def _setupResolution(self):
+ rotation = self.settings.get('app_rotation').lower()
+ resolutionStr = self.settings.get('app_resolution').lower()
+ if resolutionStr != '':
+ resolution = self.settings.getPoint2D('app_resolution')
+ else:
+ resolution = libavg.player.getScreenResolution()
+
+ windowSizeStr = self.settings.get('app_window_size')
+ if windowSizeStr != '':
+ windowSize = self.settings.getPoint2D('app_window_size')
+ else:
+ windowSize = resolution
+
+ if rotation in ('left', 'right'):
+ resolution = Point2D(resolution.y, resolution.x)
+ windowSize = Point2D(windowSize.y, windowSize.x)
+
+ self._resolution = resolution
+ self._windowSize = windowSize
+
+ def _applyResolution(self):
+ fullscreen = self.settings.getBoolean('app_fullscreen')
+
+ if fullscreen:
+ resolution = self._resolution
+ else:
+ resolution = self._windowSize
+
+ libavg.player.setResolution(
+ fullscreen,
+ int(resolution.x), int(resolution.y),
+ 0 # color depth
+ )
+
+ libavg.player.showCursor(self.settings.getBoolean('app_show_cursor'))
+
+ def _setupKeyboardManager(self):
+ keyboardmanager.init()
+ keyboardmanager.bindKeyDown(
+ keystring='d',
+ handler=self._debugPanel.toggleVisibility,
+ help='Show/hide the debug panel',
+ modifiers=libavg.avg.KEYMOD_CTRL)
+
+ keyboardmanager.bindKeyDown(
+ keystring='h',
+ handler=lambda: libavg.player.showCursor(
+ not libavg.player.isCursorShown()),
+ help='Show/hide cursor',
+ modifiers=libavg.avg.KEYMOD_CTRL)
+
+ keyboardmanager.bindKeyDown(
+ keystring='p',
+ handler=self.takeScreenshot,
+ help='Take screenshot',
+ modifiers=libavg.avg.KEYMOD_CTRL)
+
+ keyboardmanager.bindKeyDown(
+ keystring='b',
+ handler=self.dumpTextObjectCount,
+ help='Dump objects count to the console',
+ modifiers=libavg.avg.KEYMOD_CTRL)
+
+ keyboardmanager.bindKeyDown(
+ keystring='e',
+ handler=self._toggleMtEmulation,
+ help='Toggle multitouch emulation',
+ modifiers=libavg.avg.KEYMOD_CTRL)
+
+ self.debugPanel.setupKeys()
+
+ def _toggleMtEmulation(self):
+ if self._mtEmu is None:
+ self._mtEmu = mtemu.MTemu()
+ keyboardmanager.bindKeyDown('shift', self._mtEmu.enableDualTouch,
+ 'Enable pinch gesture emulation')
+ keyboardmanager.bindKeyUp('shift', self._mtEmu.disableDualTouch,
+ 'Disable pinch gesture emulation')
+
+ keyboardmanager.bindKeyDown('t', self._mtEmu.toggleSource,
+ 'Toggle source between TOUCH and TRACK', libavg.avg.KEYMOD_CTRL)
+ else:
+ self._mtEmu.deinit()
+ keyboardmanager.unbindKeyDown('t', libavg.avg.KEYMOD_CTRL)
+ keyboardmanager.unbindKeyDown('shift')
+ keyboardmanager.unbindKeyUp('shift')
+
+ del self._mtEmu
+ self._mtEmu = None
+
+ def _teardownKeyboardManager(self):
+ keyboardmanager.unbindAll()
+
+ def _setupOnInit(self):
+ libavg.player.setTimeout(0, self._onInitInternal)
+
+ def _runLoop(self):
+ libavg.player.play()
+
+ def _onInitInternal(self):
+ self._setupMultitouch()
+ self.mainDiv.onInit()
+ libavg.player.subscribe(libavg.player.ON_FRAME, self.mainDiv.onFrame)
diff --git a/src/python/app/debugpanel.py b/src/python/app/debugpanel.py
new file mode 100644
index 0000000..c786785
--- /dev/null
+++ b/src/python/app/debugpanel.py
@@ -0,0 +1,697 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+# libavg - Media Playback Engine.
+# Copyright (C) 2003-2014 Ulrich von Zadow
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Current versions can be found at www.libavg.de
+#
+# Original authors of this file are
+# OXullo Interecans <x at brainrapers dot org>
+# Richard Klemm <richy at coding-reality.de>
+
+from collections import defaultdict
+from collections import deque
+import math
+
+import libavg
+from libavg import avg
+from touchvisualization import DebugTouchVisualization
+from touchvisualization import TouchVisualizationOverlay as TouchVisOverlay
+
+
+import keyboardmanager as kbmgr
+
+g_fontsize = 10
+
+PANGO_ENTITIES_MAP = {
+ "&": "&amp;",
+ '"': "&quot;",
+ "'": "&apos;",
+ ">": "&gt;",
+ "<": "&lt;",
+}
+
+def subscribe(publisher, msgID, callable_):
+ publisher.subscribe(msgID, callable_)
+ return lambda: publisher.unsubscribe(msgID, callable_)
+
+
+class DebugWidgetFrame(avg.DivNode):
+
+ BORDER = 7
+ FRAME_HEIGHT_CHANGED = avg.Publisher.genMessageID()
+
+ def __init__(self, size, widgetCls, *args, **kwargs):
+ super(DebugWidgetFrame, self).__init__(size=size, *args, **kwargs)
+ self.registerInstance(self, None)
+ self.setup(widgetCls)
+ self.subscribe(self.SIZE_CHANGED, self._onSizeChanged)
+ self.size = size
+ self._onSizeChanged(size)
+
+ def setup(self, widgetCls):
+ self.__background = avg.RectNode(parent=self, opacity=0.8,
+ fillcolor='000000', fillopacity=0.8)
+ self.__widget = widgetCls(parent=self,
+ size=(max(0, self.width - self.BORDER * 2), 0),
+ pos=(self.BORDER, self.BORDER))
+ self.__selectHighlight = avg.RectNode(parent=self, color="35C0CD",
+ strokewidth=self.BORDER, opacity=0.8,
+ pos=(self.BORDER / 2, self.BORDER / 2), active=False, sensitive=False)
+ self.__boundary = avg.RectNode(parent=self, sensitive=False)
+
+ self.publish(DebugWidgetFrame.FRAME_HEIGHT_CHANGED)
+
+ self.__widget.subscribe(self.__widget.WIDGET_HEIGHT_CHANGED,
+ self.adjustWidgetHeight)
+ self.__widget.update()
+
+ def _onSizeChanged(self, size):
+ self.__boundary.size = size
+ self.__background.size = size
+ childSize = (max(0, size[0] - self.BORDER * 2), max(0, size[1] - self.BORDER * 2))
+ self.__selectHighlight.size = (max(0, size[0] - self.BORDER),
+ max(0, size[1] - self.BORDER))
+ self.__widget.size = childSize
+ self.__widget.syncSize(childSize)
+
+ def adjustWidgetHeight(self, height):
+ self.size = (max(0, self.width), height + 2 * self.BORDER)
+ self.notifySubscribers(DebugWidgetFrame.FRAME_HEIGHT_CHANGED, [])
+
+ def toggleSelect(self, event=None):
+ self.__selectHighlight.active = not(self.__selectHighlight.active)
+
+ def isSelected(self):
+ return self.__selectHighlight.active
+
+ def select(self):
+ self.__selectHighlight.active = True
+
+ def unselect(self):
+ self.__selectHighlight.active = False
+
+ def show(self):
+ self.active = True
+ self.__widget.onShow()
+ self.__widget.update()
+
+ def hide(self):
+ self.active = False
+ self.__widget.onHide()
+
+ @property
+ def widget(self):
+ return self.__widget
+
+
+class DebugWidget(avg.DivNode):
+ SLOT_HEIGHT = 200
+ CAPTION = ''
+
+ WIDGET_HEIGHT_CHANGED = avg.Publisher.genMessageID()
+
+ def __init__(self, parent=None, **kwargs):
+ super(DebugWidget, self).__init__(**kwargs)
+ self.registerInstance(self, parent)
+ self.publish(DebugWidget.WIDGET_HEIGHT_CHANGED)
+ if self.CAPTION:
+ self._caption = avg.WordsNode(text=self.CAPTION, pivot=(0, 0),
+ opacity=0.5, fontsize=14, parent=self)
+ self._caption.angle = math.pi / 2
+ self._caption.pos = (self.width, 0)
+
+ def syncSize(self, size):
+ self._caption.width = size[1]
+
+ def update(self):
+ pass
+
+ def onShow(self):
+ pass
+
+ def onHide(self):
+ pass
+
+ def kill(self):
+ pass
+
+
+NUM_COLS = 10
+COL_WIDTH = 60
+ROW_HEIGHT = g_fontsize + 2
+
+
+class TableRow(avg.DivNode):
+ COL_POS_X = 0
+ ROW_ID = 0
+
+ def __init__(self, parent=None, **kwargs):
+ super(TableRow, self).__init__(**kwargs)
+ self.registerInstance(self, parent)
+ global NUM_COLS
+ NUM_COLS = int((self.parent.width - COL_WIDTH * 4) / COL_WIDTH)
+ self._initRow()
+ TableRow.ROW_ID += 1
+
+ def _initRow(self):
+ self.columnBackground = avg.RectNode(parent=self, fillcolor="222222",
+ fillopacity=0.6, opacity=0)
+ self.columnContainer = avg.DivNode(parent=self)
+ if TableRow.ROW_ID % 2 != 0:
+ self.columnBackground.fillopacity = 0
+ self.cols = [0] * NUM_COLS
+ self.liveColumn = avg.WordsNode(parent=self.columnContainer, fontsize=g_fontsize,
+ text="N/A - SPECIAL", size=(COL_WIDTH, ROW_HEIGHT), variant="bold")
+ for i in xrange(0, NUM_COLS):
+ self.cols[i] = (avg.WordsNode(parent=self.columnContainer,
+ fontsize=g_fontsize,
+ text="0", size=(COL_WIDTH / 2.0, ROW_HEIGHT),
+ pos=((i+1) * COL_WIDTH, 0)),
+ avg.WordsNode(parent=self.columnContainer,
+ fontsize=g_fontsize,
+ text="(0)", size=(COL_WIDTH / 2.0, ROW_HEIGHT),
+ pos=((i+1) * COL_WIDTH + COL_WIDTH / 2, 0),
+ color="000000"))
+
+ self.rowData = deque([(0, 0)] * (NUM_COLS + 1), maxlen=NUM_COLS + 1)
+ self.label = avg.WordsNode(parent=self, fontsize=g_fontsize, variant="bold")
+ self.setLabel("NONE")
+
+ @property
+ def height(self):
+ return self.label.height
+
+ def setLabel(self, label):
+ if self.label.text == label + ":":
+ return
+ self.label.text = label + ":"
+ TableRow.COL_POS_X = max(TableRow.COL_POS_X, self.label.width)
+ if self.label.width < TableRow.COL_POS_X:
+ self.parent.labelColumnSizeChanged()
+
+ def resizeLabelColumn(self):
+ self.columnContainer.pos = (TableRow.COL_POS_X + 10, 0)
+ self.columnBackground.size = (self.columnContainer.x + self.liveColumn.x +
+ self.liveColumn.width, g_fontsize)
+
+ def insertValue(self, data):
+ prevValue = self.rowData[0][0]
+ self.rowData.appendleft([data, data-prevValue])
+ for i in xrange(0, len(self.rowData)-1):
+ val, diff = self.rowData[i]
+ column = self.cols[i]
+ column[0].text = str(val)
+ column[1].text = "({diff})".format(diff=diff)
+ column[1].pos = (column[0].x + column[0].getLineExtents(0)[0] + 2,
+ column[0].y)
+ if diff == 0:
+ column[1].color = "000000"
+ elif diff < 0:
+ column[1].color = "00FF00"
+ else:
+ column[1].color = "FF0000"
+
+ def updateLiveColumn(self, value):
+ self.liveColumn.text = str(value)
+
+
+class Table(avg.DivNode):
+ def __init__(self, parent=None, **kwargs):
+ super(Table, self).__init__(**kwargs)
+ self.registerInstance(self, parent)
+
+ def labelColumnSizeChanged(self):
+ for childID in xrange(0, self.getNumChildren()):
+ child = self.getChild(childID)
+ child.resizeLabelColumn()
+
+
+class ObjectDumpWidget(DebugWidget):
+ CAPTION = 'Objects count'
+
+ def __init__(self, parent=None, **kwargs):
+ super(ObjectDumpWidget, self).__init__(**kwargs)
+ self.registerInstance(self, parent)
+ self.tableContainer = Table(parent=self, size=(self.width, self.SLOT_HEIGHT))
+ self.tableDivs = defaultdict(lambda: TableRow(parent=self.tableContainer))
+
+ def update(self):
+ objDump = libavg.player.getTestHelper().getObjectCount()
+ pos = (0, 0)
+ for key in sorted(objDump.iterkeys()):
+ val = objDump[key]
+ self.tableDivs[key].updateLiveColumn(val)
+ self.tableDivs[key].setLabel(key)
+ self.tableDivs[key].pos = pos
+ pos = (0, pos[1] + self.tableDivs[key].height)
+ height = len(objDump) * self.tableDivs[key].height
+ if self.height != height:
+ self.notifySubscribers(DebugWidget.WIDGET_HEIGHT_CHANGED, [height])
+
+ def persistColumn(self):
+ objDump = libavg.player.getTestHelper().getObjectCount()
+ for key, val in objDump.iteritems():
+ self.tableDivs[key].insertValue(val)
+
+ def syncSize(self, size):
+ self.tableContainer.size = (size[0], size[1] - (g_fontsize + 2))
+
+ def onShow(self):
+ self.intervalID = libavg.player.setInterval(1000, self.update)
+ kbmgr.bindKeyDown(keystring='i',
+ handler=self.persistColumn,
+ help="Object count snapshot",
+ modifiers=libavg.KEYMOD_CTRL)
+
+ def onHide(self):
+ if self.intervalID:
+ libavg.player.clearInterval(self.intervalID)
+ self.intervalID = None
+ kbmgr.unbindKeyDown(keystring='i', modifiers=libavg.KEYMOD_CTRL)
+
+ def kill(self):
+ self.onHide()
+ self.tableDivs = None
+
+
+class GraphWidget(DebugWidget):
+ def __init__(self, **kwargs):
+ super(GraphWidget, self).__init__(**kwargs)
+ self.registerInstance(self, None)
+ self.__graph = None
+
+ def onShow(self):
+ if self.__graph:
+ self.__graph.active = True
+ else:
+ self.__graph = self._createGraph()
+
+ def onHide(self):
+ if self.__graph:
+ self.__graph.active = False
+
+ def kill(self):
+ self.__graph.unlink(True)
+
+ def _createGraph(self):
+ pass
+
+
+class MemoryGraphWidget(GraphWidget):
+ CAPTION = 'Memory usage'
+
+ def _createGraph(self):
+ return libavg.graph.AveragingGraph(parent=self, size=self.size,
+ getValue=avg.getMemoryUsage)
+
+
+class FrametimeGraphWidget(GraphWidget):
+ CAPTION = 'Time per frame'
+
+ def _createGraph(self):
+ return libavg.graph.SlidingBinnedGraph(parent=self,
+ getValue=libavg.player.getFrameTime,
+ binsThresholds=[0.0, 20.0, 40.0, 80.0, 160.0],
+ size=self.size)
+
+
+class GPUMemoryGraphWidget(GraphWidget):
+ CAPTION = 'GPU Memory usage'
+
+ def _createGraph(self):
+ try:
+ libavg.player.getVideoMemUsed()
+ except RuntimeError:
+ return avg.WordsNode(parent=self,
+ text='GPU memory graph is not supported on this hardware',
+ color='ff5555')
+ else:
+ return libavg.graph.AveragingGraph(parent=self, size=self.size,
+ getValue=libavg.player.getVideoMemUsed)
+
+
+class KeyboardManagerBindingsShower(DebugWidget):
+ CAPTION = 'Keyboard bindings'
+
+ def __init__(self, *args, **kwargs):
+ super(KeyboardManagerBindingsShower, self).__init__(**kwargs)
+ self.registerInstance(self, None)
+ self.keybindingWordNodes = []
+ kbmgr.publisher.subscribe(kbmgr.publisher.BINDINGS_UPDATED, self.update)
+
+ def clear(self):
+ for node in self.keybindingWordNodes:
+ node.unlink(True)
+ self.keybindingWordNodes = []
+
+ def update(self):
+ self.clear()
+ for binding in kbmgr.getCurrentBindings():
+ keystring = binding.keystring.decode('utf8')
+ modifiersStr = self.__modifiersToString(binding.modifiers)
+
+ if modifiersStr is not None:
+ key = '%s-%s' % (modifiersStr, keystring)
+ else:
+ key = keystring
+
+ if binding.type == libavg.avg.KEYDOWN:
+ key = '%s %s' % (unichr(8595), key)
+ else:
+ key = '%s %s' % (unichr(8593), key)
+
+ node = avg.WordsNode(
+ text='<span size="large"><b>%s</b></span>: %s' %
+ (key, binding.help),
+ fontsize=g_fontsize, parent=self)
+ self.keybindingWordNodes.append(node)
+
+ self._placeNodes()
+
+ def _placeNodes(self):
+ if not self.keybindingWordNodes:
+ return
+
+ maxWidth = max([node.width for node in self.keybindingWordNodes])
+ columns = int(self.parent.width / maxWidth)
+ rows = len(self.keybindingWordNodes) / columns
+ remainder = len(self.keybindingWordNodes) % columns
+
+ if remainder != 0:
+ rows += 1
+
+ colSize = self.parent.width / columns
+
+ currentColumn = 0
+ currentRow = 0
+ heights = [0] * columns
+ for node in self.keybindingWordNodes:
+ if currentRow == rows and currentColumn < columns - 1:
+ currentRow = 0
+ currentColumn += 1
+
+ node.pos = (currentColumn * colSize, heights[currentColumn])
+ heights[currentColumn] += node.height
+ currentRow += 1
+
+ finalHeight = max(heights)
+ if self.height != finalHeight:
+ self.notifySubscribers(self.WIDGET_HEIGHT_CHANGED, [finalHeight])
+
+ def __modifiersToString(self, modifiers):
+ def isSingleBit(number):
+ bitsSet = 0
+ for i in xrange(8):
+ if (1 << i) & number:
+ bitsSet += 1
+
+ return bitsSet == 1
+
+ if modifiers in (0, kbmgr.KEYMOD_ANY):
+ return None
+
+ allModifiers = []
+ for mod in dir(avg):
+ if 'KEYMOD_' in mod:
+ maskVal = int(getattr(avg, mod))
+ if isSingleBit(maskVal):
+ allModifiers.append((maskVal, mod))
+
+ modifiersStringsList = []
+ for modval, modstr in allModifiers:
+ if modifiers & modval:
+ modifiersStringsList.append(modstr.replace('KEYMOD_', ''))
+
+ for doubleMod in ['CTRL', 'META', 'SHIFT']:
+ left = 'L' + doubleMod
+ right = 'R' + doubleMod
+ if left in modifiersStringsList and right in modifiersStringsList:
+ modifiersStringsList.remove(left)
+ modifiersStringsList.remove(right)
+ modifiersStringsList.append(doubleMod)
+
+ return '/'.join(modifiersStringsList).lower()
+
+
+class DebugPanel(avg.DivNode):
+ def __init__(self, parent=None, fontsize=10, **kwargs):
+ super(DebugPanel, self).__init__(**kwargs)
+ self.registerInstance(self, parent)
+
+ avg.RectNode(size=self.size, opacity=0, fillopacity=0.3, fillcolor='ff0000',
+ parent=self)
+ avg.WordsNode(text='Debug panel', fontsize=fontsize,
+ pos=(0, self.height - fontsize - fontsize / 3),
+ parent=self)
+
+ self.sensitive = False
+ self.active = False
+ self.__panel = None
+ self.__callables = []
+ self.__fontsize = fontsize
+ self.__touchVisOverlay = None
+
+ def setupKeys(self):
+ kbmgr.bindKeyDown(keystring='g',
+ handler=lambda: self.toggleWidget(GPUMemoryGraphWidget),
+ help="GPU memory graph",
+ modifiers=libavg.avg.KEYMOD_CTRL)
+
+ kbmgr.bindKeyDown(keystring='m',
+ handler=lambda: self.toggleWidget(MemoryGraphWidget),
+ help="Memory graph",
+ modifiers=libavg.avg.KEYMOD_CTRL)
+
+ kbmgr.bindKeyDown(keystring='f',
+ handler=lambda: self.toggleWidget(FrametimeGraphWidget),
+ help="Frametime graph",
+ modifiers=libavg.avg.KEYMOD_CTRL)
+
+ kbmgr.bindKeyDown(keystring='?',
+ handler=lambda: self.toggleWidget(KeyboardManagerBindingsShower),
+ help="Show keyboard bindings",
+ modifiers=kbmgr.KEYMOD_ANY)
+
+ kbmgr.bindKeyDown(keystring='o',
+ handler=lambda: self.toggleWidget(ObjectDumpWidget),
+ help="Object count table",
+ modifiers=libavg.avg.KEYMOD_CTRL)
+
+ kbmgr.bindKeyDown(keystring='v', handler=self.toggleTouchVisualization,
+ help="Cursor visualization",
+ modifiers=libavg.avg.KEYMOD_CTRL)
+
+ def addWidget(self, widgetCls, *args, **kwargs):
+ callable_ = lambda: self.__panel.addWidget(widgetCls, *args, **kwargs)
+ if self.__panel:
+ callable_()
+ else:
+ self.__callables.append(callable_)
+
+ def toggleWidget(self, *args, **kwargs):
+ if not self.active:
+ self.show()
+ self.__panel.ensureWidgetWisible(*args, **kwargs)
+ else:
+ self.__panel.toggleWidget(*args, **kwargs)
+
+ if not self.__panel.activeWidgetClasses:
+ self.hide()
+
+ def hide(self):
+ if self.__panel and self.active:
+ self.__panel.hide()
+ self.active = False
+
+ def show(self):
+ if self.__panel:
+ if not self.active:
+ self.__panel.show()
+ else:
+ self.forceLoadPanel()
+
+ self.active = True
+
+ def toggleVisibility(self):
+ if self.active:
+ self.hide()
+ else:
+ self.show()
+
+ def toggleTouchVisualization(self):
+ if self.__touchVisOverlay is None:
+ self.__touchVisOverlay = TouchVisOverlay(
+ isDebug=True,
+ visClass=DebugTouchVisualization,
+ size=self.parent.size,
+ parent=self.parent)
+ else:
+ self.__touchVisOverlay.unlink(True)
+ self.__touchVisOverlay = None
+
+ def forceLoadPanel(self):
+ if self.__panel is None:
+ self.__panel = _DebugPanel(parent=self, size=self.size,
+ fontsize=self.__fontsize)
+ for callable_ in self.__callables:
+ callable_()
+
+
+class _DebugPanel(avg.DivNode):
+
+ def __init__(self, parent=None, fontsize=10, **kwargs):
+ super(_DebugPanel, self).__init__(**kwargs)
+ self.registerInstance(self, parent)
+
+ self.__slots = []
+
+ self.maxSize = self.size
+ self.size = (self.size[0], 0)
+ self.activeWidgetClasses = []
+ self.__selectedWidget = None
+
+ global g_fontsize
+ g_fontsize = fontsize
+
+ self.show()
+
+ def show(self):
+ for widgetFrame in self.__slots:
+ if widgetFrame:
+ widgetFrame.show()
+ self.updateWidgets()
+
+ def hide(self):
+ for widget in self.__slots:
+ if widget:
+ widget.hide()
+
+ def ensureWidgetWisible(self, widgetClass, *args, **kwargs):
+ if not widgetClass in self.activeWidgetClasses:
+ self.toggleWidget(widgetClass, *args, **kwargs)
+
+ def toggleWidget(self, widgetClass, *args, **kwargs):
+ if widgetClass in self.activeWidgetClasses:
+ self._removeWidgetByClass(widgetClass)
+ else:
+ self.addWidget(widgetClass, *args, **kwargs)
+
+ def addWidget(self, widgetClass, *args, **kwargs):
+ if widgetClass in self.activeWidgetClasses:
+ libavg.logger.warning("You can't add the same widget twice")
+ return
+
+ widgetFrame = DebugWidgetFrame((max(0, self.width), DebugWidget.SLOT_HEIGHT),
+ widgetClass)
+ height = 0
+ for frame in self.__slots:
+ if frame:
+ height += frame.height
+ height += widgetFrame.height
+
+ if height > self.maxSize[1]:
+ libavg.logger.warning("No vertical space left. "
+ "Delete a widget and try again")
+ return False
+
+ self.appendChild(widgetFrame)
+
+ widgetPlaced = False
+ for idx, slot in enumerate(self.__slots):
+ if slot is None:
+ self.__slots[idx] = widgetFrame
+ widgetPlaced = True
+ break
+ if not widgetPlaced:
+ self.__slots.append(widgetFrame)
+ widgetFrame.subscribe(widgetFrame.FRAME_HEIGHT_CHANGED, self._heightChanged)
+
+ self.reorderWidgets()
+ widgetFrame.show()
+ self.updateWidgets()
+ self.activeWidgetClasses.append(widgetClass)
+
+ def _removeWidgetByClass(self, widgetClass):
+ for frame in self.__slots:
+ if frame and frame.widget.__class__ == widgetClass:
+ self.removeWidgetFrame(frame)
+ return
+
+ def _heightChanged(self):
+ height = 0
+ for childID in xrange(0, self.getNumChildren()):
+ child = self.getChild(childID)
+ height += child.height
+ self.height = height
+ self.reorderWidgets()
+
+ def updateWidgets(self):
+ for childID in xrange(0, self.getNumChildren()):
+ self.getChild(childID).widget.update()
+
+ def selectWidget(self, id):
+ id = id % self.getNumChildren()
+ for childID in xrange(0, self.getNumChildren()):
+ self.getChild(childID).unselect()
+ self.getChild(id).select()
+ self.__selectedWidget = id
+
+ def selectPreviousWidget(self):
+ if self.__selectedWidget is None:
+ self.selectWidget(-1)
+ else:
+ self.selectWidget(self.__selectedWidget - 1)
+
+ def selectNextWidget(self):
+ if self.__selectedWidget is None:
+ self.selectWidget(0)
+ else:
+ self.selectWidget(self.__selectedWidget + 1)
+
+ def removeWidgetFrame(self, widgetFrame):
+ self.activeWidgetClasses.remove(widgetFrame.widget.__class__)
+ for idx, slot in enumerate(self.__slots):
+ if slot == widgetFrame:
+ self.__slots[idx] = None
+ break
+ widgetFrame.widget.kill()
+ widgetFrame.unlink(True)
+ self.reorderWidgets()
+ self.updateWidgets()
+
+ def removeSelectedWidgetFrames(self):
+ candidates = []
+ for childID in xrange(0, self.getNumChildren()):
+ child = self.getChild(childID)
+ if child.isSelected():
+ candidates.append(child)
+ for widgetFrame in candidates:
+ self.removeWidgetFrame(widgetFrame)
+ self.__selectedWidget = None
+
+ def reorderWidgets(self):
+ #TODO: This is no layout management, yet
+ count = 0
+ height = 0
+ for idx, widgetFrame in enumerate(self.__slots):
+ if widgetFrame:
+ widgetFrame.pos = (0, height)
+ count += 1
+ height += widgetFrame.height
+ self.size = (self.maxSize[0], height)
diff --git a/src/python/app/flashmessage.py b/src/python/app/flashmessage.py
new file mode 100644
index 0000000..ebaab85
--- /dev/null
+++ b/src/python/app/flashmessage.py
@@ -0,0 +1,98 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+# libavg - Media Playback Engine.
+# Copyright (C) 2003-2014 Ulrich von Zadow
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Current versions can be found at www.libavg.de
+#
+# Original author of this file is OXullo Interecans <x at brainrapers dot org>
+
+
+'''
+Simple user notification API to report information to the user
+'''
+
+import libavg
+
+class FlashMessage(object):
+ DEFAULT_TIMEOUT = 3000
+ LINE_HEIGHT = 20
+ BORDER = 2
+
+ messages = []
+
+ @classmethod
+ def remove(cls, killedMessage):
+ cls.messages.remove(killedMessage)
+ for index, message in enumerate(cls.messages):
+ message.move(index)
+
+ def __init__(self, text, timeout=DEFAULT_TIMEOUT, parent=None, isError=False,
+ acknowledge=False):
+ FlashMessage.messages.append(self)
+
+ if parent is None:
+ parent = libavg.player.getRootNode()
+
+ if isError:
+ color = 'ff0000'
+ else:
+ color = 'ffffff'
+
+ rootNode = libavg.player.getRootNode()
+ self.__container = libavg.avg.DivNode(sensitive=acknowledge, parent=parent)
+ libavg.avg.RectNode(opacity=0, fillcolor='ffffff', fillopacity=1,
+ pos=(self.BORDER, self.BORDER),
+ size=(rootNode.size.x - self.BORDER * 2, self.LINE_HEIGHT - self.BORDER),
+ parent=self.__container)
+ libavg.avg.RectNode(opacity=0, fillcolor='000000', fillopacity=0.8,
+ pos=(self.BORDER, self.BORDER),
+ size=(rootNode.size.x - self.BORDER * 2, self.LINE_HEIGHT - self.BORDER),
+ parent=self.__container)
+ libavg.avg.WordsNode(text=text, fontsize=(self.LINE_HEIGHT - 3),
+ sensitive=False,
+ color=color,
+ pos=(self.BORDER, self.BORDER),
+ parent=self.__container)
+
+ self.move(len(FlashMessage.messages) - 1, animate=False)
+
+ if acknowledge:
+ self.__container.subscribe(self.__container.CURSOR_DOWN,
+ lambda e: self.__kill())
+ else:
+ libavg.player.setTimeout(timeout, self.__kill)
+
+ def move(self, index, animate=True):
+ finalPos = (self.BORDER, index * self.LINE_HEIGHT)
+
+ if animate:
+ libavg.avg.LinearAnim(self.__container, 'pos', duration=150,
+ startValue=self.__container.pos,
+ endValue=finalPos).start()
+ else:
+ self.__container.pos = finalPos
+
+ def __kill(self):
+ def finalizeRemoval():
+ self.__container.unlink(True)
+ self.__container = None
+ FlashMessage.remove(self)
+
+ libavg.avg.fadeOut(self.__container, 200, finalizeRemoval)
+
diff --git a/src/python/app/keyboardmanager.py b/src/python/app/keyboardmanager.py
new file mode 100644
index 0000000..accdf52
--- /dev/null
+++ b/src/python/app/keyboardmanager.py
@@ -0,0 +1,204 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+# libavg - Media Playback Engine.
+# Copyright (C) 2003-2014 Ulrich von Zadow
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Current versions can be found at www.libavg.de
+#
+# Original author of this file is OXullo Interecans <x at brainrapers dot org>
+
+
+from collections import namedtuple
+
+from libavg import avg, player
+
+IGNORED_KEYMODS = avg.KEYMOD_NUM
+KEYMOD_ANY = -1
+
+LOGCAT = avg.logger.configureCategory('KEYBOARDMANAGER',
+ avg.logger.Severity.WARN)
+
+class KeyboardManagerPublisher(avg.Publisher):
+ BINDINGS_UPDATED = avg.Publisher.genMessageID()
+ def __init__(self):
+ super(KeyboardManagerPublisher, self).__init__()
+ self.publish(self.BINDINGS_UPDATED)
+
+ def notifyUpdate(self):
+ self.notifySubscribers(self.BINDINGS_UPDATED, [])
+
+publisher = KeyboardManagerPublisher()
+
+_KeyBinding = namedtuple('_KeyBinding',
+ ['keystring', 'handler', 'help', 'modifiers', 'type'])
+
+
+_modifiedKeyBindings = []
+_plainKeyBindings = []
+_plainKeyBindingsStack = []
+_isEnabled = True
+
+
+def init():
+ player.subscribe(player.KEY_DOWN, _onKeyDown)
+ player.subscribe(player.KEY_UP, _onKeyUp)
+ avg.logger.debug('Keyboardmanager initialized', LOGCAT)
+
+def bindKeyDown(keystring, handler, help, modifiers=avg.KEYMOD_NONE):
+ _bindKey(keystring, handler, help, modifiers, avg.KEYDOWN)
+
+def bindKeyUp(keystring, handler, help, modifiers=avg.KEYMOD_NONE):
+ _bindKey(keystring, handler, help, modifiers, avg.KEYUP)
+
+def unbindKeyUp(keystring, modifiers=avg.KEYMOD_NONE):
+ _unbindKey(keystring, modifiers, avg.KEYUP)
+
+def unbindKeyDown(keystring, modifiers=avg.KEYMOD_NONE):
+ _unbindKey(keystring, modifiers, avg.KEYDOWN)
+
+def unbindAll():
+ global _modifiedKeyBindings, _plainKeyBindings, _plainKeyBindingsStack
+ _modifiedKeyBindings = []
+ _plainKeyBindings = []
+ _plainKeyBindingsStack = []
+ publisher.notifyUpdate()
+
+def push():
+ '''
+ Push the current non-modified defined key bindings to the stack
+ '''
+ global _plainKeyBindings
+ _plainKeyBindingsStack.append(_plainKeyBindings)
+ _plainKeyBindings = []
+ publisher.notifyUpdate()
+
+def pop():
+ '''
+ Pop from the stack the current non-modified defined key bindings
+ '''
+ global _plainKeyBindings
+ _plainKeyBindings = _plainKeyBindingsStack.pop()
+ publisher.notifyUpdate()
+
+def getCurrentBindings():
+ return _modifiedKeyBindings + _plainKeyBindings
+
+def enable():
+ global _isEnabled
+ _isEnabled = True
+
+def disable():
+ global _isEnabled
+ _isEnabled = False
+
+def _bindKey(keystring, handler, help, modifiers, type_):
+ if type(keystring) == unicode:
+ keystring = keystring.encode('utf8')
+
+ avg.logger.info('Binding key <%s> (mod:%s) to handler %s (%s)' % (keystring,
+ modifiers, handler, type), LOGCAT)
+ _checkDuplicates(keystring, modifiers, type_)
+ keyBinding = _KeyBinding(keystring, handler, help, modifiers, type_)
+
+ if modifiers != avg.KEYMOD_NONE:
+ _modifiedKeyBindings.append(keyBinding)
+ else:
+ _plainKeyBindings.append(keyBinding)
+
+ publisher.notifyUpdate()
+
+def _findAndRemoveKeybinding(keystring, modifiers, type, list):
+ for keybinding in list:
+ if keybinding.keystring == keystring and \
+ keybinding.modifiers == modifiers and \
+ keybinding.type == type:
+ list.remove(keybinding)
+ break;
+
+def _unbindKey(keystring, modifiers, type_):
+ if type(keystring) == unicode:
+ keystring = keystring.encode('utf8')
+
+ avg.logger.info('Unbinding key <%s> (mod:%s) (%s)' % (keystring,
+ modifiers, type), LOGCAT)
+ if modifiers != avg.KEYMOD_NONE:
+ _findAndRemoveKeybinding(keystring, modifiers, type_, _modifiedKeyBindings)
+ else:
+ _findAndRemoveKeybinding(keystring, modifiers, type_, _plainKeyBindings)
+
+ publisher.notifyUpdate()
+
+def _onKeyDown(event):
+ if _isEnabled:
+ _processEvent(event, avg.KEYDOWN)
+
+def _onKeyUp(event):
+ if _isEnabled:
+ _processEvent(event, avg.KEYUP)
+
+def _testModifiers(mod1, mod2):
+ if mod1 == KEYMOD_ANY or mod2 == KEYMOD_ANY:
+ return True
+
+ mod1 &= ~IGNORED_KEYMODS
+ mod2 &= ~IGNORED_KEYMODS
+ return mod1 == mod2 or mod1 & mod2
+
+def _testPatternMatch(pattern, text):
+ if pattern in ('shift', 'alt', 'ctrl', 'meta', 'super'):
+ return pattern in text
+ else:
+ return False
+
+def _testMatchString(keyBinding, keyString, type_):
+ sameType = keyBinding.type == type_
+ patternMatch = _testPatternMatch(keyBinding.keystring, keyString)
+ directMatch = keyBinding.keystring == keyString
+
+ return sameType and (directMatch or patternMatch)
+
+def _testMatchEvent(keyBinding, event, type_):
+ if not _testModifiers(event.modifiers, keyBinding.modifiers):
+ return False
+
+ if _testMatchString(keyBinding, event.keystring, type_):
+ return True
+
+ if type_ == avg.KEYDOWN:
+ return _testMatchString(keyBinding,
+ unichr(event.unicode).encode('utf8'), type_)
+ else:
+ return False
+
+def _processEvent(event, type_):
+ avg.logger.debug('Processing event keystring=%s '
+ 'modifiers=%s type=%s' % (event.keystring, event.modifiers, event.type),
+ LOGCAT)
+ for keyBinding in _plainKeyBindings + _modifiedKeyBindings:
+ if _testMatchEvent(keyBinding, event, type_):
+ avg.logger.debug(' Found keyBinding=%s' % (keyBinding,), LOGCAT)
+ keyBinding.handler()
+ return
+
+def _checkDuplicates(keystring, modifiers, type_):
+ for keyBinding in _plainKeyBindings + _modifiedKeyBindings:
+ if (_testModifiers(keyBinding.modifiers, modifiers) and
+ _testMatchString(keyBinding, keystring, type_)):
+ raise RuntimeError('Key binding keystring=%s modifiers=%s type=%s '
+ 'already defined' % (keystring, modifiers, type_))
+
diff --git a/src/python/app/settings.py b/src/python/app/settings.py
new file mode 100644
index 0000000..a25eece
--- /dev/null
+++ b/src/python/app/settings.py
@@ -0,0 +1,277 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+# libavg - Media Playback Engine.
+# Copyright (C) 2003-2014 Ulrich von Zadow
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Current versions can be found at www.libavg.de
+#
+# Original author of this file is OXullo Interecans <x at brainrapers dot org>
+
+
+import sys
+import re
+import optparse
+
+import libavg
+
+
+class Option(object):
+ def __init__(self, key, value, help=None):
+ if not isinstance(key, str):
+ raise ValueError('The type of %s key is not string (value=%s)' % (key, value))
+
+ self.__key = key
+ self.value = value
+ self.__help = help
+
+ def __repr__(self):
+ return '<%s key=%s value=%s help=%s>' % (self.__class__.__name__,
+ self.key, self.value, self.help)
+
+ @property
+ def key(self):
+ return self.__key
+
+ @property
+ def value(self):
+ return self.__value
+
+ @value.setter
+ def value(self, value):
+ if not isinstance(value, str):
+ raise ValueError('The type of %s value (%s) '
+ 'must be string instead of %s' % (self.__key, value, type(value)))
+
+ self.__value = value
+
+ @property
+ def group(self):
+ components = self.__getComponents()
+ if len(components) == 1:
+ return 'DEFAULT'
+ else:
+ return components[0]
+
+ @property
+ def tail(self):
+ components = self.__getComponents()
+ if len(components) == 1:
+ return self.key
+ else:
+ return components[1]
+
+ @property
+ def help(self):
+ return self.__help
+
+ def __getComponents(self):
+ return self.key.split('_', 1)
+
+
+class KargsExtender(object):
+ def __init__(self, optionsKargs):
+ self.__optionsKargs = optionsKargs
+
+ def __call__(self, optionsList):
+ optionsKeyset = set([option.key for option in optionsList])
+ kaKeyset = set(self.__optionsKargs.keys())
+
+ if not optionsKeyset.issuperset(kaKeyset):
+ raise RuntimeError('No such option/s: %s' % list(kaKeyset - optionsKeyset))
+
+ for option in optionsList:
+ if option.key in self.__optionsKargs:
+ option.value = self.__optionsKargs[option.key]
+
+ return optionsList
+
+
+class HelpPrintingOptionParser(optparse.OptionParser):
+ def error(self, *args, **kargs):
+ self.print_help()
+ optparse.OptionParser.error(self, *args, **kargs)
+
+
+class ArgvExtender(object):
+ def __init__(self, appVersionInfo, args=None):
+ self.__appVersionInfo = appVersionInfo
+ self.__parser = HelpPrintingOptionParser()
+ self.__args = args
+ self.__parsedArgs = None
+
+ def __call__(self, optionsList):
+ self.__parser.add_option('-v', '--version', dest='version', action='store_true',
+ help='print libavg and application version information')
+
+ groups = self.__groupOptionsKeys(optionsList)
+
+ for group in sorted(groups):
+ parserGroup = optparse.OptionGroup(self.__parser,
+ '%s section' % group.title())
+
+ keys = sorted(groups[group])
+
+ for option in [option for option in optionsList if option.key in keys]:
+ cliKey = '--%s' % option.key.replace('_', '-').lower()
+ currentValue = option.value if option.value else '<undefined>'
+
+ help = '[Default: %s]' % currentValue
+
+ if option.help:
+ help = '%s %s' % (option.help, help)
+
+ parserGroup.add_option(cliKey, help=help)
+
+ self.__parser.add_option_group(parserGroup)
+
+ if self.__args is None:
+ self.__args = sys.argv[1:]
+
+ self.__parsedArgs = self.__parser.parse_args(args=self.__args)
+
+ parsedOptions = self.__parsedArgs[0]
+
+ if parsedOptions.version:
+ print 'libavg'
+ vi = libavg.VersionInfo()
+ print ' version : %s' % vi.full
+ print ' builder : %s (%s)' % (vi.builder, vi.buildtime)
+ print ' branchurl: %s' % vi.branchurl
+ print
+ print 'application'
+ print ' version: %s' % self.__appVersionInfo
+ sys.exit(0)
+
+ for key, value in parsedOptions.__dict__.iteritems():
+ if value is not None:
+ for option in optionsList:
+ if option.key == key:
+ option.value = value
+
+ return optionsList
+
+ @property
+ def parsedArgs(self):
+ if self.__parsedArgs is None:
+ raise RuntimeError('Cannot provide parsedArgs before applying the extender')
+
+ return self.__parsedArgs
+
+ @property
+ def parser(self):
+ return self.__parser
+
+ def __groupOptionsKeys(self, optionsList):
+ groups = {}
+ for option in optionsList:
+ if not option.group in groups:
+ groups[option.group] = []
+
+ groups[option.group].append(option.key)
+
+ return groups
+
+
+class Settings(object):
+ def __init__(self, defaults=[]):
+ if (type(defaults) not in (tuple, list) or
+ not all([isinstance(opt, Option) for opt in defaults])):
+ raise ValueError('Settings must be initialized with a list '
+ 'of Option instances')
+
+ self.__options = []
+
+ for option in defaults:
+ self.addOption(option)
+
+ def __iter__(self):
+ return self.__options.__iter__()
+
+ def applyExtender(self, extender):
+ self.__options = extender(self.__options)
+
+ def hasOption(self, key):
+ return self.__getOptionOrNone(key) is not None
+
+ def getOption(self, key):
+ option = self.__getOptionOrNone(key)
+
+ if option is None:
+ raise RuntimeError('Cannot find key %s in the settings' % key)
+
+ return option
+
+ def get(self, key, convertFunc=lambda v: v):
+ option = self.getOption(key)
+
+ try:
+ return convertFunc(option.value)
+ except (TypeError, ValueError), e:
+ raise ValueError('%s (option=%s)' % (e, option))
+
+ def getJson(self, key):
+ import json
+
+ return self.get(key, json.loads)
+
+ def getPoint2D(self, key):
+ value = self.get(key)
+ maybeTuple = re.split(r'\s*[,xX]\s*', value)
+
+ if len(maybeTuple) != 2:
+ raise ValueError('Cannot convert key %s value %s to Point2D' % (key, value))
+
+ return libavg.Point2D(map(float, maybeTuple))
+
+ def getInt(self, key):
+ return self.get(key, int)
+
+ def getFloat(self, key):
+ return self.get(key, float)
+
+ def getBoolean(self, key):
+ value = self.get(key).lower()
+
+ if value in ('yes', 'true'):
+ return True
+ elif value in ('no', 'false'):
+ return False
+ else:
+ raise ValueError('Cannot convert %s to boolean' % value)
+
+ def set(self, key, value):
+ option = self.getOption(key)
+ option.value = value
+
+ def addOption(self, option):
+ if not isinstance(option, Option):
+ raise TypeError('Must be an instance of Option')
+
+ if self.__getOptionOrNone(option.key):
+ raise RuntimeError('Option %s has been already defined' % option.key)
+
+ self.__options.append(option)
+
+ def __getOptionOrNone(self, key):
+ for option in self.__options:
+ if option.key == key:
+ return option
+
+ return None
+
+
diff --git a/src/python/app/touchvisualization.py b/src/python/app/touchvisualization.py
new file mode 100644
index 0000000..7953b02
--- /dev/null
+++ b/src/python/app/touchvisualization.py
@@ -0,0 +1,188 @@
+# libavg - Media Playback Engine.
+# Copyright (C) 2003-2014 Ulrich von Zadow
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Current versions can be found at www.libavg.de
+#
+
+import os
+
+from libavg import avg, player
+
+
+class BaseTouchVisualization(avg.DivNode):
+
+ def __init__(self, event, parent=None, **kwargs):
+ avg.DivNode.__init__(self, **kwargs)
+ self.registerInstance(self, parent)
+
+ event.contact.subscribe(avg.Contact.CURSOR_MOTION, self._onMotion)
+ event.contact.subscribe(avg.Contact.CURSOR_UP, self._onUp)
+ self.pos = avg.Point2D(event.pos)
+ self._fingerSize = 7*player.getPixelsPerMM() # Assume 14mm width for a finger.
+ self._radius = self._getRadius(event)
+
+ def _abort(self):
+ self.unlink(True)
+ del self
+
+ def _onMotion(self, event):
+ self.pos = event.pos
+ self._radius = self._getRadius(event)
+
+ def _onUp(self, event):
+ self.unlink(True)
+ del self
+
+ def _getRadius(self, event):
+ if event.source in [avg.Event.MOUSE]:
+ return self._fingerSize
+ else:
+ return max(self._fingerSize, event.majoraxis.getNorm())
+
+
+
+class DebugTouchVisualization(BaseTouchVisualization):
+
+ def __init__(self, event, **kwargs):
+ BaseTouchVisualization.__init__(self, event, **kwargs)
+ self.positions = [event.pos]
+
+ if event.source == avg.Event.TOUCH:
+ color = 'e5d8d8'
+ else:
+ color = 'd8e5e5'
+ self.opacity = 0.5
+
+ self.__transparentCircle = avg.CircleNode(r=self._radius+20, fillcolor=color,
+ fillopacity=0.2, opacity=0.0, strokewidth=1, sensitive=False, parent=self)
+ self.__pulsecircle = avg.CircleNode(r=self._radius, fillcolor=color, color=color,
+ fillopacity=0.5, opacity=0.5, strokewidth=1,
+ sensitive=False, parent=self)
+ if event.source in [avg.Event.TOUCH, avg.Event.TRACK]:
+ self.__majorAxis = avg.LineNode(pos1=(0,0), pos2=event.majoraxis,
+ color='FFFFFF', sensitive=False, parent=self)
+ self.__minorAxis = avg.LineNode(pos1=(0,0), pos2=event.minoraxis,
+ color='FFFFFF', sensitive=False, parent=self)
+ if event.source == avg.Event.TOUCH:
+ self.__handAxis = avg.LineNode(pos1=(0,0), pos2=self.__getHandVector(event),
+ opacity=0.5, color='A0FFA0', sensitive=False, parent=self)
+ fontPos = avg.Point2D(self.__pulsecircle.r, 0)
+
+ if event.cursorid == -1:
+ text = 'MOUSE'
+ else:
+ text = '%s %d' % (event.source, event.cursorid)
+ avg.WordsNode(pos=fontPos, text=text, fontsize=9, parent=self)
+ self.motionPath = avg.PolyLineNode(pos=self.positions,
+ opacity=0.7, color=color, parent=kwargs['parent'])
+ self.motionVector = avg.LineNode(pos1=(0,0) , pos2=-event.contact.motionvec,
+ opacity=0.4, parent=self)
+ pulseCircleAnim = avg.LinearAnim(self.__pulsecircle, 'r', 200, 50, self._radius)
+ pulseCircleAnim.start()
+
+ def unlink(self, kill=True):
+ if self.motionPath:
+ self.motionPath.unlink(True)
+ super(DebugTouchVisualization, self).unlink(kill)
+
+ def _onMotion(self, event):
+ BaseTouchVisualization._onMotion(self, event)
+ self.positions.append(event.pos)
+ if len(self.positions) > 100:
+ self.positions.pop(0)
+
+ self.__pulsecircle.r = self._radius
+ self.setAxisSecondPos(event)
+ self.motionVector.pos2 = -event.contact.motionvec
+ if event.source == avg.Event.TOUCH:
+ self.__handAxis.pos2 = self.__getHandVector(event)
+ self.motionPath.pos = self.positions
+
+ def __getHandVector(self, event):
+ return -avg.Point2D.fromPolar(event.handorientation, 30)
+
+ def setAxisSecondPos(self, event):
+ if event.source not in [avg.Event.MOUSE]:
+ self.__majorAxis.pos2 = event.majoraxis
+ self.__minorAxis.pos2 = event.minoraxis
+
+
+class TouchVisualization(BaseTouchVisualization):
+
+ mediadir = os.path.join(os.path.dirname(__file__), os.path.pardir, 'data')
+ sources = [avg.Event.TOUCH]
+ bmp = avg.Bitmap(mediadir+"/TouchFeedback.png")
+
+ def __init__(self, event, **kwargs):
+ BaseTouchVisualization.__init__(self, event, **kwargs)
+
+ if event.source in self.sources:
+ self.__circle = avg.ImageNode(parent=self)
+ self.__circle.setBitmap(self.bmp)
+ self.__setRadius(self._radius)
+ avg.LinearAnim(self.__circle, "opacity", 200, 0.7, 0.4).start()
+ else:
+ self.unlink(True)
+ self._abort()
+
+ def _onMotion(self, event):
+ BaseTouchVisualization._onMotion(self, event)
+ self.__setRadius(self._radius)
+
+ def _onUp(self, event):
+
+ def gone(self):
+ BaseTouchVisualization._onUp(self, event)
+ self.unlink(True)
+ del self
+
+ avg.fadeIn(self.__circle, 100, 1)
+ avg.LinearAnim(self.__circle, "size", 100, self.__circle.size, (4,4)).start()
+ avg.LinearAnim(self.__circle, "pos", 100, self.__circle.pos, (-2,-2)).start()
+ player.setTimeout(100, lambda: gone(self))
+
+ def __setRadius(self, radius):
+ self.__circle.pos = (-radius, -radius)
+ self.__circle.size = (radius*2,radius*2)
+
+
+class TouchVisualizationOverlay(avg.DivNode):
+ def __init__(self, isDebug, visClass, rootNode=None, parent=None,
+ **kwargs):
+ super(TouchVisualizationOverlay, self).__init__(**kwargs)
+ self.registerInstance(self, parent)
+
+ self.sensitive = False
+ self.visClass = visClass
+ if rootNode is None:
+ rootNode = player.getRootNode()
+
+ if isDebug:
+ self.elementoutlinecolor='FFFFAA'
+ avg.RectNode(parent=self, size=self.size, fillopacity=0.2, fillcolor='000000')
+ rootNode.subscribe(avg.Node.CURSOR_DOWN, self.__onTouchDown)
+ rootNode.subscribe(avg.Node.HOVER_DOWN, self.__onTouchDown)
+
+ def unlink(self, kill=True):
+ rootNode = player.getRootNode()
+ if rootNode:
+ rootNode.unsubscribe(avg.Node.CURSOR_DOWN, self.__onTouchDown)
+ rootNode.unsubscribe(avg.Node.HOVER_DOWN, self.__onTouchDown)
+ super(TouchVisualizationOverlay, self).unlink(kill)
+
+ def __onTouchDown(self, event):
+ self.visClass(event, parent=self)
diff --git a/src/python/apphelpers.py b/src/python/apphelpers.py
new file mode 100644
index 0000000..b23b69c
--- /dev/null
+++ b/src/python/apphelpers.py
@@ -0,0 +1,235 @@
+# libavg - Media Playback Engine.
+# Copyright (C) 2003-2014 Ulrich von Zadow
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Current versions can be found at www.libavg.de
+#
+
+import os
+
+from libavg import avg, player
+
+from app.touchvisualization import *
+
+
+class KeysCaptionNode(avg.DivNode):
+ def __init__(self, parent=None, **kwargs):
+ super(KeysCaptionNode, self).__init__(**kwargs)
+ self.registerInstance(self, parent)
+
+ self.sensitive = False
+ self.opacity = 0
+
+ self.__background = avg.RectNode(fillcolor='000000', fillopacity=0.6,
+ opacity=0, size=(450, 450), parent=self)
+
+ self.__keysNode = avg.WordsNode(pos=(10, 10), fontsize=18,
+ color='DDDDDD', parent=self)
+
+ self.__isShown = False
+
+ def toggleHelp(self):
+ self.__isShown = not self.__isShown
+
+ keys = g_KbManager.getActiveKeyBindings()
+
+ if self.__isShown:
+ helpText = '<span><b> ACTIVE KEYS </b><br/></span>'
+
+ for keyObj in sorted(keys, key=lambda ko: ko.key):
+ if keyObj.state == 'up':
+ stateAddition = ' (up)'
+ else:
+ stateAddition = ''
+
+ helpText += ('<span><b>%s</b> '
+ '<small>%s%s</small></span><br/>' % (keyObj.key,
+ keyObj.description, stateAddition))
+
+ self.__keysNode.text = helpText
+ self.opacity = 1
+ self.__background.size = self.__keysNode.getMediaSize()
+
+ self.getParent().reorderChild(
+ self.getParent().indexOf(self),
+ self.getParent().getNumChildren()-1)
+ else:
+ self.__keysNode.text = ''
+ self.opacity = 0
+
+
+class KeyBinding(object):
+ def __init__(self, key, description, state, callback):
+ if not isinstance(key, unicode) and not isinstance(key, str):
+ raise TypeError('KeyBinding key should be either a string or unicode object')
+
+ self.__key = key
+ self.__description = description
+ self.__state = state
+ self.__callback = callback
+
+ def __repr__(self):
+ return '<%s key=%s (%s) state=%s>' % (self.__class__.__name__,
+ self.__key, self.__description, self.__state)
+
+ @property
+ def key(self):
+ return self.__key
+
+ @property
+ def description(self):
+ return self.__description
+
+ @property
+ def state(self):
+ return self.__state
+
+ def checkKey(self, key, state):
+ if state is not None and self.__state != state:
+ return False
+
+ return self.__key == key
+
+ def checkEvent(self, event, state):
+ if self.__state != state:
+ return False
+
+ if isinstance(self.__key, unicode):
+ return self.__key == unichr(event.unicode)
+ else:
+ return self.__key == event.keystring
+
+ def executeCallback(self):
+ self.__callback()
+
+
+class KeyboardManager(object):
+ _instance = None
+ TOGGLE_HELP_UNICODE = 63
+
+ def __init__(self):
+ if self._instance is not None:
+ raise RuntimeError('KeyboardManager has been already instantiated')
+
+ self.__keyBindings = []
+ self.__keyBindingsStack = []
+
+ self.__onKeyDownCb = lambda e: False
+ self.__onKeyUpCb = lambda e: False
+
+ self.__keyCaptionsNode = None
+
+ KeyboardManager._instance = self
+
+ @classmethod
+ def get(cls):
+ if cls._instance is None:
+ cls()
+
+ return cls._instance
+
+ def setup(self, onKeyDownCb, onKeyUpCb):
+ player.subscribe(avg.Player.KEY_DOWN, self.__onKeyDown)
+ player.subscribe(avg.Player.KEY_UP, self.__onKeyUp)
+
+ self.__onKeyDownCb = onKeyDownCb
+ self.__onKeyUpCb = onKeyUpCb
+
+ self.__keyCaptionsNode = KeysCaptionNode(pos=(5,5), parent=player.getRootNode())
+
+ def teardown(self):
+ self.__keyBindings = []
+
+ self.__keyCaptionsNode.unlink(True)
+ del self.__keyCaptionsNode
+ self.__keyCaptionsNode = None
+
+ def push(self):
+ self.__keyBindingsStack.append(self.__keyBindings)
+ self.__keyBindings = []
+
+ def pop(self):
+ if not self.__keyBindingsStack:
+ raise RuntimeError('Empty stack')
+
+ self.__keyBindings = self.__keyBindingsStack.pop()
+
+ def getActiveKeyBindings(self):
+ return self.__keyBindings
+
+ def bindKey(self, key, func, funcName, state='down'):
+ import warnings
+ warnings.warn('libavg.KeyboardManager is deprecated, use '
+ 'libavg.app.keyboardmanager instead')
+
+ if isinstance(key, unicode) and state != 'down':
+ raise RuntimeError('bindKey() with unicode keys '
+ 'can be used only with state=down')
+
+ if key == unichr(self.TOGGLE_HELP_UNICODE):
+ raise RuntimeError('%s key is reserved')
+
+ keyObj = self.__findKeyByKeystring(key, state)
+ if keyObj is not None:
+ raise RuntimeError('Key %s has already been bound (%s)' % (key, keyObj))
+
+ self.__keyBindings.append(KeyBinding(key, funcName, state, func))
+
+ def unbindKey(self, key):
+ keyObj = self.__findKeyByKeystring(key)
+
+ if keyObj is not None:
+ self.__keyBindings.remove(keyObj)
+ else:
+ raise KeyError('Key %s not found' % key)
+
+ def bindUnicode(self, key, func, funcName, state='down'):
+ raise DeprecationWarning('Use bindKey() passing an unicode object as keystring')
+
+ def __findKeyByEvent(self, event, state):
+ for keyObj in self.__keyBindings:
+ if keyObj.checkEvent(event, state):
+ return keyObj
+
+ return None
+
+ def __findKeyByKeystring(self, key, state=None):
+ for keyObj in self.__keyBindings:
+ if keyObj.checkKey(key, state):
+ return keyObj
+
+ return None
+
+ def __onKeyDown(self, event):
+ if self.__onKeyDownCb(event):
+ return
+ elif event.unicode == self.TOGGLE_HELP_UNICODE:
+ self.__keyCaptionsNode.toggleHelp()
+ else:
+ keyObj = self.__findKeyByEvent(event, 'down')
+ if keyObj is not None:
+ keyObj.executeCallback()
+
+ def __onKeyUp(self, event):
+ if self.__onKeyUpCb(event):
+ return
+ else:
+ keyObj = self.__findKeyByEvent(event, 'up')
+ if keyObj is not None:
+ keyObj.executeCallback()
+
+
+g_KbManager = KeyboardManager.get()
diff --git a/src/python/appstarter.py b/src/python/appstarter.py
new file mode 100644
index 0000000..aca4fe0
--- /dev/null
+++ b/src/python/appstarter.py
@@ -0,0 +1,396 @@
+# libavg - Media Playback Engine.
+# Copyright (C) 2003-2014 Ulrich von Zadow
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Current versions can be found at www.libavg.de
+#
+# Original author of this file is Martin Heistermann <mh at sponc dot de>
+#
+
+import os
+import gc
+import math
+
+from libavg import avg, Point2D, player
+import graph
+from mtemu import MTemu
+import apphelpers
+
+
+DEFAULT_RESOLUTION = (640, 480)
+
+g_KbManager = apphelpers.KeyboardManager.get()
+
+
+class AppStarter(object):
+ '''Starts an AVGApp'''
+ def __init__(self, appClass, resolution=DEFAULT_RESOLUTION,
+ debugWindowSize=None, fakeFullscreen=False):
+
+ resolution = Point2D(resolution)
+ testMode = not 'AVG_DEPLOY' in os.environ
+
+ if testMode and debugWindowSize is not None:
+ debugWindowSize = Point2D(debugWindowSize)
+ else:
+ debugWindowSize = Point2D(0, 0)
+
+ if fakeFullscreen:
+ if os.name != 'nt':
+ raise RuntimeError('Fakefullscreen is supported only on windows')
+ elif not testMode:
+ self.__enableFakeFullscreen()
+
+ fullscreen = False
+ else:
+ fullscreen = not testMode
+
+ player.enableMouse(not 'AVG_DISABLE_MOUSE' in os.environ)
+ player.showCursor(testMode)
+ self._setupBaseDivs(resolution)
+
+ player.setResolution(
+ fullscreen,
+ int(debugWindowSize.x), int(debugWindowSize.y),
+ 0 # color depth
+ )
+
+ self._startApp(appClass)
+
+ def _startApp(self, appClass):
+ self._onBeforePlay()
+ player.setTimeout(0, self._onStart)
+ self._appInstance = appClass(self._appNode)
+ g_KbManager.setup(
+ self._appInstance.onKeyDown,
+ self._appInstance.onKeyUp)
+
+ self._setupDefaultKeys()
+
+ self._appInstance.setStarter(self)
+ player.play()
+ self._appInstance.exit()
+ g_KbManager.teardown()
+
+ def _setupBaseDivs(self, resolution):
+ player.loadString('''
+<?xml version="1.0"?>
+<!DOCTYPE avg SYSTEM "../../libavg/doc/avg.dtd">
+<avg width="%s" height="%s">
+</avg>''' % (resolution.x, resolution.y))
+
+ rootNode = player.getRootNode()
+ self._appNode = avg.DivNode(opacity=0, sensitive=False,
+ size=rootNode.size, parent=rootNode)
+
+ def _setupDefaultKeys(self):
+ pass
+
+ def _onBeforePlay(self):
+ pass
+
+ def _onStart(self):
+ self._appInstance.init()
+ self._appNode.opacity = 1
+ self._appNode.sensitive = True
+ self._activeApp = self._appInstance
+ self._appInstance.enter()
+
+ def __enableFakeFullscreen(self):
+ player.setWindowPos(0, 0)
+ player.setWindowFrame(False)
+
+
+class AVGAppStarter(AppStarter):
+ def __init__(self, *args, **kwargs):
+ self.__graphs = []
+ self._mtEmu = None
+ self.__memGraph = None
+ self.__vidMemGraph = None
+ self.__frGraph = None
+ self.__notifyNode = None
+ self.__debugTouchVisOverlay = None
+
+ super(AVGAppStarter, self).__init__(*args, **kwargs)
+
+ def _setupDefaultKeys(self):
+ super(AVGAppStarter, self)._setupDefaultKeys()
+ g_KbManager.bindKey('o', self.__dumpObjects, 'Dump objects')
+ g_KbManager.bindKey('m', self.showMemoryUsage, 'Show memory usage graph')
+
+ g_KbManager.bindKey('f', self.showFrameRate, 'Show framerate graph')
+ g_KbManager.bindKey('t', self.__switchMtemu, 'Activate multitouch emulation')
+ g_KbManager.bindKey('e', self.__switchShowMTEvents, 'Show multitouch events')
+ g_KbManager.bindKey('s', self.__screenshot, 'Take screenshot')
+
+ def _onStart(self):
+ try:
+ player.getVideoMemUsed()
+ g_KbManager.bindKey('v', self.showVideoMemoryUsage,
+ 'Show video memory usage graph')
+ except RuntimeError:
+ # Video memory query not supported.
+ pass
+
+ AppStarter._onStart(self)
+
+ def __dumpObjects(self):
+ gc.collect()
+ testHelper = player.getTestHelper()
+ testHelper.dumpObjects()
+ print 'Num anims: ', avg.getNumRunningAnims()
+ print 'Num python objects: ', len(gc.get_objects())
+
+ def showMemoryUsage(self):
+ if self.__memGraph:
+ self.__memGraph.unlink(True)
+ self.__graphs.remove(self.__memGraph)
+ self.__memGraph = None
+ else:
+ size = (self._appNode.width, self._appNode.height/6.0)
+ self.__memGraph = graph.AveragingGraph(title = 'Memory Usage',
+ getValue = avg.getMemoryUsage, parent=player.getRootNode(), size=size)
+ self.__graphs.append(self.__memGraph)
+ self.__positionGraphs()
+
+ def showVideoMemoryUsage(self):
+ if self.__vidMemGraph:
+ self.__vidMemGraph.unlink(True)
+ self.__graphs.remove(self.__vidMemGraph)
+ self.__vidMemGraph = None
+ else:
+ size = (self._appNode.width, self._appNode.height/6.0)
+ self.__vidMemGraph = graph.AveragingGraph(title='Video Memory Usage',
+ getValue=player.getVideoMemUsed, parent=player.getRootNode(),
+ size=size)
+ self.__graphs.append(self.__vidMemGraph)
+ self.__positionGraphs()
+
+ def showFrameRate(self):
+ if self.__frGraph:
+ self.__frGraph.unlink(True)
+ self.__graphs.remove(self.__frGraph)
+ self.__frGraph = None
+ else:
+ size = (self._appNode.width, self._appNode.height/6.0)
+ self.__frGraph = graph.SlidingGraph(title = 'Time per Frame',
+ getValue = player.getFrameTime, parent = self._appNode, size=size)
+ self.__graphs.append(self.__frGraph)
+ self.__positionGraphs()
+
+ def __positionGraphs(self):
+ ypos = 10
+ for gr in self.__graphs:
+ gr.y = ypos
+ ypos += gr.height + 10
+
+ def __switchMtemu(self):
+ if self._mtEmu is None:
+ self._mtEmu = MTemu()
+ g_KbManager.bindKey('left shift', self._mtEmu.toggleDualTouch,
+ 'Toggle Multitouch Emulation')
+ g_KbManager.bindKey('right shift', self._mtEmu.toggleDualTouch,
+ 'Toggle Multitouch Emulation')
+ g_KbManager.bindKey('left ctrl', self._mtEmu.toggleSource,
+ 'Toggle Touch Source')
+ g_KbManager.bindKey('right ctrl', self._mtEmu.toggleSource,
+ 'Toggle Touch Source')
+ else:
+ self._mtEmu.deinit()
+ g_KbManager.unbindKey('left ctrl')
+ g_KbManager.unbindKey('right ctrl')
+ g_KbManager.unbindKey('left shift')
+ g_KbManager.unbindKey('right shift')
+
+ del self._mtEmu
+ self._mtEmu = None
+
+ def __switchShowMTEvents(self):
+ if self.__debugTouchVisOverlay is None:
+ rootNode = player.getRootNode()
+ self.__debugTouchVisOverlay = apphelpers.TouchVisualizationOverlay(
+ isDebug=True, visClass=apphelpers.DebugTouchVisualization,
+ size=self._appNode.size, parent=rootNode)
+ else:
+ self.__debugTouchVisOverlay.unlink(True)
+ del self.__debugTouchVisOverlay
+ self.__debugTouchVisOverlay = None
+
+ def __killNotifyNode(self):
+ if self.__notifyNode:
+ self.__notifyNode.unlink()
+ self.__notifyNode = None
+
+ def __screenshot(self):
+ fnum = 0
+ fnameTemplate = 'screenshot-%03d.png'
+ while os.path.exists(fnameTemplate % fnum):
+ fnum += 1
+
+ try:
+ player.screenshot().save('screenshot-%03d.png' % fnum)
+ except RuntimeError:
+ text = 'Cannot save snapshot file'
+ else:
+ text = 'Screenshot saved as ' + fnameTemplate % fnum
+
+ self.__killNotifyNode()
+
+ self.__notifyNode = avg.WordsNode(
+ text=text, x=player.getRootNode().width - 50,
+ y=player.getRootNode().height - 50, alignment='right', fontsize=20,
+ sensitive=False, parent=player.getRootNode())
+
+ player.setTimeout(2000, self.__killNotifyNode)
+
+
+class AVGMTAppStarter(AVGAppStarter):
+
+ def __init__(self, *args, **kwargs):
+ self.__touchVisOverlay = None
+ super(AVGMTAppStarter, self).__init__(*args, **kwargs)
+
+ def setTouchVisualization(self, visClass):
+ if not(self.__touchVisOverlay is None):
+ self.__touchVisOverlay.unlink(True)
+ del self.__touchVisOverlay
+ self.__touchVisOverlay = None
+ if not(visClass is None):
+ rootNode = player.getRootNode()
+ self.__touchVisOverlay = apphelpers.TouchVisualizationOverlay(
+ isDebug=False, visClass=visClass, size=self._appNode.size,
+ parent=rootNode)
+
+ def toggleTrackerImage(self):
+ if self.__showTrackerImage:
+ self.hideTrackerImage()
+ else:
+ self.showTrackerImage()
+
+ def showTrackerImage(self):
+ if self.__showTrackerImage:
+ return
+ self.__showTrackerImage = True
+ self.__updateTrackerImageInterval = \
+ player.subscribe(player.ON_FRAME, self.__updateTrackerImage)
+ self.__trackerImageNode.opacity = 1
+ self.tracker.setDebugImages(False, True)
+
+ def hideTrackerImage(self):
+ if not self.__showTrackerImage:
+ return
+ self.__showTrackerImage = False
+ if self.__updateTrackerImageInterval:
+ player.clearInterval(self.__updateTrackerImageInterval)
+ self.__updateTrackerImageInterval = None
+ self.__trackerImageNode.opacity = 0
+ self.tracker.setDebugImages(False, False)
+
+ def __updateTrackerImage(self):
+ def transformPos((x,y)):
+ if self.trackerFlipX:
+ x = 1 - x
+ if self.trackerFlipY:
+ y = 1 - y
+ return (x, y)
+
+ fingerBitmap = self.tracker.getImage(avg.IMG_FINGERS)
+ node = self.__trackerImageNode
+ node.setBitmap(fingerBitmap)
+ node.pos = self.tracker.getDisplayROIPos()
+ node.size = self.tracker.getDisplayROISize()
+
+ grid = node.getOrigVertexCoords()
+ grid = [ [ transformPos(pos) for pos in line ] for line in grid]
+ node.setWarpedVertexCoords(grid)
+
+ def _onStart(self):
+ from camcalibrator import Calibrator
+
+ # we must add the tracker first, calibrator depends on it
+ try:
+ player.enableMultitouch()
+ except RuntimeError, err:
+ avg.logger.warning(str(err))
+
+ self.tracker = player.getTracker()
+
+ if self.tracker:
+ if Calibrator:
+ self.__calibratorNode = player.createNode('div',{
+ 'opacity': 0,
+ 'active': False,
+ })
+ rootNode = player.getRootNode()
+ rootNode.appendChild(self.__calibratorNode)
+ self.__calibratorNode.size = rootNode.size
+ self.__calibrator = Calibrator(self.__calibratorNode, appStarter=self)
+ self.__calibrator.setOnCalibrationSuccess(self.__onCalibrationSuccess)
+ self.__calibrator.init()
+ else:
+ self.__calibrator = None
+
+ self.__showTrackerImage = False
+ self.__updateTrackerImageInterval = None
+ self.__trackerImageNode = player.createNode('image', {'sensitive': False})
+ player.getRootNode().appendChild(self.__trackerImageNode)
+
+ self.__updateTrackerImageFixup()
+
+ g_KbManager.bindKey('h', self.tracker.resetHistory, 'RESET tracker history')
+ g_KbManager.bindKey('d', self.toggleTrackerImage, 'toggle tracker image')
+
+ if self.__calibrator:
+ g_KbManager.bindKey('c', self.__enterCalibrator, 'enter calibrator')
+ AVGAppStarter._onStart(self)
+
+ def __updateTrackerImageFixup(self):
+ # finger bitmap might need to be rotated/flipped
+ trackerAngle = float(self.tracker.getParam('/transform/angle/@value'))
+ angle = round(trackerAngle/math.pi) * math.pi
+ self.__trackerImageNode.angle = angle
+ self.trackerFlipX = (float(self.tracker.getParam('/transform/displayscale/@x'))
+ < 0)
+ self.trackerFlipY = (float(self.tracker.getParam('/transform/displayscale/@y'))
+ < 0)
+
+ def __onCalibrationSuccess(self):
+ self.__updateTrackerImageFixup()
+
+ def __enterCalibrator(self):
+
+ def leaveCalibrator():
+ g_KbManager.unbindKey('e')
+ self._activeApp = self._appInstance
+ self._appInstance.enter()
+ self.__calibrator.leave()
+ self._appNode.opacity = 1
+ self._appNode.active = True
+ self.__calibratorNode.opacity = 0
+ self.__calibratorNode.active = False
+
+ if self.__calibrator.isRunning():
+ print "calibrator already running!"
+ return
+
+ self._activeApp = self.__calibrator
+ self.__calibrator.enter()
+ g_KbManager.bindKey('e', leaveCalibrator, 'leave Calibrator')
+ self._appInstance.leave()
+ self.__calibratorNode.opacity = 1
+ self.__calibratorNode.active = True
+ self._appNode.opacity = 0
+ self._appNode.active = False
diff --git a/src/python/avgapp.py b/src/python/avgapp.py
new file mode 100644
index 0000000..5e3d4b3
--- /dev/null
+++ b/src/python/avgapp.py
@@ -0,0 +1,142 @@
+# libavg - Media Playback Engine.
+# Copyright (C) 2003-2014 Ulrich von Zadow
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Current versions can be found at www.libavg.de
+#
+# Original author of this file is Martin Heistermann <mh at sponc dot de>
+#
+
+from appstarter import AppStarter
+
+
+class AVGApp(object):
+ _instances = {}
+ multitouch = False
+ fakeFullscreen = False
+
+ def __init__(self, parentNode):
+ '''
+ Initialization before Player.play()
+ Use this only when needed, e.g. for
+ WordsNode.addFontDir(). Do not forget to call
+ super(YourApp, self).__init__(parentNode)
+ '''
+
+ import warnings
+ warnings.warn('AVGApp is deprecated, use libavg.app.App instead')
+
+ appname = self.__class__.__name__
+ if appname in AVGApp._instances:
+ raise RuntimeError('App %s already setup' % appname)
+
+ AVGApp._instances[appname] = self
+
+ self.__isRunning = False
+ self._parentNode = parentNode
+ self._starter = None
+
+ if 'onKey' in dir(self):
+ raise DeprecationWarning, \
+ 'AVGApp.onKey() has been renamed to AVGApp.onKeyDown().'
+
+ @classmethod
+ def get(cls):
+ '''
+ Get the Application instance
+
+ Note: this class method has to be called from the top-level app class:
+
+ >>> class MyApp(libavg.AVGApp):
+ ... pass
+ >>> instance = MyApp.get()
+ '''
+ return cls._instances.get(cls.__name__, None)
+
+ @classmethod
+ def start(cls, **kwargs):
+ if cls.multitouch:
+ from appstarter import AVGMTAppStarter
+ starter = AVGMTAppStarter
+ else:
+ from appstarter import AVGAppStarter
+ starter = AVGAppStarter
+
+ starter(appClass=cls, fakeFullscreen=cls.fakeFullscreen, **kwargs)
+
+ def init(self):
+ """main initialization
+ build node hierarchy under self.__parentNode."""
+ pass
+
+ def exit(self):
+ """Deinitialization
+ Called after player.play() returns. End of program run."""
+ pass
+
+ def _enter(self):
+ """enter the application, internal interface.
+ override this and start all animations, intervals
+ etc. here"""
+ pass
+
+ def _leave(self):
+ """leave the application, internal interface.
+ override this and stop all animations, intervals
+ etc. Take care your application does not use any
+ non-needed resources after this."""
+ pass
+
+ def enter(self, onLeave = lambda: None):
+ """enter the application, external interface.
+ Do not override this."""
+ self.__isRunning = True
+ self._onLeave = onLeave
+ self._enter()
+
+ def leave(self):
+ """leave the application, external interface.
+ Do not override this."""
+ self.__isRunning = False
+ self._onLeave()
+ self._leave()
+
+ def onKeyDown(self, event):
+ """returns bool indicating if the event was handled
+ by the application """
+ return False
+
+ def onKeyUp(self, event):
+ """returns bool indicating if the event was handled
+ by the application """
+ return False
+
+ def isRunning(self):
+ return self.__isRunning
+
+ def setStarter(self, starter):
+ self._starter = starter
+
+ def getStarter(self):
+ return self._starter
+
+
+class App(object):
+ @classmethod
+ def start(cls, *args, **kargs):
+ raise RuntimeError('avgapp.App cannot be used any longer. Use libavg.AVGApp for '
+ 'a compatible class or switch to the new libavg.app.App')
+
diff --git a/src/python/camcalibrator.py b/src/python/camcalibrator.py
new file mode 100644
index 0000000..08bd308
--- /dev/null
+++ b/src/python/camcalibrator.py
@@ -0,0 +1,469 @@
+# libavg - Media Playback Engine.
+# Copyright (C) 2003-2014 Ulrich von Zadow
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Current versions can be found at www.libavg.de
+#
+# Original author of this file is igor <igor (at) c-base (dot) org>
+#
+
+import sys, os
+from libavg import avg, AVGApp, player
+
+import coordcalibrator
+import apphelpers
+
+mediadir = os.path.join(os.path.dirname(__file__), 'data')
+g_KbManager = apphelpers.KeyboardManager.get()
+
+
+def camera_setup(CameraType):
+ if CameraType == "Fire-i":
+ paramList = [
+ {'Name':"Brightness",
+ 'path':"/camera/brightness/@value",
+ 'min':128, 'max':383, 'increment':1, 'precision':0},
+ {'Name':"Exposure",
+ 'path':"/camera/exposure/@value",
+ 'min':-1, 'max':511, 'increment':1, 'precision':0},
+ {'Name':"Shutter",
+ 'path':"/camera/shutter/@value",
+ 'min':0, 'max':7, 'increment':1, 'precision':0},
+ {'Name':"Gain",
+ 'path':"/camera/gain/@value",
+ 'min':0, 'max':255, 'increment':1, 'precision':0},
+ ]
+ elif CameraType == "FireFly":
+ paramList = [
+ {'Name':"Brightness",
+ 'path':"/camera/brightness/@value",
+ 'min':1, 'max':255, 'increment':1, 'precision':0},
+ {'Name':"Shutter",
+ 'path':"/camera/shutter/@value",
+ 'min':1, 'max':533, 'increment':1, 'precision':0},
+ {'Name':"Gain",
+ 'path':"/camera/gain/@value",
+ 'min':16, 'max':64, 'increment':1, 'precision':0},
+ {'Name':"Gamma",
+ 'path':"/camera/gamma/@value",
+ 'min':0, 'max':1, 'increment':1, 'precision':0},
+ ]
+ elif CameraType == "DragonFly":
+ paramList = [
+ {'Name':"Brightness",
+ 'path':"/camera/brightness/@value",
+ 'min':1, 'max':255, 'increment':1, 'precision':0},
+ {'Name':"Gamma",
+ 'path':"/camera/gamma/@value",
+ 'min':512, 'max':4095, 'increment':5, 'precision':0},
+ {'Name':"Shutter",
+ 'path':"/camera/shutter/@value",
+ 'min':0, 'max':709, 'increment':2, 'precision':0},
+ {'Name':"Gain",
+ 'path':"/camera/gain/@value",
+ 'min':16, 'max':683, 'increment':2, 'precision':0},
+ ]
+ else:
+ avg.logger.error("Unknown CameraType %s" % CameraType)
+ sys.exit()
+
+ paramList.extend([
+ # Touch
+ {'Name':"Threshold",
+ 'path':"/tracker/touch/threshold/@value",
+ 'min':1, 'max':255, 'increment':1, 'precision':0},
+ {'Name':"Similarity",
+ 'path':"/tracker/touch/similarity/@value",
+ 'min':1, 'max':300, 'increment':1, 'precision':1},
+
+ {'Name':"Min Area",
+ 'path':"/tracker/touch/areabounds/@min",
+ 'min':1, 'max':1000000, 'increment':3, 'precision':0},
+ {'Name':"Max Area",
+ 'path':"/tracker/touch/areabounds/@max",
+ 'min':20, 'max':1000000, 'increment':10, 'precision':0},
+
+ {'Name':"Ecc. Min",
+ 'path':"/tracker/touch/eccentricitybounds/@min",
+ 'min':1, 'max':30, 'increment':1, 'precision':1},
+ {'Name':"Ecc. Max",
+ 'path':"/tracker/touch/eccentricitybounds/@max",
+ 'min':1, 'max':2000, 'increment':1, 'precision':1},
+
+ {'Name':"Bandpass Min",
+ 'path':"/tracker/touch/bandpass/@min",
+ 'min':0, 'max':15, 'increment':.1, 'precision':1},
+ {'Name':"Bandpass Max",
+ 'path':"/tracker/touch/bandpass/@max",
+ 'min':0, 'max':15, 'increment':.1, 'precision':1},
+ {'Name':"Bandpass Postmult",
+ 'path':"/tracker/touch/bandpasspostmult/@value",
+ 'min':0, 'max':30, 'increment':.1, 'precision':1},
+
+ # Track
+ {'Name':"Threshold",
+ 'path':"/tracker/track/threshold/@value",
+ 'min':1, 'max':255, 'increment':1, 'precision':0},
+
+ {'Name':"Min Area",
+ 'path':"/tracker/track/areabounds/@min",
+ 'min':1, 'max':1000000, 'increment':3, 'precision':0},
+ {'Name':"Max Area",
+ 'path':"/tracker/track/areabounds/@max",
+ 'min':20, 'max':1000000, 'increment':10, 'precision':0},
+
+ {'Name':"Ecc. Min",
+ 'path':"/tracker/track/eccentricitybounds/@min",
+ 'min':1, 'max':30, 'increment':1, 'precision':1},
+ {'Name':"Ecc. Max",
+ 'path':"/tracker/track/eccentricitybounds/@max",
+ 'min':1, 'max':2000, 'increment':1, 'precision':1},
+
+ # Transform
+ {'Name':"p2",
+ 'path':"/transform/distortionparams/@p2",
+ 'min':-3, 'max':3, 'increment':0.001, 'precision':3},
+ {'Name':"Trapezoid",
+ 'path':"/transform/trapezoid/@value",
+ 'min':-3, 'max':3, 'increment':0.0001, 'precision':4},
+ {'Name':"Angle",
+ 'path':"/transform/angle/@value",
+ 'min':-3.15, 'max':3.15, 'increment':0.01, 'precision':2},
+ {'Name':"Displ. x",
+ 'path':"/transform/displaydisplacement/@x",
+ 'min':-5000, 'max':0, 'increment':1, 'precision':0},
+ {'Name':"Displ. y",
+ 'path':"/transform/displaydisplacement/@y",
+ 'min':-5000, 'max':0, 'increment':1, 'precision':0},
+ {'Name':"Scale x",
+ 'path':"/transform/displayscale/@x",
+ 'min':-3, 'max':8, 'increment':0.01, 'precision':2},
+ {'Name':"Scale y",
+ 'path':"/transform/displayscale/@y",
+ 'min':-3, 'max':8, 'increment':0.01, 'precision':2},
+ ])
+ return paramList
+
+class Calibrator(AVGApp):
+ def __init__(self, parentNode, CameraType = "FireFly", appStarter = None):
+ super(Calibrator, self).__init__(parentNode)
+ self.paramList = camera_setup(CameraType)
+ self.parentNode=parentNode
+ self.appStarter = appStarter
+ self.mainNode = player.createNode(
+ """
+ <div active="False" opacity="0">
+ <image width="1280" height="800" href="black.png"/>
+ <image id="cal_distorted" x="0" y="0" width="1280" height="800"
+ sensitive="false" opacity="1"/>
+ <words id="cal_fps" x="30" y="30" color="00FF00" text=""/>
+ <words id="cal_notification" x="390" y="390" width="500" fontsize="18"
+ color="ff3333" alignment="center" />
+ <div id="cal_gui" x="30" y="540">
+ <image id="cal_shadow" x="0" y="13" width="500" height="150"
+ href="black.png" opacity="0.6"/>
+
+ <words x="2" y="13" text="camera" fontsize="16" color="00FF00"/>
+ <image x="2" y="32" href="CamImgBorder.png"/>
+ <image id="cal_camera" x="4" y="34" width="160" height="120"/>
+
+ <words x="168" y="13" text="nohistory" fontsize="16" color="00FF00"/>
+ <image x="168" y="32" href="CamImgBorder.png"/>
+ <image id="cal_nohistory" x="170" y="34" width="160" height="120"/>
+
+ <words x="334" y="13" text="histogram" fontsize="16" color="00FF00"/>
+ <image x="334" y="32" href="CamImgBorder.png"/>
+ <image id="cal_histogram" x="336" y="34" width="160" height="120"/>
+
+ <div id="cal_params" y="170" opacity="0.9">
+ <image id="cal_shadow2" width="750" height="65" href="black.png" opacity="0.6"/>
+ <div id="cal_paramdiv0" x="2">
+ <words text="camera" y="0" fontsize="10" color="00ff00" />
+ <words id="cal_param0" y="12" fontsize="10"/>
+ <words id="cal_param1" y="24" fontsize="10"/>
+ <words id="cal_param2" y="36" fontsize="10"/>
+ <words id="cal_param3" y="48" fontsize="10"/>
+ </div>
+ <div id="cal_paramdiv1" x="80">
+ <words text="touch" y="0" fontsize="10" color="00ff00" />
+ <words id="cal_param4" y="12" fontsize="10"/>
+ <words id="cal_param5" y="24" fontsize="10"/>
+ <words id="cal_param6" y="36" fontsize="10"/>
+ <words id="cal_param7" y="48" fontsize="10"/>
+ </div>
+ <div id="cal_paramdiv2" x="200">
+ <words id="cal_param8" y="0" fontsize="10"/>
+ <words id="cal_param9" y="12" fontsize="10"/>
+ <words id="cal_param10" y="24" fontsize="10"/>
+ <words id="cal_param11" y="36" fontsize="10"/>
+ <words id="cal_param12" y="48" fontsize="10"/>
+ </div>
+ <div id="cal_paramdiv3" x="350">
+ <words text="track" y="0" fontsize="10" color="00ff00" />
+ <words id="cal_param13" y="12" fontsize="10"/>
+ <words id="cal_param14" y="24" fontsize="10"/>
+ <words id="cal_param15" y="36" fontsize="10"/>
+ <words id="cal_param16" y="48" fontsize="10"/>
+ </div>
+ <div id="cal_paramdiv4" x="500">
+ <words id="cal_param17" y="0" fontsize="10"/>
+ <words text="distort" y="12" fontsize="10" color="00ff00"/>
+ <words id="cal_param18" y="24" fontsize="10"/>
+ <words id="cal_param19" y="36" fontsize="10"/>
+ <words id="cal_param20" y="48" fontsize="10"/>
+ </div>
+ <div id="cal_paramdiv5" x="650">
+ <words id="cal_param21" y="0" fontsize="10"/>
+ <words id="cal_param22" y="12" fontsize="10"/>
+ <words id="cal_param23" y="24" fontsize="10"/>
+ <words id="cal_param24" y="36" fontsize="10"/>
+ <words id="cal_param25" y="48" fontsize="10"/>
+ </div>
+ </div>
+ </div>
+ <div id="cal_coordcalibrator" opacity="0" active="false">
+ <image x="0" y="0" width="1280" height="800" href="border.png"/>
+ <div id="cal_messages" x="100" y="100"/>
+ <image id="cal_crosshair" href="crosshair.png"/>
+ <image id="cal_feedback" href="Feedback.png"/>
+ </div>
+ </div>
+ """)
+ self.mainNode.mediadir=mediadir
+ parentNode.insertChild(self.mainNode, 0)
+
+ self.coordCal = None
+ self.tracker = player.getTracker()
+ self.curParam = 0
+ self.saveIndex = 0
+ self.hideMainNodeTimeout = None
+ self.video = []
+ self.__guiOpacity = 1
+ self.__showBigCamImage = False
+ self.__notificationTimer = None
+ self.__onCalibrationSuccess = None
+
+
+
+ def _enter(self):
+
+ g_KbManager.push()
+
+ g_KbManager.bindKey('d', self.__trackerSetDebugImages, 'tracker set debug images')
+ g_KbManager.bindKey('b', self.__bigCamImage, 'big cam image')
+ g_KbManager.bindKey('up', self.__keyFuncUP, 'select parameter up')
+ g_KbManager.bindKey('down', self.__keyFuncDOWN, 'select parameter down')
+ g_KbManager.bindKey('left', self.__keyFuncLEFT, 'value up')
+ g_KbManager.bindKey('right', self.__keyFuncRIGHT, 'value down')
+ g_KbManager.bindKey('page up', self.__keyFuncPAGEUp, 'value up * 10')
+ g_KbManager.bindKey('page down', self.__keyFuncPAGEDown, 'value down * 10')
+ g_KbManager.bindKey('s', self.__trackerSaveConfig, 'save configuration')
+ g_KbManager.bindKey('g', self.__toggleGUI, 'toggle GUI')
+ g_KbManager.bindKey('c', self.__startCoordCalibration,
+ 'start geometry calibration')
+ g_KbManager.bindKey('w', self.__saveTrackerIMG, 'SAVE trager image')
+ g_KbManager.bindKey('h', self.appStarter.tracker.resetHistory, 'RESET history')
+
+ self.appStarter.showTrackerImage()
+ self.mainNode.active=True
+ self.tracker.setDebugImages(True, True)
+ avg.fadeIn(self.mainNode, 400, 1)
+ Bitmap = self.tracker.getImage(avg.IMG_DISTORTED) # Why is this needed?
+ self.__onFrameID = player.subscribe(player.ON_FRAME, self.__onFrame)
+ #grandparent = self.parentNode.getParent()
+ #if grandparent:
+ # grandparent.reorderChild(grandparent.indexOf(self.parentNode), grandparent.getNumChildren()-1)
+ self.displayParams()
+ if self.hideMainNodeTimeout:
+ player.clearInterval(self.hideMainNodeTimeout)
+
+ def _leave(self):
+ #unbind all calibrator keys - bind old keys
+ g_KbManager.pop()
+
+ def hideMainNode():
+ self.mainNode.opacity=0
+ self.mainNode.active = False
+ self.appStarter.hideTrackerImage()
+ #grandparent = self.parentNode.getParent()
+ #if grandparent:
+ # grandparent.reorderChild(grandparent.indexOf(self.parentNode), 0)
+ self.hideMainNodeTimeout = player.setTimeout(400, hideMainNode)
+ player.clearInterval(self.__onFrameID)
+
+ def reparent(self, newParent):
+ """reparents the calibrator node; returns the old(!) parent node"""
+ oldParent = self.mainNode.getParent()
+ self.mainNode.unlink()
+ newParent.appendChild(self.mainNode)
+ return oldParent
+
+ def __deferredRefreshCB(self):
+ self.displayParams()
+ self.tracker.resetHistory()
+ self.setNotification('')
+ g_KbManager.pop()
+ player.getElementByID('cal_params').opacity = 0.9
+
+ def __clearNotification(self):
+ self.__notificationTimer = None
+ self.setNotification('')
+
+ def __toggleGUI(self):
+ self.__guiOpacity = 1 - self.__guiOpacity
+ player.getElementByID('cal_gui').opacity = self.__guiOpacity
+
+ def __onFrame(self):
+ def showTrackerImage(trackerImageID, nodeID, size, pos=(0,0)):
+ bitmap = self.tracker.getImage(trackerImageID)
+ node = player.getElementByID(nodeID)
+ node.setBitmap(bitmap)
+ node.size = size
+ if pos != (0,0):
+ node.pos = pos
+
+ # flip:
+ grid = node.getOrigVertexCoords()
+ grid = [ [ (1-pos[0], pos[1]) for pos in line ] for line in grid]
+ node.setWarpedVertexCoords(grid)
+
+ if self.__showBigCamImage:
+ showTrackerImage(avg.IMG_CAMERA, "cal_distorted", (1280, 960))
+ else:
+ pos = self.tracker.getDisplayROIPos()
+ size = self.tracker.getDisplayROISize()
+ showTrackerImage(avg.IMG_DISTORTED, "cal_distorted", pos = pos, size = size)
+ showTrackerImage(avg.IMG_CAMERA, "cal_camera", (160, 120))
+ showTrackerImage(avg.IMG_NOHISTORY, "cal_nohistory", (160, 120))
+ showTrackerImage(avg.IMG_HISTOGRAM, "cal_histogram", (160, 120))
+ fps = player.getEffectiveFramerate()
+ player.getElementByID("cal_fps").text = '%(val).2f' % {'val': fps}
+
+ def __trackerSetDebugImages(self):
+ self.appStarter.toggleTrackerImage()
+ # toggleTrackerImage() will influence setDebugImages status, so we have to reset it:
+ self.tracker.setDebugImages(True, True)
+
+ def __bigCamImage(self):
+ self.__showBigCamImage = not(self.__showBigCamImage)
+
+ def __keyFuncUP(self):
+ if self.curParam > 0:
+ self.curParam -= 1
+ self.displayParams()
+
+ def __keyFuncDOWN(self):
+ if self.curParam < len(self.paramList)-1:
+ self.curParam += 1
+ self.displayParams()
+
+ def __keyFuncLEFT(self):
+ self.changeParam(-1)
+ self.displayParams()
+
+ def __keyFuncRIGHT(self):
+ self.changeParam(1)
+ self.displayParams()
+
+ def __keyFuncPAGEUp(self):
+ self.changeParam(10)
+ self.displayParams()
+
+ def __keyFuncPAGEDown(self):
+ self.changeParam(-10)
+ self.displayParams()
+
+ def __trackerSaveConfig(self):
+ self.tracker.saveConfig()
+ self.setNotification('Tracker configuration saved', 2000)
+ avg.logger.info("Tracker configuration saved.")
+
+ def __saveTrackerIMG(self):
+ def saveTrackerImage(id, name):
+ self.tracker.getImage(id).save("img"+str(self.saveIndex)+"_"+name+".png")
+
+ self.saveIndex += 1
+ saveTrackerImage(avg.IMG_CAMERA, "camera")
+ saveTrackerImage(avg.IMG_DISTORTED, "distorted")
+ saveTrackerImage(avg.IMG_NOHISTORY, "nohistory")
+ saveTrackerImage(avg.IMG_HIGHPASS, "highpass")
+ saveTrackerImage(avg.IMG_FINGERS, "fingers")
+ saveTrackerImage(avg.IMG_HISTOGRAM, "histogram")
+ self.setNotification('Tracker images dumped', 2000)
+ avg.logger.info("Tracker images saved.")
+
+ def __startCoordCalibration(self):
+ assert(not self.coordCal)
+
+ self.__savedShutter = self.tracker.getParam("/camera/shutter/@value")
+ self.tracker.setParam("/camera/shutter/@value", "8")
+ self.__savedGain = self.tracker.getParam("/camera/gain/@value")
+ self.tracker.setParam("/camera/gain/@value", "16")
+ self.__savedStrobe = self.tracker.getParam("/camera/strobeduration/@value")
+ self.tracker.setParam("/camera/strobeduration/@value", "-1")
+ self.coordCal = coordcalibrator.CoordCalibrator(self.__onCalibrationTerminated)
+
+ def __onCalibrationTerminated(self, isSuccessful):
+ self.coordCal = None
+ self.tracker.setParam("/camera/shutter/@value", self.__savedShutter)
+ self.tracker.setParam("/camera/gain/@value", self.__savedGain)
+ self.tracker.setParam("/camera/strobeduration/@value", self.__savedStrobe)
+ self.deferredRefresh()
+
+ def setOnCalibrationSuccess(self, callback):
+ self.__onCalibrationSuccess = callback
+
+ def deferredRefresh(self):
+ player.setTimeout(1500, self.__deferredRefreshCB)
+ self.setNotification('Please wait for settlement')
+ g_KbManager.push()
+ player.getElementByID('cal_params').opacity = 0.3
+
+ def setNotification(self, text, timeout=0):
+ player.getElementByID('cal_notification').text = text
+ if timeout:
+ if self.__notificationTimer is not None:
+ player.clearInterval(self.__notificationTimer)
+
+ self.__notificationTimer = player.setTimeout(timeout,
+ self.__clearNotification)
+
+ def displayParams(self):
+ i = 0
+ for Param in self.paramList:
+ Node = player.getElementByID("cal_param"+str(i))
+ Path = Param['path']
+ Val = float(self.tracker.getParam(Path))
+ Node.text = (Param['Name']+": "
+ +('%(val).'+str(Param['precision'])+'f') % {'val': Val})
+ if self.curParam == i:
+ Node.color = "FFFFFF"
+ else:
+ Node.color = "A0A0FF"
+ i += 1
+
+ def changeParam(self, Change):
+ param = self.paramList[self.curParam]
+ if param['increment'] >= 1:
+ Val = int(float(self.tracker.getParam(param['path'])))
+ else:
+ Val = float(self.tracker.getParam(param['path']))
+ Val += Change*param['increment']
+ if Val < param['min']:
+ Val = param['min']
+ if Val > param['max']:
+ Val = param['max']
+ self.tracker.setParam(param['path'], str(Val))
diff --git a/src/python/coordcalibrator.py b/src/python/coordcalibrator.py
new file mode 100644
index 0000000..c3dad01
--- /dev/null
+++ b/src/python/coordcalibrator.py
@@ -0,0 +1,133 @@
+# libavg - Media Playback Engine.
+# Copyright (C) 2003-2014 Ulrich von Zadow
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Current versions can be found at www.libavg.de
+
+from libavg import avg, player
+
+import apphelpers
+
+g_KbManager = apphelpers.KeyboardManager.get()
+
+
+class CoordCalibrator(object):
+ def __init__(self, calibrationTerminatedCb):
+ self.__calibrationTerminatedCb = calibrationTerminatedCb
+ self.__CurPointIndex = 0
+ self.__CPPCal = player.getTracker().startCalibration()
+ self.__LastCenter = None
+ self.__NumMessages = 0
+ self._mycursor = None
+ mainNode = player.getElementByID("cal_coordcalibrator")
+ mainNode.active = True
+ mainNode.opacity = 1
+ mainNode.setEventHandler(avg.Event.CURSOR_DOWN, avg.Event.TOUCH,
+ self.__onTouchDown)
+ mainNode.setEventHandler(avg.Event.CURSOR_MOTION, avg.Event.TOUCH,
+ self.__onTouchMove)
+ mainNode.setEventHandler(avg.Event.CURSOR_UP, avg.Event.TOUCH, self.__onTouchUp)
+ self.__crosshair = player.getElementByID("cal_crosshair")
+ self.__feedback = player.getElementByID("cal_feedback")
+ self.__feedback.opacity = 0
+ self.__addMessage("Starting calibration.")
+ self.__moveMarker()
+
+ g_KbManager.push()
+ g_KbManager.bindKey('space', self.__nextPoint, 'sample next point')
+ g_KbManager.bindKey('a', self.__abortCalibration, 'abort calibration')
+
+ def __endCalibration(self, isSuccessful):
+ player.getElementByID("cal_coordcalibrator").active = False
+ player.getElementByID("cal_coordcalibrator").opacity = 0
+ MsgsNode = player.getElementByID("cal_messages")
+ for i in range(0, MsgsNode.getNumChildren()):
+ MsgsNode.removeChild(0)
+
+ g_KbManager.pop()
+ self.__calibrationTerminatedCb(isSuccessful)
+
+ def __nextPoint(self):
+ if self.__LastCenter:
+ self.__CPPCal.setCamPoint(self.__LastCenter)
+ self.__addMessage (" Using: %(x).2f, %(y).2f" %
+ { "x": self.__LastCenter[0], "y": self.__LastCenter[1]})
+ self._mycursor = None
+ self.__LastCenter = None
+
+ hasNextPoint = self.__CPPCal.nextPoint()
+
+ if not hasNextPoint:
+ # Note: may raise RuntimeError. A rollback doesn't appear to be possible,
+ # which means crashing here is safer than handling the exception
+ player.getTracker().endCalibration()
+ self.__endCalibration(True)
+ else:
+ self.__CurPointIndex += 1
+ self.__moveMarker()
+
+ def __abortCalibration(self):
+ player.getTracker().abortCalibration()
+ self.__endCalibration(False)
+
+ def __moveMarker(self):
+ self.__crosshair.x, self.__crosshair.y = self.__CPPCal.getDisplayPoint()
+ self.__crosshair.x, self.__crosshair.y = self.__feedback.x, self.__feedback.y = \
+ (self.__crosshair.x-7, self.__crosshair.y-7)
+ self.__addMessage("Calibrating point "+str(self.__CurPointIndex))
+
+ def __addMessage(self, text):
+ MsgsNode = player.getElementByID("cal_messages")
+ if self.__NumMessages > 38:
+ for i in range(0, MsgsNode.getNumChildren()-1):
+ MsgsNode.getChild(i).text = MsgsNode.getChild(i+1).text
+ MsgsNode.removeChild(MsgsNode.getNumChildren()-1)
+ else:
+ self.__NumMessages += 1
+ Node = player.createNode(
+ "<words fontsize='10' font='Eurostile' color='00FF00'/>")
+ Node.x = 0
+ Node.y = self.__NumMessages*13
+ Node.text = text
+ MsgsNode.appendChild(Node)
+
+ def __onTouchDown(self, Event):
+ if Event.source != avg.Event.TOUCH:
+ return
+ if not self._mycursor:
+ self._mycursor = Event.cursorid
+ else:
+ return
+ self.__LastCenter = Event.center
+ self.__addMessage(" Touch at %(x).2f, %(y).2f" % {
+ "x": Event.center[0], "y": Event.center[1]})
+ self.__feedback.opacity = 1
+
+ def __onTouchMove(self,Event):
+ if Event.source != avg.Event.TOUCH:
+ return
+ if self._mycursor == Event.cursorid:
+ self.__LastCenter = Event.center
+
+ def __onTouchUp(self, Event):
+ if Event.source != avg.Event.TOUCH:
+ return
+ self.__addMessage("touchup")
+ self.__feedback.opacity = 0
+ if self._mycursor:
+ self._mycursor = None
+ else:
+ return
diff --git a/src/python/data/CamImgBorder.png b/src/python/data/CamImgBorder.png
new file mode 100644
index 0000000..4bc1a37
--- /dev/null
+++ b/src/python/data/CamImgBorder.png
Binary files differ
diff --git a/src/python/data/Feedback.png b/src/python/data/Feedback.png
new file mode 100644
index 0000000..3c71f9c
--- /dev/null
+++ b/src/python/data/Feedback.png
Binary files differ
diff --git a/src/python/data/Makefile.am b/src/python/data/Makefile.am
new file mode 100644
index 0000000..02a416a
--- /dev/null
+++ b/src/python/data/Makefile.am
@@ -0,0 +1,4 @@
+EXTRA_DIST = $(wildcard *.xml) $(wildcard *.xsd) $(wildcard *.png) $(wildcard *.avg) \
+ $(wildcard *.mpg) $(wildcard *.avi) $(wildcard *.mov)
+datadir = $(pkgpyexecdir)/data
+data_DATA = $(EXTRA_DIST)
diff --git a/src/python/data/SimpleSkin.xml b/src/python/data/SimpleSkin.xml
new file mode 100644
index 0000000..3f21274
--- /dev/null
+++ b/src/python/data/SimpleSkin.xml
@@ -0,0 +1,83 @@
+<skin>
+ <fontdef id="stdFont" font="Bitstream Vera Sans" variant="Roman" fontsize="12"
+ color="000000" letterspacing="0" linespacing="-1"/>
+ <fontdef id="downFont" baseid="stdFont" color="CCCCCC"/>
+ <fontdef id="disabledFont" baseid="stdFont" color="444444"/>
+ <textbutton
+ upSrc="button_bg_up.png"
+ downSrc="button_bg_down.png"
+ font="stdFont"
+ downFont="downFont"
+ disabledFont="disabledFont"
+ endsExtent="(7,7)"/>
+ <slider>
+ <horizontal
+ trackSrc="slider_horiz_track.png"
+ trackDisabledSrc="slider_horiz_track_disabled.png"
+ trackEndsExtent="6"
+ thumbUpSrc="slider_thumb_up.png"
+ thumbDownSrc="slider_thumb_down.png"/>
+ <vertical
+ trackSrc="slider_vert_track.png"
+ trackDisabledSrc="slider_vert_track_disabled.png"
+ trackEndsExtent="6"
+ thumbUpSrc="slider_thumb_up.png"
+ thumbDownSrc="slider_thumb_down.png"/>
+ </slider>
+ <scrollbar>
+ <horizontal
+ trackSrc="scrollbar_horiz_track.png"
+ trackDisabledSrc="scrollbar_horiz_track_disabled.png"
+ trackEndsExtent="2"
+ thumbUpSrc="scrollbar_horiz_thumb_up.png"
+ thumbDownSrc="scrollbar_horiz_thumb_down.png"
+ thumbEndsExtent="4"/>
+ <vertical
+ trackSrc="scrollbar_vert_track.png"
+ trackDisabledSrc="scrollbar_vert_track_disabled.png"
+ trackEndsExtent="2"
+ thumbUpSrc="scrollbar_vert_thumb_up.png"
+ thumbDownSrc="scrollbar_vert_thumb_down.png"
+ thumbEndsExtent="4"/>
+ </scrollbar>
+ <progressbar>
+ <horizontal
+ trackSrc="scrollbar_horiz_track.png"
+ trackEndsExtent="2"
+ thumbUpSrc="scrollbar_horiz_thumb_up.png"
+ thumbDisabledSrc="scrollbar_vert_thumb_down.png"
+ thumbEndsExtent="4"/>
+ <vertical
+ trackSrc="scrollbar_vert_track.png"
+ trackEndsExtent="2"
+ thumbUpSrc="scrollbar_vert_thumb_up.png"
+ thumbDisabledSrc="scrollbar_vert_thumb_down.png"
+ thumbEndsExtent="4"/>
+ </progressbar>
+ <scrollarea
+ borderSrc="scrollarea_border.png"
+ borderEndsExtent="(8,8)"
+ margins="(1,1,8,8)"
+ friction="-1"
+ sensitiveScrollBars="True"/>
+ <checkbox
+ uncheckedUpSrc="checkbox_unchecked_up.png"
+ uncheckedDownSrc="checkbox_unchecked_down.png"
+ uncheckedDisabledSrc="checkbox_unchecked_disabled.png"
+ checkedUpSrc="checkbox_checked_up.png"
+ checkedDownSrc="checkbox_checked_down.png"
+ checkedDisabledSrc="checkbox_checked_disabled.png"
+ font="stdFont"
+ downFont="stdFont"
+ disabledFont="disabledFont"/>
+ <mediacontrol
+ playUpSrc="play_button_up.png"
+ playDownSrc="play_button_down.png"
+ pauseUpSrc="pause_button_up.png"
+ pauseDownSrc="pause_button_down.png"
+ font="stdFont"
+ timePos="(15,0)"
+ timeLeftPos="(-42,0)"
+ barPos="(55,2)"
+ barRight="-45"/>
+</skin>
diff --git a/src/python/data/TouchFeedback.png b/src/python/data/TouchFeedback.png
new file mode 100644
index 0000000..9f5dcda
--- /dev/null
+++ b/src/python/data/TouchFeedback.png
Binary files differ
diff --git a/src/python/data/black.png b/src/python/data/black.png
new file mode 100644
index 0000000..23bd512
--- /dev/null
+++ b/src/python/data/black.png
Binary files differ
diff --git a/src/python/data/border.png b/src/python/data/border.png
new file mode 100644
index 0000000..447a3e6
--- /dev/null
+++ b/src/python/data/border.png
Binary files differ
diff --git a/src/python/data/button_bg_down.png b/src/python/data/button_bg_down.png
new file mode 100644
index 0000000..c44179b
--- /dev/null
+++ b/src/python/data/button_bg_down.png
Binary files differ
diff --git a/src/python/data/button_bg_up.png b/src/python/data/button_bg_up.png
new file mode 100644
index 0000000..475c9c9
--- /dev/null
+++ b/src/python/data/button_bg_up.png
Binary files differ
diff --git a/src/python/data/checkbox_checked_disabled.png b/src/python/data/checkbox_checked_disabled.png
new file mode 100644
index 0000000..da58829
--- /dev/null
+++ b/src/python/data/checkbox_checked_disabled.png
Binary files differ
diff --git a/src/python/data/checkbox_checked_down.png b/src/python/data/checkbox_checked_down.png
new file mode 100644
index 0000000..4fbbd83
--- /dev/null
+++ b/src/python/data/checkbox_checked_down.png
Binary files differ
diff --git a/src/python/data/checkbox_checked_up.png b/src/python/data/checkbox_checked_up.png
new file mode 100644
index 0000000..ca901f4
--- /dev/null
+++ b/src/python/data/checkbox_checked_up.png
Binary files differ
diff --git a/src/python/data/checkbox_unchecked_disabled.png b/src/python/data/checkbox_unchecked_disabled.png
new file mode 100644
index 0000000..e8c2116
--- /dev/null
+++ b/src/python/data/checkbox_unchecked_disabled.png
Binary files differ
diff --git a/src/python/data/checkbox_unchecked_down.png b/src/python/data/checkbox_unchecked_down.png
new file mode 100644
index 0000000..69f8282
--- /dev/null
+++ b/src/python/data/checkbox_unchecked_down.png
Binary files differ
diff --git a/src/python/data/checkbox_unchecked_up.png b/src/python/data/checkbox_unchecked_up.png
new file mode 100644
index 0000000..e354492
--- /dev/null
+++ b/src/python/data/checkbox_unchecked_up.png
Binary files differ
diff --git a/src/python/data/crosshair.png b/src/python/data/crosshair.png
new file mode 100644
index 0000000..be025b1
--- /dev/null
+++ b/src/python/data/crosshair.png
Binary files differ
diff --git a/src/python/data/mpeg1-48x48-sound.avi b/src/python/data/mpeg1-48x48-sound.avi
new file mode 100644
index 0000000..be415db
--- /dev/null
+++ b/src/python/data/mpeg1-48x48-sound.avi
Binary files differ
diff --git a/src/python/data/mpeg1-48x48.mov b/src/python/data/mpeg1-48x48.mov
new file mode 100644
index 0000000..16ab499
--- /dev/null
+++ b/src/python/data/mpeg1-48x48.mov
Binary files differ
diff --git a/src/python/data/pause_button_down.png b/src/python/data/pause_button_down.png
new file mode 100644
index 0000000..c06b34a
--- /dev/null
+++ b/src/python/data/pause_button_down.png
Binary files differ
diff --git a/src/python/data/pause_button_up.png b/src/python/data/pause_button_up.png
new file mode 100644
index 0000000..1a923b9
--- /dev/null
+++ b/src/python/data/pause_button_up.png
Binary files differ
diff --git a/src/python/data/play_button_down.png b/src/python/data/play_button_down.png
new file mode 100644
index 0000000..07b167b
--- /dev/null
+++ b/src/python/data/play_button_down.png
Binary files differ
diff --git a/src/python/data/play_button_up.png b/src/python/data/play_button_up.png
new file mode 100644
index 0000000..e16ec9e
--- /dev/null
+++ b/src/python/data/play_button_up.png
Binary files differ
diff --git a/src/python/data/rgb24alpha-64x64.png b/src/python/data/rgb24alpha-64x64.png
new file mode 100644
index 0000000..41b69c3
--- /dev/null
+++ b/src/python/data/rgb24alpha-64x64.png
Binary files differ
diff --git a/src/python/data/scrollarea_border.png b/src/python/data/scrollarea_border.png
new file mode 100644
index 0000000..2e95f57
--- /dev/null
+++ b/src/python/data/scrollarea_border.png
Binary files differ
diff --git a/src/python/data/scrollbar_horiz_thumb_down.png b/src/python/data/scrollbar_horiz_thumb_down.png
new file mode 100644
index 0000000..6dc6fd1
--- /dev/null
+++ b/src/python/data/scrollbar_horiz_thumb_down.png
Binary files differ
diff --git a/src/python/data/scrollbar_horiz_thumb_up.png b/src/python/data/scrollbar_horiz_thumb_up.png
new file mode 100644
index 0000000..02748f2
--- /dev/null
+++ b/src/python/data/scrollbar_horiz_thumb_up.png
Binary files differ
diff --git a/src/python/data/scrollbar_horiz_track.png b/src/python/data/scrollbar_horiz_track.png
new file mode 100644
index 0000000..052002a
--- /dev/null
+++ b/src/python/data/scrollbar_horiz_track.png
Binary files differ
diff --git a/src/python/data/scrollbar_horiz_track_disabled.png b/src/python/data/scrollbar_horiz_track_disabled.png
new file mode 100644
index 0000000..7ac86fe
--- /dev/null
+++ b/src/python/data/scrollbar_horiz_track_disabled.png
Binary files differ
diff --git a/src/python/data/scrollbar_vert_thumb_down.png b/src/python/data/scrollbar_vert_thumb_down.png
new file mode 100644
index 0000000..c7b09d1
--- /dev/null
+++ b/src/python/data/scrollbar_vert_thumb_down.png
Binary files differ
diff --git a/src/python/data/scrollbar_vert_thumb_up.png b/src/python/data/scrollbar_vert_thumb_up.png
new file mode 100644
index 0000000..f6c2f88
--- /dev/null
+++ b/src/python/data/scrollbar_vert_thumb_up.png
Binary files differ
diff --git a/src/python/data/scrollbar_vert_track.png b/src/python/data/scrollbar_vert_track.png
new file mode 100644
index 0000000..58af284
--- /dev/null
+++ b/src/python/data/scrollbar_vert_track.png
Binary files differ
diff --git a/src/python/data/scrollbar_vert_track_disabled.png b/src/python/data/scrollbar_vert_track_disabled.png
new file mode 100644
index 0000000..695b112
--- /dev/null
+++ b/src/python/data/scrollbar_vert_track_disabled.png
Binary files differ
diff --git a/src/python/data/skin.xsd b/src/python/data/skin.xsd
new file mode 100644
index 0000000..4b8e545
--- /dev/null
+++ b/src/python/data/skin.xsd
@@ -0,0 +1,137 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+ <xsd:complexType name="SliderDef">
+ <xsd:attribute name="trackSrc" type="xsd:string" use="required"/>
+ <xsd:attribute name="trackDisabledSrc" type="xsd:string"/>
+ <xsd:attribute name="trackEndsExtent" type="xsd:integer"/>
+ <xsd:attribute name="thumbUpSrc" type="xsd:string" use="required"/>
+ <xsd:attribute name="thumbDownSrc" type="xsd:string"/>
+ <xsd:attribute name="thumbDisabledSrc" type="xsd:string"/>
+ </xsd:complexType>
+ <xsd:complexType name="ScrollBarDef">
+ <xsd:complexContent>
+ <xsd:extension base="SliderDef">
+ <xsd:attribute name="thumbEndsExtent" type="xsd:integer"/>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:complexType name="ProgressBarDef">
+ <xsd:attribute name="trackSrc" type="xsd:string" use="required"/>
+ <xsd:attribute name="trackEndsExtent" type="xsd:integer"/>
+ <xsd:attribute name="thumbUpSrc" type="xsd:string" use="required"/>
+ <xsd:attribute name="thumbDisabledSrc" type="xsd:string"/>
+ <xsd:attribute name="thumbEndsExtent" type="xsd:integer"/>
+ </xsd:complexType>
+ <xsd:simpleType name="bool">
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="True"/>
+ <xsd:enumeration value="False"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+ <xsd:element name="skin">
+ <xsd:complexType>
+ <xsd:sequence maxOccurs="unbounded">
+ <xsd:element name="fontdef" minOccurs="0" maxOccurs="unbounded">
+ <xsd:complexType>
+ <xsd:attribute name="id" type="xsd:ID" use="required"/>
+ <xsd:attribute name="baseid" type="xsd:IDREF"/>
+ <xsd:attribute name="font" type="xsd:string"/>
+ <xsd:attribute name="variant" type="xsd:string"/>
+ <xsd:attribute name="color" type="xsd:string"/>
+ <xsd:attribute name="aagamma" type="xsd:decimal"/>
+ <xsd:attribute name="fontsize" type="xsd:decimal"/>
+ <xsd:attribute name="indent" type="xsd:integer"/>
+ <xsd:attribute name="linespacing" type="xsd:decimal"/>
+ <xsd:attribute name="alignment" type="xsd:string"/>
+ <xsd:attribute name="wrapmode" type="xsd:string"/>
+ <xsd:attribute name="justify" type="bool"/>
+ <xsd:attribute name="letterspacing" type="xsd:decimal"/>
+ <xsd:attribute name="hint" type="bool"/>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="textbutton" minOccurs="0" maxOccurs="unbounded">
+ <xsd:complexType>
+ <xsd:attribute name="id" type="xsd:ID"/>
+ <xsd:attribute name="upSrc" type="xsd:string" use="required"/>
+ <xsd:attribute name="downSrc" type="xsd:string" use="required"/>
+ <xsd:attribute name="disabledSrc" type="xsd:string"/>
+ <xsd:attribute name="endsExtent" type="xsd:string" use="required"/>
+ <xsd:attribute name="font" type="xsd:IDREF" use="required"/>
+ <xsd:attribute name="downFont" type="xsd:IDREF"/>
+ <xsd:attribute name="disabledFont" type="xsd:IDREF"/>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="checkbox" minOccurs="0" maxOccurs="unbounded">
+ <xsd:complexType>
+ <xsd:attribute name="id" type="xsd:ID"/>
+ <xsd:attribute name="checkedUpSrc" type="xsd:string" use="required"/>
+ <xsd:attribute name="checkedDownSrc" type="xsd:string" use="required"/>
+ <xsd:attribute name="checkedDisabledSrc" type="xsd:string"/>
+ <xsd:attribute name="uncheckedUpSrc" type="xsd:string" use="required"/>
+ <xsd:attribute name="uncheckedDownSrc" type="xsd:string" use="required"/>
+ <xsd:attribute name="uncheckedDisabledSrc" type="xsd:string"/>
+ <xsd:attribute name="font" type="xsd:IDREF" use="required"/>
+ <xsd:attribute name="downFont" type="xsd:IDREF"/>
+ <xsd:attribute name="disabledFont" type="xsd:IDREF"/>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="mediacontrol" minOccurs="0" maxOccurs="unbounded">
+ <xsd:complexType>
+ <xsd:attribute name="id" type="xsd:ID"/>
+ <xsd:attribute name="playUpSrc" type="xsd:string" use="required"/>
+ <xsd:attribute name="playDownSrc" type="xsd:string" use="required"/>
+ <xsd:attribute name="playDisabledSrc" type="xsd:string"/>
+ <xsd:attribute name="pauseUpSrc" type="xsd:string" use="required"/>
+ <xsd:attribute name="pauseDownSrc" type="xsd:string" use="required"/>
+ <xsd:attribute name="pauseDisabledSrc" type="xsd:string"/>
+ <xsd:attribute name="font" type="xsd:IDREF" use="required"/>
+ <xsd:attribute name="timePos" type="xsd:string" use="required"/>
+ <xsd:attribute name="timeLeftPos" type="xsd:string" use="required"/>
+ <xsd:attribute name="barPos" type="xsd:string" use="required"/>
+ <xsd:attribute name="barRight" type="xsd:string" use="required"/>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="slider" minOccurs="0" maxOccurs="unbounded">
+ <xsd:complexType>
+ <xsd:all>
+ <xsd:element name="vertical" type="SliderDef" minOccurs="0" maxOccurs="1"/>
+ <xsd:element name="horizontal" type="SliderDef" minOccurs="0"
+ maxOccurs="1"/>
+ </xsd:all>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="scrollbar" minOccurs="0" maxOccurs="unbounded">
+ <xsd:complexType>
+ <xsd:all>
+ <xsd:element name="vertical" type="ScrollBarDef" minOccurs="0"
+ maxOccurs="1"/>
+ <xsd:element name="horizontal" type="ScrollBarDef" minOccurs="1"
+ maxOccurs="1"/>
+ </xsd:all>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="progressbar" minOccurs="0" maxOccurs="unbounded">
+ <xsd:complexType>
+ <xsd:all>
+ <xsd:element name="vertical" type="ProgressBarDef" minOccurs="0"
+ maxOccurs="1"/>
+ <xsd:element name="horizontal" type="ProgressBarDef" minOccurs="0"
+ maxOccurs="1"/>
+ </xsd:all>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="scrollarea" minOccurs="0" maxOccurs="unbounded">
+ <xsd:complexType>
+ <xsd:attribute name="id" type="xsd:ID"/>
+ <xsd:attribute name="scrollBarID" type="xsd:IDREF"/>
+ <xsd:attribute name="borderSrc" type="xsd:string"/>
+ <xsd:attribute name="borderEndsExtent" type="xsd:string"/>
+ <xsd:attribute name="margins" type="xsd:string"/>
+ <xsd:attribute name="friction" type="xsd:string"/>
+ <xsd:attribute name="sensitiveScrollBars" type="bool" use="required"/>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+</xsd:schema>
diff --git a/src/python/data/slider_horiz_track.png b/src/python/data/slider_horiz_track.png
new file mode 100644
index 0000000..6e233a5
--- /dev/null
+++ b/src/python/data/slider_horiz_track.png
Binary files differ
diff --git a/src/python/data/slider_horiz_track_disabled.png b/src/python/data/slider_horiz_track_disabled.png
new file mode 100644
index 0000000..01c880d
--- /dev/null
+++ b/src/python/data/slider_horiz_track_disabled.png
Binary files differ
diff --git a/src/python/data/slider_thumb_down.png b/src/python/data/slider_thumb_down.png
new file mode 100644
index 0000000..1f2acc2
--- /dev/null
+++ b/src/python/data/slider_thumb_down.png
Binary files differ
diff --git a/src/python/data/slider_thumb_up.png b/src/python/data/slider_thumb_up.png
new file mode 100644
index 0000000..885506d
--- /dev/null
+++ b/src/python/data/slider_thumb_up.png
Binary files differ
diff --git a/src/python/data/slider_vert_track.png b/src/python/data/slider_vert_track.png
new file mode 100644
index 0000000..51bac37
--- /dev/null
+++ b/src/python/data/slider_vert_track.png
Binary files differ
diff --git a/src/python/data/slider_vert_track_disabled.png b/src/python/data/slider_vert_track_disabled.png
new file mode 100644
index 0000000..bc8d7b6
--- /dev/null
+++ b/src/python/data/slider_vert_track_disabled.png
Binary files differ
diff --git a/src/python/enumcompat.py b/src/python/enumcompat.py
new file mode 100644
index 0000000..df859a5
--- /dev/null
+++ b/src/python/enumcompat.py
@@ -0,0 +1,37 @@
+# -*- coding: utf-8 -*-
+# libavg - Media Playback Engine.
+# Copyright (C) 2003-2014 Ulrich von Zadow
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Current versions can be found at www.libavg.de
+#
+
+import avg
+avg.KEYUP = avg.Event.KEY_UP
+avg.KEYDOWN = avg.Event.KEY_DOWN
+avg.CURSORMOTION = avg.Event.CURSOR_MOTION
+avg.CURSORUP = avg.Event.CURSOR_UP
+avg.CURSORDOWN = avg.Event.CURSOR_DOWN
+avg.CURSOROVER = avg.Event.CURSOR_OVER
+avg.CURSOROUT = avg.Event.CURSOR_OUT
+avg.CUSTOMEVENT = avg.Event.CUSTOM_EVENT
+
+avg.MOUSE = avg.Event.MOUSE
+avg.TOUCH = avg.Event.TOUCH
+avg.TRACK = avg.Event.TRACK
+avg.CUSTOM = avg.Event.CUSTOM
+avg.NONE = avg.Event.NONE
+
diff --git a/src/python/filter.py b/src/python/filter.py
new file mode 100644
index 0000000..f6c268b
--- /dev/null
+++ b/src/python/filter.py
@@ -0,0 +1,95 @@
+# -*- coding: utf-8 -*-
+# libavg - Media Playback Engine.
+# Copyright (C) 2003-2014 Ulrich von Zadow
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Current versions can be found at www.libavg.de
+#
+
+import math
+
+# Input filter based on:
+# Casiez, G., Roussel, N. and Vogel, D. (2012). 1€ Filter: A Simple Speed-based Low-pass
+# Filter for Noisy Input in Interactive Systems. Proceedings of the ACM Conference on
+# Human Factors in Computing Systems (CHI '12). Austin, Texas (May 5-12, 2012). New York:
+# ACM Press, pp. 2527-2530.
+
+class LowPassFilter(object):
+
+ def __init__(self, alpha):
+ self.__setAlpha(alpha)
+ self.__y = None
+ self.__s = None
+
+ def __setAlpha(self, alpha):
+ alpha = float(alpha)
+ if alpha <= 0 or alpha > 1.0:
+ raise RuntimeError("LowPassFilter alpha (%s) should be in (0.0, 1.0]"%alpha)
+ self.__alpha = alpha
+
+ def apply(self, value, timestamp=None, alpha=None):
+ if alpha is not None:
+ self.__setAlpha(alpha)
+ if self.__y is None:
+ s = value
+ else:
+ s = self.__alpha*value + (1.0-self.__alpha)*self.__s
+ self.__y = value
+ self.__s = s
+ return s
+
+ def lastValue(self):
+ return self.__y
+
+
+class OneEuroFilter(object):
+
+ def __init__(self, mincutoff=1.0, beta=0.0, dcutoff=1.0):
+ if mincutoff<=0:
+ raise ValueError("mincutoff should be >0")
+ if dcutoff<=0:
+ raise ValueError("dcutoff should be >0")
+ self.__freq = 60 # Initial freq, updated as soon as we have > 1 sample
+ self.__mincutoff = float(mincutoff)
+ self.__beta = float(beta)
+ self.__dcutoff = float(dcutoff)
+ self.__x = LowPassFilter(self.__alpha(self.__mincutoff))
+ self.__dx = LowPassFilter(self.__alpha(self.__dcutoff))
+ self.__lasttime = None
+
+ def __alpha(self, cutoff):
+ te = 1.0 / self.__freq
+ tau = 1.0 / (2*math.pi*cutoff)
+ return 1.0 / (1.0 + tau/te)
+
+ def apply(self, x, timestamp):
+ timestamp /= 1000.
+ if self.__lasttime == timestamp:
+ return x
+ else:
+ # ---- update the sampling frequency based on timestamps
+ if self.__lasttime and timestamp:
+ self.__freq = 1.0 / (timestamp-self.__lasttime)
+ self.__lasttime = timestamp
+ # ---- estimate the current variation per second
+ prev_x = self.__x.lastValue()
+ dx = 0.0 if prev_x is None else (x-prev_x)*self.__freq # FIXME: 0.0 or value?
+ edx = self.__dx.apply(dx, timestamp, alpha=self.__alpha(self.__dcutoff))
+ # ---- use it to update the cutoff frequency
+ cutoff = self.__mincutoff + self.__beta*math.fabs(edx)
+ # ---- filter the given value
+ return self.__x.apply(x, timestamp, alpha=self.__alpha(cutoff))
+
diff --git a/src/python/geom.py b/src/python/geom.py
new file mode 100644
index 0000000..5f6f98c
--- /dev/null
+++ b/src/python/geom.py
@@ -0,0 +1,202 @@
+# libavg - Media Playback Engine.
+# Copyright (C) 2003-2014 Ulrich von Zadow
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Current versions can be found at www.libavg.de
+#
+
+from libavg import avg
+
+class RoundedRect(avg.PolygonNode):
+ def __init__(self, size, radius, pos=(0,0), parent=None, **kwargs):
+ super(RoundedRect, self).__init__(**kwargs)
+ self.__pos = avg.Point2D(pos)
+ self.__size = avg.Point2D(size)
+ self.__radius = radius
+ self.__calcPolygon()
+ self.registerInstance(self, parent)
+
+ def getPos(self):
+ return self.__pos
+
+ def setPos(self, pos):
+ self.__pos = avg.Point2D(pos)
+ self.__calcPolygon()
+ polyPos = avg.PolygonNode.pos
+ pos = property(getPos, setPos)
+
+ def getSize(self):
+ return self.__size
+
+ def setSize(self, size):
+ self.__size = avg.Point2D(size)
+ self.__calcPolygon()
+ size = property(getSize, setSize)
+
+ def getRadius(self):
+ return self.__radius
+
+ def setRadius(self, radius):
+ self.__radius = radius
+ self.__calcPolygon()
+ radius = property(getRadius, setRadius)
+
+ def __calcPolygon(self):
+ def calcQuarterCircle(center, r, startAngle):
+ pos = []
+ for i in xrange(int(r)+1):
+ angle = i*(1.57/r)+startAngle
+ p = avg.Point2D(center)+avg.Point2D.fromPolar(angle, r)
+ pos.append(p)
+ return pos
+
+ r = self.__radius
+ if self.__size.x < r*2:
+ r = self.__size.x/2
+ if self.__size.y < r*2:
+ r = self.__size.y/2
+ if r == 0:
+ r = 0.01
+ pos = []
+ size = self.__size
+ pos.extend(calcQuarterCircle(self.pos+(size.x-r,r), r, -1.57))
+ pos.extend(calcQuarterCircle(self.pos+(size.x-r,size.y-r), r, 0))
+ pos.extend(calcQuarterCircle(self.pos+(r,size.y-r), r, 1.57))
+ pos.extend(calcQuarterCircle(self.pos+(r,r), r, 3.14))
+ self.polyPos = pos
+
+
+class PieSlice(avg.PolygonNode):
+ def __init__(self, radius, startangle, endangle, pos=(0,0), parent=None,
+ **kwargs):
+ super(PieSlice, self).__init__(**kwargs)
+ self.__pos = avg.Point2D(pos)
+ self.__radius = radius
+ self.__startangle = startangle
+ self.__endangle = endangle
+ self.__calcPolygon()
+ self.registerInstance(self, parent)
+
+ def getPos(self):
+ return self.__pos
+
+ def setPos(self, pos):
+ self.__pos = avg.Point2D(pos)
+ self.__calcPolygon()
+ polyPos = avg.PolygonNode.pos
+ pos = property(getPos, setPos)
+
+ def getRadius(self):
+ return self.__radius
+
+ def setRadius(self, radius):
+ self.__radius = radius
+ self.__calcPolygon()
+ radius = property(getRadius, setRadius)
+
+ def getStartAngle(self):
+ return self.__startangle
+
+ def setStartAngle(self, startangle):
+ self.__startangle = startangle
+ self.__calcPolygon()
+ startangle = property(getStartAngle, setStartAngle)
+
+ def getEndAngle(self):
+ return self.__endangle
+
+ def setEndAngle(self, endangle):
+ self.__endangle = endangle
+ self.__calcPolygon()
+ endangle = property(getEndAngle, setEndAngle)
+
+ def __calcPolygon(self):
+
+ def getCirclePoint(i):
+ angle = self.__startangle + (self.__endangle-self.__startangle)*i
+ return avg.Point2D(self.__pos)+avg.Point2D.fromPolar(angle, self.__radius)
+
+ pos = []
+ circlePart = (self.__endangle - self.__startangle)/6.28
+ numPoints = self.__radius*2.*circlePart
+ if numPoints < 4:
+ numPoints = 4
+ for i in xrange(0, int(numPoints)):
+ pos.append(getCirclePoint(i/numPoints))
+ pos.append(getCirclePoint(1))
+ pos.append(self.__pos)
+ self.polyPos = pos
+
+
+class Arc(avg.PolyLineNode):
+ # TODO: Code duplication with PieSlice
+ def __init__(self, radius, startangle, endangle, pos=(0,0), parent=None,
+ **kwargs):
+ super(Arc, self).__init__(**kwargs)
+ self.__pos = avg.Point2D(pos)
+ self.__radius = radius
+ self.__startangle = startangle
+ self.__endangle = endangle
+ self.__calcPolygon()
+ self.registerInstance(self, parent)
+
+ def getPos(self):
+ return self.__pos
+
+ def setPos(self, pos):
+ self.__pos = avg.Point2D(pos)
+ self.__calcPolygon()
+ polyPos = avg.PolyLineNode.pos
+ pos = property(getPos, setPos)
+
+ def getRadius(self):
+ return self.__radius
+
+ def setRadius(self, radius):
+ self.__radius = radius
+ self.__calcPolygon()
+ radius = property(getRadius, setRadius)
+
+ def getStartAngle(self):
+ return self.__startangle
+
+ def setStartAngle(self, startangle):
+ self.__startangle = startangle
+ self.__calcPolygon()
+ startangle = property(getStartAngle, setStartAngle)
+
+ def getEndAngle(self):
+ return self.__endangle
+
+ def setEndAngle(self, endangle):
+ self.__endangle = endangle
+ self.__calcPolygon()
+ endangle = property(getEndAngle, setEndAngle)
+
+ def __calcPolygon(self):
+
+ def getCirclePoint(i):
+ angle = self.__startangle + (self.__endangle-self.__startangle)*i
+ return avg.Point2D(self.__pos)+avg.Point2D.fromPolar(angle, self.__radius)
+
+ pos = []
+ circlePart = (self.__endangle - self.__startangle)/6.28
+ numPoints = self.__radius*2.*circlePart
+ for i in xrange(0, int(numPoints)):
+ pos.append(getCirclePoint(i/numPoints))
+ pos.append(getCirclePoint(1))
+ self.polyPos = pos
+
diff --git a/src/python/gesture.py b/src/python/gesture.py
new file mode 100644
index 0000000..0334e26
--- /dev/null
+++ b/src/python/gesture.py
@@ -0,0 +1,1000 @@
+# -*- coding: utf-8 -*-
+# libavg - Media Playback Engine.
+# Copyright (C) 2003-2014 Ulrich von Zadow
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Current versions can be found at www.libavg.de
+#
+
+from libavg import avg, statemachine, player, filter
+
+import weakref
+
+import math
+
+class Recognizer(avg.Publisher):
+
+ POSSIBLE = avg.Publisher.genMessageID()
+ DETECTED = avg.Publisher.genMessageID()
+ FAILED = avg.Publisher.genMessageID()
+ MOTION = avg.Publisher.genMessageID()
+ UP = avg.Publisher.genMessageID()
+ END = avg.Publisher.genMessageID()
+
+ def __init__(self, node, isContinuous, maxContacts, initialEvent,
+ possibleHandler=None, failHandler=None, detectedHandler=None,
+ endHandler=None):
+ super(Recognizer, self).__init__()
+
+ if node:
+ self.__node = weakref.ref(node)
+ else:
+ self.__node = None
+ self.__isContinuous = isContinuous
+ self.__maxContacts = maxContacts
+
+ self.__setEventHandler()
+ self.__isEnabled = True
+ self._contacts = set()
+ self.__dirty = False
+
+ self.publish(Recognizer.POSSIBLE)
+ self.publish(Recognizer.DETECTED)
+ self.publish(Recognizer.FAILED)
+ self.publish(Recognizer.END)
+ self.__stateMachine = statemachine.StateMachine(str(type(self)), "IDLE")
+ if self.__isContinuous:
+ self.publish(Recognizer.MOTION)
+ self.publish(Recognizer.UP)
+ self.__stateMachine.addState("IDLE", ("POSSIBLE", "RUNNING"))
+ self.__stateMachine.addState("POSSIBLE", ("IDLE", "RUNNING"))
+ self.__stateMachine.addState("RUNNING", ("IDLE",))
+ else:
+ self.__stateMachine.addState("IDLE", ("POSSIBLE",))
+ self.__stateMachine.addState("POSSIBLE", ("IDLE",))
+
+ self.subscribe(Recognizer.POSSIBLE, possibleHandler)
+ self.subscribe(Recognizer.FAILED, failHandler)
+ self.subscribe(Recognizer.DETECTED, detectedHandler)
+ self.subscribe(Recognizer.END, endHandler)
+ # self.__stateMachine.traceChanges(True)
+ self.__frameHandlerID = None
+
+ if initialEvent:
+ self.__onDown(initialEvent)
+
+ @property
+ def contacts(self):
+ return list(self._contacts)
+
+ def abort(self):
+ if self.__isEnabled:
+ self.__abort()
+ self.__setEventHandler()
+
+ def enable(self, isEnabled):
+ if bool(isEnabled) != self.__isEnabled:
+ self.__isEnabled = bool(isEnabled)
+ if isEnabled:
+ self.__setEventHandler()
+ else:
+ self.__abort()
+
+ def isEnabled(self):
+ return self.__isEnabled
+
+ def getState(self):
+ return self.__stateMachine.state
+
+ def _setPossible(self, event):
+ self.__stateMachine.changeState("POSSIBLE")
+ self.notifySubscribers(Recognizer.POSSIBLE, [])
+
+ def _setFail(self, event):
+ assert(self.__stateMachine.state != "RUNNING")
+ if self.__stateMachine.state != "IDLE":
+ self.__stateMachine.changeState("IDLE")
+ self._disconnectContacts()
+ self.notifySubscribers(Recognizer.FAILED, [])
+
+ def _setDetected(self, event):
+ if self.__isContinuous:
+ self.__stateMachine.changeState("RUNNING")
+ else:
+ self.__stateMachine.changeState("IDLE")
+ self.notifySubscribers(Recognizer.DETECTED, [])
+
+ def _setEnd(self, event):
+ assert(self.__stateMachine.state != "POSSIBLE")
+ if self.__stateMachine.state != "IDLE":
+ self.__stateMachine.changeState("IDLE")
+ self.notifySubscribers(Recognizer.END, [])
+
+ def __onDown(self, event):
+ nodeGone = self._handleNodeGone()
+ if event.contact and not(nodeGone):
+ if (self.__maxContacts == None or len(self._contacts) <
+ self.__maxContacts):
+ event.contact.subscribe(avg.Contact.CURSOR_MOTION, self.__onMotion)
+ event.contact.subscribe(avg.Contact.CURSOR_UP, self.__onUp)
+ self._contacts.add(event.contact)
+ if len(self._contacts) == 1:
+ self.__frameHandlerID = player.subscribe(player.ON_FRAME,
+ self._onFrame)
+ self.__dirty = True
+ return self._handleDown(event)
+
+ def __onMotion(self, event):
+ nodeGone = self._handleNodeGone()
+ if event.contact and not(nodeGone):
+ self.__dirty = True
+ self._handleMove(event)
+
+ def __onUp(self, event):
+ nodeGone = self._handleNodeGone()
+ if event.contact and not(nodeGone):
+ self.__dirty = True
+ self._contacts.remove(event.contact)
+ if len(self._contacts) == 0:
+ player.unsubscribe(player.ON_FRAME, self.__frameHandlerID)
+ self.__frameHandlerID = None
+ self._handleUp(event)
+
+ def __abort(self):
+ if self.__stateMachine.state != "IDLE":
+ self.__stateMachine.changeState("IDLE")
+ if len(self._contacts) != 0:
+ self._disconnectContacts()
+ if self.__node and self.__node():
+ self.__node().unsubscribe(avg.Node.CURSOR_DOWN, self.__onDown)
+
+ def _disconnectContacts(self):
+ for contact in self._contacts:
+ contact.unsubscribe(avg.Contact.CURSOR_MOTION, self.__onMotion)
+ contact.unsubscribe(avg.Contact.CURSOR_UP, self.__onUp)
+ self._contacts = set()
+ if self.__frameHandlerID:
+ player.unsubscribe(player.ON_FRAME, self.__frameHandlerID)
+ self.__frameHandlerID = None
+
+ def _handleDown(self, event):
+ pass
+
+ def _handleMove(self, event):
+ pass
+
+ def _handleUp(self, event):
+ pass
+
+ def _handleChange(self):
+ pass
+
+ def _onFrame(self):
+ nodeGone = self._handleNodeGone()
+ if not(nodeGone) and self.__dirty:
+ self._handleChange()
+ self.__dirty = False
+
+ def _handleNodeGone(self):
+ if self.__node and not(self.__node()):
+ self.enable(False)
+ return True
+ else:
+ return False
+
+ def __setEventHandler(self):
+ if self.__node and self.__node():
+ self.__node().subscribe(avg.Node.CURSOR_DOWN, self.__onDown)
+
+
+class TapRecognizer(Recognizer):
+
+ MAX_TAP_DIST = None
+
+ def __init__(self, node, maxTime=None, maxDist=None, initialEvent=None,
+ possibleHandler=None, failHandler=None, detectedHandler=None):
+ self.__maxTime = maxTime
+ if maxDist == None:
+ maxDist = TapRecognizer.MAX_TAP_DIST
+ self.__maxDist = maxDist
+ super(TapRecognizer, self).__init__(node, False, 1, initialEvent,
+ possibleHandler, failHandler, detectedHandler)
+
+ def _handleDown(self, event):
+ self._setPossible(event)
+ self.__startTime = player.getFrameTime()
+
+ def _handleMove(self, event):
+ if self.getState() != "IDLE":
+ if (event.contact.distancefromstart >
+ self.__maxDist*player.getPixelsPerMM()):
+ self._setFail(event)
+
+ def _handleUp(self, event):
+ if self.getState() == "POSSIBLE":
+ if (event.contact.distancefromstart >
+ self.__maxDist*player.getPixelsPerMM()):
+ self._setFail(event)
+ else:
+ self._setDetected(event)
+
+ def _onFrame(self):
+ downTime = player.getFrameTime() - self.__startTime
+ if self.getState() == "POSSIBLE":
+ if self.__maxTime and downTime > self.__maxTime:
+ self._setFail(None)
+ super(TapRecognizer, self)._onFrame()
+
+
+class DoubletapRecognizer(Recognizer):
+
+ MAX_DOUBLETAP_TIME = None
+
+ def __init__(self, node, maxTime=None, maxDist=None, initialEvent=None,
+ possibleHandler=None, failHandler=None, detectedHandler=None):
+ if maxTime == None:
+ maxTime = DoubletapRecognizer.MAX_DOUBLETAP_TIME
+ self.__maxTime = maxTime
+ if maxDist == None:
+ maxDist = TapRecognizer.MAX_TAP_DIST
+ self.__maxDist = maxDist
+
+ self.__stateMachine = statemachine.StateMachine("DoubletapRecognizer", "IDLE")
+ self.__stateMachine.addState("IDLE", ("DOWN1",), enterFunc=self.__enterIdle)
+ self.__stateMachine.addState("DOWN1", ("UP1", "IDLE"))
+ self.__stateMachine.addState("UP1", ("DOWN2", "IDLE"))
+ self.__stateMachine.addState("DOWN2", ("IDLE",))
+ #self.__stateMachine.traceChanges(True)
+ self.__frameHandlerID = None
+ super(DoubletapRecognizer, self).__init__(node, False, 1,
+ initialEvent, possibleHandler, failHandler, detectedHandler)
+
+ def abort(self):
+ if self.__stateMachine.state != "IDLE":
+ self.__stateMachine.changeState("IDLE")
+ super(DoubletapRecognizer, self).abort()
+
+ def enable(self, isEnabled):
+ if self.__stateMachine.state != "IDLE":
+ self.__stateMachine.changeState("IDLE")
+ super(DoubletapRecognizer, self).enable(isEnabled)
+
+ def _handleDown(self, event):
+ self.__startTime = player.getFrameTime()
+ if self.__stateMachine.state == "IDLE":
+ self.__frameHandlerID = player.subscribe(player.ON_FRAME, self.__onFrame)
+ self.__stateMachine.changeState("DOWN1")
+ self.__startPos = event.pos
+ self._setPossible(event)
+ elif self.__stateMachine.state == "UP1":
+ if ((event.pos - self.__startPos).getNorm() >
+ self.__maxDist*player.getPixelsPerMM()):
+ self.__stateMachine.changeState("IDLE")
+ self._setFail(event)
+ else:
+ self.__stateMachine.changeState("DOWN2")
+ else:
+ assert(False), self.__stateMachine.state
+
+ def _handleMove(self, event):
+ if self.__stateMachine.state != "IDLE":
+ if ((event.pos - self.__startPos).getNorm() >
+ self.__maxDist*player.getPixelsPerMM()):
+ self.__stateMachine.changeState("IDLE")
+ self._setFail(event)
+
+ def _handleUp(self, event):
+ if self.__stateMachine.state == "DOWN1":
+ self.__startTime = player.getFrameTime()
+ self.__stateMachine.changeState("UP1")
+ elif self.__stateMachine.state == "DOWN2":
+ if ((event.pos - self.__startPos).getNorm() >
+ self.__maxDist*player.getPixelsPerMM()):
+ self._setFail(event)
+ else:
+ self._setDetected(event)
+ self.__stateMachine.changeState("IDLE")
+ elif self.__stateMachine.state == "IDLE":
+ pass
+ else:
+ assert(False), self.__stateMachine.state
+
+ def __onFrame(self):
+ downTime = player.getFrameTime() - self.__startTime
+ if downTime > self.__maxTime:
+ self._setFail(None)
+ self.__stateMachine.changeState("IDLE")
+
+ def __enterIdle(self):
+ player.unsubscribe(player.ON_FRAME, self.__frameHandlerID)
+
+
+class SwipeRecognizer(Recognizer):
+
+ LEFT = 1
+ RIGHT = 2
+ UP = 3
+ DOWN = 4
+
+ SWIPE_DIRECTION_TOLERANCE = math.pi/8
+ MIN_SWIPE_DIST = 50
+ MAX_SWIPE_CONTACT_DIST = 100
+
+ def __init__(self, node, direction, numContacts=1, initialEvent=None,
+ directionTolerance=SWIPE_DIRECTION_TOLERANCE, minDist=MIN_SWIPE_DIST,
+ maxContactDist=MAX_SWIPE_CONTACT_DIST,
+ possibleHandler=None, failHandler=None, detectedHandler=None):
+
+ self.__numContacts = numContacts
+ self.__angleWanted = self.__angleFromDirection(direction)
+ self.__directionTolerance = directionTolerance
+ self.__minDist = minDist*player.getPixelsPerMM()
+ self.__maxInterContactDist = maxContactDist*player.getPixelsPerMM()
+ super(SwipeRecognizer, self).__init__(node, False, numContacts,
+ initialEvent, possibleHandler=possibleHandler, failHandler=failHandler,
+ detectedHandler=detectedHandler)
+
+ def _handleDown(self, event):
+ if len(self._contacts) == 1:
+ self.__startPos = event.pos
+ else:
+ if (event.pos-self.__startPos).getNorm() > self.__maxInterContactDist:
+ self._setFail(event)
+ return
+ if len(self._contacts) == self.__numContacts:
+ self._setPossible(event)
+
+ def _handleMove(self, event):
+ pass
+
+ def _handleUp(self, event):
+ if self.getState() == "POSSIBLE":
+ if (event.contact.distancefromstart < self.__minDist or
+ not(self.__isValidAngle(event.contact.motionangle))):
+ self._setFail(event)
+ elif len(self._contacts) == 0:
+ self._setDetected(event)
+
+ def __angleFromDirection(self, direction):
+ if direction == SwipeRecognizer.RIGHT:
+ return 0
+ elif direction == SwipeRecognizer.DOWN:
+ return math.pi/2
+ elif direction == SwipeRecognizer.LEFT:
+ return math.pi
+ elif direction == SwipeRecognizer.UP:
+ return 3*math.pi/2
+ else:
+ raise RuntimeError("%s is not a valid direction."%direction)
+
+ def __isValidAngle(self, angle):
+ if angle < 0:
+ angle += 2*math.pi
+ minAngle = self.__angleWanted - self.__directionTolerance
+ maxAngle = self.__angleWanted + self.__directionTolerance
+ if minAngle >= 0:
+ return angle > minAngle and angle < maxAngle
+ else:
+ # Valid range spans 0
+ return angle > minAngle+2*math.pi or angle < maxAngle
+
+
+class HoldRecognizer(Recognizer):
+
+ HOLD_DELAY = None
+
+ def __init__(self, node, delay=None, maxDist=None, initialEvent=None,
+ possibleHandler=None, failHandler=None,
+ detectedHandler=None, stopHandler=None):
+ if delay == None:
+ delay = HoldRecognizer.HOLD_DELAY
+ self.__delay = delay
+ if maxDist == None:
+ maxDist = TapRecognizer.MAX_TAP_DIST
+ self.__maxDist = maxDist
+
+ self.__lastEvent = None
+ super(HoldRecognizer, self).__init__(node, True, 1, initialEvent,
+ possibleHandler, failHandler, detectedHandler, stopHandler)
+
+ def _handleDown(self, event):
+ self.__lastEvent = event
+ self._setPossible(event)
+ self.__startTime = player.getFrameTime()
+
+ def _handleMove(self, event):
+ self.__lastEvent = event
+ if self.getState() == "POSSIBLE":
+ if (event.contact.distancefromstart >
+ self.__maxDist*player.getPixelsPerMM()):
+ self._setFail(event)
+
+ def _handleUp(self, event):
+ self.__lastEvent = event
+ if self.getState() == "POSSIBLE":
+ self._setFail(event)
+ elif self.getState() == "RUNNING":
+ self._setEnd(event)
+
+ def _onFrame(self):
+ downTime = player.getFrameTime() - self.__startTime
+ if self.getState() == "POSSIBLE":
+ if downTime > self.__delay:
+ self._setDetected(self.__lastEvent)
+ super(HoldRecognizer, self)._onFrame()
+
+
+class DragRecognizer(Recognizer):
+
+ ANY_DIRECTION = 0
+ VERTICAL = 1
+ HORIZONTAL = 2
+
+ DIRECTION_TOLERANCE = math.pi/4
+ MIN_DRAG_DIST = None
+ FRICTION = None
+
+ def __init__(self, eventNode, coordSysNode=None, initialEvent=None,
+ direction=ANY_DIRECTION, directionTolerance=DIRECTION_TOLERANCE,
+ friction=None, minDragDist=None,
+ possibleHandler=None, failHandler=None, detectedHandler=None,
+ moveHandler=None, upHandler=None, endHandler=None):
+
+ if coordSysNode != None:
+ self.__coordSysNode = weakref.ref(coordSysNode)
+ else:
+ self.__coordSysNode = weakref.ref(eventNode)
+ self.__direction = direction
+ self.__directionTolerance = directionTolerance
+
+ if minDragDist != None:
+ self.__minDragDist = minDragDist
+ else:
+ if self.__direction == DragRecognizer.ANY_DIRECTION:
+ self.__minDragDist = 0
+ else:
+ self.__minDragDist = DragRecognizer.MIN_DRAG_DIST
+
+ if friction == None:
+ self.__friction = DragRecognizer.FRICTION
+ else:
+ self.__friction = friction
+
+ self.__isSliding = False
+ self.__inertiaHandler = None
+ super(DragRecognizer, self).__init__(eventNode, True, 1,
+ initialEvent, possibleHandler=possibleHandler, failHandler=failHandler,
+ detectedHandler=detectedHandler, endHandler=endHandler)
+ self.subscribe(Recognizer.MOTION, moveHandler)
+ self.subscribe(Recognizer.UP, upHandler)
+
+ def abort(self):
+ if self.__inertiaHandler:
+ self.__inertiaHandler.abort()
+ self.__inertiaHandler = None
+ super(DragRecognizer, self).abort()
+
+ def _handleDown(self, event):
+ if not self._handleCoordSysNodeUnlinked():
+ if self.__inertiaHandler:
+ self.__inertiaHandler.abort()
+ self._setEnd(event)
+ if self.__friction != -1:
+ self.__inertiaHandler = InertiaHandler(self.__friction,
+ self.__onInertiaMove, self.__onInertiaStop)
+ if self.__minDragDist == 0:
+ self._setDetected(event)
+ else:
+ self._setPossible(event)
+ pos = self.__relEventPos(event)
+ self.__dragStartPos = pos
+ self.__lastPos = pos
+
+ def _handleMove(self, event):
+ if not self._handleCoordSysNodeUnlinked():
+ if self.getState() != "IDLE":
+ pos = self.__relEventPos(event)
+ offset = pos - self.__dragStartPos
+ if self.getState() == "RUNNING":
+ self.notifySubscribers(Recognizer.MOTION, [offset]);
+ else:
+ if offset.getNorm() > self.__minDragDist*player.getPixelsPerMM():
+ if self.__angleFits(offset):
+ self._setDetected(event)
+ self.notifySubscribers(Recognizer.MOTION, [offset]);
+ else:
+ self.__fail(event)
+ if self.__inertiaHandler:
+ self.__inertiaHandler.onDrag(Transform(pos - self.__lastPos))
+ self.__lastPos = pos
+
+ def _handleUp(self, event):
+ if not self._handleCoordSysNodeUnlinked():
+ if self.getState() != "IDLE":
+ pos = self.__relEventPos(event)
+ if self.getState() == "RUNNING":
+ self.__offset = pos - self.__dragStartPos
+ self.notifySubscribers(Recognizer.UP, [self.__offset]);
+ if self.__friction != -1:
+ self.__isSliding = True
+ self.__inertiaHandler.onDrag(Transform(pos - self.__lastPos))
+ self.__inertiaHandler.onUp()
+ else:
+ self._setEnd(event)
+ else:
+ self.__fail(event)
+
+ def _handleCoordSysNodeUnlinked(self):
+ if self.__coordSysNode().getParent():
+ return False
+ else:
+ self.abort()
+ return True
+
+ def __fail(self, event):
+ self._setFail(event)
+ if self.__inertiaHandler:
+ self.__inertiaHandler.abort()
+ self.__inertiaHandler = None
+
+ def __onInertiaMove(self, transform):
+ self.__offset += transform.trans
+ self.notifySubscribers(Recognizer.MOTION, [self.__offset]);
+
+ def __onInertiaStop(self):
+ self.__inertiaHandler = None
+ self.__isSliding = False
+ if self.getState() == "POSSIBLE":
+ self._setFail(None)
+ else:
+ self._setEnd(None)
+
+ def __relEventPos(self, event):
+ return self.__coordSysNode().getParent().getRelPos(event.pos)
+
+ def __angleFits(self, offset):
+ angle = offset.getAngle()
+ if angle < 0:
+ angle = -angle
+ if self.__direction == DragRecognizer.VERTICAL:
+ return (angle > math.pi/2-self.__directionTolerance
+ and angle < math.pi/2+self.__directionTolerance)
+ elif self.__direction == DragRecognizer.HORIZONTAL:
+ return (angle < self.__directionTolerance
+ or angle > math.pi-self.__directionTolerance)
+ else:
+ return True
+
+class Mat3x3:
+ # Internal class. Will be removed again.
+
+ def __init__(self, row0=(1,0,0), row1=(0,1,0), row2=(0,0,1)):
+ self.m = [row0, row1, row2]
+
+ @classmethod
+ def translate(cls, t):
+ return Mat3x3([1, 0, t[0]],
+ [0, 1, t[1]])
+
+ @classmethod
+ def rotate(cls, a):
+ return Mat3x3([math.cos(a), -math.sin(a), 0],
+ [math.sin(a), math.cos(a), 0])
+
+ @classmethod
+ def pivotRotate(cls, t, a):
+ rot = Mat3x3.rotate(a)
+ trans = Mat3x3.translate(t)
+ return trans.applyMat(rot.applyMat(trans.inverse()))
+
+ @classmethod
+ def scale(cls, s):
+ return Mat3x3([s[0], 0, 0],
+ [0, s[1], 0])
+
+ @classmethod
+ def fromNode(cls, node):
+ return Mat3x3.translate(node.pos).applyMat(
+ Mat3x3.translate(node.pivot).applyMat(
+ Mat3x3.rotate(node.angle).applyMat(
+ Mat3x3.translate(-node.pivot).applyMat(
+ Mat3x3.scale(node.size)))))
+
+ def setNodeTransform(self, node):
+ v = self.applyVec([1,0,0])
+ rot = avg.Point2D(v[0], v[1]).getAngle()
+ node.angle = rot
+ if self.getScale().x < 9999 and self.getScale().y < 9999:
+ node.size = self.getScale()
+ else:
+ node.size = (0,0)
+ node.pivot = node.size/2
+ v = self.applyVec([0,0,1])
+ node.pos = (avg.Point2D(v[0], v[1]) + (node.pivot).getRotated(node.angle) -
+ node.pivot)
+
+ def getScale(self):
+ v = self.applyVec([1,0,0])
+ xscale = avg.Point2D(v[0], v[1]).getNorm()
+ v = self.applyVec([0,1,0])
+ yscale = avg.Point2D(v[0], v[1]).getNorm()
+ return avg.Point2D(xscale, yscale)
+
+ def __str__(self):
+ return self.m.__str__()
+
+ def applyVec(self, v):
+ m = self.m
+ v1 = []
+ for i in range(3):
+ v1.append(m[i][0]*v[0] + m[i][1]*v[1] + m[i][2]*v[2])
+ return v1
+
+ def applyMat(self, m1):
+ m0 = self.m
+ result = Mat3x3()
+ for i in range(3):
+ v = []
+ for j in range(3):
+ v.append(m0[i][0]*m1.m[0][j] + m0[i][1]*m1.m[1][j] + m0[i][2]*m1.m[2][j])
+ result.m[i] = v
+ return result
+
+ def det(self):
+ m = self.m
+ return float( m[0][0] * (m[2][2]*m[1][1]-m[2][1]*m[1][2])
+ -m[1][0] * (m[2][2]*m[0][1]-m[2][1]*m[0][2])
+ +m[2][0] * (m[1][2]*m[0][1]-m[1][1]*m[0][2]))
+
+ def scalarMult(self, s):
+ m = self.m
+ result = Mat3x3()
+ for i in range(3):
+ v = []
+ for j in range(3):
+ v.append(m[i][j]*s)
+ result.m[i] = v
+ return result
+
+ def inverse(self):
+ m = self.m
+ temp = Mat3x3([ m[2][2]*m[1][1]-m[2][1]*m[1][2], -(m[2][2]*m[0][1]-m[2][1]*m[0][2]), m[1][2]*m[0][1]-m[1][1]*m[0][2] ],
+ [-(m[2][2]*m[1][0]-m[2][0]*m[1][2]), m[2][2]*m[0][0]-m[2][0]*m[0][2] , -(m[1][2]*m[0][0]-m[1][0]*m[0][2])],
+ [ m[2][1]*m[1][0]-m[2][0]*m[1][1], -(m[2][1]*m[0][0]-m[2][0]*m[0][1]), m[1][1]*m[0][0]-m[1][0]*m[0][1] ])
+ return temp.scalarMult(1/self.det())
+
+
+def getCentroid(indexes, pts):
+ c = avg.Point2D(0, 0)
+ for i in indexes:
+ c += pts[i]
+ return c/len(indexes)
+
+def calcKMeans(pts):
+
+ # in: List of points
+ # out: Two lists, each containing indexes into the input list
+ assert(len(pts) > 1)
+ p1 = pts[0]
+ p2 = pts[1]
+ oldP1 = None
+ oldP2 = None
+ j = 0
+ while not(p1 == oldP1 and p2 == oldP2) and j < 50:
+ l1 = []
+ l2 = []
+ # Group points
+ for i, pt in enumerate(pts):
+ dist1 = (pt-p1).getNorm()
+ dist2 = (pt-p2).getNorm()
+ if dist1 < dist2:
+ l1.append(i)
+ else:
+ l2.append(i)
+ oldP1 = p1
+ oldP2 = p2
+ p1 = getCentroid(l1, pts)
+ p2 = getCentroid(l2, pts)
+ j += 1
+ return l1, l2
+
+
+class Transform():
+ def __init__(self, trans, rot=0, scale=1, pivot=(0,0)):
+ self.trans = avg.Point2D(trans)
+ self.rot = rot
+ self.scale = scale
+ self.pivot = avg.Point2D(pivot)
+
+ def moveNode(self, node):
+ transMat = Mat3x3.translate(self.trans)
+ rotMat = Mat3x3.rotate(self.rot)
+ scaleMat = Mat3x3.scale((self.scale, self.scale))
+ pivotMat = Mat3x3.translate(self.pivot)
+ invPivotMat = pivotMat.inverse()
+ startTransform = Mat3x3.fromNode(node)
+ newTransform = pivotMat.applyMat(
+ rotMat.applyMat(
+ scaleMat.applyMat(
+ invPivotMat.applyMat(
+ transMat.applyMat(
+ startTransform)))))
+ newTransform.setNodeTransform(node)
+
+ def __repr__(self):
+ return "Transform"+str((self.trans, self.rot, self.scale, self.pivot))
+
+
+class TransformRecognizer(Recognizer):
+
+ FILTER_MIN_CUTOFF = None
+ FILTER_BETA = None
+
+ def __init__(self, eventNode, coordSysNode=None, initialEvent=None, friction=None,
+ detectedHandler=None, moveHandler=None, upHandler=None, endHandler=None):
+ if coordSysNode != None:
+ self.__coordSysNode = weakref.ref(coordSysNode)
+ else:
+ self.__coordSysNode = weakref.ref(eventNode)
+
+ if friction == None:
+ self.__friction = DragRecognizer.FRICTION
+ else:
+ self.__friction = friction
+
+ self.__baseTransform = Mat3x3()
+ self.__lastPosns = []
+ self.__posns = []
+ self.__inertiaHandler = None
+ self.__filters = {}
+ self.__frameHandlerID = None
+ super(TransformRecognizer, self).__init__(eventNode, True, None,
+ initialEvent, detectedHandler=detectedHandler, endHandler=endHandler)
+ self.subscribe(Recognizer.MOTION, moveHandler)
+ self.subscribe(Recognizer.UP, upHandler)
+
+ def enable(self, isEnabled):
+ if bool(isEnabled) != self.isEnabled() and not(isEnabled):
+ self.__abort()
+ super(TransformRecognizer, self).enable(isEnabled)
+
+ def abort(self):
+ self.__abort()
+ super(TransformRecognizer, self).abort()
+
+ def _handleDown(self, event):
+ numContacts = len(self._contacts)
+ self.__newPhase()
+ if self.__isFiltered():
+ self.__filters[event.contact] = [
+ filter.OneEuroFilter(mincutoff=TransformRecognizer.FILTER_MIN_CUTOFF,
+ beta=TransformRecognizer.FILTER_BETA),
+ filter.OneEuroFilter(mincutoff=TransformRecognizer.FILTER_MIN_CUTOFF,
+ beta=TransformRecognizer.FILTER_BETA)]
+ if numContacts == 1:
+ if self.__inertiaHandler:
+ self.__inertiaHandler.abort()
+ self._setEnd(event)
+ self._setDetected(event)
+ self.__frameHandlerID = player.subscribe(player.ON_FRAME, self.__onFrame)
+ if self.__friction != -1:
+ self.__inertiaHandler = InertiaHandler(self.__friction,
+ self.__onInertiaMove, self.__onInertiaStop)
+
+ def _handleUp(self, event):
+ numContacts = len(self._contacts)
+ if numContacts == 0:
+ contact = event.contact
+ transform = Transform(self.__filteredRelContactPos(contact)
+ - self.__lastPosns[0])
+ self.notifySubscribers(Recognizer.UP, [transform]);
+ player.unsubscribe(player.ON_FRAME, self.__frameHandlerID)
+ self.__frameHandlerID = None
+ if self.__friction != -1:
+ self.__inertiaHandler.onDrag(transform)
+ self.__inertiaHandler.onUp()
+ else:
+ self._setEnd(event)
+ elif numContacts == 1:
+ self.__newPhase()
+ else:
+ self.__newPhase()
+ if self.__isFiltered():
+ del self.__filters[event.contact]
+
+ def _handleNodeGone(self):
+ if self.__coordSysNode and not(self.__coordSysNode()):
+ self.enable(False)
+ return True
+ else:
+ return super(TransformRecognizer, self)._handleNodeGone()
+
+ def __onFrame(self):
+ nodeGone = self._handleNodeGone()
+ if not(nodeGone):
+ self.__move()
+
+ def __move(self):
+ numContacts = len(self._contacts)
+ contactPosns = [self.__filteredRelContactPos(contact)
+ for contact in self._contacts]
+ if numContacts == 1:
+ transform = Transform(contactPosns[0] - self.__lastPosns[0])
+ if self.__friction != -1:
+ self.__inertiaHandler.onDrag(transform)
+ self.notifySubscribers(Recognizer.MOTION, [transform]);
+ self.__lastPosns = contactPosns
+ else:
+ if numContacts == 2:
+ self.__posns = contactPosns
+ else:
+ self.__posns = [getCentroid(self.__clusters[i], contactPosns) for
+ i in range(2)]
+
+ startDelta = self.__lastPosns[1]-self.__lastPosns[0]
+ curDelta = self.__posns[1]-self.__posns[0]
+
+ pivot = (self.__posns[0]+self.__posns[1])/2
+
+ rot = avg.Point2D.angle(curDelta, startDelta)
+
+ if self.__lastPosns[0] == self.__lastPosns[1]:
+ scale = 1
+ else:
+ scale = ((self.__posns[0]-self.__posns[1]).getNorm() /
+ (self.__lastPosns[0]-self.__lastPosns[1]).getNorm())
+
+ trans = ((self.__posns[0]+self.__posns[1])/2 -
+ (self.__lastPosns[0]+self.__lastPosns[1])/2)
+ transform = Transform(trans, rot, scale, pivot)
+ if self.__friction != -1:
+ self.__inertiaHandler.onDrag(transform)
+ self.notifySubscribers(Recognizer.MOTION, [transform]);
+ self.__lastPosns = self.__posns
+
+ def __newPhase(self):
+ self.__lastPosns = []
+ numContacts = len(self._contacts)
+ contactPosns = [self.__relContactPos(contact)
+ for contact in self._contacts]
+ if numContacts == 1:
+ self.__lastPosns.append(contactPosns[0])
+ else:
+ if numContacts == 2:
+ self.__lastPosns = contactPosns
+ else:
+ self.__clusters = calcKMeans(contactPosns)
+ self.__lastPosns = [getCentroid(self.__clusters[i], contactPosns) for
+ i in range(2)]
+
+ def __onInertiaMove(self, transform):
+ self.notifySubscribers(Recognizer.MOTION, [transform]);
+
+ def __onInertiaStop(self):
+ self.__inertiaHandler = None
+ self._setEnd(None)
+
+ def __filteredRelContactPos(self, contact):
+ rawPos = self.__relContactPos(contact)
+ if self.__isFiltered():
+ f = self.__filters[contact]
+ return avg.Point2D(f[0].apply(rawPos.x, player.getFrameTime()),
+ f[1].apply(rawPos.y, player.getFrameTime()))
+ else:
+ return rawPos
+
+ def __relContactPos(self, contact):
+ return self.__coordSysNode().getParent().getRelPos(contact.events[-1].pos)
+
+ def __isFiltered(self):
+ return TransformRecognizer.FILTER_MIN_CUTOFF != None
+
+ def __abort(self):
+ if self.__frameHandlerID:
+ player.unsubscribe(player.ON_FRAME, self.__frameHandlerID)
+ self.__frameHandlerID = None
+ if self.__inertiaHandler:
+ self.__inertiaHandler.abort()
+ self.__inertiaHandler = None
+
+
+class InertiaHandler(object):
+ def __init__(self, friction, moveHandler, stopHandler):
+ self.__friction = friction
+ self.__moveHandler = moveHandler
+ self.__stopHandler = stopHandler
+
+ self.__transVel = avg.Point2D(0, 0)
+ self.__curPivot = avg.Point2D(0, 0)
+ self.__angVel = 0
+ self.__sizeVel = avg.Point2D(0, 0)
+ self.__frameHandlerID = player.subscribe(player.ON_FRAME, self.__onDragFrame)
+
+ def abort(self):
+ player.unsubscribe(player.ON_FRAME, self.__frameHandlerID)
+ self.__stopHandler = None
+ self.__moveHandler = None
+
+ def onDrag(self, transform):
+ frameDuration = player.getFrameDuration()
+ if frameDuration > 0:
+ self.__transVel += 0.1*transform.trans/frameDuration
+ if transform.pivot != avg.Point2D(0,0):
+ self.__curPivot = transform.pivot
+ if transform.rot > math.pi:
+ transform.rot -= 2*math.pi
+ if frameDuration > 0:
+ self.__angVel += 0.1*transform.rot/frameDuration
+
+ def onUp(self):
+ player.unsubscribe(player.ON_FRAME, self.__frameHandlerID)
+ self.__frameHandlerID = player.subscribe(player.ON_FRAME, self.__onInertiaFrame)
+ self.__onInertiaFrame()
+
+ def __onDragFrame(self):
+ self.__transVel *= 0.9
+ self.__angVel *= 0.9
+
+ def __onInertiaFrame(self):
+ transNorm = self.__transVel.getNorm()
+ if transNorm - self.__friction > 0:
+ direction = self.__transVel.getNormalized()
+ self.__transVel = direction * (transNorm-self.__friction)
+ curTrans = self.__transVel * player.getFrameDuration()
+ else:
+ curTrans = avg.Point2D(0, 0)
+
+ if self.__angVel != 0:
+ angSign = self.__angVel/math.fabs(self.__angVel)
+ self.__angVel = self.__angVel - angSign*self.__friction/200
+ newAngSign = self.__angVel/math.fabs(self.__angVel)
+ if newAngSign != angSign:
+ self.__angVel = 0
+ curAng = self.__angVel * player.getFrameDuration()
+ self.__curPivot += curTrans
+
+ if transNorm - self.__friction > 0 or self.__angVel != 0:
+ if self.__moveHandler:
+ self.__moveHandler(Transform(curTrans, curAng, 1, self.__curPivot))
+ else:
+ self.__stop()
+
+ def __stop(self):
+ player.unsubscribe(player.ON_FRAME, self.__frameHandlerID)
+ self.__stopHandler()
+ self.__stopHandler = None
+ self.__moveHandler = None
+
+
+def initConfig():
+ def getFloatOption(name):
+ return float(player.getConfigOption("gesture", name))
+
+ TapRecognizer.MAX_TAP_DIST = getFloatOption("maxtapdist")
+ DoubletapRecognizer.MAX_DOUBLETAP_TIME = getFloatOption("maxdoubletaptime")
+ SwipeRecognizer.MIN_SWIPE_DIST = getFloatOption("minswipedist")
+ SwipeRecognizer.SWIPE_DIRECTION_TOLERANCE = getFloatOption("swipedirectiontolerance")
+ SwipeRecognizer.MAX_SWIPE_CONTACT_DIST = getFloatOption("maxswipecontactdist")
+ HoldRecognizer.HOLD_DELAY = getFloatOption("holddelay")
+ DragRecognizer.MIN_DRAG_DIST = getFloatOption("mindragdist")
+ DragRecognizer.FRICTION = getFloatOption("friction")
+ TransformRecognizer.FILTER_MIN_CUTOFF = getFloatOption("filtermincutoff")
+ if TransformRecognizer.FILTER_MIN_CUTOFF == -1:
+ TransformRecognizer.FILTER_MIN_CUTOFF = None
+ TransformRecognizer.FILTER_BETA = getFloatOption("filterbeta")
+
+
+initConfig()
diff --git a/src/python/graph.py b/src/python/graph.py
new file mode 100644
index 0000000..9be9d6d
--- /dev/null
+++ b/src/python/graph.py
@@ -0,0 +1,229 @@
+# libavg - Media Playback Engine.
+# Copyright (C) 2003-2014 Ulrich von Zadow
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Current versions can be found at www.libavg.de
+
+import math
+import time
+
+from libavg import avg, player, Point2D
+
+
+class Graph(avg.DivNode):
+ def __init__(self, title='', getValue=None, parent=None, **kwargs):
+ super(Graph, self).__init__(**kwargs)
+ self.registerInstance(self, parent)
+
+ self._getValue = getValue
+ self._xSkip = 2
+ self._curUsage = 0
+ self.sensitive = False
+
+ avg.RectNode(parent=self, strokewidth=0, fillopacity=0.6, fillcolor="FFFFFF",
+ size=self.size)
+ self._textNode0 = avg.WordsNode(parent=self, x=10, y=self.size.y - 22,
+ color="000080")
+ self._textNode1 = avg.WordsNode(parent=self, x=10, y=self.size.y - 39,
+ color="000080")
+ self._maxLineNode = avg.PolyLineNode(parent=self, color="880000")
+ self._lineNode = avg.PolyLineNode(parent=self, color="008000")
+ self.__graphText = avg.WordsNode(parent=self, x=10, y=0, color="000080")
+ self.__graphText.text = title
+ self._setup()
+
+ def _setup(self):
+ raise RuntimeError('Please overload _setup() function')
+
+
+class AveragingGraph(Graph):
+
+ def __init__(self, title='', getValue=None, parent=None, **kwargs):
+ super(AveragingGraph, self).__init__(title, getValue, parent, **kwargs)
+ self.registerInstance(self, None)
+
+ def unlink(self, kill):
+ player.clearInterval(self.__interval)
+ self.__interval = None
+ super(AveragingGraph, self).unlink(kill)
+
+ def _setup(self):
+ self.__interval = player.setInterval(1000, self._nextMemSample)
+ self.__numSamples = 0
+ self._usage = [0]
+ self._maxUsage = [0]
+ self._minutesUsage = [0]
+ self._minutesMaxUsage = [0]
+ self._nextMemSample()
+
+ def _nextMemSample(self):
+ curUsage = self._getValue()
+ self._usage.append(curUsage)
+ maxUsage = self._maxUsage[-1]
+
+ if curUsage > maxUsage:
+ maxUsage = curUsage
+ lastMaxChangeTime = time.time()
+ self._textNode1.text = ("Last increase in maximum: "
+ + time.strftime("%d.%m.%Y %H:%M:%S",
+ time.localtime(lastMaxChangeTime)))
+ self._maxUsage.append(maxUsage)
+ self.__numSamples += 1
+
+ if self.__numSamples % 60 == 0:
+ lastMinuteAverage = sum(self._usage[-60:]) / 60
+ self._minutesUsage.append(lastMinuteAverage)
+ self._minutesMaxUsage.append(maxUsage)
+
+ if self.__numSamples < 60 * 60:
+ self._plotLine(self._usage, self._lineNode, maxUsage)
+ self._plotLine(self._maxUsage, self._maxLineNode, maxUsage)
+ else:
+ self._plotLine(self._minutesUsage, self._lineNode, maxUsage)
+ self._plotLine(self._minutesMaxUsage, self._maxLineNode, maxUsage)
+
+ self._textNode0.text = ("Max. memory usage: %(size).2f MB" %
+ {"size": maxUsage / (1024 * 1024.0)})
+
+ if self.__numSamples % 3600 == 0:
+ del self._usage[0:3600]
+ del self._maxUsage[0:3599]
+ if self.__numSamples == 604800:
+ self.__numSamples == 0
+
+ def _plotLine(self, data, node, maxy):
+ yfactor = (self.size.y - 10.0) / float(maxy)
+ xfactor = (self.size.x - 10.0) / float(len(data) - 1)
+ node.pos = [(pos[0] * xfactor + 10, (maxy - pos[1]) * yfactor + 10.0)
+ for pos in enumerate(data)]
+
+
+class SlidingGraph(Graph):
+ def __init__(self, title='', getValue=None, limit=120.0, parent=None, **kwargs):
+ super(SlidingGraph, self).__init__(title, getValue, parent, **kwargs)
+ self.registerInstance(self, None)
+ self._limitValue = float(limit)
+
+ def _setup(self):
+ self.__frameHandlerID = player.subscribe(avg.Player.ON_FRAME,
+ self._nextFrameTimeSample)
+ self._numSamples = 0
+ self._lastCurUsage = 0
+ self._maxFrameTime = 0
+ self._values = []
+
+ def _nextFrameTimeSample(self):
+ val = self._frameTimeSample()
+ self._appendValue(val)
+ self._numSamples += 1
+
+ def _appendValue(self, value):
+ maxValue = min(self._limitValue, value)
+ y = self.height - (self.height * (maxValue / self._limitValue))
+ y = max(0, y)
+ numValues = int(self.width / self._xSkip)
+ self._values = (self._values + [y])[-numValues:]
+ self._plotGraph()
+
+ def _frameTimeSample(self):
+ frameTime = self._getValue()
+ diff = frameTime - self._lastCurUsage
+ if self._numSamples < 2:
+ self._maxFrameTime = 0
+ if diff > self._maxFrameTime:
+ lastMaxChangeTime = time.time()
+ self._maxFrameTime = diff
+ self._textNode0.text = ("Max FrameTime: %.f" % self._maxFrameTime + " ms" +
+ " Time: " + time.strftime("%d.%m.%Y %H:%M:%S",
+ time.localtime(lastMaxChangeTime)))
+
+ self._lastCurUsage = frameTime
+ self._textNode1.text = ("Current FrameTime: %.f" % diff + " ms")
+ return diff
+
+ def _plotGraph(self):
+ self._lineNode.pos = self._getCoords()
+
+ def _getCoords(self):
+ return zip(xrange(0, len(self._values) * self._xSkip, self._xSkip), self._values)
+
+
+class BinBar(avg.DivNode):
+ def __init__(self, label, parent=None, **kwargs):
+ super(BinBar, self).__init__(**kwargs)
+ self.registerInstance(self, parent)
+
+ avg.WordsNode(text=label, fontsize=8, alignment='center',
+ pos=(self.size.x / 2, self.size.y - 12), parent=self)
+
+ self._vbar = avg.RectNode(opacity=0, fillopacity=0.4,
+ fillcolor='ff0000', parent=self)
+
+ self.update(0)
+
+ def update(self, value):
+ value = min(max(value, 0), 1)
+
+ height = (self.size.y - 15) * value
+ self._vbar.size = (self.size.x - 2, height)
+ self._vbar.pos = (1, self.size.y - height - 12)
+
+
+class BinsGraph(avg.DivNode):
+ def __init__(self, binsThresholds, parent=None, **kwargs):
+ super(BinsGraph, self).__init__(**kwargs)
+ self.registerInstance(self, parent)
+
+ avg.RectNode(size=self.size, parent=self)
+ colWidth = self.size.x / len(binsThresholds)
+ self._binBars = [BinBar(str(int(thr)),
+ pos=(idx * colWidth, 0),
+ size=(colWidth, self.size.y),
+ parent=self)
+ for idx, thr in enumerate(binsThresholds)]
+
+ def update(self, values):
+ s = sum(values)
+
+ for binBar, value in zip(self._binBars, values):
+ normValue = float(value) / s
+ logValue = math.log10(normValue * 9 + 1) if normValue != 0 else 0
+ binBar.update(logValue)
+
+
+class SlidingBinnedGraph(SlidingGraph):
+ def __init__(self, title='', getValue=None, limit=120.0, binsThresholds=[],
+ parent=None, **kwargs):
+ super(SlidingBinnedGraph, self).__init__(title, getValue, limit, parent, **kwargs)
+ if not all([isinstance(x, (int, float)) for x in binsThresholds]):
+ raise RuntimeError('Bins thresholds must be provided as list of numbers')
+
+ self._bins = [0] * len(binsThresholds)
+ self._binsThresholds = binsThresholds
+ self._binsGraph = BinsGraph(binsThresholds=binsThresholds,
+ pos=(self.size.x - 120, 5), size=(90, self.size.y - 10),
+ parent=self)
+
+ def _appendValue(self, value):
+ for i in xrange(len(self._binsThresholds) - 1, -1, -1):
+ if value >= self._binsThresholds[i]:
+ self._bins[i] += 1
+ break
+
+ if sum(self._bins) % 100 == 0:
+ self._binsGraph.update(self._bins)
+
+ super(SlidingBinnedGraph, self)._appendValue(value)
diff --git a/src/python/mathutil.py b/src/python/mathutil.py
new file mode 100644
index 0000000..b27758e
--- /dev/null
+++ b/src/python/mathutil.py
@@ -0,0 +1,168 @@
+# libavg - Media Playback Engine.
+# Copyright (C) 2003-2014 Ulrich von Zadow
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Current versions can be found at www.libavg.de
+#
+# Original author of this file is Martin Heistermann <mh at sponc dot de>
+#
+
+# TODO: Some of this stuff is duplicated - either in Point2D or in MathHelper.h/.cpp.
+# Clean that up.
+
+import math
+from libavg import Point2D
+
+def getAngle(p1, p2):
+ vec = p2 - p1
+ res = math.atan2(vec.y, vec.x)
+ if res < 0:
+ res += math.pi * 2
+ return res
+
+def getDistance (p, q):
+ return math.sqrt((p.x-q.x)**2 + (p.y-q.y)**2)
+
+def getDistSquared (p, q):
+ return (p.x-q.x)**2 + (p.y-q.y)**2
+
+def getScaleToSize ((width, height), (max_width, max_height)):
+ if width < max_width:
+ height = height * (float(max_width) / width)
+ width = max_width
+ elif height > max_height:
+ width = width * (float(max_height) / height)
+ height = max_height
+ return getScaledDim((width, height), (max_width, max_height))
+
+def getScaledDim (size, max = None, min = None):
+ width, height = size
+ if width == 0 or height == 0:
+ return size
+
+ if max:
+ max = Point2D(max)
+ assert (max.x > 0 and max.y > 0)
+ if width > max.x:
+ height = height * (max.x / width)
+ width = max.x
+ if height > max.y:
+ width = width * (max.y / height)
+ height = max.y
+
+ if min:
+ min = Point2D(min)
+ assert (min.x > 0 and min.y > 0)
+ if width < min.x:
+ height = height * (min.x / width)
+ width = min.x
+ if height < min.y:
+ width = width * (min.y / height)
+ height = min.y
+
+ return Point2D(width, height)
+
+
+class EquationNotSolvable (Exception):
+ pass
+class EquationSingular (Exception):
+ pass
+
+def gauss_jordan(m, eps = 1.0/(10**10)):
+ """Puts given matrix (2D array) into the Reduced Row Echelon Form.
+ Returns True if successful, False if 'm' is singular.
+ NOTE: make sure all the matrix items support fractions! Int matrix will NOT work!
+ Written by Jarno Elonen in April 2005, released into Public Domain
+ http://elonen.iki.fi/code/misc-notes/affine-fit/index.html"""
+ (h, w) = (len(m), len(m[0]))
+ for y in range(0,h):
+ maxrow = y
+ for y2 in range(y+1, h): # Find max pivot
+ if abs(m[y2][y]) > abs(m[maxrow][y]):
+ maxrow = y2
+ (m[y], m[maxrow]) = (m[maxrow], m[y])
+ if abs(m[y][y]) <= eps: # Singular?
+ raise EquationSingular
+ for y2 in range(y+1, h): # Eliminate column y
+ c = m[y2][y] / m[y][y]
+ for x in range(y, w):
+ m[y2][x] -= m[y][x] * c
+ for y in range(h-1, 0-1, -1): # Backsubstitute
+ c = m[y][y]
+ for y2 in range(0,y):
+ for x in range(w-1, y-1, -1):
+ m[y2][x] -= m[y][x] * m[y2][y] / c
+ m[y][y] /= c
+ for x in range(h, w): # Normalize row y
+ m[y][x] /= c
+ return m
+
+
+def solveEquationMatrix(_matrix, eps = 1.0/(10**10)):
+ matrix=[]
+ for coefficients, res in _matrix:
+ newrow = map(float, coefficients + (res,))
+ matrix.append(newrow)
+ matrix = gauss_jordan (matrix)
+ res=[]
+ for col in xrange(len(matrix[0])-1):
+ rows = filter(lambda row: row[col] >= eps, matrix)
+ if len(rows)!=1:
+ raise EquationNotSolvable
+ res.append (rows[0][-1])
+
+ return res
+
+
+def getOffsetForMovedPivot(oldPivot, newPivot, angle):
+ oldPos = Point2D(0,0).getRotated(angle, oldPivot)
+ newPos = Point2D(0,0).getRotated(angle, newPivot)
+ return oldPos - newPos
+
+def isNaN(x):
+ return (not(x<=0) and not(x>=0))
+
+def sgn (x):
+ if x<0:
+ return -1
+ elif x==0:
+ return 0
+ else:
+ return 1
+
+class MovingAverage:
+ """
+ Moving average implementation.
+ Example:
+ ma = MovingAverage(20)
+ print ma(2)
+ print ma(3)
+ print ma(10)
+ """
+ def __init__(self, points):
+ self.__points = points
+ self.__values = []
+
+ def __appendValue(self, value):
+ self.__values = (self.__values + [value])[-self.__points:]
+
+ def __getAverage(self):
+ sum = reduce(lambda a,b:a+b, self.__values)
+ return float(sum) / len(self.__values)
+
+ def __call__(self, value):
+ self.__appendValue(value)
+ return self.__getAverage()
diff --git a/src/python/methodref.py b/src/python/methodref.py
new file mode 100644
index 0000000..f59ed24
--- /dev/null
+++ b/src/python/methodref.py
@@ -0,0 +1,69 @@
+# libavg - Media Playback Engine.
+# Copyright (C) 2003-2014 Ulrich von Zadow
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Current versions can be found at www.libavg.de
+
+import weakref, new
+
+class methodref(object):
+ # From Python Cookbook
+ """ Wraps any callable, most importantly a bound method, in a way that allows a bound
+ method's object to be GC'ed, while providing the same interface as a normal weak
+ reference."""
+ def __init__(self, fn):
+ try:
+ # Try getting object, function and class
+ o, f, c = fn.im_self, fn.im_func, fn.im_class
+ except AttributeError:
+ # It's not a bound method
+ self._obj = None
+ self._func = fn
+ self._clas = None
+ if fn:
+ self.__name__ = fn.__name__
+ else:
+ self.__name__ = None
+ else:
+ # Bound method
+ if o is None: # ... actually UN-bound
+ self._obj = None
+ self.__name__ = f.__name__
+ else:
+ self._obj = weakref.ref(o)
+ self.__name__ = fn.im_class.__name__ + "." + fn.__name__
+ self._func = f
+ self._clas = c
+
+ def isSameFunc(self, func):
+ if self._obj is None:
+ return func == self._func
+ elif self._obj() is None:
+ return func is None
+ else:
+ try:
+ o, f, c = func.im_self, func.im_func, func.im_class
+ except AttributeError:
+ return False
+ else:
+ return (o == self._obj() and f == self._func and c == self._clas)
+
+ def __call__(self):
+ if self._obj is None:
+ return self._func
+ elif self._obj() is None:
+ return None
+ return new.instancemethod(self._func, self._obj(), self._clas)
diff --git a/src/python/mtemu.py b/src/python/mtemu.py
new file mode 100644
index 0000000..3bd348f
--- /dev/null
+++ b/src/python/mtemu.py
@@ -0,0 +1,166 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+# libavg - Media Playback Engine.
+# Copyright (C) 2003-2014 Ulrich von Zadow
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Current versions can be found at www.libavg.de
+# Original author of this file is Sebastian Maulbeck
+# <sm (at) archimedes-solutions (dot) de>
+
+'''
+Multitouch emulation helper, supporting pinch gestures
+'''
+
+from libavg import avg, Point2D, player
+
+
+class MTemu(object):
+ MOUSE_STATE_UP = 'MOUSE_STATE_UP'
+ MOUSE_STATE_DOWN = 'MOUSE_STATE_DOWN'
+
+ def __init__(self):
+ self.__mouseState = self.MOUSE_STATE_UP
+ self.__cursorID = 0
+ self.__dualTouch = False
+ self.__secondTouch = False
+ self.__source = avg.Event.TOUCH
+
+ self.__oldEventHook = player.getEventHook()
+ player.setEventHook(self.__onEvent)
+
+ root = player.getRootNode()
+ self.__caption = avg.WordsNode(pos=(root.size.x - 15, root.size.y - 20),
+ alignment = 'right',
+ color='DDDDDD',
+ sensitive=False,
+ fontsize=14,
+ parent=root)
+ self.__updateCaption()
+
+ def deinit(self):
+ player.setEventHook(self.__oldEventHook)
+ self.__caption.unlink()
+ if self.__mouseState == self.MOUSE_STATE_DOWN:
+ self.__releaseTouch(self.__cursorID)
+ if self.__secondTouch:
+ self.__releaseTouch(self.__cursorID+1)
+
+ def toggleSource(self):
+ '''
+ Switch between avg.Event.TOUCH and avg.Event.TRACK - source
+ '''
+ self.__clearSourceState()
+ self.__source = (avg.Event.TOUCH if self.__source == avg.Event.TRACK
+ else avg.Event.TRACK)
+ self.__updateCaption()
+
+ def toggleDualTouch(self):
+ self.__dualTouch = not(self.__dualTouch)
+ self.__clearDualtouchState()
+
+ def enableDualTouch(self):
+ self.__dualTouch = True
+ self.__clearDualtouchState()
+
+ def disableDualTouch(self):
+ self.__dualTouch = False
+ self.__clearDualtouchState()
+
+ def __clearSourceState(self):
+ if self.__mouseState == self.MOUSE_STATE_DOWN:
+ self.__releaseTouch(self.__cursorID)
+ if self.__secondTouch:
+ self.__releaseTouch(self.__cursorID+1)
+ self.__mouseState = self.MOUSE_STATE_UP
+ self.__secondTouch = False
+
+ def __clearDualtouchState(self):
+ if self.__mouseState == self.MOUSE_STATE_DOWN:
+ if self.__secondTouch:
+ self.__releaseTouch(self.__cursorID+1)
+ else:
+ self.__sendFakeTouch(self.__cursorID+1, Point2D(0,0),
+ avg.Event.CURSOR_DOWN, mirror=True)
+ self.__secondTouch = not(self.__secondTouch)
+
+ def __updateCaption(self):
+ self.__caption.text = 'Multitouch emulation (%s source)' % self.__source
+
+ def __onEvent(self, event):
+ if event.source == avg.Event.MOUSE:
+ if event.type == avg.Event.CURSOR_DOWN:
+ self.__onMouseDown(event)
+ elif event.type == avg.Event.CURSOR_MOTION:
+ self.__onMouseMotion(event)
+ elif event.type == avg.Event.CURSOR_UP:
+ self.__onMouseUp(event)
+ return True
+ else:
+ return False
+
+ def __onMouseDown(self, event):
+ self._initialPos = event.pos
+ if self.__mouseState == self.MOUSE_STATE_UP and event.button == 1:
+ self.__sendFakeTouch(self.__cursorID, event.pos, event.type)
+ if self.__dualTouch and not self.__secondTouch:
+ self.__sendFakeTouch(self.__cursorID+1, event.pos, event.type,
+ True)
+ self.__secondTouch = True
+ self.__mouseState = self.MOUSE_STATE_DOWN
+
+ def __onMouseMotion(self, event):
+ if self.__mouseState == self.MOUSE_STATE_DOWN:
+ self.__sendFakeTouch(self.__cursorID, event.pos, event.type)
+ if self.__dualTouch and self.__secondTouch:
+ self.__sendFakeTouch(self.__cursorID+1, event.pos,
+ event.type, True)
+
+ def __onMouseUp(self, event):
+ if self.__mouseState == self.MOUSE_STATE_DOWN and event.button == 1:
+ self.__sendFakeTouch(self.__cursorID, event.pos, event.type)
+ if self.__dualTouch and self.__secondTouch:
+ self.__sendFakeTouch(self.__cursorID+1, event.pos,
+ event.type, True)
+ self.__secondTouch = False
+ self.__mouseState = self.MOUSE_STATE_UP
+ self.__cursorID += 2 #Even for left uneven for right touch
+
+ def __sendFakeTouch(self, cursorID, pos, touchType, mirror=False):
+ offset = Point2D(0,0)
+ if self.__dualTouch:
+ offset = Point2D(40, 0)
+ if mirror:
+ pos = 2*(self._initialPos)-pos
+ offset = -offset
+ player.getTestHelper().fakeTouchEvent(cursorID,
+ touchType, self.__source, self.__clampPos(pos+offset))
+
+ def __releaseTouch(self, cursorID):
+ self.__sendFakeTouch(cursorID, Point2D(0,0), avg.Event.CURSOR_UP)
+
+ def __clampPos(self, pos):
+ if pos[0] < 0:
+ pos[0] = 0
+ if pos[1] < 0:
+ pos[1] = 0
+ if pos[0] >= player.getRootNode().size[0]:
+ pos[0] = player.getRootNode().size[0]-1
+ if pos[1] >= player.getRootNode().size[1]:
+ pos[1] = player.getRootNode().size[1]-1
+ return pos
+
diff --git a/src/python/parsecamargs.py b/src/python/parsecamargs.py
new file mode 100644
index 0000000..7515b2f
--- /dev/null
+++ b/src/python/parsecamargs.py
@@ -0,0 +1,49 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# libavg - Media Playback Engine.
+# Copyright (C) 2003-2014 Ulrich von Zadow
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Current versions can be found at www.libavg.de
+#
+
+from libavg import avg
+
+validPixFmt = list();
+for formatItem in avg.getSupportedPixelFormats():
+ validPixFmt.append(formatItem);
+validDrivers = ('firewire', 'video4linux', 'directshow')
+
+def addOptions(parser):
+ parser.add_option("-t", "--driver", action="store", dest="driver",
+ choices=validDrivers,
+ help="camera drivers (one of: %s)" %', '.join(validDrivers))
+ parser.add_option("-d", "--device", action = "store", dest = "device", default = "",
+ help = "camera device identifier (may be GUID or device path)")
+ parser.add_option("-u", "--unit", action="store", dest="unit", default="-1",
+ type="int", help="unit number")
+ parser.add_option("-w", "--width", dest="width", default="640", type="int",
+ help="capture width in pixels")
+ parser.add_option("-e", "--height", dest="height", default="480", type="int",
+ help="capture height in pixels")
+ parser.add_option("-p", "--pixformat", dest="pixelFormat", default="R8G8B8",
+ choices=validPixFmt,
+ help="camera frame pixel format (one of: %s)" %', '.join(validPixFmt))
+ parser.add_option("-f", "--framerate", dest="framerate", default="15", type="float",
+ help="capture frame rate")
+ parser.add_option("-8", "--fw800", dest="fw800", action="store_true", default=False,
+ help="set firewire bus speed to s800 (if applicable)")
diff --git a/src/python/persist.py b/src/python/persist.py
new file mode 100644
index 0000000..1357609
--- /dev/null
+++ b/src/python/persist.py
@@ -0,0 +1,157 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+# libavg - Media Playback Engine.
+# Copyright (C) 2003-2014 Ulrich von Zadow
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Current versions can be found at www.libavg.de
+#
+# Original author of this file is OXullo Interecans <x at brainrapers dot org>
+
+
+import os
+import time
+import cPickle as pickle
+
+import libavg
+
+
+class Persist(object):
+ def __init__(self, storeFile, initialData, validator=lambda v: True,
+ autoCommit=False):
+ self.__storeFile = storeFile
+
+ if hasattr(initialData, '__call__'):
+ initialData = initialData()
+ elif initialData is None:
+ initialData = dict()
+
+ if os.path.exists(self.__storeFile):
+ if not os.path.isfile:
+ raise RuntimeError('%s dump file is not a plain file' % self)
+ elif not os.access(self.__storeFile, os.R_OK | os.W_OK):
+ raise RuntimeError('%s dump file'
+ 'cannot be accessed with r/w permissions' % self)
+
+ try:
+ f = open(self.__storeFile)
+ except IOError:
+ libavg.logger.debug('Initializing %s' % self)
+ self.data = initialData
+ self.commit()
+ else:
+ try:
+ self.data = pickle.load(f)
+ except:
+ f.close()
+ libavg.logger.warning('Persist %s is corrupted or unreadable, '
+ 'reinitializing' % self)
+ self.data = initialData
+ self.commit()
+ else:
+ f.close()
+ if not validator(self.data):
+ libavg.logger.warning('Sanity check failed for %s, '
+ 'reinitializing' % self)
+ self.data = initialData
+ self.commit()
+ else:
+ libavg.logger.debug('%s successfully loaded' % self)
+
+ if autoCommit:
+ import atexit
+ atexit.register(self.commit)
+
+ def __repr__(self):
+ return '<%s %s>' % (self.__class__.__name__, self.__storeFile)
+
+ @property
+ def storeFile(self):
+ return self.__storeFile
+
+ def commit(self):
+ tempFile = self.__storeFile + '.tmp.' + str(int(time.time() * 1000))
+
+ try:
+ with open(tempFile, 'wb') as f:
+ pickle.dump(self.data, f)
+ except Exception, e:
+ libavg.logger.warning('Cannot save %s (%s)' % (self.__storeFile, str(e)))
+ return False
+ else:
+ if os.path.exists(self.__storeFile):
+ try:
+ os.remove(self.__storeFile)
+ except Exception, e:
+ libavg.logger.warning('Cannot overwrite dump file '
+ '%s (%s)' % (self, str(e)))
+ return False
+ try:
+ os.rename(tempFile, self.__storeFile)
+ except Exception, e:
+ libavg.logger.warning('Cannot save %s (%s)' % (self, str(e)))
+ os.remove(tempFile)
+ return False
+ else:
+ libavg.logger.debug('%s saved' % self)
+ return True
+
+
+class UserPersistentData(Persist):
+ def __init__(self, appName, fileName, *args, **kargs):
+ basePath = os.path.join(self._getUserDataPath(), appName)
+ fullPath = os.path.join(basePath, '%s.pkl' % fileName)
+
+ try:
+ os.makedirs(basePath)
+ except OSError, e:
+ import errno
+ if e.errno != errno.EEXIST:
+ raise
+
+ super(UserPersistentData, self).__init__(fullPath, *args, **kargs)
+
+ def _getUserDataPath(self):
+ if os.name == 'posix':
+ path = os.path.join(os.environ['HOME'], '.avg')
+ elif os.name == 'nt':
+ path = os.path.join(os.environ['APPDATA'], 'Avg')
+ else:
+ raise RuntimeError('Unsupported system %s' % os.name)
+
+ return path
+
+
+if __name__ == '__main__':
+ testFile = './testfile.pkl'
+ initialData = {'initial': True}
+ p = Persist(testFile, initialData)
+ p.commit()
+ p.data['initial'] = False
+ p.commit()
+
+ p = Persist(testFile, initialData)
+ print not p.data['initial']
+
+ os.unlink(testFile)
+
+ p = UserPersistentData('myapp', 'hiscore', initialData)
+ p.data['initial'] = False
+ p.commit()
+
+ print p
+
diff --git a/src/python/statemachine.py b/src/python/statemachine.py
new file mode 100644
index 0000000..993ef9b
--- /dev/null
+++ b/src/python/statemachine.py
@@ -0,0 +1,149 @@
+# libavg - Media Playback Engine.
+# Copyright (C) 2003-2014 Ulrich von Zadow
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Current versions can be found at www.libavg.de
+#
+
+from methodref import methodref
+
+import subprocess
+import os
+
+class State(object):
+ def __init__(self, transitions, enterFunc, leaveFunc):
+ self.transitions = {}
+ for destState, transfunc in transitions.items():
+ ref = methodref(transfunc)
+ self.transitions[destState] = ref
+ self.enterFunc = methodref(enterFunc)
+ self.leaveFunc = methodref(leaveFunc)
+
+class StateMachine(object):
+ def __init__(self, name, startState):
+ self.__states = {}
+ self.__name = name
+ self.__startState = startState
+ self.__curState = startState
+ self.__trace = False
+ self.__initDone = False
+
+ def addState(self, state, transitions, enterFunc=None, leaveFunc=None):
+ if self.__initDone:
+ raise RuntimeError(
+ "StateMachine: Can't add new states after calling changeState")
+ if self.__states.has_key(state):
+ raise RuntimeError("StateMachine: Duplicate state " + state + ".")
+
+ if isinstance(transitions, (list, tuple)):
+ transitions = dict.fromkeys(transitions)
+ self.__states[state] = State(transitions, enterFunc, leaveFunc)
+
+ def changeState(self, newState):
+ if not(self.__initDone):
+ self.__initDone = True
+ self.__doSanityCheck()
+
+ if self.__trace:
+ print self.__name, ":", self.__curState, "-->", newState
+
+ if not(newState in self.__states):
+ raise RuntimeError('StateMachine: Attempt to change to nonexistent state '+
+ newState+'.')
+ assert(self.__curState in self.__states)
+ state = self.__states[self.__curState]
+ if newState in state.transitions:
+ if state.leaveFunc() != None:
+ state.leaveFunc()()
+ transitionFunc = state.transitions[newState]()
+ if transitionFunc != None:
+ try:
+ transitionFunc(self.__curState, newState)
+ except TypeError:
+ transitionFunc()
+ self.__curState = newState
+ enterFunc = self.__states[self.__curState].enterFunc()
+ if enterFunc != None:
+ enterFunc()
+ else:
+ raise RuntimeError('StateMachine: State change from '+self.__curState+' to '+
+ newState+' not allowed.')
+
+ def traceChanges(self, trace):
+ self.__trace = trace
+
+ @property
+ def state(self):
+ return self.__curState
+
+ def dump(self):
+ for oldStateName, state in self.__states.iteritems():
+ print oldStateName, ("(enter: " + self.__getNiceFuncName(state.enterFunc)
+ + ", leave: " + self.__getNiceFuncName(state.leaveFunc) + "):")
+ for newState, func in state.transitions.iteritems():
+ print " -->", newState, ":", self.__getNiceFuncName(func)
+ print "Current state:", self.__curState
+
+ def makeDiagram(self, fName, showMethods=False):
+ def writeState(stateName, state):
+ label = stateName
+ if showMethods:
+ if state.enterFunc.__name__ is not(None):
+ label += ('<br/><font point-size="10">entry/'
+ + state.enterFunc.__name__ + '</font>')
+ if state.leaveFunc.__name__ is not(None):
+ label += ('<br/><font point-size="10">exit/'
+ + state.leaveFunc.__name__ + '</font>')
+ dotFile.write(' "'+stateName+'" [label=<'+label+'>];\n')
+
+ def writeTransition(origState, destState, func):
+ dotFile.write(' "'+origState+'" -> "'+destState+'"')
+ if showMethods and func and func.__name__ is not(None):
+ dotFile.write(' [label="/'+func.__name__+'", fontsize=10]')
+ dotFile.write(";\n")
+
+
+ dotFile = open("tmp.dot", "w")
+ dotFile.write('digraph "'+self.__name+'" {\n')
+ dotFile.write(' node [fontsize=12, shape=box, style=rounded];\n')
+ dotFile.write(' startstate [shape=point, height=0.2, width=0.2, label=""];\n')
+ dotFile.write(' { rank=source; "startstate" };\n')
+ writeTransition("startstate", self.__startState, None)
+ for stateName, state in self.__states.iteritems():
+ writeState(stateName, state)
+ for destState, func in state.transitions.iteritems():
+ writeTransition(stateName, destState, func)
+ dotFile.write(' "'+self.__curState+'" [style="rounded,bold"];\n')
+ dotFile.write('}\n')
+ dotFile.close()
+ try:
+ subprocess.call(["dot", "tmp.dot", "-Tpng", "-o"+fName])
+ except OSError:
+ raise RuntimeError("dot executable not found. graphviz needs to be installed for StateMachine.makeDiagram to work.")
+ os.remove("tmp.dot")
+
+ def __getNiceFuncName(self, f):
+ if f.__name__ is not(None):
+ return f.__name__
+ else:
+ return "None"
+
+ def __doSanityCheck(self):
+ for stateName, state in self.__states.iteritems():
+ for transitionName in state.transitions.iterkeys():
+ if not(self.__states.has_key(transitionName)):
+ raise RuntimeError("StateMachine: transition " + stateName + " -> " +
+ transitionName + " has an unknown destination state.")
diff --git a/src/python/textarea.py b/src/python/textarea.py
new file mode 100644
index 0000000..8b9bcf1
--- /dev/null
+++ b/src/python/textarea.py
@@ -0,0 +1,833 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# libavg - Media Playback Engine.
+# Copyright (C) 2003-2014 Ulrich von Zadow
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Current versions can be found at www.libavg.de
+#
+# Original author of this module is Marco Fagiolini <mfx at archi-me-des dot de>
+#
+
+"""
+Single/Multi-Line editable text field widget for libavg
+
+textarea module provides two classes:
+
+1. TextArea
+ This is the implementation of the widget. Every instantiated TextArea
+ represents an editable text field, which can be set up with several styles
+ and behaviors.
+
+2. FocusContext
+ This helps to easily route the events that comes from keyboards to an
+ appropriate TextArea instance, cycling focuses and dispatching events on
+ the selected field.
+
+"""
+
+g_FocusContext = None
+g_LastKeyEvent = None
+g_activityCallback = None
+g_LastKeyRepeated = 0
+g_RepeatDelay = 0.2
+g_CharDelay = 0.1
+
+KEYCODE_TAB = 9
+KEYCODE_LINEFEED = 13
+KEYCODE_SHTAB = 25
+KEYCODE_FORMFEED = 12
+KEYCODE_CRS_UP = 63232
+KEYCODE_CRS_DOWN = 63233
+KEYCODE_CRS_LEFT = 63234
+KEYCODE_CRS_RIGHT = 63235
+KEYCODES_BACKSPACE = (8,127)
+KEYCODES_DEL = 63272
+
+CURSOR_PADDING_PCT = 15
+CURSOR_WIDTH_PCT = 4
+CURSOR_SPACING_PCT = 4
+CURSOR_FLASHING_DELAY = 600
+CURSOR_FLASH_AFTER_INACTIVITY = 200
+
+DEFAULT_BLUR_OPACITY = 0.3
+
+import time
+
+from libavg import avg, player, gesture
+from avg import Point2D
+
+
+class FocusContext(object):
+ """
+ This class helps to group TextArea elements
+
+ TextArea elements that belong to the same FocusContext cycle focus among
+ themselves. There can be several FocusContextes but only one active at once
+ ( using the global function setActiveFocusContext() )
+ """
+ def __init__(self):
+ self.__elements = []
+ self.__isActive = False
+
+ def isActive(self):
+ """
+ Test if this FocusContext is currently active
+ """
+ return self.__isActive
+
+ def register(self, taElement):
+ """
+ Register a floating textarea on this FocusContext
+
+ @param taElement: a TextArea instance
+ """
+ self.__elements.append(taElement)
+
+ def getFocused(self):
+ """
+ Query the TextArea element that currently has focus
+
+ @return: TextArea instance or None
+ """
+ for ob in self.__elements:
+ if ob.hasFocus():
+ return ob
+ return None
+
+ def keyCharPressed(self, kchar):
+ """
+ Inject an utf-8 encoded characted into the flow
+
+ Shift a character (Unicode keycode) into the active (w/focus) TextArea
+ @type kchar: string
+ @param kchar: a single character (if more than one, the following are ignored)
+ """
+ uch = unicode(kchar, 'utf-8')
+ self.keyUCodePressed(ord(uch[0]))
+
+ def keyUCodePressed(self, keycode):
+ """
+ Inject an Unicode code point into the flow
+
+ Shift a character (Unicode keycode) into the active (w/focus) TextArea
+ @type keycode: int
+ @param keycode: unicode code point of the character
+ """
+ # TAB key cycles focus through textareas
+ if keycode == KEYCODE_TAB:
+ self.cycleFocus()
+ return
+ # Shift-TAB key cycles focus through textareas backwards
+ if keycode == KEYCODE_SHTAB:
+ self.cycleFocus(True)
+ return
+
+ for ob in self.__elements:
+ if ob.hasFocus():
+ ob.onKeyDown(keycode)
+
+ def backspace(self):
+ """
+ Emulate a backspace character keypress
+ """
+ self.keyUCodePressed(KEYCODES_BACKSPACE[0])
+
+ def delete(self):
+ """
+ Emulate a delete character keypress
+ """
+ self.keyUCodePressed(KEYCODE_DEL)
+
+ def clear(self):
+ """
+ Clear the active textarea, emulating the press of FF character
+ """
+ self.keyUCodePressed(KEYCODE_FORMFEED)
+
+ def resetFocuses(self):
+ """
+ Blur every TextArea registered within this FocusContext
+ """
+ for ob in self.__elements:
+ ob.clearFocus()
+
+ def cycleFocus(self, backwards=False):
+ """
+ Force a focus cycle among instantiated textareas
+
+ TAB/Sh-TAB keypress is what is translated in a focus cycle.
+ @param backwards: as default, the method cycles following the order
+ that has been followed during the registration of TextArea
+ instances. Setting this to True, the order is inverted.
+ """
+
+ els = []
+ els.extend(self.__elements)
+
+ if len(els) == 0:
+ return
+
+ if backwards:
+ els.reverse()
+
+ elected = 0
+ for ob in els:
+ if not ob.hasFocus():
+ elected = elected + 1
+ else:
+ break
+
+ # elects the first if no ta are in focus or if the
+ # last one has it
+ if elected in (len(els), len(els)-1):
+ elected = 0
+ else:
+ elected = elected + 1
+
+ for ob in els:
+ ob.setFocus(False)
+
+ els[elected].setFocus(True)
+
+ def getRegistered(self):
+ """
+ Returns a list of TextArea currently registered within this FocusContext
+ @return: a list of registered TextArea instances
+ """
+ return self.__elements
+
+ def _switchActive(self, active):
+ if active:
+ self.resetFocuses()
+ self.cycleFocus()
+ else:
+ self.resetFocuses()
+
+ self.__isActive = active
+
+
+class TextArea(avg.DivNode):
+ """
+ TextArea class is a libavg widget to create editable text fields
+
+ TextArea is an extended <words> node that reacts to user input (mouse/touch for
+ focus, keyboard for text input). Can be set as a single line or span to multiple
+ lines.
+ """
+ def __init__(self, focusContext=None, disableMouseFocus=False,
+ moveCoursorOnTouch=True, textBackgroundNode=None, loupeBackgroundNode=None,
+ parent=None, **kwargs):
+ """
+ @param parent: parent of the node
+ @param focusContext: FocusContext object which directs focus for TextArea elements
+ @param disableMouseFocus: boolean, prevents that mouse can set focus for
+ this instance
+ @param moveCoursorOnTouch: boolean, activate the coursor motion on touch events
+ """
+ super(TextArea, self).__init__(**kwargs)
+ self.registerInstance(self, parent)
+
+ self.__focusContext = focusContext
+ self.__blurOpacity = DEFAULT_BLUR_OPACITY
+ self.__border = 0
+ self.__data = []
+ self.__cursorPosition = 0
+
+ textNode = avg.WordsNode(rawtextmode=True)
+
+ if textBackgroundNode != None:
+ self.appendChild(textBackgroundNode)
+
+ if not disableMouseFocus:
+ self.setEventHandler(avg.Event.CURSOR_UP, avg.Event.MOUSE, self.__onClick)
+ self.setEventHandler(avg.Event.CURSOR_UP, avg.Event.TOUCH, self.__onClick)
+
+ self.appendChild(textNode)
+
+ cursorContainer = avg.DivNode()
+ cursorNode = avg.LineNode(color='000000')
+ self.appendChild(cursorContainer)
+ cursorContainer.appendChild(cursorNode)
+ self.__flashingCursor = False
+
+ self.__cursorContainer = cursorContainer
+ self.__cursorNode = cursorNode
+ self.__textNode = textNode
+
+ self.__loupe = None
+
+ if focusContext is not None:
+ focusContext.register(self)
+ self.setFocus(False)
+ else:
+ self.setFocus(True)
+
+ player.setInterval(CURSOR_FLASHING_DELAY, self.__tickFlashCursor)
+
+ self.__lastActivity = 0
+
+ if moveCoursorOnTouch:
+ self.__recognizer = gesture.DragRecognizer(eventNode=self, friction=-1,
+ moveHandler=self.__moveHandler,
+ detectedHandler=self.__detectedHandler,
+ upHandler=self.__upHandler)
+ self.__loupeZoomFactor = 0.5
+ self.__loupe = avg.DivNode(parent=self, crop=True)
+
+ if loupeBackgroundNode != None:
+ self.__loupe.appendChild(loupeBackgroundNode)
+ self.__loupe.size = loupeBackgroundNode.size
+ else:
+ self.__loupe.size = (50,50)
+ avg.RectNode(fillopacity=1, fillcolor="f5f5f5", color="ffffff",
+ size=self.__loupe.size, parent=self.__loupe)
+ self.__loupeOffset = (self.__loupe.size[0]/2.0, self.__loupe.size[1]+20)
+ self.__loupe.unlink()
+ self.__zoomedImage = avg.DivNode(parent=self.__loupe)
+ self.__loupeTextNode = avg.WordsNode(rawtextmode=True,
+ parent=self.__zoomedImage)
+
+ self.__loupeCursorContainer = avg.DivNode(parent=self.__zoomedImage)
+ self.__loupeCursorNode = avg.LineNode(color='000000',
+ parent=self.__loupeCursorContainer)
+ self.setStyle()
+
+ def clearText(self):
+ """
+ Clears the text
+ """
+ self.setText(u'')
+
+ def setText(self, uString):
+ """
+ Set the text on the TextArea
+
+ @param uString: an unicode string (or an utf-8 encoded string)
+ """
+ if not isinstance(uString, unicode):
+ uString = unicode(uString, 'utf-8')
+
+ self.__data = []
+ for c in uString:
+ self.__data.append(c)
+
+ self.__cursorPosition = len(self.__data)
+ self.__update()
+
+ def getText(self):
+ """
+ Get the text stored and displayed on the TextArea
+ """
+ return self.__getUnicodeFromData()
+
+ def setStyle(self, font='sans', fontsize=12, alignment='left', variant='Regular',
+ color='000000', multiline=True, cursorWidth=None, border=(0,0),
+ blurOpacity=DEFAULT_BLUR_OPACITY, flashingCursor=False, cursorColor='000000',
+ lineSpacing=0, letterSpacing=0):
+ """
+ Set TextArea's graphical appearance
+ @param font: font face
+ @param fontsize: font size in pixels
+ @param alignment: one among 'left', 'right', 'center'
+ @param variant: font variant (eg: 'bold')
+ @param color: RGB hex for text color
+ @param multiline: boolean, whether TextArea has to wrap (undefinitely)
+ or stop at full width
+ @param cursorWidth: int, width of the cursor in pixels
+ @param border: amount of offsetting pixels that words node will have from image
+ extents
+ @param blurOpacity: opacity that textarea gets when goes to blur state
+ @param flashingCursor: whether the cursor should flash or not
+ @param cursorColor: RGB hex for cursor color
+ @param lineSpacing: linespacing property of words node
+ @param letterSpacing: letterspacing property of words node
+ """
+ self.__textNode.fontstyle = avg.FontStyle(font=font, fontsize=fontsize,
+ alignment=alignment, variant=variant, linespacing=lineSpacing,
+ letterspacing=letterSpacing)
+ self.__textNode.color = color
+ self.__isMultiline = multiline
+ self.__border = border
+ self.__maxLength = -1
+ self.__blurOpacity = blurOpacity
+
+ if multiline:
+ self.__textNode.width = int(self.width) - self.__border[0] * 2
+ self.__textNode.wrapmode = 'wordchar'
+ else:
+ self.__textNode.width = 0
+
+ self.__textNode.x = self.__border[0]
+ self.__textNode.y = self.__border[1]
+
+ tempNode = avg.WordsNode(text=u'W', font=font, fontsize=int(fontsize),
+ variant=variant)
+ self.__textNode.realFontSize = tempNode.getGlyphSize(0)
+ del tempNode
+ self.__textNode.alignmentOffset = Point2D(0,0)
+
+ if alignment != "left":
+ offset = Point2D(self.size.x / 2,0)
+ if alignment == "right":
+ offset = Point2D(self.size.x,0)
+ self.__textNode.pos += offset
+ self.__textNode.alignmentOffset = offset
+ self.__cursorContainer.pos = offset
+
+ self.__cursorNode.color = cursorColor
+ if cursorWidth is not None:
+ self.__cursorNode.strokewidth = cursorWidth
+ else:
+ w = float(fontsize) * CURSOR_WIDTH_PCT / 100.0
+ if w < 1:
+ w = 1
+ self.__cursorNode.strokewidth = w
+ x = self.__cursorNode.strokewidth / 2.0
+ self.__cursorNode.pos1 = Point2D(x, self.__cursorNode.pos1.y)
+ self.__cursorNode.pos2 = Point2D(x, self.__cursorNode.pos2.y)
+
+ self.__flashingCursor = flashingCursor
+ if not flashingCursor:
+ self.__cursorContainer.opacity = 1
+
+ if self.__loupe:
+ zoomfactor = (1.0 + self.__loupeZoomFactor)
+ self.__loupeTextNode.fontstyle = self.__textNode.fontstyle
+ self.__loupeTextNode.fontsize = int(fontsize) * zoomfactor
+ self.__loupeTextNode.color = color
+ if multiline:
+ self.__loupeTextNode.width = self.__textNode.width * zoomfactor
+ self.__loupeTextNode.wrapmode = 'wordchar'
+ else:
+ self.__loupeTextNode.width = 0
+
+ self.__loupeTextNode.x = self.__border[0] * 2
+ self.__loupeTextNode.y = self.__border[1] * 2
+
+ self.__loupeTextNode.realFontSize = self.__textNode.realFontSize * zoomfactor
+
+ if alignment != "left":
+ self.__loupeTextNode.pos = self.__textNode.pos * zoomfactor
+ self.__loupeTextNode.alignmentOffset = self.__textNode.alignmentOffset * \
+ zoomfactor
+ self.__loupeCursorContainer.pos = self.__cursorContainer.pos * zoomfactor
+
+ self.__loupeCursorNode.color = cursorColor
+ if cursorWidth is not None:
+ self.__loupeCursorNode.strokewidth = cursorWidth * zoomfactor
+ else:
+ w = float(self.__loupeTextNode.fontsize) * CURSOR_WIDTH_PCT / 100.0
+ if w < 1:
+ w = 1
+ self.__loupeCursorNode.strokewidth = w * zoomfactor
+ x = self.__loupeCursorNode.strokewidth / 2.0
+ self.__loupeCursorNode.pos1 = Point2D(x, self.__loupeCursorNode.pos1.y)
+ self.__loupeCursorNode.pos2 = Point2D(x, self.__loupeCursorNode.pos2.y)
+
+ if not flashingCursor:
+ self.__loupeCursorContainer.opacity = 1
+ self.__updateCursors()
+
+ def setMaxLength(self, maxlen):
+ """
+ Set character limit of the input
+
+ @param maxlen: max number of character allowed
+ """
+ self.__maxLength = maxlen
+
+ def clearFocus(self):
+ """
+ Compact form to blur the TextArea
+ """
+ self.opacity = self.__blurOpacity
+ self.__hasFocus = False
+
+ def setFocus(self, hasFocus):
+ """
+ Force the focus (or blur) of this TextArea
+
+ @param hasFocus: boolean
+ """
+ if self.__focusContext is not None:
+ self.__focusContext.resetFocuses()
+
+ if hasFocus:
+ self.opacity = 1
+ self.__cursorContainer.opacity = 1
+ else:
+ self.clearFocus()
+ self.__cursorContainer.opacity = 0
+
+ self.__hasFocus = hasFocus
+
+ def hasFocus(self):
+ """
+ Query the focus status for this TextArea
+ """
+ return self.__hasFocus
+
+ def showCursor(self, show):
+ if show:
+ avg.fadeIn(self.__cursorNode, 200)
+ if self.__loupe:
+ avg.fadeIn(self.__loupeCursorNode, 200)
+ else:
+ avg.fadeOut(self.__cursorNode, 200)
+ if self.__loupe:
+ avg.fadeOut(self.__loupeCursorNode, 200)
+
+ def onKeyDown(self, keycode):
+ """
+ Inject a keycode into TextArea flow
+
+ Used mainly by FocusContext. It can be used directly, but the best option
+ is always to use a FocusContext helper, which exposes convenience method for
+ injection.
+ @param keycode: characted to insert
+ @type keycode: int (SDL reference)
+ """
+ # Ensure that the cursor is shown
+ if self.__flashingCursor:
+ self.__cursorContainer.opacity = 1
+
+ if keycode in KEYCODES_BACKSPACE:
+ self.__removeChar(left=True)
+ self.__updateLastActivity()
+ self.__updateCursors()
+ elif keycode == KEYCODES_DEL:
+ self.__removeChar(left=False)
+ self.__updateLastActivity()
+ self.__updateCursors()
+ # NP/FF clears text
+ elif keycode == KEYCODE_FORMFEED:
+ self.clearText()
+ elif keycode in (KEYCODE_CRS_UP, KEYCODE_CRS_DOWN, KEYCODE_CRS_LEFT,
+ KEYCODE_CRS_RIGHT):
+ if keycode == KEYCODE_CRS_LEFT and self.__cursorPosition > 0:
+ self.__cursorPosition -= 1
+ self.__update()
+ elif (keycode == KEYCODE_CRS_RIGHT and
+ self.__cursorPosition < len(self.__data)):
+ self.__cursorPosition += 1
+ self.__update()
+ elif keycode == KEYCODE_CRS_UP and self.__cursorPosition != 0:
+ self.__cursorPosition = 0
+ self.__update()
+ elif (keycode == KEYCODE_CRS_DOWN and
+ self.__cursorPosition != len(self.__data)):
+ self.__cursorPosition = len(self.__data)
+ self.__update()
+ # add linefeed only on multiline textareas
+ elif keycode == KEYCODE_LINEFEED and self.__isMultiline:
+ self.__appendUChar('\n')
+ # avoid shift-tab, return, zero, delete
+ elif keycode not in (KEYCODE_LINEFEED, 0, 25, 63272):
+ self.__appendKeycode(keycode)
+ self.__updateLastActivity()
+ self.__updateCursors()
+
+ def __onClick(self, e):
+ if self.__focusContext is not None:
+ if self.__focusContext.isActive():
+ self.setFocus(True)
+ else:
+ self.setFocus(True)
+
+ def __getUnicodeFromData(self):
+ return u''.join(self.__data)
+
+ def __appendKeycode(self, keycode):
+ self.__appendUChar(unichr(keycode))
+
+ def __appendUChar(self, uchar):
+ # if maximum number of char is specified, honour the limit
+ if self.__maxLength > -1 and len(self.__data) > self.__maxLength:
+ return
+
+ # Boundary control
+ if len(self.__data) > 0:
+ maxCharDim = self.__textNode.fontsize
+ lastCharPos = self.__textNode.getGlyphPos(len(self.__data) - 1)
+ if self.__isMultiline:
+ if lastCharPos[1] + maxCharDim*2 > self.height - self.__border[1]*2:
+ if lastCharPos[0] + maxCharDim*1.5 > self.width - self.__border[0]*2:
+ return
+ if ord(uchar) == 10:
+ return
+ else:
+ if lastCharPos[0] + maxCharDim*1.5 > self.width - self.__border[0]*2:
+ return
+
+ self.__data.insert(self.__cursorPosition, uchar)
+ self.__cursorPosition += 1
+ self.__update()
+
+ def __removeChar(self, left=True):
+ if left and self.__cursorPosition > 0:
+ self.__cursorPosition -= 1
+ del self.__data[self.__cursorPosition]
+ self.__update()
+ elif not left and self.__cursorPosition < len(self.__data):
+ del self.__data[self.__cursorPosition]
+ self.__update()
+
+ def __update(self):
+ self.__textNode.text = self.__getUnicodeFromData()
+ if self.__loupe:
+ self.__loupeTextNode.text = self.__getUnicodeFromData()
+ self.__updateCursors()
+
+ def __updateCursors(self):
+ self.__updateCursor(self.__cursorNode, self.__cursorContainer, self.__textNode)
+ if self.__loupe:
+ self.__updateCursor(self.__loupeCursorNode, self.__loupeCursorContainer,
+ self.__loupeTextNode)
+
+ def __updateCursor(self, cursorNode, cursorContainer, textNode):
+ if self.__cursorPosition == 0:
+ lastCharPos = (0,0)
+ lastCharExtents = (0,0)
+ else:
+ lastCharPos = textNode.getGlyphPos(self.__cursorPosition - 1)
+ lastCharExtents = textNode.getGlyphSize(self.__cursorPosition - 1)
+
+ if self.__data[self.__cursorPosition - 1] == '\n':
+ lastCharPos = (0, lastCharPos[1] + lastCharExtents[1])
+ lastCharExtents = (0, lastCharExtents[1])
+
+ xPos = cursorNode.pos2.x
+ cursorNode.pos2 = Point2D(xPos, textNode.realFontSize.y * \
+ (1 - CURSOR_PADDING_PCT/100.0))
+
+ if textNode.alignment != "left":
+ if len(self.__data) > 0:
+ lineWidth = textNode.getLineExtents(self.__selectTextLine(lastCharPos,
+ textNode))
+ else:
+ lineWidth = Point2D(0,0)
+ if textNode.alignment == "center":
+ lineWidth *= 0.5
+ cursorContainer.x = textNode.alignmentOffset.x - lineWidth.x + \
+ lastCharPos[0] + lastCharExtents[0] + self.__border[0]
+ else:
+ cursorContainer.x = lastCharPos[0] + lastCharExtents[0] + self.__border[0]
+ cursorContainer.y = (lastCharPos[1] +
+ cursorNode.pos2.y * CURSOR_PADDING_PCT/200.0 + self.__border[1])
+
+ def __updateLastActivity(self):
+ self.__lastActivity = time.time()
+
+ def __tickFlashCursor(self):
+ if (self.__flashingCursor and
+ self.__hasFocus and
+ time.time() - self.__lastActivity > CURSOR_FLASH_AFTER_INACTIVITY/1000.0):
+ if self.__cursorContainer.opacity == 0:
+ self.__cursorContainer.opacity = 1
+ if self.__loupe:
+ self.__loupeCursorContainer.opacity = 1
+ else:
+ self.__cursorContainer.opacity = 0
+ if self.__loupe:
+ self.__loupeCursorContainer.opacity = 0
+ elif self.__hasFocus:
+ self.__cursorContainer.opacity = 1
+ if self.__loupe:
+ self.__loupeCursorContainer.opacity = 1
+
+ def __moveHandler(self, offset):
+ self.__addLoupe()
+ event = player.getCurrentEvent()
+ eventPos = self.getRelPos(event.pos)
+ if ( (eventPos[0] >= -1 and eventPos[0] <= self.size[0]) and
+ (eventPos[1] >= 0 and eventPos[1] <= self.size[1]) ):
+ self.__updateCursorPosition(event)
+ else:
+ self.__upHandler(None)
+
+ def __detectedHandler(self):
+ event = player.getCurrentEvent()
+ self.__updateCursorPosition(event)
+ self.__timerID = player.setTimeout(1000, self.__addLoupe)
+
+ def __addLoupe(self):
+ if not self.__loupe.getParent():
+ self.appendChild(self.__loupe)
+
+ def __upHandler (self, offset):
+ player.clearInterval(self.__timerID)
+ if self.__loupe.getParent():
+ self.__loupe.unlink()
+
+ def __selectTextLine(self, pos, textNode):
+ for line in range(textNode.getNumLines()):
+ curLine = textNode.getLineExtents(line)
+ minMaxHight = (curLine[1] * line,curLine[1] * (line + 1) )
+ if pos[1] >= minMaxHight[0] and pos[1] < minMaxHight[1]:
+ return line
+ return 0
+
+ def __updateCursorPosition(self, event):
+ eventPos = self.__textNode.getRelPos(event.pos)
+ if len(self.__data) > 0:
+ lineWidth = self.__textNode.getLineExtents(self.__selectTextLine(eventPos,
+ self.__textNode))
+ else:
+ lineWidth = Point2D(0,0)
+ if self.__textNode.alignment != "left":
+ if self.__textNode.alignment == "center":
+ eventPos = Point2D(eventPos.x + lineWidth.x / 2, eventPos.y)
+ else:
+ eventPos = Point2D(eventPos.x + lineWidth.x, eventPos.y)
+ length = len(self.__data)
+ if length > 0:
+ index = self.__textNode.getCharIndexFromPos(eventPos) # click on letter
+ if index == None: # click behind line
+ realLines = self.__textNode.getNumLines() - 1
+ for line in range(realLines + 1):
+ curLine = self.__textNode.getLineExtents(line)
+ minMaxHight = (curLine[1] * line,curLine[1] * (line + 1) )
+ if eventPos[1] >= minMaxHight[0] and eventPos[1] < minMaxHight[1]:
+ if curLine[0] != 0: # line with letters
+ correction = 1
+ if self.__textNode.alignment != "left":
+ if eventPos[0] < 0:
+ targetLine = (1, curLine[1] * line)
+ correction = 0
+ else:
+ targetLine = (curLine[0] - 1, curLine[1] * line)
+ else:
+ targetLine = (curLine[0] - 1, curLine[1] * line)
+ index = (self.__textNode.getCharIndexFromPos(targetLine)
+ + correction)
+ else: # empty line
+ count = 0
+ for char in range(length-1):
+ if count < line:
+ if self.__textNode.text[char] == "\n":
+ count += 1
+ else:
+ index = char
+ break
+ break
+ if index == None: # click under text
+ curLine = self.__textNode.getLineExtents(realLines)
+ curLine *= realLines
+ index = self.__textNode.getCharIndexFromPos( (eventPos[0],curLine[1]) )
+ if index == None:
+ index = length
+ self.__cursorPosition = index
+
+ self.__update()
+ self.__updateLoupe(event)
+
+ def __updateLoupe(self, event):
+ # setzt es mittig ueber das orginal
+# self.__zoomedImage.pos = - self.getRelPos(event.pos) + self.__loupe.size / 2.0
+ # add zoomfactor position
+# self.__zoomedImage.pos = - self.getRelPos(event.pos) + self.__loupe.size / 2.0 -\
+# ( 0.0,(self.__textNode.fontsize * self.__loupeZoomFactor))
+ # add scrolling | without zoom positioning
+
+ self.__zoomedImage.pos = - self.getRelPos(event.pos) + self.__loupe.size / 2.0 - \
+ self.getRelPos(event.pos)* self.__loupeZoomFactor + Point2D(0,5)
+ self.__loupe.pos = self.getRelPos(event.pos) - self.__loupeOffset
+##################################
+# MODULE FUNCTIONS
+
+def init(g_avg, catchKeyboard=True, repeatDelay=0.2, charDelay=0.1):
+ """
+ Initialization routine for the module
+
+ This method should be called immediately after avg file
+ load (Player.loadFile())
+ @param g_avg: avg package
+ @param catchKeyboard: boolean, if true events from keyboard are catched
+ @param repeatDelay: wait time (seconds) before starting to repeat a key which
+ is held down
+ @param charDelay: delay among character repetition (of an steadily pressed key)
+ """
+ global avg, g_RepeatDelay, g_CharDelay
+ avg = g_avg
+ g_RepeatDelay = repeatDelay
+ g_CharDelay = charDelay
+
+ player.subscribe(player.ON_FRAME, _onFrame)
+
+ if catchKeyboard:
+ player.subscribe(avg.Player.KEY_DOWN, _onKeyDown)
+ player.subscribe(avg.Player.KEY_UP, _onKeyUp)
+
+def setActiveFocusContext(focusContext):
+ """
+ Tell the module what FocusContext is presently active
+
+ Only one FocusContext at once can be set 'active' and therefore
+ prepared to receive the flow of user events from keyboard.
+ @param focusContext: set the active focusContext. If initialization has been
+ made with 'catchKeyboard' == True, the new active focusContext will receive
+ the flow of events from keyboard.
+ """
+ global g_FocusContext
+
+ if g_FocusContext is not None:
+ g_FocusContext._switchActive(False)
+
+ g_FocusContext = focusContext
+ g_FocusContext._switchActive(True)
+
+def setActivityCallback(pyfunc):
+ """
+ Set a callback that is called at every keyboard's keypress
+
+ If a callback of user interaction is needed (eg: resetting idle timeout)
+ just pass a function to this method, which is going to be called at each
+ user intervention (keydown, keyup).
+ Active focusContext will be passed as argument
+ """
+ global g_activityCallback
+ g_activityCallback = pyfunc
+
+
+def _onFrame():
+ global g_LastKeyEvent, g_LastKeyRepeated, g_CharDelay
+ if (g_LastKeyEvent is not None and
+ time.time() - g_LastKeyRepeated > g_CharDelay and
+ g_FocusContext is not None):
+ g_FocusContext.keyUCodePressed(g_LastKeyEvent.unicode)
+ g_LastKeyRepeated = time.time()
+
+def _onKeyDown(e):
+ global g_LastKeyEvent, g_LastKeyRepeated, g_RepeatDelay, g_activityCallback
+
+ if e.unicode == 0:
+ return
+
+ g_LastKeyEvent = e
+ g_LastKeyRepeated = time.time() + g_RepeatDelay
+
+ if g_FocusContext is not None:
+ g_FocusContext.keyUCodePressed(e.unicode)
+
+ if g_activityCallback is not None:
+ g_activityCallback(g_FocusContext)
+
+def _onKeyUp(e):
+ global g_LastKeyEvent
+
+ g_LastKeyEvent = None
diff --git a/src/python/utils.py b/src/python/utils.py
new file mode 100644
index 0000000..86f76c0
--- /dev/null
+++ b/src/python/utils.py
@@ -0,0 +1,63 @@
+# libavg - Media Playback Engine.
+# Copyright (C) 2003-2014 Ulrich von Zadow
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Current versions can be found at www.libavg.de
+#
+# Original author of this file is Martin Heistermann <mh at sponc dot de>
+#
+
+import os
+
+from libavg import avg, mathutil, player
+
+
+def getMediaDir(_file_=None, subdir='media'):
+ """call with _file_=__file__"""
+ if _file_ == None:
+ _file_ = __file__
+ myDir = os.path.dirname(_file_)
+ mediaDir = os.path.join(myDir, subdir)
+ return os.path.abspath(mediaDir)
+
+def getMediaDirFromNode(node, path=''):
+ '''
+ Recursively build the mediadir path, starting from the given node.
+ '''
+ if node.getParent():
+ if type(node) in (avg.DivNode, avg.AVGNode):
+ return getMediaDirFromNode(node.getParent(), os.path.join(node.mediadir, path))
+ else:
+ return getMediaDirFromNode(node.getParent(), path)
+ else:
+ return path
+
+def createImagePreviewNode(maxSize, absHref):
+ node = player.createNode('image', {'href': absHref})
+ node.size = mathutil.getScaledDim(node.size, max = maxSize)
+ return node
+
+def initFXCache(numFXNodes):
+ nodes = []
+ mediadir = os.path.join(os.path.dirname(__file__), 'data')
+ for i in range(numFXNodes):
+ node = avg.ImageNode(href=mediadir+"/black.png",
+ parent=player.getRootNode())
+ node.setEffect(avg.NullFXNode())
+ nodes.append(node)
+ for node in nodes:
+ node.unlink(True)
+
diff --git a/src/python/widget/Makefile.am b/src/python/widget/Makefile.am
new file mode 100644
index 0000000..ad04474
--- /dev/null
+++ b/src/python/widget/Makefile.am
@@ -0,0 +1,3 @@
+pkgwidgetdir = $(pkgpyexecdir)/widget
+pkgwidget_PYTHON = __init__.py button.py keyboard.py scrollarea.py slider.py base.py \
+ skin.py mediacontrol.py
diff --git a/src/python/widget/__init__.py b/src/python/widget/__init__.py
new file mode 100644
index 0000000..c94febb
--- /dev/null
+++ b/src/python/widget/__init__.py
@@ -0,0 +1,7 @@
+from base import SwitchNode, HStretchNode, VStretchNode, HVStretchNode, Orientation
+from button import Button, BmpButton, TextButton, ToggleButton, BmpToggleButton, CheckBox
+from keyboard import Keyboard
+from scrollarea import ScrollPane, ScrollArea
+from skin import Skin
+from slider import Slider, ScrollBar, ScrollBarTrack, ScrollBarThumb, SliderThumb, ProgressBar
+from mediacontrol import TimeSlider, MediaControl
diff --git a/src/python/widget/base.py b/src/python/widget/base.py
new file mode 100644
index 0000000..7a898e6
--- /dev/null
+++ b/src/python/widget/base.py
@@ -0,0 +1,267 @@
+# -*- coding: utf-8 -*-
+# libavg - Media Playback Engine.
+# Copyright (C) 2003-2014 Ulrich von Zadow
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Current versions can be found at www.libavg.de
+
+from libavg import avg, player
+
+class Orientation():
+ VERTICAL = 0
+ HORIZONTAL = 1
+
+
+def bmpFromSrc(src):
+ if isinstance(src, basestring):
+ return avg.Bitmap(src)
+ elif isinstance(src, avg.Bitmap):
+ return src
+ else:
+ raise RuntimeError("src must be a string or a Bitmap.")
+
+class _StretchNodeBase(avg.DivNode):
+
+ def __init__(self, src=None, parent=None, **kwargs):
+ super(_StretchNodeBase, self).__init__(**kwargs)
+ self.registerInstance(self, parent)
+ if isinstance(src, avg.Bitmap):
+ self._bmp = src
+ else:
+ self._bmp = bmpFromSrc(src)
+
+ self.subscribe(self.SIZE_CHANGED, self._positionNodes)
+
+ def _initNodes(self):
+ self._setSizeFromBmp(self._bmp)
+ self._positionNodes(self.size)
+
+ if player.isPlaying():
+ self._renderImages()
+ else:
+ player.subscribe(avg.Player.PLAYBACK_START, self._renderImages)
+
+ def _setSizeFromBmp(self, bmp):
+ size = bmp.getSize()
+ if self.width == 0:
+ self.width = size.x
+ if self.height == 0:
+ self.height = size.y
+
+ def _checkExtents(self, endsExtent, minExtent):
+ if endsExtent < 0:
+ raise RuntimeError(
+ "Illegal value for endsExtent: %i. Must be >= 0"%endsExtent)
+ elif endsExtent == 0:
+ # 1 has same effect as 0 - we just create one-pixel wide start and end images.
+ endsExtent = 1
+
+ if minExtent == -1:
+ minExtent = endsExtent*2+1
+ else:
+ minExtent = minExtent
+ return (endsExtent, minExtent)
+
+ def _renderImage(self, srcBmp, node, pos, size):
+ canvas = player.createCanvas(id="stretch_canvas", size=size)
+ img = avg.ImageNode(pos=pos, parent=canvas.getRootNode())
+ img.setBitmap(srcBmp)
+ canvas.render()
+ node.setBitmap(canvas.screenshot())
+ player.deleteCanvas("stretch_canvas")
+
+
+class HStretchNode(_StretchNodeBase):
+
+ def __init__(self, endsExtent, minExtent=-1, **kwargs):
+ super(HStretchNode, self).__init__(**kwargs)
+
+ (self.__endsExtent, self.__minExtent) = self._checkExtents(endsExtent, minExtent)
+
+ self.__startImg = avg.ImageNode(parent=self)
+ self.__centerImg = avg.ImageNode(parent=self)
+ self.__endImg = avg.ImageNode(parent=self)
+
+ self._initNodes()
+
+ def _positionNodes(self, newSize):
+ if newSize.x < self.__minExtent:
+ self.width = self.__minExtent
+ else:
+ self.__centerImg.x = self.__endsExtent
+ self.__centerImg.width = newSize.x - self.__endsExtent*2
+ self.__endImg.x = newSize.x - self.__endsExtent
+
+ def _renderImages(self):
+ height = self._bmp.getSize().y
+ self._renderImage(self._bmp, self.__startImg, (0,0), (self.__endsExtent, height))
+ self._renderImage(self._bmp, self.__centerImg,
+ (-self.__endsExtent,0), (1, height))
+ endOffset = self._bmp.getSize().x - self.__endsExtent
+ self._renderImage(self._bmp, self.__endImg,
+ (-endOffset,0), (self.__endsExtent, height))
+
+
+class VStretchNode(_StretchNodeBase):
+
+ def __init__(self, endsExtent, minExtent=-1, **kwargs):
+ super(VStretchNode, self).__init__(**kwargs)
+
+ (self.__endsExtent, self.__minExtent) = self._checkExtents(endsExtent, minExtent)
+
+ self.__startImg = avg.ImageNode(parent=self)
+ self.__centerImg = avg.ImageNode(parent=self)
+ self.__endImg = avg.ImageNode(parent=self)
+
+ self._initNodes()
+
+ def _positionNodes(self, newSize):
+ if newSize.y < self.__minExtent:
+ self.height = self.__minExtent
+ else:
+ self.__centerImg.y = self.__endsExtent
+ self.__centerImg.height = newSize.y - self.__endsExtent*2
+ self.__endImg.y = newSize.y - self.__endsExtent
+
+ def _renderImages(self):
+ width = self._bmp.getSize().x
+ self._renderImage(self._bmp, self.__startImg, (0,0), (width, self.__endsExtent))
+ self._renderImage(self._bmp, self.__centerImg,
+ (0,-self.__endsExtent), (width, 1))
+ endOffset = self._bmp.getSize().y - self.__endsExtent
+ self._renderImage(self._bmp, self.__endImg, (0,-endOffset),
+ (width, self.__endsExtent))
+
+
+class HVStretchNode(_StretchNodeBase):
+
+ def __init__(self, endsExtent, minExtent=(-1,-1), **kwargs):
+ super(HVStretchNode, self).__init__(**kwargs)
+
+ (hEndsExtent, hMinExtent) = self._checkExtents(endsExtent[0], minExtent[0])
+ (vEndsExtent, vMinExtent) = self._checkExtents(endsExtent[1], minExtent[1])
+ self.__endsExtent = avg.Point2D(hEndsExtent, vEndsExtent)
+ self.__minExtent = avg.Point2D(hMinExtent, vMinExtent)
+
+ self.__createNodes()
+
+ self._initNodes()
+
+ def __calcNodePositions(self, newSize):
+ xPosns = (0, self.__endsExtent[0], newSize.x-self.__endsExtent[0], newSize.x)
+ yPosns = (0, self.__endsExtent[1], newSize.y-self.__endsExtent[1], newSize.y)
+
+ self.__nodePosns = []
+ for y in range(4):
+ curRow = []
+ for x in range(4):
+ curRow.append(avg.Point2D(xPosns[x], yPosns[y]))
+ self.__nodePosns.append(curRow)
+
+ def __createNodes(self):
+ self.__nodes = []
+ for y in range(3):
+ curRow = []
+ for x in range(3):
+ node = avg.ImageNode(parent=self)
+ curRow.append(node)
+ self.__nodes.append(curRow)
+
+ def _positionNodes(self, newSize):
+ newSize = avg.Point2D(
+ max(self.__minExtent.x, newSize.x),
+ max(self.__minExtent.y, newSize.y))
+
+ self.__calcNodePositions(newSize)
+
+ for y in range(3):
+ for x in range(3):
+ pos = self.__nodePosns[y][x]
+ size = self.__nodePosns[y+1][x+1] - self.__nodePosns[y][x]
+ node = self.__nodes[y][x]
+ node.pos = pos
+ node.size = size
+
+ def _renderImages(self):
+ bmpSize = self._bmp.getSize()
+ xPosns = (0, self.__endsExtent[0], bmpSize.x-self.__endsExtent[0], bmpSize.x)
+ yPosns = (0, self.__endsExtent[1], bmpSize.y-self.__endsExtent[1], bmpSize.y)
+ for y in range(3):
+ for x in range(3):
+ node = self.__nodes[y][x]
+ pos = avg.Point2D(xPosns[x], yPosns[y])
+ size = avg.Point2D(xPosns[x+1], yPosns[y+1]) - pos
+ if x == 1:
+ size.x = 1
+ if y == 1:
+ size.y = 1
+ self._renderImage(self._bmp, node, -pos, size)
+
+
+class SwitchNode(avg.DivNode):
+
+ def __init__(self, nodeMap=None, visibleid=None, parent=None, **kwargs):
+ super(SwitchNode, self).__init__(**kwargs)
+ self.registerInstance(self, parent)
+
+ self.__nodeMap = None
+ if nodeMap:
+ self.setNodeMap(nodeMap)
+ if visibleid:
+ self.setVisibleID(visibleid)
+
+ self.subscribe(self.SIZE_CHANGED, self.__setChildSizes)
+
+ def setNodeMap(self, nodeMap):
+ if self.__nodeMap is not None:
+ raise RuntimeError("SwitchNode.nodeMap can only be set once.")
+ self.__nodeMap = nodeMap
+ for node in self.__nodeMap.itervalues():
+ if node:
+ # Only insert child if it hasn't been inserted yet.
+ try:
+ self.indexOf(node)
+ except RuntimeError:
+ self.appendChild(node)
+ if self.size != (0,0):
+ size = self.size
+ else:
+ key = list(self.__nodeMap.keys())[0]
+ size = self.__nodeMap[key].size
+ self.size = size
+
+ def getVisibleID(self):
+ return self.__visibleid
+
+ def setVisibleID(self, visibleid):
+ if not (visibleid in self.__nodeMap):
+ raise RuntimeError("'%s' is not a registered id." % visibleid)
+ self.__visibleid = visibleid
+ for node in self.__nodeMap.itervalues():
+ node.active = False
+ self.__nodeMap[visibleid].active = True
+
+ visibleid = property(getVisibleID, setVisibleID)
+
+ def __setChildSizes(self, newSize):
+ if self.__nodeMap:
+ for node in self.__nodeMap.itervalues():
+ if node:
+ node.size = newSize
+ # Hack to support min. size in SwitchNodes containing StretchNodes
+ if node.size > newSize:
+ self.size = node.size
+ return
diff --git a/src/python/widget/button.py b/src/python/widget/button.py
new file mode 100644
index 0000000..f938e46
--- /dev/null
+++ b/src/python/widget/button.py
@@ -0,0 +1,443 @@
+# -*- coding: utf-8 -*-
+# libavg - Media Playback Engine.
+# Copyright (C) 2003-2014 Ulrich von Zadow
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Current versions can be found at www.libavg.de
+#
+# Original author of this file is Henrik Thoms
+
+from libavg import avg, statemachine, player, gesture
+
+from base import SwitchNode, HVStretchNode
+from . import skin
+
+class _ButtonBase(avg.DivNode):
+
+ PRESSED = avg.Publisher.genMessageID()
+ RELEASED = avg.Publisher.genMessageID()
+
+ def __init__(self, parent=None, **kwargs):
+ super(_ButtonBase, self).__init__(**kwargs)
+ self.registerInstance(self, parent)
+ self.publish(self.PRESSED)
+ self.publish(self.RELEASED)
+
+ def _setActiveArea(self, upNode, activeAreaNode, fatFingerEnlarge):
+ if fatFingerEnlarge:
+ if activeAreaNode:
+ raise(RuntimeError(
+ "Button: Can't specify both fatFingerEnlarge and activeAreaNode"))
+ size = upNode.size
+ minSize = 20*player.getPixelsPerMM()
+ size = avg.Point2D(max(minSize, size.x), max(minSize, size.y))
+ activeAreaNode = avg.RectNode(size=size, opacity=0, parent=self)
+ #Here we need to store a 'hard' reference to the active area node
+ #because the tap recognizer won't keep it
+ self.__activeAreaNode = activeAreaNode
+ else:
+ if activeAreaNode == None:
+ activeAreaNode = self
+ else:
+ self.appendChild(activeAreaNode)
+
+ self._tapRecognizer = gesture.TapRecognizer(activeAreaNode,
+ possibleHandler=self._onDown,
+ detectedHandler=self._onTap,
+ failHandler=self._onTapFail)
+
+
+class Button(_ButtonBase):
+
+ CLICKED = avg.Publisher.genMessageID()
+
+ def __init__(self, upNode, downNode, disabledNode=None, activeAreaNode=None,
+ enabled=True, fatFingerEnlarge=False, **kwargs):
+ super(Button, self).__init__(**kwargs)
+
+ if disabledNode == None:
+ disabledNode = upNode
+
+ nodeMap = {
+ "UP": upNode,
+ "DOWN": downNode,
+ "DISABLED": disabledNode
+ }
+ self.__switchNode = SwitchNode(nodeMap=nodeMap, visibleid="UP", parent=self)
+ self.publish(self.CLICKED)
+
+ self.__stateMachine = statemachine.StateMachine("Button", "UP")
+ self.__stateMachine.addState("UP", ("DOWN", "DISABLED"),
+ enterFunc=self._enterUp, leaveFunc=self._leaveUp)
+ self.__stateMachine.addState("DOWN", ("UP", "DISABLED"),
+ enterFunc=self._enterDown, leaveFunc=self._leaveDown)
+ self.__stateMachine.addState("DISABLED", ("UP",),
+ enterFunc=self._enterDisabled, leaveFunc=self._leaveDisabled)
+
+ self._setActiveArea(upNode, activeAreaNode, fatFingerEnlarge)
+
+ if not(enabled):
+ self.setEnabled(False)
+
+ def getEnabled(self):
+ return self.__stateMachine.state != "DISABLED"
+
+ def setEnabled(self, enabled):
+ if enabled:
+ if self.__stateMachine.state == "DISABLED":
+ self.__stateMachine.changeState("UP")
+ else:
+ if self.__stateMachine.state != "DISABLED":
+ self.__stateMachine.changeState("DISABLED")
+
+ enabled = property(getEnabled, setEnabled)
+
+ def _getState(self):
+ return self.__stateMachine.state
+
+ def _onDown(self):
+ self.__stateMachine.changeState("DOWN")
+ self.notifySubscribers(self.PRESSED, [])
+
+ def _onTap(self):
+ self.__stateMachine.changeState("UP")
+ self.notifySubscribers(self.CLICKED, [])
+ self.notifySubscribers(self.RELEASED, [])
+
+ def _onTapFail(self):
+ self.__stateMachine.changeState("UP")
+ self.notifySubscribers(self.RELEASED, [])
+
+ def _enterUp(self):
+ self.__setActiveNode()
+
+ def _leaveUp(self):
+ pass
+
+ def _enterDown(self):
+ self.__setActiveNode()
+
+ def _leaveDown(self):
+ pass
+
+ def _enterDisabled(self):
+ self.__setActiveNode()
+ self._tapRecognizer.enable(False)
+
+ def _leaveDisabled(self):
+ self._tapRecognizer.enable(True)
+
+ def __setActiveNode(self):
+ self.__switchNode.visibleid = self.__stateMachine.state
+
+
+class BmpButton(Button):
+
+ def __init__(self, upSrc, downSrc, disabledSrc=None, **kwargs):
+ upNode = avg.ImageNode(href=upSrc)
+ downNode = avg.ImageNode(href=downSrc)
+ if disabledSrc != None:
+ disabledNode = avg.ImageNode(href=disabledSrc)
+ else:
+ disabledNode = None
+ super(BmpButton, self).__init__(upNode=upNode, downNode=downNode,
+ disabledNode=disabledNode, **kwargs)
+
+
+class TextButton(Button):
+
+ def __init__(self, text, skinObj=skin.Skin.default, **kwargs):
+ size = avg.Point2D(kwargs["size"])
+ cfg = skinObj.defaultTextButtonCfg
+
+ self.wordsNodes = []
+
+ upNode = self.__createStateNode(size, cfg, "upBmp", text, "font")
+ downNode = self.__createStateNode(size, cfg, "downBmp", text, "downFont")
+ if "disabledBmp" in cfg:
+ disabledNode = self.__createStateNode(size, cfg, "disabledBmp", text,
+ "disabledFont")
+ else:
+ disabledNode = None
+
+ super(TextButton, self).__init__(upNode=upNode, downNode=downNode,
+ disabledNode=disabledNode, **kwargs)
+
+ def __createStateNode(self, size, cfg, bmpName, text, fontStyleName):
+ stateNode = avg.DivNode(size=size)
+ endsExtent = eval(cfg["endsExtent"], {}, {})
+ HVStretchNode(size=size, src=cfg[bmpName], endsExtent=endsExtent,
+ parent=stateNode)
+ words = avg.WordsNode(text=text, fontstyle=cfg[fontStyleName], parent=stateNode)
+ words.pos = (round((size.x-words.size.x)/2), round((size.y-words.size.y)/2))
+ self.wordsNodes.append(words)
+ return stateNode
+
+ def getText(self):
+ return self.wordsNodes[0].text
+
+ def setText(self, text):
+ for node in self.wordsNodes:
+ node.text = text
+ node.pos = (self.size-node.size)/2
+
+ text = property(getText, setText)
+
+
+class ToggleButton(_ButtonBase):
+
+ TOGGLED = avg.Publisher.genMessageID()
+
+ def __init__(self, uncheckedUpNode, uncheckedDownNode, checkedUpNode, checkedDownNode,
+ uncheckedDisabledNode=None, checkedDisabledNode=None, activeAreaNode=None,
+ enabled=True, fatFingerEnlarge=False, checked=False, **kwargs):
+ super(ToggleButton, self).__init__(**kwargs)
+ nodeMap = {
+ "UNCHECKED_UP": uncheckedUpNode,
+ "UNCHECKED_DOWN": uncheckedDownNode,
+ "CHECKED_UP": checkedUpNode,
+ "CHECKED_DOWN": checkedDownNode,
+ "UNCHECKED_DISABLED": uncheckedDisabledNode,
+ "CHECKED_DISABLED": checkedDisabledNode,
+ }
+ if uncheckedDisabledNode == None:
+ nodeMap["UNCHECKED_DISABLED"] = uncheckedUpNode
+ if checkedDisabledNode == None:
+ nodeMap["CHECKED_DISABLED"] = checkedUpNode
+ self.__switchNode = SwitchNode(nodeMap=nodeMap, visibleid="UNCHECKED_UP",
+ parent=self)
+
+ self.publish(ToggleButton.TOGGLED)
+
+ self.__stateMachine = statemachine.StateMachine("ToggleButton", "UNCHECKED_UP")
+ self.__stateMachine.addState("UNCHECKED_UP", ("UNCHECKED_DOWN",
+ "UNCHECKED_DISABLED"), enterFunc=self._enterUncheckedUp,
+ leaveFunc=self._leaveUncheckedUp)
+ self.__stateMachine.addState("UNCHECKED_DOWN", ("UNCHECKED_UP",
+ "UNCHECKED_DISABLED", "CHECKED_UP"), enterFunc=self._enterUncheckedDown,
+ leaveFunc=self._leaveUncheckedDown)
+ self.__stateMachine.addState("CHECKED_UP", ("CHECKED_DOWN", "CHECKED_DISABLED"),
+ enterFunc=self._enterCheckedUp, leaveFunc=self._leaveCheckedUp)
+ self.__stateMachine.addState("CHECKED_DOWN", ("CHECKED_UP", "UNCHECKED_UP",
+ "CHECKED_DISABLED"), enterFunc=self._enterCheckedDown,
+ leaveFunc=self._leaveCheckedDown)
+ self.__stateMachine.addState("UNCHECKED_DISABLED", ("UNCHECKED_UP",),
+ enterFunc=self._enterUncheckedDisabled,
+ leaveFunc=self._leaveUncheckedDisabled)
+ self.__stateMachine.addState("CHECKED_DISABLED", ("CHECKED_UP", ),
+ enterFunc=self._enterCheckedDisabled,
+ leaveFunc=self._leaveCheckedDisabled)
+
+ self._setActiveArea(uncheckedUpNode, activeAreaNode, fatFingerEnlarge)
+
+ if not enabled:
+ self.__stateMachine.changeState("UNCHECKED_DISABLED")
+ if checked:
+ self.setChecked(True)
+
+ def getEnabled(self):
+ return (self.__stateMachine.state != "CHECKED_DISABLED" and
+ self.__stateMachine.state != "UNCHECKED_DISABLED")
+
+ def setEnabled(self, enabled):
+ if enabled:
+ if self.__stateMachine.state == "CHECKED_DISABLED":
+ self.__stateMachine.changeState("CHECKED_UP")
+ elif self.__stateMachine.state == "UNCHECKED_DISABLED":
+ self.__stateMachine.changeState("UNCHECKED_UP")
+ else:
+ if (self.__stateMachine.state == "CHECKED_UP" or
+ self.__stateMachine.state == "CHECKED_DOWN") :
+ self.__stateMachine.changeState("CHECKED_DISABLED")
+ elif (self.__stateMachine.state == "UNCHECKED_UP" or
+ self.__stateMachine.state == "UNCHECKED_DOWN") :
+ self.__stateMachine.changeState("UNCHECKED_DISABLED")
+
+ enabled = property(getEnabled, setEnabled)
+
+ def getChecked(self):
+ return (self.__stateMachine.state != "UNCHECKED_UP" and
+ self.__stateMachine.state != "UNCHECKED_DOWN" and
+ self.__stateMachine.state != "UNCHECKED_DISABLED")
+
+ def setChecked(self, checked):
+ oldEnabled = self.getEnabled()
+ if checked:
+ if self.__stateMachine.state == "UNCHECKED_DISABLED":
+ self.__stateMachine.changeState("UNCHECKED_UP")
+ if self.__stateMachine.state == "UNCHECKED_UP":
+ self.__stateMachine.changeState("UNCHECKED_DOWN")
+ if self.__stateMachine.state != "CHECKED_UP":
+ self.__stateMachine.changeState("CHECKED_UP")
+ if not oldEnabled:
+ self.__stateMachine.changeState("CHECKED_DISABLED")
+ else:
+ if self.__stateMachine.state == "CHECKED_DISABLED":
+ self.__stateMachine.changeState("CHECKED_UP")
+ if self.__stateMachine.state == "CHECKED_UP":
+ self.__stateMachine.changeState("CHECKED_DOWN")
+ if self.__stateMachine.state != "UNCHECKED_UP":
+ self.__stateMachine.changeState("UNCHECKED_UP")
+ if not oldEnabled:
+ self.__stateMachine.changeState("UNCHECKED_DISABLED")
+
+ checked = property(getChecked, setChecked)
+
+ def _getState(self):
+ return self.__stateMachine.state
+
+ def _enterUncheckedUp(self):
+ self.__setActiveNode()
+
+ def _leaveUncheckedUp(self):
+ pass
+
+ def _enterUncheckedDown(self):
+ self.__setActiveNode()
+
+ def _leaveUncheckedDown(self):
+ pass
+
+ def _enterCheckedUp(self):
+ self.__setActiveNode()
+
+ def _leaveCheckedUp(self):
+ pass
+
+ def _enterCheckedDown(self):
+ self.__setActiveNode()
+
+ def _leaveCheckedDown(self):
+ pass
+
+ def _enterUncheckedDisabled(self):
+ self.__setActiveNode()
+ self._tapRecognizer.enable(False)
+
+ def _leaveUncheckedDisabled(self):
+ self._tapRecognizer.enable(True)
+
+ def _enterCheckedDisabled(self):
+ self.__setActiveNode()
+ self._tapRecognizer.enable(False)
+
+ def _leaveCheckedDisabled(self):
+ self._tapRecognizer.enable(True)
+
+ def _onDown(self):
+ if self.__stateMachine.state == "UNCHECKED_UP":
+ self.__stateMachine.changeState("UNCHECKED_DOWN")
+ elif self.__stateMachine.state == "CHECKED_UP":
+ self.__stateMachine.changeState("CHECKED_DOWN")
+ self.notifySubscribers(self.PRESSED, [])
+
+ def _onTap(self):
+ if self.__stateMachine.state == "UNCHECKED_DOWN":
+ self.__stateMachine.changeState("CHECKED_UP")
+ self.notifySubscribers(ToggleButton.TOGGLED, [True])
+ elif self.__stateMachine.state == "CHECKED_DOWN":
+ self.__stateMachine.changeState("UNCHECKED_UP")
+ self.notifySubscribers(ToggleButton.TOGGLED, [False])
+ self.notifySubscribers(self.RELEASED, [])
+
+ def _onTapFail(self):
+ if self.__stateMachine.state == "UNCHECKED_DOWN":
+ self.__stateMachine.changeState("UNCHECKED_UP")
+ elif self.__stateMachine.state == "CHECKED_DOWN":
+ self.__stateMachine.changeState("CHECKED_UP")
+ self.notifySubscribers(self.RELEASED, [])
+
+ def __setActiveNode(self):
+ self.__switchNode.visibleid = self.__stateMachine.state
+
+
+class CheckBox(ToggleButton):
+
+ def __init__(self, text="", skinObj=skin.Skin.default, **kwargs):
+ self.cfg = skinObj.defaultCheckBoxCfg
+
+ uncheckedUpNode = self.__createImageNode(self.cfg["uncheckedUpBmp"])
+ uncheckedDownNode = self.__createImageNode(self.cfg["uncheckedDownBmp"])
+ uncheckedDisabledNode = self.__createImageNode(self.cfg["uncheckedDisabledBmp"])
+ checkedUpNode = self.__createImageNode(self.cfg["checkedUpBmp"])
+ checkedDownNode = self.__createImageNode(self.cfg["checkedDownBmp"])
+ checkedDisabledNode = self.__createImageNode(self.cfg["checkedDisabledBmp"])
+
+ super(CheckBox, self).__init__(uncheckedUpNode=uncheckedUpNode,
+ uncheckedDownNode=uncheckedDownNode,
+ uncheckedDisabledNode=uncheckedDisabledNode,
+ checkedUpNode=checkedUpNode,
+ checkedDownNode=checkedDownNode,
+ checkedDisabledNode=checkedDisabledNode,
+ **kwargs)
+ self.textNode = avg.WordsNode(pos=(20,0), text=text, fontstyle=self.cfg["font"],
+ parent=self)
+
+ def _enterUncheckedUp(self):
+ self.textNode.fontstyle = self.cfg["font"]
+ super(CheckBox, self)._enterUncheckedUp()
+
+ def _enterUncheckedDown(self):
+ self.textNode.fontstyle = self.cfg["downFont"]
+ super(CheckBox, self)._enterUncheckedDown()
+
+ def _enterCheckedUp(self):
+ self.textNode.fontstyle = self.cfg["font"]
+ super(CheckBox, self)._enterCheckedUp()
+
+ def _enterCheckedDown(self):
+ self.textNode.fontstyle = self.cfg["downFont"]
+ super(CheckBox, self)._enterCheckedDown()
+
+ def _enterUncheckedDisabled(self):
+ self.textNode.fontstyle = self.cfg["disabledFont"]
+ super(CheckBox, self)._enterUncheckedDisabled()
+
+ def _enterCheckedDisabled(self):
+ self.textNode.fontstyle = self.cfg["disabledFont"]
+ super(CheckBox, self)._enterCheckedDisabled()
+
+ def __createImageNode(self, bmp):
+ node = avg.ImageNode()
+ node.setBitmap(bmp)
+ return node
+
+
+class BmpToggleButton(ToggleButton):
+ def __init__(self, uncheckedUpSrc, uncheckedDownSrc, checkedUpSrc, checkedDownSrc,
+ uncheckedDisabledSrc=None, checkedDisabledSrc=None, **kwargs):
+ uncheckedUpNode = avg.ImageNode(href=uncheckedUpSrc)
+ uncheckedDownNode = avg.ImageNode(href=uncheckedDownSrc)
+ checkedUpNode = avg.ImageNode(href=checkedUpSrc)
+ checkedDownNode = avg.ImageNode(href=checkedDownSrc)
+
+ if uncheckedDisabledSrc != None:
+ uncheckedDisabledNode = avg.ImageNode(href=uncheckedDisabledSrc)
+ else:
+ uncheckedDisabledNode = None
+ if checkedDisabledSrc != None:
+ checkedDisabledNode = avg.ImageNode(href=checkedDisabledSrc)
+ else:
+ checkedDisabledNode = None
+
+ super(BmpToggleButton, self).__init__(uncheckedUpNode=uncheckedUpNode,
+ uncheckedDownNode=uncheckedDownNode,
+ checkedUpNode=checkedUpNode,
+ checkedDownNode=checkedDownNode,
+ uncheckedDisabledNode=uncheckedDisabledNode,
+ checkedDisabledNode=checkedDisabledNode,
+ **kwargs)
+
diff --git a/src/python/widget/keyboard.py b/src/python/widget/keyboard.py
new file mode 100644
index 0000000..cca0afc
--- /dev/null
+++ b/src/python/widget/keyboard.py
@@ -0,0 +1,302 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# libavg - Media Playback Engine.
+# Copyright (C) 2003-2014 Ulrich von Zadow
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Current versions can be found at www.libavg.de
+#
+# Original author of this module: Thomas Schott <scotty at c-base dot org>
+#
+
+import os.path
+
+from libavg import avg, player
+
+FEEDBACK_ZOOM_FACTOR = 1.0
+
+# XXX Merge with base.bmpFromSrc()
+def _bmpFromSrc(node, src):
+ if isinstance(src, basestring):
+ if os.path.isabs(src):
+ effectiveSrc = src
+ else:
+ effectiveSrc = node.getParent().getEffectiveMediaDir() + src
+ return avg.Bitmap(effectiveSrc)
+ elif isinstance(src, avg.Bitmap):
+ return src
+ elif src is None:
+ return None
+ else:
+ raise RuntimeError("src must be a string or a Bitmap.")
+
+class Key(avg.DivNode):
+ # KeyDef is (keyCode, pos, size, isCommand=False)
+ def __init__(self, keyDef, downBmp, feedbackBmp, sticky=False, parent=None,
+ **kwargs):
+ self.__keyCode = keyDef[0]
+ if not(isinstance(self.__keyCode, tuple)):
+ self.__keyCode = (self.__keyCode,)
+ kwargs['pos'] = avg.Point2D(keyDef[1])
+ kwargs['size'] = avg.Point2D(keyDef[2])
+ if len(keyDef) == 4:
+ self.__isCommand = keyDef[3]
+ else:
+ self.__isCommand = False
+ super(Key, self).__init__(**kwargs)
+ self.registerInstance(self, parent)
+
+ self.__sticky = sticky
+ self.__stickyIsDown = False
+ self.__cursorID = None
+ if downBmp:
+ if player.isPlaying():
+ self.__createImages(downBmp, feedbackBmp)
+ else:
+ player.subscribe(avg.Player.PLAYBACK_START,
+ lambda: self.__createImages(downBmp, feedbackBmp))
+
+ def reset(self):
+ if self.__sticky:
+ self.__image.opacity = 0.0
+ self.__stickyIsDown = False
+
+ def isCommand(self):
+ return self.__isCommand
+
+ def getCode(self):
+ return self.__keyCode
+
+ def isStickyDown(self):
+ return self.__sticky and self.__stickyIsDown
+
+ def onDown(self, event):
+ if self.__cursorID:
+ return
+ self.__cursorID = event.cursorid
+ self.__image.opacity = 1.0
+
+ def onUp(self, event):
+ if not self.__cursorID == event.cursorid:
+ return
+ if self.__sticky:
+ self.__stickyIsDown = not(self.__stickyIsDown)
+ if not self.__stickyIsDown:
+ self.__image.opacity = 0.0
+ else:
+ self.__image.opacity = 0.0
+ self.__cursorID = None
+
+ def onOut(self, event):
+ if not self.__cursorID == event.cursorid:
+ return
+ if not(self.__sticky) or (not self.__stickyIsDown):
+ self.__cursorID = None
+ self.__image.opacity = 0.0
+
+ def showFeedback(self, show):
+ if show:
+ self.__feedbackImage.opacity = 0.95
+ else:
+ self.__feedbackImage.opacity = 0.0
+
+ def __createImages(self, downBmp, feedbackBmp):
+ self.__image = avg.ImageNode(parent=self, opacity=0.0)
+ self.__createImage(self.__image, downBmp, 1)
+
+ self.__feedbackImage = avg.ImageNode(parent=self, opacity=0.0)
+ if feedbackBmp and not(self.__isCommand):
+ self.__createImage(self.__feedbackImage, feedbackBmp, 2)
+ self.__feedbackImage.pos = (-self.size.x/2, -self.size.y/3 - \
+ self.__feedbackImage.size.y)
+
+ def __createImage(self, node, bmp, sizeFactor):
+ canvas = player.createCanvas(id="keycanvas", size=self.size*sizeFactor)
+ canvasImage = avg.ImageNode(pos=-self.pos*sizeFactor, parent=canvas.getRootNode())
+ canvasImage.setBitmap(bmp)
+ canvas.render()
+ node.setBitmap(canvas.screenshot())
+ player.deleteCanvas('keycanvas')
+
+
+class Keyboard(avg.DivNode):
+
+ DOWN = avg.Publisher.genMessageID()
+ UP = avg.Publisher.genMessageID()
+ CHAR = avg.Publisher.genMessageID()
+
+ def __init__(self, bgSrc, downSrc, keyDefs, shiftKeyCode, altGrKeyCode=None,
+ stickyShift=False, feedbackSrc=None, parent=None, **kwargs):
+ super(Keyboard, self).__init__(**kwargs)
+ self.registerInstance(self, parent)
+
+ self.__shiftKeyCode = shiftKeyCode
+ self.__shiftDownCounter = 0
+ self.__stickyShift = stickyShift
+ self.__altGrKeyCode = altGrKeyCode
+ self.__altGrKeyCounter = 0
+ if not(self.__shiftKeyCode) and self.__altGrKeyCode:
+ raise RuntimeError(
+ "Keyboard: If there is an altgr key, there must also be a shift key.")
+ self.__codesPerKey = 1
+ if self.__shiftKeyCode:
+ self.__codesPerKey = 2
+ if self.__altGrKeyCode:
+ self.__codesPerKey = 3
+
+ self.__keys = []
+ if bgSrc:
+ bgNode = avg.ImageNode(parent=self)
+ bgNode.setBitmap(_bmpFromSrc(self, bgSrc))
+ for kd in keyDefs:
+ downBmp = _bmpFromSrc(self, downSrc)
+ feedbackBmp = _bmpFromSrc(self, feedbackSrc)
+ if isinstance(kd[0], tuple):
+ while len(kd[0]) < self.__codesPerKey:
+ kd[0] += (kd[0][0],)
+ key = Key(kd, downBmp, feedbackBmp, parent=self)
+ else:
+ sticky =(self.__stickyShift and
+ (self.__shiftKeyCode == kd[0] or self.__altGrKeyCode == kd[0]))
+ key = Key(kd, downBmp, feedbackBmp, sticky=sticky, parent=self)
+ self.__keys.append(key)
+ self.subscribe(avg.Node.CURSOR_DOWN, self.__onCursorDown)
+ self.__curKeys = {}
+ self.__feedbackKey = None
+
+ self.publish(Keyboard.DOWN)
+ self.publish(Keyboard.UP)
+ self.publish(Keyboard.CHAR)
+
+ @classmethod
+ def makeRowKeyDefs(cls, startPos, keySize, spacing, keyStr, shiftKeyStr,
+ altGrKeyStr=None):
+ keyDefs = []
+ curPos = avg.Point2D(startPos)
+ offset = keySize[0]+spacing
+ if (len(shiftKeyStr) != len(keyStr) or
+ (altGrKeyStr and len(altGrKeyStr) != len(keyStr))):
+ raise RuntimeError("makeRowKeyDefs string lengths must be identical.")
+
+ for i in xrange(len(keyStr)):
+ if altGrKeyStr:
+ codes = (keyStr[i], shiftKeyStr[i], altGrKeyStr[i])
+ else:
+ codes = (keyStr[i], shiftKeyStr[i])
+ keyDefs.append([codes, curPos, avg.Point2D(keySize), False])
+ curPos = (curPos[0]+offset, curPos[1])
+ return keyDefs
+
+ def reset(self):
+ for key in self.__keys:
+ key.reset()
+ self.__shiftDownCounter = 0
+ self.__altGrKeyCounter = 0
+
+ def __onCursorDown(self, event):
+ curKey = self.__findKey(event.pos)
+ self.__keyDown(curKey, event)
+ event.contact.subscribe(avg.Contact.CURSOR_MOTION, self.__onCursorMotion)
+ event.contact.subscribe(avg.Contact.CURSOR_UP, self.__onCursorUp)
+
+ def __onCursorMotion(self, event):
+ newKey = self.__findKey(event.pos)
+ oldKey = self.__curKeys[event.contact]
+ if newKey != oldKey:
+ if oldKey:
+ oldKey.onOut(event)
+ self.notifySubscribers(Keyboard.UP, [oldKey.getCode()[0]])
+ if oldKey.isCommand():
+ self.__onCommandKeyUp(oldKey)
+ self.__keyDown(newKey, event)
+
+ def __onCursorUp(self, event):
+ self.__onCursorMotion(event)
+ key = self.__curKeys[event.contact]
+ if key:
+ key.onUp(event)
+ self.notifySubscribers(Keyboard.UP, [key.getCode()[0]])
+ if key.isCommand():
+ self.__onCommandKeyUp(key)
+ else:
+ self.__onCharKeyUp(key.getCode())
+ self.__switchFeedbackKey(None)
+ del self.__curKeys[event.contact]
+
+ def __findKey(self, pos):
+ for key in self.__keys:
+ localPos = key.getRelPos(pos)
+ if self.__isInside(localPos, key):
+ return key
+ return None
+
+ def __isInside(self, pos, node):
+ return (pos.x >= 0 and pos.y >= 0 and
+ pos.x <= node.size.x and pos.y <= node.size.y)
+
+ def __switchFeedbackKey(self, newKey):
+ if self.__feedbackKey:
+ self.__feedbackKey.showFeedback(False)
+ self.__feedbackKey = newKey
+ if self.__feedbackKey:
+ self.__feedbackKey.showFeedback(True)
+
+ def __keyDown(self, key, event):
+ self.__switchFeedbackKey(key)
+ self.__curKeys[event.contact] = key
+ if key:
+ key.onDown(event)
+ if key.isCommand():
+ self.__onCommandKeyDown(key)
+ else:
+ self.__onCharKeyDown(key.getCode())
+
+ def __getCharKeyCode(self, keyCodes):
+ if self.__shiftDownCounter:
+ return keyCodes[1]
+ elif self.__altGrKeyCounter:
+ return keyCodes[2]
+ else:
+ return keyCodes[0]
+
+ def __onCharKeyDown(self, keyCodes):
+ self.notifySubscribers(Keyboard.DOWN, [keyCodes[0]])
+
+ def __onCharKeyUp(self, keyCodes):
+ self.notifySubscribers(Keyboard.CHAR, [self.__getCharKeyCode(keyCodes)])
+
+ def __onCommandKeyDown(self, key):
+ keyCode = key.getCode()[0]
+ if not(key.isStickyDown()):
+ if keyCode == self.__shiftKeyCode:
+ self.__shiftDownCounter += 1
+ if keyCode == self.__altGrKeyCode:
+ self.__altGrKeyCounter += 1
+ self.notifySubscribers(Keyboard.DOWN, [keyCode])
+
+ def __onCommandKeyUp(self, key):
+ keyCode = key.getCode()[0]
+ if not(key.isStickyDown()):
+ if keyCode == self.__shiftKeyCode:
+ if self.__shiftDownCounter > 0:
+ self.__shiftDownCounter -= 1
+ else:
+ avg.logger.warning('Keyboard: ShiftDownCounter=0 on [%s] up'
+ %self.__shiftKeyCode)
+ elif keyCode == self.__altGrKeyCode:
+ if self.__altGrKeyCounter > 0:
+ self.__altGrKeyCounter -= 1
diff --git a/src/python/widget/mediacontrol.py b/src/python/widget/mediacontrol.py
new file mode 100644
index 0000000..3e740d0
--- /dev/null
+++ b/src/python/widget/mediacontrol.py
@@ -0,0 +1,161 @@
+# -*- coding: utf-8 -*-
+# libavg - Media Playback Engine.
+# Copyright (C) 2003-2014 Ulrich von Zadow
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Current versions can be found at www.libavg.de
+
+from libavg import avg
+from . import slider, button, skin
+
+class TimeSlider(slider.Slider):
+
+ def __init__(self, orientation=slider.Orientation.HORIZONTAL,
+ skinObj=skin.Skin.default, **kwargs):
+ self.__progressThumb = None
+ super(TimeSlider, self).__init__(skinObj=skinObj, orientation=orientation,
+ **kwargs)
+
+ if self._orientation == slider.Orientation.HORIZONTAL:
+ progressCfg = skinObj.defaultProgressBarCfg["horizontal"]
+ else:
+ progressCfg = skinObj.defaultProgressBarCfg["vertical"]
+
+ thumbUpBmp = progressCfg["thumbUpBmp"]
+ thumbDisabledBmp = skin.getBmpFromCfg(progressCfg, "thumbDisabledBmp",
+ "thumbUpBmp")
+ endsExtent = progressCfg["thumbEndsExtent"]
+ self.__progressThumb = slider.ScrollBarThumb(orientation=orientation,
+ upBmp=thumbUpBmp, downBmp=thumbUpBmp, disabledBmp=thumbDisabledBmp,
+ endsExtent=endsExtent)
+ self.insertChildAfter(self.__progressThumb, self._trackNode)
+ self._positionNodes()
+
+ def _positionNodes(self, newSliderPos=None):
+ super(TimeSlider, self)._positionNodes(newSliderPos)
+
+ if self.__progressThumb:
+ if self._orientation == slider.Orientation.HORIZONTAL:
+ self.__progressThumb.width = self._thumbNode.x+self._thumbNode.width/2
+ else:
+ self.__progressThumb.height = self._thumbNode.y+self._thumbNode.height/2
+
+
+class MediaControl(avg.DivNode):
+
+ PLAY_CLICKED = avg.Publisher.genMessageID()
+ PAUSE_CLICKED = avg.Publisher.genMessageID()
+ SEEK_PRESSED = avg.Publisher.genMessageID()
+ SEEK_MOTION = avg.Publisher.genMessageID()
+ SEEK_RELEASED = avg.Publisher.genMessageID()
+
+ def __init__(self, skinObj=skin.Skin.default, duration=1000, time=0, parent=None,
+ **kwargs):
+ super(MediaControl, self).__init__(**kwargs)
+ self.registerInstance(self, parent)
+
+ cfg = skinObj.defaultMediaControlCfg
+
+ # subscribe to button & slider changes
+ self._playButton = button.ToggleButton(
+ uncheckedUpNode=self.__createImageNode(cfg, "playUpBmp"),
+ uncheckedDownNode=self.__createImageNode(cfg, "playDownBmp"),
+ uncheckedDisabledNode=self.__createImageNode(cfg, "playDisabledBmp",
+ "playUpBmp"),
+ checkedUpNode=self.__createImageNode(cfg, "pauseUpBmp"),
+ checkedDownNode=self.__createImageNode(cfg, "pauseDownBmp"),
+ checkedDisabledNode=self.__createImageNode(cfg, "pauseDisabledBmp",
+ "pauseUpBmp"),
+ parent=self)
+ self._playButton.subscribe(button.ToggleButton.TOGGLED, self.__onTogglePlay)
+
+ sliderWidth = self.width + cfg["barRight"] - cfg["barPos"][0]
+ self._timeSlider = TimeSlider(skinObj=skinObj, pos=cfg["barPos"],
+ width=sliderWidth, parent=self)
+ self._timeSlider.subscribe(TimeSlider.PRESSED, self.__onSliderPressed)
+ self._timeSlider.subscribe(TimeSlider.RELEASED, self.__onSliderReleased)
+ self._timeSlider.subscribe(TimeSlider.THUMB_POS_CHANGED, self.__onSliderMotion)
+
+ self._timeNode = avg.WordsNode(pos=cfg["timePos"], fontstyle=cfg["font"],
+ color="FFFFFF", parent=self)
+ timeLeftPos = (self.width+cfg["timeLeftPos"][0], cfg["timeLeftPos"][1])
+ self._timeLeftNode = avg.WordsNode(pos=timeLeftPos, fontstyle=cfg["font"],
+ color="FFFFFF", parent=self)
+
+ self.setDuration(duration)
+ self.setTime(time)
+
+ self.publish(MediaControl.PLAY_CLICKED)
+ self.publish(MediaControl.PAUSE_CLICKED)
+ self.publish(MediaControl.SEEK_PRESSED)
+ self.publish(MediaControl.SEEK_MOTION)
+ self.publish(MediaControl.SEEK_RELEASED)
+
+ def play(self):
+ self._playButton.checked = True
+
+ def pause(self):
+ self._playButton.checked = False
+
+ def getDuration(self):
+ return self._timeSlider.range[1]
+
+ def setDuration(self, duration):
+ self._timeSlider.range = (0, duration-100)
+ self.__updateText()
+ duration = property(getDuration, setDuration)
+
+ def getTime(self):
+ return self._timeSlider.thumbPos
+
+ def setTime(self, curTime):
+ self._timeSlider.thumbPos = curTime
+ self.__updateText()
+ time = property(getTime, setTime)
+
+ def __onTogglePlay(self, play):
+ if play:
+ self.notifySubscribers(MediaControl.PLAY_CLICKED, [])
+ else:
+ self.notifySubscribers(MediaControl.PAUSE_CLICKED, [])
+
+ def __onSliderPressed(self):
+ self.notifySubscribers(MediaControl.SEEK_PRESSED, [])
+
+ def __onSliderReleased(self):
+ self.notifySubscribers(MediaControl.SEEK_RELEASED, [])
+
+ def __onSliderMotion(self, curTime):
+ self.__updateText()
+ self.notifySubscribers(MediaControl.SEEK_MOTION, [curTime])
+
+ def __updateText(self):
+ self._timeNode.text = self.__msToMinSec(self._timeSlider.thumbPos)
+ self._timeLeftNode.text = "-"+self.__msToMinSec(
+ (self._timeSlider.range[1]-self._timeSlider.thumbPos))
+
+ def __createImageNode(self, cfg, src, defaultSrc=None):
+ bmp = skin.getBmpFromCfg(cfg, src, defaultSrc)
+ node = avg.ImageNode()
+ node.setBitmap(bmp)
+ return node
+
+ def __msToMinSec(self, ms):
+ ms += 500
+ minutes, ms = divmod(ms, 60000)
+ seconds, ms = divmod(ms, 1000)
+ return "%d:%02d"%(minutes, seconds)
+
diff --git a/src/python/widget/scrollarea.py b/src/python/widget/scrollarea.py
new file mode 100644
index 0000000..d22877f
--- /dev/null
+++ b/src/python/widget/scrollarea.py
@@ -0,0 +1,240 @@
+# -*- coding: utf-8 -*-
+# libavg - Media Playback Engine.
+# Copyright (C) 2003-2014 Ulrich von Zadow
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Current versions can be found at www.libavg.de
+#
+
+from libavg import avg, gesture
+from . import slider
+from base import HVStretchNode, Orientation
+from . import skin
+
+class ScrollPane(avg.DivNode):
+
+ def __init__(self, contentNode, parent=None, **kwargs):
+
+ super(ScrollPane, self).__init__(crop=True, **kwargs)
+ self.registerInstance(self, parent)
+
+ self.appendChild(contentNode)
+ self._contentNode = contentNode
+
+ def setContentPos(self, pos):
+
+ def constrain(pos, limit):
+ if limit > 0:
+ # Content larger than container
+ if pos > limit:
+ pos = limit
+ elif pos < 0:
+ pos = 0
+ else:
+ # Content smaller than container
+ if pos > 0:
+ pos = 0
+ elif pos < limit:
+ pos = limit
+ return pos
+
+ maxPos = self.getMaxContentPos()
+ pos = avg.Point2D(pos)
+ pos.x = constrain(pos.x, maxPos.x)
+ pos.y = constrain(pos.y, maxPos.y)
+ self._contentNode.pos = -pos
+
+ def getContentPos(self):
+ return -self._contentNode.pos
+ contentpos = property(getContentPos, setContentPos)
+
+ def getContentSize(self):
+ return self._contentNode.size
+
+ def setContentSize(self, size):
+ self._contentNode.size = size
+ self.setContentPos(-self._contentNode.pos) # Recheck constraints.
+ contentsize = property(getContentSize, setContentSize)
+
+ def getMaxContentPos(self):
+ maxPos = avg.Point2D(self._contentNode.size - self.size)
+ if maxPos.x < 0:
+ maxPos.x = 0
+ if maxPos.y < 0:
+ maxPos.y = 0
+ return maxPos
+
+
+class ScrollArea(avg.DivNode):
+
+ PRESSED = avg.Publisher.genMessageID()
+ RELEASED = avg.Publisher.genMessageID()
+ CONTENT_POS_CHANGED = avg.Publisher.genMessageID()
+
+ def __init__(self, contentNode, size, skinObj=skin.Skin.default, enabled=True,
+ scrollBars=(Orientation.HORIZONTAL, Orientation.VERTICAL),
+ parent=None, **kwargs):
+
+ super(ScrollArea, self).__init__(**kwargs)
+ self.registerInstance(self, parent)
+ self.cfg = skinObj.defaultScrollAreaCfg
+
+ self.publish(self.PRESSED)
+ self.publish(self.RELEASED)
+ self.publish(self.CONTENT_POS_CHANGED)
+
+ self.__scrollPane = ScrollPane(contentNode=contentNode, parent=self)
+
+ if "borderBmp" in self.cfg:
+ endsExtent = self.cfg["borderEndsExtent"]
+ self._borderNode = HVStretchNode(src=self.cfg["borderBmp"],
+ endsExtent=endsExtent, sensitive=False, parent=self)
+ else:
+ self._borderNode = None
+
+ sensitiveScrollBars = self.cfg["sensitiveScrollBars"]
+
+ if Orientation.HORIZONTAL in scrollBars:
+ self._hScrollBar = slider.ScrollBar(sensitive=sensitiveScrollBars,
+ parent=self, skinObj=skinObj)
+ self._hScrollBar.subscribe(slider.Slider.THUMB_POS_CHANGED,
+ self.__onHThumbMove)
+ else:
+ self._hScrollBar = None
+
+ if Orientation.VERTICAL in scrollBars:
+ self._vScrollBar = slider.ScrollBar(orientation=Orientation.VERTICAL,
+ sensitive=sensitiveScrollBars, parent=self, skinObj=skinObj)
+ self._vScrollBar.subscribe(slider.Slider.THUMB_POS_CHANGED,
+ self.__onVThumbMove)
+ else:
+ self._vScrollBar = None
+
+ self.subscribe(self.SIZE_CHANGED, self.__positionNodes)
+ self.size = size
+
+ self.__enabled = True
+ if not(enabled):
+ self.setEnabled(False)
+
+ self.recognizer = gesture.DragRecognizer(
+ eventNode=self.__scrollPane,
+ detectedHandler=self.__onDragStart,
+ moveHandler=self.__onDragMove,
+ upHandler=self.__onDragUp,
+ friction=self.cfg["friction"]
+ )
+
+ def getContentSize(self):
+ return self.__scrollPane._contentNode.size
+
+ def setContentSize(self, size):
+ self.__scrollPane.contentsize = size
+ self.__positionNodes(self.size)
+ contentsize = property(getContentSize, setContentSize)
+
+ def getContentPos(self):
+ return self.__scrollPane.contentpos
+
+ def setContentPos(self, pos):
+ self.__scrollPane.contentpos = pos
+ self.__positionNodes(self.size)
+ self.__positionThumbs(avg.Point2D(pos))
+ self.notifySubscribers(self.CONTENT_POS_CHANGED, [self.__scrollPane.contentpos])
+ contentpos = property(getContentPos, setContentPos)
+
+ def getEnabled(self):
+ return self.__enabled
+
+ def setEnabled(self, enabled):
+ if enabled and not(self.__enabled):
+ self.recognizer.enable(True)
+ elif not(enabled) and self.__enabled:
+ self.recognizer.enable(False)
+
+ if self._vScrollBar:
+ self._vScrollBar.enabled = enabled
+ if self._hScrollBar:
+ self._hScrollBar.enabled = enabled
+ self.__enabled = enabled
+ enabled = property(getEnabled, setEnabled)
+
+ def __onHThumbMove(self, thumbPos):
+ self.__scrollPane.contentpos = (thumbPos, self.__scrollPane.contentpos.y)
+ self.notifySubscribers(self.CONTENT_POS_CHANGED, [self.__scrollPane.contentpos])
+
+ def __onVThumbMove(self, thumbPos):
+ self.__scrollPane.contentpos = (self.__scrollPane.contentpos.x, thumbPos)
+ self.notifySubscribers(self.CONTENT_POS_CHANGED, [self.__scrollPane.contentpos])
+
+ def __onDragStart(self):
+ self.__dragStartPos = self.__scrollPane.contentpos
+ self.notifySubscribers(self.PRESSED, [])
+
+ def __onDragMove(self, offset):
+ contentpos = self.__dragStartPos - offset
+ self.__scrollPane.contentpos = contentpos
+ self.__positionThumbs(contentpos)
+ self.notifySubscribers(self.CONTENT_POS_CHANGED, [self.__scrollPane.contentpos])
+
+ def __onDragUp(self, offset):
+ self.__onDragMove(offset)
+ self.notifySubscribers(self.RELEASED, [])
+
+ def __positionNodes(self, size):
+ paneSize = size
+ if self._borderNode:
+ self._borderNode.size = size
+
+ margins = self.cfg["margins"]
+ if self._hScrollBar:
+ paneSize -= (0, margins[0]+margins[2])
+ if self._vScrollBar:
+ paneSize -= (margins[1]+margins[3], 0)
+ self.__scrollPane.pos = (margins[0], margins[1])
+ self.__scrollPane.size = paneSize
+
+
+ if self._hScrollBar:
+ self._hScrollBar.pos = (0, size.y-self._hScrollBar.height)
+ self._hScrollBar.width = self.__scrollPane.width
+
+ if self.__scrollPane.contentsize.x <= self.__scrollPane.width:
+ self._hScrollBar.range = (0, self.__scrollPane.width)
+ self._hScrollBar.enabled = False
+ else:
+ self._hScrollBar.range = (0, self.__scrollPane.contentsize.x)
+ self._hScrollBar.enabled = True
+ self._hScrollBar.thumbExtent = self.__scrollPane.width
+
+ if self._vScrollBar:
+ self._vScrollBar.pos = (size.x-self._vScrollBar.width, 0)
+ self._vScrollBar.height = self.__scrollPane.height
+
+ if self.__scrollPane.contentsize.y <= self.__scrollPane.height:
+ self._vScrollBar.range = (0, self.__scrollPane.height)
+ self._vScrollBar.enabled = False
+ else:
+ self._vScrollBar.range = (0, self.__scrollPane.contentsize.y)
+ self._vScrollBar.enabled = True
+ self._vScrollBar.thumbExtent = self.__scrollPane.height
+
+ def __positionThumbs(self, contentPos):
+ if self._hScrollBar:
+ self._hScrollBar.thumbPos = contentPos.x
+ if self._vScrollBar:
+ self._vScrollBar.thumbPos = contentPos.y
+
diff --git a/src/python/widget/skin.py b/src/python/widget/skin.py
new file mode 100644
index 0000000..9490d40
--- /dev/null
+++ b/src/python/widget/skin.py
@@ -0,0 +1,161 @@
+# -*- coding: utf-8 -*-
+# libavg - Media Playback Engine.
+# Copyright (C) 2003-2014 Ulrich von Zadow
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Current versions can be found at www.libavg.de
+
+from libavg import avg
+
+import os, copy
+import xml.etree.ElementTree as ET
+
+class Skin:
+
+ default = None
+
+ def __init__(self, skinXmlFName, mediaDir=""):
+ global defaultMediaDir
+ self.__mediaDir = defaultMediaDir if mediaDir == "" else mediaDir
+ schemaFName = defaultMediaDir+"skin.xsd"
+ schemaString = open(schemaFName, "r").read()
+ skinPath = os.path.join(self.__mediaDir, skinXmlFName)
+ xmlString = open(skinPath, "r").read()
+ avg.validateXml(xmlString, schemaString, skinXmlFName, schemaFName)
+
+ xmlRoot = ET.fromstring(xmlString)
+
+ self.fonts = {}
+ for fontNode in xmlRoot.findall("fontdef"):
+ fontid, attrs = self.__splitAttrs(fontNode)
+ if "baseid" in attrs:
+ self.fonts[fontid] = copy.copy(self.fonts[attrs["baseid"]])
+ font = self.fonts[fontid]
+ del attrs["baseid"]
+ for (key, value) in attrs.iteritems():
+ setattr(font, key, value)
+ else:
+ kwargs = self.__extractArgs(attrs,
+ ("fontsize", "letterspacing", "linespacing"))
+ self.fonts[fontid] = avg.FontStyle(**kwargs)
+
+ self.textButtonCfg, self.defaultTextButtonCfg = self.__parseElement(
+ xmlRoot, "textbutton",
+ bmpArgNames={"upSrc": "upBmp", "downSrc": "downBmp",
+ "disabledSrc": "disabledBmp"},
+ fontArgNames=("font", "downFont", "disabledFont"))
+
+ self.checkBoxCfg, self.defaultCheckBoxCfg = self.__parseElement(
+ xmlRoot, "checkbox",
+ bmpArgNames={"uncheckedUpSrc":"uncheckedUpBmp",
+ "uncheckedDownSrc":"uncheckedDownBmp",
+ "uncheckedDisabledSrc":"uncheckedDisabledBmp",
+ "checkedUpSrc":"checkedUpBmp",
+ "checkedDownSrc":"checkedDownBmp",
+ "checkedDisabledSrc":"checkedDisabledBmp"},
+ fontArgNames=("font", "downFont", "disabledFont"))
+
+ self.sliderCfg, self.defaultSliderCfg = self.__initSliders(xmlRoot, "slider")
+ self.scrollBarCfg, self.defaultScrollBarCfg = self.__initSliders(
+ xmlRoot, "scrollbar")
+ self.progressBarCfg, self.defaultProgressBarCfg = self.__initSliders(
+ xmlRoot, "progressbar")
+
+ self.scrollAreaCfg, self.defaultScrollAreaCfg = self.__parseElement(
+ xmlRoot, "scrollarea",
+ pyArgNames=("friction","borderEndsExtent","margins",
+ "sensitiveScrollBars"),
+ bmpArgNames={"borderSrc":"borderBmp"})
+
+ self.mediaControlCfg, self.defaultMediaControlCfg = self.__parseElement(
+ xmlRoot, "mediacontrol",
+ bmpArgNames={"playUpSrc":"playUpBmp",
+ "playDownSrc":"playDownBmp",
+ "playDisabledSrc":"playDisabledBmp",
+ "pauseUpSrc":"pauseUpBmp",
+ "pauseDownSrc":"pauseDownBmp",
+ "pauseDisabledSrc":"pauseDisabledBmp"},
+ pyArgNames=("timePos", "timeLeftPos", "barPos", "barRight"),
+ fontArgNames=("font"))
+
+ def __parseElement(self, xmlRoot, elementName, pyArgNames=(), bmpArgNames={},
+ fontArgNames=()):
+ cfgMap = {}
+ defaultCfg = None
+ for node in xmlRoot.findall(elementName):
+ nodeid, attrs = self.__splitAttrs(node)
+ kwargs = self.__extractArgs(attrs, pyArgNames=pyArgNames,
+ bmpArgNames=bmpArgNames, fontArgNames=fontArgNames)
+ cfgMap[nodeid] = kwargs
+ if defaultCfg == None or nodeid == None:
+ defaultCfg = kwargs
+ return cfgMap, defaultCfg
+
+ def __splitAttrs(self, xmlNode):
+ attrs = xmlNode.attrib
+ if "id" in attrs:
+ nodeID = attrs["id"]
+ del attrs["id"]
+ else:
+ nodeID = None
+ return nodeID, attrs
+
+ def __extractArgs(self, attrs, pyArgNames=(), bmpArgNames={}, fontArgNames=()):
+ kwargs = {}
+ for (key, value) in attrs.iteritems():
+ if key in pyArgNames:
+ kwargs[key] = eval(value)
+ elif key in bmpArgNames.iterkeys():
+ argkey = bmpArgNames[key]
+ kwargs[argkey] = avg.Bitmap(os.path.join(self.__mediaDir, value))
+ elif key in fontArgNames:
+ kwargs[key] = self.fonts[value]
+ else:
+ kwargs[key] = value
+ return kwargs
+
+ def __initSliders(self, xmlRoot, typeName):
+ sliderCfg = {}
+ defaultSliderCfg = None
+ for sliderXmlNode in xmlRoot.findall(typeName):
+ (nodeID, bogus) = self.__splitAttrs(sliderXmlNode)
+ sliderCfg[nodeID] = {}
+ if defaultSliderCfg == None or nodeID == None:
+ defaultSliderCfg = sliderCfg[nodeID]
+ for xmlNode in sliderXmlNode.findall("*"):
+ # Loop through orientations (horiz, vert)
+ bogus, attrs = self.__splitAttrs(xmlNode)
+ kwargs = self.__extractArgs(attrs,
+ pyArgNames=("trackEndsExtent", "thumbEndsExtent"),
+ bmpArgNames={"trackSrc": "trackBmp",
+ "trackDisabledSrc": "trackDisabledBmp",
+ "thumbUpSrc": "thumbUpBmp",
+ "thumbDownSrc": "thumbDownBmp",
+ "thumbDisabledSrc": "thumbDisabledBmp"})
+ sliderCfg[nodeID][xmlNode.tag] = kwargs
+
+ return (sliderCfg, defaultSliderCfg)
+
+
+def getBmpFromCfg(cfg, bmpName, defaultName=None):
+ if bmpName in cfg:
+ return cfg[bmpName]
+ else:
+ return cfg[defaultName]
+
+
+defaultMediaDir = os.path.join(os.path.dirname(__file__), "..", 'data/')
+Skin.default = Skin("SimpleSkin.xml", "")
diff --git a/src/python/widget/slider.py b/src/python/widget/slider.py
new file mode 100644
index 0000000..1e63f0a
--- /dev/null
+++ b/src/python/widget/slider.py
@@ -0,0 +1,371 @@
+# -*- coding: utf-8 -*-
+# libavg - Media Playback Engine.
+# Copyright (C) 2003-2014 Ulrich von Zadow
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Current versions can be found at www.libavg.de
+
+from libavg import avg, gesture
+from base import SwitchNode, HStretchNode, VStretchNode, Orientation
+from . import skin
+
+import math
+
+
+class ScrollBarTrack(SwitchNode):
+
+ def __init__(self, bmp, endsExtent, disabledBmp, orientation=Orientation.HORIZONTAL,
+ **kwargs):
+
+ super(ScrollBarTrack, self).__init__(nodeMap=None, **kwargs)
+ if orientation == Orientation.HORIZONTAL:
+ StretchNode = HStretchNode
+ else:
+ StretchNode = VStretchNode
+ self.__enabledNode = StretchNode(src=bmp, endsExtent=endsExtent, parent=self)
+ self.__disabledNode = StretchNode(src=disabledBmp, endsExtent=endsExtent,
+ parent=self)
+
+ self.setNodeMap({
+ "ENABLED": self.__enabledNode,
+ "DISABLED": self.__disabledNode
+ })
+ self.visibleid = "ENABLED"
+
+
+class ScrollBarThumb(SwitchNode):
+
+ def __init__(self, upBmp, downBmp, disabledBmp, endsExtent,
+ orientation=Orientation.HORIZONTAL, minExtent=-1,
+ **kwargs):
+
+ super(ScrollBarThumb, self).__init__(nodeMap=None, **kwargs)
+
+ if orientation == Orientation.HORIZONTAL:
+ StretchNode = HStretchNode
+ else:
+ StretchNode = VStretchNode
+ self.__upNode = StretchNode(src=upBmp, endsExtent=endsExtent, minExtent=minExtent)
+ self.__downNode = StretchNode(src=downBmp, endsExtent=endsExtent,
+ minExtent=minExtent)
+ self.__disabledNode = StretchNode(src=disabledBmp, endsExtent=endsExtent,
+ minExtent=minExtent)
+
+ self.setNodeMap({
+ "UP": self.__upNode,
+ "DOWN": self.__downNode,
+ "DISABLED": self.__disabledNode
+ })
+ self.visibleid = "UP"
+
+
+class SliderThumb(SwitchNode):
+
+ def __init__(self, upBmp, downBmp, disabledBmp, **kwargs):
+ upNode = avg.ImageNode()
+ upNode.setBitmap(upBmp)
+ downNode = avg.ImageNode()
+ downNode.setBitmap(downBmp)
+ disabledNode = avg.ImageNode()
+ disabledNode.setBitmap(disabledBmp)
+ nodeMap = {"UP": upNode, "DOWN": downNode, "DISABLED": disabledNode}
+ super(SliderThumb, self).__init__(nodeMap=nodeMap, visibleid="UP", **kwargs)
+
+
+class ProgressBar(avg.DivNode):
+
+ def __init__(self, orientation, skinObj=skin.Skin.default, height=0, width=0,
+ range=(0.,1.), value=0.0, parent=None, **kwargs):
+ super(ProgressBar, self).__init__(**kwargs)
+ self.registerInstance(self, parent)
+ if orientation == Orientation.HORIZONTAL:
+ cfg = skinObj.defaultProgressBarCfg["horizontal"]
+ else:
+ cfg = skinObj.defaultProgressBarCfg["vertical"]
+
+ self._orientation = orientation
+
+ trackBmp = cfg["trackBmp"]
+ self._trackNode = ScrollBarTrack(bmp=trackBmp, disabledBmp=trackBmp,
+ endsExtent=cfg["trackEndsExtent"], orientation=self._orientation)
+ self.appendChild(self._trackNode)
+
+ thumbUpBmp = cfg["thumbUpBmp"]
+ endsExtent=cfg["thumbEndsExtent"]
+
+ self.__thumbNode = ScrollBarThumb(orientation=self._orientation,
+ upBmp=thumbUpBmp, downBmp=thumbUpBmp, disabledBmp=thumbUpBmp,
+ endsExtent=endsExtent)
+ self.appendChild(self.__thumbNode)
+
+ self.__range = range
+ self.__value = value
+
+ if orientation == Orientation.HORIZONTAL:
+ self.size = (width, trackBmp.getSize().y)
+ else:
+ self.size = (trackBmp.getSize().x, height)
+ self._positionNodes()
+
+ def getRange(self):
+ return self.__range
+
+ def setRange(self, range):
+ self.__range = (float(range[0]), float(range[1]))
+ self._positionNodes()
+ range = property(getRange, setRange)
+
+ def getValue(self):
+ return self.__value
+
+ def setValue(self, value):
+ self._positionNodes(value)
+ value = property(getValue, setValue)
+
+ def _positionNodes(self, newValue=None):
+ if newValue is not None:
+ self.__value = float(newValue)
+ if self.__value < self.__range[0]:
+ self.__value = self.__range[0]
+ if self.__value > self.__range[1]:
+ self.__value = self.__range[1]
+ self._trackNode.size = self.size
+
+ effectiveRange = math.fabs(self.__range[1] - self.__range[0])
+ normValue = ((self.__value-self.__range[0])/effectiveRange)
+ if self._orientation == Orientation.HORIZONTAL:
+ self.__thumbNode.width = normValue*self.size.x
+ else:
+ self.__thumbNode.height = normValue*self.size.y
+
+
+class SliderBase(avg.DivNode):
+
+ THUMB_POS_CHANGED = avg.Publisher.genMessageID()
+ PRESSED = avg.Publisher.genMessageID()
+ RELEASED = avg.Publisher.genMessageID()
+
+ def __init__(self, orientation, cfg, enabled=True, height=0, width=0, range=(0.,1.),
+ thumbPos=0.0, parent=None, **kwargs):
+ super(SliderBase, self).__init__(**kwargs)
+ self.registerInstance(self, parent)
+
+ self.publish(SliderBase.THUMB_POS_CHANGED)
+ self.publish(SliderBase.PRESSED)
+ self.publish(SliderBase.RELEASED)
+
+ self._orientation = orientation
+
+ trackBmp = cfg["trackBmp"]
+ trackDisabledBmp = cfg["trackDisabledBmp"]
+ self._trackNode = ScrollBarTrack(bmp=trackBmp, disabledBmp=trackDisabledBmp,
+ endsExtent=cfg["trackEndsExtent"], orientation=self._orientation)
+ self.appendChild(self._trackNode)
+
+ self._initThumb(cfg)
+
+ self._range = range
+ self._thumbPos = thumbPos
+
+ self.subscribe(self.SIZE_CHANGED, lambda newSize: self._positionNodes())
+ if orientation == Orientation.HORIZONTAL:
+ self.size = (width, trackBmp.getSize().y)
+ else:
+ self.size = (trackBmp.getSize().x, height)
+ if not(enabled):
+ self.setEnabled(False)
+
+ self.__recognizer = gesture.DragRecognizer(self._thumbNode, friction=-1,
+ detectedHandler=self.__onDragStart, moveHandler=self.__onDrag,
+ upHandler=self.__onUp)
+
+ def getRange(self):
+ return self._range
+
+ def setRange(self, range):
+ self._range = (float(range[0]), float(range[1]))
+ self._positionNodes()
+
+ # range[1] > range[0]: Reversed scrollbar.
+ range = property(getRange, setRange)
+
+ def getThumbPos(self):
+ return self._thumbPos
+
+ def setThumbPos(self, thumbPos):
+ self._positionNodes(thumbPos)
+
+ thumbPos = property(getThumbPos, setThumbPos)
+
+ def getEnabled(self):
+ return self._trackNode.visibleid != "DISABLED"
+
+ def setEnabled(self, enabled):
+ if enabled:
+ if self._trackNode.visibleid == "DISABLED":
+ self._trackNode.visibleid = "ENABLED"
+ self._thumbNode.visibleid = "UP"
+ self.__recognizer.enable(True)
+ else:
+ if self._trackNode.visibleid != "DISABLED":
+ self._trackNode.visibleid = "DISABLED"
+ self._thumbNode.visibleid = "DISABLED"
+ self.__recognizer.enable(False)
+
+ enabled = property(getEnabled, setEnabled)
+
+ def _positionNodes(self, newSliderPos=None):
+ if newSliderPos is not None:
+ self._thumbPos = float(newSliderPos)
+ self._trackNode.size = self.size
+
+ self._constrainSliderPos()
+
+ pixelRange = self._getScrollRangeInPixels()
+ if self._getSliderRange() == 0:
+ thumbPixelPos = 0
+ else:
+ thumbPixelPos = (((self._thumbPos-self._range[0])/self._getSliderRange())*
+ pixelRange)
+ if self._orientation == Orientation.HORIZONTAL:
+ self._thumbNode.x = thumbPixelPos
+ else:
+ self._thumbNode.y = thumbPixelPos
+
+ def __onDragStart(self):
+ self._thumbNode.visibleid = "DOWN"
+ self.__dragStartPos = self._thumbPos
+ self.notifySubscribers(Slider.PRESSED, [])
+
+ def __onDrag(self, offset):
+ pixelRange = self._getScrollRangeInPixels()
+ if pixelRange == 0:
+ normalizedOffset = 0
+ else:
+ if self._orientation == Orientation.HORIZONTAL:
+ normalizedOffset = offset.x/pixelRange
+ else:
+ normalizedOffset = offset.y/pixelRange
+ oldThumbPos = self._thumbPos
+ self._positionNodes(self.__dragStartPos + normalizedOffset*self._getSliderRange())
+ if self._thumbPos != oldThumbPos:
+ self.notifySubscribers(Slider.THUMB_POS_CHANGED, [self._thumbPos])
+
+ def __onUp(self, offset):
+ self.__onDrag(offset)
+ self._thumbNode.visibleid = "UP"
+ self.notifySubscribers(Slider.RELEASED, [])
+
+
+class Slider(SliderBase):
+
+ def __init__(self, orientation=Orientation.HORIZONTAL, skinObj=skin.Skin.default,
+ **kwargs):
+ if orientation == Orientation.HORIZONTAL:
+ cfg = skinObj.defaultSliderCfg["horizontal"]
+ else:
+ cfg = skinObj.defaultSliderCfg["vertical"]
+ super(Slider, self).__init__(orientation, cfg, **kwargs)
+
+ def _initThumb(self, cfg):
+ thumbUpBmp = cfg["thumbUpBmp"]
+ thumbDownBmp = skin.getBmpFromCfg(cfg, "thumbDownBmp", "thumbUpBmp")
+ thumbDisabledBmp = skin.getBmpFromCfg(cfg, "thumbDisabledBmp", "thumbUpBmp")
+ self._thumbNode = SliderThumb(upBmp=thumbUpBmp, downBmp=thumbDownBmp,
+ disabledBmp=thumbDisabledBmp)
+ self.appendChild(self._thumbNode)
+
+ def _getScrollRangeInPixels(self):
+ if self._orientation == Orientation.HORIZONTAL:
+ return self.size.x - self._thumbNode.size.x
+ else:
+ return self.size.y - self._thumbNode.size.y
+
+ def _getSliderRange(self):
+ return self._range[1] - self._range[0]
+
+ def _constrainSliderPos(self):
+ rangeMin = min(self._range[0], self._range[1])
+ rangeMax = max(self._range[0], self._range[1])
+ self._thumbPos = max(rangeMin, self._thumbPos)
+ self._thumbPos = min(rangeMax, self._thumbPos)
+
+
+class ScrollBar(SliderBase):
+
+ def __init__(self, orientation=Orientation.HORIZONTAL, skinObj=skin.Skin.default,
+ thumbExtent=0.1, **kwargs):
+ self.__thumbExtent = thumbExtent
+ if orientation == Orientation.HORIZONTAL:
+ cfg = skinObj.defaultScrollBarCfg["horizontal"]
+ else:
+ cfg = skinObj.defaultScrollBarCfg["vertical"]
+ super(ScrollBar, self).__init__(orientation=orientation, cfg=cfg, **kwargs)
+
+ def _initThumb(self, cfg):
+ thumbUpBmp = cfg["thumbUpBmp"]
+ thumbDownBmp = skin.getBmpFromCfg(cfg, "thumbDownBmp", "thumbUpBmp")
+ thumbDisabledBmp = skin.getBmpFromCfg(cfg, "thumbDisabledBmp", "thumbUpBmp")
+ endsExtent=cfg["thumbEndsExtent"]
+
+ self._thumbNode = ScrollBarThumb(orientation=self._orientation,
+ upBmp=thumbUpBmp, downBmp=thumbDownBmp,
+ disabledBmp=thumbDisabledBmp, endsExtent=endsExtent)
+ self.appendChild(self._thumbNode)
+
+ def getThumbExtent(self):
+ return self.__thumbExtent
+
+ def setThumbExtent(self, thumbExtent):
+ self.__thumbExtent = float(thumbExtent)
+ self._positionNodes()
+
+ thumbExtent = property(getThumbExtent, setThumbExtent)
+
+ def _getScrollRangeInPixels(self):
+ if self._orientation == Orientation.HORIZONTAL:
+ return self.size.x - self._thumbNode.width
+ else:
+ return self.size.y - self._thumbNode.height
+
+ def _positionNodes(self, newSliderPos=None):
+ effectiveRange = math.fabs(self._range[1] - self._range[0])
+ if self._orientation == Orientation.HORIZONTAL:
+ thumbExtent = (self.__thumbExtent/effectiveRange)*self.size.x
+ self._thumbNode.width = thumbExtent
+ else:
+ thumbExtent = (self.__thumbExtent/effectiveRange)*self.size.y
+ self._thumbNode.height = thumbExtent
+ super(ScrollBar, self)._positionNodes(newSliderPos)
+ if self._range[1] < self._range[0]:
+ # Reversed (upside-down) scrollbar
+ if self._orientation == Orientation.HORIZONTAL:
+ self._thumbNode.x -= thumbExtent
+ else:
+ self._thumbNode.y -= thumbExtent
+
+ def _getSliderRange(self):
+ if self._range[1] > self._range[0]:
+ return self._range[1] - self._range[0] - self.__thumbExtent
+ else:
+ return self._range[1] - self._range[0] + self.__thumbExtent
+
+ def _constrainSliderPos(self):
+ rangeMin = min(self._range[0], self._range[1])
+ rangeMax = max(self._range[0], self._range[1])
+ self._thumbPos = max(rangeMin, self._thumbPos)
+ self._thumbPos = min(rangeMax-self.__thumbExtent, self._thumbPos)
+
diff --git a/src/samples/Makefile.am b/src/samples/Makefile.am
new file mode 100644
index 0000000..8af2a57
--- /dev/null
+++ b/src/samples/Makefile.am
@@ -0,0 +1,5 @@
+EXTRA_DIST = $(wildcard *.avg) $(wildcard *.png) $(wildcard *.avi)
+pkgsampledir = $(pkgpyexecdir)/samples
+pkgsample_PYTHON = $(wildcard *.py)
+pkgsample_DATA = $(wildcard *.avg) $(wildcard *.png) $(wildcard *.avi)
+SUBDIRS = firebirds
diff --git a/src/samples/abort_gestures.py b/src/samples/abort_gestures.py
new file mode 100755
index 0000000..f948805
--- /dev/null
+++ b/src/samples/abort_gestures.py
@@ -0,0 +1,114 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+from libavg import avg, gesture, app
+
+import gestures
+
+RESOLUTION = avg.Point2D(800, 600)
+
+nodeList = []
+nodesEnabled = True
+
+def abortAll():
+ for node in nodeList:
+ node.recognizer.abort()
+
+def switchNodesEnabled():
+ global nodesEnabled
+ nodesEnabled = not nodesEnabled
+ for node in nodeList:
+ node.recognizer.enable(nodesEnabled)
+
+
+class TapButton(gestures.TextRect):
+ def __init__(self, text, **kwargs):
+ super(TapButton, self).__init__(text, **kwargs)
+
+ self.recognizer = gesture.TapRecognizer(node=self,
+ possibleHandler=self._onPossible, detectedHandler=self._onDetected,
+ failHandler=self._onFail)
+
+ def _onPossible(self):
+ self.rect.fillcolor = "FFFFFF"
+
+ def _onDetected(self):
+ self.rect.fillcolor = "000000"
+ self.rect.color = "00FF00"
+
+ def _onFail(self):
+ self.rect.fillcolor = "000000"
+ self.rect.color = "FF0000"
+
+
+class AbortButton(TapButton):
+ def __init__(self, text, **kwargs):
+ super(AbortButton, self).__init__(text, **kwargs)
+
+ def _onPossible(self):
+ super(AbortButton, self)._onPossible()
+ self.words.color = "000000"
+
+ def _onDetected(self):
+ super(AbortButton, self)._onDetected()
+ abortAll()
+ self.words.color = "FFFFFF"
+
+ def _onFail(self):
+ super(AbortButton, self)._onFail()
+ self.words.color = "FFFFFF"
+
+
+class EnableButton(TapButton):
+ def __init__(self, text, **kwargs):
+ super(EnableButton, self).__init__(text, **kwargs)
+
+ self.words.color = "FF0000"
+
+ def changeText(self):
+ if(nodesEnabled):
+ self.words.text = "Disable all"
+ self.words.color = "FF0000"
+ else:
+ self.words.text = "Enable all"
+ self.words.color = "00FF00"
+
+ def _onDetected(self):
+ super(EnableButton, self)._onDetected()
+ switchNodesEnabled()
+ self.changeText()
+
+
+class GestureDemoDiv(app.MainDiv):
+
+ def onInit(self):
+
+ avg.WordsNode(text='''a - abort recognition <br/>
+ d - enable/disable recognition <br/><br/>
+ or use the buttons on the right side''',
+ pos=(20, 510), parent=self)
+
+ nodeList.append(gestures.HoldNode(text="HoldRecognizer", pos=(20,20), parent=self))
+
+ nodeList.append(gestures.DragNode(text="DragRecognizer<br/>friction",pos=(200,20),
+ friction=0.05, parent=self))
+
+ nodeList.append(gestures.TransformNode(text="TransformRecognizer",
+ ignoreRotation=False, ignoreScale=False, pos=(380,20), parent=self))
+
+ self.abortButton = AbortButton(text="Abort all", pos = (630, 490), parent=self)
+
+ self.enableButton = EnableButton(text="Disable all", pos = (630, 540), parent=self)
+
+ app.keyboardmanager.bindKeyDown(keystring="a", handler=abortAll,
+ help="abort recognition")
+ app.keyboardmanager.bindKeyDown(keystring="d", handler=self.onEnableKey,
+ help="Enable/disable recognition")
+
+ def onEnableKey(self):
+ switchNodesEnabled()
+ self.enableButton.changeText()
+
+
+if __name__ == '__main__':
+ app.App().run(GestureDemoDiv(), app_resolution="800,600")
diff --git a/src/samples/anim1.py b/src/samples/anim1.py
new file mode 100755
index 0000000..0e78c02
--- /dev/null
+++ b/src/samples/anim1.py
@@ -0,0 +1,17 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+from libavg import *
+
+def startAnim():
+ animObj.start()
+
+canvas = player.createMainCanvas(size=(640,480))
+rootNode = canvas.getRootNode()
+node = avg.WordsNode(pos=(10,10), text="Hello World", parent=rootNode)
+
+animObj = LinearAnim(node, "x", 2000, 0, 200)
+player.setTimeout(0, startAnim)
+
+player.play()
+
diff --git a/src/samples/anim2.py b/src/samples/anim2.py
new file mode 100755
index 0000000..f48106f
--- /dev/null
+++ b/src/samples/anim2.py
@@ -0,0 +1,19 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+from libavg import *
+
+def startAnim():
+ animObj.start()
+
+canvas = player.createMainCanvas(size=(640,480))
+rootNode = canvas.getRootNode()
+node = avg.WordsNode(pos=(10,10), text="Hello World", parent=rootNode)
+
+animObj = ParallelAnim(
+ [LinearAnim(node, "x", 2000, 0, 200),
+ LinearAnim(node, "y", 2000, 0, 10)])
+player.setTimeout(0, startAnim)
+
+player.play()
+
diff --git a/src/samples/app_complete.py b/src/samples/app_complete.py
new file mode 100755
index 0000000..ac4af8d
--- /dev/null
+++ b/src/samples/app_complete.py
@@ -0,0 +1,58 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+import libavg
+from libavg import app, player
+
+
+class MyMainDiv(app.MainDiv):
+ # An OptionParser instance is passed to this function, allowing the MainDiv to
+ # add command line arguments
+ def onArgvParserCreated(self, parser):
+ parser.add_option('--speed', '-s', default='0.3', dest='speed',
+ help='Pixels per second')
+ parser.add_option('--color', '-c', default='ff0000', dest='color',
+ help='Fill color of the running block')
+
+ # This method is called when the command line options are being parsed.
+ # options, args are the result of OptionParser.parse_args().
+ def onArgvParsed(self, options, args, parser):
+ self.argvoptions = options
+
+ # This is called as soon as the player is started by the App object.
+ # Initialize everything here.
+ def onInit(self):
+ libavg.WordsNode(text='block_speed=%s app_resolution=%s' %
+ (self.argvoptions.speed,
+ self.settings.getPoint2D('app_resolution')),
+ pos=(10, self.height - 25), parent=self)
+
+ # Create a graphic element that will be animated
+ self.__runningBlock = libavg.RectNode(pos=(0, 100), size=(20, 20),
+ fillopacity=1, fillcolor=self.argvoptions.color,
+ parent=self)
+ self.__shouldMove = True
+
+ app.keyboardmanager.bindKeyDown('m', self.__toggleMotion, 'Toggle motion')
+
+ def onExit(self):
+ print 'Exiting..'
+
+ def onFrame(self):
+ if self.__shouldMove:
+ speed = float(self.argvoptions.speed)
+ self.__runningBlock.pos += (speed * player.getFrameDuration(), 0)
+ if self.__runningBlock.pos.x > self.size.x:
+ self.__runningBlock.pos = (0, 100)
+
+ def __toggleMotion(self):
+ self.__shouldMove = not self.__shouldMove
+ # Flash messages are debug notifications that are shown temporarily on top of all
+ # the visible elements.
+ app.flashmessage.FlashMessage('Should move: %s' % self.__shouldMove)
+
+
+if __name__ == '__main__':
+ # App options (such as app_resolution) can be changed as parameters of App().run()
+ app.App().run(MyMainDiv(), app_resolution='1024x500')
+
diff --git a/src/samples/app_minimal.py b/src/samples/app_minimal.py
new file mode 100755
index 0000000..230b98f
--- /dev/null
+++ b/src/samples/app_minimal.py
@@ -0,0 +1,17 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+from libavg import app
+
+class MyMainDiv(app.MainDiv):
+ def onInit(self):
+ pass
+
+ def onExit(self):
+ pass
+
+ def onFrame(self):
+ pass
+
+app.App().run(MyMainDiv())
+
diff --git a/src/samples/asyncload.py b/src/samples/asyncload.py
new file mode 100755
index 0000000..48f15db
--- /dev/null
+++ b/src/samples/asyncload.py
@@ -0,0 +1,89 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+'''
+Shows how to use BitmapManager to asynchronously load a Bitmap from a file.
+Run this snippet providing a list of filenames of (high resolution) pictures:
+
+$ ./asyncload.py /path/to/mypics/*.jpg anotherpic.png nonexistent.png
+
+Press space to sequentially load the pictures. A rotating rectangle appears
+during the time the picture file is being loaded to show how the main thread
+is not affected by the load operation.
+
+Press 'f' to display the frame time graph, which should show no significant
+glitches while loading
+'''
+
+import sys
+from libavg import avg, player, app
+
+APP_RESOLUTION = (640, 480)
+
+
+class AsyncLoadDiv(app.MainDiv):
+
+ def onInit(self):
+ '''
+ Create placeholders for the example. A single ImageNode is used to show
+ the pictures.
+ '''
+ self.__imageNode = avg.ImageNode(pos=(10, 20), parent=self)
+ self.__spinner = avg.RectNode(color='222222', fillopacity=1, size=(40, 40),
+ active=False, pos=(10, self.size.y - 50), parent=self)
+ self.__infoNode = avg.WordsNode(text='Press space to load the first image',
+ fontsize=11, pos=(10, 5), parent=self)
+
+ self.__pics = sys.argv[1:]
+ self.__currentPic = -1
+ player.subscribe(player.ON_FRAME, self.__onFrame)
+ app.keyboardmanager.bindKeyDown(keystring="space", handler=self.__requestNextBitmap,
+ help="Request next bitmap")
+
+ def __requestNextBitmap(self):
+ '''
+ Ask the BitmapManager to load a new file. loadBitmap() call returns immediately.
+ '''
+ self.__currentPic = (self.__currentPic + 1) % len(self.__pics)
+ avg.BitmapManager.get().loadBitmap(self.__pics[self.__currentPic],
+ self.__onBitmapLoaded)
+
+ self.__spinner.active = True
+ self.__spinner.angle = 0
+
+ def __onBitmapLoaded(self, bmp):
+ '''
+ This callback is invoked by BitmapManager, 'bmp' can be either a Bitmap instance
+ or a RuntimeError instance (hence checking for Exception is consistent).
+ '''
+ self.__spinner.active = False
+ if isinstance(bmp, Exception):
+ self.__infoNode.text = ('Error loading '
+ 'image %s : %s' % (self.__pics[self.__currentPic], str(bmp)))
+ self.__imageNode.href = ''
+ else:
+ self.__infoNode.text = ('Loaded %s, '
+ 'press space for the next one' % self.__pics[self.__currentPic])
+ self.__setBitmapAndResize(bmp)
+
+ def __setBitmapAndResize(self, bmp):
+ originalSize = bmp.getSize()
+
+ if originalSize.x > originalSize.y:
+ ratio = (APP_RESOLUTION[0] - 20) / originalSize.x
+ else:
+ ratio = (APP_RESOLUTION[1] - 40) / originalSize.y
+
+ self.__imageNode.setBitmap(bmp)
+ self.__imageNode.size = originalSize * ratio
+
+ def __onFrame(self):
+ if self.__spinner.active:
+ self.__spinner.angle += 0.05
+
+if len(sys.argv) == 1:
+ print 'Usage: %s <filename> [<filename> [<filename> [..]]]' % sys.argv[0]
+ sys.exit(1)
+
+app.App().run(AsyncLoadDiv(), app_resolution="640,480")
+
diff --git a/src/samples/attributes.py b/src/samples/attributes.py
new file mode 100755
index 0000000..b4aa6d4
--- /dev/null
+++ b/src/samples/attributes.py
@@ -0,0 +1,11 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+from libavg import avg, player
+
+canvas = player.createMainCanvas(size=(640,480))
+rootNode = canvas.getRootNode()
+node = avg.WordsNode(pos=(10,10), text="Hello World", parent=rootNode)
+print node.x
+node.x = 200
+player.play()
diff --git a/src/samples/canvas.py b/src/samples/canvas.py
new file mode 100755
index 0000000..ad5bb2b
--- /dev/null
+++ b/src/samples/canvas.py
@@ -0,0 +1,14 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+from libavg import avg, player
+
+offscreenCanvas = player.createCanvas(id="londoncalling", size=(320,240))
+avg.WordsNode(pos=(10,10), text="London Calling",
+ parent=offscreenCanvas.getRootNode())
+
+mainCanvas = player.createMainCanvas(size=(640,480))
+rootNode = mainCanvas.getRootNode()
+avg.ImageNode(href="canvas:londoncalling", parent=rootNode)
+
+player.play()
diff --git a/src/samples/drag.py b/src/samples/drag.py
new file mode 100755
index 0000000..e5d50e7
--- /dev/null
+++ b/src/samples/drag.py
@@ -0,0 +1,36 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+from libavg import avg, player
+
+offset = None
+
+def onMouseDown(event):
+ global offset
+ node = event.node
+ offset = node.getRelPos((event.x, event.y))
+ node.setEventCapture()
+
+def onMouseMove(event):
+ global offset
+ node = event.node
+ if offset != None:
+ node.x = event.x-offset[0]
+ node.y = event.y-offset[1]
+
+def onMouseUp(event):
+ global offset
+ node = event.node
+ if offset != None:
+ node.releaseEventCapture()
+ offset = None;
+
+canvas = player.createMainCanvas(size=(640,480))
+rootNode = canvas.getRootNode()
+node = avg.WordsNode(pos=(10,10), text="Hello World", parent=rootNode)
+node.subscribe(node.CURSOR_DOWN, onMouseDown)
+node.subscribe(node.CURSOR_MOTION, onMouseMove)
+node.subscribe(node.CURSOR_UP, onMouseUp)
+
+player.play()
+
diff --git a/src/samples/event1.py b/src/samples/event1.py
new file mode 100755
index 0000000..d0de427
--- /dev/null
+++ b/src/samples/event1.py
@@ -0,0 +1,20 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+from libavg import avg, player
+
+def onMouseOver(event):
+ global node
+ node.color = "FF8000"
+
+def onMouseOut(event):
+ global node
+ node.color = "FFFFFF"
+
+canvas = player.createMainCanvas(size=(640,480))
+rootNode = canvas.getRootNode()
+node = avg.WordsNode(pos=(10,10), text="Hello World", parent=rootNode)
+node.subscribe(node.CURSOR_OVER, onMouseOver)
+node.subscribe(node.CURSOR_OUT, onMouseOut)
+player.play()
+
diff --git a/src/samples/event2.py b/src/samples/event2.py
new file mode 100755
index 0000000..6e7de63
--- /dev/null
+++ b/src/samples/event2.py
@@ -0,0 +1,21 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+from libavg import avg, player
+
+def onDiv(event):
+ words.color = "FF8000"
+
+def onWords(event):
+ words.color = "00FF00"
+
+canvas = player.createMainCanvas(size=(640,480))
+rootNode = canvas.getRootNode()
+words = avg.WordsNode(pos=(10,10), text="Should I stay or should I go?",
+ parent=rootNode)
+div = avg.DivNode(pos=(100,0), size=(80,200), parent=rootNode)
+words.subscribe(words.CURSOR_MOTION, onWords)
+div.subscribe(div.CURSOR_MOTION, onDiv)
+
+player.play()
+
diff --git a/src/samples/firebirds/LICENSE b/src/samples/firebirds/LICENSE
new file mode 100644
index 0000000..8da327f
--- /dev/null
+++ b/src/samples/firebirds/LICENSE
@@ -0,0 +1,6 @@
+Firebirds is a rewrite of the firebirds game published for an XNA tutorial by
+the magazine c't (9/2011, p 184) and developed by Alfred Bigler.
+
+The images, videos and sounds in the media/ directory are Copyright (C) Alfred
+Bigler and distributed under the CC BY-SA 3.0 License by his permission. See
+http://creativecommons.org/licenses/by-sa/3.0/ for the complete license text.
diff --git a/src/samples/firebirds/Makefile.am b/src/samples/firebirds/Makefile.am
new file mode 100644
index 0000000..c574414
--- /dev/null
+++ b/src/samples/firebirds/Makefile.am
@@ -0,0 +1,3 @@
+pkgtutorialdir = $(pkgpyexecdir)/samples/firebirds
+pkgtutorial_PYTHON = $(wildcard *.py)
+SUBDIRS = plugin media
diff --git a/src/samples/firebirds/firebirds.py b/src/samples/firebirds/firebirds.py
new file mode 100755
index 0000000..3656255
--- /dev/null
+++ b/src/samples/firebirds/firebirds.py
@@ -0,0 +1,469 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+# libavg - Media Playback Engine.
+# Copyright (C) 2012-2013 Ulrich von Zadow
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Current versions can be found at www.libavg.de
+#
+# Original author of this file: Thomas Schott <scotty@c-base.org>
+
+# See the LICENSE file for license information regarding the media
+# used by this sample.
+
+from random import randint
+
+from libavg import avg, player
+from libavg import app
+from libavg.utils import getMediaDir
+
+player.loadPlugin('collisiondetector')
+
+def playVideo(video):
+ if not player.isUsingGLES():
+ video.play()
+
+
+### game elements ###
+
+class Bullet(avg.VideoNode):
+ __SPEED = 360 # px/s
+
+ def __init__(self, parent=None, **kwargs):
+ super(Bullet, self).__init__(href='bullet.mov', loop=True, active=False, **kwargs)
+ self.registerInstance(self, parent)
+ self.pause()
+
+ def reset(self, pos):
+ self.pos = pos
+ self.active = True
+ playVideo(self)
+
+ def update(self, dt):
+ y = self.y - Bullet.__SPEED * dt
+ if y > -self.height:
+ self.y = y
+ else:
+ self.destroy()
+
+ def destroy(self):
+ self.active = False
+ self.pause()
+
+
+class _Aircraft(avg.DivNode):
+ _SPEED = 300 # px/s
+ __SHADOW_SCALE = 0.5
+ __SHADOW_OFFSET = avg.Point2D(170, 170)
+
+ def __init__(self, mediabase, shadowdiv, parent=None, **kwargs):
+ super(_Aircraft, self).__init__(**kwargs)
+ self.registerInstance(self, parent)
+ self.__alive = False
+ self.__aircraftVid = avg.VideoNode(href=mediabase+'.mov', loop=True, parent=self)
+ self.__aircraftVid.pause()
+ self.__destroyVid = avg.VideoNode(href='explosion.mov', active=False,
+ threaded=False, parent=self)
+ self.__destroyVid.pause()
+ self.__destroyVid.subscribe(avg.VideoNode.END_OF_FILE, self._hide)
+ self.__shadowImg = avg.ImageNode(href=mediabase+'.gif', opacity=0.5,
+ pos=self.pos + _Aircraft.__SHADOW_OFFSET, parent=shadowdiv)
+ self.__shadowImg.size *= _Aircraft.__SHADOW_SCALE
+ if not player.isUsingGLES():
+ self.__shadowImg.setEffect(avg.BlurFXNode(6.0))
+ self.size = self.__aircraftVid.size
+ #self._debug('created')
+
+ @property
+ def alive(self):
+ return self.__alive
+
+ def reset(self):
+ #self._debug('reset')
+ self.active = True
+ self.__alive = True
+ self.__aircraftVid.active = True
+ playVideo(self.__aircraftVid)
+ self.__destroyVid.active = False
+ self.__destroyVid.pause()
+ self.__shadowImg.active = True
+
+ def destroy(self):
+ #self._debug('destroy')
+ self.__alive = False
+ self.__aircraftVid.active = False
+ self.__aircraftVid.pause()
+ self.__destroyVid.active = True
+ playVideo(self.__destroyVid)
+ self.__destroyVid.seekToFrame(0)
+ self.__shadowImg.active = False
+ if player.isUsingGLES():
+ self._hide()
+
+ def _move(self, pos):
+ self.pos = pos
+ self.__shadowImg.pos = self.pos + _Aircraft.__SHADOW_OFFSET
+
+ def _hide(self):
+ #self._debug('hide')
+ self.active = False
+ self.__alive = False
+ self.__aircraftVid.pause()
+ self.__destroyVid.pause()
+ self.__shadowImg.active = False
+
+ @classmethod
+ def _debug(cls, msg):
+ print '%6d [%s] %s' %(player.getFrameTime(), cls.__name__, msg)
+
+
+class PlayerAircraft(_Aircraft):
+ ACTION_KEYS = ('left', 'right', 'up', 'down', 'space')
+ __BULLET_OFFSET_L = avg.Point2D( 52, 16)
+ __BULLET_OFFSET_R = avg.Point2D(140, 16)
+
+ def __init__(self, shadowdiv, gunCtrl, parent=None, **kwargs):
+ super(PlayerAircraft, self).__init__('spitfire', shadowdiv, parent, **kwargs)
+ self.__gunCtrl = gunCtrl
+ self.__bullets = [Bullet(parent=self.parent) for i in xrange(10)]
+ self.__engineSnd = avg.SoundNode(href='flySound.mp3', loop=True, parent=self)
+ self.__bulletSnd = avg.SoundNode(href='bulletSound.mp3', volume=0.75, parent=self)
+ self.__maxX, self.__maxY = self.parent.size - self.size
+
+ def reset(self):
+ super(PlayerAircraft, self).reset()
+ self.__gunCtrl.reset()
+ self._move((self.__maxX / 2, self.__maxY))
+ self.__engineSnd.play()
+
+ def destroy(self):
+ super(PlayerAircraft, self).destroy()
+ self.__engineSnd.stop()
+
+ def update(self, dt, keyStates):
+ d = _Aircraft._SPEED * dt
+ dx = 0
+ if keyStates['left']:
+ dx = -d
+ if keyStates['right']:
+ dx += d
+ dy = 0
+ if keyStates['up']:
+ dy = -d
+ if keyStates['down']:
+ dy += d
+ pos = (max(min(self.x + dx, self.__maxX), 0),
+ max(min(self.y + dy, self.__maxY), 0))
+ if pos != self.pos:
+ self._move(pos)
+
+ if keyStates['space'] and self.__gunCtrl.shoot():
+ # fire bullets
+ bulletLeft = None
+ bulletRight = None
+ for b in self.__bullets:
+ if b.active:
+ b.update(dt)
+ elif not bulletLeft:
+ bulletLeft = b
+ elif not bulletRight:
+ bulletRight = b
+ if not bulletLeft:
+ bulletLeft = Bullet(parent=self.parent)
+ self.__bullets.append(bulletLeft)
+ if not bulletRight:
+ bulletRight = Bullet(parent=self.parent)
+ self.__bullets.append(bulletRight)
+ bulletLeft.reset(self.pos + PlayerAircraft.__BULLET_OFFSET_L)
+ bulletRight.reset(self.pos + PlayerAircraft.__BULLET_OFFSET_R)
+ self.__bulletSnd.play()
+ self.__bulletSnd.seekToTime(0)
+ else:
+ self.__gunCtrl.update(dt)
+ self.updateBullets(dt)
+
+ def updateBullets(self, dt):
+ bulletsAlive = False
+ for b in self.__bullets:
+ if b.active:
+ bulletsAlive = True
+ b.update(dt)
+ return bulletsAlive
+
+ def getActiveBullets(self):
+ return [b for b in self.__bullets if b.active]
+
+
+class EnemyAircraft(_Aircraft):
+ ESCAPED = avg.Publisher.genMessageID()
+
+ def __init__(self, shadowdiv, parent=None, **kwargs):
+ super(EnemyAircraft, self).__init__('enemy', shadowdiv, parent, **kwargs)
+ self.publish(EnemyAircraft.ESCAPED)
+ self.__destroySnd = avg.SoundNode(href='enemyDeath.mp3', volume=2.0, parent=self)
+ self._hide()
+
+ def reset(self):
+ super(EnemyAircraft, self).reset()
+ self._move((randint(0, self.parent.width - self.width), -self.height))
+
+ def destroy(self):
+ super(EnemyAircraft, self).destroy()
+ self.__destroySnd.play()
+ self.__destroySnd.seekToTime(0)
+
+ def update(self, dt):
+ y = self.y + _Aircraft._SPEED * dt
+ if y < self.parent.height:
+ self._move((self.x, y))
+ else:
+ self._hide()
+ self.notifySubscribers(EnemyAircraft.ESCAPED, [])
+
+
+### gui elements ###
+
+class ScrollingBackground(object):
+ __SCROLL_SPEED = 120.0 # px/s
+
+ def __init__(self, parent):
+ self.__imgA = avg.ImageNode(href='ground.jpg', parent=parent)
+ self.__imgB = avg.ImageNode(href='ground.jpg', pos=(0, -self.__imgA.height),
+ parent=parent)
+
+ def update(self, dt):
+ dy = ScrollingBackground.__SCROLL_SPEED * dt
+ self.__imgA.y += dy
+ self.__imgB.y += dy
+ if self.__imgA.y >= self.__imgA.height:
+ self.__imgA.y = self.__imgB.y - self.__imgA.height
+ elif self.__imgB.y >= self.__imgA.height:
+ self.__imgB.y = self.__imgA.y - self.__imgA.height
+
+
+class LiveCounter(avg.DivNode):
+ __NUM_LIVES = 3
+
+ def __init__(self, parent=None, **kwargs):
+ super(LiveCounter, self).__init__(**kwargs)
+ self.registerInstance(self, parent)
+ self.__numLives = 0
+ self.__images = []
+ x = 0
+ for i in xrange(LiveCounter.__NUM_LIVES):
+ avg.ImageNode(href='gui_lives_bg.png', pos=(x, 0), parent=self)
+ img = avg.ImageNode(href='gui_lives_fg.png', pos=(x, 0), parent=self)
+ self.__images.append(img)
+ x += img.width
+
+ def reset(self):
+ self.__numLives = 3
+ for img in self.__images:
+ avg.fadeIn(img, 250)
+
+ def dec(self):
+ assert(self.__numLives)
+ self.__numLives -= 1
+ avg.fadeOut(self.__images[self.__numLives], 250)
+ return not self.__numLives
+
+
+class ScoreCounter(avg.DivNode):
+ def __init__(self, parent=None, **kwargs):
+ super(ScoreCounter, self).__init__(size=(3 * 34, 34), crop=True, **kwargs)
+ self.registerInstance(self, parent)
+ self.__score = 0
+ self.__images = [avg.ImageNode(href='gui_numbers.png', pos=((2 - i) * 34, 0),
+ parent=self) for i in xrange(3)]
+
+ def reset(self):
+ self.__score = 0
+ for img in self.__images:
+ if img.y != 0:
+ avg.LinearAnim(img, 'y', 250, img.y, 0).start()
+
+ def inc(self):
+ self.__score += 1
+ self.__updateImages()
+
+ def dec(self):
+ if self.__score > 0:
+ self.__score -= 1
+ self.__updateImages()
+
+ def __updateImages(self):
+ s = self.__score
+ for img in self.__images:
+ y = s % 10 * -34
+ if img.y != y:
+ avg.LinearAnim(img, 'y', 250, img.y, y).start()
+ s /= 10
+
+
+class GunControl(avg.DivNode):
+ __SHOOT_INTERVAL = 1.0 / 7 # ms
+ __TEMPERATURE_INC = 30 # px/shot
+ __TEMPERATURE_DEC = 60 # px/s
+
+ def __init__(self, parent=None, **kwargs):
+ super(GunControl, self).__init__(**kwargs)
+ self.registerInstance(self, parent)
+ bg = avg.ImageNode(href='gui_heatbar_bg.png', parent=self)
+ self.__heatbar = avg.DivNode(size=(1, bg.height), crop=True, parent=self)
+ avg.ImageNode(href='gui_heatbar_fg.png', parent=self.__heatbar)
+ self.__maxTemp = bg.width - GunControl.__TEMPERATURE_INC
+ self.__shootTimeout = 0.0
+
+ def reset(self):
+ self.__heatbar.width = 1
+
+ def update(self, dt):
+ if self.__shootTimeout > 0.0:
+ self.__shootTimeout = max(0.0, self.__shootTimeout - dt)
+ dw = GunControl.__TEMPERATURE_DEC * dt
+ if self.__heatbar.width > dw:
+ self.__heatbar.width -= dw
+
+ def shoot(self):
+ if self.__shootTimeout == 0.0 and self.__heatbar.width < self.__maxTemp:
+ self.__shootTimeout = GunControl.__SHOOT_INTERVAL
+ self.__heatbar.width += GunControl.__TEMPERATURE_INC
+ return True
+ return False
+
+
+### application ###
+
+class FireBirds(app.MainDiv):
+ ENEMY_SPAWN_TIMEOUT = 1000 # ms
+
+ def onInit(self):
+ self.mediadir = getMediaDir(__file__)
+
+ self.__gameMusic = avg.SoundNode(href='Fire_Birds.mp3', loop=True,
+ volume=0.75, parent=self)
+ self.__scrollingBg = ScrollingBackground(self)
+ self.__shadowDiv = avg.DivNode(parent=self)
+ self.__gameDiv = avg.DivNode(size=self.size, parent=self)
+ self.__guiDiv = avg.DivNode(parent=self)
+
+ bg = avg.ImageNode(href='gui_frame.png', parent=self.__guiDiv)
+ self.__guiDiv.pos = (0, self.height - bg.height)
+ self.__liveCounter = LiveCounter(pos=(8, 12), parent=self.__guiDiv)
+ gunCtrl = GunControl(pos=(300, 54), parent=self.__guiDiv)
+ self.__scoreCounter = ScoreCounter(pos=(1142, 54), parent=self.__guiDiv)
+
+ self.__enemies = []
+ for i in xrange(2):
+ self.__createEnemy()
+ self.__player = PlayerAircraft(self.__shadowDiv, gunCtrl, parent=self.__gameDiv)
+
+ enemyMask = avg.Bitmap(self.mediadir + '/enemy.gif')
+ self.__playerCollisionDetector = collisiondetector.CollisionDetector(
+ enemyMask, avg.Bitmap(self.mediadir + '/spitfire.gif'))
+ self.__bulletCollisionDetector = collisiondetector.CollisionDetector(
+ enemyMask, avg.Bitmap(self.mediadir + '/bullet.gif'))
+
+ self.__keyStates = dict.fromkeys(PlayerAircraft.ACTION_KEYS, False)
+ self.__frameHandlerId = None
+ self.__spawnTimeoutId = None
+ self.__gameMusic.play()
+ self.__start()
+ player.subscribe(player.KEY_DOWN, self.__onKeyDown)
+ player.subscribe(player.KEY_UP, self.__onKeyUp)
+
+ def __onKeyDown(self, event):
+ if self.__player.alive:
+ if event.keystring in PlayerAircraft.ACTION_KEYS:
+ self.__keyStates[event.keystring] = True
+ elif not self.__frameHandlerId: # game stopped
+ if event.keystring == 'space':
+ self.__start()
+ # else: wait for bullets and enemies to leave the screen
+
+ def __onKeyUp(self, event):
+ if event.keystring in PlayerAircraft.ACTION_KEYS:
+ self.__keyStates[event.keystring] = False
+
+ def __start(self):
+ assert(not self.__frameHandlerId and not self.__spawnTimeoutId)
+ self.__liveCounter.reset()
+ self.__scoreCounter.reset()
+ self.__player.reset()
+ self.__frameHandlerId = player.subscribe(player.ON_FRAME, self.__onFrame)
+ self.__spawnTimeoutId = player.setInterval(self.ENEMY_SPAWN_TIMEOUT,
+ self.__spawnEnemy)
+
+ def __stop(self):
+ assert(self.__frameHandlerId and self.__spawnTimeoutId)
+ player.clearInterval(self.__spawnTimeoutId)
+ self.__spawnTimeoutId = None
+
+ def __createEnemy(self):
+ enemy = EnemyAircraft(self.__shadowDiv, parent=self.__gameDiv)
+ enemy.subscribe(EnemyAircraft.ESCAPED, self.__scoreCounter.dec)
+ self.__enemies.append(enemy)
+ return enemy
+
+ def __spawnEnemy(self):
+ assert(self.__frameHandlerId)
+ enemy = None
+ for e in self.__enemies:
+ if not e.active:
+ enemy = e
+ break
+ if not enemy:
+ enemy = self.__createEnemy()
+ enemy.reset()
+
+ def __onFrame(self):
+ dt = player.getFrameDuration() * 0.001
+ self.__scrollingBg.update(dt)
+
+ bullets = self.__player.getActiveBullets()
+ enemiesActive = False
+ for e in self.__enemies:
+ if e.active:
+ enemiesActive = True
+ if e.alive:
+ for b in bullets:
+ if self.__bulletCollisionDetector.detect(e.pos, b.pos):
+ self.__scoreCounter.inc()
+ e.destroy()
+ b.destroy()
+ break
+ if e.alive: # no bullet hit
+ if self.__player.alive and \
+ self.__playerCollisionDetector.detect(e.pos, self.__player.pos):
+ e.destroy()
+ if self.__liveCounter.dec():
+ self.__stop()
+ self.__player.destroy()
+ if e.alive: # no player collision
+ e.update(dt)
+
+ if self.__player.alive:
+ self.__player.update(dt, self.__keyStates)
+ elif not self.__player.updateBullets(dt) and not enemiesActive:
+ # player dead, all bullets and enemies left the screen, all destroy videos played
+ player.unsubscribe(player.ON_FRAME, self.__frameHandlerId)
+ self.__frameHandlerId = None
+
+
+if __name__ == '__main__':
+ app.App().run(FireBirds(), app_resolution='1280x720')
+
diff --git a/src/samples/firebirds/media/Fire_Birds.mp3 b/src/samples/firebirds/media/Fire_Birds.mp3
new file mode 100644
index 0000000..264723e
--- /dev/null
+++ b/src/samples/firebirds/media/Fire_Birds.mp3
Binary files differ
diff --git a/src/samples/firebirds/media/Makefile.am b/src/samples/firebirds/media/Makefile.am
new file mode 100644
index 0000000..bfd5cdf
--- /dev/null
+++ b/src/samples/firebirds/media/Makefile.am
@@ -0,0 +1,5 @@
+EXTRA_DIST = $(wildcard *.gif) $(wildcard *.png) $(wildcard *.jpg) \
+ $(wildcard *.mov) $(wildcard *.mp3)
+datadir = $(pkgpyexecdir)/samples/firebirds/media
+data_DATA = $(wildcard *.gif) $(wildcard *.png) $(wildcard *.jpg) \
+ $(wildcard *.mov) $(wildcard *.mp3)
diff --git a/src/samples/firebirds/media/bullet.gif b/src/samples/firebirds/media/bullet.gif
new file mode 100644
index 0000000..ad1cca3
--- /dev/null
+++ b/src/samples/firebirds/media/bullet.gif
Binary files differ
diff --git a/src/samples/firebirds/media/bullet.mov b/src/samples/firebirds/media/bullet.mov
new file mode 100644
index 0000000..eac58d5
--- /dev/null
+++ b/src/samples/firebirds/media/bullet.mov
Binary files differ
diff --git a/src/samples/firebirds/media/bulletSound.mp3 b/src/samples/firebirds/media/bulletSound.mp3
new file mode 100644
index 0000000..2172667
--- /dev/null
+++ b/src/samples/firebirds/media/bulletSound.mp3
Binary files differ
diff --git a/src/samples/firebirds/media/enemy.gif b/src/samples/firebirds/media/enemy.gif
new file mode 100644
index 0000000..59cc1e2
--- /dev/null
+++ b/src/samples/firebirds/media/enemy.gif
Binary files differ
diff --git a/src/samples/firebirds/media/enemy.mov b/src/samples/firebirds/media/enemy.mov
new file mode 100644
index 0000000..8487095
--- /dev/null
+++ b/src/samples/firebirds/media/enemy.mov
Binary files differ
diff --git a/src/samples/firebirds/media/enemyDeath.mp3 b/src/samples/firebirds/media/enemyDeath.mp3
new file mode 100644
index 0000000..c5b0b67
--- /dev/null
+++ b/src/samples/firebirds/media/enemyDeath.mp3
Binary files differ
diff --git a/src/samples/firebirds/media/explosion.mov b/src/samples/firebirds/media/explosion.mov
new file mode 100644
index 0000000..a03f4e9
--- /dev/null
+++ b/src/samples/firebirds/media/explosion.mov
Binary files differ
diff --git a/src/samples/firebirds/media/flySound.mp3 b/src/samples/firebirds/media/flySound.mp3
new file mode 100644
index 0000000..bc83bf4
--- /dev/null
+++ b/src/samples/firebirds/media/flySound.mp3
Binary files differ
diff --git a/src/samples/firebirds/media/ground.jpg b/src/samples/firebirds/media/ground.jpg
new file mode 100644
index 0000000..2425fcc
--- /dev/null
+++ b/src/samples/firebirds/media/ground.jpg
Binary files differ
diff --git a/src/samples/firebirds/media/gui_frame.png b/src/samples/firebirds/media/gui_frame.png
new file mode 100644
index 0000000..414cb00
--- /dev/null
+++ b/src/samples/firebirds/media/gui_frame.png
Binary files differ
diff --git a/src/samples/firebirds/media/gui_heatbar_bg.png b/src/samples/firebirds/media/gui_heatbar_bg.png
new file mode 100644
index 0000000..3e330e2
--- /dev/null
+++ b/src/samples/firebirds/media/gui_heatbar_bg.png
Binary files differ
diff --git a/src/samples/firebirds/media/gui_heatbar_fg.png b/src/samples/firebirds/media/gui_heatbar_fg.png
new file mode 100644
index 0000000..fa79bb7
--- /dev/null
+++ b/src/samples/firebirds/media/gui_heatbar_fg.png
Binary files differ
diff --git a/src/samples/firebirds/media/gui_lives_bg.png b/src/samples/firebirds/media/gui_lives_bg.png
new file mode 100644
index 0000000..e206a9d
--- /dev/null
+++ b/src/samples/firebirds/media/gui_lives_bg.png
Binary files differ
diff --git a/src/samples/firebirds/media/gui_lives_fg.png b/src/samples/firebirds/media/gui_lives_fg.png
new file mode 100644
index 0000000..cdceba8
--- /dev/null
+++ b/src/samples/firebirds/media/gui_lives_fg.png
Binary files differ
diff --git a/src/samples/firebirds/media/gui_numbers.png b/src/samples/firebirds/media/gui_numbers.png
new file mode 100644
index 0000000..c567766
--- /dev/null
+++ b/src/samples/firebirds/media/gui_numbers.png
Binary files differ
diff --git a/src/samples/firebirds/media/spitfire.gif b/src/samples/firebirds/media/spitfire.gif
new file mode 100644
index 0000000..47976cc
--- /dev/null
+++ b/src/samples/firebirds/media/spitfire.gif
Binary files differ
diff --git a/src/samples/firebirds/media/spitfire.mov b/src/samples/firebirds/media/spitfire.mov
new file mode 100644
index 0000000..384cac2
--- /dev/null
+++ b/src/samples/firebirds/media/spitfire.mov
Binary files differ
diff --git a/src/samples/firebirds/plugin/CollisionDetector.cpp b/src/samples/firebirds/plugin/CollisionDetector.cpp
new file mode 100644
index 0000000..1eca5c9
--- /dev/null
+++ b/src/samples/firebirds/plugin/CollisionDetector.cpp
@@ -0,0 +1,122 @@
+#include "CollisionDetector.h"
+
+#include "../../../base/ScopeTimer.h"
+#include "../../../wrapper/WrapHelper.h"
+
+namespace avg {
+
+CollisionDetector::CollisionDetector(const Bitmap& bmpA, const Bitmap& bmpB)
+{
+ m_pBmpA = new Bitmap(bmpA.getSize(), B8G8R8A8);
+ m_pBmpA->copyPixels(bmpA);
+ m_pBmpB = new Bitmap(bmpB.getSize(), B8G8R8A8);
+ m_pBmpB->copyPixels(bmpB);
+}
+
+CollisionDetector::~CollisionDetector()
+{
+ delete m_pBmpA;
+ delete m_pBmpB;
+}
+
+static ProfilingZoneID CollisionDetectorProfilingZone("Detect collisions");
+
+bool CollisionDetector::detect(glm::vec2 posA, glm::vec2 posB)
+{
+ ScopeTimer Timer(CollisionDetectorProfilingZone);
+
+ int widthA = m_pBmpA->getSize().x;
+ int heightA = m_pBmpA->getSize().y;
+ int rightA = posA.x + widthA;
+ int bottomA = posA.y + heightA;
+ int widthB = m_pBmpB->getSize().x;
+ int heightB = m_pBmpB->getSize().y;
+ int rightB = posB.x + widthB;
+ int bottomB = posB.y + heightB;
+
+ // bounding box test
+ if (rightA <= posB.x || posA.x >= rightB || bottomA <= posB.y || posA.y >= bottomB) {
+ return false;
+ }
+
+ // pixel level test
+
+ // calculate x overlap
+ int dX = posB.x - posA.x;
+ if (dX < 0) {
+ posA.x = 0;
+ posB.x = -dX;
+ }
+ else {
+ posA.x = dX;
+ posB.x = 0;
+ }
+ int width;
+ dX = rightB - rightA;
+ if (dX < 0)
+ width = std::min(widthA + dX, widthB);
+ else
+ width = std::min(widthB - dX, widthA);
+ // calculate y overlap
+ int dY = posB.y - posA.y;
+ if (dY < 0) {
+ posA.y = 0;
+ posB.y = -dY;
+ }
+ else {
+ posA.y = dY;
+ posB.y = 0;
+ }
+ int height;
+ dY = bottomB - bottomA;
+ if (dY < 0)
+ height = std::min(heightA + dY, heightB);
+ else
+ height = std::min(heightB - dY, heightA);
+
+ // test alpha channels
+ const unsigned char* pPixStartA = m_pBmpA->getPixels() +
+ (int) posA.y * m_pBmpA->getStride() +
+ (int) posA.x * 4 + 3; // alpha channel of 1st A pixel
+ const unsigned char* pPixStartB = m_pBmpB->getPixels() +
+ (int) posB.y * m_pBmpB->getStride() +
+ (int) posB.x * 4 + 3; // alpha channel of 1st B pixel
+ const unsigned char* pPixA = pPixStartA;
+ const unsigned char* pPixB = pPixStartB;
+ for (int y = 0; y < height; y++) {
+ for (int x = 0; x < width; x++) {
+ if (*pPixA && *pPixB) {
+ return true; // both pixels have alpha > 0 --> collision
+ }
+ pPixA += 4;
+ pPixB += 4;
+ }
+ pPixA = pPixStartA + y * m_pBmpA->getStride();
+ pPixB = pPixStartB + y * m_pBmpB->getStride();
+ }
+
+ return false;
+}
+
+} // namespace avg
+
+
+using namespace boost::python;
+
+BOOST_PYTHON_MODULE(collisiondetector)
+{
+ class_<avg::CollisionDetector, boost::noncopyable>("CollisionDetector", no_init)
+ .def(init<avg::Bitmap&, avg::Bitmap&>())
+ .def("detect", &avg::CollisionDetector::detect)
+ ;
+}
+
+
+AVG_PLUGIN_API void registerPlugin()
+{
+ initcollisiondetector(); // created by BOOST_PYTHON_MODULE
+ object mainModule(handle<>(borrowed(PyImport_AddModule("__main__"))));
+ object collisiondetectorModule(handle<>(PyImport_ImportModule("collisiondetector")));
+ mainModule.attr("collisiondetector") = collisiondetectorModule;
+}
+
diff --git a/src/samples/firebirds/plugin/CollisionDetector.h b/src/samples/firebirds/plugin/CollisionDetector.h
new file mode 100644
index 0000000..7d477e2
--- /dev/null
+++ b/src/samples/firebirds/plugin/CollisionDetector.h
@@ -0,0 +1,28 @@
+#ifndef _COLLISION_DETECTOR_H_
+#define _COLLISION_DETECTOR_H_
+
+#define AVG_PLUGIN
+
+#include "../../../graphics/Bitmap.h"
+
+
+namespace avg {
+
+class CollisionDetector
+{
+public:
+ CollisionDetector(const Bitmap& bmpA, const Bitmap& bmpB);
+ ~CollisionDetector();
+
+ bool detect(glm::vec2 posA, glm::vec2 posB);
+
+private:
+ Bitmap* m_pBmpA;
+ Bitmap* m_pBmpB;
+};
+
+}
+
+
+#endif
+
diff --git a/src/samples/firebirds/plugin/Makefile.am b/src/samples/firebirds/plugin/Makefile.am
new file mode 100644
index 0000000..69a63db
--- /dev/null
+++ b/src/samples/firebirds/plugin/Makefile.am
@@ -0,0 +1,16 @@
+AM_CPPFLAGS = -I. @XML2_CFLAGS@ @PYTHON_CPPFLAGS@
+
+if APPLE
+ XGL_LIBS =
+ EXTRA_LDFLAGS = -read_only_relocs suppress
+else
+ XGL_LIBS = -lXxf86vm
+ EXTRA_LDFLAGS = -XCClinker ../../../wrapper/.libs/avg.so
+endif
+
+ALL_GL_LIBS = @GL_LIBS@ @SDL_LIBS@ $(XGL_LIBS)
+
+pkgplugindir = $(pkgpyexecdir)/samples/firebirds/plugin
+pkgplugin_LTLIBRARIES = collisiondetector.la
+collisiondetector_la_SOURCES = CollisionDetector.h CollisionDetector.cpp
+collisiondetector_la_LDFLAGS = $(EXTRA_LDFLAGS) -module
diff --git a/src/samples/flashmessages.py b/src/samples/flashmessages.py
new file mode 100644
index 0000000..25c11d1
--- /dev/null
+++ b/src/samples/flashmessages.py
@@ -0,0 +1,58 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+# libavg - Media Playback Engine.
+# Copyright (C) 2003-2014 Ulrich von Zadow
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Current versions can be found at www.libavg.de
+#
+# Original author of this file is OXullo Interecans <x at brainrapers dot org>
+# Sponsored by Archimedes Exhibitions GmbH ( http://www.archimedes-exhibitions.de )
+
+
+import libavg
+from libavg import app
+
+
+class MyScene(app.MainDiv):
+ def onInit(self):
+ # This message is displayed immediately
+ app.flashmessage.FlashMessage('helloworld! this message will disappear in a bit')
+
+ # Displayed when the 'v' key is pressed, again a simple flash message
+ app.keyboardmanager.bindKeyDown('v',
+ lambda: app.flashmessage.FlashMessage('v key pressed'), 'Test me')
+
+ # This message shows the message in a different color and sends the text to
+ # the logger as well
+ app.keyboardmanager.bindKeyDown('b',
+ lambda: app.flashmessage.FlashMessage('this is an error', isError=True),
+ 'Test me too')
+
+ # This message disappears when it's acknowledged with a mouse click
+ app.keyboardmanager.bindKeyDown('n',
+ lambda: app.flashmessage.FlashMessage('persistent, click here to dismiss',
+ acknowledge=True),
+ 'Test me too again')
+
+ libavg.avg.WordsNode(parent=self, pos=(10, 50), fontsize=20,
+ text='Press the keys: v, b, n')
+
+
+if __name__ == '__main__':
+ app.App().run(MyScene())
+
diff --git a/src/samples/fontstyle.py b/src/samples/fontstyle.py
new file mode 100755
index 0000000..c6707a4
--- /dev/null
+++ b/src/samples/fontstyle.py
@@ -0,0 +1,23 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+from libavg import avg, player
+
+BASE_STYLE = avg.FontStyle(font='Arial', variant='Regular', fontsize=14, linespacing=2)
+HEADER_STYLE = avg.FontStyle(basestyle=BASE_STYLE, variant='Bold', color='FF0000')
+
+SAMPLE_TEXT="""
+Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin vitae gravida urna. Nam ut nisi ac nulla venenatis tincidunt a in urna. Cras vel enim purus, sit amet adipiscing dolor. Aliquam tincidunt interdum velit sed hendrerit. Proin ut enim dolor, sit amet egestas mi. Aenean felis quam, sollicitudin sed tempus in, pharetra eget turpis.
+"""
+
+canvas = player.createMainCanvas(size=(640, 480))
+rootNode = canvas.getRootNode()
+
+avg.WordsNode(pos=(50, 50), text='Lorem Ipsum', fontstyle=HEADER_STYLE, parent=rootNode)
+avg.WordsNode(pos=(50, 70), text='Lorem Ipsum', fontstyle=HEADER_STYLE, variant='Italic',
+ parent=rootNode)
+avg.WordsNode(pos=(50, 90), text=SAMPLE_TEXT, width=400, fontstyle=BASE_STYLE,
+ parent=rootNode)
+
+player.play()
+
diff --git a/src/samples/gestures.py b/src/samples/gestures.py
new file mode 100755
index 0000000..9b4a0be
--- /dev/null
+++ b/src/samples/gestures.py
@@ -0,0 +1,287 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+from libavg import avg, gesture, app
+
+RESOLUTION = avg.Point2D(800, 600)
+
+def moveNodeToTop(node):
+ parent = node.getParent()
+ parent.reorderChild(node, parent.getNumChildren()-1)
+
+def moveNodeOnScreen(node):
+ center = node.pos + node.size/2
+ if center.x < 0:
+ node.pos = (-node.size.x/2, node.pos.y)
+ if center.x > RESOLUTION.x:
+ node.pos = (RESOLUTION.x-node.size.x/2, node.pos.y)
+ if center.y < 0:
+ node.pos = (node.pos.x, -node.size.y/2)
+ if center.y > RESOLUTION.y:
+ node.pos = (node.pos.x, RESOLUTION.y-node.size.y/2)
+
+
+class TextRect(avg.DivNode):
+ def __init__(self, text, parent=None, **kwargs):
+ super(TextRect, self).__init__(size=(150,40), **kwargs)
+ if parent:
+ parent.appendChild(self)
+
+ self.rect = avg.RectNode(size=self.size, fillopacity=1, fillcolor="000000",
+ color="FFFFFF", parent=self)
+ self.words = avg.WordsNode(color="FFFFFF", text=text, alignment="center",
+ parent=self)
+ self.words.pos = (self.size-(0,self.words.size.y)) / 2
+
+ def getSize(self):
+ return self.__divSize
+
+ def setSize(self, size):
+ self.rect.size = size
+ self.words.pos = (size-(0,self.words.size.y)) / 2
+ self.__divSize = size
+ __divSize = avg.DivNode.size
+ size = property(getSize, setSize)
+
+
+class TransformNode(TextRect):
+ def __init__(self, text, ignoreScale, ignoreRotation, friction=-1, **kwargs):
+ super(TransformNode, self).__init__(text, **kwargs)
+ self.__ignoreScale = ignoreScale
+ self.__ignoreRotation = ignoreRotation
+
+ self.recognizer = gesture.TransformRecognizer(
+ eventNode=self,
+ detectedHandler=self.__onDetected,
+ moveHandler=self.__onMove,
+ upHandler=self.__onUp,
+ friction=friction
+ )
+
+ def __onDetected(self):
+ moveNodeToTop(self)
+
+ def __onMove(self, transform):
+ if self.__ignoreScale:
+ transform.scale = 1
+ if self.__ignoreRotation:
+ transform.rot = 0
+ transform.moveNode(self)
+ moveNodeOnScreen(self)
+
+ def __onUp(self, transform):
+ pass
+
+
+class TransformChildNode(avg.DivNode):
+ def __init__(self, text, parent=None, **kwargs):
+ super(TransformChildNode, self).__init__( **kwargs)
+ if parent:
+ parent.appendChild(self)
+
+ self.textRect = TextRect(text, parent=self)
+ self.size = self.textRect.size
+
+ self.inputNode = avg.RectNode(size=(self.size.x, self.size.y/2),
+ fillopacity=0.5, fillcolor="808080", strokewidth=0, parent=self)
+ self.recognizer = gesture.TransformRecognizer(
+ eventNode=self.inputNode,
+ coordSysNode=self,
+ detectedHandler=self.__onDetected,
+ moveHandler=self.__onMove,
+ friction=0.05
+ )
+
+ def __onDetected(self):
+ moveNodeToTop(self)
+
+ def __onMove(self, transform):
+ transform.moveNode(self)
+ moveNodeOnScreen(self)
+ self.textRect.size = self.size
+ self.inputNode.size = (self.size.x, self.size.y/2)
+
+
+class DragNode(TextRect):
+ def __init__(self, text, friction=-1, **kwargs):
+ super(DragNode, self).__init__(text, **kwargs)
+
+ self.recognizer = gesture.DragRecognizer(
+ eventNode=self,
+ detectedHandler=self.__onDetected,
+ moveHandler=self.__onMove,
+ upHandler=self.__onMove,
+ endHandler=self.__onEnd,
+ friction=friction
+ )
+
+ def __onDetected(self):
+ self.__dragStartPos = self.pos
+ moveNodeToTop(self)
+
+ def __onMove(self, offset):
+ self.pos = self.__dragStartPos + offset
+ moveNodeOnScreen(self)
+
+ def __onEnd(self):
+ pass
+
+
+class ConstrainedDragNode(TextRect):
+ def __init__(self, text, friction=-1, **kwargs):
+ super(ConstrainedDragNode, self).__init__(text, **kwargs)
+
+ self.recognizer = gesture.DragRecognizer(
+ eventNode=self,
+ detectedHandler=self.__onDetected,
+ moveHandler=self.__onHorizMove,
+ upHandler=self.__onHorizMove,
+ direction=gesture.DragRecognizer.HORIZONTAL,
+ friction=0.05
+ )
+
+ self.recognizer2 = gesture.DragRecognizer(
+ eventNode=self,
+ detectedHandler=self.__onDetected,
+ moveHandler=self.__onVertMove,
+ upHandler=self.__onVertMove,
+ direction=gesture.DragRecognizer.VERTICAL,
+ friction=0.05
+ )
+
+ def __onDetected(self):
+ self.__dragStartPos = self.pos
+ moveNodeToTop(self)
+
+ def __onHorizMove(self, offset):
+ self.pos = self.__dragStartPos + (offset.x, 0)
+ moveNodeOnScreen(self)
+
+ def __onVertMove(self, offset):
+ self.pos = self.__dragStartPos + (0, offset.y)
+ moveNodeOnScreen(self)
+
+
+class TapNode(TextRect):
+ def __init__(self, text, isDoubleTap, **kwargs):
+ super(TapNode, self).__init__(text, **kwargs)
+
+ if isDoubleTap:
+ self.recognizer = gesture.DoubletapRecognizer(node=self,
+ possibleHandler=self.__onPossible, detectedHandler=self.__onDetected,
+ failHandler=self.__onFail)
+ else:
+ self.recognizer = gesture.TapRecognizer(node=self,
+ possibleHandler=self.__onPossible, detectedHandler=self.__onDetected,
+ failHandler=self.__onFail)
+
+ def __onPossible(self):
+ self.rect.fillcolor = "FFFFFF"
+ self.words.color = "000000"
+
+ def __onDetected(self):
+ self.rect.fillcolor = "000000"
+ self.words.color = "FFFFFF"
+ self.rect.color = "00FF00"
+
+ def __onFail(self):
+ self.rect.fillcolor = "000000"
+ self.words.color = "FFFFFF"
+ self.rect.color = "FF0000"
+
+
+class SwipeNode(TextRect):
+ def __init__(self, text, numContacts, **kwargs):
+ super(SwipeNode, self).__init__(text, **kwargs)
+
+ self.recognizer = gesture.SwipeRecognizer(node=self, minDist=25,
+ numContacts=numContacts, direction=gesture.SwipeRecognizer.RIGHT,
+ possibleHandler=self.__onPossible, detectedHandler=self.__onDetected,
+ failHandler=self.__onFail)
+
+ def __onPossible(self):
+ self.rect.fillcolor = "FFFFFF"
+ self.words.color = "000000"
+
+ def __onDetected(self):
+ self.rect.fillcolor = "000000"
+ self.words.color = "FFFFFF"
+ self.rect.color = "00FF00"
+
+ def __onFail(self):
+ self.rect.fillcolor = "000000"
+ self.words.color = "FFFFFF"
+ self.rect.color = "FF0000"
+
+
+class HoldNode(TextRect):
+ def __init__(self, text, **kwargs):
+ super(HoldNode, self).__init__(text, **kwargs)
+
+ self.recognizer = gesture.HoldRecognizer(node=self,
+ possibleHandler=self.__onPossible, detectedHandler=self.__onDetected,
+ failHandler=self.__onFail, stopHandler=self.__onStop)
+
+ def __onPossible(self):
+ self.rect.fillcolor = "FFFFFF"
+ self.rect.color = "FFFFFF"
+ self.words.color = "000000"
+
+ def __onDetected(self):
+ self.rect.fillcolor = "000000"
+ self.words.color = "FFFFFF"
+ self.rect.color = "00FF00"
+
+ def __onFail(self):
+ self.rect.fillcolor = "000000"
+ self.words.color = "FFFFFF"
+ self.rect.color = "FF0000"
+
+ def __onStop(self):
+ self.rect.fillcolor = "000000"
+ self.rect.color = "FFFFFF"
+ self.words.color = "FFFFFF"
+
+
+class GestureDemoDiv(app.MainDiv):
+
+ def onInit(self):
+ TransformNode(text="TransformRecognizer",
+ ignoreRotation=False, ignoreScale=False, pos=(20,20), parent=self)
+
+ TransformNode(text="TransformRecognizer<br/>ignoreRotation",
+ ignoreRotation=True, ignoreScale=False, pos=(20,70), parent=self)
+
+ TransformNode(text="TransformRecognizer<br/>ignoreScale",
+ ignoreRotation=False, ignoreScale=True, pos=(20,120), parent=self)
+
+ TransformNode(text="TransformRecognizer<br/>friction",
+ ignoreRotation=False, ignoreScale=False,
+ pos=(20,170), friction=0.02, parent=self)
+
+ TransformChildNode(text="TransformRecognizer<br/>child dragger",
+ pos=(20,220), parent=self)
+
+ DragNode(text="DragRecognizer", pos=(200,20), parent=self)
+
+ DragNode(text="DragRecognizer<br/>friction", pos=(200,70), friction=0.01,
+ parent=self)
+
+ ConstrainedDragNode(text="DragRecognizer<br/>constrained", pos=(200,120),
+ friction=0.01, parent=self)
+
+ TapNode(text="TapRecognizer", pos=(380,20), isDoubleTap=False, parent=self)
+
+ TapNode(text="DoubletapRecognizer", pos=(380,70), isDoubleTap=True, parent=self)
+
+ HoldNode(text="HoldRecognizer", pos=(380,120), parent=self)
+
+ SwipeNode(text="SwipeRecognizer<br/>(Right)", pos=(380,170),
+ numContacts=1, parent=self)
+
+ SwipeNode(text="SwipeRecognizer<br/>(Right, 2 fingers)", pos=(380,220),
+ numContacts=2, parent=self)
+
+
+if __name__ == '__main__':
+ app.App().run(GestureDemoDiv(), app_resolution="800,600")
diff --git a/src/samples/globalcoords.py b/src/samples/globalcoords.py
new file mode 100755
index 0000000..be95bb2
--- /dev/null
+++ b/src/samples/globalcoords.py
@@ -0,0 +1,9 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+from libavg import avg, player
+
+canvas = player.createMainCanvas(size=(160,120))
+rootNode = canvas.getRootNode()
+avg.ImageNode(pos=(40,30), size=(80,60), href="rgb24-64x64.png", parent=rootNode)
+player.play()
diff --git a/src/samples/invertfx.py b/src/samples/invertfx.py
new file mode 100755
index 0000000..039a99a
--- /dev/null
+++ b/src/samples/invertfx.py
@@ -0,0 +1,35 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+# libavg - Media Playback Engine.
+# Copyright (C) 2003-2014 Ulrich von Zadow
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Current versions can be found at www.libavg.de
+
+from libavg import avg, app
+
+class Invert(app.MainDiv):
+ def onInit(self):
+ orig = avg.ImageNode(parent=self, href='../test/media/hsl.png')
+ invert = avg.ImageNode(parent=self, href='../test/media/hsl.png',
+ pos=(orig.size.x+10, 0))
+ invert.setEffect(avg.InvertFXNode())
+
+
+if __name__ == '__main__':
+ app.App().run(Invert(), app_resolution='200x200')
+
diff --git a/src/samples/localcoords.py b/src/samples/localcoords.py
new file mode 100755
index 0000000..f40b63f
--- /dev/null
+++ b/src/samples/localcoords.py
@@ -0,0 +1,10 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+from libavg import avg, player
+
+canvas = player.createMainCanvas(size=(160,120))
+rootNode = canvas.getRootNode()
+divNode = avg.DivNode(pos=(40,30), parent=rootNode)
+avg.ImageNode(pos=(40,30), size=(80,60), href="rgb24-64x64.png", parent=divNode)
+player.play()
diff --git a/src/samples/localcoordsrot.py b/src/samples/localcoordsrot.py
new file mode 100755
index 0000000..0cefadd
--- /dev/null
+++ b/src/samples/localcoordsrot.py
@@ -0,0 +1,11 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+from libavg import avg, player
+
+canvas = player.createMainCanvas(size=(160,120))
+rootNode = canvas.getRootNode()
+divNode = avg.DivNode(pos=(120,30), pivot=(0,0), angle=1.570, parent=rootNode)
+avg.ImageNode(pos=(40,30), size=(40,30), href="rgb24-64x64.png", parent=divNode)
+player.play()
+
diff --git a/src/samples/logsample.py b/src/samples/logsample.py
new file mode 100755
index 0000000..0436c4f
--- /dev/null
+++ b/src/samples/logsample.py
@@ -0,0 +1,55 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+import logging
+
+from libavg import avg, app
+
+# Setup Python Logger
+hdlr = logging.StreamHandler()
+# category is added as an extra formatting key by libavg
+formatter = logging.Formatter('[%(asctime)s][%(levelname)s][%(category)s] : %(message)s')
+hdlr.setFormatter(formatter)
+pyLogger = logging.getLogger(__name__)
+pyLogger.addHandler(hdlr)
+pyLogger.propagate = False
+pyLogger.level = logging.DEBUG
+
+
+class LoggingTest(app.MainDiv):
+ def onInit(self):
+ # Add the python logger to libavgs logger as a message sink
+ avg.logger.removeStdLogSink()
+ avg.logger.addSink(pyLogger)
+
+ avg.logger.debug("Hidden, unless AVG_LOG_CATEGORIES configured with APP:DEBUG")
+
+ avg.logger.configureCategory(avg.logger.Category.APP, avg.logger.Severity.INFO)
+ avg.logger.log("Custom Info level message", avg.logger.Category.APP,
+ avg.logger.Severity.INFO)
+
+ avg.logger.info("Info level message, with APP Category")
+ avg.logger.warning("Warn level message, with APP Category")
+
+ #Remove the logSink, no message should be logged now, if run with
+ #AVG_LOG_OMIT_STDERR=1
+ #avg.logger.removeSink(logging.getLogger("MY_APP"))
+
+ avg.logger.error("std::err - Error")
+ avg.logger.critical("std::err - Critical")
+ avg.logger.log("std::err - Log")
+
+ #Register custom log category
+ CUSTOM_LOG_CAT = avg.logger.configureCategory("My Custom Category",
+ avg.logger.Severity.INFO)
+
+ #Log with custom log category
+ avg.logger.log("Message with custom category", CUSTOM_LOG_CAT)
+ avg.logger.debug("Hidden message", CUSTOM_LOG_CAT)
+ avg.logger.configureCategory(CUSTOM_LOG_CAT, avg.logger.Severity.DBG)
+ avg.logger.debug("This will show up", CUSTOM_LOG_CAT)
+
+
+if __name__ == '__main__':
+ app.App().run(LoggingTest(), app_resolution='140x140')
+
diff --git a/src/samples/mesh.py b/src/samples/mesh.py
new file mode 100755
index 0000000..8f18de1
--- /dev/null
+++ b/src/samples/mesh.py
@@ -0,0 +1,13 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+from libavg import avg, player
+
+canvas = player.createMainCanvas(size=(160,120))
+avg.MeshNode(texhref="rgb24-64x64.png",
+ vertexcoords=((0,0), (64,0), (0,64), (64, 64), (32, 32)),
+ texcoords=((0,0), (1,0), (0,1), (1,1), (0.5,0.5)),
+ triangles=((0,1,4), (1,3,4), (3,2,4), (2,0,4)),
+ parent=player.getRootNode())
+player.play()
+
diff --git a/src/samples/minimal.py b/src/samples/minimal.py
new file mode 100755
index 0000000..bc57f21
--- /dev/null
+++ b/src/samples/minimal.py
@@ -0,0 +1,9 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+from libavg import avg, player
+
+canvas = player.createMainCanvas(size=(640,480))
+rootNode = canvas.getRootNode()
+avg.WordsNode(pos=(10,10), text="Hello World", parent=rootNode)
+player.play()
diff --git a/src/samples/mpeg1-48x48-sound.avi b/src/samples/mpeg1-48x48-sound.avi
new file mode 100644
index 0000000..be415db
--- /dev/null
+++ b/src/samples/mpeg1-48x48-sound.avi
Binary files differ
diff --git a/src/samples/plugin.py b/src/samples/plugin.py
new file mode 100755
index 0000000..6aa7100
--- /dev/null
+++ b/src/samples/plugin.py
@@ -0,0 +1,15 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+from libavg import player
+
+canvas = player.createMainCanvas(size=(160,120))
+# Change following line if the plugin is somewhere else.
+player.pluginPath = "../test/plugin/.libs"
+player.loadPlugin("colorplugin")
+
+rootNode = canvas.getRootNode()
+node = colorplugin.ColorNode(fillcolor="7f7f00", parent=rootNode)
+node.fillcolor = "7f007f"
+player.play()
+
diff --git a/src/samples/rgb24-64x64.png b/src/samples/rgb24-64x64.png
new file mode 100644
index 0000000..cca71fe
--- /dev/null
+++ b/src/samples/rgb24-64x64.png
Binary files differ
diff --git a/src/samples/rotcustompivot.py b/src/samples/rotcustompivot.py
new file mode 100755
index 0000000..b4765a6
--- /dev/null
+++ b/src/samples/rotcustompivot.py
@@ -0,0 +1,11 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+from libavg import avg, player
+
+canvas = player.createMainCanvas(size=(160,120))
+rootNode = canvas.getRootNode()
+avg.ImageNode(pos=(80,30), size=(40,30), href="rgb24-64x64.png", angle=1.570, pivot=(0,0),
+ parent=rootNode)
+player.play()
+
diff --git a/src/samples/rotdefaultpivot.py b/src/samples/rotdefaultpivot.py
new file mode 100755
index 0000000..99f1826
--- /dev/null
+++ b/src/samples/rotdefaultpivot.py
@@ -0,0 +1,11 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+from libavg import avg, player
+
+canvas = player.createMainCanvas(size=(160,120))
+rootNode = canvas.getRootNode()
+avg.ImageNode(pos=(40,30), size=(80,60), href="rgb24-64x64.png", angle=1.570,
+ parent=rootNode)
+player.play()
+
diff --git a/src/samples/showvideo.py b/src/samples/showvideo.py
new file mode 100755
index 0000000..571034b
--- /dev/null
+++ b/src/samples/showvideo.py
@@ -0,0 +1,14 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+from libavg import avg, app
+import sys
+
+class VideoPlayer(app.MainDiv):
+ def init(self):
+ self.videoNode = avg.VideoNode(
+ href=sys.argv[1],
+ parent=self)
+ self.videoNode.play()
+
+app.App().run(VideoPlayer(), app_resolution='1920x1080', app_window_size='720x450')
diff --git a/src/samples/slideshow.py b/src/samples/slideshow.py
new file mode 100755
index 0000000..98704d0
--- /dev/null
+++ b/src/samples/slideshow.py
@@ -0,0 +1,159 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+# libavg - Media Playback Engine.
+# Copyright (C) 2003-2014 Ulrich von Zadow
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Current versions can be found at www.libavg.de
+#
+# Original author of this file: Thomas Schott <scotty@c-base.org>
+#
+
+"""
+Image slideshow example which shows all images found in the current working
+directory (default) or the one provided via the "app_image_dir" setting.
+
+Images are cross-faded and some random motion/scaling is applied while they're shown.
+This example also shows how to use libavg's BitmapManager to asynchronously load images
+in background.
+"""
+
+# TODO:
+# add app settings for:
+# * show/transition intervals
+# * max. move distance
+# * sorted/shuffled show order (shuffled yet)
+
+import sys
+import os
+from random import shuffle, randint
+from libavg import avg, player, app
+
+
+IMAGE_EXTENSIONS = ['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.tga', '.tif', '.tiff']
+SHOW_INTERVAL = 6000 # [ms]
+TRANS_INTERVAL = 2000 # [ms]
+CHANGE_INTERVAL = SHOW_INTERVAL + TRANS_INTERVAL
+ANIM_INTERVAL = CHANGE_INTERVAL + TRANS_INTERVAL
+ANIM_MAX_MOVE = 200 # [px]
+
+BitmapMgr = avg.BitmapManager.get()
+
+
+def scaleMax(srcSize, maxSize):
+ """
+ Returns scrSize aspect correct scaled to fit right into maxSize.
+ """
+ aspect = srcSize.x / srcSize.y
+ if aspect < maxSize.x / maxSize.y:
+ return avg.Point2D(maxSize.y * aspect, maxSize.y)
+ return avg.Point2D(maxSize.x, maxSize.x / aspect)
+
+def scaleMin(srcSize, minSize):
+ """
+ Returns scrSize aspect correct scaled to completely fill minSize.
+ """
+ aspect = srcSize.x / srcSize.y
+ if aspect < minSize.x / minSize.y:
+ return avg.Point2D(minSize.x, minSize.x / aspect)
+ return avg.Point2D(minSize.y * aspect, minSize.y)
+
+
+class Slide(avg.ImageNode):
+ HIDE_DONE = avg.Publisher.genMessageID()
+
+ def __init__(self, parent=None, **kwargs):
+ super(Slide, self).__init__(opacity=0.0, **kwargs)
+ self.registerInstance(self, parent)
+ self.publish(Slide.HIDE_DONE)
+
+ def show(self):
+ s = self.getMediaSize()
+ assert s.x and s.y
+ # initial size and position (scaled to screen size and centered)
+ self.size = scaleMax(s, self.parent.size)
+ self.pos = (self.parent.size - self.size) * 0.5
+ # random final size and position (center moved by (dx, dy) and scaled up accordingly)
+ dx = float(randint(-ANIM_MAX_MOVE, ANIM_MAX_MOVE))
+ dy = float(randint(-ANIM_MAX_MOVE, ANIM_MAX_MOVE))
+ size = scaleMin(s, self.size + avg.Point2D(abs(dx), abs(dy)) * 2.0)
+ pos = self.pos + avg.Point2D(dx, dy) + (self.size - size) * 0.5
+ # start in-transition
+ avg.fadeIn(self, TRANS_INTERVAL)
+ # start move/scale animation
+ avg.ParallelAnim([
+ avg.LinearAnim(self, 'size', ANIM_INTERVAL, self.size, size),
+ avg.LinearAnim(self, 'pos', ANIM_INTERVAL, self.pos, pos)]).start()
+
+ def hide(self):
+ # start out-transition, notify subscribers when finished
+ avg.fadeOut(self, TRANS_INTERVAL,
+ lambda: self.notifySubscribers(Slide.HIDE_DONE, [self]))
+
+
+class Slideshow(app.MainDiv):
+ def onArgvParserCreated(self, parser):
+ parser.set_usage('%prog <images dir>')
+
+ def onArgvParsed(self, options, args, parser):
+ if len(args) != 1:
+ parser.print_help()
+ sys.exit(1)
+ self._imagesDir = args[0]
+
+ def onInit(self):
+ if not os.path.isdir(self._imagesDir):
+ avg.logger.error('Directory [%s] not found' % self._imagesDir)
+ exit(1)
+ avg.logger.info('Scanning directory [%s] ...' % self._imagesDir)
+
+ imgExts = tuple(IMAGE_EXTENSIONS + [ext.upper() for ext in IMAGE_EXTENSIONS])
+ self.__imgFiles = [os.path.join(self._imagesDir, imgFile) for imgFile in
+ filter(lambda f: f.endswith(imgExts), os.listdir(self._imagesDir))]
+ if not self.__imgFiles:
+ avg.logger.error('No image files found, '
+ 'scanned file extensions:\n%s' % (', '.join(imgExts)))
+ exit(1)
+ l = len(self.__imgFiles)
+ avg.logger.info('%d image file%s found' % (l, 's' if l > 1 else ''))
+ shuffle(self.__imgFiles)
+
+ self.__slidesDiv = avg.DivNode(size=self.size, parent=self)
+ # ping-pong two slides for cross-fade transition
+ self.__newSlide = Slide(parent=self.__slidesDiv)
+ self.__oldSlide = Slide(href=self.__imgFiles[0], parent=self.__slidesDiv)
+ # HIDE_DONE notifications will trigger asynchronous pre-loading of the next image
+ self.__newSlide.subscribe(Slide.HIDE_DONE, self.__asyncPreload)
+ self.__oldSlide.subscribe(Slide.HIDE_DONE, self.__asyncPreload)
+ self.__currentIdx = 0
+ self.__changeSlide()
+ player.setInterval(CHANGE_INTERVAL, self.__changeSlide)
+
+ def __asyncPreload(self, slide):
+ self.__currentIdx = (self.__currentIdx + 1) % len(self.__imgFiles)
+ BitmapMgr.loadBitmap(self.__imgFiles[self.__currentIdx], slide.setBitmap)
+
+ def __changeSlide(self):
+ self.__oldSlide, self.__newSlide = self.__newSlide, self.__oldSlide
+ self.__slidesDiv.reorderChild(self.__newSlide, 1) # move to top
+ self.__newSlide.show()
+ self.__oldSlide.hide()
+
+
+if __name__ == '__main__':
+ app.App().run(Slideshow())
+
diff --git a/src/samples/subclass.py b/src/samples/subclass.py
new file mode 100755
index 0000000..b0b6380
--- /dev/null
+++ b/src/samples/subclass.py
@@ -0,0 +1,40 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+from libavg import avg, gesture, app
+import libavg
+
+class TextRect(avg.DivNode):
+ def __init__(self, text, parent=None, **kwargs):
+ super(TextRect, self).__init__(**kwargs)
+ self.registerInstance(self, parent)
+ self.rect = avg.RectNode(size=self.size, fillopacity=1, fillcolor="000000",
+ color="FFFFFF", parent=self)
+ self.words = avg.WordsNode(color="FFFFFF", text=text, alignment="center",
+ parent=self)
+ self.words.pos = (self.size-(0,self.words.size.y)) / 2
+
+ def getSize(self):
+ return self.__divSize
+
+ def setSize(self, size):
+ self.rect.size = size
+ self.words.pos = (size-(0,self.words.size.y)) / 2
+ self.__divSize = size
+ __divSize = avg.DivNode.size
+ size = property(getSize, setSize)
+
+
+class SubclassDemo(app.MainDiv):
+
+ def onInit(self):
+ self.rect = TextRect(text="Hello World", pos=(20,20), size=(200,120),
+ parent=self)
+ self.__recognizer = gesture.TapRecognizer(node=self.rect,
+ detectedHandler=self.onTap)
+
+ def onTap(self):
+ self.rect.size = self.rect.size + (10,10)
+
+if __name__ == '__main__':
+ app.App().run(SubclassDemo(), app_resolution='800x600')
diff --git a/src/samples/timer.py b/src/samples/timer.py
new file mode 100755
index 0000000..9973d4e
--- /dev/null
+++ b/src/samples/timer.py
@@ -0,0 +1,16 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+from libavg import avg, player
+
+def moveText():
+ global node
+ node.x = 200
+
+canvas = player.createMainCanvas(size=(640,480))
+rootNode = canvas.getRootNode()
+node = avg.WordsNode(pos=(10,10), text="Hello World", parent=rootNode)
+player.setTimeout(1000, moveText)
+
+player.play()
+
diff --git a/src/samples/timer2.py b/src/samples/timer2.py
new file mode 100755
index 0000000..006005d
--- /dev/null
+++ b/src/samples/timer2.py
@@ -0,0 +1,17 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+from libavg import avg, player
+
+def moveText():
+ global node
+ if node.x < 200:
+ node.x += 1
+
+canvas = player.createMainCanvas(size=(640,480))
+rootNode = canvas.getRootNode()
+node = avg.WordsNode(pos=(10,10), text="Hello World", parent=rootNode)
+player.subscribe(player.ON_FRAME, moveText)
+
+player.play()
+
diff --git a/src/samples/timer3.py b/src/samples/timer3.py
new file mode 100755
index 0000000..492cdda
--- /dev/null
+++ b/src/samples/timer3.py
@@ -0,0 +1,19 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+from libavg import avg, player
+
+def moveText():
+ global node
+ if node.x < 200:
+ node.x += 20
+ else:
+ player.clearInterval(timer)
+
+canvas = player.createMainCanvas(size=(640,480))
+rootNode = canvas.getRootNode()
+node = avg.WordsNode(pos=(10,10), text="Hello World", parent=rootNode)
+timer = player.setInterval(200, moveText)
+
+player.play()
+
diff --git a/src/samples/twovideos.py b/src/samples/twovideos.py
new file mode 100755
index 0000000..1ad3fca
--- /dev/null
+++ b/src/samples/twovideos.py
@@ -0,0 +1,55 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+import sys
+import libavg
+from libavg import avg, app, player
+
+
+class HDVideo(app.MainDiv):
+ def onArgvParserCreated(self, parser):
+ parser.set_usage('%prog <video1> <video2>')
+ parser.add_option('--duration', '-d', dest='duration',
+ default=2000, type='int', help='Crossfade duration')
+
+ def onArgvParsed(self, options, args, parser):
+ if len(args) != 2:
+ parser.print_help()
+ sys.exit(1)
+
+ self.__videos = args
+ self.__duration = options.duration
+
+ def onInit(self):
+ self.videoNodes = []
+ for fileName in (self.__videos[0], self.__videos[1]):
+ videoNode = avg.VideoNode(
+ size=(1680, 1050),
+ href=fileName,
+ opacity=0,
+ loop=True,
+ parent=self)
+ videoNode.play()
+ self.videoNodes.append(videoNode)
+
+ self.videoNodes[0].opacity = 1
+ self.runningVideo = 0
+ self.isFading = False
+
+ app.keyboardmanager.bindKeyDown('1', self.onButtonPressed,
+ 'Crossfade between videos')
+
+ def onButtonPressed(self):
+ if not(self.isFading):
+ if self.runningVideo == 0:
+ avg.fadeIn(self.videoNodes[1], self.__duration)
+ else:
+ avg.fadeOut(self.videoNodes[1], self.__duration)
+ player.setTimeout(self.__duration, self.fadeEnd)
+ self.runningVideo = (self.runningVideo+1)%2
+ self.isFading = True
+
+ def fadeEnd(self):
+ self.isFading = False
+
+app.App().run(HDVideo(), app_resolution='1680x1050', app_window_size='720x450')
diff --git a/src/samples/video.py b/src/samples/video.py
new file mode 100755
index 0000000..73d8c3e
--- /dev/null
+++ b/src/samples/video.py
@@ -0,0 +1,11 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+from libavg import avg, player
+
+canvas = player.createMainCanvas(size=(160,120))
+rootNode = canvas.getRootNode()
+videoNode = avg.VideoNode(href="mpeg1-48x48-sound.avi", pos=(10,10),
+ parent=rootNode)
+videoNode.play()
+player.play()
diff --git a/src/samples/videochooser.py b/src/samples/videochooser.py
new file mode 100755
index 0000000..c0f9fb4
--- /dev/null
+++ b/src/samples/videochooser.py
@@ -0,0 +1,87 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+import os, sys
+from libavg import avg, app, player, Point2D
+
+
+class VideoChooser(app.MainDiv):
+ def onArgvParserCreated(self, parser):
+ parser.set_usage("%prog <folder>")
+ parser.add_option('--duration', '-d', dest='duration',
+ default=2000, type='int', help='Fade duration')
+ parser.add_option('--width', '-w', dest='thumbWidth',
+ default=320, type='int', help='Thumbnail width')
+
+ def onArgvParsed(self, options, args, parser):
+ if len(args) != 1:
+ parser.print_help()
+ sys.exit(1)
+
+ self.__folder = args[0]
+ self.__duration = options.duration
+ self.__thumbWidth = options.thumbWidth
+
+ def onInit(self):
+ player.showCursor(True)
+
+ self.videoListNode = avg.DivNode(parent=self)
+ self.videoNodes = []
+ fileNames = os.listdir(self.__folder)
+ i = 0
+ for fileName in fileNames:
+ try:
+ videoNode = avg.VideoNode(
+ pos=(i*(self.__thumbWidth+20), 0),
+ href=self.__folder+'/'+fileName,
+ loop=True,
+ mipmap=True,
+ enablesound=False,
+ parent = self.videoListNode)
+ videoNode.play()
+ self.videoNodes.append(videoNode)
+
+ size = videoNode.getMediaSize()
+ height = (self.__thumbWidth*size.y)/size.x
+ videoNode.size = (self.__thumbWidth, height)
+ videoNode.subscribe(videoNode.CURSOR_DOWN,
+ lambda event, videoNode=videoNode:
+ self.chooseVideo(event, videoNode))
+ i += 1
+ except RuntimeError:
+ pass
+
+ self.subscribe(self.CURSOR_MOTION, self.onMouseMove)
+ self.bigVideoNode = None
+
+ def onMouseMove(self, event):
+ windowWidth = player.getRootNode().width
+ ratio = event.x/float(windowWidth)
+ self.videoListNode.x = -(ratio*(self.getTotalWidth()-windowWidth))
+
+ def chooseVideo(self, event, videoNode):
+ if self.bigVideoNode:
+ self.removeBigVideo()
+ destSize = videoNode.size*2
+ destPos = Point2D(720, 550)-destSize/2
+ absPos = videoNode.getAbsPos(Point2D(0,0))
+ frame = videoNode.getCurFrame()
+ self.bigVideoNode = avg.VideoNode(href=videoNode.href, loop=True, sensitive=False,
+ parent=self)
+ self.bigVideoNode.play()
+ self.bigVideoNode.seekToFrame(frame)
+ avg.EaseInOutAnim(self.bigVideoNode, "pos", 1000, absPos, destPos, False,
+ 300, 300).start()
+ avg.EaseInOutAnim(self.bigVideoNode, "size", 1000, videoNode.size, destSize,
+ False, 300, 300).start()
+
+ def removeBigVideo(self):
+ oldVideoNode = self.bigVideoNode
+ avg.fadeOut(oldVideoNode, self.__duration, lambda: oldVideoNode.unlink(True))
+
+ def getTotalWidth(self):
+ return (self.__thumbWidth+20)*len(self.videoNodes)
+
+
+app.App().run(VideoChooser(), app_resolution='1440x900', app_window_size='720x450')
+
diff --git a/src/samples/widget.py b/src/samples/widget.py
new file mode 100755
index 0000000..0396299
--- /dev/null
+++ b/src/samples/widget.py
@@ -0,0 +1,77 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+from libavg import avg, app, widget
+
+class SimpleUI(app.MainDiv):
+ def onInit(self):
+ avg.RectNode(size=(1024,768), fillopacity=1, fillcolor="FFFFFF",
+ parent=self)
+
+ hScrollBar = widget.ScrollBar(pos=(10,10), width=150, parent=self)
+ self.__addValueDisplay(hScrollBar, (175,12))
+
+ vScrollBar = widget.ScrollBar(pos=(15,60), height=150,
+ orientation=widget.Orientation.VERTICAL, parent=self)
+ vScrollBar.thumbExtent = 5
+ vScrollBar.range = (10,0)
+ self.__addValueDisplay(vScrollBar, (10,220))
+
+ hSlider = widget.Slider(pos=(10,35), width=150, parent=self)
+ self.__addValueDisplay(hSlider, (175,33))
+
+ vSlider = widget.Slider(pos=(60.5,60), height=150,
+ orientation=widget.Orientation.VERTICAL, parent=self)
+ vSlider.range = (1,0)
+ self.__addValueDisplay(vSlider, (55,220))
+ self.controls = [hScrollBar, vScrollBar, hSlider, vSlider]
+
+ self.createScrollArea(avg.Point2D(220,10))
+
+ checkBox = widget.CheckBox(pos=(10,270), text="Disable everything",
+ parent=self)
+ checkBox.subscribe(widget.CheckBox.TOGGLED, self.onCheck)
+
+ def setText(self, pos, node):
+ node.text = "%.2f"%pos
+
+ def setImageWidth(self, scrollArea, thumbPos):
+ scrollArea.contentsize = (thumbPos, scrollArea.contentsize.y)
+
+ def setImageHeight(self, scrollArea, thumbPos):
+ scrollArea.contentsize = (scrollArea.contentsize.x, thumbPos)
+
+ def createScrollArea(self, pos):
+ image = avg.ImageNode(href="rgb24-64x64.png", size=(1024, 1024))
+ scrollArea = widget.ScrollArea(contentNode=image, parent=self,
+ pos=pos, size=(220,220))
+
+ imageWidthSlider = widget.Slider(pos=pos+(0,230), width=220,
+ parent=self)
+ imageWidthSlider.range = (100,1024)
+ imageWidthSlider.thumbPos = 1024
+ imageWidthSlider.subscribe(widget.ScrollBar.THUMB_POS_CHANGED,
+ lambda thumbPos, scrollArea=scrollArea:
+ self.setImageWidth(scrollArea, thumbPos))
+
+ imageHeightSlider = widget.Slider(pos=pos+(230,0), height=220,
+ orientation=widget.Orientation.VERTICAL, parent=self)
+ imageHeightSlider.range = (100,1024)
+ imageHeightSlider.thumbPos = 1024
+ imageHeightSlider.subscribe(widget.ScrollBar.THUMB_POS_CHANGED,
+ lambda thumbPos, scrollArea=scrollArea:
+ self.setImageHeight(scrollArea, thumbPos))
+ self.controls.extend([scrollArea, imageWidthSlider, imageHeightSlider])
+
+ def onCheck(self, isChecked):
+ for node in self.controls:
+ node.enabled = not(isChecked)
+
+ def __addValueDisplay(self, scrollBar, pos):
+ textNode = avg.WordsNode(pos=pos, color="000000", parent=self)
+ scrollBar.subscribe(widget.ScrollBar.THUMB_POS_CHANGED,
+ lambda pos, node=textNode: self.setText(pos, node))
+ self.setText(scrollBar.thumbPos, textNode)
+
+
+app.App().run(SimpleUI(), app_resolution='1024x768')
diff --git a/src/samples/wordspos.py b/src/samples/wordspos.py
new file mode 100755
index 0000000..85a8ceb
--- /dev/null
+++ b/src/samples/wordspos.py
@@ -0,0 +1,15 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+from libavg import avg, player
+
+canvas = player.createMainCanvas(size=(160,120))
+rootNode = canvas.getRootNode()
+avg.WordsNode(pos=(10,10), width=70, text="<i>Left-justified paragraph</i>",
+ parent=rootNode)
+avg.WordsNode(pos=(150,10), width=70, alignment="right", text="Right-justified paragraph",
+ parent=rootNode)
+avg.WordsNode(pos=(80,80), width=70, alignment="center", text="Centered paragraph",
+ parent=rootNode)
+player.play()
+
diff --git a/src/test/AVGAppTest.py b/src/test/AVGAppTest.py
new file mode 100644
index 0000000..9178e4c
--- /dev/null
+++ b/src/test/AVGAppTest.py
@@ -0,0 +1,187 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# libavg - Media Playback Engine.
+# Copyright (C) 2003-2014 Ulrich von Zadow
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Current versions can be found at www.libavg.de
+#
+
+import os
+import time
+
+import libavg
+from libavg import avg, Point2D, player
+import testcase
+
+g_helper = player.getTestHelper()
+
+TEST_RESOLUTION = (160, 120)
+
+class TestAppBase(libavg.AVGApp):
+ @classmethod
+ def start(cls, **kwargs):
+ with testcase.SuppressOutput():
+ super(TestAppBase, cls).start(**kwargs)
+
+ def requestStop(self, timeout=0):
+ player.setTimeout(timeout, player.stop)
+
+ def singleKeyPress(self, char):
+ g_helper.fakeKeyEvent(avg.Event.KEY_DOWN, ord(char), ord(char), char, ord(char),
+ avg.KEYMOD_NONE)
+ g_helper.fakeKeyEvent(avg.Event.KEY_UP, ord(char), ord(char), char, ord(char),
+ avg.KEYMOD_NONE)
+
+
+class AVGAppTestCase(testcase.AVGTestCase):
+ def testMinimal(self):
+ class MinimalApp(TestAppBase):
+ testInstance = self
+ def init(self):
+ self.testInstance.assert_(not player.isFullscreen())
+ self.requestStop()
+
+ if 'AVG_DEPLOY' in os.environ:
+ del os.environ['AVG_DEPLOY']
+ MinimalApp.start(resolution=TEST_RESOLUTION)
+
+ def testAvgDeploy(self):
+ class FullscreenApp(TestAppBase):
+ testInstance = self
+ def init(self):
+ self.testInstance.assert_(player.isFullscreen())
+ rootNodeSize = player.getRootNode().size
+ self.testInstance.assertEqual(rootNodeSize, resolution)
+ self.requestStop()
+
+ resolution = player.getScreenResolution()
+ os.environ['AVG_DEPLOY'] = '1'
+ FullscreenApp.start(resolution=resolution)
+ del os.environ['AVG_DEPLOY']
+
+ def testDebugWindowSize(self):
+ class DebugwindowApp(TestAppBase):
+ testInstance = self
+ def init(self):
+ self.testInstance.assert_(not player.isFullscreen())
+ rootNodeSize = player.getRootNode().size
+ self.testInstance.assertEqual(rootNodeSize, TEST_RESOLUTION)
+
+ # windowSize = player.getWindowResolution()
+ # self.testInstance.assertEqual(windowSize, Point2D(TEST_RESOLUTION)/2)
+ self.requestStop()
+
+ DebugwindowApp.start(resolution=TEST_RESOLUTION,
+ debugWindowSize=Point2D(TEST_RESOLUTION) / 2)
+
+ def testScreenshot(self):
+ if not(self._isCurrentDirWriteable()):
+ self.skip("Current dir not writeable")
+ return
+
+ expectedFiles = ['screenshot-000.png', 'screenshot-001.png']
+
+ def cleanup():
+ for screenshotFile in expectedFiles[::-1]:
+ if os.path.exists(screenshotFile):
+ os.unlink(screenshotFile)
+
+ def checkCallback():
+ for screenshotFile in expectedFiles[::-1]:
+ if os.path.exists(screenshotFile):
+ avg.Bitmap(screenshotFile)
+ else:
+ raise RuntimeError('Cannot find the expected '
+ 'screenshot file %s' % screenshotFile)
+
+ player.stop()
+
+ class ScreenshotApp(TestAppBase):
+ def init(self):
+ self.singleKeyPress('s')
+ self.singleKeyPress('s')
+ self.timeStarted = time.time()
+ self.timerId = player.subscribe(player.ON_FRAME, self.onFrame)
+
+ def onFrame(self):
+ if (os.path.exists(expectedFiles[-1]) or
+ time.time() - self.timeStarted > 1):
+ player.clearInterval(self.timerId)
+ checkCallback()
+
+ cleanup()
+ ScreenshotApp.start(resolution=TEST_RESOLUTION)
+ cleanup()
+
+ def testGraphs(self):
+ class GraphsApp(TestAppBase):
+ def init(self):
+ self.enableGraphs()
+
+ def enableGraphs(self):
+ self.singleKeyPress('f')
+ self.singleKeyPress('m')
+ player.setTimeout(500, self.disableGraphs)
+
+ def disableGraphs(self):
+ self.singleKeyPress('m')
+ self.singleKeyPress('f')
+ self.requestStop()
+
+ GraphsApp.start(resolution=TEST_RESOLUTION)
+
+ def testToggleKeys(self):
+ TOGGLE_KEYS = ['?', 't', 'e']
+ class ToggleKeysApp(TestAppBase):
+ def init(self):
+ self.keys = TOGGLE_KEYS[:]
+ player.setTimeout(0, self.nextKey)
+
+ def nextKey(self):
+ if not self.keys:
+ player.stop()
+ else:
+ key = self.keys.pop()
+ self.singleKeyPress(key)
+ player.setTimeout(0, self.nextKey)
+
+ ToggleKeysApp.start(resolution=TEST_RESOLUTION)
+
+ def testFakeFullscreen(self):
+ class FakeFullscreenApp(TestAppBase):
+ fakeFullscreen = True
+ def init(self):
+ player.setTimeout(0, player.stop)
+
+ resolution = player.getScreenResolution()
+ if os.name == 'nt':
+ FakeFullscreenApp.start(resolution=resolution)
+ else:
+ self.assertException(
+ lambda: FakeFullscreenApp.start(resolution=resolution))
+
+def avgAppTestSuite(tests):
+ availableTests = (
+ 'testMinimal',
+ 'testAvgDeploy',
+ 'testDebugWindowSize',
+ 'testScreenshot',
+ 'testGraphs',
+ 'testToggleKeys',
+ 'testFakeFullscreen',
+ )
+ return testcase.createAVGTestSuite(availableTests, AVGAppTestCase, tests)
diff --git a/src/test/AVTest.py b/src/test/AVTest.py
new file mode 100644
index 0000000..04de91e
--- /dev/null
+++ b/src/test/AVTest.py
@@ -0,0 +1,674 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# libavg - Media Playback Engine.
+# Copyright (C) 2003-2014 Ulrich von Zadow
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Current versions can be found at www.libavg.de
+#
+
+from libavg import avg, player
+from testcase import *
+
+class AVTestCase(AVGTestCase):
+ def __init__(self, testFuncName):
+ AVGTestCase.__init__(self, testFuncName)
+
+ def setUp(self):
+ AVGTestCase.setUp(self)
+
+ def testEOF(self, node):
+ def onEOF():
+ player.stop()
+
+ def onNoEOF():
+ self.fail("No EOF")
+
+ def onSubscribeEOF():
+ self.eofCalled = True
+
+ self.eofCalled = False
+ root = self.loadEmptyScene()
+ root.appendChild(node)
+ node.play()
+ node.setEOFCallback(onEOF)
+ node.subscribe(avg.Node.END_OF_FILE, onSubscribeEOF)
+ player.setTimeout(100000, onNoEOF)
+ player.play()
+ self.assert_(self.eofCalled)
+
+ def testVideoInfo(self):
+ def checkInfo():
+ node.pause()
+ self.assertEqual(node.getContainerFormat(), "avi")
+ self.assertEqual(node.getCurFrame(), 0)
+ self.assertEqual(node.getCurTime(), 0)
+ self.assertEqual(node.getDuration(), 1000)
+ self.assertEqual(node.getBitrate(), 224064)
+ self.assertEqual(node.getVideoCodec(), "mpeg4")
+ self.assertEqual(node.getStreamPixelFormat(), "yuv420p")
+ self.assertEqual(node.getVideoDuration(), 1000)
+ if isThreaded:
+ self.assertEqual(node.getAudioCodec(), "mp2")
+ self.assertEqual(node.getAudioSampleRate(), 44100)
+ self.assertEqual(node.getNumAudioChannels(), 2)
+ self.assert_(node.getVideoDuration() >= 1000)
+
+ def checkEnableSound():
+ node = avg.VideoNode(href="mpeg1-48x48-sound.avi", threaded=isThreaded,
+ enablesound=False, parent=root)
+ node.pause()
+ self.assertEqual(node.getVideoCodec(), "mpeg4")
+ self.assertException(node.getAudioCodec)
+
+ def checkExceptions():
+ node = avg.VideoNode(href="mpeg1-48x48.mov", threaded=isThreaded)
+ self.assertException(node.getDuration)
+ self.assertException(node.getBitrate)
+ self.assertException(node.getVideoCodec)
+ self.assertException(node.getStreamPixelFormat)
+ node.pause()
+ self.assertException(node.getAudioCodec)
+ self.assertException(node.getAudioSampleRate)
+ self.assertException(node.getNumAudioChannels)
+ root.appendChild(node)
+
+ def checkAudioFile():
+ node = avg.VideoNode(href="44.1kHz_16bit_stereo.wav", threaded=isThreaded,
+ parent=root)
+ self.assertException(node.pause)
+
+ sys.stderr.write("\n")
+ for isThreaded in (False, True):
+ sys.stderr.write(" Threaded: " + str(isThreaded) + "\n")
+ root = self.loadEmptyScene()
+ node = avg.VideoNode(href="mpeg1-48x48-sound.avi", threaded=isThreaded,
+ parent=root)
+ checkInfo()
+ checkEnableSound()
+ checkExceptions()
+ self.start(False,
+ (checkInfo,
+ checkExceptions,
+ checkAudioFile,
+ ))
+ sys.stderr.write(" Nonstandard queue length\n")
+ root = self.loadEmptyScene()
+ node = avg.VideoNode(href="mpeg1-48x48-sound.avi", queuelength=23, parent=root)
+ self.assertEqual(node.queuelength, 23)
+
+ def testVideoFiles(self):
+ def testVideoFile(filename, isThreaded):
+ def setVolume(volume):
+ node.volume = volume
+
+ def testGetVolume(volume):
+ self.assertAlmostEqual(node.volume, volume)
+
+ def checkImage(filename):
+ if not(isThreaded):
+ self.compareImage("testVideo-"+filename+"1")
+
+ def testInfo():
+ if filename == "mpeg1-48x48-sound.avi" and isThreaded:
+ self.assert_(node.hasAudio())
+ else:
+ self.assert_(not(node.hasAudio()))
+ self.assert_((filename == "rgba-48x48.mov" or
+ filename == "vp6a-yuva-48x48.flv") == node.hasAlpha())
+
+ root = self.loadEmptyScene()
+ node = avg.VideoNode(href=filename, volume=0.8, size=(96,96),
+ threaded=isThreaded)
+ self.assertEqual(node.threaded, isThreaded)
+ setVolume(0.6)
+ root.appendChild(node)
+ self.assertException(node.hasAudio)
+ self.start(False,
+ (lambda: setVolume(0.5),
+ lambda: testGetVolume(0.5),
+ lambda: node.play(),
+ lambda: checkImage(filename),
+ lambda: setVolume(0.3),
+ lambda: testGetVolume(0.3),
+ testInfo,
+ lambda: node.stop()
+ ))
+ videoFiles = ["mjpeg-48x48.avi", "mpeg1-48x48.mov", #"mpeg1-48x48-sound.avi",
+ "rgba-48x48.mov", "h264-48x48.h264", "vp6a-yuva-48x48.flv"]
+ sys.stderr.write("\n")
+ for filename in videoFiles:
+ sys.stderr.write(" "+filename+"\n")
+ for isThreaded in [False, True]:
+ sys.stderr.write(" threaded: "+str(isThreaded)+"\n")
+ testVideoFile(filename, isThreaded)
+
+ def testPlayBeforeConnect(self):
+ node = avg.VideoNode(href="media/mpeg1-48x48.mov", threaded=False)
+ node.play()
+ player.createMainCanvas(size=(160,120))
+ root = player.getRootNode()
+ root.insertChild(node, 0)
+ player.setFakeFPS(25)
+ self.start(False,
+ (lambda: self.assertEqual(node.size, (48, 48)),
+ lambda: self.compareImage("testPlayBeforeConnect"),
+ ))
+
+ def testVideoState(self):
+ for accelerated in [True, False]:
+ root = self.loadEmptyScene()
+ node = avg.VideoNode(href="mpeg1-48x48.mov", size=(96,96), threaded=False,
+ accelerated=accelerated, parent=root)
+ player.setFakeFPS(25)
+ self.start(False,
+ (lambda: node.play(),
+ lambda: self.compareImage("testVideoState1"),
+ lambda: node.pause(),
+ lambda: self.compareImage("testVideoState2"),
+ lambda: self.compareImage("testVideoState2"),
+ lambda: node.play(),
+ lambda: self.compareImage("testVideoState3"),
+ lambda: node.stop(),
+ lambda: self.compareImage("testVideoState4"),
+ lambda: node.pause(),
+ lambda: self.compareImage("testVideoState5"),
+ lambda: self.compareImage("testVideoState5"),
+ lambda: node.stop(),
+ lambda: self.compareImage("testVideoState4"),
+ ))
+
+ def testVideoActive(self):
+ def deactivate():
+ node.active=0
+
+ def activate():
+ node.active=1
+
+ root = self.loadEmptyScene()
+ node = avg.VideoNode(href="mpeg1-48x48.mov", size=(96,96), threaded=False,
+ parent=root)
+ player.setFakeFPS(25)
+ self.start(False,
+ (lambda: node.play(),
+ deactivate,
+ lambda: self.compareImage("testVideoActive1"),
+ activate,
+ lambda: self.compareImage("testVideoActive2")
+ ))
+
+ def testVideoHRef(self):
+ def testGetMediaSize():
+ self.assertEqual(node.getMediaSize(), (48, 48))
+
+ def setHRefLoaded():
+ node.href = "h264-48x48.h264"
+
+ def setHRefUnloaded():
+ node = avg.VideoNode()
+ node.href = "h264-48x48.h264"
+ node.play()
+
+ def testVideoNotFound():
+ # Missing file, but no play() or pause(): Should just work.
+ node = avg.VideoNode(href="MissingFile.mov")
+ node.href = "SecondMissingFile.mov"
+ # Now libavg notices the missing file.
+ self.assertException(node.play)
+
+ def testVideoBroken():
+ node = avg.VideoNode(href="rgb24-64x64.png")
+ self.assertException(node.play)
+
+ root = self.loadEmptyScene()
+ node = avg.VideoNode(href="mpeg1-48x48.mov", threaded=False, parent=root)
+ player.setFakeFPS(25)
+ testVideoNotFound()
+ testVideoBroken()
+ setHRefUnloaded()
+ self.start(False,
+ (lambda: node.play(),
+ testGetMediaSize,
+ setHRefLoaded,
+ lambda: self.compareImage("testVideoHRef1"),
+ testGetMediaSize,
+ testVideoNotFound,
+ testVideoBroken
+ ))
+
+ def testVideoOpacity(self):
+ def testWithFile(filename, testImgName):
+ def hide():
+ self.videoNode.opacity=0
+
+ def show():
+ self.videoNode.opacity=1
+
+ player.setFakeFPS(25)
+ root = self.loadEmptyScene()
+ self.videoNode = avg.VideoNode(href=filename, loop=True, threaded=False,
+ parent=root)
+ self.start(False,
+ (lambda: self.videoNode.play(),
+ None,
+ lambda: self.compareImage(testImgName+"1"),
+ hide,
+ None,
+ None,
+ show,
+ lambda: self.compareImage(testImgName+"2")
+ ))
+ testWithFile("rgba-48x48.mov", "testVideoOpacityRGBA")
+ testWithFile("mpeg1-48x48.mov", "testVideoOpacityYUV")
+
+ def testVideoSeek(self):
+ def seek(frame):
+ videoNode.seekToFrame(frame)
+
+ def checkCurFrame():
+ self.assertEqual(videoNode.getCurFrame(), 26)
+
+ player.setFakeFPS(25)
+ for useCustomFPS in [False, True]:
+ root = self.loadEmptyScene()
+ if useCustomFPS:
+ videoNode = avg.VideoNode(parent=root, loop=True, size=(96,96), fps=25,
+ threaded=False, href="mjpeg-48x48.avi")
+ else:
+ videoNode = avg.VideoNode(parent=root, loop=True, size=(96,96),
+ threaded=False, href="mjpeg-48x48.avi")
+
+ videoNode.play()
+ seek(26)
+ self.start(False,
+ (checkCurFrame,
+ lambda: self.compareImage("testVideoSeek0"),
+ lambda: seek(100),
+ lambda: self.compareImage("testVideoSeek1"),
+ lambda: videoNode.pause(),
+ lambda: seek(26),
+ None,
+ lambda: self.compareImage("testVideoSeek2"),
+ lambda: videoNode.play(),
+ None,
+ lambda: self.compareImage("testVideoSeek3")
+ ))
+
+ def checkSeek():
+ seek(26)
+ self.assertNotEqual(videoNode.getCurFrame(), 0)
+
+ def testVideoFPS(self):
+ player.setFakeFPS(25)
+ root = self.loadEmptyScene()
+ root = root
+ videoNode = avg.VideoNode(size=(80,80), loop=True, threaded=False,
+ href="mjpeg-48x48.avi", fps=250, parent=root)
+ self.start(False,
+ (lambda: videoNode.play(),
+ None,
+ lambda: self.compareImage("testVideoFPS")
+ ))
+
+ def testVideoLoop(self):
+ def onEOF():
+ self.eof = True
+
+ def onFrame():
+ if self.eof:
+ if not(threaded):
+ self.compareImage("testVideoLoop")
+ player.stop()
+
+ for threaded in [False, True]:
+ self.eof = False
+ player.setFakeFPS(25)
+ root = self.loadEmptyScene()
+ videoNode = avg.VideoNode(parent=root, loop=True, fps=25, size=(96,96),
+ threaded=threaded, href="mpeg1-48x48.mov")
+ videoNode.subscribe(avg.Node.END_OF_FILE, onEOF)
+ videoNode.play()
+ player.subscribe(player.ON_FRAME, onFrame)
+ player.play()
+
+ def testVideoMask(self):
+ def testWithFile(filename, testImgName):
+ def setMask(href):
+ video.maskhref = href
+
+ def setOpacity():
+ video.opacity = 0.5
+
+ player.setFakeFPS(25)
+ root = self.loadEmptyScene()
+ video = avg.VideoNode(href=filename, threaded=False,
+ parent=root)
+ video.play()
+ self.start(False,
+ (lambda: setMask("mask.png"),
+ lambda: self.compareImage(testImgName+"1"),
+ lambda: video.seekToFrame(10),
+ lambda: setMask(""),
+ lambda: self.compareImage(testImgName+"2"),
+ lambda: setMask("mask2.png"),
+ lambda: self.compareImage(testImgName+"3"),
+ setOpacity,
+ lambda: self.compareImage(testImgName+"4"),
+ ))
+
+ testWithFile("mpeg1-48x48.mov", "testVideoMaskYUV")
+ testWithFile("mjpeg-48x48.avi", "testVideoMaskYUVJ")
+ testWithFile("rgba-48x48.mov", "testVideoMaskRGBA")
+
+ def testException(self):
+ class TestException(Exception):
+ pass
+
+ def throwException():
+ raise TestException
+
+ player.setFakeFPS(0.1)
+ videoNode = avg.VideoNode(threaded = False)
+ videoNode.href = "../testmediadir/mjpeg-48x48.avi"
+ videoNode.subscribe(avg.Node.END_OF_FILE, throwException)
+
+ root = self.loadEmptyScene()
+ root.appendChild(videoNode)
+
+ self.__exceptionThrown = False
+ try:
+ self.start(False,
+ (videoNode.pause,
+ lambda: videoNode.seekToFrame(videoNode.getNumFrames()),
+ videoNode.play,
+ lambda: None
+ ))
+ except TestException:
+ self.__exceptionThrown = True
+
+ self.assert_(self.__exceptionThrown)
+
+ def testVideoEOF(self):
+ player.setFakeFPS(25)
+ for filename in ["mpeg1-48x48.mov", "mpeg1-48x48-sound.avi"]:
+ node = avg.VideoNode(href=filename)
+ self.testEOF(node)
+ node = avg.VideoNode(href="mpeg1-48x48.mov", opacity=0)
+ self.testEOF(node)
+
+ root = self.loadEmptyScene()
+ video = avg.VideoNode(href="mpeg1-48x48.mov", threaded=False,
+ parent=root)
+ player.setFakeFPS(0.1)
+
+ # Should never be called
+ eofID = video.subscribe(avg.Node.END_OF_FILE, lambda: self.assert_(False))
+ self.start(False,
+ (lambda: video.unsubscribe(avg.Node.END_OF_FILE, eofID),
+ video.play,
+ None
+ ))
+
+ def testVideoSeekAfterEOF(self):
+ def onEOF():
+ node.seekToTime(0)
+ player.subscribe(avg.Player.ON_FRAME, onFrame)
+
+ def onFrame():
+ if node.getCurTime() < 100:
+ self.compareImage("testSeekAfterEOF")
+ player.stop()
+
+ def onNoEOF():
+ self.fail("No EOF")
+
+ player.setFakeFPS(25)
+ root = self.loadEmptyScene()
+ node = avg.VideoNode(href="mpeg1-48x48.mov", parent=root)
+ node.play()
+ node.subscribe(avg.VideoNode.END_OF_FILE, onEOF)
+ player.setTimeout(100000, onNoEOF)
+ player.play()
+
+ def testSound(self):
+ def testSoundFile(filename):
+ def setVolume(volume):
+ node.volume = volume
+
+ def testGetVolume(volume):
+ self.assertAlmostEqual(node.volume, volume)
+
+ root = self.loadEmptyScene()
+ node = avg.SoundNode(href=filename, parent=root)
+ self.start(False,
+ (lambda: setVolume(0.5),
+ lambda: testGetVolume(0.5),
+ lambda: node.play(),
+ None,
+ lambda: node.stop(),
+ lambda: node.play(),
+ lambda: node.pause(),
+ lambda: node.play(),
+ lambda: setVolume(0.5),
+ lambda: testGetVolume(0.5),
+ lambda: node.pause(),
+ lambda: node.stop(),
+ lambda: setVolume(0.3),
+ lambda: testGetVolume(0.3),
+ lambda: node.pause()
+ ))
+ player.setFakeFPS(-1)
+ player.volume = 0
+ # "44.1kHz_mono.ogg" not tested for now - broken under Windows.
+ # Assuming buggy ffmpeg version.
+ for filename in ["22.050Hz_16bit_mono.wav", "44.1kHz_16bit_stereo.aif",
+ "44.1kHz_16bit_stereo.wav", "44.1kHz_stereo.mp3",
+ "48kHz_24bit_stereo.wav"]:
+ testSoundFile(filename)
+
+ def testSoundInfo(self):
+ def checkInfo():
+ node.pause()
+ self.assertEqual(node.getAudioCodec(), "pcm_s16le")
+ self.assertEqual(node.getAudioSampleRate(), 44100)
+ self.assertEqual(node.getNumAudioChannels(), 2)
+
+ def checkExceptions():
+ node = avg.SoundNode(href="44.1kHz_16bit_stereo.wav")
+ self.assertException(node.getAudioCodec)
+ self.assertException(node.getAudioSampleRate)
+ self.assertException(node.getNumAudioChannels)
+
+ def checkVideoFile():
+ node = avg.SoundNode(href="mpeg1-48x48.mov", parent=root)
+ self.assertException(node.pause)
+
+ root = self.loadEmptyScene()
+ node = avg.SoundNode(href="44.1kHz_16bit_stereo.wav", parent=root)
+ checkInfo()
+ checkExceptions()
+ self.start(False,
+ (checkInfo,
+ checkExceptions,
+ checkVideoFile,
+ ))
+
+ def testSoundSeek(self):
+ player.setFakeFPS(-1)
+ player.volume = 0
+ root = self.loadEmptyScene()
+ soundNode = avg.SoundNode(parent=root, href="44.1kHz_16bit_stereo.wav")
+ soundNode.play()
+ soundNode.seekToTime(500)
+ self.start(False,
+ (None,
+ lambda: soundNode.seekToTime(200),
+ ))
+
+
+ def testBrokenSound(self):
+ def openSound():
+ node = avg.SoundNode(href="44.1kHz_16bit_6Chan.ogg", parent=root)
+ self.assertException(node.play)
+
+ root = self.loadEmptyScene()
+ self.start(False, [openSound])
+
+ def testSoundEOF(self):
+ player.setFakeFPS(-1)
+ player.volume = 0
+ node = avg.SoundNode(href="44.1kHz_16bit_mono.wav")
+ self.testEOF(node)
+
+ def testVideoWriter(self):
+
+ def startWriter(fps, syncToPlayback):
+ self.videoWriter = avg.VideoWriter(canvas, "test.mov", fps, 3, 5,
+ syncToPlayback)
+
+ def stopWriter():
+ self.videoWriter.stop()
+
+ def killWriter():
+ self.videoWriter = None
+
+ def pauseWriter():
+ self.videoWriter.pause()
+
+ def playWriter():
+ self.videoWriter.play()
+
+ def hideVideo():
+ videoNode.opacity = 0
+
+ def showVideo():
+ videoNode.opacity = 1
+
+ def checkVideo(numFrames):
+ savedVideoNode = avg.VideoNode(href="../test.mov", pos=(48,0),
+ threaded=False, parent=root)
+ savedVideoNode.pause()
+ self.assertEqual(savedVideoNode.getVideoCodec(), "mjpeg")
+ self.assertEqual(savedVideoNode.getNumFrames(), numFrames)
+ self.assertEqual(savedVideoNode.getStreamPixelFormat(), "yuvj420p")
+
+ def testCreateException():
+ self.assertException(lambda: avg.VideoWriter(player.getMainCanvas(),
+ "nonexistentdir/test.mov", 30))
+
+ if not(self._isCurrentDirWriteable()):
+ self.skip("Current dir not writeable.")
+ return
+ if player.isUsingGLES():
+ self.skip("VideoWriter not supported under GLES.")
+ return
+
+ self.assertException(lambda:
+ avg.VideoWriter(player.getMainCanvas(), "test.mov", 30, 3, 5, False))
+
+ for useCanvas in (False, True):
+ player.setFakeFPS(30)
+
+ root = self.loadEmptyScene()
+ videoNode = avg.VideoNode(href="mpeg1-48x48.mov", threaded=False)
+ if useCanvas:
+ canvas = player.createCanvas(id="canvas", size=(48,48),
+ mediadir="media")
+ canvas.getRootNode().appendChild(videoNode)
+ avg.ImageNode(parent=root, href="canvas:canvas")
+ testImageName = "testVideoWriterCanvas"
+ else:
+ root.appendChild(videoNode)
+ canvas = player.getMainCanvas()
+ testImageName = "testVideoWriter"
+
+ self.start(False,
+ (videoNode.play,
+ lambda: startWriter(30, True),
+ lambda: self.delay(100),
+ stopWriter,
+ killWriter,
+ lambda: checkVideo(4),
+ hideVideo,
+ lambda: self.compareImage(testImageName+"1"),
+ showVideo,
+ testCreateException,
+ lambda: startWriter(15, False),
+ lambda: self.delay(150),
+ stopWriter,
+ killWriter,
+ lambda: checkVideo(2),
+ lambda: startWriter(30, False),
+ pauseWriter,
+ lambda: self.delay(200),
+ playWriter,
+ stopWriter,
+ killWriter,
+ lambda: checkVideo(1),
+ lambda: startWriter(30, False),
+ killWriter,
+ lambda: checkVideo(1),
+ ))
+ os.remove("test.mov")
+
+ def test2VideosAtOnce(self):
+ player.setFakeFPS(25)
+ self.loadEmptyScene()
+ root = player.getRootNode()
+ for pos in ((0,0), (80,0)):
+ video = avg.VideoNode(pos=pos, threaded=False, href="mpeg1-48x48.mov",
+ parent=root)
+ video.play()
+ self.start(False,
+ [lambda: self.compareImage("test2VideosAtOnce1"),])
+
+ def testVideoAccel(self):
+ accelConfig = avg.VideoNode.getVideoAccelConfig()
+ video = avg.VideoNode(accelerated=False, href="media/mpeg1-48x48.mov")
+ video.play()
+ self.assertEqual(video.accelerated, False)
+ video = avg.VideoNode(accelerated=True, href="media/mpeg1-48x48.mov")
+ video.play()
+ self.assertEqual(video.accelerated, (accelConfig != avg.NO_ACCELERATION))
+
+
+def AVTestSuite(tests):
+ availableTests = [
+ "testSound",
+ "testSoundInfo",
+ "testSoundSeek",
+ "testBrokenSound",
+ "testSoundEOF",
+ "testVideoInfo",
+ "testVideoFiles",
+ "testPlayBeforeConnect",
+ "testVideoState",
+ "testVideoActive",
+ "testVideoHRef",
+ "testVideoOpacity",
+ "testVideoSeek",
+ "testVideoFPS",
+ "testVideoLoop",
+ "testVideoMask",
+ "testVideoEOF",
+ "testVideoSeekAfterEOF",
+ "testException",
+ "testVideoWriter",
+ "test2VideosAtOnce",
+ "testVideoAccel",
+ ]
+ return createAVGTestSuite(availableTests, AVTestCase, tests)
+
diff --git a/src/test/AnimTest.py b/src/test/AnimTest.py
new file mode 100644
index 0000000..4079b6a
--- /dev/null
+++ b/src/test/AnimTest.py
@@ -0,0 +1,512 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# libavg - Media Playback Engine.
+# Copyright (C) 2003-2014 Ulrich von Zadow
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Current versions can be found at www.libavg.de
+#
+
+from libavg import avg, player
+from testcase import *
+
+class AnimTestCase(AVGTestCase):
+ def __init__(self, testFuncName):
+ AVGTestCase.__init__(self, testFuncName)
+
+ def initScene(self):
+ root = self.loadEmptyScene()
+ self.__node = avg.ImageNode(id="test", pos=(64,30), href="rgb24-65x65.png",
+ parent=root)
+ player.setFakeFPS(10)
+
+ def testAnimType(self, curAnim, imgBaseName):
+ def onStop():
+ self.__onStopCalled = True
+
+ def startAnim():
+ self.__onStopCalled = False
+ self.__anim.start()
+
+ def startKeepAttr():
+ self.__node.x = 32
+ self.__anim.start(True)
+
+ def abortAnim():
+ self.__anim.abort()
+
+ self.__anim = curAnim
+ self.__anim.setStopCallback(onStop)
+ self.__onStopCalled = False
+ self.assertException(lambda: self.__anim.start())
+ self.start(False,
+ (startAnim,
+ lambda: self.compareImage(imgBaseName+"1"),
+ lambda: self.compareImage(imgBaseName+"2"),
+ lambda: self.compareImage(imgBaseName+"3"),
+ lambda: self.assert_(self.__onStopCalled),
+ lambda: self.assert_(not(self.__anim.isRunning())),
+ lambda: self.assertEqual(avg.getNumRunningAnims(), 0),
+ lambda: self.compareImage(imgBaseName+"4"),
+ lambda: self.assertEqual(self.__node.x, 100),
+ startAnim,
+ lambda: self.compareImage(imgBaseName+"1"),
+ lambda: self.assertEqual(avg.getNumRunningAnims(), 1),
+ abortAnim,
+ lambda: self.assertEqual(avg.getNumRunningAnims(), 0),
+ lambda: self.compareImage(imgBaseName+"5"),
+ lambda: self.assert_(not(self.__anim.isRunning())),
+ None,
+ lambda: self.assert_(self.__onStopCalled),
+ startKeepAttr,
+ lambda: self.compareImage(imgBaseName+"6"),
+ lambda: self.assertEqual(avg.getNumRunningAnims(), 1)
+ ))
+ self.__anim = None
+
+ def testLinearAnim(self):
+ self.initScene()
+ curAnim = avg.LinearAnim(self.__node, "x", 300, 0, 100)
+ self.testAnimType(curAnim, "testLinearAnimC")
+
+ def testAnimRegistry(self):
+ def on1Stop():
+ self.__onStopCalled = True
+
+ def on2Start():
+ self.__onStopBeforeOnStart = self.__onStopCalled
+
+ self.initScene()
+ sameNode = player.getElementByID("test")
+ anim1 = avg.LinearAnim(self.__node, "x", 500, 0, 100,
+ False, None, on1Stop)
+ anim2 = avg.LinearAnim(sameNode, "x", 300, 0, 100,
+ False, on2Start)
+ self.__onStopCalled = False
+ self.__onStopBeforeOnStart = False
+ self.start(False,
+ (lambda: anim1.start(),
+ lambda: self.assert_(not(self.__onStopCalled)),
+ lambda: anim2.start(),
+ lambda: self.assert_(self.__onStopBeforeOnStart),
+ lambda: self.assertEqual(avg.getNumRunningAnims(), 1)
+ ))
+ anim1 = None
+ anim2 = None
+
+ def testFadeIn(self):
+ def onStop():
+ self.__onStopCalled = True
+
+ self.initScene()
+ self.__node.opacity=0.5
+ self.__onStopCalled = False
+ self.start(False,
+ (lambda: avg.fadeIn(self.__node, 200, 1, onStop),
+ lambda: self.compareImage("testFadeIn1"),
+ lambda: self.compareImage("testFadeIn2"),
+ lambda: self.compareImage("testFadeIn3"),
+ lambda: self.assert_(self.__onStopCalled),
+ lambda: self.assertEqual(avg.getNumRunningAnims(), 0)
+ ))
+ self.__anim = None
+
+ def testFadeOut(self):
+ def onStop():
+ self.__onStopCalled = True
+
+ self.initScene()
+ self.__node.opacity=0.5
+ self.__onStopCalled = False
+ self.start(False,
+ (lambda: avg.fadeOut(self.__node, 200, onStop),
+ lambda: self.compareImage("testFadeOut1"),
+ lambda: self.compareImage("testFadeOut2"),
+ lambda: self.compareImage("testFadeOut3"),
+ lambda: self.assert_(self.__onStopCalled),
+ lambda: self.assertEqual(avg.getNumRunningAnims(), 0)
+ ))
+ self.__anim = None
+
+ def testNonExistentAttributeAnim(self):
+ self.initScene()
+ self.assertException(lambda: avg.LinearAnim(self.__node, "foo", 0, 0, 0, False))
+ self.assertException(lambda: avg.LinearAnim(None, "x", 0, 0, 0, False))
+
+ def testLinearAnimZeroDuration(self):
+ def onStop():
+ self.__onStopCalled = True
+
+ def startAnim():
+ self.__onStopCalled = False
+ self.__anim.start()
+
+ self.initScene()
+ self.__anim = avg.LinearAnim(self.__node, "x", 0, 0, 100, False, None, onStop)
+ self.__onStopCalled = False
+ self.start(False,
+ (startAnim,
+ lambda: self.compareImage("testLinearAnimZeroDurationC1"),
+ lambda: self.assertEqual(avg.getNumRunningAnims(), 0),
+ lambda: self.assert_(self.__onStopCalled),
+ lambda: self.assert_(not(self.__anim.isRunning()))
+ ))
+ self.__anim = None
+
+ def testPingPongStopAnim(self):
+ def forth():
+ anim = avg.LinearAnim(self.__node, 'pos', 100, (50, 100),
+ (100, 100), False, None, back)
+ anim.start()
+
+ def back():
+ anim = avg.LinearAnim(self.__node, 'pos', 100, (100, 100),
+ (50, 100), False, None, forth)
+ anim.start()
+
+ self.initScene()
+ self.start(False,
+ (forth,
+ lambda: self.delay(300),
+ ))
+
+ def testPointAnim(self):
+ self._testPointAnim(
+ startPos=(0, 0),
+ endPos=(100, 40),
+ keepAttrPos=(50, 20),
+ startPosImgSrc="testPointAnim1",
+ endPosImgSrc="testPointAnim2",
+ keepAttrPosImgSrc="testPointAnim3")
+
+ def testXPosPointAnim(self):
+ self._testPointAnim(
+ startPos=(0, 0),
+ endPos=(80, 0),
+ keepAttrPos=(40, 0),
+ startPosImgSrc="testXPosPointAnim1",
+ endPosImgSrc="testXPosPointAnim2",
+ keepAttrPosImgSrc="testXPosPointAnim3")
+
+ def testYPosPointAnim(self):
+ self._testPointAnim(
+ startPos=(0, 0),
+ endPos=(0, 80),
+ keepAttrPos=(0, 40),
+ startPosImgSrc="testYPosPointAnim1",
+ endPosImgSrc="testYPosPointAnim2",
+ keepAttrPosImgSrc="testYPosPointAnim3")
+
+ def testIntAnim(self):
+ self.initScene()
+ self.__doubleAnim = avg.LinearAnim(self.__node, "x", 300, 0, 100, True)
+ self.__pointAnim = avg.LinearAnim(self.__node, "pos", 200, avg.Point2D(0,0),
+ avg.Point2D(100,40), True)
+ self.start(False,
+ (self.__doubleAnim.start,
+ lambda: self.delay(100),
+ lambda: self.compareImage("testIntAnim1"),
+ self.__doubleAnim.abort,
+ self.__pointAnim.start,
+ lambda: self.delay(100),
+ lambda: self.compareImage("testIntAnim2"),
+ ))
+
+ def testEaseInOutAnim(self):
+ self.initScene()
+ curAnim = avg.EaseInOutAnim(self.__node, "x", 300, 0, 100, 100, 100, False)
+ self.testAnimType(curAnim, "testEaseInOutAnimC")
+
+ def testContinuousAnim(self):
+ def startAnim():
+ self.__animStarted = True
+
+ def stopAnim():
+ self.__animStopped = True
+
+ def reset():
+ self.__animStarted = False
+ self.__animStopped = False
+
+ self.initScene()
+ self.__anim = avg.ContinuousAnim(self.__node, "angle", 0, 2*math.pi,
+ False, startAnim, stopAnim)
+ self.__linearAnim = avg.LinearAnim(self.__node, "angle", 1000, math.pi, math.pi)
+
+ self.__animStarted = False
+ self.__animStopped = False
+ self.start(False,
+ (self.__anim.start,
+ lambda: self.assert_(self.__animStarted),
+ lambda: self.compareImage("testContinuousAnim1"),
+ self.__anim.abort,
+ lambda: self.assert_(self.__animStopped),
+ reset,
+ self.__anim.start,
+ self.__linearAnim.start,
+ lambda: self.assert_(self.__animStopped),
+ lambda: self.compareImage("testContinuousAnim2"),
+ self.__linearAnim.abort,
+ ))
+
+ def testWaitAnim(self):
+ def animStopped():
+ self.__endCalled = True
+
+ def startAnim():
+ self.anim = avg.WaitAnim(200, animStopped, None)
+ self.anim.start()
+
+ self.initScene()
+ self.__endCalled = False
+ self.start(False,
+ (startAnim,
+ lambda: self.assert_(self.anim.isRunning()),
+ lambda: self.delay(200),
+ lambda: self.assert_(not(self.anim.isRunning())),
+ lambda: self.assert_(self.__endCalled)
+ ))
+
+ def testParallelAnim(self):
+ def animStopped():
+ self.__endCalled = True
+
+ def startFireForgetAnim():
+ avg.ParallelAnim(
+ [ avg.LinearAnim(self.nodes[0], "x", 200, 0, 60),
+ avg.LinearAnim(self.nodes[1], "x", 200, 0, 120)
+ ]).start()
+
+ def startAnim():
+ self.anim = avg.ParallelAnim(
+ [ avg.LinearAnim(self.nodes[0], "x", 200, 0, 60),
+ avg.LinearAnim(self.nodes[1], "x", 400, 0, 120),
+ avg.EaseInOutAnim(self.nodes[2], "x", 400, 0, 120, 100, 100)
+ ], None, animStopped)
+ self.__endCalled = False
+ self.anim.start()
+
+ def startTimedAnim():
+ self.anim = avg.ParallelAnim(
+ [ avg.LinearAnim(self.nodes[0], "x", 200, 0, 60),
+ avg.LinearAnim(self.nodes[1], "x", 400, 0, 120),
+ ], None, animStopped, 200)
+ self.__endCalled = False
+ self.anim.start()
+
+ def abortAnim():
+ self.anim.abort()
+
+ def deleteAnim():
+ self.anim = None
+
+ root = self.loadEmptyScene()
+ self.nodes = []
+ for i in range(3):
+ node = avg.ImageNode(id=str(i), pos=(64, i*20), href="rgb24-64x64.png")
+ root.appendChild(node)
+ self.nodes.append(node)
+ player.setFakeFPS(10)
+ self.__endCalled = False
+ self.start(False,
+ (startFireForgetAnim,
+ lambda: self.assertEqual(avg.getNumRunningAnims(), 2),
+ None,
+ startAnim,
+ lambda: self.assertEqual(avg.getNumRunningAnims(), 3),
+ lambda: self.compareImage("testParallelAnimC1"),
+ lambda: self.assert_(self.anim.isRunning()),
+ lambda: self.delay(200),
+ lambda: self.assert_(not(self.anim.isRunning())),
+ lambda: self.compareImage("testParallelAnimC2"),
+ lambda: self.assert_(self.__endCalled),
+ lambda: self.assertEqual(avg.getNumRunningAnims(), 0),
+ startAnim,
+ abortAnim,
+ lambda: self.compareImage("testParallelAnimC3"),
+ lambda: self.assert_(self.__endCalled),
+ lambda: self.assertEqual(avg.getNumRunningAnims(), 0),
+ startTimedAnim,
+ lambda: self.delay(200),
+ lambda: self.assert_(self.__endCalled),
+ lambda: self.assertEqual(avg.getNumRunningAnims(), 0),
+ startAnim
+ ))
+ self.nodes = []
+
+ def testParallelAnimRegistry(self):
+ def makeAnims():
+ avg.ParallelAnim(
+ [ avg.LinearAnim(self.__node, "x", 200, 0, 60),
+ avg.LinearAnim(self.__node, "y", 200, 0, 120)
+ ]).start()
+
+ avg.LinearAnim(self.__node, "x", 300, 0, 100, False, None).start()
+
+ self.initScene()
+ self.start(False,
+ (makeAnims,
+ None
+ ))
+
+ def testStateAnim(self):
+ def state1StopCallback():
+ self.__state1StopCallbackCalled = True
+
+ def state2StartCallback():
+ if self.__state1StopCallbackCalled:
+ self.__stop1Start2CallbackOrder = True
+ self.__state2StartCallbackCalled = True
+
+ def makeAnim():
+ self.anim = avg.StateAnim(
+ [avg.AnimState("STATE1", avg.LinearAnim(self.__node, "x", 200,
+ 0, 100, False, None, state1StopCallback), "STATE2"),
+ avg.AnimState("STATE2", avg.LinearAnim(self.__node, "x", 200,
+ 100, 50, False, state2StartCallback), "STATE3"),
+ avg.AnimState("STATE3", avg.WaitAnim())
+ ])
+# self.anim.setDebug(True)
+
+ def killAnim():
+ self.anim = None
+
+ self.initScene()
+ self.__state1StopCallbackCalled = False
+ self.__state2StartCallbackCalled = False
+ self.__stop1Start2CallbackOrder = False
+ self.start(False,
+ (makeAnim,
+ lambda: self.compareImage("testStateAnimC1"),
+ lambda: self.anim.setState("STATE1"),
+ None,
+ lambda: self.compareImage("testStateAnimC2"),
+ lambda: self.assertEqual(self.anim.getState(), "STATE2"),
+ lambda: self.compareImage("testStateAnimC3"),
+ lambda: self.assert_(self.__state1StopCallbackCalled),
+ lambda: self.assert_(self.__state2StartCallbackCalled),
+ lambda: self.assert_(self.__stop1Start2CallbackOrder),
+ lambda: self.assertEqual(self.anim.getState(), "STATE3"),
+ lambda: self.compareImage("testStateAnimC4"),
+ lambda: self.anim.setState("STATE1"),
+ lambda: self.assertEqual(avg.getNumRunningAnims(), 1),
+ lambda: self.compareImage("testStateAnimC5"),
+ killAnim,
+# lambda: player.getTestHelper().dumpObjects()
+ ))
+
+ def testNonNodeAttrAnim(self):
+ class GenericClass(object):
+ def __init__(self):
+ self.numberValue = 0
+ self.pointValue = avg.Point2D(0.0, 0.0)
+
+ def on1Stop():
+ self.__onStopCalled = True
+
+ def on2Start():
+ self.__onStopBeforeOnStart = self.__onStopCalled
+
+ self.loadEmptyScene()
+ player.setFakeFPS(10)
+ genericObject1 = GenericClass()
+ genericObject2 = genericObject1
+ genericObject3 = GenericClass()
+ anim1 = avg.LinearAnim(genericObject1, "numberValue", 1000, 0, 100,
+ False, None, on1Stop)
+ anim2 = avg.LinearAnim(genericObject2, "numberValue", 1200, 0, 200,
+ False, on2Start)
+ anim3 = avg.LinearAnim(genericObject1, "pointValue", 800, (0, 0), (100, 200))
+ anim4 = avg.LinearAnim(genericObject3, "numberValue", 400, 0, 42)
+ self.__onStopCalled = False
+ self.__onStopBeforeOnStart = False
+ self.start(False,
+ (lambda: anim1.start(),
+ lambda: self.assert_(anim1.isRunning()),
+ lambda: self.assert_(not(self.__onStopCalled)),
+ lambda: anim2.start(),
+ lambda: self.assert_(self.__onStopBeforeOnStart),
+ lambda: self.assert_(not(anim1.isRunning())),
+ lambda: self.assert_(anim2.isRunning()),
+ lambda: self.assertEqual(avg.getNumRunningAnims(), 1),
+ lambda: anim3.start(),
+ lambda: self.assert_(anim2.isRunning()),
+ lambda: self.assert_(anim3.isRunning()),
+ lambda: self.assertEqual(avg.getNumRunningAnims(), 2),
+ lambda: anim4.start(),
+ lambda: self.assert_(anim4.isRunning()),
+ lambda: self.assertEqual(avg.getNumRunningAnims(), 3),
+ lambda: self.delay(200),
+ lambda: self.assertEqual(avg.getNumRunningAnims(), 0),
+ lambda: self.assert_(genericObject1.numberValue == 200),
+ lambda: self.assert_(genericObject2.pointValue == (100, 200)),
+ lambda: self.assert_(genericObject3.numberValue == 42)
+ ))
+ anim1 = None
+ anim2 = None
+ anim3 = None
+ anim4 = None
+ genericObject1 = None
+ genericObject2 = None
+ genericObject3 = None
+
+
+ def _testPointAnim(self, startPos, endPos, keepAttrPos, startPosImgSrc, endPosImgSrc,
+ keepAttrPosImgSrc):
+ def startAnim():
+ self.__anim.start()
+
+ def startKeepAttr():
+ self.__node.pos = keepAttrPos
+ self.__anim.start(True)
+
+ self.initScene()
+ self.__anim = avg.LinearAnim(self.__node, "pos", 200, avg.Point2D(startPos),
+ avg.Point2D(endPos), False)
+ self.start(False,
+ (startAnim,
+ lambda: self.compareImage(startPosImgSrc),
+ lambda: self.compareImage(endPosImgSrc),
+ None,
+ lambda: self.assert_(not(self.__anim.isRunning())),
+ startKeepAttr,
+ lambda: self.compareImage(keepAttrPosImgSrc),
+ ))
+
+
+def animTestSuite(tests):
+ availableTests = (
+ "testLinearAnim",
+ "testAnimRegistry",
+ "testFadeIn",
+ "testFadeOut",
+ "testNonExistentAttributeAnim",
+ "testLinearAnimZeroDuration",
+ "testPingPongStopAnim",
+ "testPointAnim",
+ "testXPosPointAnim",
+ "testYPosPointAnim",
+ "testEaseInOutAnim",
+ "testIntAnim",
+ "testContinuousAnim",
+ "testWaitAnim",
+ "testParallelAnim",
+ "testParallelAnimRegistry",
+ "testStateAnim",
+ "testNonNodeAttrAnim"
+ )
+ return createAVGTestSuite(availableTests, AnimTestCase, tests)
+
diff --git a/src/test/AppTest.py b/src/test/AppTest.py
new file mode 100644
index 0000000..e3b5463
--- /dev/null
+++ b/src/test/AppTest.py
@@ -0,0 +1,299 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# libavg - Media Playback Engine.
+# Copyright (C) 2003-2014 Ulrich von Zadow
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Current versions can be found at www.libavg.de
+#
+# Original author of this file is OXullo Interecans <x at brainrapers dot org>
+
+
+import os
+import sys
+import tempfile
+import libavg
+from libavg import player
+from libavg.app import settings
+from libavg.app import keyboardmanager
+from libavg.app.settings import Option
+import testcase
+
+
+class TestApp(libavg.app.App):
+ CUSTOM_SETTINGS = {'app_resolution': '160x120', 'app_window_size': '160x120'}
+
+ def testRun(self, onFrameHandlersList=[], mainDiv=None, runtimeOptions={}):
+ assert type(onFrameHandlersList) == list
+ self.__onFrameHandlersList = onFrameHandlersList
+ player.subscribe(player.ON_FRAME, self.__onFrame)
+ player.setFramerate(10000)
+ player.assumePixelsPerMM(1)
+ for k, v in self.CUSTOM_SETTINGS.iteritems():
+ self.settings.set(k, v)
+
+ if mainDiv is None:
+ mainDiv = libavg.app.MainDiv()
+
+ self.run(mainDiv, **runtimeOptions)
+
+ def __onFrame(self):
+ if self.__onFrameHandlersList:
+ todo = self.__onFrameHandlersList.pop(0)
+ todo()
+ else:
+ player.stop()
+
+
+class AppTestCase(testcase.AVGTestCase):
+ def testSettingsOptions(self):
+ self.assertRaises(ValueError, lambda: settings.Option('test', 1))
+
+ self.assertRaises(RuntimeError, lambda: settings.Settings(
+ [Option('foo', 'bar'), Option('foo', 'bar')]))
+
+ s = settings.Settings([Option('foo', 'bar')])
+ self.assertRaises(RuntimeError, lambda: s.addOption(Option('foo', 'baz')))
+
+ def testSettingsTypes(self):
+ defaults = [
+ Option('test_boolean', 'True', 'help'),
+ Option('test_string', 'string'),
+ Option('another_value_int', '1234'),
+ Option('test_2d', '1280x1024'),
+ Option('test_2d_alt','1280,1024'),
+ Option('test_float','12.345'),
+ Option('test_json','[1, null,3 , "string", 12.345]')
+ ]
+
+ s = settings.Settings(defaults)
+
+ self.assertEquals(s.getBoolean('test_boolean'), True)
+
+ self.assertEquals(type(s.get('test_string')), str)
+ self.assertRaises(ValueError, lambda: s.getBoolean('test_string'))
+
+ self.assertEquals(s.getInt('another_value_int'), 1234)
+ self.assertRaises(ValueError, lambda: s.getInt('test_string'))
+ self.assertEquals(s.get('another_value_int'), '1234')
+
+ self.assertEquals(s.getPoint2D('test_2d'), libavg.Point2D(1280, 1024))
+ self.assertEquals(s.getPoint2D('test_2d_alt'), libavg.Point2D(1280, 1024))
+ self.assertRaises(ValueError, lambda: s.getInt('test_2d'))
+
+ self.assertEquals(s.getFloat('test_float'), 12.345)
+
+ self.assertEquals(s.getJson('test_json'), [1, None, 3, 'string', 12.345])
+
+ def testSettingsSet(self):
+ s = settings.Settings()
+ s.addOption(Option('test_value', ''))
+ self.assertRaises(ValueError, lambda: s.set('test_value', 1234))
+
+ s.set('test_value', '1234')
+ self.assertEquals(s.getInt('test_value'), 1234)
+
+ def testSettingsHasOption(self):
+ s = settings.Settings()
+ s.addOption(Option('test_value', ''))
+ self.assertEquals(s.hasOption('test_value'), True)
+ self.assertEquals(s.hasOption('test_value_foo'), False)
+
+ def testSettingsArgvExtender(self):
+ s = settings.Settings([Option('foo_bar', 'bar')])
+ e = settings.ArgvExtender('', args=['foo', '--foo-bar', 'baz', '-c', 'baz2'])
+ e.parser.add_option('-c')
+ s.applyExtender(e)
+ self.assertEquals(s.get('foo_bar'), 'baz')
+ self.assertEquals(e.parsedArgs[0].c, 'baz2')
+ self.assertEquals(e.parsedArgs[1], ['foo'])
+
+ e = settings.ArgvExtender('', args=['foo', '--foo-baxxx', 'baz'])
+ with testcase.SuppressOutput():
+ self.assertRaises(SystemExit, lambda: s.applyExtender(e))
+
+ def testSettingsKargsExtender(self):
+ s = settings.Settings([Option('foo_bar', 'bar')])
+ e = settings.KargsExtender({'foo_bar': 'baz'})
+ s.applyExtender(e)
+ self.assertEquals(s.get('foo_bar'), 'baz')
+
+ e = settings.KargsExtender({'foo_baxxx': 'baz'})
+ self.assertRaises(RuntimeError, lambda: s.applyExtender(e))
+
+ def testAppAdditionalSettings(self):
+ app = TestApp()
+ app.settings.addOption(Option('foo_bar', 'baz'))
+ app.settings.addOption(Option('bar_foo', 'baz'))
+ self.assertEquals(app.settings.get('foo_bar'), 'baz')
+
+ def testAppRuntimeSettings(self):
+ app = TestApp()
+ app.settings.addOption(Option('foo_bar', 'baz'))
+ app.testRun([
+ lambda: self.assertEquals(libavg.app.instance.settings.get('foo_bar'),
+ 'bar'),
+ ],
+ runtimeOptions={'foo_bar':'bar'})
+
+ def testAppRuntimeSettingsFail(self):
+ app = TestApp()
+ self.assertRaises(RuntimeError,
+ lambda: app.testRun(runtimeOptions={'foo_bar':'bar'}))
+
+ def testAppInstance(self):
+ app = TestApp()
+ self.assertEquals(app, libavg.app.instance)
+
+ def testAppResolution(self):
+ app = TestApp()
+ app.testRun([
+ lambda: self.assertEquals(player.getRootNode().size, (160, 120)),
+ lambda: self.assert_(not player.isFullscreen()),
+ ])
+
+ def testAppDefaultWindowSize(self):
+ app = TestApp()
+ app.CUSTOM_SETTINGS = {'app_resolution': '160x120'}
+ app.testRun()
+
+ def testAppFullscreen(self):
+ app = TestApp()
+ app.settings.set('app_fullscreen', 'true')
+ app.testRun([
+ lambda: self.assert_(player.isFullscreen()),
+ ])
+
+ def testAppRotation(self):
+ app = TestApp()
+ app.settings.set('app_rotation', 'left')
+ app.testRun([
+ lambda: self.assertEquals(player.getRootNode().size, (120, 160)),
+ ])
+
+ def testScreenshot(self):
+ tempDir = tempfile.gettempdir()
+ expectedFiles = map(lambda v: os.path.join(tempDir, v),
+ ['TestApp-001.png', 'TestApp-002.png'])
+
+ def removeFiles():
+ for file in expectedFiles:
+ if os.path.exists(file):
+ os.unlink(file)
+
+ def testScreenshots():
+ for file in expectedFiles:
+ self.assert_(os.path.exists(file))
+
+ removeFiles()
+ app = TestApp()
+ app.testRun([
+ lambda: app.takeScreenshot(tempDir),
+ lambda: app.takeScreenshot(tempDir),
+ testScreenshots,
+ removeFiles,
+ ])
+
+ def testKeyboardManagerPlain(self):
+ tester = lambda: self.__emuKeyPress(0, 97, 'a', 97, libavg.avg.KEYMOD_NONE)
+ self.__testKeyboardManager('a', libavg.avg.KEYMOD_NONE, tester)
+
+ def testKeyboardManagerPlainMod(self):
+ tester = lambda: self.__emuKeyPress(0, 97, 'a', 97, libavg.avg.KEYMOD_LSHIFT)
+ self.__testKeyboardManager('a', libavg.avg.KEYMOD_SHIFT, tester)
+
+ def testKeyboardManagerUnicodeBinary(self):
+ tester = lambda: self.__emuKeyPress(53, 164, 'ö', 246, libavg.avg.KEYMOD_NONE)
+ self.__testKeyboardManager('ö', libavg.avg.KEYMOD_NONE, tester)
+
+ def testKeyboardManagerUnicodeExplicit(self):
+ tester = lambda: self.__emuKeyPress(53, 164, 'ö', 246, libavg.avg.KEYMOD_NONE)
+ self.__testKeyboardManager(u'ö', libavg.avg.KEYMOD_NONE, tester)
+
+ def testKeyboardManagerUnicodeMod(self):
+ tester = lambda: self.__emuKeyPress(0, 65, 'A', 65, libavg.avg.KEYMOD_LSHIFT)
+ self.__testKeyboardManager(u'A', keyboardmanager.KEYMOD_ANY, tester)
+ self.tearDown()
+ self.__testKeyboardManager(u'A', libavg.avg.KEYMOD_SHIFT, tester)
+
+ def tearDown(self):
+ libavg.app.instance = None
+
+ def __testKeyboardManager(self, keyString, modifiers, tester):
+ self.statesRecords = [False, False]
+ def keyDownPressed():
+ self.statesRecords[0] = True
+
+ def keyUpPressed():
+ self.statesRecords[1] = True
+
+ def bindKeys():
+ keyboardmanager.bindKeyDown(keyString, keyDownPressed, '', modifiers)
+ keyboardmanager.bindKeyUp(keyString, keyUpPressed, '', modifiers)
+
+ def reset():
+ keyboardmanager.unbindKeyDown(keyString, modifiers)
+ keyboardmanager.unbindKeyUp(keyString, modifiers)
+ self.statesRecords = [False, False]
+
+ def cleanup():
+ del self.statesRecords
+
+ app = TestApp()
+ app.testRun([
+ bindKeys,
+ tester,
+ lambda: self.assert_(all(self.statesRecords)),
+ reset,
+ tester,
+ lambda: self.assert_(not any(self.statesRecords)),
+ cleanup,
+ ])
+
+ def __emuKeyPress(self, scanCode, keyCode, keyString, unicode_, modifiers):
+ helper = libavg.player.getTestHelper()
+ helper.fakeKeyEvent(libavg.avg.Event.KEY_DOWN, scanCode, keyCode, keyString,
+ unicode_, modifiers)
+ # Note: on up, unicode is always 0
+ helper.fakeKeyEvent(libavg.avg.Event.KEY_UP, scanCode, keyCode, keyString,
+ 0, modifiers)
+
+
+def appTestSuite(tests):
+ availableTests = (
+ 'testSettingsOptions',
+ 'testSettingsTypes',
+ 'testSettingsSet',
+ 'testSettingsHasOption',
+ 'testSettingsArgvExtender',
+ 'testSettingsKargsExtender',
+ 'testAppAdditionalSettings',
+ 'testAppRuntimeSettings',
+ 'testAppRuntimeSettingsFail',
+ 'testAppInstance',
+ 'testAppResolution',
+ 'testAppDefaultWindowSize',
+ 'testAppFullscreen',
+ 'testAppRotation',
+ 'testScreenshot',
+ 'testKeyboardManagerPlain',
+ 'testKeyboardManagerPlainMod',
+ 'testKeyboardManagerUnicodeBinary',
+ 'testKeyboardManagerUnicodeExplicit',
+ 'testKeyboardManagerUnicodeMod',
+ )
+ return testcase.createAVGTestSuite(availableTests, AppTestCase, tests)
+
diff --git a/src/test/DynamicsTest.py b/src/test/DynamicsTest.py
new file mode 100644
index 0000000..522c2f0
--- /dev/null
+++ b/src/test/DynamicsTest.py
@@ -0,0 +1,380 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# libavg - Media Playback Engine.
+# Copyright (C) 2003-2014 Ulrich von Zadow
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Current versions can be found at www.libavg.de
+#
+
+from libavg import avg, player
+from testcase import *
+
+class DynamicsTestCase(AVGTestCase):
+ def __init__(self, testFuncName):
+ AVGTestCase.__init__(self, testFuncName)
+
+ def __runDynamicsTest(self, createFunc, testName, isVideo = False,
+ warnOnImageDiff = False):
+
+ def createNode1(useXml):
+
+ def setNodeID():
+ node.id = "bork"
+
+ node = createFunc(useXml)
+ node.id = "nodeid1"
+ node.x = 10
+ node.y = 20
+ self.root.appendChild(node)
+ self.assertException(setNodeID)
+ self.assertEqual(self.root.indexOf(player.getElementByID("nodeid1")), 0)
+ self.assertException(lambda: self.root.indexOf(self.root))
+
+ def createNode2(useXml):
+ node = createFunc(useXml)
+ node.id = "nodeid2"
+ oldNode = player.getElementByID("nodeid1")
+ self.root.insertChildBefore(node, oldNode)
+
+ def reorderNode():
+ self.root.reorderChild(0, 1)
+ node = player.getElementByID("nodeid1")
+ self.root.reorderChild(node, 0)
+
+ def removeNodes():
+ self.node = player.getElementByID("nodeid1")
+ self.root.removeChild(self.root.indexOf(self.node))
+ node2 = player.getElementByID("nodeid2")
+ self.root.removeChild(node2)
+ self.assertEqual(player.getElementByID("nodeid1"), None)
+
+ def reAddNode():
+ self.root.appendChild(self.node)
+ if isVideo:
+ self.node.play()
+ self.node = None
+
+ def killNode():
+ self.node = player.getElementByID("nodeid1")
+ self.node.unlink(True)
+ gone = player.getElementByID("nodeid1")
+ self.assertEqual(gone, None)
+
+ def removeAgain():
+ node = player.getElementByID("nodeid1")
+ node.unlink()
+ gone = player.getElementByID("nodeid1")
+ self.assertEqual(gone, None)
+
+ def runTest(useXml):
+ self.root = self.loadEmptyScene()
+ createNode1(useXml)
+ player.stop()
+ self.root = self.loadEmptyScene()
+ player.setFakeFPS(25)
+ self.start(warnOnImageDiff,
+ (lambda: createNode1(useXml),
+ lambda: self.compareImage(testName+"1"),
+ lambda: createNode2(useXml),
+ lambda: self.compareImage(testName+"2"),
+ reorderNode,
+ lambda: self.compareImage(testName+"3"),
+ removeNodes,
+ lambda: self.compareImage(testName+"4"),
+ reAddNode,
+ lambda: self.compareImage(testName+"5"),
+ killNode,
+ reAddNode,
+ removeAgain
+ ))
+
+ runTest(True)
+ runTest(False)
+
+ def testImgDynamics(self):
+ def createImg(useXml):
+ if useXml:
+ node = player.createNode("<image href='rgb24-64x64.png'/>")
+ else:
+ node = player.createNode("image", {"href":"rgb24-64x64.png"})
+ return node
+
+ self.__runDynamicsTest(createImg, "testImgDynamics")
+
+ def testVideoDynamics(self):
+ def createVideo(useXml):
+ if useXml:
+ node = player.createNode(
+ "<video href='mpeg1-48x48.mov' threaded='false'/>")
+ else:
+ node = player.createNode("video",
+ {"href":"mpeg1-48x48.mov", "threaded":False})
+ node.play()
+ return node
+
+ self.__runDynamicsTest(createVideo, "testVideoDynamics", True)
+
+ def testWordsDynamics(self):
+ def createWords(useXml):
+ if useXml:
+ node = player.createNode("<words text='test'/>")
+ else:
+ node = player.createNode("words", {"text":"test"})
+ node.font="Bitstream Vera Sans"
+ node.fontsize=12
+ node.width=200
+ return node
+
+ self.__runDynamicsTest(createWords, "testWordsDynamics", False, True)
+
+ def testDivDynamics(self):
+ def createDiv(useXml):
+ if useXml:
+ node = player.createNode("""
+ <div>
+ <image href='rgb24-64x64.png'/>
+ </div>
+ """)
+ else:
+ node = avg.DivNode()
+ avg.ImageNode(href="rgb24-64x64.png", parent=node)
+ return node
+
+ self.__runDynamicsTest(createDiv, "testDivDynamics")
+
+ def testDuplicateID(self):
+ root = self.loadEmptyScene()
+ avg.ImageNode(href="rgb24-64x64.png", id="testdup", parent=root)
+ self.assertException(lambda: avg.ImageNode(href="rgb24-64x64.png",
+ id="testdup", parent=root))
+ self.start(False,
+ (self.assertException(lambda: avg.ImageNode(href="rgb24-64x64.png",
+ id="testdup", parent=root)),
+ ))
+
+ def testChangeParentError(self):
+ def changeParent():
+ div = avg.DivNode()
+ img = avg.ImageNode(href="additive/rgb24-64x64.png", parent=div)
+ root.appendChild(img)
+
+ root = self.loadEmptyScene()
+ self.assertException(changeParent)
+ self.start(False, (self.assertException(changeParent),))
+
+ def testDynamicEventCapture(self):
+ # Tests if deleting a node that has events captured works.
+ def createImg():
+ parentNode = root
+ node = player.createNode("image", {"id": "img", "href":"rgb24-64x64.png"})
+ parentNode.appendChild(node)
+ node.subscribe(avg.Node.CURSOR_DOWN, captureMouseDown)
+ parentNode.subscribe(avg.Node.CURSOR_UP, mainMouseUp)
+
+ def setEventCapture():
+ player.getElementByID("img").setEventCapture()
+
+ def deleteImg():
+ parentNode = root
+ node = player.getElementByID("img")
+ parentNode.removeChild(parentNode.indexOf(node))
+
+ def captureMouseDown(event):
+ self.captureMouseDownCalled = True
+
+ def mainMouseUp(event):
+ self.mainMouseUpCalled = True
+
+ self.captureMouseDownCalled = False
+ self.mainMouseUpCalled = False
+ root = self.loadEmptyScene()
+ self.start(False,
+ (createImg,
+ setEventCapture,
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 100, 10),
+ lambda: self.assert_(self.captureMouseDownCalled),
+ deleteImg,
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_UP, 100, 10),
+ lambda: self.assert_(self.mainMouseUpCalled)
+ ))
+
+ def testEventBubbling(self):
+ def click (x, y):
+ self.fakeClick(x, y)
+
+ def createNodes():
+ def appendEventString (s):
+ self.__eventString += s
+ return True
+
+ def setHandler (node, s, swallow = False):
+ node.setEventHandler(avg.Event.CURSOR_DOWN, avg.Event.MOUSE,
+ lambda e: appendEventString(s) and swallow)
+
+ parentNode = root
+ node = player.createNode("div", {'x':0,'y':0,'width':50, 'height':50})
+ setHandler (node, 'a')
+ parentNode.appendChild(node)
+ node = player.createNode("div", {'x':0,'y':0,'width':100, 'height':100})
+ setHandler (node, 'b')
+ parentNode.insertChild(node,0)
+ parentNode = node
+ node = player.createNode("div", {'x':40,'y':40,'width':30, 'height':30})
+ setHandler (node, 'c')
+ parentNode.appendChild(node)
+ node = player.createNode("div", {'x':60,'y':40,'width':30, 'height':30})
+ setHandler (node, 'd', True)
+ parentNode.appendChild(node)
+
+ def resetEventString():
+ self.__eventString = ''
+
+ root = self.loadEmptyScene()
+ self.start(False,
+ (createNodes,
+ resetEventString,
+ lambda: click (10,10),
+ lambda: self.assertEqual(self.__eventString, 'a'),
+ resetEventString,
+ lambda: click (55,55),
+ lambda: self.assertEqual(self.__eventString, 'cb'),
+ resetEventString,
+ lambda: click (65,55),
+ lambda: self.assertEqual(self.__eventString, 'd'),
+ ))
+
+ def testComplexDiv(self):
+ def setImageID(imgNode):
+ imgNode.id = "imageid"
+
+ def createDiv():
+ imgNode = player.createNode("image",
+ {"id":"imageid", "href":"rgb24-64x64.png"})
+ node = player.createNode("div", {"id":"divid"})
+ node.appendChild(imgNode)
+ imgNode.id = "imageid"
+ root.appendChild(node)
+ self.assertException(lambda: setImageID(imgNode))
+
+ def removeDiv():
+ node = player.getElementByID("divid")
+ imgNode = player.getElementByID("imageid")
+ node.unlink()
+ imgNode.id = "imageid"
+ imgNode.unlink()
+ root.appendChild(node)
+ node.appendChild(imgNode)
+ self.assertException(lambda: setImageID(imgNode))
+
+ root = self.loadEmptyScene()
+ createDiv()
+ removeDiv()
+ player.stop()
+ root = self.loadEmptyScene()
+ player.setFakeFPS(25)
+ self.start(False,
+ (createDiv,
+ lambda: self.compareImage("testComplexDiv1"),
+ removeDiv,
+ lambda: self.compareImage("testComplexDiv1"),
+ ))
+
+ def testNodeCustomization(self):
+ def testNodePythonAttribute():
+ node1 = player.createNode("image", {"id":"foo", "pos":(23, 42)})
+ root.appendChild(node1)
+ node1.customAttribute = "bbb"
+ node2 = player.getElementByID("foo")
+ self.assertEqual(node1, node2)
+ self.assertEqual(node2.customAttribute, "bbb")
+ node1.unlink(True)
+
+ def testNodePythonSubclass():
+
+ class CustomImageNode(avg.ImageNode):
+ def __init__(self, p, parent=None, **kwargs):
+ avg.ImageNode.__init__(self, pos=p, href="rgb24-64x64.png", **kwargs)
+ self.registerInstance(self, parent)
+
+ def customMethod(self):
+ pass
+
+ class CustomDivNode(avg.DivNode):
+ def __init__(self, parent=None, **kwargs):
+ avg.DivNode.__init__(self, **kwargs)
+ self.registerInstance(self, parent)
+ CustomImageNode((23,42), parent=self)
+
+
+ customNode = CustomImageNode((23, 42), parent=root)
+ retrievedImage = root.getChild(0)
+ self.assertEqual(type(retrievedImage), CustomImageNode)
+ self.assertEqual(retrievedImage.pos, (23,42))
+ self.assertEqual(retrievedImage.href, "rgb24-64x64.png")
+ retrievedImage.customMethod()
+ customNode.unlink(True)
+
+ CustomDivNode(parent=player.getRootNode())
+ retrievedDiv = player.getRootNode().getChild(0)
+ self.assertEqual(type(retrievedDiv), CustomDivNode)
+ retrievedImage = retrievedDiv.getChild(0)
+ self.assertEqual(type(retrievedImage), CustomImageNode)
+ retrievedDiv = retrievedImage.parent
+ self.assertEqual(type(retrievedDiv), CustomDivNode)
+ retrievedDiv.unlink(True)
+
+ customNode = CustomImageNode((23,42))
+ root.appendChild(customNode)
+ retrievedImage = root.getChild(0)
+ self.assertEqual(type(retrievedImage), CustomImageNode)
+
+ root = self.loadEmptyScene()
+ testNodePythonAttribute()
+ testNodePythonSubclass()
+
+ def testDynamicMediaDir(self):
+ def attachNode():
+ root.appendChild(imageNode1)
+
+ root = self.loadEmptyScene()
+ root.mediadir="testmediadir"
+ imageNode1 = player.createNode("image", {"href": "rgb24-64x64a.png"})
+ imageNode2 = player.createNode("image", {"href": "rgb24-64x64a.png", "x":30})
+ root.appendChild(imageNode2)
+ self.start(False,
+ (lambda: self.compareImage("testDynamicMediaDir1"),
+ attachNode,
+ lambda: self.compareImage("testDynamicMediaDir2")
+ ))
+
+
+def dynamicsTestSuite(tests):
+ availableTests = (
+ "testImgDynamics",
+ "testVideoDynamics",
+ "testWordsDynamics",
+ "testDivDynamics",
+ "testEventBubbling",
+ "testDuplicateID",
+ "testChangeParentError",
+ "testDynamicEventCapture",
+ "testComplexDiv",
+ "testNodeCustomization",
+ "testDynamicMediaDir",
+ )
+
+ return createAVGTestSuite(availableTests, DynamicsTestCase, tests)
diff --git a/src/test/EventTest.py b/src/test/EventTest.py
new file mode 100644
index 0000000..afdfe94
--- /dev/null
+++ b/src/test/EventTest.py
@@ -0,0 +1,1086 @@
+# -*- coding: utf-8 -*-
+# libavg - Media Playback Engine.
+# Copyright (C) 2003-2014 Ulrich von Zadow
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Current versions can be found at www.libavg.de
+#
+
+from libavg import avg, player
+from testcase import *
+
+def dumpMouseEvent(Event):
+ print Event
+ print " type: "+str(Event.type)
+ print " leftbuttonstate: "+str(Event.leftbuttonstate)
+ print " middlebuttonstate: "+str(Event.middlebuttonstate)
+ print " rightbuttonstate: "+str(Event.rightbuttonstate)
+ print " position: "+str(Event.x)+","+str(Event.y)
+ print " node: "+Event.node.id
+
+mainMouseUpCalled = False
+mainMouseDownCalled = False
+
+def mainMouseUp(Event):
+ global mainMouseUpCalled
+ assert (Event.type == avg.Event.CURSOR_UP)
+ mainMouseUpCalled = True
+
+def mainMouseDown(Event):
+ global mainMouseDownCalled
+ assert (Event.type == avg.Event.CURSOR_DOWN)
+ mainMouseDownCalled = True
+
+
+class EventTestCase(AVGTestCase):
+ def __init__(self, testFuncName):
+ AVGTestCase.__init__(self, testFuncName)
+
+ def testKeyEvents(self):
+ def onKeyDown(event):
+ if event.keystring == 'A' and event.keycode == 65 and event.unicode == 65:
+ self.keyDownCalled = True
+
+ def onKeyUp(event):
+ if event.keystring == 'A' and event.keycode == 65 and event.unicode == 65:
+ self.keyUpCalled = True
+
+ def onSubscribeKeyDown(event):
+ self.subscribeKeyDownCalled = True
+
+ def onSubscribeKeyUp(event):
+ self.subscribeKeyUpCalled = True
+
+ root = self.loadEmptyScene()
+ root.setEventHandler(avg.Event.KEY_DOWN, avg.Event.NONE, onKeyDown)
+ root.setEventHandler(avg.Event.KEY_UP, avg.Event.NONE, onKeyUp)
+ player.subscribe(avg.Player.KEY_DOWN, onSubscribeKeyDown)
+ player.subscribe(avg.Player.KEY_UP, onSubscribeKeyUp)
+ self.start(False,
+ (lambda: Helper.fakeKeyEvent(avg.Event.KEY_DOWN, 65, 65, "A", 65,
+ avg.KEYMOD_NONE),
+ lambda: self.assert_(self.keyDownCalled and self.subscribeKeyDownCalled),
+ lambda: Helper.fakeKeyEvent(avg.Event.KEY_UP, 65, 65, "A", 65,
+ avg.KEYMOD_NONE),
+ lambda: self.assert_(self.keyUpCalled and self.subscribeKeyUpCalled)
+ ))
+
+ def testSimpleEvents(self):
+ def getMouseState():
+ Event = player.getMouseState()
+ self.assertEqual(Event.pos, avg.Point2D(10,10))
+
+ root = self.loadEmptyScene()
+ img1 = avg.ImageNode(pos=(0,0), href="rgb24-65x65.png", parent=root)
+ handlerTester1 = NodeHandlerTester(self, img1)
+
+ img2 = avg.ImageNode(pos=(64,0), href="rgb24-65x65.png", parent=root)
+ handlerTester2 = NodeHandlerTester(self, img2)
+
+ self.start(False,
+ (# down, getMouseState(), move, up.
+ # events are inside img1 but outside img2.
+ lambda: self.assert_(not(player.isMultitouchAvailable())),
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 10, 10),
+ lambda: handlerTester1.assertState(
+ (avg.Node.CURSOR_DOWN, avg.Node.CURSOR_OVER)),
+ lambda: handlerTester2.assertState(()),
+ getMouseState,
+
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_MOTION, 12, 12),
+ lambda: handlerTester1.assertState((avg.Node.CURSOR_MOTION,)),
+
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_UP, 12, 12),
+ lambda: handlerTester1.assertState((avg.Node.CURSOR_UP,))
+
+ ))
+
+ def testTilted(self):
+ root = self.loadEmptyScene()
+ img = avg.ImageNode(pos=(0,0), href="rgb24-65x65.png", angle=0.785, parent=root)
+ handlerTester = NodeHandlerTester(self, img)
+
+ self.start(False,
+ (lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 32, 32),
+ lambda: handlerTester.assertState(
+ (avg.Node.CURSOR_DOWN, avg.Node.CURSOR_OVER)),
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_UP, 0, 0),
+ lambda: handlerTester.assertState((avg.Node.CURSOR_OUT,)),
+ ))
+
+ def testWordsClicks(self):
+ root = self.loadEmptyScene()
+ words = avg.WordsNode(pos=(40,40), alignment="right", text="test", parent=root)
+ handlerTester = NodeHandlerTester(self, words)
+ self.start(False,
+ (lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 45, 45),
+ lambda: handlerTester.assertState(()),
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_UP, 35, 45),
+ lambda: handlerTester.assertState(
+ (avg.Node.CURSOR_UP, avg.Node.CURSOR_OVER)),
+ ))
+
+ def testDivEvents(self):
+ root = self.loadEmptyScene()
+ div = avg.DivNode(pos=(0,0), parent=root)
+ divHandlerTester = NodeHandlerTester(self, div)
+
+ img = avg.ImageNode(pos=(0,0), href="rgb24-65x65.png", parent=div)
+ imgHandlerTester = NodeHandlerTester(self, img)
+
+ self.start(False,
+ (# down, move, up.
+ # events are inside img and therefore should bubble to div.
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 10, 10),
+ lambda: divHandlerTester.assertState(
+ (avg.Node.CURSOR_DOWN, avg.Node.CURSOR_OVER)),
+ lambda: imgHandlerTester.assertState(
+ (avg.Node.CURSOR_DOWN, avg.Node.CURSOR_OVER)),
+
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_MOTION, 12, 12),
+ lambda: divHandlerTester.assertState((avg.Node.CURSOR_MOTION,)),
+ lambda: imgHandlerTester.assertState((avg.Node.CURSOR_MOTION,)),
+
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_UP, 12, 12),
+ lambda: divHandlerTester.assertState((avg.Node.CURSOR_UP,)),
+ lambda: imgHandlerTester.assertState((avg.Node.CURSOR_UP,))
+ ))
+
+ def testDivNegativePos(self):
+ root = self.loadEmptyScene()
+ div = avg.DivNode(pos=(10,10), parent=root)
+ divHandlerTester = NodeHandlerTester(self, div)
+
+ img = avg.ImageNode(pos=(-10,-10), href="rgb24-65x65.png", parent=div)
+ imgHandlerTester = NodeHandlerTester(self, img)
+
+ self.start(False,
+ (lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 1, 1),
+ lambda: divHandlerTester.assertState(
+ (avg.Node.CURSOR_DOWN, avg.Node.CURSOR_OVER)),
+ lambda: imgHandlerTester.assertState(
+ (avg.Node.CURSOR_DOWN, avg.Node.CURSOR_OVER)),
+ ))
+
+ def testUnlinkInHandler(self):
+ def onImgDown(event):
+ self.__imgDownCalled = True
+ self.div.unlink(True)
+
+ def onDivDown(event):
+ self.__divDownCalled = True
+
+ def checkState():
+ self.assert_(self.__imgDownCalled and not(self.__divDownCalled))
+
+ self.__imgDownCalled = False
+ self.__divDownCalled = False
+ root = self.loadEmptyScene()
+ self.div = avg.DivNode(pos=(0,0), parent=root)
+ self.div.connectEventHandler(avg.Event.CURSOR_DOWN, avg.Event.MOUSE, self,
+ onDivDown)
+
+ img = avg.ImageNode(pos=(0,0), href="rgb24-65x65.png", parent=self.div)
+ img.connectEventHandler(avg.Event.CURSOR_DOWN, avg.Event.MOUSE, self, onImgDown)
+
+ self.start(False,
+ (lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 10, 10),
+ checkState))
+
+
+ def testConnectHandler(self):
+ def onDown1(event):
+ self.down1Called = True
+
+ def onDown2(event):
+ self.down2Called = True
+
+ def resetDownCalled():
+ self.down1Called = False
+ self.down2Called = False
+
+ def connectTwoHandlers():
+ self.img.connectEventHandler(avg.Event.CURSOR_DOWN, avg.Event.MOUSE, self,
+ onDown1)
+ self.img.connectEventHandler(avg.Event.CURSOR_DOWN, avg.Event.MOUSE, self,
+ onDown2)
+
+ def connectUnlinkHandler():
+ self.img.disconnectEventHandler(self)
+ self.img.connectEventHandler(avg.Event.CURSOR_DOWN, avg.Event.MOUSE, self,
+ unlinkHandler)
+ self.img.connectEventHandler(avg.Event.CURSOR_DOWN, avg.Event.MOUSE, self,
+ onDown2)
+
+ def unlinkHandler(event):
+ self.img.disconnectEventHandler(self)
+
+ root = self.loadEmptyScene()
+ self.img = avg.ImageNode(pos=(0,0), href="rgb24-65x65.png", parent=root)
+ connectTwoHandlers()
+ self.img.disconnectEventHandler(self, onDown1)
+ self.img.disconnectEventHandler(self, onDown2)
+ connectTwoHandlers()
+ self.img.disconnectEventHandler(self)
+
+ resetDownCalled()
+ self.start(False,
+ (connectTwoHandlers,
+ lambda: self.fakeClick(10,10),
+ lambda: self.assert_(self.down1Called and self.down2Called),
+ resetDownCalled,
+ lambda: self.img.disconnectEventHandler(self, onDown1),
+ lambda: self.fakeClick(10,10),
+ lambda: self.assert_(not(self.down1Called) and self.down2Called),
+ connectUnlinkHandler,
+ lambda: self.fakeClick(10,10),
+ ))
+
+ def testPublisher(self):
+ def onDown(event):
+ self.assert_(event.type == avg.Event.CURSOR_DOWN)
+ curEvent = player.getCurrentEvent()
+ self.assert_(curEvent.type == avg.Event.CURSOR_DOWN)
+ self.assert_(curEvent.when == event.when)
+ self.downCalled = True
+
+ def unsubscribe():
+ self.assert_(self.img.isSubscribed(avg.Node.CURSOR_DOWN, onDown))
+ self.img.unsubscribe(avg.Node.CURSOR_DOWN, onDown)
+ self.assert_(not(self.img.isSubscribed(avg.Node.CURSOR_DOWN, onDown)))
+ self.assert_(self.img.getNumSubscribers(avg.Node.CURSOR_DOWN) == 0)
+ self.downCalled = False
+ self.assertException(
+ lambda: self.img.unsubscribe(avg.Node.CURSOR_DOWN, onDown))
+
+ def initUnsubscribeInEvent(useMessageID):
+ self.subscriberID = self.img.subscribe(avg.Node.CURSOR_DOWN,
+ lambda event: onDownUnsubscribe(event, useMessageID))
+
+ def onDownUnsubscribe(event, useMessageID):
+ if useMessageID:
+ self.img.unsubscribe(avg.Node.CURSOR_DOWN, self.subscriberID)
+ self.assertException(lambda:
+ self.img.unsubscribe(avg.Node.CURSOR_DOWN, self.subscriberID))
+ else:
+ self.img.unsubscribe(self.subscriberID)
+ self.assertException(lambda: self.img.unsubscribe(self.subscriberID))
+
+ self.downCalled = True
+
+ def onFrame():
+ self.onFrameCalled = True
+
+ self.downCalled = False
+ self.onFrameCalled = False
+ root = self.loadEmptyScene()
+ player.subscribe(player.ON_FRAME, onFrame)
+ self.img = avg.ImageNode(pos=(0,0), href="rgb24-65x65.png", parent=root)
+ self.img.subscribe(avg.Node.CURSOR_DOWN, onDown)
+ self.assertException(lambda: self.img.subscribe(23, onDown))
+ self.assertException(lambda: self.img.unsubscribe(avg.Node.CURSOR_DOWN, 23))
+ self.start(False,
+ (lambda: self.fakeClick(10,10),
+ lambda: self.assert_(self.downCalled),
+ lambda: self.assert_(self.onFrameCalled),
+
+ unsubscribe,
+ lambda: self.fakeClick(10,10),
+ lambda: self.assert_(not(self.downCalled)),
+
+ lambda: initUnsubscribeInEvent(True),
+ lambda: self.fakeClick(10,10),
+ lambda: self.assert_(self.downCalled),
+
+ lambda: initUnsubscribeInEvent(False),
+ lambda: self.fakeClick(10,10),
+ lambda: self.assert_(self.downCalled),
+ ))
+
+ def testComplexPublisher(self):
+ def setupUnsubscribe():
+ self.downCalled = [False, False]
+ self.msgIDs = []
+ for i in range(0,2):
+ self.msgIDs.append(self.img.subscribe(avg.Node.CURSOR_DOWN,
+ lambda event, i=i: onUnsubscribeDown(i)))
+
+ def onUnsubscribeDown(i):
+ self.downCalled[i] = True
+ for j in range(0,2):
+ self.img.unsubscribe(avg.Node.CURSOR_DOWN, self.msgIDs[j])
+
+ def assertCorrectUnsubscribe():
+ # Exactly one of the two callbacks should have been invoked
+ self.assert_(self.downCalled[0] != self.downCalled[1])
+
+ def setupSubscribe():
+ self.downCalled = [False, False]
+ self.msgIDs = []
+ self.msgIDs.append(self.img.subscribe(avg.Node.CURSOR_DOWN,
+ lambda event: onSubscribeDown()))
+
+ def onSubscribeDown():
+ self.downCalled[0] = True
+ self.msgIDs.append(self.img.subscribe(avg.Node.CURSOR_DOWN,
+ lambda event: onSecondSubscribeDown()))
+
+ def onSecondSubscribeDown():
+ self.downCalled[1] = True
+
+ def assertDownsCalled(expectedState):
+ self.assert_(self.downCalled == expectedState)
+
+ root = self.loadEmptyScene()
+ self.img = avg.ImageNode(pos=(0,0), href="rgb24-65x65.png", parent=root)
+
+ self.start(False,
+ (# Subscribe twice to an event, unsubscribe both during processing of the
+ # first. Second shouldn't be called anymore.
+ lambda: setupUnsubscribe(),
+ lambda: self.fakeClick(10,10),
+ assertCorrectUnsubscribe,
+
+ # Subscribe to an event, subscribe again during event processing.
+ # The second one shouldn't be called immediately.
+ lambda: setupSubscribe(),
+ lambda: self.fakeClick(10,10),
+ lambda: assertDownsCalled([True, False]),
+ lambda: self.fakeClick(10,10),
+ lambda: assertDownsCalled([True, True]),
+ ))
+
+ def testPublisherAutoDelete(self):
+
+ class TestSubscriber():
+ def __init__(self):
+ self.__downCalled = False
+
+ def subscribe(self, node):
+ node.subscribe(avg.Node.CURSOR_DOWN, self.onDown)
+
+ def subscribeLambda(self, node):
+ node.subscribe(avg.Node.CURSOR_DOWN, lambda event: self.onDown(event))
+
+ def onDown(self, event):
+ self.__downCalled = True
+
+ def hasClicked(self):
+ return self.__downCalled
+
+ def removeSubscriber():
+ del self.subscriber;
+
+ root = self.loadEmptyScene()
+ self.img = avg.ImageNode(pos=(0,0), href="rgb24-65x65.png", parent=root)
+ self.subscriber = TestSubscriber()
+ self.subscriber.subscribe(self.img)
+ self.start(False,
+ (lambda: self.fakeClick(10,10),
+ lambda: self.assert_(self.subscriber.hasClicked()),
+ removeSubscriber,
+ lambda: self.fakeClick(10,10),
+ lambda: self.assert_(
+ self.img.getNumSubscribers(avg.Node.CURSOR_DOWN) == 0)
+ ))
+
+
+ def testPublisherNestedUnsubscribe(self):
+
+ class TestPublisher(avg.Publisher):
+
+ OUTER_EVENT = avg.Publisher.genMessageID()
+ INNER_EVENT = avg.Publisher.genMessageID()
+
+ def __init__(self):
+ super(TestPublisher, self).__init__()
+ self.publish(TestPublisher.OUTER_EVENT)
+ self.publish(TestPublisher.INNER_EVENT)
+
+ def generateEvent(self):
+ self.notifySubscribers(TestPublisher.OUTER_EVENT, [])
+
+ def generateInnerEvent(self):
+ self.notifySubscribers(TestPublisher.INNER_EVENT, [])
+
+ def onEvent():
+ self.publisher.generateInnerEvent()
+
+ def onEvent2():
+ self.event2Called = True;
+
+ def onInnerEvent():
+ self.publisher.unsubscribe(TestPublisher.OUTER_EVENT, onEvent)
+ self.publisher.unsubscribe(TestPublisher.OUTER_EVENT, onEvent2)
+
+ self.loadEmptyScene()
+ self.publisher = TestPublisher()
+ self.publisher.subscribe(TestPublisher.OUTER_EVENT, onEvent2)
+ self.publisher.subscribe(TestPublisher.OUTER_EVENT, onEvent)
+ self.publisher.subscribe(TestPublisher.INNER_EVENT, onInnerEvent)
+ self.event2Called = False
+ self.start(False,
+ (self.publisher.generateEvent,
+ ))
+ self.assert_(not(self.event2Called))
+
+
+ def testObscuringEvents(self):
+ root = self.loadEmptyScene()
+ img1 = avg.ImageNode(pos=(0,0), href="rgb24-65x65.png", parent=root)
+ handlerTester1 = NodeHandlerTester(self, img1)
+
+ img2 = avg.ImageNode(pos=(0,0), href="rgb24-65x65.png", parent=root)
+ handlerTester2 = NodeHandlerTester(self, img2)
+ self.start(False,
+ (# down, move, up.
+ # events should only arrive at img2 because img1 is obscured by img1.
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 10, 10),
+ lambda: handlerTester1.assertState(()),
+ lambda: handlerTester2.assertState(
+ (avg.Node.CURSOR_DOWN, avg.Node.CURSOR_OVER)),
+
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_MOTION, 12, 12),
+ lambda: handlerTester1.assertState(()),
+ lambda: handlerTester2.assertState((avg.Node.CURSOR_MOTION,)),
+
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_UP, 12, 12),
+ lambda: handlerTester1.assertState(()),
+ lambda: handlerTester2.assertState((avg.Node.CURSOR_UP,))
+ ))
+
+ def testSensitive(self):
+ # Tests both sensitive and active attributes.
+ def activateNode(node, useSensitiveAttr, b):
+ if useSensitiveAttr:
+ node.sensitive = b
+ else:
+ node.active = b
+
+ def onNode2Down(event):
+ self.__node2Down = True
+
+ for useSensitiveAttr in (True, False):
+ root = self.loadEmptyScene()
+ self.img = avg.ImageNode(pos=(0,0), href="rgb24-65x65.png", parent=root)
+ handlerTester = NodeHandlerTester(self, self.img)
+
+ activateNode(self.img, useSensitiveAttr, False)
+ self.start(False,
+ (# Node is inactive -> no events.
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 10, 10),
+ lambda: handlerTester.assertState(()),
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_UP, 10, 10),
+
+ # Activate the node -> events arrive.
+ lambda: activateNode(self.img, useSensitiveAttr, True),
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 10, 10),
+ lambda: handlerTester.assertState(
+ (avg.Node.CURSOR_DOWN, avg.Node.CURSOR_OVER)),
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_UP, 10, 10),
+ ))
+ self.img = None
+
+ # Check if sensitive is deactivated immediately, not at the end of the frame.
+ root = self.loadEmptyScene()
+ self.img1 = avg.ImageNode(pos=(0,0), href="rgb24-65x65.png", parent=root)
+ self.img2 = avg.ImageNode(pos=(64,0), href="rgb24-65x65.png", parent=root)
+ self.img1.connectEventHandler(avg.Event.CURSOR_DOWN, avg.Event.TOUCH, self,
+ lambda event: activateNode(self.img2, useSensitiveAttr, False))
+ self.img2.connectEventHandler(avg.Event.CURSOR_DOWN, avg.Event.TOUCH, self,
+ onNode2Down)
+ self.__node2Down = False
+
+ self.start(False,
+ (lambda: self._sendTouchEvents((
+ (1, avg.Event.CURSOR_DOWN, 10, 10),
+ (2, avg.Event.CURSOR_DOWN, 80, 10),)),
+ lambda: self.assert_(not(self.__node2Down)),
+ ))
+
+ def testChangingHandlers(self):
+ root = self.loadEmptyScene()
+ img = avg.ImageNode(pos=(0,0), href="rgb24-65x65.png", parent=root)
+ handlerTester = NodeHandlerTester(self, img)
+
+ self.start(False,
+ (lambda: handlerTester.clearHandlers(),
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 10, 10),
+ lambda: handlerTester.assertState(()),
+ lambda: handlerTester.setHandlers(),
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_UP, 10, 10),
+ lambda: handlerTester.assertState((avg.Node.CURSOR_UP,)),
+ ))
+
+ def testEventCapture(self):
+ def onMainMouseDown(Event):
+ self.mainMouseDownCalled = True
+
+ def onMouseDown(Event):
+ self.mouseDownCalled = True
+
+ def captureEvent():
+ self.mouseDownCalled = False
+ self.mainMouseDownCalled = False
+ self.img.setEventCapture()
+
+ def noCaptureEvent():
+ self.mouseDownCalled = False
+ self.mainMouseDownCalled = False
+ self.img.releaseEventCapture()
+
+ def doubleCaptureEvent():
+ self.mouseDownCalled = False
+ self.mainMouseDownCalled = False
+ self.img.setEventCapture()
+ self.img.setEventCapture()
+ self.img.releaseEventCapture()
+
+ def releaseTooMuch():
+ self.img.releaseEventCapture()
+ self.assertException(self.img.releaseEventCapture)
+
+ self.mouseDownCalled = False
+ self.mainMouseDownCalled = False
+
+ root = self.loadEmptyScene()
+ root.setEventHandler(avg.Event.CURSOR_DOWN, avg.Event.MOUSE, onMainMouseDown)
+ self.img = avg.ImageNode(pos=(0,0), href="rgb24-65x65.png", parent=root)
+ self.img.setEventHandler(avg.Event.CURSOR_DOWN, avg.Event.MOUSE, onMouseDown)
+
+ self.start(False,
+ (lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 10, 10),
+ lambda: self.assert_(self.mouseDownCalled),
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_UP, 10, 10),
+ captureEvent,
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 100, 10),
+ lambda: self.assert_(self.mouseDownCalled and
+ self.mainMouseDownCalled),
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_UP, 100, 10),
+ noCaptureEvent,
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 100, 10),
+ lambda: self.assert_(not(self.mouseDownCalled) and
+ self.mainMouseDownCalled),
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_UP, 100, 10),
+ doubleCaptureEvent,
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 100, 10),
+ lambda: self.assert_(self.mouseDownCalled and
+ self.mainMouseDownCalled),
+ releaseTooMuch,
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_UP, 100, 10),
+ ))
+ self.img = None
+
+ def testMouseOver(self):
+ def onImg2MouseOver(Event):
+ self.img2MouseOverCalled = True
+
+ def onImg2MouseOut(Event):
+ self.img2MouseOutCalled = True
+
+ def onDivMouseOver(Event):
+ self.divMouseOverCalled = True
+
+ def onDivMouseOut(Event):
+ self.divMouseOutCalled = True
+
+ def onAVGMouseOver(Event):
+ self.avgMouseOverCalled = True
+
+ def onImg1MouseOver(Event):
+ self.img1MouseOverCalled = True
+
+ def printState():
+ print "----"
+ print "img2MouseOverCalled=", self.img2MouseOverCalled
+ print "img2MouseOutCalled=", self.img2MouseOutCalled
+ print "divMouseOverCalled=", self.divMouseOverCalled
+ print "divMouseOutCalled=", self.divMouseOutCalled
+ print "avgMouseOverCalled=", self.avgMouseOverCalled
+ print "img1MouseOverCalled=", self.img1MouseOverCalled
+
+ def resetState():
+ self.img2MouseOverCalled = False
+ self.img2MouseOutCalled = False
+ self.divMouseOverCalled = False
+ self.divMouseOutCalled = False
+ self.avgMouseOverCalled = False
+ self.img1MouseOverCalled = False
+
+ def killNodeUnderCursor():
+ Parent = img1.parent
+ Parent.removeChild(Parent.indexOf(img1))
+
+ root = self.loadEmptyScene()
+ img1 = avg.ImageNode(href="rgb24-65x65.png", parent=root)
+ div = avg.DivNode(pos=(65,0), parent=root)
+ img3 = avg.ImageNode(href="rgb24-65x65.png", parent=div)
+ img2 = avg.ImageNode(pos=(0,65), href="rgb24-65x65.png", parent=div)
+
+ img2.setEventHandler(avg.Event.CURSOR_OVER, avg.Event.MOUSE, onImg2MouseOver)
+ img2.setEventHandler(avg.Event.CURSOR_OUT, avg.Event.MOUSE, onImg2MouseOut)
+ div.setEventHandler(avg.Event.CURSOR_OVER, avg.Event.MOUSE, onDivMouseOver)
+ div.setEventHandler(avg.Event.CURSOR_OUT, avg.Event.MOUSE, onDivMouseOut)
+ root.setEventHandler(avg.Event.CURSOR_OVER, avg.Event.MOUSE, onAVGMouseOver)
+ img1.setEventHandler(avg.Event.CURSOR_OVER, avg.Event.MOUSE, onImg1MouseOver)
+ self.start(False,
+ (resetState,
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 70, 70),
+ lambda: self.assert_(
+ self.img2MouseOverCalled and
+ self.divMouseOverCalled and
+ self.avgMouseOverCalled and
+ not(self.img2MouseOutCalled) and
+ not(self.divMouseOutCalled) and
+ not(self.img1MouseOverCalled)),
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_UP, 70, 70),
+ resetState,
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 70, 10),
+ lambda: self.assert_(
+ not(self.img2MouseOverCalled) and
+ not(self.divMouseOverCalled) and
+ not(self.avgMouseOverCalled) and
+ self.img2MouseOutCalled and
+ not(self.divMouseOutCalled) and
+ not(self.img1MouseOverCalled)),
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_UP, 70, 10),
+
+ resetState,
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 10, 10),
+ lambda: self.assert_(
+ not(self.img2MouseOverCalled) and
+ not(self.divMouseOverCalled) and
+ not(self.avgMouseOverCalled) and
+ not(self.img2MouseOutCalled) and
+ self.divMouseOutCalled and
+ self.img1MouseOverCalled),
+
+ resetState,
+ killNodeUnderCursor,
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_UP, 10, 10),
+ lambda: self.assert_(
+ not(self.img2MouseOverCalled) and
+ not(self.divMouseOverCalled) and
+ not(self.avgMouseOverCalled) and
+ not(self.img2MouseOutCalled) and
+ not(self.divMouseOutCalled) and
+ not(self.img1MouseOverCalled)),
+
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 10, 10),
+ resetState,
+ lambda: img2.setEventCapture(),
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_UP, 70, 70),
+ lambda: self.assert_(
+ self.img2MouseOverCalled and
+ self.divMouseOverCalled and
+ not(self.avgMouseOverCalled) and
+ not(self.img2MouseOutCalled) and
+ not(self.divMouseOutCalled) and
+ not(self.img1MouseOverCalled)),
+
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 70, 70),
+ resetState,
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_UP, 10, 10),
+ lambda: self.assert_(
+ not(self.img2MouseOverCalled) and
+ not(self.divMouseOverCalled) and
+ not(self.avgMouseOverCalled) and
+ self.img2MouseOutCalled and
+ self.divMouseOutCalled and
+ not(self.img1MouseOverCalled))
+ ))
+
+ def testMouseDisable(self):
+ def checkMouseWorking(working):
+ if working:
+ downTestEvents = (avg.Node.CURSOR_DOWN, avg.Node.CURSOR_OVER)
+ upTestEvents = (avg.Node.CURSOR_UP,)
+ else:
+ downTestEvents = ()
+ upTestEvents = ()
+
+ return (lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 10, 10),
+ lambda: handlerTester.assertState(downTestEvents),
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_UP, 10, 10),
+ lambda: handlerTester.assertState(upTestEvents)
+ )
+
+ root = self.loadEmptyScene()
+ img = avg.ImageNode(pos=(0,0), href="rgb24-65x65.png", parent=root)
+ handlerTester = NodeHandlerTester(self, img)
+ player.enableMouse(False)
+
+ self.start(False,
+ (checkMouseWorking(False),
+ lambda: player.enableMouse(True),
+ checkMouseWorking(True),
+ lambda: player.enableMouse(False),
+ checkMouseWorking(False),
+ lambda: player.enableMouse(True),
+ ))
+
+ def testEventErr(self):
+ def onErrMouseOver(Event):
+ undefinedFunction()
+
+ root = self.loadEmptyScene()
+ root.setEventHandler(avg.Event.CURSOR_DOWN, avg.Event.MOUSE, onErrMouseOver)
+ self.assertException(lambda:
+ self.start(False,
+ (lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 10, 10),
+ )))
+
+ def testEventHook(self):
+ def resetState():
+ self.ehookMouseEvent = False
+ self.ehookKeyboardEvent = False
+
+ def cleanup():
+ resetState()
+ player.setEventHook(None)
+
+ def handleEvent(event):
+ if isinstance(event, avg.MouseEvent) and event.source == avg.Event.MOUSE:
+ if event.type == avg.Event.CURSOR_DOWN:
+ self.ehookMouseEvent = True
+ elif isinstance(event, avg.KeyEvent):
+ self.ehookKeyboardEvent = True
+ else:
+ self.fail()
+
+ self.loadEmptyScene()
+ resetState()
+
+ player.setEventHook(handleEvent)
+ self.start(False,
+ (lambda: self.fakeClick(10, 10),
+ lambda: self.assert_(self.ehookMouseEvent),
+ lambda: Helper.fakeKeyEvent(avg.Event.KEY_DOWN, 65, 65, "A", 65, 0),
+ lambda: self.assert_(self.ehookKeyboardEvent),
+ cleanup,
+ lambda: self.fakeClick(10, 10),
+ lambda: self.assert_(not self.ehookMouseEvent),
+ lambda: Helper.fakeKeyEvent(avg.Event.KEY_DOWN, 65, 65, "A", 65, 0),
+ lambda: self.assert_(not self.ehookKeyboardEvent),
+ ))
+
+ def testException(self):
+
+ class TestException(Exception):
+ pass
+
+ def throwException(event):
+ raise TestException
+
+ rect = avg.RectNode(size = (50, 50))
+ rect.setEventHandler(avg.Event.CURSOR_DOWN, avg.Event.MOUSE, throwException)
+
+ root = self.loadEmptyScene()
+ root.appendChild(rect)
+
+ self.__exceptionThrown = False
+ try:
+ self.start(False,
+ (lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 10, 10),
+ lambda: None
+ ))
+ except TestException:
+ self.__exceptionThrown = True
+
+ self.assert_(self.__exceptionThrown)
+
+ def testContacts(self):
+
+ def onDown(event):
+ contact = event.contact
+ self.assertEqual(event.cursorid, contact.id)
+ self.assertEqual(contact.age, 0)
+ self.assertEqual(contact.distancefromstart, 0)
+ self.assertEqual(contact.motionangle, 0)
+ self.assertEqual(contact.motionvec, (0,0))
+ self.assertEqual(contact.distancetravelled, 0)
+ self.assertEqual(contact.events[0].pos, event.pos)
+ self.assertEqual(len(contact.events), 1)
+ contact.connectListener(onMotion, onUp)
+ contact.subscribe(avg.Contact.CURSOR_MOTION, onMotionSubscribe)
+ contact.subscribe(avg.Contact.CURSOR_UP, onUpSubscribe)
+
+ def onMotion(event):
+ contact = event.contact
+ self.assertEqual(event.cursorid, contact.id)
+ self.assertEqual(contact.age, 40)
+ self.assertEqual(contact.distancefromstart, 10)
+ self.assertEqual(contact.motionangle, 0)
+ self.assertEqual(contact.motionvec, (10,0))
+ self.assertEqual(contact.distancetravelled, 10)
+ self.assertEqual(contact.events[-1].pos, event.pos)
+ self.assert_(len(contact.events) > 1)
+ self.numContactCallbacks += 1
+
+ def onUp(event):
+ contact = event.contact
+ self.assertEqual(event.cursorid, contact.id)
+ self.assertEqual(contact.age, 80)
+ self.assertEqual(contact.distancefromstart, 0)
+ self.assertEqual(contact.motionangle, 0)
+ self.assertEqual(contact.motionvec, (0,0))
+ self.assertEqual(contact.distancetravelled, 20)
+ self.assertEqual(contact.events[-1].pos, event.pos)
+ self.assert_(len(contact.events) > 1)
+ self.numContactCallbacks += 1
+
+ def onMotionSubscribe(event):
+ self.motionCalled = True
+
+ def onUpSubscribe(event):
+ self.upCalled = True
+
+ def onOver(event):
+ self.numOverCallbacks += 1
+ self.assertEqual(event.cursorid, event.contact.id)
+
+ def onOut(event):
+ self.numOutCallbacks += 1
+ self.assertEqual(event.cursorid, event.contact.id)
+
+ root = self.loadEmptyScene()
+ root.subscribe(avg.Node.CURSOR_DOWN, onDown)
+ self.numContactCallbacks = 0
+ rect = avg.RectNode(pos=(5,5), size=(10,10), parent=root)
+ rect.subscribe(avg.Node.CURSOR_OVER, onOver)
+ self.numOverCallbacks = 0
+ rect.subscribe(avg.Node.CURSOR_OUT, onOut)
+ self.numOutCallbacks = 0
+ player.setFakeFPS(25)
+ self.motionCalled = False
+ self.upCalled = False
+ self.start(False,
+ (lambda: self._sendTouchEvent(1, avg.Event.CURSOR_DOWN, 10, 10),
+ lambda: self._sendTouchEvent(1, avg.Event.CURSOR_MOTION, 20, 10),
+ lambda: self._sendTouchEvent(1, avg.Event.CURSOR_UP, 10, 10),
+ ))
+ self.assertEqual(self.numContactCallbacks, 2)
+ self.assertEqual(self.numOverCallbacks, 2)
+ self.assertEqual(self.numOutCallbacks, 2)
+ self.assert_(self.motionCalled and self.upCalled)
+
+ root = self.loadEmptyScene()
+ root.subscribe(avg.Node.CURSOR_DOWN, onDown)
+ self.numContactCallbacks = 0
+ self.start(False,
+ (lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 10, 10),
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_MOTION, 20, 10),
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_UP, 10, 10),
+ ))
+ self.assertEqual(self.numContactCallbacks, 2)
+
+ def testContactRegistration(self):
+
+ def onDown(event):
+ root.setEventCapture(event.cursorid)
+ root.releaseEventCapture(event.cursorid)
+
+ def onMotion(event):
+ contact = event.contact
+ self.contactID = contact.subscribe(avg.Contact.CURSOR_MOTION, onContactMotion)
+ self.numMotionCallbacks += 1
+ root.unsubscribe(avg.Node.CURSOR_DOWN, onDown)
+ root.unsubscribe(avg.Node.CURSOR_MOTION, onMotion)
+
+ def onContactMotion(event):
+ contact = event.contact
+ contact.unsubscribe(self.contactID)
+ self.assertException(lambda: contact.unsubscribe(self.contactID))
+ self.numContactCallbacks += 1
+
+ root = self.loadEmptyScene()
+ root.subscribe(avg.Node.CURSOR_DOWN, onDown)
+ self.numMotionCallbacks = 0
+ root.subscribe(avg.Node.CURSOR_MOTION, onMotion)
+ self.numContactCallbacks = 0
+ player.setFakeFPS(25)
+ self.start(False,
+ (lambda: self._sendTouchEvent(1, avg.Event.CURSOR_DOWN, 10, 10),
+ lambda: self._sendTouchEvent(1, avg.Event.CURSOR_MOTION, 20, 10),
+ lambda: self._sendTouchEvent(1, avg.Event.CURSOR_MOTION, 30, 10),
+ lambda: self._sendTouchEvent(1, avg.Event.CURSOR_MOTION, 40, 10),
+ ))
+ self.assertEqual(self.numContactCallbacks, 1)
+ self.assertEqual(self.numMotionCallbacks, 1)
+
+ def testMultiContactRegistration(self):
+
+ def onDown(event):
+ contact = event.contact
+ self.motionListenerID = contact.subscribe(avg.Contact.CURSOR_MOTION, onContact2)
+ self.upListenerID = contact.subscribe(avg.Contact.CURSOR_UP, onContact2)
+ contact.subscribe(avg.Contact.CURSOR_MOTION, onContact1)
+ contact.subscribe(avg.Contact.CURSOR_UP, onContact1)
+
+ def onContact1(event):
+ if self.numContact1Callbacks == 0:
+ event.contact.unsubscribe(self.motionListenerID)
+ event.contact.unsubscribe(self.upListenerID)
+ self.numContact1Callbacks += 1
+
+ def onContact2(event):
+ self.assertEqual(self.numContact1Callbacks, 0)
+ self.numContact2Callbacks += 1
+
+ root = self.loadEmptyScene()
+ root.subscribe(avg.Node.CURSOR_DOWN, onDown)
+ player.setFakeFPS(25)
+ self.numContact1Callbacks = 0
+ self.numContact2Callbacks = 0
+ self.start(False,
+ (lambda: self._sendTouchEvent(1, avg.Event.CURSOR_DOWN, 10, 10),
+ lambda: self._sendTouchEvent(1, avg.Event.CURSOR_MOTION, 20, 10),
+ lambda: self._sendTouchEvent(1, avg.Event.CURSOR_UP, 10, 10),
+ ))
+ self.assertEqual(self.numContact1Callbacks, 2)
+ # The order of callbacks is unspecified, so onContact2 might be called once.
+ self.assert_(self.numContact2Callbacks <= 1)
+
+ def testPlaybackMessages(self):
+
+ self.loadEmptyScene()
+ messageTester = MessageTester(player,
+ [avg.Player.PLAYBACK_START, avg.Player.PLAYBACK_END], self)
+ self.start(False,
+ (lambda: messageTester.assertState([avg.Player.PLAYBACK_START]),
+ ))
+ messageTester.assertState([avg.Player.PLAYBACK_END])
+
+ def testImageSizeChanged(self):
+ def onResize(newSize):
+ self.assert_(newSize == self.sizeExpected)
+ self.messageReceived = True
+
+ def changeHref():
+ self.messageReceived = False
+ self.sizeExpected = (32,32)
+ self.image.href="rgb24-32x32.png"
+ self.assert_(self.messageReceived)
+
+ def explicitChangeSize():
+ self.messageReceived = False
+ self.sizeExpected = (64,64)
+ self.image.size = self.sizeExpected
+ self.assert_(self.messageReceived)
+
+ def changeWidth():
+ self.messageReceived = False
+ self.sizeExpected = (32,64)
+ self.image.width = 32
+ self.assert_(self.messageReceived)
+
+ def move():
+ self.messageReceived = False
+ self.image.x = 4
+ self.assert_(not(self.messageReceived))
+
+ root = self.loadEmptyScene()
+ self.image = avg.ImageNode(href="rgb24-64x64.png", parent=root)
+ self.image.subscribe(avg.AreaNode.SIZE_CHANGED, onResize)
+ self.sizeExpected = (64, 64)
+ self.start(False,
+ (changeHref,
+ explicitChangeSize,
+ changeWidth,
+ move,
+ ))
+
+ def testWordsSizeChanged(self):
+ def onResize(newSize):
+ self.messageReceived = True
+
+ def checkMessageReceived():
+ self.assert_(self.messageReceived)
+ self.messageReceived = False
+
+ def changeText():
+ self.words.text="NewText"
+ checkMessageReceived()
+
+ self.messageReceived = False
+ root = self.loadEmptyScene()
+ self.words = avg.WordsNode(text="Test", parent=root)
+ self.words.subscribe(self.words.SIZE_CHANGED, onResize)
+ self.start(False,
+ (checkMessageReceived,
+ changeText,
+ ))
+
+ def testVideoSizeChanged(self):
+
+ def onResize(newSize):
+ self.messageReceived = True
+
+ self.messageReceived = False
+ root = self.loadEmptyScene()
+ self.video = avg.VideoNode(href="mpeg1-48x48.mov", parent=root)
+ self.video.subscribe(self.video.SIZE_CHANGED, onResize)
+ self.video.play()
+ self.assert_(self.messageReceived)
+
+ def testRectSizeChanged(self):
+
+ def onResize(newSize):
+ self.messageReceived = True
+
+ self.messageReceived = False
+ root = self.loadEmptyScene()
+ self.rect = avg.RectNode(size=(10,10), parent=root)
+ self.rect.subscribe(self.rect.SIZE_CHANGED, onResize)
+ self.rect.size=(100,100)
+ self.assert_(self.messageReceived)
+
+
+def eventTestSuite(tests):
+ availableTests = (
+ "testKeyEvents",
+ "testSimpleEvents",
+ "testTilted",
+ "testWordsClicks",
+ "testDivEvents",
+ "testDivNegativePos",
+ "testUnlinkInHandler",
+ "testConnectHandler",
+ "testPublisher",
+ "testComplexPublisher",
+ "testPublisherAutoDelete",
+ "testPublisherNestedUnsubscribe",
+ "testObscuringEvents",
+ "testSensitive",
+ "testChangingHandlers",
+ "testEventCapture",
+ "testMouseOver",
+ "testMouseDisable",
+ "testEventErr",
+ "testEventHook",
+ "testException",
+ "testContacts",
+ "testContactRegistration",
+ "testMultiContactRegistration",
+ "testPlaybackMessages",
+ "testImageSizeChanged",
+ "testWordsSizeChanged",
+ "testVideoSizeChanged",
+ "testRectSizeChanged",
+ )
+ return createAVGTestSuite(availableTests, EventTestCase, tests)
+
+Helper = player.getTestHelper()
diff --git a/src/test/FXTest.py b/src/test/FXTest.py
new file mode 100644
index 0000000..de677a0
--- /dev/null
+++ b/src/test/FXTest.py
@@ -0,0 +1,483 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# libavg - Media Playback Engine.
+# Copyright (C) 2003-2014 Ulrich von Zadow
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Current versions can be found at www.libavg.de
+#
+
+from libavg import avg, utils, player
+from testcase import *
+
+
+class FXTestCase(AVGTestCase):
+ def __init__(self, testFuncName):
+ AVGTestCase.__init__(self, testFuncName)
+
+ def testImageNullFX(self):
+ def activateFX():
+ for node in self.nodes[0]:
+ node.setEffect(avg.NullFXNode())
+
+ def newNode():
+ self.newNode = avg.ImageNode(parent=root, href="rgb24-32x32.png", pos=(64,0))
+ self.newNode.setEffect(avg.NullFXNode())
+
+ def newFX():
+ self.newNode.setEffect(avg.NullFXNode())
+
+ def addBgNode():
+ node = avg.RectNode(pos=(0,0), size=(64,96), fillopacity=1, opacity=0,
+ fillcolor="FFFFFF")
+ root.insertChild(node, 0)
+
+ def emptyImageFX():
+ node = avg.ImageNode(parent=root, href="", pos=(64,0))
+ node.setEffect(avg.NullFXNode())
+
+ # Initial setup is 3x2 images:
+ # rows: no alpha, alpha, alpha & opacity 0.6
+ # cols: no FX, FX
+ # The two cols should look the same.
+ root = self.loadEmptyScene()
+ self.nodes = []
+ for fx in (False, True):
+ curNodes = []
+ self.nodes.append(curNodes)
+ def configureNode(node, fx):
+ curNodes.append(node)
+ if fx:
+ node.x = 32
+ node.setEffect(avg.NullFXNode())
+
+ node = avg.ImageNode(parent=root, href="rgb24-32x32.png", pos=(0,0))
+ configureNode(node, fx)
+ node = avg.ImageNode(parent=root, href="rgb24alpha-32x32.png", pos=(0,32))
+ configureNode(node, fx)
+ node = avg.ImageNode(parent=root, href="rgb24alpha-32x32.png", pos=(0,64),
+ opacity=0.6)
+ configureNode(node, fx)
+
+ self.start(False,
+ (lambda: self.compareImage("testImageNullFX1"),
+ addBgNode,
+ lambda: self.compareImage("testImageNullFX2"),
+ activateFX,
+ lambda: self.compareImage("testImageNullFX2"),
+ newNode,
+ lambda: self.compareImage("testImageNullFX3"),
+ newFX,
+ lambda: self.compareImage("testImageNullFX3"),
+ emptyImageFX,
+ lambda: utils.initFXCache(10),
+ ))
+
+ def testVideoNullFX(self):
+ root = self.loadEmptyScene()
+ player.setFakeFPS(25)
+ node = avg.VideoNode(parent=root, href="mjpeg-48x48.avi",
+ threaded=False)
+ node.setEffect(avg.NullFXNode())
+ node.play()
+ self.start(False, (lambda: self.compareImage("testVideoNullFX"),))
+
+ def testWordsNullFX(self):
+ root = self.loadEmptyScene()
+ node = avg.WordsNode(parent=root, text="testtext", font="Bitstream Vera Sans")
+ node.setEffect(avg.NullFXNode())
+ node = avg.WordsNode(parent=root, text="testtext", pos=(0,20),
+ font="Bitstream Vera Sans")
+ self.start(True,
+ (lambda: self.compareImage("testWordsNullFX"),
+ ))
+
+ def testCanvasNullFX(self):
+ def setOuterOpacity():
+ node.opacity=0.6
+
+ def setInnerOpacity():
+ innerNode = canvas.getElementByID("test")
+ innerNode.opacity = 0.0
+
+ root = self.loadEmptyScene()
+ canvas = self.__createOffscreenCanvas()
+ node = avg.ImageNode(parent=root, href="canvas:offscreen")
+ node.setEffect(avg.NullFXNode())
+ self.start(False,
+ (lambda: self.compareImage("testCanvasNullFX1"),
+ setOuterOpacity,
+ lambda: self.compareImage("testCanvasNullFX2"),
+ setInnerOpacity,
+ lambda: self.compareImage("testCanvasNullFX3"),
+ ))
+
+ def testNodeInCanvasNullFX(self):
+ root = self.loadEmptyScene()
+ canvas = self.__createOffscreenCanvas()
+ avg.ImageNode(parent=root, href="canvas:offscreen")
+ node = canvas.getElementByID("test")
+ node.setEffect(avg.NullFXNode())
+ rect = avg.RectNode(size=(100,100), strokewidth=0, fillcolor="FF0000",
+ fillopacity=1)
+ canvas.getRootNode().insertChild(rect, 0)
+
+ self.start(False,
+ (lambda: self.compareImage("testNodeInCanvasNullFX1"),
+ ))
+
+ def testRenderPipeline(self):
+ sys.stderr.write("\n")
+ for useSrcCanvas in (False, True):
+ for useDestCanvas in (False, True):
+ for useFX in (False, True):
+ for useColorConv in (False, True):
+ sys.stderr.write(" "+str(useSrcCanvas)+" "+str(useDestCanvas)+
+ " "+str(useFX)+" "+str(useColorConv)+"\n")
+ root = self.loadEmptyScene()
+ if useSrcCanvas:
+ srcCanvas = player.createCanvas(id="src", size=(160,120),
+ mediadir="media")
+ avg.ImageNode(href="rgb24alpha-64x64.png",
+ parent=srcCanvas.getRootNode())
+ srcImg = avg.ImageNode(href="canvas:src")
+ else:
+ srcImg = avg.ImageNode(href="rgb24alpha-64x64.png")
+ if useFX:
+ srcImg.setEffect(avg.NullFXNode())
+ if useColorConv:
+ srcImg.contrast = (1.01, 1.0, 1.0)
+ if useDestCanvas:
+ destCanvas = player.createCanvas(id="dest",
+ size=(160,120), mediadir="media")
+ destCanvas.getRootNode().appendChild(srcImg)
+ avg.ImageNode(href="canvas:dest", parent=root)
+ else:
+ root.appendChild(srcImg)
+ self.start(False,
+ (lambda: self.compareImage("testRenderPipeline"),
+ ))
+
+ def testBlurFX(self):
+
+ def setRadius(radius):
+ self.effect.radius = radius
+
+ def removeFX():
+ self.node.setEffect(None)
+
+ def reAddFX():
+ self.node.setEffect(self.effect)
+
+ def addNewFX():
+ effect = avg.BlurFXNode(8)
+ self.node.setEffect(effect)
+
+ root = self.loadEmptyScene()
+ self.node = avg.ImageNode(parent=root, pos=(10,10), href="rgb24-64x64.png")
+ self.effect = avg.BlurFXNode()
+ self.start(False,
+ (self.skipIfMinimalShader,
+ lambda: self.node.setEffect(self.effect),
+ lambda: self.compareImage("testBlurFX1"),
+ lambda: setRadius(8),
+ lambda: self.compareImage("testBlurFX2"),
+ removeFX,
+ lambda: self.compareImage("testBlurFX3"),
+ reAddFX,
+ lambda: self.compareImage("testBlurFX2"),
+ removeFX,
+ addNewFX,
+ lambda: self.compareImage("testBlurFX2"),
+ lambda: setRadius(300),
+ ))
+
+ def testHueSatFX(self):
+
+ def resetFX():
+ self.effect = avg.HueSatFXNode()
+ self.node.setEffect(self.effect)
+
+ def setParam(param, value):
+ assert(hasattr(self.effect, param))
+ setattr(self.effect, param, value)
+
+ root = self.loadEmptyScene()
+ self.node = avg.ImageNode(parent=root, pos=(10,10), href="rgb24alpha-64x64.png")
+ resetFX()
+ self.start(False,
+ (self.skipIfMinimalShader,
+ lambda: self.compareImage("testHueSatFX1"),
+ lambda: setParam('saturation', -50),
+ lambda: self.compareImage("testHueSatFX2"),
+ lambda: setParam('saturation', -100),
+ lambda: self.compareImage("testHueSatFX3"),
+ lambda: setParam('saturation', -150),
+ lambda: self.compareImage("testHueSatFX3"),
+ resetFX,
+ lambda: setParam('hue', 180),
+ lambda: self.compareImage("testHueSatFX4"),
+ lambda: setParam('hue', -180),
+ lambda: self.compareImage("testHueSatFX4"),
+ ))
+
+ def testInvertFX(self):
+
+ def resetFX():
+ self.effect = avg.InvertFXNode()
+ self.node.setEffect(self.effect)
+
+ def redAlphaScene():
+ self.redRect = avg.RectNode(parent=self.root, pos=(5, 5), fillcolor='FF0000',
+ fillopacity=1, opacity=0, size=(72, 72))
+ self.node = avg.ImageNode(parent=self.root, pos=(10,10),
+ href="rgb24alpha-64x64.png")
+ resetFX()
+
+ self.root = self.loadEmptyScene()
+ self.node = avg.ImageNode(parent=self.root, pos=(10,10), href="hsl.png")
+ resetFX()
+ self.start(False,
+ (self.skipIfMinimalShader,
+ lambda: self.compareImage("testInvertFX1"),
+ redAlphaScene,
+ lambda: self.compareImage("testInvertFX2"),
+ ))
+
+ def testShadowFX(self):
+
+ def setParams(offset, radius, opacity, color):
+ effect.offset = offset
+ effect.radius = radius
+ effect.opacity = opacity
+ effect.color = color
+
+ root = self.loadEmptyScene()
+ rect = avg.RectNode(parent=root, pos=(9.5,9.5), color="0000FF")
+ node = avg.ImageNode(parent=root, pos=(10,10), href="shadow.png")
+ rect.size = node.size + (1, 1)
+ effect = avg.ShadowFXNode((0,0), 1, 1, "FFFFFF")
+ self.start(False,
+ (self.skipIfMinimalShader,
+ lambda: node.setEffect(effect),
+ lambda: self.compareImage("testShadowFX1"),
+ lambda: setParams((0,0), 3, 2, "00FFFF"),
+ lambda: self.compareImage("testShadowFX2"),
+ lambda: setParams((2,2), 0.1, 1, "FFFFFF"),
+ lambda: self.compareImage("testShadowFX3"),
+ lambda: setParams((-2,-2), 0.1, 1, "FFFFFF"),
+ lambda: self.compareImage("testShadowFX4"),
+ lambda: setParams((-2,-2), 3, 1, "FFFFFF"),
+ lambda: self.compareImage("testShadowFX5"),
+ lambda: setParams((0,0), 0, 1, "FFFFFF"),
+ lambda: self.compareImage("testShadowFX6"),
+ ))
+
+ def testWordsShadowFX(self):
+
+ def setParams(offset, radius, opacity, color):
+ effect.offset = offset
+ effect.radius = radius
+ effect.opacity = opacity
+ effect.color = color
+
+ root = self.loadEmptyScene()
+ node = avg.WordsNode(parent=root, pos=(10,10), text="testtext",
+ font="Bitstream Vera Sans")
+ effect = avg.ShadowFXNode()
+ setParams((0,0), 1.5, 1.5, "FF0000")
+ self.start(True,
+ (self.skipIfMinimalShader,
+ lambda: node.setEffect(effect),
+ lambda: self.compareImage("testWordsShadowFX1"),
+ lambda: setParams((2,2), 2, 2, "00FFFF"),
+ lambda: self.compareImage("testWordsShadowFX2"),
+ ))
+
+ def testGamma(self):
+ def setGamma(val):
+ node.gamma = val
+
+ root = self.loadEmptyScene()
+ node = avg.ImageNode(parent=root, href="colorramp.png", gamma=(0.5,0.5,0.5))
+ self.assertEqual(node.gamma, (0.5,0.5,0.5))
+ self.start(False,
+ (lambda: self.compareImage("testGamma1"),
+ lambda: setGamma((1.5,2.0,2.5)),
+ lambda: self.assertEqual(node.gamma, (1.5,2.0,2.5)),
+ lambda: self.compareImage("testGamma2"),
+ ))
+
+ def testIntensity(self):
+ def setIntensity(val):
+ node.intensity = val
+
+ def showVideo():
+ node.unlink(True)
+ self.videoNode = avg.VideoNode(parent=root, size=(96,96), threaded=False,
+ href="mpeg1-48x48.mov", intensity=(0.5,0.5,0.5))
+ self.videoNode.play()
+
+ root = self.loadEmptyScene()
+ node = avg.ImageNode(parent=root, href="colorramp.png", intensity=(0.5,0.5,0.5))
+ self.assertEqual(node.intensity, (0.5,0.5,0.5))
+ player.setFakeFPS(10)
+ self.start(False,
+ (lambda: self.compareImage("testIntensity1"),
+ lambda: setIntensity((1.5,2.0,2.5)),
+ lambda: self.assertEqual(node.intensity, (1.5,2.0,2.5)),
+ lambda: self.compareImage("testIntensity2"),
+ showVideo,
+ lambda: self.compareImage("testIntensity3"),
+ ))
+ player.setFakeFPS(-1)
+ self.videoNode = None
+
+ def testWordsIntensity(self):
+ root = self.loadEmptyScene()
+ avg.WordsNode(parent=root, fontsize=24, font="Bitstream Vera Sans",
+ intensity=(0.5,0.5,0.5), text="brightness",
+ width=140)
+ self.start(True,
+ (lambda: self.compareImage("testWordsIntensity"),
+ ))
+
+
+ def testContrast(self):
+ def setContrast(val):
+ node.contrast = val
+
+ def showVideo():
+ node.unlink(True)
+ videoNode = avg.VideoNode(parent=root, size=(96,96), threaded=False,
+ href="mpeg1-48x48.mov", contrast=(0.5,0.5,0.5))
+ videoNode.play()
+
+ root = self.loadEmptyScene()
+ node = avg.ImageNode(parent=root, href="colorramp.png", contrast=(0.5,0.5,0.5))
+ self.assertEqual(node.contrast, (0.5,0.5,0.5))
+ player.setFakeFPS(10)
+ self.start(False,
+ (lambda: self.compareImage("testContrast1"),
+ lambda: setContrast((1.5,2.0,2.5)),
+ lambda: self.assertEqual(node.contrast, (1.5,2.0,2.5)),
+ lambda: self.compareImage("testContrast2"),
+ showVideo,
+ lambda: self.compareImage("testContrast3"),
+ ))
+ player.setFakeFPS(-1)
+
+ def testFXUpdate(self):
+ # This tests if the FX render-on-demand functionality doesn't forget updates.
+ def changeTexture():
+ node.href = "colorramp.png"
+
+ def addMaskTex():
+ node.maskhref = "mask.png"
+
+ def changeMaskTex():
+ node.maskhref = "mask2.png"
+
+ def changeMaskPos():
+ node.maskpos = (10, 10)
+
+ def changeFX():
+ effect.radius = 2
+
+ def addVideo():
+ node.unlink(True)
+ videoNode = avg.VideoNode(parent=root, threaded=False, size=(96,96),
+ href="mpeg1-48x48.mov")
+ effect = avg.BlurFXNode()
+ effect.radius = 0
+ videoNode.setEffect(effect)
+ videoNode.play()
+
+ root = self.loadEmptyScene()
+ node = avg.ImageNode(parent=root, href="rgb24alpha-64x64.png")
+ effect = avg.BlurFXNode()
+ effect.radius = 0
+ player.setFakeFPS(25)
+ self.start(False,
+ (self.skipIfMinimalShader,
+ lambda: node.setEffect(effect),
+ changeTexture,
+ lambda: self.compareImage("testFXUpdateTex"),
+ addMaskTex,
+ lambda: self.compareImage("testFXUpdateMaskTex1"),
+ changeMaskTex,
+ lambda: self.compareImage("testFXUpdateMaskTex2"),
+ changeMaskPos,
+ lambda: self.compareImage("testFXUpdateMaskPos"),
+ changeFX,
+ lambda: self.compareImage("testFXUpdateFX"),
+ addVideo,
+ None,
+ lambda: self.compareImage("testFXUpdateVideo"),
+ ))
+
+ def testChromaKeyFX(self):
+
+ def setParams(htol, ltol, stol):
+ effect.htolerance = htol
+ effect.ltolerance = ltol
+ effect.stolerance = stol
+
+ root = self.loadEmptyScene()
+ node = avg.ImageNode(parent=root, href="rgb24-64x64.png")
+ effect = avg.ChromaKeyFXNode()
+ setParams(0.01, 0.01, 0.01)
+ self.start(False,
+ (self.skipIfMinimalShader,
+ lambda: node.setEffect(effect),
+ lambda: self.compareImage("testChromaKeyFX1"),
+ lambda: setParams(0.2, 0.2, 0.2),
+ lambda: self.compareImage("testChromaKeyFX2"),
+ lambda: effect.__setattr__("color", "FF0000"),
+ lambda: self.compareImage("testChromaKeyFX3"),
+ lambda: effect.__setattr__("spillthreshold", 1),
+ lambda: self.compareImage("testChromaKeyFX4"),
+ ))
+
+ def __createOffscreenCanvas(self):
+ canvas = player.createCanvas(id="offscreen", size=(160,120), mediadir="media")
+ root = canvas.getRootNode()
+ avg.ImageNode(href="rgb24-32x32.png", parent=root)
+ avg.ImageNode(id="test", pos=(32,0), href="rgb24alpha-32x32.png", parent=root)
+ return canvas
+
+
+def fxTestSuite(tests):
+ availableTests = [
+ "testImageNullFX",
+ "testVideoNullFX",
+ "testWordsNullFX",
+ "testCanvasNullFX",
+ "testNodeInCanvasNullFX",
+ "testRenderPipeline",
+ "testBlurFX",
+ "testHueSatFX",
+ "testInvertFX",
+ "testShadowFX",
+ "testWordsShadowFX",
+ "testGamma",
+ "testIntensity",
+ "testWordsIntensity",
+ "testContrast",
+ "testFXUpdate",
+ "testChromaKeyFX",
+ ]
+ return createAVGTestSuite(availableTests, FXTestCase, tests)
diff --git a/src/test/GestureTest.py b/src/test/GestureTest.py
new file mode 100644
index 0000000..4c1a792
--- /dev/null
+++ b/src/test/GestureTest.py
@@ -0,0 +1,1048 @@
+# -*- coding: utf-8 -*-
+# libavg - Media Playback Engine.
+# Copyright (C) 2003-2014 Ulrich von Zadow
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Current versions can be found at www.libavg.de
+#
+
+from libavg import avg, gesture, player
+
+import math
+from testcase import *
+
+class GestureTestCase(AVGTestCase):
+
+ def __init__(self, testFuncName):
+ AVGTestCase.__init__(self, testFuncName)
+
+ def testTapRecognizer(self):
+
+ def abort():
+ self.__tapRecognizer.abort()
+
+ def enable(isEnabled):
+ self.__tapRecognizer.enable(isEnabled)
+
+ self.__initImageScene()
+ self.__tapRecognizer = gesture.TapRecognizer(self.image)
+ self.messageTester = MessageTester(self.__tapRecognizer,
+ [gesture.Recognizer.POSSIBLE, gesture.Recognizer.DETECTED,
+ gesture.Recognizer.FAILED], self)
+ player.setFakeFPS(10)
+ self.start(False,
+ (# Down-up: recognized as tap.
+ self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30,
+ [gesture.Recognizer.POSSIBLE]),
+ self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30,
+ [gesture.Recognizer.DETECTED]),
+ # Down-small move-up: recognized as tap.
+ self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30,
+ [gesture.Recognizer.POSSIBLE]),
+ self._genMouseEventFrames(avg.Event.CURSOR_MOTION, 31, 30, []),
+ self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30,
+ [gesture.Recognizer.DETECTED]),
+
+ # Down-small down-second up-second up-first: recognized as tap
+ self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30,
+ [gesture.Recognizer.POSSIBLE]),
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 31, 30, btn=2),
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_UP, 31, 30, btn=2),
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 31, 30, btn=2),
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_UP, 31, 30, btn=2),
+ self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30,
+ [gesture.Recognizer.DETECTED]),
+
+ # Down-big move-up: fail
+ self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30,
+ [gesture.Recognizer.POSSIBLE]),
+ self._genMouseEventFrames(avg.Event.CURSOR_MOTION, 80, 80,
+ [gesture.Recognizer.FAILED]),
+ self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, []),
+ # Down-Abort-Up: not recognized as tap
+ self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30,
+ [gesture.Recognizer.POSSIBLE]),
+ abort,
+ self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, []),
+ # Abort-Down-Up: recognized as tap
+ abort,
+ self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30,
+ [gesture.Recognizer.POSSIBLE]),
+ self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30,
+ [gesture.Recognizer.DETECTED]),
+ # Down-Abort-Up-Down-Up: recognized as tap
+ self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30,
+ [gesture.Recognizer.POSSIBLE]),
+ abort,
+ self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, []),
+ self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30,
+ [gesture.Recognizer.POSSIBLE]),
+ self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30,
+ [gesture.Recognizer.DETECTED]),
+ # Disable-Down-Up-Enable: not recognized as tap
+ lambda: enable(False),
+ self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30, []),
+ self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, []),
+ lambda: enable(True),
+ # Down-Disable-Enable-Up: not recognized as tap
+ self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30,
+ [gesture.Recognizer.POSSIBLE]),
+ lambda: enable(False),
+ lambda: enable(True),
+ self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, []),
+ # Down-Disable-Up-Enable-Down-Up: recognized as tap
+ self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30,
+ [gesture.Recognizer.POSSIBLE]),
+ lambda: enable(False),
+ self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, []),
+ lambda: enable(True),
+ self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30,
+ [gesture.Recognizer.POSSIBLE]),
+ self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30,
+ [gesture.Recognizer.DETECTED]),
+ # Abort-Disable-Abort-Enable-Abort-Down-Up: recognized as tap
+ abort,
+ lambda: enable(False),
+ abort,
+ lambda: enable(True),
+ abort,
+ self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30,
+ [gesture.Recognizer.POSSIBLE]),
+ self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30,
+ [gesture.Recognizer.DETECTED]),
+
+ # Remove node while tap is in progress.
+ self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30,
+ [gesture.Recognizer.POSSIBLE]),
+ self.__killImageNode,
+ self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, []),
+ ))
+
+ def testHoldRecognizer(self):
+
+ def abort():
+ self.__holdRecognizer.abort()
+
+ def enable(isEnabled):
+ self.__holdRecognizer.enable(isEnabled)
+
+ player.setFakeFPS(20)
+ self.__initImageScene()
+ self.__holdRecognizer = gesture.HoldRecognizer(self.image,
+ delay=1000)
+ self.messageTester = MessageTester(self.__holdRecognizer,
+ [gesture.Recognizer.POSSIBLE, gesture.Recognizer.DETECTED,
+ gesture.Recognizer.FAILED, gesture.Recognizer.END], self)
+ self.start(False,
+ (# Standard down-hold-up sequence.
+ self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30,
+ [gesture.Recognizer.POSSIBLE]),
+ lambda: self.delay(1100),
+ lambda: self.messageTester.assertState([gesture.Recognizer.DETECTED]),
+ self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30,
+ [gesture.Recognizer.END]),
+
+ # down-up sequence, hold not long enough.
+ self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30,
+ [gesture.Recognizer.POSSIBLE]),
+ self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30,
+ [gesture.Recognizer.FAILED]),
+
+ # down-move-up sequence, should fail.
+ self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 1, 1,
+ [gesture.Recognizer.POSSIBLE]),
+ self._genMouseEventFrames(avg.Event.CURSOR_MOTION, 150, 50,
+ [gesture.Recognizer.FAILED]),
+ self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, []),
+
+ # down-hold-abort-up, should be recognized, no end event.
+ self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30,
+ [gesture.Recognizer.POSSIBLE]),
+ lambda: self.delay(1100),
+ lambda: self.messageTester.assertState([gesture.Recognizer.DETECTED]),
+ abort,
+ self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, []),
+
+ # down-abort-hold-up, should not be recognized
+ self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30,
+ [gesture.Recognizer.POSSIBLE]),
+ abort,
+ lambda: self.delay(1100),
+ lambda: self.messageTester.assertState([]),
+ self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, []),
+
+ # down-hold-disabled-up-enabled, should be recognized, no end event.
+ self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30,
+ [gesture.Recognizer.POSSIBLE]),
+ lambda: self.delay(1100),
+ lambda: self.messageTester.assertState([gesture.Recognizer.DETECTED]),
+ lambda: enable(False),
+ self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, []),
+ lambda: enable(True),
+
+ # down-disabled-enabled-hold-up, should not be recognized
+ self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30,
+ [gesture.Recognizer.POSSIBLE]),
+ lambda: enable(False),
+ lambda: enable(True),
+ lambda: self.delay(1100),
+ lambda: self.messageTester.assertState([]),
+ self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, []),
+
+ # Remove node while hold is in progress.
+ self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30,
+ [gesture.Recognizer.POSSIBLE]),
+ self.__killImageNode,
+ lambda: self.delay(1100),
+ self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, []),
+ ))
+ player.setFakeFPS(-1)
+
+
+ def testDoubletapRecognizer(self):
+
+ def abort():
+ self.__tapRecognizer.abort()
+
+ def enable(isEnabled):
+ self.__tapRecognizer.enable(isEnabled)
+
+ root = self.loadEmptyScene()
+ image = avg.ImageNode(parent=root, href="rgb24-64x64.png", size=(128,128))
+ self.__tapRecognizer = gesture.DoubletapRecognizer(image)
+ self.messageTester = MessageTester(self.__tapRecognizer,
+ [gesture.Recognizer.POSSIBLE, gesture.Recognizer.DETECTED,
+ gesture.Recognizer.FAILED, gesture.Recognizer.END], self)
+ player.setFakeFPS(20)
+ self.start(False,
+ (# Down, up, down, up: click
+ self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30,
+ [gesture.Recognizer.POSSIBLE]),
+ self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, []),
+ self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30, []),
+ self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30,
+ [gesture.Recognizer.DETECTED]),
+ # Down, move: stop
+ self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 0, 30,
+ [gesture.Recognizer.POSSIBLE]),
+ self._genMouseEventFrames(avg.Event.CURSOR_MOTION, 80, 30,
+ [gesture.Recognizer.FAILED]),
+ self._genMouseEventFrames(avg.Event.CURSOR_UP, 0, 30, []),
+ # Down, up, move: stop
+ self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 0, 30,
+ [gesture.Recognizer.POSSIBLE]),
+ self._genMouseEventFrames(avg.Event.CURSOR_UP, 0, 30, []),
+ self._genMouseEventFrames(avg.Event.CURSOR_MOTION, 80, 30, []),
+ self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 80, 30,
+ [gesture.Recognizer.FAILED]),
+ self._genMouseEventFrames(avg.Event.CURSOR_UP, 0, 30, []),
+ # Down, up, down, move: stop
+ self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 0, 30,
+ [gesture.Recognizer.POSSIBLE]),
+ self._genMouseEventFrames(avg.Event.CURSOR_UP, 0, 30, []),
+ self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 0, 30, []),
+ self._genMouseEventFrames(avg.Event.CURSOR_MOTION, 80, 30,
+ [gesture.Recognizer.FAILED]),
+ self._genMouseEventFrames(avg.Event.CURSOR_UP, 0, 30, []),
+ # Down,delay: stop
+ self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30,
+ [gesture.Recognizer.POSSIBLE]),
+ lambda: self.delay(1000),
+ lambda: self.messageTester.assertState([gesture.Recognizer.FAILED]),
+ self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30,
+ []),
+ # Down, up, delay: stop
+ self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30,
+ [gesture.Recognizer.POSSIBLE]),
+ self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, []),
+ lambda: self.delay(1000),
+ lambda: self.messageTester.assertState([gesture.Recognizer.FAILED]),
+ # Down, up, down, delay: stop
+ self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30,
+ [gesture.Recognizer.POSSIBLE]),
+ self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, []),
+ self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30, []),
+ lambda: self.delay(1000),
+ lambda: self.messageTester.assertState([gesture.Recognizer.FAILED]),
+ self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30,
+ []),
+ # Down, abort, up, down, up, delay: just one click
+ self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30,
+ [gesture.Recognizer.POSSIBLE]),
+ abort,
+ self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, []),
+ self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30,
+ [gesture.Recognizer.POSSIBLE]),
+ self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, []),
+ lambda: self.delay(1000),
+ lambda: self.messageTester.assertState([gesture.Recognizer.FAILED]),
+ # Down, up, abort, down, up, delay: two clicks but no double-click
+ self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30,
+ [gesture.Recognizer.POSSIBLE]),
+ self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, []),
+ abort,
+ self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30,
+ [gesture.Recognizer.POSSIBLE]),
+ self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, []),
+ lambda: self.delay(1000),
+ lambda: self.messageTester.assertState([gesture.Recognizer.FAILED]),
+ # Down, up, down, abort, up: just one click
+ self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30,
+ [gesture.Recognizer.POSSIBLE]),
+ self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, []),
+ self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30, []),
+ abort,
+ self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, []),
+ # Down, abort, up, down, up, down up: first aborted then recognized
+ self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30,
+ [gesture.Recognizer.POSSIBLE]),
+ abort,
+ self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, []),
+ self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30,
+ [gesture.Recognizer.POSSIBLE]),
+ self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, []),
+ self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30, []),
+ self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30,
+ [gesture.Recognizer.DETECTED]),
+ # Disabled, down, up, down, up, enabled: nothing
+ lambda: enable(False),
+ self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30, []),
+ self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, []),
+ self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30, []),
+ self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, []),
+ lambda: enable(True),
+ # Down, disabled up, down, up, enabled: just one down
+ self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30,
+ [gesture.Recognizer.POSSIBLE]),
+ lambda: enable(False),
+ self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, []),
+ self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30, []),
+ self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, []),
+ lambda: enable(True),
+ # Down, up, disabled, down, up, enabled: just one click
+ self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30,
+ [gesture.Recognizer.POSSIBLE]),
+ self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, []),
+ lambda: enable(False),
+ self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30, []),
+ self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, []),
+ lambda: enable(True),
+ # Down, up, down, disabled, up, enabled: just one click
+ self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30,
+ [gesture.Recognizer.POSSIBLE]),
+ self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, []),
+ self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30, []),
+ lambda: enable(False),
+ self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, []),
+ lambda: enable(True),
+ # Down, disabled, enabled, up, down, up, down, up: recognized
+ self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30,
+ [gesture.Recognizer.POSSIBLE]),
+ lambda: enable(False),
+ lambda: enable(True),
+ self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, []),
+ self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30,
+ [gesture.Recognizer.POSSIBLE]),
+ self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, []),
+ self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30, []),
+ self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30,
+ [gesture.Recognizer.DETECTED]),
+ ))
+
+
+ def testSwipeRecognizer(self):
+
+ # One finger
+ for direction, xdir in (
+ (gesture.SwipeRecognizer.RIGHT, 1), (gesture.SwipeRecognizer.LEFT, -1)):
+ self.__initImageScene()
+ swipeRecognizer = gesture.SwipeRecognizer(self.image, minDist=20,
+ direction=direction)
+ self.messageTester = MessageTester(swipeRecognizer,
+ [gesture.Recognizer.POSSIBLE, gesture.Recognizer.DETECTED,
+ gesture.Recognizer.FAILED],
+ self)
+ self.start(False,
+ (self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30,
+ [gesture.Recognizer.POSSIBLE]),
+ self._genMouseEventFrames(avg.Event.CURSOR_UP, 30+xdir*30, 30,
+ [gesture.Recognizer.DETECTED]),
+ # Check angle tolerance
+ self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30,
+ [gesture.Recognizer.POSSIBLE]),
+ self._genMouseEventFrames(avg.Event.CURSOR_UP, 30+xdir*30, 25,
+ [gesture.Recognizer.DETECTED]),
+ self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30,
+ [gesture.Recognizer.POSSIBLE]),
+ self._genMouseEventFrames(avg.Event.CURSOR_UP, 30+xdir*30, 35,
+ [gesture.Recognizer.DETECTED]),
+ # Not far enough -> fail
+ self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30,
+ [gesture.Recognizer.POSSIBLE]),
+ self._genMouseEventFrames(avg.Event.CURSOR_UP, 30+xdir*10, 30,
+ [gesture.Recognizer.FAILED]),
+ # Wrong direction -> fail
+ self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30,
+ [gesture.Recognizer.POSSIBLE]),
+ self._genMouseEventFrames(avg.Event.CURSOR_UP, 30+xdir*30, 60,
+ [gesture.Recognizer.FAILED]),
+ self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30,
+ [gesture.Recognizer.POSSIBLE]),
+ self._genMouseEventFrames(avg.Event.CURSOR_UP, 30+xdir*30, 5,
+ [gesture.Recognizer.FAILED]),
+ ))
+
+
+ def testSwipeRecognizerTwoFingers(self):
+ self.__initImageScene()
+ swipeRecognizer = gesture.SwipeRecognizer(self.image, minDist=20, numContacts=2,
+ maxContactDist=15, direction=gesture.SwipeRecognizer.RIGHT)
+ self.messageTester = MessageTester(swipeRecognizer,
+ [gesture.Recognizer.POSSIBLE, gesture.Recognizer.DETECTED,
+ gesture.Recognizer.FAILED],
+ self)
+ self.start(False,
+ (self._genTouchEventFrames(
+ [(0, avg.Event.CURSOR_DOWN, 30, 30,),],
+ []),
+ self._genTouchEventFrames(
+ [(1, avg.Event.CURSOR_DOWN, 40, 30,),],
+ [gesture.Recognizer.POSSIBLE]),
+ self._genTouchEventFrames(
+ [(1, avg.Event.CURSOR_UP, 70, 30,),],
+ []),
+ self._genTouchEventFrames(
+ [(0, avg.Event.CURSOR_UP, 60, 30,),],
+ [gesture.Recognizer.DETECTED]),
+ # Not enough fingers -> not recognized
+ self._genTouchEventFrames(
+ [(0, avg.Event.CURSOR_DOWN, 30, 30,),],
+ []),
+ self._genTouchEventFrames(
+ [(0, avg.Event.CURSOR_UP, 60, 30,),],
+ []),
+ # Fail first finger
+ self._genTouchEventFrames(
+ [(0, avg.Event.CURSOR_DOWN, 30, 30,),],
+ []),
+ self._genTouchEventFrames(
+ [(1, avg.Event.CURSOR_DOWN, 40, 30,),],
+ [gesture.Recognizer.POSSIBLE]),
+ self._genTouchEventFrames(
+ [(1, avg.Event.CURSOR_UP, 35, 30,),],
+ [gesture.Recognizer.FAILED]),
+ self._genTouchEventFrames(
+ [(0, avg.Event.CURSOR_UP, 60, 30,),],
+ []),
+ # Fail second finger
+ self._genTouchEventFrames(
+ [(0, avg.Event.CURSOR_DOWN, 30, 30,),],
+ []),
+ self._genTouchEventFrames(
+ [(1, avg.Event.CURSOR_DOWN, 40, 30,),],
+ [gesture.Recognizer.POSSIBLE]),
+ self._genTouchEventFrames(
+ [(1, avg.Event.CURSOR_UP, 70, 30,),],
+ []),
+ self._genTouchEventFrames(
+ [(0, avg.Event.CURSOR_UP, 35, 30,),],
+ [gesture.Recognizer.FAILED]),
+ # Fingers too far apart
+ self._genTouchEventFrames(
+ [(0, avg.Event.CURSOR_DOWN, 30, 30,),],
+ []),
+ self._genTouchEventFrames(
+ [(1, avg.Event.CURSOR_DOWN, 50, 30,),],
+ [gesture.Recognizer.FAILED]),
+ self._genTouchEventFrames(
+ [(1, avg.Event.CURSOR_UP, 70, 30,),
+ (0, avg.Event.CURSOR_UP, 60, 30,),],
+ []),
+ ))
+
+ def testDragRecognizer(self):
+
+ def onMove(offset):
+ if self.friction == -1:
+ self.assertEqual(offset, (40,40))
+ self.messageTester.setMessageReceived(gesture.Recognizer.MOTION)
+
+ def onUp(offset):
+ if self.friction == -1:
+ self.assertEqual(offset, (10,-10))
+ self.messageTester.setMessageReceived(gesture.Recognizer.UP)
+
+ def enable(isEnabled):
+ dragRecognizer.enable(isEnabled)
+
+ def abort():
+ dragRecognizer.abort()
+
+ def setupRecognizer(friction, moveHandler=onMove, minDragDist=0,
+ direction=gesture.DragRecognizer.ANY_DIRECTION, **kargs):
+ self.__initImageScene()
+ dragRecognizer = gesture.DragRecognizer(self.image, moveHandler=moveHandler,
+ upHandler=onUp, friction=friction, minDragDist=minDragDist,
+ direction=direction, **kargs)
+ messageTester = MessageTester(dragRecognizer, [gesture.Recognizer.POSSIBLE,
+ gesture.Recognizer.DETECTED, gesture.Recognizer.FAILED,
+ gesture.Recognizer.END],
+ self)
+ return (dragRecognizer, messageTester)
+
+ player.setFakeFPS(100)
+ sys.stderr.write("\n")
+ for self.friction in (-1, 100):
+ if self.friction == -1:
+ sys.stderr.write(" Simple drag, no inertia\n")
+ else:
+ sys.stderr.write(" Simple drag, inertia\n")
+ dragRecognizer, self.messageTester = setupRecognizer(friction=self.friction)
+ self.start(False,
+ (self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30,
+ [gesture.Recognizer.DETECTED]),
+ self._genMouseEventFrames(avg.Event.CURSOR_MOTION, 70, 70,
+ [gesture.Recognizer.MOTION]),
+ self._genMouseEventFrames(avg.Event.CURSOR_UP, 40, 20,
+ [gesture.Recognizer.UP, gesture.Recognizer.END]),
+ lambda: enable(False),
+ self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30, []),
+ lambda: dragRecognizer.enable(True),
+ self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, []),
+ self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30,
+ [gesture.Recognizer.DETECTED]),
+ self._genMouseEventFrames(avg.Event.CURSOR_UP, 40, 20,
+ [gesture.Recognizer.UP, gesture.Recognizer.END]),
+
+ # Remove node during drag.
+ self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30,
+ [gesture.Recognizer.DETECTED]),
+ self.__killImageNode,
+ self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30, []),
+ ))
+
+ # Test with constraint.
+ def onVertMove(offset):
+ if self.friction == -1:
+ self.assertEqual(offset, (0,40))
+ self.messageTester.setMessageReceived(gesture.Recognizer.MOTION)
+
+ for self.friction in (-1, 100):
+ if self.friction == -1:
+ sys.stderr.write(" Drag with constraint, no inertia\n")
+ else:
+ sys.stderr.write(" Drag with constraint, inertia\n")
+ dragRecognizer, self.messageTester = setupRecognizer(moveHandler=onVertMove,
+ friction=self.friction, direction=gesture.DragRecognizer.VERTICAL,
+ minDragDist=5)
+ self.start(False,
+ (self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30,
+ [gesture.Recognizer.POSSIBLE]),
+ self._genMouseEventFrames(avg.Event.CURSOR_MOTION, 35, 30, []),
+ self._genMouseEventFrames(avg.Event.CURSOR_MOTION, 30, 70,
+ [gesture.Recognizer.DETECTED, gesture.Recognizer.MOTION]),
+ self._genMouseEventFrames(avg.Event.CURSOR_UP, 40, 20,
+ [gesture.Recognizer.UP, gesture.Recognizer.END]),
+ # Wrong direction -> stop.
+ self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30,
+ [gesture.Recognizer.POSSIBLE]),
+ self._genMouseEventFrames(avg.Event.CURSOR_MOTION, 70, 30,
+ [gesture.Recognizer.FAILED]),
+ self._genMouseEventFrames(avg.Event.CURSOR_UP, 70, 30, []),
+
+ # No movement -> stop.
+ self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30,
+ [gesture.Recognizer.POSSIBLE]),
+ self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 30,
+ [gesture.Recognizer.FAILED]),
+
+ # Down, Abort, Motion, Motion, Up -> not recognized
+ self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30,
+ [gesture.Recognizer.POSSIBLE]),
+ abort,
+ self._genMouseEventFrames(avg.Event.CURSOR_MOTION, 35, 30, []),
+ self._genMouseEventFrames(avg.Event.CURSOR_MOTION, 30, 70, []),
+ self._genMouseEventFrames(avg.Event.CURSOR_UP, 40, 20, []),
+
+ # Down, Motion, Abort, Motion, Up -> not Recognized
+ self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30,
+ [gesture.Recognizer.POSSIBLE]),
+ self._genMouseEventFrames(avg.Event.CURSOR_MOTION, 35, 30, []),
+ abort,
+ self._genMouseEventFrames(avg.Event.CURSOR_MOTION, 30, 70, []),
+ self._genMouseEventFrames(avg.Event.CURSOR_UP, 40, 20, []),
+
+ # Down, Motion, Motion, Abort, Up -> not recognized
+ self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30,
+ [gesture.Recognizer.POSSIBLE]),
+ self._genMouseEventFrames(avg.Event.CURSOR_MOTION, 35, 30, []),
+ self._genMouseEventFrames(avg.Event.CURSOR_MOTION, 30, 70,
+ [gesture.Recognizer.DETECTED, gesture.Recognizer.MOTION]),
+ abort,
+ self._genMouseEventFrames(avg.Event.CURSOR_UP, 40, 20, []),
+
+ # Down, Motion, Abort, Up, Down, Motion, Motion, Up -> Recognized
+ self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30,
+ [gesture.Recognizer.POSSIBLE]),
+ self._genMouseEventFrames(avg.Event.CURSOR_MOTION, 35, 30, []),
+ abort,
+ self._genMouseEventFrames(avg.Event.CURSOR_UP, 40, 20, []),
+
+ self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30,
+ [gesture.Recognizer.POSSIBLE]),
+ self._genMouseEventFrames(avg.Event.CURSOR_MOTION, 35, 30, []),
+ self._genMouseEventFrames(avg.Event.CURSOR_MOTION, 30, 70,
+ [gesture.Recognizer.DETECTED, gesture.Recognizer.MOTION]),
+ self._genMouseEventFrames(avg.Event.CURSOR_UP, 40, 20,
+ [gesture.Recognizer.UP, gesture.Recognizer.END]),
+ ))
+
+ # Test second down during inertia.
+ sys.stderr.write(" Down during inertia\n")
+ dragRecognizer, self.messageTester = setupRecognizer(friction=0.01)
+ self.start(False,
+ (lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 30, 30),
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_UP, 40, 20),
+ self.messageTester.reset,
+ self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 40, 20,
+ [gesture.Recognizer.END, gesture.Recognizer.DETECTED,
+ gesture.Recognizer.MOTION]),
+ ))
+
+ # Test node delete during inertia
+ sys.stderr.write(" Delete during inertia\n")
+ dragRecognizer, self.messageTester = setupRecognizer(friction=0.01)
+ self.start(False,
+ (self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30,
+ [gesture.Recognizer.DETECTED]),
+ self._genMouseEventFrames(avg.Event.CURSOR_UP, 40, 20,
+ [gesture.Recognizer.MOTION, gesture.Recognizer.UP]),
+ self.__killImageNode,
+ self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 40, 20,
+ [gesture.Recognizer.MOTION]),
+ ))
+
+ # Test second down during inertia, constrained recognizer
+ sys.stderr.write(" Down during inertia, constrained recognizer\n")
+ dragRecognizer, self.messageTester = setupRecognizer(friction=0.01,
+ direction=gesture.DragRecognizer.VERTICAL, minDragDist=5)
+ self.start(False,
+ (lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 30, 30),
+ self._genMouseEventFrames(avg.Event.CURSOR_MOTION, 30, 70,
+ [gesture.Recognizer.DETECTED, gesture.Recognizer.MOTION,
+ gesture.Recognizer.POSSIBLE]),
+ self._genMouseEventFrames(avg.Event.CURSOR_UP, 30, 70,
+ [gesture.Recognizer.MOTION, gesture.Recognizer.UP]),
+ self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30,
+ [gesture.Recognizer.END, gesture.Recognizer.POSSIBLE,
+ gesture.Recognizer.MOTION]),
+ ))
+
+ # Test abort in possible handler
+ for self.friction in (-1, 100):
+ if self.friction == -1:
+ sys.stderr.write(" Abort in possible handler, no inertia\n")
+ else:
+ sys.stderr.write(" Abort in possible handler, inertia\n")
+ dragRecognizer, self.messageTester = setupRecognizer(friction=self.friction,
+ minDragDist=5, possibleHandler=abort)
+ self.start(False,
+ (self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30,
+ [gesture.Recognizer.POSSIBLE]),
+ self._genMouseEventFrames(avg.Event.CURSOR_MOTION, 70, 70, []),
+ self._genMouseEventFrames(avg.Event.CURSOR_UP, 70, 70, []),
+ self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 30, 30,
+ [gesture.Recognizer.POSSIBLE]),
+ ))
+
+ player.setFakeFPS(-1)
+
+
+ def testDragRecognizerRelCoords(self):
+
+ def onDrag(offset):
+ self.assertAlmostEqual(offset, (-40,-40))
+ self.__onDragCalled = True
+
+ player.setFakeFPS(100)
+ self.__onDragCalled = False
+ for self.friction in (-1, 100):
+ root = self.loadEmptyScene()
+ div = avg.DivNode(pos=(64,64), angle=math.pi, parent=root)
+ image = avg.ImageNode(parent=div, href="rgb24-64x64.png")
+ dragRecognizer = gesture.DragRecognizer(image, moveHandler=onDrag,
+ friction=self.friction)
+ self.start(False,
+ (lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 30, 30),
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_MOTION, 70, 70),
+ ))
+ player.setFakeFPS(-1)
+ assert(self.__onDragCalled)
+
+
+ def testDragRecognizerInitialEvent(self):
+
+ def onMotion(offset):
+ gesture.DragRecognizer(self.image,
+ detectedHandler=onDragStart, moveHandler=onDrag,
+ initialEvent=player.getCurrentEvent())
+ self.image.unsubscribe(avg.Node.CURSOR_MOTION, onMotion)
+
+ def onDragStart():
+ self.__dragStartCalled = True
+
+ def onDrag(offset):
+ self.assertEqual(offset, (10,0))
+
+ self.__initImageScene()
+ self.image.subscribe(avg.Node.CURSOR_MOTION, onMotion)
+ self.__dragStartCalled = False
+ self.start(False,
+ (lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 30, 30),
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_MOTION, 40, 30),
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_MOTION, 50, 30),
+ ))
+ assert(self.__dragStartCalled)
+
+
+ def testDragRecognizerCoordSysNode(self):
+
+ def onDrag(offset):
+ self.assertEqual(offset, (40,40))
+ self.__dragRecognizerCalled = True
+
+ root = self.loadEmptyScene()
+ div = avg.DivNode(pos=(64,64), angle=math.pi, parent=root)
+ image = avg.ImageNode(parent=div, href="rgb24-64x64.png")
+ dragRecognizer = gesture.DragRecognizer(image, moveHandler=onDrag,
+ coordSysNode=div, friction=-1)
+ self.__dragRecognizerCalled = False
+ self.start(False,
+ (lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 30, 30),
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_MOTION, 70, 70),
+ ))
+ assert(self.__dragRecognizerCalled)
+
+
+ def testDragRecognizerCoordSysNodeParentUnlink(self):
+
+ def onDrag(offset):
+ self.assertEqual(offset, (40,40))
+ self.__dragRecognizerCalled = True
+
+ def onUp(offset):
+ self.__upRecognizerCalled = True
+
+ root = self.loadEmptyScene()
+ div = avg.DivNode(pos=(64,64), angle=math.pi, parent=root)
+ image = avg.ImageNode(parent=div, href="rgb24-64x64.png")
+ dragRecognizer = gesture.DragRecognizer(image, moveHandler=onDrag,
+ coordSysNode=div, friction=-1)
+ self.__dragRecognizerCalled = False
+ self.__upRecognizerCalled = False
+ self.start(False,
+ (lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 30, 30),
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_MOTION, 70, 70),
+ lambda: div.unlink(False),
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_UP, 70, 70),
+ ))
+ assert(self.__dragRecognizerCalled)
+ assert(not self.__upRecognizerCalled)
+
+
+ def testDragRecognizerMinDist(self):
+
+ def onMove(offset):
+ self.messageTester.setMessageReceived(gesture.Recognizer.MOTION)
+
+ self.__initImageScene()
+ dragRecognizer = gesture.DragRecognizer(self.image, moveHandler=onMove,
+ minDragDist=10, friction=-1)
+ self.messageTester = MessageTester(dragRecognizer, [gesture.Recognizer.DETECTED],
+ self)
+ self.start(False,
+ (lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 30, 30),
+ self._genMouseEventFrames(avg.Event.CURSOR_MOTION, 30, 35,
+ []),
+ self._genMouseEventFrames(avg.Event.CURSOR_MOTION, 30, 50,
+ [gesture.Recognizer.DETECTED, gesture.Recognizer.MOTION]),
+ ))
+
+
+ def testTransformRecognizer(self):
+
+ def onDetected():
+ pass
+
+ def onMove(transform):
+ self.transform = transform
+
+ def onUp(transform):
+ self.transform = transform
+
+ def checkTransform(expectedTransform):
+# print self.transform
+# print expectedTransform
+# print
+ self.assertAlmostEqual(self.transform.trans, expectedTransform.trans)
+ self.assertAlmostEqual(self.transform.rot, expectedTransform.rot)
+ self.assertAlmostEqual(self.transform.scale, expectedTransform.scale)
+ if expectedTransform.rot != 0 or expectedTransform.scale != 1:
+ self.assertAlmostEqual(self.transform.pivot, expectedTransform.pivot)
+
+ def createTransTestFrames():
+ return (
+ lambda: self._sendTouchEvent(1, avg.Event.CURSOR_DOWN, 10, 10),
+ lambda: self._sendTouchEvent(1, avg.Event.CURSOR_UP, 20, 10),
+ lambda: checkTransform(gesture.Transform((10,0))),
+ )
+
+ def createRotTestFrames(expectedTransform):
+ return (
+ lambda: self._sendTouchEvents((
+ (1, avg.Event.CURSOR_DOWN, 0, 10),
+ (2, avg.Event.CURSOR_DOWN, 0, 20))),
+ lambda: self._sendTouchEvents((
+ (1, avg.Event.CURSOR_MOTION, 0, 20),
+ (2, avg.Event.CURSOR_MOTION, 0, 10))),
+ lambda: checkTransform(expectedTransform),
+ lambda: self._sendTouchEvents((
+ (1, avg.Event.CURSOR_UP, 0, 20),
+ (2, avg.Event.CURSOR_UP, 0, 10))),
+ )
+
+ def createScaleTestFrames(expectedTransform):
+ return (
+ lambda: self._sendTouchEvent(1, avg.Event.CURSOR_DOWN, 0, 10),
+ lambda: self._sendTouchEvent(2, avg.Event.CURSOR_DOWN, 0, 20),
+ lambda: self._sendTouchEvent(1, avg.Event.CURSOR_MOTION, 0, 10),
+ lambda: self._sendTouchEvent(2, avg.Event.CURSOR_MOTION, 0, 30),
+ lambda: checkTransform(expectedTransform),
+ lambda: self._sendTouchEvent(1, avg.Event.CURSOR_UP, 0, 10),
+ lambda: self._sendTouchEvent(2, avg.Event.CURSOR_UP, 0, 30),
+ )
+
+ player.setFakeFPS(100)
+ self.__initImageScene()
+ # Turn off the jitter filter.
+ gesture.TransformRecognizer.FILTER_MIN_CUTOFF = None
+ gesture.TransformRecognizer.FILTER_BETA = None
+
+ self.__transformRecognizer = gesture.TransformRecognizer(self.image,
+ friction=-1,
+ detectedHandler=onDetected, moveHandler=onMove, upHandler=onUp)
+ self.start(False,
+ (# Check up/down handling
+ lambda: self._sendTouchEvent(1, avg.Event.CURSOR_DOWN, 10, 10),
+ lambda: checkTransform(gesture.Transform((0,0))),
+ lambda: self._sendTouchEvent(1, avg.Event.CURSOR_MOTION, 20, 10),
+ lambda: checkTransform(gesture.Transform((10,0))),
+ lambda: self._sendTouchEvent(2, avg.Event.CURSOR_DOWN, 20, 20),
+ lambda: checkTransform(gesture.Transform((0,0))),
+ lambda: self._sendTouchEvents((
+ (1, avg.Event.CURSOR_MOTION, 30, 10),
+ (2, avg.Event.CURSOR_MOTION, 30, 20))),
+ lambda: checkTransform(gesture.Transform((10,0))),
+ lambda: self._sendTouchEvent(2, avg.Event.CURSOR_UP, 30, 20),
+ lambda: checkTransform(gesture.Transform((0,0))),
+ lambda: self._sendTouchEvent(1, avg.Event.CURSOR_MOTION, 40, 10),
+ lambda: checkTransform(gesture.Transform((10,0))),
+ lambda: self._sendTouchEvent(1, avg.Event.CURSOR_UP, 50, 10),
+ lambda: checkTransform(gesture.Transform((10,0))),
+
+ createRotTestFrames(gesture.Transform((0,0), math.pi, 1, (0,15))),
+
+ createScaleTestFrames(gesture.Transform((0,5), 0, 2, (0,20))),
+
+ # Delete node during transform
+ lambda: self._sendTouchEvents((
+ (1, avg.Event.CURSOR_DOWN, 30, 10),
+ (2, avg.Event.CURSOR_DOWN, 30, 20))),
+ self.__killImageNode,
+ lambda: self._sendTouchEvents((
+ (1, avg.Event.CURSOR_UP, 30, 10),
+ (2, avg.Event.CURSOR_UP, 30, 20))),
+ ))
+
+ # Test rel. coords.
+ root = self.loadEmptyScene()
+ div = avg.DivNode(parent=root, pos=(0,10))
+ image = avg.ImageNode(parent=div, href="rgb24-64x64.png")
+ self.__transformRecognizer = gesture.TransformRecognizer(image, friction=-1,
+ detectedHandler=onDetected, moveHandler=onMove, upHandler=onUp)
+ self.start(False,
+ (createTransTestFrames(),
+ createRotTestFrames(gesture.Transform((0,0), math.pi, 1, (0,5))),
+ createScaleTestFrames(gesture.Transform((0,5), 0, 2, (0,10))),
+ ))
+
+ # Test coordSysNode.
+ root = self.loadEmptyScene()
+ div = avg.DivNode(parent=root, pos=(0,10))
+ image = avg.ImageNode(parent=div, href="rgb24-64x64.png")
+ self.__transformRecognizer = gesture.TransformRecognizer(image, coordSysNode=div,
+ friction=-1,
+ detectedHandler=onDetected, moveHandler=onMove, upHandler=onUp)
+ self.start(False,
+ (createTransTestFrames(),
+ createRotTestFrames(gesture.Transform((0,0), math.pi, 1, (0,15))),
+ createScaleTestFrames(gesture.Transform((0,5), 0, 2, (0,20))),
+ ))
+
+ # Test friction
+ root = self.loadEmptyScene()
+ div = avg.DivNode(parent=root, pos=(0,10))
+ image = avg.ImageNode(parent=div, href="rgb24-64x64.png")
+ self.__transformRecognizer = gesture.TransformRecognizer(image, friction=0.01,
+ detectedHandler=onDetected, moveHandler=onMove, upHandler=onUp)
+ self.start(False,
+ (lambda: self._sendTouchEvent(1, avg.Event.CURSOR_DOWN, 10, 10),
+ lambda: self._sendTouchEvent(1, avg.Event.CURSOR_UP, 20, 10),
+ lambda: self._sendTouchEvent(1, avg.Event.CURSOR_DOWN, 10, 10),
+ lambda: self._sendTouchEvent(1, avg.Event.CURSOR_UP, 20, 10),
+ ))
+
+ # Test abort
+ self.__initImageScene()
+ self.__transformRecognizer = gesture.TransformRecognizer(self.image,
+ detectedHandler=onDetected, moveHandler=onMove, upHandler=onUp)
+ self.start(False,
+ (self.__transformRecognizer.abort,
+ lambda: self._sendTouchEvent(1, avg.Event.CURSOR_DOWN, 10, 10),
+ self.__transformRecognizer.abort,
+ lambda: self._sendTouchEvent(1, avg.Event.CURSOR_MOTION, 20, 10),
+ lambda: self._sendTouchEvent(1, avg.Event.CURSOR_UP, 30, 10),
+ lambda: checkTransform(gesture.Transform((0,0))),
+ self.__transformRecognizer.abort,
+ ))
+
+ # Test enable/disable
+ self.__initImageScene()
+ self.__transformRecognizer = gesture.TransformRecognizer(self.image, friction=-1,
+ detectedHandler=onDetected, moveHandler=onMove, upHandler=onUp)
+ self.start(False,
+ (# Regular disable
+ lambda: self.__transformRecognizer.enable(False),
+ lambda: self._sendTouchEvent(1, avg.Event.CURSOR_DOWN, 10, 10),
+ lambda: self._sendTouchEvent(1, avg.Event.CURSOR_MOTION, 20, 10),
+ lambda: self._sendTouchEvent(1, avg.Event.CURSOR_UP, 30, 10),
+ lambda: checkTransform(gesture.Transform((0,0))),
+ # Re-enable
+ lambda: self.__transformRecognizer.enable(True),
+ lambda: self._sendTouchEvent(1, avg.Event.CURSOR_DOWN, 10, 10),
+ lambda: self._sendTouchEvent(1, avg.Event.CURSOR_UP, 20, 10),
+ lambda: checkTransform(gesture.Transform((10,0))),
+ # Disable during gesture
+ lambda: self._sendTouchEvent(1, avg.Event.CURSOR_DOWN, 10, 10),
+ lambda: self.__transformRecognizer.enable(False),
+ lambda: self._sendTouchEvent(1, avg.Event.CURSOR_UP, 20, 10),
+ lambda: checkTransform(gesture.Transform((0,0))),
+ lambda: self.__transformRecognizer.enable(True),
+ ))
+
+ # Test enable/disable, friction
+ def disableDuringEnd():
+ self.__transformRecognizer.enable(False)
+
+ self.__initImageScene()
+ self.__transformRecognizer = gesture.TransformRecognizer(self.image, friction=1,
+ detectedHandler=onDetected, moveHandler=onMove, upHandler=onUp)
+ self.start(False,
+ (# Disable during end event
+ lambda: self._sendTouchEvent(1, avg.Event.CURSOR_DOWN, 10, 10),
+ lambda: self.__transformRecognizer.subscribe(gesture.Recognizer.END,
+ disableDuringEnd),
+ lambda: self._sendTouchEvent(1, avg.Event.CURSOR_UP, 10, 10),
+ None,
+ ))
+
+ # Test second down during inertia.
+ self.__initImageScene()
+ self.__transformRecognizer = gesture.TransformRecognizer(self.image,
+ friction=0.01, detectedHandler=onDetected, moveHandler=onMove,
+ upHandler=onUp)
+ self.start(False,
+ (
+ lambda: self._sendTouchEvent(1, avg.Event.CURSOR_DOWN, 10, 10),
+ lambda: self._sendTouchEvent(1, avg.Event.CURSOR_UP, 30, 10),
+ lambda: self._sendTouchEvent(1, avg.Event.CURSOR_DOWN, 30, 10),
+ ))
+ player.setFakeFPS(-1)
+
+ def testKMeans(self):
+ pts = [avg.Point2D(0,0), avg.Point2D(0,1)]
+ means = gesture.calcKMeans(pts)
+ self.assertEqual(means, ([0], [1]))
+
+ pts.append (avg.Point2D(0,4))
+ means = gesture.calcKMeans(pts)
+ self.assertEqual(means, ([0,1], [2]))
+
+
+ def testMat3x3(self):
+ t = gesture.Mat3x3.translate([1,0,1])
+ v = [1,0,1]
+ self.assertEqual(t.applyVec(v), [2,0,1])
+ r = gesture.Mat3x3.rotate(math.pi/2)
+ self.assertAlmostEqual(r.applyVec(v), [0,1,1])
+ self.assertAlmostEqual(t.applyMat(t).m, gesture.Mat3x3.translate([2,0,1]).m)
+ self.assertAlmostEqual(t.applyMat(r).m, gesture.Mat3x3([0,-1,1],[1,0,0]).m)
+ self.assertAlmostEqual(r.applyMat(t).m, gesture.Mat3x3([0,-1,0],[1,0,1]).m)
+ self.assertAlmostEqual(gesture.Mat3x3().m, gesture.Mat3x3().inverse().m)
+ m = gesture.Mat3x3([-1, 3, -3],
+ [ 0, -6, 5],
+ [-5, -3, 1])
+ im = gesture.Mat3x3([3./2, 1., -1./2],
+ [-25./6, -8./3, 5./6],
+ [-5., -3., 1.])
+ self.assertAlmostEqual(m.inverse().m, im.m)
+
+ image = avg.ImageNode(pos=(10,20), size=(30,40), angle=1.57,
+ href="rgb24alpha-64x64.png")
+ mat = gesture.Mat3x3.fromNode(image)
+ mat.setNodeTransform(image)
+ self.assertAlmostEqual(image.pos, (10,20))
+ self.assertAlmostEqual(image.size, (30,40))
+ self.assertAlmostEqual(image.angle, 1.57)
+
+ def __initImageScene(self):
+ root = self.loadEmptyScene()
+ self.image = avg.ImageNode(parent=root, href="rgb24-64x64.png")
+
+ def __killImageNode(self):
+ self.image.unlink(True)
+ self.image = None
+
+
+def gestureTestSuite(tests):
+ availableTests = (
+ "testTapRecognizer",
+ "testHoldRecognizer",
+ "testDoubletapRecognizer",
+ "testSwipeRecognizer",
+ "testSwipeRecognizerTwoFingers",
+ "testDragRecognizer",
+ "testDragRecognizerRelCoords",
+ "testDragRecognizerInitialEvent",
+ "testDragRecognizerCoordSysNode",
+ "testDragRecognizerCoordSysNodeParentUnlink",
+ "testDragRecognizerMinDist",
+ "testTransformRecognizer",
+ "testKMeans",
+ "testMat3x3",
+ )
+
+ return createAVGTestSuite(availableTests, GestureTestCase, tests)
diff --git a/src/test/ImageTest.py b/src/test/ImageTest.py
new file mode 100644
index 0000000..f59d4ad
--- /dev/null
+++ b/src/test/ImageTest.py
@@ -0,0 +1,583 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# libavg - Media Playback Engine.
+# Copyright (C) 2003-2014 Ulrich von Zadow
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Current versions can be found at www.libavg.de
+#
+
+
+import shutil
+
+from libavg import avg, player
+from testcase import *
+
+class ImageTestCase(AVGTestCase):
+ def __init__(self, testFuncName):
+ AVGTestCase.__init__(self, testFuncName)
+
+ def testImageHRef(self):
+ def createXmlNode(pos):
+ node = player.createNode(
+ """<image pos="%s" href="rgb24-32x32.png"/>"""%str(pos))
+ self.assertEqual(node.getMediaSize(), avg.Point2D(32, 32))
+ return node
+
+ def createDictNode(root, p):
+ node = avg.ImageNode(pos=p, href="rgb24-32x32.png", parent=root)
+ self.assertEqual(node.getMediaSize(), avg.Point2D(32, 32))
+ self.assertEqual(node.size, avg.Point2D(32, 32))
+ return node
+
+ def addNodes(y):
+ xmlNode = createXmlNode((16, y))
+ root.appendChild(xmlNode)
+
+ createDictNode(root, (48, y))
+
+ noAttachNode = createXmlNode((80, y))
+ noAttachNode.href = "rgb24alpha-32x32.png"
+ self.assertEqual(noAttachNode.getMediaSize(), avg.Point2D(32, 32))
+ self.assertEqual(noAttachNode.size, avg.Point2D(32,32))
+ root.appendChild(noAttachNode)
+
+ attachNode = createXmlNode((112, y))
+ root.appendChild(attachNode)
+ attachNode.href = "rgb24alpha-32x32.png"
+ self.assertEqual(attachNode.getMediaSize(), avg.Point2D(32, 32))
+ self.assertEqual(attachNode.size, avg.Point2D(32,32))
+
+ def setUnicodeHref():
+ if self._isCurrentDirWriteable():
+ # Can't check unicode filenames into svn or the windows client breaks.
+ # So we rename the file locally.
+ shutil.copyfile("media/oe.png", u"media/ö.png")
+ node = createXmlNode((16, 16))
+ root.appendChild(node)
+ node.href = u"ö.png"
+ os.remove(u"media/ö.png")
+
+ def compareUnicode():
+ if self._isCurrentDirWriteable():
+ self.compareImage("testImgHRef3")
+
+ root = self.loadEmptyScene()
+ addNodes(16)
+ self.start(False,
+ (lambda: self.compareImage("testImgHRef1"),
+ lambda: addNodes(48),
+ lambda: self.compareImage("testImgHRef2"),
+ setUnicodeHref,
+ compareUnicode
+ ))
+
+ def testImagePos(self):
+ def createXmlNode(pos):
+ return player.createNode(
+ """<image pos="%s" href="rgb24-32x32.png"/>"""%str(pos))
+
+ def createDictNode(root, p):
+ return avg.ImageNode(pos=p, href="rgb24-32x32.png", parent=root)
+
+ def illegalMove(node):
+ self.assertException(node.pos.x == 23)
+ self.assertException(node.pos.y == 23)
+
+ def addNodes(y):
+ xmlNode = createXmlNode((16, y))
+ root.appendChild(xmlNode)
+ createDictNode(root, (48, y))
+ noAttachNode = createXmlNode((0, 0))
+ noAttachNode.pos = avg.Point2D(80, y)
+ illegalMove(noAttachNode)
+ root.appendChild(noAttachNode)
+ attachNode = createXmlNode((0, 0))
+ root.appendChild(attachNode)
+ attachNode.pos = avg.Point2D(112, y)
+ illegalMove(attachNode)
+
+ root = self.loadEmptyScene()
+ addNodes(16)
+ self.start(False,
+ (lambda: self.compareImage("testImgPos1"),
+ lambda: addNodes(48),
+ lambda: self.compareImage("testImgPos2"),
+ ))
+
+ def testImageSize(self):
+ def createXmlNode(pos, size):
+ return player.createNode(
+ """<image pos="%s" size="%s" href="rgb24-64x64.png"/>"""
+ %(str(pos), str(size)))
+
+ def createDictNode(p, s):
+ return avg.ImageNode(pos=p, size=s, href="rgb24-64x64.png")
+
+ def addNodes(y):
+ xmlNode = createXmlNode((16, y), (32, 32))
+ self.assertEqual(xmlNode.size, avg.Point2D(32, 32))
+ root.appendChild(xmlNode)
+ dictNode = createDictNode((48, y), (32, 32))
+ self.assertEqual(dictNode.size, avg.Point2D(32, 32))
+ root.appendChild(dictNode)
+ noAttachNode = createXmlNode((80, y), (0, 0))
+ noAttachNode.size = avg.Point2D(32, 32)
+ self.assertEqual(noAttachNode.size, avg.Point2D(32, 32))
+ root.appendChild(noAttachNode)
+ attachNode = createXmlNode((112, y), (0, 0))
+ root.appendChild(attachNode)
+ attachNode.size = avg.Point2D(32, 32)
+ self.assertEqual(attachNode.size, avg.Point2D(32, 32))
+
+ root = self.loadEmptyScene()
+ addNodes(16)
+ self.start(False,
+ (lambda: self.compareImage("testImgSize1"),
+ lambda: addNodes(48),
+ lambda: self.compareImage("testImgSize2"),
+ ))
+
+ def testImageWarp(self):
+ def createNode(p):
+ return avg.ImageNode(pos=p, href="rgb24-32x32.png",
+ maxtilewidth=16, maxtileheight=8)
+
+ def moveVertex(node):
+ grid = node.getWarpedVertexCoords()
+ grid[0][1] = (grid[0][1][0]+0.25, grid[0][1][1]+0.25)
+ node.setWarpedVertexCoords(grid)
+
+ def testEarlyAccessException():
+ node = createNode((16, 16))
+ root.appendChild(node)
+ self.assertException(node.getWarpedVertexCoords)
+ node.unlink()
+
+ def addNode():
+ self.node = createNode((16, 16))
+ root.appendChild(self.node)
+ moveVertex(self.node)
+
+ def changeHref():
+ self.node.href = "rgb24-65x65.png"
+ grid = self.node.getWarpedVertexCoords()
+ self.assert_(len(grid) == 10)
+ self.assert_(len(grid[0]) == 6)
+
+
+ root = self.loadEmptyScene()
+ testEarlyAccessException()
+ self.start(False,
+ (lambda: addNode(),
+ lambda: self.compareImage("testImgWarp1"),
+ lambda: changeHref(),
+ lambda: self.compareImage("testImgWarp2"),
+ ))
+
+ def testBitmap(self):
+ def getBitmap(node):
+ bmp = node.getBitmap()
+ self.assertEqual(bmp.getSize(), (65,65))
+ self.assert_(bmp.getFormat() == avg.R8G8B8X8 or
+ bmp.getFormat() == avg.B8G8R8X8)
+ node.setBitmap(bmp)
+ self.assertEqual(node.getMediaSize(), (65,65))
+
+ def loadFromBitmap(p, orighref):
+ node = avg.ImageNode(pos=p, size=(32, 32), href=orighref)
+ bmp = avg.Bitmap('media/rgb24-65x65.png')
+ self.assertEqual(bmp.getSize(), (65,65))
+ node.setBitmap(bmp)
+ self.assertEqual(node.getMediaSize(), (65,65))
+ root.appendChild(node)
+
+ def testStringConversion():
+ bmp = avg.Bitmap('media/rgb24-65x65.png')
+ s = bmp.getPixels()
+ bmp1 = avg.Bitmap(bmp.getSize(), bmp.getFormat(), "sample")
+ bmp1.setPixels(s)
+ self.assert_(self.areSimilarBmps(bmp, bmp1, 0.01, 0.01))
+
+ def testCropRect():
+ bmp = avg.Bitmap('media/rgb24-65x65.png')
+ bmp1 = avg.Bitmap(bmp, (32,32), (64,64))
+ self.assert_(bmp1.getSize() == (32,32))
+ node = avg.ImageNode(pos=(96,0), parent=root)
+ node.setBitmap(bmp1)
+
+ def testBlt():
+ srcBmp = avg.Bitmap('media/rgb24-65x65.png')
+ destBmp = avg.Bitmap((65,65), srcBmp.getFormat(), "bmp")
+ destBmp.blt(srcBmp, (0,0))
+ destBmp.blt(srcBmp, (32,32))
+ node = avg.ImageNode(pos=(96,32), size=(32,32), parent=root)
+ node.setBitmap(destBmp)
+
+ def testResize():
+ srcBmp = avg.Bitmap('media/rgb24-32x32.png')
+ destBmp = srcBmp.getResized((64,64))
+ self.assert_(destBmp.getSize() == (64,64))
+ node = avg.ImageNode(pos=(128,0), size=(32,32), parent=root)
+ node.setBitmap(destBmp)
+
+ def testUnicode():
+ if self._isCurrentDirWriteable():
+ # Can't check unicode filenames into svn or the windows client breaks.
+ # So we rename the file locally.
+ shutil.copyfile("media/oe.png", u"media/ö.png")
+ avg.Bitmap(u"media/ö.png")
+ os.remove(u"media/ö.png")
+
+ def testGetPixel():
+ bmp = avg.Bitmap('media/rgb24-65x65.png')
+ self.assertEqual(bmp.getPixel((1,1)), (255,0,0,255))
+ self.assertEqual(bmp.getPixel((33,1)), (0,255,0,255))
+ bmp = avg.Bitmap('media/rgb24alpha-64x64.png')
+ self.assertEqual(bmp.getPixel((1,1)), (0,0,0,0))
+ self.assertEqual(bmp.getPixel((63,1)), (83,255,83,142))
+ bmp = avg.Bitmap('media/greyscale.png')
+ self.assertEqual(bmp.getPixel((1,1)), (255,255,255,255))
+ self.assertEqual(bmp.getPixel((1,63)), (0,0,0,255))
+ self.assertException(lambda: bmp.getPixel((64,0)))
+
+ def setNullBitmap():
+ node.setBitmap(None)
+
+ def testSubBitmap():
+ srcBmp = avg.Bitmap('media/rgb24-32x32.png')
+ destBmp = avg.Bitmap(srcBmp, (16,16), (32,32))
+ self.assertEqual(srcBmp.getPixel((16,16)), destBmp.getPixel((0,0)))
+ self.assertException(lambda: avg.Bitmap(srcBmp, (16,16), (16,32)))
+
+ node = avg.ImageNode(href="media/rgb24-65x65.png", size=(32, 32))
+ getBitmap(node)
+
+ root = self.loadEmptyScene()
+ node = avg.ImageNode(pos=(0,0), size=(32, 32), href="rgb24-65x65.png")
+ root.appendChild(node)
+ getBitmap(node)
+ self.assertEqual(node.size, (32,32))
+ loadFromBitmap((32,0), "")
+ loadFromBitmap((64,0), "rgb24alpha-64x64.png")
+ testStringConversion()
+ testUnicode()
+ self.start(False,
+ (lambda: getBitmap(node),
+ lambda: loadFromBitmap((32,32), ""),
+ lambda: loadFromBitmap((64,32), "rgb24alpha-64x64.png"),
+ lambda: self.compareImage("testBitmap1"),
+ testCropRect,
+ lambda: self.compareImage("testBitmap2"),
+ testBlt,
+ lambda: self.compareImage("testBitmap3"),
+ testResize,
+ lambda: self.compareImage("testBitmap4"),
+ testGetPixel,
+ lambda: self.assertException(setNullBitmap),
+ testSubBitmap,
+ ))
+
+ def testBitmapManager(self):
+ WAIT_TIMEOUT = 2000
+ def expectException(returnValue, nextAction):
+ if isinstance(returnValue, Exception):
+ nextAction()
+ else:
+ raise RuntimeError("Expected exception, got %s (%s)" % (
+ returnValue, type(returnValue)))
+
+ def loadValidBitmap():
+ def validBitmapCb(bitmap):
+ self.assert_(not isinstance(bitmap, Exception))
+ player.setTimeout(0, loadBitmapWithPixelFormat)
+
+ avg.BitmapManager.get().loadBitmap("media/rgb24alpha-64x64.png",
+ validBitmapCb)
+
+ def loadBitmapWithPixelFormat():
+ def validBitmapCb(bitmap):
+ self.assert_(not isinstance(bitmap, Exception))
+ self.assert_(bitmap.getFormat() == avg.B5G6R5)
+ player.setTimeout(0, loadUnexistentBitmap)
+
+ avg.BitmapManager.get().loadBitmap("media/rgb24alpha-64x64.png",
+ validBitmapCb, avg.B5G6R5)
+
+ def loadUnexistentBitmap():
+ avg.BitmapManager.get().loadBitmap("nonexistent.png",
+ lambda bmp: expectException(
+ returnValue=bmp,
+ nextAction=lambda: player.setTimeout(0, loadBrokenBitmap)))
+
+ def loadBrokenBitmap():
+ import tempfile
+ tempFileName = os.path.join(tempfile.gettempdir(),
+ "broken.png")
+ open(tempFileName, "w")
+
+ def cleanupAndTestReturnValue(returnValue):
+ os.unlink(tempFileName)
+ expectException(returnValue=returnValue, nextAction=player.stop)
+
+ avg.BitmapManager.get().loadBitmap(tempFileName,
+ cleanupAndTestReturnValue)
+
+ def reportStuck():
+ raise RuntimeError("BitmapManager didn't reply "
+ "within %dms timeout" % WAIT_TIMEOUT)
+ player.stop()
+
+ for multithread in [False, True]:
+ self.loadEmptyScene()
+ if multithread:
+ avg.BitmapManager.get().setNumThreads(2)
+ player.setTimeout(WAIT_TIMEOUT, reportStuck)
+ player.setResolution(0, 0, 0, 0)
+ loadValidBitmap()
+ player.play()
+ avg.BitmapManager.get().setNumThreads(1)
+
+ def testBitmapManagerException(self):
+ def bitmapCb(bitmap):
+ raise RuntimeError
+
+ self.loadEmptyScene()
+ avg.BitmapManager.get().loadBitmap("rgb24alpha-64x64.png", bitmapCb),
+ self.assertException(player.play)
+
+ def testBlendMode(self):
+ def isBlendMinMaxSupported():
+ def tryInsertNode():
+ try:
+ avg.ImageNode(href="rgb24-65x65.png", blendmode="min", parent=root)
+ except RuntimeError:
+ self.supported = False
+ root = self.loadEmptyScene()
+ self.supported = True
+ self.start(False,
+ (tryInsertNode,
+ ))
+ return self.supported
+
+
+ def setBlendMode():
+ blendNode.blendmode="add"
+
+ if not(isBlendMinMaxSupported()):
+ self.skip("Blend modes min and max not supported.")
+ return
+ root = self.loadEmptyScene()
+ avg.ImageNode(href="freidrehen.jpg", parent=root)
+ blendNode = avg.ImageNode(opacity=0.6, href="rgb24-65x65.png", parent=root)
+ avg.ImageNode(pos=(0,48), opacity=0.6, href="rgb24-65x65.png", blendmode="add",
+ parent=root)
+ avg.ImageNode(pos=(48,0), opacity=1, href="rgb24-65x65.png", blendmode="min",
+ parent=root)
+ avg.ImageNode(pos=(48,48), opacity=1, href="rgb24-65x65.png", blendmode="max",
+ parent=root)
+
+ self.start(False,
+ (lambda: self.compareImage("testBlend1"),
+ setBlendMode,
+ lambda: self.compareImage("testBlend2")
+ ))
+
+ def testImageMask(self):
+ def createNode(p):
+ node = avg.ImageNode(href="rgb24-65x65.png", maskhref="mask.png",
+ pos=p, size=(32, 32))
+ root.appendChild(node)
+
+ def setNoAttach(p):
+ node = avg.ImageNode(href="rgb24-65x65.png", pos=p, size=(32, 32))
+ node.maskhref = "mask.png"
+ root.appendChild(node)
+
+ def setAttach(p):
+ node = avg.ImageNode(href="rgb24-65x65.png", pos=p, size=(32, 32))
+ root.appendChild(node)
+ node.maskhref = "mask.png"
+
+ def changeHRef():
+ node.maskhref = "mask2.png"
+
+ def changeBaseHRef():
+ node.href = "greyscale.png"
+
+ def setMaskNotFound():
+ node.maskhref = "nonexistentmask.png"
+
+ root = self.loadEmptyScene()
+ createNode((0,0))
+ node = root.getChild(0)
+ setNoAttach((32,0))
+ setAttach((64,0))
+ self.start(False,
+ (lambda: createNode((0, 32)),
+ lambda: setNoAttach((32,32)),
+ lambda: setAttach((64,32)),
+ lambda: self.compareImage("testImgMask1"),
+ changeHRef,
+ lambda: self.compareImage("testImgMask2"),
+ changeBaseHRef,
+ lambda: self.compareImage("testImgMask3"),
+ setMaskNotFound
+ ))
+
+ def testImageMaskCanvas(self):
+ root = self.loadEmptyScene()
+ canvas = player.createCanvas(id="testcanvas", size=(64,64), mediadir="media")
+ avg.ImageNode(href="rgb24-64x64.png", parent=canvas.getRootNode())
+ avg.RectNode(size=(160,120), fillcolor="FFFFFF", fillopacity=1, parent=root)
+ avg.ImageNode(href="canvas:testcanvas", maskhref="mask.png", parent=root)
+ self.start(False,
+ (lambda: self.compareImage("testImgMaskCanvas"),))
+
+ def testImageMaskPos(self):
+ def createNode(p):
+ node = avg.ImageNode(href="rgb24-65x65.png", maskhref="mask.png",
+ pos=p, size=(32, 32), maskpos=(32, 32))
+ root.appendChild(node)
+
+ def setNoAttach(p):
+ node = avg.ImageNode(href="rgb24-65x65.png", maskhref="mask.png",
+ pos=p, size=(32, 32))
+ node.maskpos = (32, 32)
+ root.appendChild(node)
+
+ def setAttach(p):
+ node = avg.ImageNode(href="rgb24-65x65.png", maskhref="mask.png",
+ pos=p, size=(32, 32))
+ root.appendChild(node)
+ node.maskpos = (32, 32)
+
+ root = self.loadEmptyScene()
+ createNode((0,0))
+ setNoAttach((32,0))
+ setAttach((64,0))
+ self.start(False,
+ (lambda: createNode((0, 32)),
+ lambda: setNoAttach((32,32)),
+ lambda: setAttach((64,32)),
+ lambda: self.compareImage("testImgMaskPos")
+ ))
+
+ def testImageMaskSize(self):
+ def createNode(p):
+ avg.ImageNode(href="rgb24-65x65.png", maskhref="mask.png",
+ pos=p, size=(32, 32), masksize=(48, 48), parent=root)
+
+ def setNoAttach(p):
+ node = avg.ImageNode(href="rgb24-65x65.png", maskhref="mask.png",
+ pos=p, size=(32, 32))
+ node.masksize = (48, 48)
+ root.appendChild(node)
+
+ def setAttach(p):
+ node = avg.ImageNode(href="rgb24-65x65.png", maskhref="mask.png",
+ pos=p, size=(32, 32), parent=root)
+ node.masksize = (48, 48)
+
+ def setPos():
+ node.maskpos = (16, 16)
+
+ def resetPos():
+ node.maskpos = (0, 0)
+ node.masksize = (0, 0)
+
+ root = self.loadEmptyScene()
+ createNode((0,0))
+ node = root.getChild(0)
+ setNoAttach((32,0))
+ setAttach((64,0))
+ self.start(False,
+ (lambda: createNode((0, 32)),
+ lambda: setNoAttach((32,32)),
+ lambda: setAttach((64,32)),
+ lambda: self.compareImage("testImgMaskSize1"),
+ setPos,
+ lambda: self.compareImage("testImgMaskSize2"),
+ resetPos,
+ lambda: self.compareImage("testImgMaskSize3")
+ ))
+
+ def testImageMipmap(self):
+ root = self.loadEmptyScene()
+ avg.ImageNode(size=(64,64), href="checker.png", mipmap=True, parent=root)
+ self.start(False,
+ (lambda: self.compareImage("testMipmap"),))
+
+ def testImageCompression(self):
+ def loadBitmap():
+ bmp = avg.Bitmap("media/colorramp.png")
+ self.image.setBitmap(bmp)
+
+ def relink():
+ self.image.unlink(False)
+ root.appendChild(self.image)
+
+ def checkAlpha():
+ self.image.href="rgb24alpha-64x64.png"
+
+ root = self.loadEmptyScene()
+ self.image = avg.ImageNode(href="rgb24-64x64.png", compression="B5G6R5",
+ parent=root)
+ self.assertEqual(self.image.compression, "B5G6R5")
+ self.start(False,
+ [lambda: self.compareImage("testTexCompression1"),
+ loadBitmap,
+ lambda: self.compareImage("testTexCompression2"),
+ relink,
+ lambda: self.compareImage("testTexCompression2"),
+ checkAlpha,
+ ])
+
+ def testSpline(self):
+ spline = avg.CubicSpline([(0,3),(1,2),(2,1),(3,0)])
+ self.assertAlmostEqual(spline.interpolate(0), 3)
+ self.assertAlmostEqual(spline.interpolate(0.5), 2.5)
+ self.assertAlmostEqual(spline.interpolate(1), 2)
+ self.assertAlmostEqual(spline.interpolate(-1), 4)
+ self.assertAlmostEqual(spline.interpolate(4), -1)
+
+ spline = avg.CubicSpline([(2,0),(4,1),(6,3),(8,6)])
+ self.assertAlmostEqual(spline.interpolate(2), 0)
+ self.assert_(spline.interpolate(3) < 0.5)
+ self.assert_(spline.interpolate(3) > 0.0)
+ self.assert_(spline.interpolate(7) < 4.5)
+ self.assert_(spline.interpolate(7) > 4)
+
+
+def imageTestSuite(tests):
+ availableTests = (
+ "testImageHRef",
+ "testImagePos",
+ "testImageSize",
+ "testImageWarp",
+ "testBitmap",
+ "testBitmapManager",
+ "testBitmapManagerException",
+ "testBlendMode",
+ "testImageMask",
+ "testImageMaskCanvas",
+ "testImageMaskPos",
+ "testImageMaskSize",
+ "testImageMipmap",
+ "testImageCompression",
+ "testSpline",
+ )
+ return createAVGTestSuite(availableTests, ImageTestCase, tests)
diff --git a/src/test/InputDeviceTest.py b/src/test/InputDeviceTest.py
new file mode 100644
index 0000000..c6350cb
--- /dev/null
+++ b/src/test/InputDeviceTest.py
@@ -0,0 +1,218 @@
+# -*- coding: utf-8 -*-
+# libavg - Media Playback Engine.
+# Copyright (C) 2003-2014 Ulrich von Zadow
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Current versions can be found at www.libavg.de
+#
+
+from libavg import avg, player
+from testcase import *
+
+
+class CustomMouseEvent(avg.TouchEvent):
+ def __init__(self, eventId, eventType, pos, source):
+ super(CustomMouseEvent, self).__init__(eventId, eventType, pos, source)
+ self.customAttribute = None
+
+ def customMethod(self):
+ pass
+
+
+class CustomInputDevice(avg.InputDevice):
+ def __init__(self, eventReceiverNode=None):
+ if eventReceiverNode:
+ super(CustomInputDevice, self).__init__(self.__class__.__name__,
+ eventReceiverNode)
+ else:
+ super(CustomInputDevice, self).__init__(self.__class__.__name__)
+
+ self.__events = []
+
+ def pollEvents(self):
+ events = self.__events[:]
+ self.__events = []
+ return events
+
+ def feedEvent(self, event):
+ self.__events.append(event)
+
+
+class AnonymousInputDevice(avg.InputDevice):
+ def __init__(self, eventReceiverNode=None):
+ if eventReceiverNode:
+ super(AnonymousInputDevice, self).__init__(self.__class__.__name__,
+ eventReceiverNode)
+ else:
+ super(AnonymousInputDevice, self).__init__(self.__class__.__name__)
+
+ self.__isInitialized = False
+
+ def pollEvents(self):
+ if self.__isInitialized: return []
+ self.__isInitialized = True
+ return [ avg.Event(avg.Event.CUSTOM_EVENT, avg.Event.CUSTOM) ]
+
+
+class EventTestCase(AVGTestCase):
+ def __init__(self, testFuncName):
+ AVGTestCase.__init__(self, testFuncName)
+
+ def testCustomInputDevice(self):
+ root = self.loadEmptyScene()
+
+ class DerivedEvent(avg.Event):
+ def __init__(self):
+ super(DerivedEvent, self).__init__(avg.Event.CUSTOM_EVENT, avg.Event.NONE)
+ self.property = True
+
+ class CustomMouseEvent(avg.TouchEvent):
+ def __init__(self):
+ super(CustomMouseEvent, self).__init__(42, avg.Event.CURSOR_DOWN,
+ (10, 10), avg.Event.TOUCH)
+ self.customAttribute = None
+
+ self.hasEventHandlerBeenCalled = False
+ self.isCustomInputDeviceSet = False
+ self.isCustomInputDeviceNameSet = False
+ self.hasCustomEventProperty = False
+ self.customMouseEventHandlerCalled = False
+
+ def eventHandler(event):
+ self.hasEventHandlerBeenCalled = True
+ self.isCustomInputDeviceSet = event.inputdevice == self.customInputDevice
+ self.isCustomInputDeviceNameSet = (event.inputdevicename ==
+ self.customInputDevice.name)
+
+ def customEventEventHandler(event):
+ self.hasCustomEventProperty = event.property
+
+ def customMouseEventHandler(event):
+ self.customMouseEventHandlerCalled = True
+ self.assert_(hasattr(event, "customAttribute"))
+
+ def checkAndResetResults():
+ if not self.hasEventHandlerBeenCalled: return False
+ if not self.isCustomInputDeviceSet: return False
+ if not self.isCustomInputDeviceNameSet: return False
+
+ self.hasEventHandlerBeenCalled = False
+ self.isCustomInputDeviceSet = False
+ self.isCustomInputDeviceNameSet = False
+ return True
+
+ rectNode = avg.RectNode(parent=root, pos=(0, 0), size=(50, 50))
+ rectNode.subscribe(avg.Node.CURSOR_DOWN, eventHandler)
+
+ root.subscribe(avg.Node.CURSOR_DOWN, eventHandler)
+ root.setEventHandler(avg.Event.CUSTOM_EVENT, avg.Event.NONE,
+ customEventEventHandler)
+
+ self.customInputDevice = CustomInputDevice()
+ player.addInputDevice(self.customInputDevice)
+
+ self.start(False,
+ (lambda: self.customInputDevice.feedEvent(
+ avg.Event(avg.Event.CURSOR_DOWN, avg.Event.MOUSE)),
+ lambda: self.assert_(checkAndResetResults()),
+
+ lambda: self.customInputDevice.feedEvent(
+ DerivedEvent()),
+ lambda: self.assert_(self.hasCustomEventProperty),
+
+ lambda: self.customInputDevice.feedEvent(
+ avg.MouseEvent(avg.Event.CURSOR_DOWN, False, False, False,
+ (5, 5), 0)),
+ lambda: self.assert_(checkAndResetResults()),
+
+ lambda: self.customInputDevice.feedEvent(
+ avg.TouchEvent(300, avg.Event.CURSOR_DOWN, (5, 5),
+ avg.Event.TOUCH, (10,10))),
+ lambda: self.assert_(checkAndResetResults()),
+
+ lambda: root.subscribe(avg.Node.CURSOR_DOWN, customMouseEventHandler),
+ lambda: self.customInputDevice.feedEvent(CustomMouseEvent()),
+ lambda: self.assert_(self.customMouseEventHandlerCalled),
+ ))
+
+ def testAnonymousInputDevice(self):
+ root = self.loadEmptyScene()
+
+ self.hasEventHandlerBeenCalled = False
+
+ def eventHandler(event):
+ self.hasEventHandlerBeenCalled = (event.inputdevicename ==
+ AnonymousInputDevice.__name__)
+
+ def checkAndResetResults():
+ if not self.hasEventHandlerBeenCalled:
+ return False
+
+ self.hasEventHandlerBeenCalled = False
+ return True
+
+ root.setEventHandler(avg.Event.CUSTOM_EVENT, avg.Event.CUSTOM, eventHandler)
+ player.addInputDevice(AnonymousInputDevice())
+
+ self.start(False,
+ (lambda: None,
+ lambda: None,
+ lambda: self.assert_(checkAndResetResults())
+ ))
+
+ def testInputDeviceEventReceiverNode(self):
+ root = self.loadEmptyScene()
+
+ divNode = avg.DivNode(id="div", size=(50, 50), parent=root)
+ rectNode = avg.RectNode(id="rect", size=(50, 50), parent=root)
+
+ self.customInputDevice = CustomInputDevice(divNode)
+ player.addInputDevice(self.customInputDevice)
+
+ handlerTester = NodeHandlerTester(self, divNode)
+
+ self.start(False,
+ (lambda: self.customInputDevice.feedEvent(
+ avg.MouseEvent(avg.Event.CURSOR_DOWN, True, False, False,
+ (10, 10), 1)),
+ lambda: handlerTester.assertState(
+ (avg.Node.CURSOR_DOWN, avg.Node.CURSOR_OVER)),
+
+ lambda: self.customInputDevice.feedEvent(avg.MouseEvent(
+ avg.Event.CURSOR_MOTION, True, False, False, (12, 12), 1)),
+ lambda: handlerTester.assertState((avg.Node.CURSOR_MOTION,)),
+
+ lambda: self.customInputDevice.feedEvent(avg.MouseEvent(
+ avg.Event.CURSOR_MOTION, True, False, False, (100, 100), 1)),
+ lambda: handlerTester.assertState((avg.Node.CURSOR_OUT,)),
+
+ lambda: self.customInputDevice.feedEvent(avg.MouseEvent(
+ avg.Event.CURSOR_MOTION, True, False, False, (12, 12), 1)),
+ lambda: handlerTester.assertState(
+ (avg.Node.CURSOR_OVER, avg.Node.CURSOR_MOTION)),
+
+ lambda: self.customInputDevice.feedEvent(avg.MouseEvent(
+ avg.Event.CURSOR_UP, False, False, False, (12, 12), 1)),
+ lambda: handlerTester.assertState((avg.Node.CURSOR_UP,)),
+ ))
+
+def inputDeviceTestSuite(tests):
+ availableTests = (
+ "testCustomInputDevice",
+ "testAnonymousInputDevice",
+ "testInputDeviceEventReceiverNode"
+ )
+ return createAVGTestSuite(availableTests, EventTestCase, tests)
diff --git a/src/test/LoggerTest.py b/src/test/LoggerTest.py
new file mode 100644
index 0000000..9848dcd
--- /dev/null
+++ b/src/test/LoggerTest.py
@@ -0,0 +1,96 @@
+# -*- coding: utf-8 -*-
+# libavg - Media Playback Engine.
+# Copyright (C) 2003-2014 Ulrich von Zadow
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Current versions can be found at www.libavg.de
+#
+
+import StringIO
+import logging
+
+from libavg import logger
+
+from testcase import *
+
+
+class LoggerTestCase(AVGTestCase):
+ def __init__(self, testFuncName):
+ AVGTestCase.__init__(self, testFuncName)
+ self.testMsg = u'福 means good fortune'
+
+ def setUp(self):
+ self.stream = StringIO.StringIO()
+ self.hdlr = logging.StreamHandler(self.stream)
+ self.pyLogger = logging.getLogger(__name__)
+ self.pyLogger.addHandler(self.hdlr)
+ self.pyLogger.propagate = False
+ self.pyLogger.level = logging.DEBUG
+ logger.addSink(self.pyLogger)
+ logger.removeStdLogSink()
+
+ def tearDown(self):
+ self.pyLogger.removeHandler(self.hdlr)
+
+ def _assertMsg(self):
+ self.stream.flush()
+ self.assert_(self.stream.getvalue().decode('utf8').find(self.testMsg) != -1)
+ self.stream.close()
+
+ def _assertNoMsg(self):
+ self.stream.flush()
+ self.assert_(self.stream.getvalue().decode('utf8').find(self.testMsg) == -1)
+ self.stream.close()
+
+ def testRemoveSink(self):
+ logger.removeSink(self.pyLogger)
+ logger.info(self.testMsg)
+ self._assertNoMsg()
+
+ def testConfigureCategory(self):
+ snowmanCategory = logger.configureCategory(u'☃ Category')
+ logger.warning(self.testMsg, snowmanCategory)
+ self._assertMsg()
+
+ def testReconfigureCategory(self):
+ snowmanCategory = logger.configureCategory(u'☃ Category', logger.Severity.INFO)
+ logger.info(self.testMsg, snowmanCategory)
+ self._assertMsg()
+
+ def testOmitCategory(self):
+ logger.configureCategory(logger.Category.APP, logger.Severity.CRIT)
+ logger.info(self.testMsg)
+ self._assertNoMsg()
+
+ def testLogCategory(self):
+ logger.configureCategory(logger.Category.APP, logger.Severity.INFO)
+ logger.info(self.testMsg)
+ self._assertMsg()
+
+ def testUnknownCategoryWarning(self):
+ self.assertException(lambda: logger.error("Foo", "Bar"))
+
+
+def loggerTestSuite(tests):
+ availableTests = (
+ "testRemoveSink",
+ "testConfigureCategory",
+ "testReconfigureCategory",
+ "testOmitCategory",
+ "testLogCategory",
+ "testUnknownCategoryWarning",
+ )
+ return createAVGTestSuite(availableTests, LoggerTestCase, tests)
diff --git a/src/test/Makefile.am b/src/test/Makefile.am
new file mode 100644
index 0000000..27b0e90
--- /dev/null
+++ b/src/test/Makefile.am
@@ -0,0 +1,9 @@
+SUBDIRS = plugin
+
+pkgpyexec_PYTHON = testcase.py testapp.py
+
+EXTRA_DIST = $(wildcard *.avg) $(wildcard *.png) $(wildcard *.jpg) $(wildcard *.tif) \
+ $(wildcard *.py) $(wildcard baseline/*.png) $(wildcard testmediadir/*) \
+ $(wildcard extrafonts) $(wildcard fonts) $(wildcard *.svg) $(wildcard media/*)
+
+TESTS = Test.py
diff --git a/src/test/OffscreenTest.py b/src/test/OffscreenTest.py
new file mode 100644
index 0000000..76bff52
--- /dev/null
+++ b/src/test/OffscreenTest.py
@@ -0,0 +1,472 @@
+# -*- coding: utf-8 -*-
+# libavg - Media Playback Engine.
+# Copyright (C) 2003-2014 Ulrich von Zadow
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Current versions can be found at www.libavg.de
+#
+
+from libavg import avg, player
+from testcase import *
+import gc
+
+class OffscreenTestCase(AVGTestCase):
+ def __init__(self, testFuncName):
+ AVGTestCase.__init__(self, testFuncName)
+
+ def testCanvasBasics(self):
+ def createCanvas(isFirst, canvasName, x):
+ canvas = self.__createOffscreenCanvas(canvasName, False)
+ canvas.getElementByID("test1").x = x
+ node = avg.ImageNode(parent=root, id="imagenode")
+ node.href="canvas:"+canvasName
+ if isFirst:
+ self.assertEqual(canvas.getNumDependentCanvases(), 0)
+ self.canvas1 = canvas
+ else:
+ self.assertEqual(canvas.getNumDependentCanvases(), 1)
+ self.canvas2 = canvas
+
+ def unlink():
+ self.node = player.getElementByID("imagenode")
+ self.node.unlink()
+ self.assertEqual(self.canvas1.getNumDependentCanvases(), 0)
+ gc.collect()
+
+ def relink():
+ root.appendChild(self.node)
+ self.node = None
+ self.assertEqual(self.canvas1.getNumDependentCanvases(), 1)
+
+ def changeHRef(href):
+ player.getElementByID("imagenode").href = href
+
+ def setBitmap():
+ bitmap = avg.Bitmap("media/rgb24-65x65.png")
+ player.getElementByID("imagenode").setBitmap(bitmap)
+
+ def deleteCanvases():
+ changeHRef("")
+ firstNode.href = ""
+ player.deleteCanvas("testcanvas1")
+# self.assertException(lambda: changeHRef("canvas:testcanvas1"))
+ changeHRef("canvas:testcanvas2")
+# self.assertException(lambda: player.deleteCanvas("testcanvas2"))
+ changeHRef("")
+ player.deleteCanvas("testcanvas2")
+# self.assertException(lambda: player.deleteCanvas("foo"))
+
+ root = self.loadEmptyScene()
+ root.mediadir = "media"
+ createCanvas(True, "testcanvas1", 0)
+ firstNode = player.getElementByID("imagenode")
+ self.start(False,
+ (lambda: self.compareImage("testOffscreen1"),
+ unlink,
+ lambda: self.compareImage("testOffscreen2"),
+ relink,
+ lambda: self.compareImage("testOffscreen1"),
+ unlink,
+ lambda: createCanvas(False, "testcanvas2", 80),
+ lambda: self.compareImage("testOffscreen3"),
+ lambda: changeHRef("canvas:testcanvas1"),
+ lambda: self.assertEqual(self.canvas1.getNumDependentCanvases(), 1),
+ lambda: self.assertEqual(self.canvas2.getNumDependentCanvases(), 0),
+ lambda: self.compareImage("testOffscreen1"),
+ lambda: changeHRef("rgb24-65x65.png"),
+ lambda: self.assertEqual(self.canvas1.getNumDependentCanvases(), 0),
+ lambda: self.compareImage("testOffscreen4"),
+ lambda: changeHRef("canvas:testcanvas1"),
+ lambda: self.assertEqual(self.canvas1.getNumDependentCanvases(), 1),
+ lambda: self.compareImage("testOffscreen1"),
+ setBitmap,
+ lambda: self.compareImage("testOffscreen4"),
+ deleteCanvases,
+ lambda: self.compareImage("testOffscreen5"),
+ ))
+
+ def testCanvasLoadAfterPlay(self):
+ def createOffscreenCanvas():
+ self.__createOffscreenCanvas("offscreencanvas", False)
+ self.node = avg.ImageNode(parent=root, href="canvas:offscreencanvas")
+
+ root = self.loadEmptyScene()
+ self.start(False,
+ (createOffscreenCanvas,
+ lambda: self.compareImage("testOffscreen1"),
+ ))
+
+ def testCanvasResize(self):
+ def setSize():
+ self.node.size = (80, 60)
+
+ mainCanvas, offscreenCanvas = self.__setupCanvas(False)
+ self.start(False,
+ (setSize,
+ lambda: self.compareImage("testCanvasResize")
+ ))
+
+ def testCanvasErrors(self):
+ self.loadEmptyScene()
+ # Missing size
+ self.assertException(
+ lambda: player.createCanvas(id="foo"))
+ # Duplicate canvas id
+ player.createCanvas(id="foo", size=(160, 120))
+ self.assertException(
+ lambda: player.createCanvas(id="foo", size=(160, 120)))
+
+ def testCanvasAPI(self):
+ def checkMainScreenshot():
+ bmp1 = player.screenshot()
+ bmp2 = mainCanvas.screenshot()
+ self.assert_(self.areSimilarBmps(bmp1, bmp2, 0.01, 0.01))
+
+ def checkCanvasScreenshot():
+ bmp = offscreenCanvas.screenshot()
+ self.compareBitmapToFile(bmp, "testOffscreenScreenshot")
+
+ def createCompressed():
+ avg.ImageNode(href="canvas:offscreencanvas", compression="B5G6R5",
+ parent=root)
+
+ root = self.loadEmptyScene()
+ mainCanvas = player.getMainCanvas()
+ self.assertEqual(mainCanvas.getRootNode(), root)
+ offscreenCanvas = self.__createOffscreenCanvas("offscreencanvas", False)
+ self.assertEqual(offscreenCanvas, player.getCanvas("offscreencanvas"))
+ self.assertEqual(offscreenCanvas.getElementByID("test1").href, "rgb24-65x65.png")
+ self.assertEqual(offscreenCanvas.getElementByID("missingnode"), None)
+ self.assertException(player.screenshot)
+ self.assertException(createCompressed)
+ self.start(False,
+ (checkMainScreenshot,
+ checkCanvasScreenshot))
+
+ def testCanvasEvents(self):
+ def onOffscreenImageDown(event):
+ self.__offscreenImageDownCalled = True
+
+ def onMainDown(event):
+ self.__mainDownCalled = True
+
+ def reset():
+ self.__offscreenImageDownCalled = False
+ self.__mainDownCalled = False
+
+ def setPos():
+ self.node.pos = (80, 60)
+ self.node.size = (80, 60)
+
+ mainCanvas, offscreenCanvas = self.__setupCanvas(True)
+ offscreenImage = offscreenCanvas.getElementByID("test1")
+ offscreenImage.subscribe(avg.Node.CURSOR_DOWN, onOffscreenImageDown)
+ player.getRootNode().subscribe(avg.Node.CURSOR_DOWN, onMainDown)
+ self.__offscreenImageDownCalled = False
+ self.__mainDownCalled = False
+ self.start(False,
+ (lambda: self.fakeClick(10, 10),
+ lambda: self.assert_(self.__offscreenImageDownCalled),
+ reset,
+ lambda: self.fakeClick(80, 10),
+ lambda: self.assert_(not(self.__offscreenImageDownCalled)),
+ reset,
+ setPos,
+ lambda: self.fakeClick(70, 65),
+ lambda: self.assert_(not(self.__offscreenImageDownCalled)),
+ lambda: self.fakeClick(120, 65),
+ lambda: self.assert_(not(self.__offscreenImageDownCalled)),
+ reset,
+ lambda: self.fakeClick(110, 65),
+ lambda: self.assert_(self.__offscreenImageDownCalled and
+ self.__mainDownCalled),
+ reset,
+ lambda: self.fakeClick(1, 1),
+ lambda: self.assert_(not(self.__offscreenImageDownCalled) and
+ self.__mainDownCalled),
+ ))
+
+ def testCanvasEventCapture(self):
+ def onOffscreenImageDown(event):
+ self.__offscreenImageDownCalled = True
+
+ mainCanvas, offscreenCanvas = self.__setupCanvas(True)
+ offscreenImage = offscreenCanvas.getElementByID("test1")
+ offscreenImage.subscribe(avg.Node.CURSOR_DOWN, onOffscreenImageDown);
+ self.__offscreenImageDownCalled = False
+ offscreenImage.setEventCapture()
+ self.start(False,
+ (lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 80, 10),
+ lambda: self.assert_(self.__offscreenImageDownCalled),
+ ))
+
+ def testCanvasRender(self):
+ def createCanvas():
+ canvas = player.createCanvas(id="testcanvas", size=(160,120),
+ mediadir="media", autorender=False)
+ avg.ImageNode(id="test", href="rgb24-65x65.png", parent=canvas.getRootNode())
+ return canvas
+
+ def testEarlyScreenshotException():
+ self.assertException(self.__offscreenCanvas.screenshot)
+
+ def renderCanvas():
+ self.__offscreenCanvas.render()
+ bmp = self.__offscreenCanvas.screenshot()
+ self.compareBitmapToFile(bmp, "testOffscreenScreenshot")
+
+ def deleteCanvas():
+ player.deleteCanvas("testcanvas")
+ self.__offscreenCanvas = None
+
+ def recreateCanvas():
+ self.__offscreenCanvas = createCanvas()
+
+ self.loadEmptyScene()
+ self.__offscreenCanvas = createCanvas()
+ self.assertException(renderCanvas)
+ self.start(False,
+ (testEarlyScreenshotException,
+ renderCanvas,
+ deleteCanvas,
+ recreateCanvas,
+ renderCanvas
+ ))
+
+ def testCanvasAutoRender(self):
+ def createCanvas():
+ canvas = self.__createOffscreenCanvas("testcanvas", False)
+ avg.ImageNode(href="canvas:testcanvas", parent=root)
+ return canvas
+
+ def disableAutoRender():
+ self.__offscreenCanvas.autorender = False
+
+ def enableAutoRender():
+ self.__offscreenCanvas.autorender = True
+
+ def changeContent():
+ self.__offscreenCanvas.getElementByID("test1").x = 42
+
+ root = self.loadEmptyScene()
+ self.__offscreenCanvas = createCanvas()
+ self.start(False,
+ (lambda: self.assert_(self.__offscreenCanvas.autorender),
+ lambda: self.compareImage("testOffscreenAutoRender1"),
+ disableAutoRender,
+ lambda: self.assert_(not(self.__offscreenCanvas.autorender)),
+ changeContent,
+ lambda: self.compareImage("testOffscreenAutoRender1"),
+ enableAutoRender,
+ lambda: self.assert_(self.__offscreenCanvas.autorender),
+ lambda: self.compareImage("testOffscreenAutoRender2")
+ ))
+
+ def testCanvasCrop(self):
+ root = self.loadEmptyScene()
+ canvas = player.createCanvas(id="testcanvas", size=(160,120),
+ mediadir="media")
+ div = avg.DivNode(pos=(40,30), size=(80,60), crop=True,
+ parent=canvas.getRootNode())
+ avg.ImageNode(id="test1", pos=(-32, -32), href="rgb24-65x65.png", parent=div)
+ avg.ImageNode(parent=root, href="canvas:testcanvas")
+ self.start(False, (lambda: self.compareImage("testCanvasCrop"),))
+
+ def testCanvasAlpha(self):
+ root = self.loadEmptyScene()
+ canvas = player.createCanvas(id="testcanvas", size=(80,120), mediadir="media")
+ avg.ImageNode(id="test1", href="rgb24alpha-64x64.png",
+ parent=canvas.getRootNode())
+ avg.RectNode(parent=root, fillcolor="FFFFFF",
+ pos=(0.5, 0.5), size=(160, 48), fillopacity=1)
+ avg.ImageNode(parent=root, href="canvas:testcanvas")
+ avg.ImageNode(parent=root, x=64, href="rgb24alpha-64x64.png")
+ self.start(False, (lambda: self.compareImage("testCanvasAlpha"),))
+
+ def testCanvasBlendModes(self):
+ def createBaseCanvas():
+ canvas = player.createCanvas(id="testcanvas", size=(64,64),
+ mediadir="media")
+ avg.ImageNode(href="rgb24alpha-64x64.png", parent=canvas.getRootNode())
+ return canvas
+
+ root = self.loadEmptyScene()
+ createBaseCanvas()
+ avg.RectNode(parent=root, pos=(48,0), size=(32, 120), strokewidth=2,
+ fillopacity=1, fillcolor="808080")
+ avg.ImageNode(parent=root, href="canvas:testcanvas")
+ avg.ImageNode(parent=root, pos=(0,64), href="canvas:testcanvas",
+ opacity=0.6)
+ avg.ImageNode(parent=root, pos=(64,0), href="canvas:testcanvas",
+ blendmode="add")
+ avg.ImageNode(parent=root, pos=(64,64), href="canvas:testcanvas",
+ opacity=0.6, blendmode="add")
+ self.start(False, (lambda: self.compareImage("testCanvasBlendModes"),))
+
+ def testCanvasMultisampling(self):
+ def testIllegalSamples(numSamples):
+ self.canvas = player.createCanvas(id="brokencanvas", size=(160,120),
+ multisamplesamples=numSamples)
+
+ def screenshot():
+ bmp = self.canvas.screenshot()
+ self.compareBitmapToFile(bmp, "testOffscreenMultisampleScreenshot")
+
+ def createCanvas():
+ if not(avg.OffscreenCanvas.isMultisampleSupported()):
+ self.skip("Offscreen multisampling not supported")
+ player.stop()
+ return
+ try:
+ self.canvas = player.createCanvas(id="testcanvas", size=(160,120),
+ mediadir="media", multisamplesamples=2)
+ avg.ImageNode(id="test1", href="rgb24-65x65.png", angle=0.1,
+ parent=self.canvas.getRootNode())
+ except RuntimeError:
+ self.skip("Offscreen multisampling init failed")
+ player.stop()
+ return
+ self.assertEqual(self.canvas.multisamplesamples, 2)
+ avg.ImageNode(parent=root, href="canvas:testcanvas")
+
+
+ root = self.loadEmptyScene()
+ self.start(False,
+ (createCanvas,
+ lambda: self.compareImage("testCanvasMultisample"),
+ screenshot,
+ lambda: self.assertException(lambda: testIllegalSamples(42)),
+ lambda: self.assertException(lambda: testIllegalSamples(0)),
+ ))
+ self.canvas = None
+
+ def testCanvasMipmap(self):
+ root = self.loadEmptyScene()
+
+ canvas = player.createCanvas(id="testcanvas", size=(80,120), mediadir="media",
+ mipmap=True)
+ avg.ImageNode(id="test1", href="rgb24alpha-64x64.png",
+ parent=canvas.getRootNode())
+ avg.ImageNode(parent=root, size=(40, 30), href="canvas:testcanvas")
+ try:
+ self.start(False, (lambda: self.compareImage("testCanvasMipmap"),))
+ except RuntimeError:
+ self.skip("Offscreen mipmap init failed.")
+ return
+
+ def testCanvasDependencies(self):
+ def makeCircularRef():
+ self.offscreen1.getElementByID("test1").href = "canvas:offscreencanvas2"
+
+ def makeSelfRef1():
+ avg.ImageNode(href="canvas:offscreencanvas1",
+ parent=self.offscreen1.getRootNode())
+
+ def makeSelfRef2():
+ self.offscreen1.getElementByID("test1").href = "canvas:offscreencanvas1"
+
+ def createTwoCanvases():
+ self.offscreen1 = self.__createOffscreenCanvas("offscreencanvas1", False)
+ self.offscreen2 = self.__createOffscreenCanvas("offscreencanvas2", False)
+ self.node = avg.ImageNode(parent=root,
+ href="canvas:offscreencanvas1")
+ node = self.offscreen1.getElementByID("test1")
+ node.href = "canvas:offscreencanvas2"
+ node.size = (80, 60)
+
+ def exchangeCanvases():
+ self.offscreen1.getElementByID("test1").href = "rgb24-65x65.png"
+ self.offscreen2.getElementByID("test1").href = "canvas:offscreencanvas1"
+ self.node.href = "canvas:offscreencanvas2"
+
+ def loadCanvasDepString():
+ player.createCanvas(id="canvas1", size=(160, 120))
+ canvas2 = player.createCanvas(id="canvas2", size=(160, 120))
+ avg.ImageNode(href="canvas:canvas1", parent=canvas2.getRootNode())
+ player.deleteCanvas('canvas2')
+ player.deleteCanvas('canvas1')
+
+ root = self.loadEmptyScene()
+ createTwoCanvases()
+ self.offscreen1.getElementByID("test1").href = ""
+ self.offscreen1 = None
+ self.offscreen2 = None
+ self.node.href = ""
+ self.node = None
+ player.deleteCanvas("offscreencanvas1")
+ player.deleteCanvas("offscreencanvas2")
+ self.start(False,
+ (createTwoCanvases,
+ lambda: self.compareImage("testCanvasDependencies1"),
+ exchangeCanvases,
+ lambda: self.compareImage("testCanvasDependencies2"),
+ lambda: self.assertException(makeCircularRef),
+ lambda: self.assertException(makeSelfRef1),
+ lambda: self.assertException(makeSelfRef2),
+ loadCanvasDepString,
+ ))
+
+ def __setupCanvas(self, handleEvents):
+ root = self.loadEmptyScene()
+ mainCanvas = player.getMainCanvas()
+ offscreenCanvas = self.__createOffscreenCanvas("offscreencanvas", handleEvents)
+ self.node = avg.ImageNode(parent=root, href="canvas:offscreencanvas")
+ return (mainCanvas, offscreenCanvas)
+
+ def __createOffscreenCanvas(self, canvasName, handleEvents):
+ canvas = player.createCanvas(id=canvasName, size=(160,120),
+ handleevents=handleEvents)
+ canvas.getRootNode().mediadir = "media"
+ avg.ImageNode(id="test1", href="rgb24-65x65.png", parent=canvas.getRootNode())
+ return canvas
+
+def isOffscreenSupported():
+
+ def testOffscreenSupported():
+ global offscreenSupported
+ offscreenSupported = avg.OffscreenCanvas.isSupported()
+ player.stop()
+
+ global offscreenSupported
+ sceneString = """<avg id="avg" width="160" height="120"/>"""
+ player.loadString(sceneString)
+ player.setTimeout(0, testOffscreenSupported)
+ player.play()
+ return offscreenSupported
+
+def offscreenTestSuite(tests):
+ if isOffscreenSupported():
+ availableTests = (
+ "testCanvasBasics",
+ "testCanvasLoadAfterPlay",
+ "testCanvasResize",
+ "testCanvasErrors",
+ "testCanvasAPI",
+ "testCanvasEvents",
+ "testCanvasEventCapture",
+ "testCanvasRender",
+ "testCanvasAutoRender",
+ "testCanvasCrop",
+ "testCanvasAlpha",
+ "testCanvasBlendModes",
+ "testCanvasMultisampling",
+ "testCanvasMipmap",
+ "testCanvasDependencies",
+ )
+ return createAVGTestSuite(availableTests, OffscreenTestCase, tests)
+ else:
+ sys.stderr.write("Skipping offscreen tests - no canvas support with this graphics configuration.\n")
+ return unittest.TestSuite()
diff --git a/src/test/PlayerTest.py b/src/test/PlayerTest.py
new file mode 100644
index 0000000..2443759
--- /dev/null
+++ b/src/test/PlayerTest.py
@@ -0,0 +1,853 @@
+# -*- coding: utf-8 -*-
+# libavg - Media Playback Engine.
+# Copyright (C) 2003-2014 Ulrich von Zadow
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Current versions can be found at www.libavg.de
+#
+
+import math
+import threading
+
+from libavg import avg, player
+from testcase import *
+
+class PlayerTestCase(AVGTestCase):
+ def __init__(self, testFuncName):
+ AVGTestCase.__init__(self, testFuncName)
+
+ def testPoint(self):
+ def testHash():
+ ptMap = {}
+ ptMap[avg.Point2D(0,0)] = 0
+ ptMap[avg.Point2D(1,0)] = 1
+ ptMap[avg.Point2D(0,0)] = 2
+ self.assertEqual(len(ptMap), 2)
+ self.assertEqual(ptMap[avg.Point2D(0,0)], 2)
+
+ def testToTupleConversion():
+ pt = avg.Point2D(10, 20)
+ tpl = tuple(pt)
+ self.assertEqual(pt.x, tpl[0])
+ self.assertEqual(pt.y, tpl[1])
+
+ def testFromTupleConversion():
+ tpl = (15, 20)
+ pt = avg.Point2D(tpl)
+ self.assertEqual(pt.x, tpl[0])
+ self.assertEqual(pt.y, tpl[1])
+
+ pt = avg.Point2D()
+ self.assertEqual(pt, avg.Point2D(0,0))
+ pt = avg.Point2D(10, 20)
+ self.assertEqual(pt[0], pt.x)
+ self.assertEqual(pt[1], pt.y)
+ pt = avg.Point2D(10, 10)
+ self.assertEqual(pt, avg.Point2D(10, 10))
+ self.assertEqual(pt, (10, 10))
+ self.assertEqual(pt, avg.Point2D([10, 10]))
+ self.assertNotEqual(pt, avg.Point2D(11, 10))
+ self.assertEqual(str(pt), "(10,10)")
+ pt2 = eval(repr(pt))
+ self.assertEqual(pt2, pt)
+ testHash()
+ testFromTupleConversion()
+ testToTupleConversion()
+ self.assertAlmostEqual(avg.Point2D(10,0).getNormalized(), avg.Point2D(1,0))
+ self.assertAlmostEqual(pt.getRotated(math.pi, (5,5)), avg.Point2D(0,0))
+ self.assertEqual(-pt, (-10, -10))
+ self.assertEqual(pt-(10,0), (0,10))
+ self.assertEqual(pt+(10,0), (20,10))
+ self.assertEqual(pt*2, (20,20))
+ self.assertEqual(2*pt, (20,20))
+ pt.x = 21
+ pt.y = 23
+ self.assertEqual(pt, avg.Point2D(21, 23))
+ pt.x -= 11
+ pt.y -= 13
+ pt += avg.Point2D(10, 10)
+ self.assertEqual(pt, avg.Point2D(20, 20))
+ pt -= avg.Point2D(6, 6)
+ self.assertEqual(pt, avg.Point2D(14, 14))
+ self.assertNotEqual(pt, avg.Point2D(13, 13))
+ pt = pt/2.
+ self.assertEqual(pt, avg.Point2D(7, 7))
+ pt = avg.Point2D((10, 10))
+ self.assertEqual(pt, (10, 10))
+ self.assertEqual(len(pt), 2)
+ self.assertEqual(pt[0], pt.x)
+ self.assertEqual(pt[1], pt.y)
+ self.assertException(lambda: pt[2])
+ self.assertAlmostEqual(avg.Point2D(10,0), avg.Point2D.fromPolar(0,10))
+ self.assertException(avg.Point2D(0,0).getNormalized)
+ self.assertException(lambda: avg.Point2D(0,))
+ self.assertException(lambda: avg.Point2D(0,1,2))
+ for point in ((10,0), (0,10), (-10,0), (0,-10)):
+ pt = avg.Point2D(point)
+ angle = pt.getAngle()
+ norm = pt.getNorm()
+ self.assertAlmostEqual(pt, avg.Point2D.fromPolar(angle,norm))
+
+ def testBasics(self):
+ def getFramerate():
+ framerate = player.getEffectiveFramerate()
+ self.assert_(framerate > 0)
+
+ def invalidCreateNode():
+ avg.ImageNode(1, 2, 3)
+
+ player.showCursor(0)
+ player.showCursor(1)
+ root = self.loadEmptyScene()
+ avg.ImageNode(href="rgb24-65x65.png", parent=root)
+ self.assertException(invalidCreateNode)
+ self.start(False,
+ (getFramerate,
+ lambda: self.compareImage("testbasics"),
+ lambda: player.setGamma(0.3, 0.3, 0.3),
+ lambda: player.showCursor(0),
+ lambda: player.showCursor(1),
+ ))
+
+ def testColorParse(self):
+ def setColor(colorName):
+ node.color = colorName
+
+ node = avg.LineNode(pos1=(0.5, 0), pos2=(0.5, 50), color="FF0000")
+ setColor("ff00ff")
+ self.assertException(lambda: setColor("foo"))
+ self.assertException(lambda: setColor("ff00f"))
+ self.assertException(lambda: setColor("ff00ffx"))
+ self.assertException(lambda: setColor("ff00fx"))
+
+ def testFakeTime(self):
+ def checkTime():
+ self.assertEqual(player.getFrameTime(), 50)
+ self.assertEqual(player.getFrameDuration(), 50)
+ self.assertEqual(player.getEffectiveFramerate(), 20)
+
+ self.loadEmptyScene()
+ player.setFakeFPS(20)
+ self.start(False,
+ (checkTime,
+ ))
+
+ def testDivResize(self):
+ def checkSize (w, h):
+ self.assertEqual(node.width, w)
+ self.assertEqual(node.height, h)
+ self.assertEqual(node.size, (w,h))
+
+ def setSize (size):
+ node.size = size
+
+ def setWidth (w):
+ node.width = w
+
+ def setHeight (h):
+ node.height = h
+
+ self.__initDefaultScene()
+ node = player.getElementByID('nestedavg')
+
+ self.start(False,
+ (lambda: checkSize(128, 32),
+ lambda: setSize((14,15)),
+ lambda: checkSize(14,15),
+ lambda: setWidth(23),
+ lambda: checkSize(23,15),
+ lambda: setHeight(22),
+ lambda: checkSize(23,22),
+ ))
+
+ def testRotate(self):
+ def onOuterDown(Event):
+ self.onOuterDownCalled = True
+
+ def fakeRotate():
+ player.getElementByID("outer").angle += 0.1
+ player.getElementByID("inner").angle -= 0.1
+
+ def testCoordConversions():
+ innerNode = player.getElementByID("inner")
+ relPos = innerNode.getRelPos((90, 80))
+ self.assertAlmostEqual(relPos, (10, 10))
+ outerNode = player.getElementByID("outer")
+ relPos = outerNode.getRelPos((90, 80))
+ self.assertAlmostEqual(relPos[0], 12.332806394528092)
+ self.assertAlmostEqual(relPos[1], 6.9211188716194592)
+ absPos = outerNode.getAbsPos(relPos)
+ self.assertAlmostEqual(absPos, (90, 80))
+ self.assertEqual(outerNode.getElementByPos((10, 10)), innerNode)
+ self.assertEqual(outerNode.getElementByPos((0, 10)), outerNode)
+ self.assertEqual(outerNode.getElementByPos((-10, -110)), None)
+
+ def disableCrop():
+ player.getElementByID("outer").crop = False
+ player.getElementByID("inner").crop = False
+
+ self.__initDefaultRotateScene()
+ player.getElementByID("outer").subscribe(avg.Node.CURSOR_DOWN, onOuterDown)
+ self.onOuterDownCalled = False
+ self.start(False,
+ (lambda: self.compareImage("testRotate1"),
+ testCoordConversions,
+ fakeRotate,
+ lambda: self.compareImage("testRotate1a"),
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 85, 70),
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_UP, 85, 70),
+ lambda: self.assert_(not(self.onOuterDownCalled)),
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 85, 75),
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_UP, 85, 75),
+ lambda: self.assert_(self.onOuterDownCalled),
+ disableCrop,
+ lambda: self.compareImage("testRotate1b"),
+ ))
+
+ def testRotate2(self):
+ root = self.loadEmptyScene()
+
+ div1 = avg.DivNode(pos=(80,0), size=(160,120), pivot=(0,0), angle=1.57,
+ parent=root)
+ avg.ImageNode(size=(16,16), href="rgb24-65x65.png", parent=div1)
+ div2 = avg.DivNode(pos=(40,0), size=(110,80), pivot=(0,0), angle=1.57,
+ crop=True, parent=div1)
+ avg.ImageNode(pos=(0,0), size=(16,16), href="rgb24-65x65.png", parent=div2)
+ avg.ImageNode(pos=(30,-6), size=(16,16), href="rgb24-65x65.png", parent=div2)
+ self.start(False, [lambda: self.compareImage("testRotate2")])
+
+ def testRotatePivot(self):
+ def setPivot (pos):
+ node.pivot = pos
+
+ def addPivot (offset):
+ node.pivot += offset
+
+ root = self.loadEmptyScene()
+ node = avg.DivNode(pos=(80,0), size=(160,120), pivot=(0,0), angle=1.57,
+ crop=True, parent=root)
+ div = avg.DivNode(pos=(40,-20), size=(160,120), pivot=(0,0), angle=0.79,
+ crop=True, parent=node)
+ avg.ImageNode(pos=(-10,-10), size=(128,128), href="rgb24-65x65.png", parent=div)
+ avg.ImageNode(pos=(0,10), size=(32,32), href="rgb24-65x65.png", parent=node)
+ self.start(False,
+ (lambda: self.compareImage("testRotatePivot1"),
+ lambda: setPivot((10, 10)),
+ lambda: self.compareImage("testRotatePivot2"),
+ lambda: addPivot((-8, 0)),
+ lambda: self.compareImage("testRotatePivot3"),
+ ))
+
+ def testOpacity(self):
+ root = self.loadEmptyScene()
+ avg.ImageNode(pos=(0,0), href="rgb24-65x65.png", opacity=0.5, parent=root)
+ avg.RectNode(pos=(0,64), size=(64,64), opacity=0.5, fillopacity=0.5,
+ fillcolor="FF0000", strokewidth=2, parent=root)
+ div = avg.DivNode(pos=(80,0), opacity=0.5, parent=root)
+ avg.ImageNode(pos=(0,0), href="rgb24-65x65.png", parent=div)
+ avg.RectNode(pos=(0,64), size=(64,64), opacity=1, fillopacity=1,
+ fillcolor="FF0000", strokewidth=2, parent=div)
+ self.start(False,
+ (lambda: self.compareImage("testOpacity"),
+ ))
+
+ def testOutlines(self):
+ root = self.__initDefaultRotateScene()
+ root.elementoutlinecolor = "FFFFFF"
+ innerDiv = player.getElementByID("inner")
+ innerDiv.size = (0, 0)
+ innerDiv.getChild(0).elementoutlinecolor = "00FF00"
+ self.start(False, [lambda: self.compareImage("testOutlines")])
+
+ def testWordsOutlines(self):
+ root = self.loadEmptyScene()
+ root.elementoutlinecolor = "FFFFFF"
+ avg.WordsNode(pos=(40,40), alignment="center", text="test", parent=root)
+ self.start(True, [lambda: self.compareImage("testWordsOutlines")])
+
+ def testError(self):
+ self.initDefaultImageScene()
+ player.setTimeout(1, lambda: undefinedFunction)
+ player.setTimeout(50, player.stop)
+ try:
+ player.play()
+ except NameError:
+ self.assert_(1)
+ else:
+ self.assert_(0)
+
+ def testExceptionInTimeout(self):
+ def throwException():
+ raise ZeroDivisionError
+
+ try:
+ self.initDefaultImageScene()
+ self.start(False, [throwException])
+ except ZeroDivisionError:
+ self.assert_(1)
+ else:
+ self.assert_(0)
+
+ def testInvalidImageFilename(self):
+ def activateNode():
+ div.active = 1
+
+ root = self.loadEmptyScene()
+ div = avg.DivNode(active=False, parent=root)
+ avg.ImageNode(href="filedoesntexist.png", parent=div)
+ self.start(False, [activateNode])
+
+ def testInvalidVideoFilename(self):
+ def tryplay():
+ assertException(lambda: video.play())
+
+ root = self.loadEmptyScene()
+ video = avg.VideoNode(href="filedoesntexist.avi", parent=root)
+ self.start(False,
+ (lambda: tryplay,
+ lambda: video.stop()
+ ))
+
+ def testTimeouts(self):
+ class TestException(Exception):
+ pass
+
+ def timeout1():
+ player.clearInterval(self.timeout1ID)
+ player.clearInterval(self.timeout2ID)
+ self.timeout1called = True
+
+ def timeout2():
+ self.timeout2called = True
+
+ def onFrame():
+ self.numOnFramesCalled += 1
+ if self.numOnFramesCalled == 3:
+ player.clearInterval(self.intervalID)
+
+ def wait():
+ pass
+
+ def throwException():
+ raise TestException
+
+ def initException():
+ self.timeout3ID = player.setTimeout(0, throwException)
+
+ def setupTimeouts():
+ self.timeout1ID = player.setTimeout(0, timeout1)
+ self.timeout2ID = player.setTimeout(1, timeout2)
+ self.intervalID = player.setOnFrameHandler(onFrame)
+
+ self.timeout1called = False
+ self.timeout2called = False
+ self.__exceptionThrown = False
+ self.numOnFramesCalled = 0
+ try:
+ self.initDefaultImageScene()
+ self.start(False,
+ (setupTimeouts,
+ None,
+ lambda: self.assert_(self.timeout1called),
+ lambda: self.assert_(not(self.timeout2called)),
+ lambda: self.assert_(self.numOnFramesCalled == 3),
+ lambda: initException(),
+ lambda: self.delay(10),
+ ))
+ except TestException:
+ self.__exceptionThrown = True
+
+ self.assert_(self.__exceptionThrown)
+ player.clearInterval(self.timeout3ID)
+
+ def testCallFromThread(self):
+
+ def onAsyncCall():
+ self.asyncCalled = True
+
+ def threadFunc():
+ player.setTimeout(0, onAsyncCall)
+
+ def startThread():
+ self.thread = threading.Thread(target=threadFunc)
+ self.thread.start()
+
+ self.initDefaultImageScene()
+ self.asyncCalled = False
+ player.setFakeFPS(-1)
+ self.start(False,
+ (startThread,
+ lambda: self.thread.join(),
+ None,
+ lambda: self.assert_(self.asyncCalled),
+ ))
+
+ def testAVGFile(self):
+ player.loadFile("image.avg")
+ self.start(False,
+ (lambda: self.compareImage("testAVGFile"),
+ ))
+ self.assertException(lambda: player.loadFile("filedoesntexist.avg"))
+
+ def testBroken(self):
+ def testBrokenString(string):
+ self.assertException(lambda: player.loadString(string))
+
+ # This isn't xml
+ testBrokenString("""
+ xxx<avg width="400" height="300">
+ </avg>
+ """)
+ # This isn't avg
+ testBrokenString("""
+ <bla>hallo
+ </bla>""")
+ testBrokenString("""
+ <avg width="640" height="480" invalidattribute="bla">
+ </avg>
+ """)
+
+ def testMove(self):
+ def moveit():
+ node = player.getElementByID("nestedimg1")
+ node.x += 50
+ node.opacity -= 0.7
+ node = player.getElementByID("nestedavg")
+ node.x += 50
+
+ def checkRelPos():
+ RelPos = player.getElementByID("obscured").getRelPos((50,52))
+ self.assertEqual(RelPos, (0, 0))
+
+ self.__initDefaultScene()
+ self.start(False,
+ (lambda: self.compareImage("testMove1"),
+ moveit,
+ checkRelPos
+ ))
+
+ def testCropImage(self):
+ def moveTLCrop():
+ node = player.getElementByID("img")
+ node.x = -20
+ node.y = -20
+
+ def moveBRCrop():
+ node = player.getElementByID("img")
+ node.x = 60
+ node.y = 40
+
+ def moveTLNegative():
+ node = player.getElementByID("img")
+ node.x = -60
+ node.y = -50
+
+ def moveBRGone():
+ node = player.getElementByID("img")
+ node.x = 140
+ node.y = 100
+
+ def rotate():
+ node = player.getElementByID("img")
+ node.x = 10
+ node.y = 10
+ player.getElementByID("nestedavg").angle = 1.0
+ player.getElementByID("bkgd").angle = 1.0
+
+ root = self.loadEmptyScene()
+ avg.ImageNode(id="bkgd", href="crop_bkgd.png", parent=root)
+ root.appendChild(
+ player.createNode("""
+ <div id="nestedavg" x="40" y="30" width="80" height="60" crop="True">
+ <div id="nestedavg2" crop="True">
+ <div id="nestedavg3" crop="True">
+ <image id="img" x="10" y="10" width="40" height="40"
+ href="rgb24-64x64.png"/>
+ </div>
+ </div>
+ </div>
+ """))
+ self.start(False,
+ (lambda: self.compareImage("testCropImage1"),
+ moveTLCrop,
+ lambda: self.compareImage("testCropImage2"),
+ moveBRCrop,
+ lambda: self.compareImage("testCropImage3"),
+ moveTLNegative,
+ lambda: self.compareImage("testCropImage4"),
+ moveBRGone,
+ lambda: self.compareImage("testCropImage5"),
+
+ rotate,
+ lambda: self.compareImage("testCropImage6"),
+ moveTLCrop,
+ lambda: self.compareImage("testCropImage7"),
+ moveBRCrop,
+ lambda: self.compareImage("testCropImage8"),
+ moveTLNegative,
+ lambda: self.compareImage("testCropImage9"),
+ moveBRGone,
+ lambda: self.compareImage("testCropImage10")
+ ))
+
+ def testCropMovie(self):
+ def playMovie():
+ node = player.getElementByID("movie")
+ node.play()
+
+ def moveTLCrop():
+ node = player.getElementByID("movie")
+ node.x = -20
+ node.y = -20
+
+ def moveBRCrop():
+ node = player.getElementByID("movie")
+ node.x = 60
+ node.y = 40
+
+ def moveTLNegative():
+ node = player.getElementByID("movie")
+ node.x = -60
+ node.y = -50
+
+ def moveBRGone():
+ node = player.getElementByID("movie")
+ node.x = 140
+ node.y = 100
+
+ def rotate():
+ node = player.getElementByID("movie")
+ node.x = 10
+ node.y = 10
+ player.getElementByID("nestedavg").angle = 1.0
+ player.getElementByID("bkgd").angle = 1.0
+
+ player.setFakeFPS(30)
+ root = self.loadEmptyScene()
+ avg.ImageNode(id="bkgd", href="crop_bkgd.png", parent=root)
+ root.appendChild(
+ player.createNode("""
+ <div id="nestedavg" x="40" y="30" width="80" height="60" crop="True">
+ <video id="movie" x="10" y="10" width="40" height="40"
+ threaded="false" href="mpeg1-48x48.mov"
+ fps="30"/>
+ </div>
+ """))
+ self.start(False,
+ (playMovie,
+ lambda: self.compareImage("testCropMovie1"),
+ moveTLCrop,
+ lambda: self.compareImage("testCropMovie2"),
+ moveBRCrop,
+ lambda: self.compareImage("testCropMovie3"),
+ moveTLNegative,
+ lambda: self.compareImage("testCropMovie4"),
+ moveBRGone,
+ lambda: self.compareImage("testCropMovie5"),
+
+ rotate,
+ lambda: self.compareImage("testCropMovie6"),
+ moveTLCrop,
+ lambda: self.compareImage("testCropMovie7"),
+ moveBRCrop,
+ lambda: self.compareImage("testCropMovie8"),
+ moveTLNegative,
+ lambda: self.compareImage("testCropMovie9"),
+ moveBRGone,
+ lambda: self.compareImage("testCropMovie10")
+ ))
+
+ def testWarp(self):
+ def moveVertex():
+ grid = image.getWarpedVertexCoords()
+ grid[1][1] = (grid[1][1][0]+0.06, grid[1][1][1]+0.06)
+ image.setWarpedVertexCoords(grid)
+ grid = video.getWarpedVertexCoords()
+ grid[0][0] = (grid[0][0][0]+0.06, grid[0][0][1]+0.06)
+ grid[1][1] = (grid[1][1][0]-0.06, grid[1][1][1]-0.06)
+ video.setWarpedVertexCoords(grid)
+
+ def flip():
+ grid = image.getOrigVertexCoords()
+ grid = [ [ (1-pos[0], pos[1]) for pos in line ] for line in grid]
+ image.setWarpedVertexCoords(grid)
+
+ root = self.loadEmptyScene()
+ image = avg.ImageNode(href="rgb24-64x64.png",
+ maxtilewidth=32, maxtileheight=16, parent=root)
+ video = avg.VideoNode(pos=(40,0), size=(80,80), opacity=0.5, loop=True,
+ href="mpeg1-48x48.mov", threaded=False, fps=30, parent=root)
+
+ self.assertException(image.getOrigVertexCoords)
+ self.assertException(image.getWarpedVertexCoords)
+ player.setFakeFPS(30)
+ self.start(False,
+ (lambda: video.play(),
+ lambda: self.compareImage("testWarp1"),
+ moveVertex,
+ lambda: self.compareImage("testWarp2"),
+ flip,
+ lambda: self.compareImage("testWarp3")
+ ))
+
+ def testMediaDir(self):
+ def createImageNode():
+ # Node is not in tree; mediadir should be root node dir.
+ node = avg.ImageNode(href="rgb24-64x64a.png")
+ self.assertEqual(node.size, avg.Point2D(0,0)) # File not found
+ node.href = "rgb24-64x64.png"
+ self.assertEqual(node.size, avg.Point2D(64,64)) # File found
+ node = avg.ImageNode(href="rgb24-64x64a.png", width=23, height=42)
+ # File not found, but custom size
+ self.assertEqual(node.size, avg.Point2D(23,42))
+ node.href = "rgb24-64x64.png"
+ # File found, custom size stays
+ self.assertEqual(node.size, avg.Point2D(23,42))
+ node.size = (0,0)
+ # File found, custom size cleared. Media size should be used.
+ self.assertEqual(node.size, avg.Point2D(64,64))
+
+ def setDir():
+ div.mediadir=""
+
+ def setAbsDir():
+ def absDir():
+ # Should not find any media here...
+ div.mediadir="/testmediadir"
+
+ self.assertException(absDir)
+
+ def createNode():
+ avg.VideoNode(href="mjpeg1-48x48.avi", fps=30)
+
+ root = self.loadEmptyScene()
+ div = avg.DivNode(mediadir="../testmediadir", parent=root)
+ image = avg.ImageNode(pos=(0,30), href="rgb24-64x64a.png", parent=div)
+ video = avg.VideoNode(href="mjpeg-48x48.avi", threaded=False, parent=div)
+ self.start(False,
+ (createImageNode,
+ lambda: video.play(),
+ lambda: self.compareImage("testMediaDir1"),
+ setDir,
+ lambda: video.play(),
+ lambda: self.compareImage("testMediaDir2"),
+ lambda: self.assertEqual(image.width, 0),
+ createNode,
+ setAbsDir
+ ))
+
+ def testMemoryQuery(self):
+ self.assertNotEqual(avg.getMemoryUsage(), 0)
+
+ def testStopOnEscape(self):
+ def pressEscape():
+ Helper = player.getTestHelper()
+ escape = 27
+ Helper.fakeKeyEvent(avg.Event.KEY_DOWN, escape, escape, "escape", escape,
+ avg.KEYMOD_NONE),
+ Helper.fakeKeyEvent(avg.Event.KEY_UP, escape, escape, "escape", escape,
+ avg.KEYMOD_NONE),
+
+ def testEscape1():
+ player.stopOnEscape(False)
+ pressEscape()
+
+ def testEscape2():
+ player.stopOnEscape(True)
+ player.stopOnEscape(False)
+ pressEscape()
+
+ def testEscape3():
+ player.stopOnEscape(True)
+ pressEscape()
+
+ def setAlive():
+ self.testStopOnEscapeAlive = True
+
+ self.testStopOnEscapeAlive = False
+ self.__initDefaultScene()
+ self.start(False,
+ (testEscape1,
+ testEscape2,
+ setAlive
+ ))
+ self.assert_(self.testStopOnEscapeAlive)
+ self.__initDefaultScene()
+ self.start(False,
+ (testEscape3, # this should exit the player
+ lambda: self.fail(),
+ ))
+
+ def testScreenDimensions(self):
+ def queryDimensions():
+ res = player.getScreenResolution()
+ self.assert_(res.x > 0 and res.y > 0 and res.x < 10000 and res.y < 10000)
+ ppmm = player.getPixelsPerMM()
+ self.assert_(ppmm > 0 and ppmm < 10000)
+ mm = player.getPhysicalScreenDimensions()
+ self.assert_(mm.x > 0 and mm.y > 0 and mm.x < 10000 and mm.y < 10000)
+ player.assumePixelsPerMM(ppmm)
+ newPPMM = player.getPixelsPerMM()
+ self.assertAlmostEqual(newPPMM, ppmm)
+ newMM = player.getPhysicalScreenDimensions()
+ self.assertEqual(newMM, mm)
+
+ queryDimensions()
+ self.__initDefaultScene()
+ self.start(False,
+ (queryDimensions,
+ ))
+
+ def testSVG(self):
+ svgFile = avg.SVG("media/rect.svg", False)
+
+ # renderElement
+ bmp = svgFile.renderElement("rect")
+ self.compareBitmapToFile(bmp, "testSvgBmp")
+ self.assertEqual(svgFile.getElementSize("rect"), avg.Point2D(22,12))
+ bmp = svgFile.renderElement("pos_rect")
+ self.compareBitmapToFile(bmp, "testSvgPosBmp")
+ bmp = svgFile.renderElement("rect", 5)
+ self.compareBitmapToFile(bmp, "testSvgScaleBmp1")
+ bmp = svgFile.renderElement("rect", (20,20))
+ self.compareBitmapToFile(bmp, "testSvgScaleBmp2")
+
+ # error handling
+ self.assertException(lambda: avg.SVG("filedoesntexist.svg", False))
+ self.assertException(lambda: svgFile.renderElement("missing_id"))
+
+ # unescapeIllustratorIDs
+ svgIllustratorFile = avg.SVG("illustratorRect.svg", True)
+ svgIllustratorFile.getElementSize("pos_rect")
+
+ # createImageNode
+ root = self.loadEmptyScene()
+ self.start(False,
+ (lambda: svgFile.createImageNode("rect", {"pos":(10,10), "parent":root}),
+ lambda: self.compareImage("testSvgNode"),
+ lambda: svgFile.createImageNode("rect", {"pos":(5,5), "parent":root},
+ 5),
+ lambda: self.compareImage("testSvgScaledNode1"),
+ lambda: svgFile.createImageNode("rect", {"pos":(1,1), "parent":root},
+ (40,40)),
+ lambda: self.compareImage("testSvgScaledNode2")
+ ))
+
+ def testGetConfigOption(self):
+ self.assert_(len(player.getConfigOption("scr", "bpp")) > 0)
+ self.assertException(lambda: player.getConfigOption("scr", "illegalOption"))
+ self.assertException(lambda:
+ player.getConfigOption("illegalGroup", "illegalOption"))
+
+ def testValidateXml(self):
+ schema = """<?xml version="1.0" encoding="UTF-8"?>
+ <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
+
+ <xs:element name="shiporder">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="orderperson" type="xs:string"/>
+ </xs:sequence>
+ <xs:attribute name="orderid" type="xs:string" use="required"/>
+ </xs:complexType>
+ </xs:element>
+
+ </xs:schema>
+ """
+ xmlString = """<?xml version="1.0" encoding="UTF-8"?>
+
+ <shiporder orderid="889923">
+ <orderperson>John Smith</orderperson>
+ </shiporder>
+ """
+ avg.validateXml(xmlString, schema, "shiporder.xml", "shiporder.xsd")
+
+ brokenSchema = "ff"+schema
+ self.assertException(lambda: avg.validateXml(xmlString, brokenSchema,
+ "shiporder.xml", "shiporder.xsd"))
+
+ brokenXml = xmlString+"ff"
+ self.assertException(lambda: avg.validateXml(brokenXml, schema,
+ "shiporder.xml", "shiporder.xsd"))
+
+ # Not executed due to bug #145 - hangs with some window managers.
+ def testWindowFrame(self):
+ def revertWindowFrame():
+ player.setWindowFrame(True)
+
+ player.setWindowFrame(False)
+ self.__initDefaultScene()
+ self.start(False, [revertWindowFrame])
+
+ def __initDefaultScene(self):
+ root = self.loadEmptyScene()
+ avg.ImageNode(id="mainimg", size=(100, 75), href="rgb24-65x65.png", parent=root)
+ div = avg.DivNode(id="nestedavg", pos=(0,32), opacity=1, size=(128, 32),
+ crop=True, parent=root)
+ avg.ImageNode(id="obscured", pos=(0,20), size=(96,40), href="rgb24-65x65.png",
+ parent=div)
+ avg.ImageNode(id="nestedimg1", size=(96,48), href="rgb24-65x65.png",
+ parent=div)
+ avg.ImageNode(id="nestedimg2", pos=(65,0), href="rgb24alpha-64x64.png",
+ parent=div)
+
+ def __initDefaultRotateScene(self):
+ root = self.loadEmptyScene()
+ div = avg.DivNode(pos=(80,10), size=(80,60), pivot=(0,0), angle=0.274,
+ crop=True, parent=root)
+ avg.ImageNode(pos=(10,10), size=(32,32), href="rgb24-65x65.png", parent=div)
+ outerDiv = avg.DivNode(id="outer", pos=(80,70), size=(80,60),
+ pivot=(0,0), angle=0.274, crop=True, parent=root)
+ innerDiv = avg.DivNode(id="inner", size=(80,60), pivot=(0,0), angle=-0.274,
+ crop=True, parent=outerDiv)
+ avg.ImageNode(pos=(10,10), size=(32,32), href="rgb24-65x65.png", parent=innerDiv)
+ return root
+
+def playerTestSuite(tests):
+ availableTests = (
+ "testPoint",
+ "testBasics",
+ "testColorParse",
+ "testFakeTime",
+ "testDivResize",
+ "testRotate",
+ "testRotate2",
+ "testRotatePivot",
+ "testOpacity",
+ "testOutlines",
+ "testWordsOutlines",
+ "testError",
+ "testExceptionInTimeout",
+ "testInvalidImageFilename",
+ "testInvalidVideoFilename",
+ "testTimeouts",
+ "testCallFromThread",
+ "testAVGFile",
+ "testBroken",
+ "testMove",
+ "testCropImage",
+ "testCropMovie",
+ "testWarp",
+ "testMediaDir",
+ "testMemoryQuery",
+ "testStopOnEscape",
+ "testScreenDimensions",
+ "testSVG",
+ "testGetConfigOption",
+ "testValidateXml",
+# "testWindowFrame",
+ )
+ return createAVGTestSuite(availableTests, PlayerTestCase, tests)
diff --git a/src/test/PluginTest.py b/src/test/PluginTest.py
new file mode 100644
index 0000000..186f7e4
--- /dev/null
+++ b/src/test/PluginTest.py
@@ -0,0 +1,65 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# libavg - Media Playback Engine.
+# Copyright (C) 2003-2014 Ulrich von Zadow
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Current versions can be found at www.libavg.de
+#
+
+import platform
+
+from libavg import player
+from testcase import *
+
+class PluginTestCase(AVGTestCase):
+ def __init__(self, testFuncName):
+ AVGTestCase.__init__(self, testFuncName)
+
+ def testColorNodePlugin(self):
+ def loadPlugin():
+ if platform.system() != 'Windows':
+ if not(os.getenv('srcdir') in ('.', None)):
+ # make distcheck
+ player.pluginPath += ":../../_build/src/test/plugin/.libs"
+ player.loadPlugin("colorplugin")
+
+ def usePlugin1():
+ node = colorplugin.ColorNode(fillcolor="7f7f00", id="mynode1")
+ root.appendChild(node)
+
+ mynode = player.getElementByID("mynode1")
+ self.assertEqual(mynode.fillcolor, "7f7f00")
+
+ def usePlugin2():
+ node = player.createNode('<colornode fillcolor="0f3f7f" id="mynode2" />')
+ root.appendChild(node)
+
+ mynode = player.getElementByID("mynode2")
+ self.assertEqual(mynode.fillcolor, "0f3f7f")
+
+ root = self.loadEmptyScene()
+ self.start(False,
+ (loadPlugin,
+ usePlugin1,
+ lambda: self.compareImage("testplugin1"),
+ usePlugin2,
+ lambda: self.compareImage("testplugin2"),
+ ))
+
+def pluginTestSuite (tests):
+ availableTests = ("testColorNodePlugin",)
+ return createAVGTestSuite(availableTests, PluginTestCase, tests)
diff --git a/src/test/PythonTest.py b/src/test/PythonTest.py
new file mode 100644
index 0000000..21dd68b
--- /dev/null
+++ b/src/test/PythonTest.py
@@ -0,0 +1,239 @@
+# -*- coding: utf-8 -*-
+# libavg - Media Playback Engine.
+# Copyright (C) 2003-2014 Ulrich von Zadow
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Current versions can be found at www.libavg.de
+#
+
+import os
+import time
+import tempfile
+
+from libavg import geom, statemachine, persist
+
+from testcase import *
+
+def getTempFileName():
+ return os.path.join(tempfile.gettempdir(), 'libavg.%d' % time.time())
+
+
+class PythonTestCase(AVGTestCase):
+ def __init__(self, testFuncName):
+ AVGTestCase.__init__(self, testFuncName)
+
+ def testRoundedRect(self):
+ def setPos():
+ self.rect.pos = (20.5, 3.5)
+
+ def setSize():
+ self.rect.size = (40, 20)
+
+ def setRadius(r):
+ self.rect.radius = r
+
+ def setFill():
+ self.rect.fillcolor = "0000FF"
+ self.rect.fillopacity = 0.5
+
+ def createDegenRect():
+ self.rect.unlink(True)
+ rect = geom.RoundedRect(parent=root, pos=(10.5,10.5), size=(10,10), radius=6,
+ fillopacity=0.5, color="FFFFFF")
+ self.assert_(rect.radius == 6)
+
+ root = self.loadEmptyScene()
+ self.rect = geom.RoundedRect(parent=root, pos=(2.5,2.5),
+ size=(64,64), radius=5, color="FF0000")
+ self.start(False,
+ (lambda: self.compareImage("testRoundedRect1"),
+ setPos,
+ lambda: self.compareImage("testRoundedRect2"),
+ setSize,
+ lambda: self.compareImage("testRoundedRect3"),
+ lambda: setRadius(10),
+ lambda: self.compareImage("testRoundedRect4"),
+ setFill,
+ lambda: self.compareImage("testRoundedRect5"),
+ createDegenRect,
+ lambda: self.compareImage("testRoundedRect6"),
+ ))
+
+ def testPieSlice(self):
+ def changeAttrs():
+ self.pieSlice.startangle = -1
+ self.pieSlice.endangle = 3.14
+ self.pieSlice.radius = 50
+ self.pieSlice.pos = (80.5, 60.5)
+ self.pieSlice.fillcolor = "00FFFF"
+ self.pieSlice.fillopacity = 0.5
+
+ def makeSmall():
+ self.pieSlice.radius = 0.6
+
+ root = self.loadEmptyScene()
+ self.pieSlice = geom.PieSlice(parent=root, pos=(20.5,20.5),
+ radius=40, startangle=0, endangle=1.57, color="FF0000")
+
+ self.start(False,
+ (lambda: self.compareImage("testPieSlice1"),
+ changeAttrs,
+ lambda: self.compareImage("testPieSlice2"),
+ makeSmall,
+ lambda: self.compareImage("testPieSlice3"),
+ ))
+
+ def testArc(self):
+ def changeAttrs():
+ self.arc.startangle = -1
+ self.arc.endangle = 3.14
+ self.arc.radius = 50
+ self.arc.pos = (80.5, 60.5)
+
+ root = self.loadEmptyScene()
+ self.arc = geom.Arc(parent=root, pos=(20.5,20.5),
+ radius=40, startangle=0, endangle=1.57, color="FF0000")
+
+ self.start(False,
+ (lambda: self.compareImage("testArc1"),
+ changeAttrs,
+ lambda: self.compareImage("testArc2"),
+ ))
+
+ def btoa(self):
+ # Test for member function handling in StateMachine.
+ self.btoaCalled = True
+
+ def testStateMachine(self):
+ def atob(oldState, newState):
+ self.atobCalled = True
+
+ def btoc(dummy):
+ # Dummy argument so we can test handling of lambda expressions.
+ self.btocCalled = True
+
+ def aEntered():
+ self.aEnteredCalled = True
+
+ def aLeft():
+ self.aLeftCalled = True
+
+ self.atobCalled = False
+ self.btocCalled = False
+ self.btoaCalled = False
+ self.aLeftCalled = False
+ self.aEnteredCalled = False
+ machine = statemachine.StateMachine("testmachine", 'A')
+ machine.addState('A', {'B': atob, 'nostate': atob}, aEntered, aLeft)
+ machine.addState('B', {'C': lambda: btoc("dummy"), 'A': self.btoa})
+ machine.addState('C', {'A': None})
+ self.assertException(lambda: machine.addState('C', {'A': None}))
+ self.assertException(lambda: machine.changeState('C'))
+ self.assertException(lambda: machine.changeState('nostate'))
+ machine.changeState('B')
+ self.assert_(self.atobCalled)
+ self.assert_(self.aLeftCalled)
+ machine.changeState('A')
+ self.assert_(self.aEnteredCalled)
+ self.assert_(self.btoaCalled)
+ machine.changeState('B')
+ machine.changeState('C')
+ self.assert_(self.btocCalled)
+ machine.changeState('A')
+ self.assertEqual(machine.state, 'A')
+# machine.dump()
+
+ self.assertException(lambda: machine.addState('illegal', {}))
+
+ # Create a machine without transition callbacks
+ machine = statemachine.StateMachine("testmachine", 'A')
+ machine.addState('A', ('B',), aEntered, aLeft)
+ machine.addState('B', ('C', 'A'))
+ machine.addState('C', ('A',))
+ machine.changeState('B')
+
+ # Make a machine with a transition to a nonexistent state.
+ kaputtMachine = statemachine.StateMachine("kaputt", 'A')
+ kaputtMachine.addState('A', {'B': None})
+ self.assertException(lambda: kaputtMachine.changeState('B'))
+
+ def testStateMachineDiagram(self):
+ def aEntered():
+ pass
+
+ if not(self._isCurrentDirWriteable()):
+ self.skip("Current dir not writeable")
+ return
+
+ machine = statemachine.StateMachine("testmachine", 'A')
+ machine.addState('A', {'B': None, 'nostate': None}, aEntered)
+ machine.addState('B', {'C': None, 'A': self.btoa})
+ machine.addState('C', {'A': None})
+
+ imageFName = AVGTestCase.imageResultDirectory + "/stateMachineGraphViz.png"
+ try:
+ machine.makeDiagram(imageFName)
+ except RuntimeError:
+ self.skip("graphviz not installed.")
+
+ def testPersistStore(self):
+ testFile = getTempFileName()
+ p = persist.Persist(testFile, {})
+ self.assertEqual(p.storeFile, testFile)
+ self.assertEqual(p.data, {})
+ p.data['test'] = 1
+ p.commit()
+ p = persist.Persist(testFile, {})
+ self.assert_('test' in p.data)
+ self.assertEqual(p.data['test'], 1)
+ os.unlink(testFile)
+
+ def testPersistCorrupted(self):
+ logger.configureCategory("APP", logger.Severity.ERR);
+ testFile = getTempFileName()
+ f = open(testFile, 'w')
+ f.write('garbage')
+ f.close()
+ p = persist.Persist(testFile, {})
+ self.assertEqual(p.data, {})
+ os.unlink(testFile)
+ logger.configureCategory("APP", logger.Severity.WARN);
+
+ def testPersistValidation(self):
+ logger.configureCategory("APP", logger.Severity.ERR);
+ testFile = getTempFileName()
+ p = persist.Persist(testFile, {'test': 1})
+ p.commit()
+ p = persist.Persist(testFile, [], validator=lambda v: isinstance(v, list))
+ self.assertEqual(p.data, [])
+ os.unlink(testFile)
+ logger.configureCategory("APP", logger.Severity.WARN);
+
+
+def pythonTestSuite(tests):
+ availableTests = (
+ "testRoundedRect",
+ "testPieSlice",
+ "testArc",
+ "testStateMachine",
+ "testStateMachineDiagram",
+ "testPersistStore",
+ "testPersistCorrupted",
+ "testPersistValidation",
+ )
+
+ return createAVGTestSuite(availableTests, PythonTestCase, tests)
+
diff --git a/src/test/Test.py b/src/test/Test.py
new file mode 100755
index 0000000..4c4de8f
--- /dev/null
+++ b/src/test/Test.py
@@ -0,0 +1,150 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# libavg - Media Playback Engine.
+# Copyright (C) 2003-2014 Ulrich von Zadow
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Current versions can be found at www.libavg.de
+#
+
+'''
+Runner for libavg unit tests
+
+On autotools-based systems, tests are performed on a local libavg package.
+This package is created by symlinking all the relevant files in a local, temporary
+directory, letting python find it as first instance.
+On windows, instead, tests are always carried on after distutils installs the package.
+'''
+
+import sys
+import os
+import shutil
+import atexit
+
+def cleanup(folder):
+ if os.path.isdir(folder):
+ sys.stderr.write('Wiping out directory: %s\n' % folder)
+ shutil.rmtree(folder)
+
+def symtree(src, dest):
+ os.mkdir(dest)
+ for f in os.listdir(src):
+ fpath = os.path.join(src, f)
+ if (f and f[0] != '.' and
+ (os.path.isdir(fpath) or
+ (os.path.isfile(fpath) and os.path.splitext(f)[1] in ('.py', '.glsl')))):
+ os.symlink(os.path.join(os.pardir, src, f), os.path.join(dest, f))
+
+
+if sys.platform != 'win32':
+ tempPackageDir = os.path.join(os.getcwd(), 'libavg')
+ # Possible values for srcdir:
+ # '.': make check
+ # None: ./Test.py
+ # dir name: make distcheck
+ srcDir = os.getenv("srcdir",".")
+ if srcDir == '.':
+ # Running make check or ./Test.py
+ if os.path.basename(os.getcwd()) != 'test':
+ raise RuntimeError('Manual tests must be performed inside directory "test"')
+
+ cleanup(tempPackageDir)
+
+ try:
+ symtree('../python', 'libavg')
+ os.symlink('../../graphics/shaders', 'libavg/shaders')
+ except OSError:
+ pass
+ else:
+ # Running make distcheck
+ symtree('../../../../src/python', 'libavg')
+ os.symlink('../../../../../src/graphics/shaders', 'libavg/shaders')
+
+ # distcheck doesn't want leftovers (.pyc files)
+ atexit.register(lambda tempPackageDir=tempPackageDir: cleanup(tempPackageDir))
+
+ if os.path.exists('../wrapper/.libs/avg.so'):
+ # Normal case: use the local version (not the installed one)
+ shutil.copy2('../wrapper/.libs/avg.so', 'libavg/avg.so')
+ elif os.path.exists('../../avg.so'):
+ # Mac version after installer dmg
+ pass
+ else:
+ raise RuntimeError('Compile libavg before running tests or use "make check"')
+
+ # The following line prevents the test to be run
+ # with an unknown version of libavg, which can be hiding somewhere
+ # in the system
+ sys.path.insert(0, os.getcwd())
+
+ # Meaningful only for distcheck
+ os.chdir(srcDir)
+
+import libavg
+libavg.logger.configureCategory(libavg.Logger.Category.APP, libavg.Logger.Severity.INFO)
+libavg.logger.info("Using libavg from: "+ os.path.dirname(libavg.__file__),
+ libavg.Logger.Category.APP)
+# Ensure mouse is activated
+libavg.player.enableMouse(True)
+
+import testapp
+
+libavg.Player.get().keepWindowOpen()
+
+import PluginTest
+import PlayerTest
+import OffscreenTest
+import ImageTest
+import FXTest
+import VectorTest
+import WordsTest
+import AVTest
+import DynamicsTest
+import PythonTest
+import AnimTest
+import EventTest
+import InputDeviceTest
+import AVGAppTest
+import WidgetTest
+import GestureTest
+import LoggerTest
+import AppTest
+
+app = testapp.TestApp()
+
+app.registerSuiteFactory('plugin', PluginTest.pluginTestSuite)
+app.registerSuiteFactory('player', PlayerTest.playerTestSuite)
+app.registerSuiteFactory('offscreen', OffscreenTest.offscreenTestSuite)
+app.registerSuiteFactory('image', ImageTest.imageTestSuite)
+app.registerSuiteFactory('fx', FXTest.fxTestSuite)
+app.registerSuiteFactory('vector', VectorTest.vectorTestSuite)
+app.registerSuiteFactory('words', WordsTest.wordsTestSuite)
+app.registerSuiteFactory('av', AVTest.AVTestSuite)
+app.registerSuiteFactory('dynamics', DynamicsTest.dynamicsTestSuite)
+app.registerSuiteFactory('python', PythonTest.pythonTestSuite)
+app.registerSuiteFactory('anim', AnimTest.animTestSuite)
+app.registerSuiteFactory('event', EventTest.eventTestSuite)
+app.registerSuiteFactory('inputdevice', InputDeviceTest.inputDeviceTestSuite)
+app.registerSuiteFactory('widget', WidgetTest.widgetTestSuite)
+app.registerSuiteFactory('gesture', GestureTest.gestureTestSuite)
+app.registerSuiteFactory('avgapp', AVGAppTest.avgAppTestSuite)
+app.registerSuiteFactory('logger', LoggerTest.loggerTestSuite)
+app.registerSuiteFactory('app', AppTest.appTestSuite)
+
+app.run()
+
+sys.exit(app.exitCode())
+
diff --git a/src/test/VectorTest.py b/src/test/VectorTest.py
new file mode 100644
index 0000000..af0ddaf
--- /dev/null
+++ b/src/test/VectorTest.py
@@ -0,0 +1,734 @@
+# -*- coding: utf-8 -*-
+# libavg - Media Playback Engine.
+# Copyright (C) 2003-2014 Ulrich von Zadow
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Current versions can be found at www.libavg.de
+#
+
+from libavg import avg, player
+from testcase import *
+
+class VectorTestCase(AVGTestCase):
+ def __init__(self, testFuncName):
+ AVGTestCase.__init__(self, testFuncName)
+
+ def makeEmptyCanvas(self):
+ root = self.loadEmptyScene()
+ canvas = avg.DivNode(id="canvas", size=(160,120), parent=root)
+ return canvas
+
+ def testLine(self):
+ def addLines():
+ def addLine(attribs):
+ line = player.createNode("line", attribs)
+ canvas.appendChild(line)
+
+ addLine({"pos1":(2, 2.5), "pos2":(100, 2.5)})
+ addLine({"pos1":(2, 5), "pos2":(100, 5), "strokewidth":2})
+ addLine({"pos1":(2.5, 20), "pos2":(2.5, 100)})
+ addLine({"pos1":(5, 20), "pos2":(5, 100), "strokewidth":2})
+ addLine({"pos1":(2, 7.5), "pos2":(100, 7.5), "color":"FF0000"})
+ addLine({"pos1":(2, 9.5), "pos2":(100, 9.5), "color":"00FF00"})
+ addLine({"pos1":(2, 11.5), "pos2":(100, 11.5), "color":"0000FF"})
+
+ def changeLine():
+ line.color="FF0000"
+ line.strokewidth=3
+
+ def moveLine():
+ line.pos1 += (0, 30)
+ line.pos2 += (0, 30)
+
+ def blendMode():
+ line = canvas.getChild(6)
+ line.pos1 = (line.pos1.x, 7.9)
+ line.pos2 = (line.pos2.x, 7.9)
+ line.strokewidth = 10
+ line.blendmode="add"
+
+ canvas = self.makeEmptyCanvas()
+ addLines()
+ line = canvas.getChild(0)
+ self.start(False,
+ (lambda: self.compareImage("testline1"),
+ changeLine,
+ lambda: self.compareImage("testline2"),
+ moveLine,
+ lambda: self.compareImage("testline3"),
+ blendMode,
+ lambda: self.compareImage("testline4")
+ ))
+
+ def testLotsOfLines(self):
+ def addLines():
+ for i in xrange(500):
+ y = i+2.5
+ line = avg.LineNode(pos1=(2, y), pos2=(10, y))
+ canvas.appendChild(line)
+
+ canvas = self.makeEmptyCanvas()
+ self.start(False,
+ (addLines,
+ lambda: self.compareImage("testlotsoflines"),
+ ))
+
+ def testTexturedLine(self):
+ def addLine():
+ line = avg.LineNode(pos1=(2, 20), pos2=(100, 20), texhref="rgb24-64x64.png",
+ strokewidth=30)
+ canvas.appendChild(line)
+
+ def removeLine():
+ self.line = canvas.getChild(0)
+ self.line.unlink()
+
+ def reAddLine():
+ canvas.appendChild(self.line)
+
+ def moveTexture():
+ self.line.texcoord1 = -0.5
+ self.line.texcoord2 = 1.5
+
+ def bmpTexture():
+ bmp = avg.Bitmap("media/rgb24alpha-64x64.png")
+ self.line.setBitmap(bmp)
+
+ def bmpNoTexture():
+ self.line.setBitmap(None)
+
+ canvas = self.makeEmptyCanvas()
+ addLine()
+ self.start(False,
+ (lambda: self.compareImage("testtexturedline1"),
+ removeLine,
+ lambda: self.compareImage("testtexturedline2"),
+ addLine,
+ lambda: self.compareImage("testtexturedline1"),
+ removeLine,
+ lambda: self.compareImage("testtexturedline2"),
+ reAddLine,
+ lambda: self.compareImage("testtexturedline1"),
+ moveTexture,
+ lambda: self.compareImage("testtexturedline3"),
+ bmpTexture,
+ lambda: self.compareImage("testtexturedline4"),
+ bmpNoTexture,
+ lambda: self.compareImage("testtexturedline5"),
+ ))
+
+ def testLineOpacity(self):
+ def addLine():
+ line = avg.LineNode(pos1=(2, 2.5), pos2=(158, 2.5), opacity=0.5)
+ canvas.appendChild(line)
+
+ def changeCanvasOpacity():
+ canvas.opacity = 0.5
+ canvas.getChild(0).opacity = 0.25
+
+ canvas = self.makeEmptyCanvas()
+ self.start(False,
+ (addLine,
+ lambda: self.compareImage("testlineopacity1"),
+ changeCanvasOpacity,
+ lambda: self.compareImage("testlineopacity2"),
+ ))
+
+ def testRect(self):
+ def addRect():
+ rect = avg.RectNode(pos=(2, 2), size=(50, 30), fillopacity=1,
+ strokewidth=0)
+ canvas.appendChild(rect)
+ rect.subscribe(avg.Node.CURSOR_DOWN, onMouseDown)
+ return rect
+
+ def moveRect():
+ rect.pos = (50, 50)
+ rect.size = (30, 10)
+ rect.fillcolor = "FF0000"
+ rect.fillopacity = 0.5
+ rect.color = "FFFF00"
+ rect.strokewidth = 2
+
+ def rotateRect():
+ rect.angle = 1.57
+
+ def addRect2():
+ rect = avg.RectNode(pos=(60, 2), size=(50, 30), fillopacity=1,
+ strokewidth=2)
+ rect.color = "FFFF00"
+ canvas.insertChild(rect, 0)
+
+ def onMouseDown(event):
+ self.__mouseDownCalled = True
+
+ self.__mouseDownCalled = False
+ canvas = self.makeEmptyCanvas()
+ rect = addRect()
+ self.start(False,
+ (lambda: self.compareImage("testRect1"),
+ moveRect,
+ lambda: self.compareImage("testRect2"),
+ rotateRect,
+ lambda: self.compareImage("testRect3"),
+ addRect2,
+ lambda: self.compareImage("testRect4"),
+ lambda: self.fakeClick(100, 100),
+ lambda: self.assertEqual(self.__mouseDownCalled, False),
+ lambda: self.fakeClick(55, 50),
+ lambda: self.assertEqual(self.__mouseDownCalled, False),
+ lambda: self.fakeClick(65, 65),
+ lambda: self.assert_(self.__mouseDownCalled)
+ ))
+
+ def testTexturedRect(self):
+ def addRect():
+ self.rect = avg.RectNode(pos=(20, 20), size=(50, 40), fillopacity=1,
+ filltexcoord1=(1,1), filltexcoord2=(0,0), strokewidth=20,
+ texcoords=(1, 0.75, 0.5, 0.25, 0), texhref="rgb24-64x64.png")
+ canvas.appendChild(self.rect)
+ return self.rect
+
+ def newRect():
+ self.rect.unlink()
+ self.rect = player.createNode(
+ """<rect pos="(20, 20)" size="(50, 40)" fillopacity="1"
+ filltexcoord1="(1,1)" filltexcoord2="(0,0)"
+ texcoords="(0, 0.25, 0.5, 0.75, 1)"
+ strokewidth="20" texhref="rgb24-64x64.png"/>""")
+ canvas.appendChild(self.rect)
+
+ def setTexCoords():
+ self.rect.texcoords = [-1, 0, 1, 2, 3]
+
+ def setFillTex():
+ self.rect.strokewidth = 2
+ self.rect.texhref = ""
+ self.rect.filltexhref="rgb24alpha-64x64.png"
+
+ def setFillTexCoords():
+ self.rect.filltexcoord1 = (0.5, 0.5)
+ self.rect.filltexcoord2 = (1.5, 1.5)
+
+ def setFillBitmap():
+ bmp = avg.Bitmap("media/rgb24-64x64.png")
+ self.rect.setFillBitmap(bmp)
+
+ def clearFillBitmap():
+ self.rect.fillcolor = "FF0000"
+ self.rect.setFillBitmap(None)
+
+ def setTransparentBorder():
+ self.rect.fillopacity = 0
+ self.rect.texhref = "rectborder.png"
+ self.rect.strokewidth = 10
+
+ canvas = self.makeEmptyCanvas()
+ addRect()
+ self.start(False,
+ (lambda: self.compareImage("testTexturedRect1"),
+ newRect,
+ lambda: self.compareImage("testTexturedRect2"),
+ setTexCoords,
+ lambda: self.compareImage("testTexturedRect3"),
+ setFillTex,
+ lambda: self.compareImage("testTexturedRect4"),
+ setFillTexCoords,
+ lambda: self.compareImage("testTexturedRect5"),
+ setFillBitmap,
+ lambda: self.compareImage("testTexturedRect6"),
+ clearFillBitmap,
+ lambda: self.compareImage("testTexturedRect7"),
+ setFillBitmap,
+ lambda: self.compareImage("testTexturedRect6"),
+# setTransparentBorder,
+# lambda: self.compareImage("testTexturedRect8"),
+ ))
+
+ def testCurve(self):
+ def addCurve():
+ curve = avg.CurveNode(pos1=(10.5, 10), pos2=(10.5, 80), pos3=(80.5, 80),
+ pos4=(80.5, 10))
+ canvas.appendChild(curve)
+ return curve
+
+ def changeCurve():
+ curve.strokewidth = 19
+ curve.color="FFFF00"
+
+ def moveCurve():
+ curve.pos2 = (10.5, 120)
+ curve.pos3 = (80.5, 120)
+
+ def addCurve2():
+ curve = avg.CurveNode(pos1=(30.5, 10), pos2=(30.5, 120), pos3=(100.5, 120),
+ pos4=(100.5, 10))
+ curve.color="FF0000"
+ canvas.appendChild(curve)
+
+ canvas = self.makeEmptyCanvas()
+ curve = addCurve()
+ self.assertAlmostEqual(curve.length, 210)
+ self.assertAlmostEqual(curve.getPtOnCurve(0), (10.5,10))
+ self.assertAlmostEqual(curve.getPtOnCurve(1), (80.5,10))
+ self.assertAlmostEqual(curve.getPtOnCurve(0.5), (45.5,62.5))
+ self.start(False,
+ (lambda: self.compareImage("testCurve1"),
+ changeCurve,
+ lambda: self.compareImage("testCurve2"),
+ moveCurve,
+ lambda: self.compareImage("testCurve3"),
+ addCurve2,
+ lambda: self.compareImage("testCurve4"),
+ ))
+
+ def testTexturedCurve(self):
+ def addCurve():
+ curve = avg.CurveNode(pos1=(10.5, 10), pos2=(10.5, 80), pos3=(80.5, 80),
+ pos4=(80.5, 10), strokewidth=19, texhref="rgb24-64x64.png")
+ canvas.appendChild(curve)
+ return curve
+
+ def setTexCoords():
+ curve.texcoord1=-1
+ curve.texcoord2=2
+
+ canvas = self.makeEmptyCanvas()
+ curve = addCurve()
+ self.start(False,
+ (lambda: self.compareImage("testTexturedCurve1"),
+ setTexCoords,
+ lambda: self.compareImage("testTexturedCurve2")
+ ))
+
+ def testPolyLine(self):
+ def addPolyLine():
+ polyline = avg.PolyLineNode(strokewidth=2, color="FF00FF",
+ pos=[(10,10), (50,10), (90,50), (90, 90)])
+ canvas.appendChild(polyline)
+ return polyline
+
+ def changePolyLine():
+ polyline.strokewidth = 16
+ polyline.color="FFFF00"
+ pos = polyline.pos
+ pos.append((110, 90))
+ polyline.pos = pos
+
+ def miterPolyLine():
+ polyline.linejoin = "miter"
+
+ def addPolyLine2():
+ polyline2 = player.createNode(
+ """<polyline strokewidth="2" color="FF00FF"
+ pos="((110,10), (100,50), (110,70))" />""")
+ canvas.insertChild(polyline2,0)
+
+ def testEmptyPolyLine():
+ polyline2 = canvas.getChild(0)
+ polyline2.pos=[]
+
+ def testAlmostEmptyPolyLine():
+ polyline2 = canvas.getChild(0)
+ polyline2.pos=[(10,10)]
+
+ def testAcutePolyLine():
+ polyline2 = canvas.getChild(0)
+ polyline2.strokewidth = 10
+ polyline2.linejoin="bevel"
+ polyline2.pos = [(50,10), (60,10), (50,11)]
+ canvas.removeChild(1)
+
+ canvas = self.makeEmptyCanvas()
+ polyline = addPolyLine()
+ self.start(False,
+ (lambda: self.compareImage("testPolyLine1"),
+ changePolyLine,
+ lambda: self.compareImage("testPolyLine2"),
+ miterPolyLine,
+ lambda: self.compareImage("testPolyLine3"),
+ addPolyLine2,
+ lambda: self.compareImage("testPolyLine4"),
+ testEmptyPolyLine,
+ lambda: self.compareImage("testPolyLine5"),
+ testAlmostEmptyPolyLine,
+ lambda: self.compareImage("testPolyLine5"),
+ testAcutePolyLine,
+ lambda: self.compareImage("testPolyLine6")
+ ))
+
+ def testTexturedPolyLine(self):
+ def texturePolyLine():
+ polyline = avg.PolyLineNode(strokewidth=20, color="FF00FF",
+ texhref="rgb24-64x64.png", pos=((10,10), (50,10), (90,50), (90, 90)),
+ texcoords=(0, 0.3, 0.7, 1))
+ canvas.appendChild(polyline)
+ return polyline
+
+ def miter():
+ polyline.linejoin = "miter"
+
+ def setTexCoords():
+ polyline.texcoords = [-1, 0, 1, 2]
+
+ def repeatTexCoords():
+ polyline.pos = [(10,10), (30,10), (30,50), (50,50), (50,70), (70,70)]
+ polyline.texcoords = [1, 2, 3]
+
+ canvas = self.makeEmptyCanvas()
+ polyline = texturePolyLine()
+ self.start(False,
+ (lambda: self.compareImage("testTexturedPolyLine1"),
+ miter,
+ lambda: self.compareImage("testTexturedPolyLine2"),
+ setTexCoords,
+ lambda: self.compareImage("testTexturedPolyLine3"),
+ repeatTexCoords,
+ lambda: self.compareImage("testTexturedPolyLine4")
+ ))
+
+ def testPolygon(self):
+ def addPolygon():
+ polygon = avg.PolygonNode(strokewidth=2, color="FF00FF",
+ pos=((10,10), (50,10), (90,50), (90, 90)))
+ polygon.subscribe(avg.Node.CURSOR_DOWN, onMouseDown)
+ canvas.appendChild(polygon)
+ return polygon
+
+ def changePolygon():
+ polygon.strokewidth = 12
+ polygon.color="FFFF00"
+ pos = polygon.pos
+ pos.append((10, 90))
+ polygon.pos = pos
+
+ def fillPolygon():
+ polygon.strokewidth = 4
+ polygon.fillcolor = "00FFFF"
+ polygon.fillopacity = 0.5
+ pos = polygon.pos
+ pos.append((80, 50))
+ pos.append((50, 20))
+ pos.append((40, 40))
+ polygon.pos = pos
+
+ def addEmptyPoint():
+ pos = polygon.pos
+ pos.insert(1, (10, 10))
+ pos.append((40, 40))
+ polygon.pos = pos
+
+ def addPolygon2():
+ polygon = avg.PolygonNode(strokewidth=3, color="FF00FF",
+ pos=((100.5,10.5), (100.5,30.5), (120.5,30.5), (120.5, 10.5)))
+ canvas.insertChild(polygon, 0)
+
+ def miterPolygons():
+ polygon.linejoin = "miter"
+ polygon2 = canvas.getChild(0)
+ polygon2.linejoin = "miter"
+
+ def onMouseDown(event):
+ self.__mouseDownCalled = True
+
+ def addEmptyPolygon():
+ avg.PolygonNode(parent=canvas, fillopacity=1)
+
+ def createLeftOpenPolygon():
+ polygon.pos = ( (15,0), (35,0), (55,10), (65,30), (55,50), (35,60), (15,60),
+ (5,50), (15,40), (35,40), (35,30), (35,20), (15,20), (5,10) )
+ polygon.strokewidth = 2
+
+ def createUpOpenPolygon():
+ polygon.pos = ( (15,0), (25,10), (25,30), (35,30), (45,30), (45,10), (55,0),
+ (65,10), (65,30), (55,50), (35,60), (15,50), (5,30), (5,10) )
+
+ def createBottomOpenPolygon():
+ polygon.pos = ( (35,0), (55,10), (65,30), (65,50), (55,60), (45,50), (45,30),
+ (35,30), (25,30), (25,50), (15,60), (5,50), (5,30), (15,10) )
+
+ def createOneHole():
+ polygon.holes = ( [(35,10), (40,15), (35,20), (30,15)], )
+
+ def createMoreHoles():
+ newHoles = ( polygon.holes[0], [(20,35), (20,45), (10,40)],
+ [(50,35), (50,45), (60,40)], )
+ polygon.holes = newHoles
+
+ def clearCanvas():
+ for i in xrange(canvas.getNumChildren()-1):
+ dell = canvas.getChild(i)
+ canvas.removeChild(dell)
+
+ self.__mouseDownCalled = False
+ canvas = self.makeEmptyCanvas()
+ polygon = addPolygon()
+ self.start(False,
+ (lambda: self.compareImage("testPolygon1"),
+ changePolygon,
+ lambda: self.compareImage("testPolygon2"),
+ fillPolygon,
+ lambda: self.compareImage("testPolygon3"),
+ addEmptyPoint,
+ lambda: self.compareImage("testPolygon4"),
+ addPolygon2,
+ lambda: self.compareImage("testPolygon5"),
+ miterPolygons,
+ lambda: self.compareImage("testPolygon6"),
+ lambda: self.fakeClick(50, 50),
+ lambda: self.assertEqual(self.__mouseDownCalled, False),
+ lambda: self.fakeClick(20, 87),
+ lambda: self.assert_(self.__mouseDownCalled),
+ addEmptyPolygon,
+ clearCanvas,
+ createLeftOpenPolygon,
+ lambda: self.compareImage("testPolygon7"),
+ createUpOpenPolygon,
+ lambda: self.compareImage("testPolygon8"),
+ createBottomOpenPolygon,
+ lambda: self.compareImage("testPolygon9"),
+ createOneHole,
+ lambda: self.compareImage("testPolygonHole1"),
+ createMoreHoles,
+ lambda: self.compareImage("testPolygonHole2")
+ ))
+
+ def testTexturedPolygon(self):
+ def texturePolygon():
+ polygon = avg.PolygonNode(strokewidth=20, color="FF00FF",
+ texhref="rgb24-64x64.png", pos=((10,10), (50,10), (90,50), (90, 90)))
+ canvas.appendChild(polygon)
+ return polygon
+
+ def miter():
+ polygon.linejoin = "miter"
+
+ def setTexCoords():
+ polygon.texcoords = [-1, 0, 1, 2, 3]
+
+ def repeatTexCoords():
+ polygon.texcoords = [0, 1]
+
+ def setFillTex():
+ polygon.fillopacity=1
+ polygon.texhref=""
+ polygon.strokewidth=2
+ polygon.filltexhref="rgb24alpha-64x64.png"
+
+ def setFillTexCoords():
+ polygon.filltexcoord1=(0.5, 1)
+ polygon.filltexcoord2=(1.5, 3)
+
+ canvas = self.makeEmptyCanvas()
+ polygon = texturePolygon()
+ self.start(False,
+ (lambda: self.compareImage("testTexturedPolygon1"),
+ miter,
+ lambda: self.compareImage("testTexturedPolygon2"),
+ setTexCoords,
+ lambda: self.compareImage("testTexturedPolygon3"),
+ repeatTexCoords,
+ lambda: self.compareImage("testTexturedPolygon4"),
+ setFillTex,
+ lambda: self.compareImage("testTexturedPolygon5"),
+ setFillTexCoords,
+ lambda: self.compareImage("testTexturedPolygon6")
+ ))
+
+ def testPointInPolygon(self):
+ polygon_pos = [(10, 10), (50, 10), (90, 50), (90, 90)]
+ self.assert_(avg.pointInPolygon((50, 20), polygon_pos))
+ self.assert_(avg.pointInPolygon((10, 20), polygon_pos) == False)
+
+ def testCircle(self):
+ def addCircle():
+ circle = avg.CircleNode(pos=(30, 30), r=20)
+ circle.subscribe(avg.Node.CURSOR_DOWN, onMouseDown)
+ canvas.appendChild(circle)
+ return circle
+
+ def changeCircle():
+ circle.color="FF0000"
+ circle.fillcolor=u"FFFFFF"
+ circle.fillopacity=0.5
+ circle.strokewidth=3
+
+ def textureCircle():
+ circle.texhref="rgb24-64x64.png"
+ circle.strokewidth=20
+ circle.pos = (50, 50)
+ circle.texcoord1 = -1
+ circle.texcoord2 = 1
+
+ def setFillTex():
+ circle.strokewidth=1
+ circle.fillopacity=1
+ circle.texhref = ""
+ circle.filltexhref="rgb24alpha-64x64.png"
+
+ def setFillTexCoords():
+ circle.filltexcoord1 = (0.5, 0.5)
+ circle.filltexcoord2 = (1.5, 1.5)
+
+ def onMouseDown(event):
+ self.__mouseDownCalled = True
+
+ self.__mouseDownCalled = False
+ canvas = self.makeEmptyCanvas()
+ circle = addCircle()
+ self.start(False,
+ (lambda: self.compareImage("testCircle1"),
+ changeCircle,
+ lambda: self.compareImage("testCircle2"),
+ textureCircle,
+ lambda: self.compareImage("testCircle3"),
+ setFillTex,
+ lambda: self.compareImage("testCircle4"),
+ setFillTexCoords,
+ lambda: self.compareImage("testCircle5"),
+ lambda: self.fakeClick(32, 32),
+ lambda: self.assert_(self.__mouseDownCalled == False),
+ lambda: self.fakeClick(67, 50),
+ lambda: self.assert_(self.__mouseDownCalled)
+ ))
+
+ def testMesh(self):
+ def addMesh():
+ div = avg.DivNode()
+ mesh = avg.MeshNode(
+ texhref="rgb24-64x64.png",
+ vertexcoords=((0,0), (64,0), (0,64), (64, 64),(32, 32)),
+ texcoords=((0,0),(1,0),(0,1),(1,1),(0.5,0.5)),
+ triangles=((0,1,4),(1,3,4),(3,2,4),(2,0,4)))
+ div.appendChild(mesh)
+ div.x = 50
+ div.y = 30
+ canvas.appendChild(div)
+ return mesh
+
+ def setVertexCoords():
+ mesh.vertexcoords = ((0,0), (64,0), (0,64), (64, 64),(32, 64))
+
+ def setTexCoords():
+ mesh.vertexcoords = ((0,0), (64,0), (0,64), (64, 64),(32, 32))
+ mesh.texcoords = ((1,1),(1,1),(1,1),(1,1),(0.5,0.5))
+
+ def setTriangles():
+ mesh.vertexcoords = ((0,0), (64,0), (0,64), (64, 64),(31.5, 32))
+ mesh.texcoords = ((0,0),(1,0),(0,1),(1,1),(0.5,0.5))
+ mesh.triangles = ((3,1,4),(1,3,4),(1,2,4),(2,0,4))
+
+ def setTrianglesSameItem():
+ mesh.vertexcoords = ((0,0), (64,0), (0,64), (64, 64),(32, 32))
+ mesh.texcoords = ((0,0),(1,0),(0,1),(1,1),(0.5,0.5))
+ mesh.triangles = ((1,1,1),(2,2,2),(3,3,3),(4,4,4))
+
+ def setHref():
+ mesh.texhref = "rgb24alpha-64x64.png"
+
+ def setBackfaceCullTrue():
+ mesh.texhref="rgb24-64x64.png"
+ mesh.vertexcoords = ((0,0), (64,0), (0,64), (64, 64),(31.5, 32))
+ mesh.texcoords = ((0,0),(1,0),(0,1),(1,1),(0.5,0.5))
+ mesh.triangles = ((3,1,4),(1,3,4),(1,2,4),(2,0,4))
+ mesh.backfacecull = True
+
+ def setBackfaceCullFalse():
+ mesh.backfacecull = False
+
+ def setIllegalVertexes():
+ mesh.vertexcoords = ((0,0), (64,0), (0,64), (64, 64),(32, 32), (16,16))
+
+ def setIllegalTextures():
+ mesh.texcoords = ((100,0),(1,0),(0,1),(1,1),(0.5,0.5), (1.0,1.0))
+
+ def setIllegalIndexes():
+ mesh.triangles = ((27,1,1),(1,3,4),(3,2,4),(2,0,4))
+
+ canvas = self.makeEmptyCanvas()
+ mesh = addMesh()
+ self.assertException(setIllegalVertexes)
+ self.assertException(setIllegalTextures)
+ self.assertException(setIllegalIndexes)
+ self.start(False,
+ (lambda: self.compareImage("testMesh1"),
+ setVertexCoords,
+ lambda: self.compareImage("testMesh2"),
+ setTexCoords,
+ lambda: self.compareImage("testMesh3"),
+ setTriangles,
+ lambda: self.compareImage("testMesh4"),
+ setHref,
+ lambda: self.compareImage("testMesh5"),
+ setTrianglesSameItem,
+ lambda: self.compareImage("testMesh6"),
+ setBackfaceCullTrue,
+ lambda: self.compareImage("testMesh7"),
+ setBackfaceCullFalse,
+ lambda: self.compareImage("testMesh8")
+ ))
+
+ def testInactiveVector(self):
+ def addVectorNode():
+ node = avg.LineNode(pos1=(2, 2), pos2=(50, 2), strokewidth=2)
+ canvas.appendChild(node)
+ return node
+
+ def addFilledVectorNode():
+ node = avg.RectNode(pos=(2, 6), size=(50, 30), strokewidth=2)
+ node.subscribe(avg.Node.CURSOR_DOWN, onDown)
+ canvas.appendChild(node)
+ return node
+
+ def onDown(Event):
+ vNode.active = False
+ fvNode.active = False
+ self.onDownCalled = not self.onDownCalled
+
+ canvas = self.makeEmptyCanvas()
+ vNode = addVectorNode()
+ fvNode = addFilledVectorNode()
+ self.onDownCalled = False
+ self.start(False,
+ (lambda: self.compareImage("testInactiveVector1"),
+ lambda: self.fakeClick(20, 20),
+ lambda: self.assert_(self.onDownCalled),
+ lambda: self.compareImage("testInactiveVector2"),
+ lambda: self.fakeClick(20, 20),
+ lambda: self.assert_(self.onDownCalled)
+ ))
+
+
+def vectorTestSuite(tests):
+ availableTests = (
+ "testLine",
+ "testLotsOfLines",
+ "testLineOpacity",
+ "testTexturedLine",
+ "testRect",
+ "testTexturedRect",
+ "testCurve",
+ "testTexturedCurve",
+ "testPolyLine",
+ "testTexturedPolyLine",
+ "testPolygon",
+ "testTexturedPolygon",
+ "testPointInPolygon",
+ "testCircle",
+ "testMesh",
+ "testInactiveVector"
+ )
+ return createAVGTestSuite(availableTests, VectorTestCase, tests)
diff --git a/src/test/WidgetTest.py b/src/test/WidgetTest.py
new file mode 100644
index 0000000..720171e
--- /dev/null
+++ b/src/test/WidgetTest.py
@@ -0,0 +1,900 @@
+# -*- coding: utf-8 -*-
+# libavg - Media Playback Engine.
+# Copyright (C) 2003-2014 Ulrich von Zadow
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Current versions can be found at www.libavg.de
+#
+
+from libavg import avg, textarea, widget, player
+
+from testcase import *
+
+class WidgetTestCase(AVGTestCase):
+ def __init__(self, testFuncName):
+ AVGTestCase.__init__(self, testFuncName)
+
+ def testKeyboard(self):
+ def createKbd(pos, shiftKey=None, feedbackImage=None):
+ keyDefs = [
+ [("a", "A"), ( 5, 5), (30, 30), False],
+ [("1", ), (35, 5), (30, 30), False],
+ ["SHIFT", (65, 5), (50, 30), True]]
+ kbd = widget.Keyboard("keyboard_bg.png", "keyboard_down.png", keyDefs,
+ shiftKey, feedbackSrc=feedbackImage, pos=pos, parent=root)
+
+ for msg in (widget.Keyboard.DOWN, widget.Keyboard.UP, widget.Keyboard.CHAR):
+ kbd.subscribe(msg, lambda keyCode, msg=msg: onMessage(msg, keyCode))
+ return kbd
+
+ def onMessage(msg, keyCode):
+ self.__messageTester.setMessageReceived(msg)
+ self.__keyCode = keyCode
+
+ def assertState(msgs, keyCode, imageSrc):
+ self.__messageTester.assertState(msgs)
+ self.assert_(self.__keyCode == keyCode)
+ self.compareImage(imageSrc)
+
+ root = self.loadEmptyScene()
+ self.__keyCode = ""
+
+ # Keyboard without shift support, no feedback image.
+ kbNoShift = createKbd((10, 10))
+ self.__messageTester = MessageTester(kbNoShift, [], self)
+
+ self.start(False,
+ (lambda: self.compareImage("testUIKeyboard"),
+ # test character key
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 30, 30),
+ lambda: assertState((widget.Keyboard.DOWN,), "a", "testUIKeyboardA"),
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_UP, 30, 30),
+ lambda: assertState((widget.Keyboard.CHAR,widget.Keyboard.UP),
+ "a", "testUIKeyboard"),
+ # test command key
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 100, 30),
+ lambda: assertState((widget.Keyboard.DOWN,), "SHIFT", "testUIKeyboardS"),
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_UP, 100, 30),
+ lambda: assertState((widget.Keyboard.UP,), "SHIFT", "testUIKeyboard"),
+ # test multiple keys
+ lambda: self._sendTouchEvent(1, avg.Event.CURSOR_DOWN, 100, 30),
+ lambda: self._sendTouchEvent(2, avg.Event.CURSOR_DOWN, 30, 30),
+ lambda: assertState((widget.Keyboard.DOWN,), "a", "testUIKeyboardAS"),
+ lambda: self._sendTouchEvent(3, avg.Event.CURSOR_DOWN, 60, 30),
+ lambda: assertState((widget.Keyboard.DOWN,), "1", "testUIKeyboardA1S"),
+ lambda: self._sendTouchEvent(2, avg.Event.CURSOR_UP, 30, 30),
+ lambda: assertState((widget.Keyboard.CHAR,widget.Keyboard.UP),
+ "a", "testUIKeyboard1S"),
+ lambda: self._sendTouchEvent(3, avg.Event.CURSOR_UP, 60, 30),
+ lambda: assertState((widget.Keyboard.CHAR,widget.Keyboard.UP),
+ "1", "testUIKeyboardS"),
+ lambda: self._sendTouchEvent(1, avg.Event.CURSOR_UP, 100, 30),
+ lambda: assertState((widget.Keyboard.UP,), "SHIFT", "testUIKeyboard"),
+ ))
+
+ root = self.loadEmptyScene()
+ self.__keyCode = ""
+
+ # Keyboard with shift support, feedback image.
+ kbd = createKbd((10, 60), "SHIFT", "keyboard_feedback.png")
+ self.__messageTester = MessageTester(kbd, [], self)
+
+ self.start(False,
+ # test shift key
+ (lambda: self.compareImage("testUIKeyboardFB"),
+ lambda: self._sendTouchEvent(1, avg.Event.CURSOR_DOWN, 100, 80),
+ lambda: self._sendTouchEvent(2, avg.Event.CURSOR_DOWN, 30, 80),
+ lambda: assertState((widget.Keyboard.DOWN,), "a", "testUIKeyboardFBAS"),
+ lambda: self._sendTouchEvent(3, avg.Event.CURSOR_DOWN, 60, 80),
+ lambda: assertState((widget.Keyboard.DOWN,), "1", "testUIKeyboardFBA1S"),
+ lambda: self._sendTouchEvent(2, avg.Event.CURSOR_UP, 30, 80),
+ lambda: assertState((widget.Keyboard.CHAR,widget.Keyboard.UP),
+ "A", "testUIKeyboardNoFB1S"),
+ lambda: self._sendTouchEvent(3, avg.Event.CURSOR_UP, 60, 80),
+ lambda: assertState((widget.Keyboard.CHAR,widget.Keyboard.UP),
+ "1", "testUIKeyboardFBS"),
+ lambda: self._sendTouchEvent(1, avg.Event.CURSOR_UP, 100, 80),
+ lambda: assertState((widget.Keyboard.UP,), "SHIFT", "testUIKeyboardFB"),
+ # test drag over keys
+ lambda: self._sendTouchEvent(1, avg.Event.CURSOR_DOWN, 60, 80),
+ lambda: assertState((widget.Keyboard.DOWN,), "1", "testUIKeyboardFB1"),
+ lambda: self._sendTouchEvent(1, avg.Event.CURSOR_MOTION, 60, 50),
+ lambda: assertState((widget.Keyboard.UP,), "1", "testUIKeyboardFB"),
+ lambda: self._sendTouchEvent(1, avg.Event.CURSOR_MOTION, 100, 80),
+ lambda: assertState((widget.Keyboard.DOWN,), "SHIFT",
+ "testUIKeyboardFBS"),
+ lambda: self._sendTouchEvent(1, avg.Event.CURSOR_MOTION, 60, 80),
+ lambda: assertState((widget.Keyboard.DOWN,widget.Keyboard.UP),
+ "1", "testUIKeyboardFB1"),
+ lambda: self._sendTouchEvent(1, avg.Event.CURSOR_UP, 60, 80),
+ lambda: assertState((widget.Keyboard.CHAR,widget.Keyboard.UP),
+ "1", "testUIKeyboardFB"),
+ ))
+
+ def testTextArea(self):
+ def setup():
+ self.ta1 = textarea.TextArea(pos=(2,2), size=(156, 96), parent=root)
+ self.ta1.setStyle(font="Bitstream vera sans", variant="Roman", fontsize=16,
+ multiline=True, color='FFFFFF')
+ self.ta1.setText('Lorem ipsum')
+ self.ta1.setFocus(True) # TODO: REMOVE
+
+ self.ta2 = textarea.TextArea(pos=(2,100), size=(156, 18), parent=root)
+ self.ta2.setStyle(font="Bitstream vera sans", variant="Roman", fontsize=14,
+ multiline=False, color='4b94ef', cursorColor='FF0000',
+ flashingCursor=False)
+ self.ta2.setText('sit dolor')
+ self.ta2.showCursor(False)
+ self.ta2.setFocus(True) # TODO: REMOVE
+
+ def setAndCheck(ta, text):
+ ta.setText(text)
+ self.assertEqual(ta.getText(), text)
+
+ def clear(ta):
+ ta.onKeyDown(textarea.KEYCODE_FORMFEED)
+ self.assertEqual(ta.getText(), '')
+
+ def testUnicode():
+ self.ta1.setText(u'some ùnìcöde')
+ self.ta1.onKeyDown(textarea.KEYCODES_BACKSPACE[0])
+ self.assertEqual(self.ta1.getText(), u'some ùnìcöd')
+ self.ta1.onKeyDown(textarea.KEYCODES_BACKSPACE[1])
+ self.ta1.onKeyDown(textarea.KEYCODES_BACKSPACE[0])
+ self.assertEqual(self.ta1.getText(), u'some ùnìc')
+ self.ta1.onKeyDown(ord(u'Ä'))
+ self.assertEqual(self.ta1.getText(), u'some ùnìcÄ')
+
+ def testSpecialChars():
+ clear(self.ta1)
+ self.ta1.onKeyDown(ord(u'&'))
+ self.ta1.onKeyDown(textarea.KEYCODES_BACKSPACE[0])
+ self.assertEqual(self.ta1.getText(), '')
+
+ def checkSingleLine():
+ text = ''
+ self.ta2.setText('')
+ while True:
+ self.assert_(len(text) < 20)
+ self.ta2.onKeyDown(ord(u'A'))
+ text = text + 'A'
+ if text != self.ta2.getText():
+ break
+
+ root = self.loadEmptyScene()
+
+ player.setFakeFPS(20)
+ textarea.init(avg, False)
+ self.start(True,
+ (setup,
+ lambda: self.delay(200),
+ lambda: self.assertEqual(self.ta1.getText(), 'Lorem ipsum'),
+ lambda: setAndCheck(self.ta1, ''),
+ lambda: setAndCheck(self.ta2, 'Lorem Ipsum'),
+ testUnicode,
+ lambda: self.compareImage("testTextArea1"),
+ testSpecialChars,
+ checkSingleLine,
+ lambda: self.compareImage("testTextArea2"),
+ lambda: self.ta2.showCursor(True),
+ lambda: self.delay(200),
+ lambda: self._sendTouchEvent(1, avg.Event.CURSOR_DOWN, 30, 100),
+ lambda: self._sendTouchEvent(1, avg.Event.CURSOR_UP, 30, 100),
+ lambda: self.compareImage("testTextArea3"),
+ lambda: self._sendTouchEvent(2, avg.Event.CURSOR_DOWN, 130, 100),
+ lambda: self.delay(1100),
+ lambda: self.compareImage("testTextArea4"),
+ lambda: self._sendTouchEvent(2, avg.Event.CURSOR_MOTION, 30, 100),
+ lambda: self.compareImage("testTextArea5"),
+ lambda: self._sendTouchEvent(2, avg.Event.CURSOR_UP, 30, 100),
+ lambda: self.compareImage("testTextArea3"),
+ ))
+ player.setFakeFPS(-1)
+
+ def testFocusContext(self):
+ def setup():
+ textarea.init(avg)
+ self.ctx1 = textarea.FocusContext()
+ self.ctx2 = textarea.FocusContext()
+
+ self.ta1 = textarea.TextArea(self.ctx1, pos=(2,2), size=(156,54), parent=root)
+ self.ta1.setStyle(fontsize=16, multiline=True, color='FFFFFF')
+ self.ta1.setText('Lorem ipsum')
+
+ self.ta2 = textarea.TextArea(self.ctx1, pos=(2,58), size=(76,54), parent=root)
+ self.ta2.setStyle(fontsize=14, multiline=False, color='FFFFFF')
+ self.ta2.setText('dolor')
+
+ self.bgImage = avg.ImageNode(href="1x1_white.png", size=(76,54))
+ self.ta3 = textarea.TextArea(self.ctx2, disableMouseFocus=True, pos=(80,58),
+ size=(76,54), textBackgroundNode=self.bgImage, parent=root)
+ self.ta3.setStyle(fontsize=14, multiline=True, color='FFFFFF')
+ self.ta3.setText('dolor sit amet')
+
+ textarea.setActiveFocusContext(self.ctx1)
+
+ def writeChar():
+ helper = player.getTestHelper()
+ helper.fakeKeyEvent(avg.Event.KEY_DOWN, 65, 65, "A", 65, 0)
+ helper.fakeKeyEvent(avg.Event.KEY_UP, 65, 65, "A", 65, 0)
+ helper.fakeKeyEvent(avg.Event.KEY_DOWN, 66, 66, "B", 66, 0)
+ helper.fakeKeyEvent(avg.Event.KEY_UP, 66, 66, "B", 66, 0)
+ helper.fakeKeyEvent(avg.Event.KEY_DOWN, 67, 67, "C", 67, 0)
+ helper.fakeKeyEvent(avg.Event.KEY_UP, 67, 67, "C", 67, 0)
+
+ def switchFocus():
+ self.ctx1.cycleFocus()
+
+ def clearFocused():
+ self.ctx1.clear()
+
+ def clickForFocus():
+ self._sendMouseEvent(avg.Event.CURSOR_DOWN, 20, 70)
+ self._sendMouseEvent(avg.Event.CURSOR_UP, 20, 70)
+
+ root = self.loadEmptyScene()
+ self.start(True,
+ (setup,
+ lambda: self.compareImage("testFocusContext1"),
+ writeChar,
+ lambda: self.compareImage("testFocusContext2"),
+ switchFocus,
+ writeChar,
+ lambda: self.compareImage("testFocusContext3"),
+ switchFocus,
+ clearFocused,
+ lambda: self.compareImage("testFocusContext4"),
+ clickForFocus,
+ clearFocused,
+ lambda: self.compareImage("testFocusContext5"),
+ ))
+
+
+ def testButton(self):
+
+ def enable(enabled):
+ button.enabled = enabled
+
+ def createScene(**kwargs):
+ root = self.loadEmptyScene()
+ button = widget.Button(
+ parent = root,
+ upNode = avg.ImageNode(href="button_up.png"),
+ downNode = avg.ImageNode(href="button_down.png"),
+ disabledNode = avg.ImageNode(href="button_disabled.png"),
+ **kwargs
+ )
+ self.messageTester = MessageTester(button,
+ [widget.Button.CLICKED, widget.Button.PRESSED,
+ widget.Button.RELEASED], self)
+ return button
+
+ def runTest():
+ self.start(False,
+ (# Standard down->up
+ self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 0, 0,
+ [widget.Button.PRESSED]),
+ lambda: self.compareImage("testUIButtonDown"),
+ self._genMouseEventFrames(avg.Event.CURSOR_UP, 0, 0,
+ [widget.Button.CLICKED, widget.Button.RELEASED]),
+ lambda: self.compareImage("testUIButtonUp"),
+
+ # Disable, down, up -> no click
+ lambda: self.assert_(button.enabled),
+ lambda: enable(False),
+ lambda: self.assert_(not(button.enabled)),
+ lambda: self.compareImage("testUIButtonDisabled"),
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 0, 0),
+ self._genMouseEventFrames(avg.Event.CURSOR_UP, 0, 0, []),
+ lambda: enable(True),
+ lambda: self.assert_(button.enabled),
+
+ # Down, up further away -> no click
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 0, 0),
+ self._genMouseEventFrames(avg.Event.CURSOR_UP, 100, 0,
+ [widget.Button.PRESSED, widget.Button.RELEASED]),
+ lambda: self.compareImage("testUIButtonUp"),
+
+ # Down, move further away, up -> no click
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 0, 0),
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_MOTION, 100, 0),
+ self._genMouseEventFrames(avg.Event.CURSOR_UP, 100, 0,
+ [widget.Button.PRESSED, widget.Button.RELEASED]),
+ lambda: self.compareImage("testUIButtonUp"),
+
+ # Test if button still reacts after abort
+ self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 0, 0,
+ [widget.Button.PRESSED]),
+ lambda: self.compareImage("testUIButtonDown"),
+ self._genMouseEventFrames(avg.Event.CURSOR_UP, 0, 0,
+ [widget.Button.CLICKED, widget.Button.RELEASED]),
+ lambda: self.compareImage("testUIButtonUp"),
+ ))
+
+ button = createScene()
+ runTest()
+
+ button = createScene(activeAreaNode=avg.CircleNode(r=5, opacity=0))
+ runTest()
+
+ button = createScene(fatFingerEnlarge=True)
+ runTest()
+
+ root = self.loadEmptyScene()
+ button = widget.BmpButton(
+ parent = root,
+ upSrc = "button_up.png",
+ downSrc = "button_down.png",
+ disabledSrc = "button_disabled.png",
+ )
+ self.messageTester = MessageTester(button,
+ [widget.Button.CLICKED, widget.Button.PRESSED, widget.Button.RELEASED],
+ self)
+ runTest()
+
+ button = createScene(enabled=False)
+ self.start(False,
+ (lambda: self.compareImage("testUIButtonDisabled"),
+ ))
+
+ def testTextButton(self):
+ root = self.loadEmptyScene()
+ button = widget.TextButton("text", parent=root, size=(50,42))
+ self.messageTester = MessageTester(button,
+ [widget.Button.CLICKED, widget.Button.PRESSED, widget.Button.RELEASED],
+ self)
+ self.start(True,
+ (# Standard down->up
+ self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 0, 0,
+ [widget.Button.PRESSED]),
+ lambda: self.compareImage("testTextButtonDown"),
+ self._genMouseEventFrames(avg.Event.CURSOR_UP, 0, 0,
+ [widget.Button.CLICKED, widget.Button.RELEASED]),
+ lambda: self.compareImage("testTextButtonUp"),
+
+ # Check disabled graphics
+ lambda: self.assert_(button.enabled),
+ lambda: button.setEnabled(False),
+ lambda: self.assert_(not(button.enabled)),
+ lambda: self.compareImage("testTextButtonDisabled"),
+ lambda: button.setEnabled(True),
+
+ # Change text
+ lambda: button.setText("newText"),
+ lambda: self.compareImage("testTextButtonUpNewText"),
+ self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 0, 0,
+ [widget.Button.PRESSED]),
+ lambda: self.compareImage("testTextButtonDownNewText"),
+ ))
+
+
+ def testToggleButton(self):
+
+ def onToggled(isToggled):
+ self.messageTester.setMessageReceived(widget.ToggleButton.TOGGLED)
+ self.toggled = isToggled
+
+ def createScene(**kwargs):
+ root = self.loadEmptyScene()
+ button = widget.ToggleButton(
+ uncheckedUpNode = avg.ImageNode(href="toggle_unchecked_Up.png"),
+ uncheckedDownNode = avg.ImageNode(href="toggle_unchecked_Down.png"),
+ checkedUpNode = avg.ImageNode(href="toggle_checked_Up.png"),
+ checkedDownNode = avg.ImageNode(href="toggle_checked_Down.png"),
+ uncheckedDisabledNode =
+ avg.ImageNode(href="toggle_unchecked_Disabled.png"),
+ checkedDisabledNode =
+ avg.ImageNode(href="toggle_checked_Disabled.png"),
+ parent=root,
+ **kwargs
+ )
+ self.messageTester = MessageTester(button,
+ [widget.ToggleButton.PRESSED, widget.ToggleButton.RELEASED], self)
+
+ button.subscribe(widget.ToggleButton.TOGGLED, onToggled)
+ return button
+
+ def testToggle():
+ self.start(False,
+ (lambda: self.compareImage("testUIToggleUnchecked_Up"),
+ self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 0, 0,
+ [widget.ToggleButton.PRESSED]),
+ lambda: self.assert_(not self.toggled),
+ lambda: self.compareImage("testUIToggleUnchecked_Down"),
+ self._genMouseEventFrames(avg.Event.CURSOR_UP, 0, 0,
+ [widget.ToggleButton.RELEASED, widget.ToggleButton.TOGGLED]),
+ lambda: self.assert_(self.toggled),
+ lambda: self.compareImage("testUIToggleChecked_Up"),
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 0, 0),
+ lambda: self.compareImage("testUIToggleChecked_Down"),
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_UP, 0, 0),
+ lambda: self.assert_(not(self.toggled)),
+ lambda: self.compareImage("testUIToggleUnchecked_Up"),
+ ))
+
+ def testToggleAbort():
+ self.start(False,
+ (lambda: self.compareImage("testUIToggleUnchecked_Up"),
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 0, 0),
+ lambda: self.compareImage("testUIToggleUnchecked_Down"),
+ self._genMouseEventFrames(avg.Event.CURSOR_UP, 100, 0,
+ [widget.ToggleButton.PRESSED, widget.ToggleButton.RELEASED]),
+ lambda: self.assert_(not self.toggled),
+ lambda: self.compareImage("testUIToggleUnchecked_Up"),
+ lambda: button.setChecked(True),
+ lambda: self.compareImage("testUIToggleChecked_Up"),
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 0, 0),
+ lambda: self.compareImage("testUIToggleChecked_Down"),
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_UP, 100, 0),
+ lambda: self.assert_(not(self.toggled)),
+ lambda: self.compareImage("testUIToggleChecked_Up"),
+ ))
+
+ def testToggleDisable():
+ self.start(False,
+ (lambda: self.compareImage("testUIToggleUnchecked_Disabled"),
+ lambda: self._sendTouchEvent(1, avg.Event.CURSOR_DOWN, 0, 0),
+ lambda: self._sendTouchEvent(1, avg.Event.CURSOR_UP, 0, 0),
+ lambda: self.compareImage("testUIToggleUnchecked_Disabled"),
+ lambda: button.setEnabled(True),
+ lambda: self.compareImage("testUIToggleUnchecked_Up"),
+ lambda: self._sendTouchEvent(2, avg.Event.CURSOR_DOWN, 0, 0),
+ lambda: button.setEnabled(False),
+ lambda: self._sendTouchEvent(2, avg.Event.CURSOR_UP, 0, 0),
+ lambda: self.assert_(not(self.toggled)),
+ lambda: self.compareImage("testUIToggleUnchecked_Disabled"),
+
+ lambda: button.setEnabled(True),
+ lambda: self.compareImage("testUIToggleUnchecked_Up"),
+ lambda: button.setChecked(True),
+ lambda: self.compareImage("testUIToggleChecked_Up"),
+ lambda: button.setEnabled(False),
+ lambda: self.compareImage("testUIToggleChecked_Disabled"),
+ lambda: self._sendTouchEvent(3, avg.Event.CURSOR_DOWN, 0, 0),
+ lambda: self._sendTouchEvent(3, avg.Event.CURSOR_UP, 0, 0),
+ lambda: self.compareImage("testUIToggleChecked_Disabled"),
+ lambda: button.setEnabled(True),
+ lambda: self.compareImage("testUIToggleChecked_Up"),
+ lambda: self._sendTouchEvent(4, avg.Event.CURSOR_DOWN, 0, 0),
+ lambda: button.setEnabled(False),
+ lambda: self._sendTouchEvent(4, avg.Event.CURSOR_UP, 0, 0),
+ lambda: self.assert_(not(self.toggled)),
+ lambda: self.compareImage("testUIToggleChecked_Disabled"),
+ ))
+
+ def testFromSrc():
+ root = self.loadEmptyScene()
+ button = widget.BmpToggleButton(
+ uncheckedUpSrc="toggle_unchecked_Up.png",
+ uncheckedDownSrc="toggle_unchecked_Down.png",
+ checkedUpSrc="toggle_checked_Up.png",
+ checkedDownSrc="toggle_checked_Down.png",
+ uncheckedDisabledSrc="toggle_unchecked_Disabled.png",
+ checkedDisabledSrc="toggle_checked_Disabled.png",
+ parent=root)
+ button.subscribe(widget.ToggleButton.TOGGLED, onToggled)
+ self.start(False,
+ (lambda: self.compareImage("testUIToggleUnchecked_Up"),
+ lambda: button.setChecked(True),
+ lambda: self.compareImage("testUIToggleChecked_Up"),
+ lambda: button.setChecked(False),
+ lambda: button.setEnabled(False),
+ lambda: self.compareImage("testUIToggleUnchecked_Disabled"),
+ lambda: button.setChecked(True),
+ lambda: self.compareImage("testUIToggleChecked_Disabled"),
+ ))
+
+ self.toggled = False
+ button = createScene()
+ testToggle()
+
+ button = createScene()
+ testToggleAbort()
+
+ button = createScene(enabled = False)
+ testToggleDisable()
+
+ button = createScene(activeAreaNode = avg.CircleNode(r=5, opacity=0))
+ testToggle()
+
+ button = createScene(fatFingerEnlarge = True)
+ testToggle()
+
+ testFromSrc()
+
+
+ def testCheckBox(self):
+
+ root = self.loadEmptyScene()
+ avg.RectNode(size=(160,120), fillcolor="FFFFFF", fillopacity=1, parent=root)
+ checkBox = widget.CheckBox(text="checkboxtext", pos=(10,10), parent=root)
+
+ self.start(True,
+ (lambda: self.compareImage("testUICheckBoxUnchecked_Up"),
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 15, 15),
+ lambda: self.compareImage("testUICheckBoxUnchecked_Down"),
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_UP, 15, 15),
+ lambda: self.compareImage("testUICheckBoxChecked_Up"),
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 15, 15),
+ lambda: self.compareImage("testUICheckBoxChecked_Down"),
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_UP, 15, 15),
+ lambda: self.compareImage("testUICheckBoxUnchecked_Up"),
+ lambda: checkBox.setEnabled(False),
+ lambda: self.compareImage("testUICheckBoxUnchecked_Disabled"),
+ lambda: checkBox.setEnabled(True),
+ lambda: self.compareImage("testUICheckBoxUnchecked_Up"),
+ # Test click on text.
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 50, 15),
+ lambda: self.compareImage("testUICheckBoxUnchecked_Down"),
+ ))
+
+
+ def testScrollPane(self):
+ def scrollLarge():
+ scrollPane.contentpos = (34, 34)
+ self.assertEqual(scrollPane.contentpos, (32,32))
+
+ def initSmallContent():
+ scrollPane.size = (64, 64)
+ contentArea.size = (32, 32)
+ image.size = (32, 32)
+ scrollPane.contentpos = (0, 0)
+ self.assertEqual(scrollPane.getMaxContentPos(), (0,0))
+
+ def scrollSmall():
+ scrollPane.contentpos = (32, 32)
+
+ root = self.loadEmptyScene()
+ contentArea = avg.DivNode(size=(64,64))
+ image = avg.ImageNode(href="rgb24-64x64.png", parent=contentArea)
+ scrollPane = widget.ScrollPane(contentNode=contentArea, size=(32,32), parent=root)
+
+ self.start(False,
+ (lambda: self.compareImage("testScrollPane1"),
+ scrollLarge,
+ lambda: self.compareImage("testScrollPane2"),
+ initSmallContent,
+ lambda: self.compareImage("testScrollPane3"),
+ scrollSmall,
+ lambda: self.compareImage("testScrollPane3"),
+ ))
+
+ def testStretchNode(self):
+
+ def changeExtent():
+ if orientation == widget.Orientation.HORIZONTAL:
+ self.node.width = 100
+ else:
+ self.node.height = 100
+
+ def minExtent():
+ if orientation == widget.Orientation.HORIZONTAL:
+ self.node.width = 3
+ self.assert_(self.node.width == 31)
+ else:
+ self.node.height = 3
+ self.assert_(self.node.height == 31)
+
+ for orientation, orName in (
+ (widget.Orientation.HORIZONTAL,"Horiz"),
+ (widget.Orientation.VERTICAL, "Vert"),):
+ root = self.loadEmptyScene()
+ if orientation == widget.Orientation.HORIZONTAL:
+ self.node = widget.HStretchNode(src="media/rgb24-32x32.png",
+ endsExtent=15, size=(31,31), parent=root)
+ else:
+ self.node = widget.VStretchNode(src="media/rgb24-32x32.png",
+ endsExtent=15, size=(31,31), parent=root)
+ self.start(False,
+ (lambda: self.compareImage("testStretchNode"+orName+"1"),
+ changeExtent,
+ lambda: self.compareImage("testStretchNode"+orName+"2"),
+ minExtent,
+ lambda: self.compareImage("testStretchNode"+orName+"1"),
+ ))
+
+
+ def testHVStretchNode(self):
+
+ def changeSize():
+ self.node.size = (64, 64)
+ self.assert_(self.node.size == (64,64))
+
+ root = self.loadEmptyScene()
+ self.node = widget.HVStretchNode(src="media/rgb24-32x32.png", endsExtent=(5,5),
+ size=(31,31), parent=root)
+ self.start(False,
+ (lambda: self.compareImage("testHVStretchNode1"),
+ changeSize,
+ lambda: self.compareImage("testHVStretchNode2"),
+ ))
+
+
+ def testSlider(self):
+ def onThumbPosChanged(pos):
+ self.thumbPos = pos
+
+ def setSize():
+ if orientation == widget.Orientation.HORIZONTAL:
+ self.node.width=140
+ else:
+ self.node.height=60
+
+ sys.stderr.write("\n")
+ for orientation, orName in (
+ (widget.Orientation.HORIZONTAL, "Horiz"),
+ (widget.Orientation.VERTICAL, "Vert")):
+ for widgetType in ("Slider", "TimeSlider"):
+ sys.stderr.write(" "+widgetType+", "+orName+"\n")
+ root = self.loadEmptyScene()
+ if widgetType == "Slider":
+ self.node = widget.Slider(orientation=orientation, pos=(20,20),
+ width=100, height=100, parent=root)
+ else:
+ self.node = widget.TimeSlider(orientation=orientation, pos=(20,20),
+ width=100, height=100, parent=root)
+ self.start(False,
+ (lambda: self.compareImage("test"+widgetType+orName+"1"),
+ lambda: self.node.setThumbPos(0.25),
+ lambda: self.compareImage("test"+widgetType+orName+"2"),
+ lambda: self.node.setThumbPos(1),
+ lambda: self.compareImage("test"+widgetType+orName+"3"),
+ lambda: self.node.setRange((1,10)),
+ lambda: self.compareImage("test"+widgetType+orName+"1"),
+ lambda: self.node.setRange((10,1)),
+ lambda: self.compareImage("test"+widgetType+orName+"3"),
+ setSize,
+ lambda: self.compareImage("test"+widgetType+orName+"4"),
+ lambda: self.node.setEnabled(False),
+ lambda: self.compareImage("test"+widgetType+orName+"5"),
+ lambda: self.node.setEnabled(True),
+ lambda: self.compareImage("test"+widgetType+orName+"4"),
+ ))
+
+
+ def testScrollBar(self):
+
+ def onThumbPosChanged(pos):
+ self.thumbPos = pos
+
+ for orientation, orName in (
+ (widget.Orientation.HORIZONTAL, "Horiz"),
+ (widget.Orientation.VERTICAL, "Vert")):
+ root = self.loadEmptyScene()
+ self.node = widget.ScrollBar(orientation=orientation, pos=(20,20),
+ width=100, height=100, parent=root)
+ self.start(False,
+ (lambda: self.compareImage("testScrollBar"+orName+"1"),
+ lambda: self.node.setThumbExtent(0.5),
+ lambda: self.compareImage("testScrollBar"+orName+"2"),
+ lambda: self.node.setThumbPos(0.25),
+ lambda: self.compareImage("testScrollBar"+orName+"3"),
+ lambda: self.node.setThumbPos(5),
+ lambda: self.compareImage("testScrollBar"+orName+"4"),
+ lambda: self.node.setRange((0,10)),
+ lambda: self.node.setThumbPos(4.75),
+ lambda: self.compareImage("testScrollBar"+orName+"5"),
+ lambda: self.node.setRange((10,20)),
+ lambda: self.node.setThumbPos(14.75),
+ lambda: self.compareImage("testScrollBar"+orName+"5"),
+ lambda: self.node.setThumbExtent(10),
+ lambda: self.compareImage("testScrollBar"+orName+"6"),
+ lambda: self.node.setRange((10,0)),
+ lambda: self.node.setThumbExtent(0.5),
+ lambda: self.node.setThumbPos(4.75),
+ lambda: self.compareImage("testScrollBar"+orName+"5"),
+ ))
+
+ # Horizontal
+ root = self.loadEmptyScene()
+ self.node = widget.ScrollBar(orientation=widget.Orientation.HORIZONTAL,
+ pos=(20,5), width=100, parent=root)
+ self.messageTester = MessageTester(self.node,
+ [widget.Slider.PRESSED, widget.Slider.RELEASED], self)
+ self.start(False,
+ (lambda: self.node.setThumbExtent(0.5),
+ # User input
+ self._genMouseEventFrames(avg.Event.CURSOR_DOWN, 25, 10,
+ [widget.Slider.PRESSED]),
+ lambda: self.compareImage("testScrollBarHoriz7"),
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_MOTION, 50, 10),
+ lambda: self.compareImage("testScrollBarHoriz8"),
+ lambda: self.assertAlmostEqual(self.node.getThumbPos(), 0.25),
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_MOTION, 25, 10),
+ lambda: self.compareImage("testScrollBarHoriz9"),
+ lambda: self.assertAlmostEqual(self.node.getThumbPos(), 0),
+ self._genMouseEventFrames(avg.Event.CURSOR_UP, 0, 10,
+ [widget.Slider.RELEASED]),
+ lambda: self.compareImage("testScrollBarHoriz10"),
+ lambda: self.assertAlmostEqual(self.node.getThumbPos(), 0),
+
+ # Publish/Subscribe interface
+ lambda: self.node.subscribe(widget.ScrollBar.THUMB_POS_CHANGED,
+ onThumbPosChanged),
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 25, 10),
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_UP, 50, 10),
+ lambda: self.assertAlmostEqual(self.thumbPos, 0.25),
+
+ # Enable/disable
+ self.messageTester.reset,
+ lambda: self.node.setEnabled(False),
+ lambda: self.compareImage("testScrollBarHoriz11"),
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 50, 10),
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_UP, 25, 10),
+ lambda: self.messageTester.assertState([]),
+ lambda: self.assertAlmostEqual(self.thumbPos, 0.25),
+ lambda: self.node.setEnabled(True),
+ lambda: self.compareImage("testScrollBarHoriz12"),
+
+ # Disable after down: Drag aborted
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 50, 10),
+ lambda: self.node.setEnabled(False),
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_UP, 25, 10),
+ lambda: self.assertAlmostEqual(self.thumbPos, 0.25),
+ lambda: self.node.setEnabled(True),
+ lambda: self.compareImage("testScrollBarHoriz12"),
+ ))
+
+ # Vertical: Don't need to test everything again, just make sure coords are
+ # calculated correctly.
+ root = self.loadEmptyScene()
+ self.node = widget.ScrollBar(orientation=widget.Orientation.VERTICAL, pos=(5,5),
+ height=100, parent=root)
+ self.start(False,
+ (lambda: self.node.setThumbExtent(0.5),
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 10, 25),
+ lambda: self.compareImage("testScrollBarVert7"),
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_MOTION, 10, 50),
+ lambda: self.compareImage("testScrollBarVert8"),
+ lambda: self.assertAlmostEqual(self.node.getThumbPos(), 0.25),
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_UP, 10, 0),
+ lambda: self.compareImage("testScrollBarVert9"),
+ lambda: self.assertAlmostEqual(self.node.getThumbPos(), 0),
+ ))
+
+ def testProgressBar(self):
+
+ def setValue(value):
+ self.node.value = value
+
+ def setRange(range):
+ self.node.range = range
+
+ root = self.loadEmptyScene()
+ self.node = widget.ProgressBar(orientation=widget.Orientation.HORIZONTAL,
+ pos=(5,5), width=100, parent=root)
+ self.start(False,
+ (lambda: self.compareImage("testProgressBar1"),
+ lambda: setValue(0.5),
+ lambda: self.compareImage("testProgressBar2"),
+ lambda: setValue(1),
+ lambda: self.compareImage("testProgressBar3"),
+ lambda: setRange((23,42)),
+ lambda: self.compareImage("testProgressBar1"),
+ lambda: setValue(32.5),
+ lambda: self.compareImage("testProgressBar2"),
+ ))
+
+ def testMediaControl(self):
+
+ def onSeek(time):
+ self.messageTester.setMessageReceived(widget.MediaControl.SEEK_MOTION)
+
+ root = self.loadEmptyScene()
+ self.node = widget.MediaControl(size=(160,30), parent=root)
+ self.messageTester = MessageTester(self.node,
+ [widget.MediaControl.PLAY_CLICKED, widget.MediaControl.PAUSE_CLICKED,
+ widget.MediaControl.SEEK_PRESSED, widget.MediaControl.SEEK_RELEASED],
+ self)
+ self.node.subscribe(widget.MediaControl.SEEK_MOTION, onSeek)
+ self.start(True,
+ (lambda: self.compareImage("testMediaControl1"),
+ lambda: self.node.setDuration(60*1000),
+ lambda: self.compareImage("testMediaControl2"),
+ lambda: self.node.setTime(30*1000),
+ lambda: self.compareImage("testMediaControl3"),
+ lambda: self.node.setTime(60*1000),
+ lambda: self.compareImage("testMediaControl4"),
+ lambda: self.node.play(),
+ lambda: self.compareImage("testMediaControl5"),
+ lambda: self.node.pause(),
+ lambda: self.compareImage("testMediaControl4"),
+ self.messageTester.reset,
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 1, 1),
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_UP, 1, 1),
+ lambda: self.messageTester.assertState(
+ [widget.MediaControl.PLAY_CLICKED,]),
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 1, 1),
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_UP, 1, 1),
+ lambda: self.messageTester.assertState(
+ [widget.MediaControl.PAUSE_CLICKED,]),
+ lambda: self.node.setTime(0),
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 56, 5),
+ lambda: self.messageTester.assertState(
+ [widget.MediaControl.SEEK_PRESSED]),
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_MOTION, 150, 5),
+ lambda: self.messageTester.assertState(
+ [widget.MediaControl.SEEK_MOTION,]),
+ lambda: self.compareImage("testMediaControl4"),
+ lambda: self._sendMouseEvent(avg.Event.CURSOR_UP, 150, 5),
+ lambda: self.messageTester.assertState(
+ [widget.MediaControl.SEEK_RELEASED,]),
+ ))
+
+ def testScrollArea(self):
+ def setSize(size):
+ self.node.size = size
+
+ root = self.loadEmptyScene()
+ image = avg.ImageNode(href="rgb24-64x64.png", size=(200,400))
+ self.node = widget.ScrollArea(contentNode=image, size=(80,80), parent=root)
+ self.start(False,
+ (lambda: self.compareImage("testScrollArea1"),
+ lambda: setSize((120,80)),
+ lambda: self.compareImage("testScrollArea2"),
+ ))
+
+ def testScrollAreaCustomSkin(self):
+ root = self.loadEmptyScene()
+ image = avg.ImageNode(href="rgb24-64x64.png", size=(200, 400))
+ pwdPath = os.path.dirname(os.path.realpath(__file__))
+ mediaPath = os.path.join(pwdPath, "media")
+ skin = widget.Skin("CustomSkin.xml", mediaPath)
+ self.node = widget.ScrollArea(contentNode=image, size=(80, 80), skinObj=skin,
+ parent=root)
+ self.start(False,
+ (lambda: self.compareImage("testScrollArea3"),))
+
+ def testCustomMediaDir(self):
+ root = self.loadEmptyScene()
+
+ pwdPath = os.path.dirname(os.path.realpath(__file__))
+ mediaPath = os.path.join(pwdPath, "media")
+ skin = widget.Skin("SimpleSkin.xml", mediaPath)
+ downBmpPath = skin.textButtonCfg[None]['downBmp'].getName()
+ upBmpPath = skin.textButtonCfg[None]['upBmp'].getName()
+ self.assert_(downBmpPath == os.path.join(mediaPath, 'button_bg_down.png'))
+ self.assert_(upBmpPath == os.path.join(mediaPath, 'button_bg_up.png'))
+
+ customSkinMediaPath = os.path.join(mediaPath, 'incompleteSkinMedia')
+ skin = widget.Skin("IncompleteSkin.xml", customSkinMediaPath)
+ self.node = widget.ScrollBar(orientation=widget.Orientation.HORIZONTAL,
+ pos=(20,5), width=100, parent=root, skinObj=skin)
+ self.start(False, ())
+
+
+def widgetTestSuite(tests):
+ availableTests = (
+ "testKeyboard",
+ "testTextArea",
+ "testFocusContext",
+ "testButton",
+ "testTextButton",
+ "testToggleButton",
+ "testCheckBox",
+ "testScrollPane",
+ "testStretchNode",
+ "testHVStretchNode",
+ "testSlider",
+ "testScrollBar",
+ "testProgressBar",
+ "testMediaControl",
+ "testScrollArea",
+ "testScrollAreaCustomSkin",
+ "testCustomMediaDir",
+ )
+
+ return createAVGTestSuite(availableTests, WidgetTestCase, tests)
diff --git a/src/test/WordsTest.py b/src/test/WordsTest.py
new file mode 100644
index 0000000..a5e856e
--- /dev/null
+++ b/src/test/WordsTest.py
@@ -0,0 +1,701 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# libavg - Media Playback Engine.
+# Copyright (C) 2003-2014 Ulrich von Zadow
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Current versions can be found at www.libavg.de
+#
+
+import platform
+
+from libavg import avg, player
+from testcase import *
+
+class WordsTestCase(AVGTestCase):
+ def __init__(self, testFuncName):
+ AVGTestCase.__init__(self, testFuncName)
+
+ def testSimpleWords(self):
+ def checkFont():
+ self.assertEqual(node.variant, "bold")
+
+ def checkUnicodeText():
+ node.text = u"föa"
+ avg.WordsNode(text=u"öäü", font="Bitstream Vera Sans")
+
+ fontList = avg.WordsNode.getFontFamilies()
+ try:
+ fontList.index("Bitstream Vera Sans")
+ except ValueError:
+ self.fail("Font not found")
+ variantList = avg.WordsNode.getFontVariants("Bitstream Vera Sans")
+ self.assert_(len(variantList) >= 4)
+ root = self.loadEmptyScene()
+ avg.WordsNode (pos=(1,1), fontsize=12, font="Bitstream Vera Sans",
+ text="Bitstream Vera Sans", variant="roman", parent=root)
+ node = avg.WordsNode(pos=(1,16), fontsize=12, font="Bitstream Vera Sans",
+ text="Bold", variant="bold", parent=root)
+ self.assertNotEqual(node.size, (0,0))
+ node.getGlyphPos(0)
+ self.start(True,
+ (lambda: self.compareImage("testSimpleWords"),
+ checkFont,
+ checkUnicodeText,
+ ))
+
+ def testRedrawOnDemand(self):
+
+ def changeText(newText):
+ size = node.size
+ node.text = newText
+ self.assertNotEqual(node.size, size)
+
+ def changeFont():
+ size = node.size
+ node.fontsize = 18
+ self.assertNotEqual(node.size, size)
+
+ root = self.loadEmptyScene()
+ node = avg.WordsNode(font="Bitstream Vera Sans", fontsize=12, text="foo",
+ parent=root)
+ changeText("foobar")
+ self.start(True,
+ (lambda: changeText("bar"),
+ changeFont,
+ ))
+
+ def testFontStyle(self):
+
+ def setStyle(node, style):
+ node.fontstyle = style
+ self.assert_(node.fontsize == 15)
+
+ fontStyle = avg.FontStyle(font="Bitstream Vera Sans", variant="Roman",
+ fontsize=12)
+ self.assert_(fontStyle.font == "Bitstream Vera Sans")
+ root = self.loadEmptyScene()
+ words = avg.WordsNode(pos=(1,1), fontstyle=fontStyle, text="Bitstream Vera Sans",
+ parent=root)
+ avg.WordsNode (pos=(1,16), fontstyle=fontStyle, variant="bold", text="Bold",
+ parent=root)
+ otherFontStyle = fontStyle
+ otherFontStyle.fontsize = 15
+ self.start(True,
+ (lambda: self.compareImage("testFontStyle1"),
+ lambda: setStyle(words, otherFontStyle),
+ lambda: self.compareImage("testFontStyle2"),
+ ))
+
+ def testBaseStyle(self):
+ attrs = {"font": "Bitstream Vera Sans",
+ "variant": "Bold",
+ "color": "FF0000",
+ "aagamma": 0.5,
+ "fontsize": 20,
+ "indent": 1,
+ "linespacing": 2,
+ "alignment": "right",
+ "wrapmode": "char",
+ "justify": True,
+ "letterspacing": 3,
+ "hint": False}
+ defaultStyle = avg.FontStyle()
+ fontStyle1 = avg.FontStyle(basestyle=defaultStyle, **attrs)
+ for attrName in attrs.iterkeys():
+ self.assert_(getattr(fontStyle1, attrName) != getattr(defaultStyle, attrName))
+ self.assert_(getattr(fontStyle1, attrName) == attrs[attrName])
+ fontStyle2 = avg.FontStyle(basestyle=fontStyle1)
+ for attrName in attrs.iterkeys():
+ self.assert_(getattr(fontStyle2, attrName) == getattr(fontStyle1, attrName))
+
+ def testGlyphPos(self):
+ def posAlmostEqual(pos1, pos2):
+ return math.fabs(pos1[0]-pos2[0]) <= 2 and math.fabs(pos1[1]-pos2[1]) <= 2
+
+ node = avg.WordsNode(text="Bold", font="Bitstream Vera Sans")
+ self.assertEqual(node.getGlyphPos(0), (0,0))
+ size = node.getGlyphSize(0)
+ self.assert_(posAlmostEqual(size, (10, 18)))
+ self.assert_(posAlmostEqual(node.getGlyphPos(3), (22,0)))
+ size = node.getGlyphSize(3)
+ self.assert_(posAlmostEqual(size, (8, 18)))
+ self.assertException(lambda: node.getGlyphPos(4))
+ node.text=u"föa"
+ self.assert_(posAlmostEqual(node.getGlyphPos(1), (4,0)))
+# print [ node.getGlyphPos(i) for i in range(3)]
+ self.assert_(posAlmostEqual(node.getGlyphPos(2), (12,0)))
+ self.assertException(lambda: node.getGlyphPos(3))
+
+ def testParaWords(self):
+ root = self.loadEmptyScene()
+ avg.LineNode(pos1=(0.5, 0), pos2=(0.5, 50), color="FF0000", parent=root)
+ avg.LineNode(pos1=(119.5, 0.5), pos2=(119.5, 50), color="FF0000", parent=root)
+ avg.LineNode(pos1=(74.5,60), pos2=(74.5, 110), color="FF0000", parent=root)
+ avg.WordsNode(id="para", pos=(1,1), fontsize=12, width=70,
+ font="Bitstream Vera Sans", text="Left-justified paragraph.",
+ parent=root)
+ avg.WordsNode(id="paracenter", pos=(120,1), fontsize=12, width=70,
+ font="Bitstream Vera Sans", text="Centered paragraph",
+ alignment="center", parent=root)
+ avg.WordsNode(id="pararight", pos=(75,60), fontsize=12, width=70,
+ font="Bitstream Vera Sans", alignment="right",
+ text="Right-justified paragraph.<i>l</i>",
+ parent=root)
+ avg.WordsNode(id="paralinespacing", pos=(80,60), fontsize=12, width=70,
+ font="Bitstream Vera Sans", linespacing=-4,
+ text="Paragraph with custom line spacing.",
+ parent=root)
+ self.start(True, [lambda: self.compareImage("testParaWords")])
+
+ def testJustify(self):
+ root = self.loadEmptyScene()
+ avg.WordsNode(pos=(1,1), fontsize=12, font="Bitstream Vera Sans",
+ variant="roman", justify=True, width=100,
+ text="Justified paragraph more than one line long.", parent=root)
+ self.start(True, [lambda: self.compareImage("testJustify")])
+
+ def testWrapMode(self):
+ def setCharMode():
+ node.wrapmode = 'char'
+
+ def setWordMode():
+ node.wrapmode = 'word'
+
+ def setWordCharMode():
+ node.wrapmode = 'wordchar'
+
+ root = self.loadEmptyScene()
+ node = avg.WordsNode(pos=(1,1), fontsize=12, font="Bitstream Vera Sans",
+ variant="roman", width=100,
+ text="""Wrapped paragraph more than one line long.
+ Withaverylongpackedlinewithnobreaks""",
+ parent=root)
+ self.start(True,
+ (lambda: self.compareImage("testWrapMode1"),
+ setCharMode,
+ lambda: self.compareImage("testWrapMode2"),
+ setWordMode,
+ lambda: self.compareImage("testWrapMode3"),
+ setWordCharMode,
+ lambda: self.compareImage("testWrapMode4"),
+ ))
+
+ def testWordsMask(self):
+ def setMask():
+ try:
+ node.maskhref = "mask1.png"
+ except RuntimeError:
+ self.skip("no shader support")
+ player.stop()
+
+ def setColor():
+ node.color = "FFFF00"
+
+ def setOpacity():
+ node.opacity = 0.5
+
+ def setSize():
+ rect = avg.RectNode(pos=(39.5, 30.5), size=(80, 60))
+ root.appendChild(rect)
+ node.masksize = (160, 120)
+ node.opacity = 1
+
+ def setPos():
+ node.pos = (40, 20)
+ node.maskpos = (-40, -20)
+
+ def setDefaultSize():
+ node.masksize = (0,0)
+
+ def setCentered():
+ node.alignment = "center"
+ node.masksize = (160, 120)
+ node.pos = (80,20)
+ node.maskpos = (0, -20)
+
+ root = self.loadEmptyScene()
+ node = avg.WordsNode(fontsize=8, linespacing=-4, font="Bitstream Vera Sans",
+ variant="roman", width=160,
+ text="Ich bin nur ein kleiner Blindtext. Wenn ich gross bin, will ich \
+ Ulysses von James Joyce werden. Aber jetzt lohnt es sich noch nicht, \
+ mich weiterzulesen. Denn vorerst bin ich nur ein kleiner Blindtext. \
+ Ich bin nur ein kleiner Blindtext. Wenn ich gross bin, will ich \
+ Ulysses von James Joyce werden. Aber jetzt lohnt es sich noch nicht, \
+ mich weiterzulesen. Denn vorerst bin ich nur ein kleiner Blindtext. \
+ Ich bin nur ein kleiner Blindtext. Wenn ich gross bin, will ich \
+ Ulysses von James Joyce werden. Aber jetzt lohnt es sich noch nicht, \
+ mich weiterzulesen. Denn vorerst bin ich nur ein kleiner Blindtext.",
+ parent=root)
+ self.start(True,
+ (setMask,
+ lambda: self.compareImage("testWordsMask1"),
+ setColor,
+ lambda: self.compareImage("testWordsMask2"),
+ setOpacity,
+ lambda: self.compareImage("testWordsMask3"),
+ setSize,
+ lambda: self.compareImage("testWordsMask4"),
+ setPos,
+ lambda: self.compareImage("testWordsMask5"),
+ setDefaultSize,
+ lambda: self.compareImage("testWordsMask6"),
+ setCentered,
+ lambda: self.compareImage("testWordsMask7"),
+ ))
+
+ def testHinting(self):
+ def checkPositions():
+# node0 = root.getChild(0)
+# for i in range(len(node0.text)):
+# print node0.getGlyphPos(i)
+ noHint = root.getChild(0)
+ hint = root.getChild(1)
+ posNoHint = noHint.getGlyphPos(6)
+ posHint = hint.getGlyphPos(6)
+ self.assertNotEqual(posNoHint, posHint)
+ noHint.hint = True
+ hint.hint = False
+ self.assertEqual(posNoHint, hint.getGlyphPos(6))
+ self.assertEqual(posHint, noHint.getGlyphPos(6))
+
+ if platform.system() == "Linux":
+ self.skip("Linux support requires modified font config")
+ else:
+ root = self.loadEmptyScene()
+ avg.WordsNode(pos=(1,1), fontsize=12, font="Bitstream Vera Sans",
+ variant="roman", hint=False, text="Lorem ipsum dolor (no hinting)",
+ parent=root)
+ avg.WordsNode(pos=(1,15), fontsize=12, font="Bitstream Vera Sans",
+ variant="roman", hint=True, text="Lorem ipsum dolor (hinting)",
+ parent=root)
+ self.start(True, [checkPositions])
+
+
+ def testSpanWords(self):
+ def setTextAttrib():
+ self.baselineBmp = player.screenshot()
+ player.getElementByID("words").text = self.text
+
+ def checkSameImage():
+ bmp = player.screenshot()
+ self.assert_(self.areSimilarBmps(bmp, self.baselineBmp, 0, 0))
+
+ def createUsingDict():
+ player.getElementByID("words").unlink()
+ node = avg.WordsNode(id="words", pos=(1,1), fontsize=12, width=120,
+ font="Bitstream Vera Sans", variant="roman", text=self.text)
+ root.appendChild(node)
+
+ self.text = """
+ Markup:
+ <span size='14000' rise='5000' foreground='red'>span</span>,
+ <i>italics</i>, <b>bold</b>
+ """
+ root = self.loadEmptyScene()
+ node = player.createNode("""
+ <words id="words" x="1" y="1" fontsize="12" width="120"
+ font="Bitstream Vera Sans" variant="roman">
+ """
+ +self.text+
+ """
+ </words>
+ """)
+ root.appendChild(node)
+ self.start(True,
+ [lambda: self.compareImage("testSpanWords"),
+ setTextAttrib,
+ lambda: self.compareImage("testSpanWords"),
+ checkSameImage,
+ createUsingDict,
+ lambda: self.compareImage("testSpanWords"),
+ checkSameImage,
+ ])
+
+ def testDynamicWords(self):
+ def changeText():
+ oldwidth = words.width
+ words.text = "blue"
+ self.assertNotEqual(words.width, oldwidth)
+ words.color = "404080"
+ words.x += 10
+
+ def changeHeight():
+ words.height = 28
+
+ def activateText():
+ words.active = True
+
+ def deactivateText():
+ words.active = False
+
+ def changeFont():
+ words.font = "Bitstream Vera Sans"
+ words.height = 0
+ words.fontsize = 30
+
+ def changeFont2():
+ words.fontsize = 18
+
+ def changeTextWithInvalidTag():
+ try:
+ words.text = "This <invalid_tag/>bombs"
+ except:
+ words.text = "except"
+ self.assertEqual(words.text, "except")
+
+ root = self.loadEmptyScene()
+ words = avg.WordsNode(pos=(1,1), fontsize=12, font="Bitstream Vera Sans",
+ text="foo", parent=root)
+ self.start(True,
+ (lambda: self.compareImage("testDynamicWords1"),
+ changeText,
+ changeHeight,
+ changeFont,
+ lambda: self.compareImage("testDynamicWords2"),
+ deactivateText,
+ lambda: self.compareImage("testDynamicWords3"),
+ activateText,
+ changeFont2,
+ lambda: self.compareImage("testDynamicWords4"),
+ changeTextWithInvalidTag
+ ))
+
+ def testI18NWords(self):
+ def changeUnicodeText():
+ words.text = "Arabic nonsense: ﯿﭗ"
+
+ def setNBSP():
+ words.width=100
+ words.text=(u"blindtext1\u00A0blindtext2\u00Ablindtext3 "+
+ u"blindtext4\u00A0blindtext\u00A0blindtext\u00A0")
+
+ root = self.loadEmptyScene()
+ avg.WordsNode(pos=(1,1), fontsize=14, font="Bitstream Vera Sans",
+ text="一二三四五六七八九", parent=root)
+ words = avg.WordsNode(pos=(1,24), fontsize=12, font="Bitstream Vera Sans",
+ text="foo", parent=root)
+ root.appendChild(
+ player.createNode("""
+ <words x="1" y="48" fontsize="12" font="Bitstream Vera Sans">
+ &amp;
+ </words>
+ """))
+ avg.WordsNode(pos=(12,48), fontsize=12, font="Bitstream Vera Sans", text="&amp;",
+ rawtextmode=True, parent=root)
+
+ self.start(True,
+ (lambda: self.compareImage("testI18NWords1"),
+ changeUnicodeText,
+ lambda: self.compareImage("testI18NWords2"),
+ setNBSP,
+ lambda: self.compareImage("testI18NWords3"),
+ ))
+
+ def testRawText(self):
+ def createDynNodes():
+ self.dictdnode = avg.WordsNode(text='&lt;test dyndict&amp;',
+ rawtextmode=True, pos=(1,65), font='Bitstream Vera Sans',
+ variant='roman', fontsize=12)
+ root.appendChild(self.dictdnode)
+
+ self.xmldnode = player.createNode("""
+ <words text="&lt;test dynattr&amp;" fontsize="12"
+ font="Bitstream Vera Sans" variant="roman" rawtextmode="true"
+ x="1" y="85"/>""")
+ root.appendChild(self.xmldnode)
+
+ def switchRawMode():
+ self.dictdnode.rawtextmode = False
+ valNode.rawtextmode = True
+ attribNode.rawtextmode = True
+
+ def bombIt():
+ def cantRun():
+ self.xmldnode.rawtextmode = False
+ self.assert_(0)
+ self.assertException(cantRun)
+
+ def assignNewTexts():
+ text = u'&ùùààxx>'
+ self.dictdnode.rawtextmode = True
+ self.dictdnode.text = text
+ self.xmldnode.text = text
+ valNode.text = text
+ attribNode.text = text
+
+ root = self.loadEmptyScene()
+ attribNode = avg.WordsNode(text="ùnicòdé <b>bold</b>",
+ fontsize=12, pos=(1,5), font="Bitstream Vera Sans", parent=root)
+ valNode = player.createNode("""
+ <words id="nodeval" fontsize="10" x="1" y="25" font="Bitstream Vera Sans"><b>bold</b> ùnicòdé &lt;</words>""")
+ root.appendChild(valNode)
+ root.appendChild(
+ player.createNode("""
+ <words x="1" y="45" fontsize="15" font="Bitstream Vera Sans">
+ &amp;
+ </words>"""))
+
+ self.start(True,
+ (lambda: self.compareImage("testRawText1"),
+ createDynNodes,
+ lambda: self.compareImage("testRawText2"),
+ switchRawMode,
+ lambda: self.compareImage("testRawText3"),
+ bombIt,
+ assignNewTexts,
+ lambda: self.compareImage("testRawText4"),
+ ))
+
+ def testWordsBR(self):
+ root = self.loadEmptyScene()
+ avg.WordsNode(pos=(1,1), fontsize=12, font="Bitstream Vera Sans", variant="roman",
+ text="paragraph 1<br/>paragraph 2", parent=root)
+ self.start(True,
+ [lambda: self.compareImage("testWordsBR")])
+
+ def testLetterSpacing(self):
+ def setSpacing():
+ player.getElementByID("words1").letterspacing=-2
+ player.getElementByID("words2").letterspacing=-2
+
+ root = self.loadEmptyScene()
+ avg.WordsNode(id="words1", pos=(1,1), fontsize=12, font="Bitstream Vera Sans",
+ variant="roman",
+ text="""normal
+ <span letter_spacing="-2048"> packed</span>
+ <span letter_spacing="2048"> spaced</span>""",
+ parent=root)
+ avg.WordsNode(id="words2", pos=(1,20), fontsize=12, font="Bitstream Vera Sans",
+ variant="roman", letterspacing=2, text="spaced", parent=root)
+ self.start(True,
+ (lambda: self.compareImage("testLetterSpacing1"),
+ setSpacing,
+ lambda: self.compareImage("testLetterSpacing2")
+ ))
+
+ def testPositioning(self):
+ def click(pos):
+ self.fakeClick(int(pos[0]), int(pos[1]))
+
+ def testInside(bInside):
+ ok = bInside == self.clicked
+ self.clicked = False
+ return ok
+
+ def onMouse(event):
+ self.clicked = True
+
+ root = self.loadEmptyScene()
+ avg.LineNode(pos1=(4, 20.5), pos2=(157, 20.5), color="FF0000", parent=root)
+ avg.LineNode(pos1=(4.5, 20.5), pos2=(4.5, 110), color="FF0000", parent=root)
+ avg.LineNode(pos1=(156.5, 20.5), pos2=(156.5, 110), color="FF0000", parent=root)
+ avg.LineNode(pos1=(80.5, 20.5), pos2=(80.5, 110), color="FF0000", parent=root)
+ avg.WordsNode(id="left", pos=(4,20), fontsize=12, font="Bitstream Vera Sans",
+ variant="roman", text="Norm", parent=root)
+ avg.WordsNode(pos=(45,20), fontsize=12, font="Bitstream Vera Sans",
+ variant="roman", text="orm", parent=root)
+ avg.WordsNode(pos=(75,20), fontsize=12, font="Bitstream Vera Sans",
+ variant="roman", text="ÖÄÜ", parent=root)
+ avg.WordsNode(pos=(4,40), fontsize=12, font="Bitstream Vera Sans",
+ variant="oblique", text="Jtalic", parent=root)
+ avg.WordsNode(id="right", pos=(156,60), fontsize=12, alignment="right",
+ font="Bitstream Vera Sans", variant="roman", text="Right-aligned",
+ parent=root)
+ avg.WordsNode(id="center", pos=(80,80), fontsize=12, alignment="center",
+ font="Bitstream Vera Sans", variant="roman", text="Centered",
+ parent=root)
+ for id in ["left", "center", "right"]:
+ player.getElementByID(id).subscribe(avg.Node.CURSOR_DOWN, onMouse)
+ self.clicked = False
+ leftWidth = player.getElementByID("left").getMediaSize()[0]
+ centerWidth = player.getElementByID("center").getMediaSize()[0]
+ rightWidth = player.getElementByID("right").getMediaSize()[0]
+
+ self.start(True,
+ (lambda: self.compareImage("testPositioning"),
+ lambda: click((4,20)),
+ lambda: self.assert_(testInside(True)),
+ lambda: click((3,20)),
+ lambda: self.assert_(testInside(False)),
+ lambda: click((3+leftWidth,20)),
+ lambda: self.assert_(testInside(True)),
+ lambda: click((4+leftWidth,20)),
+ lambda: self.assert_(testInside(False)),
+
+ lambda: click((81-centerWidth/2,80)),
+ lambda: self.assert_(testInside(True)),
+ lambda: click((80-centerWidth/2,80)),
+ lambda: self.assert_(testInside(False)),
+ lambda: click((80+centerWidth/2,80)),
+ lambda: self.assert_(testInside(True)),
+ lambda: click((81+centerWidth/2,80)),
+ lambda: self.assert_(testInside(False)),
+
+ lambda: click((156-rightWidth,60)),
+ lambda: self.assert_(testInside(True)),
+ lambda: click((155-rightWidth,60)),
+ lambda: self.assert_(testInside(False)),
+ lambda: click((155,60)),
+ lambda: self.assert_(testInside(True)),
+ lambda: click((156,60)),
+ lambda: self.assert_(testInside(False)),
+ ))
+
+ def testInvalidColor(self):
+ def testColor(col):
+ avg.WordsNode(color=col)
+
+ def assignValidColor():
+ testColor('123456')
+
+ def assignInvalidColor1():
+ testColor('1234567')
+
+ def assignInvalidColor2():
+ testColor('xxx')
+
+ def assignInvalidColor3():
+ testColor('xxxxxx')
+
+ self.loadEmptyScene()
+ self.start(True,
+ (self.assertException(assignInvalidColor1),
+ self.assertException(assignInvalidColor2),
+ self.assertException(assignInvalidColor3),
+ ))
+
+ def testFontDir(self):
+ avg.WordsNode.addFontDir('extrafonts')
+ root = self.loadEmptyScene()
+ avg.WordsNode(font="testaddfontdir", fontsize=50, text="ABAAA", parent=root)
+ self.start(True,
+ (lambda: self.compareImage("testFontDir"),))
+
+ def testGetNumLines(self):
+ textNode = avg.WordsNode(text="paragraph 1<br/>paragraph 2<br/>paragraph 3")
+ self.assertEqual(textNode.getNumLines(), 3)
+ textNode.text = ""
+ self.assertEqual(textNode.getNumLines(), 0)
+
+ def testGetLineExtents(self):
+ textNode = avg.WordsNode(fontsize = 100,
+ font = "Bitstream Vera Sans",
+ text = "bla <br/> blabli <br/> blabliblabla")
+ self.assertEqual(textNode.getLineExtents(0), (184,117))
+ self.assertEqual(textNode.getLineExtents(1), (303,117))
+
+ def testGetCharIndexFromPos(self):
+ textNode = avg.WordsNode(fontsize=30,
+ font = "Bitstream Vera Sans",
+ text = "A B C D E F G H Ä Ö Ü ? Ì Á Í Å Ø ∏ ~ ç Ç Å",
+ width = 300)
+
+ for k in (1,2,3,23,42):
+ pos = textNode.getGlyphPos(k)
+ char = textNode.getCharIndexFromPos(pos)
+ self.assertEqual(char, k)
+
+ def testGetTextAsDisplayed(self):
+ orgText = "A<br/>B C <b>D</b> E F G H <i>Ä</i> Ö Ü ? Ì Á<br/>Í Å Ø ∏ ~ ç Ç Å"
+ orgTextWithout = "A\nB C D E F G H Ä Ö Ü ? Ì Á\nÍ Å Ø ∏ ~ ç Ç Å"
+ textNode = avg.WordsNode(fontsize=30,
+ font = "Bitstream Vera Sans",
+ text = orgText,
+ width = 300)
+ self.assertEqual(orgTextWithout, textNode.getTextAsDisplayed())
+
+ def testSetWidth(self):
+ root = self.loadEmptyScene()
+ text = "42 " * 42
+ textNode = avg.WordsNode(
+ parent=root,
+ fontsize = 10,
+ font = "Bitstream Vera Sans",
+ text = text)
+
+ def testSize(p1, p2):
+ self.assert_(abs(p1.x - p2.x) < 5)
+ self.assert_(abs(p1.y - p2.y) < 50)
+
+ testSize(textNode.size, avg.Point2D(630,13))
+ testSize(textNode.getMediaSize(), avg.Point2D(630,13))
+ mediaSize = textNode.getMediaSize()
+
+ def changeSize():
+ textNode.width = 50
+ testSize(textNode.size, avg.Point2D(50,182))
+ testSize(textNode.getMediaSize(), avg.Point2D(45,182))
+ self.assertNotEqual(mediaSize, textNode.getMediaSize())
+
+ self.start(True,
+ [lambda: changeSize()])
+
+ def testTooWide(self):
+ root = self.loadEmptyScene()
+ text = "42 " * 42 * 20
+ avg.WordsNode(parent=root, text=text)
+ self.assertException(
+ lambda: self.start((None, None))
+ )
+
+ def testWordsGamma(self):
+
+ def setGamma():
+ node.aagamma = 4
+
+ root = self.loadEmptyScene()
+ for i, gamma in enumerate((2, 1.5, 1)):
+ node = avg.WordsNode(pos=(1,i*20), fontsize=12, font="Bitstream Vera Sans",
+ variant="roman", aagamma=gamma, text="lorem ipsum dolor",
+ parent=root)
+ self.start(True,
+ (lambda: self.compareImage("testWordsGamma1"),
+ setGamma,
+ lambda: self.compareImage("testWordsGamma2"),
+ ))
+
+
+def wordsTestSuite(tests):
+ availableTests = (
+ "testSimpleWords",
+ "testRedrawOnDemand",
+ "testFontStyle",
+ "testBaseStyle",
+ "testGlyphPos",
+ "testParaWords",
+ "testJustify",
+ "testWrapMode",
+ "testWordsMask",
+ "testHinting",
+ "testSpanWords",
+ "testDynamicWords",
+ "testI18NWords",
+ "testRawText",
+ "testWordsBR",
+ "testLetterSpacing",
+ "testPositioning",
+ "testInvalidColor",
+ "testFontDir",
+ "testGetNumLines",
+ "testGetLineExtents",
+ "testGetCharIndexFromPos",
+ "testGetTextAsDisplayed",
+ "testSetWidth",
+ "testTooWide",
+ "testWordsGamma",
+ )
+ return createAVGTestSuite(availableTests, WordsTestCase, tests)
diff --git a/src/test/baseline/test2VideosAtOnce1.png b/src/test/baseline/test2VideosAtOnce1.png
new file mode 100644
index 0000000..f561888
--- /dev/null
+++ b/src/test/baseline/test2VideosAtOnce1.png
Binary files differ
diff --git a/src/test/baseline/testAVGFile.png b/src/test/baseline/testAVGFile.png
new file mode 100644
index 0000000..375582b
--- /dev/null
+++ b/src/test/baseline/testAVGFile.png
Binary files differ
diff --git a/src/test/baseline/testAnim1.png b/src/test/baseline/testAnim1.png
new file mode 100644
index 0000000..6651fc3
--- /dev/null
+++ b/src/test/baseline/testAnim1.png
Binary files differ
diff --git a/src/test/baseline/testAnim2.png b/src/test/baseline/testAnim2.png
new file mode 100644
index 0000000..d8553de
--- /dev/null
+++ b/src/test/baseline/testAnim2.png
Binary files differ
diff --git a/src/test/baseline/testAnim3.png b/src/test/baseline/testAnim3.png
new file mode 100644
index 0000000..4d6dbd7
--- /dev/null
+++ b/src/test/baseline/testAnim3.png
Binary files differ
diff --git a/src/test/baseline/testArc1.png b/src/test/baseline/testArc1.png
new file mode 100644
index 0000000..9c4a2f0
--- /dev/null
+++ b/src/test/baseline/testArc1.png
Binary files differ
diff --git a/src/test/baseline/testArc2.png b/src/test/baseline/testArc2.png
new file mode 100644
index 0000000..1e321a3
--- /dev/null
+++ b/src/test/baseline/testArc2.png
Binary files differ
diff --git a/src/test/baseline/testBitmap1.png b/src/test/baseline/testBitmap1.png
new file mode 100644
index 0000000..c5b06a0
--- /dev/null
+++ b/src/test/baseline/testBitmap1.png
Binary files differ
diff --git a/src/test/baseline/testBitmap2.png b/src/test/baseline/testBitmap2.png
new file mode 100644
index 0000000..f94b54e
--- /dev/null
+++ b/src/test/baseline/testBitmap2.png
Binary files differ
diff --git a/src/test/baseline/testBitmap3.png b/src/test/baseline/testBitmap3.png
new file mode 100644
index 0000000..7d0898d
--- /dev/null
+++ b/src/test/baseline/testBitmap3.png
Binary files differ
diff --git a/src/test/baseline/testBitmap4.png b/src/test/baseline/testBitmap4.png
new file mode 100644
index 0000000..5569133
--- /dev/null
+++ b/src/test/baseline/testBitmap4.png
Binary files differ
diff --git a/src/test/baseline/testBlend1.png b/src/test/baseline/testBlend1.png
new file mode 100644
index 0000000..29e4a11
--- /dev/null
+++ b/src/test/baseline/testBlend1.png
Binary files differ
diff --git a/src/test/baseline/testBlend2.png b/src/test/baseline/testBlend2.png
new file mode 100644
index 0000000..8b2ae59
--- /dev/null
+++ b/src/test/baseline/testBlend2.png
Binary files differ
diff --git a/src/test/baseline/testBlurFX1.png b/src/test/baseline/testBlurFX1.png
new file mode 100644
index 0000000..9564d6f
--- /dev/null
+++ b/src/test/baseline/testBlurFX1.png
Binary files differ
diff --git a/src/test/baseline/testBlurFX2.png b/src/test/baseline/testBlurFX2.png
new file mode 100644
index 0000000..0147846
--- /dev/null
+++ b/src/test/baseline/testBlurFX2.png
Binary files differ
diff --git a/src/test/baseline/testBlurFX3.png b/src/test/baseline/testBlurFX3.png
new file mode 100644
index 0000000..b50decf
--- /dev/null
+++ b/src/test/baseline/testBlurFX3.png
Binary files differ
diff --git a/src/test/baseline/testButtonDisabled.png b/src/test/baseline/testButtonDisabled.png
new file mode 100644
index 0000000..6b7eea4
--- /dev/null
+++ b/src/test/baseline/testButtonDisabled.png
Binary files differ
diff --git a/src/test/baseline/testButtonDown.png b/src/test/baseline/testButtonDown.png
new file mode 100644
index 0000000..96e6e40
--- /dev/null
+++ b/src/test/baseline/testButtonDown.png
Binary files differ
diff --git a/src/test/baseline/testButtonOver.png b/src/test/baseline/testButtonOver.png
new file mode 100644
index 0000000..f3d5a0e
--- /dev/null
+++ b/src/test/baseline/testButtonOver.png
Binary files differ
diff --git a/src/test/baseline/testButtonUp.png b/src/test/baseline/testButtonUp.png
new file mode 100644
index 0000000..a9adeb5
--- /dev/null
+++ b/src/test/baseline/testButtonUp.png
Binary files differ
diff --git a/src/test/baseline/testCanvasAlpha.png b/src/test/baseline/testCanvasAlpha.png
new file mode 100644
index 0000000..63fb052
--- /dev/null
+++ b/src/test/baseline/testCanvasAlpha.png
Binary files differ
diff --git a/src/test/baseline/testCanvasBlendModes.png b/src/test/baseline/testCanvasBlendModes.png
new file mode 100644
index 0000000..f0feba3
--- /dev/null
+++ b/src/test/baseline/testCanvasBlendModes.png
Binary files differ
diff --git a/src/test/baseline/testCanvasCrop.png b/src/test/baseline/testCanvasCrop.png
new file mode 100644
index 0000000..ffcdcfa
--- /dev/null
+++ b/src/test/baseline/testCanvasCrop.png
Binary files differ
diff --git a/src/test/baseline/testCanvasDependencies1.png b/src/test/baseline/testCanvasDependencies1.png
new file mode 100644
index 0000000..5821855
--- /dev/null
+++ b/src/test/baseline/testCanvasDependencies1.png
Binary files differ
diff --git a/src/test/baseline/testCanvasDependencies2.png b/src/test/baseline/testCanvasDependencies2.png
new file mode 100644
index 0000000..d38ac6a
--- /dev/null
+++ b/src/test/baseline/testCanvasDependencies2.png
Binary files differ
diff --git a/src/test/baseline/testCanvasMipmap.png b/src/test/baseline/testCanvasMipmap.png
new file mode 100644
index 0000000..ecc51f0
--- /dev/null
+++ b/src/test/baseline/testCanvasMipmap.png
Binary files differ
diff --git a/src/test/baseline/testCanvasMultisample.png b/src/test/baseline/testCanvasMultisample.png
new file mode 100644
index 0000000..1f30aad
--- /dev/null
+++ b/src/test/baseline/testCanvasMultisample.png
Binary files differ
diff --git a/src/test/baseline/testCanvasNullFX1.png b/src/test/baseline/testCanvasNullFX1.png
new file mode 100644
index 0000000..c877bdf
--- /dev/null
+++ b/src/test/baseline/testCanvasNullFX1.png
Binary files differ
diff --git a/src/test/baseline/testCanvasNullFX2.png b/src/test/baseline/testCanvasNullFX2.png
new file mode 100644
index 0000000..8e485f7
--- /dev/null
+++ b/src/test/baseline/testCanvasNullFX2.png
Binary files differ
diff --git a/src/test/baseline/testCanvasNullFX3.png b/src/test/baseline/testCanvasNullFX3.png
new file mode 100644
index 0000000..56571a2
--- /dev/null
+++ b/src/test/baseline/testCanvasNullFX3.png
Binary files differ
diff --git a/src/test/baseline/testCanvasResize.png b/src/test/baseline/testCanvasResize.png
new file mode 100644
index 0000000..5821855
--- /dev/null
+++ b/src/test/baseline/testCanvasResize.png
Binary files differ
diff --git a/src/test/baseline/testCheckboxClickedDown.png b/src/test/baseline/testCheckboxClickedDown.png
new file mode 100644
index 0000000..2065be3
--- /dev/null
+++ b/src/test/baseline/testCheckboxClickedDown.png
Binary files differ
diff --git a/src/test/baseline/testCheckboxClickedOut.png b/src/test/baseline/testCheckboxClickedOut.png
new file mode 100644
index 0000000..a17d5b2
--- /dev/null
+++ b/src/test/baseline/testCheckboxClickedOut.png
Binary files differ
diff --git a/src/test/baseline/testCheckboxClickedOver.png b/src/test/baseline/testCheckboxClickedOver.png
new file mode 100644
index 0000000..b94c9d9
--- /dev/null
+++ b/src/test/baseline/testCheckboxClickedOver.png
Binary files differ
diff --git a/src/test/baseline/testCheckboxDown.png b/src/test/baseline/testCheckboxDown.png
new file mode 100644
index 0000000..96e6e40
--- /dev/null
+++ b/src/test/baseline/testCheckboxDown.png
Binary files differ
diff --git a/src/test/baseline/testCheckboxOver.png b/src/test/baseline/testCheckboxOver.png
new file mode 100644
index 0000000..f3d5a0e
--- /dev/null
+++ b/src/test/baseline/testCheckboxOver.png
Binary files differ
diff --git a/src/test/baseline/testCheckboxUp.png b/src/test/baseline/testCheckboxUp.png
new file mode 100644
index 0000000..a9adeb5
--- /dev/null
+++ b/src/test/baseline/testCheckboxUp.png
Binary files differ
diff --git a/src/test/baseline/testChromaKeyFX1.png b/src/test/baseline/testChromaKeyFX1.png
new file mode 100644
index 0000000..9f63ce5
--- /dev/null
+++ b/src/test/baseline/testChromaKeyFX1.png
Binary files differ
diff --git a/src/test/baseline/testChromaKeyFX2.png b/src/test/baseline/testChromaKeyFX2.png
new file mode 100644
index 0000000..65df5ea
--- /dev/null
+++ b/src/test/baseline/testChromaKeyFX2.png
Binary files differ
diff --git a/src/test/baseline/testChromaKeyFX3.png b/src/test/baseline/testChromaKeyFX3.png
new file mode 100644
index 0000000..1ab1b59
--- /dev/null
+++ b/src/test/baseline/testChromaKeyFX3.png
Binary files differ
diff --git a/src/test/baseline/testChromaKeyFX4.png b/src/test/baseline/testChromaKeyFX4.png
new file mode 100644
index 0000000..86efc70
--- /dev/null
+++ b/src/test/baseline/testChromaKeyFX4.png
Binary files differ
diff --git a/src/test/baseline/testCircle1.png b/src/test/baseline/testCircle1.png
new file mode 100644
index 0000000..45f2c58
--- /dev/null
+++ b/src/test/baseline/testCircle1.png
Binary files differ
diff --git a/src/test/baseline/testCircle2.png b/src/test/baseline/testCircle2.png
new file mode 100644
index 0000000..26ca01c
--- /dev/null
+++ b/src/test/baseline/testCircle2.png
Binary files differ
diff --git a/src/test/baseline/testCircle3.png b/src/test/baseline/testCircle3.png
new file mode 100644
index 0000000..4824bcf
--- /dev/null
+++ b/src/test/baseline/testCircle3.png
Binary files differ
diff --git a/src/test/baseline/testCircle4.png b/src/test/baseline/testCircle4.png
new file mode 100644
index 0000000..be36e58
--- /dev/null
+++ b/src/test/baseline/testCircle4.png
Binary files differ
diff --git a/src/test/baseline/testCircle5.png b/src/test/baseline/testCircle5.png
new file mode 100644
index 0000000..f70b3eb
--- /dev/null
+++ b/src/test/baseline/testCircle5.png
Binary files differ
diff --git a/src/test/baseline/testColorFX1.png b/src/test/baseline/testColorFX1.png
new file mode 100644
index 0000000..1a225e9
--- /dev/null
+++ b/src/test/baseline/testColorFX1.png
Binary files differ
diff --git a/src/test/baseline/testColorFX2.png b/src/test/baseline/testColorFX2.png
new file mode 100644
index 0000000..dc708c6
--- /dev/null
+++ b/src/test/baseline/testColorFX2.png
Binary files differ
diff --git a/src/test/baseline/testColorFX3.png b/src/test/baseline/testColorFX3.png
new file mode 100644
index 0000000..b82c72d
--- /dev/null
+++ b/src/test/baseline/testColorFX3.png
Binary files differ
diff --git a/src/test/baseline/testColorFX4.png b/src/test/baseline/testColorFX4.png
new file mode 100644
index 0000000..5722a24
--- /dev/null
+++ b/src/test/baseline/testColorFX4.png
Binary files differ
diff --git a/src/test/baseline/testColorFX5.png b/src/test/baseline/testColorFX5.png
new file mode 100644
index 0000000..dbcec1c
--- /dev/null
+++ b/src/test/baseline/testColorFX5.png
Binary files differ
diff --git a/src/test/baseline/testColorFX6.png b/src/test/baseline/testColorFX6.png
new file mode 100644
index 0000000..ab46da3
--- /dev/null
+++ b/src/test/baseline/testColorFX6.png
Binary files differ
diff --git a/src/test/baseline/testColorFX7.png b/src/test/baseline/testColorFX7.png
new file mode 100644
index 0000000..5fb43b8
--- /dev/null
+++ b/src/test/baseline/testColorFX7.png
Binary files differ
diff --git a/src/test/baseline/testComplexDiv1.png b/src/test/baseline/testComplexDiv1.png
new file mode 100644
index 0000000..bde774d
--- /dev/null
+++ b/src/test/baseline/testComplexDiv1.png
Binary files differ
diff --git a/src/test/baseline/testContAnim1.png b/src/test/baseline/testContAnim1.png
new file mode 100644
index 0000000..f337d2f
--- /dev/null
+++ b/src/test/baseline/testContAnim1.png
Binary files differ
diff --git a/src/test/baseline/testContAnim2.png b/src/test/baseline/testContAnim2.png
new file mode 100644
index 0000000..1e2b4fd
--- /dev/null
+++ b/src/test/baseline/testContAnim2.png
Binary files differ
diff --git a/src/test/baseline/testContAnim3.png b/src/test/baseline/testContAnim3.png
new file mode 100644
index 0000000..cdf6b45
--- /dev/null
+++ b/src/test/baseline/testContAnim3.png
Binary files differ
diff --git a/src/test/baseline/testContAnim4.png b/src/test/baseline/testContAnim4.png
new file mode 100644
index 0000000..3a16eeb
--- /dev/null
+++ b/src/test/baseline/testContAnim4.png
Binary files differ
diff --git a/src/test/baseline/testContinuousAnim1.png b/src/test/baseline/testContinuousAnim1.png
new file mode 100644
index 0000000..4f8a5be
--- /dev/null
+++ b/src/test/baseline/testContinuousAnim1.png
Binary files differ
diff --git a/src/test/baseline/testContinuousAnim2.png b/src/test/baseline/testContinuousAnim2.png
new file mode 100644
index 0000000..34a9e24
--- /dev/null
+++ b/src/test/baseline/testContinuousAnim2.png
Binary files differ
diff --git a/src/test/baseline/testContrast1.png b/src/test/baseline/testContrast1.png
new file mode 100644
index 0000000..06bf3d0
--- /dev/null
+++ b/src/test/baseline/testContrast1.png
Binary files differ
diff --git a/src/test/baseline/testContrast2.png b/src/test/baseline/testContrast2.png
new file mode 100644
index 0000000..fc1e0e6
--- /dev/null
+++ b/src/test/baseline/testContrast2.png
Binary files differ
diff --git a/src/test/baseline/testContrast3.png b/src/test/baseline/testContrast3.png
new file mode 100644
index 0000000..e979473
--- /dev/null
+++ b/src/test/baseline/testContrast3.png
Binary files differ
diff --git a/src/test/baseline/testCropImage1.png b/src/test/baseline/testCropImage1.png
new file mode 100644
index 0000000..40bdcfe
--- /dev/null
+++ b/src/test/baseline/testCropImage1.png
Binary files differ
diff --git a/src/test/baseline/testCropImage10.png b/src/test/baseline/testCropImage10.png
new file mode 100644
index 0000000..f05723a
--- /dev/null
+++ b/src/test/baseline/testCropImage10.png
Binary files differ
diff --git a/src/test/baseline/testCropImage2.png b/src/test/baseline/testCropImage2.png
new file mode 100644
index 0000000..e0706ea
--- /dev/null
+++ b/src/test/baseline/testCropImage2.png
Binary files differ
diff --git a/src/test/baseline/testCropImage3.png b/src/test/baseline/testCropImage3.png
new file mode 100644
index 0000000..33078f2
--- /dev/null
+++ b/src/test/baseline/testCropImage3.png
Binary files differ
diff --git a/src/test/baseline/testCropImage4.png b/src/test/baseline/testCropImage4.png
new file mode 100644
index 0000000..e230b9a
--- /dev/null
+++ b/src/test/baseline/testCropImage4.png
Binary files differ
diff --git a/src/test/baseline/testCropImage5.png b/src/test/baseline/testCropImage5.png
new file mode 100644
index 0000000..0636df4
--- /dev/null
+++ b/src/test/baseline/testCropImage5.png
Binary files differ
diff --git a/src/test/baseline/testCropImage6.png b/src/test/baseline/testCropImage6.png
new file mode 100644
index 0000000..566f599
--- /dev/null
+++ b/src/test/baseline/testCropImage6.png
Binary files differ
diff --git a/src/test/baseline/testCropImage7.png b/src/test/baseline/testCropImage7.png
new file mode 100644
index 0000000..632a158
--- /dev/null
+++ b/src/test/baseline/testCropImage7.png
Binary files differ
diff --git a/src/test/baseline/testCropImage8.png b/src/test/baseline/testCropImage8.png
new file mode 100644
index 0000000..017faca
--- /dev/null
+++ b/src/test/baseline/testCropImage8.png
Binary files differ
diff --git a/src/test/baseline/testCropImage9.png b/src/test/baseline/testCropImage9.png
new file mode 100644
index 0000000..2f013fc
--- /dev/null
+++ b/src/test/baseline/testCropImage9.png
Binary files differ
diff --git a/src/test/baseline/testCropMovie1.png b/src/test/baseline/testCropMovie1.png
new file mode 100644
index 0000000..aaff2c3
--- /dev/null
+++ b/src/test/baseline/testCropMovie1.png
Binary files differ
diff --git a/src/test/baseline/testCropMovie10.png b/src/test/baseline/testCropMovie10.png
new file mode 100644
index 0000000..1ef3ca3
--- /dev/null
+++ b/src/test/baseline/testCropMovie10.png
Binary files differ
diff --git a/src/test/baseline/testCropMovie2.png b/src/test/baseline/testCropMovie2.png
new file mode 100644
index 0000000..1345610
--- /dev/null
+++ b/src/test/baseline/testCropMovie2.png
Binary files differ
diff --git a/src/test/baseline/testCropMovie3.png b/src/test/baseline/testCropMovie3.png
new file mode 100644
index 0000000..a2aef90
--- /dev/null
+++ b/src/test/baseline/testCropMovie3.png
Binary files differ
diff --git a/src/test/baseline/testCropMovie4.png b/src/test/baseline/testCropMovie4.png
new file mode 100644
index 0000000..72a5ae2
--- /dev/null
+++ b/src/test/baseline/testCropMovie4.png
Binary files differ
diff --git a/src/test/baseline/testCropMovie5.png b/src/test/baseline/testCropMovie5.png
new file mode 100644
index 0000000..8e663fc
--- /dev/null
+++ b/src/test/baseline/testCropMovie5.png
Binary files differ
diff --git a/src/test/baseline/testCropMovie6.png b/src/test/baseline/testCropMovie6.png
new file mode 100644
index 0000000..ff47430
--- /dev/null
+++ b/src/test/baseline/testCropMovie6.png
Binary files differ
diff --git a/src/test/baseline/testCropMovie7.png b/src/test/baseline/testCropMovie7.png
new file mode 100644
index 0000000..60941e4
--- /dev/null
+++ b/src/test/baseline/testCropMovie7.png
Binary files differ
diff --git a/src/test/baseline/testCropMovie8.png b/src/test/baseline/testCropMovie8.png
new file mode 100644
index 0000000..e12b702
--- /dev/null
+++ b/src/test/baseline/testCropMovie8.png
Binary files differ
diff --git a/src/test/baseline/testCropMovie9.png b/src/test/baseline/testCropMovie9.png
new file mode 100644
index 0000000..f0ede3e
--- /dev/null
+++ b/src/test/baseline/testCropMovie9.png
Binary files differ
diff --git a/src/test/baseline/testCurve1.png b/src/test/baseline/testCurve1.png
new file mode 100644
index 0000000..70127bc
--- /dev/null
+++ b/src/test/baseline/testCurve1.png
Binary files differ
diff --git a/src/test/baseline/testCurve2.png b/src/test/baseline/testCurve2.png
new file mode 100644
index 0000000..6046c98
--- /dev/null
+++ b/src/test/baseline/testCurve2.png
Binary files differ
diff --git a/src/test/baseline/testCurve3.png b/src/test/baseline/testCurve3.png
new file mode 100644
index 0000000..9545904
--- /dev/null
+++ b/src/test/baseline/testCurve3.png
Binary files differ
diff --git a/src/test/baseline/testCurve4.png b/src/test/baseline/testCurve4.png
new file mode 100644
index 0000000..1472c2f
--- /dev/null
+++ b/src/test/baseline/testCurve4.png
Binary files differ
diff --git a/src/test/baseline/testDivDynamics1.png b/src/test/baseline/testDivDynamics1.png
new file mode 100644
index 0000000..d05741d
--- /dev/null
+++ b/src/test/baseline/testDivDynamics1.png
Binary files differ
diff --git a/src/test/baseline/testDivDynamics2.png b/src/test/baseline/testDivDynamics2.png
new file mode 100644
index 0000000..b3f308f
--- /dev/null
+++ b/src/test/baseline/testDivDynamics2.png
Binary files differ
diff --git a/src/test/baseline/testDivDynamics3.png b/src/test/baseline/testDivDynamics3.png
new file mode 100644
index 0000000..72a9acf
--- /dev/null
+++ b/src/test/baseline/testDivDynamics3.png
Binary files differ
diff --git a/src/test/baseline/testDivDynamics4.png b/src/test/baseline/testDivDynamics4.png
new file mode 100644
index 0000000..174636b
--- /dev/null
+++ b/src/test/baseline/testDivDynamics4.png
Binary files differ
diff --git a/src/test/baseline/testDivDynamics5.png b/src/test/baseline/testDivDynamics5.png
new file mode 100644
index 0000000..d05741d
--- /dev/null
+++ b/src/test/baseline/testDivDynamics5.png
Binary files differ
diff --git a/src/test/baseline/testDraggable1.png b/src/test/baseline/testDraggable1.png
new file mode 100644
index 0000000..d60276f
--- /dev/null
+++ b/src/test/baseline/testDraggable1.png
Binary files differ
diff --git a/src/test/baseline/testDraggable2.png b/src/test/baseline/testDraggable2.png
new file mode 100644
index 0000000..19ad729
--- /dev/null
+++ b/src/test/baseline/testDraggable2.png
Binary files differ
diff --git a/src/test/baseline/testDynamicMediaDir1.png b/src/test/baseline/testDynamicMediaDir1.png
new file mode 100644
index 0000000..71c0100
--- /dev/null
+++ b/src/test/baseline/testDynamicMediaDir1.png
Binary files differ
diff --git a/src/test/baseline/testDynamicMediaDir2.png b/src/test/baseline/testDynamicMediaDir2.png
new file mode 100644
index 0000000..392e2a8
--- /dev/null
+++ b/src/test/baseline/testDynamicMediaDir2.png
Binary files differ
diff --git a/src/test/baseline/testDynamicWords1.png b/src/test/baseline/testDynamicWords1.png
new file mode 100644
index 0000000..9b37b72
--- /dev/null
+++ b/src/test/baseline/testDynamicWords1.png
Binary files differ
diff --git a/src/test/baseline/testDynamicWords2.png b/src/test/baseline/testDynamicWords2.png
new file mode 100644
index 0000000..390d0f3
--- /dev/null
+++ b/src/test/baseline/testDynamicWords2.png
Binary files differ
diff --git a/src/test/baseline/testDynamicWords3.png b/src/test/baseline/testDynamicWords3.png
new file mode 100644
index 0000000..174636b
--- /dev/null
+++ b/src/test/baseline/testDynamicWords3.png
Binary files differ
diff --git a/src/test/baseline/testDynamicWords4.png b/src/test/baseline/testDynamicWords4.png
new file mode 100644
index 0000000..789c2c8
--- /dev/null
+++ b/src/test/baseline/testDynamicWords4.png
Binary files differ
diff --git a/src/test/baseline/testEaseInOutAnim1.png b/src/test/baseline/testEaseInOutAnim1.png
new file mode 100644
index 0000000..82abf89
--- /dev/null
+++ b/src/test/baseline/testEaseInOutAnim1.png
Binary files differ
diff --git a/src/test/baseline/testEaseInOutAnim2.png b/src/test/baseline/testEaseInOutAnim2.png
new file mode 100644
index 0000000..e299221
--- /dev/null
+++ b/src/test/baseline/testEaseInOutAnim2.png
Binary files differ
diff --git a/src/test/baseline/testEaseInOutAnim3.png b/src/test/baseline/testEaseInOutAnim3.png
new file mode 100644
index 0000000..03311b5
--- /dev/null
+++ b/src/test/baseline/testEaseInOutAnim3.png
Binary files differ
diff --git a/src/test/baseline/testEaseInOutAnimC1.png b/src/test/baseline/testEaseInOutAnimC1.png
new file mode 100644
index 0000000..fbe5b29
--- /dev/null
+++ b/src/test/baseline/testEaseInOutAnimC1.png
Binary files differ
diff --git a/src/test/baseline/testEaseInOutAnimC2.png b/src/test/baseline/testEaseInOutAnimC2.png
new file mode 100644
index 0000000..1e889df
--- /dev/null
+++ b/src/test/baseline/testEaseInOutAnimC2.png
Binary files differ
diff --git a/src/test/baseline/testEaseInOutAnimC3.png b/src/test/baseline/testEaseInOutAnimC3.png
new file mode 100644
index 0000000..40d820a
--- /dev/null
+++ b/src/test/baseline/testEaseInOutAnimC3.png
Binary files differ
diff --git a/src/test/baseline/testEaseInOutAnimC4.png b/src/test/baseline/testEaseInOutAnimC4.png
new file mode 100644
index 0000000..9703e09
--- /dev/null
+++ b/src/test/baseline/testEaseInOutAnimC4.png
Binary files differ
diff --git a/src/test/baseline/testEaseInOutAnimC5.png b/src/test/baseline/testEaseInOutAnimC5.png
new file mode 100644
index 0000000..40d820a
--- /dev/null
+++ b/src/test/baseline/testEaseInOutAnimC5.png
Binary files differ
diff --git a/src/test/baseline/testEaseInOutAnimC6.png b/src/test/baseline/testEaseInOutAnimC6.png
new file mode 100644
index 0000000..60da2b1
--- /dev/null
+++ b/src/test/baseline/testEaseInOutAnimC6.png
Binary files differ
diff --git a/src/test/baseline/testEvents.png b/src/test/baseline/testEvents.png
new file mode 100644
index 0000000..bdd9280
--- /dev/null
+++ b/src/test/baseline/testEvents.png
Binary files differ
diff --git a/src/test/baseline/testFXUpdateFX.png b/src/test/baseline/testFXUpdateFX.png
new file mode 100644
index 0000000..a2d1a44
--- /dev/null
+++ b/src/test/baseline/testFXUpdateFX.png
Binary files differ
diff --git a/src/test/baseline/testFXUpdateMaskPos.png b/src/test/baseline/testFXUpdateMaskPos.png
new file mode 100644
index 0000000..150ebd2
--- /dev/null
+++ b/src/test/baseline/testFXUpdateMaskPos.png
Binary files differ
diff --git a/src/test/baseline/testFXUpdateMaskTex1.png b/src/test/baseline/testFXUpdateMaskTex1.png
new file mode 100644
index 0000000..18588ff
--- /dev/null
+++ b/src/test/baseline/testFXUpdateMaskTex1.png
Binary files differ
diff --git a/src/test/baseline/testFXUpdateMaskTex2.png b/src/test/baseline/testFXUpdateMaskTex2.png
new file mode 100644
index 0000000..4790154
--- /dev/null
+++ b/src/test/baseline/testFXUpdateMaskTex2.png
Binary files differ
diff --git a/src/test/baseline/testFXUpdateTex.png b/src/test/baseline/testFXUpdateTex.png
new file mode 100644
index 0000000..3111780
--- /dev/null
+++ b/src/test/baseline/testFXUpdateTex.png
Binary files differ
diff --git a/src/test/baseline/testFXUpdateVideo.png b/src/test/baseline/testFXUpdateVideo.png
new file mode 100644
index 0000000..fed9567
--- /dev/null
+++ b/src/test/baseline/testFXUpdateVideo.png
Binary files differ
diff --git a/src/test/baseline/testFadeIn1.png b/src/test/baseline/testFadeIn1.png
new file mode 100644
index 0000000..e4a332a
--- /dev/null
+++ b/src/test/baseline/testFadeIn1.png
Binary files differ
diff --git a/src/test/baseline/testFadeIn2.png b/src/test/baseline/testFadeIn2.png
new file mode 100644
index 0000000..b1c6746
--- /dev/null
+++ b/src/test/baseline/testFadeIn2.png
Binary files differ
diff --git a/src/test/baseline/testFadeIn3.png b/src/test/baseline/testFadeIn3.png
new file mode 100644
index 0000000..02f0389
--- /dev/null
+++ b/src/test/baseline/testFadeIn3.png
Binary files differ
diff --git a/src/test/baseline/testFadeOut1.png b/src/test/baseline/testFadeOut1.png
new file mode 100644
index 0000000..e4a332a
--- /dev/null
+++ b/src/test/baseline/testFadeOut1.png
Binary files differ
diff --git a/src/test/baseline/testFadeOut2.png b/src/test/baseline/testFadeOut2.png
new file mode 100644
index 0000000..f7bcf5b
--- /dev/null
+++ b/src/test/baseline/testFadeOut2.png
Binary files differ
diff --git a/src/test/baseline/testFadeOut3.png b/src/test/baseline/testFadeOut3.png
new file mode 100644
index 0000000..174636b
--- /dev/null
+++ b/src/test/baseline/testFadeOut3.png
Binary files differ
diff --git a/src/test/baseline/testFocusContext1.png b/src/test/baseline/testFocusContext1.png
new file mode 100644
index 0000000..380902e
--- /dev/null
+++ b/src/test/baseline/testFocusContext1.png
Binary files differ
diff --git a/src/test/baseline/testFocusContext2.png b/src/test/baseline/testFocusContext2.png
new file mode 100644
index 0000000..5ecbcf4
--- /dev/null
+++ b/src/test/baseline/testFocusContext2.png
Binary files differ
diff --git a/src/test/baseline/testFocusContext3.png b/src/test/baseline/testFocusContext3.png
new file mode 100644
index 0000000..0606d81
--- /dev/null
+++ b/src/test/baseline/testFocusContext3.png
Binary files differ
diff --git a/src/test/baseline/testFocusContext4.png b/src/test/baseline/testFocusContext4.png
new file mode 100644
index 0000000..9629e81
--- /dev/null
+++ b/src/test/baseline/testFocusContext4.png
Binary files differ
diff --git a/src/test/baseline/testFocusContext5.png b/src/test/baseline/testFocusContext5.png
new file mode 100644
index 0000000..2ae68e0
--- /dev/null
+++ b/src/test/baseline/testFocusContext5.png
Binary files differ
diff --git a/src/test/baseline/testFontDir.png b/src/test/baseline/testFontDir.png
new file mode 100644
index 0000000..5dc4858
--- /dev/null
+++ b/src/test/baseline/testFontDir.png
Binary files differ
diff --git a/src/test/baseline/testFontStyle1.png b/src/test/baseline/testFontStyle1.png
new file mode 100644
index 0000000..3d773d6
--- /dev/null
+++ b/src/test/baseline/testFontStyle1.png
Binary files differ
diff --git a/src/test/baseline/testFontStyle2.png b/src/test/baseline/testFontStyle2.png
new file mode 100644
index 0000000..e67cfa4
--- /dev/null
+++ b/src/test/baseline/testFontStyle2.png
Binary files differ
diff --git a/src/test/baseline/testGamma1.png b/src/test/baseline/testGamma1.png
new file mode 100644
index 0000000..a713a13
--- /dev/null
+++ b/src/test/baseline/testGamma1.png
Binary files differ
diff --git a/src/test/baseline/testGamma2.png b/src/test/baseline/testGamma2.png
new file mode 100644
index 0000000..18d0479
--- /dev/null
+++ b/src/test/baseline/testGamma2.png
Binary files differ
diff --git a/src/test/baseline/testHVStretchNode1.png b/src/test/baseline/testHVStretchNode1.png
new file mode 100644
index 0000000..304c23e
--- /dev/null
+++ b/src/test/baseline/testHVStretchNode1.png
Binary files differ
diff --git a/src/test/baseline/testHVStretchNode2.png b/src/test/baseline/testHVStretchNode2.png
new file mode 100644
index 0000000..ca1f0f2
--- /dev/null
+++ b/src/test/baseline/testHVStretchNode2.png
Binary files differ
diff --git a/src/test/baseline/testHinting1.png b/src/test/baseline/testHinting1.png
new file mode 100644
index 0000000..4657e71
--- /dev/null
+++ b/src/test/baseline/testHinting1.png
Binary files differ
diff --git a/src/test/baseline/testHueSatFX1.png b/src/test/baseline/testHueSatFX1.png
new file mode 100644
index 0000000..abe4582
--- /dev/null
+++ b/src/test/baseline/testHueSatFX1.png
Binary files differ
diff --git a/src/test/baseline/testHueSatFX2.png b/src/test/baseline/testHueSatFX2.png
new file mode 100644
index 0000000..736bfbd
--- /dev/null
+++ b/src/test/baseline/testHueSatFX2.png
Binary files differ
diff --git a/src/test/baseline/testHueSatFX3.png b/src/test/baseline/testHueSatFX3.png
new file mode 100644
index 0000000..96e7744
--- /dev/null
+++ b/src/test/baseline/testHueSatFX3.png
Binary files differ
diff --git a/src/test/baseline/testHueSatFX4.png b/src/test/baseline/testHueSatFX4.png
new file mode 100644
index 0000000..7aff060
--- /dev/null
+++ b/src/test/baseline/testHueSatFX4.png
Binary files differ
diff --git a/src/test/baseline/testHugeImage0.png b/src/test/baseline/testHugeImage0.png
new file mode 100644
index 0000000..eb59ae0
--- /dev/null
+++ b/src/test/baseline/testHugeImage0.png
Binary files differ
diff --git a/src/test/baseline/testHugeImage1.png b/src/test/baseline/testHugeImage1.png
new file mode 100644
index 0000000..241b52f
--- /dev/null
+++ b/src/test/baseline/testHugeImage1.png
Binary files differ
diff --git a/src/test/baseline/testI18NWords1.png b/src/test/baseline/testI18NWords1.png
new file mode 100644
index 0000000..b9b8808
--- /dev/null
+++ b/src/test/baseline/testI18NWords1.png
Binary files differ
diff --git a/src/test/baseline/testI18NWords2.png b/src/test/baseline/testI18NWords2.png
new file mode 100644
index 0000000..e3f649b
--- /dev/null
+++ b/src/test/baseline/testI18NWords2.png
Binary files differ
diff --git a/src/test/baseline/testI18NWords3.png b/src/test/baseline/testI18NWords3.png
new file mode 100644
index 0000000..ace8433
--- /dev/null
+++ b/src/test/baseline/testI18NWords3.png
Binary files differ
diff --git a/src/test/baseline/testImageNullFX1.png b/src/test/baseline/testImageNullFX1.png
new file mode 100644
index 0000000..cdbf3fb
--- /dev/null
+++ b/src/test/baseline/testImageNullFX1.png
Binary files differ
diff --git a/src/test/baseline/testImageNullFX2.png b/src/test/baseline/testImageNullFX2.png
new file mode 100644
index 0000000..a5dd14b
--- /dev/null
+++ b/src/test/baseline/testImageNullFX2.png
Binary files differ
diff --git a/src/test/baseline/testImageNullFX3.png b/src/test/baseline/testImageNullFX3.png
new file mode 100644
index 0000000..f9b00d9
--- /dev/null
+++ b/src/test/baseline/testImageNullFX3.png
Binary files differ
diff --git a/src/test/baseline/testImgDynamics1.png b/src/test/baseline/testImgDynamics1.png
new file mode 100644
index 0000000..d05741d
--- /dev/null
+++ b/src/test/baseline/testImgDynamics1.png
Binary files differ
diff --git a/src/test/baseline/testImgDynamics2.png b/src/test/baseline/testImgDynamics2.png
new file mode 100644
index 0000000..b3f308f
--- /dev/null
+++ b/src/test/baseline/testImgDynamics2.png
Binary files differ
diff --git a/src/test/baseline/testImgDynamics3.png b/src/test/baseline/testImgDynamics3.png
new file mode 100644
index 0000000..72a9acf
--- /dev/null
+++ b/src/test/baseline/testImgDynamics3.png
Binary files differ
diff --git a/src/test/baseline/testImgDynamics4.png b/src/test/baseline/testImgDynamics4.png
new file mode 100644
index 0000000..21c01f2
--- /dev/null
+++ b/src/test/baseline/testImgDynamics4.png
Binary files differ
diff --git a/src/test/baseline/testImgDynamics5.png b/src/test/baseline/testImgDynamics5.png
new file mode 100644
index 0000000..d05741d
--- /dev/null
+++ b/src/test/baseline/testImgDynamics5.png
Binary files differ
diff --git a/src/test/baseline/testImgHRef1.png b/src/test/baseline/testImgHRef1.png
new file mode 100644
index 0000000..a1df968
--- /dev/null
+++ b/src/test/baseline/testImgHRef1.png
Binary files differ
diff --git a/src/test/baseline/testImgHRef2.png b/src/test/baseline/testImgHRef2.png
new file mode 100644
index 0000000..03c8e41
--- /dev/null
+++ b/src/test/baseline/testImgHRef2.png
Binary files differ
diff --git a/src/test/baseline/testImgHRef3.png b/src/test/baseline/testImgHRef3.png
new file mode 100644
index 0000000..b18ec93
--- /dev/null
+++ b/src/test/baseline/testImgHRef3.png
Binary files differ
diff --git a/src/test/baseline/testImgMask1.png b/src/test/baseline/testImgMask1.png
new file mode 100644
index 0000000..2fe736a
--- /dev/null
+++ b/src/test/baseline/testImgMask1.png
Binary files differ
diff --git a/src/test/baseline/testImgMask2.png b/src/test/baseline/testImgMask2.png
new file mode 100644
index 0000000..9d1f486
--- /dev/null
+++ b/src/test/baseline/testImgMask2.png
Binary files differ
diff --git a/src/test/baseline/testImgMask3.png b/src/test/baseline/testImgMask3.png
new file mode 100644
index 0000000..70f58ff
--- /dev/null
+++ b/src/test/baseline/testImgMask3.png
Binary files differ
diff --git a/src/test/baseline/testImgMaskCanvas.png b/src/test/baseline/testImgMaskCanvas.png
new file mode 100644
index 0000000..1faa5d5
--- /dev/null
+++ b/src/test/baseline/testImgMaskCanvas.png
Binary files differ
diff --git a/src/test/baseline/testImgMaskPos.png b/src/test/baseline/testImgMaskPos.png
new file mode 100644
index 0000000..16176eb
--- /dev/null
+++ b/src/test/baseline/testImgMaskPos.png
Binary files differ
diff --git a/src/test/baseline/testImgMaskSize1.png b/src/test/baseline/testImgMaskSize1.png
new file mode 100644
index 0000000..41ac537
--- /dev/null
+++ b/src/test/baseline/testImgMaskSize1.png
Binary files differ
diff --git a/src/test/baseline/testImgMaskSize2.png b/src/test/baseline/testImgMaskSize2.png
new file mode 100644
index 0000000..de6549d
--- /dev/null
+++ b/src/test/baseline/testImgMaskSize2.png
Binary files differ
diff --git a/src/test/baseline/testImgMaskSize3.png b/src/test/baseline/testImgMaskSize3.png
new file mode 100644
index 0000000..d452f98
--- /dev/null
+++ b/src/test/baseline/testImgMaskSize3.png
Binary files differ
diff --git a/src/test/baseline/testImgPos1.png b/src/test/baseline/testImgPos1.png
new file mode 100644
index 0000000..5bb376d
--- /dev/null
+++ b/src/test/baseline/testImgPos1.png
Binary files differ
diff --git a/src/test/baseline/testImgPos2.png b/src/test/baseline/testImgPos2.png
new file mode 100644
index 0000000..017609d
--- /dev/null
+++ b/src/test/baseline/testImgPos2.png
Binary files differ
diff --git a/src/test/baseline/testImgSize1.png b/src/test/baseline/testImgSize1.png
new file mode 100644
index 0000000..5a5a7d6
--- /dev/null
+++ b/src/test/baseline/testImgSize1.png
Binary files differ
diff --git a/src/test/baseline/testImgSize2.png b/src/test/baseline/testImgSize2.png
new file mode 100644
index 0000000..df562d3
--- /dev/null
+++ b/src/test/baseline/testImgSize2.png
Binary files differ
diff --git a/src/test/baseline/testImgWarp1.png b/src/test/baseline/testImgWarp1.png
new file mode 100644
index 0000000..a5ee5c0
--- /dev/null
+++ b/src/test/baseline/testImgWarp1.png
Binary files differ
diff --git a/src/test/baseline/testImgWarp2.png b/src/test/baseline/testImgWarp2.png
new file mode 100644
index 0000000..514e6f4
--- /dev/null
+++ b/src/test/baseline/testImgWarp2.png
Binary files differ
diff --git a/src/test/baseline/testInactiveVector1.png b/src/test/baseline/testInactiveVector1.png
new file mode 100644
index 0000000..be0f350
--- /dev/null
+++ b/src/test/baseline/testInactiveVector1.png
Binary files differ
diff --git a/src/test/baseline/testInactiveVector2.png b/src/test/baseline/testInactiveVector2.png
new file mode 100644
index 0000000..174636b
--- /dev/null
+++ b/src/test/baseline/testInactiveVector2.png
Binary files differ
diff --git a/src/test/baseline/testIntAnim1.png b/src/test/baseline/testIntAnim1.png
new file mode 100644
index 0000000..904a872
--- /dev/null
+++ b/src/test/baseline/testIntAnim1.png
Binary files differ
diff --git a/src/test/baseline/testIntAnim2.png b/src/test/baseline/testIntAnim2.png
new file mode 100644
index 0000000..c2df44a
--- /dev/null
+++ b/src/test/baseline/testIntAnim2.png
Binary files differ
diff --git a/src/test/baseline/testIntensity1.png b/src/test/baseline/testIntensity1.png
new file mode 100644
index 0000000..cf19285
--- /dev/null
+++ b/src/test/baseline/testIntensity1.png
Binary files differ
diff --git a/src/test/baseline/testIntensity2.png b/src/test/baseline/testIntensity2.png
new file mode 100644
index 0000000..c8bb26a
--- /dev/null
+++ b/src/test/baseline/testIntensity2.png
Binary files differ
diff --git a/src/test/baseline/testIntensity3.png b/src/test/baseline/testIntensity3.png
new file mode 100644
index 0000000..450327c
--- /dev/null
+++ b/src/test/baseline/testIntensity3.png
Binary files differ
diff --git a/src/test/baseline/testIntensity4.png b/src/test/baseline/testIntensity4.png
new file mode 100644
index 0000000..649cd82
--- /dev/null
+++ b/src/test/baseline/testIntensity4.png
Binary files differ
diff --git a/src/test/baseline/testInvertFX1.png b/src/test/baseline/testInvertFX1.png
new file mode 100644
index 0000000..cbce0de
--- /dev/null
+++ b/src/test/baseline/testInvertFX1.png
Binary files differ
diff --git a/src/test/baseline/testInvertFX2.png b/src/test/baseline/testInvertFX2.png
new file mode 100644
index 0000000..2c5a673
--- /dev/null
+++ b/src/test/baseline/testInvertFX2.png
Binary files differ
diff --git a/src/test/baseline/testJustify.png b/src/test/baseline/testJustify.png
new file mode 100644
index 0000000..4d5affc
--- /dev/null
+++ b/src/test/baseline/testJustify.png
Binary files differ
diff --git a/src/test/baseline/testLetterSpacing1.png b/src/test/baseline/testLetterSpacing1.png
new file mode 100644
index 0000000..3b04e0e
--- /dev/null
+++ b/src/test/baseline/testLetterSpacing1.png
Binary files differ
diff --git a/src/test/baseline/testLetterSpacing2.png b/src/test/baseline/testLetterSpacing2.png
new file mode 100644
index 0000000..8385a22
--- /dev/null
+++ b/src/test/baseline/testLetterSpacing2.png
Binary files differ
diff --git a/src/test/baseline/testLinearAnim1.png b/src/test/baseline/testLinearAnim1.png
new file mode 100644
index 0000000..82abf89
--- /dev/null
+++ b/src/test/baseline/testLinearAnim1.png
Binary files differ
diff --git a/src/test/baseline/testLinearAnim2.png b/src/test/baseline/testLinearAnim2.png
new file mode 100644
index 0000000..e299221
--- /dev/null
+++ b/src/test/baseline/testLinearAnim2.png
Binary files differ
diff --git a/src/test/baseline/testLinearAnim3.png b/src/test/baseline/testLinearAnim3.png
new file mode 100644
index 0000000..e299221
--- /dev/null
+++ b/src/test/baseline/testLinearAnim3.png
Binary files differ
diff --git a/src/test/baseline/testLinearAnimC1.png b/src/test/baseline/testLinearAnimC1.png
new file mode 100644
index 0000000..fbe5b29
--- /dev/null
+++ b/src/test/baseline/testLinearAnimC1.png
Binary files differ
diff --git a/src/test/baseline/testLinearAnimC2.png b/src/test/baseline/testLinearAnimC2.png
new file mode 100644
index 0000000..b6403be
--- /dev/null
+++ b/src/test/baseline/testLinearAnimC2.png
Binary files differ
diff --git a/src/test/baseline/testLinearAnimC3.png b/src/test/baseline/testLinearAnimC3.png
new file mode 100644
index 0000000..b5e695e
--- /dev/null
+++ b/src/test/baseline/testLinearAnimC3.png
Binary files differ
diff --git a/src/test/baseline/testLinearAnimC4.png b/src/test/baseline/testLinearAnimC4.png
new file mode 100644
index 0000000..9703e09
--- /dev/null
+++ b/src/test/baseline/testLinearAnimC4.png
Binary files differ
diff --git a/src/test/baseline/testLinearAnimC5.png b/src/test/baseline/testLinearAnimC5.png
new file mode 100644
index 0000000..b5e695e
--- /dev/null
+++ b/src/test/baseline/testLinearAnimC5.png
Binary files differ
diff --git a/src/test/baseline/testLinearAnimC6.png b/src/test/baseline/testLinearAnimC6.png
new file mode 100644
index 0000000..f1fbb13
--- /dev/null
+++ b/src/test/baseline/testLinearAnimC6.png
Binary files differ
diff --git a/src/test/baseline/testLinearAnimZeroDuration1.png b/src/test/baseline/testLinearAnimZeroDuration1.png
new file mode 100644
index 0000000..e299221
--- /dev/null
+++ b/src/test/baseline/testLinearAnimZeroDuration1.png
Binary files differ
diff --git a/src/test/baseline/testLinearAnimZeroDuration2.png b/src/test/baseline/testLinearAnimZeroDuration2.png
new file mode 100644
index 0000000..ef346f8
--- /dev/null
+++ b/src/test/baseline/testLinearAnimZeroDuration2.png
Binary files differ
diff --git a/src/test/baseline/testLinearAnimZeroDuration3.png b/src/test/baseline/testLinearAnimZeroDuration3.png
new file mode 100644
index 0000000..ef346f8
--- /dev/null
+++ b/src/test/baseline/testLinearAnimZeroDuration3.png
Binary files differ
diff --git a/src/test/baseline/testLinearAnimZeroDurationC1.png b/src/test/baseline/testLinearAnimZeroDurationC1.png
new file mode 100644
index 0000000..9703e09
--- /dev/null
+++ b/src/test/baseline/testLinearAnimZeroDurationC1.png
Binary files differ
diff --git a/src/test/baseline/testLinearAnimZeroDurationC2.png b/src/test/baseline/testLinearAnimZeroDurationC2.png
new file mode 100644
index 0000000..ef346f8
--- /dev/null
+++ b/src/test/baseline/testLinearAnimZeroDurationC2.png
Binary files differ
diff --git a/src/test/baseline/testLinearAnimZeroDurationC3.png b/src/test/baseline/testLinearAnimZeroDurationC3.png
new file mode 100644
index 0000000..ef346f8
--- /dev/null
+++ b/src/test/baseline/testLinearAnimZeroDurationC3.png
Binary files differ
diff --git a/src/test/baseline/testMediaControl1.png b/src/test/baseline/testMediaControl1.png
new file mode 100644
index 0000000..fd36c50
--- /dev/null
+++ b/src/test/baseline/testMediaControl1.png
Binary files differ
diff --git a/src/test/baseline/testMediaControl2.png b/src/test/baseline/testMediaControl2.png
new file mode 100644
index 0000000..fd01c50
--- /dev/null
+++ b/src/test/baseline/testMediaControl2.png
Binary files differ
diff --git a/src/test/baseline/testMediaControl3.png b/src/test/baseline/testMediaControl3.png
new file mode 100644
index 0000000..9f9c0ee
--- /dev/null
+++ b/src/test/baseline/testMediaControl3.png
Binary files differ
diff --git a/src/test/baseline/testMediaControl4.png b/src/test/baseline/testMediaControl4.png
new file mode 100644
index 0000000..53adc06
--- /dev/null
+++ b/src/test/baseline/testMediaControl4.png
Binary files differ
diff --git a/src/test/baseline/testMediaControl5.png b/src/test/baseline/testMediaControl5.png
new file mode 100644
index 0000000..37d7bf4
--- /dev/null
+++ b/src/test/baseline/testMediaControl5.png
Binary files differ
diff --git a/src/test/baseline/testMediaDir1.png b/src/test/baseline/testMediaDir1.png
new file mode 100644
index 0000000..d566076
--- /dev/null
+++ b/src/test/baseline/testMediaDir1.png
Binary files differ
diff --git a/src/test/baseline/testMediaDir2.png b/src/test/baseline/testMediaDir2.png
new file mode 100644
index 0000000..e46ab2c
--- /dev/null
+++ b/src/test/baseline/testMediaDir2.png
Binary files differ
diff --git a/src/test/baseline/testMesh1.png b/src/test/baseline/testMesh1.png
new file mode 100644
index 0000000..533ea09
--- /dev/null
+++ b/src/test/baseline/testMesh1.png
Binary files differ
diff --git a/src/test/baseline/testMesh2.png b/src/test/baseline/testMesh2.png
new file mode 100644
index 0000000..d81ddbd
--- /dev/null
+++ b/src/test/baseline/testMesh2.png
Binary files differ
diff --git a/src/test/baseline/testMesh3.png b/src/test/baseline/testMesh3.png
new file mode 100644
index 0000000..4e3dab2
--- /dev/null
+++ b/src/test/baseline/testMesh3.png
Binary files differ
diff --git a/src/test/baseline/testMesh4.png b/src/test/baseline/testMesh4.png
new file mode 100644
index 0000000..f325b53
--- /dev/null
+++ b/src/test/baseline/testMesh4.png
Binary files differ
diff --git a/src/test/baseline/testMesh5.png b/src/test/baseline/testMesh5.png
new file mode 100644
index 0000000..86c0a24
--- /dev/null
+++ b/src/test/baseline/testMesh5.png
Binary files differ
diff --git a/src/test/baseline/testMesh6.png b/src/test/baseline/testMesh6.png
new file mode 100644
index 0000000..174636b
--- /dev/null
+++ b/src/test/baseline/testMesh6.png
Binary files differ
diff --git a/src/test/baseline/testMesh7.png b/src/test/baseline/testMesh7.png
new file mode 100644
index 0000000..a7e2493
--- /dev/null
+++ b/src/test/baseline/testMesh7.png
Binary files differ
diff --git a/src/test/baseline/testMesh8.png b/src/test/baseline/testMesh8.png
new file mode 100644
index 0000000..20e4fb1
--- /dev/null
+++ b/src/test/baseline/testMesh8.png
Binary files differ
diff --git a/src/test/baseline/testMipmap.png b/src/test/baseline/testMipmap.png
new file mode 100644
index 0000000..eb6185e
--- /dev/null
+++ b/src/test/baseline/testMipmap.png
Binary files differ
diff --git a/src/test/baseline/testMove1.png b/src/test/baseline/testMove1.png
new file mode 100644
index 0000000..4d0bdec
--- /dev/null
+++ b/src/test/baseline/testMove1.png
Binary files differ
diff --git a/src/test/baseline/testNodeInCanvasNullFX1.png b/src/test/baseline/testNodeInCanvasNullFX1.png
new file mode 100644
index 0000000..00767fb
--- /dev/null
+++ b/src/test/baseline/testNodeInCanvasNullFX1.png
Binary files differ
diff --git a/src/test/baseline/testOffscreen1.png b/src/test/baseline/testOffscreen1.png
new file mode 100644
index 0000000..4c1afa7
--- /dev/null
+++ b/src/test/baseline/testOffscreen1.png
Binary files differ
diff --git a/src/test/baseline/testOffscreen2.png b/src/test/baseline/testOffscreen2.png
new file mode 100644
index 0000000..174636b
--- /dev/null
+++ b/src/test/baseline/testOffscreen2.png
Binary files differ
diff --git a/src/test/baseline/testOffscreen3.png b/src/test/baseline/testOffscreen3.png
new file mode 100644
index 0000000..f274a2b
--- /dev/null
+++ b/src/test/baseline/testOffscreen3.png
Binary files differ
diff --git a/src/test/baseline/testOffscreen4.png b/src/test/baseline/testOffscreen4.png
new file mode 100644
index 0000000..4c1afa7
--- /dev/null
+++ b/src/test/baseline/testOffscreen4.png
Binary files differ
diff --git a/src/test/baseline/testOffscreen5.png b/src/test/baseline/testOffscreen5.png
new file mode 100644
index 0000000..174636b
--- /dev/null
+++ b/src/test/baseline/testOffscreen5.png
Binary files differ
diff --git a/src/test/baseline/testOffscreenAutoRender1.png b/src/test/baseline/testOffscreenAutoRender1.png
new file mode 100644
index 0000000..4c1afa7
--- /dev/null
+++ b/src/test/baseline/testOffscreenAutoRender1.png
Binary files differ
diff --git a/src/test/baseline/testOffscreenAutoRender2.png b/src/test/baseline/testOffscreenAutoRender2.png
new file mode 100644
index 0000000..0d508a9
--- /dev/null
+++ b/src/test/baseline/testOffscreenAutoRender2.png
Binary files differ
diff --git a/src/test/baseline/testOffscreenMultisampleScreenshot.png b/src/test/baseline/testOffscreenMultisampleScreenshot.png
new file mode 100644
index 0000000..1a04a20
--- /dev/null
+++ b/src/test/baseline/testOffscreenMultisampleScreenshot.png
Binary files differ
diff --git a/src/test/baseline/testOffscreenScreenshot.png b/src/test/baseline/testOffscreenScreenshot.png
new file mode 100644
index 0000000..31fcc27
--- /dev/null
+++ b/src/test/baseline/testOffscreenScreenshot.png
Binary files differ
diff --git a/src/test/baseline/testOpacity.png b/src/test/baseline/testOpacity.png
new file mode 100644
index 0000000..aab7cdb
--- /dev/null
+++ b/src/test/baseline/testOpacity.png
Binary files differ
diff --git a/src/test/baseline/testOutlines.png b/src/test/baseline/testOutlines.png
new file mode 100644
index 0000000..36a7c14
--- /dev/null
+++ b/src/test/baseline/testOutlines.png
Binary files differ
diff --git a/src/test/baseline/testPanoDynamics1.png b/src/test/baseline/testPanoDynamics1.png
new file mode 100644
index 0000000..8cac76c
--- /dev/null
+++ b/src/test/baseline/testPanoDynamics1.png
Binary files differ
diff --git a/src/test/baseline/testPanoDynamics2.png b/src/test/baseline/testPanoDynamics2.png
new file mode 100644
index 0000000..21c01f2
--- /dev/null
+++ b/src/test/baseline/testPanoDynamics2.png
Binary files differ
diff --git a/src/test/baseline/testPanoDynamics3.png b/src/test/baseline/testPanoDynamics3.png
new file mode 100644
index 0000000..e52d01b
--- /dev/null
+++ b/src/test/baseline/testPanoDynamics3.png
Binary files differ
diff --git a/src/test/baseline/testPanoImage.png b/src/test/baseline/testPanoImage.png
new file mode 100644
index 0000000..6ce1008
--- /dev/null
+++ b/src/test/baseline/testPanoImage.png
Binary files differ
diff --git a/src/test/baseline/testPanoImagewNOP.png b/src/test/baseline/testPanoImagewNOP.png
new file mode 100644
index 0000000..6ce1008
--- /dev/null
+++ b/src/test/baseline/testPanoImagewNOP.png
Binary files differ
diff --git a/src/test/baseline/testParaWords.png b/src/test/baseline/testParaWords.png
new file mode 100644
index 0000000..4709a3b
--- /dev/null
+++ b/src/test/baseline/testParaWords.png
Binary files differ
diff --git a/src/test/baseline/testParallelAnimC1.png b/src/test/baseline/testParallelAnimC1.png
new file mode 100644
index 0000000..69aa068
--- /dev/null
+++ b/src/test/baseline/testParallelAnimC1.png
Binary files differ
diff --git a/src/test/baseline/testParallelAnimC2.png b/src/test/baseline/testParallelAnimC2.png
new file mode 100644
index 0000000..80a7f81
--- /dev/null
+++ b/src/test/baseline/testParallelAnimC2.png
Binary files differ
diff --git a/src/test/baseline/testParallelAnimC3.png b/src/test/baseline/testParallelAnimC3.png
new file mode 100644
index 0000000..ec591f3
--- /dev/null
+++ b/src/test/baseline/testParallelAnimC3.png
Binary files differ
diff --git a/src/test/baseline/testParallelAnims1.png b/src/test/baseline/testParallelAnims1.png
new file mode 100644
index 0000000..4d189b7
--- /dev/null
+++ b/src/test/baseline/testParallelAnims1.png
Binary files differ
diff --git a/src/test/baseline/testParallelAnims2.png b/src/test/baseline/testParallelAnims2.png
new file mode 100644
index 0000000..64f85d1
--- /dev/null
+++ b/src/test/baseline/testParallelAnims2.png
Binary files differ
diff --git a/src/test/baseline/testPieSlice1.png b/src/test/baseline/testPieSlice1.png
new file mode 100644
index 0000000..9d5bc4d
--- /dev/null
+++ b/src/test/baseline/testPieSlice1.png
Binary files differ
diff --git a/src/test/baseline/testPieSlice2.png b/src/test/baseline/testPieSlice2.png
new file mode 100644
index 0000000..5d62891
--- /dev/null
+++ b/src/test/baseline/testPieSlice2.png
Binary files differ
diff --git a/src/test/baseline/testPieSlice3.png b/src/test/baseline/testPieSlice3.png
new file mode 100644
index 0000000..c011af3
--- /dev/null
+++ b/src/test/baseline/testPieSlice3.png
Binary files differ
diff --git a/src/test/baseline/testPlayBeforeConnect.png b/src/test/baseline/testPlayBeforeConnect.png
new file mode 100644
index 0000000..d27fda0
--- /dev/null
+++ b/src/test/baseline/testPlayBeforeConnect.png
Binary files differ
diff --git a/src/test/baseline/testPointAnim1.png b/src/test/baseline/testPointAnim1.png
new file mode 100644
index 0000000..4c1afa7
--- /dev/null
+++ b/src/test/baseline/testPointAnim1.png
Binary files differ
diff --git a/src/test/baseline/testPointAnim2.png b/src/test/baseline/testPointAnim2.png
new file mode 100644
index 0000000..1d46750
--- /dev/null
+++ b/src/test/baseline/testPointAnim2.png
Binary files differ
diff --git a/src/test/baseline/testPointAnim3.png b/src/test/baseline/testPointAnim3.png
new file mode 100644
index 0000000..1d46750
--- /dev/null
+++ b/src/test/baseline/testPointAnim3.png
Binary files differ
diff --git a/src/test/baseline/testPolyLine1.png b/src/test/baseline/testPolyLine1.png
new file mode 100644
index 0000000..e2843f6
--- /dev/null
+++ b/src/test/baseline/testPolyLine1.png
Binary files differ
diff --git a/src/test/baseline/testPolyLine2.png b/src/test/baseline/testPolyLine2.png
new file mode 100644
index 0000000..4b26092
--- /dev/null
+++ b/src/test/baseline/testPolyLine2.png
Binary files differ
diff --git a/src/test/baseline/testPolyLine3.png b/src/test/baseline/testPolyLine3.png
new file mode 100644
index 0000000..80df8a0
--- /dev/null
+++ b/src/test/baseline/testPolyLine3.png
Binary files differ
diff --git a/src/test/baseline/testPolyLine4.png b/src/test/baseline/testPolyLine4.png
new file mode 100644
index 0000000..e37c026
--- /dev/null
+++ b/src/test/baseline/testPolyLine4.png
Binary files differ
diff --git a/src/test/baseline/testPolyLine5.png b/src/test/baseline/testPolyLine5.png
new file mode 100644
index 0000000..80df8a0
--- /dev/null
+++ b/src/test/baseline/testPolyLine5.png
Binary files differ
diff --git a/src/test/baseline/testPolyLine6.png b/src/test/baseline/testPolyLine6.png
new file mode 100644
index 0000000..2607d53
--- /dev/null
+++ b/src/test/baseline/testPolyLine6.png
Binary files differ
diff --git a/src/test/baseline/testPolygon1.png b/src/test/baseline/testPolygon1.png
new file mode 100644
index 0000000..441ed9b
--- /dev/null
+++ b/src/test/baseline/testPolygon1.png
Binary files differ
diff --git a/src/test/baseline/testPolygon2.png b/src/test/baseline/testPolygon2.png
new file mode 100644
index 0000000..858bf40
--- /dev/null
+++ b/src/test/baseline/testPolygon2.png
Binary files differ
diff --git a/src/test/baseline/testPolygon3.png b/src/test/baseline/testPolygon3.png
new file mode 100644
index 0000000..636ada8
--- /dev/null
+++ b/src/test/baseline/testPolygon3.png
Binary files differ
diff --git a/src/test/baseline/testPolygon4.png b/src/test/baseline/testPolygon4.png
new file mode 100644
index 0000000..636ada8
--- /dev/null
+++ b/src/test/baseline/testPolygon4.png
Binary files differ
diff --git a/src/test/baseline/testPolygon5.png b/src/test/baseline/testPolygon5.png
new file mode 100644
index 0000000..964a01b
--- /dev/null
+++ b/src/test/baseline/testPolygon5.png
Binary files differ
diff --git a/src/test/baseline/testPolygon6.png b/src/test/baseline/testPolygon6.png
new file mode 100644
index 0000000..45ee95d
--- /dev/null
+++ b/src/test/baseline/testPolygon6.png
Binary files differ
diff --git a/src/test/baseline/testPolygon7.png b/src/test/baseline/testPolygon7.png
new file mode 100644
index 0000000..5cb45e6
--- /dev/null
+++ b/src/test/baseline/testPolygon7.png
Binary files differ
diff --git a/src/test/baseline/testPolygon8.png b/src/test/baseline/testPolygon8.png
new file mode 100644
index 0000000..f926687
--- /dev/null
+++ b/src/test/baseline/testPolygon8.png
Binary files differ
diff --git a/src/test/baseline/testPolygon9.png b/src/test/baseline/testPolygon9.png
new file mode 100644
index 0000000..3e00de4
--- /dev/null
+++ b/src/test/baseline/testPolygon9.png
Binary files differ
diff --git a/src/test/baseline/testPolygonHole1.png b/src/test/baseline/testPolygonHole1.png
new file mode 100644
index 0000000..9c18ad1
--- /dev/null
+++ b/src/test/baseline/testPolygonHole1.png
Binary files differ
diff --git a/src/test/baseline/testPolygonHole2.png b/src/test/baseline/testPolygonHole2.png
new file mode 100644
index 0000000..d8199da
--- /dev/null
+++ b/src/test/baseline/testPolygonHole2.png
Binary files differ
diff --git a/src/test/baseline/testPositioning.png b/src/test/baseline/testPositioning.png
new file mode 100644
index 0000000..1b174b0
--- /dev/null
+++ b/src/test/baseline/testPositioning.png
Binary files differ
diff --git a/src/test/baseline/testProgressBar1.png b/src/test/baseline/testProgressBar1.png
new file mode 100644
index 0000000..2b2c752
--- /dev/null
+++ b/src/test/baseline/testProgressBar1.png
Binary files differ
diff --git a/src/test/baseline/testProgressBar2.png b/src/test/baseline/testProgressBar2.png
new file mode 100644
index 0000000..6c1f56b
--- /dev/null
+++ b/src/test/baseline/testProgressBar2.png
Binary files differ
diff --git a/src/test/baseline/testProgressBar3.png b/src/test/baseline/testProgressBar3.png
new file mode 100644
index 0000000..d788f76
--- /dev/null
+++ b/src/test/baseline/testProgressBar3.png
Binary files differ
diff --git a/src/test/baseline/testRawText1.png b/src/test/baseline/testRawText1.png
new file mode 100644
index 0000000..4733e87
--- /dev/null
+++ b/src/test/baseline/testRawText1.png
Binary files differ
diff --git a/src/test/baseline/testRawText2.png b/src/test/baseline/testRawText2.png
new file mode 100644
index 0000000..cedb8bb
--- /dev/null
+++ b/src/test/baseline/testRawText2.png
Binary files differ
diff --git a/src/test/baseline/testRawText3.png b/src/test/baseline/testRawText3.png
new file mode 100644
index 0000000..e91b743
--- /dev/null
+++ b/src/test/baseline/testRawText3.png
Binary files differ
diff --git a/src/test/baseline/testRawText4.png b/src/test/baseline/testRawText4.png
new file mode 100644
index 0000000..cd1c0dc
--- /dev/null
+++ b/src/test/baseline/testRawText4.png
Binary files differ
diff --git a/src/test/baseline/testRect1.png b/src/test/baseline/testRect1.png
new file mode 100644
index 0000000..c2f4c5e
--- /dev/null
+++ b/src/test/baseline/testRect1.png
Binary files differ
diff --git a/src/test/baseline/testRect2.png b/src/test/baseline/testRect2.png
new file mode 100644
index 0000000..9d9ec9d
--- /dev/null
+++ b/src/test/baseline/testRect2.png
Binary files differ
diff --git a/src/test/baseline/testRect3.png b/src/test/baseline/testRect3.png
new file mode 100644
index 0000000..aabb540
--- /dev/null
+++ b/src/test/baseline/testRect3.png
Binary files differ
diff --git a/src/test/baseline/testRect4.png b/src/test/baseline/testRect4.png
new file mode 100644
index 0000000..c549747
--- /dev/null
+++ b/src/test/baseline/testRect4.png
Binary files differ
diff --git a/src/test/baseline/testRenderPipeline.png b/src/test/baseline/testRenderPipeline.png
new file mode 100644
index 0000000..f9603fd
--- /dev/null
+++ b/src/test/baseline/testRenderPipeline.png
Binary files differ
diff --git a/src/test/baseline/testRotate1.png b/src/test/baseline/testRotate1.png
new file mode 100644
index 0000000..7c8aa25
--- /dev/null
+++ b/src/test/baseline/testRotate1.png
Binary files differ
diff --git a/src/test/baseline/testRotate1a.png b/src/test/baseline/testRotate1a.png
new file mode 100644
index 0000000..4e71a64
--- /dev/null
+++ b/src/test/baseline/testRotate1a.png
Binary files differ
diff --git a/src/test/baseline/testRotate1b.png b/src/test/baseline/testRotate1b.png
new file mode 100644
index 0000000..d1b5321
--- /dev/null
+++ b/src/test/baseline/testRotate1b.png
Binary files differ
diff --git a/src/test/baseline/testRotate2.png b/src/test/baseline/testRotate2.png
new file mode 100644
index 0000000..5db6d09
--- /dev/null
+++ b/src/test/baseline/testRotate2.png
Binary files differ
diff --git a/src/test/baseline/testRotatePivot1.png b/src/test/baseline/testRotatePivot1.png
new file mode 100644
index 0000000..6b4d6ef
--- /dev/null
+++ b/src/test/baseline/testRotatePivot1.png
Binary files differ
diff --git a/src/test/baseline/testRotatePivot2.png b/src/test/baseline/testRotatePivot2.png
new file mode 100644
index 0000000..d5122c7
--- /dev/null
+++ b/src/test/baseline/testRotatePivot2.png
Binary files differ
diff --git a/src/test/baseline/testRotatePivot3.png b/src/test/baseline/testRotatePivot3.png
new file mode 100644
index 0000000..8237df6
--- /dev/null
+++ b/src/test/baseline/testRotatePivot3.png
Binary files differ
diff --git a/src/test/baseline/testRoundedRect1.png b/src/test/baseline/testRoundedRect1.png
new file mode 100644
index 0000000..44e5013
--- /dev/null
+++ b/src/test/baseline/testRoundedRect1.png
Binary files differ
diff --git a/src/test/baseline/testRoundedRect2.png b/src/test/baseline/testRoundedRect2.png
new file mode 100644
index 0000000..b50d434
--- /dev/null
+++ b/src/test/baseline/testRoundedRect2.png
Binary files differ
diff --git a/src/test/baseline/testRoundedRect3.png b/src/test/baseline/testRoundedRect3.png
new file mode 100644
index 0000000..b35eb14
--- /dev/null
+++ b/src/test/baseline/testRoundedRect3.png
Binary files differ
diff --git a/src/test/baseline/testRoundedRect4.png b/src/test/baseline/testRoundedRect4.png
new file mode 100644
index 0000000..a6e5d6e
--- /dev/null
+++ b/src/test/baseline/testRoundedRect4.png
Binary files differ
diff --git a/src/test/baseline/testRoundedRect5.png b/src/test/baseline/testRoundedRect5.png
new file mode 100644
index 0000000..c6da32c
--- /dev/null
+++ b/src/test/baseline/testRoundedRect5.png
Binary files differ
diff --git a/src/test/baseline/testRoundedRect6.png b/src/test/baseline/testRoundedRect6.png
new file mode 100644
index 0000000..a9e76a8
--- /dev/null
+++ b/src/test/baseline/testRoundedRect6.png
Binary files differ
diff --git a/src/test/baseline/testScrollArea1.png b/src/test/baseline/testScrollArea1.png
new file mode 100644
index 0000000..4cb67e2
--- /dev/null
+++ b/src/test/baseline/testScrollArea1.png
Binary files differ
diff --git a/src/test/baseline/testScrollArea2.png b/src/test/baseline/testScrollArea2.png
new file mode 100644
index 0000000..7939cae
--- /dev/null
+++ b/src/test/baseline/testScrollArea2.png
Binary files differ
diff --git a/src/test/baseline/testScrollArea3.png b/src/test/baseline/testScrollArea3.png
new file mode 100644
index 0000000..1fc62df
--- /dev/null
+++ b/src/test/baseline/testScrollArea3.png
Binary files differ
diff --git a/src/test/baseline/testScrollBarHoriz1.png b/src/test/baseline/testScrollBarHoriz1.png
new file mode 100644
index 0000000..aedcb12
--- /dev/null
+++ b/src/test/baseline/testScrollBarHoriz1.png
Binary files differ
diff --git a/src/test/baseline/testScrollBarHoriz10.png b/src/test/baseline/testScrollBarHoriz10.png
new file mode 100644
index 0000000..0c8a5af
--- /dev/null
+++ b/src/test/baseline/testScrollBarHoriz10.png
Binary files differ
diff --git a/src/test/baseline/testScrollBarHoriz11.png b/src/test/baseline/testScrollBarHoriz11.png
new file mode 100644
index 0000000..da84ebc
--- /dev/null
+++ b/src/test/baseline/testScrollBarHoriz11.png
Binary files differ
diff --git a/src/test/baseline/testScrollBarHoriz12.png b/src/test/baseline/testScrollBarHoriz12.png
new file mode 100644
index 0000000..5e2f013
--- /dev/null
+++ b/src/test/baseline/testScrollBarHoriz12.png
Binary files differ
diff --git a/src/test/baseline/testScrollBarHoriz2.png b/src/test/baseline/testScrollBarHoriz2.png
new file mode 100644
index 0000000..b8a2dcd
--- /dev/null
+++ b/src/test/baseline/testScrollBarHoriz2.png
Binary files differ
diff --git a/src/test/baseline/testScrollBarHoriz3.png b/src/test/baseline/testScrollBarHoriz3.png
new file mode 100644
index 0000000..885b429
--- /dev/null
+++ b/src/test/baseline/testScrollBarHoriz3.png
Binary files differ
diff --git a/src/test/baseline/testScrollBarHoriz4.png b/src/test/baseline/testScrollBarHoriz4.png
new file mode 100644
index 0000000..8ceea4f
--- /dev/null
+++ b/src/test/baseline/testScrollBarHoriz4.png
Binary files differ
diff --git a/src/test/baseline/testScrollBarHoriz5.png b/src/test/baseline/testScrollBarHoriz5.png
new file mode 100644
index 0000000..4278825
--- /dev/null
+++ b/src/test/baseline/testScrollBarHoriz5.png
Binary files differ
diff --git a/src/test/baseline/testScrollBarHoriz6.png b/src/test/baseline/testScrollBarHoriz6.png
new file mode 100644
index 0000000..ee270d3
--- /dev/null
+++ b/src/test/baseline/testScrollBarHoriz6.png
Binary files differ
diff --git a/src/test/baseline/testScrollBarHoriz7.png b/src/test/baseline/testScrollBarHoriz7.png
new file mode 100644
index 0000000..0fefd7b
--- /dev/null
+++ b/src/test/baseline/testScrollBarHoriz7.png
Binary files differ
diff --git a/src/test/baseline/testScrollBarHoriz8.png b/src/test/baseline/testScrollBarHoriz8.png
new file mode 100644
index 0000000..138ec3a
--- /dev/null
+++ b/src/test/baseline/testScrollBarHoriz8.png
Binary files differ
diff --git a/src/test/baseline/testScrollBarHoriz9.png b/src/test/baseline/testScrollBarHoriz9.png
new file mode 100644
index 0000000..0fefd7b
--- /dev/null
+++ b/src/test/baseline/testScrollBarHoriz9.png
Binary files differ
diff --git a/src/test/baseline/testScrollBarVert1.png b/src/test/baseline/testScrollBarVert1.png
new file mode 100644
index 0000000..25c3098
--- /dev/null
+++ b/src/test/baseline/testScrollBarVert1.png
Binary files differ
diff --git a/src/test/baseline/testScrollBarVert2.png b/src/test/baseline/testScrollBarVert2.png
new file mode 100644
index 0000000..572fac9
--- /dev/null
+++ b/src/test/baseline/testScrollBarVert2.png
Binary files differ
diff --git a/src/test/baseline/testScrollBarVert3.png b/src/test/baseline/testScrollBarVert3.png
new file mode 100644
index 0000000..d1a893c
--- /dev/null
+++ b/src/test/baseline/testScrollBarVert3.png
Binary files differ
diff --git a/src/test/baseline/testScrollBarVert4.png b/src/test/baseline/testScrollBarVert4.png
new file mode 100644
index 0000000..a29849f
--- /dev/null
+++ b/src/test/baseline/testScrollBarVert4.png
Binary files differ
diff --git a/src/test/baseline/testScrollBarVert5.png b/src/test/baseline/testScrollBarVert5.png
new file mode 100644
index 0000000..ff40ef7
--- /dev/null
+++ b/src/test/baseline/testScrollBarVert5.png
Binary files differ
diff --git a/src/test/baseline/testScrollBarVert6.png b/src/test/baseline/testScrollBarVert6.png
new file mode 100644
index 0000000..edb3196
--- /dev/null
+++ b/src/test/baseline/testScrollBarVert6.png
Binary files differ
diff --git a/src/test/baseline/testScrollBarVert7.png b/src/test/baseline/testScrollBarVert7.png
new file mode 100644
index 0000000..115d8ca
--- /dev/null
+++ b/src/test/baseline/testScrollBarVert7.png
Binary files differ
diff --git a/src/test/baseline/testScrollBarVert8.png b/src/test/baseline/testScrollBarVert8.png
new file mode 100644
index 0000000..5e1e08b
--- /dev/null
+++ b/src/test/baseline/testScrollBarVert8.png
Binary files differ
diff --git a/src/test/baseline/testScrollBarVert9.png b/src/test/baseline/testScrollBarVert9.png
new file mode 100644
index 0000000..3a7ff70
--- /dev/null
+++ b/src/test/baseline/testScrollBarVert9.png
Binary files differ
diff --git a/src/test/baseline/testScrollPane1.png b/src/test/baseline/testScrollPane1.png
new file mode 100644
index 0000000..68fcad1
--- /dev/null
+++ b/src/test/baseline/testScrollPane1.png
Binary files differ
diff --git a/src/test/baseline/testScrollPane2.png b/src/test/baseline/testScrollPane2.png
new file mode 100644
index 0000000..3e58737
--- /dev/null
+++ b/src/test/baseline/testScrollPane2.png
Binary files differ
diff --git a/src/test/baseline/testScrollPane3.png b/src/test/baseline/testScrollPane3.png
new file mode 100644
index 0000000..834a091
--- /dev/null
+++ b/src/test/baseline/testScrollPane3.png
Binary files differ
diff --git a/src/test/baseline/testSeekAfterEOF.png b/src/test/baseline/testSeekAfterEOF.png
new file mode 100644
index 0000000..76e79c1
--- /dev/null
+++ b/src/test/baseline/testSeekAfterEOF.png
Binary files differ
diff --git a/src/test/baseline/testShadowFX1.png b/src/test/baseline/testShadowFX1.png
new file mode 100644
index 0000000..7d1d5d7
--- /dev/null
+++ b/src/test/baseline/testShadowFX1.png
Binary files differ
diff --git a/src/test/baseline/testShadowFX2.png b/src/test/baseline/testShadowFX2.png
new file mode 100644
index 0000000..0d9b1ee
--- /dev/null
+++ b/src/test/baseline/testShadowFX2.png
Binary files differ
diff --git a/src/test/baseline/testShadowFX3.png b/src/test/baseline/testShadowFX3.png
new file mode 100644
index 0000000..3a3a678
--- /dev/null
+++ b/src/test/baseline/testShadowFX3.png
Binary files differ
diff --git a/src/test/baseline/testShadowFX4.png b/src/test/baseline/testShadowFX4.png
new file mode 100644
index 0000000..13da229
--- /dev/null
+++ b/src/test/baseline/testShadowFX4.png
Binary files differ
diff --git a/src/test/baseline/testShadowFX5.png b/src/test/baseline/testShadowFX5.png
new file mode 100644
index 0000000..b1ed885
--- /dev/null
+++ b/src/test/baseline/testShadowFX5.png
Binary files differ
diff --git a/src/test/baseline/testShadowFX6.png b/src/test/baseline/testShadowFX6.png
new file mode 100644
index 0000000..52e8c14
--- /dev/null
+++ b/src/test/baseline/testShadowFX6.png
Binary files differ
diff --git a/src/test/baseline/testSimpleWords.png b/src/test/baseline/testSimpleWords.png
new file mode 100644
index 0000000..21e1a1b
--- /dev/null
+++ b/src/test/baseline/testSimpleWords.png
Binary files differ
diff --git a/src/test/baseline/testSliderHoriz1.png b/src/test/baseline/testSliderHoriz1.png
new file mode 100644
index 0000000..c30040d
--- /dev/null
+++ b/src/test/baseline/testSliderHoriz1.png
Binary files differ
diff --git a/src/test/baseline/testSliderHoriz2.png b/src/test/baseline/testSliderHoriz2.png
new file mode 100644
index 0000000..e22a32f
--- /dev/null
+++ b/src/test/baseline/testSliderHoriz2.png
Binary files differ
diff --git a/src/test/baseline/testSliderHoriz3.png b/src/test/baseline/testSliderHoriz3.png
new file mode 100644
index 0000000..bcf1690
--- /dev/null
+++ b/src/test/baseline/testSliderHoriz3.png
Binary files differ
diff --git a/src/test/baseline/testSliderHoriz4.png b/src/test/baseline/testSliderHoriz4.png
new file mode 100644
index 0000000..7c48e5a
--- /dev/null
+++ b/src/test/baseline/testSliderHoriz4.png
Binary files differ
diff --git a/src/test/baseline/testSliderHoriz5.png b/src/test/baseline/testSliderHoriz5.png
new file mode 100644
index 0000000..2b6534a
--- /dev/null
+++ b/src/test/baseline/testSliderHoriz5.png
Binary files differ
diff --git a/src/test/baseline/testSliderVert1.png b/src/test/baseline/testSliderVert1.png
new file mode 100644
index 0000000..d82d467
--- /dev/null
+++ b/src/test/baseline/testSliderVert1.png
Binary files differ
diff --git a/src/test/baseline/testSliderVert2.png b/src/test/baseline/testSliderVert2.png
new file mode 100644
index 0000000..294dae9
--- /dev/null
+++ b/src/test/baseline/testSliderVert2.png
Binary files differ
diff --git a/src/test/baseline/testSliderVert3.png b/src/test/baseline/testSliderVert3.png
new file mode 100644
index 0000000..4a00a8f
--- /dev/null
+++ b/src/test/baseline/testSliderVert3.png
Binary files differ
diff --git a/src/test/baseline/testSliderVert4.png b/src/test/baseline/testSliderVert4.png
new file mode 100644
index 0000000..f13d278
--- /dev/null
+++ b/src/test/baseline/testSliderVert4.png
Binary files differ
diff --git a/src/test/baseline/testSliderVert5.png b/src/test/baseline/testSliderVert5.png
new file mode 100644
index 0000000..a939fe0
--- /dev/null
+++ b/src/test/baseline/testSliderVert5.png
Binary files differ
diff --git a/src/test/baseline/testSpanWords.png b/src/test/baseline/testSpanWords.png
new file mode 100644
index 0000000..c206d60
--- /dev/null
+++ b/src/test/baseline/testSpanWords.png
Binary files differ
diff --git a/src/test/baseline/testSplineAnim1.png b/src/test/baseline/testSplineAnim1.png
new file mode 100644
index 0000000..82abf89
--- /dev/null
+++ b/src/test/baseline/testSplineAnim1.png
Binary files differ
diff --git a/src/test/baseline/testSplineAnim2.png b/src/test/baseline/testSplineAnim2.png
new file mode 100644
index 0000000..e299221
--- /dev/null
+++ b/src/test/baseline/testSplineAnim2.png
Binary files differ
diff --git a/src/test/baseline/testSplineAnim3.png b/src/test/baseline/testSplineAnim3.png
new file mode 100644
index 0000000..36a6afc
--- /dev/null
+++ b/src/test/baseline/testSplineAnim3.png
Binary files differ
diff --git a/src/test/baseline/testStateAnim1.png b/src/test/baseline/testStateAnim1.png
new file mode 100644
index 0000000..19ad729
--- /dev/null
+++ b/src/test/baseline/testStateAnim1.png
Binary files differ
diff --git a/src/test/baseline/testStateAnim2.png b/src/test/baseline/testStateAnim2.png
new file mode 100644
index 0000000..92a98a5
--- /dev/null
+++ b/src/test/baseline/testStateAnim2.png
Binary files differ
diff --git a/src/test/baseline/testStateAnim3.png b/src/test/baseline/testStateAnim3.png
new file mode 100644
index 0000000..92a98a5
--- /dev/null
+++ b/src/test/baseline/testStateAnim3.png
Binary files differ
diff --git a/src/test/baseline/testStateAnim4.png b/src/test/baseline/testStateAnim4.png
new file mode 100644
index 0000000..19ad729
--- /dev/null
+++ b/src/test/baseline/testStateAnim4.png
Binary files differ
diff --git a/src/test/baseline/testStateAnim5.png b/src/test/baseline/testStateAnim5.png
new file mode 100644
index 0000000..92a98a5
--- /dev/null
+++ b/src/test/baseline/testStateAnim5.png
Binary files differ
diff --git a/src/test/baseline/testStateAnimC1.png b/src/test/baseline/testStateAnimC1.png
new file mode 100644
index 0000000..02f0389
--- /dev/null
+++ b/src/test/baseline/testStateAnimC1.png
Binary files differ
diff --git a/src/test/baseline/testStateAnimC2.png b/src/test/baseline/testStateAnimC2.png
new file mode 100644
index 0000000..2126c02
--- /dev/null
+++ b/src/test/baseline/testStateAnimC2.png
Binary files differ
diff --git a/src/test/baseline/testStateAnimC3.png b/src/test/baseline/testStateAnimC3.png
new file mode 100644
index 0000000..dc43edc
--- /dev/null
+++ b/src/test/baseline/testStateAnimC3.png
Binary files differ
diff --git a/src/test/baseline/testStateAnimC4.png b/src/test/baseline/testStateAnimC4.png
new file mode 100644
index 0000000..2126c02
--- /dev/null
+++ b/src/test/baseline/testStateAnimC4.png
Binary files differ
diff --git a/src/test/baseline/testStateAnimC5.png b/src/test/baseline/testStateAnimC5.png
new file mode 100644
index 0000000..2126c02
--- /dev/null
+++ b/src/test/baseline/testStateAnimC5.png
Binary files differ
diff --git a/src/test/baseline/testStretchNodeHoriz1.png b/src/test/baseline/testStretchNodeHoriz1.png
new file mode 100644
index 0000000..652ada8
--- /dev/null
+++ b/src/test/baseline/testStretchNodeHoriz1.png
Binary files differ
diff --git a/src/test/baseline/testStretchNodeHoriz2.png b/src/test/baseline/testStretchNodeHoriz2.png
new file mode 100644
index 0000000..fe123b0
--- /dev/null
+++ b/src/test/baseline/testStretchNodeHoriz2.png
Binary files differ
diff --git a/src/test/baseline/testStretchNodeVert1.png b/src/test/baseline/testStretchNodeVert1.png
new file mode 100644
index 0000000..a0e6fe3
--- /dev/null
+++ b/src/test/baseline/testStretchNodeVert1.png
Binary files differ
diff --git a/src/test/baseline/testStretchNodeVert2.png b/src/test/baseline/testStretchNodeVert2.png
new file mode 100644
index 0000000..ac7d496
--- /dev/null
+++ b/src/test/baseline/testStretchNodeVert2.png
Binary files differ
diff --git a/src/test/baseline/testSvgBmp.png b/src/test/baseline/testSvgBmp.png
new file mode 100644
index 0000000..8020a67
--- /dev/null
+++ b/src/test/baseline/testSvgBmp.png
Binary files differ
diff --git a/src/test/baseline/testSvgNode.png b/src/test/baseline/testSvgNode.png
new file mode 100644
index 0000000..76d1632
--- /dev/null
+++ b/src/test/baseline/testSvgNode.png
Binary files differ
diff --git a/src/test/baseline/testSvgPosBmp.png b/src/test/baseline/testSvgPosBmp.png
new file mode 100644
index 0000000..6eb83fe
--- /dev/null
+++ b/src/test/baseline/testSvgPosBmp.png
Binary files differ
diff --git a/src/test/baseline/testSvgScaleBmp1.png b/src/test/baseline/testSvgScaleBmp1.png
new file mode 100644
index 0000000..ba46499
--- /dev/null
+++ b/src/test/baseline/testSvgScaleBmp1.png
Binary files differ
diff --git a/src/test/baseline/testSvgScaleBmp2.png b/src/test/baseline/testSvgScaleBmp2.png
new file mode 100644
index 0000000..eb038d5
--- /dev/null
+++ b/src/test/baseline/testSvgScaleBmp2.png
Binary files differ
diff --git a/src/test/baseline/testSvgScaledNode1.png b/src/test/baseline/testSvgScaledNode1.png
new file mode 100644
index 0000000..7c78fb5
--- /dev/null
+++ b/src/test/baseline/testSvgScaledNode1.png
Binary files differ
diff --git a/src/test/baseline/testSvgScaledNode2.png b/src/test/baseline/testSvgScaledNode2.png
new file mode 100644
index 0000000..3cdff7f
--- /dev/null
+++ b/src/test/baseline/testSvgScaledNode2.png
Binary files differ
diff --git a/src/test/baseline/testTexCompression1.png b/src/test/baseline/testTexCompression1.png
new file mode 100644
index 0000000..8629a85
--- /dev/null
+++ b/src/test/baseline/testTexCompression1.png
Binary files differ
diff --git a/src/test/baseline/testTexCompression2.png b/src/test/baseline/testTexCompression2.png
new file mode 100644
index 0000000..51acdba
--- /dev/null
+++ b/src/test/baseline/testTexCompression2.png
Binary files differ
diff --git a/src/test/baseline/testTextArea1.png b/src/test/baseline/testTextArea1.png
new file mode 100644
index 0000000..7cf8ac1
--- /dev/null
+++ b/src/test/baseline/testTextArea1.png
Binary files differ
diff --git a/src/test/baseline/testTextArea2.png b/src/test/baseline/testTextArea2.png
new file mode 100644
index 0000000..6fe4c64
--- /dev/null
+++ b/src/test/baseline/testTextArea2.png
Binary files differ
diff --git a/src/test/baseline/testTextArea3.png b/src/test/baseline/testTextArea3.png
new file mode 100644
index 0000000..6577cf2
--- /dev/null
+++ b/src/test/baseline/testTextArea3.png
Binary files differ
diff --git a/src/test/baseline/testTextArea4.png b/src/test/baseline/testTextArea4.png
new file mode 100644
index 0000000..2fc48fe
--- /dev/null
+++ b/src/test/baseline/testTextArea4.png
Binary files differ
diff --git a/src/test/baseline/testTextArea5.png b/src/test/baseline/testTextArea5.png
new file mode 100644
index 0000000..a7c53e2
--- /dev/null
+++ b/src/test/baseline/testTextArea5.png
Binary files differ
diff --git a/src/test/baseline/testTextButtonDisabled.png b/src/test/baseline/testTextButtonDisabled.png
new file mode 100644
index 0000000..c859bfa
--- /dev/null
+++ b/src/test/baseline/testTextButtonDisabled.png
Binary files differ
diff --git a/src/test/baseline/testTextButtonDown.png b/src/test/baseline/testTextButtonDown.png
new file mode 100644
index 0000000..9122c33
--- /dev/null
+++ b/src/test/baseline/testTextButtonDown.png
Binary files differ
diff --git a/src/test/baseline/testTextButtonDownNewText.png b/src/test/baseline/testTextButtonDownNewText.png
new file mode 100644
index 0000000..9592a86
--- /dev/null
+++ b/src/test/baseline/testTextButtonDownNewText.png
Binary files differ
diff --git a/src/test/baseline/testTextButtonUp.png b/src/test/baseline/testTextButtonUp.png
new file mode 100644
index 0000000..c859bfa
--- /dev/null
+++ b/src/test/baseline/testTextButtonUp.png
Binary files differ
diff --git a/src/test/baseline/testTextButtonUpNewText.png b/src/test/baseline/testTextButtonUpNewText.png
new file mode 100644
index 0000000..ebb66bc
--- /dev/null
+++ b/src/test/baseline/testTextButtonUpNewText.png
Binary files differ
diff --git a/src/test/baseline/testTexturedCurve1.png b/src/test/baseline/testTexturedCurve1.png
new file mode 100644
index 0000000..dc626fd
--- /dev/null
+++ b/src/test/baseline/testTexturedCurve1.png
Binary files differ
diff --git a/src/test/baseline/testTexturedCurve2.png b/src/test/baseline/testTexturedCurve2.png
new file mode 100644
index 0000000..f75a670
--- /dev/null
+++ b/src/test/baseline/testTexturedCurve2.png
Binary files differ
diff --git a/src/test/baseline/testTexturedPolyLine1.png b/src/test/baseline/testTexturedPolyLine1.png
new file mode 100644
index 0000000..1fd2e84
--- /dev/null
+++ b/src/test/baseline/testTexturedPolyLine1.png
Binary files differ
diff --git a/src/test/baseline/testTexturedPolyLine2.png b/src/test/baseline/testTexturedPolyLine2.png
new file mode 100644
index 0000000..ccbe01d
--- /dev/null
+++ b/src/test/baseline/testTexturedPolyLine2.png
Binary files differ
diff --git a/src/test/baseline/testTexturedPolyLine3.png b/src/test/baseline/testTexturedPolyLine3.png
new file mode 100644
index 0000000..65c59eb
--- /dev/null
+++ b/src/test/baseline/testTexturedPolyLine3.png
Binary files differ
diff --git a/src/test/baseline/testTexturedPolyLine4.png b/src/test/baseline/testTexturedPolyLine4.png
new file mode 100644
index 0000000..f063a2f
--- /dev/null
+++ b/src/test/baseline/testTexturedPolyLine4.png
Binary files differ
diff --git a/src/test/baseline/testTexturedPolygon1.png b/src/test/baseline/testTexturedPolygon1.png
new file mode 100644
index 0000000..7064f8d
--- /dev/null
+++ b/src/test/baseline/testTexturedPolygon1.png
Binary files differ
diff --git a/src/test/baseline/testTexturedPolygon2.png b/src/test/baseline/testTexturedPolygon2.png
new file mode 100644
index 0000000..05f67c2
--- /dev/null
+++ b/src/test/baseline/testTexturedPolygon2.png
Binary files differ
diff --git a/src/test/baseline/testTexturedPolygon3.png b/src/test/baseline/testTexturedPolygon3.png
new file mode 100644
index 0000000..31730e0
--- /dev/null
+++ b/src/test/baseline/testTexturedPolygon3.png
Binary files differ
diff --git a/src/test/baseline/testTexturedPolygon4.png b/src/test/baseline/testTexturedPolygon4.png
new file mode 100644
index 0000000..333ada7
--- /dev/null
+++ b/src/test/baseline/testTexturedPolygon4.png
Binary files differ
diff --git a/src/test/baseline/testTexturedPolygon5.png b/src/test/baseline/testTexturedPolygon5.png
new file mode 100644
index 0000000..e7f7cc4
--- /dev/null
+++ b/src/test/baseline/testTexturedPolygon5.png
Binary files differ
diff --git a/src/test/baseline/testTexturedPolygon6.png b/src/test/baseline/testTexturedPolygon6.png
new file mode 100644
index 0000000..1222a19
--- /dev/null
+++ b/src/test/baseline/testTexturedPolygon6.png
Binary files differ
diff --git a/src/test/baseline/testTexturedRect1.png b/src/test/baseline/testTexturedRect1.png
new file mode 100644
index 0000000..35edac3
--- /dev/null
+++ b/src/test/baseline/testTexturedRect1.png
Binary files differ
diff --git a/src/test/baseline/testTexturedRect2.png b/src/test/baseline/testTexturedRect2.png
new file mode 100644
index 0000000..5d2a0ba
--- /dev/null
+++ b/src/test/baseline/testTexturedRect2.png
Binary files differ
diff --git a/src/test/baseline/testTexturedRect3.png b/src/test/baseline/testTexturedRect3.png
new file mode 100644
index 0000000..f5f2b77
--- /dev/null
+++ b/src/test/baseline/testTexturedRect3.png
Binary files differ
diff --git a/src/test/baseline/testTexturedRect4.png b/src/test/baseline/testTexturedRect4.png
new file mode 100644
index 0000000..795a7ad
--- /dev/null
+++ b/src/test/baseline/testTexturedRect4.png
Binary files differ
diff --git a/src/test/baseline/testTexturedRect5.png b/src/test/baseline/testTexturedRect5.png
new file mode 100644
index 0000000..38d6e56
--- /dev/null
+++ b/src/test/baseline/testTexturedRect5.png
Binary files differ
diff --git a/src/test/baseline/testTexturedRect6.png b/src/test/baseline/testTexturedRect6.png
new file mode 100644
index 0000000..b124377
--- /dev/null
+++ b/src/test/baseline/testTexturedRect6.png
Binary files differ
diff --git a/src/test/baseline/testTexturedRect7.png b/src/test/baseline/testTexturedRect7.png
new file mode 100644
index 0000000..ed51fa1
--- /dev/null
+++ b/src/test/baseline/testTexturedRect7.png
Binary files differ
diff --git a/src/test/baseline/testTexturedRect8.png b/src/test/baseline/testTexturedRect8.png
new file mode 100644
index 0000000..ddf74a2
--- /dev/null
+++ b/src/test/baseline/testTexturedRect8.png
Binary files differ
diff --git a/src/test/baseline/testTimeSliderHoriz1.png b/src/test/baseline/testTimeSliderHoriz1.png
new file mode 100644
index 0000000..42c0eca
--- /dev/null
+++ b/src/test/baseline/testTimeSliderHoriz1.png
Binary files differ
diff --git a/src/test/baseline/testTimeSliderHoriz2.png b/src/test/baseline/testTimeSliderHoriz2.png
new file mode 100644
index 0000000..a42b8ca
--- /dev/null
+++ b/src/test/baseline/testTimeSliderHoriz2.png
Binary files differ
diff --git a/src/test/baseline/testTimeSliderHoriz3.png b/src/test/baseline/testTimeSliderHoriz3.png
new file mode 100644
index 0000000..4908be5
--- /dev/null
+++ b/src/test/baseline/testTimeSliderHoriz3.png
Binary files differ
diff --git a/src/test/baseline/testTimeSliderHoriz4.png b/src/test/baseline/testTimeSliderHoriz4.png
new file mode 100644
index 0000000..1371480
--- /dev/null
+++ b/src/test/baseline/testTimeSliderHoriz4.png
Binary files differ
diff --git a/src/test/baseline/testTimeSliderHoriz5.png b/src/test/baseline/testTimeSliderHoriz5.png
new file mode 100644
index 0000000..1371480
--- /dev/null
+++ b/src/test/baseline/testTimeSliderHoriz5.png
Binary files differ
diff --git a/src/test/baseline/testTimeSliderVert1.png b/src/test/baseline/testTimeSliderVert1.png
new file mode 100644
index 0000000..8b31bac
--- /dev/null
+++ b/src/test/baseline/testTimeSliderVert1.png
Binary files differ
diff --git a/src/test/baseline/testTimeSliderVert2.png b/src/test/baseline/testTimeSliderVert2.png
new file mode 100644
index 0000000..79be7d1
--- /dev/null
+++ b/src/test/baseline/testTimeSliderVert2.png
Binary files differ
diff --git a/src/test/baseline/testTimeSliderVert3.png b/src/test/baseline/testTimeSliderVert3.png
new file mode 100644
index 0000000..a3a8718
--- /dev/null
+++ b/src/test/baseline/testTimeSliderVert3.png
Binary files differ
diff --git a/src/test/baseline/testTimeSliderVert4.png b/src/test/baseline/testTimeSliderVert4.png
new file mode 100644
index 0000000..f64996b
--- /dev/null
+++ b/src/test/baseline/testTimeSliderVert4.png
Binary files differ
diff --git a/src/test/baseline/testTimeSliderVert5.png b/src/test/baseline/testTimeSliderVert5.png
new file mode 100644
index 0000000..f64996b
--- /dev/null
+++ b/src/test/baseline/testTimeSliderVert5.png
Binary files differ
diff --git a/src/test/baseline/testUIButtonDisabled.png b/src/test/baseline/testUIButtonDisabled.png
new file mode 100644
index 0000000..9e00094
--- /dev/null
+++ b/src/test/baseline/testUIButtonDisabled.png
Binary files differ
diff --git a/src/test/baseline/testUIButtonDown.png b/src/test/baseline/testUIButtonDown.png
new file mode 100644
index 0000000..c9e3369
--- /dev/null
+++ b/src/test/baseline/testUIButtonDown.png
Binary files differ
diff --git a/src/test/baseline/testUIButtonUp.png b/src/test/baseline/testUIButtonUp.png
new file mode 100644
index 0000000..f385f38
--- /dev/null
+++ b/src/test/baseline/testUIButtonUp.png
Binary files differ
diff --git a/src/test/baseline/testUICheckBoxChecked_Down.png b/src/test/baseline/testUICheckBoxChecked_Down.png
new file mode 100644
index 0000000..73818b9
--- /dev/null
+++ b/src/test/baseline/testUICheckBoxChecked_Down.png
Binary files differ
diff --git a/src/test/baseline/testUICheckBoxChecked_Up.png b/src/test/baseline/testUICheckBoxChecked_Up.png
new file mode 100644
index 0000000..a4af8c9
--- /dev/null
+++ b/src/test/baseline/testUICheckBoxChecked_Up.png
Binary files differ
diff --git a/src/test/baseline/testUICheckBoxUnchecked_Disabled.png b/src/test/baseline/testUICheckBoxUnchecked_Disabled.png
new file mode 100644
index 0000000..ebcb3ef
--- /dev/null
+++ b/src/test/baseline/testUICheckBoxUnchecked_Disabled.png
Binary files differ
diff --git a/src/test/baseline/testUICheckBoxUnchecked_Down.png b/src/test/baseline/testUICheckBoxUnchecked_Down.png
new file mode 100644
index 0000000..4967f44
--- /dev/null
+++ b/src/test/baseline/testUICheckBoxUnchecked_Down.png
Binary files differ
diff --git a/src/test/baseline/testUICheckBoxUnchecked_Up.png b/src/test/baseline/testUICheckBoxUnchecked_Up.png
new file mode 100644
index 0000000..1c102e7
--- /dev/null
+++ b/src/test/baseline/testUICheckBoxUnchecked_Up.png
Binary files differ
diff --git a/src/test/baseline/testUIKeyboard.png b/src/test/baseline/testUIKeyboard.png
new file mode 100644
index 0000000..87d23a2
--- /dev/null
+++ b/src/test/baseline/testUIKeyboard.png
Binary files differ
diff --git a/src/test/baseline/testUIKeyboard1S.png b/src/test/baseline/testUIKeyboard1S.png
new file mode 100644
index 0000000..d7f0606
--- /dev/null
+++ b/src/test/baseline/testUIKeyboard1S.png
Binary files differ
diff --git a/src/test/baseline/testUIKeyboardA.png b/src/test/baseline/testUIKeyboardA.png
new file mode 100644
index 0000000..0012b33
--- /dev/null
+++ b/src/test/baseline/testUIKeyboardA.png
Binary files differ
diff --git a/src/test/baseline/testUIKeyboardA1S.png b/src/test/baseline/testUIKeyboardA1S.png
new file mode 100644
index 0000000..f2ccd3a
--- /dev/null
+++ b/src/test/baseline/testUIKeyboardA1S.png
Binary files differ
diff --git a/src/test/baseline/testUIKeyboardAS.png b/src/test/baseline/testUIKeyboardAS.png
new file mode 100644
index 0000000..cd76aad
--- /dev/null
+++ b/src/test/baseline/testUIKeyboardAS.png
Binary files differ
diff --git a/src/test/baseline/testUIKeyboardDown11.png b/src/test/baseline/testUIKeyboardDown11.png
new file mode 100644
index 0000000..bfc8a50
--- /dev/null
+++ b/src/test/baseline/testUIKeyboardDown11.png
Binary files differ
diff --git a/src/test/baseline/testUIKeyboardDownA212S2.png b/src/test/baseline/testUIKeyboardDownA212S2.png
new file mode 100644
index 0000000..cd79feb
--- /dev/null
+++ b/src/test/baseline/testUIKeyboardDownA212S2.png
Binary files differ
diff --git a/src/test/baseline/testUIKeyboardDownA2S1.png b/src/test/baseline/testUIKeyboardDownA2S1.png
new file mode 100644
index 0000000..6c07214
--- /dev/null
+++ b/src/test/baseline/testUIKeyboardDownA2S1.png
Binary files differ
diff --git a/src/test/baseline/testUIKeyboardFB.png b/src/test/baseline/testUIKeyboardFB.png
new file mode 100644
index 0000000..f4836a1
--- /dev/null
+++ b/src/test/baseline/testUIKeyboardFB.png
Binary files differ
diff --git a/src/test/baseline/testUIKeyboardFB1.png b/src/test/baseline/testUIKeyboardFB1.png
new file mode 100644
index 0000000..13a56aa
--- /dev/null
+++ b/src/test/baseline/testUIKeyboardFB1.png
Binary files differ
diff --git a/src/test/baseline/testUIKeyboardFBA1S.png b/src/test/baseline/testUIKeyboardFBA1S.png
new file mode 100644
index 0000000..e9e5534
--- /dev/null
+++ b/src/test/baseline/testUIKeyboardFBA1S.png
Binary files differ
diff --git a/src/test/baseline/testUIKeyboardFBAS.png b/src/test/baseline/testUIKeyboardFBAS.png
new file mode 100644
index 0000000..0e10aaf
--- /dev/null
+++ b/src/test/baseline/testUIKeyboardFBAS.png
Binary files differ
diff --git a/src/test/baseline/testUIKeyboardFBS.png b/src/test/baseline/testUIKeyboardFBS.png
new file mode 100644
index 0000000..9e0964a
--- /dev/null
+++ b/src/test/baseline/testUIKeyboardFBS.png
Binary files differ
diff --git a/src/test/baseline/testUIKeyboardNoFB1S.png b/src/test/baseline/testUIKeyboardNoFB1S.png
new file mode 100644
index 0000000..4c91d91
--- /dev/null
+++ b/src/test/baseline/testUIKeyboardNoFB1S.png
Binary files differ
diff --git a/src/test/baseline/testUIKeyboardS.png b/src/test/baseline/testUIKeyboardS.png
new file mode 100644
index 0000000..12a6c9f
--- /dev/null
+++ b/src/test/baseline/testUIKeyboardS.png
Binary files differ
diff --git a/src/test/baseline/testUIToggleChecked_Disabled.png b/src/test/baseline/testUIToggleChecked_Disabled.png
new file mode 100644
index 0000000..6a23dda
--- /dev/null
+++ b/src/test/baseline/testUIToggleChecked_Disabled.png
Binary files differ
diff --git a/src/test/baseline/testUIToggleChecked_Down.png b/src/test/baseline/testUIToggleChecked_Down.png
new file mode 100644
index 0000000..a17041f
--- /dev/null
+++ b/src/test/baseline/testUIToggleChecked_Down.png
Binary files differ
diff --git a/src/test/baseline/testUIToggleChecked_Up.png b/src/test/baseline/testUIToggleChecked_Up.png
new file mode 100644
index 0000000..03f2f41
--- /dev/null
+++ b/src/test/baseline/testUIToggleChecked_Up.png
Binary files differ
diff --git a/src/test/baseline/testUIToggleUnchecked_Disabled.png b/src/test/baseline/testUIToggleUnchecked_Disabled.png
new file mode 100644
index 0000000..8fccaa6
--- /dev/null
+++ b/src/test/baseline/testUIToggleUnchecked_Disabled.png
Binary files differ
diff --git a/src/test/baseline/testUIToggleUnchecked_Down.png b/src/test/baseline/testUIToggleUnchecked_Down.png
new file mode 100644
index 0000000..bbad224
--- /dev/null
+++ b/src/test/baseline/testUIToggleUnchecked_Down.png
Binary files differ
diff --git a/src/test/baseline/testUIToggleUnchecked_Up.png b/src/test/baseline/testUIToggleUnchecked_Up.png
new file mode 100644
index 0000000..a6f08f0
--- /dev/null
+++ b/src/test/baseline/testUIToggleUnchecked_Up.png
Binary files differ
diff --git a/src/test/baseline/testVideo-h264-48x48.h2641.png b/src/test/baseline/testVideo-h264-48x48.h2641.png
new file mode 100644
index 0000000..5adc733
--- /dev/null
+++ b/src/test/baseline/testVideo-h264-48x48.h2641.png
Binary files differ
diff --git a/src/test/baseline/testVideo-mjpeg-48x48.avi1.png b/src/test/baseline/testVideo-mjpeg-48x48.avi1.png
new file mode 100644
index 0000000..a16beec
--- /dev/null
+++ b/src/test/baseline/testVideo-mjpeg-48x48.avi1.png
Binary files differ
diff --git a/src/test/baseline/testVideo-mpeg1-48x48-sound.avi1.png b/src/test/baseline/testVideo-mpeg1-48x48-sound.avi1.png
new file mode 100644
index 0000000..043fa46
--- /dev/null
+++ b/src/test/baseline/testVideo-mpeg1-48x48-sound.avi1.png
Binary files differ
diff --git a/src/test/baseline/testVideo-mpeg1-48x48.mov1.png b/src/test/baseline/testVideo-mpeg1-48x48.mov1.png
new file mode 100644
index 0000000..ad9dcf8
--- /dev/null
+++ b/src/test/baseline/testVideo-mpeg1-48x48.mov1.png
Binary files differ
diff --git a/src/test/baseline/testVideo-rgba-48x48.mov1.png b/src/test/baseline/testVideo-rgba-48x48.mov1.png
new file mode 100644
index 0000000..700b042
--- /dev/null
+++ b/src/test/baseline/testVideo-rgba-48x48.mov1.png
Binary files differ
diff --git a/src/test/baseline/testVideo-vp6a-yuva-48x48.flv1.png b/src/test/baseline/testVideo-vp6a-yuva-48x48.flv1.png
new file mode 100644
index 0000000..970e6a4
--- /dev/null
+++ b/src/test/baseline/testVideo-vp6a-yuva-48x48.flv1.png
Binary files differ
diff --git a/src/test/baseline/testVideoActive1.png b/src/test/baseline/testVideoActive1.png
new file mode 100644
index 0000000..174636b
--- /dev/null
+++ b/src/test/baseline/testVideoActive1.png
Binary files differ
diff --git a/src/test/baseline/testVideoActive2.png b/src/test/baseline/testVideoActive2.png
new file mode 100644
index 0000000..0f1b555
--- /dev/null
+++ b/src/test/baseline/testVideoActive2.png
Binary files differ
diff --git a/src/test/baseline/testVideoDynamics1.png b/src/test/baseline/testVideoDynamics1.png
new file mode 100644
index 0000000..3eca9a4
--- /dev/null
+++ b/src/test/baseline/testVideoDynamics1.png
Binary files differ
diff --git a/src/test/baseline/testVideoDynamics2.png b/src/test/baseline/testVideoDynamics2.png
new file mode 100644
index 0000000..8e8716c
--- /dev/null
+++ b/src/test/baseline/testVideoDynamics2.png
Binary files differ
diff --git a/src/test/baseline/testVideoDynamics3.png b/src/test/baseline/testVideoDynamics3.png
new file mode 100644
index 0000000..90bde83
--- /dev/null
+++ b/src/test/baseline/testVideoDynamics3.png
Binary files differ
diff --git a/src/test/baseline/testVideoDynamics4.png b/src/test/baseline/testVideoDynamics4.png
new file mode 100644
index 0000000..174636b
--- /dev/null
+++ b/src/test/baseline/testVideoDynamics4.png
Binary files differ
diff --git a/src/test/baseline/testVideoDynamics5.png b/src/test/baseline/testVideoDynamics5.png
new file mode 100644
index 0000000..3eca9a4
--- /dev/null
+++ b/src/test/baseline/testVideoDynamics5.png
Binary files differ
diff --git a/src/test/baseline/testVideoFPS.png b/src/test/baseline/testVideoFPS.png
new file mode 100644
index 0000000..70e60fd
--- /dev/null
+++ b/src/test/baseline/testVideoFPS.png
Binary files differ
diff --git a/src/test/baseline/testVideoHRef1.png b/src/test/baseline/testVideoHRef1.png
new file mode 100644
index 0000000..c463313
--- /dev/null
+++ b/src/test/baseline/testVideoHRef1.png
Binary files differ
diff --git a/src/test/baseline/testVideoLoop.png b/src/test/baseline/testVideoLoop.png
new file mode 100644
index 0000000..ad9dcf8
--- /dev/null
+++ b/src/test/baseline/testVideoLoop.png
Binary files differ
diff --git a/src/test/baseline/testVideoMaskRGBA1.png b/src/test/baseline/testVideoMaskRGBA1.png
new file mode 100644
index 0000000..2ddf341
--- /dev/null
+++ b/src/test/baseline/testVideoMaskRGBA1.png
Binary files differ
diff --git a/src/test/baseline/testVideoMaskRGBA2.png b/src/test/baseline/testVideoMaskRGBA2.png
new file mode 100644
index 0000000..12fccc3
--- /dev/null
+++ b/src/test/baseline/testVideoMaskRGBA2.png
Binary files differ
diff --git a/src/test/baseline/testVideoMaskRGBA3.png b/src/test/baseline/testVideoMaskRGBA3.png
new file mode 100644
index 0000000..9241d08
--- /dev/null
+++ b/src/test/baseline/testVideoMaskRGBA3.png
Binary files differ
diff --git a/src/test/baseline/testVideoMaskRGBA4.png b/src/test/baseline/testVideoMaskRGBA4.png
new file mode 100644
index 0000000..2b00886
--- /dev/null
+++ b/src/test/baseline/testVideoMaskRGBA4.png
Binary files differ
diff --git a/src/test/baseline/testVideoMaskYUV1.png b/src/test/baseline/testVideoMaskYUV1.png
new file mode 100644
index 0000000..9b3cb7b
--- /dev/null
+++ b/src/test/baseline/testVideoMaskYUV1.png
Binary files differ
diff --git a/src/test/baseline/testVideoMaskYUV2.png b/src/test/baseline/testVideoMaskYUV2.png
new file mode 100644
index 0000000..978f3a6
--- /dev/null
+++ b/src/test/baseline/testVideoMaskYUV2.png
Binary files differ
diff --git a/src/test/baseline/testVideoMaskYUV3.png b/src/test/baseline/testVideoMaskYUV3.png
new file mode 100644
index 0000000..238edc4
--- /dev/null
+++ b/src/test/baseline/testVideoMaskYUV3.png
Binary files differ
diff --git a/src/test/baseline/testVideoMaskYUV4.png b/src/test/baseline/testVideoMaskYUV4.png
new file mode 100644
index 0000000..e4379a3
--- /dev/null
+++ b/src/test/baseline/testVideoMaskYUV4.png
Binary files differ
diff --git a/src/test/baseline/testVideoMaskYUVJ1.png b/src/test/baseline/testVideoMaskYUVJ1.png
new file mode 100644
index 0000000..ccb7e0d
--- /dev/null
+++ b/src/test/baseline/testVideoMaskYUVJ1.png
Binary files differ
diff --git a/src/test/baseline/testVideoMaskYUVJ2.png b/src/test/baseline/testVideoMaskYUVJ2.png
new file mode 100644
index 0000000..bfbd99c
--- /dev/null
+++ b/src/test/baseline/testVideoMaskYUVJ2.png
Binary files differ
diff --git a/src/test/baseline/testVideoMaskYUVJ3.png b/src/test/baseline/testVideoMaskYUVJ3.png
new file mode 100644
index 0000000..bf95a39
--- /dev/null
+++ b/src/test/baseline/testVideoMaskYUVJ3.png
Binary files differ
diff --git a/src/test/baseline/testVideoMaskYUVJ4.png b/src/test/baseline/testVideoMaskYUVJ4.png
new file mode 100644
index 0000000..b0f6e66
--- /dev/null
+++ b/src/test/baseline/testVideoMaskYUVJ4.png
Binary files differ
diff --git a/src/test/baseline/testVideoNullFX.png b/src/test/baseline/testVideoNullFX.png
new file mode 100644
index 0000000..9c1a999
--- /dev/null
+++ b/src/test/baseline/testVideoNullFX.png
Binary files differ
diff --git a/src/test/baseline/testVideoOpacityRGBA1.png b/src/test/baseline/testVideoOpacityRGBA1.png
new file mode 100644
index 0000000..e98478f
--- /dev/null
+++ b/src/test/baseline/testVideoOpacityRGBA1.png
Binary files differ
diff --git a/src/test/baseline/testVideoOpacityRGBA2.png b/src/test/baseline/testVideoOpacityRGBA2.png
new file mode 100644
index 0000000..00cf166
--- /dev/null
+++ b/src/test/baseline/testVideoOpacityRGBA2.png
Binary files differ
diff --git a/src/test/baseline/testVideoOpacityYUV1.png b/src/test/baseline/testVideoOpacityYUV1.png
new file mode 100644
index 0000000..d27fda0
--- /dev/null
+++ b/src/test/baseline/testVideoOpacityYUV1.png
Binary files differ
diff --git a/src/test/baseline/testVideoOpacityYUV2.png b/src/test/baseline/testVideoOpacityYUV2.png
new file mode 100644
index 0000000..152df47
--- /dev/null
+++ b/src/test/baseline/testVideoOpacityYUV2.png
Binary files differ
diff --git a/src/test/baseline/testVideoSeek0.png b/src/test/baseline/testVideoSeek0.png
new file mode 100644
index 0000000..e0046ba
--- /dev/null
+++ b/src/test/baseline/testVideoSeek0.png
Binary files differ
diff --git a/src/test/baseline/testVideoSeek1.png b/src/test/baseline/testVideoSeek1.png
new file mode 100644
index 0000000..6f658da
--- /dev/null
+++ b/src/test/baseline/testVideoSeek1.png
Binary files differ
diff --git a/src/test/baseline/testVideoSeek2.png b/src/test/baseline/testVideoSeek2.png
new file mode 100644
index 0000000..6a48ed4
--- /dev/null
+++ b/src/test/baseline/testVideoSeek2.png
Binary files differ
diff --git a/src/test/baseline/testVideoSeek3.png b/src/test/baseline/testVideoSeek3.png
new file mode 100644
index 0000000..c436802
--- /dev/null
+++ b/src/test/baseline/testVideoSeek3.png
Binary files differ
diff --git a/src/test/baseline/testVideoState1.png b/src/test/baseline/testVideoState1.png
new file mode 100644
index 0000000..ad9dcf8
--- /dev/null
+++ b/src/test/baseline/testVideoState1.png
Binary files differ
diff --git a/src/test/baseline/testVideoState2.png b/src/test/baseline/testVideoState2.png
new file mode 100644
index 0000000..fed9567
--- /dev/null
+++ b/src/test/baseline/testVideoState2.png
Binary files differ
diff --git a/src/test/baseline/testVideoState3.png b/src/test/baseline/testVideoState3.png
new file mode 100644
index 0000000..b7bc073
--- /dev/null
+++ b/src/test/baseline/testVideoState3.png
Binary files differ
diff --git a/src/test/baseline/testVideoState4.png b/src/test/baseline/testVideoState4.png
new file mode 100644
index 0000000..174636b
--- /dev/null
+++ b/src/test/baseline/testVideoState4.png
Binary files differ
diff --git a/src/test/baseline/testVideoState5.png b/src/test/baseline/testVideoState5.png
new file mode 100644
index 0000000..ad9dcf8
--- /dev/null
+++ b/src/test/baseline/testVideoState5.png
Binary files differ
diff --git a/src/test/baseline/testVideoWriter1.png b/src/test/baseline/testVideoWriter1.png
new file mode 100644
index 0000000..6a9f728
--- /dev/null
+++ b/src/test/baseline/testVideoWriter1.png
Binary files differ
diff --git a/src/test/baseline/testVideoWriterCanvas1.png b/src/test/baseline/testVideoWriterCanvas1.png
new file mode 100644
index 0000000..b319da2
--- /dev/null
+++ b/src/test/baseline/testVideoWriterCanvas1.png
Binary files differ
diff --git a/src/test/baseline/testWarp1.png b/src/test/baseline/testWarp1.png
new file mode 100644
index 0000000..99ddc2f
--- /dev/null
+++ b/src/test/baseline/testWarp1.png
Binary files differ
diff --git a/src/test/baseline/testWarp2.png b/src/test/baseline/testWarp2.png
new file mode 100644
index 0000000..0dca03a
--- /dev/null
+++ b/src/test/baseline/testWarp2.png
Binary files differ
diff --git a/src/test/baseline/testWarp3.png b/src/test/baseline/testWarp3.png
new file mode 100644
index 0000000..357a1b3
--- /dev/null
+++ b/src/test/baseline/testWarp3.png
Binary files differ
diff --git a/src/test/baseline/testWordsBR.png b/src/test/baseline/testWordsBR.png
new file mode 100644
index 0000000..82df070
--- /dev/null
+++ b/src/test/baseline/testWordsBR.png
Binary files differ
diff --git a/src/test/baseline/testWordsDynamics1.png b/src/test/baseline/testWordsDynamics1.png
new file mode 100644
index 0000000..c68081b
--- /dev/null
+++ b/src/test/baseline/testWordsDynamics1.png
Binary files differ
diff --git a/src/test/baseline/testWordsDynamics2.png b/src/test/baseline/testWordsDynamics2.png
new file mode 100644
index 0000000..ff6c80f
--- /dev/null
+++ b/src/test/baseline/testWordsDynamics2.png
Binary files differ
diff --git a/src/test/baseline/testWordsDynamics3.png b/src/test/baseline/testWordsDynamics3.png
new file mode 100644
index 0000000..ff6c80f
--- /dev/null
+++ b/src/test/baseline/testWordsDynamics3.png
Binary files differ
diff --git a/src/test/baseline/testWordsDynamics4.png b/src/test/baseline/testWordsDynamics4.png
new file mode 100644
index 0000000..174636b
--- /dev/null
+++ b/src/test/baseline/testWordsDynamics4.png
Binary files differ
diff --git a/src/test/baseline/testWordsDynamics5.png b/src/test/baseline/testWordsDynamics5.png
new file mode 100644
index 0000000..c68081b
--- /dev/null
+++ b/src/test/baseline/testWordsDynamics5.png
Binary files differ
diff --git a/src/test/baseline/testWordsGamma1.png b/src/test/baseline/testWordsGamma1.png
new file mode 100644
index 0000000..9586c80
--- /dev/null
+++ b/src/test/baseline/testWordsGamma1.png
Binary files differ
diff --git a/src/test/baseline/testWordsGamma2.png b/src/test/baseline/testWordsGamma2.png
new file mode 100644
index 0000000..f5c2367
--- /dev/null
+++ b/src/test/baseline/testWordsGamma2.png
Binary files differ
diff --git a/src/test/baseline/testWordsIntensity.png b/src/test/baseline/testWordsIntensity.png
new file mode 100644
index 0000000..c49904e
--- /dev/null
+++ b/src/test/baseline/testWordsIntensity.png
Binary files differ
diff --git a/src/test/baseline/testWordsMask1.png b/src/test/baseline/testWordsMask1.png
new file mode 100644
index 0000000..10affb2
--- /dev/null
+++ b/src/test/baseline/testWordsMask1.png
Binary files differ
diff --git a/src/test/baseline/testWordsMask2.png b/src/test/baseline/testWordsMask2.png
new file mode 100644
index 0000000..093b6a3
--- /dev/null
+++ b/src/test/baseline/testWordsMask2.png
Binary files differ
diff --git a/src/test/baseline/testWordsMask3.png b/src/test/baseline/testWordsMask3.png
new file mode 100644
index 0000000..2a6e464
--- /dev/null
+++ b/src/test/baseline/testWordsMask3.png
Binary files differ
diff --git a/src/test/baseline/testWordsMask4.png b/src/test/baseline/testWordsMask4.png
new file mode 100644
index 0000000..a65df77
--- /dev/null
+++ b/src/test/baseline/testWordsMask4.png
Binary files differ
diff --git a/src/test/baseline/testWordsMask5.png b/src/test/baseline/testWordsMask5.png
new file mode 100644
index 0000000..3df07d1
--- /dev/null
+++ b/src/test/baseline/testWordsMask5.png
Binary files differ
diff --git a/src/test/baseline/testWordsMask6.png b/src/test/baseline/testWordsMask6.png
new file mode 100644
index 0000000..7c592c6
--- /dev/null
+++ b/src/test/baseline/testWordsMask6.png
Binary files differ
diff --git a/src/test/baseline/testWordsMask7.png b/src/test/baseline/testWordsMask7.png
new file mode 100644
index 0000000..6be97bc
--- /dev/null
+++ b/src/test/baseline/testWordsMask7.png
Binary files differ
diff --git a/src/test/baseline/testWordsNullFX.png b/src/test/baseline/testWordsNullFX.png
new file mode 100644
index 0000000..3197c3d
--- /dev/null
+++ b/src/test/baseline/testWordsNullFX.png
Binary files differ
diff --git a/src/test/baseline/testWordsOutlines.png b/src/test/baseline/testWordsOutlines.png
new file mode 100644
index 0000000..6187147
--- /dev/null
+++ b/src/test/baseline/testWordsOutlines.png
Binary files differ
diff --git a/src/test/baseline/testWordsShadowFX1.png b/src/test/baseline/testWordsShadowFX1.png
new file mode 100644
index 0000000..bd50822
--- /dev/null
+++ b/src/test/baseline/testWordsShadowFX1.png
Binary files differ
diff --git a/src/test/baseline/testWordsShadowFX2.png b/src/test/baseline/testWordsShadowFX2.png
new file mode 100644
index 0000000..84b503c
--- /dev/null
+++ b/src/test/baseline/testWordsShadowFX2.png
Binary files differ
diff --git a/src/test/baseline/testWrapMode1.png b/src/test/baseline/testWrapMode1.png
new file mode 100644
index 0000000..cff05d0
--- /dev/null
+++ b/src/test/baseline/testWrapMode1.png
Binary files differ
diff --git a/src/test/baseline/testWrapMode2.png b/src/test/baseline/testWrapMode2.png
new file mode 100644
index 0000000..596cdb6
--- /dev/null
+++ b/src/test/baseline/testWrapMode2.png
Binary files differ
diff --git a/src/test/baseline/testWrapMode3.png b/src/test/baseline/testWrapMode3.png
new file mode 100644
index 0000000..cff05d0
--- /dev/null
+++ b/src/test/baseline/testWrapMode3.png
Binary files differ
diff --git a/src/test/baseline/testWrapMode4.png b/src/test/baseline/testWrapMode4.png
new file mode 100644
index 0000000..6d17b93
--- /dev/null
+++ b/src/test/baseline/testWrapMode4.png
Binary files differ
diff --git a/src/test/baseline/testXPosPointAnim1.png b/src/test/baseline/testXPosPointAnim1.png
new file mode 100644
index 0000000..ce2f589
--- /dev/null
+++ b/src/test/baseline/testXPosPointAnim1.png
Binary files differ
diff --git a/src/test/baseline/testXPosPointAnim2.png b/src/test/baseline/testXPosPointAnim2.png
new file mode 100644
index 0000000..84eca4f
--- /dev/null
+++ b/src/test/baseline/testXPosPointAnim2.png
Binary files differ
diff --git a/src/test/baseline/testXPosPointAnim3.png b/src/test/baseline/testXPosPointAnim3.png
new file mode 100644
index 0000000..84eca4f
--- /dev/null
+++ b/src/test/baseline/testXPosPointAnim3.png
Binary files differ
diff --git a/src/test/baseline/testYPosPointAnim1.png b/src/test/baseline/testYPosPointAnim1.png
new file mode 100644
index 0000000..ce2f589
--- /dev/null
+++ b/src/test/baseline/testYPosPointAnim1.png
Binary files differ
diff --git a/src/test/baseline/testYPosPointAnim2.png b/src/test/baseline/testYPosPointAnim2.png
new file mode 100644
index 0000000..39d093e
--- /dev/null
+++ b/src/test/baseline/testYPosPointAnim2.png
Binary files differ
diff --git a/src/test/baseline/testYPosPointAnim3.png b/src/test/baseline/testYPosPointAnim3.png
new file mode 100644
index 0000000..39d093e
--- /dev/null
+++ b/src/test/baseline/testYPosPointAnim3.png
Binary files differ
diff --git a/src/test/baseline/testbasics.png b/src/test/baseline/testbasics.png
new file mode 100644
index 0000000..4c1afa7
--- /dev/null
+++ b/src/test/baseline/testbasics.png
Binary files differ
diff --git a/src/test/baseline/testline1.png b/src/test/baseline/testline1.png
new file mode 100644
index 0000000..b499abd
--- /dev/null
+++ b/src/test/baseline/testline1.png
Binary files differ
diff --git a/src/test/baseline/testline2.png b/src/test/baseline/testline2.png
new file mode 100644
index 0000000..c307bd7
--- /dev/null
+++ b/src/test/baseline/testline2.png
Binary files differ
diff --git a/src/test/baseline/testline3.png b/src/test/baseline/testline3.png
new file mode 100644
index 0000000..c1a7795
--- /dev/null
+++ b/src/test/baseline/testline3.png
Binary files differ
diff --git a/src/test/baseline/testline4.png b/src/test/baseline/testline4.png
new file mode 100644
index 0000000..b086840
--- /dev/null
+++ b/src/test/baseline/testline4.png
Binary files differ
diff --git a/src/test/baseline/testlineopacity1.png b/src/test/baseline/testlineopacity1.png
new file mode 100644
index 0000000..0c11d1c
--- /dev/null
+++ b/src/test/baseline/testlineopacity1.png
Binary files differ
diff --git a/src/test/baseline/testlineopacity2.png b/src/test/baseline/testlineopacity2.png
new file mode 100644
index 0000000..ee9b3e7
--- /dev/null
+++ b/src/test/baseline/testlineopacity2.png
Binary files differ
diff --git a/src/test/baseline/testlotsoflines.png b/src/test/baseline/testlotsoflines.png
new file mode 100644
index 0000000..485d9c5
--- /dev/null
+++ b/src/test/baseline/testlotsoflines.png
Binary files differ
diff --git a/src/test/baseline/testplugin1.png b/src/test/baseline/testplugin1.png
new file mode 100644
index 0000000..fd07f6c
--- /dev/null
+++ b/src/test/baseline/testplugin1.png
Binary files differ
diff --git a/src/test/baseline/testplugin2.png b/src/test/baseline/testplugin2.png
new file mode 100644
index 0000000..2ec2e11
--- /dev/null
+++ b/src/test/baseline/testplugin2.png
Binary files differ
diff --git a/src/test/baseline/testtexturedline1.png b/src/test/baseline/testtexturedline1.png
new file mode 100644
index 0000000..d4b3719
--- /dev/null
+++ b/src/test/baseline/testtexturedline1.png
Binary files differ
diff --git a/src/test/baseline/testtexturedline2.png b/src/test/baseline/testtexturedline2.png
new file mode 100644
index 0000000..174636b
--- /dev/null
+++ b/src/test/baseline/testtexturedline2.png
Binary files differ
diff --git a/src/test/baseline/testtexturedline3.png b/src/test/baseline/testtexturedline3.png
new file mode 100644
index 0000000..7ac3757
--- /dev/null
+++ b/src/test/baseline/testtexturedline3.png
Binary files differ
diff --git a/src/test/baseline/testtexturedline4.png b/src/test/baseline/testtexturedline4.png
new file mode 100644
index 0000000..07b7750
--- /dev/null
+++ b/src/test/baseline/testtexturedline4.png
Binary files differ
diff --git a/src/test/baseline/testtexturedline5.png b/src/test/baseline/testtexturedline5.png
new file mode 100644
index 0000000..7ffeed2
--- /dev/null
+++ b/src/test/baseline/testtexturedline5.png
Binary files differ
diff --git a/src/test/camcfgs.py b/src/test/camcfgs.py
new file mode 100644
index 0000000..5c65229
--- /dev/null
+++ b/src/test/camcfgs.py
@@ -0,0 +1,133 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# libavg - Media Playback Engine.
+# Copyright (C) 2003-2014 Ulrich von Zadow
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Current versions can be found at www.libavg.de
+#
+
+class CameraTestCfg:
+ def __init__(self, driver, device, unit, fw800, formats, illegalFormat, paramTests,
+ defaultParams):
+ self.driver = driver
+ self.device = device
+ self.unit = unit
+ self.fw800 = fw800
+
+ self.formats = formats
+ self.illegalFormat = illegalFormat
+ self.paramTests = paramTests
+ self.defaultParams = defaultParams
+
+class CameraFormatCfg:
+ def __init__(self, size, pixelformat, framerate):
+ self.size = size
+ self.pixelformat = pixelformat
+ self.framerate = framerate
+
+class ParamTestCfg:
+ def __init__(self, name, testValues, minMedDiff, medMaxDiff):
+ self.name = name
+ self.testValues = testValues
+ self.minMedDiff = minMedDiff
+ self.medMaxDiff = medMaxDiff
+
+DFx31BF03Cfg = CameraTestCfg('firewire', '', -1, False,
+ [CameraFormatCfg((1024,768), 'BAYER8', 30),
+ CameraFormatCfg((1024,768), 'I8', 30),
+ CameraFormatCfg((1024,768), 'YUV422', 15),
+ CameraFormatCfg((1024,768), 'YUV422', 7.5)],
+ CameraFormatCfg((320,240), 'BAYER8', 30),
+ [ParamTestCfg('gain', (180, 800, 1023), 6, 6),
+ ParamTestCfg('camgamma', (10, 16, 22), 15, 15),
+ ParamTestCfg('brightness', (0, 127, 254), 8, 8)],
+ {'gain':300, 'shutter':220, 'saturation':1200, 'camgamma':16,
+ 'brightness':120, 'setWhitebalance':[450, 450]}
+ )
+
+FireflyMV = CameraTestCfg('firewire', '', -1, False,
+ [CameraFormatCfg((640, 480), 'I8', 7.5),
+ CameraFormatCfg((640, 480), 'I8', 15),
+ CameraFormatCfg((640, 480), 'I8', 60),
+ CameraFormatCfg((640, 480), 'I16', 7.5),
+ CameraFormatCfg((640, 480), 'I16', 15),
+ CameraFormatCfg((640, 480), 'I16', 30)],
+ CameraFormatCfg((640, 480), 'I8', 30),
+ [ParamTestCfg('gain', (16, 30, 64), 15, 15),
+ ParamTestCfg('shutter', (1, 150, 531), 50, 20),
+ ParamTestCfg('brightness', (1, 130, 255), 10, 10)],
+ {'gain':16, 'shutter':100, 'brightness':130}
+ )
+
+Dragonfly2 = CameraTestCfg('firewire', '', -1, False,
+ [CameraFormatCfg((640,480), 'RGB', 30),
+ CameraFormatCfg((1024,768), 'I8', 15),
+ CameraFormatCfg((1024,768), 'I16', 15),
+ CameraFormatCfg((1024,768), 'BAYER8', 30),
+ CameraFormatCfg((1024,768), 'YUV422', 7.5)],
+ CameraFormatCfg((123,456), 'RGB', 30),
+ [ParamTestCfg('gain', (0, 346, 683), 10, 30),
+ ParamTestCfg('camgamma', (0, 1278, 4095), 30, 50),
+ ParamTestCfg('brightness', (0, 127, 254), 8, 8)],
+ {'gain':300, 'shutter':220, 'saturation':1200, 'camgamma':1200,
+ 'brightness':120, 'setWhitebalance':[450, 450]}
+ )
+
+Firei = CameraTestCfg('firewire', '', -1, False,
+ [CameraFormatCfg((640,480), 'YUV411', 30),
+ CameraFormatCfg((640,480), 'RGB', 15),
+ CameraFormatCfg((640,480), 'YUV422', 15),
+ CameraFormatCfg((640,480), 'I8', 30),
+ CameraFormatCfg((320,240), 'YUV422', 7.5)],
+ CameraFormatCfg((123,456), 'RGB', 30),
+ #To check: there is something strange with shutter and gain in this camera.
+ [ParamTestCfg('gain', (1, 100, 255), 10, 30),
+ ParamTestCfg('brightness', (128, 255, 383), 8, 8),
+ ParamTestCfg('shutter', (4, 4, 4), 8, 8)],
+ {'gain':87, 'shutter':6, 'brightness':304, 'setWhitebalance':[95, 87]}
+ )
+
+QuickCamProLinux = CameraTestCfg('video4linux', '', -1, False,
+ [CameraFormatCfg((352,288), 'YUYV422', 30),
+ CameraFormatCfg((320,240), 'YUYV422', 15),
+ CameraFormatCfg((176,144), 'YUYV422', 30),
+ CameraFormatCfg((640,480), 'YUYV422', 30)],
+ CameraFormatCfg((123,456), 'I16', 30),
+ [ParamTestCfg('brightness', (0, 127, 254), 40, 50)],
+ {'brightness':-1}
+ )
+
+QuickCamPro9Win = CameraTestCfg('directshow', '', -1, False,
+ [CameraFormatCfg((352,288), 'YUYV422', 30),
+ CameraFormatCfg((320,240), 'YUYV422', 15),
+ CameraFormatCfg((640,480), 'YUYV422', 30),
+ CameraFormatCfg((176,144), 'YUYV422', 30)],
+ CameraFormatCfg((123,456), 'RGB', 30),
+ [ParamTestCfg('brightness', (0, 127, 254), 40, 50)],
+ {'brightness': 60}
+ )
+
+QuickCamProBGRWin = CameraTestCfg('directshow', '', -1, False,
+ [CameraFormatCfg((352,288), 'BGR', 30),
+ CameraFormatCfg((320,240), 'BGR', 15),
+ CameraFormatCfg((640,480), 'BGR', 30),
+ CameraFormatCfg((176,144), 'BGR', 30)],
+ CameraFormatCfg((123,456), 'YUYV422', 30),
+ [ParamTestCfg('brightness', (0, 127, 254), 40, 50)],
+ {'brightness': 60}
+ )
+
diff --git a/src/test/checkcamera.py b/src/test/checkcamera.py
new file mode 100755
index 0000000..1146679
--- /dev/null
+++ b/src/test/checkcamera.py
@@ -0,0 +1,225 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# libavg - Media Playback Engine.
+# Copyright (C) 2003-2014 Ulrich von Zadow
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Current versions can be found at www.libavg.de
+#
+# Original author of this file is Robert Parcus <betoparcus@gmail.com>
+#
+
+from libavg import *
+import camcfgs
+import optparse
+
+from testcase import *
+
+def parseCmdLine():
+ global g_TestParams
+
+ validCameras = ('Dragonfly', 'FireflyMV', 'Firei', 'DFx31BF03', 'QuickCamProLinux',
+ 'QuickCamProBGRWin', 'QuickCamPro9Win')
+ parser = optparse.OptionParser(usage=
+"""%prog cameraname [option].
+A test to check camera features support by libavg. Supported cameras are """
++ str(validCameras))
+# parser.add_argument(dest='camera', action='store', type=str,
+# choices=validCameras, help = 'Select which camera model to test.')
+ parser.add_option('--test-params', '-p', dest='testParams', action='store_true',
+ default=False,
+ help='Execute optional tests for camera params like gain, shutter, etc.')
+ (options, args) = parser.parse_args()
+ g_TestParams = options.testParams
+ if len(args) != 1:
+ parser.error("Must be invoked with camera name as argument")
+ cameraName = args[0]
+ if cameraName == 'Dragonfly':
+ return camcfgs.Dragonfly2
+ elif cameraName == 'FireflyMV':
+ return camcfgs.FireflyMV
+ elif cameraName == 'Firei':
+ return camcfgs.Firei
+ elif cameraName == 'DFx31BF03':
+ return camcfgs.DFx31BF03Cfg
+ elif cameraName == 'QuickCamProLinux':
+ return camcfgs.QuickCamProLinux
+ elif cameraName == 'QuickCamPro9Win':
+ return camcfgs.QuickCamPro9Win
+ elif cameraName == 'QuickCamProBGRWin':
+ return camcfgs.QuickCamProBGRWin
+ else:
+ parser.error("Unknown camera name '" + cameraName + "'.")
+
+class CameraTestCase(AVGTestCase):
+ def __init__(self, cameraCfg, fmt, testFuncName, *testFuncArgs):
+ self.cameraCfg = cameraCfg
+ self.fmt = fmt
+ self.testFuncArgs = testFuncArgs
+ AVGTestCase.__init__(self, testFuncName)
+
+ def testFormat(self):
+ self.__dumpFormat()
+ self.loadEmptyScene()
+ self.__openCamera()
+ self.actions = [None, None]
+ avg.player.setOnFrameHandler(self.__onFrame)
+ avg.player.play()
+ self.assertEqual(self.cam.framenum, 2)
+ self.cam = None
+
+ def testIllegalFormat(self):
+ self.loadEmptyScene()
+ self.assertException(lambda: self.__openCamera())
+
+ def testCreateDelete(self):
+ # Create and delete without ever calling play.
+ self.__openCamera()
+ self.cam.unlink(True)
+
+ def testParams(self):
+ def buildParamActionList(testCfg):
+ actions = []
+ actions.append(setDefaultParams)
+ actions.append(None)
+ for val in testCfg.testValues:
+ actions.append(lambda paramName=testCfg.name, val=val:
+ setCamParam(paramName, val))
+ actions.append(None)
+ actions.append(None)
+ actions.append(None)
+ actions.append(lambda name=testCfg.name: calcCamImgAverage(name))
+ actions.append(lambda testCfg=testCfg: checkCamImageChange(testCfg))
+ return actions
+
+ def setDefaultParams():
+ for (paramName, val) in cameraCfg.defaultParams.iteritems():
+ if paramName == "setWhitebalance":
+ self.cam.setWhitebalance(*val)
+ else:
+ setattr(self.cam, paramName, val)
+
+ def setCamParam(paramName, val):
+ if paramName == 'setwhitebalance':
+ self.cam.setWhitebalance(*val)
+ else:
+ setattr(self.cam, paramName, val)
+
+ def calcCamImgAverage(param):
+ bmp = self.cam.getBitmap()
+ self.camBmps.append(bmp)
+ if isColorParam(param):
+ colour = []
+ colour.append(bmp.getChannelAvg(0))
+ colour.append(bmp.getChannelAvg(1))
+ colour.append(bmp.getChannelAvg(2))
+ self.averages.append(colour)
+ else:
+ self.averages.append(bmp.getAvg())
+
+ def checkCamImageChange(testCfg):
+
+ def saveCamImages():
+# print
+# print "Average image brightnesses: ",minAverages, medAverages, maxAverages
+ dir = AVGTestCase.getImageResultDir()
+ for (i, category) in enumerate(("min", "med", "max")):
+ self.camBmps[i].save(dir+"/cam"+testCfg.name+category+".png")
+
+ minAverages = self.averages[0]
+ medAverages = self.averages[1]
+ maxAverages = self.averages[2]
+ ok = False
+ if isColorParam(testCfg.name):
+ pass
+ else:
+ if minAverages+testCfg.minMedDiff > medAverages:
+ saveCamImages()
+ self.fail()
+ if medAverages+testCfg.medMaxDiff > maxAverages:
+ saveCamImages()
+ self.fail()
+ self.averages = []
+ self.camBmps = []
+
+ def isColorParam(paramName):
+ return paramName in ['saturation', 'setwhitebalance']
+
+ testCfg = self.testFuncArgs[0]
+ print >>sys.stderr, testCfg.name, " ",
+ self.loadEmptyScene()
+ self.__openCamera()
+ self.actions = buildParamActionList(testCfg)
+ avg.player.setOnFrameHandler(self.__onFrame)
+ self.averages = []
+ self.camBmps = []
+ avg.player.play()
+ self.cam = None
+
+ def __openCamera(self):
+ self.cam = avg.CameraNode(driver=self.cameraCfg.driver,
+ device=self.cameraCfg.device, unit=self.cameraCfg.unit,
+ fw800=self.cameraCfg.fw800, framerate=self.fmt.framerate,
+ capturewidth=self.fmt.size[0], captureheight=self.fmt.size[1],
+ pixelformat=self.fmt.pixelformat,
+ parent=avg.player.getRootNode())
+ self.cam.play()
+ self.lastCameraFrame = -1
+ self.assert_(self.cam.isAvailable())
+
+ def __onFrame(self):
+ # We execute one action per camera frame.
+# print self.cam.framenum
+ if self.cam.framenum != self.lastCameraFrame:
+ self.lastCameraFrame += 1
+ if len(self.actions) == self.lastCameraFrame:
+ avg.player.stop()
+ else:
+ action = self.actions[self.lastCameraFrame]
+ if action != None:
+ action()
+
+ def __dumpFormat(self):
+ print >>sys.stderr, str(self.fmt.size)+", "+str(self.fmt.pixelformat)+ \
+ ", "+str(self.fmt.framerate)+" ",
+
+def dumpCameraCfg(cfg):
+ print >>sys.stderr, "Camera config: driver="+cfg.driver+", device="+cfg.device+ \
+ ", unit="+str(cfg.unit)
+
+
+cameraCfg = parseCmdLine()
+AVGTestCase.cleanResultDir()
+suite = unittest.TestSuite()
+dumpCameraCfg(cameraCfg)
+for fmt in cameraCfg.formats:
+ suite.addTest(CameraTestCase(cameraCfg, fmt, "testFormat"))
+suite.addTest(CameraTestCase(cameraCfg, cameraCfg.illegalFormat, "testIllegalFormat"))
+suite.addTest(CameraTestCase(cameraCfg, cameraCfg.formats[0], "testCreateDelete"))
+if g_TestParams:
+ for testCfg in cameraCfg.paramTests:
+ suite.addTest(CameraTestCase(cameraCfg, cameraCfg.formats[0], "testParams",
+ testCfg))
+testRunner = unittest.TextTestRunner(verbosity = 2)
+testResult = testRunner.run(suite)
+
+if testResult.wasSuccessful():
+ exitCode = 0
+else:
+ exitCode = 1
+sys.exit(exitCode)
+
+
diff --git a/src/test/extrafonts/testaddfontdir.ttf b/src/test/extrafonts/testaddfontdir.ttf
new file mode 100644
index 0000000..d57eda6
--- /dev/null
+++ b/src/test/extrafonts/testaddfontdir.ttf
Binary files differ
diff --git a/src/test/fonts/Vera.ttf b/src/test/fonts/Vera.ttf
new file mode 100644
index 0000000..58cd6b5
--- /dev/null
+++ b/src/test/fonts/Vera.ttf
Binary files differ
diff --git a/src/test/fonts/VeraBI.ttf b/src/test/fonts/VeraBI.ttf
new file mode 100644
index 0000000..b55eee3
--- /dev/null
+++ b/src/test/fonts/VeraBI.ttf
Binary files differ
diff --git a/src/test/fonts/VeraBd.ttf b/src/test/fonts/VeraBd.ttf
new file mode 100644
index 0000000..51d6111
--- /dev/null
+++ b/src/test/fonts/VeraBd.ttf
Binary files differ
diff --git a/src/test/fonts/VeraIt.ttf b/src/test/fonts/VeraIt.ttf
new file mode 100644
index 0000000..cc23c9e
--- /dev/null
+++ b/src/test/fonts/VeraIt.ttf
Binary files differ
diff --git a/src/test/illustratorRect.svg b/src/test/illustratorRect.svg
new file mode 100644
index 0000000..37a4a6d
--- /dev/null
+++ b/src/test/illustratorRect.svg
@@ -0,0 +1,7 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg">
+ <rect id="pos_x5F_rect" x="5" y="15" width="8" height="12" style="fill:rgb(255,0,0);stroke-width:1; stroke:rgb(0,0,255)"/>
+</svg>
+
diff --git a/src/test/image.avg b/src/test/image.avg
new file mode 100644
index 0000000..7fc4c13
--- /dev/null
+++ b/src/test/image.avg
@@ -0,0 +1,8 @@
+<avg id="imageavg" width="160" height="120" mediadir="media">
+ <image id="testtiles" pos="(0, 30)" size=" ( 65 , 65 ) "
+ opacity="1" href="rgb24-65x65.png" maxtilewidth="16" maxtileheight="32"/>
+ <image id="test" x="64" y="30"
+ opacity="1" href="rgb24-65x65.png" pivot="(0, 0)" angle="0.274"/>
+ <image id="test1" x="129" y="30"
+ opacity="1" href="rgb24-65x65.png"/>
+</avg>
diff --git a/src/test/media/1x1_white.png b/src/test/media/1x1_white.png
new file mode 100644
index 0000000..5800230
--- /dev/null
+++ b/src/test/media/1x1_white.png
Binary files differ
diff --git a/src/test/media/22.050Hz_16bit_mono.wav b/src/test/media/22.050Hz_16bit_mono.wav
new file mode 100755
index 0000000..1f86e64
--- /dev/null
+++ b/src/test/media/22.050Hz_16bit_mono.wav
Binary files differ
diff --git a/src/test/media/44.1kHz_16bit_6Chan.ogg b/src/test/media/44.1kHz_16bit_6Chan.ogg
new file mode 100644
index 0000000..7d190d1
--- /dev/null
+++ b/src/test/media/44.1kHz_16bit_6Chan.ogg
Binary files differ
diff --git a/src/test/media/44.1kHz_16bit_mono.wav b/src/test/media/44.1kHz_16bit_mono.wav
new file mode 100755
index 0000000..8676a75
--- /dev/null
+++ b/src/test/media/44.1kHz_16bit_mono.wav
Binary files differ
diff --git a/src/test/media/44.1kHz_16bit_stereo.aif b/src/test/media/44.1kHz_16bit_stereo.aif
new file mode 100755
index 0000000..0c9b5c7
--- /dev/null
+++ b/src/test/media/44.1kHz_16bit_stereo.aif
Binary files differ
diff --git a/src/test/media/44.1kHz_16bit_stereo.wav b/src/test/media/44.1kHz_16bit_stereo.wav
new file mode 100755
index 0000000..af5c2ee
--- /dev/null
+++ b/src/test/media/44.1kHz_16bit_stereo.wav
Binary files differ
diff --git a/src/test/media/44.1kHz_24bit_mono.wav b/src/test/media/44.1kHz_24bit_mono.wav
new file mode 100755
index 0000000..fd2deed
--- /dev/null
+++ b/src/test/media/44.1kHz_24bit_mono.wav
Binary files differ
diff --git a/src/test/media/44.1kHz_24bit_stereo.aif b/src/test/media/44.1kHz_24bit_stereo.aif
new file mode 100755
index 0000000..f569ded
--- /dev/null
+++ b/src/test/media/44.1kHz_24bit_stereo.aif
Binary files differ
diff --git a/src/test/media/44.1kHz_24bit_stereo.wav b/src/test/media/44.1kHz_24bit_stereo.wav
new file mode 100755
index 0000000..36c6aa7
--- /dev/null
+++ b/src/test/media/44.1kHz_24bit_stereo.wav
Binary files differ
diff --git a/src/test/media/44.1kHz_mono.ogg b/src/test/media/44.1kHz_mono.ogg
new file mode 100755
index 0000000..7bcb866
--- /dev/null
+++ b/src/test/media/44.1kHz_mono.ogg
Binary files differ
diff --git a/src/test/media/44.1kHz_stereo.mp3 b/src/test/media/44.1kHz_stereo.mp3
new file mode 100644
index 0000000..cbefc63
--- /dev/null
+++ b/src/test/media/44.1kHz_stereo.mp3
Binary files differ
diff --git a/src/test/media/44.1kHz_stereo.ogg b/src/test/media/44.1kHz_stereo.ogg
new file mode 100644
index 0000000..f5ed4d0
--- /dev/null
+++ b/src/test/media/44.1kHz_stereo.ogg
Binary files differ
diff --git a/src/test/media/48kHz_16bit_mono.wav b/src/test/media/48kHz_16bit_mono.wav
new file mode 100755
index 0000000..0f817c9
--- /dev/null
+++ b/src/test/media/48kHz_16bit_mono.wav
Binary files differ
diff --git a/src/test/media/48kHz_16bit_stereo.aif b/src/test/media/48kHz_16bit_stereo.aif
new file mode 100755
index 0000000..db3a381
--- /dev/null
+++ b/src/test/media/48kHz_16bit_stereo.aif
Binary files differ
diff --git a/src/test/media/48kHz_16bit_stereo.wav b/src/test/media/48kHz_16bit_stereo.wav
new file mode 100755
index 0000000..9fc52f1
--- /dev/null
+++ b/src/test/media/48kHz_16bit_stereo.wav
Binary files differ
diff --git a/src/test/media/48kHz_24bit_mono.wav b/src/test/media/48kHz_24bit_mono.wav
new file mode 100755
index 0000000..296ca11
--- /dev/null
+++ b/src/test/media/48kHz_24bit_mono.wav
Binary files differ
diff --git a/src/test/media/48kHz_24bit_stereo.aif b/src/test/media/48kHz_24bit_stereo.aif
new file mode 100755
index 0000000..3ab7cf1
--- /dev/null
+++ b/src/test/media/48kHz_24bit_stereo.aif
Binary files differ
diff --git a/src/test/media/48kHz_24bit_stereo.wav b/src/test/media/48kHz_24bit_stereo.wav
new file mode 100755
index 0000000..af2c977
--- /dev/null
+++ b/src/test/media/48kHz_24bit_stereo.wav
Binary files differ
diff --git a/src/test/media/48kHz_stereo.mp3 b/src/test/media/48kHz_stereo.mp3
new file mode 100644
index 0000000..0eaa0f5
--- /dev/null
+++ b/src/test/media/48kHz_stereo.mp3
Binary files differ
diff --git a/src/test/media/48kHz_stereo.ogg b/src/test/media/48kHz_stereo.ogg
new file mode 100644
index 0000000..92d7b7b
--- /dev/null
+++ b/src/test/media/48kHz_stereo.ogg
Binary files differ
diff --git a/src/test/media/CustomSkin.xml b/src/test/media/CustomSkin.xml
new file mode 100644
index 0000000..3f21274
--- /dev/null
+++ b/src/test/media/CustomSkin.xml
@@ -0,0 +1,83 @@
+<skin>
+ <fontdef id="stdFont" font="Bitstream Vera Sans" variant="Roman" fontsize="12"
+ color="000000" letterspacing="0" linespacing="-1"/>
+ <fontdef id="downFont" baseid="stdFont" color="CCCCCC"/>
+ <fontdef id="disabledFont" baseid="stdFont" color="444444"/>
+ <textbutton
+ upSrc="button_bg_up.png"
+ downSrc="button_bg_down.png"
+ font="stdFont"
+ downFont="downFont"
+ disabledFont="disabledFont"
+ endsExtent="(7,7)"/>
+ <slider>
+ <horizontal
+ trackSrc="slider_horiz_track.png"
+ trackDisabledSrc="slider_horiz_track_disabled.png"
+ trackEndsExtent="6"
+ thumbUpSrc="slider_thumb_up.png"
+ thumbDownSrc="slider_thumb_down.png"/>
+ <vertical
+ trackSrc="slider_vert_track.png"
+ trackDisabledSrc="slider_vert_track_disabled.png"
+ trackEndsExtent="6"
+ thumbUpSrc="slider_thumb_up.png"
+ thumbDownSrc="slider_thumb_down.png"/>
+ </slider>
+ <scrollbar>
+ <horizontal
+ trackSrc="scrollbar_horiz_track.png"
+ trackDisabledSrc="scrollbar_horiz_track_disabled.png"
+ trackEndsExtent="2"
+ thumbUpSrc="scrollbar_horiz_thumb_up.png"
+ thumbDownSrc="scrollbar_horiz_thumb_down.png"
+ thumbEndsExtent="4"/>
+ <vertical
+ trackSrc="scrollbar_vert_track.png"
+ trackDisabledSrc="scrollbar_vert_track_disabled.png"
+ trackEndsExtent="2"
+ thumbUpSrc="scrollbar_vert_thumb_up.png"
+ thumbDownSrc="scrollbar_vert_thumb_down.png"
+ thumbEndsExtent="4"/>
+ </scrollbar>
+ <progressbar>
+ <horizontal
+ trackSrc="scrollbar_horiz_track.png"
+ trackEndsExtent="2"
+ thumbUpSrc="scrollbar_horiz_thumb_up.png"
+ thumbDisabledSrc="scrollbar_vert_thumb_down.png"
+ thumbEndsExtent="4"/>
+ <vertical
+ trackSrc="scrollbar_vert_track.png"
+ trackEndsExtent="2"
+ thumbUpSrc="scrollbar_vert_thumb_up.png"
+ thumbDisabledSrc="scrollbar_vert_thumb_down.png"
+ thumbEndsExtent="4"/>
+ </progressbar>
+ <scrollarea
+ borderSrc="scrollarea_border.png"
+ borderEndsExtent="(8,8)"
+ margins="(1,1,8,8)"
+ friction="-1"
+ sensitiveScrollBars="True"/>
+ <checkbox
+ uncheckedUpSrc="checkbox_unchecked_up.png"
+ uncheckedDownSrc="checkbox_unchecked_down.png"
+ uncheckedDisabledSrc="checkbox_unchecked_disabled.png"
+ checkedUpSrc="checkbox_checked_up.png"
+ checkedDownSrc="checkbox_checked_down.png"
+ checkedDisabledSrc="checkbox_checked_disabled.png"
+ font="stdFont"
+ downFont="stdFont"
+ disabledFont="disabledFont"/>
+ <mediacontrol
+ playUpSrc="play_button_up.png"
+ playDownSrc="play_button_down.png"
+ pauseUpSrc="pause_button_up.png"
+ pauseDownSrc="pause_button_down.png"
+ font="stdFont"
+ timePos="(15,0)"
+ timeLeftPos="(-42,0)"
+ barPos="(55,2)"
+ barRight="-45"/>
+</skin>
diff --git a/src/test/media/SimpleSkin.xml b/src/test/media/SimpleSkin.xml
new file mode 100644
index 0000000..3f21274
--- /dev/null
+++ b/src/test/media/SimpleSkin.xml
@@ -0,0 +1,83 @@
+<skin>
+ <fontdef id="stdFont" font="Bitstream Vera Sans" variant="Roman" fontsize="12"
+ color="000000" letterspacing="0" linespacing="-1"/>
+ <fontdef id="downFont" baseid="stdFont" color="CCCCCC"/>
+ <fontdef id="disabledFont" baseid="stdFont" color="444444"/>
+ <textbutton
+ upSrc="button_bg_up.png"
+ downSrc="button_bg_down.png"
+ font="stdFont"
+ downFont="downFont"
+ disabledFont="disabledFont"
+ endsExtent="(7,7)"/>
+ <slider>
+ <horizontal
+ trackSrc="slider_horiz_track.png"
+ trackDisabledSrc="slider_horiz_track_disabled.png"
+ trackEndsExtent="6"
+ thumbUpSrc="slider_thumb_up.png"
+ thumbDownSrc="slider_thumb_down.png"/>
+ <vertical
+ trackSrc="slider_vert_track.png"
+ trackDisabledSrc="slider_vert_track_disabled.png"
+ trackEndsExtent="6"
+ thumbUpSrc="slider_thumb_up.png"
+ thumbDownSrc="slider_thumb_down.png"/>
+ </slider>
+ <scrollbar>
+ <horizontal
+ trackSrc="scrollbar_horiz_track.png"
+ trackDisabledSrc="scrollbar_horiz_track_disabled.png"
+ trackEndsExtent="2"
+ thumbUpSrc="scrollbar_horiz_thumb_up.png"
+ thumbDownSrc="scrollbar_horiz_thumb_down.png"
+ thumbEndsExtent="4"/>
+ <vertical
+ trackSrc="scrollbar_vert_track.png"
+ trackDisabledSrc="scrollbar_vert_track_disabled.png"
+ trackEndsExtent="2"
+ thumbUpSrc="scrollbar_vert_thumb_up.png"
+ thumbDownSrc="scrollbar_vert_thumb_down.png"
+ thumbEndsExtent="4"/>
+ </scrollbar>
+ <progressbar>
+ <horizontal
+ trackSrc="scrollbar_horiz_track.png"
+ trackEndsExtent="2"
+ thumbUpSrc="scrollbar_horiz_thumb_up.png"
+ thumbDisabledSrc="scrollbar_vert_thumb_down.png"
+ thumbEndsExtent="4"/>
+ <vertical
+ trackSrc="scrollbar_vert_track.png"
+ trackEndsExtent="2"
+ thumbUpSrc="scrollbar_vert_thumb_up.png"
+ thumbDisabledSrc="scrollbar_vert_thumb_down.png"
+ thumbEndsExtent="4"/>
+ </progressbar>
+ <scrollarea
+ borderSrc="scrollarea_border.png"
+ borderEndsExtent="(8,8)"
+ margins="(1,1,8,8)"
+ friction="-1"
+ sensitiveScrollBars="True"/>
+ <checkbox
+ uncheckedUpSrc="checkbox_unchecked_up.png"
+ uncheckedDownSrc="checkbox_unchecked_down.png"
+ uncheckedDisabledSrc="checkbox_unchecked_disabled.png"
+ checkedUpSrc="checkbox_checked_up.png"
+ checkedDownSrc="checkbox_checked_down.png"
+ checkedDisabledSrc="checkbox_checked_disabled.png"
+ font="stdFont"
+ downFont="stdFont"
+ disabledFont="disabledFont"/>
+ <mediacontrol
+ playUpSrc="play_button_up.png"
+ playDownSrc="play_button_down.png"
+ pauseUpSrc="pause_button_up.png"
+ pauseDownSrc="pause_button_down.png"
+ font="stdFont"
+ timePos="(15,0)"
+ timeLeftPos="(-42,0)"
+ barPos="(55,2)"
+ barRight="-45"/>
+</skin>
diff --git a/src/test/media/button_bg_down.png b/src/test/media/button_bg_down.png
new file mode 100644
index 0000000..81cbb0f
--- /dev/null
+++ b/src/test/media/button_bg_down.png
Binary files differ
diff --git a/src/test/media/button_bg_up.png b/src/test/media/button_bg_up.png
new file mode 100644
index 0000000..91cfe04
--- /dev/null
+++ b/src/test/media/button_bg_up.png
Binary files differ
diff --git a/src/test/media/button_check.png b/src/test/media/button_check.png
new file mode 100644
index 0000000..b0aa4a9
--- /dev/null
+++ b/src/test/media/button_check.png
Binary files differ
diff --git a/src/test/media/button_disabled.png b/src/test/media/button_disabled.png
new file mode 100644
index 0000000..dbf1309
--- /dev/null
+++ b/src/test/media/button_disabled.png
Binary files differ
diff --git a/src/test/media/button_down.png b/src/test/media/button_down.png
new file mode 100644
index 0000000..88ee5f5
--- /dev/null
+++ b/src/test/media/button_down.png
Binary files differ
diff --git a/src/test/media/button_over.png b/src/test/media/button_over.png
new file mode 100644
index 0000000..0837e8e
--- /dev/null
+++ b/src/test/media/button_over.png
Binary files differ
diff --git a/src/test/media/button_up.png b/src/test/media/button_up.png
new file mode 100644
index 0000000..aa7d33a
--- /dev/null
+++ b/src/test/media/button_up.png
Binary files differ
diff --git a/src/test/media/checkbox_checked_disabled.png b/src/test/media/checkbox_checked_disabled.png
new file mode 100644
index 0000000..da58829
--- /dev/null
+++ b/src/test/media/checkbox_checked_disabled.png
Binary files differ
diff --git a/src/test/media/checkbox_checked_down.png b/src/test/media/checkbox_checked_down.png
new file mode 100644
index 0000000..4fbbd83
--- /dev/null
+++ b/src/test/media/checkbox_checked_down.png
Binary files differ
diff --git a/src/test/media/checkbox_checked_up.png b/src/test/media/checkbox_checked_up.png
new file mode 100644
index 0000000..ca901f4
--- /dev/null
+++ b/src/test/media/checkbox_checked_up.png
Binary files differ
diff --git a/src/test/media/checkbox_unchecked_disabled.png b/src/test/media/checkbox_unchecked_disabled.png
new file mode 100644
index 0000000..e8c2116
--- /dev/null
+++ b/src/test/media/checkbox_unchecked_disabled.png
Binary files differ
diff --git a/src/test/media/checkbox_unchecked_down.png b/src/test/media/checkbox_unchecked_down.png
new file mode 100644
index 0000000..69f8282
--- /dev/null
+++ b/src/test/media/checkbox_unchecked_down.png
Binary files differ
diff --git a/src/test/media/checkbox_unchecked_up.png b/src/test/media/checkbox_unchecked_up.png
new file mode 100644
index 0000000..e354492
--- /dev/null
+++ b/src/test/media/checkbox_unchecked_up.png
Binary files differ
diff --git a/src/test/media/checker.png b/src/test/media/checker.png
new file mode 100644
index 0000000..4f100c5
--- /dev/null
+++ b/src/test/media/checker.png
Binary files differ
diff --git a/src/test/media/chromakey-median.png b/src/test/media/chromakey-median.png
new file mode 100644
index 0000000..5858c4b
--- /dev/null
+++ b/src/test/media/chromakey-median.png
Binary files differ
diff --git a/src/test/media/chromakey.png b/src/test/media/chromakey.png
new file mode 100644
index 0000000..b2cfc2e
--- /dev/null
+++ b/src/test/media/chromakey.png
Binary files differ
diff --git a/src/test/media/colorramp.png b/src/test/media/colorramp.png
new file mode 100644
index 0000000..da12725
--- /dev/null
+++ b/src/test/media/colorramp.png
Binary files differ
diff --git a/src/test/media/crop_bkgd.png b/src/test/media/crop_bkgd.png
new file mode 100644
index 0000000..89f9e95
--- /dev/null
+++ b/src/test/media/crop_bkgd.png
Binary files differ
diff --git a/src/test/media/dilation.png b/src/test/media/dilation.png
new file mode 100644
index 0000000..7981594
--- /dev/null
+++ b/src/test/media/dilation.png
Binary files differ
diff --git a/src/test/media/erosion.png b/src/test/media/erosion.png
new file mode 100644
index 0000000..899e2c4
--- /dev/null
+++ b/src/test/media/erosion.png
Binary files differ
diff --git a/src/test/media/filterwipeborder.png b/src/test/media/filterwipeborder.png
new file mode 100644
index 0000000..58ac84d
--- /dev/null
+++ b/src/test/media/filterwipeborder.png
Binary files differ
diff --git a/src/test/media/flat.png b/src/test/media/flat.png
new file mode 100644
index 0000000..51d2c55
--- /dev/null
+++ b/src/test/media/flat.png
Binary files differ
diff --git a/src/test/media/floodfill.png b/src/test/media/floodfill.png
new file mode 100644
index 0000000..6a9e5b5
--- /dev/null
+++ b/src/test/media/floodfill.png
Binary files differ
diff --git a/src/test/media/freidrehen.jpg b/src/test/media/freidrehen.jpg
new file mode 100644
index 0000000..7f93bf0
--- /dev/null
+++ b/src/test/media/freidrehen.jpg
Binary files differ
diff --git a/src/test/media/greyscale.png b/src/test/media/greyscale.png
new file mode 100644
index 0000000..f86a18b
--- /dev/null
+++ b/src/test/media/greyscale.png
Binary files differ
diff --git a/src/test/media/h264-48x48.h264 b/src/test/media/h264-48x48.h264
new file mode 100644
index 0000000..d650960
--- /dev/null
+++ b/src/test/media/h264-48x48.h264
Binary files differ
diff --git a/src/test/media/hsl.png b/src/test/media/hsl.png
new file mode 100644
index 0000000..9621451
--- /dev/null
+++ b/src/test/media/hsl.png
Binary files differ
diff --git a/src/test/media/i8-64x64.png b/src/test/media/i8-64x64.png
new file mode 100644
index 0000000..ec88c8c
--- /dev/null
+++ b/src/test/media/i8-64x64.png
Binary files differ
diff --git a/src/test/media/incompleteSkinMedia/IncompleteSkin.xml b/src/test/media/incompleteSkinMedia/IncompleteSkin.xml
new file mode 100644
index 0000000..019d702
--- /dev/null
+++ b/src/test/media/incompleteSkinMedia/IncompleteSkin.xml
@@ -0,0 +1,11 @@
+<skin>
+<scrollbar>
+ <horizontal
+ trackSrc="scrollbar_horiz_track.png"
+ trackDisabledSrc="scrollbar_horiz_track_disabled.png"
+ trackEndsExtent="2"
+ thumbUpSrc="scrollbar_horiz_thumb_up.png"
+ thumbDownSrc="scrollbar_horiz_thumb_down.png"
+ thumbEndsExtent="4"/>
+</scrollbar>
+</skin>
diff --git a/src/test/media/incompleteSkinMedia/scrollbar_horiz_thumb_down.png b/src/test/media/incompleteSkinMedia/scrollbar_horiz_thumb_down.png
new file mode 100644
index 0000000..6dc6fd1
--- /dev/null
+++ b/src/test/media/incompleteSkinMedia/scrollbar_horiz_thumb_down.png
Binary files differ
diff --git a/src/test/media/incompleteSkinMedia/scrollbar_horiz_thumb_up.png b/src/test/media/incompleteSkinMedia/scrollbar_horiz_thumb_up.png
new file mode 100644
index 0000000..eb6b005
--- /dev/null
+++ b/src/test/media/incompleteSkinMedia/scrollbar_horiz_thumb_up.png
Binary files differ
diff --git a/src/test/media/incompleteSkinMedia/scrollbar_horiz_track.png b/src/test/media/incompleteSkinMedia/scrollbar_horiz_track.png
new file mode 100644
index 0000000..d2f393b
--- /dev/null
+++ b/src/test/media/incompleteSkinMedia/scrollbar_horiz_track.png
Binary files differ
diff --git a/src/test/media/incompleteSkinMedia/scrollbar_horiz_track_disabled.png b/src/test/media/incompleteSkinMedia/scrollbar_horiz_track_disabled.png
new file mode 100644
index 0000000..7ac86fe
--- /dev/null
+++ b/src/test/media/incompleteSkinMedia/scrollbar_horiz_track_disabled.png
Binary files differ
diff --git a/src/test/media/keyboard_bg.png b/src/test/media/keyboard_bg.png
new file mode 100644
index 0000000..a767d06
--- /dev/null
+++ b/src/test/media/keyboard_bg.png
Binary files differ
diff --git a/src/test/media/keyboard_down.png b/src/test/media/keyboard_down.png
new file mode 100644
index 0000000..f3ead71
--- /dev/null
+++ b/src/test/media/keyboard_down.png
Binary files differ
diff --git a/src/test/media/keyboard_feedback.png b/src/test/media/keyboard_feedback.png
new file mode 100644
index 0000000..e519594
--- /dev/null
+++ b/src/test/media/keyboard_feedback.png
Binary files differ
diff --git a/src/test/media/mask.png b/src/test/media/mask.png
new file mode 100644
index 0000000..031b39a
--- /dev/null
+++ b/src/test/media/mask.png
Binary files differ
diff --git a/src/test/media/mask1.png b/src/test/media/mask1.png
new file mode 100644
index 0000000..ffe5618
--- /dev/null
+++ b/src/test/media/mask1.png
Binary files differ
diff --git a/src/test/media/mask2.png b/src/test/media/mask2.png
new file mode 100644
index 0000000..92975df
--- /dev/null
+++ b/src/test/media/mask2.png
Binary files differ
diff --git a/src/test/media/mjpeg-48x48.avi b/src/test/media/mjpeg-48x48.avi
new file mode 100644
index 0000000..337df16
--- /dev/null
+++ b/src/test/media/mjpeg-48x48.avi
Binary files differ
diff --git a/src/test/media/mpeg1-48x48-sound.avi b/src/test/media/mpeg1-48x48-sound.avi
new file mode 100644
index 0000000..be415db
--- /dev/null
+++ b/src/test/media/mpeg1-48x48-sound.avi
Binary files differ
diff --git a/src/test/media/mpeg1-48x48.mov b/src/test/media/mpeg1-48x48.mov
new file mode 100644
index 0000000..16ab499
--- /dev/null
+++ b/src/test/media/mpeg1-48x48.mov
Binary files differ
diff --git a/src/test/media/oe.png b/src/test/media/oe.png
new file mode 100644
index 0000000..3527967
--- /dev/null
+++ b/src/test/media/oe.png
Binary files differ
diff --git a/src/test/media/pause_button_down.png b/src/test/media/pause_button_down.png
new file mode 100644
index 0000000..c06b34a
--- /dev/null
+++ b/src/test/media/pause_button_down.png
Binary files differ
diff --git a/src/test/media/pause_button_up.png b/src/test/media/pause_button_up.png
new file mode 100644
index 0000000..1a923b9
--- /dev/null
+++ b/src/test/media/pause_button_up.png
Binary files differ
diff --git a/src/test/media/play_button_down.png b/src/test/media/play_button_down.png
new file mode 100644
index 0000000..07b167b
--- /dev/null
+++ b/src/test/media/play_button_down.png
Binary files differ
diff --git a/src/test/media/play_button_up.png b/src/test/media/play_button_up.png
new file mode 100644
index 0000000..e16ec9e
--- /dev/null
+++ b/src/test/media/play_button_up.png
Binary files differ
diff --git a/src/test/media/rect.svg b/src/test/media/rect.svg
new file mode 100644
index 0000000..136b061
--- /dev/null
+++ b/src/test/media/rect.svg
@@ -0,0 +1,8 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg">
+ <rect id="rect" x="1" y="1" width="20" height="10" style="fill:rgb(255,0,0);stroke-width:1; stroke:rgb(0,0,255)"/>
+ <rect id="pos_rect" x="5" y="15" width="8" height="12" style="fill:rgb(255,0,0);stroke-width:1; stroke:rgb(0,0,255)"/>
+</svg>
+
diff --git a/src/test/media/rectborder.png b/src/test/media/rectborder.png
new file mode 100644
index 0000000..1675688
--- /dev/null
+++ b/src/test/media/rectborder.png
Binary files differ
diff --git a/src/test/media/rgb24-32x32.png b/src/test/media/rgb24-32x32.png
new file mode 100644
index 0000000..c5d6711
--- /dev/null
+++ b/src/test/media/rgb24-32x32.png
Binary files differ
diff --git a/src/test/media/rgb24-64x64.png b/src/test/media/rgb24-64x64.png
new file mode 100644
index 0000000..cca71fe
--- /dev/null
+++ b/src/test/media/rgb24-64x64.png
Binary files differ
diff --git a/src/test/media/rgb24-65x65.png b/src/test/media/rgb24-65x65.png
new file mode 100644
index 0000000..ada2689
--- /dev/null
+++ b/src/test/media/rgb24-65x65.png
Binary files differ
diff --git a/src/test/media/rgb24alpha-32x32.png b/src/test/media/rgb24alpha-32x32.png
new file mode 100644
index 0000000..2e9e6af
--- /dev/null
+++ b/src/test/media/rgb24alpha-32x32.png
Binary files differ
diff --git a/src/test/media/rgb24alpha-64x64.png b/src/test/media/rgb24alpha-64x64.png
new file mode 100644
index 0000000..41b69c3
--- /dev/null
+++ b/src/test/media/rgb24alpha-64x64.png
Binary files differ
diff --git a/src/test/media/rgba-48x48.mov b/src/test/media/rgba-48x48.mov
new file mode 100644
index 0000000..7e311cc
--- /dev/null
+++ b/src/test/media/rgba-48x48.mov
Binary files differ
diff --git a/src/test/media/scrollarea_border.png b/src/test/media/scrollarea_border.png
new file mode 100644
index 0000000..2e95f57
--- /dev/null
+++ b/src/test/media/scrollarea_border.png
Binary files differ
diff --git a/src/test/media/scrollbar_horiz_thumb_disabled.png b/src/test/media/scrollbar_horiz_thumb_disabled.png
new file mode 100644
index 0000000..4645372
--- /dev/null
+++ b/src/test/media/scrollbar_horiz_thumb_disabled.png
Binary files differ
diff --git a/src/test/media/scrollbar_horiz_thumb_down.png b/src/test/media/scrollbar_horiz_thumb_down.png
new file mode 100644
index 0000000..6dc6fd1
--- /dev/null
+++ b/src/test/media/scrollbar_horiz_thumb_down.png
Binary files differ
diff --git a/src/test/media/scrollbar_horiz_thumb_up.png b/src/test/media/scrollbar_horiz_thumb_up.png
new file mode 100644
index 0000000..eb6b005
--- /dev/null
+++ b/src/test/media/scrollbar_horiz_thumb_up.png
Binary files differ
diff --git a/src/test/media/scrollbar_horiz_track.png b/src/test/media/scrollbar_horiz_track.png
new file mode 100644
index 0000000..d2f393b
--- /dev/null
+++ b/src/test/media/scrollbar_horiz_track.png
Binary files differ
diff --git a/src/test/media/scrollbar_horiz_track_disabled.png b/src/test/media/scrollbar_horiz_track_disabled.png
new file mode 100644
index 0000000..7ac86fe
--- /dev/null
+++ b/src/test/media/scrollbar_horiz_track_disabled.png
Binary files differ
diff --git a/src/test/media/scrollbar_vert_thumb_disabled.png b/src/test/media/scrollbar_vert_thumb_disabled.png
new file mode 100644
index 0000000..f375a2b
--- /dev/null
+++ b/src/test/media/scrollbar_vert_thumb_disabled.png
Binary files differ
diff --git a/src/test/media/scrollbar_vert_thumb_down.png b/src/test/media/scrollbar_vert_thumb_down.png
new file mode 100644
index 0000000..c7b09d1
--- /dev/null
+++ b/src/test/media/scrollbar_vert_thumb_down.png
Binary files differ
diff --git a/src/test/media/scrollbar_vert_thumb_up.png b/src/test/media/scrollbar_vert_thumb_up.png
new file mode 100644
index 0000000..f6c2f88
--- /dev/null
+++ b/src/test/media/scrollbar_vert_thumb_up.png
Binary files differ
diff --git a/src/test/media/scrollbar_vert_track.png b/src/test/media/scrollbar_vert_track.png
new file mode 100644
index 0000000..58af284
--- /dev/null
+++ b/src/test/media/scrollbar_vert_track.png
Binary files differ
diff --git a/src/test/media/scrollbar_vert_track_disabled.png b/src/test/media/scrollbar_vert_track_disabled.png
new file mode 100644
index 0000000..695b112
--- /dev/null
+++ b/src/test/media/scrollbar_vert_track_disabled.png
Binary files differ
diff --git a/src/test/media/shadow.png b/src/test/media/shadow.png
new file mode 100644
index 0000000..0a4563f
--- /dev/null
+++ b/src/test/media/shadow.png
Binary files differ
diff --git a/src/test/media/slider_horiz_track.png b/src/test/media/slider_horiz_track.png
new file mode 100644
index 0000000..6e233a5
--- /dev/null
+++ b/src/test/media/slider_horiz_track.png
Binary files differ
diff --git a/src/test/media/slider_horiz_track_disabled.png b/src/test/media/slider_horiz_track_disabled.png
new file mode 100644
index 0000000..01c880d
--- /dev/null
+++ b/src/test/media/slider_horiz_track_disabled.png
Binary files differ
diff --git a/src/test/media/slider_thumb_down.png b/src/test/media/slider_thumb_down.png
new file mode 100644
index 0000000..1f2acc2
--- /dev/null
+++ b/src/test/media/slider_thumb_down.png
Binary files differ
diff --git a/src/test/media/slider_thumb_up.png b/src/test/media/slider_thumb_up.png
new file mode 100644
index 0000000..885506d
--- /dev/null
+++ b/src/test/media/slider_thumb_up.png
Binary files differ
diff --git a/src/test/media/slider_vert_track.png b/src/test/media/slider_vert_track.png
new file mode 100644
index 0000000..51bac37
--- /dev/null
+++ b/src/test/media/slider_vert_track.png
Binary files differ
diff --git a/src/test/media/slider_vert_track_disabled.png b/src/test/media/slider_vert_track_disabled.png
new file mode 100644
index 0000000..bc8d7b6
--- /dev/null
+++ b/src/test/media/slider_vert_track_disabled.png
Binary files differ
diff --git a/src/test/media/spike.png b/src/test/media/spike.png
new file mode 100644
index 0000000..958e95d
--- /dev/null
+++ b/src/test/media/spike.png
Binary files differ
diff --git a/src/test/media/toggle_checked_Disabled.png b/src/test/media/toggle_checked_Disabled.png
new file mode 100644
index 0000000..31372c0
--- /dev/null
+++ b/src/test/media/toggle_checked_Disabled.png
Binary files differ
diff --git a/src/test/media/toggle_checked_Down.png b/src/test/media/toggle_checked_Down.png
new file mode 100644
index 0000000..8c4afd2
--- /dev/null
+++ b/src/test/media/toggle_checked_Down.png
Binary files differ
diff --git a/src/test/media/toggle_checked_Up.png b/src/test/media/toggle_checked_Up.png
new file mode 100644
index 0000000..8214fcf
--- /dev/null
+++ b/src/test/media/toggle_checked_Up.png
Binary files differ
diff --git a/src/test/media/toggle_unchecked_Disabled.png b/src/test/media/toggle_unchecked_Disabled.png
new file mode 100644
index 0000000..6b90e0b
--- /dev/null
+++ b/src/test/media/toggle_unchecked_Disabled.png
Binary files differ
diff --git a/src/test/media/toggle_unchecked_Down.png b/src/test/media/toggle_unchecked_Down.png
new file mode 100644
index 0000000..f2e4272
--- /dev/null
+++ b/src/test/media/toggle_unchecked_Down.png
Binary files differ
diff --git a/src/test/media/toggle_unchecked_Up.png b/src/test/media/toggle_unchecked_Up.png
new file mode 100644
index 0000000..3a006ea
--- /dev/null
+++ b/src/test/media/toggle_unchecked_Up.png
Binary files differ
diff --git a/src/test/media/vp6a-yuva-48x48.flv b/src/test/media/vp6a-yuva-48x48.flv
new file mode 100644
index 0000000..21866fe
--- /dev/null
+++ b/src/test/media/vp6a-yuva-48x48.flv
Binary files differ
diff --git a/src/test/media/widebmp.jpg b/src/test/media/widebmp.jpg
new file mode 100644
index 0000000..8304e3d
--- /dev/null
+++ b/src/test/media/widebmp.jpg
Binary files differ
diff --git a/src/test/plugin/ColorNode.cpp b/src/test/plugin/ColorNode.cpp
new file mode 100644
index 0000000..b98c98b
--- /dev/null
+++ b/src/test/plugin/ColorNode.cpp
@@ -0,0 +1,153 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+// Original author of this file is Jan Boelsche (regular.gonzales@googlemail.com).
+//
+
+#define AVG_PLUGIN
+#include "../../api.h"
+
+#include "../../player/Player.h"
+#include "../../player/AreaNode.h"
+#include "../../player/TypeDefinition.h"
+
+#include "../../base/Logger.h"
+#include "../../graphics/OGLHelper.h"
+#include "../../wrapper/WrapHelper.h"
+#include "../../wrapper/raw_constructor.hpp"
+
+#include <string>
+#include <iostream>
+#include <sstream>
+#include <iomanip>
+
+using namespace std;
+using namespace boost::python;
+
+namespace avg {
+
+class ColorNode : public AreaNode
+{
+public:
+ static void registerType();
+
+ ColorNode(const ArgList& Args);
+
+ void setFillColor(const std::string& sColor);
+ const std::string& getFillColor() const;
+
+ float getFloat() const;
+ void setFloat(float f);
+
+ virtual void maybeRender(const glm::mat4& parentTransform);
+ virtual void render();
+
+private:
+ std::string m_sFillColorName;
+ Pixel32 m_Color;
+ float m_FloatParam;
+};
+
+ColorNode::ColorNode(const ArgList& Args)
+ : m_sFillColorName("FFFFFF")
+{
+ AVG_TRACE(Logger::category::PLUGIN, Logger::severity::INFO,
+ "ColorNode c'tor gets Argument fillcolor= " <<
+ Args.getArgVal<string>("fillcolor"));
+
+ Args.setMembers(this);
+ AVG_TRACE(Logger::category::PLUGIN, Logger::severity::INFO,
+ "ColorNode constructed with " << m_sFillColorName);
+ m_Color = colorStringToColor(m_sFillColorName);
+}
+
+void ColorNode::setFillColor(const string& sFillColor)
+{
+ AVG_TRACE(Logger::category::PLUGIN, Logger::severity::INFO,
+ "setFillColor called with " << sFillColor);
+ m_sFillColorName = sFillColor;
+ m_Color = colorStringToColor(m_sFillColorName);
+}
+
+const std::string& ColorNode::getFillColor() const
+{
+ return m_sFillColorName;
+}
+
+float ColorNode::getFloat() const
+{
+ return m_FloatParam;
+}
+
+void ColorNode::setFloat(float f)
+{
+ m_FloatParam = f;
+}
+
+
+void ColorNode::maybeRender(const glm::mat4& parentTransform)
+{
+ render();
+}
+
+void ColorNode::render()
+{
+ glClearColor(m_Color.getR()/255., m_Color.getG()/255., m_Color.getB()/255., 1.0);
+ glClear(GL_COLOR_BUFFER_BIT);
+}
+
+char colorNodeName[] = "colornode";
+
+void ColorNode::registerType()
+{
+ avg::TypeDefinition def = avg::TypeDefinition("colornode", "areanode",
+ ExportedObject::buildObject<ColorNode>)
+ .addArg(Arg<float>("floatparam", 0.0f, false,
+ offsetof(ColorNode, m_FloatParam)))
+ .addArg(Arg<string>("fillcolor", "0F0F0F", false,
+ offsetof(ColorNode, m_sFillColorName)));
+ const char* allowedParentNodeNames[] = {"avg", 0};
+ avg::TypeRegistry::get()->registerType(def, allowedParentNodeNames);
+}
+
+}
+
+using namespace avg;
+
+BOOST_PYTHON_MODULE(colorplugin)
+{
+ class_<ColorNode, bases<AreaNode>, boost::noncopyable>("ColorNode", no_init)
+ .def("__init__", raw_constructor(createNode<colorNodeName>))
+ .add_property("floatparam", &ColorNode::getFloat, &ColorNode::setFloat)
+ .add_property("fillcolor", make_function(&ColorNode::getFillColor,
+ return_value_policy<copy_const_reference>()), &ColorNode::setFillColor);
+}
+
+AVG_PLUGIN_API void registerPlugin()
+{
+ initcolorplugin();
+ object mainModule(handle<>(borrowed(PyImport_AddModule("__builtin__"))));
+ object colorModule(handle<>(PyImport_ImportModule("colorplugin")));
+ mainModule.attr("colorplugin") = colorModule;
+
+ avg::ColorNode::registerType();
+
+}
+
diff --git a/src/test/plugin/Makefile.am b/src/test/plugin/Makefile.am
new file mode 100644
index 0000000..9aa10b1
--- /dev/null
+++ b/src/test/plugin/Makefile.am
@@ -0,0 +1,19 @@
+AM_CPPFLAGS = -I. -I../player \
+ @XML2_CFLAGS@ @PTHREAD_CFLAGS@ @PANGOFT2_CFLAGS@ \
+ @PYTHON_CPPFLAGS@ @DC1394_2_CFLAGS@
+
+ALL_H =
+
+if APPLE
+ XGL_LIBS =
+ EXTRA_LDFLAGS = -read_only_relocs suppress
+else
+ XGL_LIBS = -lXxf86vm
+ EXTRA_LDFLAGS = -XCClinker ../../wrapper/.libs/avg.so
+endif
+
+ALL_GL_LIBS = @GL_LIBS@ @SDL_LIBS@ $(XGL_LIBS)
+
+pkgpyexec_LTLIBRARIES = colorplugin.la
+colorplugin_la_SOURCES = ColorNode.cpp
+colorplugin_la_LDFLAGS = $(EXTRA_LDFLAGS) -module
diff --git a/src/test/plugin/test.sh b/src/test/plugin/test.sh
new file mode 100755
index 0000000..9af205f
--- /dev/null
+++ b/src/test/plugin/test.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+pushd ..
+./PluginTest.py
+popd
+
diff --git a/src/test/testapp.py b/src/test/testapp.py
new file mode 100644
index 0000000..251ab47
--- /dev/null
+++ b/src/test/testapp.py
@@ -0,0 +1,191 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# libavg - Media Playback Engine.
+# Copyright (C) 2003-2014 Ulrich von Zadow
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Current versions can be found at www.libavg.de
+#
+
+import unittest
+
+import optparse
+import os
+import sys
+
+from libavg import avg, player
+import testcase
+
+
+class TestApp(object):
+ EXIT_OK = 0
+ EXIT_FAILURE = 1
+
+ def __init__(self):
+ self.__exitOk = TestApp.EXIT_FAILURE
+
+ self.__registeredSuiteFactories = []
+ self.__registerdSuiteFactoriesDict = {}
+
+ self.__suitesToRun = []
+ self.__suitesTestSubsets = []
+
+ self.__testSuite = unittest.TestSuite()
+ self.__optionParser = None
+ self.__commandlineOptions = None
+ player.keepWindowOpen()
+
+ def getSuiteFactory(self, name):
+ return self.__registerdSuiteFactoriesDict[name]
+
+ def isSuiteFactoryRegistered(self, name):
+ return name in self.__registeredSuiteFactories
+
+ def getSuiteFactoryNames(self):
+ return list(self.__registeredSuiteFactories)
+
+ def getSuiteFactories(self):
+ return [ self.__registerdSuiteFactoriesDict[name]
+ for name in self.__registeredSuiteFactories ]
+
+ def registerSuiteFactory(self, name, suite):
+ self.__registeredSuiteFactories.append(name)
+ self.__registerdSuiteFactoriesDict[name] = suite
+
+ def run(self):
+ hasAVGConsoleTest = os.getenv("AVG_CONSOLE_TEST")
+ if hasAVGConsoleTest:
+ self.__runVideoTest()
+ else:
+ self.__setupTestApp()
+ self.__run()
+
+ def exitCode(self):
+ return self.__exitOk
+
+ def __iter__(self):
+ for name in self.__registeredSuiteFactories:
+ yield self.__RegisterdSuitesDict[name]
+
+ def __runVideoTest(self):
+ player.loadFile("image.avg")
+
+ def __run(self):
+ testRunner = unittest.TextTestRunner(verbosity = 2)
+ testcase.AVGTestCase.cleanResultDir()
+ testResult = testRunner.run(self.__testSuite)
+
+ numSkipped = 0
+ for suite in self.__testSuite:
+ for test in suite:
+ if test.skipped():
+ numSkipped += 1
+ if numSkipped > 0:
+ sys.stderr.write("Skipped "+str(numSkipped)+" tests:\n")
+ for suite in self.__testSuite:
+ for test in suite:
+ if test.skipped():
+ print " " + str(test) + ": " + test.skipReason()
+
+ if testResult.wasSuccessful():
+ self.__exitOk = TestApp.EXIT_OK
+
+ def __setupTestApp(self):
+ self.__setupCommandlineParser()
+ self.__parseCommandline()
+ self.__setupGlobalPlayerOptions()
+ self.__dumpConfig()
+ self.__populateTestSuite()
+
+ def __setupGlobalPlayerOptions(self):
+ if self.__commandlineOptions.shaderusage == "FULL":
+ shaderUsage = avg.SHADERUSAGE_FULL
+ elif self.__commandlineOptions.shaderusage == "MINIMAL":
+ shaderUsage = avg.SHADERUSAGE_MINIMAL
+ elif self.__commandlineOptions.shaderusage == "FRAGMENT_ONLY":
+ shaderUsage = avg.SHADERUSAGE_FRAGMENT_ONLY
+ elif self.__commandlineOptions.shaderusage == "AUTO":
+ shaderUsage = avg.SHADERUSAGE_AUTO
+ else:
+ sys.stderr.write("\nUnknown value for --shaderusage command-line parameter.\n")
+ self.__optionParser.print_help()
+ sys.exit(-1)
+
+ player.setOGLOptions(self.__commandlineOptions.usepow2textures,
+ self.__commandlineOptions.usepixelbuffers, 1, shaderUsage, True)
+
+ def __setupCommandlineParser(self):
+ self.__optionParser = optparse.OptionParser(
+ usage = '%prog [options] [<suite> [testcase] [testcase] [...]]')
+
+ self.__optionParser.add_option("--usepow2textures",
+ dest = "usepow2textures",
+ action = 'store_true',
+ default = False,
+ help = "Use power of 2 textures")
+
+ self.__optionParser.add_option("--nopixelbuffers",
+ dest = "usepixelbuffers",
+ action = 'store_false',
+ default = True,
+ help = "Use pixel buffers")
+
+ self.__optionParser.add_option("--shaderusage",
+ dest = "shaderusage",
+ default = "AUTO",
+ help = "Configure usage of shaders. Valid values are FULL, MINIMAL, FRAGMENT_ONLY and AUTO.")
+
+ def __parseCommandline(self):
+ self.__commandlineOptions, args = self.__optionParser.parse_args()
+
+ # MFX 2013-11-10: cleanup argv consuming testapp args to avoid clashes
+ # with libavg.app.App ArgvExtender
+ sys.argv = [sys.argv[0]]
+
+ if len(args): # suite
+ suiteFactory = args.pop(0)
+ if not(self.isSuiteFactoryRegistered(suiteFactory)):
+ sys.stderr.write("Unknown test suite, registered suites:\n")
+ for factory in self.getSuiteFactoryNames():
+ sys.stderr.write(factory+"\n")
+ sys.stderr.write("\n")
+ self.__optionParser.print_usage()
+
+ self.__suitesToRun.append(self.getSuiteFactory(suiteFactory))
+ self.__suitesTestSubsets = args
+
+ else:
+ self.__suitesToRun = self.getSuiteFactories()
+
+ def __populateTestSuite(self):
+ for suite in self.__suitesToRun:
+ self.__testSuite.addTest(suite(self.__suitesTestSubsets))
+
+ def __dumpConfig(self):
+ player.enableGLErrorChecks(True)
+ cats = avg.logger.getCategories()
+ for cat in [avg.logger.Category.APP, avg.logger.Category.CONFIG,
+ avg.logger.Category.DEPREC]:
+ avg.logger.configureCategory(cat, avg.logger.Severity.INFO)
+ player.loadString("""
+ <avg id="avg" width="160" height="120">
+ </avg>
+ """)
+ player.setTimeout(0, player.stop)
+ player.setFramerate(10000)
+ player.play()
+ for cat, severity in cats.iteritems():
+ avg.logger.configureCategory(cat, severity)
diff --git a/src/test/testcase.py b/src/test/testcase.py
new file mode 100644
index 0000000..95f271e
--- /dev/null
+++ b/src/test/testcase.py
@@ -0,0 +1,369 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# libavg - Media Playback Engine.
+# Copyright (C) 2003-2014 Ulrich von Zadow
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Current versions can be found at www.libavg.de
+#
+
+import unittest
+
+import sys
+import os
+import math
+
+from libavg import avg, player, logger
+
+def almostEqual(a, b, epsilon):
+ try:
+ bOk = True
+ for i in range(len(a)):
+ if not(almostEqual(a[i], b[i], epsilon)):
+ bOk = False
+ return bOk
+ except:
+ return math.fabs(a-b) < epsilon
+
+def flatten(l):
+ ltype = type(l)
+ l = list(l)
+ i = 0
+ while i < len(l):
+ while isinstance(l[i], (list, tuple)):
+ if not l[i]:
+ l.pop(i)
+ i -= 1
+ break
+ else:
+ l[i:i + 1] = l[i]
+ i += 1
+ return ltype(l)
+
+
+class SuppressOutput(object):
+ class Blackhole(object):
+ def write(self, *args):
+ pass
+
+ def __init__(self):
+ self.__savedStreams = [sys.stdout, sys.stderr]
+
+ def __enter__(self):
+ sys.stdout = self.Blackhole()
+ sys.stderr = self.Blackhole()
+
+ def __exit__(self, *args):
+ sys.stdout, sys.stderr = self.__savedStreams
+
+
+class MouseEmulator(object):
+ def __init__(self):
+ self.btnStates = [False, False, False]
+
+ def sendMouseEvent(self, type_, x, y, btn=1):
+ helper = player.getTestHelper()
+ index = btn-1
+ if type_ == avg.Event.CURSOR_UP:
+ self.btnStates[index] = False
+ if type_ == avg.Event.CURSOR_DOWN:
+ self.btnStates[index] = True
+
+ helper.fakeMouseEvent(type_, self.btnStates[0], self.btnStates[1],
+ self.btnStates[2], x, y, btn)
+
+
+class AVGTestCase(unittest.TestCase):
+ imageResultDirectory = "resultimages"
+ baselineImageResultDirectory = "baseline"
+
+ def __init__(self, testFuncName):
+ unittest.TestCase.__init__(self, testFuncName)
+
+ player.enableGLErrorChecks(True)
+ logger.configureCategory("MEMORY", logger.Severity.ERR);
+ logger.configureCategory("DEPREC", logger.Severity.ERR);
+ self.__testFuncName = testFuncName
+ self.__logger = avg.logger
+ self.__skipped = False
+ self.__warnOnImageDiff = False
+ self.__mouseEmulator = None
+
+ def __setupPlayer(self):
+ player.setMultiSampleSamples(1)
+ player.setResolution(0, 0, 0, 0)
+
+ @staticmethod
+ def setImageResultDirectory(name):
+ AVGTestCase.imageResultDirectory = name
+
+ @staticmethod
+ def getImageResultDir():
+ return AVGTestCase.imageResultDirectory
+
+ @staticmethod
+ def cleanResultDir():
+ dir = AVGTestCase.getImageResultDir()
+ try:
+ files = os.listdir(dir)
+ for file in files:
+ os.remove(dir+"/"+file)
+ except OSError:
+ try:
+ os.mkdir(dir)
+ except OSError:
+ pass
+
+ def start(self, warnOnImageDiff, actions):
+ self.__setupPlayer()
+ self.__dumpTestFrames = (os.getenv("AVG_DUMP_TEST_FRAMES") != None)
+ self.__delaying = False
+ self.__warnOnImageDiff = warnOnImageDiff
+
+ self.assert_(player.isPlaying() == 0)
+ self.actions = flatten(actions)
+ self.curFrame = 0
+ player.subscribe(player.ON_FRAME, self.__nextAction)
+ player.setFramerate(10000)
+ player.assumePixelsPerMM(1)
+ player.play()
+ self.assert_(player.isPlaying() == 0)
+
+ def delay(self, time):
+ def timeout():
+ self.__delaying = False
+ self.__delaying = True
+ player.setTimeout(time, timeout)
+
+ def compareImage(self, fileName):
+ bmp = player.screenshot()
+ self.compareBitmapToFile(bmp, fileName)
+
+ def compareBitmapToFile(self, bmp, fileName):
+ try:
+ baselineBmp = avg.Bitmap(AVGTestCase.baselineImageResultDirectory + "/"
+ + fileName + ".png")
+ except RuntimeError:
+ bmp.save(AVGTestCase.getImageResultDir()+"/"+fileName+".png")
+ self.__logger.warning("Could not load image "+fileName+".png")
+ raise
+ diffBmp = bmp.subtract(baselineBmp)
+ average = diffBmp.getAvg()
+ stdDev = diffBmp.getStdDev()
+ if (average > 0.1 or stdDev > 0.5):
+ if self._isCurrentDirWriteable():
+ bmp.save(AVGTestCase.getImageResultDir() + "/" + fileName + ".png")
+ baselineBmp.save(AVGTestCase.getImageResultDir() + "/" + fileName
+ + "_baseline.png")
+ diffBmp.save(AVGTestCase.getImageResultDir() + "/" + fileName
+ + "_diff.png")
+ if (average > 2 or stdDev > 6):
+ msg = (" "+fileName+
+ ": Difference image has avg=%(avg).2f, std dev=%(stddev).2f"%
+ {'avg':average, 'stddev':stdDev})
+ if self.__warnOnImageDiff:
+ sys.stderr.write("\n"+msg+"\n")
+ else:
+ self.fail(msg)
+
+ def areSimilarBmps(self, bmp1, bmp2, maxAvg, maxStdDev):
+ diffBmp = bmp1.subtract(bmp2)
+ avg = diffBmp.getAvg()
+ stdDev = diffBmp.getStdDev()
+ return avg <= maxAvg and stdDev <= maxStdDev
+
+ def assertException(self, code):
+ exceptionRaised = False
+ try:
+ code()
+ except:
+ exceptionRaised = True
+
+ self.assert_(exceptionRaised)
+
+ def assertAlmostEqual(self, a, b, epsilon=0.00001):
+ if not(almostEqual(a, b, epsilon)):
+ msg = "almostEqual: " + str(a) + " != " + str(b)
+ self.fail(msg)
+
+ def loadEmptyScene(self, resolution=(160,120)):
+ player.createMainCanvas(size=resolution)
+ root = player.getRootNode()
+ root.mediadir = "media"
+ return root
+
+ def initDefaultImageScene(self):
+ root = self.loadEmptyScene()
+ avg.ImageNode(id="testtiles", pos=(0,30), size=(65,65), href="rgb24-65x65.png",
+ maxtilewidth=16, maxtileheight=32, parent=root)
+ avg.ImageNode(id="test", pos=(64,30), href="rgb24-65x65.png", pivot=(0,0),
+ angle=0.274, parent=root)
+ avg.ImageNode(id="test1", pos=(129,30), href="rgb24-65x65.png", parent=root)
+
+ def fakeClick(self, x, y):
+ helper = player.getTestHelper()
+ helper.fakeMouseEvent(avg.Event.CURSOR_DOWN, True, False, False, x, y, 1)
+ helper.fakeMouseEvent(avg.Event.CURSOR_UP, False, False, False, x, y, 1)
+
+ def skip(self, message):
+ self.__skipReason = str(message)
+ sys.stderr.write("skipping: " + str(message) + " ... ")
+ self.__skipped = True
+
+ def skipped(self):
+ return self.__skipped
+
+ def skipReason(self):
+ return self.__skipReason
+
+ def skipIfMinimalShader(self):
+ if not(player.areFullShadersSupported()):
+ self.skip("Not supported if ShaderUsage == MINIMAL")
+ player.stop()
+ return
+
+ def _sendMouseEvent(self, type, x, y, btn=1):
+ if not self.__mouseEmulator:
+ self.__mouseEmulator = MouseEmulator()
+ self.__mouseEmulator.sendMouseEvent(type, x, y, btn)
+
+ def _sendTouchEvent(self, id, type, x, y):
+ helper = player.getTestHelper()
+ helper.fakeTouchEvent(id, type, avg.Event.TOUCH, avg.Point2D(x, y))
+
+ def _sendTouchEvents(self, eventData):
+ helper = player.getTestHelper()
+ for (id, type, x, y) in eventData:
+ helper.fakeTouchEvent(id, type, avg.Event.TOUCH, avg.Point2D(x, y))
+
+ def _genMouseEventFrames(self, type, x, y, expectedEvents):
+ return [
+ lambda: self._sendMouseEvent(type, x, y),
+ lambda: self.messageTester.assertState(expectedEvents),
+ ]
+
+ def _genTouchEventFrames(self, eventData, expectedEvents):
+ return [
+ lambda: self._sendTouchEvents(eventData),
+ lambda: self.messageTester.assertState(expectedEvents),
+ ]
+
+ def _isCurrentDirWriteable(self):
+ return bool(os.access('.', os.W_OK))
+
+ def __nextAction(self):
+ if not(self.__delaying):
+ if self.__dumpTestFrames:
+ self.__logger.log("Frame "+str(self.curFrame))
+ if len(self.actions) == self.curFrame:
+ player.stop()
+ else:
+ action = self.actions[self.curFrame]
+ if action != None:
+ action()
+ self.curFrame += 1
+
+
+def createAVGTestSuite(availableTests, AVGTestCaseClass, testSubset):
+ testNames = []
+ if testSubset:
+ for testName in testSubset:
+ if testName in availableTests:
+ testNames.append(testName)
+ else:
+ sys.stderr.write(("No test named %s"%testName) + "\n")
+ sys.exit(1)
+ else:
+ testNames = availableTests
+
+ suite = unittest.TestSuite()
+ for testName in testNames:
+ suite.addTest(AVGTestCaseClass(testName))
+
+ return suite
+
+
+class NodeHandlerTester(object):
+ def __init__(self, testCase, node):
+ self.__testCase = testCase
+ self.reset()
+ self.__node = node
+ self.__subscriberIDs = set()
+ self.setHandlers()
+ self.__messagesReceived = set()
+
+ def assertState(self, expectedMessages):
+ self.__testCase.assert_(self.isState(expectedMessages))
+ self.reset()
+
+ def isState(self, expectedMessages):
+ expectedMessages = set(expectedMessages)
+ if expectedMessages != self.__messagesReceived:
+ sys.stderr.write("\nState expected: "+str(expectedMessages)+"\n")
+ sys.stderr.write("Actual state: "+str(self.__messagesReceived)+"\n")
+ return False
+ else:
+ return True
+
+ def reset(self):
+ self.__messagesReceived = set()
+
+ def setHandlers(self):
+ messageIDs = [avg.Node.CURSOR_DOWN, avg.Node.CURSOR_UP, avg.Node.CURSOR_OVER,
+ avg.Node.CURSOR_OUT, avg.Node.CURSOR_MOTION]
+ for messageID in messageIDs:
+ subscriberID = self.__node.subscribe(messageID,
+ lambda event, messageID=messageID:
+ self.setMessageReceived(messageID, event))
+ self.__subscriberIDs.add(subscriberID)
+
+ def clearHandlers(self):
+ for subscriber in self.__subscriberIDs:
+ self.__node.unsubscribe(subscriber)
+ self.__subscriberIDs = set()
+
+ def setMessageReceived(self, messageID, event):
+ self.__messagesReceived.add(messageID)
+
+
+class MessageTester(object):
+
+ def __init__(self, publisher, messageIDs, testCase=None):
+ for messageID in messageIDs:
+ publisher.subscribe(messageID,
+ lambda messageID=messageID: self.setMessageReceived(messageID))
+ self.__messagesReceived = set()
+ self.__testCase = testCase
+
+ def assertState(self, expectedMessages):
+ self.__testCase.assert_(self.isState(expectedMessages))
+ self.reset()
+
+ def isState(self, expectedMessages):
+ expectedMessages = set(expectedMessages)
+ if expectedMessages != self.__messagesReceived:
+ sys.stderr.write("\nState expected: "+str(expectedMessages)+"\n")
+ sys.stderr.write("Actual state: "+str(self.__messagesReceived)+"\n")
+ return False
+ else:
+ return True
+
+ def setMessageReceived(self, messageID):
+ self.__messagesReceived.add(messageID)
+
+ def reset(self):
+ self.__messagesReceived = set()
+
diff --git a/src/test/testmediadir/mjpeg-48x48.avi b/src/test/testmediadir/mjpeg-48x48.avi
new file mode 100644
index 0000000..d62180a
--- /dev/null
+++ b/src/test/testmediadir/mjpeg-48x48.avi
Binary files differ
diff --git a/src/test/testmediadir/rgb24-64x64a.png b/src/test/testmediadir/rgb24-64x64a.png
new file mode 100644
index 0000000..41b69c3
--- /dev/null
+++ b/src/test/testmediadir/rgb24-64x64a.png
Binary files differ
diff --git a/src/utils/Makefile.am b/src/utils/Makefile.am
new file mode 100644
index 0000000..7527ad7
--- /dev/null
+++ b/src/utils/Makefile.am
@@ -0,0 +1,5 @@
+bin_SCRIPTS = avg_audioplayer.py avg_chromakey.py avg_showcamera.py avg_showfile.py \
+ avg_showfont.py avg_videoinfo.py avg_videoplayer.py avg_checkvsync.py \
+ avg_checktouch.py avg_showsvg.py avg_checkspeed.py \
+ avg_checkpolygonspeed.py avg_jitterfilter.py
+pkgpyexec_PYTHON = $(bin_SCRIPTS)
diff --git a/src/utils/avg_audioplayer.py b/src/utils/avg_audioplayer.py
new file mode 100755
index 0000000..1355bbf
--- /dev/null
+++ b/src/utils/avg_audioplayer.py
@@ -0,0 +1,49 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+# libavg - Media Playback Engine.
+# Copyright (C) 2003-2014 Ulrich von Zadow
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Current versions can be found at www.libavg.de
+
+import sys
+from libavg import avg, app, player
+
+
+class AudioPlayerDiv(app.MainDiv):
+ def onArgvParserCreated(self, parser):
+ parser.set_usage("%prog <filename>")
+
+ def onArgvParsed(self, options, args, parser):
+ if len(args) != 1:
+ parser.print_help()
+ sys.exit(1)
+ self._audioFName = args[0]
+
+ def onInit(self):
+ self._node = avg.SoundNode(parent=self, href=self._audioFName)
+ self._node.play()
+ self._words = avg.WordsNode(parent=self, pos=(10, 22), fontsize=10)
+
+ def onFrame(self):
+ curTime = self._node.getCurTime()
+ self._words.text = "Time: "+str(curTime/1000.0)
+
+
+if __name__ == "__main__":
+ app.App().run(AudioPlayerDiv(), app_resolution="320x200")
+
diff --git a/src/utils/avg_checkpolygonspeed.py b/src/utils/avg_checkpolygonspeed.py
new file mode 100755
index 0000000..409d3a3
--- /dev/null
+++ b/src/utils/avg_checkpolygonspeed.py
@@ -0,0 +1,145 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+# libavg - Media Playback Engine.
+# Copyright (C) 2003-2014 Ulrich von Zadow
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Current versions can be found at www.libavg.de
+#
+# Original author of this file is Robert Parcus <betoparcus@gmail.com>
+
+from libavg import *
+
+import random
+import math
+import time
+
+R = 40.0
+g_Trigger = True
+
+
+class SpeedDiv(app.MainDiv):
+ def onArgvParserCreated(self, parser):
+ usage = '%prog [options]\n' \
+ 'Checks libavg performance by creating lots of polygon nodes. ' \
+ 'Displays a frame time graph and executes for 20 secs.'
+ parser.set_usage(usage)
+
+ parser.add_option('--hole-polygon', '-y', dest='hole',
+ action='store_true', default=False,
+ help='generate polygons with holes')
+ parser.add_option('--create-nodes', '-c', dest='create',
+ action='store_true', default=False,
+ help='destroy and recreate all nodes every 400 ms')
+ parser.add_option('--move', '-m', dest='move',
+ action='store_true', default=False,
+ help='move nodes every frame')
+ parser.add_option('--vsync', '-s', dest='vsync',
+ action='store_true', default=False,
+ help='sync output to vertical refresh')
+ parser.add_option('--num-objs', '-n', dest='numObjs',
+ type='int', default=40,
+ help='number of polygons to create [Default: 40]')
+ parser.add_option('--num-points', '-x', dest='numPoints',
+ type='int', default=10,
+ help='number of points in each polygon [Default: 10]')
+ parser.add_option('--profile', '-p', dest='profile',
+ action='store_true', default=False,
+ help='enable profiling output, note that profiling makes things slower')
+
+ def onArgvParsed(self, options, args, parser):
+ self.__optHole = options.hole
+ self.__optCreate = options.create
+ self.__optMove = options.move
+ self.__optVsync = options.vsync
+ self.__optNumObjs = options.numObjs
+ if self.__optNumObjs < 1:
+ self.__optNumObjs = 40
+ self.__optNumPoints = options.numPoints
+ if self.__optNumPoints < 10:
+ self.__optNumPoints = 10
+ elif self.__optNumPoints % 2 != 0:
+ self.__optNumPoints -= 1
+
+ log = avg.logger
+ log.configureCategory(log.Category.CONFIG, log.Severity.DBG)
+ if options.profile:
+ log.configureCategory(log.Category.PROFILE, log.Severity.DBG)
+
+ def onInit(self):
+ if not self.__optVsync:
+ player.setFramerate(1000)
+
+ tstart = time.time()
+ self.__createNodes()
+ print 'Time to create nodes: %f' % (time.time()-tstart)
+ app.instance.debugPanel.toggleWidget(app.debugpanel.FrametimeGraphWidget)
+ if self.__optCreate:
+ player.setInterval(400, self.__createNodes)
+ # Ignore the first frame for the 20 sec-limit so long startup times don't
+ # break things.
+ player.setTimeout(0, lambda: player.setTimeout(20000, player.stop))
+
+ def onFrame(self):
+ if self.__optMove:
+ self.__moveNodes()
+
+ def __createNodes(self):
+ self.__nodes = []
+ for i in xrange(self.__optNumObjs):
+ pos = (random.randrange(800-64), random.randrange(600-64))
+ polyPos = self.__calPolyCords(pos, R)
+ holes = []
+ if self.__optHole:
+ holes = (self.__calPolyCords(pos, R/2), )
+ node = avg.PolygonNode(parent=self, pos=polyPos, fillopacity=1, holes=holes)
+ self.__nodes.append(node)
+ if self.__optCreate:
+ player.setTimeout(300, self.__deleteNodes)
+
+ def __deleteNodes(self):
+ for node in self.__nodes:
+ node.unlink(True)
+ self.__nodes = []
+
+ def __moveNodes(self):
+ global g_Trigger
+ for node in self.__nodes:
+ newPos = []
+ if g_Trigger:
+ newPos = [(i[0]+1, i[1]+1) for i in node.pos]
+ else:
+ newPos = [(i[0]-1, i[1]-1) for i in node.pos]
+ node.pos = newPos
+ g_Trigger = not g_Trigger
+
+ def __calPolyCords(self, offset, r):
+ r2 = r/2
+ alpha = math.radians(360.0 / (self.__optNumPoints/2))
+ beta = alpha/2
+ result = []
+ for i in xrange(self.__optNumPoints/2):
+ result.append((r*math.cos(i*alpha) + offset[0],
+ r*math.sin(i*alpha) + offset[1]))
+ result.append((r2*math.cos(i*alpha+beta) + offset[0],
+ r2*math.sin(i*alpha+beta) + offset[1]))
+ return result
+
+
+if __name__ == '__main__':
+ app.App().run(SpeedDiv(), app_resolution='800x600')
+
diff --git a/src/utils/avg_checkspeed.py b/src/utils/avg_checkspeed.py
new file mode 100755
index 0000000..87619df
--- /dev/null
+++ b/src/utils/avg_checkspeed.py
@@ -0,0 +1,141 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+# libavg - Media Playback Engine.
+# Copyright (C) 2003-2014 Ulrich von Zadow
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Current versions can be found at www.libavg.de
+#
+# Original author of this file is Robert Parcus <betoparcus@gmail.com>
+
+from libavg import *
+
+import random
+
+
+class SpeedDiv(app.MainDiv):
+ def onArgvParserCreated(self, parser):
+ usage = '%prog [options]\n' \
+ 'Checks libavg performance by creating lots of nodes. ' \
+ 'Displays a frame time graph and executes for 20 secs.'
+ parser.set_usage(usage)
+
+ parser.add_option('--use-fx', '-f', dest='useFX',
+ action='store_true', default=False,
+ help='display everything using a NullFX to test FX overhead')
+ parser.add_option('--video', '-i', dest='video',
+ action='store_true', default=False,
+ help='show videos instead of images')
+ parser.add_option('--audio', '-a', dest='audio',
+ action='store_true', default=False,
+ help='when showing videos, use videos with an audio channel')
+ parser.add_option('--create-nodes', '-c', dest='create',
+ action='store_true', default=False,
+ help='destroy and recreate all nodes every 400 ms')
+ parser.add_option('--move', '-m', dest='move',
+ action='store_true', default=False,
+ help='move nodes every frame')
+ parser.add_option('--blur', '-b', dest='blur',
+ action='store_true', default=False,
+ help='apply a BlurFXNode to the nodes')
+ parser.add_option('--color', '-o', dest='color',
+ action='store_true', default=False,
+ help='apply gamma to the nodes, causing the color correction shader to activate')
+ parser.add_option('--vsync', '-s', dest='vsync',
+ action='store_true', default=False,
+ help='sync output to vertical refresh')
+ parser.add_option('--num-objs', '-n', dest='numObjs',
+ type='int', default=-1,
+ help='number of objects to create [Default: 200 images or 40 videos]')
+ parser.add_option('--profile', '-p', dest='profile',
+ action='store_true', default=False,
+ help='enable profiling output, note that profiling makes things slower')
+
+ def onArgvParsed(self, options, args, parser):
+ self.__optUseFX = options.useFX
+ self.__optVideo = options.video
+ self.__optAudio = options.audio
+ self.__optCreate = options.create
+ self.__optMove = options.move
+ self.__optBlur = options.blur
+ self.__optColor = options.color
+ self.__optVsync = options.vsync
+ self.__optNumObjs = options.numObjs
+ if self.__optNumObjs < 1:
+ if self.__optVideo:
+ self.__optNumObjs = 40
+ else:
+ self.__optNumObjs = 200
+
+ log = avg.logger
+ log.configureCategory(log.Category.CONFIG, log.Severity.DBG)
+ if options.profile:
+ log.configureCategory(log.Category.PROFILE, log.Severity.DBG)
+
+ def onInit(self):
+ if not self.__optVsync:
+ player.setFramerate(1000)
+
+ self.mediadir = utils.getMediaDir(None, 'data')
+ self.__createNodes()
+ app.instance.debugPanel.toggleWidget(app.debugpanel.FrametimeGraphWidget)
+ if self.__optCreate:
+ player.setInterval(400, self.__createNodes)
+ # Ignore the first frame for the 20 sec-limit so long startup times don't
+ # break things.
+ player.setTimeout(0, lambda: player.setTimeout(20000, player.stop))
+
+ def onFrame(self):
+ if self.__optMove:
+ self.__moveNodes()
+
+ def __createNodes(self):
+ self.__nodes = []
+ for i in xrange(self.__optNumObjs):
+ pos = (random.randrange(800-64), random.randrange(600-64))
+ if self.__optVideo:
+ if self.__optAudio:
+ fname = "mpeg1-48x48-sound.avi"
+ else:
+ fname = "mpeg1-48x48.mov"
+ node = avg.VideoNode(pos=pos, href=fname, loop=True, parent=self)
+ node.play()
+ else:
+ node = avg.ImageNode(pos=pos, href="rgb24alpha-64x64.png", parent=self)
+ if self.__optUseFX:
+ node.setEffect(avg.NullFXNode())
+ if self.__optBlur:
+ node.setEffect(avg.BlurFXNode(10))
+ if self.__optColor:
+ node.gamma = (1.1, 1.1, 1.1)
+ self.__nodes.append(node)
+ if self.__optCreate:
+ player.setTimeout(300, self.__deleteNodes)
+
+ def __deleteNodes(self):
+ for node in self.__nodes:
+ node.unlink(True)
+ self.__nodes = []
+
+ def __moveNodes(self):
+ for node in self.__nodes:
+ node.pos = (random.randrange(800-64), random.randrange(600-64))
+
+
+if __name__ == '__main__':
+ app.App().run(SpeedDiv(), app_resolution='800x600')
+
diff --git a/src/utils/avg_checktouch.py b/src/utils/avg_checktouch.py
new file mode 100755
index 0000000..15c0ccd
--- /dev/null
+++ b/src/utils/avg_checktouch.py
@@ -0,0 +1,57 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+# libavg - Media Playback Engine.
+# Copyright (C) 2003-2014 Ulrich von Zadow
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Current versions can be found at www.libavg.de
+
+from libavg import *
+
+
+class TouchApp(app.MainDiv):
+ def onArgvParsed(self, options, args, parser):
+ if self.settings.getBoolean("app_fullscreen"):
+ self.settings.set("app_resolution", "") # use screen resolution
+
+ def onInit(self):
+ self.subscribe(avg.Node.CURSOR_DOWN, self.__onDown)
+ app.instance.debugPanel.toggleTouchVisualization()
+
+ def __onDown(self, event):
+# if event.source == avg.MOUSE:
+# print event.type, event.button
+# else:
+# print event.type
+ if (event.contact):
+ event.contact.subscribe(avg.Contact.CURSOR_MOTION, self.__onContact)
+ event.contact.subscribe(avg.Contact.CURSOR_UP, self.__onContact)
+ contact = event.contact
+# print "new contact: ", contact.id, event.pos, contact.age, \
+# contact.distancefromstart, contact.motionangle, contact.motionvec, \
+# contact.distancetravelled
+
+ def __onContact(self, event):
+ contact = event.contact
+# print event.type, contact.id, event.pos, contact.age, \
+# contact.distancefromstart, contact.motionangle, contact.motionvec, \
+# contact.distancetravelled, event.speed
+
+
+if __name__ == "__main__":
+ app.App().run(TouchApp(), app_resolution="800x600", multitouch_enabled="true")
+
diff --git a/src/utils/avg_checkvsync.py b/src/utils/avg_checkvsync.py
new file mode 100755
index 0000000..5dc89ce
--- /dev/null
+++ b/src/utils/avg_checkvsync.py
@@ -0,0 +1,44 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+# libavg - Media Playback Engine.
+# Copyright (C) 2003-2014 Ulrich von Zadow
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Current versions can be found at www.libavg.de
+#
+# Original author of this file is Robert Parcus <betoparcus@gmail.com>
+
+
+from libavg import avg, app
+
+
+class VSyncDiv(app.MainDiv):
+ def onInit(self):
+ self.__line = avg.LineNode(color='FFFFFF', parent=self)
+ self.__x = 0
+
+ def onFrame(self):
+ self.__x += 1
+ if self.__x == self.width:
+ self.__x = 0
+ self.__line.pos1 = (self.__x, 0)
+ self.__line.pos2 = (self.__x, self.height)
+
+
+if __name__ == '__main__':
+ app.App().run(VSyncDiv(), app_resolution='800x600')
+
diff --git a/src/utils/avg_chromakey.py b/src/utils/avg_chromakey.py
new file mode 100755
index 0000000..f572488
--- /dev/null
+++ b/src/utils/avg_chromakey.py
@@ -0,0 +1,189 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+# libavg - Media Playback Engine.
+# Copyright (C) 2003-2014 Ulrich von Zadow
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Current versions can be found at www.libavg.de
+
+from libavg import avg, app, widget
+from libavg import parsecamargs
+
+GUI_SIZE=(300, 526)
+
+
+class FXSlider(avg.DivNode):
+ def __init__(self, row, min, max, fxNode, fxAttrName, caption, isInt, parent=None,
+ **kwargs):
+ super(FXSlider, self).__init__(**kwargs)
+ if parent:
+ parent.appendChild(self)
+ avg.RectNode(pos=(0,8), size=(280,38), color="808080", strokewidth=2, parent=self)
+ textBgRect = avg.RectNode(pos=(8,2), fillcolor="000000", fillopacity=1,
+ strokewidth=0, parent=self)
+ caption = avg.WordsNode(pos=(10,0), text=caption, parent=self)
+ textBgRect.size = caption.getMediaSize() + (4,2)
+ self.__words = avg.WordsNode(pos=(240,23), parent=self)
+ self.__slider = widget.Slider(width=220, range=(min,max), pos=(15,20), parent=self)
+ self.__slider.subscribe(self.__slider.THUMB_POS_CHANGED, self.__onSliderMove)
+ self.pos = (0, row*46)
+ self.__fxNode = fxNode
+ self.__fxAttrName = fxAttrName
+ self.__caption = caption
+ self.__isInt = isInt
+ self.__slider.thumbPos = getattr(self.__fxNode, fxAttrName)
+ self.__onSliderMove(self.__slider.thumbPos)
+
+ def __onSliderMove(self, thumbPos):
+ if self.__isInt:
+ setattr(self.__fxNode, self.__fxAttrName, int(thumbPos))
+ self.__words.text = "%i"%thumbPos
+ else:
+ setattr(self.__fxNode, self.__fxAttrName, thumbPos)
+ self.__words.text = "%.2f"%thumbPos
+
+
+def colorToString(colorTuple):
+ s = "%02X%02X%02X"%colorTuple[:-1]
+ return s
+
+
+class Chromakey(app.MainDiv):
+ def onArgvParserCreated(self, parser):
+ parser.set_usage(usage)
+ parsecamargs.addOptions(parser)
+
+ def onArgvParsed(self, options, args, parser):
+ if options.driver is None:
+ parser.print_help()
+ print
+ print "ERROR: at least '--driver' must be specified"
+ exit(1)
+
+ self.__optWidth = options.width
+ self.__optHeight = options.height
+ self.__optsCam = {
+ "driver": options.driver,
+ "device": options.device,
+ "unit": options.unit,
+ "fw800": options.fw800,
+ "pixelformat": options.pixelFormat,
+ "framerate": options.framerate}
+
+ self.settings.set("app_resolution", "%dx%d"
+ %(GUI_SIZE[0]+options.width, max(GUI_SIZE[1], options.height)))
+
+ def onInit(self):
+ avg.RectNode(size=(self.__optWidth,self.__optHeight), fillcolor="FF0000",
+ fillopacity=1, strokewidth=0, parent=self)
+ self.__camNode = avg.CameraNode(
+ capturewidth=self.__optWidth, captureheight=self.__optHeight,
+ width=self.__optWidth, height=self.__optHeight, parent=self,
+ **self.__optsCam)
+ self.__camNode.play()
+ self.__filter = avg.ChromaKeyFXNode()
+ self.__camNode.setEffect(self.__filter)
+ self.__filter.color = "0000FF"
+ self.__filter.htolerance = 0.05
+ self.__filter.stolerance = 1.0
+ self.__filter.ltolerance = 1.0
+ self.__filter.softness = 0.0
+
+ self.__createGUI()
+
+ def __createGUI(self):
+ self.__guiDiv = avg.DivNode(pos=(self.__optWidth+10,10), parent=self)
+
+ self.__colorWords = avg.WordsNode(pos=(0,14), parent=self.__guiDiv)
+ self.__colorWords.text = "Key Color: "+self.__filter.color
+ self.__colorRect = avg.RectNode(pos=(200,12), size=(20, 20),
+ fillcolor=self.__filter.color, fillopacity=1,
+ color="FFFFFF", parent=self.__guiDiv)
+ self.__camNode.subscribe(avg.Node.CURSOR_DOWN, self.__onColorDown)
+
+ FXSlider(1, 0.0, 1.0, self.__filter, "htolerance", "Hue Tolerance",
+ False, parent=self.__guiDiv)
+ FXSlider(2, 0.0, 1.0, self.__filter, "stolerance", "Saturation Tolerance",
+ False, parent=self.__guiDiv)
+ FXSlider(3, 0.0, 1.0, self.__filter, "ltolerance", "Lightness Tolerance",
+ False, parent=self.__guiDiv)
+ FXSlider(4, 0.0, 1.0, self.__filter, "softness", "Softness",
+ False, parent=self.__guiDiv)
+ FXSlider(5, 0, 8, self.__filter, "erosion", "Erosion",
+ True, parent=self.__guiDiv)
+ FXSlider(6, 0.0, 1.0, self.__filter, "spillthreshold", "Spill Suppression",
+ False, parent=self.__guiDiv)
+
+ button = widget.TextButton(pos=(0,332), text="Whitebalance", size=(100,22),
+ parent=self.__guiDiv)
+ button.subscribe(button.CLICKED, self.__onWhitebalance)
+ button = widget.TextButton(pos=(110,332), text="Dump Config", size=(100,22),
+ parent=self.__guiDiv)
+ button.subscribe(button.CLICKED, self.__dumpConfig)
+
+ FXSlider(9, 0, 500, self.__camNode, "shutter", "Shutter",
+ True, parent=self.__guiDiv)
+ FXSlider(10, 128, 1023, self.__camNode, "gain", "Gain",
+ True, parent=self.__guiDiv)
+
+ def __onColorDown(self, event):
+ pos = self.__camNode.getRelPos(event.pos)
+ bmp = self.__camNode.getBitmap()
+ color = bmp.getPixel(pos)
+ colorString = colorToString(color)
+ self.__filter.color = colorString
+ self.__colorWords.text = "Key Color: "+colorString
+ self.__colorRect.fillcolor = colorString
+
+ def __onWhitebalance(self):
+ self.__camNode.setWhitebalance(
+ self.__camNode.getWhitebalanceU(), self.__camNode.getWhitebalanceV())
+ self.__camNode.doOneShotWhitebalance()
+
+ def __dumpConfig(self):
+ print "Camera:"
+ print " device=", self.__camNode.device
+ print " shutter=", self.__camNode.shutter
+ print " gain=", self.__camNode.gain
+ print " White Balance: (u=", self.__camNode.getWhitebalanceU(), ", v=", \
+ self.__camNode.getWhitebalanceV()
+
+ print "Chromakey:"
+ print " color=", self.__filter.color
+ print " htolerance=", self.__filter.htolerance
+ print " stolerance=", self.__filter.stolerance
+ print " ltolerance=", self.__filter.ltolerance
+ print " softness=", self.__filter.softness
+ print " erosion=", self.__filter.erosion
+ print " spillthreshold=", self.__filter.spillthreshold
+
+
+usage = """%prog [options]
+
+avg_chromakey.py is a configuration utility for the libavg chromakey filter.
+The chromakey filter allows implementation of green- or bluescreens with
+libavg.
+
+This utility shows a camera image with chromakey applied to it and allows the
+user to adjust the camera and filter parameters. The parameters can be dumped
+to the console for easy inclusion in libavg scripts.
+"""
+
+
+if __name__ == "__main__":
+ app.App().run(Chromakey())
+
diff --git a/src/utils/avg_jitterfilter.py b/src/utils/avg_jitterfilter.py
new file mode 100755
index 0000000..6b0f2cb
--- /dev/null
+++ b/src/utils/avg_jitterfilter.py
@@ -0,0 +1,111 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+# libavg - Media Playback Engine.
+# Copyright (C) 2003-2014 Ulrich von Zadow
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Current versions can be found at www.libavg.de
+
+from libavg import avg, app, player, filter, widget
+
+
+class LabledSlider(avg.DivNode):
+ def __init__(self, label, range, formatStr, parent=None, **kwargs):
+ super(LabledSlider, self).__init__(**kwargs)
+ self.registerInstance(self, parent)
+ self.__formatStr = formatStr
+
+ fontStyle = widget.Skin.default.fonts["stdFont"]
+ avg.WordsNode(text=label, fontstyle=fontStyle, color="FFFFFF", parent=self)
+ self.__slider = widget.Slider(width=300, range=range, pos=(15,20), parent=self)
+ self.__slider.subscribe(self.__slider.THUMB_POS_CHANGED, self.__onSliderMove)
+ self.__valueDisplay = avg.WordsNode(pos=(320, 18), fontstyle=fontStyle,
+ color="FFFFFF", parent=self)
+ self.__valueDisplay.text = self.__formatStr%self.__slider.thumbPos
+
+ self.publish(widget.Slider.THUMB_POS_CHANGED)
+
+ def getThumbPos(self):
+ return self.__slider.thumbPos
+ thumbPos = property(getThumbPos)
+
+ def __onSliderMove(self, thumbPos):
+ self.notifySubscribers(widget.Slider.THUMB_POS_CHANGED, [thumbPos,])
+ self.__valueDisplay.text = self.__formatStr%thumbPos
+
+
+class JitterFilter(app.MainDiv):
+ def onArgvParsed(self, options, args, parser):
+ if self.settings.getBoolean("app_fullscreen"):
+ self.settings.set("app_resolution", "") # use screen resolution
+
+ def onInit(self):
+ self.__minCutoffSlider = LabledSlider(label="Minimum Cutoff", range=(0.3, 8.0),
+ formatStr="%.1f", pos=(10,10), parent=self)
+ self.__minCutoffSlider.subscribe(widget.Slider.THUMB_POS_CHANGED,
+ self.__onSliderMove)
+ self.__cutoffSlopeSlider = LabledSlider(label="Cutoff Slope", range=(0.0, 0.05),
+ formatStr="%.3f", pos=(10,50), parent=self)
+ self.__minCutoffSlider.subscribe(widget.Slider.THUMB_POS_CHANGED,
+ self.__onSliderMove)
+ self.__onSliderMove(avg.Point2D(0,0))
+
+ self.subscribe(avg.Node.CURSOR_DOWN, self.__onDown)
+ self.__contact = None
+ self.__rawContactCircle = avg.CircleNode(r=7*player.getPixelsPerMM(),
+ color="FF0000", opacity=0, parent=self)
+ self.__filteredContactCircle = avg.CircleNode(r=7*player.getPixelsPerMM(),
+ color="00FF00", opacity=0, parent=self)
+ self.__filters = None
+
+ def __onSliderMove(self, pos):
+ self.__minCutoff = self.__minCutoffSlider.thumbPos
+ self.__cutoffSlope = self.__cutoffSlopeSlider.thumbPos
+
+ def __onDown(self, event):
+ if self.__contact is None:
+ self.__contact = event.contact
+ event.contact.subscribe(avg.Contact.CURSOR_UP, self.__onUp)
+ self.__rawContactCircle.opacity = 1
+ self.__filteredContactCircle.opacity = 1
+ self.__filters = [
+ filter.OneEuroFilter(self.__minCutoff,self.__cutoffSlope),
+ filter.OneEuroFilter(self.__minCutoff,self.__cutoffSlope)]
+ self.__onFrame = player.subscribe(player.ON_FRAME, self.__moveContact)
+
+ def __onUp(self, event):
+ self.__rawContactCircle.opacity = 0
+ self.__filteredContactCircle.opacity = 0
+ self.__contact = None
+ self.__filters = None
+ player.unsubscribe(self.__onFrame)
+
+ def __moveContact(self):
+ time = player.getFrameTime()
+ rawPos = self.__contact.events[-1].pos
+ self.__rawContactCircle.pos = rawPos
+ filteredPos = avg.Point2D(self.__filters[0].apply(rawPos.x, time),
+ self.__filters[1].apply(rawPos.y, time))
+ self.__filteredContactCircle.pos = filteredPos
+
+
+if __name__ == "__main__":
+ app.App().run(JitterFilter(),
+ app_resolution="800x600",
+ app_show_cursor="true",
+ multitouch_enabled="true")
+
diff --git a/src/utils/avg_showcamera.py b/src/utils/avg_showcamera.py
new file mode 100755
index 0000000..4c2cc18
--- /dev/null
+++ b/src/utils/avg_showcamera.py
@@ -0,0 +1,201 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+# libavg - Media Playback Engine.
+# Copyright (C) 2003-2014 Ulrich von Zadow
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Current versions can be found at www.libavg.de
+
+import time
+from libavg import avg, player
+from libavg import parsecamargs
+from libavg import app
+
+usage = """%prog [options]
+
+avg_showcamera.py shows the images captured by a camera attached to the
+system. Its main use is to find out which parameters - device names,
+image formats, framerates, etc. can be used with the camera(s)."""
+
+
+class ShowCamera(app.MainDiv):
+ def onArgvParserCreated(self, parser):
+ parser.set_usage(usage)
+ parsecamargs.addOptions(parser)
+ parser.add_option("-l", "--list", dest="list",
+ action="store_true", default=False,
+ help="lists informations about detected cameras")
+ parser.add_option("-s", "--noinfo", dest="noinfo",
+ action="store_true", default=False,
+ help="don't show any info overlayed on the screen")
+ parser.add_option("-r", "--resetbus", dest="resetbus",
+ action="store_true", default=False,
+ help="reset the firewire bus")
+
+ def onArgvParsed(self, options, args, parser):
+ if options.list:
+ infoList = list()
+ infoList = avg.CameraNode.getCamerasInfos()
+ if (len(infoList) <= 0):
+ print "No camera available!"
+ for info in infoList:
+ print ""
+ print "##################",info.driver,"##################"
+ print "Device ID:", info.deviceID
+ print ""
+ print "----------------- FORMATS ------------------"
+ formatsList = list()
+ formatsList = info.imageFormats
+ for format in formatsList:
+ print "++++"
+ print "Pixelformat:", format.pixelFormat
+ print "Resolution:", format.size
+ print "Framerates: |",
+ framerateList = list()
+ framerateList = format.framerates
+ for framerate in framerateList:
+ print framerate, "|",
+ print ""
+ print ""
+ print "----------------- CONTROLS -----------------"
+ controlsList = list()
+ controlsList = info.controls
+ for control in controlsList:
+ print "++++", control.controlName
+ print "Min:" , control.min, "| Max:", control.max,
+ print "| Default:", control.default
+ print ""
+ exit(0)
+
+ if options.resetbus:
+ avg.logger.info("Resetting firewire bus.")
+ avg.CameraNode.resetFirewireBus()
+ time.sleep(1)
+ if not options.driver:
+ exit(0)
+
+ if options.driver is None and not options.list and not options.resetbus:
+ parser.print_help()
+ print
+ print "ERROR: at least '--driver', '--list' or '--resetbus' options " \
+ "must be specified"
+ exit(1)
+
+ self.optdict = {}
+ for attr in dir(options):
+ if attr[0] != '_':
+ self.optdict[attr] = eval("options.%s" %attr)
+
+ self.settings.set("app_resolution", "%dx%d" %(options.width, options.height))
+
+ def onInit(self):
+ self.curFrame = 0
+
+ avg.logger.info("Creating camera:")
+ avg.logger.info("driver=%(driver)s device=%(device)s" %self.optdict)
+ avg.logger.info(
+ "width=%(width)d height=%(height)d pixelformat=%(pixelFormat)s"
+ %self.optdict)
+ avg.logger.info("unit=%(unit)d framerate=%(framerate)d fw800=%(fw800)s"
+ %self.optdict)
+
+ self.camNode = avg.CameraNode(driver=self.optdict["driver"],
+ device=self.optdict["device"], unit=self.optdict["unit"],
+ fw800=self.optdict["fw800"], framerate=self.optdict["framerate"],
+ capturewidth=self.optdict["width"], captureheight=self.optdict["height"],
+ pixelformat=self.optdict["pixelFormat"], parent=self)
+
+ if not self.optdict["noinfo"]:
+ self.infoText = ("Driver=%(driver)s (dev=%(device)s unit=%(unit)d) "
+ "%(width)dx%(height)d@%(framerate)f" %self.optdict)
+ avg.WordsNode(text=self.infoText, color="ff3333", pos=(5,5), fontsize=14,
+ rawtextmode=True, parent=self)
+ self.frameText = avg.WordsNode(color="ff3333", pos=(5,25), fontsize=14,
+ parent=self)
+ else:
+ self.frameText = None
+
+ self.setupKeys()
+
+ self.camNode.play()
+ player.setTimeout(100, self.checkCamera)
+
+ def onFrame(self):
+ if self.frameText:
+ self.curFrame += 1
+ self.frameText.text = "%(cam)d/%(app)d" \
+ %{"cam":self.camNode.framenum, "app":self.curFrame}
+
+ def checkCamera(self):
+ if not(self.camNode.isAvailable()):
+ avg.logger.error("Could not open camera")
+ exit(1)
+
+ def setupKeys(self):
+ def setWhitebalance():
+ print "Setting whitebalance"
+ self.camNode.doOneShotWhitebalance()
+
+ def addWhitebalance(du = 0, dv = 0):
+ self.camNode.setWhitebalance(self.camNode.getWhitebalanceU() + du,
+ self.camNode.getWhitebalanceV() + dv)
+ print ("u:", self.camNode.getWhitebalanceU(), "v:",
+ self.camNode.getWhitebalanceV())
+
+ def addGain(gain):
+ self.camNode.gain += gain
+ print "gain:", self.camNode.gain
+
+ def addShutter(shutter):
+ self.camNode.shutter += shutter
+ print "shutter:", self.camNode.shutter
+
+ app.keyboardmanager.bindKeyDown(keystring="w",
+ handler=setWhitebalance,
+ help="Execute whitebalance")
+
+ app.keyboardmanager.bindKeyDown(keystring="1",
+ handler=lambda: addWhitebalance(du = -1),
+ help="Decrease whitebalance u")
+ app.keyboardmanager.bindKeyDown(keystring="2",
+ handler=lambda: addWhitebalance(du = 1),
+ help="Increase whitebalance u")
+ app.keyboardmanager.bindKeyDown(keystring="3",
+ handler=lambda: addWhitebalance(dv = -1),
+ help="Decrease whitebalance v")
+ app.keyboardmanager.bindKeyDown(keystring="4",
+ handler=lambda: addWhitebalance(dv = 1),
+ help="Increase whitebalance v")
+
+ app.keyboardmanager.bindKeyDown(keystring="left",
+ handler=lambda: addShutter(shutter = -1),
+ help="Decrease shutter")
+ app.keyboardmanager.bindKeyDown(keystring="right",
+ handler=lambda: addShutter(shutter = 1),
+ help="Increase shutter")
+
+ app.keyboardmanager.bindKeyDown(keystring="up",
+ handler=lambda: addGain(gain = 1),
+ help="Increase gain")
+ app.keyboardmanager.bindKeyDown(keystring="down",
+ handler=lambda: addGain(gain = -1),
+ help="Decrease gain")
+
+
+if __name__ == "__main__":
+ app.App().run(ShowCamera())
+
diff --git a/src/utils/avg_showfile.py b/src/utils/avg_showfile.py
new file mode 100755
index 0000000..748037c
--- /dev/null
+++ b/src/utils/avg_showfile.py
@@ -0,0 +1,38 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# libavg - Media Playback Engine.
+# Copyright (C) 2003-2014 Ulrich von Zadow
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Current versions can be found at www.libavg.de
+#
+
+import sys
+from libavg import player
+
+if len(sys.argv) ==1:
+ print
+ print "avg_showfile.py displays the contents of an avg file."
+ print
+ print "Usage: avg_showfile.py <avgfile>"
+ print
+ sys.exit(1)
+
+player.loadFile(sys.argv[1])
+player.play()
+
+
diff --git a/src/utils/avg_showfont.py b/src/utils/avg_showfont.py
new file mode 100755
index 0000000..fa4c562
--- /dev/null
+++ b/src/utils/avg_showfont.py
@@ -0,0 +1,68 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+# libavg - Media Playback Engine.
+# Copyright (C) 2003-2014 Ulrich von Zadow
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Current versions can be found at www.libavg.de
+
+from libavg import avg, app
+
+
+class ShowFont(app.MainDiv):
+ def onArgvParserCreated(self, parser):
+ self._usage = 'Usage: %s [<fontname> [<text>]] [options]\n\n' \
+ ' Shows all available variants of a font.\n' \
+ ' If <text> is given, displays the text.\n' \
+ ' If <fontname> is not given, dumps a list of all fonts available.' \
+ %parser.get_prog_name()
+ parser.set_usage(self._usage)
+
+ def onArgvParsed(self, options, args, parser):
+ if len(args) == 0:
+ fontList = avg.WordsNode.getFontFamilies()
+ print 'Available fonts:'
+ print fontList
+ print
+ print self._usage
+ print ' Option -h or --help gives a full help.'
+ exit()
+
+ self._fontname = args[0]
+ if len(args) > 1:
+ self._displayText = args[1]
+ else:
+ self._displayText = None
+
+ def onInit(self):
+ variants = avg.WordsNode.getFontVariants(self._fontname)
+ print variants
+
+ y = 10
+ for variant in variants:
+ if self._displayText:
+ text = self._displayText
+ else:
+ text = self._fontname + ": " + variant
+ avg.WordsNode(text=text, font=self._fontname, variant=variant, fontsize=24,
+ pos=(10, y), parent=self)
+ y += 50
+
+
+if __name__ == '__main__':
+ app.App().run(ShowFont())
+
diff --git a/src/utils/avg_showsvg.py b/src/utils/avg_showsvg.py
new file mode 100755
index 0000000..915ae40
--- /dev/null
+++ b/src/utils/avg_showsvg.py
@@ -0,0 +1,63 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+# libavg - Media Playback Engine.
+# Copyright (C) 2003-2014 Ulrich von Zadow
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Current versions can be found at www.libavg.de
+#
+
+import sys
+
+from libavg import avg, app
+
+
+class ShowSVG(app.MainDiv):
+ def onArgvParserCreated(self, parser):
+ parser.set_usage("%prog [options] <svgFileName> <elementID>")
+
+ parser.add_option("-s", "--size", dest="size",
+ type="float", default=1.0,
+ help="specify a factor for the size of the element [Default: 1.0]")
+ parser.add_option("--save-image", dest="saveImage",
+ action="store_true", default=False,
+ help="save the image rendered to a png file")
+
+ def onArgvParsed(self, options, args, parser):
+ if len(args) != 2:
+ parser.print_help()
+ sys.exit(1)
+ self._svgFName = args[0]
+ self._svgID = args[1]
+ self._size = options.size
+ self._saveImage = options.saveImage
+
+ def onInit(self):
+ self.svg = avg.SVG(self._svgFName, True)
+ img = self.svg.createImageNode(self._svgID, {"pos":(1,1), "parent":self},
+ self._size)
+ rect = avg.RectNode(fillcolor="808080", color="FFFFFF", fillopacity=1,
+ pos=(0.5, 0.5), size=img.size+(1,1))
+ self.insertChild(rect, 0)
+ if self._saveImage:
+ bmp = self.svg.renderElement(self._svgID, self._size)
+ bmp.save(self._svgID+".png")
+
+
+if __name__ == "__main__":
+ app.App().run(ShowSVG(), app_resolution="1024x768")
+
diff --git a/src/utils/avg_videoinfo.py b/src/utils/avg_videoinfo.py
new file mode 100755
index 0000000..1d7c41a
--- /dev/null
+++ b/src/utils/avg_videoinfo.py
@@ -0,0 +1,275 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# libavg - Media Playback Engine.
+# Copyright (C) 2003-2014 Ulrich von Zadow
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Current versions can be found at www.libavg.de
+#
+
+from optparse import OptionParser
+import sys
+from libavg import avg
+from xml.dom import minidom
+import os
+
+parser = OptionParser(usage="%prog filename(s) [options]")
+parser.add_option("-x", "--xml", dest = "xml", action = "store_true",
+ help = "Output in XML format")
+parser.add_option("-c", "--csv", dest = "csv", action = "store_true",
+ help = "Output in csv format")
+parser.add_option("-r", "--recursion", dest = "recursion", action = "store_true",
+ help = "Recurse into subdirectories")
+options, args = parser.parse_args()
+
+def sortByName(a, b):
+ if a < b:
+ return -1
+ else:
+ return 1
+
+class OutputHandler(object):
+
+ def __init__(self, args):
+ self._node = avg.VideoNode()
+ self.__getFileNames(args)
+
+ def __getFileNames(self, args):
+ self._fileNameList = []
+ filePaths = []
+ for arg in args:
+ if arg == ".":
+ filePaths.extend(os.listdir(os.curdir))
+ if options.recursion:
+ for folder in filePaths:
+ if os.path.isdir(folder):
+ filePaths.extend(self.__getFilesInFolder(folder))
+ elif arg == ".." or os.path.isdir(arg):
+ filePaths.extend(self.__getFilesInFolder(arg))
+ else:
+ if os.path.isfile(arg):
+ filePaths.append(arg)
+
+ for file in filePaths:
+ try:
+ if os.path.isfile(file):
+ self._node.href = str(file)
+ self._node.play()
+ self._fileNameList.append(self._node.href)
+ except RuntimeError, err:
+ sys.stderr.write(str(err) + "\n")
+ self._node = avg.VideoNode()
+ self._fileNameList.sort(cmp=sortByName)
+
+ def __getFilesInFolder(self, folder):
+ folderFiles = []
+ newFiles = os.listdir(folder)
+ for newfile in newFiles:
+ if folder == "..":
+ testFile = "../"+newfile
+ else:
+ testFile = str(folder)+"/"+newfile
+ if os.path.isfile(testFile):
+ folderFiles.append(testFile)
+ if options.recursion and os.path.isdir(testFile):
+ folderFiles.extend(self.__getFilesInFolder(testFile))
+ return folderFiles
+
+
+class ConsoleOutputHandler(OutputHandler):
+
+ def __init__(self, args):
+ super(ConsoleOutputHandler, self).__init__(args)
+ if self._fileNameList == []:
+ print "No valid video files found."
+ printHelp()
+
+ def output(self):
+ if len(self._fileNameList) == 1:
+ self.__outputSingleFile(self._fileNameList[0])
+ else:
+ self.__outputTable()
+
+ def __outputSingleFile(self, filename):
+ self._node.href = filename
+ print "File: " + self._node.href
+ print ("Duration: " + str(self._node.getDuration()/1000.) + " s ("
+ + str(self._node.getNumFrames()) + " frames)")
+ print "Bitrate: " + str(self._node.getBitrate()) + " b/s"
+ print "Video stream: "
+ print " Codec: " + self._node.getVideoCodec()
+ print " Size: " + str(self._node.getMediaSize())
+ print " Pixel format: " + self._node.getStreamPixelFormat()
+ print " FPS: " + str(self._node.fps)
+ print " Duration: " + str(self._node.getVideoDuration()/1000.) + " s"
+ if self._node.hasAudio():
+ print "Audio stream: "
+ print " Codec: " + self._node.getAudioCodec()
+ print " Sample rate: " + str(self._node.getAudioSampleRate()) + " Hz"
+ print " Channels: " + str(self._node.getNumAudioChannels())
+ print " Duration: " + str(self._node.getAudioDuration()/1000.) + " s"
+
+ def __outputTable(self):
+ self.__filenameLen = 8
+ self.__videoCodecLen = 5
+ self.__videoFormatLen = 6
+ self.__audioCodecLen = 5
+
+ for filename in self._fileNameList:
+ self._node.href = filename
+ self._node.play()
+ self.__filenameLen = max(self.__filenameLen, len(filename))
+ curLen = len(self._node.getVideoCodec())
+ self.__videoCodecLen = max(self.__videoCodecLen, curLen)
+ curLen = len(self._node.getStreamPixelFormat())
+ self.__videoFormatLen = max(self.__videoFormatLen, curLen)
+ if self._node.hasAudio():
+ curLen = len(self._node.getAudioCodec())
+ self.__audioCodecLen = max(self.__audioCodecLen, curLen)
+
+ self.__outputTableHeader()
+
+ for filename in self._fileNameList:
+ self._node.href = filename
+ self.__outputTableLine(self._node)
+
+ def __outputTableHeader(self):
+ vFile = "Filename".ljust(self.__filenameLen+1)
+ vDuration = "Duration".ljust(9)
+ vVideoCodec = "Codec".ljust(self.__videoCodecLen +1)
+ vVideoSize = "Size".ljust(13)
+ vPixel = "Pixels".ljust(self.__videoFormatLen+1)
+ vFPS = "FPS".ljust(6)
+ vAudioCodec = "Codec".ljust(self.__audioCodecLen+1)
+ vSampleRate = "Rate".ljust(6)
+ vChannels = "Channels".ljust(8)
+
+ videoPropWidth = self.__videoFormatLen+self.__videoCodecLen+30
+ print ("| ".rjust(self.__filenameLen + 3) +
+ "Video properties".center(videoPropWidth) +
+ "| " +
+ "Audio properties".center((self.__audioCodecLen+17)))
+ print (vFile + "| " + vDuration + vVideoCodec +
+ vVideoSize + vPixel + vFPS + "| " + vAudioCodec +
+ vSampleRate + vChannels )
+ print ("| ".rjust(self.__filenameLen+3) +
+ "|".rjust(videoPropWidth+1))
+
+ def __outputTableLine(self, node):
+ vFile = node.href.ljust(self.__filenameLen + 1)
+ vDuration = str(node.getDuration()/1000.).ljust(9)
+ vVideoCodec = str(node.getVideoCodec()).ljust(self.__videoCodecLen + 1)
+ vVideoSize = str(node.getMediaSize()).ljust(13)
+ vPixel = str(node.getStreamPixelFormat()).ljust(self.__videoFormatLen + 1)
+ if node.fps%1 < 0.0000001:
+ vFPS = str(int(node.fps)).ljust(6)
+ else:
+ vFPS = str(round(node.fps, 2)).ljust(6)
+
+ if node.hasAudio():
+ vAudioCodec = str(node.getAudioCodec()).ljust(self.__audioCodecLen + 1)
+ vSampleRate = str(node.getAudioSampleRate()).ljust(6)
+ vChannels = str(node.getNumAudioChannels()).ljust(8)
+ else:
+ vAudioCodec = "no audio"
+ vSampleRate = ""
+ vChannels = ""
+
+ info = (vFile + "| " + vDuration + vVideoCodec + vVideoSize + vPixel +
+ vFPS + "| " + vAudioCodec + vSampleRate + vChannels)
+ print info
+
+class XMLOutputHandler(OutputHandler):
+
+ def __init__(self, args):
+ super(XMLOutputHandler, self).__init__(args)
+ self.__impl = minidom.getDOMImplementation()
+ self.__doc = self.__impl.createDocument(None, "videodict", None)
+ self.__rootElement = self.__doc.documentElement
+
+ def output(self):
+ for filename in self._fileNameList:
+ self._node.href = str(filename)
+ self.__appendXMLChild(self._node)
+ print self.__doc.toprettyxml(indent=" ",encoding="utf-8")
+
+ def __appendXMLChild(self, node):
+ node.play()
+ videoinfo = self.__doc.createElement("videoinfo")
+ videoinfo.setAttribute("file", node.href)
+ videoinfo.setAttribute("duration", str(node.getDuration()/1000.))
+ videoinfo.setAttribute("bitrate", str(node.getBitrate()))
+ self.__rootElement.appendChild(videoinfo)
+ videoNode = self.__doc.createElement("video")
+ videoNode.setAttribute("codec", node.getVideoCodec())
+ videoNode.setAttribute("size", str(node.getMediaSize()))
+ videoNode.setAttribute("pixelformat", node.getStreamPixelFormat())
+ videoNode.setAttribute("fps", str(node.fps))
+ videoinfo.appendChild(videoNode)
+ if node.hasAudio():
+ audioNode = self.__doc.createElement("audio")
+ audioNode.setAttribute("codec", node.getAudioCodec())
+ audioNode.setAttribute("samplerate", str(node.getAudioSampleRate()))
+ audioNode.setAttribute("channels", str(node.getNumAudioChannels()))
+ videoinfo.appendChild(audioNode)
+
+class CSVOutputHandler(OutputHandler):
+
+ def __init__(self, args):
+ super(CSVOutputHandler, self).__init__(args)
+
+ def output(self):
+ print ("File\tDuration(sec)\tNumber of Frames\tBitrate(b/s)\tVideo Codec\t" +
+ "Width\tHeight\tPixel format\tFPS\tAudio Codec\t" +
+ "Audio Sample rate(Hz)\t Audio channels")
+ for filename in self._fileNameList:
+ self._node.href = str(filename)
+ self.__outputNode(self._node)
+
+ def __outputNode(self, node):
+ s = (str(node.href)+'\t'+
+ str(node.getDuration()/1000.)+'\t' +
+ str(node.getNumFrames())+"\t" +
+ str(node.getBitrate()) + '\t' +
+ str(node.getVideoCodec()) + '\t' +
+ str(node.getMediaSize()[0]) + '\t' +
+ str(node.getMediaSize()[1]) + '\t' +
+ str(node.getStreamPixelFormat()) + '\t' +
+ str(node.fps) + '\t')
+ if node.hasAudio():
+ s += (
+ str(node.getAudioCodec()) + '\t' +
+ str(node.getAudioSampleRate()) + '\t' +
+ str(node.getNumAudioChannels()))
+ else:
+ s += ' \t \t'
+ print s
+
+def printHelp():
+ parser.print_help()
+ sys.exit(1)
+
+if len(sys.argv) == 1:
+ printHelp()
+
+if options.xml:
+ outputHandler = XMLOutputHandler(args)
+elif options.csv:
+ outputHandler = CSVOutputHandler(args)
+else:
+ outputHandler = ConsoleOutputHandler(args)
+outputHandler.output()
diff --git a/src/utils/avg_videoplayer.py b/src/utils/avg_videoplayer.py
new file mode 100755
index 0000000..17268ca
--- /dev/null
+++ b/src/utils/avg_videoplayer.py
@@ -0,0 +1,143 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+# libavg - Media Playback Engine.
+# Copyright (C) 2003-2014 Ulrich von Zadow
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Current versions can be found at www.libavg.de
+
+import sys
+from libavg import avg, app, player, widget
+
+
+class VideoPlayer(app.MainDiv):
+ CONTROL_WIDTH=240
+
+ def onArgvParserCreated(self, parser):
+ parser.set_usage("%prog [options] <filename>")
+ parser.add_option("-d", "--disable-accel", dest="disableAccel",
+ action="store_true", default=False,
+ help="disable vdpau acceleration")
+
+ def onArgvParsed(self, options, args, parser):
+ if len(args) != 1:
+ parser.print_help()
+ sys.exit(1)
+
+ self.node = avg.VideoNode(href=args[0], accelerated=not(options.disableAccel))
+ self.node.pause()
+
+ mediaSize = self.node.getMediaSize()
+ size = avg.Point2D(max(mediaSize.x, 320), max(mediaSize.y, 120))
+ screenSize = player.getScreenResolution()
+ size = avg.Point2D(min(size.x, screenSize.x), min(size.y, screenSize.y-80))
+ self.settings.set("app_resolution", "%dx%d" %(size.x, size.y))
+
+ def onInit(self):
+ self.node.play()
+
+ mediaSize = self.node.getMediaSize()
+ canvasSize = self.size
+ sizeRatio = min(mediaSize.x/canvasSize.x, mediaSize.y/canvasSize.y)
+ self.node.size /= sizeRatio
+
+ self.node.x = (self.width-self.node.width)/2
+ self.node.y = (self.height-self.node.height)/2
+ self.node.subscribe(avg.VideoNode.END_OF_FILE, self.onEOF)
+
+ if self.node.hasAlpha():
+ self.__makeAlphaBackground()
+ self.appendChild(self.node)
+ self.curFrameWords = avg.WordsNode(parent=self, pos=(10, 10), fontsize=10)
+ self.framesQueuedWords = avg.WordsNode(parent=self, pos=(10, 22), fontsize=10)
+
+ controlPos = ((self.width-VideoPlayer.CONTROL_WIDTH)/2, self.height-25)
+ self.videoControl = widget.MediaControl(pos=controlPos,
+ size=(VideoPlayer.CONTROL_WIDTH, 20),
+ duration=self.node.getDuration(),
+ parent=self)
+ self.videoControl.play()
+ self.videoControl.subscribe(widget.MediaControl.PLAY_CLICKED, self.onPlay)
+ self.videoControl.subscribe(widget.MediaControl.PAUSE_CLICKED, self.onPause)
+ self.videoControl.subscribe(widget.MediaControl.SEEK_PRESSED, self.onSeekStart)
+ self.videoControl.subscribe(widget.MediaControl.SEEK_RELEASED, self.onSeekEnd)
+ self.videoControl.subscribe(widget.MediaControl.SEEK_MOTION, self.onSeek)
+
+ self.isSeeking = False
+ self.isPaused = False
+
+ def onKeyDown(self, event):
+ curTime = self.node.getCurTime()
+ if event.keystring == "right":
+ self.node.seekToTime(curTime+10000)
+ elif event.keystring == "left":
+ if curTime > 10000:
+ self.node.seekToTime(curTime-10000)
+ else:
+ self.node.seekToTime(0)
+ return False
+
+ def onFrame(self):
+ curFrame = self.node.getCurFrame()
+ numFrames = self.node.getNumFrames()
+ self.curFrameWords.text = "Frame: %i/%i"%(curFrame, numFrames)
+ framesQueued = self.node.getNumFramesQueued()
+ self.framesQueuedWords.text = "Frames queued: "+str(framesQueued)
+ if not(self.isSeeking):
+ self.videoControl.time = self.node.getCurTime()
+
+ def onEOF(self):
+ self.videoControl.pause()
+ self.isPaused = True
+
+ def onPlay(self):
+ self.node.play()
+ self.isPaused = False
+
+ def onPause(self):
+ self.node.pause()
+ self.isPaused = True
+
+ def onSeekStart(self):
+ self.node.pause()
+ self.isSeeking = True
+
+ def onSeekEnd(self):
+ if not(self.isPaused):
+ self.node.play()
+ self.isSeeking = False
+
+ def onSeek(self, time):
+ self.node.seekToTime(int(time))
+
+ def __makeAlphaBackground(self):
+ SQUARESIZE=40
+ size = self.node.getMediaSize()
+ avg.RectNode(parent=self, size=self.node.getMediaSize(),
+ strokewidth=0, fillcolor="FFFFFF", fillopacity=1)
+ for y in xrange(0, int(size.y)/SQUARESIZE):
+ for x in xrange(0, int(size.x)/(SQUARESIZE*2)):
+ pos = avg.Point2D(x*SQUARESIZE*2, y*SQUARESIZE)
+ if y%2==1:
+ pos += (SQUARESIZE, 0)
+ avg.RectNode(parent=self, pos=pos, size=(SQUARESIZE, SQUARESIZE),
+ strokewidth=0, fillcolor="C0C0C0", fillopacity=1)
+
+
+if __name__ == "__main__":
+ app.App().run(VideoPlayer())
+
diff --git a/src/video/AsyncVideoDecoder.cpp b/src/video/AsyncVideoDecoder.cpp
new file mode 100644
index 0000000..4ba7033
--- /dev/null
+++ b/src/video/AsyncVideoDecoder.cpp
@@ -0,0 +1,505 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "AsyncVideoDecoder.h"
+
+#ifdef AVG_ENABLE_VDPAU
+#include "VDPAUDecoder.h"
+#include "VDPAUHelper.h"
+#endif
+
+#include "../base/ObjectCounter.h"
+#include "../base/Exception.h"
+#include "../base/ScopeTimer.h"
+
+#include <boost/thread/thread.hpp>
+#include <boost/bind.hpp>
+
+#include <math.h>
+#include <iostream>
+
+using namespace std;
+using boost::dynamic_pointer_cast;
+
+#define AUDIO_MSG_QUEUE_LENGTH 50
+#define AUDIO_STATUS_QUEUE_LENGTH -1
+#define PACKET_QUEUE_LENGTH 50
+
+namespace avg {
+
+AsyncVideoDecoder::AsyncVideoDecoder(int queueLength)
+ : m_QueueLength(queueLength),
+ m_pDemuxThread(0),
+ m_pVDecoderThread(0),
+ m_pADecoderThread(0),
+ m_bUseStreamFPS(true),
+ m_FPS(0)
+{
+ ObjectCounter::get()->incRef(&typeid(*this));
+}
+
+AsyncVideoDecoder::~AsyncVideoDecoder()
+{
+ if (m_pVDecoderThread || m_pADecoderThread) {
+ close();
+ }
+ ObjectCounter::get()->decRef(&typeid(*this));
+}
+
+void AsyncVideoDecoder::open(const std::string& sFilename, bool bUseHardwareAcceleration,
+ bool bEnableSound)
+{
+ m_NumSeeksSent = 0;
+ m_NumVSeeksDone = 0;
+ m_NumASeeksDone = 0;
+ m_bAudioEOF = false;
+ m_bVideoEOF = false;
+ m_bWasVSeeking = false;
+ m_bWasSeeking = false;
+ m_CurVideoFrameTime = -1;
+
+ VideoDecoder::open(sFilename, bUseHardwareAcceleration, bEnableSound);
+
+ if (getVideoInfo().m_bHasVideo && m_bUseStreamFPS) {
+ m_FPS = getStreamFPS();
+ }
+}
+
+void AsyncVideoDecoder::startDecoding(bool bDeliverYCbCr, const AudioParams* pAP)
+{
+ VideoDecoder::startDecoding(bDeliverYCbCr, pAP);
+
+ AVG_ASSERT(!m_pDemuxThread);
+ vector<int> streamIndexes;
+ if (getVStreamIndex() >= 0) {
+ streamIndexes.push_back(getVStreamIndex());
+ }
+ if (getAStreamIndex() >= 0) {
+ streamIndexes.push_back(getAStreamIndex());
+ }
+ setupDemuxer(streamIndexes);
+
+ if (getVideoInfo().m_bHasVideo) {
+ m_LastVideoFrameTime = -1;
+ m_CurVideoFrameTime = -1;
+ if (m_bUseStreamFPS) {
+ m_FPS = getStreamFPS();
+ }
+ m_pVCmdQ = VideoDecoderThread::CQueuePtr(new VideoDecoderThread::CQueue);
+ m_pVMsgQ = VideoMsgQueuePtr(new VideoMsgQueue(m_QueueLength));
+ VideoMsgQueue& packetQ = *m_PacketQs[getVStreamIndex()];
+
+ m_pVDecoderThread = new boost::thread(VideoDecoderThread(
+ *m_pVCmdQ, *m_pVMsgQ, packetQ, getVideoStream(),
+ getSize(), getPixelFormat(), usesVDPAU()));
+ }
+
+ if (getVideoInfo().m_bHasAudio) {
+ m_pACmdQ = AudioDecoderThread::CQueuePtr(new AudioDecoderThread::CQueue);
+ m_pAMsgQ = AudioMsgQueuePtr(new AudioMsgQueue(AUDIO_MSG_QUEUE_LENGTH));
+ m_pAStatusQ = AudioMsgQueuePtr(new AudioMsgQueue(AUDIO_STATUS_QUEUE_LENGTH));
+ VideoMsgQueue& packetQ = *m_PacketQs[getAStreamIndex()];
+ m_pADecoderThread = new boost::thread(
+ AudioDecoderThread(*m_pACmdQ, *m_pAMsgQ, packetQ, getAudioStream(), *pAP));
+ m_LastAudioFrameTime = 0;
+ }
+}
+
+void AsyncVideoDecoder::close()
+{
+ AVG_ASSERT(getState() != CLOSED);
+
+ if (m_pDemuxThread) {
+ m_pDemuxCmdQ->pushCmd(boost::bind(&VideoDemuxerThread::close, _1));
+ m_pDemuxThread->join();
+ }
+
+ if (m_pVDecoderThread) {
+ m_pVMsgQ->clear();
+ m_pVDecoderThread->join();
+ delete m_pVDecoderThread;
+ m_pVDecoderThread = 0;
+ m_pVMsgQ = VideoMsgQueuePtr();
+ }
+ if (m_pADecoderThread) {
+ m_pAMsgQ->clear();
+ m_pAStatusQ->clear();
+ m_pADecoderThread->join();
+ delete m_pADecoderThread;
+ m_pADecoderThread = 0;
+ m_pAStatusQ = AudioMsgQueuePtr();
+ m_pAMsgQ = AudioMsgQueuePtr();
+ }
+ VideoDecoder::close();
+ if (m_pDemuxThread) {
+ deleteDemuxer();
+ }
+}
+
+void AsyncVideoDecoder::seek(float destTime)
+{
+ AVG_ASSERT(getState() == DECODING);
+ m_bAudioEOF = false;
+ m_bVideoEOF = false;
+ m_NumSeeksSent++;
+ m_pDemuxCmdQ->pushCmd(boost::bind(&VideoDemuxerThread::seek, _1, m_NumSeeksSent,
+ destTime));
+}
+
+void AsyncVideoDecoder::loop()
+{
+ m_LastVideoFrameTime = -1;
+ m_bAudioEOF = false;
+ m_bVideoEOF = false;
+ seek(0);
+}
+
+int AsyncVideoDecoder::getCurFrame() const
+{
+ AVG_ASSERT(getState() != CLOSED);
+ return int(getCurTime()*getVideoInfo().m_StreamFPS+0.5);
+}
+
+int AsyncVideoDecoder::getNumFramesQueued() const
+{
+ AVG_ASSERT(getState() == DECODING);
+ return m_pVMsgQ->size();
+}
+
+float AsyncVideoDecoder::getCurTime() const
+{
+ AVG_ASSERT(getState() != CLOSED);
+ if (getVideoInfo().m_bHasVideo) {
+ return m_CurVideoFrameTime;
+ } else {
+ return m_LastAudioFrameTime;
+ }
+}
+
+float AsyncVideoDecoder::getFPS() const
+{
+ AVG_ASSERT(getState() != CLOSED);
+ return m_FPS;
+}
+
+void AsyncVideoDecoder::setFPS(float fps)
+{
+ AVG_ASSERT(!m_pADecoderThread);
+ m_pVCmdQ->pushCmd(boost::bind(&VideoDecoderThread::setFPS, _1, fps));
+ m_bUseStreamFPS = (fps == 0);
+ if (m_bUseStreamFPS) {
+ m_FPS = getVideoInfo().m_StreamFPS;
+ } else {
+ m_FPS = fps;
+ }
+}
+
+static ProfilingZoneID VDPAUDecodeProfilingZone("AsyncVideoDecoder: VDPAU", true);
+
+FrameAvailableCode AsyncVideoDecoder::renderToBmps(vector<BitmapPtr>& pBmps,
+ float timeWanted)
+{
+ AVG_ASSERT(getState() == DECODING);
+ FrameAvailableCode frameAvailable;
+ VideoMsgPtr pFrameMsg;
+ if (timeWanted == -1) {
+ waitForSeekDone();
+ pFrameMsg = getNextBmps(true);
+ frameAvailable = FA_NEW_FRAME;
+ } else {
+ pFrameMsg = getBmpsForTime(timeWanted, frameAvailable);
+ }
+ if (frameAvailable == FA_NEW_FRAME) {
+ AVG_ASSERT(pFrameMsg);
+ m_LastVideoFrameTime = pFrameMsg->getFrameTime();
+ m_CurVideoFrameTime = m_LastVideoFrameTime;
+ if (pFrameMsg->getType() == VideoMsg::VDPAU_FRAME) {
+#ifdef AVG_ENABLE_VDPAU
+ ScopeTimer timer(VDPAUDecodeProfilingZone);
+ vdpau_render_state* pRenderState = pFrameMsg->getRenderState();
+ if (pixelFormatIsPlanar(getPixelFormat())) {
+ getPlanesFromVDPAU(pRenderState, pBmps[0], pBmps[1], pBmps[2]);
+ } else {
+ getBitmapFromVDPAU(pRenderState, pBmps[0]);
+ }
+#endif
+ } else {
+ for (unsigned i = 0; i < pBmps.size(); ++i) {
+ pBmps[i]->copyPixels(*(pFrameMsg->getFrameBitmap(i)));
+ }
+ returnFrame(pFrameMsg);
+ }
+ }
+ return frameAvailable;
+}
+
+void AsyncVideoDecoder::updateAudioStatus()
+{
+ if (m_pAStatusQ) {
+ AudioMsgPtr pMsg = m_pAStatusQ->pop(false);
+ while (pMsg) {
+ handleAudioMsg(pMsg);
+ pMsg = m_pAStatusQ->pop(false);
+ }
+ }
+}
+
+bool AsyncVideoDecoder::isEOF() const
+{
+ AVG_ASSERT(getState() == DECODING);
+ bool bEOF = true;
+ if (getVideoInfo().m_bHasAudio && !m_bAudioEOF) {
+ bEOF = false;
+ }
+ if (getVideoInfo().m_bHasVideo && !m_bVideoEOF) {
+ bEOF = false;
+ }
+ return bEOF;
+}
+
+void AsyncVideoDecoder::throwAwayFrame(float timeWanted)
+{
+ AVG_ASSERT(getState() == DECODING);
+ FrameAvailableCode frameAvailable;
+ VideoMsgPtr pFrameMsg = getBmpsForTime(timeWanted, frameAvailable);
+}
+
+AudioMsgQueuePtr AsyncVideoDecoder::getAudioMsgQ()
+{
+ return m_pAMsgQ;
+}
+
+AudioMsgQueuePtr AsyncVideoDecoder::getAudioStatusQ() const
+{
+ return m_pAStatusQ;
+}
+
+void AsyncVideoDecoder::setupDemuxer(vector<int> streamIndexes)
+{
+ m_pDemuxCmdQ = VideoDemuxerThread::CQueuePtr(new VideoDemuxerThread::CQueue());
+ for (unsigned i = 0; i < streamIndexes.size(); ++i) {
+ VideoMsgQueuePtr pPacketQ(new VideoMsgQueue(PACKET_QUEUE_LENGTH));
+ m_PacketQs[streamIndexes[i]] = pPacketQ;
+ }
+ m_pDemuxThread = new boost::thread(VideoDemuxerThread(*m_pDemuxCmdQ,
+ getFormatContext(), m_PacketQs));
+}
+
+void AsyncVideoDecoder::deleteDemuxer()
+{
+ delete m_pDemuxThread;
+ m_pDemuxThread = 0;
+ map<int, VideoMsgQueuePtr>::iterator it;
+ for (it = m_PacketQs.begin(); it != m_PacketQs.end(); it++) {
+ VideoMsgQueuePtr pPacketQ = it->second;
+ VideoMsgPtr pPacketMsg;
+ pPacketMsg = pPacketQ->pop(false);
+ while (pPacketMsg) {
+ pPacketMsg->freePacket();
+ pPacketMsg = pPacketQ->pop(false);
+ }
+ }
+}
+
+VideoMsgPtr AsyncVideoDecoder::getBmpsForTime(float timeWanted,
+ FrameAvailableCode& frameAvailable)
+{
+ if (timeWanted < 0) {
+ cerr << "Illegal timeWanted: " << timeWanted << endl;
+ AVG_ASSERT(false);
+ }
+ VideoMsgPtr pFrameMsg;
+ float timePerFrame = 1.0f/getFPS();
+
+ checkForSeekDone();
+ bool bVSeekDone = (!isVSeeking() && m_bWasVSeeking);
+ m_bWasVSeeking = isVSeeking();
+
+ if (!isSeeking() && m_bWasSeeking) {
+// cerr << "timeWanted: " << timeWanted << ", audio: " << m_LastAudioFrameTime
+// << ", diff: " << timeWanted-m_LastAudioFrameTime << endl;
+ }
+ m_bWasSeeking = isSeeking();
+ if ((!bVSeekDone &&
+ (isVSeeking() ||
+ fabs(float(timeWanted-m_LastVideoFrameTime)) < 0.5*timePerFrame ||
+ m_LastVideoFrameTime > timeWanted+timePerFrame)) ||
+ m_bVideoEOF)
+ {
+ // The last frame is still current. Display it again.
+ frameAvailable = FA_USE_LAST_FRAME;
+ return VideoMsgPtr();
+ } else {
+ float frameTime = -1;
+ while (frameTime-timeWanted < -0.5*timePerFrame && !m_bVideoEOF) {
+ if (pFrameMsg) {
+ if (pFrameMsg->getType() == VideoMsg::FRAME) {
+ returnFrame(pFrameMsg);
+ } else {
+#if AVG_ENABLE_VDPAU
+ vdpau_render_state* pRenderState = pFrameMsg->getRenderState();
+ unlockVDPAUSurface(pRenderState);
+#endif
+ }
+ }
+ pFrameMsg = getNextBmps(false);
+ if (pFrameMsg) {
+ frameTime = pFrameMsg->getFrameTime();
+ } else {
+ frameAvailable = FA_STILL_DECODING;
+ return VideoMsgPtr();
+ }
+ }
+ if (!pFrameMsg) {
+ cerr << "frameTime=" << frameTime << ", timeWanted=" << timeWanted
+ << ", timePerFrame=" << timePerFrame << ", m_bVideoEOF="
+ << m_bVideoEOF << endl;
+ AVG_ASSERT(false);
+ }
+ frameAvailable = FA_NEW_FRAME;
+ }
+ return pFrameMsg;
+}
+
+VideoMsgPtr AsyncVideoDecoder::getNextBmps(bool bWait)
+{
+ VideoMsgPtr pMsg = m_pVMsgQ->pop(bWait);
+ if (pMsg) {
+ switch (pMsg->getType()) {
+ case VideoMsg::FRAME:
+ case VideoMsg::VDPAU_FRAME:
+ return pMsg;
+ case VideoMsg::END_OF_FILE:
+ m_NumVSeeksDone = m_NumSeeksSent;
+ m_bVideoEOF = true;
+ return VideoMsgPtr();
+ case VideoMsg::ERROR:
+ m_bVideoEOF = true;
+ return VideoMsgPtr();
+ case AudioMsg::SEEK_DONE:
+ handleVSeekDone(pMsg);
+ return getNextBmps(bWait);
+ default:
+ // Unhandled message type.
+ AVG_ASSERT(false);
+ return VideoMsgPtr();
+ }
+ } else {
+ return pMsg;
+ }
+}
+void AsyncVideoDecoder::waitForSeekDone()
+{
+ while (isVSeeking()) {
+ VideoMsgPtr pMsg = m_pVMsgQ->pop(true);
+ handleVSeekMsg(pMsg);
+ }
+}
+
+void AsyncVideoDecoder::checkForSeekDone()
+{
+ if (isVSeeking()) {
+ VideoMsgPtr pMsg;
+ do {
+ pMsg = m_pVMsgQ->pop(false);
+ if (pMsg) {
+ handleVSeekMsg(pMsg);
+ }
+ } while (pMsg && isVSeeking());
+ }
+}
+
+void AsyncVideoDecoder::handleVSeekMsg(VideoMsgPtr pMsg)
+{
+ switch (pMsg->getType()) {
+ case AudioMsg::SEEK_DONE:
+ handleVSeekDone(pMsg);
+ break;
+ case VideoMsg::FRAME:
+ returnFrame(dynamic_pointer_cast<VideoMsg>(pMsg));
+ break;
+ case VideoMsg::VDPAU_FRAME:
+#ifdef AVG_ENABLE_VDPAU
+ unlockVDPAUSurface(pMsg->getRenderState());
+#endif
+ break;
+ case VideoMsg::END_OF_FILE:
+ m_NumVSeeksDone = m_NumSeeksSent;
+ m_bVideoEOF = true;
+ break;
+ default:
+ // TODO: Handle ERROR messages here.
+ AVG_ASSERT(false);
+ }
+}
+
+void AsyncVideoDecoder::handleVSeekDone(AudioMsgPtr pMsg)
+{
+ m_LastVideoFrameTime = pMsg->getSeekTime() - 1/m_FPS;
+ if (m_NumVSeeksDone < pMsg->getSeekSeqNum()) {
+ m_NumVSeeksDone = pMsg->getSeekSeqNum();
+ }
+}
+
+void AsyncVideoDecoder::handleAudioMsg(AudioMsgPtr pMsg)
+{
+ switch (pMsg->getType()) {
+ case AudioMsg::END_OF_FILE:
+ case AudioMsg::ERROR:
+ m_bAudioEOF = true;
+ break;
+ case AudioMsg::SEEK_DONE:
+// pMsg->dump();
+ m_bAudioEOF = false;
+ m_LastAudioFrameTime = pMsg->getSeekTime();
+ if (m_NumASeeksDone < pMsg->getSeekSeqNum()) {
+ m_NumASeeksDone = pMsg->getSeekSeqNum();
+ }
+ break;
+ case AudioMsg::AUDIO_TIME:
+ m_LastAudioFrameTime = pMsg->getAudioTime();
+ break;
+ default:
+ // Unhandled message type.
+ pMsg->dump();
+ AVG_ASSERT(false);
+ }
+}
+
+void AsyncVideoDecoder::returnFrame(VideoMsgPtr pFrameMsg)
+{
+ if (pFrameMsg) {
+ AVG_ASSERT(pFrameMsg->getType() == VideoMsg::FRAME);
+ m_pVCmdQ->pushCmd(boost::bind(&VideoDecoderThread::returnFrame, _1, pFrameMsg));
+ }
+}
+
+bool AsyncVideoDecoder::isSeeking() const
+{
+ return (m_NumSeeksSent > m_NumVSeeksDone || m_NumSeeksSent > m_NumASeeksDone);
+}
+
+bool AsyncVideoDecoder::isVSeeking() const
+{
+ return m_NumSeeksSent > m_NumVSeeksDone;
+}
+
+}
diff --git a/src/video/AsyncVideoDecoder.h b/src/video/AsyncVideoDecoder.h
new file mode 100644
index 0000000..7773831
--- /dev/null
+++ b/src/video/AsyncVideoDecoder.h
@@ -0,0 +1,117 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _AsyncVideoDecoder_H_
+#define _AsyncVideoDecoder_H_
+
+#include "../api.h"
+#include "VideoDecoder.h"
+#include "VideoDemuxerThread.h"
+#include "VideoDecoderThread.h"
+#include "AudioDecoderThread.h"
+#include "VideoMsg.h"
+
+#include "../graphics/Bitmap.h"
+#include "../audio/AudioParams.h"
+
+#include <boost/thread/mutex.hpp>
+
+#include <string>
+
+namespace avg {
+
+class AVG_API AsyncVideoDecoder: public VideoDecoder
+{
+public:
+ AsyncVideoDecoder(int queueLength);
+ virtual ~AsyncVideoDecoder();
+ virtual void open(const std::string& sFilename, bool bUseHardwareAcceleration,
+ bool bEnableSound);
+ virtual void startDecoding(bool bDeliverYCbCr, const AudioParams* pAP);
+ virtual void close();
+ virtual void seek(float destTime);
+ virtual void loop();
+ virtual int getCurFrame() const;
+ virtual int getNumFramesQueued() const;
+ virtual float getCurTime() const;
+ virtual float getFPS() const;
+ virtual void setFPS(float fps);
+
+ virtual FrameAvailableCode renderToBmps(std::vector<BitmapPtr>& pBmps,
+ float timeWanted);
+ void updateAudioStatus();
+ virtual bool isEOF() const;
+ virtual void throwAwayFrame(float timeWanted);
+
+ AudioMsgQueuePtr getAudioMsgQ();
+ AudioMsgQueuePtr getAudioStatusQ() const;
+
+private:
+ void setupDemuxer(std::vector<int> streamIndexes);
+ void deleteDemuxer();
+ VideoMsgPtr getBmpsForTime(float timeWanted, FrameAvailableCode& frameAvailable);
+ VideoMsgPtr getNextBmps(bool bWait);
+ void waitForSeekDone();
+ void checkForSeekDone();
+ void handleVSeekMsg(VideoMsgPtr pMsg);
+ void handleVSeekDone(AudioMsgPtr pMsg);
+ void handleAudioMsg(AudioMsgPtr pMsg);
+ void returnFrame(VideoMsgPtr pFrameMsg);
+ bool isSeeking() const;
+ bool isVSeeking() const;
+
+ int m_QueueLength;
+
+ boost::thread* m_pDemuxThread;
+ std::map<int, VideoMsgQueuePtr> m_PacketQs;
+ VideoDemuxerThread::CQueuePtr m_pDemuxCmdQ;
+
+ boost::thread* m_pVDecoderThread;
+ VideoDecoderThread::CQueuePtr m_pVCmdQ;
+ VideoMsgQueuePtr m_pVMsgQ;
+
+ boost::thread* m_pADecoderThread;
+ AudioDecoderThread::CQueuePtr m_pACmdQ;
+ AudioMsgQueuePtr m_pAMsgQ;
+ AudioMsgQueuePtr m_pAStatusQ;
+
+ bool m_bUseStreamFPS;
+ float m_FPS;
+
+ int m_NumSeeksSent;
+ int m_NumVSeeksDone;
+ int m_NumASeeksDone;
+ bool m_bWasVSeeking;
+ bool m_bWasSeeking;
+
+ bool m_bAudioEOF;
+ bool m_bVideoEOF;
+
+ float m_LastVideoFrameTime;
+ float m_CurVideoFrameTime;
+ float m_LastAudioFrameTime;
+};
+
+typedef boost::shared_ptr<AsyncVideoDecoder> AsyncVideoDecoderPtr;
+
+}
+#endif
+
diff --git a/src/video/AudioDecoderThread.cpp b/src/video/AudioDecoderThread.cpp
new file mode 100644
index 0000000..8f4aee3
--- /dev/null
+++ b/src/video/AudioDecoderThread.cpp
@@ -0,0 +1,366 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+// Original author of this file is Nick Hebner (hebnern@gmail.com).
+//
+
+#include "AudioDecoderThread.h"
+
+#include "../base/Logger.h"
+#include "../base/TimeSource.h"
+#include "../base/ScopeTimer.h"
+
+#if AVUTIL_VERSION_INT > AV_VERSION_INT(52, 0, 0)
+#include <libavutil/samplefmt.h>
+#endif
+
+#ifndef AVCODEC_MAX_AUDIO_FRAME_SIZE
+ #define AVCODEC_MAX_AUDIO_FRAME_SIZE 192000
+#endif
+
+using namespace std;
+
+namespace avg {
+
+AudioDecoderThread::AudioDecoderThread(CQueue& cmdQ, AudioMsgQueue& msgQ,
+ VideoMsgQueue& packetQ, AVStream* pStream, const AudioParams& ap)
+ : WorkerThread<AudioDecoderThread>(string("AudioDecoderThread"), cmdQ),
+ m_MsgQ(msgQ),
+ m_PacketQ(packetQ),
+ m_AP(ap),
+ m_pStream(pStream),
+ m_pResampleContext(0),
+ m_State(DECODING)
+{
+ m_LastFrameTime = 0;
+ m_AudioStartTimestamp = 0;
+
+ if (m_pStream->start_time != (long long)AV_NOPTS_VALUE) {
+ m_AudioStartTimestamp = float(av_q2d(m_pStream->time_base)*m_pStream->start_time);
+ }
+ m_InputSampleRate = (int)(m_pStream->codec->sample_rate);
+ m_InputSampleFormat = m_pStream->codec->sample_fmt;
+}
+
+AudioDecoderThread::~AudioDecoderThread()
+{
+ if (m_pResampleContext) {
+#ifdef LIBAVRESAMPLE_VERSION
+ avresample_close(m_pResampleContext);
+ avresample_free(&m_pResampleContext);
+#else
+ audio_resample_close(m_pResampleContext);
+#endif
+ m_pResampleContext = 0;
+ }
+}
+
+static ProfilingZoneID DecoderProfilingZone("Audio Decoder Thread", true);
+static ProfilingZoneID PacketWaitProfilingZone("Audio Wait for packet", true);
+
+bool AudioDecoderThread::work()
+{
+ ScopeTimer timer(DecoderProfilingZone);
+ VideoMsgPtr pMsg;
+ {
+ ScopeTimer timer(PacketWaitProfilingZone);
+ pMsg = m_PacketQ.pop(true);
+ }
+ switch (pMsg->getType()) {
+ case VideoMsg::PACKET: {
+ AVPacket* pPacket = pMsg->getPacket();
+ switch(m_State) {
+ case DECODING:
+ decodePacket(pPacket);
+ break;
+ case SEEK_DONE:
+ handleSeekDone(pPacket);
+ break;
+ case DISCARDING:
+ discardPacket(pPacket);
+ break;
+ default:
+ AVG_ASSERT(false);
+ }
+ av_free_packet(pPacket);
+ delete pPacket;
+ break;
+ }
+ case VideoMsg::SEEK_DONE:
+ m_State = SEEK_DONE;
+ m_SeekSeqNum = pMsg->getSeekSeqNum();
+ m_SeekTime = pMsg->getSeekTime();
+ break;
+ case VideoMsg::END_OF_FILE:
+ pushEOF();
+ break;
+ case VideoMsg::CLOSED:
+ m_MsgQ.clear();
+ stop();
+ break;
+ default:
+ pMsg->dump();
+ AVG_ASSERT(false);
+ }
+ ThreadProfiler::get()->reset();
+ return true;
+}
+
+void AudioDecoderThread::decodePacket(AVPacket* pPacket)
+{
+ char* pDecodedData = (char*)av_malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE +
+ FF_INPUT_BUFFER_PADDING_SIZE);
+ AVPacket* pTempPacket = new AVPacket;
+ av_init_packet(pTempPacket);
+ pTempPacket->data = pPacket->data;
+ pTempPacket->size = pPacket->size;
+#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(53, 25, 0)
+ int gotFrame = 0;
+ AVFrame* pDecodedFrame;
+ pDecodedFrame = avcodec_alloc_frame();
+#endif
+ while (pTempPacket->size > 0) {
+ int bytesDecoded = AVCODEC_MAX_AUDIO_FRAME_SIZE;
+#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(53, 25, 0)
+ int bytesConsumed = avcodec_decode_audio4(m_pStream->codec, pDecodedFrame,
+ &gotFrame, pTempPacket);
+ int planeSize;
+ bytesDecoded = av_samples_get_buffer_size(&planeSize, m_pStream->codec->channels,
+ pDecodedFrame->nb_samples, m_pStream->codec->sample_fmt, 1);
+#else
+ int bytesConsumed = avcodec_decode_audio3(m_pStream->codec, (short*)pDecodedData,
+ &bytesDecoded, pTempPacket);
+#endif
+// This is triggered for some strange/broken videos.
+// AVG_ASSERT(bytesConsumed != 0);
+ if (bytesConsumed < 0) {
+ // Error decoding -> throw away current packet.
+ bytesDecoded = 0;
+ pTempPacket->size = 0;
+ } else {
+ pTempPacket->data += bytesConsumed;
+ pTempPacket->size -= bytesConsumed;
+ }
+ if (bytesDecoded > 0) {
+ int framesDecoded = bytesDecoded/(m_pStream->codec->channels*
+ getBytesPerSample(m_InputSampleFormat));
+ AudioBufferPtr pBuffer;
+ bool bNeedsResample = (m_InputSampleRate != m_AP.m_SampleRate ||
+ m_InputSampleFormat != SAMPLE_FMT_S16 ||
+ m_pStream->codec->channels != m_AP.m_Channels);
+ bool bIsPlanar = false;
+#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(51, 27, 0)
+ bIsPlanar = av_sample_fmt_is_planar((SampleFormat)m_InputSampleFormat);
+ if (bIsPlanar) {
+ char* pPackedData = (char*)av_malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE +
+ FF_INPUT_BUFFER_PADDING_SIZE);
+ planarToInterleaved(pPackedData, pDecodedData, m_pStream->codec->channels,
+ m_pStream->codec->frame_size);
+ pBuffer = resampleAudio(pPackedData, framesDecoded,
+ av_get_packed_sample_fmt((SampleFormat)m_InputSampleFormat));
+ av_free(pPackedData);
+ bNeedsResample = false;
+ }
+#endif
+ if (bNeedsResample) {
+ pBuffer = resampleAudio(pDecodedData, framesDecoded,
+ m_InputSampleFormat);
+ } else if (!bIsPlanar) {
+ pBuffer = AudioBufferPtr(new AudioBuffer(framesDecoded, m_AP));
+ memcpy(pBuffer->getData(), pDecodedData, bytesDecoded);
+ }
+ m_LastFrameTime += float(pBuffer->getNumFrames())/m_AP.m_SampleRate;
+ pushAudioMsg(pBuffer, m_LastFrameTime);
+ }
+ }
+ av_free(pDecodedData);
+#if LIBAVCODEC_VERSION_MAJOR > 53
+ avcodec_free_frame(&pDecodedFrame);
+#elif LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(53, 25, 0)
+ delete pDecodedFrame;
+#endif
+ delete pTempPacket;
+}
+
+void AudioDecoderThread::handleSeekDone(AVPacket* pPacket)
+{
+ m_MsgQ.clear();
+ m_LastFrameTime = float(pPacket->dts*av_q2d(m_pStream->time_base))
+ - m_AudioStartTimestamp;
+
+ if (fabs(m_LastFrameTime - m_SeekTime) < 0.01) {
+ pushSeekDone(m_LastFrameTime, m_SeekSeqNum);
+ decodePacket(pPacket);
+ m_State = DECODING;
+ } else {
+ if (m_LastFrameTime-0.01f < m_SeekTime) {
+ // Received frame that's earlier than the destination, so throw away frames
+ // until the time is correct.
+ m_State = DISCARDING;
+ } else {
+ // Received frame that's too late, so insert a buffer of silence to
+ // compensate.
+ insertSilence(m_LastFrameTime - m_SeekTime);
+ m_LastFrameTime = m_SeekTime;
+ pushSeekDone(m_LastFrameTime, m_SeekSeqNum);
+ decodePacket(pPacket);
+ m_State = DECODING;
+ }
+ }
+}
+
+void AudioDecoderThread::discardPacket(AVPacket* pPacket)
+{
+ m_LastFrameTime = float(pPacket->dts*av_q2d(m_pStream->time_base))
+ - m_AudioStartTimestamp;
+ if (m_LastFrameTime-0.01f > m_SeekTime) {
+ pushSeekDone(m_LastFrameTime, m_SeekSeqNum);
+ m_State = DECODING;
+ }
+}
+
+AudioBufferPtr AudioDecoderThread::resampleAudio(char* pDecodedData, int framesDecoded,
+ int currentSampleFormat)
+{
+ if (!m_pResampleContext) {
+#ifdef LIBAVRESAMPLE_VERSION
+ m_pResampleContext = avresample_alloc_context();
+ av_opt_set_int(m_pResampleContext, "in_channel_layout",
+ av_get_default_channel_layout(m_pStream->codec->channels), 0);
+ av_opt_set_int(m_pResampleContext, "out_channel_layout", AV_CH_LAYOUT_STEREO, 0);
+ av_opt_set_int(m_pResampleContext, "in_sample_rate", m_InputSampleRate, 0);
+ av_opt_set_int(m_pResampleContext, "out_sample_rate", m_AP.m_SampleRate, 0);
+ av_opt_set_int(m_pResampleContext, "in_sample_fmt",
+ (SampleFormat)currentSampleFormat, 0);
+ av_opt_set_int(m_pResampleContext, "out_sample_fmt", AV_SAMPLE_FMT_S16, 0);
+ int err = avresample_open(m_pResampleContext);
+ AVG_ASSERT(err >= 0);
+#else
+ m_pResampleContext = av_audio_resample_init(m_AP.m_Channels,
+ m_pStream->codec->channels, m_AP.m_SampleRate, m_InputSampleRate,
+ SAMPLE_FMT_S16, (SampleFormat)currentSampleFormat, 16, 10, 0, 0.8);
+#endif
+ AVG_ASSERT(m_pResampleContext);
+ }
+#ifdef LIBAVRESAMPLE_VERSION
+ uint8_t *pResampledData;
+ int leftoverSamples = avresample_available(m_pResampleContext);
+ int framesAvailable = leftoverSamples +
+ av_rescale_rnd(avresample_get_delay(m_pResampleContext) +
+ framesDecoded, m_AP.m_SampleRate, m_InputSampleRate, AV_ROUND_UP);
+ av_samples_alloc(&pResampledData, 0, 2, framesAvailable,
+ AV_SAMPLE_FMT_S16, 0);
+ int framesResampled = avresample_convert(m_pResampleContext, &pResampledData, 0,
+ framesAvailable, (uint8_t**)&pDecodedData, 0, framesDecoded);
+ AudioBufferPtr pBuffer(new AudioBuffer(framesResampled, m_AP));
+ memcpy(pBuffer->getData(), pResampledData,
+ framesResampled*m_AP.m_Channels*sizeof(short));
+ av_freep(&pResampledData);
+#else
+ short pResampledData[AVCODEC_MAX_AUDIO_FRAME_SIZE/2];
+ int framesResampled = audio_resample(m_pResampleContext, pResampledData,
+ (short*)pDecodedData, framesDecoded);
+ AudioBufferPtr pBuffer(new AudioBuffer(framesResampled, m_AP));
+ memcpy(pBuffer->getData(), pResampledData,
+ framesResampled*m_AP.m_Channels*sizeof(short));
+#endif
+ return pBuffer;
+}
+
+void AudioDecoderThread::planarToInterleaved(char* pOutput, char* pInput, int numChannels,
+ int numSamples)
+{
+ AVG_ASSERT(numChannels <= 8);
+ if (numSamples == 0) {
+ // Fishy, some ogg files have no proper frame_size set. But outputBufferSamples
+ // worked for sample ogg file.
+ numSamples = m_AP.m_OutputBufferSamples;
+ }
+ int i, j;
+ int bytesPerSample = getBytesPerSample(m_InputSampleFormat);
+ char * pPlanes[8] = {};
+ for (i=0; i<numChannels; i++) {
+ pPlanes[i] = pInput + i*(numSamples*bytesPerSample);
+ }
+ for (i=0; i<numSamples; i++) {
+ for (j=0; j<numChannels; j++) {
+ memcpy(pOutput, pPlanes[j], bytesPerSample);
+ pOutput += bytesPerSample;
+ pPlanes[j] += bytesPerSample;
+ }
+ }
+}
+
+void AudioDecoderThread::insertSilence(float duration)
+{
+ int numDelaySamples = int(duration*m_AP.m_SampleRate);
+ AudioBufferPtr pBuffer(new AudioBuffer(numDelaySamples, m_AP));
+ pBuffer->clear();
+ pushAudioMsg(pBuffer, m_LastFrameTime);
+}
+
+void AudioDecoderThread::pushAudioMsg(AudioBufferPtr pBuffer, float time)
+{
+ VideoMsgPtr pMsg(new VideoMsg());
+ pMsg->setAudio(pBuffer, time);
+ m_MsgQ.push(pMsg);
+}
+
+void AudioDecoderThread::pushSeekDone(float time, int seqNum)
+{
+ VideoMsgPtr pMsg(new VideoMsg());
+ pMsg->setSeekDone(seqNum, time);
+ m_MsgQ.push(pMsg);
+}
+
+void AudioDecoderThread::pushEOF()
+{
+ VideoMsgPtr pMsg(new VideoMsg());
+ pMsg->setEOF();
+ m_MsgQ.push(pMsg);
+}
+
+int AudioDecoderThread::getBytesPerSample(int sampleFormat)
+{
+ switch (sampleFormat) {
+ case SAMPLE_FMT_U8:
+ return 1;
+ case SAMPLE_FMT_S16:
+ return 2;
+ case SAMPLE_FMT_S32:
+ return 4;
+ case SAMPLE_FMT_FLT:
+ return 4;
+ case SAMPLE_FMT_DBL:
+ return 8;
+#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(52, 3, 0)
+ case SAMPLE_FMT_S16P:
+ return 2;
+ case SAMPLE_FMT_FLTP:
+ return 4;
+#endif
+ default:
+ AVG_LOG_ERROR("Unknown SampleFormat: " << sampleFormat << "\n");
+ AVG_ASSERT(false);
+ return 0;
+ }
+}
+
+}
diff --git a/src/video/AudioDecoderThread.h b/src/video/AudioDecoderThread.h
new file mode 100644
index 0000000..c8493b2
--- /dev/null
+++ b/src/video/AudioDecoderThread.h
@@ -0,0 +1,88 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+// Original author of this file is Nick Hebner (hebnern@gmail.com).
+//
+
+#ifndef _AudioDecoderThread_H_
+#define _AudioDecoderThread_H_
+
+#include "../avgconfigwrapper.h"
+#include "VideoMsg.h"
+
+#include "../base/WorkerThread.h"
+#include "../base/Command.h"
+#include "../audio/AudioParams.h"
+
+#include "WrapFFMpeg.h"
+
+#include <boost/thread.hpp>
+
+#include <string>
+
+namespace avg {
+
+class AVG_API AudioDecoderThread : public WorkerThread<AudioDecoderThread> {
+ public:
+ AudioDecoderThread(CQueue& cmdQ, AudioMsgQueue& msgQ, VideoMsgQueue& packetQ,
+ AVStream* pStream, const AudioParams& ap);
+ virtual ~AudioDecoderThread();
+
+ bool work();
+
+ private:
+ void decodePacket(AVPacket* pPacket);
+ void handleSeekDone(AVPacket* pPacket);
+ void discardPacket(AVPacket* pPacket);
+ AudioBufferPtr resampleAudio(char* pDecodedData, int framesDecoded,
+ int currentSampleFormat);
+ void insertSilence(float duration);
+ void planarToInterleaved(char* pOutput, char* pInput, int numChannels,
+ int numSamples);
+ void pushAudioMsg(AudioBufferPtr pBuffer, float time);
+ void pushSeekDone(float time, int seqNum);
+ void pushEOF();
+ int getBytesPerSample(int sampleFormat);
+
+ AudioMsgQueue& m_MsgQ;
+ VideoMsgQueue& m_PacketQ;
+ AudioParams m_AP;
+
+ AVStream * m_pStream;
+
+ int m_InputSampleRate;
+ int m_InputSampleFormat;
+#ifdef LIBAVRESAMPLE_VERSION
+ AVAudioResampleContext * m_pResampleContext;
+#else
+ ReSampleContext * m_pResampleContext;
+#endif
+ float m_AudioStartTimestamp;
+ float m_LastFrameTime;
+
+ enum State {DECODING, SEEK_DONE, DISCARDING};
+ State m_State;
+ int m_SeekSeqNum;
+ float m_SeekTime;
+};
+
+}
+#endif
+
diff --git a/src/video/FFMpegDemuxer.cpp b/src/video/FFMpegDemuxer.cpp
new file mode 100644
index 0000000..b092c7d
--- /dev/null
+++ b/src/video/FFMpegDemuxer.cpp
@@ -0,0 +1,153 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "FFMpegDemuxer.h"
+
+#include "../base/ScopeTimer.h"
+#include "../base/ObjectCounter.h"
+#include "../base/Exception.h"
+#include "../base/Logger.h"
+
+#include <cstring>
+#include <iostream>
+
+using namespace std;
+
+namespace avg {
+
+FFMpegDemuxer::FFMpegDemuxer(AVFormatContext * pFormatContext, vector<int> streamIndexes)
+ : m_pFormatContext(pFormatContext)
+{
+ ObjectCounter::get()->incRef(&typeid(*this));
+ for (unsigned i = 0; i < streamIndexes.size(); ++i) {
+ m_PacketLists[streamIndexes[i]] = PacketList();
+ }
+}
+
+FFMpegDemuxer::~FFMpegDemuxer()
+{
+ clearPacketCache();
+ ObjectCounter::get()->decRef(&typeid(*this));
+}
+
+AVPacket * FFMpegDemuxer::getPacket(int streamIndex)
+{
+ // Make sure enableStream was called on streamIndex.
+ AVG_ASSERT(m_PacketLists.size() > 0);
+ AVG_ASSERT(streamIndex > -1 && streamIndex < 10);
+
+ if (m_PacketLists.find(streamIndex) == m_PacketLists.end()) {
+ cerr << this << ": getPacket: Stream " << streamIndex << " not found." << endl;
+ dump();
+ AVG_ASSERT(false);
+ }
+
+ PacketList& curPacketList = m_PacketLists.find(streamIndex)->second;
+ AVPacket* pPacket;
+ if (!curPacketList.empty()) {
+ // The stream has packets queued already.
+ pPacket = curPacketList.front();
+ curPacketList.pop_front();
+ } else {
+ // No packets queued for this stream -> read and queue packets until we get one
+ // that is meant for this stream.
+ do {
+ pPacket = new AVPacket;
+ memset(pPacket, 0, sizeof(AVPacket));
+ int err = av_read_frame(m_pFormatContext, pPacket);
+ if (err < 0) {
+ // EOF or error
+#if LIBAVUTIL_VERSION_MAJOR > 50
+ if (err != int(AVERROR_EOF)) {
+ char sz[256];
+ av_strerror(err, sz, 256);
+ AVG_TRACE(Logger::category::PLAYER, Logger::severity::ERROR,
+ "Error decoding video: " << sz);
+ }
+#endif
+ av_free_packet(pPacket);
+ delete pPacket;
+ pPacket = 0;
+ return 0;
+ }
+ if (pPacket->stream_index != streamIndex) {
+ if (m_PacketLists.find(pPacket->stream_index) != m_PacketLists.end()) {
+ // Relevant stream, but not ours
+ av_dup_packet(pPacket);
+ PacketList& otherPacketList =
+ m_PacketLists.find(pPacket->stream_index)->second;
+ otherPacketList.push_back(pPacket);
+ } else {
+ // Disabled stream
+ av_free_packet(pPacket);
+ delete pPacket;
+ pPacket = 0;
+ }
+ } else {
+ // Our stream
+ av_dup_packet(pPacket);
+ }
+ } while (!pPacket || pPacket->stream_index != streamIndex);
+ }
+
+ return pPacket;
+}
+
+void FFMpegDemuxer::seek(float destTime)
+{
+#if LIBAVFORMAT_BUILD <= 4616
+ av_seek_frame(m_pFormatContext, -1, destTime*1000000);
+#else
+#if LIBAVFORMAT_BUILD < ((49<<16)+(0<<8)+0)
+ av_seek_frame(m_pFormatContext, -1, destTime*1000000, 0);
+#else
+ av_seek_frame(m_pFormatContext, -1, (long long)(destTime*AV_TIME_BASE),
+ AVSEEK_FLAG_BACKWARD);
+#endif
+#endif
+ clearPacketCache();
+}
+
+void FFMpegDemuxer::clearPacketCache()
+{
+ map<int, PacketList>::iterator it;
+ for (it = m_PacketLists.begin(); it != m_PacketLists.end(); ++it) {
+ PacketList::iterator it2;
+ PacketList* pPacketList = &(it->second);
+ for (it2 = pPacketList->begin(); it2 != pPacketList->end(); ++it2) {
+ av_free_packet(*it2);
+ delete *it2;
+ }
+ pPacketList->clear();
+ }
+}
+
+void FFMpegDemuxer::dump()
+{
+ map<int, PacketList>::iterator it;
+ cerr << "FFMpegDemuxer " << this << endl;
+ cerr << "packetlists.size(): " << int(m_PacketLists.size()) << endl;
+ for (it = m_PacketLists.begin(); it != m_PacketLists.end(); ++it) {
+ cerr << " " << it->first << ": " << int(it->second.size()) << endl;
+ }
+}
+
+}
diff --git a/src/video/FFMpegDemuxer.h b/src/video/FFMpegDemuxer.h
new file mode 100644
index 0000000..b8219de
--- /dev/null
+++ b/src/video/FFMpegDemuxer.h
@@ -0,0 +1,58 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _FFMpegDemuxer_H_
+#define _FFMpegDemuxer_H_
+
+#include "../avgconfigwrapper.h"
+
+#include "WrapFFMpeg.h"
+
+#include <list>
+#include <vector>
+#include <map>
+
+#include <boost/shared_ptr.hpp>
+
+namespace avg {
+
+class AVG_API FFMpegDemuxer {
+ public:
+ FFMpegDemuxer(AVFormatContext * pFormatContext, std::vector<int> streamIndexes);
+ virtual ~FFMpegDemuxer();
+
+ AVPacket * getPacket(int streamIndex);
+ void seek(float destTime);
+ void dump();
+
+ private:
+ void clearPacketCache();
+
+ // Packets that haven't been delivered yet.
+ typedef std::list<AVPacket *> PacketList;
+ std::map<int, PacketList> m_PacketLists;
+
+ AVFormatContext * m_pFormatContext;
+};
+typedef boost::shared_ptr<FFMpegDemuxer> FFMpegDemuxerPtr;
+}
+
+#endif
diff --git a/src/video/FFMpegFrameDecoder.cpp b/src/video/FFMpegFrameDecoder.cpp
new file mode 100644
index 0000000..685b341
--- /dev/null
+++ b/src/video/FFMpegFrameDecoder.cpp
@@ -0,0 +1,258 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "FFMpegFrameDecoder.h"
+#include "FFMpegDemuxer.h"
+#include "VideoInfo.h"
+#ifdef AVG_ENABLE_VDPAU
+#include "VDPAUDecoder.h"
+#endif
+
+#include "../base/Exception.h"
+#include "../base/Logger.h"
+#include "../base/ScopeTimer.h"
+#include "../base/ObjectCounter.h"
+#include "../base/ProfilingZoneID.h"
+#include "../base/StringHelper.h"
+
+#include <iostream>
+#include <sstream>
+#ifndef _WIN32
+#include <unistd.h>
+#endif
+
+using namespace std;
+
+namespace avg {
+
+FFMpegFrameDecoder::FFMpegFrameDecoder(AVStream* pStream)
+ : m_pSwsContext(0),
+ m_pStream(pStream),
+ m_bEOF(false),
+ m_StartTimestamp(-1),
+ m_LastFrameTime(-1),
+ m_bUseStreamFPS(true)
+{
+ m_TimeUnitsPerSecond = float(1.0/av_q2d(pStream->time_base));
+ m_FPS = getStreamFPS(pStream);
+
+ ObjectCounter::get()->incRef(&typeid(*this));
+}
+
+FFMpegFrameDecoder::~FFMpegFrameDecoder()
+{
+ if (m_pSwsContext) {
+ sws_freeContext(m_pSwsContext);
+ m_pSwsContext = 0;
+ }
+ ObjectCounter::get()->decRef(&typeid(*this));
+}
+
+static ProfilingZoneID DecodePacketProfilingZone("Decode packet", true);
+
+bool FFMpegFrameDecoder::decodePacket(AVPacket* pPacket, AVFrame* pFrame,
+ bool bFrameAfterSeek)
+{
+ ScopeTimer timer(DecodePacketProfilingZone);
+ int bGotPicture = 0;
+ AVCodecContext* pContext = m_pStream->codec;
+ AVG_ASSERT(pPacket);
+ avcodec_decode_video2(pContext, pFrame, &bGotPicture, pPacket);
+ if (bGotPicture) {
+ m_LastFrameTime = getFrameTime(pPacket->dts, bFrameAfterSeek);
+ }
+ av_free_packet(pPacket);
+ delete pPacket;
+ return (bGotPicture != 0);
+}
+
+bool FFMpegFrameDecoder::decodeLastFrame(AVFrame* pFrame)
+{
+ // EOF. Decode the last data we got.
+ int bGotPicture = 0;
+ AVCodecContext* pContext = m_pStream->codec;
+ AVPacket packet;
+ av_init_packet(&packet);
+ packet.data = 0;
+ packet.size = 0;
+ avcodec_decode_video2(pContext, pFrame, &bGotPicture, &packet);
+ m_bEOF = true;
+
+ // We don't have a timestamp for the last frame, so we'll
+ // calculate it based on the frame before.
+ m_LastFrameTime += 1.0f/m_FPS;
+ return (bGotPicture != 0);
+}
+
+
+static ProfilingZoneID ConvertImageLibavgProfilingZone(
+ "FFMpeg: colorspace conv (libavg)", true);
+static ProfilingZoneID ConvertImageSWSProfilingZone(
+ "FFMpeg: colorspace conv (SWS)", true);
+static ProfilingZoneID SetAlphaProfilingZone("FFMpeg: set alpha channel", true);
+
+void FFMpegFrameDecoder::convertFrameToBmp(AVFrame* pFrame, BitmapPtr pBmp)
+{
+ AVPicture destPict;
+ unsigned char * pDestBits = pBmp->getPixels();
+ destPict.data[0] = pDestBits;
+ destPict.linesize[0] = pBmp->getStride();
+ AVPixelFormat destFmt;
+ switch (pBmp->getPixelFormat()) {
+ case R8G8B8X8:
+ case R8G8B8A8:
+ destFmt = PIX_FMT_RGBA;
+ break;
+ case B8G8R8X8:
+ case B8G8R8A8:
+ destFmt = PIX_FMT_BGRA;
+ break;
+ case R8G8B8:
+ destFmt = PIX_FMT_RGB24;
+ break;
+ case B8G8R8:
+ destFmt = PIX_FMT_BGR24;
+ break;
+ case YCbCr422:
+ destFmt = PIX_FMT_YUYV422;
+ break;
+ default:
+ AVG_ASSERT_MSG(false, (string("FFMpegFrameDecoder: Dest format ") +
+ toString(pBmp->getPixelFormat()) + " not supported.").c_str());
+ destFmt = PIX_FMT_BGRA;
+ }
+ AVCodecContext const* pContext = m_pStream->codec;
+ if (destFmt == PIX_FMT_BGRA && (pContext->pix_fmt == PIX_FMT_YUV420P ||
+ pContext->pix_fmt == PIX_FMT_YUVJ420P))
+ {
+ ScopeTimer timer(ConvertImageLibavgProfilingZone);
+ BitmapPtr pBmpY(new Bitmap(pBmp->getSize(), I8, pFrame->data[0],
+ pFrame->linesize[0], false));
+ BitmapPtr pBmpU(new Bitmap(pBmp->getSize(), I8, pFrame->data[1],
+ pFrame->linesize[1], false));
+ BitmapPtr pBmpV(new Bitmap(pBmp->getSize(), I8, pFrame->data[2],
+ pFrame->linesize[2], false));
+ pBmp->copyYUVPixels(*pBmpY, *pBmpU, *pBmpV,
+ pContext->pix_fmt == PIX_FMT_YUVJ420P);
+ } else {
+ if (!m_pSwsContext) {
+ m_pSwsContext = sws_getContext(pContext->width, pContext->height,
+ pContext->pix_fmt, pContext->width, pContext->height, destFmt,
+ SWS_BICUBIC, 0, 0, 0);
+ AVG_ASSERT(m_pSwsContext);
+ }
+ {
+ ScopeTimer timer(ConvertImageSWSProfilingZone);
+ sws_scale(m_pSwsContext, pFrame->data, pFrame->linesize, 0,
+ pContext->height, destPict.data, destPict.linesize);
+ }
+ if (pBmp->getPixelFormat() == B8G8R8X8 || pBmp->getPixelFormat() == R8G8B8X8) {
+ ScopeTimer timer(SetAlphaProfilingZone);
+ // Make sure the alpha channel is white.
+ // TODO: This is slow. Make OpenGL do it.
+ unsigned char * pLine = pBmp->getPixels();
+ IntPoint size = pBmp->getSize();
+ for (int y = 0; y < size.y; ++y) {
+ unsigned char * pPixel = pLine;
+ for (int x = 0; x < size.x; ++x) {
+ pPixel[3] = 0xFF;
+ pPixel += 4;
+ }
+ pLine = pLine + pBmp->getStride();
+ }
+ }
+ }
+}
+
+void FFMpegFrameDecoder::copyPlaneToBmp(BitmapPtr pBmp, unsigned char * pData, int stride)
+{
+ unsigned char * pSrc=pData;
+ unsigned char * pDest= pBmp->getPixels();
+ int destStride = pBmp->getStride();
+ int height = pBmp->getSize().y;
+ int width = pBmp->getSize().x;
+ for (int y = 0; y < height; y++) {
+ memcpy(pDest, pSrc, width);
+ pSrc += stride;
+ pDest += destStride;
+ }
+}
+
+void FFMpegFrameDecoder::handleSeek()
+{
+ m_LastFrameTime = -1.0f;
+ avcodec_flush_buffers(m_pStream->codec);
+ m_bEOF = false;
+ if (m_StartTimestamp == -1) {
+ m_StartTimestamp = 0;
+ }
+}
+
+float FFMpegFrameDecoder::getCurTime() const
+{
+ return m_LastFrameTime;
+}
+
+float FFMpegFrameDecoder::getFPS() const
+{
+ return m_FPS;
+}
+
+void FFMpegFrameDecoder::setFPS(float fps)
+{
+ m_bUseStreamFPS = (fps == 0);
+ if (fps == 0) {
+ m_FPS = getStreamFPS(m_pStream);
+ } else {
+ m_FPS = fps;
+ }
+}
+
+bool FFMpegFrameDecoder::isEOF() const
+{
+ return m_bEOF;
+}
+
+float FFMpegFrameDecoder::getFrameTime(long long dts, bool bFrameAfterSeek)
+{
+ bool bUseStreamFPS = m_bUseStreamFPS;
+ if (dts == (long long)AV_NOPTS_VALUE) {
+ bUseStreamFPS = false;
+ dts = 0;
+ }
+ if (m_StartTimestamp == -1) {
+ m_StartTimestamp = dts;
+ }
+ float frameTime;
+ if (bUseStreamFPS || bFrameAfterSeek) {
+ frameTime = float(dts-m_StartTimestamp)/m_TimeUnitsPerSecond;
+ } else {
+ if (m_LastFrameTime == -1) {
+ frameTime = 0;
+ } else {
+ frameTime = m_LastFrameTime + 1.0f/m_FPS;
+ }
+ }
+ return frameTime;
+}
+
+}
+
diff --git a/src/video/FFMpegFrameDecoder.h b/src/video/FFMpegFrameDecoder.h
new file mode 100644
index 0000000..51b875f
--- /dev/null
+++ b/src/video/FFMpegFrameDecoder.h
@@ -0,0 +1,72 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _FFMpegFrameDecoder_H_
+#define _FFMpegFrameDecoder_H_
+
+#include "../avgconfigwrapper.h"
+
+#include "../graphics/Bitmap.h"
+
+#include "WrapFFMpeg.h"
+
+namespace avg {
+
+class AVG_API FFMpegFrameDecoder
+{
+ public:
+ FFMpegFrameDecoder(AVStream* pStream);
+ virtual ~FFMpegFrameDecoder();
+
+ bool decodePacket(AVPacket* pPacket, AVFrame* pFrame, bool bFrameAfterSeek);
+ bool decodeLastFrame(AVFrame* pFrame);
+ void convertFrameToBmp(AVFrame* pFrame, BitmapPtr pBmp);
+ void copyPlaneToBmp(BitmapPtr pBmp, unsigned char * pData, int stride);
+
+ void handleSeek();
+
+ virtual float getCurTime() const;
+ virtual float getFPS() const;
+ virtual void setFPS(float fps);
+
+ virtual bool isEOF() const;
+
+ private:
+ float getFrameTime(long long dts, bool bFrameAfterSeek);
+
+ SwsContext * m_pSwsContext;
+ AVStream* m_pStream;
+
+ bool m_bEOF;
+
+ float m_TimeUnitsPerSecond;
+ long long m_StartTimestamp;
+ float m_LastFrameTime;
+
+ bool m_bUseStreamFPS;
+ float m_FPS;
+};
+
+typedef boost::shared_ptr<FFMpegFrameDecoder> FFMpegFrameDecoderPtr;
+
+}
+#endif
+
diff --git a/src/video/Makefile.am b/src/video/Makefile.am
new file mode 100644
index 0000000..a48d1f6
--- /dev/null
+++ b/src/video/Makefile.am
@@ -0,0 +1,50 @@
+AM_CPPFLAGS = -I.. @XML2_CFLAGS@ @PTHREAD_CFLAGS@ @GDK_PIXBUF_CFLAGS@
+
+if APPLE
+ X_LIBS =
+else
+if ENABLE_RPI
+ X_LIBS = -lX11 -lGLESv2 -lEGL
+else
+if ENABLE_EGL
+ X_LIBS = -lXxf86vm -lX11 -lGLESv2 -lEGL
+else
+ X_LIBS = -lXxf86vm -lX11
+endif
+endif
+endif
+
+ALL_H = FFMpegDemuxer.h VideoDemuxerThread.h VideoDecoder.h \
+ VideoDecoderThread.h AudioDecoderThread.h VideoMsg.h FFMpegFrameDecoder.h \
+ AsyncVideoDecoder.h VideoDecoderThread.h SyncVideoDecoder.h \
+ VideoInfo.h WrapFFMpeg.h
+
+if USE_VDPAU_SRC
+ ALL_H += VDPAUDecoder.h VDPAUHelper.h
+endif
+
+TESTS = testvideo
+
+EXTRA_DIST = $(wildcard baseline/*.png)
+
+noinst_LTLIBRARIES = libvideo.la
+noinst_PROGRAMS = testvideo
+
+libvideo_la_SOURCES = FFMpegDemuxer.cpp VideoDemuxerThread.cpp VideoDecoder.cpp \
+ VideoDecoderThread.cpp AudioDecoderThread.cpp VideoMsg.cpp \
+ AsyncVideoDecoder.cpp VideoInfo.cpp SyncVideoDecoder.cpp \
+ FFMpegFrameDecoder.cpp \
+ $(ALL_H)
+
+if USE_VDPAU_SRC
+ libvideo_la_SOURCES += VDPAUDecoder.cpp VDPAUHelper.cpp
+endif
+
+libvideo_la_LIBADD = @LIBVIDEO_LDADD@
+
+testvideo_SOURCES = testvideo.cpp $(ALL_H)
+testvideo_LDADD = ./libvideo.la ../audio/libaudio.la ../graphics/libgraphics.la \
+ ../base/libbase.la ../base/triangulate/libtriangulate.la -ldl \
+ @GL_LIBS@ @GLU_LIBS@ @SDL_LIBS@ @XML2_LIBS@ \
+ @BOOST_THREAD_LIBS@ @PTHREAD_LIBS@ @LIBFFMPEG@ @LIBAVRESAMPLE@ @GDK_PIXBUF_LIBS@ \
+ $(X_LIBS)
diff --git a/src/video/SyncVideoDecoder.cpp b/src/video/SyncVideoDecoder.cpp
new file mode 100644
index 0000000..a0c62ce
--- /dev/null
+++ b/src/video/SyncVideoDecoder.cpp
@@ -0,0 +1,261 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "SyncVideoDecoder.h"
+#include "FFMpegDemuxer.h"
+
+#include "../base/Exception.h"
+#include "../base/Logger.h"
+#include "../base/ScopeTimer.h"
+#include "../base/ObjectCounter.h"
+#include "../base/ProfilingZoneID.h"
+#include "../base/StringHelper.h"
+
+#include "../graphics/BitmapLoader.h"
+
+#include <iostream>
+#include <sstream>
+#ifndef _WIN32
+#include <unistd.h>
+#endif
+
+using namespace std;
+
+namespace avg {
+
+SyncVideoDecoder::SyncVideoDecoder()
+ : m_pDemuxer(0),
+ m_bFirstPacket(false),
+ m_bUseStreamFPS(true),
+ m_FPS(0)
+{
+ ObjectCounter::get()->incRef(&typeid(*this));
+}
+
+SyncVideoDecoder::~SyncVideoDecoder()
+{
+ ObjectCounter::get()->decRef(&typeid(*this));
+}
+
+void SyncVideoDecoder::open(const string& sFilename, bool bUseHardwareAcceleration,
+ bool bEnableSound)
+{
+ m_bProcessingLastFrames = false;
+ VideoDecoder::open(sFilename, false, false);
+
+ if (getVStreamIndex() >= 0) {
+ if (m_bUseStreamFPS) {
+ m_FPS = getStreamFPS();
+ }
+ m_bFirstPacket = true;
+ m_bVideoSeekDone = false;
+ }
+}
+
+void SyncVideoDecoder::startDecoding(bool bDeliverYCbCr, const AudioParams* pAP)
+{
+ VideoDecoder::startDecoding(bDeliverYCbCr, 0);
+
+ AVG_ASSERT(!m_pDemuxer);
+ vector<int> streamIndexes;
+ streamIndexes.push_back(getVStreamIndex());
+ m_pDemuxer = new FFMpegDemuxer(getFormatContext(), streamIndexes);
+
+ m_pFrameDecoder = FFMpegFrameDecoderPtr(new FFMpegFrameDecoder(getVideoStream()));
+ m_pFrameDecoder->setFPS(m_FPS);
+#if LIBAVCODEC_VERSION_INT > AV_VERSION_INT(54, 28, 0)
+ m_pFrame = avcodec_alloc_frame();
+#else
+ m_pFrame = new AVFrame;
+#endif
+}
+
+void SyncVideoDecoder::close()
+{
+ delete m_pDemuxer;
+ m_pDemuxer = 0;
+
+ m_pFrameDecoder = FFMpegFrameDecoderPtr();
+ VideoDecoder::close();
+#if LIBAVCODEC_VERSION_INT > AV_VERSION_INT(54, 28, 0)
+ avcodec_free_frame(&m_pFrame);
+#else
+ delete m_pFrame;
+#endif
+}
+
+void SyncVideoDecoder::seek(float destTime)
+{
+ AVG_ASSERT(getState() == DECODING);
+
+ if (m_bFirstPacket) {
+ readFrame(m_pFrame);
+ }
+ m_pDemuxer->seek(destTime);
+ m_bVideoSeekDone = true;
+ m_pFrameDecoder->handleSeek();
+}
+
+void SyncVideoDecoder::loop()
+{
+ seek(0);
+}
+
+int SyncVideoDecoder::getCurFrame() const
+{
+ return int(getCurTime()*getStreamFPS()+0.49);
+}
+
+int SyncVideoDecoder::getNumFramesQueued() const
+{
+ return 0;
+}
+
+float SyncVideoDecoder::getCurTime() const
+{
+ AVG_ASSERT(getState() != CLOSED);
+ if (m_pFrameDecoder) {
+ return m_pFrameDecoder->getCurTime();
+ } else {
+ return 0;
+ }
+}
+
+float SyncVideoDecoder::getFPS() const
+{
+ AVG_ASSERT(getState() != CLOSED);
+ return m_FPS;
+}
+
+void SyncVideoDecoder::setFPS(float fps)
+{
+ m_bUseStreamFPS = (fps == 0);
+ if (fps == 0) {
+ m_FPS = getStreamFPS();
+ } else {
+ m_FPS = fps;
+ }
+ if (m_pFrameDecoder) {
+ m_pFrameDecoder->setFPS(m_FPS);
+ }
+}
+
+static ProfilingZoneID RenderToBmpProfilingZone("FFMpeg: renderToBmp", true);
+static ProfilingZoneID CopyImageProfilingZone("FFMpeg: copy image", true);
+
+FrameAvailableCode SyncVideoDecoder::renderToBmps(vector<BitmapPtr>& pBmps,
+ float timeWanted)
+{
+ AVG_ASSERT(getState() == DECODING);
+ ScopeTimer timer(RenderToBmpProfilingZone);
+ FrameAvailableCode frameAvailable;
+ if (timeWanted == -1) {
+ readFrame(m_pFrame);
+ frameAvailable = FA_NEW_FRAME;
+ } else {
+ frameAvailable = readFrameForTime(m_pFrame, timeWanted);
+ }
+ if (frameAvailable == FA_USE_LAST_FRAME || isEOF()) {
+ return FA_USE_LAST_FRAME;
+ } else {
+ if (pixelFormatIsPlanar(getPixelFormat())) {
+ ScopeTimer timer(CopyImageProfilingZone);
+ for (unsigned i = 0; i < pBmps.size(); ++i) {
+ m_pFrameDecoder->copyPlaneToBmp(pBmps[i], m_pFrame->data[i],
+ m_pFrame->linesize[i]);
+ }
+ } else {
+ m_pFrameDecoder->convertFrameToBmp(m_pFrame, pBmps[0]);
+ }
+ return FA_NEW_FRAME;
+ }
+}
+
+void SyncVideoDecoder::throwAwayFrame(float timeWanted)
+{
+ AVG_ASSERT(getState() == DECODING);
+ readFrameForTime(m_pFrame, timeWanted);
+}
+
+bool SyncVideoDecoder::isEOF() const
+{
+ AVG_ASSERT(getState() == DECODING);
+ return m_pFrameDecoder->isEOF() && !m_bProcessingLastFrames;
+}
+
+FrameAvailableCode SyncVideoDecoder::readFrameForTime(AVFrame* pFrame, float timeWanted)
+{
+ AVG_ASSERT(getState() == DECODING);
+ float timePerFrame = 1.0f/m_FPS;
+ if (!m_bVideoSeekDone && timeWanted-m_pFrameDecoder->getCurTime() < 0.5f*timePerFrame)
+ {
+ // The last frame is still current. Display it again.
+ return FA_USE_LAST_FRAME;
+ } else {
+ bool bInvalidFrame = true;
+ while (bInvalidFrame && !isEOF()) {
+ readFrame(pFrame);
+ bInvalidFrame = m_pFrameDecoder->getCurTime()-timeWanted < -0.5f*timePerFrame;
+ }
+ }
+ if (m_bVideoSeekDone) {
+ m_bVideoSeekDone = false;
+ }
+ return FA_NEW_FRAME;
+}
+
+static ProfilingZoneID DecodeProfilingZone("FFMpeg: decode", true);
+
+void SyncVideoDecoder::readFrame(AVFrame* pFrame)
+{
+ AVG_ASSERT(getState() == DECODING);
+ ScopeTimer timer(DecodeProfilingZone);
+
+ if (m_bProcessingLastFrames) {
+ // EOF received, but last frames still need to be decoded.
+ bool bGotPicture = m_pFrameDecoder->decodeLastFrame(pFrame);
+ if (!bGotPicture) {
+ m_bProcessingLastFrames = false;
+ }
+ } else {
+ bool bDone = false;
+ while (!bDone) {
+ AVPacket* pPacket = m_pDemuxer->getPacket(getVStreamIndex());
+ m_bFirstPacket = false;
+ bool bGotPicture;
+ if (pPacket) {
+ bGotPicture = m_pFrameDecoder->decodePacket(pPacket, pFrame,
+ m_bVideoSeekDone);
+ } else {
+ bGotPicture = m_pFrameDecoder->decodeLastFrame(pFrame);
+ }
+ if (bGotPicture && m_pFrameDecoder->isEOF()) {
+ m_bProcessingLastFrames = true;
+ }
+ if (bGotPicture || m_pFrameDecoder->isEOF()) {
+ bDone = true;
+ }
+ }
+ }
+}
+
+}
+
diff --git a/src/video/SyncVideoDecoder.h b/src/video/SyncVideoDecoder.h
new file mode 100644
index 0000000..345e8f6
--- /dev/null
+++ b/src/video/SyncVideoDecoder.h
@@ -0,0 +1,77 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _SyncVideoDecoder_H_
+#define _SyncVideoDecoder_H_
+
+#include "../avgconfigwrapper.h"
+#include "VideoDecoder.h"
+#include "FFMpegDemuxer.h"
+#include "FFMpegFrameDecoder.h"
+
+namespace avg {
+
+class AVG_API SyncVideoDecoder: public VideoDecoder
+{
+ public:
+ SyncVideoDecoder();
+ virtual ~SyncVideoDecoder();
+ virtual void open(const std::string& sFilename, bool bUseHardwareAcceleration,
+ bool bEnableSound);
+ virtual void startDecoding(bool bDeliverYCbCr, const AudioParams* pAP);
+ virtual void close();
+
+
+ virtual int getCurFrame() const;
+ virtual int getNumFramesQueued() const;
+ virtual float getCurTime() const;
+ virtual float getFPS() const;
+ virtual void setFPS(float fps);
+ virtual FrameAvailableCode renderToBmps(std::vector<BitmapPtr>& pBmps,
+ float timeWanted);
+ virtual void throwAwayFrame(float timeWanted);
+
+ virtual void seek(float destTime);
+ virtual void loop();
+ virtual bool isEOF() const;
+
+ private:
+ FrameAvailableCode readFrameForTime(AVFrame* pFrame, float timeWanted);
+ void readFrame(AVFrame* pFrame);
+
+ FFMpegFrameDecoderPtr m_pFrameDecoder;
+ bool m_bVideoSeekDone;
+
+ FFMpegDemuxer * m_pDemuxer;
+
+ bool m_bProcessingLastFrames;
+ bool m_bFirstPacket;
+
+ bool m_bUseStreamFPS;
+ float m_FPS;
+ AVFrame* m_pFrame;
+};
+
+typedef boost::shared_ptr<SyncVideoDecoder> SyncVideoDecoderPtr;
+
+}
+#endif
+
diff --git a/src/video/VDPAUDecoder.cpp b/src/video/VDPAUDecoder.cpp
new file mode 100644
index 0000000..2a344d6
--- /dev/null
+++ b/src/video/VDPAUDecoder.cpp
@@ -0,0 +1,251 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+#include "VDPAUDecoder.h"
+#include "VDPAUHelper.h"
+
+#include "../base/Exception.h"
+
+#include <iostream>
+
+/*
+Notes on adding Render-to-texture support:
+- For every Surface, call
+ VDPAURegisterSurfaceNV()
+ VDPAUSurfaceAccessNV(..., READ)
+- VideoNode: Create OGLSurface and GLTexture objs each frame from texids,
+ map VDPAU surfaces while textures exist.
+- New OGLSurface pixel format VDPAU_INTERLACED
+- Support new OGLSurface pixel format in shader
+*/
+
+using namespace std;
+
+namespace avg {
+
+VDPAUDecoder::VDPAUDecoder()
+ : m_VDPDecoder(VDP_INVALID_HANDLE),
+ m_VDPMixer(VDP_INVALID_HANDLE),
+ m_PixFmt(PIX_FMT_NONE),
+ m_Size(-1,-1)
+{
+}
+
+VDPAUDecoder::~VDPAUDecoder()
+{
+ if (m_VDPMixer != VDP_INVALID_HANDLE) {
+ vdp_video_mixer_destroy(m_VDPMixer);
+ }
+ if (m_VDPDecoder != VDP_INVALID_HANDLE) {
+ vdp_decoder_destroy(m_VDPDecoder);
+ }
+ for (unsigned i = 0; i < m_RenderStates.size(); i++) {
+ vdp_video_surface_destroy(m_RenderStates[i]->surface);
+ delete m_RenderStates[i];
+ }
+}
+
+AVCodec* VDPAUDecoder::openCodec(AVCodecContext* pContext)
+{
+ if (!isAvailable()) {
+ return 0;
+ }
+
+ AVCodec* pCodec = 0;
+ switch (pContext->codec_id) {
+ case AV_CODEC_ID_MPEG1VIDEO:
+ pCodec = avcodec_find_decoder_by_name("mpeg1video_vdpau");
+ if(pCodec) {
+ pCodec->id = AV_CODEC_ID_MPEG1VIDEO;
+ }
+ break;
+ case AV_CODEC_ID_MPEG2VIDEO:
+ pCodec = avcodec_find_decoder_by_name("mpegvideo_vdpau");
+ break;
+ case AV_CODEC_ID_H264:
+ pCodec = avcodec_find_decoder_by_name("h264_vdpau");
+ break;
+ case AV_CODEC_ID_WMV3:
+ pCodec = avcodec_find_decoder_by_name("wmv3_vdpau");
+ break;
+ case AV_CODEC_ID_VC1:
+ pCodec = avcodec_find_decoder_by_name("vc1_vdpau");
+ break;
+ default:
+ pCodec = 0;
+ }
+ if (pCodec) {
+ pContext->get_buffer = VDPAUDecoder::getBuffer;
+ pContext->release_buffer = VDPAUDecoder::releaseBuffer;
+ pContext->draw_horiz_band = VDPAUDecoder::drawHorizBand;
+ pContext->get_format = VDPAUDecoder::getFormat;
+ pContext->slice_flags = SLICE_FLAG_CODED_ORDER | SLICE_FLAG_ALLOW_FIELD;
+ m_Size = IntPoint(pContext->width, pContext->height);
+ }
+ return pCodec;
+}
+
+bool VDPAUDecoder::isAvailable()
+{
+#if LIBAVCODEC_VERSION_INT > AV_VERSION_INT(53, 34, 0)
+ return getVDPAUDevice() != 0;
+#else
+ return false;
+#endif
+}
+
+int VDPAUDecoder::getBuffer(AVCodecContext* pContext, AVFrame* pFrame)
+{
+ VDPAUDecoder* pVDPAUDecoder = (VDPAUDecoder*)pContext->opaque;
+ return pVDPAUDecoder->getBufferInternal(pContext, pFrame);
+}
+
+// does not release the render structure, that will be unlocked after getting data
+void VDPAUDecoder::releaseBuffer(struct AVCodecContext* pContext, AVFrame* pFrame)
+{
+ pFrame->data[0] = 0;
+}
+
+
+// main rendering routine
+void VDPAUDecoder::drawHorizBand(struct AVCodecContext* pContext, const AVFrame* src,
+ int offset[4], int y, int type, int height)
+{
+ VDPAUDecoder* pVDPAUDecoder = (VDPAUDecoder*)pContext->opaque;
+ pVDPAUDecoder->render(pContext, src);
+}
+
+AVPixelFormat VDPAUDecoder::getFormat(AVCodecContext* pContext, const AVPixelFormat* pFmt)
+{
+ switch (pContext->codec_id) {
+ case AV_CODEC_ID_H264:
+ return PIX_FMT_VDPAU_H264;
+ case AV_CODEC_ID_MPEG1VIDEO:
+ return PIX_FMT_VDPAU_MPEG1;
+ case AV_CODEC_ID_MPEG2VIDEO:
+ return PIX_FMT_VDPAU_MPEG2;
+ case AV_CODEC_ID_WMV3:
+ return PIX_FMT_VDPAU_WMV3;
+ case AV_CODEC_ID_VC1:
+ return PIX_FMT_VDPAU_VC1;
+ default:
+ return pFmt[0];
+ }
+}
+
+vdpau_render_state* VDPAUDecoder::getFreeRenderState()
+{
+ for (unsigned i = 0; i < m_RenderStates.size(); i++) {
+ vdpau_render_state* pRenderState = m_RenderStates[i];
+ if (!(pRenderState->state & FF_VDPAU_STATE_USED_FOR_REFERENCE)) {
+ return m_RenderStates[i];
+ }
+ }
+
+ // No free surfaces available -> create new surface
+ vdpau_render_state* pRenderState = new vdpau_render_state;
+ m_RenderStates.push_back(pRenderState);
+ memset(pRenderState, 0, sizeof(vdpau_render_state));
+ pRenderState->surface = VDP_INVALID_HANDLE;
+ VdpStatus status = vdp_video_surface_create(getVDPAUDevice(), VDP_CHROMA_TYPE_420,
+ m_Size.x, m_Size.y, &pRenderState->surface);
+ AVG_ASSERT(status == VDP_STATUS_OK);
+
+ return pRenderState;
+}
+
+int VDPAUDecoder::getBufferInternal(AVCodecContext* pContext, AVFrame* pFrame)
+{
+ vdpau_render_state* pRenderState = getFreeRenderState();
+ pFrame->data[0] = (uint8_t*)pRenderState;
+ pFrame->type = FF_BUFFER_TYPE_USER;
+
+ pRenderState->state |= FF_VDPAU_STATE_USED_FOR_REFERENCE;
+ return 0;
+}
+
+void VDPAUDecoder::render(AVCodecContext* pContext, const AVFrame* pFrame)
+{
+ vdpau_render_state* pRenderState = (vdpau_render_state*)pFrame->data[0];
+
+ if (m_VDPDecoder == VDP_INVALID_HANDLE) {
+ setupDecoder(pContext);
+ }
+
+ VdpStatus status = vdp_decoder_render(m_VDPDecoder, pRenderState->surface,
+ (VdpPictureInfo const*)&(pRenderState->info),
+ pRenderState->bitstream_buffers_used, pRenderState->bitstream_buffers);
+ AVG_ASSERT(status == VDP_STATUS_OK);
+}
+
+void VDPAUDecoder::setupDecoder(AVCodecContext* pContext)
+{
+ VdpStatus status;
+
+ // Create new decoder and mixer.
+ VdpDecoderProfile profile = 0;
+ switch (pContext->pix_fmt) {
+ case PIX_FMT_VDPAU_MPEG1:
+ profile = VDP_DECODER_PROFILE_MPEG1;
+ break;
+ case PIX_FMT_VDPAU_MPEG2:
+ profile = VDP_DECODER_PROFILE_MPEG2_MAIN;
+ break;
+ case PIX_FMT_VDPAU_H264:
+ profile = VDP_DECODER_PROFILE_H264_HIGH;
+ break;
+ case PIX_FMT_VDPAU_WMV3:
+ profile = VDP_DECODER_PROFILE_VC1_SIMPLE;
+ break;
+ case PIX_FMT_VDPAU_VC1:
+ profile = VDP_DECODER_PROFILE_VC1_SIMPLE;
+ break;
+ default:
+ AVG_ASSERT(false);
+ }
+ status = vdp_decoder_create(getVDPAUDevice(), profile, m_Size.x, m_Size.y, 16,
+ &m_VDPDecoder);
+ AVG_ASSERT(status == VDP_STATUS_OK);
+
+ m_PixFmt = pContext->pix_fmt;
+
+ VdpVideoMixerFeature features[] = {
+ VDP_VIDEO_MIXER_FEATURE_DEINTERLACE_TEMPORAL,
+ VDP_VIDEO_MIXER_FEATURE_DEINTERLACE_TEMPORAL_SPATIAL,
+ };
+ VdpVideoMixerParameter params[] = {
+ VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_WIDTH,
+ VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_HEIGHT,
+ VDP_VIDEO_MIXER_PARAMETER_CHROMA_TYPE,
+ VDP_VIDEO_MIXER_PARAMETER_LAYERS
+ };
+ VdpChromaType chroma = VDP_CHROMA_TYPE_420;
+ int numLayers = 0;
+ void const* paramValues [] = { &m_Size.x, &m_Size.y, &chroma, &numLayers };
+
+ status = vdp_video_mixer_create(getVDPAUDevice(), 2, features, 4, params,
+ paramValues, &m_VDPMixer);
+ AVG_ASSERT(status == VDP_STATUS_OK);
+
+}
+
+}
+
+
diff --git a/src/video/VDPAUDecoder.h b/src/video/VDPAUDecoder.h
new file mode 100644
index 0000000..15dc5b4
--- /dev/null
+++ b/src/video/VDPAUDecoder.h
@@ -0,0 +1,67 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+#ifndef _VDPAUDecoder_H_
+#define _VDPAUDecoder_H_
+
+
+#include "../avgconfigwrapper.h"
+#include "../base/GLMHelper.h"
+
+#include "WrapFFMpeg.h"
+
+#include <vdpau/vdpau.h>
+#include <libavcodec/vdpau.h>
+
+namespace avg {
+
+class VDPAUDecoder
+{
+public:
+ VDPAUDecoder();
+ ~VDPAUDecoder();
+ AVCodec* openCodec(AVCodecContext* pCodec);
+
+ static bool isAvailable();
+
+private:
+ // Callbacks
+ static int getBuffer(AVCodecContext* pContext, AVFrame* pFrame);
+ static void releaseBuffer(struct AVCodecContext* pContext, AVFrame* pFrame);
+ static void drawHorizBand(AVCodecContext* pContext, const AVFrame* pFrame,
+ int offset[4], int y, int type, int height);
+ static AVPixelFormat getFormat(AVCodecContext* pContext, const AVPixelFormat* pFmt);
+
+ vdpau_render_state* getFreeRenderState();
+ int getBufferInternal(AVCodecContext* pContext, AVFrame* pFrame);
+ void render(AVCodecContext* pContext, const AVFrame* pFrame);
+ void setupDecoder(AVCodecContext* pContext);
+
+ VdpDecoder m_VDPDecoder;
+ VdpVideoMixer m_VDPMixer;
+ AVPixelFormat m_PixFmt;
+ IntPoint m_Size;
+ std::vector<vdpau_render_state*> m_RenderStates;
+
+};
+
+}
+#endif
+
diff --git a/src/video/VDPAUHelper.cpp b/src/video/VDPAUHelper.cpp
new file mode 100644
index 0000000..36d8a9f
--- /dev/null
+++ b/src/video/VDPAUHelper.cpp
@@ -0,0 +1,182 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "VDPAUHelper.h"
+
+#include "../base/Exception.h"
+#include "../base/ConfigMgr.h"
+
+#include "../graphics/Bitmap.h"
+
+#include <dlfcn.h>
+
+using namespace std;
+
+namespace avg {
+
+VdpGetProcAddress* vdp_get_proc_address;
+
+VdpVideoSurfaceGetParameters* vdp_video_surface_get_parameters;
+VdpVideoSurfaceGetBitsYCbCr* vdp_video_surface_get_bits_y_cb_cr;
+VdpVideoSurfaceCreate* vdp_video_surface_create;
+VdpVideoSurfaceDestroy* vdp_video_surface_destroy;
+
+VdpDeviceDestroy* vdp_device_destroy;
+
+VdpDecoderCreate* vdp_decoder_create;
+VdpDecoderDestroy* vdp_decoder_destroy;
+VdpDecoderRender* vdp_decoder_render;
+
+VdpOutputSurfaceCreate* vdp_output_surface_create;
+VdpOutputSurfaceDestroy* vdp_output_surface_destroy;
+VdpOutputSurfaceGetBitsNative* vdp_output_surface_get_bits_native;
+VdpOutputSurfaceGetParameters* vdp_output_surface_get_parameters;
+
+VdpVideoMixerCreate* vdp_video_mixer_create;
+VdpVideoMixerDestroy* vdp_video_mixer_destroy;
+VdpVideoMixerRender* vdp_video_mixer_render;
+
+VdpPresentationQueueCreate* vdp_presentation_queue_create;
+VdpPresentationQueueDestroy* vdp_presentation_queue_destroy;
+VdpPresentationQueueGetTime* vdp_presentation_queue_get_time;
+VdpPresentationQueueTargetCreateX11* vdp_presentation_queue_target_create_x11;
+VdpPresentationQueueQuerySurfaceStatus* vdp_presentation_queue_query_surface_status;
+VdpPresentationQueueDisplay* vdp_presentation_queue_display;
+VdpPresentationQueueBlockUntilSurfaceIdle*
+ vdp_presentation_queue_block_until_surface_idle;
+
+
+void safeGetProcAddress(VdpFuncId functionId, void** functionPointer)
+{
+ VdpStatus status;
+ status = vdp_get_proc_address(getVDPAUDevice(), functionId, functionPointer);
+ AVG_ASSERT(status == VDP_STATUS_OK);
+}
+
+VdpDevice getVDPAUDevice()
+{
+ static VdpDevice vdpDevice = 0;
+ static bool bInitFailed = false;
+
+ if (vdpDevice) {
+ return vdpDevice;
+ }
+
+ if (bInitFailed) {
+ return 0;
+ }
+
+ Display* pXDisplay = XOpenDisplay(0);
+ AVG_ASSERT(pXDisplay);
+
+ if (!(ConfigMgr::get()->getBoolOption("scr", "videoaccel", true))) {
+ bInitFailed = true;
+ return 0;
+ }
+ VdpStatus status;
+ status = vdp_device_create_x11(pXDisplay, DefaultScreen(pXDisplay), &vdpDevice,
+ &vdp_get_proc_address);
+ if (status != VDP_STATUS_OK)
+ {
+ bInitFailed = true;
+ return 0;
+ }
+
+ safeGetProcAddress(VDP_FUNC_ID_DEVICE_DESTROY, (void**)&vdp_device_destroy);
+ safeGetProcAddress(VDP_FUNC_ID_OUTPUT_SURFACE_CREATE,
+ (void**)&vdp_output_surface_create);
+ safeGetProcAddress(VDP_FUNC_ID_OUTPUT_SURFACE_DESTROY,
+ (void**)&vdp_output_surface_destroy);
+ safeGetProcAddress(VDP_FUNC_ID_OUTPUT_SURFACE_GET_BITS_NATIVE,
+ (void**)&vdp_output_surface_get_bits_native);
+ safeGetProcAddress(VDP_FUNC_ID_VIDEO_SURFACE_CREATE,
+ (void**)&vdp_video_surface_create);
+ safeGetProcAddress(VDP_FUNC_ID_VIDEO_SURFACE_DESTROY,
+ (void**)&vdp_video_surface_destroy);
+ safeGetProcAddress(VDP_FUNC_ID_DECODER_CREATE, (void**)&vdp_decoder_create);
+ safeGetProcAddress(VDP_FUNC_ID_DECODER_DESTROY, (void**)&vdp_decoder_destroy);
+ safeGetProcAddress(VDP_FUNC_ID_DECODER_RENDER, (void**)&vdp_decoder_render);
+ safeGetProcAddress(VDP_FUNC_ID_VIDEO_SURFACE_GET_BITS_Y_CB_CR,
+ (void**)&vdp_video_surface_get_bits_y_cb_cr);
+ safeGetProcAddress(VDP_FUNC_ID_VIDEO_MIXER_CREATE,
+ (void**)&vdp_video_mixer_create);
+ safeGetProcAddress(VDP_FUNC_ID_VIDEO_MIXER_DESTROY,
+ (void**)&vdp_video_mixer_destroy);
+ safeGetProcAddress(VDP_FUNC_ID_VIDEO_MIXER_RENDER,
+ (void**)&vdp_video_mixer_render);
+ safeGetProcAddress(VDP_FUNC_ID_PRESENTATION_QUEUE_CREATE,
+ (void**)&vdp_presentation_queue_create);
+ safeGetProcAddress(VDP_FUNC_ID_PRESENTATION_QUEUE_DESTROY,
+ (void**)&vdp_presentation_queue_destroy);
+ safeGetProcAddress(VDP_FUNC_ID_PRESENTATION_QUEUE_TARGET_CREATE_X11,
+ (void**)&vdp_presentation_queue_target_create_x11);
+ safeGetProcAddress(VDP_FUNC_ID_PRESENTATION_QUEUE_QUERY_SURFACE_STATUS,
+ (void**)&vdp_presentation_queue_query_surface_status);
+ safeGetProcAddress(VDP_FUNC_ID_PRESENTATION_QUEUE_DISPLAY,
+ (void**)&vdp_presentation_queue_display);
+ safeGetProcAddress(VDP_FUNC_ID_PRESENTATION_QUEUE_GET_TIME,
+ (void**)&vdp_presentation_queue_get_time);
+ safeGetProcAddress(VDP_FUNC_ID_PRESENTATION_QUEUE_BLOCK_UNTIL_SURFACE_IDLE,
+ (void**)&vdp_presentation_queue_block_until_surface_idle);
+ safeGetProcAddress(VDP_FUNC_ID_VIDEO_SURFACE_GET_PARAMETERS,
+ (void**)&vdp_video_surface_get_parameters);
+ safeGetProcAddress(VDP_FUNC_ID_OUTPUT_SURFACE_GET_PARAMETERS,
+ (void**)&vdp_output_surface_get_parameters);
+ return vdpDevice;
+}
+
+void getPlanesFromVDPAU(vdpau_render_state* pRenderState, BitmapPtr pBmpY,
+ BitmapPtr pBmpU, BitmapPtr pBmpV)
+{
+ VdpStatus status;
+ void *dest[3] = {
+ pBmpY->getPixels(),
+ pBmpV->getPixels(),
+ pBmpU->getPixels()
+ };
+ uint32_t pitches[3] = {
+ uint32_t(pBmpY->getStride()),
+ uint32_t(pBmpV->getStride()),
+ uint32_t(pBmpU->getStride())
+ };
+ status = vdp_video_surface_get_bits_y_cb_cr(pRenderState->surface,
+ VDP_YCBCR_FORMAT_YV12, dest, pitches);
+ AVG_ASSERT(status == VDP_STATUS_OK);
+ unlockVDPAUSurface(pRenderState);
+}
+
+void getBitmapFromVDPAU(vdpau_render_state* pRenderState, BitmapPtr pBmpDest)
+{
+ IntPoint YSize = pBmpDest->getSize();
+ IntPoint UVSize(YSize.x/2, YSize.y/2);
+ BitmapPtr pBmpY(new Bitmap(YSize, I8));
+ BitmapPtr pBmpU(new Bitmap(UVSize, I8));
+ BitmapPtr pBmpV(new Bitmap(UVSize, I8));
+ getPlanesFromVDPAU(pRenderState, pBmpY, pBmpU, pBmpV);
+ pBmpDest->copyYUVPixels(*pBmpY, *pBmpU, *pBmpV, false);
+}
+
+void unlockVDPAUSurface(vdpau_render_state* pRenderState)
+{
+ pRenderState->state &= ~FF_VDPAU_STATE_USED_FOR_REFERENCE;
+}
+
+}
diff --git a/src/video/VDPAUHelper.h b/src/video/VDPAUHelper.h
new file mode 100644
index 0000000..5c84788
--- /dev/null
+++ b/src/video/VDPAUHelper.h
@@ -0,0 +1,76 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+#ifndef _VDPAUHelper_H_
+#define _VDPAUHelper_H_
+
+
+#include "../avgconfigwrapper.h"
+#include "../graphics/Bitmap.h"
+
+#include <vdpau/vdpau.h>
+#include <libavcodec/vdpau.h>
+#include <boost/shared_ptr.hpp>
+
+namespace avg {
+
+extern VdpGetProcAddress* vdp_get_proc_address;
+
+extern VdpVideoSurfaceGetParameters* vdp_video_surface_get_parameters;
+extern VdpVideoSurfaceGetBitsYCbCr* vdp_video_surface_get_bits_y_cb_cr;
+extern VdpVideoSurfaceCreate* vdp_video_surface_create;
+extern VdpVideoSurfaceDestroy* vdp_video_surface_destroy;
+
+extern VdpDeviceDestroy* vdp_device_destroy;
+
+extern VdpDecoderCreate* vdp_decoder_create;
+extern VdpDecoderDestroy* vdp_decoder_destroy;
+extern VdpDecoderRender* vdp_decoder_render;
+
+extern VdpOutputSurfaceCreate* vdp_output_surface_create;
+extern VdpOutputSurfaceDestroy* vdp_output_surface_destroy;
+extern VdpOutputSurfaceGetBitsNative* vdp_output_surface_get_bits_native;
+extern VdpOutputSurfaceGetParameters* vdp_output_surface_get_parameters;
+
+extern VdpVideoMixerCreate* vdp_video_mixer_create;
+extern VdpVideoMixerDestroy* vdp_video_mixer_destroy;
+extern VdpVideoMixerRender* vdp_video_mixer_render;
+
+extern VdpPresentationQueueCreate* vdp_presentation_queue_create;
+extern VdpPresentationQueueDestroy* vdp_presentation_queue_destroy;
+extern VdpPresentationQueueGetTime* vdp_presentation_queue_get_time;
+extern VdpPresentationQueueTargetCreateX11* vdp_presentation_queue_target_create_x11;
+extern VdpPresentationQueueQuerySurfaceStatus*
+ vdp_presentation_queue_query_surface_status;
+extern VdpPresentationQueueDisplay* vdp_presentation_queue_display;
+extern VdpPresentationQueueBlockUntilSurfaceIdle*
+ vdp_presentation_queue_block_until_surface_idle;
+
+
+VdpDevice getVDPAUDevice();
+
+void getPlanesFromVDPAU(vdpau_render_state* pRenderState, BitmapPtr pBmpY,
+ BitmapPtr pBmpU, BitmapPtr pBmpV);
+void getBitmapFromVDPAU(vdpau_render_state* pRenderState, BitmapPtr pBmpDest);
+void unlockVDPAUSurface(vdpau_render_state* pRenderState);
+
+}
+#endif
+
diff --git a/src/video/VideoDecoder.cpp b/src/video/VideoDecoder.cpp
new file mode 100644
index 0000000..eddf002
--- /dev/null
+++ b/src/video/VideoDecoder.cpp
@@ -0,0 +1,485 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "VideoDecoder.h"
+#ifdef AVG_ENABLE_VDPAU
+#include "VDPAUDecoder.h"
+#endif
+
+#include "../base/Exception.h"
+#include "../base/Logger.h"
+#include "../base/ObjectCounter.h"
+#include "../base/StringHelper.h"
+
+#include "../graphics/Bitmap.h"
+#include "../graphics/BitmapLoader.h"
+#include "../graphics/GLTexture.h"
+
+#include <string>
+
+#include "WrapFFMpeg.h"
+
+using namespace std;
+using namespace boost;
+
+namespace avg {
+
+bool VideoDecoder::s_bInitialized = false;
+boost::mutex VideoDecoder::s_OpenMutex;
+
+
+VideoDecoder::VideoDecoder()
+ : m_State(CLOSED),
+ m_pFormatContext(0),
+ m_VStreamIndex(-1),
+ m_pVStream(0),
+ m_PF(NO_PIXELFORMAT),
+ m_Size(0,0),
+#ifdef AVG_ENABLE_VDPAU
+ m_pVDPAUDecoder(0),
+#endif
+ m_AStreamIndex(-1),
+ m_pAStream(0)
+{
+ ObjectCounter::get()->incRef(&typeid(*this));
+ initVideoSupport();
+}
+
+VideoDecoder::~VideoDecoder()
+{
+ if (m_pFormatContext) {
+ close();
+ }
+#ifdef AVG_ENABLE_VDPAU
+ if (m_pVDPAUDecoder) {
+ delete m_pVDPAUDecoder;
+ }
+#endif
+ ObjectCounter::get()->decRef(&typeid(*this));
+}
+
+void VideoDecoder::open(const string& sFilename, bool bUseHardwareAcceleration,
+ bool bEnableSound)
+{
+ lock_guard lock(s_OpenMutex);
+ int err;
+ m_sFilename = sFilename;
+
+ AVG_TRACE(Logger::category::MEMORY, Logger::severity::INFO, "Opening " << sFilename);
+ err = avformat_open_input(&m_pFormatContext, sFilename.c_str(), 0, 0);
+ if (err < 0) {
+ m_sFilename = "";
+ m_pFormatContext = 0;
+ avcodecError(sFilename, err);
+ }
+
+ err = avformat_find_stream_info(m_pFormatContext, 0);
+
+ if (err < 0) {
+ m_sFilename = "";
+ m_pFormatContext = 0;
+ throw Exception(AVG_ERR_VIDEO_INIT_FAILED,
+ sFilename + ": Could not find codec parameters.");
+ }
+ if (strcmp(m_pFormatContext->iformat->name, "image2") == 0) {
+ m_sFilename = "";
+ m_pFormatContext = 0;
+ throw Exception(AVG_ERR_VIDEO_INIT_FAILED,
+ sFilename + ": Image files not supported as videos.");
+ }
+ av_read_play(m_pFormatContext);
+
+ // Find audio and video streams in the file
+ m_VStreamIndex = -1;
+ m_AStreamIndex = -1;
+ for (unsigned i = 0; i < m_pFormatContext->nb_streams; i++) {
+ AVCodecContext* pContext = m_pFormatContext->streams[i]->codec;
+ switch (pContext->codec_type) {
+ case AVMEDIA_TYPE_VIDEO:
+ if (m_VStreamIndex < 0) {
+ m_VStreamIndex = i;
+ }
+ break;
+ case AVMEDIA_TYPE_AUDIO:
+ if (m_AStreamIndex < 0 && bEnableSound) {
+ m_AStreamIndex = i;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ // Enable video stream demuxing
+ if (m_VStreamIndex >= 0) {
+ m_pVStream = m_pFormatContext->streams[m_VStreamIndex];
+
+ m_Size = IntPoint(m_pVStream->codec->width, m_pVStream->codec->height);
+
+ char szCodec[256];
+ avcodec_string(szCodec, sizeof(szCodec), m_pVStream->codec, 0);
+ int rc = openCodec(m_VStreamIndex, bUseHardwareAcceleration);
+ if (rc == -1) {
+ m_VStreamIndex = -1;
+ m_pVStream = 0;
+ throw Exception(AVG_ERR_VIDEO_INIT_FAILED,
+ sFilename + ": unsupported video codec ("+szCodec+").");
+ }
+ m_PF = calcPixelFormat(true);
+ }
+ // Enable audio stream demuxing.
+ if (m_AStreamIndex >= 0) {
+ m_pAStream = m_pFormatContext->streams[m_AStreamIndex];
+ char szCodec[256];
+ avcodec_string(szCodec, sizeof(szCodec), m_pAStream->codec, 0);
+ int rc = openCodec(m_AStreamIndex, false);
+ if (rc == -1) {
+ m_AStreamIndex = -1;
+ m_pAStream = 0;
+ throw Exception(AVG_ERR_VIDEO_INIT_FAILED,
+ sFilename + ": unsupported audio codec ("+szCodec+").");
+ }
+ }
+ if (!m_pVStream && !m_pAStream) {
+ throw Exception(AVG_ERR_VIDEO_INIT_FAILED,
+ sFilename + ": no usable streams found.");
+ }
+
+ m_State = OPENED;
+}
+
+void VideoDecoder::startDecoding(bool bDeliverYCbCr, const AudioParams* pAP)
+{
+ AVG_ASSERT(m_State == OPENED);
+ if (m_VStreamIndex >= 0) {
+ m_PF = calcPixelFormat(bDeliverYCbCr);
+ }
+ bool bAudioEnabled = (pAP!=0);
+ if (!bAudioEnabled) {
+ m_AStreamIndex = -1;
+ if (m_pAStream) {
+ avcodec_close(m_pAStream->codec);
+ }
+ m_pAStream = 0;
+ }
+
+ if (m_AStreamIndex >= 0) {
+ if (m_pAStream->codec->channels > pAP->m_Channels) {
+ throw Exception(AVG_ERR_VIDEO_INIT_FAILED,
+ m_sFilename + ": unsupported number of audio channels (" +
+ toString(m_pAStream->codec->channels) + ").");
+ m_AStreamIndex = -1;
+ m_pAStream = 0;
+ }
+ }
+
+ if (!m_pVStream && !m_pAStream) {
+ throw Exception(AVG_ERR_VIDEO_INIT_FAILED,
+ m_sFilename + ": no usable streams found.");
+ }
+
+ m_State = DECODING;
+}
+
+void VideoDecoder::close()
+{
+ lock_guard lock(s_OpenMutex);
+ AVG_TRACE(Logger::category::MEMORY, Logger::severity::INFO, "Closing " << m_sFilename);
+
+ // Close audio and video codecs
+ if (m_pVStream) {
+ avcodec_close(m_pVStream->codec);
+ m_pVStream = 0;
+ m_VStreamIndex = -1;
+ }
+
+ if (m_pAStream) {
+ avcodec_close(m_pAStream->codec);
+ m_pAStream = 0;
+ m_AStreamIndex = -1;
+ }
+ if (m_pFormatContext) {
+#if LIBAVCODEC_VERSION_INT > AV_VERSION_INT(53, 21, 0)
+ avformat_close_input(&m_pFormatContext);
+#else
+ av_close_input_file(m_pFormatContext);
+ m_pFormatContext = 0;
+#endif
+ }
+
+ m_State = CLOSED;
+}
+
+VideoDecoder::DecoderState VideoDecoder::getState() const
+{
+ return m_State;
+}
+
+VideoInfo VideoDecoder::getVideoInfo() const
+{
+ AVG_ASSERT(m_State != CLOSED);
+ AVG_ASSERT(m_pVStream || m_pAStream);
+ float duration = getDuration(SS_DEFAULT);
+
+ VideoInfo info(m_pFormatContext->iformat->name, duration, m_pFormatContext->bit_rate,
+ m_pVStream != 0, m_pAStream != 0);
+ if (m_pVStream) {
+ info.setVideoData(m_Size, getStreamPF(), getNumFrames(), getStreamFPS(),
+ m_pVStream->codec->codec->name, usesVDPAU(), getDuration(SS_VIDEO));
+ }
+ if (m_pAStream) {
+ AVCodecContext * pACodec = m_pAStream->codec;
+ info.setAudioData(pACodec->codec->name, pACodec->sample_rate,
+ pACodec->channels, getDuration(SS_AUDIO));
+ }
+ return info;
+}
+
+PixelFormat VideoDecoder::getPixelFormat() const
+{
+ AVG_ASSERT(m_State != CLOSED);
+ return m_PF;
+}
+
+IntPoint VideoDecoder::getSize() const
+{
+ AVG_ASSERT(m_State != CLOSED);
+ return m_Size;
+}
+
+float VideoDecoder::getStreamFPS() const
+{
+ AVG_ASSERT(m_State != CLOSED);
+ return avg::getStreamFPS(m_pVStream);
+}
+
+FrameAvailableCode VideoDecoder::renderToBmp(BitmapPtr pBmp, float timeWanted)
+{
+ std::vector<BitmapPtr> pBmps;
+ pBmps.push_back(pBmp);
+ return renderToBmps(pBmps, timeWanted);
+}
+
+FrameAvailableCode VideoDecoder::renderToTexture(GLTexturePtr pTextures[4],
+ float timeWanted)
+{
+ std::vector<BitmapPtr> pBmps;
+ for (unsigned i=0; i<getNumPixelFormatPlanes(m_PF); ++i) {
+ pBmps.push_back(pTextures[i]->lockStreamingBmp());
+ }
+ FrameAvailableCode frameAvailable;
+ if (pixelFormatIsPlanar(m_PF)) {
+ frameAvailable = renderToBmps(pBmps, timeWanted);
+ } else {
+ frameAvailable = renderToBmp(pBmps[0], timeWanted);
+ }
+ for (unsigned i=0; i<getNumPixelFormatPlanes(m_PF); ++i) {
+ pTextures[i]->unlockStreamingBmp(frameAvailable == FA_NEW_FRAME);
+ }
+ return frameAvailable;
+}
+
+void VideoDecoder::logConfig()
+{
+ bool bVDPAUAvailable = false;
+#ifdef AVG_ENABLE_VDPAU
+ bVDPAUAvailable = VDPAUDecoder::isAvailable();
+#endif
+ if (bVDPAUAvailable) {
+ AVG_TRACE(Logger::category::CONFIG, Logger::severity::INFO,
+ "Hardware video acceleration: VDPAU");
+ } else {
+ AVG_TRACE(Logger::category::CONFIG, Logger::severity::INFO,
+ "Hardware video acceleration: Off");
+ }
+}
+
+int VideoDecoder::getNumFrames() const
+{
+ AVG_ASSERT(m_State != CLOSED);
+ int numFrames = int(m_pVStream->nb_frames);
+ if (numFrames > 0) {
+ return numFrames;
+ } else {
+ return int(getDuration(SS_VIDEO) * getStreamFPS());
+ }
+}
+
+AVFormatContext* VideoDecoder::getFormatContext()
+{
+ AVG_ASSERT(m_pFormatContext);
+ return m_pFormatContext;
+}
+
+bool VideoDecoder::usesVDPAU() const
+{
+#ifdef AVG_ENABLE_VDPAU
+ AVCodecContext const* pContext = getCodecContext();
+ return pContext->codec && (pContext->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU);
+#else
+ return false;
+#endif
+}
+
+AVCodecContext const* VideoDecoder::getCodecContext() const
+{
+ return m_pVStream->codec;
+}
+
+AVCodecContext* VideoDecoder::getCodecContext()
+{
+ return m_pVStream->codec;
+}
+
+int VideoDecoder::getVStreamIndex() const
+{
+ return m_VStreamIndex;
+}
+
+AVStream* VideoDecoder::getVideoStream() const
+{
+ return m_pVStream;
+}
+
+int VideoDecoder::getAStreamIndex() const
+{
+ return m_AStreamIndex;
+}
+
+AVStream* VideoDecoder::getAudioStream() const
+{
+ return m_pAStream;
+}
+
+void VideoDecoder::initVideoSupport()
+{
+ if (!s_bInitialized) {
+ av_register_all();
+ s_bInitialized = true;
+ // Tune libavcodec console spam.
+// av_log_set_level(AV_LOG_DEBUG);
+ av_log_set_level(AV_LOG_QUIET);
+ }
+}
+
+int VideoDecoder::openCodec(int streamIndex, bool bUseHardwareAcceleration)
+{
+ AVCodecContext* pContext;
+ pContext = m_pFormatContext->streams[streamIndex]->codec;
+// pContext->debug = 0x0001; // see avcodec.h
+
+ AVCodec * pCodec = 0;
+#ifdef AVG_ENABLE_VDPAU
+ if (bUseHardwareAcceleration) {
+ m_pVDPAUDecoder = new VDPAUDecoder();
+ pContext->opaque = m_pVDPAUDecoder;
+ pCodec = m_pVDPAUDecoder->openCodec(pContext);
+ }
+#endif
+ if (!pCodec) {
+ pCodec = avcodec_find_decoder(pContext->codec_id);
+ }
+ if (!pCodec) {
+ return -1;
+ }
+ int rc = avcodec_open2(pContext, pCodec, 0);
+
+ if (rc < 0) {
+ return -1;
+ }
+ return 0;
+}
+
+float VideoDecoder::getDuration(StreamSelect streamSelect) const
+{
+ AVG_ASSERT(m_State != CLOSED);
+ long long duration;
+ AVRational time_base;
+ if (streamSelect == SS_DEFAULT) {
+ if (m_pVStream) {
+ streamSelect = SS_VIDEO;
+ } else {
+ streamSelect = SS_AUDIO;
+ }
+ }
+ if (streamSelect == SS_VIDEO) {
+ duration = m_pVStream->duration;
+ time_base = m_pVStream->time_base;
+ } else {
+ duration = m_pAStream->duration;
+ time_base = m_pAStream->time_base;
+ }
+ if (duration == (long long)AV_NOPTS_VALUE) {
+ return 0;
+ } else {
+ return float(duration)*float(av_q2d(time_base));
+ }
+}
+
+PixelFormat VideoDecoder::calcPixelFormat(bool bUseYCbCr)
+{
+ AVCodecContext const* pContext = getCodecContext();
+ if (bUseYCbCr) {
+ switch(pContext->pix_fmt) {
+ case PIX_FMT_YUV420P:
+#ifdef AVG_ENABLE_VDPAU
+ case PIX_FMT_VDPAU_H264:
+ case PIX_FMT_VDPAU_MPEG1:
+ case PIX_FMT_VDPAU_MPEG2:
+ case PIX_FMT_VDPAU_WMV3:
+ case PIX_FMT_VDPAU_VC1:
+#endif
+ return YCbCr420p;
+ case PIX_FMT_YUVJ420P:
+ return YCbCrJ420p;
+ case PIX_FMT_YUVA420P:
+ return YCbCrA420p;
+ default:
+ break;
+ }
+ }
+ bool bAlpha = (pContext->pix_fmt == PIX_FMT_BGRA ||
+ pContext->pix_fmt == PIX_FMT_YUVA420P);
+ return BitmapLoader::get()->getDefaultPixelFormat(bAlpha);
+}
+
+string VideoDecoder::getStreamPF() const
+{
+ AVCodecContext const* pCodec = getCodecContext();
+ AVPixelFormat pf = pCodec->pix_fmt;
+ const char* psz = av_get_pix_fmt_name(pf);
+ string s;
+ if (psz) {
+ s = psz;
+ }
+ return s;
+}
+
+void avcodecError(const string& sFilename, int err)
+{
+ char buf[256];
+ av_strerror(err, buf, 256);
+ throw Exception(AVG_ERR_VIDEO_INIT_FAILED, sFilename + ": " + buf);
+}
+
+}
+
+
diff --git a/src/video/VideoDecoder.h b/src/video/VideoDecoder.h
new file mode 100644
index 0000000..6d99da8
--- /dev/null
+++ b/src/video/VideoDecoder.h
@@ -0,0 +1,138 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _VideoDecoder_H_
+#define _VideoDecoder_H_
+
+#include "../api.h"
+#include "../avgconfigwrapper.h"
+
+#include "VideoInfo.h"
+
+#include "../audio/AudioParams.h"
+#include "../graphics/PixelFormat.h"
+
+#include "WrapFFMpeg.h"
+
+#include <string>
+#include <boost/shared_ptr.hpp>
+#include <boost/thread/mutex.hpp>
+
+struct vdpau_render_state;
+
+namespace avg {
+
+class Bitmap;
+typedef boost::shared_ptr<Bitmap> BitmapPtr;
+class GLTexture;
+typedef boost::shared_ptr<GLTexture> GLTexturePtr;
+class VDPAUDecoder;
+
+enum FrameAvailableCode {
+ FA_NEW_FRAME, FA_USE_LAST_FRAME, FA_STILL_DECODING
+};
+
+enum StreamSelect {
+ SS_AUDIO, SS_VIDEO, SS_DEFAULT
+};
+
+class AVG_API VideoDecoder
+{
+ public:
+ enum DecoderState {CLOSED, OPENED, DECODING};
+ VideoDecoder();
+ virtual ~VideoDecoder();
+ virtual void open(const std::string& sFilename, bool bUseHardwareAcceleration,
+ bool bEnableSound);
+ virtual void startDecoding(bool bDeliverYCbCr, const AudioParams* pAP);
+ virtual void close();
+ virtual DecoderState getState() const;
+ VideoInfo getVideoInfo() const;
+ PixelFormat getPixelFormat() const;
+ IntPoint getSize() const;
+ float getStreamFPS() const;
+
+ virtual void seek(float destTime) = 0;
+ virtual void loop() = 0;
+ virtual int getCurFrame() const = 0;
+ virtual int getNumFramesQueued() const = 0;
+ virtual float getCurTime() const = 0;
+ virtual float getFPS() const = 0;
+ virtual void setFPS(float fps) = 0;
+
+ virtual FrameAvailableCode renderToBmp(BitmapPtr pBmp, float timeWanted);
+ virtual FrameAvailableCode renderToBmps(std::vector<BitmapPtr>& pBmps,
+ float timeWanted) = 0;
+ virtual FrameAvailableCode renderToTexture(GLTexturePtr pTextures[4],
+ float timeWanted);
+ virtual bool isEOF() const = 0;
+ virtual void throwAwayFrame(float timeWanted) = 0;
+
+ static void logConfig();
+
+ protected:
+ int getNumFrames() const;
+ AVFormatContext* getFormatContext();
+ bool usesVDPAU() const;
+ AVCodecContext const * getCodecContext() const;
+ AVCodecContext * getCodecContext();
+
+ int getVStreamIndex() const;
+ AVStream* getVideoStream() const;
+ int getAStreamIndex() const;
+ AVStream* getAudioStream() const;
+
+ private:
+ void initVideoSupport();
+ int openCodec(int streamIndex, bool bUseHardwareAcceleration);
+ float getDuration(StreamSelect streamSelect) const;
+ PixelFormat calcPixelFormat(bool bUseYCbCr);
+ std::string getStreamPF() const;
+
+ DecoderState m_State;
+ AVFormatContext * m_pFormatContext;
+ std::string m_sFilename;
+
+ // Video
+ int m_VStreamIndex;
+ AVStream * m_pVStream;
+ PixelFormat m_PF;
+ IntPoint m_Size;
+#ifdef AVG_ENABLE_VDPAU
+ VDPAUDecoder* m_pVDPAUDecoder;
+#endif
+
+ // Audio
+ int m_AStreamIndex;
+ AVStream * m_pAStream;
+
+ static bool s_bInitialized;
+ // Prevents different decoder instances from executing open/close simultaneously
+ static boost::mutex s_OpenMutex;
+};
+
+typedef boost::shared_ptr<VideoDecoder> VideoDecoderPtr;
+
+void avcodecError(const std::string& sFilename, int err);
+
+}
+#endif
+
diff --git a/src/video/VideoDecoderThread.cpp b/src/video/VideoDecoderThread.cpp
new file mode 100644
index 0000000..d1c701c
--- /dev/null
+++ b/src/video/VideoDecoderThread.cpp
@@ -0,0 +1,222 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "VideoDecoderThread.h"
+#include "FFMpegFrameDecoder.h"
+
+#include "../base/Logger.h"
+#include "../base/Exception.h"
+#include "../base/ScopeTimer.h"
+#include "../base/TimeSource.h"
+#include "../avgconfigwrapper.h"
+
+struct vdpau_render_state;
+
+using namespace std;
+
+namespace avg {
+
+VideoDecoderThread::VideoDecoderThread(CQueue& cmdQ, VideoMsgQueue& msgQ,
+ VideoMsgQueue& packetQ, AVStream* pStream, const IntPoint& size, PixelFormat pf,
+ bool bUseVDPAU)
+ : WorkerThread<VideoDecoderThread>(string("Video Decoder"), cmdQ,
+ Logger::category::PROFILE_VIDEO),
+ m_MsgQ(msgQ),
+ m_PacketQ(packetQ),
+ m_pBmpQ(new BitmapQueue()),
+ m_pHalfBmpQ(new BitmapQueue()),
+ m_Size(size),
+ m_PF(pf),
+ m_bUseVDPAU(bUseVDPAU),
+ m_bSeekDone(false),
+ m_bProcessingLastFrames(false)
+{
+ m_pFrameDecoder = FFMpegFrameDecoderPtr(new FFMpegFrameDecoder(pStream));
+}
+
+VideoDecoderThread::~VideoDecoderThread()
+{
+}
+
+bool VideoDecoderThread::init()
+{
+#if LIBAVCODEC_VERSION_INT > AV_VERSION_INT(54, 28, 0)
+ m_pFrame = avcodec_alloc_frame();
+#else
+ m_pFrame = new AVFrame;
+#endif
+ return true;
+}
+
+void VideoDecoderThread::deinit()
+{
+#if LIBAVCODEC_VERSION_INT > AV_VERSION_INT(54, 28, 0)
+ avcodec_free_frame(&m_pFrame);
+#else
+ delete m_pFrame;
+#endif
+}
+
+static ProfilingZoneID DecoderProfilingZone("Video Decoder Thread", true);
+static ProfilingZoneID PacketWaitProfilingZone("Video wait for packet", true);
+
+bool VideoDecoderThread::work()
+{
+ ScopeTimer timer(DecoderProfilingZone);
+ if (m_bProcessingLastFrames) {
+ // EOF received, but last frames still need to be decoded.
+ handleEOF();
+ } else {
+ // Standard decoding.
+ VideoMsgPtr pMsg;
+ {
+ ScopeTimer timer(PacketWaitProfilingZone);
+ pMsg = m_PacketQ.pop(true);
+ }
+ switch (pMsg->getType()) {
+ case VideoMsg::PACKET:
+ decodePacket(pMsg->getPacket());
+ break;
+ case VideoMsg::END_OF_FILE:
+ handleEOF();
+ m_bProcessingLastFrames = true;
+ break;
+ case VideoMsg::SEEK_DONE:
+ handleSeekDone(pMsg);
+ break;
+ case VideoMsg::CLOSED:
+ close();
+ break;
+ default:
+ pMsg->dump();
+ AVG_ASSERT(false);
+ }
+ }
+ ThreadProfiler::get()->reset();
+ return true;
+}
+
+void VideoDecoderThread::setFPS(float fps)
+{
+ m_pFrameDecoder->setFPS(fps);
+}
+
+void VideoDecoderThread::returnFrame(VideoMsgPtr pMsg)
+{
+ m_pBmpQ->push(pMsg->getFrameBitmap(0));
+ if (pixelFormatIsPlanar(m_PF)) {
+ m_pHalfBmpQ->push(pMsg->getFrameBitmap(1));
+ m_pHalfBmpQ->push(pMsg->getFrameBitmap(2));
+ if (m_PF == YCbCrA420p) {
+ m_pBmpQ->push(pMsg->getFrameBitmap(3));
+ }
+ }
+}
+
+void VideoDecoderThread::decodePacket(AVPacket* pPacket)
+{
+ bool bGotPicture = m_pFrameDecoder->decodePacket(pPacket, m_pFrame, m_bSeekDone);
+ if (bGotPicture) {
+ m_bSeekDone = false;
+ sendFrame(m_pFrame);
+ }
+}
+
+void VideoDecoderThread::handleEOF()
+{
+ bool bGotPicture = m_pFrameDecoder->decodeLastFrame(m_pFrame);
+ if (bGotPicture) {
+ sendFrame(m_pFrame);
+ } else {
+ m_bProcessingLastFrames = false;
+ VideoMsgPtr pMsg(new VideoMsg());
+ pMsg->setEOF();
+ pushMsg(pMsg);
+ }
+}
+
+void VideoDecoderThread::handleSeekDone(VideoMsgPtr pMsg)
+{
+ m_pFrameDecoder->handleSeek();
+ m_bSeekDone = true;
+ m_MsgQ.clear();
+ pushMsg(pMsg);
+}
+
+static ProfilingZoneID CopyImageProfilingZone("Copy image", true);
+
+void VideoDecoderThread::sendFrame(AVFrame* pFrame)
+{
+ VideoMsgPtr pMsg(new VideoMsg());
+ if (m_bUseVDPAU) {
+ vdpau_render_state *pRenderState = (vdpau_render_state *)pFrame->data[0];
+ pMsg->setVDPAUFrame(pRenderState, m_pFrameDecoder->getCurTime());
+ } else {
+ vector<BitmapPtr> pBmps;
+ if (pixelFormatIsPlanar(m_PF)) {
+ ScopeTimer timer(CopyImageProfilingZone);
+ IntPoint halfSize(m_Size.x/2, m_Size.y/2);
+ pBmps.push_back(getBmp(m_pBmpQ, m_Size, I8));
+ pBmps.push_back(getBmp(m_pHalfBmpQ, halfSize, I8));
+ pBmps.push_back(getBmp(m_pHalfBmpQ, halfSize, I8));
+ if (m_PF == YCbCrA420p) {
+ pBmps.push_back(getBmp(m_pBmpQ, m_Size, I8));
+ }
+ for (unsigned i = 0; i < pBmps.size(); ++i) {
+ m_pFrameDecoder->copyPlaneToBmp(pBmps[i], pFrame->data[i],
+ pFrame->linesize[i]);
+ }
+ } else {
+ pBmps.push_back(getBmp(m_pBmpQ, m_Size, m_PF));
+ m_pFrameDecoder->convertFrameToBmp(pFrame, pBmps[0]);
+ }
+ pMsg->setFrame(pBmps, m_pFrameDecoder->getCurTime());
+ }
+ pushMsg(pMsg);
+}
+
+void VideoDecoderThread::close()
+{
+ m_MsgQ.clear();
+ stop();
+}
+
+BitmapPtr VideoDecoderThread::getBmp(BitmapQueuePtr pBmpQ, const IntPoint& size,
+ PixelFormat pf)
+{
+ BitmapPtr pBmp = pBmpQ->pop(false);
+ if (pBmp) {
+ AVG_ASSERT (pBmp->getSize() == size && pBmp->getPixelFormat() == pf);
+ return pBmp;
+ } else {
+ return BitmapPtr(new Bitmap(size, pf));
+ }
+}
+
+static ProfilingZoneID PushMsgProfilingZone("Push message", true);
+
+void VideoDecoderThread::pushMsg(VideoMsgPtr pMsg)
+{
+ ScopeTimer timer(PushMsgProfilingZone);
+ m_MsgQ.push(pMsg);
+}
+
+}
diff --git a/src/video/VideoDecoderThread.h b/src/video/VideoDecoderThread.h
new file mode 100644
index 0000000..c03e7cb
--- /dev/null
+++ b/src/video/VideoDecoderThread.h
@@ -0,0 +1,83 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _VideoDecoderThread_H_
+#define _VideoDecoderThread_H_
+
+#include "../api.h"
+#include "VideoMsg.h"
+
+#include "../base/WorkerThread.h"
+#include "../base/Command.h"
+#include "../base/Queue.h"
+
+#include "WrapFFMpeg.h"
+
+#include <boost/thread.hpp>
+
+namespace avg {
+
+typedef Queue<Bitmap> BitmapQueue;
+typedef boost::shared_ptr<BitmapQueue> BitmapQueuePtr;
+
+class FFMpegFrameDecoder;
+typedef boost::shared_ptr<FFMpegFrameDecoder> FFMpegFrameDecoderPtr;
+
+class AVG_API VideoDecoderThread: public WorkerThread<VideoDecoderThread> {
+ public:
+ VideoDecoderThread(CQueue& cmdQ, VideoMsgQueue& msgQ, VideoMsgQueue& packetQ,
+ AVStream* pStream, const IntPoint& size, PixelFormat pf, bool bUseVDPAU);
+ virtual ~VideoDecoderThread();
+ virtual bool init();
+ virtual void deinit();
+
+ bool work();
+ void setFPS(float fps);
+ void returnFrame(VideoMsgPtr pMsg);
+
+ private:
+ void decodePacket(AVPacket* pPacket);
+ void handleEOF();
+ void handleSeekDone(VideoMsgPtr pMsg);
+ void sendFrame(AVFrame* pFrame);
+ void close();
+ BitmapPtr getBmp(BitmapQueuePtr pBmpQ, const IntPoint& size, PixelFormat pf);
+ void pushMsg(VideoMsgPtr pMsg);
+
+ VideoMsgQueue& m_MsgQ;
+ FFMpegFrameDecoderPtr m_pFrameDecoder;
+ VideoMsgQueue& m_PacketQ;
+
+ BitmapQueuePtr m_pBmpQ;
+ BitmapQueuePtr m_pHalfBmpQ;
+
+ IntPoint m_Size;
+ PixelFormat m_PF;
+ bool m_bUseVDPAU;
+
+ bool m_bSeekDone;
+ bool m_bProcessingLastFrames;
+ AVFrame* m_pFrame;
+};
+
+}
+#endif
+
diff --git a/src/video/VideoDemuxerThread.cpp b/src/video/VideoDemuxerThread.cpp
new file mode 100644
index 0000000..370e237
--- /dev/null
+++ b/src/video/VideoDemuxerThread.cpp
@@ -0,0 +1,157 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "VideoDemuxerThread.h"
+
+#include "../base/TimeSource.h"
+
+using namespace std;
+
+namespace avg {
+
+VideoDemuxerThread::VideoDemuxerThread(CQueue& cmdQ, AVFormatContext* pFormatContext,
+ const map<int, VideoMsgQueuePtr>& packetQs)
+ : WorkerThread<VideoDemuxerThread>("VideoDemuxer", cmdQ),
+ m_PacketQs(packetQs),
+ m_bEOF(false),
+ m_pFormatContext(pFormatContext),
+ m_pDemuxer()
+{
+ map<int, VideoMsgQueuePtr>::iterator it;
+ for (it = m_PacketQs.begin(); it != m_PacketQs.end(); it++) {
+ int streamIndex = it->first;
+ m_PacketQEOFMap[streamIndex] = false;
+ }
+}
+
+VideoDemuxerThread::~VideoDemuxerThread()
+{
+}
+
+bool VideoDemuxerThread::init()
+{
+ map<int, VideoMsgQueuePtr>::iterator it;
+ vector<int> streamIndexes;
+ for (it = m_PacketQs.begin(); it != m_PacketQs.end(); it++) {
+ streamIndexes.push_back(it->first);
+ }
+ m_pDemuxer = FFMpegDemuxerPtr(new FFMpegDemuxer(m_pFormatContext, streamIndexes));
+ return true;
+}
+
+bool VideoDemuxerThread::work()
+{
+ if (m_bEOF) {
+ waitForCommand();
+ } else {
+ map<int, VideoMsgQueuePtr>::iterator it;
+ int shortestQ = -1;
+ int shortestLength = INT_MAX;
+ for (it = m_PacketQs.begin(); it != m_PacketQs.end(); it++) {
+ if (it->second->size() < shortestLength &&
+ it->second->size() < it->second->getMaxSize() &&
+ !m_PacketQEOFMap[it->first])
+ {
+ shortestLength = it->second->size();
+ shortestQ = it->first;
+ }
+ }
+
+ if (shortestQ < 0) {
+ // All queues are at their max capacity. Take a nap and try again later.
+ // Note that we can't wait on the queue. If decoding is paused, the queues can
+ // remain full indefinitely and commands from the application (seek() and
+ // close() must still be processed.
+ msleep(10);
+ return true;
+ }
+
+ AVPacket * pPacket = m_pDemuxer->getPacket(shortestQ);
+ VideoMsgPtr pMsg(new VideoMsg);
+ if (pPacket == 0) {
+ onStreamEOF(shortestQ);
+ pMsg->setEOF();
+ } else {
+ pMsg->setPacket(pPacket);
+ }
+ m_PacketQs[shortestQ]->push(pMsg);
+ msleep(0);
+ }
+ return true;
+}
+
+void VideoDemuxerThread::seek(int seqNum, float destTime)
+{
+ map<int, VideoMsgQueuePtr>::iterator it;
+ m_pDemuxer->seek(destTime);
+ for (it = m_PacketQs.begin(); it != m_PacketQs.end(); it++) {
+ VideoMsgQueuePtr pPacketQ = it->second;
+ clearQueue(pPacketQ);
+
+ // send SEEK_DONE
+ VideoMsgPtr pMsg(new VideoMsg);
+ pMsg->setSeekDone(seqNum, destTime);
+ pPacketQ->push(pMsg);
+ m_PacketQEOFMap[it->first] = false;
+ }
+ m_bEOF = false;
+}
+
+void VideoDemuxerThread::close()
+{
+ map<int, VideoMsgQueuePtr>::iterator it;
+ for (it = m_PacketQs.begin(); it != m_PacketQs.end(); it++) {
+ VideoMsgQueuePtr pPacketQ = it->second;
+ clearQueue(pPacketQ);
+
+ VideoMsgPtr pMsg(new VideoMsg);
+ pMsg->setClosed();
+ pPacketQ->push(pMsg);
+ m_PacketQEOFMap[it->first] = false;
+ }
+ stop();
+}
+
+void VideoDemuxerThread::onStreamEOF(int streamIndex)
+{
+ m_PacketQEOFMap[streamIndex] = true;
+ m_bEOF = true;
+ map<int, bool>::iterator it;
+ for (it = m_PacketQEOFMap.begin(); it != m_PacketQEOFMap.end(); it++) {
+ if (!it->second) {
+ m_bEOF = false;
+ break;
+ }
+ }
+}
+
+void VideoDemuxerThread::clearQueue(VideoMsgQueuePtr pPacketQ)
+{
+ VideoMsgPtr pMsg;
+ do {
+ pMsg = pPacketQ->pop(false);
+ if (pMsg) {
+ pMsg->freePacket();
+ }
+ } while (pMsg);
+}
+
+}
diff --git a/src/video/VideoDemuxerThread.h b/src/video/VideoDemuxerThread.h
new file mode 100644
index 0000000..b89e58c
--- /dev/null
+++ b/src/video/VideoDemuxerThread.h
@@ -0,0 +1,63 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _VideoDemuxerThread_H_
+#define _VideoDemuxerThread_H_
+
+#include "../api.h"
+#include "FFMpegDemuxer.h"
+#include "VideoMsg.h"
+
+#include "../base/WorkerThread.h"
+#include "../base/Command.h"
+
+#include <boost/thread.hpp>
+
+#include <string>
+#include <vector>
+
+namespace avg {
+
+class AVG_API VideoDemuxerThread: public WorkerThread<VideoDemuxerThread> {
+ public:
+ VideoDemuxerThread(CQueue& cmdQ, AVFormatContext* pFormatContext,
+ const std::map<int, VideoMsgQueuePtr>& packetQs);
+ virtual ~VideoDemuxerThread();
+ bool init();
+ bool work();
+
+ void seek(int seqNum, float DestTime);
+ void close();
+
+ private:
+ void onStreamEOF(int streamIndex);
+ void clearQueue(VideoMsgQueuePtr pPacketQ);
+
+ std::map<int, VideoMsgQueuePtr> m_PacketQs;
+ std::map<int, bool> m_PacketQEOFMap;
+ bool m_bEOF;
+ AVFormatContext* m_pFormatContext;
+ FFMpegDemuxerPtr m_pDemuxer;
+};
+
+}
+#endif
+
diff --git a/src/video/VideoInfo.cpp b/src/video/VideoInfo.cpp
new file mode 100644
index 0000000..50cfec4
--- /dev/null
+++ b/src/video/VideoInfo.cpp
@@ -0,0 +1,94 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "VideoInfo.h"
+
+#include "../base/Exception.h"
+
+namespace avg {
+
+using namespace std;
+
+VideoInfo::VideoInfo()
+{
+}
+
+VideoInfo::VideoInfo(string sContainerFormat, float duration, int bitrate, bool bHasVideo,
+ bool bHasAudio)
+ : m_sContainerFormat(sContainerFormat),
+ m_Duration(duration),
+ m_Bitrate(bitrate),
+ m_bHasVideo(bHasVideo),
+ m_bHasAudio(bHasAudio)
+{
+}
+
+void VideoInfo::setVideoData(const IntPoint& size, const string& sPixelFormat,
+ int numFrames, float streamFPS, const string& sVCodec,
+ bool bUsesVDPAU, float duration)
+{
+ AVG_ASSERT(m_bHasVideo);
+ m_Size = size;
+ m_sPixelFormat = sPixelFormat;
+ m_NumFrames = numFrames;
+ m_StreamFPS = streamFPS;
+ m_sVCodec = sVCodec;
+ m_bUsesVDPAU = bUsesVDPAU;
+ m_VideoDuration = duration;
+}
+
+void VideoInfo::setAudioData(const string& sACodec, int sampleRate, int numAudioChannels,
+ float duration)
+{
+ AVG_ASSERT(m_bHasAudio);
+ m_sACodec = sACodec;
+ m_SampleRate = sampleRate;
+ m_NumAudioChannels = numAudioChannels;
+ m_AudioDuration = duration;
+}
+
+float getStreamFPS(AVStream* pStream)
+{
+ float fps = 0;
+ if (pStream->avg_frame_rate.den != 0) {
+ fps = float(av_q2d(pStream->avg_frame_rate));
+ }
+#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(54, 25, 0)
+ if (fps == 0 && pStream->r_frame_rate.den != 0) {
+ fps = float(av_q2d(pStream->r_frame_rate));
+ }
+#endif
+ if (fps == 0) {
+ float duration = float(pStream->duration)*float(av_q2d(pStream->time_base));
+ fps = pStream->nb_frames/duration;
+ }
+ AVG_ASSERT(fps < 10000);
+/*
+ cerr << "getStreamFPS: fps= " << fps << endl;
+ cerr << " r_frame_rate num: " << m_pVStream->r_frame_rate.num << ", den: " << m_pVStream->r_frame_rate.den << endl;
+ cerr << " avg_frame_rate: num: " << m_pVStream->avg_frame_rate.num << ", den: " << m_pVStream->avg_frame_rate.den << endl;
+ cerr << " numFrames= " << getNumFrames() << ", duration= "
+ << getDuration(SS_VIDEO) << endl;
+*/
+ return fps;
+}
+
+}
diff --git a/src/video/VideoInfo.h b/src/video/VideoInfo.h
new file mode 100644
index 0000000..f2c1311
--- /dev/null
+++ b/src/video/VideoInfo.h
@@ -0,0 +1,71 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _VideoInfo_H_
+#define _VideoInfo_H_
+
+#include "../api.h"
+
+#include "WrapFFMpeg.h"
+
+#include "../base/GLMHelper.h"
+
+#include <string>
+
+namespace avg {
+
+struct AVG_API VideoInfo
+{
+ VideoInfo();
+ VideoInfo(std::string sContainerFormat, float duration, int bitrate, bool bHasVideo,
+ bool bHasAudio);
+ void setVideoData(const IntPoint& size, const std::string& sPixelFormat,
+ int numFrames, float streamFPS, const std::string& sVCodec,
+ bool bUsesVDPAU, float duration);
+
+ void setAudioData(const std::string& sACodec, int sampleRate, int numAudioChannels,
+ float duration);
+
+ std::string m_sContainerFormat;
+ float m_Duration;
+ int m_Bitrate;
+
+ bool m_bHasVideo;
+ IntPoint m_Size;
+ std::string m_sPixelFormat;
+ int m_NumFrames;
+ float m_StreamFPS;
+ std::string m_sVCodec;
+ bool m_bUsesVDPAU;
+ float m_VideoDuration;
+
+ bool m_bHasAudio;
+ std::string m_sACodec;
+ int m_SampleRate;
+ int m_NumAudioChannels;
+ float m_AudioDuration;
+};
+
+float getStreamFPS(AVStream* pStream);
+
+}
+#endif
+
diff --git a/src/video/VideoMsg.cpp b/src/video/VideoMsg.cpp
new file mode 100644
index 0000000..6e3be26
--- /dev/null
+++ b/src/video/VideoMsg.cpp
@@ -0,0 +1,94 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "VideoMsg.h"
+#include "WrapFFMpeg.h"
+
+#include "../base/ObjectCounter.h"
+#include "../base/Exception.h"
+
+namespace avg {
+
+VideoMsg::VideoMsg()
+{
+}
+
+VideoMsg::~VideoMsg()
+{
+}
+
+void VideoMsg::setFrame(const std::vector<BitmapPtr>& pBmps, float frameTime)
+{
+ AVG_ASSERT(pBmps.size() == 1 || pBmps.size() == 3 || pBmps.size() == 4);
+ setType(FRAME);
+ m_pBmps = pBmps;
+ m_FrameTime = frameTime;
+}
+
+void VideoMsg::setVDPAUFrame(vdpau_render_state* pRenderState, float frameTime)
+{
+ setType(VDPAU_FRAME);
+ m_pRenderState = pRenderState;
+ m_FrameTime = frameTime;
+}
+
+void VideoMsg::setPacket(AVPacket* pPacket)
+{
+ setType(PACKET);
+ AVG_ASSERT(pPacket);
+ m_pPacket = pPacket;
+}
+
+AVPacket * VideoMsg::getPacket()
+{
+ AVG_ASSERT(getType() == PACKET);
+ return m_pPacket;
+}
+
+void VideoMsg::freePacket()
+{
+ if (getType() == PACKET) {
+ av_free_packet(m_pPacket);
+ delete m_pPacket;
+ m_pPacket = 0;
+ }
+}
+
+BitmapPtr VideoMsg::getFrameBitmap(int i)
+{
+ AVG_ASSERT(getType() == FRAME);
+ return m_pBmps[i];
+}
+
+float VideoMsg::getFrameTime()
+{
+ AVG_ASSERT(getType() == FRAME || getType() == VDPAU_FRAME);
+ return m_FrameTime;
+}
+
+vdpau_render_state* VideoMsg::getRenderState()
+{
+ AVG_ASSERT(getType() == VDPAU_FRAME);
+ return m_pRenderState;
+}
+
+}
+
diff --git a/src/video/VideoMsg.h b/src/video/VideoMsg.h
new file mode 100644
index 0000000..15a6007
--- /dev/null
+++ b/src/video/VideoMsg.h
@@ -0,0 +1,72 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _VideoMsg_H_
+#define _VideoMsg_H_
+
+#include "../api.h"
+#include "../base/Queue.h"
+#include "../graphics/Bitmap.h"
+
+#include "../audio/AudioMsg.h"
+
+#include <boost/shared_ptr.hpp>
+
+struct vdpau_render_state;
+struct AVPacket;
+
+namespace avg {
+
+class AVG_API VideoMsg: public AudioMsg {
+public:
+ VideoMsg();
+ void setFrame(const std::vector<BitmapPtr>& pBmps, float frameTime);
+ void setVDPAUFrame(vdpau_render_state* pRenderState, float frameTime);
+ void setPacket(AVPacket* pPacket);
+
+ virtual ~VideoMsg();
+
+ BitmapPtr getFrameBitmap(int i);
+ float getFrameTime();
+ AVPacket* getPacket();
+ void freePacket();
+
+ vdpau_render_state* getRenderState();
+
+private:
+ // FRAME
+ std::vector<BitmapPtr> m_pBmps;
+ float m_FrameTime;
+
+ // VDPAU_FRAME
+ vdpau_render_state* m_pRenderState;
+
+ // PACKET
+ AVPacket * m_pPacket;
+};
+
+typedef boost::shared_ptr<VideoMsg> VideoMsgPtr;
+typedef Queue<VideoMsg> VideoMsgQueue;
+typedef boost::shared_ptr<VideoMsgQueue> VideoMsgQueuePtr;
+
+}
+#endif
+
diff --git a/src/video/WrapFFMpeg.h b/src/video/WrapFFMpeg.h
new file mode 100644
index 0000000..d61d8a0
--- /dev/null
+++ b/src/video/WrapFFMpeg.h
@@ -0,0 +1,93 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _WrapFFMpeg_H_
+#define _WrapFFMpeg_H_
+
+#include "../avgconfigwrapper.h"
+
+#ifdef _WIN32
+#define EMULATE_INTTYPES
+#else
+// This is probably GCC-specific.
+#if !defined INT64_C
+#if defined __WORDSIZE && __WORDSIZE == 64
+#define INT64_C(c) c ## L
+#define UINT64_C(c) c ## UL
+#else
+#define INT64_C(c) c ## LL
+#define UINT64_C(c) c ## ULL
+#endif
+#endif
+#endif
+
+extern "C" {
+#include <libavcodec/avcodec.h>
+#include <libavformat/avformat.h>
+#include <libswscale/swscale.h>
+#include <libavutil/avutil.h>
+#include <libavutil/pixdesc.h>
+#include <libavutil/mathematics.h>
+#include <libavutil/opt.h>
+#if LIBAVFORMAT_VERSION_MAJOR < 53
+#define AVMEDIA_TYPE_VIDEO CODEC_TYPE_VIDEO
+#define AVMEDIA_TYPE_AUDIO CODEC_TYPE_AUDIO
+#endif
+
+#if LIBAVFORMAT_VERSION_MAJOR > 52
+ #define SAMPLE_FMT_S16 AV_SAMPLE_FMT_S16
+ #define SAMPLE_FMT_FLT AV_SAMPLE_FMT_FLT
+ #define SAMPLE_FMT_DBL AV_SAMPLE_FMT_DBL
+ #define SAMPLE_FMT_S32 AV_SAMPLE_FMT_S32
+ #define SAMPLE_FMT_U8 AV_SAMPLE_FMT_U8
+ #define SAMPLE_FMT_S16P AV_SAMPLE_FMT_S16P
+ #define SAMPLE_FMT_FLTP AV_SAMPLE_FMT_FLTP
+ #define SampleFormat AVSampleFormat
+#endif
+
+#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(54, 25, 00)
+ #define AV_CODEC_ID_MPEG1VIDEO CODEC_ID_MPEG1VIDEO
+ #define AV_CODEC_ID_MPEG2VIDEO CODEC_ID_MPEG2VIDEO
+ #define AV_CODEC_ID_H264 CODEC_ID_H264
+ #define AV_CODEC_ID_WMV3 CODEC_ID_WMV3
+ #define AV_CODEC_ID_VC1 CODEC_ID_VC1
+ #define AV_CODEC_ID_MJPEG CODEC_ID_MJPEG
+ #define AV_CODEC_ID_NONE CODEC_ID_NONE
+#endif
+
+#ifndef URL_WRONLY
+ #define url_fopen avio_open
+ #define url_fclose avio_close
+ #define URL_WRONLY AVIO_FLAG_WRITE
+#endif
+#ifdef HAVE_LIBAVRESAMPLE_AVRESAMPLE_H
+ #include <libavresample/avresample.h>
+ #include <libavresample/version.h>
+#endif
+}
+
+#ifdef PixelFormat
+#undef PixelFormat
+#else
+#define AVPixelFormat ::PixelFormat
+#endif
+
+#endif
diff --git a/src/video/baseline/mjpeg-48x48.avi_1.png b/src/video/baseline/mjpeg-48x48.avi_1.png
new file mode 100644
index 0000000..0a8e5ca
--- /dev/null
+++ b/src/video/baseline/mjpeg-48x48.avi_1.png
Binary files differ
diff --git a/src/video/baseline/mjpeg-48x48.avi_100.png b/src/video/baseline/mjpeg-48x48.avi_100.png
new file mode 100644
index 0000000..343e45b
--- /dev/null
+++ b/src/video/baseline/mjpeg-48x48.avi_100.png
Binary files differ
diff --git a/src/video/baseline/mjpeg-48x48.avi_2.png b/src/video/baseline/mjpeg-48x48.avi_2.png
new file mode 100644
index 0000000..93a551b
--- /dev/null
+++ b/src/video/baseline/mjpeg-48x48.avi_2.png
Binary files differ
diff --git a/src/video/baseline/mjpeg-48x48.avi_201.png b/src/video/baseline/mjpeg-48x48.avi_201.png
new file mode 100644
index 0000000..eb9d4a0
--- /dev/null
+++ b/src/video/baseline/mjpeg-48x48.avi_201.png
Binary files differ
diff --git a/src/video/baseline/mjpeg-48x48.avi_53.png b/src/video/baseline/mjpeg-48x48.avi_53.png
new file mode 100644
index 0000000..22f00c2
--- /dev/null
+++ b/src/video/baseline/mjpeg-48x48.avi_53.png
Binary files differ
diff --git a/src/video/baseline/mjpeg-48x48.avi_end.png b/src/video/baseline/mjpeg-48x48.avi_end.png
new file mode 100644
index 0000000..ed5df07
--- /dev/null
+++ b/src/video/baseline/mjpeg-48x48.avi_end.png
Binary files differ
diff --git a/src/video/baseline/mjpeg-48x48.avi_loop.png b/src/video/baseline/mjpeg-48x48.avi_loop.png
new file mode 100644
index 0000000..f711a88
--- /dev/null
+++ b/src/video/baseline/mjpeg-48x48.avi_loop.png
Binary files differ
diff --git a/src/video/baseline/mpeg1-48x48-sound.avi_end.png b/src/video/baseline/mpeg1-48x48-sound.avi_end.png
new file mode 100644
index 0000000..ad712f0
--- /dev/null
+++ b/src/video/baseline/mpeg1-48x48-sound.avi_end.png
Binary files differ
diff --git a/src/video/baseline/mpeg1-48x48-sound.avi_loop.png b/src/video/baseline/mpeg1-48x48-sound.avi_loop.png
new file mode 100644
index 0000000..db42610
--- /dev/null
+++ b/src/video/baseline/mpeg1-48x48-sound.avi_loop.png
Binary files differ
diff --git a/src/video/baseline/mpeg1-48x48.mov_1.png b/src/video/baseline/mpeg1-48x48.mov_1.png
new file mode 100644
index 0000000..f14e25b
--- /dev/null
+++ b/src/video/baseline/mpeg1-48x48.mov_1.png
Binary files differ
diff --git a/src/video/baseline/mpeg1-48x48.mov_2.png b/src/video/baseline/mpeg1-48x48.mov_2.png
new file mode 100644
index 0000000..0c0aa5a
--- /dev/null
+++ b/src/video/baseline/mpeg1-48x48.mov_2.png
Binary files differ
diff --git a/src/video/baseline/mpeg1-48x48.mov_end.png b/src/video/baseline/mpeg1-48x48.mov_end.png
new file mode 100644
index 0000000..07efff2
--- /dev/null
+++ b/src/video/baseline/mpeg1-48x48.mov_end.png
Binary files differ
diff --git a/src/video/baseline/mpeg1-48x48.mov_loop.png b/src/video/baseline/mpeg1-48x48.mov_loop.png
new file mode 100644
index 0000000..f14e25b
--- /dev/null
+++ b/src/video/baseline/mpeg1-48x48.mov_loop.png
Binary files differ
diff --git a/src/video/testvideo.cpp b/src/video/testvideo.cpp
new file mode 100644
index 0000000..0bca650
--- /dev/null
+++ b/src/video/testvideo.cpp
@@ -0,0 +1,543 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "AsyncVideoDecoder.h"
+#include "SyncVideoDecoder.h"
+#ifdef AVG_ENABLE_VDPAU
+#include "VDPAUDecoder.h"
+#endif
+
+#include "../graphics/Filterfliprgba.h"
+#include "../graphics/Filterfliprgb.h"
+#include "../graphics/GraphicsTest.h"
+#include "../graphics/BitmapLoader.h"
+
+#include "../base/StringHelper.h"
+#include "../base/TimeSource.h"
+#include "../base/TestSuite.h"
+#include "../base/Exception.h"
+#include "../base/ThreadProfiler.h"
+#include "../base/Directory.h"
+#include "../base/DirEntry.h"
+
+#include <string>
+#include <sstream>
+#include <cmath>
+
+#include <glib-object.h>
+
+using namespace avg;
+using namespace std;
+using namespace boost;
+
+class DecoderTest: public GraphicsTest {
+ public:
+ DecoderTest(const string& sClassName, bool bThreaded,
+ bool bUseHardwareAcceleration)
+ : GraphicsTest(sClassName+getDecoderName(bThreaded, bUseHardwareAcceleration),
+ 2),
+ m_bThreaded(bThreaded),
+ m_bUseHardwareAcceleration(bUseHardwareAcceleration)
+ {}
+
+ protected:
+ bool isThreaded()
+ {
+ return m_bThreaded;
+ }
+
+ bool useHardwareAcceleration()
+ {
+ return m_bUseHardwareAcceleration;
+ }
+
+ VideoDecoderPtr createDecoder()
+ {
+ VideoDecoderPtr pDecoder;
+ if (m_bThreaded) {
+ pDecoder = VideoDecoderPtr(new AsyncVideoDecoder(8));
+ } else {
+ pDecoder = VideoDecoderPtr(new SyncVideoDecoder());
+ }
+
+ return pDecoder;
+ }
+
+ const AudioParams* getAudioParams()
+ {
+ static AudioParams AP(44100, 2, 256);
+ return &AP;
+ }
+
+ int processAudioMsg(AudioMsgQueuePtr pMsgQ, AudioMsgQueuePtr pStatusQ)
+ {
+ AudioMsgPtr pMsg = pMsgQ->pop(false);
+ if (pMsg) {
+ switch (pMsg->getType()) {
+ case AudioMsg::AUDIO: {
+ AudioBufferPtr pBuffer = pMsg->getAudioBuffer();
+ AudioMsgPtr pStatusMsg(new AudioMsg);
+ pStatusMsg->setAudioTime(pMsg->getAudioTime());
+ pStatusQ->push(AudioMsgPtr(pStatusMsg));
+ return pBuffer->getNumFrames();
+ }
+ case AudioMsg::SEEK_DONE: {
+ AudioMsgPtr pStatusMsg(new AudioMsg);
+ pStatusMsg->setSeekDone(pMsg->getSeekSeqNum(),
+ pMsg->getSeekTime());
+ pStatusQ->push(AudioMsgPtr(pStatusMsg));
+ return -1;
+ }
+ default:
+ pStatusQ->push(pMsg);
+ return 0;
+ }
+ } else {
+ return 0;
+ }
+ }
+
+ void processAudioSeek(AudioMsgQueuePtr pMsgQ, AudioMsgQueuePtr pStatusQ)
+ {
+ int framesDecoded = 0;
+ while (framesDecoded != -1) {
+ // The real AudioSource blocks on pMsgQ->pop()
+ msleep(10);
+ framesDecoded = processAudioMsg(pMsgQ, pStatusQ);
+ }
+ }
+
+ virtual void testEqual(Bitmap& resultBmp, const std::string& sFName,
+ avg::PixelFormat pf = NO_PIXELFORMAT, float maxAverage=1.0,
+ float maxStdDev=1.0)
+ {
+ GraphicsTest::testEqual(resultBmp, sFName, pf, maxAverage, maxStdDev);
+ }
+
+ void testEqual(Bitmap& resultBmp, Bitmap& BaselineBmp,
+ const std::string& sFName, float maxAverage=1.0f, float maxStdDev=1.0f)
+ {
+ GraphicsTest::testEqual(resultBmp, BaselineBmp, sFName,
+ maxAverage, maxStdDev);
+ }
+
+ string getMediaLoc(const string& sFilename)
+ {
+ return getSrcDirName()+"../test/media/"+sFilename;
+ }
+
+ private:
+ string getDecoderName(bool bThreaded, bool bUseHardwareAcceleration)
+ {
+ string sName = "(";
+ if (bThreaded) {
+ sName += "Threaded";
+ } else {
+ sName += "Sync";
+ }
+ if (bUseHardwareAcceleration) {
+ sName += ", VDPAU)";
+ } else {
+ sName += ")";
+ }
+ return sName;
+ }
+
+ bool m_bThreaded;
+ bool m_bUseHardwareAcceleration;
+};
+
+class VideoDecoderTest: public DecoderTest {
+ public:
+ VideoDecoderTest(bool bThreaded, bool bUseHardwareAcceleration)
+ : DecoderTest("VideoDecoderTest", bThreaded, bUseHardwareAcceleration)
+ {}
+
+ void runTests()
+ {
+ basicFileTest("mpeg1-48x48.mov", 30);
+#ifndef AVG_ENABLE_RPI
+ basicFileTest("mjpeg-48x48.avi", 202);
+ testSeeks("mjpeg-48x48.avi");
+#else
+ cerr << "Skipping mjpeg tests: SW decoding too slow on RaspberryPi." << endl;
+#endif
+ }
+
+ private:
+ void basicFileTest(const string& sFilename, int expectedNumFrames)
+ {
+ try {
+ cerr << " Testing " << sFilename << endl;
+
+ VideoDecoderPtr pDecoder = createDecoder();
+ pDecoder->open(getMediaLoc(sFilename), useHardwareAcceleration(), true);
+ IntPoint frameSize = pDecoder->getSize();
+ TEST(frameSize == IntPoint(48, 48));
+ TEST(pDecoder->getVideoInfo().m_bHasVideo);
+ TEST(pDecoder->getVideoInfo().m_Duration != 0);
+ TEST(pDecoder->getStreamFPS() != 0);
+ TEST(pDecoder->getFPS() != 0);
+ pDecoder->startDecoding(false, getAudioParams());
+ TEST(pDecoder->getPixelFormat() == B8G8R8X8);
+ BitmapPtr pBmp(new Bitmap(frameSize, B8G8R8X8));
+
+ // Test first two frames.
+ pDecoder->renderToBmp(pBmp, -1);
+ testEqual(*pBmp, sFilename+"_1", B8G8R8X8);
+ TEST(pDecoder->getCurFrame() == 0);
+ TEST(pDecoder->getCurTime() == 0);
+
+ pDecoder->renderToBmp(pBmp, -1);
+ testEqual(*pBmp, sFilename+"_2", B8G8R8X8);
+ pDecoder->close();
+
+ readWholeFile(sFilename, 1, expectedNumFrames);
+ readWholeFile(sFilename, 0.5, expectedNumFrames);
+ readWholeFile(sFilename, 2, expectedNumFrames/2);
+ } catch (Exception & ex) {
+ cerr << string(m_IndentLevel+6, ' ') << ex.getStr() << endl;
+ throw;
+ }
+ }
+
+ void testSeeks(const string& sFilename)
+ {
+ cerr << " Testing " << sFilename << " (seek)" << endl;
+
+ VideoDecoderPtr pDecoder = createDecoder();
+ pDecoder->open(getMediaLoc(sFilename), useHardwareAcceleration(), true);
+ pDecoder->startDecoding(false, getAudioParams());
+
+ // Seek forward
+ testSeek(100, sFilename, pDecoder);
+ // Seek backward
+ testSeek(53, sFilename, pDecoder);
+ // Seek to last frame
+ testSeek(201, sFilename, pDecoder);
+
+ pDecoder->close();
+ }
+
+ void testSeek(int frameNum, const string& sFilename, VideoDecoderPtr pDecoder)
+ {
+ IntPoint frameSize = pDecoder->getSize();
+
+ BitmapPtr pBmp(new Bitmap(frameSize, B8G8R8X8));
+ pDecoder->seek(float(frameNum)/pDecoder->getStreamFPS());
+ pDecoder->renderToBmp(pBmp, -1);
+ testEqual(*pBmp, sFilename+"_"+toString(frameNum), B8G8R8X8);
+
+ }
+
+ void readWholeFile(const string& sFilename, float speedFactor,
+ int expectedNumFrames)
+ {
+ // Read whole file, test last image.
+ VideoDecoderPtr pDecoder = createDecoder();
+ pDecoder->open(getMediaLoc(sFilename), useHardwareAcceleration(), true);
+ IntPoint frameSize = pDecoder->getSize();
+ float timePerFrame = (1.0f/pDecoder->getFPS())*speedFactor;
+ pDecoder->startDecoding(false, getAudioParams());
+ BitmapPtr pBmp(new Bitmap(frameSize, B8G8R8X8));
+ int numFrames = 0;
+ float curTime = 0;
+
+ while (!pDecoder->isEOF()) {
+ FrameAvailableCode frameAvailable = pDecoder->renderToBmp(pBmp, curTime);
+ if (frameAvailable == FA_NEW_FRAME) {
+/*
+ stringstream ss;
+ ss << "resultimages/" << sFilename << numFrames << ".png";
+ pBmp->save(ss.str());
+*/
+ numFrames++;
+ } else {
+ msleep(0);
+ }
+ if (frameAvailable == FA_NEW_FRAME || frameAvailable == FA_USE_LAST_FRAME)
+ {
+ curTime += timePerFrame;
+ }
+ }
+// cerr << "numFrames: " << numFrames <<
+// ", expectedNumFrames: " << expectedNumFrames << endl;
+ TEST(numFrames == expectedNumFrames);
+ if (speedFactor == 1 && !useHardwareAcceleration()) {
+ // The last frame is broken with VDPAU sometimes. Not sure why this is,
+ // possibly a libav bug.
+ testEqual(*pBmp, sFilename+"_end", B8G8R8X8);
+ }
+
+ // Test loop.
+ pDecoder->loop();
+ pDecoder->renderToBmp(pBmp, -1);
+ testEqual(*pBmp, sFilename+"_loop", B8G8R8X8);
+
+ pDecoder->close();
+ }
+
+};
+
+class AudioDecoderTest: public DecoderTest {
+ public:
+ AudioDecoderTest()
+ : DecoderTest("AudioDecoderTest", true, false)
+ {}
+
+ void runTests()
+ {
+
+ testOneFile("22.050Hz_16bit_mono.wav");
+
+ testOneFile("44.1kHz_16bit_mono.wav");
+ testOneFile("44.1kHz_16bit_stereo.wav");
+ testOneFile("44.1kHz_24bit_mono.wav");
+ testOneFile("44.1kHz_24bit_stereo.wav");
+
+ testOneFile("48kHz_16bit_mono.wav");
+ testOneFile("48kHz_16bit_stereo.wav");
+ testOneFile("48kHz_24bit_mono.wav");
+ testOneFile("48kHz_24bit_stereo.wav");
+
+ testOneFile("44.1kHz_16bit_stereo.aif");
+ testOneFile("44.1kHz_stereo.mp3");
+ }
+
+ private:
+ void testOneFile(const string& sFilename)
+ {
+ try {
+ cerr << " Testing " << sFilename << endl;
+
+ {
+ cerr << " Reading complete file." << endl;
+ AsyncVideoDecoderPtr pDecoder =
+ dynamic_pointer_cast<AsyncVideoDecoder>(createDecoder());
+ pDecoder->open(getMediaLoc(sFilename), useHardwareAcceleration(), true);
+ TEST(pDecoder->getVideoInfo().m_bHasAudio);
+ pDecoder->startDecoding(false, getAudioParams());
+ AudioMsgQueuePtr pMsgQ = pDecoder->getAudioMsgQ();
+ AudioMsgQueuePtr pStatusQ = pDecoder->getAudioStatusQ();
+ int totalFramesDecoded = 0;
+ readAudioToEOF(pDecoder, pMsgQ, pStatusQ, totalFramesDecoded, true);
+
+ // Check if we've decoded the whole file.
+ int framesInDuration = int(pDecoder->getVideoInfo().m_Duration*44100);
+// cerr << "framesInDuration: " << framesInDuration << endl;
+// cerr << "framesDecoded: " << totalFramesDecoded << endl;
+ TEST(abs(totalFramesDecoded-framesInDuration) < 65);
+ }
+ {
+ cerr << " Seek test." << endl;
+ AsyncVideoDecoderPtr pDecoder =
+ dynamic_pointer_cast<AsyncVideoDecoder>(createDecoder());
+ pDecoder->open(getMediaLoc(sFilename), useHardwareAcceleration(), true);
+ float duration = pDecoder->getVideoInfo().m_Duration;
+ pDecoder->startDecoding(false, getAudioParams());
+ AudioMsgQueuePtr pMsgQ = pDecoder->getAudioMsgQ();
+ AudioMsgQueuePtr pStatusQ = pDecoder->getAudioStatusQ();
+ pDecoder->seek(duration/2);
+ processAudioSeek(pMsgQ, pStatusQ);
+ int totalFramesDecoded = 0;
+
+ readAudioToEOF(pDecoder, pMsgQ, pStatusQ, totalFramesDecoded, false);
+ if (sFilename.find(".mp3") == string::npos) {
+ // Check if we've decoded half the file.
+ // TODO: Find out why there are problems with this
+ // for mp3 files.
+ int framesInDuration =
+ int(pDecoder->getVideoInfo().m_Duration*44100);
+// cerr << "framesDecoded: " << totalFramesDecoded << endl;
+// cerr << "framesInDuration: " << framesInDuration << endl;
+ TEST(abs(totalFramesDecoded-framesInDuration/2) < 65);
+ }
+ }
+
+ } catch (Exception & ex) {
+ cerr << string(m_IndentLevel+6, ' ') << ex.getStr() << endl;
+ throw;
+ }
+ }
+
+ void readAudioToEOF(AsyncVideoDecoderPtr pDecoder, AudioMsgQueuePtr pMsgQ,
+ AudioMsgQueuePtr pStatusQ, int& totalFramesDecoded,
+ bool bCheckTimestamps)
+ {
+ int numWrongTimestamps = 0;
+ while (!pDecoder->isEOF()) {
+ int framesDecoded = 0;
+ while (framesDecoded == 0 && !pDecoder->isEOF()) {
+ framesDecoded = processAudioMsg(pMsgQ, pStatusQ);
+ AVG_ASSERT(framesDecoded != -1);
+ pDecoder->updateAudioStatus();
+ msleep(0);
+ }
+ totalFramesDecoded += framesDecoded;
+ float curTime = float(totalFramesDecoded)/44100;
+ if (abs(curTime-pDecoder->getCurTime()) > 0.02f) {
+ numWrongTimestamps++;
+ }
+ }
+ if (bCheckTimestamps) {
+ if (numWrongTimestamps>0) {
+ TEST_FAILED(numWrongTimestamps << " wrong timestamps.");
+ }
+ }
+ }
+};
+
+
+class AVDecoderTest: public DecoderTest {
+ public:
+ AVDecoderTest(bool bUseHardwareAcceleration)
+ : DecoderTest("AVDecoderTest", true, bUseHardwareAcceleration)
+ {}
+
+ void runTests()
+ {
+ basicFileTest("mpeg1-48x48-sound.avi", 30);
+ }
+
+ private:
+ void basicFileTest(const string& sFilename, int expectedNumFrames)
+ {
+ VideoDecoderPtr pDecoder = createDecoder();
+ pDecoder->open(getMediaLoc(sFilename), useHardwareAcceleration(), true);
+ TEST(pDecoder->getVideoInfo().m_bHasVideo);
+ TEST(pDecoder->getStreamFPS() != 0);
+ pDecoder->startDecoding(false, getAudioParams());
+ AudioMsgQueuePtr pMsgQ;
+ AudioMsgQueuePtr pStatusQ;
+
+ pMsgQ = dynamic_pointer_cast<AsyncVideoDecoder>(pDecoder) ->getAudioMsgQ();
+ pStatusQ = dynamic_pointer_cast<AsyncVideoDecoder>(pDecoder)
+ ->getAudioStatusQ();
+ TEST(pDecoder->getVideoInfo().m_bHasAudio);
+
+ IntPoint frameSize = pDecoder->getSize();
+ BitmapPtr pBmp(new Bitmap(frameSize, B8G8R8X8));
+ int numFrames = 0;
+ int totalFramesDecoded = 0;
+ float curTime = 0;
+
+ while (!pDecoder->isEOF()) {
+ FrameAvailableCode frameAvailable;
+ do {
+ frameAvailable = pDecoder->renderToBmp(pBmp, curTime);
+ msleep(0);
+ } while (frameAvailable == FA_STILL_DECODING);
+ if (frameAvailable == FA_NEW_FRAME) {
+// stringstream ss;
+// ss << sFilename << numFrames << ".png";
+// pBmp->save(ss.str());
+ numFrames++;
+ }
+ int framesDecoded = 0;
+ while (framesDecoded == 0 && !pDecoder->isEOF()) {
+ framesDecoded = processAudioMsg(pMsgQ, pStatusQ);
+ dynamic_pointer_cast<AsyncVideoDecoder>(pDecoder)
+ ->updateAudioStatus();
+ msleep(0);
+ }
+ totalFramesDecoded += framesDecoded;
+
+ curTime += 1.0f/pDecoder->getFPS();
+ }
+ TEST(pDecoder->isEOF());
+ TEST(numFrames == expectedNumFrames);
+ testEqual(*pBmp, sFilename+"_end", B8G8R8X8);
+
+ // Test loop.
+ pDecoder->seek(0);
+ processAudioSeek(pMsgQ, pStatusQ);
+ pDecoder->renderToBmp(pBmp, -1);
+ testEqual(*pBmp, sFilename+"_loop", B8G8R8X8);
+
+ pDecoder->close();
+ }
+};
+
+
+class VideoTestSuite: public TestSuite {
+public:
+ VideoTestSuite()
+ : TestSuite("VideoTestSuite")
+ {
+ addAudioTests();
+ addVideoTests(false);
+#ifdef AVG_ENABLE_VDPAU
+ if (VDPAUDecoder::isAvailable()) {
+ addVideoTests(true);
+ } else {
+ cerr << "Skipping VDPAU tests: VDPAU configured but not available." << endl;
+ }
+#else
+ cerr << "Skipping VDPAU tests: VDPAU not configured." << endl;
+#endif
+ }
+private:
+
+ void addAudioTests()
+ {
+ addTest(TestPtr(new AudioDecoderTest()));
+ }
+
+ void addVideoTests(bool bUseHardwareAcceleration)
+ {
+ addTest(TestPtr(new VideoDecoderTest(false, bUseHardwareAcceleration)));
+ addTest(TestPtr(new VideoDecoderTest(true, bUseHardwareAcceleration)));
+
+ addTest(TestPtr(new AVDecoderTest(bUseHardwareAcceleration)));
+ }
+};
+
+
+int main(int nargs, char** args)
+{
+ ThreadProfiler* pProfiler = ThreadProfiler::get();
+ pProfiler->setName("main");
+
+ GraphicsTest::createResultImgDir();
+
+ BitmapLoader::init(true);
+ VideoTestSuite suite;
+ bool bOk;
+
+ suite.runTests();
+ bOk = suite.isOk();
+/*
+ for (int i=0; i<300; ++i) {
+// while(true) {
+ suite.runTests();
+ bOk = suite.isOk();
+ if (!bOk) {
+ return 1;
+ }
+ }
+*/
+ if (bOk) {
+ return 0;
+ } else {
+ return 1;
+ }
+}
+
diff --git a/src/wrapper/Makefile.am b/src/wrapper/Makefile.am
new file mode 100644
index 0000000..93d5260
--- /dev/null
+++ b/src/wrapper/Makefile.am
@@ -0,0 +1,45 @@
+AM_CPPFLAGS = -I. -I../player \
+ @XML2_CFLAGS@ @PTHREAD_CFLAGS@ @PANGOFT2_CFLAGS@ @PYTHON_CPPFLAGS@ \
+ @DC1394_2_CFLAGS@ @LIBRSVG_CFLAGS@ @FONTCONFIG_CFLAGS@
+
+ALL_H = WrapHelper.h raw_constructor.hpp
+
+if APPLE
+ XGL_LIBS =
+ APPLE_LDFLAGS = -read_only_relocs suppress -F/System/Library/PrivateFrameworks \
+ -framework MultitouchSupport
+else
+if ENABLE_RPI
+ XGL_LIBS = -lXxf86vm -lX11 -lGLESv2 -lEGL
+else
+if ENABLE_EGL
+ XGL_LIBS = -lX11 -lGLESv2 -lEGL
+else
+ XGL_LIBS = -lXxf86vm -lX11
+endif
+endif
+ APPLE_LDFLAGS =
+endif
+
+ALL_GL_LIBS = @GL_LIBS@ @SDL_LIBS@ $(XGL_LIBS)
+
+pkgpyexec_LTLIBRARIES = avg.la
+avg_la_SOURCES = WrapHelper.cpp avg_wrap.cpp node_wrap.cpp raster_wrap.cpp \
+ event_wrap.cpp fx_wrap.cpp \
+ bitmap_wrap.cpp anim_wrap.cpp $(ALL_H)
+avg_la_LDFLAGS = $(APPLE_LDFLAGS) -module -XCClinker
+avg_la_LIBADD = ../player/libplayer.la \
+ ../audio/libaudio.la \
+ ../video/libvideo.la \
+ ../graphics/libgraphics.la \
+ ../base/libbase.la \
+ ../base/triangulate/libtriangulate.la \
+ ../imaging/libimaging.la \
+ ../anim/libanim.la \
+ ../lmfit/liblmfit.la \
+ ../oscpack/liboscpack.la \
+ @PANGOFT2_LIBS@ @LIBRSVG_LIBS@ $(BOOST_PYTHON_LIBS) \
+ @BOOST_THREAD_LIBS@ @XML2_LIBS@ \
+ @DC1394_2_LIBS@ @GLU_LIBS@ $(XI2_1_LIBS) $(XI2_2_LIBS) \
+ $(ALL_GL_LIBS) @LIBFFMPEG@ @LIBAVRESAMPLE@ @PTHREAD_LIBS@ \
+ @GDK_PIXBUF_LIBS@ @FONTCONFIG_LIBS@
diff --git a/src/wrapper/WrapHelper.cpp b/src/wrapper/WrapHelper.cpp
new file mode 100644
index 0000000..258a094
--- /dev/null
+++ b/src/wrapper/WrapHelper.cpp
@@ -0,0 +1,428 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "WrapHelper.h"
+
+#include "../base/Logger.h"
+#include "../base/Exception.h"
+#include "../base/MathHelper.h"
+#include "../base/ObjectCounter.h"
+
+#include "../player/PythonLogSink.h"
+#include "../player/PublisherDefinitionRegistry.h"
+
+#include <boost/version.hpp>
+
+using namespace avg;
+using namespace std;
+using namespace boost::python;
+
+namespace Vec2Helper
+{
+ int len(const glm::vec2&)
+ {
+ return 2;
+ }
+
+ float getX(const glm::vec2& pt)
+ {
+ return pt.x;
+ }
+
+ float getY(const glm::vec2& pt)
+ {
+ return pt.y;
+ }
+
+ void setX(glm::vec2& pt, float val)
+ {
+ pt.x = val;
+ }
+
+ void setY(glm::vec2& pt, float val)
+ {
+ pt.y = val;
+ }
+
+ void checkItemRange(int i) {
+ if (i != 0 && i != 1) {
+ throw std::out_of_range("Index out of range for Point2D. Must be 0 or 1.");
+ }
+ }
+
+ float getItem(const glm::vec2& pt, int i)
+ {
+ checkItemRange(i);
+ if (i==0) {
+ return pt.x;
+ } else {
+ return pt.y;
+ }
+ }
+
+ void setItem(glm::vec2& pt, int i, float val)
+ {
+ checkItemRange(i);
+ if (i==0) {
+ pt.x = val;
+ } else {
+ pt.y = val;
+ }
+ }
+
+ string str(const glm::vec2& pt)
+ {
+ stringstream st;
+ st << "(" << pt.x << "," << pt.y << ")";
+ return st.str();
+ }
+
+ string repr(const glm::vec2& pt)
+ {
+ stringstream st;
+ st << "avg.Point2D(" << pt.x << "," << pt.y << ")";
+ return st.str();
+ }
+
+ long getHash(const glm::vec2& pt)
+ {
+ // Wild guess at what could constitute a good hash function.
+ // Will generate very bad hashes if most values are in a range < 0.1,
+ // but this is meant for pixel values anyway, right? ;-).
+ return long(pt.x*42+pt.y*23);
+ }
+
+ glm::vec2 safeGetNormalized(const glm::vec2& pt)
+ {
+ if (pt.x==0 && pt.y==0) {
+ throw Exception(AVG_ERR_OUT_OF_RANGE, "Can't normalize (0,0).");
+ } else {
+ float invNorm = 1/sqrt(pt.x*pt.x+pt.y*pt.y);
+ return glm::vec2(pt.x*invNorm, pt.y*invNorm);
+ }
+ }
+
+ float getNorm(const glm::vec2& pt)
+ {
+ return glm::length(pt);
+ }
+
+ float vecAngle(const glm::vec2& pt1, const glm::vec2& pt2)
+ {
+ float angle = fmod((atan2(pt1.y, pt1.x) - atan2(pt2.y, pt2.x)), float(2*M_PI));
+ if (angle < 0) {
+ angle += 2*M_PI;
+ }
+ return angle;
+ }
+}
+
+// The ConstVec2 stuff is there so that vec2 attributes behave sensibly. That is,
+// node.pos.x = 30 causes an error instead of failing silently.
+ConstVec2::ConstVec2()
+{
+}
+
+ConstVec2::ConstVec2(const glm::vec2& other)
+{
+ x = other.x;
+ y = other.y;
+}
+
+glm::vec2 ConstVec2::toVec2() const
+{
+ return glm::vec2(x,y);
+}
+
+void checkEmptyArgs(const boost::python::tuple &args, int numArgs)
+{
+ if (boost::python::len(args) != numArgs) {
+ throw avg::Exception(AVG_ERR_INVALID_ARGS,
+ "Nodes must be constructed using named parameters. Positional parameters are not supported.");
+ }
+}
+
+template<class VEC2>
+struct Vec2_to_python_tuple
+{
+ static PyObject* convert (VEC2 v)
+ {
+ return boost::python::incref(boost::python::make_tuple(v.x, v.y).ptr());
+ }
+};
+
+template<class VEC3>
+struct Vec3_to_python_tuple
+{
+ static PyObject* convert (VEC3 v)
+ {
+ return boost::python::incref(boost::python::make_tuple(v.x, v.y, v.z).ptr());
+ }
+};
+
+template<class VEC2, class ATTR>
+struct vec2_from_python
+{
+ vec2_from_python()
+ {
+ boost::python::converter::registry::push_back(
+ &convertible, &construct, boost::python::type_id<VEC2>());
+ }
+
+ static void* convertible(PyObject* obj_ptr)
+ {
+ // Using PySequence_Check here causes infinite recursion.
+ if (!PyTuple_Check(obj_ptr) && !PyList_Check(obj_ptr)) {
+ return 0;
+ }
+ if (PySequence_Size(obj_ptr) != 2) {
+ return 0;
+ }
+ return obj_ptr;
+ }
+
+ static void construct(PyObject* obj_ptr,
+ boost::python::converter::rvalue_from_python_stage1_data* data)
+ {
+ VEC2 pt;
+ PyObject * pEntry = PySequence_GetItem(obj_ptr, 0);
+ pt.x = (ATTR)PyFloat_AsDouble(pEntry);
+ Py_DECREF(pEntry);
+ pEntry = PySequence_GetItem(obj_ptr, 1);
+ pt.y = (ATTR)PyFloat_AsDouble(pEntry);
+ Py_DECREF(pEntry);
+ void* storage = (
+ (boost::python::converter::rvalue_from_python_storage<VEC2>*)data)
+ ->storage.bytes;
+ new (storage) VEC2(pt);
+ data->convertible = storage;
+ }
+};
+
+template<class VEC3, class ATTR>
+struct vec3_from_python
+{
+ vec3_from_python()
+ {
+ boost::python::converter::registry::push_back(
+ &convertible, &construct, boost::python::type_id<VEC3>());
+ }
+
+ static void* convertible(PyObject* obj_ptr)
+ {
+ if (!PySequence_Check(obj_ptr)) {
+ return 0;
+ }
+ if (PySequence_Size(obj_ptr) != 3) {
+ return 0;
+ }
+ return obj_ptr;
+ }
+
+ static void construct(PyObject* obj_ptr,
+ boost::python::converter::rvalue_from_python_stage1_data* data)
+ {
+ VEC3 t;
+ PyObject * pEntry = PySequence_GetItem(obj_ptr, 0);
+ t.x = (ATTR)PyFloat_AsDouble(pEntry);
+ Py_DECREF(pEntry);
+ pEntry = PySequence_GetItem(obj_ptr, 1);
+ t.y = (ATTR)PyFloat_AsDouble(pEntry);
+ Py_DECREF(pEntry);
+ pEntry = PySequence_GetItem(obj_ptr, 2);
+ t.z = (ATTR)PyFloat_AsDouble(pEntry);
+ Py_DECREF(pEntry);
+ void* storage = (
+ (boost::python::converter::rvalue_from_python_storage<VEC3>*)
+ data)->storage.bytes;
+ new (storage) VEC3(t);
+ data->convertible = storage;
+ }
+};
+
+struct UTF8String_to_unicode
+{
+ static PyObject *convert(const UTF8String & s)
+ {
+ const char * pStr = s.c_str();
+ return PyUnicode_DecodeUTF8(pStr, strlen(pStr), "ignore");
+ }
+};
+
+struct UTF8String_from_unicode
+{
+ UTF8String_from_unicode()
+ {
+ boost::python::converter::registry::push_back(
+ &convertible,
+ &construct,
+ boost::python::type_id<UTF8String>());
+ }
+
+ static void* convertible(PyObject* obj_ptr)
+ {
+ if (!PyUnicode_Check(obj_ptr)) return 0;
+ return obj_ptr;
+ }
+
+ static void construct(PyObject* obj_ptr,
+ boost::python::converter::rvalue_from_python_stage1_data* data)
+ {
+ PyObject * pPyUTF8 = PyUnicode_AsUTF8String(obj_ptr);
+ char * psz = PyString_AsString(pPyUTF8);
+ void* storage = (
+ (boost::python::converter::rvalue_from_python_storage<UTF8String>*)data)
+ ->storage.bytes;
+ new (storage) UTF8String(psz);
+ data->convertible = storage;
+ Py_DECREF(pPyUTF8);
+ }
+};
+
+struct UTF8String_from_string
+{
+ UTF8String_from_string()
+ {
+ boost::python::converter::registry::push_back(
+ &convertible,
+ &construct,
+ boost::python::type_id<UTF8String>());
+ }
+
+ static void* convertible(PyObject* obj_ptr)
+ {
+ if (!PyString_Check(obj_ptr)) return 0;
+ return obj_ptr;
+ }
+
+ static void construct(PyObject* obj_ptr,
+ boost::python::converter::rvalue_from_python_stage1_data* data)
+ {
+ const char * psz = PyString_AsString(obj_ptr);
+ void* storage = (
+ (boost::python::converter::rvalue_from_python_storage<UTF8String>*)data)
+ ->storage.bytes;
+ new (storage) UTF8String(psz);
+ data->convertible = storage;
+ }
+};
+
+void exportMessages(object& nodeClass, const string& sClassName)
+{
+ PublisherDefinitionPtr pPubDef = PublisherDefinitionRegistry::get()
+ ->getDefinition(sClassName);
+ const vector<MessageID>& messageIDs = pPubDef->getMessageIDs();
+ for (unsigned i=0; i<messageIDs.size(); ++i) {
+ string sName = messageIDs[i].m_sName;
+ nodeClass.attr(sName.c_str()) = messageIDs[i];
+ }
+};
+
+struct type_info_to_string{
+ static PyObject* convert(const std::type_info& info)
+ {
+ boost::python::object result(ObjectCounter::get()->demangle(info.name()));
+ return boost::python::incref(result.ptr());
+ }
+};
+
+
+void export_base()
+{
+ // Exceptions
+
+ translateException<exception>(PyExc_RuntimeError);
+ translateException<out_of_range>(PyExc_IndexError);
+ translateException<Exception>(PyExc_RuntimeError);
+ to_python_converter< exception, Exception_to_python_exception<exception> >();
+ to_python_converter< Exception, Exception_to_python_exception<Exception> >();
+
+ // vec2
+ to_python_converter<IntPoint, Vec2_to_python_tuple<IntPoint> >();
+ vec2_from_python<IntPoint, int>();
+ vec2_from_python<glm::vec2, float>();
+ vec2_from_python<ConstVec2, float>();
+
+ // vector<vec2>
+ to_python_converter<vector<glm::vec2>, to_list<vector<glm::vec2> > >();
+ from_python_sequence<vector<IntPoint>, variable_capacity_policy>();
+ from_python_sequence<vector<glm::vec2>, variable_capacity_policy>();
+
+ // vec3
+ to_python_converter<glm::ivec3, Vec3_to_python_tuple<glm::ivec3> >();
+ to_python_converter<glm::vec3, Vec3_to_python_tuple<glm::vec3> >();
+ vec3_from_python<glm::ivec3, int>();
+ vec3_from_python<glm::vec3, float>();
+
+ // vector<vec3>
+ to_python_converter<vector<glm::ivec3>, to_list<vector<glm::ivec3> > >();
+ to_python_converter<vector<glm::vec3>, to_list<vector<glm::vec3> > >();
+ from_python_sequence<vector<glm::ivec3>, variable_capacity_policy>();
+ from_python_sequence<vector<glm::vec3>, variable_capacity_policy>();
+
+ // string
+ to_python_converter<UTF8String, UTF8String_to_unicode>();
+ UTF8String_from_unicode();
+ UTF8String_from_string();
+
+ to_python_converter<vector<string>, to_list<vector<string> > >();
+ from_python_sequence<vector<string>, variable_capacity_policy>();
+
+ from_python_sequence<vector<float>, variable_capacity_policy>();
+ from_python_sequence<vector<int>, variable_capacity_policy>();
+
+ to_python_converter<std::type_info, type_info_to_string>();
+ //Maps
+ to_python_converter<TypeMap, to_dict<TypeMap> >();
+ to_python_converter<CatToSeverityMap, to_dict<CatToSeverityMap> >();
+}
+
+namespace {
+ std::map<PyObject *, LogSinkPtr> m_pyObjectMap;
+}
+
+void addPythonLogger(PyObject * self, PyObject * pyLogger)
+{
+ Logger * logger = Logger::get();
+ LogSinkPtr logSink(new PythonLogSink(pyLogger));
+ logger->addLogSink(logSink);
+ m_pyObjectMap[pyLogger] = logSink;
+}
+
+void removePythonLogger(PyObject * self, PyObject * pyLogger)
+{
+ Logger* logger = Logger::get();
+ std::map<PyObject *, LogSinkPtr>::iterator it;
+ it = m_pyObjectMap.find(pyLogger);
+ if( it !=m_pyObjectMap.end() ){
+ logger->removeLogSink(it->second);
+ m_pyObjectMap.erase(it);
+ }
+}
+
+void pytrace(PyObject * self, const avg::category_t& category, const UTF8String& sMsg,
+ avg::severity_t severity)
+{
+ avgDeprecationWarning(string("1.8"), "logger.trace",
+ "any of the logging convenience functions");
+ Logger::get()->trace(sMsg, category, severity);
+}
+
diff --git a/src/wrapper/WrapHelper.h b/src/wrapper/WrapHelper.h
new file mode 100644
index 0000000..cd86439
--- /dev/null
+++ b/src/wrapper/WrapHelper.h
@@ -0,0 +1,397 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _WrapHelper_H_
+#define _WrapHelper_H_
+
+#include "../api.h"
+#include "../base/GLMHelper.h"
+#include "../base/Exception.h"
+#include "../base/ILogSink.h"
+
+#include "../player/BoostPython.h"
+#include "../player/Player.h"
+#include "../player/TypeRegistry.h"
+
+#include <string>
+
+template<typename T> const T copyObject(const T& v) { return v; }
+
+template <typename ContainerType>
+struct to_tuple
+{
+ static PyObject* convert(ContainerType const& a)
+ {
+ boost::python::list result;
+ typedef typename ContainerType::const_iterator const_iter;
+ for(const_iter p=a.begin();p!=a.end();p++) {
+ result.append(boost::python::object(*p));
+ }
+ return boost::python::incref(boost::python::tuple(result).ptr());
+ }
+
+ static const PyTypeObject* get_pytype() { return &PyTuple_Type; }
+};
+
+template <typename ContainerType>
+struct to_list
+{
+ static PyObject* convert(ContainerType const& a)
+ {
+ boost::python::list result;
+ typedef typename ContainerType::const_iterator const_iter;
+ for(const_iter p=a.begin();p!=a.end();p++) {
+ result.append(boost::python::object(*p));
+ }
+ return boost::python::incref(result.ptr());
+ }
+
+ static const PyTypeObject* get_pytype() { return &PyList_Type; }
+};
+
+template <typename MapType>
+struct to_dict
+{
+ static PyObject* convert(MapType const& a)
+ {
+ boost::python::dict result;
+ typedef typename MapType::const_iterator const_iter;
+ for(const_iter p=a.begin();p!=a.end();p++){
+ result[p->first] = p->second;
+ }
+ return boost::python::incref(boost::python::dict(result).ptr());
+ }
+ static const PyTypeObject* get_pytype() { return &PyDict_Type; }
+};
+
+struct default_policy
+{
+ static bool check_convertibility_per_element() { return false; }
+
+ template <typename ContainerType>
+ static bool check_size(boost::type<ContainerType>, std::size_t /*sz*/)
+ {
+ return true;
+ }
+
+ template <typename ContainerType>
+ static void assert_size(boost::type<ContainerType>, std::size_t /*sz*/) {}
+
+ template <typename ContainerType>
+ static void reserve(ContainerType& a, std::size_t sz) {}
+};
+
+struct fixed_size_policy
+{
+ static bool check_convertibility_per_element() { return true; }
+
+ template <typename ContainerType>
+ static bool check_size(boost::type<ContainerType>, std::size_t sz)
+ {
+ return ContainerType::size() == sz;
+ }
+
+ template <typename ContainerType>
+ static void assert_size(boost::type<ContainerType>, std::size_t sz)
+ {
+ if (!check_size(boost::type<ContainerType>(), sz)) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "Insufficient elements for fixed-size array.");
+ boost::python::throw_error_already_set();
+ }
+ }
+
+ template <typename ContainerType>
+ static void reserve(ContainerType& /*a*/, std::size_t sz)
+ {
+ if (sz > ContainerType::size()) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "Too many elements for fixed-size array.");
+ boost::python::throw_error_already_set();
+ }
+ }
+
+ template <typename ContainerType, typename ValueType>
+ static void set_value(ContainerType& a, std::size_t i, ValueType const& v)
+ {
+ reserve(a, i+1);
+ a[i] = v;
+ }
+};
+
+struct variable_capacity_policy : default_policy
+{
+ template <typename ContainerType>
+ static void reserve(ContainerType& a, std::size_t sz)
+ {
+ a.reserve(sz);
+ }
+
+ template <typename ContainerType, typename ValueType>
+ static void set_value(
+ ContainerType& a,
+ std::size_t
+#if !defined(NDEBUG)
+ i
+#endif
+ ,
+ ValueType const& v)
+ {
+ assert(a.size() == i);
+ a.push_back(v);
+ }
+};
+
+struct fixed_capacity_policy : variable_capacity_policy
+{
+ template <typename ContainerType>
+ static bool check_size(boost::type<ContainerType>, std::size_t sz)
+ {
+ return ContainerType::max_size() >= sz;
+ }
+};
+
+struct linked_list_policy : default_policy
+{
+ template <typename ContainerType, typename ValueType>
+ static void
+ set_value(ContainerType& a, std::size_t /*i*/, ValueType const& v)
+ {
+ a.push_back(v);
+ }
+};
+
+struct set_policy : default_policy
+{
+ template <typename ContainerType, typename ValueType>
+ static void
+ set_value(ContainerType& a, std::size_t /*i*/, ValueType const& v)
+ {
+ a.insert(v);
+ }
+};
+
+template <typename ContainerType, typename ConversionPolicy>
+struct from_python_sequence
+{
+ typedef typename ContainerType::value_type container_element_type;
+
+ from_python_sequence()
+ {
+ boost::python::converter::registry::push_back(
+ &convertible,
+ &construct,
+ boost::python::type_id<ContainerType>());
+ }
+
+ static void* convertible(PyObject* obj_ptr)
+ {
+ if (!( PyList_Check(obj_ptr)
+ || PyTuple_Check(obj_ptr)
+ || PyIter_Check(obj_ptr)
+ || PyRange_Check(obj_ptr)
+ || ( !PyString_Check(obj_ptr)
+ && !PyUnicode_Check(obj_ptr)
+ && ( obj_ptr->ob_type == 0
+ || obj_ptr->ob_type->ob_type == 0
+ || obj_ptr->ob_type->ob_type->tp_name == 0
+ || std::strcmp(
+ obj_ptr->ob_type->ob_type->tp_name,
+ "Boost.Python.class") != 0)
+ && PyObject_HasAttrString(obj_ptr, "__len__")
+ && PyObject_HasAttrString(obj_ptr, "__getitem__")))) return 0;
+ boost::python::handle<> obj_iter(
+ boost::python::allow_null(PyObject_GetIter(obj_ptr)));
+ if (!obj_iter.get()) { // must be convertible to an iterator
+ PyErr_Clear();
+ return 0;
+ }
+ if (ConversionPolicy::check_convertibility_per_element()) {
+ int obj_size = int(PyObject_Length(obj_ptr));
+ if (obj_size < 0) { // must be a measurable sequence
+ PyErr_Clear();
+ return 0;
+ }
+ if (!ConversionPolicy::check_size(
+ boost::type<ContainerType>(), obj_size)) return 0;
+ bool is_range = PyRange_Check(obj_ptr);
+ std::size_t i=0;
+ if (!all_elements_convertible(obj_iter, is_range, i)) return 0;
+ if (!is_range) assert(i == (std::size_t)obj_size);
+ }
+ return obj_ptr;
+ }
+
+ // This loop factored out by Achim Domma to avoid Visual C++
+ // Internal Compiler Error.
+ static bool
+ all_elements_convertible(
+ boost::python::handle<>& obj_iter,
+ bool is_range,
+ std::size_t& i)
+ {
+ for(;;i++) {
+ boost::python::handle<> py_elem_hdl(
+ boost::python::allow_null(PyIter_Next(obj_iter.get())));
+ if (PyErr_Occurred()) {
+ PyErr_Clear();
+ return false;
+ }
+ if (!py_elem_hdl.get()) break; // end of iteration
+ boost::python::object py_elem_obj(py_elem_hdl);
+ boost::python::extract<container_element_type>
+ elem_proxy(py_elem_obj);
+ if (!elem_proxy.check()) return false;
+ if (is_range) break; // in a range all elements are of the same type
+ }
+ return true;
+ }
+
+ static void construct(
+ PyObject* obj_ptr,
+ boost::python::converter::rvalue_from_python_stage1_data* data)
+ {
+ boost::python::handle<> obj_iter(PyObject_GetIter(obj_ptr));
+ void* storage = (
+ (boost::python::converter::rvalue_from_python_storage<ContainerType>*)
+ data)->storage.bytes;
+ new (storage) ContainerType();
+ data->convertible = storage;
+ ContainerType& result = *((ContainerType*)storage);
+ std::size_t i=0;
+ for(;;i++) {
+ boost::python::handle<> py_elem_hdl(
+ boost::python::allow_null(PyIter_Next(obj_iter.get())));
+ if (PyErr_Occurred()) boost::python::throw_error_already_set();
+ if (!py_elem_hdl.get()) break; // end of iteration
+ boost::python::object py_elem_obj(py_elem_hdl);
+ boost::python::extract<container_element_type> elem_proxy(py_elem_obj);
+ ConversionPolicy::set_value(result, i, elem_proxy());
+ }
+ ConversionPolicy::assert_size(boost::type<ContainerType>(), i);
+ }
+};
+
+template<class T>
+float deprecatedGet(T& node)
+{
+ throw avg::Exception(AVG_ERR_DEPRECATED, "Attribute has been removed from libavg.");
+}
+
+template<class T>
+void deprecatedSet(T& node, float d)
+{
+ throw avg::Exception(AVG_ERR_DEPRECATED, "Attribute has been removed from libavg.");
+}
+
+namespace Vec2Helper
+{
+ int len(const glm::vec2&);
+ float getX(const glm::vec2& pt);
+ float getY(const glm::vec2& pt);
+ void setX(glm::vec2& pt, float val);
+ void setY(glm::vec2& pt, float val);
+ void checkItemRange(int i);
+ float getItem(const glm::vec2& pt, int i);
+ void setItem(glm::vec2& pt, int i, float val);
+ std::string str(const glm::vec2& pt);
+ std::string repr(const glm::vec2& pt);
+ long getHash(const glm::vec2& pt);
+ glm::vec2 safeGetNormalized(const glm::vec2& pt);
+ float getNorm(const glm::vec2& pt);
+ float vecAngle(const glm::vec2& pt1, const glm::vec2& pt2);
+}
+
+class ConstVec2: public glm::vec2
+{
+public:
+ ConstVec2();
+ ConstVec2(const glm::vec2& other);
+ glm::vec2 toVec2() const;
+ //operator glm::vec2() const;
+};
+
+AVG_API void checkEmptyArgs(const boost::python::tuple &args, int numArgs=1);
+
+template<const char * pszType>
+avg::ExportedObjectPtr createExportedObject(const boost::python::tuple &args,
+ const boost::python::dict &attrs)
+{
+ checkEmptyArgs(args);
+ return avg::TypeRegistry::get()->createObject(pszType, attrs);
+}
+
+template<const char * pszType>
+avg::NodePtr createNode(const boost::python::tuple &args,
+ const boost::python::dict &attrs)
+{
+ checkEmptyArgs(args);
+ return avg::Player::get()->createNode(pszType, attrs, args[0]);
+};
+
+template <typename T>struct Exception_to_python_exception
+{
+ static PyObject* convert (const T& ex)
+ {
+ PyObject *arglist = boost::python::incref(
+ Py_BuildValue("(s)", ex.what()));
+ return boost::python::incref(
+ PyObject_CallObject(PyExc_RuntimeError, arglist));
+ }
+};
+
+
+template<typename T> struct ExceptionTranslator
+{
+public:
+ void operator()(const T& ex) const
+ {
+ PyErr_SetString(m_PyExcept, ex.what());
+ }
+
+ ExceptionTranslator(PyObject* py_except): m_PyExcept(py_except)
+ {
+ boost::python::register_exception_translator<T>(*this);
+ }
+
+ ExceptionTranslator(const ExceptionTranslator& other):m_PyExcept(other.m_PyExcept)
+ {
+ }
+
+ private:
+
+ PyObject* m_PyExcept;
+
+};
+
+template <typename T> void translateException(PyObject* e) {
+ ExceptionTranslator<T> my_translator(e);
+}
+
+void exportMessages(boost::python::object& nodeClass, const std::string& sClassName);
+
+void addPythonLogger(PyObject * self, PyObject * pyLogger);
+void removePythonLogger(PyObject * self, PyObject * pyLogger);
+
+void pytrace(PyObject * self, const avg::category_t& category, const avg::UTF8String& sMsg,
+ avg::severity_t severity);
+
+#endif
diff --git a/src/wrapper/anim_wrap.cpp b/src/wrapper/anim_wrap.cpp
new file mode 100644
index 0000000..0dfadf2
--- /dev/null
+++ b/src/wrapper/anim_wrap.cpp
@@ -0,0 +1,131 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "WrapHelper.h"
+
+#include "../anim/SimpleAnim.h"
+#include "../anim/LinearAnim.h"
+#include "../anim/EaseInOutAnim.h"
+#include "../anim/ContinuousAnim.h"
+#include "../anim/WaitAnim.h"
+#include "../anim/ParallelAnim.h"
+#include "../anim/StateAnim.h"
+
+#include "../player/BoostPython.h"
+
+using namespace boost::python;
+using namespace avg;
+namespace bp = boost::python;
+
+BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(start_overloads, start, 0, 1);
+BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(setState_overloads, StateAnim::setState, 1, 2);
+BOOST_PYTHON_FUNCTION_OVERLOADS(fadeIn_overloads, fadeIn, 2, 4);
+BOOST_PYTHON_FUNCTION_OVERLOADS(fadeOut_overloads, fadeOut, 2, 3);
+
+void export_anim()
+{
+ from_python_sequence<std::vector<AnimPtr>, variable_capacity_policy>();
+ from_python_sequence<std::vector<AnimState>, variable_capacity_policy>();
+
+ def("getNumRunningAnims", AttrAnim::getNumRunningAnims);
+
+ class_<Anim, boost::shared_ptr<Anim>, boost::noncopyable>("Anim", no_init)
+ .def("setStartCallback", &Anim::setStartCallback)
+ .def("setStopCallback", &Anim::setStopCallback)
+ .def("abort", &Anim::abort)
+ .def("isRunning", &Anim::isRunning)
+ ;
+
+ class_<AttrAnim, boost::shared_ptr<AttrAnim>, bases<Anim>, boost::noncopyable>
+ ("AttrAnim", no_init)
+ .def("start", &AttrAnim::start, start_overloads(args("bKeepAttr")))
+ ;
+
+ class_<SimpleAnim, boost::shared_ptr<SimpleAnim>, bases<AttrAnim>,
+ boost::noncopyable>("SimpleAnim", no_init)
+ ;
+
+ class_<LinearAnim, boost::shared_ptr<LinearAnim>, bases<SimpleAnim>,
+ boost::noncopyable>("LinearAnim", no_init)
+ .def(init<const object&, const std::string&, long long, const object&,
+ const object&, optional<bool, const object&, const object&> >
+ ((bp::arg("node"), bp::arg("attrName"), bp::arg("duration"),
+ bp::arg("startValue"), bp::arg("endValue"), bp::arg("useInt")=false,
+ bp::arg("startCallback")=object(), bp::arg("stopCallback")=object())))
+ ;
+
+ class_<EaseInOutAnim, boost::shared_ptr<EaseInOutAnim>, bases<SimpleAnim>,
+ boost::noncopyable>("EaseInOutAnim", no_init)
+ .def(init<const object&, const std::string&, long long, const object&,
+ const object&, long long, long long,
+ optional<bool, const object&, const object&> >
+ ((bp::arg("node"), bp::arg("attrName"), bp::arg("duration"),
+ bp::arg("startValue"), bp::arg("endValue"), bp::arg("easeInDuration"),
+ bp::arg("easeOutDuration"), bp::arg("useInt")=false,
+ bp::arg("startCallback")=object(), bp::arg("stopCallback")=object())))
+ ;
+
+ class_<ContinuousAnim, boost::shared_ptr<ContinuousAnim>, bases<AttrAnim>,
+ boost::noncopyable>("ContinuousAnim", no_init)
+ .def(init<const object&, const std::string&, const object&, const object&,
+ optional<bool, const object&, const object&> >
+ ((bp::arg("node"), bp::arg("attrName"), bp::arg("duration"),
+ bp::arg("startValue"), bp::arg("speed"), bp::arg("useInt")=false,
+ bp::arg("startCallback")=object(), bp::arg("stopCallback")=object())))
+ ;
+
+ class_<WaitAnim, boost::shared_ptr<WaitAnim>, bases<Anim>, boost::noncopyable>(
+ "WaitAnim", no_init)
+ .def(init<optional<long long, const object&, const object&> >
+ ((bp::arg("duration")=-1, bp::arg("startCallback")=object(),
+ bp::arg("stopCallback")=object())))
+ .def("start", &WaitAnim::start, start_overloads(bp::args("bKeepAttr")))
+ ;
+
+ class_<ParallelAnim, boost::shared_ptr<ParallelAnim>, bases<Anim>,
+ boost::noncopyable>("ParallelAnim", no_init)
+ .def(init<const std::vector<AnimPtr>&,
+ optional<const object&, const object&, long long> >
+ ((bp::arg("anims"), bp::arg("startCallback")=object(),
+ bp::arg("stopCallback")=object(), bp::arg("maxAge")=-1)))
+ .def("start", &ParallelAnim::start, start_overloads(args("bKeepAttr")))
+ ;
+
+ class_<AnimState, boost::noncopyable>("AnimState", no_init)
+ .def(init<const std::string&, AnimPtr, optional<const std::string&> >
+ ((bp::arg("name"), bp::arg("anim"), bp::arg("nextName")="")))
+ ;
+
+ class_<StateAnim, boost::shared_ptr<StateAnim>, bases<Anim>,
+ boost::noncopyable>("StateAnim", init<const std::vector<AnimState>&>())
+ .def("setState", &StateAnim::setState, setState_overloads(args("bKeepAttr")))
+ .def("getState", make_function(&StateAnim::getState,
+ return_value_policy<copy_const_reference>()))
+ .def("setDebug", &StateAnim::setDebug)
+ ;
+
+ def("fadeIn", fadeIn, (bp::arg("node"), bp::arg("duration"), bp::arg("max")=1.0,
+ bp::arg("stopCallback")=object()));
+
+ def("fadeOut", fadeOut, (bp::arg("node"), bp::arg("duration"),
+ bp::arg("stopCallback")=object()));
+
+}
diff --git a/src/wrapper/avg_wrap.cpp b/src/wrapper/avg_wrap.cpp
new file mode 100644
index 0000000..acdc525
--- /dev/null
+++ b/src/wrapper/avg_wrap.cpp
@@ -0,0 +1,355 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+void export_base();
+void export_node();
+void export_event();
+void export_anim();
+
+#include "WrapHelper.h"
+#include "raw_constructor.hpp"
+
+#include "../base/Logger.h"
+#include "../base/OSHelper.h"
+#include "../base/GeomHelper.h"
+#include "../base/XMLHelper.h"
+#include "../player/Player.h"
+#include "../player/AVGNode.h"
+#include "../player/DivNode.h"
+#include "../player/TrackerInputDevice.h"
+#include "../player/TouchEvent.h"
+#include "../player/MouseEvent.h"
+#include "../player/TestHelper.h"
+#include "../player/Canvas.h"
+#include "../player/OffscreenCanvas.h"
+#include "../player/VideoWriter.h"
+#include "../player/SVG.h"
+#include "../player/VersionInfo.h"
+#include "../player/ExportedObject.h"
+
+#include <boost/version.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/python/raw_function.hpp>
+
+using namespace boost::python;
+using namespace avg;
+using namespace std;
+
+namespace bp = boost::python;
+
+BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(TestHelper_fakeTouchEvent_overloads,
+ fakeTouchEvent, 4, 5)
+BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(Player_createNode_overloads,
+ createNode, 2, 3)
+
+OffscreenCanvasPtr createCanvas(const boost::python::tuple &args,
+ const boost::python::dict& params)
+{
+ checkEmptyArgs(args, 1);
+ return extract<Player&>(args[0])().createCanvas(params);
+}
+
+CanvasPtr createMainCanvas(const boost::python::tuple &args,
+ const boost::python::dict& params)
+{
+ checkEmptyArgs(args, 1);
+ return extract<Player&>(args[0])().createMainCanvas(params);
+}
+
+class SeverityScopeHelper{};
+class CategoryScopeHelper{};
+
+BOOST_PYTHON_MODULE(avg)
+{
+ try {
+ docstring_options doc_options(true, false);
+
+ Player::get();
+ PyEval_InitThreads();
+ export_base();
+
+ register_ptr_to_python<DivNodePtr>();
+ register_ptr_to_python<CanvasNodePtr>();
+ register_ptr_to_python<AVGNodePtr>();
+ register_ptr_to_python<EventPtr>();
+ register_ptr_to_python<MouseEventPtr>();
+ register_ptr_to_python<TouchEventPtr>();
+
+ def("getMemoryUsage", getMemoryUsage);
+
+ def("pointInPolygon", pointInPolygon);
+ def("validateXml", validateXml);
+
+ class_<MessageID>("MessageID", no_init)
+ .def("__repr__", &MessageID::getRepr)
+ ;
+
+ {
+ scope loggerScope = class_<Logger, boost::noncopyable>("Logger", no_init)
+ .def("addSink", addPythonLogger)
+ .def("removeSink", removePythonLogger)
+ .def("removeStdLogSink", &Logger::removeStdLogSink)
+ .def("configureCategory", &Logger::configureCategory,
+ (bp::arg("severity")=Logger::severity::NONE))
+ .def("getCategories", &Logger::getCategories)
+ .def("trace", pytrace,
+ (bp::arg("severity")=Logger::severity::INFO))
+ .def("debug", &Logger::logDebug,
+ (bp::arg("category")=Logger::category::APP))
+ .def("info", &Logger::logInfo,
+ (bp::arg("category")=Logger::category::APP))
+ .def("warning", &Logger::logWarning,
+ (bp::arg("category")=Logger::category::APP))
+ .def("error", &Logger::logError,
+ (bp::arg("category")=Logger::category::APP))
+ .def("critical", &Logger::logCritical,
+ (bp::arg("category")=Logger::category::APP))
+ .def("log", &Logger::log,
+ (bp::arg("category")=Logger::category::APP,
+ bp::arg("severity")=Logger::severity::INFO))
+ ;
+ {
+ scope severityScope = class_<SeverityScopeHelper>("Severity");
+ severityScope.attr("CRIT") = Logger::severity::CRITICAL;
+ severityScope.attr("ERR") = Logger::severity::ERROR;
+ severityScope.attr("WARN") = Logger::severity::WARNING;
+ severityScope.attr("INFO") = Logger::severity::INFO;
+ severityScope.attr("DBG") = Logger::severity::DEBUG;
+ severityScope.attr("NONE") = Logger::severity::NONE;
+ }
+ {
+ scope categoryScope = class_<CategoryScopeHelper>("Category");
+ categoryScope.attr("APP") = Logger::category::APP;
+ categoryScope.attr("CONFIG") = Logger::category::CONFIG;
+ categoryScope.attr("DEPREC") = Logger::category::DEPRECATION;
+ categoryScope.attr("EVENTS") = Logger::category::EVENTS;
+ categoryScope.attr("MEMORY") = Logger::category::MEMORY;
+ categoryScope.attr("NONE") = Logger::category::NONE;
+ categoryScope.attr("PROFILE") = Logger::category::PROFILE;
+ categoryScope.attr("PROFILE_V") = Logger::category::PROFILE_VIDEO;
+ categoryScope.attr("PLUGIN") = Logger::category::PLUGIN;
+ categoryScope.attr("PLAYER") = Logger::category::PLAYER;
+ categoryScope.attr("SHADER") = Logger::category::SHADER;
+ }
+ }
+
+ scope().attr("logger") = boost::python::ptr(Logger::get());
+
+ class_<ExportedObject, boost::shared_ptr<ExportedObject>, boost::noncopyable>
+ ("ExportedObject", no_init)
+ .def(self == self)
+ .def(self != self)
+ .def("__hash__", &ExportedObject::getHash)
+ ;
+
+ class_<Publisher, bases<ExportedObject>, boost::noncopyable>("Publisher")
+ .def("subscribe", &Publisher::subscribe)
+ .def("unsubscribe", &Publisher::unsubscribeCallable)
+ .def("unsubscribe", &Publisher::unsubscribe)
+ .def("unsubscribe", &Publisher::unsubscribe1)
+ .def("isSubscribed", &Publisher::isSubscribedCallable)
+ .def("isSubscribed", &Publisher::isSubscribed)
+ .def("getNumSubscribers", &Publisher::getNumSubscribers)
+ .def("publish", &Publisher::publish)
+ .def("notifySubscribers", &Publisher::notifySubscribersPy)
+ .def("genMessageID", &Publisher::genMessageID)
+ .staticmethod("genMessageID")
+ ;
+
+ export_event();
+ export_node();
+ export_anim();
+
+ class_<TestHelper>("TestHelper", no_init)
+ .def("fakeMouseEvent", &TestHelper::fakeMouseEvent)
+ .def("fakeTouchEvent", &TestHelper::fakeTouchEvent,
+ TestHelper_fakeTouchEvent_overloads())
+ .def("fakeKeyEvent", &TestHelper::fakeKeyEvent)
+ .def("dumpObjects", &TestHelper::dumpObjects)
+ .def("getObjectCount", &TestHelper::getObjectCount)
+ ;
+
+ enum_<GLConfig::ShaderUsage>("ShaderUsage")
+ .value("SHADERUSAGE_FULL", GLConfig::FULL)
+ .value("SHADERUSAGE_MINIMAL", GLConfig::MINIMAL)
+ .value("SHADERUSAGE_AUTO", GLConfig::AUTO)
+ .export_values()
+ ;
+
+ object playerClass = class_<Player, bases<Publisher>, boost::noncopyable>
+ ("Player")
+ .def("get", &Player::get,
+ return_value_policy<reference_existing_object>())
+ .staticmethod("get")
+ .def("setResolution", &Player::setResolution)
+ .def("isFullscreen", &Player::isFullscreen)
+ .def("setWindowFrame", &Player::setWindowFrame)
+ .def("setWindowPos", &Player::setWindowPos)
+ .def("setWindowTitle", &Player::setWindowTitle)
+ .def("useGLES", &Player::useGLES)
+ .def("setOGLOptions", &Player::setOGLOptions)
+ .def("setMultiSampleSamples", &Player::setMultiSampleSamples)
+ .def("enableGLErrorChecks", &Player::enableGLErrorChecks)
+ .def("getScreenResolution", &Player::getScreenResolution)
+ .def("getPixelsPerMM", &Player::getPixelsPerMM)
+ .def("getPhysicalScreenDimensions", &Player::getPhysicalScreenDimensions)
+ .def("assumePixelsPerMM", &Player::assumePixelsPerMM)
+ .def("loadFile", &Player::loadFile)
+ .def("loadString", &Player::loadString)
+ .def("loadCanvasFile", &Player::loadCanvasFile)
+ .def("loadCanvasString", &Player::loadCanvasString)
+ .def("createMainCanvas", raw_function(createMainCanvas))
+ .def("createCanvas", raw_function(createCanvas))
+ .def("deleteCanvas", &Player::deleteCanvas)
+ .def("getMainCanvas", &Player::getMainCanvas)
+ .def("getCanvas", &Player::getCanvas)
+ .def("play", &Player::play)
+ .def("stop", &Player::stop)
+ .def("isPlaying", &Player::isPlaying)
+ .def("setFramerate", &Player::setFramerate)
+ .def("setVBlankFramerate", &Player::setVBlankFramerate)
+ .def("getEffectiveFramerate", &Player::getEffectiveFramerate)
+ .def("getTestHelper", &Player::getTestHelper,
+ return_value_policy<reference_existing_object>())
+ .def("setFakeFPS", &Player::setFakeFPS)
+ .def("getFrameTime", &Player::getFrameTime)
+ .def("getFrameDuration", &Player::getFrameDuration)
+ .def("createNode", &Player::createNodeFromXmlString)
+ .def("createNode", &Player::createNode, Player_createNode_overloads())
+ .def("enableMultitouch", &Player::enableMultitouch)
+ .def("enableMouse", &Player::enableMouse)
+ .def("isMultitouchAvailable", &Player::isMultitouchAvailable)
+ .def("getTracker", &Player::getTracker,
+ return_value_policy<reference_existing_object>())
+ .def("setInterval", &Player::setInterval)
+ .def("setTimeout", &Player::setTimeout)
+ .def("callFromThread", &Player::callFromThread)
+ .def("setOnFrameHandler", &Player::setOnFrameHandler)
+ .def("clearInterval", &Player::clearInterval)
+ .def("addInputDevice", &Player::addInputDevice)
+ .def("getMouseState", &Player::getMouseState)
+ .def("getCurrentEvent", &Player::getCurrentEvent)
+ .def("getKeyModifierState", &Player::getKeyModifierState)
+ .def("screenshot", &Player::screenshot)
+ .def("keepWindowOpen", &Player::keepWindowOpen)
+ .def("stopOnEscape", &Player::setStopOnEscape)
+ .def("showCursor", &Player::showCursor)
+ .def("isCursorShown", &Player::isCursorShown)
+ .def("setCursor", &Player::setCursor)
+ .def("getElementByID", &Player::getElementByID)
+ .def("getRootNode", &Player::getRootNode)
+ .def("getFramerate", &Player::getFramerate)
+ .def("getVideoRefreshRate", &Player::getVideoRefreshRate)
+ .def("getVideoMemInstalled", &Player::getVideoMemInstalled)
+ .def("getVideoMemUsed", &Player::getVideoMemUsed)
+ .def("setGamma", &Player::setGamma)
+ .def("setMousePos", &Player::setMousePos)
+ .def("loadPlugin", &Player::loadPlugin)
+ .def("setEventHook", &Player::setEventHook)
+ .def("getEventHook", &Player::getEventHook)
+ .def("getConfigOption", &Player::getConfigOption)
+ .def("isUsingGLES", &Player::isUsingGLES)
+ .def("areFullShadersSupported", &Player::areFullShadersSupported)
+ .add_property("pluginPath", &Player::getPluginPath, &Player::setPluginPath)
+ .add_property("volume", &Player::getVolume, &Player::setVolume)
+ ;
+ exportMessages(playerClass, "Player");
+
+ class_<Canvas, boost::shared_ptr<Canvas>, bases<ExportedObject>,
+ boost::noncopyable>("Canvas", no_init)
+ .def("getRootNode", &Canvas::getRootNode)
+ .def("getElementByID", &Canvas::getElementByID)
+ .def("screenshot", &Canvas::screenshot)
+ ;
+
+ class_<OffscreenCanvas, boost::shared_ptr<OffscreenCanvas>, bases<Canvas>,
+ boost::noncopyable>("OffscreenCanvas", no_init)
+ .def("getID", &OffscreenCanvas::getID)
+ .def("render", &OffscreenCanvas::manualRender)
+ .def("registerCameraNode", &OffscreenCanvas::registerCameraNode)
+ .def("unregisterCameraNode", &OffscreenCanvas::unregisterCameraNode)
+ .add_property("handleevents", &OffscreenCanvas::getHandleEvents)
+ .add_property("multisamplesamples", &OffscreenCanvas::getMultiSampleSamples)
+ .add_property("mipmap", &OffscreenCanvas::getMipmap)
+ .add_property("autorender", &OffscreenCanvas::getAutoRender,
+ &OffscreenCanvas::setAutoRender)
+ .def("getNumDependentCanvases", &OffscreenCanvas::getNumDependentCanvases)
+ .def("isSupported", &OffscreenCanvas::isSupported)
+ .staticmethod("isSupported")
+ .def("isMultisampleSupported", &OffscreenCanvas::isMultisampleSupported)
+ .staticmethod("isMultisampleSupported")
+ ;
+
+ class_<VideoWriter, boost::shared_ptr<VideoWriter>, boost::noncopyable>
+ ("VideoWriter", no_init)
+ .def(init<CanvasPtr, const std::string&, int, int, int, bool>())
+ .def(init<CanvasPtr, const std::string&, int, int, int>())
+ .def(init<CanvasPtr, const std::string&, int>())
+ .def("stop", &VideoWriter::stop)
+ .def("pause", &VideoWriter::pause)
+ .def("play", &VideoWriter::play)
+ .add_property("filename", &VideoWriter::getFileName)
+ .add_property("framerate", &VideoWriter::getFramerate)
+ .add_property("qmin", &VideoWriter::getQMin)
+ .add_property("qmax", &VideoWriter::getQMax)
+ ;
+
+ BitmapPtr (SVG::*renderElement1)(const UTF8String&) = &SVG::renderElement;
+ BitmapPtr (SVG::*renderElement2)(const UTF8String&, const glm::vec2&) =
+ &SVG::renderElement;
+ BitmapPtr (SVG::*renderElement3)(const UTF8String&, float) =
+ &SVG::renderElement;
+ NodePtr (SVG::*createImageNode1)(const UTF8String&, const dict&) =
+ &SVG::createImageNode;
+ NodePtr (SVG::*createImageNode2)(const UTF8String&, const dict&, const glm::vec2&) =
+ &SVG::createImageNode;
+ NodePtr (SVG::*createImageNode3)(const UTF8String&, const dict&, float) =
+ &SVG::createImageNode;
+
+ class_<SVG, boost::noncopyable>("SVG", no_init)
+ .def(init<const UTF8String&>())
+ .def(init<const UTF8String&, bool>())
+ .def("renderElement", renderElement1)
+ .def("renderElement", renderElement2)
+ .def("renderElement", renderElement3)
+ .def("createImageNode", createImageNode1)
+ .def("createImageNode", createImageNode2)
+ .def("createImageNode", createImageNode3)
+ .def("getElementPos", &SVG::getElementPos)
+ .def("getElementSize", &SVG::getElementSize)
+ ;
+
+ class_<VersionInfo>("VersionInfo")
+ .add_property("full", &VersionInfo::getFull)
+ .add_property("release", &VersionInfo::getRelease)
+ .add_property("major", &VersionInfo::getMajor)
+ .add_property("minor", &VersionInfo::getMinor)
+ .add_property("micro", &VersionInfo::getMicro)
+ .add_property("revision", &VersionInfo::getRevision)
+ .add_property("branchurl", &VersionInfo::getBranchUrl)
+ .add_property("builder", &VersionInfo::getBuilder)
+ .add_property("buildtime", &VersionInfo::getBuildTime)
+ ;
+ } catch (const exception& e) {
+ PyErr_SetString(PyExc_RuntimeError, e.what());
+ throw error_already_set();
+ }
+}
diff --git a/src/wrapper/bitmap_wrap.cpp b/src/wrapper/bitmap_wrap.cpp
new file mode 100644
index 0000000..5f86fb9
--- /dev/null
+++ b/src/wrapper/bitmap_wrap.cpp
@@ -0,0 +1,207 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "WrapHelper.h"
+
+#include "../player/BoostPython.h"
+#include "../player/BitmapManager.h"
+
+#include "../graphics/Bitmap.h"
+#include "../graphics/BitmapLoader.h"
+#include "../graphics/FilterResizeBilinear.h"
+
+#include "../base/CubicSpline.h"
+
+#include "../glm/gtx/vector_angle.hpp"
+
+#include <vector>
+#include <sstream>
+
+using namespace boost::python;
+using namespace std;
+using namespace avg;
+
+template<class POINT>
+class_<POINT> export_point(const string& sName)
+{
+ return class_<POINT>(sName.c_str(), no_init)
+ .def("__len__", &Vec2Helper::len)
+ .def("__getitem__", &Vec2Helper::getItem)
+ .def("__str__", &Vec2Helper::str)
+ .def("__repr__", &Vec2Helper::repr)
+ .def("__hash__", &Vec2Helper::getHash)
+ .def("getNormalized", &Vec2Helper::safeGetNormalized)
+ .def("getNorm", &Vec2Helper::getNorm)
+ .def("getRotated", &getRotated)
+ .def("getRotated", &getRotatedPivot)
+ .def(self == self)
+ .def(self != self)
+ .def(-self)
+ .def(self + self)
+ .def(self - self)
+ .def(float() * self)
+ .def(self * float())
+ .def(self / float())
+ .def("getAngle", &getAngle)
+ .def("fromPolar", &fromPolar)
+ .staticmethod("fromPolar")
+ .def("angle", &Vec2Helper::vecAngle)
+ .staticmethod("angle")
+ ;
+}
+
+struct Pixel32_to_python_tuple
+{
+ static PyObject* convert (avg::Pixel32 px)
+ {
+ return boost::python::incref(boost::python::make_tuple(
+ px.getR(), px.getG(), px.getB(), px.getA()).ptr());
+ }
+};
+
+ConstVec2 Bitmap_getSize(Bitmap* This)
+{
+ return (glm::vec2)(This->getSize());
+}
+
+BitmapPtr Bitmap_getResized(BitmapPtr This, const glm::vec2& size)
+{
+ return FilterResizeBilinear(IntPoint(size)).apply(This);
+}
+
+glm::vec2* createPoint()
+{
+ return new glm::vec2(0,0);
+}
+
+BitmapPtr createBitmapFromFile(const UTF8String& sFName)
+{
+ return loadBitmap(sFName);
+}
+
+BitmapPtr createBitmapWithRect(BitmapPtr pBmp,
+ const glm::vec2& tlPos, const glm::vec2& brPos)
+{
+ if (tlPos.x >= brPos.x || tlPos.y >= brPos.y) {
+ throw Exception(AVG_ERR_OUT_OF_RANGE,
+ "Can't create a bitmap with zero or negative width/height.");
+ }
+ IntPoint size = pBmp->getSize();
+ if (tlPos.x < 0 || tlPos.y < 0 || brPos.x > size.x || brPos.y > size.y) {
+ throw Exception(AVG_ERR_OUT_OF_RANGE,
+ "Attempt to create a subbitmap that doesn't fit into the parent bitmap.");
+ }
+ IntRect rect = IntRect(IntPoint(tlPos), IntPoint(brPos));
+ return BitmapPtr(new Bitmap(*pBmp, rect));
+}
+
+BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(loadBitmap_overloads, BitmapManager::loadBitmapPy,
+ 2, 3);
+
+void export_bitmap()
+{
+ export_point<glm::vec2>("Point2D")
+ .def("__init__", make_constructor(createPoint))
+ .def(init<float, float>())
+ .def(init<const glm::vec2&>())
+ .def("__setitem__", &Vec2Helper::setItem)
+ .add_property("x", &Vec2Helper::getX, &Vec2Helper::setX,"")
+ .add_property("y", &Vec2Helper::getY, &Vec2Helper::setY,"")
+ ;
+
+ export_point<ConstVec2>("ConstPoint2D")
+ .add_property("x", &Vec2Helper::getX, "")
+ .add_property("y", &Vec2Helper::getY, "")
+ ;
+
+ implicitly_convertible<ConstVec2, glm::vec2>();
+ implicitly_convertible<glm::vec2, ConstVec2>();
+
+ enum_<PixelFormat>("pixelformat")
+ .value("B5G6R5", B5G6R5)
+ .value("B8G8R8", B8G8R8)
+ .value("B8G8R8A8", B8G8R8A8)
+ .value("B8G8R8X8", B8G8R8X8)
+ .value("A8B8G8R8", A8B8G8R8)
+ .value("X8B8G8R8", X8B8G8R8)
+ .value("R5G6B5", R5G6B5)
+ .value("R8G8B8", R8G8B8)
+ .value("R8G8B8A8", R8G8B8A8)
+ .value("R8G8B8X8", R8G8B8X8)
+ .value("A8R8G8B8", A8R8G8B8)
+ .value("X8R8G8B8", X8R8G8B8)
+ .value("I8", I8)
+ .value("I16", I16)
+ .value("A8", A8)
+ .value("YCbCr411", YCbCr411)
+ .value("YCbCr422", YCbCr422)
+ .value("YUYV422", YUYV422)
+ .value("YCbCr420p", YCbCr420p)
+ .value("YCbCrJ420p", YCbCrJ420p)
+ .value("YCbCrA420p", YCbCrA420p)
+ .value("BAYER8", BAYER8)
+ .value("BAYER8_RGGB", BAYER8_RGGB)
+ .value("BAYER8_GBRG", BAYER8_GBRG)
+ .value("BAYER8_GRBG", BAYER8_GRBG)
+ .value("BAYER8_BGGR", BAYER8_BGGR)
+ .value("R32G32B32A32F", R32G32B32A32F)
+ .value("I32F", I32F)
+ .export_values();
+
+ def("getSupportedPixelFormats", &getSupportedPixelFormats);
+
+ to_python_converter<Pixel32, Pixel32_to_python_tuple>();
+
+ class_<Bitmap, boost::shared_ptr<Bitmap> >("Bitmap", no_init)
+ .def(init<glm::vec2, PixelFormat, UTF8String>())
+ .def(init<Bitmap>())
+ .def("__init__", make_constructor(createBitmapWithRect))
+ .def("__init__", make_constructor(createBitmapFromFile))
+ .def("blt", &Bitmap::blt)
+ .def("getResized", &Bitmap_getResized)
+ .def("save", &Bitmap::save)
+ .def("getSize", &Bitmap_getSize)
+ .def("getFormat", &Bitmap::getPixelFormat)
+ .def("getPixels", &Bitmap::getPixelsAsString)
+ .def("setPixels", &Bitmap::setPixelsFromString)
+ .def("getPixel", &Bitmap::getPythonPixel)
+ .def("subtract", &Bitmap::subtract)
+ .def("getAvg", &Bitmap::getAvg)
+ .def("getChannelAvg", &Bitmap::getChannelAvg)
+ .def("getStdDev", &Bitmap::getStdDev)
+ .def("getName", &Bitmap::getName,
+ return_value_policy<copy_const_reference>())
+ ;
+
+ class_<BitmapManager>("BitmapManager", no_init)
+ .def("get", &BitmapManager::get,
+ return_value_policy<reference_existing_object>())
+ .staticmethod("get")
+ .def("loadBitmap", &BitmapManager::loadBitmapPy, loadBitmap_overloads())
+ .def("setNumThreads", &BitmapManager::setNumThreads)
+ ;
+
+ class_<CubicSpline, boost::noncopyable>("CubicSpline", no_init)
+ .def(init<const vector<glm::vec2>&>())
+ .def(init<const vector<glm::vec2>&, bool>())
+ .def("interpolate", &CubicSpline::interpolate)
+ ;
+}
diff --git a/src/wrapper/event_wrap.cpp b/src/wrapper/event_wrap.cpp
new file mode 100644
index 0000000..3b0dfba
--- /dev/null
+++ b/src/wrapper/event_wrap.cpp
@@ -0,0 +1,251 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "WrapHelper.h"
+
+#include "../player/KeyEvent.h"
+#include "../player/MouseEvent.h"
+#include "../player/TouchEvent.h"
+#include "../player/Contact.h"
+#include "../player/TrackerInputDevice.h"
+#include "../player/Publisher.h"
+
+#include <boost/shared_ptr.hpp>
+#include <string>
+
+using namespace boost::python;
+using namespace avg;
+using namespace std;
+
+
+class IInputDeviceWrapper : public IInputDevice, public wrapper<IInputDevice>
+{
+ public:
+ IInputDeviceWrapper(const std::string& name,
+ const DivNodePtr& pEventReceiverNode=DivNodePtr())
+ : IInputDevice(name, pEventReceiverNode)
+ {
+ }
+
+ IInputDeviceWrapper(const IInputDevice& inputDevice)
+ : IInputDevice(inputDevice)
+ {
+ }
+
+ virtual void start()
+ {
+ override startMethod = this->get_override("start");
+ if (startMethod) {
+ startMethod();
+ }
+ IInputDevice::start();
+ }
+
+ void default_start()
+ {
+ return this->IInputDevice::start();
+ }
+
+ virtual std::vector<EventPtr> pollEvents()
+ {
+ return this->get_override("pollEvents")();
+ }
+
+};
+
+void export_event()
+{
+ boost::python::to_python_converter<vector<TouchEventPtr>,
+ to_tuple<vector<TouchEventPtr> > >();
+ boost::python::to_python_converter<vector<CursorEventPtr>,
+ to_tuple<vector<CursorEventPtr> > >();
+
+ boost::python::to_python_converter<ContourSeq, to_list<ContourSeq> >();
+
+ from_python_sequence<ContourSeq, variable_capacity_policy>();
+ from_python_sequence<vector<EventPtr>, variable_capacity_policy>();
+
+ enum_<int>("KeyModifier")
+ .value("KEYMOD_NONE", key::KEYMOD_NONE)
+ .value("KEYMOD_LSHIFT", key::KEYMOD_LSHIFT)
+ .value("KEYMOD_RSHIFT", key::KEYMOD_RSHIFT)
+ .value("KEYMOD_LCTRL", key::KEYMOD_LCTRL)
+ .value("KEYMOD_RCTRL", key::KEYMOD_RCTRL)
+ .value("KEYMOD_LALT", key::KEYMOD_LALT)
+ .value("KEYMOD_RALT", key::KEYMOD_RALT)
+ .value("KEYMOD_LMETA", key::KEYMOD_LMETA)
+ .value("KEYMOD_RMETA", key::KEYMOD_RMETA)
+ .value("KEYMOD_NUM", key::KEYMOD_NUM)
+ .value("KEYMOD_CAPS", key::KEYMOD_CAPS)
+ .value("KEYMOD_MODE", key::KEYMOD_MODE)
+ .value("KEYMOD_RESERVED", key::KEYMOD_RESERVED)
+ .value("KEYMOD_CTRL", key::KEYMOD_CTRL)
+ .value("KEYMOD_SHIFT", key::KEYMOD_SHIFT)
+ .value("KEYMOD_ALT", key::KEYMOD_ALT)
+ .value("KEYMOD_META", key::KEYMOD_META)
+ .export_values()
+ ;
+
+ scope mainScope;
+
+ scope eventScope = class_<Event, boost::noncopyable>("Event", init<Event::Type,
+ Event::Source, optional<int> >())
+ .add_property("type", &Event::getType)
+ .add_property("source", &Event::getSource)
+ .add_property("when", &Event::getWhen)
+ .add_property("inputdevice", &Event::getInputDevice)
+ .add_property("inputdevicename", make_function(&Event::getInputDeviceName,
+ return_value_policy<copy_const_reference>()))
+ ;
+
+ enum_<Event::Type>("Type")
+ .value("KEY_UP", Event::KEY_UP)
+ .value("KEY_DOWN", Event::KEY_DOWN)
+ .value("CURSOR_MOTION", Event::CURSOR_MOTION)
+ .value("CURSOR_UP", Event::CURSOR_UP)
+ .value("CURSOR_DOWN", Event::CURSOR_DOWN)
+ .value("CURSOR_OVER", Event::CURSOR_OVER)
+ .value("CURSOR_OUT", Event::CURSOR_OUT)
+ .value("CUSTOM_EVENT", Event::CUSTOM_EVENT)
+ .export_values()
+ ;
+
+ enum_<CursorEvent::Source>("Source")
+ .value("MOUSE", CursorEvent::MOUSE)
+ .value("TOUCH", CursorEvent::TOUCH)
+ .value("TRACK", CursorEvent::TRACK)
+ .value("CUSTOM", Event::CUSTOM)
+ .value("NONE", Event::NONE)
+ .export_values()
+ ;
+
+ scope oldScope1(mainScope);
+
+ class_<CursorEvent, boost::shared_ptr<CursorEvent>, bases<Event> >("CursorEvent",
+ no_init)
+ .add_property("source", &CursorEvent::getSource)
+ .add_property("pos", &CursorEvent::getPos)
+ .add_property("x", &CursorEvent::getXPosition)
+ .add_property("y", &CursorEvent::getYPosition)
+ .add_property("cursorid", &CursorEvent::getCursorID, &CursorEvent::setCursorID)
+ .add_property("node", &CursorEvent::getNode)
+ .add_property("speed", make_function(&CursorEvent::getSpeed,
+ return_value_policy<copy_const_reference>()))
+ .add_property("contact", &CursorEvent::getContact)
+ ;
+
+ class_<KeyEvent, bases<Event> >("KeyEvent", no_init)
+ .add_property("scancode", &KeyEvent::getScanCode)
+ .add_property("keycode", &KeyEvent::getKeyCode)
+ .add_property("keystring", make_function(&KeyEvent::getKeyString,
+ return_value_policy<copy_const_reference>()))
+ .add_property("unicode", &KeyEvent::getUnicode)
+ .add_property("modifiers", &KeyEvent::getModifiers)
+ ;
+
+ class_<MouseEvent, bases<CursorEvent> >("MouseEvent",
+ init<Event::Type, bool, bool, bool, const IntPoint&, int,
+ optional<const glm::vec2&, int> >())
+ .add_property("leftbuttonstate", &MouseEvent::getLeftButtonState)
+ .add_property("middlebuttonstate", &MouseEvent::getMiddleButtonState)
+ .add_property("rightbuttonstate", &MouseEvent::getRightButtonState)
+ .add_property("button", &MouseEvent::getButton)
+ ;
+
+ class_<TouchEvent, bases<CursorEvent> >("TouchEvent", init<int, Event::Type,
+ const IntPoint&, Event::Source, optional<const glm::vec2&> >())
+ .add_property("area", &TouchEvent::getArea)
+ .add_property("orientation", &TouchEvent::getOrientation)
+ .add_property("eccentricity", &TouchEvent::getEccentricity)
+ .add_property("center", make_function(&TouchEvent::getCenter,
+ return_value_policy<copy_const_reference>()))
+ .add_property("majoraxis", make_function(&TouchEvent::getMajorAxis,
+ return_value_policy<copy_const_reference>()))
+ .add_property("minoraxis", make_function(&TouchEvent::getMinorAxis,
+ return_value_policy<copy_const_reference>()))
+ .add_property("handorientation", &TouchEvent::getHandOrientation)
+ .def("getRelatedEvents", &TouchEvent::getRelatedEvents)
+ .def("getContour", &TouchEvent::getContour)
+ ;
+
+ object contactClass = class_<Contact, boost::shared_ptr<Contact>, bases<Publisher> >
+ ("Contact", no_init)
+ .add_property("id", &Contact::getID)
+ .add_property("age", &Contact::getAge)
+ .add_property("distancefromstart", &Contact::getDistanceFromStart)
+ .add_property("motionangle", &Contact::getMotionAngle)
+ .add_property("motionvec", &Contact::getMotionVec)
+ .add_property("distancetravelled", &Contact::getDistanceTravelled)
+ .add_property("events", &Contact::getEvents)
+ .def("connectListener", &Contact::connectListener)
+ .def("disconnectListener", &Contact::disconnectListener)
+ ;
+ exportMessages(contactClass, "Contact");
+
+ enum_<TrackerImageID>("TrackerImageID")
+ .value("IMG_CAMERA", TRACKER_IMG_CAMERA)
+ .value("IMG_DISTORTED", TRACKER_IMG_DISTORTED)
+ .value("IMG_NOHISTORY", TRACKER_IMG_NOHISTORY)
+ .value("IMG_HISTOGRAM", TRACKER_IMG_HISTOGRAM)
+ .value("IMG_FINGERS", TRACKER_IMG_FINGERS)
+ .value("IMG_HIGHPASS", TRACKER_IMG_HIGHPASS)
+ .export_values()
+ ;
+
+ class_<IInputDevicePtr>("IInputDevice")
+ ;
+
+ class_< IInputDeviceWrapper,
+ boost::shared_ptr<IInputDeviceWrapper>,
+ boost::noncopyable
+ >("InputDevice", init<const std::string&, optional<const DivNodePtr&> >())
+ .def("start", &IInputDevice::start, &IInputDeviceWrapper::default_start)
+ .def("pollEvents", pure_virtual(&IInputDevice::pollEvents))
+ .add_property("name",
+ make_function(&IInputDevice::getName,
+ return_value_policy<copy_const_reference>()))
+ .add_property("eventreceivernode",
+ make_function(&IInputDevice::getEventReceiverNode,
+ return_value_policy<copy_const_reference>()))
+ ;
+
+ class_<TrackerInputDevice, boost::noncopyable>("Tracker", no_init)
+ .def("getImage", &TrackerInputDevice::getImage,
+ return_value_policy<manage_new_object>())
+ .def("getDisplayROIPos", &TrackerInputDevice::getDisplayROIPos)
+ .def("getDisplayROISize", &TrackerInputDevice::getDisplayROISize)
+ .def("saveConfig", &TrackerInputDevice::saveConfig)
+ .def("resetHistory", &TrackerInputDevice::resetHistory)
+ .def("setDebugImages", &TrackerInputDevice::setDebugImages)
+ .def("startCalibration", &TrackerInputDevice::startCalibration,
+ return_value_policy<reference_existing_object>())
+ .def("endCalibration", &TrackerInputDevice::endCalibration)
+ .def("abortCalibration", &TrackerInputDevice::abortCalibration)
+ .def("setParam", &TrackerInputDevice::setParam)
+ .def("getParam", &TrackerInputDevice::getParam)
+ ;
+
+ class_<TrackerCalibrator, boost::noncopyable>("TrackerCalibrator", no_init)
+ .def("nextPoint", &TrackerCalibrator::nextPoint)
+ .def("getDisplayPoint", &TrackerCalibrator::getDisplayPoint)
+ .def("setCamPoint", &TrackerCalibrator::setCamPoint)
+ ;
+}
diff --git a/src/wrapper/fx_wrap.cpp b/src/wrapper/fx_wrap.cpp
new file mode 100644
index 0000000..b3e2ca8
--- /dev/null
+++ b/src/wrapper/fx_wrap.cpp
@@ -0,0 +1,100 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "WrapHelper.h"
+#include "raw_constructor.hpp"
+
+#include "../player/BlurFXNode.h"
+#include "../player/ChromaKeyFXNode.h"
+#include "../player/FXNode.h"
+#include "../player/HueSatFXNode.h"
+#include "../player/InvertFXNode.h"
+#include "../player/NullFXNode.h"
+#include "../player/ShadowFXNode.h"
+
+#include <boost/shared_ptr.hpp>
+
+using namespace boost::python;
+using namespace avg;
+
+void export_fx()
+{
+
+ class_<FXNode, boost::shared_ptr<FXNode>, boost::noncopyable>("FXNode", no_init)
+ ;
+
+ class_<BlurFXNode, bases<FXNode>, boost::shared_ptr<BlurFXNode>,
+ boost::noncopyable>("BlurFXNode", init<optional<float> >())
+ .add_property("radius", &BlurFXNode::getRadius,
+ &BlurFXNode::setRadius)
+ ;
+
+ class_<ChromaKeyFXNode, bases<FXNode>, boost::shared_ptr<ChromaKeyFXNode>,
+ boost::noncopyable>("ChromaKeyFXNode")
+ .add_property("color",
+ make_function(&ChromaKeyFXNode::getColor,
+ return_value_policy<copy_const_reference>()),
+ &ChromaKeyFXNode::setColor)
+ .add_property("htolerance", &ChromaKeyFXNode::getHTolerance,
+ &ChromaKeyFXNode::setHTolerance)
+ .add_property("stolerance", &ChromaKeyFXNode::getSTolerance,
+ &ChromaKeyFXNode::setSTolerance)
+ .add_property("ltolerance", &ChromaKeyFXNode::getLTolerance,
+ &ChromaKeyFXNode::setLTolerance)
+ .add_property("softness", &ChromaKeyFXNode::getSoftness,
+ &ChromaKeyFXNode::setSoftness)
+ .add_property("erosion", &ChromaKeyFXNode::getErosion,
+ &ChromaKeyFXNode::setErosion)
+ .add_property("spillthreshold", &ChromaKeyFXNode::getSpillThreshold,
+ &ChromaKeyFXNode::setSpillThreshold)
+ ;
+
+ class_<HueSatFXNode, bases<FXNode>, boost::shared_ptr<HueSatFXNode>,
+ boost::noncopyable > ("HueSatFXNode", init<optional<float, float, float,
+ bool> >())
+ .add_property("hue", &HueSatFXNode::getHue,
+ &HueSatFXNode::setHue)
+ .add_property("saturation", &HueSatFXNode::getSaturation,
+ &HueSatFXNode::setSaturation)
+ .add_property("lightness", &HueSatFXNode::getLightnessOffset,
+ &HueSatFXNode::setLightnessOffset)
+ .add_property("colorize", &HueSatFXNode::isColorizing,
+ &HueSatFXNode::setColorizing)
+ .def("__repr__", &HueSatFXNode::toString)
+ ;
+
+ class_<InvertFXNode, bases<FXNode>, boost::shared_ptr<InvertFXNode>,
+ boost::noncopyable>("InvertFXNode")
+ ;
+
+ class_<NullFXNode, bases<FXNode>, boost::shared_ptr<NullFXNode>, boost::noncopyable>(
+ "NullFXNode")
+ ;
+
+ class_<ShadowFXNode, bases<FXNode>, boost::shared_ptr<ShadowFXNode>,
+ boost::noncopyable>("ShadowFXNode",
+ init<optional<glm::vec2, float, float, std::string> >())
+ .add_property("offset", &ShadowFXNode::getOffset, &ShadowFXNode::setOffset)
+ .add_property("radius", &ShadowFXNode::getRadius, &ShadowFXNode::setRadius)
+ .add_property("opacity", &ShadowFXNode::getOpacity, &ShadowFXNode::setOpacity)
+ .add_property("color", &ShadowFXNode::getColor, &ShadowFXNode::setColor)
+ ;
+}
diff --git a/src/wrapper/node_wrap.cpp b/src/wrapper/node_wrap.cpp
new file mode 100644
index 0000000..46ce021
--- /dev/null
+++ b/src/wrapper/node_wrap.cpp
@@ -0,0 +1,333 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+void export_bitmap();
+void export_fx();
+void export_raster();
+void export_event();
+#ifndef WIN32
+void export_devices();
+#endif
+
+#include "WrapHelper.h"
+#include "raw_constructor.hpp"
+
+#include "../base/Logger.h"
+#include "../base/Exception.h"
+#include "../player/Player.h"
+#include "../player/AVGNode.h"
+#include "../player/CanvasNode.h"
+#include "../player/DivNode.h"
+#include "../player/SoundNode.h"
+#include "../player/LineNode.h"
+#include "../player/RectNode.h"
+#include "../player/CurveNode.h"
+#include "../player/PolyLineNode.h"
+#include "../player/PolygonNode.h"
+#include "../player/CircleNode.h"
+#include "../player/MeshNode.h"
+
+#include <boost/version.hpp>
+#include <boost/shared_ptr.hpp>
+#include <string>
+
+using namespace boost::python;
+using namespace avg;
+using namespace std;
+
+BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(unlink_overloads, Node::unlink, 0, 1);
+BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(disconnectEventHandler_overloads,
+ Node::disconnectEventHandler, 1, 2);
+
+// These function templates essentially call functions such as AreaNode::getPos()
+// and return a version of the result that don't allow setting of the individual
+// elements of the vec2 returned.
+// Without this stuff, python code like node.pos.x=30 would fail silently. With it,
+// it at least throws an exception.
+template<class CLASS, const glm::vec2& (CLASS::*FUNC)() const>
+ConstVec2 constPointGetterRef(const CLASS& node)
+{
+ return (node.*FUNC)();
+}
+
+template<class CLASS, glm::vec2 (CLASS::*FUNC)() const>
+ConstVec2 constPointGetter(const CLASS& node)
+{
+ return (node.*FUNC)();
+}
+
+ConstVec2 AreaNode_getMediaSize(AreaNode* This)
+{
+ return (glm::vec2)(This->getMediaSize());
+}
+
+char divNodeName[] = "div";
+char avgNodeName[] = "avg";
+char soundNodeName[] = "sound";
+char panoImageNodeName[] = "panoimage";
+char lineNodeName[] = "line";
+char rectNodeName[] = "rect";
+char curveNodeName[] = "curve";
+char polylineNodeName[] = "polyline";
+char polygonNodeName[] = "polygon";
+char circleNodeName[] = "circle";
+char meshNodeName[] = "mesh";
+
+void export_node()
+{
+ // vector< vector<vec2> > PolygonNode
+ to_python_converter<VectorVec2Vector, to_list<VectorVec2Vector> >();
+ from_python_sequence<VectorVec2Vector, variable_capacity_policy>();
+
+ object nodeClass = class_<Node, boost::shared_ptr<Node>, bases<Publisher>,
+ boost::noncopyable>("Node", no_init)
+ .add_property("id", make_function(&Node::getID,
+ return_value_policy<copy_const_reference>()), &Node::setID)
+ .def("registerInstance", &Node::registerInstance)
+ .def("getParent", &Node::getParent)
+ .def("unlink", &Node::unlink, unlink_overloads(args("bKill")))
+ .def("setEventCapture", &Node::setMouseEventCapture)
+ .def("setEventCapture", &Node::setEventCapture)
+ .def("releaseEventCapture", &Node::releaseMouseEventCapture)
+ .def("releaseEventCapture", &Node::releaseEventCapture)
+ .def("setEventHandler", &Node::setEventHandler)
+ .def("connectEventHandler", &Node::connectEventHandler)
+ .def("disconnectEventHandler", &Node::disconnectEventHandler,
+ disconnectEventHandler_overloads(args("pFunc")))
+ .def("getAbsPos", &Node::getAbsPos)
+ .def("getRelPos", &Node::getRelPos)
+ .def("getElementByPos", &Node::getElementByPos)
+ .add_property("parent", &Node::getParent)
+ .add_property("active", &Node::getActive, &Node::setActive)
+ .add_property("sensitive", &Node::getSensitive, &Node::setSensitive)
+ .add_property("opacity", &Node::getOpacity, &Node::setOpacity)
+ ;
+ exportMessages(nodeClass, "Node");
+
+ class_<AreaNode, boost::shared_ptr<AreaNode>, bases<Node>,
+ boost::noncopyable>("AreaNode", no_init)
+ .def("getMediaSize", &AreaNode_getMediaSize)
+ .add_property("x", &AreaNode::getX, &AreaNode::setX)
+ .add_property("y", &AreaNode::getY, &AreaNode::setY)
+ .add_property("pos", &constPointGetterRef<AreaNode, &AreaNode::getPos>,
+ &AreaNode::setPos)
+ .add_property("width", &AreaNode::getWidth, &AreaNode::setWidth)
+ .add_property("height", &AreaNode::getHeight, &AreaNode::setHeight)
+ .add_property("angle", &AreaNode::getAngle, &AreaNode::setAngle)
+ .add_property("size", &constPointGetter<AreaNode, &AreaNode::getSize>,
+ &AreaNode::setSize)
+ .add_property("pivot", &constPointGetter<AreaNode, &AreaNode::getPivot>,
+ &AreaNode::setPivot)
+ .add_property("pivotx", &deprecatedGet<AreaNode>, &deprecatedSet<AreaNode>)
+ .add_property("pivoty", &deprecatedGet<AreaNode>, &deprecatedSet<AreaNode>)
+ .add_property("elementoutlinecolor",
+ make_function(&AreaNode::getElementOutlineColor,
+ return_value_policy<copy_const_reference>()),
+ make_function(&AreaNode::setElementOutlineColor,
+ return_value_policy<copy_const_reference>()))
+ ;
+
+ export_bitmap();
+ export_fx();
+ export_raster();
+
+ class_<DivNode, bases<AreaNode>, boost::noncopyable>("DivNode", no_init)
+ .def("__init__", raw_constructor(createNode<divNodeName>))
+ .add_property("crop", &DivNode::getCrop, &DivNode::setCrop)
+ .def("getNumChildren", &DivNode::getNumChildren)
+ .def("getChild", make_function(&DivNode::getChild,
+ return_value_policy<copy_const_reference>()))
+ .def("appendChild", &DivNode::appendChild)
+ .def("insertChildBefore", &DivNode::insertChildBefore)
+ .def("insertChildAfter", &DivNode::insertChildAfter)
+ .def("insertChild", &DivNode::insertChild)
+ .def("removeChild", (void (DivNode::*)(NodePtr))(&DivNode::removeChild))
+ .def("removeChild", (void (DivNode::*)(unsigned))(&DivNode::removeChild))
+ .def("reorderChild", (void (DivNode::*)(unsigned, unsigned))
+ (&DivNode::reorderChild))
+ .def("reorderChild", (void (DivNode::*)(NodePtr, unsigned))
+ (&DivNode::reorderChild))
+ .def("indexOf", &DivNode::indexOf)
+ .def("getEffectiveMediaDir", &DivNode::getEffectiveMediaDir)
+ .add_property("mediadir", make_function(&DivNode::getMediaDir,
+ return_value_policy<copy_const_reference>()), &DivNode::setMediaDir)
+ ;
+
+ class_<CanvasNode, bases<DivNode> >("CanvasNode",
+ no_init)
+ ;
+
+ class_<AVGNode, bases<CanvasNode> >("AVGNode", no_init)
+ ;
+
+ class_<SoundNode, bases<AreaNode> >("SoundNode", no_init)
+ .def("__init__", raw_constructor(createNode<soundNodeName>))
+ .def("play", &SoundNode::play)
+ .def("stop", &SoundNode::stop)
+ .def("pause", &SoundNode::pause)
+ .def("setEOFCallback", &SoundNode::setEOFCallback)
+ .def("getAudioCodec", &SoundNode::getAudioCodec)
+ .def("getAudioSampleRate", &SoundNode::getAudioSampleRate)
+ .def("getNumAudioChannels", &SoundNode::getNumAudioChannels)
+ .def("seekToTime", &SoundNode::seekToTime)
+ .def("getCurTime", &SoundNode::getCurTime)
+ .add_property("href", make_function(&SoundNode::getHRef,
+ return_value_policy<copy_const_reference>()), &SoundNode::setHRef)
+ .add_property("loop", &SoundNode::getLoop)
+ .add_property("duration", &SoundNode::getDuration)
+ .add_property("volume", &SoundNode::getVolume, &SoundNode::setVolume)
+ ;
+
+ class_<VectorNode, bases<Node>, boost::noncopyable>("VectorNode",
+ no_init)
+ .add_property("strokewidth", &VectorNode::getStrokeWidth,
+ &VectorNode::setStrokeWidth)
+ .add_property("color", make_function(&VectorNode::getColor,
+ return_value_policy<copy_const_reference>()), &VectorNode::setColor)
+ .add_property("texhref", make_function(&VectorNode::getTexHRef,
+ return_value_policy<copy_const_reference>()), &VectorNode::setTexHRef)
+ .add_property("blendmode",
+ make_function(&VectorNode::getBlendModeStr,
+ return_value_policy<copy_const_reference>()),
+ &VectorNode::setBlendModeStr)
+ .def("setBitmap", &VectorNode::setBitmap)
+ ;
+
+ class_<FilledVectorNode, bases<VectorNode>, boost::noncopyable>("FilledVectorNode",
+ no_init)
+ .add_property("filltexhref", make_function(&FilledVectorNode::getFillTexHRef,
+ return_value_policy<copy_const_reference>()),
+ &FilledVectorNode::setFillTexHRef)
+ .add_property("fillcolor", make_function(&FilledVectorNode::getFillColor,
+ return_value_policy<copy_const_reference>()),
+ &FilledVectorNode::setFillColor)
+ .add_property("fillopacity", &FilledVectorNode::getFillOpacity,
+ &FilledVectorNode::setFillOpacity)
+ .add_property("filltexcoord1", make_function(&FilledVectorNode::getFillTexCoord1,
+ return_value_policy<copy_const_reference>()),
+ &FilledVectorNode::setFillTexCoord1)
+ .add_property("filltexcoord2", make_function(&FilledVectorNode::getFillTexCoord2,
+ return_value_policy<copy_const_reference>()),
+ &FilledVectorNode::setFillTexCoord2)
+ .def("setFillBitmap", &FilledVectorNode::setFillBitmap)
+ ;
+
+ class_<LineNode, bases<VectorNode>, boost::noncopyable>("LineNode",
+ no_init)
+ .def("__init__", raw_constructor(createNode<lineNodeName>))
+ .add_property("pos1", &constPointGetterRef<LineNode, &LineNode::getPos1>,
+ &LineNode::setPos1)
+ .add_property("pos2", &constPointGetterRef<LineNode, &LineNode::getPos2>,
+ &LineNode::setPos2)
+ .add_property("x1", &deprecatedGet<LineNode>, &deprecatedSet<LineNode>)
+ .add_property("y1", &deprecatedGet<LineNode>, &deprecatedSet<LineNode>)
+ .add_property("x2", &deprecatedGet<LineNode>, &deprecatedSet<LineNode>)
+ .add_property("y2", &deprecatedGet<LineNode>, &deprecatedSet<LineNode>)
+ .add_property("texcoord1", &LineNode::getTexCoord1, &LineNode::setTexCoord1)
+ .add_property("texcoord2", &LineNode::getTexCoord2, &LineNode::setTexCoord2)
+ ;
+
+ class_<RectNode, bases<FilledVectorNode>, boost::noncopyable>("RectNode",
+ no_init)
+ .def("__init__", raw_constructor(createNode<rectNodeName>))
+ .add_property("pos", &constPointGetterRef<RectNode, &RectNode::getPos>,
+ &RectNode::setPos)
+ .add_property("size", &constPointGetter<RectNode, &RectNode::getSize>,
+ &RectNode::setSize)
+ .add_property("x", &deprecatedGet<RectNode>, &deprecatedSet<RectNode>)
+ .add_property("y", &deprecatedGet<RectNode>, &deprecatedSet<RectNode>)
+ .add_property("width", &deprecatedGet<RectNode>, &deprecatedSet<RectNode>)
+ .add_property("height", &deprecatedGet<RectNode>, &deprecatedSet<RectNode>)
+ .add_property("texcoords", make_function(&RectNode::getTexCoords,
+ return_value_policy<copy_const_reference>()), &RectNode::setTexCoords)
+ .add_property("angle", &RectNode::getAngle, &RectNode::setAngle)
+ ;
+
+ class_<CurveNode, bases<VectorNode>, boost::noncopyable>("CurveNode",
+ no_init)
+ .def("__init__", raw_constructor(createNode<curveNodeName>))
+ .add_property("pos1", &constPointGetterRef<CurveNode, &CurveNode::getPos1>,
+ &CurveNode::setPos1)
+ .add_property("pos2", &constPointGetterRef<CurveNode, &CurveNode::getPos2>,
+ &CurveNode::setPos2)
+ .add_property("pos3", &constPointGetterRef<CurveNode, &CurveNode::getPos3>,
+ &CurveNode::setPos3)
+ .add_property("pos4", &constPointGetterRef<CurveNode, &CurveNode::getPos4>,
+ &CurveNode::setPos4)
+ .add_property("x1", &deprecatedGet<CurveNode>, &deprecatedSet<CurveNode>)
+ .add_property("y1", &deprecatedGet<CurveNode>, &deprecatedSet<CurveNode>)
+ .add_property("x2", &deprecatedGet<CurveNode>, &deprecatedSet<CurveNode>)
+ .add_property("y2", &deprecatedGet<CurveNode>, &deprecatedSet<CurveNode>)
+ .add_property("x3", &deprecatedGet<CurveNode>, &deprecatedSet<CurveNode>)
+ .add_property("y3", &deprecatedGet<CurveNode>, &deprecatedSet<CurveNode>)
+ .add_property("x4", &deprecatedGet<CurveNode>, &deprecatedSet<CurveNode>)
+ .add_property("y4", &deprecatedGet<CurveNode>, &deprecatedSet<CurveNode>)
+ .add_property("texcoord1", &CurveNode::getTexCoord1, &CurveNode::setTexCoord1)
+ .add_property("texcoord2", &CurveNode::getTexCoord2, &CurveNode::setTexCoord2)
+ .add_property("length", &CurveNode::getCurveLen)
+ .def("getPtOnCurve", &CurveNode::getPtOnCurve)
+ ;
+
+ class_<PolyLineNode, bases<VectorNode>, boost::noncopyable>("PolyLineNode", no_init)
+ .def("__init__", raw_constructor(createNode<polylineNodeName>))
+ .add_property("pos", make_function(&PolyLineNode::getPos,
+ return_value_policy<copy_const_reference>()), &PolyLineNode::setPos)
+ .add_property("texcoords", make_function(&PolyLineNode::getTexCoords,
+ return_value_policy<copy_const_reference>()), &PolyLineNode::setTexCoords)
+ .add_property("linejoin", &PolyLineNode::getLineJoin, &PolyLineNode::setLineJoin)
+ ;
+
+ class_<PolygonNode, bases<FilledVectorNode>, boost::noncopyable>("PolygonNode",
+ no_init)
+ .def("__init__", raw_constructor(createNode<polygonNodeName>))
+ .add_property("pos", make_function(&PolygonNode::getPos,
+ return_value_policy<copy_const_reference>()), &PolygonNode::setPos)
+ .add_property("texcoords", make_function(&PolygonNode::getTexCoords,
+ return_value_policy<copy_const_reference>()), &PolygonNode::setTexCoords)
+ .add_property("linejoin", &PolygonNode::getLineJoin, &PolygonNode::setLineJoin)
+ .add_property("holes", make_function(&PolygonNode::getHoles,
+ return_value_policy<copy_const_reference>()), &PolygonNode::setHoles)
+ ;
+
+ class_<CircleNode, bases<FilledVectorNode>, boost::noncopyable>("CircleNode",
+ no_init)
+ .def("__init__", raw_constructor(createNode<circleNodeName>))
+ .add_property("pos", &constPointGetterRef<CircleNode, &CircleNode::getPos>,
+ &CircleNode::setPos)
+ .add_property("x", &deprecatedGet<CircleNode>, &deprecatedSet<CircleNode>)
+ .add_property("y", &deprecatedGet<CircleNode>, &deprecatedSet<CircleNode>)
+ .add_property("r", &CircleNode::getR, &CircleNode::setR)
+ .add_property("texcoord1", &CircleNode::getTexCoord1, &CircleNode::setTexCoord1)
+ .add_property("texcoord2", &CircleNode::getTexCoord2, &CircleNode::setTexCoord2)
+ ;
+
+ class_<MeshNode, bases<VectorNode>, boost::noncopyable>("MeshNode", no_init)
+ .def("__init__", raw_constructor(createNode<meshNodeName>))
+ .add_property("vertexcoords", make_function(&MeshNode::getVertexCoords,
+ return_value_policy<copy_const_reference>()), &MeshNode::setVertexCoords)
+ .add_property("texcoords", make_function(&MeshNode::getTexCoords,
+ return_value_policy<copy_const_reference>()), &MeshNode::setTexCoords)
+ .add_property("triangles", make_function(&MeshNode::getTriangles,
+ return_value_policy<copy_const_reference>()), &MeshNode::setTriangles)
+ .add_property("backfacecull", &MeshNode::getBackfaceCull, &MeshNode::setBackfaceCull)
+ ;
+
+}
diff --git a/src/wrapper/raster_wrap.cpp b/src/wrapper/raster_wrap.cpp
new file mode 100644
index 0000000..c0cdebb
--- /dev/null
+++ b/src/wrapper/raster_wrap.cpp
@@ -0,0 +1,279 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "WrapHelper.h"
+#include "raw_constructor.hpp"
+
+#include "../player/CameraNode.h"
+#include "../player/ImageNode.h"
+#include "../player/VideoNode.h"
+#include "../player/FontStyle.h"
+#include "../player/WordsNode.h"
+
+using namespace boost::python;
+using namespace avg;
+using namespace std;
+
+char imageNodeName[] = "image";
+char cameraNodeName[] = "camera";
+char videoNodeName[] = "video";
+char fontStyleName[] = "fontstyle";
+char wordsNodeName[] = "words";
+
+void export_raster()
+{
+
+ class_<RasterNode, bases<AreaNode>, boost::noncopyable>("RasterNode", no_init)
+ .def("getOrigVertexCoords", &RasterNode::getOrigVertexCoords)
+ .def("getWarpedVertexCoords", &RasterNode::getWarpedVertexCoords)
+ .def("setWarpedVertexCoords", &RasterNode::setWarpedVertexCoords)
+ .def("setEffect", &RasterNode::setEffect)
+ .add_property("maxtilewidth", &RasterNode::getMaxTileWidth)
+ .add_property("maxtileheight", &RasterNode::getMaxTileHeight)
+ .add_property("blendmode",
+ make_function(&RasterNode::getBlendModeStr,
+ return_value_policy<copy_const_reference>()),
+ &RasterNode::setBlendModeStr)
+ .add_property("maskhref",
+ make_function(&RasterNode::getMaskHRef,
+ return_value_policy<copy_const_reference>()),
+ &RasterNode::setMaskHRef)
+ .add_property("maskpos",
+ make_function(&RasterNode::getMaskPos,
+ return_value_policy<copy_const_reference>()),
+ &RasterNode::setMaskPos)
+ .add_property("masksize",
+ make_function(&RasterNode::getMaskSize,
+ return_value_policy<copy_const_reference>()),
+ &RasterNode::setMaskSize)
+ .add_property("mipmap", &RasterNode::getMipmap)
+ .add_property("gamma", &RasterNode::getGamma, &RasterNode::setGamma)
+ .add_property("intensity", &RasterNode::getIntensity, &RasterNode::setIntensity)
+ .add_property("contrast", &RasterNode::getContrast, &RasterNode::setContrast)
+ ;
+
+ class_<ImageNode, bases<RasterNode> >("ImageNode", no_init)
+ .def("__init__", raw_constructor(createNode<imageNodeName>))
+ .def("getBitmap", &ImageNode::getBitmap)
+ .def("setBitmap", &ImageNode::setBitmap)
+ .add_property("href",
+ make_function(&ImageNode::getHRef,
+ return_value_policy<copy_const_reference>()),
+ &ImageNode::setHRef)
+ .add_property("compression",
+ &ImageNode::getCompression)
+ ;
+
+ class_<CameraNode, bases<RasterNode> >("CameraNode", no_init)
+ .def("__init__", raw_constructor(createNode<cameraNodeName>))
+ .add_property("device", make_function(&CameraNode::getDevice,
+ return_value_policy<copy_const_reference>()))
+ .add_property("driver", make_function(&CameraNode::getDriverName,
+ return_value_policy<copy_const_reference>()))
+ .add_property("framerate", &CameraNode::getFrameRate)
+ .add_property("framenum", &CameraNode::getFrameNum)
+ .add_property("brightness", &CameraNode::getBrightness,
+ &CameraNode::setBrightness)
+ .add_property("sharpness", &CameraNode::getSharpness, &CameraNode::setSharpness)
+ .add_property("saturation", &CameraNode::getSaturation,
+ &CameraNode::setSaturation)
+ .add_property("camgamma", &CameraNode::getCamGamma, &CameraNode::setCamGamma)
+ .add_property("shutter", &CameraNode::getShutter, &CameraNode::setShutter)
+ .add_property("gain", &CameraNode::getGain, &CameraNode::setGain)
+ .add_property("strobeduration", &CameraNode::getStrobeDuration,
+ &CameraNode::setStrobeDuration)
+ .def("play", &CameraNode::play)
+ .def("stop", &CameraNode::stop)
+ .def("getBitmap", &CameraNode::getBitmap)
+ .def("getWhitebalanceU", &CameraNode::getWhitebalanceU)
+ .def("getWhitebalanceV", &CameraNode::getWhitebalanceV)
+ .def("setWhitebalance", &CameraNode::setWhitebalance)
+ .def("doOneShotWhitebalance", &CameraNode::doOneShotWhitebalance)
+ .def("isAvailable", &CameraNode::isAvailable)
+ .def("getCamerasInfos", make_function(&CameraNode::getCamerasInfos))
+ .staticmethod("getCamerasInfos")
+ .def("resetFirewireBus", &CameraNode::resetFirewireBus)
+ .staticmethod("resetFirewireBus")
+ ;
+
+ //Wrap std::vector from CameraInfo to Pyhton list
+ to_python_converter<CamerasInfosVector, to_list<CamerasInfosVector> >();
+ from_python_sequence<CamerasInfosVector, variable_capacity_policy>();
+
+ to_python_converter<CameraImageFormatsVector, to_list<CameraImageFormatsVector> >();
+ from_python_sequence<CameraImageFormatsVector, variable_capacity_policy>();
+
+ to_python_converter<CameraControlsVector, to_list<CameraControlsVector> >();
+ from_python_sequence<CameraControlsVector, variable_capacity_policy>();
+
+ to_python_converter<FrameratesVector, to_list<FrameratesVector> >();
+ from_python_sequence<FrameratesVector, variable_capacity_policy>();
+
+ class_<CameraImageFormat>("CameraImageFormat", no_init)
+ .add_property("size", &CameraImageFormat::getSize)
+ .add_property("pixelFormat", &CameraImageFormat::getPixelFormat)
+ .add_property("framerates", &CameraImageFormat::getFramerates)
+ ;
+
+ class_<CameraControl>("CameraControl", no_init)
+ .add_property("controlName", &CameraControl::getControlName)
+ .add_property("min", &CameraControl::getMin)
+ .add_property("max", &CameraControl::getMax)
+ .add_property("default", &CameraControl::getDefault)
+ ;
+
+ class_<CameraInfo>("CameraInfo", no_init)
+ .add_property("driver", &CameraInfo::getDriver)
+ .add_property("deviceID", &CameraInfo::getDeviceID)
+ .add_property("imageFormats", &CameraInfo::getImageFormats)
+ .add_property("controls", &CameraInfo::getControls)
+ ;
+
+ enum_<VideoNode::VideoAccelType>("VideoAccelType")
+ .value("NO_ACCELERATION", VideoNode::NONE)
+ .value("VDPAU", VideoNode::VDPAU)
+ .export_values()
+ ;
+
+ class_<VideoNode, bases<RasterNode> >("VideoNode", no_init)
+ .def("__init__", raw_constructor(createNode<videoNodeName>))
+ .def("play", &VideoNode::play)
+ .def("stop", &VideoNode::stop)
+ .def("pause", &VideoNode::pause)
+ .def("getNumFrames", &VideoNode::getNumFrames)
+ .def("getNumFramesQueued", &VideoNode::getNumFramesQueued)
+ .def("getCurFrame", &VideoNode::getCurFrame)
+ .def("seekToFrame", &VideoNode::seekToFrame)
+ .def("getStreamPixelFormat", &VideoNode::getStreamPixelFormat)
+ .def("getDuration", &VideoNode::getDuration)
+ .def("getVideoDuration", &VideoNode::getVideoDuration)
+ .def("getAudioDuration", &VideoNode::getAudioDuration)
+ .def("getBitrate", &VideoNode::getBitrate)
+ .def("getContainerFormat", &VideoNode::getContainerFormat)
+ .def("getVideoCodec", &VideoNode::getVideoCodec)
+ .def("getAudioCodec", &VideoNode::getAudioCodec)
+ .def("getAudioSampleRate", &VideoNode::getAudioSampleRate)
+ .def("getNumAudioChannels", &VideoNode::getNumAudioChannels)
+ .def("getCurTime", &VideoNode::getCurTime)
+ .def("seekToTime", &VideoNode::seekToTime)
+ .def("hasAudio", &VideoNode::hasAudio)
+ .def("hasAlpha", &VideoNode::hasAlpha)
+ .def("setEOFCallback", &VideoNode::setEOFCallback)
+ .def("getVideoAccelConfig", &VideoNode::getVideoAccelConfig)
+ .staticmethod("getVideoAccelConfig")
+ .add_property("fps", &VideoNode::getFPS)
+ .add_property("queuelength", &VideoNode::getQueueLength)
+ .add_property("href",
+ make_function(&VideoNode::getHRef,
+ return_value_policy<copy_const_reference>()),
+ &VideoNode::setHRef)
+ .add_property("loop", &VideoNode::getLoop)
+ .add_property("volume", &VideoNode::getVolume, &VideoNode::setVolume)
+ .add_property("threaded", &VideoNode::isThreaded)
+ .add_property("accelerated", &VideoNode::isAccelerated)
+ ;
+
+ class_<FontStyle, bases<ExportedObject> >("FontStyle", no_init)
+ .def("__init__", raw_constructor(createExportedObject<fontStyleName>))
+ .def("__copy__", copyObject<FontStyle>)
+ .add_property("font",
+ make_function(&FontStyle::getFont,
+ return_value_policy<copy_const_reference>()),
+ make_function(&FontStyle::setFont,
+ return_value_policy<copy_const_reference>()))
+ .add_property("variant",
+ make_function(&FontStyle::getFontVariant,
+ return_value_policy<copy_const_reference>()),
+ make_function(&FontStyle::setFontVariant,
+ return_value_policy<copy_const_reference>()))
+ .add_property("color",
+ make_function(&FontStyle::getColor,
+ return_value_policy<copy_const_reference>()),
+ make_function(&FontStyle::setColor,
+ return_value_policy<copy_const_reference>()))
+ .add_property("aagamma", &FontStyle::getAAGamma, &FontStyle::setAAGamma)
+ .add_property("fontsize", &FontStyle::getFontSize, &FontStyle::setFontSize)
+ .add_property("indent", &FontStyle::getIndent, &FontStyle::setIndent)
+ .add_property("linespacing", &FontStyle::getLineSpacing,
+ &FontStyle::setLineSpacing)
+ .add_property("alignment", &FontStyle::getAlignment, &FontStyle::setAlignment)
+ .add_property("wrapmode", &FontStyle::getWrapMode, &FontStyle::setWrapMode)
+ .add_property("justify", &FontStyle::getJustify, &FontStyle::setJustify)
+ .add_property("letterspacing", &FontStyle::getLetterSpacing,
+ &FontStyle::setLetterSpacing)
+ .add_property("hint", &FontStyle::getHint, &FontStyle::setHint)
+ ;
+
+ class_<WordsNode, bases<RasterNode> >("WordsNode", no_init)
+ .def("__init__", raw_constructor(createNode<wordsNodeName>))
+ .add_property("fontstyle",
+ make_function(&WordsNode::getFontStyle,
+ return_value_policy<copy_const_reference>()),
+ &WordsNode::setFontStyle)
+ .add_property("font",
+ make_function(&WordsNode::getFont,
+ return_value_policy<copy_const_reference>()),
+ make_function(&WordsNode::setFont,
+ return_value_policy<copy_const_reference>()))
+ .add_property("variant",
+ make_function(&WordsNode::getFontVariant,
+ return_value_policy<copy_const_reference>()),
+ make_function(&WordsNode::setFontVariant,
+ return_value_policy<copy_const_reference>()))
+ .add_property("text",
+ make_function(&WordsNode::getText,
+ return_value_policy<copy_const_reference>()),
+ &WordsNode::setText)
+ .add_property("color",
+ make_function(&WordsNode::getColor,
+ return_value_policy<copy_const_reference>()),
+ make_function(&WordsNode::setColor,
+ return_value_policy<copy_const_reference>()))
+ .add_property("aagamma", &WordsNode::getAAGamma, &WordsNode::setAAGamma)
+ .add_property("fontsize", &WordsNode::getFontSize, &WordsNode::setFontSize)
+ .add_property("parawidth", &deprecatedGet<WordsNode>, &deprecatedSet<WordsNode>)
+ .add_property("indent", &WordsNode::getIndent, &WordsNode::setIndent)
+ .add_property("linespacing", &WordsNode::getLineSpacing,
+ &WordsNode::setLineSpacing)
+ .add_property("alignment", &WordsNode::getAlignment, &WordsNode::setAlignment)
+ .add_property("wrapmode", &WordsNode::getWrapMode, &WordsNode::setWrapMode)
+ .add_property("justify", &WordsNode::getJustify, &WordsNode::setJustify)
+ .add_property("rawtextmode", &WordsNode::getRawTextMode,
+ &WordsNode::setRawTextMode)
+ .add_property("letterspacing", &WordsNode::getLetterSpacing,
+ &WordsNode::setLetterSpacing)
+ .add_property("hint", &WordsNode::getHint, &WordsNode::setHint)
+ .def("getGlyphPos", &WordsNode::getGlyphPos)
+ .def("getGlyphSize", &WordsNode::getGlyphSize)
+ .def("getNumLines", &WordsNode::getNumLines)
+ .def("getCharIndexFromPos", &WordsNode::getCharIndexFromPos)
+ .def("getTextAsDisplayed", &WordsNode::getTextAsDisplayed)
+ .def("getLineExtents", &WordsNode::getLineExtents)
+ .def("getFontFamilies", make_function(&WordsNode::getFontFamilies,
+ return_value_policy<copy_const_reference>()))
+ .staticmethod("getFontFamilies")
+ .def("getFontVariants", make_function(&WordsNode::getFontVariants,
+ return_value_policy<copy_const_reference>()))
+ .staticmethod("getFontVariants")
+ .def("addFontDir", &WordsNode::addFontDir)
+ .staticmethod("addFontDir")
+ ;
+}
diff --git a/src/wrapper/raw_constructor.hpp b/src/wrapper/raw_constructor.hpp
new file mode 100644
index 0000000..69ee9ba
--- /dev/null
+++ b/src/wrapper/raw_constructor.hpp
@@ -0,0 +1,61 @@
+// Original code by Hans Meine <meine <at> kogs1.informatik.uni-hamburg.de>:
+// Subject: Re: Raw constructor (i.e. combination of make_constructor and raw_function)
+// Newsgroups: gmane.comp.python.c++
+// Date: 2005-11-17 18:43:48 GMT
+// No copyright statement found. Presumed to be in the public domain.
+
+#ifndef RAW_CONSTRUCTOR_HPP
+#define RAW_CONSTRUCTOR_HPP
+
+#include <boost/python.hpp>
+#include <boost/python/raw_function.hpp>
+#include <boost/python/make_constructor.hpp>
+#include "boost/python/detail/api_placeholder.hpp" // python::len
+
+namespace boost { namespace python {
+
+namespace detail {
+
+ template <class F>
+ struct raw_constructor_dispatcher
+ {
+ raw_constructor_dispatcher(F f)
+ : f(make_constructor(f)) {}
+
+ PyObject* operator()(PyObject* args, PyObject* keywords)
+ {
+ borrowed_reference_t* ra = borrowed_reference(args);
+ object a(ra);
+ return incref(
+ object(
+ f(
+ object(a[0])
+ , object(a.slice(0, len(a)))
+ , keywords ? dict(borrowed_reference(keywords)) : dict()
+ )
+ ).ptr()
+ );
+ }
+
+ private:
+ object f;
+ };
+
+} // namespace detail
+
+template <class F>
+object raw_constructor(F f, int min_args = 0)
+{
+ return detail::make_raw_function(
+ objects::py_function(
+ detail::raw_constructor_dispatcher<F>(f)
+ , mpl::vector2<void, object>()
+ , min_args+1
+ , (std::numeric_limits<unsigned>::max)()
+ )
+ );
+}
+
+}} // namespace boost::python
+
+#endif // RAW_CONSTRUCTOR_HPP
diff --git a/updateMessages.sh b/updateMessages.sh
new file mode 100755
index 0000000..4f12e33
--- /dev/null
+++ b/updateMessages.sh
@@ -0,0 +1,34 @@
+#!/bin/bash
+# Replaces old message enums with new ones.
+
+sed -i 's/avg.KEYUP/avg.Event.KEY_UP/g' *.py
+sed -i 's/avg.KEYDOWN/avg.Event.KEY_DOWN/g' *.py
+sed -i 's/avg.CURSORMOTION/avg.Event.CURSOR_MOTION/g' *.py
+sed -i 's/avg.CURSORUP/avg.Event.CURSOR_UP/g' *.py
+sed -i 's/avg.CURSORDOWN/avg.Event.CURSOR_DOWN/g' *.py
+sed -i 's/avg.CURSOROVER/avg.Event.CURSOR_OVER/g' *.py
+sed -i 's/avg.CURSOROUT/avg.Event.CURSOR_OUT/g' *.py
+
+sed -i 's/avg.MOUSE/avg.Event.MOUSE/g' *.py
+sed -i 's/avg.TOUCH/avg.Event.TOUCH/g' *.py
+sed -i 's/avg.TRACK/avg.Event.TRACK/g' *.py
+sed -i 's/avg.CUSTOM/avg.Event.CUSTOM/g' *.py
+sed -i 's/avg.NONE/avg.Event.NONE/g' *.py
+
+# Changes internal to libui-branch
+sed -i 's/avg.Player.KEYUP/avg.Player.KEY_UP/g' *.py
+sed -i 's/avg.Player.KEYDOWN/avg.Player.KEY_DOWN/g' *.py
+sed -i 's/avg.Player.PLAYBACKSTART/avg.Player.PLAYBACK_START/g' *.py
+sed -i 's/avg.Player.PLAYBACKEND/avg.Player.PLAYBACK_END/g' *.py
+
+sed -i 's/avg.Node.CURSORMOTION/avg.Node.CURSOR_MOTION/g' *.py
+sed -i 's/avg.Node.CURSORUP/avg.Node.CURSOR_UP/g' *.py
+sed -i 's/avg.Node.CURSORDOWN/avg.Node.CURSOR_DOWN/g' *.py
+sed -i 's/avg.Node.HOVERMOTION/avg.Node.HOVER_MOTION/g' *.py
+sed -i 's/avg.Node.HOVERUP/avg.Node.HOVER_UP/g' *.py
+sed -i 's/avg.Node.HOVERDOWN/avg.Node.HOVER_DOWN/g' *.py
+sed -i 's/avg.Node.ENDOFFILE/avg.Node.END_OF_FILE/g' *.py
+
+sed -i 's/avg.Contact.CURSORMOTION/avg.Contact.CURSOR_MOTION/g' *.py
+sed -i 's/avg.Contact.CURSORUP/avg.Contact.CURSOR_UP/g' *.py
+
diff --git a/valgrind.cmdline b/valgrind.cmdline
new file mode 100644
index 0000000..19c50fb
--- /dev/null
+++ b/valgrind.cmdline
@@ -0,0 +1 @@
+valgrind --sim-hints=lax-ioctls leak-check=full --suppressions=../../valgrind.suppressions --suppressions=/usr/lib/valgrind/python.supp --smc-check=all --num-callers=25 --leak-resolution=high --gen-suppressions=yes python Test.py player
diff --git a/valgrind.suppressions b/valgrind.suppressions
new file mode 100644
index 0000000..0f75d51
--- /dev/null
+++ b/valgrind.suppressions
@@ -0,0 +1,808 @@
+{
+ GL_Errors_0
+ Memcheck:Cond
+ obj:/usr/lib/nvidia-current/libnvidia-glcore.so.*
+}
+{
+ GL_Errors_0
+ Memcheck:Cond
+ obj:/usr/lib/libGLcore.so.*
+}
+{
+ GL_Errors_1
+ Memcheck:Param
+ ioctl(generic)
+ obj:/lib/ld-2.*.so
+ obj:/usr/lib/libGLcore.so.*
+}
+{
+ GL_Leak_0
+ Memcheck:Leak
+ fun:malloc
+ obj:/usr/lib/libGL.so.*
+}
+{
+ GL_Leak_1
+ Memcheck:Leak
+ fun:malloc
+ fun:realloc
+ obj:/usr/lib/libGL.so.*
+}
+{
+ GL_Leak_2
+ Memcheck:Leak
+ fun:calloc
+ obj:/lib/tls/i686/cmov/libdl-2.*.so
+ fun:dlopen
+ obj:/usr/lib/libGL.so.*
+}
+{
+ GL_Leak_3
+ Memcheck:Leak
+ fun:malloc
+ fun:_XReply
+ obj:/usr/lib/libGL.so.*
+}
+{
+ GL_Leak_4
+ Memcheck:Leak
+ fun:malloc
+ obj:/lib/ld-2.*.so
+ obj:/lib/ld-2.*.so
+ obj:/lib/ld-2.*.so
+ obj:/lib/ld-2.*.so
+ obj:/lib/tls/i686/cmov/libdl-2.*.so
+ obj:/lib/ld-2.*.so
+ obj:/lib/tls/i686/cmov/libdl-2.*.so
+ fun:dlopen
+ obj:/usr/lib/libGL.so.*
+}
+{
+ GL_Leak_5
+ Memcheck:Leak
+ fun:realloc
+ obj:/usr/lib/libGL.so.*
+}
+{
+ GL_Leak_6
+ Memcheck:Leak
+ fun:calloc
+ obj:/usr/lib/libGL.so.*
+ fun:_ZN3avg17OGLImagingContextC1ERKNS_5PointIiEE
+ fun:main
+}
+{
+ GL_Leak_7
+ Memcheck:Leak
+ fun:malloc
+ obj:/lib/ld-2.*.so
+ obj:/lib/ld-2.*.so
+ obj:/lib/ld-2.*.so
+ obj:/lib/ld-2.*.so
+ obj:/lib/ld-2.*.so
+ obj:/lib/tls/i686/cmov/libdl-2.*.so
+ obj:/lib/ld-2.*.so
+ obj:/lib/tls/i686/cmov/libdl-2.*.so
+ fun:dlopen
+ obj:/usr/lib/libGL.so.*
+}
+{
+ GL_Leak_8
+ Memcheck:Leak
+ fun:malloc
+ obj:/lib/ld-2.*.so
+ obj:/lib/ld-2.*.so
+ obj:/lib/ld-2.*.so
+ obj:/lib/ld-2.*.so
+ obj:/lib/ld-2.*.so
+ obj:/lib/ld-2.*.so
+ obj:/lib/tls/i686/cmov/libdl-2.*.so
+ obj:/lib/ld-2.*.so
+ obj:/lib/tls/i686/cmov/libdl-2.*.so
+ fun:dlopen
+ obj:/usr/lib/libGL.so.*
+}
+{
+ GL_Leak_9
+ Memcheck:Leak
+ fun:calloc
+ obj:/lib/ld-2.*.so
+ obj:/lib/ld-2.*.so
+ obj:/lib/ld-2.*.so
+ obj:/lib/ld-2.*.so
+ obj:/lib/tls/i686/cmov/libdl-2.*.so
+ obj:/lib/ld-2.*.so
+ obj:/lib/tls/i686/cmov/libdl-2.*.so
+ fun:dlopen
+ obj:/usr/lib/libGL.so.*
+}
+{
+ GL_Leak_10
+ Memcheck:Leak
+ fun:calloc
+ obj:/lib/ld-2.*.so
+ obj:/lib/ld-2.*.so
+ obj:/lib/ld-2.*.so
+ obj:/lib/ld-2.*.so
+ obj:/lib/ld-2.*.so
+ obj:/lib/ld-2.*.so
+ obj:/lib/tls/i686/cmov/libdl-2.*.so
+ obj:/lib/ld-2.*.so
+ obj:/lib/tls/i686/cmov/libdl-2.*.so
+ fun:dlopen
+ obj:/usr/lib/libGL.so.*
+}
+{
+ getProcAddress
+ Memcheck:Addr4
+ obj:/lib/ld-2.*.so
+ obj:/lib/tls/i686/cmov/libc-2.*.so
+ fun:_dl_sym
+ obj:/lib/tls/i686/cmov/libdl-2.*.so
+ obj:/lib/ld-2.*.so
+ obj:/lib/tls/i686/cmov/libdl-2.*.so
+ fun:dlsym
+ fun:_ZN3avg14getProcAddressERKSs
+ fun:_ZN3avg19getFuzzyProcAddressEPKc
+ fun:_ZN3avg6glproc4initEv
+}
+{
+ VertexArray_appendPos
+ Memcheck:Cond
+ fun:_ZN3avg11VertexArray9appendPosERKNS_5PointIdEES4_RKNS_7Pixel32E
+}
+{
+ VertexArray_BufferCache_0
+ Memcheck:Leak
+ fun:_Znwj
+ fun:_ZNSt6vectorIPvSaIS0_EE14_M_fill_insertEN9__gnu_cxx17__normal_iteratorIPS0_S2_EEjRKS0_
+ fun:_ZN5boost6detail3tss3setEPv
+ fun:_ZN5boost19thread_specific_ptrISt6vectorIjSaIjEEE5resetEPS3_
+ fun:_ZN3avg11VertexArray15initBufferCacheEv
+}
+{
+ VertexArray_BufferCache_1
+ Memcheck:Leak
+ fun:_Znwj
+ fun:_ZNSt6vectorIPN5boost9function1IvPvSaINS0_13function_baseEEEESaIS6_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS6_S8_EERKS6_
+ fun:_ZN5boost6detail3tss4initEPNS_9function1IvPvSaINS_13function_baseEEEE
+ fun:_ZN5boost6detail3tssC1EPNS_9function1IvPvSaINS_13function_baseEEEE
+ fun:_ZN5boost19thread_specific_ptrISt6vectorIjSaIjEEEC1Ev
+ fun:_Z41__static_initialization_and_destruction_0ii
+ fun:_GLOBAL__I_VertexArray.cpp
+}
+{
+ VertexArray_BufferCache_2
+ Memcheck:Leak
+ fun:_Znwj
+ obj:/usr/lib/libboost_thread-gcc42-mt-1_34_1.so.1.34.1
+ fun:_ZN5boost6detail3tss3setEPv
+ fun:_ZN5boost19thread_specific_ptrISt6vectorIjSaIjEEE5resetEPS3_
+ fun:_ZN3avg11VertexArray15initBufferCacheEv
+}
+{
+ VertexArray_BufferCache_3
+ Memcheck:Leak
+ fun:_Znwj
+ obj:/usr/lib/libboost_thread-gcc42-mt-1_34_1.so.1.34.1
+ obj:/usr/lib/libboost_thread-gcc42-mt-1_34_1.so.1.34.1
+ fun:pthread_once
+ fun:_ZN5boost6detail3tss4initEPNS_9function1IvPvSaINS_13function_baseEEEE
+ fun:_ZN5boost6detail3tssC1EPNS_9function1IvPvSaINS_13function_baseEEEE
+ fun:_ZN5boost19thread_specific_ptrISt6vectorIjSaIjEEEC1Ev
+ fun:_Z41__static_initialization_and_destruction_0ii
+ fun:_GLOBAL__I_VertexArray.cpp
+}
+{
+ VertexArray_BufferCache_4
+ Memcheck:Leak
+ fun:_Znwj
+ fun:_ZN5boost19thread_specific_ptrISt6vectorIjSaIjEEEC1Ev
+ fun:_Z41__static_initialization_and_destruction_0ii
+ fun:_GLOBAL__I_VertexArray.cpp
+}
+{
+ VertexArray_BufferCache_5
+ Memcheck:Leak
+ fun:_Znwj
+ fun:_ZN9__gnu_cxx13new_allocatorIN5boost6detail11tss_adapterISt6vectorIjSaIjEEEEE8allocateEjPKv
+ fun:_ZNK5boost6detail8function13basic_vtable1IvPvSaINS_13function_baseEEE14assign_functorINS0_11tss_adapterISt6vectorIjSaIjEEEEEEvRKT_RNS1_15function_bufferEN4mpl_5bool_ILb0EEE
+ fun:_ZNK5boost6detail8function13basic_vtable1IvPvSaINS_13function_baseEEE9assign_toINS0_11tss_adapterISt6vectorIjSaIjEEEEEEbRKT_RNS1_15function_bufferENS1_16function_obj_tagE
+ fun:_ZNK5boost6detail8function13basic_vtable1IvPvSaINS_13function_baseEEE9assign_toINS0_11tss_adapterISt6vectorIjSaIjEEEEEEbRKT_RNS1_15function_bufferE
+ fun:_ZN5boost9function1IvPvSaINS_13function_baseEEE9assign_toINS_6detail11tss_adapterISt6vectorIjSaIjEEEEEEvRKT_
+ fun:_ZN5boost9function1IvPvSaINS_13function_baseEEEC1INS_6detail11tss_adapterISt6vectorIjSaIjEEEEEET_NS_11enable_if_cIXsrNS_11type_traits7ice_notIXsrNS_11is_integralISC_EE5valueEEE5valueEiE4typeE
+ fun:_ZN5boost19thread_specific_ptrISt6vectorIjSaIjEEEC1Ev
+ fun:_Z41__static_initialization_and_destruction_0ii
+ fun:_GLOBAL__I_VertexArray.cpp
+}
+{
+ ThreadProfiler_0
+ Memcheck:Leak
+ fun:_Znwj
+ fun:_ZNSt6vectorIPvSaIS0_EE14_M_fill_insertEN9__gnu_cxx17__normal_iteratorIPS0_S2_EEjRKS0_
+ fun:_ZN5boost6detail3tss3setEPv
+ fun:_ZN5boost19thread_specific_ptrINS_10shared_ptrIN3avg14ThreadProfilerEEEE5resetEPS4_
+ fun:_ZN3avg14ThreadProfiler3getEv
+}
+{
+ ThreadProfiler_1
+ Memcheck:Leak
+ fun:_Znwj
+ fun:_ZNSt6vectorIPN5boost9function1IvPvSaINS0_13function_baseEEEESaIS6_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS6_S8_EERKS6_
+ fun:_ZN5boost6detail3tss4initEPNS_9function1IvPvSaINS_13function_baseEEEE
+ fun:_ZN5boost6detail3tssC1EPNS_9function1IvPvSaINS_13function_baseEEEE
+ fun:_ZN5boost19thread_specific_ptrINS_10shared_ptrIN3avg14ThreadProfilerEEEEC1Ev
+ fun:_Z41__static_initialization_and_destruction_0ii
+ fun:_GLOBAL__I_ThreadProfiler.cpp
+}
+{
+ ThreadProfiler_2
+ Memcheck:Leak
+ fun:_Znwj
+ obj:/usr/lib/libboost_thread-gcc42-mt-1_34_1.so.1.34.1
+ fun:_ZN5boost6detail3tss3setEPv
+ fun:_ZN5boost19thread_specific_ptrINS_10shared_ptrIN3avg14ThreadProfilerEEEE5resetEPS4_
+ fun:_ZN3avg14ThreadProfiler3getEv
+}
+{
+ ThreadProfiler_3
+ Memcheck:Leak
+ fun:_Znwj
+ obj:/usr/lib/libboost_thread-gcc42-mt-1_34_1.so.1.34.1
+ obj:/usr/lib/libboost_thread-gcc42-mt-1_34_1.so.1.34.1
+ fun:pthread_once
+ fun:_ZN5boost6detail3tss4initEPNS_9function1IvPvSaINS_13function_baseEEEE
+ fun:_ZN5boost6detail3tssC1EPNS_9function1IvPvSaINS_13function_baseEEEE
+ fun:_ZN5boost19thread_specific_ptrINS_10shared_ptrIN3avg14ThreadProfilerEEEEC1Ev
+ fun:_Z41__static_initialization_and_destruction_0ii
+ fun:_GLOBAL__I_ThreadProfiler.cpp
+}
+{
+ ThreadProfiler_5
+ Memcheck:Leak
+ fun:_Znwj
+ fun:_ZN5boost19thread_specific_ptrINS_10shared_ptrIN3avg14ThreadProfilerEEEEC1Ev
+ fun:_Z41__static_initialization_and_destruction_0ii
+ fun:_GLOBAL__I_ThreadProfiler.cpp
+}
+{
+ Logger
+ Memcheck:Leak
+ fun:_Znwj
+ fun:_ZN3avg6Logger3getEv
+}
+{
+ libxml_0
+ Memcheck:Leak
+ fun:malloc
+ fun:xmlNewMutex
+ fun:xmlInitGlobals
+}
+{
+ libxml_1
+ Memcheck:Leak
+ fun:malloc
+ fun:xmlStrndup
+ fun:xmlStrdup
+ fun:xmlNewCharEncodingHandler
+ fun:xmlInitCharEncodingHandlers
+}
+{
+ libxml_2
+ Memcheck:Leak
+ fun:malloc
+ fun:xmlInitCharEncodingHandlers
+}
+{
+ libxml_3
+ Memcheck:Leak
+ fun:malloc
+ fun:xmlNewCharEncodingHandler
+ fun:xmlInitCharEncodingHandlers
+}
+{
+ libxml_4
+ Memcheck:Cond
+ fun:inflateReset2
+}
+{
+ libSDL
+ Memcheck:Cond
+ obj:/usr/lib/libSDL-1.2.so.0.11.*
+ obj:/usr/lib/libSDL-1.2.so.0.11.*
+ obj:/usr/lib/libSDL-1.2.so.0.11.*
+ fun:SDL_PumpEvents
+}
+{
+ X11
+ Memcheck:Leak
+ fun:realloc
+ obj:/usr/lib/libX11.so.6.2.0
+ obj:/usr/lib/libX11.so.6.2.0
+ obj:/usr/lib/libX11.so.6.2.0
+ fun:_XlcCreateLC
+ fun:_XlcDefaultLoader
+ fun:_XOpenLC
+ fun:_XlcCurrentLC
+ fun:XSetLocaleModifiers
+}
+{
+ TimeSource
+ Memcheck:Leak
+ fun:_Znwj
+ fun:_ZN3avg10TimeSource3getEv
+}
+{
+ SDL_Audio_0
+ Memcheck:Leak
+ fun:calloc
+ fun:snd_config_update_r
+ fun:snd_config_update
+ fun:snd_pcm_open
+ obj:/usr/lib/libSDL-1.2.so.0.11.1
+ fun:SDL_AudioInit
+}
+{
+ SDL_Audio_1
+ Memcheck:Leak
+ fun:malloc
+ obj:/usr/lib/libasound.so.2.0.0
+ obj:/usr/lib/libasound.so.2.0.0
+ obj:/usr/lib/libasound.so.2.0.0
+ obj:/usr/lib/libSDL-1.2.so.0.11.1
+ fun:SDL_AudioInit
+}
+{
+ SDL_Audio_2
+ Memcheck:Leak
+ fun:malloc
+ fun:strdup
+ fun:snd_user_file
+ fun:snd_config_update_r
+ fun:snd_config_update
+ fun:snd_pcm_open
+ obj:/usr/lib/libSDL-1.2.so.0.11.1
+ fun:SDL_AudioInit
+}
+{
+ SDL_Audio_3
+ Memcheck:Leak
+ fun:malloc
+ obj:/usr/lib/libasound.so.2.0.0
+ obj:/usr/lib/libasound.so.2.0.0
+ obj:/usr/lib/libasound.so.2.0.0
+ obj:/usr/lib/libasound.so.2.0.0
+ fun:snd_config_update_r
+ fun:snd_config_update
+ fun:snd_pcm_open
+ obj:/usr/lib/libSDL-1.2.so.0.11.1
+ fun:SDL_AudioInit
+}
+{
+ SDL_Audio_4
+ Memcheck:Leak
+ fun:calloc
+ obj:/usr/lib/libasound.so.2.0.0
+ fun:snd_config_update_r
+ fun:snd_config_update
+ fun:snd_pcm_open
+ obj:/usr/lib/libSDL-1.2.so.0.11.1
+ fun:SDL_AudioInit
+}
+{
+ SDL_Audio_5
+ Memcheck:Leak
+ fun:calloc
+ obj:/usr/lib/libasound.so.2.0.0
+ obj:/usr/lib/libasound.so.2.0.0
+ obj:/usr/lib/libasound.so.2.0.0
+ obj:/usr/lib/libasound.so.2.0.0
+ obj:/usr/lib/libasound.so.2.0.0
+ fun:snd_config_update_r
+ fun:snd_config_update
+ fun:snd_pcm_open
+ obj:/usr/lib/libSDL-1.2.so.0.11.1
+ fun:SDL_AudioInit
+}
+{
+ libasound_0
+ Memcheck:Leak
+ fun:malloc
+ obj:/lib/ld-2.*.so
+ obj:/lib/ld-2.*.so
+ obj:/lib/ld-2.*.so
+ obj:/lib/ld-2.*.so
+ obj:/lib/ld-2.*.so
+ obj:/lib/tls/i686/cmov/libdl-2.*.so
+ obj:/lib/ld-2.*.so
+ obj:/lib/tls/i686/cmov/libdl-2.*.so
+ fun:dlopen
+ fun:snd_dlopen
+ obj:/usr/lib/libasound.so.2.0.0
+}
+{
+ libasound_1
+ Memcheck:Leak
+ fun:calloc
+ obj:/usr/lib/libasound.so.2.0.0
+ obj:/usr/lib/libasound.so.2.0.0
+ obj:/usr/lib/libasound.so.2.0.0
+ obj:/usr/lib/libasound.so.2.0.0
+ obj:/usr/lib/libasound.so.2.0.0
+ obj:/usr/lib/libasound.so.2.0.0
+ obj:/usr/lib/libasound.so.2.0.0
+ fun:snd_config_update_r
+ fun:snd_config_update
+ fun:snd_pcm_open
+}
+{
+ SDL_Unload_0
+ Memcheck:Leak
+ fun:malloc
+ obj:/lib/ld-2.*.so
+ obj:/lib/ld-2.*.so
+ obj:/lib/tls/i686/cmov/libdl-2.*.so
+ obj:/lib/ld-2.*.so
+ obj:/lib/tls/i686/cmov/libdl-2.*.so
+ fun:dlclose
+ fun:SDL_UnloadObject
+}
+{
+ SDL_Unload_1
+ Memcheck:Leak
+ fun:malloc
+ obj:/lib/ld-2.*.so
+ obj:/lib/ld-2.*.so
+ obj:/lib/ld-2.*.so
+ obj:/lib/tls/i686/cmov/libdl-2.*.so
+ obj:/lib/ld-2.*.so
+ obj:/lib/tls/i686/cmov/libdl-2.*.so
+ fun:dlclose
+ fun:SDL_UnloadObject
+}
+{
+ SDL_SetVideoMode
+ Memcheck:Leak
+ fun:malloc
+ obj:/usr/lib/libX11.so.6.2.0
+ fun:_XimEncodeLocalICAttr
+ fun:_XimSetICValueData
+ fun:_XimLocalCreateIC
+ fun:XCreateIC
+ obj:/usr/lib/libSDL-1.2.so.0.11.1
+ obj:/usr/lib/libSDL-1.2.so.0.11.1
+}
+{
+ boost_converter_1
+ Memcheck:Leak
+ fun:_Znwj
+ fun:*
+ fun:_ZN5boost6python9converter29initialize_builtin_convertersEv
+}
+{
+ libpng_0
+ Memcheck:Cond
+ obj:/*lib/libz.so.1*
+ fun:deflate
+ obj:/*lib/libpng12.so.0*
+ obj:/*lib/libpng12.so.0*
+ obj:/*lib/libpng12.so.0*
+ fun:png_write_row
+}
+{
+ libpng_1
+ Memcheck:Value4
+ obj:/*lib/libz.so.1*
+ fun:deflate
+ obj:/*lib/libpng12.so.0*
+ obj:/*lib/libpng12.so.0*
+ obj:/*lib/libpng12.so.0*
+ fun:png_write_row
+}
+{
+ libpng_2
+ Memcheck:Value4
+ obj:/*lib/libz.so.1*
+ obj:/*lib/libz.so.1*
+ obj:/*lib/libz.so.1*
+ fun:deflate
+ obj:/*lib/libpng12.so.0*
+ obj:/*lib/libpng12.so.0*
+ obj:/*lib/libpng12.so.0*
+ fun:png_write_row
+}
+{
+ libpng_3
+ Memcheck:Value4
+ fun:crc32
+ obj:/*lib/libpng12.so.0*
+ fun:png_write_chunk_data
+ fun:png_write_chunk
+ obj:/*lib/libpng12.so.0*
+ obj:/*lib/libpng12.so.0*
+ obj:/*lib/libpng12.so.0*
+ obj:/*lib/libpng12.so.0*
+ fun:png_write_row
+}
+{
+ libpng_4
+ Memcheck:Cond
+ fun:inflateReset2
+ obj:/*lib/libz.so.1*
+ fun:*
+}
+{
+ GraphicsMagick
+ Memcheck:Param
+ write(buf)
+ obj:/lib/ld-2.*.so
+ fun:_IO_do_write
+ fun:_IO_file_close_it
+ fun:fclose
+ fun:CloseBlob
+ obj:/usr/lib/libGraphicsMagick.so.1.0.11
+ fun:WriteImage
+}
+{
+ python_1
+ Memcheck:Leak
+ fun:malloc
+ fun:_PyObject_GC_NewVar
+ fun:*
+}
+{
+ python_2
+ Memcheck:Cond
+ fun:PyObject_Free
+ obj:*
+ obj:*
+}
+{
+ python_3
+ Memcheck:Value4
+ fun:PyObject_Free
+ obj:*
+ obj:*
+}
+{
+ python_4
+ Memcheck:Addr4
+ fun:PyObject_Free
+ obj:*
+}
+{
+ python_5
+ Memcheck:Value8
+ fun:PyObject_Free
+ obj:*
+ obj:*
+}
+{
+ python_6
+ Memcheck:Addr8
+ fun:PyObject_Free
+ obj:*
+ obj:*
+}
+{
+ python_7
+ Memcheck:Addr4
+ fun:PyObject_Realloc
+ obj:*
+}
+{
+ python_8
+ Memcheck:Cond
+ fun:PyObject_Realloc
+ obj:*
+ obj:*
+}
+{
+ python_9
+ Memcheck:Value4
+ fun:PyObject_Realloc
+ obj:*
+ obj:*
+}
+{
+ python_10
+ Memcheck:Addr8
+ fun:PyObject_Realloc
+ obj:*
+ obj:*
+}
+{
+ python_11
+ Memcheck:Value8
+ fun:PyObject_Realloc
+ obj:*
+ obj:*
+}
+{
+ python_12
+ Memcheck:Addr4
+ fun:*
+ obj:/usr/bin/python2.7
+}
+{
+ python_13
+ Memcheck:Cond
+ fun:*
+ fun:_PyObject_GC_Resize
+}
+{
+ python_14
+ Memcheck:Value8
+ fun:*
+ obj:/usr/bin/python2.7
+}
+{
+ python_15
+ Memcheck:Cond
+ fun:*
+ obj:/usr/bin/python2.7
+}
+{
+ boost.python
+ Memcheck:Leak
+ fun:_Znwj
+ fun:_ZN5boost6python9converter8registry9push_backEPFPvP7_objectEPFvS5_PNS1_30rvalue_from_python_stage1_dataEENS0_9type_infoE
+ fun:_ZN26IntPoint_from_python_tupleC1Ev
+ fun:_Z15init_module_avgv
+}
+{
+ glxChooseVisual
+ Memcheck:Leak
+ fun:malloc
+ fun:XGetVisualInfo
+ fun:glXChooseVisual
+}
+{
+ libdc1394_0
+ Memcheck:Cond
+ obj:/usr/lib/libdc1394.so.22.1.0
+ fun:refresh_enumeration
+ fun:dc1394_camera_enumerate
+}
+{
+ libdc1394_1
+ Memcheck:Value4
+ obj:/usr/lib/libdc1394.so.22.1.0
+ fun:refresh_enumeration
+ fun:dc1394_camera_enumerate
+}
+{
+ libdc1394_2
+ Memcheck:Cond
+ obj:/usr/lib/libdc1394.so.22.1.0
+ obj:/usr/lib/libdc1394.so.22.1.0
+ fun:refresh_enumeration
+ fun:dc1394_camera_enumerate
+}
+{
+ libdc1394_6
+ Memcheck:Value4
+ obj:/usr/lib/libdc1394.so.22.1.0
+}
+{
+ libdc1394_4
+ Memcheck:Cond
+ fun:_ZN3avg8FWCameraC1ESsyiNS_5PointIiEESsdb
+}
+{
+ libdc1394_5
+ Memcheck:Cond
+ obj:/usr/lib/libdc1394.so.22.1.0
+}
+{
+ libdc1394_6
+ Memcheck:Param
+ write(buf)
+ obj:/lib/ld-2.*.so
+ fun:raw1394_read
+ fun:platform_camera_read
+}
+{
+ libdc1394_7
+ Memcheck:Cond
+ obj:/lib/tls/i686/cmov/libc-2.8.90.so
+ fun:vfprintf
+ obj:/lib/tls/i686/cmov/libc-2.8.90.so
+ fun:vfprintf
+ fun:fprintf
+ fun:dc1394_feature_print
+}
+{
+ libdc1394_8
+ Memcheck:Param
+ write(buf)
+ obj:/lib/ld-2.*.so
+ fun:raw1394_write
+ fun:platform_camera_write
+ fun:dc1394_set_control_registers
+ fun:dc1394_video_set_iso_speed
+}
+{
+ libdc1394_9
+ Memcheck:Cond
+ obj:/usr/lib/libraw1394.so.8.2.0
+}
+{
+ libdc1394_10
+ Memcheck:Value4
+ obj:/usr/lib/libraw1394.so.8.2.0
+}
+{
+ libdc1394_11
+ Memcheck:Value4
+ obj:/lib/tls/i686/cmov/libc-2.8.90.so
+ fun:vfprintf
+ obj:/lib/tls/i686/cmov/libc-2.8.90.so
+ fun:vfprintf
+ fun:fprintf
+ fun:dc1394_feature_print
+}
+{
+ libdc1394_12
+ Memcheck:Cond
+ fun:vfprintf
+ obj:/lib/tls/i686/cmov/libc-2.8.90.so
+ fun:vfprintf
+ fun:fprintf
+ fun:dc1394_feature_print
+}
+{
+ libdc1394_13
+ Memcheck:Param
+ ioctl(generic)
+ obj:/lib/ld-2.*.so
+ fun:dc1394_capture_setup
+}
+{
+ libdc1394_14
+ Memcheck:Cond
+ fun:strlen
+ fun:*
+ fun:_ZNK3avg8FWCamera9getDeviceEv
+}
+{
+ libdc1394_15
+ Memcheck:Cond
+ fun:*
+ fun:*
+ fun:*
+ fun:*
+ fun:_ZNK3avg8FWCamera9getDeviceEv
+}
+{
+ fontconfig1
+ Memcheck:Addr4
+ ...
+ fun:FcConfigParseAndLoad
+ ...
+}
+{
+ fontconfig2
+ Memcheck:Leak
+ ...
+ fun:FcConfigParseAndLoad
+ ...
+}
+{
+ libavcodec
+ Memcheck:Cond
+ obj:/usr/lib/i686/cmov/libavcodec.so.52.72.2
+}
+{
+ drm_intel
+ Memcheck:Cond
+ fun:drm_intel_bufmgr_gem_init
+ obj:/usr/lib/x86_64-linux-gnu/dri/i965_dri.so
+}
+{
+ mesa
+ Memcheck:Cond
+ fun:_ZN22_mesa_glsl_parse_stateC1EP10gl_contextjPv
+ obj:/usr/lib/x86_64-linux-gnu/dri/libglsl.so
+}
+
diff --git a/win/anim/anim.vcxproj b/win/anim/anim.vcxproj
new file mode 100644
index 0000000..68288f3
--- /dev/null
+++ b/win/anim/anim.vcxproj
@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{A8BAD8F9-6DAA-4C23-9AD8-55552A6B8D4E}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ <RootNamespace>anim</RootNamespace>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="..\libavg.props" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="..\libavg.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup />
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <PreprocessorDefinitions>NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <None Include="ReadMe.txt" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\src\anim\Anim.h" />
+ <ClInclude Include="..\..\src\anim\AttrAnim.h" />
+ <ClInclude Include="..\..\src\anim\ContinuousAnim.h" />
+ <ClInclude Include="..\..\src\anim\EaseInOutAnim.h" />
+ <ClInclude Include="..\..\src\anim\LinearAnim.h" />
+ <ClInclude Include="..\..\src\anim\ParallelAnim.h" />
+ <ClInclude Include="..\..\src\anim\SimpleAnim.h" />
+ <ClInclude Include="..\..\src\anim\StateAnim.h" />
+ <ClInclude Include="..\..\src\anim\WaitAnim.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\src\anim\Anim.cpp" />
+ <ClCompile Include="..\..\src\anim\AttrAnim.cpp" />
+ <ClCompile Include="..\..\src\anim\ContinuousAnim.cpp" />
+ <ClCompile Include="..\..\src\anim\EaseInOutAnim.cpp" />
+ <ClCompile Include="..\..\src\anim\LinearAnim.cpp" />
+ <ClCompile Include="..\..\src\anim\ParallelAnim.cpp" />
+ <ClCompile Include="..\..\src\anim\SimpleAnim.cpp" />
+ <ClCompile Include="..\..\src\anim\StateAnim.cpp" />
+ <ClCompile Include="..\..\src\anim\WaitAnim.cpp" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/win/audio/audio.vcxproj b/win/audio/audio.vcxproj
new file mode 100644
index 0000000..c4107f7
--- /dev/null
+++ b/win/audio/audio.vcxproj
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{D0C1A58C-BF0E-4F88-885A-65444A23516E}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ <RootNamespace>audio</RootNamespace>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="..\libavg.props" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="..\libavg.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup />
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <PreprocessorDefinitions>NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ </Link>
+ <Lib>
+ <AdditionalDependencies>
+ </AdditionalDependencies>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <None Include="ReadMe.txt" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\src\audio\AudioBuffer.cpp" />
+ <ClCompile Include="..\..\src\audio\AudioEngine.cpp" />
+ <ClCompile Include="..\..\src\audio\AudioMsg.cpp" />
+ <ClCompile Include="..\..\src\audio\AudioParams.cpp" />
+ <ClCompile Include="..\..\src\audio\AudioSource.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\src\audio\AudioBuffer.h" />
+ <ClInclude Include="..\..\src\audio\AudioEngine.h" />
+ <ClInclude Include="..\..\src\audio\AudioMsg.h" />
+ <ClInclude Include="..\..\src\audio\AudioParams.h" />
+ <ClInclude Include="..\..\src\audio\Dynamics.h" />
+ <ClInclude Include="..\..\src\audio\IProcessor.h" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/win/base/base.vcxproj b/win/base/base.vcxproj
new file mode 100755
index 0000000..2b0d672
--- /dev/null
+++ b/win/base/base.vcxproj
@@ -0,0 +1,177 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{4B3614A9-4CF5-4C14-9F71-4254B7988324}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ <RootNamespace>base</RootNamespace>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <WholeProgramOptimization>false</WholeProgramOptimization>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="..\libavg.props" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="..\libavg.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <CustomBuildBeforeTargets>
+ </CustomBuildBeforeTargets>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <PreprocessorDefinitions>NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ </Link>
+ <Lib>
+ <AdditionalDependencies>libxml2.lib</AdditionalDependencies>
+ <LinkTimeCodeGeneration>false</LinkTimeCodeGeneration>
+ </Lib>
+ <CustomBuildStep>
+ <Command>
+ </Command>
+ <Message>
+ </Message>
+ <Outputs>
+ </Outputs>
+ </CustomBuildStep>
+ <PreBuildEvent>
+ <Command>python.exe ..\..\CreateVersionFile.py ..\..\src</Command>
+ </PreBuildEvent>
+ <PreBuildEvent>
+ <Message>Generating version.h</Message>
+ </PreBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\src\base\Backtrace.h" />
+ <ClInclude Include="..\..\src\base\BezierCurve.h" />
+ <ClInclude Include="..\..\src\base\CmdQueue.h" />
+ <ClInclude Include="..\..\src\base\Command.h" />
+ <ClInclude Include="..\..\src\base\ConfigMgr.h" />
+ <ClInclude Include="..\..\src\base\CubicSpline.h" />
+ <ClInclude Include="..\..\src\base\DAG.h" />
+ <ClInclude Include="..\..\src\base\Directory.h" />
+ <ClInclude Include="..\..\src\base\DirEntry.h" />
+ <ClInclude Include="..\..\src\base\DlfcnWrapper.h" />
+ <ClInclude Include="..\..\src\base\Exception.h" />
+ <ClInclude Include="..\..\src\base\FileHelper.h" />
+ <ClInclude Include="..\..\src\base\GeomHelper.h" />
+ <ClInclude Include="..\..\src\base\GLMHelper.h" />
+ <ClInclude Include="..\..\src\base\IFrameEndListener.h" />
+ <ClInclude Include="..\..\src\base\ILogHandler.h" />
+ <ClInclude Include="..\..\src\base\ILogSink.h" />
+ <ClInclude Include="..\..\src\base\IPlaybackEndListener.h" />
+ <ClInclude Include="..\..\src\base\IPreRenderListener.h" />
+ <ClInclude Include="..\..\src\base\Logger.h" />
+ <ClInclude Include="..\..\src\base\MathHelper.h" />
+ <ClInclude Include="..\..\src\base\ObjectCounter.h" />
+ <ClInclude Include="..\..\src\base\OSHelper.h" />
+ <ClInclude Include="..\..\src\base\ProfilingZone.h" />
+ <ClInclude Include="..\..\src\base\ProfilingZoneID.h" />
+ <ClInclude Include="..\..\src\base\Queue.h" />
+ <ClInclude Include="..\..\src\base\Rect.h" />
+ <ClInclude Include="..\..\src\base\ScopeTimer.h" />
+ <ClInclude Include="..\..\src\base\Signal.h" />
+ <ClInclude Include="..\..\src\base\StandardLogSink.h" />
+ <ClInclude Include="..\..\src\base\StringHelper.h" />
+ <ClInclude Include="..\..\src\base\Test.h" />
+ <ClInclude Include="..\..\src\base\TestSuite.h" />
+ <ClInclude Include="..\..\src\base\ThreadProfiler.h" />
+ <ClInclude Include="..\..\src\base\TimeSource.h" />
+ <ClInclude Include="..\..\src\base\Triangle.h" />
+ <ClInclude Include="..\..\src\base\triangulate\AdvancingFront.h" />
+ <ClInclude Include="..\..\src\base\triangulate\Shapes.h" />
+ <ClInclude Include="..\..\src\base\triangulate\Sweep.h" />
+ <ClInclude Include="..\..\src\base\triangulate\SweepContext.h" />
+ <ClInclude Include="..\..\src\base\triangulate\Triangulate.h" />
+ <ClInclude Include="..\..\src\base\triangulate\Utils.h" />
+ <ClInclude Include="..\..\src\base\UTF8String.h" />
+ <ClInclude Include="..\..\src\base\WideLine.h" />
+ <ClInclude Include="..\..\src\base\WorkerThread.h" />
+ <ClInclude Include="..\..\src\base\ThreadHelper.h" />
+ <ClInclude Include="..\..\src\base\XMLHelper.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\src\base\Backtrace.cpp" />
+ <ClCompile Include="..\..\src\base\BezierCurve.cpp" />
+ <ClCompile Include="..\..\src\base\ConfigMgr.cpp" />
+ <ClCompile Include="..\..\src\base\CubicSpline.cpp" />
+ <ClCompile Include="..\..\src\base\DAG.cpp" />
+ <ClCompile Include="..\..\src\base\Directory.cpp" />
+ <ClCompile Include="..\..\src\base\DirEntry.cpp" />
+ <ClCompile Include="..\..\src\base\DlfcnWrapper.cpp" />
+ <ClCompile Include="..\..\src\base\Exception.cpp" />
+ <ClCompile Include="..\..\src\base\FileHelper.cpp" />
+ <ClCompile Include="..\..\src\base\GeomHelper.cpp" />
+ <ClCompile Include="..\..\src\base\GLMHelper.cpp" />
+ <ClCompile Include="..\..\src\base\Logger.cpp" />
+ <ClCompile Include="..\..\src\base\MathHelper.cpp" />
+ <ClCompile Include="..\..\src\base\ObjectCounter.cpp" />
+ <ClCompile Include="..\..\src\base\OSHelper.cpp" />
+ <ClCompile Include="..\..\src\base\ProfilingZone.cpp" />
+ <ClCompile Include="..\..\src\base\ProfilingZoneID.cpp" />
+ <ClCompile Include="..\..\src\base\ScopeTimer.cpp" />
+ <ClCompile Include="..\..\src\base\StandardLogSink.cpp" />
+ <ClCompile Include="..\..\src\base\StringHelper.cpp" />
+ <ClCompile Include="..\..\src\base\Test.cpp" />
+ <ClCompile Include="..\..\src\base\TestSuite.cpp" />
+ <ClCompile Include="..\..\src\base\ThreadProfiler.cpp" />
+ <ClCompile Include="..\..\src\base\TimeSource.cpp" />
+ <ClCompile Include="..\..\src\base\Triangle.cpp" />
+ <ClCompile Include="..\..\src\base\triangulate\AdvancingFront.cpp" />
+ <ClCompile Include="..\..\src\base\triangulate\Shapes.cpp" />
+ <ClCompile Include="..\..\src\base\triangulate\Sweep.cpp" />
+ <ClCompile Include="..\..\src\base\triangulate\SweepContext.cpp" />
+ <ClCompile Include="..\..\src\base\triangulate\Triangulate.cpp" />
+ <ClCompile Include="..\..\src\base\UTF8String.cpp" />
+ <ClCompile Include="..\..\src\base\WideLine.cpp" />
+ <ClCompile Include="..\..\src\base\WorkerThread.cpp" />
+ <ClCompile Include="..\..\src\base\ThreadHelper.cpp" />
+ <ClCompile Include="..\..\src\base\XMLHelper.cpp" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project>
diff --git a/win/genwinimportlibs.py b/win/genwinimportlibs.py
new file mode 100755
index 0000000..819585a
--- /dev/null
+++ b/win/genwinimportlibs.py
@@ -0,0 +1,35 @@
+#!/usr/bin/env python
+
+import os
+import string
+
+os.chdir("deps")
+
+def tmpFileToDef(baseName):
+ tmpFile = open("tmp", "r")
+ defFile = open(baseName+".def", "w")
+ defFile.write("EXPORTS\n")
+ content = tmpFile.readlines()
+ i = 0
+ while content[i].find("ordinal hint") == -1:
+ i += 1
+ isEmptyLine = False;
+ i += 2
+
+ while not(isEmptyLine):
+ line = string.split(content[i])
+ isEmptyLine = len(line) == 0
+ if not(isEmptyLine):
+ defFile.write(line[3]+"\n")
+ i += 1
+ defFile.close()
+
+
+for dllName in os.listdir("bin"):
+ if dllName[-4:] == ".dll":
+ print "Generating lib for '" + dllName + "'."
+ os.system("dumpbin /EXPORTS bin\\"+dllName+" > tmp")
+ baseName = dllName[:-4]
+ tmpFileToDef(baseName)
+ os.system("lib /def:"+baseName+".def /out:lib\\"+baseName+".lib /machine:x86")
+
diff --git a/win/graphics/graphics.vcxproj b/win/graphics/graphics.vcxproj
new file mode 100755
index 0000000..3561c43
--- /dev/null
+++ b/win/graphics/graphics.vcxproj
@@ -0,0 +1,211 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{9B9F3907-0C54-4FF4-AAF3-8FDA3496DB88}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ <RootNamespace>graphics</RootNamespace>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="..\libavg.props" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="..\libavg.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup />
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <Optimization>MaxSpeed</Optimization>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <PreprocessorDefinitions>NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ </Link>
+ <Lib>
+ <AdditionalDependencies>
+ </AdditionalDependencies>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\src\graphics\Bitmap.h" />
+ <ClInclude Include="..\..\src\graphics\BitmapLoader.h" />
+ <ClInclude Include="..\..\src\graphics\BmpTextureMover.h" />
+ <ClInclude Include="..\..\src\graphics\ContribDefs.h" />
+ <ClInclude Include="..\..\src\graphics\Display.h" />
+ <ClInclude Include="..\..\src\graphics\FBO.h" />
+ <ClInclude Include="..\..\src\graphics\Filter.h" />
+ <ClInclude Include="..\..\src\graphics\Filter3x3.h" />
+ <ClInclude Include="..\..\src\graphics\FilterBandpass.h" />
+ <ClInclude Include="..\..\src\graphics\FilterBlur.h" />
+ <ClInclude Include="..\..\src\graphics\Filtercolorize.h" />
+ <ClInclude Include="..\..\src\graphics\FilterConvol.h" />
+ <ClInclude Include="..\..\src\graphics\FilterDilation.h" />
+ <ClInclude Include="..\..\src\graphics\FilterErosion.h" />
+ <ClInclude Include="..\..\src\graphics\FilterFastBandpass.h" />
+ <ClInclude Include="..\..\src\graphics\FilterFastDownscale.h" />
+ <ClInclude Include="..\..\src\graphics\Filterfill.h" />
+ <ClInclude Include="..\..\src\graphics\Filterfillrect.h" />
+ <ClInclude Include="..\..\src\graphics\Filterflip.h" />
+ <ClInclude Include="..\..\src\graphics\Filterfliprgb.h" />
+ <ClInclude Include="..\..\src\graphics\Filterfliprgba.h" />
+ <ClInclude Include="..\..\src\graphics\Filterflipuv.h" />
+ <ClInclude Include="..\..\src\graphics\FilterflipX.h" />
+ <ClInclude Include="..\..\src\graphics\FilterFloodfill.h" />
+ <ClInclude Include="..\..\src\graphics\FilterGauss.h" />
+ <ClInclude Include="..\..\src\graphics\FilterGetAlpha.h" />
+ <ClInclude Include="..\..\src\graphics\Filtergrayscale.h" />
+ <ClInclude Include="..\..\src\graphics\FilterHighpass.h" />
+ <ClInclude Include="..\..\src\graphics\FilterId.h" />
+ <ClInclude Include="..\..\src\graphics\FilterIntensity.h" />
+ <ClInclude Include="..\..\src\graphics\FilterMask.h" />
+ <ClInclude Include="..\..\src\graphics\FilterNormalize.h" />
+ <ClInclude Include="..\..\src\graphics\FilterResizeBilinear.h" />
+ <ClInclude Include="..\..\src\graphics\FilterResizeGaussian.h" />
+ <ClInclude Include="..\..\src\graphics\FilterThreshold.h" />
+ <ClInclude Include="..\..\src\graphics\FilterUnmultiplyAlpha.h" />
+ <ClInclude Include="..\..\src\graphics\GLBufferCache.h" />
+ <ClInclude Include="..\..\src\graphics\GLConfig.h" />
+ <ClInclude Include="..\..\src\graphics\GLContext.h" />
+ <ClInclude Include="..\..\src\graphics\GLShaderParam.h" />
+ <ClInclude Include="..\..\src\graphics\GLTexture.h" />
+ <ClInclude Include="..\..\src\graphics\GPUBandpassFilter.h" />
+ <ClInclude Include="..\..\src\graphics\GPUBlurFilter.h" />
+ <ClInclude Include="..\..\src\graphics\GPUBrightnessFilter.h" />
+ <ClInclude Include="..\..\src\graphics\GPUChromaKeyFilter.h" />
+ <ClInclude Include="..\..\src\graphics\GPUFilter.h" />
+ <ClInclude Include="..\..\src\graphics\GPUHueSatFilter.h" />
+ <ClInclude Include="..\..\src\graphics\GPUInvertFilter.h" />
+ <ClInclude Include="..\..\src\graphics\GPUNullFilter.h" />
+ <ClInclude Include="..\..\src\graphics\GPURGB2YUVFilter.h" />
+ <ClInclude Include="..\..\src\graphics\GPUShadowFilter.h" />
+ <ClInclude Include="..\..\src\graphics\GraphicsTest.h" />
+ <ClInclude Include="..\..\src\graphics\HistoryPreProcessor.h" />
+ <ClInclude Include="..\..\src\graphics\ImagingProjection.h" />
+ <ClInclude Include="..\..\src\graphics\OGLHelper.h" />
+ <ClInclude Include="..\..\src\graphics\OGLShader.h" />
+ <ClInclude Include="..\..\src\graphics\PBO.h" />
+ <ClInclude Include="..\..\src\graphics\Pixel16.h" />
+ <ClInclude Include="..\..\src\graphics\Pixel24.h" />
+ <ClInclude Include="..\..\src\graphics\Pixel32.h" />
+ <ClInclude Include="..\..\src\graphics\Pixel8.h" />
+ <ClInclude Include="..\..\src\graphics\Pixeldefs.h" />
+ <ClInclude Include="..\..\src\graphics\PixelFormat.h" />
+ <ClInclude Include="..\..\src\graphics\ShaderRegistry.h" />
+ <ClInclude Include="..\..\src\graphics\StandardShader.h" />
+ <ClInclude Include="..\..\src\graphics\SubVertexArray.h" />
+ <ClInclude Include="..\..\src\graphics\TextureMover.h" />
+ <ClInclude Include="..\..\src\graphics\TwoPassScale.h" />
+ <ClInclude Include="..\..\src\graphics\VertexArray.h" />
+ <ClInclude Include="..\..\src\graphics\VertexData.h" />
+ <ClInclude Include="..\..\src\graphics\WGLContext.h" />
+ <ClInclude Include="..\..\src\graphics\WinDisplay.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\src\graphics\Bitmap.cpp" />
+ <ClCompile Include="..\..\src\graphics\BitmapLoader.cpp" />
+ <ClCompile Include="..\..\src\graphics\BmpTextureMover.cpp" />
+ <ClCompile Include="..\..\src\graphics\Display.cpp" />
+ <ClCompile Include="..\..\src\graphics\FBO.cpp" />
+ <ClCompile Include="..\..\src\graphics\Filter.cpp" />
+ <ClCompile Include="..\..\src\graphics\Filter3x3.cpp" />
+ <ClCompile Include="..\..\src\graphics\FilterBandpass.cpp" />
+ <ClCompile Include="..\..\src\graphics\FilterBlur.cpp" />
+ <ClCompile Include="..\..\src\graphics\Filtercolorize.cpp" />
+ <ClCompile Include="..\..\src\graphics\FilterDilation.cpp" />
+ <ClCompile Include="..\..\src\graphics\FilterErosion.cpp" />
+ <ClCompile Include="..\..\src\graphics\FilterFastBandpass.cpp" />
+ <ClCompile Include="..\..\src\graphics\FilterFastDownscale.cpp" />
+ <ClCompile Include="..\..\src\graphics\Filterflip.cpp" />
+ <ClCompile Include="..\..\src\graphics\Filterfliprgb.cpp" />
+ <ClCompile Include="..\..\src\graphics\Filterfliprgba.cpp" />
+ <ClCompile Include="..\..\src\graphics\Filterflipuv.cpp" />
+ <ClCompile Include="..\..\src\graphics\FilterflipX.cpp" />
+ <ClCompile Include="..\..\src\graphics\FilterGauss.cpp" />
+ <ClCompile Include="..\..\src\graphics\FilterGetAlpha.cpp" />
+ <ClCompile Include="..\..\src\graphics\Filtergrayscale.cpp" />
+ <ClCompile Include="..\..\src\graphics\FilterHighpass.cpp" />
+ <ClCompile Include="..\..\src\graphics\FilterIntensity.cpp" />
+ <ClCompile Include="..\..\src\graphics\FilterMask.cpp" />
+ <ClCompile Include="..\..\src\graphics\FilterNormalize.cpp" />
+ <ClCompile Include="..\..\src\graphics\FilterResizeBilinear.cpp" />
+ <ClCompile Include="..\..\src\graphics\FilterResizeGaussian.cpp" />
+ <ClCompile Include="..\..\src\graphics\FilterThreshold.cpp" />
+ <ClCompile Include="..\..\src\graphics\FilterUnmultiplyAlpha.cpp" />
+ <ClCompile Include="..\..\src\graphics\GLBufferCache.cpp" />
+ <ClCompile Include="..\..\src\graphics\GLConfig.cpp" />
+ <ClCompile Include="..\..\src\graphics\GLContext.cpp" />
+ <ClCompile Include="..\..\src\graphics\GLShaderParam.cpp" />
+ <ClCompile Include="..\..\src\graphics\GLTexture.cpp" />
+ <ClCompile Include="..\..\src\graphics\GPUBandpassFilter.cpp" />
+ <ClCompile Include="..\..\src\graphics\GPUBlurFilter.cpp" />
+ <ClCompile Include="..\..\src\graphics\GPUBrightnessFilter.cpp" />
+ <ClCompile Include="..\..\src\graphics\GPUChromaKeyFilter.cpp" />
+ <ClCompile Include="..\..\src\graphics\GPUFilter.cpp" />
+ <ClCompile Include="..\..\src\graphics\GPUHueSatFilter.cpp" />
+ <ClCompile Include="..\..\src\graphics\GPUInvertFilter.cpp" />
+ <ClCompile Include="..\..\src\graphics\GPUNullFilter.cpp" />
+ <ClCompile Include="..\..\src\graphics\GPURGB2YUVFilter.cpp" />
+ <ClCompile Include="..\..\src\graphics\GPUShadowFilter.cpp" />
+ <ClCompile Include="..\..\src\graphics\GraphicsTest.cpp" />
+ <ClCompile Include="..\..\src\graphics\HistoryPreProcessor.cpp" />
+ <ClCompile Include="..\..\src\graphics\ImagingProjection.cpp" />
+ <ClCompile Include="..\..\src\graphics\OGLHelper.cpp" />
+ <ClCompile Include="..\..\src\graphics\OGLShader.cpp" />
+ <ClCompile Include="..\..\src\graphics\PBO.cpp" />
+ <ClCompile Include="..\..\src\graphics\Pixel32.cpp" />
+ <ClCompile Include="..\..\src\graphics\PixelFormat.cpp" />
+ <ClCompile Include="..\..\src\graphics\ShaderRegistry.cpp" />
+ <ClCompile Include="..\..\src\graphics\StandardShader.cpp" />
+ <ClCompile Include="..\..\src\graphics\SubVertexArray.cpp" />
+ <ClCompile Include="..\..\src\graphics\TextureMover.cpp" />
+ <ClCompile Include="..\..\src\graphics\VertexArray.cpp" />
+ <ClCompile Include="..\..\src\graphics\VertexData.cpp" />
+ <ClCompile Include="..\..\src\graphics\WGLContext.cpp" />
+ <ClCompile Include="..\..\src\graphics\WinDisplay.cpp" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/win/imaging/imaging.vcxproj b/win/imaging/imaging.vcxproj
new file mode 100644
index 0000000..0a5273e
--- /dev/null
+++ b/win/imaging/imaging.vcxproj
@@ -0,0 +1,126 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{669BEA02-213C-4387-B384-3B1CE60EA647}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ <RootNamespace>imaging</RootNamespace>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="..\libavg.props" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="..\libavg.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <IncludePath>$(MSBuildProgramFiles32)\CMU\1394Camera\include;$(IncludePath)</IncludePath>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <LibraryPath>$(LibraryPath)</LibraryPath>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <Optimization>MaxSpeed</Optimization>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <PreprocessorDefinitions>NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ </Link>
+ <Lib>
+ <AdditionalDependencies>
+ </AdditionalDependencies>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\src\imaging\Blob.cpp" />
+ <ClCompile Include="..\..\src\imaging\Camera.cpp" />
+ <ClCompile Include="..\..\src\imaging\CameraInfo.cpp" />
+ <ClCompile Include="..\..\src\imaging\checktracking.cpp" />
+ <ClCompile Include="..\..\src\imaging\CMUCamera.cpp" />
+ <ClCompile Include="..\..\src\imaging\CMUCameraUtils.cpp" />
+ <ClCompile Include="..\..\src\imaging\CoordTransformer.cpp" />
+ <ClCompile Include="..\..\src\imaging\DeDistort.cpp" />
+ <ClCompile Include="..\..\src\imaging\DSCamera.cpp" />
+ <ClCompile Include="..\..\src\imaging\DSHelper.cpp" />
+ <ClCompile Include="..\..\src\imaging\DSSampleGrabber.cpp" />
+ <ClCompile Include="..\..\src\imaging\FakeCamera.cpp" />
+ <ClCompile Include="..\..\src\imaging\FilterClearBorder.cpp" />
+ <ClCompile Include="..\..\src\imaging\FilterDistortion.cpp" />
+ <ClCompile Include="..\..\src\imaging\FilterWipeBorder.cpp" />
+ <ClCompile Include="..\..\src\imaging\FWCamera.cpp" />
+ <ClCompile Include="..\..\src\imaging\Run.cpp" />
+ <ClCompile Include="..\..\src\imaging\TrackerConfig.cpp" />
+ <ClCompile Include="..\..\src\imaging\trackerconfigdtd.cpp" />
+ <ClCompile Include="..\..\src\imaging\TrackerThread.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\src\imaging\Blob.h" />
+ <ClInclude Include="..\..\src\imaging\Camera.h" />
+ <ClInclude Include="..\..\src\imaging\CameraInfo.h" />
+ <ClInclude Include="..\..\src\imaging\CMUCamera.h" />
+ <ClInclude Include="..\..\src\imaging\CMUCameraUtils.h" />
+ <ClInclude Include="..\..\src\imaging\CoordTransformer.h" />
+ <ClInclude Include="..\..\src\imaging\DeDistort.h" />
+ <ClInclude Include="..\..\src\imaging\DSCamera.h" />
+ <ClInclude Include="..\..\src\imaging\DSHelper.h" />
+ <ClInclude Include="..\..\src\imaging\DSSampleGrabber.h" />
+ <ClInclude Include="..\..\src\imaging\FakeCamera.h" />
+ <ClInclude Include="..\..\src\imaging\FilterClearBorder.h" />
+ <ClInclude Include="..\..\src\imaging\FilterDistortion.h" />
+ <ClInclude Include="..\..\src\imaging\FilterWipeBorder.h" />
+ <ClInclude Include="..\..\src\imaging\FWCamera.h" />
+ <ClInclude Include="..\..\src\imaging\FWCameraUtils.h" />
+ <ClInclude Include="..\..\src\imaging\IDSSampleCallback.h" />
+ <ClInclude Include="..\..\src\imaging\qedit.h" />
+ <ClInclude Include="..\..\src\imaging\Run.h" />
+ <ClInclude Include="..\..\src\imaging\TrackerConfig.h" />
+ <ClInclude Include="..\..\src\imaging\trackerconfigdtd.h" />
+ <ClInclude Include="..\..\src\imaging\TrackerThread.h" />
+ <ClInclude Include="..\..\src\imaging\V4LCamera.h" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/win/libavg.props b/win/libavg.props
new file mode 100755
index 0000000..f0b13b5
--- /dev/null
+++ b/win/libavg.props
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ImportGroup Label="PropertySheets" />
+ <PropertyGroup Label="UserMacros">
+ <PYTHON_ROOT>C:\Python27</PYTHON_ROOT>
+ </PropertyGroup>
+ <PropertyGroup>
+ <IncludePath>$(PYTHON_ROOT)\include;..\..\..\include;$(IncludePath)</IncludePath>
+ <LibraryPath>$(PYTHON_ROOT)\libs;..\Release;..\..\..\lib;$(MSBuildProgramFiles32)\CMU\1394Camera\lib;$(LibraryPath)</LibraryPath>
+ </PropertyGroup>
+ <ItemDefinitionGroup>
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup>
+ <ClCompile>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <PreprocessorDefinitions>WIN32;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;BOOST_PYTHON_DYNAMIC_LIB;BOOST_ALL_DYN_LINK;WIN32_LEAN_AND_MEAN</PreprocessorDefinitions>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <FloatingPointModel>Fast</FloatingPointModel>
+ <RuntimeTypeInfo>true</RuntimeTypeInfo>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>dbghelp.lib;psapi.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration>
+ </Link>
+ <Lib>
+ <AdditionalOptions>/IGNORE:4006 %(AdditionalOptions)</AdditionalOptions>
+ <LinkTimeCodeGeneration>false</LinkTimeCodeGeneration>
+ </Lib>
+ <ProjectReference>
+ <LinkLibraryDependencies>false</LinkLibraryDependencies>
+ </ProjectReference>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <BuildMacro Include="PYTHON_ROOT">
+ <Value>$(PYTHON_ROOT)</Value>
+ <EnvironmentVariable>true</EnvironmentVariable>
+ </BuildMacro>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/win/libavg.sln b/win/libavg.sln
new file mode 100755
index 0000000..b42f33f
--- /dev/null
+++ b/win/libavg.sln
@@ -0,0 +1,191 @@
+
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual C++ Express 2010
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "base", "base\base.vcxproj", "{4B3614A9-4CF5-4C14-9F71-4254B7988324}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testbase", "testbase\testbase.vcxproj", "{775830D7-7FD4-401B-B650-01376DE4D192}"
+ ProjectSection(ProjectDependencies) = postProject
+ {4B3614A9-4CF5-4C14-9F71-4254B7988324} = {4B3614A9-4CF5-4C14-9F71-4254B7988324}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "graphics", "graphics\graphics.vcxproj", "{9B9F3907-0C54-4FF4-AAF3-8FDA3496DB88}"
+ ProjectSection(ProjectDependencies) = postProject
+ {4B3614A9-4CF5-4C14-9F71-4254B7988324} = {4B3614A9-4CF5-4C14-9F71-4254B7988324}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testgraphics", "testgraphics\testgraphics.vcxproj", "{C8174AA7-D062-4337-B740-90460C16FD86}"
+ ProjectSection(ProjectDependencies) = postProject
+ {9B9F3907-0C54-4FF4-AAF3-8FDA3496DB88} = {9B9F3907-0C54-4FF4-AAF3-8FDA3496DB88}
+ {4B3614A9-4CF5-4C14-9F71-4254B7988324} = {4B3614A9-4CF5-4C14-9F71-4254B7988324}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testgpu", "testgpu\testgpu.vcxproj", "{C7F16268-E53F-4E2C-A283-0475EA113745}"
+ ProjectSection(ProjectDependencies) = postProject
+ {9B9F3907-0C54-4FF4-AAF3-8FDA3496DB88} = {9B9F3907-0C54-4FF4-AAF3-8FDA3496DB88}
+ {4B3614A9-4CF5-4C14-9F71-4254B7988324} = {4B3614A9-4CF5-4C14-9F71-4254B7988324}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "audio", "audio\audio.vcxproj", "{D0C1A58C-BF0E-4F88-885A-65444A23516E}"
+ ProjectSection(ProjectDependencies) = postProject
+ {4B3614A9-4CF5-4C14-9F71-4254B7988324} = {4B3614A9-4CF5-4C14-9F71-4254B7988324}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testlimiter", "testlimiter\testlimiter.vcxproj", "{3D8F042E-55B5-40D9-818A-C51B3D2A6368}"
+ ProjectSection(ProjectDependencies) = postProject
+ {D0C1A58C-BF0E-4F88-885A-65444A23516E} = {D0C1A58C-BF0E-4F88-885A-65444A23516E}
+ {4B3614A9-4CF5-4C14-9F71-4254B7988324} = {4B3614A9-4CF5-4C14-9F71-4254B7988324}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "imaging", "imaging\imaging.vcxproj", "{669BEA02-213C-4387-B384-3B1CE60EA647}"
+ ProjectSection(ProjectDependencies) = postProject
+ {9B9F3907-0C54-4FF4-AAF3-8FDA3496DB88} = {9B9F3907-0C54-4FF4-AAF3-8FDA3496DB88}
+ {4B3614A9-4CF5-4C14-9F71-4254B7988324} = {4B3614A9-4CF5-4C14-9F71-4254B7988324}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testimaging", "testimaging\testimaging.vcxproj", "{B2ED4D82-E0C8-482E-93CD-B3546EDC9D56}"
+ ProjectSection(ProjectDependencies) = postProject
+ {669BEA02-213C-4387-B384-3B1CE60EA647} = {669BEA02-213C-4387-B384-3B1CE60EA647}
+ {9B9F3907-0C54-4FF4-AAF3-8FDA3496DB88} = {9B9F3907-0C54-4FF4-AAF3-8FDA3496DB88}
+ {4B3614A9-4CF5-4C14-9F71-4254B7988324} = {4B3614A9-4CF5-4C14-9F71-4254B7988324}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lmfit", "lmfit\lmfit.vcxproj", "{8B473FDD-CC57-453D-A037-107D8E8C4E8C}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "video", "video\video.vcxproj", "{016C3620-D5BD-4138-97E4-C0AD38E32EB2}"
+ ProjectSection(ProjectDependencies) = postProject
+ {9B9F3907-0C54-4FF4-AAF3-8FDA3496DB88} = {9B9F3907-0C54-4FF4-AAF3-8FDA3496DB88}
+ {D0C1A58C-BF0E-4F88-885A-65444A23516E} = {D0C1A58C-BF0E-4F88-885A-65444A23516E}
+ {4B3614A9-4CF5-4C14-9F71-4254B7988324} = {4B3614A9-4CF5-4C14-9F71-4254B7988324}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testvideo", "testvideo\testvideo.vcxproj", "{9247BEBF-91E4-4AEE-989C-94A9D731E9ED}"
+ ProjectSection(ProjectDependencies) = postProject
+ {9B9F3907-0C54-4FF4-AAF3-8FDA3496DB88} = {9B9F3907-0C54-4FF4-AAF3-8FDA3496DB88}
+ {016C3620-D5BD-4138-97E4-C0AD38E32EB2} = {016C3620-D5BD-4138-97E4-C0AD38E32EB2}
+ {D0C1A58C-BF0E-4F88-885A-65444A23516E} = {D0C1A58C-BF0E-4F88-885A-65444A23516E}
+ {4B3614A9-4CF5-4C14-9F71-4254B7988324} = {4B3614A9-4CF5-4C14-9F71-4254B7988324}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "player", "player\player.vcxproj", "{545732F5-BD6B-4C05-9A9B-4D6D0C31BD13}"
+ ProjectSection(ProjectDependencies) = postProject
+ {669BEA02-213C-4387-B384-3B1CE60EA647} = {669BEA02-213C-4387-B384-3B1CE60EA647}
+ {9B9F3907-0C54-4FF4-AAF3-8FDA3496DB88} = {9B9F3907-0C54-4FF4-AAF3-8FDA3496DB88}
+ {016C3620-D5BD-4138-97E4-C0AD38E32EB2} = {016C3620-D5BD-4138-97E4-C0AD38E32EB2}
+ {D0C1A58C-BF0E-4F88-885A-65444A23516E} = {D0C1A58C-BF0E-4F88-885A-65444A23516E}
+ {4B3614A9-4CF5-4C14-9F71-4254B7988324} = {4B3614A9-4CF5-4C14-9F71-4254B7988324}
+ {7BA3D8D4-985D-4070-91B4-AC442C4ADE27} = {7BA3D8D4-985D-4070-91B4-AC442C4ADE27}
+ {8B473FDD-CC57-453D-A037-107D8E8C4E8C} = {8B473FDD-CC57-453D-A037-107D8E8C4E8C}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testplayer", "testplayer\testplayer.vcxproj", "{3FBD021A-344A-459A-A3DD-234AFCC17808}"
+ ProjectSection(ProjectDependencies) = postProject
+ {669BEA02-213C-4387-B384-3B1CE60EA647} = {669BEA02-213C-4387-B384-3B1CE60EA647}
+ {9B9F3907-0C54-4FF4-AAF3-8FDA3496DB88} = {9B9F3907-0C54-4FF4-AAF3-8FDA3496DB88}
+ {016C3620-D5BD-4138-97E4-C0AD38E32EB2} = {016C3620-D5BD-4138-97E4-C0AD38E32EB2}
+ {D0C1A58C-BF0E-4F88-885A-65444A23516E} = {D0C1A58C-BF0E-4F88-885A-65444A23516E}
+ {4B3614A9-4CF5-4C14-9F71-4254B7988324} = {4B3614A9-4CF5-4C14-9F71-4254B7988324}
+ {8B473FDD-CC57-453D-A037-107D8E8C4E8C} = {8B473FDD-CC57-453D-A037-107D8E8C4E8C}
+ {545732F5-BD6B-4C05-9A9B-4D6D0C31BD13} = {545732F5-BD6B-4C05-9A9B-4D6D0C31BD13}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "oscpack", "oscpack\oscpack.vcxproj", "{7BA3D8D4-985D-4070-91B4-AC442C4ADE27}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wrapper", "wrapper\wrapper.vcxproj", "{0AFC225A-A1CF-463E-A516-BF9A0D2F554B}"
+ ProjectSection(ProjectDependencies) = postProject
+ {545732F5-BD6B-4C05-9A9B-4D6D0C31BD13} = {545732F5-BD6B-4C05-9A9B-4D6D0C31BD13}
+ {A8BAD8F9-6DAA-4C23-9AD8-55552A6B8D4E} = {A8BAD8F9-6DAA-4C23-9AD8-55552A6B8D4E}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "anim", "anim\anim.vcxproj", "{A8BAD8F9-6DAA-4C23-9AD8-55552A6B8D4E}"
+ ProjectSection(ProjectDependencies) = postProject
+ {545732F5-BD6B-4C05-9A9B-4D6D0C31BD13} = {545732F5-BD6B-4C05-9A9B-4D6D0C31BD13}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testplugin", "testplugin\testplugin.vcxproj", "{B51101B0-9DFF-40D0-AFC1-5E41E67C0F73}"
+ ProjectSection(ProjectDependencies) = postProject
+ {0AFC225A-A1CF-463E-A516-BF9A0D2F554B} = {0AFC225A-A1CF-463E-A516-BF9A0D2F554B}
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {4B3614A9-4CF5-4C14-9F71-4254B7988324}.Debug|Win32.ActiveCfg = Debug|Win32
+ {4B3614A9-4CF5-4C14-9F71-4254B7988324}.Debug|Win32.Build.0 = Debug|Win32
+ {4B3614A9-4CF5-4C14-9F71-4254B7988324}.Release|Win32.ActiveCfg = Release|Win32
+ {4B3614A9-4CF5-4C14-9F71-4254B7988324}.Release|Win32.Build.0 = Release|Win32
+ {775830D7-7FD4-401B-B650-01376DE4D192}.Debug|Win32.ActiveCfg = Debug|Win32
+ {775830D7-7FD4-401B-B650-01376DE4D192}.Debug|Win32.Build.0 = Debug|Win32
+ {775830D7-7FD4-401B-B650-01376DE4D192}.Release|Win32.ActiveCfg = Release|Win32
+ {775830D7-7FD4-401B-B650-01376DE4D192}.Release|Win32.Build.0 = Release|Win32
+ {9B9F3907-0C54-4FF4-AAF3-8FDA3496DB88}.Debug|Win32.ActiveCfg = Debug|Win32
+ {9B9F3907-0C54-4FF4-AAF3-8FDA3496DB88}.Debug|Win32.Build.0 = Debug|Win32
+ {9B9F3907-0C54-4FF4-AAF3-8FDA3496DB88}.Release|Win32.ActiveCfg = Release|Win32
+ {9B9F3907-0C54-4FF4-AAF3-8FDA3496DB88}.Release|Win32.Build.0 = Release|Win32
+ {C8174AA7-D062-4337-B740-90460C16FD86}.Debug|Win32.ActiveCfg = Debug|Win32
+ {C8174AA7-D062-4337-B740-90460C16FD86}.Debug|Win32.Build.0 = Debug|Win32
+ {C8174AA7-D062-4337-B740-90460C16FD86}.Release|Win32.ActiveCfg = Release|Win32
+ {C8174AA7-D062-4337-B740-90460C16FD86}.Release|Win32.Build.0 = Release|Win32
+ {C7F16268-E53F-4E2C-A283-0475EA113745}.Debug|Win32.ActiveCfg = Debug|Win32
+ {C7F16268-E53F-4E2C-A283-0475EA113745}.Debug|Win32.Build.0 = Debug|Win32
+ {C7F16268-E53F-4E2C-A283-0475EA113745}.Release|Win32.ActiveCfg = Release|Win32
+ {C7F16268-E53F-4E2C-A283-0475EA113745}.Release|Win32.Build.0 = Release|Win32
+ {D0C1A58C-BF0E-4F88-885A-65444A23516E}.Debug|Win32.ActiveCfg = Debug|Win32
+ {D0C1A58C-BF0E-4F88-885A-65444A23516E}.Debug|Win32.Build.0 = Debug|Win32
+ {D0C1A58C-BF0E-4F88-885A-65444A23516E}.Release|Win32.ActiveCfg = Release|Win32
+ {D0C1A58C-BF0E-4F88-885A-65444A23516E}.Release|Win32.Build.0 = Release|Win32
+ {3D8F042E-55B5-40D9-818A-C51B3D2A6368}.Debug|Win32.ActiveCfg = Debug|Win32
+ {3D8F042E-55B5-40D9-818A-C51B3D2A6368}.Debug|Win32.Build.0 = Debug|Win32
+ {3D8F042E-55B5-40D9-818A-C51B3D2A6368}.Release|Win32.ActiveCfg = Release|Win32
+ {3D8F042E-55B5-40D9-818A-C51B3D2A6368}.Release|Win32.Build.0 = Release|Win32
+ {669BEA02-213C-4387-B384-3B1CE60EA647}.Debug|Win32.ActiveCfg = Debug|Win32
+ {669BEA02-213C-4387-B384-3B1CE60EA647}.Debug|Win32.Build.0 = Debug|Win32
+ {669BEA02-213C-4387-B384-3B1CE60EA647}.Release|Win32.ActiveCfg = Release|Win32
+ {669BEA02-213C-4387-B384-3B1CE60EA647}.Release|Win32.Build.0 = Release|Win32
+ {B2ED4D82-E0C8-482E-93CD-B3546EDC9D56}.Debug|Win32.ActiveCfg = Debug|Win32
+ {B2ED4D82-E0C8-482E-93CD-B3546EDC9D56}.Debug|Win32.Build.0 = Debug|Win32
+ {B2ED4D82-E0C8-482E-93CD-B3546EDC9D56}.Release|Win32.ActiveCfg = Release|Win32
+ {B2ED4D82-E0C8-482E-93CD-B3546EDC9D56}.Release|Win32.Build.0 = Release|Win32
+ {8B473FDD-CC57-453D-A037-107D8E8C4E8C}.Debug|Win32.ActiveCfg = Debug|Win32
+ {8B473FDD-CC57-453D-A037-107D8E8C4E8C}.Debug|Win32.Build.0 = Debug|Win32
+ {8B473FDD-CC57-453D-A037-107D8E8C4E8C}.Release|Win32.ActiveCfg = Release|Win32
+ {8B473FDD-CC57-453D-A037-107D8E8C4E8C}.Release|Win32.Build.0 = Release|Win32
+ {016C3620-D5BD-4138-97E4-C0AD38E32EB2}.Debug|Win32.ActiveCfg = Debug|Win32
+ {016C3620-D5BD-4138-97E4-C0AD38E32EB2}.Debug|Win32.Build.0 = Debug|Win32
+ {016C3620-D5BD-4138-97E4-C0AD38E32EB2}.Release|Win32.ActiveCfg = Release|Win32
+ {016C3620-D5BD-4138-97E4-C0AD38E32EB2}.Release|Win32.Build.0 = Release|Win32
+ {9247BEBF-91E4-4AEE-989C-94A9D731E9ED}.Debug|Win32.ActiveCfg = Debug|Win32
+ {9247BEBF-91E4-4AEE-989C-94A9D731E9ED}.Debug|Win32.Build.0 = Debug|Win32
+ {9247BEBF-91E4-4AEE-989C-94A9D731E9ED}.Release|Win32.ActiveCfg = Release|Win32
+ {9247BEBF-91E4-4AEE-989C-94A9D731E9ED}.Release|Win32.Build.0 = Release|Win32
+ {545732F5-BD6B-4C05-9A9B-4D6D0C31BD13}.Debug|Win32.ActiveCfg = Debug|Win32
+ {545732F5-BD6B-4C05-9A9B-4D6D0C31BD13}.Debug|Win32.Build.0 = Debug|Win32
+ {545732F5-BD6B-4C05-9A9B-4D6D0C31BD13}.Release|Win32.ActiveCfg = Release|Win32
+ {545732F5-BD6B-4C05-9A9B-4D6D0C31BD13}.Release|Win32.Build.0 = Release|Win32
+ {3FBD021A-344A-459A-A3DD-234AFCC17808}.Debug|Win32.ActiveCfg = Debug|Win32
+ {3FBD021A-344A-459A-A3DD-234AFCC17808}.Debug|Win32.Build.0 = Debug|Win32
+ {3FBD021A-344A-459A-A3DD-234AFCC17808}.Release|Win32.ActiveCfg = Release|Win32
+ {3FBD021A-344A-459A-A3DD-234AFCC17808}.Release|Win32.Build.0 = Release|Win32
+ {7BA3D8D4-985D-4070-91B4-AC442C4ADE27}.Debug|Win32.ActiveCfg = Debug|Win32
+ {7BA3D8D4-985D-4070-91B4-AC442C4ADE27}.Debug|Win32.Build.0 = Debug|Win32
+ {7BA3D8D4-985D-4070-91B4-AC442C4ADE27}.Release|Win32.ActiveCfg = Release|Win32
+ {7BA3D8D4-985D-4070-91B4-AC442C4ADE27}.Release|Win32.Build.0 = Release|Win32
+ {0AFC225A-A1CF-463E-A516-BF9A0D2F554B}.Debug|Win32.ActiveCfg = Debug|Win32
+ {0AFC225A-A1CF-463E-A516-BF9A0D2F554B}.Debug|Win32.Build.0 = Debug|Win32
+ {0AFC225A-A1CF-463E-A516-BF9A0D2F554B}.Release|Win32.ActiveCfg = Release|Win32
+ {0AFC225A-A1CF-463E-A516-BF9A0D2F554B}.Release|Win32.Build.0 = Release|Win32
+ {A8BAD8F9-6DAA-4C23-9AD8-55552A6B8D4E}.Debug|Win32.ActiveCfg = Debug|Win32
+ {A8BAD8F9-6DAA-4C23-9AD8-55552A6B8D4E}.Debug|Win32.Build.0 = Debug|Win32
+ {A8BAD8F9-6DAA-4C23-9AD8-55552A6B8D4E}.Release|Win32.ActiveCfg = Release|Win32
+ {A8BAD8F9-6DAA-4C23-9AD8-55552A6B8D4E}.Release|Win32.Build.0 = Release|Win32
+ {B51101B0-9DFF-40D0-AFC1-5E41E67C0F73}.Debug|Win32.ActiveCfg = Debug|Win32
+ {B51101B0-9DFF-40D0-AFC1-5E41E67C0F73}.Debug|Win32.Build.0 = Debug|Win32
+ {B51101B0-9DFF-40D0-AFC1-5E41E67C0F73}.Release|Win32.ActiveCfg = Release|Win32
+ {B51101B0-9DFF-40D0-AFC1-5E41E67C0F73}.Release|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/win/lmfit/lmfit.vcxproj b/win/lmfit/lmfit.vcxproj
new file mode 100644
index 0000000..00058c6
--- /dev/null
+++ b/win/lmfit/lmfit.vcxproj
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{8B473FDD-CC57-453D-A037-107D8E8C4E8C}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ <RootNamespace>lmfit</RootNamespace>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="..\libavg.props" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="..\libavg.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup />
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <Optimization>MaxSpeed</Optimization>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <PreprocessorDefinitions>NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\src\lmfit\lmmin.c" />
+ <ClCompile Include="..\..\src\lmfit\lm_eval.c" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\src\lmfit\lmmin.h" />
+ <ClInclude Include="..\..\src\lmfit\lm_eval.h" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/win/oscpack/oscpack.vcxproj b/win/oscpack/oscpack.vcxproj
new file mode 100644
index 0000000..c4374cb
--- /dev/null
+++ b/win/oscpack/oscpack.vcxproj
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{7BA3D8D4-985D-4070-91B4-AC442C4ADE27}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ <RootNamespace>oscpack</RootNamespace>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="..\libavg.props" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="..\libavg.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup />
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <Optimization>MaxSpeed</Optimization>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <PreprocessorDefinitions>NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ </Link>
+ <Lib>
+ <AdditionalDependencies>Ws2_32.lib</AdditionalDependencies>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <None Include="ReadMe.txt" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\src\oscpack\IpEndpointName.h" />
+ <ClInclude Include="..\..\src\oscpack\MessageMappingOscPacketListener.h" />
+ <ClInclude Include="..\..\src\oscpack\NetworkingUtils.h" />
+ <ClInclude Include="..\..\src\oscpack\OscException.h" />
+ <ClInclude Include="..\..\src\oscpack\OscHostEndianness.h" />
+ <ClInclude Include="..\..\src\oscpack\OscOutboundPacketStream.h" />
+ <ClInclude Include="..\..\src\oscpack\OscPacketListener.h" />
+ <ClInclude Include="..\..\src\oscpack\OscPrintReceivedElements.h" />
+ <ClInclude Include="..\..\src\oscpack\OscReceivedElements.h" />
+ <ClInclude Include="..\..\src\oscpack\OscTypes.h" />
+ <ClInclude Include="..\..\src\oscpack\PacketListener.h" />
+ <ClInclude Include="..\..\src\oscpack\TimerListener.h" />
+ <ClInclude Include="..\..\src\oscpack\UdpSocket.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\src\oscpack\IpEndpointName.cpp" />
+ <ClCompile Include="..\..\src\oscpack\NetworkingUtils.cpp" />
+ <ClCompile Include="..\..\src\oscpack\OscOutboundPacketStream.cpp" />
+ <ClCompile Include="..\..\src\oscpack\OscPrintReceivedElements.cpp" />
+ <ClCompile Include="..\..\src\oscpack\OscReceivedElements.cpp" />
+ <ClCompile Include="..\..\src\oscpack\OscTypes.cpp" />
+ <ClCompile Include="..\..\src\oscpack\UdpSocket.cpp" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/win/player/player.vcxproj b/win/player/player.vcxproj
new file mode 100644
index 0000000..2054961
--- /dev/null
+++ b/win/player/player.vcxproj
@@ -0,0 +1,238 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{545732F5-BD6B-4C05-9A9B-4D6D0C31BD13}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ <RootNamespace>player</RootNamespace>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="..\libavg.props" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="..\libavg.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup />
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <PreprocessorDefinitions>NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ </Link>
+ <Lib>
+ <AdditionalDependencies>
+ </AdditionalDependencies>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\src\player\AreaNode.cpp" />
+ <ClCompile Include="..\..\src\player\ArgBase.cpp" />
+ <ClCompile Include="..\..\src\player\ArgList.cpp" />
+ <ClCompile Include="..\..\src\player\AVGNode.cpp" />
+ <ClCompile Include="..\..\src\player\BitmapManager.cpp" />
+ <ClCompile Include="..\..\src\player\BitmapManagerMsg.cpp" />
+ <ClCompile Include="..\..\src\player\BitmapManagerThread.cpp" />
+ <ClCompile Include="..\..\src\player\BlurFXNode.cpp" />
+ <ClCompile Include="..\..\src\player\CameraNode.cpp" />
+ <ClCompile Include="..\..\src\player\Canvas.cpp" />
+ <ClCompile Include="..\..\src\player\CanvasNode.cpp" />
+ <ClCompile Include="..\..\src\player\ChromaKeyFXNode.cpp" />
+ <ClCompile Include="..\..\src\player\CircleNode.cpp" />
+ <ClCompile Include="..\..\src\player\Contact.cpp" />
+ <ClCompile Include="..\..\src\player\CursorEvent.cpp" />
+ <ClCompile Include="..\..\src\player\CursorState.cpp" />
+ <ClCompile Include="..\..\src\player\CurveNode.cpp" />
+ <ClCompile Include="..\..\src\player\DisplayEngine.cpp" />
+ <ClCompile Include="..\..\src\player\DisplayParams.cpp" />
+ <ClCompile Include="..\..\src\player\DivNode.cpp" />
+ <ClCompile Include="..\..\src\player\Event.cpp" />
+ <ClCompile Include="..\..\src\player\EventDispatcher.cpp" />
+ <ClCompile Include="..\..\src\player\ExportedObject.cpp" />
+ <ClCompile Include="..\..\src\player\FilledVectorNode.cpp" />
+ <ClCompile Include="..\..\src\player\FontStyle.cpp" />
+ <ClCompile Include="..\..\src\player\FXNode.cpp" />
+ <ClCompile Include="..\..\src\player\HueSatFXNode.cpp" />
+ <ClCompile Include="..\..\src\player\InvertFXNode.cpp" />
+ <ClCompile Include="..\..\src\player\Image.cpp" />
+ <ClCompile Include="..\..\src\player\ImageNode.cpp" />
+ <ClCompile Include="..\..\src\player\KeyEvent.cpp" />
+ <ClCompile Include="..\..\src\player\LineNode.cpp" />
+ <ClCompile Include="..\..\src\player\MainCanvas.cpp" />
+ <ClCompile Include="..\..\src\player\MaterialInfo.cpp" />
+ <ClCompile Include="..\..\src\player\MeshNode.cpp" />
+ <ClCompile Include="..\..\src\player\MessageID.cpp" />
+ <ClCompile Include="..\..\src\player\MouseEvent.cpp" />
+ <ClCompile Include="..\..\src\player\MultitouchInputDevice.cpp" />
+ <ClCompile Include="..\..\src\player\Node.cpp" />
+ <ClCompile Include="..\..\src\player\NullFXNode.cpp" />
+ <ClCompile Include="..\..\src\player\OffscreenCanvas.cpp" />
+ <ClCompile Include="..\..\src\player\OffscreenCanvasNode.cpp" />
+ <ClCompile Include="..\..\src\player\OGLSurface.cpp" />
+ <ClCompile Include="..\..\src\player\Player.cpp" />
+ <ClCompile Include="..\..\src\player\PluginManager.cpp" />
+ <ClCompile Include="..\..\src\player\PolygonNode.cpp" />
+ <ClCompile Include="..\..\src\player\PolyLineNode.cpp" />
+ <ClCompile Include="..\..\src\player\Publisher.cpp" />
+ <ClCompile Include="..\..\src\player\PublisherDefinition.cpp" />
+ <ClCompile Include="..\..\src\player\PublisherDefinitionRegistry.cpp" />
+ <ClCompile Include="..\..\src\player\PythonLogSink.cpp" />
+ <ClCompile Include="..\..\src\player\RasterNode.cpp" />
+ <ClCompile Include="..\..\src\player\RectNode.cpp" />
+ <ClCompile Include="..\..\src\player\SDLDisplayEngine.cpp" />
+ <ClCompile Include="..\..\src\player\ShadowFXNode.cpp" />
+ <ClCompile Include="..\..\src\player\Shape.cpp" />
+ <ClCompile Include="..\..\src\player\SoundNode.cpp" />
+ <ClCompile Include="..\..\src\player\SubscriberInfo.cpp" />
+ <ClCompile Include="..\..\src\player\SVG.cpp" />
+ <ClCompile Include="..\..\src\player\SVGElement.cpp" />
+ <ClCompile Include="..\..\src\player\TestHelper.cpp" />
+ <ClCompile Include="..\..\src\player\TextEngine.cpp" />
+ <ClCompile Include="..\..\src\player\Timeout.cpp" />
+ <ClCompile Include="..\..\src\player\TouchEvent.cpp" />
+ <ClCompile Include="..\..\src\player\TouchStatus.cpp" />
+ <ClCompile Include="..\..\src\player\TrackerCalibrator.cpp" />
+ <ClCompile Include="..\..\src\player\TrackerInputDevice.cpp" />
+ <ClCompile Include="..\..\src\player\TrackerTouchStatus.cpp" />
+ <ClCompile Include="..\..\src\player\TUIOInputDevice.cpp" />
+ <ClCompile Include="..\..\src\player\TypeDefinition.cpp" />
+ <ClCompile Include="..\..\src\player\TypeRegistry.cpp" />
+ <ClCompile Include="..\..\src\player\VectorNode.cpp" />
+ <ClCompile Include="..\..\src\player\VersionInfo.cpp" />
+ <ClCompile Include="..\..\src\player\VideoNode.cpp" />
+ <ClCompile Include="..\..\src\player\VideoWriter.cpp" />
+ <ClCompile Include="..\..\src\player\VideoWriterThread.cpp" />
+ <ClCompile Include="..\..\src\player\Win7TouchInputDevice.cpp" />
+ <ClCompile Include="..\..\src\player\WordsNode.cpp" />
+ <ClCompile Include="..\..\src\player\WrapPython.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\src\player\AreaNode.h" />
+ <ClInclude Include="..\..\src\player\Arg.h" />
+ <ClInclude Include="..\..\src\player\ArgBase.h" />
+ <ClInclude Include="..\..\src\player\ArgList.h" />
+ <ClInclude Include="..\..\src\player\AVGNode.h" />
+ <ClInclude Include="..\..\src\player\BitmapManager.h" />
+ <ClInclude Include="..\..\src\player\BitmapManagerMsg.h" />
+ <ClInclude Include="..\..\src\player\BitmapManagerThread.h" />
+ <ClInclude Include="..\..\src\player\BlurFXNode.h" />
+ <ClInclude Include="..\..\src\player\BoostPython.h" />
+ <ClInclude Include="..\..\src\player\CameraNode.h" />
+ <ClInclude Include="..\..\src\player\Canvas.h" />
+ <ClInclude Include="..\..\src\player\CanvasNode.h" />
+ <ClInclude Include="..\..\src\player\ChromaKeyFXNode.h" />
+ <ClInclude Include="..\..\src\player\CircleNode.h" />
+ <ClInclude Include="..\..\src\player\Contact.h" />
+ <ClInclude Include="..\..\src\player\CursorEvent.h" />
+ <ClInclude Include="..\..\src\player\CursorState.h" />
+ <ClInclude Include="..\..\src\player\CurveNode.h" />
+ <ClInclude Include="..\..\src\player\DisplayEngine.h" />
+ <ClInclude Include="..\..\src\player\DisplayParams.h" />
+ <ClInclude Include="..\..\src\player\DivNode.h" />
+ <ClInclude Include="..\..\src\player\Event.h" />
+ <ClInclude Include="..\..\src\player\EventDispatcher.h" />
+ <ClInclude Include="..\..\src\player\ExportedObject.h" />
+ <ClInclude Include="..\..\src\player\FilledVectorNode.h" />
+ <ClInclude Include="..\..\src\player\FontStyle.h" />
+ <ClInclude Include="..\..\src\player\FXNode.h" />
+ <ClInclude Include="..\..\src\player\HueSatFXNode.h" />
+ <ClInclude Include="..\..\src\player\InvertFXNode.h" />
+ <ClInclude Include="..\..\src\player\IInputDevice.h" />
+ <ClInclude Include="..\..\src\player\Image.h" />
+ <ClInclude Include="..\..\src\player\ImageNode.h" />
+ <ClInclude Include="..\..\src\player\KeyEvent.h" />
+ <ClInclude Include="..\..\src\player\LineNode.h" />
+ <ClInclude Include="..\..\src\player\MainCanvas.h" />
+ <ClInclude Include="..\..\src\player\MaterialInfo.h" />
+ <ClInclude Include="..\..\src\player\MeshNode.h" />
+ <ClInclude Include="..\..\src\player\MessageID.h" />
+ <ClInclude Include="..\..\src\player\MouseEvent.h" />
+ <ClInclude Include="..\..\src\player\MultitouchInputDevice.h" />
+ <ClInclude Include="..\..\src\player\Node.h" />
+ <ClInclude Include="..\..\src\player\NullFXNode.h" />
+ <ClInclude Include="..\..\src\player\OffscreenCanvas.h" />
+ <ClInclude Include="..\..\src\player\OffscreenCanvasNode.h" />
+ <ClInclude Include="..\..\src\player\OGLSurface.h" />
+ <ClInclude Include="..\..\src\player\Player.h" />
+ <ClInclude Include="..\..\src\player\PluginManager.h" />
+ <ClInclude Include="..\..\src\player\PolygonNode.h" />
+ <ClInclude Include="..\..\src\player\PolyLineNode.h" />
+ <ClInclude Include="..\..\src\player\Publisher.h" />
+ <ClInclude Include="..\..\src\player\PublisherDefinition.h" />
+ <ClInclude Include="..\..\src\player\PublisherDefinitionRegistry.h" />
+ <ClInclude Include="..\..\src\player\PythonLogSink.h" />
+ <ClInclude Include="..\..\src\player\RasterNode.h" />
+ <ClInclude Include="..\..\src\player\RectNode.h" />
+ <ClInclude Include="..\..\src\player\SDLDisplayEngine.h" />
+ <ClInclude Include="..\..\src\player\SDLMain.h" />
+ <ClInclude Include="..\..\src\player\ShadowFXNode.h" />
+ <ClInclude Include="..\..\src\player\Shape.h" />
+ <ClInclude Include="..\..\src\player\SoundNode.h" />
+ <ClInclude Include="..\..\src\player\SubscriberInfo.h" />
+ <ClInclude Include="..\..\src\player\SVG.h" />
+ <ClInclude Include="..\..\src\player\SVGElement.h" />
+ <ClInclude Include="..\..\src\player\TestHelper.h" />
+ <ClInclude Include="..\..\src\player\TextEngine.h" />
+ <ClInclude Include="..\..\src\player\Timeout.h" />
+ <ClInclude Include="..\..\src\player\TouchEvent.h" />
+ <ClInclude Include="..\..\src\player\TouchStatus.h" />
+ <ClInclude Include="..\..\src\player\TrackerCalibrator.h" />
+ <ClInclude Include="..\..\src\player\TrackerInputDevice.h" />
+ <ClInclude Include="..\..\src\player\TrackerTouchStatus.h" />
+ <ClInclude Include="..\..\src\player\TUIOInputDevice.h" />
+ <ClInclude Include="..\..\src\player\TypeDefinition.h" />
+ <ClInclude Include="..\..\src\player\TypeRegistry.h" />
+ <ClInclude Include="..\..\src\player\VectorNode.h" />
+ <ClInclude Include="..\..\src\player\VersionInfo.h" />
+ <ClInclude Include="..\..\src\player\VideoNode.h" />
+ <ClInclude Include="..\..\src\player\VideoWriter.h" />
+ <ClInclude Include="..\..\src\player\VideoWriterThread.h" />
+ <ClInclude Include="..\..\src\player\Win7TouchInputDevice.h" />
+ <ClInclude Include="..\..\src\player\WordsNode.h" />
+ <ClInclude Include="..\..\src\player\WrapPython.h" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/win/testbase/testbase.vcxproj b/win/testbase/testbase.vcxproj
new file mode 100755
index 0000000..28b42ee
--- /dev/null
+++ b/win/testbase/testbase.vcxproj
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{775830D7-7FD4-401B-B650-01376DE4D192}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ <RootNamespace>testbase</RootNamespace>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <WholeProgramOptimization>false</WholeProgramOptimization>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="..\libavg.props" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="..\libavg.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <LinkIncremental>true</LinkIncremental>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ <AdditionalDependencies>base.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\src\base\testbase.cpp" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/win/testgpu/testgpu.vcxproj b/win/testgpu/testgpu.vcxproj
new file mode 100755
index 0000000..82291ba
--- /dev/null
+++ b/win/testgpu/testgpu.vcxproj
@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{C7F16268-E53F-4E2C-A283-0475EA113745}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ <RootNamespace>testgpu</RootNamespace>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="..\libavg.props" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="..\libavg.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <LinkIncremental>true</LinkIncremental>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <LinkIncremental>false</LinkIncremental>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <Optimization>MaxSpeed</Optimization>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ <AdditionalDependencies>graphics.lib;base.lib;opengl32.lib;glu32.lib;gdk_pixbuf-2.0.lib;glib-2.0.lib;gobject-2.0.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\src\graphics\testgpu.cpp" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/win/testgraphics/testgraphics.vcxproj b/win/testgraphics/testgraphics.vcxproj
new file mode 100755
index 0000000..3678174
--- /dev/null
+++ b/win/testgraphics/testgraphics.vcxproj
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{C8174AA7-D062-4337-B740-90460C16FD86}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ <RootNamespace>testgraphics</RootNamespace>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="..\libavg.props" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="..\libavg.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <LinkIncremental>true</LinkIncremental>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <Optimization>MaxSpeed</Optimization>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ <AdditionalDependencies>graphics.lib;base.lib;opengl32.lib;glu32.lib;gdk_pixbuf-2.0.lib;glib-2.0.lib;gobject-2.0.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\src\graphics\testgraphics.cpp" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/win/testimaging/testimaging.vcxproj b/win/testimaging/testimaging.vcxproj
new file mode 100644
index 0000000..70f5fc8
--- /dev/null
+++ b/win/testimaging/testimaging.vcxproj
@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{B2ED4D82-E0C8-482E-93CD-B3546EDC9D56}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ <RootNamespace>testimaging</RootNamespace>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="..\libavg.props" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="..\libavg.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <LinkIncremental>true</LinkIncremental>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <LinkIncremental>false</LinkIncremental>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <Optimization>MaxSpeed</Optimization>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ <AdditionalDependencies>imaging.lib;graphics.lib;base.lib;opengl32.lib;glu32.lib;1394camera.lib;strmiids.lib;quartz.lib;strmbase.lib;gdk_pixbuf-2.0.lib;glib-2.0.lib;gobject-2.0.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\src\imaging\testimaging.cpp" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/win/testlimiter/testlimiter.vcxproj b/win/testlimiter/testlimiter.vcxproj
new file mode 100644
index 0000000..06a1eb8
--- /dev/null
+++ b/win/testlimiter/testlimiter.vcxproj
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{3D8F042E-55B5-40D9-818A-C51B3D2A6368}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ <RootNamespace>testlimiter</RootNamespace>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="..\libavg.props" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="..\libavg.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <LinkIncremental>true</LinkIncremental>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <LinkIncremental>false</LinkIncremental>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ <AdditionalDependencies>audio.lib;base.lib;SDL.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\src\audio\testlimiter.cpp" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/win/testplayer/testplayer.vcxproj b/win/testplayer/testplayer.vcxproj
new file mode 100644
index 0000000..e4783b2
--- /dev/null
+++ b/win/testplayer/testplayer.vcxproj
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{3FBD021A-344A-459A-A3DD-234AFCC17808}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ <RootNamespace>testplayer</RootNamespace>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="..\libavg.props" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="..\libavg.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <LinkIncremental>true</LinkIncremental>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <LinkIncremental>false</LinkIncremental>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ <AdditionalDependencies>player.lib;video.lib;imaging.lib;graphics.lib;audio.lib;lmfit.lib;oscpack.lib;base.lib;avcodec.lib;avdevice.lib;avfilter.lib;avformat.lib;avutil.lib;swscale.lib;opengl32.lib;glu32.lib;SDL.lib;1394camera.lib;strmiids.lib;quartz.lib;pango-1.0.lib;pangoft2-1.0.lib;cairo.lib;glib-2.0.lib;gobject-2.0.lib;gmodule-2.0.lib;gdk_pixbuf-2.0.lib;fontconfig.lib;strmbase.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\src\player\testplayer.cpp" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/win/testplugin/batch_template.txt b/win/testplugin/batch_template.txt
new file mode 100644
index 0000000..9fc1e43
--- /dev/null
+++ b/win/testplugin/batch_template.txt
@@ -0,0 +1,18 @@
+@echo off
+
+setlocal
+
+IF EXIST "%~dp0..\python.exe" (
+ set PYTHON_EXE="%~dp0..\python"
+) ELSE IF EXIST "%~dp0python.exe" (
+ REM virtualenv install
+ set PYTHON_EXE="%~dp0python"
+) ELSE (
+ echo Warning! Unable to find python.exe. Relying on PATH which may fail
+ echo.
+ set PYTHON_EXE=python
+)
+
+%PYTHON_EXE% "%~dp0#$#PYSCRIPT#$#" %*
+
+exit /b %ERRORLEVEL%
diff --git a/win/testplugin/setup.py b/win/testplugin/setup.py
new file mode 100644
index 0000000..7ce88be
--- /dev/null
+++ b/win/testplugin/setup.py
@@ -0,0 +1,188 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# libavg - Media Playback Engine.
+# Copyright (C) 2003-2014 Ulrich von Zadow
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Current versions can be found at www.libavg.de
+#
+
+from distutils.core import setup, Extension
+import os, sys, shutil, subprocess, glob
+
+sys.path.append('../../')
+
+import CreateVersionFile
+
+DEVEL_ROOT='../../../'
+LIBAVG_SRC_DIR='../../src/'
+site_packages_path = sys.exec_prefix+"\\Lib\\site-packages\\libavg"
+
+ERROR_STR= """Error removing %(path)s, %(error)s """
+
+def rmgeneric(path, __func__):
+ try:
+ __func__(path)
+ print 'Removed ', path
+ except OSError, (errno, strerror):
+ print ERROR_STR % {'path' : path, 'error': strerror }
+
+def removeall(path):
+ if not os.path.isdir(path):
+ return
+ files=os.listdir(path)
+ for x in files:
+ fullpath=os.path.join(path, x)
+ if os.path.isfile(fullpath):
+ f=os.remove
+ rmgeneric(fullpath, f)
+ elif os.path.isdir(fullpath):
+ removeall(fullpath)
+ f=os.rmdir
+ rmgeneric(fullpath, f)
+
+
+def gatherFilesInDir(dirName, exclude=[]):
+ return [os.path.join(dirName, fname) for fname in os.listdir(dirName) if
+ not os.path.isdir(os.path.join(dirName, fname)) and not fname in exclude]
+
+def gatherPythonFilesInDir(dirName):
+ return [dirName + fname for fname in os.listdir(dirName) if
+ fname[-3:] == ".py"]
+
+fnull = open(os.devnull, 'w')
+try:
+ rc = subprocess.call(["svn",], stdout=fnull, stderr=fnull)
+ fnull.close()
+except WindowsError:
+ print "Failed to execute subversion - no release info."
+ rc = 1
+
+if rc != 1:
+ print 'WARNING: SVN returned a bad code'
+ svnError()
+
+# Gather dlls:
+dlls=[DEVEL_ROOT+'/bin/'+dllname for dllname in os.listdir(DEVEL_ROOT+'/bin/')
+ if dllname[-4:] == ".dll" or dllname[-9:] == ".manifest"]
+dlls.append('../Release/avg.pyd')
+dlls.append('../Release/avg.pdb')
+
+test_files=[fname for fname in gatherFilesInDir(LIBAVG_SRC_DIR+'test/')
+ if '.' in fname[-4:] ]
+test_baseline_files=gatherFilesInDir(LIBAVG_SRC_DIR+'test/baseline/')
+
+test_testmediadir_files=gatherFilesInDir(LIBAVG_SRC_DIR+'test/testmediadir/')
+test_fonts_files=gatherFilesInDir(LIBAVG_SRC_DIR+'test/fonts/')
+test_media_files=gatherFilesInDir(LIBAVG_SRC_DIR+'test/media/')
+test_media_skin_files=gatherFilesInDir(LIBAVG_SRC_DIR+'test/media/incompleteSkinMedia')
+
+python_files = gatherPythonFilesInDir(LIBAVG_SRC_DIR+'python/')
+python_files += [
+ LIBAVG_SRC_DIR+'test/testcase.py',
+ LIBAVG_SRC_DIR+'test/testapp.py',
+ ]
+python_app_files = gatherFilesInDir(LIBAVG_SRC_DIR+'python/app/',
+ ('Makefile.am',))
+python_widget_files = gatherPythonFilesInDir(LIBAVG_SRC_DIR+'python/widget/')
+python_data_files = gatherFilesInDir(LIBAVG_SRC_DIR+'python/data/',
+ ('Makefile.am',))
+shader_files = gatherFilesInDir(LIBAVG_SRC_DIR+'graphics/shaders/',
+ ('Makefile.am',))
+
+assets_files=[]
+
+data_files_list=[
+ ('Lib/site-packages/libavg', dlls),
+ ('Lib/site-packages/libavg', ('version.txt',)),
+ ('Lib/site-packages/libavg/test', test_files),
+ ('Lib/site-packages/libavg/test/baseline', test_baseline_files),
+ ('Lib/site-packages/libavg/test/testmediadir', test_testmediadir_files),
+ ('Lib/site-packages/libavg/test/fonts', test_fonts_files),
+ ('Lib/site-packages/libavg/test/media', test_media_files),
+ ('Lib/site-packages/libavg/test/media/incompleteSkinMedia', test_media_skin_files),
+
+ ('Lib/site-packages/libavg/plugin', ('../Release/colorplugin.dll',)),
+ ('Lib/site-packages/libavg', python_files),
+ ('Lib/site-packages/libavg/app', python_app_files),
+ ('Lib/site-packages/libavg/widget', python_widget_files),
+ ('Lib/site-packages/libavg/data', python_data_files),
+ ('Lib/site-packages/libavg/shaders', shader_files),
+ ('Lib/site-packages/libavg', assets_files)
+ ]
+
+fontconfig_files=[DEVEL_ROOT+'etc/fonts/fonts.conf',
+ DEVEL_ROOT+'etc/fonts/fonts.dtd']
+
+data_files_list.append(('Lib/site-packages/libavg/etc',
+ [LIBAVG_SRC_DIR+'avgrc']))
+
+data_files_list += (
+ ('Lib/site-packages/libavg/etc/fonts', fontconfig_files),
+ )
+
+revision = 'svn'
+
+try:
+ nenv = os.environ
+ nenv['LANG'] = 'EN'
+ output = subprocess.Popen(["svn", "info", DEVEL_ROOT+'/libavg'],
+ stdout=subprocess.PIPE, env=nenv).communicate()[0]
+ f = open("version.txt", "w")
+ f.write(output)
+ f.close()
+except:
+ pass
+ f = open("version.txt", "w")
+ f.write("")
+ f.close()
+else:
+ import re
+ cre = re.compile('. (\d+)$', re.M)
+ match = cre.search(output)
+ if match and match.groups:
+ revision = 'r' + match.groups()[0]
+
+scripts = glob.glob(os.path.join(LIBAVG_SRC_DIR, 'utils', 'avg_*.py'))
+batches = []
+
+f = open('batch_template.txt')
+batchTemplate = f.read(1024)
+f.close()
+
+for py in map(os.path.basename, scripts):
+ batch = os.path.splitext(py)[0] + '.bat'
+ fw = open(batch, 'w')
+ fw.write(batchTemplate.replace('#$#PYSCRIPT#$#', py))
+ fw.close()
+ batches.append(batch)
+
+version = '.'.join([str(c) for c in CreateVersionFile.getVersionComponents()])
+
+setup(name='libavg',
+ version=version,
+ author='Ulrich von Zadow',
+ author_email='uzadow@libavg.de',
+ url='http://www.libavg.de',
+ packages=['libavg'],
+ package_dir = {'libavg': '.'},
+ data_files = data_files_list,
+ scripts=scripts + batches,
+ )
+
+for batch in batches:
+ os.unlink(batch)
+
diff --git a/win/testplugin/testplugin.vcxproj b/win/testplugin/testplugin.vcxproj
new file mode 100644
index 0000000..105887a
--- /dev/null
+++ b/win/testplugin/testplugin.vcxproj
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{B51101B0-9DFF-40D0-AFC1-5E41E67C0F73}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ <RootNamespace>testplugin</RootNamespace>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <CharacterSet>NotSet</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="..\libavg.props" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="..\libavg.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <LinkIncremental>true</LinkIncremental>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <TargetName>colorplugin</TargetName>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;TESTPLUGIN_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <PreprocessorDefinitions>NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ <AdditionalDependencies>avg.lib;opengl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <IgnoreSpecificDefaultLibraries>
+ </IgnoreSpecificDefaultLibraries>
+ <AdditionalOptions>/force:multiple %(AdditionalOptions)</AdditionalOptions>
+ </Link>
+ <CustomBuildStep>
+ <Command>python.exe setup.py install</Command>
+ </CustomBuildStep>
+ <CustomBuildStep>
+ <Outputs>colornode.dll</Outputs>
+ </CustomBuildStep>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\src\test\plugin\ColorNode.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="setup.py" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/win/testvideo/testvideo.vcxproj b/win/testvideo/testvideo.vcxproj
new file mode 100644
index 0000000..ebffcdb
--- /dev/null
+++ b/win/testvideo/testvideo.vcxproj
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{9247BEBF-91E4-4AEE-989C-94A9D731E9ED}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ <RootNamespace>testvideo</RootNamespace>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="..\libavg.props" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="..\libavg.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <LinkIncremental>true</LinkIncremental>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ <IgnoreAllDefaultLibraries>
+ </IgnoreAllDefaultLibraries>
+ <AdditionalDependencies>video.lib;graphics.lib;audio.lib;base.lib;avcodec.lib;avdevice.lib;avfilter.lib;avformat.lib;avutil.lib;swscale.lib;opengl32.lib;glu32.lib;gdk_pixbuf-2.0.lib;glib-2.0.lib;gobject-2.0.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\src\video\testvideo.cpp" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/win/video/video.vcxproj b/win/video/video.vcxproj
new file mode 100644
index 0000000..e2506a0
--- /dev/null
+++ b/win/video/video.vcxproj
@@ -0,0 +1,97 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{016C3620-D5BD-4138-97E4-C0AD38E32EB2}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ <RootNamespace>video</RootNamespace>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="..\libavg.props" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="..\libavg.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup />
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <PreprocessorDefinitions>NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ </Link>
+ <Lib>
+ <AdditionalDependencies>
+ </AdditionalDependencies>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\src\video\AsyncVideoDecoder.h" />
+ <ClInclude Include="..\..\src\video\AudioDecoderThread.h" />
+ <ClInclude Include="..\..\src\video\FFMpegDemuxer.h" />
+ <ClInclude Include="..\..\src\video\FFMpegFrameDecoder.h" />
+ <ClInclude Include="..\..\src\video\SyncVideoDecoder.h" />
+ <ClInclude Include="..\..\src\video\VideoDecoder.h" />
+ <ClInclude Include="..\..\src\video\VideoDecoderThread.h" />
+ <ClInclude Include="..\..\src\video\VideoDemuxerThread.h" />
+ <ClInclude Include="..\..\src\video\VideoInfo.h" />
+ <ClInclude Include="..\..\src\video\VideoMsg.h" />
+ <ClInclude Include="..\..\src\video\wrapffmpeg.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\src\video\AsyncVideoDecoder.cpp" />
+ <ClCompile Include="..\..\src\video\AudioDecoderThread.cpp" />
+ <ClCompile Include="..\..\src\video\FFMpegDemuxer.cpp" />
+ <ClCompile Include="..\..\src\video\FFMpegFrameDecoder.cpp" />
+ <ClCompile Include="..\..\src\video\SyncVideoDecoder.cpp" />
+ <ClCompile Include="..\..\src\video\VideoDecoder.cpp" />
+ <ClCompile Include="..\..\src\video\VideoDecoderThread.cpp" />
+ <ClCompile Include="..\..\src\video\VideoDemuxerThread.cpp" />
+ <ClCompile Include="..\..\src\video\VideoInfo.cpp" />
+ <ClCompile Include="..\..\src\video\VideoMsg.cpp" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/win/wrapper/wrapper.vcxproj b/win/wrapper/wrapper.vcxproj
new file mode 100644
index 0000000..3ec9ac3
--- /dev/null
+++ b/win/wrapper/wrapper.vcxproj
@@ -0,0 +1,96 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{0AFC225A-A1CF-463E-A516-BF9A0D2F554B}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ <RootNamespace>wrapper</RootNamespace>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="..\libavg.props" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="..\libavg.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <LinkIncremental>true</LinkIncremental>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <TargetName>avg</TargetName>
+ <TargetExt>.pyd</TargetExt>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>_DEBUG;_WINDOWS;_USRDLL;WRAPPER_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <PreprocessorDefinitions>NDEBUG;_WINDOWS;_USRDLL;WRAPPER_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <FunctionLevelLinking>false</FunctionLevelLinking>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>false</OptimizeReferences>
+ <AdditionalDependencies>anim.lib;player.lib;video.lib;imaging.lib;graphics.lib;audio.lib;lmfit.lib;oscpack.lib;base.lib;avcodec.lib;avdevice.lib;avfilter.lib;avformat.lib;avutil.lib;swscale.lib;opengl32.lib;glu32.lib;SDL.lib;1394camera.lib;strmiids.lib;quartz.lib;pango-1.0.lib;pangoft2-1.0.lib;cairo.lib;glib-2.0.lib;gobject-2.0.lib;gmodule-2.0.lib;gdk_pixbuf-2.0.lib;fontconfig.lib;strmbase.lib;librsvg-2-2.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ <CustomBuildStep>
+ <Command>
+ </Command>
+ <Outputs>
+ </Outputs>
+ </CustomBuildStep>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\src\wrapper\anim_wrap.cpp" />
+ <ClCompile Include="..\..\src\wrapper\avg_wrap.cpp" />
+ <ClCompile Include="..\..\src\wrapper\bitmap_wrap.cpp" />
+ <ClCompile Include="..\..\src\wrapper\event_wrap.cpp" />
+ <ClCompile Include="..\..\src\wrapper\fx_wrap.cpp" />
+ <ClCompile Include="..\..\src\wrapper\node_wrap.cpp" />
+ <ClCompile Include="..\..\src\wrapper\raster_wrap.cpp" />
+ <ClCompile Include="..\..\src\wrapper\WrapHelper.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\src\wrapper\raw_constructor.hpp" />
+ <ClInclude Include="..\..\src\wrapper\WrapHelper.h" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file