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