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 // arbitrary but distinct values, (roughly) ordered according to version number
23 #define OPENGL_ES_2_0 1
24 #define OPENGL_2_1 2
25 #define OPENGL_3_3 3
26 #define OPENGL_VERSION OPENGL_2_1
27 
28 namespace gl {
29 
30 void checkGLError(std::string_view prefix);
31 
32 
33 // Dummy object, to be able to construct empty handler objects.
34 struct Null {};
35 
36 
40 class Texture
41 {
42 public:
43  Texture(const Texture&) = delete;
44  Texture& operator=(const Texture&) = delete;
45 
47  explicit Texture(bool interpolation = false, bool wrap = false);
48 
50  explicit Texture(Null) : textureId(0) {}
51 
53  ~Texture() { reset(); }
54 
56  Texture(Texture&& other) noexcept
57  : textureId(other.textureId)
58  {
59  other.textureId = 0; // 0 is not a valid openGL texture name
60  }
61  Texture& operator=(Texture&& other) noexcept {
62  std::swap(textureId, other.textureId);
63  return *this;
64  }
65 
67  void allocate();
68 
70  void reset();
71 
75  GLuint get() const { return textureId; }
76 
82  void bind() {
83  glBindTexture(GL_TEXTURE_2D, textureId);
84  }
85 
89  void setInterpolation(bool interpolation);
90 
91  void setWrapMode(bool wrap);
92 
93 protected:
94  GLuint textureId;
95 
96  friend class FrameBufferObject;
97 };
98 
99 class ColorTexture : public Texture
100 {
101 public:
103  ColorTexture() = default;
104 
108  ColorTexture(GLsizei width, GLsizei height);
109  void resize(GLsizei width, GLsizei height);
110 
111  GLsizei getWidth () const { return width; }
112  GLsizei getHeight() const { return height; }
113 
114 private:
115  GLsizei width = 0;
116  GLsizei height = 0;
117 };
118 
120 {
121 public:
122  FrameBufferObject() = default;
123  explicit FrameBufferObject(Texture& texture);
125  : bufferId(other.bufferId)
126  {
127  other.bufferId = 0;
128  }
130  std::swap(bufferId, other.bufferId);
131  return *this;
132  }
134 
135  void push();
136  void pop();
137 
138 private:
139  GLuint bufferId = 0; // 0 is not a valid openGL name
140  GLint previousId = 0;
141 };
142 
152 template <typename T> class PixelBuffer
153 {
154 public:
156  PixelBuffer(PixelBuffer&& other) noexcept;
157  PixelBuffer& operator=(PixelBuffer&& other) noexcept;
159 
164  void setImage(GLuint width, GLuint height);
165 
170  void bind() const;
171 
174  void unbind() const;
175 
182  T* getOffset(GLuint x, GLuint y);
183 
192  T* mapWrite();
193 
198  void unmap() const;
199 
200 private:
203  openmsx::MemBuffer<T> allocated;
204 
207  //GLuint bufferId;
208 
211  GLuint width = 0;
212 
215  GLuint height = 0;
216 };
217 
218 // class PixelBuffer
219 
220 template <typename T>
222 {
223  //glGenBuffers(1, &bufferId);
224 }
225 
226 template <typename T>
228  : allocated(std::move(other.allocated))
229  //, bufferId(other.bufferId)
230  , width(other.width)
231  , height(other.height)
232 {
233  //other.bufferId = 0;
234 }
235 
236 template <typename T>
238 {
239  std::swap(allocated, other.allocated);
240  //std::swap(bufferId, other.bufferId);
241  std::swap(width, other.width);
242  std::swap(height, other.height);
243  return *this;
244 }
245 
246 template <typename T>
248 {
249  //glDeleteBuffers(1, &bufferId); // ok to delete '0'
250 }
251 
252 template <typename T>
253 void PixelBuffer<T>::setImage(GLuint width_, GLuint height_)
254 {
255  width = width_;
256  height = height_;
257  //if (bufferId != 0) {
258  // bind();
259  // // TODO make performance hint configurable?
260  // glBufferData(GL_PIXEL_UNPACK_BUFFER,
261  // width * height * 4,
262  // nullptr, // leave data undefined
263  // GL_STREAM_DRAW); // performance hint
264  // unbind();
265  //} else {
266  allocated.resize(width * height);
267  //}
268 }
269 
270 template <typename T>
272 {
273  //if (bufferId != 0) {
274  // glBindBuffer(GL_PIXEL_UNPACK_BUFFER, bufferId);
275  //}
276 }
277 
278 template <typename T>
280 {
281  //if (bufferId != 0) {
282  // glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
283  //}
284 }
285 
286 template <typename T>
287 T* PixelBuffer<T>::getOffset(GLuint x, GLuint y)
288 {
289  assert(x < width);
290  assert(y < height);
291  auto offset = x + size_t(width) * y;
292  //if (bufferId != 0) {
293  // return reinterpret_cast<T*>(offset * sizeof(T));
294  //} else {
295  return &allocated[offset];
296  //}
297 }
298 
299 template <typename T>
301 {
302  //if (bufferId != 0) {
303  // return reinterpret_cast<T*>(glMapBuffer(
304  // GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY));
305  //} else {
306  return allocated.data();
307  //}
308 }
309 
310 template <typename T>
312 {
313  //if (bufferId != 0) {
314  // glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
315  //}
316 }
317 
318 
319 
323 class Shader
324 {
325 public:
328  bool isOK() const;
329 
330 protected:
335  Shader(GLenum type, const std::string& filename);
336  Shader(GLenum type, const std::string& header,
337  const std::string& filename);
338  ~Shader();
339 
340 private:
341  void init(GLenum type, const std::string& header,
342  const std::string& filename);
343 
344  friend class ShaderProgram;
345 
346  GLuint handle;
347 };
348 
352 class VertexShader : public Shader
353 {
354 public:
358  explicit VertexShader(const std::string& filename);
359  VertexShader(const std::string& header, const std::string& filename);
360 };
361 
365 class FragmentShader : public Shader
366 {
367 public:
371  explicit FragmentShader(const std::string& filename);
372  FragmentShader(const std::string& header, const std::string& filename);
373 };
374 
379 {
380 public:
381  ShaderProgram(const ShaderProgram&) = delete;
383 
386 
388  explicit ShaderProgram(Null) : handle(0) {}
389 
392 
394  void allocate();
395 
397  void reset();
398 
402  GLuint get() const { return handle; }
403 
407  bool isOK() const;
408 
411  void attach(const Shader& shader);
412 
416  void link();
417 
421  void bindAttribLocation(unsigned index, const char* name);
422 
427  GLint getUniformLocation(const char* name) const;
428 
432  void activate() const;
433 
434  void validate() const;
435 
436 private:
437  GLuint handle;
438 };
439 
441 {
442 public:
443  BufferObject();
444  ~BufferObject();
445  BufferObject(BufferObject&& other) noexcept
446  : bufferId(other.bufferId)
447  {
448  other.bufferId = 0;
449  }
450  BufferObject& operator=(BufferObject&& other) noexcept {
451  std::swap(bufferId, other.bufferId);
452  return *this;
453  }
454 
455  GLuint get() const { return bufferId; }
456 
457 private:
458  GLuint bufferId;
459 };
460 
461 } // namespace gl
462 
463 #endif // COMPONENT_GL
464 #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:50
gl::BufferObject::get
GLuint get() const
Definition: GLUtil.hh:455
gl::Texture::reset
void reset()
Release openGL texture name.
Definition: GLUtil.cc:43
gl::BufferObject
Definition: GLUtil.hh:441
gl::Texture
Most basic/generic texture: only contains a texture ID.
Definition: GLUtil.hh:41
gl::Texture::get
GLuint get() const
Returns the underlying openGL handler id.
Definition: GLUtil.hh:75
gl::VertexShader
Wrapper around an OpenGL vertex shader: a program executed on the GPU that computes per-vertex stuff.
Definition: GLUtil.hh:353
gl::BufferObject::operator=
BufferObject & operator=(BufferObject &&other) noexcept
Definition: GLUtil.hh:450
gl::ColorTexture
Definition: GLUtil.hh:100
gl::Null
Definition: GLUtil.hh:34
gl::ShaderProgram::ShaderProgram
ShaderProgram(Null)
Create null handler (don't yet allocate a openGL object).
Definition: GLUtil.hh:388
gl::ShaderProgram::reset
void reset()
Release the shader program handle.
Definition: GLUtil.cc:239
gl::ColorTexture::getWidth
GLsizei getWidth() const
Definition: GLUtil.hh:111
gl::PixelBuffer::mapWrite
T * mapWrite()
Maps the contents of this buffer into memory.
Definition: GLUtil.hh:300
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:285
gl::BufferObject::BufferObject
BufferObject(BufferObject &&other) noexcept
Definition: GLUtil.hh:445
gl::ShaderProgram::activate
void activate() const
Makes this program the active shader program.
Definition: GLUtil.cc:298
gl::Texture::bind
void bind()
Makes this texture the active GL texture.
Definition: GLUtil.hh:82
gl::ColorTexture::getHeight
GLsizei getHeight() const
Definition: GLUtil.hh:112
gl::ShaderProgram::validate
void validate() const
Definition: GLUtil.cc:304
gl::Texture::textureId
GLuint textureId
Definition: GLUtil.hh:94
gl::FrameBufferObject::operator=
FrameBufferObject & operator=(FrameBufferObject &&other) noexcept
Definition: GLUtil.hh:129
gl::PixelBuffer::PixelBuffer
PixelBuffer(PixelBuffer &&other) noexcept
Definition: GLUtil.hh:227
gl::Texture::~Texture
~Texture()
Release openGL texture name.
Definition: GLUtil.hh:53
gl
Definition: gl_mat.hh:24
gl::Texture::operator=
Texture & operator=(Texture &&other) noexcept
Definition: GLUtil.hh:61
gl::PixelBuffer::setImage
void setImage(GLuint width, GLuint height)
Sets the image for this buffer.
Definition: GLUtil.hh:253
gl::PixelBuffer::unmap
void unmap() const
Unmaps the contents of this buffer.
Definition: GLUtil.hh:311
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:290
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:56
gl::FrameBufferObject
Definition: GLUtil.hh:120
gl::Shader
Wrapper around an OpenGL shader: a program executed on the GPU.
Definition: GLUtil.hh:324
gl::ShaderProgram::get
GLuint get() const
Returns the underlying openGL handler id.
Definition: GLUtil.hh:402
openmsx::MemBuffer< T >
gl::BufferObject::~BufferObject
~BufferObject()
Definition: GLUtil.cc:327
gl::Texture::operator=
Texture & operator=(const Texture &)=delete
openmsx::filename
constexpr const char *const filename
Definition: FirmwareSwitch.cc:10
gl::PixelBuffer::operator=
PixelBuffer & operator=(PixelBuffer &&other) noexcept
Definition: GLUtil.hh:237
build-info.hh
gl::PixelBuffer
Wrapper around a pixel buffer.
Definition: GLUtil.hh:153
MemBuffer.hh
gl::Shader::isOK
bool isOK() const
Returns true iff this shader is loaded and compiled without errors.
Definition: GLUtil.cc:194
gl::PixelBuffer::unbind
void unbind() const
Unbind this buffer.
Definition: GLUtil.hh:279
gl::ShaderProgram::allocate
void allocate()
Allocate a shader program handle.
Definition: GLUtil.cc:231
components.hh
gl::PixelBuffer::PixelBuffer
PixelBuffer()
Definition: GLUtil.hh:221
openmsx::x
constexpr KeyMatrixPosition x
Keyboard bindings.
Definition: Keyboard.cc:1416
gl::Texture::Texture
Texture(const Texture &)=delete
gl::FragmentShader::FragmentShader
FragmentShader(const std::string &filename)
Instantiates a fragment shader.
Definition: GLUtil.cc:218
gl::ShaderProgram::attach
void attach(const Shader &shader)
Adds a given shader to this program.
Definition: GLUtil.cc:253
gl::VertexShader::VertexShader
VertexShader(const std::string &filename)
Instantiates a vertex shader.
Definition: GLUtil.cc:205
gl::Shader::~Shader
~Shader()
Definition: GLUtil.cc:189
gl::BufferObject::BufferObject
BufferObject()
Definition: GLUtil.cc:322
gl::FrameBufferObject::FrameBufferObject
FrameBufferObject()=default
gl::ShaderProgram
Wrapper around an OpenGL program: a collection of vertex and fragment shaders.
Definition: GLUtil.hh:379
gl::PixelBuffer::bind
void bind() const
Bind this PixelBuffer.
Definition: GLUtil.hh:271
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:385
gl::PixelBuffer::getOffset
T * getOffset(GLuint x, GLuint y)
Gets a pointer relative to the start of this buffer.
Definition: GLUtil.hh:287
gl::FrameBufferObject::~FrameBufferObject
~FrameBufferObject()
Definition: GLUtil.cc:110
gl::ShaderProgram::link
void link()
Links all attached shaders together into one program.
Definition: GLUtil.cc:265
gl::checkGLError
void checkGLError(std::string_view prefix)
Definition: GLUtil.cc:17
gl::FragmentShader
Wrapper around an OpenGL fragment shader: a program executed on the GPU that computes the colors of p...
Definition: GLUtil.hh:366
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:124
gl::ShaderProgram::isOK
bool isOK() const
Returns true iff this program was linked without errors.
Definition: GLUtil.cc:245
gl::ShaderProgram::~ShaderProgram
~ShaderProgram()
Destroy handler object (release the underlying openGL object).
Definition: GLUtil.hh:391
gl::PixelBuffer::~PixelBuffer
~PixelBuffer()
Definition: GLUtil.hh:247