使用wglCreateContextAttribsARB創建OpenGL


#include <gl/glew.h>
#include <gl/wglew.h>


//祖傳設置像素格式函數
bool set_pixel_format(HDC hdc)
{
    PIXELFORMATDESCRIPTOR pfd = { 0 };

    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 = 32;
    pfd.cRedBits = 8;
    //pfd.cRedShift = 16;
    pfd.cGreenBits = 8;
    //pfd.cGreenShift = 8;
    pfd.cBlueBits = 8;
    //pfd.cBlueShift = 0;
    pfd.cAlphaBits = 8;
    //pfd.cAlphaShift = 0;
    //pfd.cAccumBits = 64;
    //pfd.cAccumRedBits = 16;
    //pfd.cAccumGreenBits = 16;
    //pfd.cAccumBlueBits = 16;
    //pfd.cAccumAlphaBits = 0;
    pfd.cDepthBits = 24;
    pfd.cStencilBits = 8;
    pfd.cAuxBuffers = 0;
    pfd.iLayerType = PFD_MAIN_PLANE;
    pfd.bReserved = 0;
    pfd.dwLayerMask = 0;
    pfd.dwVisibleMask = 0;
    pfd.dwDamageMask = 0;

    int pixel_id = ChoosePixelFormat(hdc, &pfd);

    if (!pixel_id) {
        //Let's choose a default index.
        pixel_id = 1;
        if (FALSE == DescribePixelFormat(hdc, pixel_id, sizeof(PIXELFORMATDESCRIPTOR), &pfd)) {
            MessageBox(WindowFromDC(hdc), TEXT("DescribePixelFormat error."), TEXT("OpenGL"), MB_OK);
            return -1;
        }
    }

    if (FALSE == SetPixelFormat(hdc, pixel_id, &pfd))
    {
        MessageBox(WindowFromDC(hdc), TEXT("SetPixelFormat error."), TEXT("OpenGL"), MB_OK);
        return -2;
    }
}

//初始化1.1版本的OpenGL
HGLRC init_context(HDC hdc)
{
    if(set_pixel_format(hdc) == false){
        return NULL;
    }

    HGLRC hRC = wglCreateContext(hdc);
    if (!hRC) {
        MessageBox(WindowFromDC(hdc), TEXT("wglCreateContext error."), TEXT("OpenGL"), MB_OK);
    }

    if (FALSE == wglMakeCurrent(hdc, hRC)) {
        MessageBox(WindowFromDC(hdc), TEXT("wglMakeCurrent error."), TEXT("OpenGL"), MB_OK);
    }

    return hRC;
}

void set_attribute(int* attrib, int name, int value)
{
    while(*attrib){
        if(*attrib == name){
            *++attrib = value;
            break;
        }
        attrib += 2;
    }
}

//使用wglCreateContextAttribsARB初始化OpenGL
//HGLRC init_context_ext(hDC, 主版本, 次版本)
HGLRC init_context_ext(HDC hDC, int major, int minor)
{
    HGLRC hRC = init_context(hDC);
    if(hRC == NULL){
        return NULL;
    }

    //init glew
    int err = glewInit();

    if (GLEW_OK != err){
        MessageBox(WindowFromDC(hDC), TEXT("glewInit() error."), TEXT("OpenGL"), 0);
        return false;
    }

    //init wglew
    err = wglewInit();

    if (GLEW_OK != err){
        MessageBox(WindowFromDC(hDC), TEXT("wglewInit() error."), TEXT("OpenGL"), 0);
        return false;
    }

    //刪除當前OpenGL環境
    wglMakeCurrent(NULL, NULL);
    wglDeleteContext(hRC);

    int nPixelFormat=-1;
    int nPixCount = 0;
    float fPixAttribs[]= {
        0,0
    };

    int pixel_attrib[] =
    {
        WGL_SUPPORT_OPENGL_ARB, GL_TRUE,    // Must support OGL rendering
        WGL_DRAW_TO_WINDOW_ARB, GL_TRUE,    // pf that can run a window
        WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB,    // must be HW accelerated
        WGL_DOUBLE_BUFFER_ARB, GL_TRUE,     // Double buffered context

        WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB,
        WGL_COLOR_BITS_ARB, 32,             // 8 bits of each R, G and B
        WGL_DEPTH_BITS_ARB, 24,             // 24 bits of depth precision for window
        WGL_STENCIL_BITS_ARB, 8,            // 開啟模板緩沖區,模板緩沖區位數=8

        WGL_SAMPLE_BUFFERS_ARB, GL_TRUE,    // MSAA on,開啟多重采樣
        WGL_SAMPLES_ARB, 4,                 // 4x MSAA ,多重采樣樣本數量為4

        0, 0
    };

    //這些沒有測試
    //WGL_CONTEXT_CORE_PROFILE_BIT_ARB 只包含核心環境
    //WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 創建一個能夠兼容所有OpenGL老版本的環境。
    //WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB
    //WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,

    wglChoosePixelFormatARB(hDC, pixel_attrib, fPixAttribs, 1, &nPixelFormat, (UINT*)&nPixCount);
    if (nPixelFormat==-1) {
        // Try again without MSAA
        set_attribute(pixel_attrib, WGL_SAMPLE_BUFFERS_ARB, GL_FALSE);
        wglChoosePixelFormatARB(hDC, pixel_attrib, fPixAttribs, 1, &nPixelFormat, (UINT*)&nPixCount);
    }

    GLint attribs[] = {
        //WGL_CONTEXT_MAJOR_VERSION_ARB, 3,//主版本3
        //WGL_CONTEXT_MINOR_VERSION_ARB, 3,//次版本號3

        WGL_CONTEXT_MAJOR_VERSION_ARB, major,   //主版本
        WGL_CONTEXT_MINOR_VERSION_ARB, minor,   //次版本號

        WGL_CONTEXT_PROFILE_MASK_ARB,WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
            //要求返回兼容模式環境,如果不指定或指定為WGL_CONTEXT_CORE_PROFILE_BIT_ARB會返回只包含核心功能的環境
        0, 0
    };

    /*
    hRC = wglCreateContextAttribsARB(hDC, 0, attribs);
    if (hRC == NULL) {
        MessageBox(WindowFromDC(hDC), TEXT("Could not create an OpenGL 3.3 context."), TEXT("OpenGL"), 0);
        attribs[3] = 2;
        hRC = wglCreateContextAttribsARB(hDC,0, attribs);
        if (hRC == NULL) {
            MessageBox(WindowFromDC(hDC), TEXT("Could not create an OpenGL 3.2 context."), TEXT("OpenGL"), 0);
            //要求opengl3.2以上環境
            return NULL;
        }
    }
    */

    hRC = wglCreateContextAttribsARB(hDC, 0, attribs);
    if (hRC == NULL) {
        MessageBox(WindowFromDC(hDC), TEXT("Could not create an OpenGL context."), TEXT("OpenGL"), 0);
        return NULL;
    }

    if (FALSE == wglMakeCurrent(hDC, hRC)) {
        wglDeleteContext(hRC);
        MessageBox(WindowFromDC(hDC), TEXT("wglMakeCurrent error."), TEXT("OpenGL"), MB_OK);
        return NULL;
    }

    return hRC;
}

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM