openMSX
GLUtil.hh
Go to the documentation of this file.
1#ifndef GLUTIL_HH
2#define GLUTIL_HH
3
4// Include GLEW headers.
5#include <GL/glew.h>
6// Include OpenGL headers.
7#ifdef __APPLE__
8#include <OpenGL/gl.h>
9#else
10#include <GL/gl.h>
11#endif
12
13#include "MemBuffer.hh"
14
15#include <bit>
16#include <cassert>
17#include <cstdint>
18#include <span>
19#include <string_view>
20
21// arbitrary but distinct values, (roughly) ordered according to version number
22#define OPENGL_ES_2_0 1
23#define OPENGL_2_1 2
24#define OPENGL_3_3 3
25#define OPENGL_VERSION OPENGL_2_1
26
27namespace gl {
28
29void checkGLError(std::string_view prefix);
30
31
32// Dummy object, to be able to construct empty handler objects.
33struct Null {};
34
35
40{
41public:
42 Texture(const Texture&) = delete;
43 Texture& operator=(const Texture&) = delete;
44
46 explicit Texture(bool interpolation = false, bool wrap = false);
47
49 explicit Texture(Null) : textureId(0) {}
50
52 ~Texture() { reset(); }
53
55 Texture(Texture&& other) noexcept
56 : textureId(other.textureId)
57 {
58 other.textureId = 0; // 0 is not a valid openGL texture name
59 }
60 Texture& operator=(Texture&& other) noexcept {
61 std::swap(textureId, other.textureId);
62 return *this;
63 }
64
66 void allocate();
67
69 void reset();
70
74 [[nodiscard]] GLuint get() const { return textureId; }
75
78 [[nodiscard]] unsigned long long getImGui() const {
79 assert(textureId);
80 return uintptr_t(textureId);
81 }
82
88 void bind() const {
89 glBindTexture(GL_TEXTURE_2D, textureId);
90 }
91
95 void setInterpolation(bool interpolation);
96
97 void setWrapMode(bool wrap);
98
99protected:
100 GLuint textureId;
101
102 friend class FrameBufferObject;
103};
104
105class ColorTexture : public Texture
106{
107public:
109 ColorTexture() = default;
110
114 ColorTexture(GLsizei width, GLsizei height);
115 void resize(GLsizei width, GLsizei height);
116
117 [[nodiscard]] GLsizei getWidth () const { return width; }
118 [[nodiscard]] GLsizei getHeight() const { return height; }
119
120private:
121 GLsizei width = 0;
122 GLsizei height = 0;
123};
124
126{
127public:
128 FrameBufferObject() = default;
129 explicit FrameBufferObject(Texture& texture);
131 : bufferId(other.bufferId)
132 {
133 other.bufferId = 0;
134 }
136 std::swap(bufferId, other.bufferId);
137 return *this;
138 }
140
141 void push();
142 void pop();
143
144private:
145 GLuint bufferId = 0; // 0 is not a valid openGL name
146 GLint previousId = 0;
147};
148
158template<typename T> class PixelBuffer
159{
160public:
162 PixelBuffer(const PixelBuffer& other) = delete;
163 PixelBuffer(PixelBuffer&& other) noexcept;
164 PixelBuffer& operator=(const PixelBuffer& other) = delete;
167
170 void allocate(GLuint size);
171
176 void bind() const;
177
180 void unbind() const;
181
190 [[nodiscard]] std::span<T> mapWrite();
191
196 void unmap() const;
197
198private:
201 openmsx::MemBuffer<T> allocated;
202
205 //GLuint bufferId;
206};
207
208// class PixelBuffer
209
210template<typename T>
212{
213 //glGenBuffers(1, &bufferId);
214}
215
216template<typename T>
218{
219 //glDeleteBuffers(1, &bufferId); // ok to delete '0'
220}
221
222template<typename T>
224 : allocated(std::move(other.allocated))
225 //, bufferId(other.bufferId)
226{
227 //other.bufferId = 0;
228}
229
230template<typename T>
232{
233 std::swap(allocated, other.allocated);
234 //std::swap(bufferId, other.bufferId);
235 return *this;
236}
237
238template<typename T>
240{
241 //if (bufferId != 0) {
242 // bind();
243 // // TODO make performance hint configurable?
244 // glBufferData(GL_PIXEL_UNPACK_BUFFER,
245 // size * 4,
246 // nullptr, // leave data undefined
247 // GL_STREAM_DRAW); // performance hint
248 // unbind();
249 //} else {
250 allocated.resize(size);
251 //}
252}
253
254template<typename T>
256{
257 //if (bufferId != 0) {
258 // glBindBuffer(GL_PIXEL_UNPACK_BUFFER, bufferId);
259 //}
260}
261
262template<typename T>
264{
265 //if (bufferId != 0) {
266 // glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
267 //}
268}
269
270template<typename T>
272{
273 //if (bufferId != 0) {
274 // return std::bit_cast<T*>(glMapBuffer(
275 // GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY));
276 //} else {
277 return std::span{allocated};
278 //}
279}
280
281template<typename T>
283{
284 //if (bufferId != 0) {
285 // glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
286 //}
287}
288
289
290
295{
296public:
297 Shader(const Shader&) = delete;
298 Shader(Shader&&) = delete;
299 Shader& operator=(const Shader&) = delete;
300 Shader& operator=(Shader&&) = delete;
301
304 [[nodiscard]] bool isOK() const;
305
306protected:
311 Shader(GLenum type, std::string_view filename) {
312 init(type, {}, filename);
313 }
314 Shader(GLenum type, std::string_view header, std::string_view filename) {
315 init(type, header, filename);
316 }
317 ~Shader();
318
319private:
320 void init(GLenum type, std::string_view header,
321 std::string_view filename);
322
323 friend class ShaderProgram;
324
325private:
326 GLuint handle;
327};
328
332class VertexShader : public Shader
333{
334public:
338 explicit VertexShader(std::string_view filename)
339 : Shader(GL_VERTEX_SHADER, filename) {}
340 VertexShader(std::string_view header, std::string_view filename)
341 : Shader(GL_VERTEX_SHADER, header, filename) {}
342};
343
347class FragmentShader : public Shader
348{
349public:
353 explicit FragmentShader(std::string_view filename)
354 : Shader(GL_FRAGMENT_SHADER, filename) {}
355 FragmentShader(std::string_view header, std::string_view filename)
356 : Shader(GL_FRAGMENT_SHADER, header, filename) {}
357};
358
363{
364public:
365 ShaderProgram(const ShaderProgram&) = delete;
369
372
374 explicit ShaderProgram(Null) : handle(0) {}
375
378
380 void allocate();
381
383 void reset();
384
388 [[nodiscard]] GLuint get() const { return handle; }
389
393 [[nodiscard]] bool isOK() const;
394
397 void attach(const Shader& shader);
398
402 void link();
403
407 void bindAttribLocation(unsigned index, const char* name);
408
413 [[nodiscard]] GLint getUniformLocation(const char* name) const;
414
418 void activate() const;
419
420 void validate() const;
421
422private:
423 GLuint handle;
424};
425
427{
428public:
429 BufferObject();
430 BufferObject(const BufferObject&) = delete;
433
434 BufferObject(BufferObject&& other) noexcept
435 : bufferId(other.bufferId)
436 {
437 other.bufferId = 0;
438 }
440 std::swap(bufferId, other.bufferId);
441 return *this;
442 }
443
444 [[nodiscard]] GLuint get() const { return bufferId; }
445
446private:
447 GLuint bufferId;
448};
449
450} // namespace gl
451
452#endif // GLUTIL_HH
BufferObject & operator=(BufferObject &&other) noexcept
Definition GLUtil.hh:439
BufferObject(BufferObject &&other) noexcept
Definition GLUtil.hh:434
BufferObject & operator=(const BufferObject &)=delete
GLuint get() const
Definition GLUtil.hh:444
BufferObject(const BufferObject &)=delete
GLsizei getHeight() const
Definition GLUtil.hh:118
GLsizei getWidth() const
Definition GLUtil.hh:117
void resize(GLsizei width, GLsizei height)
Definition GLUtil.cc:85
ColorTexture()=default
Default constructor, zero-sized texture.
Wrapper around an OpenGL fragment shader: a program executed on the GPU that computes the colors of p...
Definition GLUtil.hh:348
FragmentShader(std::string_view header, std::string_view filename)
Definition GLUtil.hh:355
FragmentShader(std::string_view filename)
Instantiates a fragment shader.
Definition GLUtil.hh:353
FrameBufferObject()=default
FrameBufferObject(FrameBufferObject &&other) noexcept
Definition GLUtil.hh:130
FrameBufferObject & operator=(FrameBufferObject &&other) noexcept
Definition GLUtil.hh:135
Wrapper around a pixel buffer.
Definition GLUtil.hh:159
PixelBuffer(const PixelBuffer &other)=delete
PixelBuffer & operator=(PixelBuffer &&other) noexcept
Definition GLUtil.hh:231
void allocate(GLuint size)
Allocate the maximum required size for this buffer.
Definition GLUtil.hh:239
void unmap() const
Unmaps the contents of this buffer.
Definition GLUtil.hh:282
void unbind() const
Unbind this buffer.
Definition GLUtil.hh:263
PixelBuffer(PixelBuffer &&other) noexcept
Definition GLUtil.hh:223
void bind() const
Bind this PixelBuffer.
Definition GLUtil.hh:255
PixelBuffer & operator=(const PixelBuffer &other)=delete
std::span< T > mapWrite()
Maps the contents of this buffer into memory.
Definition GLUtil.hh:271
Wrapper around an OpenGL program: a collection of vertex and fragment shaders.
Definition GLUtil.hh:363
ShaderProgram & operator=(const ShaderProgram &)=delete
void activate() const
Makes this program the active shader program.
Definition GLUtil.cc:282
GLuint get() const
Returns the underlying openGL handler id.
Definition GLUtil.hh:388
bool isOK() const
Returns true iff this program was linked without errors.
Definition GLUtil.cc:229
void attach(const Shader &shader)
Adds a given shader to this program.
Definition GLUtil.cc:237
ShaderProgram(ShaderProgram &&)=delete
void validate() const
Definition GLUtil.cc:288
ShaderProgram(Null)
Create null handler (don't yet allocate a openGL object).
Definition GLUtil.hh:374
void allocate()
Allocate a shader program handle.
Definition GLUtil.cc:212
ShaderProgram & operator=(ShaderProgram &&)=delete
~ShaderProgram()
Destroy handler object (release the underlying openGL object).
Definition GLUtil.hh:377
ShaderProgram(const ShaderProgram &)=delete
ShaderProgram()
Create handler and allocate underlying openGL object.
Definition GLUtil.hh:371
void reset()
Release the shader program handle.
Definition GLUtil.cc:220
void link()
Links all attached shaders together into one program.
Definition GLUtil.cc:249
void bindAttribLocation(unsigned index, const char *name)
Bind the given name for a vertex shader attribute to the given location.
Definition GLUtil.cc:269
GLint getUniformLocation(const char *name) const
Gets a reference to a uniform variable declared in the shader source.
Definition GLUtil.cc:274
Wrapper around an OpenGL shader: a program executed on the GPU.
Definition GLUtil.hh:295
Shader & operator=(Shader &&)=delete
Shader(const Shader &)=delete
Shader(Shader &&)=delete
Shader & operator=(const Shader &)=delete
bool isOK() const
Returns true iff this shader is loaded and compiled without errors.
Definition GLUtil.cc:201
Shader(GLenum type, std::string_view filename)
Instantiates a shader.
Definition GLUtil.hh:311
Shader(GLenum type, std::string_view header, std::string_view filename)
Definition GLUtil.hh:314
Most basic/generic texture: only contains a texture ID.
Definition GLUtil.hh:40
Texture & operator=(Texture &&other) noexcept
Definition GLUtil.hh:60
void reset()
Release openGL texture name.
Definition GLUtil.cc:44
Texture(const Texture &)=delete
void bind() const
Makes this texture the active GL texture.
Definition GLUtil.hh:88
void setWrapMode(bool wrap)
Definition GLUtil.cc:69
void setInterpolation(bool interpolation)
Enable/disable bilinear interpolation for this texture.
Definition GLUtil.cc:61
~Texture()
Release openGL texture name.
Definition GLUtil.hh:52
GLuint get() const
Returns the underlying openGL handler id.
Definition GLUtil.hh:74
void allocate()
Allocate an openGL texture name.
Definition GLUtil.cc:39
unsigned long long getImGui() const
Return as a 'void*' (needed for 'Dear ImGui').
Definition GLUtil.hh:78
Texture(Texture &&other) noexcept
Move constructor and assignment.
Definition GLUtil.hh:55
GLuint textureId
Definition GLUtil.hh:100
Texture & operator=(const Texture &)=delete
Texture(Null)
Create null-handle (not yet allocate an openGL handle).
Definition GLUtil.hh:49
Wrapper around an OpenGL vertex shader: a program executed on the GPU that computes per-vertex stuff.
Definition GLUtil.hh:333
VertexShader(std::string_view filename)
Instantiates a vertex shader.
Definition GLUtil.hh:338
VertexShader(std::string_view header, std::string_view filename)
Definition GLUtil.hh:340
This class manages the lifetime of a block of memory.
Definition MemBuffer.hh:32
Definition gl_mat.hh:23
void checkGLError(std::string_view prefix)
Definition GLUtil.cc:18