示例#1
0
void initGraphics()
{
  /* Use an orthographic path-to-clip-space transform to map the
  [0..1000]x[0..1000] range of the star's path coordinates to the [-1..1]
  clip space cube: */
  glMatrixLoadIdentityEXT(GL_PROJECTION);
  glMatrixLoadIdentityEXT(GL_MODELVIEW);
  glMatrixOrthoEXT(GL_MODELVIEW, 0, 1000, 1000, 0, -1, 1);

  /* Before rendering to a window with a stencil buffer, clear the stencil
  buffer to zero and the color buffer to blue: */
  glClearStencil(0);
  glClearColor(0.1, 0.3, 0.6, 0.0);
  glEnable(GL_STENCIL_TEST);

  initDragon();
}
示例#2
0
void initGraphics()
{
  /* Use an orthographic path-to-clip-space transform to map the
  [0..640]x[0..480] range of the star's path coordinates to the [-1..1]
  clip space cube: */
  glMatrixLoadIdentityEXT(GL_PROJECTION);
  glMatrixOrthoEXT(GL_PROJECTION, 0, canvas_width, canvas_height, 0, -1, 1);
  glMatrixLoadIdentityEXT(GL_MODELVIEW);

  /* Before rendering to a window with a stencil buffer, clear the stencil
  buffer to zero and the color buffer to blue: */
  glClearStencil(0);
  glClearColor(0.1, 0.3, 0.6, 0.0);

  initTiger();

  glEnable(GL_STENCIL_TEST);
  glStencilFunc(GL_NOTEQUAL, 0, 0x1F);
  glStencilOp(GL_KEEP, GL_KEEP, GL_ZERO);
}
示例#3
0
文件: helpers.cpp 项目: npapier/oglpp
// Matrix manipulation commands
void loadIdentity( GLenum mode )
{
	if ( isDSAEnabled() )
	{
		glMatrixLoadIdentityEXT( mode );
	}
	else
	{
		glMatrixMode( mode );
		glLoadIdentity();
	}
}
示例#4
0
void StCVisitor::coverRect(RectBounds &bounds)
{
    // XXX this absolute matrix loading usage is incompatible
    // with compiled display list mode (makingDlist).
    glMatrixLoadIdentityEXT(GL_MODELVIEW);

    RectBounds dilated = bounds.dilate(
                             2.0f / renderer->view_width_height.x,
                             2.0f / renderer->view_width_height.y);

    glBegin(GL_QUADS);
    {
        glVertex2f(dilated.x, dilated.y);
        glVertex2f(dilated.x, dilated.w);
        glVertex2f(dilated.z, dilated.w);
        glVertex2f(dilated.z, dilated.y);
    }
    glEnd();

    loadCurrentMatrix();
}
示例#5
0
文件: render.cpp 项目: greggman/regal
void dreamTorusDisplay( bool clear )
{
    static float r = 0.0f;
    static int count = 0;

    if( count == 0 ) {
        init();
    }

    glPushGroupMarkerEXT(0, "display");

#if 1
    if( count == 0 ) {
        RegalSetErrorCallback( regalerr );
    } else if( count == 11 ) {
        RegalSetErrorCallback( NULL );
    }
    count++;
#endif

    glUseProgram( 0 );
    if( clear ) {
        glClearDepth( 1.0 );
        glClearColor( r / 400.f, 0, 0, 0);
        glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
    }
    glEnable( GL_DEPTH_TEST );

    for( int i = 0; i < 8; i++ ) {
        glActiveTexture( GL_TEXTURE0 + i );
        glDisable( GL_TEXTURE_2D );
    }

    glBindMultiTextureEXT( texunit, GL_TEXTURE_2D, tex );
    glActiveTexture( texunit );
    glEnable( GL_TEXTURE_2D );


    float sc = 2.0f * fabs( ( count % 800 ) / 400.0f - 1.0f ) + 1.0f;

    glMatrixLoadIdentityEXT( texunit );
    glMatrixScalefEXT( texunit, sc, 1, 1 );

    float osc = sc * 0.5f;


    glEnable( GL_FOG );

    if( ( count % 7 ) == 0 || ( count % 17 ) == 0 ) {
        glDisable( GL_NORMALIZE );
        glEnable( GL_RESCALE_NORMAL );
        glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
        glMatrixMode( GL_MODELVIEW );
        glPushMatrix();
        glRotatef( (float) count, -1.0f, 1.0f, 0.0f );
        glScalef( osc, osc, osc );
        drawAnObject();
        glPopMatrix();
    } else {
        glEnable( GL_NORMALIZE );
        glDisable( GL_RESCALE_NORMAL );
        glMultiTexEnviEXT( texunit, GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
        glMatrixPushEXT( GL_MODELVIEW );
        glMatrixRotatefEXT( GL_MODELVIEW, (float) count, -1.0f, 1.0f, 0.0f );
        glMatrixScalefEXT( GL_MODELVIEW, osc, osc, osc );
        drawAnObject();
        glMatrixPopEXT( GL_MODELVIEW );
    }

    r += 1.0f;
    if( r > 399 ) {
        r = 0.0f;
    }

    glPopGroupMarkerEXT();

  //printf( "Draw with r=%f\n", r );
}
示例#6
0
文件: render.cpp 项目: greggman/regal
static void init()
{
    glPushGroupMarkerEXT(0, "init");

    glGenTextures( 1, &tex );
    GLubyte pix[] = {
        0x60, 0xff, 0x00, 0xff,  0xff, 0x00, 0x00, 0xff,  0xff, 0x00, 0xff, 0xff,  0x00, 0xff, 0xff, 0xff,
        0xff, 0xff, 0xff, 0xff,  0x00, 0x00, 0xff, 0xff,  0x00, 0x00, 0x00, 0xff,  0xff, 0x80, 0x00, 0xff,
        0x80, 0x80, 0xff, 0xff,  0xff, 0x00, 0x00, 0xff,  0x80, 0x80, 0x80, 0xff,  0x00, 0x80, 0x80, 0xff,
        0x00, 0xff, 0xff, 0xff,  0x00, 0x80, 0x00, 0xff,  0x80, 0x00, 0xff, 0xff,  0x00, 0x00, 0x80, 0xff
    };
    glTextureImage2DEXT( tex, GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, pix );
    glTextureParameteriEXT( tex, GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
    glTextureParameteriEXT( tex, GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
    glBindMultiTextureEXT( texunit, GL_TEXTURE_2D, tex );

    GLfloat mat_specular[]   = { 0.0f, 0.0f, 1.0f, 1.0f };
    GLfloat mat_shininess[]  = { 50.0f };
    GLfloat light_position[] = { 1.0f, 1.0f, 0.2f, 1.0f };
    GLfloat light_atten[]    = { 1.0f, 1.0f, 1.0f };
    GLfloat light_diffuse[]  = { 10.0f, 10.0f, 10.0f, 10.0f };
    GLfloat light_specular[] = { 10.0f, 10.0f, 10.0f, 10.0f };
    GLfloat light_spotdir[]  = { -0.1f, -0.1f, -1.0f };
    GLfloat light_spotcut[]  = { 30.0f };
    GLfloat light_spotexp[]  = { 3.0f };
    glClearColor (0.0, 0.0, 0.0, 0.0);
    //glShadeModel (GL_SMOOTH);

    glMatrixPushEXT( GL_MODELVIEW );
    glMatrixLoadIdentityEXT( GL_MODELVIEW );

    glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
    glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, mat_shininess);
    //glMaterialfv(GL_BACK, GL_SHININESS, mat_shininess);
    glLightfv(GL_LIGHT0, GL_POSITION, light_position);
    glLightf( GL_LIGHT0, GL_LINEAR_ATTENUATION, light_atten[1] );
    glLightf( GL_LIGHT0, GL_QUADRATIC_ATTENUATION, light_atten[2] );
    glLightfv( GL_LIGHT0, GL_DIFFUSE, light_diffuse );
    glLightfv( GL_LIGHT0, GL_SPECULAR, light_specular );
    glLightfv( GL_LIGHT0, GL_SPOT_DIRECTION, light_spotdir );
    glLightfv( GL_LIGHT0, GL_SPOT_CUTOFF, light_spotcut );
    glLightfv( GL_LIGHT0, GL_SPOT_EXPONENT, light_spotexp );
    //GLfloat light_ambient[] = { 0.0, -1.0, 0.0, 0.0 };
    //glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);

    glMatrixPopEXT( GL_MODELVIEW );

    glLightModeli( GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE );
    glLightModelf( GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR );

    glEnable( GL_COLOR_MATERIAL ) ;
    glColorMaterial( GL_BACK, GL_SPECULAR );

    glLightModeli( GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE );

    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);

    glFogi( GL_FOG_MODE, GL_LINEAR );
    glFogf( GL_FOG_START, 2.0f );
    glFogf( GL_FOG_END, 4.0f );
    GLfloat fog_color[] = { 1.0, 1.0, 0.0, 0.0 };
    glFogfv( GL_FOG_COLOR, fog_color );

    glEnable( GL_CLIP_PLANE3 );
    GLdouble clip[] = { 1, 1, -1, 0 };
    glClipPlane( GL_CLIP_PLANE3, clip );

    glPopGroupMarkerEXT();
}
void  agg_renderer<T>::process(shield_symbolizer const& sym,
                               mapnik::feature_impl & feature,
                               proj_transform const& prj_trans)
{


    for (std::list<feature_ptr>::iterator f = featureList_->begin(); f != featureList_->end(); f++) {
        feature_ptr featurePtr = *f;

    shield_symbolizer_helper<face_manager<freetype_engine>,
        label_collision_detector4> helper(
            sym, *featurePtr, prj_trans,
            width_, height_,
            scale_factor_,
            t_, font_manager_, *detector_,
            query_extent_);

    text_renderer<T> ren(*current_buffer_,
                         font_manager_,
                         *(font_manager_.get_stroker()),
                         sym.comp_op(),
                         scale_factor_);

    while (helper.next())
    {
        placements_type const& placements = helper.placements();
        for (unsigned int ii = 0; ii < placements.size(); ++ii)
        {
            // get_marker_position returns (minx,miny) corner position,
            // while (currently only) agg_renderer::render_marker newly
            // expects center position;
            // until all renderers and shield_symbolizer_helper are
            // modified accordingly, we must adjust the position here
             pixel_position pos = helper.get_marker_position(placements[ii]);
            // pos.x += 0.5 * helper.get_marker_width();
            // pos.y += 0.5 * helper.get_marker_height();
            // render_marker(pos,
            //               helper.get_marker(),
            //               helper.get_image_transform(),
            //               sym.get_opacity(),
            //               sym.comp_op());


          marker const& marker_ = helper.get_marker();

          image_data_32 const& src = **marker_.get_bitmap_data();
          double width =  src.width();
          double height =  src.height();

          const double shifted = 0;
          double markerX = pos.x + shifted, markerY = height_ - pos.y - shifted - height;



  glMatrixLoadIdentityEXT(GL_PROJECTION);
  glMatrixOrthoEXT(GL_PROJECTION, 0, width_, height_, 0, -1, 1);
  glMatrixLoadIdentityEXT(GL_MODELVIEW);


  GLubyte cmd[5];  
  GLfloat coord[8];
  int m = 0, n = 0;


  cmd[m++] = GL_MOVE_TO_NV;
  coord[n++] = markerX;
  coord[n++] = markerY;
  cmd[m++] = GL_LINE_TO_NV;
  coord[n++] = markerX + width;
  coord[n++] = markerY;
  cmd[m++] = GL_LINE_TO_NV;
  coord[n++] = markerX + width;
  coord[n++] = markerY + height;
  cmd[m++] = GL_LINE_TO_NV;
  coord[n++] = markerX;
  coord[n++] = markerY + height;
  cmd[m++] = GL_CLOSE_PATH_NV;

  glPathCommandsNV(pathObject_, m, cmd, n, GL_FLOAT, coord);



  // glStencilFunc(GL_NOTEQUAL, 0, 0x1F);
  // glStencilOp(GL_KEEP, GL_KEEP, GL_ZERO);


  //makeFaceTexture(TEXTURE_FACE);
  static GLuint texName;
  glGenTextures(1, &texName);
  glBindTexture(GL_TEXTURE_2D, texName);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0,
    GL_RGBA, GL_UNSIGNED_BYTE, (unsigned char *)src.getBytes());


  glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);




  GLfloat data[2][3] = { { 1,0,0 },    /* s = 1*x + 0*y + 0 */
                         { 0,1,0 } };  /* t = 0*x + 1*y + 0 */

  //glEnable(GL_STENCIL_TEST);
  
    //glColor3f(1,1,1);
    glEnable(GL_TEXTURE_2D);
    glPathTexGenNV(GL_TEXTURE0, GL_PATH_OBJECT_BOUNDING_BOX_NV, 2, &data[0][0]);
    glStencilFillPathNV(pathObject_, GL_COUNT_UP_NV, 0x1F);
    glCoverFillPathNV(pathObject_, GL_BOUNDING_BOX_NV);
    glDisable(GL_TEXTURE_2D);

    pathObject_++;


            //Text rendering
            //ren.prepare_glyphs(placements[ii]);
            //ren.render(placements[ii].center);

             const int size = placements[ii].num_nodes();
            int strokeEnable = 0;
            char word[size]; 
            unsigned red,green,blue,alpha;
            double textWidth = 0;
            double textHeight = 0;
            color textColor,strokeColor;
            double opacity = 0.0;


             for (int i = 0; i < placements[ii].num_nodes(); i++)
            {
              char_info_ptr c;
              double x, y, angle;

             placements[ii].vertex(&c, &x, &y, &angle);
             word[i] = (char)c->c;
              textWidth += c->width;
            textHeight = c->height();

              double halo_radius = c->format->halo_radius;

                if (halo_radius > 0.0 && halo_radius < 1024.0){
                  strokeEnable = 1;
                  // red = c->format->halo_fill.red();
                  // green = c->format->halo_fill.green();
                  // blue = c->format->halo_fill.blue();
                  // alpha = c->format->halo_fill.alpha();
                  strokeColor = c->format->halo_fill;

                } 

               textColor = c->format->fill;
               opacity = c->format->text_opacity;
            }

           double posX = placements[ii].center.x, posY = placements[ii].center.y;

           int centerText = textWidth / 2;
           double posTextY = height_ - markerY - (height)/2;
           double posTextX = posX - centerText;

           if(posTextY <= height_ / 2) posTextY -= 5;
           if(posTextX >= width_ / 2) posTextX += 5;


           if(!strokeEnable){
            render_text(size, word, posTextX, posTextY,textColor, opacity);  
           }

           if(strokeEnable){
            render_text(size, word, posTextX, posTextY,textColor,strokeColor,opacity);  
           }




        }
    }

  }
}
示例#8
0
bool agg_renderer<T>::setupOpenGL(Map const &m) {

    // Start setting up OpenGL
    int argc = 0;
    char **argv = NULL;

    glutInit(&argc, argv);
    glutInitWindowSize(width_, height_);
    glutCreateWindow("map_rendering");
    glutHideWindow();
    glutInitDisplayMode(GLUT_RGBA | GLUT_MULTISAMPLE | GLUT_DEPTH | GLUT_STENCIL);

    int statusGlew = glewInit();

    if (statusGlew != GLEW_OK) {
        fprintf(stderr, "%s\n", "OpenGL Extension Wrangler (GLEW) failed to initialize");
        exit(1);
    }

    // Disable Vsync
    Display *dpy = glXGetCurrentDisplay();
    GLXDrawable drawable = glXGetCurrentDrawable();
    const int interval = 0;

    if (drawable) {
        glXSwapIntervalEXT(dpy, drawable, interval);
    }

    // Temporary disable
    // if (!glewIsSupported("GL_EXT_direct_state_access")) {
    //     fprintf(stderr, "%s\n", "OpenGL implementation doesn't support GL_EXT_direct_state_access (you should be using NVIDIA GPUs...)");
    //     exit(1);
    // }

    initializeNVPR("Mapnik GPU");
    if (!has_NV_path_rendering) {
        fprintf(stderr, "%s\n", "required NV_path_rendering OpenGL extension is not present");
        exit(1);
    }

    // Create initial shader program (srcOver)
    // currentProgram_ = createProgram(src_over);
    // currentShader_  = src_over;

    // glUseProgram(currentProgram_);

    // checkOpenGLError("Check error after set up initial program")

    // Initialize textures
    glGenTextures(4, textureArray_);

    for (unsigned int i = 0; i < 3; i++) {
        glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, textureArray_[i]);
        glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 16, GL_RGBA, width_, height_, GL_TRUE);
    }

    glBindTexture(GL_TEXTURE_2D, textureArray_[3]);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width_, height_, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);

    mainTexture_     = textureArray_[0];
    styleTexture_    = textureArray_[1];
    featureTexture_  = textureArray_[2];
    blankTexture_    = textureArray_[3];

    // For texture compositing
    listIndex_ = glGenLists(1);
    glNewList(listIndex_, GL_COMPILE);
    glBegin(GL_QUADS);
        glMultiTexCoord2f(GL_TEXTURE1, 0, 0); glMultiTexCoord2f(GL_TEXTURE2, 0, 0); glVertex2i(0, 0);
        glMultiTexCoord2f(GL_TEXTURE1, 1, 0); glMultiTexCoord2f(GL_TEXTURE2, 1, 0); glVertex2i(width_, 0);
        glMultiTexCoord2f(GL_TEXTURE1, 1, 1); glMultiTexCoord2f(GL_TEXTURE2, 1, 1); glVertex2i(width_, height_);
        glMultiTexCoord2f(GL_TEXTURE1, 0, 1); glMultiTexCoord2f(GL_TEXTURE2, 0, 1); glVertex2i(0, height_);
    glEnd();
    glEndList();

    // For texture cleaning
    rectDrawingIndex_ = glGenLists(1);
    glNewList(rectDrawingIndex_, GL_COMPILE);
    glBegin(GL_QUADS);
        glVertex2i(0, 0);
        glVertex2i(width_, 0);
        glVertex2i(width_, height_);
        glVertex2i(0, height_);
    glEnd();
    glEndList();

    glMatrixLoadIdentityEXT(GL_PROJECTION);
    glMatrixLoadIdentityEXT(GL_MODELVIEW);
    glMatrixOrthoEXT(GL_MODELVIEW, 0, width_, 0, height_, -1, 1);

    // Create frame buffer blit object
    glGenFramebuffers(1, &frameBufferBlit_);
    glBindFramebuffer(GL_FRAMEBUFFER, frameBufferBlit_);

    // Create color buffer
    glGenRenderbuffers(1, &colorBufferBlit_);
    glBindRenderbuffer(GL_RENDERBUFFER, colorBufferBlit_);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, width_, height_);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorBufferBlit_);

    glGenRenderbuffers(1, &depthBufferBlit_);
    glBindRenderbuffer(GL_RENDERBUFFER, depthBufferBlit_);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width_, height_);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthBufferBlit_);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depthBufferBlit_);

    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, blankTexture_, 0);

    // -----------------------------------------------------------------------------------------------

    // Create frame buffer object
    glGenFramebuffers(1, &frameBuffer_);
    glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer_);

    // Create color buffer
    glGenRenderbuffers(1, &colorBuffer_);
    glBindRenderbuffer(GL_RENDERBUFFER, colorBuffer_);
    glRenderbufferStorageMultisample(GL_RENDERBUFFER, 16, GL_RGBA8, width_, height_);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorBuffer_);

    glGenRenderbuffers(1, &depthBuffer_);
    glBindRenderbuffer(GL_RENDERBUFFER, depthBuffer_);
    glRenderbufferStorageMultisample(GL_RENDERBUFFER, 16, GL_DEPTH24_STENCIL8, width_, height_);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthBuffer_);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depthBuffer_);

    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, mainTexture_, 0);

    GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);

    if (status == GL_FRAMEBUFFER_COMPLETE) {
        // You have succeeded!
        glClearStencil(0);
        glClearColor(0, 0, 0, 0); // White BG
        glStencilMask(~0);
        glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        glEnable(GL_STENCIL_TEST);
        glStencilFunc(GL_NOTEQUAL, 0, 0x1F);
        glStencilOp(GL_KEEP, GL_KEEP, GL_ZERO);
    } else {
        // You are all about failure.
        switch(status){

            case GL_FRAMEBUFFER_UNDEFINED:
                 fprintf(stderr, "GL_FRAMEBUFFER_UNDEFINED\n");
                 break;

            case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
                fprintf(stderr, "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT\n");
                 break;

            case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
                fprintf(stderr, "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT\n");

                break;

            case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
            fprintf(stderr, "GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER\n");
                break;

            case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
            fprintf(stderr, "GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER\n");
                break;

            case GL_FRAMEBUFFER_UNSUPPORTED:
            fprintf(stderr, "GL_FRAMEBUFFER_UNSUPPORTED\n");
                break;

            case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:
            fprintf(stderr, "GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE\n");
                break;

            case GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS:
            fprintf(stderr, "GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS\n");
                break;

            default:
            fprintf(stderr, "else\n");
            break;

        }


        exit(1);
    }

    // Set up background
    boost::optional<color> const& bg = m.background();
    if (bg) {
        cleanTexture(mainTexture_, bg->red(), bg->green(), bg->blue(), bg->alpha());
        //cleanTexture(featureTexture_, 255, 255, 255, 0);
    }

    // TODO: Background image
    return true;

}