设为首页 收藏本站
| 数控仿真 | 编程软件 | 技术文章 | 数控大赛 | 斐克科技 | 公路造价 | 文档备份 |
| 幸运之门彩票网 | 彩票论坛 | 彩票新闻 | 免费招聘 | 百科问吧 | 百姓族谱 | 小游戏网 |
“武场"是京剧中的?
C#(CSharp) | VC/C++ | C++Builder | ASP(ASP.NET) | SQL Server | OpenGL | CMM | Web | NC | GIS | OS | 免费小游戏 | 彩票论坛
Google
联高软件 > 技术文章 > VB(ASP)/VB.NET > 超酷三维汉字特效
VB(ASP)/VB.NET | VC/VC++/VC.NET | C#(CSharp) | C++Builder | Java/JSP | EJB/J2EE |
超酷三维汉字特效

发表:联高软件www.legalsoft.com.cn,本文被阅读:1

大家好,我是Skyman(SM3D),喜欢三维编程,现在正在系统学习OpenGL,DirectX,VR等.我经常到各大论坛上去转转.其中去得最多的地方是NeHe的OpenGL网站(http://nehe.gamedev.net),那是我所见过的最好的学习OpenGL的网站,强烈推荐!!!这是我的第一篇关于OpenGL的文章,写得不是很好,欢迎大家指正.
大家知道,在OpenGL中输出文本有两个函数:wglUseFontBitmaps和wglUseFontOutlines,前者用来输出2维文字,后者用来输出3维文字.而要输出汉字,必须使用TrueType字体.本文就教你如何使用wglUseFontOutlines来创建很酷的三维汉字特效.从此文,你可以学到三点知识:1.如何从文件中载入位图作为纹理;2.如何生成三维汉字;3.如何将纹理贴到三维汉字上.本程序运行效果如下图所示:


我使用的是NeHe的Simple框架.为了简便起见,我这里只列出增加的代码.
首先,再头文件定义区加上:#include <stdio.h>
接着,在bool fullscreen=TRUE;后面定义要用到的变量:
GLuint texture[1];//纹理ID
int rot=0;//三维汉字绕x轴旋转的角度
HFONT hFont;//字体句柄
LOGFONT lf;//逻辑字体
GLYPHMETRICSFLOAT gmf[128];//包括字形的位置和方向信息的结构
unsigned int ichar=0; //字符的整型值
char cchar; //要转换为显示列表的字符
unsigned int i=0;//循环变量
unsigned int j=0; //循环变量
char Text[128];//存放要显示的字符的数组
BYTE TextList[128];//显示列表
const GLuint ListBase=1000; //显示列表的基
然后在LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);后面定义载入文理的函数LoadBMP和LoadGLTextures,这个在NeHe的许多教程里都有,这里再写一下:
AUX_RGBImageRec *LoadBMP(char *Filename) // 载入位图
{
FILE *File=NULL; // 文件句柄
if (!Filename) //文件名已给了吗?
{
return NULL; // 若没有则返回NULL
}
File=fopen(Filename,"r"); // 检查文件是否存在
if (File) // 文件存在吗?
{
fclose(File); // 关闭文件
return auxDIBImageLoad(Filename); // 载入位图并返回位图的指针
}
return NULL; // 若载入失败则返回NULL
}

int LoadGLTextures() // 载入位图并转换为纹理
{
int Status=FALSE; // 状态指示
AUX_RGBImageRec *TextureImage[1]; // 为纹理创建存储空间
memset(TextureImage,0,sizeof(void *)*1); // 清零
// 载入位图,检查误,如位图不存在则退出
if (TextureImage[0]=LoadBMP("Data/tex.bmp"))//纹理图片的路径
{
Status=TRUE; // 状态设为TRUE
glGenTextures(1, &texture[0]); // 创建纹理
glBindTexture(GL_TEXTURE_2D, texture[0]);
gluBuild2DMipmaps(GL_TEXTURE_2D, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);//过滤
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);//过滤
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);//自动生成纹理坐标
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);//自动生成纹理坐标
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
}
if (TextureImage[0]) // 如果纹理存在
{
if (TextureImage[0]->data) // 如果纹理图象存在
{
free(TextureImage[0]->data); // 释放纹理图象所占用的内存
}
free(TextureImage[0]); // 释放图象结构
}
return Status; // 返回状态
}
注明:因为三维字体是比较复杂的模型,所以要手工定义纹理坐标很难.我们可以让OpenGL自动生成纹理坐标.函数glTexGen()用于自动生成纹理坐标.
Void gltexgen{ifd}(GLenum coord,GLenum pname,TYPE param);
参数coord必须是GL_S,GL_T,GL_R或GL_Q,表明是否要生成纹理坐标s,t,r或q.参数pname为GL_TEXTURE_GEN_MODE,表示纹理坐标的生成模式.参数param可选GL_OBJECT_LINEAR,GL_EYE_LINEAR或GL_SPHERE_MAP. GL_OBJECT_LINEAR表示纹理图象相对于一个移动的物体静止,本程序就采用这种方式.
然后在InitGL()函数中的glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);后面加入如下语句:
glEnable(GL_LIGHT0); // 激活默认光照 (虽然光照效果不是很好但是速度快)
glEnable(GL_LIGHTING); // 激活光照
glEnable(GL_COLOR_MATERIAL);//激活材质颜色
glEnable(GL_TEXTURE_2D);//激活二维纹理
glBindTexture(GL_TEXTURE_2D, texture[0]);//绑定纹理

memset(&lf,0,sizeof(LOGFONT));//清空内存
//设定逻辑字体lf的属性
lf.lfHeight=-1;//指定字高
lf.lfWidth = -1 ;//指定字宽
lf.lfEscapement = 0 ; //指定角度(1/10度)
lf.lfOrientation = 0 ; //指定字符的基线与x轴的角度(1/10度)
lf.lfWeight = FW_BOLD ; //指定字体的重量(FW_BOLD=700)
lf.lfItalic = FALSE ;//指定是否斜体
lf.lfUnderline = FALSE ; //指定是否有下划线
lf.lfStrikeOut = FALSE ; //指定是否是StrikeOut字体
lf.lfCharSet = ANSI_CHARSET ; //指定字符集
lf.lfOutPrecision = OUT_TT_PRECIS ; //指定输出精度
lf.lfClipPrecision= CLIP_DEFAULT_PRECIS ; //指定裁剪精度
lf.lfQuality = PROOF_QUALITY ;//指定输出质量
lf.lfPitchAndFamily = VARIABLE_PITCH | TMPF_TRUETYPE | FF_MODERN ; //指定字体的定位和外观
lstrcpy (lf.lfFaceName, "宋体") ; //指定字体名称
hFont=CreateFontIndirect(&lf);//创建逻辑字体
SelectObject(hDC, hFont);//将逻辑字体选入设备环境
然后在DrawGLScene()函数中的glLoadIdentity();后面加入:
strcpy(Text,"重庆大学欢迎你");//指定所要显示的字符
i=0;//对i赋初制值
j=0;// 对j赋初制值
while(i<128)
{
if(IsDBCSLeadByte(Text[i]))//判断是否为双字节
{
ichar=Text[i];
ichar=(ichar<<8)+256; //256为汉字内码的"偏移量"
ichar=ichar+Text[i+1];
i++;i++;
wglUseFontOutlines(hDC, //设备环境句柄
ichar, //要转换为显示列表的第一个字符
1, //要转换为显示列表的字符数
1000+j, //显示列表的基数
0.0f, //指定与实际轮廓的最大偏移量
0.2f, //在Z轴负方向的值
WGL_FONT_POLYGONS, //指定显示列表用多边形创建字体
&gmf[j]); //接受字符的地址
TextList[j]=j;
j++;
}
Else//若是单字节(英文)
{
cchar=Text[i];
i++;
wglUseFontOutlines(hDC, //设备环境句柄
cchar, //要转换为显示列表的第一个字符
1, //要转换为显示列表的字符数
1000+j, //显示列表的基数
0.0f, //指定与实际轮廓的最大偏移量
0.5f, //在Z轴负方向的值
WGL_FONT_POLYGONS, //指定显示列表用多边形创建字体
&gmf[j]); //接受字符的地址
TextList[j]=j;
j++;
}
}
glListBase(ListBase);//设置显示列表的初始索引值
glTranslatef(-4.0f,0.0f,-10.0f);//要显示的文本的位置
glRotatef(float(rot),1.0f,0.0f,0.0f);//文本绕x轴旋转
glCallLists(strlen(Text),GL_UNSIGNED_BYTE,& TextList);//调用多显示列表绘制文本
glFlush();//强制绘图
rot=(rot+1)%360;//旋转变量递增
注明:1. 双字节内码DBCS(双字节字符集) 支持很多不同的东亚语言字母,如汉语、日语和朝鲜语等。 DBCS 使用数字 0–128 表示 ASCII 字符集。其它大于 128 的数字作为前导字节字符,它并不是真正的字符,只是简单的表明下一个字符属于非拉丁字符集。在 DBCS 中,ASCII 字符的长度是一个字节,而日语、朝鲜语和其它东亚字符的长度是 2 个字节。汉字内码的偏移量为256。
2.执行多显示列表可以有效的提高渲染速度。方法是将显示列表的索引值放入一个数组中,然后调用glCallLists()命令。对于有多种字体的情况,需要为每种字体建立一个不同的初始显示列表索引值。这些初始索引值可以在调用glCallLists()函数之前,通过调用glListBase()函数来指定。该函数指定一个偏移量,该偏移量被加到glCallLists()函数中的显示列表索引中,以获取最终的显示列表索引值。函数glCallLists(n,type,*lists)执行n个显示列表。所执行的列表索引值是由当前显示列表基(由glListBase()指定)指明的偏移量,加上由 lists指向的数组中的整数之和。
OK。一切搞定!编译运行,你看到了什么!不错,很酷的三维汉字特效!(注:本程序不仅可以显示汉字,也可以显示英文:))。你可以加入光照、材质、雾等效果,使它更酷!!!

 联高软件 > 技术文章 > VB(ASP)/VB.NET
·用HttpWebRequest和正则表达式提取网页中的链接 (2437)
·五种常见的ASP.NET安全缺陷 (1371)
·ASP+与ASP有什么不同 (1384)
·ASP.NET移植须知 (1306)
·在ASP.NET程序中创建唯一序号 (1343)
·ASP和ASP.NET的MD5加密中文结果不同原因 (226)
·使用ASP.NET 2.0 输出缓存替换的功能实现“甜圈缓存(Donut Caching)” (195)
·在ASP.NET中自动给URL地址加上超链接 (255)
·asp重定向 (286)
·不用 EOF 以加快记录循环(vb) (315)
 最新文章
·如何使用SQLSERVER2000中的XML功能
·超强C#图片上传,加水印,自动生成缩略图
·C#中用SYSTEM.XML读写XML说明与代码
·C#取真实IP地址及分析
·C#+DIRECT3D9.0开发实例之月亮绕着地球转
·ASP程序员学习C#之超级攻略
·通过C#实现集合类纵览.NETCOLLECTIONS及
·C#开发WAP程序实例
·C#3.0中对象初始化器和集合初始化器
·C#3.0新特性速览
·ASP和ASP.NET的MD5加密中文结果不同原因
·CSS截取固定长度字符串
·简单实用的C#分词源代码(含词库素材下载
·C#高效分页代码(不用存储过程)
·SERVER.TRANSFER是在两个页面之间进行传
·一个克隆对象的C#基类
·C#语言FTP客户端代码
·递归枚举排列、组合的C#源码
·在C#.NET中跟踪代码的运行过程
·ASP.NET2.0中实现跨页面提交
·C#通用的数据操作类
·常用的C#数据检查类
·C#中的域(FIELD)和属性(PROPERTY)
·C#编码规范和编程好习惯
·C#编码好习惯
·用C#实现C/S模式下软件自动在线升级
·C#参考之访问关键字:BASE、THIS
·C#实现遗传算法模拟花朵的进化
·用C#的类实现数据结构的堆栈算法
·在C#中应用哈希表(HASHTABLE)
·用C#生成中文汉字验证码的基本原理
·C#.NET支付宝接口
·在C#中利用SHARPZIPLIB进行文件的压缩和
·程序员必须知道的SQLSERVER数据库优化技
·360度全方位比较C#和VB
·C#设计模式之建造者(BUILDER)模式示例源
·C#抽象工厂模式的几种实现方法及比较
·用设计模式固化C#程序
·数据结构与算法(C#实现)系列---二叉树
·在C#中建立复杂的、灵活的SQL查询/命令
·解读C#中的正则表达式
·对C#开发的两个基本原则的深入讨论
·正则表达式使用高级技巧之组的概念
·模板和泛型如何配合使用
·C#中提供的VB不支持的新特性
·关于C#在LUCENE.NET下的中文切词
·无废话C#设计模式之十:FLYWEIGHT
·无废话C#设计模式之十一:COMPOSITE
·无废话C#设计模式之十二:BRIDGE
·无废话C#设计模式之十三:DECORATOR
 热门文章
·程序员必须知道的SQLSERVER数据库优化技
·OpenGL 入门教程(一)
·OpenGL基础篇
·使用回调函数(VC & Delphi)
·OpenGL 入门教程(二)
·数控加工技术试题库
·C++Builder的一些技巧
·矩阵相乘的快速算法
·如何实现进程间数据通讯技术
·数控考题(二)
·矩阵求逆的快速算法
·数控试题(一)
·第一个三角形:NeHe的OpenGL第二课
·Universal Geospatial Data Exchange
·TServerSocket和TClientSocket的使用
·地理信息系统中的常规网络分析功能及相关
·选择与反馈 (OpenGL)
·数控车床加工编程典型实例分析
·函数调用的几个概念:_stdcall,_cdecl..
·OpenGL 入门教程(三)
·OpenGL 入门教程(六)
·Dijkstra 最短路径算法的一种高效率实现
·OpenGL 入门教程(四)
·应用程序的网上升级-VB
·自己绘制True type font字体
·OpenGL 入门教程(五)
·数控车床基本坐标关系及几种对刀方法比较
·数控机床标准M代码
·OpenGL 入门教程(七)
·关于VC多文档应用中OpenGL的使用
免费小游戏
宠物连连看

真人美女换装

美女脱衣服

美女胴体猜猜看

调戏床上美女

黄金矿工
历届奥运会会徽全接触
| 幸运之门 | 免费招聘 | 小游戏网 | 百科问吧 | 国际机票 | 我的信息 | 技术文章 | 文档备份 | 公路造价软件 | 联系我们 | 广告代理 | 媒体合作 | 免责条款 |
北京联高软件开发有限公司 1999-2008© 京ICP备05034864号 工商
地址:北京市海淀区中关村北二条13号中科科仪1号楼5层 地图
电话:010-82386887 010-62343002