`
缥缈孤鸿
  • 浏览: 42172 次
  • 性别: Icon_minigender_1
  • 来自: 大连
最近访客 更多访客>>
社区版块
存档分类
最新评论

MFC OpenGL标签云 (转)

    博客分类:
  • C++
阅读更多
  初识标签云是在去年年末,一看到这个应用我就特别感兴趣。还记得08年在北京做Mobile应用的时候就在想,是不是可以通过某种方式做界面扩展,让相对狭小的手机屏幕只显示有效部分,而扩展部分可以在屏幕以外,通过某种方式将他们调到屏幕以内。后来证实做这种思考的人不只是我自己,因为现在划屏应用已经是移动终端的基本应用模式了。当时也想过能不能在纵向做界面延伸,让界面深入到屏幕里面,要知道那可是无限的空间,不过没有想到什么好的方式。见到标签云的那一刻,我知道这就是我想要的,所以当时我就决定用OpenGL模拟一下,然后拿出来和大家共同探讨,看看有没有可能做成一个更成熟些应用。不过过年回来工作比较忙,所以也就搁置了。这两天刚阶段性的完成一个项目,所以得了空可以写这篇博客。
        要实现功能就要先分析原理,通过使用和观察我觉得标签云的每一个标签都分布在一个球体上,球在视平面上的投影是一个圆,而整个球就根据鼠标和这个投影圆的位置关系不同而旋转。鼠标离圆心越远转速愉快,反之则越慢。球体旋转是围绕一根通过球心且与视平面平行的转轴进行的,鼠标和投影圆圆心的位置关系同样控制者转轴的方向,那就是转轴垂直于投影圆圆心和鼠标的连线。最后一点,旋转过程总是迎着鼠标进行。
        知道了基本原理就要开始分析算法了,实现三维空间用OpenGL这自不必说,我曾经写过一篇日志《OpenGL控件》介绍了一个内置OpenGL基本框架环境的自定义控件,这次就是极基于这个控件的一个扩展应用。我还曾经在《三维向量类》一文中介绍过我自己写的一个进行三维程序设计时很实用的向量类CVector,当然这次建模还是要依靠它。唯一的问题是OpenGL对于中文支持的不好,有没有什么方法可以方便的显示中文呢?我这里采用的方法是在内存中生成一张文字的贴图,然后用Alpha混合的方式赋予一个plan,这样就可以利用系统字库在OpenGL中显示各种类型丰富的文字了。好了,主要问题都解决了,开始写代码。
        首先定义一个结构体来代表标签元中的一个标签:
 
typedef struct	tagTAGNODE
{
	CVector		m_vtrPos;	// 标签位置
	float		m_fWidth,	// 标签长
				m_fHeight;	// 标签宽
	UINT		m_uTexture; 	// 贴图号
}CloudTag, *lpCloudTag;     

   然后在COpenGLCtrl里维护一个CloudTag数组用来管理所有标签,也就是整个云。函数AddCloud用来添加一个标签,其代码如下:
 view plaincopyprint?void COpenGLCtrl::AddCloud(CString strName, COLORREF clrText, CString strFontName, int nPointSize, int nWeight, UINT uCharset)  
{  
    int         nMode;  
    CSize       sizeText;  
    CRect       rectTag;  
    CBitmap     bitmapTemp, *pOldBitmap;  
    CFont       fontTag, *pOldFont;  
    COLORREF    clrOld;  
    LOGFONT     lf;  
    CDC*        pDC         = GetDC();  
    CDC*        pMemDC      = new CDC;  
    lpCloudTag  pCloudTag   = new CloudTag;  
    int         nExtend     = 5;  
    float       fTemp;  
  
  
    //设置字体   
    memset(&lf, 0, sizeof(LOGFONT));  
  
    //设置字体样式   
    wcscpy_s(lf.lfFaceName, strFontName);  
    lf.lfHeight  = nPointSize;  
    lf.lfWeight  = nWeight;  
    lf.lfCharSet = uCharset;  
  
    fontTag.CreateFontIndirect(&lf);  
  
    //创建位图内存   
    pMemDC->CreateCompatibleDC(pDC);  
    pOldFont    = pMemDC->SelectObject(&fontTag);  
    nMode       = pMemDC->SetBkMode(TRANSPARENT);  
    clrOld      = pMemDC->SetTextColor(clrText);  
  
    sizeText    = pMemDC->GetTextExtent(strName, strName.GetLength());  
    pCloudTag->m_fWidth      = float(sizeText.cx+nExtend)/40;  
    pCloudTag->m_fHeight = float(sizeText.cy+nExtend)/40;  
    rectTag.SetRect(0, 0, sizeText.cx+nExtend, sizeText.cy+nExtend);  
  
    bitmapTemp.CreateCompatibleBitmap(pDC, rectTag.Width(), rectTag.Height());  
    pOldBitmap  = pMemDC->SelectObject(&bitmapTemp);  
  
    //填充客户区   
    pMemDC->DrawText(strName, strName.GetLength(), rectTag, DT_SINGLELINE|DT_CENTER|DT_VCENTER);  
    pMemDC->SetBkMode(nMode);  
    pMemDC->SelectObject(pOldFont);  
    pMemDC->SelectObject(pOldBitmap);  
    pMemDC->SetTextColor(clrOld);  
    delete  pMemDC;  
  
    BITMAP      bmData;  
    bitmapTemp.GetBitmap(&bmData);  
    unsigned char*  pData   = new unsigned char[bmData.bmWidthBytes*bmData.bmHeight];  
    bitmapTemp.GetBitmapBits(bmData.bmWidthBytes*bmData.bmHeight, pData);  
    for(int i=0; i<bmData.bmWidth; i++)  
    {  
        for(int j=0; j<bmData.bmHeight; j++)  
        {  
            if(pData[i*4+j*bmData.bmWidthBytes]!=0 || pData[i*4+j*bmData.bmWidthBytes+1]!=0 || pData[i*4+j*bmData.bmWidthBytes+2]!=0)  
                pData[i*4+j*bmData.bmWidthBytes+3]=255;  
        }  
    }  
    glGenTextures(1, &pCloudTag->m_uTexture);  
    glBindTexture(GL_TEXTURE_2D, pCloudTag->m_uTexture);  
    gluBuild2DMipmaps(GL_TEXTURE_2D, 4, bmData.bmWidth, bmData.bmHeight, GL_RGBA, GL_UNSIGNED_BYTE, pData);  
  
    delete  pData;  
  
    fTemp   = (rand()%50)/10.0f+3;  
    pCloudTag->m_vtrPos  = CVector(0, 0, fTemp);  
    fTemp   = (rand()%360-180)/360.0f;  
    pCloudTag->m_vtrPos.Rotate(fTemp, CVector(1, 0, 0));  
    fTemp   = (rand()%360-180)/360.0f;  
    pCloudTag->m_vtrPos.Rotate(fTemp, CVector(0, 1, 0));  
    fTemp   = (rand()%360-180)/360.0f;  
    pCloudTag->m_vtrPos.Rotate(fTemp, CVector(0, 0, 1));  
    m_tcDemo.Add(pCloudTag);  
}  

void COpenGLCtrl::AddCloud(CString strName, COLORREF clrText, CString strFontName, int nPointSize, int nWeight, UINT uCharset)
{
	int			nMode;
	CSize		sizeText;
	CRect		rectTag;
	CBitmap		bitmapTemp, *pOldBitmap;
	CFont		fontTag, *pOldFont;
	COLORREF	clrOld;
	LOGFONT		lf;
	CDC*		pDC			= GetDC();
	CDC*		pMemDC		= new CDC;
	lpCloudTag	pCloudTag	= new CloudTag;
	int			nExtend		= 5;
	float		fTemp;


	//设置字体
	memset(&lf, 0, sizeof(LOGFONT));

	//设置字体样式
	wcscpy_s(lf.lfFaceName, strFontName);
	lf.lfHeight	 = nPointSize;
	lf.lfWeight  = nWeight;
	lf.lfCharSet = uCharset;

	fontTag.CreateFontIndirect(&lf);

	//创建位图内存
	pMemDC->CreateCompatibleDC(pDC);
	pOldFont	= pMemDC->SelectObject(&fontTag);
	nMode		= pMemDC->SetBkMode(TRANSPARENT);
	clrOld		= pMemDC->SetTextColor(clrText);

	sizeText	= pMemDC->GetTextExtent(strName, strName.GetLength());
	pCloudTag->m_fWidth		= float(sizeText.cx+nExtend)/40;
	pCloudTag->m_fHeight	= float(sizeText.cy+nExtend)/40;
	rectTag.SetRect(0, 0, sizeText.cx+nExtend, sizeText.cy+nExtend);

	bitmapTemp.CreateCompatibleBitmap(pDC, rectTag.Width(), rectTag.Height());
	pOldBitmap	= pMemDC->SelectObject(&bitmapTemp);

	//填充客户区
	pMemDC->DrawText(strName, strName.GetLength(), rectTag, DT_SINGLELINE|DT_CENTER|DT_VCENTER);
	pMemDC->SetBkMode(nMode);
	pMemDC->SelectObject(pOldFont);
	pMemDC->SelectObject(pOldBitmap);
	pMemDC->SetTextColor(clrOld);
	delete	pMemDC;

	BITMAP		bmData;
	bitmapTemp.GetBitmap(&bmData);
	unsigned char*	pData	= new unsigned char[bmData.bmWidthBytes*bmData.bmHeight];
	bitmapTemp.GetBitmapBits(bmData.bmWidthBytes*bmData.bmHeight, pData);
	for(int i=0; i<bmData.bmWidth; i++)
	{
		for(int j=0; j<bmData.bmHeight; j++)
		{
			if(pData[i*4+j*bmData.bmWidthBytes]!=0 || pData[i*4+j*bmData.bmWidthBytes+1]!=0 || pData[i*4+j*bmData.bmWidthBytes+2]!=0)
				pData[i*4+j*bmData.bmWidthBytes+3]=255;
		}
	}
	glGenTextures(1, &pCloudTag->m_uTexture);
	glBindTexture(GL_TEXTURE_2D, pCloudTag->m_uTexture);
	gluBuild2DMipmaps(GL_TEXTURE_2D, 4, bmData.bmWidth, bmData.bmHeight, GL_RGBA, GL_UNSIGNED_BYTE, pData);

	delete	pData;

	fTemp	= (rand()%50)/10.0f+3;
	pCloudTag->m_vtrPos	= CVector(0, 0, fTemp);
	fTemp	= (rand()%360-180)/360.0f;
	pCloudTag->m_vtrPos.Rotate(fTemp, CVector(1, 0, 0));
	fTemp	= (rand()%360-180)/360.0f;
	pCloudTag->m_vtrPos.Rotate(fTemp, CVector(0, 1, 0));
	fTemp	= (rand()%360-180)/360.0f;
	pCloudTag->m_vtrPos.Rotate(fTemp, CVector(0, 0, 1));
	m_tcDemo.Add(pCloudTag);


这个函数是生成标签的核心函数,在程序里标签表现出来的形式就是文本,所以函数支持对文本的几乎一切定制,这包括内容、颜色、字体、字号、样式等。函数首先会创建一个字体,然后根据文本内容需要的大小创建一个内存位图,将文字绘制于这个位图之上。准备好文字的位图就要通过它来制作材质了,这里有一个问题,位图是没有Alpha通道的,怎么办呢,有没有什么相对简单的方法处理呢?这里我的处理方法是这样的,看代码,通过GetBitmap获取位图信息然后观察bmData.bmWidth和bmData.bmWidthBytes的值,可以发现bmWidthBytes是bmWidth的四倍。原来位图在内存里是以RGBA的方式存储的,所以通过GetBitmapBits获取到的数据就是4位的。众所周知,内存位图创建时是黑色的,这里我认定标签文字不能为黑色,所以检测数据如果是黑色的就把Alpha设为透明,不是就设为不透明,然后创建贴图。最后设置向量,在一个范围内随机生成一个长度做一个指向屏幕外的向量,在以x、y、z三个轴随机旋转一个角度,这样就完成了一个标签的建模。
        渲染的部分很简单,就是常规的OpenGL绘制,只不过加上了材质设置了Alpha透明。其实这个Demo做的比较粗糙,文字周围存在黑边,不过做这个例子不是特别追求表现所以也就没有特别处理,代码如下:


 view plaincopyprint?void COpenGLCtrl::OnPaint()   
{  
    CPaintDC    dc(this);  
  
    //绘背景色   
    COLORREF    clrBkgnd    = GetSysColor(COLOR_BTNFACE);  
    glClearColor(float(GetRValue(clrBkgnd))/255, float(GetGValue(clrBkgnd))/255, float(GetBValue(clrBkgnd))/255, 0.0f);  
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);  
  
    //设置场景坐标系   
    glLoadIdentity();  
    //设置观察点   
    gluLookAt(0, 0, 30, 0, 0, 0, 0, 1, 0);  
  
    INT_PTR nCount  = m_tcDemo.GetCount();  
    for(int i=0; i<nCount; i++)  
    {  
        lpCloudTag  pCloudTag   = m_tcDemo.GetAt(i);  
  
        glBindTexture(GL_TEXTURE_2D, pCloudTag->m_uTexture);  
        glEnable(GL_BLEND);  
        glEnable(GL_ALPHA_TEST);  
        glAlphaFunc(GL_GREATER, 0.1f);  
        glBegin(GL_QUADS);  
        glTexCoord2i(0, 0), glVertex3f(pCloudTag->m_vtrPos.m_fVectorX-pCloudTag->m_fWidth/2, pCloudTag->m_vtrPos.m_fVectorY+pCloudTag->m_fHeight/2, pCloudTag->m_vtrPos.m_fVectorZ);  
        glTexCoord2i(1, 0), glVertex3f(pCloudTag->m_vtrPos.m_fVectorX+pCloudTag->m_fWidth/2, pCloudTag->m_vtrPos.m_fVectorY+pCloudTag->m_fHeight/2, pCloudTag->m_vtrPos.m_fVectorZ);  
        glTexCoord2i(1, 1), glVertex3f(pCloudTag->m_vtrPos.m_fVectorX+pCloudTag->m_fWidth/2, pCloudTag->m_vtrPos.m_fVectorY-pCloudTag->m_fHeight/2, pCloudTag->m_vtrPos.m_fVectorZ);  
        glTexCoord2i(0, 1), glVertex3f(pCloudTag->m_vtrPos.m_fVectorX-pCloudTag->m_fWidth/2, pCloudTag->m_vtrPos.m_fVectorY-pCloudTag->m_fHeight/2, pCloudTag->m_vtrPos.m_fVectorZ);  
        glEnd();  
        glDisable(GL_ALPHA_TEST);  
        glDisable(GL_BLEND);  
  
    }  
  
    //翻页   
    SwapBuffers(m_pDC->m_hDC);  
}  

void COpenGLCtrl::OnPaint() 
{
	CPaintDC	dc(this);

	//绘背景色
	COLORREF	clrBkgnd	= GetSysColor(COLOR_BTNFACE);
	glClearColor(float(GetRValue(clrBkgnd))/255, float(GetGValue(clrBkgnd))/255, float(GetBValue(clrBkgnd))/255, 0.0f);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	//设置场景坐标系
	glLoadIdentity();
	//设置观察点
	gluLookAt(0, 0, 30, 0, 0, 0, 0, 1, 0);

	INT_PTR	nCount	= m_tcDemo.GetCount();
	for(int i=0; i<nCount; i++)
	{
		lpCloudTag	pCloudTag	= m_tcDemo.GetAt(i);

		glBindTexture(GL_TEXTURE_2D, pCloudTag->m_uTexture);
		glEnable(GL_BLEND);
		glEnable(GL_ALPHA_TEST);
		glAlphaFunc(GL_GREATER, 0.1f);
		glBegin(GL_QUADS);
		glTexCoord2i(0, 0), glVertex3f(pCloudTag->m_vtrPos.m_fVectorX-pCloudTag->m_fWidth/2, pCloudTag->m_vtrPos.m_fVectorY+pCloudTag->m_fHeight/2, pCloudTag->m_vtrPos.m_fVectorZ);
		glTexCoord2i(1, 0), glVertex3f(pCloudTag->m_vtrPos.m_fVectorX+pCloudTag->m_fWidth/2, pCloudTag->m_vtrPos.m_fVectorY+pCloudTag->m_fHeight/2, pCloudTag->m_vtrPos.m_fVectorZ);
		glTexCoord2i(1, 1), glVertex3f(pCloudTag->m_vtrPos.m_fVectorX+pCloudTag->m_fWidth/2, pCloudTag->m_vtrPos.m_fVectorY-pCloudTag->m_fHeight/2, pCloudTag->m_vtrPos.m_fVectorZ);
		glTexCoord2i(0, 1), glVertex3f(pCloudTag->m_vtrPos.m_fVectorX-pCloudTag->m_fWidth/2, pCloudTag->m_vtrPos.m_fVectorY-pCloudTag->m_fHeight/2, pCloudTag->m_vtrPos.m_fVectorZ);
		glEnd();
		glDisable(GL_ALPHA_TEST);
		glDisable(GL_BLEND);

	}

	//翻页
	SwapBuffers(m_pDC->m_hDC);
}   
     剩下的事情就是鼠标控制和动画实现了,由于我的向量类很好的支持了旋转功能,而且标签云建模就是通过向量实现的,所以这一步也就好说了。所有标签都是通过以原点为起点的向量定位的,所以转轴也是通过原点的在XOZ面上的向量。在OnMouseHover中计算状态和转速,然后在OnTimer里旋转每个标签的向量就是了,代码如下:
view plaincopyprint?LRESULT COpenGLCtrl::OnMouseHover(WPARAM wParam, LPARAM lParam)  
{  
    CRect   rectView;  
    CPoint  point;  
  
    GetWindowRect(rectView);  
    GetCursorPos(&point);  
  
    m_vtrRotate.SetVector(float(-point.x), float(point.y), 0, -float(rectView.right+rectView.left)/2, float(rectView.bottom+rectView.top)/2, 0);  
    m_vtrRotate.Rotate(-PI/2, CVector(0, 0, 1));  
  
    m_fAngle    = m_vtrRotate.GetMod()/2000;  
    return 1;  
}  

LRESULT COpenGLCtrl::OnMouseHover(WPARAM wParam, LPARAM lParam)
{
	CRect	rectView;
	CPoint	point;

	GetWindowRect(rectView);
	GetCursorPos(&point);

	m_vtrRotate.SetVector(float(-point.x), float(point.y), 0, -float(rectView.right+rectView.left)/2, float(rectView.bottom+rectView.top)/2, 0);
	m_vtrRotate.Rotate(-PI/2, CVector(0, 0, 1));

	m_fAngle	= m_vtrRotate.GetMod()/2000;
	return 1;
}
[cpp] view plaincopyprint?void COpenGLCtrl::OnTimer(UINT_PTR nIDEvent)  
{  
    switch(nIDEvent)  
    {  
    case TIMER_MOVE:  
        {  
            if(m_fAngle==0)  
                return;  
  
            INT_PTR nCount  = m_tcDemo.GetCount();  
            for(int i=0; i<nCount; i++)  
            {  
                lpCloudTag  pCloudTag   = m_tcDemo.GetAt(i);  
                pCloudTag->m_vtrPos.Rotate(m_fAngle, m_vtrRotate);  
                Invalidate();  
            }  
        }break;  
    }  
  
    CWnd::OnTimer(nIDEvent);  
}  

void COpenGLCtrl::OnTimer(UINT_PTR nIDEvent)
{
	switch(nIDEvent)
	{
	case TIMER_MOVE:
		{
			if(m_fAngle==0)
				return;

			INT_PTR	nCount	= m_tcDemo.GetCount();
			for(int i=0; i<nCount; i++)
			{
				lpCloudTag	pCloudTag	= m_tcDemo.GetAt(i);
				pCloudTag->m_vtrPos.Rotate(m_fAngle, m_vtrRotate);
				Invalidate();
			}
		}break;
	}



CWnd::OnTimer(nIDEvent);
}        到此基本的功能就已经全部实现了,在我的资源里上传了这个Demo有兴趣朋友可以下载研究一下,有什么好的想法可以和我进一步交流。做这个东西,写这篇文章权当抛砖引玉,希望能给大家些灵感,从三维的角度作出有更好用户体验的界面设计。最后贴一个效果图,见笑见笑。
[img][/img]




转(http://blog.csdn.net/xianglitian/article/details/6590687)
分享到:
评论

相关推荐

    mfc-opengl.rar_MFC opengl _OpenGL MFC_draw_opengl mfc_opengl

    在标签中,“mfc__opengl__ opengl_mfc draw opengl__mfc opengl__vrml”提到了几个关键点: 1. **mfc__opengl** 和 **opengl_mfc** 指的是MFC与OpenGL的结合。 2. **draw opengl** 强调了这个例子的核心是关于如何...

    OpenGL+MFC实现旋转、缩放、平移

    OpenGL和MFC(Microsoft Foundation Classes)是两种不同的技术,但它们可以协同工作来创建复杂的图形用户界面。在本项目中,我们看到一个基于VS2010的MFC应用程序,它利用OpenGL进行3D图形渲染,实现了物体的旋转、...

    MFC OpenGL画图程序

    在这个"MFC OpenGL画图程序"中,我们看到的是将OpenGL与MFC框架结合,创建一个用户界面友好且功能丰富的图形绘制工具。 首先,程序的核心在于OpenGL,它提供了基本的图形绘制功能。直线段、多边形和圆等二维图形的...

    MFC OpenGL 环境搭建

    在VS2005中,转到“工程属性”&gt;“配置属性”&gt;“C/C++”&gt;“常规”&gt;“附加包含目录”,添加OpenGL库的路径。接着,在“链接器”&gt;“输入”&gt;“附加依赖项”中,添加`OPENGL32.LIB`、`GLUT32.LIB`和`GLU32.LIB`,这些都是...

    MFC Opengl多线程框架

    OpenGL是用于渲染2D、3D图形的强大库,而MFC(Microsoft Foundation Classes)是微软提供的一个C++类库,用于构建Windows应用程序。MFC OpenGL多线程框架结合了这两个技术,允许开发者在同一个应用程序中同时处理...

    vs mfc opengl配置教程

    ### VS MFC OpenGL配置教程详解 #### 一、前言 在进行图形编程时,OpenGL 是一个非常重要的工具,它提供了强大的图形渲染能力。而 Microsoft Foundation Classes (MFC) 则是一个广泛应用于 Windows 应用程序开发的...

    opengl_mfc.rar_MFC OPENgl_MFC opengl _OpenGL MFC

    在“opengl_mfc.rar”这个压缩包中,包含了一个基于MFC的OpenGL开发框架,这是为OpenGL初学者或爱好者提供的一种基础结构,他们可以在上面进行二次开发,快速构建自己的图形应用。这表明压缩包内可能包含了实现MFC与...

    MFC OpenGL 三维模型旋转

    在MFC中用 OpenGL 实现三维模型旋转

    基于MFC单文档OpenGL打开3D模型旋转缩放

    在本文中,我们将深入探讨如何使用MFC(Microsoft Foundation Classes)单文档接口和OpenGL库来实现3D模型的加载、旋转以及缩放功能。MFC是微软提供的C++类库,用于构建Windows应用程序,而OpenGL则是一种强大的跨...

    MFC 单文档 实现opengl 三维旋转 缩放 光照

    MFC 单文档 实现opengl 三维旋转 缩放 光照MFC 单文档 实现opengl 三维旋转 缩放 光照MFC 单文档 实现opengl 三维旋转 缩放 光照MFC 单文档 实现opengl 三维旋转 缩放 光照MFC 单文档 实现opengl 三维旋转 缩放 光照...

    OpenGL实现标签云

    将OpenGL与MFC结合,可以在MFC应用中嵌入OpenGL的图形渲染功能,比如在这个案例中的标签云效果。 标签云通常用于显示大量标签或关键词,每个标签的大小和旋转角度可以反映其重要性或频率。在OpenGL中,我们可以利用...

    MFC与OpenGL的简单例子

    **MFC与OpenGL结合编程详解** MFC(Microsoft Foundation Classes)是微软提供的一个C++类库,用于构建Windows应用程序,而OpenGL则是一个跨语言、跨平台的图形编程接口,广泛应用于2D和3D图形处理。将MFC与OpenGL...

    MFC_OpenGL.rar_MFC 教程_OpenGL MFC_Opengl 教程_mfc opengl_mfc_opengl

    OpenGL是用于创建2D和3D图形的强大框架,而MFC(Microsoft Foundation Classes)是微软提供的C++类库,用于构建Windows应用程序。本教程“MFC_OpenGL.rar”结合了这两个技术,帮助初学者理解如何在MFC环境中集成并...

    MFC与OpenGL框架

    ### MFC与OpenGL框架知识点详解 #### 一、概述 MFC(Microsoft Foundation Classes)是微软为简化基于Windows的应用程序开发而提供的一套类库。它封装了大部分Win32 API,使得开发者能够更容易地创建复杂的图形...

    mfc+opengl 开发框架,有缩放、旋转、移动功能

    mfc+opengl 开发框架,有缩放、旋转、移动功能。

    MFC-OPENGL.zip_mfc opengl

    标签“mfc_opengl”进一步确认了主题,表明这个压缩包可能包含一个文档,详述了如何在MFC和OpenGL之间建立桥梁,包括配置、实例代码、以及可能出现的问题解决方案。 文档“MFC OPENGL.docx”可能提供了具体的步骤、...

    MFC_OpenGL.rar_MFC OpenGL图像_OPENGL 图像处理_mfc opengl puch

    将OpenGL与MFC结合,开发者可以在MFC应用程序中充分利用OpenGL的图形渲染能力。 在"MFC_OpenGL.rar"这个压缩包中,包含了使用MFC和OpenGL进行图像处理的VC源码。这为学习和理解如何在Windows环境下集成OpenGL提供了...

    MFC OpenGL绘图、保存

    首先,要在MFC应用中集成OpenGL,你需要创建一个继承自CWnd的类,该类将作为OpenGL渲染区域。在这个类中,你需要重写OnCreate()函数来初始化OpenGL上下文。这通常涉及设置窗口类样式,创建设备上下文(DC),并创建...

    OpenGL.rar_MFC 窗口_OpenGL MFC_mfc and opengl_mfc opengl_opengl

    在本资源“OpenGL.rar”中,我们看到的是将OpenGL集成到MFC框架中的示例,这允许开发者使用MFC的便利性来构建具有OpenGL图形功能的应用程序。 MFC窗口与OpenGL结合,可以创建一个OpenGL上下文,这是OpenGL进行渲染...

    mfc开发opengl源码

    mfc开发opengl.rar mfc开发opengl.rar

Global site tag (gtag.js) - Google Analytics