1 module gfx.gl3.context;
2 
3 import gfx.bindings.opengl.gl : Gl;
4 import gfx.core.rc : IAtomicRefCounted;
5 import gfx.graal.format : Format;
6 
7 enum GlProfile
8 {
9     core,
10     compatibility
11 }
12 
13 struct GlAttribs
14 {
15     enum profile = GlProfile.core;
16     enum doublebuffer = true;
17 
18     uint majorVersion = 3;
19     uint minorVersion = 1;
20 
21     uint samples = 1;
22 
23     @property Format colorFormat() const pure {
24         return _colorFormat;
25     }
26     @property Format depthStencilFormat() const pure {
27         return _depthStencilFormat;
28     }
29 
30     private Format _colorFormat = Format.rgba8_uNorm;
31     private Format _depthStencilFormat = Format.d24s8_uNorm;
32 
33     @property uint decimalVersion() const pure {
34         return majorVersion * 10 + minorVersion;
35     }
36 }
37 
38 /// The list of OpenGL versions that gfx-d is compatible with.
39 immutable uint[] glVersions = [
40     46, 45, 44, 43, 42, 41, 40,
41     33, 32, 31, // 30
42     // 21, 20,
43     // 15, 14, 13, 12, 11, 10,
44 ];
45 
46 /// The GLSL version for the passed OpenGL version.
47 uint glslVersion(in uint glVersion) pure {
48     if (glVersion >= 33) return 10*glVersion;
49     switch(glVersion) {
50     case 32:    return 150;
51     case 31:    return 140;
52     case 30:    return 130;
53     case 21:    return 120;
54     case 20:    return 110;
55     default:    assert(false);
56     }
57 }
58 
59 interface GlContext : IAtomicRefCounted
60 {
61     @property Gl gl();
62 
63     @property GlAttribs attribs();
64 
65     bool makeCurrent(size_t nativeHandle);
66 
67     void doneCurrent();
68 
69     @property bool current();
70 
71     @property int swapInterval()
72     in { assert(current); }
73 
74     @property void swapInterval(int interval)
75     in { assert(current); }
76 
77     void swapBuffers(size_t nativeHandle)
78     in { assert(current); }
79 }
80 
81 immutable string[] glRequiredExtensions = [
82     "GL_ARB_framebuffer_object"
83 ];
84 immutable string[] glOptionalExtensions = [
85     "GL_ARB_buffer_storage",
86     "GL_ARB_texture_storage",
87     "GL_ARB_texture_storage_multisample",
88     "GL_ARB_sampler_object",
89     "ARB_draw_elements_base_vertex",
90     "ARB_base_instance",
91     "ARB_viewport_array",
92     "GL_EXT_polygon_offset_clamp",
93 ];
94 
95 string[] glAvailableExtensions(Gl gl)
96 {
97     import gfx.bindings.opengl.gl : GLint, GL_EXTENSIONS, GL_NUM_EXTENSIONS;
98 
99     GLint num;
100     gl.GetIntegerv(GL_NUM_EXTENSIONS, &num);
101     string[] exts;
102     foreach (i; 0 .. num)
103     {
104         import std..string : fromStringz;
105         auto cStr = cast(const(char)*)gl.GetStringi(GL_EXTENSIONS, i);
106         exts ~= fromStringz(cStr).idup;
107     }
108     return exts;
109 }