⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ogreglxwindow.cpp

📁 使用stl技术,(还没看,是听说的)
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*
-----------------------------------------------------------------------------
This source file is part of OGRE
    (Object-oriented Graphics Rendering Engine)
For the latest info, see http://www.ogre3d.org/
 
Copyright ? 2000-2004 The OGRE Team
Also see acknowledgements in Readme.html
 
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later
version.
 
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
 
You should have received a copy of the GNU Lesser General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA, or go to
http://www.gnu.org/copyleft/lesser.txt.
-----------------------------------------------------------------------------
*/

#include "OgreGLXWindow.h"
#include "OgreRoot.h"
#include "OgreGLRenderSystem.h"
#include "OgreImageCodec.h"
#include "OgreException.h"
#include "OgreLogManager.h"
#include "OgreStringConverter.h"

#include <iostream>
#include <algorithm>
#include <sys/time.h>
#include <climits>

#include <X11/Xlib.h>
#include <X11/keysym.h>

#ifndef NO_XRANDR
#include <X11/extensions/Xrandr.h>
#endif

#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glx.h>


namespace Ogre {

GLXWindow::GLXWindow(Display *display) :
		mDisplay(display),
		mWindow(0),
		mGlxContext(0),
        mActive(false), mClosed(false),mFullScreen(false), mOldMode(-1),
        mContext(0) {}

GLXWindow::~GLXWindow() {
	if(mGlxContext)
		glXDestroyContext(mDisplay, mGlxContext);
	if(mWindow)
		XDestroyWindow(mDisplay, mWindow);
#ifndef NO_XRANDR

	if(mFullScreen) {
		// Restore original video mode.
		Window rootWindow = DefaultRootWindow(mDisplay);
		XRRScreenConfiguration *config;

		// Get current screen info
		config = XRRGetScreenInfo(mDisplay, rootWindow);
		if(config) {
			Rotation current_rotation;
			XRRConfigCurrentConfiguration (config, &current_rotation);
			//std::cerr << "Restore mode " << mOldMode << std::endl;
			LogManager::getSingleton().logMessage("GLXWindow::~GLXWindow -- Leaving full screen mode");
			XRRSetScreenConfig(mDisplay, config, rootWindow, mOldMode, current_rotation, CurrentTime);
			XRRFreeScreenConfigInfo(config);
		} else {
			LogManager::getSingleton().logMessage("GLXWindow::~GLXWindow -- Could not switch from full screen mode: XRRGetScreenInfo failed");
		}
	}
#endif
}

namespace {

/**
 * Loads an icon from an Ogre resource into the X Server. This currently only
 * works for 24 and 32 bit displays. The image must be findable by the Ogre
 * resource system, and of format PF_A8R8G8B8.
 *
 * @param mDisplay,rootWindow	X resources to use
 * @param name			Name of image to load
 * @param pix			Receiver for the output pixmap
 * @param mask			Receiver for the output mask (alpha bitmap)
 * @returns true on success
 */
bool LoadIcon(Display *mDisplay, Window rootWindow, const std::string &name, Pixmap *pix, Pixmap *mask) {
	Image img;
	int mWidth, mHeight;
	char *data, *bitmap;
	try {
		// Try to load image
		img.load(name);
		mWidth = img.getWidth();
		mHeight = img.getHeight();
		if(img.getFormat() != PF_A8R8G8B8)
			// Image format must be RGBA
			return 0;
	} catch(Exception &e) {
		// Could not find image; never mind
		return false;
	}

	// Allocate space for image data
	data = (char*)malloc(mWidth * mHeight * 4); // Must be allocated with malloc
	// Allocate space for transparency bitmap
	int wbits = (mWidth+7)/8;
	bitmap = (char*)malloc(wbits * mHeight);

	// Convert and copy image
	const char *imgdata = (const char*)img.getData();
	int sptr = 0, dptr = 0;
	for(int y=0; y<mHeight; y++) {
		for(int x=0; x<mWidth; x++) {
			data[dptr + 0] = 0;
			data[dptr + 1] = imgdata[sptr + 0];
			data[dptr + 2] = imgdata[sptr + 1];
			data[dptr + 3] = imgdata[sptr + 2];
			// Alpha threshold
			if(((unsigned char)imgdata[sptr + 3])<128) {
				bitmap[y*wbits+(x>>3)] &= ~(1<<(x&7));
			} else {
				bitmap[y*wbits+(x>>3)] |= 1<<(x&7);
			}
			sptr += 4;
			dptr += 4;
		}
	}

	/* put my pixmap data into the client side X image data structure */
	XImage *image = XCreateImage (mDisplay, NULL, 24, ZPixmap, 0,
	                              data,
	                              mWidth, mHeight, 8,
	                              mWidth*4);
	image->byte_order = MSBFirst; // 0RGB format

	/* tell server to start managing my pixmap */
	Pixmap retval = XCreatePixmap(mDisplay, rootWindow, mWidth,
	                              mHeight, 24);

	/* copy from client to server */
	GC context = XCreateGC (mDisplay, rootWindow, 0, NULL);
	XPutImage(mDisplay, retval, context, image, 0, 0, 0, 0,
	          mWidth, mHeight);

	/* free up the client side pixmap data area */
	XDestroyImage(image); // also cleans data
	XFreeGC(mDisplay, context);

	*pix = retval;
	*mask = XCreateBitmapFromData(mDisplay, rootWindow, bitmap, mWidth, mHeight);
	free(bitmap);
	return true;
}

struct visual_attribs
{
   /* X visual attribs */
   int id;
   int klass;
   int depth;
   int redMask, greenMask, blueMask;
   int colormapSize;
   int bitsPerRGB;

   /* GL visual attribs */
   int supportsGL;
   int transparentType;
   int transparentRedValue;
   int transparentGreenValue;
   int transparentBlueValue;
   int transparentAlphaValue;
   int transparentIndexValue;
   int bufferSize;
   int level;
   int rgba;
   int doubleBuffer;
   int stereo;
   int auxBuffers;
   int redSize, greenSize, blueSize, alphaSize;
   int depthSize;
   int stencilSize;
   int accumRedSize, accumGreenSize, accumBlueSize, accumAlphaSize;
   int numSamples, numMultisample;
   int visualCaveat;
};


static void
get_visual_attribs(Display *dpy, XVisualInfo *vInfo,
                   struct visual_attribs *attribs) {
	const char *ext = glXQueryExtensionsString(dpy, vInfo->screen);

	memset(attribs, 0, sizeof(struct visual_attribs));

	attribs->id = vInfo->visualid;
#if defined(__cplusplus) || defined(c_plusplus)

	attribs->klass = vInfo->c_class;
#else

	attribs->klass = vInfo->class;
#endif

	attribs->depth = vInfo->depth;
	attribs->redMask = vInfo->red_mask;
	attribs->greenMask = vInfo->green_mask;
	attribs->blueMask = vInfo->blue_mask;
	attribs->colormapSize = vInfo->colormap_size;
	attribs->bitsPerRGB = vInfo->bits_per_rgb;

	if (glXGetConfig(dpy, vInfo, GLX_USE_GL, &attribs->supportsGL) != 0)
		return;
	glXGetConfig(dpy, vInfo, GLX_BUFFER_SIZE, &attribs->bufferSize);
	glXGetConfig(dpy, vInfo, GLX_LEVEL, &attribs->level);
	glXGetConfig(dpy, vInfo, GLX_RGBA, &attribs->rgba);
	glXGetConfig(dpy, vInfo, GLX_DOUBLEBUFFER, &attribs->doubleBuffer);
	glXGetConfig(dpy, vInfo, GLX_STEREO, &attribs->stereo);
	glXGetConfig(dpy, vInfo, GLX_AUX_BUFFERS, &attribs->auxBuffers);
	glXGetConfig(dpy, vInfo, GLX_RED_SIZE, &attribs->redSize);
	glXGetConfig(dpy, vInfo, GLX_GREEN_SIZE, &attribs->greenSize);
	glXGetConfig(dpy, vInfo, GLX_BLUE_SIZE, &attribs->blueSize);
	glXGetConfig(dpy, vInfo, GLX_ALPHA_SIZE, &attribs->alphaSize);
	glXGetConfig(dpy, vInfo, GLX_DEPTH_SIZE, &attribs->depthSize);
	glXGetConfig(dpy, vInfo, GLX_STENCIL_SIZE, &attribs->stencilSize);
	glXGetConfig(dpy, vInfo, GLX_ACCUM_RED_SIZE, &attribs->accumRedSize);
	glXGetConfig(dpy, vInfo, GLX_ACCUM_GREEN_SIZE, &attribs->accumGreenSize);
	glXGetConfig(dpy, vInfo, GLX_ACCUM_BLUE_SIZE, &attribs->accumBlueSize);
	glXGetConfig(dpy, vInfo, GLX_ACCUM_ALPHA_SIZE, &attribs->accumAlphaSize);

	/* get transparent pixel stuff */
	glXGetConfig(dpy, vInfo,GLX_TRANSPARENT_TYPE, &attribs->transparentType);
	if (attribs->transparentType == GLX_TRANSPARENT_RGB) {
		glXGetConfig(dpy, vInfo, GLX_TRANSPARENT_RED_VALUE, &attribs->transparentRedValue);
		glXGetConfig(dpy, vInfo, GLX_TRANSPARENT_GREEN_VALUE, &attribs->transparentGreenValue);
		glXGetConfig(dpy, vInfo, GLX_TRANSPARENT_BLUE_VALUE, &attribs->transparentBlueValue);
		glXGetConfig(dpy, vInfo, GLX_TRANSPARENT_ALPHA_VALUE, &attribs->transparentAlphaValue);
	} else if (attribs->transparentType == GLX_TRANSPARENT_INDEX) {
		glXGetConfig(dpy, vInfo, GLX_TRANSPARENT_INDEX_VALUE, &attribs->transparentIndexValue);
	}

	/* multisample attribs */
#ifdef GLX_ARB_multisample
	if (ext && strstr("GLX_ARB_multisample", ext) == 0) {
		glXGetConfig(dpy, vInfo, GLX_SAMPLE_BUFFERS_ARB, &attribs->numMultisample);
		glXGetConfig(dpy, vInfo, GLX_SAMPLES_ARB, &attribs->numSamples);
	}
#endif
	else {
		attribs->numSamples = 0;
		attribs->numMultisample = 0;
	}

#if defined(GLX_EXT_visual_rating)
	if (ext && strstr(ext, "GLX_EXT_visual_rating")) {
		glXGetConfig(dpy, vInfo, GLX_VISUAL_CAVEAT_EXT, &attribs->visualCaveat);
	} else {
		attribs->visualCaveat = GLX_NONE_EXT;
	}
#else
	attribs->visualCaveat = 0;
#endif
}

/*
 * Examine all visuals to find the so-called best one.
 * We prefer deepest RGBA buffer with depth, stencil and accum
 * that has no caveats.
 * @author Brian Paul (from the glxinfo source)
 */
int find_best_visual(Display *dpy, int scrnum) {
	XVisualInfo theTemplate;
	XVisualInfo *visuals;
	int numVisuals;
	long mask;
	int i;
	struct visual_attribs bestVis;

	/* get list of all visuals on this screen */
	theTemplate.screen = scrnum;
	mask = VisualScreenMask;
	visuals = XGetVisualInfo(dpy, mask, &theTemplate, &numVisuals);
	if(numVisuals == 0 || visuals == 0) {
		/* something went wrong */
		if(visuals)
			XFree(visuals);
		return -1;
	}

	/* init bestVis with first visual info */
	get_visual_attribs(dpy, &visuals[0], &bestVis);

	/* try to find a "better" visual */
	for (i = 1; i < numVisuals; i++) {
		struct visual_attribs vis;

		get_visual_attribs(dpy, &visuals[i], &vis);

		/* always skip visuals with caveats */
		if (vis.visualCaveat != GLX_NONE_EXT)
			continue;

		/* see if this vis is better than bestVis */
		if ((!bestVis.supportsGL && vis.supportsGL) ||
		                (bestVis.visualCaveat != GLX_NONE_EXT) ||
		                (!bestVis.rgba && vis.rgba) ||
		                (!bestVis.doubleBuffer && vis.doubleBuffer) ||
		                (bestVis.redSize < vis.redSize) ||
		                (bestVis.greenSize < vis.greenSize) ||
		                (bestVis.blueSize < vis.blueSize) ||

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -