title: glCheckFramebufferStatus returns zero on integrated graphics
body: <p>I'm writing a 2D OpenGL engine and I recently included a framebuffer wrapper class that I use to generate texture atlas at runtime. It worked pretty great and improved performance a lot, until I tested it on my laptop's integrated graphics.</p>
  
  <p>Apparently, when running on integrated graphics glCheckFramebufferStatus returns zero. No, it doesn't return GL_FRAMEBUFFER_UNSUPPORTED. It returns ZERO. I really don't think that my integrated graphics don't support framebuffers since they're not that old.
  I also tried to delay the initialization of the framebuffer to do it inside the main GLUT loop but it didn't solve the problem. I also tried using framebufferEXT instead of framebuffer, but nothing changed.
  If I ignore the error it doesn't draw anything when I attempt drawing the framebuffer's texture.
  Also: what should I fallback to if the video card doesn't support framebuffers and I absolutely need them?</p>
  
  <p>Here's the code of my framebuffer class:</p>
  
  <p>framebuffer.hpp:</p>
  
  <pre><code>#pragma once
  
  #include "sprite.hpp"
  
  namespace core
  {
      class framebuffer
      {
      public:
          framebuffer();
          virtual ~framebuffer();
          bool initialized();
          void initialize(int width, int height);
          int width();
          int height();
          sprite *getframe();
          void begin();
          void end();
  
      protected:
          GLubyte *pixels;
          int w, h;
          GLuint id, tex;
          sprite frame;
      };
  }
  </code></pre>
  
  <p>framebuffer.cpp:</p>
  
  <pre><code>#include "framebuffer.hpp"
  #include &lt;iostream&gt;
  #include &lt;cmath&gt;
  
  namespace core
  {
      framebuffer::framebuffer()
          : pixels(NULL), w(0), h(0)
      {
          // empty
      }
  
      framebuffer::~framebuffer()
      {
          glDeleteFramebuffers(1, &amp;id);
  
          if (pixels)
          {
              // TODO: convert to smart pointer once everything works ok
              delete [] pixels;
              pixels = NULL;
          }
      }
  
      bool framebuffer::initialized()
      {
          return w != 0 &amp;&amp; h != 0;
      }
  
      void framebuffer::initialize(int width, int height)
      {
          w = width;
          h = height;
          //std::cout &lt;&lt; "framebuffer.initialize: w = " &lt;&lt; w &lt;&lt; "\nh = " &lt;&lt; h &lt;&lt; std::endl;
      }
  
      int framebuffer::width()
      {
          return w;
      }
  
      int framebuffer::height()
      {
          return h;
      }
  
      sprite *framebuffer::getframe()
      {
          GLuint oldtex;
  
          glBindFramebuffer(GL_FRAMEBUFFER, id);
          glEnable(GL_TEXTURE_RECTANGLE_ARB);
          glGetIntegerv(GL_TEXTURE_RECTANGLE_ARB, reinterpret_cast&lt;GLint *&gt;(&amp;oldtex)); // store old bound texture
          glBindTexture(GL_TEXTURE_RECTANGLE_ARB, tex); // bind framebuffer texture
          glGetTexImage(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); // get framebuffer pixels
          frame.fromtexture(tex, GL_RGBA, w, h, GL_RGBA, pixels); // create a sprite object from raw pixels
          glBindTexture(GL_TEXTURE_RECTANGLE_ARB, oldtex); // re-bind the old texture
          glDisable(GL_TEXTURE_RECTANGLE_ARB);
          glBindFramebuffer(GL_FRAMEBUFFER, 0);
  
          return &amp;frame;
      }
  
      void framebuffer::begin() // call this to start drawing to the framebuffer
      {
          if (!pixels)
          {
              GLenum result;
  
              // initialize the frame buffer if it isn't already
  
              glGenTextures(1, &amp;tex); // generate the texture that will store the frame
  
              glEnable(GL_TEXTURE_RECTANGLE_ARB);
              glBindTexture(GL_TEXTURE_RECTANGLE_ARB, tex);
  
              // reserve video memory for the framebuffer image
              pixels = new GLubyte[w * h * 4];
              glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
              glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
              glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  
              glGenFramebuffers(1, &amp;id); // create frame buffer
              glBindFramebuffer(GL_FRAMEBUFFER, id);
  
              // assign the texture to the framebuffer
              glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_RECTANGLE_ARB, tex, 0);
  
              result = glCheckFramebufferStatus(GL_FRAMEBUFFER);
  
              if (result != GL_FRAMEBUFFER_COMPLETE)
              {
                  if (result == GL_FRAMEBUFFER_UNSUPPORTED)
                  {
                      // todo: handle errors as exceptions and cleanup everything gracefully
                      std::cout &lt;&lt; "framebuffer.begin: your video card doesn't seem to support framebuffers" &lt;&lt; std::endl;
                      exit(0);
                  }
  
                  std::cout &lt;&lt; "framebuffer.begin: failed to initialize framebuffer | error " &lt;&lt; result &lt;&lt; std::endl;
                  exit(0);
              }
  
              glDisable(GL_TEXTURE_RECTANGLE_ARB);
          }
  
          glBindFramebuffer(GL_FRAMEBUFFER, id); // bind the framebuffer
          glPushAttrib(GL_VIEWPORT_BIT | GL_ENABLE_BIT);
          glViewport(0, 0, w, h); // adjust viewport to the fbo's size
          glLoadIdentity(); // reset modelview matrix
  
          glMatrixMode(GL_PROJECTION);
          glPushMatrix(); // store the non-flipped matrix
          glLoadIdentity();
          glOrtho(0, w, 0, h, -1, 1); // stupid fbo's flipping stuff upside down
  
          glMatrixMode(GL_MODELVIEW);
          glEnable(GL_BLEND);
          glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
      }
  
      void framebuffer::end() // call this to stop drawing to the framebuffer
      {
          glPopAttrib();
          glBindFramebuffer(GL_FRAMEBUFFER, 0);
          glMatrixMode(GL_PROJECTION);
          glPopMatrix(); // restore old matrix
          glMatrixMode(GL_MODELVIEW);
      }
  }
  </code></pre>