openMSX
GLUtil.hh
Go to the documentation of this file.
1 #ifndef GLUTIL_HH
2 #define GLUTIL_HH
3 
4 // Check for availability of OpenGL.
5 #include "components.hh"
6 #if COMPONENT_GL
7 
8 // Include GLEW headers.
9 #include <GL/glew.h>
10 // Include OpenGL headers.
11 #ifdef __APPLE__
12 #include <OpenGL/gl.h>
13 #else
14 #include <GL/gl.h>
15 #endif
16 
17 #include "MemBuffer.hh"
18 #include "build-info.hh"
19 #include <string>
20 #include <cassert>
21 
22 namespace gl {
23 
24 // TODO this needs glu, but atm we don't link against glu (in windows)
25 //void checkGLError(const std::string& prefix);
26 
27 
28 // Dummy object, to be able to construct empty handler objects.
29 struct Null {};
30 
31 
35 class Texture
36 {
37 public:
38  Texture(const Texture&) = delete;
39  Texture& operator=(const Texture&) = delete;
40 
42  explicit Texture(bool interpolation = false, bool wrap = false);
43 
45  explicit Texture(Null) : textureId(0) {}
46 
48  ~Texture() { reset(); }
49 
51  Texture(Texture&& other) noexcept
52  : textureId(other.textureId)
53  {
54  other.textureId = 0; // 0 is not a valid openGL texture name
55  }
56  Texture& operator=(Texture&& other) noexcept {
57  std::swap(textureId, other.textureId);
58  return *this;
59  }
60 
62  void allocate();
63 
65  void reset();
66 
70  GLuint get() const { return textureId; }
71 
77  void bind() {
78  glBindTexture(GL_TEXTURE_2D, textureId);
79  }
80 
84  void setInterpolation(bool interpolation);
85 
86  void setWrapMode(bool wrap);
87 
88 protected:
89  GLuint textureId;
90 
91  friend class FrameBufferObject;
92 };
93 
94 class ColorTexture : public Texture
95 {
96 public:
98  ColorTexture() = default;
99 
103  ColorTexture(GLsizei width, GLsizei height);
104  void resize(GLsizei width, GLsizei height);
105 
106  GLsizei getWidth () const { return width; }
107  GLsizei getHeight() const { return height; }
108 
109 private:
110  GLsizei width = 0;
111  GLsizei height = 0;
112 };
113 
115 {
116 public:
117  FrameBufferObject() = default;
118  explicit FrameBufferObject(Texture& texture);
120  : bufferId(other.bufferId)
121  {
122  other.bufferId = 0;
123  }
125  std::swap(bufferId, other.bufferId);
126  return *this;
127  }
129 
130  void push();
131  void pop();
132 
133 private:
134  GLuint bufferId = 0; // 0 is not a valid openGL name
135  GLint previousId = 0;
136 };
137 
143 template <typename T> class PixelBuffer
144 {
145 public:
147  PixelBuffer(PixelBuffer&& other) noexcept;
148  PixelBuffer& operator=(PixelBuffer&& other) noexcept;
150 
155  void setImage(GLuint width, GLuint height);
156 
161  void bind() const;
162 
165  void unbind() const;
166 
173  T* getOffset(GLuint x, GLuint y);
174 
183  T* mapWrite();
184 
189  void unmap() const;
190 
191 private:
194  openmsx::MemBuffer<T> allocated;
195 
198  GLuint bufferId;
199 
202  GLuint width = 0;
203 
206  GLuint height = 0;
207 };
208 
209 // class PixelBuffer
210 
211 template <typename T>
213 {
214  glGenBuffers(1, &bufferId);
215 }
216 
217 template <typename T>
219  : allocated(std::move(other.allocated))
220  , bufferId(other.bufferId)
221  , width(other.width)
222  , height(other.height)
223 {
224  other.bufferId = 0;
225 }
226 
227 template <typename T>
229 {
230  std::swap(allocated, other.allocated);
231  std::swap(bufferId, other.bufferId);
232  std::swap(width, other.width);
233  std::swap(height, other.height);
234  return *this;
235 }
236 
237 template <typename T>
239 {
240  glDeleteBuffers(1, &bufferId); // ok to delete '0'
241 }
242 
243 template <typename T>
244 void PixelBuffer<T>::setImage(GLuint width_, GLuint height_)
245 {
246  width = width_;
247  height = height_;
248  if (bufferId != 0) {
249  bind();
250  // TODO make performance hint configurable?
251  glBufferData(GL_PIXEL_UNPACK_BUFFER,
252  width * height * 4,
253  nullptr, // leave data undefined
254  GL_STREAM_DRAW); // performance hint
255  unbind();
256  } else {
257  allocated.resize(width * height);
258  }
259 }
260 
261 template <typename T>
263 {
264  if (bufferId != 0) {
265  glBindBuffer(GL_PIXEL_UNPACK_BUFFER, bufferId);
266  }
267 }
268 
269 template <typename T>
271 {
272  if (bufferId != 0) {
273  glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
274  }
275 }
276 
277 template <typename T>
278 T* PixelBuffer<T>::getOffset(GLuint x, GLuint y)
279 {
280  assert(x < width);
281  assert(y < height);
282  auto offset = x + size_t(width) * y;
283  if (bufferId != 0) {
284  return reinterpret_cast<T*>(offset * sizeof(T));
285  } else {
286  return &allocated[offset];
287  }
288 }
289 
290 template <typename T>
292 {
293  if (bufferId != 0) {
294  return reinterpret_cast<T*>(glMapBuffer(
295  GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY));
296  } else {
297  return allocated.data();
298  }
299 }
300 
301 template <typename T>
303 {
304  if (bufferId != 0) {
305  glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
306  }
307 }
308 
309 
310 
314 class Shader
315 {
316 public:
319  bool isOK() const;
320 
321 protected:
326  Shader(GLenum type, const std::string& filename);
327  Shader(GLenum type, const std::string& header,
328  const std::string& filename);
329  ~Shader();
330 
331 private:
332  void init(GLenum type, const std::string& header,
333  const std::string& filename);
334 
335  friend class ShaderProgram;
336 
337  GLuint handle;
338 };
339 
343 class VertexShader : public Shader
344 {
345 public:
349  explicit VertexShader(const std::string& filename);
350  VertexShader(const std::string& header, const std::string& filename);
351 };
352 
356 class FragmentShader : public Shader
357 {
358 public:
362  explicit FragmentShader(const std::string& filename);
363  FragmentShader(const std::string& header, const std::string& filename);
364 };
365 
370 {
371 public:
372  ShaderProgram(const ShaderProgram&) = delete;
374 
377 
379  explicit ShaderProgram(Null) : handle(0) {}
380 
383 
385  void allocate();
386 
388  void reset();
389 
393  GLuint get() const { return handle; }
394 
398  bool isOK() const;
399 
402  void attach(const Shader& shader);
403 
407  void link();
408 
412  void bindAttribLocation(unsigned index, const char* name);
413 
418  GLint getUniformLocation(const char* name) const;
419 
423  void activate() const;
424 
425  void validate() const;
426 
427 private:
428  GLuint handle;
429 };
430 
432 {
433 public:
434  BufferObject();
435  ~BufferObject();
436  BufferObject(BufferObject&& other) noexcept
437  : bufferId(other.bufferId)
438  {
439  other.bufferId = 0;
440  }
441  BufferObject& operator=(BufferObject&& other) noexcept {
442  std::swap(bufferId, other.bufferId);
443  return *this;
444  }
445 
446  GLuint get() const { return bufferId; }
447 
448 private:
449  GLuint bufferId;
450 };
451 
453 {
454 public:
455  VertexArray();
456  ~VertexArray();
457  VertexArray(VertexArray&& other) noexcept
458  : bufferId(other.bufferId)
459  {
460  other.bufferId = 0;
461  }
462  VertexArray& operator=(VertexArray&& other) noexcept {
463  std::swap(bufferId, other.bufferId);
464  return *this;
465  }
466 
470  void bind() const { glBindVertexArray(bufferId); }
471 
474  void unbind() const { glBindVertexArray(0); }
475 
476  GLuint get() const { return bufferId; }
477 
478 private:
479  GLuint bufferId;
480 };
481 
482 } // namespace gl
483 
484 #endif // COMPONENT_GL
485 #endif // GLUTIL_HH
gl::ColorTexture::resize
void resize(GLsizei width, GLsizei height)
Definition: GLUtil.cc:73
gl::FrameBufferObject::pop
void pop()
Definition: GLUtil.cc:122
gl::Texture::Texture
Texture(Null)
Create null-handle (not yet allocate an openGL handle).
Definition: GLUtil.hh:45
gl::BufferObject::get
GLuint get() const
Definition: GLUtil.hh:446
gl::Texture::reset
void reset()
Release openGL texture name.
Definition: GLUtil.cc:43
gl::BufferObject
Definition: GLUtil.hh:432
gl::Texture
Most basic/generic texture: only contains a texture ID.
Definition: GLUtil.hh:36
gl::Texture::get
GLuint get() const
Returns the underlying openGL handler id.
Definition: GLUtil.hh:70
gl::VertexShader
Wrapper around an OpenGL vertex shader: a program executed on the GPU that computes per-vertex stuff.
Definition: GLUtil.hh:344
gl::BufferObject::operator=
BufferObject & operator=(BufferObject &&other) noexcept
Definition: GLUtil.hh:441
gl::ColorTexture
Definition: GLUtil.hh:95
gl::Null
Definition: GLUtil.hh:29
gl::ShaderProgram::ShaderProgram
ShaderProgram(Null)
Create null handler (don't yet allocate a openGL object).
Definition: GLUtil.hh:379
gl::ShaderProgram::reset
void reset()
Release the shader program handle.
Definition: GLUtil.cc:231
gl::ColorTexture::getWidth
GLsizei getWidth() const
Definition: GLUtil.hh:106
gl::PixelBuffer::mapWrite
T * mapWrite()
Maps the contents of this buffer into memory.
Definition: GLUtil.hh:291
gl::ShaderProgram::operator=
ShaderProgram & operator=(const ShaderProgram &)=delete
gl::ColorTexture::ColorTexture
ColorTexture()=default
Default constructor, zero-sized texture.
gl::FrameBufferObject::push
void push()
Definition: GLUtil.cc:116
gl::ShaderProgram::bindAttribLocation
void bindAttribLocation(unsigned index, const char *name)
Bind the given name for a vertex shader attribute to the given location.
Definition: GLUtil.cc:277
gl::BufferObject::BufferObject
BufferObject(BufferObject &&other) noexcept
Definition: GLUtil.hh:436
gl::ShaderProgram::activate
void activate() const
Makes this program the active shader program.
Definition: GLUtil.cc:290
gl::Texture::bind
void bind()
Makes this texture the active GL texture.
Definition: GLUtil.hh:77
gl::ColorTexture::getHeight
GLsizei getHeight() const
Definition: GLUtil.hh:107
gl::VertexArray::VertexArray
VertexArray(VertexArray &&other) noexcept
Definition: GLUtil.hh:457
gl::ShaderProgram::validate
void validate() const
Definition: GLUtil.cc:296
gl::Texture::textureId
GLuint textureId
Definition: GLUtil.hh:89
gl::FrameBufferObject::operator=
FrameBufferObject & operator=(FrameBufferObject &&other) noexcept
Definition: GLUtil.hh:124
gl::PixelBuffer::PixelBuffer
PixelBuffer(PixelBuffer &&other) noexcept
Definition: GLUtil.hh:218
gl::Texture::~Texture
~Texture()
Release openGL texture name.
Definition: GLUtil.hh:48
gl
Definition: gl_mat.hh:24
gl::Texture::operator=
Texture & operator=(Texture &&other) noexcept
Definition: GLUtil.hh:56
gl::PixelBuffer::setImage
void setImage(GLuint width, GLuint height)
Sets the image for this buffer.
Definition: GLUtil.hh:244
gl::PixelBuffer::unmap
void unmap() const
Unmaps the contents of this buffer.
Definition: GLUtil.hh:302
gl::Texture::setWrapMode
void setWrapMode(bool wrap)
Definition: GLUtil.cc:57
gl::ShaderProgram::getUniformLocation
GLint getUniformLocation(const char *name) const
Gets a reference to a uniform variable declared in the shader source.
Definition: GLUtil.cc:282
gl::ShaderProgram::ShaderProgram
ShaderProgram(const ShaderProgram &)=delete
gl::Texture::allocate
void allocate()
Allocate an openGL texture name.
Definition: GLUtil.cc:38
gl::Texture::Texture
Texture(Texture &&other) noexcept
Move constructor and assignment.
Definition: GLUtil.hh:51
gl::FrameBufferObject
Definition: GLUtil.hh:115
gl::VertexArray::bind
void bind() const
Bind this VertexArray.
Definition: GLUtil.hh:470
gl::Shader
Wrapper around an OpenGL shader: a program executed on the GPU.
Definition: GLUtil.hh:315
gl::ShaderProgram::get
GLuint get() const
Returns the underlying openGL handler id.
Definition: GLUtil.hh:393
openmsx::MemBuffer< T >
gl::BufferObject::~BufferObject
~BufferObject()
Definition: GLUtil.cc:319
gl::Texture::operator=
Texture & operator=(const Texture &)=delete
openmsx::filename
constexpr const char *const filename
Definition: FirmwareSwitch.cc:10
gl::VertexArray::operator=
VertexArray & operator=(VertexArray &&other) noexcept
Definition: GLUtil.hh:462
gl::PixelBuffer::operator=
PixelBuffer & operator=(PixelBuffer &&other) noexcept
Definition: GLUtil.hh:228
build-info.hh
gl::PixelBuffer
Wrapper around a pixel buffer.
Definition: GLUtil.hh:144
MemBuffer.hh
gl::Shader::isOK
bool isOK() const
Returns true iff this shader is loaded and compiled without errors.
Definition: GLUtil.cc:186
gl::PixelBuffer::unbind
void unbind() const
Unbind this buffer.
Definition: GLUtil.hh:270
gl::ShaderProgram::allocate
void allocate()
Allocate a shader program handle.
Definition: GLUtil.cc:223
gl::VertexArray::VertexArray
VertexArray()
Definition: GLUtil.cc:327
components.hh
gl::PixelBuffer::PixelBuffer
PixelBuffer()
Definition: GLUtil.hh:212
openmsx::x
constexpr KeyMatrixPosition x
Keyboard bindings.
Definition: Keyboard.cc:1419
gl::Texture::Texture
Texture(const Texture &)=delete
gl::FragmentShader::FragmentShader
FragmentShader(const std::string &filename)
Instantiates a fragment shader.
Definition: GLUtil.cc:210
gl::ShaderProgram::attach
void attach(const Shader &shader)
Adds a given shader to this program.
Definition: GLUtil.cc:245
gl::VertexShader::VertexShader
VertexShader(const std::string &filename)
Instantiates a vertex shader.
Definition: GLUtil.cc:197
gl::Shader::~Shader
~Shader()
Definition: GLUtil.cc:181
gl::BufferObject::BufferObject
BufferObject()
Definition: GLUtil.cc:314
gl::VertexArray::unbind
void unbind() const
Unbind this VertexArray.
Definition: GLUtil.hh:474
gl::FrameBufferObject::FrameBufferObject
FrameBufferObject()=default
gl::ShaderProgram
Wrapper around an OpenGL program: a collection of vertex and fragment shaders.
Definition: GLUtil.hh:370
gl::PixelBuffer::bind
void bind() const
Bind this PixelBuffer.
Definition: GLUtil.hh:262
gl::Shader::Shader
Shader(GLenum type, const std::string &filename)
Instantiates a shader.
Definition: GLUtil.cc:130
gl::ShaderProgram::ShaderProgram
ShaderProgram()
Create handler and allocate underlying openGL object.
Definition: GLUtil.hh:376
gl::VertexArray
Definition: GLUtil.hh:453
gl::PixelBuffer::getOffset
T * getOffset(GLuint x, GLuint y)
Gets a pointer relative to the start of this buffer.
Definition: GLUtil.hh:278
gl::FrameBufferObject::~FrameBufferObject
~FrameBufferObject()
Definition: GLUtil.cc:110
gl::ShaderProgram::link
void link()
Links all attached shaders together into one program.
Definition: GLUtil.cc:257
gl::FragmentShader
Wrapper around an OpenGL fragment shader: a program executed on the GPU that computes the colors of p...
Definition: GLUtil.hh:357
gl::Texture::setInterpolation
void setInterpolation(bool interpolation)
Enable/disable bilinear interpolation for this texture.
Definition: GLUtil.cc:49
gl::FrameBufferObject::FrameBufferObject
FrameBufferObject(FrameBufferObject &&other) noexcept
Definition: GLUtil.hh:119
gl::ShaderProgram::isOK
bool isOK() const
Returns true iff this program was linked without errors.
Definition: GLUtil.cc:237
gl::VertexArray::~VertexArray
~VertexArray()
Definition: GLUtil.cc:332
gl::ShaderProgram::~ShaderProgram
~ShaderProgram()
Destroy handler object (release the underlying openGL object).
Definition: GLUtil.hh:382
gl::PixelBuffer::~PixelBuffer
~PixelBuffer()
Definition: GLUtil.hh:238
gl::VertexArray::get
GLuint get() const
Definition: GLUtil.hh:476