1
0
Fork 0
flightgear/src/Main/fg_os.cxx

221 lines
4.8 KiB
C++
Raw Normal View History

2004-04-30 08:44:59 +00:00
#ifndef _MSC_VER // MSVC really needs a definition for wchar_t
#define _WCHAR_T_DEFINED 1 // Glut needs this, or else it tries to
// redefine it
2004-04-30 08:44:59 +00:00
#endif
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <simgear/compiler.h>
#include SG_GLUT_H
#include <plib/pu.h>
2004-04-01 15:44:13 +00:00
#include "fg_props.hxx"
#include "fg_os.hxx"
//
// fg_os callback registration APIs
// (These are not glut-specific)
//
static fgIdleHandler IdleHandler = 0;
static fgDrawHandler DrawHandler = 0;
static fgWindowResizeHandler WindowResizeHandler = 0;
static fgKeyHandler KeyHandler = 0;
static fgMouseClickHandler MouseClickHandler = 0;
static fgMouseMotionHandler MouseMotionHandler = 0;
void fgRegisterIdleHandler(fgIdleHandler func)
{
IdleHandler = func;
}
void fgRegisterDrawHandler(fgDrawHandler func)
{
DrawHandler = func;
}
void fgRegisterWindowResizeHandler(fgWindowResizeHandler func)
{
WindowResizeHandler = func;
}
void fgRegisterKeyHandler(fgKeyHandler func)
{
KeyHandler = func;
}
void fgRegisterMouseClickHandler(fgMouseClickHandler func)
{
MouseClickHandler = func;
}
void fgRegisterMouseMotionHandler(fgMouseMotionHandler func)
{
MouseMotionHandler = func;
}
//
// Native glut callbacks.
// These translate the glut event model into fg*Handler callbacks
//
static int GlutModifiers = 0;
static void callKeyHandler(int k, int mods, int x, int y)
{
int puiup = mods & KEYMOD_RELEASED ? PU_UP : PU_DOWN;
if(puKeyboard(k, puiup))
return;
if(KeyHandler) (*KeyHandler)(k, mods, x, y);
}
static void GLUTmotion (int x, int y)
{
if(MouseMotionHandler) (*MouseMotionHandler)(x, y);
}
static void GLUTmouse (int button, int updown, int x, int y)
{
GlutModifiers = glutGetModifiers();
if(MouseClickHandler) (*MouseClickHandler)(button, updown, x, y);
}
static void GLUTspecialkeyup(int k, int x, int y)
{
GlutModifiers = glutGetModifiers();
callKeyHandler(256 + k, fgGetKeyModifiers() | KEYMOD_RELEASED, x, y);
}
static void GLUTspecialkey(int k, int x, int y)
{
GlutModifiers = glutGetModifiers();
callKeyHandler(256 + k, fgGetKeyModifiers(), x, y);
}
static void GLUTkeyup(unsigned char k, int x, int y)
{
GlutModifiers = glutGetModifiers();
callKeyHandler(k, fgGetKeyModifiers() | KEYMOD_RELEASED, x, y);
}
static void GLUTkey(unsigned char k, int x, int y)
{
GlutModifiers = glutGetModifiers();
callKeyHandler(k, fgGetKeyModifiers(), x, y);
}
static void GLUTidle()
{
if(IdleHandler) (*IdleHandler)();
}
static void GLUTdraw()
{
if(DrawHandler) (*DrawHandler)();
glutSwapBuffers();
}
static void GLUTreshape(int w, int h)
{
if(WindowResizeHandler) (*WindowResizeHandler)(w, h);
}
//
// fg_os API definition
//
void fgOSInit(int* argc, char** argv)
{
glutInit(argc, argv);
}
void fgOSFullScreen()
{
glutFullScreen();
}
void fgOSMainLoop()
{
glutMainLoop();
}
2004-04-25 02:17:03 +00:00
void fgOSExit(int code)
{
exit(code);
}
static int CurrentCursor = MOUSE_CURSOR_POINTER;
int fgGetMouseCursor()
{
return CurrentCursor;
}
void fgSetMouseCursor(int cursor)
{
CurrentCursor = cursor;
if (cursor == MOUSE_CURSOR_NONE) cursor = GLUT_CURSOR_NONE;
else if(cursor == MOUSE_CURSOR_POINTER) cursor = GLUT_CURSOR_INHERIT;
else if(cursor == MOUSE_CURSOR_WAIT) cursor = GLUT_CURSOR_WAIT;
else if(cursor == MOUSE_CURSOR_CROSSHAIR) cursor = GLUT_CURSOR_CROSSHAIR;
else if(cursor == MOUSE_CURSOR_LEFTRIGHT) cursor = GLUT_CURSOR_LEFT_RIGHT;
// Otherwise, pass it through unchanged...
glutSetCursor(cursor);
}
void fgWarpMouse(int x, int y)
{
glutWarpPointer(x, y);
}
int fgGetKeyModifiers()
{
int result = 0;
if(GlutModifiers & GLUT_ACTIVE_SHIFT) result |= KEYMOD_SHIFT;
if(GlutModifiers & GLUT_ACTIVE_CTRL) result |= KEYMOD_CTRL;
if(GlutModifiers & GLUT_ACTIVE_ALT) result |= KEYMOD_ALT;
return result;
}
void fgRequestRedraw()
{
glutPostRedisplay();
}
void fgOSOpenWindow(int w, int h, int bpp, bool alpha,
bool stencil, bool fullscreen)
{
int mode = GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE;
if(alpha) mode |= GLUT_ALPHA;
Frederic Bouvier: FG_ENABLE_MULTIPASS_CLOUDS must be defined to enable the algorithm. I made this because the stencil buffer must be initialized at the beginning of the program and OpenGL can fallback to software rendering if it can't find a visual with stencil buffer. I didn't touch the configure script, so CXXFLAGS=-DFG_ENABLE_MULTIPASS_CLOUDS must be set before running ./configure. If FG_ENABLE_MULTIPASS_CLOUDS is defined, the main render loop begins by reading the /sim/rendering/multi-pass-clouds property. It is a boolean property so there are only two quality levels. false means no multi pass and no use of the stencil buffer, true means an additionnal pass for both upper and lower cloud layers. The algorithms are as follow : /sim/rendering/multi-pass-clouds=false 1. draw sky dome 2. draw terrain only 3. draw clouds above the viewer 4. draw models except the aircraft 5. draw clouds below the viewer 6. draw the aircraft. The cloud rendering doesn't update the depth buffer. This means that models overwrite clouds above the viewer. This is only noticeable for tall buildings and when flying very low. Also, drawing low clouds after models means that they are not blended with models' translucent surfaces. Large transparent area require alpha test enabled and AI aircraft canopy are making holes. The pilot's aircraft being rendered at the end, there is no problem with canopy or prop disc. /sim/rendering/multi-pass-clouds=true 1. draw the sky dome 2. draw the terrain only 3. draw all clouds 4. draw models except the aircraft 5. redraw the clouds where the models where drawn ( stencil test on ) 6. draw the aircraft The assumptions made by this algoritm are that the terrain is not transparent ( should be true in all cases and that there are no clouds between the aircraft and the viewer. Assuming these facts, there should be no blending bugs. The screenshot rendering is not updated yet.
2004-04-02 14:40:54 +00:00
if(stencil) mode |= GLUT_STENCIL;
glutInitDisplayMode(mode);
glutInitWindowSize(w, h);
2004-04-01 15:44:13 +00:00
if(!fgGetBool("/sim/startup/game-mode")) {
glutCreateWindow("FlightGear");
} else {
char game_mode_str[256];
sprintf(game_mode_str, "width=%d height=%d bpp=%d", w, h, bpp);
glutGameModeString( game_mode_str );
glutEnterGameMode();
}
// Register these here. Calling them before the window is open
// crashes.
glutMotionFunc(GLUTmotion);
glutPassiveMotionFunc(GLUTmotion);
glutMouseFunc(GLUTmouse);
glutSpecialUpFunc(GLUTspecialkeyup);
glutSpecialFunc(GLUTspecialkey);
glutKeyboardUpFunc(GLUTkeyup);
glutKeyboardFunc(GLUTkey);
glutIdleFunc(GLUTidle);
glutDisplayFunc(GLUTdraw);
glutReshapeFunc(GLUTreshape);
2004-04-01 15:44:13 +00:00
}