使用ARB扩展的OpenGL上下文创建不起作用

问题描述 投票:0回答:2

我想使用ARB扩展来创建OpenGL上下文,但是它不起作用。运行时在控制台上打印的错误消息(我的puts()调用)是:“选择最终的窗口像素格式失败。”和“创建最终渲染上下文失败。”。而且窗口不会显示。

当我删除数组的最后3个属性时,该程序在控制台中不输出任何内容,但在屏幕上不显示任何内容,然后停止(有一个while循环)。这很奇怪。

使用wglGetProcAddress()强制转换的第二个函数指针在用gcc和-Wextra标志编译时会生成警告(对于所有警告)。我不知道为什么,如果有人可以解决这个问题,请告诉我。

代码:

#include <stdio.h>

#define UNICODE
#include <windows.h>
#include <dwmapi.h>

#define GLEW_STATIC
#include <glew.h>

#include <GL\wglext.h>

LRESULT CALLBACK FirstWindowProcedure(HWND hWnd, UINT uMsg, WPARAM wp,
    LPARAM lp);
LRESULT CALLBACK FinalWindowProcedure(HWND hWnd, UINT uMsg, WPARAM wp,
    LPARAM lp);
unsigned int CreateShaderProgram(char* VertexSource, char* FragmentSource);

int main(void){
    WNDCLASSEX FirstWindowClass = {};
    FirstWindowClass.cbSize = sizeof(WNDCLASSEX);
    FirstWindowClass.style = CS_OWNDC;
    FirstWindowClass.lpfnWndProc = FirstWindowProcedure;
    FirstWindowClass.lpszClassName = L"FirstWindowClass";
    if(!RegisterClassEx(&FirstWindowClass))
        puts("Registration of the first window class failed.\n");

    HWND FirstWindow = CreateWindowEx(WS_EX_APPWINDOW,
        FirstWindowClass.lpszClassName, L"FirstWindow", WS_POPUP, 0, 0, 10, 10,
        NULL, NULL, NULL, NULL);
    if(FirstWindow == NULL)
        puts("Creation of the first window failed.\n");

    PIXELFORMATDESCRIPTOR FirstWindowPixelFormatDescriptor = {};
    FirstWindowPixelFormatDescriptor.nSize = sizeof(PIXELFORMATDESCRIPTOR);
    FirstWindowPixelFormatDescriptor.nVersion = 1;
    FirstWindowPixelFormatDescriptor.dwFlags = PFD_DRAW_TO_WINDOW |
        PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
    FirstWindowPixelFormatDescriptor.iPixelType = PFD_TYPE_RGBA;
    FirstWindowPixelFormatDescriptor.cColorBits = 32;
    FirstWindowPixelFormatDescriptor.cDepthBits = 24;
    FirstWindowPixelFormatDescriptor.cStencilBits = 8;
    FirstWindowPixelFormatDescriptor.iLayerType = PFD_MAIN_PLANE;

    HDC FirstWindowDeviceContext = GetDC(FirstWindow);
    if(FirstWindowDeviceContext == NULL)
        puts("First window device context retrieving failed.\n");

    int FirstWindowPixelFormat = ChoosePixelFormat(FirstWindowDeviceContext,
        &FirstWindowPixelFormatDescriptor);
    if(FirstWindowPixelFormat == 0)
        puts("Choosing the first pixel format failed.\n");

    if(SetPixelFormat(FirstWindowDeviceContext, FirstWindowPixelFormat,
    &FirstWindowPixelFormatDescriptor) == FALSE)
        puts("Setting the first pixel format failed.\n");

    HGLRC FirstWindowRenderingContext =
        wglCreateContext(FirstWindowDeviceContext);
    if(FirstWindowRenderingContext == NULL)
        puts("Creating the first rendering context failed.\n");

    if(wglMakeCurrent(FirstWindowDeviceContext, FirstWindowRenderingContext) ==
    FALSE)
        puts("Making the first context current failed.\n");

    if(glewInit() != GLEW_OK)
        puts("Initialisation of GLEW failed.\n");

    WNDCLASSEX FinalWindowClass = {};
    FinalWindowClass.cbSize = sizeof(WNDCLASSEX);
    FinalWindowClass.style = CS_OWNDC;
    FinalWindowClass.lpfnWndProc = FinalWindowProcedure;
    FinalWindowClass.lpszClassName = L"FinalWindowClass";
    if(!RegisterClassEx(&FinalWindowClass))
        puts("Registration of the final window class failed\n");

    HWND FinalWindow = CreateWindowEx(WS_EX_APPWINDOW,
        FinalWindowClass.lpszClassName, L"FinalWindow", WS_POPUP, 0, 0, 10, 10,
        NULL, NULL, NULL, NULL);
    if(FinalWindow == NULL)
        puts("Creation of the final window failed.\n");

    PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB =
        wglGetProcAddress("wglChoosePixelFormatARB");
    if(wglChoosePixelFormatARB == NULL)
        puts("Getting the wglChoosePixelFormatARB function pointer failed.\n");

    PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB =
        (PFNWGLCREATECONTEXTATTRIBSARBPROC)
        wglGetProcAddress("wglCreateContextAttribsARB");
    if(wglCreateContextAttribsARB == NULL)
        puts("Getting the wglCreateContextAttribsARB function pointer"
            "failed.\n");

    int FinalWindowContextAttributes[] = {
        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,
        WGL_STENCIL_BITS_ARB, 8,
        WGL_CONTEXT_MAJOR_VERSION_ARB, 4,
        WGL_CONTEXT_MINOR_VERSION_ARB, 4,
        WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
        0,
    };

    HDC FinalWindowDeviceContext = GetDC(FinalWindow);
    if(FinalWindowDeviceContext == NULL)
        puts("Retrieving the final window device cotext failed.\n");

    int FinalWindowPixelFormat;
    if(FALSE == wglChoosePixelFormatARB(FinalWindowDeviceContext,
    FinalWindowContextAttributes, NULL, 1, &FinalWindowPixelFormat, NULL))
        puts("Choosing the final window pixel format failed.\n");

    HGLRC FinalWindowRenderingContext =
        wglCreateContextAttribsARB(FinalWindowDeviceContext, NULL,
        FinalWindowContextAttributes);
    if(FinalWindowRenderingContext == NULL)
        puts("Creating the final rendering context failed.\n");

    if(FALSE == wglMakeCurrent(FinalWindowDeviceContext,
    FinalWindowRenderingContext))
        puts("Making the final context current failed.\n");

    DWM_BLURBEHIND blur = {};
    blur.dwFlags = DWM_BB_ENABLE | DWM_BB_BLURREGION;
    blur.fEnable = 1;
    blur.hRgnBlur = CreateRectRgn(0, 0, -1, -1);
    DwmEnableBlurBehindWindow(FinalWindow, &blur);

    SetLayeredWindowAttributes(FinalWindow, RGB(0, 0, 0), 255, LWA_COLORKEY);

    char VertexShaderSource[] =
    "#version 440 core\n"
    "\n"
    "layout(location = 0) in vec4 position;\n"
    "\n"
    "void main(){\n"
    "   gl_Position = position;\n"
    "}";

    char FragmentShaderSource[] =
    "#version 440 core\n"
    "\n"
    "layout(location = 0) out vec4 colour;\n"
    "\n"
    "void main(){\n"
    "   colour = vec4(0.5, 0.5, 0.5, 1.0);\n"
    "}";

    float Verticies[] = {
         0.0f,  0.5f, // top    : 0
         0.5f,  0.0f, // right  : 1
         0.0f, -0.5f, // bottom : 2
        -0.5f,  0.0f  // left   : 3
    };

    unsigned int Indices[] = {
        3, 0, 1, // top
        3, 2, 1  // bottom
    };

    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    unsigned int VertexArray;
    glGenVertexArrays(1, &VertexArray);
    glBindVertexArray(VertexArray);

    unsigned int VertexBuffer;
    glGenBuffers(1, &VertexBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, VertexBuffer);
    glBufferData(GL_ARRAY_BUFFER, 8 * sizeof(float), Verticies, GL_STATIC_DRAW);

    unsigned int IndexBuffer;
    glGenBuffers(1, &IndexBuffer);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexBuffer);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, 6 * sizeof(unsigned int), Indices,
        GL_STATIC_DRAW);

    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 2, 0);

    unsigned int ShaderProgram = CreateShaderProgram(VertexShaderSource,
        FragmentShaderSource);
    glUseProgram(ShaderProgram);

    glViewport(0, 0, 800, 400);

    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);

    ShowWindow(FinalWindow, 1);

    MSG msg;
    while(GetMessage(&msg, NULL, 0, 0)){
        DispatchMessage(&msg);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, NULL);
        wglSwapLayerBuffers(FinalWindowDeviceContext, WGL_SWAP_MAIN_PLANE);
    }
}

LRESULT CALLBACK FirstWindowProcedure(HWND hWnd, UINT uMsg, WPARAM wp, LPARAM lp){
    return DefWindowProc(hWnd, uMsg, wp, lp);
}

LRESULT CALLBACK FinalWindowProcedure(HWND hWnd, UINT uMsg, WPARAM wp, LPARAM lp){
    switch(uMsg){
        case WM_NCHITTEST: return HTCAPTION;
        case WM_DESTROY: PostQuitMessage(0); return 0;
        default: return DefWindowProc(hWnd, uMsg, wp, lp);
    }
}

unsigned int CreateShader(char* Source, unsigned int Type);

unsigned int CreateShaderProgram(char* VertexSource,
char* FragmentSource){
    unsigned int ShaderProgram = glCreateProgram(),
        VertexShader = CreateShader(VertexSource, GL_VERTEX_SHADER),
        FragmentShader = CreateShader(FragmentSource, GL_FRAGMENT_SHADER);
    glAttachShader(ShaderProgram, VertexShader);
    glAttachShader(ShaderProgram, FragmentShader);
    glLinkProgram(ShaderProgram);
    glValidateProgram(ShaderProgram);
    return ShaderProgram;
}

unsigned int CreateShader(char* Source, unsigned int Type){
    unsigned int Shader = glCreateShader(Type);
    glShaderSource(Shader, 1, (const char* const*)&Source, NULL);
    glCompileShader(Shader);
    return Shader;
}
c winapi opengl
2个回答
1
投票

因为您使用glew.h,所以我建议也使用“ wglew.h”。参见The OpenGL Extension Wrangler Library

#include <wglext.h>

#include <GL/wglew.h>

wglew.h处理wgl * api的动态链接。因此,您可以跳过调用wglGetProcAddress

/*   DELETE

PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB =
    (PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress("wglChoosePixelFormatARB");
if(wglChoosePixelFormatARB == NULL)
    puts("Getting the wglChoosePixelFormatARB function pointer failed.\n");

PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB =
    (PFNWGLCREATECONTEXTATTRIBSARBPROC)
    wglGetProcAddress("wglCreateContextAttribsARB");
if(wglCreateContextAttribsARB == NULL)
    puts("Getting the wglCreateContextAttribsARB function pointer"
        "failed.\n");
*/

0
投票
if(glewInit() != GLEW_OK)

您需要在glewInit()之后再次调用wglMakeCurrent()以获得最终窗口,并且希望立即销毁临时窗口。否则,GLEW将保留之前没有Core Profile的初始化状态。

int FinalWindowContextAttributes [] = {

如上一个问题中所指定,wglChoosePixelFormatARB()wglCreateContextAttribsARB()接受不同的属性列表,因此您需要创建单独的列表。

您可以尝试以下CreateCoreProfile()方法来创建OpenGL核心配置文件(我想这就是您要寻找的)。该代码段包含wglext.h中的定义,因此您可以删除它们以使用wglext.h。它不依赖GLEW,仅依赖WinAPI。

    wglSwapLayerBuffers(FinalWindowDeviceContext, WGL_SWAP_MAIN_PLANE);

您应该非常小心,并考虑使用SwapBuffers()(不带wgl前缀),因为wglSwapLayerBuffers()可能会导致非常奇怪的行为,并且我所见过的大多数参考资料都不推荐这样做。但是我想这是您正在考虑考虑SetLayeredWindowAttributes()电话的问题。

使用wglGetProcAddress()强制转换的函数指针在使用gcc编译时会生成警告

这是一个已知的GCC问题-WGL(wglGetProcAddress()),GLX和EGL API以及其他许多API都没有其他方法来验证返回的函数指针的签名。这是不安全的(应用程序将在调用具有不同签名的函数时崩溃),但是您无法采取任何措施来修复警告-暂时只能将其删除。

#include <windows.h>
#include <iostream>
#include <GL/gl.h>

//! Auxiliary tool creating WGL rendering context.
class WglWindow
{
private:
  #define GL_SHADING_LANGUAGE_VERSION 0x8B8C

  // WGL_ARB_pixel_format
  #define WGL_DRAW_TO_WINDOW_ARB  0x2001
  #define WGL_DRAW_TO_BITMAP_ARB  0x2002
  #define WGL_ACCELERATION_ARB    0x2003
  #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_DEPTH_BITS_ARB      0x2022
  #define WGL_STENCIL_BITS_ARB    0x2023

  #define WGL_NO_ACCELERATION_ARB      0x2025
  #define WGL_GENERIC_ACCELERATION_ARB 0x2026
  #define WGL_FULL_ACCELERATION_ARB    0x2027

  #define WGL_TYPE_RGBA_ARB       0x202B
  #define WGL_TYPE_COLORINDEX_ARB 0x202C

  // WGL_ARB_create_context_profile
  #define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091
  #define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092
  #define WGL_CONTEXT_FLAGS_ARB         0x2094
  #define WGL_CONTEXT_PROFILE_MASK_ARB  0x9126

  // WGL_CONTEXT_FLAGS bits
  #define WGL_CONTEXT_DEBUG_BIT_ARB 0x0001
  #define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002

  // WGL_CONTEXT_PROFILE_MASK_ARB bits
  #define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
  #define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002

  #define GL_NUM_EXTENSIONS 0x821D

  typedef const char* (WINAPI *wglGetExtensionsStringARB_t)(HDC theDeviceContext);
  typedef BOOL (WINAPI *wglChoosePixelFormatARB_t)(HDC theDevCtx, const int* theIntAttribs,
                                                   const float* theFloatAttribs, unsigned int theMaxFormats,
                                                   int* theFormatsOut, unsigned int* theNumFormatsOut);
  typedef HGLRC (WINAPI *wglCreateContextAttribsARB_t)(HDC theDevCtx, HGLRC theShareContext, const int* theAttribs);
  typedef const GLubyte* (WINAPI *glGetStringi_t) (GLenum name, GLuint index);

public:

  //! Create OpenGL Core Profile rendering context for specified window.
  static HGLRC CreateCoreProfile (HDC  theDevCtx,
                                  bool theIsDebugCtx)
  {
    HGLRC aGlCtx = NULL;
    {
      WglWindow aCtxTmp (L"wgltemp");
      if (!aCtxTmp.CreateDefaultWindow()) { return NULL; }
      const char* aWglExts = NULL;
      {
        wglGetExtensionsStringARB_t wglGetExtensionsStringARB = (wglGetExtensionsStringARB_t )wglGetProcAddress ("wglGetExtensionsStringARB");
        if (wglGetExtensionsStringARB != NULL) { aWglExts = wglGetExtensionsStringARB (aCtxTmp.myDevCtx); }
      }
      if (aWglExts == NULL) { return NULL; } // should never happen

      // in WGL world wglGetProcAddress() returns NULL if extensions is unavailable, so that checking for extension string can be skipped
      //if (checkGlExtension (aWglExts, "WGL_ARB_pixel_format"))
      //if (checkGlExtension (aWglExts, "WGL_ARB_create_context_profile"))
      wglChoosePixelFormatARB_t    aChoosePixProc = (wglChoosePixelFormatARB_t    )wglGetProcAddress ("wglChoosePixelFormatARB");
      wglCreateContextAttribsARB_t aCreateCtxProc = (wglCreateContextAttribsARB_t )wglGetProcAddress ("wglCreateContextAttribsARB");
      if (aCreateCtxProc == NULL) { return NULL; } // core profile cannot be created

      const int aPixAttribs[] =
      {
        WGL_DRAW_TO_WINDOW_ARB, GL_TRUE,
        WGL_SUPPORT_OPENGL_ARB, GL_TRUE,
        WGL_DOUBLE_BUFFER_ARB,  GL_TRUE,
        WGL_STEREO_ARB,         GL_FALSE,
        WGL_PIXEL_TYPE_ARB,     WGL_TYPE_RGBA_ARB,
        WGL_COLOR_BITS_ARB,     24,
        WGL_DEPTH_BITS_ARB,     24,
        WGL_STENCIL_BITS_ARB,   8,
        WGL_ACCELERATION_ARB,   WGL_FULL_ACCELERATION_ARB,
        0, 0,
      };
      unsigned int aFrmtsNb = 0;
      int aPixelFrmtId = 0;
      if (!aChoosePixProc (theDevCtx, aPixAttribs, NULL, 1, &aPixelFrmtId, &aFrmtsNb)
       ||  aPixelFrmtId == 0
       || !WglWindow::SetWindowPixelFormat (theDevCtx, aPixelFrmtId))
      {
        return NULL;
      }

      int aCoreCtxAttribs[] =
      {
        WGL_CONTEXT_MAJOR_VERSION_ARB, 3,
        WGL_CONTEXT_MINOR_VERSION_ARB, 2,
        WGL_CONTEXT_PROFILE_MASK_ARB,  WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
        WGL_CONTEXT_FLAGS_ARB,         theIsDebugCtx ? WGL_CONTEXT_DEBUG_BIT_ARB : 0,
        0, 0
      };

      // Try to create the core profile of highest OpenGL version.
      // This will be done automatically by some drivers when requesting 3.2,
      // but some will not (e.g. AMD Catalyst) since WGL_ARB_create_context_profile specification allows both implementations.
      for (int aLowVer4 = 7; aLowVer4 >= 0 && aGlCtx == NULL; --aLowVer4)
      {
        aCoreCtxAttribs[1] = 4; aCoreCtxAttribs[3] = aLowVer4;
        aGlCtx = aCreateCtxProc (theDevCtx, NULL, aCoreCtxAttribs);
      }
      for (int aLowVer3 = 3; aLowVer3 >= 2 && aGlCtx == NULL; --aLowVer3)
      {
        aCoreCtxAttribs[1] = 3; aCoreCtxAttribs[3] = aLowVer3;
        aGlCtx = aCreateCtxProc (theDevCtx, NULL, aCoreCtxAttribs);
      }
    }
    if (aGlCtx != NULL)
    {
      if (!::wglMakeCurrent (theDevCtx, aGlCtx)) { std::cerr << "Error: unable to bind context\n"; }
    }   
    return aGlCtx;
  }

public:

  //! Empty constructor.
  WglWindow (const wchar_t* theName) : myWin (NULL), myDevCtx (NULL), myGlCtx (NULL) {}

  //! Destructor.
  ~WglWindow() { Release(); }

  //! Release resources.
  void Release()
  {
    //wglMakeCurrent (NULL, NULL);
    if (myWin != NULL && myDevCtx != NULL) { ::ReleaseDC (myWin, myDevCtx); myDevCtx = NULL; }
    if (myGlCtx != NULL) { ::wglDeleteContext (myGlCtx); myGlCtx = NULL; }
    if (myWin   != NULL) { ::DestroyWindow (myWin); myWin = NULL; }
  }

public:

  //! Create a window handle.
  bool CreateDefaultWindow()
  {
    myWin = createWglWindow (L"TmpGlWindow");
    if (myWin == NULL) { return false; }
    myDevCtx = ::GetDC (myWin);
    if (myDevCtx == NULL) { return false; }
    if (!WglWindow::SetWindowPixelFormat (myDevCtx, -1)) { return false; }
    myGlCtx = ::wglCreateContext (myDevCtx);
    return myGlCtx != NULL && ::wglMakeCurrent (myDevCtx, myGlCtx);    
  }

  //! Wrapper for SetPixelFormat().
  static bool SetWindowPixelFormat (HDC theDevCtx, int theFormat)
  {
    PIXELFORMATDESCRIPTOR aFormat = {};
    aFormat.nSize = sizeof(aFormat);
    aFormat.nVersion = 1;
    aFormat.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL;
    aFormat.iPixelType = PFD_TYPE_RGBA;
    aFormat.cColorBits = 32;
    const int aFormatIndex = theFormat == -1 ? ::ChoosePixelFormat (theDevCtx, &aFormat) : theFormat;
    if (aFormatIndex == 0)
    {
      std::cerr << "Error: ChoosePixelFormat() failed, Cannot find a suitable pixel format.\n";
      return false;
    }

    if (theFormat != -1) { ::DescribePixelFormat (theDevCtx, aFormatIndex, sizeof(PIXELFORMATDESCRIPTOR), &aFormat); }
    if (::SetPixelFormat (theDevCtx, aFormatIndex, &aFormat) == FALSE)
    {
      std::cerr << "Error: SetPixelFormat(" << aFormatIndex << ") failed with error code " << GetLastError() << "\n";
      return false;
    }
    return true;
  }

public:
  //! Dummy window procedure.
  static LRESULT WINAPI dummyWinProc (HWND theWin, UINT theMsg, WPARAM theParamW, LPARAM theParamL)
  {
    return ::DefWindowProcW (theWin, theMsg, theParamW, theParamL);
  }

  //! Create a window handle.
  static HWND createWglWindow (const wchar_t* theTitle)
  {
    WNDCLASSW aWinClass = {};
    aWinClass.lpszClassName = L"OpenGL";
    static HINSTANCE anAppInstance = NULL;
    if (anAppInstance == NULL)
    {
      // only register the window class once
      anAppInstance = GetModuleHandleW (NULL);
      aWinClass.style = CS_OWNDC;
      aWinClass.lpfnWndProc = dummyWinProc;
      aWinClass.hInstance = anAppInstance;
      aWinClass.hIcon   = LoadIconW (NULL, IDI_WINLOGO);
      aWinClass.hCursor = LoadCursorW (NULL, IDC_ARROW);
      if (!RegisterClassW (&aWinClass))
      {
        std::cerr << "Error: RegisterClass() failed, cannot register window class.\n";
        return NULL;
      }
    }

    HWND aWin = CreateWindowExW (WS_EX_TOOLWINDOW | WS_EX_WINDOWEDGE, aWinClass.lpszClassName, theTitle,
                                 WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
                                 2, 2, 4, 4, NULL, NULL, anAppInstance, NULL);
    if (aWin == NULL) { std::cerr << "Error: CreateWindow() failed, Cannot create a window.\n"; }
    return aWin;
  }

private:
  HWND  myWin;
  HDC   myDevCtx;
  HGLRC myGlCtx;
};

int main()
{
  HWND  aTestWin = WglWindow::createWglWindow (L"GLWindow");
  HDC   aDevCtx  = ::GetDC (aTestWin);
  HGLRC aGlCtx   = WglWindow::CreateCoreProfile (aDevCtx, false);
  if (aGlCtx != NULL)
  {
    std::cout << "[WGL] OpenGL vendor string: "   << ::glGetString (GL_VENDOR)   << "\n";
    std::cout << "[WGL] OpenGL renderer string: " << ::glGetString (GL_RENDERER) << "\n";
    std::cout << "[WGL] OpenGL version string: "  << ::glGetString (GL_VERSION)  << "\n";
  }
  return 0;
}

请注意,代码段尝试创建最高4.x或3.x版本的Core Profile(对于这种情况,当引擎是可扩展的,并且希望尽可能地用作匹配功能时),如果仅需要,可以将其省略确切的版本。

© www.soinside.com 2019 - 2024. All rights reserved.