glgraphics.win32.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588
  1. #include <windows.h>
  2. #include <gl/gl.h>
  3. #include <brl.mod/systemdefault.mod/system.h>
  4. enum{
  5. _BACKBUFFER= 0x2,
  6. _ALPHABUFFER= 0x4,
  7. _DEPTHBUFFER= 0x8,
  8. _STENCILBUFFER= 0x10,
  9. _ACCUMBUFFER= 0x20,
  10. _BORDERLESS= 0x40,
  11. _FULLSCREEN_DESKTOP= 0x80,
  12. //win32 exclusive
  13. _MULTISAMPLE2X= 0x100,
  14. _MULTISAMPLE4X= 0x200,
  15. _MULTISAMPLE8X= 0x400,
  16. _MULTISAMPLE16X=0x800,
  17. _HIDDEN=0x1000,
  18. //add them here so they are not accidentally used
  19. _SWAPINTERVAL0 = 0x10000,
  20. _SWAPINTERVAL1 = 0x20000,
  21. };
  22. enum{
  23. MODE_SHARED,
  24. MODE_WIDGET,
  25. MODE_WINDOW,
  26. MODE_DISPLAY
  27. };
  28. //------------
  29. // NEW SECTION
  30. //------------
  31. #define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000
  32. #define WGL_DRAW_TO_WINDOW_ARB 0x2001
  33. #define WGL_DRAW_TO_BITMAP_ARB 0x2002
  34. #define WGL_ACCELERATION_ARB 0x2003
  35. #define WGL_NEED_PALETTE_ARB 0x2004
  36. #define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005
  37. #define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006
  38. #define WGL_SWAP_METHOD_ARB 0x2007
  39. #define WGL_NUMBER_OVERLAYS_ARB 0x2008
  40. #define WGL_NUMBER_UNDERLAYS_ARB 0x2009
  41. #define WGL_TRANSPARENT_ARB 0x200A
  42. #define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037
  43. #define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038
  44. #define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039
  45. #define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A
  46. #define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B
  47. #define WGL_SHARE_DEPTH_ARB 0x200C
  48. #define WGL_SHARE_STENCIL_ARB 0x200D
  49. #define WGL_SHARE_ACCUM_ARB 0x200E
  50. #define WGL_SUPPORT_GDI_ARB 0x200F
  51. #define WGL_SUPPORT_OPENGL_ARB 0x2010
  52. #define WGL_DOUBLE_BUFFER_ARB 0x2011
  53. #define WGL_STEREO_ARB 0x2012
  54. #define WGL_PIXEL_TYPE_ARB 0x2013
  55. #define WGL_COLOR_BITS_ARB 0x2014
  56. #define WGL_RED_BITS_ARB 0x2015
  57. #define WGL_RED_SHIFT_ARB 0x2016
  58. #define WGL_GREEN_BITS_ARB 0x2017
  59. #define WGL_GREEN_SHIFT_ARB 0x2018
  60. #define WGL_BLUE_BITS_ARB 0x2019
  61. #define WGL_BLUE_SHIFT_ARB 0x201A
  62. #define WGL_ALPHA_BITS_ARB 0x201B
  63. #define WGL_ALPHA_SHIFT_ARB 0x201C
  64. #define WGL_ACCUM_BITS_ARB 0x201D
  65. #define WGL_ACCUM_RED_BITS_ARB 0x201E
  66. #define WGL_ACCUM_GREEN_BITS_ARB 0x201F
  67. #define WGL_ACCUM_BLUE_BITS_ARB 0x2020
  68. #define WGL_ACCUM_ALPHA_BITS_ARB 0x2021
  69. #define WGL_DEPTH_BITS_ARB 0x2022
  70. #define WGL_STENCIL_BITS_ARB 0x2023
  71. #define WGL_AUX_BUFFERS_ARB 0x2024
  72. #define WGL_NO_ACCELERATION_ARB 0x2025
  73. #define WGL_GENERIC_ACCELERATION_ARB 0x2026
  74. #define WGL_FULL_ACCELERATION_ARB 0x2027
  75. #define WGL_SWAP_EXCHANGE_ARB 0x2028
  76. #define WGL_SWAP_COPY_ARB 0x2029
  77. #define WGL_SWAP_UNDEFINED_ARB 0x202A
  78. #define WGL_TYPE_RGBA_ARB 0x202B
  79. #define WGL_TYPE_COLORINDEX_ARB 0x202C
  80. #define WGL_SAMPLE_BUFFERS_ARB 0x2041
  81. #define WGL_SAMPLES_ARB 0x2042
  82. static BOOL _wglChoosePixelFormatARB( HDC hDC, const int *intAttribs, const FLOAT *floatAttribs, unsigned int maxFormats, int *lPixelFormat, unsigned int *numFormats){
  83. //Define function pointer datatype
  84. typedef BOOL (APIENTRY * WGLCHOOSEPIXELFORMATARB) (HDC hDC, const int *intAttribs, const FLOAT *floatAttribs, unsigned int maxFormats, int *lPixelFormat, unsigned int *numFormats);
  85. //Get the "wglChoosePixelFormatARB" function
  86. WGLCHOOSEPIXELFORMATARB wglChoosePixelFormatARB = (WGLCHOOSEPIXELFORMATARB)wglGetProcAddress("wglChoosePixelFormatARB");
  87. if(wglChoosePixelFormatARB)
  88. return wglChoosePixelFormatARB(hDC, intAttribs, floatAttribs, maxFormats, lPixelFormat, numFormats);
  89. else
  90. MessageBox(0,"wglChoosePixelFormatARB() function not found!","Error",0);
  91. return 0;
  92. }
  93. static int MyChoosePixelFormat( HDC hDC, const BBInt64 flags ){
  94. //Extract multisample mode from flags
  95. int multisample = 0;
  96. if (_MULTISAMPLE2X & flags) multisample = 2;
  97. else if (_MULTISAMPLE4X & flags) multisample = 4;
  98. else if (_MULTISAMPLE8X & flags) multisample = 8;
  99. else if (_MULTISAMPLE16X & flags) multisample = 16;
  100. //Empty float attributes array
  101. float floatAttribs[] = {0.0,0.0};
  102. //Some variables
  103. int lPixelFormat = 0;
  104. int numFormats=1;
  105. int result=0;
  106. //Include the multisample in the flags
  107. if (multisample > 0){
  108. int intAttribs[] = {WGL_DRAW_TO_WINDOW_ARB,GL_TRUE,WGL_SUPPORT_OPENGL_ARB,GL_TRUE,WGL_ACCELERATION_ARB,WGL_FULL_ACCELERATION_ARB,WGL_COLOR_BITS_ARB,24,WGL_ALPHA_BITS_ARB,8,WGL_DEPTH_BITS_ARB,16,WGL_DOUBLE_BUFFER_ARB,GL_TRUE,WGL_SAMPLE_BUFFERS_ARB,GL_TRUE,WGL_SAMPLES_ARB,multisample,0,0};
  109. result=_wglChoosePixelFormatARB(hDC, &intAttribs, &floatAttribs, 1, &lPixelFormat, &numFormats);
  110. }else{
  111. int intAttribs[] = {WGL_DRAW_TO_WINDOW_ARB,GL_TRUE,WGL_SUPPORT_OPENGL_ARB,GL_TRUE,WGL_ACCELERATION_ARB,WGL_FULL_ACCELERATION_ARB,WGL_COLOR_BITS_ARB,24,WGL_ALPHA_BITS_ARB,8,WGL_DEPTH_BITS_ARB,16,WGL_DOUBLE_BUFFER_ARB,GL_TRUE,WGL_SAMPLE_BUFFERS_ARB,GL_FALSE,0,0};
  112. result=_wglChoosePixelFormatARB(hDC, &intAttribs, &floatAttribs, 1, &lPixelFormat, &numFormats);
  113. }
  114. //If result=True return lPixelFormat
  115. if (result > 0){
  116. return lPixelFormat;
  117. }else{
  118. MessageBox(0,"wglChoosePixelFormatARB() failed.","Error",MB_OK);
  119. return 0;
  120. }
  121. }
  122. //------------
  123. //
  124. //------------
  125. extern int _bbusew;
  126. static const char *CLASS_NAME="BlitzMax GLGraphics";
  127. static const wchar_t *CLASS_NAMEW=L"BlitzMax GLGraphics";
  128. typedef struct BBGLContext BBGLContext;
  129. struct BBGLContext{
  130. BBGLContext *succ;
  131. int mode,width,height,depth,hertz;
  132. BBInt64 flags;
  133. HDC hdc;
  134. HWND hwnd;
  135. HGLRC hglrc;
  136. };
  137. static BBGLContext *_contexts;
  138. static BBGLContext *_sharedContext;
  139. static BBGLContext *_currentContext;
  140. typedef BOOL (APIENTRY * WGLSWAPINTERVALEXT) (int);
  141. void bbGLGraphicsClose( BBGLContext *context );
  142. void bbGLGraphicsGetSettings( BBGLContext *context,int *width,int *height,int *depth,int *hertz,BBInt64 *flags );
  143. void bbGLGraphicsSetGraphics( BBGLContext *context );
  144. static void _initPfd( PIXELFORMATDESCRIPTOR *pfd,BBInt64 flags ){
  145. memset( pfd,0,sizeof(*pfd) );
  146. pfd->nSize=sizeof(pfd);
  147. pfd->nVersion=1;
  148. pfd->cColorBits=1;
  149. pfd->iPixelType=PFD_TYPE_RGBA;
  150. pfd->iLayerType=PFD_MAIN_PLANE;
  151. pfd->dwFlags=PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL;
  152. pfd->dwFlags|=(flags & _BACKBUFFER) ? PFD_DOUBLEBUFFER : 0;
  153. pfd->cAlphaBits=(flags & _ALPHABUFFER) ? 1 : 0;
  154. pfd->cDepthBits=(flags & _DEPTHBUFFER) ? 1 : 0;
  155. pfd->cStencilBits=(flags & _STENCILBUFFER) ? 1 : 0;
  156. pfd->cAccumBits=(flags & _ACCUMBUFFER) ? 1 : 0;
  157. }
  158. static int _setSwapInterval( int n ){
  159. WGLSWAPINTERVALEXT wglSwapIntervalEXT=(WGLSWAPINTERVALEXT)wglGetProcAddress("wglSwapIntervalEXT");
  160. if( wglSwapIntervalEXT ) wglSwapIntervalEXT( n );
  161. }
  162. static _stdcall long _wndProc( HWND hwnd,UINT msg,WPARAM wp,LPARAM lp ){
  163. static HWND _fullScreen;
  164. BBGLContext *c;
  165. for( c=_contexts;c && c->hwnd!=hwnd;c=c->succ ){}
  166. if( !c ){
  167. return _bbusew ? DefWindowProcW( hwnd,msg,wp,lp ) : DefWindowProc( hwnd,msg,wp,lp );
  168. }
  169. bbSystemEmitOSEvent( hwnd,msg,wp,lp,&bbNullObject );
  170. switch( msg ){
  171. case WM_CLOSE:
  172. return 0;
  173. case WM_SYSCOMMAND:
  174. if (wp==SC_SCREENSAVE) return 1;
  175. if (wp==SC_MONITORPOWER) return 1;
  176. break;
  177. case WM_SYSKEYDOWN:
  178. if( wp!=VK_F4 ) return 0;
  179. break;
  180. case WM_SETFOCUS:
  181. if( c && c->mode==MODE_DISPLAY && hwnd!=_fullScreen ){
  182. DEVMODE dm;
  183. int swapInt=0;
  184. memset( &dm,0,sizeof(dm) );
  185. dm.dmSize=sizeof(dm);
  186. dm.dmPelsWidth=c->width;
  187. dm.dmPelsHeight=c->height;
  188. dm.dmBitsPerPel=c->depth;
  189. dm.dmFields=DM_PELSWIDTH|DM_PELSHEIGHT|DM_BITSPERPEL;
  190. if( c->hertz ){
  191. dm.dmDisplayFrequency=c->hertz;
  192. dm.dmFields|=DM_DISPLAYFREQUENCY;
  193. swapInt=1;
  194. }
  195. if( ChangeDisplaySettings( &dm,CDS_FULLSCREEN )==DISP_CHANGE_SUCCESSFUL ){
  196. _fullScreen=hwnd;
  197. }else if( dm.dmFields & DM_DISPLAYFREQUENCY ){
  198. dm.dmDisplayFrequency=0;
  199. dm.dmFields&=~DM_DISPLAYFREQUENCY;
  200. if( ChangeDisplaySettings( &dm,CDS_FULLSCREEN )==DISP_CHANGE_SUCCESSFUL ){
  201. _fullScreen=hwnd;
  202. swapInt=0;
  203. }
  204. }
  205. if( !_fullScreen ) bbExThrowCString( "GLGraphicsDriver failed to set display mode" );
  206. _setSwapInterval( swapInt );
  207. }
  208. return 0;
  209. case WM_DESTROY:
  210. case WM_KILLFOCUS:
  211. if( hwnd==_fullScreen ){
  212. ChangeDisplaySettings( 0,CDS_FULLSCREEN );
  213. ShowWindow( hwnd,SW_MINIMIZE );
  214. _setSwapInterval( 0 );
  215. _fullScreen=0;
  216. }
  217. return 0;
  218. case WM_PAINT:
  219. ValidateRect( hwnd,0 );
  220. return 0;
  221. case WM_LBUTTONDOWN: case WM_RBUTTONDOWN: case WM_MBUTTONDOWN:
  222. if( !_fullScreen ) SetCapture( hwnd );
  223. return 0;
  224. case WM_LBUTTONUP: case WM_RBUTTONUP: case WM_MBUTTONUP:
  225. if( !_fullScreen ) ReleaseCapture();
  226. return 0;
  227. }
  228. return _bbusew ? DefWindowProcW( hwnd,msg,wp,lp ) : DefWindowProc( hwnd,msg,wp,lp );
  229. }
  230. static void _initWndClass(){
  231. static int _done;
  232. if( _done ) return;
  233. if( _bbusew ){
  234. WNDCLASSEXW wc={sizeof(wc)};
  235. wc.style=CS_HREDRAW|CS_VREDRAW|CS_OWNDC;
  236. wc.lpfnWndProc=(WNDPROC)_wndProc;
  237. wc.hInstance=GetModuleHandle(0);
  238. wc.lpszClassName=CLASS_NAMEW;
  239. wc.hCursor=(HCURSOR)LoadCursor( 0,IDC_ARROW );
  240. wc.hIcon = bbAppIcon(wc.hInstance);
  241. wc.hbrBackground=0;
  242. if( !RegisterClassExW( &wc ) ) exit( -1 );
  243. }else{
  244. WNDCLASSEX wc={sizeof(wc)};
  245. wc.style=CS_HREDRAW|CS_VREDRAW|CS_OWNDC;
  246. wc.lpfnWndProc=(WNDPROC)_wndProc;
  247. wc.hInstance=GetModuleHandle(0);
  248. wc.lpszClassName=CLASS_NAME;
  249. wc.hCursor=(HCURSOR)LoadCursor( 0,IDC_ARROW );
  250. wc.hIcon = bbAppIcon(wc.hInstance);
  251. wc.hbrBackground=0;
  252. if( !RegisterClassEx( &wc ) ) exit( -1 );
  253. }
  254. _done=1;
  255. }
  256. static void _validateSize( BBGLContext *context ){
  257. if( context->mode==MODE_WIDGET ){
  258. RECT rect;
  259. GetClientRect( context->hwnd,&rect );
  260. context->width=rect.right-rect.left;
  261. context->height=rect.bottom-rect.top;
  262. }
  263. }
  264. void bbGLGraphicsShareContexts(){
  265. BBGLContext *context;
  266. HDC hdc;
  267. HWND hwnd;
  268. HGLRC hglrc;
  269. long pf;
  270. PIXELFORMATDESCRIPTOR pfd;
  271. if( _sharedContext ) return;
  272. _initWndClass();
  273. if( _bbusew ){
  274. hwnd=CreateWindowExW( 0,CLASS_NAMEW,0,WS_POPUP,0,0,1,1,0,0,GetModuleHandle(0),0 );
  275. }else{
  276. hwnd=CreateWindowEx( 0,CLASS_NAME,0,WS_POPUP,0,0,1,1,0,0,GetModuleHandle(0),0 );
  277. }
  278. _initPfd( &pfd,0 );
  279. hdc=GetDC( hwnd );
  280. pf=ChoosePixelFormat( hdc,&pfd );
  281. if( !pf ){
  282. exit(0);
  283. DestroyWindow( hwnd );
  284. return;
  285. }
  286. SetPixelFormat( hdc,pf,&pfd );
  287. hglrc=wglCreateContext( hdc );
  288. if( !hglrc ) exit(0);
  289. _sharedContext=(BBGLContext*)malloc( sizeof(BBGLContext) );
  290. memset( _sharedContext,0,sizeof(BBGLContext) );
  291. _sharedContext->mode=MODE_SHARED;
  292. _sharedContext->width=1;
  293. _sharedContext->height=1;
  294. _sharedContext->hdc=hdc;
  295. _sharedContext->hwnd=hwnd;
  296. _sharedContext->hglrc=hglrc;
  297. }
  298. int bbGLGraphicsGraphicsModes( int *modes,int count ){
  299. int i=0,n=0;
  300. while( n<count ){
  301. DEVMODE mode;
  302. mode.dmSize=sizeof(DEVMODE);
  303. mode.dmDriverExtra=0;
  304. if( !EnumDisplaySettings(0,i++,&mode) ) break;
  305. if( mode.dmBitsPerPel<16 ) continue;
  306. *modes++=mode.dmPelsWidth;
  307. *modes++=mode.dmPelsHeight;
  308. *modes++=mode.dmBitsPerPel;
  309. *modes++=mode.dmDisplayFrequency;
  310. ++n;
  311. }
  312. return n;
  313. }
  314. BBGLContext *bbGLGraphicsAttachGraphics( HWND hwnd,BBInt64 flags ){
  315. BBGLContext *context;
  316. HDC hdc;
  317. HGLRC hglrc;
  318. long pf;
  319. PIXELFORMATDESCRIPTOR pfd;
  320. RECT rect;
  321. _initWndClass();
  322. hdc=GetDC( hwnd );
  323. if( !hdc ) return 0;
  324. _initPfd( &pfd,flags );
  325. int multisample = 0;
  326. if (_MULTISAMPLE2X & flags) multisample = 2;
  327. else if (_MULTISAMPLE4X & flags) multisample = 4;
  328. else if (_MULTISAMPLE8X & flags) multisample = 8;
  329. else if (_MULTISAMPLE16X & flags) multisample = 16;
  330. if (multisample>0){
  331. pf=MyChoosePixelFormat( hdc,flags );
  332. }else{
  333. pf=ChoosePixelFormat( hdc,&pfd );
  334. }
  335. if( !pf ) return 0;
  336. SetPixelFormat( hdc,pf,&pfd );
  337. hglrc=wglCreateContext( hdc );
  338. if( _sharedContext ) wglShareLists( _sharedContext->hglrc,hglrc );
  339. GetClientRect( hwnd,&rect );
  340. context=(BBGLContext*)malloc( sizeof(BBGLContext) );
  341. memset( context,0,sizeof(*context) );
  342. context->mode=MODE_WIDGET;
  343. context->width=rect.right;
  344. context->height=rect.bottom;
  345. context->flags=flags;
  346. context->hdc=hdc;
  347. context->hwnd=hwnd;
  348. context->hglrc=hglrc;
  349. context->succ=_contexts;
  350. _contexts=context;
  351. return context;
  352. }
  353. BBGLContext *bbGLGraphicsCreateGraphics( int width,int height,int depth,int hertz, BBInt64 flags, int x, int y ){
  354. BBGLContext *context;
  355. int mode;
  356. HDC hdc;
  357. HWND hwnd;
  358. HGLRC hglrc;
  359. long pf;
  360. PIXELFORMATDESCRIPTOR pfd;
  361. int hwnd_style;
  362. RECT rect={0,0,width,height};
  363. _initWndClass();
  364. if( depth ){
  365. mode=MODE_DISPLAY;
  366. hwnd_style=WS_POPUP;
  367. }else{
  368. HWND desktop = GetDesktopWindow();
  369. RECT desktopRect;
  370. GetWindowRect(desktop, &desktopRect);
  371. rect.left=(x == -1) ? desktopRect.right/2-width/2 : x + GetSystemMetrics(SM_CXBORDER);
  372. rect.top=(y == -1) ? desktopRect.bottom/2-height/2: y + GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CYFIXEDFRAME);
  373. rect.right=rect.left+width;
  374. rect.bottom=rect.top+height;
  375. mode=MODE_WINDOW;
  376. hwnd_style=WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX;
  377. }
  378. AdjustWindowRectEx( &rect,hwnd_style,0,0 );
  379. if( _bbusew ){
  380. BBChar *p=bbStringToWString( bbAppTitle );
  381. hwnd=CreateWindowExW(
  382. 0,CLASS_NAMEW,p,
  383. hwnd_style,rect.left,rect.top,rect.right-rect.left,rect.bottom-rect.top,0,0,GetModuleHandle(0),0 );
  384. bbMemFree(p);
  385. }else{
  386. char *p=bbStringToCString( bbAppTitle );
  387. hwnd=CreateWindowEx(
  388. 0,CLASS_NAME,p,
  389. hwnd_style,rect.left,rect.top,rect.right-rect.left,rect.bottom-rect.top,0,0,GetModuleHandle(0),0 );
  390. bbMemFree(p);
  391. }
  392. if( !hwnd ) return 0;
  393. GetClientRect( hwnd,&rect );
  394. width=rect.right-rect.left;
  395. height=rect.bottom-rect.top;
  396. _initPfd( &pfd,flags );
  397. hdc=GetDC( hwnd );
  398. int multisample = 0;
  399. if (_MULTISAMPLE2X & flags) multisample = 2;
  400. else if (_MULTISAMPLE4X & flags) multisample = 4;
  401. else if (_MULTISAMPLE8X & flags) multisample = 8;
  402. else if (_MULTISAMPLE16X & flags) multisample = 16;
  403. if (multisample>0){
  404. pf=MyChoosePixelFormat( hdc,flags );
  405. }else{
  406. pf=ChoosePixelFormat( hdc,&pfd );
  407. }
  408. if( !pf ){
  409. DestroyWindow( hwnd );
  410. return 0;
  411. }
  412. SetPixelFormat( hdc,pf,&pfd );
  413. hglrc=wglCreateContext( hdc );
  414. if( _sharedContext ) wglShareLists( _sharedContext->hglrc,hglrc );
  415. context=(BBGLContext*)malloc( sizeof(BBGLContext) );
  416. memset( context,0,sizeof(context) );
  417. context->mode=mode;
  418. context->width=width;
  419. context->height=height;
  420. context->depth=depth;
  421. context->hertz=hertz;
  422. context->flags=flags;
  423. context->hdc=hdc;
  424. context->hwnd=hwnd;
  425. context->hglrc=hglrc;
  426. context->succ=_contexts;
  427. _contexts=context;
  428. ShowWindow( hwnd,SW_SHOW );
  429. return context;
  430. }
  431. void bbGLGraphicsGetSettings( BBGLContext *context,int *width,int *height,int *depth,int *hertz,BBInt64 *flags ){
  432. _validateSize( context );
  433. *width=context->width;
  434. *height=context->height;
  435. *depth=context->depth;
  436. *hertz=context->hertz;
  437. *flags=context->flags;
  438. }
  439. void bbGLGraphicsClose( BBGLContext *context ){
  440. BBGLContext **p,*t;
  441. for( p=&_contexts;(t=*p) && (t!=context);p=&t->succ ){}
  442. if( !t ) return;
  443. if( t==_currentContext ){
  444. bbGLGraphicsSetGraphics( 0 );
  445. }
  446. wglDeleteContext( context->hglrc );
  447. if( t->mode==MODE_DISPLAY || t->mode==MODE_WINDOW ){
  448. DestroyWindow( t->hwnd );
  449. }
  450. *p=t->succ;
  451. }
  452. void bbGLGraphicsSwapSharedContext(){
  453. if( wglGetCurrentContext()!=_sharedContext->hglrc ){
  454. wglMakeCurrent( _sharedContext->hdc,_sharedContext->hglrc );
  455. }else if( _currentContext ){
  456. wglMakeCurrent( _currentContext->hdc,_currentContext->hglrc );
  457. }else{
  458. wglMakeCurrent( 0,0 );
  459. }
  460. }
  461. void bbGLGraphicsSetGraphics( BBGLContext *context ){
  462. if( context==_currentContext ) return;
  463. _currentContext=context;
  464. if( context ){
  465. wglMakeCurrent( context->hdc,context->hglrc );
  466. }else{
  467. wglMakeCurrent( 0,0 );
  468. }
  469. }
  470. void bbGLGraphicsFlip( int sync ){
  471. if( !_currentContext ) return;
  472. _setSwapInterval( sync ? 1 : 0 );
  473. /*
  474. static int _sync=-1;
  475. sync=sync ? 1 : 0;
  476. if( sync!=_sync ){
  477. _sync=sync;
  478. _setSwapInterval( _sync );
  479. }
  480. */
  481. SwapBuffers( _currentContext->hdc );
  482. }