I was following this tutorial for my first attempt at OpenGL. All I'm doing is initializing an empty window. His VS 2010 code is here. Using Dev-C++ as my IDE on Windows 7, and MS SDK 7.1, I get this error:

[Linker error] undefined reference to `_imp____wglewCreateContextAttribsARB' 
ld returned 1 exit status 
[Build Error]  ["My] Error 1 

I have -lopengl32 and -lglew32 as my linker parameters, and I've tried adding -lglu32 too.

Here's my code.
Opengl_3.h

#pragma once

#include <windows.h>
#include <iostream>

#include <GL/glew.h>
#include <GL/wglew.h>
//#pragma comment(lib, "glew32.lib")
//#pragma comment(lib, "opengl32.lib")


/*
OpenGLContext is a class designed to store all of your OpenGL functions and keep them
out of the way of your application logic. Here we have the ability to create an OpenGL
context on a given window and then render to that window.
*/
class OpenGLContext {

public:
    OpenGLContext(void); // Default constructor
    OpenGLContext(HWND hwnd); // Constructor for creating our context given a hwnd
    ~OpenGLContext(void); // Destructor for cleaning up our application
    bool create30Context(HWND hwnd); // Creation of our OpenGL 3.x context
    void setupScene(void); // All scene information can be setup here
    void reshapeWindow(int w, int h); // Method to get our window width and height on resize
    void renderScene(void); // Render scene (display method from previous OpenGL tutorials)

private:
    int windowWidth; // Store the width of our window
    int windowHeight; // Store the height of our window

protected:
    HGLRC hrc; // Rendering context
    HDC hdc; // Device context
    HWND hwnd; // Window identifier

};

Opengl_3.cpp

#include "Opengl_3.h"

/*
Default constructor for the OpenGLContext class. At this stage it does nothing
but you can put anything you want here.
*/
OpenGLContext::OpenGLContext(void) {}

/*
Constructor for the OpenGLContext class which will create a context given a windows HWND.
*/
OpenGLContext::OpenGLContext(HWND hwnd) {
    create30Context(hwnd); // Create a context given a HWND
}

/*
Destructor for our OpenGLContext class which will clean up our rendering context
and release the device context from the current window.
*/
OpenGLContext::~OpenGLContext(void) {
    wglMakeCurrent(hdc, 0); // Remove the rendering context from our device context
    wglDeleteContext(hrc); // Delete our rendering context

    ReleaseDC(hwnd, hdc); // Release the device context from our window
}

/*
create30Context creates an OpenGL context and attaches it to the window provided by
the HWND. This method currently creates an OpenGL 3.2 context by default, but will default
to an OpenGL 2.1 capable context if the OpenGL 3.2 context cannot be created.
*/
bool OpenGLContext::create30Context(HWND hwnd)
{
    this->hwnd = hwnd; // Set the HWND for our window

    hdc = GetDC(hwnd); // Get the device context for our window

    PIXELFORMATDESCRIPTOR pfd; // Create a new PIXELFORMATDESCRIPTOR (PFD)
    memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR)); // Clear our  PFD
    pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); // Set the size of the PFD to the size of the class
    pfd.dwFlags = PFD_DOUBLEBUFFER | PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW; // Enable double buffering, opengl support and drawing to a window
    pfd.iPixelType = PFD_TYPE_RGBA; // Set our application to use RGBA pixels
    pfd.cColorBits = 32; // Give us 32 bits of color information (the higher, the more colors)
    pfd.cDepthBits = 32; // Give us 32 bits of depth information (the higher, the more depth levels)
    pfd.iLayerType = PFD_MAIN_PLANE; // Set the layer of the PFD

    int nPixelFormat = ChoosePixelFormat(hdc, &pfd); // Check if our PFD is valid and get a pixel format back
    if (nPixelFormat == 0) // If it fails
        return false;

    bool bResult = SetPixelFormat(hdc, nPixelFormat, &pfd); // Try and set the pixel format based on our PFD
    if (!bResult) // If it fails
        return false;

    HGLRC tempOpenGLContext = wglCreateContext(hdc); // Create an OpenGL 2.1 context for our device context
    wglMakeCurrent(hdc, tempOpenGLContext); // Make the OpenGL 2.1 context current and active

    //glewExperimental = GL_TRUE;
    GLenum error = glewInit(); // Enable GLEW
    if (error != GLEW_OK) // If GLEW fails
        return false;

    int attributes[] = {
        WGL_CONTEXT_MAJOR_VERSION_ARB, 3, // Set the MAJOR version of OpenGL to 3
        WGL_CONTEXT_MINOR_VERSION_ARB, 3, // Set the MINOR version of OpenGL to 2
        WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB, // Set our OpenGL context to be forward compatible
        0
    };

    if (wglewIsSupported("WGL_ARB_create_context") == 1) { // If the OpenGL 3.x context creation extension is available
        hrc = wglCreateContextAttribsARB(hdc, NULL, attributes); // Create and OpenGL 3.x context based on the given attributes
        wglMakeCurrent(NULL, NULL); // Remove the temporary context from being active
        wglDeleteContext(tempOpenGLContext); // Delete the temporary OpenGL 2.1 context
        wglMakeCurrent(hdc, hrc); // Make our OpenGL 3.0 context current
    }
    else {
        hrc = tempOpenGLContext; // If we didn't have support for OpenGL 3.x and up, use the OpenGL 2.1 context
    }

    int glVersion[2] = {-1, -1}; // Set some default values for the version
    glGetIntegerv(GL_MAJOR_VERSION, &glVersion[0]); // Get back the OpenGL MAJOR version we are using
    glGetIntegerv(GL_MINOR_VERSION, &glVersion[1]); // Get back the OpenGL MINOR version we are using

    std::cout << "Using OpenGL: " << glVersion[0] << "." << glVersion[1] << std::endl; // Output which version of OpenGL we are using On Windows, you won’t get a console for a Win32 Application, but a nifty trick to get console output, is to open up Command Prompt, navigate to your directory with your executable file, and use something like: “program.exe > temp.txt”

    return true; // We have successfully created a context, return true
}

/*
setupScene will contain anything we need to setup before we render
*/
void OpenGLContext::setupScene(void) {
    glClearColor(0.4f, 0.6f, 0.9f, 0.0f); // Set the clear color based on Microsofts CornflowerBlue (default in XNA)
}

/*
reshapeWindow is called every time our window is resized, and it sets our windowWidth and windowHeight
so that we can set our viewport size.
*/
void OpenGLContext::reshapeWindow(int w, int h) {
    windowWidth = w; // Set the window width
    windowHeight = h; // Set the window height
}

/*
renderScene will contain all our rendering code.

The first thing we are going to do is set our viewport size to fill the entire window.

Next up we are going to clear our COLOR, DEPTH and STENCIL buffers to avoid overlapping
of renders.

Any of your other rendering code will go here.

Finally we are going to swap buffers.
*/
void OpenGLContext::renderScene(void) {
    glViewport(0, 0, windowWidth, windowHeight); // Set the viewport size to fill the window
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); // Clear required buffers
    SwapBuffers(hdc); // Swap buffers so we can see our rendering
}

main.cpp

#include "Opengl_3.h"

OpenGLContext openglContext; // Our OpenGL Context class

bool running = true; // Whether or not the application is currently running

HINSTANCE hInstance; // The HINSTANCE of this application
//LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); // Standard window callback


/**
WndProc is a standard method used in Win32 programming for handling Window messages. Here we
handle our window resizing and tell our OpenGLContext the new window size.
*/
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message) {
        case WM_SIZE: // If our window is resizing
            openglContext.reshapeWindow(LOWORD(lParam), HIWORD(lParam)); // Send the new window size to our OpenGLContext
            break;
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
        default:
            return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}


bool createWindow(char *title, int width, int height)
{
    WNDCLASS wc;
    HWND hWnd;

    hInstance = GetModuleHandle(NULL);

    wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
    wc.lpfnWndProc = (WNDPROC) 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 = title;

    if (!RegisterClass(&wc))
        return false;

    DWORD dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
    hWnd = CreateWindowEx(dwExStyle, title, title, WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, 0, width, height, NULL, NULL, hInstance, NULL);

    openglContext.create30Context(hWnd); // Create our OpenGL context on the given window we just created

    ShowWindow(hWnd, SW_SHOW);
    UpdateWindow(hWnd);
    return true;
}


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

    char title[] = "OpenGL 3 Project";

    createWindow(title, 500, 500); // Create our OpenGL window
    openglContext.setupScene(); // Setup our OpenGL scene

    while (running)
    {
        if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
        { // If we have a message to process, process it
            if (msg.message == WM_QUIT)
                running = false; // Set running to false if we have a message to quit
            else
            {
                TranslateMessage(&msg);
                DispatchMessage(&msg);
            }
        }
        else // If we don't have a message to process
            openglContext.renderScene(); // Render our scene (which also handles swapping of buffers)
    }

    return (int) msg.wParam;
}

Recommended Answers

All 10 Replies

//#pragma comment(lib, "glew32.lib")
//#pragma comment(lib, "opengl32.lib")

Why did you uncomment these two lines?
if you uncomment these two lines then you need to mention the library in the command line.
something like -lglew32 -lopengl32 like....

The Visual Studio libraries probably aren't going to work for MinGW (what Dev C++ compiles with).
MinGW = Minimal GNU for Windows.

And Dev C++ is kind of dead anyway.

Get a full MinGW installation (GCC & G++) with at least a minimal MSYS that has Make.
Then get Eclipse or NetBeans as your IDE. (NetBeans, at least for me, has always felt "friendlier.")

Meanwhile, I'm going to see if I can get Glew built for MinGW.

Uh... hm...
It's... um... astonishingly easy. If you've ever used MSYS. Which you probably haven't.

OK, so assume I have a full MinGW and MSYS install.
I download the source file (at https://sourceforge.net/projects/glew/files/glew/1.7.0/glew-1.7.0.tgz/download ) to my C:\Workspace\Source folder.

I open MSYS which takes me to a command-line. I change to the C:\Workspace\Source folder.
cd /c/Workspace/Source
I unzip the tar-ball.
tar -xzf glew-1.7.0.tgz
I change to the glew-1.7.0 folder.
cd glew-1.7.0

I openthe Makefile in Wordpad (formerly called Write).
write Makefile
I scroll down a few pages until I see:
GLEW_DEST ?= /usr
I change it to:
GLEW_DEST ?= /mingw
I save and close Wordpad.

I run the Makefile with the make program. This compiles the binaries.
make

Then, when it finishes,
make install
This copies the binaries and header files where the compiler can use them.

It's ready to rock.

I installed NetBeans, MinGW, MSYS and your glew, but I'm still getting undefined reference errors.

build/Debug/MinGW-Windows/Opengl_3.o: In function `~OpenGLContext':
C:\MyProject/Opengl_3.cpp:21: undefined reference to `wglMakeCurrent@8'
C:\MyProject/Opengl_3.cpp:22: undefined reference to `wglDeleteContext@4'
build/Debug/MinGW-Windows/Opengl_3.o: In function ZN13OpenGLContext15create30ContextEP6HWND__':
C:\MyProject/Opengl_3.cpp:47: undefined reference to `ChoosePixelFormat@8'
(etc)

I changed the beginning of Opengl_3.h to this

#pragma once

#include <windows.h>
#include <iostream>

#include <GL/glew.h>
#include <GL/wglew.h>
#pragma comment(lib, "libglew32.a")
#pragma comment(lib, "libopengl32.a")

OK, the #pragma bit doesn't factor in with MinGW. You've got to tell the linker what you're using.
You'll need to go to Project Properties and Linker settings. I can't remember the exact location so lmgtfy:
http://lmgtfy.com/?q=netbeans+C%2B%2B+linker+libraries
You need to link in glew32, opengl32, and gdi32 - in that order.
Make sure to do that for both Debug and Release.

Make sure that the glew32.dll is somewhere in your system path. (It's in the lib folder, but that probably won't work. I copied mine to the bin folder.) Otherwise, your program will croak prematurely.

Also, I compiled and ran the program. It's blue. That's it. That's the great smurfing mystery. It's Microsmurf Cornflower blue. That's all there is.

Yeah, I figured the pragma thing wasn't doing anything, because it didn't for dev. That's why it was commented out before. I just uncommented them for NetBeans in case they did. I also already had glew32.dll installed.

I had gone through all the menus, and the only thing relevant I could find was tools>options>c++>project options, where I had glew32 and opengl32 added as make options. Turns out that there's a wealth of project options hidden elsewhere, outside the menus, after right clicking on a project root in the expanding project browser on the left, and going down to properties.

I didn't know I needed gdi32 though... I've spent a couple days straight trying to get this to compile and I never found that.

And I knew it was an empty window, hah. I said that in my first post.

I am getting fewer errors now, thank you.

build/Debug/MinGW-Windows/Opengl_3.o: In function `ZN13OpenGLContext15create30ContextEP6HWND__':
C:\MyProject/Opengl_3.cpp:60: undefined reference to `_imp__glewInit'
C:\MyProject/Opengl_3.cpp:70: undefined reference to `_imp__wglewIsSupported'
C:\MyProject/Opengl_3.cpp:71: undefined reference to `_imp____wglewCreateContextAttribsARB'

That's all of them.

Okay.. I switched from libglew32.a to libglew32.dll.a, and... it compiled!! But, I didn't get a window, just an empty console. And when I switch from 'debug' to 'release' it just gives a bunch of errors again.

build/Release/MinGW-Windows/Opengl_3.o:Opengl_3.cpp:(.text+0x2f): undefined reference to `wglMakeCurrent@8'
build/Release/MinGW-Windows/Opengl_3.o:Opengl_3.cpp:(.text+0x3d): undefined reference to `wglDeleteContext@4'
build/Release/MinGW-Windows/Opengl_3.o:Opengl_3.cpp:(.text+0xb2): undefined reference to `ChoosePixelFormat@8'
(etc)

Edit: Nevermind about the debug/release thing, it turns out I added libraries only to the 'debug' version.
Edit again: RegisterClassEx(&wc) is returning false.

Ahah, I shouldn't have changed it to Ex. It works now, my smurf is very happy and he thanks you deeply.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.