??xml version="1.0" encoding="utf-8" standalone="yes"?>
在程序用Dll有两个加载方式,一U是动态方式,是LoadLibrary载入Dll,然后用GetProcAddress来加载需要用的Dll函数。另一U就是静态连接方式,dll生成的libQ加入到工程中,然后可以很方便的调用?/p>
我们知道很多dll在发布时不提供libQ没有lib我们׃能静态的加蝲Q所以得惛_法来生成一个libQ在vs2005中有q样的一个命?/p>
不过我们q需要一个def文gQ怎样来获得一个def文g哪?
我们知道def是一个库导出文g 单的格式是:EXPORTS ?一些导出函?/p>
我们可以用vc6自带的一个depends来查看dll中有哪些导出函数Q来手动做一?def文g
xxx.dll和xxx.defQ放C个文件夹中,启动“Visual Studio 2005 命o提示”
工作目录切换到放有xxx.dll和xxx.def的文件夹中输入:
q样会产生一个xxx.lib了,此lib文g和dll文g拷到工程中,可以进行静态链接了
最q一D|间不是很忙,写了一个自q游戏服务器框枉形,很多地方q不够完善,但是基本上也是能够跑v来了。我先从上层l构说vQ一直到实现l节吧,惌v什么就写什么?/p>
W一部分 服务器逻辑
服务器这边简单的分ؓ三个部分Q客L的连接首先到辄x务器Q网兌里有个线E用来监听来自与客户端的q接Q然后在这些数据发送到游戏逻辑服务器上Q这个逻辑游戏服务器上Q数据的交互是通过与数据服务器q行交互。RecordServer专门用来处理与数据库的连接,查询q些事情。当然ؓ了游戏服务器能够最大程度的不卡Q肯定就得规定好|关服务器上的连接数量,免得像我们号U流畅的铁道部订网l一样做个卡BQ想想玩一局dota被卡的悲剧吧。当我们要做一个大型网游时Q这三个服务器显然不够。当然在自己写的游戏的时候就无所谓了Q几个服务器全部架设在自q破笔记本上,不就是启动几个程序而已?/p>
q个感觉写得差不多了,到细节吧?/p>
W二部分 实现l节
q个比较ؕ了,雉散散的,随便写了。这里很多都是对各种工具的封装,以便于自?在项目的使用
1.make
目q么多目录,q么多子目录Q肯定得用工具去~译了,使用aclocal,automake,autoconf,make,把我们的程序编译好了,~写自己configure.in文gQ定义编译选项、链接库{等一pd׃八糟的东西,然后Ҏ个需要编译的子项目编写Makefile.am,有的需要要~译成库的,比如base{基c这些,其他的都~译成可执行文g了,GatewayServer,LogicalServer,RecordServer?/p>
2.套接字封装,epoll使用
linux里,我们使用socket来读写网l上的数据,q个很简单了Qgateway上一个客Lq接q来Q我们就为它分配一个socket 描述W了Q在|关上,一个线E用来accept,一个线E用来做数据的处理,当accept一个连接请求后Q放到数据处理的U程Q接受到一个数据,然后直接转发到logical server上,我们使用epoll_waitQ来处理套接上的d处理。每n ms处理一ơ@环,每次循环中用一ơepoll_waitQ一ơ把q些有事件的socket取出来?/p>
3.数据加密解密Q压~解?/p>
对网l上的数据,Z保证安全性,必须对它们进行加密解密处理,q个单了Q网上各U内容,q里׃说了Q全部写完了Q有旉再写Q。对数据q行压羃Q能减少带宽吞吐Q就是简单的调用几个zlib函数的调用,不细_在前面{发的《zlib使用》中有讲Q发现自己太懒,实在是懒得打字了?/p>
4.U程装Q互斥量Q读写锁
q些都是单的使用RAII或其他方式,对这些东西进行一ơ本地封装。(应该得写一个线E池ȝ理这些线E,todoQ?/p>
5.数据库封?/p>
使用mysql,使用mysql的C API函数Q这个必d装一下,不是每次数据的处理,都得d很多事情Q实C个本地的数据的Field(?,RecordQ记录),TableQ表Q?DataBaseQ数据库Q?RecordSet(查询l果?。制作一个数据库q接句柄MysqlHandleQ处理对数据库的q接Q处理等Q实C个HandlerPool,Q每ơ从Pool中取Z个句柄来Ҏ据库q行查询Q免得每ơ都去重新连接,什么的?/p>
6.自己的内存池
在之前分享的文章中《内存池技术详解》《编写自q内存分配器》,自己的《内存池应用》,已经很详l的说明了,内存池的制作Q当然我在这里还是有一些改动的Q但是大概思\是q些了?/p>
7.有一个状态机的实?/p>
q个也在自己之前写的那个状态机相关的文章里Q也做记录了。哈哈,实在是不想l码字了Q但是还是坚持下厅R?/p>
8.lua与c++交互框架
q个暂时写了一半,{全部完成了Q再来弄Q反正就是像npc处理q些Q脚本处理这些,使用tolua++?/p>
9.tinyxml装Q正则表辑ּ装
tinyxml一个轻量的xml解析器,很简单,反正是把q些现成的东西拿来自q。正则表辑ּ没有q入c++标准Q但是还是很多现成的正则表达式的处理Q直接用linux库下的regex.h,是~译正则表达式,匚wl果q些Q?/p>
10.logpȝ
一个项目怎么能没有自q日志pȝ呢,反正是打日志,往文g里面写东西,用std::fstreamL搞定Q定义好日志U别:error / debug / fatel / infoq些
11.旉装
q个必须有,否则自己q每ơ去调用get_clocktime,gmtime,time各种函数呀?/p>
12.使用boost库里的,Noncopyable,Singletonq些设计ҎQ来写我们的代码
13.定义好各U信号句柄,信号发生旉用什么策略,如SIGPIPEQ做忽略处理
待箋。。。。。。。。(睡觉了)
游戏服务器技术应该算来已l很成熟了,相比客户端,它的技术更新速度很慢了。客Lq边Q技术很多,各种游戏引擎比如3D的虚q这些,什么粒子引擎,声音q些Q页游的flash, html5,utility,Q太多了Q搞不过来呀。我先把服务器这边好好专专,其他的等以后再说吧?/p>
惌v写这文章是在看侯杰先生的《深入浅出MFC》时, H然觉得自己在大学这几年关于游戏~程斚wq算是有些心得,因此写出q篇文,介绍我眼中的游戏E序 员的书单与源代码参考。一则是作ؓ自己今后两年学习目标的备忘录,二来没准对别Z有点参考h倹{我的原则是只写自己研究q或准备研究的资料,所以内Ҏ 疑会带上强烈的个人喜好色? 比如对网l?数据库等重要斚w完全没有涉及。因׃要对三维囑Ş引擎, 人工法, 脚本pȝ, 反外?(反反外挂? ^Q^){方面感兴趣。这学期电脑都没联网?在岳麓山闭关修炼?^Q^),q这文章都得在学校图书馆电子阅览室Q电影放映室Q)上传,内容很多凭记忆写? 如有误差敬请订正。程序员应该在理论学习与实践~程中反复P代,所以学习资料是一回事Q须知尽信书不如无书?/p>
一、书c:
法与数据结构:
《数据结构(C语言版)?#8212;—严蔚敏、吴伟民 清华出版C?/p>
我觉得其配套习题集甚x原书更有价|每个较难的题都值得做一下?/p>
《Introduction to Algorithms》第二版 中文名《算法导论?/p>
?于算法的标准学习教材与工E参考手册,在去qCSDN|站上其译版竟然评为年度二十大技术畅销书,同时《程序员》杂志上开设了“法擂台”栏目Q这些溯 源固本的丑֊Q不由得使h对中国现今Qw不堪的所?#8220;IT”业又产生了一U希望。这本厚厚的书,q怺打折我才买得赗虽然厚辑֍,但其英文通俗晓畅Q内 Ҏ入浅出,可见l典之作往往比一般水准的书还耐读。还能找到MIT的视频教E,W一节课那个老教授嘻皮笑脸的Q后面就是一长发助教上课了?/p>
《C语言名题_N百?技巧篇?#8212;—冼镜?机械工业出版C?/p>
?者花费一q时间搜集了各种常见CE序D늚极具技巧性的~程法,其内定w是大有来头的Q而且l出了详l的参考资料。如一个普通的Fibonacci数就l出 了非递归解、快速算法、扩充算法等Q步步深入,直至几无Ҏ可榨。对于视速度如生命,q一个普通的点数{化ؓ整数都另辟蹊径以减少CPU cycle的游戏程序员Q怎可不看Q?/p>
《计机法基础Q第二版Q?#8212;— 佘祥宣等 华中U大出版C?/p>
我看到几个学校的研究生拿它作教材Q研I生才开法Q太开玩笑了吧Q。这本书薄是薄了点,用作者的话来_倒也“_辟”。其实此书是《Fundamentals of Computer Algorithms》的~写版,不过原书出版太久了,反正我是没找到?/p>
《The Art of Computer Programming》Volume 1-3
?者Donald E. Knuth是我心目中与?Z曹{Dijkstra、Shannonq列的四位大师。这本书作者从d学本U时开始写Q一直写到博士时Q十q磨一剑,?见其下了功夫。可作ؓ计算机技术的核心——法与数据结构的l极参考手册。创新处也颇多,譬如常见的Shell排序他在书中提出可用(3i-1)/2?间隔Q这使其E快于O(n1. 5)。当然这套书描述高度数学化,为此恐怕一般的人(我?Q最好还得先看一本数学预备书《Concrete Mathematics》(直译为凝土数学Q^Q^Q再说。可惜的是这套书才出到第三卷Qƈ没有覆盖全部常见的算法内宏V不q好在对于游戏程序员来说Q?常见的法用得多Q这也不是什么要命的损失?/p>
《STL源码剖析?#8212;— 侯捷 华中U大出版C?/p>
?捷不用介l了Q华人技术作家中的旗舎ͼ说其有世界水准也不。这本书我以为是C++与数据结构的葵花宝典Q欲l此功,必先自宫Q。也是_不下几层 地狱很难看懂Q因为它要求的预备知识太多了Q如STL、数据结构、泛型编E、内存管理都要很扎实Qؓ此是不是q要看看有内存管理设计模式之U的 《Small Memory Software》这本书呢?Q,但是一旦看懂,真会是所向披靡?/p>
《Data Structures for Game Programmers?/p>
每个数据l构的例E都是一个小游戏Q还用SDL库实C一个算法演C系l。虽然内容失之于,但v码让Z解了数据l构在游戏中的作用?/p>
?实游戏程序ƈ不比其它E序ҎQ甚臌求基本功更加扎实Q所以花旉做一些看g实际应用不甚相干的习题,对今后的工作是大有裨益的。而且有些应用很广?法Q如常被人|z乐道的A*法及其变种Q牵涉到囄索周怸分枝-限界法,恐怕还得读一些艰q论文才能充分明白q用Q如Donald E. Knuth的《An analysis of alpha-beta cutoffs》。其实还有不此cȝ好书Q如《Data Structures and Algorithms in C++》、《Programming Pearls》、《More Programming Pearls》(法珠玑Q等Q我却以先看严}一点的著作Q再看内定wW一点的书?/p>
汇编Q?/p>
《IBM-PC 汇编语言E序设计》第二版
国内l典教材?/p>
《The Art of Assembly Language?/p>
q本书?600,噢!
C语言Q?/p>
《The C Programming Language》第二版
虽然幅短小Q但每个例程都很l典。(我们老师开始拿它作教材Q后面换K强的C语言书,理由为:例子是些文本处理。我q了闷了,NC的计机E序不是大量时间消耗在字符串与文本的处理上吗?Q?/p>
C++Q?/p>
学过C语言Q再学C++Q先看这本《C++ Primer》的~写版:
《Essential C++?/p>
对C++有个入门了解Q再?/p>
《C++ Common Knowledge: Essential Intermediate Programming?/p>
׃会有什么重要的知识点完全不知所措了Q接下来?/p>
《The C++ Standard Library : A Tutorial and Reference?/p>
标准库,当然主要是标准模板库的标准学习参考手册,然后最好^时边写程序边参悟?/p>
《Effective C++》等
我是说书名以形容?+ C++的那些书Q计有七八本Q慢慢看吧,|马不是一日徏成的?/p>
(《Essential C++》、《Effective C++》、《More Effective C++》、《Accelerated C++》、《Effective STL》、《Exceptional C++》、《More Exceptional C++》、《Imperfect C++》,虽然书名格式怼Q但每一本都l非马虎之作?
谁说C++E序比CE序要慢Q那p看下面:
《The Design and Evolution of C++?/p>
知其q去才能知其未来Q才能应用?/p>
《Inside the C++ Object Model?/p>
揭露C++的编译器模型?/p>
《Efficient C++ Performance Programming Techniques?/p>
当算法优化已到极_在运用汇~之前,最后还可看看此书,有时高和低阉能做成相同的事情?/p>
q有两本特别的书Q?/p>
《Modern C++ Design : Generic Programming and Design Patterns Applied?/p>
作者想把设计模式和泛型~程l合hQƈ写了个尝试提供一切的Loki库来实作,不过其观点ƈ未得到C++C的普遍响应。尽如此,本书仍称得上思想前沿性与技术实用性结合的典范?/p>
《C++ Template Metaprogramming?/p>
?~译器当作计器Q本书介l了Boost库的MPL模板元编E库。当然提到Boost库,对于游戏E序员不能不提到其中的Graph库,有《The Boost Graph Library》一书可看。还有其中Python库,L国内首款商业三维囑Ş引擎的v点引擎就用了BoostQPython库。说实话我觉得v点引擎还 是蛮不错的,那个自制的三l编辑器虽然界面陋,但功能还蛮完善Q给游戏学院用作教学内容也不错。另有一个号UC国首ƾ自ȝ发的全套|游解决Ҏ。我 看到它那个三l编辑器Q心惌不就是国外一个叫freeworld3D的编辑器吗?虽然有点偏门Q但我以前还较劲试破解q呢。还把英文界面汉化了Q大?用exescopeq样的资源修改Y件就能搞定吧。我又心想ؓ什么要找freeworld3Dq个功能q不太强大的~辑器呢Q仅仅是因ؓ它便宜到几十?金?它唯一特别一点的地方是支持导出OGRE囑Ş引擎的场景格式,q样一想不由得使h对它囑Ş引擎?#8220;自主”性也产生怀疑了。这L“自主”研发真让?汗颜Q只要中国还没封sourceforgeq个|站Q据说以前和freeBSD|站一赯过Q)Q国人就?#8220;自主”研发?/p>
有hq会推荐《C++ Primer》《Thinking in C++》《The C++ Programming Language》等书吧Q诚然这些书也很好,但我总觉得它们太大部头了。还不如多花Ҏ间看看国外好的源代码?/p>
Windows~程
《Operating System Concepts》第五版
国内有些操作pȝ的教E其实就是它的羃写版?/p>
《Windows 95 System Programming Secrets?/p>
深入剖析了Windows操作pȝ的种U种U,有hq《Linux内核完全注释》,有hq《自己动手写操作pȝ》这L情的书,但我想作为商业的操作pȝQ把Windows内核剖析到这地步也高׃Ԓ止了?/p>
《Programming Applications for Microsoft Windows》第四版
先进E线E,再虚存管理,再动态链接库Q最多讲到消息机制。作者在序言中说Q?#8220;我不讲什么ActiveX, COM{等Q因为当你了解了q些基础后,那些东西很快׃明白Q?#8221;可以作ؓ《Programming Windows》的先修课?/p>
计算Zp:
《Computer Systems : A Programmer’s Perspective?/p>
和《The Art of Computer Programming》在我心中是计算机史上两本称得上伟大的书Q计机l成原理Q操作系l,汇编Q编译原理,计算机网l等{课E汇成这本千늚大书Q因机在作者眼中就是一个整体?/p>
开源阅读:
《Code Reading : The Open Source Perspective?/p>
张大千摹了几百张明代石涛的山水Q画出的M假ؕ真,后来他去敦煌潜心临摹几年Q回来画风大变,l成大家。程序员其实? 0%的时间是在读别h的源代码Q侯捷先生说Q?#8220;源码面前Q了无秘?#8221;Q又?#8220;天下大事Q必作于l?#8221;Q可以与他的《上IL落下黄泉Q源码追t经验谈》参看?/p>
MFC:
《深入浅出MFC?/p>
?实在以ؓ没有看过侯捷先生的《深入浅出MFC》的人多半不会懂得MFC~程。其实我是打用一q多的时间写一个给游戏工用的三维~辑器,Z作ؓ毕业?计。图形库qMFC吧,反正也没得选择。如果要用wxWidgets无非是猎奇而已Q还不是MFC的翻版,当然它跨q_了。就象阻L对自己枪械的零g 了如指掌一P要想用MFC写出非玩L序的Z定要了解其内部构造。还有一本书叫《MFC深入出》,q不是同一本?/p>
IDE:
《Microsoft Visual Studio 2005 Unleashed?/p>
工欲善其事,必先利其器。当然我认ؓ与其用Ş如Source Insight、Slick Edit、Code Visualizer之类的代码阅d、图形化工具Q还不如用自q大脑。但如果你嫌打源代码慢的话,可以用Visual AssistX。如果嫌老是写重复相似的代码的话Q可以用Code Smith。单元测试可以用CppUnitQBoost库中的测试框架也不错。有心情可以吧Visual Studio外接Intel的CompilerQ内嵌STLportQ但不是大工E,性能分析没必要动不动q下VTune吧?/p>
E序员之路:
《游戏之?#8212;—我的~程感悟?#add不怎么?
?风大哥。在我心目中游戏E序员国外首推卡马克Q国内首推云风。也许过两年我会到网易当云风大哥的助理程序员吧。It’s my dream.Q^-^Q他写这本书的时候本着只有透彻理解的东西才写出来,因此内容不会很酷斎ͼ但是怿我,每读一遍都有新的收P主要q不是知识上的, 因ؓ知识是学无止境的Q授Zg如授Z渔,_上的启_才是长久的。诚如经典游戏?仙剑 奇侠传》的dE序员兼术指导姚壮宪(人称姚仙Q在序言中所说的“云风得到的只是一些稿费,而整个中国民族游戏业得到的是一ơ知识的推动”Q此a不虚矣?/p>
《编E高手箴a?#add?
?肇新是豪杰超U解霸的作者,本来每个合格的程序员QProgrammer , 而非CoderQ都应该掌握的东西,现在变成了编E高手的独家言。不知是作者的q运q是中国IT业的悲哀。知识点q是讲得蛮多的,不过对MFC的地位颇 有微词。我实在认ؓMFC的名声就是那些不懂得用它的h搞臭的。不q作者的牢骚也情有可原,每个h创造力的程序员都应该不太喜Ƣframework?/p>
《Masters of DOOM: How Two Guys Created an Empire and Transformed Pop Culture》中文名《DOOM启世录?/p>
?马克Q罗z斯Q这些游戏史上如雯耳的名字。(现在卡马克已专注于火制造上Q罗z斯则携d乡隐居)要不是没上过大学的卡马克和图形学大师亚伯拉罕的功 勋,可能到现在游戏中q不知三lؓ何物。勿庸置疑,在计机界历史是英雄们所推动的。这本书真实的记录了q些世英雄的所为所思?/p>
作ؓE序员的我对q几本策划与工的书也生了厚兴趣Q以前搞q一两年?DS MAX插g~程Q觉得用maxscriptq是好过MaxSDKQ毕竟游戏开发中所多的是模型场景数据的导入导出Q大可不必大动干戈?/p>
{划Q?/p>
《Creating Emotion in Games : The Craft and Art of Emotioneering?/p>
在壮丽煊目的宏伟三维世界背后Q在D酷的杀戮,动h心魄的情节背后,我们q需要什么来抓住玩家的心Q答对了Q就是emotion.真正打动人心的,才是深入骨髓的?/p>
《Ultimate Game Design : Building Game Worlds?/p>
从名字可以看出,写给兛_设计师的Q特别是讲室外自然场景的构徏颇有可取之处?/p>
《Developing Online Games : An Insider’s Guide?/p>
p名ؓ反模式的书讲软g团队q营一Pq本书讲商业q作多过技术。一个历l艰难,现在盛大的游戏程序员Q翻译了q本书?br />工Q?/p>
《Digital Cinematography & Directing?/p>
数字摄媄导演术,每当你在3DS MAX或者Maya{三l创作Y件中摆放摄媄机,设计其运动轨qҎQ你可曾惌你也站在导演的位|上了?
《The Animator’s Survival Kit?/p>
?着q本讲卡通角色运动规律的书,一边生温习《猫和老鼠》的念头Q一边l对前不久新闻联播中关于中国产生了某计算动卡通动ȝ成Y件报道的蔑视Q这 条报道称此D可大大加快中国卡通动ȝ产量。我且不从技术上探讨其是否是在放卫星Q其实我知道得很清楚Q前文已表,本h搞过一两年的卡通动画辅助Y件编 E)Q但计算机机械生成的动画怎可代替人类充满灉|的创作Q?/p>
《The Dark Side of Game Texturing?/p>
用Photoshop制作材质贴图Q还真有些学问?/p>
三维囑Ş学:
搞三l图形学首先q是要扎扎实实的先看解析几何、线性代数、计几何的教材Q后面的习题一个都不能。国内数学书q是蛮好的。苏步青大师的《计几何》称得上h世界U水准,可惜中国CAD的宏图被盗版l击垮了。现在是我们接过接力的时候了。It’s time!
《Computer Graphics Geometrical Tools?/p>
《计机囑Ş学几何工L法详解》算法很多,U漏处也不少?/p>
?D Math Primer for Graphics and Game Development?/p>
易Q可作ؓ三维数学?#8220;速食“?/p>
《Mathematics for 3D Game Programming & Computer Graphics》第二版
比上面那本深入一些,证明推理的数学气也浓一些,可作Z业的数学书与~程实践一个过渡的桥梁吧。内Ҏ猎也q,线q踪Q光照计,可视裁剪Q碰撞检,多边形技术,阴媄法Q刚体物理,体水LQ数值方法,曲线曲面Q还真够丰富?/p>
《Vector Game Math Processors?/p>
惛_MMX,SSE吗,那就看它吧,不过从基讲v的,要耐心哦?/p>
DirectX:
《Introduction to 3D Game Programming with DirectX 9.0?/p>
DirectX入门的龙书,作者自己写的简单示例框Ӟ后面我干脆用State模式Q把所有例子绑C块儿M?/p>
《Beginning Direct3D Game Programming?/p>
?者取得律师学位后变成了游戏程序员Q真是怪也哉。本书虽定位为入门书,内容颇有独特可取之处。它用到的示例框架是DXSDK Sample FrameworkQ而不是现在通行的DXUT。要想编译有两种办法吧,一是自己改写成用DXUT的。二是找旧的Sample Framework。我又懒得ؓ了一个示例框架下载整个早期版本的DirectXQ后面在Nvidia SDK 9.5中发C?/p>
《Advanced Animation with DirectX?/p>
DirectX 高动画技术。骨骼系l,渐变关键帧动画,偶h技术,表情变ŞQ粒子系l,布料柔体Q动态材质,不一而。我常常在想Q从三维创作软g导出的种U效果,?成一堆text或binaryQ先加密压羃打包再解包解压解密,再用游戏E序重徏一个Lite动画pȝQ游戏程序员也真是辛苦?/p>
OpenGL:
《NeHe OpenGL Tutorials?/p>
虽是|络教程Q不比正式的书逊,本来学OpenGL׃q是看百来条C函数文档的工夫吧,如果囑Ş学基知识扎实的话?/p>
《OpenGL Shading Language?/p>
OpenGL支持最新显卡技术要靠修修补补的插g扩展Q所以还要配?/p>
《Nvidia OpenGL Extension Specifications?/p>
来看Z?/p>
《Focus on 3D Models?/p>
《Focus on 3D Terrain Programming?/p>
《Focus on Curves and Surfaces?/p>
思义Q三本专论,虽然都很不深Q但要对未知三维模型格式作反向工E前Q研读Geomipmapping地Ş法论文前,CAD前,q是要看看它们ؓ上,如果没从别处得过到基的话?/p>
脚本Q?/p>
先看
《Game Scripting Mastery?/p>
{自׃解了虚拟机的构造,可以设计出简单的脚本解释执行pȝ了?/p>
再去查Python , Lua QRuby的手册吧Q会事半半功倍倍的?/p>
《Programming Role Playing Games with DirectX 8.0?/p>
一Ҏ学一边用DirectX写出了一个GameCore库,初具引擎EŞ?/p>
《Isometric Game Programming with DirectX 7.0?/p>
三维也是建立在二l的基础上,q就是这本书现在q值得看的原因?/p>
《Visual C++|络游戏建模与实现?/p>
联众的程序员写的Q功力很扎实Q讲牌cL戏编E,特别讲了UML建模和Rotional Rose?/p>
《Object-Oriented Game Development?/p>
套用某h的话Q?#8220;I like this book.”
Shader:
要入门可先看
《Shaders for Game Programmers and Artists?/p>
讲在RenderMonkey中用HLSL高着色语a写Shader.
再看
《Direct3D ShaderX : Vertex and Pixel Shander Tips and Tricks?/p>
用汇~着色语aQ纯银赤金?/p>
三大宝库Q?/p>
《Game Programming Gems?/p>
我只见到1-6本,据说W??本也出来了?附带的源代码常有bugQ不q瑕不掩瑜,q套世界游戏E序员每q一度的技术文集,涉及游戏开发的各个斚wQ我觉得富有开发经验的人更能在其中扑ֈ共鸣?/p>
《Graphics Gems》全五本
囑Ş学编EBibleQ看了这套书你会明白计算机领域的U学家和工程师区别之所在。科学家L_q个东西在理Z可行。工E师会说Q要佉K题在logN的时限内解决我只能忍痛割爱,舍繁简?/p>
《GPU Gems》出了二?/p>
Nvidia公司召集囑Ş学Gurus写的Q等到看懂的那一天,我也有心情跑去Siggraph国际囑Ş学大会上投文章碰q气?/p>
游戏引擎~程Q?/p>
?D Game Engine Programming?/p>
是ZFXEngine引擎的设计思\阐释Q很q_Q冇太多惊喜?/p>
?D Game Engine Design?/p>
数学物理的理论知识讲解较多,本来q样够了,q能期待更多吗?
人工Q?/p>
《AI Techniques for Game Programming?/p>
讲遗传算法,人工经|络Q主要用C数组Q图法。书的原型是Ҏ作者发表到GameDev.net论坛上的内容整理出来的,q比较切中实际?/p>
《AI Game Programming Wisdom?/p>
相当于AI~程的Gems?/p>
《PC游戏~程(人机博弈)?/p>
?象棋E序本,介绍了很多种搜烦法Q除了常见的极大极小值算法及其改q?-负极大值算法,q有深度优先搜烦以外。更提供了多U改q算法, 如:Alpha-Beta,Fail-soft alpha-beta,Aspiration Search, Minimal Window Search,Zobrist Hash,Iterative Deepening,History Heuristic,Killer Heuristic,SSS*,DUAL*,MFD and more.琳琅满目Q实属难得?/p>
反外挂:
《加密与解密(W二??看雪论坛站长 D钢
破解序列号与反外挂有关系么?不过Q世上哪两g事情之间又没有关pdQ?/p>
《UML Distilled?Martin Fowler
很多人直到看了这本书才真正学懂UML?/p>
Martin Fowler是真正的大师,从早期的分析模式,到这本UML_a,革命性的重构都是他提出的,后来又写了企业模式一书。现在领g个Y件开发咨询公司,dJavaOne中国大会他作Z家来华了吧。个人网站:MartinFowler.com
设计模式三剑客:
《Design Patterns Elements of Reusable Object-Oriented Software?/p>
《Design Patterns Explained?/p>
《Head First Design Patterns?/p>
重构三板斧:
《Refactoring : Improving the Design of Existing Code?/p>
《Refactoring to Patterns?/p>
《Refactoring Workbook?/p>
软g工程:
《Extreme Programming Explained : Embrace Change》第二版
其中Simplicity的Value真是振聋发聩Q这是我什么都喜欢轻量U的原因?/p>
《Agile Software Development Principles,Patterns,and Practices?/p>
敏捷真是炒得够火的,q企业都有敏捷一_不过大师是不会这么advertising的?/p>
《Code Complete》第二版
名著?/p>
数学Q?/p>
《数学,定性的丧失》M.克莱?/p>
原来数学也只不过是hcȝ发明与臆造,用不着供入殿Q想起历史上那么多不食h间烟火的U学Ӟ多半是数学家Q,自以为发C宇宙q作的奥U,是时候走下神坛了?/p>
物理Q?/p>
《普通物理学》第一?+= 《Physics for Game Developers?/p>
物理我想到此ؓ此吧Q再复杂我可要用Newton Engine,ODE了,{待物理卡PPU普及的那天,可充分发挥PhysX的功效了Q看q最新的《细胞分裂》游戏Demo演示Q成千上万个Box疯狂CollideQ骨灰玩家该一Ҏ钱包一Ҏ口水了?/p>
二、开源代码:
Irrlicht
?名的鬼火引擎Q从两年前第一眼看到它Q这个轻量的三l图形引擎,喜Ƣ上了它。源代码优雅Q高效,且不故弄玄虚。值得每个C++E序员一读,q不限于?形编E者。它的周边中也有不少轻量U的东西。如Lightfeather扩展引擎QICE、IrrlichtRPG、IrrWizard.q有 IrrEdit、IrrKlang、IrrXML可用。(可能是ؓ了效率原因,很多开源作者往往喜欢自己写XML解析库,如以上的IrrXML?即有现成的tinyXML库可用。这真会让tomcat里面塞AxisQAxis里面塞JUDDIQ弄得像俄罗斯套娃玩LJava Web Service Coder们汗颜。)
OGRE
?名第一的开源图形引擎,当然规模是很大的Q周边也很多。除了以C#写就的OgreStudio Qofusion嵌入3DS MAX作ؓWYSWYG式的三维~辑器也是棒的Q特别是其几个场景、地形插件值得研究。以至于《Pro OGRE 3D Programming》一书专论其用法。搜狐的《天龙八部》游戏就是以其作为图形引擎,当然q另外开发了引擎插块啦。我早知道OGRE开发组中有一个中 国h谢程序员Q他以前做了很多q的传统软g~程。有一ơ天龙八部游戏的囑Ş模块的出错信息中包含了一串某E序员的工作目录Q有一个文件夹名即是谢E序员的 英文名,我据此推断谢E序员即是搜狐北京的ȝ。看来中国对开源事业还是有所贡献的嘛Q王开源哥哥的努力看来不会白费Q(^-^Q不q我侦测的手法也有些 像网站数据库爆库了,非君子之所Z?/p>
RakNet
ZUDI的网l库Q竟q支持声音传输,以后和OpenVisionl合h做个视聊E序试试?/p>
Blender
声誉最盛的开源三l动画YӞ竟还带一个游戏引擎。虽然操作以快捷键驱动,也就是说要背上百来个快捷键才能熟l用。但是作Z商业代码变ؓ开源之作,威胁三维商业巨头的轻骑兵Q历l十q锤|代码辄万行Q此代码只应天上有,人间哪得几回看,怎可不作为长期的源码参考?
风魂
二维囑Ş库。云风大哥的成名之作。虽然不代表其最高水qI最高水q作为商业代码保存在q州|易互动的SVN里呢Q,但是也可以一仰风采了?/p>
圣剑英雄?/p>
?lRPG。几个作者已成ؓ成都锦天的主力程序员。锦天的老M一百万发家Q三q时间n仯亿,也是一代枭雄了。这份代码作为几q前的学生作品也可以了Q?因ؓ一个工E讲I的是四q_EIq不一定要哪个模块多么出彩。反正我是没有时间写q么一个东东,q个工都找不到Q只能整天想着破解别h的资源(^- ^Q?/p>
Boost
C++准标准库Q我x多的时候可以参考学习其源代码?/p>
Yake
?遇到的最好的轻量U游戏框架了。在以前把一个工E中的图形引擎从Irrlicht换成OGRE的尝试中Q遇C它。OGRE的周边工E在我看来都很庸肿, 没有完善文档的情况下看v来和Linux内核差不多。不q这个Yake引擎倒是很喜Ƣ。它以一个FSM有限状态机作ؓ实时E序的调度核心,然后每个模块Q?物理、图形、网l、脚本、GUI、输入等{都提供一个接口,接口之下再提供到每种具体开源引擎的接口Q然后再接具体引擎。通过q样层层抽象Q此时你是接 Newton Engine,ODEq是PysX都可以;是接OGRE,Crystal Spaceq是Irrlicht都可以;是接RakNetq是LibCurl都可以;是接PythonQLuaq是Ruby都可以,是接CEGUIq是 othersQ是接OISq是othersQ呵?ChothersQ都可以。所以Yake本质上不是OGRE的周辏V虽然用Neoengine的h 都倒向了它Q但是现在版本还很早。特别是我认为,学习研究时一定要有这U抽象之抽象Q接口之接口的东西把思维从具体的l定打开Q而开发时抽象要有限度的, 像蔡学镛在《Java夜未眠》中讲的Q面向对象用得过滥也会得OOOO?面向对象q敏??/p>
Quake Doompd
据说很经典,卡马克这U开源的黑客_值得赞许。把商业源代码放出来Q走自己的创C路,让别d。不qQuake与Unreal引擎的三l编辑器是现在所有编辑器的E,看来要好好看看了?/p>
Nvidia SDK 9.X
?l图形编E的大宝库,q些Diret3D与OpenGL的示例程序都是用来展C其最新的昑֍技术的。硬件厂商往往对Y件品不甚在意,源代码给你看,东西 l你用去吧,学完了还得买我的g。Intel的编译器QPhysX物理引擎大概也都是这栗Havok会把它的Havok物理引擎免费l别人用吗?别说 试用版,q个Demo都看不到。所以这套SDK的内容可比MS DirectX SDK里面那些入门U的CZ酷多了,反正我是如获臛_Q三月不知愁滋味。不q显卡要so-so哦。我的GeForce 6600有两三个跑不q去,差强人意?/p>
三、网站:
www.CSDN.net
E序员大本营吧,软文?#8220;新技术秀”讨厌了点Qblog和社区是_֍之所在?/p>
www.GameRes.com
游戏E序员基圎ͼ文档库中q有点东ѝ投E的接收者Seabug与圣剑英雄传的主ESeabug会是同一个h吗?一个在成都锦天担当技术重担的高手q有旉l护|站吗?我不得而知?/p>
“何苦做游?#8221;|站
名字很个性,站长也是历尽几年前业发展初期的艰难才出此名字?/p>
www.66rpg.com
二维游戏囄资源很多Q站长柳柳主推的RPGMaker 软g也可以玩一玩吧Q但对于专业开发者来说不可当真?/p>
www.GameDev.net
论坛中有不少热心的国外高手在zd?/p>
www.SourceForge.net
不用说了Q世界最大的开源代码库Q入金山怎可I手而返Q看到国外那些学生项目动不动像模像L。(DirectX的稚形就是英国的学生目Q在学校q被判ؓ不合根{)
www.koders.com
?代码搜烦引擎,支持正则表达?google Lab中也有。当你某U功能写不出来时,可以看一下开源代码怎么写的,当然不过是仅供参?开源代码未必都有品的强度。说到google,可看 《Google Power Tools Bible》一书,你会发现Qgoogle的众多品原来也有这么多使用门道?/p>
q篇文写了一天半的时_不由得我对侯捷一L技术作安期伏案辛勤劳作深深敬佩了。看来对于书c或者YӞ都应该尊重作者或者programmer的才智劳动?/p>
你因为如下原因进入游戏业—— 投递应聘材料须知: 1、别人帮忙发的简历(别h帮你Q会被视Z介,一律免谈。你托别人发Q对自己没有信心嘛。当Ӟ熟h推荐的例外)Q?/p>
2、给别家公司发的历,抄送一份过来(q是一个最L的礼貌问题,好比你要拿三份礼物送给三家Q你只能拿一份跑一Ӟ我很奇怪,分开发很ȝ吗?Q; 3、利用一些招聘网站的模版发过来的Q或者是一些招聘网站自动发q来的(既然是一份愿意从事的职业Q请认真对待Q而不是发传单。你ȝQ我也轻率)Q?/p>
4、邮件的内容只有一句话Q?#8220;我是你们x的hQ请和我联系Q留下qq或者手机号?#8221;Q公司招聘上有公怿息,你的邮g中没有你的信息,对话必须建立在双方对{的情况下)Q?/p>
5、邮件内部附一个网址链接Q说“q个链接有我的介l和作品”Q对不vQ陌生hl的链接从来不点Q怕中毒,邮g附g为可执行文g的同样处理)?/p>
1、邮仉U自׃ؓ天纵英才Q睿智博学,能力群是中国游戏业救世主的(W一Q咱池小水浅Q怕无法让您这条大龙翱;W二Q在黑客帝国里,先知没说奥是救世主Q谁也不会找到尼奥当他是Q我们这行也没有先知说您是救世主Q第三,驾q样h兼备的h士,衷心希望您去从事更高、更伟大的职业)Q?/p>
2、邮仉U自己有天才x、非凡设计、无以u比的构思,期待共同成功的(委婉的说Q有q种气魄和精是好的Q但是未l验证谁也不能保证成功,我不是说完全没有成功的可能,只是׃能拿十数人到数十人好几年的劳作,几百上千万的资金投入来验证您的豪a壮语不是Q坦白点Ԍ阁下何d何能Q有何资历,如何服众啊?凭什么要众h受您qQ以成就您的青天白日大头梦呢Q)Q?/p>
3、邮件的历与游戏业,游戏制作业毫无关p(q种历经常发自刚毕业的大学生Q上书姓名、性别、出生年月日Q以及教育经历、获奖情c个人爱好等。除此之外,既不谈对游戏的爱好,也不谈对游戏业的认识。所以,我只能诚恳的告诉你,q种历发CQ何游戏公叔R是直接回收站Q,补充一点,g所有h都当q学生干部?也统l获得过奖学金? 4、邮件内容语无uơ,dQ扭扭捏捏?br /> 5、简历中错字q篇、重大常识性错误、信口胡说的?br />Q诸如在个h能力介绍中,不厌其烦的说?#8220;教强”的XX能力Q?#8220;教深”的XX修养Q在个h薪金期望上写错位数达到年?亿的Q写游戏名字中英文拼写都错误的,某某q_的游戏张冠李戴到另一个^C?.....Q; 6、简历制作及内容不合格的。譬?#8212;— 7、可能有潜在性麻烦的邮g?br /> 8、简历中有不切实际的要求的?br /> 9、接受过来自XX游戏培训机构的简历(q个部分在下期予以说明Q?/p>
10、附有几十页乃至数百不{的{划案({划书)?br /> {划之野?#8212;—
AQ玩了很多游戏想做;
BQ认己是天才Q充满创造力Q想找个地方用;
CQ这行能赚钱Q试囑利双Ӟ
DQ感到现在的游戏都是**作品Q想改变现状Q?br />EQ高薪就业与兴趣相结合;
FQ当作一份工作?br />
]]>
输出l果Q?br>after initialization:
p: 42
q: NULL
after assigning auto pointers:
p: NULL
q: 42
after change and reassingnment:
p: 55
q: NULL
hL键l? . .
基础提高Q?br>法艺术与信息学竞赛 W二?刘汝?br>法设计与分?王晓?br>法设计与试验题?王晓?br>U曼Q《算法导论?br>l合数学 W三?冯舜??br>计算几何Q算法设计与分析 周培?br>国际信息学奥林匹克竞赛指导??实用法的分析与E序设计 吴文?王徏?/p>
|络法与复杂性理?谢政 李徏q?br>《Concrete Mathematics --- A Foundation For Computer Science?Ronald L. Graham Q?Donald E. Knuth Q?Oren Patashnik《具体数学》(能买C文版最好)
《计机E序设计艺术》三?Knuth
l合数学的算法与E序设计
《程序设计中的组合数学?吴文?br>图论的算法与E序设计
图、网l与法
国际大学生程序设计竞赛辅导教E?郭嵩?崔昊
《ACM国际大学生程序设计竞赛试题与解析》全部册Q吴文虎著,清华大学出版C)
C法Q第1P基础、数据结构、排序和搜烦Q第三版Q?br>C法(W?卷图法W?版中文版)译?周良?(国)塞奇威克?
国际大学生程序设计竞赛例题解 四本 郭嵩?/p>
h有的新队员认真完成以下各题。如果做题遇到困难,如题意难以理解、不知如何着手或不知错在哪里Q不要气馁,可以h别的队员Q也可请教教l。我们会力帮助你完成这几组中每一道题。但不要复制别h的程序,即便参考了别h的程序,也要亲自再完成一遍。而且不徏议过多参考别人程序,q样会消pl的效果Q也减少了思考的乐趣?/p>
有些队员可能觉得某些题太单,但我们还是徏议将它们都做掉。因为题目虽然简单,但是再简单的题目都不能保证一ơ做对,而做错题的各U原因如题意理解错误Q格式错误等你都会碰到。了解这些原因对减少错误率很有好处?/p>
?nbsp; ACM竞赛参考书
《实用算法的分析与程序设计?nbsp; Q吴文虎Q王建d著,电子工业出版C,竞赛cȝ黑宝书)
《青年国际和全国信息学Q计机Q奥林匹克竞赛指|――组合数学的法
和程序设计?nbsp; Q吴文虎Q王建d著,清华大学出版C,参加竞赛l合数学必学Q?br> 《计机法设计与分析?nbsp; Q王晓东~著Q最好的数据l构教材Q?br> 《数据结构与法?nbsp; Q傅清祥Q王晓东~著Q我所见过的最好的法教材Q?br> 《信息学奥林匹克竞赛指导―?997-1998竞赛试题解析》(吴文虎,王徏徯Q清华大学出版社Q?nbsp;
内容极佳Q?br> 《计机E序设计技巧?nbsp; D.E.Kruth著,法书中最著名的《葵花宝典》,大师的作品,隑ֺ大)
《计几何?nbsp; Q周陪d著,全面介绍了计几何)
《ACM国际大学生程序设计竞赛试题与解析Q一Q?nbsp; Q吴文虎著,清华大学出版C)
<<数学建模竞赛培训教材>> ׃?叶其孝主~?br> <<数学模型>> W二?姜启?br> <<随机规划>>
<<模糊数学>>
<<数据l构>>
<<数学建模入门>> 徐全?br> <<计算机算法设计与分析>> 国防U大
?常见的几个网上题?br> 常用|站Q?br> 1Q信息学初学者之Ӟhttp://oibh.ioiforum.org/
Q?Q大榕树~程世界Q?a >http://www.fjsdfz.org/~drs/program/default.asp
Q?Q中国教育曙光网Q?a >http://www.chinaschool.org/aosai/
Q?Q福Z息学奥林匹克Q?a >http://www.cfcs.com.cn/fjas/index.htm
Q?Q第20届全国青年信息学奥林匹克竞赛:http://www.noi2003.org/
Q?Q第15届国际青年信息学奥林匹克竞赛:http://www.ioi2003.org/
Q?Q全计机奥林匹克竞赛Q?a >http://ace.delos.com/usacogate
Q?Q美国信息学奥林匹克竞赛官方|站Q?a >http://www.usaco.org/
Q?Q俄|斯Ural州立大学Q?a >http://acm.timus.ru/
Q?0Q西班牙Valladolid大学Q?a >http://acm.uva.es/problemset
Q?1QACM-ICPCQ?a >http://icpc.baylor.edu/icpc/
Q?2Q北京大学:http://acm.pku.edu.cn/JudgeOnline/index.acm
Q?3Q浙江大学:http://acm.zju.edu.cn/
Q?4QIOIQ?a >http://olympiads.win.tue.nl/ioi/
Q?5Q?003q江苏省信息学奥林匹克竞赛夏令营Q?a >http://jsoi.czyz.com.cn
Q?6Q?a >http://acm.zju.edu.cn
Q?7Q?a >http://acm.zsu.edu.cn
Q?8Q?a >www.shumo.com
Q?9Q?a >http://www.bepark.com/downldmanag/index.asp
Q?0Q?a >http://www.yh01.com colin_fox/colin_fox
?如何备战ACM/ICPC
1Q个人准备(法书,习题集,|上做题和讨论)
2Q?000?亚洲冠军=世界册
3Q做好资料收集和整理工作Q?
USACO
http://ace.delos.com/usacogate
国著名在线题库Q专门ؓ信息学竞赛选手准备
TJU
http://acm.tongji.edu.cn/
同济大学在线题库Q唯一的中文题库,适合NOIP选手
ZJU
http://acm.zju.edu.cn/
江大学在线题库
JLU
http://acm.jlu.edu.cn/
吉林大学在线题库Q一直上不去Q?/p>
PKU
http://acm.pku.edu.cn
北京大学在线题库
URAL
http://acm.timus.ru
俄罗斯乌拉尔大学在线题库
SGU
http://acm.sgu.ru/
俄罗斯圣萨拉托夫州大学在UK?/p>
ELJ
http://acm.mipt.ru/judge/bin/problems.pl?lang=en
俄罗斯莫斯科物理技术学?/p>
SPOJ
https://spoj.sphere.pl/
波兰g斯克理工大学
UVA
http://acm.uva.es/
西班牙的Universidad de Valladolid在线?/p>
ACM联系
一位高手对我的Q?/p>
一般要做到50行以内的E序不用调试?00行以内的二分钟内调试成功.acm主要是考算法的
Q主要时间是花在思考算法上Q不是花在写E序与debug上?
下面l个计划你练l:
W一阶段Q?br> l经典常用算法,下面的每个算法给我打上十C十遍Q同时自q代码Q?br>因ؓ太常用,所以要l到写时不用惻I10-15分钟内打完,甚至x昄器都可以把程序打
出来.
1.最短\(Floyd、Dijstra,BellmanFord)
2.最生成树(先写个prim,kruscal要用q查集,不好?
3.大数Q高_ֺQ加减乘?
4.二分查找. (代码可在五行以内)
5.叉乘、判U段怺、然后写个凸?
6.BFS、DFS,同时熟练hash?要熟Q要灉|,代码要简)
7.数学上的有:辗{盔RQ两行内Q,U段交点、多角Ş面积公式.
8. 调用pȝ的qsort, 技巧很多,慢慢掌握.
9. Lq制间的转换
W二阶段Q?br> l习复杂一点,但也较常用的法?
如:
1. 二分囑配(匈牙利)Q最\径覆?
2. |络,最费用流?
3. U段?
4. q查集?
5. 熟悉动态规划的各个典型QLCS、最镉K增子串、三角剖分、记忆化dp
6.博弈cȝ法。博弈树Q二q制法等?
7.最大团Q最大独立集?
8.判断点在多边形内?
9. 差分U束pȝ.
10. 双向q度搜烦、A*法Q最耗散优先.
W三阶段Q?br> 前两个阶D|打基Q第三阶D|ȝ在比赛中可以快速徏立模型、想新算?br>。这pqx多做做综合的题型了?
1. 把oibh上的论文看看Q大概几癄的,我只看了一点点Q呵呵)?
2. qx扫扫zoj上的N啦,别老做那些不用想的?(中大acm的版ȝ常说我挑单的?br>?-P )
3. 多参加网上的比赛Q感受一下比赛的气氛Q评估自q实力.
4. 一道题不要q了qQ问一下hQ有更好的算法也打一下?
5. 做过的题要记?:-)
如果不到30岁,看到40岁标题这几个字就跌去,那么你的人生很有可能失去提早准备的机会。要回答『程序员40岁以后还可以做点什么』的q个问题Q首先要看一看那些已l超q?0岁的E序员现在都在干什么,然后怺比较Q从中得到启发,思考如何选择一条最适合自己模仿的\?/span>
衡量一个h成功的标准有很多Q有些h把胦富或权力视ؓ成功Q还有些人则把内心的安宁和n体健庯为成功,甚至不同国家地区、文化背景下也有其特艌Ӏ?/span>当然Q还有一个我们容易忽略的重点Q就是这些前辈在他们二十多岁选择的技术和方向Q过了二十年后,I竟哪些投资报酬率最高?我们在时代变q下Q从q些选择中领悟到什么?q些选择h什么样的特质?又有哪些可以作ؓ现在选择的参考?
信息化时代的特征是快速变化和创新Q所以如果你不够快或不够创新Q显然这不是一个适合养老的行当。姑且不谈每q新生h口有多少Q就是每q国内大学毕业生的h敎ͼ差不多相当于目前香港h口的LQ这些职场新力军可以比前辈更卖力学习Q有些甚臌求更低工资,在选择Z时更没有后顾之忧Qƈ且能放手大干一场?/p>
所以,如果你二十几岁,但目前正在做的事没有MU篏Q只是不断在淘汰与被淘汰间轮回,沉迷一些短暂的技术噱_忽略人际关系的成长,那么很显Ӟ旉对你是不利的。因为等到面?0岁这道关卡时Q你会发现自己和和十q前差异q不大,q且开始怀疑自q价值和竞争力,更别提什么不可替换性了?/span>
聪明和智慧是有区别的Q聪明是一时的反应和敏P而智慧则需要经验和旉的积累?/span>新生代固然在聪明上占有先天的优势Q但q长的一代是否具有智慧ƈ不是l对Q这需要看他们在年LQ是否徏立了一套积累智慧的完备体系Q否则最l可能落得既不聪明也没有智慧的空白,甚至望着大把青春渐逝,徒呼负负?/p>
我现在已l年q?0了,只是当年正y赶上台湾90q代信息发展的初期。在我之前很多出色的前辈Q有些技术写手,后来成立了规模大大小的出版工作室或公司Q有的则是成立了软g公司Q在攫取几桶金后Q投资其他行业或公司Q还有的回到学校重新执教Q过着qxE又充实的日子Q更多的则是不知其所t?下落不明?q搜索引擎都找不C...)?/p>
我还在写代码吗?当然Q编E和英文一h我不会放弃的兴趣Q只不过前者是和机器沟通的语言。VBA一直都是我喜爱的工?- 在Q何时间、Q何地点进行创意设计。当Ӟ我也使用Visual Studio 2010Q但只是作ؓ技术管理,指导团队如何在项目中协作和系l化思考?/p>
我真正的收入来源是金融和传媒Q但q两者都不是我在学习~程后才涉猎的领域。不Z在编E的某个领域多么或者靠着q项能力获取了多收入,永远记得Q?span style="BACKGROUND-COLOR: yellow">在当今信息化的时代,你要具备~程与自动化的能力,但不能只靠编E过z?/span>。』,所以及早ؓ自己做准备,q样不论q了多少岁,永远都可以当一个快乐而非忧虑的程序员?/span> 本文来自CSDN博客Q{载请标明出处Q?a >http://blog.csdn.net/oiio/archive/2010/11/03/5983765.aspx
~程语言
除了C++之外Q还有Java、BASIC、COBOL、FORTRAN、PASCAL和CQ只是因为它是B语言的后l语aQ等~程语言?br>所有这些称为高U语aQ因为它们可以比较容易地表达计算机完成的工作Q而且不针Ҏ台计机?br>高语言中的每个源语句一般映ؓ几个内部机器指o?br>低语言比较接近内部机器指oQ通常UCؓ汇编语言Q一个汇~语a专门用于一U硬件设计,一般一个汇~指令映ؓ一个内部机器指令?/p>
~程语言?br>FORTRAN是第一U开发出来的高语言Q第一个FORTRAN~译器是?9世纪50q代后期开发出来的?br>已有40多年的历史了Q目前仍q泛应用于科学和工程计算中,但C++和其他语a也逐渐q入q些领域?/p>
COBOL语言专门用于商务数据处理应用E序Q它的历史几乎与FORTRAN语言一样长Q目前几乎不用COBOL~写代码?/p>
BASIC?9世纪70q代诞生Q那时已l有了个机的概c有的是,Microsoft销售的W一个品是一个BASIC解释E序?br>q种语言所固有的易用性之很快普及,直到今天仍非常流行?/p>
Java是在19世纪90q代开发的Q它最初开发ؓOak语言Q用于给型电子讑֤~程?br>1995q_Oak演变为Java语言Q可以在Web面中内嵌代码,从那时v直到现在Q这已经成ؓJava的主要用途?br>Java成功的主要原因是它的可移植性。JavaE序可以在Q何支持它的硬件^Cq行Q而且不需要Q何修攏V?br>Java语言的语法有许多Ҏ,使它看v来很像C++Q但有很大的区别。Java在可UL性方面比C++好,但执行性能比不上C++?/p>
C在上个世U?0q代被开发ؓ一U高U语aQ用于低U编E,例如实现操作pȝ。大多数Unix操作pȝ是用C~写的?/p>
C++?9世纪80q代早期开发的Q是一U基于C的面向对象语a?br>思义QC++表示C的篏加?br>׃C++ZCQ所以这两种语言有许多共同的语法和功能,C中所有低U编E的功能都在C++中保留下来?br>但是QC++比其前n丰富得多Q用途也q泛得多?br>C++对内存管理功能进行了非常大的改进QC++q具有面向对象的功能Q所以C在功能上只是C++的一个很的子集?br>C++在适用范围、性能和功能上也是无可Ҏ的?br>因此Q目前大多数高性能的应用程序和pȝ仍用C++~写?/p>
解释性程序和~译性程序的执行q程
无论使用哪种~程语言Q编写出来的E序都是由各个指令或源语句构成的Q它们描qC希望计算机执行的动作?br>q些指o或源语句l称为源代码Q存储在盘的源文g中?br>M规模的C++E序都是pq个源文件组成的?/p>
~程语言的目的是Q与计算机可以执行的E序相比Q能够更单地描述希望计算机执行的动作?br>计算机只能执行包含机器指令(也称为机器代码)的程序,不能直接执行我们~写的程序?/p>
用前面提到的语言~写的程序基本上有两U执行方式,在大多数情况下,一U语a会选择其中一U执行方式?br>例如Q用BASIC语言~写的程序通常是解释性的Q?br>也就是说Q另一个称释器的程序会查BASIC源代码,定该程序要做什么,再让计算机完成这些动作?/p>
而C++是一U编译语a。在执行C++E序之前Q必ȝ另一个程序(即编译器Q把它{换ؓ机器语言?br>~译器会查ƈ分析C++E序Qƈ生成机器指oQ以执行源代码指定的动作?br>当然Q解释和~译都不像这里描q的那样单,但其工作原理是q样?/p>
使用解释性语aQ执行过E是间接的,也就是说Q每ơ执行程序时Q都需要确定源代码的意图?br>因此Q这U语a比编译语a的对应程序的执行速度慢得多,有时要慢100倍?br>其优Ҏ在运行之前,不必{待E序的编译?br>使用解释性语aQ一旦输入代码,可以立L行程序?/p>
M一U语a要么是解释性,要么是编译性的Q这通常是由该语a的设计和用途来军_?br>前面说过BASIC是一U解释性语aQ但q不是绝对的Q目前有许多BASIC语言的编译器?/p>
没有所?#8220;最?#8221;的语aQ因取决于环境?br>看具体环境在意的是开发速度Q还是运行速度Q又或是UL能力{等?/p>
?br>每次~写E序Ӟ如果L要从头开始编写,q当繁琐?br>Z解决q个问题Q编E语a通常提供了大量预先编写好的代码,以执行标准的操作Q这样就不必重新~写q些代码了?br>可用于Q意程序的标准代码都保存在一个库中?br>~程语言附带的库跟语a本n一样重要,因ؓ库的质量和用范围对完成某一~程d所需的时间有非常大的影响?/p>
C++是一U功能强大的语言
C++的ANSI/ISO标准
名称
C++E序中的许多元素都有用来表示它们的名Uͼ也称为标识符?br>在C++E序中,可以命名?U元素是Q?br>函数、变量、类型、标{、命名空?/p>
关键?br>C++中有一些保留字Q称为关键字Q它们在C++语言中有Ҏ的含义?/p>
C++语句和语句块
语句是指定程序做什么和E序所处理的数据元素的基本单元?/p>
把名U引入源文g的语句称为声明?br>声明只是引入名称Q指定该名称表示什么,它与定义不同?/p>
定义是分配一些内存,来包含名U所指代的内宏V?br>大多数声明也是定??????????(q句如何理解Q?)
变量是内存中一个可以存储数据项的空间?br>下面的语句示例声明了一个变量名Q定义ƈ初始化了一个变量:
double result = 0.0;
q个语句把名Uresult声明Z个doublecd的变量(声明Q,
把内存分配给该变量(定义Q,
q设|其初始gؓ0.0Q初始化Q?/p>
可以把几个语句放在一对花括号中,此时q些语句q句块?br>函数体就是一个语句块?br>语句块也UCؓ复合语句Q因为在许多情况下,语句块可以看做是一个语句?/p>
在C++中,在可以放|一个语句的M地方Q都可以攄一个包含在花括号对中的语句块?/p>
语句块可以放在其他语句块内部Q这个概늧为嵌套。语句块可以嵌套LU?/p>
语句块对用于存储数据的变量有重要的作用。(变量作用?Q?/p>
代码的显C样?br>注意使用制表W、空格羃q程序语句,昄些语句的逻辑Q再以一致的方式使用定义E序块的匚w花括P使块之间的关pL清晰?/p>
E序l构
每个C++E序都由一个或多个文gl成?br>ҎU定Q用于存储源代码的文件有两类Q头文g和源文g?br>头文件可以包含描q程序所需的数据类型的代码Q以及其他类型的声明?br>头文仉常用文件扩展名.h来区分,但这不是强制的?br>源文件的扩展名是.cppQ它包含了函数声明,即程序的可执行代码。这些代码通常引用在自q头文件中定义的数据类型的声明或定义?/p>
~译器在~译代码Ӟ需要知道这些声明或定义Q因此应在文件的开头通过#include指o指定.cpp文g中需要的.h文g?br>#include指o是编译器的一个指令,它可以把指定头文件的内容插入代码Q还需要ؓ代码需要的标准库头文gd#include指o?/p>
~译器提供了大量的标准头文gQ其中包含用标准库功能所需要的声明?br>实际上,C++的标准头文g名都没有扩展名,q就把它们与其他头文件区分开来?/p>
E序的函数和执行
C++E序臛_包含一个函数main()Q但E序一般还包含许多其他函数Q一些是自己~写的,另一些是标准库函数?br>执行一个函数称用函数。在调用函数Ӟ可以l它传送数据项?br>在函数执行完后,执行控制q回到调用函数的地方?br>函数在执行完毕时Q还可以把一个D回到调用的位|上?br>q回值可以存储v来,以备以后使用Q也可以参与某种cd的计,例如术表达式的计算?/p>
从源文g中创建可执行文g
从C++源代码中创徏可以执行的程序模块需要两步:
W一步是~译器把每个.cpp文g转换为对象文Ӟ其中包含了与源文件内容对应的机器码?br>W二步是链接E序把编译器生成的对象文件合q到包含完整可执行程序的文g中?/p>
~译器把每个源文件看作一个独立的实体Qؓ每个.cpp文g生成一个对象文件?br>然后在链接步骤中Q把E序的对象文件和必要的库函数l合C个可执行文g中?/p>
实际上,~译是一个P代的q程Q编写源码,~译Q发现错误,修改源码Q再~译Q发现错误,再修改,再编译,……
~译
源文件的~译q程包含两个主要阶段Q而它们之间的转换是自动的?br>W一个阶D|预处理阶D,在正式的~译阶段之前q行?br>预处理阶D将Ҏ已放|在文g中的预处理指令来修改源文件的内容?br>#include指o是一个预处理指oQ它把头文g的内Ҏ加到.cpp文g中。还有其他许多预处理指o?/p>
q个在编译之前修Ҏ文g的方式提供了很大的灵zL,以适应不同的计机和操作系l环境?br>一个环境需要的代码跟另一个环境所需的代码可能有所不同Q因为可用的g或操作系l是不同的?br>在许多情况下Q可以把用于不同环境的代码放在同一个文件中Q再在预处理阶段修改代码Q之适应当前的环境?/p>
预处理器一般不能独立于~译器来执行Q调用编译器会自动执行预处理q程Q之后才~译代码?/p>
链接
~译器ؓl定源文件输出的是机器码Q执行这个过E需要较长时间?br>在对象文件之间ƈ没有建立Mq接?br>对应于某个源文g的对象文件包含在其他源文件中的定义的函数引用或其他指定项的引用,而这些函数或仍没有被解析?br>同样Q也没有建立同库函数的链接?br>实际上,q些函数的代码ƈ不是文g的一部分?br>q些工作是由链接E序完成的?/p>
链接E序把所有对象文件中的机器码l合在一P
q解析它们之间的交叉引用?br>它还集成了对象模块所使用的库函数的代码?br>q是链接E序的一U简化表C,因ؓq里假定在可执行模块中,模块之间的所有链接都是静态徏立的?br>实际上有些链接是动态的Q即q些链接是在E序执行时徏立的?/p>
链接E序静态地建立函数之间的链接,卛_E序执行之前建立l成E序的源文g中所包含的函数链接?br>动态徏立的函数之间的链接(在程序执行过E中建立的链接)函数编译ƈ链接hQ创建另一U可执行模块——动态链接库或共享库?br>动态链接库中的函数链接是程序调用函数时才徏立的Q在E序调用之前Q该链接是不存在的?/p>
动态链接库优点Q?br>动态链接库中的函数可以在几个ƈ行执行的E序之间׃nQ在执行的多个函数需要动态链接库中的函数所提供的服务时Q这节省同一个函数占用的内存I间?br>动态链接库在调用其中的函数之前是不会加载到内存中的Q也是_如果不用给定动态链接库中的函数Q该动态链接库׃会占用内存空间?/p>
动态链接库是与操作pȝ紧密相关的一个系l功能?/p>
C++源字W?br>~写C++语句要用基本源字符集,q些是在C++源文件中可以昑ּ使用的字W集?br>包括Q大写字母Q数字,控制字符Q一些特D字W?/p>
在C++中用的字符定义q没有说明字W的~码方式。编译器决定用于编写C++源代码的字符在计机上如何表C?/p>
通用字符集(Universal Character Set, UCSQ?br>由UCS标准定义的字W编码与Unicode定义的编码相同?/p>
三字W序?br>是用于表示另一个字W的三个字符序列。以前ؓ了表C键盘上没有的字W,q是必不可少的一U方法?br>~译器会用对应的字符替代它们Q再Ҏ代码q行其他处理?/p>
转义序列
通过转义序列可以把控制字W输入字W常量。{义序列是指定字符的一U间接方式,通常以一个反斜杠\开头?/p>
׃反斜框表C{义序列的开始,因此把反斜杠字符输入一个字W常量的唯一方式是用两个连l的反斜杠?/p>
转义序列q提供了用键盘不支持的语a来表C字W的一U通用方式Q因为可以用十六进Ӟ基数?6Q或八进Ӟ基数?Q数字前|一个反斜杠来指定字W的~码?/p>
׃使用了数字编码,可以用这U方式指定Q何字W?/p>
在C++中,十六q制数据以x或X开头?/p>
q可以用至?个八q制数字前置一个反斜杠来表C字W。例如\165。没有x或XQ就表示该编码应解释Z个八q制数字?/p>
cout << "\n\" Least said\n\t\tsoonest mended.\ "\n\a";
双引号之间的字符串称为字W串字面量?br>双引号字W表C字符串字面量的开始和l束Q它们不是字W串的一部分?/p>
字符串内部的双引号不会解释ؓ字符串字面量的结束,q是因ؓ每个双引L前面都有一个反斜杠Q表C是一个{义序列?/p>
语句中的I白
除了在语句的元素之间或引号中的字W串内用作分隔符之外Q编译器会忽略空白?br>因此可以在代码中包含L多个I白QɽE序的可L更高?/p>
在一些编E语a中,语句的结是代码行的末尾Q但在C++中,语句的结分号表示?br>因此Q可以把一个语句分散放在好几行代码行上?/p>
E序的注?br>C++中注释有两种形式Q单行和多行?br>单行注释以双斜杠开_//Q?br>~译器会忽略双斜杠后面的所有内宏V?/p>
多行注释?*开_?/l尾。在/*?/之间的所有内定w被忽略?br>注意多行注释不能嵌套Q否则会使编译器发出错误消息?/p>
标准?br>标准库包含了大量的函数和其他支持实体Q增加和扩展了C++的基本语a功能?br>标准库的内容是C++的一部分Q在语言的语法和语义斚w跟C++相同?br>C++的标准定义了q两者,所以每个符合该标准的编译器都提供了完整的标准库?/p>
标准库的范围是很Ҏ的?br>使用该标准库获得非常多的功能,包括基本元素如基本语a支持?br>输入输出函数和异常处理(异常是在E序执行中发生的偶然事gQ常常是某种错误Q?br>实用函数Q数学例E和各种预先~写好ƈ试通过的功能?br>在程序执行过E中可借助q些功能来存储和理数据?/p>
使用标准库所需要的定义和声明位于标准头文g中?br>C++标准库中的几乎所有内定w是在命名I间std中定义的?/p>
用C++~程
q程化编E方法和面向对象~程Ҏ
结
C++E序臛_包含一个main()函数?br>函数的可执行部分由包含在一对花括号中的语句l成?br>一对花括号定义了一个语句块?br>在C++中,语句用分L束?br>关键字是C++中有Ҏ含义的一l保留字。程序中的实体不能与C++语言中的M关键字同名?br>C++E序包含在一个或多个文g中?br>定义函数的代码通常存储在扩展名?cpp的文件中?br>定义数据cd的代码通常存储在扩展名?h的头文g中?br>C++标准库提供了支持和扩展C++语言的大量功能?br>C++中的输入和输出是利用来执行的,q且需要用插入和撮运符Q即<<?gt;>?br>面向对象的编E方式需要定义专门用于某E序的新数据cd。一旦定义好需要的数据cdQ就可以Ҏq些新数据类型来~写E序?/p>
副标? 自修教程与参考手?br>ISBN: 9787560927824
|: 800
出版C? 华中U技大学出版C?br>定h: 108.00?br>装: q16开
出版q? 2002-9
Windows是基于图形界面的Q所以在Win32~程中,囑Ş操作是最常用的操作?/span>GDI的意义在于将E序对图形界面的操作和硬件设备隔l开来,在程序中可以所有的囑Ş讑֤都看成是虚拟讑֤Q包括视频显C器和打印机{,然后通过GDI函数用同LҎL作它们,?/span>Windows负责函数调用{化成针对具体g的操作。只要一个设备提供了?/span>Windows兼容的驱动程序,它就可以被看做是一个标准的讑֤。以前在DOSpȝ下写应用E序的时候,如果要进行图形操作,那么p考虑到市Z每种昄卡的不同Q否则在装配某种昑֍的计机上就可能无法正常q行Q对汇编E序员来_q真是一个恶梦。在Win32~程中,正是GDI函数让这个恶梦成为历双Ӏ?/span>
GDI函数全部包括?/span>GDI32.DLL中,在编E的时候,注意要在源程序的开头加上相应的包含语句Q?/span>
include gdi32.inc
includelib gdi32.lib
?/span>GDI相关的内容真是太庞大了,只要查看一?/span>gdi32.inc文g可以发玎ͼ函数的L辑ֈ?/span>300多个Q和GDI相关的数据结构也非常多,Z能了?/span>GDI的原理和基本的用方法:
归纳hQ?/span>GDI操作可以?/span>3个方面去了解—?/span>When, Where?/span>HowQ?/span>
When——指的是q行囑Ş操作的时机,I竟什么时L适合E序q行囑Ş操作呢?—?#8220;GDIE序的结?#8221;
Where——指的是囑Ş该往哪里画,既然Windows隔离了硬件图形设备,那么该把什么地方当?#8220;下笔”的地方呢Q—?#8220;讑֤环境”
How——了解了上面两个问题后,最后还要知?#8220;如何?#8221;Q这涉及如何用大部分GDI函数的问题了?/span>
一?/span>GDIE序的结?/span>
1、客户区的刷?/span>
正如上面所说的Q这里讨论的?#8220;When”的问题,读者可能会问:Z么会有这个问题,如果要向H口输出囑ŞQ程序想在什么时候输出那是什么时候,Nq个时刻q有规定不成Q?/span>
?/span>DOS操作pȝ中编E的时候,E序把文字或囑Ş输出到屏q,在输出新的内容之前,q些内容L保留在屏q原处,q些内容会被意外覆盖的唯一情况是激zM?/span>TSRE序Q但TSRE序在退Z前有义务恢复原来的屏q,如果它无法恢复屏q的内容Q那么这是它的责任,我们不会在自qE序中去考虑屏幕内容会无~无故消pU情况,所以可以把屏幕看成是应用程序私有的?/span>
如果E序输出的内容过多,如用dir昄一个含有很多文件的目录Q用h本无法看清快速上ȝ屏幕Q这时程序可以设计一个参数来暂停一下,?/span>dir/p。这已经?/span>DOSE序最“体脓”的做法了Q如果用h回过头去看已l滚出屏q的内容Q那可对不vQ只能再执行一遍了Q?/span>
所以对DOSE序来说Q程序想在什么时候输Z息那是什么时候,Ҏ不存?/span>Whenq个问题?/span>
但在Windows操作pȝ中,屏幕是多个程?#8220;公用”的,用户E序不要指望输出到窗口中的内容经q一D|间后q会保留在那里,它们可能被别的东西覆盖,如其他窗口、鼠标箭头或下拉的菜单等。在Windows中,恢复被覆盖内容的责Q大部分属于用L序自己,理由很简单:Windows是个多Q务的操作pȝQ假如程?/span>B覆盖了程?/span>A的窗口内容,覆盖掉的内容q?/span>B负责恢复的话Q它必M存它覆盖掉的内容Q但是在它将保存的内Ҏ复之前,E序A也在q行Qƈ可能在程?/span>B恢复以前已经向它自己的窗口输出新的内容,l果当程?/span>B恢复它保存的H口内容Ӟ保存的内容可能是q时的(?/span>DOS的情况就不同Q?/span>TSRE序Ȁzȝ时候,用户E序是被挂v的)Q所以最好的办法是让程?/span>A自己来决定如何恢复?/span>
Windowspȝ采用的方法是Q当Windows到H口被覆盖的地方需要恢复的时候,它会向用L序发送一?/span>WM_PAINT消息Q消息中包括了需要恢复的区域Q然后由用户E序来决定如何恢复被覆盖的内宏V?/span>
如果E序因ؓ忙于处理其他事务以至于无法及时响?/span>WM_PAINT消息Q那么窗口客户区原先被覆盖的地方可能会被Windows暂时L一块白Ԍ或者背景色Q的矩ŞQ或者根本就是保留被覆盖时的情ŞQ直到程序有旉d?/span>WM_PAINT消息为止。我们常常可以看到这U情况发生在死锁E序的客户区内,q就是因为死锁的E序无法响应WM_PAINT消息来恢复客户区造成的?/span>
所以对?#8220;When”q个问题Q答案是Q程序应该在Windows要求的时候绘d户区Q也是在收?/span>WM_PAINT消息的时候。如果程序需要主动刷新客户区Q那么可以通过调用InvalidateRect{函数引发一?/span>WM_PAINT消息Q因为在WM_PAINT消息中刷新客户区的代码是必须存在的,所以用q种看似“舍近求远”的办法实际上可以节省一份重复的代码。即使是在游戏程序这U?#8220;dh”q远多于“被动h”的程序中Q只要窗口有被其他东西覆盖的可能Q那么这个原则就是适用的?/span>
2?/span>GDIE序的结?/span>
对于Win32E序来说Q?/span>WM_PAINT消息随时可能发生Q这意味着Q程序再也不能像?/span>DOS下一栯出结果后׃了Q反q来Q程序在M时刻都应该知道如何恢复整个或局部客户区中以前输出的内容?/span>
如果E序的功能比较简单,可以计及h整个客户区的代码全部安排?/span>WM_PAINT消息中完成,q样Q每ơ当客户区的全部或部分需要被更新的时候,E序重新执行整个生成客户区屏q数据的功能模块q刷新客户区。这U结构适用于功能模块很短小且执行速度很快的情况,整个q程的时间最好不过几百msQ否则,用户会在一个明昄{待旉后才看到E序把客户区中的“I洞”补上?/span>
当生成屏q数据的功能模块有些复杂的时候,应该考虑采用如下l构Q即功能模块和客户区h模块分别在不同的子程序中实现Q功能模块单独用一个子E序完成Q这个子E序可以q户通过选择菜单在WM_COMMAND消息中执行,也可以新建另外一个线和来完成QMQ它最后把计算l果攑ֈ一个缓冲区中,而每当客户区需要刷新时Q程序在WM_PAINT消息中调用客户区h子程序,q个子程序从计算好的~冲Z取出数据q输出到客户ZQ由于单U的屏幕hq程是很快的Q所以用h本来不及看到客户Z的空z?/span>
3、探?/span>WM_PAINT消息
当客户区被覆盖ƈ重新昄的时候,Windowsq不是在所有的的下都发?/span>WM_PAINT消息Q下面是几种不同的情况:
l 当鼠标光标移q窗口客户区以及图标拖过客户两种情况Q?/span>WindowsL自己保存被覆盖的区域q恢复它Qƈ不需要发?/span>WM_PAINT消息通知用户E序?/span>
l 当窗口客户区被自q下拉式菜单覆盖,或者被自己弹出的对话框覆盖后,Windows会尝试保存被覆盖的区域ƈ在以后恢复它Q如果因为某U原因无法保存ƈ恢复的话Q?/span>Windows会发送一?/span>WM_PAINT消息通知E序?/span>
l 别的情况造成H口的一部分从不可见变到可见Q如E序从最化的状态恢复,其他的窗口覆盖客户区后移开Q用h变了H口的大不一和用h动滚动条{,在这些情况下Q?/span>Windows会向H口发?/span>WM_PAINT消息?/span>
l 一些函C引发WM_PAINT消息Q如UpdateWindowQ?/span>InvalidateRect以及InvalidateRgn函数{?/span>
H口q程收到WM_PAINT消息后,q不代表整个客户区都需要被hQ有可能客户覆盖的区域只有一块Q这个区域就叫做“无效区域”Q程序只需要更新这个区域?/span>
?/span>WM_TIMER消息cMQ?/span>WM_PAINT消息也是一个低U别的消息,虽然它不会像WM_TIMER消息一栯丢弃Q但WindowsL在消息@环空的时候才?/span>WM_PAINT攑օ其中Q实际上Q?/span>Windows为每个窗口维护一?#8220;l图信息l构”Q无效区域的坐标在其中Q每当消息@环空的时候,如果Windows发现存在一个无效区域,׃攑օ一?/span>WM_PAINT消息?/span>
无效区域的坐标ƈ不附带在WM_PAINT消息的参CQ在E序中有其他Ҏ可以获取Q?/span>WM_PAINT消息只是通知E序有个区域需要更新而已Q所?/span>Windows也不会同时将两条WM_PAINT消息攑օ消息循环Q当Windows要放入一?/span>WM_PAINT消息的时候,如果发现已存在一个无效区域了Q那么它只需要把新旧两个无效区域合ƈ计算Z个新的无效区域就可以了,消息循环中还是只需要一?/span>WM_PAINT消息?/span>
׃存在“无效区域”q样一个东西,所以程序在WM_PAINT消息中对客户区刷新完毕后工作q没有结束,如果不无效区域变得有效Q?/span>Windows会在下一轮消息@环中l箋攑օ一?/span>WM_PAINT消息。当Windows?#8220;l图信息l构”的时候发现没有了无效区域Q也׃会l发?/span>WM_PAINT消息了?/span>
WM_PAINT消息的处理流E一般是Q?/span>
.if eax == WM_PAINT ;eax?/span>uMsg
invoke BeginPaint, hWnd, addr stPS
;h客户区的代码
invoke EndPaint, hWnd, addr stPS
xor eax, eax
ret
读者可以发C间ƈ没有调用ValidateRect来无效区域变得有效Q这是因?/span>BeginPaint函数?/span>EndPaint函数隐含有这个功能,如果不是?/span>BeginPaint/EndPaint当做消息处理代码的头话,那么?/span>WM_PAINT消息q回的时候就必须调用ValidateRect函数?/span>
BeginPaint函数的第二个参数是一个绘图信息结构的~冲区地址Q?/span>Windows会在q里q回l图信息l构Q结构中包含了无效区域的位置和大,l图信息l构的定义如下:
PAINTSTRUCT STRUCT
hdc DWORD ?
fErase DWORD ?
rcPaint RECT <>
fRestore DWORD ?
fIncUpdate DWORD ?
rgbReserved BYTE 32 dup(?)
PAINTSTRUCT ENDS
其中hdc字段是窗口的讑֤环境句柄Q?/span>rcPaint字段是一?/span>RECTl构Q它指定了无效区域矩形的对角点Q?/span>fErase字段如果为非零|表示Windows在发?/span>WM_PAINT消息前已l用背景色擦除了无效区域Q后?/span>3个字D|Windows内部使用的,应用E序不必ȝ会它们?/span>
二、设备环?/span>
解决?#8220;When”的L后,再考虑一?#8220;Where”的问题?/span>
?/span>DOS操作pȝ中,向屏q输出数据实际上是把输出内容拯到视频缓冲区中,如果在文本模式下昄信息Q只需要把内容拯?/span>B8000h处的内存中;昄囑Ş信息Q可以把囑Ş数据拯?/span>A0000h处的内存中?/span>
?/span>Windows中,GDI接口把程序和g分隔出来Q在Win32~程中,再也不能通过直接向视频缓冲区拯数据的办法来昄信息了,那么Q究竟该往哪里输出囑Ş呢——这是“Where”的问题。答案是Q通过“讑֤环境”来输出图形?/span>
1、什么是讑֤环境
?/span>Windows中,所有与囑Ş相关的操作都是用l一的方法来完成的(不然׃能称?#8220;囑Ş讑֤接口”了)。不是l画屏幕上的一个窗口,q是把图形输出到打印机,或者对一q位图进行绘画,使用的绘囑և数都是相同的Qؓ了实现方法上的统一Q必d所有的囑Ş对象看成是一个虚拟的讑֤Q这些设备可能有不同的属性,如黑白打印机和彩色屏q的颜色深度是不同的Q不同打印机的尺寸和分L率可能是不同的,l图仪只支持矢量而不支持位图{。不同设备的不同属性就构成了一个绘囄“环境”Q就?/span>DOS操作pȝ中把视频~冲区当做图形操作的对象一Pq个l图?#8220;环境”是Win32~程中图形操作的对象Q把它叫?#8220;讑֤环境”。设备环境实际上是一个数据结构,l构中保存的是讑֤的属性,当对讑֤环境q行囑Ş操作的时候,Windows可以Ҏq些属性找到对应的讑֤q行相关的操作?/span>
在实际用中Q通过“讑֤环境”可以操作的对象很q泛Q除了可以是打印机或l图仪等g讑֤外,也可以是H口的客户区Q包括大大小的所有可以被UCؓH口的按钮与控g{的客户区,也可以是一个位图。MQQ何需要用到图形操作的东西都可以通过“讑֤环境”q行l图?/span>
Z更好地理?#8220;讑֤环境”是什么,先来看一个例子:
//DcCopy.asm
.386
.model flat, stdcall
option casemap:none
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Include 文g定义
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include windows.inc
include gdi32.inc
includelib gdi32.lib
include user32.inc
includelib user32.lib
include kernel32.inc
includelib kernel32.lib
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
ID_TIMER equ 1
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 数据D?/span>
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.data?
hInstance dd ?
hWin1 dd ?
hWin2 dd ?
.const
szClass1 db 'SourceWindow',0
szClass2 db 'DestWindow',0
szCaption1 db '请尝试用别的H口覆盖本窗?/span>!',0
szCaption2 db '本窗口图像拷贝自另一H口',0
szText db 'Win32 Assembly, Simple and powerful!',0
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.code
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 定时器过E?/span>
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_ProcTimer proc _hWnd, uMsg, _idEvent, _dwTime
local @hDc1, @hDc2
local @stRect:RECT
invoke GetDC, hWin1
mov @hDc1, eax
invoke GetDC, hWin2
mov @hDc2,eax
invoke GetClientRect, hWin1, addr @stRect
invoke BitBlt, @hDc2, 0, 0, @stRect.right, @stRect.bottom, @hDc1, 0, 0, SRCCOPY
invoke ReleaseDC, hWin1, @hDc1
invoke ReleaseDC, hWin2, @hDc2
ret
_ProcTimer endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; H口q程
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_ProcWinMain proc uses ebx edi esi, hWnd, uMsg, wParam, lParam
local @stPs:PAINTSTRUCT
local @stRect:RECT
local @hDc
mov eax, uMsg
mov ecx, hWnd
;****************************************************************
.if eax == WM_PAINT && ecx == hWin1
invoke BeginPaint, hWnd, addr @stPs
mov @hDc, eax
invoke GetClientRect, hWnd, addr @stRect
invoke DrawText, @hDc, addr szText, -1, addr @stRect, DT_SINGLELINE or DT_CENTER or DT_VCENTER
invoke EndPaint, hWnd, addr @stPs
;****************************************************************
.elseif eax == WM_CLOSE
invoke PostQuitMessage, NULL
invoke DestroyWindow, hWin1
invoke DestroyWindow, hWin2
;****************************************************************
.else
invoke DefWindowProc, hWnd, uMsg, wParam, lParam
ret
.endif
;****************************************************************
xor eax, eax
ret
_ProcWinMain endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_WinMain proc
local @stWndClass:WNDCLASSEX
local @stMsg:MSG
local @hTimer
invoke GetModuleHandle, NULL
mov hInstance, eax
invoke RtlZeroMemory, addr @stWndClass, sizeof @stWndClass
;****************************************************************
invoke LoadCursor, 0, IDC_ARROW
mov @stWndClass.hCursor, eax
push hInstance
pop @stWndClass.hInstance
mov @stWndClass.cbSize, sizeof WNDCLASSEX
mov @stWndClass.style, CS_HREDRAW or CS_VREDRAW
mov @stWndClass.lpfnWndProc, offset _ProcWinMain
mov @stWndClass.hbrBackground, COLOR_WINDOW + 1
mov @stWndClass.lpszClassName, offset szClass1
invoke RegisterClassEx, addr @stWndClass
invoke CreateWindowEx, WS_EX_CLIENTEDGE, offset szClass1, offset szCaption1, WS_OVERLAPPEDWINDOW, 450, 100, 300, 300, NULL, NULL, hInstance, NULL
mov hWin1, eax
invoke ShowWindow, hWin1, SW_SHOWNORMAL
invoke UpdateWindow, hWin1
;****************************************************************
mov @stWndClass.lpszClassName, offset szClass2
invoke RegisterClassEx, addr @stWndClass
invoke CreateWindowEx, WS_EX_CLIENTEDGE, offset szClass2, offset szCaption2, WS_OVERLAPPEDWINDOW, 100, 100, 300, 300, NULL, NULL, hInstance, NULL
mov hWin2, eax
invoke ShowWindow, hWin2, SW_SHOWNORMAL
invoke UpdateWindow, hWin2
;****************************************************************
; 讄定时?/span>
;****************************************************************
invoke SetTimer, NULL, NULL, 100, addr _ProcTimer
mov @hTimer, eax
;****************************************************************
; 消息循环
;****************************************************************
.while TRUE
invoke GetMessage, addr @stMsg, NULL, 0, 0
.break .if eax == 0
invoke TranslateMessage, addr @stMsg
invoke DispatchMessage, addr @stMsg
.endw
;****************************************************************
; 清除定时?/span>
;****************************************************************
invoke KillTimer, NULL, @hTimer
ret
_WinMain endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
start:
call _WinMain
invoke ExitProcess, NULL
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
end start
q个E序的代码用到的大部分知识都是前面已l讲到的Q在_WinMain中,用一个同LH口cd立了两个H口Q两个窗口属于同一个窗口类Q所以它们的H口q程都是_ProcWinMainQؓ了关闭Q何一个窗口都可以l束E序Q?/span>WM_CLOSE消息中用DestroyWindow函数摧毁了两个窗口。程序设|了一个周期ؓ100ms的定时器Q?/span>Windows会每?/span>100ms调用_ProcTimer子程序。在_ProcTimer中,其中一个窗口的客户区拷贝到另一个窗口的客户ZQ方法是通过GetDC获取H口?/span>DC句柄Qƈ?/span>BitBlt函数完成拯工作Q所以在双的窗口显CZ一?#8220;Win32 Assembly, Simple and powerful!”Q左边的H口中也会出现这句话?/span>
E序?/span>100ms右边窗口的客户区拷贝到左边的窗口客户区中,通过左边H口的客户区可以了解右边客户区?/span>DC对应的究竟是什么内宏V?/span>
通过左边H口的变化可以惊奇地发现Q右边窗口客户区的内容ƈ不是E序自己输出到客户区的那句文本,而是以客户区为矩形区域的屏幕上我们真正看到的东西Q它竟然包括其他H口覆盖在上面的东西。这意味着Q扫h戏和U牌游戏通过自己客户区对应的讑֤环境d形,囑Ş数据竟然d?/span>DcCopyH口客户区对应的讑֤环境中?/span>
q个例子验证?strong>“讑֤环境”只是“环境”而不?#8220;讑֤”Q它q不存储发给它的囑Ş数据Q图形数据透过它写C它所描述?#8220;讑֤”上,每个H口客户区的“讑֤环境”对应的设备都是屏q,但它们在位置上可能重叠,所以向一个窗口的客户区写数据相当于同时写了下层窗口的客户区?/strong>
Z让当前激zȝH口在视觉上保持在最上面Q下层窗口向自己客户区写的内定w先要l过Windows?#8220;qo”Q只有没有被其他H口覆盖掉的部分才真正被写到了屏q上?/span>
读者应该时L醒自己—?#8220;讑֤环境”只是一个环境,是设备属性的一l定义,E序输出的图形数据透过“讑֤环境”被定向到了具体的讑֤上,“讑֤环境”本nq不存储q些数据?/span>
Device Context?/span>Context的含义:讑֤环境的上面是应用E序Q下面是具体讑֤Q而它是用?#8220;联系上下关系”用的?/span>
有h可能认ؓQ屏q上的窗口就像放在桌面上的一张张U,虽然一张纸可能暂时被另一张遮住,但纸上写的东西还是存在的Q移开另一张纸可以再ơ露出来。但实际情况是:桌面更像一个用_笔写的公告黑板Q一个窗口相当于划了一块空间写告示Q写另一个告C的时候要把老告C的内容擦去一部分以便写新的内容,擦去的东西也׃存在了,如果要恢复老告C,那么必须把擦ȝ部分重新写上厅R?/span>
2、获取设备环境句?/span>
要想对Q何设备绘图,首先必须获取讑֤?#8220;讑֤环境句柄”Q?/span>hDCQ,几乎所有的GDI函数的操作目标都?/span>hDCQ在E序中得C?/span>hDC有几U方法?/span>
最常用的方法是?/span>WM_PAINT消息中用BeginPaint函数得到hDCQ?/span>WM_PAINT消息的代码结构一般是Q?/span>
.if eax == WM_PAINT ;eax?/span>uMsg
invoke BeginPaint, hWnd, addr stPS
;h客户区的代码
invoke EndPaint, hWnd, addr stPS
xor eax, eax
ret
BeginPaint函数的返回值就是需要刷新区域的hDC。要注意的是Q?/span>BeginPaintq回?/span>hDC对应的尺总是无效区域,无法用它l画到这个区域以外的地方厅R由于窗口过E每ơ接?/span>WM_PAINT消息时的无效区域可能是不同的Q所以这?/span>hDC的g?/span>WM_PAINT消息中有效,E序不应该保存它q把它用?/span>WM_PAINT消息以外的代码中。基于同L道理Q?/span>BeginPaint?/span>EndPaint函数只能用在WM_PAINT消息中,因ؓ只有q时候才存在无效区域?/span>
E序中常常有q种需求,是在非WM_PAINT消息中主动绘d户区Q由?/span>BeginPaint?/span>EndPaint函数必须?/span>WM_PAINT消息中用,所以这时必ȝ另外的方法获?/span>hDCQ可以用以下的ҎQ?/span>
invoke GetDC, hWnd ;获取hDC
;q回值是hDC
;l图代码
invoke ReleaseDC, hWnd ;释放hDC
GetDC函数q回?/span>hDC对应H口的整个客户区Q当使用完毕的时候,hDC必须?/span>ReleaseDC函数释放。对于用GetDC获取?/span>hDCQ?/span>Windows使用的范围限于单条消息内Q当E序在处理某条消息的时候需要绘d户区Ӟ可以?/span>GetDC获取hDCQ但在消息返回前Q必ȝReleaseDC它释放掉,如果在下一条消息中需要l用到hDCQ那么必重新用GetDC函数获取?/span>
上面的两U方法获取的hDC都是H口?/span>hDCQ如果要操作的是其他的东西,如打印机、位囄Q就不能使用BeginPaint?/span>GetDC函数了。当l图的对象是一个设备的时候,可以?/span>CreateDC函数来徏立一?/span>DCQ?/span>
invoke CreateDC, lpszDriver, lpszDevice, lpszOutput, lpInitData
lpszDriver指向讑֤名称Q如昄讑֤的设备名?/span>DISPLAYQ打印机的设备名一般ؓWINSPOOLQ下面这几句代码建立?/span>DC对应整个屏幕Q?/span>
szDriver db “DISPLAY”,0
…
invoke CreateDC, addr szDriver, NULL, NULL, NULL
mov hDC, eax
当绘囑֯象是位图的时候,同样需要一个和位图句柄相联pȝDCQ这时可以用函数CreateCompatibleDC来创Z个显C面仅存在于内存中?/span>DCQ?/span>
invoke CreateCompatibleDC, hDC
参数中的hDC是用来参考的DC句柄Q如果指定的参数?/span>NULLQ那么徏立的DC和当前屏幕的设|兼容,Z?/span>CreateCompatibleDC建立?/span>DCl画一个位图,q需要用SelectObject函数?/span>hDC和位囑֏柄联pv来?/span>
?/span>CreateDC?/span>CreateCompatibleDC函数建立?/span>hDC在用结束以后,必须?/span>DeleteDC函数删除Q注意这里不能用ReleaseDCQ这个函数是?/span>GetDC配合用的?/span>
?/span>BeginPaint/EndPaint以及GetDC获取?/span>hDC的用时间不能超出本条消息,与此相比Q用CreateDC以及CreateCompatibleDC建立?/span>hDC没有这个限Ӟ可以在Q何时d立它q且一直用到不再需要ؓ止?/span>
三、色彩和坐标
1?/span>Windows中的色彩
可以表示的颜色L由颜色深度决定,也就是存储每个像素所用的位数Q各U显C备可以显C的颜色L可能大不相同Q如果设备支持的颜色深度太浅Q就会媄响到囑փ的质量,会让人看h觉得很粗p和不自然?/span>
一U颜色可以分解成U、绿、蓝三原Ԍ所以可以用U、绿、蓝3个分量的l合来表C各U颜艌Ӏ?/span>
当设备支持的颜色深度于{于8位时Q如8位(256Ԍ?/span>4位(16Ԍ?/span>2位(4Ԍ?/span>1位(2ԌQ,M位数太少Q不以用来表达3个颜色分量,q时pȝ建立一个色彩表Q像素数据用来做索引在色彩表中获取颜色|所以低?/span>8位的颜色UCؓ索引艌Ӏ?/span>
只有当颜色深度大?/span>8位的时候,像素数据中才直接包含U、绿、蓝3个分量。当颜色深度?/span>16位的时候,U、绿、蓝各用5位表C,剩下?/span>1位用做属性位Q实际可以表C的颜色数目?/span>2^15=32 768U,16位深度的彩色又称?/span>16位色、高彩色或增。当颜色深度?/span>24位的时候,3个分量各?/span>8位表C,实际可以表示的颜色数目ؓ2^24=16777216U,24位深度的彩色又称?/span>24位色?/span>
?/span>Win32的编E中Q统一使用32位的整数表示一个深度ؓ24位的颜色Q在q?/span>32位中只用低24位,每一U原色分量占?/span>8位,其中0~7位ؓU色Q?/span>8~15位ؓl色Q?/span>16~23位ؓ蓝色。在E序中用CU颜色常数的时候,可以如下使用Q?/span>
move ax, U色 + l色*100h + 蓝色*10000h ;颜色放?/span>eax?/span>
当显C备无法表C?/span>24位色的时候,Windows会自动用讑֤可以昄的最接近的颜色来代替它,当显C备的颜色深度比较低的时候,可以通过函数GetNearestColor来得知一U颜Ԍ颜色Q会被系l替换成哪种颜色Q?/span>
invoke GetNearestColor, hDC, dwColor ;q回真正使用的颜色?/span>
但是当显C备颜色深度太低的时候,l过Windows自动转换的图像可能会让h觉得很不自然Q所以在有些时候,E序员可能希望预先得知设备的颜色深度Q然后根据具体情冉|CZ同的囑Ş?/span>
昄讑֤的颜色深度可以用以下函数获取Q?/span>
invoke GetDeviceCaps, hDC, PLANES
mov ebx, dwPlanes
invoke GetDeviceCaps, hDC, BITSPIXEL
mul ebx
mov dwColorDepth, eax
W一个函数调用返?/span>DC的色彩^面数Q第二个函数调用q回每个像素的色彩位敎ͼ颜色深度最后可以通过dwPlanes乘以dwBitsPixel得到?/span>
2?/span>Windows中的坐标p?/span>
要用GDI函数l图Q就必须首先了解q些函数使用的坐标系Q在默认的状态下Q?/span>Windows坐标pM左上角做坐标原点Q以x当做X坐标的正方向Q以下方当做Y坐标的正方向。坐标的数D用一个有W号?/span>16位数来表C,范围?/span>-32 768~32767Q坐标的单位为像素。这U坐标系定义Ҏ的好处是Q窗口中每一点的坐标不会因ؓH口的大改变而改变,试想一下,如以数学中通常的表C方法,以左下角做坐标原点,那么当窗口高度被用户调整的时候,客户Z每一点的Y坐标都会变化Q在具体使用中就会有诸多不便?/span>
但是Windows也提供了其他的一些坐标映方法供E序员用,可以?/span>SetMapMode函数来ؓ一?/span>DC讄新的坐标映射ҎQ?/span>
invoke SetMapMode, hDC, iMapMode
可以讄的参数包括坐标原炏V坐标和逻辑单位和坐标的正方向等Q参C?/span>iMapMode为新的映方式,其可以选择的取值如下表所C,Windows默认使用的映方式ؓMM_TEXT?/span>
Windows中可用的坐标映射方式
映射方式 |
原点 |
逻辑单位 |
X正方?/span> |
Y正方?/span> |
MM_TEXT(默认方式) |
左上 |
像素 |
?/span> |
?/span> |
MM_HIENGLISH |
左上 |
0.001英寸 |
?/span> |
?/span> |
MM_LOENGLISH |
左上 |
0.01英寸 |
?/span> |
?/span> |
MM_HIMETRIC |
左上 |
0.01毫米 |
?/span> |
?/span> |
MM_LOMETRIC |
左上 |
0.1毫米 |
?/span> |
?/span> |
MM_TWIPS |
左上 |
1/1440英寸 |
?/span> |
?/span> |
MM_ISOTROPIC |
可变 |
可变Q?/span>x=yQ?/span> |
可变 |
可变 |
MM_ANISOTROPIC |
可变 |
可变Q?/span>x!=yQ?/span> |
可变 |
可变 |
可以看到Q除了默认的MM_TEXT方式外,下面5U映方式:MM_HIENGLISHQ?/span>MM_LOENGLISHQ?/span>MM_HIMETRICQ?/span>MM_LOMETRIC?/span>MM_TWIPS采用的都是原点位于左上角?/span>X正方向向上的映射方式Q另外,它们的坐标逻辑单位是不同的?/span>
最后的两种映射方式MM_ISOTROPIC?/span>MM_ANISOTROPIC提供了更灉|的选择Q设|ؓq两U映方式后Q程序可以l调?/span>SetViewportOrgExQ?/span>SetViewportExtEx?/span>SetWindowExtEx函数来自p|坐标系的原炏V逻辑单位和坐标的正方向等所有参数。在其他映射方式下的时候,不能使用q?/span>3个设|函敎ͼq时M对它们的调用都会被忽略?/span>