I have tried to do offscreen rendering in my linux server(a virtual machine with no graphics card and no window system) by OSMesa, refer to the osmesa demo osdemos. Every thing works fine.
For antialiasing, i tried to create a multisamping render buffer to bind to FBO, but result with GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT, the single sampled render buffer works fine. here is the code to create the FBO, change the sample_number for 1, works fine, for 4 with GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT error. Any suggestions are appricate.
#define GL_GLEXT_PROTOTYPES
#include <GL/glu.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <vector>
#include <iostream>
#include "GL/osmesa.h"
#include <GL/glut.h>
const int Width = 1920;
const int Height = 1080;
int main(int argc, char *argv[])
{
OSMesaContext ctx;
void *buffer;
#if OSMESA_MAJOR_VERSION * 100 + OSMESA_MINOR_VERSION >= 305
ctx = OSMesaCreateContextExt( OSMESA_RGBA, 32, 0, 0, NULL );
#else
ctx = OSMesaCreateContext( OSMESA_RGBA, NULL );
#endif
if (!ctx) {
printf("OSMesaCreateContext failed!\n");
return 0;
}
buffer = malloc( Width * Height * 4 * sizeof(GLubyte) );
if (!buffer) {
printf("Alloc image buffer failed!\n");
return 0;
}
if (!OSMesaMakeCurrent( ctx, buffer, GL_UNSIGNED_BYTE, Width, Height )) {
printf("OSMesaMakeCurrent failed!\n");
return 0;
}
int render_width = 200, render_height = 200;
enum { Color, Depth, NumRenderbuffers };
// multi-sampled frame buffer object as the draw target
GLuint framebuffer_ms, renderbuffer_ms[NumRenderbuffers];
// generate color and depth render buffers and allocate storage for the multi-sampled FBO
glGenRenderbuffers(NumRenderbuffers, renderbuffer_ms);
glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer_ms[Color]);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, // here set 1 works fine
GL_RGBA8, render_width, render_height);
glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer_ms[Depth]);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, // here set 1 works fine
GL_DEPTH_COMPONENT24, render_width, render_height);
// generate frame buffer object for the multi-sampled FBO
glGenFramebuffers(1, &framebuffer_ms);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer_ms);
glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_RENDERBUFFER, renderbuffer_ms[Color]);
glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
GL_RENDERBUFFER, renderbuffer_ms[Depth]);
auto status = glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER);
if (status == GL_FRAMEBUFFER_COMPLETE) {
std::cout << "fbo status fine!!!" << std::endl;
} else {
std::cout << "Failed:" << status << std::endl;
}
exit(__LINE__);
// render_image();
// std::vector<GLubyte> data(width *height * 4);
// glReadBuffer(GL_COLOR_ATTACHMENT0);
// glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, data.data());
// write_targa(data.data(), width, height);
glDeleteFramebuffers(1, &framebuffer_ms);
glDeleteRenderbuffers(2, renderbuffer_ms);
free(buffer);
return 0;
}