这里说的全屏抗锯齿,不是基于着色器的FXAA之类的方式,而是兼容性更好的,基于固定管线的多重采样方式。

    先来说一下开发环境,我用的是VC2013+GLEW1.11。

    要通过程序设置多重采样,首先需要进入控制面板,确定抗锯齿的设置是“根据应用程序而定” ,当然,这个设置的具体名称,不同的显卡厂商有不同的叫法。

    接下来,就是重点了。

    Windows下要通过程序设置多重采样,必须使用wglChoosePixelFormatARB这个函数。目前网上基本都是自己去获取这个函数的接口地址,其实根本不用这么麻烦。GLEW已经有这个函数接口了,我们要做的,就是正确地使用而已。正确使用这个函数的关键,就是需要创建一个临时窗体,通过这个窗体,我们可以初始化GLEW,以及获取必须的基础像素格式,然后再使用wglChoosePixelFormatARB这个函数,得到可用的多重采样像素格式,最后,对渲染窗口设置这个像素格式即可。



//----------创建一个临时窗体
    HWND secondwnd;
    WNDCLASS wc; //窗体类结构体  
    wc.style = CS_HREDRAW | CS_VREDRAW; //窗体风格   
    wc.lpfnWndProc = WndProc; //窗体处理函数  
    wc.cbClsExtra = 0; //窗体类是否由扩展  
    wc.cbWndExtra = 0; //窗体实例是否由扩展  
    wc.hInstance = NULL; //窗体句柄  
    wc.hIcon = LoadIcon(0, IDI_APPLICATION); //窗体图标  
    wc.hCursor = LoadCursor(NULL, IDC_ARROW); //窗体鼠标样式  
    wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); //窗体背景颜色  
    wc.lpszMenuName = NULL; //窗体菜单  
    wc.lpszClassName = L"BaseWndClass"; //窗体类名  
    if (!RegisterClass(&wc)) //判断窗体是否注册成功  
    {
        MessageBox(L"注册失败");
        return;
    }
    //创建窗体  
    secondwnd = CreateWindow(L"BaseWndClass", //窗体类名  
        L"MyFrom",  //窗体标题名  
        WS_OVERLAPPEDWINDOW,  //窗体风格  
        CW_USEDEFAULT,
        CW_USEDEFAULT, //窗体坐标  
        CW_USEDEFAULT,
        CW_USEDEFAULT, //窗体坐标  
        NULL, //窗体的父窗体  
        NULL, //窗体的子菜单  
        NULL,  //窗体句柄  
        NULL); // 如果函数成功,返回值为新窗口的句柄:如果函数失败,返回值为NULL  
    if (secondwnd == 0)//判断创建窗体是否成功  
    {
        MessageBox(L"创建窗体失败");
        return;
    }
    ::ShowWindow(secondwnd, SW_HIDE); //显示窗体  
    ::UpdateWindow(secondwnd); //绘制窗体;  

    PIXELFORMATDESCRIPTOR pfd = //定义像素格式
    {
        sizeof(PIXELFORMATDESCRIPTOR), // 上述格式描述符的大小
        1,         // 版本号
        PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
        PFD_TYPE_RGBA,      // 申请 RGBA 格式
        32,
        0, 0, 0, 0, 0, 0,     // 忽略的色彩位
        8,         // 无Alpha缓存
        0,         // 忽略Shift Bit
        0,         // 无累加缓存
        0, 0, 0, 0,       // 忽略聚集位
        32,         // 32位 Z-缓存 (深度缓存)
        8,         // 无蒙板缓存
        0,         // 无辅助缓存
        PFD_MAIN_PLANE,      // 主绘图层
        0,         // Reserved
        0, 0, 0        // 忽略层遮罩
    };
    //----------用这个临时窗体得到一个可用HGLRC
    HDC secondDC = ::GetDC(secondwnd);
    int nIndex = ChoosePixelFormat(secondDC, &pfd); //选择刚刚定义的像素格式
    if (nIndex == 0)
    {
        return;
    }

    SetPixelFormat(secondDC, nIndex, &pfd);   //设置像素格式

    glRC = wglCreateContext(secondDC);
    wglMakeCurrent(secondDC, glRC);
  //----------然后初始化GLEW
    GLenum glerr = glewInit();
    if (glerr != GLEW_OK)
    {
        MessageBox(L"无法初始化GLEW!");
    }
    else
    {
        OutputDebugString(L"成功加载GLEW\n");
    }

    UINT Multisample = 4; //4倍多重采样率
    int pixelformat;
    UINT numformat;
    float   fAttributes[] = { 0, 0 };
    int iAtributes[] =
    {
        WGL_DRAW_TO_WINDOW_ARB, GL_TRUE,
        WGL_SUPPORT_OPENGL_ARB, GL_TRUE,
        WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB,
        WGL_COLOR_BITS_ARB, 24,
        WGL_ALPHA_BITS_ARB, 8,
        WGL_DEPTH_BITS_ARB, 32,
        WGL_STENCIL_BITS_ARB, 8,
        WGL_DOUBLE_BUFFER_ARB, GL_TRUE,
        WGL_SAMPLE_BUFFERS_ARB, GL_TRUE,
        WGL_SAMPLES_ARB, Multisample,
        0, 0
    };
    //----------取得可用的多重采样像素格式
    if (!wglChoosePixelFormatARB(secondDC, iAtributes, fAttributes, 1, &pixelformat, &numformat))
    {
        MessageBox(L"找不到可用的抗锯齿格式");
    }

  //----------删除由临时窗体得到的HGLRC,同时销毁临时窗体
    wglMakeCurrent(NULL, NULL);
    wglDeleteContext(glRC);

    ::ReleaseDC(secondwnd, secondDC);
    ::DestroyWindow(secondwnd);
    //----------用得到的多重采样像素格式,设置渲染窗体
    SetPixelFormat(this->GetDC()->m_hDC, pixelformat, &pfd);   //设置像素格式

    glRC = wglCreateContext(this->GetDC()->m_hDC);
    wglMakeCurrent(this->GetDC()->m_hDC, glRC);



上面这段代码,就是按照我所说的方式初始化了OpenGL。

这样设置后,你就能通过glEnable/glDisable启用或禁用多重采样了。

 

希望这点经验能够对和我一样曾困于此问题的朋友有所帮助。