OpenGL get Device Context

2020-07-30 03:32发布

问题:

I am trying to create an OpenGL application on windows. As far as I can understand, one of the first things I must acquire is a Device Context, which must be passed on to a couple of functions that choose and set a pixel format and create a rendering context. I used the OpenGL wiki to get a rough idea about what I should do. My code is something like:

#include <iostream>
#include <windef.h>
#include <wingdi.h>

HDC hdc;

int main() {
    hdc = wglGetCurrentDC();
    std::cout << "HDC: " << hdc << std::endl;
    return 0;
}

This prints

HDC: 0

I assumed a Device Context refers to a physical device, but I read somewhere that it refers to any drawable "surface". In both cases is my question: how can I obtain a non-null DC? Or should I perform a completely different set of steps in order to set up this whole OpenGL system?

I found a lot of tutorials online, but they all use GLUT, GLEW, GLFW, X11, SDL etc. which are libraries. Libraries make certain things easier, but they usually do not perform tasks that are impossible without using them. This time, I want to try to do things the hard way and therefore use no libraries, just plain OpenGL.

I found, at last, a tutorial that only used the windows libraries for creating a window.

回答1:

You did not state your OS but I assume Windows from the function names. The problem is exactly as Reto Koradi stated in the comment. To set up OpenGL you need to do this:

  1. Obtain OS handle to object with valid device context

    It can be OS window or OS bitmap. If you have just console app then you need to create a valid OS window first and use its handle (to my knowledge console does not have Canvas).

    you can use GLUT for the window creation or If your compiler IDE has an window App you can use that. You can also combine OpenGL and Window components. VCL is also not a problem (I am using it for years with OpenGL)

    In windows you can use CreateWindowEx so google an example for it...

    Anyway you should have your handle in a variable like:

    HWND hwin=NULL;
    

    If you have no experience with windows applications then use GLUT for this. Otherwise you would need to learn a lot of stuff just to cover window creation, message handling of events and user/app interaction which can be really overwhelming for a rookie without guide.

  2. Get Device context for that handle

    HDC hdc = GetDC(hwin);
    
  3. Set pixel format you need of device context

    PIXELFORMATDESCRIPTOR pfd;
    ZeroMemory( &pfd, sizeof( pfd ) );      // set the pixel format for the DC
    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 = 24;
    pfd.cDepthBits = 24;
    pfd.iLayerType = PFD_MAIN_PLANE;
    SetPixelFormat(hdc,ChoosePixelFormat(hdc, &pfd),&pfd);
    
  4. Create OpenGL rendering context for device context

    HGLRC hrc = wglCreateContext(hdc);
    
  5. Set it as default OpenGL context

    wglMakeCurrent(hdc, hrc);
    

This is absolute minimum without any error checking , additional buffers etc. For more info and actual code see related QA's:

  • How to render an openGL frame in C++ builder? for oldstyle GL
  • simple complete GL+VAO/VBO+GLSL+shaders example in C++ with the new stuff

You can use GLUT for all of this. This is first hit I found by quick search:

  • How can I set an OpenGL display (Window created by OpenGL) to maximized?

Or follow OpenGL tutorials there are tons of them out there ...