重载MFC中的WM_CRATE消息响应函数int OnCreate(LPCREATESTRUCT lpCreateStruct),显示调用Init函数,如下:
int C3DStereoView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;
Init(); // 初始化OpenGL
return 0;
}
在Init函数(自定义的)中完成OpenGL环境初始化,定义如下:
void C3DStereoView::Init()
{
PIXELFORMATDESCRIPTOR pfd;
int n;
m_pDC = new CClientDC(this);
ASSERT(m_pDC != NULL);
if (!bSetupPixelFormat())
return;
n = ::GetPixelFormat(m_pDC->GetSafeHdc());
::DescribePixelFormat(m_pDC->GetSafeHdc(), n, sizeof(pfd), &pfd);
hrc = wglCreateContext(m_pDC->GetSafeHdc());
if(wglGetCurrentContext() == NULL)
wglMakeCurrent(m_pDC->GetSafeHdc(),hrc);
else
{
wglMakeCurrent(NULL,NULL);
wglMakeCurrent(m_pDC->GetSafeHdc(),hrc);
}
//--- 初始化材料属性、光照和深度缓存 ----
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glColorMaterial(GL_FRONT_AND_BACK,GL_DIFFUSE);
glEnable(GL_COLOR_MATERIAL);
GLfloat m_light0Ambient[4]={0.5f,0.5f,0.5f,1.0f}; // 环境光
GLfloat m_light0Diffuse[4]={1.0f,1.0f,1.0f,1.0f}; // 散射(漫反射)光
GLfloat m_light0Pos[4]={1,1,1,0.0f}; // 光源位置
glLightfv(GL_LIGHT0,GL_AMBIENT,m_light0Ambient);
glLightfv(GL_LIGHT0,GL_DIFFUSE,m_light0Diffuse);
glLightfv(GL_LIGHT0,GL_POSITION,m_light0Pos);
if(m_pDisplayControl->dispalayTexture)
glEnable(GL_LIGHTING);
else
glDisable(GL_LIGHTING);
glEnable(GL_LIGHT0);
SetTimer(1, 2000, NULL); //设置时钟
if(model!=NULL)
modelInit();
//--------- font 的初始化 ---------
glShadeModel (GL_FLAT);
//---------- 使得 CToolTips 控件可用----------
EnableToolTips(TRUE);
m_ttc.Create(this);
m_ttc.Activate(TRUE);
m_ttc.AddTool(this, "IDC_BUTTON1 ");
m_ttc.SetTipBkColor(RGB(255,255,255)); // 白底
m_ttc.SetTipTextColor(RGB(0,0,255)); // 蓝字
m_ttc.SetDelayTime(150);
return;
}
在Init函数中调用了bSetupPixelFormat函数(也是自定义的),在这个函数中为DC设置指定的像素格式
BOOL C3DStereoView::bSetupPixelFormat()
{
static PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd
1, // version number
PFD_DRAW_TO_WINDOW | // support window
PFD_SUPPORT_OPENGL | // support OpenGL
PFD_DOUBLEBUFFER, // double buffered
PFD_TYPE_RGBA, // RGBA type
24, // 24-bit 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, // accum bits ignored
32, // 32-bit z-buffer
0, // no stencil buffer
0, // no auxiliary buffer
PFD_MAIN_PLANE, // main layer
0, // reserved
0, 0, 0 // layer masks ignored
};
int pixelformat;
if ( (pixelformat = ChoosePixelFormat(m_pDC->GetSafeHdc(), &pfd)) == 0 )
{
MessageBox(_T("ChoosePixelFormat failed"));
return FALSE;
}
if (SetPixelFormat(m_pDC->GetSafeHdc(), pixelformat, &pfd) == FALSE)
{
MessageBox(_T("SetPixelFormat failed"));
return FALSE;
}
return TRUE;
}
重载MFC中的WM_SIZE消息响应函数void OnSize(UINTnType,int cx, int cy),设置显示尺寸
void C3DStereoView::OnSize(UINT nType, int cx, int cy)
{
CView::OnSize(nType, cx, cy);
int w=cx;
int h=cy;
GLfloat nRange=1.5f;
//避免除数为0
if(h==0)
h=1;
//设置视口与窗口匹配
glViewport(0,0,w,h);
//重新设置坐标系统
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//----------- (4)定义投影方式为透视图 -------------
if(cy>0)
gluPerspective(m_dFovy, (GLdouble)(cx/cy), m_fNearPlane, m_fFarPlane);
// 参数说明:
// m_dFovy --像机向视景体投射时左右视角(在 0.0-180。0 的范围之内)(即视景体的远面向近面交汇的夹角)
// aspect=cx/cy (视景体顶面或底面上 x,y的比例,即视景体的宽高比),
// m_fNearPlane--视点至近裁切面的距离,
// m_fFarPlane --视点至远裁切面的距离
glMatrixMode(GL_MODELVIEW);
//glLoadIdentity(); 张丽云多加了这句,画不出来
CalculateScale();
}
重载MFC的WM_ERASEBKGND消息响应函数OnEraseBkgnd(CDC* pDC) ,目的是消除屏幕闪烁
BOOL C3DStereoView::OnEraseBkgnd(CDC* pDC)
{
return TRUE;
}
最后,记得解除hrc与dc的绑定关系,删除HGLRC对象,重载MFC的WM_DESTROY消息
void C3DStereoView::OnDestroy()
{
//HGLRC hrc;
//hrc = ::wglGetCurrentContext();
//::wglMakeCurrent(NULL, NULL);
if( wglGetCurrentContext() != NULL)
::wglMakeCurrent(NULL, NULL);
if( hrc )
::wglDeleteContext(hrc);
if( m_pDC != NULL)
{
delete m_pDC;
//ReleaseDC(m_pDC);
m_pDC = NULL;
}
CView::OnDestroy();
}
OpenGL框架其他搭建例子:
例1:https://blog.csdn.net/wang15061955806/article/details/49073731
例2:https://blog.csdn.net/hf19931101/article/details/50389315