I needed a very very simple OpenGL interface for drawing graphics on Win32 windows. My aim was/is to simply put a pixel on a window. If you are able to put a pixel, you can draw anything, isn't it?

For this purpose, I wrote the class below:

GLWindow.h
Code:
#ifndef GLWINDOW_H
#define GLWINDOW_H

#include <Windows.h>
#include <gl/GL.h>

class GLWindow
{
	public:
		GLWindow(HWND hWindowHandle, UINT uiPixelWidth, UINT uiPixelHeight);
		~GLWindow(){};

		// Thrown exception values and their meanings:
		// 1: Failed: GetDC()
		// 2: Failed: ChoosePixelFormat()
		// 3: Failed: SetPixelFormat()
		// 4: Failed: wglCreateContext()
		// 5: Failed: wglMakeCurrent()
		void Initialize() throw(int);

		// Thrown exception values and their meanings:
		// 1: Failed: wglMakeCurrent()
		// 2: Failed: wglDeleteContext()
		void Destroy() throw(int);

		void SetColor(GLubyte ubRed, GLubyte ubGreen, GLubyte ubBlue) const;

		void PutPixel(UINT x, UINT y) const;

		void ClearScreen() const;

		// Thrown exception values and their meanings:
		// 1: Failed: SwapBuffers()
		void SwapBuffers() const throw(int);

	protected:
		double	m_dbWidth;
		double	m_dbHeight;
		HWND	m_hWnd;
		HDC	m_hDC;
		HGLRC	m_hGLRC;
};

#endif

GLWindow.cpp
Code:
#include "GLWindow.h"
#include <gl/GL.h>


GLWindow::GLWindow(HWND hWindowHandle, UINT uiPixelWidth, UINT uiPixelHeight)
{
	m_hWnd = hWindowHandle;
	m_dbWidth = static_cast<double>(uiPixelWidth);
	m_dbHeight = static_cast<double>(uiPixelHeight);
}

void GLWindow::Initialize() throw(int)
{
	m_hDC = GetDC(m_hWnd);
	if (m_hDC == NULL) throw(1);

	PIXELFORMATDESCRIPTOR Pfd;
	ZeroMemory(&Pfd, sizeof(Pfd));
	Pfd.nSize = sizeof(Pfd);
	Pfd.nVersion = 1;
	Pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
	Pfd.iPixelType = PFD_TYPE_RGBA;
	Pfd.cColorBits = 24;
	Pfd.cDepthBits = 16;
	Pfd.iLayerType = PFD_MAIN_PLANE;

	int iFormat = ChoosePixelFormat(m_hDC, &Pfd);
	if (iFormat == 0) throw(2);

	if (SetPixelFormat(m_hDC, iFormat, &Pfd) == FALSE) throw(3);

	m_hGLRC = wglCreateContext(m_hDC);
	if (m_hGLRC == NULL) throw(4);

	if (wglMakeCurrent(m_hDC, m_hGLRC) == FALSE) throw(5);

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

	glEnable(GL_DEPTH_TEST);
	glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glLoadIdentity();
	glPushMatrix();
		glLoadIdentity();
		glScaled(2.0 / m_dbWidth, 2.0 / m_dbHeight, 1.0);
		glTranslated(-m_dbWidth / 2.0, -m_dbHeight / 2.0, 0.0);
		glBegin(GL_POINTS);
}

void GLWindow::Destroy() throw(int)
{
		glEnd();
	glPopMatrix();
	glFlush();

	if (wglMakeCurrent(m_hDC, NULL) == FALSE) throw(1);
	if (wglDeleteContext(m_hGLRC) == FALSE) throw(2);
}

void GLWindow::SetColor(GLubyte ubRed, GLubyte ubGreen, GLubyte ubBlue) const
{
	glColor3ub(ubRed, ubGreen, ubBlue);
}

void GLWindow::PutPixel(UINT x, UINT y) const
{
	glVertex3i(static_cast<GLint>(x), static_cast<GLint>(y), 0);
}

void GLWindow::ClearScreen() const
{
	glEnd();
	glClearColor(0.0f, 0.0f, 0.0f, 1.0f );
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glBegin(GL_POINTS);
}

void GLWindow::SwapBuffers() const throw(int)
{
	glEnd();
	if (::SwapBuffers(m_hDC) == FALSE) throw(1);
	glBegin(GL_POINTS);
}

Yes, this class is only for printing a custom colored pixel on a window, and it does nothing else. I know how vast the capabilities of OpenGL is, but my requirement was as simple as this.

The below is my code that uses this class:

main.cpp
Code:
#include <Windows.h>
#include <string>
#include <gl/GL.h>
#include <math.h>
#include "GLWindow.h"

HWND g_hWnd;
const UINT WIN_WIDTH = 600;
const UINT WIN_HEIGHT = 400;

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
	std::string ClassName("MyWindowClass");
	WNDCLASSEX wcx;
	wcx.cbSize		= sizeof(wcx);
	wcx.style		= 0;
	wcx.lpfnWndProc		= DefWindowProc;
	wcx.cbClsExtra		= 0;
	wcx.cbWndExtra		= 0;
	wcx.hInstance		= hInstance;
	wcx.hIcon		= NULL;
	wcx.hCursor		= LoadCursor(NULL, IDC_ARROW);
	wcx.hbrBackground	= (HBRUSH) 2;
	wcx.lpszMenuName	= NULL;
	wcx.lpszClassName	= ClassName.c_str();
	wcx.hIconSm		= NULL;

	ATOM Atom = RegisterClassEx(&wcx);
	
	std::string WindowName("GLWindow Test");
	g_hWnd = CreateWindowEx(0,
		ClassName.c_str(),
		WindowName.c_str(),
		WS_OVERLAPPED | WS_VISIBLE | WS_TILEDWINDOW,
		1300, 650,
		WIN_WIDTH, WIN_HEIGHT,
		HWND_DESKTOP,
		(HMENU) NULL,
		hInstance,
		(LPVOID) NULL);


	GLWindow glWnd(g_hWnd, WIN_WIDTH, WIN_HEIGHT);
	glWnd.Initialize();

	///////////////////////////////////////////////////////////////////////
	///////////////////////////////////////////////////////////////////////
	//////////////// MY CODE STARTS HERE //////////////////////////////////

	// Draw a diagonal line
	for (UINT x=0, y; x<WIN_WIDTH; x++)
	{
		glWnd.SetColor(255,	(GLbyte) (255.0 * x / (double) WIN_WIDTH),
					(GLbyte) (255.0 * x / (double) WIN_WIDTH));
		y = ((double) WIN_HEIGHT / WIN_WIDTH) * x;
		glWnd.PutPixel(x, y);
	}
	
	// Display it on the screen
	glWnd.SwapBuffers();

	// Draw a quarter of a circle
	UINT x, y;
	for (double teta=0.0; teta<1.5708 /* PI/2 */; teta+=0.001)
	{
		x = WIN_HEIGHT * cos(teta);
		y = WIN_HEIGHT * sin(teta);
		glWnd.SetColor(	(GLbyte) (150.0 * teta),
				(GLbyte) (256.0 - 150.0 * teta),
				128.0);
		glWnd.PutPixel(x, y);
	}

	// Switch between line and circle several times
	for (UINT i=0; i<10; i++)
	{
		glWnd.SwapBuffers();
		Sleep(1000);
	}
	
	// Close OpenGL engine
	glWnd.Destroy();

	// Quit the program
	PostQuitMessage(0);

	/////////////// MY CODE ENDS HERE /////////////////////////////////////
	///////////////////////////////////////////////////////////////////////
	///////////////////////////////////////////////////////////////////////

	MSG Msg;
	const UINT wMsgFilterMin = 0;
	const UINT wMsgFilterMax = 0;
	while (GetMessage(&Msg, (HWND) NULL, wMsgFilterMin, wMsgFilterMax) > 0)
	{
		TranslateMessage(&Msg);
		DispatchMessage(&Msg);
	}

	return 0;
}
My code above (which is in the main.cpp file) works very fine. Try it yourself if you have time.

Now, I want two things from you guys.
  1. Criticize my code. Do you see any flaw? Would it work in all cases (except for the problem I stated in (2))?
  2. I feel that this code won't work when I use two objects of this class under the same process. And I feel that every GLWindow object must check if they are the "current", if not, they must make themselves the "current" by somehow using the function wglMakeCurrent(). But I don't know how to do it, because I don't know much about OpenGL at all. How do I do it?