17#ifndef __gui_opengl_gl_h__
18#define __gui_opengl_gl_h__
24#if QT_VERSION >= 0x050000
30#include "gui/opengl/gl_core_3_3.h"
43#ifdef GL_SHOW_DEBUG_MESSAGE
44# define GL_DEBUG(msg) DEBUG(msg)
46# define GL_DEBUG(msg) (void)0
50# define GL_CHECK_ERROR
52# define GL_CHECK_ERROR ::MR::GUI::GL::check_error (__FILE__, __LINE__)
56#define GLGETBOOL(x,n) { GLboolean __v[n]; gl::GetBooleanv (x, __v); std::cerr << #x " = "; for (auto i : __v) std::cerr << int(i) << " "; std::cerr << "\n"; }
57#define GLGETINT(x,n) { GLint __v[n]; gl::GetIntegerv (x, __v); std::cerr << #x " = "; for (auto i : __v) std::cerr << int(i) << " "; std::cerr << "\n"; }
68#if QT_VERSION >= 0x050400
70 using Area = QOpenGLWidget;
71 using Format = QSurfaceFormat;
76 using QGLWidget::QGLWidget;
89 GLenum err = gl::GetError();
91 FAIL (std::string (
"[") + filename +
": " +
str(line) +
"] OpenGL error: " +
ErrorString (err));
110#if QT_VERSION >= 0x050400
111 inline std::pair<QOpenGLContext*,QSurface*>
current() {
112 QOpenGLContext* context = QOpenGLContext::currentContext();
113 QSurface* surface = context ? context->surface() :
nullptr;
114 return { context, surface };
117 inline std::pair<QOpenGLContext*,QSurface*>
get (QWidget* window) {
118 QOpenGLContext* context =
reinterpret_cast<QOpenGLWidget*
> (window)->context();
119 QSurface* surface = context ? context->surface() :
nullptr;
120 return { context, surface };
123 inline std::pair<QOpenGLContext*,QSurface*>
makeCurrent (QWidget* window) {
124 auto previous_context =
current();
126 reinterpret_cast<QOpenGLWidget*
> (window)->
makeCurrent();
127 return previous_context;
130 inline void restore (std::pair<QOpenGLContext*,QSurface*> previous_context) {
131 if (previous_context.first)
132 previous_context.first->makeCurrent (previous_context.second);
135 inline std::pair<int,int>
current() {
return { 0, 0 }; }
136 inline std::pair<int,int>
get (QWidget*) {
return { 0, 0 }; }
137 inline std::pair<int,int>
makeCurrent (QWidget*) {
return { 0, 0 }; }
173 operator GLuint ()
const {
return id; }
174 void gen (GLenum target, GLint interp_type = gl::LINEAR) {
178 gl::GenTextures (1, &
id);
181 gl::TexParameteri (
tex_type, gl::TEXTURE_BASE_LEVEL, 0);
182 gl::TexParameteri (
tex_type, gl::TEXTURE_MAX_LEVEL, 0);
183 gl::TexParameteri (
tex_type, gl::TEXTURE_MAG_FILTER, interp_type);
184 gl::TexParameteri (
tex_type, gl::TEXTURE_MIN_FILTER, interp_type);
185 gl::TexParameteri (
tex_type, gl::TEXTURE_WRAP_S, gl::CLAMP_TO_EDGE);
186 gl::TexParameteri (
tex_type, gl::TEXTURE_WRAP_T, gl::CLAMP_TO_EDGE);
188 gl::TexParameteri (
tex_type, gl::TEXTURE_WRAP_R, gl::CLAMP_TO_EDGE);
195 GL_DEBUG (
"deleting OpenGL texture ID " +
str(
id));
196 gl::DeleteTextures (1, &
id);
209 gl::TexParameteri (
tex_type, gl::TEXTURE_MAG_FILTER,
type);
210 gl::TexParameteri (
tex_type, gl::TEXTURE_MIN_FILTER,
type);
227 operator GLuint ()
const {
return id; }
231 gl::GenBuffers (1, &
id);
232 GL_DEBUG (
"created OpenGL vertex buffer ID " +
str(
id));
238 GL_DEBUG (
"deleting OpenGL vertex buffer ID " +
str(
id));
239 gl::DeleteBuffers (1, &
id);
243 void bind (GLenum target)
const {
246 GL_DEBUG (
"binding OpenGL vertex buffer ID " +
str(
id));
247 gl::BindBuffer (target,
id);
262 operator GLuint ()
const {
return id; }
266 gl::GenVertexArrays (1, &
id);
267 GL_DEBUG (
"created OpenGL vertex array ID " +
str(
id));
273 GL_DEBUG (
"deleting OpenGL vertex array ID " +
str(
id));
274 gl::DeleteVertexArrays (1, &
id);
id = 0;
280 GL_DEBUG (
"binding OpenGL vertex array ID " +
str(
id));
281 gl::BindVertexArray (
id);
296 operator GLuint ()
const {
return id; }
300 gl::GenBuffers (1, &
id);
301 GL_DEBUG (
"created OpenGL index buffer ID " +
str(
id));
307 GL_DEBUG (
"deleting OpenGL index buffer ID " +
str(
id));
308 gl::DeleteBuffers (1, &
id);
315 GL_DEBUG (
"binding OpenGL index buffer ID " +
str(
id));
316 gl::BindBuffer (gl::ELEMENT_ARRAY_BUFFER,
id);
332 operator GLuint ()
const {
return id; }
336 gl::GenFramebuffers (1, &
id);
337 GL_DEBUG (
"created OpenGL framebuffer ID " +
str(
id));
343 GL_DEBUG (
"deleting OpenGL framebuffer ID " +
str(
id));
344 gl::DeleteFramebuffers (1, &
id);
352 GL_DEBUG (
"binding OpenGL framebuffer ID " +
str(
id));
353 gl::BindFramebuffer (gl::FRAMEBUFFER,
id);
357 GL_DEBUG (
"binding default OpenGL framebuffer");
358#if QT_VERSION >= 0x050400
359 gl::BindFramebuffer (gl::FRAMEBUFFER, QOpenGLContext::currentContext()->defaultFramebufferObject());
361 gl::BindFramebuffer (gl::FRAMEBUFFER, 0);
369 GL_DEBUG (
"texture ID " +
str (tex) +
" attached to framebuffer ID " +
str(
id) +
" at color attachement " +
str(attachment));
370 gl::FramebufferTexture (gl::FRAMEBUFFER, GLenum (
size_t (gl::COLOR_ATTACHMENT0) + attachment), tex, 0);
374 GLenum list[1] = { GLenum (
size_t (gl::COLOR_ATTACHMENT0) + first) };
375 gl::DrawBuffers (1 , list);
379 GLenum list[2] = { GLenum (
size_t(gl::COLOR_ATTACHMENT0) + first), GLenum (
size_t (gl::COLOR_ATTACHMENT0) + second) };
380 gl::DrawBuffers (2 , list);
385 if (gl::CheckFramebufferStatus (gl::FRAMEBUFFER) != gl::FRAMEBUFFER_COMPLETE)
386 throw Exception (
"FIXME: framebuffer is not complete");
FrameBuffer & operator=(FrameBuffer &&t)
void attach_color(Texture &tex, size_t attachment) const
FrameBuffer(const FrameBuffer &)
Context::Checker check_context
void draw_buffers(size_t first, size_t second) const
void draw_buffers(size_t first) const
FrameBuffer(FrameBuffer &&t)
IndexBuffer(const IndexBuffer &)
Context::Checker check_context
IndexBuffer & operator=(IndexBuffer &&t)
IndexBuffer(IndexBuffer &&t)
void set_interp(GLint type) const
void set_interp_on(bool interpolate) const
void gen(GLenum target, GLint interp_type=gl::LINEAR)
void cache_copy(const Texture &t)
Context::Checker check_context
Texture & operator=(Texture &&t)
VertexArrayObject(VertexArrayObject &&t)
Context::Checker check_context
VertexArrayObject(const VertexArrayObject &)
VertexArrayObject & operator=(VertexArrayObject &&t)
Context::Checker check_context
void bind(GLenum target) const
VertexBuffer & operator=(VertexBuffer &&t)
VertexBuffer(const VertexBuffer &)
VertexBuffer(VertexBuffer &&t)
std::pair< int, int > get(QWidget *)
std::pair< int, int > current()
std::pair< int, int > makeCurrent(QWidget *)
void restore(std::pair< int, int >)
const char * ErrorString(GLenum errorcode)
void __assert_context_is_current(QWidget *glarea)
void assert_context_is_current(QWidget *glarea=nullptr)
void set_default_context()
void check_error(const char *filename, int line)
std::string str(const T &value, int precision=0)
NOMEMALIGN decltype(current()) original_context
Grab(QWidget *window=nullptr)
NOMEMALIGN decltype(current()) previous_context