Main Page Namespace List Class Hierarchy Alphabetical List Compound List File List Namespace Members Compound Members File Members Related Pages

# OgreGLXWindow.cpp

Go to the documentation of this file.

    00001 /*
    00002 -----------------------------------------------------------------------------
    00003 This source file is part of OGRE
    00004     (Object-oriented Graphics Rendering Engine)
    00005 For the latest info, see http://www.ogre3d.org/
    00006
    00007 Copyright ? 2000-2004 The OGRE Team
    00008 Also see acknowledgements in Readme.html
    00009
    00010 This program is free software; you can redistribute it and/or modify it under
    00011 the terms of the GNU Lesser General Public License as published by the Free Software
    00012 Foundation; either version 2 of the License, or (at your option) any later
    00013 version.
    00014
    00015 This program is distributed in the hope that it will be useful, but WITHOUT
    00016 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    00017 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
    00018
    00019 You should have received a copy of the GNU Lesser General Public License along with
    00020 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
    00021 Place - Suite 330, Boston, MA 02111-1307, USA, or go to
    00022 http://www.gnu.org/copyleft/lesser.txt.
    00023 -----------------------------------------------------------------------------
    00024 */
    00025
    00026 #include "OgreGLXWindow.h"
    00027 #include "OgreRoot.h"
    00028 #include "OgreRenderSystem.h"
    00029 #include "OgreImageCodec.h"
    00030 #include "OgreException.h"
    00031 #include "OgreLogManager.h"
    00032 #include "OgreStringConverter.h"
    00033
    00034 #include <iostream>
    00035 #include <algorithm>
    00036 #include <sys/time.h>
    00037 #include <climits>
    00038
    00039 #include <X11/Xlib.h>
    00040 #include <X11/keysym.h>
    00041
    00042 #ifndef NO_XRANDR
    00043 #include <X11/extensions/Xrandr.h>
    00044 #endif
    00045
    00046 #include <GL/gl.h>
    00047 #include <GL/glu.h>
    00048 #include <GL/glx.h>
    00049
    00050
    00051 namespace Ogre {
    00052
    00053 GLXWindow::GLXWindow(Display *display) :
    00054         mDisplay(display),
    00055         mWindow(0),
    00056         mGlxContext(0),
    00057 mActive(false), mClosed(false),mFullScreen(false), mOldMode(-1) {}
    00058
    00059 GLXWindow::~GLXWindow() {
    00060     if(mGlxContext)
    00061         glXDestroyContext(mDisplay, mGlxContext);
    00062     if(mWindow)
    00063         XDestroyWindow(mDisplay, mWindow);
    00064 #ifndef NO_XRANDR
    00065
    00066     if(mFullScreen) {
    00067         // Restore original video mode.
    00068         Window rootWindow = DefaultRootWindow(mDisplay);
    00069         XRRScreenConfiguration *config;
    00070
    00071         // Get current screen info
    00072         config = XRRGetScreenInfo(mDisplay, rootWindow);
    00073         if(config) {
    00074             Rotation current_rotation;
    00075             XRRConfigCurrentConfiguration (config, &current_rotation);
    00076             //std::cerr << "Restore mode " << mOldMode << std::endl;
    00077             LogManager::getSingleton().logMessage("GLXWindow::~GLXWindow -- Leaving full screen mode");
    00078             XRRSetScreenConfig(mDisplay, config, rootWindow, mOldMode, current_rotation, CurrentTime);
    00079             XRRFreeScreenConfigInfo(config);
    00080         } else {
    00081             LogManager::getSingleton().logMessage("GLXWindow::~GLXWindow -- Could not switch from full screen mode: XRRGetScreenInfo failed");
    00082         }
    00083     }
    00084 #endif
    00085 }
    00086
    00087 namespace {
    00088
    00100 bool LoadIcon(Display *mDisplay, Window rootWindow, const std::string &name, Pixmap *pix, Pixmap *mask) {
    00101     Image img;
    00102     int mWidth, mHeight;
    00103     char *data, *bitmap;
    00104     try {
    00105         // Try to load image
    00106         img.load(name);
    00107         mWidth = img.getWidth();
    00108         mHeight = img.getHeight();
    00109         if(img.getFormat() != PF_A8R8G8B8)
    00110             // Image format must be RGBA
    00111             return 0;
    00112     } catch(Exception &e) {
    00113         // Could not find image; never mind
    00114         return false;
    00115     }
    00116
    00117     // Allocate space for image data
    00118     data = (char*)malloc(mWidth * mHeight * 4); // Must be allocated with malloc
    00119     // Allocate space for transparency bitmap
    00120     int wbits = (mWidth+7)/8;
    00121     bitmap = (char*)malloc(wbits * mHeight);
    00122
    00123     // Convert and copy image
    00124     const char *imgdata = (const char*)img.getData();
    00125     int sptr = 0, dptr = 0;
    00126     for(int y=0; y<mHeight; y++) {
    00127         for(int x=0; x<mWidth; x++) {
    00128             data[dptr + 0] = 0;
    00129             data[dptr + 1] = imgdata[sptr + 0];
    00130             data[dptr + 2] = imgdata[sptr + 1];
    00131             data[dptr + 3] = imgdata[sptr + 2];
    00132             // Alpha threshold
    00133             if(((unsigned char)imgdata[sptr + 3])<128) {
    00134                 bitmap[y*wbits+(x>>3)] &= ~(1<<(x&7));
    00135             } else {
    00136                 bitmap[y*wbits+(x>>3)] |= 1<<(x&7);
    00137             }
    00138             sptr += 4;
    00139             dptr += 4;
    00140         }
    00141     }
    00142
    00143     /* put my pixmap data into the client side X image data structure */
    00144     XImage *image = XCreateImage (mDisplay, NULL, 24, ZPixmap, 0,
    00145                                   data,
    00146                                   mWidth, mHeight, 8,
    00147                                   mWidth*4);
    00148     image->byte_order = MSBFirst; // 0RGB format
    00149
    00150     /* tell server to start managing my pixmap */
    00151     Pixmap retval = XCreatePixmap(mDisplay, rootWindow, mWidth,
    00152                                   mHeight, 24);
    00153
    00154     /* copy from client to server */
    00155     GC context = XCreateGC (mDisplay, rootWindow, 0, NULL);
    00156     XPutImage(mDisplay, retval, context, image, 0, 0, 0, 0,
    00157               mWidth, mHeight);
    00158
    00159     /* free up the client side pixmap data area */
    00160     XDestroyImage(image); // also cleans data
    00161     XFreeGC(mDisplay, context);
    00162
    00163     *pix = retval;
    00164     *mask = XCreateBitmapFromData(mDisplay, rootWindow, bitmap, mWidth, mHeight);
    00165     free(bitmap);
    00166     return true;
    00167 }
    00168
    00169 struct visual_attribs
    00170 {
    00171    /* X visual attribs */
    00172    int id;
    00173    int klass;
    00174    int depth;
    00175    int redMask, greenMask, blueMask;
    00176    int colormapSize;
    00177    int bitsPerRGB;
    00178
    00179    /* GL visual attribs */
    00180    int supportsGL;
    00181    int transparentType;
    00182    int transparentRedValue;
    00183    int transparentGreenValue;
    00184    int transparentBlueValue;
    00185    int transparentAlphaValue;
    00186    int transparentIndexValue;
    00187    int bufferSize;
    00188    int level;
    00189    int rgba;
    00190    int doubleBuffer;
    00191    int stereo;
    00192    int auxBuffers;
    00193    int redSize, greenSize, blueSize, alphaSize;
    00194    int depthSize;
    00195    int stencilSize;
    00196    int accumRedSize, accumGreenSize, accumBlueSize, accumAlphaSize;
    00197    int numSamples, numMultisample;
    00198    int visualCaveat;
    00199 };
    00200
    00201
    00202 static void
    00203 get_visual_attribs(Display *dpy, XVisualInfo *vInfo,
    00204                    struct visual_attribs *attribs) {
    00205     const char *ext = glXQueryExtensionsString(dpy, vInfo->screen);
    00206
    00207     memset(attribs, 0, sizeof(struct visual_attribs));
    00208
    00209     attribs->id = vInfo->visualid;
    00210 #if defined(__cplusplus) || defined(c_plusplus)
    00211
    00212     attribs->klass = vInfo->c_class;
    00213 #else
    00214
    00215     attribs->klass = vInfo->class;
    00216 #endif
    00217
    00218     attribs->depth = vInfo->depth;
    00219     attribs->redMask = vInfo->red_mask;
    00220     attribs->greenMask = vInfo->green_mask;
    00221     attribs->blueMask = vInfo->blue_mask;
    00222     attribs->colormapSize = vInfo->colormap_size;
    00223     attribs->bitsPerRGB = vInfo->bits_per_rgb;
    00224
    00225     if (glXGetConfig(dpy, vInfo, GLX_USE_GL, &attribs->supportsGL) != 0)
    00226         return;
    00227     glXGetConfig(dpy, vInfo, GLX_BUFFER_SIZE, &attribs->bufferSize);
    00228     glXGetConfig(dpy, vInfo, GLX_LEVEL, &attribs->level);
    00229     glXGetConfig(dpy, vInfo, GLX_RGBA, &attribs->rgba);
    00230     glXGetConfig(dpy, vInfo, GLX_DOUBLEBUFFER, &attribs->doubleBuffer);
    00231     glXGetConfig(dpy, vInfo, GLX_STEREO, &attribs->stereo);
    00232     glXGetConfig(dpy, vInfo, GLX_AUX_BUFFERS, &attribs->auxBuffers);
    00233     glXGetConfig(dpy, vInfo, GLX_RED_SIZE, &attribs->redSize);
    00234     glXGetConfig(dpy, vInfo, GLX_GREEN_SIZE, &attribs->greenSize);
    00235     glXGetConfig(dpy, vInfo, GLX_BLUE_SIZE, &attribs->blueSize);
    00236     glXGetConfig(dpy, vInfo, GLX_ALPHA_SIZE, &attribs->alphaSize);
    00237     glXGetConfig(dpy, vInfo, GLX_DEPTH_SIZE, &attribs->depthSize);
    00238     glXGetConfig(dpy, vInfo, GLX_STENCIL_SIZE, &attribs->stencilSize);
    00239     glXGetConfig(dpy, vInfo, GLX_ACCUM_RED_SIZE, &attribs->accumRedSize);
    00240     glXGetConfig(dpy, vInfo, GLX_ACCUM_GREEN_SIZE, &attribs->accumGreenSize);
    00241     glXGetConfig(dpy, vInfo, GLX_ACCUM_BLUE_SIZE, &attribs->accumBlueSize);
    00242     glXGetConfig(dpy, vInfo, GLX_ACCUM_ALPHA_SIZE, &attribs->accumAlphaSize);
    00243
    00244     /* get transparent pixel stuff */
    00245     glXGetConfig(dpy, vInfo,GLX_TRANSPARENT_TYPE, &attribs->transparentType);
    00246     if (attribs->transparentType == GLX_TRANSPARENT_RGB) {
    00247         glXGetConfig(dpy, vInfo, GLX_TRANSPARENT_RED_VALUE, &attribs->transparentRedValue);
    00248         glXGetConfig(dpy, vInfo, GLX_TRANSPARENT_GREEN_VALUE, &attribs->transparentGreenValue);
    00249         glXGetConfig(dpy, vInfo, GLX_TRANSPARENT_BLUE_VALUE, &attribs->transparentBlueValue);
    00250         glXGetConfig(dpy, vInfo, GLX_TRANSPARENT_ALPHA_VALUE, &attribs->transparentAlphaValue);
    00251     } else if (attribs->transparentType == GLX_TRANSPARENT_INDEX) {
    00252         glXGetConfig(dpy, vInfo, GLX_TRANSPARENT_INDEX_VALUE, &attribs->transparentIndexValue);
    00253     }
    00254
    00255     /* multisample attribs */
    00256 #ifdef GLX_ARB_multisample
    00257     if (ext && strstr("GLX_ARB_multisample", ext) == 0) {
    00258         glXGetConfig(dpy, vInfo, GLX_SAMPLE_BUFFERS_ARB, &attribs->numMultisample);
    00259         glXGetConfig(dpy, vInfo, GLX_SAMPLES_ARB, &attribs->numSamples);
    00260     }
    00261 #endif
    00262     else {
    00263         attribs->numSamples = 0;
    00264         attribs->numMultisample = 0;
    00265     }
    00266
    00267 #if defined(GLX_EXT_visual_rating)
    00268     if (ext && strstr(ext, "GLX_EXT_visual_rating")) {
    00269         glXGetConfig(dpy, vInfo, GLX_VISUAL_CAVEAT_EXT, &attribs->visualCaveat);
    00270     } else {
    00271         attribs->visualCaveat = GLX_NONE_EXT;
    00272     }
    00273 #else
    00274     attribs->visualCaveat = 0;
    00275 #endif
    00276 }
    00277
    00278 /*
    00279  * Examine all visuals to find the so-called best one.
    00280  * We prefer deepest RGBA buffer with depth, stencil and accum
    00281  * that has no caveats.
    00282  * @author Brian Paul (from the glxinfo source)
    00283  */
    00284 int find_best_visual(Display *dpy, int scrnum) {
    00285     XVisualInfo theTemplate;
    00286     XVisualInfo *visuals;
    00287     int numVisuals;
    00288     long mask;
    00289     int i;
    00290     struct visual_attribs bestVis;
    00291
    00292     /* get list of all visuals on this screen */
    00293     theTemplate.screen = scrnum;
    00294     mask = VisualScreenMask;
    00295     visuals = XGetVisualInfo(dpy, mask, &theTemplate, &numVisuals);
    00296     if(numVisuals == 0 || visuals == 0) {
    00297         /* something went wrong */
    00298         if(visuals)
    00299             XFree(visuals);
    00300         return -1;
    00301     }
    00302
    00303     /* init bestVis with first visual info */
    00304     get_visual_attribs(dpy, &visuals[0], &bestVis);
    00305
    00306     /* try to find a "better" visual */
    00307     for (i = 1; i < numVisuals; i++) {
    00308         struct visual_attribs vis;
    00309
    00310         get_visual_attribs(dpy, &visuals[i], &vis);
    00311
    00312         /* always skip visuals with caveats */
    00313         if (vis.visualCaveat != GLX_NONE_EXT)
    00314             continue;
    00315
    00316         /* see if this vis is better than bestVis */
    00317         if ((!bestVis.supportsGL && vis.supportsGL) ||
    00318                         (bestVis.visualCaveat != GLX_NONE_EXT) ||
    00319                         (!bestVis.rgba && vis.rgba) ||
    00320                         (!bestVis.doubleBuffer && vis.doubleBuffer) ||
    00321                         (bestVis.redSize < vis.redSize) ||
    00322                         (bestVis.greenSize < vis.greenSize) ||
    00323                         (bestVis.blueSize < vis.blueSize) ||
    00324                         (bestVis.alphaSize < vis.alphaSize) ||
    00325                         (bestVis.depthSize < vis.depthSize) ||
    00326                         (bestVis.stencilSize < vis.stencilSize) ||
    00327                         (bestVis.accumRedSize < vis.accumRedSize)) {
    00328             /* found a better visual */
    00329             bestVis = vis;
    00330         }
    00331     }
    00332
    00333     XFree(visuals);
    00334
    00335     return bestVis.id;
    00336 }
    00337
    00338 };
    00339
    00340 void GLXWindow::create(const String& name, unsigned int width, unsigned int height, unsigned int colourDepth,
    00341                        bool fullScreen, int left, int top, bool depthBuffer,
    00342                        void* miscParam, ...) {
    00343     std::cerr << "GLXWindow::create" << std::endl;
    00344
    00345     // We will attempt to create new window on default screen op display 0
    00346     int screen = DefaultScreen(mDisplay);
    00347     int depth = DisplayPlanes(mDisplay, screen);
    00348     Window rootWindow = RootWindow(mDisplay,screen);
    00349 #ifndef NO_XRANDR
    00350     // Attempt mode switch for fullscreen -- only if RANDR extension is there
    00351     int dummy;
    00352     if(fullScreen && ! XQueryExtension(mDisplay, "RANDR", &dummy, &dummy, &dummy)) {
    00353             LogManager::getSingleton().logMessage("GLXWindow::create -- Could not switch to full screen mode: No XRANDR extension found");
    00354     } else if(fullScreen) {
    00355         // Use Xrandr extension to switch video modes. This is much better than
    00356         // XVidMode as you can't scroll away from the full-screen applications.
    00357         XRRScreenConfiguration *config;
    00358         XRRScreenSize *sizes;
    00359         Rotation current_rotation;
    00360         int current_size;
    00361         int nsizes;
    00362
    00363         // Get current screen info
    00364         config = XRRGetScreenInfo(mDisplay, rootWindow);
    00365         // Get available sizes
    00366         if(config)
    00367             sizes = XRRConfigSizes (config, &nsizes);
    00368
    00369         if(config && nsizes > 0) {
    00370             // Get current size and rotation
    00371             mOldMode = XRRConfigCurrentConfiguration (config, &current_rotation);
    00372             // Find smallest matching mode
    00373             int mode = -1;
    00374             int mode_width = INT_MAX;
    00375             int mode_height = INT_MAX;
    00376             for(int i=0; i<nsizes; i++) {
    00377                 if(sizes[i].width >= width && sizes[i].height >= height &&
    00378                                 sizes[i].width < mode_width && sizes[i].height < mode_height) {
    00379                     mode = i;
    00380                     mode_width = sizes[i].width;
    00381                     mode_height = sizes[i].height;
    00382                 }
    00383             }
    00384             if(mode >= 0) {
    00385                 // Finally, set the screen configuration
    00386                 LogManager::getSingleton().logMessage("GLXWindow::create -- Entering full screen mode");
    00387                 XRRSetScreenConfig(mDisplay, config, rootWindow, mode, current_rotation, CurrentTime);
    00388             } else {
    00389                 LogManager::getSingleton().logMessage("GLXWindow::create -- Could not switch to full screen mode: No conforming mode was found");
    00390             }
    00391             // Free configuration data
    00392             XRRFreeScreenConfigInfo(config);
    00393         } else {
    00394             LogManager::getSingleton().logMessage("GLXWindow::create -- Could not switch to full screen mode: XRRGetScreenInfo failed");
    00395         }
    00396     }
    00397 #endif
    00398     // Apply some magic algorithm to get the best visual
    00399     int best_visual = find_best_visual(mDisplay, screen);
    00400     LogManager::getSingleton().logMessage("GLXWindow::create -- Best visual is "+StringConverter::toString(best_visual));
    00401
    00402     // Get information about this so-called-best visual
    00403     XVisualInfo templ;
    00404     int nmatch;
    00405     templ.visualid = best_visual;
    00406     XVisualInfo *visualInfo = XGetVisualInfo(mDisplay, VisualIDMask, &templ, &nmatch);
    00407     if(visualInfo==0 || nmatch==0) {
    00408         Except(999, "GLXWindow: error choosing visual", "GLXWindow::create");
    00409     }
    00410
    00411     XSetWindowAttributes attr;
    00412     unsigned long mask;
    00413     attr.background_pixel = 0;
    00414     attr.border_pixel = 0;
    00415     attr.colormap = XCreateColormap(mDisplay,rootWindow,visualInfo->visual,AllocNone);
    00416     attr.event_mask = StructureNotifyMask | KeyPressMask | KeyReleaseMask | PointerMotionMask | ButtonPressMask | ButtonReleaseMask;
    00417     if(fullScreen) {
    00418         mask = CWBackPixel | CWColormap | CWOverrideRedirect | CWSaveUnder | CWBackingStore | CWEventMask;
    00419         attr.override_redirect = True;
    00420         attr.backing_store = NotUseful;
    00421         attr.save_under = False;
    00422         // Fullscreen windows are always in the top left origin
    00423         left = top = 0;
    00424     } else
    00425         mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
    00426
    00427     // Create window on server
    00428     mWindow = XCreateWindow(mDisplay,rootWindow,left,top,width,height,0,visualInfo->depth,InputOutput,visualInfo->visual,mask,&attr);
    00429     if(!mWindow) {
    00430         Except(999, "GLXWindow: XCreateWindow failed", "GLXWindow::create");
    00431     }
    00432
    00433     // Make sure the window is in normal state
    00434     XWMHints *wm_hints;
    00435     if ((wm_hints = XAllocWMHints()) != NULL) {
    00436         wm_hints->initial_state = NormalState;
    00437         wm_hints->input = True;
    00438         wm_hints->flags = StateHint | InputHint;
    00439
    00440         // Check if we can give it an icon
    00441         if(depth == 24 || depth == 32) {
    00442             // Woot! The right bit depth, we can load an icon
    00443             if(LoadIcon(mDisplay, rootWindow, "GLX_icon.png", &wm_hints->icon_pixmap, &wm_hints->icon_mask))
    00444                 wm_hints->flags |= IconPixmapHint | IconMaskHint;
    00445         }
    00446     }
    00447
    00448     // Set size and location hints
    00449     XSizeHints *size_hints;
    00450     if ((size_hints = XAllocSizeHints()) != NULL) {
    00451         // Otherwise some window managers ignore our position request
    00452         size_hints->flags = USPosition;
    00453     }
    00454
    00455     // Make text property from title
    00456     XTextProperty titleprop;
    00457     char *lst = (char*)name.c_str();
    00458     XStringListToTextProperty((char **)&lst, 1, &titleprop);
    00459
    00460     XSetWMProperties(mDisplay, mWindow, &titleprop, NULL, NULL, 0, size_hints, wm_hints, NULL);
    00461
    00462     // We don't like memory leaks. Free the clientside storage, but not the
    00463     // pixmaps as they're still being used by the server.
    00464     XFree(titleprop.value);
    00465     XFree(wm_hints);
    00466     XFree(size_hints);
    00467
    00468     // Acquire atom to recognize window close events
    00469     mAtomDeleteWindow = XInternAtom(mDisplay,"WM_DELETE_WINDOW",False);
    00470     XSetWMProtocols(mDisplay,mWindow,&mAtomDeleteWindow,1);
    00471
    00472     // Map window unto screen and focus it.
    00473     XMapWindow(mDisplay,mWindow);
    00474
    00475     // Make sure the server is up to date and focus the window
    00476     XFlush(mDisplay);
    00477
    00478     // Finally, create a GL context
    00479     mGlxContext = glXCreateContext(mDisplay,visualInfo,NULL,True);
    00480     if(!mGlxContext) {
    00481         Except(999, "glXCreateContext failed", "GLXWindow::create");
    00482     }
    00483     glXMakeCurrent(mDisplay,mWindow,mGlxContext);
    00484
    00485     // Free visual info
    00486     XFree(visualInfo);
    00487
    00488     mName = name;
    00489     mWidth = width;
    00490     mHeight = height;
    00491     mFullScreen = fullScreen;
    00492 }
    00493
    00494 void GLXWindow::destroy(void) {
    00495     if(mGlxContext)
    00496         glXDestroyContext(mDisplay, mGlxContext);
    00497     if(mWindow)
    00498         XDestroyWindow(mDisplay, mWindow);
    00499     mWindow = 0;
    00500     mGlxContext = 0;
    00501     mActive = false;
    00502
    00503     Root::getSingleton().getRenderSystem()->detachRenderTarget( this->getName() );
    00504 }
    00505
    00506 bool GLXWindow::isActive() const {
    00507     return mActive;
    00508 }
    00509
    00510 bool GLXWindow::isClosed() const {
    00511     return mClosed;
    00512 }
    00513
    00514 void GLXWindow::reposition(int left, int top) {
    00515     XMoveWindow(mDisplay,mWindow,left,top);
    00516 }
    00517
    00518 void GLXWindow::resize(unsigned int width, unsigned int height) {
    00519     XResizeWindow(mDisplay,mWindow,width,height);
    00520 }
    00521
    00522 void GLXWindow::swapBuffers(bool waitForVSync) {
    00523     glXSwapBuffers(mDisplay,mWindow);
    00524 }
    00525
    00526 void GLXWindow::processEvent(const XEvent &event) {
    00527     // Process only events for this window
    00528     switch(event.type) {
    00529     case ClientMessage:
    00530         if(event.xclient.display != mDisplay || event.xclient.window != mWindow)
    00531             // Not for me
    00532             break;
    00533         if(event.xclient.format == 32 && event.xclient.data.l[0] == (long)mAtomDeleteWindow)  {
    00534             // Window deleted -- oops, this does not work, ogre doesn't register the close
    00535             //mClosed = true;
    00536             //mActive = false;
    00537             //Root::getSingleton().getRenderSystem()->detachRenderTarget( this->getName() );
    00538         }
    00539         break;
    00540     case ConfigureNotify:
    00541         if(event.xconfigure.display != mDisplay || event.xconfigure.window != mWindow)
    00542             // Not for me
    00543             break;
    00544         // Check if the window size really changed
    00545         if(mWidth == event.xconfigure.width && mHeight == event.xconfigure.height)
    00546             break;
    00547         mWidth = event.xconfigure.width;
    00548         mHeight = event.xconfigure.height;
    00549
    00550         for (ViewportList::iterator it = mViewportList.begin();
    00551                         it != mViewportList.end(); ++it) {
    00552             (*it).second->_updateDimensions();
    00553         }
    00554
    00555         break;
    00556     case MapNotify:
    00557         if(event.xconfigure.display != mDisplay || event.xconfigure.window != mWindow)
    00558             // Not for me
    00559             break;
    00560         // Window was mapped to the screen
    00561         mActive = true;
    00562         break;
    00563     case UnmapNotify:
    00564         if(event.xconfigure.display != mDisplay || event.xconfigure.window != mWindow)
    00565             // Not for me
    00566             break;
    00567         // Window was unmapped from the screen (user switched
    00568         // to another workspace, for example)
    00569         mActive = false;
    00570         break;
    00571     }
    00572 }
    00573
    00574
    00575 void GLXWindow::getCustomAttribute( const String& name, void* pData ) {
    00576     if( name == "GLXWINDOW" ) {
    00577         *static_cast<Window*>(pData) = mWindow;
    00578         return;
    00579     } else if( name == "GLXDISPLAY" ) {
    00580         *static_cast<Display**>(pData) = mDisplay;
    00581         return;
    00582     }
    00583     RenderWindow::getCustomAttribute(name, pData);
    00584 }
    00585
    00586 void GLXWindow::writeContentsToFile(const String& filename) {
    00587
    00588     ImageCodec::ImageData imgData;
    00589     imgData.width = mWidth;
    00590     imgData.height = mHeight;
    00591     imgData.format = PF_R8G8B8;
    00592
    00593     // Allocate buffer
    00594     uchar* pBuffer = new uchar[mWidth * mHeight * 3];
    00595
    00596     // Read pixels
    00597     // I love GL: it does all the locking & colour conversion for us
    00598     glReadPixels(0,0, mWidth-1, mHeight-1, GL_RGB, GL_UNSIGNED_BYTE, pBuffer);
    00599
    00600     // Wrap buffer in a chunk
    00601     DataChunk chunk(pBuffer, mWidth * mHeight * 3);
    00602
    00603     // Need to flip the read data over in Y though
    00604     Image img;
    00605     img.loadRawData(chunk, mWidth, mHeight, PF_R8G8B8 );
    00606     img.flipAroundX();
    00607
    00608     DataChunk chunkFlipped(img.getData(), chunk.getSize());
    00609
    00610     // Get codec
    00611     size_t pos = filename.find_last_of(".");
    00612     String extension;
    00613     if( pos == String::npos )
    00614         Except(
    00615                 Exception::ERR_INVALIDPARAMS,
    00616                 "Unable to determine image type for '" + filename + "' - invalid extension.",
    00617                 "GLXWindow::writeContentsToFile" );
    00618
    00619     while( pos != filename.length() - 1 )
    00620         extension += filename[++pos];
    00621
    00622     // Get the codec
    00623     Codec * pCodec = Codec::getCodec(extension);
    00624
    00625     // Write out
    00626     pCodec->codeToFile(chunkFlipped, filename, &imgData);
    00627
    00628     delete [] pBuffer;
    00629
    00630
    00631 }
    00632 }

Copyright © 2002-2003 by The OGRE Team
Last modified Sun Nov 28 19:48:27 2004