summaryrefslogtreecommitdiff
path: root/tests/fbo.cc
diff options
context:
space:
mode:
authorDon Bright <hugh.m.bright@gmail.com>2011-10-09 01:02:40 (GMT)
committerDon Bright <hugh.m.bright@gmail.com>2011-10-09 01:02:40 (GMT)
commit589991c41e5420e68a8504670c25b0dba9e6628e (patch)
tree792553691ad1d6a1c5258d532003e1eea900ffec /tests/fbo.cc
parent872fc643218ef642544612954272e89629e145c5 (diff)
Linux offscreen OpenGL using glxpixmaps. also fix FBO ARB/EXT issues
Diffstat (limited to 'tests/fbo.cc')
-rw-r--r--tests/fbo.cc144
1 files changed, 132 insertions, 12 deletions
diff --git a/tests/fbo.cc b/tests/fbo.cc
index 403a32e..b7bf1c0 100644
--- a/tests/fbo.cc
+++ b/tests/fbo.cc
@@ -15,13 +15,94 @@ fbo_t *fbo_new()
#define REPORTGLERROR(task) { GLenum tGLErr = glGetError(); if (tGLErr != GL_NO_ERROR) { std::cout << "OpenGL error " << tGLErr << " while " << task << "\n"; } }
-bool fbo_init(fbo_t *fbo, size_t width, size_t height)
+bool use_ext()
+{
+ // do we need to use the EXT or ARB version?
+ if (!glewIsSupported("GL_ARB_framebuffer_object") &&
+ glewIsSupported("GL_EXT_framebuffer_object")) {
+ return true;
+ } else {
+ return false;
+ }
+}
+
+bool check_fbo_status()
{
- if (!glewIsSupported("GL_ARB_framebuffer_object")) {
- fprintf(stderr, "Framebuffer extension not found\n");
+ /* This code is based on user V-man code from
+ http://www.opengl.org/wiki/GL_EXT_framebuffer_multisample
+ See also: http://www.songho.ca/opengl/gl_fbo.html */
+ GLenum status;
+ bool result = false;
+ if (use_ext())
+ status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
+ else
+ status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+
+ if (glGetError() != GL_NO_ERROR)
+ fprintf(stderr, "OpenGL Error %i\n",glGetError());
+
+ if (status == GL_FRAMEBUFFER_COMPLETE)
+ result = true;
+ else if (status == GL_FRAMEBUFFER_UNSUPPORTED)
+ fprintf(stderr, "GL_FRAMEBUFFER_UNSUPPORTED\n");
+ else if (status == GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT)
+ fprintf(stderr, "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT\n");
+ else if (status == GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT)
+ fprintf(stderr, "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT\n");
+ else if (status == GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT)
+ fprintf(stderr, "GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT\n");
+ else if (status == GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT)
+ fprintf(stderr, "GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT\n");
+ else if (status == GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT)
+ fprintf(stderr, "GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT\n");
+ else if (status == GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT)
+ fprintf(stderr, "GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT\n");
+ else if (status == GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT)
+ fprintf(stderr, "GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT\n");
+ else
+ fprintf(stderr, "Unknown Code: glCheckFramebufferStatusEXT returned %i\n",status);
+ return result;
+}
+
+bool fbo_ext_init(fbo_t *fbo, size_t width, size_t height)
+{
+ // Generate and bind FBO
+ glGenFramebuffersEXT(1, &fbo->fbo_id);
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo->fbo_id);
+ REPORTGLERROR("binding framebuffer");
+
+ // Generate depth and render buffers
+ glGenRenderbuffersEXT(1, &fbo->depthbuf_id);
+ glGenRenderbuffersEXT(1, &fbo->renderbuf_id);
+
+ // Create buffers with correct size
+ if (!fbo_resize(fbo, width, height)) return false;
+
+ // Attach render and depth buffers
+ glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
+ GL_RENDERBUFFER_EXT, fbo->renderbuf_id);
+ REPORTGLERROR("specifying color render buffer");
+
+
+ if (!check_fbo_status()) {
+ fprintf(stderr, "Problem with OpenGL framebuffer after specifying color render buffer.\n");
+ return false;
+ }
+
+ glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
+ GL_RENDERBUFFER_EXT, fbo->depthbuf_id);
+ REPORTGLERROR("specifying depth render buffer");
+
+ if (!check_fbo_status()) {
+ fprintf(stderr, "Problem with OpenGL framebuffer after specifying depth render buffer.\n");
return false;
}
+ return true;
+}
+
+bool fbo_arb_init(fbo_t *fbo, size_t width, size_t height)
+{
// Generate and bind FBO
glGenFramebuffers(1, &fbo->fbo_id);
glBindFramebuffer(GL_FRAMEBUFFER, fbo->fbo_id);
@@ -56,15 +137,48 @@ bool fbo_init(fbo_t *fbo, size_t width, size_t height)
return true;
}
-bool fbo_resize(fbo_t *fbo, size_t width, size_t height)
+
+bool fbo_init(fbo_t *fbo, size_t width, size_t height)
{
- glBindRenderbuffer(GL_RENDERBUFFER, fbo->depthbuf_id);
- glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, width, height);
- REPORTGLERROR("creating depth render buffer");
+ /*
+ Some OpenGL drivers include the framebuffer functions but not with
+ core or ARB names, only with the EXT name. This has been worked-around
+ by deciding at runtime, using GLEW, which version needs to be used. See also:
+
+ http://www.opengl.org/wiki/Framebuffer_Object
+ http://stackoverflow.com/questions/6912988/glgenframebuffers-or-glgenframebuffersex
+ http://www.devmaster.net/forums/showthread.php?t=10967
+ */
+
+ bool result = false;
+ if (glewIsSupported("GL_ARB_framebuffer_object"))
+ result = fbo_arb_init(fbo, width, height);
+ else if (use_ext())
+ result = fbo_ext_init(fbo, width, height);
+ else
+ fprintf(stderr, "Framebuffer Object extension not found by GLEW\n");
+ return result;
+}
- glBindRenderbuffer(GL_RENDERBUFFER, fbo->renderbuf_id);
- glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, width, height);
- REPORTGLERROR("creating color render buffer");
+bool fbo_resize(fbo_t *fbo, size_t width, size_t height)
+{
+ if (use_ext()) {
+ glBindRenderbufferEXT(GL_RENDERBUFFER, fbo->depthbuf_id);
+ glRenderbufferStorageEXT(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, width, height);
+ REPORTGLERROR("creating depth render buffer");
+
+ glBindRenderbufferEXT(GL_RENDERBUFFER, fbo->renderbuf_id);
+ glRenderbufferStorageEXT(GL_RENDERBUFFER, GL_RGBA8, width, height);
+ REPORTGLERROR("creating color render buffer");
+ } else {
+ glBindRenderbuffer(GL_RENDERBUFFER, fbo->depthbuf_id);
+ glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, width, height);
+ REPORTGLERROR("creating depth render buffer");
+
+ glBindRenderbuffer(GL_RENDERBUFFER, fbo->renderbuf_id);
+ glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, width, height);
+ REPORTGLERROR("creating color render buffer");
+ }
return true;
}
@@ -77,11 +191,17 @@ void fbo_delete(fbo_t *fbo)
GLuint fbo_bind(fbo_t *fbo)
{
glGetIntegerv(GL_FRAMEBUFFER_BINDING, (GLint *)&fbo->old_fbo_id);
- glBindFramebuffer(GL_FRAMEBUFFER, fbo->fbo_id);
+ if (use_ext())
+ glBindFramebufferEXT(GL_FRAMEBUFFER, fbo->fbo_id);
+ else
+ glBindFramebuffer(GL_FRAMEBUFFER, fbo->fbo_id);
return fbo->old_fbo_id;
}
void fbo_unbind(fbo_t *fbo)
{
- glBindFramebuffer(GL_FRAMEBUFFER, fbo->old_fbo_id);
+ if (use_ext())
+ glBindFramebufferEXT(GL_FRAMEBUFFER, fbo->old_fbo_id);
+ else
+ glBindFramebuffer(GL_FRAMEBUFFER, fbo->old_fbo_id);
}
contact: Jan Huwald // Impressum