www.gusucode.com > VC++制作3D效果的旋转文字特效源码程序 > VC++制作3D效果的旋转文字特效源码程序\code\HzGL.cpp
// HzGL.cpp: implementation of the CHzGL class. // Download by http://www.NewXing.com ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "HzGL.h" #include <gl\gl.h> #include <gl\glu.h> #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CHzGL::CHzGL() { m_iDisplayListStart1=1000; m_iDisplayListStart2=2000; m_angle.cx = 0 ;//向下旋转角度初值 m_angle.cy = 0 ;//左右旋转角度初值 m_theString = "电脑编程技巧" ; m_String="电脑编程"; } bool CHzGL::Create(CWnd* pWnd) { int iPixelType= PFD_TYPE_RGBA; DWORD dwFlags= PFD_DOUBLEBUFFER | // 使用双缓冲区 PFD_SUPPORT_OPENGL | // 使用 OpenGL PFD_DRAW_TO_WINDOW; // 窗口象数格式 //描述图形表面象数格式结构 PIXELFORMATDESCRIPTOR pfd ; memset(&pfd,0, sizeof(PIXELFORMATDESCRIPTOR)) ; pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); pfd.nVersion = 1 ; // 版本号 pfd.dwFlags = dwFlags ; //象数缓冲区属性 pfd.iPixelType = iPixelType ; pfd.cColorBits = 24 ; // 24 位颜色 pfd.cDepthBits = 32 ; // 32-bit 颜色浓度缓冲区 pfd.iLayerType = PFD_MAIN_PLANE ; // Layer type m_pdc = new CClientDC(pWnd); //创建TrueType字体,根据实现需要,可用楷体、琥珀等字体 LOGFONT lf; m_pdc->GetCurrentFont()->GetLogFont(&lf); lf.lfCharSet=134; strcpy(lf.lfFaceName, "黑体") ; fontOpenGL1.CreateFontIndirect(&lf); strcpy(lf.lfFaceName, "宋体") ; fontOpenGL2.CreateFontIndirect(&lf); //选择与设备描述符(DC)接近的像素格式 int nPixelFormat = ChoosePixelFormat(m_pdc->m_hDC, &pfd); if (nPixelFormat == 0) { AfxMessageBox("ChoosePixelFormat Failed %d\r\n",GetLastError()) ; return false; } // 设置与设备描述符(DC)接近的像素格式 BOOL bResult = SetPixelFormat(m_pdc->m_hDC, nPixelFormat, &pfd); if (!bResult) { AfxMessageBox("SetPixelFormat Failed %d\r\n",GetLastError()) ; return false; } // // 创建OpenGL绘图上下文-图形操作描述符(rendering context) // m_hrc = wglCreateContext(m_pdc->m_hDC); if (!m_hrc) { AfxMessageBox("wglCreateContext Failed %x\r\n", GetLastError()) ; return false; } //指定rendering context if(!wglMakeCurrent(m_pdc->m_hDC, m_hrc)) { AfxMessageBox("wglMakeCurrent Failed %x\r\n", GetLastError()) ; return false; } //调用成员私有函数-OpenGL初始化 if(OnInit()) return true; else return false; } bool CHzGL::OnInit() { // 允许颜色浓度 glEnable(GL_DEPTH_TEST); // 设置前颜色为材料颜色 glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE) ; glEnable(GL_COLOR_MATERIAL) ; // 设置光线位置 float fLightPosition[3] = {-1.0f, -1.0f, 1.0f} ; glLightfv(GL_LIGHT0, GL_POSITION, fLightPosition) ; // 允许计算光源 glEnable(GL_LIGHTING) ; glEnable(GL_LIGHT0) ; // 设置屏幕底色 glClearColor(0.0f, 0.0f, 0.0f, 0.0f) ;//设置底色为黑色 //glClearColor(1.0f, 1.0f, 1.0f, 0.0f) ;//设置底色为白色 Create3DFont(); return true ; } void CHzGL::Create3DFont() { int i=0; CFont* pOldFont=(CFont*)m_pdc->SelectObject(&fontOpenGL1); // 产生显示列表. unsigned int j=0; i=0; j=0; while(i< m_theString.GetLength()) { if (IsDBCSLeadByte(m_theString[i])){ //判 断 是 否 为 双 字 节 wglUseFontOutlines(m_pdc->m_hDC, // 所选字体的设备描述符 (256+m_theString[i])*256+(256+m_theString[i+1]),// 要转换为显示列表的第一个字符 1, // 转换为显示列表的字符个数 m_iDisplayListStart1+j, // 指定的显示列表基数 0.0,// 指定的最大偏离值,一般为0 0.15f, // 它是立体字体具体表现,Z轴(纵深方向)方向的值 WGL_FONT_POLYGONS,// 显示的字体轮廓线格式,多边形-实心 &m_agmf1[j]); // 接受字符特性 FTextList[j]=j; j++; i++;i++; } else{ wglUseFontOutlines(m_pdc->m_hDC, // 所选字体的设备描述符 m_theString[i], // 要转换为显示列表的第一个字符 1, // 转换为显示列表的字符个数 m_iDisplayListStart1+j, // 指定的显示列表基数 0.0,// 指定的最大偏离值,一般为0 0.15f, // 它是立体字体具体表现,Z轴(纵深方向)方向的值 WGL_FONT_POLYGONS,// 显示的字体轮廓线格式,多边形-实心 &m_agmf1[j]); // 接受字符特性 FTextList[j]=j; i++; j++; } } m_pdc->SelectObject(&fontOpenGL2); i=0; j=0; while(i<m_String.GetLength()) { if (IsDBCSLeadByte(m_String[i])){ ///判 断 是 否 为 双 字 节 wglUseFontOutlines(m_pdc->m_hDC,// 所选字体的设备描述符 (256+m_theString[i])*256+(256+m_theString[i+1]),// 要转换为显示列表的第一个字符 1, // 转换为显示列表的字符个数 m_iDisplayListStart2+j, // 指定的显示列表基数 0.0,// 指定的最大偏离值,一般为0 0.15f, // 它是立体字体具体表现,Z轴(纵深方向)方向的值 WGL_FONT_POLYGONS,// 显示的字体轮廓线格式,多边形-实心 &m_agmf2[j]); // 接受字符特性 FTextList[j]=j; j++; i++;i++; } else{ wglUseFontOutlines(m_pdc->m_hDC, // 所选字体的设备描述符 m_theString[i], // 要转换为显示列表的第一个字符 1, // 转换为显示列表的字符个数 m_iDisplayListStart2+j, // 指定的显示列表基数 0.0,// 指定的最大偏离值,一般为0 0.15f, // 它是立体字体具体表现,Z轴(纵深方向)方向的值 WGL_FONT_POLYGONS,// 显示的字体轮廓线格式,多边形-实心 &m_agmf2[j]); // 接受字符特性 FTextList[j]=j; i++; j++; } } if (pOldFont) m_pdc->SelectObject(pOldFont) ; } CHzGL::~CHzGL() { if (m_hrc) { // 删除图形操作描述符 if (m_hrc == wglGetCurrentContext()) wglMakeCurrent(NULL,NULL) ; wglDeleteContext(m_hrc) ; m_hrc = NULL ; } delete m_pdc; } bool CHzGL::Render() { // Make the HGLRC current wglMakeCurrent(m_pdc->m_hDC, m_hrc); //第一个字符串颜色 static GLdouble purple[3] = {2, 1, 1 } ; //第二个字符串四个字体不同颜色 static GLubyte byPink[3] = {196, 0, 196} ; static GLubyte byTeal[3] = {0, 153, 168} ; static GLubyte byBlue[3] = {42, 38, 215} ; static GLubyte byGreen[3] = {0, 171, 82} ; // Clear the color and depth buffers glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //显示第一行汉字 glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslated(-3.10,0.9,-7.0 );//字体位置X,Y,字体大小 glRotated(m_angle.cx, 1, 0, 0);// 旋转角度X,Y,Z glColor3dv(purple) ; glListBase(m_iDisplayListStart1); glCallLists(m_theString.GetLength(),GL_UNSIGNED_BYTE,&FTextList); //显示第二行汉字 double widthMN = (m_agmf2[0].gmfCellIncX + m_agmf2[3].gmfCellIncX) * 0.5 ; glLoadIdentity(); glTranslated(0.0, -0.65, -3.0 ); glRotated(m_angle.cy, 0.0, 1.0, 0.0); glTranslated(-widthMN, 0.0, 0.0) ; glScaled(0.5, 0.5, 0.5) ; glColor3ubv(byPink) ; glCallList(m_iDisplayListStart2) ; glColor3ubv(byTeal) ; glCallList(m_iDisplayListStart2+1) ; glColor3ubv(byBlue) ; glCallList(m_iDisplayListStart2+2) ; glColor3ubv(byGreen) ; glCallList(m_iDisplayListStart2+3) ; glFlush() ; GdiFlush() ; SwapBuffers(m_pdc->m_hDC) ; GdiFlush() ; spin();//调用成员私有函数—旋转增量 return true; } BOOL CHzGL::OnResize(int cx, int cy) { GLdouble gldAspect = (GLdouble) cx/ (GLdouble) cy; glMatrixMode(GL_PROJECTION); glLoadIdentity(); //设置透视发射矩阵 gluPerspective(30.0, gldAspect, 1.0, 10.0); glViewport(0, 0, cx, cy); return TRUE ; } BOOL CHzGL::spin()//旋转函数 { m_angle.cx += 10 ; m_angle.cy += 10 ; if (m_angle.cx >= 360) m_angle.cx = 0 ; if (m_angle.cy >= 360) m_angle.cy = 0 ; }