| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434 |
- #include <windows.h>
- #include <gl/gl.h>
- #include <brl.mod/system.mod/system.h>
- enum{
- _BACKBUFFER= 0x2,
- _ALPHABUFFER= 0x4,
- _DEPTHBUFFER= 0x8,
- _STENCILBUFFER= 0x10,
- _ACCUMBUFFER= 0x20,
- };
- enum{
- MODE_SHARED,
- MODE_WIDGET,
- MODE_WINDOW,
- MODE_DISPLAY
- };
- extern int _bbusew;
- static const char *CLASS_NAME="BlitzMax GLGraphics";
- static const wchar_t *CLASS_NAMEW=L"BlitzMax GLGraphics";
- typedef struct BBGLContext BBGLContext;
- struct BBGLContext{
- BBGLContext *succ;
- int mode,width,height,depth,hertz,flags;
-
- HDC hdc;
- HWND hwnd;
- HGLRC hglrc;
- };
- static BBGLContext *_contexts;
- static BBGLContext *_sharedContext;
- static BBGLContext *_currentContext;
- typedef BOOL (APIENTRY * WGLSWAPINTERVALEXT) (int);
- void bbGLGraphicsClose( BBGLContext *context );
- void bbGLGraphicsGetSettings( BBGLContext *context,int *width,int *height,int *depth,int *hertz,int *flags );
- void bbGLGraphicsSetGraphics( BBGLContext *context );
- static const char *appTitle(){
- return bbTmpCString( bbAppTitle );
- }
- static const wchar_t *appTitleW(){
- return bbTmpWString( bbAppTitle );
- }
- static void _initPfd( PIXELFORMATDESCRIPTOR *pfd,int flags ){
- memset( pfd,0,sizeof(*pfd) );
- pfd->nSize=sizeof(pfd);
- pfd->nVersion=1;
- pfd->cColorBits=1;
- pfd->iPixelType=PFD_TYPE_RGBA;
- pfd->iLayerType=PFD_MAIN_PLANE;
- pfd->dwFlags=PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL;
- pfd->dwFlags|=(flags & _BACKBUFFER) ? PFD_DOUBLEBUFFER : 0;
- pfd->cAlphaBits=(flags & _ALPHABUFFER) ? 1 : 0;
- pfd->cDepthBits=(flags & _DEPTHBUFFER) ? 1 : 0;
- pfd->cStencilBits=(flags & _STENCILBUFFER) ? 1 : 0;
- pfd->cAccumBits=(flags & _ACCUMBUFFER) ? 1 : 0;
- }
- static int _setSwapInterval( int n ){
- WGLSWAPINTERVALEXT wglSwapIntervalEXT=(WGLSWAPINTERVALEXT)wglGetProcAddress("wglSwapIntervalEXT");
- if( wglSwapIntervalEXT ) wglSwapIntervalEXT( n );
- }
- static _stdcall long _wndProc( HWND hwnd,UINT msg,WPARAM wp,LPARAM lp ){
- static HWND _fullScreen;
- BBGLContext *c;
- for( c=_contexts;c && c->hwnd!=hwnd;c=c->succ ){}
- if( !c ){
- return _bbusew ? DefWindowProcW( hwnd,msg,wp,lp ) : DefWindowProc( hwnd,msg,wp,lp );
- }
- bbSystemEmitOSEvent( hwnd,msg,wp,lp,&bbNullObject );
- switch( msg ){
- case WM_CLOSE:
- return 0;
- case WM_SYSCOMMAND:
- if (wp==SC_SCREENSAVE) return 1;
- if (wp==SC_MONITORPOWER) return 1;
- break;
- case WM_SYSKEYDOWN:
- if( wp!=VK_F4 ) return 0;
- break;
- case WM_SETFOCUS:
- if( c && c->mode==MODE_DISPLAY && hwnd!=_fullScreen ){
- DEVMODE dm;
- int swapInt=0;
- memset( &dm,0,sizeof(dm) );
- dm.dmSize=sizeof(dm);
- dm.dmPelsWidth=c->width;
- dm.dmPelsHeight=c->height;
- dm.dmBitsPerPel=c->depth;
- dm.dmFields=DM_PELSWIDTH|DM_PELSHEIGHT|DM_BITSPERPEL;
- if( c->hertz ){
- dm.dmDisplayFrequency=c->hertz;
- dm.dmFields|=DM_DISPLAYFREQUENCY;
- swapInt=1;
- }
- if( ChangeDisplaySettings( &dm,CDS_FULLSCREEN )==DISP_CHANGE_SUCCESSFUL ){
- _fullScreen=hwnd;
- }else if( dm.dmFields & DM_DISPLAYFREQUENCY ){
- dm.dmDisplayFrequency=0;
- dm.dmFields&=~DM_DISPLAYFREQUENCY;
- if( ChangeDisplaySettings( &dm,CDS_FULLSCREEN )==DISP_CHANGE_SUCCESSFUL ){
- _fullScreen=hwnd;
- swapInt=0;
- }
- }
- if( !_fullScreen ) bbExThrowCString( "GLGraphicsDriver failed to set display mode" );
-
- _setSwapInterval( swapInt );
- }
- return 0;
- case WM_DESTROY:
- case WM_KILLFOCUS:
- if( hwnd==_fullScreen ){
- ChangeDisplaySettings( 0,CDS_FULLSCREEN );
- ShowWindow( hwnd,SW_MINIMIZE );
- _setSwapInterval( 0 );
- _fullScreen=0;
- }
- return 0;
- case WM_PAINT:
- ValidateRect( hwnd,0 );
- return 0;
- }
- return _bbusew ? DefWindowProcW( hwnd,msg,wp,lp ) : DefWindowProc( hwnd,msg,wp,lp );
- }
- static void _initWndClass(){
- static int _done;
- if( _done ) return;
- if( _bbusew ){
- WNDCLASSEXW wc={sizeof(wc)};
- wc.style=CS_HREDRAW|CS_VREDRAW|CS_OWNDC;
- wc.lpfnWndProc=(WNDPROC)_wndProc;
- wc.hInstance=GetModuleHandle(0);
- wc.lpszClassName=CLASS_NAMEW;
- wc.hCursor=(HCURSOR)LoadCursor( 0,IDC_ARROW );
- wc.hbrBackground=0;
- if( !RegisterClassExW( &wc ) ) exit( -1 );
- }else{
- WNDCLASSEX wc={sizeof(wc)};
- wc.style=CS_HREDRAW|CS_VREDRAW|CS_OWNDC;
- wc.lpfnWndProc=(WNDPROC)_wndProc;
- wc.hInstance=GetModuleHandle(0);
- wc.lpszClassName=CLASS_NAME;
- wc.hCursor=(HCURSOR)LoadCursor( 0,IDC_ARROW );
- wc.hbrBackground=0;
- if( !RegisterClassEx( &wc ) ) exit( -1 );
- }
- _done=1;
- }
- static void _validateSize( BBGLContext *context ){
- if( context->mode==MODE_WIDGET ){
- RECT rect;
- GetClientRect( context->hwnd,&rect );
- context->width=rect.right-rect.left;
- context->height=rect.bottom-rect.top;
- }
- }
- void bbGLGraphicsShareContexts(){
- BBGLContext *context;
- HDC hdc;
- HWND hwnd;
- HGLRC hglrc;
- long pf;
- PIXELFORMATDESCRIPTOR pfd;
-
- if( _sharedContext ) return;
-
- _initWndClass();
-
- if( _bbusew ){
- hwnd=CreateWindowExW( 0,CLASS_NAMEW,0,WS_POPUP,0,0,1,1,0,0,GetModuleHandle(0),0 );
- }else{
- hwnd=CreateWindowEx( 0,CLASS_NAME,0,WS_POPUP,0,0,1,1,0,0,GetModuleHandle(0),0 );
- }
-
- _initPfd( &pfd,0 );
-
- hdc=GetDC( hwnd );
- pf=ChoosePixelFormat( hdc,&pfd );
- if( !pf ){
- exit(0);
- DestroyWindow( hwnd );
- return;
- }
- SetPixelFormat( hdc,pf,&pfd );
- hglrc=wglCreateContext( hdc );
- if( !hglrc ) exit(0);
-
- _sharedContext=(BBGLContext*)malloc( sizeof(BBGLContext) );
- memset( _sharedContext,0,sizeof(BBGLContext) );
- _sharedContext->mode=MODE_SHARED;
- _sharedContext->width=1;
- _sharedContext->height=1;
-
- _sharedContext->hdc=hdc;
- _sharedContext->hwnd=hwnd;
- _sharedContext->hglrc=hglrc;
- }
- int bbGLGraphicsGraphicsModes( int *modes,int count ){
- int i=0,n=0;
- while( n<count ){
- DEVMODE mode;
- mode.dmSize=sizeof(DEVMODE);
- mode.dmDriverExtra=0;
- if( !EnumDisplaySettings(0,i++,&mode) ) break;
- if( mode.dmBitsPerPel<16 ) continue;
- *modes++=mode.dmPelsWidth;
- *modes++=mode.dmPelsHeight;
- *modes++=mode.dmBitsPerPel;
- *modes++=mode.dmDisplayFrequency;
- ++n;
- }
- return n;
- }
- BBGLContext *bbGLGraphicsAttachGraphics( HWND hwnd,int flags ){
- BBGLContext *context;
-
- HDC hdc;
- HGLRC hglrc;
-
- long pf;
- PIXELFORMATDESCRIPTOR pfd;
- RECT rect;
-
- _initWndClass();
-
- hdc=GetDC( hwnd );
- if( !hdc ) return 0;
-
- _initPfd( &pfd,flags );
- pf=ChoosePixelFormat( hdc,&pfd );
- if( !pf ) return 0;
- SetPixelFormat( hdc,pf,&pfd );
- hglrc=wglCreateContext( hdc );
-
- if( _sharedContext ) wglShareLists( _sharedContext->hglrc,hglrc );
-
- GetClientRect( hwnd,&rect );
-
- context=(BBGLContext*)malloc( sizeof(BBGLContext) );
- memset( context,0,sizeof(*context) );
-
- context->mode=MODE_WIDGET;
- context->width=rect.right;
- context->height=rect.bottom;
- context->flags=flags;
-
- context->hdc=hdc;
- context->hwnd=hwnd;
- context->hglrc=hglrc;
-
- context->succ=_contexts;
- _contexts=context;
-
- return context;
- }
- BBGLContext *bbGLGraphicsCreateGraphics( int width,int height,int depth,int hertz,int flags ){
- BBGLContext *context;
-
- int mode;
- HDC hdc;
- HWND hwnd;
- HGLRC hglrc;
-
- long pf;
- PIXELFORMATDESCRIPTOR pfd;
- int hwnd_style;
- RECT rect={0,0,width,height};
-
- _initWndClass();
-
- if( depth ){
- mode=MODE_DISPLAY;
- hwnd_style=WS_POPUP;
- }else{
- HWND desktop = GetDesktopWindow();
- RECT desktopRect;
- GetWindowRect(desktop, &desktopRect);
- rect.left=desktopRect.right/2-width/2;
- rect.top=desktopRect.bottom/2-height/2;
- rect.right=rect.left+width;
- rect.bottom=rect.top+height;
-
- mode=MODE_WINDOW;
- hwnd_style=WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX;
- }
-
- AdjustWindowRectEx( &rect,hwnd_style,0,0 );
-
- if( _bbusew ){
- hwnd=CreateWindowExW(
- 0,CLASS_NAMEW,appTitleW(),
- hwnd_style,rect.left,rect.top,rect.right-rect.left,rect.bottom-rect.top,0,0,GetModuleHandle(0),0 );
- }else{
- hwnd=CreateWindowEx(
- 0,CLASS_NAME,appTitle(),
- hwnd_style,rect.left,rect.top,rect.right-rect.left,rect.bottom-rect.top,0,0,GetModuleHandle(0),0 );
- }
-
- if( !hwnd ) return 0;
- GetClientRect( hwnd,&rect );
- width=rect.right-rect.left;
- height=rect.bottom-rect.top;
-
- _initPfd( &pfd,flags );
- hdc=GetDC( hwnd );
- pf=ChoosePixelFormat( hdc,&pfd );
- if( !pf ){
- DestroyWindow( hwnd );
- return 0;
- }
- SetPixelFormat( hdc,pf,&pfd );
- hglrc=wglCreateContext( hdc );
-
- if( _sharedContext ) wglShareLists( _sharedContext->hglrc,hglrc );
-
- context=(BBGLContext*)malloc( sizeof(BBGLContext) );
- memset( context,0,sizeof(context) );
-
- context->mode=mode;
- context->width=width;
- context->height=height;
- context->depth=depth;
- context->hertz=hertz;
- context->flags=flags;
-
- context->hdc=hdc;
- context->hwnd=hwnd;
- context->hglrc=hglrc;
-
- context->succ=_contexts;
- _contexts=context;
-
- ShowWindow( hwnd,SW_SHOW );
-
- return context;
- }
- void bbGLGraphicsGetSettings( BBGLContext *context,int *width,int *height,int *depth,int *hertz,int *flags ){
- _validateSize( context );
- *width=context->width;
- *height=context->height;
- *depth=context->depth;
- *hertz=context->hertz;
- *flags=context->flags;
- }
- void bbGLGraphicsClose( BBGLContext *context ){
- BBGLContext **p,*t;
-
- for( p=&_contexts;(t=*p) && (t!=context);p=&t->succ ){}
- if( !t ) return;
-
- if( t==_currentContext ){
- bbGLGraphicsSetGraphics( 0 );
- }
-
- wglDeleteContext( context->hglrc );
- if( t->mode==MODE_DISPLAY || t->mode==MODE_WINDOW ){
- DestroyWindow( t->hwnd );
- }
-
- *p=t->succ;
- }
- void bbGLGraphicsSetGraphics( BBGLContext *context ){
- if( context==_currentContext ) return;
-
- _currentContext=context;
-
- if( context ){
- wglMakeCurrent( context->hdc,context->hglrc );
- }else{
- wglMakeCurrent( 0,0 );
- }
- }
- void bbGLGraphicsFlip( int sync ){
- if( !_currentContext ) return;
-
- _setSwapInterval( sync ? 1 : 0 );
-
- /*
- static int _sync=-1;
- sync=sync ? 1 : 0;
- if( sync!=_sync ){
- _sync=sync;
- _setSwapInterval( _sync );
- }
- */
- SwapBuffers( _currentContext->hdc );
- }
|