atlopengl

#ifndef __ATLOPENGL_H__
#define __ATLOPENGL_H__

#pragma once

#ifndef __cplusplus
	#error ATL requires C++ compilation (use a .cpp suffix)
#endif

#ifndef __ATLAPP_H__
	#error atlopengl.h requires atlapp.h to be included first
#endif

#ifndef __ATLWIN_H__
	#error atlopengl.h requires atlwin.h to be included first
#endif

#ifndef __ATLGDI_H__
	#error atlopengl.h requires atlgdi.h to be included first
#endif

#if (WINVER < 0x0400)
	#error WTL requires Windows version 4.0 or higher
#endif


#ifdef _ATL_NO_OPENGL
	#error atlopengl.h requires OpenGL support
#endif

// required libraries
#ifndef _ATL_NO_OPENGL_UTIL
	#include <gl/glu.h>
	#pragma comment (lib, "glu32.lib")     /* link with Microsoft OpenGL Utility lib */
#endif

namespace WTL
{

/////////////////////////////////////////////////////////////////////////////
// CGLMessageLoop - used for OpenGL animation

class CGLMessageLoop : public CMessageLoop {
	
	BOOL OnIdle(int nIdleCount) {
		return !CMessageLoop::OnIdle(nIdleCount);
	}
	
};

/////////////////////////////////////////////////////////////////////////////
// COpenGL

template <class T>
class ATL_NO_VTABLE COpenGL
{
public:

	HGLRC m_hRC;			// Handle to RC

// Message map and handlers
	typedef COpenGL<T>	thisClass;
		
	BEGIN_MSG_MAP(thisClass)
		MESSAGE_HANDLER(WM_CREATE, OnCreate)
		MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
		MESSAGE_HANDLER(WM_PAINT, OnPaint)
		MESSAGE_HANDLER(WM_SIZE, OnSize)
		MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBkgnd)

		//
		MESSAGE_HANDLER(WM_LBUTTONDOWN,OnLButtonDown)
		MESSAGE_HANDLER(WM_LBUTTONUP,OnLButtonUp)
		MESSAGE_HANDLER(WM_MOUSEMOVE,OnMouseMove)

	END_MSG_MAP()
	
	LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
	{
		mbLMouseDn = false;
		mfSpinX_L = 0;
		mfSpinY_L = 0;

		T* pT = static_cast<T*>(this);
		CClientDC dc(pT->m_hWnd);
		
		// Fill in the pixel format descriptor.
		PIXELFORMATDESCRIPTOR pfd;
		memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
		pfd.nSize      = sizeof(PIXELFORMATDESCRIPTOR); 
		pfd.nVersion   = 1; 
		pfd.dwFlags    = PFD_DOUBLEBUFFER | PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW;
		pfd.iPixelType = PFD_TYPE_RGBA; 
		pfd.cColorBits = 24;
		pfd.cDepthBits = 32; 
		pfd.iLayerType = PFD_MAIN_PLANE ;
		
		int nPixelFormat = dc.ChoosePixelFormat(&pfd);
	    ATLASSERT(nPixelFormat != 0);
		
		BOOL bResult = dc.SetPixelFormat (nPixelFormat, &pfd);
		ATLASSERT(bResult);
		
		m_hRC = dc.wglCreateContext();
		ATLASSERT(m_hRC);

		dc.wglMakeCurrent(m_hRC);
		pT->OnInit();
		dc.wglMakeCurrent(NULL);

		bHandled = FALSE;
		return 0;
	}
	
	LRESULT OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
	{
		if (m_hRC) {
			::wglDeleteContext(m_hRC);
			m_hRC = NULL;
		}
		
		bHandled = FALSE;
		return 0;
	}
	
	LRESULT OnPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
	{
		T* pT = static_cast<T*>(this);
		CPaintDC dc(pT->m_hWnd);
		dc.wglMakeCurrent(m_hRC);
		pT->OnRender();
		dc.SwapBuffers();
		dc.wglMakeCurrent(NULL);
		
		return 0;
	}
	
	LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
	{
		T* pT = static_cast<T*>(this);
		int cx = LOWORD(lParam);
		int cy = HIWORD(lParam);
		
		if	(cx==0 || cy==0 || pT->m_hWnd==NULL)
			return 0;

		CClientDC dc(pT->m_hWnd);
		dc.wglMakeCurrent(m_hRC);
		pT->OnResize(cx, cy);
		dc.wglMakeCurrent(NULL);

		bHandled = FALSE;
		return 0;
	}

	LRESULT OnEraseBkgnd(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
	{
		return 1;
	}


	LRESULT OnLButtonDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
	{
		mbLMouseDn = true;
		return false;
	}

	LRESULT OnLButtonUp(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
	{
		mbLMouseDn = false;
		return false;
	}

	LRESULT OnMouseMove(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
	{
		ptCurrentMousePosit_L.x = LOWORD (lParam);
		ptCurrentMousePosit_L.y = HIWORD (lParam);

		if( mbLMouseDn )
		{
			mfSpinX_L -= (ptCurrentMousePosit_L.x - ptLastMousePosit_L.x);
			mfSpinY_L -= (ptCurrentMousePosit_L.y - ptLastMousePosit_L.y);
		}

		ptLastMousePosit_L.x = ptCurrentMousePosit_L.x;
		ptLastMousePosit_L.y = ptCurrentMousePosit_L.y;

		return false;
	}

	void GetRorateByMouse(float &x, float &y)
	{
		x = mfSpinX_L;
		y = mfSpinY_L;
	}

private:
	bool	mbLMouseDn;
	float	mfSpinX_L;
	float	mfSpinY_L;

	POINT ptLastMousePosit_L;
	POINT ptCurrentMousePosit_L;
};

}; //namespace WTL

#endif // __ATLOPENGL_H__

你可能感兴趣的:(atlopengl)