Advertisement
Guest User

code/graphics/gropengl.cpp x-style-mouse

a guest
Apr 5th, 2015
381
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 60.44 KB | None | 0 0
  1.  
  2.  
  3.  
  4.  
  5. #include "globalincs/pstypes.h"
  6. #include "cmdline/cmdline.h"
  7. #include "osapi/osapi.h"
  8. #include "graphics/2d.h"
  9. #include "render/3d.h"
  10. #include "bmpman/bmpman.h"
  11. #include "math/floating.h"
  12. #include "palman/palman.h"
  13. #include "globalincs/systemvars.h"
  14. #include "graphics/grinternal.h"
  15. #include "graphics/gropengl.h"
  16. #include "graphics/line.h"
  17. #include "nebula/neb.h"
  18. #include "io/mouse.h"
  19. #include "osapi/osregistry.h"
  20. #include "cfile/cfile.h"
  21. #include "io/timer.h"
  22. #include "ddsutils/ddsutils.h"
  23. #include "model/model.h"
  24. #include "debugconsole/console.h"
  25. #include "debugconsole/timerbar.h"
  26. #include "graphics/gropenglbmpman.h"
  27. #include "graphics/gropengllight.h"
  28. #include "graphics/gropengltexture.h"
  29. #include "graphics/gropenglextension.h"
  30. #include "graphics/gropengltnl.h"
  31. #include "graphics/gropenglbmpman.h"
  32. #include "graphics/gropengldraw.h"
  33. #include "graphics/gropenglshader.h"
  34. #include "graphics/gropenglstate.h"
  35. #include "graphics/gropenglpostprocessing.h"
  36.  
  37.  
  38. #if defined(_WIN32)
  39. #include <windows.h>
  40. #include <windowsx.h>
  41. #include <direct.h>
  42. #elif defined(__APPLE__)
  43. #include "OpenGL.h"
  44. #else
  45. typedef int ( * PFNGLXSWAPINTERVALSGIPROC) (int interval);
  46. #endif
  47.  
  48.  
  49. #if defined(_WIN32) && !defined(__GNUC__)
  50. #pragma comment (lib, "opengl32")
  51. #pragma comment (lib, "glu32")
  52. #endif
  53.  
  54. // minimum GL version we can reliably support is 1.2
  55. static const int MIN_REQUIRED_GL_VERSION = 12;
  56.  
  57. int GL_version = 0;
  58.  
  59. bool GL_initted = 0;
  60.  
  61. //0==no fog
  62. //1==linear
  63. //2==fog coord EXT
  64. //3==NV Radial
  65. int OGL_fogmode = 0;
  66.  
  67. #ifdef _WIN32
  68. static HDC GL_device_context = NULL;
  69. static HGLRC GL_render_context = NULL;
  70. static PIXELFORMATDESCRIPTOR GL_pfd;
  71. #endif
  72.  
  73. static ushort *GL_original_gamma_ramp = NULL;
  74.  
  75. int Use_VBOs = 0;
  76. int Use_PBOs = 0;
  77. int Use_GLSL = 0;
  78.  
  79. static int GL_dump_frames = 0;
  80. static ubyte *GL_dump_buffer = NULL;
  81. static int GL_dump_frame_number = 0;
  82. static int GL_dump_frame_count = 0;
  83. static int GL_dump_frame_count_max = 0;
  84. static int GL_dump_frame_size = 0;
  85.  
  86. static ubyte *GL_saved_screen = NULL;
  87. static ubyte *GL_saved_mouse_data = NULL;
  88. static int GL_saved_screen_id = -1;
  89. static GLuint GL_cursor_pbo = 0;
  90. static GLuint GL_screen_pbo = 0;
  91.  
  92. static int GL_mouse_saved = 0;
  93. static int GL_mouse_saved_x1 = 0;
  94. static int GL_mouse_saved_y1 = 0;
  95. static int GL_mouse_saved_x2 = 0;
  96. static int GL_mouse_saved_y2 = 0;
  97.  
  98. void opengl_save_mouse_area(int x, int y, int w, int h);
  99.  
  100. extern const char *Osreg_title;
  101.  
  102. extern GLfloat GL_anisotropy;
  103.  
  104. extern float FreeSpace_gamma;
  105. void gr_opengl_set_gamma(float gamma);
  106.  
  107. extern float FreeSpace_gamma;
  108. void gr_opengl_set_gamma(float gamma);
  109.  
  110. static int GL_fullscreen = 0;
  111. static int GL_windowed = 0;
  112. static int GL_minimized = 0;
  113.  
  114. static GLenum GL_read_format = GL_BGRA;
  115.  
  116.  
  117. void opengl_go_fullscreen()
  118. {
  119.     if (Cmdline_fullscreen_window || Cmdline_window || GL_fullscreen || Fred_running)
  120.         return;
  121.  
  122. #ifdef _WIN32
  123.     DEVMODE dm;
  124.     RECT cursor_clip;
  125.     HWND wnd = (HWND)os_get_window();
  126.  
  127.     Assert( wnd );
  128.  
  129.     os_suspend();
  130.  
  131.     memset((void*)&dm, 0, sizeof(DEVMODE));
  132.  
  133.     dm.dmSize = sizeof(DEVMODE);
  134.     dm.dmPelsHeight = gr_screen.max_h;
  135.     dm.dmPelsWidth = gr_screen.max_w;
  136.     dm.dmBitsPerPel = gr_screen.bits_per_pixel;
  137.     dm.dmDisplayFrequency = os_config_read_uint( NULL, NOX("OGL_RefreshRate"), 0 );
  138.     dm.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
  139.  
  140.     if (dm.dmDisplayFrequency)
  141.         dm.dmFields |= DM_DISPLAYFREQUENCY;
  142.  
  143.     if ( (ChangeDisplaySettings(&dm, CDS_FULLSCREEN)) != DISP_CHANGE_SUCCESSFUL ) {
  144.         if (dm.dmDisplayFrequency) {
  145.             // failed to switch with freq change so try without it just in case
  146.             dm.dmDisplayFrequency = 0;
  147.             dm.dmFields &= ~DM_DISPLAYFREQUENCY;
  148.  
  149.             if ( (ChangeDisplaySettings(&dm, CDS_FULLSCREEN)) != DISP_CHANGE_SUCCESSFUL ) {
  150.                 Warning( LOCATION, "Unable to go fullscreen on second attempt!" );
  151.             }
  152.         } else {
  153.             Warning( LOCATION, "Unable to go fullscreen!" );
  154.         }
  155.     }
  156.  
  157.     ShowWindow( wnd, SW_SHOWNORMAL );
  158.     UpdateWindow( wnd );
  159.  
  160.     SetForegroundWindow( wnd );
  161.     SetActiveWindow( wnd );
  162.     SetFocus( wnd );
  163.  
  164.     GetWindowRect((HWND)os_get_window(), &cursor_clip);
  165.     ClipCursor(&cursor_clip);
  166.     ShowCursor(FALSE);
  167.  
  168.     os_resume();  
  169. #else
  170.     if ( (os_config_read_uint(NULL, NOX("Fullscreen"), 1) == 1) && !(SDL_GetVideoSurface()->flags & SDL_FULLSCREEN) ) {
  171.         os_suspend();
  172.     //  SDL_WM_ToggleFullScreen( SDL_GetVideoSurface() );
  173.         if ( (SDL_SetVideoMode(gr_screen.max_w, gr_screen.max_h, 0, SDL_OPENGL | SDL_FULLSCREEN)) == NULL ) {
  174.             mprintf(("Couldn't go fullscreen!\n"));
  175.             if ( (SDL_SetVideoMode(gr_screen.max_w, gr_screen.max_h, 0, SDL_OPENGL)) == NULL ) {
  176.                 mprintf(("Couldn't drop back to windowed mode either!\n"));
  177.                 exit(1);
  178.             }
  179.         }
  180.         os_resume();
  181.     }
  182. #endif
  183.  
  184.     gr_opengl_set_gamma(FreeSpace_gamma);
  185.  
  186.     GL_fullscreen = 1;
  187.     GL_minimized = 0;
  188.     GL_windowed = 0;
  189. }
  190.  
  191. void opengl_go_windowed()
  192. {
  193.     if ( ( !Cmdline_fullscreen_window && !Cmdline_window ) /*|| GL_windowed*/ || Fred_running )
  194.         return;
  195.  
  196. #ifdef _WIN32
  197.     HWND wnd = (HWND)os_get_window();
  198.     Assert( wnd );
  199.  
  200.     // if we are already in a windowed state, then just make sure that we are sane and bail
  201.     if (GL_windowed) {
  202.         SetForegroundWindow( wnd );
  203.         SetActiveWindow( wnd );
  204.         SetFocus( wnd );
  205.  
  206.         ClipCursor(NULL);
  207.         ShowCursor(FALSE);
  208.         return;
  209.     }
  210.  
  211.     os_suspend();
  212.  
  213.     ShowWindow( wnd, SW_SHOWNORMAL );
  214.     UpdateWindow( wnd );
  215.  
  216.     SetForegroundWindow( wnd );
  217.     SetActiveWindow( wnd );
  218.     SetFocus( wnd );
  219.  
  220.     ClipCursor(NULL);
  221.     ShowCursor(FALSE);
  222.  
  223.     os_resume();  
  224.  
  225. #else
  226.     if (SDL_GetVideoSurface()->flags & SDL_FULLSCREEN) {
  227.         os_suspend();
  228.  
  229.     //  SDL_WM_ToggleFullScreen( SDL_GetVideoSurface() );
  230.         if ( (SDL_SetVideoMode(gr_screen.max_w, gr_screen.max_h, 0, SDL_OPENGL)) == NULL ) {
  231.             Warning( LOCATION, "Unable to enter windowed mode!" );
  232.         }
  233.  
  234.         os_resume();
  235.     }
  236. #endif
  237.  
  238.     GL_windowed = 1;
  239.     GL_minimized = 0;
  240.     GL_fullscreen = 0;
  241. }
  242.  
  243. void opengl_minimize()
  244. {
  245.     // don't attempt to minimize if we are already in a window, or already minimized, or when playing a movie
  246.     if (GL_minimized /*|| GL_windowed || Cmdline_window*/ || Fred_running)
  247.         return;
  248.  
  249. #ifdef _WIN32
  250.     HWND wnd = (HWND)os_get_window();
  251.     Assert( wnd );
  252.  
  253.     // if we are a window then just show the cursor and bail
  254.     if ( Cmdline_fullscreen_window || Cmdline_window || GL_windowed) {
  255.         ClipCursor(NULL);
  256.         ShowCursor(TRUE);
  257.         return;
  258.     }
  259.  
  260.     os_suspend();
  261.  
  262.     // restore original gamma settings
  263.     if (GL_original_gamma_ramp != NULL) {
  264.         SetDeviceGammaRamp( GL_device_context, GL_original_gamma_ramp );
  265.     }
  266.  
  267.     ShowWindow(wnd, SW_MINIMIZE);
  268.     ChangeDisplaySettings(NULL, 0);
  269.  
  270.     ClipCursor(NULL);
  271.     ShowCursor(TRUE);
  272.  
  273.     os_resume();
  274. #else
  275.     // lets not minimize if we are in windowed mode
  276.     if ( !(SDL_GetVideoSurface()->flags & SDL_FULLSCREEN) )
  277.         return;
  278.  
  279.     os_suspend();
  280.  
  281.     if (GL_original_gamma_ramp != NULL) {
  282.         SDL_SetGammaRamp( GL_original_gamma_ramp, (GL_original_gamma_ramp+256), (GL_original_gamma_ramp+512) );
  283.     }
  284.  
  285.     SDL_WM_IconifyWindow();
  286.     os_resume();
  287. #endif
  288.  
  289.     GL_minimized = 1;
  290.     GL_windowed = 0;
  291.     GL_fullscreen = 0;
  292. }
  293.  
  294. void gr_opengl_activate(int active)
  295. {
  296.     if (active) {
  297.         if (Cmdline_fullscreen_window||Cmdline_window)
  298.             opengl_go_windowed();
  299.         else
  300.             opengl_go_fullscreen();
  301.  
  302. #ifdef SCP_UNIX
  303.         // Check again and if we didn't go fullscreen turn on grabbing if possible
  304.         if(!Cmdline_no_grab && !(SDL_GetVideoSurface()->flags & SDL_FULLSCREEN)) {
  305.             SDL_WM_GrabInput(SDL_GRAB_ON);
  306.         }
  307. #endif
  308.     } else {
  309.         opengl_minimize();
  310.  
  311. #ifdef SCP_UNIX
  312.         // let go of mouse/keyboard
  313.         if (SDL_WM_GrabInput(SDL_GRAB_QUERY) == SDL_GRAB_ON)
  314.             SDL_WM_GrabInput(SDL_GRAB_OFF);
  315. #endif
  316.     }
  317. }
  318.  
  319. void gr_opengl_clear()
  320. {
  321.     glClearColor(gr_screen.current_clear_color.red / 255.0f,
  322.         gr_screen.current_clear_color.green / 255.0f,
  323.         gr_screen.current_clear_color.blue / 255.0f, gr_screen.current_clear_color.alpha / 255.0f);
  324.  
  325.     glClear ( GL_COLOR_BUFFER_BIT );
  326. }
  327.  
  328. //=======================####### BLOCK BEGIN  by hanzo@150402
  329. #ifndef __hanzo_mouseJoy_disable__
  330. extern int g_nMjoyX, g_nMjoyY;  // implemented in playercontrol.cpp
  331. extern float g_fMjoyDeadZn__;   // implemented in playercontrol.cpp
  332. extern int Gr_crosshair;        // implemented in 2d.cpp
  333. extern int Use_mouse_to_fly;
  334. static int l_isUsingMouseJoy = 0;
  335. static unsigned int l_CircleFrameCntMsk = 0;
  336.  
  337. #define __hanzo_minmax__( HzvAl_, HzmIn_, hZmAx_ ) { if( HzvAl_ < (HzmIn_) ) HzvAl_ = HzmIn_; if( HzvAl_ > (hZmAx_) ) HzvAl_ = hZmAx_; }
  338.  
  339. void drawMjoyDeadzoneCircle( GLubyte colR, GLubyte colG, GLubyte colB )
  340. {
  341. static GLfloat *circleVbuf = NULL;
  342. static int numCircleSeg = 0;
  343.  
  344.     if( circleVbuf == NULL ) {
  345.       int xc = gr_screen.max_w/2, yc = gr_screen.max_h/2, r = (int)g_fMjoyDeadZn__, segments = 4 + r, offset_x = gr_screen.offset_x, offset_y = gr_screen.offset_y;
  346.       float theta = 2 * PI / float(segments - 1), c, s, t, x1 = 1.0f, y1 = 0.0f, x2 = 1.0f, y2 = 0.0f, halflinewidth = 0.5f, inner_rad = r - halflinewidth, outer_rad = r + halflinewidth;
  347.       GLfloat *circle;
  348.  
  349.         c = cosf(theta); s = sinf(theta);
  350.         circle = circleVbuf = new GLfloat[segments * 4];
  351.  
  352.         for (int i=0; i < segments * 4; i+=4) {
  353.             circle[i] = i2fl(xc + (x2 * outer_rad) + offset_x); circle[i+1] = i2fl(yc + (y2 * outer_rad) + offset_y); circle[i+2] = i2fl(xc + (x2 * inner_rad) + offset_x); circle[i+3] = i2fl(yc + (y2 * inner_rad) + offset_y);
  354.             t = x2;     x2 = c * x1 - s * y1;   y2 = s * t + c * y1; x1 = x2; y1 = y2;
  355.         }
  356.         numCircleSeg = segments;
  357.     }
  358.  
  359.     GL_state.SetTextureSource(TEXTURE_SOURCE_NONE);
  360.     GL_state.SetAlphaBlendMode(ALPHA_BLEND_ALPHA_BLEND_ALPHA);
  361.     GL_state.SetZbufferType(ZBUFFER_TYPE_NONE);
  362.     gr_opengl_set_2d_matrix();
  363.     GL_state.Color(colR, colG, colB, 255 );
  364.     GL_state.Array.EnableClientVertex();
  365.     GL_state.Array.VertexPointer(2, GL_FLOAT, 0, circleVbuf);
  366.     glDrawArrays(GL_QUAD_STRIP, 0, numCircleSeg * 2);
  367.     GL_state.Array.DisableClientVertex();
  368.     GL_CHECK_FOR_ERRORS("end of deadzone_circle()");
  369.     gr_opengl_end_2d_matrix();
  370. }
  371.  
  372. static int _processMouseState_()
  373. {
  374. static int l_nPrevMouseVisible = 1;
  375. int i;
  376.  
  377.     i = mouse_is_visible();
  378.     if( i == l_nPrevMouseVisible ) return i;
  379.  
  380.     l_nPrevMouseVisible = i;
  381.     // reset the position
  382.     g_nMjoyX = g_nMjoyY = 0;
  383.  
  384.     l_isUsingMouseJoy = 0;
  385.     if( !i && Use_mouse_to_fly ) l_isUsingMouseJoy = 1;
  386.  
  387.     return i;
  388. }
  389. #endif
  390. //=======================####### BLOCK END
  391.  
  392. void gr_opengl_flip()
  393. {
  394.     if ( !GL_initted )
  395.         return;
  396.  
  397.     gr_reset_clip();
  398.  
  399.     mouse_eval_deltas();
  400.    
  401.     GL_mouse_saved = 0;
  402.    
  403. #ifndef __hanzo_mouseJoy_disable__
  404.     if ( _processMouseState_() ) { // if ( mouse_is_visible() ) { // modified by hanzo@150402
  405. #else
  406.     if ( mouse_is_visible() ) {
  407. #endif
  408.         int mx, my;
  409.  
  410.         gr_reset_clip();
  411.         mouse_get_pos( &mx, &my );
  412.  
  413.     //  opengl_save_mouse_area(mx, my, Gr_cursor_size, Gr_cursor_size);
  414.  
  415.         if (Gr_cursor != -1 && bm_is_valid(Gr_cursor)) {
  416.             gr_set_bitmap(Gr_cursor);
  417.             gr_bitmap( mx, my, GR_RESIZE_NONE);
  418.         }
  419.     }
  420. #ifndef __hanzo_mouseJoy_disable__
  421.     //=======================####### BLOCK BEGIN  by hanzo@150402
  422.     else if( l_isUsingMouseJoy ) {
  423.       int mx, my, smw = gr_screen.max_w, smh = gr_screen.max_h;
  424.       GLubyte bTmp;
  425.  
  426.         mx = (smw/2) + g_nMjoyX;
  427.         __hanzo_minmax__( mx, 0, smw-1 );
  428.         my = (smh/2) + g_nMjoyY;
  429.         __hanzo_minmax__( my, 0, smh-1 );
  430.  
  431.         gr_reset_clip();
  432.         // todo!!!: draw mousejoy deadzone circle here
  433.         bTmp = (GLubyte)(l_CircleFrameCntMsk & 31);
  434.         if( l_CircleFrameCntMsk & 32 ) {
  435.             bTmp = (256/32) * bTmp;
  436.             drawMjoyDeadzoneCircle( bTmp, bTmp, 0 );
  437.         } else {
  438.             bTmp = 255 - ((256/32) * bTmp);
  439.             drawMjoyDeadzoneCircle( bTmp, bTmp, 0 );
  440.         }
  441.         l_CircleFrameCntMsk++;
  442.  
  443.         if (Gr_crosshair != -1 && bm_is_valid(Gr_crosshair)) {
  444.             // draw mousejoy cursor
  445.             gr_set_bitmap(Gr_crosshair);
  446.             gr_bitmap( mx-16, my-16, GR_RESIZE_NONE); // using 32x32 cursor with (11,11) hot spot
  447.         }
  448.     }
  449.     //=======================####### BLOCK END
  450. #endif
  451.  
  452. #ifdef _WIN32
  453.     SwapBuffers(GL_device_context);
  454. #else
  455.     if (Cmdline_gl_finish)
  456.         glFinish ();
  457.     SDL_GL_SwapBuffers();
  458. #endif
  459.  
  460.     opengl_tcache_frame();
  461.  
  462. #ifndef NDEBUG
  463.     int ic = opengl_check_for_errors();
  464.  
  465.     if (ic) {
  466.         mprintf(("!!DEBUG!! OpenGL Errors this frame: %i\n", ic));
  467.     }
  468. #endif
  469. }
  470.  
  471. void gr_opengl_set_clip(int x, int y, int w, int h, int resize_mode)
  472. {
  473.     // check for sanity of parameters
  474.     if (x < 0) {
  475.         x = 0;
  476.     }
  477.  
  478.     if (y < 0) {
  479.         y = 0;
  480.     }
  481.  
  482.     int to_resize = (resize_mode != GR_RESIZE_NONE && (gr_screen.custom_size || (gr_screen.rendering_to_texture != -1)));
  483.  
  484.     int max_w = ((to_resize) ? gr_screen.max_w_unscaled : gr_screen.max_w);
  485.     int max_h = ((to_resize) ? gr_screen.max_h_unscaled : gr_screen.max_h);
  486.  
  487.     if ((gr_screen.rendering_to_texture != -1) && to_resize) {
  488.         gr_unsize_screen_pos(&max_w, &max_h);
  489.     }
  490.  
  491.     if (x >= max_w) {
  492.         x = max_w - 1;
  493.     }
  494.  
  495.     if (y >= max_h) {
  496.         y = max_h - 1;
  497.     }
  498.  
  499.     if (x + w > max_w) {
  500.         w = max_w - x;
  501.     }
  502.  
  503.     if (y + h > max_h) {
  504.         h = max_h - y;
  505.     }
  506.    
  507.     if (w > max_w) {
  508.         w = max_w;
  509.     }
  510.  
  511.     if (h > max_h) {
  512.         h = max_h;
  513.     }
  514.  
  515.     gr_screen.offset_x_unscaled = x;
  516.     gr_screen.offset_y_unscaled = y;
  517.     gr_screen.clip_left_unscaled = 0;
  518.     gr_screen.clip_right_unscaled = w-1;
  519.     gr_screen.clip_top_unscaled = 0;
  520.     gr_screen.clip_bottom_unscaled = h-1;
  521.     gr_screen.clip_width_unscaled = w;
  522.     gr_screen.clip_height_unscaled = h;
  523.  
  524.     if (to_resize) {
  525.         gr_resize_screen_pos(&x, &y, &w, &h, resize_mode);
  526.     } else {
  527.         gr_unsize_screen_pos( &gr_screen.offset_x_unscaled, &gr_screen.offset_y_unscaled );
  528.         gr_unsize_screen_pos( &gr_screen.clip_right_unscaled, &gr_screen.clip_bottom_unscaled );
  529.         gr_unsize_screen_pos( &gr_screen.clip_width_unscaled, &gr_screen.clip_height_unscaled );
  530.     }
  531.  
  532.     gr_screen.offset_x = x;
  533.     gr_screen.offset_y = y;
  534.     gr_screen.clip_left = 0;
  535.     gr_screen.clip_right = w-1;
  536.     gr_screen.clip_top = 0;
  537.     gr_screen.clip_bottom = h-1;
  538.     gr_screen.clip_width = w;
  539.     gr_screen.clip_height = h;
  540.  
  541.     gr_screen.clip_aspect = i2fl(w) / i2fl(h);
  542.     gr_screen.clip_center_x = (gr_screen.clip_left + gr_screen.clip_right) * 0.5f;
  543.     gr_screen.clip_center_y = (gr_screen.clip_top + gr_screen.clip_bottom) * 0.5f;
  544.  
  545.     // just return early if we aren't actually going to need the scissor test
  546.     if ( (x == 0) && (y == 0) && (w == max_w) && (h == max_h) ) {
  547.         GL_state.ScissorTest(GL_FALSE);
  548.         return;
  549.     }
  550.  
  551.     GL_state.ScissorTest(GL_TRUE);
  552.     if(GL_rendering_to_texture) {
  553.         glScissor(x, y, w, h);
  554.     } else {
  555.         glScissor(x, gr_screen.max_h-y-h, w, h);
  556.     }
  557. }
  558.  
  559. void gr_opengl_reset_clip()
  560. {
  561.     gr_screen.offset_x = gr_screen.offset_x_unscaled = 0;
  562.     gr_screen.offset_y = gr_screen.offset_y_unscaled = 0;
  563.     gr_screen.clip_left = gr_screen.clip_left_unscaled = 0;
  564.     gr_screen.clip_top = gr_screen.clip_top_unscaled = 0;
  565.     gr_screen.clip_right = gr_screen.clip_right_unscaled = gr_screen.max_w - 1;
  566.     gr_screen.clip_bottom = gr_screen.clip_bottom_unscaled = gr_screen.max_h - 1;
  567.     gr_screen.clip_width = gr_screen.clip_width_unscaled = gr_screen.max_w;
  568.     gr_screen.clip_height = gr_screen.clip_height_unscaled = gr_screen.max_h;
  569.  
  570.     if (gr_screen.custom_size) {
  571.         gr_unsize_screen_pos( &gr_screen.clip_right_unscaled, &gr_screen.clip_bottom_unscaled );
  572.         gr_unsize_screen_pos( &gr_screen.clip_width_unscaled, &gr_screen.clip_height_unscaled );
  573.     }
  574.  
  575.     gr_screen.clip_aspect = i2fl(gr_screen.clip_width) / i2fl(gr_screen.clip_height);
  576.     gr_screen.clip_center_x = (gr_screen.clip_left + gr_screen.clip_right) * 0.5f;
  577.     gr_screen.clip_center_y = (gr_screen.clip_top + gr_screen.clip_bottom) * 0.5f;
  578.  
  579.     GL_state.ScissorTest(GL_FALSE);
  580. }
  581.  
  582. void gr_opengl_set_palette(ubyte *new_palette, int is_alphacolor)
  583. {
  584. }
  585.  
  586. void gr_opengl_print_screen(const char *filename)
  587. {
  588.     char tmp[MAX_PATH_LEN];
  589.     ubyte tga_hdr[18];
  590.     int i;
  591.     ushort width, height;
  592.     GLubyte *pixels = NULL;
  593.     GLuint pbo = 0;
  594.  
  595.     // save to a "screenshots" directory and tack on the filename
  596. #ifdef SCP_UNIX
  597.     snprintf( tmp, MAX_PATH_LEN-1, "%s/%s/screenshots/%s.tga", detect_home(), Osreg_user_dir, filename);
  598.     _mkdir( tmp );
  599. #else
  600.     _getcwd( tmp, MAX_PATH_LEN-1 );
  601.     strcat_s( tmp, "\\screenshots\\" );
  602.     _mkdir( tmp );
  603.  
  604.     strcat_s( tmp, filename );
  605.     strcat_s( tmp, ".tga" );
  606. #endif
  607.  
  608.     FILE *fout = fopen(tmp, "wb");
  609.  
  610.     if (fout == NULL) {
  611.         return;
  612.     }
  613.  
  614. //  glReadBuffer(GL_FRONT);
  615.  
  616.     // now for the data
  617.     if (Use_PBOs) {
  618.         Assert( !pbo );
  619.         vglGenBuffersARB(1, &pbo);
  620.  
  621.         if ( !pbo ) {
  622.             if (fout != NULL)
  623.                 fclose(fout);
  624.  
  625.             return;
  626.         }
  627.  
  628.         vglBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pbo);
  629.         vglBufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, (gr_screen.max_w * gr_screen.max_h * 4), NULL, GL_STATIC_READ);
  630.  
  631.         glReadBuffer(GL_FRONT);
  632.         glReadPixels(0, 0, gr_screen.max_w, gr_screen.max_h, GL_read_format, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
  633.  
  634.         // map the image data so that we can save it to file
  635.         pixels = (GLubyte*) vglMapBufferARB(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY);
  636.     } else {
  637.         pixels = (GLubyte*) vm_malloc_q(gr_screen.max_w * gr_screen.max_h * 4);
  638.  
  639.         if (pixels == NULL) {
  640.             if (fout != NULL) {
  641.                 fclose(fout);
  642.             }
  643.  
  644.             return;
  645.         }
  646.  
  647.         glReadPixels(0, 0, gr_screen.max_w, gr_screen.max_h, GL_read_format, GL_UNSIGNED_INT_8_8_8_8_REV, pixels);
  648.         glFlush();
  649.     }
  650.  
  651.     // Write the TGA header
  652.     width = INTEL_SHORT((ushort)gr_screen.max_w);
  653.     height = INTEL_SHORT((ushort)gr_screen.max_h);
  654.  
  655.     memset( tga_hdr, 0, sizeof(tga_hdr) );
  656.  
  657.     tga_hdr[2] = 2;     // ImageType    2 = 24bpp, uncompressed
  658.     memcpy( tga_hdr + 12, &width, sizeof(ushort) );     // Width
  659.     memcpy( tga_hdr + 14, &height, sizeof(ushort) );    // Height
  660.     tga_hdr[16] = 24;   // PixelDepth
  661.  
  662.     fwrite( tga_hdr, sizeof(tga_hdr), 1, fout );
  663.  
  664.     // now for the data, we convert it from 32-bit to 24-bit
  665.     for (i = 0; i < (gr_screen.max_w * gr_screen.max_h * 4); i += 4) {
  666. #if BYTE_ORDER == BIG_ENDIAN
  667.         int pix, *pix_tmp;
  668.  
  669.         pix_tmp = (int*)(pixels + i);
  670.         pix = INTEL_INT(*pix_tmp);
  671.  
  672.         fwrite( &pix, 1, 3, fout );
  673. #else
  674.         fwrite( pixels + i, 1, 3, fout );
  675. #endif
  676.     }
  677.  
  678.     if (pbo) {
  679.         vglUnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB);
  680.         pixels = NULL;
  681.         vglBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0);
  682.         vglDeleteBuffersARB(1, &pbo);
  683.     }
  684.  
  685.     // done!
  686.     fclose(fout);
  687.  
  688.     if (pixels != NULL) {
  689.         vm_free(pixels);
  690.     }
  691. }
  692.  
  693. void gr_opengl_cleanup(int minimize)
  694. {  
  695.     if ( !GL_initted ) {
  696.         return;
  697.     }
  698.  
  699.     if ( !Fred_running ) {
  700.         gr_reset_clip();
  701.         gr_clear();
  702.         gr_flip();
  703.         gr_clear();
  704.         gr_flip();
  705.         gr_clear();
  706.     }
  707.  
  708.     GL_initted = false;
  709.  
  710.     opengl_tcache_flush();
  711.  
  712. #ifdef _WIN32
  713.     HWND wnd = (HWND)os_get_window();
  714.  
  715.     if (GL_render_context) {
  716.         if ( !wglMakeCurrent(NULL, NULL) ) {
  717.             MessageBox(wnd, "SHUTDOWN ERROR", "error", MB_OK);
  718.         }
  719.  
  720.         if ( !wglDeleteContext(GL_render_context) ) {
  721.             MessageBox(wnd, "Unable to delete rendering context", "error", MB_OK);
  722.         }
  723.  
  724.         GL_render_context = NULL;
  725.     }
  726. #endif
  727.  
  728.     opengl_minimize();
  729.  
  730.     if (minimize) {
  731. #ifdef _WIN32
  732.         if ( !Cmdline_fullscreen_window && !Cmdline_window ) {
  733.             ChangeDisplaySettings(NULL, 0);
  734.         }
  735. #endif
  736.     }
  737. }
  738.  
  739. void gr_opengl_fog_set(int fog_mode, int r, int g, int b, float fog_near, float fog_far)
  740. {
  741. //  mprintf(("gr_opengl_fog_set(%d,%d,%d,%d,%f,%f)\n",fog_mode,r,g,b,fog_near,fog_far));
  742.  
  743.     Assert((r >= 0) && (r < 256));
  744.     Assert((g >= 0) && (g < 256));
  745.     Assert((b >= 0) && (b < 256));
  746.    
  747.     if (fog_mode == GR_FOGMODE_NONE) {
  748.         if ( GL_state.Fog() ) {
  749.             GL_state.Fog(GL_FALSE);
  750.         }
  751.  
  752.         gr_screen.current_fog_mode = fog_mode;
  753.        
  754.         return;
  755.     }
  756.    
  757.     if (OGL_fogmode == 3) {
  758.         glFogf(GL_FOG_DISTANCE_MODE_NV, GL_EYE_RADIAL_NV);
  759.         glFogf(GL_FOG_COORDINATE_SOURCE, GL_FRAGMENT_DEPTH);
  760.     }
  761.     // Um.. this is not the correct way to fog in software, probably doesn't matter though
  762.     else if ( (OGL_fogmode == 2) && Cmdline_nohtl ) {
  763.         glFogf(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT);
  764.         fog_near *= fog_near;       // it's faster this way
  765.         fog_far *= fog_far;    
  766.     } else {
  767.         glFogf(GL_FOG_COORDINATE_SOURCE, GL_FRAGMENT_DEPTH);
  768.     }
  769.  
  770.     GL_state.Fog(GL_TRUE);
  771.     glFogf(GL_FOG_MODE, GL_LINEAR);
  772.     glFogf(GL_FOG_START, fog_near);
  773.     glFogf(GL_FOG_END, fog_far);
  774.  
  775.     gr_screen.current_fog_mode = fog_mode;
  776.    
  777.     if ( (gr_screen.current_fog_color.red != r) ||
  778.             (gr_screen.current_fog_color.green != g) ||
  779.             (gr_screen.current_fog_color.blue != b) )
  780.     {
  781.         GLfloat fc[4];
  782.        
  783.         gr_init_color( &gr_screen.current_fog_color, r, g, b );
  784.    
  785.         fc[0] = (float)r/255.0f;
  786.         fc[1] = (float)g/255.0f;
  787.         fc[2] = (float)b/255.0f;
  788.         fc[3] = 1.0f;
  789.        
  790.         glFogfv(GL_FOG_COLOR, fc);
  791.     }
  792.  
  793. }
  794.  
  795. int gr_opengl_set_cull(int cull)
  796. {
  797.     GLboolean enabled = GL_FALSE;
  798.  
  799.     if (cull) {
  800.         enabled = GL_state.CullFace(GL_TRUE);
  801.         GL_state.FrontFaceValue(GL_CCW);
  802.         GL_state.CullFaceValue(GL_BACK);
  803.     } else {
  804.         enabled = GL_state.CullFace(GL_FALSE);
  805.     }
  806.  
  807.     return (enabled) ? 1 : 0;
  808. }
  809.  
  810. void gr_opengl_set_clear_color(int r, int g, int b)
  811. {
  812.     gr_init_color(&gr_screen.current_clear_color, r, g, b);
  813. }
  814.  
  815. int gr_opengl_set_color_buffer(int mode)
  816. {
  817.     GLboolean enabled = GL_FALSE;
  818.  
  819.     if ( mode ) {
  820.         enabled = GL_state.ColorMask(GL_TRUE);
  821.     } else {
  822.         enabled = GL_state.ColorMask(GL_FALSE);
  823.     }
  824.  
  825.     GL_state.SetAlphaBlendMode(ALPHA_BLEND_ALPHA_BLEND_ALPHA);
  826.  
  827.     return (enabled) ? 1 : 0;
  828. }
  829.  
  830. int gr_opengl_zbuffer_get()
  831. {
  832.     if ( !gr_global_zbuffering ) {
  833.         return GR_ZBUFF_NONE;
  834.     }
  835.  
  836.     return gr_zbuffering_mode;
  837. }
  838.  
  839. int gr_opengl_zbuffer_set(int mode)
  840. {
  841.     int tmp = gr_zbuffering_mode;
  842.  
  843.     gr_zbuffering_mode = mode;
  844.  
  845.     if (gr_zbuffering_mode == GR_ZBUFF_NONE) {
  846.         gr_zbuffering = 0;
  847.         GL_state.SetZbufferType(ZBUFFER_TYPE_NONE);
  848.     } else if ( gr_zbuffering_mode == GR_ZBUFF_READ ) {
  849.         gr_zbuffering = 1;
  850.         GL_state.SetZbufferType(ZBUFFER_TYPE_READ);
  851.     } else {
  852.         gr_zbuffering = 1;
  853.         GL_state.SetZbufferType(ZBUFFER_TYPE_FULL);
  854.     }
  855.  
  856.     return tmp;
  857. }
  858.  
  859. void gr_opengl_zbuffer_clear(int mode)
  860. {
  861.     if (mode) {
  862.         gr_zbuffering = 1;
  863.         gr_zbuffering_mode = GR_ZBUFF_FULL;
  864.         gr_global_zbuffering = 1;
  865.  
  866.         GL_state.SetTextureSource(TEXTURE_SOURCE_NONE);
  867.         GL_state.SetAlphaBlendMode(ALPHA_BLEND_NONE);
  868.         GL_state.SetZbufferType(ZBUFFER_TYPE_FULL);
  869.  
  870.         glClear(GL_DEPTH_BUFFER_BIT);
  871.     } else {
  872.         gr_zbuffering = 0;
  873.         gr_zbuffering_mode = GR_ZBUFF_NONE;
  874.         gr_global_zbuffering = 0;
  875.  
  876.         GL_state.DepthTest(GL_FALSE);
  877.     }
  878. }
  879.  
  880. int gr_opengl_stencil_set(int mode)
  881. {
  882.     int tmp = gr_stencil_mode;
  883.  
  884.     gr_stencil_mode = mode;
  885.  
  886.     if ( mode == GR_STENCIL_READ ) {
  887.         GL_state.StencilTest(1);
  888.         GL_state.SetStencilType(STENCIL_TYPE_READ);
  889.     } else if ( mode == GR_STENCIL_WRITE ) {
  890.         GL_state.StencilTest(1);
  891.         GL_state.SetStencilType(STENCIL_TYPE_WRITE);
  892.     } else {
  893.         GL_state.StencilTest(0);
  894.         GL_state.SetStencilType(STENCIL_TYPE_NONE);
  895.     }
  896.  
  897.     return tmp;
  898. }
  899.  
  900. void gr_opengl_stencil_clear()
  901. {
  902.     glClear(GL_STENCIL_BUFFER_BIT);
  903. }
  904.  
  905. int gr_opengl_alpha_mask_set(int mode, float alpha)
  906. {
  907.     int tmp = gr_alpha_test;
  908.  
  909.     gr_alpha_test = mode;
  910.  
  911.     if ( mode ) {
  912.         GL_state.AlphaTest(GL_TRUE);
  913.         GL_state.AlphaFunc(GL_GREATER, alpha);
  914.     } else {
  915.         GL_state.AlphaTest(GL_FALSE);
  916.         GL_state.AlphaFunc(GL_ALWAYS, 1.0f);
  917.     }
  918.  
  919.     return tmp;
  920. }
  921.  
  922. // I feel dirty...
  923. static void opengl_make_gamma_ramp(float gamma, ushort *ramp)
  924. {
  925.     ushort x, y;
  926.     ushort base_ramp[256];
  927.  
  928.     Assert( ramp != NULL );
  929.  
  930.     // generate the base ramp values first off
  931.  
  932.     // if no gamma set then just do this quickly
  933.     if (gamma <= 0.0f) {
  934.         memset( ramp, 0, 3 * 256 * sizeof(ushort) );
  935.         return;
  936.     }
  937.     // identity gamma, avoid all of the math
  938.     else if ( (gamma == 1.0f) || (GL_original_gamma_ramp == NULL) ) {
  939.         if (GL_original_gamma_ramp != NULL) {
  940.             memcpy( ramp, GL_original_gamma_ramp, 3 * 256 * sizeof(ushort) );
  941.         }
  942.         // set identity if no original ramp
  943.         else {
  944.             for (x = 0; x < 256; x++) {
  945.                 ramp[x] = (x << 8) | x;
  946.                 ramp[x + 256] = (x << 8) | x;
  947.                 ramp[x + 512] = (x << 8) | x;
  948.             }
  949.         }
  950.  
  951.         return;
  952.     }
  953.     // for everything else we need to actually figure it up
  954.     else {
  955.         double g = 1.0 / (double)gamma;
  956.         double val;
  957.  
  958.         Assert( GL_original_gamma_ramp != NULL );
  959.  
  960.         for (x = 0; x < 256; x++) {
  961.             val = (pow(x/255.0, g) * 65535.0 + 0.5);
  962.             CLAMP( val, 0, 65535 );
  963.  
  964.             base_ramp[x] = (ushort)val;
  965.         }
  966.  
  967.         for (y = 0; y < 3; y++) {
  968.             for (x = 0; x < 256; x++) {
  969.                 val = (base_ramp[x] * 2) - GL_original_gamma_ramp[x + y * 256];
  970.                 CLAMP( val, 0, 65535 );
  971.  
  972.                 ramp[x + y * 256] = (ushort)val;
  973.             }
  974.         }
  975.     }
  976. }
  977.  
  978. void gr_opengl_set_gamma(float gamma)
  979. {
  980.     ushort *gamma_ramp = NULL;
  981.  
  982.     Gr_gamma = gamma;
  983.     Gr_gamma_int = int (Gr_gamma*10);
  984.  
  985.     // new way - but not while running FRED
  986.     if (!Fred_running && !Cmdline_no_set_gamma) {
  987.         gamma_ramp = (ushort*) vm_malloc_q( 3 * 256 * sizeof(ushort) );
  988.  
  989.         if (gamma_ramp == NULL) {
  990.             Int3();
  991.             return;
  992.         }
  993.  
  994.         memset( gamma_ramp, 0, 3 * 256 * sizeof(ushort) );
  995.  
  996.         // Create the Gamma lookup table
  997.         opengl_make_gamma_ramp(gamma, gamma_ramp);
  998.  
  999. #ifdef _WIN32
  1000.         SetDeviceGammaRamp( GL_device_context, gamma_ramp );
  1001. #else
  1002.         SDL_SetGammaRamp( gamma_ramp, (gamma_ramp+256), (gamma_ramp+512) );
  1003. #endif
  1004.  
  1005.         vm_free(gamma_ramp);
  1006.     }
  1007. }
  1008.  
  1009. void gr_opengl_get_region(int front, int w, int h, ubyte *data)
  1010. {
  1011.  
  1012. //  if (front) {
  1013. //      glReadBuffer(GL_FRONT);
  1014. //  } else {
  1015.         glReadBuffer(GL_BACK);
  1016. //  }
  1017.  
  1018.     GL_state.SetTextureSource(TEXTURE_SOURCE_NO_FILTERING);
  1019.     GL_state.SetAlphaBlendMode(ALPHA_BLEND_NONE);
  1020.     GL_state.SetZbufferType(ZBUFFER_TYPE_NONE);
  1021.    
  1022.     if (gr_screen.bits_per_pixel == 16) {
  1023.         glReadPixels(0, gr_screen.max_h-h, w, h, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, data);
  1024.     } else if (gr_screen.bits_per_pixel == 32) {
  1025.         glReadPixels(0, gr_screen.max_h-h, w, h, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, data);
  1026.     }
  1027.  
  1028.  
  1029. }
  1030.  
  1031. void opengl_save_mouse_area(int x, int y, int w, int h)
  1032. {
  1033.     int cursor_size;
  1034.  
  1035.     GL_CHECK_FOR_ERRORS("start of save_mouse_area()");
  1036.  
  1037.     // lazy - taylor
  1038.     cursor_size = (Gr_cursor_size * Gr_cursor_size);
  1039.  
  1040.     // no reason to be bigger than the cursor, should never be smaller
  1041.     if (w != Gr_cursor_size)
  1042.         w = Gr_cursor_size;
  1043.     if (h != Gr_cursor_size)
  1044.         h = Gr_cursor_size;
  1045.  
  1046.     GL_mouse_saved_x1 = x;
  1047.     GL_mouse_saved_y1 = y;
  1048.     GL_mouse_saved_x2 = x+w-1;
  1049.     GL_mouse_saved_y2 = y+h-1;
  1050.  
  1051.     CLAMP(GL_mouse_saved_x1, gr_screen.clip_left, gr_screen.clip_right );
  1052.     CLAMP(GL_mouse_saved_x2, gr_screen.clip_left, gr_screen.clip_right );
  1053.     CLAMP(GL_mouse_saved_y1, gr_screen.clip_top, gr_screen.clip_bottom );
  1054.     CLAMP(GL_mouse_saved_y2, gr_screen.clip_top, gr_screen.clip_bottom );
  1055.  
  1056.     GL_state.SetTextureSource(TEXTURE_SOURCE_NO_FILTERING);
  1057.     GL_state.SetAlphaBlendMode(ALPHA_BLEND_NONE);
  1058.     GL_state.SetZbufferType(ZBUFFER_TYPE_NONE);
  1059.  
  1060.     if ( Use_PBOs ) {
  1061.         // since this is used a lot, and is pretty small in size, we just create it once and leave it until exit
  1062.         if (!GL_cursor_pbo) {
  1063.             vglGenBuffersARB(1, &GL_cursor_pbo);
  1064.             vglBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, GL_cursor_pbo);
  1065.             vglBufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, cursor_size * 4, NULL, GL_STATIC_READ);
  1066.         }
  1067.  
  1068.         vglBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, GL_cursor_pbo);
  1069.         glReadBuffer(GL_BACK);
  1070.         glReadPixels(x, gr_screen.max_h-y-1-h, w, h, GL_read_format, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
  1071.         vglBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0);
  1072.     } else {
  1073.         // this should really only have to be malloc'd once
  1074.         if (GL_saved_mouse_data == NULL)
  1075.             GL_saved_mouse_data = (ubyte*)vm_malloc_q(cursor_size * 4);
  1076.  
  1077.         if (GL_saved_mouse_data == NULL)
  1078.             return;
  1079.  
  1080.         glReadBuffer(GL_BACK);
  1081.         glReadPixels(x, gr_screen.max_h-y-1-h, w, h, GL_read_format, GL_UNSIGNED_INT_8_8_8_8_REV, GL_saved_mouse_data);
  1082.     }
  1083.  
  1084.     GL_CHECK_FOR_ERRORS("end of save_mouse_area()");
  1085.  
  1086.     GL_mouse_saved = 1;
  1087. }
  1088.  
  1089. int gr_opengl_save_screen()
  1090. {
  1091.     int i;
  1092.     ubyte *sptr = NULL, *dptr = NULL;
  1093.     ubyte *opengl_screen_tmp = NULL;
  1094.     int width_times_pixel, mouse_times_pixel;
  1095.  
  1096.     gr_opengl_reset_clip();
  1097.  
  1098.     if (GL_saved_screen || GL_screen_pbo) {
  1099.         // already have a screen saved so just bail...
  1100.         return -1;
  1101.     }
  1102.  
  1103.     GL_saved_screen = (ubyte*)vm_malloc_q( gr_screen.max_w * gr_screen.max_h * 4 );
  1104.  
  1105.     if (!GL_saved_screen) {
  1106.         mprintf(( "Couldn't get memory for saved screen!\n" ));
  1107.         return -1;
  1108.     }
  1109.  
  1110.     GLboolean save_state = GL_state.DepthTest(GL_FALSE);
  1111.     glReadBuffer(GL_FRONT_LEFT);
  1112.  
  1113.     if ( Use_PBOs ) {
  1114.         GLubyte *pixels = NULL;
  1115.  
  1116.         vglGenBuffersARB(1, &GL_screen_pbo);
  1117.  
  1118.         if (!GL_screen_pbo) {
  1119.             if (GL_saved_screen) {
  1120.                 vm_free(GL_saved_screen);
  1121.                 GL_saved_screen = NULL;
  1122.             }
  1123.  
  1124.             return -1;
  1125.         }
  1126.  
  1127.         vglBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, GL_screen_pbo);
  1128.         vglBufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, gr_screen.max_w * gr_screen.max_h * 4, NULL, GL_STATIC_READ);
  1129.  
  1130.         glReadPixels(0, 0, gr_screen.max_w, gr_screen.max_h, GL_read_format, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
  1131.  
  1132.         pixels = (GLubyte*)vglMapBufferARB(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY);
  1133.  
  1134.         width_times_pixel = (gr_screen.max_w * 4);
  1135.         mouse_times_pixel = (Gr_cursor_size * 4);
  1136.  
  1137.         sptr = (ubyte *)pixels;
  1138.         dptr = (ubyte *)&GL_saved_screen[gr_screen.max_w * gr_screen.max_h * 4];
  1139.  
  1140.         for (i = 0; i < gr_screen.max_h; i++) {
  1141.             dptr -= width_times_pixel;
  1142.             memcpy(dptr, sptr, width_times_pixel);
  1143.             sptr += width_times_pixel;
  1144.         }
  1145.  
  1146.         vglUnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB);
  1147.         vglBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0);
  1148.  
  1149.         if (GL_mouse_saved && GL_cursor_pbo) {
  1150.             vglBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, GL_cursor_pbo);
  1151.  
  1152.             pixels = (GLubyte*)vglMapBufferARB(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY);
  1153.  
  1154.             sptr = (ubyte *)pixels;
  1155.             dptr = (ubyte *)&GL_saved_screen[(GL_mouse_saved_x1 + GL_mouse_saved_y2 * gr_screen.max_w) * 4];
  1156.  
  1157.             for (i = 0; i < Gr_cursor_size; i++) {
  1158.                 memcpy(dptr, sptr, mouse_times_pixel);
  1159.                 sptr += mouse_times_pixel;
  1160.                 dptr -= width_times_pixel;
  1161.             }
  1162.  
  1163.             vglUnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB);
  1164.             vglBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0);
  1165.         }
  1166.  
  1167.         vglDeleteBuffersARB(1, &GL_screen_pbo);
  1168.         GL_screen_pbo = 0;
  1169.  
  1170.         GL_saved_screen_id = bm_create(32, gr_screen.max_w, gr_screen.max_h, GL_saved_screen, 0);
  1171.     } else {
  1172.         opengl_screen_tmp = (ubyte*)vm_malloc_q( gr_screen.max_w * gr_screen.max_h * 4 );
  1173.  
  1174.         if (!opengl_screen_tmp) {
  1175.             if (GL_saved_screen) {
  1176.                 vm_free(GL_saved_screen);
  1177.                 GL_saved_screen = NULL;
  1178.             }
  1179.  
  1180.             mprintf(( "Couldn't get memory for temporary saved screen!\n" ));
  1181.             GL_state.DepthTest(save_state);
  1182.             return -1;
  1183.         }
  1184.  
  1185.         glReadPixels(0, 0, gr_screen.max_w, gr_screen.max_h, GL_read_format, GL_UNSIGNED_INT_8_8_8_8_REV, opengl_screen_tmp);
  1186.  
  1187.         sptr = (ubyte *)&opengl_screen_tmp[gr_screen.max_w * gr_screen.max_h * 4];
  1188.         dptr = (ubyte *)GL_saved_screen;
  1189.  
  1190.         width_times_pixel = (gr_screen.max_w * 4);
  1191.         mouse_times_pixel = (Gr_cursor_size * 4);
  1192.  
  1193.         for (i = 0; i < gr_screen.max_h; i++) {
  1194.             sptr -= width_times_pixel;
  1195.             memcpy(dptr, sptr, width_times_pixel);
  1196.             dptr += width_times_pixel;
  1197.         }
  1198.  
  1199.         vm_free(opengl_screen_tmp);
  1200.  
  1201.         if (GL_mouse_saved && GL_saved_mouse_data) {
  1202.             sptr = (ubyte *)GL_saved_mouse_data;
  1203.             dptr = (ubyte *)&GL_saved_screen[(GL_mouse_saved_x1 + GL_mouse_saved_y2 * gr_screen.max_w) * 4];
  1204.  
  1205.             for (i = 0; i < Gr_cursor_size; i++) {
  1206.                 memcpy(dptr, sptr, mouse_times_pixel);
  1207.                 sptr += mouse_times_pixel;
  1208.                 dptr -= width_times_pixel;
  1209.             }
  1210.         }
  1211.  
  1212.         GL_saved_screen_id = bm_create(32, gr_screen.max_w, gr_screen.max_h, GL_saved_screen, 0);
  1213.     }
  1214.  
  1215.     GL_state.DepthTest(save_state);
  1216.  
  1217.     return GL_saved_screen_id;
  1218. }
  1219.  
  1220. void gr_opengl_restore_screen(int bmp_id)
  1221. {
  1222.     gr_reset_clip();
  1223.  
  1224.     if ( !GL_saved_screen ) {
  1225.         gr_clear();
  1226.         return;
  1227.     }
  1228.  
  1229.     Assert( (bmp_id < 0) || (bmp_id == GL_saved_screen_id) );
  1230.  
  1231.     if (GL_saved_screen_id < 0)
  1232.         return;
  1233.  
  1234.     gr_set_bitmap(GL_saved_screen_id);
  1235.     gr_bitmap(0, 0, GR_RESIZE_NONE);    // don't scale here since we already have real screen size
  1236. }
  1237.  
  1238. void gr_opengl_free_screen(int bmp_id)
  1239. {
  1240.     if (!GL_saved_screen)
  1241.         return;
  1242.  
  1243.     vm_free(GL_saved_screen);
  1244.     GL_saved_screen = NULL;
  1245.  
  1246.     Assert( (bmp_id < 0) || (bmp_id == GL_saved_screen_id) );
  1247.  
  1248.     if (GL_saved_screen_id < 0)
  1249.         return;
  1250.  
  1251.     bm_release(GL_saved_screen_id);
  1252.     GL_saved_screen_id = -1;
  1253. }
  1254.  
  1255. static void opengl_flush_frame_dump()
  1256. {
  1257.     char filename[MAX_FILENAME_LEN];
  1258.  
  1259.     Assert( GL_dump_buffer != NULL);
  1260.  
  1261.     for (int i = 0; i < GL_dump_frame_count; i++) {
  1262.         sprintf(filename, NOX("frm%04d.tga"), GL_dump_frame_number );
  1263.         GL_dump_frame_number++;
  1264.  
  1265.         CFILE *f = cfopen(filename, "wb", CFILE_NORMAL, CF_TYPE_DATA);
  1266.  
  1267.         // Write the TGA header
  1268.         cfwrite_ubyte( 0, f );  //  IDLength;
  1269.         cfwrite_ubyte( 0, f );  //  ColorMapType;
  1270.         cfwrite_ubyte( 2, f );  //  ImageType;      // 2 = 24bpp, uncompressed, 10=24bpp rle compressed
  1271.         cfwrite_ushort( 0, f ); // CMapStart;
  1272.         cfwrite_ushort( 0, f ); //  CMapLength;
  1273.         cfwrite_ubyte( 0, f );  // CMapDepth;
  1274.         cfwrite_ushort( 0, f ); //  XOffset;
  1275.         cfwrite_ushort( 0, f ); //  YOffset;
  1276.         cfwrite_ushort( (ushort)gr_screen.max_w, f );   //  Width;
  1277.         cfwrite_ushort( (ushort)gr_screen.max_h, f );   //  Height;
  1278.         cfwrite_ubyte( 24, f ); //PixelDepth;
  1279.         cfwrite_ubyte( 0, f );  //ImageDesc;
  1280.  
  1281.         glReadBuffer(GL_FRONT);
  1282.         glReadPixels(0, 0, gr_screen.max_w, gr_screen.max_h, GL_BGR_EXT, GL_UNSIGNED_BYTE, GL_dump_buffer);
  1283.  
  1284.         // save the data out
  1285.         cfwrite( GL_dump_buffer, GL_dump_frame_size, 1, f );
  1286.  
  1287.         cfclose(f);
  1288.  
  1289.     }
  1290.  
  1291.     GL_dump_frame_count = 0;
  1292. }
  1293.  
  1294. void gr_opengl_dump_frame_start(int first_frame, int frames_between_dumps)
  1295. {
  1296.     if ( GL_dump_frames )   {
  1297.         Int3();     //  We're already dumping frames.  See John.
  1298.         return;
  1299.     }
  1300.  
  1301.     GL_dump_frames = 1;
  1302.     GL_dump_frame_number = first_frame;
  1303.     GL_dump_frame_count = 0;
  1304.     GL_dump_frame_count_max = frames_between_dumps; // only works if it's 1
  1305.     GL_dump_frame_size = gr_screen.max_w * gr_screen.max_h * 3;
  1306.    
  1307.     if ( !GL_dump_buffer ) {
  1308.         int size = GL_dump_frame_count_max * GL_dump_frame_size;
  1309.  
  1310.         GL_dump_buffer = (ubyte *)vm_malloc(size);
  1311.  
  1312.         if ( !GL_dump_buffer )  {
  1313.             Error(LOCATION, "Unable to malloc %d bytes for dump buffer", size );
  1314.         }
  1315.     }
  1316. }
  1317.  
  1318. void gr_opengl_dump_frame_stop()
  1319. {
  1320.     if ( !GL_dump_frames )  {
  1321.         Int3();     //  We're not dumping frames.  See John.
  1322.         return;
  1323.     }  
  1324.  
  1325.     // dump any remaining frames
  1326.     opengl_flush_frame_dump();
  1327.    
  1328.     GL_dump_frames = 0;
  1329.  
  1330.     if ( GL_dump_buffer )   {
  1331.         vm_free(GL_dump_buffer);
  1332.         GL_dump_buffer = NULL;
  1333.     }
  1334. }
  1335.  
  1336. void gr_opengl_dump_frame()
  1337. {
  1338.     GL_dump_frame_count++;
  1339.  
  1340.     if ( GL_dump_frame_count == GL_dump_frame_count_max ) {
  1341.         opengl_flush_frame_dump();
  1342.     }
  1343. }
  1344.  
  1345. //fill mode, solid/wire frame
  1346. void gr_opengl_set_fill_mode(int mode)
  1347. {
  1348.     if (mode == GR_FILL_MODE_SOLID) {
  1349.         glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  1350.         return;
  1351.     }
  1352.  
  1353.     if (mode == GR_FILL_MODE_WIRE) {
  1354.         glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
  1355.         return;
  1356.     }
  1357.  
  1358.     // default setting
  1359.     glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  1360. }
  1361.  
  1362. void gr_opengl_zbias(int bias)
  1363. {
  1364.     if (bias) {
  1365.         GL_state.PolygonOffsetFill(GL_TRUE);
  1366.         glPolygonOffset(0.0, -i2fl(bias));
  1367.     } else {
  1368.         GL_state.PolygonOffsetFill(GL_FALSE);
  1369.     }
  1370. }
  1371.  
  1372. void gr_opengl_push_texture_matrix(int unit)
  1373. {
  1374.     GLint current_matrix;
  1375.  
  1376.     if (unit > GL_supported_texture_units)
  1377.         return;
  1378.  
  1379.     glGetIntegerv(GL_MATRIX_MODE, &current_matrix);
  1380.     vglActiveTextureARB(GL_TEXTURE0_ARB+unit);
  1381.  
  1382.     glMatrixMode(GL_TEXTURE);
  1383.     glPushMatrix();
  1384.  
  1385.     glMatrixMode(current_matrix);
  1386. }
  1387.  
  1388. void gr_opengl_pop_texture_matrix(int unit)
  1389. {
  1390.     GLint current_matrix;
  1391.  
  1392.     if (unit > GL_supported_texture_units)
  1393.         return;
  1394.  
  1395.     glGetIntegerv(GL_MATRIX_MODE, &current_matrix);
  1396.     vglActiveTextureARB(GL_TEXTURE0_ARB+unit);
  1397.  
  1398.     glMatrixMode(GL_TEXTURE);
  1399.     glPopMatrix();
  1400.  
  1401.     glMatrixMode(current_matrix);
  1402. }
  1403.  
  1404. void gr_opengl_translate_texture_matrix(int unit, vec3d *shift)
  1405. {
  1406.     GLint current_matrix;
  1407.  
  1408.     if (unit > GL_supported_texture_units) {
  1409.         /*tex_shift=*shift;*/
  1410.         return;
  1411.     }
  1412.  
  1413.     glGetIntegerv(GL_MATRIX_MODE, &current_matrix);
  1414.     vglActiveTextureARB(GL_TEXTURE0_ARB+unit);
  1415.  
  1416.     glMatrixMode(GL_TEXTURE);
  1417.     glTranslated(shift->xyz.x, shift->xyz.y, shift->xyz.z);
  1418.  
  1419.     glMatrixMode(current_matrix);
  1420.  
  1421. //  tex_shift=vmd_zero_vector;
  1422. }
  1423.  
  1424. void gr_opengl_setup_background_fog(bool set)
  1425. {
  1426.     if (Cmdline_nohtl) {
  1427.         return;
  1428.     }
  1429. }
  1430.  
  1431. void gr_opengl_set_line_width(float width)
  1432. {
  1433.     glLineWidth(width);
  1434. }
  1435.  
  1436. // Returns the human readable error string if there is an error or NULL if not
  1437. const char *opengl_error_string()
  1438. {
  1439.     GLenum error = GL_NO_ERROR;
  1440.  
  1441.     error = glGetError();
  1442.  
  1443.     if ( error != GL_NO_ERROR ) {
  1444.         return (const char *)gluErrorString(error);
  1445.     }
  1446.  
  1447.     return NULL;
  1448. }
  1449.  
  1450. int opengl_check_for_errors(char *err_at)
  1451. {
  1452. #ifdef NDEBUG
  1453.     return 0;
  1454. #endif
  1455.     const char *error_str = NULL;
  1456.     int num_errors = 0;
  1457.  
  1458.     error_str = opengl_error_string();
  1459.  
  1460.     if (error_str) {
  1461.         if (err_at != NULL) {
  1462.             nprintf(("OpenGL", "OpenGL Error from %s: %s\n", err_at, error_str));
  1463.         } else {
  1464.             nprintf(("OpenGL", "OpenGL Error: %s\n", error_str));
  1465.         }
  1466.  
  1467.         num_errors++;
  1468.     }
  1469.  
  1470.     return num_errors;
  1471. }
  1472.  
  1473. void opengl_set_vsync(int status)
  1474. {
  1475.     if ( (status < 0) || (status > 1) ) {
  1476.         Int3();
  1477.         return;
  1478.     }
  1479.  
  1480. #if defined(__APPLE__)
  1481.     // GLInt on 10.6 is an actual int now, instead of a long
  1482.     // This will need further testing once Snow Leopard 10.6 goes RTM
  1483.     CGLSetParameter(CGLGetCurrentContext(), kCGLCPSwapInterval, (GLint*)&status);
  1484. #elif defined(_WIN32)
  1485.     vwglSwapIntervalEXT(status);
  1486. #else
  1487.     // NOTE: this may not work well with the closed NVIDIA drivers since those use the
  1488.     //       special "__GL_SYNC_TO_VBLANK" environment variable to manage sync
  1489.     vglXSwapIntervalSGI(status);
  1490. #endif
  1491.  
  1492.     GL_CHECK_FOR_ERRORS("end of set_vsync()");
  1493. }
  1494.  
  1495. void opengl_setup_viewport()
  1496. {
  1497.     glViewport(0, 0, gr_screen.max_w, gr_screen.max_h);
  1498.  
  1499.     glMatrixMode(GL_PROJECTION);
  1500.     glLoadIdentity();
  1501.  
  1502.     // the top and bottom positions are reversed on purpose, but RTT needs them the other way
  1503.     if (GL_rendering_to_texture) {
  1504.         glOrtho(0, gr_screen.max_w, 0, gr_screen.max_h, -1.0, 1.0);
  1505.     } else {
  1506.         glOrtho(0, gr_screen.max_w, gr_screen.max_h, 0, -1.0, 1.0);
  1507.     }
  1508.  
  1509.     glMatrixMode(GL_MODELVIEW);
  1510.     glLoadIdentity();
  1511. }
  1512.  
  1513. // NOTE: This should only ever be called through os_cleanup(), or when switching video APIs
  1514. void gr_opengl_shutdown()
  1515. {
  1516.     if (GL_cursor_pbo) {
  1517.         vglDeleteBuffersARB(1, &GL_cursor_pbo);
  1518.         GL_cursor_pbo = 0;
  1519.     }
  1520.  
  1521.     if (GL_saved_mouse_data != NULL) {
  1522.         vm_free(GL_saved_mouse_data);
  1523.         GL_saved_mouse_data = NULL;
  1524.     }
  1525.  
  1526.     opengl_tcache_shutdown();
  1527.     opengl_light_shutdown();
  1528.     opengl_tnl_shutdown();
  1529.     opengl_scene_texture_shutdown();
  1530.     opengl_post_process_shutdown();
  1531.     opengl_shader_shutdown();
  1532.  
  1533.     GL_initted = false;
  1534.  
  1535. #ifdef _WIN32
  1536.     // restore original gamma settings
  1537.     if (GL_original_gamma_ramp != NULL) {
  1538.         SetDeviceGammaRamp( GL_device_context, GL_original_gamma_ramp );
  1539.     }
  1540.  
  1541.     // swap out our window mode and un-jail the cursor
  1542.     ShowWindow((HWND)os_get_window(), SW_HIDE);
  1543.     ClipCursor(NULL);
  1544.     ChangeDisplaySettings( NULL, 0 );
  1545. #else
  1546.     if (GL_original_gamma_ramp != NULL) {
  1547.         SDL_SetGammaRamp( GL_original_gamma_ramp, (GL_original_gamma_ramp+256), (GL_original_gamma_ramp+512) );
  1548.     }
  1549. #endif
  1550.  
  1551.     if (GL_original_gamma_ramp != NULL) {
  1552.         vm_free(GL_original_gamma_ramp);
  1553.         GL_original_gamma_ramp = NULL;
  1554.     }
  1555.  
  1556. #ifdef _WIN32
  1557.     wglMakeCurrent(NULL, NULL);
  1558.  
  1559.     if (GL_render_context) {
  1560.         wglDeleteContext(GL_render_context);
  1561.         GL_render_context = NULL;
  1562.     }
  1563.  
  1564.     GL_device_context = NULL;
  1565. #endif
  1566. }
  1567.  
  1568. // NOTE: This should only ever be called through atexit()!!!
  1569. void opengl_close()
  1570. {
  1571. //  if ( !GL_initted )
  1572. //      return;
  1573. }
  1574.  
  1575. int opengl_init_display_device()
  1576. {
  1577.     int bpp = gr_screen.bits_per_pixel;
  1578.  
  1579.     if ( (bpp != 16) && (bpp != 32) ) {
  1580.         Int3();
  1581.         return 1;
  1582.     }
  1583.  
  1584.  
  1585.     // screen format
  1586.     switch (bpp) {
  1587.         case 16: {
  1588.             Gr_red.bits = 5;
  1589.             Gr_red.shift = 11;
  1590.             Gr_red.scale = 8;
  1591.             Gr_red.mask = 0xF800;
  1592.  
  1593.             Gr_green.bits = 6;
  1594.             Gr_green.shift = 5;
  1595.             Gr_green.scale = 4;
  1596.             Gr_green.mask = 0x7E0;
  1597.  
  1598.             Gr_blue.bits = 5;
  1599.             Gr_blue.shift = 0;
  1600.             Gr_blue.scale = 8;
  1601.             Gr_blue.mask = 0x1F;       
  1602.  
  1603.             break;
  1604.         }
  1605.  
  1606.         case 32: {
  1607.             Gr_red.bits = 8;
  1608.             Gr_red.shift = 16;
  1609.             Gr_red.scale = 1;
  1610.             Gr_red.mask = 0xff0000;
  1611.  
  1612.             Gr_green.bits = 8;
  1613.             Gr_green.shift = 8;
  1614.             Gr_green.scale = 1;
  1615.             Gr_green.mask = 0x00ff00;
  1616.  
  1617.             Gr_blue.bits = 8;
  1618.             Gr_blue.shift = 0;
  1619.             Gr_blue.scale = 1;
  1620.             Gr_blue.mask = 0x0000ff;
  1621.  
  1622.             Gr_alpha.bits = 8;
  1623.             Gr_alpha.shift = 24;
  1624.             Gr_alpha.mask = 0xff000000;
  1625.             Gr_alpha.scale = 1;
  1626.  
  1627.             break;
  1628.         }
  1629.     }
  1630.  
  1631.     // texture format
  1632.     Gr_t_red.bits = 5;
  1633.     Gr_t_red.mask = 0x7c00;
  1634.     Gr_t_red.shift = 10;
  1635.     Gr_t_red.scale = 8;
  1636.    
  1637.     Gr_t_green.bits = 5;
  1638.     Gr_t_green.mask = 0x03e0;
  1639.     Gr_t_green.shift = 5;
  1640.     Gr_t_green.scale = 8;
  1641.    
  1642.     Gr_t_blue.bits = 5;
  1643.     Gr_t_blue.mask = 0x001f;
  1644.     Gr_t_blue.shift = 0;
  1645.     Gr_t_blue.scale = 8;
  1646.    
  1647.     Gr_t_alpha.bits = 1;
  1648.     Gr_t_alpha.mask = 0x8000;
  1649.     Gr_t_alpha.scale = 255;
  1650.     Gr_t_alpha.shift = 15;
  1651.  
  1652.     // alpha-texture format
  1653.     Gr_ta_red.bits = 4;
  1654.     Gr_ta_red.mask = 0x0f00;
  1655.     Gr_ta_red.shift = 8;
  1656.     Gr_ta_red.scale = 17;
  1657.    
  1658.     Gr_ta_green.bits = 4;
  1659.     Gr_ta_green.mask = 0x00f0;
  1660.     Gr_ta_green.shift = 4;
  1661.     Gr_ta_green.scale = 17;
  1662.    
  1663.     Gr_ta_blue.bits = 4;
  1664.     Gr_ta_blue.mask = 0x000f;
  1665.     Gr_ta_blue.shift = 0;
  1666.     Gr_ta_blue.scale = 17;
  1667.    
  1668.     Gr_ta_alpha.bits = 4;
  1669.     Gr_ta_alpha.mask = 0xf000;
  1670.     Gr_ta_alpha.shift = 12;
  1671.     Gr_ta_alpha.scale = 17;
  1672.  
  1673.     // allocate storage for original gamma settings
  1674.     if ( !Cmdline_no_set_gamma && (GL_original_gamma_ramp == NULL) ) {
  1675.         GL_original_gamma_ramp = (ushort*) vm_malloc_q( 3 * 256 * sizeof(ushort) );
  1676.  
  1677.         if (GL_original_gamma_ramp == NULL) {
  1678.             mprintf(("  Unable to allocate memory for gamma ramp!  Disabling...\n"));
  1679.             Cmdline_no_set_gamma = 1;
  1680.         } else {
  1681.             // assume identity ramp by default, to be overwritten by true ramp later
  1682.             for (ushort x = 0; x < 256; x++) {
  1683.                 GL_original_gamma_ramp[x] = GL_original_gamma_ramp[x + 256] = GL_original_gamma_ramp[x + 512] = (x << 8) | x;
  1684.             }
  1685.         }
  1686.     }
  1687.  
  1688.  
  1689.     // now init the display device
  1690. #ifdef _WIN32
  1691.     int PixelFormat;
  1692.     HWND wnd = 0;
  1693.     PIXELFORMATDESCRIPTOR pfd_test;
  1694.  
  1695.     mprintf(("  Initializing WGL...\n"));
  1696.  
  1697.     memset(&GL_pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
  1698.     memset(&pfd_test, 0, sizeof(PIXELFORMATDESCRIPTOR));
  1699.  
  1700.     GL_pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
  1701.     GL_pfd.nVersion = 1;
  1702.     GL_pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
  1703.     GL_pfd.iPixelType = PFD_TYPE_RGBA;
  1704.     GL_pfd.cColorBits = (ubyte)bpp;
  1705.     GL_pfd.cRedBits = (ubyte)Gr_red.bits;
  1706.     GL_pfd.cGreenBits = (ubyte)Gr_green.bits;
  1707.     GL_pfd.cBlueBits = (ubyte)Gr_blue.bits;
  1708.     GL_pfd.cAlphaBits = (bpp == 32) ? (ubyte)Gr_alpha.bits : 0;
  1709.     GL_pfd.cDepthBits = (bpp == 32) ? 24 : 16;
  1710.     GL_pfd.cStencilBits = (bpp == 32) ? 8 : 1;
  1711.  
  1712.     wnd = (HWND)os_get_window();
  1713.  
  1714.     Assert( wnd != NULL );
  1715.  
  1716.     extern uint os_get_dc();
  1717.     GL_device_context = (HDC)os_get_dc();
  1718.  
  1719.     if ( !GL_device_context ) {
  1720.         MessageBox(wnd, "Unable to get device context for OpenGL W32!", "error", MB_ICONERROR | MB_OK);
  1721.         return 1;
  1722.     }
  1723.  
  1724.     PixelFormat = ChoosePixelFormat(GL_device_context, &GL_pfd);
  1725.  
  1726.     if ( !PixelFormat ) {
  1727.         MessageBox(wnd, "Unable to choose pixel format for OpenGL W32!","error", MB_ICONERROR | MB_OK);
  1728.         return 1;
  1729.     } else {
  1730.         DescribePixelFormat(GL_device_context, PixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd_test);
  1731.  
  1732.         // make sure that we are hardware accelerated and not using the generic implementation
  1733.         if ( !Fred_running && (pfd_test.dwFlags & PFD_GENERIC_FORMAT) && !(pfd_test.dwFlags & PFD_GENERIC_ACCELERATED) ) {
  1734.             Assert( bpp == 32 );
  1735.  
  1736.             // if we failed at 32-bit then we are probably a 16-bit desktop, so try and init a 16-bit visual instead
  1737.             GL_pfd.cAlphaBits = 0;
  1738.             GL_pfd.cDepthBits = 16;
  1739.             GL_pfd.cStencilBits = 1;
  1740.             // NOTE: the bit values for colors should get updated automatically by ChoosePixelFormat()
  1741.  
  1742.             PixelFormat = ChoosePixelFormat(GL_device_context, &GL_pfd);
  1743.  
  1744.             if (!PixelFormat) {
  1745.                 MessageBox(wnd, "Unable to choose pixel format for OpenGL W32!","error", MB_ICONERROR | MB_OK);
  1746.                 return 1;
  1747.             }
  1748.  
  1749.             // double-check that we are correct now
  1750.             DescribePixelFormat(GL_device_context, PixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd_test);
  1751.  
  1752.             if ( (pfd_test.dwFlags & PFD_GENERIC_FORMAT) && !(pfd_test.dwFlags & PFD_GENERIC_ACCELERATED) ) {
  1753.                 MessageBox(wnd, "Unable to get proper pixel format for OpenGL W32!", "Error", MB_ICONERROR | MB_OK);
  1754.                 return 1;
  1755.             }
  1756.         }
  1757.     }
  1758.  
  1759.     if ( !SetPixelFormat(GL_device_context, PixelFormat, &GL_pfd) ) {
  1760.         MessageBox(wnd, "Unable to set pixel format for OpenGL W32!", "error", MB_ICONERROR | MB_OK);
  1761.         return 1;
  1762.     }
  1763.  
  1764.     GL_render_context = wglCreateContext(GL_device_context);
  1765.     if ( !GL_render_context ) {
  1766.         MessageBox(wnd, "Unable to create rendering context for OpenGL W32!", "error", MB_ICONERROR | MB_OK);
  1767.         return 1;
  1768.     }
  1769.  
  1770.     if ( !wglMakeCurrent(GL_device_context, GL_render_context) ) {
  1771.         MessageBox(wnd, "Unable to make current thread for OpenGL W32!", "error", MB_ICONERROR | MB_OK);
  1772.         return 1;
  1773.     }
  1774.  
  1775.     mprintf(("  Requested WGL Video values = R: %d, G: %d, B: %d, depth: %d, stencil: %d, double-buffer: %d\n", Gr_red.bits, Gr_green.bits, Gr_blue.bits, GL_pfd.cDepthBits, GL_pfd.cStencilBits, (GL_pfd.dwFlags & PFD_DOUBLEBUFFER) > 0));
  1776.  
  1777.     // now report back as to what we ended up getting
  1778.  
  1779.     DescribePixelFormat(GL_device_context, PixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &GL_pfd);
  1780.  
  1781.     int r = GL_pfd.cRedBits;
  1782.     int g = GL_pfd.cGreenBits;
  1783.     int b = GL_pfd.cBlueBits;
  1784.     int depth = GL_pfd.cDepthBits;
  1785.     int stencil = GL_pfd.cStencilBits;
  1786.     int db = ((GL_pfd.dwFlags & PFD_DOUBLEBUFFER) > 0);
  1787.  
  1788.     mprintf(("  Actual WGL Video values    = R: %d, G: %d, B: %d, depth: %d, stencil: %d, double-buffer: %d\n", r, g, b, depth, stencil, db));
  1789.  
  1790.     // get the default gamma ramp so that we can restore it on close
  1791.     if (GL_original_gamma_ramp != NULL) {
  1792.         GetDeviceGammaRamp( GL_device_context, GL_original_gamma_ramp );
  1793.     }
  1794.  
  1795. #else
  1796.  
  1797.     int flags = SDL_OPENGL;
  1798.     int r = 0, g = 0, b = 0, depth = 0, stencil = 1, db = 1;
  1799.  
  1800.     mprintf(("  Initializing SDL...\n"));
  1801.  
  1802.     if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) {
  1803.         fprintf (stderr, "Couldn't init SDL: %s", SDL_GetError());
  1804.         return 1;
  1805.     }
  1806.  
  1807.     // grab mouse/key unless told otherwise, ignore when we are going fullscreen
  1808.     if ( (Cmdline_fullscreen_window|| Cmdline_window || os_config_read_uint(NULL, "Fullscreen", 1) == 0) && !Cmdline_no_grab ) {
  1809.         SDL_WM_GrabInput(SDL_GRAB_ON);
  1810.     }
  1811.  
  1812.     SDL_GL_SetAttribute(SDL_GL_RED_SIZE, Gr_red.bits);
  1813.     SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, Gr_green.bits);
  1814.     SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, Gr_blue.bits);
  1815.     SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, (bpp == 32) ? 24 : 16);
  1816.     SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, (bpp == 32) ? 8 : 1);
  1817.     SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, db);
  1818.    
  1819.     int fsaa_samples = os_config_read_uint(NULL, "OGL_AntiAliasSamples", 0);
  1820.    
  1821.     SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, (fsaa_samples == 0) ? 0 : 1);
  1822.     SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, fsaa_samples);
  1823.  
  1824.     // Slight hack to make Mesa advertise S3TC support without libtxc_dxtn
  1825.     setenv("force_s3tc_enable", "true", 1);
  1826.  
  1827.     mprintf(("  Requested SDL Video values = R: %d, G: %d, B: %d, depth: %d, stencil: %d, double-buffer: %d, FSAA: %d\n", Gr_red.bits, Gr_green.bits, Gr_blue.bits, (bpp == 32) ? 24 : 16, (bpp == 32) ? 8 : 1, db, fsaa_samples));
  1828.  
  1829.     if (SDL_SetVideoMode(gr_screen.max_w, gr_screen.max_h, bpp, flags) == NULL) {
  1830.         fprintf (stderr, "Couldn't set video mode: %s", SDL_GetError());
  1831.         return 1;
  1832.     }
  1833.  
  1834.     SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &r);
  1835.     SDL_GL_GetAttribute(SDL_GL_GREEN_SIZE, &g);
  1836.     SDL_GL_GetAttribute(SDL_GL_BLUE_SIZE, &b);
  1837.     SDL_GL_GetAttribute(SDL_GL_DEPTH_SIZE, &depth);
  1838.     SDL_GL_GetAttribute(SDL_GL_DOUBLEBUFFER, &db);
  1839.     SDL_GL_GetAttribute(SDL_GL_STENCIL_SIZE, &stencil);
  1840.     SDL_GL_GetAttribute(SDL_GL_MULTISAMPLESAMPLES, &fsaa_samples);
  1841.  
  1842.     mprintf(("  Actual SDL Video values    = R: %d, G: %d, B: %d, depth: %d, stencil: %d, double-buffer: %d, FSAA: %d\n", r, g, b, depth, stencil, db, fsaa_samples));
  1843.  
  1844.     SDL_ShowCursor(0);
  1845.  
  1846.     /* might as well put this here */
  1847.     SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
  1848.  
  1849.     if (GL_original_gamma_ramp != NULL) {
  1850.         SDL_GetGammaRamp( GL_original_gamma_ramp, (GL_original_gamma_ramp+256), (GL_original_gamma_ramp+512) );
  1851.     }
  1852. #endif
  1853.  
  1854.     return 0;
  1855. }
  1856.  
  1857.  
  1858. void opengl_setup_function_pointers()
  1859. {
  1860.     // *****************************************************************************
  1861.     // NOTE: All function pointers here should have a Cmdline_nohtl check at the top
  1862.     //       if they shouldn't be run in non-HTL mode, Don't keep separate entries.
  1863.  
  1864.     gr_screen.gf_flip               = gr_opengl_flip;
  1865.     gr_screen.gf_set_clip           = gr_opengl_set_clip;
  1866.     gr_screen.gf_reset_clip         = gr_opengl_reset_clip;
  1867.    
  1868.     gr_screen.gf_clear              = gr_opengl_clear;
  1869. //  gr_screen.gf_bitmap             = gr_opengl_bitmap;
  1870.     gr_screen.gf_bitmap_ex          = gr_opengl_bitmap_ex;
  1871.     gr_screen.gf_aabitmap           = gr_opengl_aabitmap;
  1872.     gr_screen.gf_aabitmap_ex        = gr_opengl_aabitmap_ex;
  1873.    
  1874. //  gr_screen.gf_rect               = gr_opengl_rect;
  1875. //  gr_screen.gf_shade              = gr_opengl_shade;
  1876.     gr_screen.gf_string             = gr_opengl_string;
  1877.     gr_screen.gf_circle             = gr_opengl_circle;
  1878.     gr_screen.gf_unfilled_circle    = gr_opengl_unfilled_circle;
  1879.     gr_screen.gf_arc                = gr_opengl_arc;
  1880.     gr_screen.gf_curve              = gr_opengl_curve;
  1881.  
  1882.     gr_screen.gf_line               = gr_opengl_line;
  1883.     gr_screen.gf_aaline             = gr_opengl_aaline;
  1884.     gr_screen.gf_pixel              = gr_opengl_pixel;
  1885.     gr_screen.gf_scaler             = gr_opengl_scaler;
  1886.     gr_screen.gf_tmapper            = gr_opengl_tmapper;
  1887.     gr_screen.gf_render             = gr_opengl_render;
  1888.     gr_screen.gf_render_effect      = gr_opengl_render_effect;
  1889.  
  1890.     gr_screen.gf_gradient           = gr_opengl_gradient;
  1891.  
  1892.     gr_screen.gf_set_palette        = gr_opengl_set_palette;
  1893.     gr_screen.gf_print_screen       = gr_opengl_print_screen;
  1894.  
  1895.     gr_screen.gf_fade_in            = gr_opengl_fade_in;
  1896.     gr_screen.gf_fade_out           = gr_opengl_fade_out;
  1897.     gr_screen.gf_flash              = gr_opengl_flash;
  1898.     gr_screen.gf_flash_alpha        = gr_opengl_flash_alpha;
  1899.    
  1900.     gr_screen.gf_zbuffer_get        = gr_opengl_zbuffer_get;
  1901.     gr_screen.gf_zbuffer_set        = gr_opengl_zbuffer_set;
  1902.     gr_screen.gf_zbuffer_clear      = gr_opengl_zbuffer_clear;
  1903.  
  1904.     gr_screen.gf_stencil_set        = gr_opengl_stencil_set;
  1905.     gr_screen.gf_stencil_clear      = gr_opengl_stencil_clear;
  1906.  
  1907.     gr_screen.gf_alpha_mask_set     = gr_opengl_alpha_mask_set;
  1908.    
  1909.     gr_screen.gf_save_screen        = gr_opengl_save_screen;
  1910.     gr_screen.gf_restore_screen     = gr_opengl_restore_screen;
  1911.     gr_screen.gf_free_screen        = gr_opengl_free_screen;
  1912.    
  1913.     gr_screen.gf_dump_frame_start   = gr_opengl_dump_frame_start;
  1914.     gr_screen.gf_dump_frame_stop    = gr_opengl_dump_frame_stop;
  1915.     gr_screen.gf_dump_frame         = gr_opengl_dump_frame;
  1916.    
  1917.     gr_screen.gf_set_gamma          = gr_opengl_set_gamma;
  1918.  
  1919.     gr_screen.gf_fog_set            = gr_opengl_fog_set;   
  1920.  
  1921.     // UnknownPlayer : Don't recognize this - MAY NEED DEBUGGING
  1922.     gr_screen.gf_get_region         = gr_opengl_get_region;
  1923.  
  1924.     // now for the bitmap functions
  1925.     gr_screen.gf_bm_free_data           = gr_opengl_bm_free_data;
  1926.     gr_screen.gf_bm_create              = gr_opengl_bm_create;
  1927.     gr_screen.gf_bm_init                = gr_opengl_bm_init;
  1928.     gr_screen.gf_bm_load                = gr_opengl_bm_load;
  1929.     gr_screen.gf_bm_page_in_start       = gr_opengl_bm_page_in_start;
  1930.     gr_screen.gf_bm_lock                = gr_opengl_bm_lock;
  1931.     gr_screen.gf_bm_make_render_target  = gr_opengl_bm_make_render_target;
  1932.     gr_screen.gf_bm_set_render_target   = gr_opengl_bm_set_render_target;
  1933.  
  1934.     gr_screen.gf_set_cull           = gr_opengl_set_cull;
  1935.     gr_screen.gf_set_color_buffer   = gr_opengl_set_color_buffer;
  1936.  
  1937.     gr_screen.gf_cross_fade         = gr_opengl_cross_fade;
  1938.  
  1939.     gr_screen.gf_tcache_set         = gr_opengl_tcache_set;
  1940.  
  1941.     gr_screen.gf_set_clear_color    = gr_opengl_set_clear_color;
  1942.  
  1943.     gr_screen.gf_preload            = gr_opengl_preload;
  1944.  
  1945.     gr_screen.gf_push_texture_matrix        = gr_opengl_push_texture_matrix;
  1946.     gr_screen.gf_pop_texture_matrix         = gr_opengl_pop_texture_matrix;
  1947.     gr_screen.gf_translate_texture_matrix   = gr_opengl_translate_texture_matrix;
  1948.  
  1949.     gr_screen.gf_set_texture_addressing = gr_opengl_set_texture_addressing;
  1950.     gr_screen.gf_zbias                  = gr_opengl_zbias;
  1951.     gr_screen.gf_set_fill_mode          = gr_opengl_set_fill_mode;
  1952.     gr_screen.gf_set_texture_panning    = gr_opengl_set_texture_panning;
  1953.  
  1954.     gr_screen.gf_create_buffer      = gr_opengl_create_buffer;
  1955.     gr_screen.gf_config_buffer      = gr_opengl_config_buffer;
  1956.     gr_screen.gf_pack_buffer        = gr_opengl_pack_buffer;
  1957.     gr_screen.gf_destroy_buffer     = gr_opengl_destroy_buffer;
  1958.     gr_screen.gf_render_buffer      = gr_opengl_render_buffer;
  1959.     gr_screen.gf_set_buffer         = gr_opengl_set_buffer;
  1960.  
  1961.     gr_screen.gf_create_stream_buffer       = gr_opengl_create_stream_buffer;
  1962.     gr_screen.gf_update_stream_buffer       = gr_opengl_update_stream_buffer;
  1963.     gr_screen.gf_render_stream_buffer       = gr_opengl_render_stream_buffer;
  1964.     gr_screen.gf_render_stream_buffer_start = gr_opengl_render_stream_buffer_start;
  1965.     gr_screen.gf_render_stream_buffer_end   = gr_opengl_render_stream_buffer_end;
  1966.  
  1967.     gr_screen.gf_start_instance_matrix          = gr_opengl_start_instance_matrix;
  1968.     gr_screen.gf_end_instance_matrix            = gr_opengl_end_instance_matrix;
  1969.     gr_screen.gf_start_angles_instance_matrix   = gr_opengl_start_instance_angles;
  1970.  
  1971.     gr_screen.gf_make_light         = gr_opengl_make_light;
  1972.     gr_screen.gf_modify_light       = gr_opengl_modify_light;
  1973.     gr_screen.gf_destroy_light      = gr_opengl_destroy_light;
  1974.     gr_screen.gf_set_light          = gr_opengl_set_light;
  1975.     gr_screen.gf_reset_lighting     = gr_opengl_reset_lighting;
  1976.     gr_screen.gf_set_ambient_light  = gr_opengl_set_ambient_light;
  1977.  
  1978.     gr_screen.gf_post_process_set_effect    = gr_opengl_post_process_set_effect;
  1979.     gr_screen.gf_post_process_set_defaults  = gr_opengl_post_process_set_defaults;
  1980.  
  1981.     gr_screen.gf_post_process_begin     = gr_opengl_post_process_begin;
  1982.     gr_screen.gf_post_process_end       = gr_opengl_post_process_end;
  1983.     gr_screen.gf_post_process_save_zbuffer  = gr_opengl_post_process_save_zbuffer;
  1984.  
  1985.     gr_screen.gf_scene_texture_begin = gr_opengl_scene_texture_begin;
  1986.     gr_screen.gf_scene_texture_end = gr_opengl_scene_texture_end;
  1987.  
  1988.     gr_screen.gf_start_clip_plane   = gr_opengl_start_clip_plane;
  1989.     gr_screen.gf_end_clip_plane     = gr_opengl_end_clip_plane;
  1990.  
  1991.     gr_screen.gf_lighting           = gr_opengl_set_lighting;
  1992.  
  1993.     gr_screen.gf_set_proj_matrix    = gr_opengl_set_projection_matrix;
  1994.     gr_screen.gf_end_proj_matrix    = gr_opengl_end_projection_matrix;
  1995.  
  1996.     gr_screen.gf_set_view_matrix    = gr_opengl_set_view_matrix;
  1997.     gr_screen.gf_end_view_matrix    = gr_opengl_end_view_matrix;
  1998.  
  1999.     gr_screen.gf_push_scale_matrix  = gr_opengl_push_scale_matrix;
  2000.     gr_screen.gf_pop_scale_matrix   = gr_opengl_pop_scale_matrix;
  2001.     gr_screen.gf_center_alpha       = gr_opengl_center_alpha;
  2002.  
  2003.     gr_screen.gf_setup_background_fog   = gr_opengl_setup_background_fog;
  2004.  
  2005.     gr_screen.gf_start_state_block  = gr_opengl_start_state_block;
  2006.     gr_screen.gf_end_state_block    = gr_opengl_end_state_block;
  2007.     gr_screen.gf_set_state_block    = gr_opengl_set_state_block;
  2008.  
  2009.     gr_screen.gf_draw_line_list     = gr_opengl_draw_line_list;
  2010.  
  2011.     gr_screen.gf_set_line_width     = gr_opengl_set_line_width;
  2012.  
  2013.     gr_screen.gf_line_htl           = gr_opengl_line_htl;
  2014.     gr_screen.gf_sphere_htl         = gr_opengl_sphere_htl;
  2015.  
  2016.     gr_screen.gf_maybe_create_shader = gr_opengl_maybe_create_shader;
  2017.  
  2018.     gr_screen.gf_flush_data_states  = gr_opengl_flush_data_states;
  2019.  
  2020.     gr_screen.gf_set_team_color     = gr_opengl_set_team_color;
  2021.     gr_screen.gf_disable_team_color = gr_opengl_disable_team_color;
  2022.  
  2023.     gr_screen.gf_update_texture = gr_opengl_update_texture;
  2024.     // NOTE: All function pointers here should have a Cmdline_nohtl check at the top
  2025.     //       if they shouldn't be run in non-HTL mode, Don't keep separate entries.
  2026.     // *****************************************************************************
  2027. }
  2028.  
  2029.  
  2030. bool gr_opengl_init()
  2031. {
  2032.     char *ver;
  2033.     int major = 0, minor = 0;
  2034.  
  2035.     if ( !GL_initted )
  2036.         atexit(opengl_close);
  2037.  
  2038.     if (GL_initted) {
  2039.         gr_opengl_cleanup();
  2040.         GL_initted = false;
  2041.     }
  2042.  
  2043.     mprintf(( "Initializing OpenGL graphics device at %ix%i with %i-bit color...\n", gr_screen.max_w, gr_screen.max_h, gr_screen.bits_per_pixel ));
  2044.  
  2045.     if ( opengl_init_display_device() ) {
  2046.         Error(LOCATION, "Unable to initialize display device!\n");
  2047.     }
  2048.  
  2049.     // version check
  2050.     ver = (char *)glGetString(GL_VERSION);
  2051.     sscanf(ver, "%d.%d", &major, &minor);
  2052.  
  2053.     GL_version = (major * 10) + minor;
  2054.  
  2055.     if (GL_version < MIN_REQUIRED_GL_VERSION) {
  2056.         Error(LOCATION, "Current GL Version of %d.%d is less than the required version of %d.%d.\nSwitch video modes or update your drivers.", major, minor, (MIN_REQUIRED_GL_VERSION / 10), (MIN_REQUIRED_GL_VERSION % 10));
  2057.     }
  2058.  
  2059.     GL_initted = true;
  2060.  
  2061.     // this MUST be done before any other gr_opengl_* or opengl_* funcion calls!!
  2062.     opengl_setup_function_pointers();
  2063.  
  2064.     mprintf(( "  OpenGL Vendor    : %s\n", glGetString(GL_VENDOR) ));
  2065.     mprintf(( "  OpenGL Renderer  : %s\n", glGetString(GL_RENDERER) ));
  2066.     mprintf(( "  OpenGL Version   : %s\n", ver ));
  2067.     mprintf(( "\n" ));
  2068.  
  2069.     if (Cmdline_fullscreen_window || Cmdline_window) {
  2070.         opengl_go_windowed();
  2071.     } else {
  2072.         opengl_go_fullscreen();
  2073.     }
  2074.  
  2075.     // initialize the extensions and make sure we aren't missing something that we need
  2076.     opengl_extensions_init();
  2077.  
  2078.     // setup the lighting stuff that will get used later
  2079.     opengl_light_init();
  2080.    
  2081.     // init state system (must come AFTER light is set up)
  2082.     GL_state.init();
  2083.  
  2084.     GLint max_texture_units = GL_supported_texture_units;
  2085.  
  2086.     if (Use_GLSL) {
  2087.         glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS_ARB, &max_texture_units);
  2088.     }
  2089.  
  2090.     GL_state.Texture.init(max_texture_units);
  2091.     GL_state.Array.init(max_texture_units);
  2092.  
  2093.     opengl_set_texture_target();
  2094.     GL_state.Texture.SetActiveUnit(0);
  2095.     GL_state.Texture.SetTarget(GL_TEXTURE_2D);
  2096.     GL_state.Texture.Enable();
  2097.  
  2098.     // ready the texture system
  2099.     opengl_tcache_init();
  2100.  
  2101.     extern void opengl_tnl_init();
  2102.     opengl_tnl_init();
  2103.  
  2104.     // setup default shaders, and shader related items
  2105.     opengl_shader_init();
  2106.  
  2107.     // post processing effects, after shaders are initialized
  2108.     opengl_setup_scene_textures();
  2109.     opengl_post_process_init();
  2110.  
  2111.     // must be called after extensions are setup
  2112.     opengl_set_vsync( !Cmdline_no_vsync );
  2113.  
  2114.  
  2115.     opengl_setup_viewport();
  2116.  
  2117.     glClear(GL_DEPTH_BUFFER_BIT);
  2118.     glClear(GL_STENCIL_BUFFER_BIT);
  2119.  
  2120.     glShadeModel(GL_SMOOTH);
  2121.  
  2122.     glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
  2123.     glHint(GL_FOG_HINT, GL_NICEST);
  2124.  
  2125.     glDepthRange(0.0, 1.0);
  2126.  
  2127.     glPixelStorei(GL_PACK_ALIGNMENT, 1);
  2128.     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  2129.    
  2130.     glFlush();
  2131.  
  2132.     Gr_current_red = &Gr_red;
  2133.     Gr_current_blue = &Gr_blue;
  2134.     Gr_current_green = &Gr_green;
  2135.     Gr_current_alpha = &Gr_alpha;
  2136.  
  2137.     Mouse_hidden++;
  2138.     gr_opengl_reset_clip();
  2139.     gr_opengl_clear();
  2140.     gr_opengl_flip();
  2141.     gr_opengl_clear();
  2142.     gr_opengl_flip();
  2143.     gr_opengl_clear();
  2144.     Mouse_hidden--;
  2145.  
  2146.  
  2147.     glGetIntegerv(GL_MAX_ELEMENTS_VERTICES, &GL_max_elements_vertices);
  2148.     glGetIntegerv(GL_MAX_ELEMENTS_INDICES, &GL_max_elements_indices);
  2149.  
  2150.     mprintf(( "  Max texture units: %i (%i)\n", GL_supported_texture_units, max_texture_units ));
  2151.     mprintf(( "  Max elements vertices: %i\n", GL_max_elements_vertices ));
  2152.     mprintf(( "  Max elements indices: %i\n", GL_max_elements_indices ));
  2153.     mprintf(( "  Max texture size: %ix%i\n", GL_max_texture_width, GL_max_texture_height ));
  2154.  
  2155.     if ( Is_Extension_Enabled(OGL_EXT_FRAMEBUFFER_OBJECT) ) {
  2156.         mprintf(( "  Max render buffer size: %ix%i\n", GL_max_renderbuffer_size, GL_max_renderbuffer_size ));
  2157.     }
  2158.  
  2159.     mprintf(( "  Can use compressed textures: %s\n", Use_compressed_textures ? NOX("YES") : NOX("NO") ));
  2160.     mprintf(( "  Texture compression available: %s\n", Texture_compression_available ? NOX("YES") : NOX("NO") ));
  2161.     mprintf(( "  Post-processing enabled: %s\n", (Cmdline_postprocess) ? "YES" : "NO"));
  2162.     mprintf(( "  Using %s texture filter.\n", (GL_mipmap_filter) ? NOX("trilinear") : NOX("bilinear") ));
  2163.  
  2164.     if (Use_GLSL) {
  2165.         mprintf(( "  OpenGL Shader Version: %s\n", glGetString(GL_SHADING_LANGUAGE_VERSION_ARB) ));
  2166.     }
  2167.  
  2168.  
  2169.  
  2170.     // This stops fred crashing if no textures are set
  2171.     gr_screen.current_bitmap = -1;
  2172.  
  2173.     mprintf(("... OpenGL init is complete!\n"));
  2174.  
  2175.     if (Cmdline_ati_color_swap)
  2176.         GL_read_format = GL_RGBA;
  2177.  
  2178.     return true;
  2179. }
  2180.  
  2181. DCF(ogl_minimize, "Minimizes opengl")
  2182. {
  2183.     bool minimize_ogl = false;
  2184.  
  2185.     if ( gr_screen.mode != GR_OPENGL ) {
  2186.         dc_printf("Command only available in OpenGL mode.\n");
  2187.         return;
  2188.     }
  2189.  
  2190.     if (dc_optional_string_either("help", "--help")) {
  2191.         dc_printf("[bool] If true is passed, then the OpenGL window will minimize.\n");
  2192.         return;
  2193.     }
  2194.     dc_stuff_boolean(&minimize_ogl);
  2195.  
  2196.     if (minimize_ogl) {
  2197.         opengl_minimize();
  2198.     }
  2199. }
  2200.  
  2201. DCF(ogl_anisotropy, "toggles anisotropic filtering")
  2202. {
  2203.     bool process = true;
  2204.     int value;
  2205.  
  2206.     if ( gr_screen.mode != GR_OPENGL ) {
  2207.         dc_printf("Can only set anisotropic filter in OpenGL mode.\n");
  2208.         return;
  2209.     }
  2210.  
  2211.     if (dc_optional_string_either("help", "--help")) {
  2212.         dc_printf("Sets OpenGL anisotropic filtering level.\n");
  2213.         dc_printf("GL_anisotropy [int]  Valid values are 0 to %i. 0 turns off anisotropic filtering.\n", (int)opengl_get_max_anisotropy());
  2214.         process = false;
  2215.     }
  2216.  
  2217.     if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  2218.         dc_printf("Current anisotropic filter value is %i\n", (int)GL_anisotropy);
  2219.         process = false;
  2220.     }
  2221.  
  2222.     if (!process) {
  2223.         return;
  2224.     }
  2225.  
  2226.     if ( !Is_Extension_Enabled(OGL_EXT_TEXTURE_FILTER_ANISOTROPIC) ) {
  2227.         dc_printf("Error: Anisotropic filter is not settable!\n");
  2228.         return;
  2229.     }
  2230.  
  2231.     if (!dc_maybe_stuff_int(&value)) {
  2232.         // No arg passed, set to default
  2233.             GL_anisotropy = 1.0f;
  2234.         //  opengl_set_anisotropy();
  2235.             dc_printf("Anisotropic filter value reset to default level.\n");
  2236.     } else {
  2237.         GL_anisotropy = (GLfloat)value;
  2238.         //  opengl_set_anisotropy( (float)Dc_arg_float );
  2239.     }
  2240. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement