1 module gfm.opengl.renderbuffer; 2 3 import std.string; 4 5 import derelict.opengl3.gl3; 6 7 import gfm.math.funcs, 8 gfm.opengl.opengl; 9 10 /// OpenGL Renderbuffer wrapper. 11 final class GLRenderBuffer 12 { 13 public 14 { 15 /// <p>Creates an OpenGL renderbuffer.</p> 16 /// <p>If asking for a multisampled render buffer fails, 17 /// a non multisampled buffer will be created instead.</p> 18 /// Throws: $(D OpenGLException) if creation failed. 19 this(OpenGL gl, GLenum internalFormat, int width, int height, int samples = 0) 20 { 21 _gl = gl; 22 glGenRenderbuffers(1, &_handle); 23 gl.runtimeCheck(); 24 25 use(); 26 scope(exit) unuse(); 27 if (samples > 1) 28 { 29 // fallback to non multisampled 30 if (glRenderbufferStorageMultisample is null) 31 { 32 gl._logger.warningf("render-buffer multisampling is not supported, fallback to non-multisampled"); 33 goto non_mutisampled; 34 } 35 36 int maxSamples; 37 glGetIntegerv(GL_MAX_SAMPLES, &maxSamples); 38 if (maxSamples < 1) 39 maxSamples = 1; 40 41 // limit samples to what is supported on this machine 42 if (samples >= maxSamples) 43 { 44 int newSamples = clamp(samples, 0, maxSamples - 1); 45 gl._logger.warningf(format("implementation does not support %s samples, fallback to %s samples", samples, newSamples)); 46 samples = newSamples; 47 } 48 49 try 50 { 51 glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, internalFormat, width, height); 52 } 53 catch(OpenGLException e) 54 { 55 _gl._logger.warning(e.msg); 56 goto non_mutisampled; // fallback to non multisampled 57 } 58 } 59 else 60 { 61 non_mutisampled: 62 glRenderbufferStorage(GL_RENDERBUFFER, internalFormat, width, height); 63 gl.runtimeCheck(); 64 } 65 66 _initialized = true; 67 } 68 69 ~this() 70 { 71 close(); 72 } 73 74 /// Releases the OpenGL renderbuffer resource. 75 void close() 76 { 77 if (_initialized) 78 { 79 _initialized = false; 80 glDeleteRenderbuffers(1, &_handle); 81 } 82 } 83 84 /// Binds this renderbuffer. 85 /// Throws: $(D OpenGLException) on error. 86 void use() 87 { 88 glBindRenderbuffer(GL_RENDERBUFFER, _handle); 89 _gl.runtimeCheck(); 90 } 91 92 /// Unbinds this renderbuffer. 93 /// Throws: $(D OpenGLException) on error. 94 void unuse() 95 { 96 glBindRenderbuffer(GL_RENDERBUFFER, 0); 97 _gl.runtimeCheck(); 98 } 99 100 /// Returns: Wrapped OpenGL resource handle. 101 GLuint handle() pure const nothrow 102 { 103 return _handle; 104 } 105 } 106 107 package 108 { 109 GLuint _handle; 110 } 111 112 private 113 { 114 OpenGL _gl; 115 GLenum _format; 116 GLenum _type; 117 bool _initialized; 118 } 119 }