📄 ogreglxconfig.cpp
字号:
/*
-----------------------------------------------------------------------------
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 "OgreGLXConfig.h"
#include "OgreException.h"
#include "OgreImage.h"
#include "OgreLogManager.h"
#include <cstdlib>
#include <iostream>
#include <string>
#include <X11/X.h>
#include <X11/Xutil.h>
#include <X11/Xlib.h>
#include <X11/keysym.h>
#include <X11/extensions/xf86vmode.h>
#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>
#include <X11/Xaw/Command.h>
#include <X11/Xaw/Form.h>
#include <X11/Xaw/Box.h>
#include <X11/Shell.h>
#include <X11/Xaw/Toggle.h>
#include <X11/Xaw/MenuButton.h>
#include <X11/Xaw/SimpleMenu.h>
#include <X11/Xaw/SmeBSB.h>
#include <list>
namespace Ogre {
/**
* Single X window with image backdrop, making it possible to configure
* OGRE in a graphical way.
* XaW uses a not-very-smart widget positioning system, so I override it to use
* fixed positions. This works great, but it means you need to define the various
* positions manually.
* Furthermore, it has no OptionMenu by default, so I simulate this with dropdown
* buttons.
*/
class GLXConfigurator {
/* GUI constants */
static const int wWidth = 400; // Width of window
static const int wHeight = 300; // Height of window
static const int col1x = 20; // Starting x of column 1 (labels)
static const int col2x = 180; // Starting x of column 2 (options)
static const int col1w = 150; // Width of column 1 (labels)
static const int col2w = 200; // Width of column 2 (options)
static const int ystart = 105; // Starting y of option table rows
static const int rowh = 20; // Height of one row in the option table
static const std::string GLXConfigurator::backdrop; // Background image, defined below
public:
GLXConfigurator();
~GLXConfigurator();
bool CreateWindow();
void Main();
/**
* Exit from main loop.
*/
void Exit();
protected:
Display *mDisplay;
Window mWindow;
Pixmap mBackDrop;
int mWidth, mHeight;
// Xt
XtAppContext appContext;
Widget toplevel;
/**
* Create backdrop image, and return it as a Pixmap.
*/
virtual Pixmap CreateBackdrop(Window rootWindow, int depth);
/**
* Called after window initialisation.
*/
virtual bool Init();
/**
* Called initially, and on expose.
*/
virtual void Draw();
public:
/* Local */
bool accept;
/* Class that binds a callback to a RenderSystem */
class RendererCallbackData {
public:
RendererCallbackData(GLXConfigurator *parent, RenderSystem *renderer, Widget optionmenu):
parent(parent),
renderer(renderer),
optionmenu(optionmenu) {
}
GLXConfigurator *parent;
RenderSystem *renderer;
Widget optionmenu;
};
std::list<RendererCallbackData> mRendererCallbackData;
RenderSystem *mRenderer;
Widget box; // Box'o control widgets
std::list<Widget> mRenderOptionWidgets; // List of RenderSystem specific
// widgets for visibility management (cleared when another rendersystem is selected)
/* Class that binds a callback to a certain configuration option/value */
class ConfigCallbackData {
public:
ConfigCallbackData(GLXConfigurator *parent, const std::string &optionName, const std::string &valueName, Widget optionmenu):
parent(parent),
optionName(optionName),
valueName(valueName),
optionmenu(optionmenu) {
}
GLXConfigurator *parent;
std::string optionName, valueName;
Widget optionmenu;
};
std::list<ConfigCallbackData> mConfigCallbackData;
void SetRenderSystem(RenderSystem *sys) {
mRenderer = sys;
}
private:
/* Callbacks that terminate modal dialog loop */
static void acceptHandler(Widget w, GLXConfigurator *obj, XtPointer callData) {
// Check if a renderer was selected, if not, don't accept
if(!obj->mRenderer)
return;
obj->accept = true;
obj->Exit();
}
static void cancelHandler(Widget w, GLXConfigurator *obj, XtPointer callData) {
obj->Exit();
}
/* Callbacks that set a setting */
static void renderSystemHandler(Widget w, RendererCallbackData *cdata, XtPointer callData) {
// Set selected renderer its name
XtVaSetValues(cdata->optionmenu, XtNlabel, cdata->renderer->getName().c_str(), 0, NULL);
// Notify Configurator (and Ogre)
cdata->parent->SetRenderer(cdata->renderer);
}
static void configOptionHandler(Widget w, ConfigCallbackData *cdata, XtPointer callData) {
// Set selected renderer its name
XtVaSetValues(cdata->optionmenu, XtNlabel, cdata->valueName.c_str(), 0, NULL);
// Notify Configurator (and Ogre)
cdata->parent->SetConfigOption(cdata->optionName, cdata->valueName);
}
/* Functions reacting to GUI */
void SetRenderer(RenderSystem *);
void SetConfigOption(const std::string &optionName, const std::string &valueName);
};
/*
* Backdrop image. This must be sized mWidth by mHeight, and produce a
* RGB pixel format when loaded with Image::load .
*/
const std::string GLXConfigurator::backdrop = "GLX_backdrop.png";
GLXConfigurator::GLXConfigurator():
mDisplay(0), mWindow(0), mBackDrop(0),
mWidth(wWidth), mHeight(wHeight),
appContext(0), toplevel(0),
accept(false),
mRenderer(0) {
}
GLXConfigurator::~GLXConfigurator() {
if(mBackDrop)
XFreePixmap(mDisplay, mBackDrop);
if(toplevel) {
XtUnrealizeWidget(toplevel);
XtDestroyWidget(toplevel);
}
if(mDisplay) {
XCloseDisplay(mDisplay);
}
}
bool GLXConfigurator::CreateWindow() {
char *bla[] = {"Rendering Settings", "-bg", "black", "-fg", "green","-bd","darkgreen"};
int argc = sizeof(bla)/sizeof(*bla);
toplevel = XtVaOpenApplication(&appContext, "OGRE", NULL, 0, &argc, bla, NULL,sessionShellWidgetClass,
XtNwidth, mWidth,
XtNheight, mHeight,
XtNminWidth, mWidth,
XtNmaxWidth, mWidth,
XtNminHeight, mHeight,
XtNmaxHeight, mHeight,
XtNallowShellResize, False,
XtNborderWidth, 0,
XtNoverrideRedirect, True,
NULL, NULL);
/* Find out display and screen used */
mDisplay = XtDisplay(toplevel);
int screen = DefaultScreen(mDisplay);
Window rootWindow = RootWindow(mDisplay,screen);
/* Move to center of display */
int w = DisplayWidth(mDisplay, screen);
int h = DisplayHeight(mDisplay, screen);
XtVaSetValues(toplevel,
XtNx, w/2-mWidth/2,
XtNy, h/2-mHeight/2, 0, NULL);
/* Backdrop stuff */
mBackDrop = CreateBackdrop(rootWindow, DefaultDepth(mDisplay,screen));
/* Create toplevel */
box = XtVaCreateManagedWidget("box",formWidgetClass,toplevel,
XtNbackgroundPixmap, mBackDrop,
0,NULL);
/* Create renderer selection */
int cury = ystart + 0*rowh;
Widget lb1 = XtVaCreateManagedWidget("topLabel", labelWidgetClass, box, XtNlabel, "Select Renderer", XtNborderWidth, 0,
XtNwidth, col1w, // Fixed width
XtNheight, 18,
XtNleft, XawChainLeft,
XtNtop, XawChainTop,
XtNright, XawChainLeft,
XtNbottom, XawChainTop,
XtNhorizDistance, col1x,
XtNvertDistance, cury,
XtNjustify, XtJustifyLeft,
NULL);
const char *curRenderName = " Select One "; // Name of current renderer, or hint to select one
if(mRenderer)
curRenderName = mRenderer->getName().c_str();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -