FrameBufferGLX.cc

Go to the documentation of this file.
00001 #include <gra/framebuffer/FrameBufferGLX.h>
00002 
00003 using namespace gra;
00004 
00005 void FrameBufferGLX::_init(const char * name)
00006 {
00007     int visualAttr[11] = { GLX_RED_SIZE,   1,
00008                            GLX_GREEN_SIZE, 1,
00009                            GLX_BLUE_SIZE,  1,
00010                            GLX_RGBA, None, None, None, None };
00011     int i = 7;
00012     if (!(_fbMode & FB_RGBA))
00013         cerr << "FrameBufferGLX: Switching to RGBA mode" << endl;
00014     if (_fbMode & FB_DOUBLE) visualAttr[i++] = GLX_DOUBLEBUFFER;
00015     if (_fbMode & FB_DEPTH) {
00016         visualAttr[i++] = GLX_DEPTH_SIZE;
00017         visualAttr[i++] = 1;
00018     } else {
00019         visualAttr[i++] = GLX_DEPTH_SIZE;
00020         visualAttr[i++] = 0;
00021     }
00022     
00023     _pDisplay    = NULL;
00024     _pVisualInfo = NULL;
00025     _pImage      = NULL;
00026 
00027     /* get a connection */
00028     if (!(_pDisplay = XOpenDisplay(name))) {
00029         cerr << "FrameBufferGLX: Unable to open X display" << endl;
00030         return;
00031     }
00032 
00033     if (! glXQueryExtension(_pDisplay, NULL, NULL)) {
00034         cerr << "FrameBufferGLX: GLX extension is not supported by X server" << endl;
00035         return;
00036     }
00037 
00038     /* get an appropriate visual */
00039     if (!(_pVisualInfo = glXChooseVisual(_pDisplay,
00040                                          DefaultScreen(_pDisplay),
00041                                          visualAttr)))
00042     {
00043         cerr << "FrameBufferGLX: Unable to get X visual" << endl;
00044         return;
00045     }
00046 
00047     /* set attributes necessary for corrent conversion from our colors to */
00048     /* display colors                                                     */
00049     _shiftRed   = ffs(_pVisualInfo->red_mask)   - 1;
00050     _shiftGreen = ffs(_pVisualInfo->green_mask) - 1;
00051     _shiftBlue  = ffs(_pVisualInfo->blue_mask)  - 1;
00052 
00053 #if BYTE_ORDER == BIG_ENDIAN 
00054     _byteRev = (ImageByteOrder(_pDisplay) != MSBFirst);
00055 #else
00056     _byteRev = (ImageByteOrder(_pDisplay) != LSBFirst);
00057 #endif
00058 
00059 
00060     /* create a GLX context */
00061     _context = glXCreateContext(_pDisplay, _pVisualInfo, 0, GL_TRUE);
00062 
00063     /* create a window */
00064     _winAttr.colormap = XCreateColormap(_pDisplay,
00065                                         RootWindow(_pDisplay,
00066                                                    _pVisualInfo->screen),
00067                                         _pVisualInfo->visual,
00068                                         AllocNone);
00069     _winAttr.border_pixel = 0;
00070     _winAttr.event_mask = StructureNotifyMask;
00071     _win = XCreateWindow(_pDisplay,
00072                          RootWindow(_pDisplay, _pVisualInfo->screen),
00073                          0, 0, _width, _height, 0,
00074                          _pVisualInfo->depth, InputOutput,
00075                          _pVisualInfo->visual,
00076                          CWBorderPixel|CWColormap|CWEventMask,
00077                          &_winAttr);
00078     XMapWindow(_pDisplay, _win);
00079     //XIfEvent(_pDisplay, &_event, WaitForNotify, (char*)_win);
00080 
00081     /* create a graphics context for drawing */
00082     _gcValues.function = GXcopy;
00083     _gc = XCreateGC(_pDisplay, _win, GCFunction, &_gcValues);
00084 
00085 
00086     /* Allocate and create XImage to save the image if it gets covered */
00087     if (!(_pImage = XCreateImage(_pDisplay,
00088                                  _pVisualInfo->visual,
00089                                  _pVisualInfo->depth,
00090                                  ZPixmap,
00091                                  0,
00092                                  NULL,
00093                                  _width,
00094                                  _height,
00095                                  BitmapPad(_pDisplay),
00096                                  0)))
00097     {
00098         cerr << "FrameBufferGLX: Unable to create X image" << endl;
00099         return;
00100     }
00101 
00102     if (!(_pImage->data=(char *)calloc(1, _pImage->bytes_per_line*_height))) {
00103         cerr << "FrameBufferGLX: Unable to allocate data in the X image" << endl;
00104         return;
00105     }
00106 
00107     /* connect the context to the window */
00108     glXMakeCurrent(_pDisplay, _win, _context);
00109 }
00110 
00111 void FrameBufferGLX::_destroy()
00112 {
00113     if (_pImage) {
00114         if (_pImage->data) {
00115             free(_pImage->data);
00116             _pImage->data = NULL;
00117         }
00118         XDestroyImage(_pImage);
00119         _pImage = NULL;
00120     }
00121     if (_winAttr.colormap != None) {
00122         XFreeColormap(_pDisplay, _winAttr.colormap);
00123         _winAttr.colormap = None;
00124     }
00125     if (_pVisualInfo) {
00126         XFree(_pVisualInfo);
00127         _pVisualInfo = NULL;
00128     }
00129     if (_pDisplay) {
00130         XDestroyWindow(_pDisplay, _win);
00131         glXDestroyContext(_pDisplay, _context);
00132         XCloseDisplay(_pDisplay);
00133         _pDisplay = NULL;
00134     }
00135 }
00136 
00137 void FrameBufferGLX::setWidth(unsigned w)
00138 {
00139     _width = w;
00140 
00141     if (_pDisplay) return;
00142     
00143     XResizeWindow(_pDisplay, _win, _width, _height);
00144     
00145     if (_pImage) {
00146         if (_pImage->data) {
00147             free(_pImage->data);
00148             _pImage->data = NULL;
00149         }
00150         XDestroyImage(_pImage);
00151         _pImage = NULL;
00152     }
00153 
00154     /* Allocate and create XImage to save the image if it gets covered */
00155     if (!(_pImage = XCreateImage(_pDisplay,
00156                                  _pVisualInfo->visual,
00157                                  _pVisualInfo->depth,
00158                                  ZPixmap,
00159                                  0,
00160                                  NULL,
00161                                  _width,
00162                                  _height,
00163                                  BitmapPad(_pDisplay),
00164                                  0)))
00165     {
00166         cerr << "FrameBufferGLX::setWidth(): Unable to create X image" << endl;
00167         return;
00168     }
00169 
00170     if (!(_pImage->data=(char *)calloc(1, _pImage->bytes_per_line*_height))) {
00171         cerr << "FrameBufferGLX::setWidth(): Unable to allocate data in the X image" << endl;
00172         return;
00173     }
00174 }
00175 
00176 void FrameBufferGLX::setHeight(unsigned h)
00177 {
00178     _height = h;
00179     
00180     if (_pDisplay) return;
00181 
00182     XResizeWindow(_pDisplay, _win, _width, _height);
00183 
00184     if (_pImage) {
00185         if (_pImage->data) {
00186             free(_pImage->data);
00187             _pImage->data = NULL;
00188         }
00189         XDestroyImage(_pImage);
00190         _pImage = NULL;
00191     }
00192 
00193     /* Allocate and create XImage to save the image if it gets covered */
00194     if (!(_pImage = XCreateImage(_pDisplay,
00195                                  _pVisualInfo->visual,
00196                                  _pVisualInfo->depth,
00197                                  ZPixmap,
00198                                  0,
00199                                  NULL,
00200                                  _width,
00201                                  _height,
00202                                  BitmapPad(_pDisplay),
00203                                  0)))
00204     {
00205         cerr << "FrameBufferGLX::setHeight(): Unable to create X image" << endl;
00206         return;
00207     }
00208 
00209     if (!(_pImage->data=(char *)calloc(1, _pImage->bytes_per_line*_height))) {
00210         cerr << "FrameBufferGLX::setHeight(): Unable to allocate data in the X image" << endl;
00211         return;
00212     }
00213 }
00214 
00215 void FrameBufferGLX::showContent()
00216 {
00217     if (!_pDisplay || !_pImage) return;
00218     if (_fbMode & FB_DOUBLE) glXSwapBuffers(_pDisplay, _win);
00219     XPutImage(_pDisplay, _win, _gc, _pImage, 0, 0, 0, 0,
00220           _pImage->width, _pImage->height);
00221     //glFlush();
00222 }
00223 
00224 void FrameBufferGLX::setColor(const Camera&  camera,
00225                               unsigned       x,
00226                               unsigned       y,
00227                               float          , // depth is ignored
00228                               const Color3f& color)
00229 {
00230     // to do
00231     cerr << "FrameBufferGLX::setColor(): Depth of pixels is not supported" << endl;
00232     setColor(camera, x, y, color);
00233 }
00234 
00235 void FrameBufferGLX::setColor(const Camera&  , // camera is ignored
00236                               unsigned       x,
00237                               unsigned       y,
00238                               const Color3f& color)
00239 {
00240     if (!_pVisualInfo || !_pDisplay) return;
00241 
00242     unsigned long r = (unsigned long)(color.x * 255.0);
00243     unsigned long g = (unsigned long)(color.y * 255.0);
00244     unsigned long b = (unsigned long)(color.z * 255.0);
00245 
00246     // clip values
00247     if (r > 255) r = 255;
00248     if (g > 255) g = 255;
00249     if (b > 255) b = 255;
00250 
00251     unsigned long pixel =
00252         ((_byteRev) ?
00253          (b << _shiftRed) | (g << _shiftGreen) | (r << _shiftBlue) :
00254          (r << _shiftRed) | (g << _shiftGreen) | (b << _shiftBlue));
00255 
00256     unsigned posy = _height - 1 - y;
00257 
00258     XPutPixel(_pImage, x, posy, pixel);
00259     XPutImage(_pDisplay, _win, _gc, _pImage, x, posy, x, posy, 1, 1);
00260 }
00261 
00262 void FrameBufferGLX::setColors(const Camera& camera,
00263                                unsigned      x,
00264                                unsigned      y,
00265                                float         depth,
00266                                const Color3f colors[],
00267                                unsigned      size)
00268 {
00269     fprintf(stderr,"FrameBufferGL::setColors(): To do");
00270     // to do
00271 }
00272 
00273 void FrameBufferGLX::setColors(const Camera& camera,
00274                                unsigned      x,
00275                                unsigned      y,
00276                                const Color3f colors[],
00277                                unsigned      size)
00278 {
00279     unsigned long xpos = x;
00280     unsigned long ypos = y;
00281 
00282     for (unsigned i = 0; i < size; i++) {
00283         if (xpos >= _width) { xpos = 0; ypos--; }
00284         setColor(camera, xpos++, ypos, colors[i]);
00285     }
00286 
00287     XPutImage(_pDisplay, _win, _gc, _pImage, 0, 0, 0, 0,
00288               _pImage->width, _pImage->height);
00289 }
00290 
00291 Color3f FrameBufferGLX::getColor(unsigned x, unsigned y) const
00292 {
00293     Color3f c;
00294     if (!_pImage || !_pVisualInfo) return c;
00295     
00296     unsigned long pixel = XGetPixel(_pImage, x, _height-y);
00297 
00298     float r = ((float)((pixel & _pVisualInfo->red_mask) >> _shiftRed) /
00299                (float)(_pVisualInfo->red_mask >> _shiftRed));
00300     float g = ((float)((pixel & _pVisualInfo->green_mask) >> _shiftGreen) /
00301                (float)(_pVisualInfo->green_mask >> _shiftGreen));
00302     float b = ((float)((pixel & _pVisualInfo->blue_mask) >> _shiftBlue) /
00303                (float)(_pVisualInfo->blue_mask >> _shiftBlue));
00304 
00305     (_byteRev) ? c.set(b,g,r) : c.set(r,g,b);
00306     return c;
00307 }
00308 
00309 void FrameBufferGLX::clearColor(const Color3f& color)
00310 {
00311     glClearColor(color.x, color.y, color.z, 1.0);
00312     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00313     if (_fbMode & FB_DOUBLE) glXSwapBuffers(_pDisplay, _win);
00314 }

Generated on Tue Nov 21 15:11:42 2006 for gra by  doxygen 1.4.6