🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

Lesson 01: Can't get DC

Started by
0 comments, last by BrknPhoenix 17 years, 7 months ago
Alright, firstly I run compile the NeHe Lesson 01 as-is just fine. The difference between the code I'm having a problem with and the NeHe code is primarily that I put my version into a class. Other than that it's pretty much the same thing. I stepped through my code and it fails getting a DC and quits. So my question: Why does the way I did it not work! I can't say for sure what the problem is so I'm just including everything, but my guess is that the problem lies in the fact that I used classes at all and something just isn't in a place where it is supposed to be... The basic rundown of what's going on: 1. The OpenGLWindow class is most of NeHe's openGL window creation code. The functions have slightly different names but they're pretty similar. 2. The OpenGLWindow class is instantiated with global scope with a pointer to the OpenGLWindow object. 3. The object's Create function is called from WinMain, and it makes it up to trying to get a DC, and fails to get it. OpenGLWindow.h (sorry for the formatting on this one, it appears source tags don't like my style of tabbing)

#ifndef __OpenGLWindow__
#define __OpenGLWindow__

#include <windows.h>
#include <gl\gl.h>
#include <gl\glu.h>

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

class OpenGLWindow
{
private:
	HGLRC	    rendering_context;
	HDC		    device_context;
	HWND	    window_handle;
	HINSTANCE   application_instance;

	bool		keys[256];
	bool		active;
	bool		fullscreen;
public:
	            OpenGLWindow();
	            ~OpenGLWindow();

	void		Resize(GLsizei, GLsizei);
	void		InitializeOpenGL();
	void		Close();
	void		Draw();
	bool		Create(char*, int, int, int, bool);

    HGLRC		GetRenderingContext()				 { return rendering_context;    }
    HDC		    GetDeviceContext()					 { return device_context;       }
    HWND		GetWindowHandle()					 { return window_handle;        }
    HINSTANCE   GetApplicationInstance()			 { return application_instance; }

    void		SetRenderingContext(HGLRC rc)		 { rendering_context = rc;      }
    void		SetDeviceContext(HDC dc)			 { device_context = dc;         }
    void		SetWindowHandle(HWND wh)	         { window_handle = wh;          }
    void	    SetApplicationInstance(HINSTANCE ai) { application_instance = ai;   }

	bool		KeyDown(unsigned char vk)			 { return keys[vk];				}
	void		SetKeyDown(WPARAM vk)	    	     { keys[vk] = true;				}
	void		SetKeyUp(WPARAM vk)		    	     { keys[vk] = false;			}	

	bool		GetActive()							 { return active;				}
	bool		GetFullscreen()						 { return fullscreen;		    }

	void		SetActive(bool a)					 { active = a;					}
	void		SetFullscreen(bool f)				 { fullscreen = f;				}
};

extern OpenGLWindow* MainWindow;

#endif // __OpenGLWindow__





OpenGLWindow.cpp

#include "OpenGLWindow.h"

OpenGLWindow* MainWindow = new OpenGLWindow;

OpenGLWindow::OpenGLWindow()
{
	active     = true;
	fullscreen = true;
}

OpenGLWindow::~OpenGLWindow()
{
}

void OpenGLWindow::Resize(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();
}

void OpenGLWindow::InitializeOpenGL()
{
	glShadeModel(GL_SMOOTH);
	glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
	glClearDepth(1.0f);
	glEnable(GL_DEPTH_TEST);
	glDepthFunc(GL_LEQUAL);
	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
}

void OpenGLWindow::Close()
{
	if (fullscreen)
	{
		ChangeDisplaySettings(NULL, 0);
		ShowCursor(TRUE);
	}

	if (rendering_context)
	{
		if (!wglMakeCurrent(NULL, NULL))
		{
			 // Release of DC and RC failed
		}

		if (!wglDeleteContext(rendering_context))
		{
			// Release of RC failed			
		}

		rendering_context = NULL;
	}

	if (device_context && !ReleaseDC(window_handle, device_context))
	{
		// Release DC failed

		device_context = NULL;
	}

	if (window_handle && !DestroyWindow(window_handle))
	{
		// Release hWnd failed

		window_handle = NULL;
	}

	if (!UnregisterClass((LPCTSTR)"OpenGL", application_instance))
	{
		// Could not unregister class

		application_instance = NULL;
	}
}

void OpenGLWindow::Draw()
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glLoadIdentity();
}

bool OpenGLWindow::Create(char* title, int width, int height, int bits, bool fullscreen_flag)
{
	GLuint   pixel_format;
	WNDCLASS window_class;
	DWORD    dwExStyle;
	DWORD    dwStyle;
	RECT     window_rect;

	window_rect.left   = (long)0;
	window_rect.right  = (long)width;
	window_rect.top    = (long)0;
	window_rect.bottom = (long)height;

	fullscreen = fullscreen_flag;

	application_instance	   = GetModuleHandle(NULL);
	window_class.style		   = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
	window_class.lpfnWndProc   = (WNDPROC)WindowProcedure;
	window_class.cbClsExtra    = 0;
	window_class.cbWndExtra    = 0;
	window_class.hInstance     = application_instance;
	window_class.hIcon	       = LoadIcon(NULL, IDI_APPLICATION);
	window_class.hCursor	   = LoadCursor(NULL, IDC_ARROW);
	window_class.hbrBackground = NULL;
	window_class.lpszMenuName  = NULL;
	window_class.lpszClassName = "brknogl";

	if (!RegisterClass(&window_class))
	{
		// Couldn't register the window class

		return false;
	}

	if (fullscreen)
	{
		DEVMODE screen_settings;
		memset(&screen_settings, 0, sizeof(screen_settings));

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

		if (ChangeDisplaySettings(&screen_settings, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)
		{
			// Fullscreen mode failed

			fullscreen = false;
		}
	}

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

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

	CreateWindowEx( dwExStyle,
					"brknogl",
					title,
					WS_CLIPSIBLINGS |
					WS_CLIPCHILDREN |
					dwStyle,
					0, 0,
					window_rect.right - window_rect.left,
					window_rect.bottom - window_rect.top,
					NULL,
					NULL, 
					application_instance,
					NULL
				  );

	if (!window_handle)
	{
		// Couldn't create the window

		Close();
		return false;
	}

	static PIXELFORMATDESCRIPTOR pixel_format_descriptor =
	{
		sizeof(PIXELFORMATDESCRIPTOR),					
		1,							
		PFD_DRAW_TO_WINDOW |		
		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						
	};

	device_context = GetDC(window_handle);

	if (!device_context)
	{
		// Couldn't get DC

		Close();
		return false;
	}

	pixel_format = ChoosePixelFormat(device_context, &pixel_format_descriptor);

	if (!pixel_format)
	{
		// Couldn't find matching pixel format

		Close();
		return false;
	}

	if (!SetPixelFormat(device_context, pixel_format, &pixel_format_descriptor))
	{
		// Couldn't set pixel format

		Close();
		return false;
	}

	rendering_context = wglCreateContext(device_context);

	if (!rendering_context)
	{
		// Couldn't get RC

		Close();
		return false;
	}

	if (!wglMakeCurrent(device_context, rendering_context))
	{
		// Couldn't activate rendering context

		Close();
	}

	ShowWindow(window_handle, SW_SHOW);
	SetForegroundWindow(window_handle);
	SetFocus(window_handle);
	Resize(width, height);

	InitializeOpenGL();

	return true;
}

LRESULT CALLBACK WindowProcedure(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	switch (message)
	{
		case WM_ACTIVATE:
		{
			if (!HIWORD(wParam))
			{
				MainWindow->SetActive(true);
			}
			else
			{
				MainWindow->SetActive(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:
		{
			MainWindow->SetKeyDown(wParam);
			return 0;
		}
		case WM_KEYUP:
		{
			MainWindow->SetKeyUp(wParam);
			return 0;
		}
		case WM_SIZE:
		{
			MainWindow->Resize(LOWORD(lParam), HIWORD(lParam));
			return 0;
		}
	}

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





WinMain.cpp

#include "OpenGLWindow.h"

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
	MSG  message;
	bool quit = false;

#ifdef FULLSCREEN
	MainWindow->SetFullscreen(true);
#else
	MainWindow->SetFullscreen(false);
#endif

	MainWindow->Create("OpenGL Window", 640, 480, 16, MainWindow->GetFullscreen());

	while (!quit)
	{
		if (PeekMessage(&message, NULL, 0, 0, PM_REMOVE))
		{
			if (message.message == WM_QUIT)
			{
				quit = true;
			}
			else
			{
				TranslateMessage(&message);
				DispatchMessage(&message);
			}
		}
		else
		{
			if (MainWindow->GetActive())
			{
				if (MainWindow->KeyDown(VK_ESCAPE))
				{
					quit = true;
				}
				else
				{
					MainWindow->Draw();
					SwapBuffers(MainWindow->GetDeviceContext());
				}
			}

			if (MainWindow->KeyDown(VK_F1))
			{
				MainWindow->SetKeyUp(VK_F1);
				MainWindow->Close();
				MainWindow->SetFullscreen(!MainWindow->GetFullscreen());
				MainWindow->Create("OpenGL Window", 640, 480, 16, MainWindow->GetFullscreen());
			}
		}
	}

	MainWindow->Close();
	return (int)(message.wParam);
}





Advertisement
Haha, co-worker just solved my problem. It's quite silly. CreateWindowEx is called but the return value isn't placed into window handle, and the if (!window_handle) check passes because window_handle isn't initialized to NULL. :)

This topic is closed to new replies.

Advertisement