gmsh-TingyuanDoc  0.1
An Open-Source Timing-driven Analytical Mixed-size FPGA Placer
PixelBuffer.h
Go to the documentation of this file.
1 // Gmsh - Copyright (C) 1997-2022 C. Geuzaine, J.-F. Remacle
2 //
3 // See the LICENSE.txt file in the Gmsh root directory for license information.
4 // Please report all issues on https://gitlab.onelab.info/gmsh/gmsh/issues.
5 
6 #ifndef PIXEL_BUFFER_H
7 #define PIXEL_BUFFER_H
8 
9 #include <string.h>
10 #include "GmshConfig.h"
11 #include "GmshMessage.h"
12 #include "drawContext.h"
13 
14 #if defined(WIN32)
15 #include <windows.h>
16 #undef min
17 #undef max
18 #endif
19 
20 #if defined(__APPLE__)
21 #include <OpenGL/gl.h>
22 #include <OpenGL/glu.h>
23 #else
24 #include <GL/gl.h>
25 #include <GL/glu.h>
26 #endif
27 
28 #if defined(HAVE_OSMESA)
29 #include <GL/osmesa.h>
30 #endif
31 
32 class PixelBuffer {
33 private:
35  GLenum _format, _type;
36  unsigned char *_pixels;
37 
38 public:
39  PixelBuffer(int width, int height, GLenum format, GLenum type)
40  : _width(width), _height(height), _format(format), _type(type)
41  {
42  if(format == GL_RGB) {
43  _numComp = 3;
44  }
45  else if(format == GL_RGBA) {
46  _numComp = 4;
47  }
48  else {
49  Msg::Error("Unknown pixel format: assuming RGB");
50  _format = GL_RGB;
51  _numComp = 3;
52  }
53 
54  if(type == GL_UNSIGNED_BYTE) {
55  _dataSize = sizeof(unsigned char);
56  }
57  else if(type == GL_FLOAT) {
58  _dataSize = sizeof(float);
59  }
60  else {
61  Msg::Error("Unknown pixel storage type: assuming unsigned byte");
62  _type = GL_UNSIGNED_BYTE;
63  _dataSize = sizeof(unsigned char);
64  }
65  int n = _numComp * _width * _height * _dataSize;
66  _pixels = new unsigned char[n];
67  for(int i = 0; i < n; i++) _pixels[i] = 0;
68  }
69  ~PixelBuffer() { delete[] _pixels; }
70  int getWidth() { return _width; }
71  int getHeight() { return _height; }
72  int getNumComp() { return _numComp; }
73  int getDataSize() { return _dataSize; }
74  GLenum getFormat() { return _format; }
75  GLenum getType() { return _type; }
76  void *getPixels() { return (void *)_pixels; }
77  void copyPixels(int x, int y, PixelBuffer *buffer)
78  {
79  if(x + buffer->getWidth() > _width || y + buffer->getHeight() > _height) {
80  Msg::Error("Destination pixel buffer too small for holding copy");
81  return;
82  }
83  if(buffer->getNumComp() != _numComp || buffer->getDataSize() != _dataSize ||
84  buffer->getFormat() != _format || buffer->getType() != _type) {
85  Msg::Error("Pixel buffer type mismatch: impossible to copy");
86  return;
87  }
88  for(int i = 0; i < buffer->getWidth(); i++)
89  for(int j = 0; j < buffer->getHeight(); j++)
90  memcpy(_pixels + ((j + y) * _width + (i + x)) * _dataSize * _numComp,
91  (unsigned char *)buffer->getPixels() +
92  (j * buffer->getWidth() + i) * _dataSize * _numComp,
94  }
95  void fill(int offscreen)
96  {
97  if(!offscreen) {
98  // workaround double buffering issues by redrawing twice
101  glFinish();
102  glPixelStorei(GL_PACK_ALIGNMENT, 1);
103  glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
104  glReadPixels(0, 0, _width, _height, _format, _type, (void *)_pixels);
105  }
106  else {
107 #if defined(HAVE_OSMESA)
108  if(_format != GL_RGB && _type != GL_UNSIGNED_BYTE) {
109  Msg::Error(
110  "Offscreen rendering only implemented for GL_RGB/GL_UNSIGNED_BYTE");
111  return;
112  }
113  OSMesaContext ctx = OSMesaCreateContextExt(OSMESA_RGB, 16, 0, 0, nullptr);
114  if(!ctx) {
115  Msg::Error("OSMesaCreateContext failed");
116  return;
117  }
118  if(!OSMesaMakeCurrent(ctx, (void *)_pixels, GL_UNSIGNED_BYTE, _width,
119  _height)) {
120  Msg::Error("OSMesaMakeCurrent failed");
121  }
123  glFinish();
124  OSMesaDestroyContext(ctx);
125 #else
126  Msg::Warning(
127  "Gmsh must be compiled with OSMesa to support offscreen rendering");
128 #endif
129  }
130  }
131 };
132 
133 #endif
PixelBuffer::getHeight
int getHeight()
Definition: PixelBuffer.h:71
Msg::Warning
static void Warning(const char *fmt,...)
Definition: GmshMessage.cpp:543
Msg::Error
static void Error(const char *fmt,...)
Definition: GmshMessage.cpp:482
PixelBuffer::getFormat
GLenum getFormat()
Definition: PixelBuffer.h:74
drawContextGlobal::drawCurrentOpenglWindow
virtual void drawCurrentOpenglWindow(bool make_current)
Definition: drawContext.h:98
GmshMessage.h
PixelBuffer::getType
GLenum getType()
Definition: PixelBuffer.h:75
PixelBuffer::_dataSize
int _dataSize
Definition: PixelBuffer.h:34
drawContext::global
static drawContextGlobal * global()
Definition: drawContext.cpp:85
PixelBuffer::_pixels
unsigned char * _pixels
Definition: PixelBuffer.h:36
PixelBuffer::fill
void fill(int offscreen)
Definition: PixelBuffer.h:95
PixelBuffer::getPixels
void * getPixels()
Definition: PixelBuffer.h:76
PixelBuffer::PixelBuffer
PixelBuffer(int width, int height, GLenum format, GLenum type)
Definition: PixelBuffer.h:39
PixelBuffer::_width
int _width
Definition: PixelBuffer.h:34
PixelBuffer::getWidth
int getWidth()
Definition: PixelBuffer.h:70
PixelBuffer::getDataSize
int getDataSize()
Definition: PixelBuffer.h:73
PixelBuffer::_format
GLenum _format
Definition: PixelBuffer.h:35
PixelBuffer::_height
int _height
Definition: PixelBuffer.h:34
PixelBuffer::_numComp
int _numComp
Definition: PixelBuffer.h:34
PixelBuffer::_type
GLenum _type
Definition: PixelBuffer.h:35
PixelBuffer::getNumComp
int getNumComp()
Definition: PixelBuffer.h:72
PixelBuffer
Definition: PixelBuffer.h:32
PixelBuffer::copyPixels
void copyPixels(int x, int y, PixelBuffer *buffer)
Definition: PixelBuffer.h:77
PixelBuffer::~PixelBuffer
~PixelBuffer()
Definition: PixelBuffer.h:69
drawContext.h