首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SetPixelFormat在使用WGL_SAMPLE_BUFFERS_ARB / WGL_SAMPLES_ARB时失败

SetPixelFormat在使用WGL_SAMPLE_BUFFERS_ARB / WGL_SAMPLES_ARB时失败
EN

Stack Overflow用户
提问于 2016-01-26 07:41:51
回答 1查看 1.7K关注 0票数 0

我决定将MSAA支持添加到我的应用程序中,并为此检查了要做什么。我发现的示例总是引用像素格式描述符中的WGL_SAMPLE_BUFFERS_ARB / WGL_SAMPLES_ARB来实现这一点。我现在用的是glew

代码语言:javascript
复制
int DesiredColorBits   = 32;
int DesiredStencilBits = 0;
int DesiredDepthBits   = 24;
int MajorVersion=3;
int MinorVersion=3;

PIXELFORMATDESCRIPTOR temppfd =
    {
        sizeof(PIXELFORMATDESCRIPTOR),
        1,
        PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
        PFD_TYPE_RGBA,
        DesiredColorBits,
        0, 0, 0, 0, 0, 0,
        0, 0,
        0, 0, 0, 0, 0,
        DesiredDepthBits,
        0,//DesiredStencilBits,
        0,
        PFD_MAIN_PLANE,
        0,
        0, 0, 0
    };

HDC TemphDC;
TemphDC = GetDC( hWnd );
int nPixelFormat = ChoosePixelFormat( TemphDC, &temppfd );
check(nPixelFormat);
verify(SetPixelFormat( TemphDC, nPixelFormat, &temppfd ));

// oldstyle context to init glew.
HGLRC tempContext = wglCreateContext(TemphDC);
wglMakeCurrent(TemphDC, tempContext);

//init glew
glewExperimental = GL_TRUE;
GLenum err = glewInit();
if (GLEW_OK != err)
    errorprintf(TEXT("Error: Init glew failed: %s"), glewGetErrorString(err)));
else debugprintf( TEXT("Glew successfully initialized."));

ReleaseDC(hWnd, TemphDC);

//Now init pure OpenGL >= 3.3 context.
if (WGLEW_ARB_create_context && WGLEW_ARB_pixel_format)
{
    wglMakeCurrent(NULL, NULL);
    wglDeleteContext(tempContext);
    PIXELFORMATDESCRIPTOR pfd;
    memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
    pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
    pfd.nVersion = 1;
    pfd.dwFlags = PFD_DOUBLEBUFFER | PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW;
    pfd.iPixelType = PFD_TYPE_RGBA;
    pfd.cColorBits = DesiredColorBits;
    pfd.cDepthBits = DesiredDepthBits;
    pfd.iLayerType = PFD_MAIN_PLANE;

    int iPixelFormatAttribList[30];
    iPixelFormatAttribList[0] = WGL_DRAW_TO_WINDOW_ARB;
    iPixelFormatAttribList[1] = GL_TRUE;
    iPixelFormatAttribList[2] = WGL_SUPPORT_OPENGL_ARB;
    iPixelFormatAttribList[3] = GL_TRUE;
    iPixelFormatAttribList[4] = WGL_DOUBLE_BUFFER_ARB;
    iPixelFormatAttribList[5] = GL_TRUE;
    iPixelFormatAttribList[6] = WGL_PIXEL_TYPE_ARB;
    iPixelFormatAttribList[7] = WGL_TYPE_RGBA_ARB;
    iPixelFormatAttribList[8] = WGL_COLOR_BITS_ARB;
    iPixelFormatAttribList[9] = DesiredColorBits;
    iPixelFormatAttribList[10] = WGL_DEPTH_BITS_ARB;
    iPixelFormatAttribList[11] = DesiredDepthBits;
    iPixelFormatAttribList[12] = WGL_STENCIL_BITS_ARB;
    iPixelFormatAttribList[13] = 0;
    iPixelFormatAttribList[14] = WGL_SAMPLE_BUFFERS_ARB;
    iPixelFormatAttribList[15] = GL_TRUE;
    iPixelFormatAttribList[16] = WGL_SAMPLES_ARB;
    iPixelFormatAttribList[17] = NumAASamples;
    iPixelFormatAttribList[18] = 0;

    int iPixelFormat, iNumFormats;
    wglChoosePixelFormatARB(hDC, iPixelFormatAttribList, NULL, 1, &iPixelFormat, (GLuint*)&iNumFormats);

    if( iNumFormats == 0 )
    {
        debugprintf(TEXT("Couldn't support multisampling"));
    }
    else debugprintf(TEXT("Available formats: %i %i"),iNumFormats,iPixelFormat);

    int iContextAttribs[] =
    {
        WGL_CONTEXT_MAJOR_VERSION_ARB, MajorVersion,
        WGL_CONTEXT_MINOR_VERSION_ARB, MinorVersion,
        WGL_CONTEXT_FLAGS_ARB, ContextFlags,
        0 // End of attributes list
    };

    // pfd oldstyle crap...
    debugprintf(TEXT("DesiredColorBits: %i"), DesiredColorBits);
    debugprintf(TEXT("DesiredDepthBits: %i"), DesiredDepthBits);

    if (!SetPixelFormat(hDC, iPixelFormat, &pfd))
    {
        debugprintf(TEXT("Setting PixelFormat %i failed!"), iPixelFormat);
        iPixelFormat = ChoosePixelFormat(hDC, &pfd); 
        if (!SetPixelFormat(hDC, iPixelFormat, &pfd))
            errorprintf(TEXT("Error: SetPixelFormat %i failed."),iPixelFormat);
    }

    hRC = wglCreateContextAttribsARB(hDC, 0, iContextAttribs);
}
else  errorprintf(TEXT("Error: Init glew failed: %s"), glewGetErrorString(err)));

if(hRC)
{
    MakeCurrent();

    debugprintf( TEXT("GL_VENDOR     : %s"), glGetString(GL_VENDOR));
    debugprintf( TEXT("GL_RENDERER   : %s"), glGetString(GL_RENDERER));
    debugprintf( TEXT("GL_VERSION    : %s"), glGetString(GL_VERSION));
    debugprintf( TEXT("GLEW Version  : %s"), glewGetString(GLEW_VERSION));

    int NumberOfAASamples=0, NumberOfSampleBufers;
    glGetintegerv(GL_SAMPLE_BUFFERS,&NumberOfSampleBufers);
    glGetintegerv(GL_SAMPLES,&NumberOfAASamples);
    debugprintf(TEXT("SampleBuffers: %i, NumAASamples: (%i/%i)"),NumberOfSampleBufers, NumberOfAASamples,NumAASamples);

    int NumberOfExtensions=0;
    glGetintegerv(GL_NUM_EXTENSIONS, &NumberOfExtensions);
    for (int i = 0; i<NumberOfExtensions; i++)
    {
        FString ExtensionString = glGetStringi(GL_EXTENSIONS, i));
        debugprintf(NAME_DevLoad, TEXT("GL_EXTENSIONS(%i) : %s"), i, ExtensionString);
    }
    debugprintf( TEXT("OpenGL %i.%i context initialized!"), MajorVersion,MinorVersion);
}

到目前为止,到目前为止,我得到了我的诱饵到init,它初始化正确,并准备使用,也没有问题的SetPixelFormat-至少没有样本缓冲区。现在,如果我要添加WGL_SAMPLE_BUFFERS_ARB和WGL_SAMPLES_ARB,我仍然可以从wglChoosePixelFormatARB获得一个像素格式(实际上iNumFormats返回32),但是SetPixelFormat总是会失败,返回的像素格式也会失败。我尝试了不同的颜色和深度,但无论我做什么,我似乎找不到一种方法来使这个工作。我也尝试在我的NVidia和英特尔卡,没有AA预置是强制的。

现在-有什么不同的方法来得到这个结果吗?我认为SetPixelformat是“不推荐的”,从我所读到的部分甚至是过时的,但是我似乎需要它来启用MSAA,这是一种有点烦人的依赖。我错过了什么吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-01-26 15:57:23

我通过改变一件事解决了这个问题,我为glew init创建了一个完全独立的窗口:

代码语言:javascript
复制
LRESULT CALLBACK WndProc(HWND hWnd, UINT uiMsg, WPARAM wParam, LPARAM lParam)
{
    switch(uiMsg)
    {
        case WM_CLOSE:
            PostQuitMessage(0);
            break;

        default:
            return DefWindowProc(hWnd, uiMsg, wParam, lParam);
    }

    return 0;
}
PIXELFORMATDESCRIPTOR temppfd =
{
    sizeof(PIXELFORMATDESCRIPTOR),
    1,
    PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
    PFD_TYPE_RGBA,
    DesiredColorBits,
    0, 0, 0, 0, 0, 0,
    0, 0,
    0, 0, 0, 0, 0,
    DesiredDepthBits,
    0,//DesiredStencilBits,
    0,
    PFD_MAIN_PLANE,
    0,
    0, 0, 0
};
DWORD Style = WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
WNDCLASSEX WndClassEx;
memset(&WndClassEx, 0, sizeof(WNDCLASSEX));

WndClassEx.cbSize = sizeof(WNDCLASSEX);
WndClassEx.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
WndClassEx.lpfnWndProc = WndProc;
WndClassEx.hInstance = hInstance;
WndClassEx.hIcon = LoadIcon(NULL, IDI_APPLICATION);
WndClassEx.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
WndClassEx.hCursor = LoadCursor(NULL, IDC_ARROW);
WndClassEx.lpszClassName = L"Win32OpenGLWindow";

if(RegisterClassEx(&WndClassEx) == 0)
{
    debugprintf(TEXT("RegisterClassEx failed!"));
}
HWND TemphWnd = CreateWindowEx(WS_EX_APPWINDOW, WndClassEx.lpszClassName,  L"InitWIndow", Style, 0, 0, SizeX, SizeY, NULL, NULL, hInstance, NULL);
HDC TemphDC = GetDC( TemphWnd );
INT nPixelFormat = ChoosePixelFormat( TemphDC, &temppfd );
check(nPixelFormat);
verify(SetPixelFormat( TemphDC, nPixelFormat, &temppfd ));

// oldstyle context to init glew.
HGLRC tempContext = wglCreateContext(TemphDC);
wglMakeCurrent(TemphDC, tempContext);

//init glew
glewExperimental = GL_TRUE;
GLenum err = glewInit();
if (GLEW_OK != err)
    errorprintf(TEXT("Error: Init glew failed: %s"),glewGetErrorString(err));
else debugprintf(TEXT("Glew successfully initialized."));

//Now init pure OpenGL >= 3.3 context.
if (WGLEW_ARB_create_context && WGLEW_ARB_pixel_format)
{
    wglMakeCurrent(NULL, NULL);
    wglDeleteContext(tempContext);
    ReleaseDC(TemphWnd, TemphDC);
    DestroyWindow(TemphWnd);
...

在销毁了这个临时窗口,然后使用实际的游戏,如上面所示,有可能使用SetPixelFormat与新的选项。当不添加WGL_SAMPLE_BUFFERS_ARB / WGL_SAMPLES_ARB (我不知道)时,它为什么没有造成这样的麻烦呢?我假设以后不可能真正更改窗口的像素格式,这与任何hWnd、hDC或上下文无关,如果它们在中间被销毁或更新。网络上的许多例子和教程都不清楚这一点,而且也在以错误的方式展示这一点。简而言之,创建一个temphWnd和temphDC,然后init,销毁所有临时的东西,然后继续用真正的窗口hWnd和hDC创建你真正想要的上下文,否则你就会有麻烦。

是的,我认为在windows中获取干净的上下文是一件非常糟糕的事情。

不管怎样,我希望这会对其他人有所帮助。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35008927

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档