Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ / OpenGL | "undefined reference to `_imp__ChoosePixelFormat@8`" and more

I was reading NeHe's first guide to OpenGL programming, and when it came down to compiling the result of completing his first tutorial, I was stumped to find errors throughout. Here's the entire source file where the errors occur (Created in Eclipse CDT with 'opengl32' 'glaux' 'glut32' 'glu32' linked successfully):

#include <windows.h>
#include <gl/gl.h>
#include <gl/glu.h>
#include <gl/glaux.h>
#define GLEW_STATIC

HGLRC hRC = NULL;
HDC hDC = NULL;
HWND hWnd = NULL;
HINSTANCE hInstance;

bool keys[256];
bool active = TRUE;
bool fullscreen = TRUE;

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

GLvoid ResizeGLScene(GLsizei width, GLsizei height)
{
    if(height == 0) height = 1;

    glViewport(0, 0, width, height);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    gluPerspective(45.0f, (GLfloat) width / (GLfloat) height, 0.1f, 100.0f);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}

int InitGL()
{
    glShadeModel(GL_SMOOTH);
    glClearColor(0, 0, 0, 0);
    glClearDepth(1);
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LEQUAL);
    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);

    return TRUE;
}

int DrawGLScene()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();

    return TRUE;
}

void KillGLWindow()
{
    if(fullscreen)
    {
        ChangeDisplaySettings(NULL, 0);
        ShowCursor(TRUE);
    }

    if(hRC)
    {
        if(!wglMakeCurrent(NULL, NULL))
        {
            MessageBox(NULL, "Release of DC and RC failed.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);
        }

        if(!wglDeleteContext(hRC))
        {
            MessageBox(NULL, "Release rendering context failed.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);
        }

        hRC = NULL;
    }

    if(hDC && !ReleaseDC(hWnd, hDC))
    {
        MessageBox(NULL, "Release device context failed.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);

        hDC = NULL;
    }

    if(hWnd && !DestroyWindow(hWnd))
    {
        MessageBox(NULL, "Could not release hWnd.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);

        hWnd = NULL;
    }

    if(!UnregisterClass("OpenGL", hInstance))
    {
        MessageBox(NULL, "Could not unregister class.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);

        hInstance = NULL;
    }
}

BOOL CreateGLWindow(char* title, int width, int height, int bits, bool fullscreenFlag)
{
    GLuint pixelFormat;
    WNDCLASS wc;
    DWORD dwExStyle;
    DWORD dwStyle;
    RECT windowRect;

    windowRect.left = 0;
    windowRect.right = width;
    windowRect.top = 0;
    windowRect.bottom = height;

    fullscreen = fullscreenFlag;
    hInstance = GetModuleHandle(NULL);

    wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
    wc.lpfnWndProc = WndProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInstance;
    wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = NULL;
    wc.lpszMenuName = NULL;
    wc.lpszClassName = "OpenGL";

    if(!RegisterClass(&wc))
    {
        MessageBox(NULL, "Failed to register the window class.", "ERROR", MB_OK | MB_ICONEXCLAMATION);

        return FALSE;
    }

    if(fullscreen)
    {
        DEVMODE dmScreenSettings;

        memset(&dmScreenSettings, 0, sizeof(dmScreenSettings));

        dmScreenSettings.dmSize = sizeof(dmScreenSettings);
        dmScreenSettings.dmPelsWidth = width;
        dmScreenSettings.dmPelsHeight = height;
        dmScreenSettings.dmBitsPerPel = bits;
        dmScreenSettings.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;

        if(ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)
        {
            if(MessageBox(NULL, "The requested fullscreen mode is not supported by\nyour video card.  Use windowed mode instead?", "OpenGL", MB_YESNO | MB_ICONEXCLAMATION) == IDYES)
            {
                fullscreen = FALSE;
            }
            else
            {
                MessageBox(NULL, "Program will now close.", "ERROR", MB_OK | MB_ICONSTOP);

                return FALSE;
            }
        }
    }

    if(fullscreen)
    {
        dwExStyle = WS_EX_APPWINDOW;
        dwStyle = WS_POPUP;

        ShowCursor(FALSE);
    }
    else
    {
        dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
        dwStyle = WS_OVERLAPPEDWINDOW;
    }

    AdjustWindowRectEx(&windowRect, dwStyle, FALSE, dwExStyle);

    if(!(hWnd = CreateWindowEx(dwExStyle,
            "OpenGL",
            title,
            WS_CLIPSIBLINGS |
            WS_CLIPCHILDREN |
            dwStyle,
            0,
            0,
            windowRect.right - windowRect.left,
            windowRect.bottom - windowRect.top,
            NULL,
            NULL,
            hInstance,
            NULL)))
        {
            KillGLWindow();

            MessageBox(NULL, "Window creation error.", "ERROR", MB_OK | MB_ICONINFORMATION);

            return FALSE;
        }

    static PIXELFORMATDESCRIPTOR pfd =
    {
            sizeof(PIXELFORMATDESCRIPTOR),
            1,
            PFD_DRAW_TO_BITMAP |
            PFD_SUPPORT_OPENGL |
            PFD_DOUBLEBUFFER,
            PFD_TYPE_RGBA,
            bits,
            0, 0, 0, 0, 0, 0,
            0,
            0,
            0,
            0, 0, 0, 0,
            16,
            0,
            0,
            PFD_MAIN_PLANE,
            0,
            0, 0, 0
    };

    if(!(hDC = GetDC(hWnd)))
    {
        KillGLWindow();

        MessageBox(NULL, "Cannot create a GL device context.", "ERROR", MB_OK | MB_ICONEXCLAMATION);

        return FALSE;
    }

    if(!(pixelFormat = ChoosePixelFormat(hDC, &pfd)))
    {

        ChoosePixelFormat(hDC, &pfd);
        KillGLWindow();

        MessageBox(NULL, "Cannot find a suitable pixel format.", "ERROR", MB_OK | MB_ICONEXCLAMATION);

        return FALSE;
    }

    if(!SetPixelFormat(hDC, pixelFormat, &pfd))
    {
        KillGLWindow();

        MessageBox(NULL, "Cannot set the pixel format.", "ERROR", MB_OK | MB_ICONEXCLAMATION);

        return FALSE;
    }

    if(!(hRC = wglCreateContext(hDC)))
    {
        KillGLWindow();

        MessageBox(NULL, "Cannot create a GL rendering context.", "ERROR", MB_OK | MB_ICONEXCLAMATION);

        return FALSE;
    }

    if(!wglMakeCurrent(hDC, hRC))
    {
        KillGLWindow();

        MessageBox(NULL, "Cannot activate the GL rendering context.", "ERROR", MB_OK | MB_ICONEXCLAMATION);

        return FALSE;
    }

    ShowWindow(hWnd, SW_SHOW);
    SetForegroundWindow(hWnd);
    SetFocus(hWnd);
    ResizeGLScene(width, height);

    if(!InitGL())
    {
        KillGLWindow();

        MessageBox(NULL, "Initialization failed.", "ERROR", MB_OK | MB_ICONEXCLAMATION);

        return FALSE;
    }

    return TRUE;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch(uMsg)
    {
        case WM_ACTIVATE:
        {
            if(!HIWORD(wParam))
            {
                active = TRUE;
            }
            else
            {
                active = FALSE;
            }

            return 0;
        }


        case WM_SYSCOMMAND:
        {
            switch(wParam)
            {
                case SC_SCREENSAVE:
                case SC_MONITORPOWER:

                return 0;
            }

            break;
        }

        case WM_CLOSE:
        {
            PostQuitMessage(0);

            return 0;
        }

        case WM_KEYDOWN:
        {
            keys[wParam] = TRUE;

            return 0;
        }

        case WM_KEYUP:
        {
            keys[wParam] = FALSE;

            return 0;
        }

        case WM_SIZE:
        {
            ResizeGLScene(LOWORD(lParam), HIWORD(lParam));

            return 0;
        }
    }

    return DefWindowProc(hWnd, uMsg, wParam, lParam);
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    MSG msg;
    BOOL done = FALSE;

    if(MessageBox(NULL, "Would you like to run in fullscreen mode?", "Start Fullscreen", MB_YESNO | MB_ICONQUESTION) == IDNO)
    {
        fullscreen = false;
    }

    if(!CreateGLWindow("OpenGL", 640, 480, 16, fullscreen))
    {
        return 0;
    }

    while(!done)
    {
        if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
        {
            if(msg.message == WM_QUIT)
            {
                done = TRUE;
            }
            else
            {
                TranslateMessage(&msg);
                DispatchMessage(&msg);
            }
        }
        else
        {
            if(active)
            {
                if(keys[VK_ESCAPE])
                {
                    done = TRUE;
                }
                else
                {
                    DrawGLScene();
                    SwapBuffers(hDC);
                }
            }

            if(keys[VK_F1])
            {
                keys[VK_F1] = FALSE;
                KillGLWindow();

                fullscreen = !fullscreen;

                if(!CreateGLWindow("OpenGL", 640, 480, 16, fullscreen))
                {
                    return 0;
                }
            }
        }
    }

    KillGLWindow();

    return msg.wParam;
}

...and here is the resulting compile (Using MinGW, opengl, glut, glaux added):

03:52:04 **** Incremental Build of configuration Debug for project GL ****
Info: Internal Builder is used for build
g++ -O0 -g3 -Wall -c -fmessage-length=0 -o "src\\Main.o" "..\\src\\Main.cpp" 
..\src\Main.cpp: In function 'BOOL CreateGLWindow(char*, int, int, int, bool)':
..\src\Main.cpp:216:2: warning: narrowing conversion of 'bits' from 'int' to 'BYTE {aka unsigned char}' inside { } is ill-formed in C++11 [-Wnarrowing]
  };
  ^
..\src\Main.cpp: In function 'int WinMain(HINSTANCE, HINSTANCE, LPSTR, int)':
..\src\Main.cpp:356:55: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
  if(!CreateGLWindow("OpenGL", 640, 480, 16, fullscreen))
                                                       ^
..\src\Main.cpp:397:58: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
     if(!CreateGLWindow("OpenGL", 640, 480, 16, fullscreen))
                                                          ^
g++ -o GL.exe "src\\Main.o" -lopengl32 -lglaux -lglaux -lglu32 -lfreeglut 
src\Main.o: In function `Z14CreateGLWindowPciiib':
C:\Users\Michael\Desktop\LiTHiA\C++\GL\Debug/../src/Main.cpp:227: undefined reference to `_imp__ChoosePixelFormat@8'
C:\Users\Michael\Desktop\LiTHiA\C++\GL\Debug/../src/Main.cpp:230: undefined reference to `_imp__ChoosePixelFormat@8'
C:\Users\Michael\Desktop\LiTHiA\C++\GL\Debug/../src/Main.cpp:238: undefined reference to `_imp__SetPixelFormat@12'
src\Main.o: In function `WinMain@16':
C:\Users\Michael\Desktop\LiTHiA\C++\GL\Debug/../src/Main.cpp:386: undefined reference to `_imp__SwapBuffers@4'
collect2.exe: error: ld returned 1 exit status

03:52:05 Build Finished (took 1s.598ms)

I apologize that the code is quite extensive. Any help / advice? Any is appreciated. Thanks in advance.

like image 276
Michael Shift Avatar asked Jan 03 '15 09:01

Michael Shift


1 Answers

Link against gdi32 (i.e. add -lgdi32 to the linker command line). This library defines the functions ChoosePixelFormat, SetPixelFormat and SwapBuffers which are reported as undefined references in the linker error messages.

like image 93
user3146587 Avatar answered Oct 09 '22 09:10

user3146587