1
  1. Windows has only provided the GL v1.1 ; How to download the latest version of OpenGL binaries (+hearders) to begin coding in Windows, and where exactly to find them?
  2. Which version of the OpenGL is the latest version which is fully supported by all three MacOS, Linux, and Windows platforms?
genpfault
  • 51,148
  • 11
  • 85
  • 139
Jahan
  • 11
  • 3

4 Answers4

1

OpenGL is only a standard. I think the OpenGL Khronos group provide only headers for the OpenGL implementation but nothing else. The graphics card vendor provides a driver for their graphics card which is linked into the OS kernel. The problem here is that you don't know how the driver works. The vendor thus have to provide user mode libraries with their driver in order for the software implementer to be able to drive the card. This often comes in the form of an OpenGL/Direct3D implementation in the form of a user mode library that can be linked against from user mode programs.

Also, I'm not an expert but, I can tell that you need to create an OpenGL context and link this context with a platform dependent context that is the actual window to render content. This means that you need to tell the OS where to draw when your thread executes OpenGL commands. Otherwise, your OpenGL commands/code lines don't do anything because they are not linked with a window/device context.

For example, on Linux you have a file called /dev/dri/card0 which is the integrated graphics card on Intel/AMD based computers. The OpenGL library implementation will do system calls in the form of ioctl() calls on this character device to drive the card. Underneath, there is a driver which is provided by hardware vendors which registers itself in the kernel and tells the kernel with some functions that this driver is a graphics driver and that it supports certain types of devices among which is the /dev/dri/card0 character device. It probably also passes a PCI ID which is the device ID that the graphics card returns upon reading its PCI configuration space. The OS kernel is thus able to identify that this driver must be used for a certain character device because this device has an ID which is the same as the one the driver provided upon registration.

There are some libraries provided like glut, freeglut and GLFW which, imho, are very bad. They often don't work and are quite hard to work with because they often end up creating lot of linking issues and a game/3D developer worthy of this name won't use them. These libraries only provide window and user input capabilities. These libraries are thus quite useless in the sense that creating a window and getting user input on Linux with the X server is 5 lines of code and the equivalent on Windows is 1 line of code and what's called a procedure for the window. It is really simple to implement by yourself. Actually, these libraries (freeglut, GLFW, etc.) use the platform dependent API provided by the OS kernel developers. They only wrap these in some #ifdef (macros) to provide cross-platform capabilities. In the end, reproducing the work that these libraries do is trivial and is often really better than actually using these libraries.

Also, Windows only provides OpenGL 1.1 support out of the box. You thus have these functions readily available and defined in the Visual Studio IDE. You can see that by the fact that these functions are highlighted in brown and you can see the signature of the function when you hover your mouse on top. The GLEW (not GLFW) library was found to be quite useful for a beginner (like me) to be able to start coding in OpenGL above 1.1 without requiring more work. The GLEW library will test the presence of OpenGL functions and get the procedure address using GetProcAdress() or wglGetProcAddress() on Windows and it is cross-platform (more info here: https://www.khronos.org/opengl/wiki/Load_OpenGL_Functions). This library requires one static .lib file called glew32.lib, one .dll (that you put in your executable's directory) called glew32.dll and one header that you include in your program called glew.h. Now I won't tell how to add include and library directories to Visual Studio but you can have a look somewhere on Google. The GLEW provided OpenGL functions will be in the form of macros. You will see them in purple in Visual Studio.

For example, a simple OpenGL program that does the same as GLFW on Windows with WinAPI and Visual Studio would look like the following:

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

#pragma comment(lib, "glew32")
#pragma comment(lib, "opengl32")
#pragma comment(lib, "glu32")

HDC dc;
HGLRC rc;

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
    switch (uMsg)
    {
    case WM_PAINT:
    {

    }
    break;
    case WM_LBUTTONDOWN:
    {

    }
    break;
    case WM_CLOSE:
    {
        DestroyWindow(hwnd);
    }
    break;
    case WM_DESTROY:
    {
        PostQuitMessage(0);
    }
    break;
    default:
        return DefWindowProc(hwnd, uMsg, wParam, lParam);
        break;
    }
}

int wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow) {
    WNDCLASS wc = { };
    wc.lpfnWndProc = WindowProc;
    wc.hInstance = hInstance;
    wc.lpszClassName = L"Window";
    RegisterClass(&wc);
    HWND hwnd = CreateWindowExW(0, L"Window", L"Window", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,
        CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
    ShowWindow(hwnd, nCmdShow);
    AllocConsole();
    freopen_s((FILE**)stdout, "CONOUT$", "w", stdout);
    MSG msg = { };

    PIXELFORMATDESCRIPTOR pfd = {
            sizeof(PIXELFORMATDESCRIPTOR),  //  size of this pfd  
            1,                     // version number  
            PFD_DRAW_TO_WINDOW |   // support window  
            PFD_SUPPORT_OPENGL |   // support OpenGL  
            PFD_DOUBLEBUFFER,      // double buffered  
            PFD_TYPE_RGBA,         // RGBA type  
            24,                    // 24-bit color depth  
            0, 0, 0, 0, 0, 0,      // color bits ignored  
            0,                     // no alpha buffer  
            0,                     // shift bit ignored  
            0,                     // no accumulation buffer  
            0, 0, 0, 0,            // accum bits ignored  
            32,                    // 32-bit z-buffer      
            0,                     // no stencil buffer  
            0,                     // no auxiliary buffer  
            PFD_MAIN_PLANE,        // main layer  
            0,                     // reserved  
            0, 0, 0                // layer masks ignored  
    };
    dc = GetDC(hwnd);
    int  index;
    index = ChoosePixelFormat(dc, &pfd);
    SetPixelFormat(dc, index, &pfd);
    rc = wglCreateContext(dc);
    wglMakeCurrent(dc, rc);

    GLenum res = glewInit();
    if (res != GLEW_OK) {
        printf("GLEW init failed: %s!", glewGetErrorString(res));
    }
    else {
        printf("GLEW init success!\n");
    }
    
    glClearColor(0.0, 0.0, 0.0, 1.0);
    glClear(GL_COLOR_BUFFER_BIT);
    SwapBuffers(dc);

    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return 0;
}

This program should create a blank window, create a console, print "GLEW init sucess!" on the console and then make the background of the window black. You see that this code is really trivial and this is what GLFW does underneath its "cross-platform" API. Like I said, I'm a beginner but I think that, in this case, the OpenGL calls will write into a double-buffer because we enabled double-buffering in the pixel format structure. To actually render something on the screen, one needs to call SwapBuffers() with the dc of the window to swap the double-buffer with the main buffer that is actually drawn.

user123
  • 2,510
  • 2
  • 6
  • 20
0

OpenGL is an open standart. The latest version depends on the driver you have installed for your GPU.

To use opengl higher than 1.1 you need glew (it exposes functionallity supported by your driver) and a framework for your context creation:

GLFW, GLUT, SDL

and more.

Currently latest OpenGL implementation: 4.5

Sup3rlum
  • 51
  • 7
  • 1
    To use GL higher than 1.1 you do not *need* glew. You also do not need any additional frameworks, you can do everything with just the GL API as it stands. – MuertoExcobito Jun 06 '15 at 19:14
0

There is no updated SDK for Windows, only the gl.h for OpenGL 1.1 is provided. To use additional functionality in Window OpenGL, you must use the extension header glext.h. This is available from Khronos, and it updated when new extensions become available. You can use wglGetProcAddress to get function pointers to function available in later versions of GL (or extensions). The procedure for getting access to additional functionality varies per platform. For example, if you are using X11, you can use glXGetProcAddressARB, if you have EGL on your platform, you would use eglGetProcAddress.

Depending on the platform and SDK, you can also simply #define GL_GLEXT_PROTOTYPES, before including glext.h, if the platform provides an updated GL SDK. Obviously, since Windows does not provide an updated SDK, this is not possible there, but it is on Linux, Mac, iOS and Android. In both methods, you will need to ensure that the GL context you are using either supports the function in the core API, or an extension that provides the function is available (see glGetString with GL_EXTENSIONS)), it is not enough that the SDK you build with contains the functionality. Thus, using the 'runtime linking' glGetProcAddress method is somewhat safer, in that if the function is not available, it will just return NULL. Using a function that is not available will lead to undefined behavior, and likely will crash.

As for the latest version supported on any given platform, this is dependent on your video driver, and not on the SDK you build with. When you create an OpenGL context, glGetString w/GL_VERSION will indicate which version of OpenGL your context supports, regardless which version of the GL SDK you built with. You can use any functionality that version guarantees, as well any functionality provided by the reported extensions.

MuertoExcobito
  • 9,741
  • 2
  • 37
  • 78
  • defining GL_GLEXT_PROTOTYPES **will not** automagically resolve the runtime symbols! All it does is providing gobal function pointer variable symbols which the addresses returned by `…GetProcAddress` can be assigned to. Without doing that runtime function address gathering the symbols' values are left undefined and thereby undefined behaviour (usually the program crashing) is invoked. You absolutely must retrieve the function pointers at runtime using `…GetProcAddress`; in fact on Windows you must retrieve the function pointers context, since the function pointers may be different for each one – datenwolf Jun 07 '15 at 14:51
  • Defining GL_GLEXT_PROTOTYPES *will* resolve the runtime symbols, on OSX, Linux, iOS and Android. No call to 'GetProcAddress' is required, in fact on some platforms, such a call doesn't even exist. Since the SDK on Windows is never updated, this was bad advice there, so, I've updated the answer based on your comment. – MuertoExcobito Jun 08 '15 at 11:31
  • On Linux this only works on circumstance if the `libGL.so` in question is not using hidden visibility on functions going beyond the ABI requirements. The recently published LSB requires only OpenGL-2.1 to be exposed. Older LSB requires only OpenGL-1.2. For any **conforming** program it is invalid to expect symbols to be exposed by the libGL.so and function pointers must be loaded at runtime with glXGetProcAddress. Driver developers may decide anytime to hide the symbols that lie outside the LSB requirements, thereby breaking *all* programs relying on GL_GLEXT_PROTOTYPES. – datenwolf Jun 08 '15 at 12:47
  • On OSX it's not necessary, because the OpenGL framework is exposing the symbols regardless; same goes for iOS. And on Android it's outright dangerous to rely on GL_GLEXT_PROTOTYPES, because on the Android platform you're in the hands of 3rd party driver vendors that can deliver whatever they want, without some strict ABI requirements in place. – datenwolf Jun 08 '15 at 12:49
  • Okay - so we're settled on OSX and iOS :). For Android before API-9, you *had* to use GL_GLEXT_PROTOTYPES, as EGL wasn't available until then. Mildly dangerous, because as you said, the driver vendors didn't necessary have to ship a valid ABI, but there was no choice. If they reported an extension, you had to rely that they also provided the appropriate function binding. – MuertoExcobito Jun 08 '15 at 12:57
  • No, on Android API <9 you did not have to use GL_GLEXT_PROTOTYPES. Why? Because launching programs/apps which use symbols not exposed by the OpenGL interface .so will result in a failure. The proper and canonical way to go about this is using `dlopen` and `dlsym` to resolve the symbols at runtime. – datenwolf Jun 08 '15 at 15:27
0
  1. in general, OpenGL wiki has all the links to download the latest OpenGL for your platform (OS and graphics card). Specifically for Windows, if you're using Visual Studio, NuGet package manager has a good pre-packaged OpenGL distribution called 'nupengl.core'.

  2. as Arctic said, 4.5 is the latest standard. Whether it is supported by your build depends on the graphics card, not on the OS.

Community
  • 1
  • 1
Qwerty
  • 183
  • 10
  • The nupengl.core package is basically freeglut and glew. It is a very bad package which creates linking issues and lacks updates. I know this was from 2015 but some people still end up here trying to set up OpenGL on Windows. I think the "using freeglut" advice is bad advice. Every tutorial on internet I could find give this bad advice but no developer will actually use this library. They will either use a 3D engine like Unreal or code their own targeting only Windows and start from scratch using WinAPI (see my answer). – user123 Nov 04 '21 at 17:42