JeVois  1.20
JeVois Smart Embedded Machine Vision Toolkit
Share this page:
GPUimage.C
Go to the documentation of this file.
1 // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2 //
3 // JeVois Smart Embedded Machine Vision Toolkit - Copyright (C) 2020 by Laurent Itti, the University of Southern
4 // California (USC), and iLab at USC. See http://iLab.usc.edu and http://jevois.org for information about this project.
5 //
6 // This file is part of the JeVois Smart Embedded Machine Vision Toolkit. This program is free software; you can
7 // redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software
8 // Foundation, version 2. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
9 // without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
10 // License for more details. You should have received a copy of the GNU General Public License along with this program;
11 // if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
12 //
13 // Contact information: Laurent Itti - 3641 Watt Way, HNB-07A - Los Angeles, CA 90089-2520 - USA.
14 // Tel: +1 213 740 3527 - itti@pollux.usc.edu - http://iLab.usc.edu - http://jevois.org
15 // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
16 /*! \file */
17 
18 #ifdef JEVOIS_PRO
19 
20 #include <jevois/GPU/GPUimage.H>
21 
22 #include <jevois/Util/Utils.H>
23 #include <jevois/GPU/GPUtexture.H>
25 #include <jevois/GPU/GPUprogram.H>
26 #include <glm/glm.hpp>
27 #include <glm/gtc/type_ptr.hpp>
28 
29 // ##############################################################################################################
30 // Shaders used here:
31 namespace jevois
32 {
33  namespace shader
34  {
35  extern char const * vert; // Vertex shader
36  extern char const * frag_rgba; // To display an RGBA image
37  extern char const * frag_rgb; // To display an RGB image
38  extern char const * frag_grey; // To display a greyscale image
39  extern char const * frag_yuyv; // To display a YUYV image
40  extern char const * frag_oes; // To display a DMABUF camera image
41  extern char const * frag_rgba_twirl; // To display an RGBA image with a twirl effect
42  extern char const * frag_rgb_twirl; // To display an RGB image with a twirl effect
43  extern char const * frag_grey_twirl; // To display a greyscale image with a twirl effect
44  extern char const * frag_yuyv_twirl; // To display a YUYV image with a twirl effect
45  extern char const * frag_oes_twirl; // To display a DMABUF camera image with a twirl effect
46  }
47 }
48 
49 // ##############################################################################################################
51 { }
52 
53 // ##############################################################################################################
55 {
56  if (itsVertexArray) glDeleteVertexArrays(1, &itsVertexArray);
57  if (itsVertexBuffers[0]) glDeleteBuffers(2, itsVertexBuffers);
58 }
59 
60 // ##############################################################################################################
61 void jevois::GPUimage::setInternal(unsigned int width, unsigned int height, unsigned int fmt,
62  unsigned char const * data)
63 {
64  if (width == 0 || height == 0) LFATAL("Cannot handle zero image width or height");
65 
66  // If image format has changed, load the appropriate program:
67  if (fmt != itsFormat)
68  {
69  char const * frag_shader;
70  switch (fmt)
71  {
72  case V4L2_PIX_FMT_YUYV: // YUYV shader gets YUYV (2 pixels) from one RGBA texture value (1 texel)
73  if (itsTwirl) frag_shader = jevois::shader::frag_yuyv_twirl;
74  else frag_shader = jevois::shader::frag_yuyv;
75  itsGLtextureWidth = width / 2; itsGLtextureFmt = GL_RGBA;
76  break;
77 
78  case V4L2_PIX_FMT_RGB32: // RGBA shader is simple pass-through
79  if (itsTwirl) frag_shader = jevois::shader::frag_rgba_twirl;
80  else frag_shader = jevois::shader::frag_rgba;
81  itsGLtextureWidth = width; itsGLtextureFmt = GL_RGBA;
82  break;
83 
84  case V4L2_PIX_FMT_GREY: // GRAY shader just converts from greyscale to RGBA
85  if (itsTwirl) frag_shader = jevois::shader::frag_grey_twirl;
86  else frag_shader = jevois::shader::frag_grey;
87  itsGLtextureWidth = width; itsGLtextureFmt = GL_LUMINANCE;
88  break;
89 
90  case V4L2_PIX_FMT_RGB24: // RGB shader gets R,G,B from 3 successive texels in a 3x wide luminance texture
91  if (itsTwirl) frag_shader = jevois::shader::frag_rgb_twirl;
92  else frag_shader = jevois::shader::frag_rgb;
93  itsGLtextureWidth = width * 3; itsGLtextureFmt = GL_LUMINANCE;
94  break;
95 
96  case V4L2_PIX_FMT_BGR24:
97  case V4L2_PIX_FMT_SRGGB8:
98  case V4L2_PIX_FMT_RGB565:
99  case V4L2_PIX_FMT_MJPEG:
100  case V4L2_PIX_FMT_UYVY:
101  case V4L2_PIX_FMT_SBGGR16:
102  case V4L2_PIX_FMT_SGRBG16:
103  case V4L2_PIX_FMT_NV12:
104  case V4L2_PIX_FMT_YUV444:
105  case 0:
106  default: LFATAL("Unsupported pixel format " << jevois::fccstr(fmt));
107  }
108 
109  // Load the appropriate program:
110  itsProgram.reset(new GPUprogram(jevois::shader::vert, frag_shader));
111 
112  // Get a handle to s_texture variable in the fragment shader, to update the texture with each new camera frame:
113  itsLocation = glGetUniformLocation(itsProgram->id(), "s_texture");
114  }
115 
116  // Generate a texture for incoming image data if needed:
117  if (width != itsTextureWidth || height != itsTextureHeight || fmt != itsFormat || !itsTexture)
118  {
119  // Now create our texture:
120  itsTexture.reset(new jevois::GPUtexture(itsGLtextureWidth, height, itsGLtextureFmt, false));
121  LDEBUG("Input texture for " << width << 'x' << height << ' ' << jevois::fccstr(fmt) << " ready.");
122  }
123 
124 #ifdef JEVOIS_PLATFORM_PRO
125  if (itsTextureDmaBuf) itsTextureDmaBuf.reset(); // invalidate any previously used dmabuf texture
126 #endif
127 
128  // Assign pixel data to our texture:
129  itsTexture->setPixels(data);
130 
131  // Remember our latest size and format:
132  itsTextureWidth = width; itsTextureHeight = height; itsFormat = fmt;
133 }
134 
135 // ##############################################################################################################
137 {
138  setInternal(img.width, img.height, img.fmt, static_cast<unsigned char const *>(img.buf->data()));
139 }
140 
141 // ##############################################################################################################
142 void jevois::GPUimage::set(cv::Mat const & img, bool rgb)
143 {
144  unsigned int fmt;
145 
146  switch(img.type())
147  {
148  case CV_8UC4: if (rgb) fmt = V4L2_PIX_FMT_RGB32; else fmt = V4L2_PIX_FMT_BGR32; break;
149  case CV_8UC3: if (rgb) fmt = V4L2_PIX_FMT_RGB24; else fmt = V4L2_PIX_FMT_BGR24; break;
150  case CV_8UC2: fmt = V4L2_PIX_FMT_YUYV; break;
151  case CV_8UC1: fmt = V4L2_PIX_FMT_GREY; break;
152  default: LFATAL("Unsupported OpenCV image format: " << img.type());
153  }
154 
155  setInternal(img.cols, img.rows, fmt, img.data);
156 }
157 
158 #ifdef JEVOIS_PLATFORM_PRO
159 // ##############################################################################################################
160 void jevois::GPUimage::set(jevois::InputFrame const & frame, EGLDisplay display)
161 {
162  jevois::RawImage const img = frame.get();
163  int const dmafd = img.buf->dmaFd();
164 
165  // EGLimageKHR which we use with DMAbuf requires width to be a multiple of 32; otherwise revert to normal texture:
166  if ((img.width % 32) || dmafd < 0) { set(img); return; }
167 
168  // DMAbuf only supports some formats, otherwise revert to normal texture. Keep in sync with GPUtextureDmaBuf:
169  switch (img.fmt)
170  {
171  case V4L2_PIX_FMT_YUYV:
172  case V4L2_PIX_FMT_RGB32:
173  case V4L2_PIX_FMT_RGB565:
174  case V4L2_PIX_FMT_BGR24:
175  case V4L2_PIX_FMT_RGB24:
176  case V4L2_PIX_FMT_UYVY:
177  setWithDmaBuf(img, dmafd, display);
178  break;
179 
180  default:
181  set(img);
182  }
183 }
184 
185 // ##############################################################################################################
186 void jevois::GPUimage::set2(jevois::InputFrame const & frame, EGLDisplay display)
187 {
188  jevois::RawImage const img = frame.get2();
189  int const dmafd = img.buf->dmaFd();
190 
191  // EGLimageKHR which we use with DMAbuf requires width to be a multiple of 32; otherwise revert to normal texture:
192  if ((img.width % 32) || dmafd < 0) { set(img); return; }
193 
194  // DMAbuf only supports some formats, otherwise revert to normal texture. Keep in sync with GPUtextureDmaBuf:
195  switch (img.fmt)
196  {
197  case V4L2_PIX_FMT_YUYV:
198  case V4L2_PIX_FMT_RGB32:
199  case V4L2_PIX_FMT_RGB565:
200  case V4L2_PIX_FMT_BGR24:
201  case V4L2_PIX_FMT_RGB24:
202  case V4L2_PIX_FMT_UYVY:
203  setWithDmaBuf(img, dmafd, display);
204  break;
205 
206  default:
207  set(img);
208  }
209 }
210 
211 // ##############################################################################################################
212 void jevois::GPUimage::setWithDmaBuf(jevois::RawImage const & img, int dmafd, EGLDisplay display)
213 {
214  if (img.width == 0 || img.height == 0) LFATAL("Cannot handle zero image width or height");
215 
216  // Generate a dmabuf texture for incoming image data if needed:
217  if (img.width != itsTextureWidth || img.height != itsTextureHeight || img.fmt != itsFormat ||
218  itsTexture || !itsTextureDmaBuf)
219  {
220  itsTextureDmaBuf.reset(new jevois::GPUtextureDmaBuf(display, img.width, img.height, img.fmt, dmafd));
221  itsTexture.reset(); // invalidate any previously used regular texture
222  LDEBUG("Input DMABUF texture for " << img.width <<'x'<< img.height << ' ' << jevois::fccstr(img.fmt) << " ready.");
223 
224  // Remember our latest size:
225  itsTextureWidth = img.width; itsTextureHeight = img.height;
226 
227  // Load the appropriate program:
228  if (itsTwirl) itsProgram.reset(new GPUprogram(jevois::shader::vert, jevois::shader::frag_oes_twirl));
229  else itsProgram.reset(new GPUprogram(jevois::shader::vert, jevois::shader::frag_oes));
230 
231  // Get a handle to s_texture variable in the fragment shader, to update the texture with each new camera frame:
232  itsLocation = glGetUniformLocation(itsProgram->id(), "s_texture");
233 
234  // Remember our latest format:
235  itsFormat = img.fmt;
236  }
237 
238  // All done. No need to assign pixel data, it will be DMA'd over.
239 }
240 
241 #else // JEVOIS_PLATFORM_PRO
242 
243 // ##############################################################################################################
244 void jevois::GPUimage::set(jevois::InputFrame const & frame, EGLDisplay JEVOIS_UNUSED_PARAM(display))
245 {
246  // DMABUF acceleration not supported:
247  jevois::RawImage const img = frame.get();
248  set(img);
249 }
250 
251 // ##############################################################################################################
252 void jevois::GPUimage::set2(jevois::InputFrame const & frame, EGLDisplay JEVOIS_UNUSED_PARAM(display))
253 {
254  // DMABUF acceleration not supported:
255  jevois::RawImage const img = frame.get2();
256  set(img);
257 }
258 
259 #endif // JEVOIS_PLATFORM_PRO
260 
261 // ##############################################################################################################
262 void jevois::GPUimage::draw(int & x, int & y, unsigned short & w, unsigned short & h, bool noalias,
263  glm::mat4 const & pvm)
264 {
265  if (itsTextureWidth == 0) throw std::runtime_error("You must call set() before draw()");
266 
267  // Enable blending, used for RGBA textures that have transparency:
268  glEnable(GL_BLEND);
269  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
270 
271  // Get the current viewport size:
272  GLint viewport[4];
273  glGetIntegerv(GL_VIEWPORT, viewport);
274 
275  if (w == 0 || h == 0)
276  {
277  // Letterbox the image into the window to occupy as much space as possible without changing aspect ratio:
278  unsigned int winw = viewport[2], winh = viewport[3];
279  itsDrawWidth = itsTextureWidth; itsDrawHeight = itsTextureHeight;
280  jevois::applyLetterBox(itsDrawWidth, itsDrawHeight, winw, winh, noalias);
281  x = (winw - itsDrawWidth) / 2; y = (winh - itsDrawHeight) / 2; w = itsDrawWidth; h = itsDrawHeight;
282  }
283 
284  // Flip the ordinate. Our OpenGL texture rendering uses 0,0 at the bottom-left corner, with increasing y going up on
285  // the screen. But machine vision (and our users) assumes 0,0 at top left of the screen with increasing y going down:
286  int const yy = viewport[3] - y - h;
287 
288  // Allocate/update vertex arrays if needed (including on first frame):
289  if (itsDrawX != x || itsDrawY != y || itsDrawWidth != w || itsDrawHeight != h)
290  {
291  // Compute vertex coordinates: We here assume that the projection matrix is such that at the pixel perfect plane,
292  // our vertex x,y coordinates match their pixel counterparts, except that image center is at 0,0. The view matrix is
293  // responsible for translating our z from 0 here to the pixel pixel perfect plane:
294  float const tx = x - 0.5 * viewport[2];
295  float const ty = yy - 0.5 * viewport[3];
296  float const bx = tx + w;
297  float const by = ty + h;
298 
299  // Create a new vertex array. A group of vertices and indices stored in GPU memory. The frame being drawn is static
300  // for the program duration, upload all the information to the GPU at the beginning then reference the location each
301  // frame without copying the data each frame.
302  GLfloat const vertices[] = { tx, by, 0.0f, 0.0f, 0.0f,
303  tx, ty, 0.0f, 0.0f, 1.0f,
304  bx, ty, 0.0f, 1.0f, 1.0f,
305  bx, by, 0.0f, 1.0f, 0.0f };
306  static GLushort const indices[] = { 0, 1, 2, 0, 2, 3 };
307 
308  if (itsVertexArray) { glDeleteVertexArrays(1, &itsVertexArray); glDeleteBuffers(2, itsVertexBuffers); }
309  glGenVertexArrays(1, &itsVertexArray);
310 
311  // Select the vertex array that was just created and bind the new vertex buffers to the array:
312  glBindVertexArray(itsVertexArray);
313 
314  // Generate vertex buffers in GPU memory. First buffer is for vertex data, second for index data:
315  if (itsVertexBuffers[0]) glDeleteBuffers(2, itsVertexBuffers);
316  glGenBuffers(2, itsVertexBuffers);
317 
318  // Bind the first vertex buffer with the vertices to the vertex array:
319  glBindBuffer(GL_ARRAY_BUFFER, itsVertexBuffers[0]);
320  glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
321 
322  // Bind the second vertex buffer with the indices to the vertex array:
323  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, itsVertexBuffers[1]);
324  glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
325 
326  // Enable a_position (location 0) and a_tex_coord (location 1) in the vertex shader:
327  glEnableVertexAttribArray(0);
328  glEnableVertexAttribArray(1);
329 
330  // Copy the vertices to the GPU to be used in a_position:
331  GL_CHECK(glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), 0));
332 
333  // Copy the texture co-ordinates to the GPU to be used in a_tex_coord:
334  GL_CHECK(glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (void const *)(3 * sizeof(GLfloat))));
335 
336  // Select the default vertex array, allowing the application's array to be unbound:
337  glBindVertexArray(0);
338 
339  // Remember our latest draw location and size:
340  itsDrawX = x; itsDrawY = y; itsDrawWidth = w; itsDrawHeight = h;
341  }
342 
343  if (!itsProgram) throw std::runtime_error("You must call set() before draw()");
344 
345  // Tell OpenGL to use our program:
346  glUseProgram(itsProgram->id());
347 
348  // Select the vertex array which includes the vertices and indices describing the window rectangle:
349  glBindVertexArray(itsVertexArray);
350 
351  // Bind our texture, regular or DMABUF:
352  GL_CHECK(glActiveTexture(GL_TEXTURE0));
353  if (itsTexture)
354  GL_CHECK(glBindTexture(GL_TEXTURE_2D, itsTexture->Id));
355 #ifdef JEVOIS_PLATFORM_PRO
356  else if (itsTextureDmaBuf)
357  GL_CHECK(glBindTexture(GL_TEXTURE_EXTERNAL_OES, itsTextureDmaBuf->Id));
358 #endif
359  else throw std::runtime_error("You must call set() before draw()");
360 
361  // Indicate that GL_TEXTURE0 is s_texture from previous lookup:
362  glUniform1i(itsLocation, 0);
363 
364  // Let the fragment shader know the true (unscaled by bpp) image width and height. Also set the PVM matrix. Ignore any
365  // errors as some shaders may not have these variables:
366  glUniform2f(glGetUniformLocation(itsProgram->id(), "tdim"), GLfloat(itsTextureWidth), GLfloat(itsTextureHeight));
367  glUniformMatrix4fv(glGetUniformLocation(itsProgram->id(), "pvm"), 1, GL_FALSE, glm::value_ptr(pvm));
368 
369  if (itsTwirl)
370  {
371  glUniform1f(glGetUniformLocation(itsProgram->id(), "twirlamount"), itsTwirl);
372  glUniform1f(glGetUniformLocation(itsProgram->id(), "alpha"), itsAlpha);
373  }
374 
375  // Draw the two triangles from 6 indices to form a rectangle from the data in the vertex array.
376  // The fourth parameter, indices value here is passed as null since the values are already
377  // available in the GPU memory through the vertex array
378  // GL_TRIANGLES - draw each set of three vertices as an individual triangle.
379  glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0);
380 
381  // Select the default vertex array, allowing the application array to be unbound:
382  glBindVertexArray(0);
383 }
384 
385 // ##############################################################################################################
386 ImVec2 jevois::GPUimage::i2d(ImVec2 const & p)
387 {
388  if (itsDrawWidth == 0) throw std::runtime_error("Need to call set() then draw() first");
389  return ImVec2(itsDrawX + p.x * itsDrawWidth / itsTextureWidth, itsDrawY + p.y * itsDrawHeight / itsTextureHeight);
390 }
391 
392 // ##############################################################################################################
393 ImVec2 jevois::GPUimage::i2ds(ImVec2 const & p)
394 {
395  if (itsDrawWidth == 0) throw std::runtime_error("Need to call set() then draw() first");
396  return ImVec2(p.x * itsDrawWidth / itsTextureWidth, p.y * itsDrawHeight / itsTextureHeight);
397 }
398 
399 // ##############################################################################################################
400 ImVec2 jevois::GPUimage::d2i(ImVec2 const & p)
401 {
402  if (itsDrawWidth == 0) throw std::runtime_error("Need to call set() then draw() first");
403  return ImVec2((p.x - itsDrawX) * itsTextureWidth / itsDrawWidth, (p.y - itsDrawY) * itsTextureHeight / itsDrawHeight);
404 }
405 
406 // ##############################################################################################################
407 ImVec2 jevois::GPUimage::d2is(ImVec2 const & p)
408 {
409  if (itsDrawWidth == 0) throw std::runtime_error("Need to call set() then draw() first");
410  return ImVec2(p.x * itsTextureWidth / itsDrawWidth, p.y * itsTextureHeight / itsDrawHeight);
411 }
412 
413 // ##############################################################################################################
414 void jevois::GPUimage::twirl(float t, float alpha)
415 {
416  // If we are not already twirling, or we want to stop twirling, force a reload of the shader program:
417  if (itsTwirl == 0.0F || t == 0.0F) itsFormat = 0;
418 
419  // Remember the new twirl amount:
420  itsTwirl = t;
421  itsAlpha = alpha;
422 }
423 
424 #endif // JEVOIS_PRO
jevois::GPUtexture
Simple class to hold an OpenGL texture.
Definition: GPUtexture.H:28
jevois::shader::frag_grey
const char * frag_grey
jevois::shader::frag_rgb_twirl
const char * frag_rgb_twirl
GPUprogram.H
GPUimage.H
LDEBUG
#define LDEBUG(msg)
Convenience macro for users to print out console or syslog messages, DEBUG level.
Definition: Log.H:173
GPUtextureDmaBuf.H
jevois::shader::frag_rgba_twirl
const char * frag_rgba_twirl
jevois::GPUimage::~GPUimage
~GPUimage()
Destructor.
Definition: GPUimage.C:54
jevois::shader::frag_rgba
const char * frag_rgba
jevois::GPUimage::setWithDmaBuf
void setWithDmaBuf(jevois::RawImage const &img, int dmafd, EGLDisplay display)
Definition: GPUimage.C:212
jevois::shader::frag_rgb
const char * frag_rgb
jevois::shader::frag_oes_twirl
const char * frag_oes_twirl
jevois::RawImage
A raw image as coming from a V4L2 Camera and/or being sent out to a USB Gadget.
Definition: RawImage.H:110
jevois::GPUprogram
Simple class to load and compile some OpenGL-ES program.
Definition: GPUprogram.H:25
GPUtexture.H
GL_CHECK
#define GL_CHECK(stmt)
Simple macro to check for OpenGL errors.
Definition: OpenGL.H:77
jevois::InputFrame::get
const RawImage & get(bool casync=false) const
Get the next captured camera image.
Definition: InputFrame.C:50
jevois::RawImage::width
unsigned int width
Image width in pixels.
Definition: RawImage.H:145
jevois::shader::vert
const char * vert
jevois::shader::frag_grey_twirl
const char * frag_grey_twirl
jevois
Definition: Concepts.dox:1
F
float F
Definition: GUIhelper.C:2373
jevois::shader::frag_yuyv_twirl
const char * frag_yuyv_twirl
jevois::GPUimage::twirl
void twirl(float t, float alpha=1.0F)
Optional twirl and alpha fading effect to the image, useful mostly for demos/transitions.
Definition: GPUimage.C:414
jevois::GPUimage::GPUimage
GPUimage()
Constructor.
Definition: GPUimage.C:50
jevois::GPUimage::draw
void draw(int &x, int &y, unsigned short &w, unsigned short &h, bool noalias, glm::mat4 const &pvm)
Draw to OpenGL.
Definition: GPUimage.C:262
jevois::fccstr
std::string fccstr(unsigned int fcc)
Convert a V4L2 four-cc code (V4L2_PIX_FMT_...) to a 4-char string.
Definition: Utils.C:45
jevois::GPUimage::i2ds
ImVec2 i2ds(ImVec2 const &p)
Convert a 2D size from within a rendered image to on-screen.
Definition: GPUimage.C:393
jevois::InputFrame::get2
const RawImage & get2(bool casync=false) const
Get the next captured camera image, ISP-scaled second frame.
Definition: InputFrame.C:67
jevois::applyLetterBox
void applyLetterBox(unsigned int &imw, unsigned int &imh, unsigned int const winw, unsigned int const winh, bool noalias)
Apply a letterbox resizing to fit an image into a window.
Definition: Utils.C:222
jevois::shader::frag_yuyv
const char * frag_yuyv
LFATAL
#define LFATAL(msg)
Convenience macro for users to print out console or syslog messages, FATAL level.
jevois::GPUtextureDmaBuf
Simple class to hold an OpenGL texture with in-GPU pixel format conversion and DMABUF acceleration.
Definition: GPUtextureDmaBuf.H:30
jevois::RawImage::height
unsigned int height
Image height in pixels.
Definition: RawImage.H:146
jevois::InputFrame
Exception-safe wrapper around a raw camera input frame.
Definition: InputFrame.H:50
jevois::GPUimage::setInternal
void setInternal(unsigned int width, unsigned int height, unsigned int fmt, unsigned char const *data)
Definition: GPUimage.C:61
jevois::RawImage::fmt
unsigned int fmt
Pixel format as a V4L2_PIX_FMT_XXX.
Definition: RawImage.H:147
Utils.H
jevois::GPUimage::i2d
ImVec2 i2d(ImVec2 const &p)
Convert coordinates of a point from within a rendered image to on-screen.
Definition: GPUimage.C:386
jevois::RawImage::buf
std::shared_ptr< VideoBuf > buf
The pixel data buffer.
Definition: RawImage.H:149
h
int h
Definition: GUIhelper.C:2373
jevois::GPUimage::set
void set(RawImage const &img)
Set pixel data from a vanilla RawImage, pixel data will be copied to texture.
Definition: GPUimage.C:136
jevois::shader::frag_oes
const char * frag_oes
jevois::GPUimage::d2i
ImVec2 d2i(ImVec2 const &p)
Convert coordinates of a point from on-screen to within a rendered image.
Definition: GPUimage.C:400
jevois::GPUimage::set2
void set2(InputFrame const &frame, EGLDisplay display)
Set pixel data from camera input second (scaled) frame, sharing data with camera kernel driver using ...
Definition: GPUimage.C:186
jevois::GPUimage::d2is
ImVec2 d2is(ImVec2 const &p)
Convert a 2D size from on-screen to within a rendered image.
Definition: GPUimage.C:407