1 #include "glObjects.h" 2 3 #if FEATURE_3D_RENDERING 4 5 #include <GL/glew.h> 6 #include <type_traits> 7 #include <cassert> 8 9 static_assert(std::is_same<uint32_t, GLuint>::value, "GLuint and uint32_t are *NOT* the same: troubles!"); 10 11 #ifndef NDEBUG 12 #define GL_STRINGIFY(v) #v 13 #define GL_CHECK(statement) \ 14 do { \ 15 auto err = glGetError(); \ 16 assert(err == GL_NO_ERROR && "Error before " GL_STRINGIFY(statement)); \ 17 statement; \ 18 err = glGetError(); \ 19 assert(err == GL_NO_ERROR && "Error after " GL_STRINGIFY(statement)); \ 20 } while (false) 21 #else 22 #define GL_CHECK(statement) statement 23 #endif 24 25 namespace gl 26 { 27 namespace details 28 { createBuffers(size_t count,uint32_t * buffers)29 void createBuffers(size_t count, uint32_t* buffers) 30 { 31 GL_CHECK(glGenBuffers(count, buffers)); 32 } deleteBuffers(size_t count,const uint32_t * buffers)33 void deleteBuffers(size_t count, const uint32_t* buffers) 34 { 35 GL_CHECK(glDeleteBuffers(count, buffers)); 36 } 37 createTextures(size_t count,uint32_t * textures)38 void createTextures(size_t count, uint32_t* textures) 39 { 40 GL_CHECK(glGenTextures(count, textures)); 41 } deleteTextures(size_t count,const uint32_t * textures)42 void deleteTextures(size_t count, const uint32_t* textures) 43 { 44 GL_CHECK(glDeleteTextures(count, textures)); 45 } 46 } 47 ScopedBufferBinding(uint32_t target,uint32_t buffer)48 ScopedBufferBinding::ScopedBufferBinding(uint32_t target, uint32_t buffer) 49 :target{target}, buffer{buffer} 50 { 51 GL_CHECK(glBindBuffer(target, buffer)); 52 } 53 ~ScopedBufferBinding()54 ScopedBufferBinding::~ScopedBufferBinding() 55 { 56 GL_CHECK(glBindBuffer(target, GL_NONE)); 57 } 58 ScopedVertexAttribArray(int32_t attrib)59 ScopedVertexAttribArray::ScopedVertexAttribArray(int32_t attrib) 60 :attrib{ attrib } 61 { 62 if (attrib != -1) 63 GL_CHECK(glEnableVertexAttribArray(attrib)); 64 } 65 ~ScopedVertexAttribArray()66 ScopedVertexAttribArray::~ScopedVertexAttribArray() 67 { 68 if (attrib != -1) 69 GL_CHECK(glDisableVertexAttribArray(attrib)); 70 } 71 ScopedVertexAttribArray(ScopedVertexAttribArray && other)72 ScopedVertexAttribArray::ScopedVertexAttribArray(ScopedVertexAttribArray&& other) noexcept 73 :attrib{other.attrib} 74 { 75 other.attrib = -1; 76 } 77 operator =(ScopedVertexAttribArray && other)78 ScopedVertexAttribArray& ScopedVertexAttribArray::operator=(ScopedVertexAttribArray&& other) noexcept 79 { 80 if (this != &other) 81 { 82 if (attrib != -1 && attrib != other.attrib) 83 GL_CHECK(glDisableVertexAttribArray(attrib)); 84 attrib = other.attrib; 85 other.attrib = -1; 86 } 87 88 return *this; 89 } 90 ScopedTexture(uint32_t target,uint32_t texture)91 ScopedTexture::ScopedTexture(uint32_t target, uint32_t texture) 92 :target{ target }, texture{ texture } 93 { 94 // ES2 only supports 2D textures and cubemaps. 95 GL_CHECK(glGetIntegerv(target == GL_TEXTURE_2D ? GL_TEXTURE_BINDING_2D : GL_TEXTURE_BINDING_CUBE_MAP, (int32_t*)&previously_bound)); 96 97 if (previously_bound != texture) 98 GL_CHECK(glBindTexture(target, texture)); 99 } 100 ~ScopedTexture()101 ScopedTexture::~ScopedTexture() 102 { 103 if (previously_bound != texture) 104 GL_CHECK(glBindTexture(target, previously_bound)); 105 } 106 isAvailable()107 bool isAvailable() 108 { 109 // Works in "greater or equal than" fashion.. 110 return GLEW_VERSION_2_0; 111 } 112 } // namespace gl 113 114 #endif // FEATURE_3D_RENDERING 115 116