频道栏目
首页 > 程序开发 > 综合编程 > 其他综合 > 正文
VC++下的OpenGL编程
2017-04-14 10:03:12         来源:沈春旭的博客  
收藏   我要投稿

VC++下的OpenGL编程一般情况下,VC++下进行OpenGL应用程序开发步骤如下:1.通过PIXELFORMATDESCRIPTOR结构设置备注描述表DC的像素格式属性。

2.创建渲染描述表RC,并与设备描述表DC建立联系。

3.使用OpenGL作图4.释放所占用的资源,包括解除DC和RC的联系、删除RC及其关联的DC。在这里,应该先为应用程序添加所需的变量和函数,对相关变量进行初始化,然后在相应函数中实现DC像素格式设置、RC的创建及其和DC的关联、图形绘制以及资源释放等功能。

2.一个典型实例

2.1 添加成员变量和成员函数

CClientDC* pDrawDC;     // 用于指向当前DC的指针
BOOL PixelformatSetting(void);   // 用于设置像素格式
void GLSetting(void);            // 用于创建渲染描述表RC 并关联RC/DC
void DrawGraphics(void);         //OpenGL作图

2.2 添加消息响应函数

WM_CREATE --- OnCreate(); //该消息响应函数在建立一个窗体前被调用。

WM_DESTROY --- OnDestroy(); //窗口撤销时响应此函数,因此在该函数中释放所有被占用的资源。

WM_SIZE --- OnSize(); //改变窗口大小时响应此函数,可以调整视场。

afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnDestroy();
afx_msg void OnSize(UINT nType, int cx, int cy);

2.3 成员函数和消息响应函数添加代码

设置像素格式

BOOL CtestGLView::PixelformatSetting(void)
{
	static PIXELFORMATDESCRIPTOR pdf =
	{
		sizeof(PIXELFORMATDESCRIPTOR),
		1,
		PFD_DRAW_TO_WINDOW|
		PFD_SUPPORT_OPENGL|
		PFD_DOUBLEBUFFER,
		PFD_TYPE_RGBA,
		24,
		0,0,0,0,0,0,0,0,0,0,0,0,
		32,
		0,0,
		PFD_MAIN_PLANE,
		0,0,0,0
	}; //填充PIXELFORMATDISCRIPTOR
	int ipixelformat;
	//获得最佳匹配的像素格式索引
	if((ipixelformat = ChoosePixelFormat(pDrawDC->GetSafeHdc(), &pdf))==0)
	{
		MessageBox(_T("Choose pixel format failed!"));
		return FALSE;
	}
	//把DC的像素格式设置成由索引值ipixelformat指向的像素格式
	if(SetPixelFormat(pDrawDC->GetSafeHdc(),ipixelformat, &pdf) == FALSE)
	{
		MessageBox(_T("Set pixel format failed"));
		return FALSE;
	}
	return TRUE;
}
创建渲染描述表,调用PixelFormatSetting()设置像素格式,创建和DC关联的RC

void CtestGLView::GLSetting(void)
{
	HGLRC hRC;                       //渲染描述表句柄
	pDrawDC = new CClientDC (this);  //使用pDrawDC指向当前DC
	ASSERT(pDrawDC != NULL);
	if( !PixelformatSetting())       //设置像素格式
		return;
	//创建和当前DC兼容的RC,并和当前DC关联
	hRC = wglCreateContext(pDrawDC->GetSafeHdc());
	wglMakeCurrent(pDrawDC->GetSafeHdc(),hRC);
}
在消息响应函数OnCreate()中调用函数GLSetting(),使得GL环境生效

int CtestGLView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CView::OnCreate(lpCreateStruct) == -1)
		return -1;
	GLSetting();
	return 0;
}
绘制几何拓扑

void CtestGLView::DrawGraphics(void)
{
	//移动物体到显示区
	glTranslatef(0.0,0.0,-6.0);  //相当于在调整照相机 避免像太大
	glRotated(RotateAngle,1,1,1);
	//以边线的方式绘制三角形
	glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
	//绘制三角形,顺序给出3个三角形的顶点
	glBegin(GL_TRIANGLES);
	glVertex3f(-0.6,0,0);
	glVertex3f(0.6,0,0);
	glVertex3f(0.0,0.15,0.6);

	glVertex3f(-0.6,0,0);
	glVertex3f(0,0.15,0.6);
	glVertex3f(0,0.9,0.6);

	glVertex3f(0,0.9,0.6);
	glVertex3f(0,0.15,0.6);
	glVertex3f(0.6,0,0);
	glEnd();
}
OnDraw函数中,图像显示

void CtestGLView::OnDraw(CDC* /*pDC*/)
{
	CtestGLDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	if (!pDoc)
		return;

	static BOOL bBusy = FALSE;  //定义开关变量
	if(bBusy)                   //开关 绘制完成后才可以更新缓存
	{
		return;
	}
	bBusy = TRUE;
	glClearColor(0,0,0.5,0.5);//设置背景颜色
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //清除深度缓存和颜色缓存
	glMatrixMode(GL_MODELVIEW);  //启动模型视图矩阵
	glLoadIdentity();
	DrawGraphics();
	SwapBuffers(wglGetCurrentDC());  //更新缓存
	bBusy = FALSE;
}
删除渲染描述表RC及其绑定的设备描述表DC

void CtestGLView::OnDestroy()
{
	CView::OnDestroy();
	//删除渲染描述表及其绑定的设备描述表
	HGLRC  hRC;  //OpenGL的渲染描述表 
	hRC = ::wglGetCurrentContext();
	::wglMakeCurrent(NULL,NULL);  //解除当前RC和DC的关联,并把当前RC非当前化
	if(hRC)
	{
		::wglDeleteContext(hRC);
	}
	if(pDrawDC)
	{
		delete pDrawDC;
	}
}

2.4 添加人机交互(旋转功能)

采用鼠标左键控制开关,定时旋转方案。

WM_BUTTONDOWN --- OnLButtonDown();

WM_TIMER --- OnTimer();

添加变量:

BOOL bRotate;
float RotateAngle;
void CtestGLView::OnLButtonDown(UINT nFlags, CPoint point)
{
	if (bRotate)
	{
		SetTimer(1,100,NULL);
	} 
	else
	{
		KillTimer(1);
	}
	bRotate = !bRotate;
	CView::OnLButtonDown(nFlags, point);
}

void CtestGLView::OnTimer(UINT_PTR nIDEvent)
{
	//定时器计时达到预定时刻 则旋转角度增加10
	if( nIDEvent == 1)
	{
		RotateAngle += 10;
		Invalidate(FALSE);  //重新绘制
	}
	CView::OnTimer(nIDEvent);
}

 

3.输出结果

\


点击复制链接 与好友分享!回本站首页
上一篇:WOJ26 矩阵快速幂
下一篇:LeetCode 461题目解答
相关文章
图文推荐
点击排行

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站