Skip to main content
GameDev.net gamedev.net
🔒 Locked

local function definition error !?

Started by GarlandIX Jan 5, 2003 at 12:21 PM 1 replies 3.8k views
Original Post
GarlandIX
GarlandIX
I am getting some weird errors from MSVC++ . Here is my code:
  
// OGLApp.cpp: implementation of the COGLApp class.

//

//////////////////////////////////////////////////////////////////////


#include "OGLApp.h"

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////


COGLApp::COGLApp()
{
	m_active = true;
	m_app_quit = false;
	m_appTitle = "OpenGL Application";
	m_bFullscreen = false;
	m_FPS = 0;
	m_Frequency = 0;
	m_hDC = NULL;
	m_hRC = NULL;
	m_hWnd = NULL;
}

COGLApp::~COGLApp()
{

}

bool COGLApp::InitGL()
{
	glShadeModel(GL_SMOOTH);
	glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
	glClearDepth(1.0f);
	glEnable(GL_DEPTH_TEST);
	glDepthFunc(GL_LEQUAL);
	glEnable(GL_CULL_FACE);
	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
	return true;
}

bool COGLApp::DrawScene()
{
	return true;
}

void COGLApp::UpdateFPSCounter()
{
	static int frameCount = 0;
	static __int64 NewCount = 0;
	static __int64 LastCount = 0;

	frameCount++;
	QueryPerformanceCounter((LARGE_INTEGER*)&NewCount);
	if (NewCount-LastCount >= m_Frequency)
	{
		m_FPS = frameCount;
		frameCount = 0;
		LastCount = NewCount;
	}
}

bool COGLApp::CleanupGL()
{
	if (m_bFullscreen)
	{
		ChangeDisplaySettings(NULL, 0);
	}
	if (m_hRC)
	{
		wglMakeCurrent(NULL, NULL);
		wglDeleteContext(m_hRC);
		m_hRC = NULL;
	}
	if (m_hDC) ReleaseDC(m_hWnd, m_hDC);
	return true;
}

LRESULT CALLBACK COGLApp::GLWinProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	switch (msg)
	{
	case WM_ACTIVATE:
		{
			if (!HIWORD(wParam))
			{
				m_active = true;
			}
			else
			{
				m_active = false;
			}

			return 0;
		}break;
	case WM_SYSCOMMAND:
		{
			switch(wParam)
			{
			case SC_SCREENSAVE:
			case SC_MONITORPOWER:
				return 0;
			}
		}break;
	case WM_KEYDOWN:
		{
			m_keys[wParam] = true;
			return 0;
		}break;
	case WM_KEYUP:
		{
			m_keys[wParam] = false;
			return 0;
		}break;
	case WM_SIZE:
		{
			ResizeGLScene(LOWORD(lParam), HIWORD(lParam));
			return 0;
		}break;
	case WM_DESTROY:
		{
			PostQuitMessage(0);
			return 0;
		}break;
	default:break;
	}
	return DefWindowProc(hWnd, msg, wParam, lParam);
}

int COGLApp::Run()
{
	MSG msg;
	while (!m_app_quit)
	{
		if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
		{
			if (msg.message == WM_QUIT)
			{
				m_app_quit = true;
				break;
			}
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
		else
		{
			if (m_active)
			{
				if (m_keys[VK_ESCAPE]) m_app_quit = true;
				if (m_app_quit) continue;
				DrawScene();
				UpdateFPSCounter();

		}
	}

	CleanupGL();
	return msg.wParam;
}

bool COGLApp::Create(HINSTANCE hInstance, int nShowCmd, int width, int height, int bpp)
{
	WNDCLASSEX wc;
	bool r;
	int ans = 0;

	wc.cbSize = sizeof(WNDCLASSEX);
	wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
	wc.lpfnWndProc = GLWinProc;
	wc.cbClsExtra = 0;
	wc.cbWndExtra = 0;
	wc.hInstance = hInstance;
	wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
	wc.hCursor = LoadCursor(NULL, IDC_ARROW);
	wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
	wc.lpszMenuName = NULL;
	wc.lpszClassName = WNDCLASSNAME;
	wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
	RegisterClassEx(&wc);

	ans = MessageBox(NULL, "Do you want to run in fullscreen mode?", "Fullscreen or Windowed?", MB_YESNO | MB_ICONQUESTION);
	if (ans == IDYES) bFullscreen = true;
	else bFullscreen = false;

	if (bFullscreen)
	{
		m_hWnd = CreateWindowEx(0, WNDCLASSNAME, WINDOW_TITLE, WS_POPUP|WS_CLIPSIBLINGS|WS_CLIPCHILDREN,
							  0, 0, width, height, NULL, NULL, hInstance, NULL);
	}
	else
	{
		m_hWnd = CreateWindowEx(0, WNDCLASSNAME, WINDOW_TITLE, WS_OVERLAPPED|WS_CLIPSIBLINGS|WS_CLIPCHILDREN,
							  0, 0, width, height, NULL, NULL, hInstance, NULL);
	}
	ShowWindow(m_hWnd, nShowCmd);
	UpdateWindow(m_hWnd);
	SetFocus(m_hWnd);

	QueryPerformanceFrequency((LARGE_INTEGER*)&m_Frequency); // initialize FPS counter


	r = SetDisplayMode(m_hWnd, width, height, bpp);
	if (!r)
	{
		MessageBox(NULL, "SetDisplayMode() Failed. Application will now close.", "Error!", MB_OK | MB_ICONERROR);
		return false;
	}
	r = InitGL();
	if (!r)
	{
		MessageBox(NULL, "InitGL() Failed. Application will now close.", "Error!", MB_OK | MB_ICONERROR);
		return false;
	}
	return true;
}

GLvoid COGLApp::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, 1.0f, 1000.0f);

	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
}

bool COGLApp::SetDisplayMode(HWND hwnd, int width, int height, int bpp)
{
	DEVMODE dm;
	int pixelformat;
	static PIXELFORMATDESCRIPTOR pfd =
	{
		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 An RGBA Format

		bpp,							// 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,								// 16Bit Z-Buffer (Depth Buffer)

		0,								// No Stencil Buffer

		0,								// No Auxiliary Buffer

		PFD_MAIN_PLANE,					// Main Drawing Layer

		0,								// Reserved

		0, 0, 0							// Layer Masks Ignored

	};
	int r;

	if (bFullscreen)
	{
		EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dm);
		dm.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;
		dm.dmPelsWidth = width;
		dm.dmPelsHeight = height;
		dm.dmBitsPerPel = bpp;
		r = ChangeDisplaySettings(&dm, CDS_FULLSCREEN);
		if (r != DISP_CHANGE_SUCCESSFUL)
		{
			MessageBox(NULL, "Could not change display settings!", "Error!", MB_OK | MB_ICONERROR);
			return false;
		}
	}

	m_hDC = GetDC(hWnd);
	if (!(pixelformat = ChoosePixelFormat(m_hDC,&pfd)))			
	{
		MessageBox(NULL, "Can''t Find A Suitable PixelFormat.", "Error!" , MB_OK|MB_ICONERROR);
		return false;
	}
	if (!SetPixelFormat(m_hDC,pixelformat,&pfd))
	{
		MessageBox(NULL, "Can''t Set The PixelFormat.", "Error!", MB_OK|MB_ICONERROR);
		return false;
	}

	if (!(m_hRC = wglCreateContext(m_hDC)))
	{
		MessageBox(NULL, "Couldn''t Create and OpenGL Rendering Context!", "Error!", MB_OK | MB_ICONERROR);
		return false;
	}
	wglMakeCurrent(m_hDC, m_hRC);
	ResizeGLScene(width, height);

	return true;
}

void COGLApp::InitScene()
{

}

void COGLApp::CleanupScene()
{

}
  
And here are the errors I am getting: c:\documents and settings\owner\desktop\openglapp\oglapp.cpp(161) : error C2601: ''Create'' : local function definitions are illegal c:\documents and settings\owner\desktop\openglapp\oglapp.cpp(216) : error C2601: ''ResizeGLScene'' : local function definitions are illegal c:\documents and settings\owner\desktop\openglapp\oglapp.cpp(230) : error C2601: ''SetDisplayMode'' : local function definitions are illegal c:\documents and settings\owner\desktop\openglapp\oglapp.cpp(295) : error C2601: ''InitScene'' : local function definitions are illegal c:\documents and settings\owner\desktop\openglapp\oglapp.cpp(300) : error C2601: ''CleanupScene'' : local function definitions are illegal c:\documents and settings\owner\desktop\openglapp\oglapp.cpp(303) : error C1004: unexpected end of file found So my question is: What is a local function definition and why is it illegal? As far as I can tell there is nothing wrong with my code. The only thing that may be causing errors is the fact that all those functions are virtual, but I have no idea why that would screw up or how to fix it. ------------------------------ BASIC programmers don''t die, they just GOSUB and don''t return.
------------------------------BASIC programmers don't die, they just GOSUB and don't return.
SabreMan
SabreMan
quote:
Original post by GarlandIX
So my question is: What is a local function definition and why is it illegal?

A local function definition is a function defined within the scope of another function. C and C++ only allow functions to be defined at the top-level, due to the complexity of implementing a the ability to create local functions. In languages which do allow you to do this, you have the ability to create what is called a "lexical closure", which means the function definition "closes over" it''s local lexical environment. To do that pretty much implies garbage collection is required. Therefore, C and C++ rule out local functions.

Imagine this hypothetical code:

func make_adder(int x)
{
int g(int num)
{
return num+x;
}

return g();
}

Pretend that the type "func" is "a function object", and that make_adder defines a local function called g, and returns that as a function object to the caller. When something calls make_adder, g has to bind the lexical environment, which in this case means it has to capture the value of x at the point g() is defined. Imagine two calls to make_adder, like this:

func f1 = make_adder(10);
func f2 = make_adder(20);

Each one of those would close over a different value of x. That means that each instance of x has to persist beyond return from make_adder - it has to last as long as f1 and f2 require those values. So, how does the compiler know when the two values of x can be discarded? It needs to determine nothing is referencing those values. As I say, that implies GC.

In C++, you have to use a class to simulate closures. I guess you could write up such a hackaround and call it a "Design Pattern", if that''s your thing.
quote:

As far as I can tell there is nothing wrong with my code.

I suspect you haven''t closed a brace somewhere.
quote:

The only thing that may be causing errors is the fact that all those functions are virtual

I doubt it, but here''s a question. Why are they all virtual? I suspect you''re over-using virtual.
ToohrVyk
ToohrVyk
Yep, brace missing...

[script]

int COGLApp::Run() {
MSG msg;
while (!m_app_quit) {
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { if (msg.message == WM_QUIT) { m_app_quit = true;
break;
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else {
if (m_active) {
if(m_keys[VK_ESCAPE])
m_app_quit = true;
if (m_app_quit)
continue;
DrawScene();
UpdateFPSCounter();
//Missing bracket for (m_active) here..
}
}
CleanupGL();
return msg.wParam;
}
[/script]

ToohrVyk
-------------
Extatica - a free 3d game engine
Available soon!
Click here to learn more

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.