3D C/C++ tutorials -> OpenGL 1.5 -> MFC OpenGL Window
Use for personal or educational purposes only. Commercial and other profit uses strictly prohibited. Exploitation of content on a website or in a publication prohibited.
mfc_opengl_window.h
#include <afxwin.h>
#include <gl/glew.h> // http://glew.sourceforge.net/
#include <gl/wglew.h>
// ----------------------------------------------------------------------------------------------------------------------------
#pragma comment(lib, "opengl32.lib")
#pragma comment(lib, "glu32.lib")
#pragma comment(lib, "glew32.lib")
// ----------------------------------------------------------------------------------------------------------------------------
extern CString ErrorLog;
// ----------------------------------------------------------------------------------------------------------------------------
class COpenGLRenderer
{
protected:
int Width, Height;
public:
COpenGLRenderer();
~COpenGLRenderer();
bool Init();
void Render(float FrameTime);
void Resize(int Width, int Height);
void Destroy();
};
// ----------------------------------------------------------------------------------------------------------------------------
class CMyWnd : public CWnd
{
protected:
CString Title;
HGLRC hGLRC;
int Width, Height;
public:
CMyWnd();
~CMyWnd();
void Show(bool Maximized = false);
DECLARE_MESSAGE_MAP()
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnDestroy();
afx_msg void OnPaint();
afx_msg void OnSize(UINT nType, int cx, int cy);
};
// ----------------------------------------------------------------------------------------------------------------------------
class CMyWinApp : public CWinApp
{
public:
CMyWinApp();
~CMyWinApp();
virtual BOOL InitInstance();
};
mfc_opengl_window.cpp
#include "mfc_opengl_window.h"
// ----------------------------------------------------------------------------------------------------------------------------
COpenGLRenderer::COpenGLRenderer()
{
}
COpenGLRenderer::~COpenGLRenderer()
{
}
bool COpenGLRenderer::Init()
{
return true;
}
void COpenGLRenderer::Render(float FrameTime)
{
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_TRIANGLES);
glColor3f(1.0f, 0.0f, 0.0); glVertex2f(-0.5f, -0.5f);
glColor3f(0.0f, 1.0f, 0.0); glVertex2f( 0.5f, -0.5f);
glColor3f(0.0f, 0.0f, 1.0); glVertex2f( 0.0f, 0.5f);
glEnd();
}
void COpenGLRenderer::Resize(int Width, int Height)
{
this->Width = Width;
this->Height = Height;
glViewport(0, 0, Width, Height);
}
void COpenGLRenderer::Destroy()
{
}
// ----------------------------------------------------------------------------------------------------------------------------
COpenGLRenderer OpenGLRenderer;
// ----------------------------------------------------------------------------------------------------------------------------
CString ErrorLog;
// ----------------------------------------------------------------------------------------------------------------------------
BEGIN_MESSAGE_MAP(CMyWnd, CWnd)
ON_WM_CREATE()
ON_WM_DESTROY()
ON_WM_PAINT()
ON_WM_SIZE()
END_MESSAGE_MAP()
// ----------------------------------------------------------------------------------------------------------------------------
CMyWnd::CMyWnd()
{
}
CMyWnd::~CMyWnd()
{
}
void CMyWnd::Show(bool Maximized)
{
RECT dRect, wRect, cRect;
::GetWindowRect(*GetDesktopWindow(), &dRect);
GetWindowRect(&wRect);
GetClientRect(&cRect);
wRect.right += Width - cRect.right;
wRect.bottom += Height - cRect.bottom;
wRect.right -= wRect.left;
wRect.bottom -= wRect.top;
wRect.left = dRect.right / 2 - wRect.right / 2;
wRect.top = dRect.bottom / 2 - wRect.bottom / 2;
MoveWindow(wRect.left, wRect.top, wRect.right, wRect.bottom, FALSE);
ShowWindow(Maximized ? SW_SHOWMAXIMIZED : SW_SHOWNORMAL);
}
int CMyWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if(CWnd::OnCreate(lpCreateStruct) == -1)
{
return -1;
}
Title = lpCreateStruct->lpszName;
Width = lpCreateStruct->cx;
Height = lpCreateStruct->cy;
CDC *cDC = GetDC();
if(cDC == NULL)
{
ErrorLog.SetString("GetDC failed!");
return -1;
}
PIXELFORMATDESCRIPTOR pfd;
memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 32;
pfd.cDepthBits = 24;
pfd.iLayerType = PFD_MAIN_PLANE;
int PixelFormat = ChoosePixelFormat(*cDC, &pfd);
if(PixelFormat == 0)
{
ErrorLog.SetString("ChoosePixelFormat failed!");
return -1;
}
if(SetPixelFormat(*cDC, PixelFormat, &pfd) == FALSE)
{
ErrorLog.SetString("SetPixelFormat failed!");
return -1;
}
hGLRC = wglCreateContext(*cDC);
if(hGLRC == NULL)
{
ErrorLog.SetString("wglCreateContext failed!");
return -1;
}
if(wglMakeCurrent(*cDC, hGLRC) == FALSE)
{
ErrorLog.SetString("wglMakeCurrent failed!");
return -1;
}
if(glewInit() != GLEW_OK)
{
ErrorLog.SetString("glewInit failed!");
return -1;
}
if(WGLEW_EXT_swap_control)
{
wglSwapIntervalEXT(0);
}
if(OpenGLRenderer.Init() == false)
{
return -1;
}
return 0;
}
void CMyWnd::OnDestroy()
{
OpenGLRenderer.Destroy();
wglDeleteContext(hGLRC);
}
void CMyWnd::OnPaint()
{
CPaintDC dc(this);
static DWORD LastFPSTime = GetTickCount(), LastFrameTime = LastFPSTime;
static int FPS = 0;
DWORD Time = GetTickCount();
float FrameTime = (Time - LastFrameTime) * 0.001f;
LastFrameTime = Time;
if(Time - LastFPSTime > 1000)
{
CString Text = Title;
Text.AppendFormat(" - %dx%d", Width, Height);
Text.AppendFormat(", FPS: %d", FPS);
Text.AppendFormat(" - %s", (char*)glGetString(GL_RENDERER));
SetWindowText(Text);
LastFPSTime = Time;
FPS = 0;
}
else
{
FPS++;
}
OpenGLRenderer.Render(FrameTime);
SwapBuffers(dc);
Invalidate(FALSE);
}
void CMyWnd::OnSize(UINT nType, int cx, int cy)
{
CWnd::OnSize(nType, cx, cy);
Width = cx;
Height = cy;
OpenGLRenderer.Resize(Width, Height);
}
// ----------------------------------------------------------------------------------------------------------------------------
CMyWnd MyWnd;
// ----------------------------------------------------------------------------------------------------------------------------
CMyWinApp::CMyWinApp()
{
}
CMyWinApp::~CMyWinApp()
{
}
BOOL CMyWinApp::InitInstance()
{
LPCTSTR WindowClassName = AfxRegisterWndClass(CS_OWNDC | CS_HREDRAW | CS_VREDRAW, ::LoadCursor(NULL, IDC_ARROW), 0, ::LoadIcon(NULL, IDI_APPLICATION));
char *AppName = "MFC OpenGL Window";
DWORD Style = WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
int Width = 800, Height = 600;
if(MyWnd.CreateEx(WS_EX_APPWINDOW, WindowClassName, AppName, Style, 0, 0, Width, Height, NULL, 0) == FALSE)
{
MessageBox(NULL, ErrorLog, AppName, MB_OK | MB_ICONERROR);
return FALSE;
}
MyWnd.Show();
m_pMainWnd = &MyWnd;
return TRUE;
}
// ----------------------------------------------------------------------------------------------------------------------------
CMyWinApp MyWinApp;
Download
|