OpenGL Link Error

I am trying to write a windows wrapper for opengl and am getting a link error that has been bugging me for quite a while. Below is the code and I would appreciate any feedback. Thanks, community.

WindowsGLWrapper.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
/**
 *  WindowsGLWrapper.h
 *
 *	Defines functions that link Windows and OpenGL together. These
 *	allow the basics of rendering a window, resizing it, destroying
 *	it, and capturing input from the user via Windows Message Passing
 *	featured in wndProc().
 *
 *  Created by Jaise Donovan on 4/13/11.
 *	Property of Noodle Inc.
 */

// INCLUDES
#include <string>				// use of string 
#include <windows.h>			// Windows functions
#include <WindowsX.h>			// more Windows functions

class WindowsGLWrapper 
{
public:
	WindowsGLWrapper(wchar_t* className);
	~WindowsGLWrapper();

	// Windows Functions
	static LRESULT CALLBACK wndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
	
	// OpenGL Functions
	int initGL();
	bool createGLWindow(std::wstring title, int width, int height, int bits, bool fullscreen);
	void resizeGLScene(int width, int height);
	void killGLWindow();
	void setTimer(UINT_PTR newTimer) { m_timer = newTimer; }
	
	// Windows specific fields
	HDC			m_hDC;			// GDI device context
	HGLRC		m_hRC;			// rendering context
	HWND		m_hWnd;			// window handle 
	HINSTANCE	m_hInstance;	// instance of the application
	UINT_PTR	m_timer;		// timer used to establish timeouts and calculate delta T
	
	// Application specific fields
	bool	m_keys[256];		// array used for keyboard gestures (true if keyDown, else false)
	bool	m_active;			// window active, flag set to TRUE by default
	bool	m_fullscreen;		// fullscreen, flag set to FALSE by default
	bool	m_mouseDown;		// flag to indicate the mouse state (true if down, else false)
	int		m_mouseX;			// the mouse x position
	int		m_mouseY;			// the mouse y position
	DWORD	m_timeNow;			// the current system time
	DWORD	m_timeLast;			// the previous system time
	LPCWSTR m_className;		// the name of the class we give to the window
}; // eo WindowsGLWrapper 


test.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52

// INCLUDES
#include "WindowsGLWrapper.h"	// Includes function prototypes
#include <windows.h>			// Windows functions
#include <WindowsX.h>			// more Windows functions
#include <gl\gl.h>				// OpenGL32 library
#include <gl\glu.h>				// GLu32 library

// NAMESPACES
using namespace std;

// CONSTANTS
const int SCREEN_HEIGHT = 600;		// the height of the screen
const int SCREEN_WIDTH	= 800;		// the width of the screen

int WINAPI WinMain(	HINSTANCE	hInstance,			// instance
					HINSTANCE	hPrevInstance,		// previous instance
					LPSTR		lpCmdLine,			// command line parameters
					int			nCmdShow)			// window show state
{
	MSG		msg;									// windows message structure
	BOOL	done=FALSE;								// bool variable to exit loop
	BOOL	fullscreen = FALSE;						// windowed mode

	WindowsGLWrapper* windowsWrapper = new WindowsGLWrapper( (wchar_t*)"Test Window" );

	// create an OpenGL window
	if (!windowsWrapper->createGLWindow(windowsWrapper->m_className, SCREEN_WIDTH, SCREEN_HEIGHT, 32, fullscreen))
	{
		return 0;									// quit if window is not created
	}

	// set up the game application
	windowsWrapper->setTimer( SetTimer(windowsWrapper->m_hWnd, 0, 1000/60 /* 60 FPS */, NULL) );
	BOOL bRet;
	while( (bRet = GetMessage( &msg, NULL, 0, 0 )) != 0)
    { 
        if (bRet == -1)
            break;
        else
        {
            TranslateMessage(&msg); 
            DispatchMessage(&msg); 
        }
    } 

	// Shutdown
	windowsWrapper->killGLWindow();					// Kill The Window

	if(windowsWrapper) delete windowsWrapper; windowsWrapper = NULL;
	return (int)(msg.wParam);						// Exit The Program
}


Any additional suggestions that could enhance this module would be awesome. Thanks again for the help.
WindowsGLWrapper.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
/**
 *  WindowsGLWrapper.h
 *
 *	Defines functions that link Windows and OpenGL together. These
 *	allow the basics of rendering a window, resizing it, destroying
 *	it, and capturing input from the user via Windows Message Passing
 *	featured in wndProc().
 *
 *  Created by Jaise Donovan on 4/13/11.
 *	Property of Noodle Inc.
 */

// INCLUDES
#include "WindowsGLWrapper.h"	// Includes function prototypes
#include <windows.h>			// Windows functions
#include <WindowsX.h>			// more Windows functions
#include <gl\gl.h>				// OpenGL32 library
#include <gl\glu.h>				// GLu32 library

// NAMESPACES
using namespace std;

// DEFINES
#define IDI_ICON  101

/**
 *	WindowsGLWrapper:
 *		Set up all of the fields to their default values.
 */
WindowsGLWrapper::WindowsGLWrapper(wchar_t* className) :
	m_hDC(NULL), m_hRC(NULL), m_hWnd(NULL), m_hInstance(NULL), m_timer(NULL),
	m_active(TRUE), m_fullscreen(FALSE), m_mouseDown(FALSE), 
	m_mouseX(0), m_mouseY(0), m_timeNow(NULL), m_timeLast(NULL), 
	m_className(className)
{
} // eo WindowsGLWrapper

/**
 *	~WindowsGLWrapper:
 *		Nothing to clean up.
 */
WindowsGLWrapper::~WindowsGLWrapper()
{
	// do nothing
} // eo ~WindowsGLWrapper

LRESULT CALLBACK WindowsGLWrapper::wndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	return DefWindowProc(hWnd,uMsg,wParam,lParam);
} // eo wndProc

/**
 *	initGL:
 *		Initializes OpenGL and gets it ready to start rendering.
 */
int WindowsGLWrapper::initGL()
{
	glShadeModel(GL_SMOOTH);				// enable smooth shading
	glClearColor(0.0f, 0.0f, 0.0f, 1.0f);	// set black background
	glClearDepth(1.0f);						// setup to clear entire depth buffer
	glEnable(GL_DEPTH_TEST);				// start GL and enable depth testing
	glDepthFunc(GL_LEQUAL);					// specify how to test the depths
	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // specify linear interpolation behavior (very nice)
	return TRUE;							// init successful
} // initGL

/**
 *	createGLWindow:
 *		Creates a window with the specified parameters.
 *
 *	params:
 *		(string) title - title to appear in the window caption
 *		(int)	 width - the width of the window 
 *		(int)	 height- the height of the window
 *		(int)	 bits  - the number of bits for color depth (8/16/24/32)
 *		(bool)	 fullscreen - fullscreen (true), windowed mode (false)
 */
bool WindowsGLWrapper::createGLWindow(wstring title, int width, int height, int bits, bool fullscreen)
{
	GLuint		pixelFormat;			// holds the results after searching for a match
	WNDCLASS	wc;						// Windows class structure
	DWORD		dwExStyle;				// Windows Extended Style
	DWORD		dwStyle;				// Windows Style
	RECT		WindowRect;				// gets window dimensions (upperLeft to lowerRight)
	WindowRect.left = (long)0;			// set left value to 0
	WindowRect.right = (long) width;	// set the right value to param width
	WindowRect.top = (long) 0;			// set the top value to 0
	WindowRect.bottom = (long) height;	// set the bottom value to param height

	fullscreen = fullscreen;

	
	m_hInstance			= GetModuleHandle(NULL);				// grab an instance of the window
	wc.style			= CS_HREDRAW | CS_VREDRAW | CS_OWNDC;	// redraw on size and own DC of window
	wc.lpfnWndProc		= (WNDPROC) WindowsGLWrapper::wndProc;					// WndProc Handles Messages
	wc.cbClsExtra		= 0;									// no extra window data
	wc.cbWndExtra		= 0;									// no extra window data
	wc.hInstance		= m_hInstance;							// set the instance
	wc.hIcon			= LoadIcon(m_hInstance, MAKEINTRESOURCE(IDI_ICON));			// load default icon
	wc.hCursor			= LoadCursor(NULL, IDC_ARROW);			// load the glPoint cursor
	wc.hbrBackground	= NULL;									// no background for OpenGL
	wc.lpszMenuName		= NULL;									// no menu
	wc.lpszClassName	= m_className;							// set the class name of the window

	// attempt to register the window class
	if (!RegisterClass(&wc))									
	{
		MessageBox(NULL, L"Failed To Register The Window Class.", L"ERROR", MB_OK | MB_ICONEXCLAMATION);
		return FALSE;											
	}

	dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;						// Windows style extended
	dwStyle = WS_OVERLAPPEDWINDOW & ~(WS_THICKFRAME|WS_MAXIMIZEBOX );	// Windows style
	AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle);			// Adjust window to requested size

	// create the window
	if (!(m_hWnd=CreateWindowEx(dwExStyle,							// extended style for the window
								m_className,						// class name
								title.c_str(),						// window title
								dwStyle |							// defined window style
								WS_CLIPSIBLINGS |					// required window style
								WS_CLIPCHILDREN,					// required window style
								400, 100,							// window position
								WindowRect.right-WindowRect.left,	// calculate window width
								WindowRect.bottom-WindowRect.top,	// calculate window height
								NULL,								// no parent window
								NULL,								// no menu
								m_hInstance,						// instance of the window
								NULL)))								// dont pass anything to WM_CREATE
	{
		killGLWindow();								// reset the display
		MessageBox(NULL, L"Window Creation Error.", L"ERROR", MB_OK | MB_ICONEXCLAMATION);
		return FALSE;								// return FALSE
	}

	static	PIXELFORMATDESCRIPTOR pfd=				// pfd - tells Windows how we want things to be
	{
		sizeof(PIXELFORMATDESCRIPTOR),				// size of this pixel format descriptor
		1,											// version number
		PFD_DRAW_TO_WINDOW |						// format must support window
		PFD_SUPPORT_OPENGL |						// format must support OpenGL
		PFD_DOUBLEBUFFER,							// must support double buffering
		PFD_TYPE_RGBA,								// request a RGBA format
		bits,										// select our color depth
		0, 0, 0, 0, 0, 0,							// color bits ignored
		0,											// no alpha buffer
		0,											// shift bit ignored
		0,											// no accumulation buffer
		0, 0, 0, 0,									// accumulation bits ignored
		16,											// 16-bit Z-Buffer (Depth Buffer)  
		0,											// no stencil buffer
		0,											// no auxiliary buffer
		PFD_MAIN_PLANE,								// main drawing layer
		0,											// reserved
		0, 0, 0										// player masks ignored
	};
	
	// did we get a device context?
	if (!(m_hDC=GetDC(m_hWnd)))						
	{
		killGLWindow();								// reset the display
		MessageBox(NULL, L"Can't Create A GL Device Context.", L"ERROR", MB_OK | MB_ICONEXCLAMATION);
		return FALSE;								// return FALSE
	}

	// did windows find a matching pixel format?
	if (!(pixelFormat = ChoosePixelFormat(m_hDC, &pfd)))	
	{
		killGLWindow();								// reset the display
		MessageBox(NULL, L"Can't Find A Suitable PixelFormat.", L"ERROR", MB_OK | MB_ICONEXCLAMATION);
		return FALSE;								// return FALSE
	}

	// are we able to set the pixel format?
	if(!SetPixelFormat(m_hDC, pixelFormat, &pfd))		
	{
		killGLWindow();								// reset the display
		MessageBox(NULL, L"Can't Set The PixelFormat.", L"ERROR", MB_OK | MB_ICONEXCLAMATION);
		return FALSE;								// return FALSE
	}

	// are we able to get a rendering context?
	if (!(m_hRC = wglCreateContext(m_hDC)))				
	{
		killGLWindow();								// reset the display
		MessageBox(NULL, L"Can't Create A GL Rendering Context.", L"ERROR", MB_OK | MB_ICONEXCLAMATION);
		return FALSE;								// return FALSE
	}

	// try to activate the rendering context
	if(!wglMakeCurrent(m_hDC, m_hRC))					
	{
		killGLWindow();								// reset the display
		MessageBox(NULL, L"Can't Activate The GL Rendering Context.", L"ERROR", MB_OK | MB_ICONEXCLAMATION);
		return FALSE;								// return FALSE
	}

	ShowWindow(m_hWnd, SW_SHOW);					// show the window
	SetForegroundWindow(m_hWnd);					// activates the window
	SetFocus(m_hWnd);								// sets keyboard focus to the window
	resizeGLScene(width, height);					// setup the GL screen

	// initialize the new GL window
	if (!initGL())									
	{
		killGLWindow();								// reset the display
		MessageBox(NULL, L"Initialization Failed.", L"ERROR", MB_OK | MB_ICONEXCLAMATION);
		return FALSE;								// return FALSE
	}

	return TRUE;									// success
} // createGLWindow 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
/** 
 *	resizeGLScene:
 *		Resizes the OpenGL window. Resets viewport, 
 *		perspective, and resets the projection and model-view
 *		matrices.
 *
 *	params:
 *		(GLsizei) width - the width of the window
 *		(GLsizei) height - the height of the window
 */
void WindowsGLWrapper::resizeGLScene(int width, int height)
{
	// a check for division by zero, set to 1 otherwise
	if(height == 0)
		height = 1;
	
	// reset the viewport starting with bottom left (0,0)
	// and make it the appropriate size of the screen
	glViewport(0, 0, width, height);
	
	// select the projection matrix and reset it
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	
	/**
	 *	setup the projection matrix:
	 *		1. setup 45 degree angle field of view
	 *		2. aspect ratio = width/height
	 *		3. specifies the distance from user to near clipping plane
	 *		4. specifies the distance from user to far clipping plane
	 */
	gluPerspective(45.0f, (GLfloat)width / (GLfloat)height, 0.1f, 100.0f);
	
	// select the model-view matrix and reset it
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
} // eo resizeGLScene

void WindowsGLWrapper::killGLWindow()
{
	// are we in fullscreen?
	if(m_fullscreen)
	{
		ChangeDisplaySettings(NULL, 0);		// switch back to the desktop
		ShowCursor(TRUE);					// display the mouse cursor
	}

	// do we have a rendering context?
	if(m_hRC)
	{
		// able to release the DC and RC contexts?
		if(!wglMakeCurrent(NULL, NULL))
			MessageBox(NULL, L"Release of DC and RC failed.", L"SHUTDOWN_ERROR", MB_OK | MB_ICONINFORMATION);

		// able to delete the context?
		if(!wglDeleteContext(m_hRC))
			MessageBox(NULL, L"Release of Rendering Context failed.", L"SHUTDOWN_ERROR", MB_OK | MB_ICONINFORMATION);

		m_hRC = NULL;
	}

	// able to release the DC context?
	if(m_hDC && !ReleaseDC(m_hWnd, m_hDC))
	{
		MessageBox(NULL, L"Release Device Context failed.", L"SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);
		m_hDC = NULL;
	}

	// able to destroy the window?
	if(m_hWnd && !DestroyWindow(m_hWnd))
	{
		MessageBox(NULL, L"Could Not Release hWnd.", L"SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);
		m_hWnd = NULL;	
	}

	// able to unregister the class?
	if(!UnregisterClass(m_className, m_hInstance))
	{
		MessageBox(NULL, L"Could Not Unregister Class.", L"SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);
		m_hInstance = NULL;	
	} 
} // eo killGLWindow 
It would REALLY help if you posted the error message.

Are you sure you are linking to opengl32 and gdi32?
Topic archived. No new replies allowed.