| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964 |
- /*
- -----------------------------------------------------------------------------
- This source file is part of OGRE
- (Object-oriented Graphics Rendering Engine)
- For the latest info, see http://www.ogre3d.org/
- Copyright (c) 2000-2011 Torus Knot Software Ltd
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- THE SOFTWARE.
- -----------------------------------------------------------------------------
- */
- #include "CmException.h"
- #include "CmStringConverter.h"
- #include "CmGLXGLSupport.h"
- #include "CmGLXUtils.h"
- #include "CmGLXWindow.h"
- #include "CmGLXRenderTexture.h"
- #include <X11/extensions/Xrandr.h>
- GLenum glxewContextInit(Ogre::GLSupport *glSupport);
- static Display *_currentDisplay;
- static Display *_getCurrentDisplay(void) { return _currentDisplay; }
- namespace CamelotEngine
- {
- //-------------------------------------------------------------------------------------------------//
- template<class C> void remove_duplicates(C& c)
- {
- std::sort(c.begin(), c.end());
- typename C::iterator p = std::unique(c.begin(), c.end());
- c.erase(p, c.end());
- }
- //-------------------------------------------------------------------------------------------------//
- GLXGLSupport::GLXGLSupport() : mGLDisplay(0), mXDisplay(0)
- {
- // A connection that might be shared with the application for GL rendering:
- mGLDisplay = getGLDisplay();
-
- // A connection that is NOT shared to enable independent event processing:
- mXDisplay = getXDisplay();
-
- int dummy;
-
- if (XQueryExtension(mXDisplay, "RANDR", &dummy, &dummy, &dummy))
- {
- XRRScreenConfiguration *screenConfig;
-
- screenConfig = XRRGetScreenInfo(mXDisplay, DefaultRootWindow(mXDisplay));
-
- if (screenConfig)
- {
- XRRScreenSize *screenSizes;
- int nSizes = 0;
- Rotation currentRotation;
- int currentSizeID = XRRConfigCurrentConfiguration(screenConfig, ¤tRotation);
-
- screenSizes = XRRConfigSizes(screenConfig, &nSizes);
-
- mCurrentMode.first.first = screenSizes[currentSizeID].width;
- mCurrentMode.first.second = screenSizes[currentSizeID].height;
- mCurrentMode.second = XRRConfigCurrentRate(screenConfig);
-
- mOriginalMode = mCurrentMode;
-
- for(int sizeID = 0; sizeID < nSizes; sizeID++)
- {
- short *rates;
- int nRates = 0;
-
- rates = XRRConfigRates(screenConfig, sizeID, &nRates);
-
- for (int rate = 0; rate < nRates; rate++)
- {
- VideoMode mode;
-
- mode.first.first = screenSizes[sizeID].width;
- mode.first.second = screenSizes[sizeID].height;
- mode.second = rates[rate];
-
- mVideoModes.push_back(mode);
- }
- }
- XRRFreeScreenConfigInfo(screenConfig);
- }
- }
- else
- {
- mCurrentMode.first.first = DisplayWidth(mXDisplay, DefaultScreen(mXDisplay));
- mCurrentMode.first.second = DisplayHeight(mXDisplay, DefaultScreen(mXDisplay));
- mCurrentMode.second = 0;
-
- mOriginalMode = mCurrentMode;
-
- mVideoModes.push_back(mCurrentMode);
- }
-
- GLXFBConfig *fbConfigs;
- int config, nConfigs = 0;
-
- fbConfigs = chooseFBConfig(NULL, &nConfigs);
-
- for (config = 0; config < nConfigs; config++)
- {
- int caveat, samples;
-
- getFBConfigAttrib (fbConfigs[config], GLX_CONFIG_CAVEAT, &caveat);
-
- if (caveat != GLX_SLOW_CONFIG)
- {
- getFBConfigAttrib (fbConfigs[config], GLX_SAMPLES, &samples);
- mSampleLevels.push_back(StringConverter::toString(samples));
- }
- }
-
- XFree (fbConfigs);
-
- remove_duplicates(mSampleLevels);
- }
- //-------------------------------------------------------------------------------------------------//
- GLXGLSupport::~GLXGLSupport()
- {
- if (mXDisplay)
- XCloseDisplay(mXDisplay);
-
- if (! mIsExternalDisplay && mGLDisplay)
- XCloseDisplay(mGLDisplay);
- }
-
- //-------------------------------------------------------------------------------------------------//
- void GLXGLSupport::addConfig(void)
- {
- ConfigOption optFullScreen;
- ConfigOption optVideoMode;
- ConfigOption optDisplayFrequency;
- ConfigOption optVSync;
- ConfigOption optFSAA;
- ConfigOption optRTTMode;
- ConfigOption optSRGB;
-
- optFullScreen.name = "Full Screen";
- optFullScreen.immutable = false;
-
- optVideoMode.name = "Video Mode";
- optVideoMode.immutable = false;
-
- optDisplayFrequency.name = "Display Frequency";
- optDisplayFrequency.immutable = false;
-
- optVSync.name = "VSync";
- optVSync.immutable = false;
-
- optFSAA.name = "FSAA";
- optFSAA.immutable = false;
-
- optRTTMode.name = "RTT Preferred Mode";
- optRTTMode.immutable = false;
-
- optSRGB.name = "sRGB Gamma Conversion";
- optSRGB.immutable = false;
- optFullScreen.possibleValues.push_back("No");
- optFullScreen.possibleValues.push_back("Yes");
-
- optFullScreen.currentValue = optFullScreen.possibleValues[1];
-
- VideoModes::const_iterator value = mVideoModes.begin();
- VideoModes::const_iterator end = mVideoModes.end();
-
- for (; value != end; value++)
- {
- String mode = StringConverter::toString(value->first.first,4) + " x " + StringConverter::toString(value->first.second,4);
-
- optVideoMode.possibleValues.push_back(mode);
- }
-
- remove_duplicates(optVideoMode.possibleValues);
-
- optVideoMode.currentValue = StringConverter::toString(mCurrentMode.first.first,4) + " x " + StringConverter::toString(mCurrentMode.first.second,4);
-
- refreshConfig();
-
- if (GLXEW_SGI_swap_control)
- {
- optVSync.possibleValues.push_back("No");
- optVSync.possibleValues.push_back("Yes");
-
- optVSync.currentValue = optVSync.possibleValues[0];
- }
-
- // Is it worth checking for GL_EXT_framebuffer_object ?
- optRTTMode.possibleValues.push_back("FBO");
-
- if (GLXEW_VERSION_1_3)
- {
- optRTTMode.possibleValues.push_back("PBuffer");
- }
-
- optRTTMode.possibleValues.push_back("Copy");
-
- optRTTMode.currentValue = optRTTMode.possibleValues[0];
-
- if (! mSampleLevels.empty())
- {
- StringVector::const_iterator value = mSampleLevels.begin();
- StringVector::const_iterator end = mSampleLevels.end();
-
- for (; value != end; value++)
- {
- optFSAA.possibleValues.push_back(*value);
- }
-
- optFSAA.currentValue = optFSAA.possibleValues[0];
- }
-
- if (GLXEW_EXT_framebuffer_sRGB)
- {
- optSRGB.possibleValues.push_back("No");
- optSRGB.possibleValues.push_back("Yes");
- optSRGB.currentValue = optSRGB.possibleValues[0];
- }
- mOptions[optFullScreen.name] = optFullScreen;
- mOptions[optVideoMode.name] = optVideoMode;
- mOptions[optDisplayFrequency.name] = optDisplayFrequency;
- mOptions[optVSync.name] = optVSync;
- mOptions[optRTTMode.name] = optRTTMode;
- mOptions[optFSAA.name] = optFSAA;
- mOptions[optSRGB.name] = optSRGB;
-
- refreshConfig();
- }
-
- //-------------------------------------------------------------------------------------------------//
- void GLXGLSupport::refreshConfig(void)
- {
- ConfigOptionMap::iterator optVideoMode = mOptions.find("Video Mode");
- ConfigOptionMap::iterator optDisplayFrequency = mOptions.find("Display Frequency");
-
- if (optVideoMode != mOptions.end() && optDisplayFrequency != mOptions.end())
- {
- optDisplayFrequency->second.possibleValues.clear();
-
- VideoModes::const_iterator value = mVideoModes.begin();
- VideoModes::const_iterator end = mVideoModes.end();
-
- for (; value != end; value++)
- {
- String mode = StringConverter::toString(value->first.first,4) + " x " + StringConverter::toString(value->first.second,4);
-
- if (mode == optVideoMode->second.currentValue)
- {
- String frequency = StringConverter::toString(value->second) + " MHz";
-
- optDisplayFrequency->second.possibleValues.push_back(frequency);
- }
- }
-
- if (! optDisplayFrequency->second.possibleValues.empty())
- {
- optDisplayFrequency->second.currentValue = optDisplayFrequency->second.possibleValues[0];
- }
- else
- {
- optVideoMode->second.currentValue = StringConverter::toString(mVideoModes[0].first.first,4) + " x " + StringConverter::toString(mVideoModes[0].first.second,4);
- optDisplayFrequency->second.currentValue = StringConverter::toString(mVideoModes[0].second) + " MHz";
- }
- }
- }
-
- //-------------------------------------------------------------------------------------------------//
- void GLXGLSupport::setConfigOption(const String &name, const String &value)
- {
- ConfigOptionMap::iterator option = mOptions.find(name);
-
- if(option == mOptions.end())
- {
- OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS, "Option named " + name + " does not exist.", "GLXGLSupport::setConfigOption" );
- }
- else
- {
- option->second.currentValue = value;
- }
-
- if (name == "Video Mode")
- {
- ConfigOptionMap::iterator opt;
- if((opt = mOptions.find("Full Screen")) != mOptions.end())
- {
- if (opt->second.currentValue == "Yes")
- refreshConfig();
- }
- }
- }
- //-------------------------------------------------------------------------------------------------//
- String GLXGLSupport::validateConfig(void)
- {
- // TO DO
- return StringUtil::BLANK;
- }
- //-------------------------------------------------------------------------------------------------//
- RenderWindow* GLXGLSupport::createWindow(bool autoCreateWindow, GLRenderSystem* renderSystem, const String& windowTitle)
- {
- RenderWindow *window = 0;
-
- if (autoCreateWindow)
- {
- ConfigOptionMap::iterator opt;
- ConfigOptionMap::iterator end = mOptions.end();
- NameValuePairList miscParams;
-
- bool fullscreen = false;
- uint w = 800, h = 600;
-
- if((opt = mOptions.find("Full Screen")) != end)
- fullscreen = (opt->second.currentValue == "Yes");
-
- if((opt = mOptions.find("Display Frequency")) != end)
- miscParams["displayFrequency"] = opt->second.currentValue;
-
- if((opt = mOptions.find("Video Mode")) != end)
- {
- String val = opt->second.currentValue;
- String::size_type pos = val.find('x');
-
- if (pos != String::npos)
- {
- w = StringConverter::parseUnsignedInt(val.substr(0, pos));
- h = StringConverter::parseUnsignedInt(val.substr(pos + 1));
- }
- }
-
- if((opt = mOptions.find("FSAA")) != end)
- miscParams["FSAA"] = opt->second.currentValue;
-
- if((opt = mOptions.find("VSync")) != end)
- miscParams["vsync"] = opt->second.currentValue;
- if((opt = mOptions.find("sRGB Gamma Conversion")) != end)
- miscParams["gamma"] = opt->second.currentValue;
-
- window = renderSystem->_createRenderWindow(windowTitle, w, h, fullscreen, &miscParams);
- }
-
- return window;
- }
-
- //-------------------------------------------------------------------------------------------------//
- RenderWindow* GLXGLSupport::newWindow(const String &name, unsigned int width, unsigned int height, bool fullScreen, const NameValuePairList *miscParams)
- {
- GLXWindow* window = new GLXWindow(this);
-
- window->create(name, width, height, fullScreen, miscParams);
-
- return window;
- }
- //-------------------------------------------------------------------------------------------------//
- GLPBuffer *GLXGLSupport::createPBuffer(PixelComponentType format, size_t width, size_t height)
- {
- return new GLXPBuffer(this, format, width, height);
- }
-
- //-------------------------------------------------------------------------------------------------//
- void GLXGLSupport::start()
- {
- LogManager::getSingleton().logMessage(
- "******************************\n"
- "*** Starting GLX Subsystem ***\n"
- "******************************");
- }
- //-------------------------------------------------------------------------------------------------//
- void GLXGLSupport::stop()
- {
- LogManager::getSingleton().logMessage(
- "******************************\n"
- "*** Stopping GLX Subsystem ***\n"
- "******************************");
- }
- //-------------------------------------------------------------------------------------------------//
- void* GLXGLSupport::getProcAddress(const String& procname) {
- return (void*)glXGetProcAddressARB((const GLubyte*)procname.c_str());
- }
-
- //-------------------------------------------------------------------------------------------------//
- void GLXGLSupport::initialiseExtensions(void)
- {
- assert (mGLDisplay);
-
- GLSupport::initialiseExtensions();
-
- const char* extensionsString;
-
- // This is more realistic than using glXGetClientString:
- extensionsString = glXQueryExtensionsString(mGLDisplay, DefaultScreen(mGLDisplay));
-
- LogManager::getSingleton().stream() << "Supported GLX extensions: " << extensionsString;
-
- std::stringstream ext;
- String instr;
-
- ext << extensionsString;
-
- while(ext >> instr)
- {
- extensionList.insert(instr);
- }
- }
- //-------------------------------------------------------------------------------------------------//
- // Returns the FBConfig behind a GLXContext
-
- GLXFBConfig GLXGLSupport::getFBConfigFromContext(::GLXContext context)
- {
- GLXFBConfig fbConfig = 0;
-
- if (GLXEW_VERSION_1_3)
- {
- int fbConfigAttrib[] = {
- GLX_FBCONFIG_ID, 0,
- None
- };
- GLXFBConfig *fbConfigs;
- int nElements = 0;
-
- glXQueryContext(mGLDisplay, context, GLX_FBCONFIG_ID, &fbConfigAttrib[1]);
- fbConfigs = glXChooseFBConfig(mGLDisplay, DefaultScreen(mGLDisplay), fbConfigAttrib, &nElements);
-
- if (nElements)
- {
- fbConfig = fbConfigs[0];
- XFree(fbConfigs);
- }
- }
- else if (GLXEW_EXT_import_context && GLXEW_SGIX_fbconfig)
- {
- VisualID visualid;
-
- if (glXQueryContextInfoEXT(mGLDisplay, context, GLX_VISUAL_ID, (int*)&visualid))
- {
- fbConfig = getFBConfigFromVisualID(visualid);
- }
- }
-
- return fbConfig;
- }
-
- //-------------------------------------------------------------------------------------------------//
- // Returns the FBConfig behind a GLXDrawable, or returns 0 when
- // missing GLX_SGIX_fbconfig and drawable is Window (unlikely), OR
- // missing GLX_VERSION_1_3 and drawable is a GLXPixmap (possible).
-
- GLXFBConfig GLXGLSupport::getFBConfigFromDrawable(GLXDrawable drawable, unsigned int *width, unsigned int *height)
- {
- GLXFBConfig fbConfig = 0;
-
- if (GLXEW_VERSION_1_3)
- {
- int fbConfigAttrib[] = {
- GLX_FBCONFIG_ID, 0,
- None
- };
- GLXFBConfig *fbConfigs;
- int nElements = 0;
-
- glXQueryDrawable (mGLDisplay, drawable, GLX_FBCONFIG_ID, (unsigned int*)&fbConfigAttrib[1]);
-
- fbConfigs = glXChooseFBConfig(mGLDisplay, DefaultScreen(mGLDisplay), fbConfigAttrib, &nElements);
-
- if (nElements)
- {
- fbConfig = fbConfigs[0];
- XFree (fbConfigs);
-
- glXQueryDrawable(mGLDisplay, drawable, GLX_WIDTH, width);
- glXQueryDrawable(mGLDisplay, drawable, GLX_HEIGHT, height);
- }
- }
-
- if (! fbConfig && GLXEW_SGIX_fbconfig)
- {
- XWindowAttributes windowAttrib;
-
- if (XGetWindowAttributes(mGLDisplay, drawable, &windowAttrib))
- {
- VisualID visualid = XVisualIDFromVisual(windowAttrib.visual);
-
- fbConfig = getFBConfigFromVisualID(visualid);
-
- *width = windowAttrib.width;
- *height = windowAttrib.height;
- }
- }
-
- return fbConfig;
- }
- //-------------------------------------------------------------------------------------------------//
- // Finds a GLXFBConfig compatible with a given VisualID.
- GLXFBConfig GLXGLSupport::getFBConfigFromVisualID(VisualID visualid)
- {
- GLXFBConfig fbConfig = 0;
-
- if (GLXEW_SGIX_fbconfig && glXGetFBConfigFromVisualSGIX)
- {
- XVisualInfo visualInfo;
-
- visualInfo.screen = DefaultScreen(mGLDisplay);
- visualInfo.depth = DefaultDepth(mGLDisplay, DefaultScreen(mGLDisplay));
- visualInfo.visualid = visualid;
-
- fbConfig = glXGetFBConfigFromVisualSGIX(mGLDisplay, &visualInfo);
- }
-
- if (! fbConfig)
- {
- int minAttribs[] = {
- GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT || GLX_PIXMAP_BIT,
- GLX_RENDER_TYPE, GLX_RGBA_BIT,
- GLX_RED_SIZE, 1,
- GLX_BLUE_SIZE, 1,
- GLX_GREEN_SIZE, 1,
- None
- };
- int nConfigs = 0;
-
- GLXFBConfig *fbConfigs = chooseFBConfig(minAttribs, &nConfigs);
-
- for (int i = 0; i < nConfigs && ! fbConfig; i++)
- {
- XVisualInfo *visualInfo = getVisualFromFBConfig(fbConfigs[i]);
-
- if (visualInfo->visualid == visualid)
- fbConfig = fbConfigs[i];
-
- XFree(visualInfo);
- }
- XFree(fbConfigs);
- }
-
- return fbConfig;
- }
- //-------------------------------------------------------------------------------------------------//
- // A helper class for the implementation of selectFBConfig
- class FBConfigAttribs
- {
- public:
- FBConfigAttribs(const int* attribs)
- {
- fields[GLX_CONFIG_CAVEAT] = GLX_NONE;
-
- for (int i = 0; attribs[2*i]; i++)
- {
- fields[attribs[2*i]] = attribs[2*i+1];
- }
- }
- void load(GLXGLSupport* const glSupport, GLXFBConfig fbConfig)
- {
- std::map<int,int>::iterator it;
-
- for (it = fields.begin(); it != fields.end(); it++)
- {
- it->second = 0;
- glSupport->getFBConfigAttrib(fbConfig, it->first, &it->second);
- }
- }
- bool operator>(FBConfigAttribs& alternative)
- {
- // Caveats are best avoided, but might be needed for anti-aliasing
-
- if (fields[GLX_CONFIG_CAVEAT] != alternative.fields[GLX_CONFIG_CAVEAT])
- {
- if (fields[GLX_CONFIG_CAVEAT] == GLX_SLOW_CONFIG)
- return false;
-
- if (fields.find(GLX_SAMPLES) != fields.end() &&
- fields[GLX_SAMPLES] < alternative.fields[GLX_SAMPLES])
- return false;
- }
-
- std::map<int,int>::iterator it;
-
- for (it = fields.begin(); it != fields.end(); it++)
- {
- if (it->first != GLX_CONFIG_CAVEAT && fields[it->first] > alternative.fields[it->first])
- return true;
- }
-
- return false;
- }
-
- std::map<int,int> fields;
- };
- //-------------------------------------------------------------------------------------------------//
- // Finds an FBConfig that possesses each of minAttribs and gets as close
- // as possible to each of the maxAttribs without exceeding them.
- // Resembles glXChooseFBConfig, but is forgiving to platforms
- // that do not support the attributes listed in the maxAttribs.
-
- GLXFBConfig GLXGLSupport::selectFBConfig (const int* minAttribs, const int *maxAttribs)
- {
- GLXFBConfig *fbConfigs;
- GLXFBConfig fbConfig = 0;
- int config, nConfigs = 0;
-
- fbConfigs = chooseFBConfig(minAttribs, &nConfigs);
-
- // this is a fix for cases where chooseFBConfig is not supported.
- // On the 10/2010 chooseFBConfig was not supported on VirtualBox
- // http://www.virtualbox.org/ticket/7195
- if (!nConfigs)
- {
- fbConfigs = glXGetFBConfigs(mGLDisplay, DefaultScreen(mGLDisplay), &nConfigs);
- }
-
- if (! nConfigs)
- return 0;
-
- fbConfig = fbConfigs[0];
-
- if (maxAttribs)
- {
- FBConfigAttribs maximum(maxAttribs);
- FBConfigAttribs best(maxAttribs);
- FBConfigAttribs candidate(maxAttribs);
-
- best.load(this, fbConfig);
-
- for (config = 1; config < nConfigs; config++)
- {
- candidate.load(this, fbConfigs[config]);
-
- if (candidate > maximum)
- continue;
-
- if (candidate > best)
- {
- fbConfig = fbConfigs[config];
-
- best.load(this, fbConfig);
- }
- }
- }
- XFree (fbConfigs);
- return fbConfig;
- }
- //-------------------------------------------------------------------------------------------------//
- bool GLXGLSupport::loadIcon(const std::string &name, Pixmap *pixmap, Pixmap *bitmap)
- {
- Image image;
- int width, height;
- char* imageData;
-
- try
- {
- // Try to load image
- image.load(name, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
-
- if(image.getFormat() != PF_A8R8G8B8)
- {
- // Image format must be RGBA
- return false;
- }
-
- width = image.getWidth();
- height = image.getHeight();
- imageData = (char*)image.getData();
- }
- catch(Exception &e)
- {
- // Could not find image; never mind
- return false;
- }
-
- int bitmapLineLength = (width + 7) / 8;
- int pixmapLineLength = 4 * width;
-
- char* bitmapData = (char*)malloc(bitmapLineLength * height);
- char* pixmapData = (char*)malloc(pixmapLineLength * height);
-
- int sptr = 0, dptr = 0;
-
- for(int y = 0; y < height; y++)
- {
- for(int x = 0; x < width; x++)
- {
- if (ImageByteOrder(mXDisplay) == MSBFirst)
- {
- pixmapData[dptr + 0] = 0;
- pixmapData[dptr + 1] = imageData[sptr + 0];
- pixmapData[dptr + 2] = imageData[sptr + 1];
- pixmapData[dptr + 3] = imageData[sptr + 2];
- }
- else
- {
- pixmapData[dptr + 3] = 0;
- pixmapData[dptr + 2] = imageData[sptr + 0];
- pixmapData[dptr + 1] = imageData[sptr + 1];
- pixmapData[dptr + 0] = imageData[sptr + 2];
- }
-
- if(((unsigned char)imageData[sptr + 3])<128)
- {
- bitmapData[y*bitmapLineLength+(x>>3)] &= ~(1<<(x&7));
- }
- else
- {
- bitmapData[y*bitmapLineLength+(x>>3)] |= 1<<(x&7);
- }
- sptr += 4;
- dptr += 4;
- }
- }
-
- // Create bitmap on server and copy over bitmapData
- *bitmap = XCreateBitmapFromData(mXDisplay, DefaultRootWindow(mXDisplay), bitmapData, width, height);
-
- free(bitmapData);
-
- // Create pixmap on server and copy over pixmapData (via pixmapXImage)
- *pixmap = XCreatePixmap(mXDisplay, DefaultRootWindow(mXDisplay), width, height, 24);
-
- GC gc = XCreateGC (mXDisplay, DefaultRootWindow(mXDisplay), 0, NULL);
- XImage *pixmapXImage = XCreateImage(mXDisplay, NULL, 24, ZPixmap, 0, pixmapData, width, height, 8, width*4);
- XPutImage(mXDisplay, *pixmap, gc, pixmapXImage, 0, 0, 0, 0, width, height);
- XDestroyImage(pixmapXImage);
- XFreeGC(mXDisplay, gc);
-
- return true;
- }
-
- //-------------------------------------------------------------------------------------------------//
- Display* GLXGLSupport::getGLDisplay(void)
- {
- if (! mGLDisplay)
- {
- glXGetCurrentDisplay = (PFNGLXGETCURRENTDISPLAYPROC)getProcAddress("glXGetCurrentDisplay");
-
- mGLDisplay = glXGetCurrentDisplay();
- mIsExternalDisplay = true;
-
- if (! mGLDisplay)
- {
- mGLDisplay = XOpenDisplay(0);
- mIsExternalDisplay = false;
- }
-
- if(! mGLDisplay)
- {
- OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Couldn`t open X display " + String((const char*)XDisplayName (0)), "GLXGLSupport::getGLDisplay");
- }
-
- initialiseGLXEW();
-
- if (! GLXEW_VERSION_1_3 && ! (GLXEW_SGIX_fbconfig && GLXEW_EXT_import_context))
- {
- OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "No GLX FBConfig support on your display", "GLXGLSupport::GLXGLSupport");
- }
- }
-
- return mGLDisplay;
- }
- //-------------------------------------------------------------------------------------------------//
- Display* GLXGLSupport::getXDisplay(void)
- {
- if (! mXDisplay)
- {
- char* displayString = mGLDisplay ? DisplayString(mGLDisplay) : 0;
-
- mXDisplay = XOpenDisplay(displayString);
-
- if (! mXDisplay)
- {
- OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Couldn`t open X display " + String((const char*)displayString), "GLXGLSupport::getXDisplay");
- }
-
- mAtomDeleteWindow = XInternAtom(mXDisplay, "WM_DELETE_WINDOW", True);
- mAtomFullScreen = XInternAtom(mXDisplay, "_NET_WM_STATE_FULLSCREEN", True);
- mAtomState = XInternAtom(mXDisplay, "_NET_WM_STATE", True);
- }
-
- return mXDisplay;
- }
- //-------------------------------------------------------------------------------------------------//
- String GLXGLSupport::getDisplayName(void)
- {
- return String((const char*)XDisplayName(DisplayString(mGLDisplay)));
- }
- //-------------------------------------------------------------------------------------------------//
- GLXFBConfig* GLXGLSupport::chooseFBConfig(const GLint *attribList, GLint *nElements)
- {
- GLXFBConfig *fbConfigs;
-
- if (GLXEW_VERSION_1_3)
- fbConfigs = glXChooseFBConfig(mGLDisplay, DefaultScreen(mGLDisplay), attribList, nElements);
- else
- fbConfigs = glXChooseFBConfigSGIX(mGLDisplay, DefaultScreen(mGLDisplay), attribList, nElements);
-
- return fbConfigs;
- }
-
- //-------------------------------------------------------------------------------------------------//
- ::GLXContext GLXGLSupport::createNewContext(GLXFBConfig fbConfig, GLint renderType, ::GLXContext shareList, GLboolean direct) const
- {
- ::GLXContext glxContext;
-
- if (GLXEW_VERSION_1_3)
- glxContext = glXCreateNewContext(mGLDisplay, fbConfig, renderType, shareList, direct);
- else
- glxContext = glXCreateContextWithConfigSGIX(mGLDisplay, fbConfig, renderType, shareList, direct);
-
- return glxContext;
- }
-
- //-------------------------------------------------------------------------------------------------//
- GLint GLXGLSupport::getFBConfigAttrib(GLXFBConfig fbConfig, GLint attribute, GLint *value)
- {
- GLint status;
-
- if (GLXEW_VERSION_1_3)
- status = glXGetFBConfigAttrib(mGLDisplay, fbConfig, attribute, value);
- else
- status = glXGetFBConfigAttribSGIX(mGLDisplay, fbConfig, attribute, value);
-
- return status;
- }
-
- //-------------------------------------------------------------------------------------------------//
- XVisualInfo* GLXGLSupport::getVisualFromFBConfig(GLXFBConfig fbConfig)
- {
- XVisualInfo *visualInfo;
-
- if (GLXEW_VERSION_1_3)
- visualInfo = glXGetVisualFromFBConfig(mGLDisplay, fbConfig);
- else
- visualInfo = glXGetVisualFromFBConfigSGIX(mGLDisplay, fbConfig);
-
- return visualInfo;
- }
- //-------------------------------------------------------------------------------------------------//
- void GLXGLSupport::switchMode(uint& width, uint& height, short& frequency)
- {
- int size = 0;
- int newSize = -1;
-
- VideoModes::iterator mode;
- VideoModes::iterator end = mVideoModes.end();
- VideoMode *newMode = 0;
-
- for(mode = mVideoModes.begin(); mode != end; size++)
- {
- if (mode->first.first >= static_cast<int>(width) &&
- mode->first.second >= static_cast<int>(height))
- {
- if (! newMode ||
- mode->first.first < newMode->first.first ||
- mode->first.second < newMode->first.second)
- {
- newSize = size;
- newMode = &(*mode);
- }
- }
-
- VideoMode *lastMode = &(*mode);
-
- while (++mode != end && mode->first == lastMode->first)
- {
- if (lastMode == newMode && mode->second == frequency)
- {
- newMode = &(*mode);
- }
- }
- }
-
- if (newMode && *newMode != mCurrentMode)
- {
- XRRScreenConfiguration *screenConfig = XRRGetScreenInfo (mXDisplay, DefaultRootWindow(mXDisplay));
-
- if (screenConfig)
- {
- Rotation currentRotation;
-
- XRRConfigCurrentConfiguration (screenConfig, ¤tRotation);
-
- XRRSetScreenConfigAndRate(mXDisplay, screenConfig, DefaultRootWindow(mXDisplay), newSize, currentRotation, newMode->second, CurrentTime);
-
- XRRFreeScreenConfigInfo(screenConfig);
-
- mCurrentMode = *newMode;
-
- LogManager::getSingleton().logMessage("Entered video mode " + StringConverter::toString(mCurrentMode.first.first) + "x" + StringConverter::toString(mCurrentMode.first.second) + " @ " + StringConverter::toString(mCurrentMode.second) + "MHz");
- }
- }
- }
-
- //-------------------------------------------------------------------------------------------------//
- void GLXGLSupport::switchMode(void)
- {
- return switchMode(mOriginalMode.first.first, mOriginalMode.first.second, mOriginalMode.second);
- }
- //-------------------------------------------------------------------------------------------------//
- // Initialise GLXEW
- //
- // Overloading glXGetCurrentDisplay allows us to call glxewContextInit
- // before establishing a GL context. This approach is a bit of a hack,
- // but it minimises the patches required between glew.c and glew.cpp.
- void GLXGLSupport::initialiseGLXEW(void)
- {
- _currentDisplay = mGLDisplay;
-
- glXGetCurrentDisplay = (PFNGLXGETCURRENTDISPLAYPROC)_getCurrentDisplay;
-
- if (glxewContextInit(this) != GLEW_OK)
- {
- XCloseDisplay (mGLDisplay);
- XCloseDisplay (mXDisplay);
- OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "No GLX 1.1 support on your platform", "GLXGLSupport::initialiseGLXEW");
- }
-
- glXGetCurrentDisplay = (PFNGLXGETCURRENTDISPLAYPROC)getProcAddress("glXGetCurrentDisplay");
- }
- }
|