??xml version="1.0" encoding="utf-8" standalone="yes"?>久久婷婷五月综合色奶水99啪,69久久夜色精品国产69,2021久久精品免费观看http://www.shnenglu.com/mybios/category/3029.html游戏开?C++ Cocos2d-x OpenGL DirectX 数学 计算机图形学 SQL Server <BR> <BR>zh-cnSun, 17 Jul 2016 21:45:47 GMTSun, 17 Jul 2016 21:45:47 GMT60关于CEGUI的String的调试问?/title><link>http://www.shnenglu.com/mybios/archive/2007/07/29/28914.html</link><dc:creator>李锦?mybios)</dc:creator><author>李锦?mybios)</author><pubDate>Sun, 29 Jul 2007 02:17:00 GMT</pubDate><guid>http://www.shnenglu.com/mybios/archive/2007/07/29/28914.html</guid><wfw:comment>http://www.shnenglu.com/mybios/comments/28914.html</wfw:comment><comments>http://www.shnenglu.com/mybios/archive/2007/07/29/28914.html#Feedback</comments><slash:comments>11</slash:comments><wfw:commentRss>http://www.shnenglu.com/mybios/comments/commentRss/28914.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/mybios/services/trackbacks/28914.html</trackback:ping><description><![CDATA[CEGUI的String不是std::string或std::wstringQ而是自己实现的一个字W串c,他的功能跟std的string很接q?br>但是Q他支持unicodeQ内部存储是使用utf32~码规范来存储unicode字符Q也是?nbsp;typedef  uint32 utf32; utf32*  d_buffer;用这?2位无W号整型的数l来保存unicode字符丌Ӏ优Ҏ显而易见的Q就是世界上所有字W都可以包囊q去Q毕竟是32位啊Q但是,~点也出来了Q有两点Q?br>W一、内存占用过多,一个字W就要占4个字节,也太费了点Q?br>W二、调试不方便Q由于VS2005的调试窗口只支持ansi和utf16的格式,所以,CEGUI的String在调试器中只能看C堆数字数l,而看不到字符Q这是很郁闷的,每次要查看都要翻到内存那里看Q而且q一堆ؕ码,ȝ?br><br>解决办法Q修改Stringc,使用utf16来代替CEGUI的utf32?br>优点Q?br>解决了内存占用过多的问题Q一个字W只?个字节就可以了;<br>解决了调试问题,VS2005直接支持utf16的显C?br>~点Q?br>可能不支持全世界的字W,因ؓutf16不能表示过16位的字符Q但是,对于大多数国家的字符来说Q已l够了Q毕竟windows2000/xp也是Zutf16~码的?br><br>然后Q下面是修改后的字符串类Q?a title=CEGUIString href="http://www.shnenglu.com/Files/mybios/CEGUIString.rar">CEGUIString</a><br> <img src ="http://www.shnenglu.com/mybios/aggbug/28914.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/mybios/" target="_blank">李锦?mybios)</a> 2007-07-29 10:17 <a href="http://www.shnenglu.com/mybios/archive/2007/07/29/28914.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>在windows下用patch工具更新源码http://www.shnenglu.com/mybios/archive/2007/07/28/28900.html李锦?mybios)李锦?mybios)Sat, 28 Jul 2007 09:09:00 GMThttp://www.shnenglu.com/mybios/archive/2007/07/28/28900.htmlhttp://www.shnenglu.com/mybios/comments/28900.htmlhttp://www.shnenglu.com/mybios/archive/2007/07/28/28900.html#Feedback4http://www.shnenglu.com/mybios/comments/commentRss/28900.htmlhttp://www.shnenglu.com/mybios/services/trackbacks/28900.html但是Q我们下载到的patch文gQ貌似是linux/unix的diff工具生成的,要用linux/unix的patch工具才能把补丁文件更新到源码中?br />后来Q我发现了个windows下可以用的patch工具Q网址如下Q?a >http://gnuwin32.sourceforge.net/packages/patch.htm
使用是很单的Q用命o行方式执行:
patch 源文?补丁文g

例如我们有源文gtest.cppQ下载了个补丁文件test.patchQ那么执行patch test.cpp test.patchQ就会自动把patch里的内容更新到test.cpp中去了?br />
PSQcygwin貌似也有q个工具吧。。以前看q里面好像还有diff工具Q可以生成patch文gQ呵c?br />

如果本文对你的开发有所帮助Qƈ且你手头恰好有零钱?/p>

不如打赏我一杯咖啡,鼓励我l分享优U的文章?br />





李锦?mybios) 2007-07-28 17:09 发表评论
]]>
关于GOOF的bug问题http://www.shnenglu.com/mybios/archive/2007/07/16/28157.html李锦?mybios)李锦?mybios)Mon, 16 Jul 2007 14:53:00 GMThttp://www.shnenglu.com/mybios/archive/2007/07/16/28157.htmlhttp://www.shnenglu.com/mybios/comments/28157.htmlhttp://www.shnenglu.com/mybios/archive/2007/07/16/28157.html#Feedback10http://www.shnenglu.com/mybios/comments/commentRss/28157.htmlhttp://www.shnenglu.com/mybios/services/trackbacks/28157.html使用了几天GOOFQ发C存在很多bug啊,什么缓存溢出,数组界之类的。。很明显q个框架没有真正用在一个项目上的。我列D几个大问题吧。好让大家别到处壁?br />bool EnvironmentGameSystem::save(DataElementPtr element)q个函数没有实现Q所以无法保存环境信息?br />
q有
 void GridPartition::enumerateConnectedPartitions(vector<CorePartition*>& connected)
 {
  //get surrounding grid cells within a certain radius
  float loadRadius = mGridPartitionMgr->getGridCellLoadRadius();

  //enumerate partitions
  vector<CorePartition*> partitions;
  mGridPartitionMgr->enumeratePartitions(partitions);

  //iterate through and check distance
  for(vector<CorePartition*>::iterator itr = partitions.begin(); itr != partitions.end(); ++itr)
  {
   float distance = Vector3(getWorldPosition() - (*itr)->getWorldPosition()).length();
   // add by 李锦?2007-7-16
   // 不要q回自己作ؓdQ会产生bug
   if(distance < loadRadius && *itr != this)
    connected.push_back(*itr);
  }
 }

再给Z个比较严重的bug
GOOFTranslationManipulator.h中的
  // add by 李锦?2007-7-12
  // 不要用魔术数Q搞到缓存溢?br />  SceneNode* mNode[AT_LAST];
  Entity* mEnt[AT_LAST];
  Entity* mConeEnt[AT_LAST];
  CollisionShapePtr mCol[AT_LAST];
  AxisManipulatorHandle* mHandle[AT_LAST];

另外QCorePartition中的setSkyboxMaterial、setGlobalAmbient之类的代码貌似没用。准备弃之?br />


    // add by 李锦?2007-7-16
    // q个法暂时有问题,先屏蔽,以后再慢慢解?br />    //disable static geometry until it is fixed
    if(false)// getStaticGeometryRule() == SGR_ALWAYS || (getStaticGeometryRule() == SGR_WHEN_NOT_PROX_IMMEDIATE && getPartition()->getProximity() != CorePartition::PROX_IMMEDIATE))
    {
     willConvertToStaticGeometry = true;
     getPartition()->addObjectToConvertToStaticGeometry(this);
    }

李锦?mybios) 2007-07-16 22:53 发表评论
]]>
VS2003下编译Windows计算?/title><link>http://www.shnenglu.com/mybios/archive/2006/12/02/15889.html</link><dc:creator>李锦?mybios)</dc:creator><author>李锦?mybios)</author><pubDate>Sat, 02 Dec 2006 08:10:00 GMT</pubDate><guid>http://www.shnenglu.com/mybios/archive/2006/12/02/15889.html</guid><wfw:comment>http://www.shnenglu.com/mybios/comments/15889.html</wfw:comment><comments>http://www.shnenglu.com/mybios/archive/2006/12/02/15889.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.shnenglu.com/mybios/comments/commentRss/15889.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/mybios/services/trackbacks/15889.html</trackback:ping><description><![CDATA[工程已经放上Q?a href="http://www.shnenglu.com/Files/mybios/calc.rar">下蝲回去~译p</a>Q放个脓图:<br /><br /><img height="309" alt="Calc.JPG" src="http://www.shnenglu.com/images/cppblog_com/mybios/ArticlePics/Calc.JPG" width="480" border="0" /><img src ="http://www.shnenglu.com/mybios/aggbug/15889.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/mybios/" target="_blank">李锦?mybios)</a> 2006-12-02 16:10 <a href="http://www.shnenglu.com/mybios/archive/2006/12/02/15889.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>今天遇到了郁LC函数Q幸好遇到高手帮忙解决了http://www.shnenglu.com/mybios/archive/2006/11/30/15817.html李锦?mybios)李锦?mybios)Thu, 30 Nov 2006 08:30:00 GMThttp://www.shnenglu.com/mybios/archive/2006/11/30/15817.htmlhttp://www.shnenglu.com/mybios/comments/15817.htmlhttp://www.shnenglu.com/mybios/archive/2006/11/30/15817.html#Feedback0http://www.shnenglu.com/mybios/comments/commentRss/15817.htmlhttp://www.shnenglu.com/mybios/services/trackbacks/15817.html
char sChar[MAX_PATH];
const WCHAR wChar[] = L"我的朋友";
// 把wCharq个Unicode字符串{换成ANSI字符Ԍ保存到sCharQƈ且返回ANSI的字W串大小Q如果失败,则返?1
  wcstombs(sChar, wChar, MAX_PATH);

q样是运行不q不ȝQLq回-1?br />
后来lh提醒Q需要在调用wcstombs之前要先讄代码:

char sChar[MAX_PATH];
const WCHAR wChar[] = L"我的朋友";

// 讄代码ؓ默认代码?br />  _tsetlocale(LC_ALL,_T(""));
// 把wCharq个Unicode字符串{换成ANSI字符Ԍ保存到sCharQƈ且返回ANSI的字W串大小Q如果失败,则返?1
  wcstombs(sChar, wChar, MAX_PATH);


q样可以了Q不用调用烦人的WideCharToMultiByteQ多好啊Q?br />相反的函敎ͼmbstowcsQ可以从ANSI转换到Unicode

李锦?mybios) 2006-11-30 16:30 发表评论
]]>
【{贴】C语言高效~程的几?/title><link>http://www.shnenglu.com/mybios/archive/2006/11/21/15514.html</link><dc:creator>李锦?mybios)</dc:creator><author>李锦?mybios)</author><pubDate>Tue, 21 Nov 2006 09:26:00 GMT</pubDate><guid>http://www.shnenglu.com/mybios/archive/2006/11/21/15514.html</guid><wfw:comment>http://www.shnenglu.com/mybios/comments/15514.html</wfw:comment><comments>http://www.shnenglu.com/mybios/archive/2006/11/21/15514.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.shnenglu.com/mybios/comments/commentRss/15514.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/mybios/services/trackbacks/15514.html</trackback:ping><description><![CDATA[引言Q?br />  ~写高效z的C语言代码Q是许多软g工程师追求的目标。本文就工作中的一些体会和l验做相关的阐述Q不对的地方请各位指教?br /><br />W?招:以空间换旉<br /><br />  计算机程序中最大的矛盾是空间和旉的矛盾,那么Q从q个角度出发逆向思维来考虑E序的效率问题,我们有了解决问题的W?招——以I间换时间?br />例如Q字W串的赋倹{?br />ҎAQ通常的办法:<br />#define LEN 32<br />char string1 [LEN];<br />memset (string1,0,LEN);<br />strcpy (string1,“This is a example!!”);<br />ҎBQ?br />const char string2[LEN] =“This is a example!?<br />char * cp;<br />cp = string2 ;<br />(使用的时候可以直接用指针来操作?<br /><br />  从上面的例子可以看出QA和B的效率是不能比的。在同样的存储空间下QB直接使用指针可以操作了Q而A需要调用两个字W函数才能完成。B的缺点在于灵zL没有A好。在需要频J更改一个字W串内容的时候,Ah更好的灵zL;如果采用ҎBQ则需要预存许多字W串Q虽然占用了大量的内存,但是获得了程序执行的高效率?br /><br />  如果pȝ的实时性要求很高,内存q有一些,那我推荐你用该招数?br /><br />  该招数的变招——用宏函数而不是函数。D例如下:<br />ҎCQ?br />#define bwMCDR2_ADDRESS 4<br />#define bsMCDR2_ADDRESS 17<br />int BIT_MASK(int __bf)<br />{<br />return ((1U << (bw ## __bf)) - 1) << (bs ## __bf);<br />}<br />void SET_BITS(int __dst, int __bf, int __val)<br />{<br />__dst = ((__dst) & ~(BIT_MASK(__bf))) | \<br />(((__val) << (bs ## __bf)) & (BIT_MASK(__bf))))<br />}<br /><br />SET_BITS(MCDR2, MCDR2_ADDRESS, RegisterNumber);<br />ҎDQ?br />#define bwMCDR2_ADDRESS 4<br />#define bsMCDR2_ADDRESS 17<br />#define bmMCDR2_ADDRESS BIT_MASK(MCDR2_ADDRESS)<br />#define BIT_MASK(__bf) (((1U << (bw ## __bf)) - 1) << (bs ## __bf))<br />#define SET_BITS(__dst, __bf, __val) \<br />((__dst) = ((__dst) & ~(BIT_MASK(__bf))) | \<br />(((__val) << (bs ## __bf)) & (BIT_MASK(__bf))))<br /><br />SET_BITS(MCDR2, MCDR2_ADDRESS, RegisterNumber);<br /><br />  函数和宏函数的区别就在于Q宏函数占用了大量的I间Q而函数占用了旉。大家要知道的是Q函数调用是要用系l的栈来保存数据的,如果~译器里有栈查选项Q一般在函数的头会嵌入一些汇~语句对当前栈进行检查;同时QCPU也要在函数调用时保存和恢复当前的现场Q进行压栈和Ҏ操作Q所以,函数调用需要一些CPU旉。而宏函数不存在这个问题。宏函数仅仅作ؓ预先写好的代码嵌入到当前E序Q不会生函数调用,所以仅仅是占用了空_在频J调用同一个宏函数的时候,该现象尤其突出?br /><br />  DҎ是我看到的最好的|位操作函数Q是ARM公司源码的一部分Q在短短的三行内实现了很多功能,几乎늛了所有的位操作功能。CҎ是其变体Q其中滋呌需大家仔细体会?br /><br />W?招:数学Ҏ解决问题<br /><br />  现在我们演绎高效C语言~写的第二招——采用数学方法来解决问题?br /><br />  数学是计机之母Q没有数学的依据和基Q就没有计算机的发展Q所以在~写E序的时候,采用一些数学方法会对程序的执行效率有数量的提高?br />举例如下Q求 1~100的和?br />ҎE<br />int I , j;<br />for (I = 1 ;I<=100; I ++Q{<br />j += I;<br />}<br />ҎF<br />int I;<br />I = (100 * (1+100)) / 2<br /><br />  q个例子是我印象最q一个数学用例,是我的计机启蒙老师考我的。当时我只有学三年U,可惜我当时不知道用公?N×QN+1Q? 2 来解册个问题。方法E循环?00ơ才解决问题Q也是说最用?00个赋|100个判断,200个加法(I和jQ;而方法F仅仅用了1个加法,1 ơ乘法,1ơ除法。效果自然不a而喻。所以,现在我在~程序的时候,更多的是动脑{找规律Q最大限度地发挥数学的威力来提高E序q行的效率?br /><br />W?招:使用位操?br /><br />  实现高效的C语言~写的第三招——用位操作Q减除法和取模的运?br /><br />  在计机E序中,数据的位是可以操作的最数据单位,理论上可以用“位q算”来完成所有的q算和操作。一般的位操作是用来控制g的,或者做数据变换使用Q但是,灉|的位操作可以有效地提高程序运行的效率。D例如下:<br />ҎG<br />int I,J;<br />I = 257 /8;<br />J = 456 % 32;<br />ҎH<br />int I,J;<br />I = 257 >>3;<br />J = 456 - (456 >> 4 << 4);<br /><br />  在字面上好像H比Gȝ了好多,但是Q仔l查看生的汇编代码׃明白Q方法G调用了基本的取模函数和除法函敎ͼ既有函数调用Q还有很多汇~代码和寄存器参与运;而方法H则仅仅是几句相关的汇~,代码更简z,效率更高。当Ӟ׃~译器的不同Q可能效率的差距不大Q但是,以我目前遇到的MS C ,ARM C 来看Q效率的差距q是不小。相x~代码就不在q里列D了?br />q用q招需要注意的是,因ؓCPU的不同而生的问题。比如说Q在PC上用q招~写的程序,q在PC上调试通过Q在ULC?6位机q_上的时候,可能会生代码隐患。所以只有在一定技术进阶的基础下才可以使用q招?br /><br />W?招:汇编嵌入<br /><br />  高效C语言~程的必杀技Q第四招——嵌入汇~?br /><br />  “在熟悉汇编语言的h眼里QC语言~写的程序都是垃䏀。这U说法虽然偏Ȁ了一些,但是却有它的道理。汇~语a是效率最高的计算aQ但是,不可能靠着它来写一个操作系l吧?所以,Z获得E序的高效率Q我们只好采用变通的Ҏ ——嵌入汇~,混合~程?br /><br />  举例如下Q将数组一赋值给数组?要求每一字节都相W?br />char string1[1024],string2[1024];<br />ҎI<br />int I;<br />for (I =0 ;I<1024;I++)<br />*(string2 + I) = *(string1 + I)<br />ҎJ<br />#ifdef _PC_<br />int I;<br />for (I =0 ;I<1024;I++)<br />*(string2 + I) = *(string1 + I);<br />#else<br />#ifdef _ARM_<br />__asm<br />{<br />MOV R0,string1<br />MOV R1,string2<br />MOV R2,#0<br />loop:<br />LDMIA R0!, [R3-R11]<br />STMIA R1!, [R3-R11]<br />ADD R2,R2,#8<br />CMP R2, #400<br />BNE loop<br />}<br />#endif<br /><br />  ҎI是最常见的方法,使用?024ơ@环;ҎJ则根据^C同做了区分,在ARMq_下,用嵌入汇~仅?28ơ@环就完成了同L操作。这里有朋友会说Qؓ什么不用标准的内存拯函数?q是因ؓ在源数据里可能含有数据ؓ0的字节,q样的话Q标准库函数会提前结束而不会完成我们要求的操作。这个例E典型应用于LCD数据的拷贝过E。根据不同的CPUQ熟l用相应的嵌入汇编Q可以大大提高程序执行的效率?br /><br />  虽然是必杀技Q但是如果轻易用会付出惨重的代仗这是因为,使用了嵌入汇~,侉K制了E序的可UL性,使程序在不同q_UL的过E中Q卧虎藏龙,险象环生Q同时该招数也与C软g工程的思想相违背,只有在迫不得已的情况下才可以采用。切讎ͼ切记?<br /><br /><img src ="http://www.shnenglu.com/mybios/aggbug/15514.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/mybios/" target="_blank">李锦?mybios)</a> 2006-11-21 17:26 <a href="http://www.shnenglu.com/mybios/archive/2006/11/21/15514.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>【{贴】直接蝲入内存中的DLLhttp://www.shnenglu.com/mybios/archive/2006/11/21/15483.html李锦?mybios)李锦?mybios)Mon, 20 Nov 2006 16:45:00 GMThttp://www.shnenglu.com/mybios/archive/2006/11/21/15483.htmlhttp://www.shnenglu.com/mybios/comments/15483.htmlhttp://www.shnenglu.com/mybios/archive/2006/11/21/15483.html#Feedback6http://www.shnenglu.com/mybios/comments/commentRss/15483.htmlhttp://www.shnenglu.com/mybios/services/trackbacks/15483.htmlL?/a>

下蝲源代?/a>

前言

  你可能不希望在发布程序时附带上一个外部的 DLLQ因为可能会有些用户在无意中?DLL 删除了而造成 EXE 不能正确q行Q也有可能该 DLL 会被别h拿去使用Q也有可能,?DLL 会成为破解者破解你的程序的H破口。无论出于何U原因,如果你想把一?DLL 合ƈC?EXE 中的话,本文向你介绍q种Ҏ?


Win32 E序调用 DLL 的机?/strong>

   Win32 EXE 在调用一个外?DLL 中的函数Ӟ首先要调?LoadLibary 函数来蝲入此 DLL 到程序的q程地址I间?如果 LoadLibary 载入?DLL 成功Q将q回一个该 DLL 的句柄?q个句柄实际上就是该 DLL 在内存中的v始地址?在蝲?DLL 成功后,q必调?GetProcAddress 函数来获取要调用的函数的地址。然后再Ҏ该地址来调用这个函数?br />Ҏ上述原理Q我们可以把一?DLL 作ؓ资源文g攑ֈ EXE 文g中,在程序运行时Q分配一块内存,然后此资源复制到该分配的内存中QƈҎ该内存地址计算得到相关的导出函数地址Q然后,当我们需要调用某一函数Ӟ可以用该函数在内存中的地址来调用它?
E序实现?br />  首先Q把要合q的 DLL 作ؓ资源加入到项目的资源文g中,然后在程序运行时Q从资源中蝲入该资源Q以得到?DLL 在内存中的位|:
LPVOID sRawDll; // 资源文g在内存中的地址 
HRSRC hRes; 
HMODULE hLibrary; 
HGLOBAL hResourceLoaded; 
char lib_name[MAX_PATH]; 
GetModuleFileName(hInstance, lib_name, MAX_PATH ); // 得到q行E序的名?
hLibrary = LoadLibrary(lib_name);                  // p载入一?DLL 一栯入运行程序到内存?

if (NULL != hLibrary) 
{
	// 得到指定的资源文件在内存中的位置 
	hRes = FindResource(hLibrary, MAKEINTRESOURCE(IDR_DATA1), RT_RCDATA); 
	if (NULL != hRes) 
	{
		// 资源文件蝲入内?
		hResourceLoaded = LoadResource(hLibrary, hRes); 
		if (NULL != hResourceLoaded) 
		{
			// 得到资源文g大小 
			SizeofResource(hLibrary, hRes); 

			// 锁定资源以得到它在内存中的地址 
			sRawDll = (LPVOID)LockResource(hResourceLoaded); 
		}
	}
	else return 1; 
	FreeLibrary(hLibrary);
}
else return 1; 
然后Q从资源中蝲?DLL 到内存函?LoadPbDllFromMemory 蝲?DLL 到内存中Q?该函数有两个参数Q第一个参数是指向 DLL 资源在内存中的地址的指针,也就是前面代码中?LockResource 函数的返回倹{第二个参数是一个空的指针,如果函数 LoadPbDllFromMemory q行成功Q该指针指向重新组合后的内存中?DLL 的v始地址。该函数q有一个功能就是如果运行成功,它将手动地用 DLL_PROCESS_ATTACH 参数调用 DLL 的入口函?DllMain 来初始化?DLL。除此之外,它还会手动地载入合ƈ?DLL 的入口表中导入的 DLL q调整它们在内存中的相对地址。以下是该函C?
DWORD LoadPbDllFromMemory(LPVOID lpRawDll, LPVOID lpImageDll) 
{
	SYSTEM_INFO sSysInfo; 
	PIMAGE_DOS_HEADER dosHeader; 
	PIMAGE_NT_HEADERS pNTHeader; 
	PIMAGE_SECTION_HEADER section; 
	PIMAGE_IMPORT_DESCRIPTOR pImportDesc; 
	PIMAGE_IMPORT_BY_NAME pOrdinalName; 
	PIMAGE_BASE_RELOCATION baseReloc; 
	PDWORD lpLink; 
	unsigned char Protection[4096]; 
	HINSTANCE hDll; 
	WORD i; 
	DWORD ImagePages,fOldProtect,j,MaxLen,HdrLen,Addr1,Addr2,Pg,Pg1,Pg2; 
	char * sDllName; 

	if(NULL == lpRawDll) return 1 ; 

	dosHeader = (PIMAGE_DOS_HEADER)lpRawDll; 

	// Is this the MZ header? 
	if ((TRUE == IsBadReadPtr(dosHeader,sizeof (IMAGE_DOS_HEADER))) ||
				 (IMAGE_DOS_SIGNATURE != dosHeader->e_magic)) 
		return 2; 

	// Get the PE header. 
	pNTHeader = MakePtr(PIMAGE_NT_HEADERS,dosHeader,dosHeader->e_lfanew); 

	// Is this a real PE image? 
	if((TRUE == IsBadReadPtr(pNTHeader,sizeof ( IMAGE_NT_HEADERS))) || 
				( IMAGE_NT_SIGNATURE != pNTHeader->Signature)) 
		return 3 ; 

	if(( pNTHeader->FileHeader.SizeOfOptionalHeader != 
			sizeof(pNTHeader->OptionalHeader)) || 
		(pNTHeader->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC)) 
		return 4; 

	if (pNTHeader->FileHeader.NumberOfSections < 1) return 5; 

	section = IMAGE_FIRST_SECTION( pNTHeader ); 
	int HeaderSize = sizeof(IMAGE_SECTION_HEADER); 

	// 节头长度 
	HdrLen = (DWORD)section - (DWORD)dosHeader + 
			HeaderSize * pNTHeader->FileHeader.NumberOfSections; 

	// 扑և最大的节的长度,此节一般是代码所在的?.text ? 
	MaxLen = HdrLen; 
	int ii=0; 

	for (i = 0;i<(DWORD)pNTHeader->FileHeader.NumberOfSections;i++)// find MaxLen 
	{
		if(MaxLen < section[i].VirtualAddress + section[i].SizeOfRawData) 
		{
			MaxLen = section[i].VirtualAddress + section[i].SizeOfRawData; 
		}
		if(strcmp((const char *)section[i].Name,".rsrc") == 0) ii=i; 
	}

	GetSystemInfo(&sSysInfo);
	ImagePages = MaxLen / sSysInfo.dwPageSize; 
	if (MaxLen % sSysInfo.dwPageSize) ImagePages++; 

	// 分配所需的内?
	DWORD NeededMemory = ImagePages * sSysInfo.dwPageSize; 
	lpImageDll = VirtualAlloc(NULL, NeededMemory, MEM_COMMIT, PAGE_EXECUTE_READWRITE); 

	if (lpImageDll == NULL) return 6; // 分配内存p| 

	MoveMemory( lpImageDll, lpRawDll, HdrLen ); // 复制节头 

	DWORD OrgAddr = 0; 
	DWORD NewAddr = 0; 
	DWORD Size = 0; 

	// 复制 .text 节数?
	for (i = 0;i<pNTHeader->FileHeader.NumberOfSections;i++) 
	{
		OrgAddr = (DWORD)lpImageDll + (DWORD)section[i].VirtualAddress; 
		NewAddr = (DWORD)lpRawDll + (DWORD)section[i].PointerToRawData; 
		Size = (DWORD)section[i].SizeOfRawData; 
		MoveMemory((void *)OrgAddr, (void *)NewAddr, Size ); 
	}

	// 把指针指向新?DLL 映像 
	dosHeader = (PIMAGE_DOS_HEADER) lpImageDll; // Switch to new image 
	pNTHeader = (PIMAGE_NT_HEADERS) ((DWORD)dosHeader + dosHeader->e_lfanew); 
	section = (PIMAGE_SECTION_HEADER) ((DWORD)pNTHeader + sizeof(IMAGE_NT_HEADERS)); 
	pImageBase = (PBYTE)dosHeader; 

	if((ii!=0) && (IsNT()==TRUE)) 
	{
		section[ii].VirtualAddress = section[ii].VirtualAddress + (DWORD)lpRawDll; 
		section[ii].PointerToRawData = section[ii].PointerToRawData + (DWORD)lpRawDll; 
	}

	DWORD importsStartRVA; 

	// Look up where the imports section is (normally in the .idata section) 
	// but not necessarily so. Therefore, grab the RVA from the data dir. 
	importsStartRVA = GetImgDirEntryRVA(pNTHeader,IMAGE_DIRECTORY_ENTRY_IMPORT); 
	if ( !importsStartRVA ) 
	{
		VirtualFree(dosHeader,0, MEM_RELEASE); 
		return 7; 
	}

	pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR) pNTHeader->
		OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress; 

	if(pImportDesc!= 0) 
		pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR) ((DWORD)pImportDesc + (DWORD)dosHeader); 
	else 
	{
		VirtualFree(dosHeader,0, MEM_RELEASE); 
		return 8; 
	}

	while (1) // 处理各入口表中的 DLL 
	{
		// 查是否遇CI的 IMAGE_IMPORT_DESCRIPTOR 
		if ((pImportDesc->TimeDateStamp==0 ) && (pImportDesc->Name==0)) break; 

		// 从磁盘蝲入必ȝ Dll, 
		// 注意,载入?DLL 是合q的 DLL 的入口表中的 DLL, 
		// 不是合ƈ?EXE 中的 DLL 
		sDllName = (char *) (pImportDesc->Name + (DWORD)pImageBase); 
		hDll = GetModuleHandle(sDllName); 

		if (hDll == 0 ) hDll = LoadLibrary(sDllName); 

		if (hDll == 0 ) 
		{
			MessageBox(NULL, "Can''t find required Dll",
					"Error in LoadPbDllFromMemory()",0); 
			VirtualFree(dosHeader,0, MEM_RELEASE); 
			return 9; 
		}

		DWORD *lpFuncNameRef = (DWORD *) (pImportDesc->OriginalFirstThunk +
								 (DWORD)dosHeader); 
		DWORD *lpFuncAddr = (DWORD *) (pImportDesc->FirstThunk +
								 (DWORD)dosHeader); 

		while( *lpFuncNameRef != 0) 
		{
			pOrdinalName = (PIMAGE_IMPORT_BY_NAME) (*lpFuncNameRef +
						 (DWORD)dosHeader); 
			DWORD pIMAGE_ORDINAL_FLAG = 0x80000000; 

			if (*lpFuncNameRef & pIMAGE_ORDINAL_FLAG) 
				*lpFuncAddr = (DWORD) GetProcAddress(hDll,
					 (const char *)(*lpFuncNameRef & 0xFFFF)); 
			else
				*lpFuncAddr = (DWORD) GetProcAddress(hDll,
						 (const char *)pOrdinalName->Name); 

			if (lpFuncAddr == 0) 
			{
				VirtualFree(dosHeader,0, MEM_RELEASE); 
				return 10;// Can''t GetProcAddress 
			}

			lpFuncAddr++;
			lpFuncNameRef++;
		}
		pImportDesc++;
	}

	DWORD TpOffset; 
	baseReloc = (PIMAGE_BASE_RELOCATION)((DWORD)pNTHeader->
     OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress); 

	if (baseReloc !=0) 
	{
		baseReloc = (PIMAGE_BASE_RELOCATION) ((DWORD)baseReloc + (DWORD)dosHeader); 
		while(baseReloc->VirtualAddress != 0) 
		{
			PWORD lpTypeOffset = (PWORD) ((DWORD)baseReloc +
					 sizeof(IMAGE_BASE_RELOCATION)); 
			while (lpTypeOffset < (PWORD)((DWORD)baseReloc +
						 (DWORD)baseReloc->SizeOfBlock)) 
			{
				TpOffset = *lpTypeOffset & 0xF000; 
				if(TpOffset == 0x3000) 
				{
					lpLink = (PDWORD) ((DWORD)dosHeader +
                                   baseReloc->VirtualAddress +
                                                      (*lpTypeOffset & 0xFFF)); 
					*lpLink = (DWORD)dosHeader + 
                                            (*lpLink) - pNTHeader->OptionalHeader.ImageBase; 
				}
				else
				{
					if (TpOffset != 0) 
					{
						VirtualFree(dosHeader,0, MEM_RELEASE); 
						return 10; 
					}
				}
				lpTypeOffset++;
			}
			baseReloc = (PIMAGE_BASE_RELOCATION)((DWORD)baseReloc + 
				(DWORD)baseReloc->SizeOfBlock); 
		}
	}

	// 取得原始的内存状?
	memset(Protection,0,4096);
	for (i = 0;i<=pNTHeader->FileHeader.NumberOfSections;i++) 
	{
		if (i == pNTHeader->FileHeader.NumberOfSections) 
		{
			Addr1 = 0; 
			Addr2 = HdrLen; 
			j = 0x60000000; 
		}
		else
		{
			Addr1 = section[i].VirtualAddress; 
			Addr2 = section[i].SizeOfRawData; 
			j = section[i].Characteristics; 
		}
		Addr2 += Addr1 - 1; 

		Pg1 = Addr1 / sSysInfo.dwPageSize; 
		Pg2 = Addr2 / sSysInfo.dwPageSize; 
		for(Pg = Pg1 ;Pg<=Pg2;Pg++) 
		{
			if (j & 0x20000000) Protection[Pg] |= 1; // Execute 
			if (j & 0x40000000) Protection[Pg] |= 2; // Read 
			if (j & 0x80000000) Protection[Pg] |= 4; // Write 
		}
	}

	// 恢复原始的内存状?
	Addr1 = (DWORD)dosHeader; 
	for (Pg = 0 ;Pg<= ImagePages;Pg++) 
	{
		switch(Protection[Pg])
		{
		case 2: 
			fOldProtect = PAGE_READONLY; 
			break;
		case 3: 
			fOldProtect = PAGE_EXECUTE_READ; 
			break;
		case 6: 
			fOldProtect = PAGE_READWRITE; 
			break;
		default: 
			// Ignore strange combinations
			fOldProtect = PAGE_EXECUTE_READWRITE;  
			break;
		}

		if (fOldProtect !=PAGE_EXECUTE_READWRITE) 
		{
			if (VirtualProtect((void *)Addr1, 
				sSysInfo.dwPageSize, 
				fOldProtect,
				&fOldProtect) == 0) 
			{
				VirtualFree(dosHeader,0, MEM_RELEASE); 
				return 11; 
			}
		}
		Addr1 += sSysInfo.dwPageSize; 
	}

	EntryPoint = (LPENTRYPOINT) ((DWORD)pNTHeader->OptionalHeader.AddressOfEntryPoint +
				 (DWORD)dosHeader); 
	LPVOID lpReserved = 0; 
	EntryPoint((HINSTANCE)dosHeader, DLL_PROCESS_ATTACH, lpReserved); 
	lpImageDll2=lpImageDll;
	return 0; 
}
  一?DLL 被正地载入到内存中Q我们就可以通过自定义函?GetProcAddressDirectly 来获取某函数在内存中的地址QƈҎ该地址来调用该函数Q该函数也有两个参数Q第一个参数是指向载入到内存中?DLL 的v始地址的指针,W二个是要调用的函数的函数名。以下是 GetProcAddressDirectly 函数代码:
DWORD GetProcAddressDirectly(PIMAGE_DOS_HEADER dosHeader, char * FuncName)  
{ 
	PIMAGE_NT_HEADERS pNTHeader;  
	PIMAGE_EXPORT_DIRECTORY pExportDir;  
	PWORD lpNameOrdinals;  
	LPDWORD lpFunctions;  
	DWORD * lpName;  
	char * lpExpFuncName;  
	DWORD i;  
	DWORD j;  
	char * lpFuncName;  

	if(dosHeader->e_magic != IMAGE_DOS_SIGNATURE) return 0;  

	pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)dosHeader + dosHeader->e_lfanew);  

	if (pNTHeader->Signature != IMAGE_NT_SIGNATURE) return 0;  

	if ((pNTHeader->FileHeader.SizeOfOptionalHeader != sizeof(pNTHeader->OptionalHeader)) ||  
		(pNTHeader->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC))  
		return 0;  

	DWORD exportsStartRVA, exportsEndRVA;  
	pImageBase = (PBYTE)dosHeader;  

	// Make pointers to 32 and 64 bit versions of the header.  
	pNTHeader = MakePtr( PIMAGE_NT_HEADERS, dosHeader,dosHeader->e_lfanew );  

	exportsStartRVA = GetImgDirEntryRVA(pNTHeader,IMAGE_DIRECTORY_ENTRY_EXPORT);  
	exportsEndRVA = exportsStartRVA +  
		GetImgDirEntrySize(pNTHeader, IMAGE_DIRECTORY_ENTRY_EXPORT);  

	// Get the IMAGE_SECTION_HEADER that contains the exports. This is  
	// usually the .edata section, but doesn''t have to be.  
	PIMAGE_SECTION_HEADER header;  
	header = GetEnclosingSectionHeader( exportsStartRVA, pNTHeader );  
	if ( !header ) return 0;  

	INT delta;  
	delta = (INT)(header->VirtualAddress - header->PointerToRawData);  
	pExportDir = (PIMAGE_EXPORT_DIRECTORY)GetPtrFromRVA(exportsStartRVA, 
				pNTHeader, pImageBase);  


	pExportDir =(PIMAGE_EXPORT_DIRECTORY) (pNTHeader->
	OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);  

	if (pExportDir == 0)  
	{ 
		MessageBox(NULL,"Error in GetProcAddressDirectly()",0,0);  
		return 0;  
	} 

	pExportDir =(PIMAGE_EXPORT_DIRECTORY) ((DWORD)pExportDir + (DWORD)dosHeader);  
	lpNameOrdinals =(PWORD)((DWORD)pExportDir->AddressOfNameOrdinals + (DWORD)dosHeader);  
	lpName =(LPDWORD) (pExportDir->AddressOfNames + (DWORD)dosHeader);  
	lpFunctions =(LPDWORD) (pExportDir->AddressOfFunctions + (DWORD)dosHeader);  
	lpFuncName = FuncName;  

	if(HIWORD(lpFuncName)!=0 )  
	{ 
		for( i = 0;i<=pExportDir->NumberOfFunctions - 1;i++)  
		{ 
			DWORD entryPointRVA = *lpFunctions;  

			// Skip over gaps in exported function  
			if ( entryPointRVA == 0 ) continue; 
			for( j = 0;j<=pExportDir->NumberOfNames-1;j++)  
			{ 
				if( lpNameOrdinals[j] == i)  
				{ 
					lpExpFuncName = (char *) (lpName[j] + 
							(DWORD)dosHeader);  
					if(strcmp((char *)lpExpFuncName,(char *)FuncName)==0)  
						return (DWORD) (lpFunctions[i] + 
								(DWORD)dosHeader);  
				} 
			} 
		} 
	} 
	else 
	{ 
		for (i = 0 ;i<=pExportDir->NumberOfFunctions - 1;i++)  
		{ 
			if (lpFuncName == (char *)(pExportDir->Base + i))  
			{ 
				if (lpFunctions[i]) return (unsigned long) (lpFunctions[i] + 
							dosHeader);  
			} 
		} 
	} 
	return 0;  
}


在调用完函数后,不要忘记?UnloadPbDllFromMemory 来从内存中移?DLL 以释攑ֈ配的内存Q该函数q会?DLL_PROCESS_DETACH 参数调用 DLL 的入口函?DllMain 来从调用q程的地址I间卸蝲?DLL?以下?UnloadPbDllFromMemory 函数代码:
DWORD UnloadPbDllFromMemory(PIMAGE_DOS_HEADER dosHeader) 
{
	PIMAGE_NT_HEADERS pNTHeader; 
	pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)dosHeader + (DWORD)dosHeader->e_lfanew); 
	EntryPoint = (LPENTRYPOINT)(pNTHeader->OptionalHeader.AddressOfEntryPoint +
					 (DWORD)dosHeader); 
	EntryPoint((HINSTANCE)dosHeader, DLL_PROCESS_DETACH, 0); 
	return VirtualFree(dosHeader, 0, MEM_RELEASE); 
}


关于CZ代码的说?/strong>

  在本文附带的CZ代码中,合ƈ了一个名?hardware.dll 的动态连接库Q该动态连接库是一个获取系l硬件信息的库文Ӟ其中包括了以下函?

   getmac 		取得|卡 MAC 
   VolumeNumber 	取得盘h 
   changeres            改变屏幕分辩?
   IsDiskInDrive        查Y׃是否插有?nbsp;
   DPGetDefaultPrinter  取得默认的打印机?
   DPSetDefaultPrinter  讄默认的打印机 
   getserial            取得盘的出厂序列号 
   getmetric            取得昄分辩?
   PrintStringDirect    直接向打印机发送一个串 
   vfpbeep              ?PC 喇叭发声 
   getcpuid             取得 CPU ID 
   getbios              取得L BIOS ID 
  在示例代码中Q只调用了其中一个函?getbios 来获取主?BIOS IDQ?q里说明一下,该函数实际上好象只能?AWARD L?BIOSQ?也就是说它是d的是pȝ内存 0x000fex71 处的倹{因为其它牌子的L BIOS 的位|稍有不同,但在E序中没有进行这斚w的处理,所以在d它牌子的L BIOS 时可能会有些问题(d的内容可能不正确)。关于此 DLL 的内容和实现Q也许我会在另一文章中论及?
 

局?br />  在我q行试Ӟ发现对于有些含有资源?DLLQ在 9x q_下可能会有问题?br />

题外?br />  另外Q其它一些本文未提及的非主要的函敎ͼ误行参见源代码中的注释?br />再,本文涉及 PE 文g格式斚w的知识,它们已经出了本文的范围Q具体信息可参见 MSDM 中的:

  • Peering Inside the PE: A Tour of the Win32 Portable Executable File Format 一文和
  • Microsoft Portable Executable and Common Object File Format Specification 一?
  • 特别感谢卢春明(AmingQ在我编写本文时所作的一些技术方面的和指?/strong>


    如果本文对你的开发有所帮助Qƈ且你手头恰好有零钱?/p>

    不如打赏我一杯咖啡,鼓励我l分享优U的文章?br />





    李锦?mybios) 2006-11-21 00:45 发表评论
    ]]>
    【{贴】直接运行内存中的程?/title><link>http://www.shnenglu.com/mybios/archive/2006/11/20/15452.html</link><dc:creator>李锦?mybios)</dc:creator><author>李锦?mybios)</author><pubDate>Mon, 20 Nov 2006 03:54:00 GMT</pubDate><guid>http://www.shnenglu.com/mybios/archive/2006/11/20/15452.html</guid><wfw:comment>http://www.shnenglu.com/mybios/comments/15452.html</wfw:comment><comments>http://www.shnenglu.com/mybios/archive/2006/11/20/15452.html#Feedback</comments><slash:comments>6</slash:comments><wfw:commentRss>http://www.shnenglu.com/mybios/comments/commentRss/15452.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/mybios/services/trackbacks/15452.html</trackback:ping><description><![CDATA[     摘要: 哈哈Q想不到有h居然把这U代码也搞出来了。  ?Windows的PE加蝲器在启动E序的时候,会将盘上的文g加蝲到内存,然后做很多操作,如函数导入表重定位,变量预处理之cȝ。这位仁兄等于是自己写了一个PE加蝲器。直接将内存中的E序启动。记得以前的“红色代码”病毒也有相同的Ҏ。  ?直接启动内存中的E序相当于加了一个壳Q可以把E序加密保存Q运行时解密到内存,然后启动Q不q对于增加破解难度还要稍...  <a href='http://www.shnenglu.com/mybios/archive/2006/11/20/15452.html'>阅读全文</a><img src ="http://www.shnenglu.com/mybios/aggbug/15452.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/mybios/" target="_blank">李锦?mybios)</a> 2006-11-20 11:54 <a href="http://www.shnenglu.com/mybios/archive/2006/11/20/15452.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>【原创】魔兽争霸III 地图~辑器原理(关键是脚本)http://www.shnenglu.com/mybios/archive/2006/11/19/15404.html李锦?mybios)李锦?mybios)Sat, 18 Nov 2006 16:20:00 GMThttp://www.shnenglu.com/mybios/archive/2006/11/19/15404.htmlhttp://www.shnenglu.com/mybios/comments/15404.htmlhttp://www.shnenglu.com/mybios/archive/2006/11/19/15404.html#Feedback9http://www.shnenglu.com/mybios/comments/commentRss/15404.htmlhttp://www.shnenglu.com/mybios/services/trackbacks/15404.html  注意Q本文纯属是本h从研I兽争霸III地图~辑器的q程中的一U猜惻I所以,不当之处Q还请高手指出。谢谢!

      兽争霸III我以前玩得比较多Q也听说他的地图~辑器非常牛XQ以前也曄想编辑个地图出来。但是,限于当时得水q问题,没有成功。直到最q在研究如何制作游戏的时候,打开兽争霸III的地囄辑器来看Q突然有一U扩然开朗的感觉Q哦Q原来地囄辑器是这样出来的Q闲话不多说Q马上进入正题!

      兽争霸III的地囄辑器使用了一个文件来代表一个地图,地图里包含了什么东西?我无从得知,但是Q从他的~辑器上看,看到~辑器能对地图修改的东西Q就可以大概猜想到有哪些东西。仔l看地图~辑器,看到有那么几个模块:地Ş~辑器、开关编辑器、声音编辑器、物体编辑器、战役编辑器、AI~辑器、物体管理器、输入管理器。我把我的理解逐一说来阅读全文  阅读全文

    李锦?mybios) 2006-11-19 00:20 发表评论
    ]]>
    【{贴】一些高效代码片D?/title><link>http://www.shnenglu.com/mybios/archive/2006/11/18/15359.html</link><dc:creator>李锦?mybios)</dc:creator><author>李锦?mybios)</author><pubDate>Sat, 18 Nov 2006 07:17:00 GMT</pubDate><guid>http://www.shnenglu.com/mybios/archive/2006/11/18/15359.html</guid><wfw:comment>http://www.shnenglu.com/mybios/comments/15359.html</wfw:comment><comments>http://www.shnenglu.com/mybios/archive/2006/11/18/15359.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.shnenglu.com/mybios/comments/commentRss/15359.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/mybios/services/trackbacks/15359.html</trackback:ping><description><![CDATA[ <strong>一个快速开方的函数<br /></strong> <pre class="code"> <span id="hvdrhjv" class="coMULTI"> <em> <font color="#808080">/* 来至 Quake 3 的源?*/</font> </em> </span> <span id="dxptppz" class="kw4"> <font color="#993333">float</font> </span> CarmSqrt<span id="pvrfbzh" class="br0"><font color="#66cc66">(</font></span><span id="dzblpfl" class="kw4"><font color="#993333">float</font></span> x<font color="#66cc66"><span id="zdnxjzp" class="br0">)</span><span id="vpjvnvb" class="br0">{</span></font><span id="bdxzlrh" class="kw4"><font color="#993333">union</font></span><span id="ffjtfll" class="br0"><font color="#66cc66">{</font></span><span id="vzblvlb" class="kw4"><font color="#993333">int</font></span> intPart; <span id="hjvbvtj" class="kw4"><font color="#993333">float</font></span> floatPart; <span id="dfpjdbz" class="br0"><font color="#66cc66">}</font></span> convertor; <span id="nnrlnbz" class="kw4"><font color="#993333">union</font></span><span id="dvhjttj" class="br0"><font color="#66cc66">{</font></span><span id="dfrjndj" class="kw4"><font color="#993333">int</font></span> intPart; <span id="jvhhbbh" class="kw4"><font color="#993333">float</font></span> floatPart; <span id="pztvxnb" class="br0"><font color="#66cc66">}</font></span> convertor2; convertor.<span id="hrdpjpx" class="me1">floatPart</span> = x; convertor2.<span id="bvfzdjp" class="me1">floatPart</span> = x; convertor.<span id="bnpxbjz" class="me1">intPart</span> = 0x1FBCF800 + <span id="rdvxbpx" class="br0"><font color="#66cc66">(</font></span>convertor.<span id="bdzzlbp" class="me1">intPart</span> >> <span id="xzjlvll" class="nu0"><font color="#cc66cc">1</font></span><span id="dfrlxdl" class="br0"><font color="#66cc66">)</font></span>; convertor2.<span id="xxblxtt" class="me1">intPart</span> = 0x5f3759df - <span id="rblnzhv" class="br0"><font color="#66cc66">(</font></span>convertor2.<span id="htvfrzn" class="me1">intPart</span> >> <span id="zjdjvjh" class="nu0"><font color="#cc66cc">1</font></span><span id="zrdfppf" class="br0"><font color="#66cc66">)</font></span>; <span id="vxhtdbr" class="kw1"><font color="#b1b100">return</font></span><span id="fhjfxxd" class="nu0"><font color="#cc66cc">0</font></span>.5f*<span id="hrlvfdl" class="br0"><font color="#66cc66">(</font></span>convertor.<span id="nhlnpxv" class="me1">floatPart</span> + <span id="jbfhzzf" class="br0"><font color="#66cc66">(</font></span>x * convertor2.<span id="lvxjbjp" class="me1">floatPart</span><font color="#66cc66"><span id="vfjtvdj" class="br0">)</span><span id="lvhzdbh" class="br0">)</span></font>; <span id="zjdvpnl" class="br0"><font color="#66cc66">}</font></span></pre> <br />参考链接:<a target="_blank" rel="nofollow"><img title="在新H口中打开" height="11" alt="[External Link]" hspace="4" src="http://blog.codingnow.com/cloud//images/www.gif" width="11" border="0" /></a><a rel="nofollow"><font color="#003399">http://greatsorcerer.go2.icpcn.com/info/fastsqrt.html</font></a><br /><font color="#003399"><hr noshade="" size="1" /></font><strong>快?double 转整?</strong><br /><pre class="code"><span id="lfhbltz" class="kw4"><font color="#993333">union</font></span> luai_Cast <span id="rbvhrzx" class="br0"><font color="#66cc66">{</font></span><span id="hlfxjzn" class="kw4"><font color="#993333">double</font></span> l_d; <span id="jjlpzpd" class="kw4"><font color="#993333">long</font></span> l_l; <span id="rdnrtjr" class="br0"><font color="#66cc66">}</font></span>; <span id="jvhztjr" class="co2"><em><font color="#808080">#define lua_number2int(i,d) \</font></em></span><span id="hjtvppd" class="br0"><font color="#66cc66">{</font></span><span id="xxbvfdj" class="kw4"><font color="#993333">volatile</font></span><span id="dfjtfbz" class="kw4"><font color="#993333">union</font></span> luai_Cast u; u.<span id="nnprtbz" class="me1">l_d</span> = <span id="dxjdvvl" class="br0"><font color="#66cc66">(</font></span>d<span id="tdxrdbj" class="br0"><font color="#66cc66">)</font></span> + <span id="tfztdlj" class="nu0"><font color="#cc66cc">6755399441055744</font></span>.<span id="tvpzlbj" class="nu0"><font color="#cc66cc">0</font></span>; <span id="vhrlxdj" class="br0"><font color="#66cc66">(</font></span>i<span id="rlfhjxv" class="br0"><font color="#66cc66">)</font></span> = u.<span id="vfpjvlz" class="me1">l_l</span>; <span id="ztvfzpn" class="br0"><font color="#66cc66">}</font></span></pre><br />参考链接:<a target="_blank"><img title="在新H口中打开" height="11" alt="[InterWiki]" hspace="4" src="http://blog.codingnow.com/cloud//images/inter.gif" width="11" border="0" /></a><a ><font color="#003399">double to int 奇?magic number</font></a><br /><font color="#003399"><hr noshade="" size="1" /></font><strong>RGB565 ?alpha 混合 </strong><br /><pre class="code"><span id="ztfxbzn" class="kw4"><font color="#993333">unsigned</font></span><span id="lvhrllr" class="kw4"><font color="#993333">short</font></span> alpha_blender<span id="fdhrtzp" class="br0"><font color="#66cc66">(</font></span><span id="rlvfbxf" class="kw4"><font color="#993333">unsigned</font></span><span id="dvpbljr" class="kw4"><font color="#993333">int</font></span> x,<span id="lnrdnnl" class="kw4"><font color="#993333">unsigned</font></span><span id="lfxrdbz" class="kw4"><font color="#993333">int</font></span> y,<span id="vnzjvlz" class="kw4"><font color="#993333">unsigned</font></span><span id="xjddfvb" class="kw4"><font color="#993333">int</font></span> alpha<span id="phtxhpn" class="br0"><font color="#66cc66">)</font></span><span id="dfpjtzp" class="br0"><font color="#66cc66">{</font></span> x = <span id="llxzjhp" class="br0"><font color="#66cc66">(</font></span>x | <span id="tvpjflb" class="br0"><font color="#66cc66">(</font></span>x<<<span id="nptnhft" class="nu0"><font color="#cc66cc">16</font></span><font color="#66cc66"><span id="pbdhjrf" class="br0">)</span><span id="nrblnll" class="br0">)</span></font> & 0x7E0F81F; y = <span id="zjlnhxf" class="br0"><font color="#66cc66">(</font></span>y | <span id="bnhrtrp" class="br0"><font color="#66cc66">(</font></span>y<<<span id="fhjdxdl" class="nu0"><font color="#cc66cc">16</font></span><font color="#66cc66"><span id="rjdxjpn" class="br0">)</span><span id="rvfrjjh" class="br0">)</span></font> & 0x7E0F81F; <span id="xjbfpfv" class="kw4"><font color="#993333">unsigned</font></span><span id="lfzlfvb" class="kw4"><font color="#993333">int</font></span> result = <font color="#66cc66"><span id="lfzrljz" class="br0">(</span><span id="bvhrdbr" class="br0">(</span></font>x - y<span id="pzllpnd" class="br0"><font color="#66cc66">)</font></span> * alpha / <span id="zbxpjrh" class="nu0"><font color="#cc66cc">32</font></span> + y<span id="txzjdlb" class="br0"><font color="#66cc66">)</font></span> & 0x7E0F81F; <span id="bdxhrzh" class="kw1"><font color="#b1b100">return</font></span><span id="xrdnpvd" class="br0"><font color="#66cc66">(</font></span><span id="prbxxxt" class="kw4"><font color="#993333">unsigned</font></span><span id="vxhbdjj" class="kw4"><font color="#993333">short</font></span><font color="#66cc66"><span id="nzrtflb" class="br0">)</span><span id="prtnhfv" class="br0">(</span><span id="blnzbpx" class="br0">(</span></font>result&0xFFFF<span id="xztfzpl" class="br0"><font color="#66cc66">)</font></span> | <span id="dfrlxnl" class="br0"><font color="#66cc66">(</font></span>result>><span id="fpjvxll" class="nu0"><font color="#cc66cc">16</font></span><font color="#66cc66"><span id="blhztjh" class="br0">)</span><span id="lnhbllb" class="br0">)</span></font>; <span id="xprtnlb" class="br0"><font color="#66cc66">}</font></span></pre><br />参考链接:<a target="_blank"><img title="在新H口中打开" height="11" alt="[InterWiki]" hspace="4" src="http://blog.codingnow.com/cloud//images/inter.gif" width="11" border="0" /></a><a ><font color="#003399">64K 色的 Alpha 混合</font></a><br /><font color="#003399"><hr noshade="" size="1" /></font><strong>一个不错的字符?hash 函数 </strong><br /><pre class="code"><span id="fxjldtb" class="kw4"><font color="#993333">unsigned</font></span><span id="htdfjxn" class="kw4"><font color="#993333">long</font></span> hash<span id="zlnxrzp" class="br0"><font color="#66cc66">(</font></span><span id="zbdxjxn" class="kw4"><font color="#993333">const</font></span><span id="hbdfrnd" class="kw4"><font color="#993333">char</font></span> *name,size_t len<span id="phjnxnl" class="br0"><font color="#66cc66">)</font></span><span id="hbvphhf" class="br0"><font color="#66cc66">{</font></span><span id="jlxhlrz" class="kw4"><font color="#993333">unsigned</font></span><span id="hjdfhxd" class="kw4"><font color="#993333">long</font></span> h=<span id="prjlfdb" class="br0"><font color="#66cc66">(</font></span><span id="rtpztrf" class="kw4"><font color="#993333">unsigned</font></span><span id="ddhrdbz" class="kw4"><font color="#993333">long</font></span><span id="prbdndl" class="br0"><font color="#66cc66">)</font></span>len; size_t step = <span id="nhbtvjh" class="br0"><font color="#66cc66">(</font></span>len>><span id="xzrlxvl" class="nu0"><font color="#cc66cc">5</font></span><span id="blfjlrp" class="br0"><font color="#66cc66">)</font></span>+<span id="hzldhnd" class="nu0"><font color="#cc66cc">1</font></span>; <span id="blfpzxf" class="kw1"><font color="#b1b100">for</font></span><span id="nrjlflj" class="br0"><font color="#66cc66">(</font></span>size_t i=len; i>=step; i-=step<span id="nxrbvtb" class="br0"><font color="#66cc66">)</font></span> h = h ^ <font color="#66cc66"><span id="htnhrhf" class="br0">(</span><span id="fztdpvt" class="br0">(</span></font>h<<<span id="rlnxhpv" class="nu0"><font color="#cc66cc">5</font></span><span id="pbvpzhn" class="br0"><font color="#66cc66">)</font></span>+<span id="bdnxjrp" class="br0"><font color="#66cc66">(</font></span>h>><span id="hjvxxnv" class="nu0"><font color="#cc66cc">2</font></span><span id="prlfhxd" class="br0"><font color="#66cc66">)</font></span>+<span id="dxrbdbz" class="br0"><font color="#66cc66">(</font></span><span id="rnpblrh" class="kw4"><font color="#993333">unsigned</font></span><span id="jtnhljx" class="kw4"><font color="#993333">long</font></span><span id="xrjnxvl" class="br0"><font color="#66cc66">)</font></span>name<span id="lnhzbzp" class="br0"><font color="#66cc66">[</font></span>i-<span id="lxpbntz" class="nu0"><font color="#cc66cc">1</font></span><font color="#66cc66"><span id="xhdvpnv" class="br0">]</span><span id="bdpjltz" class="br0">)</span></font>; <span id="hbtxzfl" class="kw1"><font color="#b1b100">return</font></span> h; <span id="vxbtfll" class="br0"><font color="#66cc66">}</font></span></pre><br />一个方便的 hash 函数应该散列的比较开Q计速度跟字W串长度关系不大Q又不能只计字W串的开头或末尾。这里的法是从 <a ><font color="#003399">Lua</font></a> 中看来的?br /><hr noshade="" size="1" /><strong>关于脏矩形技术的演示 </strong><br />׃代码q长Q单起一:<a ><font color="#003399">脏矩?demo</font></a><br />参考链接:<a target="_blank" rel="nofollow"><img title="在新H口中打开" height="11" alt="[External Link]" hspace="4" src="http://blog.codingnow.com/cloud//images/www.gif" width="11" border="0" /></a><a rel="nofollow"><font color="#003399">Blog上的帖子Q脏矩Ş演示demo</font></a><br /><font color="#003399"><hr noshade="" size="1" /></font><strong>UTF8 ?UTF16 的{?单个字符) </strong><br /><pre class="code"><span id="dxrdpvt" class="kw4"><font color="#993333">int</font></span> UTF8toUTF16<span id="zjlfppd" class="br0"><font color="#66cc66">(</font></span><span id="tdhzvbh" class="kw4"><font color="#993333">int</font></span> c<span id="bdfprrn" class="br0"><font color="#66cc66">)</font></span><span id="nnztfdt" class="br0"><font color="#66cc66">{</font></span><span id="rtvnzfn" class="kw4"><font color="#993333">signed</font></span><span id="lnrbllh" class="kw4"><font color="#993333">char</font></span> *t=<span id="vxzlxlj" class="br0"><font color="#66cc66">(</font></span><span id="nrllxnt" class="kw4"><font color="#993333">signed</font></span><span id="vrtfhpv" class="kw4"><font color="#993333">char</font></span>*<span id="vvhjtth" class="br0"><font color="#66cc66">)</font></span>&c; <span id="hrbdznd" class="kw4"><font color="#993333">int</font></span> ret=*t &<span id="rtvpjjp" class="br0"><font color="#66cc66">(</font></span>0x0f | <font color="#66cc66"><span id="llnzlzx" class="br0">(</span><span id="xzbdxfd" class="br0">(</span></font>*t>><span id="nfzbnlj" class="nu0"><font color="#cc66cc">1</font></span><span id="xpbfpvl" class="br0"><font color="#66cc66">)</font></span> &0x1f<span id="tdprtbr" class="br0"><font color="#66cc66">)</font></span> | ~<span id="ltxxjrx" class="br0"><font color="#66cc66">(</font></span>*t>><span id="xpbvpnv" class="nu0"><font color="#cc66cc">7</font></span><font color="#66cc66"><span id="nhjdffb" class="br0">)</span><span id="nhzdvlj" class="br0">)</span></font>; <span id="nzjnffl" class="kw4"><font color="#993333">int</font></span> i; assert <font color="#66cc66"><span id="zzdvhnl" class="br0">(</span><span id="vxzbnjh" class="br0">(</span></font>*t & 0xc0<span id="bnztdtr" class="br0"><font color="#66cc66">)</font></span> != 0x80<span id="jtxhdrp" class="br0"><font color="#66cc66">)</font></span>; <span id="nxtlfvd" class="kw1"><font color="#b1b100">for</font></span><span id="fpztfvt" class="br0"><font color="#66cc66">(</font></span>i=<span id="jtnzbrh" class="nu0"><font color="#cc66cc">1</font></span>;i<<span id="dnhbflb" class="nu0"><font color="#cc66cc">3</font></span>;i++<span id="txzrljr" class="br0"><font color="#66cc66">)</font></span><span id="bvztlbb" class="br0"><font color="#66cc66">{</font></span><span id="jbfzjhp" class="kw1"><font color="#b1b100">if</font></span><font color="#66cc66"><span id="lnhrvjj" class="br0">(</span><span id="npjdfdr" class="br0">(</span></font>t<span id="xxrlpvl" class="br0"><font color="#66cc66">[</font></span>i<span id="tfhdntr" class="br0"><font color="#66cc66">]</font></span> & 0xc0<span id="jdprlzz" class="br0"><font color="#66cc66">)</font></span>!=0x80<span id="tfzjttj" class="br0"><font color="#66cc66">)</font></span><span id="xjlvpnn" class="br0"><font color="#66cc66">{</font></span><span id="lpzbvdz" class="kw2"><strong>break</strong></span>; <span id="jtxxthf" class="br0"><font color="#66cc66">}</font></span> ret=ret<<<span id="phlnpvt" class="nu0"><font color="#cc66cc">6</font></span> | <span id="xhjvhnt" class="br0"><font color="#66cc66">(</font></span>t<span id="vfzbnbr" class="br0"><font color="#66cc66">[</font></span>i<span id="zhtfxnl" class="br0"><font color="#66cc66">]</font></span> & 0x3f<span id="phlnxdd" class="br0"><font color="#66cc66">)</font></span>; <span id="vxpbntz" class="br0"><font color="#66cc66">}</font></span><span id="bdnzbhp" class="kw1"><font color="#b1b100">return</font></span> ret; <span id="hzvnpnd" class="br0"><font color="#66cc66">}</font></span></pre><br />q只是一个字W的转换Q如果{换字W串Q可以再做一点优化?img src ="http://www.shnenglu.com/mybios/aggbug/15359.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/mybios/" target="_blank">李锦?mybios)</a> 2006-11-18 15:17 <a href="http://www.shnenglu.com/mybios/archive/2006/11/18/15359.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>【{贴】泛型算法:Tipshttp://www.shnenglu.com/mybios/archive/2006/11/18/15333.html李锦?mybios)李锦?mybios)Sat, 18 Nov 2006 01:17:00 GMThttp://www.shnenglu.com/mybios/archive/2006/11/18/15333.htmlhttp://www.shnenglu.com/mybios/comments/15333.htmlhttp://www.shnenglu.com/mybios/archive/2006/11/18/15333.html#Feedback2http://www.shnenglu.com/mybios/comments/commentRss/15333.htmlhttp://www.shnenglu.com/mybios/services/trackbacks/15333.html阅读全文

    李锦?mybios) 2006-11-18 09:17 发表评论
    ]]>
    【{贴】PhysX SDK物理引擎开发包使用教程Q基于OpenGLhttp://www.shnenglu.com/mybios/archive/2006/11/18/15327.html李锦?mybios)李锦?mybios)Sat, 18 Nov 2006 00:53:00 GMThttp://www.shnenglu.com/mybios/archive/2006/11/18/15327.htmlhttp://www.shnenglu.com/mybios/comments/15327.htmlhttp://www.shnenglu.com/mybios/archive/2006/11/18/15327.html#Feedback1http://www.shnenglu.com/mybios/comments/commentRss/15327.htmlhttp://www.shnenglu.com/mybios/services/trackbacks/15327.html

    AGEIA的PhysX处理器是世界上首Ƅ理模拟处理器 (PPU), 该处理器解除中央处理器q行物理模拟的负担。PhysX PPU 的设计构架基于顶点的多线E操作,允许游戏开发h员进行精、流畅和动画创作和运动模拟,例如毛发、布料、液体、流体等。本文介l了如何利用PhysX SDK物理引擎开发包来实现我们仿真的效果?/p>


    AGEIA的PhysX处理器是世界上首Ƅ理模拟处理器 (PPU), 该处理器解除中央处理器q行物理模拟的负担。PhysX PPU 的设计构架基于顶点的多线E操作,允许游戏开发h员进行精、流畅和动画创作和运动模拟,例如毛发、布料、液体、流体等。目?AGEIA 的PhysX处理器是世界上第一ƾ也是唯一一ƾ专注于物理法处理器的产品.
    利用PhysX SDK物理引擎开发包来实现我们仿真的效果Ӟ一般需要以下几个步骤:
    Q?Q?span style="FONT: 7pt 'Times New Roman'">    PrintControls();
    Q?Q?span style="FONT: 7pt 'Times New Roman'">    InitGlut(argc, argv);
    Q?Q?span style="FONT: 7pt 'Times New Roman'">    InitNx();
    Q?Q?span style="FONT: 7pt 'Times New Roman'">    glutMainLoop();
    Q?Q?span style="FONT: 7pt 'Times New Roman'">    ReleaseNx();
    其中最Z要的函数是InitNxQ)Q也既是初始化PhysXQ创Z个PhysX SDK实例以及建立我们的场景。下面具体分析各个函数的作用?/span>
    一Q?/span> PrintControls();
    显而易见,利用该函数的目的是在告诉玩家该如何进行操作。操作的按键可根据自q喜好q行讄?/span>
    二. InitGlut(argc, argv);
    PhysX是OpenGL上开发的Q所以在初始化PhysX实例之前Q必d立一个OpenGL的框架?/span>
    ?    glutInit(&argc, argv) 用来初始化GLUTQƈ且处理Q意的命o行变?/span>
    ?    glutInitWindowSize(int width, int size) 指定了窗口以像素为单位的寸
    ?     glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH) 建立一个带有双~存、RGB颜色模型和很大缓存的H口
    ?    glutCreateWindowQchar* stringQ?创徏一个具有OpenGL创徏的窗口,stringH口的窗口名
    ?    glutSetWindowQ)
    ?    glutDisplayFunc(RenderCallback) 渲染
    ProcessCameraKeys();
         SetupCamera();
             if (gScene && !bPause)
         {
            GetPhysicsResults();
    ProcessInputs();Ҏ选择的对象,l该对象施加前后、上下、左右不同方向的力,然后调用对象的方法addForceQ生不同的物理效果
            StartPhysics();
         }
        // Display scene
         RenderActors(bShadows);
    调用函数DrawActor(NxActor* actor)场景中的物体渲染出来,实在是在DrawActor(NxActor* actor)函数中根据物体Ş状调用不同Ş状的l画函数物体渲染出来的。在渲染的过E中Q利用显C列表绘制不同Ş状的物体。在PhysX中,物体形状分ؓ以下几种QNX_SHAPE_PLANE(面板?, NX_SHAPE_BOX(盒子?, NX_SHAPE_ SPHERE(球Ş?, NX_SHAPE_CAPSULE(胶囊?, NX_SHAPE_CONVEX(凸多边Ş?, NX_SHAPE_MESH(|状??/span>
    当bShadows为trueӞ渲染物体的阴影;为false时就不绘?/span>
         DrawForce(box, gForceVec, NxVec3(1,1,0));
            物体受力的受力方向渲染出来
    ?    glutReshapeFunc(ReshapeCallback)
    讄H口
    ?    glutIdleFunc(IdleCallback);
      
    ?    glutKeyboardFunc(KeyboardCallback);
    ?    glutKeyboardUpFunc(KeyboardUpCallback);
    ?    glutSpecialFunc(SpecialCallback);
    在此Q调用ResetNxQ)Q重新渲?/span>
    ?    glutMouseFunc(MouseCallback);
    ?    glutMotionFunc(MotionCallback);
    ?    MotionCallback(0,0);
    三. InitNx() 因ؓ我们需要初始化PhysX SDK实例Qƈ且徏立我们需要的场景Q所以我们需要设|以下几个变量,q且它们设|ؓ全局变量
            NxPhysicsSDK* gPhysicsSDK = NULL; //PhysX SDK实例对象
    NxScene* gScene = NULL; //场景对象
    NxVec3   gDefaultGravity(0,-9.8,0);
    ***注意Q坐标系的方向指向,在PhysX、OpenGL以及3DMax都有一些不一P当运行里面的demo的时候就可以体会到。它们的坐标pd别如下:    
     

       下面在InitNxQ)中开始初始化实例以及建立场景.
    ?    实例?physics SDK
    gPhysicsSDK = NxCreatePhysicsSDK(NX_PHYSICS_SDK_VERSION);
    初始化完Physics SDK后,只是单的一个实例。可以通过讄实例的物理参数来充实我们的模拟效?
    gPhysicsSDK->setParameter(NX_SKIN_WIDTH, 0.01);
    ?    创徏场景
                NxSceneDesc sceneDesc; //场景表述表对?/span>
                sceneDesc.gravity = gDefaultGravity;
            sceneDesc.broadPhase = NX_BROADPHASE_COHERENT;
            sceneDesc.collisionDetection    = true;
                gScene = gPhysicsSDK->createScene(sceneDesc);
    在PhysX中,不管是创建场景还是创建各个物体角色时Q都是先通过各自对应的描q器Q翻译的不是很准)讄场景和各个物体的物理参数Q用来模拟真实的世界环境和物体。徏立好表述器后Q通过函数 createSce neQ?/span> NxSceneDesc Q函数就可以建立需要的场景对象?/span>
    一般情况下Q场景描q器的参数就是设|重力加速度 sceneDesc.gravity Q是否进行碰撞检?/span> collisionDetection , true行, 在PhysX SDK中描q器被广泛的应用. 描述器包括所有你创徏物体的信?/span> broadphase-coherent 是三U碰撞检中的一U?/span>
    gPhysicsSDK->setParameter(NX_SKIN_WIDTH, 0.01);
    当相互碰撞的物体的材质都很Y的时候,在现实中׃发现当发生碰撞的时候物体之间就会相互嵌入一部分Q在q里我们可以利用物理参?/span> NX_SKIN_WIDTH Q它的默认gؓ0.05mQ该D大,嵌入的就多
     
    同时Q我们可以对场景中的所有物体创建材质。创建的材质定义了碰撞和物体材料的物理属性。比如反弹系数、静摩擦力、滑动摩擦力{?/span>
     
                 // Create the default material 通过材质索引创徏一个材质的对象
                 NxMaterial* defaultMaterial = gScene->getMaterialFromIndex(0);
                defaultMaterial->setRestitution(0.5);
                 defaultMaterial->setStaticFriction(0.5);
                defaultMaterial->setDynamicFriction(0.5);
     
    创徏物体Q以boxZ
    NxActor* box = CreateBox(NxVec3(5,1,0));
    NxActor* CreateBox(const NxVec3& pos)
    {
            // Add a single-shape actor to the scene
            NxActorDesc actorDesc;
            NxBodyDesc bodyDesc;
     
            // The actor has one shape, a box
            NxBoxShapeDesc boxDesc;
            boxDesc.dimensions.set(0.5,1,0.5);
            actorDesc.shapes.pushBack(&boxDesc);
     
            actorDesc.body = &bodyDesc;
            actorDesc.density = 10;
            actorDesc.globalPose.t = pos;
            return gScene->createActor(actorDesc); 
    }
    我们创徏一个角色参与者boxQ它的类型ؓ NxActor* 。徏立该对象的时候需要设|它的描q器Q然后利用函?/span> createActor(NxActorDesc actorDesc) 该对象加入场景中。每一个对象又有和自己形状相对应的描述器。利用它讄对象的物理参数?/span> boxDesc 该描q器描述了该盒子的长、宽、高分别?.5Q初始化的位|以及该盒子的密度?/span>
    ?    创徏完所有的物体对象Ӟ调用 UpdateTime() 得到从上一帧渲染到现在l过的时?/span>
    ?    当创建的场景成功Q利用函?/span> StartPhysics() 开始它的第一帧模拟?/span>
                void StartPhysics()
    {
        // Update the time step
                NxReal deltaTime = UpdateTime();
     
                    // Start collision and dynamics for delta time since the last frame
                    gScene->simulate(deltaTime);
                    gScene->flushStream();
    }
    simulate(deltaTime) 是PhysX 解决物理学的关键
                  flushStream() Ҏ间步q行仿真
    四. glutMainLoop()
    E序一直停留在glutMainLoop()中,直到用户自己l束。当场景一旦被渲染后, ?/span> 每次 讄下一场景?/span> Q?/span> RenderCallback() 回调函数 ?/span> 被调?/span>
    五. ReleaseNx()
        删除场景中所有的物体对象以及场景本n
     


    李锦?mybios) 2006-11-18 08:53 发表评论
    ]]>
    þɫۺһ| þþƷɧ| þƵ6| 99þֻƷ| 뾫ƷþɪӰ| þˬˬƬAV| þþþþAvӰԺ| ޾ҹþþþþ| ۺϾƷ㽶þ| þ㽶ۺɫһۺɫ88| Ʒþþþѿ| Ʒþþþþþ| ˾Ʒþ| þ99һ| þþþһƷɫ| þþƷhþþƷ帣ӰԺ1421 | 91Ʒ91þþþþ| ޾ƷҹVAþó | þþƷ| þþƷӰԺ| þþһƷ99þþƷ88| þĻƵ| Ʒһþ| һɫþ99һۺ| һһþaþþƷۺ鶹| 99Ʒþ| ޾ƷŮþþ| ˼˼þ99ֻƵƷ66| þ| һaƬþëƬëƬ| þþƷһ| ŮƷþþþ| avպƷþþþþa| þݺҹҹ2020һ| þþþ99ƷƬëƬ| ˺ݺۺϾþ| þƵۿ| ƷþþĻ| yellowĻþ| ƷžžþƵ| þùֱ|