MFC下OpenGL环境搭建

106 篇文章 2 订阅
9 篇文章 0 订阅

重载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


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值