My code:
class OpenGLDisplayClass : public CWnd
{
public:
OpenGLDisplayClass();
virtual BOOL Create(CWnd*, const RECT&, int TypeOfWindow = 0);
virtual void Update();
virtual void Display(){};
void ChangeViewPort(double angle, int x1, int y1, int width, int height, int projection = 0);
void MakeContextCurrent(BOOL onOff);
~OpenGLDisplayClass();
protected:
// declare event functions
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
afx_msg void OnSize (UINT, int, int);
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
DECLARE_MESSAGE_MAP ()
void CreateViewPort(double angle, int x1, int y1, int width, int height);
static HGLRC m_first_hRC ; //OpenGL Rendering Context
static CDC* m_first_pDC; //Device Context
HGLRC m_hRC ; //OpenGL Rendering Context
CDC* m_pDC; //Device Context
HDC m_hdc;
CRect m_window_area;
ViewType m_view;
BOOL SetupPixelFormat();
BOOL InitOpenGL();
static int m_objects;
static bool m_initialized;
private:
};
int OpenGLDisplayClass::m_objects = 0;
bool OpenGLDisplayClass::m_initialized = false;
HGLRC OpenGLDisplayClass::m_first_hRC = NULL; //OpenGL Rendering Context
CDC* OpenGLDisplayClass::m_first_pDC = NULL;
//CDC* OpenGLDisplayClass::m_pDC; //Device Context
BEGIN_MESSAGE_MAP (OpenGLDisplayClass, CWnd)
ON_WM_CREATE()
ON_WM_SIZE()
ON_WM_ERASEBKGND()
END_MESSAGE_MAP ()
//-----------------------------------------------------------------------------
OpenGLDisplayClass::OpenGLDisplayClass()
{
m_view = view_chase;
m_objects++;
};
//-----------------------------------------------------------------------------
OpenGLDisplayClass::~OpenGLDisplayClass()
{
wglMakeCurrent(0,0);
wglDeleteContext(m_hRC);
if(m_pDC)
{
delete m_pDC;
}
m_pDC = NULL;
m_objects--;
if (m_objects<= 0)
{
m_initialized = false;
m_objects = 0;
}
};
//-----------------------------------------------------------------------------
BOOL OpenGLDisplayClass::SetupPixelFormat()
{
static PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR), // Size of this pixel format descriptor.
1, // Version number
PFD_DRAW_TO_WINDOW | // Format must support windows
PFD_SUPPORT_OPENGL | // Use OpenGL
PFD_DOUBLEBUFFER | // Use double buffer
PFD_GENERIC_ACCELERATED |
PFD_GENERIC_FORMAT, // Pixel format is for a window.
PFD_TYPE_RGBA, // Request A RGBA Format
24, // Select Our Color Depth
0, 0, 0, 0, 0, 0, // Color Bits Ignored
0, // No Alpha Buffer
0, // Shift Bit Ignored
0, // No Accumulation Buffer
0, 0, 0, 0, // Accumulation Bits Ignored
32, // 32bit Z-buffer (depth buffer)
1, // 1 Stencil Buffer
0, // No Auxiliary Buffer
PFD_MAIN_PLANE, // Main Drawing Layer
0, // Reserved
0, 0, 0 // Layer Masks Ignored
};
//int m_nPixelFormat = ::ChoosePixelFormat(m_pDC->GetSafeHdc(), &pfd);
int m_nPixelFormat = ::ChoosePixelFormat(m_hdc, &pfd);
if (m_nPixelFormat == 0)
return FALSE;
// return ::SetPixelFormat(dc.m_hDC, nPixelFormat, &pfd);
// return ::SetPixelFormat(m_pDC->GetSafeHdc(), m_nPixelFormat, &pfd);
return ::SetPixelFormat(m_hdc, m_nPixelFormat, &pfd);
};
//-----------------------------------------------------------------------------
BOOL OpenGLDisplayClass::InitOpenGL()
{
//Get a DC for the Client Area
m_pDC = new CClientDC(this);
//Failure to Get DC
if(m_pDC == NULL)
return FALSE;
// Get device context only once.
m_hdc = GetDC()->m_hDC;
// m_hdc = m_pDC->GetSafeHdc();
if(!SetupPixelFormat())
return FALSE;
//Create Rendering Context
m_hRC = wglCreateContext(m_hdc);//m_pDC->GetSafeHdc());
//Failure to Create Rendering Context
if(m_hRC == 0)
return FALSE;
//Make the RC Current
//if(::wglMakeCurrent(m_pDC->GetSafeHdc(), m_hRC) == FALSE)
// return FALSE;
if(wglMakeCurrent(m_hdc, m_hRC) == FALSE)
return FALSE;
// set material values.
GLfloat mat_specular[] = {0.5f, 0.5f, 0.5f, 1.0};
GLfloat mat_shininess[] = {30.0f};
// set the light values.
GLfloat diffuse[] = {1.0f, 1.0f, 1.0f, 1.0f };
GLfloat specular[] = {1.0f, 1.0f, 1.0f, 1.0f };
GLfloat ambient[] = {0.3f, 0.3f, 0.3f, 1.0f };
GLfloat lightPos[] = {10000.0, 0.0, 1000.0, 0.0};
// setup lights and material
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
glLightfv(GL_LIGHT0, GL_SPECULAR, specular);
glLightfv(GL_LIGHT0, GL_POSITION, lightPos);
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient);
// glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_DEPTH_TEST);
glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
glShadeModel(GL_SMOOTH); // Enable Smooth Shading
glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // Black Background
glClearDepth(1.0f); // Depth Buffer Setup
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST); // Really Nice Perspective Calculations
glHint(GL_POLYGON_SMOOTH_HINT , GL_FASTEST);
glHint(GL_POINT_SMOOTH_HINT , GL_FASTEST);
glHint(GL_LINE_SMOOTH_HINT , GL_FASTEST);
return true;
};
//-----------------------------------------------------------------------------
BOOL OpenGLDisplayClass::Create(CWnd *pParentWnd, const RECT &rect, int TypeOfWindow)
{
if (CWnd::Create(NULL, "", WS_CHILD | WS_VISIBLE, rect, pParentWnd, 0, NULL) == -1)
return false;
GetClientRect(&m_window_area);
if (!InitOpenGL())
{
MessageBox("Error setting up OpenGL!",
"Init Error!",
MB_OK | MB_ICONERROR );
return -1;
}
if (m_initialized == false)
{
BuildFont(m_hdc);//m_pDC->GetSafeHdc());
LoadCommonTextures();
DrawCommonShapes(TypeOfWindow);
m_first_hRC = m_hRC;
m_initialized = true;
}
else
{
wglShareLists(m_first_hRC, m_hRC);
};
return true;
};
//-----------------------------------------------------------------------------
BOOL OpenGLDisplayClass::PreCreateWindow(CREATESTRUCT&a mp; cs)
{
cs.style |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN | CS_OWNDC;
return CWnd::PreCreateWindow(cs);
}
//-----------------------------------------------------------------------------
BOOL OpenGLDisplayClass::OnEraseBkgnd(CDC* pDC)
{
//return CView::OnEraseBkgnd(pDC);
return TRUE ;
}
//-----------------------------------------------------------------------------
void OpenGLDisplayClass::CreateViewPort(double angle, int x1, int y1, int width, int height)
{
glScissor(x1, y1, width,height);
glEnable(GL_SCISSOR_TEST);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDisable(GL_SCISSOR_TEST);
glViewport(x1, y1, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(angle, (float) width / (float)height, 1.0, 3000000.0);
glMatrixMode(GL_MODELVIEW);
// glLoadIdentity();
}
void OpenGLDisplayClass::ChangeViewPort(double angle, int x1, int y1, int width, int height, int projection)
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
int left = x1,
right = width,
bottom = y1,
top = height;
glViewport(x1, y1, width, height);
if (projection == 0)
{
// glTranslated(x1, y1, 0);
gluPerspective(angle, (float) width / (float)height, 1.0, 3000000.0);
}
else
{
glOrtho(left, right, bottom, top, -1000, 3000);
};
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
};
//-----------------------------------------------------------------------------
void OpenGLDisplayClass::OnSize(UINT nType, int cx, int cy)
{
CClientDC dc(this);
wglMakeCurrent(dc.m_hDC, m_hRC);
m_window_area = CRect(0, 0, cx, cy);
CreateViewPort(30.0, 0, 0, cx, cy);
wglMakeCurrent(NULL, NULL);
}
//-----------------------------------------------------------------------------
void OpenGLDisplayClass::MakeContextCurrent(BOOL onOff)
{
if (onOff)
{
// ::wglMakeCurrent(m_pDC->GetSafeHdc(), m_hRC);
::wglMakeCurrent(m_hdc, m_hRC);
}
else
{
::wglMakeCurrent(NULL, NULL);
};
}
//-----------------------------------------------------------------------------
void OpenGLDisplayClass::Update()
{
Invalidate(FALSE);
UpdateWindow();
};