Click here to Skip to main content
15,884,177 members
Articles / Desktop Programming / WTL

A WTL class for developping OpenGL programs using WTL

Rate me:
Please Sign up or sign in to vote.
4.85/5 (10 votes)
1 Oct 20012 min read 102.8K   3.3K   32  
A class to develop OpenGL programs which can be easily plugged into your WTL programs
// MainFrm.h : interface of the CMainFrame class
//
// partial codes generated by OpenGL AppWizard developed by Ulf Ohlen (ulf_ohlen@hotmail.com) 
// see http://www.codeproject.com/opengl/oglwiz.asp for details
//
//
/////////////////////////////////////////////////////////////////////////////

#if !defined(AFX_MAINFRM_H__0879C256_36E6_4CB6_B5E0_0BB8527B0AC4__INCLUDED_)
#define AFX_MAINFRM_H__0879C256_36E6_4CB6_B5E0_0BB8527B0AC4__INCLUDED_

#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000

#include <stdio.h>

class CMainFrame : public CFrameWindowImpl<CMainFrame>, COpenGL<CMainFrame>, public CUpdateUI<CMainFrame>,
		public CMessageFilter, public CIdleHandler
{
public:
	DECLARE_FRAME_WND_CLASS(NULL, IDR_MAINFRAME)

	GLfloat m_fAngle;		// Rotation angle of the cube

	virtual BOOL PreTranslateMessage(MSG* pMsg)
	{
		return CFrameWindowImpl<CMainFrame>::PreTranslateMessage(pMsg);
	}

	virtual BOOL OnIdle()
	{
		m_fAngle+= 1; // Add some rotation to the cube
		UpdateFPS();
		RedrawWindow();
		return FALSE;
	}

	BEGIN_MSG_MAP(CMainFrame)
		MESSAGE_HANDLER(WM_CREATE, OnCreate)
		COMMAND_ID_HANDLER(ID_APP_EXIT, OnFileExit)
		COMMAND_ID_HANDLER(ID_FILE_NEW, OnFileNew)
		COMMAND_ID_HANDLER(ID_APP_ABOUT, OnAppAbout)
		CHAIN_MSG_MAP(CUpdateUI<CMainFrame>)
		CHAIN_MSG_MAP(CFrameWindowImpl<CMainFrame>)
		CHAIN_MSG_MAP(COpenGL<CMainFrame>)
	END_MSG_MAP()

	BEGIN_UPDATE_UI_MAP(CMainFrame)
	END_UPDATE_UI_MAP()

	LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
	{
		// register object for message filtering and idle updates
		CMessageLoop* pLoop = _Module.GetMessageLoop();
		ATLASSERT(pLoop != NULL);
		pLoop->AddMessageFilter(this);
		pLoop->AddIdleHandler(this);
		
		bHandled = FALSE;
		return 0;
	}

	LRESULT OnFileExit(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
	{
		PostMessage(WM_CLOSE);
		return 0;
	}

	LRESULT OnFileNew(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
	{
		// TODO: add code to initialize document

		return 0;
	}

	LRESULT OnAppAbout(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
	{
		CAboutDlg dlg;
		dlg.DoModal();
		return 0;
	}

	void OnInit(void) {
		m_fAngle = 0.0f;

		glClearColor(0.000f, 0.000f, 0.000f, 1.0f); //Background color

		// Activate lighting and a light source
		glEnable(GL_LIGHT0);
		glEnable(GL_LIGHTING);
		glEnable(GL_DEPTH_TEST);

		// Define material parameters
		static GLfloat glfMatAmbient[] = {0.000f, 0.450f, 1.000f, 1.0f};
		static GLfloat glfMatDiffuse[] = {0.000f, 0.000f, 0.580f, 1.0f};
		static GLfloat glfMatSpecular[]= {1.000f, 1.000f, 1.000f, 1.0f};
		static GLfloat glfMatEmission[]= {0.000f, 0.000f, 0.000f, 1.0f};
		static GLfloat fShininess = 128.000f;

		// Set material parameters
		glMaterialfv(GL_FRONT, GL_AMBIENT,  glfMatAmbient);
		glMaterialfv(GL_FRONT, GL_DIFFUSE,  glfMatDiffuse);
		glMaterialfv(GL_FRONT, GL_SPECULAR, glfMatSpecular);
		glMaterialfv(GL_FRONT, GL_EMISSION, glfMatEmission);
		glMaterialf(GL_FRONT, GL_SHININESS, fShininess);
	}

	void OnRender(void) {
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear buffers
		glLoadIdentity(); // Load identity matrix

		// Add a light source
		GLfloat glfLight[] = {-4.0f, 4.0f, 4.0f, 0.0f};
		glLightfv(GL_LIGHT0, GL_POSITION, glfLight);
 
		// Position and rotate the camera
		glTranslatef(0.0f, 0.0f, -5.0f);	
		glRotatef(30.0f, 1.0f, 0.0f, 0.0f);
		glRotatef(m_fAngle, 0.0f, 1.0f, 0.0f);

		// Draw a cube
		static GLfloat r = .7f;
		GLCube(-r, -r, -r, r, r, r);

		glFlush();
	}

	void OnResize(int cx, int cy) {
		GLfloat fFovy  = 30.0f; // Field-of-view
		GLfloat fZNear = 1.0f;  // Near clipping plane
		GLfloat fZFar = 10.0f;  // Far clipping plane

		// Calculate viewport aspect
		RECT rc;
		GetClientRect(&rc);

		GLfloat fAspect = (GLfloat)(rc.right-rc.left) / (GLfloat)(rc.bottom-rc.top);

		// Define viewport
		glMatrixMode(GL_PROJECTION);
		glLoadIdentity();
		gluPerspective(fFovy, fAspect, fZNear, fZFar);
		glViewport(rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top);
		glMatrixMode(GL_MODELVIEW);
	}

	void UpdateFPS()
	{
		const int FRAMEINTERVAL = 1000;            // Show FPS every 1000th milliseconds
		static DWORD nFrames = 0;                  // Number of frames since last update
		static DWORD nLastTick = GetTickCount();   // Time of last update
		DWORD nTick = GetTickCount();              // Current time
		if(nTick-nLastTick>=FRAMEINTERVAL)
		{	
			float fFPS = 1000.0f*(GLfloat)nFrames/(GLfloat)(nTick-nLastTick);
			nLastTick = nTick;
			nFrames = 0;
			char szFPS[256];
			sprintf(szFPS, "%.1f FPS", fFPS);
			SetWindowText(szFPS);
		}
		nFrames++;
	}
	// GLCube()
	// Renders a cube.
	//
	void GLCube(GLfloat x1, GLfloat y1, GLfloat z1, GLfloat x2, GLfloat y2, GLfloat z2)
	{
		glBegin(GL_POLYGON);
		glNormal3f(0.0f, 0.0f, 1.0f);
		glVertex3f(x2, y2, z2);
		glVertex3f(x1, y2, z2);
		glVertex3f(x1, y1, z2);
		glVertex3f(x2, y1, z2);
		glEnd();

		glBegin(GL_POLYGON);
		glNormal3f(0.0f, 0.0f, -1.0f);
		glVertex3f(x2, y2, z1);
		glVertex3f(x2, y1, z1);
		glVertex3f(x1, y1, z1);
		glVertex3f(x1, y2, z1);
		glEnd();

		glBegin(GL_POLYGON);
		glNormal3f(-1.0f, 0.0f, 0.0f);
		glVertex3f(x1, y2, z2);
		glVertex3f(x1, y2, z1);
		glVertex3f(x1, y1, z1);
		glVertex3f(x1, y1, z2);
		glEnd();

		glBegin(GL_POLYGON);
		glNormal3f(1.0f, 0.0f, 0.0f);
		glVertex3f(x2, y2, z2);
		glVertex3f(x2, y1, z2);
		glVertex3f(x2, y1, z1);
		glVertex3f(x2, y2, z1);
		glEnd();

		glBegin(GL_POLYGON);
		glNormal3f(0.0f, 1.0f, 0.0f);
		glVertex3f(x1, y2, z1);
		glVertex3f(x1, y2, z2);
		glVertex3f(x2, y2, z2);
		glVertex3f(x2, y2, z1);
		glEnd();

		glBegin(GL_POLYGON);
		glNormal3f(0.0f, -1.0f, 0.0f);
		glVertex3f(x1, y1, z1);
		glVertex3f(x2, y1, z1);
		glVertex3f(x2, y1, z2);
		glVertex3f(x1, y1, z2);
		glEnd();
	}
};

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

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_MAINFRM_H__0879C256_36E6_4CB6_B5E0_0BB8527B0AC4__INCLUDED_)

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions