CreateContextAttribsARB在NVIDIA硬件

CreateContextAttribsARB在NVIDIA硬件

本文介绍了wglCreateContextAttribsARB在NVIDIA硬件上失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  ContextWin32 :: ContextWin32(WindowHandle parent,NLOpenGLSettings settings)
:IPlatformContext(parent,settings)
{
int pf = 0;
PIXELFORMATDESCRIPTOR pfd = {0};
OSVERSIONINFO osvi = {0};
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);

//获取此窗口的HDC。
if(!(m_hdc = GetDC((HWND)parent)))
{
NLError([ContextWin32] GetDC
throw NLException(GetDC()failed。,true);
}

//为窗口创建和设置像素格式。
pfd.nSize = sizeof(pfd);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = settings.BPP;
pfd.cDepthBits = settings.BPP;
pfd.iLayerType = PFD_MAIN_PLANE;

//获取Windows版本
if(!GetVersionEx(& osvi))
{
NLError([ContextWin32] GetVersionEx()失败。
throw NLException([ContextWin32] GetVersionEx()failed。);
}

//根据我们的设置获取像素格式
pf = ChoosePixelFormat(m_hdc,& pfd);

//设置像素格式
if(!SetPixelFormat(m_hdc,pf,& pfd))
{
NLError([ContextWin32] GetVersionEx 。);
throw NLException([ContextWin32] SetPixelFormat()failed。);
}

//在Windows Vista或更高版本下运行时支持桌面组合。
//在全屏模式下运行时并不适用。
if(osvi.dwMajorVersion> 6 ||(osvi.dwMajorVersion == 6&& osvi.dwMinorVersion> = 0))
pfd.dwFlags | = PFD_SUPPORT_COMPOSITION;

//验证这个OpenGL实现是否支持我们需要的扩展
std :: string extensions = wglGetExtensionsStringARB(m_hdc);
如果(extensions.find(WGL_ARB_create_context)==标准::字符串::非营利组织){
NLError([ContextWin32]必扩展不支持WGL_ARB_create_context。);
throw NLException([ContextWin32]不支持所需的扩展名WGL_ARB_create_context。
}

INT attribList [] =
{
WGL_CONTEXT_MAJOR_VERSION_ARB,settings.MAJOR,
WGL_CONTEXT_MINOR_VERSION_ARB,settings.MINOR,

WGL_ACCELERATION_ARB,WGL_FULL_ACCELERATION_ARB,
WGL_CONTEXT_PROFILE_MASK_ARB,WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
WGL_DRAW_TO_WINDOW_ARB,GL_TRUE,
WGL_SUPPORT_OPENGL_ARB,GL_TRUE,
WGL_DOUBLE_BUFFER_ARB,GL_TRUE,
WGL_PIXEL_TYPE_ARB,WGL_TYPE_RGBA_ARB,
WGL_COLOR_BITS_ARB ,32,
WGL_DEPTH_BITS_ARB,24,
0
};

//首先尝试创建一个OpenGL上下文。
if(!(m_hglrc = wglCreateContextAttribsARB(m_hdc,0,attribList)))
{
//回到OpenGL 3.0上下文。
attribList [3] = 0;
如果{
NLError([ContextWin32] wglCreateContextAttribsARB()失败的OpenGL 3上下文。)((m_hglrc = wglCreateContextAttribsARB(m_hdc,0,attribList))!);
throw NLException([ContextWin32] wglCreateContextAttribsARB()失败了OpenGL 3上下文,true);
}
}

如果(!wglMakeCurrent(m_hdc,m_hglrc)){
NLError([ContextWin32] wglMakeCurrent()失败的OpenGL 3上下文。) ;
throw NLException([ContextWin32] wglMakeCurrent()失败了OpenGL 3上下文。
}

//加载wglSwapIntervalExt
typedef BOOL(APIENTRY * PFNWGLSWAPINTERVALEXTPROC)(int);
static PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT = 0;
wglSwapIntervalEXT = reinterpret_cast< PFNWGLSWAPINTERVALEXTPROC>(wglGetProcAddress(wglSwapIntervalEXT));

if(wglSwapIntervalEXT)
{
if(settings.VSYNC == true)
{
wglSwapIntervalEXT(1);
}
else if(settings.VSYNC == false)
{
wglSwapIntervalEXT(0);
}
}
else if(wglSwapIntervalEXT == NULL)
{
NLWarning([ContextWin32]无法加载wglSwapIntervalEXT
}
}

这是有问题的代码。
当我尝试设置属性时,它在77行上失败。
但是相同的代码适用于我的ATI。
我没有任何NVIDIA产品,并且不能再现它,但我需要修复它当然。任何人都可以帮助这个问题?我忽略了什么?



我的定义:

  externC {

的#define ERROR_INVALID_VERSION_ARB 0x2095
的#define WGL_CONTEXT_DEBUG_BIT_ARB 0x0001的
的#define WGL_CONTEXT_FLAGS_ARB 0x2094
的#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB为0x0002
的#define WGL_CONTEXT_LAYER_PLANE_ARB 0x2093
#定义WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091
的#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092
的#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 00000001
的#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126


的#define WGL_NUMBER_PIXEL_FORMATS_ARB为0x2000
的#define WGL_DRAW_TO_WINDOW_ARB 0x2001
的#define WGL_DRAW_TO_BITMAP_ARB 0x2002
的#define WGL_ACCELERATION_ARB 0x2003
的#define WGL_NEED_PALETTE_ARB 0x2004
的#define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005
的#define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006
的#define WGL_SWAP_METHOD_ARB 0x2007
的#define WGL_NUMBER_OVERLAYS_ARB 0x2008
的#define WGL_NUMBER_UNDERLAYS_ARB西班牙语 - 秘鲁
的#define WGL_TRANSPARENT_ARB 0x200A
的#define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037
的#define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038
的#define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039
的#define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A
的#define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B
的#define WGL_SHARE_DEPTH_ARB 0x200C
的#define WGL_SHARE_STENCIL_ARB 0x200D
的#define WGL_SHARE_ACCUM_ARB 0x200E
的#define WGL_SUPPORT_GDI_ARB 0x200F
#定义WGL_SUPPORT_OPENGL_ARB 0x2010
的#define WGL_DOUBLE_BUFFER_ARB 0x2011
的#define WGL_STEREO_ARB 0x2012
的#define WGL_PIXEL_TYPE_ARB 0x2013
的#define WGL_COLOR_BITS_ARB 0x2014
的#define WGL_RED_BITS_ARB 0x2015
的#define WGL_RED_SHIFT_ARB 0x2016
的#define WGL_GREEN_BITS_ARB 0x2017
的#define WGL_GREEN_SHIFT_ARB 0x2018
的#define WGL_BLUE_BITS_ARB 0x2019
的#define WGL_BLUE_SHIFT_ARB 0x201A
的#define WGL_ALPHA_BITS_ARB 0x201B
的#define WGL_ALPHA_SHIFT_ARB 0x201C
的#define WGL_ACCUM_BITS_ARB 0x201D
的#define WGL_ACCUM_RED_BITS_ARB 0x201E
的#define WGL_ACCUM_GREEN_BITS_ARB 0x201F
的#define WGL_ACCUM_BLUE_BITS_ARB 0x2020
的#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021
的#define WGL_DEPTH_BITS_ARB 0x2022
的#define WGL_STENCIL_BITS_ARB 0x2023
的#define WGL_AUX_BUFFERS_ARB 0x2024
的#define WGL_NO_ACCELERATION_ARB 0x2025
的#define WGL_GENERIC_ACCELERATION_ARB 0x2026
的#define WGL_FULL_ACCELERATION_ARB 0x2027

的#define WGL_SWAP_EXCHANGE_ARB 0x2028
的#define WGL_SWAP_COPY_ARB 0x2029
的#define WGL_SWAP_UNDEFINED_ARB 0x202A

的#define WGL_TYPE_RGBA_ARB 0x202B
的#define WGL_TYPE_COLORINDEX_ARB 0x202C

的extern HGLRC wglCreateContextAttribsARB(HDC的hDC ,HGLRC hShareContext,const int * attribList);

}

也许我有一些#defines错了?

任何输入都非常感谢。



ps:关于AttribList [3]的小毛刺= 0;

解决方案

attribList

em>'以下对:




  • WGL_ACCELERATION_ARB

  • WGL_DRAW_TO_WINDOW_ARB

  • WGL_SUPPORT_OPENGL_ARB(显然,支持OpenGL!)

  • WGL_DOUBLE_BUFFER_ARB

  • WGL_PIXEL_TYPE_ARB

  • WGL_COLOR_BITS_ARB

  • WGL_DEPTH_BITS_ARB



这些属性名称已由'* m_hdc *'句柄指定



我在NVIDIA平台上创建一个没有这些标志的有效上下文。



CreateContextAttribsARB 的有效属性名称是:

  WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091 
WGL_CONTEXT_MINOR_VERSION_ARB 0x2092
WGL_CONTEXT_LAYER_PLANE_ARB 0x2093
WGL_CONTEXT_FLAGS_ARB 0x2094
WGL_CONTEXT_PROFILE_MASK_ARB 0x9126

错误是否正在返回 wglCreateContextAttribsARB



实例示例:

  int err = Gl.GetError(); 

switch(err){
case Gl.INVALID_OPERATION:
throw new InvalidOperationException(String.Format(无法创建上下文{0} ),sVersionDb [version] .GLMajor,sVersionDb [version] .GLMinor,invalid operation));
case Wgl.ERROR_INVALID_VERSION_ARB:
throw new InvalidOperationException(String.Format(无法创建上下文{0}。{1}({2}),sVersionDb [version] .GLMajor,sVersionDb [version ] .GLMinor,invalid version));
case Wgl.ERROR_INVALID_PROFILE_ARB:
throw new InvalidOperationException(String.Format(无法创建上下文{0}。{1}({2}),sVersionDb [version] .GLMajor,sVersionDb [version ] .GLMinor,invalid profile));
case Wgl.ERROR_INVALID_PIXEL_TYPE_ARB:
throw new InvalidOperationException(String.Format(无法创建上下文{0}。{1}({2}),sVersionDb [version] .GLMajor,sVersionDb [version ] .GLMinor,invalid pixel format));
默认值:
throw new InvalidOperationException(String.Format(无法创建上下文{0}。{1}({2}),sVersionDb [version] .GLMajor,sVersionDb [version] .GLMinor ,unknown error+ err));
}


ContextWin32::ContextWin32(WindowHandle parent, NLOpenGLSettings settings)
: IPlatformContext(parent, settings)
{
    int pf = 0;
    PIXELFORMATDESCRIPTOR pfd = {0};
    OSVERSIONINFO osvi = {0};
    osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);

    // Obtain HDC for this window.
    if (!(m_hdc = GetDC((HWND)parent)))
    {
        NLError("[ContextWin32] GetDC() failed.");
        throw NLException("GetDC() failed.", true);
    }

    // Create and set a pixel format for the window.
    pfd.nSize = sizeof(pfd);
    pfd.nVersion = 1;
    pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
    pfd.iPixelType = PFD_TYPE_RGBA;
    pfd.cColorBits = settings.BPP;
    pfd.cDepthBits = settings.BPP;
    pfd.iLayerType = PFD_MAIN_PLANE;

    // Obtain Windows Version
    if (!GetVersionEx(&osvi))
    {
        NLError("[ContextWin32] GetVersionEx() failed.");
        throw NLException("[ContextWin32] GetVersionEx() failed.");
    }

    // Get a pixelformat, based on our settings
    pf = ChoosePixelFormat(m_hdc, &pfd);

    // Set the pixelformat
    if (!SetPixelFormat(m_hdc, pf, &pfd))
    {
        NLError("[ContextWin32] GetVersionEx() failed.");
        throw NLException("[ContextWin32] SetPixelFormat() failed.");
    }

    // When running under Windows Vista or later support desktop composition.
    // This doesn't really apply when running in full screen mode.
    if (osvi.dwMajorVersion > 6 || (osvi.dwMajorVersion == 6 && osvi.dwMinorVersion >= 0))
        pfd.dwFlags |= PFD_SUPPORT_COMPOSITION;

    // Verify that this OpenGL implementation supports the extensions we need
    std::string extensions = wglGetExtensionsStringARB(m_hdc);
    if (extensions.find("WGL_ARB_create_context") == std::string::npos){
        NLError("[ContextWin32] Required extension WGL_ARB_create_context is not supported.");
        throw NLException("[ContextWin32] Required extension WGL_ARB_create_context is not supported.");
    }

    int attribList[] =
    {
        WGL_CONTEXT_MAJOR_VERSION_ARB, settings.MAJOR,
        WGL_CONTEXT_MINOR_VERSION_ARB, settings.MINOR,

        WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB,
        WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
        WGL_DRAW_TO_WINDOW_ARB, GL_TRUE,
        WGL_SUPPORT_OPENGL_ARB, GL_TRUE,
        WGL_DOUBLE_BUFFER_ARB, GL_TRUE,
        WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB,
        WGL_COLOR_BITS_ARB, 32,
        WGL_DEPTH_BITS_ARB, 24,
        0
    };

    // First try creating an OpenGL context.
    if (!(m_hglrc = wglCreateContextAttribsARB(m_hdc, 0, attribList)))
    {
        // Fall back to an OpenGL 3.0 context.
        attribList[3] = 0;
        if (!(m_hglrc = wglCreateContextAttribsARB(m_hdc, 0, attribList))){
            NLError("[ContextWin32] wglCreateContextAttribsARB() failed for OpenGL 3 context.");
            throw NLException("[ContextWin32] wglCreateContextAttribsARB() failed for OpenGL 3 context.", true);
        }
    }

    if (!wglMakeCurrent(m_hdc, m_hglrc)){
        NLError("[ContextWin32] wglMakeCurrent() failed for OpenGL 3 context.");
        throw NLException("[ContextWin32] wglMakeCurrent() failed for OpenGL 3 context.");
    }

    // Load wglSwapIntervalExt
    typedef BOOL (APIENTRY * PFNWGLSWAPINTERVALEXTPROC)(int);
    static PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT = 0;
    wglSwapIntervalEXT = reinterpret_cast<PFNWGLSWAPINTERVALEXTPROC>(wglGetProcAddress("wglSwapIntervalEXT"));

    if ( wglSwapIntervalEXT )
    {
            if ( settings.VSYNC == true )
            {
                wglSwapIntervalEXT(1);
            }
            else if ( settings.VSYNC == false )
            {
                wglSwapIntervalEXT(0);
            }
    }
    else if (wglSwapIntervalEXT == NULL )
    {
        NLWarning("[ContextWin32] Cannot load wglSwapIntervalEXT");
    }
}

This is the code in question.It fails on Line 77, when I try to set the Attributes.But the very same code works on my ATI.I do not own any NVIDIA Product and cannot reproduce it, but I need to fix it of course. Can anyone help on the issue? What did I overlook?

My Definitions:

extern "C" {

#define ERROR_INVALID_VERSION_ARB               0x2095
#define WGL_CONTEXT_DEBUG_BIT_ARB               0x0001
#define WGL_CONTEXT_FLAGS_ARB                   0x2094
#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB  0x0002
#define WGL_CONTEXT_LAYER_PLANE_ARB             0x2093
#define WGL_CONTEXT_MAJOR_VERSION_ARB           0x2091
#define WGL_CONTEXT_MINOR_VERSION_ARB           0x2092
#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB            0x00000001
#define WGL_CONTEXT_PROFILE_MASK_ARB            0x9126


#define WGL_NUMBER_PIXEL_FORMATS_ARB            0x2000
#define WGL_DRAW_TO_WINDOW_ARB                  0x2001
#define WGL_DRAW_TO_BITMAP_ARB                  0x2002
#define WGL_ACCELERATION_ARB                    0x2003
#define WGL_NEED_PALETTE_ARB                    0x2004
#define WGL_NEED_SYSTEM_PALETTE_ARB             0x2005
#define WGL_SWAP_LAYER_BUFFERS_ARB              0x2006
#define WGL_SWAP_METHOD_ARB                     0x2007
#define WGL_NUMBER_OVERLAYS_ARB                 0x2008
#define WGL_NUMBER_UNDERLAYS_ARB                0x2009
#define WGL_TRANSPARENT_ARB                     0x200A
#define WGL_TRANSPARENT_RED_VALUE_ARB           0x2037
#define WGL_TRANSPARENT_GREEN_VALUE_ARB         0x2038
#define WGL_TRANSPARENT_BLUE_VALUE_ARB          0x2039
#define WGL_TRANSPARENT_ALPHA_VALUE_ARB         0x203A
#define WGL_TRANSPARENT_INDEX_VALUE_ARB         0x203B
#define WGL_SHARE_DEPTH_ARB                     0x200C
#define WGL_SHARE_STENCIL_ARB                   0x200D
#define WGL_SHARE_ACCUM_ARB                     0x200E
#define WGL_SUPPORT_GDI_ARB                     0x200F
#define WGL_SUPPORT_OPENGL_ARB                  0x2010
#define WGL_DOUBLE_BUFFER_ARB                   0x2011
#define WGL_STEREO_ARB                          0x2012
#define WGL_PIXEL_TYPE_ARB                      0x2013
#define WGL_COLOR_BITS_ARB                      0x2014
#define WGL_RED_BITS_ARB                        0x2015
#define WGL_RED_SHIFT_ARB                       0x2016
#define WGL_GREEN_BITS_ARB                      0x2017
#define WGL_GREEN_SHIFT_ARB                     0x2018
#define WGL_BLUE_BITS_ARB                       0x2019
#define WGL_BLUE_SHIFT_ARB                      0x201A
#define WGL_ALPHA_BITS_ARB                      0x201B
#define WGL_ALPHA_SHIFT_ARB                     0x201C
#define WGL_ACCUM_BITS_ARB                      0x201D
#define WGL_ACCUM_RED_BITS_ARB                  0x201E
#define WGL_ACCUM_GREEN_BITS_ARB                0x201F
#define WGL_ACCUM_BLUE_BITS_ARB                 0x2020
#define WGL_ACCUM_ALPHA_BITS_ARB                0x2021
#define WGL_DEPTH_BITS_ARB                      0x2022
#define WGL_STENCIL_BITS_ARB                    0x2023
#define WGL_AUX_BUFFERS_ARB                     0x2024
#define WGL_NO_ACCELERATION_ARB                 0x2025
#define WGL_GENERIC_ACCELERATION_ARB            0x2026
#define WGL_FULL_ACCELERATION_ARB               0x2027

#define WGL_SWAP_EXCHANGE_ARB                   0x2028
#define WGL_SWAP_COPY_ARB                       0x2029
#define WGL_SWAP_UNDEFINED_ARB                  0x202A

#define WGL_TYPE_RGBA_ARB                       0x202B
#define WGL_TYPE_COLORINDEX_ARB                 0x202C

extern HGLRC wglCreateContextAttribsARB(HDC hDC, HGLRC hShareContext, const int *attribList);

}

Maybe I got some #defines wrong?

Any input is highly appreciated.

ps.: The little glitch regarding AttribList[3] = 0; is fixed by now, must be 1. But that was not the issue.

解决方案

Remove from 'attribList' the following pairs:

  • WGL_ACCELERATION_ARB
  • WGL_DRAW_TO_WINDOW_ARB
  • WGL_SUPPORT_OPENGL_ARB (obvious that support OpenGL!)
  • WGL_DOUBLE_BUFFER_ARB
  • WGL_PIXEL_TYPE_ARB
  • WGL_COLOR_BITS_ARB
  • WGL_DEPTH_BITS_ARB

Those attribute names are already specified by the '*m_hdc*' handle (infact you call SetPixelFormat on it).

I create a valid context without those flags on NVIDIA platforms.

Valid attribute names for CreateContextAttribsARB are:

WGL_CONTEXT_MAJOR_VERSION_ARB       0x2091
WGL_CONTEXT_MINOR_VERSION_ARB       0x2092
WGL_CONTEXT_LAYER_PLANE_ARB     0x2093
WGL_CONTEXT_FLAGS_ARB           0x2094
WGL_CONTEXT_PROFILE_MASK_ARB        0x9126

Furthermore, what error is returning wglCreateContextAttribsARB?

Instance example:

int err = Gl.GetError();

switch (err) {
    case Gl.INVALID_OPERATION:
        throw new InvalidOperationException(String.Format("unable to create context {0}.{1} ({2})", sVersionDb[version].GLMajor, sVersionDb[version].GLMinor, "invalid operation"));
    case Wgl.ERROR_INVALID_VERSION_ARB:
        throw new InvalidOperationException(String.Format("unable to create context {0}.{1} ({2})", sVersionDb[version].GLMajor, sVersionDb[version].GLMinor, "invalid version"));
    case Wgl.ERROR_INVALID_PROFILE_ARB:
        throw new InvalidOperationException(String.Format("unable to create context {0}.{1} ({2})", sVersionDb[version].GLMajor, sVersionDb[version].GLMinor, "invalid profile"));
    case Wgl.ERROR_INVALID_PIXEL_TYPE_ARB:
        throw new InvalidOperationException(String.Format("unable to create context {0}.{1} ({2})", sVersionDb[version].GLMajor, sVersionDb[version].GLMinor, "invalid pixel format"));
    default:
        throw new InvalidOperationException(String.Format("unable to create context {0}.{1} ({2})", sVersionDb[version].GLMajor, sVersionDb[version].GLMinor, "unknown error " + err));
}

这篇关于wglCreateContextAttribsARB在NVIDIA硬件上失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-30 04:15