
{type
   TGDHandle = ptrint;
   TCGrafPtr = Pointer;
   PAGLDevice = ^TAGLDevice;
   TAGLDevice = TGDHandle;
   PAGLDrawable = ^TAGLDrawable;
   TAGLDrawable = TCGrafPtr;
   TAGLRendererInfo = Pointer;

   TAGLPixelFormat = Pointer;

   TAGLContext = Pointer;

   TAGLPbuffer = Pointer;
   PAGLPbuffer = ^TAGLPbuffer;}
const
  AGL_SWAP_INTERVAL = 222;


//everything is hard linked via {$linkframework AGL} in cge.pp
function aglCreateContext(PixelFormat, share: pointer): pointer; cdecl; external;
function aglDestroyContext(context: pointer): GLboolean; cdecl; external;
procedure aglSwapBuffers(context: pointer); cdecl; external;
function aglSetInteger(context: pointer; pname:GLenum; params: PGLint): GLboolean; cdecl; external;
function aglGetInteger(context: pointer; pname:GLenum; params: PGLint): GLboolean; cdecl; external;



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

    InitOpenGL(Config.Str['opengl', 'GL_' + SystemSuffix]);




    CheckGLVersion;

{    wglDescribePixelFormat(display, PixelFormat, sizeof(pfd), @pfd);
    AddLog(MI_LOG_SCREEN_FORMAT, [WinW, WinH,
              pfd.cRedBits, pfd.cGreenBits,pfd.cBlueBits, pfd.cAlphaBits,
              pfd.cDepthBits, pfd.cStencilBits]);}

{    wglSwapInterval:= _GetGLProcAddress ('wglSwapInterval');
    if not Assigned(@wglSwapInterval) then wglSwapInterval:= _GetGLProcAddress ('wglSwapIntervalEXT');
    wglGetSwapInterval:= _GetGLProcAddress ('wglGetSwapInterval');
    if not Assigned(@wglGetSwapInterval) then 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
}

    if MotherState.IsFullScreen then begin
      i:= 0;
      if not aglSetInteger (context, AGL_SWAP_INTERVAL, @i)
        then GivePeriodicWarning(1.0, 'unable-to-turn-vsync-off', MI_WARN_WARNING, //annoy the user once a day
              MI_SWAP_CRAP, ['( - )'])

    end;
    if not
    GLInitialized:=Yes;
  end;



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

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

    if MotherState.WindowExists then begin

    end;

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

    if MotherState.DebugMode then AddLogOk;
  end;

(*
Drawing to a Carbon Window
This section describes the steps for setting up onscreen drawing to a Carbon window.
 To get an idea of how these steps fit into an full application, you should look at
 the sample application GLCarbonAGLWindow.
Follow these steps to use the AGL API to set up onscreen drawing to a Carbon window:
   1.
      Set up an array of attributes that describes the buffer characteristics and
       renderer capabilities that you want. You can supply any of the pixel format
       attributes or extended attributes defined in AGL Constants in AGL Reference.
      This example in Listing 2-10 sets up attributes for RGBA, double buffering,
      and a pixel depth of 24 bits. Your code would set up whatever attributes are
      appropriate. In later chapters in this book, you'll see how to choose attributes
       for specific purposes. (See “Techniques for Choosing Attributes.”)
   2.
      Obtain a pixel format object by passing the attributes array to the function
       aglChoosePixelFormat.
      The pixel format object contains a list of all appropriate renderer-display
      combinations. In the example shown here, it's likely that the list will contain
       at least two items—one that uses a hardware renderer and another that uses
       a software renderer.
   3.
      Bind the pixel format object to a rendering context by passing the pixel format
       object to the function aglCreateContext.
      If the pixel format object has more than one pixel format (renderer-display
       combination) in it, AGL uses the first in the list. You can call the function
        aglNextPixelFormat if you want to use the next pixel format in the list.
   4.
      Release the pixel format object by calling the function aglDestroyPixelFormat.
   5.
      Get the port associated with the Carbon window that you want to draw into by
       calling the Window Manager function GetWindowPort. After you attach a rendering
        context to the Carbon window, its viewport is set to the full size of the window.
      Note: The AGL API for drawing to a Carbon window was developed prior to Mac OS X.
       Because of this heritage, the AGLDrawable data type is a CGrafPtr data type under
        the hood. That's why you must call GetWindowPort to obtain the associated
         graphics port from the WindowRef data type passed to MySetWindowAsDrawableObject.
   6.
      Bind the window to the rendering context by passing the port to the function
      aglSetDrawable.
   7.
      Make the rendering context the current context by calling function aglSetCurrentContext.
Listing 2-10 shows how to implement these steps and how to check for errors along
the way by calling the application-defined function MySetWindowAsDrawableObject.
It's recommended that your application provides a similar error-checking function.
 In the case of an error you'll either want to notify the user and abort the program
  or take some sort of fallback action that ensures you application can draw OpenGL
  content. (See “Ensuring a Valid Pixel Format Object” for an example of backing out
   of attributes. See “Retrieve Error Information Only When Debugging” for guidelines
    on error checking and performance.)
Note that the example passes the pixel format object returned from the aglChoosePixelFormat
 function to the function aglCreateContext. By default, AGL uses the first pixel format
  in the pixel format object regardless of how many pixel formats are actually in the
   object. You can iterate through the pixel format object using the functionaglNextPixelFormat.

Listing 2-10  Setting a Carbon window as a drawable object
OSStatus MySetWindowAsDrawableObject  (WindowRef window)
{
    OSStatus err = noErr;
    Rect rectPort;
    GLint attributes[] =  { AGL_RGBA,
                        AGL_DOUBLEBUFFER,
                        AGL_DEPTH_SIZE, 24,
                        AGL_NONE };
    AGLContext  myAGLContext = NULL;
    AGLPixelFormat myAGLPixelFormat;
    myAGLPixelFormat = aglChoosePixelFormat (NULL, 0, attributes);
    err = MyAGLReportError ();
    if (myAGLPixelFormat) {
        myAGLContext = aglCreateContext (myAGLPixelFormat, NULL);
        err = MyAGLReportError ();
    }
    if (! aglSetDrawable (myAGLContext, GetWindowPort (window)))
            err = MyAGLReportError ();
    if (!aglSetCurrentContext (myAGLContext))
            err = MyAGLReportError ();
    return err;
}



OSStatus MyAGLReportError (void)
{
    GLenum err = aglGetError();
    if (AGL_NO_ERROR != err) {
        char errStr[256];
        sprintf (errStr, "AGL: %s",(char * ) aglErrorString(err));
        reportError (errStr);
    }
    if (err == AGL_NO_ERROR)
        return noErr;
    else
        return (OSStatus) err;
}

Note: Although this example shows how to draw OpenGL content to an entire Carbon window,
 it is possible for Carbon applications to draw to a part of a window. Carbon developers
  can find additional information on using windows by reading Handling Carbon Windows
   and Controls.
*)


(*
Using AGL to Create a Full-Screen Context

This extended code example is an excerpt from an application that uses an application-defined
 structure—pRecContext—to store information about the context, including display IDs for the
  displays attached to the system and a rendering context. The MySetupAGL routine in Listing
   3-2 takes as parameters a pRecContext data type, a width and height that specifies the
    screen resolution, a bit depth, and the refresh rate of the display.

The MySetupAGL routine sets the display mode and sets up a full-screen context. A detailed
 explanation for each numbered line of code appears following the listing.

Listing 3-2  A function that sets up a full-screen context using AGL

OSStatus MySetupAGL (pRecContext pContextInfo, size_t width, size_t height,
                        size_t depth, CGRefreshRate refresh)
{

Sets up renderer and buffer attributes. You must supply AGL_FULLSCREEN when you want
to set up a full-screen context using the AGL API. This example also provides a number
of other attributes: RGBA pixel format, double buffering, a depth size of 32 bits,
and the no recovery attribute. No recovery indicates that if a suitable hardware
renderer isn't found, the operating system should not substitute a software renderer.
    OSStatus err = noErr;
    GLint attribs[] = { AGL_RGBA, AGL_NO_RECOVERY,
            AGL_FULLSCREEN, AGL_DOUBLEBUFFER,
            AGL_DEPTH_SIZE, 32,
                        0 };


Obtains the best display mode for the screen resolution, bit depth, and refresh rate
passed to the MySetupAGL function.
    AGLPixelFormat pixelFormat = NULL;
    long i, index;
    GDHandle gdhDisplay;
    CFDictionaryRef refDisplayMode = 0;
    if (NULL == pContextInfo)
        return paramErr;
    refDisplayMode = CGDisplayBestModeForParametersAndRefreshRate(
                            pContextInfo->display,
                            depth, width, height, refresh, NULL);


Gets the current display mode and then saves it so that it can be restored later.
It's recommended practice for you to save and restore the display mode.
    if (refDisplayMode) {
        gOldDisplayMode = CGDisplayCurrentMode( pContextInfo->display);

Switches to the display mode.
        gOldDisplayModeValid = GL_TRUE;
        CGDisplaySwitchToMode (pContextInfo->display, refDisplayMode);
    }


Gets the display capabilities of interest for current display. For more information
on determining the capabilities of a display, see “Determining the OpenGL Capabilities
Supported by the Hardware.”
    for (i = 0; i < gNumDisplays; i++) {

Calls the Display Manager function that obtains a handle for the video device with the
specified display ID. You must pass this handle to aglChoosePixelFormat.
        if (pContextInfo->display == gDisplayCaps[i].cgDisplayID) index = i;
    }
    err = DMGetGDeviceByDisplayID ((DisplayIDType)pContextInfo->display,
                                 &gdhDisplay, false);
Sets the current context to the newly created context. If you fail to perform this task,
you won't see any OpenGL content drawn on the screen.
    if (noErr == err)
        if (!(pixelFormat = aglChoosePixelFormat (&gdhDisplay, 1, attribs)))
            err = aglReportError ();
    if (pixelFormat) {
        if (!(pContextInfo->aglContext = aglCreateContext( pixelFormat, NULL)))
            err = aglReportError ();
        aglDestroyPixelFormat (pixelFormat);
    }
    if (pContextInfo->aglContext) {
        short fNum;
        GLint swap = 1;
        if (!aglSetCurrentContext (pContextInfo->aglContext)) // 7
            err = aglReportError ();

Attaches the full-screen drawable object to the rendering context.
        if ((noErr == err) && !aglSetFullScreen( pContextInfo->aglContext,  0, 0, 0, 0)) // 8
            err = aglReportError ();


Synchronizes to the refresh rate by setting the swap interval to 1. (Recall that the swap
variable was previously assigned a value of 1). For more information, see “Synchronize
with the Screen Refresh Rate.” The function aglSetInteger allows you to set a variety of
rendering context parameters. For more information see “Techniques for Working with Rendering Contexts.”
        if (noErr == err) {
            if (!aglSetInteger (pContextInfo->aglContext,
                                AGL_SWAP_INTERVAL, &swap)); // 9
                err = aglReportError ();
            /* Your code to perform other initializations here */
        }
    }
    return err;
}
  *)
