Browse code

Add Texture

Robert Cranston authored on 28/02/2023 02:21:38
Showing 1 changed files
... ...
@@ -7,6 +7,33 @@ class GLTraits
7 7
     template <GLenum id> struct ValueID;
8 8
 
9 9
     template <GLenum object_type> struct Object;
10
+
11
+    template <std::size_t N> struct Texture;
12
+
13
+  private:
14
+    template <std::size_t... Is> struct Indices
15
+    {
16
+    };
17
+
18
+    template <std::size_t N, std::size_t... Is>
19
+    struct MakeIndices_ : MakeIndices_<N - 1, N - 1, Is...>
20
+    {
21
+    };
22
+
23
+    template <std::size_t... Is> struct MakeIndices_<0, Is...>
24
+    {
25
+        using Indices_ = Indices<Is...>;
26
+    };
27
+
28
+    template <std::size_t N>
29
+    using MakeIndices = typename MakeIndices_<N>::Indices_;
30
+
31
+    template <
32
+        std::size_t N,
33
+        typename Indices,
34
+        typename CopySizeIndices,
35
+        typename CopyOffsetIndices>
36
+    struct Texture_;
10 37
 };
11 38
 
12 39
 template <> struct GLTraits::Value<GLfloat>
... ...
@@ -2633,3 +2660,734 @@ template <> struct GLTraits::Object<GL_PROGRAM_PIPELINE>
2633 2660
     }
2634 2661
 };
2635 2662
 
2663
+
2664
+template <> struct GLTraits::Texture<0>
2665
+{
2666
+  protected:
2667
+    void static defaults_(
2668
+        GLenum & internal_format,
2669
+        GLenum & format,
2670
+        GLenum & type,
2671
+        GLenum   default_internal_format,
2672
+        GLenum   default_format,
2673
+        GLenum   default_type)
2674
+    {
2675
+        if (!internal_format)
2676
+            internal_format = default_internal_format;
2677
+        switch (internal_format)
2678
+        {
2679
+        case GL_DEPTH_STENCIL:
2680
+        case GL_DEPTH24_STENCIL8:
2681
+        case GL_DEPTH32F_STENCIL8:
2682
+            if (!format)
2683
+                format = GL_DEPTH_STENCIL;
2684
+            if (!type)
2685
+                type = GL_UNSIGNED_INT_24_8;
2686
+            break;
2687
+        case GL_DEPTH_COMPONENT:
2688
+        case GL_DEPTH_COMPONENT16:
2689
+        case GL_DEPTH_COMPONENT24:
2690
+        case GL_DEPTH_COMPONENT32:
2691
+        case GL_DEPTH_COMPONENT32F:
2692
+            if (!format)
2693
+                format = GL_DEPTH_COMPONENT;
2694
+            if (!type)
2695
+                type = GL_UNSIGNED_INT;
2696
+            break;
2697
+        case GL_STENCIL_INDEX:
2698
+        case GL_STENCIL_INDEX1:
2699
+        case GL_STENCIL_INDEX4:
2700
+        case GL_STENCIL_INDEX8:
2701
+        case GL_STENCIL_INDEX16:
2702
+            if (!format)
2703
+                format = GL_STENCIL_INDEX;
2704
+            if (!type)
2705
+                type = GL_UNSIGNED_BYTE;
2706
+            break;
2707
+        default:
2708
+            if (!format)
2709
+                format = default_format;
2710
+            if (!type)
2711
+                type = default_type;
2712
+        }
2713
+    }
2714
+};
2715
+
2716
+template <
2717
+    std::size_t... Is,
2718
+    std::size_t... CopySizeIs,
2719
+    std::size_t... CopyOffsetIs>
2720
+struct GLTraits::Texture_<
2721
+    1,
2722
+    GLTraits::Indices<Is...>,
2723
+    GLTraits::Indices<CopySizeIs...>,
2724
+    GLTraits::Indices<CopyOffsetIs...>> : GLTraits::Texture<0>
2725
+{
2726
+    using Size       = std::array<GLsizei, sizeof...(Is)>;
2727
+    using Offset     = std::array<GLsizei, sizeof...(Is)>;
2728
+    using CopySize   = std::array<GLsizei, sizeof...(CopySizeIs)>;
2729
+    using CopyOffset = std::array<GLsizei, sizeof...(CopyOffsetIs)>;
2730
+    auto static constexpr default_target  = GL_TEXTURE_1D;
2731
+    auto static constexpr default_binding = GL_TEXTURE_BINDING_1D;
2732
+    template <typename Value = GLubyte>
2733
+    void static tex_image(
2734
+        GLenum        target,
2735
+        Size          size,
2736
+        GLenum        internal_format = 0,
2737
+        Value const * data            = nullptr,
2738
+        GLenum        format          = 0,
2739
+        GLenum        type            = 0,
2740
+        GLint         level           = 0,
2741
+        GLint         border          = 0)
2742
+    {
2743
+        if (GLBase::debug() >= 1)
2744
+            GLBase::check_supported({1, 0}, {});
2745
+        defaults_(
2746
+            internal_format,
2747
+            format,
2748
+            type,
2749
+            GLTraits::Value<Value>::internal_format,
2750
+            GLTraits::Value<Value>::format,
2751
+            GLTraits::Value<Value>::type);
2752
+        glTexImage1D(
2753
+            target,
2754
+            level,
2755
+            (GLint)internal_format,
2756
+            std::get<Is>(size)...,
2757
+            border,
2758
+            format,
2759
+            type,
2760
+            data);
2761
+    }
2762
+    template <typename Value = GLubyte>
2763
+    void static tex_sub_image(
2764
+        GLenum        target,
2765
+        Size          size,
2766
+        Value const * data,
2767
+        GLenum        format = 0,
2768
+        GLenum        type   = 0,
2769
+        Offset        offset = {},
2770
+        GLint         level  = 0)
2771
+    {
2772
+        if (GLBase::debug() >= 1)
2773
+            GLBase::check_supported({1, 1}, {});
2774
+        if (!format)
2775
+            format = GLTraits::Value<Value>::format;
2776
+        if (!type)
2777
+            type = GLTraits::Value<Value>::type;
2778
+        glTexSubImage1D(
2779
+            target,
2780
+            level,
2781
+            std::get<Is>(offset)...,
2782
+            std::get<Is>(size)...,
2783
+            format,
2784
+            type,
2785
+            data);
2786
+    }
2787
+    void static copy_tex_sub_image(
2788
+        GLenum     target,
2789
+        CopySize   copy_size,
2790
+        CopyOffset copy_offset = {},
2791
+        Offset     offset      = {},
2792
+        GLint      level       = 0)
2793
+    {
2794
+        if (GLBase::debug() >= 1)
2795
+            GLBase::check_supported({1, 1}, {});
2796
+        glCopyTexSubImage1D(
2797
+            target,
2798
+            level,
2799
+            std::get<Is>(offset)...,
2800
+            std::get<CopyOffsetIs>(copy_offset)...,
2801
+            std::get<CopySizeIs>(copy_size)...);
2802
+    }
2803
+    void static compressed_tex_image(
2804
+        GLenum       target,
2805
+        Size         size,
2806
+        GLenum       internal_format,
2807
+        GLsizei      data_size = 0,
2808
+        void const * data      = nullptr,
2809
+        GLint        level     = 0,
2810
+        GLint        border    = 0)
2811
+    {
2812
+        if (GLBase::debug() >= 1)
2813
+            GLBase::check_supported({1, 3}, {});
2814
+        glCompressedTexImage1D(
2815
+            target,
2816
+            level,
2817
+            internal_format,
2818
+            std::get<Is>(size)...,
2819
+            border,
2820
+            data_size,
2821
+            data);
2822
+    }
2823
+    void static compressed_tex_sub_image(
2824
+        GLenum       target,
2825
+        Size         size,
2826
+        GLsizei      data_size,
2827
+        void const * data,
2828
+        GLenum       internal_format,
2829
+        Offset       offset = {},
2830
+        GLint        level  = 0)
2831
+    {
2832
+        if (GLBase::debug() >= 1)
2833
+            GLBase::check_supported({1, 3}, {});
2834
+        glCompressedTexSubImage1D(
2835
+            target,
2836
+            level,
2837
+            std::get<Is>(offset)...,
2838
+            std::get<Is>(size)...,
2839
+            internal_format,
2840
+            data_size,
2841
+            data);
2842
+    }
2843
+    template <typename Value = GLubyte>
2844
+    void static tex_storage(
2845
+        GLenum  target,
2846
+        Size    size,
2847
+        GLenum  internal_format = 0,
2848
+        GLsizei levels          = 1)
2849
+    {
2850
+        if (GLBase::debug() >= 1)
2851
+            GLBase::check_supported({4, 2}, "GL_ARB_texture_storage");
2852
+        if (!internal_format)
2853
+            internal_format = GLTraits::Value<Value>::internal_format;
2854
+        glTexStorage1D(target, levels, internal_format, std::get<Is>(size)...);
2855
+    }
2856
+    template <typename Value = GLubyte>
2857
+    void static texture_storage(
2858
+        GLuint  texture,
2859
+        Size    size,
2860
+        GLenum  internal_format = 0,
2861
+        GLsizei levels          = 1)
2862
+    {
2863
+        if (GLBase::debug() >= 1)
2864
+            GLBase::check_supported({4, 5}, "GL_ARB_direct_state_access");
2865
+        if (!internal_format)
2866
+            internal_format = GLTraits::Value<Value>::internal_format;
2867
+        glTextureStorage1D(
2868
+            texture,
2869
+            levels,
2870
+            internal_format,
2871
+            std::get<Is>(size)...);
2872
+    }
2873
+    template <typename Value = GLubyte>
2874
+    void static texture_sub_image(
2875
+        GLuint        texture,
2876
+        Size          size,
2877
+        Value const * data,
2878
+        GLenum        format = 0,
2879
+        GLenum        type   = 0,
2880
+        Offset        offset = {},
2881
+        GLint         level  = 0)
2882
+    {
2883
+        if (GLBase::debug() >= 1)
2884
+            GLBase::check_supported({4, 5}, "GL_ARB_direct_state_access");
2885
+        if (!format)
2886
+            format = GLTraits::Value<Value>::format;
2887
+        if (!type)
2888
+            type = GLTraits::Value<Value>::type;
2889
+        glTextureSubImage1D(
2890
+            texture,
2891
+            level,
2892
+            std::get<Is>(offset)...,
2893
+            std::get<Is>(size)...,
2894
+            format,
2895
+            type,
2896
+            data);
2897
+    }
2898
+    void static copy_texture_sub_image(
2899
+        GLuint     texture,
2900
+        CopySize   copy_size,
2901
+        CopyOffset copy_offset = {},
2902
+        Offset     offset      = {},
2903
+        GLint      level       = 0)
2904
+    {
2905
+        if (GLBase::debug() >= 1)
2906
+            GLBase::check_supported({4, 5}, "GL_ARB_direct_state_access");
2907
+        glCopyTextureSubImage1D(
2908
+            texture,
2909
+            level,
2910
+            std::get<Is>(offset)...,
2911
+            std::get<CopyOffsetIs>(copy_offset)...,
2912
+            std::get<CopySizeIs>(copy_size)...);
2913
+    }
2914
+    void static compressed_texture_sub_image(
2915
+        GLuint       texture,
2916
+        Size         size,
2917
+        GLsizei      data_size,
2918
+        void const * data,
2919
+        GLenum       internal_format,
2920
+        Offset       offset = {},
2921
+        GLint        level  = 0)
2922
+    {
2923
+        if (GLBase::debug() >= 1)
2924
+            GLBase::check_supported({4, 5}, "GL_ARB_direct_state_access");
2925
+        glCompressedTextureSubImage1D(
2926
+            texture,
2927
+            level,
2928
+            std::get<Is>(offset)...,
2929
+            std::get<Is>(size)...,
2930
+            internal_format,
2931
+            data_size,
2932
+            data);
2933
+    }
2934
+};
2935
+
2936
+template <>
2937
+struct GLTraits::Texture<1>
2938
+    : Texture_<1, MakeIndices<1>, MakeIndices<1 < 2 ? 1 : 2>, MakeIndices<2>>
2939
+{
2940
+};
2941
+
2942
+template <
2943
+    std::size_t... Is,
2944
+    std::size_t... CopySizeIs,
2945
+    std::size_t... CopyOffsetIs>
2946
+struct GLTraits::Texture_<
2947
+    2,
2948
+    GLTraits::Indices<Is...>,
2949
+    GLTraits::Indices<CopySizeIs...>,
2950
+    GLTraits::Indices<CopyOffsetIs...>> : GLTraits::Texture<0>
2951
+{
2952
+    using Size       = std::array<GLsizei, sizeof...(Is)>;
2953
+    using Offset     = std::array<GLsizei, sizeof...(Is)>;
2954
+    using CopySize   = std::array<GLsizei, sizeof...(CopySizeIs)>;
2955
+    using CopyOffset = std::array<GLsizei, sizeof...(CopyOffsetIs)>;
2956
+    auto static constexpr default_target  = GL_TEXTURE_2D;
2957
+    auto static constexpr default_binding = GL_TEXTURE_BINDING_2D;
2958
+    template <typename Value = GLubyte>
2959
+    void static tex_image(
2960
+        GLenum        target,
2961
+        Size          size,
2962
+        GLenum        internal_format = 0,
2963
+        Value const * data            = nullptr,
2964
+        GLenum        format          = 0,
2965
+        GLenum        type            = 0,
2966
+        GLint         level           = 0,
2967
+        GLint         border          = 0)
2968
+    {
2969
+        if (GLBase::debug() >= 1)
2970
+            GLBase::check_supported({1, 0}, {});
2971
+        defaults_(
2972
+            internal_format,
2973
+            format,
2974
+            type,
2975
+            GLTraits::Value<Value>::internal_format,
2976
+            GLTraits::Value<Value>::format,
2977
+            GLTraits::Value<Value>::type);
2978
+        glTexImage2D(
2979
+            target,
2980
+            level,
2981
+            (GLint)internal_format,
2982
+            std::get<Is>(size)...,
2983
+            border,
2984
+            format,
2985
+            type,
2986
+            data);
2987
+    }
2988
+    template <typename Value = GLubyte>
2989
+    void static tex_sub_image(
2990
+        GLenum        target,
2991
+        Size          size,
2992
+        Value const * data,
2993
+        GLenum        format = 0,
2994
+        GLenum        type   = 0,
2995
+        Offset        offset = {},
2996
+        GLint         level  = 0)
2997
+    {
2998
+        if (GLBase::debug() >= 1)
2999
+            GLBase::check_supported({1, 1}, {});
3000
+        if (!format)
3001
+            format = GLTraits::Value<Value>::format;
3002
+        if (!type)
3003
+            type = GLTraits::Value<Value>::type;
3004
+        glTexSubImage2D(
3005
+            target,
3006
+            level,
3007
+            std::get<Is>(offset)...,
3008
+            std::get<Is>(size)...,
3009
+            format,
3010
+            type,
3011
+            data);
3012
+    }
3013
+    void static copy_tex_sub_image(
3014
+        GLenum     target,
3015
+        CopySize   copy_size,
3016
+        CopyOffset copy_offset = {},
3017
+        Offset     offset      = {},
3018
+        GLint      level       = 0)
3019
+    {
3020
+        if (GLBase::debug() >= 1)
3021
+            GLBase::check_supported({1, 1}, {});
3022
+        glCopyTexSubImage2D(
3023
+            target,
3024
+            level,
3025
+            std::get<Is>(offset)...,
3026
+            std::get<CopyOffsetIs>(copy_offset)...,
3027
+            std::get<CopySizeIs>(copy_size)...);
3028
+    }
3029
+    void static compressed_tex_image(
3030
+        GLenum       target,
3031
+        Size         size,
3032
+        GLenum       internal_format,
3033
+        GLsizei      data_size = 0,
3034
+        void const * data      = nullptr,
3035
+        GLint        level     = 0,
3036
+        GLint        border    = 0)
3037
+    {
3038
+        if (GLBase::debug() >= 1)
3039
+            GLBase::check_supported({1, 3}, {});
3040
+        glCompressedTexImage2D(
3041
+            target,
3042
+            level,
3043
+            internal_format,
3044
+            std::get<Is>(size)...,
3045
+            border,
3046
+            data_size,
3047
+            data);
3048
+    }
3049
+    void static compressed_tex_sub_image(
3050
+        GLenum       target,
3051
+        Size         size,
3052
+        GLsizei      data_size,
3053
+        void const * data,
3054
+        GLenum       internal_format,
3055
+        Offset       offset = {},
3056
+        GLint        level  = 0)
3057
+    {
3058
+        if (GLBase::debug() >= 1)
3059
+            GLBase::check_supported({1, 3}, {});
3060
+        glCompressedTexSubImage2D(
3061
+            target,
3062
+            level,
3063
+            std::get<Is>(offset)...,
3064
+            std::get<Is>(size)...,
3065
+            internal_format,
3066
+            data_size,
3067
+            data);
3068
+    }
3069
+    template <typename Value = GLubyte>
3070
+    void static tex_storage(
3071
+        GLenum  target,
3072
+        Size    size,
3073
+        GLenum  internal_format = 0,
3074
+        GLsizei levels          = 1)
3075
+    {
3076
+        if (GLBase::debug() >= 1)
3077
+            GLBase::check_supported({4, 2}, "GL_ARB_texture_storage");
3078
+        if (!internal_format)
3079
+            internal_format = GLTraits::Value<Value>::internal_format;
3080
+        glTexStorage2D(target, levels, internal_format, std::get<Is>(size)...);
3081
+    }
3082
+    template <typename Value = GLubyte>
3083
+    void static texture_storage(
3084
+        GLuint  texture,
3085
+        Size    size,
3086
+        GLenum  internal_format = 0,
3087
+        GLsizei levels          = 1)
3088
+    {
3089
+        if (GLBase::debug() >= 1)
3090
+            GLBase::check_supported({4, 5}, "GL_ARB_direct_state_access");
3091
+        if (!internal_format)
3092
+            internal_format = GLTraits::Value<Value>::internal_format;
3093
+        glTextureStorage2D(
3094
+            texture,
3095
+            levels,
3096
+            internal_format,
3097
+            std::get<Is>(size)...);
3098
+    }
3099
+    template <typename Value = GLubyte>
3100
+    void static texture_sub_image(
3101
+        GLuint        texture,
3102
+        Size          size,
3103
+        Value const * data,
3104
+        GLenum        format = 0,
3105
+        GLenum        type   = 0,
3106
+        Offset        offset = {},
3107
+        GLint         level  = 0)
3108
+    {
3109
+        if (GLBase::debug() >= 1)
3110
+            GLBase::check_supported({4, 5}, "GL_ARB_direct_state_access");
3111
+        if (!format)
3112
+            format = GLTraits::Value<Value>::format;
3113
+        if (!type)
3114
+            type = GLTraits::Value<Value>::type;
3115
+        glTextureSubImage2D(
3116
+            texture,
3117
+            level,
3118
+            std::get<Is>(offset)...,
3119
+            std::get<Is>(size)...,
3120
+            format,
3121
+            type,
3122
+            data);
3123
+    }
3124
+    void static copy_texture_sub_image(
3125
+        GLuint     texture,
3126
+        CopySize   copy_size,
3127
+        CopyOffset copy_offset = {},
3128
+        Offset     offset      = {},
3129
+        GLint      level       = 0)
3130
+    {
3131
+        if (GLBase::debug() >= 1)
3132
+            GLBase::check_supported({4, 5}, "GL_ARB_direct_state_access");
3133
+        glCopyTextureSubImage2D(
3134
+            texture,
3135
+            level,
3136
+            std::get<Is>(offset)...,
3137
+            std::get<CopyOffsetIs>(copy_offset)...,
3138
+            std::get<CopySizeIs>(copy_size)...);
3139
+    }
3140
+    void static compressed_texture_sub_image(
3141
+        GLuint       texture,
3142
+        Size         size,
3143
+        GLsizei      data_size,
3144
+        void const * data,
3145
+        GLenum       internal_format,
3146
+        Offset       offset = {},
3147
+        GLint        level  = 0)
3148
+    {
3149
+        if (GLBase::debug() >= 1)
3150
+            GLBase::check_supported({4, 5}, "GL_ARB_direct_state_access");
3151
+        glCompressedTextureSubImage2D(
3152
+            texture,
3153
+            level,
3154
+            std::get<Is>(offset)...,
3155
+            std::get<Is>(size)...,
3156
+            internal_format,
3157
+            data_size,
3158
+            data);
3159
+    }
3160
+};
3161
+
3162
+template <>
3163
+struct GLTraits::Texture<2>
3164
+    : Texture_<2, MakeIndices<2>, MakeIndices<2 < 2 ? 2 : 2>, MakeIndices<2>>
3165
+{
3166
+};
3167
+
3168
+template <
3169
+    std::size_t... Is,
3170
+    std::size_t... CopySizeIs,
3171
+    std::size_t... CopyOffsetIs>
3172
+struct GLTraits::Texture_<
3173
+    3,
3174
+    GLTraits::Indices<Is...>,
3175
+    GLTraits::Indices<CopySizeIs...>,
3176
+    GLTraits::Indices<CopyOffsetIs...>> : GLTraits::Texture<0>
3177
+{
3178
+    using Size       = std::array<GLsizei, sizeof...(Is)>;
3179
+    using Offset     = std::array<GLsizei, sizeof...(Is)>;
3180
+    using CopySize   = std::array<GLsizei, sizeof...(CopySizeIs)>;
3181
+    using CopyOffset = std::array<GLsizei, sizeof...(CopyOffsetIs)>;
3182
+    auto static constexpr default_target  = GL_TEXTURE_3D;
3183
+    auto static constexpr default_binding = GL_TEXTURE_BINDING_3D;
3184
+    template <typename Value = GLubyte>
3185
+    void static tex_image(
3186
+        GLenum        target,
3187
+        Size          size,
3188
+        GLenum        internal_format = 0,
3189
+        Value const * data            = nullptr,
3190
+        GLenum        format          = 0,
3191
+        GLenum        type            = 0,
3192
+        GLint         level           = 0,
3193
+        GLint         border          = 0)
3194
+    {
3195
+        if (GLBase::debug() >= 1)
3196
+            GLBase::check_supported({1, 2}, {});
3197
+        defaults_(
3198
+            internal_format,
3199
+            format,
3200
+            type,
3201
+            GLTraits::Value<Value>::internal_format,
3202
+            GLTraits::Value<Value>::format,
3203
+            GLTraits::Value<Value>::type);
3204
+        glTexImage3D(
3205
+            target,
3206
+            level,
3207
+            (GLint)internal_format,
3208
+            std::get<Is>(size)...,
3209
+            border,
3210
+            format,
3211
+            type,
3212
+            data);
3213
+    }
3214
+    template <typename Value = GLubyte>
3215
+    void static tex_sub_image(
3216
+        GLenum        target,
3217
+        Size          size,
3218
+        Value const * data,
3219
+        GLenum        format = 0,
3220
+        GLenum        type   = 0,
3221
+        Offset        offset = {},
3222
+        GLint         level  = 0)
3223
+    {
3224
+        if (GLBase::debug() >= 1)
3225
+            GLBase::check_supported({1, 2}, {});
3226
+        if (!format)
3227
+            format = GLTraits::Value<Value>::format;
3228
+        if (!type)
3229
+            type = GLTraits::Value<Value>::type;
3230
+        glTexSubImage3D(
3231
+            target,
3232
+            level,
3233
+            std::get<Is>(offset)...,
3234
+            std::get<Is>(size)...,
3235
+            format,
3236
+            type,
3237
+            data);
3238
+    }
3239
+    void static copy_tex_sub_image(
3240
+        GLenum     target,
3241
+        CopySize   copy_size,
3242
+        CopyOffset copy_offset = {},
3243
+        Offset     offset      = {},
3244
+        GLint      level       = 0)
3245
+    {
3246
+        if (GLBase::debug() >= 1)
3247
+            GLBase::check_supported({1, 2}, {});
3248
+        glCopyTexSubImage3D(
3249
+            target,
3250
+            level,
3251
+            std::get<Is>(offset)...,
3252
+            std::get<CopyOffsetIs>(copy_offset)...,
3253
+            std::get<CopySizeIs>(copy_size)...);
3254
+    }
3255
+    void static compressed_tex_image(
3256
+        GLenum       target,
3257
+        Size         size,
3258
+        GLenum       internal_format,
3259
+        GLsizei      data_size = 0,
3260
+        void const * data      = nullptr,
3261
+        GLint        level     = 0,
3262
+        GLint        border    = 0)
3263
+    {
3264
+        if (GLBase::debug() >= 1)
3265
+            GLBase::check_supported({1, 3}, {});
3266
+        glCompressedTexImage3D(
3267
+            target,
3268
+            level,
3269
+            internal_format,
3270
+            std::get<Is>(size)...,
3271
+            border,
3272
+            data_size,
3273
+            data);
3274
+    }
3275
+    void static compressed_tex_sub_image(
3276
+        GLenum       target,
3277
+        Size         size,
3278
+        GLsizei      data_size,
3279
+        void const * data,
3280
+        GLenum       internal_format,
3281
+        Offset       offset = {},
3282
+        GLint        level  = 0)
3283
+    {
3284
+        if (GLBase::debug() >= 1)
3285
+            GLBase::check_supported({1, 3}, {});
3286
+        glCompressedTexSubImage3D(
3287
+            target,
3288
+            level,
3289
+            std::get<Is>(offset)...,
3290
+            std::get<Is>(size)...,
3291
+            internal_format,
3292
+            data_size,
3293
+            data);
3294
+    }
3295
+    template <typename Value = GLubyte>
3296
+    void static tex_storage(
3297
+        GLenum  target,
3298
+        Size    size,
3299
+        GLenum  internal_format = 0,
3300
+        GLsizei levels          = 1)
3301
+    {
3302
+        if (GLBase::debug() >= 1)
3303
+            GLBase::check_supported({4, 2}, "GL_ARB_texture_storage");
3304
+        if (!internal_format)
3305
+            internal_format = GLTraits::Value<Value>::internal_format;
3306
+        glTexStorage3D(target, levels, internal_format, std::get<Is>(size)...);
3307
+    }
3308
+    template <typename Value = GLubyte>
3309
+    void static texture_storage(
3310
+        GLuint  texture,
3311
+        Size    size,
3312
+        GLenum  internal_format = 0,
3313
+        GLsizei levels          = 1)
3314
+    {
3315
+        if (GLBase::debug() >= 1)
3316
+            GLBase::check_supported({4, 5}, "GL_ARB_direct_state_access");
3317
+        if (!internal_format)
3318
+            internal_format = GLTraits::Value<Value>::internal_format;
3319
+        glTextureStorage3D(
3320
+            texture,
3321
+            levels,
3322
+            internal_format,
3323
+            std::get<Is>(size)...);
3324
+    }
3325
+    template <typename Value = GLubyte>
3326
+    void static texture_sub_image(
3327
+        GLuint        texture,
3328
+        Size          size,
3329
+        Value const * data,
3330
+        GLenum        format = 0,
3331
+        GLenum        type   = 0,
3332
+        Offset        offset = {},
3333
+        GLint         level  = 0)
3334
+    {
3335
+        if (GLBase::debug() >= 1)
3336
+            GLBase::check_supported({4, 5}, "GL_ARB_direct_state_access");
3337
+        if (!format)
3338
+            format = GLTraits::Value<Value>::format;
3339
+        if (!type)
3340
+            type = GLTraits::Value<Value>::type;
3341
+        glTextureSubImage3D(
3342
+            texture,
3343
+            level,
3344
+            std::get<Is>(offset)...,
3345
+            std::get<Is>(size)...,
3346
+            format,
3347
+            type,
3348
+            data);
3349
+    }
3350
+    void static copy_texture_sub_image(
3351
+        GLuint     texture,
3352
+        CopySize   copy_size,
3353
+        CopyOffset copy_offset = {},
3354
+        Offset     offset      = {},
3355
+        GLint      level       = 0)
3356
+    {
3357
+        if (GLBase::debug() >= 1)
3358
+            GLBase::check_supported({4, 5}, "GL_ARB_direct_state_access");
3359
+        glCopyTextureSubImage3D(
3360
+            texture,
3361
+            level,
3362
+            std::get<Is>(offset)...,
3363
+            std::get<CopyOffsetIs>(copy_offset)...,
3364
+            std::get<CopySizeIs>(copy_size)...);
3365
+    }
3366
+    void static compressed_texture_sub_image(
3367
+        GLuint       texture,
3368
+        Size         size,
3369
+        GLsizei      data_size,
3370
+        void const * data,
3371
+        GLenum       internal_format,
3372
+        Offset       offset = {},
3373
+        GLint        level  = 0)
3374
+    {
3375
+        if (GLBase::debug() >= 1)
3376
+            GLBase::check_supported({4, 5}, "GL_ARB_direct_state_access");
3377
+        glCompressedTextureSubImage3D(
3378
+            texture,
3379
+            level,
3380
+            std::get<Is>(offset)...,
3381
+            std::get<Is>(size)...,
3382
+            internal_format,
3383
+            data_size,
3384
+            data);
3385
+    }
3386
+};
3387
+
3388
+template <>
3389
+struct GLTraits::Texture<3>
3390
+    : Texture_<3, MakeIndices<3>, MakeIndices<3 < 2 ? 3 : 2>, MakeIndices<2>>
3391
+{
3392
+};
3393
+
Browse code

Add Object

Robert Cranston authored on 28/02/2023 02:19:27
Showing 1 changed files
... ...
@@ -5,6 +5,8 @@ class GLTraits
5 5
     template <typename> struct Value;
6 6
 
7 7
     template <GLenum id> struct ValueID;
8
+
9
+    template <GLenum object_type> struct Object;
8 10
 };
9 11
 
10 12
 template <> struct GLTraits::Value<GLfloat>
... ...
@@ -2382,3 +2384,252 @@ template <> struct GLTraits::ValueID<GLTraits::Value<glm::dmat4>::id>
2382 2384
     using Value = glm::dmat4;
2383 2385
 };
2384 2386
 
2387
+template <> struct GLTraits::Object<GL_TEXTURE>
2388
+{
2389
+    auto static constexpr name = "GL_"
2390
+                                 "TEXTURE";
2391
+    template <typename... Args>
2392
+    void static gen_objects(GLsizei n, GLuint * objects, Args... args)
2393
+    {
2394
+        if (GLBase::debug() >= 1)
2395
+            GLBase::check_supported({1, 1}, {});
2396
+        glGenTextures(n, objects, args...);
2397
+    }
2398
+    void static delete_objects(GLsizei n, GLuint const * objects)
2399
+    {
2400
+        if (GLBase::debug() >= 1)
2401
+            GLBase::check_supported({1, 1}, {});
2402
+        glDeleteTextures(n, objects);
2403
+    }
2404
+};
2405
+
2406
+template <> struct GLTraits::Object<GL_BUFFER>
2407
+{
2408
+    auto static constexpr name = "GL_"
2409
+                                 "BUFFER";
2410
+    template <typename... Args>
2411
+    void static gen_objects(GLsizei n, GLuint * objects, Args... args)
2412
+    {
2413
+        if (GLBase::debug() >= 1)
2414
+            GLBase::check_supported({1, 5}, {});
2415
+        glGenBuffers(n, objects, args...);
2416
+    }
2417
+    void static delete_objects(GLsizei n, GLuint const * objects)
2418
+    {
2419
+        if (GLBase::debug() >= 1)
2420
+            GLBase::check_supported({1, 5}, {});
2421
+        glDeleteBuffers(n, objects);
2422
+    }
2423
+};
2424
+
2425
+template <> struct GLTraits::Object<GL_QUERY>
2426
+{
2427
+    auto static constexpr name = "GL_"
2428
+                                 "QUERY";
2429
+    template <typename... Args>
2430
+    void static gen_objects(GLsizei n, GLuint * objects, Args... args)
2431
+    {
2432
+        if (GLBase::debug() >= 1)
2433
+            GLBase::check_supported({1, 5}, {});
2434
+        glGenQueries(n, objects, args...);
2435
+    }
2436
+    void static delete_objects(GLsizei n, GLuint const * objects)
2437
+    {
2438
+        if (GLBase::debug() >= 1)
2439
+            GLBase::check_supported({1, 5}, {});
2440
+        glDeleteQueries(n, objects);
2441
+    }
2442
+};
2443
+
2444
+template <> struct GLTraits::Object<GL_PROGRAM>
2445
+{
2446
+    auto static constexpr name = "GL_"
2447
+                                 "PROGRAM";
2448
+    template <typename... Args>
2449
+    void static gen_objects(GLsizei n, GLuint * objects, Args... args)
2450
+    {
2451
+        if (GLBase::debug() >= 1)
2452
+            GLBase::check_supported({2, 0}, {});
2453
+        while (n--)
2454
+            objects[n] = glCreateProgram(args...);
2455
+    }
2456
+    void static delete_objects(GLsizei n, GLuint const * objects)
2457
+    {
2458
+        if (GLBase::debug() >= 1)
2459
+            GLBase::check_supported({2, 0}, {});
2460
+        while (n--)
2461
+            glDeleteProgram(objects[n]);
2462
+    }
2463
+    std::string static info_log(GLuint object)
2464
+    {
2465
+        if (GLBase::debug() >= 1)
2466
+            GLBase::check_supported({2, 0}, {});
2467
+        auto length = GLint{};
2468
+        glGetProgramiv(object, GL_INFO_LOG_LENGTH, &length);
2469
+        if (length != 0)
2470
+            --length;
2471
+        auto info_log = std::string((std::size_t)length, char{});
2472
+        glGetProgramInfoLog(object, length + 1, nullptr, &info_log[0]);
2473
+        return info_log;
2474
+    }
2475
+};
2476
+
2477
+template <> struct GLTraits::Object<GL_SHADER>
2478
+{
2479
+    auto static constexpr name = "GL_"
2480
+                                 "SHADER";
2481
+    template <typename... Args>
2482
+    void static gen_objects(GLsizei n, GLuint * objects, Args... args)
2483
+    {
2484
+        if (GLBase::debug() >= 1)
2485
+            GLBase::check_supported({2, 0}, {});
2486
+        while (n--)
2487
+            objects[n] = glCreateShader(args...);
2488
+    }
2489
+    void static delete_objects(GLsizei n, GLuint const * objects)
2490
+    {
2491
+        if (GLBase::debug() >= 1)
2492
+            GLBase::check_supported({2, 0}, {});
2493
+        while (n--)
2494
+            glDeleteShader(objects[n]);
2495
+    }
2496
+    std::string static info_log(GLuint object)
2497
+    {
2498
+        if (GLBase::debug() >= 1)
2499
+            GLBase::check_supported({2, 0}, {});
2500
+        auto length = GLint{};
2501
+        glGetShaderiv(object, GL_INFO_LOG_LENGTH, &length);
2502
+        if (length != 0)
2503
+            --length;
2504
+        auto info_log = std::string((std::size_t)length, char{});
2505
+        glGetShaderInfoLog(object, length + 1, nullptr, &info_log[0]);
2506
+        return info_log;
2507
+    }
2508
+};
2509
+
2510
+template <> struct GLTraits::Object<GL_VERTEX_ARRAY>
2511
+{
2512
+    auto static constexpr name = "GL_"
2513
+                                 "VERTEX_ARRAY";
2514
+    template <typename... Args>
2515
+    void static gen_objects(GLsizei n, GLuint * objects, Args... args)
2516
+    {
2517
+        if (GLBase::debug() >= 1)
2518
+            GLBase::check_supported({3, 0}, "GL_ARB_vertex_array_object");
2519
+        glGenVertexArrays(n, objects, args...);
2520
+    }
2521
+    void static delete_objects(GLsizei n, GLuint const * objects)
2522
+    {
2523
+        if (GLBase::debug() >= 1)
2524
+            GLBase::check_supported({3, 0}, "GL_ARB_vertex_array_object");
2525
+        glDeleteVertexArrays(n, objects);
2526
+    }
2527
+};
2528
+
2529
+template <> struct GLTraits::Object<GL_FRAMEBUFFER>
2530
+{
2531
+    auto static constexpr name = "GL_"
2532
+                                 "FRAMEBUFFER";
2533
+    template <typename... Args>
2534
+    void static gen_objects(GLsizei n, GLuint * objects, Args... args)
2535
+    {
2536
+        if (GLBase::debug() >= 1)
2537
+            GLBase::check_supported({3, 0}, "GL_ARB_framebuffer_object");
2538
+        glGenFramebuffers(n, objects, args...);
2539
+    }
2540
+    void static delete_objects(GLsizei n, GLuint const * objects)
2541
+    {
2542
+        if (GLBase::debug() >= 1)
2543
+            GLBase::check_supported({3, 0}, "GL_ARB_framebuffer_object");
2544
+        glDeleteFramebuffers(n, objects);
2545
+    }
2546
+};
2547
+
2548
+template <> struct GLTraits::Object<GL_RENDERBUFFER>
2549
+{
2550
+    auto static constexpr name = "GL_"
2551
+                                 "RENDERBUFFER";
2552
+    template <typename... Args>
2553
+    void static gen_objects(GLsizei n, GLuint * objects, Args... args)
2554
+    {
2555
+        if (GLBase::debug() >= 1)
2556
+            GLBase::check_supported({3, 0}, "GL_ARB_framebuffer_object");
2557
+        glGenRenderbuffers(n, objects, args...);
2558
+    }
2559
+    void static delete_objects(GLsizei n, GLuint const * objects)
2560
+    {
2561
+        if (GLBase::debug() >= 1)
2562
+            GLBase::check_supported({3, 0}, "GL_ARB_framebuffer_object");
2563
+        glDeleteRenderbuffers(n, objects);
2564
+    }
2565
+};
2566
+
2567
+template <> struct GLTraits::Object<GL_SAMPLER>
2568
+{
2569
+    auto static constexpr name = "GL_"
2570
+                                 "SAMPLER";
2571
+    template <typename... Args>
2572
+    void static gen_objects(GLsizei n, GLuint * objects, Args... args)
2573
+    {
2574
+        if (GLBase::debug() >= 1)
2575
+            GLBase::check_supported({3, 3}, "GL_ARB_sampler_objects");
2576
+        glGenSamplers(n, objects, args...);
2577
+    }
2578
+    void static delete_objects(GLsizei n, GLuint const * objects)
2579
+    {
2580
+        if (GLBase::debug() >= 1)
2581
+            GLBase::check_supported({3, 3}, "GL_ARB_sampler_objects");
2582
+        glDeleteSamplers(n, objects);
2583
+    }
2584
+};
2585
+
2586
+template <> struct GLTraits::Object<GL_TRANSFORM_FEEDBACK>
2587
+{
2588
+    auto static constexpr name = "GL_"
2589
+                                 "TRANSFORM_FEEDBACK";
2590
+    template <typename... Args>
2591
+    void static gen_objects(GLsizei n, GLuint * objects, Args... args)
2592
+    {
2593
+        if (GLBase::debug() >= 1)
2594
+            GLBase::check_supported({4, 0}, "GL_ARB_transform_feedback2");
2595
+        glGenTransformFeedbacks(n, objects, args...);
2596
+    }
2597
+    void static delete_objects(GLsizei n, GLuint const * objects)
2598
+    {
2599
+        if (GLBase::debug() >= 1)
2600
+            GLBase::check_supported({4, 0}, "GL_ARB_transform_feedback2");
2601
+        glDeleteTransformFeedbacks(n, objects);
2602
+    }
2603
+};
2604
+
2605
+template <> struct GLTraits::Object<GL_PROGRAM_PIPELINE>
2606
+{
2607
+    auto static constexpr name = "GL_"
2608
+                                 "PROGRAM_PIPELINE";
2609
+    template <typename... Args>
2610
+    void static gen_objects(GLsizei n, GLuint * objects, Args... args)
2611
+    {
2612
+        if (GLBase::debug() >= 1)
2613
+            GLBase::check_supported({4, 1}, "GL_ARB_separate_shader_objects");
2614
+        glGenProgramPipelines(n, objects, args...);
2615
+    }
2616
+    void static delete_objects(GLsizei n, GLuint const * objects)
2617
+    {
2618
+        if (GLBase::debug() >= 1)
2619
+            GLBase::check_supported({4, 1}, "GL_ARB_separate_shader_objects");
2620
+        glDeleteProgramPipelines(n, objects);
2621
+    }
2622
+    std::string static info_log(GLuint object)
2623
+    {
2624
+        if (GLBase::debug() >= 1)
2625
+            GLBase::check_supported({4, 1}, "GL_ARB_separate_shader_objects");
2626
+        auto length = GLint{};
2627
+        glGetProgramPipelineiv(object, GL_INFO_LOG_LENGTH, &length);
2628
+        if (length != 0)
2629
+            --length;
2630
+        auto info_log = std::string((std::size_t)length, char{});
2631
+        glGetProgramPipelineInfoLog(object, length + 1, nullptr, &info_log[0]);
2632
+        return info_log;
2633
+    }
2634
+};
2635
+
Browse code

Add ValueID

Robert Cranston authored on 28/02/2023 02:16:10
Showing 1 changed files
... ...
@@ -3,6 +3,8 @@ class GLTraits
3 3
 
4 4
   public:
5 5
     template <typename> struct Value;
6
+
7
+    template <GLenum id> struct ValueID;
6 8
 };
7 9
 
8 10
 template <> struct GLTraits::Value<GLfloat>
... ...
@@ -20,6 +22,10 @@ template <> struct GLTraits::Value<GLfloat>
20 22
     auto static constexpr internal_format_compressed_srgb =
21 23
         GLenum{GL_COMPRESSED_SRGB};
22 24
     auto static constexpr integer = bool(*"");
25
+    auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) &&
26
+                                       sizeof(GLfloat) < sizeof(GLint)
27
+                                   ? type
28
+                                   : glsl;
23 29
     void static uniform(GLint location, GLfloat const & value)
24 30
     {
25 31
         if (GLBase::debug() >= 1)
... ...
@@ -56,6 +62,11 @@ template <> struct GLTraits::Value<GLfloat>
56 62
     }
57 63
 };
58 64
 
65
+template <> struct GLTraits::ValueID<GLTraits::Value<GLfloat>::id>
66
+{
67
+    using Value = GLfloat;
68
+};
69
+
59 70
 template <> struct GLTraits::Value<bool>
60 71
 {
61 72
     auto static constexpr name                 = "bool";
... ...
@@ -71,6 +82,10 @@ template <> struct GLTraits::Value<bool>
71 82
     auto static constexpr internal_format_compressed_srgb =
72 83
         GLenum{GL_COMPRESSED_SRGB};
73 84
     auto static constexpr integer = bool(*"_INTEGER");
85
+    auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) &&
86
+                                       sizeof(bool) < sizeof(GLint)
87
+                                   ? type
88
+                                   : glsl;
74 89
     void static uniform(GLint location, bool const & value)
75 90
     {
76 91
         if (GLBase::debug() >= 1)
... ...
@@ -106,6 +121,11 @@ template <> struct GLTraits::Value<bool>
106 121
     }
107 122
 };
108 123
 
124
+template <> struct GLTraits::ValueID<GLTraits::Value<bool>::id>
125
+{
126
+    using Value = bool;
127
+};
128
+
109 129
 template <> struct GLTraits::Value<GLbyte>
110 130
 {
111 131
     auto static constexpr name                 = "GLbyte";
... ...
@@ -121,6 +141,10 @@ template <> struct GLTraits::Value<GLbyte>
121 141
     auto static constexpr internal_format_compressed_srgb =
122 142
         GLenum{GL_COMPRESSED_SRGB};
123 143
     auto static constexpr integer = bool(*"_INTEGER");
144
+    auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) &&
145
+                                       sizeof(GLbyte) < sizeof(GLint)
146
+                                   ? type
147
+                                   : glsl;
124 148
     void static uniform(GLint location, GLbyte const & value)
125 149
     {
126 150
         if (GLBase::debug() >= 1)
... ...
@@ -156,6 +180,11 @@ template <> struct GLTraits::Value<GLbyte>
156 180
     }
157 181
 };
158 182
 
183
+template <> struct GLTraits::ValueID<GLTraits::Value<GLbyte>::id>
184
+{
185
+    using Value = GLbyte;
186
+};
187
+
159 188
 template <> struct GLTraits::Value<GLshort>
160 189
 {
161 190
     auto static constexpr name                 = "GLshort";
... ...
@@ -171,6 +200,10 @@ template <> struct GLTraits::Value<GLshort>
171 200
     auto static constexpr internal_format_compressed_srgb =
172 201
         GLenum{GL_COMPRESSED_SRGB};
173 202
     auto static constexpr integer = bool(*"_INTEGER");
203
+    auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) &&
204
+                                       sizeof(GLshort) < sizeof(GLint)
205
+                                   ? type
206
+                                   : glsl;
174 207
     void static uniform(GLint location, GLshort const & value)
175 208
     {
176 209
         if (GLBase::debug() >= 1)
... ...
@@ -206,6 +239,11 @@ template <> struct GLTraits::Value<GLshort>
206 239
     }
207 240
 };
208 241
 
242
+template <> struct GLTraits::ValueID<GLTraits::Value<GLshort>::id>
243
+{
244
+    using Value = GLshort;
245
+};
246
+
209 247
 template <> struct GLTraits::Value<GLint>
210 248
 {
211 249
     auto static constexpr name                 = "GLint";
... ...
@@ -221,6 +259,10 @@ template <> struct GLTraits::Value<GLint>
221 259
     auto static constexpr internal_format_compressed_srgb =
222 260
         GLenum{GL_COMPRESSED_SRGB};
223 261
     auto static constexpr integer = bool(*"_INTEGER");
262
+    auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) &&
263
+                                       sizeof(GLint) < sizeof(GLint)
264
+                                   ? type
265
+                                   : glsl;
224 266
     void static uniform(GLint location, GLint const & value)
225 267
     {
226 268
         if (GLBase::debug() >= 1)
... ...
@@ -256,6 +298,11 @@ template <> struct GLTraits::Value<GLint>
256 298
     }
257 299
 };
258 300
 
301
+template <> struct GLTraits::ValueID<GLTraits::Value<GLint>::id>
302
+{
303
+    using Value = GLint;
304
+};
305
+
259 306
 template <> struct GLTraits::Value<GLubyte>
260 307
 {
261 308
     auto static constexpr name                 = "GLubyte";
... ...
@@ -271,6 +318,10 @@ template <> struct GLTraits::Value<GLubyte>
271 318
     auto static constexpr internal_format_compressed_srgb =
272 319
         GLenum{GL_COMPRESSED_SRGB};
273 320
     auto static constexpr integer = bool(*"_INTEGER");
321
+    auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) &&
322
+                                       sizeof(GLubyte) < sizeof(GLint)
323
+                                   ? type
324
+                                   : glsl;
274 325
     void static uniform(GLint location, GLubyte const & value)
275 326
     {
276 327
         if (GLBase::debug() >= 1)
... ...
@@ -306,6 +357,11 @@ template <> struct GLTraits::Value<GLubyte>
306 357
     }
307 358
 };
308 359
 
360
+template <> struct GLTraits::ValueID<GLTraits::Value<GLubyte>::id>
361
+{
362
+    using Value = GLubyte;
363
+};
364
+
309 365
 template <> struct GLTraits::Value<GLushort>
310 366
 {
311 367
     auto static constexpr name                 = "GLushort";
... ...
@@ -321,6 +377,10 @@ template <> struct GLTraits::Value<GLushort>
321 377
     auto static constexpr internal_format_compressed_srgb =
322 378
         GLenum{GL_COMPRESSED_SRGB};
323 379
     auto static constexpr integer = bool(*"_INTEGER");
380
+    auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) &&
381
+                                       sizeof(GLushort) < sizeof(GLint)
382
+                                   ? type
383
+                                   : glsl;
324 384
     void static uniform(GLint location, GLushort const & value)
325 385
     {
326 386
         if (GLBase::debug() >= 1)
... ...
@@ -356,6 +416,11 @@ template <> struct GLTraits::Value<GLushort>
356 416
     }
357 417
 };
358 418
 
419
+template <> struct GLTraits::ValueID<GLTraits::Value<GLushort>::id>
420
+{
421
+    using Value = GLushort;
422
+};
423
+
359 424
 template <> struct GLTraits::Value<GLuint>
360 425
 {
361 426
     auto static constexpr name                 = "GLuint";
... ...
@@ -371,6 +436,10 @@ template <> struct GLTraits::Value<GLuint>
371 436
     auto static constexpr internal_format_compressed_srgb =
372 437
         GLenum{GL_COMPRESSED_SRGB};
373 438
     auto static constexpr integer = bool(*"_INTEGER");
439
+    auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) &&
440
+                                       sizeof(GLuint) < sizeof(GLint)
441
+                                   ? type
442
+                                   : glsl;
374 443
     void static uniform(GLint location, GLuint const & value)
375 444
     {
376 445
         if (GLBase::debug() >= 1)
... ...
@@ -406,6 +475,11 @@ template <> struct GLTraits::Value<GLuint>
406 475
     }
407 476
 };
408 477
 
478
+template <> struct GLTraits::ValueID<GLTraits::Value<GLuint>::id>
479
+{
480
+    using Value = GLuint;
481
+};
482
+
409 483
 template <> struct GLTraits::Value<GLdouble>
410 484
 {
411 485
     auto static constexpr name                 = "GLdouble";
... ...
@@ -421,6 +495,10 @@ template <> struct GLTraits::Value<GLdouble>
421 495
     auto static constexpr internal_format_compressed_srgb =
422 496
         GLenum{GL_COMPRESSED_SRGB};
423 497
     auto static constexpr integer = bool(*"");
498
+    auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) &&
499
+                                       sizeof(GLdouble) < sizeof(GLint)
500
+                                   ? type
501
+                                   : glsl;
424 502
     void static uniform(GLint location, GLdouble const & value)
425 503
     {
426 504
         if (GLBase::debug() >= 1)
... ...
@@ -456,6 +534,11 @@ template <> struct GLTraits::Value<GLdouble>
456 534
     }
457 535
 };
458 536
 
537
+template <> struct GLTraits::ValueID<GLTraits::Value<GLdouble>::id>
538
+{
539
+    using Value = GLdouble;
540
+};
541
+
459 542
 
460 543
 template <> struct GLTraits::Value<glm::vec2>
461 544
 {
... ...
@@ -472,6 +555,10 @@ template <> struct GLTraits::Value<glm::vec2>
472 555
     auto static constexpr internal_format_compressed_srgb =
473 556
         GLenum{GL_COMPRESSED_SRGB};
474 557
     auto static constexpr integer = bool(*"");
558
+    auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) &&
559
+                                       sizeof(glm::vec2) < sizeof(GLint)
560
+                                   ? type
561
+                                   : glsl;
475 562
     void static uniform(GLint location, glm::vec2 const & value)
476 563
     {
477 564
         if (GLBase::debug() >= 1)
... ...
@@ -510,6 +597,11 @@ template <> struct GLTraits::Value<glm::vec2>
510 597
     }
511 598
 };
512 599
 
600
+template <> struct GLTraits::ValueID<GLTraits::Value<glm::vec2>::id>
601
+{
602
+    using Value = glm::vec2;
603
+};
604
+
513 605
 template <> struct GLTraits::Value<glm::vec3>
514 606
 {
515 607
     auto static constexpr name                 = "glm::vec3";
... ...
@@ -525,6 +617,10 @@ template <> struct GLTraits::Value<glm::vec3>
525 617
     auto static constexpr internal_format_compressed_srgb =
526 618
         GLenum{GL_COMPRESSED_SRGB};
527 619
     auto static constexpr integer = bool(*"");
620
+    auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) &&
621
+                                       sizeof(glm::vec3) < sizeof(GLint)
622
+                                   ? type
623
+                                   : glsl;
528 624
     void static uniform(GLint location, glm::vec3 const & value)
529 625
     {
530 626
         if (GLBase::debug() >= 1)
... ...
@@ -563,6 +659,11 @@ template <> struct GLTraits::Value<glm::vec3>
563 659
     }
564 660
 };
565 661
 
662
+template <> struct GLTraits::ValueID<GLTraits::Value<glm::vec3>::id>
663
+{
664
+    using Value = glm::vec3;
665
+};
666
+
566 667
 template <> struct GLTraits::Value<glm::vec4>
567 668
 {
568 669
     auto static constexpr name                 = "glm::vec4";
... ...
@@ -578,6 +679,10 @@ template <> struct GLTraits::Value<glm::vec4>
578 679
     auto static constexpr internal_format_compressed_srgb =
579 680
         GLenum{GL_COMPRESSED_SRGB_ALPHA};
580 681
     auto static constexpr integer = bool(*"");
682
+    auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) &&
683
+                                       sizeof(glm::vec4) < sizeof(GLint)
684
+                                   ? type
685
+                                   : glsl;
581 686
     void static uniform(GLint location, glm::vec4 const & value)
582 687
     {
583 688
         if (GLBase::debug() >= 1)
... ...
@@ -616,6 +721,11 @@ template <> struct GLTraits::Value<glm::vec4>
616 721
     }
617 722
 };
618 723
 
724
+template <> struct GLTraits::ValueID<GLTraits::Value<glm::vec4>::id>
725
+{
726
+    using Value = glm::vec4;
727
+};
728
+
619 729
 template <> struct GLTraits::Value<glm::mat2>
620 730
 {
621 731
     auto static constexpr name                 = "glm::mat2";
... ...
@@ -631,6 +741,10 @@ template <> struct GLTraits::Value<glm::mat2>
631 741
     auto static constexpr internal_format_compressed_srgb =
632 742
         GLenum{GL_COMPRESSED_SRGB};
633 743
     auto static constexpr integer = bool(*"");
744
+    auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) &&
745
+                                       sizeof(glm::mat2) < sizeof(GLint)
746
+                                   ? type
747
+                                   : glsl;
634 748
     void static uniform(GLint location, glm::mat2 const & value)
635 749
     {
636 750
         if (GLBase::debug() >= 1)
... ...
@@ -669,6 +783,11 @@ template <> struct GLTraits::Value<glm::mat2>
669 783
     }
670 784
 };
671 785
 
786
+template <> struct GLTraits::ValueID<GLTraits::Value<glm::mat2>::id>
787
+{
788
+    using Value = glm::mat2;
789
+};
790
+
672 791
 template <> struct GLTraits::Value<glm::mat2x3>
673 792
 {
674 793
     auto static constexpr name                 = "glm::mat2x3";
... ...
@@ -684,6 +803,10 @@ template <> struct GLTraits::Value<glm::mat2x3>
684 803
     auto static constexpr internal_format_compressed_srgb =
685 804
         GLenum{GL_COMPRESSED_SRGB};
686 805
     auto static constexpr integer = bool(*"");
806
+    auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) &&
807
+                                       sizeof(glm::mat2x3) < sizeof(GLint)
808
+                                   ? type
809
+                                   : glsl;
687 810
     void static uniform(GLint location, glm::mat2x3 const & value)
688 811
     {
689 812
         if (GLBase::debug() >= 1)
... ...
@@ -722,6 +845,11 @@ template <> struct GLTraits::Value<glm::mat2x3>
722 845
     }
723 846
 };
724 847
 
848
+template <> struct GLTraits::ValueID<GLTraits::Value<glm::mat2x3>::id>
849
+{
850
+    using Value = glm::mat2x3;
851
+};
852
+
725 853
 template <> struct GLTraits::Value<glm::mat2x4>
726 854
 {
727 855
     auto static constexpr name                 = "glm::mat2x4";
... ...
@@ -737,6 +865,10 @@ template <> struct GLTraits::Value<glm::mat2x4>
737 865
     auto static constexpr internal_format_compressed_srgb =
738 866
         GLenum{GL_COMPRESSED_SRGB_ALPHA};
739 867
     auto static constexpr integer = bool(*"");
868
+    auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) &&
869
+                                       sizeof(glm::mat2x4) < sizeof(GLint)
870
+                                   ? type
871
+                                   : glsl;
740 872
     void static uniform(GLint location, glm::mat2x4 const & value)
741 873
     {
742 874
         if (GLBase::debug() >= 1)
... ...
@@ -775,6 +907,11 @@ template <> struct GLTraits::Value<glm::mat2x4>
775 907
     }
776 908
 };
777 909
 
910
+template <> struct GLTraits::ValueID<GLTraits::Value<glm::mat2x4>::id>
911
+{
912
+    using Value = glm::mat2x4;
913
+};
914
+
778 915
 template <> struct GLTraits::Value<glm::mat3x2>
779 916
 {
780 917
     auto static constexpr name                 = "glm::mat3x2";
... ...
@@ -790,6 +927,10 @@ template <> struct GLTraits::Value<glm::mat3x2>
790 927
     auto static constexpr internal_format_compressed_srgb =
791 928
         GLenum{GL_COMPRESSED_SRGB};
792 929
     auto static constexpr integer = bool(*"");
930
+    auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) &&
931
+                                       sizeof(glm::mat3x2) < sizeof(GLint)
932
+                                   ? type
933
+                                   : glsl;
793 934
     void static uniform(GLint location, glm::mat3x2 const & value)
794 935
     {
795 936
         if (GLBase::debug() >= 1)
... ...
@@ -828,6 +969,11 @@ template <> struct GLTraits::Value<glm::mat3x2>
828 969
     }
829 970
 };
830 971
 
972
+template <> struct GLTraits::ValueID<GLTraits::Value<glm::mat3x2>::id>
973
+{
974
+    using Value = glm::mat3x2;
975
+};
976
+
831 977
 template <> struct GLTraits::Value<glm::mat3>
832 978
 {
833 979
     auto static constexpr name                 = "glm::mat3";
... ...
@@ -843,6 +989,10 @@ template <> struct GLTraits::Value<glm::mat3>
843 989
     auto static constexpr internal_format_compressed_srgb =
844 990
         GLenum{GL_COMPRESSED_SRGB};
845 991
     auto static constexpr integer = bool(*"");
992
+    auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) &&
993
+                                       sizeof(glm::mat3) < sizeof(GLint)
994
+                                   ? type
995
+                                   : glsl;
846 996
     void static uniform(GLint location, glm::mat3 const & value)
847 997
     {
848 998
         if (GLBase::debug() >= 1)
... ...
@@ -881,6 +1031,11 @@ template <> struct GLTraits::Value<glm::mat3>
881 1031
     }
882 1032
 };
883 1033
 
1034
+template <> struct GLTraits::ValueID<GLTraits::Value<glm::mat3>::id>
1035
+{
1036
+    using Value = glm::mat3;
1037
+};
1038
+
884 1039
 template <> struct GLTraits::Value<glm::mat3x4>
885 1040
 {
886 1041
     auto static constexpr name                 = "glm::mat3x4";
... ...
@@ -896,6 +1051,10 @@ template <> struct GLTraits::Value<glm::mat3x4>
896 1051
     auto static constexpr internal_format_compressed_srgb =
897 1052
         GLenum{GL_COMPRESSED_SRGB_ALPHA};
898 1053
     auto static constexpr integer = bool(*"");
1054
+    auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) &&
1055
+                                       sizeof(glm::mat3x4) < sizeof(GLint)
1056
+                                   ? type
1057
+                                   : glsl;
899 1058
     void static uniform(GLint location, glm::mat3x4 const & value)
900 1059
     {
901 1060
         if (GLBase::debug() >= 1)
... ...
@@ -934,6 +1093,11 @@ template <> struct GLTraits::Value<glm::mat3x4>
934 1093
     }
935 1094
 };
936 1095
 
1096
+template <> struct GLTraits::ValueID<GLTraits::Value<glm::mat3x4>::id>
1097
+{
1098
+    using Value = glm::mat3x4;
1099
+};
1100
+
937 1101
 template <> struct GLTraits::Value<glm::mat4x2>
938 1102
 {
939 1103
     auto static constexpr name                 = "glm::mat4x2";
... ...
@@ -949,6 +1113,10 @@ template <> struct GLTraits::Value<glm::mat4x2>
949 1113
     auto static constexpr internal_format_compressed_srgb =
950 1114
         GLenum{GL_COMPRESSED_SRGB};
951 1115
     auto static constexpr integer = bool(*"");
1116
+    auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) &&
1117
+                                       sizeof(glm::mat4x2) < sizeof(GLint)
1118
+                                   ? type
1119
+                                   : glsl;
952 1120
     void static uniform(GLint location, glm::mat4x2 const & value)
953 1121
     {
954 1122
         if (GLBase::debug() >= 1)
... ...
@@ -987,6 +1155,11 @@ template <> struct GLTraits::Value<glm::mat4x2>
987 1155
     }
988 1156
 };
989 1157
 
1158
+template <> struct GLTraits::ValueID<GLTraits::Value<glm::mat4x2>::id>
1159
+{
1160
+    using Value = glm::mat4x2;
1161
+};
1162
+
990 1163
 template <> struct GLTraits::Value<glm::mat4x3>
991 1164
 {
992 1165
     auto static constexpr name                 = "glm::mat4x3";
... ...
@@ -1002,6 +1175,10 @@ template <> struct GLTraits::Value<glm::mat4x3>
1002 1175
     auto static constexpr internal_format_compressed_srgb =
1003 1176
         GLenum{GL_COMPRESSED_SRGB};
1004 1177
     auto static constexpr integer = bool(*"");
1178
+    auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) &&
1179
+                                       sizeof(glm::mat4x3) < sizeof(GLint)
1180
+                                   ? type
1181
+                                   : glsl;
1005 1182
     void static uniform(GLint location, glm::mat4x3 const & value)
1006 1183
     {
1007 1184
         if (GLBase::debug() >= 1)
... ...
@@ -1040,6 +1217,11 @@ template <> struct GLTraits::Value<glm::mat4x3>
1040 1217
     }
1041 1218
 };
1042 1219
 
1220
+template <> struct GLTraits::ValueID<GLTraits::Value<glm::mat4x3>::id>
1221
+{
1222
+    using Value = glm::mat4x3;
1223
+};
1224
+
1043 1225
 template <> struct GLTraits::Value<glm::mat4>
1044 1226
 {
1045 1227
     auto static constexpr name                 = "glm::mat4";
... ...
@@ -1055,6 +1237,10 @@ template <> struct GLTraits::Value<glm::mat4>
1055 1237
     auto static constexpr internal_format_compressed_srgb =
1056 1238
         GLenum{GL_COMPRESSED_SRGB_ALPHA};
1057 1239
     auto static constexpr integer = bool(*"");
1240
+    auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) &&
1241
+                                       sizeof(glm::mat4) < sizeof(GLint)
1242
+                                   ? type
1243
+                                   : glsl;
1058 1244
     void static uniform(GLint location, glm::mat4 const & value)
1059 1245
     {
1060 1246
         if (GLBase::debug() >= 1)
... ...
@@ -1093,6 +1279,11 @@ template <> struct GLTraits::Value<glm::mat4>
1093 1279
     }
1094 1280
 };
1095 1281
 
1282
+template <> struct GLTraits::ValueID<GLTraits::Value<glm::mat4>::id>
1283
+{
1284
+    using Value = glm::mat4;
1285
+};
1286
+
1096 1287
 template <> struct GLTraits::Value<glm::ivec2>
1097 1288
 {
1098 1289
     auto static constexpr name                 = "glm::ivec2";
... ...
@@ -1108,6 +1299,10 @@ template <> struct GLTraits::Value<glm::ivec2>
1108 1299
     auto static constexpr internal_format_compressed_srgb =
1109 1300
         GLenum{GL_COMPRESSED_SRGB};
1110 1301
     auto static constexpr integer = bool(*"_INTEGER");
1302
+    auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) &&
1303
+                                       sizeof(glm::ivec2) < sizeof(GLint)
1304
+                                   ? type
1305
+                                   : glsl;
1111 1306
     void static uniform(GLint location, glm::ivec2 const & value)
1112 1307
     {
1113 1308
         if (GLBase::debug() >= 1)
... ...
@@ -1145,6 +1340,11 @@ template <> struct GLTraits::Value<glm::ivec2>
1145 1340
     }
1146 1341
 };
1147 1342
 
1343
+template <> struct GLTraits::ValueID<GLTraits::Value<glm::ivec2>::id>
1344
+{
1345
+    using Value = glm::ivec2;
1346
+};
1347
+
1148 1348
 template <> struct GLTraits::Value<glm::ivec3>
1149 1349
 {
1150 1350
     auto static constexpr name                 = "glm::ivec3";
... ...
@@ -1160,6 +1360,10 @@ template <> struct GLTraits::Value<glm::ivec3>
1160 1360
     auto static constexpr internal_format_compressed_srgb =
1161 1361
         GLenum{GL_COMPRESSED_SRGB};
1162 1362
     auto static constexpr integer = bool(*"_INTEGER");
1363
+    auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) &&
1364
+                                       sizeof(glm::ivec3) < sizeof(GLint)
1365
+                                   ? type
1366
+                                   : glsl;
1163 1367
     void static uniform(GLint location, glm::ivec3 const & value)
1164 1368
     {
1165 1369
         if (GLBase::debug() >= 1)
... ...
@@ -1197,6 +1401,11 @@ template <> struct GLTraits::Value<glm::ivec3>
1197 1401
     }
1198 1402
 };
1199 1403
 
1404
+template <> struct GLTraits::ValueID<GLTraits::Value<glm::ivec3>::id>
1405
+{
1406
+    using Value = glm::ivec3;
1407
+};
1408
+
1200 1409
 template <> struct GLTraits::Value<glm::ivec4>
1201 1410
 {
1202 1411
     auto static constexpr name                 = "glm::ivec4";
... ...
@@ -1212,6 +1421,10 @@ template <> struct GLTraits::Value<glm::ivec4>
1212 1421
     auto static constexpr internal_format_compressed_srgb =
1213 1422
         GLenum{GL_COMPRESSED_SRGB_ALPHA};
1214 1423
     auto static constexpr integer = bool(*"_INTEGER");
1424
+    auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) &&
1425
+                                       sizeof(glm::ivec4) < sizeof(GLint)
1426
+                                   ? type
1427
+                                   : glsl;
1215 1428
     void static uniform(GLint location, glm::ivec4 const & value)
1216 1429
     {
1217 1430
         if (GLBase::debug() >= 1)
... ...
@@ -1249,6 +1462,11 @@ template <> struct GLTraits::Value<glm::ivec4>
1249 1462
     }
1250 1463
 };
1251 1464
 
1465
+template <> struct GLTraits::ValueID<GLTraits::Value<glm::ivec4>::id>
1466
+{
1467
+    using Value = glm::ivec4;
1468
+};
1469
+
1252 1470
 template <> struct GLTraits::Value<glm::uvec2>
1253 1471
 {
1254 1472
     auto static constexpr name                 = "glm::uvec2";
... ...
@@ -1264,6 +1482,10 @@ template <> struct GLTraits::Value<glm::uvec2>
1264 1482
     auto static constexpr internal_format_compressed_srgb =
1265 1483
         GLenum{GL_COMPRESSED_SRGB};
1266 1484
     auto static constexpr integer = bool(*"_INTEGER");
1485
+    auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) &&
1486
+                                       sizeof(glm::uvec2) < sizeof(GLint)
1487
+                                   ? type
1488
+                                   : glsl;
1267 1489
     void static uniform(GLint location, glm::uvec2 const & value)
1268 1490
     {
1269 1491
         if (GLBase::debug() >= 1)
... ...
@@ -1301,6 +1523,11 @@ template <> struct GLTraits::Value<glm::uvec2>
1301 1523
     }
1302 1524
 };
1303 1525
 
1526
+template <> struct GLTraits::ValueID<GLTraits::Value<glm::uvec2>::id>
1527
+{
1528
+    using Value = glm::uvec2;
1529
+};
1530
+
1304 1531
 template <> struct GLTraits::Value<glm::uvec3>
1305 1532
 {
1306 1533
     auto static constexpr name                 = "glm::uvec3";
... ...
@@ -1316,6 +1543,10 @@ template <> struct GLTraits::Value<glm::uvec3>
1316 1543
     auto static constexpr internal_format_compressed_srgb =
1317 1544
         GLenum{GL_COMPRESSED_SRGB};
1318 1545
     auto static constexpr integer = bool(*"_INTEGER");
1546
+    auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) &&
1547
+                                       sizeof(glm::uvec3) < sizeof(GLint)
1548
+                                   ? type
1549
+                                   : glsl;
1319 1550
     void static uniform(GLint location, glm::uvec3 const & value)
1320 1551
     {
1321 1552
         if (GLBase::debug() >= 1)
... ...
@@ -1353,6 +1584,11 @@ template <> struct GLTraits::Value<glm::uvec3>
1353 1584
     }
1354 1585
 };
1355 1586
 
1587
+template <> struct GLTraits::ValueID<GLTraits::Value<glm::uvec3>::id>
1588
+{
1589
+    using Value = glm::uvec3;
1590
+};
1591
+
1356 1592
 template <> struct GLTraits::Value<glm::uvec4>
1357 1593
 {
1358 1594
     auto static constexpr name                 = "glm::uvec4";
... ...
@@ -1368,6 +1604,10 @@ template <> struct GLTraits::Value<glm::uvec4>
1368 1604
     auto static constexpr internal_format_compressed_srgb =
1369 1605
         GLenum{GL_COMPRESSED_SRGB_ALPHA};
1370 1606
     auto static constexpr integer = bool(*"_INTEGER");
1607
+    auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) &&
1608
+                                       sizeof(glm::uvec4) < sizeof(GLint)
1609
+                                   ? type
1610
+                                   : glsl;
1371 1611
     void static uniform(GLint location, glm::uvec4 const & value)
1372 1612
     {
1373 1613
         if (GLBase::debug() >= 1)
... ...
@@ -1405,6 +1645,11 @@ template <> struct GLTraits::Value<glm::uvec4>
1405 1645
     }
1406 1646
 };
1407 1647
 
1648
+template <> struct GLTraits::ValueID<GLTraits::Value<glm::uvec4>::id>
1649
+{
1650
+    using Value = glm::uvec4;
1651
+};
1652
+
1408 1653
 template <> struct GLTraits::Value<glm::dvec2>
1409 1654
 {
1410 1655
     auto static constexpr name                 = "glm::dvec2";
... ...
@@ -1420,6 +1665,10 @@ template <> struct GLTraits::Value<glm::dvec2>
1420 1665
     auto static constexpr internal_format_compressed_srgb =
1421 1666
         GLenum{GL_COMPRESSED_SRGB};
1422 1667
     auto static constexpr integer = bool(*"");
1668
+    auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) &&
1669
+                                       sizeof(glm::dvec2) < sizeof(GLint)
1670
+                                   ? type
1671
+                                   : glsl;
1423 1672
     void static uniform(GLint location, glm::dvec2 const & value)
1424 1673
     {
1425 1674
         if (GLBase::debug() >= 1)
... ...
@@ -1457,6 +1706,11 @@ template <> struct GLTraits::Value<glm::dvec2>
1457 1706
     }
1458 1707
 };
1459 1708
 
1709
+template <> struct GLTraits::ValueID<GLTraits::Value<glm::dvec2>::id>
1710
+{
1711
+    using Value = glm::dvec2;
1712
+};
1713
+
1460 1714
 template <> struct GLTraits::Value<glm::dvec3>
1461 1715
 {
1462 1716
     auto static constexpr name                 = "glm::dvec3";
... ...
@@ -1472,6 +1726,10 @@ template <> struct GLTraits::Value<glm::dvec3>
1472 1726
     auto static constexpr internal_format_compressed_srgb =
1473 1727
         GLenum{GL_COMPRESSED_SRGB};
1474 1728
     auto static constexpr integer = bool(*"");
1729
+    auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) &&
1730
+                                       sizeof(glm::dvec3) < sizeof(GLint)
1731
+                                   ? type
1732
+                                   : glsl;
1475 1733
     void static uniform(GLint location, glm::dvec3 const & value)
1476 1734
     {
1477 1735
         if (GLBase::debug() >= 1)
... ...
@@ -1509,6 +1767,11 @@ template <> struct GLTraits::Value<glm::dvec3>
1509 1767
     }
1510 1768
 };
1511 1769
 
1770
+template <> struct GLTraits::ValueID<GLTraits::Value<glm::dvec3>::id>
1771
+{
1772
+    using Value = glm::dvec3;
1773
+};
1774
+
1512 1775
 template <> struct GLTraits::Value<glm::dvec4>
1513 1776
 {
1514 1777
     auto static constexpr name                 = "glm::dvec4";
... ...
@@ -1524,6 +1787,10 @@ template <> struct GLTraits::Value<glm::dvec4>
1524 1787
     auto static constexpr internal_format_compressed_srgb =
1525 1788
         GLenum{GL_COMPRESSED_SRGB_ALPHA};
1526 1789
     auto static constexpr integer = bool(*"");
1790
+    auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) &&
1791
+                                       sizeof(glm::dvec4) < sizeof(GLint)
1792
+                                   ? type
1793
+                                   : glsl;
1527 1794
     void static uniform(GLint location, glm::dvec4 const & value)
1528 1795
     {
1529 1796
         if (GLBase::debug() >= 1)
... ...
@@ -1561,6 +1828,11 @@ template <> struct GLTraits::Value<glm::dvec4>
1561 1828
     }
1562 1829
 };
1563 1830
 
1831
+template <> struct GLTraits::ValueID<GLTraits::Value<glm::dvec4>::id>
1832
+{
1833
+    using Value = glm::dvec4;
1834
+};
1835
+
1564 1836
 template <> struct GLTraits::Value<glm::dmat2>
1565 1837
 {
1566 1838
     auto static constexpr name                 = "glm::dmat2";
... ...
@@ -1576,6 +1848,10 @@ template <> struct GLTraits::Value<glm::dmat2>
1576 1848
     auto static constexpr internal_format_compressed_srgb =
1577 1849
         GLenum{GL_COMPRESSED_SRGB};
1578 1850
     auto static constexpr integer = bool(*"");
1851
+    auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) &&
1852
+                                       sizeof(glm::dmat2) < sizeof(GLint)
1853
+                                   ? type
1854
+                                   : glsl;
1579 1855
     void static uniform(GLint location, glm::dmat2 const & value)
1580 1856
     {
1581 1857
         if (GLBase::debug() >= 1)
... ...
@@ -1613,6 +1889,11 @@ template <> struct GLTraits::Value<glm::dmat2>
1613 1889
     }
1614 1890
 };
1615 1891
 
1892
+template <> struct GLTraits::ValueID<GLTraits::Value<glm::dmat2>::id>
1893
+{
1894
+    using Value = glm::dmat2;
1895
+};
1896
+
1616 1897
 template <> struct GLTraits::Value<glm::dmat2x3>
1617 1898
 {
1618 1899
     auto static constexpr name                 = "glm::dmat2x3";
... ...
@@ -1628,6 +1909,10 @@ template <> struct GLTraits::Value<glm::dmat2x3>
1628 1909
     auto static constexpr internal_format_compressed_srgb =
1629 1910
         GLenum{GL_COMPRESSED_SRGB};
1630 1911
     auto static constexpr integer = bool(*"");
1912
+    auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) &&
1913
+                                       sizeof(glm::dmat2x3) < sizeof(GLint)
1914
+                                   ? type
1915
+                                   : glsl;
1631 1916
     void static uniform(GLint location, glm::dmat2x3 const & value)
1632 1917
     {
1633 1918
         if (GLBase::debug() >= 1)
... ...
@@ -1665,6 +1950,11 @@ template <> struct GLTraits::Value<glm::dmat2x3>
1665 1950
     }
1666 1951
 };
1667 1952
 
1953
+template <> struct GLTraits::ValueID<GLTraits::Value<glm::dmat2x3>::id>
1954
+{
1955
+    using Value = glm::dmat2x3;
1956
+};
1957
+
1668 1958
 template <> struct GLTraits::Value<glm::dmat2x4>
1669 1959
 {
1670 1960
     auto static constexpr name                 = "glm::dmat2x4";
... ...
@@ -1680,6 +1970,10 @@ template <> struct GLTraits::Value<glm::dmat2x4>
1680 1970
     auto static constexpr internal_format_compressed_srgb =
1681 1971
         GLenum{GL_COMPRESSED_SRGB_ALPHA};
1682 1972
     auto static constexpr integer = bool(*"");
1973
+    auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) &&
1974
+                                       sizeof(glm::dmat2x4) < sizeof(GLint)
1975
+                                   ? type
1976
+                                   : glsl;
1683 1977
     void static uniform(GLint location, glm::dmat2x4 const & value)
1684 1978
     {
1685 1979
         if (GLBase::debug() >= 1)
... ...
@@ -1717,6 +2011,11 @@ template <> struct GLTraits::Value<glm::dmat2x4>
1717 2011
     }
1718 2012
 };
1719 2013
 
2014
+template <> struct GLTraits::ValueID<GLTraits::Value<glm::dmat2x4>::id>
2015
+{
2016
+    using Value = glm::dmat2x4;
2017
+};
2018
+
1720 2019
 template <> struct GLTraits::Value<glm::dmat3x2>
1721 2020
 {
1722 2021
     auto static constexpr name                 = "glm::dmat3x2";
... ...
@@ -1732,6 +2031,10 @@ template <> struct GLTraits::Value<glm::dmat3x2>
1732 2031
     auto static constexpr internal_format_compressed_srgb =
1733 2032
         GLenum{GL_COMPRESSED_SRGB};
1734 2033
     auto static constexpr integer = bool(*"");
2034
+    auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) &&
2035
+                                       sizeof(glm::dmat3x2) < sizeof(GLint)
2036
+                                   ? type
2037
+                                   : glsl;
1735 2038
     void static uniform(GLint location, glm::dmat3x2 const & value)
1736 2039
     {
1737 2040
         if (GLBase::debug() >= 1)
... ...
@@ -1769,6 +2072,11 @@ template <> struct GLTraits::Value<glm::dmat3x2>
1769 2072
     }
1770 2073
 };
1771 2074
 
2075
+template <> struct GLTraits::ValueID<GLTraits::Value<glm::dmat3x2>::id>
2076
+{
2077
+    using Value = glm::dmat3x2;
2078
+};
2079
+
1772 2080
 template <> struct GLTraits::Value<glm::dmat3>
1773 2081
 {
1774 2082
     auto static constexpr name                 = "glm::dmat3";
... ...
@@ -1784,6 +2092,10 @@ template <> struct GLTraits::Value<glm::dmat3>
1784 2092
     auto static constexpr internal_format_compressed_srgb =
1785 2093
         GLenum{GL_COMPRESSED_SRGB};
1786 2094
     auto static constexpr integer = bool(*"");
2095
+    auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) &&
2096
+                                       sizeof(glm::dmat3) < sizeof(GLint)
2097
+                                   ? type
2098
+                                   : glsl;
1787 2099
     void static uniform(GLint location, glm::dmat3 const & value)
1788 2100
     {
1789 2101
         if (GLBase::debug() >= 1)
... ...
@@ -1821,6 +2133,11 @@ template <> struct GLTraits::Value<glm::dmat3>
1821 2133
     }
1822 2134
 };
1823 2135
 
2136
+template <> struct GLTraits::ValueID<GLTraits::Value<glm::dmat3>::id>
2137
+{
2138
+    using Value = glm::dmat3;
2139
+};
2140
+
1824 2141
 template <> struct GLTraits::Value<glm::dmat3x4>
1825 2142
 {
1826 2143
     auto static constexpr name                 = "glm::dmat3x4";
... ...
@@ -1836,6 +2153,10 @@ template <> struct GLTraits::Value<glm::dmat3x4>
1836 2153
     auto static constexpr internal_format_compressed_srgb =
1837 2154
         GLenum{GL_COMPRESSED_SRGB_ALPHA};
1838 2155
     auto static constexpr integer = bool(*"");
2156
+    auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) &&
2157
+                                       sizeof(glm::dmat3x4) < sizeof(GLint)
2158
+                                   ? type
2159
+                                   : glsl;
1839 2160
     void static uniform(GLint location, glm::dmat3x4 const & value)
1840 2161
     {
1841 2162
         if (GLBase::debug() >= 1)
... ...
@@ -1873,6 +2194,11 @@ template <> struct GLTraits::Value<glm::dmat3x4>
1873 2194
     }
1874 2195
 };
1875 2196
 
2197
+template <> struct GLTraits::ValueID<GLTraits::Value<glm::dmat3x4>::id>
2198
+{
2199
+    using Value = glm::dmat3x4;
2200
+};
2201
+
1876 2202
 template <> struct GLTraits::Value<glm::dmat4x2>
1877 2203
 {
1878 2204
     auto static constexpr name                 = "glm::dmat4x2";
... ...
@@ -1888,6 +2214,10 @@ template <> struct GLTraits::Value<glm::dmat4x2>
1888 2214
     auto static constexpr internal_format_compressed_srgb =
1889 2215
         GLenum{GL_COMPRESSED_SRGB};
1890 2216
     auto static constexpr integer = bool(*"");
2217
+    auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) &&
2218
+                                       sizeof(glm::dmat4x2) < sizeof(GLint)
2219
+                                   ? type
2220
+                                   : glsl;
1891 2221
     void static uniform(GLint location, glm::dmat4x2 const & value)
1892 2222
     {
1893 2223
         if (GLBase::debug() >= 1)
... ...
@@ -1925,6 +2255,11 @@ template <> struct GLTraits::Value<glm::dmat4x2>
1925 2255
     }
1926 2256
 };
1927 2257
 
2258
+template <> struct GLTraits::ValueID<GLTraits::Value<glm::dmat4x2>::id>
2259
+{
2260
+    using Value = glm::dmat4x2;
2261
+};
2262
+
1928 2263
 template <> struct GLTraits::Value<glm::dmat4x3>
1929 2264
 {
1930 2265
     auto static constexpr name                 = "glm::dmat4x3";
... ...
@@ -1940,6 +2275,10 @@ template <> struct GLTraits::Value<glm::dmat4x3>
1940 2275
     auto static constexpr internal_format_compressed_srgb =
1941 2276
         GLenum{GL_COMPRESSED_SRGB};
1942 2277
     auto static constexpr integer = bool(*"");
2278
+    auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) &&
2279
+                                       sizeof(glm::dmat4x3) < sizeof(GLint)
2280
+                                   ? type
2281
+                                   : glsl;
1943 2282
     void static uniform(GLint location, glm::dmat4x3 const & value)
1944 2283
     {
1945 2284
         if (GLBase::debug() >= 1)
... ...
@@ -1977,6 +2316,11 @@ template <> struct GLTraits::Value<glm::dmat4x3>
1977 2316
     }
1978 2317
 };
1979 2318
 
2319
+template <> struct GLTraits::ValueID<GLTraits::Value<glm::dmat4x3>::id>
2320
+{
2321
+    using Value = glm::dmat4x3;
2322
+};
2323
+
1980 2324
 template <> struct GLTraits::Value<glm::dmat4>
1981 2325
 {
1982 2326
     auto static constexpr name                 = "glm::dmat4";
... ...
@@ -1992,6 +2336,10 @@ template <> struct GLTraits::Value<glm::dmat4>
1992 2336
     auto static constexpr internal_format_compressed_srgb =
1993 2337
         GLenum{GL_COMPRESSED_SRGB_ALPHA};
1994 2338
     auto static constexpr integer = bool(*"");
2339
+    auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) &&
2340
+                                       sizeof(glm::dmat4) < sizeof(GLint)
2341
+                                   ? type
2342
+                                   : glsl;
1995 2343
     void static uniform(GLint location, glm::dmat4 const & value)
1996 2344
     {
1997 2345
         if (GLBase::debug() >= 1)
... ...
@@ -2029,3 +2377,8 @@ template <> struct GLTraits::Value<glm::dmat4>
2029 2377
     }
2030 2378
 };
2031 2379
 
2380
+template <> struct GLTraits::ValueID<GLTraits::Value<glm::dmat4>::id>
2381
+{
2382
+    using Value = glm::dmat4;
2383
+};
2384
+
Browse code

Add Value

Robert Cranston authored on 15/10/2022 19:02:09
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,2031 @@
1
+class GLTraits
2
+{
3
+
4
+  public:
5
+    template <typename> struct Value;
6
+};
7
+
8
+template <> struct GLTraits::Value<GLfloat>
9
+{
10
+    auto static constexpr name                 = "GLfloat";
11
+    auto static constexpr columns              = GLint{1};
12
+    auto static constexpr rows                 = GLint{1};
13
+    auto static constexpr glsl                 = GLenum{GL_FLOAT};
14
+    auto static constexpr format               = GLenum{GL_RED};
15
+    auto static constexpr type                 = GLenum{GL_FLOAT};
16
+    auto static constexpr internal_format      = GLenum{GL_R32F};
17
+    auto static constexpr internal_format_srgb = GLenum{GL_SR8_EXT};
18
+    auto static constexpr internal_format_compressed =
19
+        GLenum{GL_COMPRESSED_RED};
20
+    auto static constexpr internal_format_compressed_srgb =
21
+        GLenum{GL_COMPRESSED_SRGB};
22
+    auto static constexpr integer = bool(*"");
23
+    void static uniform(GLint location, GLfloat const & value)
24
+    {
25
+        if (GLBase::debug() >= 1)
26
+            GLBase::check_supported({2, 0}, {});
27
+        glUniform1f(location, (value));
28
+    }
29
+    void static vertex_attrib(GLint location, GLfloat const & value)
30
+    {
31
+        if (GLBase::debug() >= 1)
32
+            GLBase::check_supported({2, 0}, {});
33
+        if (location == -1)
34
+            return;
35
+        for (auto column = GLuint{0}; column < columns; ++column)
36
+            glVertexAttrib1f((GLuint)location + column, (value));
37
+    }
38
+    void static vertex_attrib_pointer(
39
+        GLint       location,
40
+        std::size_t offset = 0,
41
+        std::size_t stride = sizeof(GLfloat))
42
+    {
43
+        if (GLBase::debug() >= 1)
44
+            GLBase::check_supported({2, 0}, {});
45
+        if (location == -1)
46
+            return;
47
+        auto constexpr sizeof_column = sizeof(GLfloat) / columns;
48
+        for (auto column = GLuint{0}; column < columns; ++column)
49
+            glVertexAttribPointer(
50
+                (GLuint)location + column,
51
+                rows,
52
+                type,
53
+                GL_FALSE,
54
+                (GLsizei)stride,
55
+                (void const *)(offset + sizeof_column * column));
56
+    }
57
+};
58
+
59
+template <> struct GLTraits::Value<bool>
60
+{
61
+    auto static constexpr name                 = "bool";
62
+    auto static constexpr columns              = GLint{1};
63
+    auto static constexpr rows                 = GLint{1};
64
+    auto static constexpr glsl                 = GLenum{GL_BOOL};
65
+    auto static constexpr format               = GLenum{GL_RED_INTEGER};
66
+    auto static constexpr type                 = GLenum{GL_BYTE};
67
+    auto static constexpr internal_format      = GLenum{GL_R8I};
68
+    auto static constexpr internal_format_srgb = GLenum{GL_SR8_EXT};
69
+    auto static constexpr internal_format_compressed =
70
+        GLenum{GL_COMPRESSED_RED};
71
+    auto static constexpr internal_format_compressed_srgb =
72
+        GLenum{GL_COMPRESSED_SRGB};
73
+    auto static constexpr integer = bool(*"_INTEGER");
74
+    void static uniform(GLint location, bool const & value)
75
+    {
76
+        if (GLBase::debug() >= 1)
77
+            GLBase::check_supported({2, 0}, {});
78
+        glUniform1i(location, (value));
79
+    }
80
+    void static vertex_attrib(GLint location, bool const & value)
81
+    {
82
+        if (GLBase::debug() >= 1)
83
+            GLBase::check_supported({3, 0}, {});
84
+        if (location == -1)
85
+            return;
86
+        for (auto column = GLuint{0}; column < columns; ++column)
87
+            glVertexAttribI1i((GLuint)location + column, (value));
88
+    }
89
+    void static vertex_attrib_pointer(
90
+        GLint       location,
91
+        std::size_t offset = 0,
92
+        std::size_t stride = sizeof(bool))
93
+    {
94
+        if (GLBase::debug() >= 1)
95
+            GLBase::check_supported({3, 0}, {});
96
+        if (location == -1)
97
+            return;
98
+        auto constexpr sizeof_column = sizeof(bool) / columns;
99
+        for (auto column = GLuint{0}; column < columns; ++column)
100
+            glVertexAttribIPointer(
101
+                (GLuint)location + column,
102
+                rows,
103
+                type,
104
+                (GLsizei)stride,
105
+                (void const *)(offset + sizeof_column * column));
106
+    }
107
+};
108
+
109
+template <> struct GLTraits::Value<GLbyte>
110
+{
111
+    auto static constexpr name                 = "GLbyte";
112
+    auto static constexpr columns              = GLint{1};
113
+    auto static constexpr rows                 = GLint{1};
114
+    auto static constexpr glsl                 = GLenum{GL_INT};
115
+    auto static constexpr format               = GLenum{GL_RED_INTEGER};
116
+    auto static constexpr type                 = GLenum{GL_BYTE};
117
+    auto static constexpr internal_format      = GLenum{GL_R8I};
118
+    auto static constexpr internal_format_srgb = GLenum{GL_SR8_EXT};
119
+    auto static constexpr internal_format_compressed =
120
+        GLenum{GL_COMPRESSED_RED};
121
+    auto static constexpr internal_format_compressed_srgb =
122
+        GLenum{GL_COMPRESSED_SRGB};
123
+    auto static constexpr integer = bool(*"_INTEGER");
124
+    void static uniform(GLint location, GLbyte const & value)
125
+    {
126
+        if (GLBase::debug() >= 1)
127
+            GLBase::check_supported({2, 0}, {});
128
+        glUniform1i(location, (value));
129
+    }
130
+    void static vertex_attrib(GLint location, GLbyte const & value)
131
+    {
132
+        if (GLBase::debug() >= 1)
133
+            GLBase::check_supported({3, 0}, {});
134
+        if (location == -1)
135
+            return;
136
+        for (auto column = GLuint{0}; column < columns; ++column)
137
+            glVertexAttribI1i((GLuint)location + column, (value));
138
+    }
139
+    void static vertex_attrib_pointer(
140
+        GLint       location,
141
+        std::size_t offset = 0,
142
+        std::size_t stride = sizeof(GLbyte))
143
+    {
144
+        if (GLBase::debug() >= 1)
145
+            GLBase::check_supported({3, 0}, {});
146
+        if (location == -1)
147
+            return;
148
+        auto constexpr sizeof_column = sizeof(GLbyte) / columns;
149
+        for (auto column = GLuint{0}; column < columns; ++column)
150
+            glVertexAttribIPointer(
151
+                (GLuint)location + column,
152
+                rows,
153
+                type,
154
+                (GLsizei)stride,
155
+                (void const *)(offset + sizeof_column * column));
156
+    }
157
+};
158
+
159
+template <> struct GLTraits::Value<GLshort>
160
+{
161
+    auto static constexpr name                 = "GLshort";
162
+    auto static constexpr columns              = GLint{1};
163
+    auto static constexpr rows                 = GLint{1};
164
+    auto static constexpr glsl                 = GLenum{GL_INT};
165
+    auto static constexpr format               = GLenum{GL_RED_INTEGER};
166
+    auto static constexpr type                 = GLenum{GL_SHORT};
167
+    auto static constexpr internal_format      = GLenum{GL_R16I};
168
+    auto static constexpr internal_format_srgb = GLenum{GL_SR8_EXT};
169
+    auto static constexpr internal_format_compressed =
170
+        GLenum{GL_COMPRESSED_RED};
171
+    auto static constexpr internal_format_compressed_srgb =
172
+        GLenum{GL_COMPRESSED_SRGB};
173
+    auto static constexpr integer = bool(*"_INTEGER");
174
+    void static uniform(GLint location, GLshort const & value)
175
+    {
176
+        if (GLBase::debug() >= 1)
177
+            GLBase::check_supported({2, 0}, {});
178
+        glUniform1i(location, (value));
179
+    }
180
+    void static vertex_attrib(GLint location, GLshort const & value)
181
+    {
182
+        if (GLBase::debug() >= 1)
183
+            GLBase::check_supported({3, 0}, {});
184
+        if (location == -1)
185
+            return;
186
+        for (auto column = GLuint{0}; column < columns; ++column)
187
+            glVertexAttribI1i((GLuint)location + column, (value));
188
+    }
189
+    void static vertex_attrib_pointer(
190
+        GLint       location,
191
+        std::size_t offset = 0,
192
+        std::size_t stride = sizeof(GLshort))
193
+    {
194
+        if (GLBase::debug() >= 1)
195
+            GLBase::check_supported({3, 0}, {});
196
+        if (location == -1)
197
+            return;
198
+        auto constexpr sizeof_column = sizeof(GLshort) / columns;
199
+        for (auto column = GLuint{0}; column < columns; ++column)
200
+            glVertexAttribIPointer(
201
+                (GLuint)location + column,
202
+                rows,
203
+                type,
204
+                (GLsizei)stride,
205
+                (void const *)(offset + sizeof_column * column));
206
+    }
207
+};
208
+
209
+template <> struct GLTraits::Value<GLint>
210
+{
211
+    auto static constexpr name                 = "GLint";
212
+    auto static constexpr columns              = GLint{1};
213
+    auto static constexpr rows                 = GLint{1};
214
+    auto static constexpr glsl                 = GLenum{GL_INT};
215
+    auto static constexpr format               = GLenum{GL_RED_INTEGER};
216
+    auto static constexpr type                 = GLenum{GL_INT};
217
+    auto static constexpr internal_format      = GLenum{GL_R32I};
218
+    auto static constexpr internal_format_srgb = GLenum{GL_SR8_EXT};
219
+    auto static constexpr internal_format_compressed =
220
+        GLenum{GL_COMPRESSED_RED};
221
+    auto static constexpr internal_format_compressed_srgb =
222
+        GLenum{GL_COMPRESSED_SRGB};
223
+    auto static constexpr integer = bool(*"_INTEGER");
224
+    void static uniform(GLint location, GLint const & value)
225
+    {
226
+        if (GLBase::debug() >= 1)
227
+            GLBase::check_supported({2, 0}, {});
228
+        glUniform1i(location, (value));
229
+    }
230
+    void static vertex_attrib(GLint location, GLint const & value)
231
+    {
232
+        if (GLBase::debug() >= 1)
233
+            GLBase::check_supported({3, 0}, {});
234
+        if (location == -1)
235
+            return;
236
+        for (auto column = GLuint{0}; column < columns; ++column)
237
+            glVertexAttribI1i((GLuint)location + column, (value));
238
+    }
239
+    void static vertex_attrib_pointer(
240
+        GLint       location,
241
+        std::size_t offset = 0,
242
+        std::size_t stride = sizeof(GLint))
243
+    {
244
+        if (GLBase::debug() >= 1)
245
+            GLBase::check_supported({3, 0}, {});
246
+        if (location == -1)
247
+            return;
248
+        auto constexpr sizeof_column = sizeof(GLint) / columns;
249
+        for (auto column = GLuint{0}; column < columns; ++column)
250
+            glVertexAttribIPointer(
251
+                (GLuint)location + column,
252
+                rows,
253
+                type,
254
+                (GLsizei)stride,
255
+                (void const *)(offset + sizeof_column * column));
256
+    }
257
+};
258
+
259
+template <> struct GLTraits::Value<GLubyte>
260
+{
261
+    auto static constexpr name                 = "GLubyte";
262
+    auto static constexpr columns              = GLint{1};
263
+    auto static constexpr rows                 = GLint{1};
264
+    auto static constexpr glsl                 = GLenum{GL_UNSIGNED_INT};
265
+    auto static constexpr format               = GLenum{GL_RED_INTEGER};
266
+    auto static constexpr type                 = GLenum{GL_UNSIGNED_BYTE};
267
+    auto static constexpr internal_format      = GLenum{GL_R8UI};
268
+    auto static constexpr internal_format_srgb = GLenum{GL_SR8_EXT};
269
+    auto static constexpr internal_format_compressed =
270
+        GLenum{GL_COMPRESSED_RED};
271
+    auto static constexpr internal_format_compressed_srgb =
272
+        GLenum{GL_COMPRESSED_SRGB};
273
+    auto static constexpr integer = bool(*"_INTEGER");
274
+    void static uniform(GLint location, GLubyte const & value)
275
+    {
276
+        if (GLBase::debug() >= 1)
277
+            GLBase::check_supported({3, 0}, {});
278
+        glUniform1ui(location, (value));
279
+    }
280
+    void static vertex_attrib(GLint location, GLubyte const & value)
281
+    {
282
+        if (GLBase::debug() >= 1)
283
+            GLBase::check_supported({3, 0}, {});
284
+        if (location == -1)
285
+            return;
286
+        for (auto column = GLuint{0}; column < columns; ++column)
287
+            glVertexAttribI1ui((GLuint)location + column, (value));
288
+    }
289
+    void static vertex_attrib_pointer(
290
+        GLint       location,
291
+        std::size_t offset = 0,
292
+        std::size_t stride = sizeof(GLubyte))
293
+    {
294
+        if (GLBase::debug() >= 1)
295
+            GLBase::check_supported({3, 0}, {});
296
+        if (location == -1)
297
+            return;
298
+        auto constexpr sizeof_column = sizeof(GLubyte) / columns;
299
+        for (auto column = GLuint{0}; column < columns; ++column)
300
+            glVertexAttribIPointer(
301
+                (GLuint)location + column,
302
+                rows,
303
+                type,
304
+                (GLsizei)stride,
305
+                (void const *)(offset + sizeof_column * column));
306
+    }
307
+};
308
+
309
+template <> struct GLTraits::Value<GLushort>
310
+{
311
+    auto static constexpr name                 = "GLushort";
312
+    auto static constexpr columns              = GLint{1};
313
+    auto static constexpr rows                 = GLint{1};
314
+    auto static constexpr glsl                 = GLenum{GL_UNSIGNED_INT};
315
+    auto static constexpr format               = GLenum{GL_RED_INTEGER};
316
+    auto static constexpr type                 = GLenum{GL_UNSIGNED_SHORT};
317
+    auto static constexpr internal_format      = GLenum{GL_R16UI};
318
+    auto static constexpr internal_format_srgb = GLenum{GL_SR8_EXT};
319
+    auto static constexpr internal_format_compressed =
320
+        GLenum{GL_COMPRESSED_RED};
321
+    auto static constexpr internal_format_compressed_srgb =
322
+        GLenum{GL_COMPRESSED_SRGB};
323
+    auto static constexpr integer = bool(*"_INTEGER");
324
+    void static uniform(GLint location, GLushort const & value)
325
+    {
326
+        if (GLBase::debug() >= 1)
327
+            GLBase::check_supported({3, 0}, {});
328
+        glUniform1ui(location, (value));
329
+    }
330
+    void static vertex_attrib(GLint location, GLushort const & value)
331
+    {
332
+        if (GLBase::debug() >= 1)
333
+            GLBase::check_supported({3, 0}, {});
334
+        if (location == -1)
335
+            return;
336
+        for (auto column = GLuint{0}; column < columns; ++column)
337
+            glVertexAttribI1ui((GLuint)location + column, (value));
338
+    }
339
+    void static vertex_attrib_pointer(
340
+        GLint       location,
341
+        std::size_t offset = 0,
342
+        std::size_t stride = sizeof(GLushort))
343
+    {
344
+        if (GLBase::debug() >= 1)
345
+            GLBase::check_supported({3, 0}, {});
346
+        if (location == -1)
347
+            return;
348
+        auto constexpr sizeof_column = sizeof(GLushort) / columns;
349
+        for (auto column = GLuint{0}; column < columns; ++column)
350
+            glVertexAttribIPointer(
351
+                (GLuint)location + column,
352
+                rows,
353
+                type,
354
+                (GLsizei)stride,
355
+                (void const *)(offset + sizeof_column * column));
356
+    }
357
+};
358
+
359
+template <> struct GLTraits::Value<GLuint>
360
+{
361
+    auto static constexpr name                 = "GLuint";
362
+    auto static constexpr columns              = GLint{1};
363
+    auto static constexpr rows                 = GLint{1};
364
+    auto static constexpr glsl                 = GLenum{GL_UNSIGNED_INT};
365
+    auto static constexpr format               = GLenum{GL_RED_INTEGER};
366
+    auto static constexpr type                 = GLenum{GL_UNSIGNED_INT};
367
+    auto static constexpr internal_format      = GLenum{GL_R32UI};
368
+    auto static constexpr internal_format_srgb = GLenum{GL_SR8_EXT};
369
+    auto static constexpr internal_format_compressed =
370
+        GLenum{GL_COMPRESSED_RED};
371
+    auto static constexpr internal_format_compressed_srgb =
372
+        GLenum{GL_COMPRESSED_SRGB};
373
+    auto static constexpr integer = bool(*"_INTEGER");
374
+    void static uniform(GLint location, GLuint const & value)
375
+    {
376
+        if (GLBase::debug() >= 1)
377
+            GLBase::check_supported({3, 0}, {});
378
+        glUniform1ui(location, (value));
379
+    }
380
+    void static vertex_attrib(GLint location, GLuint const & value)
381
+    {
382
+        if (GLBase::debug() >= 1)
383
+            GLBase::check_supported({3, 0}, {});
384
+        if (location == -1)
385
+            return;
386
+        for (auto column = GLuint{0}; column < columns; ++column)
387
+            glVertexAttribI1ui((GLuint)location + column, (value));
388
+    }
389
+    void static vertex_attrib_pointer(
390
+        GLint       location,
391
+        std::size_t offset = 0,
392
+        std::size_t stride = sizeof(GLuint))
393
+    {
394
+        if (GLBase::debug() >= 1)
395
+            GLBase::check_supported({3, 0}, {});
396
+        if (location == -1)
397
+            return;
398
+        auto constexpr sizeof_column = sizeof(GLuint) / columns;
399
+        for (auto column = GLuint{0}; column < columns; ++column)
400
+            glVertexAttribIPointer(
401
+                (GLuint)location + column,
402
+                rows,
403
+                type,
404
+                (GLsizei)stride,
405
+                (void const *)(offset + sizeof_column * column));
406
+    }
407
+};
408
+
409
+template <> struct GLTraits::Value<GLdouble>
410
+{
411
+    auto static constexpr name                 = "GLdouble";
412
+    auto static constexpr columns              = GLint{1};
413
+    auto static constexpr rows                 = GLint{1};
414
+    auto static constexpr glsl                 = GLenum{GL_DOUBLE};
415
+    auto static constexpr format               = GLenum{GL_RED};
416
+    auto static constexpr type                 = GLenum{GL_DOUBLE};
417
+    auto static constexpr internal_format      = GLenum{GL_RED};
418
+    auto static constexpr internal_format_srgb = GLenum{GL_SR8_EXT};
419
+    auto static constexpr internal_format_compressed =
420
+        GLenum{GL_COMPRESSED_RED};
421
+    auto static constexpr internal_format_compressed_srgb =
422
+        GLenum{GL_COMPRESSED_SRGB};
423
+    auto static constexpr integer = bool(*"");
424
+    void static uniform(GLint location, GLdouble const & value)
425
+    {
426
+        if (GLBase::debug() >= 1)
427
+            GLBase::check_supported({4, 0}, "GL_ARB_gpu_shader_fp64");
428
+        glUniform1d(location, (value));
429
+    }
430
+    void static vertex_attrib(GLint location, GLdouble const & value)
431
+    {
432
+        if (GLBase::debug() >= 1)
433
+            GLBase::check_supported({4, 1}, "GL_ARB_vertex_attrib_64bit");
434
+        if (location == -1)
435
+            return;
436
+        for (auto column = GLuint{0}; column < columns; ++column)
437
+            glVertexAttribL1d((GLuint)location + column, (value));
438
+    }
439
+    void static vertex_attrib_pointer(
440
+        GLint       location,
441
+        std::size_t offset = 0,
442
+        std::size_t stride = sizeof(GLdouble))
443
+    {
444
+        if (GLBase::debug() >= 1)
445
+            GLBase::check_supported({4, 1}, "GL_ARB_vertex_attrib_64bit");
446
+        if (location == -1)
447
+            return;
448
+        auto constexpr sizeof_column = sizeof(GLdouble) / columns;
449
+        for (auto column = GLuint{0}; column < columns; ++column)
450
+            glVertexAttribLPointer(
451
+                (GLuint)location + column,
452
+                rows,
453
+                type,
454
+                (GLsizei)stride,
455
+                (void const *)(offset + sizeof_column * column));
456
+    }
457
+};
458
+
459
+
460
+template <> struct GLTraits::Value<glm::vec2>
461
+{
462
+    auto static constexpr name                 = "glm::vec2";
463
+    auto static constexpr columns              = GLint{1};
464
+    auto static constexpr rows                 = GLint{2};
465
+    auto static constexpr glsl                 = GLenum{GL_FLOAT_VEC2};
466
+    auto static constexpr format               = GLenum{GL_RG};
467
+    auto static constexpr type                 = GLenum{GL_FLOAT};
468
+    auto static constexpr internal_format      = GLenum{GL_RG32F};
469
+    auto static constexpr internal_format_srgb = GLenum{GL_SRG8_EXT};
470
+    auto static constexpr internal_format_compressed =
471
+        GLenum{GL_COMPRESSED_RG};
472
+    auto static constexpr internal_format_compressed_srgb =
473
+        GLenum{GL_COMPRESSED_SRGB};
474
+    auto static constexpr integer = bool(*"");
475
+    void static uniform(GLint location, glm::vec2 const & value)
476
+    {
477
+        if (GLBase::debug() >= 1)
478
+            GLBase::check_supported({2, 0}, {});
479
+        glUniform2fv(location, 1, glm::value_ptr(value));
480
+    }
481
+    void static vertex_attrib(GLint location, glm::vec2 const & value)
482
+    {
483
+        if (GLBase::debug() >= 1)
484
+            GLBase::check_supported({2, 0}, {});
485
+        if (location == -1)
486
+            return;
487
+        for (auto column = GLuint{0}; column < columns; ++column)
488
+            glVertexAttrib2fv(
489
+                (GLuint)location + column,
490
+                glm::value_ptr(value) + rows * column);
491
+    }
492
+    void static vertex_attrib_pointer(
493
+        GLint       location,
494
+        std::size_t offset = 0,
495
+        std::size_t stride = sizeof(glm::vec2))
496
+    {
497
+        if (GLBase::debug() >= 1)
498
+            GLBase::check_supported({2, 0}, {});
499
+        if (location == -1)
500
+            return;
501
+        auto constexpr sizeof_column = sizeof(glm::vec2) / columns;
502
+        for (auto column = GLuint{0}; column < columns; ++column)
503
+            glVertexAttribPointer(
504
+                (GLuint)location + column,
505
+                rows,
506
+                type,
507
+                GL_FALSE,
508
+                (GLsizei)stride,
509
+                (void const *)(offset + sizeof_column * column));
510
+    }
511
+};
512
+
513
+template <> struct GLTraits::Value<glm::vec3>
514
+{
515
+    auto static constexpr name                 = "glm::vec3";
516
+    auto static constexpr columns              = GLint{1};
517
+    auto static constexpr rows                 = GLint{3};
518
+    auto static constexpr glsl                 = GLenum{GL_FLOAT_VEC3};
519
+    auto static constexpr format               = GLenum{GL_RGB};
520
+    auto static constexpr type                 = GLenum{GL_FLOAT};
521
+    auto static constexpr internal_format      = GLenum{GL_RGB32F};
522
+    auto static constexpr internal_format_srgb = GLenum{GL_SRGB8};
523
+    auto static constexpr internal_format_compressed =
524
+        GLenum{GL_COMPRESSED_RGB};
525
+    auto static constexpr internal_format_compressed_srgb =
526
+        GLenum{GL_COMPRESSED_SRGB};
527
+    auto static constexpr integer = bool(*"");
528
+    void static uniform(GLint location, glm::vec3 const & value)
529
+    {
530
+        if (GLBase::debug() >= 1)
531
+            GLBase::check_supported({2, 0}, {});
532
+        glUniform3fv(location, 1, glm::value_ptr(value));
533
+    }
534
+    void static vertex_attrib(GLint location, glm::vec3 const & value)
535
+    {
536
+        if (GLBase::debug() >= 1)
537
+            GLBase::check_supported({2, 0}, {});
538
+        if (location == -1)
539
+            return;
540
+        for (auto column = GLuint{0}; column < columns; ++column)
541
+            glVertexAttrib3fv(
542
+                (GLuint)location + column,
543
+                glm::value_ptr(value) + rows * column);
544
+    }
545
+    void static vertex_attrib_pointer(
546
+        GLint       location,
547
+        std::size_t offset = 0,
548
+        std::size_t stride = sizeof(glm::vec3))
549
+    {
550
+        if (GLBase::debug() >= 1)
551
+            GLBase::check_supported({2, 0}, {});
552
+        if (location == -1)
553
+            return;
554
+        auto constexpr sizeof_column = sizeof(glm::vec3) / columns;
555
+        for (auto column = GLuint{0}; column < columns; ++column)
556
+            glVertexAttribPointer(
557
+                (GLuint)location + column,
558
+                rows,
559
+                type,
560
+                GL_FALSE,
561
+                (GLsizei)stride,
562
+                (void const *)(offset + sizeof_column * column));
563
+    }
564
+};
565
+
566
+template <> struct GLTraits::Value<glm::vec4>
567
+{
568
+    auto static constexpr name                 = "glm::vec4";
569
+    auto static constexpr columns              = GLint{1};
570
+    auto static constexpr rows                 = GLint{4};
571
+    auto static constexpr glsl                 = GLenum{GL_FLOAT_VEC4};
572
+    auto static constexpr format               = GLenum{GL_RGBA};
573
+    auto static constexpr type                 = GLenum{GL_FLOAT};
574
+    auto static constexpr internal_format      = GLenum{GL_RGBA32F};
575
+    auto static constexpr internal_format_srgb = GLenum{GL_SRGB8_ALPHA8};
576
+    auto static constexpr internal_format_compressed =
577
+        GLenum{GL_COMPRESSED_RGBA};
578
+    auto static constexpr internal_format_compressed_srgb =
579
+        GLenum{GL_COMPRESSED_SRGB_ALPHA};
580
+    auto static constexpr integer = bool(*"");
581
+    void static uniform(GLint location, glm::vec4 const & value)
582
+    {
583
+        if (GLBase::debug() >= 1)
584
+            GLBase::check_supported({2, 0}, {});
585
+        glUniform4fv(location, 1, glm::value_ptr(value));
586
+    }
587
+    void static vertex_attrib(GLint location, glm::vec4 const & value)
588
+    {
589
+        if (GLBase::debug() >= 1)
590
+            GLBase::check_supported({2, 0}, {});
591
+        if (location == -1)
592
+            return;
593
+        for (auto column = GLuint{0}; column < columns; ++column)
594
+            glVertexAttrib4fv(
595
+                (GLuint)location + column,
596
+                glm::value_ptr(value) + rows * column);
597
+    }
598
+    void static vertex_attrib_pointer(
599
+        GLint       location,
600
+        std::size_t offset = 0,
601
+        std::size_t stride = sizeof(glm::vec4))
602
+    {
603
+        if (GLBase::debug() >= 1)
604
+            GLBase::check_supported({2, 0}, {});
605
+        if (location == -1)
606
+            return;
607
+        auto constexpr sizeof_column = sizeof(glm::vec4) / columns;
608
+        for (auto column = GLuint{0}; column < columns; ++column)
609
+            glVertexAttribPointer(
610
+                (GLuint)location + column,
611
+                rows,
612
+                type,
613
+                GL_FALSE,
614
+                (GLsizei)stride,
615
+                (void const *)(offset + sizeof_column * column));
616
+    }
617
+};
618
+
619
+template <> struct GLTraits::Value<glm::mat2>
620
+{
621
+    auto static constexpr name                 = "glm::mat2";
622
+    auto static constexpr columns              = GLint{2};
623
+    auto static constexpr rows                 = GLint{2};
624
+    auto static constexpr glsl                 = GLenum{GL_FLOAT_MAT2};
625
+    auto static constexpr format               = GLenum{GL_RG};
626
+    auto static constexpr type                 = GLenum{GL_FLOAT};
627
+    auto static constexpr internal_format      = GLenum{GL_RG32F};
628
+    auto static constexpr internal_format_srgb = GLenum{GL_SRG8_EXT};
629
+    auto static constexpr internal_format_compressed =
630
+        GLenum{GL_COMPRESSED_RG};
631
+    auto static constexpr internal_format_compressed_srgb =
632
+        GLenum{GL_COMPRESSED_SRGB};
633
+    auto static constexpr integer = bool(*"");
634
+    void static uniform(GLint location, glm::mat2 const & value)
635
+    {
636
+        if (GLBase::debug() >= 1)
637
+            GLBase::check_supported({2, 0}, {});
638
+        glUniformMatrix2fv(location, 1, GL_FALSE, glm::value_ptr(value));
639
+    }
640
+    void static vertex_attrib(GLint location, glm::mat2 const & value)
641
+    {
642
+        if (GLBase::debug() >= 1)
643
+            GLBase::check_supported({2, 0}, {});
644
+        if (location == -1)
645
+            return;
646
+        for (auto column = GLuint{0}; column < columns; ++column)
647
+            glVertexAttrib2fv(
648
+                (GLuint)location + column,
649
+                glm::value_ptr(value) + rows * column);
650
+    }
651
+    void static vertex_attrib_pointer(
652
+        GLint       location,
653
+        std::size_t offset = 0,
654
+        std::size_t stride = sizeof(glm::mat2))
655
+    {
656
+        if (GLBase::debug() >= 1)
657
+            GLBase::check_supported({2, 0}, {});
658
+        if (location == -1)
659
+            return;
660
+        auto constexpr sizeof_column = sizeof(glm::mat2) / columns;
661
+        for (auto column = GLuint{0}; column < columns; ++column)
662
+            glVertexAttribPointer(
663
+                (GLuint)location + column,
664
+                rows,
665
+                type,
666
+                GL_FALSE,
667
+                (GLsizei)stride,
668
+                (void const *)(offset + sizeof_column * column));
669
+    }
670
+};
671
+
672
+template <> struct GLTraits::Value<glm::mat2x3>
673
+{
674
+    auto static constexpr name                 = "glm::mat2x3";
675
+    auto static constexpr columns              = GLint{2};
676
+    auto static constexpr rows                 = GLint{3};
677
+    auto static constexpr glsl                 = GLenum{GL_FLOAT_MAT2x3};
678
+    auto static constexpr format               = GLenum{GL_RGB};
679
+    auto static constexpr type                 = GLenum{GL_FLOAT};
680
+    auto static constexpr internal_format      = GLenum{GL_RGB32F};
681
+    auto static constexpr internal_format_srgb = GLenum{GL_SRGB8};
682
+    auto static constexpr internal_format_compressed =
683
+        GLenum{GL_COMPRESSED_RGB};
684
+    auto static constexpr internal_format_compressed_srgb =
685
+        GLenum{GL_COMPRESSED_SRGB};
686
+    auto static constexpr integer = bool(*"");
687
+    void static uniform(GLint location, glm::mat2x3 const & value)
688
+    {
689
+        if (GLBase::debug() >= 1)
690
+            GLBase::check_supported({2, 1}, {});
691
+        glUniformMatrix2x3fv(location, 1, GL_FALSE, glm::value_ptr(value));
692
+    }
693
+    void static vertex_attrib(GLint location, glm::mat2x3 const & value)
694
+    {
695
+        if (GLBase::debug() >= 1)
696
+            GLBase::check_supported({2, 0}, {});
697
+        if (location == -1)
698
+            return;
699
+        for (auto column = GLuint{0}; column < columns; ++column)
700
+            glVertexAttrib3fv(
701
+                (GLuint)location + column,
702
+                glm::value_ptr(value) + rows * column);
703
+    }
704
+    void static vertex_attrib_pointer(
705
+        GLint       location,
706
+        std::size_t offset = 0,
707
+        std::size_t stride = sizeof(glm::mat2x3))
708
+    {
709
+        if (GLBase::debug() >= 1)
710
+            GLBase::check_supported({2, 0}, {});
711
+        if (location == -1)
712
+            return;
713
+        auto constexpr sizeof_column = sizeof(glm::mat2x3) / columns;
714
+        for (auto column = GLuint{0}; column < columns; ++column)
715
+            glVertexAttribPointer(
716
+                (GLuint)location + column,
717
+                rows,
718
+                type,
719
+                GL_FALSE,
720
+                (GLsizei)stride,
721
+                (void const *)(offset + sizeof_column * column));
722
+    }
723
+};
724
+
725
+template <> struct GLTraits::Value<glm::mat2x4>
726
+{
727
+    auto static constexpr name                 = "glm::mat2x4";
728
+    auto static constexpr columns              = GLint{2};
729
+    auto static constexpr rows                 = GLint{4};
730
+    auto static constexpr glsl                 = GLenum{GL_FLOAT_MAT2x4};
731
+    auto static constexpr format               = GLenum{GL_RGBA};
732
+    auto static constexpr type                 = GLenum{GL_FLOAT};
733
+    auto static constexpr internal_format      = GLenum{GL_RGBA32F};
734
+    auto static constexpr internal_format_srgb = GLenum{GL_SRGB8_ALPHA8};
735
+    auto static constexpr internal_format_compressed =
736
+        GLenum{GL_COMPRESSED_RGBA};
737
+    auto static constexpr internal_format_compressed_srgb =
738
+        GLenum{GL_COMPRESSED_SRGB_ALPHA};
739
+    auto static constexpr integer = bool(*"");
740
+    void static uniform(GLint location, glm::mat2x4 const & value)
741
+    {
742
+        if (GLBase::debug() >= 1)
743
+            GLBase::check_supported({2, 1}, {});
744
+        glUniformMatrix2x4fv(location, 1, GL_FALSE, glm::value_ptr(value));
745
+    }
746
+    void static vertex_attrib(GLint location, glm::mat2x4 const & value)
747
+    {
748
+        if (GLBase::debug() >= 1)
749
+            GLBase::check_supported({2, 0}, {});
750
+        if (location == -1)
751
+            return;
752
+        for (auto column = GLuint{0}; column < columns; ++column)
753
+            glVertexAttrib4fv(
754
+                (GLuint)location + column,
755
+                glm::value_ptr(value) + rows * column);
756
+    }
757
+    void static vertex_attrib_pointer(
758
+        GLint       location,
759
+        std::size_t offset = 0,
760
+        std::size_t stride = sizeof(glm::mat2x4))
761
+    {
762
+        if (GLBase::debug() >= 1)
763
+            GLBase::check_supported({2, 0}, {});
764
+        if (location == -1)
765
+            return;
766
+        auto constexpr sizeof_column = sizeof(glm::mat2x4) / columns;
767
+        for (auto column = GLuint{0}; column < columns; ++column)
768
+            glVertexAttribPointer(
769
+                (GLuint)location + column,
770
+                rows,
771
+                type,
772
+                GL_FALSE,
773
+                (GLsizei)stride,
774
+                (void const *)(offset + sizeof_column * column));
775
+    }
776
+};
777
+
778
+template <> struct GLTraits::Value<glm::mat3x2>
779
+{
780
+    auto static constexpr name                 = "glm::mat3x2";
781
+    auto static constexpr columns              = GLint{3};
782
+    auto static constexpr rows                 = GLint{2};
783
+    auto static constexpr glsl                 = GLenum{GL_FLOAT_MAT3x2};
784
+    auto static constexpr format               = GLenum{GL_RG};
785
+    auto static constexpr type                 = GLenum{GL_FLOAT};
786
+    auto static constexpr internal_format      = GLenum{GL_RG32F};
787
+    auto static constexpr internal_format_srgb = GLenum{GL_SRG8_EXT};
788
+    auto static constexpr internal_format_compressed =
789
+        GLenum{GL_COMPRESSED_RG};
790
+    auto static constexpr internal_format_compressed_srgb =
791
+        GLenum{GL_COMPRESSED_SRGB};
792
+    auto static constexpr integer = bool(*"");
793
+    void static uniform(GLint location, glm::mat3x2 const & value)
794
+    {
795
+        if (GLBase::debug() >= 1)
796
+            GLBase::check_supported({2, 1}, {});
797
+        glUniformMatrix3x2fv(location, 1, GL_FALSE, glm::value_ptr(value));
798
+    }
799
+    void static vertex_attrib(GLint location, glm::mat3x2 const & value)
800
+    {
801
+        if (GLBase::debug() >= 1)
802
+            GLBase::check_supported({2, 0}, {});
803
+        if (location == -1)
804
+            return;
805
+        for (auto column = GLuint{0}; column < columns; ++column)
806
+            glVertexAttrib2fv(
807
+                (GLuint)location + column,
808
+                glm::value_ptr(value) + rows * column);
809
+    }
810
+    void static vertex_attrib_pointer(
811
+        GLint       location,
812
+        std::size_t offset = 0,
813
+        std::size_t stride = sizeof(glm::mat3x2))
814
+    {
815
+        if (GLBase::debug() >= 1)
816
+            GLBase::check_supported({2, 0}, {});
817
+        if (location == -1)
818
+            return;
819
+        auto constexpr sizeof_column = sizeof(glm::mat3x2) / columns;
820
+        for (auto column = GLuint{0}; column < columns; ++column)
821
+            glVertexAttribPointer(
822
+                (GLuint)location + column,
823
+                rows,
824
+                type,
825
+                GL_FALSE,
826
+                (GLsizei)stride,
827
+                (void const *)(offset + sizeof_column * column));
828
+    }
829
+};
830
+
831
+template <> struct GLTraits::Value<glm::mat3>
832
+{
833
+    auto static constexpr name                 = "glm::mat3";
834
+    auto static constexpr columns              = GLint{3};
835
+    auto static constexpr rows                 = GLint{3};
836
+    auto static constexpr glsl                 = GLenum{GL_FLOAT_MAT3};
837
+    auto static constexpr format               = GLenum{GL_RGB};
838
+    auto static constexpr type                 = GLenum{GL_FLOAT};
839
+    auto static constexpr internal_format      = GLenum{GL_RGB32F};
840
+    auto static constexpr internal_format_srgb = GLenum{GL_SRGB8};
841
+    auto static constexpr internal_format_compressed =
842
+        GLenum{GL_COMPRESSED_RGB};
843
+    auto static constexpr internal_format_compressed_srgb =
844
+        GLenum{GL_COMPRESSED_SRGB};
845
+    auto static constexpr integer = bool(*"");
846
+    void static uniform(GLint location, glm::mat3 const & value)
847
+    {
848
+        if (GLBase::debug() >= 1)
849
+            GLBase::check_supported({2, 0}, {});
850
+        glUniformMatrix3fv(location, 1, GL_FALSE, glm::value_ptr(value));
851
+    }
852
+    void static vertex_attrib(GLint location, glm::mat3 const & value)
853
+    {
854
+        if (GLBase::debug() >= 1)
855
+            GLBase::check_supported({2, 0}, {});
856
+        if (location == -1)
857
+            return;
858
+        for (auto column = GLuint{0}; column < columns; ++column)
859
+            glVertexAttrib3fv(
860
+                (GLuint)location + column,
861
+                glm::value_ptr(value) + rows * column);
862
+    }
863
+    void static vertex_attrib_pointer(
864
+        GLint       location,
865
+        std::size_t offset = 0,
866
+        std::size_t stride = sizeof(glm::mat3))
867
+    {
868
+        if (GLBase::debug() >= 1)
869
+            GLBase::check_supported({2, 0}, {});
870
+        if (location == -1)
871
+            return;
872
+        auto constexpr sizeof_column = sizeof(glm::mat3) / columns;
873
+        for (auto column = GLuint{0}; column < columns; ++column)
874
+            glVertexAttribPointer(
875
+                (GLuint)location + column,
876
+                rows,
877
+                type,
878
+                GL_FALSE,
879
+                (GLsizei)stride,
880
+                (void const *)(offset + sizeof_column * column));
881
+    }
882
+};
883
+
884
+template <> struct GLTraits::Value<glm::mat3x4>
885
+{
886
+    auto static constexpr name                 = "glm::mat3x4";
887
+    auto static constexpr columns              = GLint{3};
888
+    auto static constexpr rows                 = GLint{4};
889
+    auto static constexpr glsl                 = GLenum{GL_FLOAT_MAT3x4};
890
+    auto static constexpr format               = GLenum{GL_RGBA};
891
+    auto static constexpr type                 = GLenum{GL_FLOAT};
892
+    auto static constexpr internal_format      = GLenum{GL_RGBA32F};
893
+    auto static constexpr internal_format_srgb = GLenum{GL_SRGB8_ALPHA8};
894
+    auto static constexpr internal_format_compressed =
895
+        GLenum{GL_COMPRESSED_RGBA};
896
+    auto static constexpr internal_format_compressed_srgb =
897
+        GLenum{GL_COMPRESSED_SRGB_ALPHA};
898
+    auto static constexpr integer = bool(*"");
899
+    void static uniform(GLint location, glm::mat3x4 const & value)
900
+    {
901
+        if (GLBase::debug() >= 1)
902
+            GLBase::check_supported({2, 1}, {});
903
+        glUniformMatrix3x4fv(location, 1, GL_FALSE, glm::value_ptr(value));
904
+    }
905
+    void static vertex_attrib(GLint location, glm::mat3x4 const & value)
906
+    {
907
+        if (GLBase::debug() >= 1)
908
+            GLBase::check_supported({2, 0}, {});
909
+        if (location == -1)
910
+            return;
911
+        for (auto column = GLuint{0}; column < columns; ++column)
912
+            glVertexAttrib4fv(
913
+                (GLuint)location + column,
914
+                glm::value_ptr(value) + rows * column);
915
+    }
916
+    void static vertex_attrib_pointer(
917
+        GLint       location,
918
+        std::size_t offset = 0,
919
+        std::size_t stride = sizeof(glm::mat3x4))
920
+    {
921
+        if (GLBase::debug() >= 1)
922
+            GLBase::check_supported({2, 0}, {});
923
+        if (location == -1)
924
+            return;
925
+        auto constexpr sizeof_column = sizeof(glm::mat3x4) / columns;
926
+        for (auto column = GLuint{0}; column < columns; ++column)
927
+            glVertexAttribPointer(
928
+                (GLuint)location + column,
929
+                rows,
930
+                type,
931
+                GL_FALSE,
932
+                (GLsizei)stride,
933
+                (void const *)(offset + sizeof_column * column));
934
+    }
935
+};
936
+
937
+template <> struct GLTraits::Value<glm::mat4x2>
938
+{
939
+    auto static constexpr name                 = "glm::mat4x2";
940
+    auto static constexpr columns              = GLint{4};
941
+    auto static constexpr rows                 = GLint{2};
942
+    auto static constexpr glsl                 = GLenum{GL_FLOAT_MAT4x2};
943
+    auto static constexpr format               = GLenum{GL_RG};
944
+    auto static constexpr type                 = GLenum{GL_FLOAT};
945
+    auto static constexpr internal_format      = GLenum{GL_RG32F};
946
+    auto static constexpr internal_format_srgb = GLenum{GL_SRG8_EXT};
947
+    auto static constexpr internal_format_compressed =
948
+        GLenum{GL_COMPRESSED_RG};
949
+    auto static constexpr internal_format_compressed_srgb =
950
+        GLenum{GL_COMPRESSED_SRGB};
951
+    auto static constexpr integer = bool(*"");
952
+    void static uniform(GLint location, glm::mat4x2 const & value)
953
+    {
954
+        if (GLBase::debug() >= 1)
955
+            GLBase::check_supported({2, 1}, {});
956
+        glUniformMatrix4x2fv(location, 1, GL_FALSE, glm::value_ptr(value));
957
+    }
958
+    void static vertex_attrib(GLint location, glm::mat4x2 const & value)
959
+    {
960
+        if (GLBase::debug() >= 1)
961
+            GLBase::check_supported({2, 0}, {});
962
+        if (location == -1)
963
+            return;
964
+        for (auto column = GLuint{0}; column < columns; ++column)
965
+            glVertexAttrib2fv(
966
+                (GLuint)location + column,
967
+                glm::value_ptr(value) + rows * column);
968
+    }
969
+    void static vertex_attrib_pointer(
970
+        GLint       location,
971
+        std::size_t offset = 0,
972
+        std::size_t stride = sizeof(glm::mat4x2))
973
+    {
974
+        if (GLBase::debug() >= 1)
975
+            GLBase::check_supported({2, 0}, {});
976
+        if (location == -1)
977
+            return;
978
+        auto constexpr sizeof_column = sizeof(glm::mat4x2) / columns;
979
+        for (auto column = GLuint{0}; column < columns; ++column)
980
+            glVertexAttribPointer(
981
+                (GLuint)location + column,
982
+                rows,
983
+                type,
984
+                GL_FALSE,
985
+                (GLsizei)stride,
986
+                (void const *)(offset + sizeof_column * column));
987
+    }
988
+};
989
+
990
+template <> struct GLTraits::Value<glm::mat4x3>
991
+{
992
+    auto static constexpr name                 = "glm::mat4x3";
993
+    auto static constexpr columns              = GLint{4};
994
+    auto static constexpr rows                 = GLint{3};
995
+    auto static constexpr glsl                 = GLenum{GL_FLOAT_MAT4x3};
996
+    auto static constexpr format               = GLenum{GL_RGB};
997
+    auto static constexpr type                 = GLenum{GL_FLOAT};
998
+    auto static constexpr internal_format      = GLenum{GL_RGB32F};
999
+    auto static constexpr internal_format_srgb = GLenum{GL_SRGB8};
1000
+    auto static constexpr internal_format_compressed =
1001
+        GLenum{GL_COMPRESSED_RGB};
1002
+    auto static constexpr internal_format_compressed_srgb =
1003
+        GLenum{GL_COMPRESSED_SRGB};
1004
+    auto static constexpr integer = bool(*"");
1005
+    void static uniform(GLint location, glm::mat4x3 const & value)
1006
+    {
1007
+        if (GLBase::debug() >= 1)
1008
+            GLBase::check_supported({2, 1}, {});
1009
+        glUniformMatrix4x3fv(location, 1, GL_FALSE, glm::value_ptr(value));
1010
+    }
1011
+    void static vertex_attrib(GLint location, glm::mat4x3 const & value)
1012
+    {
1013
+        if (GLBase::debug() >= 1)
1014
+            GLBase::check_supported({2, 0}, {});
1015
+        if (location == -1)
1016
+            return;
1017
+        for (auto column = GLuint{0}; column < columns; ++column)
1018
+            glVertexAttrib3fv(
1019
+                (GLuint)location + column,
1020
+                glm::value_ptr(value) + rows * column);
1021
+    }
1022
+    void static vertex_attrib_pointer(
1023
+        GLint       location,
1024
+        std::size_t offset = 0,
1025
+        std::size_t stride = sizeof(glm::mat4x3))
1026
+    {
1027
+        if (GLBase::debug() >= 1)
1028
+            GLBase::check_supported({2, 0}, {});
1029
+        if (location == -1)
1030
+            return;
1031
+        auto constexpr sizeof_column = sizeof(glm::mat4x3) / columns;
1032
+        for (auto column = GLuint{0}; column < columns; ++column)
1033
+            glVertexAttribPointer(
1034
+                (GLuint)location + column,
1035
+                rows,
1036
+                type,
1037
+                GL_FALSE,
1038
+                (GLsizei)stride,
1039
+                (void const *)(offset + sizeof_column * column));
1040
+    }
1041
+};
1042
+
1043
+template <> struct GLTraits::Value<glm::mat4>
1044
+{
1045
+    auto static constexpr name                 = "glm::mat4";
1046
+    auto static constexpr columns              = GLint{4};
1047
+    auto static constexpr rows                 = GLint{4};
1048
+    auto static constexpr glsl                 = GLenum{GL_FLOAT_MAT4};
1049
+    auto static constexpr format               = GLenum{GL_RGBA};
1050
+    auto static constexpr type                 = GLenum{GL_FLOAT};
1051
+    auto static constexpr internal_format      = GLenum{GL_RGBA32F};
1052
+    auto static constexpr internal_format_srgb = GLenum{GL_SRGB8_ALPHA8};
1053
+    auto static constexpr internal_format_compressed =
1054
+        GLenum{GL_COMPRESSED_RGBA};
1055
+    auto static constexpr internal_format_compressed_srgb =
1056
+        GLenum{GL_COMPRESSED_SRGB_ALPHA};
1057
+    auto static constexpr integer = bool(*"");
1058
+    void static uniform(GLint location, glm::mat4 const & value)
1059
+    {
1060
+        if (GLBase::debug() >= 1)
1061
+            GLBase::check_supported({2, 0}, {});
1062
+        glUniformMatrix4fv(location, 1, GL_FALSE, glm::value_ptr(value));
1063
+    }
1064
+    void static vertex_attrib(GLint location, glm::mat4 const & value)
1065
+    {
1066
+        if (GLBase::debug() >= 1)
1067
+            GLBase::check_supported({2, 0}, {});
1068
+        if (location == -1)
1069
+            return;
1070
+        for (auto column = GLuint{0}; column < columns; ++column)
1071
+            glVertexAttrib4fv(
1072
+                (GLuint)location + column,
1073
+                glm::value_ptr(value) + rows * column);
1074
+    }
1075
+    void static vertex_attrib_pointer(
1076
+        GLint       location,
1077
+        std::size_t offset = 0,
1078
+        std::size_t stride = sizeof(glm::mat4))
1079
+    {
1080
+        if (GLBase::debug() >= 1)
1081
+            GLBase::check_supported({2, 0}, {});
1082
+        if (location == -1)
1083
+            return;
1084
+        auto constexpr sizeof_column = sizeof(glm::mat4) / columns;
1085
+        for (auto column = GLuint{0}; column < columns; ++column)
1086
+            glVertexAttribPointer(
1087
+                (GLuint)location + column,
1088
+                rows,
1089
+                type,
1090
+                GL_FALSE,
1091
+                (GLsizei)stride,
1092
+                (void const *)(offset + sizeof_column * column));
1093
+    }
1094
+};
1095
+
1096
+template <> struct GLTraits::Value<glm::ivec2>
1097
+{
1098
+    auto static constexpr name                 = "glm::ivec2";
1099
+    auto static constexpr columns              = GLint{1};
1100
+    auto static constexpr rows                 = GLint{2};
1101
+    auto static constexpr glsl                 = GLenum{GL_INT_VEC2};
1102
+    auto static constexpr format               = GLenum{GL_RG_INTEGER};
1103
+    auto static constexpr type                 = GLenum{GL_INT};
1104
+    auto static constexpr internal_format      = GLenum{GL_RG32I};
1105
+    auto static constexpr internal_format_srgb = GLenum{GL_SRG8_EXT};
1106
+    auto static constexpr internal_format_compressed =
1107
+        GLenum{GL_COMPRESSED_RG};
1108
+    auto static constexpr internal_format_compressed_srgb =
1109
+        GLenum{GL_COMPRESSED_SRGB};
1110
+    auto static constexpr integer = bool(*"_INTEGER");
1111
+    void static uniform(GLint location, glm::ivec2 const & value)
1112
+    {
1113
+        if (GLBase::debug() >= 1)
1114
+            GLBase::check_supported({2, 0}, {});
1115
+        glUniform2iv(location, 1, glm::value_ptr(value));
1116
+    }
1117
+    void static vertex_attrib(GLint location, glm::ivec2 const & value)
1118
+    {
1119
+        if (GLBase::debug() >= 1)
1120
+            GLBase::check_supported({3, 0}, {});
1121
+        if (location == -1)
1122
+            return;
1123
+        for (auto column = GLuint{0}; column < columns; ++column)
1124
+            glVertexAttribI2iv(
1125
+                (GLuint)location + column,
1126
+                glm::value_ptr(value) + rows * column);
1127
+    }
1128
+    void static vertex_attrib_pointer(
1129
+        GLint       location,
1130
+        std::size_t offset = 0,
1131
+        std::size_t stride = sizeof(glm::ivec2))
1132
+    {
1133
+        if (GLBase::debug() >= 1)
1134
+            GLBase::check_supported({3, 0}, {});
1135
+        if (location == -1)
1136
+            return;
1137
+        auto constexpr sizeof_column = sizeof(glm::ivec2) / columns;
1138
+        for (auto column = GLuint{0}; column < columns; ++column)
1139
+            glVertexAttribIPointer(
1140
+                (GLuint)location + column,
1141
+                rows,
1142
+                type,
1143
+                (GLsizei)stride,
1144
+                (void const *)(offset + sizeof_column * column));
1145
+    }
1146
+};
1147
+
1148
+template <> struct GLTraits::Value<glm::ivec3>
1149
+{
1150
+    auto static constexpr name                 = "glm::ivec3";
1151
+    auto static constexpr columns              = GLint{1};
1152
+    auto static constexpr rows                 = GLint{3};
1153
+    auto static constexpr glsl                 = GLenum{GL_INT_VEC3};
1154
+    auto static constexpr format               = GLenum{GL_RGB_INTEGER};
1155
+    auto static constexpr type                 = GLenum{GL_INT};
1156
+    auto static constexpr internal_format      = GLenum{GL_RGB32I};
1157
+    auto static constexpr internal_format_srgb = GLenum{GL_SRGB8};
1158
+    auto static constexpr internal_format_compressed =
1159
+        GLenum{GL_COMPRESSED_RGB};
1160
+    auto static constexpr internal_format_compressed_srgb =
1161
+        GLenum{GL_COMPRESSED_SRGB};
1162
+    auto static constexpr integer = bool(*"_INTEGER");
1163
+    void static uniform(GLint location, glm::ivec3 const & value)
1164
+    {
1165
+        if (GLBase::debug() >= 1)
1166
+            GLBase::check_supported({2, 0}, {});
1167
+        glUniform3iv(location, 1, glm::value_ptr(value));
1168
+    }
1169
+    void static vertex_attrib(GLint location, glm::ivec3 const & value)
1170
+    {
1171
+        if (GLBase::debug() >= 1)
1172
+            GLBase::check_supported({3, 0}, {});
1173
+        if (location == -1)
1174
+            return;
1175
+        for (auto column = GLuint{0}; column < columns; ++column)
1176
+            glVertexAttribI3iv(
1177
+                (GLuint)location + column,
1178
+                glm::value_ptr(value) + rows * column);
1179
+    }
1180
+    void static vertex_attrib_pointer(
1181
+        GLint       location,
1182
+        std::size_t offset = 0,
1183
+        std::size_t stride = sizeof(glm::ivec3))
1184
+    {
1185
+        if (GLBase::debug() >= 1)
1186
+            GLBase::check_supported({3, 0}, {});
1187
+        if (location == -1)
1188
+            return;
1189
+        auto constexpr sizeof_column = sizeof(glm::ivec3) / columns;
1190
+        for (auto column = GLuint{0}; column < columns; ++column)
1191
+            glVertexAttribIPointer(
1192
+                (GLuint)location + column,
1193
+                rows,
1194
+                type,
1195
+                (GLsizei)stride,
1196
+                (void const *)(offset + sizeof_column * column));
1197
+    }
1198
+};
1199
+
1200
+template <> struct GLTraits::Value<glm::ivec4>
1201
+{
1202
+    auto static constexpr name                 = "glm::ivec4";
1203
+    auto static constexpr columns              = GLint{1};
1204
+    auto static constexpr rows                 = GLint{4};
1205
+    auto static constexpr glsl                 = GLenum{GL_INT_VEC4};
1206
+    auto static constexpr format               = GLenum{GL_RGBA_INTEGER};
1207
+    auto static constexpr type                 = GLenum{GL_INT};
1208
+    auto static constexpr internal_format      = GLenum{GL_RGBA32I};
1209
+    auto static constexpr internal_format_srgb = GLenum{GL_SRGB8_ALPHA8};
1210
+    auto static constexpr internal_format_compressed =
1211
+        GLenum{GL_COMPRESSED_RGBA};
1212
+    auto static constexpr internal_format_compressed_srgb =
1213
+        GLenum{GL_COMPRESSED_SRGB_ALPHA};
1214
+    auto static constexpr integer = bool(*"_INTEGER");
1215
+    void static uniform(GLint location, glm::ivec4 const & value)
1216
+    {
1217
+        if (GLBase::debug() >= 1)
1218
+            GLBase::check_supported({2, 0}, {});
1219
+        glUniform4iv(location, 1, glm::value_ptr(value));
1220
+    }
1221
+    void static vertex_attrib(GLint location, glm::ivec4 const & value)
1222
+    {
1223
+        if (GLBase::debug() >= 1)
1224
+            GLBase::check_supported({3, 0}, {});
1225
+        if (location == -1)
1226
+            return;
1227
+        for (auto column = GLuint{0}; column < columns; ++column)
1228
+            glVertexAttribI4iv(
1229
+                (GLuint)location + column,
1230
+                glm::value_ptr(value) + rows * column);
1231
+    }
1232
+    void static vertex_attrib_pointer(
1233
+        GLint       location,
1234
+        std::size_t offset = 0,
1235
+        std::size_t stride = sizeof(glm::ivec4))
1236
+    {
1237
+        if (GLBase::debug() >= 1)
1238
+            GLBase::check_supported({3, 0}, {});
1239
+        if (location == -1)
1240
+            return;
1241
+        auto constexpr sizeof_column = sizeof(glm::ivec4) / columns;
1242
+        for (auto column = GLuint{0}; column < columns; ++column)
1243
+            glVertexAttribIPointer(
1244
+                (GLuint)location + column,
1245
+                rows,
1246
+                type,
1247
+                (GLsizei)stride,
1248
+                (void const *)(offset + sizeof_column * column));
1249
+    }
1250
+};
1251
+
1252
+template <> struct GLTraits::Value<glm::uvec2>
1253
+{
1254
+    auto static constexpr name                 = "glm::uvec2";
1255
+    auto static constexpr columns              = GLint{1};
1256
+    auto static constexpr rows                 = GLint{2};
1257
+    auto static constexpr glsl                 = GLenum{GL_UNSIGNED_INT_VEC2};
1258
+    auto static constexpr format               = GLenum{GL_RG_INTEGER};
1259
+    auto static constexpr type                 = GLenum{GL_UNSIGNED_INT};
1260
+    auto static constexpr internal_format      = GLenum{GL_RG32UI};
1261
+    auto static constexpr internal_format_srgb = GLenum{GL_SRG8_EXT};
1262
+    auto static constexpr internal_format_compressed =
1263
+        GLenum{GL_COMPRESSED_RG};
1264
+    auto static constexpr internal_format_compressed_srgb =
1265
+        GLenum{GL_COMPRESSED_SRGB};
1266
+    auto static constexpr integer = bool(*"_INTEGER");
1267
+    void static uniform(GLint location, glm::uvec2 const & value)
1268
+    {
1269
+        if (GLBase::debug() >= 1)
1270
+            GLBase::check_supported({3, 0}, {});
1271
+        glUniform2uiv(location, 1, glm::value_ptr(value));
1272
+    }
1273
+    void static vertex_attrib(GLint location, glm::uvec2 const & value)
1274
+    {
1275
+        if (GLBase::debug() >= 1)
1276
+            GLBase::check_supported({3, 0}, {});
1277
+        if (location == -1)
1278
+            return;
1279
+        for (auto column = GLuint{0}; column < columns; ++column)
1280
+            glVertexAttribI2uiv(
1281
+                (GLuint)location + column,
1282
+                glm::value_ptr(value) + rows * column);
1283
+    }
1284
+    void static vertex_attrib_pointer(
1285
+        GLint       location,
1286
+        std::size_t offset = 0,
1287
+        std::size_t stride = sizeof(glm::uvec2))
1288
+    {
1289
+        if (GLBase::debug() >= 1)
1290
+            GLBase::check_supported({3, 0}, {});
1291
+        if (location == -1)
1292
+            return;
1293
+        auto constexpr sizeof_column = sizeof(glm::uvec2) / columns;
1294
+        for (auto column = GLuint{0}; column < columns; ++column)
1295
+            glVertexAttribIPointer(
1296
+                (GLuint)location + column,
1297
+                rows,
1298
+                type,
1299
+                (GLsizei)stride,
1300
+                (void const *)(offset + sizeof_column * column));
1301
+    }
1302
+};
1303
+
1304
+template <> struct GLTraits::Value<glm::uvec3>
1305
+{
1306
+    auto static constexpr name                 = "glm::uvec3";
1307
+    auto static constexpr columns              = GLint{1};
1308
+    auto static constexpr rows                 = GLint{3};
1309
+    auto static constexpr glsl                 = GLenum{GL_UNSIGNED_INT_VEC3};
1310
+    auto static constexpr format               = GLenum{GL_RGB_INTEGER};
1311
+    auto static constexpr type                 = GLenum{GL_UNSIGNED_INT};
1312
+    auto static constexpr internal_format      = GLenum{GL_RGB32UI};
1313
+    auto static constexpr internal_format_srgb = GLenum{GL_SRGB8};
1314
+    auto static constexpr internal_format_compressed =
1315
+        GLenum{GL_COMPRESSED_RGB};
1316
+    auto static constexpr internal_format_compressed_srgb =
1317
+        GLenum{GL_COMPRESSED_SRGB};
1318
+    auto static constexpr integer = bool(*"_INTEGER");
1319
+    void static uniform(GLint location, glm::uvec3 const & value)
1320
+    {
1321
+        if (GLBase::debug() >= 1)
1322
+            GLBase::check_supported({3, 0}, {});
1323
+        glUniform3uiv(location, 1, glm::value_ptr(value));
1324
+    }
1325
+    void static vertex_attrib(GLint location, glm::uvec3 const & value)
1326
+    {
1327
+        if (GLBase::debug() >= 1)
1328
+            GLBase::check_supported({3, 0}, {});
1329
+        if (location == -1)
1330
+            return;
1331
+        for (auto column = GLuint{0}; column < columns; ++column)
1332
+            glVertexAttribI3uiv(
1333
+                (GLuint)location + column,
1334
+                glm::value_ptr(value) + rows * column);
1335
+    }
1336
+    void static vertex_attrib_pointer(
1337
+        GLint       location,
1338
+        std::size_t offset = 0,
1339
+        std::size_t stride = sizeof(glm::uvec3))
1340
+    {
1341
+        if (GLBase::debug() >= 1)
1342
+            GLBase::check_supported({3, 0}, {});
1343
+        if (location == -1)
1344
+            return;
1345
+        auto constexpr sizeof_column = sizeof(glm::uvec3) / columns;
1346
+        for (auto column = GLuint{0}; column < columns; ++column)
1347
+            glVertexAttribIPointer(
1348
+                (GLuint)location + column,
1349
+                rows,
1350
+                type,
1351
+                (GLsizei)stride,
1352
+                (void const *)(offset + sizeof_column * column));
1353
+    }
1354
+};
1355
+
1356
+template <> struct GLTraits::Value<glm::uvec4>
1357
+{
1358
+    auto static constexpr name                 = "glm::uvec4";
1359
+    auto static constexpr columns              = GLint{1};
1360
+    auto static constexpr rows                 = GLint{4};
1361
+    auto static constexpr glsl                 = GLenum{GL_UNSIGNED_INT_VEC4};
1362
+    auto static constexpr format               = GLenum{GL_RGBA_INTEGER};
1363
+    auto static constexpr type                 = GLenum{GL_UNSIGNED_INT};
1364
+    auto static constexpr internal_format      = GLenum{GL_RGBA32UI};
1365
+    auto static constexpr internal_format_srgb = GLenum{GL_SRGB8_ALPHA8};
1366
+    auto static constexpr internal_format_compressed =
1367
+        GLenum{GL_COMPRESSED_RGBA};
1368
+    auto static constexpr internal_format_compressed_srgb =
1369
+        GLenum{GL_COMPRESSED_SRGB_ALPHA};
1370
+    auto static constexpr integer = bool(*"_INTEGER");
1371
+    void static uniform(GLint location, glm::uvec4 const & value)
1372
+    {
1373
+        if (GLBase::debug() >= 1)
1374
+            GLBase::check_supported({3, 0}, {});
1375
+        glUniform4uiv(location, 1, glm::value_ptr(value));
1376
+    }
1377
+    void static vertex_attrib(GLint location, glm::uvec4 const & value)
1378
+    {
1379
+        if (GLBase::debug() >= 1)
1380
+            GLBase::check_supported({3, 0}, {});
1381
+        if (location == -1)
1382
+            return;
1383
+        for (auto column = GLuint{0}; column < columns; ++column)
1384
+            glVertexAttribI4uiv(
1385
+                (GLuint)location + column,
1386
+                glm::value_ptr(value) + rows * column);
1387
+    }
1388
+    void static vertex_attrib_pointer(
1389
+        GLint       location,
1390
+        std::size_t offset = 0,
1391
+        std::size_t stride = sizeof(glm::uvec4))
1392
+    {
1393
+        if (GLBase::debug() >= 1)
1394
+            GLBase::check_supported({3, 0}, {});
1395
+        if (location == -1)
1396
+            return;
1397
+        auto constexpr sizeof_column = sizeof(glm::uvec4) / columns;
1398
+        for (auto column = GLuint{0}; column < columns; ++column)
1399
+            glVertexAttribIPointer(
1400
+                (GLuint)location + column,
1401
+                rows,
1402
+                type,
1403
+                (GLsizei)stride,
1404
+                (void const *)(offset + sizeof_column * column));
1405
+    }
1406
+};
1407
+
1408
+template <> struct GLTraits::Value<glm::dvec2>
1409
+{
1410
+    auto static constexpr name                 = "glm::dvec2";
1411
+    auto static constexpr columns              = GLint{1};
1412
+    auto static constexpr rows                 = GLint{2};
1413
+    auto static constexpr glsl                 = GLenum{GL_DOUBLE_VEC2};
1414
+    auto static constexpr format               = GLenum{GL_RG};
1415
+    auto static constexpr type                 = GLenum{GL_DOUBLE};
1416
+    auto static constexpr internal_format      = GLenum{GL_RG};
1417
+    auto static constexpr internal_format_srgb = GLenum{GL_SRG8_EXT};
1418
+    auto static constexpr internal_format_compressed =
1419
+        GLenum{GL_COMPRESSED_RG};
1420
+    auto static constexpr internal_format_compressed_srgb =
1421
+        GLenum{GL_COMPRESSED_SRGB};
1422
+    auto static constexpr integer = bool(*"");
1423
+    void static uniform(GLint location, glm::dvec2 const & value)
1424
+    {
1425
+        if (GLBase::debug() >= 1)
1426
+            GLBase::check_supported({4, 0}, "GL_ARB_gpu_shader_fp64");
1427
+        glUniform2dv(location, 1, glm::value_ptr(value));
1428
+    }
1429
+    void static vertex_attrib(GLint location, glm::dvec2 const & value)
1430
+    {
1431
+        if (GLBase::debug() >= 1)
1432
+            GLBase::check_supported({4, 1}, "GL_ARB_vertex_attrib_64bit");
1433
+        if (location == -1)
1434
+            return;
1435
+        for (auto column = GLuint{0}; column < columns; ++column)
1436
+            glVertexAttribL2dv(
1437
+                (GLuint)location + column,
1438
+                glm::value_ptr(value) + rows * column);
1439
+    }
1440
+    void static vertex_attrib_pointer(
1441
+        GLint       location,
1442
+        std::size_t offset = 0,
1443
+        std::size_t stride = sizeof(glm::dvec2))
1444
+    {
1445
+        if (GLBase::debug() >= 1)
1446
+            GLBase::check_supported({4, 1}, "GL_ARB_vertex_attrib_64bit");
1447
+        if (location == -1)
1448
+            return;
1449
+        auto constexpr sizeof_column = sizeof(glm::dvec2) / columns;
1450
+        for (auto column = GLuint{0}; column < columns; ++column)
1451
+            glVertexAttribLPointer(
1452
+                (GLuint)location + column,
1453
+                rows,
1454
+                type,
1455
+                (GLsizei)stride,
1456
+                (void const *)(offset + sizeof_column * column));
1457
+    }
1458
+};
1459
+
1460
+template <> struct GLTraits::Value<glm::dvec3>
1461
+{
1462
+    auto static constexpr name                 = "glm::dvec3";
1463
+    auto static constexpr columns              = GLint{1};
1464
+    auto static constexpr rows                 = GLint{3};
1465
+    auto static constexpr glsl                 = GLenum{GL_DOUBLE_VEC3};
1466
+    auto static constexpr format               = GLenum{GL_RGB};
1467
+    auto static constexpr type                 = GLenum{GL_DOUBLE};
1468
+    auto static constexpr internal_format      = GLenum{GL_RGB};
1469
+    auto static constexpr internal_format_srgb = GLenum{GL_SRGB8};
1470
+    auto static constexpr internal_format_compressed =
1471
+        GLenum{GL_COMPRESSED_RGB};
1472
+    auto static constexpr internal_format_compressed_srgb =
1473
+        GLenum{GL_COMPRESSED_SRGB};
1474
+    auto static constexpr integer = bool(*"");
1475
+    void static uniform(GLint location, glm::dvec3 const & value)
1476
+    {
1477
+        if (GLBase::debug() >= 1)
1478
+            GLBase::check_supported({4, 0}, "GL_ARB_gpu_shader_fp64");
1479
+        glUniform3dv(location, 1, glm::value_ptr(value));
1480
+    }
1481
+    void static vertex_attrib(GLint location, glm::dvec3 const & value)
1482
+    {
1483
+        if (GLBase::debug() >= 1)
1484
+            GLBase::check_supported({4, 1}, "GL_ARB_vertex_attrib_64bit");
1485
+        if (location == -1)
1486
+            return;
1487
+        for (auto column = GLuint{0}; column < columns; ++column)
1488
+            glVertexAttribL3dv(
1489
+                (GLuint)location + column,
1490
+                glm::value_ptr(value) + rows * column);
1491
+    }
1492
+    void static vertex_attrib_pointer(
1493
+        GLint       location,
1494
+        std::size_t offset = 0,
1495
+        std::size_t stride = sizeof(glm::dvec3))
1496
+    {
1497
+        if (GLBase::debug() >= 1)
1498
+            GLBase::check_supported({4, 1}, "GL_ARB_vertex_attrib_64bit");
1499
+        if (location == -1)
1500
+            return;
1501
+        auto constexpr sizeof_column = sizeof(glm::dvec3) / columns;
1502
+        for (auto column = GLuint{0}; column < columns; ++column)
1503
+            glVertexAttribLPointer(
1504
+                (GLuint)location + column,
1505
+                rows,
1506
+                type,
1507
+                (GLsizei)stride,
1508
+                (void const *)(offset + sizeof_column * column));
1509
+    }
1510
+};
1511
+
1512
+template <> struct GLTraits::Value<glm::dvec4>
1513
+{
1514
+    auto static constexpr name                 = "glm::dvec4";
1515
+    auto static constexpr columns              = GLint{1};
1516
+    auto static constexpr rows                 = GLint{4};
1517
+    auto static constexpr glsl                 = GLenum{GL_DOUBLE_VEC4};
1518
+    auto static constexpr format               = GLenum{GL_RGBA};
1519
+    auto static constexpr type                 = GLenum{GL_DOUBLE};
1520
+    auto static constexpr internal_format      = GLenum{GL_RGBA};
1521
+    auto static constexpr internal_format_srgb = GLenum{GL_SRGB8_ALPHA8};
1522
+    auto static constexpr internal_format_compressed =
1523
+        GLenum{GL_COMPRESSED_RGBA};
1524
+    auto static constexpr internal_format_compressed_srgb =
1525
+        GLenum{GL_COMPRESSED_SRGB_ALPHA};
1526
+    auto static constexpr integer = bool(*"");
1527
+    void static uniform(GLint location, glm::dvec4 const & value)
1528
+    {
1529
+        if (GLBase::debug() >= 1)
1530
+            GLBase::check_supported({4, 0}, "GL_ARB_gpu_shader_fp64");
1531
+        glUniform4dv(location, 1, glm::value_ptr(value));
1532
+    }
1533
+    void static vertex_attrib(GLint location, glm::dvec4 const & value)
1534
+    {
1535
+        if (GLBase::debug() >= 1)
1536
+            GLBase::check_supported({4, 1}, "GL_ARB_vertex_attrib_64bit");
1537
+        if (location == -1)
1538
+            return;
1539
+        for (auto column = GLuint{0}; column < columns; ++column)
1540
+            glVertexAttribL4dv(
1541
+                (GLuint)location + column,
1542
+                glm::value_ptr(value) + rows * column);
1543
+    }
1544
+    void static vertex_attrib_pointer(
1545
+        GLint       location,
1546
+        std::size_t offset = 0,
1547
+        std::size_t stride = sizeof(glm::dvec4))
1548
+    {
1549
+        if (GLBase::debug() >= 1)
1550
+            GLBase::check_supported({4, 1}, "GL_ARB_vertex_attrib_64bit");
1551
+        if (location == -1)
1552
+            return;
1553
+        auto constexpr sizeof_column = sizeof(glm::dvec4) / columns;
1554
+        for (auto column = GLuint{0}; column < columns; ++column)
1555
+            glVertexAttribLPointer(
1556
+                (GLuint)location + column,
1557
+                rows,
1558
+                type,
1559
+                (GLsizei)stride,
1560
+                (void const *)(offset + sizeof_column * column));
1561
+    }
1562
+};
1563
+
1564
+template <> struct GLTraits::Value<glm::dmat2>
1565
+{
1566
+    auto static constexpr name                 = "glm::dmat2";
1567
+    auto static constexpr columns              = GLint{2};
1568
+    auto static constexpr rows                 = GLint{2};
1569
+    auto static constexpr glsl                 = GLenum{GL_DOUBLE_MAT2};
1570
+    auto static constexpr format               = GLenum{GL_RG};
1571
+    auto static constexpr type                 = GLenum{GL_DOUBLE};
1572
+    auto static constexpr internal_format      = GLenum{GL_RG};
1573
+    auto static constexpr internal_format_srgb = GLenum{GL_SRG8_EXT};
1574
+    auto static constexpr internal_format_compressed =
1575
+        GLenum{GL_COMPRESSED_RG};
1576
+    auto static constexpr internal_format_compressed_srgb =
1577
+        GLenum{GL_COMPRESSED_SRGB};
1578
+    auto static constexpr integer = bool(*"");
1579
+    void static uniform(GLint location, glm::dmat2 const & value)
1580
+    {
1581
+        if (GLBase::debug() >= 1)
1582
+            GLBase::check_supported({4, 0}, "GL_ARB_gpu_shader_fp64");
1583
+        glUniformMatrix2dv(location, 1, GL_FALSE, glm::value_ptr(value));
1584
+    }
1585
+    void static vertex_attrib(GLint location, glm::dmat2 const & value)
1586
+    {
1587
+        if (GLBase::debug() >= 1)
1588
+            GLBase::check_supported({4, 1}, "GL_ARB_vertex_attrib_64bit");
1589
+        if (location == -1)
1590
+            return;
1591
+        for (auto column = GLuint{0}; column < columns; ++column)
1592
+            glVertexAttribL2dv(
1593
+                (GLuint)location + column,
1594
+                glm::value_ptr(value) + rows * column);
1595
+    }
1596
+    void static vertex_attrib_pointer(
1597
+        GLint       location,
1598
+        std::size_t offset = 0,
1599
+        std::size_t stride = sizeof(glm::dmat2))
1600
+    {
1601
+        if (GLBase::debug() >= 1)
1602
+            GLBase::check_supported({4, 1}, "GL_ARB_vertex_attrib_64bit");
1603
+        if (location == -1)
1604
+            return;
1605
+        auto constexpr sizeof_column = sizeof(glm::dmat2) / columns;
1606
+        for (auto column = GLuint{0}; column < columns; ++column)
1607
+            glVertexAttribLPointer(
1608
+                (GLuint)location + column,
1609
+                rows,
1610
+                type,
1611
+                (GLsizei)stride,
1612
+                (void const *)(offset + sizeof_column * column));
1613
+    }
1614
+};
1615
+
1616
+template <> struct GLTraits::Value<glm::dmat2x3>
1617
+{
1618
+    auto static constexpr name                 = "glm::dmat2x3";
1619
+    auto static constexpr columns              = GLint{2};
1620
+    auto static constexpr rows                 = GLint{3};
1621
+    auto static constexpr glsl                 = GLenum{GL_DOUBLE_MAT2x3};
1622
+    auto static constexpr format               = GLenum{GL_RGB};
1623
+    auto static constexpr type                 = GLenum{GL_DOUBLE};
1624
+    auto static constexpr internal_format      = GLenum{GL_RGB};
1625
+    auto static constexpr internal_format_srgb = GLenum{GL_SRGB8};
1626
+    auto static constexpr internal_format_compressed =
1627
+        GLenum{GL_COMPRESSED_RGB};
1628
+    auto static constexpr internal_format_compressed_srgb =
1629
+        GLenum{GL_COMPRESSED_SRGB};
1630
+    auto static constexpr integer = bool(*"");
1631
+    void static uniform(GLint location, glm::dmat2x3 const & value)
1632
+    {
1633
+        if (GLBase::debug() >= 1)
1634
+            GLBase::check_supported({4, 0}, "GL_ARB_gpu_shader_fp64");
1635
+        glUniformMatrix2x3dv(location, 1, GL_FALSE, glm::value_ptr(value));
1636
+    }
1637
+    void static vertex_attrib(GLint location, glm::dmat2x3 const & value)
1638
+    {
1639
+        if (GLBase::debug() >= 1)
1640
+            GLBase::check_supported({4, 1}, "GL_ARB_vertex_attrib_64bit");
1641
+        if (location == -1)
1642
+            return;
1643
+        for (auto column = GLuint{0}; column < columns; ++column)
1644
+            glVertexAttribL3dv(
1645
+                (GLuint)location + column,
1646
+                glm::value_ptr(value) + rows * column);
1647
+    }
1648
+    void static vertex_attrib_pointer(
1649
+        GLint       location,
1650
+        std::size_t offset = 0,
1651
+        std::size_t stride = sizeof(glm::dmat2x3))
1652
+    {
1653
+        if (GLBase::debug() >= 1)
1654
+            GLBase::check_supported({4, 1}, "GL_ARB_vertex_attrib_64bit");
1655
+        if (location == -1)
1656
+            return;
1657
+        auto constexpr sizeof_column = sizeof(glm::dmat2x3) / columns;
1658
+        for (auto column = GLuint{0}; column < columns; ++column)
1659
+            glVertexAttribLPointer(
1660
+                (GLuint)location + column,
1661
+                rows,
1662
+                type,
1663
+                (GLsizei)stride,
1664
+                (void const *)(offset + sizeof_column * column));
1665
+    }
1666
+};
1667
+
1668
+template <> struct GLTraits::Value<glm::dmat2x4>
1669
+{
1670
+    auto static constexpr name                 = "glm::dmat2x4";
1671
+    auto static constexpr columns              = GLint{2};
1672
+    auto static constexpr rows                 = GLint{4};
1673
+    auto static constexpr glsl                 = GLenum{GL_DOUBLE_MAT2x4};
1674
+    auto static constexpr format               = GLenum{GL_RGBA};
1675
+    auto static constexpr type                 = GLenum{GL_DOUBLE};
1676
+    auto static constexpr internal_format      = GLenum{GL_RGBA};
1677
+    auto static constexpr internal_format_srgb = GLenum{GL_SRGB8_ALPHA8};
1678
+    auto static constexpr internal_format_compressed =
1679
+        GLenum{GL_COMPRESSED_RGBA};
1680
+    auto static constexpr internal_format_compressed_srgb =
1681
+        GLenum{GL_COMPRESSED_SRGB_ALPHA};
1682
+    auto static constexpr integer = bool(*"");
1683
+    void static uniform(GLint location, glm::dmat2x4 const & value)
1684
+    {
1685
+        if (GLBase::debug() >= 1)
1686
+            GLBase::check_supported({4, 0}, "GL_ARB_gpu_shader_fp64");
1687
+        glUniformMatrix2x4dv(location, 1, GL_FALSE, glm::value_ptr(value));
1688
+    }
1689
+    void static vertex_attrib(GLint location, glm::dmat2x4 const & value)
1690
+    {
1691
+        if (GLBase::debug() >= 1)
1692
+            GLBase::check_supported({4, 1}, "GL_ARB_vertex_attrib_64bit");
1693
+        if (location == -1)
1694
+            return;
1695
+        for (auto column = GLuint{0}; column < columns; ++column)
1696
+            glVertexAttribL4dv(
1697
+                (GLuint)location + column,
1698
+                glm::value_ptr(value) + rows * column);
1699
+    }
1700
+    void static vertex_attrib_pointer(
1701
+        GLint       location,
1702
+        std::size_t offset = 0,
1703
+        std::size_t stride = sizeof(glm::dmat2x4))
1704
+    {
1705
+        if (GLBase::debug() >= 1)
1706
+            GLBase::check_supported({4, 1}, "GL_ARB_vertex_attrib_64bit");
1707
+        if (location == -1)
1708
+            return;
1709
+        auto constexpr sizeof_column = sizeof(glm::dmat2x4) / columns;
1710
+        for (auto column = GLuint{0}; column < columns; ++column)
1711
+            glVertexAttribLPointer(
1712
+                (GLuint)location + column,
1713
+                rows,
1714
+                type,
1715
+                (GLsizei)stride,
1716
+                (void const *)(offset + sizeof_column * column));
1717
+    }
1718
+};
1719
+
1720
+template <> struct GLTraits::Value<glm::dmat3x2>
1721
+{
1722
+    auto static constexpr name                 = "glm::dmat3x2";
1723
+    auto static constexpr columns              = GLint{3};
1724
+    auto static constexpr rows                 = GLint{2};
1725
+    auto static constexpr glsl                 = GLenum{GL_DOUBLE_MAT3x2};
1726
+    auto static constexpr format               = GLenum{GL_RG};
1727
+    auto static constexpr type                 = GLenum{GL_DOUBLE};
1728
+    auto static constexpr internal_format      = GLenum{GL_RG};
1729
+    auto static constexpr internal_format_srgb = GLenum{GL_SRG8_EXT};
1730
+    auto static constexpr internal_format_compressed =
1731
+        GLenum{GL_COMPRESSED_RG};
1732
+    auto static constexpr internal_format_compressed_srgb =
1733
+        GLenum{GL_COMPRESSED_SRGB};
1734
+    auto static constexpr integer = bool(*"");
1735
+    void static uniform(GLint location, glm::dmat3x2 const & value)
1736
+    {
1737
+        if (GLBase::debug() >= 1)
1738
+            GLBase::check_supported({4, 0}, "GL_ARB_gpu_shader_fp64");
1739
+        glUniformMatrix3x2dv(location, 1, GL_FALSE, glm::value_ptr(value));
1740
+    }
1741
+    void static vertex_attrib(GLint location, glm::dmat3x2 const & value)
1742
+    {
1743
+        if (GLBase::debug() >= 1)
1744
+            GLBase::check_supported({4, 1}, "GL_ARB_vertex_attrib_64bit");
1745
+        if (location == -1)
1746
+            return;
1747
+        for (auto column = GLuint{0}; column < columns; ++column)
1748
+            glVertexAttribL2dv(
1749
+                (GLuint)location + column,
1750
+                glm::value_ptr(value) + rows * column);
1751
+    }
1752
+    void static vertex_attrib_pointer(
1753
+        GLint       location,
1754
+        std::size_t offset = 0,
1755
+        std::size_t stride = sizeof(glm::dmat3x2))
1756
+    {
1757
+        if (GLBase::debug() >= 1)
1758
+            GLBase::check_supported({4, 1}, "GL_ARB_vertex_attrib_64bit");
1759
+        if (location == -1)
1760
+            return;
1761
+        auto constexpr sizeof_column = sizeof(glm::dmat3x2) / columns;
1762
+        for (auto column = GLuint{0}; column < columns; ++column)
1763
+            glVertexAttribLPointer(
1764
+                (GLuint)location + column,
1765
+                rows,
1766
+                type,
1767
+                (GLsizei)stride,
1768
+                (void const *)(offset + sizeof_column * column));
1769
+    }
1770
+};
1771
+
1772
+template <> struct GLTraits::Value<glm::dmat3>
1773
+{
1774
+    auto static constexpr name                 = "glm::dmat3";
1775
+    auto static constexpr columns              = GLint{3};
1776
+    auto static constexpr rows                 = GLint{3};
1777
+    auto static constexpr glsl                 = GLenum{GL_DOUBLE_MAT3};
1778
+    auto static constexpr format               = GLenum{GL_RGB};
1779
+    auto static constexpr type                 = GLenum{GL_DOUBLE};
1780
+    auto static constexpr internal_format      = GLenum{GL_RGB};
1781
+    auto static constexpr internal_format_srgb = GLenum{GL_SRGB8};
1782
+    auto static constexpr internal_format_compressed =
1783
+        GLenum{GL_COMPRESSED_RGB};
1784
+    auto static constexpr internal_format_compressed_srgb =
1785
+        GLenum{GL_COMPRESSED_SRGB};
1786
+    auto static constexpr integer = bool(*"");
1787
+    void static uniform(GLint location, glm::dmat3 const & value)
1788
+    {
1789
+        if (GLBase::debug() >= 1)
1790
+            GLBase::check_supported({4, 0}, "GL_ARB_gpu_shader_fp64");
1791
+        glUniformMatrix3dv(location, 1, GL_FALSE, glm::value_ptr(value));
1792
+    }
1793
+    void static vertex_attrib(GLint location, glm::dmat3 const & value)
1794
+    {
1795
+        if (GLBase::debug() >= 1)
1796
+            GLBase::check_supported({4, 1}, "GL_ARB_vertex_attrib_64bit");
1797
+        if (location == -1)
1798
+            return;
1799
+        for (auto column = GLuint{0}; column < columns; ++column)
1800
+            glVertexAttribL3dv(
1801
+                (GLuint)location + column,
1802
+                glm::value_ptr(value) + rows * column);
1803
+    }
1804
+    void static vertex_attrib_pointer(
1805
+        GLint       location,
1806
+        std::size_t offset = 0,
1807
+        std::size_t stride = sizeof(glm::dmat3))
1808
+    {
1809
+        if (GLBase::debug() >= 1)
1810
+            GLBase::check_supported({4, 1}, "GL_ARB_vertex_attrib_64bit");
1811
+        if (location == -1)
1812
+            return;
1813
+        auto constexpr sizeof_column = sizeof(glm::dmat3) / columns;
1814
+        for (auto column = GLuint{0}; column < columns; ++column)
1815
+            glVertexAttribLPointer(
1816
+                (GLuint)location + column,
1817
+                rows,
1818
+                type,
1819
+                (GLsizei)stride,
1820
+                (void const *)(offset + sizeof_column * column));
1821
+    }
1822
+};
1823
+
1824
+template <> struct GLTraits::Value<glm::dmat3x4>
1825
+{
1826
+    auto static constexpr name                 = "glm::dmat3x4";
1827
+    auto static constexpr columns              = GLint{3};
1828
+    auto static constexpr rows                 = GLint{4};
1829
+    auto static constexpr glsl                 = GLenum{GL_DOUBLE_MAT3x4};
1830
+    auto static constexpr format               = GLenum{GL_RGBA};
1831
+    auto static constexpr type                 = GLenum{GL_DOUBLE};
1832
+    auto static constexpr internal_format      = GLenum{GL_RGBA};
1833
+    auto static constexpr internal_format_srgb = GLenum{GL_SRGB8_ALPHA8};
1834
+    auto static constexpr internal_format_compressed =
1835
+        GLenum{GL_COMPRESSED_RGBA};
1836
+    auto static constexpr internal_format_compressed_srgb =
1837
+        GLenum{GL_COMPRESSED_SRGB_ALPHA};
1838
+    auto static constexpr integer = bool(*"");
1839
+    void static uniform(GLint location, glm::dmat3x4 const & value)
1840
+    {
1841
+        if (GLBase::debug() >= 1)
1842
+            GLBase::check_supported({4, 0}, "GL_ARB_gpu_shader_fp64");
1843
+        glUniformMatrix3x4dv(location, 1, GL_FALSE, glm::value_ptr(value));
1844
+    }
1845
+    void static vertex_attrib(GLint location, glm::dmat3x4 const & value)
1846
+    {
1847
+        if (GLBase::debug() >= 1)
1848
+            GLBase::check_supported({4, 1}, "GL_ARB_vertex_attrib_64bit");
1849
+        if (location == -1)
1850
+            return;
1851
+        for (auto column = GLuint{0}; column < columns; ++column)
1852
+            glVertexAttribL4dv(
1853
+                (GLuint)location + column,
1854
+                glm::value_ptr(value) + rows * column);
1855
+    }
1856
+    void static vertex_attrib_pointer(
1857
+        GLint       location,
1858
+        std::size_t offset = 0,
1859
+        std::size_t stride = sizeof(glm::dmat3x4))
1860
+    {
1861
+        if (GLBase::debug() >= 1)
1862
+            GLBase::check_supported({4, 1}, "GL_ARB_vertex_attrib_64bit");
1863
+        if (location == -1)
1864
+            return;
1865
+        auto constexpr sizeof_column = sizeof(glm::dmat3x4) / columns;
1866
+        for (auto column = GLuint{0}; column < columns; ++column)
1867
+            glVertexAttribLPointer(
1868
+                (GLuint)location + column,
1869
+                rows,
1870
+                type,
1871
+                (GLsizei)stride,
1872
+                (void const *)(offset + sizeof_column * column));
1873
+    }
1874
+};
1875
+
1876
+template <> struct GLTraits::Value<glm::dmat4x2>
1877
+{
1878
+    auto static constexpr name                 = "glm::dmat4x2";
1879
+    auto static constexpr columns              = GLint{4};
1880
+    auto static constexpr rows                 = GLint{2};
1881
+    auto static constexpr glsl                 = GLenum{GL_DOUBLE_MAT4x2};
1882
+    auto static constexpr format               = GLenum{GL_RG};
1883
+    auto static constexpr type                 = GLenum{GL_DOUBLE};
1884
+    auto static constexpr internal_format      = GLenum{GL_RG};
1885
+    auto static constexpr internal_format_srgb = GLenum{GL_SRG8_EXT};
1886
+    auto static constexpr internal_format_compressed =
1887
+        GLenum{GL_COMPRESSED_RG};
1888
+    auto static constexpr internal_format_compressed_srgb =
1889
+        GLenum{GL_COMPRESSED_SRGB};
1890
+    auto static constexpr integer = bool(*"");
1891
+    void static uniform(GLint location, glm::dmat4x2 const & value)
1892
+    {
1893
+        if (GLBase::debug() >= 1)
1894
+            GLBase::check_supported({4, 0}, "GL_ARB_gpu_shader_fp64");
1895
+        glUniformMatrix4x2dv(location, 1, GL_FALSE, glm::value_ptr(value));
1896
+    }
1897
+    void static vertex_attrib(GLint location, glm::dmat4x2 const & value)
1898
+    {
1899
+        if (GLBase::debug() >= 1)
1900
+            GLBase::check_supported({4, 1}, "GL_ARB_vertex_attrib_64bit");
1901
+        if (location == -1)
1902
+            return;
1903
+        for (auto column = GLuint{0}; column < columns; ++column)
1904
+            glVertexAttribL2dv(
1905
+                (GLuint)location + column,
1906
+                glm::value_ptr(value) + rows * column);
1907
+    }
1908
+    void static vertex_attrib_pointer(
1909
+        GLint       location,
1910
+        std::size_t offset = 0,
1911
+        std::size_t stride = sizeof(glm::dmat4x2))
1912
+    {
1913
+        if (GLBase::debug() >= 1)
1914
+            GLBase::check_supported({4, 1}, "GL_ARB_vertex_attrib_64bit");
1915
+        if (location == -1)
1916
+            return;
1917
+        auto constexpr sizeof_column = sizeof(glm::dmat4x2) / columns;
1918
+        for (auto column = GLuint{0}; column < columns; ++column)
1919
+            glVertexAttribLPointer(
1920
+                (GLuint)location + column,
1921
+                rows,
1922
+                type,
1923
+                (GLsizei)stride,
1924
+                (void const *)(offset + sizeof_column * column));
1925
+    }
1926
+};
1927
+
1928
+template <> struct GLTraits::Value<glm::dmat4x3>
1929
+{
1930
+    auto static constexpr name                 = "glm::dmat4x3";
1931
+    auto static constexpr columns              = GLint{4};
1932
+    auto static constexpr rows                 = GLint{3};
1933
+    auto static constexpr glsl                 = GLenum{GL_DOUBLE_MAT4x3};
1934
+    auto static constexpr format               = GLenum{GL_RGB};
1935
+    auto static constexpr type                 = GLenum{GL_DOUBLE};
1936
+    auto static constexpr internal_format      = GLenum{GL_RGB};
1937
+    auto static constexpr internal_format_srgb = GLenum{GL_SRGB8};
1938
+    auto static constexpr internal_format_compressed =
1939
+        GLenum{GL_COMPRESSED_RGB};
1940
+    auto static constexpr internal_format_compressed_srgb =
1941
+        GLenum{GL_COMPRESSED_SRGB};
1942
+    auto static constexpr integer = bool(*"");
1943
+    void static uniform(GLint location, glm::dmat4x3 const & value)
1944
+    {
1945
+        if (GLBase::debug() >= 1)
1946
+            GLBase::check_supported({4, 0}, "GL_ARB_gpu_shader_fp64");
1947
+        glUniformMatrix4x3dv(location, 1, GL_FALSE, glm::value_ptr(value));
1948
+    }
1949
+    void static vertex_attrib(GLint location, glm::dmat4x3 const & value)
1950
+    {
1951
+        if (GLBase::debug() >= 1)
1952
+            GLBase::check_supported({4, 1}, "GL_ARB_vertex_attrib_64bit");
1953
+        if (location == -1)
1954
+            return;
1955
+        for (auto column = GLuint{0}; column < columns; ++column)
1956
+            glVertexAttribL3dv(
1957
+                (GLuint)location + column,
1958
+                glm::value_ptr(value) + rows * column);
1959
+    }
1960
+    void static vertex_attrib_pointer(
1961
+        GLint       location,
1962
+        std::size_t offset = 0,
1963
+        std::size_t stride = sizeof(glm::dmat4x3))
1964
+    {
1965
+        if (GLBase::debug() >= 1)
1966
+            GLBase::check_supported({4, 1}, "GL_ARB_vertex_attrib_64bit");
1967
+        if (location == -1)
1968
+            return;
1969
+        auto constexpr sizeof_column = sizeof(glm::dmat4x3) / columns;
1970
+        for (auto column = GLuint{0}; column < columns; ++column)
1971
+            glVertexAttribLPointer(
1972
+                (GLuint)location + column,
1973
+                rows,
1974
+                type,
1975
+                (GLsizei)stride,
1976
+                (void const *)(offset + sizeof_column * column));
1977
+    }
1978
+};
1979
+
1980
+template <> struct GLTraits::Value<glm::dmat4>
1981
+{
1982
+    auto static constexpr name                 = "glm::dmat4";
1983
+    auto static constexpr columns              = GLint{4};
1984
+    auto static constexpr rows                 = GLint{4};
1985
+    auto static constexpr glsl                 = GLenum{GL_DOUBLE_MAT4};
1986
+    auto static constexpr format               = GLenum{GL_RGBA};
1987
+    auto static constexpr type                 = GLenum{GL_DOUBLE};
1988
+    auto static constexpr internal_format      = GLenum{GL_RGBA};
1989
+    auto static constexpr internal_format_srgb = GLenum{GL_SRGB8_ALPHA8};
1990
+    auto static constexpr internal_format_compressed =
1991
+        GLenum{GL_COMPRESSED_RGBA};
1992
+    auto static constexpr internal_format_compressed_srgb =
1993
+        GLenum{GL_COMPRESSED_SRGB_ALPHA};
1994
+    auto static constexpr integer = bool(*"");
1995
+    void static uniform(GLint location, glm::dmat4 const & value)
1996
+    {
1997
+        if (GLBase::debug() >= 1)
1998
+            GLBase::check_supported({4, 0}, "GL_ARB_gpu_shader_fp64");
1999
+        glUniformMatrix4dv(location, 1, GL_FALSE, glm::value_ptr(value));
2000
+    }
2001
+    void static vertex_attrib(GLint location, glm::dmat4 const & value)
2002
+    {
2003
+        if (GLBase::debug() >= 1)
2004
+            GLBase::check_supported({4, 1}, "GL_ARB_vertex_attrib_64bit");
2005
+        if (location == -1)
2006
+            return;
2007
+        for (auto column = GLuint{0}; column < columns; ++column)
2008
+            glVertexAttribL4dv(
2009
+                (GLuint)location + column,
2010
+                glm::value_ptr(value) + rows * column);
2011
+    }
2012
+    void static vertex_attrib_pointer(
2013
+        GLint       location,
2014
+        std::size_t offset = 0,
2015
+        std::size_t stride = sizeof(glm::dmat4))
2016
+    {
2017
+        if (GLBase::debug() >= 1)
2018
+            GLBase::check_supported({4, 1}, "GL_ARB_vertex_attrib_64bit");
2019
+        if (location == -1)
2020
+            return;
2021
+        auto constexpr sizeof_column = sizeof(glm::dmat4) / columns;
2022
+        for (auto column = GLuint{0}; column < columns; ++column)
2023
+            glVertexAttribLPointer(
2024
+                (GLuint)location + column,
2025
+                rows,
2026
+                type,
2027
+                (GLsizei)stride,
2028
+                (void const *)(offset + sizeof_column * column));
2029
+    }
2030
+};
2031
+