SLProject  4.3.020
A platform independent 3D computer graphics framework for desktop OS, Android, iOS and online in web browsers
SENSGLTextureReader Class Reference

#include <SENSGLTextureReader.h>

Public Member Functions

 SENSGLTextureReader (unsigned int textureId, bool isGlTextureExternal, int targetWidth, int targetHeight)
 ATTENTION: make sure this constructor is called from gl thread. More...
 
 ~SENSGLTextureReader ()
 
cv::Mat readImageFromGpu ()
 
std::string getLastErrorMsg () const
 

Private Member Functions

void initGl ()
 

Static Private Member Functions

static void getGLError (const char *file, int line, bool quit)
 Checks if an OpenGL error occurred. More...
 

Private Attributes

std::string _lastErrorMsg
 
unsigned int _extTextureId
 id of externally generated texture More...
 
bool _isGlTextureExternal = false
 
int _targetWidth
 
int _targetHeight
 
unsigned int _fbo = 0
 
unsigned int _prog = 0
 
unsigned int _VBO = 0
 
unsigned int _VAO = 0
 
unsigned int _EBO = 0
 
unsigned int _targetTex = 0
 

Static Private Attributes

static std::vector< std::string > _errors
 vector for errors collected in getGLError More...
 

Detailed Description

Definition at line 8 of file SENSGLTextureReader.h.

Constructor & Destructor Documentation

◆ SENSGLTextureReader()

SENSGLTextureReader::SENSGLTextureReader ( unsigned int  textureId,
bool  isGlTextureExternal,
int  targetWidth,
int  targetHeight 
)

ATTENTION: make sure this constructor is called from gl thread.

Definition at line 109 of file SENSGLTextureReader.cpp.

110  : _extTextureId(textureId),
111  _isGlTextureExternal(isGlTextureExternal),
112  _targetWidth(targetWidth),
113  _targetHeight(targetHeight)
114 {
115  initGl();
116 }
unsigned int _extTextureId
id of externally generated texture

◆ ~SENSGLTextureReader()

SENSGLTextureReader::~SENSGLTextureReader ( )

Definition at line 118 of file SENSGLTextureReader.cpp.

119 {
120  glDeleteTextures(1, &_targetTex);
121  glDeleteFramebuffers(1, &_fbo);
122  glDeleteVertexArrays(1, &_VAO);
123  glDeleteBuffers(1, &_VBO);
124  glDeleteBuffers(1, &_EBO);
125  glDeleteProgram(_prog);
126 }

Member Function Documentation

◆ getGLError()

void SENSGLTextureReader::getGLError ( const char *  file,
int  line,
bool  quit 
)
staticprivate

Checks if an OpenGL error occurred.

Definition at line 309 of file SENSGLTextureReader.cpp.

312 {
313  GLenum err;
314  if ((err = glGetError()) != GL_NO_ERROR)
315  {
316  std::string errStr;
317  switch (err)
318  {
319  case GL_INVALID_ENUM:
320  errStr = "GL_INVALID_ENUM";
321  break;
322  case GL_INVALID_VALUE:
323  errStr = "GL_INVALID_VALUE";
324  break;
325  case GL_INVALID_OPERATION:
326  errStr = "GL_INVALID_OPERATION";
327  break;
328  case GL_INVALID_FRAMEBUFFER_OPERATION:
329  errStr = "GL_INVALID_FRAMEBUFFER_OPERATION";
330  break;
331  case GL_OUT_OF_MEMORY:
332  errStr = "GL_OUT_OF_MEMORY";
333  break;
334  default:
335  errStr = "Unknown error";
336  }
337 
338  // Build error string as a concatenation of file, line & error
339  char sLine[32];
340  snprintf(sLine, sizeof(sLine), "%d", line);
341 
342  std::string newErr(file);
343  newErr += ": line:";
344  newErr += sLine;
345  newErr += ": ";
346  newErr += errStr;
347 
348  // Check if error exists already
349  bool errExists = std::find(_errors.begin(),
350  _errors.end(),
351  newErr) != _errors.end();
352  // Only print
353  if (!errExists)
354  {
355  _errors.push_back(newErr);
356  Utils::log("SENSGLTextureReader", "OpenGL Error in %s, line %d: %s\n", file, line, errStr.c_str());
357  }
358 
359  if (quit)
360  exit(1);
361  }
362 }
static std::vector< std::string > _errors
vector for errors collected in getGLError
void log(const char *tag, const char *format,...)
logs a formatted string platform independently
Definition: Utils.cpp:1100

◆ getLastErrorMsg()

std::string SENSGLTextureReader::getLastErrorMsg ( ) const
inline

Definition at line 17 of file SENSGLTextureReader.h.

17 { return _lastErrorMsg; }

◆ initGl()

void SENSGLTextureReader::initGl ( )
private

Definition at line 128 of file SENSGLTextureReader.cpp.

129 {
130  //-----------------------------------------------------------------------------
131  //store old gl state
132  GLint lastFBO = -1;
133  glGetIntegerv(GL_FRAMEBUFFER_BINDING, &lastFBO);
134  GLint lastTex = -1;
135  glGetIntegerv(GL_TEXTURE_BINDING_2D, &lastTex);
136 
137  //-----------------------------------------------------------------------------
138  //setup shader program
139  static std::string vertexShSrc =
140  "#ifdef GL_ES\n"
141  " precision highp float;\n"
142  "#endif\n"
143  "\n"
144  "layout (location = 0) in vec2 aPos;\n"
145  "layout (location = 1) in vec2 aTexCoords;\n"
146  "\n"
147  "out vec2 TexCoords;\n"
148  "\n"
149  "void main()\n"
150  "{\n"
151  " gl_Position = vec4(aPos.x, aPos.y, 0.0, 1.0);\n"
152  " TexCoords = aTexCoords;\n"
153  "}\n";
154 
155  static std::string fragShSrc =
156  "#include extension\n"
157  "#ifdef GL_ES\n"
158  " precision highp float;\n"
159  "#endif\n"
160  "\n"
161  "out vec4 FragColor;\n"
162  "\n"
163  "in vec2 TexCoords;\n"
164  "\n"
165  "#include sampler texture0;\n"
166  "\n"
167  "void main()\n"
168  "{\n"
169  " //ATTENTION: order is changed to bgr\n"
170  " FragColor = texture(texture0, vec2(TexCoords.x, TexCoords.y)).bgra;\n"
171  "}\n";
172 
173  GLuint vertexSh = buildShaderFromSource(vertexShSrc, GL_VERTEX_SHADER, _isGlTextureExternal);
174  GLuint fragSh = buildShaderFromSource(fragShSrc, GL_FRAGMENT_SHADER, _isGlTextureExternal);
175  _prog = glCreateProgram();
176  glAttachShader(_prog, vertexSh);
177  glAttachShader(_prog, fragSh);
178  glLinkProgram(_prog);
179  glDeleteShader(vertexSh);
180  glDeleteShader(fragSh);
181  GET_GL_ERROR;
182 
183  // clang-format off
184  //-----------------------------------------------------------------------------
185  //setup vertex array
186  float vertices[] = {
187  // positions // texture coords
188  1.0f, 1.0f, 1.0f, 1.0f, // top right
189  1.0f, -1.0f, 1.0f, 0.0f, // bottom right
190  -1.0f, -1.0f, 0.0f, 0.0f, // bottom left
191  -1.0f, 1.0f, 0.0f, 1.0f // top left
192  };
193  //ATTENTION: BE SURE ORDER INDICATES A FRONT FACING NORMAL
194  unsigned int indices[] = {
195  0, 3, 1, // first triangle
196  1, 3, 2 // second triangle
197  };
198  // clang-format on
199 
200  glGenVertexArrays(1, &_VAO);
201  glGenBuffers(1, &_VBO);
202  glGenBuffers(1, &_EBO);
203 
204  glBindVertexArray(_VAO);
205 
206  glBindBuffer(GL_ARRAY_BUFFER, _VBO);
207  glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
208 
209  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _EBO);
210  glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
211 
212  // position attribute
213  glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)0);
214  glEnableVertexAttribArray(0);
215  // texture coord attribute
216  glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)(2 * sizeof(float)));
217  glEnableVertexAttribArray(1);
218 
219  glBindBuffer(GL_ARRAY_BUFFER, 0);
220  glBindVertexArray(0);
221 
222  glGenFramebuffers(1, &_fbo);
223  glBindFramebuffer(GL_FRAMEBUFFER, _fbo);
224  GET_GL_ERROR;
225 
226  //-----------------------------------------------------------------------------
227  //setup target texture
228  glGenTextures(1, &_targetTex);
229  glBindTexture(GL_TEXTURE_2D, _targetTex);
230  //TODO: GL_RGB??
231  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, _targetWidth, _targetHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
232 
233  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
234  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
235 
236  //bind fbo to target texture
237  glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, _targetTex, 0);
238  GET_GL_ERROR;
239 
240  //test fbo status
241  GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
242  if (status != GL_FRAMEBUFFER_COMPLETE)
243  Utils::log("SENSGLTextureReader", "failed to make complete framebuffer object %x", status);
244  GET_GL_ERROR;
245  //-----------------------------------------------------------------------------
246  //restore old gl state
247  glBindFramebuffer(GL_FRAMEBUFFER, lastFBO);
248  glBindTexture(GL_TEXTURE_2D, lastTex);
249 }
GLuint buildShaderFromSource(std::string source, GLenum shaderType, bool isGlExternalTexture)
#define GET_GL_ERROR

◆ readImageFromGpu()

cv::Mat SENSGLTextureReader::readImageFromGpu ( )

read gl texture from gpu. The transferred image will be filled. return false if it failed in this case one can retrieve the last error

Definition at line 251 of file SENSGLTextureReader.cpp.

252 {
253  //-----------------------------------------------------------------------------
254  //store old gl state
255  GLint lastFBO = -1;
256  glGetIntegerv(GL_FRAMEBUFFER_BINDING, &lastFBO);
257  GLint lastTex = -1;
258  glGetIntegerv(GL_TEXTURE_BINDING_2D, &lastTex);
259  //depth test
260  GLboolean lastDepthTestV;
261  glGetBooleanv(GL_DEPTH_TEST, &lastDepthTestV);
262  //stencil test
263  GLboolean lastStencilTestV;
264  glGetBooleanv(GL_STENCIL_TEST, &lastStencilTestV);
265  //viewport
266  GLint lastViewport[4];
267  glGetIntegerv(GL_VIEWPORT, lastViewport);
268 
269  //-----------------------------------------------------------------------------
270  glBindFramebuffer(GL_FRAMEBUFFER, _fbo);
271  glViewport(0, 0, _targetWidth, _targetHeight);
272 
273  glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
274  glClear(GL_COLOR_BUFFER_BIT);
275  if (lastDepthTestV)
276  glDisable(GL_DEPTH_TEST);
277  if (lastStencilTestV)
278  glDisable(GL_STENCIL_TEST);
279 
280  glBindTexture(GL_TEXTURE_2D, _extTextureId);
281 
282  glUseProgram(_prog);
283  glBindVertexArray(_VAO);
284  glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
285 
286  //read pixels from framebuffer
287  cv::Mat image = cv::Mat(_targetHeight, _targetWidth, CV_8UC4);
288  glReadPixels(0, 0, _targetWidth, _targetHeight, GL_RGBA, GL_UNSIGNED_BYTE, image.data);
289 
290  //-------------------------------------------------------------------
291  //restore old gl state
292  glUseProgram(0);
293  glBindFramebuffer(GL_FRAMEBUFFER, lastFBO);
294  glBindTexture(GL_TEXTURE_2D, lastTex);
295  glViewport(lastViewport[0], lastViewport[1], lastViewport[2], lastViewport[3]);
296  if (lastDepthTestV)
297  glEnable(GL_DEPTH_TEST);
298  if (lastStencilTestV)
299  glEnable(GL_STENCIL_TEST);
300  GET_GL_ERROR;
301 
302  if (image.data)
303  return image;
304  else
305  return cv::Mat();
306 }

Member Data Documentation

◆ _EBO

unsigned int SENSGLTextureReader::_EBO = 0
private

Definition at line 35 of file SENSGLTextureReader.h.

◆ _errors

std::vector< std::string > SENSGLTextureReader::_errors
staticprivate

vector for errors collected in getGLError

Definition at line 39 of file SENSGLTextureReader.h.

◆ _extTextureId

unsigned int SENSGLTextureReader::_extTextureId
private

id of externally generated texture

Definition at line 26 of file SENSGLTextureReader.h.

◆ _fbo

unsigned int SENSGLTextureReader::_fbo = 0
private

Definition at line 31 of file SENSGLTextureReader.h.

◆ _isGlTextureExternal

bool SENSGLTextureReader::_isGlTextureExternal = false
private

Definition at line 27 of file SENSGLTextureReader.h.

◆ _lastErrorMsg

std::string SENSGLTextureReader::_lastErrorMsg
private

Definition at line 24 of file SENSGLTextureReader.h.

◆ _prog

unsigned int SENSGLTextureReader::_prog = 0
private

Definition at line 32 of file SENSGLTextureReader.h.

◆ _targetHeight

int SENSGLTextureReader::_targetHeight
private

Definition at line 29 of file SENSGLTextureReader.h.

◆ _targetTex

unsigned int SENSGLTextureReader::_targetTex = 0
private

Definition at line 36 of file SENSGLTextureReader.h.

◆ _targetWidth

int SENSGLTextureReader::_targetWidth
private

Definition at line 28 of file SENSGLTextureReader.h.

◆ _VAO

unsigned int SENSGLTextureReader::_VAO = 0
private

Definition at line 34 of file SENSGLTextureReader.h.

◆ _VBO

unsigned int SENSGLTextureReader::_VBO = 0
private

Definition at line 33 of file SENSGLTextureReader.h.


The documentation for this class was generated from the following files: