2009-07-28 21:32:10 +00:00
// Copyright (C) 2003 Dolphin Project.
2008-12-08 05:25:12 +00:00
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// 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 General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
# include "Globals.h"
2009-09-13 09:23:30 +00:00
# include "VideoConfig.h"
2008-12-08 05:25:12 +00:00
# include "IniFile.h"
# include "svnrev.h"
2009-02-22 21:16:12 +00:00
# include "Setup.h"
2008-12-08 05:25:12 +00:00
# include "Render.h"
# if defined(_WIN32)
# include "OS/Win32.h"
# else
struct RECT
{
2010-02-20 04:18:19 +00:00
int left , top ;
int right , bottom ;
2008-12-08 05:25:12 +00:00
} ;
# endif
# include "GLUtil.h"
// Handles OpenGL and the window
2009-02-28 16:33:59 +00:00
// Window dimensions.
static int s_backbuffer_width ;
static int s_backbuffer_height ;
2008-12-08 05:25:12 +00:00
# ifndef _WIN32
GLWindow GLWin ;
# endif
# if defined(_WIN32)
2009-02-28 16:33:59 +00:00
static HDC hDC = NULL ; // Private GDI Device Context
static HGLRC hRC = NULL ; // Permanent Rendering Context
2008-12-08 05:25:12 +00:00
extern HINSTANCE g_hInstance ;
# endif
void OpenGL_SwapBuffers ( )
{
2009-09-09 20:47:11 +00:00
# if defined(USE_WX) && USE_WX
2010-02-20 04:18:19 +00:00
GLWin . glCanvas - > SwapBuffers ( ) ;
2008-12-10 23:23:05 +00:00
# elif defined(HAVE_COCOA) && HAVE_COCOA
2010-02-20 04:18:19 +00:00
cocoaGLSwap ( GLWin . cocoaCtx , GLWin . cocoaWin ) ;
2008-12-08 05:25:12 +00:00
# elif defined(_WIN32)
2010-02-20 04:18:19 +00:00
SwapBuffers ( hDC ) ;
2008-12-10 23:23:05 +00:00
# elif defined(HAVE_X11) && HAVE_X11
2010-02-20 04:18:19 +00:00
glXSwapBuffers ( GLWin . dpy , GLWin . win ) ;
2008-12-08 05:25:12 +00:00
# endif
}
2009-04-03 14:35:49 +00:00
u32 OpenGL_GetBackbufferWidth ( )
{
2010-02-20 04:18:19 +00:00
return s_backbuffer_width ;
2008-12-21 21:02:43 +00:00
}
2009-04-03 14:35:49 +00:00
u32 OpenGL_GetBackbufferHeight ( )
{
2010-02-20 04:18:19 +00:00
return s_backbuffer_height ;
2008-12-21 21:02:43 +00:00
}
2009-01-15 06:48:15 +00:00
void OpenGL_SetWindowText ( const char * text )
2008-12-08 05:25:12 +00:00
{
2009-09-09 20:47:11 +00:00
# if defined(USE_WX) && USE_WX
2010-02-20 04:18:19 +00:00
GLWin . frame - > SetTitle ( wxString : : FromAscii ( text ) ) ;
2008-12-10 23:23:05 +00:00
# elif defined(HAVE_COCOA) && HAVE_COCOA
2010-02-20 04:18:19 +00:00
cocoaGLSetTitle ( GLWin . cocoaWin , text ) ;
2008-12-08 05:25:12 +00:00
# elif defined(_WIN32)
2009-07-30 07:08:31 +00:00
// TODO convert text to unicode and change SetWindowTextA to SetWindowText
2010-02-20 04:18:19 +00:00
SetWindowTextA ( EmuWindow : : GetWnd ( ) , text ) ;
2008-12-08 05:25:12 +00:00
# elif defined(HAVE_X11) && HAVE_X11 // GLX
2010-02-20 04:18:19 +00:00
// Tell X to ask the window manager to set the window title. (X
// itself doesn't provide window title functionality.)
XStoreName ( GLWin . dpy , GLWin . win , text ) ;
2008-12-08 05:25:12 +00:00
# endif
}
2009-02-19 06:52:01 +00:00
// Draw messages on top of the screen
2008-12-10 23:23:05 +00:00
unsigned int Callback_PeekMessages ( )
2008-12-08 05:25:12 +00:00
{
# ifdef _WIN32
2010-02-20 04:18:19 +00:00
// TODO: peekmessage
MSG msg ;
while ( PeekMessage ( & msg , 0 , 0 , 0 , PM_REMOVE ) )
{
if ( msg . message = = WM_QUIT )
return FALSE ;
TranslateMessage ( & msg ) ;
DispatchMessage ( & msg ) ;
}
return TRUE ;
2009-01-15 06:48:15 +00:00
# else
2010-02-20 04:18:19 +00:00
return FALSE ;
2008-12-08 05:25:12 +00:00
# endif
}
2009-02-28 16:33:59 +00:00
2009-02-19 06:52:01 +00:00
// Show the current FPS
2008-12-08 05:25:12 +00:00
void UpdateFPSDisplay ( const char * text )
{
2010-02-20 04:18:19 +00:00
char temp [ 512 ] ;
sprintf ( temp , " SVN R%s: GL: %s " , SVN_REV_STR , text ) ;
OpenGL_SetWindowText ( temp ) ;
2008-12-08 05:25:12 +00:00
}
2010-02-16 04:59:45 +00:00
# if defined(HAVE_X11) && HAVE_X11
2010-03-15 23:25:11 +00:00
THREAD_RETURN XEventThread ( void * pArg ) ;
void X11_EWMH_Fullscreen ( int action )
{
2010-03-16 01:16:55 +00:00
_assert_ ( action = = _NET_WM_STATE_REMOVE | | action = = _NET_WM_STATE_ADD
2010-03-15 23:25:11 +00:00
| | action = = _NET_WM_STATE_TOGGLE ) ;
// Init X event structure for _NET_WM_STATE_FULLSCREEN client message
XEvent event ;
event . xclient . type = ClientMessage ;
event . xclient . message_type = XInternAtom ( GLWin . dpy , " _NET_WM_STATE " , False ) ;
event . xclient . window = GLWin . win ;
event . xclient . format = 32 ;
event . xclient . data . l [ 0 ] = action ;
event . xclient . data . l [ 1 ] = XInternAtom ( GLWin . dpy , " _NET_WM_STATE_FULLSCREEN " , False ) ;
// Send the event
if ( ! XSendEvent ( GLWin . dpy , DefaultRootWindow ( GLWin . dpy ) , False ,
SubstructureRedirectMask | SubstructureNotifyMask , & event ) )
ERROR_LOG ( VIDEO , " Failed to switch fullscreen/windowed mode. \n " ) ;
}
2010-02-16 04:59:45 +00:00
void CreateXWindow ( void )
{
2010-03-15 23:25:11 +00:00
Atom wmProtocols [ 3 ] ;
Window parent ;
2010-02-16 04:59:45 +00:00
2010-03-08 23:29:16 +00:00
# if defined(HAVE_GTK2) && HAVE_GTK2 && defined(wxGTK)
wxMutexGuiEnter ( ) ;
# endif
2010-02-16 04:59:45 +00:00
# if defined(HAVE_XRANDR) && HAVE_XRANDR
2010-03-16 01:16:55 +00:00
if ( GLWin . fs & & ! GLWin . renderToMain )
2010-03-15 23:25:11 +00:00
XRRSetScreenConfig ( GLWin . dpy , GLWin . screenConfig , RootWindow ( GLWin . dpy , GLWin . screen ) ,
GLWin . fullSize , GLWin . screenRotation , CurrentTime ) ;
# endif
# if defined(HAVE_GTK2) && HAVE_GTK2 && defined(wxGTK)
2010-03-16 01:16:55 +00:00
if ( GLWin . renderToMain )
2010-03-15 23:25:11 +00:00
{
GLWin . panel - > GetSize ( ( int * ) & GLWin . width , ( int * ) & GLWin . height ) ;
GLWin . panel - > GetPosition ( & GLWin . x , & GLWin . y ) ;
parent = GDK_WINDOW_XID ( GTK_WIDGET ( GLWin . panel - > GetHandle ( ) ) - > window ) ;
GLWin . panel - > SetFocus ( ) ;
2010-02-20 04:18:19 +00:00
}
else
2010-03-08 23:29:16 +00:00
# endif
2010-03-15 23:25:11 +00:00
{
GLWin . x = 0 ;
GLWin . y = 0 ;
GLWin . width = GLWin . winWidth ;
GLWin . height = GLWin . winHeight ;
parent = RootWindow ( GLWin . dpy , GLWin . vi - > screen ) ;
2010-02-20 04:18:19 +00:00
}
// Control window size and picture scaling
2010-03-08 23:29:16 +00:00
s_backbuffer_width = GLWin . width ;
s_backbuffer_height = GLWin . height ;
2010-02-20 04:18:19 +00:00
// create the window
2010-03-08 23:29:16 +00:00
GLWin . win = XCreateWindow ( GLWin . dpy , parent ,
GLWin . x , GLWin . y , GLWin . width , GLWin . height , 0 , GLWin . vi - > depth , InputOutput , GLWin . vi - > visual ,
2010-03-15 23:25:11 +00:00
CWBorderPixel | CWBackPixel | CWColormap | CWEventMask , & GLWin . attr ) ;
2010-02-20 04:18:19 +00:00
wmProtocols [ 0 ] = XInternAtom ( GLWin . dpy , " WM_DELETE_WINDOW " , True ) ;
2010-03-15 23:25:11 +00:00
wmProtocols [ 1 ] = XInternAtom ( GLWin . dpy , " _NET_WM_STATE " , False ) ;
wmProtocols [ 2 ] = XInternAtom ( GLWin . dpy , " _NET_WM_STATE_FULLSCREEN " , False ) ;
XSetWMProtocols ( GLWin . dpy , GLWin . win , wmProtocols , 3 ) ;
2010-02-20 04:18:19 +00:00
XSetStandardProperties ( GLWin . dpy , GLWin . win , " GPU " , " GPU " , None , NULL , 0 , NULL ) ;
2010-04-01 23:13:26 +00:00
XSelectInput ( GLWin . dpy , GLWin . win , ExposureMask | KeyPressMask | KeyReleaseMask |
StructureNotifyMask | EnterWindowMask | LeaveWindowMask | FocusChangeMask ) ;
2010-02-20 04:18:19 +00:00
XMapRaised ( GLWin . dpy , GLWin . win ) ;
XSync ( GLWin . dpy , True ) ;
2010-03-08 23:29:16 +00:00
# if defined(HAVE_GTK2) && HAVE_GTK2 && defined(wxGTK)
wxMutexGuiLeave ( ) ;
# endif
2010-03-16 03:34:27 +00:00
if ( g_Config . bHideCursor )
{
// make a blank cursor
Pixmap Blank ;
XColor DummyColor ;
char ZeroData [ 1 ] = { 0 } ;
Blank = XCreateBitmapFromData ( GLWin . dpy , GLWin . win , ZeroData , 1 , 1 ) ;
GLWin . blankCursor = XCreatePixmapCursor ( GLWin . dpy , Blank , Blank , & DummyColor , & DummyColor , 0 , 0 ) ;
XFreePixmap ( GLWin . dpy , Blank ) ;
}
2010-03-15 23:25:11 +00:00
GLWin . xEventThread = new Common : : Thread ( XEventThread , NULL ) ;
2010-02-16 04:59:45 +00:00
}
void DestroyXWindow ( void )
{
2010-02-20 04:18:19 +00:00
if ( GLWin . ctx )
{
if ( ! glXMakeCurrent ( GLWin . dpy , None , NULL ) )
{
printf ( " Could not release drawing context. \n " ) ;
}
}
/* switch back to original desktop resolution if we were in fullscreen */
if ( GLWin . fs )
{
2010-02-16 04:59:45 +00:00
# if defined(HAVE_XRANDR) && HAVE_XRANDR
2010-03-15 23:25:11 +00:00
XRRSetScreenConfig ( GLWin . dpy , GLWin . screenConfig , RootWindow ( GLWin . dpy , GLWin . screen ) ,
GLWin . deskSize , GLWin . screenRotation , CurrentTime ) ;
# if defined(HAVE_GTK2) && HAVE_GTK2 && defined(wxGTK)
2010-03-16 01:16:55 +00:00
if ( ! GLWin . renderToMain )
2010-03-15 23:25:11 +00:00
# endif
X11_EWMH_Fullscreen ( _NET_WM_STATE_REMOVE ) ;
2010-02-16 04:59:45 +00:00
# endif
2010-02-20 04:18:19 +00:00
}
XUndefineCursor ( GLWin . dpy , GLWin . win ) ;
XUnmapWindow ( GLWin . dpy , GLWin . win ) ;
2010-03-15 23:25:11 +00:00
GLWin . win = 0 ;
2010-02-16 04:59:45 +00:00
}
void ToggleFullscreenMode ( void )
{
2010-02-20 04:18:19 +00:00
GLWin . fs = ! GLWin . fs ;
2010-03-15 23:25:11 +00:00
# if defined(HAVE_XRANDR) && HAVE_XRANDR
if ( GLWin . fs )
XRRSetScreenConfig ( GLWin . dpy , GLWin . screenConfig , RootWindow ( GLWin . dpy , GLWin . screen ) ,
GLWin . fullSize , GLWin . screenRotation , CurrentTime ) ;
else
XRRSetScreenConfig ( GLWin . dpy , GLWin . screenConfig , RootWindow ( GLWin . dpy , GLWin . screen ) ,
GLWin . deskSize , GLWin . screenRotation , CurrentTime ) ;
# endif
# if defined(HAVE_GTK2) && HAVE_GTK2 && defined(wxGTK)
2010-03-16 01:16:55 +00:00
if ( ! GLWin . renderToMain )
2010-03-15 23:25:11 +00:00
# endif
{
X11_EWMH_Fullscreen ( _NET_WM_STATE_TOGGLE ) ;
XRaiseWindow ( GLWin . dpy , GLWin . win ) ;
XSetInputFocus ( GLWin . dpy , GLWin . win , RevertToPointerRoot , CurrentTime ) ;
}
XSync ( GLWin . dpy , False ) ;
}
THREAD_RETURN XEventThread ( void * pArg )
{
bool bPaused = False ;
while ( GLWin . win )
{
XEvent event ;
KeySym key ;
2010-03-16 13:18:52 +00:00
for ( int num_events = XPending ( GLWin . dpy ) ; num_events > 0 ; num_events - - ) {
2010-03-15 23:25:11 +00:00
XNextEvent ( GLWin . dpy , & event ) ;
switch ( event . type ) {
case KeyPress :
key = XLookupKeysym ( ( XKeyEvent * ) & event , 0 ) ;
switch ( key )
{
case XK_F1 : case XK_F2 : case XK_F3 : case XK_F4 : case XK_F5 : case XK_F6 :
case XK_F7 : case XK_F8 : case XK_F9 : case XK_F11 : case XK_F12 :
g_VideoInitialize . pKeyPress ( key - 0xff4e ,
event . xkey . state & ShiftMask ,
event . xkey . state & ControlMask ) ;
break ;
case XK_Escape :
if ( GLWin . fs & & ! bPaused )
{
printf ( " toggling fullscreen \n " ) ;
ToggleFullscreenMode ( ) ;
}
g_VideoInitialize . pKeyPress ( 0x1c , False , False ) ;
break ;
case XK_Return :
if ( event . xkey . state & Mod1Mask )
ToggleFullscreenMode ( ) ;
break ;
case XK_3 :
OSDChoice = 1 ;
// Toggle native resolution
if ( ! ( g_Config . bNativeResolution | | g_Config . b2xResolution ) )
g_Config . bNativeResolution = true ;
else if ( g_Config . bNativeResolution & & Renderer : : AllowCustom ( ) )
{ g_Config . bNativeResolution = false ; if ( Renderer : : Allow2x ( ) ) { g_Config . b2xResolution = true ; } }
else if ( Renderer : : AllowCustom ( ) )
g_Config . b2xResolution = false ;
break ;
case XK_4 :
OSDChoice = 2 ;
// Toggle aspect ratio
g_Config . iAspectRatio = ( g_Config . iAspectRatio + 1 ) & 3 ;
break ;
case XK_5 :
OSDChoice = 3 ;
// Toggle EFB copy
if ( g_Config . bEFBCopyDisable | | g_Config . bCopyEFBToTexture )
{
g_Config . bEFBCopyDisable = ! g_Config . bEFBCopyDisable ;
g_Config . bCopyEFBToTexture = false ;
}
else
{
g_Config . bCopyEFBToTexture = ! g_Config . bCopyEFBToTexture ;
}
break ;
case XK_6 :
OSDChoice = 4 ;
g_Config . bDisableFog = ! g_Config . bDisableFog ;
break ;
case XK_7 :
OSDChoice = 5 ;
g_Config . bDisableLighting = ! g_Config . bDisableLighting ;
break ;
default :
break ;
}
break ;
case FocusIn :
2010-03-16 01:16:55 +00:00
if ( g_Config . bHideCursor & & ! bPaused & & ! GLWin . renderToMain )
2010-03-15 23:25:11 +00:00
XDefineCursor ( GLWin . dpy , GLWin . win , GLWin . blankCursor ) ;
break ;
case FocusOut :
2010-03-16 01:16:55 +00:00
if ( g_Config . bHideCursor & & ! bPaused & & ! GLWin . renderToMain )
2010-03-15 23:25:11 +00:00
XUndefineCursor ( GLWin . dpy , GLWin . win ) ;
break ;
case ConfigureNotify :
Window winDummy ;
unsigned int borderDummy ;
XGetGeometry ( GLWin . dpy , GLWin . win , & winDummy , & GLWin . x , & GLWin . y ,
& GLWin . width , & GLWin . height , & borderDummy , & GLWin . depth ) ;
s_backbuffer_width = GLWin . width ;
s_backbuffer_height = GLWin . height ;
// Save windowed mode size for return from fullscreen
if ( ! GLWin . fs )
{
GLWin . winWidth = GLWin . width ;
GLWin . winHeight = GLWin . height ;
}
break ;
case ClientMessage :
if ( ( ulong ) event . xclient . data . l [ 0 ] = = XInternAtom ( GLWin . dpy , " WM_DELETE_WINDOW " , False ) )
g_VideoInitialize . pKeyPress ( 0x1b , False , False ) ;
if ( ( ulong ) event . xclient . data . l [ 0 ] = = XInternAtom ( GLWin . dpy , " TOGGLE_FULLSCREEN " , False ) )
ToggleFullscreenMode ( ) ;
if ( g_Config . bHideCursor & &
( ulong ) event . xclient . data . l [ 0 ] = = XInternAtom ( GLWin . dpy , " PAUSE " , False ) )
{
bPaused = True ;
XUndefineCursor ( GLWin . dpy , GLWin . win ) ;
}
if ( g_Config . bHideCursor & &
( ulong ) event . xclient . data . l [ 0 ] = = XInternAtom ( GLWin . dpy , " RESUME " , False ) )
{
bPaused = False ;
XDefineCursor ( GLWin . dpy , GLWin . win , GLWin . blankCursor ) ;
}
# if defined(HAVE_GTK2) && HAVE_GTK2 && defined(wxGTK)
2010-03-16 01:16:55 +00:00
if ( GLWin . renderToMain & &
2010-03-15 23:25:11 +00:00
( ulong ) event . xclient . data . l [ 0 ] = = XInternAtom ( GLWin . dpy , " RESIZE " , False ) )
{
GLWin . panel - > GetSize ( ( int * ) & GLWin . width , ( int * ) & GLWin . height ) ;
GLWin . panel - > GetPosition ( & GLWin . x , & GLWin . y ) ;
XMoveResizeWindow ( GLWin . dpy , GLWin . win , GLWin . x , GLWin . y , GLWin . width , GLWin . height ) ;
}
2010-03-16 01:16:55 +00:00
if ( GLWin . renderToMain & &
2010-03-15 23:25:11 +00:00
( ulong ) event . xclient . data . l [ 0 ] = = XInternAtom ( GLWin . dpy , " FOCUSIN " , False ) )
{
GLWin . panel - > SetFocus ( ) ;
if ( g_Config . bHideCursor )
XDefineCursor ( GLWin . dpy , GLWin . win , GLWin . blankCursor ) ;
}
2010-03-16 01:16:55 +00:00
if ( GLWin . renderToMain & & g_Config . bHideCursor & &
2010-03-15 23:25:11 +00:00
( ulong ) event . xclient . data . l [ 0 ] = = XInternAtom ( GLWin . dpy , " FOCUSOUT " , False ) )
XUndefineCursor ( GLWin . dpy , GLWin . win ) ;
# endif
break ;
default :
break ;
}
}
Common : : SleepCurrentThread ( 20 ) ;
}
return 0 ;
2010-02-16 04:59:45 +00:00
}
# endif
2009-01-04 21:53:41 +00:00
// Create rendering window.
// Call browser: Core.cpp:EmuThread() > main.cpp:Video_Initialize()
2009-01-15 06:48:15 +00:00
bool OpenGL_Create ( SVideoInitialize & _VideoInitialize , int _iwidth , int _iheight )
2008-12-08 05:25:12 +00:00
{
2010-02-16 04:59:45 +00:00
# if !defined(HAVE_X11) || !HAVE_X11
2009-01-04 21:53:41 +00:00
// Check for fullscreen mode
2010-02-20 04:18:19 +00:00
int _twidth , _theight ;
if ( g_Config . bFullscreen )
{
if ( strlen ( g_Config . cFSResolution ) > 1 )
{
sscanf ( g_Config . cFSResolution , " %dx%d " , & _twidth , & _theight ) ;
}
else // No full screen reso set, fall back to default reso
{
_twidth = _iwidth ;
_theight = _iheight ;
}
}
else // Going Windowed
{
if ( strlen ( g_Config . cInternalRes ) > 1 )
{
sscanf ( g_Config . cInternalRes , " %dx%d " , & _twidth , & _theight ) ;
}
else // No Window resolution set, fall back to default
{
_twidth = _iwidth ;
_theight = _iheight ;
}
}
2009-01-04 21:53:41 +00:00
2008-12-08 05:25:12 +00:00
// Control window size and picture scaling
2010-02-20 04:18:19 +00:00
s_backbuffer_width = _twidth ;
s_backbuffer_height = _theight ;
2010-02-16 04:59:45 +00:00
# endif
2008-12-08 05:25:12 +00:00
2010-02-20 04:18:19 +00:00
g_VideoInitialize . pPeekMessages = & Callback_PeekMessages ;
g_VideoInitialize . pUpdateFPSDisplay = & UpdateFPSDisplay ;
2008-12-08 05:25:12 +00:00
2009-09-09 20:47:11 +00:00
# if defined(USE_WX) && USE_WX
2010-02-20 04:18:19 +00:00
int args [ ] = { WX_GL_RGBA , WX_GL_DOUBLEBUFFER , WX_GL_DEPTH_SIZE , 16 , 0 } ;
wxSize size ( _iwidth , _iheight ) ;
if ( ! g_Config . RenderToMainframe | |
g_VideoInitialize . pWindowHandle = = NULL ) {
GLWin . frame = new wxFrame ( ( wxWindow * ) NULL ,
- 1 , _ ( " Dolphin " ) , wxPoint ( 50 , 50 ) , size ) ;
} else {
GLWin . frame = new wxFrame ( ( wxWindow * ) g_VideoInitialize . pWindowHandle ,
- 1 , _ ( " Dolphin " ) , wxPoint ( 50 , 50 ) , size ) ;
}
GLWin . glCanvas = new wxGLCanvas ( GLWin . frame , wxID_ANY , args ,
wxPoint ( 0 , 0 ) , size , wxSUNKEN_BORDER ) ;
GLWin . glCtxt = new wxGLContext ( GLWin . glCanvas ) ;
GLWin . frame - > Show ( TRUE ) ;
GLWin . glCanvas - > Show ( TRUE ) ;
GLWin . glCanvas - > SetCurrent ( * GLWin . glCtxt ) ;
2009-01-04 21:53:41 +00:00
2009-09-09 20:47:11 +00:00
# elif defined(HAVE_COCOA) && HAVE_COCOA
2010-02-20 04:18:19 +00:00
GLWin . width = s_backbuffer_width ;
GLWin . height = s_backbuffer_height ;
GLWin . cocoaWin = cocoaGLCreateWindow ( GLWin . width , GLWin . height ) ;
GLWin . cocoaCtx = cocoaGLInit ( g_Config . iMultisampleMode ) ;
2009-01-04 21:53:41 +00:00
2008-12-08 05:25:12 +00:00
# elif defined(_WIN32)
2010-01-20 19:51:13 +00:00
g_VideoInitialize . pWindowHandle = ( void * ) EmuWindow : : Create ( ( HWND ) g_VideoInitialize . pWindowHandle , g_hInstance , _T ( " Please wait... " ) ) ;
2008-12-08 05:25:12 +00:00
if ( g_VideoInitialize . pWindowHandle = = NULL )
{
g_VideoInitialize . pSysMessage ( " failed to create window " ) ;
return false ;
}
2010-02-20 04:18:19 +00:00
if ( g_Config . bFullscreen )
2010-01-20 19:51:13 +00:00
{
2010-02-20 04:18:19 +00:00
DEVMODE dmScreenSettings ;
memset ( & dmScreenSettings , 0 , sizeof ( dmScreenSettings ) ) ;
dmScreenSettings . dmSize = sizeof ( dmScreenSettings ) ;
dmScreenSettings . dmPelsWidth = s_backbuffer_width ;
dmScreenSettings . dmPelsHeight = s_backbuffer_height ;
dmScreenSettings . dmBitsPerPel = 32 ;
dmScreenSettings . dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT ;
// Try To Set Selected Mode And Get Results. NOTE: CDS_FULLSCREEN Gets Rid Of Start Bar.
if ( ChangeDisplaySettings ( & dmScreenSettings , CDS_FULLSCREEN ) ! = DISP_CHANGE_SUCCESSFUL )
{
if ( MessageBox ( NULL , _T ( " The Requested Fullscreen Mode Is Not Supported By \n Your Video Card. Use Windowed Mode Instead? " ) , _T ( " NeHe GL " ) , MB_YESNO | MB_ICONEXCLAMATION ) = = IDYES )
2010-01-20 19:51:13 +00:00
EmuWindow : : ToggleFullscreen ( EmuWindow : : GetWnd ( ) ) ;
2010-02-20 04:18:19 +00:00
else
return false ;
}
2010-01-20 19:51:13 +00:00
else
{
// SetWindowPos to the upper-left corner of the screen
SetWindowPos ( EmuWindow : : GetWnd ( ) , HWND_TOP , 0 , 0 , _twidth , _theight , SWP_NOREPOSITION | SWP_NOZORDER ) ;
}
2010-02-20 04:18:19 +00:00
}
else
2008-12-08 05:25:12 +00:00
{
2010-02-20 04:18:19 +00:00
// Change to default resolution
ChangeDisplaySettings ( NULL , 0 ) ;
}
2008-12-08 05:25:12 +00:00
2010-01-20 19:51:13 +00:00
// Show the window
EmuWindow : : Show ( ) ;
2008-12-08 05:25:12 +00:00
2010-02-20 04:18:19 +00:00
PIXELFORMATDESCRIPTOR pfd = // pfd Tells Windows How We Want Things To Be
{
sizeof ( PIXELFORMATDESCRIPTOR ) , // Size Of This Pixel Format Descriptor
1 , // Version Number
PFD_DRAW_TO_WINDOW | // Format Must Support Window
PFD_SUPPORT_OPENGL | // Format Must Support OpenGL
PFD_DOUBLEBUFFER , // Must Support Double Buffering
PFD_TYPE_RGBA , // Request An RGBA Format
32 , // Select Our Color Depth
0 , 0 , 0 , 0 , 0 , 0 , // Color Bits Ignored
0 , // 8bit Alpha Buffer
0 , // Shift Bit Ignored
0 , // No Accumulation Buffer
0 , 0 , 0 , 0 , // Accumulation Bits Ignored
24 , // 24Bit Z-Buffer (Depth Buffer)
8 , // 8bit Stencil Buffer
0 , // No Auxiliary Buffer
PFD_MAIN_PLANE , // Main Drawing Layer
0 , // Reserved
0 , 0 , 0 // Layer Masks Ignored
} ;
2010-01-20 19:51:13 +00:00
GLuint PixelFormat ; // Holds The Results After Searching For A Match
2010-02-20 04:18:19 +00:00
if ( ! ( hDC = GetDC ( EmuWindow : : GetWnd ( ) ) ) ) {
2009-03-22 11:21:44 +00:00
PanicAlert ( " (1) Can't create an OpenGL Device context. Fail. " ) ;
2010-02-20 04:18:19 +00:00
return false ;
}
if ( ! ( PixelFormat = ChoosePixelFormat ( hDC , & pfd ) ) ) {
PanicAlert ( " (2) Can't find a suitable PixelFormat. " ) ;
return false ;
}
if ( ! SetPixelFormat ( hDC , PixelFormat , & pfd ) ) {
2009-03-22 11:21:44 +00:00
PanicAlert ( " (3) Can't set the PixelFormat. " ) ;
2010-02-20 04:18:19 +00:00
return false ;
}
if ( ! ( hRC = wglCreateContext ( hDC ) ) ) {
2009-03-22 11:21:44 +00:00
PanicAlert ( " (4) Can't create an OpenGL rendering context. " ) ;
2010-02-20 04:18:19 +00:00
return false ;
}
2009-01-04 21:53:41 +00:00
// --------------------------------------
2008-12-08 05:25:12 +00:00
# elif defined(HAVE_X11) && HAVE_X11
2010-02-20 04:18:19 +00:00
int glxMajorVersion , glxMinorVersion ;
int vidModeMajorVersion , vidModeMinorVersion ;
// attributes for a single buffered visual in RGBA format with at least
// 8 bits per color and a 24 bit depth buffer
int attrListSgl [ ] = { GLX_RGBA , GLX_RED_SIZE , 8 ,
GLX_GREEN_SIZE , 8 ,
GLX_BLUE_SIZE , 8 ,
GLX_DEPTH_SIZE , 24 ,
None } ;
// attributes for a double buffered visual in RGBA format with at least
// 8 bits per color and a 24 bit depth buffer
int attrListDbl [ ] = { GLX_RGBA , GLX_DOUBLEBUFFER ,
GLX_RED_SIZE , 8 ,
GLX_GREEN_SIZE , 8 ,
GLX_BLUE_SIZE , 8 ,
GLX_DEPTH_SIZE , 24 ,
GLX_SAMPLE_BUFFERS_ARB , g_Config . iMultisampleMode , GLX_SAMPLES_ARB , 1 , None } ;
GLWin . dpy = XOpenDisplay ( 0 ) ;
2010-03-08 23:29:16 +00:00
# if defined(HAVE_GTK2) && HAVE_GTK2 && defined(wxGTK)
2010-03-15 23:25:11 +00:00
GLWin . panel = ( wxPanel * ) g_VideoInitialize . pPanel ;
2010-03-08 23:29:16 +00:00
# endif
g_VideoInitialize . pWindowHandle = ( Display * ) GLWin . dpy ;
2010-02-20 04:18:19 +00:00
GLWin . screen = DefaultScreen ( GLWin . dpy ) ;
// Fullscreen option.
GLWin . fs = g_Config . bFullscreen ; //Set to setting in Options
2010-03-16 01:16:55 +00:00
// Render to main option.
# if defined(HAVE_GTK2) && HAVE_GTK2 && defined(wxGTK)
GLWin . renderToMain = g_Config . RenderToMainframe ;
# else
GLWin . renderToMain = False ;
# endif
2010-02-20 04:18:19 +00:00
/* get an appropriate visual */
GLWin . vi = glXChooseVisual ( GLWin . dpy , GLWin . screen , attrListDbl ) ;
if ( GLWin . vi = = NULL ) {
GLWin . vi = glXChooseVisual ( GLWin . dpy , GLWin . screen , attrListSgl ) ;
GLWin . doubleBuffered = False ;
ERROR_LOG ( VIDEO , " Only Singlebuffered Visual! " ) ;
}
else {
GLWin . doubleBuffered = True ;
NOTICE_LOG ( VIDEO , " Got Doublebuffered Visual! " ) ;
}
2008-12-08 05:25:12 +00:00
2009-03-22 11:21:44 +00:00
glXQueryVersion ( GLWin . dpy , & glxMajorVersion , & glxMinorVersion ) ;
NOTICE_LOG ( VIDEO , " glX-Version %d.%d " , glxMajorVersion , glxMinorVersion ) ;
// Create a GLX context.
2010-02-16 04:59:45 +00:00
GLWin . ctx = glXCreateContext ( GLWin . dpy , GLWin . vi , 0 , GL_TRUE ) ;
2009-03-22 11:21:44 +00:00
if ( ! GLWin . ctx )
{
PanicAlert ( " Couldn't Create GLX context.Quit " ) ;
exit ( 0 ) ; // TODO: Don't bring down entire Emu
}
2010-03-12 04:10:48 +00:00
// Create a color map and set the event masks
2010-03-15 23:25:11 +00:00
GLWin . attr . colormap = XCreateColormap ( GLWin . dpy ,
RootWindow ( GLWin . dpy , GLWin . vi - > screen ) , GLWin . vi - > visual , AllocNone ) ;
2010-03-12 04:10:48 +00:00
GLWin . attr . event_mask = ExposureMask | KeyPressMask | KeyReleaseMask |
StructureNotifyMask | ResizeRedirectMask ;
2010-03-15 23:25:11 +00:00
GLWin . attr . background_pixel = BlackPixel ( GLWin . dpy , GLWin . screen ) ;
2009-03-22 11:21:44 +00:00
GLWin . attr . border_pixel = 0 ;
XkbSetDetectableAutoRepeat ( GLWin . dpy , True , NULL ) ;
2008-12-08 05:25:12 +00:00
2010-02-20 04:18:19 +00:00
// Get the resolution setings for both fullscreen and windowed modes
if ( strlen ( g_Config . cFSResolution ) > 1 )
sscanf ( g_Config . cFSResolution , " %dx%d " , & GLWin . fullWidth , & GLWin . fullHeight ) ;
else // No full screen reso set, fall back to desktop resolution
{
GLWin . fullWidth = DisplayWidth ( GLWin . dpy , GLWin . screen ) ;
GLWin . fullHeight = DisplayHeight ( GLWin . dpy , GLWin . screen ) ;
}
if ( strlen ( g_Config . cInternalRes ) > 1 )
sscanf ( g_Config . cInternalRes , " %dx%d " , & GLWin . winWidth , & GLWin . winHeight ) ;
else // No Window resolution set, fall back to default
{
GLWin . winWidth = _iwidth ;
GLWin . winHeight = _iheight ;
}
2010-02-16 04:59:45 +00:00
# if defined(HAVE_XRANDR) && HAVE_XRANDR
2010-02-20 04:18:19 +00:00
XRRQueryVersion ( GLWin . dpy , & vidModeMajorVersion , & vidModeMinorVersion ) ;
XRRScreenSize * sizes ;
int numSizes ;
NOTICE_LOG ( VIDEO , " XRRExtension-Version %d.%d " , vidModeMajorVersion , vidModeMinorVersion ) ;
GLWin . screenConfig = XRRGetScreenInfo ( GLWin . dpy , RootWindow ( GLWin . dpy , GLWin . screen ) ) ;
/* save desktop resolution */
GLWin . deskSize = XRRConfigCurrentConfiguration ( GLWin . screenConfig , & GLWin . screenRotation ) ;
/* Set the desktop resolution as the default */
GLWin . fullSize = - 1 ;
/* Find the index of the fullscreen resolution from config */
sizes = XRRConfigSizes ( GLWin . screenConfig , & numSizes ) ;
if ( numSizes > 0 & & sizes ! = NULL ) {
for ( int i = 0 ; i < numSizes ; i + + ) {
if ( ( sizes [ i ] . width = = GLWin . fullWidth ) & & ( sizes [ i ] . height = = GLWin . fullHeight ) ) {
GLWin . fullSize = i ;
}
}
NOTICE_LOG ( VIDEO , " Fullscreen Resolution %dx%d " , sizes [ GLWin . fullSize ] . width , sizes [ GLWin . fullSize ] . height ) ;
}
else {
ERROR_LOG ( VIDEO , " Failed to obtain fullscreen sizes. \n "
" Using current desktop resolution for fullscreen. \n " ) ;
GLWin . fullWidth = DisplayWidth ( GLWin . dpy , GLWin . screen ) ;
GLWin . fullHeight = DisplayHeight ( GLWin . dpy , GLWin . screen ) ;
}
2010-02-16 04:59:45 +00:00
# else
2010-02-20 04:18:19 +00:00
GLWin . fullWidth = DisplayWidth ( GLWin . dpy , GLWin . screen ) ;
GLWin . fullHeight = DisplayHeight ( GLWin . dpy , GLWin . screen ) ;
2010-02-16 04:59:45 +00:00
# endif
2008-12-08 05:25:12 +00:00
2010-03-15 23:25:11 +00:00
# if defined(HAVE_GTK2) && HAVE_GTK2 && defined(wxGTK)
2010-03-16 01:16:55 +00:00
if ( GLWin . renderToMain )
2010-03-15 23:25:11 +00:00
g_VideoInitialize . pKeyPress ( 0 , False , False ) ;
# endif
2010-02-20 04:18:19 +00:00
CreateXWindow ( ) ;
g_VideoInitialize . pXWindow = ( Window * ) & GLWin . win ;
2008-12-08 05:25:12 +00:00
# endif
return true ;
}
2010-04-01 23:13:26 +00:00
bool OpenGL_Initialize ( )
2008-12-08 05:25:12 +00:00
{
2010-04-01 23:13:26 +00:00
bool success = OpenGL_MakeCurrent ( ) ;
if ( ! success )
{
PanicAlert ( " Can't Activate The GL Rendering Context. " ) ;
2010-02-20 04:18:19 +00:00
return false ;
}
2010-04-01 23:13:26 +00:00
# if defined(HAVE_X11) && HAVE_X11
2010-02-20 04:18:19 +00:00
NOTICE_LOG ( VIDEO , " GLWin Depth %d " , GLWin . depth )
if ( glXIsDirect ( GLWin . dpy , GLWin . ctx ) ) {
NOTICE_LOG ( VIDEO , " detected direct rendering " ) ;
} else {
ERROR_LOG ( VIDEO , " no Direct Rendering possible! " ) ;
}
2010-03-15 23:25:11 +00:00
if ( GLWin . fs )
{
# if defined(HAVE_GTK2) && HAVE_GTK2 && defined(wxGTK)
2010-03-16 01:16:55 +00:00
if ( GLWin . renderToMain )
2010-03-15 23:25:11 +00:00
{
GLWin . fs = False ;
g_VideoInitialize . pKeyPress ( 0x1d , False , False ) ;
}
else
# endif
X11_EWMH_Fullscreen ( _NET_WM_STATE_ADD ) ;
}
2010-02-20 04:18:19 +00:00
// Hide the cursor now
if ( g_Config . bHideCursor )
XDefineCursor ( GLWin . dpy , GLWin . win , GLWin . blankCursor ) ;
2010-04-01 23:13:26 +00:00
# endif
return success ;
2010-02-20 04:18:19 +00:00
2010-04-01 23:13:26 +00:00
}
bool OpenGL_MakeCurrent ( )
{
// connect the glx-context to the window
# if defined(USE_WX) && USE_WX
GLWin . glCanvas - > SetCurrent ( * GLWin . glCtxt ) ;
# elif defined(HAVE_COCOA) && HAVE_COCOA
cocoaGLMakeCurrent ( GLWin . cocoaCtx , GLWin . cocoaWin ) ;
# elif defined(_WIN32)
return wglMakeCurrent ( hDC , hRC )
# elif defined(HAVE_X11) && HAVE_X11
return glXMakeCurrent ( GLWin . dpy , GLWin . win , GLWin . ctx ) ;
2008-12-08 05:25:12 +00:00
# endif
return true ;
}
// Update window width, size and etc. Called from Render.cpp
void OpenGL_Update ( )
{
2009-09-09 20:47:11 +00:00
# if defined(USE_WX) && USE_WX
2010-02-20 04:18:19 +00:00
RECT rcWindow = { 0 } ;
rcWindow . right = GLWin . width ;
rcWindow . bottom = GLWin . height ;
// TODO fill in
2008-12-13 23:19:56 +00:00
2008-12-10 23:23:05 +00:00
# elif defined(HAVE_COCOA) && HAVE_COCOA
2009-02-28 16:33:59 +00:00
RECT rcWindow = { 0 } ;
2010-02-20 04:18:19 +00:00
rcWindow . right = GLWin . width ;
rcWindow . bottom = GLWin . height ;
2008-12-08 05:25:12 +00:00
# elif defined(_WIN32)
RECT rcWindow ;
2009-02-19 06:52:01 +00:00
if ( ! EmuWindow : : GetParentWnd ( ) )
{
2009-02-28 16:33:59 +00:00
// We are not rendering to a child window - use client size.
GetClientRect ( EmuWindow : : GetWnd ( ) , & rcWindow ) ;
2008-12-08 05:25:12 +00:00
}
else
{
2009-02-28 16:33:59 +00:00
// We are rendering to a child window - use parent size.
2008-12-08 05:25:12 +00:00
GetWindowRect ( EmuWindow : : GetParentWnd ( ) , & rcWindow ) ;
}
// ---------------------------------------------------------------------------------------
// Get the new window width and height
// ------------------
// See below for documentation
// ------------------
2010-02-20 04:18:19 +00:00
int width = rcWindow . right - rcWindow . left ;
int height = rcWindow . bottom - rcWindow . top ;
2008-12-08 05:25:12 +00:00
2009-02-19 06:52:01 +00:00
// If we are rendering to a child window
fixed fps limiting when using using virtual xfb, now fps = vps, in fact now real xfb is as fast as no using xfb, i'm thinking now that the correct thing is leave it enabled as default, and even remove the option.
the problem is one strange behavior i found, in opengl when xfb is enable, frame limit causes the frame rate to be limited exact half the correct speed, so if you choose auto and the game uses 30 fps you get 15 fps
so in opengl, you have to limit to the exact double of the game speed, 100 to pal games and 120 to ntsc.
in d3d this not happened every time, it just happen when you change some time consuming setting like changing the ssaa or resizing the window, in that case you have to disable and re enable frame limit to get the correct fps
to all the devs please if you can help me debug this, will give you a lot of thanks as i'm short in time to debug this error and is driving me crazy not to find the source of the problem.
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@5249 8ced0084-cf51-0410-be5f-012b33b47a6e
2010-03-28 23:51:32 +00:00
if ( EmuWindow : : GetParentWnd ( ) ! = 0 & & ( s_backbuffer_width ! = width | | s_backbuffer_height ! = height ) & & width > = 4 & & height > = 4 )
{
2008-12-25 15:56:36 +00:00
: : MoveWindow ( EmuWindow : : GetWnd ( ) , 0 , 0 , width , height , FALSE ) ;
fixed fps limiting when using using virtual xfb, now fps = vps, in fact now real xfb is as fast as no using xfb, i'm thinking now that the correct thing is leave it enabled as default, and even remove the option.
the problem is one strange behavior i found, in opengl when xfb is enable, frame limit causes the frame rate to be limited exact half the correct speed, so if you choose auto and the game uses 30 fps you get 15 fps
so in opengl, you have to limit to the exact double of the game speed, 100 to pal games and 120 to ntsc.
in d3d this not happened every time, it just happen when you change some time consuming setting like changing the ssaa or resizing the window, in that case you have to disable and re enable frame limit to get the correct fps
to all the devs please if you can help me debug this, will give you a lot of thanks as i'm short in time to debug this error and is driving me crazy not to find the source of the problem.
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@5249 8ced0084-cf51-0410-be5f-012b33b47a6e
2010-03-28 23:51:32 +00:00
s_backbuffer_width = width ;
s_backbuffer_height = height ;
}
2008-12-08 05:25:12 +00:00
2008-12-10 23:23:05 +00:00
# elif defined(HAVE_X11) && HAVE_X11
2008-12-08 05:25:12 +00:00
# endif
}
// Close plugin
void OpenGL_Shutdown ( )
{
2009-09-09 20:47:11 +00:00
# if defined(USE_WX) && USE_WX
2009-03-22 11:21:44 +00:00
delete GLWin . glCanvas ;
delete GLWin . frame ;
2009-09-09 20:47:11 +00:00
# elif defined(HAVE_COCOA) && HAVE_COCOA
2010-02-12 12:41:53 +00:00
cocoaGLDeleteWindow ( GLWin . cocoaWin ) ;
2009-09-09 20:47:11 +00:00
cocoaGLDelete ( GLWin . cocoaCtx ) ;
2008-12-08 05:25:12 +00:00
# elif defined(_WIN32)
2009-03-22 11:21:44 +00:00
if ( hRC ) // Do We Have A Rendering Context?
{
if ( ! wglMakeCurrent ( NULL , NULL ) ) // Are We Able To Release The DC And RC Contexts?
{
2008-12-08 05:25:12 +00:00
// [F|RES]: if this fails i dont see the message box and
// cant get out of the modal state so i disable it.
// This function fails only if i render to main window
2009-03-22 11:21:44 +00:00
// MessageBox(NULL,"Release Of DC And RC Failed.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);
}
2008-12-08 05:25:12 +00:00
2009-03-22 11:21:44 +00:00
if ( ! wglDeleteContext ( hRC ) ) // Are We Able To Delete The RC?
{
ERROR_LOG ( VIDEO , " Release Rendering Context Failed. " ) ;
}
hRC = NULL ; // Set RC To NULL
}
2008-12-08 05:25:12 +00:00
2009-03-22 11:21:44 +00:00
if ( hDC & & ! ReleaseDC ( EmuWindow : : GetWnd ( ) , hDC ) ) // Are We Able To Release The DC
{
ERROR_LOG ( VIDEO , " Release Device Context Failed. " ) ;
hDC = NULL ; // Set DC To NULL
}
2008-12-08 05:25:12 +00:00
# elif defined(HAVE_X11) && HAVE_X11
2010-02-20 04:18:19 +00:00
DestroyXWindow ( ) ;
2010-03-15 23:25:11 +00:00
if ( GLWin . xEventThread )
GLWin . xEventThread - > WaitForDeath ( ) ;
GLWin . xEventThread = NULL ;
2010-02-16 04:59:45 +00:00
# if defined(HAVE_XRANDR) && HAVE_XRANDR
2010-02-20 04:18:19 +00:00
if ( GLWin . fullSize > = 0 )
XRRFreeScreenConfigInfo ( GLWin . screenConfig ) ;
2010-02-07 02:41:02 +00:00
# endif
2010-02-16 04:59:45 +00:00
if ( g_Config . bHideCursor )
2010-02-20 04:18:19 +00:00
XFreeCursor ( GLWin . dpy , GLWin . blankCursor ) ;
2009-03-22 11:21:44 +00:00
if ( GLWin . ctx )
{
glXDestroyContext ( GLWin . dpy , GLWin . ctx ) ;
2010-03-12 04:10:48 +00:00
XFreeColormap ( GLWin . dpy , GLWin . attr . colormap ) ;
2009-03-22 11:21:44 +00:00
XCloseDisplay ( GLWin . dpy ) ;
GLWin . ctx = NULL ;
}
2008-12-08 09:58:02 +00:00
# endif
2008-12-08 05:25:12 +00:00
}
2009-02-21 13:11:49 +00:00
2009-03-22 11:21:44 +00:00
GLuint OpenGL_ReportGLError ( const char * function , const char * file , int line )
{
GLint err = glGetError ( ) ;
if ( err ! = GL_NO_ERROR )
{
ERROR_LOG ( VIDEO , " %s:%d: (%s) OpenGL error 0x%x - %s \n " , file , line , function , err , gluErrorString ( err ) ) ;
}
return err ;
}
void OpenGL_ReportARBProgramError ( )
2009-02-21 13:11:49 +00:00
{
const GLubyte * pstr = glGetString ( GL_PROGRAM_ERROR_STRING_ARB ) ;
if ( pstr ! = NULL & & pstr [ 0 ] ! = 0 )
{
GLint loc = 0 ;
glGetIntegerv ( GL_PROGRAM_ERROR_POSITION_ARB , & loc ) ;
2009-02-28 01:26:56 +00:00
ERROR_LOG ( VIDEO , " program error at %d: " , loc ) ;
ERROR_LOG ( VIDEO , ( char * ) pstr ) ;
2009-03-21 20:07:56 +00:00
ERROR_LOG ( VIDEO , " " ) ;
2009-02-21 13:11:49 +00:00
}
2009-03-22 11:21:44 +00:00
}
2009-02-21 13:11:49 +00:00
2009-03-22 11:21:44 +00:00
bool OpenGL_ReportFBOError ( const char * function , const char * file , int line )
{
unsigned int fbo_status = glCheckFramebufferStatusEXT ( GL_FRAMEBUFFER_EXT ) ;
if ( fbo_status ! = GL_FRAMEBUFFER_COMPLETE_EXT )
2009-02-21 13:11:49 +00:00
{
2009-03-22 11:21:44 +00:00
const char * error = " - " ;
switch ( fbo_status )
{
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT : error = " INCOMPLETE_ATTACHMENT_EXT " ; break ;
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT : error = " INCOMPLETE_MISSING_ATTACHMENT_EXT " ; break ;
case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT : error = " INCOMPLETE_DIMENSIONS_EXT " ; break ;
case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT : error = " INCOMPLETE_FORMATS_EXT " ; break ;
case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT : error = " INCOMPLETE_DRAW_BUFFER_EXT " ; break ;
case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT : error = " INCOMPLETE_READ_BUFFER_EXT " ; break ;
case GL_FRAMEBUFFER_UNSUPPORTED_EXT : error = " UNSUPPORTED_EXT " ; break ;
}
ERROR_LOG ( VIDEO , " %s:%d: (%s) OpenGL FBO error - %s \n " , file , line , function , error ) ;
return false ;
2009-02-21 13:11:49 +00:00
}
2009-03-22 11:21:44 +00:00
return true ;
2009-02-21 13:11:49 +00:00
}
2009-09-09 19:52:45 +00:00