{
    This file is part of Chentrah,
    Copyright (C) 2004-2008 Anton Rzheshevski (chebmaster@mail.ru).

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see http://www.gnu.org/licenses/

 **********************************************************************}


  procedure TWindowManager.InitGL;
  var
    PixelFormat : GLuint;
  begin
    if GLInitialized then Exit;

    InitOpenGL;

    display := GetDC(WindowHandle);
      if (display = 0) then Die(MI_ERROR_CANTINITOPENGL, ['GetDC() returned 0']);

    FillChar(pfd, SizeOf(pfd), 0);

    // Заполняем бланк-формуляр для процедуры подбора формата пикселя

    { NOTE: We do not need a depth buffer since we render everything using FBO!
      Sadly, the Windows implementations of OpenGL tend to ignore that
       and create a depth buffer anyway. See the log file or console,
       the pixel format description should ideally state depth and stencil = 0
    }
    with pfd do
    begin
      nSize           := SizeOf(TPIXELFORMATDESCRIPTOR); // Size Of This Pixel Format Descriptor
      nVersion        := 1;                    // The version of this data structure
      dwFlags         := PFD_DRAW_TO_WINDOW    // Buffer supports drawing to window. Should be off for Voodoo2 ?..
                         or PFD_SUPPORT_OPENGL // Buffer supports OpenGL drawing
                         or PFD_DOUBLEBUFFER;  // Supports double buffering
      iPixelType      := PFD_TYPE_RGBA;        // RGBA color format
//      cColorBits      := 32;                   // OpenGL color depth
//      cDepthBits      := 16;
      iLayerType      := PFD_MAIN_PLANE;       // Ignored
    end;

    // Пытаемся подобрать формат пикселя, поддерживаемый контекстом устройства,
    //  наиболее близкий к желаемому... Почему-то очень часто роняло Win98
    //  если запрашивался буфер глубины больше 16 бит... :(
    // P.S. Сколько лет этому куску кода?
    if MotherState.DebugMode then AddLog('Calling wglChoosePixelFormat()...');
    // in Win98 calling ChoosePixelFormat() often caused a system-wide crash... :(

    PixelFormat := wglChoosePixelFormat(display, @pfd);
    if (PixelFormat = 0)
      then Die(MI_ERROR_CANTINITOPENGL,['wglChoosePixelFormat() returned 0']);

    if MotherState.DebugMode then AddLog('chosen pixel format = %0.',[PixelFormat]);

    // Устанавливаем для нашего контекста устройства подобранный формат пикселя
    if not wglSetPixelFormat(display, PixelFormat, @pfd)
      then  Die(MI_ERROR_CANTINITOPENGL,['wglSetPixelFormat() returned FALSE.']);

    // Создаём рисовальный контекст OpenGL..
    context := wglCreateContext(display);
    if (context = 0)
      then Die(MI_ERROR_CANTINITOPENGL, ['wglCreateContext() returned 0']);

    if MotherState.DebugMode then AddLog('rendering context = %0',[context]);

    // ..и делаем его текущим.
    if (not wglMakeCurrent(display, context))
      then Die(MI_ERROR_CANTINITOPENGL, ['wglMakeCurrent() call failed']);
      
    CheckGLVersion;

    wglDescribePixelFormat(display, PixelFormat, sizeof(pfd), @pfd);
    AddLog(MI_LOG_SCREEN_FORMAT, [MotherState.DisplayWidth, MotherState.DisplayHeight,
              pfd.cRedBits, pfd.cGreenBits,pfd.cBlueBits, pfd.cAlphaBits,
              pfd.cDepthBits, pfd.cStencilBits]);
              
    pointer(wglSwapInterval):= _GetGLProcAddress ('wglSwapInterval');
    if not Assigned(wglSwapInterval) then pointer(wglSwapInterval):= _GetGLProcAddress ('wglSwapIntervalEXT');
    pointer(wglGetSwapInterval):= _GetGLProcAddress ('wglGetSwapInterval');
    if not Assigned(wglGetSwapInterval) then pointer(wglGetSwapInterval):= _GetGLProcAddress ('wglGetSwapIntervalEXT');

    if Assigned(wglSwapInterval) then begin
      wglSwapInterval(0);
      if Assigned(wglGetSwapInterval) and (wglGetSwapInterval() > 0)
        then GivePeriodicWarning(1.0, 'unable-to-turn-vsync-off', MI_WARN_WARNING, //annoy the user once a day
              MI_SWAP_CRAP, [RuEn(
             'OpenGL отказалась отключить Vsync.'
            ,'OpenGL refused to switch Vsync off.')])
        else
          if MotherState.DebugMode then AddLog('Vsync disabled.');
    end
    else
      if not (MotherState.OS in WindowsEmulators) then //cut the emulator some slack, won't we?
         GivePeriodicWarning(7.0, 'unable-to-turn-vsync-off', MI_WARN_WARNING, //annoy the user weekly
              MI_SWAP_CRAP, [RuEn(
               'Не поддерживается WGL_EXT_swap_control',
               'WGL_EXT_swap_control not supported')])
      else AddLog(RuEn(
           'WARNING: Не поддерживается WGL_EXT_swap_control,'#10#13'  невозможно отключить Vsync.'
          ,'WARNING: WGL_EXT_swap_control not supported,'#10#13'  cannot switch Vsync off.'));

    GLInitialized:=Yes;
  end;



  Procedure TWindowManager.CloseGL;
  begin
    if not GLInitialized then Exit;

    if MotherState.DebugMode then AddLog('ClosingOpenGL...');

    if MotherState.WindowExists then begin
    // Делаем текущий рисовальный контекст не текущим...
      if (not wglMakeCurrent(display, 0))
        then AddLog('wglMakeCurrent() failed');

    // ...и пытаемся удалить его
      if (not wglDeleteContext(context)) then
      begin
        AddLog('wglDeleteContext() failed');
        context := 0;
      end;

    // Пытаемся освободить контекст устройства
      if (ReleaseDC(WindowHandle, display) = 0)
      and IsWindow(WindowHandle)
      then begin
        AddLog('ReleaseDC() failed');
        display := 0;
      end;
    end;

    //выгружаем DLL
    CloseOpenGL;

    if MotherState.DebugMode then AddLogOk;
  end;




