1 module des.gl.base.rbo;
2 
3 import std.exception;
4 import std.conv;
5 
6 import derelict.opengl3.gl3;
7 
8 import des.math.linear;
9 
10 import des.gl.base.type;
11 
12 ///
13 class GLRenderBuffer : DesObject
14 {
15     mixin DES;
16     mixin ClassLogger;
17 
18 protected:
19     uint _id;
20     Format _format;
21 
22 public:
23 
24     ///
25     enum Format
26     {
27         R8                 = GL_R8,                 /// `GL_R8`
28         R8UI               = GL_R8UI,               /// `GL_R8UI`
29         R8I                = GL_R8I,                /// `GL_R8I`
30         R16UI              = GL_R16UI,              /// `GL_R16UI`
31         R16I               = GL_R16I,               /// `GL_R16I`
32         R32UI              = GL_R32UI,              /// `GL_R32UI`
33         R32I               = GL_R32I,               /// `GL_R32I`
34         RG8                = GL_RG8,                /// `GL_RG8`
35         RG8UI              = GL_RG8UI,              /// `GL_RG8UI`
36         RG8I               = GL_RG8I,               /// `GL_RG8I`
37         RG16UI             = GL_RG16UI,             /// `GL_RG16UI`
38         RG16I              = GL_RG16I,              /// `GL_RG16I`
39         RG32UI             = GL_RG32UI,             /// `GL_RG32UI`
40         RG32I              = GL_RG32I,              /// `GL_RG32I`
41         RGB8               = GL_RGB8,               /// `GL_RGB8`
42         RGBA8              = GL_RGBA8,              /// `GL_RGBA8`
43         SRGB8_ALPHA8       = GL_SRGB8_ALPHA8,       /// `GL_SRGB8_ALPHA8`
44         RGB5_A1            = GL_RGB5_A1,            /// `GL_RGB5_A1`
45         RGBA4              = GL_RGBA4,              /// `GL_RGBA4`
46         RGB10_A2           = GL_RGB10_A2,           /// `GL_RGB10_A2`
47         RGBA8UI            = GL_RGBA8UI,            /// `GL_RGBA8UI`
48         RGBA8I             = GL_RGBA8I,             /// `GL_RGBA8I`
49         RGB10_A2UI         = GL_RGB10_A2UI,         /// `GL_RGB10_A2UI`
50         RGBA16UI           = GL_RGBA16UI,           /// `GL_RGBA16UI`
51         RGBA16I            = GL_RGBA16I,            /// `GL_RGBA16I`
52         RGBA32I            = GL_RGBA32I,            /// `GL_RGBA32I`
53         RGBA32UI           = GL_RGBA32UI,           /// `GL_RGBA32UI`
54         DEPTH_COMPONENT16  = GL_DEPTH_COMPONENT16,  /// `GL_DEPTH_COMPONENT16`
55         DEPTH_COMPONENT24  = GL_DEPTH_COMPONENT24,  /// `GL_DEPTH_COMPONENT24`
56         DEPTH_COMPONENT32F = GL_DEPTH_COMPONENT32F, /// `GL_DEPTH_COMPONENT32F`
57         DEPTH24_STENCIL8   = GL_DEPTH24_STENCIL8,   /// `GL_DEPTH24_STENCIL8`
58         DEPTH32F_STENCIL8  = GL_DEPTH32F_STENCIL8,  /// `GL_DEPTH32F_STENCIL8`
59         STENCIL_INDEX8     = GL_STENCIL_INDEX8      /// `GL_STENCIL_INDEX8`
60     }
61 
62     /// `glGenRenderbuffers`
63     this()
64     {
65         checkGLCall!glGenRenderbuffers( 1, &_id );
66         logger = new InstanceLogger( this, std..string.format( "%d", _id ) );
67         logger.Debug( "pass" );
68     }
69 
70     final pure const @property
71     {
72         ///
73         uint id() { return _id; }
74 
75         ///
76         Format format() { return _format; }
77     }
78 
79     /// `glBindRenderbuffer( GL_RENDERBUFFER, id )`
80     void bind()
81     {
82         checkGLCall!glBindRenderbuffer( GL_RENDERBUFFER, _id );
83         debug logger.trace( "[%d]", id );
84     }
85 
86     /// `glBindRenderbuffer( GL_RENDERBUFFER, 0 )`
87     void unbind()
88     {
89         checkGLCall!glBindRenderbuffer( GL_RENDERBUFFER, 0 );
90         debug logger.trace( "call from [%d]", _id );
91     }
92 
93     /// `glRenderbufferStorage`
94     void storage( in uivec2 sz, Format fmt )
95     in
96     {
97         assert( sz[0] < GL_MAX_RENDERBUFFER_SIZE );
98         assert( sz[1] < GL_MAX_RENDERBUFFER_SIZE );
99     }
100     body
101     {
102         bind();
103         _format = fmt;
104         checkGLCall!glRenderbufferStorage( GL_RENDERBUFFER, cast(GLenum)fmt, sz[0], sz[1] );
105         unbind();
106         debug logger.Debug( "size [%d,%d], format [%s]", sz[0], sz[1], fmt );
107     }
108 
109     /// ditto
110     void storage(T)( in Vector!(2,T) sz, Format fmt )
111     if( isIntegral!T )
112     in
113     {
114         assert( sz[0] > 0 );
115         assert( sz[1] > 0 );
116     }
117     body { storage( uivec2(sz), fmt ); }
118 
119     /// set storage with new size and old format
120     void resize( in uivec2 sz )
121     in
122     {
123         assert( sz[0] > 0 );
124         assert( sz[1] > 0 );
125     }
126     body { storage( sz, _format ); }
127 
128     /// ditto
129     void resize(T)( in Vector!(2,T) sz )
130     if( isIntegral!T )
131     in
132     {
133         assert( sz[0] > 0 );
134         assert( sz[1] > 0 );
135     }
136     body { resize( uivec2(sz) ); }
137 
138 protected:
139 
140     override void selfDestroy()
141     {
142         unbind();
143         checkGLCall!glDeleteRenderbuffers( 1, &_id );
144         logger.Debug( "pass" );
145     }
146 }