CodeBlocks offers an example program in C, that uses OpenGL. It draws a single multicoloured rotating triangle. I have been building on this example. I am a novice in C and in OpenGL. I believe that I am using an old style of OpenGL coding (possibly called "Immediate Mode ?") and I am trying to keep things as simple as possible. For example, I am not, to my knowledge, using VBOs, nor VAOs, nor GLSL. I am also not, as far as I know, using any helper libraries (if that's a right way to say it), such as GLEW, GLFW, GLut, etc.

I notice that the sides of the triangles are more jagged than they need to be, given the resolution of my laptop screen. Even if no multisampling were used (and I am not yet trying to use it), much smaller "jaggies" could be achieved, if OpenGL's raster array really corresponded to the physical pixel array. I took a "print screen" and opened it in MS Paint, saving it as a .bmp. When I zoomed in, it seemed that multisampling had been used, but to smooth the edges of the large jaggies ! If you see what I mean.

EDIT: Here is a picture: Example

This shows that the text on the left (which is not from my OpenGL window) is rendered at a higher resolution than my triangley object on the right (which is in my OpenGL window).

My question is, how can I use the maximum resolution of the screen ?

Here are some excerpts from the code:

#include <windows.h>
#include <gl/gl.h>
#include <stdio.h>

int WINAPI WinMain(HINSTANCE hInstance,
                   HINSTANCE hPrevInstance,
                   LPSTR lpCmdLine,
                   int nCmdShow)
    WNDCLASSEX wcex;
    HWND hwnd;
    HDC hDC;
    HGLRC hRC;
    MSG msg;
    BOOL bQuit = FALSE;

    const int width = 768;
    const int height = 768;

    /* register window class */
    wcex.cbSize = sizeof(WNDCLASSEX);
    wcex.style = CS_OWNDC;
    wcex.lpfnWndProc = WindowProc;
    wcex.cbClsExtra = 0;
    wcex.cbWndExtra = 0;
    wcex.hInstance = hInstance;
    wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
    wcex.lpszMenuName = NULL;
    wcex.lpszClassName = "GLSample";
    wcex.hIconSm = LoadIcon(NULL, IDI_APPLICATION);;

    if (!RegisterClassEx(&wcex))
        return 0;

    /* create main window */
    hwnd = CreateWindowEx(0,
                          "OpenGL Sample",

    ShowWindow(hwnd, nCmdShow);

    /* enable OpenGL for the window */
    EnableOpenGL(hwnd, &hDC, &hRC);

and the EnableOpenGL function:

void EnableOpenGL(HWND hwnd, HDC* hDC, HGLRC* hRC)

    int iFormat;

    /* get the device context (DC) */
    *hDC = GetDC(hwnd);

    /* set the pixel format for the DC */
    ZeroMemory(&pfd, sizeof(pfd));

    pfd.nSize = sizeof(pfd);
    pfd.nVersion = 1;
    pfd.dwFlags = PFD_DRAW_TO_WINDOW |
    pfd.iPixelType = PFD_TYPE_RGBA;
    pfd.cColorBits = 24;
    pfd.cDepthBits = 16;
    pfd.iLayerType = PFD_MAIN_PLANE;

    iFormat = ChoosePixelFormat(*hDC, &pfd);

    SetPixelFormat(*hDC, iFormat, &pfd);

    /* create and enable the render context (RC) */
    *hRC = wglCreateContext(*hDC);

    wglMakeCurrent(*hDC, *hRC);

You might need to use a setting to tell Windows that your program is DPI-aware, meaning that it can adjust to very high-resolution screens like many current-gen laptops have.

Lots of older programs have trouble with such high resolutions, so without the DPI awareness flag, Windows will tell the program the resolution is lower, and then upscale the whole window. That looks like it might be what's happening to your OpenGL app.

The simplest way to do this is to add a call to SetProcessDPIAware() during your program's startup, before creating the window. You might also want to increase the hard-coded width and height values.

The other way to do it is by adding an XML "manifest" file that gets linked into your app's .exe file, but it might be hard to get that working in Code::Blocks if it doesn't have it built in.

For more information: Setting the default DPI awareness for a process

  • $\begingroup$ Wow ! Thank you very much ! That fixed it. I found the MS docs recommended using the manifest version as the in-program version can cause "unexpected behavior". Much as I don't want to potato my computer, I am also reluctant to face the learning curve of the "manifest". I also found that CodeBlocks objected to my use of the command SetProcessDPIAware(), warning that it was an implicit declaration of a function. I looked up various hacks for this, but none worked, so I will live with it. Interestingly it worked even before I included the winuser.h header file where the docs say it comes from. $\endgroup$
    – Simon
    Dec 12 '21 at 0:05
  • 1
    $\begingroup$ Glad it worked! Yeah, Microsoft recommends using the manifest, but I'm not very clear on why, or what "unexpected behavior" might mean. Bur if it works, don't fix it, I guess! $\endgroup$ Dec 12 '21 at 0:14
  • 1
    $\begingroup$ My favourite maxim !! Especially since I am doing this for hobby / educational purposes, not with a view to creating a deployable app. I think I might now be enjoying a slightly lower frame rate with all my new pixels, so I am coding a frame rate counter to test that. The dpi on this screen turns out to be so high as to make me suppose that for many purposes, there would be no point in using multisampling. $\endgroup$
    – Simon
    Dec 12 '21 at 0:19
  • $\begingroup$ Update: If my frame rate counter can be trusted, then the higher DPI made no difference. I got about 60 fps consistently even while wildly rotating the scene, with or without the high DPI. Bearing in mind that my scene only has 16 (biggish) triangles ! $\endgroup$
    – Simon
    Dec 12 '21 at 1:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.