1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
|
int CVirtualRobot::GetImage(CImageBase *img, GLuint *fbo, GLuint *depthb, GLuint *colorb) {
// get display infos
int width = glutGet(GLUT_WINDOW_WIDTH);
int height = glutGet(GLUT_WINDOW_HEIGHT);
int bpp = glutGet(GLUT_WINDOW_RGBA) ? 4 : 3;
GLenum format = (bpp==4) ? GL_RGBA : GL_RGB;
// select on which FBO to operate
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, *fbo);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, *depthb);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT32, width, height);
// attach renderbuffer to framebuffer depth buffer
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, *depthb);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, *colorb);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, format, width, height);
// attach renderbuffer to framebuffer color buffer
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, *colorb);
// Draw Scene
Draw(true);
glFlush();
glutPostRedisplay();
// create buffer
unsigned char *buf = new unsigned char[width*height*bpp];
// read from front buffer
glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
// read pixels from framebuffer, FIXME: better use "render to texture"
glReadPixels(0,0,width,height,format,GL_UNSIGNED_BYTE,buf);
// make everything fit into the image
(*img).EnsureImageType(CColorModel_RGB(),CStorageType<uchar>());
if (bpp==3) {
for (int x=0;x<width;x++)
for (int y=0;y<height;y++) {
for (int c=0;c<bpp;c++) {
(*reinterpret_cast<unsigned char*>((*img)(x,height-y-1,c))) = buf[(x+width*y)*bpp+c];
}
}
} else {
for (int x=0;x<width;x++)
for (int y=0;y<height;y++) {
for (int c=0;c<bpp-1;c++) {
(*reinterpret_cast<unsigned char*>((*img)(x,height-y-1,c))) = buf[(x+width*y)*bpp+c];
}
}
}
return 0;
}
| |