1 /** 2 * Copyright: Copyright (C) 2018 Gabriel Gheorghe, All Rights Reserved 3 * Authors: $(Gabriel Gheorghe) 4 * License: $(LINK2 https://www.gnu.org/licenses/gpl-3.0.txt, GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007) 5 * Source: $(LINK2 https://github.com/GabyForceQ/LibertyEngine/blob/master/source/liberty/graphics/opengl/buffer.d, _buffer.d) 6 * Documentation: 7 * Coverage: 8 */ 9 // TODO: optimize imports 10 module liberty.graphics.opengl.buffer; 11 version (__OpenGL__) : 12 import derelict.opengl; 13 import liberty.graphics.renderer; 14 import liberty.graphics.video.buffer : VideoBuffer; 15 /// OpenGL Buffer. 16 final class GLBuffer : VideoBuffer { 17 /// Creates an empty buffer. 18 /// Throws: $(D GLException) on error. 19 this(uint target, uint usage) { 20 _usage = usage; 21 _target = target; 22 _firstLoad = true; 23 glGenBuffers(1, &_buffer); 24 GraphicsEngine.get.backend.runtimeCheck(); 25 _initialized = true; 26 _size = 0; 27 } 28 /// Creates a buffer already filled with data. 29 /// Throws: $(D GLException) on error. 30 this(T)(uint target, uint usage, T[] buffer) { 31 this(target, usage); 32 data(buffer); 33 } 34 /// Releases the OpenGL buffer resource. 35 ~this() { 36 if (_initialized) { 37 debug import liberty.core.memory : ensureNotInGC; 38 debug ensureNotInGC("GLBuffer"); 39 glDeleteBuffers(1, &_buffer); 40 _initialized = false; 41 } 42 } 43 /// Returns the size of the buffer in bytes. 44 override size_t size() pure const nothrow { 45 return _size; 46 } 47 /// Returns the copy bytes to the buffer. 48 /// Throws: $(D OpenGLException) on error. 49 void data(T)(T[] buffer) { 50 setData(buffer.length * T.sizeof, buffer.ptr); 51 } 52 /// Returns the copy bytes to the buffer. 53 /// Throws: $(D GLException) on error. 54 override void setData(size_t size, void* data) { 55 bind(); 56 _size = size; 57 if (!_firstLoad) { 58 glBufferData(_target, size, null, _usage); 59 glBufferSubData(_target, 0, size, data); 60 } else { 61 glBufferData(_target, size, data, _usage); 62 } 63 GraphicsEngine.get.backend.runtimeCheck(); 64 _firstLoad = false; 65 } 66 /// Copies bytes to a sub-part of the buffer. You can't adress data beyond the buffer's size. 67 /// Throws: $(D GLException) on error. 68 override void setSubData(size_t offset, size_t size, void* data) { 69 bind(); 70 glBufferSubData(_target, offset, size, data); 71 GraphicsEngine.get.backend.runtimeCheck(); 72 } 73 74 /// Gets a sub-part of a buffer. 75 /// Throws: $(D GLException) on error. 76 override void getSubData(size_t offset, size_t size, void* data) { 77 bind(); 78 glGetBufferSubData(_target, offset, size, data); 79 GraphicsEngine.get.backend.runtimeCheck(); 80 } 81 82 /// Gets the whole buffer content in a newly allocated array. 83 /// <b>This is intended for debugging purposes.</b> 84 /// Throws: $(D GLException) on error. 85 override ubyte[] bytes() { 86 auto buffer = new ubyte[_size]; 87 getSubData(0, _size, buffer.ptr); 88 return buffer; 89 } 90 /// Binds this buffer. 91 /// Throws: $(D GLException) on error. 92 override void bind() @trusted { 93 glBindBuffer(_target, _buffer); 94 GraphicsEngine.get.backend.runtimeCheck(); 95 } 96 /// Unbinds this buffer. 97 /// Throws: $(D GLException) on error. 98 override void unbind() { 99 glBindBuffer(_target, 0); 100 } 101 /// Returns: Wrapped OpenGL resource handle. 102 override uint handle() pure nothrow const { 103 return _buffer; 104 } 105 }