- 浏览: 41963 次
- 性别:
- 来自: 大连
最新评论
初识标签云是在去年年末,一看到这个应用我就特别感兴趣。还记得08年在北京做Mobile应用的时候就在想,是不是可以通过某种方式做界面扩展,让相对狭小的手机屏幕只显示有效部分,而扩展部分可以在屏幕以外,通过某种方式将他们调到屏幕以内。后来证实做这种思考的人不只是我自己,因为现在划屏应用已经是移动终端的基本应用模式了。当时也想过能不能在纵向做界面延伸,让界面深入到屏幕里面,要知道那可是无限的空间,不过没有想到什么好的方式。见到标签云的那一刻,我知道这就是我想要的,所以当时我就决定用OpenGL模拟一下,然后拿出来和大家共同探讨,看看有没有可能做成一个更成熟些应用。不过过年回来工作比较忙,所以也就搁置了。这两天刚阶段性的完成一个项目,所以得了空可以写这篇博客。
要实现功能就要先分析原理,通过使用和观察我觉得标签云的每一个标签都分布在一个球体上,球在视平面上的投影是一个圆,而整个球就根据鼠标和这个投影圆的位置关系不同而旋转。鼠标离圆心越远转速愉快,反之则越慢。球体旋转是围绕一根通过球心且与视平面平行的转轴进行的,鼠标和投影圆圆心的位置关系同样控制者转轴的方向,那就是转轴垂直于投影圆圆心和鼠标的连线。最后一点,旋转过程总是迎着鼠标进行。
知道了基本原理就要开始分析算法了,实现三维空间用OpenGL这自不必说,我曾经写过一篇日志《OpenGL控件》介绍了一个内置OpenGL基本框架环境的自定义控件,这次就是极基于这个控件的一个扩展应用。我还曾经在《三维向量类》一文中介绍过我自己写的一个进行三维程序设计时很实用的向量类CVector,当然这次建模还是要依靠它。唯一的问题是OpenGL对于中文支持的不好,有没有什么方法可以方便的显示中文呢?我这里采用的方法是在内存中生成一张文字的贴图,然后用Alpha混合的方式赋予一个plan,这样就可以利用系统字库在OpenGL中显示各种类型丰富的文字了。好了,主要问题都解决了,开始写代码。
首先定义一个结构体来代表标签元中的一个标签:
这个函数是生成标签的核心函数,在程序里标签表现出来的形式就是文本,所以函数支持对文本的几乎一切定制,这包括内容、颜色、字体、字号、样式等。函数首先会创建一个字体,然后根据文本内容需要的大小创建一个内存位图,将文字绘制于这个位图之上。准备好文字的位图就要通过它来制作材质了,这里有一个问题,位图是没有Alpha通道的,怎么办呢,有没有什么相对简单的方法处理呢?这里我的处理方法是这样的,看代码,通过GetBitmap获取位图信息然后观察bmData.bmWidth和bmData.bmWidthBytes的值,可以发现bmWidthBytes是bmWidth的四倍。原来位图在内存里是以RGBA的方式存储的,所以通过GetBitmapBits获取到的数据就是4位的。众所周知,内存位图创建时是黑色的,这里我认定标签文字不能为黑色,所以检测数据如果是黑色的就把Alpha设为透明,不是就设为不透明,然后创建贴图。最后设置向量,在一个范围内随机生成一个长度做一个指向屏幕外的向量,在以x、y、z三个轴随机旋转一个角度,这样就完成了一个标签的建模。
渲染的部分很简单,就是常规的OpenGL绘制,只不过加上了材质设置了Alpha透明。其实这个Demo做的比较粗糙,文字周围存在黑边,不过做这个例子不是特别追求表现所以也就没有特别处理,代码如下:
CWnd::OnTimer(nIDEvent);
} 到此基本的功能就已经全部实现了,在我的资源里上传了这个Demo有兴趣朋友可以下载研究一下,有什么好的想法可以和我进一步交流。做这个东西,写这篇文章权当抛砖引玉,希望能给大家些灵感,从三维的角度作出有更好用户体验的界面设计。最后贴一个效果图,见笑见笑。
[img][/img]
转(http://blog.csdn.net/xianglitian/article/details/6590687)
要实现功能就要先分析原理,通过使用和观察我觉得标签云的每一个标签都分布在一个球体上,球在视平面上的投影是一个圆,而整个球就根据鼠标和这个投影圆的位置关系不同而旋转。鼠标离圆心越远转速愉快,反之则越慢。球体旋转是围绕一根通过球心且与视平面平行的转轴进行的,鼠标和投影圆圆心的位置关系同样控制者转轴的方向,那就是转轴垂直于投影圆圆心和鼠标的连线。最后一点,旋转过程总是迎着鼠标进行。
知道了基本原理就要开始分析算法了,实现三维空间用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)
发表评论
-
c++操作符优先级总结
2013-12-03 14:47 792优先级从上到下依次递减,最上面具有最高的优先级,逗号操作符具有 ... -
Qt状态机实例
2013-12-03 14:01 1099#include <QApplication> ... -
c++数据类型的隐形转换
2013-09-02 09:51 1676(1)隐式转换发生的时机:当传递给操作符或者函数的参数与指定类 ... -
C中的野指针
2013-08-30 16:11 1048讨论一 什么是野指针 ... -
STL学习(转)
2012-08-28 15:38 1440STL就是Standard Template Libr ... -
STL详解
2012-08-28 14:33 1748STL概述 STL的一个重要 ... -
c++的三种继承(转)
2012-08-23 18:47 1084http://blog.csdn.net/wang_lime ... -
MFC中ADO方式操作数据库实例(转)
2012-08-22 11:12 2440连接ACCESS为例: //头文件 #pragma on ... -
派生类的构造函数(转)
2012-08-20 18:05 989派生类的数据成员由所 ... -
元算符重载时友元函数和成员函数的选择
2012-08-18 20:14 1411一般情况下,单目运算符最好重载为类的成员函数;双目运算符则最好 ... -
C++面试题(转)
2012-08-16 17:25 8171.是不是一个父类写了一个virtual 函数,如果子类覆盖它 ... -
8皇后问题c++的递归实现
2012-08-16 16:18 1494最近用C++递归形式实现了8皇后问题,可能效率有点低 #i ... -
c++实现的一些排序算法
2012-08-15 11:37 1389最近用c++简单实现了一些排序算法,记下来,以便以后用到 ... -
mfc 常用控件使用方法及常见数据类型转换
2012-04-18 20:31 2098最近做了几个mfc小程序,想把我们经常用到而又经常忘记的的小知 ...
相关推荐
在标签中,“mfc__opengl__ opengl_mfc draw opengl__mfc opengl__vrml”提到了几个关键点: 1. **mfc__opengl** 和 **opengl_mfc** 指的是MFC与OpenGL的结合。 2. **draw opengl** 强调了这个例子的核心是关于如何...
在这个"MFC OpenGL画图程序"中,我们看到的是将OpenGL与MFC框架结合,创建一个用户界面友好且功能丰富的图形绘制工具。 首先,程序的核心在于OpenGL,它提供了基本的图形绘制功能。直线段、多边形和圆等二维图形的...
在VS2005中,转到“工程属性”>“配置属性”>“C/C++”>“常规”>“附加包含目录”,添加OpenGL库的路径。接着,在“链接器”>“输入”>“附加依赖项”中,添加`OPENGL32.LIB`、`GLUT32.LIB`和`GLU32.LIB`,这些都是...
OpenGL是用于渲染2D、3D图形的强大库,而MFC(Microsoft Foundation Classes)是微软提供的一个C++类库,用于构建Windows应用程序。MFC OpenGL多线程框架结合了这两个技术,允许开发者在同一个应用程序中同时处理...
### VS MFC OpenGL配置教程详解 #### 一、前言 在进行图形编程时,OpenGL 是一个非常重要的工具,它提供了强大的图形渲染能力。而 Microsoft Foundation Classes (MFC) 则是一个广泛应用于 Windows 应用程序开发的...
在“opengl_mfc.rar”这个压缩包中,包含了一个基于MFC的OpenGL开发框架,这是为OpenGL初学者或爱好者提供的一种基础结构,他们可以在上面进行二次开发,快速构建自己的图形应用。这表明压缩包内可能包含了实现MFC与...
在MFC中用 OpenGL 实现三维模型旋转
在本文中,我们将深入探讨如何使用MFC(Microsoft Foundation Classes)单文档接口和OpenGL库来实现3D模型的加载、旋转以及缩放功能。MFC是微软提供的C++类库,用于构建Windows应用程序,而OpenGL则是一种强大的跨...
OpenGL和MFC(Microsoft Foundation Classes)是两种不同的技术,但它们可以协同工作来创建复杂的图形用户界面。在本项目中,我们看到一个基于VS2010的MFC应用程序,它利用OpenGL进行3D图形渲染,实现了物体的旋转、...
MFC 单文档 实现opengl 三维旋转 缩放 光照MFC 单文档 实现opengl 三维旋转 缩放 光照MFC 单文档 实现opengl 三维旋转 缩放 光照MFC 单文档 实现opengl 三维旋转 缩放 光照MFC 单文档 实现opengl 三维旋转 缩放 光照...
将OpenGL与MFC结合,可以在MFC应用中嵌入OpenGL的图形渲染功能,比如在这个案例中的标签云效果。 标签云通常用于显示大量标签或关键词,每个标签的大小和旋转角度可以反映其重要性或频率。在OpenGL中,我们可以利用...
**MFC与OpenGL结合编程详解** MFC(Microsoft Foundation Classes)是微软提供的一个C++类库,用于构建Windows应用程序,而OpenGL则是一个跨语言、跨平台的图形编程接口,广泛应用于2D和3D图形处理。将MFC与OpenGL...
OpenGL是用于创建2D和3D图形的强大框架,而MFC(Microsoft Foundation Classes)是微软提供的C++类库,用于构建Windows应用程序。本教程“MFC_OpenGL.rar”结合了这两个技术,帮助初学者理解如何在MFC环境中集成并...
### MFC与OpenGL框架知识点详解 #### 一、概述 MFC(Microsoft Foundation Classes)是微软为简化基于Windows的应用程序开发而提供的一套类库。它封装了大部分Win32 API,使得开发者能够更容易地创建复杂的图形...
mfc+opengl 开发框架,有缩放、旋转、移动功能。
标签“mfc_opengl”进一步确认了主题,表明这个压缩包可能包含一个文档,详述了如何在MFC和OpenGL之间建立桥梁,包括配置、实例代码、以及可能出现的问题解决方案。 文档“MFC OPENGL.docx”可能提供了具体的步骤、...
将OpenGL与MFC结合,开发者可以在MFC应用程序中充分利用OpenGL的图形渲染能力。 在"MFC_OpenGL.rar"这个压缩包中,包含了使用MFC和OpenGL进行图像处理的VC源码。这为学习和理解如何在Windows环境下集成OpenGL提供了...
首先,要在MFC应用中集成OpenGL,你需要创建一个继承自CWnd的类,该类将作为OpenGL渲染区域。在这个类中,你需要重写OnCreate()函数来初始化OpenGL上下文。这通常涉及设置窗口类样式,创建设备上下文(DC),并创建...
在本资源“OpenGL.rar”中,我们看到的是将OpenGL集成到MFC框架中的示例,这允许开发者使用MFC的便利性来构建具有OpenGL图形功能的应用程序。 MFC窗口与OpenGL结合,可以创建一个OpenGL上下文,这是OpenGL进行渲染...
mfc开发opengl.rar mfc开发opengl.rar