//==================================================================================
// Copyright (c) 2016 , Advanced Micro Devices, Inc.  All rights reserved.
//
/// \author AMD Developer Tools Team
/// \file gsOpenGLExtensionsWrappers.cpp
///
//==================================================================================

//------------------------------ gsExtensionsWrappers.cpp ------------------------------


// ---------------------------------------------------------------------------
// File:
//   This file contains wrapper functions for the supported OpenGL, GLX and
//   WGL extensions functions.
// ---------------------------------------------------------------------------

// Infra:
#include <AMDTBaseTools/Include/AMDTDefinitions.h>
#include <AMDTOSAPIWrappers/Include/oaOpenGLIncludes.h>
#include <AMDTOSWrappers/Include/osDebugLog.h>
#include <AMDTAPIClasses/Include/apFrameTerminators.h>
#include <AMDTAPIClasses/Include/apGLRenderContextGraphicsInfo.h>
#include <AMDTAPIClasses/Include/apGLenumParameter.h>
#include <AMDTServerUtilities/Include/suGlobalVariables.h>
#include <AMDTServerUtilities/Include/suInterceptionFunctions.h>

// Local:
#include <src/gsStringConstants.h>
#include <src/gsWrappersCommon.h>
#include <src/gsExtensionsManager.h>
#include <src/gsOpenGLMonitor.h>
#include <src/gsGLDebugOutputManager.h>


// --------------------------------------------------------
//             OpenGL Extensions Wrapper functions
// --------------------------------------------------------


//////////////////////////////////////////////////////////////////////////
// OpenGL 1.2
//////////////////////////////////////////////////////////////////////////
#if ((AMDT_BUILD_TARGET == AMDT_LINUX_OS) && (AMDT_LINUX_VARIANT == AMDT_MAC_OS_X_LINUX_VARIANT))
    void APIENTRY glTexImage3D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid* pixels)
#else
    void APIENTRY glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid* pixels)
#endif
{
    SU_START_FUNCTION_WRAPPER(ap_glTexImage3D);

    // Check if stub textures are forced:
    bool areStubTexForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubTexForced = pCurrentThreadRenderContextMonitor->forcedModesManager().isStubForced(AP_OPENGL_FORCED_STUB_TEXTURES_MODE);
    }

    // If we are not in "Force stub textures" mode:
    if (!areStubTexForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glTexImage3D, (target, level, internalformat, width, height, depth, border, format, type, pixels));

        // Log the loaded texture:
        if (NULL != pCurrentThreadRenderContextMonitor)
        {
            bool rcTex = pCurrentThreadRenderContextMonitor->onTextureImageLoaded(target, level, internalformat, width, height, depth, border, format, type);
            GT_ASSERT(rcTex);
        }
    }

    // Log the call to this function:
    GLuint boundTextureName = gs_stat_openGLMonitorInstance.boundTexture(target);
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTexImage3D, 11, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_PIXEL_INTERNAL_FORMAT_PARAMETER, internalformat, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_SIZEI_PARAMETER, height, OS_TOBJ_ID_GL_SIZEI_PARAMETER, depth, OS_TOBJ_ID_GL_INT_PARAMETER, border, OS_TOBJ_ID_GL_ENUM_PARAMETER, format, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_P_VOID_PARAMETER, pixels, OS_TOBJ_ID_ASSOCIATED_TEXTURE_NAMES_PSEUDO_PARAMETER, 1, &boundTextureName);

    SU_END_FUNCTION_WRAPPER(ap_glTexImage3D);
}

void APIENTRY glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid* indices)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glDrawRangeElements);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glDrawRangeElements, 6, OS_TOBJ_ID_GL_PRIMITIVE_TYPE_PARAMETER, mode, OS_TOBJ_ID_GL_UINT_PARAMETER, start, OS_TOBJ_ID_GL_UINT_PARAMETER, end, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_P_VOID_PARAMETER, indices);

    // Get the current render context monitor:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (pCurrentThreadRenderContextMonitor != NULL)
    {
        // Get the render primitives statistics logger:
        gsRenderPrimitivesStatisticsLogger& renderPrimitivesStatisticsLogger = pCurrentThreadRenderContextMonitor->renderPrimitivesStatisticsLogger();

        // Log this draw primitives function call:
        renderPrimitivesStatisticsLogger.onDrawRangeElements(count, mode, type);
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glDrawRangeElements, (mode, start, end, count, type, indices));

    SU_END_FUNCTION_WRAPPER(ap_glDrawRangeElements);
}

void APIENTRY glColorTable(GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid* table)
{
    SU_START_FUNCTION_WRAPPER(ap_glColorTable);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glColorTable, 6, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, internalformat, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_ENUM_PARAMETER, format, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_P_VOID_PARAMETER, table);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glColorTable, (target, internalformat, width, format, type, table));

    SU_END_FUNCTION_WRAPPER(ap_glColorTable);
}

void APIENTRY glColorTableParameterfv(GLenum target, GLenum pname, const GLfloat* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glColorTableParameterfv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glColorTableParameterfv, 1, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, params);
    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glColorTableParameterfv, (target, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glColorTableParameterfv);
}

void APIENTRY glColorTableParameteriv(GLenum target, GLenum pname, const GLint* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glColorTableParameteriv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glColorTableParameteriv, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glColorTableParameteriv, (target, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glColorTableParameteriv);
}

void APIENTRY glCopyColorTable(GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width)
{
    SU_START_FUNCTION_WRAPPER(ap_glCopyColorTable);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glCopyColorTable, 5, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, internalformat, OS_TOBJ_ID_GL_INT_PARAMETER, x, OS_TOBJ_ID_GL_INT_PARAMETER, y, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glCopyColorTable, (target, internalformat, x, y, width));

    SU_END_FUNCTION_WRAPPER(ap_glCopyColorTable);
}

void APIENTRY glGetColorTable(GLenum target, GLenum format, GLenum type, GLvoid* table)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetColorTable);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetColorTable, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, format, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_P_VOID_PARAMETER, table);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetColorTable, (target, format, type, table));

    SU_END_FUNCTION_WRAPPER(ap_glGetColorTable);
}

void APIENTRY glGetColorTableParameterfv(GLenum target, GLenum pname, GLfloat* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetColorTableParameterfv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetColorTableParameterfv, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetColorTableParameterfv, (target, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetColorTableParameterfv);
}

void APIENTRY glGetColorTableParameteriv(GLenum target, GLenum pname, GLint* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetColorTableParameteriv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetColorTableParameteriv, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetColorTableParameteriv, (target, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetColorTableParameteriv);
}

void APIENTRY glTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid* pixels)
{
    SU_START_FUNCTION_WRAPPER(ap_glTexSubImage3D);

    // Check if stub textures are forced:
    bool areStubTexForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubTexForced = pCurrentThreadRenderContextMonitor->forcedModesManager().isStubForced(AP_OPENGL_FORCED_STUB_TEXTURES_MODE);
    }

    // If we are not in "Force stub textures" mode:
    if (!areStubTexForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glTexSubImage3D, (target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels));

        // Log the loaded sub-texture:
        if (NULL != pCurrentThreadRenderContextMonitor)
        {
            bool rcSubTex = pCurrentThreadRenderContextMonitor->onTextureSubImageLoaded(target, level);
            GT_ASSERT(rcSubTex);
        }
    }

    // Log the call to this function:
    GLuint boundTextureName = gs_stat_openGLMonitorInstance.boundTexture(target);
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTexSubImage3D, 12, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_INT_PARAMETER, xoffset, OS_TOBJ_ID_GL_INT_PARAMETER, yoffset, OS_TOBJ_ID_GL_INT_PARAMETER, zoffset, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_SIZEI_PARAMETER, height, OS_TOBJ_ID_GL_SIZEI_PARAMETER, depth, OS_TOBJ_ID_GL_ENUM_PARAMETER, format, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_P_VOID_PARAMETER, pixels, OS_TOBJ_ID_ASSOCIATED_TEXTURE_NAMES_PSEUDO_PARAMETER, 1, &boundTextureName);

    SU_END_FUNCTION_WRAPPER(ap_glTexSubImage3D);
}

void APIENTRY glCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height)
{
    SU_START_FUNCTION_WRAPPER(ap_glCopyTexSubImage3D);

    // Check if stub textures are forced:
    bool areStubTexForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubTexForced = pCurrentThreadRenderContextMonitor->forcedModesManager().isStubForced(AP_OPENGL_FORCED_STUB_TEXTURES_MODE);
    }

    // If we are not in "Force stub textures" mode:
    if (!areStubTexForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glCopyTexSubImage3D, (target, level, xoffset, yoffset, zoffset, x, y, width, height));

        // Log the loaded sub-texture:
        if (NULL != pCurrentThreadRenderContextMonitor)
        {
            bool rcSubTex = pCurrentThreadRenderContextMonitor->onTextureSubImageLoaded(target, level);
            GT_ASSERT(rcSubTex);
        }
    }

    // Log the call to this function:
    GLuint boundTextureName = gs_stat_openGLMonitorInstance.boundTexture(target);
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glCopyTexSubImage3D, 10, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_INT_PARAMETER, xoffset, OS_TOBJ_ID_GL_INT_PARAMETER, yoffset, OS_TOBJ_ID_GL_INT_PARAMETER, zoffset, OS_TOBJ_ID_GL_INT_PARAMETER, x, OS_TOBJ_ID_GL_INT_PARAMETER, y, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_SIZEI_PARAMETER, height, OS_TOBJ_ID_ASSOCIATED_TEXTURE_NAMES_PSEUDO_PARAMETER, 1, &boundTextureName);

    SU_END_FUNCTION_WRAPPER(ap_glCopyTexSubImage3D);
}

void APIENTRY glColorSubTable(GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid* data)
{
    SU_START_FUNCTION_WRAPPER(ap_glColorSubTable);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glColorSubTable, 6, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_SIZEI_PARAMETER, start, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_ENUM_PARAMETER, format, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_P_VOID_PARAMETER, data);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glColorSubTable, (target, start, count, format, type, data));

    SU_END_FUNCTION_WRAPPER(ap_glColorSubTable);
}

void APIENTRY glCopyColorSubTable(GLenum target, GLsizei start, GLint x, GLint y, GLsizei width)
{
    SU_START_FUNCTION_WRAPPER(ap_glCopyColorSubTable);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glCopyColorSubTable, 5, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_SIZEI_PARAMETER, start, OS_TOBJ_ID_GL_INT_PARAMETER, x, OS_TOBJ_ID_GL_INT_PARAMETER, y, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glCopyColorSubTable, (target, start, x, y, width));

    SU_END_FUNCTION_WRAPPER(ap_glCopyColorSubTable);
}

void APIENTRY glConvolutionFilter1D(GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid* image)
{
    SU_START_FUNCTION_WRAPPER(ap_glConvolutionFilter1D);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glConvolutionFilter1D, 6, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, internalformat, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_ENUM_PARAMETER, format, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_P_VOID_PARAMETER, image);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glConvolutionFilter1D, (target, internalformat, width, format, type, image));

    SU_END_FUNCTION_WRAPPER(ap_glConvolutionFilter1D);
}

void APIENTRY glConvolutionFilter2D(GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid* image)
{
    SU_START_FUNCTION_WRAPPER(ap_glConvolutionFilter2D);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glConvolutionFilter2D, 7, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, internalformat, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_SIZEI_PARAMETER, height, OS_TOBJ_ID_GL_ENUM_PARAMETER, format, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_P_VOID_PARAMETER, image);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glConvolutionFilter2D, (target, internalformat, width, height, format, type, image));

    SU_END_FUNCTION_WRAPPER(ap_glConvolutionFilter2D);
}

void APIENTRY glConvolutionParameterf(GLenum target, GLenum pname, GLfloat param)
{
    SU_START_FUNCTION_WRAPPER(ap_glConvolutionParameterf);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glConvolutionParameterf, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_FLOAT_PARAMETER, param);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glConvolutionParameterf, (target, pname, param));

    SU_END_FUNCTION_WRAPPER(ap_glConvolutionParameterf);
}

void APIENTRY glConvolutionParameterfv(GLenum target, GLenum pname, const GLfloat* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glConvolutionParameterfv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glConvolutionParameterfv, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glConvolutionParameterfv, (target, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glConvolutionParameterfv);
}

void APIENTRY glConvolutionParameteri(GLenum target, GLenum pname, GLint param)
{
    SU_START_FUNCTION_WRAPPER(ap_glConvolutionParameteri);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glConvolutionParameteri, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_INT_PARAMETER, param);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glConvolutionParameteri, (target, pname, param));

    SU_END_FUNCTION_WRAPPER(ap_glConvolutionParameteri);
}

void APIENTRY glConvolutionParameteriv(GLenum target, GLenum pname, const GLint* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glConvolutionParameteriv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glConvolutionParameteriv, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glConvolutionParameteriv, (target, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glConvolutionParameteriv);
}

void APIENTRY glCopyConvolutionFilter1D(GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width)
{
    SU_START_FUNCTION_WRAPPER(ap_glCopyConvolutionFilter1D);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glCopyConvolutionFilter1D, 5, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, internalformat, OS_TOBJ_ID_GL_INT_PARAMETER, x, OS_TOBJ_ID_GL_INT_PARAMETER, y, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glCopyConvolutionFilter1D, (target, internalformat, x, y, width));

    SU_END_FUNCTION_WRAPPER(ap_glCopyConvolutionFilter1D);
}

void APIENTRY glCopyConvolutionFilter2D(GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height)
{
    SU_START_FUNCTION_WRAPPER(ap_glCopyConvolutionFilter2D);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glCopyConvolutionFilter2D, 6, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, internalformat, OS_TOBJ_ID_GL_INT_PARAMETER, x, OS_TOBJ_ID_GL_INT_PARAMETER, y, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_SIZEI_PARAMETER, height);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glCopyConvolutionFilter2D, (target, internalformat, x, y, width, height));

    SU_END_FUNCTION_WRAPPER(ap_glCopyConvolutionFilter2D);
}

void APIENTRY glGetConvolutionFilter(GLenum target, GLenum format, GLenum type, GLvoid* image)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetConvolutionFilter);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetConvolutionFilter, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, format, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_P_VOID_PARAMETER, image);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetConvolutionFilter, (target, format, type, image));

    SU_END_FUNCTION_WRAPPER(ap_glGetConvolutionFilter);
}

void APIENTRY glGetConvolutionParameterfv(GLenum target, GLenum pname, GLfloat* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetConvolutionParameterfv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetConvolutionParameterfv, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetConvolutionParameterfv, (target, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetConvolutionParameterfv);
}

void APIENTRY glGetConvolutionParameteriv(GLenum target, GLenum pname, GLint* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetConvolutionParameteriv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetConvolutionParameteriv, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetConvolutionParameteriv, (target, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetConvolutionParameteriv);
}

void APIENTRY glGetSeparableFilter(GLenum target, GLenum format, GLenum type, GLvoid* row, GLvoid* column, GLvoid* span)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetSeparableFilter);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetSeparableFilter, 6, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, format, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_P_VOID_PARAMETER, row, OS_TOBJ_ID_GL_P_VOID_PARAMETER, column, OS_TOBJ_ID_GL_P_VOID_PARAMETER, span);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetSeparableFilter, (target, format, type, row, column, span));

    SU_END_FUNCTION_WRAPPER(ap_glGetSeparableFilter);
}

void APIENTRY glSeparableFilter2D(GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid* row, const GLvoid* column)
{
    SU_START_FUNCTION_WRAPPER(ap_glSeparableFilter2D);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glSeparableFilter2D, 8, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, internalformat, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_SIZEI_PARAMETER, height, OS_TOBJ_ID_GL_ENUM_PARAMETER, format, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_P_VOID_PARAMETER, row, OS_TOBJ_ID_GL_P_VOID_PARAMETER, column);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glSeparableFilter2D, (target, internalformat, width, height, format, type, row, column));

    SU_END_FUNCTION_WRAPPER(ap_glSeparableFilter2D);
}

void APIENTRY glGetHistogram(GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid* values)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetHistogram);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetHistogram, 5, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_BOOL_PARAMETER, reset, OS_TOBJ_ID_GL_ENUM_PARAMETER, format, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_P_VOID_PARAMETER, values);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetHistogram, (target, reset, format, type, values));

    SU_END_FUNCTION_WRAPPER(ap_glGetHistogram);
}

void APIENTRY glGetHistogramParameterfv(GLenum target, GLenum pname, GLfloat* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetHistogramParameterfv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetHistogramParameterfv, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetHistogramParameterfv, (target, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetHistogramParameterfv);
}

void APIENTRY glGetHistogramParameteriv(GLenum target, GLenum pname, GLint* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetHistogramParameteriv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetHistogramParameteriv, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetHistogramParameteriv, (target, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetHistogramParameteriv);
}

void APIENTRY glGetMinmax(GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid* values)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetMinmax);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetMinmax, 5, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_BOOL_PARAMETER, reset, OS_TOBJ_ID_GL_ENUM_PARAMETER, format, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_P_VOID_PARAMETER, values);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetMinmax, (target, reset, format, type, values));

    SU_END_FUNCTION_WRAPPER(ap_glGetMinmax);
}

void APIENTRY glGetMinmaxParameterfv(GLenum target, GLenum pname, GLfloat* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetMinmaxParameterfv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetMinmaxParameterfv, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetMinmaxParameterfv, (target, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetMinmaxParameterfv);
}

void APIENTRY glGetMinmaxParameteriv(GLenum target, GLenum pname, GLint* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetMinmaxParameteriv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetMinmaxParameteriv, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetMinmaxParameteriv, (target, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetMinmaxParameteriv);
}

void APIENTRY glHistogram(GLenum target, GLsizei width, GLenum internalformat, GLboolean sink)
{
    SU_START_FUNCTION_WRAPPER(ap_glHistogram);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glHistogram, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_ENUM_PARAMETER, internalformat, OS_TOBJ_ID_GL_BOOL_PARAMETER, sink);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glHistogram, (target, width, internalformat, sink));

    SU_END_FUNCTION_WRAPPER(ap_glHistogram);
}

void APIENTRY glMinmax(GLenum target, GLenum internalformat, GLboolean sink)
{
    SU_START_FUNCTION_WRAPPER(ap_glMinmax);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMinmax, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, internalformat, OS_TOBJ_ID_GL_BOOL_PARAMETER, sink);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMinmax, (target, internalformat, sink));

    SU_END_FUNCTION_WRAPPER(ap_glMinmax);
}

void APIENTRY glResetHistogram(GLenum target)
{
    SU_START_FUNCTION_WRAPPER(ap_glResetHistogram);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glResetHistogram, 1, OS_TOBJ_ID_GL_ENUM_PARAMETER, target);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glResetHistogram, (target));

    SU_END_FUNCTION_WRAPPER(ap_glResetHistogram);
}

void APIENTRY glResetMinmax(GLenum target)
{
    SU_START_FUNCTION_WRAPPER(ap_glResetMinmax);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glResetMinmax, 1, OS_TOBJ_ID_GL_ENUM_PARAMETER, target);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glResetMinmax, (target));

    SU_END_FUNCTION_WRAPPER(ap_glResetMinmax);
}

void APIENTRY glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
{
    SU_START_FUNCTION_WRAPPER(ap_glBlendColor);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glBlendColor, 4, OS_TOBJ_ID_GL_CLAMPF_PARAMETER, red, OS_TOBJ_ID_GL_CLAMPF_PARAMETER, green, OS_TOBJ_ID_GL_CLAMPF_PARAMETER, blue, OS_TOBJ_ID_GL_CLAMPF_PARAMETER, alpha);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glBlendColor, (red, green, blue, alpha));

    SU_END_FUNCTION_WRAPPER(ap_glBlendColor);
}

void APIENTRY glBlendEquation(GLenum mode)
{
    SU_START_FUNCTION_WRAPPER(ap_glBlendEquation);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glBlendEquation, 1, OS_TOBJ_ID_GL_ENUM_PARAMETER, mode);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glBlendEquation, (mode));

    SU_END_FUNCTION_WRAPPER(ap_glBlendEquation);
}

//////////////////////////////////////////////////////////////////////////
// OpenGL 1.3
//////////////////////////////////////////////////////////////////////////
void APIENTRY glActiveTexture(GLenum texture)
{
    SU_START_FUNCTION_WRAPPER(ap_glActiveTexture);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glActiveTexture, 1, OS_TOBJ_ID_GL_ENUM_PARAMETER, texture);

    // Log the active texture unit change:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        bool rc = pCurrentThreadRenderContextMonitor->onActiveTextureUnitChanged(texture);

        if (!rc)
        {
            // Generate a detected error:
            gtString errorDescription;
            apErrorCode errorCode = AP_NON_SUPPORTED_TEXTURE_UNIT_ERROR;

            errorDescription = GS_STR_usingNonSupportedTextureUnit;

            gs_stat_openGLMonitorInstance.reportDetectedError(errorCode, errorDescription, ap_glActiveTexture);
        }
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glActiveTexture, (texture));

    SU_END_FUNCTION_WRAPPER(ap_glActiveTexture);
}

void APIENTRY glClientActiveTexture(GLenum texture)
{
    SU_START_FUNCTION_WRAPPER(ap_glClientActiveTexture);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glClientActiveTexture, 1, OS_TOBJ_ID_GL_ENUM_PARAMETER, texture);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glClientActiveTexture, (texture));

    SU_END_FUNCTION_WRAPPER(ap_glClientActiveTexture);
}

void APIENTRY glMultiTexCoord1d(GLenum target, GLdouble s)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glMultiTexCoord1d);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexCoord1d, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, s);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexCoord1d, (target, s));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexCoord1d);
}

void APIENTRY glMultiTexCoord1dv(GLenum target, const GLdouble* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glMultiTexCoord1dv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexCoord1dv, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, 1, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexCoord1dv, (target, v));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexCoord1dv);
}

void APIENTRY glMultiTexCoord1f(GLenum target, GLfloat s)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glMultiTexCoord1f);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexCoord1f, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_FLOAT_PARAMETER, s);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexCoord1f, (target, s));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexCoord1f);
}

void APIENTRY glMultiTexCoord1fv(GLenum target, const GLfloat* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glMultiTexCoord1fv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexCoord1fv, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_FLOAT_PARAMETER, 1, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexCoord1fv, (target, v));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexCoord1fv);
}

void APIENTRY glMultiTexCoord1i(GLenum target, GLint s)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glMultiTexCoord1i);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexCoord1i, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_INT_PARAMETER, s);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexCoord1i, (target, s));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexCoord1i);
}

void APIENTRY glMultiTexCoord1iv(GLenum target, const GLint* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glMultiTexCoord1iv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexCoord1iv, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_INT_PARAMETER, 1, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexCoord1iv, (target, v));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexCoord1iv);
}

void APIENTRY glMultiTexCoord1s(GLenum target, GLshort s)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glMultiTexCoord1s);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexCoord1s, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_SHORT_PARAMETER, s);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexCoord1s, (target, s));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexCoord1s);
}

void APIENTRY glMultiTexCoord1sv(GLenum target, const GLshort* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glMultiTexCoord1sv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexCoord1sv, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_SHORT_PARAMETER, 1, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexCoord1sv, (target, v));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexCoord1sv);
}

void APIENTRY glMultiTexCoord2d(GLenum target, GLdouble s, GLdouble t)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glMultiTexCoord2d);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexCoord2d, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, s, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, t);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexCoord2d, (target, s, t));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexCoord2d);
}

void APIENTRY glMultiTexCoord2dv(GLenum target, const GLdouble* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glMultiTexCoord2dv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexCoord2dv, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, 2, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexCoord2dv, (target, v));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexCoord2dv);
}

void APIENTRY glMultiTexCoord2f(GLenum target, GLfloat s, GLfloat t)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glMultiTexCoord2f);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexCoord2f, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_FLOAT_PARAMETER, s, OS_TOBJ_ID_GL_FLOAT_PARAMETER, t);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexCoord2f, (target, s, t));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexCoord2f);
}

void APIENTRY glMultiTexCoord2fv(GLenum target, const GLfloat* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glMultiTexCoord2fv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexCoord2fv, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_FLOAT_PARAMETER, 2, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexCoord2fv, (target, v));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexCoord2fv);
}

void APIENTRY glMultiTexCoord2i(GLenum target, GLint s, GLint t)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glMultiTexCoord2i);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexCoord2i, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_INT_PARAMETER, s, OS_TOBJ_ID_GL_INT_PARAMETER, t);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexCoord2i, (target, s, t));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexCoord2i);
}

void APIENTRY glMultiTexCoord2iv(GLenum target, const GLint* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glMultiTexCoord2iv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexCoord2iv, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_INT_PARAMETER, 2, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexCoord2iv, (target, v));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexCoord2iv);
}

void APIENTRY glMultiTexCoord2s(GLenum target, GLshort s, GLshort t)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glMultiTexCoord2s);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexCoord2s, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_SHORT_PARAMETER, s, OS_TOBJ_ID_GL_SHORT_PARAMETER, t);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexCoord2s, (target, s, t));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexCoord2s);
}

void APIENTRY glMultiTexCoord2sv(GLenum target, const GLshort* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glMultiTexCoord2sv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexCoord2sv, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_SHORT_PARAMETER, 2, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexCoord2sv, (target, v));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexCoord2sv);
}

void APIENTRY glMultiTexCoord3d(GLenum target, GLdouble s, GLdouble t, GLdouble r)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glMultiTexCoord3d);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexCoord3d, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, s, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, t, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, r);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexCoord3d, (target, s, t, r));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexCoord3d);
}

void APIENTRY glMultiTexCoord3dv(GLenum target, const GLdouble* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glMultiTexCoord3dv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexCoord3dv, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, 3, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexCoord3dv, (target, v));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexCoord3dv);
}

void APIENTRY glMultiTexCoord3f(GLenum target, GLfloat s, GLfloat t, GLfloat r)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glMultiTexCoord3f);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexCoord3f, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_FLOAT_PARAMETER, s, OS_TOBJ_ID_GL_FLOAT_PARAMETER, t, OS_TOBJ_ID_GL_FLOAT_PARAMETER, r);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexCoord3f, (target, s, t, r));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexCoord3f);
}

void APIENTRY glMultiTexCoord3fv(GLenum target, const GLfloat* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glMultiTexCoord3fv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexCoord3fv, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_FLOAT_PARAMETER, 3, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexCoord3fv, (target, v));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexCoord3fv);
}

void APIENTRY glMultiTexCoord3i(GLenum target, GLint s, GLint t, GLint r)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glMultiTexCoord3i);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexCoord3i, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_INT_PARAMETER, s, OS_TOBJ_ID_GL_INT_PARAMETER, t, OS_TOBJ_ID_GL_INT_PARAMETER, r);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexCoord3i, (target, s, t, r));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexCoord3i);
}

void APIENTRY glMultiTexCoord3iv(GLenum target, const GLint* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glMultiTexCoord3iv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexCoord3iv, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_INT_PARAMETER, 3, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexCoord3iv, (target, v));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexCoord3iv);
}

void APIENTRY glMultiTexCoord3s(GLenum target, GLshort s, GLshort t, GLshort r)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glMultiTexCoord3s);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexCoord3s, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_SHORT_PARAMETER, s, OS_TOBJ_ID_GL_SHORT_PARAMETER, t, OS_TOBJ_ID_GL_SHORT_PARAMETER, r);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexCoord3s, (target, s, t, r));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexCoord3s);
}

void APIENTRY glMultiTexCoord3sv(GLenum target, const GLshort* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glMultiTexCoord3sv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexCoord3sv, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_SHORT_PARAMETER, 3, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexCoord3sv, (target, v));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexCoord3sv);
}

void APIENTRY glMultiTexCoord4d(GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glMultiTexCoord4d);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexCoord4d, 5, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, s, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, t, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, r, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, q);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexCoord4d, (target, s, t, r, q));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexCoord4d);
}

void APIENTRY glMultiTexCoord4dv(GLenum target, const GLdouble* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glMultiTexCoord4dv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexCoord4dv, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, 4, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexCoord4dv, (target, v));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexCoord4dv);
}

void APIENTRY glMultiTexCoord4f(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glMultiTexCoord4f);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexCoord4f, 5, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_FLOAT_PARAMETER, s, OS_TOBJ_ID_GL_FLOAT_PARAMETER, t, OS_TOBJ_ID_GL_FLOAT_PARAMETER, r, OS_TOBJ_ID_GL_FLOAT_PARAMETER, q);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexCoord4f, (target, s, t, r, q));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexCoord4f);
}

void APIENTRY glMultiTexCoord4fv(GLenum target, const GLfloat* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glMultiTexCoord4fv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexCoord4fv, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_FLOAT_PARAMETER, 4, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexCoord4fv, (target, v));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexCoord4fv);
}

void APIENTRY glMultiTexCoord4i(GLenum target, GLint s, GLint t, GLint r, GLint q)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glMultiTexCoord4i);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexCoord4i, 5, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_INT_PARAMETER, s, OS_TOBJ_ID_GL_INT_PARAMETER, t, OS_TOBJ_ID_GL_INT_PARAMETER, r, OS_TOBJ_ID_GL_INT_PARAMETER, q);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexCoord4i, (target, s, t, r, q));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexCoord4i);
}

void APIENTRY glMultiTexCoord4iv(GLenum target, const GLint* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glMultiTexCoord4iv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexCoord4iv, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_INT_PARAMETER, 4, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexCoord4iv, (target, v));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexCoord4iv);
}

void APIENTRY glMultiTexCoord4s(GLenum target, GLshort s, GLshort t, GLshort r, GLshort q)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glMultiTexCoord4s);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexCoord4s, 5, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_SHORT_PARAMETER, s, OS_TOBJ_ID_GL_SHORT_PARAMETER, t, OS_TOBJ_ID_GL_SHORT_PARAMETER, r, OS_TOBJ_ID_GL_SHORT_PARAMETER, q);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexCoord4s, (target, s, t, r, q));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexCoord4s);
}

void APIENTRY glMultiTexCoord4sv(GLenum target, const GLshort* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glMultiTexCoord4sv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexCoord4sv, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_SHORT_PARAMETER, 4, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexCoord4sv, (target, v));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexCoord4sv);
}

//////////////////////////////////////////////////////////////////////////
// OpenGL 1.3
//////////////////////////////////////////////////////////////////////////
void APIENTRY glCompressedTexImage3D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid* data)
{
    SU_START_FUNCTION_WRAPPER(ap_glCompressedTexImage3D);

    // Log the call to this function:
    GLuint boundTextureName = gs_stat_openGLMonitorInstance.boundTexture(target);
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glCompressedTexImage3D, 10, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_ENUM_PARAMETER, internalformat, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_SIZEI_PARAMETER, height, OS_TOBJ_ID_GL_SIZEI_PARAMETER, depth, OS_TOBJ_ID_GL_INT_PARAMETER, border, OS_TOBJ_ID_GL_SIZEI_PARAMETER, imageSize, OS_TOBJ_ID_GL_P_VOID_PARAMETER, data, OS_TOBJ_ID_ASSOCIATED_TEXTURE_NAMES_PSEUDO_PARAMETER, 1, &boundTextureName);

    // Check if stub textures are forced:
    bool areStubTexForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubTexForced = pCurrentThreadRenderContextMonitor->forcedModesManager().isStubForced(AP_OPENGL_FORCED_STUB_TEXTURES_MODE);
    }

    // If we are not in "Force stub textures" mode:
    if (!areStubTexForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glCompressedTexImage3D, (target, level, internalformat, width, height, depth, border, imageSize, data));

        // Log the loaded texture:
        if (NULL != pCurrentThreadRenderContextMonitor)
        {
            bool rcTex = pCurrentThreadRenderContextMonitor->onTextureImageLoaded(target, level, internalformat, width, height, depth, border, 0, 0);
            GT_ASSERT(rcTex);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glCompressedTexImage3D);
}

void APIENTRY glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid* data)
{
    SU_START_FUNCTION_WRAPPER(ap_glCompressedTexImage2D);

    // Log the call to this function:
    GLuint boundTextureName = gs_stat_openGLMonitorInstance.boundTexture(target);
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glCompressedTexImage2D, 9, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_ENUM_PARAMETER, internalformat, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_SIZEI_PARAMETER, height, OS_TOBJ_ID_GL_INT_PARAMETER, border, OS_TOBJ_ID_GL_SIZEI_PARAMETER, imageSize, OS_TOBJ_ID_GL_P_VOID_PARAMETER, data, OS_TOBJ_ID_ASSOCIATED_TEXTURE_NAMES_PSEUDO_PARAMETER, 1, &boundTextureName);

    // Check if stub textures are forced:
    bool areStubTexForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubTexForced = pCurrentThreadRenderContextMonitor->forcedModesManager().isStubForced(AP_OPENGL_FORCED_STUB_TEXTURES_MODE);
    }

    // If we are not in "Force stub textures" mode:
    if (!areStubTexForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glCompressedTexImage2D, (target, level, internalformat, width, height, border, imageSize, data));

        // Log the loaded texture:
        if (NULL != pCurrentThreadRenderContextMonitor)
        {
            bool rcTex = pCurrentThreadRenderContextMonitor->onTextureImageLoaded(target, level, internalformat, width, height, 0, border, 0, 0);
            GT_ASSERT(rcTex);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glCompressedTexImage2D);
}

void APIENTRY glCompressedTexImage1D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid* data)
{
    SU_START_FUNCTION_WRAPPER(ap_glCompressedTexImage1D);

    // Log the call to this function:
    GLuint boundTextureName = gs_stat_openGLMonitorInstance.boundTexture(target);
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glCompressedTexImage1D, 8, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_ENUM_PARAMETER, internalformat, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_INT_PARAMETER, border, OS_TOBJ_ID_GL_SIZEI_PARAMETER, imageSize, OS_TOBJ_ID_GL_P_VOID_PARAMETER, data, OS_TOBJ_ID_ASSOCIATED_TEXTURE_NAMES_PSEUDO_PARAMETER, 1, &boundTextureName);

    // Check if stub textures are forced:
    bool areStubTexForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubTexForced = pCurrentThreadRenderContextMonitor->forcedModesManager().isStubForced(AP_OPENGL_FORCED_STUB_TEXTURES_MODE);
    }

    // If we are not in "Force stub textures" mode:
    if (!areStubTexForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glCompressedTexImage1D, (target, level, internalformat, width, border, imageSize, data));

        // Log the loaded texture:
        if (NULL != pCurrentThreadRenderContextMonitor)
        {
            bool rcTex = pCurrentThreadRenderContextMonitor->onTextureImageLoaded(target, level, internalformat, width, 0, 0, border, 0, 0);
            GT_ASSERT(rcTex);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glCompressedTexImage1D);
}

void APIENTRY glCompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid* data)
{
    SU_START_FUNCTION_WRAPPER(ap_glCompressedTexSubImage3D);

    // Log the call to this function:
    GLuint boundTextureName = gs_stat_openGLMonitorInstance.boundTexture(target);
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glCompressedTexSubImage3D, 12, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_INT_PARAMETER, xoffset, OS_TOBJ_ID_GL_INT_PARAMETER, yoffset, OS_TOBJ_ID_GL_INT_PARAMETER, zoffset, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_SIZEI_PARAMETER, height, OS_TOBJ_ID_GL_SIZEI_PARAMETER, depth, OS_TOBJ_ID_GL_ENUM_PARAMETER, format, OS_TOBJ_ID_GL_SIZEI_PARAMETER, imageSize, OS_TOBJ_ID_GL_P_VOID_PARAMETER, data, OS_TOBJ_ID_ASSOCIATED_TEXTURE_NAMES_PSEUDO_PARAMETER, 1, &boundTextureName);

    // Check if stub textures are forced:
    bool areStubTexForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubTexForced = pCurrentThreadRenderContextMonitor->forcedModesManager().isStubForced(AP_OPENGL_FORCED_STUB_TEXTURES_MODE);
    }

    // If we are not in "Force stub textures" mode:
    if (!areStubTexForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glCompressedTexSubImage3D, (target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data));

        // Log the loaded sub-texture:
        if (NULL != pCurrentThreadRenderContextMonitor)
        {
            bool rcSubTex = pCurrentThreadRenderContextMonitor->onTextureSubImageLoaded(target, level);
            GT_ASSERT(rcSubTex);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glCompressedTexSubImage3D);
}

void APIENTRY glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid* data)
{
    SU_START_FUNCTION_WRAPPER(ap_glCompressedTexSubImage2D);

    // Log the call to this function:
    GLuint boundTextureName = gs_stat_openGLMonitorInstance.boundTexture(target);
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glCompressedTexSubImage2D, 10, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_INT_PARAMETER, xoffset, OS_TOBJ_ID_GL_INT_PARAMETER, yoffset, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_SIZEI_PARAMETER, height, OS_TOBJ_ID_GL_ENUM_PARAMETER, format, OS_TOBJ_ID_GL_SIZEI_PARAMETER, imageSize, OS_TOBJ_ID_GL_P_VOID_PARAMETER, data, OS_TOBJ_ID_ASSOCIATED_TEXTURE_NAMES_PSEUDO_PARAMETER, 1, &boundTextureName);

    // Check if stub textures are forced:
    bool areStubTexForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubTexForced = pCurrentThreadRenderContextMonitor->forcedModesManager().isStubForced(AP_OPENGL_FORCED_STUB_TEXTURES_MODE);
    }

    // If we are not in "Force stub textures" mode:
    if (!areStubTexForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glCompressedTexSubImage2D, (target, level, xoffset, yoffset, width, height, format, imageSize, data));

        // Log the loaded sub-texture:
        if (NULL != pCurrentThreadRenderContextMonitor)
        {
            bool rcSubTex = pCurrentThreadRenderContextMonitor->onTextureSubImageLoaded(target, level);
            GT_ASSERT(rcSubTex);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glCompressedTexSubImage2D);
}

void APIENTRY glCompressedTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid* data)
{
    SU_START_FUNCTION_WRAPPER(ap_glCompressedTexSubImage1D);

    // Log the call to this function:
    GLuint boundTextureName = gs_stat_openGLMonitorInstance.boundTexture(target);
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glCompressedTexSubImage1D, 8, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_INT_PARAMETER, xoffset, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_ENUM_PARAMETER, format, OS_TOBJ_ID_GL_SIZEI_PARAMETER, imageSize, OS_TOBJ_ID_GL_P_VOID_PARAMETER, data, OS_TOBJ_ID_ASSOCIATED_TEXTURE_NAMES_PSEUDO_PARAMETER, 1, &boundTextureName);

    // Check if stub textures are forced:
    bool areStubTexForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubTexForced = pCurrentThreadRenderContextMonitor->forcedModesManager().isStubForced(AP_OPENGL_FORCED_STUB_TEXTURES_MODE);
    }

    // If we are not in "Force stub textures" mode:
    if (!areStubTexForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glCompressedTexSubImage1D, (target, level, xoffset, width, format, imageSize, data));

        // Log the loaded sub-texture:
        if (NULL != pCurrentThreadRenderContextMonitor)
        {
            bool rcSubTex = pCurrentThreadRenderContextMonitor->onTextureSubImageLoaded(target, level);
            GT_ASSERT(rcSubTex);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glCompressedTexSubImage1D);
}

void APIENTRY glGetCompressedTexImage(GLenum target, GLint lod, GLvoid* img)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetCompressedTexImage);

    // Get the input bind target bounded texture name:
    GLuint boundTextureName = gs_stat_openGLMonitorInstance.boundTexture(target);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetCompressedTexImage, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_INT_PARAMETER, lod, OS_TOBJ_ID_GL_P_VOID_PARAMETER, img, OS_TOBJ_ID_ASSOCIATED_TEXTURE_NAMES_PSEUDO_PARAMETER, 1, &boundTextureName);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetCompressedTexImage, (target, lod, img));

    SU_END_FUNCTION_WRAPPER(ap_glGetCompressedTexImage);
}

void APIENTRY glSampleCoverage(GLclampf value, GLboolean invert)
{
    SU_START_FUNCTION_WRAPPER(ap_glSampleCoverage);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glSampleCoverage, 2, OS_TOBJ_ID_GL_CLAMPF_PARAMETER, value, OS_TOBJ_ID_GL_BOOL_PARAMETER, invert);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glSampleCoverage, (value, invert));

    SU_END_FUNCTION_WRAPPER(ap_glSampleCoverage);
}

void APIENTRY glLoadTransposeMatrixf(const GLfloat* m)
{
    SU_START_FUNCTION_WRAPPER(ap_glLoadTransposeMatrixf);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glLoadTransposeMatrixf, 1, OS_TOBJ_ID_MATRIX_PARAMETER, OS_TOBJ_ID_GL_FLOAT_PARAMETER, 4, 4, m);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glLoadTransposeMatrixf, (m));

    SU_END_FUNCTION_WRAPPER(ap_glLoadTransposeMatrixf);
}

void APIENTRY glLoadTransposeMatrixd(const GLdouble* m)
{
    SU_START_FUNCTION_WRAPPER(ap_glLoadTransposeMatrixd);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glLoadTransposeMatrixd, 1, OS_TOBJ_ID_MATRIX_PARAMETER, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, 4, 4, m);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glLoadTransposeMatrixd, (m));

    SU_END_FUNCTION_WRAPPER(ap_glLoadTransposeMatrixd);
}

void APIENTRY glMultTransposeMatrixf(const GLfloat* m)
{
    SU_START_FUNCTION_WRAPPER(ap_glMultTransposeMatrixf);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultTransposeMatrixf, 1, OS_TOBJ_ID_MATRIX_PARAMETER, OS_TOBJ_ID_GL_FLOAT_PARAMETER, 4, 4, m);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultTransposeMatrixf, (m));

    SU_END_FUNCTION_WRAPPER(ap_glMultTransposeMatrixf);
}

void APIENTRY glMultTransposeMatrixd(const GLdouble* m)
{
    SU_START_FUNCTION_WRAPPER(ap_glMultTransposeMatrixd);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultTransposeMatrixd, 1, OS_TOBJ_ID_MATRIX_PARAMETER, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, 4, 4, m);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultTransposeMatrixd, (m));

    SU_END_FUNCTION_WRAPPER(ap_glMultTransposeMatrixd);
}

//////////////////////////////////////////////////////////////////////////
// OpenGL 1.4
//////////////////////////////////////////////////////////////////////////
void APIENTRY glBlendFuncSeparate(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha)
{
    SU_START_FUNCTION_WRAPPER(ap_glBlendFuncSeparate);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glBlendFuncSeparate, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, sfactorRGB, OS_TOBJ_ID_GL_ENUM_PARAMETER, dfactorRGB, OS_TOBJ_ID_GL_ENUM_PARAMETER, sfactorAlpha, OS_TOBJ_ID_GL_ENUM_PARAMETER, dfactorAlpha);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glBlendFuncSeparate, (sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha));

    SU_END_FUNCTION_WRAPPER(ap_glBlendFuncSeparate);
}

void APIENTRY glFogCoordf(GLfloat coord)
{
    SU_START_FUNCTION_WRAPPER(ap_glFogCoordf);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glFogCoordf, 1, OS_TOBJ_ID_GL_FLOAT_PARAMETER, coord);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glFogCoordf, (coord));

    SU_END_FUNCTION_WRAPPER(ap_glFogCoordf);
}

void APIENTRY glFogCoordfv(const GLfloat* coord)
{
    SU_START_FUNCTION_WRAPPER(ap_glFogCoordfv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glFogCoordfv, 1, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, coord);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glFogCoordfv, (coord));

    SU_END_FUNCTION_WRAPPER(ap_glFogCoordfv);
}

void APIENTRY glFogCoordd(GLdouble coord)
{
    SU_START_FUNCTION_WRAPPER(ap_glFogCoordd);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glFogCoordd, 1, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, coord);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glFogCoordd, (coord));

    SU_END_FUNCTION_WRAPPER(ap_glFogCoordd);
}

void APIENTRY glFogCoorddv(const GLdouble* coord)
{
    SU_START_FUNCTION_WRAPPER(ap_glFogCoorddv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glFogCoorddv, 1, OS_TOBJ_ID_GL_P_DOUBLE_PARAMETER, coord);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glFogCoorddv, (coord));

    SU_END_FUNCTION_WRAPPER(ap_glFogCoorddv);
}

void APIENTRY glFogCoordPointer(GLenum type, GLsizei stride, const GLvoid* pointer)
{
    SU_START_FUNCTION_WRAPPER(ap_glFogCoordPointer);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glFogCoordPointer, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_SIZEI_PARAMETER, stride, OS_TOBJ_ID_GL_P_VOID_PARAMETER, pointer);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glFogCoordPointer, (type, stride, pointer));

    SU_END_FUNCTION_WRAPPER(ap_glFogCoordPointer);
}

void APIENTRY glMultiDrawArrays(GLenum mode, const GLint* first, const GLsizei* count, GLsizei primcount)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glMultiDrawArrays);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiDrawArrays, 4, OS_TOBJ_ID_GL_PRIMITIVE_TYPE_PARAMETER, mode, OS_TOBJ_ID_GL_P_INT_PARAMETER, first, OS_TOBJ_ID_GL_P_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_SIZEI_PARAMETER, primcount);

    // Get the current render context monitor:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (pCurrentThreadRenderContextMonitor != NULL)
    {
        // Get the render primitives statistics logger:
        gsRenderPrimitivesStatisticsLogger& renderPrimitivesStatisticsLogger = pCurrentThreadRenderContextMonitor->renderPrimitivesStatisticsLogger();

        // Log this draw primitives function call:
        renderPrimitivesStatisticsLogger.onMultiDrawArrays(count, primcount, mode);
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiDrawArrays, (mode, first, count, primcount));

    SU_END_FUNCTION_WRAPPER(ap_glMultiDrawArrays);
}

void APIENTRY glMultiDrawElements(GLenum mode, const GLsizei* count, GLenum type, const GLvoid* const* indices, GLsizei primcount)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glMultiDrawElements);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiDrawElements, 5, OS_TOBJ_ID_GL_PRIMITIVE_TYPE_PARAMETER, mode, OS_TOBJ_ID_GL_P_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_PP_VOID_PARAMETER, indices, OS_TOBJ_ID_GL_SIZEI_PARAMETER, primcount);

    // Get the current render context monitor:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (pCurrentThreadRenderContextMonitor != NULL)
    {
        // Get the render primitives statistics logger:
        gsRenderPrimitivesStatisticsLogger& renderPrimitivesStatisticsLogger = pCurrentThreadRenderContextMonitor->renderPrimitivesStatisticsLogger();

        // Log this draw primitives function call:
        renderPrimitivesStatisticsLogger.onMultiDrawElements(count, primcount, mode, type);
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiDrawElements, (mode, count, type, indices, primcount));

    SU_END_FUNCTION_WRAPPER(ap_glMultiDrawElements);
}

void APIENTRY glPointParameterf(GLenum pname, GLfloat param)
{
    SU_START_FUNCTION_WRAPPER(ap_glPointParameterf);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glPointParameterf, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_FLOAT_PARAMETER, param);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glPointParameterf, (pname, param));

    SU_END_FUNCTION_WRAPPER(ap_glPointParameterf);
}

void APIENTRY glPointParameterfv(GLenum pname, const GLfloat* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glPointParameterfv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glPointParameterfv, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glPointParameterfv, (pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glPointParameterfv);
}

void APIENTRY glPointParameteri(GLenum pname, GLint param)
{
    SU_START_FUNCTION_WRAPPER(ap_glPointParameteri);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glPointParameteri, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_INT_PARAMETER, param);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glPointParameteri, (pname, param));

    SU_END_FUNCTION_WRAPPER(ap_glPointParameteri);
}

void APIENTRY glPointParameteriv(GLenum pname, const GLint* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glPointParameteriv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glPointParameteriv, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glPointParameteriv, (pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glPointParameteriv);
}

void APIENTRY glSecondaryColor3b(GLbyte red, GLbyte green, GLbyte blue)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glSecondaryColor3b);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glSecondaryColor3b, 3, OS_TOBJ_ID_GL_BYTE_PARAMETER, red, OS_TOBJ_ID_GL_BYTE_PARAMETER, green, OS_TOBJ_ID_GL_BYTE_PARAMETER, blue);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glSecondaryColor3b, (red, green, blue));

    SU_END_FUNCTION_WRAPPER(ap_glSecondaryColor3b);
}

void APIENTRY glSecondaryColor3bv(const GLbyte* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glSecondaryColor3bv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glSecondaryColor3bv, 1, OS_TOBJ_ID_GL_P_BYTE_PARAMETER, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glSecondaryColor3bv, (v));

    SU_END_FUNCTION_WRAPPER(ap_glSecondaryColor3bv);
}

void APIENTRY glSecondaryColor3d(GLdouble red, GLdouble green, GLdouble blue)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glSecondaryColor3d);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glSecondaryColor3d, 3, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, red, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, green, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, blue);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glSecondaryColor3d, (red, green, blue));

    SU_END_FUNCTION_WRAPPER(ap_glSecondaryColor3d);
}

void APIENTRY glSecondaryColor3dv(const GLdouble* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glSecondaryColor3dv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glSecondaryColor3dv, 1, OS_TOBJ_ID_GL_P_DOUBLE_PARAMETER, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glSecondaryColor3dv, (v));

    SU_END_FUNCTION_WRAPPER(ap_glSecondaryColor3dv);
}

void APIENTRY glSecondaryColor3f(GLfloat red, GLfloat green, GLfloat blue)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glSecondaryColor3f);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glSecondaryColor3f, 3, OS_TOBJ_ID_GL_FLOAT_PARAMETER, red, OS_TOBJ_ID_GL_FLOAT_PARAMETER, green, OS_TOBJ_ID_GL_FLOAT_PARAMETER, blue);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glSecondaryColor3f, (red, green, blue));

    SU_END_FUNCTION_WRAPPER(ap_glSecondaryColor3f);
}

void APIENTRY glSecondaryColor3fv(const GLfloat* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glSecondaryColor3fv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glSecondaryColor3fv, 1, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glSecondaryColor3fv, (v));

    SU_END_FUNCTION_WRAPPER(ap_glSecondaryColor3fv);
}

void APIENTRY glSecondaryColor3i(GLint red, GLint green, GLint blue)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glSecondaryColor3i);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glSecondaryColor3i, 3, OS_TOBJ_ID_GL_INT_PARAMETER, red, OS_TOBJ_ID_GL_INT_PARAMETER, green, OS_TOBJ_ID_GL_INT_PARAMETER, blue);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glSecondaryColor3i, (red, green, blue));

    SU_END_FUNCTION_WRAPPER(ap_glSecondaryColor3i);
}

void APIENTRY glSecondaryColor3iv(const GLint* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glSecondaryColor3iv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glSecondaryColor3iv, 1, OS_TOBJ_ID_GL_P_INT_PARAMETER, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glSecondaryColor3iv, (v));

    SU_END_FUNCTION_WRAPPER(ap_glSecondaryColor3iv);
}

void APIENTRY glSecondaryColor3s(GLshort red, GLshort green, GLshort blue)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glSecondaryColor3s);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glSecondaryColor3s, 3, OS_TOBJ_ID_GL_SHORT_PARAMETER, red, OS_TOBJ_ID_GL_SHORT_PARAMETER, green, OS_TOBJ_ID_GL_SHORT_PARAMETER, blue);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glSecondaryColor3s, (red, green, blue));

    SU_END_FUNCTION_WRAPPER(ap_glSecondaryColor3s);
}

void APIENTRY glSecondaryColor3sv(const GLshort* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glSecondaryColor3sv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glSecondaryColor3sv, 1, OS_TOBJ_ID_GL_P_SHORT_PARAMETER, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glSecondaryColor3sv, (v));

    SU_END_FUNCTION_WRAPPER(ap_glSecondaryColor3sv);
}

void APIENTRY glSecondaryColor3ub(GLubyte red, GLubyte green, GLubyte blue)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glSecondaryColor3ub);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glSecondaryColor3ub, 3, OS_TOBJ_ID_GL_UBYTE_PARAMETER, red, OS_TOBJ_ID_GL_UBYTE_PARAMETER, green, OS_TOBJ_ID_GL_UBYTE_PARAMETER, blue);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glSecondaryColor3ub, (red, green, blue));

    SU_END_FUNCTION_WRAPPER(ap_glSecondaryColor3ub);
}

void APIENTRY glSecondaryColor3ubv(const GLubyte* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glSecondaryColor3ubv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glSecondaryColor3ubv, 1, OS_TOBJ_ID_GL_P_UBYTE_PARAMETER, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glSecondaryColor3ubv, (v));

    SU_END_FUNCTION_WRAPPER(ap_glSecondaryColor3ubv);
}

void APIENTRY glSecondaryColor3ui(GLuint red, GLuint green, GLuint blue)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glSecondaryColor3ui);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glSecondaryColor3ui, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, red, OS_TOBJ_ID_GL_UINT_PARAMETER, green, OS_TOBJ_ID_GL_UINT_PARAMETER, blue);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glSecondaryColor3ui, (red, green, blue));

    SU_END_FUNCTION_WRAPPER(ap_glSecondaryColor3ui);
}

void APIENTRY glSecondaryColor3uiv(const GLuint* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glSecondaryColor3uiv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glSecondaryColor3uiv, 1, OS_TOBJ_ID_GL_P_UINT_PARAMETER, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glSecondaryColor3uiv, (v));

    SU_END_FUNCTION_WRAPPER(ap_glSecondaryColor3uiv);
}

void APIENTRY glSecondaryColor3us(GLushort red, GLushort green, GLushort blue)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glSecondaryColor3us);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glSecondaryColor3us, 3, OS_TOBJ_ID_GL_USHORT_PARAMETER, red, OS_TOBJ_ID_GL_USHORT_PARAMETER, green, OS_TOBJ_ID_GL_USHORT_PARAMETER, blue);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glSecondaryColor3us, (red, green, blue));

    SU_END_FUNCTION_WRAPPER(ap_glSecondaryColor3us);
}

void APIENTRY glSecondaryColor3usv(const GLushort* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glSecondaryColor3usv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glSecondaryColor3usv, 1, OS_TOBJ_ID_GL_P_USHORT_PARAMETER, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glSecondaryColor3usv, (v));

    SU_END_FUNCTION_WRAPPER(ap_glSecondaryColor3usv);
}

void APIENTRY glSecondaryColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid* pointer)
{
    SU_START_FUNCTION_WRAPPER(ap_glSecondaryColorPointer);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glSecondaryColorPointer, 4, OS_TOBJ_ID_GL_INT_PARAMETER, size, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_SIZEI_PARAMETER, stride, OS_TOBJ_ID_GL_P_VOID_PARAMETER, pointer);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glSecondaryColorPointer, (size, type, stride, pointer));

    SU_END_FUNCTION_WRAPPER(ap_glSecondaryColorPointer);
}

void APIENTRY glWindowPos2d(GLdouble x, GLdouble y)
{
    SU_START_FUNCTION_WRAPPER(ap_glWindowPos2d);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glWindowPos2d, 2, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, x, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, y);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glWindowPos2d, (x, y));

    SU_END_FUNCTION_WRAPPER(ap_glWindowPos2d);
}

void APIENTRY glWindowPos2dv(const GLdouble* v)
{
    SU_START_FUNCTION_WRAPPER(ap_glWindowPos2dv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glWindowPos2dv, 1, OS_TOBJ_ID_GL_P_DOUBLE_PARAMETER, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glWindowPos2dv, (v));

    SU_END_FUNCTION_WRAPPER(ap_glWindowPos2dv);
}

void APIENTRY glWindowPos2f(GLfloat x, GLfloat y)
{
    SU_START_FUNCTION_WRAPPER(ap_glWindowPos2f);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glWindowPos2f, 2, OS_TOBJ_ID_GL_FLOAT_PARAMETER, x, OS_TOBJ_ID_GL_FLOAT_PARAMETER, y);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glWindowPos2f, (x, y));

    SU_END_FUNCTION_WRAPPER(ap_glWindowPos2f);
}

void APIENTRY glWindowPos2fv(const GLfloat* v)
{
    SU_START_FUNCTION_WRAPPER(ap_glWindowPos2fv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glWindowPos2fv, 1, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glWindowPos2fv, (v));

    SU_END_FUNCTION_WRAPPER(ap_glWindowPos2fv);
}

void APIENTRY glWindowPos2i(GLint x, GLint y)
{
    SU_START_FUNCTION_WRAPPER(ap_glWindowPos2i);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glWindowPos2i, 2, OS_TOBJ_ID_GL_INT_PARAMETER, x, OS_TOBJ_ID_GL_INT_PARAMETER, y);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glWindowPos2i, (x, y));

    SU_END_FUNCTION_WRAPPER(ap_glWindowPos2i);
}

void APIENTRY glWindowPos2iv(const GLint* v)
{
    SU_START_FUNCTION_WRAPPER(ap_glWindowPos2iv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glWindowPos2iv, 1, OS_TOBJ_ID_GL_P_INT_PARAMETER, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glWindowPos2iv, (v));

    SU_END_FUNCTION_WRAPPER(ap_glWindowPos2iv);
}

void APIENTRY glWindowPos2s(GLshort x, GLshort y)
{
    SU_START_FUNCTION_WRAPPER(ap_glWindowPos2s);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glWindowPos2s, 2, OS_TOBJ_ID_GL_SHORT_PARAMETER, x, OS_TOBJ_ID_GL_SHORT_PARAMETER, y);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glWindowPos2s, (x, y));

    SU_END_FUNCTION_WRAPPER(ap_glWindowPos2s);
}

void APIENTRY glWindowPos2sv(const GLshort* v)
{
    SU_START_FUNCTION_WRAPPER(ap_glWindowPos2sv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glWindowPos2sv, 1, OS_TOBJ_ID_GL_P_SHORT_PARAMETER, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glWindowPos2sv, (v));

    SU_END_FUNCTION_WRAPPER(ap_glWindowPos2sv);
}

void APIENTRY glWindowPos3d(GLdouble x, GLdouble y, GLdouble z)
{
    SU_START_FUNCTION_WRAPPER(ap_glWindowPos3d);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glWindowPos3d, 3, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, x, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, y, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, z);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glWindowPos3d, (x, y, z));

    SU_END_FUNCTION_WRAPPER(ap_glWindowPos3d);
}

void APIENTRY glWindowPos3dv(const GLdouble* v)
{
    SU_START_FUNCTION_WRAPPER(ap_glWindowPos3dv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glWindowPos3dv, 1, OS_TOBJ_ID_GL_P_DOUBLE_PARAMETER, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glWindowPos3dv, (v));

    SU_END_FUNCTION_WRAPPER(ap_glWindowPos3dv);
}

void APIENTRY glWindowPos3f(GLfloat x, GLfloat y, GLfloat z)
{
    SU_START_FUNCTION_WRAPPER(ap_glWindowPos3f);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glWindowPos3f, 3, OS_TOBJ_ID_GL_FLOAT_PARAMETER, x, OS_TOBJ_ID_GL_FLOAT_PARAMETER, y, OS_TOBJ_ID_GL_FLOAT_PARAMETER, z);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glWindowPos3f, (x, y, z));

    SU_END_FUNCTION_WRAPPER(ap_glWindowPos3f);
}

void APIENTRY glWindowPos3fv(const GLfloat* v)
{
    SU_START_FUNCTION_WRAPPER(ap_glWindowPos3fv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glWindowPos3fv, 1, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glWindowPos3fv, (v));

    SU_END_FUNCTION_WRAPPER(ap_glWindowPos3fv);
}

void APIENTRY glWindowPos3i(GLint x, GLint y, GLint z)
{
    SU_START_FUNCTION_WRAPPER(ap_glWindowPos3i);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glWindowPos3i, 3, OS_TOBJ_ID_GL_INT_PARAMETER, x, OS_TOBJ_ID_GL_INT_PARAMETER, y, OS_TOBJ_ID_GL_INT_PARAMETER, z);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glWindowPos3i, (x, y, z));

    SU_END_FUNCTION_WRAPPER(ap_glWindowPos3i);
}

void APIENTRY glWindowPos3iv(const GLint* v)
{
    SU_START_FUNCTION_WRAPPER(ap_glWindowPos3iv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glWindowPos3iv, 1, OS_TOBJ_ID_GL_P_INT_PARAMETER, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glWindowPos3iv, (v));

    SU_END_FUNCTION_WRAPPER(ap_glWindowPos3iv);
}

void APIENTRY glWindowPos3s(GLshort x, GLshort y, GLshort z)
{
    SU_START_FUNCTION_WRAPPER(ap_glWindowPos3s);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glWindowPos3s, 3, OS_TOBJ_ID_GL_SHORT_PARAMETER, x, OS_TOBJ_ID_GL_SHORT_PARAMETER, y, OS_TOBJ_ID_GL_SHORT_PARAMETER, z);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glWindowPos3s, (x, y, z));

    SU_END_FUNCTION_WRAPPER(ap_glWindowPos3s);
}

void APIENTRY glWindowPos3sv(const GLshort* v)
{
    SU_START_FUNCTION_WRAPPER(ap_glWindowPos3sv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glWindowPos3sv, 1, OS_TOBJ_ID_GL_P_SHORT_PARAMETER, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glWindowPos3sv, (v));

    SU_END_FUNCTION_WRAPPER(ap_glWindowPos3sv);
}

//////////////////////////////////////////////////////////////////////////
// OpenGL 1.5
//////////////////////////////////////////////////////////////////////////
void APIENTRY glGenQueries(GLsizei n, GLuint* ids)
{
    SU_START_FUNCTION_WRAPPER(ap_glGenQueries);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGenQueries, 2, OS_TOBJ_ID_GL_SIZEI_PARAMETER, n, OS_TOBJ_ID_GL_P_UINT_PARAMETER, ids);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGenQueries, (n, ids));

    SU_END_FUNCTION_WRAPPER(ap_glGenQueries);
}

void APIENTRY glDeleteQueries(GLsizei n, const GLuint* ids)
{
    SU_START_FUNCTION_WRAPPER(ap_glDeleteQueries);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glDeleteQueries, 2, OS_TOBJ_ID_GL_SIZEI_PARAMETER, n, OS_TOBJ_ID_GL_P_UINT_PARAMETER, ids);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glDeleteQueries, (n, ids));

    SU_END_FUNCTION_WRAPPER(ap_glDeleteQueries);
}

GLboolean APIENTRY glIsQuery(GLuint id)
{
    SU_START_FUNCTION_WRAPPER(ap_glIsQuery);

    GLboolean retVal = GL_FALSE;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glIsQuery, 1, OS_TOBJ_ID_GL_UINT_PARAMETER, id);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glIsQuery, (id), retVal);

    SU_END_FUNCTION_WRAPPER(ap_glIsQuery);

    return retVal;
}

void APIENTRY glBeginQuery(GLenum target, GLuint id)
{
    SU_START_FUNCTION_WRAPPER(ap_glBeginQuery);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glBeginQuery, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_UINT_PARAMETER, id);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glBeginQuery, (target, id));

    SU_END_FUNCTION_WRAPPER(ap_glBeginQuery);
}

void APIENTRY glEndQuery(GLenum target)
{
    SU_START_FUNCTION_WRAPPER(ap_glEndQuery);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glEndQuery, 1, OS_TOBJ_ID_GL_ENUM_PARAMETER, target);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glEndQuery, (target));

    SU_END_FUNCTION_WRAPPER(ap_glEndQuery);
}

void APIENTRY glGetQueryiv(GLenum target, GLenum pname, GLint* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetQueryiv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetQueryiv, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetQueryiv, (target, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetQueryiv);
}

void APIENTRY glGetQueryObjectiv(GLuint id, GLenum pname, GLint* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetQueryObjectiv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetQueryObjectiv, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, id, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetQueryObjectiv, (id, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetQueryObjectiv);
}

void APIENTRY glGetQueryObjectuiv(GLuint id, GLenum pname, GLuint* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetQueryObjectuiv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetQueryObjectuiv, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, id, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_UINT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetQueryObjectuiv, (id, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetQueryObjectuiv);
}

void APIENTRY glBindBuffer(GLenum target, GLuint buffer)
{
    bool inNestedFunction = su_stat_interoperabilityHelper.isInNestedFunction();
    SU_START_FUNCTION_WRAPPER(ap_glBindBuffer);

    if (!inNestedFunction)
    {
        // Log the call to this function:
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glBindBuffer, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_UINT_PARAMETER, buffer);
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glBindBuffer, (target, buffer));

    if (!inNestedFunction)
    {
        // Log the buffer binding:
        gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

        if (pCurrentThreadRenderContextMonitor != NULL)
        {
            gsVBOMonitor* vboMonitor = pCurrentThreadRenderContextMonitor->vboMonitor();
            GT_IF_WITH_ASSERT(vboMonitor != NULL)
            {
                vboMonitor->onVertexBufferObjectTargetBind(target, buffer);
            }
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glBindBuffer);
}

void APIENTRY glDeleteBuffers(GLsizei n, const GLuint* buffers)
{
    SU_START_FUNCTION_WRAPPER(ap_glDeleteBuffers);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glDeleteBuffers, 2, OS_TOBJ_ID_GL_SIZEI_PARAMETER, n, OS_TOBJ_ID_GL_P_UINT_PARAMETER, buffers);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glDeleteBuffers, (n, buffers));

    // Log the vbo deletion:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        gsVBOMonitor* vboMonitor = pCurrentThreadRenderContextMonitor->vboMonitor();
        GT_IF_WITH_ASSERT(vboMonitor != NULL)
        {
            vboMonitor->onVertexBufferObjectDeletion(n, buffers);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glDeleteBuffers);
}

void APIENTRY glGenBuffers(GLsizei n, GLuint* buffers)
{
    SU_START_FUNCTION_WRAPPER(ap_glGenBuffers);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGenBuffers, 2, OS_TOBJ_ID_GL_SIZEI_PARAMETER, n, OS_TOBJ_ID_GL_P_UINT_PARAMETER, buffers);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGenBuffers, (n, buffers));

    // Log the vbo generation:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        gsVBOMonitor* vboMonitor = pCurrentThreadRenderContextMonitor->vboMonitor();
        GT_IF_WITH_ASSERT(vboMonitor != NULL)
        {
            vboMonitor->onVertexBufferObjectGeneration(n, buffers);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glGenBuffers);
}

GLboolean APIENTRY glIsBuffer(GLuint buffer)
{
    SU_START_FUNCTION_WRAPPER(ap_glIsBuffer);

    GLboolean retVal = GL_FALSE;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glIsBuffer, 1, OS_TOBJ_ID_GL_UINT_PARAMETER, buffer);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glIsBuffer, (buffer), retVal);

    SU_END_FUNCTION_WRAPPER(ap_glIsBuffer);

    return retVal;
}

void APIENTRY glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
{
    SU_START_FUNCTION_WRAPPER(ap_glBufferData);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glBufferData, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_SIZEIPTR_PARAMETER, size, OS_TOBJ_ID_GL_P_VOID_PARAMETER, data, OS_TOBJ_ID_GL_ENUM_PARAMETER, usage);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glBufferData, (target, size, data, usage));

    // Log the vbo data set:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        gsVBOMonitor* vboMonitor = pCurrentThreadRenderContextMonitor->vboMonitor();
        GT_IF_WITH_ASSERT(vboMonitor != NULL)
        {
            vboMonitor->onVertexBufferObjectDataSet(target, size);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glBufferData);
}

void APIENTRY glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)
{
    SU_START_FUNCTION_WRAPPER(ap_glBufferSubData);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glBufferSubData, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_INTPTR_PARAMETER, offset, OS_TOBJ_ID_GL_SIZEIPTR_PARAMETER, size, OS_TOBJ_ID_GL_P_VOID_PARAMETER, data);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glBufferSubData, (target, offset, size, data));

    // Log the vbo data set:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        gsVBOMonitor* vboMonitor = pCurrentThreadRenderContextMonitor->vboMonitor();
        GT_IF_WITH_ASSERT(vboMonitor != NULL)
        {
            vboMonitor->onVertexBufferObjectSubDataSet(target);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glBufferSubData);
}

void APIENTRY glGetBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, GLvoid* data)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetBufferSubData);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetBufferSubData, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_INTPTR_PARAMETER, offset, OS_TOBJ_ID_GL_SIZEIPTR_PARAMETER, size, OS_TOBJ_ID_GL_P_VOID_PARAMETER, data);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetBufferSubData, (target, offset, size, data));

    // Log the vbo data set:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        gsVBOMonitor* vboMonitor = pCurrentThreadRenderContextMonitor->vboMonitor();
        GT_IF_WITH_ASSERT(vboMonitor != NULL)
        {
            vboMonitor->onVertexBufferObjectSubDataSet(target);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glGetBufferSubData);
}

GLvoid* APIENTRY glMapBuffer(GLenum target, GLenum access)
{
    bool inNestedFunction = su_stat_interoperabilityHelper.isInNestedFunction();
    SU_START_FUNCTION_WRAPPER(ap_glMapBuffer);

    GLvoid* retVal = NULL;

    if (!inNestedFunction)
    {
        // Log the call to this function:
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMapBuffer, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, access);
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glMapBuffer, (target, access), retVal);

    SU_END_FUNCTION_WRAPPER(ap_glMapBuffer);

    return retVal;
}

GLboolean APIENTRY glUnmapBuffer(GLenum target)
{
    bool inNestedFunction = su_stat_interoperabilityHelper.isInNestedFunction();
    SU_START_FUNCTION_WRAPPER(ap_glUnmapBuffer);

    GLboolean retVal = GL_FALSE;

    if (!inNestedFunction)
    {
        // Log the call to this function:
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glUnmapBuffer, 1, OS_TOBJ_ID_GL_ENUM_PARAMETER, target);
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glUnmapBuffer, (target), retVal);

    // TO_DO: Might want to optimize this if the mapping was GL_READ_ONLY.
    // Log the vbo data set:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        gsVBOMonitor* vboMonitor = pCurrentThreadRenderContextMonitor->vboMonitor();
        GT_IF_WITH_ASSERT(vboMonitor != NULL)
        {
            vboMonitor->onVertexBufferObjectSubDataSet(target);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glUnmapBuffer);

    return retVal;
}

void APIENTRY glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
{
    bool inNestedFunction = su_stat_interoperabilityHelper.isInNestedFunction();
    SU_START_FUNCTION_WRAPPER(ap_glGetBufferParameteriv);

    if (!inNestedFunction)
    {
        // Log the call to this function:
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetBufferParameteriv, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_PARAMETER, params);
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetBufferParameteriv, (target, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetBufferParameteriv);
}

void APIENTRY glGetBufferPointerv(GLenum target, GLenum pname, GLvoid** params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetBufferPointerv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetBufferPointerv, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_PP_VOID_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetBufferPointerv, (target, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetBufferPointerv);
}

//////////////////////////////////////////////////////////////////////////
// OpenGL 2.0
//////////////////////////////////////////////////////////////////////////
void APIENTRY glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
{
    SU_START_FUNCTION_WRAPPER(ap_glBlendEquationSeparate);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glBlendEquationSeparate, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, modeRGB, OS_TOBJ_ID_GL_ENUM_PARAMETER, modeAlpha);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glBlendEquationSeparate, (modeRGB, modeAlpha));

    SU_END_FUNCTION_WRAPPER(ap_glBlendEquationSeparate);
}

void APIENTRY glDrawBuffers(GLsizei n, const GLenum* bufs)
{
    SU_START_FUNCTION_WRAPPER(ap_glDrawBuffers);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glDrawBuffers, 2, OS_TOBJ_ID_GL_SIZEI_PARAMETER, n, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_ENUM_PARAMETER, n, bufs);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glDrawBuffers, (n, bufs));

    SU_END_FUNCTION_WRAPPER(ap_glDrawBuffers);
}

void APIENTRY glStencilOpSeparate(GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass)
{
    SU_START_FUNCTION_WRAPPER(ap_glStencilOpSeparate);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glStencilOpSeparate, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, face, OS_TOBJ_ID_GL_ENUM_PARAMETER, sfail, OS_TOBJ_ID_GL_ENUM_PARAMETER, dpfail, OS_TOBJ_ID_GL_ENUM_PARAMETER, dppass);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glStencilOpSeparate, (face, sfail, dpfail, dppass));

    SU_END_FUNCTION_WRAPPER(ap_glStencilOpSeparate);
}

void APIENTRY glStencilFuncSeparate(GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask)
{
    SU_START_FUNCTION_WRAPPER(ap_glStencilFuncSeparate);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glStencilFuncSeparate, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, frontfunc, OS_TOBJ_ID_GL_ENUM_PARAMETER, backfunc, OS_TOBJ_ID_GL_INT_PARAMETER, ref, OS_TOBJ_ID_GL_UINT_PARAMETER, mask);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glStencilFuncSeparate, (frontfunc, backfunc, ref, mask));

    SU_END_FUNCTION_WRAPPER(ap_glStencilFuncSeparate);
}

void APIENTRY glStencilMaskSeparate(GLenum face, GLuint mask)
{
    SU_START_FUNCTION_WRAPPER(ap_glStencilMaskSeparate);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glStencilMaskSeparate, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, face, OS_TOBJ_ID_GL_UINT_PARAMETER, mask);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glStencilMaskSeparate, (face, mask));

    SU_END_FUNCTION_WRAPPER(ap_glStencilMaskSeparate);
}

void APIENTRY glAttachShader(GLuint program, GLuint shader)
{
    SU_START_FUNCTION_WRAPPER(ap_glAttachShader);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glAttachShader, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_UINT_PARAMETER, shader, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program, OS_TOBJ_ID_ASSOCIATED_SHADER_NAME_PSEUDO_PARAMETER, shader);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glAttachShader, (program, shader));

    // Log the attached shader:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        gsProgramsAndShadersMonitor* progAndShaderMon = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(progAndShaderMon != NULL)
        {
            bool rc = progAndShaderMon->onShaderAttachedToProgram(program, shader);

            if (!rc)
            {
                // Generate a detected error:
                gtString errorDescription;
                apErrorCode errorCode = AP_OBJECT_NAME_DOES_NOT_EXIST_ERROR;

                if (!progAndShaderMon->isProgramObject(program))
                {
                    errorDescription = GS_STR_usingNonObjectName;
                    errorDescription.appendFormattedString(L": (program name = %u)", program);
                }
                else if (!progAndShaderMon->isShaderObject(shader))
                {
                    errorDescription = GS_STR_usingNonObjectName;
                    errorDescription.appendFormattedString(L": (shader name = %u)", shader);
                }
                else
                {
                    errorDescription.appendFormattedString(GS_STR_shaderAlreadyAttached, shader, program);
                    errorCode = AP_SHADER_ALREADY_ATTACHED_ERROR;
                }

                gs_stat_openGLMonitorInstance.reportDetectedError(errorCode, errorDescription, ap_glAttachShader);
            }
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glAttachShader);
}

void APIENTRY glBindAttribLocation(GLuint program, GLuint index, const GLchar* name)
{
    SU_START_FUNCTION_WRAPPER(ap_glBindAttribLocation);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glBindAttribLocation, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_STRING_PARAMETER, name, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glBindAttribLocation, (program, index, name));

    SU_END_FUNCTION_WRAPPER(ap_glBindAttribLocation);
}

void APIENTRY glCompileShader(GLuint shader)
{
    SU_START_FUNCTION_WRAPPER(ap_glCompileShader);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glCompileShader, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, shader, OS_TOBJ_ID_ASSOCIATED_SHADER_NAME_PSEUDO_PARAMETER, shader);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glCompileShader, (shader));

    // Log the shader compilation:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        bool wasCompilationSuccessful = true;
        gsProgramsAndShadersMonitor* progAndShaderMon = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(progAndShaderMon != NULL)
        {
            if (progAndShaderMon->isShaderObject(shader))
            {
                progAndShaderMon->onShaderCompilation(shader, wasCompilationSuccessful);
            }
            else
            {
                // Generate a detected error:
                gtString errorDescription;
                apErrorCode errorCode = AP_OBJECT_NAME_DOES_NOT_EXIST_ERROR;

                errorDescription = GS_STR_usingNonObjectName;
                errorDescription.appendFormattedString(L": (shader name = %u)", shader);

                gs_stat_openGLMonitorInstance.reportDetectedError(errorCode, errorDescription, ap_glCompileShader);
            }

            // If the compilation failed:
            if (!wasCompilationSuccessful)
            {
                // Generate a detected error:
                gtString errorDescription;
                apErrorCode errorCode = AP_SHADER_COMPILATION_FAILED_ERROR;
                errorDescription.appendFormattedString(GS_STR_shaderCompilationFailed, shader);
                gs_stat_openGLMonitorInstance.reportDetectedError(errorCode, errorDescription, ap_glCompileShader);

            }
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glCompileShader);
}

GLuint APIENTRY glCreateProgram(void)
{
    SU_START_FUNCTION_WRAPPER(ap_glCreateProgram);

    GLuint retVal = 0;

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glCreateProgram, (), retVal);

    // Log the created program:
    if (retVal != 0)
    {
        gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

        if (NULL != pCurrentThreadRenderContextMonitor)
        {
            gsProgramsAndShadersMonitor* progAndShaderMon = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
            GT_IF_WITH_ASSERT(progAndShaderMon != NULL)
            {
                progAndShaderMon->onProgramCreation(retVal, AP_GL_2_0_SHADING_OBJECT);
            }
        }
    }

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glCreateProgram, 1, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, retVal);

    SU_END_FUNCTION_WRAPPER(ap_glCreateProgram);

    return retVal;
}

GLuint APIENTRY glCreateShader(GLenum type)
{
    SU_START_FUNCTION_WRAPPER(ap_glCreateShader);

    GLuint retVal = 0;

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glCreateShader, (type), retVal);

    // Log the shader creation:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        gsProgramsAndShadersMonitor* progAndShaderMon = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(progAndShaderMon != NULL)
        {
            switch (type)
            {
                case GL_VERTEX_SHADER:
                {
                    progAndShaderMon->onVertexShaderCreation(retVal, AP_GL_2_0_SHADING_OBJECT);
                }
                break;

                case GL_FRAGMENT_SHADER:
                {
                    progAndShaderMon->onFragmentShaderCreation(retVal, AP_GL_2_0_SHADING_OBJECT);
                }
                break;

                case GL_GEOMETRY_SHADER:
                {
                    progAndShaderMon->onGeometryShaderCreation(retVal, AP_GL_2_0_SHADING_OBJECT);
                }
                break;

                case GL_TESS_CONTROL_SHADER:
                {
                    progAndShaderMon->onTessellationControlShaderCreation(retVal, AP_GL_2_0_SHADING_OBJECT);
                }
                break;

                case GL_TESS_EVALUATION_SHADER:
                {
                    progAndShaderMon->onTessellationEvaluationShaderCreation(retVal, AP_GL_2_0_SHADING_OBJECT);
                }
                break;

                case GL_COMPUTE_SHADER:
                {
                    progAndShaderMon->onComputeShaderCreation(retVal, AP_GL_2_0_SHADING_OBJECT);
                }
                break;

                default:
                {
                    // Unknown shader type:
                    GT_ASSERT(false);
                    progAndShaderMon->onUnsupportedShaderCreation(retVal, AP_GL_2_0_SHADING_OBJECT);
                }
                break;
            }
        }
    }

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glCreateShader, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_ASSOCIATED_SHADER_NAME_PSEUDO_PARAMETER, retVal);

    SU_END_FUNCTION_WRAPPER(ap_glCreateShader);

    return retVal;
}

void APIENTRY glDeleteProgram(GLuint program)
{
    SU_START_FUNCTION_WRAPPER(ap_glDeleteProgram);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glDeleteProgram, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glDeleteProgram, (program));

    // Log the program deletion:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        gsProgramsAndShadersMonitor* progAndShaderMon = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(progAndShaderMon != NULL)
        {
            bool rc = progAndShaderMon->onProgramDeletion(program);

            if (!rc)
            {
                // Generate a detected error:
                gtString errorDescription;
                apErrorCode errorCode = AP_OBJECT_NAME_DOES_NOT_EXIST_ERROR;

                errorDescription = GS_STR_usingNonObjectName;
                errorDescription.appendFormattedString(L": (program name = %u)", program);

                gs_stat_openGLMonitorInstance.reportDetectedError(errorCode, errorDescription, ap_glDeleteProgram);
            }
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glDeleteProgram);
}

void APIENTRY glDeleteShader(GLuint shader)
{
    SU_START_FUNCTION_WRAPPER(ap_glDeleteShader);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glDeleteShader, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, shader, OS_TOBJ_ID_ASSOCIATED_SHADER_NAME_PSEUDO_PARAMETER, shader);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glDeleteShader, (shader));

    // Log the shader deletion:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        gsProgramsAndShadersMonitor* progAndShaderMon = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(progAndShaderMon != NULL)
        {
            bool rc = progAndShaderMon->onShaderObjectDeletion(shader);

            if (!rc)
            {
                // Generate a detected error:
                gtString errorDescription;
                apErrorCode errorCode = AP_OBJECT_NAME_DOES_NOT_EXIST_ERROR;

                errorDescription = GS_STR_usingNonObjectName;
                errorDescription.appendFormattedString(L": (shader name = %u)", shader);

                gs_stat_openGLMonitorInstance.reportDetectedError(errorCode, errorDescription, ap_glDeleteShader);
            }
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glDeleteShader);
}

void APIENTRY glDetachShader(GLuint program, GLuint shader)
{
    SU_START_FUNCTION_WRAPPER(ap_glDetachShader);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glDetachShader, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_UINT_PARAMETER, shader, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program, OS_TOBJ_ID_ASSOCIATED_SHADER_NAME_PSEUDO_PARAMETER, shader);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    // (We do not call the real function if stub fragment shaders are forced and the detached
    //  shader is a fragment shader)
    bool shouldCallRealFunc = true;

    if (areStubFSGSForced)
    {
        if (NULL != pCurrentThreadRenderContextMonitor)
        {
            gsProgramsAndShadersMonitor* progAndShaderMon = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
            GT_IF_WITH_ASSERT(progAndShaderMon != NULL)
            {
                // Only call the function for vertex shaders and objects we do not identify:
                osTransferableObjectType shaderType = progAndShaderMon->shaderObjectType(shader);

                if ((OS_TOBJ_ID_GL_VERTEX_SHADER != shaderType) && (OS_AMOUNT_OF_TRANSFERABLE_OBJECT_TYPES != shaderType))
                {
                    shouldCallRealFunc = false;
                }
            }
        }
    }

    if (shouldCallRealFunc)
    {
        SU_CALL_EXTENSION_FUNC(glDetachShader, (program, shader));
    }

    // Log the detached shader:
    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        gsProgramsAndShadersMonitor* progAndShaderMon = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(progAndShaderMon != NULL)
        {
            bool rc = progAndShaderMon->onShaderDetachedFromProgram(program, shader);

            if (!rc)
            {
                // Generate a detected error:
                gtString errorDescription;
                apErrorCode errorCode = AP_OBJECT_NAME_DOES_NOT_EXIST_ERROR;

                if (!progAndShaderMon->isProgramObject(program))
                {
                    errorDescription = GS_STR_usingNonObjectName;
                    errorDescription.appendFormattedString(L": (program name = %u)", program);
                }
                else if (!progAndShaderMon->isShaderObject(shader))
                {
                    errorDescription = GS_STR_usingNonObjectName;
                    errorDescription.appendFormattedString(L": (shader name = %u)", shader);
                }
                else
                {
                    errorDescription.appendFormattedString(GS_STR_shaderAlreadyAttached, shader, program);
                    errorCode = AP_SHADER_ALREADY_ATTACHED_ERROR;
                }

                gs_stat_openGLMonitorInstance.reportDetectedError(errorCode, errorDescription, ap_glDetachShader);
            }
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glDetachShader);
}

void APIENTRY glDisableVertexAttribArray(GLuint index)
{
    SU_START_FUNCTION_WRAPPER(ap_glDisableVertexAttribArray);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glDisableVertexAttribArray, 1, OS_TOBJ_ID_GL_UINT_PARAMETER, index);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glDisableVertexAttribArray, (index));

    SU_END_FUNCTION_WRAPPER(ap_glDisableVertexAttribArray);
}

void APIENTRY glEnableVertexAttribArray(GLuint index)
{
    SU_START_FUNCTION_WRAPPER(ap_glEnableVertexAttribArray);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glEnableVertexAttribArray, 1, OS_TOBJ_ID_GL_UINT_PARAMETER, index);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glEnableVertexAttribArray, (index));

    SU_END_FUNCTION_WRAPPER(ap_glEnableVertexAttribArray);
}

void APIENTRY glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetActiveAttrib);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetActiveAttrib, (program, index, bufSize, length, size, type, name));

    // Log the call to this function:
    // Carefully - length can be NULL:
    if (length != NULL)
    {
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetActiveAttrib, 8, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_SIZEI_PARAMETER, bufSize, OS_TOBJ_ID_GL_SIZEI_PARAMETER, *length, OS_TOBJ_ID_GL_INT_PARAMETER, *size, OS_TOBJ_ID_GL_ENUM_PARAMETER, *type, OS_TOBJ_ID_STRING_PARAMETER, name, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);
    }
    else
    {
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetActiveAttrib, 8, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_SIZEI_PARAMETER, bufSize, OS_TOBJ_ID_GL_P_SIZEI_PARAMETER, length, OS_TOBJ_ID_GL_P_INT_PARAMETER, size, OS_TOBJ_ID_GL_ENUM_PARAMETER, *type, OS_TOBJ_ID_STRING_PARAMETER, name, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);
    }

    SU_END_FUNCTION_WRAPPER(ap_glGetActiveAttrib);
}

void APIENTRY glGetActiveUniform(GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetActiveUniform);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // If stub fragment shaders are not forced:
    if (!areStubFSGSForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glGetActiveUniform, (program, index, bufSize, length, size, type, name));
    }
    else
    {
        // Will get true iff we got the active uniform data:
        bool gotActiveUniformData = false;

        // Get the render context monitor:
        if (NULL != pCurrentThreadRenderContextMonitor)
        {
            // Get the active uniforms manager:
            const gsProgramsAndShadersMonitor* progAndShaderMon = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
            GT_IF_WITH_ASSERT(progAndShaderMon != NULL)
            {
                const gsActiveUniformsMonitor& activeUniformsMon = progAndShaderMon->programsActiveUniformsMgr();

                // Get the queried active uniform description:
                gotActiveUniformData = activeUniformsMon.getProgramActiveUniform(program, index, bufSize, length, size, type, name);
            }
        }

        if (!gotActiveUniformData)
        {
            // We cannot get the render context monitor:
            GT_ASSERT(gotActiveUniformData);

            *length = 2;
            *size = 1;
            *type = GL_INT;
            name[0] = 'N';
            name[1] = 'A';
            name[2] = 0;
        }
    }

    // Log the call to this function:
    // Carefully - length can be NULL:
    if (length != NULL)
    {
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetActiveUniform, 8, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_SIZEI_PARAMETER, bufSize, OS_TOBJ_ID_GL_SIZEI_PARAMETER, *length, OS_TOBJ_ID_GL_P_INT_PARAMETER, size, OS_TOBJ_ID_GL_ENUM_PARAMETER, *type, OS_TOBJ_ID_STRING_PARAMETER, name, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);
    }
    else
    {
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetActiveUniform, 8, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_SIZEI_PARAMETER, bufSize, OS_TOBJ_ID_GL_P_SIZEI_PARAMETER, length, OS_TOBJ_ID_GL_P_INT_PARAMETER, size, OS_TOBJ_ID_GL_ENUM_PARAMETER, *type, OS_TOBJ_ID_STRING_PARAMETER, name, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);
    }

    SU_END_FUNCTION_WRAPPER(ap_glGetActiveUniform);
}

void APIENTRY glGetAttachedShaders(GLuint program, GLsizei maxCount, GLsizei* count, GLuint* obj)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetAttachedShaders);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetAttachedShaders, (program, maxCount, count, obj));

    // Log the call to this function:
    // Carefully - count can be NULL:
    if ((count != NULL) && (*count <= GLsizei(gs_stat_maxLoggedArraySize)))
    {
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetAttachedShaders, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_SIZEI_PARAMETER, maxCount, OS_TOBJ_ID_GL_SIZEI_PARAMETER, *count, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_UINT_PARAMETER, *count, obj, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);
    }
    else
    {
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetAttachedShaders, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_SIZEI_PARAMETER, maxCount, OS_TOBJ_ID_GL_P_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_P_UINT_PARAMETER, obj, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);
    }

    SU_END_FUNCTION_WRAPPER(ap_glGetAttachedShaders);
}

GLint APIENTRY glGetAttribLocation(GLuint program, const GLchar* name)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetAttribLocation);

    GLint retVal = 0;

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glGetAttribLocation, (program, name), retVal);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetAttribLocation, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_STRING_PARAMETER, name, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);

    SU_END_FUNCTION_WRAPPER(ap_glGetAttribLocation);

    return retVal;
}

void APIENTRY glGetProgramiv(GLuint program, GLenum pname, GLint* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetProgramiv);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetProgramiv, (program, pname, params));

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetProgramiv, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_PARAMETER, params, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);

    SU_END_FUNCTION_WRAPPER(ap_glGetProgramiv);
}

void APIENTRY glGetProgramInfoLog(GLuint program, GLsizei bufSize, GLsizei* length, GLchar* infoLog)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetProgramInfoLog);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetProgramInfoLog, (program, bufSize, length, infoLog));

    // Log the call to this function:
    // Carefully - length can be NULL:
    if (length != NULL)
    {
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetProgramInfoLog, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_SIZEI_PARAMETER, bufSize, OS_TOBJ_ID_GL_SIZEI_PARAMETER, *length, OS_TOBJ_ID_STRING_PARAMETER, infoLog, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);
    }
    else
    {
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetProgramInfoLog, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_SIZEI_PARAMETER, bufSize, OS_TOBJ_ID_GL_P_SIZEI_PARAMETER, length, OS_TOBJ_ID_STRING_PARAMETER, infoLog, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);
    }

    SU_END_FUNCTION_WRAPPER(ap_glGetProgramInfoLog);
}

void APIENTRY glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetShaderiv);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetShaderiv, (shader, pname, params));

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetShaderiv, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, shader, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_PARAMETER, params, OS_TOBJ_ID_ASSOCIATED_SHADER_NAME_PSEUDO_PARAMETER, shader);

    SU_END_FUNCTION_WRAPPER(ap_glGetShaderiv);
}

void APIENTRY glGetShaderInfoLog(GLuint shader, GLsizei bufSize, GLsizei* length, GLchar* infoLog)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetShaderInfoLog);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetShaderInfoLog, (shader, bufSize, length, infoLog));

    // Log the call to this function:
    // Carefully - length can be NULL:
    if (length != NULL)
    {
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetShaderInfoLog, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, shader, OS_TOBJ_ID_GL_SIZEI_PARAMETER, bufSize, OS_TOBJ_ID_GL_SIZEI_PARAMETER, *length, OS_TOBJ_ID_STRING_PARAMETER, infoLog, OS_TOBJ_ID_ASSOCIATED_SHADER_NAME_PSEUDO_PARAMETER, shader);
    }
    else
    {
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetShaderInfoLog, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, shader, OS_TOBJ_ID_GL_SIZEI_PARAMETER, bufSize, OS_TOBJ_ID_GL_P_SIZEI_PARAMETER, length, OS_TOBJ_ID_STRING_PARAMETER, infoLog, OS_TOBJ_ID_ASSOCIATED_SHADER_NAME_PSEUDO_PARAMETER, shader);
    }

    SU_END_FUNCTION_WRAPPER(ap_glGetShaderInfoLog);
}

void APIENTRY glGetShaderSource(GLuint shader, GLsizei bufSize, GLsizei* length, GLchar* source)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetShaderSource);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetShaderSource, (shader, bufSize, length, source));

    // Log the call to this function:
    // Carefully - length can be NULL:
    if (length != NULL)
    {
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetShaderSource, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, shader, OS_TOBJ_ID_GL_SIZEI_PARAMETER, bufSize, OS_TOBJ_ID_GL_SIZEI_PARAMETER, *length, OS_TOBJ_ID_STRING_PARAMETER, source, OS_TOBJ_ID_ASSOCIATED_SHADER_NAME_PSEUDO_PARAMETER, shader);
    }
    else
    {
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetShaderSource, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, shader, OS_TOBJ_ID_GL_SIZEI_PARAMETER, bufSize, OS_TOBJ_ID_GL_P_SIZEI_PARAMETER, length, OS_TOBJ_ID_STRING_PARAMETER, source, OS_TOBJ_ID_ASSOCIATED_SHADER_NAME_PSEUDO_PARAMETER, shader);
    }

    SU_END_FUNCTION_WRAPPER(ap_glGetShaderSource);
}

GLint APIENTRY glGetUniformLocation(GLuint program, const GLchar* name)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetUniformLocation);

    GLint retVal = -1;

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // If stub fragment shaders are not forced:
    if (!areStubFSGSForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glGetUniformLocation, (program, name), retVal);
    }
    else
    {
        if (NULL != pCurrentThreadRenderContextMonitor)
        {
            // Get the active uniforms manager:
            const gsProgramsAndShadersMonitor* progAndShaderMon = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
            GT_IF_WITH_ASSERT(progAndShaderMon != NULL)
            {
                const gsActiveUniformsMonitor& activeUniformsMon = progAndShaderMon->programsActiveUniformsMgr();

                // Get the uniform location:
                retVal = activeUniformsMon.getUniformLocation(program, name);
            }
        }
    }

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetUniformLocation, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_STRING_PARAMETER, name, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);

    SU_END_FUNCTION_WRAPPER(ap_glGetUniformLocation);

    return retVal;
}

void APIENTRY glGetUniformfv(GLuint program, GLint location, GLfloat* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetUniformfv);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetUniformfv, (program, location, params));

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetUniformfv, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, params, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);

    SU_END_FUNCTION_WRAPPER(ap_glGetUniformfv);
}

void APIENTRY glGetUniformiv(GLuint program, GLint location, GLint* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetUniformiv);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetUniformiv, (program, location, params));

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetUniformiv, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_P_INT_PARAMETER, params, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);

    SU_END_FUNCTION_WRAPPER(ap_glGetUniformiv);
}

void APIENTRY glGetVertexAttribdv(GLuint index, GLenum pname, GLdouble* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetVertexAttribdv);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetVertexAttribdv, (index, pname, params));

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetVertexAttribdv, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_DOUBLE_PARAMETER, params);

    SU_END_FUNCTION_WRAPPER(ap_glGetVertexAttribdv);
}

void APIENTRY glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetVertexAttribfv);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetVertexAttribfv, (index, pname, params));

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetVertexAttribfv, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, params);

    SU_END_FUNCTION_WRAPPER(ap_glGetVertexAttribfv);
}

void APIENTRY glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetVertexAttribiv);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetVertexAttribiv, (index, pname, params));

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetVertexAttribiv, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_PARAMETER, params);

    SU_END_FUNCTION_WRAPPER(ap_glGetVertexAttribiv);
}

void APIENTRY glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetVertexAttribPointerv);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetVertexAttribPointerv, (index, pname, pointer));

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetVertexAttribPointerv, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_PP_VOID_PARAMETER, pointer);

    SU_END_FUNCTION_WRAPPER(ap_glGetVertexAttribPointerv);
}

GLboolean APIENTRY glIsProgram(GLuint program)
{
    SU_START_FUNCTION_WRAPPER(ap_glIsProgram);

    GLboolean retVal = GL_FALSE;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glIsProgram, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glIsProgram, (program), retVal);

    SU_END_FUNCTION_WRAPPER(ap_glIsProgram);

    return retVal;
}

GLboolean APIENTRY glIsShader(GLuint shader)
{
    SU_START_FUNCTION_WRAPPER(ap_glIsShader);

    GLboolean retVal = GL_FALSE;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glIsShader, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, shader, OS_TOBJ_ID_ASSOCIATED_SHADER_NAME_PSEUDO_PARAMETER, shader);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glIsShader, (shader), retVal);

    SU_END_FUNCTION_WRAPPER(ap_glIsShader);

    return retVal;
}

void APIENTRY glLinkProgram(GLuint program)
{
    SU_START_FUNCTION_WRAPPER(ap_glLinkProgram);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glLinkProgram, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glLinkProgram, (program));

    // Mark that the program was linked:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        gsProgramsAndShadersMonitor* progAndShaderMon = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(progAndShaderMon != NULL)
        {
            bool wasLinkSuccessful = false;
            bool rc = progAndShaderMon->onProgramLinked(program, wasLinkSuccessful);

            if (!rc)
            {
                // Generate a detected error:
                gtString errorDescription;
                apErrorCode errorCode = AP_OBJECT_NAME_DOES_NOT_EXIST_ERROR;

                errorDescription = GS_STR_usingNonObjectName;
                errorDescription.appendFormattedString(L": (program name = %u)", program);

                gs_stat_openGLMonitorInstance.reportDetectedError(errorCode, errorDescription, ap_glLinkProgram);
            }

            // If the link failed:
            if (!wasLinkSuccessful)
            {
                // Generate a detected error:
                gtString errorDescription;
                apErrorCode errorCode = AP_PROGRAM_LINK_FAILED_ERROR;
                errorDescription.appendFormattedString(GS_STR_programLinkFailed, program);
                gs_stat_openGLMonitorInstance.reportDetectedError(errorCode, errorDescription, ap_glLinkProgram);
            }
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glLinkProgram);
}

void APIENTRY glShaderSource(GLuint shader, GLsizei count, const GLchar* const* string, const GLint* length)
{
    SU_START_FUNCTION_WRAPPER(ap_glShaderSource);

    // Will get true iff the input shader is in "forced shader source code" mode:
    bool isShaderSourceCodeForced = false;
    bool isShaderSourceCodeStubbed = false;

    // Log the shader source code:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        gsProgramsAndShadersMonitor* progAndShaderMon = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(progAndShaderMon != NULL)
        {
            if (progAndShaderMon->isShaderObject(shader))
            {
                // Get the shader object details:
                const apGLShaderObject* pShaderObjDetails = progAndShaderMon->shaderObjectDetails(shader);
                GT_IF_WITH_ASSERT(pShaderObjDetails != NULL)
                {
                    // Check if the shader source code is forced:
                    isShaderSourceCodeForced = pShaderObjDetails->isSourceCodeForced();
                }

                if (!isShaderSourceCodeForced)
                {
                    progAndShaderMon->onShaderSourceCodeSet(shader, count, string, length);
                }

#ifdef _GR_IPHONE_BUILD

                // If this is a fragment shader and we are in the "fragment shader source stubbed" mode, we need to load the stub data instead:
                if ((pShaderObjDetails->type() == OS_TOBJ_ID_GL_FRAGMENT_SHADER) && (progAndShaderMon->areFragmentShaderSourcesStubbed()))
                {
                    progAndShaderMon->stubFragmentShaderSources(false);
                    isShaderSourceCodeStubbed = true;
                }

#endif
            }
            else
            {
                // Generate a detected error:
                gtString errorDescription;
                apErrorCode errorCode = AP_OBJECT_NAME_DOES_NOT_EXIST_ERROR;

                errorDescription = GS_STR_usingNonObjectName;
                errorDescription.appendFormattedString(L": (shader name = %u)", shader);

                gs_stat_openGLMonitorInstance.reportDetectedError(errorCode, errorDescription, ap_glShaderSource);
            }
        }
    }

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glShaderSource, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, shader, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_PP_CHAR, string, OS_TOBJ_ID_GL_P_UINT_PARAMETER, length, OS_TOBJ_ID_ASSOCIATED_SHADER_NAME_PSEUDO_PARAMETER, shader);

    if (!(isShaderSourceCodeForced || isShaderSourceCodeStubbed))
    {
        bool callRealFunction = suGetGlobalServerEnvironmentSettings().m_suDontFixCRInSourceStrings;

        if (!callRealFunction)
        {
            gtASCIIString modifiedSource;
            unsigned int* sourceLengths = new unsigned int[(count > 0) ? count : 1];

            for (GLsizei i = 0; i < count; ++i)
            {
                sourceLengths[i] = (nullptr != length) ? (unsigned int)length[i] : 0;
            }

            bool callWithModified = suHandleCRInSources((unsigned int)count, string, sourceLengths, modifiedSource);
            callRealFunction = !callWithModified;

            if (callWithModified)
            {
                // Call the real function with the modified values:
                const char* modifiedSourceAsCharArray = modifiedSource.asCharArray();
                GLint modifiedSourceLength = (GLint)modifiedSource.length();
                SU_CALL_EXTENSION_FUNC(glShaderSource, (shader, 1, &modifiedSourceAsCharArray, &modifiedSourceLength));
            }

            delete[] sourceLengths;
        }

        if (callRealFunction)
        {
            // Call the real function:
            SU_CALL_EXTENSION_FUNC(glShaderSource, (shader, count, string, length));
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glShaderSource);
}

void APIENTRY glUseProgram(GLuint program)
{
    SU_START_FUNCTION_WRAPPER(ap_glUseProgram);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glUseProgram, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glUseProgram, (program));

    // Mark that the program is used:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        bool rc = pCurrentThreadRenderContextMonitor->onProgramUsed(program);

        if (!rc)
        {
            // Generate a detected error:
            gtString errorDescription;
            apErrorCode errorCode = AP_OBJECT_NAME_DOES_NOT_EXIST_ERROR;

            errorDescription = GS_STR_usingNonObjectName;
            errorDescription.appendFormattedString(L": (program name = %u)", program);

            gs_stat_openGLMonitorInstance.reportDetectedError(errorCode, errorDescription, ap_glUseProgram);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glUseProgram);
}

void APIENTRY glUniform1f(GLint location, GLfloat v0)
{
    SU_START_FUNCTION_WRAPPER(ap_glUniform1f);

    // Log the call to this function:
    GLuint activeProgramName = gs_stat_openGLMonitorInstance.activeProgram();
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glUniform1f, 3, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_FLOAT_PARAMETER, v0, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, activeProgramName);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        SU_CALL_EXTENSION_FUNC(glUniform1f, (location, v0));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(activeProgramName, location, GL_FLOAT, (void*)(&v0));
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glUniform1f);
}

void APIENTRY glUniform2f(GLint location, GLfloat v0, GLfloat v1)
{
    SU_START_FUNCTION_WRAPPER(ap_glUniform2f);

    // Log the call to this function:
    GLuint activeProgramName = gs_stat_openGLMonitorInstance.activeProgram();
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glUniform2f, 4, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_FLOAT_PARAMETER, v0, OS_TOBJ_ID_GL_FLOAT_PARAMETER, v1, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, activeProgramName);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        SU_CALL_EXTENSION_FUNC(glUniform2f, (location, v0, v1));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            GLfloat values[2] = {v0, v1};
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(activeProgramName, location, GL_FLOAT_VEC2, (void*)values);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glUniform2f);
}

void APIENTRY glUniform3f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2)
{
    SU_START_FUNCTION_WRAPPER(ap_glUniform3f);

    // Log the call to this function:
    GLuint activeProgramName = gs_stat_openGLMonitorInstance.activeProgram();
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glUniform3f, 5, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_FLOAT_PARAMETER, v0, OS_TOBJ_ID_GL_FLOAT_PARAMETER, v1, OS_TOBJ_ID_GL_FLOAT_PARAMETER, v2, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, activeProgramName);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        SU_CALL_EXTENSION_FUNC(glUniform3f, (location, v0, v1, v2));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            GLfloat values[3] = {v0, v1, v2};
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(activeProgramName, location, GL_FLOAT_VEC3, (void*)values);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glUniform3f);
}

void APIENTRY glUniform4f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3)
{
    SU_START_FUNCTION_WRAPPER(ap_glUniform4f);

    // Log the call to this function:
    GLuint activeProgramName = gs_stat_openGLMonitorInstance.activeProgram();
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glUniform4f, 6, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_FLOAT_PARAMETER, v0, OS_TOBJ_ID_GL_FLOAT_PARAMETER, v1, OS_TOBJ_ID_GL_FLOAT_PARAMETER, v2, OS_TOBJ_ID_GL_FLOAT_PARAMETER, v3, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, activeProgramName);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        SU_CALL_EXTENSION_FUNC(glUniform4f, (location, v0, v1, v2, v3));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            GLfloat values[4] = {v0, v1, v2, v3};
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(activeProgramName, location, GL_FLOAT_VEC4, (void*)values);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glUniform4f);
}

void APIENTRY glUniform1i(GLint location, GLint v0)
{
    SU_START_FUNCTION_WRAPPER(ap_glUniform1i);

    // Log the call to this function:
    GLuint activeProgramName = gs_stat_openGLMonitorInstance.activeProgram();
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glUniform1i, 3, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_INT_PARAMETER, v0, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, activeProgramName);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        SU_CALL_EXTENSION_FUNC(glUniform1i, (location, v0));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(activeProgramName, location, GL_INT, (void*)(&v0));
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glUniform1i);
}

void APIENTRY glUniform2i(GLint location, GLint v0, GLint v1)
{
    SU_START_FUNCTION_WRAPPER(ap_glUniform2i);

    // Log the call to this function:
    GLuint activeProgramName = gs_stat_openGLMonitorInstance.activeProgram();
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glUniform2i, 4, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_INT_PARAMETER, v0, OS_TOBJ_ID_GL_INT_PARAMETER, v1, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, activeProgramName);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        SU_CALL_EXTENSION_FUNC(glUniform2i, (location, v0, v1));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            GLint values[2] = {v0, v1};
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(activeProgramName, location, GL_INT_VEC2, (void*)values);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glUniform2i);
}

void APIENTRY glUniform3i(GLint location, GLint v0, GLint v1, GLint v2)
{
    SU_START_FUNCTION_WRAPPER(ap_glUniform3i);

    // Log the call to this function:
    GLuint activeProgramName = gs_stat_openGLMonitorInstance.activeProgram();
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glUniform3i, 5, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_INT_PARAMETER, v0, OS_TOBJ_ID_GL_INT_PARAMETER, v1, OS_TOBJ_ID_GL_INT_PARAMETER, v2, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, activeProgramName);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        SU_CALL_EXTENSION_FUNC(glUniform3i, (location, v0, v1, v2));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            GLint values[3] = {v0, v1, v2};
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(activeProgramName, location, GL_INT_VEC3, (void*)values);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glUniform3i);
}

void APIENTRY glUniform4i(GLint location, GLint v0, GLint v1, GLint v2, GLint v3)
{
    SU_START_FUNCTION_WRAPPER(ap_glUniform4i);

    // Log the call to this function:
    GLuint activeProgramName = gs_stat_openGLMonitorInstance.activeProgram();
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glUniform4i, 6, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_INT_PARAMETER, v0, OS_TOBJ_ID_GL_INT_PARAMETER, v1, OS_TOBJ_ID_GL_INT_PARAMETER, v2, OS_TOBJ_ID_GL_INT_PARAMETER, v3, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, activeProgramName);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        SU_CALL_EXTENSION_FUNC(glUniform4i, (location, v0, v1, v2, v3));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            GLint values[4] = {v0, v1, v2, v3};
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(activeProgramName, location, GL_INT_VEC4, (void*)values);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glUniform4i);
}

void APIENTRY glUniform1fv(GLint location, GLsizei count, const GLfloat* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glUniform1fv);

    // Log the call to this function:
    GLuint activeProgramName = gs_stat_openGLMonitorInstance.activeProgram();
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glUniform1fv, 4, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_FLOAT_PARAMETER, 1, value, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, activeProgramName);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        SU_CALL_EXTENSION_FUNC(glUniform1fv, (location, count, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(activeProgramName, location, GL_FLOAT, (void*)value);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glUniform1fv);
}

void APIENTRY glUniform2fv(GLint location, GLsizei count, const GLfloat* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glUniform2fv);

    // Log the call to this function:
    GLuint activeProgramName = gs_stat_openGLMonitorInstance.activeProgram();
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glUniform2fv, 4, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_FLOAT_PARAMETER, 2, value, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, activeProgramName);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        SU_CALL_EXTENSION_FUNC(glUniform2fv, (location, count, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(activeProgramName, location, GL_FLOAT_VEC2, (void*)value);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glUniform2fv);
}

void APIENTRY glUniform3fv(GLint location, GLsizei count, const GLfloat* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glUniform3fv);

    // Log the call to this function:
    GLuint activeProgramName = gs_stat_openGLMonitorInstance.activeProgram();
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glUniform3fv, 4, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_FLOAT_PARAMETER, 3, value, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, activeProgramName);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        SU_CALL_EXTENSION_FUNC(glUniform3fv, (location, count, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(activeProgramName, location, GL_FLOAT_VEC3, (void*)value);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glUniform3fv);
}

void APIENTRY glUniform4fv(GLint location, GLsizei count, const GLfloat* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glUniform4fv);

    // Log the call to this function:
    GLuint activeProgramName = gs_stat_openGLMonitorInstance.activeProgram();
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glUniform4fv, 4, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_FLOAT_PARAMETER, 4, value, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, activeProgramName);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        SU_CALL_EXTENSION_FUNC(glUniform4fv, (location, count, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(activeProgramName, location, GL_FLOAT_VEC4, (void*)value);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glUniform4fv);
}

void APIENTRY glUniform1iv(GLint location, GLsizei count, const GLint* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glUniform1iv);

    // Log the call to this function:
    GLuint activeProgramName = gs_stat_openGLMonitorInstance.activeProgram();
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glUniform1iv, 4, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_INT_PARAMETER, 1, value, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, activeProgramName);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        SU_CALL_EXTENSION_FUNC(glUniform1iv, (location, count, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(activeProgramName, location, GL_INT, (void*)value);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glUniform1iv);
}

void APIENTRY glUniform2iv(GLint location, GLsizei count, const GLint* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glUniform2iv);

    // Log the call to this function:
    GLuint activeProgramName = gs_stat_openGLMonitorInstance.activeProgram();
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glUniform2iv, 4, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_INT_PARAMETER, 2, value, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, activeProgramName);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        SU_CALL_EXTENSION_FUNC(glUniform2iv, (location, count, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(activeProgramName, location, GL_INT_VEC2, (void*)value);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glUniform2iv);
}

void APIENTRY glUniform3iv(GLint location, GLsizei count, const GLint* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glUniform3iv);

    // Log the call to this function:
    GLuint activeProgramName = gs_stat_openGLMonitorInstance.activeProgram();
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glUniform3iv, 4, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_INT_PARAMETER, 3, value, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, activeProgramName);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        SU_CALL_EXTENSION_FUNC(glUniform3iv, (location, count, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(activeProgramName, location, GL_INT_VEC3, (void*)value);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glUniform3iv);
}

void APIENTRY glUniform4iv(GLint location, GLsizei count, const GLint* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glUniform4iv);

    // Log the call to this function:
    GLuint activeProgramName = gs_stat_openGLMonitorInstance.activeProgram();
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glUniform4iv, 4, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_INT_PARAMETER, 4, value, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, activeProgramName);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        SU_CALL_EXTENSION_FUNC(glUniform4iv, (location, count, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(activeProgramName, location, GL_INT_VEC4, (void*)value);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glUniform4iv);
}

void APIENTRY glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glUniformMatrix2fv);

    // Log the call to this function:
    GLuint activeProgramName = gs_stat_openGLMonitorInstance.activeProgram();
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glUniformMatrix2fv, 5, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_BOOL_PARAMETER, transpose, OS_TOBJ_ID_MATRIX_PARAMETER, OS_TOBJ_ID_GL_FLOAT_PARAMETER, 2, 2, value, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, activeProgramName);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        SU_CALL_EXTENSION_FUNC(glUniformMatrix2fv, (location, count, transpose, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(activeProgramName, location, GL_FLOAT_MAT2, (void*)value, (transpose == GL_TRUE));
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glUniformMatrix2fv);
}

void APIENTRY glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glUniformMatrix3fv);

    // Log the call to this function:
    GLuint activeProgramName = gs_stat_openGLMonitorInstance.activeProgram();
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glUniformMatrix3fv, 5, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_BOOL_PARAMETER, transpose, OS_TOBJ_ID_MATRIX_PARAMETER, OS_TOBJ_ID_GL_FLOAT_PARAMETER, 3, 3, value, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, activeProgramName);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        SU_CALL_EXTENSION_FUNC(glUniformMatrix3fv, (location, count, transpose, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(activeProgramName, location, GL_FLOAT_MAT3, (void*)value, (transpose == GL_TRUE));
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glUniformMatrix3fv);
}

void APIENTRY glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glUniformMatrix4fv);

    // Log the call to this function:
    GLuint activeProgramName = gs_stat_openGLMonitorInstance.activeProgram();
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glUniformMatrix4fv, 5, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_BOOL_PARAMETER, transpose, OS_TOBJ_ID_MATRIX_PARAMETER, OS_TOBJ_ID_GL_FLOAT_PARAMETER, 4, 4, value, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, activeProgramName);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        SU_CALL_EXTENSION_FUNC(glUniformMatrix4fv, (location, count, transpose, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(activeProgramName, location, GL_FLOAT_MAT4, (void*)value, (transpose == GL_TRUE));
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glUniformMatrix4fv);
}

void APIENTRY glValidateProgram(GLuint program)
{
    SU_START_FUNCTION_WRAPPER(ap_glValidateProgram);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glValidateProgram, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glValidateProgram, (program));

    SU_END_FUNCTION_WRAPPER(ap_glValidateProgram);
}

void APIENTRY glVertexAttrib1d(GLuint index, GLdouble x)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib1d);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib1d, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, x);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib1d, (index, x));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib1d);
}

void APIENTRY glVertexAttrib1dv(GLuint index, const GLdouble* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib1dv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib1dv, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, 1, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib1dv, (index, v));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib1dv);
}

void APIENTRY glVertexAttrib1f(GLuint index, GLfloat x)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib1f);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib1f, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_FLOAT_PARAMETER, x);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib1f, (index, x));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib1f);
}

void APIENTRY glVertexAttrib1fv(GLuint index, const GLfloat* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib1fv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib1fv, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_FLOAT_PARAMETER, 1, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib1fv, (index, v));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib1fv);
}

void APIENTRY glVertexAttrib1s(GLuint index, GLshort x)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib1s);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib1s, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_SHORT_PARAMETER, x);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib1s, (index, x));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib1s);
}

void APIENTRY glVertexAttrib1sv(GLuint index, const GLshort* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib1sv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib1sv, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_SHORT_PARAMETER, 1, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib1sv, (index, v));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib1sv);
}

void APIENTRY glVertexAttrib2d(GLuint index, GLdouble x, GLdouble y)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib2d);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib2d, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, x, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, y);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib2d, (index, x, y));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib2d);
}

void APIENTRY glVertexAttrib2dv(GLuint index, const GLdouble* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib2dv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib2dv, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, 2, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib2dv, (index, v));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib2dv);
}

void APIENTRY glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib2f);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib2f, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_FLOAT_PARAMETER, x, OS_TOBJ_ID_GL_FLOAT_PARAMETER, y);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib2f, (index, x, y));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib2f);
}

void APIENTRY glVertexAttrib2fv(GLuint index, const GLfloat* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib2fv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib2fv, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_FLOAT_PARAMETER, 2, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib2fv, (index, v));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib2fv);
}

void APIENTRY glVertexAttrib2s(GLuint index, GLshort x, GLshort y)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib2s);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib2s, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_SHORT_PARAMETER, x, OS_TOBJ_ID_GL_SHORT_PARAMETER, y);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib2s, (index, x, y));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib2s);
}

void APIENTRY glVertexAttrib2sv(GLuint index, const GLshort* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib2sv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib2sv, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_SHORT_PARAMETER, 2, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib2sv, (index, v));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib2sv);
}

void APIENTRY glVertexAttrib3d(GLuint index, GLdouble x, GLdouble y, GLdouble z)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib3d);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib3d, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, x, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, y, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, z);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib3d, (index, x, y, z));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib3d);
}

void APIENTRY glVertexAttrib3dv(GLuint index, const GLdouble* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib3dv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib3dv, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, 3, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib3dv, (index, v));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib3dv);
}

void APIENTRY glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib3f);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib3f, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_FLOAT_PARAMETER, x, OS_TOBJ_ID_GL_FLOAT_PARAMETER, y, OS_TOBJ_ID_GL_FLOAT_PARAMETER, z);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib3f, (index, x, y, z));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib3f);
}

void APIENTRY glVertexAttrib3fv(GLuint index, const GLfloat* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib3fv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib3fv, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_FLOAT_PARAMETER, 3, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib3fv, (index, v));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib3fv);
}

void APIENTRY glVertexAttrib3s(GLuint index, GLshort x, GLshort y, GLshort z)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib3s);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib3s, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_SHORT_PARAMETER, x, OS_TOBJ_ID_GL_SHORT_PARAMETER, y, OS_TOBJ_ID_GL_SHORT_PARAMETER, z);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib3s, (index, x, y, z));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib3s);
}

void APIENTRY glVertexAttrib3sv(GLuint index, const GLshort* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib3sv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib3sv, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_SHORT_PARAMETER, 3, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib3sv, (index, v));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib3sv);
}

void APIENTRY glVertexAttrib4Nbv(GLuint index, const GLbyte* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib4Nbv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib4Nbv, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_BYTE_PARAMETER, 4, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib4Nbv, (index, v));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib4Nbv);
}

void APIENTRY glVertexAttrib4Niv(GLuint index, const GLint* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib4Niv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib4Niv, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_INT_PARAMETER, 4, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib4Niv, (index, v));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib4Niv);
}

void APIENTRY glVertexAttrib4Nsv(GLuint index, const GLshort* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib4Nsv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib4Nsv, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_SHORT_PARAMETER, 4, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib4Nsv, (index, v));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib4Nsv);
}

void APIENTRY glVertexAttrib4Nub(GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib4Nub);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib4Nub, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_UBYTE_PARAMETER, x, OS_TOBJ_ID_GL_UBYTE_PARAMETER, y, OS_TOBJ_ID_GL_UBYTE_PARAMETER, z, OS_TOBJ_ID_GL_UBYTE_PARAMETER, w);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib4Nub, (index, x, y, z, w));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib4Nub);
}

void APIENTRY glVertexAttrib4Nubv(GLuint index, const GLubyte* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib4Nubv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib4Nubv, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_UBYTE_PARAMETER, 4, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib4Nubv, (index, v));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib4Nubv);
}

void APIENTRY glVertexAttrib4Nuiv(GLuint index, const GLuint* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib4Nuiv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib4Nuiv, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_UINT_PARAMETER, 4, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib4Nuiv, (index, v));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib4Nuiv);
}

void APIENTRY glVertexAttrib4Nusv(GLuint index, const GLushort* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib4Nusv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib4Nusv, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_USHORT_PARAMETER, 4, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib4Nusv, (index, v));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib4Nusv);
}

void APIENTRY glVertexAttrib4bv(GLuint index, const GLbyte* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib4bv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib4bv, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_BYTE_PARAMETER, 4, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib4bv, (index, v));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib4bv);
}

void APIENTRY glVertexAttrib4d(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib4d);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib4d, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, x, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, y, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, z, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, w);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib4d, (index, x, y, z, w));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib4d);
}

void APIENTRY glVertexAttrib4dv(GLuint index, const GLdouble* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib4dv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib4dv, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, 4, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib4dv, (index, v));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib4dv);
}

void APIENTRY glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib4f);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib4f, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_FLOAT_PARAMETER, x, OS_TOBJ_ID_GL_FLOAT_PARAMETER, y, OS_TOBJ_ID_GL_FLOAT_PARAMETER, z, OS_TOBJ_ID_GL_FLOAT_PARAMETER, w);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib4f, (index, x, y, z, w));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib4f);
}

void APIENTRY glVertexAttrib4fv(GLuint index, const GLfloat* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib4fv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib4fv, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_FLOAT_PARAMETER, 4, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib4fv, (index, v));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib4fv);
}

void APIENTRY glVertexAttrib4iv(GLuint index, const GLint* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib4iv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib4iv, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_INT_PARAMETER, 4, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib4iv, (index, v));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib4iv);
}

void APIENTRY glVertexAttrib4s(GLuint index, GLshort x, GLshort y, GLshort z, GLshort w)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib4s);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib4s, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_SHORT_PARAMETER, x, OS_TOBJ_ID_GL_SHORT_PARAMETER, y, OS_TOBJ_ID_GL_SHORT_PARAMETER, z, OS_TOBJ_ID_GL_SHORT_PARAMETER, w);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib4s, (index, x, y, z, w));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib4s);
}

void APIENTRY glVertexAttrib4sv(GLuint index, const GLshort* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib4sv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib4sv, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_SHORT_PARAMETER, 4, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib4sv, (index, v));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib4sv);
}

void APIENTRY glVertexAttrib4ubv(GLuint index, const GLubyte* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib4ubv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib4ubv, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_UBYTE_PARAMETER, 4, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib4ubv, (index, v));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib4ubv);
}

void APIENTRY glVertexAttrib4uiv(GLuint index, const GLuint* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib4uiv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib4uiv, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_UINT_PARAMETER, 4, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib4uiv, (index, v));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib4uiv);
}

void APIENTRY glVertexAttrib4usv(GLuint index, const GLushort* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib4usv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib4usv, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_USHORT_PARAMETER, 4, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib4usv, (index, v));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib4usv);
}

void APIENTRY glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* pointer)
{
    SU_START_FUNCTION_WRAPPER(ap_glVertexAttribPointer);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttribPointer, 6, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_INT_PARAMETER, size, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_BOOL_PARAMETER, normalized, OS_TOBJ_ID_GL_SIZEI_PARAMETER, stride, OS_TOBJ_ID_GL_P_VOID_PARAMETER, pointer);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttribPointer, (index, size, type, normalized, stride, pointer));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttribPointer);
}

//////////////////////////////////////////////////////////////////////////
// OpenGL 2.1
//////////////////////////////////////////////////////////////////////////
void APIENTRY glUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glUniformMatrix2x3fv);

    // Log the call to this function:
    GLuint activeProgramName = gs_stat_openGLMonitorInstance.activeProgram();
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glUniformMatrix2x3fv, 5, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_BOOL_PARAMETER, transpose, OS_TOBJ_ID_MATRIX_PARAMETER, OS_TOBJ_ID_GL_FLOAT_PARAMETER, 2, 3, value, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, activeProgramName);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        SU_CALL_EXTENSION_FUNC(glUniformMatrix2x3fv, (location, count, transpose, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(activeProgramName, location, GL_FLOAT_MAT2x3, (void*)value, (transpose == GL_TRUE));
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glUniformMatrix2x3fv);
}

void APIENTRY glUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glUniformMatrix3x2fv);

    // Log the call to this function:
    GLuint activeProgramName = gs_stat_openGLMonitorInstance.activeProgram();
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glUniformMatrix3x2fv, 5, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_BOOL_PARAMETER, transpose, OS_TOBJ_ID_MATRIX_PARAMETER, OS_TOBJ_ID_GL_FLOAT_PARAMETER, 3, 2, value, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, activeProgramName);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        SU_CALL_EXTENSION_FUNC(glUniformMatrix3x2fv, (location, count, transpose, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(activeProgramName, location, GL_FLOAT_MAT3x2, (void*)value, (transpose == GL_TRUE));
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glUniformMatrix3x2fv);
}

void APIENTRY glUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glUniformMatrix2x4fv);

    // Log the call to this function:
    GLuint activeProgramName = gs_stat_openGLMonitorInstance.activeProgram();
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glUniformMatrix2x4fv, 5, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_BOOL_PARAMETER, transpose, OS_TOBJ_ID_MATRIX_PARAMETER, OS_TOBJ_ID_GL_FLOAT_PARAMETER, 2, 4, value, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, activeProgramName);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        SU_CALL_EXTENSION_FUNC(glUniformMatrix2x4fv, (location, count, transpose, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(activeProgramName, location, GL_FLOAT_MAT2x4, (void*)value, (transpose == GL_TRUE));
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glUniformMatrix2x4fv);
}

void APIENTRY glUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glUniformMatrix4x2fv);

    // Log the call to this function:
    GLuint activeProgramName = gs_stat_openGLMonitorInstance.activeProgram();
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glUniformMatrix4x2fv, 5, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_BOOL_PARAMETER, transpose, OS_TOBJ_ID_MATRIX_PARAMETER, OS_TOBJ_ID_GL_FLOAT_PARAMETER, 4, 2, value, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, activeProgramName);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        SU_CALL_EXTENSION_FUNC(glUniformMatrix4x2fv, (location, count, transpose, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(activeProgramName, location, GL_FLOAT_MAT4x2, (void*)value, (transpose == GL_TRUE));
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glUniformMatrix4x2fv);
}

void APIENTRY glUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glUniformMatrix3x4fv);

    // Log the call to this function:
    GLuint activeProgramName = gs_stat_openGLMonitorInstance.activeProgram();
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glUniformMatrix3x4fv, 5, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_BOOL_PARAMETER, transpose, OS_TOBJ_ID_MATRIX_PARAMETER, OS_TOBJ_ID_GL_FLOAT_PARAMETER, 3, 4, value, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, activeProgramName);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        SU_CALL_EXTENSION_FUNC(glUniformMatrix3x4fv, (location, count, transpose, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(activeProgramName, location, GL_FLOAT_MAT3x4, (void*)value, (transpose == GL_TRUE));
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glUniformMatrix3x4fv);
}

void APIENTRY glUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glUniformMatrix4x3fv);

    // Log the call to this function:
    GLuint activeProgramName = gs_stat_openGLMonitorInstance.activeProgram();
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glUniformMatrix4x3fv, 5, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_BOOL_PARAMETER, transpose, OS_TOBJ_ID_MATRIX_PARAMETER, OS_TOBJ_ID_GL_FLOAT_PARAMETER, 4, 3, value, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, activeProgramName);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        SU_CALL_EXTENSION_FUNC(glUniformMatrix4x3fv, (location, count, transpose, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(activeProgramName, location, GL_FLOAT_MAT4x3, (void*)value, (transpose == GL_TRUE));
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glUniformMatrix4x3fv);
}

//////////////////////////////////////////////////////////////////////////
// OpenGL 3.0
//////////////////////////////////////////////////////////////////////////
void APIENTRY glColorMaski(GLuint buf, GLboolean r, GLboolean g, GLboolean b, GLboolean a)
{
    SU_START_FUNCTION_WRAPPER(ap_glColorMaski);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glColorMaski, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, buf, OS_TOBJ_ID_GL_BOOL_PARAMETER, r, OS_TOBJ_ID_GL_BOOL_PARAMETER, g, OS_TOBJ_ID_GL_BOOL_PARAMETER, b, OS_TOBJ_ID_GL_BOOL_PARAMETER, a);

    SU_CALL_EXTENSION_FUNC(glColorMaski, (buf, r, g, b, a));

    SU_END_FUNCTION_WRAPPER(ap_glColorMaski);
}

void APIENTRY glGetBooleani_v(GLenum target, GLuint index, GLboolean* data)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetBooleani_v);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetBooleani_v, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_P_BOOL_PARAMETER, data);

    SU_CALL_EXTENSION_FUNC(glGetBooleani_v, (target, index, data));

    SU_END_FUNCTION_WRAPPER(ap_glGetBooleani_v);
}

void APIENTRY glGetIntegeri_v(GLenum target, GLuint index, GLint* data)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetIntegeri_v);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetIntegeri_v, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_P_UINT_PARAMETER, data);

    SU_CALL_EXTENSION_FUNC(glGetIntegeri_v, (target, index, data));

    SU_END_FUNCTION_WRAPPER(ap_glGetIntegeri_v);
}

void APIENTRY glEnablei(GLenum target, GLuint index)
{
    SU_START_FUNCTION_WRAPPER(ap_glEnablei);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glEnablei, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_UINT_PARAMETER, index);

    SU_CALL_EXTENSION_FUNC(glEnablei, (target, index));

    SU_END_FUNCTION_WRAPPER(ap_glEnablei);
}

void APIENTRY glDisablei(GLenum target, GLuint index)
{
    SU_START_FUNCTION_WRAPPER(ap_glDisablei);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glDisablei, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_UINT_PARAMETER, index);

    SU_CALL_EXTENSION_FUNC(glDisablei, (target, index));

    SU_END_FUNCTION_WRAPPER(ap_glDisablei);
}

GLboolean APIENTRY glIsEnabledi(GLenum target, GLuint index)
{
    SU_START_FUNCTION_WRAPPER(ap_glIsEnabledi);

    GLboolean retVal = GL_FALSE;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glIsEnabledi, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_UINT_PARAMETER, index);

    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glIsEnabledi, (target, index), retVal);

    SU_END_FUNCTION_WRAPPER(ap_glIsEnabledi);

    return retVal;
}

void APIENTRY glBeginTransformFeedback(GLenum primitiveMode)
{
    SU_START_FUNCTION_WRAPPER(ap_glBeginTransformFeedback);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glBeginTransformFeedback, 1, OS_TOBJ_ID_GL_ENUM_PARAMETER, primitiveMode);

    SU_CALL_EXTENSION_FUNC(glBeginTransformFeedback, (primitiveMode));

    SU_END_FUNCTION_WRAPPER(ap_glBeginTransformFeedback);
}

void APIENTRY glEndTransformFeedback(void)
{
    SU_START_FUNCTION_WRAPPER(ap_glEndTransformFeedback);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glEndTransformFeedback, 0);

    SU_CALL_EXTENSION_FUNC(glEndTransformFeedback, ());

    SU_END_FUNCTION_WRAPPER(ap_glEndTransformFeedback);
}

void APIENTRY glBindBufferRange(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size)
{
    SU_START_FUNCTION_WRAPPER(ap_glBindBufferRange);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glBindBufferRange, 5, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_UINT_PARAMETER, buffer, OS_TOBJ_ID_GL_INTPTR_PARAMETER, offset, OS_TOBJ_ID_GL_SIZEIPTR_PARAMETER, size);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glBindBufferRange, (target, index, buffer, offset, size));

    // TO_DO: OpenGL3.2
    // Check glBindBufferRangeEXT and glBindBufferRangeNV - see if it needs to be supported.
    // Check if stub fragment shaders are forced - is neccessary?

    // Get the render context monitor:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        // TO_DO: support information for indexed VBO targets:
        gsVBOMonitor* vboMonitor = pCurrentThreadRenderContextMonitor->vboMonitor();
        GT_IF_WITH_ASSERT(vboMonitor != NULL)
        {
            vboMonitor->onVertexBufferObjectTargetBind(target, buffer);
        }

        // If this is a uniform buffer:
        if ((target == GL_UNIFORM_BUFFER) || (target == GL_UNIFORM_BUFFER_EXT))
        {
            // Get the active program name:
            GLuint activeProgram = gs_stat_openGLMonitorInstance.activeProgram();

            // Get the active uniforms manager:
            gsProgramsAndShadersMonitor* pProgramAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
            GT_IF_WITH_ASSERT(pProgramAndShadersMonitor != NULL)
            {
                // Get the active uniforms monitor"
                gsActiveUniformsMonitor& activeUniformsMon = pProgramAndShadersMonitor->programsActiveUniformsMgr();

                // Set uniform buffer object bind buffer:
                activeUniformsMon.onUBOBindBuffer(activeProgram, target, index, buffer);
            }
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glBindBufferRange);
}

void APIENTRY glBindBufferBase(GLenum target, GLuint index, GLuint buffer)
{
    SU_START_FUNCTION_WRAPPER(ap_glBindBufferBase);

    // TO_DO: OpenGL3.2 - Check glBindBufferEXT and glBindBufferNV - see if it needs to be supported.

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glBindBufferBase, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_UINT_PARAMETER, buffer);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glBindBufferBase, (target, index, buffer));

    // Check if stub fragment shaders are forced:
    // TO_DO: OpenGL3.2 should stub fragment shader be forced for UBOs?
    // bool areStubFSGSForced = false; - is neccessary?
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (nullptr != pCurrentThreadRenderContextMonitor)
    {
        // TO_DO: support information for indexed VBO targets:
        gsVBOMonitor* vboMonitor = pCurrentThreadRenderContextMonitor->vboMonitor();
        GT_IF_WITH_ASSERT(vboMonitor != NULL)
        {
            vboMonitor->onVertexBufferObjectTargetBind(target, buffer);
        }

        // If this is a uniform buffer:
        if ((target == GL_UNIFORM_BUFFER) || (target == GL_UNIFORM_BUFFER_EXT))
        {
            // Get the active program name:
            GLuint activeProgram = gs_stat_openGLMonitorInstance.activeProgram();

            // Get the active uniforms manager:
            gsProgramsAndShadersMonitor* pProgramAndShaderMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
            GT_IF_WITH_ASSERT(pProgramAndShaderMonitor != NULL)
            {
                // Get the active uniforms monitor:
                gsActiveUniformsMonitor& activeUniformsMonitor = pProgramAndShaderMonitor->programsActiveUniformsMgr();

                // Set uniform buffer object bind buffer:
                activeUniformsMonitor.onUBOBindBuffer(activeProgram, target, index, buffer);
            }
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glBindBufferBase);
}

void APIENTRY glTransformFeedbackVaryings(GLuint program, GLsizei count, const GLchar* const* varyings, GLenum bufferMode)
{
    SU_START_FUNCTION_WRAPPER(ap_glTransformFeedbackVaryings);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTransformFeedbackVaryings, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_PP_CHAR, varyings, OS_TOBJ_ID_GL_ENUM_PARAMETER, bufferMode);

    SU_CALL_EXTENSION_FUNC(glTransformFeedbackVaryings, (program, count, varyings, bufferMode));

    SU_END_FUNCTION_WRAPPER(ap_glTransformFeedbackVaryings);
}

void APIENTRY glGetTransformFeedbackVarying(GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLsizei* size, GLenum* type, GLchar* name)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetTransformFeedbackVarying);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetTransformFeedbackVarying, 7, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_SIZEI_PARAMETER, bufSize, OS_TOBJ_ID_GL_P_SIZEI_PARAMETER, length, OS_TOBJ_ID_GL_P_SIZEI_PARAMETER, size, OS_TOBJ_ID_GL_P_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_P_CHAR, name);

    SU_CALL_EXTENSION_FUNC(glGetTransformFeedbackVarying, (program, index, bufSize, length, size, type, name));

    SU_END_FUNCTION_WRAPPER(ap_glGetTransformFeedbackVarying);
}

void APIENTRY glClampColor(GLenum target, GLenum clamp)
{
    SU_START_FUNCTION_WRAPPER(ap_glClampColor);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glClampColor, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, clamp);

    SU_CALL_EXTENSION_FUNC(glClampColor, (target, clamp));

    SU_END_FUNCTION_WRAPPER(ap_glClampColor);
}
void APIENTRY glBeginConditionalRender(GLuint id, GLenum mode)
{
    SU_START_FUNCTION_WRAPPER(ap_glBeginConditionalRender);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glBeginConditionalRender, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, id, OS_TOBJ_ID_GL_ENUM_PARAMETER, mode);

    SU_CALL_EXTENSION_FUNC(glBeginConditionalRender, (id, mode));

    SU_END_FUNCTION_WRAPPER(ap_glBeginConditionalRender);
}

void APIENTRY glEndConditionalRender()
{
    SU_START_FUNCTION_WRAPPER(ap_glEndConditionalRender);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glEndConditionalRender, 0);

    SU_CALL_EXTENSION_FUNC(glEndConditionalRender, ());

    SU_END_FUNCTION_WRAPPER(ap_glEndConditionalRender);
}

void APIENTRY glVertexAttribI1i(GLuint index, GLint values)
{
    SU_START_FUNCTION_WRAPPER(ap_glVertexAttribI1i);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttribI1i, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_INT_PARAMETER, values);

    SU_CALL_EXTENSION_FUNC(glVertexAttribI1i, (index, values));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttribI1i);
}

void APIENTRY glVertexAttribI2i(GLuint index, GLint val1, GLint val2)
{
    SU_START_FUNCTION_WRAPPER(ap_glVertexAttribI2i);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttribI2i, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_INT_PARAMETER, val1, OS_TOBJ_ID_GL_INT_PARAMETER, val2);

    SU_CALL_EXTENSION_FUNC(glVertexAttribI2i, (index, val1, val2));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttribI2i);
}

void APIENTRY glVertexAttribI3i(GLuint index, GLint val1, GLint val2, GLint val3)
{
    SU_START_FUNCTION_WRAPPER(ap_glVertexAttribI3i);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttribI3i, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_INT_PARAMETER, val1, OS_TOBJ_ID_GL_INT_PARAMETER, val2, OS_TOBJ_ID_GL_INT_PARAMETER, val3);

    SU_CALL_EXTENSION_FUNC(glVertexAttribI3i, (index, val1, val2, val3));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttribI3i);
}

void APIENTRY glVertexAttribI4i(GLuint index, GLint val1, GLint val2, GLint val3, GLint val4)
{
    SU_START_FUNCTION_WRAPPER(ap_glVertexAttribI4i);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttribI4i, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_INT_PARAMETER, val1, OS_TOBJ_ID_GL_INT_PARAMETER, val2, OS_TOBJ_ID_GL_INT_PARAMETER, val3, OS_TOBJ_ID_GL_INT_PARAMETER, val4);

    SU_CALL_EXTENSION_FUNC(glVertexAttribI4i, (index, val1, val2, val3, val4));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttribI4i);
}

void APIENTRY glVertexAttribI1ui(GLuint index, GLuint values)
{
    SU_START_FUNCTION_WRAPPER(ap_glVertexAttribI1ui);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttribI1ui, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_UINT_PARAMETER, values);

    SU_CALL_EXTENSION_FUNC(glVertexAttribI1ui, (index, values));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttribI1ui);
}

void APIENTRY glVertexAttribI2ui(GLuint index, GLuint val1, GLuint val2)
{
    SU_START_FUNCTION_WRAPPER(ap_glVertexAttribI2ui);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttribI2ui, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_UINT_PARAMETER, val1, OS_TOBJ_ID_GL_UINT_PARAMETER, val2);

    SU_CALL_EXTENSION_FUNC(glVertexAttribI2ui, (index, val1, val2));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttribI2ui);
}

void APIENTRY glVertexAttribI3ui(GLuint index, GLuint val1, GLuint val2, GLuint val3)
{
    SU_START_FUNCTION_WRAPPER(ap_glVertexAttribI3ui);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttribI3ui, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_UINT_PARAMETER, val1, OS_TOBJ_ID_GL_UINT_PARAMETER, val2, OS_TOBJ_ID_GL_UINT_PARAMETER, val3);

    SU_CALL_EXTENSION_FUNC(glVertexAttribI3ui, (index, val1, val2, val3));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttribI3ui);
}

void APIENTRY glVertexAttribI4ui(GLuint index, GLuint val1, GLuint val2, GLuint val3, GLuint val4)
{
    SU_START_FUNCTION_WRAPPER(ap_glVertexAttribI4ui);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttribI4i, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_UINT_PARAMETER, val1, OS_TOBJ_ID_GL_UINT_PARAMETER, val2, OS_TOBJ_ID_GL_UINT_PARAMETER, val3, OS_TOBJ_ID_GL_UINT_PARAMETER, val4);

    SU_CALL_EXTENSION_FUNC(glVertexAttribI4ui, (index, val1, val2, val3, val4));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttribI4ui);
}

void APIENTRY glVertexAttribI1iv(GLuint index, const GLint* values)
{
    SU_START_FUNCTION_WRAPPER(ap_glVertexAttribI1iv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttribI1iv, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_P_INT_PARAMETER, values);

    SU_CALL_EXTENSION_FUNC(glVertexAttribI1iv, (index, values));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttribI1iv);
}

void APIENTRY glVertexAttribI2iv(GLuint index, const GLint* values)
{
    SU_START_FUNCTION_WRAPPER(ap_glVertexAttribI2iv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttribI2iv, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_P_INT_PARAMETER, values);

    SU_CALL_EXTENSION_FUNC(glVertexAttribI2iv, (index, values));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttribI2iv);
}

void APIENTRY glVertexAttribI3iv(GLuint index, const GLint* values)
{
    SU_START_FUNCTION_WRAPPER(ap_glVertexAttribI3iv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttribI3iv, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_P_INT_PARAMETER, values);

    SU_CALL_EXTENSION_FUNC(glVertexAttribI3iv, (index, values));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttribI3iv);
}

void APIENTRY glVertexAttribI4iv(GLuint index, const GLint* values)
{
    SU_START_FUNCTION_WRAPPER(ap_glVertexAttribI4iv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttribI4iv, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_P_INT_PARAMETER, values);

    SU_CALL_EXTENSION_FUNC(glVertexAttribI4iv, (index, values));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttribI4iv);
}

void APIENTRY glVertexAttribI1uiv(GLuint index, const GLuint* values)
{
    SU_START_FUNCTION_WRAPPER(ap_glVertexAttribI1uiv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttribI1uiv, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_P_UINT_PARAMETER, values);

    SU_CALL_EXTENSION_FUNC(glVertexAttribI1uiv, (index, values));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttribI1uiv);
}

void APIENTRY glVertexAttribI2uiv(GLuint index, const GLuint* values)
{
    SU_START_FUNCTION_WRAPPER(ap_glVertexAttribI2uiv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttribI2uiv, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_P_UINT_PARAMETER, values);

    SU_CALL_EXTENSION_FUNC(glVertexAttribI2uiv, (index, values));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttribI2uiv);
}

void APIENTRY glVertexAttribI3uiv(GLuint index, const GLuint* values)
{
    SU_START_FUNCTION_WRAPPER(ap_glVertexAttribI3uiv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttribI3uiv, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_P_UINT_PARAMETER, values);

    SU_CALL_EXTENSION_FUNC(glVertexAttribI3uiv, (index, values));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttribI3uiv);
}

void APIENTRY glVertexAttribI4uiv(GLuint index, const GLuint* values)
{
    SU_START_FUNCTION_WRAPPER(ap_glVertexAttribI4uiv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttribI4uiv, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_P_UINT_PARAMETER, values);

    SU_CALL_EXTENSION_FUNC(glVertexAttribI4uiv, (index, values));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttribI4uiv);
}

void APIENTRY glVertexAttribI4bv(GLuint index, const GLbyte* values)
{
    SU_START_FUNCTION_WRAPPER(ap_glVertexAttribI4bv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttribI4bv, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_P_BYTE_PARAMETER, values);

    SU_CALL_EXTENSION_FUNC(glVertexAttribI4bv, (index, values));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttribI4bv);
}

void APIENTRY glVertexAttribI4sv(GLuint index, const GLshort* values)
{
    SU_START_FUNCTION_WRAPPER(ap_glVertexAttribI4sv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttribI4sv, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_P_SHORT_PARAMETER, values);

    SU_CALL_EXTENSION_FUNC(glVertexAttribI4sv, (index, values));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttribI4sv);
}

void APIENTRY glVertexAttribI4ubv(GLuint index, const GLubyte* values)
{
    SU_START_FUNCTION_WRAPPER(ap_glVertexAttribI4ubv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttribI4ubv, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_P_UBYTE_PARAMETER, values);

    SU_CALL_EXTENSION_FUNC(glVertexAttribI4ubv, (index, values));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttribI4ubv);
}

void APIENTRY glVertexAttribI4usv(GLuint index, const GLushort* values)
{
    SU_START_FUNCTION_WRAPPER(ap_glVertexAttribI4usv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttribI4usv, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_P_USHORT_PARAMETER, values);

    SU_CALL_EXTENSION_FUNC(glVertexAttribI4usv, (index, values));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttribI4usv);
}

void APIENTRY glVertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid* pointer)
{
    SU_START_FUNCTION_WRAPPER(ap_glVertexAttribIPointer);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttribIPointer, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_INT_PARAMETER, size, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_SIZEI_PARAMETER, stride, OS_TOBJ_ID_GL_P_VOID_PARAMETER, pointer);

    SU_CALL_EXTENSION_FUNC(glVertexAttribIPointer, (index, size, type, stride, pointer));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttribIPointer);
}

void APIENTRY glGetVertexAttribIiv(GLuint index, GLenum pname, GLint* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetVertexAttribIiv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetVertexAttribIiv, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_PARAMETER, params);

    SU_CALL_EXTENSION_FUNC(glGetVertexAttribIiv, (index, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetVertexAttribIiv);
}

void APIENTRY glGetVertexAttribIuiv(GLuint index, GLenum pname, GLuint* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetVertexAttribIuiv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetVertexAttribIuiv, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_UINT_PARAMETER, params);

    SU_CALL_EXTENSION_FUNC(glGetVertexAttribIuiv, (index, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetVertexAttribIuiv);
}

void APIENTRY glGetUniformuiv(GLuint program, GLint location, GLuint* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetUniformuiv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetUniformuiv, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_P_UINT_PARAMETER, params);

    SU_CALL_EXTENSION_FUNC(glGetUniformuiv, (program, location, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetUniformuiv);
}

void APIENTRY glBindFragDataLocation(GLuint program, GLuint colorNumber, const GLchar* name)
{
    SU_START_FUNCTION_WRAPPER(ap_glBindFragDataLocation);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glBindFragDataLocation, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_UINT_PARAMETER, colorNumber, OS_TOBJ_ID_GL_P_CHAR, name);

    SU_CALL_EXTENSION_FUNC(glBindFragDataLocation, (program, colorNumber, name));

    SU_END_FUNCTION_WRAPPER(ap_glBindFragDataLocation);
}

GLint APIENTRY glGetFragDataLocation(GLuint program, const GLchar* name)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetFragDataLocation);

    GLint retVal = 0;
    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetFragDataLocation, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_P_CHAR, name);

    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glGetFragDataLocation, (program, name), retVal);

    SU_END_FUNCTION_WRAPPER(ap_glGetFragDataLocation);

    return retVal;
}

void APIENTRY glUniform1ui(GLint location, GLuint v0)
{
    SU_START_FUNCTION_WRAPPER(ap_glUniform1ui);

    // Log the call to this function:
    GLuint activeProgramName = gs_stat_openGLMonitorInstance.activeProgram();
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glUniform1ui, 3, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_UINT_PARAMETER, v0, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, activeProgramName);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        SU_CALL_EXTENSION_FUNC(glUniform1ui, (location, v0));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(activeProgramName, location, GL_UNSIGNED_INT, (void*)(&v0));
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glUniform1ui);
}

void APIENTRY glUniform2ui(GLint location, GLuint v0, GLuint v1)
{
    SU_START_FUNCTION_WRAPPER(ap_glUniform2ui);

    // Log the call to this function:
    GLuint activeProgramName = gs_stat_openGLMonitorInstance.activeProgram();
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glUniform2ui, 4, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_UINT_PARAMETER, v0, OS_TOBJ_ID_GL_UINT_PARAMETER, v1, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, activeProgramName);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        SU_CALL_EXTENSION_FUNC(glUniform2ui, (location, v0, v1));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            GLuint values[2] = {v0, v1};
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(activeProgramName, location, GL_UNSIGNED_INT_VEC2, (void*)values);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glUniform2ui);
}

void APIENTRY glUniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2)
{
    SU_START_FUNCTION_WRAPPER(ap_glUniform3ui);

    // Log the call to this function:
    GLuint activeProgramName = gs_stat_openGLMonitorInstance.activeProgram();
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glUniform3ui, 5, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_UINT_PARAMETER, v0, OS_TOBJ_ID_GL_UINT_PARAMETER, v1, OS_TOBJ_ID_GL_UINT_PARAMETER, v2, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, activeProgramName);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        SU_CALL_EXTENSION_FUNC(glUniform3ui, (location, v0, v1, v2));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            GLuint values[3] = {v0, v1, v2};
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(activeProgramName, location, GL_UNSIGNED_INT_VEC3, (void*)values);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glUniform3ui);
}

void APIENTRY glUniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3)
{
    SU_START_FUNCTION_WRAPPER(ap_glUniform4ui);

    // Log the call to this function:
    GLuint activeProgramName = gs_stat_openGLMonitorInstance.activeProgram();
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glUniform4ui, 6, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_UINT_PARAMETER, v0, OS_TOBJ_ID_GL_UINT_PARAMETER, v1, OS_TOBJ_ID_GL_UINT_PARAMETER, v2, OS_TOBJ_ID_GL_UINT_PARAMETER, v3, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, activeProgramName);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        SU_CALL_EXTENSION_FUNC(glUniform4ui, (location, v0, v1, v2, v3));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            GLuint values[4] = {v0, v1, v2, v3};
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(activeProgramName, location, GL_UNSIGNED_INT_VEC4, (void*)values);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glUniform4ui);
}

void APIENTRY glUniform1uiv(GLint location, GLsizei size, const GLuint* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glUniform1uiv);

    // Log the call to this function:
    GLuint activeProgramName = gs_stat_openGLMonitorInstance.activeProgram();
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glUniform1uiv, 4, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, size, OS_TOBJ_ID_GL_P_UINT_PARAMETER, value, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, activeProgramName);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        SU_CALL_EXTENSION_FUNC(glUniform1uiv, (location, size, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(activeProgramName, location, GL_UNSIGNED_INT, (void*)value);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glUniform1uiv);
}

void APIENTRY glUniform2uiv(GLint location, GLsizei size, const GLuint* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glUniform2uiv);

    // Log the call to this function:
    GLuint activeProgramName = gs_stat_openGLMonitorInstance.activeProgram();
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glUniform2uiv, 4, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, size, OS_TOBJ_ID_GL_P_UINT_PARAMETER, value, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, activeProgramName);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        SU_CALL_EXTENSION_FUNC(glUniform2uiv, (location, size, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(activeProgramName, location, GL_UNSIGNED_INT_VEC2, (void*)value);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glUniform2uiv);
}

void APIENTRY glUniform3uiv(GLint location, GLsizei size, const GLuint* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glUniform3uiv);

    // Log the call to this function:
    GLuint activeProgramName = gs_stat_openGLMonitorInstance.activeProgram();
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glUniform3uiv, 4, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, size, OS_TOBJ_ID_GL_P_UINT_PARAMETER, value, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, activeProgramName);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        SU_CALL_EXTENSION_FUNC(glUniform3uiv, (location, size, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(activeProgramName, location, GL_UNSIGNED_INT_VEC3, (void*)value);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glUniform3uiv);
}

void APIENTRY glUniform4uiv(GLint location, GLsizei size, const GLuint* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glUniform4uiv);

    // Log the call to this function:
    GLuint activeProgramName = gs_stat_openGLMonitorInstance.activeProgram();
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glUniform4uiv, 4, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, size, OS_TOBJ_ID_GL_P_UINT_PARAMETER, value, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, activeProgramName);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        SU_CALL_EXTENSION_FUNC(glUniform4uiv, (location, size, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(activeProgramName, location, GL_UNSIGNED_INT_VEC4, (void*)value);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glUniform4uiv);
}

void APIENTRY glTexParameterIiv(GLenum target, GLenum pname, const GLint* data)
{
    SU_START_FUNCTION_WRAPPER(ap_glTexParameterIiv);

    // Get the input bind target bounded texture name:
    GLuint boundTextureName = gs_stat_openGLMonitorInstance.boundTexture(target);

    // Log the call to this function:
    if ((pname == GL_TEXTURE_MIN_FILTER) || (pname == GL_TEXTURE_MAG_FILTER) ||
        (pname == GL_TEXTURE_COMPARE_MODE) || (pname == GL_TEXTURE_COMPARE_FUNC) || (pname == GL_DEPTH_TEXTURE_MODE) ||
        (pname == GL_TEXTURE_WRAP_S) || (pname == GL_TEXTURE_WRAP_T) || (pname == GL_TEXTURE_WRAP_R))
    {
        GLenum paramAsEnum = (GLenum) * data;
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTexParameterIiv, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_ENUM_PARAMETER, paramAsEnum, OS_TOBJ_ID_ASSOCIATED_TEXTURE_NAMES_PSEUDO_PARAMETER, 1, &boundTextureName);
    }
    else if ((pname == GL_TEXTURE_BORDER_COLOR) || (pname == GL_TEXTURE_CROP_RECT_OES))
    {
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTexParameterIiv, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_UINT_PARAMETER, 4, data, OS_TOBJ_ID_ASSOCIATED_TEXTURE_NAMES_PSEUDO_PARAMETER, 1, &boundTextureName);
    }
    else if (pname == GL_TEXTURE_PRIORITY)
    {
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTexParameterIiv, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_INT_PARAMETER, *data, OS_TOBJ_ID_ASSOCIATED_TEXTURE_NAMES_PSEUDO_PARAMETER, 1, &boundTextureName);
    }
    else
    {
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTexParameterIiv, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_PARAMETER, data, OS_TOBJ_ID_ASSOCIATED_TEXTURE_NAMES_PSEUDO_PARAMETER, 1, &boundTextureName);
    }

    // Check if stub textures are forced:
    bool areStubTexForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubTexForced = pCurrentThreadRenderContextMonitor->forcedModesManager().isStubForced(AP_OPENGL_FORCED_STUB_TEXTURES_MODE);
    }

    // If we are not in "Force stub textures" mode:
    if (!areStubTexForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glTexParameterIiv, (target, pname, data));
    }

    // Log the new parameter value:
    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        gsTexturesMonitor* texturesMon = pCurrentThreadRenderContextMonitor->texturesMonitor();
        GT_IF_WITH_ASSERT(texturesMon != NULL)
        {
            bool rcTexParamf = pCurrentThreadRenderContextMonitor->onTextureIntParameterChanged(target, pname, data);
            GT_ASSERT(rcTexParamf);
        }

        // Log the mipmap auto generation:
        if ((pname == GL_GENERATE_MIPMAP) || (pname == GL_TEXTURE_BASE_LEVEL) || (pname == GL_TEXTURE_MAX_LEVEL))
        {
            // Get the param value:
            GLint value = *data;
            bool rcMipmapGeneration = pCurrentThreadRenderContextMonitor->onMipmapGenerateParamSet(target, pname, (GLfloat)value);
            GT_ASSERT(rcMipmapGeneration);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glTexParameterIiv);
}

void APIENTRY glTexParameterIuiv(GLenum target, GLenum pname, const GLuint* data)
{
    SU_START_FUNCTION_WRAPPER(ap_glTexParameterIuiv);

    // Get the input bind target bounded texture name:
    GLuint boundTextureName = gs_stat_openGLMonitorInstance.boundTexture(target);

    // Log the call to this function:

    if ((pname == GL_TEXTURE_MIN_FILTER) || (pname == GL_TEXTURE_MAG_FILTER) ||
        (pname == GL_TEXTURE_COMPARE_MODE) || (pname == GL_TEXTURE_COMPARE_FUNC) || (pname == GL_DEPTH_TEXTURE_MODE) ||
        (pname == GL_TEXTURE_WRAP_S) || (pname == GL_TEXTURE_WRAP_T) || (pname == GL_TEXTURE_WRAP_R))
    {
        GLenum paramAsEnum = (GLenum) * data;
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTexParameterIuiv, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_ENUM_PARAMETER, paramAsEnum, OS_TOBJ_ID_ASSOCIATED_TEXTURE_NAMES_PSEUDO_PARAMETER, 1, &boundTextureName);
    }
    else if ((pname == GL_TEXTURE_BORDER_COLOR) || (pname == GL_TEXTURE_CROP_RECT_OES))
    {
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTexParameterIuiv, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_UINT_PARAMETER, 4, data, OS_TOBJ_ID_ASSOCIATED_TEXTURE_NAMES_PSEUDO_PARAMETER, 1, &boundTextureName);
    }
    else if (pname == GL_TEXTURE_PRIORITY)
    {
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTexParameterIuiv, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_UINT_PARAMETER, *data, OS_TOBJ_ID_ASSOCIATED_TEXTURE_NAMES_PSEUDO_PARAMETER, 1, &boundTextureName);
    }
    else
    {
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTexParameterIuiv, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_UINT_PARAMETER, data, OS_TOBJ_ID_ASSOCIATED_TEXTURE_NAMES_PSEUDO_PARAMETER, 1, &boundTextureName);
    }

    // Check if stub textures are forced:
    bool areStubTexForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubTexForced = pCurrentThreadRenderContextMonitor->forcedModesManager().isStubForced(AP_OPENGL_FORCED_STUB_TEXTURES_MODE);
    }

    // If we are not in "Force stub textures" mode:
    if (!areStubTexForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glTexParameterIuiv, (target, pname, data));
    }

    // Log the new parameter value:
    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        gsTexturesMonitor* texturesMon = pCurrentThreadRenderContextMonitor->texturesMonitor();
        GT_IF_WITH_ASSERT(texturesMon != NULL)
        {
            bool rcTexParamf = pCurrentThreadRenderContextMonitor->onNamedTextureUIntParameterChanged(boundTextureName, pname, data);
            GT_ASSERT(rcTexParamf);
        }

        // Log the mipmap auto generation:
        if ((pname == GL_GENERATE_MIPMAP) || (pname == GL_TEXTURE_BASE_LEVEL) || (pname == GL_TEXTURE_MAX_LEVEL))
        {
            // Get the param value:
            GLuint value = *data;
            bool rcMipmapGeneration = pCurrentThreadRenderContextMonitor->onMipmapGenerateParamSet(target, pname, (GLfloat)value);
            GT_ASSERT(rcMipmapGeneration);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glTexParameterIuiv);
}

void APIENTRY glGetTexParameterIiv(GLenum target, GLenum pname, GLint* data)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetTexParameterIiv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetTexParameterIiv, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_PARAMETER, data);

    SU_CALL_EXTENSION_FUNC(glGetTexParameterIiv, (target, pname, data));

    SU_END_FUNCTION_WRAPPER(ap_glGetTexParameterIiv);
}
void APIENTRY glGetTexParameterIuiv(GLenum target, GLenum pname, GLuint* data)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetTexParameterIuiv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetTexParameterIuiv, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_PARAMETER, data);

    SU_CALL_EXTENSION_FUNC(glGetTexParameterIuiv, (target, pname, data));

    SU_END_FUNCTION_WRAPPER(ap_glGetTexParameterIuiv);
}

void APIENTRY glClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glClearBufferiv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glClearBufferiv, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, buffer, OS_TOBJ_ID_GL_INT_PARAMETER, drawbuffer, OS_TOBJ_ID_GL_P_INT_PARAMETER, value);

    SU_CALL_EXTENSION_FUNC(glClearBufferiv, (buffer, drawbuffer, value));

    SU_END_FUNCTION_WRAPPER(ap_glClearBufferiv);
}

void APIENTRY glClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glClearBufferuiv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glClearBufferuiv, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, buffer, OS_TOBJ_ID_GL_INT_PARAMETER, drawbuffer, OS_TOBJ_ID_GL_P_UINT_PARAMETER, value);

    SU_CALL_EXTENSION_FUNC(glClearBufferuiv, (buffer, drawbuffer, value));

    SU_END_FUNCTION_WRAPPER(ap_glClearBufferuiv);
}

void APIENTRY glClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glClearBufferfv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glClearBufferfv, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, buffer, OS_TOBJ_ID_GL_INT_PARAMETER, drawbuffer, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, value);

    SU_CALL_EXTENSION_FUNC(glClearBufferfv, (buffer, drawbuffer, value));

    SU_END_FUNCTION_WRAPPER(ap_glClearBufferfv);
}

void APIENTRY glClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint value)
{
    SU_START_FUNCTION_WRAPPER(ap_glClearBufferfi);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glClearBufferfi, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, buffer, OS_TOBJ_ID_GL_INT_PARAMETER, drawbuffer, OS_TOBJ_ID_GL_FLOAT_PARAMETER, depth, OS_TOBJ_ID_GL_INT_PARAMETER, value);

    SU_CALL_EXTENSION_FUNC(glClearBufferfi, (buffer, drawbuffer, depth, value));

    SU_END_FUNCTION_WRAPPER(ap_glClearBufferfi);
}

const GLubyte* APIENTRY glGetStringi(GLenum name, GLuint index)
{
    const GLubyte* retVal = NULL;

    // If we should not log the glGetString call:
    bool areInitFunctionsLogged = gsAreInitializationFunctionsLogged();

    if (!areInitFunctionsLogged)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glGetStringi, (name, index), retVal);
    }
    else
    {
        SU_START_FUNCTION_WRAPPER(ap_glGetStringi);

        // Log the call to this function:
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetStringi, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, name, OS_TOBJ_ID_GL_UINT_PARAMETER, index);

        // If we were asked about the extensions string:
        if (name == GL_EXTENSIONS)
        {
            // Get the current thread render context monitor:
            gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();
            GT_IF_WITH_ASSERT(pCurrentThreadRenderContextMonitor != NULL)
            {
                // Return the spy extensions string:
                int renderContextId = pCurrentThreadRenderContextMonitor->spyId();
                retVal = gs_stat_extensionsManager.getSpyExtensionString(renderContextId, index);
            }
        }
        else
        {
            // If this is the regular spy:
#ifdef _AMDT_OPENGLSERVER_EXPORTS
            // Call the real function implementation:
            SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glGetStringi, (name, index), retVal);
#endif
        }

        SU_END_FUNCTION_WRAPPER(ap_glGetStringi);
    }

    return retVal;
}

//////////////////////////////////////////////////////////////////////////
// OpenGL 3.1
//////////////////////////////////////////////////////////////////////////
void APIENTRY glDrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei primcount)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glDrawArraysInstanced);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glDrawArraysInstanced, 4, OS_TOBJ_ID_GL_PRIMITIVE_TYPE_PARAMETER, mode, OS_TOBJ_ID_GL_INT_PARAMETER, first, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_SIZEI_PARAMETER, primcount);

    // Get the current render context monitor:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (pCurrentThreadRenderContextMonitor != NULL)
    {
        // Get the render primitives statistics logger:
        gsRenderPrimitivesStatisticsLogger& renderPrimitivesStatisticsLogger = pCurrentThreadRenderContextMonitor->renderPrimitivesStatisticsLogger();

        // Log this draw primitives function call:
        renderPrimitivesStatisticsLogger.onDrawArraysInstanced(count, primcount, mode);
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glDrawArraysInstanced, (mode, first, count, primcount));

    SU_END_FUNCTION_WRAPPER(ap_glDrawArraysInstanced);
}

void APIENTRY glDrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices, GLsizei primcount)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glDrawElementsInstanced);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glDrawElementsInstanced, 5, OS_TOBJ_ID_GL_PRIMITIVE_TYPE_PARAMETER, mode, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_POINTER_PARAMETER, indices, OS_TOBJ_ID_GL_SIZEI_PARAMETER, primcount);

    // Get the current render context monitor:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (pCurrentThreadRenderContextMonitor != NULL)
    {
        // Get the render primitives statistics logger:
        gsRenderPrimitivesStatisticsLogger& renderPrimitivesStatisticsLogger = pCurrentThreadRenderContextMonitor->renderPrimitivesStatisticsLogger();

        // Log this draw primitives function call:
        renderPrimitivesStatisticsLogger.onDrawElementsInstanced(count, mode, type, primcount);
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glDrawElementsInstanced, (mode, count, type, indices, primcount));

    SU_END_FUNCTION_WRAPPER(ap_glDrawElementsInstanced);
}

void APIENTRY glTexBuffer(GLenum target, GLenum internalformat, GLuint buffer)
{
    SU_START_FUNCTION_WRAPPER(ap_glTexBuffer);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTexBuffer, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, internalformat, OS_TOBJ_ID_GL_UINT_PARAMETER, buffer);

    // Log the textures buffer attachment:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        pCurrentThreadRenderContextMonitor->onTextureBuffer(target, internalformat, buffer);
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glTexBuffer, (target, internalformat, buffer));

    SU_END_FUNCTION_WRAPPER(ap_glTexBuffer);
}

void APIENTRY glPrimitiveRestartIndex(GLuint index)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glPrimitiveRestartIndex);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glPrimitiveRestartIndex, 1, OS_TOBJ_ID_GL_UINT_PARAMETER, index);

    // Get the current render context monitor:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (pCurrentThreadRenderContextMonitor != NULL)
    {
        // Get the render primitives statistics logger:
        gsRenderPrimitivesStatisticsLogger& renderPrimitivesStatisticsLogger = pCurrentThreadRenderContextMonitor->renderPrimitivesStatisticsLogger();

        // Log this draw primitives function call:
        renderPrimitivesStatisticsLogger.onPrimitiveRestartIndex(index);
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glPrimitiveRestartIndex, (index));

    SU_END_FUNCTION_WRAPPER(ap_glPrimitiveRestartIndex);
}

//////////////////////////////////////////////////////////////////////////
// OpenGL 3.2
//////////////////////////////////////////////////////////////////////////
void APIENTRY glGetInteger64i_v(GLenum target, GLuint pname, GLint64* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetInteger64i_v);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetInteger64i_v, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_UINT_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_64_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetInteger64i_v, (target, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetInteger64i_v);
}

void APIENTRY glGetBufferParameteri64v(GLenum target, GLenum pname, GLint64* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetBufferParameteri64v);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetBufferParameteri64v, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_64_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetBufferParameteri64v, (target, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetBufferParameteri64v);
}

void APIENTRY glFramebufferTexture(GLenum target, GLenum attachment, GLuint texture, GLint level)
{
    SU_START_FUNCTION_WRAPPER(ap_glFramebufferTexture);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glFramebufferTexture, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, attachment, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_INT_PARAMETER, level);

    // Get the RenderContextMonitor
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    // Construct a new apFBO for each of the generated frame buffer objects:
    GT_IF_WITH_ASSERT(pCurrentThreadRenderContextMonitor != NULL)
    {
        // Bind the texture to the active FBO:
        bool rcBindFBO = pCurrentThreadRenderContextMonitor->bindTextureToTheActiveFBO(target, GL_NONE, attachment, texture, 0);
        GT_ASSERT(rcBindFBO);
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glFramebufferTexture, (target, attachment, texture, level));

    SU_END_FUNCTION_WRAPPER(ap_glFramebufferTexture);
}

void APIENTRY glFramebufferTextureFace(GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face)
{
    SU_START_FUNCTION_WRAPPER(ap_glFramebufferTextureFace);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glFramebufferTextureFace, 5, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, attachment, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_ENUM_PARAMETER, face);

    // Get the RenderContextMonitor
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    // Construct a new apFBO for each of the generated frame buffer objects:
    GT_IF_WITH_ASSERT(pCurrentThreadRenderContextMonitor != NULL)
    {
        // Bind the texture to the active FBO:
        bool rcBindFBO = pCurrentThreadRenderContextMonitor->bindTextureToTheActiveFBO(target, GL_NONE, attachment, texture, face);
        GT_ASSERT(rcBindFBO);
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glFramebufferTextureFace, (target, attachment, texture, level, face));

    SU_END_FUNCTION_WRAPPER(ap_glFramebufferTextureFace);
}

//////////////////////////////////////////////////////////////////////////
// OpenGL 3.3
//////////////////////////////////////////////////////////////////////////
void APIENTRY glBindFragDataLocationIndexed(GLuint program, GLuint colorNumber, GLuint index, const GLchar* name)
{
    SU_START_FUNCTION_WRAPPER(ap_glBindFragDataLocationIndexed);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glBindFragDataLocationIndexed, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_UINT_PARAMETER, colorNumber, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_STRING_PARAMETER, name, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glBindFragDataLocationIndexed, (program, colorNumber, index, name));

    SU_END_FUNCTION_WRAPPER(ap_glBindFragDataLocationIndexed);
}

GLint APIENTRY glGetFragDataIndex(GLuint program, const GLchar* name)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetFragDataIndex);

    GLint retVal = -1;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetFragDataIndex, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_STRING_PARAMETER, name, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glGetFragDataIndex, (program, name), retVal);

    SU_END_FUNCTION_WRAPPER(ap_glGetFragDataIndex);

    return retVal;
}

void APIENTRY glGenSamplers(GLsizei count, GLuint* samplers)
{
    SU_START_FUNCTION_WRAPPER(ap_glGenSamplers);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGenSamplers, 2, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_P_UINT_PARAMETER, samplers);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGenSamplers, (count, samplers));

    // Get the render context monitor:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();
    GT_IF_WITH_ASSERT(pCurrentThreadRenderContextMonitor != NULL)
    {
        // Now update the monitor with the values generated by the runtime.
        gsSamplersMonitor& samplersMonitor = pCurrentThreadRenderContextMonitor->samplersMonitor();
        samplersMonitor.genSamplers(count, samplers);
    }

    SU_END_FUNCTION_WRAPPER(ap_glGenSamplers);
}

void APIENTRY glDeleteSamplers(GLsizei count, const GLuint* samplers)
{
    SU_START_FUNCTION_WRAPPER(ap_glDeleteSamplers);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glDeleteSamplers, 2, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_UINT_PARAMETER, count, samplers);

    // Get the render context monitor:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();
    GT_IF_WITH_ASSERT(pCurrentThreadRenderContextMonitor != NULL)
    {
        // Pass the request to the samplers monitor:
        gsSamplersMonitor& samplersMonitor = pCurrentThreadRenderContextMonitor->samplersMonitor();
        samplersMonitor.deleteSamplers(count, samplers);
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glDeleteSamplers, (count, samplers));

    SU_END_FUNCTION_WRAPPER(ap_glDeleteSamplers);
}

GLboolean APIENTRY glIsSampler(GLuint sampler)
{
    SU_START_FUNCTION_WRAPPER(ap_glIsSampler);

    GLboolean retVal = GL_FALSE;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glIsSampler, 1, OS_TOBJ_ID_GL_UINT_PARAMETER, sampler);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glIsSampler, (sampler), retVal);

    SU_END_FUNCTION_WRAPPER(ap_glIsSampler);

    return retVal;
}

void APIENTRY glBindSampler(GLuint unit, GLuint sampler)
{
    SU_START_FUNCTION_WRAPPER(ap_glBindSampler);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glBindSampler, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, unit, OS_TOBJ_ID_GL_UINT_PARAMETER, sampler);

    // Get the render context monitor:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();
    GT_IF_WITH_ASSERT(pCurrentThreadRenderContextMonitor != NULL)
    {
        // Pass the request to the samplers monitor:
        gsSamplersMonitor& samplersMonitor = pCurrentThreadRenderContextMonitor->samplersMonitor();
        bool rc = samplersMonitor.bindSampler(unit, sampler);
        GT_ASSERT(rc);
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glBindSampler, (unit, sampler));

    SU_END_FUNCTION_WRAPPER(ap_glBindSampler);
}

void APIENTRY glSamplerParameteri(GLuint sampler, GLenum pname, GLint param)
{
    SU_START_FUNCTION_WRAPPER(ap_glSamplerParameteri);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glSamplerParameteri, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, sampler, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_INT_PARAMETER, param);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glSamplerParameteri, (sampler, pname, param));

    SU_END_FUNCTION_WRAPPER(ap_glSamplerParameteri);
}

void APIENTRY glSamplerParameteriv(GLuint sampler, GLenum pname, const GLint* param)
{
    SU_START_FUNCTION_WRAPPER(ap_glSamplerParameteriv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glSamplerParameteriv, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, sampler, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_PARAMETER, param);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glSamplerParameteriv, (sampler, pname, param));

    SU_END_FUNCTION_WRAPPER(ap_glSamplerParameteriv);
}

void APIENTRY glSamplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
{
    SU_START_FUNCTION_WRAPPER(ap_glSamplerParameterf);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glSamplerParameterf, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, sampler, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_FLOAT_PARAMETER, param);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glSamplerParameterf, (sampler, pname, param));

    SU_END_FUNCTION_WRAPPER(ap_glSamplerParameterf);
}

void APIENTRY glSamplerParameterfv(GLuint sampler, GLenum pname, const GLfloat* param)
{
    SU_START_FUNCTION_WRAPPER(ap_glSamplerParameterfv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glSamplerParameterfv, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, sampler, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, param);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glSamplerParameterfv, (sampler, pname, param));

    SU_END_FUNCTION_WRAPPER(ap_glSamplerParameterfv);
}

void APIENTRY glSamplerParameterIiv(GLuint sampler, GLenum pname, const GLint* param)
{
    SU_START_FUNCTION_WRAPPER(ap_glSamplerParameterIiv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glSamplerParameterIiv, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, sampler, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_PARAMETER, param);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glSamplerParameterIiv, (sampler, pname, param));

    SU_END_FUNCTION_WRAPPER(ap_glSamplerParameterIiv);
}

void APIENTRY glSamplerParameterIuiv(GLuint sampler, GLenum pname, const GLuint* param)
{
    SU_START_FUNCTION_WRAPPER(ap_glSamplerParameterIuiv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glSamplerParameterIuiv, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, sampler, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_UINT_PARAMETER, param);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glSamplerParameterIuiv, (sampler, pname, param));

    SU_END_FUNCTION_WRAPPER(ap_glSamplerParameterIuiv);
}

void APIENTRY glGetSamplerParameteriv(GLuint sampler, GLenum pname, GLint* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetSamplerParameteriv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetSamplerParameteriv, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, sampler, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetSamplerParameteriv, (sampler, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetSamplerParameteriv);
}

void APIENTRY glGetSamplerParameterIiv(GLuint sampler, GLenum pname, GLint* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetSamplerParameterIiv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetSamplerParameterIiv, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, sampler, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetSamplerParameterIiv, (sampler, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetSamplerParameterIiv);
}

void APIENTRY glGetSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetSamplerParameterfv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetSamplerParameterfv, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, sampler, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetSamplerParameterfv, (sampler, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetSamplerParameterfv);
}

void APIENTRY glGetSamplerParameterIuiv(GLuint sampler, GLenum pname, GLuint* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetSamplerParameterIuiv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetSamplerParameterIuiv, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, sampler, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_UINT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetSamplerParameterIuiv, (sampler, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetSamplerParameterIuiv);
}

void APIENTRY glQueryCounter(GLuint id, GLenum target)
{
    SU_START_FUNCTION_WRAPPER(ap_glQueryCounter);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glQueryCounter, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, id, OS_TOBJ_ID_GL_ENUM_PARAMETER, target);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glQueryCounter, (id, target));

    SU_END_FUNCTION_WRAPPER(ap_glQueryCounter);
}

void APIENTRY glGetQueryObjecti64v(GLuint id, GLenum pname, GLint64* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetQueryObjecti64v);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetQueryObjecti64v, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, id, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_64_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetQueryObjecti64v, (id, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetQueryObjecti64v);
}

void APIENTRY glGetQueryObjectui64v(GLuint id, GLenum pname, GLuint64* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetQueryObjectui64v);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetQueryObjectui64v, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, id, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_UINT_64_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetQueryObjectui64v, (id, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetQueryObjectui64v);
}

void APIENTRY glVertexAttribDivisor(GLuint index, GLuint divisor)
{
    SU_START_FUNCTION_WRAPPER(ap_glVertexAttribDivisor);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttribDivisor, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_UINT_PARAMETER, divisor);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttribDivisor, (index, divisor));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttribDivisor);
}

void APIENTRY glVertexAttribP1ui(GLuint index, GLenum type, GLboolean normalized, GLuint value)
{
    SU_START_FUNCTION_WRAPPER(ap_glVertexAttribP1ui);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttribP1ui, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_BOOL_PARAMETER, normalized, OS_TOBJ_ID_GL_UINT_PARAMETER, value);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttribP1ui, (index, type, normalized, value));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttribP1ui);
}

void APIENTRY glVertexAttribP1uiv(GLuint index, GLenum type, GLboolean normalized, const GLuint* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glVertexAttribP1uiv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttribP1uiv, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_BOOL_PARAMETER, normalized, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_UINT_PARAMETER, 1, value);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttribP1uiv, (index, type, normalized, value));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttribP1uiv);
}

void APIENTRY glVertexAttribP2ui(GLuint index, GLenum type, GLboolean normalized, GLuint value)
{
    SU_START_FUNCTION_WRAPPER(ap_glVertexAttribP2ui);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttribP2ui, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_BOOL_PARAMETER, normalized, OS_TOBJ_ID_GL_UINT_PARAMETER, value);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttribP2ui, (index, type, normalized, value));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttribP2ui);
}

void APIENTRY glVertexAttribP2uiv(GLuint index, GLenum type, GLboolean normalized, const GLuint* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glVertexAttribP2uiv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttribP2uiv, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_BOOL_PARAMETER, normalized, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_UINT_PARAMETER, 2, value);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttribP2uiv, (index, type, normalized, value));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttribP2uiv);
}

void APIENTRY glVertexAttribP3ui(GLuint index, GLenum type, GLboolean normalized, GLuint value)
{
    SU_START_FUNCTION_WRAPPER(ap_glVertexAttribP3ui);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttribP3ui, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_BOOL_PARAMETER, normalized, OS_TOBJ_ID_GL_UINT_PARAMETER, value);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttribP3ui, (index, type, normalized, value));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttribP3ui);
}

void APIENTRY glVertexAttribP3uiv(GLuint index, GLenum type, GLboolean normalized, const GLuint* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glVertexAttribP3uiv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttribP3uiv, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_BOOL_PARAMETER, normalized, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_UINT_PARAMETER, 3, value);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttribP3uiv, (index, type, normalized, value));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttribP3uiv);
}

void APIENTRY glVertexAttribP4ui(GLuint index, GLenum type, GLboolean normalized, GLuint value)
{
    SU_START_FUNCTION_WRAPPER(ap_glVertexAttribP4ui);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttribP4ui, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_BOOL_PARAMETER, normalized, OS_TOBJ_ID_GL_UINT_PARAMETER, value);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttribP4ui, (index, type, normalized, value));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttribP4ui);
}

void APIENTRY glVertexAttribP4uiv(GLuint index, GLenum type, GLboolean normalized, const GLuint* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glVertexAttribP4uiv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttribP4uiv, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_BOOL_PARAMETER, normalized, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_UINT_PARAMETER, 4, value);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttribP4uiv, (index, type, normalized, value));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttribP4uiv);
}

void APIENTRY glVertexP2ui(GLenum type, GLuint value)
{
    SU_START_FUNCTION_WRAPPER(ap_glVertexP2ui);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexP2ui, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_UINT_PARAMETER, value);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexP2ui, (type, value));

    SU_END_FUNCTION_WRAPPER(ap_glVertexP2ui);
}

void APIENTRY glVertexP2uiv(GLenum type, const GLuint* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glVertexP2uiv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexP2uiv, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_UINT_PARAMETER, 2, value);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexP2uiv, (type, value));

    SU_END_FUNCTION_WRAPPER(ap_glVertexP2uiv);
}

void APIENTRY glVertexP3ui(GLenum type, GLuint value)
{
    SU_START_FUNCTION_WRAPPER(ap_glVertexP3ui);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexP3ui, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_UINT_PARAMETER, value);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexP3ui, (type, value));

    SU_END_FUNCTION_WRAPPER(ap_glVertexP3ui);
}

void APIENTRY glVertexP3uiv(GLenum type, const GLuint* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glVertexP3uiv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexP3uiv, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_UINT_PARAMETER, 3, value);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexP3uiv, (type, value));

    SU_END_FUNCTION_WRAPPER(ap_glVertexP3uiv);
}

void APIENTRY glVertexP4ui(GLenum type, GLuint value)
{
    SU_START_FUNCTION_WRAPPER(ap_glVertexP4ui);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexP4ui, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_UINT_PARAMETER, value);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexP4ui, (type, value));

    SU_END_FUNCTION_WRAPPER(ap_glVertexP4ui);
}

void APIENTRY glVertexP4uiv(GLenum type, const GLuint* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glVertexP4uiv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexP4uiv, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_UINT_PARAMETER, 4, value);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexP4uiv, (type, value));

    SU_END_FUNCTION_WRAPPER(ap_glVertexP4uiv);
}

void APIENTRY glTexCoordP1ui(GLenum type, GLuint coords)
{
    SU_START_FUNCTION_WRAPPER(ap_glTexCoordP1ui);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTexCoordP1ui, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_UINT_PARAMETER, coords);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glTexCoordP1ui, (type, coords));

    SU_END_FUNCTION_WRAPPER(ap_glTexCoordP1ui);
}

void APIENTRY glTexCoordP1uiv(GLenum type, const GLuint* coords)
{
    SU_START_FUNCTION_WRAPPER(ap_glTexCoordP1uiv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTexCoordP1uiv, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_UINT_PARAMETER, 1, coords);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glTexCoordP1uiv, (type, coords));

    SU_END_FUNCTION_WRAPPER(ap_glTexCoordP1uiv);
}

void APIENTRY glTexCoordP2ui(GLenum type, GLuint coords)
{
    SU_START_FUNCTION_WRAPPER(ap_glTexCoordP2ui);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTexCoordP2ui, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_UINT_PARAMETER, coords);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glTexCoordP2ui, (type, coords));

    SU_END_FUNCTION_WRAPPER(ap_glTexCoordP2ui);
}

void APIENTRY glTexCoordP2uiv(GLenum type, const GLuint* coords)
{
    SU_START_FUNCTION_WRAPPER(ap_glTexCoordP2uiv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTexCoordP2uiv, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_UINT_PARAMETER, 2, coords);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glTexCoordP2uiv, (type, coords));

    SU_END_FUNCTION_WRAPPER(ap_glTexCoordP2uiv);
}

void APIENTRY glTexCoordP3ui(GLenum type, GLuint coords)
{
    SU_START_FUNCTION_WRAPPER(ap_glTexCoordP3ui);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTexCoordP3ui, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_UINT_PARAMETER, coords);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glTexCoordP3ui, (type, coords));

    SU_END_FUNCTION_WRAPPER(ap_glTexCoordP3ui);
}

void APIENTRY glTexCoordP3uiv(GLenum type, const GLuint* coords)
{
    SU_START_FUNCTION_WRAPPER(ap_glTexCoordP3uiv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTexCoordP3uiv, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_UINT_PARAMETER, 3, coords);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glTexCoordP3uiv, (type, coords));

    SU_END_FUNCTION_WRAPPER(ap_glTexCoordP3uiv);
}

void APIENTRY glTexCoordP4ui(GLenum type, GLuint coords)
{
    SU_START_FUNCTION_WRAPPER(ap_glTexCoordP4ui);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTexCoordP4ui, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_UINT_PARAMETER, coords);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glTexCoordP4ui, (type, coords));

    SU_END_FUNCTION_WRAPPER(ap_glTexCoordP4ui);
}

void APIENTRY glTexCoordP4uiv(GLenum type, const GLuint* coords)
{
    SU_START_FUNCTION_WRAPPER(ap_glTexCoordP4uiv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTexCoordP4uiv, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_UINT_PARAMETER, 4, coords);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glTexCoordP4uiv, (type, coords));

    SU_END_FUNCTION_WRAPPER(ap_glTexCoordP4uiv);
}

void APIENTRY glMultiTexCoordP1ui(GLenum texture, GLenum type, GLuint coords)
{
    SU_START_FUNCTION_WRAPPER(ap_glMultiTexCoordP1ui);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexCoordP1ui, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, texture, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_UINT_PARAMETER, coords);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexCoordP1ui, (texture, type, coords));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexCoordP1ui);
}

void APIENTRY glMultiTexCoordP1uiv(GLenum texture, GLenum type, const GLuint* coords)
{
    SU_START_FUNCTION_WRAPPER(ap_glMultiTexCoordP1uiv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexCoordP1uiv, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, texture, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_UINT_PARAMETER, 1, coords);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexCoordP1uiv, (texture, type, coords));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexCoordP1uiv);
}

void APIENTRY glMultiTexCoordP2ui(GLenum texture, GLenum type, GLuint coords)
{
    SU_START_FUNCTION_WRAPPER(ap_glMultiTexCoordP2ui);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexCoordP2ui, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, texture, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_UINT_PARAMETER, coords);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexCoordP2ui, (texture, type, coords));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexCoordP2ui);
}

void APIENTRY glMultiTexCoordP2uiv(GLenum texture, GLenum type, const GLuint* coords)
{
    SU_START_FUNCTION_WRAPPER(ap_glMultiTexCoordP2uiv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexCoordP2uiv, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, texture, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_UINT_PARAMETER, 2, coords);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexCoordP2uiv, (texture, type, coords));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexCoordP2uiv);
}

void APIENTRY glMultiTexCoordP3ui(GLenum texture, GLenum type, GLuint coords)
{
    SU_START_FUNCTION_WRAPPER(ap_glMultiTexCoordP3ui);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexCoordP3ui, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, texture, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_UINT_PARAMETER, coords);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexCoordP3ui, (texture, type, coords));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexCoordP3ui);
}

void APIENTRY glMultiTexCoordP3uiv(GLenum texture, GLenum type, const GLuint* coords)
{
    SU_START_FUNCTION_WRAPPER(ap_glMultiTexCoordP3uiv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexCoordP3uiv, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, texture, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_UINT_PARAMETER, 3, coords);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexCoordP3uiv, (texture, type, coords));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexCoordP3uiv);
}

void APIENTRY glMultiTexCoordP4ui(GLenum texture, GLenum type, GLuint coords)
{
    SU_START_FUNCTION_WRAPPER(ap_glMultiTexCoordP4ui);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexCoordP4ui, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, texture, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_UINT_PARAMETER, coords);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexCoordP4ui, (texture, type, coords));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexCoordP4ui);
}

void APIENTRY glMultiTexCoordP4uiv(GLenum texture, GLenum type, const GLuint* coords)
{
    SU_START_FUNCTION_WRAPPER(ap_glMultiTexCoordP4uiv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexCoordP4uiv, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, texture, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_UINT_PARAMETER, 4, coords);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexCoordP4uiv, (texture, type, coords));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexCoordP4uiv);
}

void APIENTRY glNormalP3ui(GLenum type, GLuint coords)
{
    SU_START_FUNCTION_WRAPPER(ap_glNormalP3ui);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glNormalP3ui, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_UINT_PARAMETER, coords);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glNormalP3ui, (type, coords));

    SU_END_FUNCTION_WRAPPER(ap_glNormalP3ui);
}

void APIENTRY glNormalP3uiv(GLenum type, const GLuint* coords)
{
    SU_START_FUNCTION_WRAPPER(ap_glNormalP3uiv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glNormalP3uiv, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_UINT_PARAMETER, 3, coords);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glNormalP3uiv, (type, coords));

    SU_END_FUNCTION_WRAPPER(ap_glNormalP3uiv);
}

void APIENTRY glColorP3ui(GLenum type, GLuint color)
{
    SU_START_FUNCTION_WRAPPER(ap_glColorP3ui);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glColorP3ui, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_UINT_PARAMETER, color);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glColorP3ui, (type, color));

    SU_END_FUNCTION_WRAPPER(ap_glColorP3ui);
}

void APIENTRY glColorP3uiv(GLenum type, const GLuint* color)
{
    SU_START_FUNCTION_WRAPPER(ap_glColorP3uiv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glColorP3uiv, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_UINT_PARAMETER, 3, color);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glColorP3uiv, (type, color));

    SU_END_FUNCTION_WRAPPER(ap_glColorP3uiv);
}

void APIENTRY glColorP4ui(GLenum type, GLuint color)
{
    SU_START_FUNCTION_WRAPPER(ap_glColorP4ui);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glColorP4ui, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_UINT_PARAMETER, color);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glColorP4ui, (type, color));

    SU_END_FUNCTION_WRAPPER(ap_glColorP4ui);
}

void APIENTRY glColorP4uiv(GLenum type, const GLuint* color)
{
    SU_START_FUNCTION_WRAPPER(ap_glColorP4uiv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glColorP4uiv, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_UINT_PARAMETER, 4, color);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glColorP4uiv, (type, color));

    SU_END_FUNCTION_WRAPPER(ap_glColorP4uiv);
}

void APIENTRY glSecondaryColorP3ui(GLenum type, GLuint color)
{
    SU_START_FUNCTION_WRAPPER(ap_glSecondaryColorP3ui);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glSecondaryColorP3ui, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_UINT_PARAMETER, color);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glSecondaryColorP3ui, (type, color));

    SU_END_FUNCTION_WRAPPER(ap_glSecondaryColorP3ui);
}

void APIENTRY glSecondaryColorP3uiv(GLenum type, const GLuint* color)
{
    SU_START_FUNCTION_WRAPPER(ap_glSecondaryColorP3uiv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glSecondaryColorP3uiv, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_UINT_PARAMETER, 3, color);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glSecondaryColorP3uiv, (type, color));

    SU_END_FUNCTION_WRAPPER(ap_glSecondaryColorP3uiv);
}


//////////////////////////////////////////////////////////////////////////
// OpenGL 4.0
//////////////////////////////////////////////////////////////////////////
void APIENTRY glMinSampleShading(GLfloat value)
{
    SU_START_FUNCTION_WRAPPER(ap_glMinSampleShading);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMinSampleShading, 1, OS_TOBJ_ID_GL_FLOAT_PARAMETER, value);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMinSampleShading, (value));

    SU_END_FUNCTION_WRAPPER(ap_glMinSampleShading);
}

void APIENTRY glBlendEquationi(GLuint buf, GLenum mode)
{
    SU_START_FUNCTION_WRAPPER(ap_glBlendEquationi);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glBlendEquationi, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, buf, OS_TOBJ_ID_GL_ENUM_PARAMETER, mode);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glBlendEquationi, (buf, mode));

    SU_END_FUNCTION_WRAPPER(ap_glBlendEquationi);
}

void APIENTRY glBlendEquationSeparatei(GLuint buf, GLenum modeRGB, GLenum modeAlpha)
{
    SU_START_FUNCTION_WRAPPER(ap_glBlendEquationSeparatei);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glBlendEquationSeparatei, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, buf, OS_TOBJ_ID_GL_ENUM_PARAMETER, modeRGB, OS_TOBJ_ID_GL_ENUM_PARAMETER, modeAlpha);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glBlendEquationSeparatei, (buf, modeRGB, modeAlpha));

    SU_END_FUNCTION_WRAPPER(ap_glBlendEquationSeparatei);
}

void APIENTRY glBlendFunci(GLuint buf, GLenum src, GLenum dst)
{
    SU_START_FUNCTION_WRAPPER(ap_glBlendFunci);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glBlendFunci, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, buf, OS_TOBJ_ID_GL_ENUM_PARAMETER, src, OS_TOBJ_ID_GL_ENUM_PARAMETER, dst);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glBlendFunci, (buf, src, dst));

    SU_END_FUNCTION_WRAPPER(ap_glBlendFunci);
}

void APIENTRY glBlendFuncSeparatei(GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
{
    SU_START_FUNCTION_WRAPPER(ap_glBlendFuncSeparatei);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glBlendFuncSeparatei, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, buf, OS_TOBJ_ID_GL_ENUM_PARAMETER, srcRGB, OS_TOBJ_ID_GL_ENUM_PARAMETER, dstRGB, OS_TOBJ_ID_GL_ENUM_PARAMETER, srcAlpha, OS_TOBJ_ID_GL_ENUM_PARAMETER, dstAlpha);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glBlendFuncSeparatei, (buf, srcRGB, dstRGB, srcAlpha, dstAlpha));

    SU_END_FUNCTION_WRAPPER(ap_glBlendFuncSeparatei);
}

void APIENTRY glDrawArraysIndirect(GLenum mode, const GLvoid* indirect)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glDrawArraysIndirect);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glDrawArraysIndirect, 2, OS_TOBJ_ID_GL_PRIMITIVE_TYPE_PARAMETER, mode, OS_TOBJ_ID_GL_P_VOID_PARAMETER, indirect);

    // Get the current render context monitor:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if ((NULL != pCurrentThreadRenderContextMonitor) && (NULL != indirect))
    {
        // Get the render primitives statistics logger:
        gsRenderPrimitivesStatisticsLogger& renderPrimitivesStatisticsLogger = pCurrentThreadRenderContextMonitor->renderPrimitivesStatisticsLogger();

        // Downcast the indirect data:
        struct DrawArraysIndirectCommand
        {
            GLuint  count;
            GLuint  primCount;
            GLuint  first;
            GLuint  baseInstance;
        } * indirectData = (DrawArraysIndirectCommand*)indirect;

        // Log this draw primitives function call:
        renderPrimitivesStatisticsLogger.onDrawArraysInstanced((GLsizei)indirectData->count, (GLsizei)indirectData->primCount, mode);
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glDrawArraysIndirect, (mode, indirect));

    SU_END_FUNCTION_WRAPPER(ap_glDrawArraysIndirect);
}

void APIENTRY glDrawElementsIndirect(GLenum mode, GLenum type, const GLvoid* indirect)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glDrawElementsIndirect);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glDrawElementsIndirect, 3, OS_TOBJ_ID_GL_PRIMITIVE_TYPE_PARAMETER, mode, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_P_VOID_PARAMETER, indirect);

    // Get the current render context monitor:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if ((NULL != pCurrentThreadRenderContextMonitor) && (NULL != indirect))
    {
        // Get the render primitives statistics logger:
        gsRenderPrimitivesStatisticsLogger& renderPrimitivesStatisticsLogger = pCurrentThreadRenderContextMonitor->renderPrimitivesStatisticsLogger();

        // Downcast the indirect data:
        struct DrawElementsIndirectCommand
        {
            GLuint  count;
            GLuint  primCount;
            GLuint  firstIndex;
            GLuint  baseVertex;
            GLuint  baseInstance;
        } * indirectData = (DrawElementsIndirectCommand*)indirect;

        // Log this draw primitives function call:
        renderPrimitivesStatisticsLogger.onDrawElementsInstanced((GLsizei)indirectData->count, mode, type, (GLsizei)indirectData->primCount);
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glDrawElementsIndirect, (mode, type, indirect));

    SU_END_FUNCTION_WRAPPER(ap_glDrawElementsIndirect);
}

void APIENTRY glUniform1d(GLint location, GLdouble x)
{
    SU_START_FUNCTION_WRAPPER(ap_glUniform1d);

    // Log the call to this function:
    GLuint activeProgramName = gs_stat_openGLMonitorInstance.activeProgram();
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glUniform1d, 3, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, x, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, activeProgramName);

    // Check if stub shaders are forced:
    bool areShadersStubbed = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areShadersStubbed = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areShadersStubbed)
    {
        SU_CALL_EXTENSION_FUNC(glUniform1d, (location, x));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(activeProgramName, location, GL_DOUBLE, (void*)&x);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glUniform1d);
}

void APIENTRY glUniform2d(GLint location, GLdouble x, GLdouble y)
{
    SU_START_FUNCTION_WRAPPER(ap_glUniform2d);

    // Log the call to this function:
    GLuint activeProgramName = gs_stat_openGLMonitorInstance.activeProgram();
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glUniform2d, 4, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, x, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, y, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, activeProgramName);

    // Check if stub shaders are forced:
    bool areShadersStubbed = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areShadersStubbed = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areShadersStubbed)
    {
        SU_CALL_EXTENSION_FUNC(glUniform2d, (location, x, y));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            GLdouble values[2] = {x, y};
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(activeProgramName, location, GL_DOUBLE_VEC2, (void*)values);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glUniform2d);
}

void APIENTRY glUniform3d(GLint location, GLdouble x, GLdouble y, GLdouble z)
{
    SU_START_FUNCTION_WRAPPER(ap_glUniform3d);

    // Log the call to this function:
    GLuint activeProgramName = gs_stat_openGLMonitorInstance.activeProgram();
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glUniform3d, 5, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, x, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, y, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, z, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, activeProgramName);

    // Check if stub shaders are forced:
    bool areShadersStubbed = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areShadersStubbed = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areShadersStubbed)
    {
        SU_CALL_EXTENSION_FUNC(glUniform3d, (location, x, y, z));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            GLdouble values[3] = {x, y, z};
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(activeProgramName, location, GL_DOUBLE_VEC3, (void*)values);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glUniform3d);
}

void APIENTRY glUniform4d(GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w)
{
    SU_START_FUNCTION_WRAPPER(ap_glUniform4d);

    // Log the call to this function:
    GLuint activeProgramName = gs_stat_openGLMonitorInstance.activeProgram();
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glUniform4d, 6, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, x, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, y, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, z, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, w, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, activeProgramName);

    // Check if stub shaders are forced:
    bool areShadersStubbed = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areShadersStubbed = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areShadersStubbed)
    {
        SU_CALL_EXTENSION_FUNC(glUniform4d, (location, x, y, z, w));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            GLdouble values[4] = {x, y, z, w};
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(activeProgramName, location, GL_DOUBLE_VEC4, (void*)values);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glUniform4d);
}

void APIENTRY glUniform1dv(GLint location, GLsizei count, const GLdouble* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glUniform1dv);

    // Log the call to this function:
    GLuint activeProgramName = gs_stat_openGLMonitorInstance.activeProgram();
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glUniform1dv, 4, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, 1, value, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, activeProgramName);

    // Check if stub shaders are forced:
    bool areShadersStubbed = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areShadersStubbed = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areShadersStubbed)
    {
        SU_CALL_EXTENSION_FUNC(glUniform1dv, (location, count, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(activeProgramName, location, GL_DOUBLE, (void*)value);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glUniform1dv);
}

void APIENTRY glUniform2dv(GLint location, GLsizei count, const GLdouble* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glUniform2dv);

    // Log the call to this function:
    GLuint activeProgramName = gs_stat_openGLMonitorInstance.activeProgram();
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glUniform2dv, 4, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, 2, value, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, activeProgramName);

    // Check if stub shaders are forced:
    bool areShadersStubbed = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areShadersStubbed = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areShadersStubbed)
    {
        SU_CALL_EXTENSION_FUNC(glUniform2dv, (location, count, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(activeProgramName, location, GL_DOUBLE_VEC2, (void*)value);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glUniform2dv);
}

void APIENTRY glUniform3dv(GLint location, GLsizei count, const GLdouble* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glUniform3dv);

    // Log the call to this function:
    GLuint activeProgramName = gs_stat_openGLMonitorInstance.activeProgram();
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glUniform3dv, 4, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, 3, value, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, activeProgramName);

    // Check if stub shaders are forced:
    bool areShadersStubbed = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areShadersStubbed = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areShadersStubbed)
    {
        SU_CALL_EXTENSION_FUNC(glUniform3dv, (location, count, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(activeProgramName, location, GL_DOUBLE_VEC3, (void*)value);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glUniform3dv);
}

void APIENTRY glUniform4dv(GLint location, GLsizei count, const GLdouble* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glUniform4dv);

    // Log the call to this function:
    GLuint activeProgramName = gs_stat_openGLMonitorInstance.activeProgram();
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glUniform4dv, 4, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, 4, value, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, activeProgramName);

    // Check if stub shaders are forced:
    bool areShadersStubbed = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areShadersStubbed = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areShadersStubbed)
    {
        SU_CALL_EXTENSION_FUNC(glUniform4dv, (location, count, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(activeProgramName, location, GL_DOUBLE_VEC4, (void*)value);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glUniform4dv);
}

void APIENTRY glUniformMatrix2dv(GLint location, GLsizei count, GLboolean transpose, const GLdouble* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glUniformMatrix2dv);

    // Log the call to this function:
    GLuint activeProgramName = gs_stat_openGLMonitorInstance.activeProgram();
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glUniformMatrix2dv, 5, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_BOOL_PARAMETER, transpose, OS_TOBJ_ID_MATRIX_PARAMETER, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, 2, 2, value, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, activeProgramName);

    // Check if stub shaders are forced:
    bool areShadersStubbed = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areShadersStubbed = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areShadersStubbed)
    {
        SU_CALL_EXTENSION_FUNC(glUniformMatrix2dv, (location, count, transpose, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(activeProgramName, location, GL_DOUBLE_MAT2, (void*)value, (transpose == GL_TRUE));
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glUniformMatrix2dv);
}

void APIENTRY glUniformMatrix3dv(GLint location, GLsizei count, GLboolean transpose, const GLdouble* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glUniformMatrix3dv);

    // Log the call to this function:
    GLuint activeProgramName = gs_stat_openGLMonitorInstance.activeProgram();
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glUniformMatrix3dv, 5, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_BOOL_PARAMETER, transpose, OS_TOBJ_ID_MATRIX_PARAMETER, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, 3, 3, value, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, activeProgramName);

    // Check if stub shaders are forced:
    bool areShadersStubbed = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areShadersStubbed = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areShadersStubbed)
    {
        SU_CALL_EXTENSION_FUNC(glUniformMatrix3dv, (location, count, transpose, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(activeProgramName, location, GL_DOUBLE_MAT3, (void*)value, (transpose == GL_TRUE));
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glUniformMatrix3dv);
}

void APIENTRY glUniformMatrix4dv(GLint location, GLsizei count, GLboolean transpose, const GLdouble* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glUniformMatrix4dv);

    // Log the call to this function:
    GLuint activeProgramName = gs_stat_openGLMonitorInstance.activeProgram();
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glUniformMatrix4dv, 5, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_BOOL_PARAMETER, transpose, OS_TOBJ_ID_MATRIX_PARAMETER, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, 4, 4, value, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, activeProgramName);

    // Check if stub shaders are forced:
    bool areShadersStubbed = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areShadersStubbed = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areShadersStubbed)
    {
        SU_CALL_EXTENSION_FUNC(glUniformMatrix4dv, (location, count, transpose, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(activeProgramName, location, GL_DOUBLE_MAT4, (void*)value, (transpose == GL_TRUE));
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glUniformMatrix4dv);
}

void APIENTRY glUniformMatrix2x3dv(GLint location, GLsizei count, GLboolean transpose, const GLdouble* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glUniformMatrix2x3dv);

    // Log the call to this function:
    GLuint activeProgramName = gs_stat_openGLMonitorInstance.activeProgram();
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glUniformMatrix2x3dv, 5, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_BOOL_PARAMETER, transpose, OS_TOBJ_ID_MATRIX_PARAMETER, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, 2, 3, value, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, activeProgramName);

    // Check if stub shaders are forced:
    bool areShadersStubbed = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areShadersStubbed = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areShadersStubbed)
    {
        SU_CALL_EXTENSION_FUNC(glUniformMatrix2x3dv, (location, count, transpose, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(activeProgramName, location, GL_DOUBLE_MAT2x3, (void*)value, (transpose == GL_TRUE));
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glUniformMatrix2x3dv);
}

void APIENTRY glUniformMatrix2x4dv(GLint location, GLsizei count, GLboolean transpose, const GLdouble* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glUniformMatrix2x4dv);

    // Log the call to this function:
    GLuint activeProgramName = gs_stat_openGLMonitorInstance.activeProgram();
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glUniformMatrix2x4dv, 5, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_BOOL_PARAMETER, transpose, OS_TOBJ_ID_MATRIX_PARAMETER, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, 2, 4, value, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, activeProgramName);

    // Check if stub shaders are forced:
    bool areShadersStubbed = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areShadersStubbed = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areShadersStubbed)
    {
        SU_CALL_EXTENSION_FUNC(glUniformMatrix2x4dv, (location, count, transpose, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(activeProgramName, location, GL_DOUBLE_MAT2x4, (void*)value, (transpose == GL_TRUE));
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glUniformMatrix2x4dv);
}

void APIENTRY glUniformMatrix3x2dv(GLint location, GLsizei count, GLboolean transpose, const GLdouble* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glUniformMatrix3x2dv);

    // Log the call to this function:
    GLuint activeProgramName = gs_stat_openGLMonitorInstance.activeProgram();
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glUniformMatrix3x2dv, 5, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_BOOL_PARAMETER, transpose, OS_TOBJ_ID_MATRIX_PARAMETER, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, 3, 2, value, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, activeProgramName);

    // Check if stub shaders are forced:
    bool areShadersStubbed = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areShadersStubbed = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areShadersStubbed)
    {
        SU_CALL_EXTENSION_FUNC(glUniformMatrix3x2dv, (location, count, transpose, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(activeProgramName, location, GL_DOUBLE_MAT3x2, (void*)value, (transpose == GL_TRUE));
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glUniformMatrix3x2dv);
}

void APIENTRY glUniformMatrix3x4dv(GLint location, GLsizei count, GLboolean transpose, const GLdouble* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glUniformMatrix3x4dv);

    // Log the call to this function:
    GLuint activeProgramName = gs_stat_openGLMonitorInstance.activeProgram();
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glUniformMatrix3x4dv, 5, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_BOOL_PARAMETER, transpose, OS_TOBJ_ID_MATRIX_PARAMETER, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, 3, 4, value, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, activeProgramName);

    // Check if stub shaders are forced:
    bool areShadersStubbed = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areShadersStubbed = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areShadersStubbed)
    {
        SU_CALL_EXTENSION_FUNC(glUniformMatrix3x4dv, (location, count, transpose, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(activeProgramName, location, GL_DOUBLE_MAT3x4, (void*)value, (transpose == GL_TRUE));
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glUniformMatrix3x4dv);
}

void APIENTRY glUniformMatrix4x2dv(GLint location, GLsizei count, GLboolean transpose, const GLdouble* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glUniformMatrix4x2dv);

    // Log the call to this function:
    GLuint activeProgramName = gs_stat_openGLMonitorInstance.activeProgram();
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glUniformMatrix4x2dv, 5, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_BOOL_PARAMETER, transpose, OS_TOBJ_ID_MATRIX_PARAMETER, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, 4, 2, value, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, activeProgramName);

    // Check if stub shaders are forced:
    bool areShadersStubbed = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areShadersStubbed = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areShadersStubbed)
    {
        SU_CALL_EXTENSION_FUNC(glUniformMatrix4x2dv, (location, count, transpose, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(activeProgramName, location, GL_DOUBLE_MAT4x2, (void*)value, (transpose == GL_TRUE));
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glUniformMatrix4x2dv);
}

void APIENTRY glUniformMatrix4x3dv(GLint location, GLsizei count, GLboolean transpose, const GLdouble* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glUniformMatrix4x3dv);

    // Log the call to this function:
    GLuint activeProgramName = gs_stat_openGLMonitorInstance.activeProgram();
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glUniformMatrix4x3dv, 5, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_BOOL_PARAMETER, transpose, OS_TOBJ_ID_MATRIX_PARAMETER, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, 4, 3, value, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, activeProgramName);

    // Check if stub shaders are forced:
    bool areShadersStubbed = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areShadersStubbed = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areShadersStubbed)
    {
        SU_CALL_EXTENSION_FUNC(glUniformMatrix4x3dv, (location, count, transpose, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(activeProgramName, location, GL_DOUBLE_MAT4x3, (void*)value, (transpose == GL_TRUE));
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glUniformMatrix4x3dv);
}

void APIENTRY glGetUniformdv(GLuint program, GLint location, GLdouble* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetUniformdv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetUniformdv, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_P_DOUBLE_PARAMETER, params, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetUniformdv, (program, location, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetUniformdv);
}

GLint APIENTRY glGetSubroutineUniformLocation(GLuint program, GLenum shadertype, const GLchar* name)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetSubroutineUniformLocation);

    GLint retVal = -1;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetSubroutineUniformLocation, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_ENUM_PARAMETER, shadertype, OS_TOBJ_ID_STRING_PARAMETER, name, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glGetSubroutineUniformLocation, (program, shadertype, name), retVal);

    SU_END_FUNCTION_WRAPPER(ap_glGetSubroutineUniformLocation);

    return retVal;
}

GLuint APIENTRY glGetSubroutineIndex(GLuint program, GLenum shadertype, const GLchar* name)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetSubroutineIndex);

    GLuint retVal = GL_INVALID_INDEX;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetSubroutineIndex, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_ENUM_PARAMETER, shadertype, OS_TOBJ_ID_STRING_PARAMETER, name, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glGetSubroutineIndex, (program, shadertype, name), retVal);

    SU_END_FUNCTION_WRAPPER(ap_glGetSubroutineIndex);

    return retVal;
}

void APIENTRY glGetActiveSubroutineUniformiv(GLuint program, GLenum shadertype, GLuint index, GLenum pname, GLint* values)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetActiveSubroutineUniformiv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetActiveSubroutineUniformiv, 6, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_ENUM_PARAMETER, shadertype, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_PARAMETER, values, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetActiveSubroutineUniformiv, (program, shadertype, index, pname, values));

    SU_END_FUNCTION_WRAPPER(ap_glGetActiveSubroutineUniformiv);
}

void APIENTRY glGetActiveSubroutineUniformName(GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei* length, GLchar* name)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetActiveSubroutineUniformName);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetActiveSubroutineUniformName, 7, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_ENUM_PARAMETER, shadertype, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_SIZEI_PARAMETER, bufsize, OS_TOBJ_ID_GL_P_SIZEI_PARAMETER, length, OS_TOBJ_ID_GL_P_CHAR, name, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetActiveSubroutineUniformName, (program, shadertype, index, bufsize, length, name));

    SU_END_FUNCTION_WRAPPER(ap_glGetActiveSubroutineUniformName);
}

void APIENTRY glGetActiveSubroutineName(GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei* length, GLchar* name)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetActiveSubroutineName);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetActiveSubroutineName, 7, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_ENUM_PARAMETER, shadertype, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_SIZEI_PARAMETER, bufsize, OS_TOBJ_ID_GL_P_SIZEI_PARAMETER, length, OS_TOBJ_ID_GL_P_CHAR, name, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetActiveSubroutineName, (program, shadertype, index, bufsize, length, name));

    SU_END_FUNCTION_WRAPPER(ap_glGetActiveSubroutineName);
}

void APIENTRY glUniformSubroutinesuiv(GLenum shadertype, GLsizei count, const GLuint* indices)
{
    SU_START_FUNCTION_WRAPPER(ap_glUniformSubroutinesuiv);

    // Log the call to this function:
    GLuint activeProgramName = gs_stat_openGLMonitorInstance.activeProgram();
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glUniformSubroutinesuiv, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, shadertype, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_UINT_PARAMETER, (int)count, indices, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, activeProgramName);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glUniformSubroutinesuiv, (shadertype, count, indices));

    SU_END_FUNCTION_WRAPPER(ap_glUniformSubroutinesuiv);
}

void APIENTRY glGetUniformSubroutineuiv(GLenum shadertype, GLint location, GLuint* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetUniformSubroutineuiv);

    // Log the call to this function:
    GLuint activeProgramName = gs_stat_openGLMonitorInstance.activeProgram();
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetUniformSubroutineuiv, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, shadertype, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_P_UINT_PARAMETER, params, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, activeProgramName);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetUniformSubroutineuiv, (shadertype, location, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetUniformSubroutineuiv);
}

void APIENTRY glGetProgramStageiv(GLuint program, GLenum shadertype, GLenum pname, GLint* values)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetProgramStageiv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetProgramStageiv, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_ENUM_PARAMETER, shadertype, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_PARAMETER, values, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetProgramStageiv, (program, shadertype, pname, values));

    SU_END_FUNCTION_WRAPPER(ap_glGetProgramStageiv);
}

void APIENTRY glPatchParameteri(GLenum pname, GLint value)
{
    SU_START_FUNCTION_WRAPPER(ap_glPatchParameteri);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glPatchParameteri, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_INT_PARAMETER, value);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glPatchParameteri, (pname, value));

    SU_END_FUNCTION_WRAPPER(ap_glPatchParameteri);
}

void APIENTRY glPatchParameterfv(GLenum pname, const GLfloat* values)
{
    SU_START_FUNCTION_WRAPPER(ap_glPatchParameterfv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glPatchParameterfv, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, values);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glPatchParameterfv, (pname, values));

    SU_END_FUNCTION_WRAPPER(ap_glPatchParameterfv);
}

void APIENTRY glBindTransformFeedback(GLenum target, GLuint id)
{
    SU_START_FUNCTION_WRAPPER(ap_glBindTransformFeedback);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glBindTransformFeedback, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_UINT_PARAMETER, id);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glBindTransformFeedback, (target, id));

    SU_END_FUNCTION_WRAPPER(ap_glBindTransformFeedback);
}

void APIENTRY glDeleteTransformFeedbacks(GLsizei n, const GLuint* ids)
{
    SU_START_FUNCTION_WRAPPER(ap_glDeleteTransformFeedbacks);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glDeleteTransformFeedbacks, 2, OS_TOBJ_ID_GL_SIZEI_PARAMETER, n, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_UINT_PARAMETER, (int)n, ids);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glDeleteTransformFeedbacks, (n, ids));

    SU_END_FUNCTION_WRAPPER(ap_glDeleteTransformFeedbacks);
}

void APIENTRY glGenTransformFeedbacks(GLsizei n, GLuint* ids)
{
    SU_START_FUNCTION_WRAPPER(ap_glGenTransformFeedbacks);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGenTransformFeedbacks, 2, OS_TOBJ_ID_GL_SIZEI_PARAMETER, n, OS_TOBJ_ID_GL_P_UINT_PARAMETER, ids);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGenTransformFeedbacks, (n, ids));

    SU_END_FUNCTION_WRAPPER(ap_glGenTransformFeedbacks);
}

GLboolean APIENTRY glIsTransformFeedback(GLuint id)
{
    SU_START_FUNCTION_WRAPPER(ap_glIsTransformFeedback);

    GLboolean retVal = GL_FALSE;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glIsTransformFeedback, 1, OS_TOBJ_ID_GL_UINT_PARAMETER, id);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glIsTransformFeedback, (id), retVal);

    SU_END_FUNCTION_WRAPPER(ap_glIsTransformFeedback);

    return retVal;
}

void APIENTRY glPauseTransformFeedback(void)
{
    SU_START_FUNCTION_WRAPPER(ap_glPauseTransformFeedback);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glPauseTransformFeedback, 0);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glPauseTransformFeedback, ());

    SU_END_FUNCTION_WRAPPER(ap_glPauseTransformFeedback);
}

void APIENTRY glResumeTransformFeedback(void)
{
    SU_START_FUNCTION_WRAPPER(ap_glResumeTransformFeedback);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glResumeTransformFeedback, 0);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glResumeTransformFeedback, ());

    SU_END_FUNCTION_WRAPPER(ap_glResumeTransformFeedback);
}

void APIENTRY glDrawTransformFeedback(GLenum mode, GLuint id)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glDrawTransformFeedback);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glDrawTransformFeedback, 2, OS_TOBJ_ID_GL_PRIMITIVE_TYPE_PARAMETER, mode, OS_TOBJ_ID_GL_UINT_PARAMETER, id);

    // Get the current render context monitor:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (pCurrentThreadRenderContextMonitor != NULL)
    {
        // TO_DO: OpenGL 4.0 - we need to get the count from the transform feedback object #0 before we can log this:

        /*
        // Get the render primitives statistics logger:
        gsRenderPrimitivesStatisticsLogger& renderPrimitivesStatisticsLogger = pCurrentThreadRenderContextMonitor->renderPrimitivesStatisticsLogger();

        // Log this draw primitives function call:
        renderPrimitivesStatisticsLogger.onDrawArrays(0, count, mode);
        */
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glDrawTransformFeedback, (mode, id));

    SU_END_FUNCTION_WRAPPER(ap_glDrawTransformFeedback);
}

void APIENTRY glDrawTransformFeedbackStream(GLenum mode, GLuint id, GLuint stream)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glDrawTransformFeedbackStream);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glDrawTransformFeedbackStream, 3, OS_TOBJ_ID_GL_PRIMITIVE_TYPE_PARAMETER, mode, OS_TOBJ_ID_GL_UINT_PARAMETER, id, OS_TOBJ_ID_GL_UINT_PARAMETER, stream);

    // Get the current render context monitor:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (pCurrentThreadRenderContextMonitor != NULL)
    {
        // TO_DO: OpenGL 4.0 - we need to get the count from the transform feedback object #stream before we can log this:

        /*
        // Get the render primitives statistics logger:
        gsRenderPrimitivesStatisticsLogger& renderPrimitivesStatisticsLogger = pCurrentThreadRenderContextMonitor->renderPrimitivesStatisticsLogger();

        // Log this draw primitives function call:
        renderPrimitivesStatisticsLogger.onDrawArrays(0, count, mode);
        */
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glDrawTransformFeedbackStream, (mode, id, stream));

    SU_END_FUNCTION_WRAPPER(ap_glDrawTransformFeedbackStream);
}

void APIENTRY glBeginQueryIndexed(GLenum target, GLuint index, GLuint id)
{
    SU_START_FUNCTION_WRAPPER(ap_glBeginQueryIndexed);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glBeginQueryIndexed, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_UINT_PARAMETER, id);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glBeginQueryIndexed, (target, index, id));

    SU_END_FUNCTION_WRAPPER(ap_glBeginQueryIndexed);
}

void APIENTRY glEndQueryIndexed(GLenum target, GLuint index)
{
    SU_START_FUNCTION_WRAPPER(ap_glEndQueryIndexed);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glEndQueryIndexed, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_UINT_PARAMETER, index);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glEndQueryIndexed, (target, index));

    SU_END_FUNCTION_WRAPPER(ap_glEndQueryIndexed);
}

void APIENTRY glGetQueryIndexediv(GLenum target, GLuint index, GLenum pname, GLint* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetQueryIndexediv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetQueryIndexediv, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetQueryIndexediv, (target, index, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetQueryIndexediv);
}


//////////////////////////////////////////////////////////////////////////
// OpenGL 4.1
//////////////////////////////////////////////////////////////////////////
void APIENTRY glReleaseShaderCompiler(void)
{
    SU_START_FUNCTION_WRAPPER(ap_glReleaseShaderCompiler);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glReleaseShaderCompiler, 0);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glReleaseShaderCompiler, ());

    SU_END_FUNCTION_WRAPPER(ap_glReleaseShaderCompiler);
}

void APIENTRY glShaderBinary(GLsizei count, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
{
    SU_START_FUNCTION_WRAPPER(ap_glShaderBinary);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glShaderBinary, 5, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_UINT_PARAMETER, (int)count, shaders, OS_TOBJ_ID_GL_ENUM_PARAMETER, binaryformat, OS_TOBJ_ID_GL_P_VOID_PARAMETER, binary, OS_TOBJ_ID_GL_SIZEI_PARAMETER, length);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glShaderBinary, (count, shaders, binaryformat, binary, length));

    SU_END_FUNCTION_WRAPPER(ap_glShaderBinary);
}

void APIENTRY glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetShaderPrecisionFormat);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetShaderPrecisionFormat, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, shadertype, OS_TOBJ_ID_GL_ENUM_PARAMETER, precisiontype, OS_TOBJ_ID_GL_P_INT_PARAMETER, range, OS_TOBJ_ID_GL_P_INT_PARAMETER, precision);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetShaderPrecisionFormat, (shadertype, precisiontype, range, precision));

    SU_END_FUNCTION_WRAPPER(ap_glGetShaderPrecisionFormat);
}

void APIENTRY glDepthRangef(GLfloat n, GLfloat f)
{
    SU_START_FUNCTION_WRAPPER(ap_glDepthRangef);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glDepthRangef, 2, OS_TOBJ_ID_GL_FLOAT_PARAMETER, n, OS_TOBJ_ID_GL_FLOAT_PARAMETER, f);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glDepthRangef, (n, f));

    SU_END_FUNCTION_WRAPPER(ap_glDepthRangef);
}

void APIENTRY glClearDepthf(GLfloat d)
{
    SU_START_FUNCTION_WRAPPER(ap_glClearDepthf);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glClearDepthf, 1, OS_TOBJ_ID_GL_FLOAT_PARAMETER, d);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glClearDepthf, (d));

    SU_END_FUNCTION_WRAPPER(ap_glClearDepthf);
}

void APIENTRY glGetProgramBinary(GLuint program, GLsizei bufSize, GLsizei* length, GLenum* binaryFormat, GLvoid* binary)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetProgramBinary);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetProgramBinary, 6, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_SIZEI_PARAMETER, bufSize, OS_TOBJ_ID_GL_P_SIZEI_PARAMETER, length, OS_TOBJ_ID_GL_P_ENUM_PARAMETER, binaryFormat, OS_TOBJ_ID_GL_P_VOID_PARAMETER, binary, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetProgramBinary, (program, bufSize, length, binaryFormat, binary));

    SU_END_FUNCTION_WRAPPER(ap_glGetProgramBinary);
}

void APIENTRY glProgramBinary(GLuint program, GLenum binaryFormat, const GLvoid* binary, GLsizei length)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramBinary);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramBinary, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_ENUM_PARAMETER, binaryFormat, OS_TOBJ_ID_GL_P_VOID_PARAMETER, binary, OS_TOBJ_ID_GL_SIZEI_PARAMETER, length, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glProgramBinary, (program, binaryFormat, binary, length));

    SU_END_FUNCTION_WRAPPER(ap_glProgramBinary);
}

void APIENTRY glProgramParameteri(GLuint program, GLenum pname, GLint value)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramParameteri);

    // Log the call to this function:
    // If the second parameter is input or output primitives, log the third parameter as an enumerator:
    if ((pname == GL_GEOMETRY_INPUT_TYPE) || (pname == GL_GEOMETRY_OUTPUT_TYPE))
    {
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramParameteri, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_PRIMITIVE_TYPE_PARAMETER, value, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);
    }
    else
    {
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramParameteri, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_INT_PARAMETER, value, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glProgramParameteri, (program, pname, value));

    // Log the parameter change:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (pCurrentThreadRenderContextMonitor != NULL)
    {
        gsProgramsAndShadersMonitor* progAndShaderMon = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(progAndShaderMon != NULL)
        {
            bool rc = progAndShaderMon->onProgramParameteri(program, pname, value);

            if (!rc)
            {
                if (!progAndShaderMon->isProgramObject(program))
                {
                    gtString errorDescription;
                    apErrorCode errorCode = AP_OBJECT_NAME_DOES_NOT_EXIST_ERROR;
                    errorDescription = GS_STR_usingNonObjectName;
                    errorDescription.appendFormattedString(L": (program name = %u)", program);
                    gs_stat_openGLMonitorInstance.reportDetectedError(errorCode, errorDescription, ap_glProgramParameteri);
                }
                else
                {
                    // Currently do nothing, since we could receive a pname of a parameter we don't want to log
                }
            }
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramParameteri);
}

void APIENTRY glUseProgramStages(GLuint pipeline, GLbitfield stages, GLuint program)
{
    SU_START_FUNCTION_WRAPPER(ap_glUseProgramStages);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glUseProgramStages, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, pipeline, OS_TOBJ_ID_GL_BITFIELD_PARAMETER, stages, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);

    // Get the render context monitor:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();
    GT_IF_WITH_ASSERT(pCurrentThreadRenderContextMonitor != NULL)
    {
        // Pass the request to the pipelines monitor:
        gsPipelineMonitor& pipelinesMonitor = pCurrentThreadRenderContextMonitor->pipelinesMonitor();
        pipelinesMonitor.UseProgramStages(pipeline, stages, program);
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glUseProgramStages, (pipeline, stages, program));

    SU_END_FUNCTION_WRAPPER(ap_glUseProgramStages);
}

void APIENTRY glActiveShaderProgram(GLuint pipeline, GLuint program)
{
    SU_START_FUNCTION_WRAPPER(ap_glActiveShaderProgram);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glActiveShaderProgram, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, pipeline, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);

    // Get the render context monitor:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();
    GT_IF_WITH_ASSERT(pCurrentThreadRenderContextMonitor != NULL)
    {
        // Pass the request to the pipelines monitor:
        gsPipelineMonitor& pipelinesMonitor = pCurrentThreadRenderContextMonitor->pipelinesMonitor();
        pipelinesMonitor.ActiveShaderProgram(pipeline, program);
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glActiveShaderProgram, (pipeline, program));

    SU_END_FUNCTION_WRAPPER(ap_glActiveShaderProgram);
}

GLuint APIENTRY glCreateShaderProgramv(GLenum type, GLsizei count, const GLchar* const* strings)
{
    SU_START_FUNCTION_WRAPPER(ap_glCreateShaderProgramv);

    GLuint retVal = 0;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glCreateShaderProgramv, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_PP_CHAR, strings);

    bool callRealFunction = suGetGlobalServerEnvironmentSettings().m_suDontFixCRInSourceStrings;

    if (!callRealFunction)
    {
        gtASCIIString modifiedSource;

        bool callWithModified = suHandleCRInSources((unsigned int)count, strings, nullptr, modifiedSource);
        callRealFunction = !callWithModified;

        if (callWithModified)
        {
            // Call the real function with the modified values:
            const char* modifiedSourceAsCharArray = modifiedSource.asCharArray();
            SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glCreateShaderProgramv, (type, 1, &modifiedSourceAsCharArray), retVal);

            // If this failed, try the real version:
            callRealFunction = (0 == retVal);
        }
    }

    if (callRealFunction)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glCreateShaderProgramv, (type, count, strings), retVal);
    }

    // Log the creation of the new program:
    if (retVal != 0)
    {
        gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

        if (NULL != pCurrentThreadRenderContextMonitor)
        {
            gsProgramsAndShadersMonitor* progAndShaderMon = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
            GT_IF_WITH_ASSERT(progAndShaderMon != NULL)
            {
                progAndShaderMon->onProgramCreation(retVal, AP_GL_2_0_SHADING_OBJECT);
            }
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glCreateShaderProgramv);

    return retVal;
}

void APIENTRY glBindProgramPipeline(GLuint pipeline)
{
    SU_START_FUNCTION_WRAPPER(ap_glBindProgramPipeline);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glBindProgramPipeline, 1, OS_TOBJ_ID_GL_UINT_PARAMETER, pipeline);

    // Get the render context monitor:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();
    GT_IF_WITH_ASSERT(pCurrentThreadRenderContextMonitor != NULL)
    {
        // Pass the request to the pipelines monitor:
        gsPipelineMonitor& pipelinesMonitor = pCurrentThreadRenderContextMonitor->pipelinesMonitor();
        bool rc = pipelinesMonitor.BindProgramPipeline(pipeline);
        GT_ASSERT(rc);
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glBindProgramPipeline, (pipeline));

    SU_END_FUNCTION_WRAPPER(ap_glBindProgramPipeline);
}

void APIENTRY glDeleteProgramPipelines(GLsizei n, const GLuint* pipelines)
{
    SU_START_FUNCTION_WRAPPER(ap_glDeleteProgramPipelines);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glDeleteProgramPipelines, 2, OS_TOBJ_ID_GL_SIZEI_PARAMETER, n, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_UINT_PARAMETER, (int)n, pipelines);

    // Get the render context monitor:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();
    GT_IF_WITH_ASSERT(pCurrentThreadRenderContextMonitor != NULL)
    {
        // Pass the request to the pipelines monitor:
        gsPipelineMonitor& pipelinesMonitor = pCurrentThreadRenderContextMonitor->pipelinesMonitor();
        pipelinesMonitor.DeleteProgramPipelines(n, pipelines);
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glDeleteProgramPipelines, (n, pipelines));

    SU_END_FUNCTION_WRAPPER(ap_glDeleteProgramPipelines);
}

void APIENTRY glGenProgramPipelines(GLsizei n, GLuint* pipelines)
{
    SU_START_FUNCTION_WRAPPER(ap_glGenProgramPipelines);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGenProgramPipelines, 2, OS_TOBJ_ID_GL_SIZEI_PARAMETER, n, OS_TOBJ_ID_GL_P_UINT_PARAMETER, pipelines);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGenProgramPipelines, (n, pipelines));

    // Get the render context monitor:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();
    GT_IF_WITH_ASSERT(pCurrentThreadRenderContextMonitor != NULL)
    {
        // Now update the monitor with the values generated by the runtime.
        gsPipelineMonitor& pipelinesMonitor = pCurrentThreadRenderContextMonitor->pipelinesMonitor();
        pipelinesMonitor.GenProgramPipelines(n, pipelines);
    }

    SU_END_FUNCTION_WRAPPER(ap_glGenProgramPipelines);
}

GLboolean APIENTRY glIsProgramPipeline(GLuint pipeline)
{
    SU_START_FUNCTION_WRAPPER(ap_glIsProgramPipeline);

    GLboolean retVal = GL_FALSE;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glIsProgramPipeline, 1, OS_TOBJ_ID_GL_UINT_PARAMETER, pipeline);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glIsProgramPipeline, (pipeline), retVal);

    SU_END_FUNCTION_WRAPPER(ap_glIsProgramPipeline);

    return retVal;
}

void APIENTRY glGetProgramPipelineiv(GLuint pipeline, GLenum pname, GLint* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetProgramPipelineiv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetProgramPipelineiv, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, pipeline, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetProgramPipelineiv, (pipeline, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetProgramPipelineiv);
}

void APIENTRY glProgramUniform1i(GLuint program, GLint location, GLint v0)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniform1i);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniform1i, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_INT_PARAMETER, v0, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);

    // Check if stub shaders are forced:
    bool areShadersStubbed = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areShadersStubbed = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areShadersStubbed)
    {
        SU_CALL_EXTENSION_FUNC(glProgramUniform1i, (program, location, v0));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(program, location, GL_INT, (void*)&v0);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniform1i);
}

void APIENTRY glProgramUniform1iv(GLuint program, GLint location, GLsizei count, const GLint* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniform1iv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniform1iv, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_INT_PARAMETER, 1, value, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);

    // Check if stub shaders are forced:
    bool areShadersStubbed = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areShadersStubbed = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areShadersStubbed)
    {
        SU_CALL_EXTENSION_FUNC(glProgramUniform1iv, (program, location, count, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(program, location, GL_INT, (void*)value);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniform1iv);
}

void APIENTRY glProgramUniform1f(GLuint program, GLint location, GLfloat v0)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniform1f);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniform1f, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_FLOAT_PARAMETER, v0, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);

    // Check if stub shaders are forced:
    bool areShadersStubbed = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areShadersStubbed = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areShadersStubbed)
    {
        SU_CALL_EXTENSION_FUNC(glProgramUniform1f, (program, location, v0));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(program, location, GL_FLOAT, (void*)&v0);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniform1f);
}

void APIENTRY glProgramUniform1fv(GLuint program, GLint location, GLsizei count, const GLfloat* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniform1fv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniform1fv, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_FLOAT_PARAMETER, 1, value, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);

    // Check if stub shaders are forced:
    bool areShadersStubbed = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areShadersStubbed = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areShadersStubbed)
    {
        SU_CALL_EXTENSION_FUNC(glProgramUniform1fv, (program, location, count, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(program, location, GL_FLOAT, (void*)value);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniform1fv);
}

void APIENTRY glProgramUniform1d(GLuint program, GLint location, GLdouble v0)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniform1d);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniform1d, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, v0, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);

    // Check if stub shaders are forced:
    bool areShadersStubbed = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areShadersStubbed = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areShadersStubbed)
    {
        SU_CALL_EXTENSION_FUNC(glProgramUniform1d, (program, location, v0));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(program, location, GL_DOUBLE, (void*)&v0);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniform1d);
}

void APIENTRY glProgramUniform1dv(GLuint program, GLint location, GLsizei count, const GLdouble* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniform1dv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniform1dv, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, 1, value, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);

    // Check if stub shaders are forced:
    bool areShadersStubbed = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areShadersStubbed = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areShadersStubbed)
    {
        SU_CALL_EXTENSION_FUNC(glProgramUniform1dv, (program, location, count, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(program, location, GL_DOUBLE, (void*)value);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniform1dv);
}

void APIENTRY glProgramUniform1ui(GLuint program, GLint location, GLuint v0)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniform1ui);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniform1ui, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_UINT_PARAMETER, v0, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);

    // Check if stub shaders are forced:
    bool areShadersStubbed = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areShadersStubbed = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areShadersStubbed)
    {
        SU_CALL_EXTENSION_FUNC(glProgramUniform1ui, (program, location, v0));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(program, location, GL_UNSIGNED_INT, (void*)&v0);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniform1ui);
}

void APIENTRY glProgramUniform1uiv(GLuint program, GLint location, GLsizei count, const GLuint* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniform1uiv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniform1uiv, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_UINT_PARAMETER, 1, value, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);

    // Check if stub shaders are forced:
    bool areShadersStubbed = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areShadersStubbed = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areShadersStubbed)
    {
        SU_CALL_EXTENSION_FUNC(glProgramUniform1uiv, (program, location, count, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(program, location, GL_UNSIGNED_INT, (void*)value);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniform1uiv);
}

void APIENTRY glProgramUniform2i(GLuint program, GLint location, GLint v0, GLint v1)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniform2i);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniform2i, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_INT_PARAMETER, v0, OS_TOBJ_ID_GL_INT_PARAMETER, v1, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);

    // Check if stub shaders are forced:
    bool areShadersStubbed = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areShadersStubbed = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areShadersStubbed)
    {
        SU_CALL_EXTENSION_FUNC(glProgramUniform2i, (program, location, v0, v1));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            GLint values[2] = {v0, v1};
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(program, location, GL_INT_VEC2, (void*)values);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniform2i);
}

void APIENTRY glProgramUniform2iv(GLuint program, GLint location, GLsizei count, const GLint* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniform2iv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniform2iv, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_INT_PARAMETER, 2, value, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);

    // Check if stub shaders are forced:
    bool areShadersStubbed = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areShadersStubbed = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areShadersStubbed)
    {
        SU_CALL_EXTENSION_FUNC(glProgramUniform2iv, (program, location, count, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(program, location, GL_INT_VEC2, (void*)value);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniform2iv);
}

void APIENTRY glProgramUniform2f(GLuint program, GLint location, GLfloat v0, GLfloat v1)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniform2f);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniform2f, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_FLOAT_PARAMETER, v0, OS_TOBJ_ID_GL_FLOAT_PARAMETER, v1, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);

    // Check if stub shaders are forced:
    bool areShadersStubbed = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areShadersStubbed = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areShadersStubbed)
    {
        SU_CALL_EXTENSION_FUNC(glProgramUniform2f, (program, location, v0, v1));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            GLfloat values[2] = {v0, v1};
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(program, location, GL_FLOAT_VEC2, (void*)values);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniform2f);
}

void APIENTRY glProgramUniform2fv(GLuint program, GLint location, GLsizei count, const GLfloat* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniform2fv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniform2fv, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_FLOAT_PARAMETER, 2, value, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);

    // Check if stub shaders are forced:
    bool areShadersStubbed = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areShadersStubbed = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areShadersStubbed)
    {
        SU_CALL_EXTENSION_FUNC(glProgramUniform2fv, (program, location, count, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(program, location, GL_FLOAT_VEC2, (void*)value);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniform2fv);
}

void APIENTRY glProgramUniform2d(GLuint program, GLint location, GLdouble v0, GLdouble v1)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniform2d);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniform2d, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, v0, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, v1, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);

    // Check if stub shaders are forced:
    bool areShadersStubbed = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areShadersStubbed = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areShadersStubbed)
    {
        SU_CALL_EXTENSION_FUNC(glProgramUniform2d, (program, location, v0, v1));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            GLdouble values[2] = {v0, v1};
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(program, location, GL_DOUBLE_VEC2, (void*)values);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniform2d);
}

void APIENTRY glProgramUniform2dv(GLuint program, GLint location, GLsizei count, const GLdouble* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniform2dv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniform2dv, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, 2, value, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);

    // Check if stub shaders are forced:
    bool areShadersStubbed = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areShadersStubbed = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areShadersStubbed)
    {
        SU_CALL_EXTENSION_FUNC(glProgramUniform2dv, (program, location, count, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(program, location, GL_DOUBLE_VEC2, (void*)value);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniform2dv);
}

void APIENTRY glProgramUniform2ui(GLuint program, GLint location, GLuint v0, GLuint v1)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniform2ui);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniform2ui, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_UINT_PARAMETER, v0, OS_TOBJ_ID_GL_UINT_PARAMETER, v1, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);

    // Check if stub shaders are forced:
    bool areShadersStubbed = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areShadersStubbed = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areShadersStubbed)
    {
        SU_CALL_EXTENSION_FUNC(glProgramUniform2ui, (program, location, v0, v1));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            GLuint values[2] = {v0, v1};
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(program, location, GL_UNSIGNED_INT_VEC2, (void*)values);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniform2ui);
}

void APIENTRY glProgramUniform2uiv(GLuint program, GLint location, GLsizei count, const GLuint* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniform2uiv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniform2uiv, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_UINT_PARAMETER, 2, value, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);

    // Check if stub shaders are forced:
    bool areShadersStubbed = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areShadersStubbed = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areShadersStubbed)
    {
        SU_CALL_EXTENSION_FUNC(glProgramUniform2uiv, (program, location, count, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(program, location, GL_UNSIGNED_INT_VEC2, (void*)value);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniform2uiv);
}

void APIENTRY glProgramUniform3i(GLuint program, GLint location, GLint v0, GLint v1, GLint v2)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniform3i);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniform3i, 6, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_INT_PARAMETER, v0, OS_TOBJ_ID_GL_INT_PARAMETER, v1, OS_TOBJ_ID_GL_INT_PARAMETER, v2, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);

    // Check if stub shaders are forced:
    bool areShadersStubbed = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areShadersStubbed = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areShadersStubbed)
    {
        SU_CALL_EXTENSION_FUNC(glProgramUniform3i, (program, location, v0, v1, v2));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            GLint values[3] = {v0, v1, v2};
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(program, location, GL_INT_VEC3, (void*)values);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniform3i);
}

void APIENTRY glProgramUniform3iv(GLuint program, GLint location, GLsizei count, const GLint* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniform3iv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniform3iv, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_INT_PARAMETER, 3, value, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);

    // Check if stub shaders are forced:
    bool areShadersStubbed = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areShadersStubbed = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areShadersStubbed)
    {
        SU_CALL_EXTENSION_FUNC(glProgramUniform3iv, (program, location, count, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(program, location, GL_INT_VEC3, (void*)value);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniform3iv);
}

void APIENTRY glProgramUniform3f(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniform3f);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniform3f, 6, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_FLOAT_PARAMETER, v0, OS_TOBJ_ID_GL_FLOAT_PARAMETER, v1, OS_TOBJ_ID_GL_FLOAT_PARAMETER, v2, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);

    // Check if stub shaders are forced:
    bool areShadersStubbed = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areShadersStubbed = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areShadersStubbed)
    {
        SU_CALL_EXTENSION_FUNC(glProgramUniform3f, (program, location, v0, v1, v2));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            GLfloat values[3] = {v0, v1, v2};
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(program, location, GL_FLOAT_VEC3, (void*)values);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniform3f);
}

void APIENTRY glProgramUniform3fv(GLuint program, GLint location, GLsizei count, const GLfloat* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniform3fv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniform3fv, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_FLOAT_PARAMETER, 3, value, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);

    // Check if stub shaders are forced:
    bool areShadersStubbed = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areShadersStubbed = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areShadersStubbed)
    {
        SU_CALL_EXTENSION_FUNC(glProgramUniform3fv, (program, location, count, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(program, location, GL_FLOAT_VEC3, (void*)value);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniform3fv);
}

void APIENTRY glProgramUniform3d(GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniform3d);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniform3d, 6, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, v0, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, v1, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, v2, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);

    // Check if stub shaders are forced:
    bool areShadersStubbed = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areShadersStubbed = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areShadersStubbed)
    {
        SU_CALL_EXTENSION_FUNC(glProgramUniform3d, (program, location, v0, v1, v2));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            GLdouble values[3] = {v0, v1, v2};
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(program, location, GL_DOUBLE_VEC3, (void*)values);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniform3d);
}

void APIENTRY glProgramUniform3dv(GLuint program, GLint location, GLsizei count, const GLdouble* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniform3dv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniform3dv, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, 3, value, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);

    // Check if stub shaders are forced:
    bool areShadersStubbed = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areShadersStubbed = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areShadersStubbed)
    {
        SU_CALL_EXTENSION_FUNC(glProgramUniform3dv, (program, location, count, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(program, location, GL_DOUBLE_VEC3, (void*)value);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniform3dv);
}

void APIENTRY glProgramUniform3ui(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniform3ui);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniform3ui, 6, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_UINT_PARAMETER, v0, OS_TOBJ_ID_GL_UINT_PARAMETER, v1, OS_TOBJ_ID_GL_UINT_PARAMETER, v2, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);

    // Check if stub shaders are forced:
    bool areShadersStubbed = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areShadersStubbed = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areShadersStubbed)
    {
        SU_CALL_EXTENSION_FUNC(glProgramUniform3ui, (program, location, v0, v1, v2));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            GLuint values[] = {v0, v1, v2};
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(program, location, GL_UNSIGNED_INT_VEC3, (void*)values);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniform3ui);
}

void APIENTRY glProgramUniform3uiv(GLuint program, GLint location, GLsizei count, const GLuint* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniform3uiv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniform3uiv, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_UINT_PARAMETER, 3, value, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);

    // Check if stub shaders are forced:
    bool areShadersStubbed = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areShadersStubbed = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areShadersStubbed)
    {
        SU_CALL_EXTENSION_FUNC(glProgramUniform3uiv, (program, location, count, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(program, location, GL_UNSIGNED_INT_VEC3, (void*)value);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniform3uiv);
}

void APIENTRY glProgramUniform4i(GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniform4i);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniform4i, 7, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_INT_PARAMETER, v0, OS_TOBJ_ID_GL_INT_PARAMETER, v1, OS_TOBJ_ID_GL_INT_PARAMETER, v2, OS_TOBJ_ID_GL_INT_PARAMETER, v3, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);

    // Check if stub shaders are forced:
    bool areShadersStubbed = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areShadersStubbed = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areShadersStubbed)
    {
        SU_CALL_EXTENSION_FUNC(glProgramUniform4i, (program, location, v0, v1, v2, v3));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            GLint values[4] = {v0, v1, v2, v3};
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(program, location, GL_INT_VEC4, (void*)values);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniform4i);
}

void APIENTRY glProgramUniform4iv(GLuint program, GLint location, GLsizei count, const GLint* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniform4iv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniform4iv, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_INT_PARAMETER, 4, value, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);

    // Check if stub shaders are forced:
    bool areShadersStubbed = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areShadersStubbed = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areShadersStubbed)
    {
        SU_CALL_EXTENSION_FUNC(glProgramUniform4iv, (program, location, count, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(program, location, GL_INT_VEC4, (void*)value);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniform4iv);
}

void APIENTRY glProgramUniform4f(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniform4f);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniform4f, 7, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_FLOAT_PARAMETER, v0, OS_TOBJ_ID_GL_FLOAT_PARAMETER, v1, OS_TOBJ_ID_GL_FLOAT_PARAMETER, v2, OS_TOBJ_ID_GL_FLOAT_PARAMETER, v3, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);

    // Check if stub shaders are forced:
    bool areShadersStubbed = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areShadersStubbed = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areShadersStubbed)
    {
        SU_CALL_EXTENSION_FUNC(glProgramUniform4f, (program, location, v0, v1, v2, v3));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            GLfloat values[4] = {v0, v1, v2, v3};
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(program, location, GL_FLOAT_VEC4, (void*)values);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniform4f);
}

void APIENTRY glProgramUniform4fv(GLuint program, GLint location, GLsizei count, const GLfloat* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniform4fv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniform4fv, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_FLOAT_PARAMETER, 4, value, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);

    // Check if stub shaders are forced:
    bool areShadersStubbed = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areShadersStubbed = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areShadersStubbed)
    {
        SU_CALL_EXTENSION_FUNC(glProgramUniform4fv, (program, location, count, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(program, location, GL_FLOAT_VEC4, (void*)value);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniform4fv);
}

void APIENTRY glProgramUniform4d(GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2, GLdouble v3)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniform4d);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniform4d, 7, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, v0, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, v1, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, v2, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, v3, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);

    // Check if stub shaders are forced:
    bool areShadersStubbed = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areShadersStubbed = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areShadersStubbed)
    {
        SU_CALL_EXTENSION_FUNC(glProgramUniform4d, (program, location, v0, v1, v2, v3));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            GLdouble values[4] = {v0, v1, v2, v3};
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(program, location, GL_DOUBLE_VEC4, (void*)values);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniform4d);
}

void APIENTRY glProgramUniform4dv(GLuint program, GLint location, GLsizei count, const GLdouble* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniform4dv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniform4dv, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, 4, value, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);

    // Check if stub shaders are forced:
    bool areShadersStubbed = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areShadersStubbed = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areShadersStubbed)
    {
        SU_CALL_EXTENSION_FUNC(glProgramUniform4dv, (program, location, count, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(program, location, GL_DOUBLE_VEC4, (void*)value);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniform4dv);
}

void APIENTRY glProgramUniform4ui(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniform4ui);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniform4ui, 7, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_UINT_PARAMETER, v0, OS_TOBJ_ID_GL_UINT_PARAMETER, v1, OS_TOBJ_ID_GL_UINT_PARAMETER, v2, OS_TOBJ_ID_GL_UINT_PARAMETER, v3, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);

    // Check if stub shaders are forced:
    bool areShadersStubbed = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areShadersStubbed = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areShadersStubbed)
    {
        SU_CALL_EXTENSION_FUNC(glProgramUniform4ui, (program, location, v0, v1, v2, v3));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            GLuint values[4] = {v0, v1, v2, v3};
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(program, location, GL_UNSIGNED_INT_VEC4, (void*)values);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniform4ui);
}

void APIENTRY glProgramUniform4uiv(GLuint program, GLint location, GLsizei count, const GLuint* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniform4uiv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniform4uiv, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_UINT_PARAMETER, 4, value, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);

    // Check if stub shaders are forced:
    bool areShadersStubbed = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areShadersStubbed = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areShadersStubbed)
    {
        SU_CALL_EXTENSION_FUNC(glProgramUniform4uiv, (program, location, count, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(program, location, GL_UNSIGNED_INT_VEC4, (void*)value);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniform4uiv);
}

void APIENTRY glProgramUniformMatrix2fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniformMatrix2fv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniformMatrix2fv, 6, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_BOOL_PARAMETER, transpose, OS_TOBJ_ID_MATRIX_PARAMETER, OS_TOBJ_ID_GL_FLOAT_PARAMETER, 2, 2, value, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);

    // Check if stub shaders are forced:
    bool areShadersStubbed = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areShadersStubbed = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areShadersStubbed)
    {
        SU_CALL_EXTENSION_FUNC(glProgramUniformMatrix2fv, (program, location, count, transpose, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(program, location, GL_FLOAT_MAT2, (void*)value, (transpose == GL_TRUE));
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniformMatrix2fv);
}

void APIENTRY glProgramUniformMatrix3fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniformMatrix3fv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniformMatrix3fv, 6, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_BOOL_PARAMETER, transpose, OS_TOBJ_ID_MATRIX_PARAMETER, OS_TOBJ_ID_GL_FLOAT_PARAMETER, 3, 3, value, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);

    // Check if stub shaders are forced:
    bool areShadersStubbed = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areShadersStubbed = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areShadersStubbed)
    {
        SU_CALL_EXTENSION_FUNC(glProgramUniformMatrix3fv, (program, location, count, transpose, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(program, location, GL_FLOAT_MAT3, (void*)value, (transpose == GL_TRUE));
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniformMatrix3fv);
}

void APIENTRY glProgramUniformMatrix4fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniformMatrix4fv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniformMatrix4fv, 6, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_BOOL_PARAMETER, transpose, OS_TOBJ_ID_MATRIX_PARAMETER, OS_TOBJ_ID_GL_FLOAT_PARAMETER, 4, 4, value, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);

    // Check if stub shaders are forced:
    bool areShadersStubbed = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areShadersStubbed = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areShadersStubbed)
    {
        SU_CALL_EXTENSION_FUNC(glProgramUniformMatrix4fv, (program, location, count, transpose, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(program, location, GL_FLOAT_MAT4, (void*)value, (transpose == GL_TRUE));
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniformMatrix4fv);
}

void APIENTRY glProgramUniformMatrix2dv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniformMatrix2dv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniformMatrix2dv, 6, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_BOOL_PARAMETER, transpose, OS_TOBJ_ID_MATRIX_PARAMETER, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, 2, 2, value, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);

    // Check if stub shaders are forced:
    bool areShadersStubbed = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areShadersStubbed = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areShadersStubbed)
    {
        SU_CALL_EXTENSION_FUNC(glProgramUniformMatrix2dv, (program, location, count, transpose, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(program, location, GL_DOUBLE_MAT2, (void*)value, (transpose == GL_TRUE));
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniformMatrix2dv);
}

void APIENTRY glProgramUniformMatrix3dv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniformMatrix3dv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniformMatrix3dv, 6, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_BOOL_PARAMETER, transpose, OS_TOBJ_ID_MATRIX_PARAMETER, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, 3, 3, value, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);

    // Check if stub shaders are forced:
    bool areShadersStubbed = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areShadersStubbed = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areShadersStubbed)
    {
        SU_CALL_EXTENSION_FUNC(glProgramUniformMatrix3dv, (program, location, count, transpose, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(program, location, GL_DOUBLE_MAT3, (void*)value, (transpose == GL_TRUE));
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniformMatrix3dv);
}

void APIENTRY glProgramUniformMatrix4dv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniformMatrix4dv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniformMatrix4dv, 6, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_BOOL_PARAMETER, transpose, OS_TOBJ_ID_MATRIX_PARAMETER, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, 4, 4, value, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);

    // Check if stub shaders are forced:
    bool areShadersStubbed = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areShadersStubbed = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areShadersStubbed)
    {
        SU_CALL_EXTENSION_FUNC(glProgramUniformMatrix4dv, (program, location, count, transpose, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(program, location, GL_DOUBLE_MAT4, (void*)value, (transpose == GL_TRUE));
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniformMatrix4dv);
}

void APIENTRY glProgramUniformMatrix2x3fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniformMatrix2x3fv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniformMatrix2x3fv, 6, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_BOOL_PARAMETER, transpose, OS_TOBJ_ID_MATRIX_PARAMETER, OS_TOBJ_ID_GL_FLOAT_PARAMETER, 2, 3, value, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);

    // Check if stub shaders are forced:
    bool areShadersStubbed = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areShadersStubbed = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areShadersStubbed)
    {
        SU_CALL_EXTENSION_FUNC(glProgramUniformMatrix2x3fv, (program, location, count, transpose, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(program, location, GL_FLOAT_MAT2x3, (void*)value, (transpose == GL_TRUE));
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniformMatrix2x3fv);
}

void APIENTRY glProgramUniformMatrix3x2fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniformMatrix3x2fv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniformMatrix3x2fv, 6, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_BOOL_PARAMETER, transpose, OS_TOBJ_ID_MATRIX_PARAMETER, OS_TOBJ_ID_GL_FLOAT_PARAMETER, 3, 2, value, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);

    // Check if stub shaders are forced:
    bool areShadersStubbed = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areShadersStubbed = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areShadersStubbed)
    {
        SU_CALL_EXTENSION_FUNC(glProgramUniformMatrix3x2fv, (program, location, count, transpose, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(program, location, GL_FLOAT_MAT3x2, (void*)value, (transpose == GL_TRUE));
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniformMatrix3x2fv);
}

void APIENTRY glProgramUniformMatrix2x4fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniformMatrix2x4fv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniformMatrix2x4fv, 6, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_BOOL_PARAMETER, transpose, OS_TOBJ_ID_MATRIX_PARAMETER, OS_TOBJ_ID_GL_FLOAT_PARAMETER, 2, 4, value, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);

    // Check if stub shaders are forced:
    bool areShadersStubbed = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areShadersStubbed = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areShadersStubbed)
    {
        SU_CALL_EXTENSION_FUNC(glProgramUniformMatrix2x4fv, (program, location, count, transpose, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(program, location, GL_FLOAT_MAT2x4, (void*)value, (transpose == GL_TRUE));
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniformMatrix2x4fv);
}

void APIENTRY glProgramUniformMatrix4x2fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniformMatrix4x2fv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniformMatrix4x2fv, 6, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_BOOL_PARAMETER, transpose, OS_TOBJ_ID_MATRIX_PARAMETER, OS_TOBJ_ID_GL_FLOAT_PARAMETER, 4, 2, value, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);

    // Check if stub shaders are forced:
    bool areShadersStubbed = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areShadersStubbed = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areShadersStubbed)
    {
        SU_CALL_EXTENSION_FUNC(glProgramUniformMatrix4x2fv, (program, location, count, transpose, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(program, location, GL_FLOAT_MAT4x2, (void*)value, (transpose == GL_TRUE));
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniformMatrix4x2fv);
}

void APIENTRY glProgramUniformMatrix3x4fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniformMatrix3x4fv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniformMatrix3x4fv, 6, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_BOOL_PARAMETER, transpose, OS_TOBJ_ID_MATRIX_PARAMETER, OS_TOBJ_ID_GL_FLOAT_PARAMETER, 3, 4, value, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);

    // Check if stub shaders are forced:
    bool areShadersStubbed = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areShadersStubbed = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areShadersStubbed)
    {
        SU_CALL_EXTENSION_FUNC(glProgramUniformMatrix3x4fv, (program, location, count, transpose, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(program, location, GL_FLOAT_MAT3x4, (void*)value, (transpose == GL_TRUE));
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniformMatrix3x4fv);
}

void APIENTRY glProgramUniformMatrix4x3fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniformMatrix4x3fv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniformMatrix4x3fv, 6, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_BOOL_PARAMETER, transpose, OS_TOBJ_ID_MATRIX_PARAMETER, OS_TOBJ_ID_GL_FLOAT_PARAMETER, 4, 3, value, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);

    // Check if stub shaders are forced:
    bool areShadersStubbed = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areShadersStubbed = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areShadersStubbed)
    {
        SU_CALL_EXTENSION_FUNC(glProgramUniformMatrix4x3fv, (program, location, count, transpose, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(program, location, GL_FLOAT_MAT4x3, (void*)value, (transpose == GL_TRUE));
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniformMatrix4x3fv);
}

void APIENTRY glProgramUniformMatrix2x3dv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniformMatrix2x3dv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniformMatrix2x3dv, 6, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_BOOL_PARAMETER, transpose, OS_TOBJ_ID_MATRIX_PARAMETER, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, 2, 3, value, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);

    // Check if stub shaders are forced:
    bool areShadersStubbed = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areShadersStubbed = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areShadersStubbed)
    {
        SU_CALL_EXTENSION_FUNC(glProgramUniformMatrix2x3dv, (program, location, count, transpose, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(program, location, GL_DOUBLE_MAT2x3, (void*)value, (transpose == GL_TRUE));
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniformMatrix2x3dv);
}

void APIENTRY glProgramUniformMatrix3x2dv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniformMatrix3x2dv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniformMatrix3x2dv, 6, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_BOOL_PARAMETER, transpose, OS_TOBJ_ID_MATRIX_PARAMETER, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, 3, 2, value, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);

    // Check if stub shaders are forced:
    bool areShadersStubbed = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areShadersStubbed = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areShadersStubbed)
    {
        SU_CALL_EXTENSION_FUNC(glProgramUniformMatrix3x2dv, (program, location, count, transpose, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(program, location, GL_DOUBLE_MAT3x2, (void*)value, (transpose == GL_TRUE));
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniformMatrix3x2dv);
}

void APIENTRY glProgramUniformMatrix2x4dv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniformMatrix2x4dv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniformMatrix2x4dv, 6, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_BOOL_PARAMETER, transpose, OS_TOBJ_ID_MATRIX_PARAMETER, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, 2, 4, value, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);

    // Check if stub shaders are forced:
    bool areShadersStubbed = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areShadersStubbed = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areShadersStubbed)
    {
        SU_CALL_EXTENSION_FUNC(glProgramUniformMatrix2x4dv, (program, location, count, transpose, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(program, location, GL_DOUBLE_MAT2x4, (void*)value, (transpose == GL_TRUE));
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniformMatrix2x4dv);
}

void APIENTRY glProgramUniformMatrix4x2dv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniformMatrix4x2dv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniformMatrix4x2dv, 6, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_BOOL_PARAMETER, transpose, OS_TOBJ_ID_MATRIX_PARAMETER, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, 4, 2, value, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);

    // Check if stub shaders are forced:
    bool areShadersStubbed = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areShadersStubbed = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areShadersStubbed)
    {
        SU_CALL_EXTENSION_FUNC(glProgramUniformMatrix4x2dv, (program, location, count, transpose, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(program, location, GL_DOUBLE_MAT4x2, (void*)value, (transpose == GL_TRUE));
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniformMatrix4x2dv);
}

void APIENTRY glProgramUniformMatrix3x4dv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniformMatrix3x4dv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniformMatrix3x4dv, 6, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_BOOL_PARAMETER, transpose, OS_TOBJ_ID_MATRIX_PARAMETER, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, 3, 4, value, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);

    // Check if stub shaders are forced:
    bool areShadersStubbed = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areShadersStubbed = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areShadersStubbed)
    {
        SU_CALL_EXTENSION_FUNC(glProgramUniformMatrix3x4dv, (program, location, count, transpose, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(program, location, GL_DOUBLE_MAT3x4, (void*)value, (transpose == GL_TRUE));
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniformMatrix3x4dv);
}

void APIENTRY glProgramUniformMatrix4x3dv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniformMatrix4x3dv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniformMatrix4x3dv, 6, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_BOOL_PARAMETER, transpose, OS_TOBJ_ID_MATRIX_PARAMETER, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, 4, 3, value, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);

    // Check if stub shaders are forced:
    bool areShadersStubbed = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areShadersStubbed = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areShadersStubbed)
    {
        SU_CALL_EXTENSION_FUNC(glProgramUniformMatrix4x3dv, (program, location, count, transpose, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(program, location, GL_DOUBLE_MAT4x3, (void*)value, (transpose == GL_TRUE));
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniformMatrix4x3dv);
}

void APIENTRY glValidateProgramPipeline(GLuint pipeline)
{
    SU_START_FUNCTION_WRAPPER(ap_glValidateProgramPipeline);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glValidateProgramPipeline, 1, OS_TOBJ_ID_GL_UINT_PARAMETER, pipeline);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glValidateProgramPipeline, (pipeline));

    SU_END_FUNCTION_WRAPPER(ap_glValidateProgramPipeline);
}

void APIENTRY glGetProgramPipelineInfoLog(GLuint pipeline, GLsizei bufSize, GLsizei* length, GLchar* infoLog)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetProgramPipelineInfoLog);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetProgramPipelineInfoLog, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, pipeline, OS_TOBJ_ID_GL_SIZEI_PARAMETER, bufSize, OS_TOBJ_ID_GL_P_SIZEI_PARAMETER, length, OS_TOBJ_ID_GL_P_CHAR, infoLog);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetProgramPipelineInfoLog, (pipeline, bufSize, length, infoLog));

    SU_END_FUNCTION_WRAPPER(ap_glGetProgramPipelineInfoLog);
}

void APIENTRY glVertexAttribL1d(GLuint index, GLdouble x)
{
    SU_START_FUNCTION_WRAPPER(ap_glVertexAttribL1d);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttribL1d, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, x);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttribL1d, (index, x));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttribL1d);
}

void APIENTRY glVertexAttribL2d(GLuint index, GLdouble x, GLdouble y)
{
    SU_START_FUNCTION_WRAPPER(ap_glVertexAttribL2d);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttribL2d, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, x, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, y);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttribL2d, (index, x, y));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttribL2d);
}

void APIENTRY glVertexAttribL3d(GLuint index, GLdouble x, GLdouble y, GLdouble z)
{
    SU_START_FUNCTION_WRAPPER(ap_glVertexAttribL3d);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttribL3d, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, x, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, y, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, z);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttribL3d, (index, x, y, z));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttribL3d);
}

void APIENTRY glVertexAttribL4d(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w)
{
    SU_START_FUNCTION_WRAPPER(ap_glVertexAttribL4d);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttribL4d, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, x, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, y, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, z, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, w);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttribL4d, (index, x, y, z, w));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttribL4d);
}

void APIENTRY glVertexAttribL1dv(GLuint index, const GLdouble* v)
{
    SU_START_FUNCTION_WRAPPER(ap_glVertexAttribL1dv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttribL1dv, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, 1, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttribL1dv, (index, v));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttribL1dv);
}

void APIENTRY glVertexAttribL2dv(GLuint index, const GLdouble* v)
{
    SU_START_FUNCTION_WRAPPER(ap_glVertexAttribL2dv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttribL2dv, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, 2, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttribL2dv, (index, v));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttribL2dv);
}

void APIENTRY glVertexAttribL3dv(GLuint index, const GLdouble* v)
{
    SU_START_FUNCTION_WRAPPER(ap_glVertexAttribL3dv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttribL3dv, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, 3, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttribL3dv, (index, v));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttribL3dv);
}

void APIENTRY glVertexAttribL4dv(GLuint index, const GLdouble* v)
{
    SU_START_FUNCTION_WRAPPER(ap_glVertexAttribL4dv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttribL4dv, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, 4, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttribL4dv, (index, v));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttribL4dv);
}

void APIENTRY glVertexAttribLPointer(GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid* pointer)
{
    SU_START_FUNCTION_WRAPPER(ap_glVertexAttribLPointer);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttribLPointer, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_INT_PARAMETER, size, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_SIZEI_PARAMETER, stride, OS_TOBJ_ID_POINTER_PARAMETER, pointer);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttribLPointer, (index, size, type, stride, pointer));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttribLPointer);
}

void APIENTRY glGetVertexAttribLdv(GLuint index, GLenum pname, GLdouble* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetVertexAttribLdv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetVertexAttribLdv, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_DOUBLE_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetVertexAttribLdv, (index, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetVertexAttribLdv);
}

void APIENTRY glViewportArrayv(GLuint first, GLsizei count, const GLfloat* v)
{
    SU_START_FUNCTION_WRAPPER(ap_glViewportArrayv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glViewportArrayv, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, first, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_MATRIX_PARAMETER, OS_TOBJ_ID_GL_FLOAT_PARAMETER, 4, (int)count, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glViewportArrayv, (first, count, v));

    SU_END_FUNCTION_WRAPPER(ap_glViewportArrayv);
}

void APIENTRY glViewportIndexedf(GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h)
{
    SU_START_FUNCTION_WRAPPER(ap_glViewportIndexedf);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glViewportIndexedf, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_FLOAT_PARAMETER, x, OS_TOBJ_ID_GL_FLOAT_PARAMETER, y, OS_TOBJ_ID_GL_FLOAT_PARAMETER, w, OS_TOBJ_ID_GL_FLOAT_PARAMETER, h);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glViewportIndexedf, (index, x, y, w, h));

    SU_END_FUNCTION_WRAPPER(ap_glViewportIndexedf);
}

void APIENTRY glViewportIndexedfv(GLuint index, const GLfloat* v)
{
    SU_START_FUNCTION_WRAPPER(ap_glViewportIndexedfv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glViewportIndexedfv, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_FLOAT_PARAMETER, 4, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glViewportIndexedfv, (index, v));

    SU_END_FUNCTION_WRAPPER(ap_glViewportIndexedfv);
}

void APIENTRY glScissorArrayv(GLuint first, GLsizei count, const GLint* v)
{
    SU_START_FUNCTION_WRAPPER(ap_glScissorArrayv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glScissorArrayv, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, first, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_MATRIX_PARAMETER, OS_TOBJ_ID_GL_INT_PARAMETER, 4, (int)count, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glScissorArrayv, (first, count, v));

    SU_END_FUNCTION_WRAPPER(ap_glScissorArrayv);
}

void APIENTRY glScissorIndexed(GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height)
{
    SU_START_FUNCTION_WRAPPER(ap_glScissorIndexed);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glScissorIndexed, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_INT_PARAMETER, left, OS_TOBJ_ID_GL_INT_PARAMETER, bottom, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_SIZEI_PARAMETER, height);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glScissorIndexed, (index, left, bottom, width, height));

    SU_END_FUNCTION_WRAPPER(ap_glScissorIndexed);
}

void APIENTRY glScissorIndexedv(GLuint index, const GLint* v)
{
    SU_START_FUNCTION_WRAPPER(ap_glScissorIndexedv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glScissorIndexedv, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_INT_PARAMETER, 4, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glScissorIndexedv, (index, v));

    SU_END_FUNCTION_WRAPPER(ap_glScissorIndexedv);
}

void APIENTRY glDepthRangeArrayv(GLuint first, GLsizei count, const GLdouble* v)
{
    SU_START_FUNCTION_WRAPPER(ap_glDepthRangeArrayv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glDepthRangeArrayv, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, first, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_MATRIX_PARAMETER, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, 2, (int)count, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glDepthRangeArrayv, (first, count, v));

    SU_END_FUNCTION_WRAPPER(ap_glDepthRangeArrayv);
}

void APIENTRY glDepthRangeIndexed(GLuint index, GLdouble n, GLdouble f)
{
    SU_START_FUNCTION_WRAPPER(ap_glDepthRangeIndexed);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glDepthRangeIndexed, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, n, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, f);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glDepthRangeIndexed, (index, n, f));

    SU_END_FUNCTION_WRAPPER(ap_glDepthRangeIndexed);
}

void APIENTRY glGetFloati_v(GLenum target, GLuint index, GLfloat* data)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetFloati_v);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetFloati_v, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, data);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetFloati_v, (target, index, data));

    SU_END_FUNCTION_WRAPPER(ap_glGetFloati_v);
}

void APIENTRY glGetDoublei_v(GLenum target, GLuint index, GLdouble* data)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetDoublei_v);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetDoublei_v, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_P_DOUBLE_PARAMETER, data);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetDoublei_v, (target, index, data));

    SU_END_FUNCTION_WRAPPER(ap_glGetDoublei_v);
}


//////////////////////////////////////////////////////////////////////////
// OpenGL 4.2
//////////////////////////////////////////////////////////////////////////
void APIENTRY glDrawArraysInstancedBaseInstance(GLenum mode, GLint first, GLsizei count, GLsizei instancecount, GLuint baseinstance)
{
    SU_START_FUNCTION_WRAPPER(ap_glDrawArraysInstancedBaseInstance);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glDrawArraysInstancedBaseInstance, 5, OS_TOBJ_ID_GL_PRIMITIVE_TYPE_PARAMETER, mode, OS_TOBJ_ID_GL_INT_PARAMETER, first, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_SIZEI_PARAMETER, instancecount, OS_TOBJ_ID_GL_UINT_PARAMETER, baseinstance);

    // Get the current render context monitor:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        // Get the render primitives statistics logger:
        gsRenderPrimitivesStatisticsLogger& renderPrimitivesStatisticsLogger = pCurrentThreadRenderContextMonitor->renderPrimitivesStatisticsLogger();

        // Log this draw primitives function call:
        renderPrimitivesStatisticsLogger.onDrawArraysInstanced(count, instancecount, mode);
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glDrawArraysInstancedBaseInstance, (mode, first, count, instancecount, baseinstance));

    SU_END_FUNCTION_WRAPPER(ap_glDrawArraysInstancedBaseInstance);
}

void APIENTRY glDrawElementsInstancedBaseInstance(GLenum mode, GLsizei count, GLenum type, const void* indices, GLsizei instancecount, GLuint baseinstance)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glDrawElementsInstancedBaseInstance);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glDrawElementsInstancedBaseInstance, 6, OS_TOBJ_ID_GL_PRIMITIVE_TYPE_PARAMETER, mode, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_POINTER_PARAMETER, indices, OS_TOBJ_ID_GL_SIZEI_PARAMETER, instancecount, OS_TOBJ_ID_GL_UINT_PARAMETER, baseinstance);

    // Get the current render context monitor:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (pCurrentThreadRenderContextMonitor != NULL)
    {
        // Get the render primitives statistics logger:
        gsRenderPrimitivesStatisticsLogger& renderPrimitivesStatisticsLogger = pCurrentThreadRenderContextMonitor->renderPrimitivesStatisticsLogger();

        // Log this draw primitives function call:
        renderPrimitivesStatisticsLogger.onDrawElementsInstanced(count, mode, type, instancecount);
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glDrawElementsInstancedBaseInstance, (mode, count, type, indices, instancecount, baseinstance));

    SU_END_FUNCTION_WRAPPER(ap_glDrawElementsInstancedBaseInstance);
}

void APIENTRY glDrawElementsInstancedBaseVertexBaseInstance(GLenum mode, GLsizei count, GLenum type, const void* indices, GLsizei instancecount, GLint basevertex, GLuint baseinstance)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glDrawElementsInstancedBaseVertexBaseInstance);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glDrawElementsInstancedBaseVertexBaseInstance, 7, OS_TOBJ_ID_GL_PRIMITIVE_TYPE_PARAMETER, mode, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_POINTER_PARAMETER, indices, OS_TOBJ_ID_GL_SIZEI_PARAMETER, instancecount, OS_TOBJ_ID_GL_INT_PARAMETER, basevertex, OS_TOBJ_ID_GL_UINT_PARAMETER, baseinstance);

    // Get the current render context monitor:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (pCurrentThreadRenderContextMonitor != NULL)
    {
        // Get the render primitives statistics logger:
        gsRenderPrimitivesStatisticsLogger& renderPrimitivesStatisticsLogger = pCurrentThreadRenderContextMonitor->renderPrimitivesStatisticsLogger();

        // Log this draw primitives function call:
        renderPrimitivesStatisticsLogger.onDrawElementsInstanced(count, mode, type, instancecount);
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glDrawElementsInstancedBaseVertexBaseInstance, (mode, count, type, indices, instancecount, basevertex, baseinstance));

    SU_END_FUNCTION_WRAPPER(ap_glDrawElementsInstancedBaseVertexBaseInstance);
}

void APIENTRY glGetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetInternalformativ);

    // Log the call to this function:
    GLuint boundTextureName = gs_stat_openGLMonitorInstance.boundTexture(target);
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetInternalformativ, 6, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, internalformat, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_SIZEI_PARAMETER, bufSize, OS_TOBJ_ID_GL_P_INT_PARAMETER, params, OS_TOBJ_ID_ASSOCIATED_TEXTURE_NAMES_PSEUDO_PARAMETER, 1, &boundTextureName);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetInternalformativ, (target, internalformat, pname, bufSize, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetInternalformativ);
}

void APIENTRY glGetActiveAtomicCounterBufferiv(GLuint program, GLuint bufferIndex, GLenum pname, GLint* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetActiveAtomicCounterBufferiv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetActiveAtomicCounterBufferiv, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_UINT_PARAMETER, bufferIndex, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_PARAMETER, params, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetActiveAtomicCounterBufferiv, (program, bufferIndex, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetActiveAtomicCounterBufferiv);
}

void APIENTRY glBindImageTexture(GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format)
{
    SU_START_FUNCTION_WRAPPER(ap_glBindImageTexture);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glBindImageTexture, 8, OS_TOBJ_ID_GL_UINT_PARAMETER, unit, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_BOOL_PARAMETER, layered, OS_TOBJ_ID_GL_INT_PARAMETER, layer, OS_TOBJ_ID_GL_ENUM_PARAMETER, access, OS_TOBJ_ID_GL_ENUM_PARAMETER, format, OS_TOBJ_ID_ASSOCIATED_TEXTURE_NAMES_PSEUDO_PARAMETER, 1, &texture);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glBindImageTexture, (unit, texture, level, layered, layer, access, format));

    SU_END_FUNCTION_WRAPPER(ap_glBindImageTexture);
}

void APIENTRY glMemoryBarrier(GLbitfield barriers)
{
    SU_START_FUNCTION_WRAPPER(ap_glMemoryBarrier);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMemoryBarrier, 1, OS_TOBJ_ID_GL_BITFIELD_PARAMETER, barriers);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMemoryBarrier, (barriers));

    SU_END_FUNCTION_WRAPPER(ap_glMemoryBarrier);
}

void APIENTRY glTexStorage1D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width)
{
    SU_START_FUNCTION_WRAPPER(ap_glTexStorage1D);

    // Log the call to this function:
    GLuint boundTextureName = gs_stat_openGLMonitorInstance.boundTexture(target);
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTexStorage1D, 5, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_SIZEI_PARAMETER, levels, OS_TOBJ_ID_GL_ENUM_PARAMETER, internalformat, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_ASSOCIATED_TEXTURE_NAMES_PSEUDO_PARAMETER, 1, &boundTextureName);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glTexStorage1D, (target, levels, internalformat, width));

    // Log the texture storage setting:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (pCurrentThreadRenderContextMonitor)
    {
        bool rcTex = pCurrentThreadRenderContextMonitor->onTextureStorageSet(target, levels, internalformat, width, 0, 0);
        GT_ASSERT(rcTex);
    }

    SU_END_FUNCTION_WRAPPER(ap_glTexStorage1D);
}

void APIENTRY glTexStorage2D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height)
{
    SU_START_FUNCTION_WRAPPER(ap_glTexStorage2D);

    // Log the call to this function:
    GLuint boundTextureName = gs_stat_openGLMonitorInstance.boundTexture(target);
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTexStorage2D, 6, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_SIZEI_PARAMETER, levels, OS_TOBJ_ID_GL_ENUM_PARAMETER, internalformat, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_SIZEI_PARAMETER, height, OS_TOBJ_ID_ASSOCIATED_TEXTURE_NAMES_PSEUDO_PARAMETER, 1, &boundTextureName);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glTexStorage2D, (target, levels, internalformat, width, height));

    // Log the texture storage setting:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (pCurrentThreadRenderContextMonitor)
    {
        bool rcTex = pCurrentThreadRenderContextMonitor->onTextureStorageSet(target, levels, internalformat, width, height, 0);
        GT_ASSERT(rcTex);
    }

    SU_END_FUNCTION_WRAPPER(ap_glTexStorage2D);
}

void APIENTRY glTexStorage3D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
{
    SU_START_FUNCTION_WRAPPER(ap_glTexStorage3D);

    // Log the call to this function:
    GLuint boundTextureName = gs_stat_openGLMonitorInstance.boundTexture(target);
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTexStorage3D, 7, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_SIZEI_PARAMETER, levels, OS_TOBJ_ID_GL_ENUM_PARAMETER, internalformat, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_SIZEI_PARAMETER, height, OS_TOBJ_ID_GL_SIZEI_PARAMETER, depth, OS_TOBJ_ID_ASSOCIATED_TEXTURE_NAMES_PSEUDO_PARAMETER, 1, &boundTextureName);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glTexStorage3D, (target, levels, internalformat, width, height, depth));

    // Log the texture storage setting:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (pCurrentThreadRenderContextMonitor)
    {
        bool rcTex = pCurrentThreadRenderContextMonitor->onTextureStorageSet(target, levels, internalformat, width, height, depth);
        GT_ASSERT(rcTex);
    }

    SU_END_FUNCTION_WRAPPER(ap_glTexStorage3D);
}

void APIENTRY glDrawTransformFeedbackInstanced(GLenum mode, GLuint id, GLsizei instancecount)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glDrawTransformFeedbackInstanced);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glDrawTransformFeedbackInstanced, 3, OS_TOBJ_ID_GL_PRIMITIVE_TYPE_PARAMETER, mode, OS_TOBJ_ID_GL_UINT_PARAMETER, id, OS_TOBJ_ID_GL_SIZEI_PARAMETER, instancecount);

    // Get the current render context monitor:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (pCurrentThreadRenderContextMonitor != NULL)
    {
        // TO_DO: OpenGL 4.0 - we need to get the count from the transform feedback object #0 before we can log this:

        /*
        // Get the render primitives statistics logger:
        gsRenderPrimitivesStatisticsLogger& renderPrimitivesStatisticsLogger = pCurrentThreadRenderContextMonitor->renderPrimitivesStatisticsLogger();

        // Log this draw primitives function call:
        renderPrimitivesStatisticsLogger.onDrawArraysInstanced(count, instancecount, mode);
        */
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glDrawTransformFeedbackInstanced, (mode, id, instancecount));

    SU_END_FUNCTION_WRAPPER(ap_glDrawTransformFeedbackInstanced);
}

void APIENTRY glDrawTransformFeedbackStreamInstanced(GLenum mode, GLuint id, GLuint stream, GLsizei instancecount)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glDrawTransformFeedbackStreamInstanced);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glDrawTransformFeedbackStreamInstanced, 4, OS_TOBJ_ID_GL_PRIMITIVE_TYPE_PARAMETER, mode, OS_TOBJ_ID_GL_UINT_PARAMETER, id, OS_TOBJ_ID_GL_UINT_PARAMETER, stream, OS_TOBJ_ID_GL_SIZEI_PARAMETER, instancecount);

    // Get the current render context monitor:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (pCurrentThreadRenderContextMonitor != NULL)
    {
        // TO_DO: OpenGL 4.0 - we need to get the count from the transform feedback object #stream before we can log this:

        /*
        // Get the render primitives statistics logger:
        gsRenderPrimitivesStatisticsLogger& renderPrimitivesStatisticsLogger = pCurrentThreadRenderContextMonitor->renderPrimitivesStatisticsLogger();

        // Log this draw primitives function call:
        renderPrimitivesStatisticsLogger.onDrawArraysInstanced(count, instancecount, mode);
        */
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glDrawTransformFeedbackStreamInstanced, (mode, id, stream, instancecount));

    SU_END_FUNCTION_WRAPPER(ap_glDrawTransformFeedbackStreamInstanced);
}


//////////////////////////////////////////////////////////////////////////
// OpenGL 4.3
//////////////////////////////////////////////////////////////////////////
void APIENTRY glClearBufferData(GLenum target, GLenum internalformat, GLenum format, GLenum type, const void* data)
{
    SU_START_FUNCTION_WRAPPER(ap_glClearBufferData);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glClearBufferData, 5, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, internalformat, OS_TOBJ_ID_GL_ENUM_PARAMETER, format, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_POINTER_PARAMETER, data);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glClearBufferData, (target, internalformat, format, type, data));

    // Log the vbo data set:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        gsVBOMonitor* vboMonitor = pCurrentThreadRenderContextMonitor->vboMonitor();
        GT_IF_WITH_ASSERT(vboMonitor != NULL)
        {
            vboMonitor->onVertexBufferObjectSubDataSet(target);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glClearBufferData);
}

void APIENTRY glClearBufferSubData(GLenum target, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void* data)
{
    SU_START_FUNCTION_WRAPPER(ap_glClearBufferSubData);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glClearBufferSubData, 7, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, internalformat, OS_TOBJ_ID_GL_INTPTR_PARAMETER, offset, OS_TOBJ_ID_GL_SIZEIPTR_PARAMETER, size, OS_TOBJ_ID_GL_ENUM_PARAMETER, format, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_POINTER_PARAMETER, data);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glClearBufferSubData, (target, internalformat, offset, size, format, type, data));

    // Log the vbo data set:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        gsVBOMonitor* vboMonitor = pCurrentThreadRenderContextMonitor->vboMonitor();
        GT_IF_WITH_ASSERT(vboMonitor != NULL)
        {
            vboMonitor->onVertexBufferObjectSubDataSet(target);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glClearBufferSubData);
}

void APIENTRY glDispatchCompute(GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z)
{
    SU_START_FUNCTION_WRAPPER(ap_glDispatchCompute);

    // Log the call to this function:
    GLuint activeProgramName = gs_stat_openGLMonitorInstance.activeProgram();
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glDispatchCompute, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, num_groups_x, OS_TOBJ_ID_GL_UINT_PARAMETER, num_groups_y, OS_TOBJ_ID_GL_UINT_PARAMETER, num_groups_z, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, activeProgramName);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glDispatchCompute, (num_groups_x, num_groups_y, num_groups_z));

    SU_END_FUNCTION_WRAPPER(ap_glDispatchCompute);
}

void APIENTRY glDispatchComputeIndirect(GLintptr indirect)
{
    SU_START_FUNCTION_WRAPPER(ap_glDispatchComputeIndirect);

    // Log the call to this function:
    GLuint activeProgramName = gs_stat_openGLMonitorInstance.activeProgram();
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glDispatchComputeIndirect, 2, OS_TOBJ_ID_GL_INTPTR_PARAMETER, indirect, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, activeProgramName);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glDispatchComputeIndirect, (indirect));

    SU_END_FUNCTION_WRAPPER(ap_glDispatchComputeIndirect);
}

void APIENTRY glCopyImageSubData(GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth)
{
    SU_START_FUNCTION_WRAPPER(ap_glCopyImageSubData);

    // Log the call to this function:
    GLuint relatedTextures[2] = {srcName, dstName};
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glCopyImageSubData, 16, OS_TOBJ_ID_GL_UINT_PARAMETER, srcName, OS_TOBJ_ID_GL_ENUM_PARAMETER, srcTarget, OS_TOBJ_ID_GL_INT_PARAMETER, srcLevel, OS_TOBJ_ID_GL_INT_PARAMETER, srcX, OS_TOBJ_ID_GL_INT_PARAMETER, srcY, OS_TOBJ_ID_GL_INT_PARAMETER, srcZ, OS_TOBJ_ID_GL_UINT_PARAMETER, dstName, OS_TOBJ_ID_GL_ENUM_PARAMETER, dstTarget, OS_TOBJ_ID_GL_INT_PARAMETER, dstLevel, OS_TOBJ_ID_GL_INT_PARAMETER, dstX, OS_TOBJ_ID_GL_INT_PARAMETER, dstY, OS_TOBJ_ID_GL_INT_PARAMETER, dstZ, OS_TOBJ_ID_GL_SIZEI_PARAMETER, srcWidth, OS_TOBJ_ID_GL_SIZEI_PARAMETER, srcHeight, OS_TOBJ_ID_GL_SIZEI_PARAMETER, srcDepth, OS_TOBJ_ID_ASSOCIATED_TEXTURE_NAMES_PSEUDO_PARAMETER, 2, relatedTextures);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glCopyImageSubData, (srcName, srcTarget, srcLevel, srcX, srcY, srcZ, dstName, dstTarget, dstLevel, dstX, dstY, dstZ, srcWidth, srcHeight, srcDepth));

    SU_END_FUNCTION_WRAPPER(ap_glCopyImageSubData);
}

void APIENTRY glFramebufferParameteri(GLenum target, GLenum pname, GLint param)
{
    SU_START_FUNCTION_WRAPPER(ap_glFramebufferParameteri);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glFramebufferParameteri, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_INT_PARAMETER, param);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glFramebufferParameteri, (target, pname, param));

    SU_END_FUNCTION_WRAPPER(ap_glFramebufferParameteri);
}

void APIENTRY glGetFramebufferParameteriv(GLenum target, GLenum pname, GLint* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetFramebufferParameteriv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetFramebufferParameteriv, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetFramebufferParameteriv, (target, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetFramebufferParameteriv);
}

void APIENTRY glGetInternalformati64v(GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint64* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetInternalformati64v);

    // Log the call to this function:
    GLuint boundTextureName = gs_stat_openGLMonitorInstance.boundTexture(target);
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetInternalformati64v, 5, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, internalformat, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_SIZEI_PARAMETER, bufSize, OS_TOBJ_ID_GL_P_INT_64_PARAMETER, params, OS_TOBJ_ID_ASSOCIATED_TEXTURE_NAMES_PSEUDO_PARAMETER, 1, &boundTextureName);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetInternalformati64v, (target, internalformat, pname, bufSize, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetInternalformati64v);
}

void APIENTRY glInvalidateTexSubImage(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth)
{
    SU_START_FUNCTION_WRAPPER(ap_glInvalidateTexSubImage);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glInvalidateTexSubImage, 9, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_INT_PARAMETER, xoffset, OS_TOBJ_ID_GL_INT_PARAMETER, yoffset, OS_TOBJ_ID_GL_INT_PARAMETER, zoffset, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_SIZEI_PARAMETER, height, OS_TOBJ_ID_GL_SIZEI_PARAMETER, depth, OS_TOBJ_ID_ASSOCIATED_TEXTURE_NAMES_PSEUDO_PARAMETER, 1, &texture);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glInvalidateTexSubImage, (texture, level, xoffset, yoffset, zoffset, width, height, depth));

    SU_END_FUNCTION_WRAPPER(ap_glInvalidateTexSubImage);
}

void APIENTRY glInvalidateTexImage(GLuint texture, GLint level)
{
    SU_START_FUNCTION_WRAPPER(ap_glInvalidateTexImage);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glInvalidateTexImage, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_ASSOCIATED_TEXTURE_NAMES_PSEUDO_PARAMETER, 1, &texture);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glInvalidateTexImage, (texture, level));

    SU_END_FUNCTION_WRAPPER(ap_glInvalidateTexImage);
}

void APIENTRY glInvalidateBufferSubData(GLuint buffer, GLintptr offset, GLsizeiptr length)
{
    SU_START_FUNCTION_WRAPPER(ap_glInvalidateBufferSubData);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glInvalidateBufferSubData, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, buffer, OS_TOBJ_ID_GL_INTPTR_PARAMETER, offset, OS_TOBJ_ID_GL_SIZEIPTR_PARAMETER, length);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glInvalidateBufferSubData, (buffer, offset, length));

    SU_END_FUNCTION_WRAPPER(ap_glInvalidateBufferSubData);
}

void APIENTRY glInvalidateBufferData(GLuint buffer)
{
    SU_START_FUNCTION_WRAPPER(ap_glInvalidateBufferData);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glInvalidateBufferData, 1, OS_TOBJ_ID_GL_UINT_PARAMETER, buffer);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glInvalidateBufferData, (buffer));

    SU_END_FUNCTION_WRAPPER(ap_glInvalidateBufferData);
}

void APIENTRY glInvalidateFramebuffer(GLenum target, GLsizei numAttachments, const GLenum* attachments)
{
    SU_START_FUNCTION_WRAPPER(ap_glInvalidateFramebuffer);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glInvalidateFramebuffer, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_SIZEI_PARAMETER, numAttachments, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_ENUM_PARAMETER, (int)numAttachments, attachments);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glInvalidateFramebuffer, (target, numAttachments, attachments));

    SU_END_FUNCTION_WRAPPER(ap_glInvalidateFramebuffer);
}

void APIENTRY glInvalidateSubFramebuffer(GLenum target, GLsizei numAttachments, const GLenum* attachments, GLint x, GLint y, GLsizei width, GLsizei height)
{
    SU_START_FUNCTION_WRAPPER(ap_glInvalidateSubFramebuffer);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glInvalidateSubFramebuffer, 7, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_SIZEI_PARAMETER, numAttachments, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_ENUM_PARAMETER, (int)numAttachments, attachments, OS_TOBJ_ID_GL_INT_PARAMETER, x, OS_TOBJ_ID_GL_INT_PARAMETER, y, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_SIZEI_PARAMETER, height);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glInvalidateSubFramebuffer, (target, numAttachments, attachments, x, y, width, height));

    SU_END_FUNCTION_WRAPPER(ap_glInvalidateSubFramebuffer);
}

void APIENTRY glMultiDrawArraysIndirect(GLenum mode, const void* indirect, GLsizei drawcount, GLsizei stride)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glMultiDrawArraysIndirect);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiDrawArraysIndirect, 4, OS_TOBJ_ID_GL_PRIMITIVE_TYPE_PARAMETER, mode, OS_TOBJ_ID_POINTER_PARAMETER, indirect, OS_TOBJ_ID_GL_SIZEI_PARAMETER, drawcount, OS_TOBJ_ID_GL_SIZEI_PARAMETER, stride);

    // Get the current render context monitor:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (pCurrentThreadRenderContextMonitor != NULL)
    {
        // TO_DO: OpenGL 4.0 - we need to get the parameters from the indirect objects array:

        /*
        // Get the render primitives statistics logger:
        gsRenderPrimitivesStatisticsLogger& renderPrimitivesStatisticsLogger = pCurrentThreadRenderContextMonitor->renderPrimitivesStatisticsLogger();

        // Downcast the indirect data:
        struct DrawArraysIndirectCommand {
        GLuint  count;
        GLuint  primCount;
        GLuint  first;
        GLuint  baseInstance;
        } * indirectData = (DrawArraysIndirectCommand*)indirect;

        // Log this draw primitives function call:
        renderPrimitivesStatisticsLogger.onDrawArraysInstanced((GLsizei)currentIndirectData->count, (GLsizei)currentIndirectData->primCount, mode);
        */
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiDrawArraysIndirect, (mode, indirect, drawcount, stride));

    SU_END_FUNCTION_WRAPPER(ap_glMultiDrawArraysIndirect);
}

void APIENTRY glMultiDrawElementsIndirect(GLenum mode, GLenum type, const void* indirect, GLsizei drawcount, GLsizei stride)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glMultiDrawElementsIndirect);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiDrawElementsIndirect, 5, OS_TOBJ_ID_GL_PRIMITIVE_TYPE_PARAMETER, mode, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_POINTER_PARAMETER, indirect, OS_TOBJ_ID_GL_SIZEI_PARAMETER, drawcount, OS_TOBJ_ID_GL_SIZEI_PARAMETER, stride);

    // Get the current render context monitor:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (pCurrentThreadRenderContextMonitor != NULL)
    {
        // TO_DO: OpenGL 4.0 - we need to get the parameters from the indirect objects array:

        /*
        // Get the render primitives statistics logger:
        gsRenderPrimitivesStatisticsLogger& renderPrimitivesStatisticsLogger = pCurrentThreadRenderContextMonitor->renderPrimitivesStatisticsLogger();

        // Downcast the indirect data:
        struct DrawElementsIndirectCommand {
        GLuint  count;
        GLuint  primCount;
        GLuint  firstIndex;
        GLuint  baseVertex;
        GLuint  baseInstance;
        } * indirectData = (DrawElementsIndirectCommand*)indirect;

        // Log this draw primitives function call:
        renderPrimitivesStatisticsLogger.onDrawElementsInstanced((GLsizei)currentIndirectData->count, mode, type, (GLsizei)currentIndirectData->primCount);
        */
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiDrawElementsIndirect, (mode, type, indirect, drawcount, stride));

    SU_END_FUNCTION_WRAPPER(ap_glMultiDrawElementsIndirect);
}

void APIENTRY glGetProgramInterfaceiv(GLuint program, GLenum programInterface, GLenum pname, GLint* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetProgramInterfaceiv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetProgramInterfaceiv, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_ENUM_PARAMETER, programInterface, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_PARAMETER, params, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetProgramInterfaceiv, (program, programInterface, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetProgramInterfaceiv);
}

GLuint APIENTRY glGetProgramResourceIndex(GLuint program, GLenum programInterface, const GLchar* name)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetProgramResourceIndex);

    GLuint retVal = GL_INVALID_INDEX;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetProgramResourceIndex, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_ENUM_PARAMETER, programInterface, OS_TOBJ_ID_STRING_PARAMETER, name, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glGetProgramResourceIndex, (program, programInterface, name), retVal);

    SU_END_FUNCTION_WRAPPER(ap_glGetProgramResourceIndex);

    return retVal;
}

void APIENTRY glGetProgramResourceName(GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei* length, GLchar* name)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetProgramResourceName);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetProgramResourceName, 7, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_ENUM_PARAMETER, programInterface, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_SIZEI_PARAMETER, bufSize, OS_TOBJ_ID_GL_P_SIZEI_PARAMETER, length, OS_TOBJ_ID_GL_P_CHAR, name, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetProgramResourceName, (program, programInterface, index, bufSize, length, name));

    SU_END_FUNCTION_WRAPPER(ap_glGetProgramResourceName);
}

void APIENTRY glGetProgramResourceiv(GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum* props, GLsizei bufSize, GLsizei* length, GLint* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetProgramResourceiv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetProgramResourceiv, 9, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_ENUM_PARAMETER, programInterface, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_SIZEI_PARAMETER, propCount, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_ENUM_PARAMETER, (int)propCount, props, OS_TOBJ_ID_GL_SIZEI_PARAMETER, bufSize, OS_TOBJ_ID_GL_P_SIZEI_PARAMETER, length, OS_TOBJ_ID_GL_P_INT_PARAMETER, params, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetProgramResourceiv, (program, programInterface, index, propCount, props, bufSize, length, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetProgramResourceiv);
}

GLint APIENTRY glGetProgramResourceLocation(GLuint program, GLenum programInterface, const GLchar* name)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetProgramResourceLocation);

    GLint retVal = -1;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetProgramResourceLocation, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_ENUM_PARAMETER, programInterface, OS_TOBJ_ID_STRING_PARAMETER, name, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glGetProgramResourceLocation, (program, programInterface, name), retVal);

    SU_END_FUNCTION_WRAPPER(ap_glGetProgramResourceLocation);

    return retVal;
}

GLint APIENTRY glGetProgramResourceLocationIndex(GLuint program, GLenum programInterface, const GLchar* name)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetProgramResourceLocationIndex);

    GLint retVal = -1;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetProgramResourceLocationIndex, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_ENUM_PARAMETER, programInterface, OS_TOBJ_ID_STRING_PARAMETER, name, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glGetProgramResourceLocationIndex, (program, programInterface, name), retVal);

    SU_END_FUNCTION_WRAPPER(ap_glGetProgramResourceLocationIndex);

    return retVal;
}

void APIENTRY glShaderStorageBlockBinding(GLuint program, GLuint storageBlockIndex, GLuint storageBlockBinding)
{
    SU_START_FUNCTION_WRAPPER(ap_glShaderStorageBlockBinding);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glShaderStorageBlockBinding, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_UINT_PARAMETER, storageBlockIndex, OS_TOBJ_ID_GL_UINT_PARAMETER, storageBlockBinding, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, program);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glShaderStorageBlockBinding, (program, storageBlockIndex, storageBlockBinding));

    SU_END_FUNCTION_WRAPPER(ap_glShaderStorageBlockBinding);
}

void APIENTRY glTexBufferRange(GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size)
{
    SU_START_FUNCTION_WRAPPER(ap_glTexBufferRange);

    // Log the call to this function:
    GLuint boundTextureName = gs_stat_openGLMonitorInstance.boundTexture(target);
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTexBufferRange, 6, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, internalformat, OS_TOBJ_ID_GL_UINT_PARAMETER, buffer, OS_TOBJ_ID_GL_INTPTR_PARAMETER, offset, OS_TOBJ_ID_GL_SIZEIPTR_PARAMETER, size, OS_TOBJ_ID_ASSOCIATED_TEXTURE_NAMES_PSEUDO_PARAMETER, 1, &boundTextureName);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glTexBufferRange, (target, internalformat, buffer, offset, size));

    SU_END_FUNCTION_WRAPPER(ap_glTexBufferRange);
}

void APIENTRY glTexStorage2DMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations)
{
    SU_START_FUNCTION_WRAPPER(ap_glTexStorage2DMultisample);

    // Log the call to this function:
    GLuint boundTextureName = gs_stat_openGLMonitorInstance.boundTexture(target);
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTexStorage2DMultisample, 7, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_SIZEI_PARAMETER, samples, OS_TOBJ_ID_GL_ENUM_PARAMETER, internalformat, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_SIZEI_PARAMETER, height, OS_TOBJ_ID_GL_BOOL_PARAMETER, fixedsamplelocations, OS_TOBJ_ID_ASSOCIATED_TEXTURE_NAMES_PSEUDO_PARAMETER, 1, &boundTextureName);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glTexStorage2DMultisample, (target, samples, internalformat, width, height, fixedsamplelocations));

    // Log the texture storage setting:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (pCurrentThreadRenderContextMonitor)
    {
        // TO_DO: handle multisample textures:
        bool rcTex = pCurrentThreadRenderContextMonitor->onTextureStorageSet(target, 0, internalformat, width, height, 0);
        GT_ASSERT(rcTex);
    }

    SU_END_FUNCTION_WRAPPER(ap_glTexStorage2DMultisample);
}

void APIENTRY glTexStorage3DMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations)
{
    SU_START_FUNCTION_WRAPPER(ap_glTexStorage3DMultisample);

    // Log the call to this function:
    GLuint boundTextureName = gs_stat_openGLMonitorInstance.boundTexture(target);
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTexStorage3DMultisample, 8, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_SIZEI_PARAMETER, samples, OS_TOBJ_ID_GL_ENUM_PARAMETER, internalformat, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_SIZEI_PARAMETER, height, OS_TOBJ_ID_GL_SIZEI_PARAMETER, depth, OS_TOBJ_ID_GL_BOOL_PARAMETER, fixedsamplelocations, OS_TOBJ_ID_ASSOCIATED_TEXTURE_NAMES_PSEUDO_PARAMETER, 1, &boundTextureName);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glTexStorage3DMultisample, (target, samples, internalformat, width, height, depth, fixedsamplelocations));

    // Log the texture storage setting:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (pCurrentThreadRenderContextMonitor)
    {
        // TO_DO: handle multisample textures:
        bool rcTex = pCurrentThreadRenderContextMonitor->onTextureStorageSet(target, 0, internalformat, width, height, depth);
        GT_ASSERT(rcTex);
    }

    SU_END_FUNCTION_WRAPPER(ap_glTexStorage3DMultisample);
}

void APIENTRY glTextureView(GLuint texture, GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers)
{
    SU_START_FUNCTION_WRAPPER(ap_glTextureView);

    // Log the call to this function:
    GLuint relatedTextures[2] = {texture, origtexture};
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTextureView, 9, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_UINT_PARAMETER, origtexture, OS_TOBJ_ID_GL_ENUM_PARAMETER, internalformat, OS_TOBJ_ID_GL_UINT_PARAMETER, minlevel, OS_TOBJ_ID_GL_UINT_PARAMETER, numlevels, OS_TOBJ_ID_GL_UINT_PARAMETER, minlayer, OS_TOBJ_ID_GL_UINT_PARAMETER, numlayers, OS_TOBJ_ID_ASSOCIATED_TEXTURE_NAMES_PSEUDO_PARAMETER, 2, relatedTextures);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glTextureView, (texture, target, origtexture, internalformat, minlevel, numlevels, minlayer, numlayers));

    SU_END_FUNCTION_WRAPPER(ap_glTextureView);
}

void APIENTRY glBindVertexBuffer(GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride)
{
    SU_START_FUNCTION_WRAPPER(ap_glBindVertexBuffer);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glBindVertexBuffer, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, bindingindex, OS_TOBJ_ID_GL_UINT_PARAMETER, buffer, OS_TOBJ_ID_GL_INTPTR_PARAMETER, offset, OS_TOBJ_ID_GL_SIZEI_PARAMETER, stride);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glBindVertexBuffer, (bindingindex, buffer, offset, stride));

    SU_END_FUNCTION_WRAPPER(ap_glBindVertexBuffer);
}

void APIENTRY glVertexAttribFormat(GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset)
{
    SU_START_FUNCTION_WRAPPER(ap_glVertexAttribFormat);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttribFormat, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, attribindex, OS_TOBJ_ID_GL_INT_PARAMETER, size, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_BOOL_PARAMETER, normalized, OS_TOBJ_ID_GL_UINT_PARAMETER, relativeoffset);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttribFormat, (attribindex, size, type, normalized, relativeoffset));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttribFormat);
}

void APIENTRY glVertexAttribIFormat(GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset)
{
    SU_START_FUNCTION_WRAPPER(ap_glVertexAttribIFormat);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttribIFormat, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, attribindex, OS_TOBJ_ID_GL_INT_PARAMETER, size, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_UINT_PARAMETER, relativeoffset);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttribIFormat, (attribindex, size, type, relativeoffset));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttribIFormat);
}

void APIENTRY glVertexAttribLFormat(GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset)
{
    SU_START_FUNCTION_WRAPPER(ap_glVertexAttribLFormat);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttribLFormat, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, attribindex, OS_TOBJ_ID_GL_INT_PARAMETER, size, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_UINT_PARAMETER, relativeoffset);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttribLFormat, (attribindex, size, type, relativeoffset));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttribLFormat);
}

void APIENTRY glVertexAttribBinding(GLuint attribindex, GLuint bindingindex)
{
    SU_START_FUNCTION_WRAPPER(ap_glVertexAttribBinding);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttribBinding, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, attribindex, OS_TOBJ_ID_GL_UINT_PARAMETER, bindingindex);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttribBinding, (attribindex, bindingindex));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttribBinding);
}

void APIENTRY glVertexBindingDivisor(GLuint bindingindex, GLuint divisor)
{
    SU_START_FUNCTION_WRAPPER(ap_glVertexBindingDivisor);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexBindingDivisor, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, bindingindex, OS_TOBJ_ID_GL_UINT_PARAMETER, divisor);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexBindingDivisor, (bindingindex, divisor));

    SU_END_FUNCTION_WRAPPER(ap_glVertexBindingDivisor);
}

void APIENTRY glDebugMessageControl(GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint* ids, GLboolean enabled)
{
    SU_START_FUNCTION_WRAPPER(ap_glDebugMessageControl);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glDebugMessageControl, 6, OS_TOBJ_ID_GL_ENUM_PARAMETER, source, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_ENUM_PARAMETER, severity, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_UINT_PARAMETER, (int)count, ids, OS_TOBJ_ID_GL_BOOL_PARAMETER, enabled);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glDebugMessageControl, (source, type, severity, count, ids, enabled));

    SU_END_FUNCTION_WRAPPER(ap_glDebugMessageControl);
}

void APIENTRY glDebugMessageInsert(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* buf)
{
    SU_START_FUNCTION_WRAPPER(ap_glDebugMessageInsert);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glDebugMessageInsert, 6, OS_TOBJ_ID_GL_ENUM_PARAMETER, source, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_UINT_PARAMETER, id, OS_TOBJ_ID_GL_ENUM_PARAMETER, severity, OS_TOBJ_ID_GL_SIZEI_PARAMETER, length, OS_TOBJ_ID_STRING_PARAMETER, buf);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glDebugMessageInsert, (source, type, id, severity, length, buf));

    SU_END_FUNCTION_WRAPPER(ap_glDebugMessageInsert);
}

void APIENTRY glDebugMessageCallback(GLDEBUGPROC callback, const void* userParam)
{
    SU_START_FUNCTION_WRAPPER(ap_glDebugMessageCallback);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glDebugMessageCallback, 2, OS_TOBJ_ID_POINTER_PARAMETER, callback, OS_TOBJ_ID_POINTER_PARAMETER, userParam);

#if (AMDT_BUILD_TARGET == AMDT_WINDOWS_OS) || ((AMDT_BUILD_TARGET == AMDT_LINUX_OS) && (AMDT_LINUX_VARIANT == AMDT_GENERIC_LINUX_VARIANT))

    // NOTICE: Sigal 13/6/10
    // We do not call the real function, since we override the callback with our implementation.
    // We set the function callback and call it ourselves:
    // Call the real function:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        pCurrentThreadRenderContextMonitor->debugOutputManager().on43UserCallbackSet(callback, userParam);
    }
    else
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glDebugMessageCallback, (callback, userParam));
    }

#else

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glDebugMessageCallback, (callback, userParam));

#endif

    SU_END_FUNCTION_WRAPPER(ap_glDebugMessageCallback);
}

GLuint APIENTRY glGetDebugMessageLog(GLuint count, GLsizei bufSize, GLenum* sources, GLenum* types, GLuint* ids, GLenum* severities, GLsizei* lengths, GLchar* messageLog)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetDebugMessageLog);

    GLuint retVal = 0;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetDebugMessageLog, 8, OS_TOBJ_ID_GL_UINT_PARAMETER, count, OS_TOBJ_ID_GL_SIZEI_PARAMETER, bufSize, OS_TOBJ_ID_GL_P_ENUM_PARAMETER, sources, OS_TOBJ_ID_GL_P_ENUM_PARAMETER, types, OS_TOBJ_ID_GL_P_UINT_PARAMETER, ids, OS_TOBJ_ID_GL_P_ENUM_PARAMETER, severities, OS_TOBJ_ID_GL_P_SIZEI_PARAMETER, lengths, OS_TOBJ_ID_GL_P_CHAR, messageLog);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glGetDebugMessageLog, (count, bufSize, sources, types, ids, severities, lengths, messageLog), retVal);

    SU_END_FUNCTION_WRAPPER(ap_glGetDebugMessageLog);

    return retVal;
}

void APIENTRY glPushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar* message)
{
    SU_START_FUNCTION_WRAPPER(ap_glPushDebugGroup);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glPushDebugGroup, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, source, OS_TOBJ_ID_GL_UINT_PARAMETER, id, OS_TOBJ_ID_GL_SIZEI_PARAMETER, length, OS_TOBJ_ID_GL_STRING_PARAMETER, length, message);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glPushDebugGroup, (source, id, length, message));

    SU_END_FUNCTION_WRAPPER(ap_glPushDebugGroup);
}

void APIENTRY glPopDebugGroup(void)
{
    SU_START_FUNCTION_WRAPPER(ap_glPopDebugGroup);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glPopDebugGroup, 0);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glPopDebugGroup, ());

    SU_END_FUNCTION_WRAPPER(ap_glPopDebugGroup);
}

void APIENTRY glObjectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar* label)
{
    SU_START_FUNCTION_WRAPPER(ap_glObjectLabel);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glObjectLabel, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, identifier, OS_TOBJ_ID_GL_UINT_PARAMETER, name, OS_TOBJ_ID_GL_SIZEI_PARAMETER, length, OS_TOBJ_ID_GL_STRING_PARAMETER, length, label);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glObjectLabel, (identifier, name, length, label));

    SU_END_FUNCTION_WRAPPER(ap_glObjectLabel);
}

void APIENTRY glGetObjectLabel(GLenum identifier, GLuint name, GLsizei bufSize, GLsizei* length, GLchar* label)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetObjectLabel);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetObjectLabel, 5, OS_TOBJ_ID_GL_ENUM_PARAMETER, identifier, OS_TOBJ_ID_GL_UINT_PARAMETER, name, OS_TOBJ_ID_GL_SIZEI_PARAMETER, bufSize, OS_TOBJ_ID_GL_P_SIZEI_PARAMETER, length, OS_TOBJ_ID_GL_P_CHAR, label);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetObjectLabel, (identifier, name, bufSize, length, label));

    SU_END_FUNCTION_WRAPPER(ap_glGetObjectLabel);
}

void APIENTRY glObjectPtrLabel(const void* ptr, GLsizei length, const GLchar* label)
{
    SU_START_FUNCTION_WRAPPER(ap_glObjectPtrLabel);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glObjectPtrLabel, 3, OS_TOBJ_ID_POINTER_PARAMETER, ptr, OS_TOBJ_ID_GL_SIZEI_PARAMETER, length, OS_TOBJ_ID_GL_STRING_PARAMETER, length, label);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glObjectPtrLabel, (ptr, length, label));

    SU_END_FUNCTION_WRAPPER(ap_glObjectPtrLabel);
}

void APIENTRY glGetObjectPtrLabel(const void* ptr, GLsizei bufSize, GLsizei* length, GLchar* label)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetObjectPtrLabel);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetObjectPtrLabel, 4, OS_TOBJ_ID_POINTER_PARAMETER, ptr, OS_TOBJ_ID_GL_SIZEI_PARAMETER, bufSize, OS_TOBJ_ID_GL_P_SIZEI_PARAMETER, length, OS_TOBJ_ID_GL_P_CHAR, label);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetObjectPtrLabel, (ptr, bufSize, length, label));

    SU_END_FUNCTION_WRAPPER(ap_glGetObjectPtrLabel);
}

//////////////////////////////////////////////////////////////////////////
// OpenGL 4.4
//////////////////////////////////////////////////////////////////////////
void APIENTRY glBufferStorage(GLenum target, GLsizeiptr size, const void* data, GLbitfield flags)
{
    SU_START_FUNCTION_WRAPPER(ap_glBufferStorage);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glBufferStorage, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_SIZEIPTR_PARAMETER, size, OS_TOBJ_ID_POINTER_PARAMETER, data, OS_TOBJ_ID_GL_BITFIELD_PARAMETER, flags);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glBufferStorage, (target, size, data, flags));

    // Log the vbo data set:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        gsVBOMonitor* vboMonitor = pCurrentThreadRenderContextMonitor->vboMonitor();
        GT_IF_WITH_ASSERT(vboMonitor != NULL)
        {
            vboMonitor->onVertexBufferObjectDataSet(target, size);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glBufferStorage);
}

void APIENTRY glClearTexImage(GLuint texture, GLint level, GLenum format, GLenum type, const void* data)
{
    SU_START_FUNCTION_WRAPPER(ap_glClearTexImage);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glClearTexImage, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_ENUM_PARAMETER, format, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_POINTER_PARAMETER, data);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glClearTexImage, (texture, level, format, type, data));

    // Log the vbo data set:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (nullptr != pCurrentThreadRenderContextMonitor)
    {
        pCurrentThreadRenderContextMonitor->onNamedTextureImageLoaded(texture, level, format);
    }

    SU_END_FUNCTION_WRAPPER(ap_glClearTexImage);
}

void APIENTRY glClearTexSubImage(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void* data)
{
    SU_START_FUNCTION_WRAPPER(ap_glClearTexSubImage);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glClearTexSubImage, 11, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_INT_PARAMETER, xoffset, OS_TOBJ_ID_GL_INT_PARAMETER, yoffset, OS_TOBJ_ID_GL_INT_PARAMETER, zoffset, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_SIZEI_PARAMETER, height, OS_TOBJ_ID_GL_SIZEI_PARAMETER, depth, OS_TOBJ_ID_GL_ENUM_PARAMETER, format, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_POINTER_PARAMETER, data);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glClearTexSubImage, (texture, level, xoffset, yoffset, zoffset, width, height, depth, format, type, data));

    // Log the vbo data set:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (nullptr != pCurrentThreadRenderContextMonitor)
    {
        pCurrentThreadRenderContextMonitor->onNamedTextureSubImageLoaded(texture, level);
    }

    SU_END_FUNCTION_WRAPPER(ap_glClearTexSubImage);
}

void APIENTRY glBindBuffersBase(GLenum target, GLuint first, GLsizei count, const GLuint* buffers)
{
    SU_START_FUNCTION_WRAPPER(ap_glBindBuffersBase);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glBindBuffersBase, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_UINT_PARAMETER, first, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_P_UINT_PARAMETER, buffers);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glBindBuffersBase, (target, first, count, buffers));

    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (nullptr != pCurrentThreadRenderContextMonitor)
    {
        // TO_DO: support information for indexed VBO targets:
        gsVBOMonitor* vboMonitor = pCurrentThreadRenderContextMonitor->vboMonitor();
        GT_IF_WITH_ASSERT(vboMonitor != NULL)
        {
            // For all target indices:
            for (GLsizei i = 0; i < count; ++i)
            {
                GLuint buffer = (nullptr == buffers) ? 0 : buffers[i];
                vboMonitor->onVertexBufferObjectTargetBind(target, buffer);
            }
        }

        // If this is a uniform buffer:
        if ((target == GL_UNIFORM_BUFFER) || (target == GL_UNIFORM_BUFFER_EXT))
        {
            // Get the active program name:
            GLuint activeProgram = gs_stat_openGLMonitorInstance.activeProgram();

            // Get the active uniforms manager:
            gsProgramsAndShadersMonitor* pProgramAndShaderMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
            GT_IF_WITH_ASSERT(nullptr != pProgramAndShaderMonitor)
            {
                // Get the active uniforms monitor:
                gsActiveUniformsMonitor& activeUniformsMonitor = pProgramAndShaderMonitor->programsActiveUniformsMgr();

                // For all target indices:
                for (GLsizei i = 0; i < count; ++i)
                {
                    GLuint index = first + i;
                    GLuint buffer = (nullptr == buffers) ? 0 : buffers[i];

                    // Set uniform buffer object bind buffer:
                    activeUniformsMonitor.onUBOBindBuffer(activeProgram, target, index, buffer);
                }
            }
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glBindBuffersBase);
}

void APIENTRY glBindBuffersRange(GLenum target, GLuint first, GLsizei count, const GLuint* buffers, const GLintptr* offsets, const GLsizeiptr* sizes)
{
    SU_START_FUNCTION_WRAPPER(ap_glBindBuffersRange);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glBindBuffersRange, 6, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_UINT_PARAMETER, first, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_P_UINT_PARAMETER, buffers, OS_TOBJ_ID_GL_P_INTPTR_PARAMETER, offsets, OS_TOBJ_ID_GL_P_SIZEIPTR_PARAMETER, sizes);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glBindBuffersRange, (target, first, count, buffers, offsets, sizes));

    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (nullptr != pCurrentThreadRenderContextMonitor)
    {
        // TO_DO: support information for indexed VBO targets:
        gsVBOMonitor* vboMonitor = pCurrentThreadRenderContextMonitor->vboMonitor();
        GT_IF_WITH_ASSERT(vboMonitor != NULL)
        {
            // For all target indices:
            for (GLsizei i = 0; i < count; ++i)
            {
                GLuint buffer = (nullptr == buffers) ? 0 : buffers[i];
                vboMonitor->onVertexBufferObjectTargetBind(target, buffer);
            }
        }

        // If this is a uniform buffer:
        if ((target == GL_UNIFORM_BUFFER) || (target == GL_UNIFORM_BUFFER_EXT))
        {
            // Get the active program name:
            GLuint activeProgram = gs_stat_openGLMonitorInstance.activeProgram();

            // Get the active uniforms manager:
            gsProgramsAndShadersMonitor* pProgramAndShaderMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
            GT_IF_WITH_ASSERT(nullptr != pProgramAndShaderMonitor)
            {
                // Get the active uniforms monitor:
                gsActiveUniformsMonitor& activeUniformsMonitor = pProgramAndShaderMonitor->programsActiveUniformsMgr();

                // For all target indices:
                for (GLsizei i = 0; i < count; ++i)
                {
                    GLuint index = first + i;
                    GLuint buffer = (nullptr == buffers) ? 0 : buffers[i];

                    // Set uniform buffer object bind buffer (offset and size are irrelevant to our needs):
                    activeUniformsMonitor.onUBOBindBuffer(activeProgram, target, index, buffer);
                }
            }
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glBindBuffersRange);
}

void APIENTRY glBindTextures(GLuint first, GLsizei count, const GLuint* textures)
{
    SU_START_FUNCTION_WRAPPER(ap_glBindTextures);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glBindTextures, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, first, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_P_UINT_PARAMETER, textures);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glBindTextures, (first, count, textures));

    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (nullptr != pCurrentThreadRenderContextMonitor)
    {
        for (GLsizei i = 0; i < count; ++i)
        {
            GLenum textureUnit = GL_TEXTURE0 + first + i;
            GLuint texture = (nullptr == textures) ? 0 : textures[i];
            pCurrentThreadRenderContextMonitor->onTextureBindToUnit(textureUnit, texture);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glBindTextures);
}

void APIENTRY glBindSamplers(GLuint first, GLsizei count, const GLuint* samplers)
{
    SU_START_FUNCTION_WRAPPER(ap_glBindSamplers);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glBindSamplers, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, first, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_P_UINT_PARAMETER, samplers);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glBindSamplers, (first, count, samplers));
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (nullptr != pCurrentThreadRenderContextMonitor)
    {
        pCurrentThreadRenderContextMonitor->samplersMonitor().bindSamplers(first, count, samplers);
    }

    SU_END_FUNCTION_WRAPPER(ap_glBindSamplers);
}

void APIENTRY glBindImageTextures(GLuint first, GLsizei count, const GLuint* textures)
{
    SU_START_FUNCTION_WRAPPER(ap_glBindImageTextures);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glBindImageTextures, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, first, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_P_UINT_PARAMETER, textures);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glBindImageTextures, (first, count, textures));

    SU_END_FUNCTION_WRAPPER(ap_glBindImageTextures);
}

void APIENTRY glBindVertexBuffers(GLuint first, GLsizei count, const GLuint* buffers, const GLintptr* offsets, const GLsizei* strides)
{
    SU_START_FUNCTION_WRAPPER(ap_glBindVertexBuffers);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glBindVertexBuffers, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, first, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_P_UINT_PARAMETER, buffers, OS_TOBJ_ID_GL_P_INTPTR_PARAMETER, offsets, OS_TOBJ_ID_GL_P_SIZEI_PARAMETER, strides);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glBindVertexBuffers, (first, count, buffers, offsets, strides));

    SU_END_FUNCTION_WRAPPER(ap_glBindVertexBuffers);
}


//////////////////////////////////////////////////////////////////////////
// OpenGL 4.5
//////////////////////////////////////////////////////////////////////////
void APIENTRY glClipControl(GLenum origin, GLenum depth)
{
    SU_START_FUNCTION_WRAPPER(ap_glClipControl);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glClipControl, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, origin, OS_TOBJ_ID_GL_ENUM_PARAMETER, depth);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glClipControl, (origin, depth));

    SU_END_FUNCTION_WRAPPER(ap_glClipControl);
}

void APIENTRY glCreateTransformFeedbacks(GLsizei n, GLuint* ids)
{
    SU_START_FUNCTION_WRAPPER(ap_glCreateTransformFeedbacks);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glCreateTransformFeedbacks, 2, OS_TOBJ_ID_GL_SIZEI_PARAMETER, n, OS_TOBJ_ID_GL_P_UINT_PARAMETER, ids);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glCreateTransformFeedbacks, (n, ids));

    SU_END_FUNCTION_WRAPPER(ap_glCreateTransformFeedbacks);
}

void APIENTRY glTransformFeedbackBufferBase(GLuint xfb, GLuint index, GLuint buffer)
{
    SU_START_FUNCTION_WRAPPER(ap_glTransformFeedbackBufferBase);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTransformFeedbackBufferBase, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, xfb, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_UINT_PARAMETER, buffer);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glTransformFeedbackBufferBase, (xfb, index, buffer));

    SU_END_FUNCTION_WRAPPER(ap_glTransformFeedbackBufferBase);
}

void APIENTRY glTransformFeedbackBufferRange(GLuint xfb, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size)
{
    SU_START_FUNCTION_WRAPPER(ap_glTransformFeedbackBufferRange);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTransformFeedbackBufferRange, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, xfb, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_UINT_PARAMETER, buffer, OS_TOBJ_ID_GL_INTPTR_PARAMETER, offset, OS_TOBJ_ID_GL_SIZEIPTR_PARAMETER, size);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glTransformFeedbackBufferRange, (xfb, index, buffer, offset, size));

    SU_END_FUNCTION_WRAPPER(ap_glTransformFeedbackBufferRange);
}

void APIENTRY glGetTransformFeedbackiv(GLuint xfb, GLenum pname, GLint* param)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetTransformFeedbackiv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetTransformFeedbackiv, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, xfb, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_PARAMETER, param);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetTransformFeedbackiv, (xfb, pname, param));

    SU_END_FUNCTION_WRAPPER(ap_glGetTransformFeedbackiv);
}

void APIENTRY glGetTransformFeedbacki_v(GLuint xfb, GLenum pname, GLuint index, GLint* param)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetTransformFeedbacki_v);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetTransformFeedbacki_v, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, xfb, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_P_INT_PARAMETER, param);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetTransformFeedbacki_v, (xfb, pname, index, param));

    SU_END_FUNCTION_WRAPPER(ap_glGetTransformFeedbacki_v);
}

void APIENTRY glGetTransformFeedbacki64_v(GLuint xfb, GLenum pname, GLuint index, GLint64* param)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetTransformFeedbacki64_v);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetTransformFeedbacki64_v, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, xfb, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_P_INT_64_PARAMETER, param);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetTransformFeedbacki64_v, (xfb, pname, index, param));

    SU_END_FUNCTION_WRAPPER(ap_glGetTransformFeedbacki64_v);
}

void APIENTRY glCreateBuffers(GLsizei n, GLuint* buffers)
{
    SU_START_FUNCTION_WRAPPER(ap_glCreateBuffers);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glCreateBuffers, 2, OS_TOBJ_ID_GL_SIZEI_PARAMETER, n, OS_TOBJ_ID_GL_P_UINT_PARAMETER, buffers);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glCreateBuffers, (n, buffers));

    // Log the vbo generation:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        gsVBOMonitor* vboMonitor = pCurrentThreadRenderContextMonitor->vboMonitor();
        GT_IF_WITH_ASSERT(vboMonitor != NULL)
        {
            vboMonitor->onVertexBufferObjectGeneration(n, buffers);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glCreateBuffers);
}

void APIENTRY glNamedBufferStorage(GLuint buffer, GLsizeiptr size, const void* data, GLbitfield flags)
{
    SU_START_FUNCTION_WRAPPER(ap_glNamedBufferStorage);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glNamedBufferStorage, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, buffer, OS_TOBJ_ID_GL_SIZEIPTR_PARAMETER, size, OS_TOBJ_ID_POINTER_PARAMETER, data, OS_TOBJ_ID_GL_BITFIELD_PARAMETER, flags);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glNamedBufferStorage, (buffer, size, data, flags));

    // Log the vbo data set:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        gsVBOMonitor* vboMonitor = pCurrentThreadRenderContextMonitor->vboMonitor();
        GT_IF_WITH_ASSERT(vboMonitor != NULL)
        {
            vboMonitor->onVertexBufferObjectDirectAccessDataSet(buffer, size);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glNamedBufferStorage);
}

void APIENTRY glNamedBufferData(GLuint buffer, GLsizeiptr size, const void* data, GLenum usage)
{
    SU_START_FUNCTION_WRAPPER(ap_glNamedBufferData);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glNamedBufferData, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, buffer, OS_TOBJ_ID_GL_SIZEIPTR_PARAMETER, size, OS_TOBJ_ID_POINTER_PARAMETER, data, OS_TOBJ_ID_GL_ENUM_PARAMETER, usage);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glNamedBufferData, (buffer, size, data, usage));

    // Log the vbo data set:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        gsVBOMonitor* vboMonitor = pCurrentThreadRenderContextMonitor->vboMonitor();
        GT_IF_WITH_ASSERT(vboMonitor != NULL)
        {
            vboMonitor->onVertexBufferObjectDirectAccessDataSet(buffer, size);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glNamedBufferData);
}

void APIENTRY glNamedBufferSubData(GLuint buffer, GLintptr offset, GLsizeiptr size, const void* data)
{
    SU_START_FUNCTION_WRAPPER(ap_glNamedBufferSubData);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glNamedBufferSubData, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, buffer, OS_TOBJ_ID_GL_INTPTR_PARAMETER, offset, OS_TOBJ_ID_GL_SIZEIPTR_PARAMETER, size, OS_TOBJ_ID_POINTER_PARAMETER, data);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glNamedBufferSubData, (buffer, offset, size, data));

    // Log the vbo data set:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        gsVBOMonitor* vboMonitor = pCurrentThreadRenderContextMonitor->vboMonitor();
        GT_IF_WITH_ASSERT(vboMonitor != NULL)
        {
            vboMonitor->onVertexBufferObjectDirectAccessSubDataSet(buffer);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glNamedBufferSubData);
}

void APIENTRY glCopyNamedBufferSubData(GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size)
{
    SU_START_FUNCTION_WRAPPER(ap_glCopyNamedBufferSubData);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glCopyNamedBufferSubData, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, readBuffer, OS_TOBJ_ID_GL_UINT_PARAMETER, writeBuffer, OS_TOBJ_ID_GL_INTPTR_PARAMETER, readOffset, OS_TOBJ_ID_GL_INTPTR_PARAMETER, writeOffset, OS_TOBJ_ID_GL_SIZEIPTR_PARAMETER, size);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glCopyNamedBufferSubData, (readBuffer, writeBuffer, readOffset, writeOffset, size));

    // Log the vbo data set:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        gsVBOMonitor* vboMonitor = pCurrentThreadRenderContextMonitor->vboMonitor();
        GT_IF_WITH_ASSERT(vboMonitor != NULL)
        {
            vboMonitor->onVertexBufferObjectDirectAccessSubDataSet(writeBuffer);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glCopyNamedBufferSubData);
}

void APIENTRY glClearNamedBufferData(GLuint buffer, GLenum internalformat, GLenum format, GLenum type, const void* data)
{
    SU_START_FUNCTION_WRAPPER(ap_glClearNamedBufferData);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glClearNamedBufferData, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, buffer, OS_TOBJ_ID_GL_ENUM_PARAMETER, internalformat, OS_TOBJ_ID_GL_ENUM_PARAMETER, format, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_POINTER_PARAMETER, data);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glClearNamedBufferData, (buffer, internalformat, format, type, data));

    // Log the vbo data set:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        gsVBOMonitor* vboMonitor = pCurrentThreadRenderContextMonitor->vboMonitor();
        GT_IF_WITH_ASSERT(vboMonitor != NULL)
        {
            vboMonitor->onVertexBufferObjectDirectAccessSubDataSet(buffer);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glClearNamedBufferData);
}

void APIENTRY glClearNamedBufferSubData(GLuint buffer, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void* data)
{
    SU_START_FUNCTION_WRAPPER(ap_glClearNamedBufferSubData);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glClearNamedBufferSubData, 7, OS_TOBJ_ID_GL_UINT_PARAMETER, buffer, OS_TOBJ_ID_GL_ENUM_PARAMETER, internalformat, OS_TOBJ_ID_GL_INTPTR_PARAMETER, offset, OS_TOBJ_ID_GL_SIZEIPTR_PARAMETER, size, OS_TOBJ_ID_GL_ENUM_PARAMETER, format, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_POINTER_PARAMETER, data);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glClearNamedBufferSubData, (buffer, internalformat, offset, size, format, type, data));

    // Log the vbo data set:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        gsVBOMonitor* vboMonitor = pCurrentThreadRenderContextMonitor->vboMonitor();
        GT_IF_WITH_ASSERT(vboMonitor != NULL)
        {
            vboMonitor->onVertexBufferObjectDirectAccessSubDataSet(buffer);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glClearNamedBufferSubData);
}

void* APIENTRY glMapNamedBuffer(GLuint buffer, GLenum access)
{
    void* retVal = nullptr;

    SU_START_FUNCTION_WRAPPER(ap_glMapNamedBuffer);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMapNamedBuffer, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, buffer, OS_TOBJ_ID_GL_ENUM_PARAMETER, access);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glMapNamedBuffer, (buffer, access), retVal);

    SU_END_FUNCTION_WRAPPER(ap_glMapNamedBuffer);

    return retVal;
}

void* APIENTRY glMapNamedBufferRange(GLuint buffer, GLintptr offset, GLsizeiptr length, GLbitfield access)
{
    void* retVal = nullptr;

    SU_START_FUNCTION_WRAPPER(ap_glMapNamedBufferRange);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMapNamedBufferRange, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, buffer, OS_TOBJ_ID_GL_INTPTR_PARAMETER, offset, OS_TOBJ_ID_GL_SIZEIPTR_PARAMETER, length, OS_TOBJ_ID_GL_BITFIELD_PARAMETER, access);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glMapNamedBufferRange, (buffer, offset, length, access), retVal);

    SU_END_FUNCTION_WRAPPER(ap_glMapNamedBufferRange);

    return retVal;
}

GLboolean APIENTRY glUnmapNamedBuffer(GLuint buffer)
{
    GLboolean retVal = GL_FALSE;

    SU_START_FUNCTION_WRAPPER(ap_glUnmapNamedBuffer);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glUnmapNamedBuffer, 1, OS_TOBJ_ID_GL_UINT_PARAMETER, buffer);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glUnmapNamedBuffer, (buffer), retVal);

    // TO_DO: Might want to optimize this if the mapping was GL_READ_ONLY.
    // Log the vbo data set:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        gsVBOMonitor* vboMonitor = pCurrentThreadRenderContextMonitor->vboMonitor();
        GT_IF_WITH_ASSERT(vboMonitor != NULL)
        {
            vboMonitor->onVertexBufferObjectDirectAccessSubDataSet(buffer);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glUnmapNamedBuffer);

    return retVal;
}

void APIENTRY glFlushMappedNamedBufferRange(GLuint buffer, GLintptr offset, GLsizeiptr length)
{
    SU_START_FUNCTION_WRAPPER(ap_glFlushMappedNamedBufferRange);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glFlushMappedNamedBufferRange, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, buffer, OS_TOBJ_ID_GL_INTPTR_PARAMETER, offset, OS_TOBJ_ID_GL_SIZEIPTR_PARAMETER, length);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glFlushMappedNamedBufferRange, (buffer, offset, length));

    // Log the vbo data set:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        gsVBOMonitor* vboMonitor = pCurrentThreadRenderContextMonitor->vboMonitor();
        GT_IF_WITH_ASSERT(vboMonitor != NULL)
        {
            vboMonitor->onVertexBufferObjectDirectAccessSubDataSet(buffer);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glFlushMappedNamedBufferRange);
}

void APIENTRY glGetNamedBufferParameteriv(GLuint buffer, GLenum pname, GLint* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetNamedBufferParameteriv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetNamedBufferParameteriv, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, buffer, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetNamedBufferParameteriv, (buffer, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetNamedBufferParameteriv);
}

void APIENTRY glGetNamedBufferParameteri64v(GLuint buffer, GLenum pname, GLint64* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetNamedBufferParameteri64v);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetNamedBufferParameteri64v, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, buffer, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_64_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetNamedBufferParameteri64v, (buffer, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetNamedBufferParameteri64v);
}

void APIENTRY glGetNamedBufferPointerv(GLuint buffer, GLenum pname, void** params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetNamedBufferPointerv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetNamedBufferPointerv, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, buffer, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_PP_VOID_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetNamedBufferPointerv, (buffer, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetNamedBufferPointerv);
}

void APIENTRY glGetNamedBufferSubData(GLuint buffer, GLintptr offset, GLsizeiptr size, void* data)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetNamedBufferSubData);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetNamedBufferSubData, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, buffer, OS_TOBJ_ID_GL_INTPTR_PARAMETER, offset, OS_TOBJ_ID_GL_SIZEIPTR_PARAMETER, size, OS_TOBJ_ID_POINTER_PARAMETER, data);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetNamedBufferSubData, (buffer, offset, size, data));

    SU_END_FUNCTION_WRAPPER(ap_glGetNamedBufferSubData);
}

void APIENTRY glCreateFramebuffers(GLsizei n, GLuint* framebuffers)
{
    SU_START_FUNCTION_WRAPPER(ap_glCreateFramebuffers);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glCreateFramebuffers, 2, OS_TOBJ_ID_GL_SIZEI_PARAMETER, n, OS_TOBJ_ID_GL_P_UINT_PARAMETER, framebuffers);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glCreateFramebuffers, (n, framebuffers));

    // Get the RenderContextMonitor
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    // Construct a new apFBO for each of the generated frame buffer objects:
    GT_IF_WITH_ASSERT(pCurrentThreadRenderContextMonitor != NULL)
    {
        gsFBOMonitor* fboMon = pCurrentThreadRenderContextMonitor->fboMonitor();
        GT_IF_WITH_ASSERT(fboMon != NULL)
        {
            // Add new FBOs to the FBOs monitor
            fboMon->onGenFramebuffers(framebuffers, n);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glCreateFramebuffers);
}

void APIENTRY glNamedFramebufferRenderbuffer(GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
{
    SU_START_FUNCTION_WRAPPER(ap_glNamedFramebufferRenderbuffer);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glNamedFramebufferRenderbuffer, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, framebuffer, OS_TOBJ_ID_GL_ENUM_PARAMETER, attachment, OS_TOBJ_ID_GL_ENUM_PARAMETER, renderbuffertarget, OS_TOBJ_ID_GL_UINT_PARAMETER, renderbuffer);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glNamedFramebufferRenderbuffer, (framebuffer, attachment, renderbuffertarget, renderbuffer));

    // Get the RenderContextMonitor
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    // Construct a new apFBO for each of the generated frame buffer objects:
    GT_IF_WITH_ASSERT(pCurrentThreadRenderContextMonitor != NULL)
    {
        // Bind the texture to the active FBO:
        bool rcBindFBO = pCurrentThreadRenderContextMonitor->bindObjectToFBO(framebuffer, attachment, renderbuffertarget, renderbuffer, 0);
        GT_ASSERT(rcBindFBO);
    }

    SU_END_FUNCTION_WRAPPER(ap_glNamedFramebufferRenderbuffer);
}

void APIENTRY glNamedFramebufferParameteri(GLuint framebuffer, GLenum pname, GLint param)
{
    SU_START_FUNCTION_WRAPPER(ap_glNamedFramebufferParameteri);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glNamedFramebufferParameteri, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, framebuffer, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_INT_PARAMETER, param);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glNamedFramebufferParameteri, (framebuffer, pname, param));

    SU_END_FUNCTION_WRAPPER(ap_glNamedFramebufferParameteri);
}

void APIENTRY glNamedFramebufferTexture(GLuint framebuffer, GLenum attachment, GLuint texture, GLint level)
{
    SU_START_FUNCTION_WRAPPER(ap_glNamedFramebufferTexture);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glNamedFramebufferTexture, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, framebuffer, OS_TOBJ_ID_GL_ENUM_PARAMETER, attachment, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_INT_PARAMETER, level);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glNamedFramebufferTexture, (framebuffer, attachment, texture, level));

    // Get the RenderContextMonitor
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    // Construct a new apFBO for each of the generated frame buffer objects:
    GT_IF_WITH_ASSERT(pCurrentThreadRenderContextMonitor != NULL)
    {
        // Bind the texture to the active FBO:
        bool rcBindFBO = pCurrentThreadRenderContextMonitor->bindTextureToFBO(framebuffer, attachment, texture, 0);
        GT_ASSERT(rcBindFBO);
    }

    SU_END_FUNCTION_WRAPPER(ap_glNamedFramebufferTexture);
}

void APIENTRY glNamedFramebufferTextureLayer(GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLint layer)
{
    SU_START_FUNCTION_WRAPPER(ap_glNamedFramebufferTextureLayer);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glNamedFramebufferTextureLayer, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, framebuffer, OS_TOBJ_ID_GL_ENUM_PARAMETER, attachment, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_INT_PARAMETER, layer);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glNamedFramebufferTextureLayer, (framebuffer, attachment, texture, level, layer));

    // Get the RenderContextMonitor
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    // Construct a new apFBO for each of the generated frame buffer objects:
    GT_IF_WITH_ASSERT(pCurrentThreadRenderContextMonitor != NULL)
    {
        // Bind the texture to the active FBO:
        bool rcBindFBO = pCurrentThreadRenderContextMonitor->bindTextureToFBO(framebuffer, attachment, texture, layer);
        GT_ASSERT(rcBindFBO);
    }

    SU_END_FUNCTION_WRAPPER(ap_glNamedFramebufferTextureLayer);
}

void APIENTRY glNamedFramebufferDrawBuffer(GLuint framebuffer, GLenum buf)
{
    SU_START_FUNCTION_WRAPPER(ap_glNamedFramebufferDrawBuffer);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glNamedFramebufferDrawBuffer, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, framebuffer, OS_TOBJ_ID_GL_ENUM_PARAMETER, buf);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glNamedFramebufferDrawBuffer, (framebuffer, buf));

    SU_END_FUNCTION_WRAPPER(ap_glNamedFramebufferDrawBuffer);
}

void APIENTRY glNamedFramebufferDrawBuffers(GLuint framebuffer, GLsizei n, const GLenum* bufs)
{
    SU_START_FUNCTION_WRAPPER(ap_glNamedFramebufferDrawBuffers);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glNamedFramebufferDrawBuffers, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, framebuffer, OS_TOBJ_ID_GL_SIZEI_PARAMETER, n, OS_TOBJ_ID_GL_P_ENUM_PARAMETER, bufs);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glNamedFramebufferDrawBuffers, (framebuffer, n, bufs));

    SU_END_FUNCTION_WRAPPER(ap_glNamedFramebufferDrawBuffers);
}

void APIENTRY glNamedFramebufferReadBuffer(GLuint framebuffer, GLenum src)
{
    SU_START_FUNCTION_WRAPPER(ap_glNamedFramebufferReadBuffer);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glNamedFramebufferReadBuffer, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, framebuffer, OS_TOBJ_ID_GL_ENUM_PARAMETER, src);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glNamedFramebufferReadBuffer, (framebuffer, src));

    SU_END_FUNCTION_WRAPPER(ap_glNamedFramebufferReadBuffer);
}

void APIENTRY glInvalidateNamedFramebufferData(GLuint framebuffer, GLsizei numAttachments, const GLenum* attachments)
{
    SU_START_FUNCTION_WRAPPER(ap_glInvalidateNamedFramebufferData);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glInvalidateNamedFramebufferData, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, framebuffer, OS_TOBJ_ID_GL_SIZEI_PARAMETER, numAttachments, OS_TOBJ_ID_GL_P_ENUM_PARAMETER, attachments);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glInvalidateNamedFramebufferData, (framebuffer, numAttachments, attachments));

    SU_END_FUNCTION_WRAPPER(ap_glInvalidateNamedFramebufferData);
}

void APIENTRY glInvalidateNamedFramebufferSubData(GLuint framebuffer, GLsizei numAttachments, const GLenum* attachments, GLint x, GLint y, GLsizei width, GLsizei height)
{
    SU_START_FUNCTION_WRAPPER(ap_glInvalidateNamedFramebufferSubData);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glInvalidateNamedFramebufferSubData, 7, OS_TOBJ_ID_GL_UINT_PARAMETER, framebuffer, OS_TOBJ_ID_GL_SIZEI_PARAMETER, numAttachments, OS_TOBJ_ID_GL_P_ENUM_PARAMETER, attachments, OS_TOBJ_ID_GL_INT_PARAMETER, x, OS_TOBJ_ID_GL_INT_PARAMETER, y, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_SIZEI_PARAMETER, height);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glInvalidateNamedFramebufferSubData, (framebuffer, numAttachments, attachments, x, y, width, height));

    SU_END_FUNCTION_WRAPPER(ap_glInvalidateNamedFramebufferSubData);
}

void APIENTRY glClearNamedFramebufferiv(GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLint* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glClearNamedFramebufferiv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glClearNamedFramebufferiv, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, framebuffer, OS_TOBJ_ID_GL_ENUM_PARAMETER, buffer, OS_TOBJ_ID_GL_INT_PARAMETER, drawbuffer, OS_TOBJ_ID_GL_P_INT_PARAMETER, value);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glClearNamedFramebufferiv, (framebuffer, buffer, drawbuffer, value));

    SU_END_FUNCTION_WRAPPER(ap_glClearNamedFramebufferiv);
}

void APIENTRY glClearNamedFramebufferuiv(GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLuint* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glClearNamedFramebufferuiv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glClearNamedFramebufferuiv, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, framebuffer, OS_TOBJ_ID_GL_ENUM_PARAMETER, buffer, OS_TOBJ_ID_GL_INT_PARAMETER, drawbuffer, OS_TOBJ_ID_GL_P_UINT_PARAMETER, value);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glClearNamedFramebufferuiv, (framebuffer, buffer, drawbuffer, value));

    SU_END_FUNCTION_WRAPPER(ap_glClearNamedFramebufferuiv);
}

void APIENTRY glClearNamedFramebufferfv(GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLfloat* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glClearNamedFramebufferfv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glClearNamedFramebufferfv, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, framebuffer, OS_TOBJ_ID_GL_ENUM_PARAMETER, buffer, OS_TOBJ_ID_GL_INT_PARAMETER, drawbuffer, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, value);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glClearNamedFramebufferfv, (framebuffer, buffer, drawbuffer, value));

    SU_END_FUNCTION_WRAPPER(ap_glClearNamedFramebufferfv);
}

void APIENTRY glClearNamedFramebufferfi(GLuint framebuffer, GLenum buffer, const GLfloat depth, GLint stencil)
{
    SU_START_FUNCTION_WRAPPER(ap_glClearNamedFramebufferfi);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glClearNamedFramebufferfi, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, framebuffer, OS_TOBJ_ID_GL_ENUM_PARAMETER, buffer, OS_TOBJ_ID_GL_FLOAT_PARAMETER, depth, OS_TOBJ_ID_GL_INT_PARAMETER, stencil);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glClearNamedFramebufferfi, (framebuffer, buffer, depth, stencil));

    SU_END_FUNCTION_WRAPPER(ap_glClearNamedFramebufferfi);
}

void APIENTRY glBlitNamedFramebuffer(GLuint readFramebuffer, GLuint drawFramebuffer, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter)
{
    SU_START_FUNCTION_WRAPPER(ap_glBlitNamedFramebuffer);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glBlitNamedFramebuffer, 12, OS_TOBJ_ID_GL_UINT_PARAMETER, readFramebuffer, OS_TOBJ_ID_GL_UINT_PARAMETER, drawFramebuffer, OS_TOBJ_ID_GL_INT_PARAMETER, srcX0, OS_TOBJ_ID_GL_INT_PARAMETER, srcY0, OS_TOBJ_ID_GL_INT_PARAMETER, srcX1, OS_TOBJ_ID_GL_INT_PARAMETER, srcY1, OS_TOBJ_ID_GL_INT_PARAMETER, dstX0, OS_TOBJ_ID_GL_INT_PARAMETER, dstY0, OS_TOBJ_ID_GL_INT_PARAMETER, dstX1, OS_TOBJ_ID_GL_INT_PARAMETER, dstY1, OS_TOBJ_ID_GL_BITFIELD_PARAMETER, mask, OS_TOBJ_ID_GL_ENUM_PARAMETER, filter);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glBlitNamedFramebuffer, (readFramebuffer, drawFramebuffer, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter));

    SU_END_FUNCTION_WRAPPER(ap_glBlitNamedFramebuffer);
}

GLenum APIENTRY glCheckNamedFramebufferStatus(GLuint framebuffer, GLenum target)
{
    GLenum retVal = GL_NONE;

    SU_START_FUNCTION_WRAPPER(ap_glCheckNamedFramebufferStatus);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glCheckNamedFramebufferStatus, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, framebuffer, OS_TOBJ_ID_GL_ENUM_PARAMETER, target);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glCheckNamedFramebufferStatus, (framebuffer, target), retVal);

    SU_END_FUNCTION_WRAPPER(ap_glCheckNamedFramebufferStatus);

    return retVal;
}

void APIENTRY glGetNamedFramebufferParameteriv(GLuint framebuffer, GLenum pname, GLint* param)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetNamedFramebufferParameteriv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetNamedFramebufferParameteriv, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, framebuffer, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_PARAMETER, param);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetNamedFramebufferParameteriv, (framebuffer, pname, param));

    SU_END_FUNCTION_WRAPPER(ap_glGetNamedFramebufferParameteriv);
}

void APIENTRY glGetNamedFramebufferAttachmentParameteriv(GLuint framebuffer, GLenum attachment, GLenum pname, GLint* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetNamedFramebufferAttachmentParameteriv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetNamedFramebufferAttachmentParameteriv, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, framebuffer, OS_TOBJ_ID_GL_ENUM_PARAMETER, attachment, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetNamedFramebufferAttachmentParameteriv, (framebuffer, attachment, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetNamedFramebufferAttachmentParameteriv);
}

void APIENTRY glCreateRenderbuffers(GLsizei n, GLuint* renderbuffers)
{
    SU_START_FUNCTION_WRAPPER(ap_glCreateRenderbuffers);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glCreateRenderbuffers, 2, OS_TOBJ_ID_GL_SIZEI_PARAMETER, n, OS_TOBJ_ID_GL_P_UINT_PARAMETER, renderbuffers);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glCreateRenderbuffers, (n, renderbuffers));

    // Log the textures generation:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        gsRenderBuffersMonitor* renderBuffersMon = pCurrentThreadRenderContextMonitor->renderBuffersMonitor();
        GT_IF_WITH_ASSERT(renderBuffersMon != NULL)
        {
            renderBuffersMon->onRenderBufferObjectsGeneration(n, renderbuffers);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glCreateRenderbuffers);
}

void APIENTRY glNamedRenderbufferStorage(GLuint renderbuffer, GLenum internalformat, GLsizei width, GLsizei height)
{
    SU_START_FUNCTION_WRAPPER(ap_glNamedRenderbufferStorage);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glNamedRenderbufferStorage, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, renderbuffer, OS_TOBJ_ID_GL_ENUM_PARAMETER, internalformat, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_SIZEI_PARAMETER, height);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glNamedRenderbufferStorage, (renderbuffer, internalformat, width, height));

    // Log the render buffer parameters:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        bool rcRBOParams = pCurrentThreadRenderContextMonitor->setRenderBufferObjectParameters(renderbuffer, internalformat, width, height);
        GT_ASSERT(rcRBOParams);
    }

    SU_END_FUNCTION_WRAPPER(ap_glNamedRenderbufferStorage);
}

void APIENTRY glNamedRenderbufferStorageMultisample(GLuint renderbuffer, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
{
    SU_START_FUNCTION_WRAPPER(ap_glNamedRenderbufferStorageMultisample);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glNamedRenderbufferStorageMultisample, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, renderbuffer, OS_TOBJ_ID_GL_SIZEI_PARAMETER, samples, OS_TOBJ_ID_GL_ENUM_PARAMETER, internalformat, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_SIZEI_PARAMETER, height);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glNamedRenderbufferStorageMultisample, (renderbuffer, samples, internalformat, width, height));

    // Log the render buffer parameters:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        bool rcRBOParams = pCurrentThreadRenderContextMonitor->setRenderBufferObjectParameters(renderbuffer, internalformat, width, height);
        GT_ASSERT(rcRBOParams);
    }

    SU_END_FUNCTION_WRAPPER(ap_glNamedRenderbufferStorageMultisample);
}

void APIENTRY glGetNamedRenderbufferParameteriv(GLuint renderbuffer, GLenum pname, GLint* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetNamedRenderbufferParameteriv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetNamedRenderbufferParameteriv, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, renderbuffer, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetNamedRenderbufferParameteriv, (renderbuffer, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetNamedRenderbufferParameteriv);
}

void APIENTRY glCreateTextures(GLenum target, GLsizei n, GLuint* textures)
{
    SU_START_FUNCTION_WRAPPER(ap_glCreateTextures);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glCreateTextures, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_SIZEI_PARAMETER, n, OS_TOBJ_ID_GL_P_UINT_PARAMETER, textures);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glCreateTextures, (target, n, textures));

    // Log the textures generation:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (nullptr != pCurrentThreadRenderContextMonitor)
    {
        gsTexturesMonitor* texturesMon = pCurrentThreadRenderContextMonitor->texturesMonitor();
        GT_IF_WITH_ASSERT(texturesMon != NULL)
        {
            texturesMon->onTextureObjectsGeneration(n, textures);

        }

        // Update the texture types:
        apTextureType texType = apTextureBindTargetToTextureType(target);

        if (AP_UNKNOWN_TEXTURE_TYPE != texType)
        {
            int activeTexUnit = pCurrentThreadRenderContextMonitor->activeTextureUnitIndex();
            GLuint boundTexName = pCurrentThreadRenderContextMonitor->bindTextureName(activeTexUnit, texType);

            for (GLsizei i = 0; i < n; ++i)
            {
                // Set their target:
                pCurrentThreadRenderContextMonitor->onTextureTargetBind(target, textures[i]);
            }

            // Restore the real binding:
            pCurrentThreadRenderContextMonitor->onTextureTargetBind(target, boundTexName);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glCreateTextures);
}

void APIENTRY glTextureBuffer(GLuint texture, GLenum internalformat, GLuint buffer)
{
    SU_START_FUNCTION_WRAPPER(ap_glTextureBuffer);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTextureBuffer, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_ENUM_PARAMETER, internalformat, OS_TOBJ_ID_GL_UINT_PARAMETER, buffer);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glTextureBuffer, (texture, internalformat, buffer));

    // Log the textures buffer attachment:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        pCurrentThreadRenderContextMonitor->onTextureBuffer(texture, GL_TEXTURE_BUFFER, internalformat, buffer);
    }

    SU_END_FUNCTION_WRAPPER(ap_glTextureBuffer);
}

void APIENTRY glTextureBufferRange(GLuint texture, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size)
{
    SU_START_FUNCTION_WRAPPER(ap_glTextureBufferRange);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTextureBufferRange, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_ENUM_PARAMETER, internalformat, OS_TOBJ_ID_GL_UINT_PARAMETER, buffer, OS_TOBJ_ID_GL_INTPTR_PARAMETER, offset, OS_TOBJ_ID_GL_SIZEIPTR_PARAMETER, size);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glTextureBufferRange, (texture, internalformat, buffer, offset, size));

    // Log the textures buffer attachment:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        // TO_DO: handle range parameters?
        pCurrentThreadRenderContextMonitor->onTextureBuffer(texture, GL_TEXTURE_BUFFER, internalformat, buffer);
    }

    SU_END_FUNCTION_WRAPPER(ap_glTextureBufferRange);
}

void APIENTRY glTextureStorage1D(GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width)
{
    SU_START_FUNCTION_WRAPPER(ap_glTextureStorage1D);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTextureStorage1D, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_SIZEI_PARAMETER, levels, OS_TOBJ_ID_GL_ENUM_PARAMETER, internalformat, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glTextureStorage1D, (texture, levels, internalformat, width));

    // Log the texture storage setting:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (pCurrentThreadRenderContextMonitor)
    {
        bool rcTex = pCurrentThreadRenderContextMonitor->onNamedTextureStorageSet(texture, levels, internalformat, width, 0, 0);
        GT_ASSERT(rcTex);
    }

    SU_END_FUNCTION_WRAPPER(ap_glTextureStorage1D);
}

void APIENTRY glTextureStorage2D(GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height)
{
    SU_START_FUNCTION_WRAPPER(ap_glTextureStorage2D);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTextureStorage2D, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_SIZEI_PARAMETER, levels, OS_TOBJ_ID_GL_ENUM_PARAMETER, internalformat, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_SIZEI_PARAMETER, height);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glTextureStorage2D, (texture, levels, internalformat, width, height));

    // Log the texture storage setting:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (pCurrentThreadRenderContextMonitor)
    {
        bool rcTex = pCurrentThreadRenderContextMonitor->onNamedTextureStorageSet(texture, levels, internalformat, width, height, 0);
        GT_ASSERT(rcTex);
    }

    SU_END_FUNCTION_WRAPPER(ap_glTextureStorage2D);
}

void APIENTRY glTextureStorage3D(GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
{
    SU_START_FUNCTION_WRAPPER(ap_glTextureStorage3D);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTextureStorage3D, 6, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_SIZEI_PARAMETER, levels, OS_TOBJ_ID_GL_ENUM_PARAMETER, internalformat, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_SIZEI_PARAMETER, height, OS_TOBJ_ID_GL_SIZEI_PARAMETER, depth);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glTextureStorage3D, (texture, levels, internalformat, width, height, depth));

    // Log the texture storage setting:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (pCurrentThreadRenderContextMonitor)
    {
        bool rcTex = pCurrentThreadRenderContextMonitor->onNamedTextureStorageSet(texture, levels, internalformat, width, height, depth);
        GT_ASSERT(rcTex);
    }

    SU_END_FUNCTION_WRAPPER(ap_glTextureStorage3D);
}

void APIENTRY glTextureStorage2DMultisample(GLuint texture, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations)
{
    SU_START_FUNCTION_WRAPPER(ap_glTextureStorage2DMultisample);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTextureStorage2DMultisample, 6, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_SIZEI_PARAMETER, samples, OS_TOBJ_ID_GL_ENUM_PARAMETER, internalformat, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_SIZEI_PARAMETER, height, OS_TOBJ_ID_GL_BOOL_PARAMETER, fixedsamplelocations);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glTextureStorage2DMultisample, (texture, samples, internalformat, width, height, fixedsamplelocations));

    // Log the texture storage setting:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (pCurrentThreadRenderContextMonitor)
    {
        // TO_DO: handle multisample textures:
        bool rcTex = pCurrentThreadRenderContextMonitor->onNamedTextureStorageSet(texture, 0, internalformat, width, height, 0);
        GT_ASSERT(rcTex);
    }

    SU_END_FUNCTION_WRAPPER(ap_glTextureStorage2DMultisample);
}

void APIENTRY glTextureStorage3DMultisample(GLuint texture, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations)
{
    SU_START_FUNCTION_WRAPPER(ap_glTextureStorage3DMultisample);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTextureStorage3DMultisample, 7, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_SIZEI_PARAMETER, samples, OS_TOBJ_ID_GL_ENUM_PARAMETER, internalformat, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_SIZEI_PARAMETER, height, OS_TOBJ_ID_GL_SIZEI_PARAMETER, depth, OS_TOBJ_ID_GL_BOOL_PARAMETER, fixedsamplelocations);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glTextureStorage3DMultisample, (texture, samples, internalformat, width, height, depth, fixedsamplelocations));

    // Log the texture storage setting:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (pCurrentThreadRenderContextMonitor)
    {
        // TO_DO: handle multisample textures:
        bool rcTex = pCurrentThreadRenderContextMonitor->onNamedTextureStorageSet(texture, 0, internalformat, width, height, depth);
        GT_ASSERT(rcTex);
    }

    SU_END_FUNCTION_WRAPPER(ap_glTextureStorage3DMultisample);
}

void APIENTRY glTextureSubImage1D(GLuint texture, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void* pixels)
{
    SU_START_FUNCTION_WRAPPER(ap_glTextureSubImage1D);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTextureSubImage1D, 7, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_INT_PARAMETER, xoffset, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_ENUM_PARAMETER, format, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_POINTER_PARAMETER, pixels);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glTextureSubImage1D, (texture, level, xoffset, width, format, type, pixels));

    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    // Log the loaded sub-texture:
    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        bool rcSubTex = pCurrentThreadRenderContextMonitor->onNamedTextureSubImageLoaded(texture, level);
        GT_ASSERT(rcSubTex);
    }

    SU_END_FUNCTION_WRAPPER(ap_glTextureSubImage1D);
}

void APIENTRY glTextureSubImage2D(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels)
{
    SU_START_FUNCTION_WRAPPER(ap_glTextureSubImage2D);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTextureSubImage2D, 9, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_INT_PARAMETER, xoffset, OS_TOBJ_ID_GL_INT_PARAMETER, yoffset, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_SIZEI_PARAMETER, height, OS_TOBJ_ID_GL_ENUM_PARAMETER, format, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_POINTER_PARAMETER, pixels);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glTextureSubImage2D, (texture, level, xoffset, yoffset, width, height, format, type, pixels));

    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    // Log the loaded sub-texture:
    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        bool rcSubTex = pCurrentThreadRenderContextMonitor->onNamedTextureSubImageLoaded(texture, level);
        GT_ASSERT(rcSubTex);
    }

    SU_END_FUNCTION_WRAPPER(ap_glTextureSubImage2D);
}

void APIENTRY glTextureSubImage3D(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void* pixels)
{
    SU_START_FUNCTION_WRAPPER(ap_glTextureSubImage3D);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTextureSubImage3D, 11, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_INT_PARAMETER, xoffset, OS_TOBJ_ID_GL_INT_PARAMETER, yoffset, OS_TOBJ_ID_GL_INT_PARAMETER, zoffset, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_SIZEI_PARAMETER, height, OS_TOBJ_ID_GL_SIZEI_PARAMETER, depth, OS_TOBJ_ID_GL_ENUM_PARAMETER, format, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_POINTER_PARAMETER, pixels);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glTextureSubImage3D, (texture, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels));

    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    // Log the loaded sub-texture:
    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        bool rcSubTex = pCurrentThreadRenderContextMonitor->onNamedTextureSubImageLoaded(texture, level);
        GT_ASSERT(rcSubTex);
    }

    SU_END_FUNCTION_WRAPPER(ap_glTextureSubImage3D);
}

void APIENTRY glCompressedTextureSubImage1D(GLuint texture, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void* data)
{
    SU_START_FUNCTION_WRAPPER(ap_glCompressedTextureSubImage1D);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glCompressedTextureSubImage1D, 7, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_INT_PARAMETER, xoffset, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_ENUM_PARAMETER, format, OS_TOBJ_ID_GL_SIZEI_PARAMETER, imageSize, OS_TOBJ_ID_POINTER_PARAMETER, data);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glCompressedTextureSubImage1D, (texture, level, xoffset, width, format, imageSize, data));

    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    // Log the loaded sub-texture:
    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        bool rcSubTex = pCurrentThreadRenderContextMonitor->onNamedTextureSubImageLoaded(texture, level);
        GT_ASSERT(rcSubTex);
    }

    SU_END_FUNCTION_WRAPPER(ap_glCompressedTextureSubImage1D);
}

void APIENTRY glCompressedTextureSubImage2D(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void* data)
{
    SU_START_FUNCTION_WRAPPER(ap_glCompressedTextureSubImage2D);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glCompressedTextureSubImage2D, 9, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_INT_PARAMETER, xoffset, OS_TOBJ_ID_GL_INT_PARAMETER, yoffset, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_SIZEI_PARAMETER, height, OS_TOBJ_ID_GL_ENUM_PARAMETER, format, OS_TOBJ_ID_GL_SIZEI_PARAMETER, imageSize, OS_TOBJ_ID_POINTER_PARAMETER, data);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glCompressedTextureSubImage2D, (texture, level, xoffset, yoffset, width, height, format, imageSize, data));

    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    // Log the loaded sub-texture:
    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        bool rcSubTex = pCurrentThreadRenderContextMonitor->onNamedTextureSubImageLoaded(texture, level);
        GT_ASSERT(rcSubTex);
    }

    SU_END_FUNCTION_WRAPPER(ap_glCompressedTextureSubImage2D);
}

void APIENTRY glCompressedTextureSubImage3D(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void* data)
{
    SU_START_FUNCTION_WRAPPER(ap_glCompressedTextureSubImage3D);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glCompressedTextureSubImage3D, 11, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_INT_PARAMETER, xoffset, OS_TOBJ_ID_GL_INT_PARAMETER, yoffset, OS_TOBJ_ID_GL_INT_PARAMETER, zoffset, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_SIZEI_PARAMETER, height, OS_TOBJ_ID_GL_SIZEI_PARAMETER, depth, OS_TOBJ_ID_GL_ENUM_PARAMETER, format, OS_TOBJ_ID_GL_SIZEI_PARAMETER, imageSize, OS_TOBJ_ID_POINTER_PARAMETER, data);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glCompressedTextureSubImage3D, (texture, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data));

    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    // Log the loaded sub-texture:
    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        bool rcSubTex = pCurrentThreadRenderContextMonitor->onNamedTextureSubImageLoaded(texture, level);
        GT_ASSERT(rcSubTex);
    }

    SU_END_FUNCTION_WRAPPER(ap_glCompressedTextureSubImage3D);
}

void APIENTRY glCopyTextureSubImage1D(GLuint texture, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width)
{
    SU_START_FUNCTION_WRAPPER(ap_glCopyTextureSubImage1D);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glCopyTextureSubImage1D, 6, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_INT_PARAMETER, xoffset, OS_TOBJ_ID_GL_INT_PARAMETER, x, OS_TOBJ_ID_GL_INT_PARAMETER, y, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glCopyTextureSubImage1D, (texture, level, xoffset, x, y, width));

    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    // Log the loaded sub-texture:
    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        bool rcSubTex = pCurrentThreadRenderContextMonitor->onNamedTextureSubImageLoaded(texture, level);
        GT_ASSERT(rcSubTex);
    }

    SU_END_FUNCTION_WRAPPER(ap_glCopyTextureSubImage1D);
}

void APIENTRY glCopyTextureSubImage2D(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
{
    SU_START_FUNCTION_WRAPPER(ap_glCopyTextureSubImage2D);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glCopyTextureSubImage2D, 8, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_INT_PARAMETER, xoffset, OS_TOBJ_ID_GL_INT_PARAMETER, yoffset, OS_TOBJ_ID_GL_INT_PARAMETER, x, OS_TOBJ_ID_GL_INT_PARAMETER, y, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_SIZEI_PARAMETER, height);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glCopyTextureSubImage2D, (texture, level, xoffset, yoffset, x, y, width, height));

    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    // Log the loaded sub-texture:
    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        bool rcSubTex = pCurrentThreadRenderContextMonitor->onNamedTextureSubImageLoaded(texture, level);
        GT_ASSERT(rcSubTex);
    }

    SU_END_FUNCTION_WRAPPER(ap_glCopyTextureSubImage2D);
}

void APIENTRY glCopyTextureSubImage3D(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height)
{
    SU_START_FUNCTION_WRAPPER(ap_glCopyTextureSubImage3D);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glCopyTextureSubImage3D, 9, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_INT_PARAMETER, xoffset, OS_TOBJ_ID_GL_INT_PARAMETER, yoffset, OS_TOBJ_ID_GL_INT_PARAMETER, zoffset, OS_TOBJ_ID_GL_INT_PARAMETER, x, OS_TOBJ_ID_GL_INT_PARAMETER, y, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_SIZEI_PARAMETER, height);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glCopyTextureSubImage3D, (texture, level, xoffset, yoffset, zoffset, x, y, width, height));

    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    // Log the loaded sub-texture:
    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        bool rcSubTex = pCurrentThreadRenderContextMonitor->onNamedTextureSubImageLoaded(texture, level);
        GT_ASSERT(rcSubTex);
    }

    SU_END_FUNCTION_WRAPPER(ap_glCopyTextureSubImage3D);
}

void APIENTRY glTextureParameterf(GLuint texture, GLenum pname, GLfloat param)
{
    SU_START_FUNCTION_WRAPPER(ap_glTextureParameterf);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTextureParameterf, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_FLOAT_PARAMETER, param);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glTextureParameterf, (texture, pname, param));

    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    // Log the loaded sub-texture:
    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        bool rcSubTex = pCurrentThreadRenderContextMonitor->onNamedTextureFloatParameterChanged(texture, pname, &param);
        GT_ASSERT(rcSubTex);
    }

    SU_END_FUNCTION_WRAPPER(ap_glTextureParameterf);
}

void APIENTRY glTextureParameterfv(GLuint texture, GLenum pname, const GLfloat* param)
{
    SU_START_FUNCTION_WRAPPER(ap_glTextureParameterfv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTextureParameterfv, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, param);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glTextureParameterfv, (texture, pname, param));

    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    // Log the loaded sub-texture:
    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        bool rcSubTex = pCurrentThreadRenderContextMonitor->onNamedTextureFloatParameterChanged(texture, pname, param);
        GT_ASSERT(rcSubTex);
    }

    SU_END_FUNCTION_WRAPPER(ap_glTextureParameterfv);
}

void APIENTRY glTextureParameteri(GLuint texture, GLenum pname, GLint param)
{
    SU_START_FUNCTION_WRAPPER(ap_glTextureParameteri);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTextureParameteri, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_INT_PARAMETER, param);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glTextureParameteri, (texture, pname, param));

    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    // Log the new parameter value:
    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        gsTexturesMonitor* texturesMon = pCurrentThreadRenderContextMonitor->texturesMonitor();
        GT_IF_WITH_ASSERT(texturesMon != NULL)
        {
            bool rcTexParami = pCurrentThreadRenderContextMonitor->onNamedTextureIntParameterChanged(texture, pname, &param);
            GT_ASSERT(rcTexParami);
        }

        // Log the mipmap auto generation:
        if ((pname == GL_GENERATE_MIPMAP) || (pname == GL_TEXTURE_BASE_LEVEL) || (pname == GL_TEXTURE_MAX_LEVEL))
        {
            // Get the param value:
            bool rcMipmapGeneration = pCurrentThreadRenderContextMonitor->onMipmapGenerateParamSet(texture, pname, (GLfloat)param);
            GT_ASSERT(rcMipmapGeneration);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glTextureParameteri);
}

void APIENTRY glTextureParameterIiv(GLuint texture, GLenum pname, const GLint* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glTextureParameterIiv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTextureParameterIiv, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glTextureParameterIiv, (texture, pname, params));

    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    // Log the new parameter value:
    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        gsTexturesMonitor* texturesMon = pCurrentThreadRenderContextMonitor->texturesMonitor();
        GT_IF_WITH_ASSERT(texturesMon != NULL)
        {
            bool rcTexParami = pCurrentThreadRenderContextMonitor->onNamedTextureIntParameterChanged(texture, pname, params);
            GT_ASSERT(rcTexParami);
        }

        // Log the mipmap auto generation:
        if ((pname == GL_GENERATE_MIPMAP) || (pname == GL_TEXTURE_BASE_LEVEL) || (pname == GL_TEXTURE_MAX_LEVEL))
        {
            // Get the param value:
            GLint value = *params;
            bool rcMipmapGeneration = pCurrentThreadRenderContextMonitor->onMipmapGenerateParamSet(texture, pname, (GLfloat)value);
            GT_ASSERT(rcMipmapGeneration);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glTextureParameterIiv);
}

void APIENTRY glTextureParameterIuiv(GLuint texture, GLenum pname, const GLuint* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glTextureParameterIuiv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTextureParameterIuiv, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_UINT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glTextureParameterIuiv, (texture, pname, params));

    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    // Log the new parameter value:
    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        gsTexturesMonitor* texturesMon = pCurrentThreadRenderContextMonitor->texturesMonitor();
        GT_IF_WITH_ASSERT(texturesMon != NULL)
        {
            bool rcTexParami = pCurrentThreadRenderContextMonitor->onNamedTextureUIntParameterChanged(texture, pname, params);
            GT_ASSERT(rcTexParami);
        }

        // Log the mipmap auto generation:
        if ((pname == GL_GENERATE_MIPMAP) || (pname == GL_TEXTURE_BASE_LEVEL) || (pname == GL_TEXTURE_MAX_LEVEL))
        {
            // Get the param value:
            GLuint value = *params;
            bool rcMipmapGeneration = pCurrentThreadRenderContextMonitor->onMipmapGenerateParamSet(texture, pname, (GLfloat)value);
            GT_ASSERT(rcMipmapGeneration);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glTextureParameterIuiv);
}

void APIENTRY glTextureParameteriv(GLuint texture, GLenum pname, const GLint* param)
{
    SU_START_FUNCTION_WRAPPER(ap_glTextureParameteriv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTextureParameteriv, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_PARAMETER, param);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glTextureParameteriv, (texture, pname, param));

    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    // Log the new parameter value:
    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        gsTexturesMonitor* texturesMon = pCurrentThreadRenderContextMonitor->texturesMonitor();
        GT_IF_WITH_ASSERT(texturesMon != NULL)
        {
            bool rcTexParami = pCurrentThreadRenderContextMonitor->onNamedTextureIntParameterChanged(texture, pname, param);
            GT_ASSERT(rcTexParami);
        }

        // Log the mipmap auto generation:
        if ((pname == GL_GENERATE_MIPMAP) || (pname == GL_TEXTURE_BASE_LEVEL) || (pname == GL_TEXTURE_MAX_LEVEL))
        {
            // Get the param value:
            GLint value = *param;
            bool rcMipmapGeneration = pCurrentThreadRenderContextMonitor->onMipmapGenerateParamSet(texture, pname, (GLfloat)value);
            GT_ASSERT(rcMipmapGeneration);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glTextureParameteriv);
}

void APIENTRY glGenerateTextureMipmap(GLuint texture)
{
    SU_START_FUNCTION_WRAPPER(ap_glGenerateTextureMipmap);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGenerateTextureMipmap, 1, OS_TOBJ_ID_GL_UINT_PARAMETER, texture);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGenerateTextureMipmap, (texture));

    // Log the mipmap generation:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (pCurrentThreadRenderContextMonitor != NULL)
    {
        pCurrentThreadRenderContextMonitor->onTextureMipmapGenerate(texture);
    }

    SU_END_FUNCTION_WRAPPER(ap_glGenerateTextureMipmap);
}

void APIENTRY glBindTextureUnit(GLuint unit, GLuint texture)
{
    SU_START_FUNCTION_WRAPPER(ap_glBindTextureUnit);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glBindTextureUnit, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, unit, OS_TOBJ_ID_GL_UINT_PARAMETER, texture);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glBindTextureUnit, (unit, texture));

    // Log the mipmap generation:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (pCurrentThreadRenderContextMonitor != NULL)
    {
        pCurrentThreadRenderContextMonitor->onTextureBindToUnit(unit, texture);
    }

    SU_END_FUNCTION_WRAPPER(ap_glBindTextureUnit);
}

void APIENTRY glGetTextureImage(GLuint texture, GLint level, GLenum format, GLenum type, GLsizei bufSize, void* pixels)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetTextureImage);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetTextureImage, 6, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_ENUM_PARAMETER, format, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_SIZEI_PARAMETER, bufSize, OS_TOBJ_ID_POINTER_PARAMETER, pixels);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetTextureImage, (texture, level, format, type, bufSize, pixels));

    SU_END_FUNCTION_WRAPPER(ap_glGetTextureImage);
}

void APIENTRY glGetCompressedTextureImage(GLuint texture, GLint level, GLsizei bufSize, void* pixels)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetCompressedTextureImage);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetCompressedTextureImage, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_SIZEI_PARAMETER, bufSize, OS_TOBJ_ID_POINTER_PARAMETER, pixels);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetCompressedTextureImage, (texture, level, bufSize, pixels));

    SU_END_FUNCTION_WRAPPER(ap_glGetCompressedTextureImage);
}

void APIENTRY glGetTextureLevelParameterfv(GLuint texture, GLint level, GLenum pname, GLfloat* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetTextureLevelParameterfv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetTextureLevelParameterfv, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetTextureLevelParameterfv, (texture, level, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetTextureLevelParameterfv);
}

void APIENTRY glGetTextureLevelParameteriv(GLuint texture, GLint level, GLenum pname, GLint* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetTextureLevelParameteriv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetTextureLevelParameteriv, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetTextureLevelParameteriv, (texture, level, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetTextureLevelParameteriv);
}

void APIENTRY glGetTextureParameterfv(GLuint texture, GLenum pname, GLfloat* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetTextureParameterfv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetTextureParameterfv, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetTextureParameterfv, (texture, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetTextureParameterfv);
}

void APIENTRY glGetTextureParameterIiv(GLuint texture, GLenum pname, GLint* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetTextureParameterIiv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetTextureParameterIiv, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetTextureParameterIiv, (texture, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetTextureParameterIiv);
}

void APIENTRY glGetTextureParameterIuiv(GLuint texture, GLenum pname, GLuint* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetTextureParameterIuiv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetTextureParameterIuiv, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_UINT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetTextureParameterIuiv, (texture, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetTextureParameterIuiv);
}

void APIENTRY glGetTextureParameteriv(GLuint texture, GLenum pname, GLint* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetTextureParameteriv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetTextureParameteriv, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetTextureParameteriv, (texture, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetTextureParameteriv);
}

void APIENTRY glCreateVertexArrays(GLsizei n, GLuint* arrays)
{
    SU_START_FUNCTION_WRAPPER(ap_glCreateVertexArrays);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glCreateVertexArrays, 2, OS_TOBJ_ID_GL_SIZEI_PARAMETER, n, OS_TOBJ_ID_GL_P_UINT_PARAMETER, arrays);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glCreateVertexArrays, (n, arrays));

    SU_END_FUNCTION_WRAPPER(ap_glCreateVertexArrays);
}

void APIENTRY glDisableVertexArrayAttrib(GLuint vaobj, GLuint index)
{
    SU_START_FUNCTION_WRAPPER(ap_glDisableVertexArrayAttrib);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glDisableVertexArrayAttrib, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, vaobj, OS_TOBJ_ID_GL_UINT_PARAMETER, index);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glDisableVertexArrayAttrib, (vaobj, index));

    SU_END_FUNCTION_WRAPPER(ap_glDisableVertexArrayAttrib);
}

void APIENTRY glEnableVertexArrayAttrib(GLuint vaobj, GLuint index)
{
    SU_START_FUNCTION_WRAPPER(ap_glEnableVertexArrayAttrib);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glEnableVertexArrayAttrib, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, vaobj, OS_TOBJ_ID_GL_UINT_PARAMETER, index);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glEnableVertexArrayAttrib, (vaobj, index));

    SU_END_FUNCTION_WRAPPER(ap_glEnableVertexArrayAttrib);
}

void APIENTRY glVertexArrayElementBuffer(GLuint vaobj, GLuint buffer)
{
    SU_START_FUNCTION_WRAPPER(ap_glVertexArrayElementBuffer);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexArrayElementBuffer, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, vaobj, OS_TOBJ_ID_GL_UINT_PARAMETER, buffer);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexArrayElementBuffer, (vaobj, buffer));

    // Log the buffer binding:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (pCurrentThreadRenderContextMonitor != NULL)
    {
        gsVBOMonitor* vboMonitor = pCurrentThreadRenderContextMonitor->vboMonitor();
        GT_IF_WITH_ASSERT(vboMonitor != NULL)
        {
            vboMonitor->addTargetToBufferObject(GL_ELEMENT_ARRAY_BUFFER, buffer);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glVertexArrayElementBuffer);
}

void APIENTRY glVertexArrayVertexBuffer(GLuint vaobj, GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride)
{
    SU_START_FUNCTION_WRAPPER(ap_glVertexArrayVertexBuffer);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexArrayVertexBuffer, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, vaobj, OS_TOBJ_ID_GL_UINT_PARAMETER, bindingindex, OS_TOBJ_ID_GL_UINT_PARAMETER, buffer, OS_TOBJ_ID_GL_INTPTR_PARAMETER, offset, OS_TOBJ_ID_GL_SIZEI_PARAMETER, stride);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexArrayVertexBuffer, (vaobj, bindingindex, buffer, offset, stride));

    // Log the buffer binding:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (pCurrentThreadRenderContextMonitor != NULL)
    {
        gsVBOMonitor* vboMonitor = pCurrentThreadRenderContextMonitor->vboMonitor();
        GT_IF_WITH_ASSERT(vboMonitor != NULL)
        {
            vboMonitor->addTargetToBufferObject(GL_ARRAY_BUFFER, buffer);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glVertexArrayVertexBuffer);
}

void APIENTRY glVertexArrayVertexBuffers(GLuint vaobj, GLuint first, GLsizei count, const GLuint* buffers, const GLintptr* offsets, const GLsizei* strides)
{
    SU_START_FUNCTION_WRAPPER(ap_glVertexArrayVertexBuffers);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexArrayVertexBuffers, 6, OS_TOBJ_ID_GL_UINT_PARAMETER, vaobj, OS_TOBJ_ID_GL_UINT_PARAMETER, first, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_P_UINT_PARAMETER, buffers, OS_TOBJ_ID_GL_P_INTPTR_PARAMETER, offsets, OS_TOBJ_ID_GL_P_SIZEI_PARAMETER, strides);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexArrayVertexBuffers, (vaobj, first, count, buffers, offsets, strides));

    // Log the buffer binding:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (pCurrentThreadRenderContextMonitor != NULL)
    {
        gsVBOMonitor* vboMonitor = pCurrentThreadRenderContextMonitor->vboMonitor();
        GT_IF_WITH_ASSERT(vboMonitor != NULL)
        {
            if (nullptr != buffers)
            {
                for (GLsizei i = 0; i < count; ++i)
                {
                    vboMonitor->addTargetToBufferObject(GL_ARRAY_BUFFER, buffers[i]);
                }
            }
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glVertexArrayVertexBuffers);
}

void APIENTRY glVertexArrayAttribBinding(GLuint vaobj, GLuint attribindex, GLuint bindingindex)
{
    SU_START_FUNCTION_WRAPPER(ap_glVertexArrayAttribBinding);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexArrayAttribBinding, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, vaobj, OS_TOBJ_ID_GL_UINT_PARAMETER, attribindex, OS_TOBJ_ID_GL_UINT_PARAMETER, bindingindex);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexArrayAttribBinding, (vaobj, attribindex, bindingindex));

    SU_END_FUNCTION_WRAPPER(ap_glVertexArrayAttribBinding);
}

void APIENTRY glVertexArrayAttribFormat(GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset)
{
    SU_START_FUNCTION_WRAPPER(ap_glVertexArrayAttribFormat);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexArrayAttribFormat, 6, OS_TOBJ_ID_GL_UINT_PARAMETER, vaobj, OS_TOBJ_ID_GL_UINT_PARAMETER, attribindex, OS_TOBJ_ID_GL_INT_PARAMETER, size, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_BOOL_PARAMETER, normalized, OS_TOBJ_ID_GL_UINT_PARAMETER, relativeoffset);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexArrayAttribFormat, (vaobj, attribindex, size, type, normalized, relativeoffset));

    SU_END_FUNCTION_WRAPPER(ap_glVertexArrayAttribFormat);
}

void APIENTRY glVertexArrayAttribIFormat(GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset)
{
    SU_START_FUNCTION_WRAPPER(ap_glVertexArrayAttribIFormat);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexArrayAttribIFormat, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, vaobj, OS_TOBJ_ID_GL_UINT_PARAMETER, attribindex, OS_TOBJ_ID_GL_INT_PARAMETER, size, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_UINT_PARAMETER, relativeoffset);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexArrayAttribIFormat, (vaobj, attribindex, size, type, relativeoffset));

    SU_END_FUNCTION_WRAPPER(ap_glVertexArrayAttribIFormat);
}

void APIENTRY glVertexArrayAttribLFormat(GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset)
{
    SU_START_FUNCTION_WRAPPER(ap_glVertexArrayAttribLFormat);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexArrayAttribLFormat, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, vaobj, OS_TOBJ_ID_GL_UINT_PARAMETER, attribindex, OS_TOBJ_ID_GL_INT_PARAMETER, size, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_UINT_PARAMETER, relativeoffset);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexArrayAttribLFormat, (vaobj, attribindex, size, type, relativeoffset));

    SU_END_FUNCTION_WRAPPER(ap_glVertexArrayAttribLFormat);
}

void APIENTRY glVertexArrayBindingDivisor(GLuint vaobj, GLuint bindingindex, GLuint divisor)
{
    SU_START_FUNCTION_WRAPPER(ap_glVertexArrayBindingDivisor);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexArrayBindingDivisor, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, vaobj, OS_TOBJ_ID_GL_UINT_PARAMETER, bindingindex, OS_TOBJ_ID_GL_UINT_PARAMETER, divisor);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexArrayBindingDivisor, (vaobj, bindingindex, divisor));

    SU_END_FUNCTION_WRAPPER(ap_glVertexArrayBindingDivisor);
}

void APIENTRY glGetVertexArrayiv(GLuint vaobj, GLenum pname, GLint* param)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetVertexArrayiv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetVertexArrayiv, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, vaobj, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_PARAMETER, param);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetVertexArrayiv, (vaobj, pname, param));

    SU_END_FUNCTION_WRAPPER(ap_glGetVertexArrayiv);
}

void APIENTRY glGetVertexArrayIndexediv(GLuint vaobj, GLuint index, GLenum pname, GLint* param)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetVertexArrayIndexediv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetVertexArrayIndexediv, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, vaobj, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_PARAMETER, param);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetVertexArrayIndexediv, (vaobj, index, pname, param));

    SU_END_FUNCTION_WRAPPER(ap_glGetVertexArrayIndexediv);
}

void APIENTRY glGetVertexArrayIndexed64iv(GLuint vaobj, GLuint index, GLenum pname, GLint64* param)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetVertexArrayIndexed64iv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetVertexArrayIndexed64iv, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, vaobj, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_64_PARAMETER, param);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetVertexArrayIndexed64iv, (vaobj, index, pname, param));

    SU_END_FUNCTION_WRAPPER(ap_glGetVertexArrayIndexed64iv);
}

void APIENTRY glCreateSamplers(GLsizei n, GLuint* samplers)
{
    SU_START_FUNCTION_WRAPPER(ap_glCreateSamplers);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glCreateSamplers, 2, OS_TOBJ_ID_GL_SIZEI_PARAMETER, n, OS_TOBJ_ID_GL_P_UINT_PARAMETER, samplers);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glCreateSamplers, (n, samplers));

    // Get the render context monitor:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();
    GT_IF_WITH_ASSERT(pCurrentThreadRenderContextMonitor != NULL)
    {
        // Now update the monitor with the values generated by the runtime.
        pCurrentThreadRenderContextMonitor->samplersMonitor().genSamplers(n, samplers);
    }

    SU_END_FUNCTION_WRAPPER(ap_glCreateSamplers);
}

void APIENTRY glCreateProgramPipelines(GLsizei n, GLuint* pipelines)
{
    SU_START_FUNCTION_WRAPPER(ap_glCreateProgramPipelines);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glCreateProgramPipelines, 2, OS_TOBJ_ID_GL_SIZEI_PARAMETER, n, OS_TOBJ_ID_GL_P_UINT_PARAMETER, pipelines);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glCreateProgramPipelines, (n, pipelines));

    // Get the render context monitor:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();
    GT_IF_WITH_ASSERT(pCurrentThreadRenderContextMonitor != NULL)
    {
        // Now update the monitor with the values generated by the runtime.
        pCurrentThreadRenderContextMonitor->pipelinesMonitor().GenProgramPipelines(n, pipelines);
    }
    SU_END_FUNCTION_WRAPPER(ap_glCreateProgramPipelines);
}

void APIENTRY glCreateQueries(GLenum target, GLsizei n, GLuint* ids)
{
    SU_START_FUNCTION_WRAPPER(ap_glCreateQueries);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glCreateQueries, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_SIZEI_PARAMETER, n, OS_TOBJ_ID_GL_P_UINT_PARAMETER, ids);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glCreateQueries, (target, n, ids));

    SU_END_FUNCTION_WRAPPER(ap_glCreateQueries);
}

void APIENTRY glGetQueryBufferObjecti64v(GLuint id, GLuint buffer, GLenum pname, GLintptr offset)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetQueryBufferObjecti64v);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetQueryBufferObjecti64v, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, id, OS_TOBJ_ID_GL_UINT_PARAMETER, buffer, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_INTPTR_PARAMETER, offset);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetQueryBufferObjecti64v, (id, buffer, pname, offset));

    SU_END_FUNCTION_WRAPPER(ap_glGetQueryBufferObjecti64v);
}

void APIENTRY glGetQueryBufferObjectiv(GLuint id, GLuint buffer, GLenum pname, GLintptr offset)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetQueryBufferObjectiv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetQueryBufferObjectiv, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, id, OS_TOBJ_ID_GL_UINT_PARAMETER, buffer, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_INTPTR_PARAMETER, offset);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetQueryBufferObjectiv, (id, buffer, pname, offset));

    SU_END_FUNCTION_WRAPPER(ap_glGetQueryBufferObjectiv);
}

void APIENTRY glGetQueryBufferObjectui64v(GLuint id, GLuint buffer, GLenum pname, GLintptr offset)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetQueryBufferObjectui64v);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetQueryBufferObjectui64v, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, id, OS_TOBJ_ID_GL_UINT_PARAMETER, buffer, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_INTPTR_PARAMETER, offset);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetQueryBufferObjectui64v, (id, buffer, pname, offset));

    SU_END_FUNCTION_WRAPPER(ap_glGetQueryBufferObjectui64v);
}

void APIENTRY glGetQueryBufferObjectuiv(GLuint id, GLuint buffer, GLenum pname, GLintptr offset)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetQueryBufferObjectuiv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetQueryBufferObjectuiv, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, id, OS_TOBJ_ID_GL_UINT_PARAMETER, buffer, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_INTPTR_PARAMETER, offset);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetQueryBufferObjectuiv, (id, buffer, pname, offset));

    SU_END_FUNCTION_WRAPPER(ap_glGetQueryBufferObjectuiv);
}

void APIENTRY glMemoryBarrierByRegion(GLbitfield barriers)
{
    SU_START_FUNCTION_WRAPPER(ap_glMemoryBarrierByRegion);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMemoryBarrierByRegion, 1, OS_TOBJ_ID_GL_BITFIELD_PARAMETER, barriers);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMemoryBarrierByRegion, (barriers));

    SU_END_FUNCTION_WRAPPER(ap_glMemoryBarrierByRegion);
}

void APIENTRY glGetTextureSubImage(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLsizei bufSize, void* pixels)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetTextureSubImage);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetTextureSubImage, 12, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_INT_PARAMETER, xoffset, OS_TOBJ_ID_GL_INT_PARAMETER, yoffset, OS_TOBJ_ID_GL_INT_PARAMETER, zoffset, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_SIZEI_PARAMETER, height, OS_TOBJ_ID_GL_SIZEI_PARAMETER, depth, OS_TOBJ_ID_GL_ENUM_PARAMETER, format, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_SIZEI_PARAMETER, bufSize, OS_TOBJ_ID_POINTER_PARAMETER, pixels);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetTextureSubImage, (texture, level, xoffset, yoffset, zoffset, width, height, depth, format, type, bufSize, pixels));

    SU_END_FUNCTION_WRAPPER(ap_glGetTextureSubImage);
}

void APIENTRY glGetCompressedTextureSubImage(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei bufSize, void* pixels)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetCompressedTextureSubImage);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetCompressedTextureSubImage, 10, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_INT_PARAMETER, xoffset, OS_TOBJ_ID_GL_INT_PARAMETER, yoffset, OS_TOBJ_ID_GL_INT_PARAMETER, zoffset, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_SIZEI_PARAMETER, height, OS_TOBJ_ID_GL_SIZEI_PARAMETER, depth, OS_TOBJ_ID_GL_SIZEI_PARAMETER, bufSize, OS_TOBJ_ID_POINTER_PARAMETER, pixels);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetCompressedTextureSubImage, (texture, level, xoffset, yoffset, zoffset, width, height, depth, bufSize, pixels));

    SU_END_FUNCTION_WRAPPER(ap_glGetCompressedTextureSubImage);
}

GLenum APIENTRY glGetGraphicsResetStatus(void)
{
    GLenum retVal = GL_NONE;

    SU_START_FUNCTION_WRAPPER(ap_glGetGraphicsResetStatus);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetGraphicsResetStatus, 0);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glGetGraphicsResetStatus, (), retVal);

    SU_END_FUNCTION_WRAPPER(ap_glGetGraphicsResetStatus);

    return retVal;
}

void APIENTRY glGetnCompressedTexImage(GLenum target, GLint lod, GLsizei bufSize, void* pixels)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetnCompressedTexImage);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetnCompressedTexImage, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_INT_PARAMETER, lod, OS_TOBJ_ID_GL_SIZEI_PARAMETER, bufSize, OS_TOBJ_ID_POINTER_PARAMETER, pixels);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetnCompressedTexImage, (target, lod, bufSize, pixels));

    SU_END_FUNCTION_WRAPPER(ap_glGetnCompressedTexImage);
}

void APIENTRY glGetnTexImage(GLenum target, GLint level, GLenum format, GLenum type, GLsizei bufSize, void* pixels)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetnTexImage);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetnTexImage, 6, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_ENUM_PARAMETER, format, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_SIZEI_PARAMETER, bufSize, OS_TOBJ_ID_POINTER_PARAMETER, pixels);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetnTexImage, (target, level, format, type, bufSize, pixels));

    SU_END_FUNCTION_WRAPPER(ap_glGetnTexImage);
}

void APIENTRY glGetnUniformdv(GLuint program, GLint location, GLsizei bufSize, GLdouble* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetnUniformdv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetnUniformdv, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, bufSize, OS_TOBJ_ID_GL_P_DOUBLE_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetnUniformdv, (program, location, bufSize, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetnUniformdv);
}

void APIENTRY glGetnUniformfv(GLuint program, GLint location, GLsizei bufSize, GLfloat* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetnUniformfv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetnUniformfv, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, bufSize, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetnUniformfv, (program, location, bufSize, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetnUniformfv);
}

void APIENTRY glGetnUniformiv(GLuint program, GLint location, GLsizei bufSize, GLint* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetnUniformiv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetnUniformiv, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, bufSize, OS_TOBJ_ID_GL_P_INT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetnUniformiv, (program, location, bufSize, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetnUniformiv);
}

void APIENTRY glGetnUniformuiv(GLuint program, GLint location, GLsizei bufSize, GLuint* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetnUniformuiv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetnUniformuiv, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, bufSize, OS_TOBJ_ID_GL_P_UINT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetnUniformuiv, (program, location, bufSize, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetnUniformuiv);
}

void APIENTRY glReadnPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void* data)
{
    SU_START_FUNCTION_WRAPPER(ap_glReadnPixels);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glReadnPixels, 8, OS_TOBJ_ID_GL_INT_PARAMETER, x, OS_TOBJ_ID_GL_INT_PARAMETER, y, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_SIZEI_PARAMETER, height, OS_TOBJ_ID_GL_ENUM_PARAMETER, format, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_SIZEI_PARAMETER, bufSize, OS_TOBJ_ID_POINTER_PARAMETER, data);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glReadnPixels, (x, y, width, height, format, type, bufSize, data));

    SU_END_FUNCTION_WRAPPER(ap_glReadnPixels);
}

void APIENTRY glGetnMapdv(GLenum target, GLenum query, GLsizei bufSize, GLdouble* v)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetnMapdv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetnMapdv, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, query, OS_TOBJ_ID_GL_SIZEI_PARAMETER, bufSize, OS_TOBJ_ID_GL_P_DOUBLE_PARAMETER, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetnMapdv, (target, query, bufSize, v));

    SU_END_FUNCTION_WRAPPER(ap_glGetnMapdv);
}

void APIENTRY glGetnMapfv(GLenum target, GLenum query, GLsizei bufSize, GLfloat* v)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetnMapfv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetnMapfv, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, query, OS_TOBJ_ID_GL_SIZEI_PARAMETER, bufSize, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetnMapfv, (target, query, bufSize, v));

    SU_END_FUNCTION_WRAPPER(ap_glGetnMapfv);
}

void APIENTRY glGetnMapiv(GLenum target, GLenum query, GLsizei bufSize, GLint* v)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetnMapiv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetnMapiv, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, query, OS_TOBJ_ID_GL_SIZEI_PARAMETER, bufSize, OS_TOBJ_ID_GL_P_INT_PARAMETER, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetnMapiv, (target, query, bufSize, v));

    SU_END_FUNCTION_WRAPPER(ap_glGetnMapiv);
}

void APIENTRY glGetnPixelMapfv(GLenum map, GLsizei bufSize, GLfloat* values)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetnPixelMapfv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetnPixelMapfv, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, map, OS_TOBJ_ID_GL_SIZEI_PARAMETER, bufSize, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, values);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetnPixelMapfv, (map, bufSize, values));

    SU_END_FUNCTION_WRAPPER(ap_glGetnPixelMapfv);
}

void APIENTRY glGetnPixelMapuiv(GLenum map, GLsizei bufSize, GLuint* values)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetnPixelMapuiv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetnPixelMapuiv, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, map, OS_TOBJ_ID_GL_SIZEI_PARAMETER, bufSize, OS_TOBJ_ID_GL_P_UINT_PARAMETER, values);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetnPixelMapuiv, (map, bufSize, values));

    SU_END_FUNCTION_WRAPPER(ap_glGetnPixelMapuiv);
}

void APIENTRY glGetnPixelMapusv(GLenum map, GLsizei bufSize, GLushort* values)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetnPixelMapusv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetnPixelMapusv, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, map, OS_TOBJ_ID_GL_SIZEI_PARAMETER, bufSize, OS_TOBJ_ID_GL_P_USHORT_PARAMETER, values);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetnPixelMapusv, (map, bufSize, values));

    SU_END_FUNCTION_WRAPPER(ap_glGetnPixelMapusv);
}

void APIENTRY glGetnPolygonStipple(GLsizei bufSize, GLubyte* pattern)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetnPolygonStipple);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetnPolygonStipple, 2, OS_TOBJ_ID_GL_SIZEI_PARAMETER, bufSize, OS_TOBJ_ID_GL_P_UBYTE_PARAMETER, pattern);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetnPolygonStipple, (bufSize, pattern));

    SU_END_FUNCTION_WRAPPER(ap_glGetnPolygonStipple);
}

void APIENTRY glGetnColorTable(GLenum target, GLenum format, GLenum type, GLsizei bufSize, void* table)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetnColorTable);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetnColorTable, 5, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, format, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_SIZEI_PARAMETER, bufSize, OS_TOBJ_ID_POINTER_PARAMETER, table);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetnColorTable, (target, format, type, bufSize, table));

    SU_END_FUNCTION_WRAPPER(ap_glGetnColorTable);
}

void APIENTRY glGetnConvolutionFilter(GLenum target, GLenum format, GLenum type, GLsizei bufSize, void* image)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetnConvolutionFilter);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetnConvolutionFilter, 5, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, format, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_SIZEI_PARAMETER, bufSize, OS_TOBJ_ID_POINTER_PARAMETER, image);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetnConvolutionFilter, (target, format, type, bufSize, image));

    SU_END_FUNCTION_WRAPPER(ap_glGetnConvolutionFilter);
}

void APIENTRY glGetnSeparableFilter(GLenum target, GLenum format, GLenum type, GLsizei rowBufSize, void* row, GLsizei columnBufSize, void* column, void* span)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetnSeparableFilter);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetnSeparableFilter, 8, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, format, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_SIZEI_PARAMETER, rowBufSize, OS_TOBJ_ID_POINTER_PARAMETER, row, OS_TOBJ_ID_GL_SIZEI_PARAMETER, columnBufSize, OS_TOBJ_ID_POINTER_PARAMETER, column, OS_TOBJ_ID_POINTER_PARAMETER, span);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetnSeparableFilter, (target, format, type, rowBufSize, row, columnBufSize, column, span));

    SU_END_FUNCTION_WRAPPER(ap_glGetnSeparableFilter);
}

void APIENTRY glGetnHistogram(GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, void* values)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetnHistogram);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetnHistogram, 6, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_BOOL_PARAMETER, reset, OS_TOBJ_ID_GL_ENUM_PARAMETER, format, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_SIZEI_PARAMETER, bufSize, OS_TOBJ_ID_POINTER_PARAMETER, values);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetnHistogram, (target, reset, format, type, bufSize, values));

    SU_END_FUNCTION_WRAPPER(ap_glGetnHistogram);
}

void APIENTRY glGetnMinmax(GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, void* values)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetnMinmax);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetnMinmax, 6, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_BOOL_PARAMETER, reset, OS_TOBJ_ID_GL_ENUM_PARAMETER, format, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_SIZEI_PARAMETER, bufSize, OS_TOBJ_ID_POINTER_PARAMETER, values);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetnMinmax, (target, reset, format, type, bufSize, values));

    SU_END_FUNCTION_WRAPPER(ap_glGetnMinmax);
}

void APIENTRY glTextureBarrier(void)
{
    SU_START_FUNCTION_WRAPPER(ap_glTextureBarrier);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTextureBarrier, 0);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glTextureBarrier, ());

    SU_END_FUNCTION_WRAPPER(ap_glTextureBarrier);
}


//////////////////////////////////////////////////////////////////////////
// GL_ARB_cl_event
//////////////////////////////////////////////////////////////////////////
GLsync glCreateSyncFromCLeventARB(struct _cl_context* context, struct _cl_event* event, GLbitfield flags)
{
    SU_START_FUNCTION_WRAPPER(ap_glCreateSyncFromCLeventARB);

    GLsync retVal = NULL;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glCreateSyncFromCLeventARB, 3, OS_TOBJ_ID_POINTER_PARAMETER, context, OS_TOBJ_ID_POINTER_PARAMETER, event, OS_TOBJ_ID_GL_BITFIELD_PARAMETER, flags);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glCreateSyncFromCLeventARB, (context, event, flags), retVal);

    // Get the Sync objects monitor:
    gsSyncObjectsMonitor& syncObjectsMonitor = gs_stat_openGLMonitorInstance.syncObjectsMonitor();

    // Log the created sync object:
    syncObjectsMonitor.onSyncObjectCreation(retVal, GL_SYNC_CL_EVENT_COMPLETE_ARB);

    SU_END_FUNCTION_WRAPPER(ap_glCreateSyncFromCLeventARB);

    return retVal;
}

//////////////////////////////////////////////////////////////////////////
// GL_NV_primitive_restart
//////////////////////////////////////////////////////////////////////////
void APIENTRY glPrimitiveRestartNV(void)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glPrimitiveRestartNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glPrimitiveRestartNV, 0);

    // Get the current render context monitor:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (pCurrentThreadRenderContextMonitor != NULL)
    {
        // Get the render primitives statistics logger:
        gsRenderPrimitivesStatisticsLogger& renderPrimitivesStatisticsLogger = pCurrentThreadRenderContextMonitor->renderPrimitivesStatisticsLogger();

        // Log this draw primitives function call:
        renderPrimitivesStatisticsLogger.onPrimitiveRestart();
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glPrimitiveRestartNV, ());

    SU_END_FUNCTION_WRAPPER(ap_glPrimitiveRestartNV);
}

void APIENTRY glPrimitiveRestartIndexNV(GLuint index)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glPrimitiveRestartIndexNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glPrimitiveRestartIndexNV, 1, OS_TOBJ_ID_GL_UINT_PARAMETER, index);

    // Get the current render context monitor:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (pCurrentThreadRenderContextMonitor != NULL)
    {
        // Get the render primitives statistics logger:
        gsRenderPrimitivesStatisticsLogger& renderPrimitivesStatisticsLogger = pCurrentThreadRenderContextMonitor->renderPrimitivesStatisticsLogger();

        // Log this draw primitives function call:
        renderPrimitivesStatisticsLogger.onPrimitiveRestartIndex(index);
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glPrimitiveRestartIndexNV, (index));

    SU_END_FUNCTION_WRAPPER(ap_glPrimitiveRestartIndexNV);
}

//////////////////////////////////////////////////////////////////////////
// GL_HP_occlusion_test extension
//////////////////////////////////////////////////////////////////////////
// No functions

//////////////////////////////////////////////////////////////////////////
// GL_NV_occlusion_query
//////////////////////////////////////////////////////////////////////////
void APIENTRY glGenOcclusionQueriesNV(GLsizei n, GLuint* ids)
{
    SU_START_FUNCTION_WRAPPER(ap_glGenOcclusionQueriesNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGenOcclusionQueriesNV, 2, OS_TOBJ_ID_GL_SIZEI_PARAMETER, n, OS_TOBJ_ID_GL_P_UINT_PARAMETER, ids);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGenOcclusionQueriesNV, (n, ids));

    SU_END_FUNCTION_WRAPPER(ap_glGenOcclusionQueriesNV);
}

void APIENTRY glDeleteOcclusionQueriesNV(GLsizei n, const GLuint* ids)
{
    SU_START_FUNCTION_WRAPPER(ap_glDeleteOcclusionQueriesNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glDeleteOcclusionQueriesNV, 2, OS_TOBJ_ID_GL_SIZEI_PARAMETER, n, OS_TOBJ_ID_GL_P_UINT_PARAMETER, ids);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glDeleteOcclusionQueriesNV, (n, ids));

    SU_END_FUNCTION_WRAPPER(ap_glDeleteOcclusionQueriesNV);
}

GLboolean APIENTRY glIsOcclusionQueryNV(GLuint id)
{
    SU_START_FUNCTION_WRAPPER(ap_glIsOcclusionQueryNV);

    GLboolean retVal = GL_FALSE;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glIsOcclusionQueryNV, 1, OS_TOBJ_ID_GL_UINT_PARAMETER, id);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glIsOcclusionQueryNV, (id), retVal);

    SU_END_FUNCTION_WRAPPER(ap_glIsOcclusionQueryNV);

    return retVal;
}

void APIENTRY glBeginOcclusionQueryNV(GLuint id)
{
    SU_START_FUNCTION_WRAPPER(ap_glBeginOcclusionQueryNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glBeginOcclusionQueryNV, 1, OS_TOBJ_ID_GL_UINT_PARAMETER, id);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glBeginOcclusionQueryNV, (id));

    SU_END_FUNCTION_WRAPPER(ap_glBeginOcclusionQueryNV);
}

void APIENTRY glEndOcclusionQueryNV(void)
{
    SU_START_FUNCTION_WRAPPER(ap_glEndOcclusionQueryNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glEndOcclusionQueryNV, 0);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glEndOcclusionQueryNV, ());

    SU_END_FUNCTION_WRAPPER(ap_glEndOcclusionQueryNV);
}

void APIENTRY glGetOcclusionQueryivNV(GLuint id, GLenum pname, GLint* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetOcclusionQueryivNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetOcclusionQueryivNV, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, id, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetOcclusionQueryivNV, (id, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetOcclusionQueryivNV);
}

void APIENTRY glGetOcclusionQueryuivNV(GLuint id, GLenum pname, GLuint* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetOcclusionQueryuivNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetOcclusionQueryuivNV, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, id, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_UINT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetOcclusionQueryuivNV, (id, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetOcclusionQueryuivNV);
}


//////////////////////////////////////////////////////////////////////////
// GL_ARB_occlusion_query extension
//////////////////////////////////////////////////////////////////////////
void APIENTRY glGenQueriesARB(GLsizei n, GLuint* ids)
{
    SU_START_FUNCTION_WRAPPER(ap_glGenQueriesARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGenQueriesARB, 2, OS_TOBJ_ID_GL_SIZEI_PARAMETER, n, OS_TOBJ_ID_GL_P_UINT_PARAMETER, ids);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGenQueriesARB, (n, ids));

    SU_END_FUNCTION_WRAPPER(ap_glGenQueriesARB);
}

void APIENTRY glDeleteQueriesARB(GLsizei n, const GLuint* ids)
{
    SU_START_FUNCTION_WRAPPER(ap_glDeleteQueriesARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glDeleteQueriesARB, 2, OS_TOBJ_ID_GL_SIZEI_PARAMETER, n, OS_TOBJ_ID_GL_P_UINT_PARAMETER, ids);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glDeleteQueriesARB, (n, ids));

    SU_END_FUNCTION_WRAPPER(ap_glDeleteQueriesARB);
}

GLboolean APIENTRY glIsQueryARB(GLuint id)
{
    SU_START_FUNCTION_WRAPPER(ap_glIsQueryARB);

    GLboolean retVal = GL_FALSE;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glIsQueryARB, 1, OS_TOBJ_ID_GL_UINT_PARAMETER, id);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glIsQueryARB, (id), retVal);

    SU_END_FUNCTION_WRAPPER(ap_glIsQueryARB);

    return retVal;
}

void APIENTRY glBeginQueryARB(GLenum target, GLuint id)
{
    SU_START_FUNCTION_WRAPPER(ap_glBeginQueryARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glBeginQueryARB, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_UINT_PARAMETER, id);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glBeginQueryARB, (target, id));

    SU_END_FUNCTION_WRAPPER(ap_glBeginQueryARB);
}

void APIENTRY glEndQueryARB(GLenum target)
{
    SU_START_FUNCTION_WRAPPER(ap_glEndQueryARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glEndQueryARB, 1, OS_TOBJ_ID_GL_ENUM_PARAMETER, target);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glEndQueryARB, (target));

    SU_END_FUNCTION_WRAPPER(ap_glEndQueryARB);
}

void APIENTRY glGetQueryivARB(GLenum target, GLenum pname, GLint* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetQueryivARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetQueryivARB, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetQueryivARB, (target, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetQueryivARB);
}

void APIENTRY glGetQueryObjectivARB(GLuint id, GLenum pname, GLint* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetQueryObjectivARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetQueryObjectivARB, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, id, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetQueryObjectivARB, (id, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetQueryObjectivARB);
}

void APIENTRY glGetQueryObjectuivARB(GLuint id, GLenum pname, GLuint* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetQueryObjectuivARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetQueryObjectuivARB, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, id, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_UINT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetQueryObjectuivARB, (id, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetQueryObjectuivARB);
}

//////////////////////////////////////////////////////////////////////////
// GL_ARB_texture_compression extension
//////////////////////////////////////////////////////////////////////////
void APIENTRY glCompressedTexImage3DARB(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid* data)
{
    SU_START_FUNCTION_WRAPPER(ap_glCompressedTexImage3DARB);

    // Log the call to this function:
    GLuint boundTextureName = gs_stat_openGLMonitorInstance.boundTexture(target);
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glCompressedTexImage3DARB, 10, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_ENUM_PARAMETER, internalformat, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_SIZEI_PARAMETER, height, OS_TOBJ_ID_GL_SIZEI_PARAMETER, depth, OS_TOBJ_ID_GL_INT_PARAMETER, border, OS_TOBJ_ID_GL_SIZEI_PARAMETER, imageSize, OS_TOBJ_ID_GL_P_VOID_PARAMETER, data, OS_TOBJ_ID_ASSOCIATED_TEXTURE_NAMES_PSEUDO_PARAMETER, 1, &boundTextureName);

    // Check if stub textures are forced:
    bool areStubTexForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubTexForced = pCurrentThreadRenderContextMonitor->forcedModesManager().isStubForced(AP_OPENGL_FORCED_STUB_TEXTURES_MODE);
    }

    // If we are not in "Force stub textures" mode:
    if (!areStubTexForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glCompressedTexImage3DARB, (target, level, internalformat, width, height, depth, border, imageSize, data));

        // Log the loaded texture:
        if (NULL != pCurrentThreadRenderContextMonitor)
        {
            bool rcTex = pCurrentThreadRenderContextMonitor->onTextureImageLoaded(target, level, internalformat, width, height, depth, border, 0, 0);
            GT_ASSERT(rcTex);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glCompressedTexImage3DARB);
}

void APIENTRY glCompressedTexImage2DARB(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid* data)
{
    SU_START_FUNCTION_WRAPPER(ap_glCompressedTexImage2DARB);

    // Log the call to this function:
    GLuint boundTextureName = gs_stat_openGLMonitorInstance.boundTexture(target);
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glCompressedTexImage2DARB, 9, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_ENUM_PARAMETER, internalformat, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_SIZEI_PARAMETER, height, OS_TOBJ_ID_GL_INT_PARAMETER, border, OS_TOBJ_ID_GL_SIZEI_PARAMETER, imageSize, OS_TOBJ_ID_GL_P_VOID_PARAMETER, data, OS_TOBJ_ID_ASSOCIATED_TEXTURE_NAMES_PSEUDO_PARAMETER, 1, &boundTextureName);

    // Check if stub textures are forced:
    bool areStubTexForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubTexForced = pCurrentThreadRenderContextMonitor->forcedModesManager().isStubForced(AP_OPENGL_FORCED_STUB_TEXTURES_MODE);
    }

    // If we are not in "Force stub textures" mode:
    if (!areStubTexForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glCompressedTexImage2DARB, (target, level, internalformat, width, height, border, imageSize, data));

        // Log the loaded texture:
        if (NULL != pCurrentThreadRenderContextMonitor)
        {
            bool rcTex = pCurrentThreadRenderContextMonitor->onTextureImageLoaded(target, level, internalformat, width, height, 0, border, 0, 0);
            GT_ASSERT(rcTex);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glCompressedTexImage2DARB);
}

void APIENTRY glCompressedTexImage1DARB(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid* data)
{
    SU_START_FUNCTION_WRAPPER(ap_glCompressedTexImage1DARB);

    // Log the call to this function:
    GLuint boundTextureName = gs_stat_openGLMonitorInstance.boundTexture(target);
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glCompressedTexImage1DARB, 8, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_ENUM_PARAMETER, internalformat, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_INT_PARAMETER, border, OS_TOBJ_ID_GL_SIZEI_PARAMETER, imageSize, OS_TOBJ_ID_GL_P_VOID_PARAMETER, data, OS_TOBJ_ID_ASSOCIATED_TEXTURE_NAMES_PSEUDO_PARAMETER, 1, &boundTextureName);

    // Check if stub textures are forced:
    bool areStubTexForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubTexForced = pCurrentThreadRenderContextMonitor->forcedModesManager().isStubForced(AP_OPENGL_FORCED_STUB_TEXTURES_MODE);
    }

    // If we are not in "Force stub textures" mode:
    if (!areStubTexForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glCompressedTexImage1DARB, (target, level, internalformat, width, border, imageSize, data));

        // Log the loaded texture:
        if (NULL != pCurrentThreadRenderContextMonitor)
        {
            bool rcTex = pCurrentThreadRenderContextMonitor->onTextureImageLoaded(target, level, internalformat, width, 0, 0, border, 0, 0);
            GT_ASSERT(rcTex);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glCompressedTexImage1DARB);
}

void APIENTRY glCompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid* data)
{
    SU_START_FUNCTION_WRAPPER(ap_glCompressedTexSubImage3DARB);

    // Log the call to this function:
    GLuint boundTextureName = gs_stat_openGLMonitorInstance.boundTexture(target);
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glCompressedTexSubImage3DARB, 12, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_INT_PARAMETER, xoffset, OS_TOBJ_ID_GL_INT_PARAMETER, yoffset, OS_TOBJ_ID_GL_INT_PARAMETER, zoffset, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_SIZEI_PARAMETER, height, OS_TOBJ_ID_GL_SIZEI_PARAMETER, depth, OS_TOBJ_ID_GL_ENUM_PARAMETER, format, OS_TOBJ_ID_GL_SIZEI_PARAMETER, imageSize, OS_TOBJ_ID_GL_P_VOID_PARAMETER, data, OS_TOBJ_ID_ASSOCIATED_TEXTURE_NAMES_PSEUDO_PARAMETER, 1, &boundTextureName);

    // Check if stub textures are forced:
    bool areStubTexForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubTexForced = pCurrentThreadRenderContextMonitor->forcedModesManager().isStubForced(AP_OPENGL_FORCED_STUB_TEXTURES_MODE);
    }

    // If we are not in "Force stub textures" mode:
    if (!areStubTexForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glCompressedTexSubImage3DARB, (target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data));

        // Log the loaded sub-texture:
        if (NULL != pCurrentThreadRenderContextMonitor)
        {
            bool rcSubTex = pCurrentThreadRenderContextMonitor->onTextureSubImageLoaded(target, level);
            GT_ASSERT(rcSubTex);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glCompressedTexSubImage3DARB);
}

void APIENTRY glCompressedTexSubImage2DARB(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid* data)
{
    SU_START_FUNCTION_WRAPPER(ap_glCompressedTexSubImage2DARB);

    // Log the call to this function:
    GLuint boundTextureName = gs_stat_openGLMonitorInstance.boundTexture(target);
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glCompressedTexSubImage2DARB, 10, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_INT_PARAMETER, xoffset, OS_TOBJ_ID_GL_INT_PARAMETER, yoffset, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_SIZEI_PARAMETER, height, OS_TOBJ_ID_GL_ENUM_PARAMETER, format, OS_TOBJ_ID_GL_SIZEI_PARAMETER, imageSize, OS_TOBJ_ID_GL_P_VOID_PARAMETER, data, OS_TOBJ_ID_ASSOCIATED_TEXTURE_NAMES_PSEUDO_PARAMETER, 1, &boundTextureName);

    // Check if stub textures are forced:
    bool areStubTexForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubTexForced = pCurrentThreadRenderContextMonitor->forcedModesManager().isStubForced(AP_OPENGL_FORCED_STUB_TEXTURES_MODE);
    }

    // If we are not in "Force stub textures" mode:
    if (!areStubTexForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glCompressedTexSubImage2DARB, (target, level, xoffset, yoffset, width, height, format, imageSize, data));

        // Log the loaded sub-texture:
        if (NULL != pCurrentThreadRenderContextMonitor)
        {
            bool rcSubTex = pCurrentThreadRenderContextMonitor->onTextureSubImageLoaded(target, level);
            GT_ASSERT(rcSubTex);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glCompressedTexSubImage2DARB);
}

void APIENTRY glCompressedTexSubImage1DARB(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid* data)
{
    SU_START_FUNCTION_WRAPPER(ap_glCompressedTexSubImage1DARB);

    // Log the call to this function:
    GLuint boundTextureName = gs_stat_openGLMonitorInstance.boundTexture(target);
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glCompressedTexSubImage1DARB, 8, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_INT_PARAMETER, xoffset, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_ENUM_PARAMETER, format, OS_TOBJ_ID_GL_SIZEI_PARAMETER, imageSize, OS_TOBJ_ID_GL_P_VOID_PARAMETER, data, OS_TOBJ_ID_ASSOCIATED_TEXTURE_NAMES_PSEUDO_PARAMETER, 1, &boundTextureName);

    // Check if stub textures are forced:
    bool areStubTexForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubTexForced = pCurrentThreadRenderContextMonitor->forcedModesManager().isStubForced(AP_OPENGL_FORCED_STUB_TEXTURES_MODE);
    }

    // If we are not in "Force stub textures" mode:
    if (!areStubTexForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glCompressedTexSubImage1DARB, (target, level, xoffset, width, format, imageSize, data));

        // Log the loaded sub-texture:
        if (NULL != pCurrentThreadRenderContextMonitor)
        {
            bool rcSubTex = pCurrentThreadRenderContextMonitor->onTextureSubImageLoaded(target, level);
            GT_ASSERT(rcSubTex);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glCompressedTexSubImage1DARB);
}

void APIENTRY glGetCompressedTexImageARB(GLenum target, GLint lod, GLvoid* img)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetCompressedTexImageARB);

    // Get the input bind target bounded texture name:
    GLuint boundTextureName = gs_stat_openGLMonitorInstance.boundTexture(target);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetCompressedTexImageARB, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_INT_PARAMETER, lod, OS_TOBJ_ID_GL_P_VOID_PARAMETER, img, OS_TOBJ_ID_ASSOCIATED_TEXTURE_NAMES_PSEUDO_PARAMETER, 1, &boundTextureName);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetCompressedTexImageARB, (target, lod, img));

    SU_END_FUNCTION_WRAPPER(ap_glGetCompressedTexImageARB);
}

//////////////////////////////////////////////////////////////////////////
// GL_ARB_vertex_buffer_object extension
//////////////////////////////////////////////////////////////////////////
void APIENTRY glBindBufferARB(GLenum target, GLuint buffer)
{
    SU_START_FUNCTION_WRAPPER(ap_glBindBufferARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glBindBufferARB, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_UINT_PARAMETER, buffer);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glBindBufferARB, (target, buffer));

    // Log the textures generation:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        gsVBOMonitor* vboMonitor = pCurrentThreadRenderContextMonitor->vboMonitor();
        GT_IF_WITH_ASSERT(vboMonitor != NULL)
        {
            vboMonitor->onVertexBufferObjectTargetBind(target, buffer);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glBindBufferARB);
}

void APIENTRY glDeleteBuffersARB(GLsizei n, const GLuint* buffers)
{
    SU_START_FUNCTION_WRAPPER(ap_glDeleteBuffersARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glDeleteBuffersARB, 2, OS_TOBJ_ID_GL_SIZEI_PARAMETER, n, OS_TOBJ_ID_GL_P_UINT_PARAMETER, buffers);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glDeleteBuffersARB, (n, buffers));

    // Log the textures generation:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        gsVBOMonitor* vboMonitor = pCurrentThreadRenderContextMonitor->vboMonitor();
        GT_IF_WITH_ASSERT(vboMonitor != NULL)
        {
            vboMonitor->onVertexBufferObjectDeletion(n, buffers);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glDeleteBuffersARB);
}

void APIENTRY glGenBuffersARB(GLsizei n, GLuint* buffers)
{
    SU_START_FUNCTION_WRAPPER(ap_glGenBuffersARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGenBuffersARB, 2, OS_TOBJ_ID_GL_SIZEI_PARAMETER, n, OS_TOBJ_ID_GL_P_UINT_PARAMETER, buffers);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGenBuffersARB, (n, buffers));

    // Log the textures generation:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        gsVBOMonitor* vboMonitor = pCurrentThreadRenderContextMonitor->vboMonitor();
        GT_IF_WITH_ASSERT(vboMonitor != NULL)
        {
            vboMonitor->onVertexBufferObjectGeneration(n, buffers);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glGenBuffersARB);
}

GLboolean APIENTRY glIsBufferARB(GLuint buffer)
{
    bool inNestedFunction = su_stat_interoperabilityHelper.isInNestedFunction();
    SU_START_FUNCTION_WRAPPER(ap_glIsBufferARB);

    GLboolean retVal = GL_FALSE;

    if (!inNestedFunction)
    {
        // Log the call to this function:
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glIsBufferARB, 1, OS_TOBJ_ID_GL_UINT_PARAMETER, buffer);
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glIsBufferARB, (buffer), retVal);

    SU_END_FUNCTION_WRAPPER(ap_glIsBufferARB);

    return retVal;
}

void APIENTRY glBufferDataARB(GLenum target, GLsizeiptrARB size, const GLvoid* data, GLenum usage)
{
    SU_START_FUNCTION_WRAPPER(ap_glBufferDataARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glBufferDataARB, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_SIZEIPTR_PARAMETER, size, OS_TOBJ_ID_GL_P_VOID_PARAMETER, data, OS_TOBJ_ID_GL_ENUM_PARAMETER, usage);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glBufferDataARB, (target, size, data, usage));

    // Log the textures generation:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        gsVBOMonitor* vboMonitor = pCurrentThreadRenderContextMonitor->vboMonitor();
        GT_IF_WITH_ASSERT(vboMonitor != NULL)
        {
            vboMonitor->onVertexBufferObjectDataSet(target, size);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glBufferDataARB);
}

void APIENTRY glBufferSubDataARB(GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid* data)
{
    SU_START_FUNCTION_WRAPPER(ap_glBufferSubDataARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glBufferSubDataARB, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, target,  OS_TOBJ_ID_GL_INTPTR_PARAMETER, offset, OS_TOBJ_ID_GL_SIZEIPTR_PARAMETER, size, OS_TOBJ_ID_GL_P_VOID_PARAMETER, data);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glBufferSubDataARB, (target, offset, size, data));

    SU_END_FUNCTION_WRAPPER(ap_glBufferSubDataARB);
}

void APIENTRY glGetBufferSubDataARB(GLenum target, GLintptrARB offset, GLsizeiptrARB size, GLvoid* data)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetBufferSubDataARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetBufferSubDataARB, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_INTPTR_PARAMETER, offset, OS_TOBJ_ID_GL_SIZEIPTR_PARAMETER, size, OS_TOBJ_ID_GL_P_VOID_PARAMETER, data);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetBufferSubDataARB, (target, offset, size, data));

    SU_END_FUNCTION_WRAPPER(ap_glGetBufferSubDataARB);
}

GLvoid* APIENTRY glMapBufferARB(GLenum target, GLenum access)
{
    SU_START_FUNCTION_WRAPPER(ap_glMapBufferARB);

    GLvoid* retVal = NULL;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMapBufferARB, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, access);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glMapBufferARB, (target, access), retVal);

    SU_END_FUNCTION_WRAPPER(ap_glMapBufferARB);

    return retVal;
}

GLboolean APIENTRY glUnmapBufferARB(GLenum target)
{
    SU_START_FUNCTION_WRAPPER(ap_glUnmapBufferARB);

    GLboolean retVal = GL_FALSE;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glUnmapBufferARB, 1, OS_TOBJ_ID_GL_ENUM_PARAMETER, target);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glUnmapBufferARB, (target), retVal);

    // TO_DO: Might want to optimize this if the mapping was GL_READ_ONLY.
    // Log the vbo data set:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        gsVBOMonitor* vboMonitor = pCurrentThreadRenderContextMonitor->vboMonitor();
        GT_IF_WITH_ASSERT(vboMonitor != NULL)
        {
            vboMonitor->onVertexBufferObjectSubDataSet(target);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glUnmapBufferARB);

    return retVal;
}

void APIENTRY glGetBufferParameterivARB(GLenum target, GLenum pname, GLint* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetBufferParameterivARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetBufferParameterivARB, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetBufferParameterivARB, (target, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetBufferParameterivARB);
}

void APIENTRY glGetBufferPointervARB(GLenum target, GLenum pname, GLvoid** params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetBufferPointervARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetBufferPointervARB, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_PP_VOID_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetBufferPointervARB, (target, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetBufferPointervARB);
}

//////////////////////////////////////////////////////////////////////////
// GL_ARB_vertex_blend extension
//////////////////////////////////////////////////////////////////////////
void APIENTRY glWeightbvARB(GLint size, const GLbyte* weights)
{
    SU_START_FUNCTION_WRAPPER(ap_glWeightbvARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glWeightbvARB, 2, OS_TOBJ_ID_GL_INT_PARAMETER, size, OS_TOBJ_ID_GL_P_BYTE_PARAMETER, weights);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glWeightbvARB, (size, weights));

    SU_END_FUNCTION_WRAPPER(ap_glWeightbvARB);
}

void APIENTRY glWeightsvARB(GLint size, const GLshort* weights)
{
    SU_START_FUNCTION_WRAPPER(ap_glWeightsvARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glWeightsvARB, 2, OS_TOBJ_ID_GL_INT_PARAMETER, size, OS_TOBJ_ID_GL_P_SHORT_PARAMETER, weights);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glWeightsvARB, (size, weights));

    SU_END_FUNCTION_WRAPPER(ap_glWeightsvARB);
}

void APIENTRY glWeightivARB(GLint size, const GLint* weights)
{
    SU_START_FUNCTION_WRAPPER(ap_glWeightivARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glWeightivARB, 2, OS_TOBJ_ID_GL_INT_PARAMETER, size, OS_TOBJ_ID_GL_P_INT_PARAMETER, weights);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glWeightivARB, (size, weights));

    SU_END_FUNCTION_WRAPPER(ap_glWeightivARB);
}

void APIENTRY glWeightfvARB(GLint size, const GLfloat* weights)
{
    SU_START_FUNCTION_WRAPPER(ap_glWeightfvARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glWeightfvARB, 2, OS_TOBJ_ID_GL_INT_PARAMETER, size, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, weights);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glWeightfvARB, (size, weights));

    SU_END_FUNCTION_WRAPPER(ap_glWeightfvARB);
}

void APIENTRY glWeightdvARB(GLint size, const GLdouble* weights)
{
    SU_START_FUNCTION_WRAPPER(ap_glWeightdvARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glWeightdvARB, 2, OS_TOBJ_ID_GL_INT_PARAMETER, size, OS_TOBJ_ID_GL_P_DOUBLE_PARAMETER, weights);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glWeightdvARB, (size, weights));

    SU_END_FUNCTION_WRAPPER(ap_glWeightdvARB);
}

void APIENTRY glWeightubvARB(GLint size, const GLubyte* weights)
{
    SU_START_FUNCTION_WRAPPER(ap_glWeightubvARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glWeightubvARB, 2, OS_TOBJ_ID_GL_INT_PARAMETER, size, OS_TOBJ_ID_GL_P_UBYTE_PARAMETER, weights);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glWeightubvARB, (size, weights));

    SU_END_FUNCTION_WRAPPER(ap_glWeightubvARB);
}

void APIENTRY glWeightusvARB(GLint size, const GLushort* weights)
{
    SU_START_FUNCTION_WRAPPER(ap_glWeightusvARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glWeightusvARB, 2, OS_TOBJ_ID_GL_INT_PARAMETER, size, OS_TOBJ_ID_GL_P_USHORT_PARAMETER, weights);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glWeightusvARB, (size, weights));

    SU_END_FUNCTION_WRAPPER(ap_glWeightusvARB);
}

void APIENTRY glWeightuivARB(GLint size, const GLuint* weights)
{
    SU_START_FUNCTION_WRAPPER(ap_glWeightuivARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glWeightuivARB, 2, OS_TOBJ_ID_GL_INT_PARAMETER, size, OS_TOBJ_ID_GL_P_UINT_PARAMETER, weights);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glWeightuivARB, (size, weights));

    SU_END_FUNCTION_WRAPPER(ap_glWeightuivARB);
}

void APIENTRY glWeightPointerARB(GLint size, GLenum type, GLsizei stribe, const GLvoid* pointer)
{
    SU_START_FUNCTION_WRAPPER(ap_glWeightPointerARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glWeightPointerARB, 4, OS_TOBJ_ID_GL_INT_PARAMETER, size, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_SIZEI_PARAMETER, stribe, OS_TOBJ_ID_GL_P_VOID_PARAMETER, pointer);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glWeightPointerARB, (size, type, stribe, pointer));

    SU_END_FUNCTION_WRAPPER(ap_glWeightPointerARB);
}

void APIENTRY glVertexBlendARB(GLint count)
{
    SU_START_FUNCTION_WRAPPER(ap_glVertexBlendARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexBlendARB, 1, OS_TOBJ_ID_GL_INT_PARAMETER, count);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexBlendARB, (count));

    SU_END_FUNCTION_WRAPPER(ap_glVertexBlendARB);
}


//////////////////////////////////////////////////////////////////////////
// GL_EXT_texture3D
//////////////////////////////////////////////////////////////////////////
void APIENTRY glTexImage3DEXT(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid* pixels)
{
    SU_START_FUNCTION_WRAPPER(ap_glTexImage3DEXT);

    // Check if stub textures are forced:
    bool areStubTexForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubTexForced = pCurrentThreadRenderContextMonitor->forcedModesManager().isStubForced(AP_OPENGL_FORCED_STUB_TEXTURES_MODE);
    }

    // If we are not in "Force stub textures" mode:
    if (!areStubTexForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glTexImage3DEXT, (target, level, internalformat, width, height, depth, border, format, type, pixels));

        // Log the loaded texture:
        gsRenderContextMonitor* pCurrentThreadRenderContextMonitorInner = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

        if (NULL != pCurrentThreadRenderContextMonitorInner)
        {
            bool rcTex = pCurrentThreadRenderContextMonitorInner->onTextureImageLoaded(target, level, internalformat, width, height, depth, border, format, type);
            GT_ASSERT(rcTex);
        }
    }

    // Log the call to this function:
    GLuint boundTextureName = gs_stat_openGLMonitorInstance.boundTexture(target);
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTexImage3DEXT, 11, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_PIXEL_INTERNAL_FORMAT_PARAMETER, internalformat, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_SIZEI_PARAMETER, height, OS_TOBJ_ID_GL_SIZEI_PARAMETER, depth, OS_TOBJ_ID_GL_INT_PARAMETER, border, OS_TOBJ_ID_GL_ENUM_PARAMETER, format, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_P_VOID_PARAMETER, pixels, OS_TOBJ_ID_ASSOCIATED_TEXTURE_NAMES_PSEUDO_PARAMETER, 1, &boundTextureName);

    SU_END_FUNCTION_WRAPPER(ap_glTexImage3DEXT);
}


void APIENTRY glTexSubImage3DEXT(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid* pixels)
{
    SU_START_FUNCTION_WRAPPER(ap_glTexSubImage3DEXT);

    // Check if stub textures are forced:
    bool areStubTexForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubTexForced = pCurrentThreadRenderContextMonitor->forcedModesManager().isStubForced(AP_OPENGL_FORCED_STUB_TEXTURES_MODE);
    }

    // If we are not in "Force stub textures" mode:
    if (!areStubTexForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glTexSubImage3DEXT, (target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels));

        // Log the loaded sub-texture:
        if (NULL != pCurrentThreadRenderContextMonitor)
        {
            bool rcSubTex = pCurrentThreadRenderContextMonitor->onTextureSubImageLoaded(target, level);
            GT_ASSERT(rcSubTex);
        }
    }

    // Log the call to this function:
    GLuint boundTextureName = gs_stat_openGLMonitorInstance.boundTexture(target);
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTexSubImage3DEXT, 12, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_INT_PARAMETER, xoffset, OS_TOBJ_ID_GL_INT_PARAMETER, yoffset, OS_TOBJ_ID_GL_INT_PARAMETER, zoffset, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_SIZEI_PARAMETER, height, OS_TOBJ_ID_GL_SIZEI_PARAMETER, depth, OS_TOBJ_ID_GL_ENUM_PARAMETER, format, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_P_VOID_PARAMETER, pixels, OS_TOBJ_ID_ASSOCIATED_TEXTURE_NAMES_PSEUDO_PARAMETER, 1, &boundTextureName);

    SU_END_FUNCTION_WRAPPER(ap_glTexSubImage3DEXT);
}

//////////////////////////////////////////////////////////////////////////
// GL_ARB_vertex_program
//////////////////////////////////////////////////////////////////////////
void APIENTRY glVertexAttrib1dARB(GLuint index, GLdouble x)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib1dARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib1dARB, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, x);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib1dARB, (index, x));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib1dARB);
}

void APIENTRY glVertexAttrib1dvARB(GLuint index, const GLdouble* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib1dvARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib1dvARB, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, 1, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib1dvARB, (index, v));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib1dvARB);
}

void APIENTRY glVertexAttrib1fARB(GLuint index, GLfloat x)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib1fARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib1fARB, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_FLOAT_PARAMETER, x);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib1fARB, (index, x));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib1fARB);
}

void APIENTRY glVertexAttrib1fvARB(GLuint index, const GLfloat* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib1fvARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib1fvARB, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_FLOAT_PARAMETER, 1, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib1fvARB, (index, v));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib1fvARB);
}

void APIENTRY glVertexAttrib1sARB(GLuint index, GLshort x)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib1sARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib1sARB, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_SHORT_PARAMETER, x);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib1sARB, (index, x));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib1sARB);
}

void APIENTRY glVertexAttrib1svARB(GLuint index, const GLshort* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib1svARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib1svARB, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_SHORT_PARAMETER, 1, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib1svARB, (index, v));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib1svARB);
}

void APIENTRY glVertexAttrib2dARB(GLuint index, GLdouble x, GLdouble y)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib2dARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib2dARB, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, x, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, y);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib2dARB, (index, x, y));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib2dARB);
}

void APIENTRY glVertexAttrib2dvARB(GLuint index, const GLdouble* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib2dvARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib2dvARB, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, 2, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib2dvARB, (index, v));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib2dvARB);
}

void APIENTRY glVertexAttrib2fARB(GLuint index, GLfloat x, GLfloat y)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib2fARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib2fARB, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_FLOAT_PARAMETER, x, OS_TOBJ_ID_GL_FLOAT_PARAMETER, y);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib2fARB, (index, x, y));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib2fARB);
}

void APIENTRY glVertexAttrib2fvARB(GLuint index, const GLfloat* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib2fvARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib2fvARB, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_FLOAT_PARAMETER, 2, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib2fvARB, (index, v));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib2fvARB);
}

void APIENTRY glVertexAttrib2sARB(GLuint index, GLshort x, GLshort y)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib2sARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib2sARB, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_SHORT_PARAMETER, x, OS_TOBJ_ID_GL_SHORT_PARAMETER, y);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib2sARB, (index, x, y));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib2sARB);
}

void APIENTRY glVertexAttrib2svARB(GLuint index, const GLshort* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib2svARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib2svARB, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_SHORT_PARAMETER, 2, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib2svARB, (index, v));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib2svARB);
}

void APIENTRY glVertexAttrib3dARB(GLuint index, GLdouble x, GLdouble y, GLdouble z)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib3dARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib3dARB, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, x, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, y, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, z);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib3dARB, (index, x, y, z));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib3dARB);
}

void APIENTRY glVertexAttrib3dvARB(GLuint index, const GLdouble* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib3dvARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib3dvARB, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, 3, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib3dvARB, (index, v));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib3dvARB);
}

void APIENTRY glVertexAttrib3fARB(GLuint index, GLfloat x, GLfloat y, GLfloat z)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib3fARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib3fARB, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_FLOAT_PARAMETER, x, OS_TOBJ_ID_GL_FLOAT_PARAMETER, y, OS_TOBJ_ID_GL_FLOAT_PARAMETER, z);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib3fARB, (index, x, y, z));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib3fARB);
}

void APIENTRY glVertexAttrib3fvARB(GLuint index, const GLfloat* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib3fvARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib3fvARB, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_FLOAT_PARAMETER, 3, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib3fvARB, (index, v));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib3fvARB);
}

void APIENTRY glVertexAttrib3sARB(GLuint index, GLshort x, GLshort y, GLshort z)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib3sARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib3sARB, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_SHORT_PARAMETER, x, OS_TOBJ_ID_GL_SHORT_PARAMETER, y, OS_TOBJ_ID_GL_SHORT_PARAMETER, z);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib3sARB, (index, x, y, z));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib3sARB);
}

void APIENTRY glVertexAttrib3svARB(GLuint index, const GLshort* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib3svARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib3svARB, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_SHORT_PARAMETER, 3, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib3svARB, (index, v));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib3svARB);
}

void APIENTRY glVertexAttrib4NbvARB(GLuint index, const GLbyte* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib4NbvARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib4NbvARB, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_BYTE_PARAMETER, 4, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib4NbvARB, (index, v));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib4NbvARB);
}

void APIENTRY glVertexAttrib4NivARB(GLuint index, const GLint* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib4NivARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib4NivARB, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_INT_PARAMETER, 4, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib4NivARB, (index, v));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib4NivARB);
}

void APIENTRY glVertexAttrib4NsvARB(GLuint index, const GLshort* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib4NsvARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib4NsvARB, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_SHORT_PARAMETER, 4, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib4NsvARB, (index, v));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib4NsvARB);
}

void APIENTRY glVertexAttrib4NubARB(GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib4NubARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib4NubARB, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_UBYTE_PARAMETER, x, OS_TOBJ_ID_GL_UBYTE_PARAMETER, y, OS_TOBJ_ID_GL_UBYTE_PARAMETER, z, OS_TOBJ_ID_GL_UBYTE_PARAMETER, w);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib4NubARB, (index, x, y, z, w));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib4NubARB);
}

void APIENTRY glVertexAttrib4NubvARB(GLuint index, const GLubyte* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib4NubvARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib4NubvARB, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_UBYTE_PARAMETER, 4, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib4NubvARB, (index, v));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib4NubvARB);
}

void APIENTRY glVertexAttrib4NuivARB(GLuint index, const GLuint* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib4NuivARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib4NuivARB, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_UINT_PARAMETER, 4, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib4NuivARB, (index, v));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib4NuivARB);
}

void APIENTRY glVertexAttrib4NusvARB(GLuint index, const GLushort* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib4NusvARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib4NusvARB, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_USHORT_PARAMETER, 4, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib4NusvARB, (index, v));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib4NusvARB);
}

void APIENTRY glVertexAttrib4bvARB(GLuint index, const GLbyte* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib4bvARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib4bvARB, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_BYTE_PARAMETER, 4, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib4bvARB, (index, v));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib4bvARB);
}

void APIENTRY glVertexAttrib4dARB(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib4dARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib4dARB, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, x, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, y, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, z, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, w);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib4dARB, (index, x, y, z, w));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib4dARB);
}

void APIENTRY glVertexAttrib4dvARB(GLuint index, const GLdouble* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib4dvARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib4dvARB, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, 4, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib4dvARB, (index, v));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib4dvARB);
}

void APIENTRY glVertexAttrib4fARB(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib4fARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib4fARB, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_FLOAT_PARAMETER, x, OS_TOBJ_ID_GL_FLOAT_PARAMETER, y, OS_TOBJ_ID_GL_FLOAT_PARAMETER, z, OS_TOBJ_ID_GL_FLOAT_PARAMETER, w);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib4fARB, (index, x, y, z, w));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib4fARB);
}

void APIENTRY glVertexAttrib4fvARB(GLuint index, const GLfloat* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib4fvARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib4fvARB, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_FLOAT_PARAMETER, 4, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib4fvARB, (index, v));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib4fvARB);
}

void APIENTRY glVertexAttrib4ivARB(GLuint index, const GLint* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib4ivARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib4ivARB, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_INT_PARAMETER, 4, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib4ivARB, (index, v));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib4ivARB);
}

void APIENTRY glVertexAttrib4sARB(GLuint index, GLshort x, GLshort y, GLshort z, GLshort w)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib4sARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib4sARB, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_SHORT_PARAMETER, x, OS_TOBJ_ID_GL_SHORT_PARAMETER, y, OS_TOBJ_ID_GL_SHORT_PARAMETER, z, OS_TOBJ_ID_GL_SHORT_PARAMETER, w);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib4sARB, (index, x, y, z, w));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib4sARB);
}

void APIENTRY glVertexAttrib4svARB(GLuint index, const GLshort* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib4svARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib4svARB, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_SHORT_PARAMETER, 4, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib4svARB, (index, v));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib4svARB);
}

void APIENTRY glVertexAttrib4ubvARB(GLuint index, const GLubyte* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib4ubvARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib4ubvARB, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_UBYTE_PARAMETER, 4, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib4ubvARB, (index, v));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib4ubvARB);
}

void APIENTRY glVertexAttrib4uivARB(GLuint index, const GLuint* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib4uivARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib4uivARB, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_UINT_PARAMETER, 4, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib4uivARB, (index, v));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib4uivARB);
}

void APIENTRY glVertexAttrib4usvARB(GLuint index, const GLushort* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib4usvARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib4usvARB, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_USHORT_PARAMETER, 4, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib4usvARB, (index, v));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib4usvARB);
}

void APIENTRY glVertexAttribPointerARB(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* pointer)
{
    SU_START_FUNCTION_WRAPPER(ap_glVertexAttribPointerARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttribPointerARB, 6, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_INT_PARAMETER, size, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_BOOL_PARAMETER, normalized, OS_TOBJ_ID_GL_SIZEI_PARAMETER, stride, OS_TOBJ_ID_GL_P_VOID_PARAMETER, pointer);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttribPointerARB, (index, size, type, normalized, stride, pointer));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttribPointerARB);
}

void APIENTRY glEnableVertexAttribArrayARB(GLuint index)
{
    SU_START_FUNCTION_WRAPPER(ap_glEnableVertexAttribArrayARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glEnableVertexAttribArrayARB, 1, OS_TOBJ_ID_GL_UINT_PARAMETER, index);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glEnableVertexAttribArrayARB, (index));

    SU_END_FUNCTION_WRAPPER(ap_glEnableVertexAttribArrayARB);
}

void APIENTRY glDisableVertexAttribArrayARB(GLuint index)
{
    SU_START_FUNCTION_WRAPPER(ap_glDisableVertexAttribArrayARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glDisableVertexAttribArrayARB, 1, OS_TOBJ_ID_GL_UINT_PARAMETER, index);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glDisableVertexAttribArrayARB, (index));

    SU_END_FUNCTION_WRAPPER(ap_glDisableVertexAttribArrayARB);
}

void APIENTRY glProgramStringARB(GLenum target, GLenum format, GLsizei len, const GLvoid* string)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramStringARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramStringARB, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, format, OS_TOBJ_ID_GL_SIZEI_PARAMETER, len, OS_TOBJ_ID_GL_P_VOID_PARAMETER, string);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glProgramStringARB, (target, format, len, string));

    SU_END_FUNCTION_WRAPPER(ap_glProgramStringARB);
}

void APIENTRY glBindProgramARB(GLenum target, GLuint program)
{
    SU_START_FUNCTION_WRAPPER(ap_glBindProgramARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glBindProgramARB, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_UINT_PARAMETER, program);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glBindProgramARB, (target, program));

    SU_END_FUNCTION_WRAPPER(ap_glBindProgramARB);
}

void APIENTRY glDeleteProgramsARB(GLsizei n, const GLuint* programs)
{
    SU_START_FUNCTION_WRAPPER(ap_glDeleteProgramsARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glDeleteProgramsARB, 2, OS_TOBJ_ID_GL_SIZEI_PARAMETER, n, OS_TOBJ_ID_GL_P_UINT_PARAMETER, programs);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glDeleteProgramsARB, (n, programs));

    SU_END_FUNCTION_WRAPPER(ap_glDeleteProgramsARB);
}

void APIENTRY glGenProgramsARB(GLsizei n, GLuint* programs)
{
    SU_START_FUNCTION_WRAPPER(ap_glGenProgramsARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGenProgramsARB, 2, OS_TOBJ_ID_GL_SIZEI_PARAMETER, n, OS_TOBJ_ID_GL_P_UINT_PARAMETER, programs);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGenProgramsARB, (n, programs));

    SU_END_FUNCTION_WRAPPER(ap_glGenProgramsARB);
}

void APIENTRY glProgramEnvParameter4dARB(GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramEnvParameter4dARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramEnvParameter4dARB, 6, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, x, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, y, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, z, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, w);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glProgramEnvParameter4dARB, (target, index, x, y, z, w));

    SU_END_FUNCTION_WRAPPER(ap_glProgramEnvParameter4dARB);
}

void APIENTRY glProgramEnvParameter4dvARB(GLenum target, GLuint index, const GLdouble* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramEnvParameter4dvARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramEnvParameter4dvARB, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_P_DOUBLE_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glProgramEnvParameter4dvARB, (target, index, params));

    SU_END_FUNCTION_WRAPPER(ap_glProgramEnvParameter4dvARB);
}

void APIENTRY glProgramEnvParameter4fARB(GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramEnvParameter4fARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramEnvParameter4fARB, 6, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_FLOAT_PARAMETER, x, OS_TOBJ_ID_GL_FLOAT_PARAMETER, y, OS_TOBJ_ID_GL_FLOAT_PARAMETER, z, OS_TOBJ_ID_GL_FLOAT_PARAMETER, w);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glProgramEnvParameter4fARB, (target, index, x, y, z, w));

    SU_END_FUNCTION_WRAPPER(ap_glProgramEnvParameter4fARB);
}

void APIENTRY glProgramEnvParameter4fvARB(GLenum target, GLuint index, const GLfloat* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramEnvParameter4fvARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramEnvParameter4fvARB, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glProgramEnvParameter4fvARB, (target, index, params));

    SU_END_FUNCTION_WRAPPER(ap_glProgramEnvParameter4fvARB);
}

void APIENTRY glProgramLocalParameter4dARB(GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramLocalParameter4dARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramLocalParameter4dARB, 6, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, x, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, y, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, z, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, w);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glProgramLocalParameter4dARB, (target, index, x, y, z, w));

    SU_END_FUNCTION_WRAPPER(ap_glProgramLocalParameter4dARB);
}

void APIENTRY glProgramLocalParameter4dvARB(GLenum target, GLuint index, const GLdouble* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramLocalParameter4dvARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramLocalParameter4dvARB, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_P_DOUBLE_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glProgramLocalParameter4dvARB, (target, index, params));

    SU_END_FUNCTION_WRAPPER(ap_glProgramLocalParameter4dvARB);
}

void APIENTRY glProgramLocalParameter4fARB(GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramLocalParameter4fARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramLocalParameter4fARB, 6, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_FLOAT_PARAMETER, x, OS_TOBJ_ID_GL_FLOAT_PARAMETER, y, OS_TOBJ_ID_GL_FLOAT_PARAMETER, z, OS_TOBJ_ID_GL_FLOAT_PARAMETER, w);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glProgramLocalParameter4fARB, (target, index, x, y, z, w));

    SU_END_FUNCTION_WRAPPER(ap_glProgramLocalParameter4fARB);
}

void APIENTRY glProgramLocalParameter4fvARB(GLenum target, GLuint index, const GLfloat* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramLocalParameter4fvARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramLocalParameter4fvARB, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glProgramLocalParameter4fvARB, (target, index, params));

    SU_END_FUNCTION_WRAPPER(ap_glProgramLocalParameter4fvARB);
}

void APIENTRY glGetProgramEnvParameterdvARB(GLenum target, GLuint index, GLdouble* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetProgramEnvParameterdvARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetProgramEnvParameterdvARB, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_P_DOUBLE_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetProgramEnvParameterdvARB, (target, index, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetProgramEnvParameterdvARB);
}

void APIENTRY glGetProgramEnvParameterfvARB(GLenum target, GLuint index, GLfloat* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetProgramEnvParameterfvARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetProgramEnvParameterfvARB, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetProgramEnvParameterfvARB, (target, index, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetProgramEnvParameterfvARB);
}

void APIENTRY glGetProgramLocalParameterdvARB(GLenum target, GLuint index, GLdouble* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetProgramLocalParameterdvARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetProgramLocalParameterdvARB, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_P_DOUBLE_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetProgramLocalParameterdvARB, (target, index, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetProgramLocalParameterdvARB);
}

void APIENTRY glGetProgramLocalParameterfvARB(GLenum target, GLuint index, GLfloat* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetProgramLocalParameterfvARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetProgramLocalParameterfvARB, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetProgramLocalParameterfvARB, (target, index, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetProgramLocalParameterfvARB);
}

void APIENTRY glGetProgramivARB(GLenum target, GLenum pname, GLint* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetProgramivARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetProgramivARB, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetProgramivARB, (target, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetProgramivARB);
}

void APIENTRY glGetProgramStringARB(GLenum target, GLenum pname, GLvoid* string)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetProgramStringARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetProgramStringARB, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_VOID_PARAMETER, string);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetProgramStringARB, (target, pname, string));

    SU_END_FUNCTION_WRAPPER(ap_glGetProgramStringARB);
}

void APIENTRY glGetVertexAttribdvARB(GLuint index, GLenum pname, GLdouble* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetVertexAttribdvARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetVertexAttribdvARB, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_DOUBLE_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetVertexAttribdvARB, (index, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetVertexAttribdvARB);
}

void APIENTRY glGetVertexAttribfvARB(GLuint index, GLenum pname, GLfloat* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetVertexAttribfvARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetVertexAttribfvARB, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetVertexAttribfvARB, (index, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetVertexAttribfvARB);
}

void APIENTRY glGetVertexAttribivARB(GLuint index, GLenum pname, GLint* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetVertexAttribivARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetVertexAttribivARB, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetVertexAttribivARB, (index, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetVertexAttribivARB);
}

void APIENTRY glGetVertexAttribPointervARB(GLuint index, GLenum pname, GLvoid** pointer)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetVertexAttribPointervARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetVertexAttribPointervARB, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_PP_VOID_PARAMETER, pointer);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetVertexAttribPointervARB, (index, pname, pointer));

    SU_END_FUNCTION_WRAPPER(ap_glGetVertexAttribPointervARB);
}

GLboolean APIENTRY glIsProgramARB(GLuint program)
{
    SU_START_FUNCTION_WRAPPER(ap_glIsProgramARB);

    GLboolean retVal = GL_FALSE;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glIsProgramARB, 1, OS_TOBJ_ID_GL_UINT_PARAMETER, program);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glIsProgramARB, (program), retVal);

    SU_END_FUNCTION_WRAPPER(ap_glIsProgramARB);

    return retVal;
}

//////////////////////////////////////////////////////////////////////////
// GL_ARB_vertex_shader
//////////////////////////////////////////////////////////////////////////
void APIENTRY glBindAttribLocationARB(GLhandleARB programObj, GLuint index, const GLcharARB* name)
{
    SU_START_FUNCTION_WRAPPER(ap_glBindAttribLocationARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glBindAttribLocationARB, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, programObj, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_STRING_PARAMETER, name, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, programObj);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glBindAttribLocationARB, (programObj, index, name));

    SU_END_FUNCTION_WRAPPER(ap_glBindAttribLocationARB);
}

void APIENTRY glGetActiveAttribARB(GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei* length, GLint* size, GLenum* type, GLcharARB* name)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetActiveAttribARB);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetActiveAttribARB, (programObj, index, maxLength, length, size, type, name));

    // Log the call to this function:
    // Carefully - length can be NULL:
    if (length != NULL)
    {
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetActiveAttribARB, 8, OS_TOBJ_ID_GL_UINT_PARAMETER, programObj, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_SIZEI_PARAMETER, maxLength, OS_TOBJ_ID_GL_SIZEI_PARAMETER, *length, OS_TOBJ_ID_GL_INT_PARAMETER, *size, OS_TOBJ_ID_GL_ENUM_PARAMETER, *type, OS_TOBJ_ID_STRING_PARAMETER, name, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, programObj);
    }
    else
    {
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetActiveAttribARB, 8, OS_TOBJ_ID_GL_UINT_PARAMETER, programObj, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_SIZEI_PARAMETER, maxLength, OS_TOBJ_ID_GL_P_SIZEI_PARAMETER, length, OS_TOBJ_ID_GL_INT_PARAMETER, *size, OS_TOBJ_ID_GL_ENUM_PARAMETER, *type, OS_TOBJ_ID_STRING_PARAMETER, name, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, programObj);
    }

    SU_END_FUNCTION_WRAPPER(ap_glGetActiveAttribARB);
}

GLint APIENTRY glGetAttribLocationARB(GLhandleARB programObj, const GLcharARB* name)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetAttribLocationARB);

    GLint retVal = 0;

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glGetAttribLocationARB, (programObj, name), retVal);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetAttribLocationARB, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, programObj, OS_TOBJ_ID_STRING_PARAMETER, name, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, programObj);

    SU_END_FUNCTION_WRAPPER(ap_glGetAttribLocationARB);

    return retVal;
}

//////////////////////////////////////////////////////////////////////////
// GL_ARB_shader_objects
//////////////////////////////////////////////////////////////////////////
void APIENTRY glDeleteObjectARB(GLhandleARB obj)
{
    SU_START_FUNCTION_WRAPPER(ap_glDeleteObjectARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glDeleteObjectARB, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, obj, OS_TOBJ_ID_ASSOCIATED_SHADER_NAME_PSEUDO_PARAMETER, obj);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glDeleteObjectARB, (obj));

    // Log the program object:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        gsProgramsAndShadersMonitor* progAndShaderMon = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();

        GT_IF_WITH_ASSERT(progAndShaderMon != NULL)
        {
            // If this is a program object:
            if (progAndShaderMon->isProgramObject(obj))
            {
                progAndShaderMon->onProgramDeletion(obj);
            }
            else if (progAndShaderMon->isShaderObject(obj))
            {
                // This is a shader object:
                progAndShaderMon->onShaderObjectDeletion(obj);
            }
            else
            {
                // Generate a detected error:
                gtString errorDescription;
                apErrorCode errorCode = AP_OBJECT_NAME_DOES_NOT_EXIST_ERROR;

                errorDescription = GS_STR_usingNonObjectName;
                errorDescription.appendFormattedString(L": (object name = %u)", obj);

                gs_stat_openGLMonitorInstance.reportDetectedError(errorCode, errorDescription, ap_glDeleteObjectARB);
            }
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glDeleteObjectARB);
}

GLhandleARB APIENTRY glGetHandleARB(GLenum pname)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetHandleARB);

    // Call the real function:
    GLhandleARB retVal = 0;
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glGetHandleARB, (pname), retVal);

    // Log the call to this function:
    if (pname == GL_PROGRAM_OBJECT_ARB)
    {
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetHandleARB, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, retVal);
    }
    else
    {
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetHandleARB, 1, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname);
    }

    SU_END_FUNCTION_WRAPPER(ap_glGetHandleARB);

    return retVal;
}

void APIENTRY glDetachObjectARB(GLhandleARB containerObj, GLhandleARB attachedObj)
{
    SU_START_FUNCTION_WRAPPER(ap_glDetachObjectARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glDetachObjectARB, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, containerObj, OS_TOBJ_ID_GL_UINT_PARAMETER, attachedObj, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, containerObj, OS_TOBJ_ID_ASSOCIATED_SHADER_NAME_PSEUDO_PARAMETER, attachedObj);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    // (We do not call the real function if stub fragment shaders are forced and the detached
    //  shader is a fragment shader)
    bool shouldCallRealFunc = true;

    if (areStubFSGSForced)
    {
        if (NULL != pCurrentThreadRenderContextMonitor)
        {
            gsProgramsAndShadersMonitor* progAndShaderMon = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
            GT_IF_WITH_ASSERT(progAndShaderMon != NULL)
            {
                // Only call the function for vertex shaders and objects we do not identify:
                osTransferableObjectType shaderType = progAndShaderMon->shaderObjectType(attachedObj);

                if ((OS_TOBJ_ID_GL_VERTEX_SHADER != shaderType) && (OS_AMOUNT_OF_TRANSFERABLE_OBJECT_TYPES != shaderType))
                {
                    shouldCallRealFunc = false;
                }
            }
        }
    }

    if (shouldCallRealFunc)
    {
        SU_CALL_EXTENSION_FUNC(glDetachObjectARB, (containerObj, attachedObj));
    }

    // Log the detached shader:
    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        gsProgramsAndShadersMonitor* progAndShaderMon = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(progAndShaderMon != NULL)
        {
            bool rc = progAndShaderMon->onShaderDetachedFromProgram(containerObj, attachedObj);

            if (!rc)
            {
                // Generate a detected error:
                gtString errorDescription;
                apErrorCode errorCode = AP_OBJECT_NAME_DOES_NOT_EXIST_ERROR;

                errorDescription.appendFormattedString(GS_STR_shaderIsNotAttached, attachedObj, containerObj);

                gs_stat_openGLMonitorInstance.reportDetectedError(errorCode, errorDescription, ap_glDetachObjectARB);
            }
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glDetachObjectARB);
}

GLhandleARB APIENTRY glCreateShaderObjectARB(GLenum shaderType)
{
    SU_START_FUNCTION_WRAPPER(ap_glCreateShaderObjectARB);

    // Call the real function:
    GLhandleARB retVal = 0;
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glCreateShaderObjectARB, (shaderType), retVal);

    // Log the shader creation:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        gsProgramsAndShadersMonitor* progAndShaderMon = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(progAndShaderMon != NULL)
        {
            switch (shaderType)
            {
                case GL_VERTEX_SHADER:
                {
                    progAndShaderMon->onVertexShaderCreation(retVal, AP_GL_ARB_SHADER_OBJECTS_EXTENSION_SHADING_OBJECT);
                }
                break;

                case GL_FRAGMENT_SHADER:
                {
                    progAndShaderMon->onFragmentShaderCreation(retVal, AP_GL_ARB_SHADER_OBJECTS_EXTENSION_SHADING_OBJECT);
                }
                break;

                case GL_GEOMETRY_SHADER:
                {
                    progAndShaderMon->onGeometryShaderCreation(retVal, AP_GL_ARB_SHADER_OBJECTS_EXTENSION_SHADING_OBJECT);
                }
                break;

                case GL_TESS_CONTROL_SHADER:
                {
                    progAndShaderMon->onTessellationControlShaderCreation(retVal, AP_GL_ARB_SHADER_OBJECTS_EXTENSION_SHADING_OBJECT);
                }
                break;

                case GL_TESS_EVALUATION_SHADER:
                {
                    progAndShaderMon->onTessellationEvaluationShaderCreation(retVal, AP_GL_ARB_SHADER_OBJECTS_EXTENSION_SHADING_OBJECT);
                }
                break;

                case GL_COMPUTE_SHADER:
                {
                    progAndShaderMon->onComputeShaderCreation(retVal, AP_GL_ARB_SHADER_OBJECTS_EXTENSION_SHADING_OBJECT);
                }
                break;

                default:
                {
                    // Unknown shader type:
                    GT_ASSERT(false);
                    progAndShaderMon->onUnsupportedShaderCreation(retVal, AP_GL_ARB_SHADER_OBJECTS_EXTENSION_SHADING_OBJECT);
                }
                break;
            }
        }
    }

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glCreateShaderObjectARB, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, shaderType, OS_TOBJ_ID_ASSOCIATED_SHADER_NAME_PSEUDO_PARAMETER, retVal);

    SU_END_FUNCTION_WRAPPER(ap_glCreateShaderObjectARB);

    return retVal;
}

void APIENTRY glShaderSourceARB(GLhandleARB shaderObj, GLsizei count, const GLcharARB** string, const GLint* length)
{
    SU_START_FUNCTION_WRAPPER(ap_glShaderSourceARB);

    // Will get true iff the input shader is in "forced shader source code" mode:
    bool isShaderSourceCodeForced = false;

    // Log the shader source code:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        gsProgramsAndShadersMonitor* progAndShaderMon = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(progAndShaderMon != NULL)
        {
            if (progAndShaderMon->isShaderObject(shaderObj))
            {
                // Get the shader object details:
                const apGLShaderObject* pShaderObjDetails = progAndShaderMon->shaderObjectDetails(shaderObj);
                GT_IF_WITH_ASSERT(pShaderObjDetails != NULL)
                {
                    // Check if the shader source code is forced:
                    isShaderSourceCodeForced = pShaderObjDetails->isSourceCodeForced();
                }

                if (!isShaderSourceCodeForced)
                {
                    progAndShaderMon->onShaderSourceCodeSet(shaderObj, count, string, length);
                }
            }
            else
            {
                // Generate a detected error:
                gtString errorDescription;
                apErrorCode errorCode = AP_OBJECT_NAME_DOES_NOT_EXIST_ERROR;

                errorDescription = GS_STR_usingNonObjectName;
                errorDescription.appendFormattedString(L": (shader name = %u)", shaderObj);

                gs_stat_openGLMonitorInstance.reportDetectedError(errorCode, errorDescription, ap_glShaderSourceARB);
            }
        }
    }

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glShaderSourceARB, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, shaderObj, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_PP_CHAR, string,  OS_TOBJ_ID_GL_P_UINT_PARAMETER, length, OS_TOBJ_ID_ASSOCIATED_SHADER_NAME_PSEUDO_PARAMETER, shaderObj);

    if (!isShaderSourceCodeForced)
    {
        bool callRealFunction = suGetGlobalServerEnvironmentSettings().m_suDontFixCRInSourceStrings;

        if (!callRealFunction)
        {
            gtASCIIString modifiedSource;
            unsigned int* sourceLengths = new unsigned int[(count > 0) ? count : 1];

            for (GLsizei i = 0; i < count; ++i)
            {
                sourceLengths[i] = (nullptr != length) ? (unsigned int)length[i] : 0;
            }

            bool callWithModified = suHandleCRInSources((unsigned int)count, string, sourceLengths, modifiedSource);
            callRealFunction = !callWithModified;

            if (callWithModified)
            {
                // Call the real function with the modified values:
                const char* modifiedSourceAsCharArray = modifiedSource.asCharArray();
                GLint modifiedSourceLength = (GLint)modifiedSource.length();
                SU_CALL_EXTENSION_FUNC(glShaderSourceARB, (shaderObj, 1, &modifiedSourceAsCharArray, &modifiedSourceLength));
            }

            delete[] sourceLengths;
        }

        if (callRealFunction)
        {
            // Call the real function:
            SU_CALL_EXTENSION_FUNC(glShaderSourceARB, (shaderObj, count, string, length));
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glShaderSourceARB);
}

void APIENTRY glCompileShaderARB(GLhandleARB shaderObj)
{
    SU_START_FUNCTION_WRAPPER(ap_glCompileShaderARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glCompileShaderARB, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, shaderObj, OS_TOBJ_ID_ASSOCIATED_SHADER_NAME_PSEUDO_PARAMETER, shaderObj);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glCompileShaderARB, (shaderObj));

    // Log the shader compilation:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        gsProgramsAndShadersMonitor* progAndShaderMon = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(progAndShaderMon != NULL)
        {
            bool wasCompilationSuccessful = true;

            if (progAndShaderMon->isShaderObject(shaderObj))
            {
                progAndShaderMon->onShaderCompilation(shaderObj, wasCompilationSuccessful);
            }
            else
            {
                // Generate a detected error:
                gtString errorDescription;
                apErrorCode errorCode = AP_OBJECT_NAME_DOES_NOT_EXIST_ERROR;

                errorDescription = GS_STR_usingNonObjectName;
                errorDescription.appendFormattedString(L": (shader name = %u)", shaderObj);

                gs_stat_openGLMonitorInstance.reportDetectedError(errorCode, errorDescription, ap_glCompileShaderARB);
            }

            // If the compilation failed:
            if (!wasCompilationSuccessful)
            {
                // Generate a detected error:
                gtString errorDescription;
                apErrorCode errorCode = AP_SHADER_COMPILATION_FAILED_ERROR;
                errorDescription.appendFormattedString(GS_STR_shaderCompilationFailed, shaderObj);
                gs_stat_openGLMonitorInstance.reportDetectedError(errorCode, errorDescription, ap_glCompileShaderARB);
            }
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glCompileShaderARB);
}

GLhandleARB APIENTRY glCreateProgramObjectARB(void)
{
    SU_START_FUNCTION_WRAPPER(ap_glCreateProgramObjectARB);

    // Call the real function:
    GLhandleARB retVal = 0;
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glCreateProgramObjectARB, (), retVal);

    // Log the created program:
    if (retVal != 0)
    {
        gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

        if (NULL != pCurrentThreadRenderContextMonitor)
        {
            gsProgramsAndShadersMonitor* progAndShaderMon = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
            GT_IF_WITH_ASSERT(progAndShaderMon != NULL)
            {
                progAndShaderMon->onProgramCreation(retVal, AP_GL_ARB_SHADER_OBJECTS_EXTENSION_SHADING_OBJECT);
            }
        }
    }

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glCreateProgramObjectARB, 1, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, retVal);

    SU_END_FUNCTION_WRAPPER(ap_glCreateProgramObjectARB);

    return retVal;
}

void APIENTRY glAttachObjectARB(GLhandleARB containerObj, GLhandleARB obj)
{
    SU_START_FUNCTION_WRAPPER(ap_glAttachObjectARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glAttachObjectARB, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, containerObj, OS_TOBJ_ID_GL_UINT_PARAMETER, obj, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, containerObj, OS_TOBJ_ID_ASSOCIATED_SHADER_NAME_PSEUDO_PARAMETER, obj);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glAttachObjectARB, (containerObj, obj));

    // Log the attached shader:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        gsProgramsAndShadersMonitor* progAndShaderMon = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(progAndShaderMon != NULL)
        {
            bool rc = progAndShaderMon->onShaderAttachedToProgram(containerObj, obj);

            if (!rc)
            {
                // Generate a detected error:
                gtString errorDescription;
                apErrorCode errorCode = AP_OBJECT_NAME_DOES_NOT_EXIST_ERROR;

                if (!progAndShaderMon->isProgramObject(containerObj))
                {
                    errorDescription = GS_STR_usingNonObjectName;
                    errorDescription.appendFormattedString(L": (program name = %u)", containerObj);
                }
                else if (!progAndShaderMon->isShaderObject(obj))
                {
                    errorDescription = GS_STR_usingNonObjectName;
                    errorDescription.appendFormattedString(L": (shader name = %u)", obj);
                }
                else
                {
                    errorDescription.appendFormattedString(GS_STR_shaderAlreadyAttached, obj, containerObj);
                    errorCode = AP_SHADER_ALREADY_ATTACHED_ERROR;
                }

                gs_stat_openGLMonitorInstance.reportDetectedError(errorCode, errorDescription, ap_glAttachObjectARB);
            }
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glAttachObjectARB);
}

void APIENTRY glLinkProgramARB(GLhandleARB programObj)
{
    SU_START_FUNCTION_WRAPPER(ap_glLinkProgramARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glLinkProgramARB, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, programObj, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, programObj);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glLinkProgramARB, (programObj));

    // Mark that the program was linked:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        gsProgramsAndShadersMonitor* progAndShaderMon = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(progAndShaderMon != NULL)
        {
            bool wasLinkSuccessful = false;
            bool rc = progAndShaderMon->onProgramLinked(programObj, wasLinkSuccessful);

            if (!rc)
            {
                // Generate a detected error:
                gtString errorDescription;
                apErrorCode errorCode = AP_OBJECT_NAME_DOES_NOT_EXIST_ERROR;

                errorDescription = GS_STR_usingNonObjectName;
                errorDescription.appendFormattedString(L": (program name = %u)", programObj);

                gs_stat_openGLMonitorInstance.reportDetectedError(errorCode, errorDescription, ap_glLinkProgramARB);
            }

            // If the link failed:
            if (!wasLinkSuccessful)
            {
                // Generate a detected error:
                gtString errorDescription;
                apErrorCode errorCode = AP_PROGRAM_LINK_FAILED_ERROR;
                errorDescription.appendFormattedString(GS_STR_programLinkFailed, programObj);
                gs_stat_openGLMonitorInstance.reportDetectedError(errorCode, errorDescription, ap_glLinkProgramARB);

            }
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glLinkProgramARB);
}

void APIENTRY glUseProgramObjectARB(GLhandleARB programObj)
{
    SU_START_FUNCTION_WRAPPER(ap_glUseProgramObjectARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glUseProgramObjectARB, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, programObj, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, programObj);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glUseProgramObjectARB, (programObj));

    // Mark that the program is used:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        bool rc = pCurrentThreadRenderContextMonitor->onProgramUsed(programObj);

        if (!rc)
        {
            // Generate a detected error:
            gtString errorDescription;
            apErrorCode errorCode = AP_OBJECT_NAME_DOES_NOT_EXIST_ERROR;

            errorDescription = GS_STR_usingNonObjectName;
            errorDescription.appendFormattedString(L": (program name = %u)", programObj);

            gs_stat_openGLMonitorInstance.reportDetectedError(errorCode, errorDescription, ap_glUseProgramObjectARB);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glUseProgramObjectARB);
}

void APIENTRY glValidateProgramARB(GLhandleARB programObj)
{
    SU_START_FUNCTION_WRAPPER(ap_glValidateProgramARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glValidateProgramARB, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, programObj, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, programObj);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glValidateProgramARB, (programObj));

    SU_END_FUNCTION_WRAPPER(ap_glValidateProgramARB);
}

void APIENTRY glUniform1fARB(GLint location, GLfloat v0)
{
    SU_START_FUNCTION_WRAPPER(ap_glUniform1fARB);

    // Log the call to this function:
    GLuint activeProgramName = gs_stat_openGLMonitorInstance.activeProgram();
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glUniform1fARB, 3, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_FLOAT_PARAMETER, v0, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, activeProgramName);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        SU_CALL_EXTENSION_FUNC(glUniform1fARB, (location, v0));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(activeProgramName, location, GL_FLOAT, (void*)(&v0));
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glUniform1fARB);
}

void APIENTRY glUniform2fARB(GLint location, GLfloat v0, GLfloat v1)
{
    SU_START_FUNCTION_WRAPPER(ap_glUniform2fARB);

    // Log the call to this function:
    GLuint activeProgramName = gs_stat_openGLMonitorInstance.activeProgram();
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glUniform2fARB, 4, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_FLOAT_PARAMETER, v0, OS_TOBJ_ID_GL_FLOAT_PARAMETER, v1, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, activeProgramName);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        SU_CALL_EXTENSION_FUNC(glUniform2fARB, (location, v0, v1));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            GLfloat values[2] = {v0, v1};
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(activeProgramName, location, GL_FLOAT_VEC2_ARB, (void*)values);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glUniform2fARB);
}

void APIENTRY glUniform3fARB(GLint location, GLfloat v0, GLfloat v1, GLfloat v2)
{
    SU_START_FUNCTION_WRAPPER(ap_glUniform3fARB);

    // Log the call to this function:
    GLuint activeProgramName = gs_stat_openGLMonitorInstance.activeProgram();
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glUniform3fARB, 5, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_FLOAT_PARAMETER, v0, OS_TOBJ_ID_GL_FLOAT_PARAMETER, v1, OS_TOBJ_ID_GL_FLOAT_PARAMETER, v2, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, activeProgramName);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        SU_CALL_EXTENSION_FUNC(glUniform3fARB, (location, v0, v1, v2));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            GLfloat values[3] = {v0, v1, v2};
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(activeProgramName, location, GL_FLOAT_VEC3_ARB, (void*)values);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glUniform3fARB);
}

void APIENTRY glUniform4fARB(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3)
{
    SU_START_FUNCTION_WRAPPER(ap_glUniform4fARB);

    // Log the call to this function:
    GLuint activeProgramName = gs_stat_openGLMonitorInstance.activeProgram();
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glUniform4fARB, 6, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_FLOAT_PARAMETER, v0, OS_TOBJ_ID_GL_FLOAT_PARAMETER, v1, OS_TOBJ_ID_GL_FLOAT_PARAMETER, v2, OS_TOBJ_ID_GL_FLOAT_PARAMETER, v3, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, activeProgramName);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        SU_CALL_EXTENSION_FUNC(glUniform4fARB, (location, v0, v1, v2, v3));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            GLfloat values[4] = {v0, v1, v2, v3};
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(activeProgramName, location, GL_FLOAT_VEC4_ARB, (void*)values);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glUniform4fARB);
}

void APIENTRY glUniform1iARB(GLint location, GLint v0)
{
    SU_START_FUNCTION_WRAPPER(ap_glUniform1iARB);

    // Log the call to this function:
    GLuint activeProgramName = gs_stat_openGLMonitorInstance.activeProgram();
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glUniform1iARB, 3, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_INT_PARAMETER, v0, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, activeProgramName);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        SU_CALL_EXTENSION_FUNC(glUniform1iARB, (location, v0));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(activeProgramName, location, GL_INT, (void*)(&v0));
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glUniform1iARB);
}

void APIENTRY glUniform2iARB(GLint location, GLint v0, GLint v1)
{
    SU_START_FUNCTION_WRAPPER(ap_glUniform2iARB);

    // Log the call to this function:
    GLuint activeProgramName = gs_stat_openGLMonitorInstance.activeProgram();
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glUniform2iARB, 4, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_INT_PARAMETER, v0, OS_TOBJ_ID_GL_INT_PARAMETER, v1, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, activeProgramName);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        SU_CALL_EXTENSION_FUNC(glUniform2iARB, (location, v0, v1));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            GLint values[2] = {v0, v1};
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(activeProgramName, location, GL_INT_VEC2_ARB, (void*)values);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glUniform2iARB);
}

void APIENTRY glUniform3iARB(GLint location, GLint v0, GLint v1, GLint v2)
{
    SU_START_FUNCTION_WRAPPER(ap_glUniform3iARB);

    // Log the call to this function:
    GLuint activeProgramName = gs_stat_openGLMonitorInstance.activeProgram();
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glUniform3iARB, 5, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_INT_PARAMETER, v0, OS_TOBJ_ID_GL_INT_PARAMETER, v1, OS_TOBJ_ID_GL_INT_PARAMETER, v2, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, activeProgramName);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        SU_CALL_EXTENSION_FUNC(glUniform3iARB, (location, v0, v1, v2));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            GLint values[3] = {v0, v1, v2};
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(activeProgramName, location, GL_INT_VEC3_ARB, (void*)values);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glUniform3iARB);
}

void APIENTRY glUniform4iARB(GLint location, GLint v0, GLint v1, GLint v2, GLint v3)
{
    SU_START_FUNCTION_WRAPPER(ap_glUniform4iARB);

    // Log the call to this function:
    GLuint activeProgramName = gs_stat_openGLMonitorInstance.activeProgram();
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glUniform4iARB, 6, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_INT_PARAMETER, v0, OS_TOBJ_ID_GL_INT_PARAMETER, v1, OS_TOBJ_ID_GL_INT_PARAMETER, v2, OS_TOBJ_ID_GL_INT_PARAMETER, v3, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, activeProgramName);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        SU_CALL_EXTENSION_FUNC(glUniform4iARB, (location, v0, v1, v2, v3));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            GLint values[4] = {v0, v1, v2, v3};
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(activeProgramName, location, GL_INT_VEC4_ARB, (void*)values);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glUniform4iARB);
}

void APIENTRY glUniform1fvARB(GLint location, GLsizei count, const GLfloat* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glUniform1fvARB);

    // Log the call to this function:
    GLuint activeProgramName = gs_stat_openGLMonitorInstance.activeProgram();
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glUniform1fvARB, 4, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_FLOAT_PARAMETER, 1, value, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, activeProgramName);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        SU_CALL_EXTENSION_FUNC(glUniform1fvARB, (location, count, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(activeProgramName, location, GL_FLOAT, (void*)value);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glUniform1fvARB);
}

void APIENTRY glUniform2fvARB(GLint location, GLsizei count, const GLfloat* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glUniform2fvARB);

    // Log the call to this function:
    GLuint activeProgramName = gs_stat_openGLMonitorInstance.activeProgram();
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glUniform2fvARB, 4, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_FLOAT_PARAMETER, 2, value, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, activeProgramName);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        SU_CALL_EXTENSION_FUNC(glUniform2fvARB, (location, count, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(activeProgramName, location, GL_FLOAT_VEC2_ARB, (void*)value);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glUniform2fvARB);
}

void APIENTRY glUniform3fvARB(GLint location, GLsizei count, const GLfloat* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glUniform3fvARB);

    // Log the call to this function:
    GLuint activeProgramName = gs_stat_openGLMonitorInstance.activeProgram();
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glUniform3fvARB, 4, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_FLOAT_PARAMETER, 3, value, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, activeProgramName);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        SU_CALL_EXTENSION_FUNC(glUniform3fvARB, (location, count, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(activeProgramName, location, GL_FLOAT_VEC3_ARB, (void*)value);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glUniform3fvARB);
}

void APIENTRY glUniform4fvARB(GLint location, GLsizei count, const GLfloat* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glUniform4fvARB);

    // Log the call to this function:
    GLuint activeProgramName = gs_stat_openGLMonitorInstance.activeProgram();
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glUniform4fvARB, 4, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_FLOAT_PARAMETER, 4, value, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, activeProgramName);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        SU_CALL_EXTENSION_FUNC(glUniform4fvARB, (location, count, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(activeProgramName, location, GL_FLOAT_VEC4_ARB, (void*)value);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glUniform4fvARB);
}

void APIENTRY glUniform1ivARB(GLint location, GLsizei count, const GLint* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glUniform1ivARB);

    // Log the call to this function:
    GLuint activeProgramName = gs_stat_openGLMonitorInstance.activeProgram();
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glUniform1ivARB, 4, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_INT_PARAMETER, 1, value, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, activeProgramName);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        SU_CALL_EXTENSION_FUNC(glUniform1ivARB, (location, count, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(activeProgramName, location, GL_INT, (void*)value);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glUniform1ivARB);
}

void APIENTRY glUniform2ivARB(GLint location, GLsizei count, const GLint* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glUniform2ivARB);

    // Log the call to this function:
    GLuint activeProgramName = gs_stat_openGLMonitorInstance.activeProgram();
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glUniform2ivARB, 4, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_INT_PARAMETER, 2, value, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, activeProgramName);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        SU_CALL_EXTENSION_FUNC(glUniform2ivARB, (location, count, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(activeProgramName, location, GL_INT_VEC2_ARB, (void*)value);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glUniform2ivARB);
}

void APIENTRY glUniform3ivARB(GLint location, GLsizei count, const GLint* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glUniform3ivARB);

    // Log the call to this function:
    GLuint activeProgramName = gs_stat_openGLMonitorInstance.activeProgram();
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glUniform3ivARB, 4, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_INT_PARAMETER, 3, value, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, activeProgramName);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        SU_CALL_EXTENSION_FUNC(glUniform3ivARB, (location, count, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(activeProgramName, location, GL_INT_VEC3_ARB, (void*)value);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glUniform3ivARB);
}

void APIENTRY glUniform4ivARB(GLint location, GLsizei count, const GLint* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glUniform4ivARB);

    // Log the call to this function:
    GLuint activeProgramName = gs_stat_openGLMonitorInstance.activeProgram();
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glUniform4ivARB, 4, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_INT_PARAMETER, 4, value, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, activeProgramName);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        SU_CALL_EXTENSION_FUNC(glUniform4ivARB, (location, count, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(activeProgramName, location, GL_INT_VEC4_ARB, (void*)value);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glUniform4ivARB);
}

void APIENTRY glUniformMatrix2fvARB(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glUniformMatrix2fvARB);

    // Log the call to this function:
    GLuint activeProgramName = gs_stat_openGLMonitorInstance.activeProgram();
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glUniformMatrix2fvARB, 5, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_BOOL_PARAMETER, transpose, OS_TOBJ_ID_MATRIX_PARAMETER, OS_TOBJ_ID_GL_FLOAT_PARAMETER, 2, 2, value, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, activeProgramName);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        SU_CALL_EXTENSION_FUNC(glUniformMatrix2fvARB, (location, count, transpose, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(activeProgramName, location, GL_FLOAT_MAT2_ARB, (void*)value, (transpose == GL_TRUE));
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glUniformMatrix2fvARB);
}

void APIENTRY glUniformMatrix3fvARB(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glUniformMatrix3fvARB);

    // Log the call to this function:
    GLuint activeProgramName = gs_stat_openGLMonitorInstance.activeProgram();
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glUniformMatrix3fvARB, 5, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_BOOL_PARAMETER, transpose, OS_TOBJ_ID_MATRIX_PARAMETER, OS_TOBJ_ID_GL_FLOAT_PARAMETER, 3, 3, value, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, activeProgramName);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        SU_CALL_EXTENSION_FUNC(glUniformMatrix3fvARB, (location, count, transpose, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(activeProgramName, location, GL_FLOAT_MAT3_ARB, (void*)value, (transpose == GL_TRUE));
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glUniformMatrix3fvARB);
}

void APIENTRY glUniformMatrix4fvARB(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glUniformMatrix4fvARB);

    // Log the call to this function:
    GLuint activeProgramName = gs_stat_openGLMonitorInstance.activeProgram();
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glUniformMatrix4fvARB, 5, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_BOOL_PARAMETER, transpose, OS_TOBJ_ID_MATRIX_PARAMETER, OS_TOBJ_ID_GL_FLOAT_PARAMETER, 4, 4, value, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, activeProgramName);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        SU_CALL_EXTENSION_FUNC(glUniformMatrix4fvARB, (location, count, transpose, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(activeProgramName, location, GL_FLOAT_MAT4_ARB, (void*)value, (transpose == GL_TRUE));
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glUniformMatrix4fvARB);
}

void APIENTRY glGetObjectParameterfvARB(GLhandleARB obj, GLenum pname, GLfloat* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetObjectParameterfvARB);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetObjectParameterfvARB, (obj, pname, params));

    // Log the call to this function:
    osTransferableObjectType objType = OS_AMOUNT_OF_TRANSFERABLE_OBJECT_TYPES;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        pCurrentThreadRenderContextMonitor->getGLObjectType(obj, objType);
    }

    if ((objType == OS_TOBJ_ID_GL_VERTEX_SHADER) || (objType == OS_TOBJ_ID_GL_TESSELLATION_CONTROL_SHADER) || (objType == OS_TOBJ_ID_GL_TESSELLATION_EVALUATION_SHADER) || (objType == OS_TOBJ_ID_GL_GEOMETRY_SHADER) || (objType == OS_TOBJ_ID_GL_FRAGMENT_SHADER) || (objType == OS_TOBJ_ID_GL_COMPUTE_SHADER) || (objType == OS_TOBJ_ID_GL_UNSUPPORTED_SHADER))
    {
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetObjectParameterfvARB, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, obj, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, params, OS_TOBJ_ID_ASSOCIATED_SHADER_NAME_PSEUDO_PARAMETER, obj);
    }
    else if (objType == OS_TOBJ_ID_GL_PROGRAM)
    {
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetObjectParameterfvARB, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, obj, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, params, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, obj);
    }
    else
    {
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetObjectParameterfvARB, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, obj, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, params);
    }

    SU_END_FUNCTION_WRAPPER(ap_glGetObjectParameterfvARB);
}

void APIENTRY glGetObjectParameterivARB(GLhandleARB obj, GLenum pname, GLint* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetObjectParameterivARB);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetObjectParameterivARB, (obj, pname, params));

    // Log the call to this function:
    osTransferableObjectType objType = OS_AMOUNT_OF_TRANSFERABLE_OBJECT_TYPES;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        pCurrentThreadRenderContextMonitor->getGLObjectType(obj, objType);
    }

    if ((objType == OS_TOBJ_ID_GL_VERTEX_SHADER) || (objType == OS_TOBJ_ID_GL_TESSELLATION_CONTROL_SHADER) || (objType == OS_TOBJ_ID_GL_TESSELLATION_EVALUATION_SHADER) || (objType == OS_TOBJ_ID_GL_GEOMETRY_SHADER) || (objType == OS_TOBJ_ID_GL_FRAGMENT_SHADER) || (objType == OS_TOBJ_ID_GL_COMPUTE_SHADER) || (objType == OS_TOBJ_ID_GL_UNSUPPORTED_SHADER))
    {
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetObjectParameterivARB, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, obj, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_PARAMETER, params, OS_TOBJ_ID_ASSOCIATED_SHADER_NAME_PSEUDO_PARAMETER, obj);
    }
    else if (objType == OS_TOBJ_ID_GL_PROGRAM)
    {
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetObjectParameterivARB, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, obj, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_PARAMETER, params, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, obj);
    }
    else
    {
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetObjectParameterivARB, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, obj, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_PARAMETER, params);
    }

    SU_END_FUNCTION_WRAPPER(ap_glGetObjectParameterivARB);
}

void APIENTRY glGetInfoLogARB(GLhandleARB obj, GLsizei maxLength, GLsizei* length, GLcharARB* infoLog)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetInfoLogARB);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetInfoLogARB, (obj, maxLength, length, infoLog));

    // Log the call to this function:
    osTransferableObjectType objType = OS_AMOUNT_OF_TRANSFERABLE_OBJECT_TYPES;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        pCurrentThreadRenderContextMonitor->getGLObjectType(obj, objType);
    }

    if ((objType == OS_TOBJ_ID_GL_VERTEX_SHADER) || (objType == OS_TOBJ_ID_GL_TESSELLATION_CONTROL_SHADER) || (objType == OS_TOBJ_ID_GL_TESSELLATION_EVALUATION_SHADER) || (objType == OS_TOBJ_ID_GL_GEOMETRY_SHADER) || (objType == OS_TOBJ_ID_GL_FRAGMENT_SHADER) || (objType == OS_TOBJ_ID_GL_COMPUTE_SHADER) || (objType == OS_TOBJ_ID_GL_UNSUPPORTED_SHADER))
    {
        if (length != NULL)
        {
            gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetInfoLogARB, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, obj, OS_TOBJ_ID_GL_SIZEI_PARAMETER, maxLength, OS_TOBJ_ID_GL_SIZEI_PARAMETER, *length, OS_TOBJ_ID_STRING_PARAMETER, infoLog, OS_TOBJ_ID_ASSOCIATED_SHADER_NAME_PSEUDO_PARAMETER, obj);
        }
        else
        {
            gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetInfoLogARB, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, obj, OS_TOBJ_ID_GL_SIZEI_PARAMETER, maxLength, OS_TOBJ_ID_GL_P_SIZEI_PARAMETER, length, OS_TOBJ_ID_STRING_PARAMETER, infoLog, OS_TOBJ_ID_ASSOCIATED_SHADER_NAME_PSEUDO_PARAMETER, obj);
        }
    }
    else if (objType == OS_TOBJ_ID_GL_PROGRAM)
    {
        if (length != NULL)
        {
            gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetInfoLogARB, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, obj, OS_TOBJ_ID_GL_SIZEI_PARAMETER, maxLength, OS_TOBJ_ID_GL_SIZEI_PARAMETER, *length, OS_TOBJ_ID_STRING_PARAMETER, infoLog, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, obj);
        }
        else
        {
            gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetInfoLogARB, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, obj, OS_TOBJ_ID_GL_SIZEI_PARAMETER, maxLength, OS_TOBJ_ID_GL_P_SIZEI_PARAMETER, length, OS_TOBJ_ID_STRING_PARAMETER, infoLog, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, obj);
        }
    }
    else
    {
        if (length != NULL)
        {
            gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetInfoLogARB, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, obj, OS_TOBJ_ID_GL_SIZEI_PARAMETER, maxLength, OS_TOBJ_ID_GL_SIZEI_PARAMETER, *length, OS_TOBJ_ID_STRING_PARAMETER, infoLog);
        }
        else
        {
            gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetInfoLogARB, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, obj, OS_TOBJ_ID_GL_SIZEI_PARAMETER, maxLength, OS_TOBJ_ID_GL_P_SIZEI_PARAMETER, length, OS_TOBJ_ID_STRING_PARAMETER, infoLog);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glGetInfoLogARB);
}

void APIENTRY glGetAttachedObjectsARB(GLhandleARB containerObj, GLsizei maxCount, GLsizei* count, GLhandleARB* obj)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetAttachedObjectsARB);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetAttachedObjectsARB, (containerObj, maxCount, count, obj));

    // Log the call to this function:
    // Carefully - count can be NULL:
    if ((count != NULL) && (*count <= GLsizei(gs_stat_maxLoggedArraySize)))
    {
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetAttachedObjectsARB, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, containerObj, OS_TOBJ_ID_GL_SIZEI_PARAMETER, maxCount, OS_TOBJ_ID_GL_SIZEI_PARAMETER, *count, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_UINT_PARAMETER, *count, obj, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, containerObj);
    }
    else
    {
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetAttachedObjectsARB, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, containerObj, OS_TOBJ_ID_GL_SIZEI_PARAMETER, maxCount, OS_TOBJ_ID_GL_P_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_P_UINT_PARAMETER, obj, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, containerObj);
    }

    SU_END_FUNCTION_WRAPPER(ap_glGetAttachedObjectsARB);
}

GLint APIENTRY glGetUniformLocationARB(GLhandleARB programObj, const GLcharARB* name)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetUniformLocationARB);

    GLint retVal = -1;

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    const gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (pCurrentThreadRenderContextMonitor != NULL)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // If stub fragment shaders are not forced:
    if (!areStubFSGSForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glGetUniformLocationARB, (programObj, name), retVal);
    }
    else
    {
        // Get the render context monitor:
        GT_IF_WITH_ASSERT(pCurrentThreadRenderContextMonitor != NULL)
        {
            // Get the active uniforms manager:
            const gsProgramsAndShadersMonitor* progAndShaderMon = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
            GT_IF_WITH_ASSERT(progAndShaderMon != NULL)
            {
                const gsActiveUniformsMonitor& activeUniformsMon = progAndShaderMon->programsActiveUniformsMgr();

                // Get the uniform location:
                retVal = activeUniformsMon.getUniformLocation(programObj, name);
            }
        }
    }

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetUniformLocationARB, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, programObj, OS_TOBJ_ID_STRING_PARAMETER, name, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, programObj);

    SU_END_FUNCTION_WRAPPER(ap_glGetUniformLocationARB);

    return retVal;
}

void APIENTRY glGetActiveUniformARB(GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei* length, GLint* size, GLenum* type, GLcharARB* name)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetActiveUniformARB);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // If stub fragment shaders are not forced:
    if (!areStubFSGSForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glGetActiveUniformARB, (programObj, index, maxLength, length, size, type, name));
    }
    else
    {
        // Will get true iff we got the active uniform data:
        bool gotActiveUniformData = false;

        // Get the render context monitor:
        const gsRenderContextMonitor* pCurrentThreadRenderContextMonitorInner = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

        if (NULL != pCurrentThreadRenderContextMonitorInner)
        {
            // Get the active uniforms manager:
            const gsProgramsAndShadersMonitor* progAndShaderMon = pCurrentThreadRenderContextMonitorInner->programsAndShadersMonitor();
            GT_IF_WITH_ASSERT(progAndShaderMon != NULL)
            {
                const gsActiveUniformsMonitor& activeUniformsMon = progAndShaderMon->programsActiveUniformsMgr();

                // Get the queried active uniform description:
                gotActiveUniformData = activeUniformsMon.getProgramActiveUniform(programObj, index, maxLength, length, size, type, name);
            }
        }

        if (!gotActiveUniformData)
        {
            // We cannot get the render context monitor:
            GT_ASSERT(gotActiveUniformData);

            *length = 2;
            *size = 1;
            *type = GL_INT;
            name[0] = 'N';
            name[1] = 'A';
            name[2] = 0;
        }
    }

    // Log the call to this function:
    // Carefully - length can be NULL:
    if (length != NULL)
    {
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetActiveUniformARB, 8, OS_TOBJ_ID_GL_UINT_PARAMETER, programObj, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_SIZEI_PARAMETER, maxLength, OS_TOBJ_ID_GL_SIZEI_PARAMETER, *length, OS_TOBJ_ID_GL_INT_PARAMETER, *size, OS_TOBJ_ID_GL_ENUM_PARAMETER, *type, OS_TOBJ_ID_STRING_PARAMETER, name, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, programObj);
    }
    else
    {
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetActiveUniformARB, 8, OS_TOBJ_ID_GL_UINT_PARAMETER, programObj, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_SIZEI_PARAMETER, maxLength, OS_TOBJ_ID_GL_P_SIZEI_PARAMETER, length, OS_TOBJ_ID_GL_INT_PARAMETER, *size, OS_TOBJ_ID_GL_ENUM_PARAMETER, *type, OS_TOBJ_ID_STRING_PARAMETER, name, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, programObj);
    }

    SU_END_FUNCTION_WRAPPER(ap_glGetActiveUniformARB);
}

void APIENTRY glGetUniformfvARB(GLhandleARB programObj, GLint location, GLfloat* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetUniformfvARB);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetUniformfvARB, (programObj, location, params));

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetUniformfvARB, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, programObj, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, params);

    SU_END_FUNCTION_WRAPPER(ap_glGetUniformfvARB);
}

void APIENTRY glGetUniformivARB(GLhandleARB programObj, GLint location, GLint* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetUniformivARB);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetUniformivARB, (programObj, location, params));

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetUniformivARB, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, programObj, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_P_INT_PARAMETER, params, OS_TOBJ_ID_ASSOCIATED_PROGRAM_NAME_PSEUDO_PARAMETER, programObj);

    SU_END_FUNCTION_WRAPPER(ap_glGetUniformivARB);
}

void APIENTRY glGetShaderSourceARB(GLhandleARB obj, GLsizei maxLength, GLsizei* length, GLcharARB* source)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetShaderSourceARB);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetShaderSourceARB, (obj, maxLength, length, source));

    // Log the call to this function:
    // Carefully - length can be NULL:
    if (length != NULL)
    {
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetShaderSourceARB, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, obj, OS_TOBJ_ID_GL_SIZEI_PARAMETER, maxLength, OS_TOBJ_ID_GL_SIZEI_PARAMETER, *length, OS_TOBJ_ID_STRING_PARAMETER, source, OS_TOBJ_ID_ASSOCIATED_SHADER_NAME_PSEUDO_PARAMETER, obj);
    }
    else
    {
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetShaderSourceARB, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, obj, OS_TOBJ_ID_GL_SIZEI_PARAMETER, maxLength, OS_TOBJ_ID_GL_P_SIZEI_PARAMETER, length, OS_TOBJ_ID_STRING_PARAMETER, source, OS_TOBJ_ID_ASSOCIATED_SHADER_NAME_PSEUDO_PARAMETER, obj);
    }

    SU_END_FUNCTION_WRAPPER(ap_glGetShaderSourceARB);
}


//////////////////////////////////////////////////////////////////////////
// GL_NV_vertex_program
//////////////////////////////////////////////////////////////////////////
GLboolean APIENTRY glAreProgramsResidentNV(GLsizei n, const GLuint* programs, GLboolean* residences)
{
    SU_START_FUNCTION_WRAPPER(ap_glAreProgramsResidentNV);

    GLboolean retVal = GL_FALSE;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glAreProgramsResidentNV, 3, OS_TOBJ_ID_GL_SIZEI_PARAMETER, n, OS_TOBJ_ID_GL_P_UINT_PARAMETER, programs, OS_TOBJ_ID_GL_P_BOOL_PARAMETER, residences);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glAreProgramsResidentNV, (n, programs, residences), retVal);

    SU_END_FUNCTION_WRAPPER(ap_glAreProgramsResidentNV);

    return retVal;
}

void APIENTRY glBindProgramNV(GLenum target, GLuint id)
{
    SU_START_FUNCTION_WRAPPER(ap_glBindProgramNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glBindProgramNV, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_UINT_PARAMETER, id);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glBindProgramNV, (target, id));

    SU_END_FUNCTION_WRAPPER(ap_glBindProgramNV);
}

void APIENTRY glDeleteProgramsNV(GLsizei n, const GLuint* programs)
{
    SU_START_FUNCTION_WRAPPER(ap_glDeleteProgramsNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glDeleteProgramsNV, 2, OS_TOBJ_ID_GL_SIZEI_PARAMETER, n, OS_TOBJ_ID_GL_P_UINT_PARAMETER, programs);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glDeleteProgramsNV, (n, programs));

    SU_END_FUNCTION_WRAPPER(ap_glDeleteProgramsNV);
}

void APIENTRY glExecuteProgramNV(GLenum target, GLuint id, const GLfloat* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glExecuteProgramNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glExecuteProgramNV, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_UINT_PARAMETER, id, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glExecuteProgramNV, (target, id, params));

    SU_END_FUNCTION_WRAPPER(ap_glExecuteProgramNV);
}

void APIENTRY glGenProgramsNV(GLsizei n, GLuint* programs)
{
    SU_START_FUNCTION_WRAPPER(ap_glGenProgramsNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGenProgramsNV, 2, OS_TOBJ_ID_GL_SIZEI_PARAMETER, n, OS_TOBJ_ID_GL_P_UINT_PARAMETER, programs);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGenProgramsNV, (n, programs));

    SU_END_FUNCTION_WRAPPER(ap_glGenProgramsNV);
}

void APIENTRY glGetProgramParameterdvNV(GLenum target, GLuint index, GLenum pname, GLdouble* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetProgramParameterdvNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetProgramParameterdvNV, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_DOUBLE_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetProgramParameterdvNV, (target, index, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetProgramParameterdvNV);
}

void APIENTRY glGetProgramParameterfvNV(GLenum target, GLuint index, GLenum pname, GLfloat* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetProgramParameterfvNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetProgramParameterfvNV, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetProgramParameterfvNV, (target, index, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetProgramParameterfvNV);
}

void APIENTRY glGetProgramivNV(GLuint id, GLenum pname, GLint* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetProgramivNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetProgramivNV, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, id, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetProgramivNV, (id, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetProgramivNV);
}

void APIENTRY glGetProgramStringNV(GLuint id, GLenum pname, GLubyte* program)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetProgramStringNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetProgramStringNV, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, id, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_UBYTE_PARAMETER, program);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetProgramStringNV, (id, pname, program));

    SU_END_FUNCTION_WRAPPER(ap_glGetProgramStringNV);
}

void APIENTRY glGetTrackMatrixivNV(GLenum target, GLuint address, GLenum pname, GLint* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetTrackMatrixivNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetTrackMatrixivNV, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_UINT_PARAMETER, address, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetTrackMatrixivNV, (target, address, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetTrackMatrixivNV);
}

void APIENTRY glGetVertexAttribdvNV(GLuint index, GLenum pname, GLdouble* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetVertexAttribdvNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetVertexAttribdvNV, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_DOUBLE_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetVertexAttribdvNV, (index, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetVertexAttribdvNV);
}

void APIENTRY glGetVertexAttribfvNV(GLuint index, GLenum pname, GLfloat* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetVertexAttribfvNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetVertexAttribfvNV, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetVertexAttribfvNV, (index, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetVertexAttribfvNV);
}

void APIENTRY glGetVertexAttribivNV(GLuint index, GLenum pname, GLint* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetVertexAttribivNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetVertexAttribivNV, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetVertexAttribivNV, (index, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetVertexAttribivNV);
}

void APIENTRY glGetVertexAttribPointervNV(GLuint index, GLenum pname, GLvoid** pointer)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetVertexAttribPointervNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetVertexAttribPointervNV, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_PP_VOID_PARAMETER, pointer);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetVertexAttribPointervNV, (index, pname, pointer));

    SU_END_FUNCTION_WRAPPER(ap_glGetVertexAttribPointervNV);
}

GLboolean APIENTRY glIsProgramNV(GLuint id)
{
    SU_START_FUNCTION_WRAPPER(ap_glIsProgramNV);

    GLboolean retVal = GL_FALSE;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glIsProgramNV, 1, OS_TOBJ_ID_GL_UINT_PARAMETER, id);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glIsProgramNV, (id), retVal);

    SU_END_FUNCTION_WRAPPER(ap_glIsProgramNV);
    return retVal;
}

void APIENTRY glLoadProgramNV(GLenum target, GLuint id, GLsizei len, const GLubyte* program)
{
    SU_START_FUNCTION_WRAPPER(ap_glLoadProgramNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glLoadProgramNV, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_UINT_PARAMETER, id, OS_TOBJ_ID_GL_SIZEI_PARAMETER, len, OS_TOBJ_ID_GL_P_UBYTE_PARAMETER, program);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glLoadProgramNV, (target, id, len, program));

    SU_END_FUNCTION_WRAPPER(ap_glLoadProgramNV);
}

void APIENTRY glProgramParameter4dNV(GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramParameter4dNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramParameter4dNV, 6, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, x, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, y, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, z, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, w);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glProgramParameter4dNV, (target, index, x, y, z, w));

    SU_END_FUNCTION_WRAPPER(ap_glProgramParameter4dNV);
}

void APIENTRY glProgramParameter4dvNV(GLenum target, GLuint index, const GLdouble* v)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramParameter4dvNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramParameter4dvNV, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_P_DOUBLE_PARAMETER, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glProgramParameter4dvNV, (target, index, v));

    SU_END_FUNCTION_WRAPPER(ap_glProgramParameter4dvNV);
}

void APIENTRY glProgramParameter4fNV(GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramParameter4fNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramParameter4fNV, 6, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_FLOAT_PARAMETER, x, OS_TOBJ_ID_GL_FLOAT_PARAMETER, y, OS_TOBJ_ID_GL_FLOAT_PARAMETER, z, OS_TOBJ_ID_GL_FLOAT_PARAMETER, w);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glProgramParameter4fNV, (target, index, x, y, z, w));

    SU_END_FUNCTION_WRAPPER(ap_glProgramParameter4fNV);
}

void APIENTRY glProgramParameter4fvNV(GLenum target, GLuint index, const GLfloat* v)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramParameter4fvNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramParameter4fvNV, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glProgramParameter4fvNV, (target, index, v));

    SU_END_FUNCTION_WRAPPER(ap_glProgramParameter4fvNV);
}

void APIENTRY glProgramParameters4dvNV(GLenum target, GLuint index, GLsizei count, const GLdouble* v)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramParameters4dvNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramParameters4dvNV, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_P_DOUBLE_PARAMETER, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glProgramParameters4dvNV, (target, index, count, v));

    SU_END_FUNCTION_WRAPPER(ap_glProgramParameters4dvNV);
}

void APIENTRY glProgramParameters4fvNV(GLenum target, GLuint index, GLsizei count, const GLfloat* v)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramParameters4fvNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramParameters4fvNV, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glProgramParameters4fvNV, (target, index, count, v));

    SU_END_FUNCTION_WRAPPER(ap_glProgramParameters4fvNV);
}

void APIENTRY glRequestResidentProgramsNV(GLsizei n, const GLuint* programs)
{
    SU_START_FUNCTION_WRAPPER(ap_glRequestResidentProgramsNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glRequestResidentProgramsNV, 2, OS_TOBJ_ID_GL_SIZEI_PARAMETER, n, OS_TOBJ_ID_GL_P_UINT_PARAMETER, programs);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glRequestResidentProgramsNV, (n, programs));

    SU_END_FUNCTION_WRAPPER(ap_glRequestResidentProgramsNV);
}

void APIENTRY glTrackMatrixNV(GLenum target, GLuint address, GLenum matrix, GLenum transform)
{
    SU_START_FUNCTION_WRAPPER(ap_glTrackMatrixNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTrackMatrixNV, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_UINT_PARAMETER, address, OS_TOBJ_ID_GL_ENUM_PARAMETER, matrix, OS_TOBJ_ID_GL_ENUM_PARAMETER, transform);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glTrackMatrixNV, (target, address, matrix, transform));

    SU_END_FUNCTION_WRAPPER(ap_glTrackMatrixNV);
}

void APIENTRY glVertexAttribPointerNV(GLuint index, GLint fsize, GLenum type, GLsizei stride, const GLvoid* pointer)
{
    SU_START_FUNCTION_WRAPPER(ap_glVertexAttribPointerNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttribPointerNV, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_INT_PARAMETER, fsize, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_SIZEI_PARAMETER, stride, OS_TOBJ_ID_GL_P_VOID_PARAMETER, pointer);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttribPointerNV, (index, fsize, type, stride, pointer));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttribPointerNV);
}

void APIENTRY glVertexAttrib1dNV(GLuint index, GLdouble x)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib1dNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib1dNV, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, x);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib1dNV, (index, x));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib1dNV);
}

void APIENTRY glVertexAttrib1dvNV(GLuint index, const GLdouble* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib1dvNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib1dvNV, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, 1, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib1dvNV, (index, v));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib1dvNV);
}

void APIENTRY glVertexAttrib1fNV(GLuint index, GLfloat x)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib1fNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib1fNV, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_FLOAT_PARAMETER, x);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib1fNV, (index, x));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib1fNV);
}

void APIENTRY glVertexAttrib1fvNV(GLuint index, const GLfloat* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib1fvNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib1fvNV, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_FLOAT_PARAMETER, 1, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib1fvNV, (index, v));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib1fvNV);
}

void APIENTRY glVertexAttrib1sNV(GLuint index, GLshort x)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib1sNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib1sNV, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_SHORT_PARAMETER, x);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib1sNV, (index, x));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib1sNV);
}

void APIENTRY glVertexAttrib1svNV(GLuint index, const GLshort* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib1svNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib1svNV, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_SHORT_PARAMETER, 1, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib1svNV, (index, v));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib1svNV);
}

void APIENTRY glVertexAttrib2dNV(GLuint index, GLdouble x, GLdouble y)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib2dNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib2dNV, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, x, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, y);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib2dNV, (index, x, y));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib2dNV);
}

void APIENTRY glVertexAttrib2dvNV(GLuint index, const GLdouble* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib2dvNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib2dvNV, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, 2, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib2dvNV, (index, v));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib2dvNV);
}

void APIENTRY glVertexAttrib2fNV(GLuint index, GLfloat x, GLfloat y)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib2fNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib2fNV, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_FLOAT_PARAMETER, x, OS_TOBJ_ID_GL_FLOAT_PARAMETER, y);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib2fNV, (index, x, y));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib2fNV);
}

void APIENTRY glVertexAttrib2fvNV(GLuint index, const GLfloat* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib2fvNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib2fvNV, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_FLOAT_PARAMETER, 2, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib2fvNV, (index, v));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib2fvNV);
}

void APIENTRY glVertexAttrib2sNV(GLuint index, GLshort x, GLshort y)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib2sNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib2sNV, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_SHORT_PARAMETER, x, OS_TOBJ_ID_GL_SHORT_PARAMETER, y);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib2sNV, (index, x, y));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib2sNV);
}

void APIENTRY glVertexAttrib2svNV(GLuint index, const GLshort* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib2svNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib2svNV, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_SHORT_PARAMETER, 2, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib2svNV, (index, v));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib2svNV);
}

void APIENTRY glVertexAttrib3dNV(GLuint index, GLdouble x, GLdouble y, GLdouble z)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib3dNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib3dNV, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, x, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, y, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, z);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib3dNV, (index, x, y, z));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib3dNV);
}

void APIENTRY glVertexAttrib3dvNV(GLuint index, const GLdouble* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib3dvNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib3dvNV, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, 3, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib3dvNV, (index, v));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib3dvNV);
}

void APIENTRY glVertexAttrib3fNV(GLuint index, GLfloat x, GLfloat y, GLfloat z)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib3fNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib3fNV, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_FLOAT_PARAMETER, x, OS_TOBJ_ID_GL_FLOAT_PARAMETER, y, OS_TOBJ_ID_GL_FLOAT_PARAMETER, z);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib3fNV, (index, x, y, z));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib3fNV);
}

void APIENTRY glVertexAttrib3fvNV(GLuint index, const GLfloat* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib3fvNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib3fvNV, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_FLOAT_PARAMETER, 3, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib3fvNV, (index, v));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib3fvNV);
}

void APIENTRY glVertexAttrib3sNV(GLuint index, GLshort x, GLshort y, GLshort z)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib3sNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib3sNV, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_SHORT_PARAMETER, x, OS_TOBJ_ID_GL_SHORT_PARAMETER, y, OS_TOBJ_ID_GL_SHORT_PARAMETER, z);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib3sNV, (index, x, y, z));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib3sNV);
}

void APIENTRY glVertexAttrib3svNV(GLuint index, const GLshort* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib3svNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib3svNV, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_SHORT_PARAMETER, 3, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib3svNV, (index, v));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib3svNV);
}

void APIENTRY glVertexAttrib4dNV(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib4dNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib4dNV, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, x, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, y, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, z, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, w);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib4dNV, (index, x, y, z, w));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib4dNV);
}

void APIENTRY glVertexAttrib4dvNV(GLuint index, const GLdouble* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib4dvNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib4dvNV, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, 4, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib4dvNV, (index, v));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib4dvNV);
}

void APIENTRY glVertexAttrib4fNV(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib4fNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib4fNV, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_FLOAT_PARAMETER, x, OS_TOBJ_ID_GL_FLOAT_PARAMETER, y, OS_TOBJ_ID_GL_FLOAT_PARAMETER, z, OS_TOBJ_ID_GL_FLOAT_PARAMETER, w);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib4fNV, (index, x, y, z, w));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib4fNV);
}

void APIENTRY glVertexAttrib4fvNV(GLuint index, const GLfloat* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib4fvNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib4fvNV, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_FLOAT_PARAMETER, 4, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib4fvNV, (index, v));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib4fvNV);
}

void APIENTRY glVertexAttrib4sNV(GLuint index, GLshort x, GLshort y, GLshort z, GLshort w)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib4sNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib4sNV, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_SHORT_PARAMETER, x, OS_TOBJ_ID_GL_SHORT_PARAMETER, y, OS_TOBJ_ID_GL_SHORT_PARAMETER, z, OS_TOBJ_ID_GL_SHORT_PARAMETER, w);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib4sNV, (index, x, y, z, w));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib4sNV);
}

void APIENTRY glVertexAttrib4svNV(GLuint index, const GLshort* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib4svNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib4svNV, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_SHORT_PARAMETER, 4, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib4svNV, (index, v));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib4svNV);
}

void APIENTRY glVertexAttrib4ubNV(GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib4ubNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib4ubNV, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_UBYTE_PARAMETER, x, OS_TOBJ_ID_GL_UBYTE_PARAMETER, y, OS_TOBJ_ID_GL_UBYTE_PARAMETER, z, OS_TOBJ_ID_GL_UBYTE_PARAMETER, w);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib4ubNV, (index, x, y, z, w));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib4ubNV);
}

void APIENTRY glVertexAttrib4ubvNV(GLuint index, const GLubyte* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttrib4ubvNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttrib4ubvNV, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_UBYTE_PARAMETER, 4, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttrib4ubvNV, (index, v));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttrib4ubvNV);
}

void APIENTRY glVertexAttribs1dvNV(GLuint index, GLsizei count, const GLdouble* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttribs1dvNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttribs1dvNV, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, 1, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttribs1dvNV, (index, count, v));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttribs1dvNV);
}

void APIENTRY glVertexAttribs1fvNV(GLuint index, GLsizei count, const GLfloat* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttribs1fvNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttribs1fvNV, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_FLOAT_PARAMETER, 1, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttribs1fvNV, (index, count, v));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttribs1fvNV);
}

void APIENTRY glVertexAttribs1svNV(GLuint index, GLsizei count, const GLshort* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttribs1svNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttribs1svNV, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_SHORT_PARAMETER, 1, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttribs1svNV, (index, count, v));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttribs1svNV);
}

void APIENTRY glVertexAttribs2dvNV(GLuint index, GLsizei count, const GLdouble* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttribs2dvNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttribs2dvNV, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, 2, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttribs2dvNV, (index, count, v));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttribs2dvNV);
}

void APIENTRY glVertexAttribs2fvNV(GLuint index, GLsizei count, const GLfloat* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttribs2fvNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttribs2fvNV, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_FLOAT_PARAMETER, 2, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttribs2fvNV, (index, count, v));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttribs2fvNV);
}

void APIENTRY glVertexAttribs2svNV(GLuint index, GLsizei count, const GLshort* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttribs2svNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttribs2svNV, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_SHORT_PARAMETER, 2, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttribs2svNV, (index, count, v));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttribs2svNV);
}

void APIENTRY glVertexAttribs3dvNV(GLuint index, GLsizei count, const GLdouble* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttribs3dvNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttribs3dvNV, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, 3, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttribs3dvNV, (index, count, v));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttribs3dvNV);
}

void APIENTRY glVertexAttribs3fvNV(GLuint index, GLsizei count, const GLfloat* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttribs3fvNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttribs3fvNV, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_FLOAT_PARAMETER, 3, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttribs3fvNV, (index, count, v));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttribs3fvNV);
}

void APIENTRY glVertexAttribs3svNV(GLuint index, GLsizei count, const GLshort* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttribs3svNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttribs3svNV, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_SHORT_PARAMETER, 3, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttribs3svNV, (index, count, v));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttribs3svNV);
}

void APIENTRY glVertexAttribs4dvNV(GLuint index, GLsizei count, const GLdouble* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttribs4dvNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttribs4dvNV, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, 4, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttribs4dvNV, (index, count, v));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttribs4dvNV);
}

void APIENTRY glVertexAttribs4fvNV(GLuint index, GLsizei count, const GLfloat* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttribs4fvNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttribs4fvNV, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_FLOAT_PARAMETER, 4, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttribs4fvNV, (index, count, v));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttribs4fvNV);
}

void APIENTRY glVertexAttribs4svNV(GLuint index, GLsizei count, const GLshort* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttribs4svNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttribs4svNV, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_SHORT_PARAMETER, 4, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttribs4svNV, (index, count, v));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttribs4svNV);
}

void APIENTRY glVertexAttribs4ubvNV(GLuint index, GLsizei count, const GLubyte* v)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glVertexAttribs4ubvNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttribs4ubvNV, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_UBYTE_PARAMETER, 4, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttribs4ubvNV, (index, count, v));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttribs4ubvNV);
}


//////////////////////////////////////////////////////////////////////////
// GL_ATI_fragment_shader
//////////////////////////////////////////////////////////////////////////
GLuint APIENTRY glGenFragmentShadersATI(GLuint range)
{
    SU_START_FUNCTION_WRAPPER(ap_glGenFragmentShadersATI);

    GLuint retVal = 0;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGenFragmentShadersATI, 1, OS_TOBJ_ID_GL_UINT_PARAMETER, range);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glGenFragmentShadersATI, (range), retVal);

    SU_END_FUNCTION_WRAPPER(ap_glGenFragmentShadersATI);

    return retVal;
}

void APIENTRY glBindFragmentShaderATI(GLuint id)
{
    SU_START_FUNCTION_WRAPPER(ap_glBindFragmentShaderATI);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glBindFragmentShaderATI, 1, OS_TOBJ_ID_GL_UINT_PARAMETER, id);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glBindFragmentShaderATI, (id));

    SU_END_FUNCTION_WRAPPER(ap_glBindFragmentShaderATI);
}

void APIENTRY glDeleteFragmentShaderATI(GLuint id)
{
    SU_START_FUNCTION_WRAPPER(ap_glDeleteFragmentShaderATI);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glDeleteFragmentShaderATI, 1, OS_TOBJ_ID_GL_UINT_PARAMETER, id);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glDeleteFragmentShaderATI, (id));

    SU_END_FUNCTION_WRAPPER(ap_glDeleteFragmentShaderATI);
}

void APIENTRY glBeginFragmentShaderATI(void)
{
    SU_START_FUNCTION_WRAPPER(ap_glBeginFragmentShaderATI);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glBeginFragmentShaderATI, 0);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glBeginFragmentShaderATI, ());

    SU_END_FUNCTION_WRAPPER(ap_glBeginFragmentShaderATI);
}

void APIENTRY glEndFragmentShaderATI(void)
{
    SU_START_FUNCTION_WRAPPER(ap_glEndFragmentShaderATI);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glEndFragmentShaderATI, 0);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glEndFragmentShaderATI, ());

    SU_END_FUNCTION_WRAPPER(ap_glEndFragmentShaderATI);
}

void APIENTRY glPassTexCoordATI(GLuint dst, GLuint coord, GLenum swizzle)
{
    SU_START_FUNCTION_WRAPPER(ap_glPassTexCoordATI);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glPassTexCoordATI, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, dst, OS_TOBJ_ID_GL_UINT_PARAMETER, coord, OS_TOBJ_ID_GL_ENUM_PARAMETER, swizzle);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glPassTexCoordATI, (dst, coord, swizzle));

    SU_END_FUNCTION_WRAPPER(ap_glPassTexCoordATI);
}

void APIENTRY glSampleMapATI(GLuint dst, GLuint interp, GLenum swizzle)
{
    SU_START_FUNCTION_WRAPPER(ap_glSampleMapATI);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glSampleMapATI, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, dst, OS_TOBJ_ID_GL_UINT_PARAMETER, interp, OS_TOBJ_ID_GL_ENUM_PARAMETER, swizzle);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glSampleMapATI, (dst, interp, swizzle));

    SU_END_FUNCTION_WRAPPER(ap_glSampleMapATI);
}

void APIENTRY glColorFragmentOp1ATI(GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod)
{
    SU_START_FUNCTION_WRAPPER(ap_glColorFragmentOp1ATI);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glColorFragmentOp1ATI, 7, OS_TOBJ_ID_GL_ENUM_PARAMETER, op, OS_TOBJ_ID_GL_UINT_PARAMETER, dst, OS_TOBJ_ID_GL_UINT_PARAMETER, dstMask, OS_TOBJ_ID_GL_UINT_PARAMETER, dstMod, OS_TOBJ_ID_GL_UINT_PARAMETER, arg1, OS_TOBJ_ID_GL_UINT_PARAMETER, arg1Rep, OS_TOBJ_ID_GL_UINT_PARAMETER, arg1Mod);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glColorFragmentOp1ATI, (op, dst, dstMask, dstMod, arg1, arg1Rep, arg1Mod));

    SU_END_FUNCTION_WRAPPER(ap_glColorFragmentOp1ATI);
}

void APIENTRY glColorFragmentOp2ATI(GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod)
{
    SU_START_FUNCTION_WRAPPER(ap_glColorFragmentOp2ATI);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glColorFragmentOp2ATI, 10, OS_TOBJ_ID_GL_ENUM_PARAMETER, op, OS_TOBJ_ID_GL_UINT_PARAMETER, dst, OS_TOBJ_ID_GL_UINT_PARAMETER, dstMask, OS_TOBJ_ID_GL_UINT_PARAMETER, dstMod, OS_TOBJ_ID_GL_UINT_PARAMETER, arg1, OS_TOBJ_ID_GL_UINT_PARAMETER, arg1Rep, OS_TOBJ_ID_GL_UINT_PARAMETER, arg1Mod, OS_TOBJ_ID_GL_UINT_PARAMETER, arg2, OS_TOBJ_ID_GL_UINT_PARAMETER, arg2Rep, OS_TOBJ_ID_GL_UINT_PARAMETER, arg2Mod);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glColorFragmentOp2ATI, (op, dst, dstMask, dstMod, arg1, arg1Rep, arg1Mod, arg2, arg2Rep, arg2Mod));

    SU_END_FUNCTION_WRAPPER(ap_glColorFragmentOp2ATI);
}

void APIENTRY glColorFragmentOp3ATI(GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod)
{
    SU_START_FUNCTION_WRAPPER(ap_glColorFragmentOp3ATI);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glColorFragmentOp3ATI, 13, OS_TOBJ_ID_GL_ENUM_PARAMETER, op, OS_TOBJ_ID_GL_UINT_PARAMETER, dst, OS_TOBJ_ID_GL_UINT_PARAMETER, dstMask, OS_TOBJ_ID_GL_UINT_PARAMETER, dstMod, OS_TOBJ_ID_GL_UINT_PARAMETER, arg1, OS_TOBJ_ID_GL_UINT_PARAMETER, arg1Rep, OS_TOBJ_ID_GL_UINT_PARAMETER, arg1Mod, OS_TOBJ_ID_GL_UINT_PARAMETER, arg2, OS_TOBJ_ID_GL_UINT_PARAMETER, arg2Rep, OS_TOBJ_ID_GL_UINT_PARAMETER, arg2Mod, OS_TOBJ_ID_GL_UINT_PARAMETER, arg3, OS_TOBJ_ID_GL_UINT_PARAMETER, arg3Rep, OS_TOBJ_ID_GL_UINT_PARAMETER, arg3Mod);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glColorFragmentOp3ATI, (op, dst, dstMask, dstMod, arg1, arg1Rep, arg1Mod, arg2, arg2Rep, arg2Mod, arg3, arg3Rep, arg3Mod));

    SU_END_FUNCTION_WRAPPER(ap_glColorFragmentOp3ATI);
}

void APIENTRY glAlphaFragmentOp1ATI(GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod)
{
    SU_START_FUNCTION_WRAPPER(ap_glAlphaFragmentOp1ATI);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glAlphaFragmentOp1ATI, 6, OS_TOBJ_ID_GL_ENUM_PARAMETER, op, OS_TOBJ_ID_GL_UINT_PARAMETER, dst, OS_TOBJ_ID_GL_UINT_PARAMETER, dstMod, OS_TOBJ_ID_GL_UINT_PARAMETER, arg1, OS_TOBJ_ID_GL_UINT_PARAMETER, arg1Rep, OS_TOBJ_ID_GL_UINT_PARAMETER, arg1Mod);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glAlphaFragmentOp1ATI, (op, dst, dstMod, arg1, arg1Rep, arg1Mod));

    SU_END_FUNCTION_WRAPPER(ap_glAlphaFragmentOp1ATI);
}

void APIENTRY glAlphaFragmentOp2ATI(GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod)
{
    SU_START_FUNCTION_WRAPPER(ap_glAlphaFragmentOp2ATI);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glAlphaFragmentOp2ATI, 9, OS_TOBJ_ID_GL_ENUM_PARAMETER, op, OS_TOBJ_ID_GL_UINT_PARAMETER, dst, OS_TOBJ_ID_GL_UINT_PARAMETER, dstMod, OS_TOBJ_ID_GL_UINT_PARAMETER, arg1, OS_TOBJ_ID_GL_UINT_PARAMETER, arg1Rep, OS_TOBJ_ID_GL_UINT_PARAMETER, arg1Mod, OS_TOBJ_ID_GL_UINT_PARAMETER, arg2, OS_TOBJ_ID_GL_UINT_PARAMETER, arg2Rep, OS_TOBJ_ID_GL_UINT_PARAMETER, arg2Mod);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glAlphaFragmentOp2ATI, (op, dst, dstMod, arg1, arg1Rep, arg1Mod, arg2, arg2Rep, arg2Mod));

    SU_END_FUNCTION_WRAPPER(ap_glAlphaFragmentOp2ATI);
}

void APIENTRY glAlphaFragmentOp3ATI(GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod)
{
    SU_START_FUNCTION_WRAPPER(ap_glAlphaFragmentOp3ATI);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glAlphaFragmentOp3ATI, 12, OS_TOBJ_ID_GL_ENUM_PARAMETER, op, OS_TOBJ_ID_GL_UINT_PARAMETER, dst, OS_TOBJ_ID_GL_UINT_PARAMETER, dstMod, OS_TOBJ_ID_GL_UINT_PARAMETER, arg1, OS_TOBJ_ID_GL_UINT_PARAMETER, arg1Rep, OS_TOBJ_ID_GL_UINT_PARAMETER, arg1Mod, OS_TOBJ_ID_GL_UINT_PARAMETER, arg2, OS_TOBJ_ID_GL_UINT_PARAMETER, arg2Rep, OS_TOBJ_ID_GL_UINT_PARAMETER, arg2Mod, OS_TOBJ_ID_GL_UINT_PARAMETER, arg3, OS_TOBJ_ID_GL_UINT_PARAMETER, arg3Rep, OS_TOBJ_ID_GL_UINT_PARAMETER, arg3Mod);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glAlphaFragmentOp3ATI, (op, dst, dstMod, arg1, arg1Rep, arg1Mod, arg2, arg2Rep, arg2Mod, arg3, arg3Rep, arg3Mod));

    SU_END_FUNCTION_WRAPPER(ap_glAlphaFragmentOp3ATI);
}

void APIENTRY glSetFragmentShaderConstantATI(GLuint dst, const GLfloat* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glSetFragmentShaderConstantATI);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glSetFragmentShaderConstantATI, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, dst, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, value);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glSetFragmentShaderConstantATI, (dst, value));

    SU_END_FUNCTION_WRAPPER(ap_glSetFragmentShaderConstantATI);
}


//////////////////////////////////////////////////////////////////////////
// GL_EXT_vertex_shader
//////////////////////////////////////////////////////////////////////////
void APIENTRY glBeginVertexShaderEXT(void)
{
    SU_START_FUNCTION_WRAPPER(ap_glBeginVertexShaderEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glBeginVertexShaderEXT, 0);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glBeginVertexShaderEXT, ());

    SU_END_FUNCTION_WRAPPER(ap_glBeginVertexShaderEXT);
}

void APIENTRY glEndVertexShaderEXT(void)
{
    SU_START_FUNCTION_WRAPPER(ap_glEndVertexShaderEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glEndVertexShaderEXT, 0);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glEndVertexShaderEXT, ());

    SU_END_FUNCTION_WRAPPER(ap_glEndVertexShaderEXT);
}

void APIENTRY glBindVertexShaderEXT(GLuint id)
{
    SU_START_FUNCTION_WRAPPER(ap_glBindVertexShaderEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glBindVertexShaderEXT, 1, OS_TOBJ_ID_GL_UINT_PARAMETER, id);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glBindVertexShaderEXT, (id));

    SU_END_FUNCTION_WRAPPER(ap_glBindVertexShaderEXT);
}

GLuint APIENTRY glGenVertexShadersEXT(GLuint range)
{
    SU_START_FUNCTION_WRAPPER(ap_glGenVertexShadersEXT);

    GLuint retVal = GL_FALSE;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGenVertexShadersEXT, 1, OS_TOBJ_ID_GL_UINT_PARAMETER, range);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glGenVertexShadersEXT, (range), retVal);

    SU_END_FUNCTION_WRAPPER(ap_glGenVertexShadersEXT);

    return retVal;
}

void APIENTRY glDeleteVertexShaderEXT(GLuint id)
{
    SU_START_FUNCTION_WRAPPER(ap_glDeleteVertexShaderEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glDeleteVertexShaderEXT, 1, OS_TOBJ_ID_GL_UINT_PARAMETER, id);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glDeleteVertexShaderEXT, (id));

    SU_END_FUNCTION_WRAPPER(ap_glDeleteVertexShaderEXT);
}

void APIENTRY glShaderOp1EXT(GLenum op, GLuint res, GLuint arg1)
{
    SU_START_FUNCTION_WRAPPER(ap_glShaderOp1EXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glShaderOp1EXT, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, op, OS_TOBJ_ID_GL_UINT_PARAMETER, res, OS_TOBJ_ID_GL_UINT_PARAMETER, arg1);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glShaderOp1EXT, (op, res, arg1));

    SU_END_FUNCTION_WRAPPER(ap_glShaderOp1EXT);
}

void APIENTRY glShaderOp2EXT(GLenum op, GLuint res, GLuint arg1, GLuint arg2)
{
    SU_START_FUNCTION_WRAPPER(ap_glShaderOp2EXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glShaderOp2EXT, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, op, OS_TOBJ_ID_GL_UINT_PARAMETER, res, OS_TOBJ_ID_GL_UINT_PARAMETER, arg1, OS_TOBJ_ID_GL_UINT_PARAMETER, arg2);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glShaderOp2EXT, (op, res, arg1, arg2));

    SU_END_FUNCTION_WRAPPER(ap_glShaderOp2EXT);
}

void APIENTRY glShaderOp3EXT(GLenum op, GLuint res, GLuint arg1, GLuint arg2, GLuint arg3)
{
    SU_START_FUNCTION_WRAPPER(ap_glShaderOp3EXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glShaderOp3EXT, 5, OS_TOBJ_ID_GL_ENUM_PARAMETER, op, OS_TOBJ_ID_GL_UINT_PARAMETER, res, OS_TOBJ_ID_GL_UINT_PARAMETER, arg1, OS_TOBJ_ID_GL_UINT_PARAMETER, arg2, OS_TOBJ_ID_GL_UINT_PARAMETER, arg3);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glShaderOp3EXT, (op, res, arg1, arg2, arg3));

    SU_END_FUNCTION_WRAPPER(ap_glShaderOp3EXT);
}

void APIENTRY glSwizzleEXT(GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW)
{
    SU_START_FUNCTION_WRAPPER(ap_glSwizzleEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glSwizzleEXT, 6, OS_TOBJ_ID_GL_UINT_PARAMETER, res, OS_TOBJ_ID_GL_UINT_PARAMETER, in, OS_TOBJ_ID_GL_ENUM_PARAMETER, outX, OS_TOBJ_ID_GL_ENUM_PARAMETER, outY, OS_TOBJ_ID_GL_ENUM_PARAMETER, outZ, OS_TOBJ_ID_GL_ENUM_PARAMETER, outW);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glSwizzleEXT, (res, in, outX, outY, outZ, outW));

    SU_END_FUNCTION_WRAPPER(ap_glSwizzleEXT);
}

void APIENTRY glWriteMaskEXT(GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW)
{
    SU_START_FUNCTION_WRAPPER(ap_glWriteMaskEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glWriteMaskEXT, 6, OS_TOBJ_ID_GL_UINT_PARAMETER, res, OS_TOBJ_ID_GL_UINT_PARAMETER, in, OS_TOBJ_ID_GL_ENUM_PARAMETER, outX, OS_TOBJ_ID_GL_ENUM_PARAMETER, outY, OS_TOBJ_ID_GL_ENUM_PARAMETER, outZ, OS_TOBJ_ID_GL_ENUM_PARAMETER, outW);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glWriteMaskEXT, (res, in, outX, outY, outZ, outW));

    SU_END_FUNCTION_WRAPPER(ap_glWriteMaskEXT);
}

void APIENTRY glInsertComponentEXT(GLuint res, GLuint src, GLuint num)
{
    SU_START_FUNCTION_WRAPPER(ap_glInsertComponentEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glInsertComponentEXT, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, res, OS_TOBJ_ID_GL_UINT_PARAMETER, src, OS_TOBJ_ID_GL_UINT_PARAMETER, num);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glInsertComponentEXT, (res, src, num));

    SU_END_FUNCTION_WRAPPER(ap_glInsertComponentEXT);
}

void APIENTRY glExtractComponentEXT(GLuint res, GLuint src, GLuint num)
{
    SU_START_FUNCTION_WRAPPER(ap_glExtractComponentEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glExtractComponentEXT, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, res, OS_TOBJ_ID_GL_UINT_PARAMETER, src, OS_TOBJ_ID_GL_UINT_PARAMETER, num);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glExtractComponentEXT, (res, src, num));

    SU_END_FUNCTION_WRAPPER(ap_glExtractComponentEXT);
}

GLuint APIENTRY glGenSymbolsEXT(GLenum datatype, GLenum storagetype, GLenum range, GLuint components)
{
    SU_START_FUNCTION_WRAPPER(ap_glGenSymbolsEXT);

    GLuint retVal = GL_FALSE;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGenSymbolsEXT, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, datatype, OS_TOBJ_ID_GL_ENUM_PARAMETER, storagetype, OS_TOBJ_ID_GL_ENUM_PARAMETER, range, OS_TOBJ_ID_GL_UINT_PARAMETER, components);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glGenSymbolsEXT, (datatype, storagetype, range, components), retVal);

    SU_END_FUNCTION_WRAPPER(ap_glGenSymbolsEXT);

    return retVal;
}

void APIENTRY glSetInvariantEXT(GLuint id, GLenum type, const GLvoid* addr)
{
    SU_START_FUNCTION_WRAPPER(ap_glSetInvariantEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glSetInvariantEXT, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, id, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_P_VOID_PARAMETER, addr);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glSetInvariantEXT, (id, type, addr));

    SU_END_FUNCTION_WRAPPER(ap_glSetInvariantEXT);
}

void APIENTRY glSetLocalConstantEXT(GLuint id, GLenum type, const GLvoid* addr)
{
    SU_START_FUNCTION_WRAPPER(ap_glSetLocalConstantEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glSetLocalConstantEXT, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, id, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_P_VOID_PARAMETER, addr);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glSetLocalConstantEXT, (id, type, addr));

    SU_END_FUNCTION_WRAPPER(ap_glSetLocalConstantEXT);
}

void APIENTRY glVariantbvEXT(GLuint id, const GLbyte* addr)
{
    SU_START_FUNCTION_WRAPPER(ap_glVariantbvEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVariantbvEXT, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, id, OS_TOBJ_ID_GL_P_BYTE_PARAMETER, addr);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVariantbvEXT, (id, addr));

    SU_END_FUNCTION_WRAPPER(ap_glVariantbvEXT);
}

void APIENTRY glVariantsvEXT(GLuint id, const GLshort* addr)
{
    SU_START_FUNCTION_WRAPPER(ap_glVariantsvEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVariantsvEXT, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, id, OS_TOBJ_ID_GL_P_SHORT_PARAMETER, addr);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVariantsvEXT, (id, addr));

    SU_END_FUNCTION_WRAPPER(ap_glVariantsvEXT);
}

void APIENTRY glVariantivEXT(GLuint id, const GLint* addr)
{
    SU_START_FUNCTION_WRAPPER(ap_glVariantivEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVariantivEXT, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, id, OS_TOBJ_ID_GL_P_INT_PARAMETER, addr);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVariantivEXT, (id, addr));

    SU_END_FUNCTION_WRAPPER(ap_glVariantivEXT);
}

void APIENTRY glVariantfvEXT(GLuint id, const GLfloat* addr)
{
    SU_START_FUNCTION_WRAPPER(ap_glVariantfvEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVariantfvEXT, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, id, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, addr);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVariantfvEXT, (id, addr));

    SU_END_FUNCTION_WRAPPER(ap_glVariantfvEXT);
}

void APIENTRY glVariantdvEXT(GLuint id, const GLdouble* addr)
{
    SU_START_FUNCTION_WRAPPER(ap_glVariantdvEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVariantdvEXT, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, id, OS_TOBJ_ID_GL_P_DOUBLE_PARAMETER, addr);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVariantdvEXT, (id, addr));

    SU_END_FUNCTION_WRAPPER(ap_glVariantdvEXT);
}

void APIENTRY glVariantubvEXT(GLuint id, const GLubyte* addr)
{
    SU_START_FUNCTION_WRAPPER(ap_glVariantubvEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVariantubvEXT, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, id, OS_TOBJ_ID_GL_P_UBYTE_PARAMETER, addr);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVariantubvEXT, (id, addr));

    SU_END_FUNCTION_WRAPPER(ap_glVariantubvEXT);
}

void APIENTRY glVariantusvEXT(GLuint id, const GLushort* addr)
{
    SU_START_FUNCTION_WRAPPER(ap_glVariantusvEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVariantusvEXT, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, id, OS_TOBJ_ID_GL_P_USHORT_PARAMETER, addr);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVariantusvEXT, (id, addr));

    SU_END_FUNCTION_WRAPPER(ap_glVariantusvEXT);
}

void APIENTRY glVariantuivEXT(GLuint id, const GLuint* addr)
{
    SU_START_FUNCTION_WRAPPER(ap_glVariantuivEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVariantuivEXT, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, id, OS_TOBJ_ID_GL_P_UINT_PARAMETER, addr);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVariantuivEXT, (id, addr));

    SU_END_FUNCTION_WRAPPER(ap_glVariantuivEXT);
}

void APIENTRY glVariantPointerEXT(GLuint id, GLenum type, GLuint stride, const GLvoid* addr)
{
    SU_START_FUNCTION_WRAPPER(ap_glVariantPointerEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVariantPointerEXT, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, id, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_UINT_PARAMETER, stride, OS_TOBJ_ID_GL_P_VOID_PARAMETER, addr);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVariantPointerEXT, (id, type, stride, addr));

    SU_END_FUNCTION_WRAPPER(ap_glVariantPointerEXT);
}

void APIENTRY glEnableVariantClientStateEXT(GLuint id)
{
    SU_START_FUNCTION_WRAPPER(ap_glEnableVariantClientStateEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glEnableVariantClientStateEXT, 1, OS_TOBJ_ID_GL_UINT_PARAMETER, id);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glEnableVariantClientStateEXT, (id));

    SU_END_FUNCTION_WRAPPER(ap_glEnableVariantClientStateEXT);
}

void APIENTRY glDisableVariantClientStateEXT(GLuint id)
{
    SU_START_FUNCTION_WRAPPER(ap_glDisableVariantClientStateEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glDisableVariantClientStateEXT, 1, OS_TOBJ_ID_GL_UINT_PARAMETER, id);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glDisableVariantClientStateEXT, (id));

    SU_END_FUNCTION_WRAPPER(ap_glDisableVariantClientStateEXT);
}

GLuint APIENTRY glBindLightParameterEXT(GLenum light, GLenum value)
{
    SU_START_FUNCTION_WRAPPER(ap_glBindLightParameterEXT);

    GLuint retVal = 0;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glBindLightParameterEXT, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, light, OS_TOBJ_ID_GL_ENUM_PARAMETER, value);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glBindLightParameterEXT, (light, value), retVal);

    SU_END_FUNCTION_WRAPPER(ap_glBindLightParameterEXT);

    return retVal;
}

GLuint APIENTRY glBindMaterialParameterEXT(GLenum face, GLenum value)
{
    SU_START_FUNCTION_WRAPPER(ap_glBindMaterialParameterEXT);

    GLuint retVal = 0;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glBindMaterialParameterEXT, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, face, OS_TOBJ_ID_GL_ENUM_PARAMETER, value);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glBindMaterialParameterEXT, (face, value), retVal);

    SU_END_FUNCTION_WRAPPER(ap_glBindMaterialParameterEXT);

    return retVal;
}

GLuint APIENTRY glBindTexGenParameterEXT(GLenum unit, GLenum coord, GLenum value)
{
    SU_START_FUNCTION_WRAPPER(ap_glBindTexGenParameterEXT);

    GLuint retVal = 0;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glBindTexGenParameterEXT, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, unit, OS_TOBJ_ID_GL_ENUM_PARAMETER, coord, OS_TOBJ_ID_GL_ENUM_PARAMETER, value);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glBindTexGenParameterEXT, (unit, coord, value), retVal);

    SU_END_FUNCTION_WRAPPER(ap_glBindTexGenParameterEXT);

    return retVal;
}

GLuint APIENTRY glBindTextureUnitParameterEXT(GLenum unit, GLenum value)
{
    SU_START_FUNCTION_WRAPPER(ap_glBindTextureUnitParameterEXT);

    GLuint retVal = 0;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glBindTextureUnitParameterEXT, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, unit, OS_TOBJ_ID_GL_ENUM_PARAMETER, value);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glBindTextureUnitParameterEXT, (unit, value), retVal);

    SU_END_FUNCTION_WRAPPER(ap_glBindTextureUnitParameterEXT);

    return retVal;
}

GLuint APIENTRY glBindParameterEXT(GLenum value)
{
    SU_START_FUNCTION_WRAPPER(ap_glBindParameterEXT);

    GLuint retVal = 0;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glBindParameterEXT, 1, OS_TOBJ_ID_GL_ENUM_PARAMETER, value);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glBindParameterEXT, (value), retVal);

    SU_END_FUNCTION_WRAPPER(ap_glBindParameterEXT);

    return retVal;
}

GLboolean APIENTRY glIsVariantEnabledEXT(GLuint id, GLenum cap)
{
    SU_START_FUNCTION_WRAPPER(ap_glIsVariantEnabledEXT);

    GLboolean retVal = GL_FALSE;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glIsVariantEnabledEXT, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, id, OS_TOBJ_ID_GL_ENUM_PARAMETER, cap);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glIsVariantEnabledEXT, (id, cap), retVal);

    SU_END_FUNCTION_WRAPPER(ap_glIsVariantEnabledEXT);

    return retVal;
}

void APIENTRY glGetVariantBooleanvEXT(GLuint id, GLenum value, GLboolean* data)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetVariantBooleanvEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetVariantBooleanvEXT, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, id, OS_TOBJ_ID_GL_ENUM_PARAMETER, value, OS_TOBJ_ID_GL_P_BOOL_PARAMETER, data);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetVariantBooleanvEXT, (id, value, data));

    SU_END_FUNCTION_WRAPPER(ap_glGetVariantBooleanvEXT);
}

void APIENTRY glGetVariantIntegervEXT(GLuint id, GLenum value, GLint* data)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetVariantIntegervEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetVariantIntegervEXT, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, id, OS_TOBJ_ID_GL_ENUM_PARAMETER, value, OS_TOBJ_ID_GL_P_INT_PARAMETER, data);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetVariantIntegervEXT, (id, value, data));

    SU_END_FUNCTION_WRAPPER(ap_glGetVariantIntegervEXT);
}

void APIENTRY glGetVariantFloatvEXT(GLuint id, GLenum value, GLfloat* data)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetVariantFloatvEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetVariantFloatvEXT, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, id, OS_TOBJ_ID_GL_ENUM_PARAMETER, value, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, data);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetVariantFloatvEXT, (id, value, data));

    SU_END_FUNCTION_WRAPPER(ap_glGetVariantFloatvEXT);
}

void APIENTRY glGetVariantPointervEXT(GLuint id, GLenum value, GLvoid** data)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetVariantPointervEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetVariantPointervEXT, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, id, OS_TOBJ_ID_GL_ENUM_PARAMETER, value, OS_TOBJ_ID_GL_PP_VOID_PARAMETER, data);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetVariantPointervEXT, (id, value, data));

    SU_END_FUNCTION_WRAPPER(ap_glGetVariantPointervEXT);
}

void APIENTRY glGetInvariantBooleanvEXT(GLuint id, GLenum value, GLboolean* data)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetInvariantBooleanvEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetInvariantBooleanvEXT, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, id, OS_TOBJ_ID_GL_ENUM_PARAMETER, value, OS_TOBJ_ID_GL_P_BOOL_PARAMETER, data);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetInvariantBooleanvEXT, (id, value, data));

    SU_END_FUNCTION_WRAPPER(ap_glGetInvariantBooleanvEXT);
}

void APIENTRY glGetInvariantIntegervEXT(GLuint id, GLenum value, GLint* data)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetInvariantIntegervEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetInvariantIntegervEXT, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, id, OS_TOBJ_ID_GL_ENUM_PARAMETER, value, OS_TOBJ_ID_GL_P_INT_PARAMETER, data);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetInvariantIntegervEXT, (id, value, data));

    SU_END_FUNCTION_WRAPPER(ap_glGetInvariantIntegervEXT);
}

void APIENTRY glGetInvariantFloatvEXT(GLuint id, GLenum value, GLfloat* data)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetInvariantFloatvEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetInvariantFloatvEXT, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, id, OS_TOBJ_ID_GL_ENUM_PARAMETER, value, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, data);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetInvariantFloatvEXT, (id, value, data));

    SU_END_FUNCTION_WRAPPER(ap_glGetInvariantFloatvEXT);
}

void APIENTRY glGetLocalConstantBooleanvEXT(GLuint id, GLenum value, GLboolean* data)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetLocalConstantBooleanvEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetLocalConstantBooleanvEXT, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, id, OS_TOBJ_ID_GL_ENUM_PARAMETER, value, OS_TOBJ_ID_GL_P_BOOL_PARAMETER, data);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetLocalConstantBooleanvEXT, (id, value, data));

    SU_END_FUNCTION_WRAPPER(ap_glGetLocalConstantBooleanvEXT);
}

void APIENTRY glGetLocalConstantIntegervEXT(GLuint id, GLenum value, GLint* data)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetLocalConstantIntegervEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetLocalConstantIntegervEXT, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, id, OS_TOBJ_ID_GL_ENUM_PARAMETER, value, OS_TOBJ_ID_GL_P_INT_PARAMETER, data);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetLocalConstantIntegervEXT, (id, value, data));

    SU_END_FUNCTION_WRAPPER(ap_glGetLocalConstantIntegervEXT);
}

void APIENTRY glGetLocalConstantFloatvEXT(GLuint id, GLenum value, GLfloat* data)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetLocalConstantFloatvEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetLocalConstantFloatvEXT, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, id, OS_TOBJ_ID_GL_ENUM_PARAMETER, value, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, data);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetLocalConstantFloatvEXT, (id, value, data));

    SU_END_FUNCTION_WRAPPER(ap_glGetLocalConstantFloatvEXT);
}


//////////////////////////////////////////////////////////////////////////
// GL_NV_fragment_program
//////////////////////////////////////////////////////////////////////////
void APIENTRY glProgramNamedParameter4fNV(GLuint id, GLsizei len, const GLubyte* name, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramNamedParameter4fNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramNamedParameter4fNV, 7, OS_TOBJ_ID_GL_UINT_PARAMETER, id, OS_TOBJ_ID_GL_SIZEI_PARAMETER, len, OS_TOBJ_ID_GL_P_UBYTE_PARAMETER, name, OS_TOBJ_ID_GL_FLOAT_PARAMETER, x, OS_TOBJ_ID_GL_FLOAT_PARAMETER, y, OS_TOBJ_ID_GL_FLOAT_PARAMETER, z, OS_TOBJ_ID_GL_FLOAT_PARAMETER, w);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glProgramNamedParameter4fNV, (id, len, name, x, y, z, w));

    SU_END_FUNCTION_WRAPPER(ap_glProgramNamedParameter4fNV);
}

void APIENTRY glProgramNamedParameter4dNV(GLuint id, GLsizei len, const GLubyte* name, GLdouble x, GLdouble y, GLdouble z, GLdouble w)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramNamedParameter4dNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramNamedParameter4dNV, 7, OS_TOBJ_ID_GL_UINT_PARAMETER, id, OS_TOBJ_ID_GL_SIZEI_PARAMETER, len, OS_TOBJ_ID_GL_P_UBYTE_PARAMETER, name, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, x, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, y, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, z, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, w);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glProgramNamedParameter4dNV, (id, len, name, x, y, z, w));

    SU_END_FUNCTION_WRAPPER(ap_glProgramNamedParameter4dNV);
}

void APIENTRY glProgramNamedParameter4fvNV(GLuint id, GLsizei len, const GLubyte* name, const GLfloat* v)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramNamedParameter4fvNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramNamedParameter4fvNV, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, id, OS_TOBJ_ID_GL_SIZEI_PARAMETER, len, OS_TOBJ_ID_GL_P_UBYTE_PARAMETER, name, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glProgramNamedParameter4fvNV, (id, len, name, v));

    SU_END_FUNCTION_WRAPPER(ap_glProgramNamedParameter4fvNV);
}

void APIENTRY glProgramNamedParameter4dvNV(GLuint id, GLsizei len, const GLubyte* name, const GLdouble* v)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramNamedParameter4dvNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramNamedParameter4dvNV, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, id, OS_TOBJ_ID_GL_SIZEI_PARAMETER, len, OS_TOBJ_ID_GL_P_UBYTE_PARAMETER, name, OS_TOBJ_ID_GL_P_DOUBLE_PARAMETER, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glProgramNamedParameter4dvNV, (id, len, name, v));

    SU_END_FUNCTION_WRAPPER(ap_glProgramNamedParameter4dvNV);
}

void APIENTRY glGetProgramNamedParameterfvNV(GLuint id, GLsizei len, const GLubyte* name, GLfloat* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetProgramNamedParameterfvNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetProgramNamedParameterfvNV, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, id, OS_TOBJ_ID_GL_SIZEI_PARAMETER, len, OS_TOBJ_ID_GL_P_UBYTE_PARAMETER, name, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetProgramNamedParameterfvNV, (id, len, name, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetProgramNamedParameterfvNV);
}

void APIENTRY glGetProgramNamedParameterdvNV(GLuint id, GLsizei len, const GLubyte* name, GLdouble* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetProgramNamedParameterdvNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetProgramNamedParameterdvNV, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, id, OS_TOBJ_ID_GL_SIZEI_PARAMETER, len, OS_TOBJ_ID_GL_P_UBYTE_PARAMETER, name, OS_TOBJ_ID_GL_P_DOUBLE_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetProgramNamedParameterdvNV, (id, len, name, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetProgramNamedParameterdvNV);
}

//////////////////////////////////////////////////////////////////////////
// GL_ARB_draw_buffers
//////////////////////////////////////////////////////////////////////////
void APIENTRY glDrawBuffersARB(GLsizei n, const GLenum* bufs)
{
    SU_START_FUNCTION_WRAPPER(ap_glDrawBuffersARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glDrawBuffersARB, 2, OS_TOBJ_ID_GL_SIZEI_PARAMETER, n, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_ENUM_PARAMETER, n, bufs);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glDrawBuffersARB, (n, bufs));

    SU_END_FUNCTION_WRAPPER(ap_glDrawBuffersARB);
}

//////////////////////////////////////////////////////////////////////////
// GL_ATI_draw_buffers
//////////////////////////////////////////////////////////////////////////
void APIENTRY glDrawBuffersATI(GLsizei n, const GLenum* bufs)
{
    SU_START_FUNCTION_WRAPPER(ap_glDrawBuffersATI);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glDrawBuffersATI, 2, OS_TOBJ_ID_GL_SIZEI_PARAMETER, n, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_ENUM_PARAMETER, n, bufs);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glDrawBuffersATI, (n, bufs));

    SU_END_FUNCTION_WRAPPER(ap_glDrawBuffersATI);
}

//////////////////////////////////////////////////////////////////////////
// GL_ARB_multitexture
//////////////////////////////////////////////////////////////////////////
void APIENTRY glActiveTextureARB(GLenum texture)
{
    SU_START_FUNCTION_WRAPPER(ap_glActiveTextureARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glActiveTextureARB, 1, OS_TOBJ_ID_GL_ENUM_PARAMETER, texture);

    // Log the texture unit change:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        bool rc = pCurrentThreadRenderContextMonitor->onActiveTextureUnitChanged(texture);

        if (!rc)
        {
            // Generate a detected error:
            gtString errorDescription;
            apErrorCode errorCode = AP_NON_SUPPORTED_TEXTURE_UNIT_ERROR;

            errorDescription = GS_STR_usingNonSupportedTextureUnit;

            gs_stat_openGLMonitorInstance.reportDetectedError(errorCode, errorDescription, ap_glActiveTextureARB);

        }
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glActiveTextureARB, (texture));

    SU_END_FUNCTION_WRAPPER(ap_glActiveTextureARB);
}

void APIENTRY glClientActiveTextureARB(GLenum texture)
{
    SU_START_FUNCTION_WRAPPER(ap_glClientActiveTextureARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glClientActiveTextureARB, 1, OS_TOBJ_ID_GL_ENUM_PARAMETER, texture);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glClientActiveTextureARB, (texture));

    SU_END_FUNCTION_WRAPPER(ap_glClientActiveTextureARB);
}

void APIENTRY glMultiTexCoord1dARB(GLenum target, GLdouble s)
{
    SU_START_FUNCTION_WRAPPER(ap_glMultiTexCoord1dARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexCoord1dARB, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, s);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexCoord1dARB, (target, s));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexCoord1dARB);
}

void APIENTRY glMultiTexCoord1dvARB(GLenum target, const GLdouble* v)
{
    SU_START_FUNCTION_WRAPPER(ap_glMultiTexCoord1dvARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexCoord1dvARB, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, 1, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexCoord1dvARB, (target, v));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexCoord1dvARB);
}

void APIENTRY glMultiTexCoord1fARB(GLenum target, GLfloat s)
{
    SU_START_FUNCTION_WRAPPER(ap_glMultiTexCoord1fARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexCoord1fARB, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_FLOAT_PARAMETER, s);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexCoord1fARB, (target, s));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexCoord1fARB);
}

void APIENTRY glMultiTexCoord1fvARB(GLenum target, const GLfloat* v)
{
    SU_START_FUNCTION_WRAPPER(ap_glMultiTexCoord1fvARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexCoord1fvARB, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_FLOAT_PARAMETER, 1, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexCoord1fvARB, (target, v));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexCoord1fvARB);
}

void APIENTRY glMultiTexCoord1iARB(GLenum target, GLint s)
{
    SU_START_FUNCTION_WRAPPER(ap_glMultiTexCoord1iARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexCoord1iARB, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_INT_PARAMETER, s);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexCoord1iARB, (target, s));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexCoord1iARB);
}

void APIENTRY glMultiTexCoord1ivARB(GLenum target, const GLint* v)
{
    SU_START_FUNCTION_WRAPPER(ap_glMultiTexCoord1ivARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexCoord1ivARB, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_INT_PARAMETER, 1, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexCoord1ivARB, (target, v));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexCoord1ivARB);
}

void APIENTRY glMultiTexCoord1sARB(GLenum target, GLshort s)
{
    SU_START_FUNCTION_WRAPPER(ap_glMultiTexCoord1sARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexCoord1sARB, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_SHORT_PARAMETER, s);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexCoord1sARB, (target, s));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexCoord1sARB);
}

void APIENTRY glMultiTexCoord1svARB(GLenum target, const GLshort* v)
{
    SU_START_FUNCTION_WRAPPER(ap_glMultiTexCoord1svARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexCoord1svARB, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_SHORT_PARAMETER, 1, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexCoord1svARB, (target, v));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexCoord1svARB);
}

void APIENTRY glMultiTexCoord2dARB(GLenum target, GLdouble s, GLdouble t)
{
    SU_START_FUNCTION_WRAPPER(ap_glMultiTexCoord2dARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexCoord2dARB, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, s, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, t);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexCoord2dARB, (target, s, t));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexCoord2dARB);
}

void APIENTRY glMultiTexCoord2dvARB(GLenum target, const GLdouble* v)
{
    SU_START_FUNCTION_WRAPPER(ap_glMultiTexCoord2dvARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexCoord2dvARB, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, 2, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexCoord2dvARB, (target, v));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexCoord2dvARB);
}

void APIENTRY glMultiTexCoord2fARB(GLenum target, GLfloat s, GLfloat t)
{
    SU_START_FUNCTION_WRAPPER(ap_glMultiTexCoord2fARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexCoord2fARB, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_FLOAT_PARAMETER, s, OS_TOBJ_ID_GL_FLOAT_PARAMETER, t);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexCoord2fARB, (target, s, t));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexCoord2fARB);
}

void APIENTRY glMultiTexCoord2fvARB(GLenum target, const GLfloat* v)
{
    SU_START_FUNCTION_WRAPPER(ap_glMultiTexCoord2fvARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexCoord2fvARB, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_FLOAT_PARAMETER, 2, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexCoord2fvARB, (target, v));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexCoord2fvARB);
}

void APIENTRY glMultiTexCoord2iARB(GLenum target, GLint s, GLint t)
{
    SU_START_FUNCTION_WRAPPER(ap_glMultiTexCoord2iARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexCoord2iARB, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_INT_PARAMETER, s, OS_TOBJ_ID_GL_INT_PARAMETER, t);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexCoord2iARB, (target, s, t));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexCoord2iARB);
}

void APIENTRY glMultiTexCoord2ivARB(GLenum target, const GLint* v)
{
    SU_START_FUNCTION_WRAPPER(ap_glMultiTexCoord2ivARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexCoord2ivARB, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_INT_PARAMETER, 2, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexCoord2ivARB, (target, v));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexCoord2ivARB);
}

void APIENTRY glMultiTexCoord2sARB(GLenum target, GLshort s, GLshort t)
{
    SU_START_FUNCTION_WRAPPER(ap_glMultiTexCoord2sARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexCoord2sARB, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_SHORT_PARAMETER, s, OS_TOBJ_ID_GL_SHORT_PARAMETER, t);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexCoord2sARB, (target, s, t));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexCoord2sARB);
}

void APIENTRY glMultiTexCoord2svARB(GLenum target, const GLshort* v)
{
    SU_START_FUNCTION_WRAPPER(ap_glMultiTexCoord2svARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexCoord2svARB, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_SHORT_PARAMETER, 2, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexCoord2svARB, (target, v));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexCoord2svARB);
}

void APIENTRY glMultiTexCoord3dARB(GLenum target, GLdouble s, GLdouble t, GLdouble r)
{
    SU_START_FUNCTION_WRAPPER(ap_glMultiTexCoord3dARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexCoord3dARB, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, s, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, t, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, r);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexCoord3dARB, (target, s, t, r));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexCoord3dARB);
}

void APIENTRY glMultiTexCoord3dvARB(GLenum target, const GLdouble* v)
{
    SU_START_FUNCTION_WRAPPER(ap_glMultiTexCoord3dvARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexCoord3dvARB, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, 3, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexCoord3dvARB, (target, v));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexCoord3dvARB);
}

void APIENTRY glMultiTexCoord3fARB(GLenum target, GLfloat s, GLfloat t, GLfloat r)
{
    SU_START_FUNCTION_WRAPPER(ap_glMultiTexCoord3fARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexCoord3fARB, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_FLOAT_PARAMETER, s, OS_TOBJ_ID_GL_FLOAT_PARAMETER, t, OS_TOBJ_ID_GL_FLOAT_PARAMETER, r);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexCoord3fARB, (target, s, t, r));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexCoord3fARB);
}

void APIENTRY glMultiTexCoord3fvARB(GLenum target, const GLfloat* v)
{
    SU_START_FUNCTION_WRAPPER(ap_glMultiTexCoord3fvARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexCoord3fvARB, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_FLOAT_PARAMETER, 3, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexCoord3fvARB, (target, v));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexCoord3fvARB);
}

void APIENTRY glMultiTexCoord3iARB(GLenum target, GLint s, GLint t, GLint r)
{
    SU_START_FUNCTION_WRAPPER(ap_glMultiTexCoord3iARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexCoord3iARB, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_INT_PARAMETER, s, OS_TOBJ_ID_GL_INT_PARAMETER, t, OS_TOBJ_ID_GL_INT_PARAMETER, r);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexCoord3iARB, (target, s, t, r));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexCoord3iARB);
}

void APIENTRY glMultiTexCoord3ivARB(GLenum target, const GLint* v)
{
    SU_START_FUNCTION_WRAPPER(ap_glMultiTexCoord3ivARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexCoord3ivARB, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_INT_PARAMETER, 3, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexCoord3ivARB, (target, v));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexCoord3ivARB);
}

void APIENTRY glMultiTexCoord3sARB(GLenum target, GLshort s, GLshort t, GLshort r)
{
    SU_START_FUNCTION_WRAPPER(ap_glMultiTexCoord3sARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexCoord3sARB, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_SHORT_PARAMETER, s, OS_TOBJ_ID_GL_SHORT_PARAMETER, t, OS_TOBJ_ID_GL_SHORT_PARAMETER, r);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexCoord3sARB, (target, s, t, r));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexCoord3sARB);
}

void APIENTRY glMultiTexCoord3svARB(GLenum target, const GLshort* v)
{
    SU_START_FUNCTION_WRAPPER(ap_glMultiTexCoord3svARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexCoord3svARB, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_SHORT_PARAMETER, 3, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexCoord3svARB, (target, v));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexCoord3svARB);
}

void APIENTRY glMultiTexCoord4dARB(GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q)
{
    SU_START_FUNCTION_WRAPPER(ap_glMultiTexCoord4dARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexCoord4dARB, 5, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, s, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, t, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, r, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, q);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexCoord4dARB, (target, s, t, r, q));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexCoord4dARB);
}

void APIENTRY glMultiTexCoord4dvARB(GLenum target, const GLdouble* v)
{
    SU_START_FUNCTION_WRAPPER(ap_glMultiTexCoord4dvARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexCoord4dvARB, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, 4, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexCoord4dvARB, (target, v));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexCoord4dvARB);
}

void APIENTRY glMultiTexCoord4fARB(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q)
{
    SU_START_FUNCTION_WRAPPER(ap_glMultiTexCoord4fARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexCoord4fARB, 5, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_FLOAT_PARAMETER, s, OS_TOBJ_ID_GL_FLOAT_PARAMETER, t, OS_TOBJ_ID_GL_FLOAT_PARAMETER, r, OS_TOBJ_ID_GL_FLOAT_PARAMETER, q);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexCoord4fARB, (target, s, t, r, q));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexCoord4fARB);
}

void APIENTRY glMultiTexCoord4fvARB(GLenum target, const GLfloat* v)
{
    SU_START_FUNCTION_WRAPPER(ap_glMultiTexCoord4fvARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexCoord4fvARB, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_FLOAT_PARAMETER, 4, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexCoord4fvARB, (target, v));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexCoord4fvARB);
}

void APIENTRY glMultiTexCoord4iARB(GLenum target, GLint s, GLint t, GLint r, GLint q)
{
    SU_START_FUNCTION_WRAPPER(ap_glMultiTexCoord4iARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexCoord4iARB, 5, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_INT_PARAMETER, s, OS_TOBJ_ID_GL_INT_PARAMETER, t, OS_TOBJ_ID_GL_INT_PARAMETER, r, OS_TOBJ_ID_GL_INT_PARAMETER, q);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexCoord4iARB, (target, s, t, r, q));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexCoord4iARB);
}

void APIENTRY glMultiTexCoord4ivARB(GLenum target, const GLint* v)
{
    SU_START_FUNCTION_WRAPPER(ap_glMultiTexCoord4ivARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexCoord4ivARB, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_INT_PARAMETER, 4, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexCoord4ivARB, (target, v));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexCoord4ivARB);
}

void APIENTRY glMultiTexCoord4sARB(GLenum target, GLshort s, GLshort t, GLshort r, GLshort q)
{
    SU_START_FUNCTION_WRAPPER(ap_glMultiTexCoord4sARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexCoord4sARB, 5, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_SHORT_PARAMETER, s, OS_TOBJ_ID_GL_SHORT_PARAMETER, t, OS_TOBJ_ID_GL_SHORT_PARAMETER, r, OS_TOBJ_ID_GL_SHORT_PARAMETER, q);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexCoord4sARB, (target, s, t, r, q));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexCoord4sARB);
}

void APIENTRY glMultiTexCoord4svARB(GLenum target, const GLshort* v)
{
    SU_START_FUNCTION_WRAPPER(ap_glMultiTexCoord4svARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexCoord4svARB, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_SHORT_PARAMETER, 4, v);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexCoord4svARB, (target, v));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexCoord4svARB);
}

//////////////////////////////////////////////////////////////////////////
// GL_ARB_color_buffer_float
//////////////////////////////////////////////////////////////////////////
void APIENTRY glClampColorARB(GLenum target, GLenum clamp)
{
    SU_START_FUNCTION_WRAPPER(ap_glClampColorARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glClampColorARB, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, clamp);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glClampColorARB, (target, clamp));

    SU_END_FUNCTION_WRAPPER(ap_glClampColorARB);
}

//////////////////////////////////////////////////////////////////////////
// GL_EXT_stencil_two_side
//////////////////////////////////////////////////////////////////////////
void APIENTRY glActiveStencilFaceEXT(GLenum face)
{
    SU_START_FUNCTION_WRAPPER(ap_glActiveStencilFaceEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glActiveStencilFaceEXT, 1, OS_TOBJ_ID_GL_ENUM_PARAMETER, face);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glActiveStencilFaceEXT, (face));

    SU_END_FUNCTION_WRAPPER(ap_glActiveStencilFaceEXT);
}

//////////////////////////////////////////////////////////////////////////
// GL_EXT_framebuffer_object
//////////////////////////////////////////////////////////////////////////
GLboolean APIENTRY glIsRenderbufferEXT(GLuint renderbuffer)
{
    bool inNestedFunction = su_stat_interoperabilityHelper.isInNestedFunction();
    GLboolean retVal = GL_FALSE;

    SU_START_FUNCTION_WRAPPER(ap_glIsRenderbufferEXT);

    if (!inNestedFunction)
    {
        // Log the call to this function:
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glIsRenderbufferEXT, 1, OS_TOBJ_ID_GL_UINT_PARAMETER, renderbuffer);
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glIsRenderbufferEXT, (renderbuffer), retVal);

    SU_END_FUNCTION_WRAPPER(ap_glIsRenderbufferEXT);

    return retVal;
}

void APIENTRY glBindRenderbufferEXT(GLenum target, GLuint renderbuffer)
{
    SU_START_FUNCTION_WRAPPER(ap_glBindRenderbufferEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glBindRenderbufferEXT, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_UINT_PARAMETER, renderbuffer);

    // Get the RenderContextMonitor
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        bool rcActRBO = pCurrentThreadRenderContextMonitor->activateRenderBuffer(renderbuffer);
        GT_ASSERT(rcActRBO);
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glBindRenderbufferEXT, (target, renderbuffer));

    SU_END_FUNCTION_WRAPPER(ap_glBindRenderbufferEXT);
}

void APIENTRY glDeleteRenderbuffersEXT(GLsizei n, const GLuint* renderbuffers)
{
    SU_START_FUNCTION_WRAPPER(ap_glDeleteRenderbuffersEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glDeleteRenderbuffersEXT, 2, OS_TOBJ_ID_GL_SIZEI_PARAMETER, n, OS_TOBJ_ID_GL_P_UINT_PARAMETER, renderbuffers);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glDeleteRenderbuffersEXT, (n, renderbuffers));

    // Log the textures generation:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        gsRenderBuffersMonitor* renderBuffersMon = pCurrentThreadRenderContextMonitor->renderBuffersMonitor();
        GT_IF_WITH_ASSERT(renderBuffersMon != NULL)
        {
            renderBuffersMon->onRenderBufferObjectsDeletion(n, renderbuffers);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glDeleteRenderbuffersEXT);
}

void APIENTRY glGenRenderbuffersEXT(GLsizei n, GLuint* renderbuffers)
{
    SU_START_FUNCTION_WRAPPER(ap_glGenRenderbuffersEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGenRenderbuffersEXT, 2, OS_TOBJ_ID_GL_SIZEI_PARAMETER, n, OS_TOBJ_ID_GL_P_UINT_PARAMETER, renderbuffers);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGenRenderbuffersEXT, (n, renderbuffers));

    // Log the textures generation:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        gsRenderBuffersMonitor* renderBuffersMon = pCurrentThreadRenderContextMonitor->renderBuffersMonitor();
        GT_IF_WITH_ASSERT(renderBuffersMon != NULL)
        {
            renderBuffersMon->onRenderBufferObjectsGeneration(n, renderbuffers);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glGenRenderbuffersEXT);
}

void APIENTRY glRenderbufferStorageEXT(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
{
    SU_START_FUNCTION_WRAPPER(ap_glRenderbufferStorageEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glRenderbufferStorageEXT, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, internalformat, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_SIZEI_PARAMETER, height);

    // Log the textures generation:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        bool rcRBOParams = pCurrentThreadRenderContextMonitor->setActiveRenderBufferObjectParameters(internalformat, width, height);
        GT_ASSERT(rcRBOParams);
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glRenderbufferStorageEXT, (target, internalformat, width, height));

    SU_END_FUNCTION_WRAPPER(ap_glRenderbufferStorageEXT);
}

void APIENTRY glGetRenderbufferParameterivEXT(GLenum target, GLenum pname, GLint* params)
{
    bool inNestedFunction = su_stat_interoperabilityHelper.isInNestedFunction();
    SU_START_FUNCTION_WRAPPER(ap_glGetRenderbufferParameterivEXT);

    if (!inNestedFunction)
    {
        // Log the call to this function:
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetRenderbufferParameterivEXT, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_PARAMETER, params);
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetRenderbufferParameterivEXT, (target, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetRenderbufferParameterivEXT);
}

GLboolean APIENTRY glIsFramebufferEXT(GLuint framebuffer)
{
    GLboolean retVal = GL_FALSE;

    SU_START_FUNCTION_WRAPPER(ap_glIsFramebufferEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glIsFramebufferEXT, 1, OS_TOBJ_ID_GL_UINT_PARAMETER, framebuffer);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glIsFramebufferEXT, (framebuffer), retVal);

    SU_END_FUNCTION_WRAPPER(ap_glIsFramebufferEXT);

    return retVal;
}

void APIENTRY glBindFramebufferEXT(GLenum target, GLuint framebuffer)
{
    SU_START_FUNCTION_WRAPPER(ap_glBindFramebufferEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glBindFramebufferEXT, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_UINT_PARAMETER, framebuffer);

    // Get the RenderContextMonitor
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();
    GT_IF_WITH_ASSERT(pCurrentThreadRenderContextMonitor != NULL)
    {
        bool rcActFBO = pCurrentThreadRenderContextMonitor->activateFBO(framebuffer, target);
        GT_ASSERT(rcActFBO);
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glBindFramebufferEXT, (target, framebuffer));

    SU_END_FUNCTION_WRAPPER(ap_glBindFramebufferEXT);
}

void APIENTRY glDeleteFramebuffersEXT(GLsizei n, const GLuint* framebuffers)
{
    SU_START_FUNCTION_WRAPPER(ap_glDeleteFramebuffersEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glDeleteFramebuffersEXT, 2, OS_TOBJ_ID_GL_SIZEI_PARAMETER, n, OS_TOBJ_ID_GL_P_UINT_PARAMETER, framebuffers);

    // Get the RenderContextMonitor
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    // Delete each of the FBOs from the FBOMonitor:
    GT_IF_WITH_ASSERT(pCurrentThreadRenderContextMonitor != NULL)
    {
        gsFBOMonitor* fboMon = pCurrentThreadRenderContextMonitor->fboMonitor();
        GT_IF_WITH_ASSERT(fboMon != NULL)
        {
            for (int i = 0; i < n; i++)
            {
                // delete the FBOs from the FBOs monitor
                fboMon->removeFbo(framebuffers[i]);
            }
        }
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glDeleteFramebuffersEXT, (n, framebuffers));

    SU_END_FUNCTION_WRAPPER(ap_glDeleteFramebuffersEXT);
}

void APIENTRY glGenFramebuffersEXT(GLsizei n, GLuint* framebuffers)
{
    SU_START_FUNCTION_WRAPPER(ap_glGenFramebuffersEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGenFramebuffersEXT, 2, OS_TOBJ_ID_GL_SIZEI_PARAMETER, n, OS_TOBJ_ID_GL_P_UINT_PARAMETER, framebuffers);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGenFramebuffersEXT, (n, framebuffers));

    // Get the RenderContextMonitor
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    // Construct a new apFBO for each of the generated frame buffer objects:
    GT_IF_WITH_ASSERT(pCurrentThreadRenderContextMonitor != NULL)
    {
        gsFBOMonitor* fboMon = pCurrentThreadRenderContextMonitor->fboMonitor();
        GT_IF_WITH_ASSERT(fboMon != NULL)
        {
            // Add new FBOs to the FBOs monitor
            fboMon->onGenFramebuffers(framebuffers, n);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glGenFramebuffersEXT);
}

GLenum APIENTRY glCheckFramebufferStatusEXT(GLenum target)
{
    SU_START_FUNCTION_WRAPPER(ap_glCheckFramebufferStatusEXT);

    GLenum retVal = GL_FRAMEBUFFER_UNSUPPORTED_EXT;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glCheckFramebufferStatusEXT, 1, OS_TOBJ_ID_GL_ENUM_PARAMETER, target);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glCheckFramebufferStatusEXT, (target), retVal);

    SU_END_FUNCTION_WRAPPER(ap_glCheckFramebufferStatusEXT);

    return retVal;
}

void APIENTRY glFramebufferTexture1DEXT(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
{
    SU_START_FUNCTION_WRAPPER(ap_glFramebufferTexture1DEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glFramebufferTexture1DEXT, 5, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, attachment, OS_TOBJ_ID_GL_ENUM_PARAMETER, textarget, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_INT_PARAMETER, level);

    // Get the RenderContextMonitor
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    // Construct a new apFBO for each of the generated frame buffer objects:
    GT_IF_WITH_ASSERT(pCurrentThreadRenderContextMonitor != NULL)
    {
        // Bind the texture to the active FBO:
        bool rcBindFBO = pCurrentThreadRenderContextMonitor->bindObjectToTheActiveFBO(target, textarget, attachment, texture, 0);
        GT_ASSERT(rcBindFBO);
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glFramebufferTexture1DEXT, (target, attachment, textarget, texture, level));

    SU_END_FUNCTION_WRAPPER(ap_glFramebufferTexture1DEXT);
}

void APIENTRY glFramebufferTexture2DEXT(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
{
    SU_START_FUNCTION_WRAPPER(ap_glFramebufferTexture2DEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glFramebufferTexture2DEXT, 5, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, attachment, OS_TOBJ_ID_GL_ENUM_PARAMETER, textarget, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_INT_PARAMETER, level);

    // Get the RenderContextMonitor
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    // Construct a new apFBO for each of the generated frame buffer objects:
    GT_IF_WITH_ASSERT(pCurrentThreadRenderContextMonitor != NULL)
    {
        // Bind the texture to the active FBO:
        bool rcBindFBO = pCurrentThreadRenderContextMonitor->bindObjectToTheActiveFBO(target, attachment, textarget, texture, 0);
        GT_ASSERT(rcBindFBO);
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glFramebufferTexture2DEXT, (target, attachment, textarget, texture, level));

    SU_END_FUNCTION_WRAPPER(ap_glFramebufferTexture2DEXT);
}

void APIENTRY glFramebufferTexture3DEXT(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset)
{
    SU_START_FUNCTION_WRAPPER(ap_glFramebufferTexture3DEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glFramebufferTexture3DEXT, 6, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, attachment, OS_TOBJ_ID_GL_ENUM_PARAMETER, textarget, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_INT_PARAMETER, zoffset);

    // Get the RenderContextMonitor
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    // Construct a new apFBO for each of the generated frame buffer objects:
    GT_IF_WITH_ASSERT(pCurrentThreadRenderContextMonitor != NULL)
    {
        // Bind the texture to the active FBO:
        bool rcBindFBO = pCurrentThreadRenderContextMonitor->bindObjectToTheActiveFBO(target, attachment, textarget, texture, 0);
        GT_ASSERT(rcBindFBO);
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glFramebufferTexture3DEXT, (target, attachment, textarget, texture, level, zoffset));

    SU_END_FUNCTION_WRAPPER(ap_glFramebufferTexture3DEXT);
}

void APIENTRY glFramebufferRenderbufferEXT(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
{
    SU_START_FUNCTION_WRAPPER(ap_glFramebufferRenderbufferEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glFramebufferRenderbufferEXT, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, attachment, OS_TOBJ_ID_GL_ENUM_PARAMETER, renderbuffertarget, OS_TOBJ_ID_GL_UINT_PARAMETER, renderbuffer);

    // Get the RenderContextMonitor
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    // Construct a new apFBO for each of the generated frame buffer objects:
    GT_IF_WITH_ASSERT(pCurrentThreadRenderContextMonitor != NULL)
    {
        // Bind the texture to the active FBO:
        bool rcBindFBO = pCurrentThreadRenderContextMonitor->bindObjectToTheActiveFBO(target, attachment, renderbuffertarget, renderbuffer, 0);
        GT_ASSERT(rcBindFBO);
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glFramebufferRenderbufferEXT, (target, attachment, renderbuffertarget, renderbuffer));

    SU_END_FUNCTION_WRAPPER(ap_glFramebufferRenderbufferEXT);
}

void APIENTRY glGetFramebufferAttachmentParameterivEXT(GLenum target, GLenum attachment, GLenum pname, GLint* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetFramebufferAttachmentParameterivEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetFramebufferAttachmentParameterivEXT, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, attachment, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetFramebufferAttachmentParameterivEXT, (target, attachment, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetFramebufferAttachmentParameterivEXT);
}

void APIENTRY glGenerateMipmapEXT(GLenum target)
{
    SU_START_FUNCTION_WRAPPER(ap_glGenerateMipmapEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGenerateMipmapEXT, 1, OS_TOBJ_ID_GL_ENUM_PARAMETER, target);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGenerateMipmapEXT, (target));

    // Log the mipmap generation:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (pCurrentThreadRenderContextMonitor != NULL)
    {
        pCurrentThreadRenderContextMonitor->onTextureMipmapGenerate(target);
    }

    SU_END_FUNCTION_WRAPPER(ap_glGenerateMipmapEXT);
}

//////////////////////////////////////////////////////////////////////////
// GL_EXT_framebuffer_blit
//////////////////////////////////////////////////////////////////////////
void APIENTRY glBlitFramebufferEXT(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter)
{
    SU_START_FUNCTION_WRAPPER(ap_glBlitFramebufferEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glBlitFramebufferEXT, 10, OS_TOBJ_ID_GL_INT_PARAMETER, srcX0, OS_TOBJ_ID_GL_INT_PARAMETER, srcX1, OS_TOBJ_ID_GL_INT_PARAMETER, srcY0, OS_TOBJ_ID_GL_INT_PARAMETER, srcY1, OS_TOBJ_ID_GL_INT_PARAMETER, dstX0, OS_TOBJ_ID_GL_INT_PARAMETER, dstY0, OS_TOBJ_ID_GL_INT_PARAMETER, dstY1, OS_TOBJ_ID_GL_INT_PARAMETER, dstY1, OS_TOBJ_ID_GL_BITFIELD_PARAMETER, mask, OS_TOBJ_ID_GL_ENUM_PARAMETER, filter);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glBlitFramebufferEXT, (srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter));

    SU_END_FUNCTION_WRAPPER(ap_glBlitFramebufferEXT);
}

//////////////////////////////////////////////////////////////////////////
// GL_EXT_framebuffer_multisample
//////////////////////////////////////////////////////////////////////////
void APIENTRY glRenderbufferStorageMultisampleEXT(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
{
    SU_START_FUNCTION_WRAPPER(ap_glRenderbufferStorageMultisampleEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glRenderbufferStorageMultisampleEXT, 5, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_SIZEI_PARAMETER, samples, OS_TOBJ_ID_GL_ENUM_PARAMETER, internalformat, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_SIZEI_PARAMETER, height);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glRenderbufferStorageMultisampleEXT, (target, samples, internalformat, width, height));

    SU_END_FUNCTION_WRAPPER(ap_glRenderbufferStorageMultisampleEXT);
}


//////////////////////////////////////////////////////////////////////////
// GL_ARB_framebuffer_object
//////////////////////////////////////////////////////////////////////////
GLboolean APIENTRY glIsRenderbuffer(GLuint renderbuffer)
{
    GLboolean retVal = GL_FALSE;

    SU_START_FUNCTION_WRAPPER(ap_glIsRenderbuffer);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glIsRenderbuffer, 1, OS_TOBJ_ID_GL_UINT_PARAMETER, renderbuffer);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glIsRenderbuffer, (renderbuffer), retVal);

    SU_END_FUNCTION_WRAPPER(ap_glIsRenderbuffer);

    return retVal;
}

void APIENTRY glBindRenderbuffer(GLenum target, GLuint renderbuffer)
{
    SU_START_FUNCTION_WRAPPER(ap_glBindRenderbuffer);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glBindRenderbuffer, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_UINT_PARAMETER, renderbuffer);

    // Get the RenderContextMonitor
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        bool rcActRBO = pCurrentThreadRenderContextMonitor->activateRenderBuffer(renderbuffer);
        GT_ASSERT(rcActRBO);
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glBindRenderbuffer, (target, renderbuffer));

    SU_END_FUNCTION_WRAPPER(ap_glBindRenderbuffer);
}

void APIENTRY glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
{
    SU_START_FUNCTION_WRAPPER(ap_glDeleteRenderbuffers);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glDeleteRenderbuffers, 2, OS_TOBJ_ID_GL_SIZEI_PARAMETER, n, OS_TOBJ_ID_GL_P_UINT_PARAMETER, renderbuffers);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glDeleteRenderbuffers, (n, renderbuffers));

    // Log the textures generation:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        gsRenderBuffersMonitor* renderBuffersMon = pCurrentThreadRenderContextMonitor->renderBuffersMonitor();
        GT_IF_WITH_ASSERT(renderBuffersMon != NULL)
        {
            renderBuffersMon->onRenderBufferObjectsDeletion(n, renderbuffers);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glDeleteRenderbuffers);
}

void APIENTRY glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
{
    SU_START_FUNCTION_WRAPPER(ap_glGenRenderbuffers);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGenRenderbuffers, 2, OS_TOBJ_ID_GL_SIZEI_PARAMETER, n, OS_TOBJ_ID_GL_P_UINT_PARAMETER, renderbuffers);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGenRenderbuffers, (n, renderbuffers));

    // Log the textures generation:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        gsRenderBuffersMonitor* renderBuffersMon = pCurrentThreadRenderContextMonitor->renderBuffersMonitor();
        GT_IF_WITH_ASSERT(renderBuffersMon != NULL)
        {
            renderBuffersMon->onRenderBufferObjectsGeneration(n, renderbuffers);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glGenRenderbuffers);
}

void APIENTRY glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
{
    SU_START_FUNCTION_WRAPPER(ap_glRenderbufferStorage);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glRenderbufferStorage, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, internalformat, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_SIZEI_PARAMETER, height);

    // Log the textures generation:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        bool rcRBOParams = pCurrentThreadRenderContextMonitor->setActiveRenderBufferObjectParameters(internalformat, width, height);
        GT_ASSERT(rcRBOParams);
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glRenderbufferStorage, (target, internalformat, width, height));

    SU_END_FUNCTION_WRAPPER(ap_glRenderbufferStorage);
}

void APIENTRY glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetRenderbufferParameteriv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetRenderbufferParameteriv, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetRenderbufferParameteriv, (target, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetRenderbufferParameteriv);
}

GLboolean APIENTRY glIsFramebuffer(GLuint framebuffer)
{
    GLboolean retVal = GL_FALSE;

    SU_START_FUNCTION_WRAPPER(ap_glIsFramebuffer);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glIsFramebuffer, 1, OS_TOBJ_ID_GL_UINT_PARAMETER, framebuffer);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glIsFramebuffer, (framebuffer), retVal);

    SU_END_FUNCTION_WRAPPER(ap_glIsFramebuffer);

    return retVal;
}

void APIENTRY glBindFramebuffer(GLenum target, GLuint framebuffer)
{
    SU_START_FUNCTION_WRAPPER(ap_glBindFramebuffer);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glBindFramebuffer, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_UINT_PARAMETER, framebuffer);

    // Get the RenderContextMonitor
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();
    GT_IF_WITH_ASSERT(pCurrentThreadRenderContextMonitor != NULL)
    {
        bool rcActFBO = pCurrentThreadRenderContextMonitor->activateFBO(framebuffer, target);
        GT_ASSERT(rcActFBO);
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glBindFramebuffer, (target, framebuffer));

    SU_END_FUNCTION_WRAPPER(ap_glBindFramebuffer);
}

void APIENTRY glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
{
    SU_START_FUNCTION_WRAPPER(ap_glDeleteFramebuffers);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glDeleteFramebuffers, 2, OS_TOBJ_ID_GL_SIZEI_PARAMETER, n, OS_TOBJ_ID_GL_P_UINT_PARAMETER, framebuffers);

    // Get the RenderContextMonitor
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    // Delete each of the FBOs from the FBOMonitor:
    GT_IF_WITH_ASSERT(pCurrentThreadRenderContextMonitor != NULL)
    {
        gsFBOMonitor* fboMon = pCurrentThreadRenderContextMonitor->fboMonitor();
        GT_IF_WITH_ASSERT(fboMon != NULL)
        {
            for (int i = 0; i < n; i++)
            {
                // delete the FBOs from the FBOs monitor
                fboMon->removeFbo(framebuffers[i]);
            }
        }
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glDeleteFramebuffers, (n, framebuffers));

    SU_END_FUNCTION_WRAPPER(ap_glDeleteFramebuffers);
}

void APIENTRY glGenFramebuffers(GLsizei n, GLuint* framebuffers)
{
    SU_START_FUNCTION_WRAPPER(ap_glGenFramebuffers);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGenFramebuffers, 2, OS_TOBJ_ID_GL_SIZEI_PARAMETER, n, OS_TOBJ_ID_GL_P_UINT_PARAMETER, framebuffers);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGenFramebuffers, (n, framebuffers));

    // Get the RenderContextMonitor
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    // Construct a new apFBO for each of the generated frame buffer objects:
    GT_IF_WITH_ASSERT(pCurrentThreadRenderContextMonitor != NULL)
    {
        gsFBOMonitor* fboMon = pCurrentThreadRenderContextMonitor->fboMonitor();
        GT_IF_WITH_ASSERT(fboMon != NULL)
        {
            // Add new FBOs to the FBOs monitor
            fboMon->onGenFramebuffers(framebuffers, n);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glGenFramebuffers);
}

GLenum APIENTRY glCheckFramebufferStatus(GLenum target)
{
    SU_START_FUNCTION_WRAPPER(ap_glCheckFramebufferStatus);

    GLenum retVal = GL_FRAMEBUFFER_UNSUPPORTED_EXT;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glCheckFramebufferStatus, 1, OS_TOBJ_ID_GL_ENUM_PARAMETER, target);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glCheckFramebufferStatus, (target), retVal);

    SU_END_FUNCTION_WRAPPER(ap_glCheckFramebufferStatus);

    return retVal;
}

void APIENTRY glFramebufferTexture1D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
{
    SU_START_FUNCTION_WRAPPER(ap_glFramebufferTexture1D);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glFramebufferTexture1D, 5, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, attachment, OS_TOBJ_ID_GL_ENUM_PARAMETER, textarget, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_INT_PARAMETER, level);

    // Get the RenderContextMonitor
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    // Construct a new apFBO for each of the generated frame buffer objects:
    GT_IF_WITH_ASSERT(pCurrentThreadRenderContextMonitor != NULL)
    {
        // Bind the texture to the active FBO:
        bool rcBindFBO = pCurrentThreadRenderContextMonitor->bindObjectToTheActiveFBO(target, attachment, textarget, texture, 0);
        GT_ASSERT(rcBindFBO);
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glFramebufferTexture1D, (target, attachment, textarget, texture, level));

    SU_END_FUNCTION_WRAPPER(ap_glFramebufferTexture1D);
}

void APIENTRY glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
{
    SU_START_FUNCTION_WRAPPER(ap_glFramebufferTexture2D);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glFramebufferTexture2D, 5, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, attachment, OS_TOBJ_ID_GL_ENUM_PARAMETER, textarget, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_INT_PARAMETER, level);

    // Get the RenderContextMonitor
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    // Construct a new apFBO for each of the generated frame buffer objects:
    GT_IF_WITH_ASSERT(pCurrentThreadRenderContextMonitor != NULL)
    {
        // Bind the texture to the active FBO:
        bool rcBindFBO = pCurrentThreadRenderContextMonitor->bindObjectToTheActiveFBO(target, attachment, textarget, texture, 0);
        GT_ASSERT(rcBindFBO);
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glFramebufferTexture2D, (target, attachment, textarget, texture, level));

    SU_END_FUNCTION_WRAPPER(ap_glFramebufferTexture2D);
}

void APIENTRY glFramebufferTexture3D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset)
{
    SU_START_FUNCTION_WRAPPER(ap_glFramebufferTexture3D);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glFramebufferTexture3D, 6, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, attachment, OS_TOBJ_ID_GL_ENUM_PARAMETER, textarget, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_INT_PARAMETER, zoffset);

    // Get the RenderContextMonitor
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    // Construct a new apFBO for each of the generated frame buffer objects:
    GT_IF_WITH_ASSERT(pCurrentThreadRenderContextMonitor != NULL)
    {
        // Bind the texture to the active FBO:
        bool rcBindFBO = pCurrentThreadRenderContextMonitor->bindObjectToTheActiveFBO(target, attachment, textarget, texture, 0);
        GT_ASSERT(rcBindFBO);
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glFramebufferTexture3D, (target, attachment, textarget, texture, level, zoffset));

    SU_END_FUNCTION_WRAPPER(ap_glFramebufferTexture3D);
}

void APIENTRY glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
{
    SU_START_FUNCTION_WRAPPER(ap_glFramebufferRenderbuffer);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glFramebufferRenderbuffer, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, attachment, OS_TOBJ_ID_GL_ENUM_PARAMETER, renderbuffertarget, OS_TOBJ_ID_GL_UINT_PARAMETER, renderbuffer);

    // Get the RenderContextMonitor
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    // Construct a new apFBO for each of the generated frame buffer objects:
    GT_IF_WITH_ASSERT(pCurrentThreadRenderContextMonitor != NULL)
    {
        // Bind the texture to the active FBO:
        bool rcBindFBO = pCurrentThreadRenderContextMonitor->bindObjectToTheActiveFBO(target, attachment, renderbuffertarget, renderbuffer, 0);
        GT_ASSERT(rcBindFBO);
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glFramebufferRenderbuffer, (target, attachment, renderbuffertarget, renderbuffer));

    SU_END_FUNCTION_WRAPPER(ap_glFramebufferRenderbuffer);
}

void APIENTRY glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetFramebufferAttachmentParameteriv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetFramebufferAttachmentParameteriv, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, attachment, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetFramebufferAttachmentParameteriv, (target, attachment, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetFramebufferAttachmentParameteriv);
}

void APIENTRY glGenerateMipmap(GLenum target)
{
    SU_START_FUNCTION_WRAPPER(ap_glGenerateMipmap);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGenerateMipmap, 1, OS_TOBJ_ID_GL_ENUM_PARAMETER, target);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGenerateMipmap, (target));

    // Log the mipmap generation:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (pCurrentThreadRenderContextMonitor != NULL)
    {
        pCurrentThreadRenderContextMonitor->onTextureMipmapGenerate(target);
    }

    SU_END_FUNCTION_WRAPPER(ap_glGenerateMipmap);
}

void APIENTRY glBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter)
{
    SU_START_FUNCTION_WRAPPER(ap_glBlitFramebuffer);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glBlitFramebuffer, 10, OS_TOBJ_ID_GL_INT_PARAMETER, srcX0, OS_TOBJ_ID_GL_INT_PARAMETER, srcY0, OS_TOBJ_ID_GL_INT_PARAMETER, srcX1, OS_TOBJ_ID_GL_INT_PARAMETER, srcY1, OS_TOBJ_ID_GL_INT_PARAMETER, dstX0, OS_TOBJ_ID_GL_INT_PARAMETER, dstY0, OS_TOBJ_ID_GL_INT_PARAMETER, dstX1, OS_TOBJ_ID_GL_INT_PARAMETER, dstY1, OS_TOBJ_ID_GL_BITFIELD_PARAMETER, mask, OS_TOBJ_ID_GL_ENUM_PARAMETER, filter);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glBlitFramebuffer, (srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter));

    SU_END_FUNCTION_WRAPPER(ap_glBlitFramebuffer);
}
void APIENTRY glRenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
{
    SU_START_FUNCTION_WRAPPER(ap_glRenderbufferStorageMultisample);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glRenderbufferStorageMultisample, 5, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_SIZEI_PARAMETER, samples, OS_TOBJ_ID_GL_ENUM_PARAMETER, internalformat, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_SIZEI_PARAMETER, height);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glRenderbufferStorageMultisample, (target, samples, internalformat, width, height));

    SU_END_FUNCTION_WRAPPER(ap_glRenderbufferStorageMultisample);
}
void APIENTRY glFramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer)
{
    SU_START_FUNCTION_WRAPPER(ap_glFramebufferTextureLayer);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glFramebufferTextureLayer, 5, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, attachment, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_INT_PARAMETER, layer);

    // Get the RenderContextMonitor:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    // Construct a new apFBO for each of the generated frame buffer objects:
    GT_IF_WITH_ASSERT(pCurrentThreadRenderContextMonitor != NULL)
    {
        // Bind the texture to the active FBO:
        bool rcBindFBO = pCurrentThreadRenderContextMonitor->bindTextureLayerToTheActiveFBO(target, GL_NONE, attachment, texture, layer);
        GT_ASSERT(rcBindFBO);
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glFramebufferTextureLayer, (target, attachment, texture, level, layer));

    SU_END_FUNCTION_WRAPPER(ap_glFramebufferTextureLayer);
}

//////////////////////////////////////////////////////////////////////////
// GL_EXT_multi_draw_arrays
//////////////////////////////////////////////////////////////////////////
void APIENTRY glMultiDrawArraysEXT(GLenum mode, const GLint* first, const GLsizei* count, GLsizei primcount)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glMultiDrawArraysEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiDrawArraysEXT, 4, OS_TOBJ_ID_GL_PRIMITIVE_TYPE_PARAMETER, mode, OS_TOBJ_ID_GL_P_INT_PARAMETER, first, OS_TOBJ_ID_GL_P_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_SIZEI_PARAMETER, primcount);

    // Get the current render context monitor:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (pCurrentThreadRenderContextMonitor != NULL)
    {
        // Get the render primitives statistics logger:
        gsRenderPrimitivesStatisticsLogger& renderPrimitivesStatisticsLogger = pCurrentThreadRenderContextMonitor->renderPrimitivesStatisticsLogger();

        // Log this draw primitives function call:
        renderPrimitivesStatisticsLogger.onMultiDrawArrays(count, primcount, mode);
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiDrawArraysEXT, (mode, first, count, primcount));

    SU_END_FUNCTION_WRAPPER(ap_glMultiDrawArraysEXT);
}

void APIENTRY glMultiDrawElementsEXT(GLenum mode, const GLsizei* count, GLenum type, const GLvoid* const* indices, GLsizei primcount)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glMultiDrawElementsEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiDrawElementsEXT, 5, OS_TOBJ_ID_GL_PRIMITIVE_TYPE_PARAMETER, mode, OS_TOBJ_ID_GL_P_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_PP_VOID_PARAMETER, indices, OS_TOBJ_ID_GL_SIZEI_PARAMETER, primcount);

    // Get the current render context monitor:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (pCurrentThreadRenderContextMonitor != NULL)
    {
        // Get the render primitives statistics logger:
        gsRenderPrimitivesStatisticsLogger& renderPrimitivesStatisticsLogger = pCurrentThreadRenderContextMonitor->renderPrimitivesStatisticsLogger();

        // Log this draw primitives function call:
        renderPrimitivesStatisticsLogger.onMultiDrawElements(count, primcount, mode, type);
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiDrawElementsEXT, (mode, count, type, indices, primcount));

    SU_END_FUNCTION_WRAPPER(ap_glMultiDrawElementsEXT);
}


//////////////////////////////////////////////////////////////////////////
// GL_ARB_multisample
//////////////////////////////////////////////////////////////////////////
void APIENTRY glSampleCoverageARB(GLclampf value, GLboolean invert)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glSampleCoverageARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glSampleCoverageARB, 2, OS_TOBJ_ID_GL_CLAMPF_PARAMETER, value, OS_TOBJ_ID_GL_BOOL_PARAMETER, invert);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glSampleCoverageARB, (value, invert));

    SU_END_FUNCTION_WRAPPER(ap_glSampleCoverageARB);
}

//////////////////////////////////////////////////////////////////////////
// GL_EXT_blend_minmax
//////////////////////////////////////////////////////////////////////////
void APIENTRY glBlendEquationEXT(GLenum mode)
{
    SU_START_FUNCTION_WRAPPER(ap_glBlendEquationEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glBlendEquationEXT, 1, OS_TOBJ_ID_GL_ENUM_PARAMETER, mode);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glBlendEquationEXT, (mode));

    SU_END_FUNCTION_WRAPPER(ap_glBlendEquationEXT);
}

//////////////////////////////////////////////////////////////////////////
// GL_EXT_geometry_shader4
//////////////////////////////////////////////////////////////////////////
void APIENTRY glProgramParameteriEXT(GLuint program, GLenum pname, GLint value)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramParameteriEXT);

    // Log the call to this function:
    // If the second parameter is input or output primitives, log the third parameter as an enumerator:
    if ((pname == GL_GEOMETRY_INPUT_TYPE_EXT) || (pname == GL_GEOMETRY_OUTPUT_TYPE_EXT))
    {
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramParameteriEXT, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_PRIMITIVE_TYPE_PARAMETER, value);
    }
    else
    {
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramParameteriEXT, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_INT_PARAMETER, value);
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glProgramParameteriEXT, (program, pname, value));

    // Log the parameter change:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (pCurrentThreadRenderContextMonitor != NULL)
    {
        gsProgramsAndShadersMonitor* progAndShaderMon = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(progAndShaderMon != NULL)
        {
            bool rc = progAndShaderMon->onProgramParameteri(program, pname, value);

            if (!rc)
            {
                if (!progAndShaderMon->isProgramObject(program))
                {
                    gtString errorDescription;
                    apErrorCode errorCode = AP_OBJECT_NAME_DOES_NOT_EXIST_ERROR;
                    errorDescription = GS_STR_usingNonObjectName;
                    errorDescription.appendFormattedString(L": (program name = %u)", program);
                    gs_stat_openGLMonitorInstance.reportDetectedError(errorCode, errorDescription, ap_glProgramParameteriEXT);
                }
                else
                {
                    // Currently do nothing, since we could receive a pname of a parameter we don't want to log
                }
            }
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramParameteriEXT);
}

void APIENTRY glFramebufferTextureEXT(GLenum target, GLenum attachment, GLuint texture, GLint level)
{
    SU_START_FUNCTION_WRAPPER(ap_glFramebufferTextureEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glFramebufferTextureEXT, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, attachment, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_INT_PARAMETER, level);

    // Get the RenderContextMonitor
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    // Construct a new apFBO for each of the generated frame buffer objects:
    GT_IF_WITH_ASSERT(pCurrentThreadRenderContextMonitor != NULL)
    {
        // Bind the texture to the active FBO:
        bool rcBindFBO = pCurrentThreadRenderContextMonitor->bindTextureToTheActiveFBO(target, GL_NONE, attachment, texture, 0);
        GT_ASSERT(rcBindFBO);
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glFramebufferTextureEXT, (target, attachment, texture, level));

    SU_END_FUNCTION_WRAPPER(ap_glFramebufferTextureEXT);
}

void APIENTRY glFramebufferTextureLayerEXT(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer)
{
    SU_START_FUNCTION_WRAPPER(ap_glFramebufferTextureLayerEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glFramebufferTextureLayerEXT, 5, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, attachment, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_INT_PARAMETER, layer);

    // Get the RenderContextMonitor:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    // Construct a new apFBO for each of the generated frame buffer objects:
    GT_IF_WITH_ASSERT(pCurrentThreadRenderContextMonitor != NULL)
    {
        // Bind the texture to the active FBO:
        bool rcBindFBO = pCurrentThreadRenderContextMonitor->bindTextureLayerToTheActiveFBO(target, GL_NONE, attachment, texture, layer);
        GT_ASSERT(rcBindFBO);
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glFramebufferTextureLayerEXT, (target, attachment, texture, level, layer));

    SU_END_FUNCTION_WRAPPER(ap_glFramebufferTextureLayerEXT);
}

void APIENTRY glFramebufferTextureFaceEXT(GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face)
{
    SU_START_FUNCTION_WRAPPER(ap_glFramebufferTextureFaceEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glFramebufferTextureFaceEXT, 5, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, attachment, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_ENUM_PARAMETER, face);

    // Get the RenderContextMonitor:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    // Construct a new apFBO for each of the generated frame buffer objects:
    GT_IF_WITH_ASSERT(pCurrentThreadRenderContextMonitor != NULL)
    {
        // Bind the texture to the active FBO:
        bool rcBindFBO = pCurrentThreadRenderContextMonitor->bindTextureToTheActiveFBO(target, GL_NONE, attachment, texture, face);
        GT_ASSERT(rcBindFBO);
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glFramebufferTextureFaceEXT, (target, attachment, texture, level, face));

    SU_END_FUNCTION_WRAPPER(ap_glFramebufferTextureFaceEXT);
}

//////////////////////////////////////////////////////////////////////////
// GL_NV_shader_buffer_load
//////////////////////////////////////////////////////////////////////////
void APIENTRY glMakeBufferResidentNV(GLenum target, GLenum access)
{
    SU_START_FUNCTION_WRAPPER(ap_glMakeBufferResidentNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMakeBufferResidentNV, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, access);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMakeBufferResidentNV, (target, access));

    SU_END_FUNCTION_WRAPPER(ap_glMakeBufferResidentNV);
}

void APIENTRY glMakeBufferNonResidentNV(GLenum target)
{
    SU_START_FUNCTION_WRAPPER(ap_glMakeBufferNonResidentNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMakeBufferNonResidentNV, 1, OS_TOBJ_ID_GL_ENUM_PARAMETER, target);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMakeBufferNonResidentNV, (target));

    SU_END_FUNCTION_WRAPPER(ap_glMakeBufferNonResidentNV);
}

GLboolean APIENTRY glIsBufferResidentNV(GLenum target)
{
    SU_START_FUNCTION_WRAPPER(ap_glIsBufferResidentNV);

    GLboolean retVal = GL_FALSE;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glIsBufferResidentNV, 1, OS_TOBJ_ID_GL_ENUM_PARAMETER, target);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glIsBufferResidentNV, (target), retVal);

    SU_END_FUNCTION_WRAPPER(ap_glIsBufferResidentNV);

    return retVal;
}

void APIENTRY glMakeNamedBufferResidentNV(GLuint buffer, GLenum access)
{
    SU_START_FUNCTION_WRAPPER(ap_glMakeNamedBufferResidentNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMakeNamedBufferResidentNV, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, buffer, OS_TOBJ_ID_GL_ENUM_PARAMETER, access);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMakeNamedBufferResidentNV, (buffer, access));

    SU_END_FUNCTION_WRAPPER(ap_glMakeNamedBufferResidentNV);
}

void APIENTRY glMakeNamedBufferNonResidentNV(GLuint buffer)
{
    SU_START_FUNCTION_WRAPPER(ap_glMakeNamedBufferNonResidentNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMakeNamedBufferNonResidentNV, 1, OS_TOBJ_ID_GL_UINT_PARAMETER, buffer);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMakeNamedBufferNonResidentNV, (buffer));

    SU_END_FUNCTION_WRAPPER(ap_glMakeNamedBufferNonResidentNV);
}

void APIENTRY glNamedMakeBufferResidentNV(GLuint buffer, GLenum access)
{
    SU_START_FUNCTION_WRAPPER(ap_glNamedMakeBufferResidentNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glNamedMakeBufferResidentNV, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, buffer, OS_TOBJ_ID_GL_ENUM_PARAMETER, access);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glNamedMakeBufferResidentNV, (buffer, access));

    SU_END_FUNCTION_WRAPPER(ap_glNamedMakeBufferResidentNV);
}

void APIENTRY glNamedMakeBufferNonResidentNV(GLuint buffer)
{
    SU_START_FUNCTION_WRAPPER(ap_glNamedMakeBufferNonResidentNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glNamedMakeBufferNonResidentNV, 1, OS_TOBJ_ID_GL_UINT_PARAMETER, buffer);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glNamedMakeBufferNonResidentNV, (buffer));

    SU_END_FUNCTION_WRAPPER(ap_glNamedMakeBufferNonResidentNV);
}

GLboolean APIENTRY glIsNamedBufferResidentNV(GLuint buffer)
{
    SU_START_FUNCTION_WRAPPER(ap_glIsNamedBufferResidentNV);

    GLboolean retVal = GL_FALSE;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glIsNamedBufferResidentNV, 1, OS_TOBJ_ID_GL_UINT_PARAMETER, buffer);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glIsNamedBufferResidentNV, (buffer), retVal);

    SU_END_FUNCTION_WRAPPER(ap_glIsNamedBufferResidentNV);

    return retVal;
}

void APIENTRY glGetBufferParameterui64vNV(GLenum target, GLenum pname, GLuint64EXT* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetBufferParameterui64vNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetBufferParameterui64vNV, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_UINT_64_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetBufferParameterui64vNV, (target, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetBufferParameterui64vNV);
}
void APIENTRY glGetNamedBufferParameterui64vNV(GLenum buffer, GLenum pname, GLuint64EXT* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetNamedBufferParameterui64vNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetNamedBufferParameterui64vNV, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, buffer, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_UINT_64_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetNamedBufferParameterui64vNV, (buffer, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetNamedBufferParameterui64vNV);
}

void APIENTRY glGetIntegerui64vNV(GLenum value, GLuint64EXT* result)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetIntegerui64vNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetIntegerui64vNV, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, value, OS_TOBJ_ID_GL_P_UINT_64_PARAMETER, result);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetIntegerui64vNV, (value, result));

    SU_END_FUNCTION_WRAPPER(ap_glGetIntegerui64vNV);
}

void APIENTRY glUniformui64NV(GLint location, GLuint64EXT value)
{
    SU_START_FUNCTION_WRAPPER(ap_glUniformui64NV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glUniformui64NV, 3, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_UINT_64_PARAMETER, value);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glUniformui64NV, (location, value));

    SU_END_FUNCTION_WRAPPER(ap_glUniformui64NV);
}
void APIENTRY glUniformui64vNV(GLint location, GLsizei count, const GLuint64EXT* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glUniformui64vNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glUniformui64vNV, 3, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_P_UINT_64_PARAMETER, value);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glUniformui64vNV, (location, count, value));

    SU_END_FUNCTION_WRAPPER(ap_glUniformui64vNV);
}
void APIENTRY glGetUniformui64vNV(GLuint program, GLint location, GLuint64EXT* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetUniformui64vNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetUniformui64vNV, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_P_UINT_64_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetUniformui64vNV, (program, location, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetUniformui64vNV);
}
void APIENTRY glProgramUniformui64NV(GLuint program, GLint location, GLuint64EXT value)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniformui64NV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniformui64NV, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_UINT_64_PARAMETER, value);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glProgramUniformui64NV, (program, location, value));

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniformui64NV);
}
void APIENTRY glProgramUniformui64vNV(GLuint program, GLint location, GLsizei count, const GLuint64EXT* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniformui64vNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniformui64vNV, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_P_UINT_64_PARAMETER, value);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glProgramUniformui64vNV, (program, location, count, value));

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniformui64vNV);
}

//////////////////////////////////////////////////////////////////////////
// GL_NV_vertex_buffer_unified_memory
//////////////////////////////////////////////////////////////////////////
void APIENTRY glBufferAddressRangeNV(GLenum pname, GLuint index, GLuint64EXT address, GLsizeiptr length)
{
    SU_START_FUNCTION_WRAPPER(ap_glBufferAddressRangeNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glBufferAddressRangeNV, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_UINT_64_ADDRESS_PARAMETER, address, OS_TOBJ_ID_GL_SIZEIPTR_PARAMETER, length);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glBufferAddressRangeNV, (pname, index, address, length));

    SU_END_FUNCTION_WRAPPER(ap_glBufferAddressRangeNV);
}

void APIENTRY glVertexFormatNV(GLint size, GLenum type, GLsizei stride)
{
    SU_START_FUNCTION_WRAPPER(ap_glVertexFormatNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexFormatNV, 3, OS_TOBJ_ID_GL_INT_PARAMETER, size, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_SIZEI_PARAMETER, stride);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexFormatNV, (size, type, stride));

    SU_END_FUNCTION_WRAPPER(ap_glVertexFormatNV);
}

void APIENTRY glNormalFormatNV(GLenum type, GLsizei stride)
{
    SU_START_FUNCTION_WRAPPER(ap_glNormalFormatNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glNormalFormatNV, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_SIZEI_PARAMETER, stride);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glNormalFormatNV, (type, stride));

    SU_END_FUNCTION_WRAPPER(ap_glNormalFormatNV);
}

void APIENTRY glColorFormatNV(GLint size, GLenum type, GLsizei stride)
{
    SU_START_FUNCTION_WRAPPER(ap_glColorFormatNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glColorFormatNV, 3, OS_TOBJ_ID_GL_INT_PARAMETER, size, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_SIZEI_PARAMETER, stride);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glColorFormatNV, (size, type, stride));

    SU_END_FUNCTION_WRAPPER(ap_glColorFormatNV);
}

void APIENTRY glIndexFormatNV(GLenum type, GLsizei stride)
{
    SU_START_FUNCTION_WRAPPER(ap_glIndexFormatNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glIndexFormatNV, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_SIZEI_PARAMETER, stride);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glIndexFormatNV, (type, stride));

    SU_END_FUNCTION_WRAPPER(ap_glIndexFormatNV);
}

void APIENTRY glTexCoordFormatNV(GLint size, GLenum type, GLsizei stride)
{
    SU_START_FUNCTION_WRAPPER(ap_glTexCoordFormatNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTexCoordFormatNV, 3, OS_TOBJ_ID_GL_INT_PARAMETER, size, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_SIZEI_PARAMETER, stride);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glTexCoordFormatNV, (size, type, stride));

    SU_END_FUNCTION_WRAPPER(ap_glTexCoordFormatNV);
}

void APIENTRY glEdgeFlagFormatNV(GLsizei stride)
{
    SU_START_FUNCTION_WRAPPER(ap_glEdgeFlagFormatNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glEdgeFlagFormatNV, 1, OS_TOBJ_ID_GL_SIZEI_PARAMETER, stride);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glEdgeFlagFormatNV, (stride));

    SU_END_FUNCTION_WRAPPER(ap_glEdgeFlagFormatNV);
}

void APIENTRY glSecondaryColorFormatNV(GLint size, GLenum type, GLsizei stride)
{
    SU_START_FUNCTION_WRAPPER(ap_glSecondaryColorFormatNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glSecondaryColorFormatNV, 3, OS_TOBJ_ID_GL_INT_PARAMETER, size, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_SIZEI_PARAMETER, stride);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glSecondaryColorFormatNV, (size, type, stride));

    SU_END_FUNCTION_WRAPPER(ap_glSecondaryColorFormatNV);
}

void APIENTRY glFogCoordFormatNV(GLenum type, GLsizei stride)
{
    SU_START_FUNCTION_WRAPPER(ap_glFogCoordFormatNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glFogCoordFormatNV, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_SIZEI_PARAMETER, stride);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glFogCoordFormatNV, (type, stride));

    SU_END_FUNCTION_WRAPPER(ap_glFogCoordFormatNV);
}

void APIENTRY glVertexAttribFormatNV(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride)
{
    SU_START_FUNCTION_WRAPPER(ap_glVertexAttribFormatNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttribFormatNV, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_INT_PARAMETER, size, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_BOOL_PARAMETER, normalized, OS_TOBJ_ID_GL_SIZEI_PARAMETER, stride);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttribFormatNV, (index, size, type, normalized, stride));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttribFormatNV);
}

void APIENTRY glVertexAttribIFormatNV(GLuint index, GLint size, GLenum type, GLsizei stride)
{
    SU_START_FUNCTION_WRAPPER(ap_glVertexAttribIFormatNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttribIFormatNV, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_INT_PARAMETER, size, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_SIZEI_PARAMETER, stride);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttribIFormatNV, (index, size, type, stride));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttribIFormatNV);
}

void APIENTRY glGetIntegerui64i_vNV(GLenum value, GLuint index, GLuint64EXT* result)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetIntegerui64i_vNV);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetIntegerui64i_vNV, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, value, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_P_UINT_64_PARAMETER, result);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetIntegerui64i_vNV, (value, index, result));

    SU_END_FUNCTION_WRAPPER(ap_glGetIntegerui64i_vNV);
}

//////////////////////////////////////////////////////////////////////////
// GL_AMD_debug_output
//////////////////////////////////////////////////////////////////////////
void APIENTRY glDebugMessageEnableAMD(GLenum category, GLenum severity, GLsizei count, const GLuint* ids, GLboolean enabled)
{
    SU_START_FUNCTION_WRAPPER(ap_glDebugMessageEnableAMD);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glDebugMessageEnableAMD, 5, OS_TOBJ_ID_GL_ENUM_PARAMETER, category, OS_TOBJ_ID_GL_ENUM_PARAMETER, severity, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_P_UINT_PARAMETER, ids, OS_TOBJ_ID_GL_BOOL_PARAMETER, enabled);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glDebugMessageEnableAMD, (category, severity, count, ids, enabled));

    SU_END_FUNCTION_WRAPPER(ap_glDebugMessageEnableAMD);
}

void APIENTRY glDebugMessageInsertAMD(GLenum category, GLenum severity, GLuint id, GLsizei length, const GLchar* buf)
{
    SU_START_FUNCTION_WRAPPER(ap_glDebugMessageInsertAMD);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glDebugMessageInsertAMD, 5, OS_TOBJ_ID_GL_ENUM_PARAMETER, category, OS_TOBJ_ID_GL_ENUM_PARAMETER, severity, OS_TOBJ_ID_GL_UINT_PARAMETER, id, OS_TOBJ_ID_GL_SIZEI_PARAMETER, length, OS_TOBJ_ID_GL_STRING_PARAMETER, length, buf);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glDebugMessageInsertAMD, (category, severity, id, length, buf));

    SU_END_FUNCTION_WRAPPER(ap_glDebugMessageInsertAMD);
}

void APIENTRY glDebugMessageCallbackAMD(GLDEBUGPROCAMD callback, GLvoid* userParam)
{
    SU_START_FUNCTION_WRAPPER(ap_glDebugMessageCallbackAMD);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glDebugMessageCallbackAMD, 2, OS_TOBJ_ID_GL_P_VOID_PARAMETER, callback, OS_TOBJ_ID_GL_P_VOID_PARAMETER, userParam);

#if (AMDT_BUILD_TARGET == AMDT_WINDOWS_OS) || ((AMDT_BUILD_TARGET == AMDT_LINUX_OS) && (AMDT_LINUX_VARIANT == AMDT_GENERIC_LINUX_VARIANT))

    // NOTICE: Sigal 13/6/10
    // We do not call the real function, since we override the callback with our implementation.
    // We set the function callback and call it ourselves:
    // Call the real function:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        pCurrentThreadRenderContextMonitor->debugOutputManager().onAMDUserCallbackSet(callback, userParam);
    }
    else
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glDebugMessageCallbackAMD, (callback, userParam));
    }

#else

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glDebugMessageCallbackAMD, (callback, userParam));

#endif

    SU_END_FUNCTION_WRAPPER(ap_glDebugMessageCallbackAMD);
}

GLuint APIENTRY glGetDebugMessageLogAMD(GLuint count, GLsizei bufsize, GLenum* categories, GLuint* severities, GLuint* ids, GLsizei* lengths, GLchar* message)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetDebugMessageLogAMD);

    GLuint retVal = 0;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetDebugMessageLogAMD, 7, OS_TOBJ_ID_GL_UINT_PARAMETER, count, OS_TOBJ_ID_GL_SIZEI_PARAMETER, bufsize, OS_TOBJ_ID_GL_P_ENUM_PARAMETER, categories, OS_TOBJ_ID_GL_P_UINT_PARAMETER, severities, OS_TOBJ_ID_GL_P_UINT_PARAMETER, ids, OS_TOBJ_ID_GL_P_SIZEI_PARAMETER, lengths, OS_TOBJ_ID_GL_P_CHAR, message);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glGetDebugMessageLogAMD, (count, bufsize, categories, severities, ids, lengths, message), retVal);

    SU_END_FUNCTION_WRAPPER(ap_glGetDebugMessageLogAMD);

    return retVal;
}


//////////////////////////////////////////////////////////////////////////
// GL_AMDX_debug_output
//////////////////////////////////////////////////////////////////////////
void APIENTRY glDebugMessageEnableAMDX(GLenum category, GLenum severity, GLsizei count, const GLuint* ids, GLboolean enabled)
{
    SU_START_FUNCTION_WRAPPER(ap_glDebugMessageEnableAMDX);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glDebugMessageEnableAMDX, 5, OS_TOBJ_ID_GL_ENUM_PARAMETER, category, OS_TOBJ_ID_GL_ENUM_PARAMETER, severity, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_P_UINT_PARAMETER, ids, OS_TOBJ_ID_GL_BOOL_PARAMETER, enabled);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glDebugMessageEnableAMDX, (category, severity, count, ids, enabled));

    SU_END_FUNCTION_WRAPPER(ap_glDebugMessageEnableAMDX);
}

void APIENTRY glDebugMessageInsertAMDX(GLenum category, GLenum severity, GLuint id, GLsizei length, const GLchar* buf)
{
    SU_START_FUNCTION_WRAPPER(ap_glDebugMessageInsertAMDX);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glDebugMessageInsertAMDX, 5, OS_TOBJ_ID_GL_ENUM_PARAMETER, category, OS_TOBJ_ID_GL_ENUM_PARAMETER, severity, OS_TOBJ_ID_GL_UINT_PARAMETER, id, OS_TOBJ_ID_GL_SIZEI_PARAMETER, length, OS_TOBJ_ID_GL_STRING_PARAMETER, length, buf);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glDebugMessageInsertAMDX, (category, severity, id, length, buf));

    SU_END_FUNCTION_WRAPPER(ap_glDebugMessageInsertAMDX);
}

void APIENTRY glDebugMessageCallbackAMDX(GLDEBUGPROCAMD callback, GLvoid* userParam)
{
    SU_START_FUNCTION_WRAPPER(ap_glDebugMessageCallbackAMDX);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glDebugMessageCallbackAMDX, 2, OS_TOBJ_ID_GL_P_VOID_PARAMETER, callback, OS_TOBJ_ID_GL_P_VOID_PARAMETER, userParam);

#if (AMDT_BUILD_TARGET == AMDT_WINDOWS_OS) || ((AMDT_BUILD_TARGET == AMDT_LINUX_OS) && (AMDT_LINUX_VARIANT == AMDT_GENERIC_LINUX_VARIANT))

    // NOTICE: Sigal 13/6/10
    // We do not call the real function, since we override the callback with our implementation.
    // We set the function callback and call it ourselves:
    // Call the real function:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        pCurrentThreadRenderContextMonitor->debugOutputManager().onAMDUserCallbackSet(callback, userParam);
    }
    else
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glDebugMessageCallbackAMDX, (callback, userParam));
    }

#else

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glDebugMessageCallbackAMDX, (callback, userParam));

#endif

    SU_END_FUNCTION_WRAPPER(ap_glDebugMessageCallbackAMDX);
}

GLuint APIENTRY glGetDebugMessageLogAMDX(GLuint count, GLsizei bufsize, GLenum* categories, GLuint* severities, GLuint* ids, GLsizei* lengths, GLchar* message)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetDebugMessageLogAMDX);

    GLuint retVal = 0;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetDebugMessageLogAMDX, 7, OS_TOBJ_ID_GL_UINT_PARAMETER, count, OS_TOBJ_ID_GL_SIZEI_PARAMETER, bufsize, OS_TOBJ_ID_GL_P_ENUM_PARAMETER, categories, OS_TOBJ_ID_GL_P_UINT_PARAMETER, severities, OS_TOBJ_ID_GL_P_UINT_PARAMETER, ids, OS_TOBJ_ID_GL_P_SIZEI_PARAMETER, lengths, OS_TOBJ_ID_GL_P_CHAR, message);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glGetDebugMessageLogAMDX, (count, bufsize, categories, severities, ids, lengths, message), retVal);

    SU_END_FUNCTION_WRAPPER(ap_glGetDebugMessageLogAMDX);

    return retVal;
}

//////////////////////////////////////////////////////////////////////////
// GL_ARB_debug_output
//////////////////////////////////////////////////////////////////////////
void APIENTRY glDebugMessageControlARB(GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint* ids, GLboolean enabled)
{
    SU_START_FUNCTION_WRAPPER(ap_glDebugMessageControlARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glDebugMessageControlARB, 6, OS_TOBJ_ID_GL_ENUM_PARAMETER, source, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_ENUM_PARAMETER, severity, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_P_UINT_PARAMETER, ids, OS_TOBJ_ID_GL_BOOL_PARAMETER, enabled);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glDebugMessageControlARB, (source, type, severity, count, ids, enabled));

    SU_END_FUNCTION_WRAPPER(ap_glDebugMessageControlARB);
}

void APIENTRY glDebugMessageInsertARB(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* buf)
{
    SU_START_FUNCTION_WRAPPER(ap_glDebugMessageInsertARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glDebugMessageInsertARB, 6, OS_TOBJ_ID_GL_ENUM_PARAMETER, source, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_UINT_PARAMETER, id, OS_TOBJ_ID_GL_ENUM_PARAMETER, severity, OS_TOBJ_ID_GL_SIZEI_PARAMETER, length, OS_TOBJ_ID_GL_STRING_PARAMETER, length, buf);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glDebugMessageInsertARB, (source, type, id, severity, length, buf));

    SU_END_FUNCTION_WRAPPER(ap_glDebugMessageInsertARB);
}

void APIENTRY glDebugMessageCallbackARB(GLDEBUGPROCARB callback, const GLvoid* userParam)
{
    SU_START_FUNCTION_WRAPPER(ap_glDebugMessageCallbackARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glDebugMessageCallbackARB, 2, OS_TOBJ_ID_GL_P_VOID_PARAMETER, callback, OS_TOBJ_ID_GL_P_VOID_PARAMETER, userParam);

#if (AMDT_BUILD_TARGET == AMDT_WINDOWS_OS) || ((AMDT_BUILD_TARGET == AMDT_LINUX_OS) && (AMDT_LINUX_VARIANT == AMDT_GENERIC_LINUX_VARIANT))

    // NOTICE: Sigal 13/6/10
    // We do not call the real function, since we override the callback with our implementation.
    // We set the function callback and call it ourselves:
    // Call the real function:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        pCurrentThreadRenderContextMonitor->debugOutputManager().onARBUserCallbackSet(callback, (GLvoid*)userParam);
    }
    else
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glDebugMessageCallbackARB, (callback, userParam));
    }

#else

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glDebugMessageCallbackARB, (callback, userParam));

#endif

    SU_END_FUNCTION_WRAPPER(ap_glDebugMessageCallbackARB);
}

GLuint APIENTRY glGetDebugMessageLogARB(GLuint count, GLsizei bufsize, GLenum* sources, GLenum* types, GLuint* ids, GLuint* severities, GLsizei* lengths, GLchar* messageLog)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetDebugMessageLogARB);

    GLuint retVal = 0;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetDebugMessageLogARB, 8, OS_TOBJ_ID_GL_UINT_PARAMETER, count, OS_TOBJ_ID_GL_SIZEI_PARAMETER, bufsize, OS_TOBJ_ID_GL_P_ENUM_PARAMETER, sources, OS_TOBJ_ID_GL_P_ENUM_PARAMETER, types, OS_TOBJ_ID_GL_P_UINT_PARAMETER, ids, OS_TOBJ_ID_GL_P_UINT_PARAMETER, severities, OS_TOBJ_ID_GL_P_SIZEI_PARAMETER, lengths, OS_TOBJ_ID_GL_P_CHAR, messageLog);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glGetDebugMessageLogARB, (count, bufsize, sources, types, ids, severities, lengths, messageLog), retVal);

    SU_END_FUNCTION_WRAPPER(ap_glGetDebugMessageLogARB);

    return retVal;
}

//////////////////////////////////////////////////////////////////////////
// GL_EXT_draw_instanced
//////////////////////////////////////////////////////////////////////////
void APIENTRY glDrawArraysInstancedEXT(GLenum mode, GLint first, GLsizei count, GLsizei primcount)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glDrawArraysInstancedEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glDrawArraysInstancedEXT, 4, OS_TOBJ_ID_GL_PRIMITIVE_TYPE_PARAMETER, mode, OS_TOBJ_ID_GL_INT_PARAMETER, first, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_SIZEI_PARAMETER, primcount);

    // Get the current render context monitor:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (pCurrentThreadRenderContextMonitor != NULL)
    {
        // Get the render primitives statistics logger:
        gsRenderPrimitivesStatisticsLogger& renderPrimitivesStatisticsLogger = pCurrentThreadRenderContextMonitor->renderPrimitivesStatisticsLogger();

        // Log this draw primitives function call:
        renderPrimitivesStatisticsLogger.onDrawArraysInstanced(count, primcount, mode);
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glDrawArraysInstancedEXT, (mode, first, count, primcount));

    SU_END_FUNCTION_WRAPPER(ap_glDrawArraysInstancedEXT);
}

void APIENTRY glDrawElementsInstancedEXT(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices, GLsizei primcount)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glDrawElementsInstancedEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glDrawElementsInstancedEXT, 5, OS_TOBJ_ID_GL_PRIMITIVE_TYPE_PARAMETER, mode, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_POINTER_PARAMETER, indices, OS_TOBJ_ID_GL_SIZEI_PARAMETER, primcount);

    // Get the current render context monitor:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (pCurrentThreadRenderContextMonitor != NULL)
    {
        // Get the render primitives statistics logger:
        gsRenderPrimitivesStatisticsLogger& renderPrimitivesStatisticsLogger = pCurrentThreadRenderContextMonitor->renderPrimitivesStatisticsLogger();

        // Log this draw primitives function call:
        renderPrimitivesStatisticsLogger.onDrawElementsInstanced(count, mode, type, primcount);
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glDrawElementsInstancedEXT, (mode, count, type, indices, primcount));

    SU_END_FUNCTION_WRAPPER(ap_glDrawElementsInstancedEXT);
}

//////////////////////////////////////////////////////////////////////////
// GL_ARB_draw_instanced
//////////////////////////////////////////////////////////////////////////
void APIENTRY glDrawArraysInstancedARB(GLenum mode, GLint first, GLsizei count, GLsizei primcount)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glDrawArraysInstancedARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glDrawArraysInstancedARB, 4, OS_TOBJ_ID_GL_PRIMITIVE_TYPE_PARAMETER, mode, OS_TOBJ_ID_GL_INT_PARAMETER, first, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_SIZEI_PARAMETER, primcount);

    // Get the current render context monitor:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (pCurrentThreadRenderContextMonitor != NULL)
    {
        // Get the render primitives statistics logger:
        gsRenderPrimitivesStatisticsLogger& renderPrimitivesStatisticsLogger = pCurrentThreadRenderContextMonitor->renderPrimitivesStatisticsLogger();

        // Log this draw primitives function call:
        renderPrimitivesStatisticsLogger.onDrawArraysInstanced(count, primcount, mode);
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glDrawArraysInstancedARB, (mode, first, count, primcount));

    SU_END_FUNCTION_WRAPPER(ap_glDrawArraysInstancedARB);
}

void APIENTRY glDrawElementsInstancedARB(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices, GLsizei primcount)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glDrawElementsInstancedARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glDrawElementsInstancedARB, 5, OS_TOBJ_ID_GL_PRIMITIVE_TYPE_PARAMETER, mode, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_POINTER_PARAMETER, indices, OS_TOBJ_ID_GL_SIZEI_PARAMETER, primcount);

    // Get the current render context monitor:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (pCurrentThreadRenderContextMonitor != NULL)
    {
        // Get the render primitives statistics logger:
        gsRenderPrimitivesStatisticsLogger& renderPrimitivesStatisticsLogger = pCurrentThreadRenderContextMonitor->renderPrimitivesStatisticsLogger();

        // Log this draw primitives function call:
        renderPrimitivesStatisticsLogger.onDrawElementsInstanced(count, mode, type, primcount);
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glDrawElementsInstancedARB, (mode, count, type, indices, primcount));

    SU_END_FUNCTION_WRAPPER(ap_glDrawElementsInstancedARB);
}

//////////////////////////////////////////////////////////////////////////
// GL_EXT_compiled_vertex_array
//////////////////////////////////////////////////////////////////////////
void APIENTRY glLockArraysEXT(GLint first, GLsizei count)
{
    SU_START_FUNCTION_WRAPPER(ap_glLockArraysEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glLockArraysEXT, 2, OS_TOBJ_ID_GL_INT_PARAMETER, first, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glLockArraysEXT, (first, count));

    SU_END_FUNCTION_WRAPPER(ap_glLockArraysEXT);
}

void APIENTRY glUnlockArraysEXT(void)
{
    SU_START_FUNCTION_WRAPPER(ap_glUnlockArraysEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glUnlockArraysEXT, 0);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glUnlockArraysEXT, ());

    SU_END_FUNCTION_WRAPPER(ap_glUnlockArraysEXT);
}

//////////////////////////////////////////////////////////////////////////
// GL_ARB_transpose_matrix
//////////////////////////////////////////////////////////////////////////
void APIENTRY glLoadTransposeMatrixfARB(const GLfloat* m)
{
    SU_START_FUNCTION_WRAPPER(ap_glLoadTransposeMatrixfARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glLoadTransposeMatrixfARB, 1, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, m);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glLoadTransposeMatrixfARB, (m));

    SU_END_FUNCTION_WRAPPER(ap_glLoadTransposeMatrixfARB);
}

void APIENTRY glLoadTransposeMatrixdARB(const GLdouble* m)
{
    SU_START_FUNCTION_WRAPPER(ap_glLoadTransposeMatrixdARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glLoadTransposeMatrixdARB, 1, OS_TOBJ_ID_GL_P_DOUBLE_PARAMETER, m);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glLoadTransposeMatrixdARB, (m));

    SU_END_FUNCTION_WRAPPER(ap_glLoadTransposeMatrixdARB);
}

void APIENTRY glMultTransposeMatrixfARB(const GLfloat* m)
{
    SU_START_FUNCTION_WRAPPER(ap_glMultTransposeMatrixfARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultTransposeMatrixfARB, 1, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, m);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultTransposeMatrixfARB, (m));

    SU_END_FUNCTION_WRAPPER(ap_glMultTransposeMatrixfARB);
}

void APIENTRY glMultTransposeMatrixdARB(const GLdouble* m)
{
    SU_START_FUNCTION_WRAPPER(ap_glMultTransposeMatrixdARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultTransposeMatrixdARB, 1, OS_TOBJ_ID_GL_P_DOUBLE_PARAMETER, m);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultTransposeMatrixdARB, (m));

    SU_END_FUNCTION_WRAPPER(ap_glMultTransposeMatrixdARB);
}

//////////////////////////////////////////////////////////////////////////
// GL_ARB_point_parameters
//////////////////////////////////////////////////////////////////////////
void APIENTRY glPointParameterfARB(GLenum pname, GLfloat param)
{
    SU_START_FUNCTION_WRAPPER(ap_glPointParameterfARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glPointParameterfARB, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_FLOAT_PARAMETER, param);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glPointParameterfARB, (pname, param));

    SU_END_FUNCTION_WRAPPER(ap_glPointParameterfARB);
}

void APIENTRY glPointParameterfvARB(GLenum pname, const GLfloat* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glPointParameterfvARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glPointParameterfvARB, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glPointParameterfvARB, (pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glPointParameterfvARB);
}

//////////////////////////////////////////////////////////////////////////
// GL_ARB_matrix_palette
//////////////////////////////////////////////////////////////////////////
void APIENTRY glCurrentPaletteMatrixARB(GLint index)
{
    SU_START_FUNCTION_WRAPPER(ap_glCurrentPaletteMatrixARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glCurrentPaletteMatrixARB, 1, OS_TOBJ_ID_GL_INT_PARAMETER, index);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glCurrentPaletteMatrixARB, (index));

    SU_END_FUNCTION_WRAPPER(ap_glCurrentPaletteMatrixARB);
}

void APIENTRY glMatrixIndexubvARB(GLint size, const GLubyte* indices)
{
    SU_START_FUNCTION_WRAPPER(ap_glMatrixIndexubvARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMatrixIndexubvARB, 2, OS_TOBJ_ID_GL_INT_PARAMETER, size, OS_TOBJ_ID_GL_P_UBYTE_PARAMETER, indices);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMatrixIndexubvARB, (size, indices));

    SU_END_FUNCTION_WRAPPER(ap_glMatrixIndexubvARB);
}

void APIENTRY glMatrixIndexusvARB(GLint size, const GLushort* indices)
{
    SU_START_FUNCTION_WRAPPER(ap_glMatrixIndexusvARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMatrixIndexusvARB, 2, OS_TOBJ_ID_GL_INT_PARAMETER, size, OS_TOBJ_ID_GL_P_USHORT_PARAMETER, indices);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMatrixIndexusvARB, (size, indices));

    SU_END_FUNCTION_WRAPPER(ap_glMatrixIndexusvARB);
}

void APIENTRY glMatrixIndexuivARB(GLint size, const GLuint* indices)
{
    SU_START_FUNCTION_WRAPPER(ap_glMatrixIndexuivARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMatrixIndexuivARB, 2, OS_TOBJ_ID_GL_INT_PARAMETER, size, OS_TOBJ_ID_GL_P_UINT_PARAMETER, indices);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMatrixIndexuivARB, (size, indices));

    SU_END_FUNCTION_WRAPPER(ap_glMatrixIndexuivARB);
}

void APIENTRY glMatrixIndexPointerARB(GLint size, GLenum type, GLsizei stride, const GLvoid* pointer)
{
    SU_START_FUNCTION_WRAPPER(ap_glMatrixIndexPointerARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMatrixIndexPointerARB, 4, OS_TOBJ_ID_GL_INT_PARAMETER, size, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_SIZEI_PARAMETER, stride, OS_TOBJ_ID_GL_P_VOID_PARAMETER, pointer);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMatrixIndexPointerARB, (size, type, stride, pointer));

    SU_END_FUNCTION_WRAPPER(ap_glMatrixIndexPointerARB);
}

//////////////////////////////////////////////////////////////////////////
// GL_ARB_window_pos
//////////////////////////////////////////////////////////////////////////
void APIENTRY glWindowPos2dARB(GLdouble x, GLdouble y)
{
    SU_START_FUNCTION_WRAPPER(ap_glWindowPos2dARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glWindowPos2dARB, 2, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, x, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, y);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glWindowPos2dARB, (x, y));

    SU_END_FUNCTION_WRAPPER(ap_glWindowPos2dARB);
}

void APIENTRY glWindowPos2fARB(GLfloat x, GLfloat y)
{
    SU_START_FUNCTION_WRAPPER(ap_glWindowPos2fARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glWindowPos2fARB, 2, OS_TOBJ_ID_GL_FLOAT_PARAMETER, x, OS_TOBJ_ID_GL_FLOAT_PARAMETER, y);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glWindowPos2fARB, (x, y));

    SU_END_FUNCTION_WRAPPER(ap_glWindowPos2fARB);
}

void APIENTRY glWindowPos2iARB(GLint x, GLint y)
{
    SU_START_FUNCTION_WRAPPER(ap_glWindowPos2iARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glWindowPos2iARB, 2, OS_TOBJ_ID_GL_INT_PARAMETER, x, OS_TOBJ_ID_GL_INT_PARAMETER, y);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glWindowPos2iARB, (x, y));

    SU_END_FUNCTION_WRAPPER(ap_glWindowPos2iARB);
}

void APIENTRY glWindowPos2sARB(GLshort x, GLshort y)
{
    SU_START_FUNCTION_WRAPPER(ap_glWindowPos2sARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glWindowPos2sARB, 2, OS_TOBJ_ID_GL_SHORT_PARAMETER, x, OS_TOBJ_ID_GL_SHORT_PARAMETER, y);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glWindowPos2sARB, (x, y));

    SU_END_FUNCTION_WRAPPER(ap_glWindowPos2sARB);
}

void APIENTRY glWindowPos2dvARB(const GLdouble* p)
{
    SU_START_FUNCTION_WRAPPER(ap_glWindowPos2dvARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glWindowPos2dvARB, 1, OS_TOBJ_ID_GL_P_DOUBLE_PARAMETER, p);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glWindowPos2dvARB, (p));

    SU_END_FUNCTION_WRAPPER(ap_glWindowPos2dvARB);
}

void APIENTRY glWindowPos2fvARB(const GLfloat* p)
{
    SU_START_FUNCTION_WRAPPER(ap_glWindowPos2fvARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glWindowPos2fvARB, 1, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, p);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glWindowPos2fvARB, (p));

    SU_END_FUNCTION_WRAPPER(ap_glWindowPos2fvARB);
}

void APIENTRY glWindowPos2ivARB(const GLint* p)
{
    SU_START_FUNCTION_WRAPPER(ap_glWindowPos2ivARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glWindowPos2ivARB, 1, OS_TOBJ_ID_GL_P_INT_PARAMETER, p);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glWindowPos2ivARB, (p));

    SU_END_FUNCTION_WRAPPER(ap_glWindowPos2ivARB);
}

void APIENTRY glWindowPos2svARB(const GLshort* p)
{
    SU_START_FUNCTION_WRAPPER(ap_glWindowPos2svARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glWindowPos2svARB, 1, OS_TOBJ_ID_GL_P_SHORT_PARAMETER, p);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glWindowPos2svARB, (p));

    SU_END_FUNCTION_WRAPPER(ap_glWindowPos2svARB);
}

void APIENTRY glWindowPos3dARB(GLdouble x, GLdouble y, GLdouble z)
{
    SU_START_FUNCTION_WRAPPER(ap_glWindowPos3dARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glWindowPos3dARB, 3, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, x, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, y, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, z);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glWindowPos3dARB, (x, y, z));

    SU_END_FUNCTION_WRAPPER(ap_glWindowPos3dARB);
}

void APIENTRY glWindowPos3fARB(GLfloat x, GLfloat y, GLfloat z)
{
    SU_START_FUNCTION_WRAPPER(ap_glWindowPos3fARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glWindowPos3fARB, 3, OS_TOBJ_ID_GL_FLOAT_PARAMETER, x, OS_TOBJ_ID_GL_FLOAT_PARAMETER, y, OS_TOBJ_ID_GL_FLOAT_PARAMETER, z);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glWindowPos3fARB, (x, y, z));

    SU_END_FUNCTION_WRAPPER(ap_glWindowPos3fARB);
}

void APIENTRY glWindowPos3iARB(GLint x, GLint y, GLint z)
{
    SU_START_FUNCTION_WRAPPER(ap_glWindowPos3iARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glWindowPos3iARB, 3, OS_TOBJ_ID_GL_INT_PARAMETER, x, OS_TOBJ_ID_GL_INT_PARAMETER, y, OS_TOBJ_ID_GL_INT_PARAMETER, z);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glWindowPos3iARB, (x, y, z));

    SU_END_FUNCTION_WRAPPER(ap_glWindowPos3iARB);
}

void APIENTRY glWindowPos3sARB(GLshort x, GLshort y, GLshort z)
{
    SU_START_FUNCTION_WRAPPER(ap_glWindowPos3sARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glWindowPos3sARB, 3, OS_TOBJ_ID_GL_SHORT_PARAMETER, x, OS_TOBJ_ID_GL_SHORT_PARAMETER, y, OS_TOBJ_ID_GL_SHORT_PARAMETER, z);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glWindowPos3sARB, (x, y, z));

    SU_END_FUNCTION_WRAPPER(ap_glWindowPos3sARB);
}

void APIENTRY glWindowPos3dvARB(const GLdouble* p)
{
    SU_START_FUNCTION_WRAPPER(ap_glWindowPos3dvARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glWindowPos3dvARB, 1, OS_TOBJ_ID_GL_P_DOUBLE_PARAMETER, p);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glWindowPos3dvARB, (p));

    SU_END_FUNCTION_WRAPPER(ap_glWindowPos3dvARB);
}

void APIENTRY glWindowPos3fvARB(const GLfloat* p)
{
    SU_START_FUNCTION_WRAPPER(ap_glWindowPos3fvARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glWindowPos3fvARB, 1, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, p);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glWindowPos3fvARB, (p));

    SU_END_FUNCTION_WRAPPER(ap_glWindowPos3fvARB);
}

void APIENTRY glWindowPos3ivARB(const GLint* p)
{
    SU_START_FUNCTION_WRAPPER(ap_glWindowPos3ivARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glWindowPos3ivARB, 1, OS_TOBJ_ID_GL_P_INT_PARAMETER, p);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glWindowPos3ivARB, (p));

    SU_END_FUNCTION_WRAPPER(ap_glWindowPos3ivARB);
}

void APIENTRY glWindowPos3svARB(const GLshort* p)
{
    SU_START_FUNCTION_WRAPPER(ap_glWindowPos3svARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glWindowPos3svARB, 1, OS_TOBJ_ID_GL_P_SHORT_PARAMETER, p);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glWindowPos3svARB, (p));

    SU_END_FUNCTION_WRAPPER(ap_glWindowPos3svARB);
}

//////////////////////////////////////////////////////////////////////////
// GL_ARB_fragment_program_shadow
//////////////////////////////////////////////////////////////////////////
// No new functions

//////////////////////////////////////////////////////////////////////////
// GL_ARB_half_float_pixel
//////////////////////////////////////////////////////////////////////////
// No new functions

//////////////////////////////////////////////////////////////////////////
// GL_ARB_texture_float
//////////////////////////////////////////////////////////////////////////
// No new functions

//////////////////////////////////////////////////////////////////////////
// GL_ARB_pixel_buffer_object
//////////////////////////////////////////////////////////////////////////
// No new functions

//////////////////////////////////////////////////////////////////////////
// GL_ARB_depth_buffer_float
//////////////////////////////////////////////////////////////////////////
// No new functions

//////////////////////////////////////////////////////////////////////////
// GL_ARB_framebuffer_sRGB
//////////////////////////////////////////////////////////////////////////
// No new functions

//////////////////////////////////////////////////////////////////////////
// GL_ARB_geometry_shader4
//////////////////////////////////////////////////////////////////////////
void APIENTRY glProgramParameteriARB(GLuint program, GLenum pname, GLint value)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramParameteriARB);

    // Log the call to this function:
    // If the second parameter is input or output primitives, log the third parameter as an enumerator:
    if ((pname == GL_GEOMETRY_INPUT_TYPE_ARB) || (pname == GL_GEOMETRY_OUTPUT_TYPE_ARB))
    {
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramParameteriARB, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_PRIMITIVE_TYPE_PARAMETER, value);
    }
    else
    {
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramParameteriARB, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_INT_PARAMETER, value);
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glProgramParameteriARB, (program, pname, value));

    // Log the parameter change:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (pCurrentThreadRenderContextMonitor != NULL)
    {
        gsProgramsAndShadersMonitor* progAndShaderMon = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(progAndShaderMon != NULL)
        {
            bool rc = progAndShaderMon->onProgramParameteri(program, pname, value);

            if (!rc)
            {
                if (!progAndShaderMon->isProgramObject(program))
                {
                    gtString errorDescription;
                    apErrorCode errorCode = AP_OBJECT_NAME_DOES_NOT_EXIST_ERROR;
                    errorDescription = GS_STR_usingNonObjectName;
                    errorDescription.appendFormattedString(L": (program name = %u)", program);
                    gs_stat_openGLMonitorInstance.reportDetectedError(errorCode, errorDescription, ap_glProgramParameteriARB);
                }
                else
                {
                    // Currently do nothing, since we could receive a pname of a parameter we don't want to log
                }
            }
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramParameteriARB);
}

void APIENTRY glFramebufferTextureARB(GLenum target, GLenum attachment, GLuint texture, GLint level)
{
    SU_START_FUNCTION_WRAPPER(ap_glFramebufferTextureARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glFramebufferTextureARB, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, attachment, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_INT_PARAMETER, level);

    // Get the RenderContextMonitor
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    // Construct a new apFBO for each of the generated frame buffer objects:
    GT_IF_WITH_ASSERT(pCurrentThreadRenderContextMonitor != NULL)
    {
        // Bind the texture to the active FBO:
        bool rcBindFBO = pCurrentThreadRenderContextMonitor->bindTextureToTheActiveFBO(target, GL_NONE, attachment, texture, 0);
        GT_ASSERT(rcBindFBO);
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glFramebufferTextureARB, (target, attachment, texture, level));

    SU_END_FUNCTION_WRAPPER(ap_glFramebufferTextureARB);
}

void APIENTRY glFramebufferTextureLayerARB(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer)
{
    SU_START_FUNCTION_WRAPPER(ap_glFramebufferTextureLayerARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glFramebufferTextureLayerARB, 5, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, attachment, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_INT_PARAMETER, layer);

    // Get the RenderContextMonitor:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    // Construct a new apFBO for each of the generated frame buffer objects:
    GT_IF_WITH_ASSERT(pCurrentThreadRenderContextMonitor != NULL)
    {
        // Bind the texture to the active FBO:
        bool rcBindFBO = pCurrentThreadRenderContextMonitor->bindTextureLayerToTheActiveFBO(target, GL_NONE, attachment, texture, layer);
        GT_ASSERT(rcBindFBO);
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glFramebufferTextureLayerARB, (target, attachment, texture, level, layer));

    SU_END_FUNCTION_WRAPPER(ap_glFramebufferTextureLayerARB);
}

void APIENTRY glFramebufferTextureFaceARB(GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face)
{
    SU_START_FUNCTION_WRAPPER(ap_glFramebufferTextureFaceARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glFramebufferTextureFaceARB, 5, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, attachment, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_ENUM_PARAMETER, face);

    // Get the RenderContextMonitor:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    // Construct a new apFBO for each of the generated frame buffer objects:
    GT_IF_WITH_ASSERT(pCurrentThreadRenderContextMonitor != NULL)
    {
        // Bind the texture to the active FBO:
        bool rcBindFBO = pCurrentThreadRenderContextMonitor->bindTextureToTheActiveFBO(target, GL_NONE, attachment, texture, face);
        GT_ASSERT(rcBindFBO);
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glFramebufferTextureFaceARB, (target, attachment, texture, level, face));

    SU_END_FUNCTION_WRAPPER(ap_glFramebufferTextureFaceARB);
}

//////////////////////////////////////////////////////////////////////////
// GL_ARB_half_float_vertex
//////////////////////////////////////////////////////////////////////////
// No new functions

//////////////////////////////////////////////////////////////////////////
// GL_ARB_instanced_arrays
//////////////////////////////////////////////////////////////////////////
void APIENTRY glVertexAttribDivisorARB(GLuint index, GLuint divisor)
{
    SU_START_FUNCTION_WRAPPER(ap_glVertexAttribDivisorARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexAttribDivisorARB, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_UINT_PARAMETER, divisor);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexAttribDivisorARB, (index, divisor));

    SU_END_FUNCTION_WRAPPER(ap_glVertexAttribDivisorARB);
}

//////////////////////////////////////////////////////////////////////////
// GL_ARB_map_buffer_range
//////////////////////////////////////////////////////////////////////////
GLvoid* APIENTRY glMapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access)
{
    SU_START_FUNCTION_WRAPPER(ap_glMapBufferRange);

    GLvoid* retVal = NULL;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMapBufferRange, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_INTPTR_PARAMETER, offset, OS_TOBJ_ID_GL_SIZEIPTR_PARAMETER, length, OS_TOBJ_ID_GL_BITFIELD_PARAMETER, access);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glMapBufferRange, (target, offset, length, access), retVal);

    SU_END_FUNCTION_WRAPPER(ap_glMapBufferRange);

    return retVal;
}

void APIENTRY glFlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeiptr length)
{
    SU_START_FUNCTION_WRAPPER(ap_glFlushMappedBufferRange);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glFlushMappedBufferRange, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_INTPTR_PARAMETER, offset, OS_TOBJ_ID_GL_SIZEIPTR_PARAMETER, length);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glFlushMappedBufferRange, (target, offset, length));

    // Log the vbo data set:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        gsVBOMonitor* vboMonitor = pCurrentThreadRenderContextMonitor->vboMonitor();
        GT_IF_WITH_ASSERT(vboMonitor != NULL)
        {
            vboMonitor->onVertexBufferObjectSubDataSet(target);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glFlushMappedBufferRange);
}

//////////////////////////////////////////////////////////////////////////
// GL_ARB_texture_buffer_object
//////////////////////////////////////////////////////////////////////////
void APIENTRY glTexBufferARB(GLenum target, GLenum internalformat, GLuint buffer)
{
    SU_START_FUNCTION_WRAPPER(ap_glTexBufferARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTexBufferARB, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, internalformat, OS_TOBJ_ID_GL_UINT_PARAMETER, buffer);

    // Log the textures buffer attachment:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        pCurrentThreadRenderContextMonitor->onTextureBuffer(target, internalformat, buffer);
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glTexBufferARB, (target, internalformat, buffer));

    SU_END_FUNCTION_WRAPPER(ap_glTexBufferARB);
}

//////////////////////////////////////////////////////////////////////////
// GL_EXT_texture_buffer_object
//////////////////////////////////////////////////////////////////////////
void APIENTRY glTexBufferEXT(GLenum target, GLenum internalformat, GLuint buffer)
{
    SU_START_FUNCTION_WRAPPER(ap_glTexBufferEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTexBufferEXT, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, internalformat, OS_TOBJ_ID_GL_UINT_PARAMETER, buffer);

    // Log the textures buffer attachment:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        pCurrentThreadRenderContextMonitor->onTextureBuffer(target, internalformat, buffer);
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glTexBufferEXT, (target, internalformat, buffer));

    SU_END_FUNCTION_WRAPPER(ap_glTexBufferEXT);
}

//////////////////////////////////////////////////////////////////////////
// GL_ARB_texture_compression_rgtc
//////////////////////////////////////////////////////////////////////////
// No new functions

//////////////////////////////////////////////////////////////////////////
// GL_ARB_texture_rg
//////////////////////////////////////////////////////////////////////////
// No new functions

//////////////////////////////////////////////////////////////////////////
// GL_ARB_vertex_array_object
//////////////////////////////////////////////////////////////////////////
void APIENTRY glBindVertexArray(GLuint array)
{
    SU_START_FUNCTION_WRAPPER(ap_glBindVertexArray);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glBindVertexArray, 1, OS_TOBJ_ID_GL_UINT_PARAMETER, array);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glBindVertexArray, (array));

    SU_END_FUNCTION_WRAPPER(ap_glBindVertexArray);
}

void APIENTRY glDeleteVertexArrays(GLsizei n, const GLuint* arrays)
{
    SU_START_FUNCTION_WRAPPER(ap_glDeleteVertexArrays);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glDeleteVertexArrays, 2, OS_TOBJ_ID_GL_SIZEI_PARAMETER, n, OS_TOBJ_ID_GL_P_UINT_PARAMETER, arrays);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glDeleteVertexArrays, (n, arrays));

    SU_END_FUNCTION_WRAPPER(ap_glDeleteVertexArrays);
}

void APIENTRY glGenVertexArrays(GLsizei n, GLuint* arrays)
{
    SU_START_FUNCTION_WRAPPER(ap_glGenVertexArrays);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGenVertexArrays, 2, OS_TOBJ_ID_GL_SIZEI_PARAMETER, n, OS_TOBJ_ID_GL_P_UINT_PARAMETER, arrays);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGenVertexArrays, (n, arrays));

    SU_END_FUNCTION_WRAPPER(ap_glGenVertexArrays);
}

GLboolean APIENTRY glIsVertexArray(GLuint array)
{
    SU_START_FUNCTION_WRAPPER(ap_glIsVertexArray);

    GLboolean retVal = 0;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glIsVertexArray, 1, OS_TOBJ_ID_GL_UINT_PARAMETER, array);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glIsVertexArray, (array), retVal);

    SU_END_FUNCTION_WRAPPER(ap_glIsVertexArray);

    return retVal;
}

//////////////////////////////////////////////////////////////////////////
// GL_ARB_uniform_buffer_object
//////////////////////////////////////////////////////////////////////////
void APIENTRY glGetUniformIndices(GLuint program, GLsizei uniformCount, const GLchar* const* uniformNames, GLuint* uniformIndices)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetUniformIndices);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetUniformIndices, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_SIZEI_PARAMETER, uniformCount, OS_TOBJ_ID_GL_PP_CHAR, uniformNames, OS_TOBJ_ID_GL_P_UINT_PARAMETER, uniformIndices);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetUniformIndices, (program, uniformCount, uniformNames, uniformIndices));

    SU_END_FUNCTION_WRAPPER(ap_glGetUniformIndices);
}

void APIENTRY glGetActiveUniformsiv(GLuint program, GLsizei uniformCount, const GLuint* uniformIndices, GLenum pname, GLint* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetActiveUniformsiv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetActiveUniformsiv, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_SIZEI_PARAMETER, uniformCount, OS_TOBJ_ID_GL_P_UINT_PARAMETER, uniformIndices, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetActiveUniformsiv, (program, uniformCount, uniformIndices, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetActiveUniformsiv);
}

void APIENTRY glGetActiveUniformName(GLuint program, GLuint uniformIndex, GLsizei bufSize, GLsizei* length, GLchar* uniformName)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetActiveUniformName);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetActiveUniformName, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_UINT_PARAMETER, uniformIndex, OS_TOBJ_ID_GL_SIZEI_PARAMETER, bufSize, OS_TOBJ_ID_GL_P_SIZEI_PARAMETER, length, OS_TOBJ_ID_GL_P_CHAR, uniformName);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetActiveUniformName, (program, uniformIndex, bufSize, length, uniformName));

    SU_END_FUNCTION_WRAPPER(ap_glGetActiveUniformName);
}

GLuint APIENTRY glGetUniformBlockIndex(GLuint program, const GLchar* uniformBlockName)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetUniformBlockIndex);

    GLuint retVal = 0;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetUniformBlockIndex, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_P_CHAR, uniformBlockName);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glGetUniformBlockIndex, (program, uniformBlockName), retVal);

    SU_END_FUNCTION_WRAPPER(ap_glGetUniformBlockIndex);

    return retVal;
}

void APIENTRY glGetActiveUniformBlockiv(GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetActiveUniformBlockiv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetActiveUniformBlockiv, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_UINT_PARAMETER, uniformBlockIndex, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetActiveUniformBlockiv, (program, uniformBlockIndex, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetActiveUniformBlockiv);
}

void APIENTRY glGetActiveUniformBlockName(GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei* length, GLchar* uniformBlockName)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetActiveUniformBlockName);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetActiveUniformBlockName, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_UINT_PARAMETER, uniformBlockIndex, OS_TOBJ_ID_GL_SIZEI_PARAMETER, bufSize, OS_TOBJ_ID_GL_P_SIZEI_PARAMETER, length, OS_TOBJ_ID_GL_P_CHAR, uniformBlockName);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetActiveUniformBlockName, (program, uniformBlockIndex, bufSize, length, uniformBlockName));

    SU_END_FUNCTION_WRAPPER(ap_glGetActiveUniformBlockName);
}

void APIENTRY glUniformBlockBinding(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding)
{
    SU_START_FUNCTION_WRAPPER(ap_glUniformBlockBinding);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glUniformBlockBinding, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_UINT_PARAMETER, uniformBlockIndex, OS_TOBJ_ID_GL_UINT_PARAMETER, uniformBlockBinding);

    // Get the render context monitor:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        // Get the active uniforms manager:
        gsProgramsAndShadersMonitor* pProgramAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramAndShadersMonitor != NULL)
        {
            // Get the active uniforms monitor"
            gsActiveUniformsMonitor& activeUniformsMon = pProgramAndShadersMonitor->programsActiveUniformsMgr();

            // Set uniform block binding:
            activeUniformsMon.onUniformBlockBinding(program, uniformBlockIndex, uniformBlockBinding);
        }
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glUniformBlockBinding, (program, uniformBlockIndex, uniformBlockBinding));

    SU_END_FUNCTION_WRAPPER(ap_glUniformBlockBinding);
}

//////////////////////////////////////////////////////////////////////////
// GL_ARB_copy_buffer
//////////////////////////////////////////////////////////////////////////
void APIENTRY glCopyBufferSubData(GLenum readtarget, GLenum writetarget, GLintptr readoffset, GLintptr writeoffset, GLsizeiptr size)
{
    SU_START_FUNCTION_WRAPPER(ap_glCopyBufferSubData);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glCopyBufferSubData, 5, OS_TOBJ_ID_GL_ENUM_PARAMETER, readtarget, OS_TOBJ_ID_GL_ENUM_PARAMETER, writetarget, OS_TOBJ_ID_GL_INTPTR_PARAMETER, readoffset, OS_TOBJ_ID_GL_INTPTR_PARAMETER, writeoffset, OS_TOBJ_ID_GL_SIZEIPTR_PARAMETER, size);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glCopyBufferSubData, (readtarget, writetarget, readoffset, writeoffset, size));

    // Log the vbo data set:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        gsVBOMonitor* vboMonitor = pCurrentThreadRenderContextMonitor->vboMonitor();
        GT_IF_WITH_ASSERT(vboMonitor != NULL)
        {
            vboMonitor->onVertexBufferObjectSubDataSet(writetarget);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glCopyBufferSubData);
}


//////////////////////////////////////////////////////////////////////////
// GL_ARB_draw_elements_base_vertex
//////////////////////////////////////////////////////////////////////////
void APIENTRY glDrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices, GLint basevertex)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glDrawElementsBaseVertex);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glDrawElementsBaseVertex, 5, OS_TOBJ_ID_GL_PRIMITIVE_TYPE_PARAMETER, mode, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_P_VOID_PARAMETER, indices, OS_TOBJ_ID_GL_INT_PARAMETER, basevertex);

    // Get the current render context monitor:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (pCurrentThreadRenderContextMonitor != NULL)
    {
        // Get the render primitives statistics logger:
        gsRenderPrimitivesStatisticsLogger& renderPrimitivesStatisticsLogger = pCurrentThreadRenderContextMonitor->renderPrimitivesStatisticsLogger();

        // Log this draw primitives function call:
        renderPrimitivesStatisticsLogger.onDrawElements(count, mode, type);
    }

    // Non-OpenGL ES DLL - Just call the real function:
    SU_CALL_EXTENSION_FUNC(glDrawElementsBaseVertex, (mode, count, type, indices, basevertex));

    SU_END_FUNCTION_WRAPPER(ap_glDrawElementsBaseVertex);
}

void APIENTRY glDrawRangeElementsBaseVertex(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid* indices, GLint basevertex)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glDrawRangeElementsBaseVertex);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glDrawRangeElementsBaseVertex, 7, OS_TOBJ_ID_GL_PRIMITIVE_TYPE_PARAMETER, mode, OS_TOBJ_ID_GL_UINT_PARAMETER, start, OS_TOBJ_ID_GL_UINT_PARAMETER, end, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_P_VOID_PARAMETER, indices, OS_TOBJ_ID_GL_INT_PARAMETER, basevertex);

    // Get the current render context monitor:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (pCurrentThreadRenderContextMonitor != NULL)
    {
        // Get the render primitives statistics logger:
        gsRenderPrimitivesStatisticsLogger& renderPrimitivesStatisticsLogger = pCurrentThreadRenderContextMonitor->renderPrimitivesStatisticsLogger();

        // Log this draw primitives function call:
        renderPrimitivesStatisticsLogger.onDrawRangeElements(count, mode, type);
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glDrawRangeElementsBaseVertex, (mode, start, end, count, type, indices, basevertex));

    SU_END_FUNCTION_WRAPPER(ap_glDrawRangeElementsBaseVertex);
}

// TO_DO: OpenGL 3.2 Why don't we count the primitives drawn in drawElementsInstanced??
void APIENTRY glDrawElementsInstancedBaseVertex(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices, GLsizei primcount, GLint basevertex)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glDrawElementsInstancedBaseVertex);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glDrawElementsInstancedBaseVertex, 6, OS_TOBJ_ID_GL_PRIMITIVE_TYPE_PARAMETER, mode, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_POINTER_PARAMETER, indices, OS_TOBJ_ID_GL_SIZEI_PARAMETER, primcount, OS_TOBJ_ID_GL_INT_PARAMETER, basevertex);

    // Get the current render context monitor:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (pCurrentThreadRenderContextMonitor != NULL)
    {
        // Get the render primitives statistics logger:
        gsRenderPrimitivesStatisticsLogger& renderPrimitivesStatisticsLogger = pCurrentThreadRenderContextMonitor->renderPrimitivesStatisticsLogger();

        // Log this draw primitives function call:
        renderPrimitivesStatisticsLogger.onDrawElementsInstanced(count, mode, type, primcount);
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glDrawElementsInstancedBaseVertex, (mode, count, type, indices, primcount, basevertex));

    SU_END_FUNCTION_WRAPPER(ap_glDrawElementsInstancedBaseVertex);
}

void APIENTRY glMultiDrawElementsBaseVertex(GLenum mode, const GLsizei* count, GLenum type, const GLvoid* const* indices, GLsizei primcount, const GLint* basevertex)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glMultiDrawElementsBaseVertex);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiDrawElementsBaseVertex, 6, OS_TOBJ_ID_GL_PRIMITIVE_TYPE_PARAMETER, mode, OS_TOBJ_ID_GL_P_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_POINTER_PARAMETER, indices, OS_TOBJ_ID_GL_SIZEI_PARAMETER, primcount, OS_TOBJ_ID_GL_P_INT_PARAMETER, basevertex);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiDrawElementsBaseVertex, (mode, count, type, indices, primcount, basevertex));

    SU_END_FUNCTION_WRAPPER(ap_glMultiDrawElementsBaseVertex);
}

//////////////////////////////////////////////////////////////////////////
// GL_ARB_provoking_vertex
//////////////////////////////////////////////////////////////////////////
void APIENTRY glProvokingVertex(GLenum mode)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glProvokingVertex);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProvokingVertex, 1, OS_TOBJ_ID_GL_ENUM_PARAMETER, mode);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glProvokingVertex, (mode));

    SU_END_FUNCTION_WRAPPER(ap_glProvokingVertex);

}

//////////////////////////////////////////////////////////////////////////
// GL_ARB_sync
//////////////////////////////////////////////////////////////////////////
GLsync APIENTRY glFenceSync(GLenum condition, GLbitfield flags)
{
    SU_START_FUNCTION_WRAPPER(ap_glFenceSync);

    GLsync retVal = NULL;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glFenceSync, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, condition, OS_TOBJ_ID_GL_BITFIELD_PARAMETER, flags);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glFenceSync, (condition, flags), retVal);

    // Get the Sync objects monitor:
    gsSyncObjectsMonitor& syncObjectsMonitor = gs_stat_openGLMonitorInstance.syncObjectsMonitor();

    // Log the created sync object:
    syncObjectsMonitor.onSyncObjectCreation(retVal, condition);

    SU_END_FUNCTION_WRAPPER(ap_glFenceSync);

    return retVal;
}
GLboolean APIENTRY glIsSync(GLsync sync)
{
    SU_START_FUNCTION_WRAPPER(ap_glIsSync);

    GLboolean retVal = GL_FALSE;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glIsSync, 1, OS_TOBJ_ID_GL_SYNC_PARAMETER, sync);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glIsSync, (sync), retVal);

    SU_END_FUNCTION_WRAPPER(ap_glIsSync);

    return retVal;
}
void APIENTRY glDeleteSync(GLsync sync)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glDeleteSync);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glDeleteSync, 1, OS_TOBJ_ID_GL_SYNC_PARAMETER, sync);

    // Get the Sync objects monitor:
    gsSyncObjectsMonitor& syncObjectsMonitor = gs_stat_openGLMonitorInstance.syncObjectsMonitor();

    // Log the deleted sync object:
    syncObjectsMonitor.onSyncObjectDeletion(sync);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glDeleteSync, (sync));

    SU_END_FUNCTION_WRAPPER(ap_glDeleteSync);
}
GLenum APIENTRY glClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
{
    SU_START_FUNCTION_WRAPPER(ap_glClientWaitSync);

    GLenum retVal = GL_NONE;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glClientWaitSync, 3, OS_TOBJ_ID_GL_SYNC_PARAMETER, sync, OS_TOBJ_ID_GL_BITFIELD_PARAMETER, flags, OS_TOBJ_ID_GL_UINT_64_PARAMETER, timeout);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glClientWaitSync, (sync, flags, timeout), retVal);

    SU_END_FUNCTION_WRAPPER(ap_glClientWaitSync);

    return retVal;
}
void APIENTRY glWaitSync(GLsync sync, GLbitfield flag, GLuint64 timeout)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glWaitSync);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glWaitSync, 3, OS_TOBJ_ID_GL_SYNC_PARAMETER, sync, OS_TOBJ_ID_GL_BITFIELD_PARAMETER, flag, OS_TOBJ_ID_GL_UINT_64_PARAMETER, timeout);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glWaitSync, (sync, flag, timeout));

    SU_END_FUNCTION_WRAPPER(ap_glWaitSync);
}
void APIENTRY glGetInteger64v(GLenum pname, GLint64* data)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glGetInteger64v);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetInteger64v, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_64_PARAMETER, data);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetInteger64v, (pname, data));

    SU_END_FUNCTION_WRAPPER(ap_glGetInteger64v);
}

void APIENTRY glGetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei* length, GLint* values)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glGetSynciv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetSynciv, 5, OS_TOBJ_ID_GL_SYNC_PARAMETER, sync, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_SIZEI_PARAMETER, bufSize, OS_TOBJ_ID_GL_P_SIZEI_PARAMETER, length, OS_TOBJ_ID_GL_P_INT_PARAMETER, values);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetSynciv, (sync, pname, bufSize, length, values));

    SU_END_FUNCTION_WRAPPER(ap_glGetSynciv);
}

//////////////////////////////////////////////////////////////////////////
// GL_ARB_texture_multisample
//////////////////////////////////////////////////////////////////////////
void APIENTRY glTexImage2DMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glTexImage2DMultisample);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTexImage2DMultisample, 6, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_SIZEI_PARAMETER, samples, OS_TOBJ_ID_GL_ENUM_PARAMETER, internalformat, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_SIZEI_PARAMETER, height, OS_TOBJ_ID_GL_BOOL_PARAMETER, fixedsamplelocations);

    // Check if stub textures are forced:
    bool areStubTexForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubTexForced = pCurrentThreadRenderContextMonitor->forcedModesManager().isStubForced(AP_OPENGL_FORCED_STUB_TEXTURES_MODE);
    }

    // If we are not in "Force stub textures" mode:
    if (!areStubTexForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glTexImage2DMultisample, (target, samples, internalformat, width, height, fixedsamplelocations));

        // Log the loaded texture:
        if (NULL != pCurrentThreadRenderContextMonitor)
        {
            // TO_DO: OpenGL3.2 - format & type of multy sample texture:
            bool rcTex = pCurrentThreadRenderContextMonitor->onTextureImageLoaded(target, 0, internalformat, width, height, 0, 0, GL_NONE, GL_NONE);
            GT_ASSERT(rcTex);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glTexImage2DMultisample);
}

void APIENTRY glTexImage3DMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glTexImage3DMultisample);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTexImage3DMultisample, 7, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_SIZEI_PARAMETER, samples, OS_TOBJ_ID_GL_ENUM_PARAMETER, internalformat, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_SIZEI_PARAMETER, height, OS_TOBJ_ID_GL_SIZEI_PARAMETER, depth, OS_TOBJ_ID_GL_BOOL_PARAMETER, fixedsamplelocations);

    // Check if stub textures are forced:
    bool areStubTexForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubTexForced = pCurrentThreadRenderContextMonitor->forcedModesManager().isStubForced(AP_OPENGL_FORCED_STUB_TEXTURES_MODE);
    }

    // If we are not in "Force stub textures" mode:
    if (!areStubTexForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glTexImage3DMultisample, (target, samples, internalformat, width, height, depth, fixedsamplelocations));

        // Log the loaded texture:
        if (NULL != pCurrentThreadRenderContextMonitor)
        {
            // TO_DO: OpenGL3.2 - format & type of multy sample texture:
            bool rcTex = pCurrentThreadRenderContextMonitor->onTextureImageLoaded(target, 0, internalformat, width, height, 0, 0, GL_NONE, GL_NONE);
            GT_ASSERT(rcTex);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glTexImage3DMultisample);
}
void APIENTRY glGetMultisamplefv(GLenum pname, GLuint index, GLfloat* val)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glGetMultisamplefv);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetMultisamplefv, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, val);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetMultisamplefv, (pname, index, val));

    SU_END_FUNCTION_WRAPPER(ap_glGetMultisamplefv);
}
void APIENTRY glSampleMaski(GLuint maskNumber, GLbitfield mask)
{
    SU_START_DRAW_FUNCTION_WRAPPER(ap_glSampleMaski);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glSampleMaski, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, maskNumber, OS_TOBJ_ID_GL_BITFIELD_PARAMETER, mask);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glSampleMaski, (maskNumber, mask));

    SU_END_FUNCTION_WRAPPER(ap_glSampleMaski);
}

//////////////////////////////////////////////////////////////////////////
// GL_APPLE_aux_depth_stencil
//////////////////////////////////////////////////////////////////////////
// No new functions

//////////////////////////////////////////////////////////////////////////
// GL_APPLE_client_storage
//////////////////////////////////////////////////////////////////////////
// No new functions

//////////////////////////////////////////////////////////////////////////
// GL_APPLE_element_array
//////////////////////////////////////////////////////////////////////////
void APIENTRY glElementPointerAPPLE(GLenum type, const GLvoid* pointer)
{
    SU_START_FUNCTION_WRAPPER(ap_glElementPointerAPPLE);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glElementPointerAPPLE, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_P_VOID_PARAMETER, pointer);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glElementPointerAPPLE, (type, pointer));

    SU_END_FUNCTION_WRAPPER(ap_glElementPointerAPPLE);
}

void APIENTRY glDrawElementArrayAPPLE(GLenum mode, GLint first, GLsizei count)
{
    SU_START_FUNCTION_WRAPPER(ap_glDrawElementArrayAPPLE);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glDrawElementArrayAPPLE, 3, OS_TOBJ_ID_GL_PRIMITIVE_TYPE_PARAMETER, mode, OS_TOBJ_ID_GL_INT_PARAMETER, first, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glDrawElementArrayAPPLE, (mode, first, count));

    SU_END_FUNCTION_WRAPPER(ap_glDrawElementArrayAPPLE);
}

void APIENTRY glDrawRangeElementArrayAPPLE(GLenum mode, GLuint start, GLuint end, GLint first, GLsizei count)
{
    SU_START_FUNCTION_WRAPPER(ap_glDrawRangeElementArrayAPPLE);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glDrawRangeElementArrayAPPLE, 5, OS_TOBJ_ID_GL_PRIMITIVE_TYPE_PARAMETER, mode, OS_TOBJ_ID_GL_UINT_PARAMETER, start, OS_TOBJ_ID_GL_UINT_PARAMETER, end, OS_TOBJ_ID_GL_SIZEI_PARAMETER, first, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glDrawRangeElementArrayAPPLE, (mode, start, end, first, count));

    SU_END_FUNCTION_WRAPPER(ap_glDrawRangeElementArrayAPPLE);
}

void APIENTRY glMultiDrawElementArrayAPPLE(GLenum mode, const GLint* first, const GLsizei* count, GLsizei primcount)
{
    SU_START_FUNCTION_WRAPPER(ap_glMultiDrawElementArrayAPPLE);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiDrawElementArrayAPPLE, 4, OS_TOBJ_ID_GL_PRIMITIVE_TYPE_PARAMETER, mode, OS_TOBJ_ID_GL_P_INT_PARAMETER, first, OS_TOBJ_ID_GL_P_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_SIZEI_PARAMETER, primcount);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiDrawElementArrayAPPLE, (mode, first, count, primcount));

    SU_END_FUNCTION_WRAPPER(ap_glMultiDrawElementArrayAPPLE);
}

void APIENTRY glMultiDrawRangeElementArrayAPPLE(GLenum mode, GLuint start, GLuint end, const GLint* first, const GLsizei* count, GLsizei primcount)
{
    SU_START_FUNCTION_WRAPPER(ap_glMultiDrawRangeElementArrayAPPLE);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiDrawRangeElementArrayAPPLE, 6, OS_TOBJ_ID_GL_PRIMITIVE_TYPE_PARAMETER, mode, OS_TOBJ_ID_GL_UINT_PARAMETER, start, OS_TOBJ_ID_GL_UINT_PARAMETER, end, OS_TOBJ_ID_GL_P_INT_PARAMETER, first, OS_TOBJ_ID_GL_P_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_SIZEI_PARAMETER, primcount);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiDrawRangeElementArrayAPPLE, (mode, start, end, first, count, primcount));

    SU_END_FUNCTION_WRAPPER(ap_glMultiDrawRangeElementArrayAPPLE);
}

//////////////////////////////////////////////////////////////////////////
// GL_APPLE_fence
//////////////////////////////////////////////////////////////////////////
void APIENTRY glGenFencesAPPLE(GLsizei n, GLuint* fences)
{
    SU_START_FUNCTION_WRAPPER(ap_glGenFencesAPPLE);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGenFencesAPPLE, 2, OS_TOBJ_ID_GL_SIZEI_PARAMETER, n, OS_TOBJ_ID_GL_P_UINT_PARAMETER, fences);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGenFencesAPPLE, (n, fences));

    SU_END_FUNCTION_WRAPPER(ap_glGenFencesAPPLE);
}

void APIENTRY glDeleteFencesAPPLE(GLsizei n, const GLuint* fences)
{
    SU_START_FUNCTION_WRAPPER(ap_glDeleteFencesAPPLE);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glDeleteFencesAPPLE, 2, OS_TOBJ_ID_GL_SIZEI_PARAMETER, n, OS_TOBJ_ID_GL_P_UINT_PARAMETER, fences);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glDeleteFencesAPPLE, (n, fences));

    SU_END_FUNCTION_WRAPPER(ap_glDeleteFencesAPPLE);
}

void APIENTRY glSetFenceAPPLE(GLuint fence)
{
    SU_START_FUNCTION_WRAPPER(ap_glSetFenceAPPLE);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glSetFenceAPPLE, 1, OS_TOBJ_ID_GL_UINT_PARAMETER, fence);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glSetFenceAPPLE, (fence));

    SU_END_FUNCTION_WRAPPER(ap_glSetFenceAPPLE);
}

GLboolean APIENTRY glIsFenceAPPLE(GLuint fence)
{
    SU_START_FUNCTION_WRAPPER(ap_glIsFenceAPPLE);

    GLboolean retVal = GL_FALSE;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glIsFenceAPPLE, 1, OS_TOBJ_ID_GL_UINT_PARAMETER, fence);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glIsFenceAPPLE, (fence), retVal);

    SU_END_FUNCTION_WRAPPER(ap_glIsFenceAPPLE);

    return retVal;
}

GLboolean APIENTRY glTestFenceAPPLE(GLuint fence)
{
    SU_START_FUNCTION_WRAPPER(ap_glTestFenceAPPLE);

    GLboolean retVal = GL_FALSE;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTestFenceAPPLE, 1, OS_TOBJ_ID_GL_UINT_PARAMETER, fence);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glTestFenceAPPLE, (fence), retVal);

    SU_END_FUNCTION_WRAPPER(ap_glTestFenceAPPLE);

    return retVal;
}

void APIENTRY glFinishFenceAPPLE(GLuint fence)
{
    SU_START_FUNCTION_WRAPPER(ap_glFinishFenceAPPLE);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glFinishFenceAPPLE, 1, OS_TOBJ_ID_GL_UINT_PARAMETER, fence);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glFinishFenceAPPLE, (fence));

    SU_END_FUNCTION_WRAPPER(ap_glFinishFenceAPPLE);
}

GLboolean APIENTRY glTestObjectAPPLE(GLenum object, GLuint name)
{
    SU_START_FUNCTION_WRAPPER(ap_glTestObjectAPPLE);

    GLboolean retVal = GL_FALSE;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTestObjectAPPLE, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, object, OS_TOBJ_ID_GL_UINT_PARAMETER, name);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glTestObjectAPPLE, (object, name), retVal);

    SU_END_FUNCTION_WRAPPER(ap_glTestObjectAPPLE);

    return retVal;
}

void APIENTRY glFinishObjectAPPLE(GLenum object, GLint name)
{
    SU_START_FUNCTION_WRAPPER(ap_glFinishObjectAPPLE);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glFinishObjectAPPLE, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, object, OS_TOBJ_ID_GL_INT_PARAMETER, name);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glFinishObjectAPPLE, (object, name));

    SU_END_FUNCTION_WRAPPER(ap_glFinishObjectAPPLE);
}

//////////////////////////////////////////////////////////////////////////
// GL_APPLE_float_pixels
//////////////////////////////////////////////////////////////////////////
// No new functions

//////////////////////////////////////////////////////////////////////////
// GL_APPLE_flush_buffer_range
//////////////////////////////////////////////////////////////////////////
void APIENTRY glBufferParameteriAPPLE(GLenum target, GLenum pname, GLint param)
{
    SU_START_FUNCTION_WRAPPER(ap_glBufferParameteriAPPLE);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glBufferParameteriAPPLE, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_INT_PARAMETER, param);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glBufferParameteriAPPLE, (target, pname, param));

    SU_END_FUNCTION_WRAPPER(ap_glBufferParameteriAPPLE);
}

void APIENTRY glFlushMappedBufferRangeAPPLE(GLenum target, GLintptr offset, GLsizeiptr size)
{
    SU_START_FUNCTION_WRAPPER(ap_glFlushMappedBufferRangeAPPLE);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glFlushMappedBufferRangeAPPLE, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_INTPTR_PARAMETER, offset, OS_TOBJ_ID_GL_SIZEIPTR_PARAMETER, size);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glFlushMappedBufferRangeAPPLE, (target, offset, size));

    // Log the vbo data set:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        gsVBOMonitor* vboMonitor = pCurrentThreadRenderContextMonitor->vboMonitor();
        GT_IF_WITH_ASSERT(vboMonitor != NULL)
        {
            vboMonitor->onVertexBufferObjectSubDataSet(target);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glFlushMappedBufferRangeAPPLE);
}

//////////////////////////////////////////////////////////////////////////
// GL_APPLE_flush_render
// No new functions
//////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////
// GL_APPLE_object_purgeable
//////////////////////////////////////////////////////////////////////////
GLenum APIENTRY glObjectPurgeableAPPLE(GLenum objectType, GLuint name, GLenum option)
{
    SU_START_FUNCTION_WRAPPER(ap_glObjectPurgeableAPPLE);

    GLenum retVal = GL_NONE;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glObjectPurgeableAPPLE, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, objectType, OS_TOBJ_ID_GL_UINT_PARAMETER, name, OS_TOBJ_ID_GL_ENUM_PARAMETER, option);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glObjectPurgeableAPPLE, (objectType, name, option), retVal);

    SU_END_FUNCTION_WRAPPER(ap_glObjectPurgeableAPPLE);

    return retVal;

}
GLenum APIENTRY glObjectUnpurgeableAPPLE(GLenum objectType, GLuint name, GLenum option)
{
    SU_START_FUNCTION_WRAPPER(ap_glObjectUnpurgeableAPPLE);

    GLenum retVal = GL_NONE;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glObjectUnpurgeableAPPLE, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, objectType, OS_TOBJ_ID_GL_UINT_PARAMETER, name, OS_TOBJ_ID_GL_ENUM_PARAMETER, option);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glObjectUnpurgeableAPPLE, (objectType, name, option), retVal);

    SU_END_FUNCTION_WRAPPER(ap_glObjectUnpurgeableAPPLE);

    return retVal;

}
void APIENTRY glGetObjectParameterivAPPLE(GLenum objectType, GLuint name, GLenum pname, GLint* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetObjectParameterivAPPLE);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetObjectParameterivAPPLE, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, objectType, OS_TOBJ_ID_GL_UINT_PARAMETER, name, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetObjectParameterivAPPLE, (objectType, name, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetObjectParameterivAPPLE);
}

//////////////////////////////////////////////////////////////////////////
// GL_APPLE_packed_pixels
// No new functions
//////////////////////////////////////////////////////////////////////////

// GL_APPLE_pixel_buffer
// No new functions
//TO_DO: search for this functions (spec is unavailable on the net)
//////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////
// GL_APPLE_specular_vector
// No new functions
//////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////
// GL_APPLE_texture_range
//////////////////////////////////////////////////////////////////////////
void APIENTRY glTextureRangeAPPLE(GLenum target, GLsizei length, const GLvoid* pointer)
{
    SU_START_FUNCTION_WRAPPER(ap_glTextureRangeAPPLE);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTextureRangeAPPLE, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_SIZEI_PARAMETER, length, OS_TOBJ_ID_GL_P_VOID_PARAMETER, pointer);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glTextureRangeAPPLE, (target, length, pointer));

    SU_END_FUNCTION_WRAPPER(ap_glTextureRangeAPPLE);
}

void APIENTRY glGetTexParameterPointervAPPLE(GLenum target, GLenum pname, GLvoid** params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetTexParameterPointervAPPLE);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetTexParameterPointervAPPLE, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_PP_VOID_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetTexParameterPointervAPPLE, (target, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetTexParameterPointervAPPLE);
}


//////////////////////////////////////////////////////////////////////////
// GL_APPLE_transform_hint
// No new functions
//////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////
// GL_APPLE_vertex_array_object
//////////////////////////////////////////////////////////////////////////
void APIENTRY glBindVertexArrayAPPLE(GLuint array)
{
    SU_START_FUNCTION_WRAPPER(ap_glBindVertexArrayAPPLE);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glBindVertexArrayAPPLE, 1, OS_TOBJ_ID_GL_UINT_PARAMETER, array);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glBindVertexArrayAPPLE, (array));

    SU_END_FUNCTION_WRAPPER(ap_glBindVertexArrayAPPLE);
}

void APIENTRY glDeleteVertexArraysAPPLE(GLsizei n, const GLuint* arrays)
{
    SU_START_FUNCTION_WRAPPER(ap_glDeleteVertexArraysAPPLE);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glDeleteVertexArraysAPPLE, 3, OS_TOBJ_ID_GL_SIZEI_PARAMETER, n, OS_TOBJ_ID_GL_P_UINT_PARAMETER, arrays);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glDeleteVertexArraysAPPLE, (n, arrays));

    SU_END_FUNCTION_WRAPPER(ap_glDeleteVertexArraysAPPLE);
}

void APIENTRY glGenVertexArraysAPPLE(GLsizei n, GLuint* arrays)
{
    SU_START_FUNCTION_WRAPPER(ap_glGenVertexArraysAPPLE);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGenVertexArraysAPPLE, 2, OS_TOBJ_ID_GL_SIZEI_PARAMETER, n, OS_TOBJ_ID_GL_P_UINT_PARAMETER, arrays);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGenVertexArraysAPPLE, (n, arrays));

    SU_END_FUNCTION_WRAPPER(ap_glGenVertexArraysAPPLE);
}

GLboolean APIENTRY glIsVertexArrayAPPLE(GLuint array)
{
    SU_START_FUNCTION_WRAPPER(ap_glIsVertexArrayAPPLE);

    GLboolean retVal = GL_FALSE;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glIsVertexArrayAPPLE, 1, OS_TOBJ_ID_GL_UINT_PARAMETER, array);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glIsVertexArrayAPPLE, (array), retVal);

    SU_END_FUNCTION_WRAPPER(ap_glIsVertexArrayAPPLE);

    return retVal;
}

//////////////////////////////////////////////////////////////////////////
// GL_APPLE_vertex_array_range
//////////////////////////////////////////////////////////////////////////
void APIENTRY glVertexArrayRangeAPPLE(GLsizei length, GLvoid* pointer)
{
    SU_START_FUNCTION_WRAPPER(ap_glVertexArrayRangeAPPLE);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexArrayRangeAPPLE, 2, OS_TOBJ_ID_GL_SIZEI_PARAMETER, length, OS_TOBJ_ID_GL_P_VOID_PARAMETER, pointer);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexArrayRangeAPPLE, (length, pointer));

    SU_END_FUNCTION_WRAPPER(ap_glVertexArrayRangeAPPLE);
}

void APIENTRY glFlushVertexArrayRangeAPPLE(GLsizei length, GLvoid* pointer)
{
    SU_START_FUNCTION_WRAPPER(ap_glFlushVertexArrayRangeAPPLE);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glFlushVertexArrayRangeAPPLE, 2, OS_TOBJ_ID_GL_SIZEI_PARAMETER, length, OS_TOBJ_ID_GL_P_VOID_PARAMETER, pointer);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glFlushVertexArrayRangeAPPLE, (length, pointer));

    SU_END_FUNCTION_WRAPPER(ap_glFlushVertexArrayRangeAPPLE);
}

void APIENTRY glVertexArrayParameteriAPPLE(GLenum pname, GLint param)
{
    SU_START_FUNCTION_WRAPPER(ap_glVertexArrayParameteriAPPLE);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glVertexArrayParameteriAPPLE, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_INT_PARAMETER, param);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glVertexArrayParameteriAPPLE, (pname, param));

    SU_END_FUNCTION_WRAPPER(ap_glVertexArrayParameteriAPPLE);
}


//////////////////////////////////////////////////////////////////////////
// GL_APPLE_vertex_program_evaluators
//////////////////////////////////////////////////////////////////////////
void APIENTRY glEnableVertexAttribAPPLE(GLuint index, GLenum pname)
{
    SU_START_FUNCTION_WRAPPER(ap_glEnableVertexAttribAPPLE);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glEnableVertexAttribAPPLE, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glEnableVertexAttribAPPLE, (index, pname));

    SU_END_FUNCTION_WRAPPER(ap_glEnableVertexAttribAPPLE);
}

void APIENTRY glDisableVertexAttribAPPLE(GLuint index, GLenum pname)
{
    SU_START_FUNCTION_WRAPPER(ap_glDisableVertexAttribAPPLE);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glDisableVertexAttribAPPLE, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glDisableVertexAttribAPPLE, (index, pname));

    SU_END_FUNCTION_WRAPPER(ap_glDisableVertexAttribAPPLE);
}

GLboolean APIENTRY glIsVertexAttribEnabledAPPLE(GLuint index, GLenum pname)
{
    SU_START_FUNCTION_WRAPPER(ap_glIsVertexAttribEnabledAPPLE);

    GLboolean retVal = GL_FALSE;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glIsVertexAttribEnabledAPPLE, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glIsVertexAttribEnabledAPPLE, (index, pname), retVal);

    SU_END_FUNCTION_WRAPPER(ap_glIsVertexAttribEnabledAPPLE);

    return retVal;
}

void APIENTRY glMapVertexAttrib1dAPPLE(GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble* points)
{
    SU_START_FUNCTION_WRAPPER(ap_glMapVertexAttrib1dAPPLE);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMapVertexAttrib1dAPPLE, 7, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_UINT_PARAMETER, size, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, u1, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, u2, OS_TOBJ_ID_GL_INT_PARAMETER, stride, OS_TOBJ_ID_GL_INT_PARAMETER, order, OS_TOBJ_ID_GL_P_DOUBLE_PARAMETER, points);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMapVertexAttrib1dAPPLE, (index, size, u1, u2, stride, order, points));

    SU_END_FUNCTION_WRAPPER(ap_glMapVertexAttrib1dAPPLE);
}

void APIENTRY glMapVertexAttrib1fAPPLE(GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat* points)
{
    SU_START_FUNCTION_WRAPPER(ap_glMapVertexAttrib1fAPPLE);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMapVertexAttrib1fAPPLE, 7, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_UINT_PARAMETER, size, OS_TOBJ_ID_GL_FLOAT_PARAMETER, u1, OS_TOBJ_ID_GL_FLOAT_PARAMETER, u2, OS_TOBJ_ID_GL_INT_PARAMETER, stride, OS_TOBJ_ID_GL_INT_PARAMETER, order, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, points);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMapVertexAttrib1fAPPLE, (index, size, u1, u2, stride, order, points));

    SU_END_FUNCTION_WRAPPER(ap_glMapVertexAttrib1fAPPLE);
}

void APIENTRY glMapVertexAttrib2dAPPLE(GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble* points)
{
    SU_START_FUNCTION_WRAPPER(ap_glMapVertexAttrib2dAPPLE);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMapVertexAttrib2dAPPLE, 11, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_UINT_PARAMETER, size, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, u1, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, u2, OS_TOBJ_ID_GL_INT_PARAMETER, ustride, OS_TOBJ_ID_GL_INT_PARAMETER, uorder, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, v1, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, v2, OS_TOBJ_ID_GL_INT_PARAMETER, vstride, OS_TOBJ_ID_GL_INT_PARAMETER, vorder, OS_TOBJ_ID_GL_P_DOUBLE_PARAMETER, points);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMapVertexAttrib2dAPPLE, (index, size, u1, u2, ustride, uorder, v1, v2, vstride, vorder, points));

    SU_END_FUNCTION_WRAPPER(ap_glMapVertexAttrib2dAPPLE);
}

void APIENTRY glMapVertexAttrib2fAPPLE(GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat* points)
{
    SU_START_FUNCTION_WRAPPER(ap_glMapVertexAttrib2fAPPLE);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMapVertexAttrib2fAPPLE, 11, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_UINT_PARAMETER, size, OS_TOBJ_ID_GL_FLOAT_PARAMETER, u1, OS_TOBJ_ID_GL_FLOAT_PARAMETER, u2, OS_TOBJ_ID_GL_INT_PARAMETER, ustride, OS_TOBJ_ID_GL_INT_PARAMETER, uorder, OS_TOBJ_ID_GL_FLOAT_PARAMETER, v1, OS_TOBJ_ID_GL_FLOAT_PARAMETER, v2, OS_TOBJ_ID_GL_INT_PARAMETER, vstride, OS_TOBJ_ID_GL_INT_PARAMETER, vorder, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, points);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMapVertexAttrib2fAPPLE, (index, size, u1, u2, ustride, uorder, v1, v2, vstride, vorder, points));

    SU_END_FUNCTION_WRAPPER(ap_glMapVertexAttrib2fAPPLE);
}

//////////////////////////////////////////////////////////////////////////
// GL_APPLE_ycbcr_422
// No new functions
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
// GL_EXT_direct_state_access
//////////////////////////////////////////////////////////////////////////
void APIENTRY glClientAttribDefaultEXT(GLbitfield mask)
{
    SU_START_FUNCTION_WRAPPER(ap_glClientAttribDefaultEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glClientAttribDefaultEXT, 1, OS_TOBJ_ID_GL_BITFIELD_PARAMETER, mask);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glClientAttribDefaultEXT, (mask));

    SU_END_FUNCTION_WRAPPER(ap_glClientAttribDefaultEXT);
}

void APIENTRY glPushClientAttribDefaultEXT(GLbitfield mask)
{
    SU_START_FUNCTION_WRAPPER(ap_glPushClientAttribDefaultEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glPushClientAttribDefaultEXT, 1, OS_TOBJ_ID_GL_BITFIELD_PARAMETER, mask);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glPushClientAttribDefaultEXT, (mask));

    SU_END_FUNCTION_WRAPPER(ap_glPushClientAttribDefaultEXT);
}

void APIENTRY glMatrixLoadfEXT(GLenum matrixMode, const GLfloat* m)
{
    SU_START_FUNCTION_WRAPPER(ap_glMatrixLoadfEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMatrixLoadfEXT, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, matrixMode, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, m);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMatrixLoadfEXT, (matrixMode, m));

    SU_END_FUNCTION_WRAPPER(ap_glMatrixLoadfEXT);
}

void APIENTRY glMatrixLoaddEXT(GLenum matrixMode, const GLdouble* m)
{
    SU_START_FUNCTION_WRAPPER(ap_glMatrixLoaddEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMatrixLoaddEXT, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, matrixMode, OS_TOBJ_ID_GL_P_DOUBLE_PARAMETER, m);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMatrixLoaddEXT, (matrixMode, m));

    SU_END_FUNCTION_WRAPPER(ap_glMatrixLoaddEXT);
}

void APIENTRY glMatrixMultfEXT(GLenum matrixMode, const GLfloat* m)
{
    SU_START_FUNCTION_WRAPPER(ap_glMatrixMultfEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMatrixMultfEXT, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, matrixMode, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, m);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMatrixMultfEXT, (matrixMode, m));

    SU_END_FUNCTION_WRAPPER(ap_glMatrixMultfEXT);
}

void APIENTRY glMatrixMultdEXT(GLenum matrixMode, const GLdouble* m)
{
    SU_START_FUNCTION_WRAPPER(ap_glMatrixMultdEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMatrixMultdEXT, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, matrixMode, OS_TOBJ_ID_GL_P_DOUBLE_PARAMETER, m);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMatrixMultdEXT, (matrixMode, m));

    SU_END_FUNCTION_WRAPPER(ap_glMatrixMultdEXT);
}

void APIENTRY glMatrixLoadIdentityEXT(GLenum matrixMode)
{
    SU_START_FUNCTION_WRAPPER(ap_glMatrixLoadIdentityEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMatrixLoadIdentityEXT, 1, OS_TOBJ_ID_GL_ENUM_PARAMETER, matrixMode);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMatrixLoadIdentityEXT, (matrixMode));

    SU_END_FUNCTION_WRAPPER(ap_glMatrixLoadIdentityEXT);
}

void APIENTRY glMatrixRotatefEXT(GLenum matrixMode, GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
{
    SU_START_FUNCTION_WRAPPER(ap_glMatrixRotatefEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMatrixRotatefEXT, 5, OS_TOBJ_ID_GL_ENUM_PARAMETER, matrixMode, OS_TOBJ_ID_GL_FLOAT_PARAMETER, angle, OS_TOBJ_ID_GL_FLOAT_PARAMETER, x, OS_TOBJ_ID_GL_FLOAT_PARAMETER, y, OS_TOBJ_ID_GL_FLOAT_PARAMETER, z);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMatrixRotatefEXT, (matrixMode, angle, x, y, z));

    SU_END_FUNCTION_WRAPPER(ap_glMatrixRotatefEXT);
}

void APIENTRY glMatrixRotatedEXT(GLenum matrixMode, GLdouble angle, GLdouble x, GLdouble y, GLdouble z)
{
    SU_START_FUNCTION_WRAPPER(ap_glMatrixRotatedEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMatrixRotatedEXT, 5, OS_TOBJ_ID_GL_ENUM_PARAMETER, matrixMode, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, angle, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, x, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, y, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, z);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMatrixRotatedEXT, (matrixMode, angle, x, y, z));

    SU_END_FUNCTION_WRAPPER(ap_glMatrixRotatedEXT);
}

void APIENTRY glMatrixScalefEXT(GLenum matrixMode, GLfloat x, GLfloat y, GLfloat z)
{
    SU_START_FUNCTION_WRAPPER(ap_glMatrixScalefEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMatrixScalefEXT, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, matrixMode, OS_TOBJ_ID_GL_FLOAT_PARAMETER, x, OS_TOBJ_ID_GL_FLOAT_PARAMETER, y, OS_TOBJ_ID_GL_FLOAT_PARAMETER, z);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMatrixScalefEXT, (matrixMode, x, y, z));

    SU_END_FUNCTION_WRAPPER(ap_glMatrixScalefEXT);
}

void APIENTRY glMatrixScaledEXT(GLenum matrixMode, GLdouble x, GLdouble y, GLdouble z)
{
    SU_START_FUNCTION_WRAPPER(ap_glMatrixScaledEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMatrixScaledEXT, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, matrixMode, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, x, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, y, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, z);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMatrixScaledEXT, (matrixMode, x, y, z));

    SU_END_FUNCTION_WRAPPER(ap_glMatrixScaledEXT);
}

void APIENTRY glMatrixTranslatefEXT(GLenum matrixMode, GLfloat x, GLfloat y, GLfloat z)
{
    SU_START_FUNCTION_WRAPPER(ap_glMatrixTranslatefEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMatrixTranslatefEXT, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, matrixMode, OS_TOBJ_ID_GL_FLOAT_PARAMETER, x, OS_TOBJ_ID_GL_FLOAT_PARAMETER, y, OS_TOBJ_ID_GL_FLOAT_PARAMETER, z);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMatrixTranslatefEXT, (matrixMode, x, y, z));

    SU_END_FUNCTION_WRAPPER(ap_glMatrixTranslatefEXT);
}

void APIENTRY glMatrixTranslatedEXT(GLenum matrixMode, GLdouble x, GLdouble y, GLdouble z)
{
    SU_START_FUNCTION_WRAPPER(ap_glMatrixTranslatedEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMatrixTranslatedEXT, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, matrixMode, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, x, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, y, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, z);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMatrixTranslatedEXT, (matrixMode, x, y, z));

    SU_END_FUNCTION_WRAPPER(ap_glMatrixTranslatedEXT);
}

void APIENTRY glMatrixFrustumEXT(GLenum matrixMode, GLdouble l, GLdouble r, GLdouble b, GLdouble t, GLdouble n, GLdouble f)
{
    SU_START_FUNCTION_WRAPPER(ap_glMatrixFrustumEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMatrixFrustumEXT, 7, OS_TOBJ_ID_GL_ENUM_PARAMETER, matrixMode, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, l, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, r, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, b, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, t, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, n, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, f);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMatrixFrustumEXT, (matrixMode, l, r, b, t, n, f));

    SU_END_FUNCTION_WRAPPER(ap_glMatrixFrustumEXT);
}

void APIENTRY glMatrixOrthoEXT(GLenum matrixMode, GLdouble l, GLdouble r, GLdouble b, GLdouble t, GLdouble n, GLdouble f)
{
    SU_START_FUNCTION_WRAPPER(ap_glMatrixOrthoEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMatrixOrthoEXT, 7, OS_TOBJ_ID_GL_ENUM_PARAMETER, matrixMode, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, l, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, r, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, b, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, t, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, n, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, f);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMatrixOrthoEXT, (matrixMode, l, r, b, t, n, f));

    SU_END_FUNCTION_WRAPPER(ap_glMatrixOrthoEXT);
}

void APIENTRY glMatrixPopEXT(GLenum matrixMode)
{
    SU_START_FUNCTION_WRAPPER(ap_glMatrixPopEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMatrixPopEXT, 1, OS_TOBJ_ID_GL_ENUM_PARAMETER, matrixMode);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMatrixPopEXT, (matrixMode));

    SU_END_FUNCTION_WRAPPER(ap_glMatrixPopEXT);
}

void APIENTRY glMatrixPushEXT(GLenum matrixMode)
{
    SU_START_FUNCTION_WRAPPER(ap_glMatrixPushEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMatrixPushEXT, 1, OS_TOBJ_ID_GL_ENUM_PARAMETER, matrixMode);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMatrixPushEXT, (matrixMode));

    SU_END_FUNCTION_WRAPPER(ap_glMatrixPushEXT);
}

void APIENTRY glMatrixLoadTransposefEXT(GLenum matrixMode, const GLfloat* m)
{
    SU_START_FUNCTION_WRAPPER(ap_glMatrixLoadTransposefEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMatrixLoadTransposefEXT, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, matrixMode, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, m);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMatrixLoadTransposefEXT, (matrixMode, m));

    SU_END_FUNCTION_WRAPPER(ap_glMatrixLoadTransposefEXT);
}

void APIENTRY glMatrixLoadTransposedEXT(GLenum matrixMode, const GLdouble* m)
{
    SU_START_FUNCTION_WRAPPER(ap_glMatrixLoadTransposedEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMatrixLoadTransposedEXT, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, matrixMode, OS_TOBJ_ID_GL_P_DOUBLE_PARAMETER, m);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMatrixLoadTransposedEXT, (matrixMode, m));

    SU_END_FUNCTION_WRAPPER(ap_glMatrixLoadTransposedEXT);
}

void APIENTRY glMatrixMultTransposefEXT(GLenum matrixMode, const GLfloat* m)
{
    SU_START_FUNCTION_WRAPPER(ap_glMatrixMultTransposefEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMatrixMultTransposefEXT, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, matrixMode, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, m);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMatrixMultTransposefEXT, (matrixMode, m));

    SU_END_FUNCTION_WRAPPER(ap_glMatrixMultTransposefEXT);
}

void APIENTRY glMatrixMultTransposedEXT(GLenum matrixMode, const GLdouble* m)
{
    SU_START_FUNCTION_WRAPPER(ap_glMatrixMultTransposedEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMatrixMultTransposedEXT, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, matrixMode, OS_TOBJ_ID_GL_P_DOUBLE_PARAMETER, m);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMatrixMultTransposedEXT, (matrixMode, m));

    SU_END_FUNCTION_WRAPPER(ap_glMatrixMultTransposedEXT);
}

void APIENTRY glTextureParameterfEXT(GLuint texture, GLenum target, GLenum pname, GLfloat param)
{
    SU_START_FUNCTION_WRAPPER(ap_glTextureParameterfEXT);

    // Get the input bind target bounded texture name:
    (void) gs_stat_openGLMonitorInstance.boundTexture(target);

    // Log the call to this function:
    if ((pname == GL_TEXTURE_MIN_FILTER) || (pname == GL_TEXTURE_MAG_FILTER) ||
        (pname == GL_TEXTURE_COMPARE_MODE) || (pname == GL_TEXTURE_COMPARE_FUNC) || (pname == GL_DEPTH_TEXTURE_MODE) ||
        (pname == GL_TEXTURE_WRAP_S) || (pname == GL_TEXTURE_WRAP_T) || (pname == GL_TEXTURE_WRAP_R))
    {
        GLenum paramAsEnum = (GLenum)param;
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTextureParameterfEXT, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_ENUM_PARAMETER, paramAsEnum);
    }
    else
    {
        // Log the call to this function:
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTextureParameterfEXT, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_FLOAT_PARAMETER, param);
    }

    // Check if stub textures are forced:
    bool areStubTexForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubTexForced = pCurrentThreadRenderContextMonitor->forcedModesManager().isStubForced(AP_OPENGL_FORCED_STUB_TEXTURES_MODE);
    }

    // If we are not in "Force stub textures" mode:
    if (!areStubTexForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glTextureParameterfEXT, (texture, target, pname, param));
    }

    // Log the new parameter value:
    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        gsTexturesMonitor* texturesMon = pCurrentThreadRenderContextMonitor->texturesMonitor();
        GT_IF_WITH_ASSERT(texturesMon != NULL)
        {
            bool rcTexParamf = pCurrentThreadRenderContextMonitor->onNamedTextureFloatParameterChanged(texture, pname, &param);
            GT_ASSERT(rcTexParamf);
        }

        // Log the mipmap auto generation:
        if ((pname == GL_GENERATE_MIPMAP) || (pname == GL_TEXTURE_BASE_LEVEL) || (pname == GL_TEXTURE_MAX_LEVEL))
        {
            // Get the param value:
            GLfloat value = param;
            bool rcMipmapGeneration = pCurrentThreadRenderContextMonitor->onMipmapGenerateParamSet(texture, pname, value);
            GT_ASSERT(rcMipmapGeneration);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glTextureParameterfEXT);
}

void APIENTRY glTextureParameterfvEXT(GLuint texture, GLenum target, GLenum pname, const GLfloat* param)
{
    SU_START_FUNCTION_WRAPPER(ap_glTextureParameterfvEXT);

    // Log the call to this function:
    if ((pname == GL_TEXTURE_MIN_FILTER) || (pname == GL_TEXTURE_MAG_FILTER) ||
        (pname == GL_TEXTURE_COMPARE_MODE) || (pname == GL_TEXTURE_COMPARE_FUNC) || (pname == GL_DEPTH_TEXTURE_MODE) ||
        (pname == GL_TEXTURE_WRAP_S) || (pname == GL_TEXTURE_WRAP_T) || (pname == GL_TEXTURE_WRAP_R))
    {
        GLenum paramAsEnum = (GLenum) * param;
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTextureParameterfvEXT, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_ENUM_PARAMETER, paramAsEnum);
    }
    else
    {
        // Log the call to this function:
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTextureParameterfvEXT, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, param);
    }

    // Check if stub textures are forced:
    bool areStubTexForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubTexForced = pCurrentThreadRenderContextMonitor->forcedModesManager().isStubForced(AP_OPENGL_FORCED_STUB_TEXTURES_MODE);
    }

    // If we are not in "Force stub textures" mode:
    if (!areStubTexForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glTextureParameterfvEXT, (texture, target, pname, param));
    }

    // Log the new parameter value:
    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        gsTexturesMonitor* texturesMon = pCurrentThreadRenderContextMonitor->texturesMonitor();
        GT_IF_WITH_ASSERT(texturesMon != NULL)
        {
            bool rcTexParamf = pCurrentThreadRenderContextMonitor->onNamedTextureFloatParameterChanged(texture, pname, param);
            GT_ASSERT(rcTexParamf);
        }

        // Log the mipmap auto generation:
        if ((pname == GL_GENERATE_MIPMAP) || (pname == GL_TEXTURE_BASE_LEVEL) || (pname == GL_TEXTURE_MAX_LEVEL))
        {
            // Get the param value:
            GLfloat value = *param;
            bool rcMipmapGeneration = pCurrentThreadRenderContextMonitor->onMipmapGenerateParamSet(texture, pname, value);
            GT_ASSERT(rcMipmapGeneration);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glTextureParameterfvEXT);
}

void APIENTRY glTextureParameteriEXT(GLuint texture, GLenum target, GLenum pname, GLint param)
{
    SU_START_FUNCTION_WRAPPER(ap_glTextureParameteriEXT);

    // Log the call to this function:
    if ((pname == GL_TEXTURE_MIN_FILTER) || (pname == GL_TEXTURE_MAG_FILTER) ||
        (pname == GL_TEXTURE_COMPARE_MODE) || (pname == GL_TEXTURE_COMPARE_FUNC) || (pname == GL_DEPTH_TEXTURE_MODE) ||
        (pname == GL_TEXTURE_WRAP_S) || (pname == GL_TEXTURE_WRAP_T) || (pname == GL_TEXTURE_WRAP_R))
    {
        GLenum paramAsEnum = (GLenum)param;
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTextureParameteriEXT, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_ENUM_PARAMETER, paramAsEnum);
    }
    else
    {
        // Log the call to this function:
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTextureParameteriEXT, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_INT_PARAMETER, param);
    }

    // Check if stub textures are forced:
    bool areStubTexForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubTexForced = pCurrentThreadRenderContextMonitor->forcedModesManager().isStubForced(AP_OPENGL_FORCED_STUB_TEXTURES_MODE);
    }

    // If we are not in "Force stub textures" mode:
    if (!areStubTexForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glTextureParameteriEXT, (texture, target, pname, param));
    }

    // Log the new parameter value:
    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        gsTexturesMonitor* texturesMon = pCurrentThreadRenderContextMonitor->texturesMonitor();
        GT_IF_WITH_ASSERT(texturesMon != NULL)
        {
            bool rcTexParamf = pCurrentThreadRenderContextMonitor->onNamedTextureIntParameterChanged(texture, pname, &param);
            GT_ASSERT(rcTexParamf);
        }

        // Log the mipmap auto generation:
        if ((pname == GL_GENERATE_MIPMAP) || (pname == GL_TEXTURE_BASE_LEVEL) || (pname == GL_TEXTURE_MAX_LEVEL))
        {
            // Get the param value:
            GLint value = param;
            bool rcMipmapGeneration = pCurrentThreadRenderContextMonitor->onMipmapGenerateParamSet(texture, pname, (GLfloat)value);
            GT_ASSERT(rcMipmapGeneration);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glTextureParameteriEXT);
}

void APIENTRY glTextureParameterivEXT(GLuint texture, GLenum target, GLenum pname, const GLint* param)
{
    SU_START_FUNCTION_WRAPPER(ap_glTextureParameterivEXT);

    // Log the call to this function:
    if ((pname == GL_TEXTURE_MIN_FILTER) || (pname == GL_TEXTURE_MAG_FILTER) ||
        (pname == GL_TEXTURE_COMPARE_MODE) || (pname == GL_TEXTURE_COMPARE_FUNC) || (pname == GL_DEPTH_TEXTURE_MODE) ||
        (pname == GL_TEXTURE_WRAP_S) || (pname == GL_TEXTURE_WRAP_T) || (pname == GL_TEXTURE_WRAP_R))
    {
        GLenum paramAsEnum = (GLenum) * param;
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTextureParameterivEXT, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_ENUM_PARAMETER, paramAsEnum);
    }
    else
    {
        // Log the call to this function:
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTextureParameterivEXT, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_PARAMETER, param);
    }

    // Check if stub textures are forced:
    bool areStubTexForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubTexForced = pCurrentThreadRenderContextMonitor->forcedModesManager().isStubForced(AP_OPENGL_FORCED_STUB_TEXTURES_MODE);
    }

    // If we are not in "Force stub textures" mode:
    if (!areStubTexForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glTextureParameterivEXT, (texture, target, pname, param));
    }

    // Log the new parameter value:
    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        gsTexturesMonitor* texturesMon = pCurrentThreadRenderContextMonitor->texturesMonitor();
        GT_IF_WITH_ASSERT(texturesMon != NULL)
        {
            bool rcTexParamf = pCurrentThreadRenderContextMonitor->onNamedTextureIntParameterChanged(texture, pname, param);
            GT_ASSERT(rcTexParamf);
        }

        // Log the mipmap auto generation:
        if ((pname == GL_GENERATE_MIPMAP) || (pname == GL_TEXTURE_BASE_LEVEL) || (pname == GL_TEXTURE_MAX_LEVEL))
        {
            // Get the param value:
            GLint value = *param;
            bool rcMipmapGeneration = pCurrentThreadRenderContextMonitor->onMipmapGenerateParamSet(texture, pname, (GLfloat)value);
            GT_ASSERT(rcMipmapGeneration);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glTextureParameterivEXT);
}

void APIENTRY glTextureImage1DEXT(GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid* pixels)
{
    SU_START_FUNCTION_WRAPPER(ap_glTextureImage1DEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTextureImage1DEXT, 9, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_ENUM_PARAMETER, internalformat, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_INT_PARAMETER, border, OS_TOBJ_ID_GL_ENUM_PARAMETER, format, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_P_VOID_PARAMETER, pixels);

    // Check if stub textures are forced:
    bool areStubTexForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubTexForced = pCurrentThreadRenderContextMonitor->forcedModesManager().isStubForced(AP_OPENGL_FORCED_STUB_TEXTURES_MODE);
    }

    // If we are not in "Force stub textures" mode:
    if (!areStubTexForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glTextureImage1DEXT, (texture, target, level, internalformat, width, border, format, type, pixels));

        // Log the loaded texture:
        if (NULL != pCurrentThreadRenderContextMonitor)
        {
            bool rcTex = pCurrentThreadRenderContextMonitor->onNamedTextureImageLoaded(texture, target, level, internalformat, width, 0, 0, border, format, type);
            GT_ASSERT(rcTex);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glTextureImage1DEXT);
}

void APIENTRY glTextureImage2DEXT(GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid* pixels)
{
    SU_START_FUNCTION_WRAPPER(ap_glTextureImage2DEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTextureImage2DEXT, 10, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_ENUM_PARAMETER, internalformat, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_SIZEI_PARAMETER, height, OS_TOBJ_ID_GL_INT_PARAMETER, border, OS_TOBJ_ID_GL_ENUM_PARAMETER, format, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_P_VOID_PARAMETER, pixels);

    // Check if stub textures are forced:
    bool areStubTexForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubTexForced = pCurrentThreadRenderContextMonitor->forcedModesManager().isStubForced(AP_OPENGL_FORCED_STUB_TEXTURES_MODE);
    }

    // If we are not in "Force stub textures" mode:
    if (!areStubTexForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glTextureImage2DEXT, (texture, target, level, internalformat, width, height, border, format, type, pixels));

        // Log the loaded texture:
        if (NULL != pCurrentThreadRenderContextMonitor)
        {
            bool rcTex = pCurrentThreadRenderContextMonitor->onNamedTextureImageLoaded(texture, target, level, internalformat, width, height, 0, border, format, type);
            GT_ASSERT(rcTex);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glTextureImage2DEXT);
}

void APIENTRY glTextureSubImage1DEXT(GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid* pixels)
{
    SU_START_FUNCTION_WRAPPER(ap_glTextureSubImage1DEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTextureSubImage1DEXT, 8, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_INT_PARAMETER, xoffset, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_ENUM_PARAMETER, format, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_P_VOID_PARAMETER, pixels);

    // Check if stub textures are forced:
    bool areStubTexForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubTexForced = pCurrentThreadRenderContextMonitor->forcedModesManager().isStubForced(AP_OPENGL_FORCED_STUB_TEXTURES_MODE);
    }

    // If we are not in "Force stub textures" mode:
    if (!areStubTexForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glTextureSubImage1DEXT, (texture, target, level, xoffset, width, format, type, pixels));

        // Log the loaded sub-texture:
        if (NULL != pCurrentThreadRenderContextMonitor)
        {
            bool rcSubTex = pCurrentThreadRenderContextMonitor->onTextureSubImageLoaded(texture, target, level);
            GT_ASSERT(rcSubTex);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glTextureSubImage1DEXT);
}

void APIENTRY glTextureSubImage2DEXT(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid* pixels)
{
    SU_START_FUNCTION_WRAPPER(ap_glTextureSubImage2DEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTextureSubImage2DEXT, 10, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_INT_PARAMETER, xoffset, OS_TOBJ_ID_GL_INT_PARAMETER, yoffset, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_SIZEI_PARAMETER, height, OS_TOBJ_ID_GL_ENUM_PARAMETER, format, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_P_VOID_PARAMETER, pixels);

    // Check if stub textures are forced:
    bool areStubTexForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubTexForced = pCurrentThreadRenderContextMonitor->forcedModesManager().isStubForced(AP_OPENGL_FORCED_STUB_TEXTURES_MODE);
    }

    // If we are not in "Force stub textures" mode:
    if (!areStubTexForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glTextureSubImage2DEXT, (texture, target, level, xoffset, yoffset, width, height, format, type, pixels));

        // Log the loaded sub-texture:
        if (NULL != pCurrentThreadRenderContextMonitor)
        {
            bool rcSubTex = pCurrentThreadRenderContextMonitor->onTextureSubImageLoaded(texture, target, level);
            GT_ASSERT(rcSubTex);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glTextureSubImage2DEXT);
}

void APIENTRY glCopyTextureImage1DEXT(GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border)
{
    SU_START_FUNCTION_WRAPPER(ap_glCopyTextureImage1DEXT);

    bool areStubTexForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubTexForced = pCurrentThreadRenderContextMonitor->forcedModesManager().isStubForced(AP_OPENGL_FORCED_STUB_TEXTURES_MODE);
    }

    // If we are not in "Force stub textures" mode:
    if (!areStubTexForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glCopyTextureImage1DEXT, (texture, target, level, internalformat, x, y, width, border));

        // Log the loaded texture:
        if (NULL != pCurrentThreadRenderContextMonitor)
        {
            bool rcTex = pCurrentThreadRenderContextMonitor->onNamedTextureImageLoaded(texture, target, level, internalformat, width, 0, 0, border, GL_GREMEDY_COPIED_FROM_BUFFER, GL_GREMEDY_COPIED_FROM_BUFFER);
            GT_ASSERT(rcTex);
        }
    }

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glCopyTextureImage1DEXT, 8, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_ENUM_PARAMETER, internalformat, OS_TOBJ_ID_GL_INT_PARAMETER, x, OS_TOBJ_ID_GL_INT_PARAMETER, y, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_INT_PARAMETER, border);

    SU_END_FUNCTION_WRAPPER(ap_glCopyTextureImage1DEXT);
}

void APIENTRY glCopyTextureImage2DEXT(GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
{
    SU_START_FUNCTION_WRAPPER(ap_glCopyTextureImage2DEXT);

    // Check if stub textures are forced:
    bool areStubTexForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubTexForced = pCurrentThreadRenderContextMonitor->forcedModesManager().isStubForced(AP_OPENGL_FORCED_STUB_TEXTURES_MODE);
    }

    // If we are not in "Force stub textures" mode:
    if (!areStubTexForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glCopyTextureImage2DEXT, (texture, target, level, internalformat, x, y, width, height, border));

        // Log the loaded texture:
        if (NULL != pCurrentThreadRenderContextMonitor)
        {
            bool rcTex = pCurrentThreadRenderContextMonitor->onNamedTextureImageLoaded(texture, target, level, internalformat, width, height, 0, border, GL_GREMEDY_COPIED_FROM_BUFFER, GL_GREMEDY_COPIED_FROM_BUFFER);
            GT_ASSERT(rcTex);
        }
    }

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glCopyTextureImage2DEXT, 9, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_ENUM_PARAMETER, internalformat, OS_TOBJ_ID_GL_INT_PARAMETER, x, OS_TOBJ_ID_GL_INT_PARAMETER, y, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_SIZEI_PARAMETER, height, OS_TOBJ_ID_GL_INT_PARAMETER, border);

    SU_END_FUNCTION_WRAPPER(ap_glCopyTextureImage2DEXT);
}

void APIENTRY glCopyTextureSubImage1DEXT(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width)
{
    SU_START_FUNCTION_WRAPPER(ap_glCopyTextureSubImage1DEXT);

    // Check if stub textures are forced:
    bool areStubTexForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubTexForced = pCurrentThreadRenderContextMonitor->forcedModesManager().isStubForced(AP_OPENGL_FORCED_STUB_TEXTURES_MODE);
    }

    // If we are not in "Force stub textures" mode:
    if (!areStubTexForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glCopyTextureSubImage1DEXT, (texture, target, level, xoffset, x, y, width));

        // Log the loaded sub-texture:
        if (NULL != pCurrentThreadRenderContextMonitor)
        {
            bool rcSubTex = pCurrentThreadRenderContextMonitor->onTextureSubImageLoaded(texture, target, level);
            GT_ASSERT(rcSubTex);
        }
    }

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glCopyTextureSubImage1DEXT, 7, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_INT_PARAMETER, xoffset, OS_TOBJ_ID_GL_INT_PARAMETER, x, OS_TOBJ_ID_GL_INT_PARAMETER, y, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width);

    SU_END_FUNCTION_WRAPPER(ap_glCopyTextureSubImage1DEXT);
}

void APIENTRY glCopyTextureSubImage2DEXT(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
{
    SU_START_FUNCTION_WRAPPER(ap_glCopyTextureSubImage2DEXT);

    // Check if stub textures are forced:
    bool areStubTexForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubTexForced = pCurrentThreadRenderContextMonitor->forcedModesManager().isStubForced(AP_OPENGL_FORCED_STUB_TEXTURES_MODE);
    }

    // If we are not in "Force stub textures" mode:
    if (!areStubTexForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glCopyTextureSubImage2DEXT, (texture, target, level, xoffset, yoffset, x, y, width, height));

        // Log the loaded sub-texture:
        if (NULL != pCurrentThreadRenderContextMonitor)
        {
            bool rcSubTex = pCurrentThreadRenderContextMonitor->onTextureSubImageLoaded(texture, target, level);
            GT_ASSERT(rcSubTex);
        }
    }

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glCopyTextureSubImage2DEXT, 9, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_INT_PARAMETER, xoffset, OS_TOBJ_ID_GL_INT_PARAMETER, yoffset, OS_TOBJ_ID_GL_INT_PARAMETER, x, OS_TOBJ_ID_GL_INT_PARAMETER, y, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_SIZEI_PARAMETER, height);

    SU_END_FUNCTION_WRAPPER(ap_glCopyTextureSubImage2DEXT);
}

void APIENTRY glGetTextureImageEXT(GLuint texture, GLenum target, GLint level, GLenum format, GLenum type, GLvoid* pixels)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetTextureImageEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetTextureImageEXT, 6, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_ENUM_PARAMETER, format, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_P_VOID_PARAMETER, pixels);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetTextureImageEXT, (texture, target, level, format, type, pixels));

    SU_END_FUNCTION_WRAPPER(ap_glGetTextureImageEXT);
}

void APIENTRY glGetTextureParameterfvEXT(GLuint texture, GLenum target, GLenum pname, GLfloat* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetTextureParameterfvEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetTextureParameterfvEXT, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetTextureParameterfvEXT, (texture, target, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetTextureParameterfvEXT);
}

void APIENTRY glGetTextureParameterivEXT(GLuint texture, GLenum target, GLenum pname, GLint* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetTextureParameterivEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetTextureParameterivEXT, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetTextureParameterivEXT, (texture, target, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetTextureParameterivEXT);
}

void APIENTRY glGetTextureLevelParameterfvEXT(GLuint texture, GLenum target, GLint level, GLenum pname, GLfloat* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetTextureLevelParameterfvEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetTextureLevelParameterfvEXT, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetTextureLevelParameterfvEXT, (texture, target, level, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetTextureLevelParameterfvEXT);
}

void APIENTRY glGetTextureLevelParameterivEXT(GLuint texture, GLenum target, GLint level, GLenum pname, GLint* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetTextureLevelParameterivEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetTextureLevelParameterivEXT, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetTextureLevelParameterivEXT, (texture, target, level, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetTextureLevelParameterivEXT);
}

void APIENTRY glTextureImage3DEXT(GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid* pixels)
{
    SU_START_FUNCTION_WRAPPER(ap_glTextureImage3DEXT);

    // Check if stub textures are forced:
    bool areStubTexForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubTexForced = pCurrentThreadRenderContextMonitor->forcedModesManager().isStubForced(AP_OPENGL_FORCED_STUB_TEXTURES_MODE);
    }

    // If we are not in "Force stub textures" mode:
    if (!areStubTexForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glTextureImage3DEXT, (texture, target, level, internalformat, width, height, depth, border, format, type, pixels));

        // Log the loaded texture:
        if (NULL != pCurrentThreadRenderContextMonitor)
        {
            bool rcTex = pCurrentThreadRenderContextMonitor->onNamedTextureImageLoaded(texture, target, level, internalformat, width, height, depth, border, format, type);
            GT_ASSERT(rcTex);
        }
    }

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTextureImage3DEXT, 11, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_ENUM_PARAMETER, internalformat, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_SIZEI_PARAMETER, height, OS_TOBJ_ID_GL_SIZEI_PARAMETER, depth, OS_TOBJ_ID_GL_INT_PARAMETER, border, OS_TOBJ_ID_GL_ENUM_PARAMETER, format, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_P_VOID_PARAMETER, pixels);

    SU_END_FUNCTION_WRAPPER(ap_glTextureImage3DEXT);
}

void APIENTRY glTextureSubImage3DEXT(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid* pixels)
{
    SU_START_FUNCTION_WRAPPER(ap_glTextureSubImage3DEXT);

    // Check if stub textures are forced:
    bool areStubTexForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubTexForced = pCurrentThreadRenderContextMonitor->forcedModesManager().isStubForced(AP_OPENGL_FORCED_STUB_TEXTURES_MODE);
    }

    // If we are not in "Force stub textures" mode:
    if (!areStubTexForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glTextureSubImage3DEXT, (texture, target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels));

        // Log the loaded sub-texture:
        if (NULL != pCurrentThreadRenderContextMonitor)
        {
            bool rcSubTex = pCurrentThreadRenderContextMonitor->onTextureSubImageLoaded(texture, target, level);
            GT_ASSERT(rcSubTex);
        }
    }

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTextureSubImage3DEXT, 12, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_INT_PARAMETER, xoffset, OS_TOBJ_ID_GL_INT_PARAMETER, yoffset, OS_TOBJ_ID_GL_INT_PARAMETER, zoffset, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_SIZEI_PARAMETER, height, OS_TOBJ_ID_GL_SIZEI_PARAMETER, depth, OS_TOBJ_ID_GL_ENUM_PARAMETER, format, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_P_VOID_PARAMETER, pixels);

    SU_END_FUNCTION_WRAPPER(ap_glTextureSubImage3DEXT);
}

void APIENTRY glCopyTextureSubImage3DEXT(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height)
{
    SU_START_FUNCTION_WRAPPER(ap_glCopyTextureSubImage3DEXT);

    // Check if stub textures are forced:
    bool areStubTexForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubTexForced = pCurrentThreadRenderContextMonitor->forcedModesManager().isStubForced(AP_OPENGL_FORCED_STUB_TEXTURES_MODE);
    }

    // If we are not in "Force stub textures" mode:
    if (!areStubTexForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glCopyTextureSubImage3DEXT, (texture, target, level, xoffset, yoffset, zoffset, x, y, width, height));

        // Log the loaded sub-texture:
        if (NULL != pCurrentThreadRenderContextMonitor)
        {
            bool rcSubTex = pCurrentThreadRenderContextMonitor->onTextureSubImageLoaded(texture, target, level);
            GT_ASSERT(rcSubTex);
        }
    }

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glCopyTextureSubImage3DEXT, 10, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_INT_PARAMETER, xoffset, OS_TOBJ_ID_GL_INT_PARAMETER, yoffset, OS_TOBJ_ID_GL_INT_PARAMETER, zoffset, OS_TOBJ_ID_GL_INT_PARAMETER, x, OS_TOBJ_ID_GL_INT_PARAMETER, y, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_SIZEI_PARAMETER, height);

    SU_END_FUNCTION_WRAPPER(ap_glCopyTextureSubImage3DEXT);
}

void APIENTRY glMultiTexParameterfEXT(GLenum texunit, GLenum target, GLenum pname, GLfloat param)
{
    SU_START_FUNCTION_WRAPPER(ap_glMultiTexParameterfEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexParameterfEXT, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, texunit, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_FLOAT_PARAMETER, param);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexParameterfEXT, (texunit, target, pname, param));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexParameterfEXT);
}

void APIENTRY glMultiTexParameterfvEXT(GLenum texunit, GLenum target, GLenum pname, const GLfloat* param)
{
    SU_START_FUNCTION_WRAPPER(ap_glMultiTexParameterfvEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexParameterfvEXT, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, texunit, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, param);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexParameterfvEXT, (texunit, target, pname, param));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexParameterfvEXT);
}

void APIENTRY glMultiTexParameteriEXT(GLenum texunit, GLenum target, GLenum pname, GLint param)
{
    SU_START_FUNCTION_WRAPPER(ap_glMultiTexParameteriEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexParameteriEXT, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, texunit, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_INT_PARAMETER, param);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexParameteriEXT, (texunit, target, pname, param));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexParameteriEXT);
}

void APIENTRY glMultiTexParameterivEXT(GLenum texunit, GLenum target, GLenum pname, const GLint* param)
{
    SU_START_FUNCTION_WRAPPER(ap_glMultiTexParameterivEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexParameterivEXT, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, texunit, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_PARAMETER, param);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexParameterivEXT, (texunit, target, pname, param));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexParameterivEXT);
}

void APIENTRY glMultiTexImage1DEXT(GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid* pixels)
{
    SU_START_FUNCTION_WRAPPER(ap_glMultiTexImage1DEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexImage1DEXT, 9, OS_TOBJ_ID_GL_ENUM_PARAMETER, texunit, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_ENUM_PARAMETER, internalformat, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_INT_PARAMETER, border, OS_TOBJ_ID_GL_ENUM_PARAMETER, format, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_P_VOID_PARAMETER, pixels);

    // Check if stub textures are forced:
    bool areStubTexForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubTexForced = pCurrentThreadRenderContextMonitor->forcedModesManager().isStubForced(AP_OPENGL_FORCED_STUB_TEXTURES_MODE);
    }

    // If we are not in "Force stub textures" mode:
    if (!areStubTexForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glMultiTexImage1DEXT, (texunit, target, level, internalformat, width, border, format, type, pixels));

        // Log the loaded texture:
        if (NULL != pCurrentThreadRenderContextMonitor)
        {
            bool rcTex = pCurrentThreadRenderContextMonitor->onMultiTextureImageLoaded(texunit, target, level, internalformat, width, 0, 0, border, format, type);
            GT_ASSERT(rcTex);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexImage1DEXT);
}

void APIENTRY glMultiTexImage2DEXT(GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid* pixels)
{
    SU_START_FUNCTION_WRAPPER(ap_glMultiTexImage2DEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexImage2DEXT, 10, OS_TOBJ_ID_GL_ENUM_PARAMETER, texunit, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_ENUM_PARAMETER, internalformat, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_SIZEI_PARAMETER, height, OS_TOBJ_ID_GL_INT_PARAMETER, border, OS_TOBJ_ID_GL_ENUM_PARAMETER, format, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_P_VOID_PARAMETER, pixels);

    // Check if stub textures are forced:
    bool areStubTexForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubTexForced = pCurrentThreadRenderContextMonitor->forcedModesManager().isStubForced(AP_OPENGL_FORCED_STUB_TEXTURES_MODE);
    }

    // If we are not in "Force stub textures" mode:
    if (!areStubTexForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glMultiTexImage2DEXT, (texunit, target, level, internalformat, width, height, border, format, type, pixels));

        // Log the loaded texture:
        if (NULL != pCurrentThreadRenderContextMonitor)
        {
            bool rcTex = pCurrentThreadRenderContextMonitor->onMultiTextureImageLoaded(texunit, target, level, internalformat, width, height, 0, border, format, type);
            GT_ASSERT(rcTex);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexImage2DEXT);
}

void APIENTRY glMultiTexSubImage1DEXT(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid* pixels)
{
    SU_START_FUNCTION_WRAPPER(ap_glMultiTexSubImage1DEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexSubImage1DEXT, 8, OS_TOBJ_ID_GL_ENUM_PARAMETER, texunit, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_INT_PARAMETER, xoffset, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_ENUM_PARAMETER, format, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_P_VOID_PARAMETER, pixels);

    // Check if stub textures are forced:
    bool areStubTexForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubTexForced = pCurrentThreadRenderContextMonitor->forcedModesManager().isStubForced(AP_OPENGL_FORCED_STUB_TEXTURES_MODE);
    }

    // If we are not in "Force stub textures" mode:
    if (!areStubTexForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glMultiTexSubImage1DEXT, (texunit, target, level, xoffset, width, format, type, pixels));

        // Log the loaded texture:
        if (NULL != pCurrentThreadRenderContextMonitor)
        {
            bool rcTex = pCurrentThreadRenderContextMonitor->onMultiTextureSubImageLoaded(texunit, target, level);
            GT_ASSERT(rcTex);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexSubImage1DEXT);
}

void APIENTRY glMultiTexSubImage2DEXT(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid* pixels)
{
    SU_START_FUNCTION_WRAPPER(ap_glMultiTexSubImage2DEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexSubImage2DEXT, 10, OS_TOBJ_ID_GL_ENUM_PARAMETER, texunit, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_INT_PARAMETER, xoffset, OS_TOBJ_ID_GL_INT_PARAMETER, yoffset, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_SIZEI_PARAMETER, height, OS_TOBJ_ID_GL_ENUM_PARAMETER, format, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_P_VOID_PARAMETER, pixels);

    // Check if stub textures are forced:
    bool areStubTexForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubTexForced = pCurrentThreadRenderContextMonitor->forcedModesManager().isStubForced(AP_OPENGL_FORCED_STUB_TEXTURES_MODE);
    }

    // If we are not in "Force stub textures" mode:
    if (!areStubTexForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glMultiTexSubImage2DEXT, (texunit, target, level, xoffset, yoffset, width, height, format, type, pixels));

        // Log the loaded texture:
        if (NULL != pCurrentThreadRenderContextMonitor)
        {
            bool rcTex = pCurrentThreadRenderContextMonitor->onMultiTextureSubImageLoaded(texunit, target, level);
            GT_ASSERT(rcTex);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexSubImage2DEXT);
}

void APIENTRY glCopyMultiTexImage1DEXT(GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border)
{
    SU_START_FUNCTION_WRAPPER(ap_glCopyMultiTexImage1DEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glCopyMultiTexImage1DEXT, 8, OS_TOBJ_ID_GL_ENUM_PARAMETER, texunit, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_ENUM_PARAMETER, internalformat, OS_TOBJ_ID_GL_INT_PARAMETER, x, OS_TOBJ_ID_GL_INT_PARAMETER, y, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_INT_PARAMETER, border);

    // Check if stub textures are forced:
    bool areStubTexForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubTexForced = pCurrentThreadRenderContextMonitor->forcedModesManager().isStubForced(AP_OPENGL_FORCED_STUB_TEXTURES_MODE);
    }

    // If we are not in "Force stub textures" mode:
    if (!areStubTexForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glCopyMultiTexImage1DEXT, (texunit, target, level, internalformat, x, y, width, border));

        // Log the loaded texture:
        if (NULL != pCurrentThreadRenderContextMonitor)
        {
            bool rcTex = pCurrentThreadRenderContextMonitor->onMultiTextureImageLoaded(texunit, target, level, internalformat, width, 0, 0, border, GL_GREMEDY_COPIED_FROM_BUFFER, GL_GREMEDY_COPIED_FROM_BUFFER);
            GT_ASSERT(rcTex);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glCopyMultiTexImage1DEXT);
}

void APIENTRY glCopyMultiTexImage2DEXT(GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
{
    SU_START_FUNCTION_WRAPPER(ap_glCopyMultiTexImage2DEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glCopyMultiTexImage2DEXT, 9, OS_TOBJ_ID_GL_ENUM_PARAMETER, texunit, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_ENUM_PARAMETER, internalformat, OS_TOBJ_ID_GL_INT_PARAMETER, x, OS_TOBJ_ID_GL_INT_PARAMETER, y, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_SIZEI_PARAMETER, height, OS_TOBJ_ID_GL_INT_PARAMETER, border);

    // Check if stub textures are forced:
    bool areStubTexForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubTexForced = pCurrentThreadRenderContextMonitor->forcedModesManager().isStubForced(AP_OPENGL_FORCED_STUB_TEXTURES_MODE);
    }

    // If we are not in "Force stub textures" mode:
    if (!areStubTexForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glCopyMultiTexImage2DEXT, (texunit, target, level, internalformat, x, y, width, height, border));

        // Log the loaded texture:
        if (NULL != pCurrentThreadRenderContextMonitor)
        {
            bool rcTex = pCurrentThreadRenderContextMonitor->onMultiTextureImageLoaded(texunit, target, level, internalformat, width, height, 0, border, GL_GREMEDY_COPIED_FROM_BUFFER, GL_GREMEDY_COPIED_FROM_BUFFER);
            GT_ASSERT(rcTex);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glCopyMultiTexImage2DEXT);
}

void APIENTRY glCopyMultiTexSubImage1DEXT(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width)
{
    SU_START_FUNCTION_WRAPPER(ap_glCopyMultiTexSubImage1DEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glCopyMultiTexSubImage1DEXT, 7, OS_TOBJ_ID_GL_ENUM_PARAMETER, texunit, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_INT_PARAMETER, xoffset, OS_TOBJ_ID_GL_INT_PARAMETER, x, OS_TOBJ_ID_GL_INT_PARAMETER, y, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width);

    // Check if stub textures are forced:
    bool areStubTexForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubTexForced = pCurrentThreadRenderContextMonitor->forcedModesManager().isStubForced(AP_OPENGL_FORCED_STUB_TEXTURES_MODE);
    }

    // If we are not in "Force stub textures" mode:
    if (!areStubTexForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glCopyMultiTexSubImage1DEXT, (texunit, target, level, xoffset, x, y, width));

        // Log the loaded sub-texture:
        if (NULL != pCurrentThreadRenderContextMonitor)
        {
            bool rcSubTex = pCurrentThreadRenderContextMonitor->onMultiTextureSubImageLoaded(texunit, target, level);
            GT_ASSERT(rcSubTex);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glCopyMultiTexSubImage1DEXT);
}

void APIENTRY glCopyMultiTexSubImage2DEXT(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
{
    SU_START_FUNCTION_WRAPPER(ap_glCopyMultiTexSubImage2DEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glCopyMultiTexSubImage2DEXT, 9, OS_TOBJ_ID_GL_ENUM_PARAMETER, texunit, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_INT_PARAMETER, xoffset, OS_TOBJ_ID_GL_INT_PARAMETER, yoffset, OS_TOBJ_ID_GL_INT_PARAMETER, x, OS_TOBJ_ID_GL_INT_PARAMETER, y, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_SIZEI_PARAMETER, height);

    // Check if stub textures are forced:
    bool areStubTexForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubTexForced = pCurrentThreadRenderContextMonitor->forcedModesManager().isStubForced(AP_OPENGL_FORCED_STUB_TEXTURES_MODE);
    }

    // If we are not in "Force stub textures" mode:
    if (!areStubTexForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glCopyMultiTexSubImage2DEXT, (texunit, target, level, xoffset, yoffset, x, y, width, height));

        // Log the loaded sub-texture:
        if (NULL != pCurrentThreadRenderContextMonitor)
        {
            bool rcSubTex = pCurrentThreadRenderContextMonitor->onMultiTextureSubImageLoaded(texunit, target, level);
            GT_ASSERT(rcSubTex);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glCopyMultiTexSubImage2DEXT);
}

void APIENTRY glGetMultiTexImageEXT(GLenum texunit, GLenum target, GLint level, GLenum format, GLenum type, GLvoid* pixels)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetMultiTexImageEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetMultiTexImageEXT, 6, OS_TOBJ_ID_GL_ENUM_PARAMETER, texunit, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_ENUM_PARAMETER, format, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_P_VOID_PARAMETER, pixels);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetMultiTexImageEXT, (texunit, target, level, format, type, pixels));

    SU_END_FUNCTION_WRAPPER(ap_glGetMultiTexImageEXT);
}

void APIENTRY glGetMultiTexParameterfvEXT(GLenum texunit, GLenum target, GLenum pname, GLfloat* param)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetMultiTexParameterfvEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetMultiTexParameterfvEXT, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, texunit, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, param);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetMultiTexParameterfvEXT, (texunit, target, pname, param));

    SU_END_FUNCTION_WRAPPER(ap_glGetMultiTexParameterfvEXT);
}

void APIENTRY glGetMultiTexParameterivEXT(GLenum texunit, GLenum target, GLenum pname, GLint* param)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetMultiTexParameterivEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetMultiTexParameterivEXT, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, texunit, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_PARAMETER, param);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetMultiTexParameterivEXT, (texunit, target, pname, param));

    SU_END_FUNCTION_WRAPPER(ap_glGetMultiTexParameterivEXT);
}

void APIENTRY glGetMultiTexLevelParameterfvEXT(GLenum texunit, GLenum target, GLint level, GLenum pname, GLfloat* param)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetMultiTexLevelParameterfvEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetMultiTexLevelParameterfvEXT, 5, OS_TOBJ_ID_GL_ENUM_PARAMETER, texunit, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, param);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetMultiTexLevelParameterfvEXT, (texunit, target, level, pname, param));

    SU_END_FUNCTION_WRAPPER(ap_glGetMultiTexLevelParameterfvEXT);
}

void APIENTRY glGetMultiTexLevelParameterivEXT(GLenum texunit, GLenum target, GLint level, GLenum pname, GLint* param)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetMultiTexLevelParameterivEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetMultiTexLevelParameterivEXT, 5, OS_TOBJ_ID_GL_ENUM_PARAMETER, texunit, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_PARAMETER, param);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetMultiTexLevelParameterivEXT, (texunit, target, level, pname, param));

    SU_END_FUNCTION_WRAPPER(ap_glGetMultiTexLevelParameterivEXT);
}

void APIENTRY glMultiTexImage3DEXT(GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid* pixels)
{
    SU_START_FUNCTION_WRAPPER(ap_glMultiTexImage3DEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexImage3DEXT, 11, OS_TOBJ_ID_GL_ENUM_PARAMETER, texunit, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_ENUM_PARAMETER, internalformat, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_SIZEI_PARAMETER, height, OS_TOBJ_ID_GL_SIZEI_PARAMETER, depth, OS_TOBJ_ID_GL_INT_PARAMETER, border, OS_TOBJ_ID_GL_ENUM_PARAMETER, format, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_P_VOID_PARAMETER, pixels);

    // Check if stub textures are forced:
    bool areStubTexForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubTexForced = pCurrentThreadRenderContextMonitor->forcedModesManager().isStubForced(AP_OPENGL_FORCED_STUB_TEXTURES_MODE);
    }

    // If we are not in "Force stub textures" mode:
    if (!areStubTexForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glMultiTexImage3DEXT, (texunit, target, level, internalformat, width, height, depth, border, format, type, pixels));

        // Log the loaded texture:
        if (NULL != pCurrentThreadRenderContextMonitor)
        {
            bool rcTex = pCurrentThreadRenderContextMonitor->onMultiTextureImageLoaded(texunit, target, level, internalformat, width, height, depth, border, format, type);
            GT_ASSERT(rcTex);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexImage3DEXT);
}

void APIENTRY glMultiTexSubImage3DEXT(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid* pixels)
{
    SU_START_FUNCTION_WRAPPER(ap_glMultiTexSubImage3DEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexSubImage3DEXT, 13, OS_TOBJ_ID_GL_ENUM_PARAMETER, texunit, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_INT_PARAMETER, xoffset, OS_TOBJ_ID_GL_INT_PARAMETER, yoffset, OS_TOBJ_ID_GL_INT_PARAMETER, zoffset, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_SIZEI_PARAMETER, height, OS_TOBJ_ID_GL_SIZEI_PARAMETER, depth, OS_TOBJ_ID_GL_ENUM_PARAMETER, format, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_P_VOID_PARAMETER, pixels);

    // Check if stub textures are forced:
    bool areStubTexForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubTexForced = pCurrentThreadRenderContextMonitor->forcedModesManager().isStubForced(AP_OPENGL_FORCED_STUB_TEXTURES_MODE);
    }

    // If we are not in "Force stub textures" mode:
    if (!areStubTexForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glMultiTexSubImage3DEXT, (texunit, target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels));

        // Log the loaded texture:
        if (NULL != pCurrentThreadRenderContextMonitor)
        {
            bool rcTex = pCurrentThreadRenderContextMonitor->onMultiTextureSubImageLoaded(texunit, target, level);
            GT_ASSERT(rcTex);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexSubImage3DEXT);
}

void APIENTRY glCopyMultiTexSubImage3DEXT(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height)
{
    SU_START_FUNCTION_WRAPPER(ap_glCopyMultiTexSubImage3DEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glCopyMultiTexSubImage3DEXT, 10, OS_TOBJ_ID_GL_ENUM_PARAMETER, texunit, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_INT_PARAMETER, xoffset, OS_TOBJ_ID_GL_INT_PARAMETER, yoffset, OS_TOBJ_ID_GL_INT_PARAMETER, zoffset, OS_TOBJ_ID_GL_INT_PARAMETER, x, OS_TOBJ_ID_GL_INT_PARAMETER, y, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_SIZEI_PARAMETER, height);

    // Check if stub textures are forced:
    bool areStubTexForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubTexForced = pCurrentThreadRenderContextMonitor->forcedModesManager().isStubForced(AP_OPENGL_FORCED_STUB_TEXTURES_MODE);
    }

    // If we are not in "Force stub textures" mode:
    if (!areStubTexForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glCopyMultiTexSubImage3DEXT, (texunit, target, level, xoffset, yoffset, zoffset, x, y, width, height));

        // Log the loaded sub-texture:
        if (NULL != pCurrentThreadRenderContextMonitor)
        {
            bool rcSubTex = pCurrentThreadRenderContextMonitor->onTextureSubImageLoaded(target, level);
            GT_ASSERT(rcSubTex);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glCopyMultiTexSubImage3DEXT);
}

void APIENTRY glBindMultiTextureEXT(GLenum texunit, GLenum target, GLuint texture)
{
    SU_START_FUNCTION_WRAPPER(ap_glBindMultiTextureEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glBindMultiTextureEXT, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, texunit, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_UINT_PARAMETER, texture);

    // Check if stub textures are forced:
    bool areStubTexForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubTexForced = pCurrentThreadRenderContextMonitor->forcedModesManager().isStubForced(AP_OPENGL_FORCED_STUB_TEXTURES_MODE);
    }

    // If we are not in "Force stub textures" mode:
    if (!areStubTexForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glBindMultiTextureEXT, (texunit, target, texture));
    }
    else
    {
        // Force the stub texture to be the bind texture:
        GLuint forcedTxName = gs_stat_openGLMonitorInstance.forcedStubTextureName(target);
        SU_CALL_EXTENSION_FUNC(glBindMultiTextureEXT, (texunit, target, forcedTxName));
    }

    // Mark that a texture was bound:
    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        pCurrentThreadRenderContextMonitor->onMultiTextureTargetBind(texunit, target, texture);
    }

    SU_END_FUNCTION_WRAPPER(ap_glBindMultiTextureEXT);
}

// TO_DO: GL_EXT_direct_state_access
void APIENTRY glEnableClientStateIndexedEXT(GLenum array, GLuint index)
{
    SU_START_FUNCTION_WRAPPER(ap_glEnableClientStateIndexedEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glEnableClientStateIndexedEXT, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, array, OS_TOBJ_ID_GL_UINT_PARAMETER, index);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glEnableClientStateIndexedEXT, (array, index));

    SU_END_FUNCTION_WRAPPER(ap_glEnableClientStateIndexedEXT);
}

// TO_DO: GL_EXT_direct_state_access
void APIENTRY glDisableClientStateIndexedEXT(GLenum array, GLuint index)
{
    SU_START_FUNCTION_WRAPPER(ap_glDisableClientStateIndexedEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glDisableClientStateIndexedEXT, 2, OS_TOBJ_ID_GL_ENUM_PARAMETER, array, OS_TOBJ_ID_GL_UINT_PARAMETER, index);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glDisableClientStateIndexedEXT, (array, index));

    SU_END_FUNCTION_WRAPPER(ap_glDisableClientStateIndexedEXT);
}

void APIENTRY glMultiTexCoordPointerEXT(GLenum texunit, GLint size, GLenum type, GLsizei stride, const GLvoid* pointer)
{
    SU_START_FUNCTION_WRAPPER(ap_glMultiTexCoordPointerEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexCoordPointerEXT, 5, OS_TOBJ_ID_GL_ENUM_PARAMETER, texunit, OS_TOBJ_ID_GL_INT_PARAMETER, size, OS_TOBJ_ID_GL_ENUM_PARAMETER, type, OS_TOBJ_ID_GL_SIZEI_PARAMETER, stride, OS_TOBJ_ID_GL_P_VOID_PARAMETER, pointer);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexCoordPointerEXT, (texunit, size, type, stride, pointer));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexCoordPointerEXT);
}

void APIENTRY glMultiTexEnvfEXT(GLenum texunit, GLenum target, GLenum pname, GLfloat param)
{
    SU_START_FUNCTION_WRAPPER(ap_glMultiTexEnvfEXT);

    if (pname == GL_TEXTURE_ENV_MODE)
    {
        // In this case the parameter is not a floating point value, but rather an enumrator:
        GLenum paramAsEnum = (GLenum)param;
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexEnvfEXT, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, texunit, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_ENUM_PARAMETER, paramAsEnum);
    }
    else
    {
        // Log the call to this function:
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexEnvfEXT, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, texunit, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_FLOAT_PARAMETER, param);
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexEnvfEXT, (texunit, target, pname, param));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexEnvfEXT);
}

void APIENTRY glMultiTexEnvfvEXT(GLenum texunit, GLenum target, GLenum pname, const GLfloat* param)
{
    SU_START_FUNCTION_WRAPPER(ap_glMultiTexEnvfvEXT);

    if (pname == GL_TEXTURE_ENV_MODE)
    {
        GLenum paramAsEnum = (GLenum) * param;
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexEnvfvEXT, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, texunit, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_ENUM_PARAMETER, paramAsEnum);

    }
    else if (pname == GL_TEXTURE_ENV_COLOR)
    {
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexEnvfvEXT, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, texunit, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_FLOAT_PARAMETER, 4, param);
    }
    else
    {
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexEnvfvEXT, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, texunit, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, param);
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexEnvfvEXT, (texunit, target, pname, param));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexEnvfvEXT);
}

void APIENTRY glMultiTexEnviEXT(GLenum texunit, GLenum target, GLenum pname, GLint param)
{
    SU_START_FUNCTION_WRAPPER(ap_glMultiTexEnviEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexEnviEXT, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, texunit, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_INT_PARAMETER, param);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexEnviEXT, (texunit, target, pname, param));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexEnviEXT);
}

void APIENTRY glMultiTexEnvivEXT(GLenum texunit, GLenum target, GLenum pname, const GLint* param)
{
    SU_START_FUNCTION_WRAPPER(ap_glMultiTexEnvivEXT);

    if (pname == GL_TEXTURE_ENV_MODE)
    {
        GLenum paramAsEnum = (GLenum) * param;
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexEnvivEXT, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, texunit, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_ENUM_PARAMETER, paramAsEnum);
    }
    else if (pname == GL_TEXTURE_ENV_COLOR)
    {
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexEnvivEXT, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, texunit, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_INT_PARAMETER, 4, param);
    }
    else
    {
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexEnvivEXT, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, texunit, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_PARAMETER, param);
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexEnvivEXT, (texunit, target, pname, param));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexEnvivEXT);
}

void APIENTRY glMultiTexGendEXT(GLenum texunit, GLenum coord, GLenum pname, GLdouble param)
{
    SU_START_FUNCTION_WRAPPER(ap_glMultiTexGendEXT);

    // Log the call to this function:
    // Get the texture coordinates as strings:
    const char* coordAsString = gsTextureCoordinateString(coord);
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexGendEXT, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, texunit, OS_TOBJ_ID_STRING_PARAMETER, coordAsString, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, param);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexGendEXT, (texunit, coord, pname, param));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexGendEXT);
}

void APIENTRY glMultiTexGendvEXT(GLenum texunit, GLenum coord, GLenum pname, const GLdouble* param)
{
    SU_START_FUNCTION_WRAPPER(ap_glMultiTexGendvEXT);

    // Get the texture coordinates as strings:
    const char* coordAsString = gsTextureCoordinateString(coord);

    if (pname == GL_TEXTURE_GEN_MODE)
    {
        GLenum paramAsEnum = (GLenum) * param;
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexGendvEXT, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, texunit, OS_TOBJ_ID_STRING_PARAMETER, coordAsString, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_ENUM_PARAMETER, paramAsEnum);

    }
    else if ((pname == GL_OBJECT_PLANE) || (pname == GL_EYE_PLANE))
    {
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexGendvEXT, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, texunit, OS_TOBJ_ID_GL_ENUM_PARAMETER, coord, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, 4, param);
    }
    else
    {
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexGendvEXT, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, texunit, OS_TOBJ_ID_GL_ENUM_PARAMETER, coord, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_DOUBLE_PARAMETER, param);
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexGendvEXT, (texunit, coord, pname, param));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexGendvEXT);
}

void APIENTRY glMultiTexGenfEXT(GLenum texunit, GLenum coord, GLenum pname, GLfloat param)
{
    SU_START_FUNCTION_WRAPPER(ap_glMultiTexGenfEXT);

    // Log the call to this function:
    const char* coordAsString = gsTextureCoordinateString(coord);
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexGenfEXT, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, texunit, OS_TOBJ_ID_STRING_PARAMETER, coordAsString, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_FLOAT_PARAMETER, param);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexGenfEXT, (texunit, coord, pname, param));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexGenfEXT);
}

void APIENTRY glMultiTexGenfvEXT(GLenum texunit, GLenum coord, GLenum pname, const GLfloat* param)
{
    SU_START_FUNCTION_WRAPPER(ap_glMultiTexGenfvEXT);

    const char* coordAsString = gsTextureCoordinateString(coord);

    if (pname == GL_TEXTURE_GEN_MODE)
    {
        GLenum paramAsEnum = (GLenum) * param;
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexGenfvEXT, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, texunit, OS_TOBJ_ID_STRING_PARAMETER, coordAsString, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_ENUM_PARAMETER, paramAsEnum);

    }
    else if ((pname == GL_OBJECT_PLANE) || (pname == GL_EYE_PLANE))
    {
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexGenfvEXT, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, texunit, OS_TOBJ_ID_STRING_PARAMETER, coordAsString, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_FLOAT_PARAMETER, 4, param);

    }
    else
    {
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexGenfvEXT, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, texunit, OS_TOBJ_ID_STRING_PARAMETER, coordAsString, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, param);
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexGenfvEXT, (texunit, coord, pname, param));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexGenfvEXT);
}

void APIENTRY glMultiTexGeniEXT(GLenum texunit, GLenum coord, GLenum pname, GLint param)
{
    SU_START_FUNCTION_WRAPPER(ap_glMultiTexGeniEXT);

    // Log the call to this function:
    const char* coordAsString = gsTextureCoordinateString(coord);
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexGeniEXT, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, texunit, OS_TOBJ_ID_STRING_PARAMETER, coordAsString, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_INT_PARAMETER, param);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexGeniEXT, (texunit, coord, pname, param));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexGeniEXT);
}

void APIENTRY glMultiTexGenivEXT(GLenum texunit, GLenum coord, GLenum pname, const GLint* param)
{
    SU_START_FUNCTION_WRAPPER(ap_glMultiTexGenivEXT);

    const char* coordAsString = gsTextureCoordinateString(coord);

    if (pname == GL_TEXTURE_GEN_MODE)
    {
        GLenum paramAsEnum = (GLenum) * param;
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexGenivEXT, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, texunit, OS_TOBJ_ID_STRING_PARAMETER, coordAsString, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_ENUM_PARAMETER, paramAsEnum);
    }
    else if ((pname == GL_OBJECT_PLANE) || (pname == GL_EYE_PLANE))
    {
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexGenivEXT, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, texunit, OS_TOBJ_ID_STRING_PARAMETER, coordAsString, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_INT_PARAMETER, 4, param);

    }
    else
    {
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexGenivEXT, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, texunit, OS_TOBJ_ID_STRING_PARAMETER, coordAsString, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_PARAMETER, param);

    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexGenivEXT, (texunit, coord, pname, param));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexGenivEXT);
}

void APIENTRY glGetMultiTexEnvfvEXT(GLenum texunit, GLenum coord, GLenum pname, GLfloat* param)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetMultiTexEnvfvEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetMultiTexEnvfvEXT, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, texunit, OS_TOBJ_ID_GL_ENUM_PARAMETER, coord, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, param);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetMultiTexEnvfvEXT, (texunit, coord, pname, param));

    SU_END_FUNCTION_WRAPPER(ap_glGetMultiTexEnvfvEXT);
}

void APIENTRY glGetMultiTexEnvivEXT(GLenum texunit, GLenum coord, GLenum pname, GLint* param)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetMultiTexEnvivEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetMultiTexEnvivEXT, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, texunit, OS_TOBJ_ID_GL_ENUM_PARAMETER, coord, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_PARAMETER, param);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetMultiTexEnvivEXT, (texunit, coord, pname, param));

    SU_END_FUNCTION_WRAPPER(ap_glGetMultiTexEnvivEXT);
}

void APIENTRY glGetMultiTexGendvEXT(GLenum texunit, GLenum coord, GLenum pname, GLdouble* param)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetMultiTexGendvEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetMultiTexGendvEXT, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, texunit, OS_TOBJ_ID_GL_ENUM_PARAMETER, coord, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_DOUBLE_PARAMETER, param);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetMultiTexGendvEXT, (texunit, coord, pname, param));

    SU_END_FUNCTION_WRAPPER(ap_glGetMultiTexGendvEXT);
}

void APIENTRY glGetMultiTexGenfvEXT(GLenum texunit, GLenum coord, GLenum pname, GLfloat* param)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetMultiTexGenfvEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetMultiTexGenfvEXT, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, texunit, OS_TOBJ_ID_GL_ENUM_PARAMETER, coord, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, param);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetMultiTexGenfvEXT, (texunit, coord, pname, param));

    SU_END_FUNCTION_WRAPPER(ap_glGetMultiTexGenfvEXT);
}

void APIENTRY glGetMultiTexGenivEXT(GLenum texunit, GLenum coord, GLenum pname, GLint* param)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetMultiTexGenivEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetMultiTexGenivEXT, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, texunit, OS_TOBJ_ID_GL_ENUM_PARAMETER, coord, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_PARAMETER, param);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetMultiTexGenivEXT, (texunit, coord, pname, param));

    SU_END_FUNCTION_WRAPPER(ap_glGetMultiTexGenivEXT);
}

void APIENTRY glGetFloatIndexedvEXT(GLenum pname, GLuint index, GLfloat* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetFloatIndexedvEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetFloatIndexedvEXT, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetFloatIndexedvEXT, (pname, index, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetFloatIndexedvEXT);
}

void APIENTRY glGetDoubleIndexedvEXT(GLenum pname, GLuint index, GLdouble* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetDoubleIndexedvEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetDoubleIndexedvEXT, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_P_DOUBLE_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetDoubleIndexedvEXT, (pname, index, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetDoubleIndexedvEXT);
}

void APIENTRY glGetPointerIndexedvEXT(GLenum pname, GLuint index, GLvoid** params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetPointerIndexedvEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetPointerIndexedvEXT, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_PP_VOID_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetPointerIndexedvEXT, (pname, index, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetPointerIndexedvEXT);
}

void APIENTRY glCompressedTextureImage3DEXT(GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imagesize, const GLvoid* data)
{
    SU_START_FUNCTION_WRAPPER(ap_glCompressedTextureImage3DEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glCompressedTextureImage3DEXT, 10, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_ENUM_PARAMETER, internalformat, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_SIZEI_PARAMETER, height, OS_TOBJ_ID_GL_SIZEI_PARAMETER, depth, OS_TOBJ_ID_GL_INT_PARAMETER, border, OS_TOBJ_ID_GL_SIZEI_PARAMETER, imagesize, OS_TOBJ_ID_GL_P_VOID_PARAMETER, data);

    // Check if stub textures are forced:
    bool areStubTexForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubTexForced = pCurrentThreadRenderContextMonitor->forcedModesManager().isStubForced(AP_OPENGL_FORCED_STUB_TEXTURES_MODE);
    }

    // If we are not in "Force stub textures" mode:
    if (!areStubTexForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glCompressedTextureImage3DEXT, (texture, target, level, internalformat, width, height, depth, border, imagesize, data));

        // Log the loaded texture:
        if (NULL != pCurrentThreadRenderContextMonitor)
        {
            bool rcTex = pCurrentThreadRenderContextMonitor->onTextureImageLoaded(target, level, internalformat, width, height, depth, border, 0, 0);
            GT_ASSERT(rcTex);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glCompressedTextureImage3DEXT);
}

void APIENTRY glCompressedTextureImage2DEXT(GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imagesize, const GLvoid* data)
{
    SU_START_FUNCTION_WRAPPER(ap_glCompressedTextureImage2DEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glCompressedTextureImage2DEXT, 9, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_ENUM_PARAMETER, internalformat, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_SIZEI_PARAMETER, height, OS_TOBJ_ID_GL_INT_PARAMETER, border, OS_TOBJ_ID_GL_SIZEI_PARAMETER, imagesize, OS_TOBJ_ID_GL_P_VOID_PARAMETER, data);

    // Check if stub textures are forced:
    bool areStubTexForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubTexForced = pCurrentThreadRenderContextMonitor->forcedModesManager().isStubForced(AP_OPENGL_FORCED_STUB_TEXTURES_MODE);
    }

    // If we are not in "Force stub textures" mode:
    if (!areStubTexForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glCompressedTextureImage2DEXT, (texture, target, level, internalformat, width, height, border, imagesize, data));

        // Log the loaded texture:
        if (NULL != pCurrentThreadRenderContextMonitor)
        {
            bool rcTex = pCurrentThreadRenderContextMonitor->onTextureImageLoaded(target, level, internalformat, width, height, 0, border, 0, 0);
            GT_ASSERT(rcTex);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glCompressedTextureImage2DEXT);
}

void APIENTRY glCompressedTextureImage1DEXT(GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imagesize, const GLvoid* data)
{
    SU_START_FUNCTION_WRAPPER(ap_glCompressedTextureImage1DEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glCompressedTextureImage1DEXT, 8, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_ENUM_PARAMETER, internalformat, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_INT_PARAMETER, border, OS_TOBJ_ID_GL_SIZEI_PARAMETER, imagesize, OS_TOBJ_ID_GL_P_VOID_PARAMETER, data);

    // Check if stub textures are forced:
    bool areStubTexForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubTexForced = pCurrentThreadRenderContextMonitor->forcedModesManager().isStubForced(AP_OPENGL_FORCED_STUB_TEXTURES_MODE);
    }

    // If we are not in "Force stub textures" mode:
    if (!areStubTexForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glCompressedTextureImage1DEXT, (texture, target, level, internalformat, width, border, imagesize, data));

        // Log the loaded texture:
        if (NULL != pCurrentThreadRenderContextMonitor)
        {
            bool rcTex = pCurrentThreadRenderContextMonitor->onTextureImageLoaded(target, level, internalformat, width, 0, 0, border, 0, 0);
            GT_ASSERT(rcTex);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glCompressedTextureImage1DEXT);
}

void APIENTRY glCompressedTextureSubImage3DEXT(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid* data)
{
    SU_START_FUNCTION_WRAPPER(ap_glCompressedTextureSubImage3DEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glCompressedTextureSubImage3DEXT, 12, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_INT_PARAMETER, xoffset, OS_TOBJ_ID_GL_INT_PARAMETER, yoffset, OS_TOBJ_ID_GL_INT_PARAMETER, zoffset, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_SIZEI_PARAMETER, height, OS_TOBJ_ID_GL_SIZEI_PARAMETER, depth, OS_TOBJ_ID_GL_ENUM_PARAMETER, format, OS_TOBJ_ID_GL_SIZEI_PARAMETER, imageSize, OS_TOBJ_ID_GL_P_VOID_PARAMETER, data);

    // Check if stub textures are forced:
    bool areStubTexForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubTexForced = pCurrentThreadRenderContextMonitor->forcedModesManager().isStubForced(AP_OPENGL_FORCED_STUB_TEXTURES_MODE);
    }

    // If we are not in "Force stub textures" mode:
    if (!areStubTexForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glCompressedTextureSubImage3DEXT, (texture, target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data));

        // Log the loaded sub-texture:
        if (NULL != pCurrentThreadRenderContextMonitor)
        {
            bool rcSubTex = pCurrentThreadRenderContextMonitor->onTextureSubImageLoaded(texture, target, level);
            GT_ASSERT(rcSubTex);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glCompressedTextureSubImage3DEXT);
}

void APIENTRY glCompressedTextureSubImage2DEXT(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imagesize, const GLvoid* data)
{
    SU_START_FUNCTION_WRAPPER(ap_glCompressedTextureSubImage2DEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glCompressedTextureSubImage2DEXT, 10, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_INT_PARAMETER, xoffset, OS_TOBJ_ID_GL_INT_PARAMETER, yoffset, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_SIZEI_PARAMETER, height, OS_TOBJ_ID_GL_ENUM_PARAMETER, format, OS_TOBJ_ID_GL_SIZEI_PARAMETER, imagesize, OS_TOBJ_ID_GL_P_VOID_PARAMETER, data);

    // Check if stub textures are forced:
    bool areStubTexForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubTexForced = pCurrentThreadRenderContextMonitor->forcedModesManager().isStubForced(AP_OPENGL_FORCED_STUB_TEXTURES_MODE);
    }

    // If we are not in "Force stub textures" mode:
    if (!areStubTexForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glCompressedTextureSubImage2DEXT, (texture, target, level, xoffset, yoffset, width, height, format, imagesize, data));

        // Log the loaded sub-texture:
        if (NULL != pCurrentThreadRenderContextMonitor)
        {
            bool rcSubTex = pCurrentThreadRenderContextMonitor->onTextureSubImageLoaded(texture, target, level);
            GT_ASSERT(rcSubTex);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glCompressedTextureSubImage2DEXT);
}

void APIENTRY glCompressedTextureSubImage1DEXT(GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imagesize, const GLvoid* data)
{
    SU_START_FUNCTION_WRAPPER(ap_glCompressedTextureSubImage1DEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glCompressedTextureSubImage1DEXT, 8, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_INT_PARAMETER, xoffset, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_ENUM_PARAMETER, format, OS_TOBJ_ID_GL_SIZEI_PARAMETER, imagesize, OS_TOBJ_ID_GL_P_VOID_PARAMETER, data);

    // Check if stub textures are forced:
    bool areStubTexForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubTexForced = pCurrentThreadRenderContextMonitor->forcedModesManager().isStubForced(AP_OPENGL_FORCED_STUB_TEXTURES_MODE);
    }

    // If we are not in "Force stub textures" mode:
    if (!areStubTexForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glCompressedTextureSubImage1DEXT, (texture, target, level, xoffset, width, format, imagesize, data));

        // Log the loaded sub-texture:
        if (NULL != pCurrentThreadRenderContextMonitor)
        {
            bool rcSubTex = pCurrentThreadRenderContextMonitor->onTextureSubImageLoaded(texture, target, level);
            GT_ASSERT(rcSubTex);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glCompressedTextureSubImage1DEXT);
}

void APIENTRY glGetCompressedTextureImageEXT(GLuint texture, GLenum target, GLint level, GLvoid* img)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetCompressedTextureImageEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetCompressedTextureImageEXT, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_P_VOID_PARAMETER, img);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetCompressedTextureImageEXT, (texture, target, level, img));

    SU_END_FUNCTION_WRAPPER(ap_glGetCompressedTextureImageEXT);
}

void APIENTRY glCompressedMultiTexImage3DEXT(GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid* data)
{
    SU_START_FUNCTION_WRAPPER(ap_glCompressedMultiTexImage3DEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glCompressedMultiTexImage3DEXT, 10, OS_TOBJ_ID_GL_UINT_PARAMETER, texunit, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_ENUM_PARAMETER, internalformat, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_SIZEI_PARAMETER, height, OS_TOBJ_ID_GL_SIZEI_PARAMETER, depth, OS_TOBJ_ID_GL_INT_PARAMETER, border, OS_TOBJ_ID_GL_SIZEI_PARAMETER, imageSize, OS_TOBJ_ID_GL_P_VOID_PARAMETER, data);

    // Check if stub textures are forced:
    bool areStubTexForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubTexForced = pCurrentThreadRenderContextMonitor->forcedModesManager().isStubForced(AP_OPENGL_FORCED_STUB_TEXTURES_MODE);
    }

    // If we are not in "Force stub textures" mode:
    if (!areStubTexForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glCompressedMultiTexImage3DEXT, (texunit, target, level, internalformat, width, height, depth, border, imageSize, data));

        // Log the loaded sub-texture:
        if (NULL != pCurrentThreadRenderContextMonitor)
        {
            bool rcSubTex = pCurrentThreadRenderContextMonitor->onMultiTextureSubImageLoaded(texunit, target, level);
            GT_ASSERT(rcSubTex);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glCompressedMultiTexImage3DEXT);
}

void APIENTRY glCompressedMultiTexImage2DEXT(GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid* data)
{
    SU_START_FUNCTION_WRAPPER(ap_glCompressedMultiTexImage2DEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glCompressedMultiTexImage2DEXT, 9, OS_TOBJ_ID_GL_UINT_PARAMETER, texunit, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_ENUM_PARAMETER, internalformat, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_SIZEI_PARAMETER, height, OS_TOBJ_ID_GL_INT_PARAMETER, border, OS_TOBJ_ID_GL_SIZEI_PARAMETER, imageSize, OS_TOBJ_ID_GL_P_VOID_PARAMETER, data);

    // Check if stub textures are forced:
    bool areStubTexForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubTexForced = pCurrentThreadRenderContextMonitor->forcedModesManager().isStubForced(AP_OPENGL_FORCED_STUB_TEXTURES_MODE);
    }

    // If we are not in "Force stub textures" mode:
    if (!areStubTexForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glCompressedMultiTexImage2DEXT, (texunit, target, level, internalformat, width, height, border, imageSize, data));

        // Log the loaded sub-texture:
        if (NULL != pCurrentThreadRenderContextMonitor)
        {
            bool rcSubTex = pCurrentThreadRenderContextMonitor->onMultiTextureSubImageLoaded(texunit, target, level);
            GT_ASSERT(rcSubTex);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glCompressedMultiTexImage2DEXT);
}

void APIENTRY glCompressedMultiTexImage1DEXT(GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid* data)
{
    SU_START_FUNCTION_WRAPPER(ap_glCompressedMultiTexImage1DEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glCompressedMultiTexImage1DEXT, 8, OS_TOBJ_ID_GL_UINT_PARAMETER, texunit, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_ENUM_PARAMETER, internalformat, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_INT_PARAMETER, border, OS_TOBJ_ID_GL_SIZEI_PARAMETER, imageSize, OS_TOBJ_ID_GL_P_VOID_PARAMETER, data);

    // Check if stub textures are forced:
    bool areStubTexForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubTexForced = pCurrentThreadRenderContextMonitor->forcedModesManager().isStubForced(AP_OPENGL_FORCED_STUB_TEXTURES_MODE);
    }

    // If we are not in "Force stub textures" mode:
    if (!areStubTexForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glCompressedMultiTexImage1DEXT, (texunit, target, level, internalformat, width, border, imageSize, data));

        // Log the loaded sub-texture:
        if (NULL != pCurrentThreadRenderContextMonitor)
        {
            bool rcSubTex = pCurrentThreadRenderContextMonitor->onMultiTextureSubImageLoaded(texunit, target, level);
            GT_ASSERT(rcSubTex);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glCompressedMultiTexImage1DEXT);
}

void APIENTRY glCompressedMultiTexSubImage3DEXT(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid* data)
{
    SU_START_FUNCTION_WRAPPER(ap_glCompressedMultiTexSubImage3DEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glCompressedMultiTexSubImage3DEXT, 12, OS_TOBJ_ID_GL_UINT_PARAMETER, texunit, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_INT_PARAMETER, xoffset, OS_TOBJ_ID_GL_INT_PARAMETER, yoffset, OS_TOBJ_ID_GL_INT_PARAMETER, zoffset, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_SIZEI_PARAMETER, height, OS_TOBJ_ID_GL_SIZEI_PARAMETER, depth, OS_TOBJ_ID_GL_ENUM_PARAMETER, format, OS_TOBJ_ID_GL_SIZEI_PARAMETER, imageSize, OS_TOBJ_ID_GL_P_VOID_PARAMETER, data);

    // Check if stub textures are forced:
    bool areStubTexForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubTexForced = pCurrentThreadRenderContextMonitor->forcedModesManager().isStubForced(AP_OPENGL_FORCED_STUB_TEXTURES_MODE);
    }

    // If we are not in "Force stub textures" mode:
    if (!areStubTexForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glCompressedMultiTexSubImage3DEXT, (texunit, target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data));

        // Log the loaded sub-texture:
        if (NULL != pCurrentThreadRenderContextMonitor)
        {
            bool rcSubTex = pCurrentThreadRenderContextMonitor->onMultiTextureSubImageLoaded(texunit, target, level);
            GT_ASSERT(rcSubTex);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glCompressedMultiTexSubImage3DEXT);
}

void APIENTRY glCompressedMultiTexSubImage2DEXT(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid* data)
{
    SU_START_FUNCTION_WRAPPER(ap_glCompressedMultiTexSubImage2DEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glCompressedMultiTexSubImage2DEXT, 10, OS_TOBJ_ID_GL_UINT_PARAMETER, texunit, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_INT_PARAMETER, xoffset, OS_TOBJ_ID_GL_INT_PARAMETER, yoffset, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_SIZEI_PARAMETER, height, OS_TOBJ_ID_GL_ENUM_PARAMETER, format, OS_TOBJ_ID_GL_SIZEI_PARAMETER, imageSize, OS_TOBJ_ID_GL_P_VOID_PARAMETER, data);

    // Check if stub textures are forced:
    bool areStubTexForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubTexForced = pCurrentThreadRenderContextMonitor->forcedModesManager().isStubForced(AP_OPENGL_FORCED_STUB_TEXTURES_MODE);
    }

    // If we are not in "Force stub textures" mode:
    if (!areStubTexForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glCompressedMultiTexSubImage2DEXT, (texunit, target, level, xoffset, yoffset, width, height, format, imageSize, data));

        // Log the loaded sub-texture:
        if (NULL != pCurrentThreadRenderContextMonitor)
        {
            bool rcSubTex = pCurrentThreadRenderContextMonitor->onMultiTextureSubImageLoaded(texunit, target, level);
            GT_ASSERT(rcSubTex);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glCompressedMultiTexSubImage2DEXT);
}

void APIENTRY glCompressedMultiTexSubImage1DEXT(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid* data)
{
    SU_START_FUNCTION_WRAPPER(ap_glCompressedMultiTexSubImage1DEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glCompressedMultiTexSubImage1DEXT, 8, OS_TOBJ_ID_GL_UINT_PARAMETER, texunit, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_INT_PARAMETER, xoffset, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_ENUM_PARAMETER, format, OS_TOBJ_ID_GL_SIZEI_PARAMETER, imageSize, OS_TOBJ_ID_GL_P_VOID_PARAMETER, data);

    // Check if stub textures are forced:
    bool areStubTexForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubTexForced = pCurrentThreadRenderContextMonitor->forcedModesManager().isStubForced(AP_OPENGL_FORCED_STUB_TEXTURES_MODE);
    }

    // If we are not in "Force stub textures" mode:
    if (!areStubTexForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glCompressedMultiTexSubImage1DEXT, (texunit, target, level, xoffset, width, format, imageSize, data));

        // Log the loaded sub-texture:
        if (NULL != pCurrentThreadRenderContextMonitor)
        {
            bool rcSubTex = pCurrentThreadRenderContextMonitor->onMultiTextureSubImageLoaded(texunit, target, level);
            GT_ASSERT(rcSubTex);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glCompressedMultiTexSubImage1DEXT);
}

void APIENTRY glGetCompressedMultiTexImageEXT(GLenum texunit, GLenum target, GLint level, GLvoid* img)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetCompressedMultiTexImageEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetCompressedMultiTexImageEXT, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, texunit, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_P_VOID_PARAMETER, img);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetCompressedMultiTexImageEXT, (texunit, target, level, img));

    SU_END_FUNCTION_WRAPPER(ap_glGetCompressedMultiTexImageEXT);
}

void APIENTRY glNamedProgramStringEXT(GLuint program, GLenum target, GLenum format, GLsizei len, const GLvoid* string)
{
    SU_START_FUNCTION_WRAPPER(ap_glNamedProgramStringEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glNamedProgramStringEXT, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, format, OS_TOBJ_ID_GL_SIZEI_PARAMETER, len, OS_TOBJ_ID_GL_P_VOID_PARAMETER, string);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glNamedProgramStringEXT, (program, target, format, len, string));

    SU_END_FUNCTION_WRAPPER(ap_glNamedProgramStringEXT);
}

void APIENTRY glNamedProgramLocalParameter4dEXT(GLuint program, GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w)
{
    SU_START_FUNCTION_WRAPPER(ap_glNamedProgramLocalParameter4dEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glNamedProgramLocalParameter4dEXT, 7, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, x, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, y, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, z, OS_TOBJ_ID_GL_DOUBLE_PARAMETER, w);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glNamedProgramLocalParameter4dEXT, (program, target, index, x, y, z, w));

    SU_END_FUNCTION_WRAPPER(ap_glNamedProgramLocalParameter4dEXT);
}

void APIENTRY glNamedProgramLocalParameter4dvEXT(GLuint program, GLenum target, GLuint index, const GLdouble* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glNamedProgramLocalParameter4dvEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glNamedProgramLocalParameter4dvEXT, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_P_DOUBLE_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glNamedProgramLocalParameter4dvEXT, (program, target, index, params));

    SU_END_FUNCTION_WRAPPER(ap_glNamedProgramLocalParameter4dvEXT);
}

void APIENTRY glNamedProgramLocalParameter4fEXT(GLuint program, GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
{
    SU_START_FUNCTION_WRAPPER(ap_glNamedProgramLocalParameter4fEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glNamedProgramLocalParameter4dEXT, 7, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_FLOAT_PARAMETER, x, OS_TOBJ_ID_GL_FLOAT_PARAMETER, y, OS_TOBJ_ID_GL_FLOAT_PARAMETER, z, OS_TOBJ_ID_GL_FLOAT_PARAMETER, w);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glNamedProgramLocalParameter4fEXT, (program, target, index, x, y, w, z));

    SU_END_FUNCTION_WRAPPER(ap_glNamedProgramLocalParameter4fEXT);
}

void APIENTRY glNamedProgramLocalParameter4fvEXT(GLuint program, GLenum target, GLuint index, const GLfloat* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glNamedProgramLocalParameter4fvEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glNamedProgramLocalParameter4fvEXT, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glNamedProgramLocalParameter4fvEXT, (program, target, index, params));

    SU_END_FUNCTION_WRAPPER(ap_glNamedProgramLocalParameter4fvEXT);
}

void APIENTRY glGetNamedProgramLocalParameterdvEXT(GLuint program, GLenum target, GLuint index, GLdouble* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetNamedProgramLocalParameterdvEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetNamedProgramLocalParameterdvEXT, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_P_DOUBLE_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetNamedProgramLocalParameterdvEXT, (program, target, index, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetNamedProgramLocalParameterdvEXT);
}

void APIENTRY glGetNamedProgramLocalParameterfvEXT(GLuint program, GLenum target, GLuint index, GLfloat* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetNamedProgramLocalParameterfvEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetNamedProgramLocalParameterfvEXT, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetNamedProgramLocalParameterfvEXT, (program, target, index, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetNamedProgramLocalParameterfvEXT);
}

void APIENTRY glGetNamedProgramivEXT(GLuint program, GLenum target, GLenum pname, GLint* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetNamedProgramivEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetNamedProgramivEXT, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetNamedProgramivEXT, (program, target, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetNamedProgramivEXT);
}

void APIENTRY glGetNamedProgramStringEXT(GLuint program, GLenum target, GLenum pname, GLvoid* string)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetNamedProgramStringEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetNamedProgramStringEXT, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_VOID_PARAMETER, string);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetNamedProgramStringEXT, (program, target, pname, string));

    SU_END_FUNCTION_WRAPPER(ap_glGetNamedProgramStringEXT);
}

void APIENTRY glNamedProgramLocalParameters4fvEXT(GLuint program, GLenum target, GLuint index, GLsizei count, const GLfloat* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glNamedProgramLocalParameters4fvEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glNamedProgramLocalParameters4fvEXT, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glNamedProgramLocalParameters4fvEXT, (program, target, index, count, params));

    SU_END_FUNCTION_WRAPPER(ap_glNamedProgramLocalParameters4fvEXT);
}

void APIENTRY glNamedProgramLocalParameterI4iEXT(GLuint program, GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w)
{
    SU_START_FUNCTION_WRAPPER(ap_glNamedProgramLocalParameterI4iEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glNamedProgramLocalParameterI4iEXT, 7, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_INT_PARAMETER, x, OS_TOBJ_ID_GL_INT_PARAMETER, y, OS_TOBJ_ID_GL_INT_PARAMETER, z, OS_TOBJ_ID_GL_INT_PARAMETER, w);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glNamedProgramLocalParameterI4iEXT, (program, target, index, x, y, z, w));

    SU_END_FUNCTION_WRAPPER(ap_glNamedProgramLocalParameterI4iEXT);
}

void APIENTRY glNamedProgramLocalParameterI4ivEXT(GLuint program, GLenum target, GLuint index, const GLint* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glNamedProgramLocalParameterI4ivEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glNamedProgramLocalParameterI4ivEXT, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_P_INT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glNamedProgramLocalParameterI4ivEXT, (program, target, index, params));

    SU_END_FUNCTION_WRAPPER(ap_glNamedProgramLocalParameterI4ivEXT);
}

void APIENTRY glNamedProgramLocalParametersI4ivEXT(GLuint program, GLenum target, GLuint index, GLsizei count, const GLint* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glNamedProgramLocalParametersI4ivEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glNamedProgramLocalParametersI4ivEXT, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_P_INT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glNamedProgramLocalParametersI4ivEXT, (program, target, index, count, params));

    SU_END_FUNCTION_WRAPPER(ap_glNamedProgramLocalParametersI4ivEXT);
}

void APIENTRY glNamedProgramLocalParameterI4uiEXT(GLuint program, GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
{
    SU_START_FUNCTION_WRAPPER(ap_glNamedProgramLocalParameterI4uiEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glNamedProgramLocalParameterI4uiEXT, 7, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_UINT_PARAMETER, x, OS_TOBJ_ID_GL_UINT_PARAMETER, y, OS_TOBJ_ID_GL_UINT_PARAMETER, z, OS_TOBJ_ID_GL_UINT_PARAMETER, w);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glNamedProgramLocalParameterI4uiEXT, (program, target, index, x, y, z, w));

    SU_END_FUNCTION_WRAPPER(ap_glNamedProgramLocalParameterI4uiEXT);
}

void APIENTRY glNamedProgramLocalParameterI4uivEXT(GLuint program, GLenum target, GLuint index, const GLuint* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glNamedProgramLocalParameterI4uivEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glNamedProgramLocalParameterI4uivEXT, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_P_UINT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glNamedProgramLocalParameterI4uivEXT, (program, target, index, params));

    SU_END_FUNCTION_WRAPPER(ap_glNamedProgramLocalParameterI4uivEXT);
}

void APIENTRY glNamedProgramLocalParametersI4uivEXT(GLuint program, GLenum target, GLuint index, GLsizei count, const GLuint* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glNamedProgramLocalParametersI4uivEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glNamedProgramLocalParametersI4uivEXT, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_P_UINT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glNamedProgramLocalParametersI4uivEXT, (program, target, index, count, params));

    SU_END_FUNCTION_WRAPPER(ap_glNamedProgramLocalParametersI4uivEXT);
}

void APIENTRY glGetNamedProgramLocalParameterIivEXT(GLuint program, GLenum target, GLuint index, GLint* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetNamedProgramLocalParameterIivEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetNamedProgramLocalParameterIivEXT, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_P_INT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetNamedProgramLocalParameterIivEXT, (program, target, index, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetNamedProgramLocalParameterIivEXT);
}

void APIENTRY glGetNamedProgramLocalParameterIuivEXT(GLuint program, GLenum target, GLuint index, GLuint* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetNamedProgramLocalParameterIuivEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetNamedProgramLocalParameterIuivEXT, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_UINT_PARAMETER, index, OS_TOBJ_ID_GL_P_UINT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetNamedProgramLocalParameterIuivEXT, (program, target, index, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetNamedProgramLocalParameterIuivEXT);
}

void APIENTRY glTextureParameterIivEXT(GLuint texture, GLenum target, GLenum pname, const GLint* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glTextureParameterIivEXT);

    // Log the call to this function:
    if ((pname == GL_TEXTURE_MIN_FILTER) || (pname == GL_TEXTURE_MAG_FILTER) ||
        (pname == GL_TEXTURE_COMPARE_MODE) || (pname == GL_TEXTURE_COMPARE_FUNC) || (pname == GL_DEPTH_TEXTURE_MODE) ||
        (pname == GL_TEXTURE_WRAP_S) || (pname == GL_TEXTURE_WRAP_T) || (pname == GL_TEXTURE_WRAP_R))
    {
        GLenum paramAsEnum = (GLenum) * params;
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTextureParameterIivEXT, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_ENUM_PARAMETER, paramAsEnum);
    }
    else if (pname == GL_TEXTURE_BORDER_COLOR)
    {
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTextureParameterIivEXT, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_INT_PARAMETER, 4, params);
    }
    else if (pname == GL_TEXTURE_PRIORITY)
    {
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTextureParameterIivEXT, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_INT_PARAMETER, *params);
    }
    else
    {
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTextureParameterIivEXT, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_PARAMETER, params);
    }

    // Check if stub textures are forced:
    bool areStubTexForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubTexForced = pCurrentThreadRenderContextMonitor->forcedModesManager().isStubForced(AP_OPENGL_FORCED_STUB_TEXTURES_MODE);
    }

    // If we are not in "Force stub textures" mode:
    if (!areStubTexForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glTextureParameterIivEXT, (texture, target, pname, params));
    }

    // Log the new parameter value:
    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        gsTexturesMonitor* texturesMon = pCurrentThreadRenderContextMonitor->texturesMonitor();
        GT_IF_WITH_ASSERT(texturesMon != NULL)
        {
            bool rcTexParami = pCurrentThreadRenderContextMonitor->onNamedTextureIntParameterChanged(texture, pname, params);
            GT_ASSERT(rcTexParami);
        }

        // Log the mipmap auto generation:
        if ((pname == GL_GENERATE_MIPMAP) || (pname == GL_TEXTURE_BASE_LEVEL) || (pname == GL_TEXTURE_MAX_LEVEL))
        {
            // Get the param value:
            GLint value = *params;
            bool rcMipmapGeneration = pCurrentThreadRenderContextMonitor->onMipmapGenerateParamSet(texture, pname, (GLfloat)value);
            GT_ASSERT(rcMipmapGeneration);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glTextureParameterIivEXT);
}

void APIENTRY glTextureParameterIuivEXT(GLuint texture, GLenum target, GLenum pname, const GLuint* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glTextureParameterIuivEXT);

    // Log the call to this function:
    if ((pname == GL_TEXTURE_MIN_FILTER) || (pname == GL_TEXTURE_MAG_FILTER) ||
        (pname == GL_TEXTURE_COMPARE_MODE) || (pname == GL_TEXTURE_COMPARE_FUNC) || (pname == GL_DEPTH_TEXTURE_MODE) ||
        (pname == GL_TEXTURE_WRAP_S) || (pname == GL_TEXTURE_WRAP_T) || (pname == GL_TEXTURE_WRAP_R))
    {
        GLenum paramAsEnum = (GLenum) * params;
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTextureParameterIuivEXT, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_ENUM_PARAMETER, paramAsEnum);
    }
    else if (pname == GL_TEXTURE_BORDER_COLOR)
    {
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTextureParameterIuivEXT, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_UINT_PARAMETER, 4, params);
    }
    else if (pname == GL_TEXTURE_PRIORITY)
    {
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTextureParameterIuivEXT, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_UINT_PARAMETER, *params);
    }
    else
    {
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTextureParameterIuivEXT, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_UINT_PARAMETER, params);
    }

    // Check if stub textures are forced:
    bool areStubTexForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubTexForced = pCurrentThreadRenderContextMonitor->forcedModesManager().isStubForced(AP_OPENGL_FORCED_STUB_TEXTURES_MODE);
    }

    // If we are not in "Force stub textures" mode:
    if (!areStubTexForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glTextureParameterIuivEXT, (texture, target, pname, params));
    }

    // Log the new parameter value:
    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        gsTexturesMonitor* texturesMon = pCurrentThreadRenderContextMonitor->texturesMonitor();
        GT_IF_WITH_ASSERT(texturesMon != NULL)
        {
            bool rcTexParami = pCurrentThreadRenderContextMonitor->onNamedTextureUIntParameterChanged(texture, pname, params);
            GT_ASSERT(rcTexParami);
        }

        // Log the mipmap auto generation:
        if ((pname == GL_GENERATE_MIPMAP) || (pname == GL_TEXTURE_BASE_LEVEL) || (pname == GL_TEXTURE_MAX_LEVEL))
        {
            // Get the param value:
            GLint value = *params;
            bool rcMipmapGeneration = pCurrentThreadRenderContextMonitor->onMipmapGenerateParamSet(texture, pname, (GLfloat)value);
            GT_ASSERT(rcMipmapGeneration);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glTextureParameterIuivEXT);
}

void APIENTRY glGetTextureParameterIivEXT(GLuint texture, GLenum target, GLenum pname, GLint* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetTextureParameterIivEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetTextureParameterIivEXT, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetTextureParameterIivEXT, (texture, target, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetTextureParameterIivEXT);
}

void APIENTRY glGetTextureParameterIuivEXT(GLuint texture, GLenum target, GLenum pname, GLuint* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetTextureParameterIuivEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetTextureParameterIuivEXT, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetTextureParameterIuivEXT, (texture, target, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetTextureParameterIuivEXT);
}

void APIENTRY glMultiTexParameterIivEXT(GLenum texunit, GLenum target, GLenum pname, const GLint* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glMultiTexParameterIivEXT);

    // Log the call to this function:
    if ((pname == GL_TEXTURE_MIN_FILTER) || (pname == GL_TEXTURE_MAG_FILTER) ||
        (pname == GL_TEXTURE_COMPARE_MODE) || (pname == GL_TEXTURE_COMPARE_FUNC) || (pname == GL_DEPTH_TEXTURE_MODE) ||
        (pname == GL_TEXTURE_WRAP_S) || (pname == GL_TEXTURE_WRAP_T) || (pname == GL_TEXTURE_WRAP_R))
    {
        GLenum paramAsEnum = (GLenum) * params;
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexParameterIivEXT, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, texunit, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_ENUM_PARAMETER, paramAsEnum);

    }
    else if (pname == GL_TEXTURE_BORDER_COLOR)
    {
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexParameterIivEXT, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, texunit, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_INT_PARAMETER, 4, params);
    }
    else if (pname == GL_TEXTURE_PRIORITY)
    {
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexParameterIivEXT, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, texunit, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_INT_PARAMETER, *params);
    }
    else
    {
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexParameterIivEXT, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, texunit, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_PARAMETER, params);
    }

    // Check if stub textures are forced:
    bool areStubTexForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubTexForced = pCurrentThreadRenderContextMonitor->forcedModesManager().isStubForced(AP_OPENGL_FORCED_STUB_TEXTURES_MODE);
    }

    // If we are not in "Force stub textures" mode:
    if (!areStubTexForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glMultiTexParameterIivEXT, (texunit, target, pname, params));
    }

    // Log the new parameter value:
    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        gsTexturesMonitor* texturesMon = pCurrentThreadRenderContextMonitor->texturesMonitor();
        GT_IF_WITH_ASSERT(texturesMon != NULL)
        {
            bool rcTexParami = pCurrentThreadRenderContextMonitor->onMultiTextureIntParameterChanged(texunit, target, pname, params);
            GT_ASSERT(rcTexParami);
        }

        // Log the mipmap auto generation:
        if ((pname == GL_GENERATE_MIPMAP) || (pname == GL_TEXTURE_BASE_LEVEL) || (pname == GL_TEXTURE_MAX_LEVEL))
        {
            // Get the param value:
            GLint value = *params;
            bool rcMipmapGeneration = pCurrentThreadRenderContextMonitor->onMultiTextureMipmapGenerateParamSet(texunit, target, pname, (GLfloat)value);
            GT_ASSERT(rcMipmapGeneration);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexParameterIivEXT);
}

void APIENTRY glMultiTexParameterIuivEXT(GLenum texunit, GLenum target, GLenum pname, const GLuint* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glMultiTexParameterIuivEXT);

    // Log the call to this function:
    if ((pname == GL_TEXTURE_MIN_FILTER) || (pname == GL_TEXTURE_MAG_FILTER) ||
        (pname == GL_TEXTURE_COMPARE_MODE) || (pname == GL_TEXTURE_COMPARE_FUNC) || (pname == GL_DEPTH_TEXTURE_MODE) ||
        (pname == GL_TEXTURE_WRAP_S) || (pname == GL_TEXTURE_WRAP_T) || (pname == GL_TEXTURE_WRAP_R))
    {
        GLenum paramAsEnum = (GLenum) * params;
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexParameterIuivEXT, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, texunit, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_ENUM_PARAMETER, paramAsEnum);

    }
    else if (pname == GL_TEXTURE_BORDER_COLOR)
    {
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexParameterIuivEXT, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, texunit, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_UINT_PARAMETER, 4, params);
    }
    else if (pname == GL_TEXTURE_PRIORITY)
    {
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexParameterIuivEXT, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, texunit, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_UINT_PARAMETER, *params);
    }
    else
    {
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexParameterIuivEXT, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, texunit, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_UINT_PARAMETER, params);
    }

    // Check if stub textures are forced:
    bool areStubTexForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubTexForced = pCurrentThreadRenderContextMonitor->forcedModesManager().isStubForced(AP_OPENGL_FORCED_STUB_TEXTURES_MODE);
    }

    // If we are not in "Force stub textures" mode:
    if (!areStubTexForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glMultiTexParameterIuivEXT, (texunit, target, pname, params));
    }

    // Log the new parameter value:
    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        gsTexturesMonitor* texturesMon = pCurrentThreadRenderContextMonitor->texturesMonitor();
        GT_IF_WITH_ASSERT(texturesMon != NULL)
        {
            bool rcTexParami = pCurrentThreadRenderContextMonitor->onMultiTextureUIntParameterChanged(texunit, target, pname, params);
            GT_ASSERT(rcTexParami);
        }

        // Log the mipmap auto generation:
        if ((pname == GL_GENERATE_MIPMAP) || (pname == GL_TEXTURE_BASE_LEVEL) || (pname == GL_TEXTURE_MAX_LEVEL))
        {
            // Get the param value:
            GLint value = *params;
            bool rcMipmapGeneration = pCurrentThreadRenderContextMonitor->onMultiTextureMipmapGenerateParamSet(texunit, target, pname, (GLfloat)value);
            GT_ASSERT(rcMipmapGeneration);
        }
    }

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexParameterIuivEXT, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, texunit, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_UINT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexParameterIuivEXT, (texunit, target, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexParameterIuivEXT);
}

void APIENTRY glGetMultiTexParameterIivEXT(GLenum texunit, GLenum target, GLenum pname, GLint* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetMultiTexParameterIivEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetMultiTexParameterIivEXT, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, texunit, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetMultiTexParameterIivEXT, (texunit, target, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetMultiTexParameterIivEXT);
}

void APIENTRY glGetMultiTexParameterIuivEXT(GLenum texunit, GLenum target, GLenum pname, GLuint* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetMultiTexParameterIuivEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetMultiTexParameterIuivEXT, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, texunit, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_UINT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetMultiTexParameterIuivEXT, (texunit, target, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetMultiTexParameterIuivEXT);
}

void APIENTRY glProgramUniform1fEXT(GLuint program, GLint location, GLfloat v0)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniform1fEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniform1fEXT, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_FLOAT_PARAMETER, v0);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        SU_CALL_EXTENSION_FUNC(glProgramUniform1fEXT, (program, location, v0));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            // TO_DO: The active uniforms manager might assume that the program is the active program. We need to check this!
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(program, location, GL_FLOAT, (void*)(&v0));
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniform1fEXT);
}

void APIENTRY glProgramUniform2fEXT(GLuint program, GLint location, GLfloat v0, GLfloat v1)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniform2fEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniform2fEXT, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_FLOAT_PARAMETER, v0, OS_TOBJ_ID_GL_FLOAT_PARAMETER, v1);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glProgramUniform2fEXT, (program, location, v0, v1));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            // TO_DO: The active uniforms manager might assume that the program is the active program. We need to check this!
            GLfloat values[2] = {v0, v1};
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(program, location, GL_FLOAT_VEC2, (void*)values);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniform2fEXT);
}

void APIENTRY glProgramUniform3fEXT(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniform3fEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniform3fEXT, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_FLOAT_PARAMETER, v0, OS_TOBJ_ID_GL_FLOAT_PARAMETER, v1, OS_TOBJ_ID_GL_FLOAT_PARAMETER, v2);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glProgramUniform3fEXT, (program, location, v0, v1, v2));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            // TO_DO: The active uniforms manager might assume that the program is the active program. We need to check this!
            GLfloat values[3] = {v0, v1, v2};
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(program, location, GL_FLOAT_VEC3, (void*)values);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniform3fEXT);
}

void APIENTRY glProgramUniform4fEXT(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniform4fEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniform4fEXT, 6, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_FLOAT_PARAMETER, v0, OS_TOBJ_ID_GL_FLOAT_PARAMETER, v1, OS_TOBJ_ID_GL_FLOAT_PARAMETER, v2, OS_TOBJ_ID_GL_FLOAT_PARAMETER, v3);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glProgramUniform4fEXT, (program, location, v0, v1, v2, v3));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            // TO_DO: The active uniforms manager might assume that the program is the active program. We need to check this!
            GLfloat values[4] = {v0, v1, v2, v3};
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(program, location, GL_FLOAT_VEC4, (void*)values);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniform4fEXT);
}

void APIENTRY glProgramUniform1iEXT(GLuint program, GLint location, GLint v0)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniform1iEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniform1iEXT, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_INT_PARAMETER, v0);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glProgramUniform1iEXT, (program, location, v0));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            // TO_DO: The active uniforms manager might assume that the program is the active program. We need to check this!
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(program, location, GL_INT, (void*)(&v0));
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniform1iEXT);
}

void APIENTRY glProgramUniform2iEXT(GLuint program, GLint location, GLint v0, GLint v1)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniform2iEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniform2iEXT, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_INT_PARAMETER, v0, OS_TOBJ_ID_GL_INT_PARAMETER, v1);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glProgramUniform2iEXT, (program, location, v0, v1));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            // TO_DO: The active uniforms manager might assume that the program is the active program. We need to check this!
            GLint values[2] = {v0, v1};
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(program, location, GL_INT_VEC2, (void*)values);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniform2iEXT);
}

void APIENTRY glProgramUniform3iEXT(GLuint program, GLint location, GLint v0, GLint v1, GLint v2)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniform3iEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniform3iEXT, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_INT_PARAMETER, v0, OS_TOBJ_ID_GL_INT_PARAMETER, v1, OS_TOBJ_ID_GL_INT_PARAMETER, v2);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glProgramUniform3iEXT, (program, location, v0, v1, v2));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            // TO_DO: The active uniforms manager might assume that the program is the active program. We need to check this!
            GLint values[3] = {v0, v1, v2};
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(program, location, GL_INT_VEC3, (void*)values);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniform3iEXT);
}

void APIENTRY glProgramUniform4iEXT(GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniform4iEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniform4iEXT, 6, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_INT_PARAMETER, v0, OS_TOBJ_ID_GL_INT_PARAMETER, v1, OS_TOBJ_ID_GL_INT_PARAMETER, v2, OS_TOBJ_ID_GL_INT_PARAMETER, v3);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glProgramUniform4iEXT, (program, location, v0, v1, v2, v3));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            // TO_DO: The active uniforms manager might assume that the program is the active program. We need to check this!
            GLint values[4] = {v0, v1, v2, v3};
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(program, location, GL_INT_VEC4, (void*)values);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniform4iEXT);
}

void APIENTRY glProgramUniform1fvEXT(GLuint program, GLint location, GLsizei count, const GLfloat* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniform1fvEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniform1fvEXT, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, value);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glProgramUniform1fvEXT, (program, location, count, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            // TO_DO: The active uniforms manager might assume that the program is the active program. We need to check this!
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(program, location, GL_FLOAT, (void*)value);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniform1fvEXT);
}

void APIENTRY glProgramUniform2fvEXT(GLuint program, GLint location, GLsizei count, const GLfloat* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniform2fvEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniform2fvEXT, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, value);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glProgramUniform2fvEXT, (program, location, count, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            // TO_DO: The active uniforms manager might assume that the program is the active program. We need to check this!
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(program, location, GL_FLOAT_VEC2, (void*)value);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniform2fvEXT);
}

void APIENTRY glProgramUniform3fvEXT(GLuint program, GLint location, GLsizei count, const GLfloat* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniform3fvEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniform3fvEXT, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, value);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glProgramUniform3fvEXT, (program, location, count, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            // TO_DO: The active uniforms manager might assume that the program is the active program. We need to check this!
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(program, location, GL_FLOAT_VEC3, (void*)value);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniform3fvEXT);
}

void APIENTRY glProgramUniform4fvEXT(GLuint program, GLint location, GLsizei count, const GLfloat* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniform4fvEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniform4fvEXT, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, value);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glProgramUniform4fvEXT, (program, location, count, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            // TO_DO: The active uniforms manager might assume that the program is the active program. We need to check this!
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(program, location, GL_FLOAT_VEC4, (void*)value);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniform4fvEXT);
}

void APIENTRY glProgramUniform1ivEXT(GLuint program, GLint location, GLsizei count, const GLint* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniform1ivEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniform1ivEXT, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_P_INT_PARAMETER, value);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glProgramUniform1ivEXT, (program, location, count, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            // TO_DO: The active uniforms manager might assume that the program is the active program. We need to check this!
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(program, location, GL_INT, (void*)value);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniform1ivEXT);
}

void APIENTRY glProgramUniform2ivEXT(GLuint program, GLint location, GLsizei count, const GLint* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniform2ivEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniform2ivEXT, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_P_INT_PARAMETER, value);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glProgramUniform2ivEXT, (program, location, count, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            // TO_DO: The active uniforms manager might assume that the program is the active program. We need to check this!
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(program, location, GL_INT_VEC2, (void*)value);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniform2ivEXT);
}

void APIENTRY glProgramUniform3ivEXT(GLuint program, GLint location, GLsizei count, const GLint* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniform3ivEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniform3ivEXT, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_P_INT_PARAMETER, value);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glProgramUniform3ivEXT, (program, location, count, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            // TO_DO: The active uniforms manager might assume that the program is the active program. We need to check this!
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(program, location, GL_INT_VEC3, (void*)value);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniform3ivEXT);
}

void APIENTRY glProgramUniform4ivEXT(GLuint program, GLint location, GLsizei count, const GLint* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniform4ivEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniform4ivEXT, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_P_INT_PARAMETER, value);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glProgramUniform4ivEXT, (program, location, count, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            // TO_DO: The active uniforms manager might assume that the program is the active program. We need to check this!
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(program, location, GL_INT_VEC4, (void*)value);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniform4ivEXT);
}

void APIENTRY glProgramUniformMatrix2fvEXT(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniformMatrix2fvEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniformMatrix2fvEXT, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_BOOL_PARAMETER, transpose, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, value);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glProgramUniformMatrix2fvEXT, (program, location, count, transpose, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            // TO_DO: The active uniforms manager might assume that the program is the active program. We need to check this!
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(program, location, GL_FLOAT_MAT2, (void*)value, (transpose == GL_TRUE));
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniformMatrix2fvEXT);
}

void APIENTRY glProgramUniformMatrix3fvEXT(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniformMatrix3fvEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniformMatrix3fvEXT, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_BOOL_PARAMETER, transpose, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, value);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glProgramUniformMatrix3fvEXT, (program, location, count, transpose, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            // TO_DO: The active uniforms manager might assume that the program is the active program. We need to check this!
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(program, location, GL_FLOAT_MAT3, (void*)value, (transpose == GL_TRUE));
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniformMatrix3fvEXT);
}

void APIENTRY glProgramUniformMatrix4fvEXT(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniformMatrix4fvEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniformMatrix4fvEXT, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_BOOL_PARAMETER, transpose, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, value);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glProgramUniformMatrix4fvEXT, (program, location, count, transpose, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            // TO_DO: The active uniforms manager might assume that the program is the active program. We need to check this!
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(program, location, GL_FLOAT_MAT4, (void*)value, (transpose == GL_TRUE));
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniformMatrix4fvEXT);
}

void APIENTRY glProgramUniformMatrix2x3fvEXT(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniformMatrix2x3fvEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniformMatrix2x3fvEXT, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_BOOL_PARAMETER, transpose, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, value);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glProgramUniformMatrix2x3fvEXT, (program, location, count, transpose, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            // TO_DO: The active uniforms manager might assume that the program is the active program. We need to check this!
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(program, location, GL_FLOAT_MAT2x3, (void*)value, (transpose == GL_TRUE));
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniformMatrix2x3fvEXT);
}

void APIENTRY glProgramUniformMatrix3x2fvEXT(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniformMatrix3x2fvEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniformMatrix3x2fvEXT, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_BOOL_PARAMETER, transpose, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, value);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glProgramUniformMatrix3x2fvEXT, (program, location, count, transpose, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            // TO_DO: The active uniforms manager might assume that the program is the active program. We need to check this!
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(program, location, GL_FLOAT_MAT3x2, (void*)value, (transpose == GL_TRUE));
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniformMatrix3x2fvEXT);
}

void APIENTRY glProgramUniformMatrix2x4fvEXT(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniformMatrix2x4fvEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniformMatrix2x4fvEXT, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_BOOL_PARAMETER, transpose, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, value);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glProgramUniformMatrix2x4fvEXT, (program, location, count, transpose, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            // TO_DO: The active uniforms manager might assume that the program is the active program. We need to check this!
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(program, location, GL_FLOAT_MAT2x4, (void*)value, (transpose == GL_TRUE));
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniformMatrix2x4fvEXT);
}

void APIENTRY glProgramUniformMatrix4x2fvEXT(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniformMatrix4x2fvEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniformMatrix4x2fvEXT, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_BOOL_PARAMETER, transpose, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, value);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glProgramUniformMatrix4x2fvEXT, (program, location, count, transpose, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            // TO_DO: The active uniforms manager might assume that the program is the active program. We need to check this!
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(program, location, GL_FLOAT_MAT4x2, (void*)value, (transpose == GL_TRUE));
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniformMatrix4x2fvEXT);
}

void APIENTRY glProgramUniformMatrix3x4fvEXT(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniformMatrix3x4fvEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniformMatrix3x4fvEXT, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_BOOL_PARAMETER, transpose, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, value);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glProgramUniformMatrix3x4fvEXT, (program, location, count, transpose, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            // TO_DO: The active uniforms manager might assume that the program is the active program. We need to check this!
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(program, location, GL_FLOAT_MAT3x4, (void*)value, (transpose == GL_TRUE));
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniformMatrix3x4fvEXT);
}

void APIENTRY glProgramUniformMatrix4x3fvEXT(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniformMatrix4x3fvEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniformMatrix4x3fvEXT, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_BOOL_PARAMETER, transpose, OS_TOBJ_ID_GL_P_FLOAT_PARAMETER, value);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glProgramUniformMatrix4x3fvEXT, (program, location, count, transpose, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            // TO_DO: The active uniforms manager might assume that the program is the active program. We need to check this!
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(program, location, GL_FLOAT_MAT4x3, (void*)value, (transpose == GL_TRUE));
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniformMatrix4x3fvEXT);
}

void APIENTRY glProgramUniform1uiEXT(GLuint program, GLint location, GLuint v0)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniform1uiEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniform1uiEXT, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_UINT_PARAMETER, v0);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glProgramUniform1uiEXT, (program, location, v0));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            // TO_DO: The active uniforms manager might assume that the program is the active program. We need to check this!
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(program, location, GL_UNSIGNED_INT, (void*)(&v0));
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniform1uiEXT);
}

void APIENTRY glProgramUniform2uiEXT(GLuint program, GLint location, GLuint v0, GLuint v1)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniform2uiEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniform2uiEXT, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_UINT_PARAMETER, v0, OS_TOBJ_ID_GL_UINT_PARAMETER, v1);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glProgramUniform2uiEXT, (program, location, v0, v1));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            // TO_DO: The active uniforms manager might assume that the program is the active program. We need to check this!
            GLuint values[2] = {v0, v1};
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(program, location, GL_UNSIGNED_INT_VEC2, (void*)values);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniform2uiEXT);
}

void APIENTRY glProgramUniform3uiEXT(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniform3uiEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniform3uiEXT, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_UINT_PARAMETER, v0, OS_TOBJ_ID_GL_UINT_PARAMETER, v1, OS_TOBJ_ID_GL_UINT_PARAMETER, v2);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glProgramUniform3uiEXT, (program, location, v0, v1, v2));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            // TO_DO: The active uniforms manager might assume that the program is the active program. We need to check this!
            GLuint values[3] = {v0, v1, v2};
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(program, location, GL_UNSIGNED_INT_VEC3, (void*)values);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniform3uiEXT);
}

void APIENTRY glProgramUniform4uiEXT(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniform4uiEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniform4uiEXT, 6, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_UINT_PARAMETER, v0, OS_TOBJ_ID_GL_UINT_PARAMETER, v1, OS_TOBJ_ID_GL_UINT_PARAMETER, v2, OS_TOBJ_ID_GL_UINT_PARAMETER, v3);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glProgramUniform4uiEXT, (program, location, v0, v1, v2, v3));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            // TO_DO: The active uniforms manager might assume that the program is the active program. We need to check this!
            GLuint values[4] = {v0, v1, v2, v3};
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(program, location, GL_UNSIGNED_INT_VEC4, (void*)values);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniform4uiEXT);
}

void APIENTRY glProgramUniform1uivEXT(GLuint program, GLint location, GLsizei count, const GLuint* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniform1uivEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniform1uivEXT, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_P_UINT_PARAMETER, value);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glProgramUniform1uivEXT, (program, location, count, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            // TO_DO: The active uniforms manager might assume that the program is the active program. We need to check this!
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(program, location, GL_UNSIGNED_INT, (void*)value);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniform1uivEXT);
}

void APIENTRY glProgramUniform2uivEXT(GLuint program, GLint location, GLsizei count, const GLuint* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniform2uivEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniform2uivEXT, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_P_UINT_PARAMETER, value);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glProgramUniform2uivEXT, (program, location, count, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            // TO_DO: The active uniforms manager might assume that the program is the active program. We need to check this!
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(program, location, GL_UNSIGNED_INT_VEC2, (void*)value);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniform2uivEXT);
}

void APIENTRY glProgramUniform3uivEXT(GLuint program, GLint location, GLsizei count, const GLuint* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniform3uivEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniform3uivEXT, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_P_UINT_PARAMETER, value);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glProgramUniform3uivEXT, (program, location, count, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            // TO_DO: The active uniforms manager might assume that the program is the active program. We need to check this!
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(program, location, GL_UNSIGNED_INT_VEC3, (void*)value);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniform3uivEXT);
}

void APIENTRY glProgramUniform4uivEXT(GLuint program, GLint location, GLsizei count, const GLuint* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glProgramUniform4uivEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glProgramUniform4uivEXT, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_SIZEI_PARAMETER, count, OS_TOBJ_ID_GL_P_UINT_PARAMETER, value);

    // Check if stub fragment shaders are forced:
    bool areStubFSGSForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubFSGSForced = pCurrentThreadRenderContextMonitor->forcedModesManager().areStubShadersForced();
    }

    // Call the real function:
    if (!areStubFSGSForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glProgramUniform4uivEXT, (program, location, count, value));
    }
    else
    {
        gsProgramsAndShadersMonitor* pProgramsAndShadersMonitor = pCurrentThreadRenderContextMonitor->programsAndShadersMonitor();
        GT_IF_WITH_ASSERT(pProgramsAndShadersMonitor != NULL)
        {
            // TO_DO: The active uniforms manager might assume that the program is the active program. We need to check this!
            pProgramsAndShadersMonitor->programsActiveUniformsMgr().updateStubbedUniformValue(program, location, GL_UNSIGNED_INT_VEC4, (void*)value);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glProgramUniform4uivEXT);
}

void APIENTRY glNamedBufferDataEXT(GLuint buffer, GLsizeiptr size, const GLvoid* data, GLenum usage)
{
    SU_START_FUNCTION_WRAPPER(ap_glNamedBufferDataEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glNamedBufferDataEXT, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, buffer, OS_TOBJ_ID_GL_SIZEIPTR_PARAMETER, size, OS_TOBJ_ID_GL_P_VOID_PARAMETER, data, OS_TOBJ_ID_GL_ENUM_PARAMETER, usage);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glNamedBufferDataEXT, (buffer, size, data, usage));

    // Log the vbo data set:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        gsVBOMonitor* vboMonitor = pCurrentThreadRenderContextMonitor->vboMonitor();
        GT_IF_WITH_ASSERT(vboMonitor != NULL)
        {
            vboMonitor->onVertexBufferObjectDirectAccessDataSet(buffer, size);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glNamedBufferDataEXT);
}

void APIENTRY glNamedBufferSubDataEXT(GLuint buffer, GLintptr offset, GLsizeiptr size, const GLvoid* data)
{
    SU_START_FUNCTION_WRAPPER(ap_glNamedBufferSubDataEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glNamedBufferSubDataEXT, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, buffer, OS_TOBJ_ID_GL_INTPTR_PARAMETER, offset, OS_TOBJ_ID_GL_SIZEIPTR_PARAMETER, size, OS_TOBJ_ID_GL_P_VOID_PARAMETER, data);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glNamedBufferSubDataEXT, (buffer, offset, size, data));

    // Log the vbo data set:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        gsVBOMonitor* vboMonitor = pCurrentThreadRenderContextMonitor->vboMonitor();
        GT_IF_WITH_ASSERT(vboMonitor != NULL)
        {
            vboMonitor->onVertexBufferObjectDirectAccessSubDataSet(buffer);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glNamedBufferSubDataEXT);
}

GLvoid* APIENTRY glMapNamedBufferEXT(GLuint buffer, GLenum access)
{
    SU_START_FUNCTION_WRAPPER(ap_glMapNamedBufferEXT);

    GLvoid* retVal = NULL;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMapNamedBufferEXT, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, buffer, OS_TOBJ_ID_GL_ENUM_PARAMETER, access);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glMapNamedBufferEXT, (buffer, access), retVal);

    SU_END_FUNCTION_WRAPPER(ap_glMapNamedBufferEXT);

    return retVal;
}

GLboolean APIENTRY glUnmapNamedBufferEXT(GLuint buffer)
{
    SU_START_FUNCTION_WRAPPER(ap_glUnmapNamedBufferEXT);

    GLboolean retVal = GL_FALSE;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glUnmapNamedBufferEXT, 1, OS_TOBJ_ID_GL_UINT_PARAMETER, buffer);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glUnmapNamedBufferEXT, (buffer), retVal);

    // Log the vbo data set:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        gsVBOMonitor* vboMonitor = pCurrentThreadRenderContextMonitor->vboMonitor();
        GT_IF_WITH_ASSERT(vboMonitor != NULL)
        {
            vboMonitor->onVertexBufferObjectDirectAccessSubDataSet(buffer);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glUnmapNamedBufferEXT);

    return retVal;
}

GLvoid* APIENTRY glMapNamedBufferRangeEXT(GLuint buffer, GLintptr offset, GLsizeiptr length, GLbitfield access)
{
    SU_START_FUNCTION_WRAPPER(ap_glMapNamedBufferRangeEXT);

    GLvoid* retVal = NULL;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMapNamedBufferRangeEXT, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, buffer, OS_TOBJ_ID_GL_INTPTR_PARAMETER, offset, OS_TOBJ_ID_GL_SIZEIPTR_PARAMETER, length, OS_TOBJ_ID_GL_BITFIELD_PARAMETER, access);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glMapNamedBufferRangeEXT, (buffer, offset, length, access), retVal);

    SU_END_FUNCTION_WRAPPER(ap_glMapNamedBufferRangeEXT);

    return retVal;
}

void APIENTRY glFlushMappedNamedBufferRangeEXT(GLuint buffer, GLintptr offset, GLsizeiptr length)
{
    SU_START_FUNCTION_WRAPPER(ap_glFlushMappedNamedBufferRangeEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glFlushMappedNamedBufferRangeEXT, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, buffer, OS_TOBJ_ID_GL_INTPTR_PARAMETER, offset, OS_TOBJ_ID_GL_SIZEIPTR_PARAMETER, length);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glFlushMappedNamedBufferRangeEXT, (buffer, offset, length));

    // Log the vbo data set:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        gsVBOMonitor* vboMonitor = pCurrentThreadRenderContextMonitor->vboMonitor();
        GT_IF_WITH_ASSERT(vboMonitor != NULL)
        {
            vboMonitor->onVertexBufferObjectDirectAccessSubDataSet(buffer);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glFlushMappedNamedBufferRangeEXT);
}

void APIENTRY glNamedCopyBufferSubDataEXT(GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size)
{
    SU_START_FUNCTION_WRAPPER(ap_glNamedCopyBufferSubDataEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glNamedCopyBufferSubDataEXT, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, readBuffer, OS_TOBJ_ID_GL_UINT_PARAMETER, writeBuffer, OS_TOBJ_ID_GL_INTPTR_PARAMETER, readOffset, OS_TOBJ_ID_GL_INTPTR_PARAMETER, writeOffset, OS_TOBJ_ID_GL_SIZEIPTR_PARAMETER, size);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glNamedCopyBufferSubDataEXT, (readBuffer, writeBuffer, readOffset, writeOffset, size));

    SU_END_FUNCTION_WRAPPER(ap_glNamedCopyBufferSubDataEXT);
}

void APIENTRY glGetNamedBufferParameterivEXT(GLuint buffer, GLenum pname, GLint* param)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetNamedBufferParameterivEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetNamedBufferParameterivEXT, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, buffer, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_PARAMETER, param);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetNamedBufferParameterivEXT, (buffer, pname, param));

    SU_END_FUNCTION_WRAPPER(ap_glGetNamedBufferParameterivEXT);
}

void APIENTRY glGetNamedBufferPointervEXT(GLuint buffer, GLenum pname, GLvoid** param)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetNamedBufferPointervEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetNamedBufferPointervEXT, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, buffer, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_PP_VOID_PARAMETER, param);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetNamedBufferPointervEXT, (buffer, pname, param));

    SU_END_FUNCTION_WRAPPER(ap_glGetNamedBufferPointervEXT);
}

void APIENTRY glGetNamedBufferSubDataEXT(GLuint buffer, GLintptr offset, GLsizeiptr size, GLvoid* data)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetNamedBufferSubDataEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetNamedBufferSubDataEXT, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, buffer, OS_TOBJ_ID_GL_INTPTR_PARAMETER, offset, OS_TOBJ_ID_GL_SIZEIPTR_PARAMETER, size, OS_TOBJ_ID_GL_P_VOID_PARAMETER, data);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetNamedBufferSubDataEXT, (buffer, offset, size, data));

    SU_END_FUNCTION_WRAPPER(ap_glGetNamedBufferSubDataEXT);
}

void APIENTRY glTextureBufferEXT(GLuint texture, GLenum target, GLenum internalformat, GLuint buffer)
{
    SU_START_FUNCTION_WRAPPER(ap_glTextureBufferEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTextureBufferEXT, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, internalformat, OS_TOBJ_ID_GL_UINT_PARAMETER, buffer);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glTextureBufferEXT, (texture, target, internalformat, buffer));

    // Log the textures buffer attachment:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        pCurrentThreadRenderContextMonitor->onTextureBuffer(texture, target, internalformat, buffer);
    }

    SU_END_FUNCTION_WRAPPER(ap_glTextureBufferEXT);
}

void APIENTRY glMultiTexBufferEXT(GLenum texunit, GLenum target, GLenum internalformat, GLuint buffer)
{
    SU_START_FUNCTION_WRAPPER(ap_glMultiTexBufferEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexBufferEXT, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, texunit, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, internalformat, OS_TOBJ_ID_GL_UINT_PARAMETER, buffer);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexBufferEXT, (texunit, target, internalformat, buffer));

    // Log the textures buffer attachment:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        pCurrentThreadRenderContextMonitor->onMultiTextureBuffer(texunit, target, internalformat, buffer);
    }

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexBufferEXT);
}

void APIENTRY glNamedRenderbufferStorageEXT(GLuint renderbuffer, GLenum internalformat, GLsizei width, GLsizei height)
{
    SU_START_FUNCTION_WRAPPER(ap_glNamedRenderbufferStorageEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glNamedRenderbufferStorageEXT, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, renderbuffer, OS_TOBJ_ID_GL_ENUM_PARAMETER, internalformat, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_SIZEI_PARAMETER, height);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glNamedRenderbufferStorageEXT, (renderbuffer, internalformat, width, height));

    // Log the textures generation:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        bool rcRBOParams = pCurrentThreadRenderContextMonitor->setRenderBufferObjectParameters(renderbuffer, internalformat, width, height);
        GT_ASSERT(rcRBOParams);
    }

    SU_END_FUNCTION_WRAPPER(ap_glNamedRenderbufferStorageEXT);
}

void APIENTRY glGetNamedRenderbufferParameterivEXT(GLuint renderbuffer, GLenum pname, GLint* param)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetNamedRenderbufferParameterivEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetNamedRenderbufferParameterivEXT, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, renderbuffer, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_PARAMETER, param);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetNamedRenderbufferParameterivEXT, (renderbuffer, pname, param));

    SU_END_FUNCTION_WRAPPER(ap_glGetNamedRenderbufferParameterivEXT);
}

GLenum APIENTRY glCheckNamedFramebufferStatusEXT(GLuint framebuffer, GLenum target)
{
    SU_START_FUNCTION_WRAPPER(ap_glCheckNamedFramebufferStatusEXT);

    GLenum retVal = GL_FRAMEBUFFER_UNSUPPORTED_EXT;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glCheckNamedFramebufferStatusEXT, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, framebuffer, OS_TOBJ_ID_GL_ENUM_PARAMETER, target);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glCheckNamedFramebufferStatusEXT, (framebuffer, target), retVal);

    SU_END_FUNCTION_WRAPPER(ap_glCheckNamedFramebufferStatusEXT);

    return retVal;
}

void APIENTRY glNamedFramebufferTexture1DEXT(GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
{
    SU_START_FUNCTION_WRAPPER(ap_glNamedFramebufferTexture1DEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glNamedFramebufferTexture1DEXT, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, framebuffer, OS_TOBJ_ID_GL_ENUM_PARAMETER, attachment, OS_TOBJ_ID_GL_ENUM_PARAMETER, textarget, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_INT_PARAMETER, level);

    // Get the RenderContextMonitor
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    // Construct a new apFBO for each of the generated frame buffer objects:
    GT_IF_WITH_ASSERT(pCurrentThreadRenderContextMonitor != NULL)
    {
        // Bind the texture to the active FBO:
        bool rcBindFBO = pCurrentThreadRenderContextMonitor->bindObjectToFBO(framebuffer, attachment, textarget, texture, 0);
        GT_ASSERT(rcBindFBO);
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glNamedFramebufferTexture1DEXT, (framebuffer, attachment, textarget, texture, level));

    SU_END_FUNCTION_WRAPPER(ap_glNamedFramebufferTexture1DEXT);
}

void APIENTRY glNamedFramebufferTexture2DEXT(GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
{
    SU_START_FUNCTION_WRAPPER(ap_glNamedFramebufferTexture2DEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glNamedFramebufferTexture2DEXT, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, framebuffer, OS_TOBJ_ID_GL_ENUM_PARAMETER, attachment, OS_TOBJ_ID_GL_ENUM_PARAMETER, textarget, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_INT_PARAMETER, level);

    // Get the RenderContextMonitor
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    // Construct a new apFBO for each of the generated frame buffer objects:
    GT_IF_WITH_ASSERT(pCurrentThreadRenderContextMonitor != NULL)
    {
        // Bind the texture to the active FBO:
        bool rcBindFBO = pCurrentThreadRenderContextMonitor->bindObjectToFBO(framebuffer, attachment, textarget, texture, 0);
        GT_ASSERT(rcBindFBO);
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glNamedFramebufferTexture2DEXT, (framebuffer, attachment, textarget, texture, level));

    SU_END_FUNCTION_WRAPPER(ap_glNamedFramebufferTexture2DEXT);
}

void APIENTRY glNamedFramebufferTexture3DEXT(GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset)
{
    SU_START_FUNCTION_WRAPPER(ap_glNamedFramebufferTexture3DEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glNamedFramebufferTexture3DEXT, 6, OS_TOBJ_ID_GL_UINT_PARAMETER, framebuffer, OS_TOBJ_ID_GL_ENUM_PARAMETER, attachment, OS_TOBJ_ID_GL_ENUM_PARAMETER, textarget, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_INT_PARAMETER, zoffset);

    // Get the RenderContextMonitor
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    // Construct a new apFBO for each of the generated frame buffer objects:
    GT_IF_WITH_ASSERT(pCurrentThreadRenderContextMonitor != NULL)
    {
        // Bind the texture to the active FBO:
        bool rcBindFBO = pCurrentThreadRenderContextMonitor->bindObjectToFBO(framebuffer, attachment, textarget, texture, 0);
        GT_ASSERT(rcBindFBO);
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glNamedFramebufferTexture3DEXT, (framebuffer, attachment, textarget, texture, level, zoffset));

    SU_END_FUNCTION_WRAPPER(ap_glNamedFramebufferTexture3DEXT);
}

void APIENTRY glNamedFramebufferRenderbufferEXT(GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
{
    SU_START_FUNCTION_WRAPPER(ap_glNamedFramebufferRenderbufferEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glNamedFramebufferRenderbufferEXT, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, framebuffer, OS_TOBJ_ID_GL_ENUM_PARAMETER, attachment, OS_TOBJ_ID_GL_ENUM_PARAMETER, renderbuffertarget, OS_TOBJ_ID_GL_UINT_PARAMETER, renderbuffer);

    // Get the RenderContextMonitor
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    // Construct a new apFBO for each of the generated frame buffer objects:
    GT_IF_WITH_ASSERT(pCurrentThreadRenderContextMonitor != NULL)
    {
        // Bind the texture to the active FBO:
        bool rcBindFBO = pCurrentThreadRenderContextMonitor->bindObjectToFBO(framebuffer, attachment, renderbuffertarget, renderbuffer, 0);
        GT_ASSERT(rcBindFBO);
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glNamedFramebufferRenderbufferEXT, (framebuffer, attachment, renderbuffertarget, renderbuffer));

    SU_END_FUNCTION_WRAPPER(ap_glNamedFramebufferRenderbufferEXT);
}

void APIENTRY glGetNamedFramebufferAttachmentParameterivEXT(GLuint framebuffer, GLenum attachment, GLenum pname, GLint* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetNamedFramebufferAttachmentParameterivEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetNamedFramebufferAttachmentParameterivEXT, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, framebuffer, OS_TOBJ_ID_GL_ENUM_PARAMETER, attachment, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_PARAMETER, params);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetNamedFramebufferAttachmentParameterivEXT, (framebuffer, attachment, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetNamedFramebufferAttachmentParameterivEXT);
}

void APIENTRY glGenerateTextureMipmapEXT(GLuint texture, GLenum target)
{
    SU_START_FUNCTION_WRAPPER(ap_glGenerateTextureMipmapEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGenerateTextureMipmapEXT, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_ENUM_PARAMETER, target);

    // Log the mipmap generation:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (pCurrentThreadRenderContextMonitor != NULL)
    {
        pCurrentThreadRenderContextMonitor->onTextureMipmapGenerate(texture);
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGenerateTextureMipmapEXT, (texture, target));

    SU_END_FUNCTION_WRAPPER(ap_glGenerateTextureMipmapEXT);
}

void APIENTRY glGenerateMultiTexMipmapEXT(GLenum texunit, GLenum target)
{
    SU_START_FUNCTION_WRAPPER(ap_glGenerateMultiTexMipmapEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGenerateMultiTexMipmapEXT, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, texunit, OS_TOBJ_ID_GL_ENUM_PARAMETER, target);

    // Log the mipmap generation:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (pCurrentThreadRenderContextMonitor != NULL)
    {
        pCurrentThreadRenderContextMonitor->onMultiTextureMipmapGenerate(texunit, target);
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGenerateMultiTexMipmapEXT, (texunit, target));

    SU_END_FUNCTION_WRAPPER(ap_glGenerateMultiTexMipmapEXT);
}

void APIENTRY glFramebufferDrawBufferEXT(GLuint framebuffer, GLenum mode)
{
    SU_START_FUNCTION_WRAPPER(ap_glFramebufferDrawBufferEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glFramebufferDrawBufferEXT, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, framebuffer, OS_TOBJ_ID_GL_ENUM_PARAMETER, mode);

    bool isFrontDrawBuffForced = false;

    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        // Log the "real" draw buffer:
        gsForcedModesManager& forcedModesMgr = pCurrentThreadRenderContextMonitor->forcedModesManager();
        forcedModesMgr.onSetDrawBuffersCall(mode);

        // Check if front draw buffer is forced:
        isFrontDrawBuffForced = forcedModesMgr.isStubForced(AP_OPENGL_FORCED_FRONT_DRAW_BUFFER_MODE);
    }

    // If the OpenGL front draw buffer is not forced:
    if (!isFrontDrawBuffForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glFramebufferDrawBufferEXT, (framebuffer, mode));
    }

    SU_END_FUNCTION_WRAPPER(ap_glFramebufferDrawBufferEXT);
}

void APIENTRY glFramebufferDrawBuffersEXT(GLuint framebuffer, GLsizei n, const GLenum* bufs)
{
    SU_START_FUNCTION_WRAPPER(ap_glFramebufferDrawBuffersEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glFramebufferDrawBuffersEXT, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, framebuffer, OS_TOBJ_ID_GL_SIZEI_PARAMETER, n, OS_TOBJ_ID_GL_P_ENUM_PARAMETER, bufs);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glFramebufferDrawBuffersEXT, (framebuffer, n, bufs));

    SU_END_FUNCTION_WRAPPER(ap_glFramebufferDrawBuffersEXT);
}

void APIENTRY glFramebufferReadBufferEXT(GLuint framebuffer, GLenum mode)
{
    SU_START_FUNCTION_WRAPPER(ap_glFramebufferReadBufferEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glFramebufferReadBufferEXT, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, framebuffer, OS_TOBJ_ID_GL_ENUM_PARAMETER, mode);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glFramebufferReadBufferEXT, (framebuffer, mode));

    SU_END_FUNCTION_WRAPPER(ap_glFramebufferReadBufferEXT);
}

void APIENTRY glGetFramebufferParameterivEXT(GLuint framebuffer, GLenum pname, GLint* param)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetFramebufferParameterivEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetFramebufferParameterivEXT, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, framebuffer, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_PARAMETER, param);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glGetFramebufferParameterivEXT, (framebuffer, pname, param));

    SU_END_FUNCTION_WRAPPER(ap_glGetFramebufferParameterivEXT);
}

void APIENTRY glNamedRenderbufferStorageMultisampleEXT(GLuint renderbuffer, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
{
    SU_START_FUNCTION_WRAPPER(ap_glNamedRenderbufferStorageMultisampleEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glNamedRenderbufferStorageMultisampleEXT, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, renderbuffer, OS_TOBJ_ID_GL_SIZEI_PARAMETER, samples, OS_TOBJ_ID_GL_ENUM_PARAMETER, internalformat, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_SIZEI_PARAMETER, height);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glNamedRenderbufferStorageMultisampleEXT, (renderbuffer, samples, internalformat, width, height));

    SU_END_FUNCTION_WRAPPER(ap_glNamedRenderbufferStorageMultisampleEXT);
}

void APIENTRY glNamedRenderbufferStorageMultisampleCoverageEXT(GLuint renderbuffer, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height)
{
    SU_START_FUNCTION_WRAPPER(ap_glNamedRenderbufferStorageMultisampleCoverageEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glNamedRenderbufferStorageMultisampleCoverageEXT, 6, OS_TOBJ_ID_GL_UINT_PARAMETER, renderbuffer, OS_TOBJ_ID_GL_SIZEI_PARAMETER, coverageSamples, OS_TOBJ_ID_GL_SIZEI_PARAMETER, colorSamples, OS_TOBJ_ID_GL_ENUM_PARAMETER, internalformat, OS_TOBJ_ID_GL_SIZEI_PARAMETER, width, OS_TOBJ_ID_GL_SIZEI_PARAMETER, height);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glNamedRenderbufferStorageMultisampleCoverageEXT, (renderbuffer, coverageSamples, colorSamples, internalformat, width, height));

    SU_END_FUNCTION_WRAPPER(ap_glNamedRenderbufferStorageMultisampleCoverageEXT);
}

void APIENTRY glNamedFramebufferTextureEXT(GLuint framebuffer, GLenum attachment, GLuint texture, GLint level)
{
    SU_START_FUNCTION_WRAPPER(ap_glNamedFramebufferTextureEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glNamedFramebufferTextureEXT, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, framebuffer, OS_TOBJ_ID_GL_ENUM_PARAMETER, attachment, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_INT_PARAMETER, level);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glNamedFramebufferTextureEXT, (framebuffer, attachment, texture, level));

    // Get the RenderContextMonitor
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    // Construct a new apFBO for each of the generated frame buffer objects:
    GT_IF_WITH_ASSERT(pCurrentThreadRenderContextMonitor != NULL)
    {
        // Bind the texture to the active FBO:
        bool rcBindFBO = pCurrentThreadRenderContextMonitor->bindTextureToFBO(framebuffer, attachment, texture, 0);
        GT_ASSERT(rcBindFBO);
    }

    SU_END_FUNCTION_WRAPPER(ap_glNamedFramebufferTextureEXT);
}

void APIENTRY glNamedFramebufferTextureLayerEXT(GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLint layer)
{
    SU_START_FUNCTION_WRAPPER(ap_glNamedFramebufferTextureLayerEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glNamedFramebufferTextureLayerEXT, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, framebuffer, OS_TOBJ_ID_GL_ENUM_PARAMETER, attachment, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_INT_PARAMETER, layer);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glNamedFramebufferTextureLayerEXT, (framebuffer, attachment, texture, level, layer));

    // Get the RenderContextMonitor
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    // Construct a new apFBO for each of the generated frame buffer objects:
    GT_IF_WITH_ASSERT(pCurrentThreadRenderContextMonitor != NULL)
    {
        // Bind the texture to the active FBO:
        bool rcBindFBO = pCurrentThreadRenderContextMonitor->bindTextureToFBO(framebuffer, attachment, texture, layer);
        GT_ASSERT(rcBindFBO);
    }

    SU_END_FUNCTION_WRAPPER(ap_glNamedFramebufferTextureLayerEXT);
}

void APIENTRY glNamedFramebufferTextureFaceEXT(GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLenum face)
{
    SU_START_FUNCTION_WRAPPER(ap_glNamedFramebufferTextureFaceEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glNamedFramebufferTextureFaceEXT, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, framebuffer, OS_TOBJ_ID_GL_ENUM_PARAMETER, attachment, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_INT_PARAMETER, level, OS_TOBJ_ID_GL_ENUM_PARAMETER, face);

    // Get the RenderContextMonitor
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    // Construct a new apFBO for each of the generated frame buffer objects:
    GT_IF_WITH_ASSERT(pCurrentThreadRenderContextMonitor != NULL)
    {
        // Bind the texture to the active FBO:
        bool rcBindFBO = pCurrentThreadRenderContextMonitor->bindTextureToFBO(framebuffer, face, texture, 0);
        GT_ASSERT(rcBindFBO);
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glNamedFramebufferTextureFaceEXT, (framebuffer, attachment, texture, level, face));

    SU_END_FUNCTION_WRAPPER(ap_glNamedFramebufferTextureFaceEXT);
}

void APIENTRY glTextureRenderbufferEXT(GLuint texture, GLenum target, GLuint renderbuffer)
{
    SU_START_FUNCTION_WRAPPER(ap_glTextureRenderbufferEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTextureRenderbufferEXT, 5, OS_TOBJ_ID_GL_UINT_PARAMETER, texture, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_UINT_PARAMETER, renderbuffer);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glTextureRenderbufferEXT, (texture, target, renderbuffer));

    SU_END_FUNCTION_WRAPPER(ap_glTextureRenderbufferEXT);
}

void APIENTRY glMultiTexRenderbufferEXT(GLenum texunit, GLenum target, GLuint renderbuffer)
{
    SU_START_FUNCTION_WRAPPER(ap_glMultiTexRenderbufferEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glMultiTexRenderbufferEXT, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, texunit, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_UINT_PARAMETER, renderbuffer);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glMultiTexRenderbufferEXT, (texunit, target, renderbuffer));

    SU_END_FUNCTION_WRAPPER(ap_glMultiTexRenderbufferEXT);
}

//////////////////////////////////////////////////////////////////////////
// GL_EXT_bindable_uniform
//////////////////////////////////////////////////////////////////////////
void glUniformBufferEXT(GLuint program, GLint location, GLuint buffer)
{
    SU_START_FUNCTION_WRAPPER(ap_glUniformBufferEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glUniformBufferEXT, 3, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location, OS_TOBJ_ID_GL_UINT_PARAMETER, buffer);

    // Log the buffer binding:
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (pCurrentThreadRenderContextMonitor != NULL)
    {
        gsVBOMonitor* vboMonitor = pCurrentThreadRenderContextMonitor->vboMonitor();
        GT_IF_WITH_ASSERT(vboMonitor != NULL)
        {
            vboMonitor->onVertexBufferObjectTargetBind(GL_UNIFORM_BUFFER_EXT, buffer);
        }
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glUniformBufferEXT, (program, location, buffer));

    SU_END_FUNCTION_WRAPPER(ap_glUniformBufferEXT);
}

GLint glGetUniformBufferSizeEXT(GLuint program, GLint location)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetUniformBufferSizeEXT);

    GLint retVal = 0;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetUniformBufferSizeEXT, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glGetUniformBufferSizeEXT, (program, location), retVal);

    SU_END_FUNCTION_WRAPPER(ap_glGetUniformBufferSizeEXT);

    return retVal;
}

GLintptr glGetUniformOffsetEXT(GLuint program, GLint location)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetUniformOffsetEXT);

    GLintptr retVal = 0;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetUniformOffsetEXT, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, program, OS_TOBJ_ID_GL_INT_PARAMETER, location);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glGetUniformOffsetEXT, (program, location), retVal);

    SU_END_FUNCTION_WRAPPER(ap_glGetUniformOffsetEXT);

    return retVal;
}

//////////////////////////////////////////////////////////////////////////
// GL_EXT_texture_integer
//////////////////////////////////////////////////////////////////////////
void APIENTRY glTexParameterIivEXT(GLenum target, GLenum pname, const GLint* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glTexParameterIivEXT);

    // Get the input bind target bounded texture name:
    GLuint boundTextureName = gs_stat_openGLMonitorInstance.boundTexture(target);

    // Log the call to this function:

    if ((pname == GL_TEXTURE_MIN_FILTER) || (pname == GL_TEXTURE_MAG_FILTER) ||
        (pname == GL_TEXTURE_COMPARE_MODE) || (pname == GL_TEXTURE_COMPARE_FUNC) || (pname == GL_DEPTH_TEXTURE_MODE) ||
        (pname == GL_TEXTURE_WRAP_S) || (pname == GL_TEXTURE_WRAP_T) || (pname == GL_TEXTURE_WRAP_R))
    {
        GLenum paramAsEnum = (GLenum) * params;
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTexParameterIivEXT, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_ENUM_PARAMETER, paramAsEnum, OS_TOBJ_ID_ASSOCIATED_TEXTURE_NAMES_PSEUDO_PARAMETER, 1, &boundTextureName);
    }
    else if ((pname == GL_TEXTURE_BORDER_COLOR) || (pname == GL_TEXTURE_CROP_RECT_OES))
    {
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTexParameterIivEXT, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_INT_PARAMETER, 4, params, OS_TOBJ_ID_ASSOCIATED_TEXTURE_NAMES_PSEUDO_PARAMETER, 1, &boundTextureName);
    }
    else if (pname == GL_TEXTURE_PRIORITY)
    {
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTexParameterIivEXT, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_INT_PARAMETER, *params, OS_TOBJ_ID_ASSOCIATED_TEXTURE_NAMES_PSEUDO_PARAMETER, 1, &boundTextureName);
    }
    else
    {
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTexParameterIivEXT, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_PARAMETER, params, OS_TOBJ_ID_ASSOCIATED_TEXTURE_NAMES_PSEUDO_PARAMETER, 1, &boundTextureName);
    }

    // Check if stub textures are forced:
    bool areStubTexForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubTexForced = pCurrentThreadRenderContextMonitor->forcedModesManager().isStubForced(AP_OPENGL_FORCED_STUB_TEXTURES_MODE);
    }

    // If we are not in "Force stub textures" mode:
    if (!areStubTexForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glTexParameterIivEXT, (target, pname, params));
    }

    // Log the new parameter value:
    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        gsTexturesMonitor* texturesMon = pCurrentThreadRenderContextMonitor->texturesMonitor();
        GT_IF_WITH_ASSERT(texturesMon != NULL)
        {
            bool rcTexParamf = pCurrentThreadRenderContextMonitor->onTextureIntParameterChanged(target, pname, params);
            GT_ASSERT(rcTexParamf);
        }

        // Log the mipmap auto generation:
        if ((pname == GL_GENERATE_MIPMAP) || (pname == GL_TEXTURE_BASE_LEVEL) || (pname == GL_TEXTURE_MAX_LEVEL))
        {
            // Get the param value:
            GLint value = *params;
            bool rcMipmapGeneration = pCurrentThreadRenderContextMonitor->onMipmapGenerateParamSet(target, pname, (GLfloat)value);
            GT_ASSERT(rcMipmapGeneration);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glTexParameterIivEXT);
}

void APIENTRY glTexParameterIuivEXT(GLenum target, GLenum pname, const GLuint* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glTexParameterIuivEXT);

    // Get the input bind target bounded texture name:
    GLuint boundTextureName = gs_stat_openGLMonitorInstance.boundTexture(target);

    // Log the call to this function:

    if ((pname == GL_TEXTURE_MIN_FILTER) || (pname == GL_TEXTURE_MAG_FILTER) ||
        (pname == GL_TEXTURE_COMPARE_MODE) || (pname == GL_TEXTURE_COMPARE_FUNC) || (pname == GL_DEPTH_TEXTURE_MODE) ||
        (pname == GL_TEXTURE_WRAP_S) || (pname == GL_TEXTURE_WRAP_T) || (pname == GL_TEXTURE_WRAP_R))
    {
        GLenum paramAsEnum = (GLenum) * params;
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTexParameterIuivEXT, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_ENUM_PARAMETER, paramAsEnum, OS_TOBJ_ID_ASSOCIATED_TEXTURE_NAMES_PSEUDO_PARAMETER, 1, &boundTextureName);
    }
    else if ((pname == GL_TEXTURE_BORDER_COLOR) || (pname == GL_TEXTURE_CROP_RECT_OES))
    {
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTexParameterIuivEXT, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_GL_UINT_PARAMETER, 4, params, OS_TOBJ_ID_ASSOCIATED_TEXTURE_NAMES_PSEUDO_PARAMETER, 1, &boundTextureName);
    }
    else if (pname == GL_TEXTURE_PRIORITY)
    {
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTexParameterIuivEXT, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_UINT_PARAMETER, *params, OS_TOBJ_ID_ASSOCIATED_TEXTURE_NAMES_PSEUDO_PARAMETER, 1, &boundTextureName);
    }
    else
    {
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_glTexParameterIuivEXT, 4, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_UINT_PARAMETER, params, OS_TOBJ_ID_ASSOCIATED_TEXTURE_NAMES_PSEUDO_PARAMETER, 1, &boundTextureName);
    }

    // Check if stub textures are forced:
    bool areStubTexForced = false;
    gsRenderContextMonitor* pCurrentThreadRenderContextMonitor = gs_stat_openGLMonitorInstance.currentThreadRenderContextMonitor();

    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        areStubTexForced = pCurrentThreadRenderContextMonitor->forcedModesManager().isStubForced(AP_OPENGL_FORCED_STUB_TEXTURES_MODE);
    }

    // If we are not in "Force stub textures" mode:
    if (!areStubTexForced)
    {
        // Call the real function:
        SU_CALL_EXTENSION_FUNC(glTexParameterIuivEXT, (target, pname, params));
    }

    // Log the new parameter value:
    if (NULL != pCurrentThreadRenderContextMonitor)
    {
        gsTexturesMonitor* texturesMon = pCurrentThreadRenderContextMonitor->texturesMonitor();
        GT_IF_WITH_ASSERT(texturesMon != NULL)
        {
            bool rcTexParamf = pCurrentThreadRenderContextMonitor->onNamedTextureUIntParameterChanged(boundTextureName, pname, params);
            GT_ASSERT(rcTexParamf);
        }

        // Log the mipmap auto generation:
        if ((pname == GL_GENERATE_MIPMAP) || (pname == GL_TEXTURE_BASE_LEVEL) || (pname == GL_TEXTURE_MAX_LEVEL))
        {
            // Get the param value:
            GLuint value = *params;
            bool rcMipmapGeneration = pCurrentThreadRenderContextMonitor->onMipmapGenerateParamSet(target, pname, (GLfloat)value);
            GT_ASSERT(rcMipmapGeneration);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glTexParameterIuivEXT);
}
void APIENTRY glGetTexParameterIivEXT(GLenum target, GLenum pname, GLint* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetTexParameterIivEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetTexParameterIivEXT, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_INT_PARAMETER, params);

    SU_CALL_EXTENSION_FUNC(glGetTexParameterIivEXT, (target, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetTexParameterIivEXT);
}
void APIENTRY glGetTexParameterIuivEXT(GLenum target, GLenum pname, GLuint* params)
{
    SU_START_FUNCTION_WRAPPER(ap_glGetTexParameterIuivEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glGetTexParameterIuivEXT, 3, OS_TOBJ_ID_GL_ENUM_PARAMETER, target, OS_TOBJ_ID_GL_ENUM_PARAMETER, pname, OS_TOBJ_ID_GL_P_UINT_PARAMETER, params);

    SU_CALL_EXTENSION_FUNC(glGetTexParameterIuivEXT, (target, pname, params));

    SU_END_FUNCTION_WRAPPER(ap_glGetTexParameterIuivEXT);
}

void APIENTRY glClearColorIiEXT(GLint r, GLint g, GLint b, GLint a)
{
    SU_START_FUNCTION_WRAPPER(ap_glClearColorIiEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glClearColorIiEXT, 4, OS_TOBJ_ID_GL_INT_PARAMETER, r, OS_TOBJ_ID_GL_INT_PARAMETER, g, OS_TOBJ_ID_GL_INT_PARAMETER, b, OS_TOBJ_ID_GL_INT_PARAMETER, a);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glClearColorIiEXT, (r, g, b, a));

    SU_END_FUNCTION_WRAPPER(ap_glClearColorIiEXT);
}
void APIENTRY glClearColorIuiEXT(GLuint r, GLuint g, GLuint b, GLuint a)
{
    SU_START_FUNCTION_WRAPPER(ap_glClearColorIuiEXT);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glClearColorIuiEXT, 4, OS_TOBJ_ID_GL_UINT_PARAMETER, r, OS_TOBJ_ID_GL_UINT_PARAMETER, g, OS_TOBJ_ID_GL_UINT_PARAMETER, b, OS_TOBJ_ID_GL_UINT_PARAMETER, a);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glClearColorIuiEXT, (r, g, b, a));

    SU_END_FUNCTION_WRAPPER(ap_glClearColorIuiEXT);
}

//////////////////////////////////////////////////////////////////////////
// GL_
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// GL_
//////////////////////////////////////////////////////////////////////////

// Add new extensions here:

// --------------------------------------------------------
//             WGL Extensions Wrapper functions
// --------------------------------------------------------

#if AMDT_BUILD_TARGET == AMDT_WINDOWS_OS

const char* APIENTRY wglGetExtensionsStringARB(HDC hdc)
{
    static const char* stat_emptyString = "\0";
    const char* retVal = stat_emptyString;

    SU_START_WGL_FUNCTION_WRAPPER(ap_wglGetExtensionsStringARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_wglGetExtensionsStringARB, 1, OS_TOBJ_ID_WIN32_HDC_PARAMETER, hdc);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(wglGetExtensionsStringARB, (hdc), retVal);

    SU_END_WGL_FUNCTION_WRAPPER(ap_wglGetExtensionsStringARB);

    return retVal;
}


//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////

BOOL APIENTRY wglEnableGenlockI3D(HDC hdc)
{
    SU_START_WGL_FUNCTION_WRAPPER(ap_wglEnableGenlockI3D);

    BOOL retVal = FALSE;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_wglEnableGenlockI3D, 1, OS_TOBJ_ID_WIN32_HDC_PARAMETER, hdc);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(wglEnableGenlockI3D, (hdc), retVal);

    SU_END_WGL_FUNCTION_WRAPPER(ap_wglEnableGenlockI3D);

    return retVal;
}

BOOL APIENTRY wglDisableGenlockI3D(HDC hdc)
{
    SU_START_WGL_FUNCTION_WRAPPER(ap_wglDisableGenlockI3D);

    BOOL retVal = FALSE;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_wglDisableGenlockI3D, 1, OS_TOBJ_ID_WIN32_HDC_PARAMETER, hdc);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(wglDisableGenlockI3D, (hdc), retVal);

    SU_END_WGL_FUNCTION_WRAPPER(ap_wglDisableGenlockI3D);

    return retVal;
}

BOOL APIENTRY wglIsEnabledGenlockI3D(HDC hDC, BOOL* pFlag)
{
    SU_START_WGL_FUNCTION_WRAPPER(ap_wglIsEnabledGenlockI3D);

    BOOL retVal = FALSE;

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(wglIsEnabledGenlockI3D, (hDC, pFlag), retVal);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_wglIsEnabledGenlockI3D, 2, OS_TOBJ_ID_WIN32_HDC_PARAMETER, hDC, OS_TOBJ_ID_WIN32_BOOL_PARAMETER, *pFlag);

    SU_END_WGL_FUNCTION_WRAPPER(ap_wglIsEnabledGenlockI3D);

    return retVal;
}

BOOL APIENTRY wglGenlockSourceI3D(HDC hDC, UINT uSource)
{
    SU_START_WGL_FUNCTION_WRAPPER(ap_wglGenlockSourceI3D);

    BOOL retVal = FALSE;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_wglGenlockSourceI3D, 2, OS_TOBJ_ID_WIN32_HDC_PARAMETER, hDC, OS_TOBJ_ID_WIN32_UINT_PARAMETER, uSource);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(wglGenlockSourceI3D, (hDC, uSource), retVal);

    SU_END_WGL_FUNCTION_WRAPPER(ap_wglGenlockSourceI3D);

    return retVal;
}

BOOL APIENTRY wglGetGenlockSourceI3D(HDC hDC, UINT* uSource)
{
    SU_START_WGL_FUNCTION_WRAPPER(ap_wglGetGenlockSourceI3D);

    BOOL retVal = FALSE;

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(wglGetGenlockSourceI3D, (hDC, uSource), retVal);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_wglGetGenlockSourceI3D, 2, OS_TOBJ_ID_WIN32_HDC_PARAMETER, hDC, OS_TOBJ_ID_WIN32_UINT_PARAMETER, *uSource);

    SU_END_WGL_FUNCTION_WRAPPER(ap_wglGetGenlockSourceI3D);

    return retVal;
}

BOOL APIENTRY wglGenlockSourceEdgeI3D(HDC hDC, UINT uEdge)
{
    SU_START_WGL_FUNCTION_WRAPPER(ap_wglGenlockSourceEdgeI3D);

    BOOL retVal = FALSE;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_wglGenlockSourceEdgeI3D, 2, OS_TOBJ_ID_WIN32_HDC_PARAMETER, hDC, OS_TOBJ_ID_WIN32_UINT_PARAMETER, uEdge);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(wglGenlockSourceEdgeI3D, (hDC, uEdge), retVal);

    SU_END_WGL_FUNCTION_WRAPPER(ap_wglGenlockSourceEdgeI3D);

    return retVal;
}

BOOL APIENTRY wglGetGenlockSourceEdgeI3D(HDC hDC, UINT* uEdge)
{
    SU_START_WGL_FUNCTION_WRAPPER(ap_wglGetGenlockSourceEdgeI3D);

    BOOL retVal = FALSE;

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(wglGetGenlockSourceEdgeI3D, (hDC, uEdge), retVal);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_wglGetGenlockSourceEdgeI3D, 2, OS_TOBJ_ID_WIN32_HDC_PARAMETER, hDC, OS_TOBJ_ID_WIN32_UINT_PARAMETER, *uEdge);

    SU_END_WGL_FUNCTION_WRAPPER(ap_wglGetGenlockSourceEdgeI3D);

    return retVal;
}

BOOL APIENTRY wglGenlockSampleRateI3D(HDC hDC, UINT uRate)
{
    SU_START_WGL_FUNCTION_WRAPPER(ap_wglGenlockSampleRateI3D);

    BOOL retVal = FALSE;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_wglGenlockSampleRateI3D, 2, OS_TOBJ_ID_WIN32_HDC_PARAMETER, hDC, OS_TOBJ_ID_WIN32_UINT_PARAMETER, uRate);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(wglGenlockSampleRateI3D, (hDC, uRate), retVal);

    SU_END_WGL_FUNCTION_WRAPPER(ap_wglGenlockSampleRateI3D);

    return retVal;
}

BOOL APIENTRY wglGetGenlockSampleRateI3D(HDC hDC, UINT* uRate)
{
    SU_START_WGL_FUNCTION_WRAPPER(ap_wglGetGenlockSampleRateI3D);

    BOOL retVal = FALSE;

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(wglGetGenlockSampleRateI3D, (hDC, uRate), retVal);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_wglGetGenlockSampleRateI3D, 2, OS_TOBJ_ID_WIN32_HDC_PARAMETER, hDC, OS_TOBJ_ID_WIN32_UINT_PARAMETER, *uRate);

    SU_END_WGL_FUNCTION_WRAPPER(ap_wglGetGenlockSampleRateI3D);

    return retVal;
}

BOOL APIENTRY wglGenlockSourceDelayI3D(HDC hDC, UINT uDelay)
{
    SU_START_WGL_FUNCTION_WRAPPER(ap_wglGenlockSourceDelayI3D);

    BOOL retVal = FALSE;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_wglGenlockSourceDelayI3D, 2, OS_TOBJ_ID_WIN32_HDC_PARAMETER, hDC, OS_TOBJ_ID_WIN32_UINT_PARAMETER, uDelay);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(wglGenlockSourceDelayI3D, (hDC, uDelay), retVal);

    SU_END_WGL_FUNCTION_WRAPPER(ap_wglGenlockSourceDelayI3D);

    return retVal;
}

BOOL APIENTRY wglGetGenlockSourceDelayI3D(HDC hDC, UINT* uDelay)
{
    SU_START_WGL_FUNCTION_WRAPPER(ap_wglGetGenlockSourceDelayI3D);

    BOOL retVal = FALSE;

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(wglGetGenlockSourceDelayI3D, (hDC, uDelay), retVal);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_wglGetGenlockSourceDelayI3D, 2, OS_TOBJ_ID_WIN32_HDC_PARAMETER, hDC, OS_TOBJ_ID_WIN32_UINT_PARAMETER, *uDelay);

    SU_END_WGL_FUNCTION_WRAPPER(ap_wglGetGenlockSourceDelayI3D);

    return retVal;
}

BOOL APIENTRY wglQueryGenlockMaxSourceDelayI3D(HDC hDC, UINT* uMaxLineDelay, UINT* uMaxPixelDelay)
{
    SU_START_WGL_FUNCTION_WRAPPER(ap_wglQueryGenlockMaxSourceDelayI3D);

    BOOL retVal = FALSE;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_wglQueryGenlockMaxSourceDelayI3D, 3, OS_TOBJ_ID_WIN32_HDC_PARAMETER, hDC, OS_TOBJ_ID_WIN32_UINT_PARAMETER, *uMaxLineDelay, OS_TOBJ_ID_WIN32_UINT_PARAMETER, *uMaxPixelDelay);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(wglQueryGenlockMaxSourceDelayI3D, (hDC, uMaxLineDelay, uMaxPixelDelay), retVal);

    SU_END_WGL_FUNCTION_WRAPPER(ap_wglQueryGenlockMaxSourceDelayI3D);

    return retVal;
}


//////////////////////////////////////////////////////////////////////////
// WGL_ARB_pbuffer
//////////////////////////////////////////////////////////////////////////
HPBUFFERARB APIENTRY wglCreatePbufferARB(HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int* piAttribList)
{
    SU_START_WGL_FUNCTION_WRAPPER(ap_wglCreatePbufferARB);

    HPBUFFERARB retVal = NULL;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_wglCreatePbufferARB, 5, OS_TOBJ_ID_WIN32_HDC_PARAMETER, hDC, OS_TOBJ_ID_INT_PARAMETER, iPixelFormat, OS_TOBJ_ID_INT_PARAMETER, iWidth, OS_TOBJ_ID_INT_PARAMETER, iHeight, OS_TOBJ_ID_P_WIN32_INT_PARAMETER, piAttribList);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(wglCreatePbufferARB, (hDC, iPixelFormat, iWidth, iHeight, piAttribList), retVal);

    // Get the PBuffer monitor:
    gsPBuffersMonitor& pbuffersMonitor = gs_stat_openGLMonitorInstance.pbuffersMonitor();

    // Log the created PBuffer:
    pbuffersMonitor.onPBufferCreation(retVal, hDC, iPixelFormat, iWidth, iHeight, piAttribList);

    SU_END_WGL_FUNCTION_WRAPPER(ap_wglCreatePbufferARB);

    return retVal;
}

HDC APIENTRY wglGetPbufferDCARB(HPBUFFERARB hPbuffer)
{
    SU_START_WGL_FUNCTION_WRAPPER(ap_wglGetPbufferDCARB);

    HDC retVal = NULL;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_wglGetPbufferDCARB, 1, OS_TOBJ_ID_GL_HPBUFFERARB, hPbuffer);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(wglGetPbufferDCARB, (hPbuffer), retVal);

    // Get the PBuffer monitor:
    gsPBuffersMonitor& pbuffersMonitor = gs_stat_openGLMonitorInstance.pbuffersMonitor();

    // Log the new hDC for the PBuffer:
    pbuffersMonitor.onPBufferhDCGeneration(hPbuffer, retVal);

    SU_END_WGL_FUNCTION_WRAPPER(ap_wglGetPbufferDCARB);

    return retVal;
}

int APIENTRY wglReleasePbufferDCARB(HPBUFFERARB hPbuffer, HDC hDC)
{
    SU_START_WGL_FUNCTION_WRAPPER(ap_wglReleasePbufferDCARB);

    int retVal = 0;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_wglReleasePbufferDCARB, 2, OS_TOBJ_ID_GL_HPBUFFERARB, hPbuffer, OS_TOBJ_ID_WIN32_HDC_PARAMETER, hDC);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(wglReleasePbufferDCARB, (hPbuffer, hDC), retVal);

    // If release was successful:
    if (retVal == 1)
    {
        // Get the PBuffer monitor:
        gsPBuffersMonitor& pbuffersMonitor = gs_stat_openGLMonitorInstance.pbuffersMonitor();

        // Log the new hDC for the PBuffer:
        pbuffersMonitor.onPBufferhDCRelease(hPbuffer, hDC);
    }

    SU_END_WGL_FUNCTION_WRAPPER(ap_wglReleasePbufferDCARB);

    return retVal;
}

BOOL APIENTRY wglDestroyPbufferARB(HPBUFFERARB hPbuffer)
{
    SU_START_WGL_FUNCTION_WRAPPER(ap_wglDestroyPbufferARB);

    BOOL retVal = FALSE;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_wglDestroyPbufferARB, 1, OS_TOBJ_ID_GL_HPBUFFERARB, hPbuffer);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(wglDestroyPbufferARB, (hPbuffer), retVal);

    if (retVal == TRUE)
    {
        // Get the PBuffer monitor
        gsPBuffersMonitor& pbuffersMonitor = gs_stat_openGLMonitorInstance.pbuffersMonitor();

        // Delete the PBuffer from the PBuffer logger:
        pbuffersMonitor.onPBufferDeletion(hPbuffer);
    }

    SU_END_WGL_FUNCTION_WRAPPER(ap_wglDestroyPbufferARB);

    return retVal;
}

BOOL APIENTRY wglQueryPbufferARB(HPBUFFERARB hPbuffer, int iAttribute, int* piValue)
{
    SU_START_WGL_FUNCTION_WRAPPER(ap_wglQueryPbufferARB);

    BOOL retVal = FALSE;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_wglQueryPbufferARB, 3, OS_TOBJ_ID_GL_HPBUFFERARB, hPbuffer, OS_TOBJ_ID_INT_PARAMETER, iAttribute, OS_TOBJ_ID_P_INT_PARAMETER, piValue);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(wglQueryPbufferARB, (hPbuffer, iAttribute, piValue), retVal);

    SU_END_WGL_FUNCTION_WRAPPER(ap_wglQueryPbufferARB);

    return retVal;
}

//////////////////////////////////////////////////////////////////////////
// WGL_ARB_pixel_format
//////////////////////////////////////////////////////////////////////////
BOOL APIENTRY wglGetPixelFormatAttribivARB(HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int* piAttributes, int* piValues)
{
    SU_START_WGL_FUNCTION_WRAPPER(ap_wglGetPixelFormatAttribivARB);

    BOOL retVal = FALSE;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_wglGetPixelFormatAttribivARB, 6, OS_TOBJ_ID_WIN32_HDC_PARAMETER, hdc, OS_TOBJ_ID_INT_PARAMETER, iPixelFormat, OS_TOBJ_ID_INT_PARAMETER, iLayerPlane, OS_TOBJ_ID_WIN32_UINT_PARAMETER, nAttributes, OS_TOBJ_ID_P_INT_PARAMETER, piAttributes, OS_TOBJ_ID_P_INT_PARAMETER, piValues);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(wglGetPixelFormatAttribivARB, (hdc, iPixelFormat, iLayerPlane, nAttributes, piAttributes, piValues), retVal);

    SU_END_WGL_FUNCTION_WRAPPER(ap_wglGetPixelFormatAttribivARB);

    return retVal;
}

BOOL APIENTRY wglGetPixelFormatAttribfvARB(HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int* piAttributes, FLOAT* pfValues)
{
    SU_START_WGL_FUNCTION_WRAPPER(ap_wglGetPixelFormatAttribfvARB);

    BOOL retVal = FALSE;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_wglGetPixelFormatAttribfvARB, 6, OS_TOBJ_ID_WIN32_HDC_PARAMETER, hdc, OS_TOBJ_ID_INT_PARAMETER, iPixelFormat, OS_TOBJ_ID_INT_PARAMETER, iLayerPlane, OS_TOBJ_ID_WIN32_UINT_PARAMETER, nAttributes, OS_TOBJ_ID_P_INT_PARAMETER, piAttributes, OS_TOBJ_ID_P_WIN32_FLOAT_PARAMETER, pfValues);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(wglGetPixelFormatAttribfvARB, (hdc, iPixelFormat, iLayerPlane, nAttributes, piAttributes, pfValues), retVal);

    SU_END_WGL_FUNCTION_WRAPPER(ap_wglGetPixelFormatAttribfvARB);

    return retVal;
}

BOOL APIENTRY wglChoosePixelFormatARB(HDC hdc, const int* piAttribIList, const FLOAT* pfAttribFList, UINT nMaxFormats, int* piFormats, UINT* nNumFormats)
{
    bool inNestedFunction = su_stat_interoperabilityHelper.isInNestedFunction();
    SU_START_WGL_FUNCTION_WRAPPER(ap_wglChoosePixelFormatARB);

    BOOL retVal = FALSE;

    if (!inNestedFunction)
    {
        // Log the call to this function:
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_wglChoosePixelFormatARB, 6, OS_TOBJ_ID_WIN32_HDC_PARAMETER, hdc, OS_TOBJ_ID_P_INT_PARAMETER, piAttribIList, OS_TOBJ_ID_P_WIN32_FLOAT_PARAMETER, pfAttribFList, OS_TOBJ_ID_WIN32_UINT_PARAMETER, nMaxFormats, OS_TOBJ_ID_P_INT_PARAMETER, piFormats, OS_TOBJ_ID_P_WIN32_UINT_PARAMETER, nNumFormats);
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(wglChoosePixelFormatARB, (hdc, piAttribIList, pfAttribFList, nMaxFormats, piFormats, nNumFormats), retVal);

    SU_END_WGL_FUNCTION_WRAPPER(ap_wglChoosePixelFormatARB);

    return retVal;
}

//////////////////////////////////////////////////////////////////////////
// WGL_ARB_make_current_read
//////////////////////////////////////////////////////////////////////////
BOOL APIENTRY wglMakeContextCurrentARB(HDC hDrawDC, HDC hReadDC, HGLRC hglrc)
{
    bool inNestedFunction = su_stat_interoperabilityHelper.isInNestedFunction();
    SU_START_WGL_FUNCTION_WRAPPER(ap_wglMakeContextCurrentARB);

    BOOL retVal = FALSE;

    if (!inNestedFunction)
    {
        // Log the call to this function:
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_wglMakeContextCurrentARB, 3, OS_TOBJ_ID_WIN32_HDC_PARAMETER, hDrawDC, OS_TOBJ_ID_WIN32_HDC_PARAMETER, hReadDC, OS_TOBJ_ID_WIN32_HGLRC_PARAMETER, hglrc);
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(wglMakeContextCurrentARB, (hDrawDC, hReadDC, hglrc), retVal);

    SU_END_WGL_FUNCTION_WRAPPER(ap_wglMakeContextCurrentARB);

    return retVal;
}

HDC APIENTRY wglGetCurrentReadDCARB(void)
{
    SU_START_WGL_FUNCTION_WRAPPER(ap_wglGetCurrentReadDCARB);

    HDC retVal = NULL;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_wglGetCurrentReadDCARB, 0);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(wglGetCurrentReadDCARB, (), retVal);

    SU_END_WGL_FUNCTION_WRAPPER(ap_wglGetCurrentReadDCARB);

    return retVal;
}

//////////////////////////////////////////////////////////////////////////
// WGL_ARB_render_texture
//////////////////////////////////////////////////////////////////////////
BOOL APIENTRY wglBindTexImageARB(HPBUFFERARB hPbuffer, int iBuffer)
{
    SU_START_WGL_FUNCTION_WRAPPER(ap_wglBindTexImageARB);

    BOOL retVal = FALSE;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_wglBindTexImageARB, 2, OS_TOBJ_ID_GL_HPBUFFERARB, hPbuffer, OS_TOBJ_ID_INT_PARAMETER, iBuffer);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(wglBindTexImageARB, (hPbuffer, iBuffer), retVal);

    SU_END_WGL_FUNCTION_WRAPPER(ap_wglBindTexImageARB);

    return retVal;
}

BOOL APIENTRY wglReleaseTexImageARB(HPBUFFERARB hPbuffer, int iBuffer)
{
    SU_START_WGL_FUNCTION_WRAPPER(ap_wglReleaseTexImageARB);

    BOOL retVal = FALSE;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_wglReleaseTexImageARB, 2, OS_TOBJ_ID_GL_HPBUFFERARB, hPbuffer, OS_TOBJ_ID_INT_PARAMETER, iBuffer);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(wglReleaseTexImageARB, (hPbuffer, iBuffer), retVal);

    SU_END_WGL_FUNCTION_WRAPPER(ap_wglReleaseTexImageARB);

    return retVal;
}

BOOL APIENTRY wglSetPbufferAttribARB(HPBUFFERARB hPbuffer, const int* piAttribList)
{
    SU_START_WGL_FUNCTION_WRAPPER(ap_wglSetPbufferAttribARB);

    BOOL retVal = FALSE;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_wglSetPbufferAttribARB, 2, OS_TOBJ_ID_GL_HPBUFFERARB, hPbuffer, OS_TOBJ_ID_P_INT_PARAMETER, piAttribList);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(wglSetPbufferAttribARB, (hPbuffer, piAttribList), retVal);

    SU_END_WGL_FUNCTION_WRAPPER(ap_wglSetPbufferAttribARB);

    return retVal;
}

//////////////////////////////////////////////////////////////////////////
// WGL_ARB_buffer_region
//////////////////////////////////////////////////////////////////////////
HANDLE APIENTRY wglCreateBufferRegionARB(HDC hDC, int iLayerPlane, UINT uType)
{
    SU_START_WGL_FUNCTION_WRAPPER(ap_wglCreateBufferRegionARB);

    HANDLE retVal = FALSE;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_wglCreateBufferRegionARB, 3, OS_TOBJ_ID_WIN32_HDC_PARAMETER, hDC, OS_TOBJ_ID_INT_PARAMETER, iLayerPlane, OS_TOBJ_ID_WIN32_UINT_PARAMETER, uType);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(wglCreateBufferRegionARB, (hDC, iLayerPlane, uType), retVal);

    SU_END_WGL_FUNCTION_WRAPPER(ap_wglCreateBufferRegionARB);

    return retVal;
}

VOID APIENTRY wglDeleteBufferRegionARB(HANDLE hRegion)
{
    SU_START_WGL_FUNCTION_WRAPPER(ap_wglDeleteBufferRegionARB);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_wglDeleteBufferRegionARB, 1, OS_TOBJ_ID_WIN32_HANDLE_PARAMETER, hRegion);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(wglDeleteBufferRegionARB, (hRegion));

    SU_END_WGL_FUNCTION_WRAPPER(ap_wglDeleteBufferRegionARB);
}

BOOL APIENTRY wglSaveBufferRegionARB(HANDLE hRegion, int x, int y, int width, int height)
{
    SU_START_WGL_FUNCTION_WRAPPER(ap_wglSaveBufferRegionARB);

    BOOL retVal = FALSE;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_wglCreateBufferRegionARB, 5, OS_TOBJ_ID_WIN32_HANDLE_PARAMETER, hRegion, OS_TOBJ_ID_INT_PARAMETER, x, OS_TOBJ_ID_INT_PARAMETER, y, OS_TOBJ_ID_INT_PARAMETER, width, OS_TOBJ_ID_INT_PARAMETER, height);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(wglSaveBufferRegionARB, (hRegion, x, y, width, height), retVal);

    SU_END_WGL_FUNCTION_WRAPPER(ap_wglSaveBufferRegionARB);

    return retVal;
}

BOOL APIENTRY wglRestoreBufferRegionARB(HANDLE hRegion, int x, int y, int width, int height, int xSrc, int ySrc)
{
    SU_START_WGL_FUNCTION_WRAPPER(ap_wglRestoreBufferRegionARB);

    BOOL retVal = FALSE;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_wglRestoreBufferRegionARB, 7, OS_TOBJ_ID_WIN32_HANDLE_PARAMETER, hRegion, OS_TOBJ_ID_INT_PARAMETER, x, OS_TOBJ_ID_INT_PARAMETER, y, OS_TOBJ_ID_INT_PARAMETER, width, OS_TOBJ_ID_INT_PARAMETER, height, OS_TOBJ_ID_INT_PARAMETER, xSrc, OS_TOBJ_ID_INT_PARAMETER, ySrc);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(wglRestoreBufferRegionARB, (hRegion, x, y, width, height, xSrc, ySrc), retVal);

    SU_END_WGL_FUNCTION_WRAPPER(ap_wglRestoreBufferRegionARB);

    return retVal;
}

//////////////////////////////////////////////////////////////////////////
// WGL_ARB_multisample
//////////////////////////////////////////////////////////////////////////
// See GL_ARB_multisample

//////////////////////////////////////////////////////////////////////////
// WGL_ARB_pixel_format_float
//////////////////////////////////////////////////////////////////////////
// See GL_ARB_color_buffer_float

//////////////////////////////////////////////////////////////////////////
// WGL_ARB_framebuffer_sRGB
//////////////////////////////////////////////////////////////////////////
// No new functions

//////////////////////////////////////////////////////////////////////////
// WGL_ARB_create_context
//////////////////////////////////////////////////////////////////////////
HGLRC APIENTRY wglCreateContextAttribsARB(HDC hDC, HGLRC hShareContext, const int* attribList)
{
    bool inNestedFunction = su_stat_interoperabilityHelper.isInNestedFunction();
    SU_START_WGL_FUNCTION_WRAPPER(ap_wglCreateContextAttribsARB);

    HGLRC retVal = NULL;

    // Get the current execution mode:
    apExecutionMode currentExeuctionMode = suDebuggedProcessExecutionMode();

    // Force the debug flag if necessary:
    const int* spyAttribList = attribList;
    bool isDebugFlagForced = false;
    bool createdAttribList = false;

    if (!suGetGlobalServerEnvironmentSettings().m_gsDontForceOpenGLDebugContexts)
    {
        apGLRenderContextGraphicsInfo::forceDebugContext(currentExeuctionMode, attribList, spyAttribList, isDebugFlagForced);
        createdAttribList = true;
    }

    if (!inNestedFunction)
    {
        // Count the number of attributes to display them in the calls history view:
        int numberOfAttribs = 0;

        if (NULL != attribList)
        {
            // Add the name and value of each attribute
            while (0 != attribList[numberOfAttribs])
            {
                numberOfAttribs += 2;
            }

            // Add the terminating 0:
            numberOfAttribs++;
        }

        // Log the call to this function:
        if (numberOfAttribs > 0)
        {
            gs_stat_openGLMonitorInstance.addFunctionCall(ap_wglCreateContextAttribsARB, 3, OS_TOBJ_ID_WIN32_HDC_PARAMETER, hDC, OS_TOBJ_ID_WIN32_HGLRC_PARAMETER, hShareContext, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_INT_PARAMETER, numberOfAttribs, attribList);
        }
        else
        {
            gs_stat_openGLMonitorInstance.addFunctionCall(ap_wglCreateContextAttribsARB, 3, OS_TOBJ_ID_WIN32_HDC_PARAMETER, hDC, OS_TOBJ_ID_WIN32_HGLRC_PARAMETER, hShareContext, OS_TOBJ_ID_P_INT_PARAMETER, attribList);
        }
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(wglCreateContextAttribsARB, (hDC, hShareContext, spyAttribList), retVal);

    // If the context creation succeeded:
    if ((retVal != NULL) && (!inNestedFunction))
    {
        // Register the created context in our OpenGL monitor:
        gs_stat_openGLMonitorInstance.onContextCreation(hDC, retVal, ap_wglCreateContextAttribsARB, spyAttribList, isDebugFlagForced);

        // Mark the sharing as needed:
        // If we share another context's list, register this fact:
        if (hShareContext != NULL)
        {
            gs_stat_openGLMonitorInstance.onShareLists(hShareContext, retVal);
        }
    }

    // Release the attribute list:
    if (createdAttribList)
    {
        apGLRenderContextGraphicsInfo::releaseAttribListCreatedForDebugContextForcing(spyAttribList);
    }

    SU_END_WGL_FUNCTION_WRAPPER(ap_wglCreateContextAttribsARB);

    return retVal;
}

//////////////////////////////////////////////////////////////////////////
// WGL_EXT_swap_control
//////////////////////////////////////////////////////////////////////////
BOOL APIENTRY wglSwapIntervalEXT(int interval)
{
    SU_START_WGL_FUNCTION_WRAPPER(ap_wglSwapIntervalEXT);

    BOOL retVal = FALSE;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_wglSwapIntervalEXT, 1, OS_TOBJ_ID_INT_PARAMETER, interval);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(wglSwapIntervalEXT, (interval), retVal);

    SU_END_WGL_FUNCTION_WRAPPER(ap_wglSwapIntervalEXT);

    return retVal;
}

int APIENTRY wglGetSwapIntervalEXT()
{
    SU_START_WGL_FUNCTION_WRAPPER(ap_wglGetSwapIntervalEXT);

    int retVal = 0;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_wglGetSwapIntervalEXT, 0);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(wglGetSwapIntervalEXT, (), retVal);

    SU_END_WGL_FUNCTION_WRAPPER(ap_wglGetSwapIntervalEXT);

    return retVal;
}

//////////////////////////////////////////////////////////////////////////
// WGL_NV_present_video
//////////////////////////////////////////////////////////////////////////
int APIENTRY wglEnumerateVideoDevicesNV(HDC hDc, HVIDEOOUTPUTDEVICENV* phDeviceList)
{
    SU_START_WGL_FUNCTION_WRAPPER(ap_wglEnumerateVideoDevicesNV);

    int retVal = 0;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_wglEnumerateVideoDevicesNV, 2, OS_TOBJ_ID_WIN32_HDC_PARAMETER, hDc, OS_TOBJ_ID_POINTER_TO_POINTER_PARAMETER, phDeviceList);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(wglEnumerateVideoDevicesNV, (hDc, phDeviceList), retVal);

    SU_END_WGL_FUNCTION_WRAPPER(ap_wglEnumerateVideoDevicesNV);

    return retVal;
}

BOOL APIENTRY wglBindVideoDeviceNV(HDC hDc, unsigned int uVideoSlot, HVIDEOOUTPUTDEVICENV hVideoDevice, const int* piAttribList)
{
    SU_START_WGL_FUNCTION_WRAPPER(ap_wglBindVideoDeviceNV);

    BOOL retVal = FALSE;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_wglBindVideoDeviceNV, 4, OS_TOBJ_ID_WIN32_HDC_PARAMETER, hDc, OS_TOBJ_ID_UNSIGNED_INT_PARAMETER, uVideoSlot, OS_TOBJ_ID_POINTER_PARAMETER, hVideoDevice, OS_TOBJ_ID_P_INT_PARAMETER, piAttribList);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(wglBindVideoDeviceNV, (hDc, uVideoSlot, hVideoDevice, piAttribList), retVal);

    SU_END_WGL_FUNCTION_WRAPPER(ap_wglBindVideoDeviceNV);

    return retVal;
}

BOOL APIENTRY wglQueryCurrentContextNV(int iAttribute, int* piValue)
{
    SU_START_WGL_FUNCTION_WRAPPER(ap_wglQueryCurrentContextNV);

    BOOL retVal = FALSE;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_wglQueryCurrentContextNV, 2, OS_TOBJ_ID_INT_PARAMETER, iAttribute, OS_TOBJ_ID_P_INT_PARAMETER, piValue);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(wglQueryCurrentContextNV, (iAttribute, piValue), retVal);

    SU_END_WGL_FUNCTION_WRAPPER(ap_wglQueryCurrentContextNV);

    return retVal;
}

//////////////////////////////////////////////////////////////////////////
// WGL_NV_video_out
//////////////////////////////////////////////////////////////////////////
BOOL APIENTRY wglGetVideoDeviceNV(HDC hDC, int numDevices, HPVIDEODEV* hVideoDevice)
{
    SU_START_WGL_FUNCTION_WRAPPER(ap_wglGetVideoDeviceNV);

    BOOL retVal = FALSE;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_wglGetVideoDeviceNV, 3, OS_TOBJ_ID_WIN32_HDC_PARAMETER, hDC, OS_TOBJ_ID_INT_PARAMETER, numDevices, OS_TOBJ_ID_POINTER_TO_POINTER_PARAMETER, hVideoDevice);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(wglGetVideoDeviceNV, (hDC, numDevices, hVideoDevice), retVal);

    SU_END_WGL_FUNCTION_WRAPPER(ap_wglGetVideoDeviceNV);

    return retVal;
}

BOOL APIENTRY wglReleaseVideoDeviceNV(HPVIDEODEV hVideoDevice)
{
    SU_START_WGL_FUNCTION_WRAPPER(ap_wglReleaseVideoDeviceNV);

    BOOL retVal = FALSE;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_wglReleaseVideoDeviceNV, 1, OS_TOBJ_ID_POINTER_PARAMETER, hVideoDevice);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(wglReleaseVideoDeviceNV, (hVideoDevice), retVal);

    SU_END_WGL_FUNCTION_WRAPPER(ap_wglReleaseVideoDeviceNV);

    return retVal;
}

BOOL APIENTRY wglBindVideoImageNV(HPVIDEODEV hVideoDevice, HPBUFFERARB hPbuffer, int iVideoBuffer)
{
    SU_START_WGL_FUNCTION_WRAPPER(ap_wglBindVideoImageNV);

    BOOL retVal = FALSE;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_wglBindVideoImageNV, 3, OS_TOBJ_ID_POINTER_PARAMETER, hVideoDevice, OS_TOBJ_ID_GL_HPBUFFERARB, hPbuffer, OS_TOBJ_ID_INT_PARAMETER, iVideoBuffer);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(wglBindVideoImageNV, (hVideoDevice, hPbuffer, iVideoBuffer), retVal);

    SU_END_WGL_FUNCTION_WRAPPER(ap_wglBindVideoImageNV);

    return retVal;
}

BOOL APIENTRY wglReleaseVideoImageNV(HPBUFFERARB hPbuffer, int iVideoBuffer)
{
    SU_START_WGL_FUNCTION_WRAPPER(ap_wglReleaseVideoImageNV);

    BOOL retVal = FALSE;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_wglReleaseVideoImageNV, 2, OS_TOBJ_ID_GL_HPBUFFERARB, hPbuffer, OS_TOBJ_ID_INT_PARAMETER, iVideoBuffer);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(wglReleaseVideoImageNV, (hPbuffer, iVideoBuffer), retVal);

    SU_END_WGL_FUNCTION_WRAPPER(ap_wglReleaseVideoImageNV);

    return retVal;
}

BOOL APIENTRY wglSendPbufferToVideoNV(HPBUFFERARB hPbuffer, int iBufferType, unsigned long* pulCounterPbuffer, BOOL bBlock)
{
    SU_START_WGL_FUNCTION_WRAPPER(ap_wglSendPbufferToVideoNV);

    BOOL retVal = FALSE;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_wglSendPbufferToVideoNV, 4, OS_TOBJ_ID_GL_HPBUFFERARB, hPbuffer, OS_TOBJ_ID_INT_PARAMETER, iBufferType, OS_TOBJ_ID_POINTER_PARAMETER, pulCounterPbuffer, OS_TOBJ_ID_WIN32_BOOL_PARAMETER, bBlock);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(wglSendPbufferToVideoNV, (hPbuffer, iBufferType, pulCounterPbuffer, bBlock), retVal);

    SU_END_WGL_FUNCTION_WRAPPER(ap_wglSendPbufferToVideoNV);

    return retVal;
}

BOOL APIENTRY wglGetVideoInfoNV(HPVIDEODEV hpVideoDevice, unsigned long* pulCounterOutputPbuffer, unsigned long* pulCounterOutputVideo)
{
    SU_START_WGL_FUNCTION_WRAPPER(ap_wglGetVideoInfoNV);

    BOOL retVal = FALSE;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_wglGetVideoInfoNV, 3, OS_TOBJ_ID_POINTER_PARAMETER, hpVideoDevice, OS_TOBJ_ID_POINTER_PARAMETER, pulCounterOutputPbuffer, OS_TOBJ_ID_POINTER_PARAMETER, pulCounterOutputVideo);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(wglGetVideoInfoNV, (hpVideoDevice, pulCounterOutputPbuffer, pulCounterOutputVideo), retVal);

    SU_END_WGL_FUNCTION_WRAPPER(ap_wglGetVideoInfoNV);

    return retVal;
}

//////////////////////////////////////////////////////////////////////////
// WGL_NV_swap_group
//////////////////////////////////////////////////////////////////////////
BOOL APIENTRY wglJoinSwapGroupNV(HDC hDC, GLuint group)
{
    SU_START_WGL_FUNCTION_WRAPPER(ap_wglJoinSwapGroupNV);

    BOOL retVal = FALSE;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_wglJoinSwapGroupNV, 2, OS_TOBJ_ID_WIN32_HDC_PARAMETER, hDC, OS_TOBJ_ID_GL_UINT_PARAMETER, group);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(wglJoinSwapGroupNV, (hDC, group), retVal);

    SU_END_WGL_FUNCTION_WRAPPER(ap_wglJoinSwapGroupNV);

    return retVal;
}

BOOL APIENTRY wglBindSwapBarrierNV(GLuint group, GLuint barrier)
{
    SU_START_WGL_FUNCTION_WRAPPER(ap_wglBindSwapBarrierNV);

    BOOL retVal = FALSE;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_wglBindSwapBarrierNV, 2, OS_TOBJ_ID_GL_UINT_PARAMETER, group, OS_TOBJ_ID_GL_UINT_PARAMETER, barrier);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(wglBindSwapBarrierNV, (group, barrier), retVal);

    SU_END_WGL_FUNCTION_WRAPPER(ap_wglBindSwapBarrierNV);

    return retVal;
}

BOOL APIENTRY wglQuerySwapGroupNV(HDC hDC, GLuint* group, GLuint* barrier)
{
    SU_START_WGL_FUNCTION_WRAPPER(ap_wglQuerySwapGroupNV);

    BOOL retVal = FALSE;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_wglQuerySwapGroupNV, 3, OS_TOBJ_ID_WIN32_HDC_PARAMETER, hDC, OS_TOBJ_ID_GL_P_UINT_PARAMETER, group, OS_TOBJ_ID_GL_P_UINT_PARAMETER, barrier);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(wglQuerySwapGroupNV, (hDC, group, barrier), retVal);

    SU_END_WGL_FUNCTION_WRAPPER(ap_wglQuerySwapGroupNV);

    return retVal;
}

BOOL APIENTRY wglQueryMaxSwapGroupsNV(HDC hDC, GLuint* maxGroups, GLuint* maxBarriers)
{
    SU_START_WGL_FUNCTION_WRAPPER(ap_wglQueryMaxSwapGroupsNV);

    BOOL retVal = FALSE;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_wglQueryMaxSwapGroupsNV, 3, OS_TOBJ_ID_WIN32_HDC_PARAMETER, hDC, OS_TOBJ_ID_GL_P_UINT_PARAMETER, maxGroups, OS_TOBJ_ID_GL_P_UINT_PARAMETER, maxBarriers);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(wglQueryMaxSwapGroupsNV, (hDC, maxGroups, maxBarriers), retVal);

    SU_END_WGL_FUNCTION_WRAPPER(ap_wglQueryMaxSwapGroupsNV);

    return retVal;
}

BOOL APIENTRY wglQueryFrameCountNV(HDC hDC, GLuint* count)
{
    SU_START_WGL_FUNCTION_WRAPPER(ap_wglQueryFrameCountNV);

    BOOL retVal = FALSE;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_wglQueryFrameCountNV, 2, OS_TOBJ_ID_WIN32_HDC_PARAMETER, hDC, OS_TOBJ_ID_GL_P_UINT_PARAMETER, count);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(wglQueryFrameCountNV, (hDC, count), retVal);

    SU_END_WGL_FUNCTION_WRAPPER(ap_wglQueryFrameCountNV);

    return retVal;
}

BOOL APIENTRY wglResetFrameCountNV(HDC hDC)
{
    SU_START_WGL_FUNCTION_WRAPPER(ap_wglResetFrameCountNV);

    BOOL retVal = FALSE;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_wglResetFrameCountNV, 1, OS_TOBJ_ID_WIN32_HDC_PARAMETER, hDC);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(wglResetFrameCountNV, (hDC), retVal);

    SU_END_WGL_FUNCTION_WRAPPER(ap_wglResetFrameCountNV);

    return retVal;
}

//////////////////////////////////////////////////////////////////////////
// WGL_NV_gpu_affinity
//////////////////////////////////////////////////////////////////////////
BOOL APIENTRY wglEnumGpusNV(UINT iGpuIndex, HGPUNV* phGpu)
{
    SU_START_WGL_FUNCTION_WRAPPER(ap_wglEnumGpusNV);

    BOOL retVal = FALSE;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_wglEnumGpusNV, 2, OS_TOBJ_ID_WIN32_UINT_PARAMETER, iGpuIndex, OS_TOBJ_ID_POINTER_TO_POINTER_PARAMETER, phGpu);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(wglEnumGpusNV, (iGpuIndex, phGpu), retVal);

    SU_END_WGL_FUNCTION_WRAPPER(ap_wglEnumGpusNV);

    return retVal;
}

BOOL APIENTRY wglEnumGpuDevicesNV(HGPUNV hGpu, UINT iDeviceIndex, PGPU_DEVICE lpGpuDevice)
{
    SU_START_WGL_FUNCTION_WRAPPER(ap_wglEnumGpuDevicesNV);

    BOOL retVal = FALSE;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_wglEnumGpuDevicesNV, 3, OS_TOBJ_ID_POINTER_PARAMETER, hGpu, OS_TOBJ_ID_WIN32_UINT_PARAMETER, iDeviceIndex, OS_TOBJ_ID_POINTER_PARAMETER, lpGpuDevice);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(wglEnumGpuDevicesNV, (hGpu, iDeviceIndex, lpGpuDevice), retVal);

    SU_END_WGL_FUNCTION_WRAPPER(ap_wglEnumGpuDevicesNV);

    return retVal;
}

HDC APIENTRY wglCreateAffinityDCNV(const HGPUNV* phGpuList)
{
    SU_START_WGL_FUNCTION_WRAPPER(ap_wglCreateAffinityDCNV);

    HDC retVal = NULL;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_wglCreateAffinityDCNV, 1, OS_TOBJ_ID_POINTER_TO_POINTER_PARAMETER, phGpuList);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(wglCreateAffinityDCNV, (phGpuList), retVal);

    SU_END_WGL_FUNCTION_WRAPPER(ap_wglCreateAffinityDCNV);

    return retVal;
}

BOOL APIENTRY wglEnumGpusFromAffinityDCNV(HDC hAffinityDC, UINT iGpuIndex, HGPUNV* hGpu)
{
    SU_START_WGL_FUNCTION_WRAPPER(ap_wglEnumGpusFromAffinityDCNV);

    BOOL retVal = FALSE;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_wglEnumGpusFromAffinityDCNV, 3, OS_TOBJ_ID_WIN32_HDC_PARAMETER, hAffinityDC, OS_TOBJ_ID_WIN32_UINT_PARAMETER, iGpuIndex, OS_TOBJ_ID_POINTER_TO_POINTER_PARAMETER, hGpu);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(wglEnumGpusFromAffinityDCNV, (hAffinityDC, iGpuIndex, hGpu), retVal);

    SU_END_WGL_FUNCTION_WRAPPER(ap_wglEnumGpusFromAffinityDCNV);

    return retVal;
}

BOOL APIENTRY wglDeleteDCNV(HDC hdc)
{
    SU_START_WGL_FUNCTION_WRAPPER(ap_wglDeleteDCNV);

    BOOL retVal = FALSE;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_wglDeleteDCNV, 1, OS_TOBJ_ID_WIN32_HDC_PARAMETER, hdc);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(wglDeleteDCNV, (hdc), retVal);

    SU_END_WGL_FUNCTION_WRAPPER(ap_wglDeleteDCNV);

    return retVal;
}

//////////////////////////////////////////////////////////////////////////
// WGL_AMD_gpu_association
//////////////////////////////////////////////////////////////////////////
UINT APIENTRY wglGetGPUIDsAMD(UINT maxCount, UINT* ids)
{
    SU_START_WGL_FUNCTION_WRAPPER(ap_wglGetGPUIDsAMD);

    UINT retVal = 0;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_wglGetGPUIDsAMD, 2, OS_TOBJ_ID_WIN32_UINT_PARAMETER, maxCount, OS_TOBJ_ID_P_WIN32_UINT_PARAMETER, ids);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(wglGetGPUIDsAMD, (maxCount, ids), retVal);

    SU_END_WGL_FUNCTION_WRAPPER(ap_wglGetGPUIDsAMD);

    return retVal;
}

INT APIENTRY wglGetGPUInfoAMD(UINT id, INT property, GLenum dataType, UINT size, void* data)
{
    SU_START_WGL_FUNCTION_WRAPPER(ap_wglGetGPUInfoAMD);

    INT retVal = 0;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_wglGetGPUInfoAMD, 5, OS_TOBJ_ID_WIN32_UINT_PARAMETER, id, OS_TOBJ_ID_WIN32_INT_PARAMETER, property, OS_TOBJ_ID_GL_ENUM_PARAMETER, dataType, OS_TOBJ_ID_WIN32_UINT_PARAMETER, size, OS_TOBJ_ID_POINTER_PARAMETER, data);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(wglGetGPUInfoAMD, (id, property, dataType, size, data), retVal);

    SU_END_WGL_FUNCTION_WRAPPER(ap_wglGetGPUInfoAMD);

    return retVal;
}

UINT APIENTRY wglGetContextGPUIDAMD(HGLRC hglrc)
{
    SU_START_WGL_FUNCTION_WRAPPER(ap_wglGetContextGPUIDAMD);

    UINT retVal = 0;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_wglGetContextGPUIDAMD, 1, OS_TOBJ_ID_WIN32_HGLRC_PARAMETER, hglrc);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(wglGetContextGPUIDAMD, (hglrc), retVal);

    SU_END_WGL_FUNCTION_WRAPPER(ap_wglGetContextGPUIDAMD);

    return retVal;
}

HGLRC APIENTRY wglCreateAssociatedContextAMD(UINT id)
{
    SU_START_WGL_FUNCTION_WRAPPER(ap_wglCreateAssociatedContextAMD);

    HGLRC retVal = NULL;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_wglCreateAssociatedContextAMD, 1, OS_TOBJ_ID_WIN32_UINT_PARAMETER, id);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(wglCreateAssociatedContextAMD, (id), retVal);

    SU_END_WGL_FUNCTION_WRAPPER(ap_wglCreateAssociatedContextAMD);

    return retVal;
}

HGLRC APIENTRY wglCreateAssociatedContextAttribsAMD(UINT id, HGLRC hShareContext,
                                                    const int* attribList)
{
    SU_START_WGL_FUNCTION_WRAPPER(ap_wglCreateAssociatedContextAttribsAMD);

    HGLRC retVal = NULL;

    // Log the call to this function:

    // Count the number of attributes to display them in the calls history view:
    int numberOfAttribs = 0;

    if (NULL != attribList)
    {
        // Add the name and value of each attribute
        while (0 != attribList[numberOfAttribs])
        {
            numberOfAttribs += 2;
        }

        // Add the terminating 0:
        numberOfAttribs++;
    }

    if (numberOfAttribs > 0)
    {
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_wglCreateAssociatedContextAttribsAMD, 3, OS_TOBJ_ID_WIN32_UINT_PARAMETER, id, OS_TOBJ_ID_WIN32_HGLRC_PARAMETER, hShareContext, OS_TOBJ_ID_VECTOR_PARAMETER, OS_TOBJ_ID_INT_PARAMETER, numberOfAttribs, attribList);
    }
    else
    {
        gs_stat_openGLMonitorInstance.addFunctionCall(ap_wglCreateAssociatedContextAttribsAMD, 3, OS_TOBJ_ID_WIN32_UINT_PARAMETER, id, OS_TOBJ_ID_WIN32_HGLRC_PARAMETER, hShareContext, OS_TOBJ_ID_P_INT_PARAMETER, attribList);
    }

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(wglCreateAssociatedContextAttribsAMD, (id, hShareContext, attribList), retVal);

    SU_END_WGL_FUNCTION_WRAPPER(ap_wglCreateAssociatedContextAttribsAMD);

    return retVal;
}

BOOL APIENTRY wglDeleteAssociatedContextAMD(HGLRC hglrc)
{
    SU_START_WGL_FUNCTION_WRAPPER(ap_wglDeleteAssociatedContextAMD);

    BOOL retVal = FALSE;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_wglDeleteAssociatedContextAMD, 1, OS_TOBJ_ID_WIN32_HGLRC_PARAMETER, hglrc);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(wglDeleteAssociatedContextAMD, (hglrc), retVal);

    SU_END_WGL_FUNCTION_WRAPPER(ap_wglDeleteAssociatedContextAMD);

    return retVal;
}

BOOL APIENTRY wglMakeAssociatedContextCurrentAMD(HGLRC hglrc)
{
    SU_START_WGL_FUNCTION_WRAPPER(ap_wglMakeAssociatedContextCurrentAMD);

    BOOL retVal = FALSE;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_wglMakeAssociatedContextCurrentAMD, 1, OS_TOBJ_ID_WIN32_HGLRC_PARAMETER, hglrc);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(wglMakeAssociatedContextCurrentAMD, (hglrc), retVal);

    SU_END_WGL_FUNCTION_WRAPPER(ap_wglMakeAssociatedContextCurrentAMD);

    return retVal;
}

HGLRC APIENTRY wglGetCurrentAssociatedContextAMD(void)
{
    SU_START_WGL_FUNCTION_WRAPPER(ap_wglGetCurrentAssociatedContextAMD);

    HGLRC retVal = NULL;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_wglGetCurrentAssociatedContextAMD, 0);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(wglGetCurrentAssociatedContextAMD, (), retVal);

    SU_END_WGL_FUNCTION_WRAPPER(ap_wglGetCurrentAssociatedContextAMD);

    return retVal;
}

VOID APIENTRY wglBlitContextFramebufferAMD(HGLRC dstCtx, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter)
{
    SU_START_WGL_FUNCTION_WRAPPER(ap_wglBlitContextFramebufferAMD);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_wglBlitContextFramebufferAMD, 11, OS_TOBJ_ID_WIN32_HGLRC_PARAMETER, dstCtx, OS_TOBJ_ID_GL_INT_PARAMETER, srcX0, OS_TOBJ_ID_GL_INT_PARAMETER, srcY0, OS_TOBJ_ID_GL_INT_PARAMETER, srcX1, OS_TOBJ_ID_GL_INT_PARAMETER, srcY1, OS_TOBJ_ID_GL_INT_PARAMETER, dstX0, OS_TOBJ_ID_GL_INT_PARAMETER, dstY0, OS_TOBJ_ID_GL_INT_PARAMETER, dstX1, OS_TOBJ_ID_GL_INT_PARAMETER, dstY1, OS_TOBJ_ID_GL_BITFIELD_PARAMETER, mask, OS_TOBJ_ID_GL_ENUM_PARAMETER, filter);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(wglBlitContextFramebufferAMD, (dstCtx, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter));

    SU_END_WGL_FUNCTION_WRAPPER(ap_wglBlitContextFramebufferAMD);
}


#elif ((AMDT_BUILD_TARGET == AMDT_LINUX_OS) && (AMDT_LINUX_VARIANT == AMDT_GENERIC_LINUX_VARIANT))

// --------------------------------------------------------
//             GLX Extensions Wrapper functions
// --------------------------------------------------------

//////////////////////////////////////////////////////////////////////////
// GLX_SGIX_fbconfig
//////////////////////////////////////////////////////////////////////////
int APIENTRY glXGetFBConfigAttribSGIX(Display* dpy, GLXFBConfigSGIX config, int attribute, int* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glXGetFBConfigAttribSGIX);

    int retVal = 0;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glXGetFBConfigAttribSGIX, 3, OS_TOBJ_ID_POINTER_PARAMETER, dpy, OS_TOBJ_ID_POINTER_PARAMETER, config, OS_TOBJ_ID_INT_PARAMETER, attribute, OS_TOBJ_ID_P_INT_PARAMETER, value);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glXGetFBConfigAttribSGIX, (dpy, config, attribute, value), retVal);

    SU_END_FUNCTION_WRAPPER(ap_glXGetFBConfigAttribSGIX);

    return retVal;
}

GLXFBConfigSGIX* APIENTRY glXChooseFBConfigSGIX(Display* dpy, int screen, int* attrib_list, int* nelements)
{
    SU_START_FUNCTION_WRAPPER(ap_glXChooseFBConfigSGIX);

    GLXFBConfigSGIX* retVal = 0;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glXChooseFBConfigSGIX, 4, OS_TOBJ_ID_POINTER_PARAMETER, dpy, OS_TOBJ_ID_INT_PARAMETER, screen, OS_TOBJ_ID_P_INT_PARAMETER, attrib_list, OS_TOBJ_ID_P_INT_PARAMETER, nelements);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glXChooseFBConfigSGIX, (dpy, screen, attrib_list, nelements), retVal);

    SU_END_FUNCTION_WRAPPER(ap_glXChooseFBConfigSGIX);

    return retVal;
}

GLXPixmap APIENTRY glXCreateGLXPixmapWithConfigSGIX(Display* dpy, GLXFBConfig config, Pixmap pixmap)
{
    SU_START_FUNCTION_WRAPPER(ap_glXCreateGLXPixmapWithConfigSGIX);

    GLXPixmap retVal = 0;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glXCreateGLXPixmapWithConfigSGIX, 3, OS_TOBJ_ID_POINTER_PARAMETER, dpy, OS_TOBJ_ID_POINTER_PARAMETER, config, OS_TOBJ_ID_XID_PARAMETER, pixmap);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glXCreateGLXPixmapWithConfigSGIX, (dpy, config, pixmap), retVal);

    SU_END_FUNCTION_WRAPPER(ap_glXCreateGLXPixmapWithConfigSGIX);

    return retVal;
}

GLXContext APIENTRY glXCreateContextWithConfigSGIX(Display* dpy, GLXFBConfig config, int render_type, GLXContext share_list, Bool direct)
{
    SU_START_FUNCTION_WRAPPER(ap_glXCreateContextWithConfigSGIX);

    GLXContext retVal = 0;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glXCreateContextWithConfigSGIX, 5, OS_TOBJ_ID_POINTER_PARAMETER, dpy, OS_TOBJ_ID_POINTER_PARAMETER, config, OS_TOBJ_ID_INT_PARAMETER, render_type, OS_TOBJ_ID_POINTER_PARAMETER, share_list, OS_TOBJ_ID_X11_BOOL_PARAMETER, direct);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glXCreateContextWithConfigSGIX, (dpy, config, render_type, share_list, direct), retVal);

    // If the context creation succeeded:
    if (retVal != NULL)
    {
        // Register the created context in our OpenGL monitor:
        gs_stat_openGLMonitorInstance.onContextCreation(dpy, retVal, ap_glXCreateContextWithConfigSGIX);

        // If we share another context's list, register this fact:
        if (share_list != NULL)
        {
            gs_stat_openGLMonitorInstance.onShareLists(share_list, retVal);
        }
    }

    SU_END_FUNCTION_WRAPPER(ap_glXCreateContextWithConfigSGIX);

    return retVal;
}

XVisualInfo* APIENTRY glXGetVisualFromFBConfigSGIX(Display* dpy, GLXFBConfig config)
{
    SU_START_FUNCTION_WRAPPER(ap_glXGetVisualFromFBConfigSGIX);

    XVisualInfo* retVal = 0;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glXGetVisualFromFBConfigSGIX, 2, OS_TOBJ_ID_POINTER_PARAMETER, dpy, OS_TOBJ_ID_POINTER_PARAMETER, config);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glXGetVisualFromFBConfigSGIX, (dpy, config), retVal);

    SU_END_FUNCTION_WRAPPER(ap_glXGetVisualFromFBConfigSGIX);

    return retVal;
}

GLXFBConfigSGIX APIENTRY glXGetFBConfigFromVisualSGIX(Display* dpy, XVisualInfo* vis)
{
    SU_START_FUNCTION_WRAPPER(ap_glXGetFBConfigFromVisualSGIX);

    GLXFBConfigSGIX retVal = 0;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glXGetFBConfigFromVisualSGIX, 2, OS_TOBJ_ID_POINTER_PARAMETER, dpy, OS_TOBJ_ID_POINTER_PARAMETER, vis);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glXGetFBConfigFromVisualSGIX, (dpy, vis), retVal);

    SU_END_FUNCTION_WRAPPER(ap_glXGetFBConfigFromVisualSGIX);

    return retVal;
}

//////////////////////////////////////////////////////////////////////////
// GLX_SGI_video_sync
//////////////////////////////////////////////////////////////////////////
int APIENTRY glXGetVideoSyncSGI(unsigned int* count)
{
    SU_START_FUNCTION_WRAPPER(ap_glXGetVideoSyncSGI);

    int retVal = 0;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glXGetVideoSyncSGI, 1, OS_TOBJ_ID_POINTER_PARAMETER);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glXGetVideoSyncSGI, (count), retVal);

    SU_END_FUNCTION_WRAPPER(ap_glXGetVideoSyncSGI);

    return retVal;
}

int APIENTRY glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int* count)
{
    SU_START_FUNCTION_WRAPPER(ap_glXWaitVideoSyncSGI);

    int retVal = 0;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glXWaitVideoSyncSGI, 3, OS_TOBJ_ID_INT_PARAMETER, divisor, OS_TOBJ_ID_INT_PARAMETER, remainder, OS_TOBJ_ID_POINTER_PARAMETER, count);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glXWaitVideoSyncSGI, (divisor, remainder, count), retVal);

    SU_END_FUNCTION_WRAPPER(ap_glXWaitVideoSyncSGI);

    return retVal;
}

//////////////////////////////////////////////////////////////////////////
// GLX_ARB_get_proc_address
//////////////////////////////////////////////////////////////////////////
// See gsGLXWrappers.cpp

//////////////////////////////////////////////////////////////////////////
// GLX_ARB_multisample
//////////////////////////////////////////////////////////////////////////
// See GL_ARB_multisample

//////////////////////////////////////////////////////////////////////////
// GLX_ARB_fbconfig_float
//////////////////////////////////////////////////////////////////////////
// See GL_ARB_color_buffer_float

//////////////////////////////////////////////////////////////////////////
// GLX_ARB_framebuffer_sRGB
//////////////////////////////////////////////////////////////////////////
// See GL_ARB_framebuffer_sRGB

//////////////////////////////////////////////////////////////////////////
// GLX_SGIX_pbuffer
//////////////////////////////////////////////////////////////////////////
GLXPbufferSGIX glXCreateGLXPbufferSGIX(Display* dpy, GLXFBConfigSGIX config, unsigned int width, unsigned int height, int* attrib_list)
{
    SU_START_FUNCTION_WRAPPER(ap_glXCreateGLXPbufferSGIX);

    GLXPbufferSGIX retVal = 0;

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glXCreateGLXPbufferSGIX, 5, OS_TOBJ_ID_POINTER_PARAMETER, dpy, OS_TOBJ_ID_POINTER_PARAMETER, config, OS_TOBJ_ID_UNSIGNED_INT_PARAMETER, width, OS_TOBJ_ID_UNSIGNED_INT_PARAMETER, height, OS_TOBJ_ID_P_INT_PARAMETER, attrib_list);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glXCreateGLXPbufferSGIX, (dpy, config, width, height, attrib_list), retVal);

    SU_END_FUNCTION_WRAPPER(ap_glXCreateGLXPbufferSGIX);

    return retVal;
}

void glXDestroyGLXPbufferSGIX(Display* dpy, GLXPbufferSGIX pbuf)
{
    SU_START_FUNCTION_WRAPPER(ap_glXDestroyGLXPbufferSGIX);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glXDestroyGLXPbufferSGIX, 2, OS_TOBJ_ID_POINTER_PARAMETER, dpy, OS_TOBJ_ID_XID_PARAMETER, pbuf);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glXDestroyGLXPbufferSGIX, (dpy, pbuf));

    SU_END_FUNCTION_WRAPPER(ap_glXDestroyGLXPbufferSGIX);
}

int glXQueryGLXPbufferSGIX(Display* dpy, GLXPbufferSGIX pbuf, int attribute, unsigned int* value)
{
    SU_START_FUNCTION_WRAPPER(ap_glXQueryGLXPbufferSGIX);

    int retVal = 0;

    // Call the real function:
    SU_CALL_EXTENSION_FUNC_WITH_RET_VAL(glXQueryGLXPbufferSGIX, (dpy, pbuf, attribute, value), retVal);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glXQueryGLXPbufferSGIX, 4, OS_TOBJ_ID_POINTER_PARAMETER, dpy, OS_TOBJ_ID_XID_PARAMETER, pbuf, OS_TOBJ_ID_INT_PARAMETER, attribute, OS_TOBJ_ID_P_INT_PARAMETER, value);

    SU_END_FUNCTION_WRAPPER(ap_glXQueryGLXPbufferSGIX);

    return retVal;
}

void glXSelectEventSGIX(Display* dpy, GLXDrawable drawable, unsigned long mask)
{
    SU_START_FUNCTION_WRAPPER(ap_glXSelectEventSGIX);

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glXSelectEventSGIX, 3, OS_TOBJ_ID_POINTER_PARAMETER, dpy, OS_TOBJ_ID_XID_PARAMETER, drawable, OS_TOBJ_ID_LONG_BITFIELD_PARAMETER, mask);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glXSelectEventSGIX, (dpy, drawable, mask));

    SU_END_FUNCTION_WRAPPER(ap_glXSelectEventSGIX);
}

void glXGetSelectedEventSGIX(Display* dpy, GLXDrawable drawable, unsigned long* mask)
{
    SU_START_FUNCTION_WRAPPER(ap_glXGetSelectedEventSGIX);

    // Call the real function:
    SU_CALL_EXTENSION_FUNC(glXGetSelectedEventSGIX, (dpy, drawable, mask));

    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glXGetSelectedEventSGIX, 3, OS_TOBJ_ID_POINTER_PARAMETER, dpy, OS_TOBJ_ID_XID_PARAMETER, drawable, OS_TOBJ_ID_LONG_BITFIELD_PARAMETER, mask);

    SU_END_FUNCTION_WRAPPER(ap_glXGetSelectedEventSGIX);
}

#endif // AMDT_BUILD_TARGET 


//////////////////////////////////////////////////////////////////////////
// GL_
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// GL_
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// GL_
//////////////////////////////////////////////////////////////////////////

// --------------------------------------------------------
//             Graphic Remedy extensions Wrapper functions
// --------------------------------------------------------

//////////////////////////////////////////////////////////////////////////
// GL_GREMEDY_string_marker
//////////////////////////////////////////////////////////////////////////
void APIENTRY glStringMarkerGREMEDY(GLsizei len, const GLvoid* string)
{
    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glStringMarkerGREMEDY, 1, OS_TOBJ_ID_GL_STRING_PARAMETER, len, string);
}

//////////////////////////////////////////////////////////////////////////
// GL_GREMEDY_frame_terminator
//////////////////////////////////////////////////////////////////////////
void APIENTRY glFrameTerminatorGREMEDY(void)
{
    // Log the call to this function:
    gs_stat_openGLMonitorInstance.addFunctionCall(ap_glFrameTerminatorGREMEDY, 0);

    // If we are defines as a frame terminator:
    unsigned int frameTerminatorsMask = suFrameTerminatorsMask();

    if (frameTerminatorsMask & AP_GL_FRAME_TERMINATOR_GREMEDY)
    {
        // Terminate the current frame:
        gs_stat_openGLMonitorInstance.onFrameTerminatorCall();
    }

}

//////////////////////////////////////////////////////////////////////////
// Driver-internal functions (re-exported by the spy)
//////////////////////////////////////////////////////////////////////////
#define GS_CALL_DRIVER_INTERNAL_FUNCTION(functionPointerName, argumentsList)                        \
{                                                                                                   \
    /* If we have the requested function pointer - call it: */                                      \
    GT_IF_WITH_ASSERT(nullptr != (gs_stat_realDriverInternalFunctionPointers.functionPointerName))  \
    {                                                                                               \
        (gs_stat_realDriverInternalFunctionPointers.functionPointerName) argumentsList;             \
    }                                                                                               \
    else                                                                                            \
    {                                                                                               \
        gtString errMsg;                                                                            \
        errMsg.fromASCIIString(#functionPointerName);                                               \
        GT_ASSERT_EX(false, errMsg.asCharArray());                                                  \
    }                                                                                               \
}

#define GS_CALL_DRIVER_INTERNAL_FUNCTION_RETVAL(functionPointerName, argumentsList, retVal)         \
{                                                                                                   \
    /* If we have the requested function pointer - call it: */                                      \
    GT_IF_WITH_ASSERT(nullptr != (gs_stat_realDriverInternalFunctionPointers.functionPointerName))  \
    {                                                                                               \
        retVal = (gs_stat_realDriverInternalFunctionPointers.functionPointerName) argumentsList;    \
    }                                                                                               \
    else                                                                                            \
    {                                                                                               \
        gtString errMsg;                                                                            \
        errMsg.fromASCIIString(#functionPointerName);                                               \
        GT_ASSERT_EX(false, errMsg.asCharArray());                                                  \
    }                                                                                               \
}

//////////////////////////////////////////////////////////////////////////
// AMD Driver-internal functions
//////////////////////////////////////////////////////////////////////////
unsigned int APIENTRY _loader_get_dispatch_table_size(void)
{
    gs_stat_openGLMonitorInstance.verifyOpenGLServerInitialized();

    unsigned int retVal = 0;
    GS_CALL_DRIVER_INTERNAL_FUNCTION_RETVAL(_loader_get_dispatch_table_size, (), retVal);

    return retVal;
}

int APIENTRY _loader_get_proc_offset(const char* name)
{
    gs_stat_openGLMonitorInstance.verifyOpenGLServerInitialized();

    int retVal = 0;
    GS_CALL_DRIVER_INTERNAL_FUNCTION_RETVAL(_loader_get_proc_offset, (name), retVal);

    return retVal;
}

int APIENTRY _loader_add_dispatch(const char* const* names, const char* signature)
{
    gs_stat_openGLMonitorInstance.verifyOpenGLServerInitialized();

    int retVal = 0;
    GS_CALL_DRIVER_INTERNAL_FUNCTION_RETVAL(_loader_add_dispatch, (names, signature), retVal);

    return retVal;
}

void APIENTRY _loader_set_dispatch(const void* dispTable)
{
    gs_stat_openGLMonitorInstance.verifyOpenGLServerInitialized();

    GS_CALL_DRIVER_INTERNAL_FUNCTION(_loader_set_dispatch, (dispTable));
}

//////////////////////////////////////////////////////////////////////////
// MESA Driver-internal functions
//////////////////////////////////////////////////////////////////////////
void _glapi_noop_enable_warnings(GLboolean enable)
{
    gs_stat_openGLMonitorInstance.verifyOpenGLServerInitialized();

    GS_CALL_DRIVER_INTERNAL_FUNCTION(_glapi_noop_enable_warnings, (enable));
}

void _glapi_set_warning_func(_glapi_warning_func func)
{
    gs_stat_openGLMonitorInstance.verifyOpenGLServerInitialized();

    GS_CALL_DRIVER_INTERNAL_FUNCTION(_glapi_set_warning_func, (func));
}

void _glapi_check_multithread(void)
{
    gs_stat_openGLMonitorInstance.verifyOpenGLServerInitialized();

    GS_CALL_DRIVER_INTERNAL_FUNCTION(_glapi_check_multithread, ());
}

void _glapi_set_context(void* context)
{
    gs_stat_openGLMonitorInstance.verifyOpenGLServerInitialized();

    // Sync the TLS values before this change to flush any spy-side changes:
    gsUpdateTLSVariableValues();

    GS_CALL_DRIVER_INTERNAL_FUNCTION(_glapi_set_context, (context));

    // And sync again afterwards, in case the real function changed a TLS value:
    gsUpdateTLSVariableValues();
}

void* _glapi_get_context(void)
{
    gs_stat_openGLMonitorInstance.verifyOpenGLServerInitialized();

    // Sync the TLS values before fetching the context:
    gsUpdateTLSVariableValues();

    void* retVal = nullptr;
    GS_CALL_DRIVER_INTERNAL_FUNCTION_RETVAL(_glapi_get_context, (), retVal);

    return retVal;
}

void _glapi_set_dispatch(_glapi_table* dispatch)
{
    gs_stat_openGLMonitorInstance.verifyOpenGLServerInitialized();

    // Sync the TLS values before this change to flush any spy-side changes:
    gsUpdateTLSVariableValues();

    GS_CALL_DRIVER_INTERNAL_FUNCTION(_glapi_set_dispatch, (dispatch));

    // And sync again afterwards, in case the real function changed a TLS value:
    gsUpdateTLSVariableValues();
}

_glapi_table* _glapi_get_dispatch(void)
{
    gs_stat_openGLMonitorInstance.verifyOpenGLServerInitialized();

    // Sync the TLS values before fetching the dispatch:
    gsUpdateTLSVariableValues();

    _glapi_table* retVal = nullptr;
    GS_CALL_DRIVER_INTERNAL_FUNCTION_RETVAL(_glapi_get_dispatch, (), retVal);

    return retVal;
}

int _glapi_begin_dispatch_override(_glapi_table* override)
{
    gs_stat_openGLMonitorInstance.verifyOpenGLServerInitialized();

    // Sync the TLS values before this change to flush any spy-side changes:
    gsUpdateTLSVariableValues();

    int retVal = -1;
    GS_CALL_DRIVER_INTERNAL_FUNCTION_RETVAL(_glapi_begin_dispatch_override, (override), retVal);

    // And sync again afterwards, in case the real function changed a TLS value:
    gsUpdateTLSVariableValues();

    return retVal;
}

void _glapi_end_dispatch_override(int layer)
{
    gs_stat_openGLMonitorInstance.verifyOpenGLServerInitialized();

    // Sync the TLS values before this change to flush any spy-side changes:
    gsUpdateTLSVariableValues();

    GS_CALL_DRIVER_INTERNAL_FUNCTION(_glapi_end_dispatch_override, (layer));

    // And sync again afterwards, in case the real function changed a TLS value:
    gsUpdateTLSVariableValues();
}

_glapi_table* _glapi_get_override_dispatch(int layer)
{
    gs_stat_openGLMonitorInstance.verifyOpenGLServerInitialized();

    // Sync the TLS values before fetching the dispatch:
    gsUpdateTLSVariableValues();

    _glapi_table* retVal = nullptr;
    GS_CALL_DRIVER_INTERNAL_FUNCTION_RETVAL(_glapi_get_override_dispatch, (layer), retVal);

    return retVal;
}

GLuint _glapi_get_dispatch_table_size(void)
{
    gs_stat_openGLMonitorInstance.verifyOpenGLServerInitialized();

    GLuint retVal = 0;
    GS_CALL_DRIVER_INTERNAL_FUNCTION_RETVAL(_glapi_get_dispatch_table_size, (), retVal);

    return retVal;
}

void _glapi_check_table(const _glapi_table* table)
{
    gs_stat_openGLMonitorInstance.verifyOpenGLServerInitialized();

    // Sync the TLS values before checking the dispatch:
    gsUpdateTLSVariableValues();

    GS_CALL_DRIVER_INTERNAL_FUNCTION(_glapi_check_table, (table));
}

int _glapi_add_dispatch(const char* const* function_names, const char* parameter_signature)
{
    gs_stat_openGLMonitorInstance.verifyOpenGLServerInitialized();

    // Sync the TLS values before changing the dispatch:
    gsUpdateTLSVariableValues();

    int retVal = -1;
    GS_CALL_DRIVER_INTERNAL_FUNCTION_RETVAL(_glapi_add_dispatch, (function_names, parameter_signature), retVal);

    return retVal;
}

GLint _glapi_get_proc_offset(const char* funcName)
{
    gs_stat_openGLMonitorInstance.verifyOpenGLServerInitialized();

    // Sync the TLS values before querying the dispatch:
    gsUpdateTLSVariableValues();

    GLint retVal = 0;
    GS_CALL_DRIVER_INTERNAL_FUNCTION_RETVAL(_glapi_get_proc_offset, (funcName), retVal);

    return retVal;
}

_glapi_proc _glapi_get_proc_address(const char* funcName)
{
    gs_stat_openGLMonitorInstance.verifyOpenGLServerInitialized();

    // Sync the TLS values before querying the dispatch:
    gsUpdateTLSVariableValues();

    _glapi_proc retVal = nullptr;
    GS_CALL_DRIVER_INTERNAL_FUNCTION_RETVAL(_glapi_get_proc_address, (funcName), retVal);

    return retVal;
}

const char* _glapi_get_proc_name(GLuint offset)
{
    gs_stat_openGLMonitorInstance.verifyOpenGLServerInitialized();

    // Sync the TLS values before querying the dispatch:
    gsUpdateTLSVariableValues();

    const char* retVal = nullptr;
    GS_CALL_DRIVER_INTERNAL_FUNCTION_RETVAL(_glapi_get_proc_name, (offset), retVal);

    return retVal;
}


