SLProject  4.2.000
A platform independent 3D computer graphics framework for desktop OS, Android, iOS and online in web browsers
SLGLDepthBuffer.cpp
Go to the documentation of this file.
1 /**
2  * \file SLGLDepthBuffer.h
3  * \brief Uses an OpenGL framebuffer object as a depth-buffer
4  * \date May 2020
5  * \authors Michael Schertenleib
6  * \copyright http://opensource.org/licenses/GPL-3.0
7  * \remarks Please use clangformat to format the code. See more code style on
8  * https://github.com/cpvrlab/SLProject4/wiki/SLProject-Coding-Style
9 */
10 
11 #include <SLGLState.h>
12 #include <SLGLDepthBuffer.h>
13 #include <Profiler.h>
14 
15 //-----------------------------------------------------------------------------
16 /*!
17  * Constructor for OpenGL depth buffer framebuffer used in shadow mapping
18  * \param dimensions 2D vector pixel dimensions
19  * \param magFilter OpenGL magnification filter enum
20  * \param minFilter OpenGL minification filter enum
21  * \param wrap OpenGL texture wrapping enum
22  * \param borderColor
23  * \param target OpenGL texture target enum GL_TEXTURE_2D or GL_TEXTURE_CUBE_MAP
24  * \param name Name of the depth buffer
25  */
27  SLenum magFilter,
28  SLenum minFilter,
29  SLint wrap,
30  SLfloat borderColor[],
31  SLenum target,
32  SLstring name)
33  : SLObject(name),
34  _dimensions(dimensions),
35  _target(target)
36 {
38 
39  assert(target == GL_TEXTURE_2D || target == GL_TEXTURE_CUBE_MAP);
40  SLGLState* stateGL = SLGLState::instance();
41 
42  // Init framebuffer.
43  glGenFramebuffers(1, &_fboID);
45 
46  bind();
47 
48  glGenTextures(1, &_texID);
49  stateGL->bindTexture(target, _texID);
51 
52  // Texture parameters.
53  glTexParameteri(target, GL_TEXTURE_MIN_FILTER, minFilter);
54  glTexParameteri(target, GL_TEXTURE_MAG_FILTER, magFilter);
55  glTexParameteri(target, GL_TEXTURE_WRAP_S, wrap);
56  glTexParameteri(target, GL_TEXTURE_WRAP_T, wrap);
57 
58 #ifndef SL_GLES
59  if (borderColor != nullptr)
60  glTexParameterfv(target, GL_TEXTURE_BORDER_COLOR, borderColor);
61 #endif
62 
64 
65  if (target == GL_TEXTURE_2D)
66  {
67  glTexImage2D(GL_TEXTURE_2D,
68  0,
69  GL_DEPTH_COMPONENT32F,
70  _dimensions.x,
71  _dimensions.y,
72  0,
73  GL_DEPTH_COMPONENT,
74  GL_FLOAT,
75  nullptr);
77 
78  // Attach texture to framebuffer.
79  glFramebufferTexture2D(GL_FRAMEBUFFER,
80  GL_DEPTH_ATTACHMENT,
81  GL_TEXTURE_2D,
82  _texID,
83  0);
85  }
86  else // target is GL_TEXTURE_CUBE_MAP
87  {
88  for (SLint i = 0; i < 6; ++i)
89  {
90  glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i,
91  0,
92  GL_DEPTH_COMPONENT32F,
93  _dimensions.x,
94  _dimensions.y,
95  0,
96  GL_DEPTH_COMPONENT,
97  GL_FLOAT,
98  nullptr);
100 
101  // Attach texture to framebuffer.
102  glFramebufferTexture2D(GL_FRAMEBUFFER,
103  GL_DEPTH_ATTACHMENT,
104  GL_TEXTURE_CUBE_MAP_POSITIVE_X + i,
105  _texID,
106  0);
107  GET_GL_ERROR;
108  }
109  }
110 
111 #ifndef SL_GLES
112  glDrawBuffer(GL_NONE);
113  GET_GL_ERROR;
114 #endif
115 
116  glReadBuffer(GL_NONE);
117  GET_GL_ERROR;
118 
119  unbind();
120 
121  if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
122  SL_LOG("FBO failed to initialize correctly.");
123  GET_GL_ERROR;
124 }
125 
126 //-----------------------------------------------------------------------------
128 {
129  glDeleteTextures(1, &_texID);
130  GET_GL_ERROR;
131 
132  glDeleteFramebuffers(1, &_fboID);
133  GET_GL_ERROR;
134 }
135 //-----------------------------------------------------------------------------
136 //! Sets the active texture unit within the shader and binds the texture
137 /*!
138  The uniform location loc must be requested before with glUniformLocation.
139  The texture unit value must correspond to the number that is set with
140  glUniform1i(loc, texUnit).
141  @param texUnit Texture Unit value
142  */
144 {
145 
146  SLGLState* stateGL = SLGLState::instance();
147  stateGL->activeTexture(GL_TEXTURE0 + texUnit);
148  stateGL->bindTexture(_target, _texID);
149 }
150 
151 //-----------------------------------------------------------------------------
153 {
154  SLfloat* depth = new SLfloat[_dimensions.y * _dimensions.x];
155  glReadPixels(0,
156  0,
157  _dimensions.x,
158  _dimensions.y,
159  GL_DEPTH_COMPONENT,
160  GL_FLOAT,
161  depth);
162  GET_GL_ERROR;
163  return depth;
164 }
165 
166 //-----------------------------------------------------------------------------
167 //! Binds the OpenGL frame buffer object for the depth buffer
169 {
170  // Keep the previous FB ID for later unbinding
171  glGetIntegerv(GL_FRAMEBUFFER_BINDING, &_prevFboID);
172  glBindFramebuffer(GL_FRAMEBUFFER, _fboID);
173  GET_GL_ERROR;
174 }
175 
176 //-----------------------------------------------------------------------------
177 //! Ends the usage of the depth buffer frame buffer
179 {
180  // iOS does not allow binding to 0. That's why we keep the previous FB ID
181  glBindFramebuffer(GL_FRAMEBUFFER, _prevFboID);
182  GET_GL_ERROR;
183 }
184 
185 //-----------------------------------------------------------------------------
186 //! Binds a specific texture face of a cube map depth buffer
188 {
189  assert(_target == GL_TEXTURE_CUBE_MAP);
190  assert(face >= GL_TEXTURE_CUBE_MAP_POSITIVE_X &&
191  face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z);
192 
193  glFramebufferTexture2D(GL_FRAMEBUFFER,
194  GL_DEPTH_ATTACHMENT,
195  face,
196  _texID,
197  0);
198  GET_GL_ERROR;
199 }
200 //-----------------------------------------------------------------------------
#define PROFILE_FUNCTION()
Definition: Instrumentor.h:41
float SLfloat
Definition: SL.h:173
unsigned int SLenum
Definition: SL.h:176
#define SL_LOG(...)
Definition: SL.h:233
unsigned int SLuint
Definition: SL.h:171
string SLstring
Definition: SL.h:158
int SLint
Definition: SL.h:170
Uses an OpenGL framebuffer object as a depth-buffer.
Singleton class for global render state.
#define GET_GL_ERROR
Definition: SLGLState.h:56
void bindActive(SLuint texUnit) const
Sets the active texture unit within the shader and binds the texture.
void bindFace(SLenum face) const
Binds a specific texture face of a cube map depth buffer.
SLuint _fboID
ID of the FB object.
SLint _prevFboID
ID of the previously bound FB.
SLenum _target
GL_TEXTURE_2D or GL_TEXTURE_CUBE_MAP.
SLVec2i _dimensions
Size of the texture.
void bind()
Binds the OpenGL frame buffer object for the depth buffer.
SLuint _texID
ID of the texture.
void unbind()
Ends the usage of the depth buffer frame buffer.
SLfloat * readPixels() const
SLGLDepthBuffer(const SLVec2i &dimensions, SLenum magFilter=GL_NEAREST, SLenum minFilter=GL_NEAREST, SLint wrap=GL_REPEAT, SLfloat borderColor[]=nullptr, SLenum target=GL_TEXTURE_2D, SLstring name="SM-DepthBuffer")
Singleton class holding all OpenGL states.
Definition: SLGLState.h:71
void activeTexture(SLenum textureUnit)
Definition: SLGLState.cpp:445
static SLGLState * instance()
Public static instance getter for singleton pattern.
Definition: SLGLState.h:74
void bindTexture(SLenum target, SLuint textureID)
Definition: SLGLState.cpp:423
Base class for all other classes.
Definition: SLObject.h:23
T y
Definition: SLVec2.h:30
T x
Definition: SLVec2.h:30