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 /// Releases the OpenGL renderbuffer resource. 70 ~this() 71 { 72 if (_initialized) 73 { 74 debug ensureNotInGC("GLRenderer"); 75 _initialized = false; 76 glDeleteRenderbuffers(1, &_handle); 77 } 78 } 79 deprecated("Use .destroy instead") void close(){} 80 81 /// Binds this renderbuffer. 82 /// Throws: $(D OpenGLException) on error. 83 void use() 84 { 85 glBindRenderbuffer(GL_RENDERBUFFER, _handle); 86 _gl.runtimeCheck(); 87 } 88 89 /// Unbinds this renderbuffer. 90 /// Throws: $(D OpenGLException) on error. 91 void unuse() 92 { 93 glBindRenderbuffer(GL_RENDERBUFFER, 0); 94 _gl.runtimeCheck(); 95 } 96 97 /// Returns: Wrapped OpenGL resource handle. 98 GLuint handle() pure const nothrow 99 { 100 return _handle; 101 } 102 } 103 104 package 105 { 106 GLuint _handle; 107 } 108 109 private 110 { 111 OpenGL _gl; 112 GLenum _format; 113 GLenum _type; 114 bool _initialized; 115 } 116 }