program doesn't exit

Started by
5 comments, last by Cornstalks 10 years, 5 months ago

i have a program in visual studio but it doesn't quit after i pres x i have to manually stop the debugging, also some feedback on my coding style would be great.


#include "main.h"

createGLContext GLContext;

int WINAPI winMain(HINSTANCE hInstance,
	HINSTANCE hPrevInstance,
	LPSTR    lpCmdLine,
	int       nCmdShow)
{

	MSG msg;
	bool mainLoopRunning;
	LARGE_INTEGER prevTime, curTime;
	float deltaTime, fixedTimeStep = 0.0;

	QueryPerformanceFrequency(&curTime);
	const float pcFreq = curTime.QuadPart / 1000.0;

	/*###############################################
		load everything and create render context
	###############################################*/
	if (!createWindow("engiene", 1280, 720, &hInstance))
	{
		OutputDebugString("Couldn't create window.");
		return 0;
	}
	GLContext.setupScene();

	/*###############
		main loop
	###############*/
	mainLoopRunning = true;
	while (mainLoopRunning)
	{
		#pragma  region calculate deltaTime
		prevTime = curTime;
		QueryPerformanceCounter(&curTime);
		deltaTime = ((float)(curTime.QuadPart - prevTime.QuadPart) / pcFreq);
		#ifdef DEBUG
		if (deltaTime > 500)//if i break the code during debugging for a long time
			deltaTime = 500;
		#endif
		#pragma  endregion

		/*######################
			process messages
		######################*/
		if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { // If we have a message to process, process it
			if (msg.message == WM_QUIT) {
				mainLoopRunning = 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
			/*##################
				update world
			##################*/
			GLContext.tempRender();
		}
		#pragma  region Print_fps
		fixedTimeStep += deltaTime;
		while (fixedTimeStep > 500.0)
		{
			char str[12];
			sprintf_s(str, "%.2f FPS\n", 1000.0 / deltaTime);
			OutputDebugString(str);
			fixedTimeStep -= 500.0;
		}
		#pragma  endregion
		
		Sleep(16);//TODO make an actual game so i can remove this
	}
	return (int)msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	/*###########################
		windows event handler
	###########################*/
	switch (message)
	{
		case WM_SIZE: // If our window is resizing
		{
			GLContext.reshapeWindow(LOWORD(lParam), HIWORD(lParam));
			break;
		}
		case WM_DESTROY:
		{
			PostQuitMessage(0);
			break;
		}
	}

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

bool createWindow(const LPCSTR title, const int width, const int height, HINSTANCE *hInstance) {
	/*#########################################
		creates a window and openGL context
	#########################################*/
	WNDCLASS windowClass;
	HWND hWnd;
	DWORD dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;

	*hInstance = GetModuleHandle(NULL);

	windowClass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
	windowClass.lpfnWndProc = (WNDPROC)WndProc;
	windowClass.cbClsExtra = 0;
	windowClass.cbWndExtra = 0;
	windowClass.hInstance = *hInstance;
	windowClass.hIcon = LoadIcon(NULL, IDI_WINLOGO);
	windowClass.hCursor = LoadCursor(NULL, IDC_ARROW);
	windowClass.hbrBackground = NULL;
	windowClass.lpszMenuName = NULL;
	windowClass.lpszClassName = title;

	if (!RegisterClass(&windowClass)) {
		return false;
	}

	hWnd = CreateWindowEx(dwExStyle, title, title, WS_OVERLAPPEDWINDOW,
		CW_USEDEFAULT, 0, width, height, NULL, NULL, *hInstance, NULL);

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

	ShowWindow(hWnd, SW_SHOW);
	UpdateWindow(hWnd);

	return true;
}

#include "createGLContext.h"


createGLContext::createGLContext()
{

}

bool createGLContext::createContext(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

	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 {
		return false;
	}
	#pragma region print openGL version
	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 MAJOR version we are using
	char str[65];
	sprintf_s(str, "Using openGL version %d.%d\n", glVersion[0], glVersion[1]);
	OutputDebugString(str);
	#pragma endregion 

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

/*########################################################################
	setupScene will contain anything we need to setup before we render
########################################################################*/
void createGLContext::setupScene(void) {
	glClearColor(0.4f, 0.6f, 0.9f, 0.0f);
}

void createGLContext::reshapeWindow(const int w, const int h)
{
	glViewport(0, 0, w, h); // Set the viewport size to fill the window
}

void createGLContext::tempRender()
{
	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
}

createGLContext::~createGLContext()
{
	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
}

Advertisement

Did you try returning 0 from your window procedure when you process WM_DESTROY?

Did you try returning 0 from your window procedure when you process WM_DESTROY?

no that won't matter because when i debug it the winMain function returns but there are still some threads running so the app won't shut down.

Just a wild guess here, I've never used C++, but I see you're starting OpenGL and not disposing of it.
Perhaps you are in some background C++ Method, hell if I know, anyway that's just my suggestion as a Java developer.

Just a wild guess here, I've never used C++, but I see you're starting OpenGL and not disposing of it.
Perhaps you are in some background C++ Method, hell if I know, anyway that's just my suggestion as a Java developer.

createGLContext has a ~createGLContext() wich should release all the openGL stuff i created when createGLContext GLContextl loses scope. for good measure i tried calling the destructer manually but still no luck, but i appreciate your time

In the debugger, what's the name of the thread that doesn't close?

Did you try returning 0 from your window procedure when you process WM_DESTROY?

no that won't matter because when i debug it the winMain function returns but there are still some threads running so the app won't shut down.

Ummm... it does matter: "If an application processes this message, it should return zero." You should be returning zero for WM_SIZE too if you handle it yourself.

Why not just run the program in your debugger, close the window, and when it's just hanging there, pause the debugger to see where you are?

[size=2][ I was ninja'd 71 times before I stopped counting a long time ago ] [ f.k.a. MikeTacular ] [ My Blog ] [ SWFer: Gaplessly looped MP3s in your Flash games ]

This topic is closed to new replies.

Advertisement