1

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.

Tempestas Ludi
  • 1,113
  • 9
  • 24
  • I'd think so too, but the article is mainly about creating an OpenGL context, while the context I need is a Device Context. The article states: "You should know what a window handle (HWND) and a device context (DC) are, as well as how to create them." – Tempestas Ludi Nov 10 '16 at 00:50
  • So you mean the code is not applicable in this case. I think you might be right, but then the question becomes how I must create one. – Tempestas Ludi Nov 10 '16 at 00:56
  • Sorry, you're right; because it was a WGL function, I mistook it for `wglGetCurrentContext`. – Nicol Bolas Nov 10 '16 at 01:31
  • `wglGetCurrentDC()` will not help here. If you look at its documentation, it "... obtains a handle to the device context that is associated with the current OpenGL rendering context...". Meaning that you can only use it **after** you created an OpenGL context. This all requires quite a lot more code. You'll have to create a window first, then go through various steps to get a DC, choose a pixel format, create an OpenGL context, etc. Beyond the scope of an answer here, at least for me... Start with studying how to write a basic app with just Win32, and then add the OpenGL pieces. – Reto Koradi Nov 10 '16 at 02:59

1 Answers1

4

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:

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

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

Community
  • 1
  • 1
Spektre
  • 49,595
  • 11
  • 110
  • 380
  • I am sorry I did not mention my OS. It is windows, as you already guessed. As for the steps you described: I get 3, 4 and 5 as they are quite clearly described in the wiki article I used. Thank you for making clear that I first must create a window. About using GLUT... GLUT is a library, which means there is probably also a way to create a window without using it? CreateWindow or CreateWindowEx might work, so I will try that. Thank you. – Tempestas Ludi Nov 10 '16 at 12:19