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