<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-牵着老婆满街逛-随笔分类-图形学</title><link>http://www.cppblog.com/tx7do/category/2149.html</link><description>危机感是一种强大前进的动力！&lt;/br&gt;
GMail/GTalk: yanglinbo#google.com;&lt;/br&gt;
MSN/Email: tx7do#yahoo.com.cn;&lt;/br&gt;
QQ: 3 0 3 3 9 6 9 2 0 .</description><language>zh-cn</language><lastBuildDate>Mon, 19 May 2008 12:49:51 GMT</lastBuildDate><pubDate>Mon, 19 May 2008 12:49:51 GMT</pubDate><ttl>60</ttl><item><title>小神之Newton物理引擎教程(一) Newton物理引擎教程</title><link>http://www.cppblog.com/tx7do/archive/2007/01/25/17982.html</link><dc:creator>杨粼波</dc:creator><author>杨粼波</author><pubDate>Thu, 25 Jan 2007 07:49:00 GMT</pubDate><guid>http://www.cppblog.com/tx7do/archive/2007/01/25/17982.html</guid><wfw:comment>http://www.cppblog.com/tx7do/comments/17982.html</wfw:comment><comments>http://www.cppblog.com/tx7do/archive/2007/01/25/17982.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/tx7do/comments/commentRss/17982.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tx7do/services/trackbacks/17982.html</trackback:ping><description><![CDATA[
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 42.75pt; TEXT-INDENT: -42.75pt; mso-list: l1 level1 lfo1; tab-stops: list 42.75pt">
				<span lang="EN-US" style="FONT-SIZE: 14pt; mso-bidi-font-family: 宋体">
						<span style="mso-list: Ignore">
								<font face="Times New Roman">第一节</font>
						</span>
				</span>
				<span lang="EN-US" style="FONT-SIZE: 14pt; FONT-FAMILY: Arial">Getting started</span>
				<span lang="EN-US" style="FONT-SIZE: 14pt">
						<p> </p>
				</span>
		</p>
		<p>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<font size="3">
						<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这个例程将告诉你如何把</span>
						<span lang="EN-US">
								<font face="Times New Roman">newton</font>
						</span>
						<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">物理引擎和你的图形引擎结合起来。</span>
				</font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<font size="3">
						<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">如果你没有解过</span>
						<span lang="EN-US">
								<font face="Times New Roman">SDK</font>
						</span>
						<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">包，先解开包。</span>
				</font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">打开</span>
				<span lang="EN-US" style="FONT-SIZE: 12pt">
						<font face="Times New Roman">Visual studio</font>
				</span>
				<span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">找到包里的</span>
				<b>
						<span lang="EN-US" style="FONT-SIZE: 12pt">
								<font face="Times New Roman">Tutorials.dsw</font>
						</span>
				</b>
				<span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-weight: bold">后双击。</span>
				<span lang="EN-US" style="FONT-SIZE: 12pt; mso-bidi-font-weight: bold">
						<p> </p>
				</span>
		</p>
		<p>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-weight: bold">选择子项目</span>
				<b>
						<span lang="EN-US" style="FONT-SIZE: 12pt">
								<font face="Times New Roman">Tutorial 1 getting started</font>
						</span>
				</b>
				<span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-weight: bold">并使它活动起来。</span>
				<span lang="EN-US" style="FONT-SIZE: 12pt; mso-bidi-font-weight: bold">
						<p> </p>
				</span>
		</p>
		<p>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-weight: bold">选择</span>
				<b>
						<span lang="EN-US" style="FONT-SIZE: 12pt">
								<font face="Times New Roman">Tutorial.cpp</font>
						</span>
				</b>
				<span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-weight: bold">文件并双击在编辑框中打开。</span>
				<span lang="EN-US" style="FONT-SIZE: 12pt; mso-bidi-font-weight: bold">
						<p> </p>
				</span>
		</p>
		<p>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-weight: bold">在文件的开始你将发现</span>
				<span lang="EN-US" style="FONT-SIZE: 12pt; mso-bidi-font-weight: bold">
						<font face="Times New Roman">include</font>
				</span>
				<span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-weight: bold">部分。</span>
				<span lang="EN-US" style="FONT-SIZE: 12pt; mso-bidi-font-weight: bold">
						<p> </p>
				</span>
		</p>
		<p>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-weight: bold">看下面几行（注意黑体）：</span>
				<span lang="EN-US" style="FONT-SIZE: 12pt; mso-bidi-font-weight: bold">
						<p> </p>
				</span>
		</p>
		<p>
		</p>
		<div style="BORDER-RIGHT: black 1pt solid; PADDING-RIGHT: 1pt; BORDER-TOP: black 1pt solid; PADDING-LEFT: 1pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 1pt; BORDER-LEFT: black 1pt solid; PADDING-TOP: 1pt; BORDER-BOTTOM: black 1pt solid; mso-element: para-border-div; mso-border-alt: solid black .75pt">
				<p class="western" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 0cm; MARGIN: auto 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-border-alt: solid black .75pt; mso-padding-alt: 1.0pt 1.0pt 1.0pt 1.0pt">
						<b>
								<i>
										<span lang="EN-US" style="FONT-SIZE: 12pt">
												<font face="Times New Roman">#include “newton.h”<br /></font>
										</span>
								</i>
						</b>
						<i>
								<span lang="EN-US" style="FONT-SIZE: 12pt">
										<font face="Times New Roman">#include "tutorial.h"<br />#include "HiResTimer.h"<br />#include "RenderPrimitive.h"<br />#include "Newton.h"</font>
								</span>
						</i>
				</p>
		</div>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">
						<font size="3">找到文件主要函数。</font>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<font size="3">
						<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">首先初始化图形引擎。在这个案例中我们已经把</span>
						<span lang="EN-US">
								<font face="Times New Roman">opengl</font>
						</span>
						<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的初始化压成一个简单的函数。它可以完成你的引擎中主要系统的初始化。</span>
				</font>
		</p>
		<div style="BORDER-RIGHT: black 1pt solid; PADDING-RIGHT: 1pt; BORDER-TOP: black 1pt solid; PADDING-LEFT: 1pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 1pt; BORDER-LEFT: black 1pt solid; PADDING-TOP: 1pt; BORDER-BOTTOM: black 1pt solid; mso-element: para-border-div; mso-border-alt: solid black .75pt">
				<p class="western" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 0cm; MARGIN: auto 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-border-alt: solid black .75pt; mso-padding-alt: 1.0pt 1.0pt 1.0pt 1.0pt">
						<i>
								<span lang="EN-US" style="FONT-SIZE: 12pt">
										<font face="Times New Roman">// Initialize opengl <br />InitOpenGl (argc, argv, "<city w:st="on"><place w:st="on">Newton</place></city>Getting Started", DrawScene, NULL, Keyboard);</font>
								</span>
						</i>
				</p>
		</div>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">
						<font size="3">接下来你将看到场景初始化的的相关调用。</font>
				</span>
		</p>
		<div style="BORDER-RIGHT: black 1pt solid; PADDING-RIGHT: 1pt; BORDER-TOP: black 1pt solid; PADDING-LEFT: 1pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 1pt; BORDER-LEFT: black 1pt solid; PADDING-TOP: 1pt; BORDER-BOTTOM: black 1pt solid; mso-element: para-border-div; mso-border-alt: solid black .75pt">
				<p class="western" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 0cm; MARGIN: auto 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-border-alt: solid black .75pt; mso-padding-alt: 1.0pt 1.0pt 1.0pt 1.0pt">
						<i>
								<span lang="EN-US" style="FONT-SIZE: 12pt">
										<font face="Times New Roman">// Create the physics scene. This represents your engine scene initialization<br />InitScene();</font>
								</span>
						</i>
				</p>
		</div>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<font size="3">
						<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">最后是</span>
						<span lang="EN-US">
								<font face="Times New Roman">opengl</font>
						</span>
						<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的主体循环调用，它描述的是你的引擎主循环。</span>
				</font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<font size="3">
						<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">现在找到函数</span>
						<b>
								<span lang="EN-US" style="FONT-SIZE: 12pt">
										<font face="Times New Roman">InitScene</font>
								</span>
						</b>
				</font>
				<b>
						<span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，</span>
				</b>
				<span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-weight: bold">物理引擎的初始化就在那里。</span>
				<span lang="EN-US" style="FONT-SIZE: 12pt; mso-bidi-font-weight: bold">
						<p> </p>
				</span>
		</p>
		<p>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-weight: bold">在这个例程中，我们将实现一个简单的物理场景：一个刚体球悬浮在真空中。</span>
				<span lang="EN-US" style="FONT-SIZE: 12pt; mso-bidi-font-weight: bold">
						<p> </p>
				</span>
		</p>
		<p>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-weight: bold">我们将看到：</span>
				<span lang="EN-US" style="FONT-SIZE: 12pt; mso-bidi-font-weight: bold">
						<p> </p>
				</span>
		</p>
		<p>
		</p>
		<div style="BORDER-RIGHT: black 1pt solid; PADDING-RIGHT: 1pt; BORDER-TOP: black 1pt solid; PADDING-LEFT: 1pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 1pt; BORDER-LEFT: black 1pt solid; PADDING-TOP: 1pt; BORDER-BOTTOM: black 1pt solid; mso-element: para-border-div; mso-border-alt: solid black .75pt">
				<p class="western" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 0cm; MARGIN: auto 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-border-alt: solid black .75pt; mso-padding-alt: 1.0pt 1.0pt 1.0pt 1.0pt">
						<i>
								<span lang="EN-US" style="FONT-SIZE: 12pt">
										<font face="Times New Roman">// Create the newton world<br />nWorld = NewtonCreate (NULL, NULL);</font>
								</span>
						</i>
				</p>
		</div>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<font size="3">
						<span lang="EN-US">
								<font face="Times New Roman">//</font>
						</span>
						<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">译者注：实际上这之前还需要声明</span>
						<span lang="EN-US">
								<font face="Times New Roman">nWorld</font>
						</span>
						<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，以下许多地方类似</span>
				</font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<font size="3">
						<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">它将为</span>
						<span lang="EN-US">
								<font face="Times New Roman">nowton </font>
						</span>
						<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">世界创建一个句柄，并初始化所有内部结构。这里我们先忽视两个参数，在下个例程中我们将对之详细说明。我们保持这个指向</span>
						<span lang="EN-US">
								<font face="Times New Roman">nowton</font>
						</span>
						<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">世界的句柄为全程变量。</span>
				</font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<font size="3">
						<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">但是它（</span>
						<span lang="EN-US">
								<font face="Times New Roman">nowton</font>
						</span>
						<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">世界）不可能脱离</span>
						<span lang="EN-US">
								<font face="Times New Roman">opengl</font>
						</span>
						<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">循环，所以我们要设定一个事件去终止</span>
						<span lang="EN-US">
								<font face="Times New Roman">nowton</font>
						</span>
						<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">世界和我们已经分配的所有资源。这就是</span>
						<span lang="EN-US" style="FONT-SIZE: 12pt">
								<font face="Times New Roman">onexit (Cleanup)</font>
						</span>
				</font>
				<span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">所要做的。</span>
				<span lang="EN-US" style="FONT-SIZE: 12pt">
						<p> </p>
				</span>
		</p>
		<p>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">接下来我们要创建一个刚体，在这之前我们要创建它的几何碰撞。（刚体每时每刻都必须有几何碰撞）</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">
						<font size="3">所以我们根据图形箱子大小去创建一个碰撞。</font>
				</span>
		</p>
		<div style="BORDER-RIGHT: black 1pt solid; PADDING-RIGHT: 1pt; BORDER-TOP: black 1pt solid; PADDING-LEFT: 1pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 1pt; BORDER-LEFT: black 1pt solid; PADDING-TOP: 1pt; BORDER-BOTTOM: black 1pt solid; mso-element: para-border-div; mso-border-alt: solid black .75pt">
				<p class="western" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 0cm; MARGIN: auto 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-border-alt: solid black .75pt; mso-padding-alt: 1.0pt 1.0pt 1.0pt 1.0pt">
						<i>
								<span lang="EN-US" style="FONT-SIZE: 12pt">
										<font face="Times New Roman">// Create the collision shape<br />collision = NewtonCreateBox (nWorld, box.m_x * <chmetcnv w:st="on" tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="2" unitname="F">2.0f</chmetcnv>, box.m_y * <chmetcnv w:st="on" tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="2" unitname="F">2.0f</chmetcnv>, box.m_z * <chmetcnv w:st="on" tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="2" unitname="F">2.0f</chmetcnv>, NULL); </font>
								</span>
						</i>
				</p>
		</div>
		<p class="western" style="MARGIN: auto 0cm 0pt">
				<span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">第一个参数是</span>
				<span lang="EN-US" style="FONT-SIZE: 10.5pt">
						<font face="Times New Roman">Newton world</font>
				</span>
				<span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，接下来的是箱子大小，最后一个参数是用来设置从源刚体而得到的几何碰撞中偏转转换矩阵。当使用</span>
				<span lang="EN-US" style="FONT-SIZE: 10.5pt">
						<font face="Times New Roman">Null</font>
				</span>
				<span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">时，这个箱子会被源物体替代。现在我们创建刚体并保存为一个全局变量。</span>
				<span lang="EN-US" style="FONT-SIZE: 10.5pt">
						<p> </p>
				</span>
		</p>
		<p>
		</p>
		<div style="BORDER-RIGHT: black 1pt solid; PADDING-RIGHT: 1pt; BORDER-TOP: black 1pt solid; PADDING-LEFT: 1pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 1pt; BORDER-LEFT: black 1pt solid; PADDING-TOP: 1pt; BORDER-BOTTOM: black 1pt solid; mso-element: para-border-div; mso-border-alt: solid black .75pt">
				<p class="western" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 0cm; MARGIN: auto 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-border-alt: solid black .75pt; mso-padding-alt: 1.0pt 1.0pt 1.0pt 1.0pt">
						<i>
								<span lang="EN-US" style="FONT-SIZE: 12pt">
										<font face="Times New Roman">// Create the ridid body<br />ribidBodyBox = NewtonCreateBody (nWorld, collision);</font>
								</span>
						</i>
				</p>
		</div>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<font size="3">
						<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">当你使用完碰撞对象后你要释放它，碰撞对象在</span>
						<span lang="EN-US">
								<font face="Times New Roman">newton</font>
						</span>
						<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">里是唯一一个使用</span>
						<span lang="EN-US">
								<font face="Times New Roman">reference</font>
						</span>
						<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">数的对象，这是有必要的因为其他刚体可以分享几何碰撞。取个例子来说，你可以创建很多个同样大小的箱子，你可以使用同一个几何碰撞。</span>
				</font>
		</p>
		<div style="BORDER-RIGHT: black 1pt solid; PADDING-RIGHT: 1pt; BORDER-TOP: black 1pt solid; PADDING-LEFT: 1pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 1pt; BORDER-LEFT: black 1pt solid; PADDING-TOP: 1pt; BORDER-BOTTOM: black 1pt solid; mso-element: para-border-div; mso-border-alt: solid black .75pt">
				<p class="western" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 0cm; MARGIN: auto 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-border-alt: solid black .75pt; mso-padding-alt: 1.0pt 1.0pt 1.0pt 1.0pt">
						<i>
								<span lang="EN-US" style="FONT-SIZE: 12pt">
										<font face="Times New Roman">// Get rid of the collision<br />NewtonReleaseCollision (nWorld, collision); 
<p> </p></font>
								</span>
						</i>
				</p>
				<p>
				</p>
		</div>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<font size="3">
						<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">当</span>
						<span lang="EN-US">
								<font face="Times New Roman">newton</font>
						</span>
						<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">创建一个刚体，质量设置为无限以保持这个刚体呈静态。我们需要去告诉</span>
						<span lang="EN-US">
								<font face="Times New Roman">newton</font>
						</span>
						<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这个物体是动态的，就调用下面这个</span>
				</font>
		</p>
		<div style="BORDER-RIGHT: black 1pt solid; PADDING-RIGHT: 1pt; BORDER-TOP: black 1pt solid; PADDING-LEFT: 1pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 1pt; BORDER-LEFT: black 1pt solid; PADDING-TOP: 1pt; BORDER-BOTTOM: black 1pt solid; mso-element: para-border-div; mso-border-alt: solid black .75pt">
				<p class="western" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 0cm; MARGIN: auto 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-border-alt: solid black .75pt; mso-padding-alt: 1.0pt 1.0pt 1.0pt 1.0pt">
						<i>
								<span lang="EN-US" style="FONT-SIZE: 12pt">
										<font face="Times New Roman">// set the body mass and inertia<br />NewtonBodySetMassMatrix (ribidBodyBox, <chmetcnv w:st="on" tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="1" unitname="F">1.0f</chmetcnv>, <chmetcnv w:st="on" tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="1" unitname="F">1.0f</chmetcnv>, <chmetcnv w:st="on" tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="1" unitname="F">1.0f</chmetcnv>, <chmetcnv w:st="on" tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="1" unitname="F">1.0f</chmetcnv>);</font>
								</span>
						</i>
				</p>
		</div>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<font size="3">
						<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-size: 10.5pt">别去考虑质量与惯性，他们将会在例程</span>
						<span lang="EN-US" style="mso-bidi-font-size: 10.5pt">
								<font face="Times New Roman">the Dealing with Mass and Inertia</font>
						</span>
						<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-size: 10.5pt">中讨论。</span>
						<span lang="EN-US" style="mso-bidi-font-size: 10.5pt">
								<p> </p>
						</span>
				</font>
		</p>
		<p>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">我们同样需要在这个世界中物体的位置。</span>
		</p>
		<div style="BORDER-RIGHT: black 1pt solid; PADDING-RIGHT: 1pt; BORDER-TOP: black 1pt solid; PADDING-LEFT: 1pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 1pt; BORDER-LEFT: black 1pt solid; PADDING-TOP: 1pt; BORDER-BOTTOM: black 1pt solid; mso-element: para-border-div; mso-border-alt: solid black .75pt">
				<p class="western" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 0cm; MARGIN: auto 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-border-alt: solid black .75pt; mso-padding-alt: 1.0pt 1.0pt 1.0pt 1.0pt">
						<span lang="EN-US" style="FONT-SIZE: 12pt">
								<font face="Times New Roman">/<i>/ Set the transformation matrix</i></font>
						</span>
						<i>
								<span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">设置变换矩阵</span>
						</i>
						<i>
								<span lang="EN-US" style="FONT-SIZE: 12pt">
										<br />
										<font face="Times New Roman">dMatrix matrix (box.GetMatrix());<br />matrix.m_posit.m_x = <chmetcnv w:st="on" tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="0" unitname="F">0.0f</chmetcnv>;<br />matrix.m_posit.m_y = <chmetcnv w:st="on" tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="1" unitname="F">1.0f</chmetcnv>;<br />matrix.m_posit.m_z = <chmetcnv w:st="on" tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="0" unitname="F">0.0f</chmetcnv>;<br />NewtonBodySetMatrix (ribidBodyBox, &amp;matrix[0][0]);</font>
								</span>
						</i>
				</p>
		</div>
		<p class="western" style="MARGIN: auto 0cm 0pt">
				<span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这里没有应力和应变应用在这个物体上，我们仅仅是应用了最初的角速度</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">
						<font size="2">。</font>
				</span>
		</p>
		<div style="BORDER-RIGHT: black 1pt solid; PADDING-RIGHT: 1pt; BORDER-TOP: black 1pt solid; PADDING-LEFT: 1pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 1pt; BORDER-LEFT: black 1pt solid; PADDING-TOP: 0cm; BORDER-BOTTOM: black 1pt solid; mso-element: para-border-div; mso-border-alt: solid black .75pt">
				<p class="western" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 0cm; MARGIN: auto 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-border-alt: solid black .75pt; mso-padding-alt: 0cm 1.0pt 1.0pt 1.0pt">
						<i>
								<span lang="EN-US" style="FONT-SIZE: 12pt">
										<font face="Times New Roman">// Animate the body by setting the angular velocity</font>
								</span>
						</i>
						<i>
								<span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">设置角速度使物体动起来</span>
						</i>
						<i>
								<span lang="EN-US" style="FONT-SIZE: 12pt">
										<br />
										<font face="Times New Roman">dVector omega (<chmetcnv w:st="on" tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="1" unitname="F">1.0f</chmetcnv>, <chmetcnv w:st="on" tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="1" unitname="F">1.0f</chmetcnv>, <chmetcnv w:st="on" tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="1" unitname="F">1.0f</chmetcnv>);<br />NewtonBodySetOmega (ribidBodyBox, &amp;omega[0]);</font>
								</span>
						</i>
				</p>
		</div>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<font size="3">
						<span lang="EN-US">
								<font face="Times New Roman">//</font>
						</span>
						<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这里的</span>
						<i>
								<span lang="EN-US" style="FONT-SIZE: 12pt">
										<font face="Times New Roman">NewtonBodySetOmega</font>
								</span>
						</i>
				</font>
				<i>
						<span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中的</span>
				</i>
				<i>
						<span lang="EN-US" style="FONT-SIZE: 12pt">
								<font face="Times New Roman">Omega</font>
						</span>
				</i>
				<i>
						<span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">其实是小写希腊字母最后一个——</span>
				</i>
				<i>
						<span lang="EN-US" style="FONT-SIZE: 12pt">
								<font face="Times New Roman">ω</font>
						</span>
				</i>
				<i>
						<span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，即物理中的角速度。</span>
				</i>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">
						<font size="3">这是所有初始化，现在是主要的仿真循环。</font>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<font size="3">
						<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">每一帧在</span>
						<span lang="EN-US">
								<font face="Times New Roman">OPENGL</font>
						</span>
						<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">或者你的引擎中都将在主要仿真循环中创建一个回调。在这个例程中，它是函数</span>
						<b>
								<span lang="EN-US" style="FONT-SIZE: 12pt">
										<font face="Times New Roman">DrawScene</font>
								</span>
						</b>
				</font>
				<b>
						<span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</span>
				</b>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">
						<font size="3">注意我们需要取得从最后一次更新到现在的时间。它使用下面这个函数。</font>
				</span>
		</p>
		<div style="BORDER-RIGHT: black 1pt solid; PADDING-RIGHT: 1pt; BORDER-TOP: black 1pt solid; PADDING-LEFT: 1pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 1pt; BORDER-LEFT: black 1pt solid; PADDING-TOP: 1pt; BORDER-BOTTOM: black 1pt solid; mso-element: para-border-div; mso-border-alt: solid black .75pt">
				<p class="western" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 0cm; MARGIN: auto 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-border-alt: solid black .75pt; mso-padding-alt: 1.0pt 1.0pt 1.0pt 1.0pt">
						<i>
								<span lang="EN-US" style="FONT-SIZE: 12pt">
										<font face="Times New Roman">// get the time step<br />timeStep = timer.GetElapsedSeconds();</font>
								</span>
						</i>
				</p>
		</div>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<font size="3">
						<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">接下来，我们调用</span>
						<span lang="EN-US">
								<font face="Times New Roman">NewtonUpdate</font>
						</span>
						<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">来用时间量推动这个世界。</span>
				</font>
		</p>
		<div style="BORDER-RIGHT: black 1pt solid; PADDING-RIGHT: 1pt; BORDER-TOP: black 1pt solid; PADDING-LEFT: 1pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 1pt; BORDER-LEFT: black 1pt solid; PADDING-TOP: 1pt; BORDER-BOTTOM: black 1pt solid; mso-element: para-border-div; mso-border-alt: solid black .75pt">
				<p class="western" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 0cm; MARGIN: auto 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-border-alt: solid black .75pt; mso-padding-alt: 1.0pt 1.0pt 1.0pt 1.0pt">
						<i>
								<span lang="EN-US" style="FONT-SIZE: 12pt">
										<font face="Times New Roman">// update the <place w:st="on"><city w:st="on">Newton</city></place> physics world<br />NewtonUpdate (nWorld, timeStep);</font>
								</span>
						</i>
				</p>
		</div>
		<p class="western" style="MARGIN: auto 0cm 0pt">
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">
						<font size="2">现在我们需要找到在世界更新的过程中位置改变的物体变换矩阵，在这个例子中我们只有一个物体。</font>
				</span>
		</p>
		<div style="BORDER-RIGHT: black 1pt solid; PADDING-RIGHT: 1pt; BORDER-TOP: black 1pt solid; PADDING-LEFT: 1pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 1pt; BORDER-LEFT: black 1pt solid; PADDING-TOP: 1pt; BORDER-BOTTOM: black 1pt solid; mso-element: para-border-div; mso-border-alt: solid black .75pt">
				<p class="western" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 0cm; MARGIN: auto 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-border-alt: solid black .75pt; mso-padding-alt: 1.0pt 1.0pt 1.0pt 1.0pt">
						<i>
								<span lang="EN-US" style="FONT-SIZE: 12pt">
										<font face="Times New Roman">// get the matrix from the rigid body<br />dMatrix matrix;<br />NewtonBodyGetMatrix(ribidBodyBox, &amp;matrix[0][0]);</font>
								</span>
						</i>
				</p>
		</div>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">
						<font size="3">现在我们需要去应用这些转换到图形物体中。</font>
				</span>
		</p>
		<div style="BORDER-RIGHT: black 1pt solid; PADDING-RIGHT: 1pt; BORDER-TOP: black 1pt solid; PADDING-LEFT: 1pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 1pt; BORDER-LEFT: black 1pt solid; PADDING-TOP: 1pt; BORDER-BOTTOM: black 1pt solid; mso-element: para-border-div; mso-border-alt: solid black .75pt">
				<p class="western" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 0cm; MARGIN: auto 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-border-alt: solid black .75pt; mso-padding-alt: 1.0pt 1.0pt 1.0pt 1.0pt">
						<i>
								<span lang="EN-US" style="FONT-SIZE: 12pt">
										<font face="Times New Roman">// Set the matrix of the visual body<br />box.SetMatrix (matrix);</font>
								</span>
						</i>
				</p>
		</div>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">
						<font size="3">最后我们渲染场景。</font>
				</span>
		</p>
		<div style="BORDER-RIGHT: black 1pt solid; PADDING-RIGHT: 1pt; BORDER-TOP: black 1pt solid; PADDING-LEFT: 1pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 1pt; BORDER-LEFT: black 1pt solid; PADDING-TOP: 1pt; BORDER-BOTTOM: black 1pt solid; mso-element: para-border-div; mso-border-alt: solid black .75pt">
				<p class="western" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 0cm; MARGIN: auto 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-border-alt: solid black .75pt; mso-padding-alt: 1.0pt 1.0pt 1.0pt 1.0pt">
						<i>
								<span lang="EN-US" style="FONT-SIZE: 12pt">
										<font face="Times New Roman">// Render the object<br />glPushMatrix();<br />box.Render();<br />glPopMatrix();</font>
								</span>
						</i>
				</p>
		</div>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">
						<font size="3">这些都包含在主循环中。</font>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<font size="3">
						<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">最后的事情就是终止应用程序，我们用点击关闭窗体按钮或者按</span>
						<span lang="EN-US">
								<font face="Times New Roman">ESCAPE</font>
						</span>
						<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">键来终止。每个案例都是用</span>
						<span lang="EN-US">
								<font face="Times New Roman">exit(0)</font>
						</span>
						<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</span>
				</font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<font size="3">
						<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这个函数将会调用所有终止程序并次序颠倒的运行。在我们的案例中我们仅仅是使用</span>
						<span lang="EN-US">
								<font face="Times New Roman">cleanup</font>
						</span>
						<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">函数去销毁</span>
						<span lang="EN-US">
								<font face="Times New Roman">the Newton world</font>
						</span>
						<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</span>
				</font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<font size="3">
						<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">操作这个例程用</span>
						<span lang="EN-US">
								<font face="Times New Roman">WSAD</font>
						</span>
						<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">键。</span>
				</font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">
						<font size="3">改变运动趋势按鼠标并移动鼠标。</font>
				</span>
		</p>
		<div style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 1pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; mso-element: para-border-div; mso-border-bottom-alt: solid windowtext .75pt">
				<p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-padding-alt: 0cm 0cm 1.0pt 0cm; mso-border-bottom-alt: solid windowtext .75pt">
						<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">
								<font size="3">例程结束。</font>
						</span>
				</p>
		</div>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">
						<font size="3">从这个例程中我们可以看出，物理引擎的基本操作步骤。</font>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt; mso-list: l0 level1 lfo2; tab-stops: list 18.0pt">
				<span lang="EN-US" style="mso-fareast-font-family: 'Times New Roman'">
						<span style="mso-list: Ignore">
								<font face="Times New Roman">
										<font size="3">1、</font>
										<span style="FONT: 7pt 'Times New Roman'">  </span>
								</font>
						</span>
				</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">
						<font size="3">初始化物理引擎。</font>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt; mso-list: l0 level1 lfo2; tab-stops: list 18.0pt">
				<span lang="EN-US" style="mso-fareast-font-family: 'Times New Roman'">
						<span style="mso-list: Ignore">
								<font face="Times New Roman">
										<font size="3">2、</font>
										<span style="FONT: 7pt 'Times New Roman'">  </span>
								</font>
						</span>
				</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">
						<font size="3">取得物体的几何碰撞。</font>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt; mso-list: l0 level1 lfo2; tab-stops: list 18.0pt">
				<span lang="EN-US" style="mso-fareast-font-family: 'Times New Roman'">
						<span style="mso-list: Ignore">
								<font face="Times New Roman">
										<font size="3">3、</font>
										<span style="FONT: 7pt 'Times New Roman'">  </span>
								</font>
						</span>
				</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">
						<font size="3">根据几何碰撞创建刚体。</font>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt; mso-list: l0 level1 lfo2; tab-stops: list 18.0pt">
				<span lang="EN-US" style="mso-fareast-font-family: 'Times New Roman'">
						<span style="mso-list: Ignore">
								<font face="Times New Roman">
										<font size="3">4、</font>
										<span style="FONT: 7pt 'Times New Roman'">  </span>
								</font>
						</span>
				</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">
						<font size="3">释放几何碰撞（很多人会忘记，但很重要）</font>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt; mso-list: l0 level1 lfo2; tab-stops: list 18.0pt">
				<span lang="EN-US" style="mso-fareast-font-family: 'Times New Roman'">
						<span style="mso-list: Ignore">
								<font face="Times New Roman">
										<font size="3">5、</font>
										<span style="FONT: 7pt 'Times New Roman'">  </span>
								</font>
						</span>
				</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">
						<font size="3">设置变换矩阵。</font>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt; mso-list: l0 level1 lfo2; tab-stops: list 18.0pt">
				<span lang="EN-US" style="mso-fareast-font-family: 'Times New Roman'">
						<span style="mso-list: Ignore">
								<font face="Times New Roman">
										<font size="3">6、</font>
										<span style="FONT: 7pt 'Times New Roman'">  </span>
								</font>
						</span>
				</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">
						<font size="3">更新物理引擎。</font>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt; mso-list: l0 level1 lfo2; tab-stops: list 18.0pt">
				<span lang="EN-US" style="mso-fareast-font-family: 'Times New Roman'">
						<span style="mso-list: Ignore">
								<font face="Times New Roman">
										<font size="3">7、</font>
										<span style="FONT: 7pt 'Times New Roman'">  </span>
								</font>
						</span>
				</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">
						<font size="3">取得变换矩阵。</font>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt; mso-list: l0 level1 lfo2; tab-stops: list 18.0pt">
				<span lang="EN-US" style="mso-fareast-font-family: 'Times New Roman'">
						<span style="mso-list: Ignore">
								<font face="Times New Roman">
										<font size="3">8、</font>
										<span style="FONT: 7pt 'Times New Roman'">  </span>
								</font>
						</span>
				</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">
						<font size="3">根据取得的变换矩阵设置绘制物体当前状态。</font>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt; mso-list: l0 level1 lfo2; tab-stops: list 18.0pt">
				<span lang="EN-US" style="mso-fareast-font-family: 'Times New Roman'">
						<span style="mso-list: Ignore">
								<font face="Times New Roman">
										<font size="3">9、</font>
										<span style="FONT: 7pt 'Times New Roman'">  </span>
								</font>
						</span>
				</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">
						<font size="3">释放物理引擎。</font>
				</span>
		</p>
<img src ="http://www.cppblog.com/tx7do/aggbug/17982.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tx7do/" target="_blank">杨粼波</a> 2007-01-25 15:49 <a href="http://www.cppblog.com/tx7do/archive/2007/01/25/17982.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>三个物理引擎(转)</title><link>http://www.cppblog.com/tx7do/archive/2007/01/25/17981.html</link><dc:creator>杨粼波</dc:creator><author>杨粼波</author><pubDate>Thu, 25 Jan 2007 07:48:00 GMT</pubDate><guid>http://www.cppblog.com/tx7do/archive/2007/01/25/17981.html</guid><wfw:comment>http://www.cppblog.com/tx7do/comments/17981.html</wfw:comment><comments>http://www.cppblog.com/tx7do/archive/2007/01/25/17981.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/tx7do/comments/commentRss/17981.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tx7do/services/trackbacks/17981.html</trackback:ping><description><![CDATA[
		<strong>
				<font size="2">
						<span class="tpc_title">介绍三个物理引擎以及讨论</span>
						<br />
						<br />
				</font>
		</strong>
		<span class="tpc_content">物理引擎在3D的领域中是较年轻的，而且难度也比较高，<br />先製作这篇文章，是想让大家有个先行印象，了解这是什么。<br /><br />別担心，最终这些教学终將连结成为一体，我只是让大家的概念先推前一下。<br />当成看杂誌一般的心情即可，如果你有研究，会使用SDK，也可以马上开始。<br /><br /><strong>关於物理</strong><br />牛顿归纳出了地心引力的通则，並且开始以数学方法描述物理现象，<br />这已经是很久前的事情了，但是並不只是东西往下掉而已，虽然简单讲是这样。<br />球会滚动、羽毛会飘落、摩擦力......等等，都是自然界常见的力学现象。<br /><br /><strong>关於游戏的物理</strong><br />在2D游戏里，大部分的物理被简化为"离开地面的时候，就往下掉"，这样简单易懂，<br />马里奥、洛克人都是这样，所以我们习以为常，甚至大多数的游戏都不考虑物理的。<br />(比较明显的例子是，1942里的飞机是不可能"空中倒退"的，但实际上没人觉得奇怪)。<br /><br />事实上有个东西叫做力矩，你拋出一个纸团，他不只受地心引力往下拉，还会旋转，<br />可是要在游戏里实现这样的功能，只能说是"奢侈、浪费运算"，或是"令人不习惯"。<br /><br />现在的3D游戏已经大抵脱离简单的多边形，在建模上栩栩如生，尤其是FPS，<br />更是讲求真实，这样的演化路线终於演进到了玩家与环境的关係上。<br /><br />你用枪打玻璃，玻璃会破碎，打坏一叠箱子底下的一个，整个会塌下来，说实话，<br />一般人不太可能在现实做这些事情(但是生活中还是有物理)，游戏中要求真实性，<br />那么就需要做出一套运算库，让游戏中实现接近真实的物理。<br /><br />好吧，3D很难，复杂的数学更难，所以要栩栩如生的表现出来，几乎不可能，<br />这变成了一种商业机密、或者是纯学术研究的討论，一直到近几年，才比较平民化，<br />因为3D创作工具也普及了，结合这些东西，你也可以在自己的游戏中实现物理。<br /><br /><strong>普及的物理引擎</strong><br />这里列出三个常常被使用的物理引擎，不代表全部，但掌握其中一个都很有帮助。<br /><br /><font color="#0000ff">Open Dynamics Engine</font><a href="http://www.ode.org/" target="_blank">http://www.ode.org/</a><br />免费、开源、授权合理，所以基本上很多游戏引擎都有绑定ODE作为物理引擎，<br />但是其缺点之一就是在多物件时，相较其他物理引擎，会比较慢，但是，<br />部分修改过的商业版本情况好一点，但却不是开源的了。<br /><br /><font color="#0000ff">Newton Game Dynamics</font><a href="http://www.newtondynamics.com/" target="_blank">http://www.newtondynamics.com/</a><br />这个物理引擎是跨Win32/Mac/Linux三个平台的，同时也有3DGameStudio插件，<br />在速度和功能上很不错，你也可以找到大量范例，虽然没有开源，但广为使用，<br />有兴趣的人，从这个开始是不错的选择，他也是OGRE游戏引擎的组件之一。<br /><br /><font color="#0000ff">Tokamak Game Physics</font><a href="http://www.tokamakphysics.com/" target="_blank">http://www.tokamakphysics.com/</a><br />Tokamak是一个速度极快的物理引擎，基本上他只能被使用於Windows平台，<br />但是速度上的优势让他佔有一席之地，当然这引擎也是免费提供的，<br />Tokamak有被应用为Blitz3D的插件，所以您若是Blitz3D用户，可能见过其身影。</span>
<img src ="http://www.cppblog.com/tx7do/aggbug/17981.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tx7do/" target="_blank">杨粼波</a> 2007-01-25 15:48 <a href="http://www.cppblog.com/tx7do/archive/2007/01/25/17981.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>转自OGRE的一些游戏编程的链接 </title><link>http://www.cppblog.com/tx7do/archive/2007/01/25/17980.html</link><dc:creator>杨粼波</dc:creator><author>杨粼波</author><pubDate>Thu, 25 Jan 2007 07:47:00 GMT</pubDate><guid>http://www.cppblog.com/tx7do/archive/2007/01/25/17980.html</guid><wfw:comment>http://www.cppblog.com/tx7do/comments/17980.html</wfw:comment><comments>http://www.cppblog.com/tx7do/archive/2007/01/25/17980.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/tx7do/comments/commentRss/17980.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tx7do/services/trackbacks/17980.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: C++ / STL				[edit]												Introduction / Help																		C++ slides Optimisations, Templates and good use of heritage and polymorphisms								 (http://www.rz.rwth-aachen.de...&nbsp;&nbsp;<a href='http://www.cppblog.com/tx7do/archive/2007/01/25/17980.html'>阅读全文</a><img src ="http://www.cppblog.com/tx7do/aggbug/17980.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tx7do/" target="_blank">杨粼波</a> 2007-01-25 15:47 <a href="http://www.cppblog.com/tx7do/archive/2007/01/25/17980.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>OGRE学习笔记之一</title><link>http://www.cppblog.com/tx7do/archive/2007/01/23/17926.html</link><dc:creator>杨粼波</dc:creator><author>杨粼波</author><pubDate>Tue, 23 Jan 2007 09:07:00 GMT</pubDate><guid>http://www.cppblog.com/tx7do/archive/2007/01/23/17926.html</guid><wfw:comment>http://www.cppblog.com/tx7do/comments/17926.html</wfw:comment><comments>http://www.cppblog.com/tx7do/archive/2007/01/23/17926.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.cppblog.com/tx7do/comments/commentRss/17926.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tx7do/services/trackbacks/17926.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 开始学习3D了,很早就想学了,怎奈数学不好,一直畏惧,可是如果不直面它,就永远的害怕,永远的逃避,这是在很糟.于是,我终于开始了我的3D之旅.在学校时候就看上了OGRE,十几万行代码的图形引擎,它给我的感觉很好.不过奇怪的是国内似乎根本没有OGRE的社区,曾经是在91看到的,可是那边早已经荒废了.我使用的是OGRE的 1.2.4,VC是VC.net 2003,也就是VC7.1.我是下载源代码,自行...&nbsp;&nbsp;<a href='http://www.cppblog.com/tx7do/archive/2007/01/23/17926.html'>阅读全文</a><img src ="http://www.cppblog.com/tx7do/aggbug/17926.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tx7do/" target="_blank">杨粼波</a> 2007-01-23 17:07 <a href="http://www.cppblog.com/tx7do/archive/2007/01/23/17926.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>VC：CxImage 試用</title><link>http://www.cppblog.com/tx7do/archive/2006/09/17/12598.html</link><dc:creator>杨粼波</dc:creator><author>杨粼波</author><pubDate>Sun, 17 Sep 2006 13:53:00 GMT</pubDate><guid>http://www.cppblog.com/tx7do/archive/2006/09/17/12598.html</guid><wfw:comment>http://www.cppblog.com/tx7do/comments/12598.html</wfw:comment><comments>http://www.cppblog.com/tx7do/archive/2006/09/17/12598.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/tx7do/comments/commentRss/12598.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tx7do/services/trackbacks/12598.html</trackback:ping><description><![CDATA[
		<p>為了讓自己的 MFC 程式能開啟一些常用的圖檔格式，但自己只寫過開啟BMP的方法，所以希望能找到一些現成能用的東西。聽到 CxImage 這個東西。</p>
		<p>
				<a href="http://www.codeproject.com/bitmap/cximage.asp">http://www.codeproject.com/bitmap/cximage.asp</a>
		</p>
		<p> </p>
		<p> </p>
		<p>
				<strong>【嘗試安裝】</strong>
		</p>
		<p>下載回來後，裡面雖然有完整的說明文件，但似乎找不到安裝說明，有點頭痛。試著把裡面各個目錄中的專案都 running 過一次後，結果產生了以下的 *.lib 檔案：CxImage.lib、j2k.lib、jasper.lib、jbig.lib、jpeg.lib、png.lib、tiff.lib、zlib.lib，將它們放入 Microsoft Visual Studio\VC98\Lib 中，接著將 CxImage 目錄中的 *.h、*.cpp 拷貝到 Microsoft Visual Studio\VC98\Include\CxImage 目錄中<font color="#a2a2a2">〈本來想拷備到自己的專案中，但是怕太亂...〉</font>，最後用以下方式連結：</p>
		<p>
				<font color="#444f75"> </font>
		</p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />
				<span style="COLOR: #000000">#pragma comment (lib, </span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">CxImage.lib</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">)<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />#pragma comment (lib, </span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">j2k.lib</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">)<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />#pragma comment (lib, </span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">jasper.lib</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">)<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />#pragma comment (lib, </span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">jbig.lib</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">)<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />#pragma comment (lib, </span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">jpeg.lib</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">)<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />#pragma comment (lib, </span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">png.lib</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">)<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />#pragma comment (lib, </span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">tiff.lib</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">)<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />#pragma comment (lib, </span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">zlib.lib</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">)<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />#include </span>
				<span style="COLOR: #000000">&lt;</span>
				<span style="COLOR: #000000">CxImage</span>
				<span style="COLOR: #000000">/</span>
				<span style="COLOR: #000000">ximage.h</span>
				<span style="COLOR: #000000">&gt;</span>
		</div>
		<p> </p>
		<p> </p>
		<p>結果可以成功編譯，接著看看是不是真的能使用：</p>
		<p>
				<strong>Document 中：<br /></strong>
		</p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />
				<span style="COLOR: #000000">CxImage myImage;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />myImage.Load(</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">test.jpg</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">, </span>
				<span style="COLOR: #000000">0</span>
				<span style="COLOR: #000000">);</span>
		</div>
		<p> </p>
		<p>
				<strong>View 中：</strong>
				<br />
		</p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />
				<span style="COLOR: #000000">pDoc</span>
				<span style="COLOR: #000000">-&gt;</span>
				<span style="COLOR: #000000">myImage.Draw( pDC</span>
				<span style="COLOR: #000000">-&gt;</span>
				<span style="COLOR: #000000">GetSafeHdc(), </span>
				<span style="COLOR: #000000">0</span>
				<span style="COLOR: #000000">, </span>
				<span style="COLOR: #000000">0</span>
				<span style="COLOR: #000000">, </span>
				<span style="COLOR: #000000">-</span>
				<span style="COLOR: #000000">1</span>
				<span style="COLOR: #000000">, </span>
				<span style="COLOR: #000000">-</span>
				<span style="COLOR: #000000">1</span>
				<span style="COLOR: #000000">, NULL, </span>
				<span style="COLOR: #0000ff">false</span>
				<span style="COLOR: #000000">);</span>
		</div>
		<p> </p>
		<p> </p>
		<p>圖片真的成功讀進來了。其實把它當函數庫用就可以了。雖然還是對自己的安裝過程感到有點不安，不過至少能用了，剩下的東西可以慢慢研究。</p>
<img src ="http://www.cppblog.com/tx7do/aggbug/12598.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tx7do/" target="_blank">杨粼波</a> 2006-09-17 21:53 <a href="http://www.cppblog.com/tx7do/archive/2006/09/17/12598.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title> CxImage类使用入门</title><link>http://www.cppblog.com/tx7do/archive/2006/09/09/12201.html</link><dc:creator>杨粼波</dc:creator><author>杨粼波</author><pubDate>Sat, 09 Sep 2006 09:55:00 GMT</pubDate><guid>http://www.cppblog.com/tx7do/archive/2006/09/09/12201.html</guid><wfw:comment>http://www.cppblog.com/tx7do/comments/12201.html</wfw:comment><comments>http://www.cppblog.com/tx7do/archive/2006/09/09/12201.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/tx7do/comments/commentRss/12201.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tx7do/services/trackbacks/12201.html</trackback:ping><description><![CDATA[
		<p>关于这个类,可以看CodeProject上的文章:<a href="http://www.codeproject.com/bitmap/CXImage.asp"><font color="#006699">http://www.codeproject.com/bitmap/CXImage.asp </font></a></p>
		<p>CxImage是一个可以用于MFC的C++类，可以打开，保存，显示，转换各种格式的图像文件,比如BMP, JPEG, GIF, PNG, TIFF, MNG, ICO, PCX, TGA, WMF, WBMP, JBG, J2K 等格式的文件。可以实现BMP&lt;-&gt;JPG，PNG &lt;&gt;TIFF格式等等的转换。</p>
		<p>它的作者是: Davide Pizzolato ,主页: <a href="http://www.xdp.it/"><font color="#000000">http://www.xdp.it/</font></a></p>
		<p>--------------------------------</p>
		<p>2005.3.26 补记</p>
		<p>很久了没有接着写这个CxImage入门了,因为我自己很久没有搞图像处理了.</p>
		<p>但是,前面的只是开了个头,什么也没有写好,所以这里还是接着写一点我知道的东西吧.</p>
		<p>首先,到<a href="http://www.codeproject.com/bitmap/CXImage.asp"><font color="#006699">http://www.codeproject.com/bitmap/CXImage.asp</font></a> 下载它的源文件和Demo例子.</p>
		<p>注: 在Codeproject下载这个类,你得先注册一下,因为这个类可是含金量比较高的,下载量比较大的,当然你也会很高兴成为CodeProject的一名成员的,她不收你的费.</p>
		<p>由于很多人上codeproject的时候,老是上不去,所以,我推荐你去这个类的作者</p>
		<p>--Davide Pizzolato的主页去下载: <a href="http://www.xdp.it/"><font color="#000000">http://www.xdp.it/</font></a></p>
		<p>他的主页还有另外的源代码,有兴趣的也可以看看.</p>
		<p>当然你也可以Google或者Baidu一下,看看国内哪里有下载的.我随便搜了一个<a href="http://www.herozhan.com/soft/1112.htm"><font color="#006699">http://www.herozhan.com/soft/1112.htm</font></a></p>
		<p>然后解压缩你下载回来的源代码和Demo示例,你可以先看看作者写的那个例子,体验一下作者的本事.然后就开始编译CxImage的源文件.</p>
		<p>2005年3月28日补记</p>
		<p>下面是根据作者的源文件和<a href="http://www.codeproject.com/bitmap/CXImage.asp"><font color="#006699">作者写的文档</font></a>得出的内容:</p>
		<p>-----------------------------------------------</p>
		<p>- - - - - - - DISCONTINUED - - - - - - - <br />The author will not maintain this page any more, <br />neither replies to questions posted on the message board </p>
		<p>在作者的文档中,作者已经说明,将不再对CodeProject的这个文档进行维护,不再回复提出的问题,所以我建议到他的老巢去看看他有什么新消息,并且提问.</p>
		<p>1&gt;&gt;打开cximage599a_full\CxImgLib.dsw之后,看到下图类信息结构,图片来源<a href="http://www.codeproject.com/bitmap/CXImage.asp"><font color="#006699">http://www.codeproject.com/bitmap/CXImage.asp</font></a></p>
		<p>2&gt;&gt;还等着干什么啊,编译吧.</p>
		<p>待续&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;</p>
		<p>-----------------------------------------------------</p>
		<p>2005年3月27日补记</p>
		<p>CxImage库<br /><a href="http://www.codeproject.com/bitmap/cximage.asp"><font color="#000000">http://www.codeproject.com/bitmap/cximage.asp</font></a></p>
		<p>CxImage Sample<br /><a href="http://www.codeproject.com/listctrl/ThumbsViewer.asp"><font color="#000000">http://www.codeproject.com/listctrl/ThumbsViewer.asp</font></a></p>
		<p>GDI+ Sample<br /><a href="http://www.codeproject.com/vcpp/gdiplus/cgdiplusbitmap.asp"><font color="#000000">http://www.codeproject.com/vcpp/gdiplus/cgdiplusbitmap.asp</font></a></p>
<img src ="http://www.cppblog.com/tx7do/aggbug/12201.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tx7do/" target="_blank">杨粼波</a> 2006-09-09 17:55 <a href="http://www.cppblog.com/tx7do/archive/2006/09/09/12201.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>解决Windows 程序界面闪烁问题的一些经验 </title><link>http://www.cppblog.com/tx7do/archive/2006/08/24/11672.html</link><dc:creator>杨粼波</dc:creator><author>杨粼波</author><pubDate>Thu, 24 Aug 2006 15:45:00 GMT</pubDate><guid>http://www.cppblog.com/tx7do/archive/2006/08/24/11672.html</guid><wfw:comment>http://www.cppblog.com/tx7do/comments/11672.html</wfw:comment><comments>http://www.cppblog.com/tx7do/archive/2006/08/24/11672.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/tx7do/comments/commentRss/11672.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tx7do/services/trackbacks/11672.html</trackback:ping><description><![CDATA[文章来源：<a href="http://blog.joycode.com/yaodong/archive/2004/11/26/39764.aspx">http://blog.joycode.com/yaodong/archive/2004/11/26/39764.aspx</a><br /><br /><br /><p>一般的windows 复杂的界面需要使用多层窗口而且要用贴图来美化，所以不可避免在窗口移动或者改变大小的时候出现闪烁。</p><p>先来谈谈闪烁产生的原因</p><p>原因一：<br />如果熟悉显卡原理的话，调用GDI函数向屏幕输出的时候并不是立刻就显示在屏幕<br />上只是写到了显存里，而显卡每隔一段时间把显存的内容输出到屏幕上，这就是刷新周期。</p><p>一般显卡的刷新周期是 1/80秒左右，具体数字可以自己设置的。</p><p>这样问题就来了，一般画图都是先画背景色，然后再把内容画上去，如果这两次操作不在同一个<br />刷新周期内完成，那么给人的视觉感受就是，先看到只有背景色的图像，然后看到画上内容的图像，<br />这样就会感觉闪烁了。</p><p>解决方法：尽量快的输出图像，使输出在一个刷新周期内完成，如果输出内容很多比较慢，那么采用<br />内存缓冲的方法，先把要输出的内容在内存准备好，然后一次输出到显存。要知道一次API调用一般可以<br />在一个刷新周期内完成。</p><p>对于GDI，用创建内存DC的方法就可以了</p><p>原因二：</p><p>复杂的界面有多层窗口组成，当windows在窗口改变大小的时候是先重画父窗口，然后重画子窗口，子父<br />窗口重画的过程一般无法在一个刷新周期内完成，所以会呈现闪烁。</p><p>我们知道父窗口上被子窗口挡住的部分其实没必要重画的</p><p>解决方法：给窗口加个风格 WS_CLIPCHILDREN ,这样父窗口上被子窗口挡住的部分就不会重画了。</p><p>如果同级窗口之间有重叠，那么需要再加上 WS_CLIPSIBLINGS 风格</p><p>原因三：</p><p>有时候需要在窗口上使用一些控件，比如IE，当你的窗口改变大小的时候IE会闪烁，即使你有了WS_CLIPCHILDREN<br />也没用。原因在于窗口的类风格有CS_HREDRAW 或者 CS_VREDRAW，这两个风格表示窗口在宽度或者高度变化的时候<br />重画，但是这样就会引起IE闪烁</p><p>解决方法：注册窗口类的时候不要使用这两个风格，如果窗口需要在改变大小的时候重画，那么可以在WM_SIZE的时候<br />调用RedrawWindow。</p><p>原因四：</p><p>界面上窗口很多，而且改变大小时很多窗口都要移动和改变大小，如果使用MoveWindow或者SetWindowPos两个API来<br />改变窗口的大小和位置，由于他们是等待窗口重画完成后才返回，所以过程很慢，这样视觉效果就可能会闪烁。</p><p>解决方法：</p><p>使用以下API来处理窗口移动，BeginDeferWindowPos, DeferWindowPos，EndDeferWindowPos<br />先调用 BeginDeferWindowPos 设定需要移动的窗口的个数<br />使用DeferWindowPos，来移动窗口，这个API并不真的造成窗口移动<br />EndDeferWindowPos 一次性完成所有窗口的大小和位置的改变。</p><p>有个地方要特别注意，要仔细计算清楚要移动多少个窗口，BeginDeferWindowPos设定<br />的个数一定要和实际的个数一致，否则在Win9x下，如果实际移动的窗口数多于调用BeginDeferWindowPos<br />时设定的个数，可能会造成系统崩溃。在Windows NT系列下不会有这样的问题。</p><img src ="http://www.cppblog.com/tx7do/aggbug/11672.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tx7do/" target="_blank">杨粼波</a> 2006-08-24 23:45 <a href="http://www.cppblog.com/tx7do/archive/2006/08/24/11672.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>PNG的增强格式：MNG[转载]</title><link>http://www.cppblog.com/tx7do/archive/2006/07/20/10243.html</link><dc:creator>杨粼波</dc:creator><author>杨粼波</author><pubDate>Thu, 20 Jul 2006 01:54:00 GMT</pubDate><guid>http://www.cppblog.com/tx7do/archive/2006/07/20/10243.html</guid><wfw:comment>http://www.cppblog.com/tx7do/comments/10243.html</wfw:comment><comments>http://www.cppblog.com/tx7do/archive/2006/07/20/10243.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/tx7do/comments/commentRss/10243.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tx7do/services/trackbacks/10243.html</trackback:ping><description><![CDATA[Multiple-image Network Graphics (MNG)<br />这种格式是从PNG格式发展来的一种新格式。由于PNG还不支持动画，所以作为一种解决方案，MNG格式的制定就成为理所当然的事。 
<p></p><p>MNG图形库站点： <br />http://www.libmng.com<br />http://www.libmng.org</p><p>MNG规范分几种等级：<br />FULL 全功能型 (支持PNG和JPG--称作JNG--作为图片，及一些特殊功能)<br />LC 低复杂度型 (支持PNG作为图片，及部份特殊功能)<br />VLC 最低复杂度(支持PNG作为图片)</p><p>目前处理MNG的图形软件所支持的规范可能不一样。但VLC全都支持。</p><p>MNG规范1.0： http://www.libmng.com/pub/mng/spec/ <br />目前最新的是1.1。</p><p>MNG可以包含静态图片，动画等多种格式，甚至是3维的votex。<br />对于静态图片，支持基于PNG、基于JPG（称为JNG）格式，支持Delta-PNG以压结缩文件大小，可以定义图片播放时间间隔、同步、以及循环（可以多重循环）。<br />包含的图片大小可以不一致，每个图片都可以有自已的剪切范围；可以由多个图片组成一帧画面等等...</p><p>实在是一个理想的2D动画精灵格式。<br />目前GDI+不支持此格式，需要用libmng来读写MNG格式。<br /></p><img src ="http://www.cppblog.com/tx7do/aggbug/10243.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tx7do/" target="_blank">杨粼波</a> 2006-07-20 09:54 <a href="http://www.cppblog.com/tx7do/archive/2006/07/20/10243.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用C++和DirectX开发游戏GUI(五)</title><link>http://www.cppblog.com/tx7do/archive/2006/07/07/9526.html</link><dc:creator>杨粼波</dc:creator><author>杨粼波</author><pubDate>Fri, 07 Jul 2006 04:01:00 GMT</pubDate><guid>http://www.cppblog.com/tx7do/archive/2006/07/07/9526.html</guid><wfw:comment>http://www.cppblog.com/tx7do/comments/9526.html</wfw:comment><comments>http://www.cppblog.com/tx7do/archive/2006/07/07/9526.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/tx7do/comments/commentRss/9526.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tx7do/services/trackbacks/9526.html</trackback:ping><description><![CDATA[// represents a column in our listbox <br />class gui_listbox_column <br />{ <br />public: <br />gui_listbox_column() { } <br />virtual ~gui_listbox_column() { } <br /><br />virtual void draw(uti_rectangle &amp;where); <br /><br />void setname(const char *name) { m_name = name; } <br />uti_string getname(void) { return(m_name); } <br /><br />int getwidth(void) { return(m_width); } <br />void setwidth(int w) { m_width = w; } <br /><br />private: <br />uti_string m_name; <br />int m_width; <br />}; <br /><br />// an item in our listbox <br />class gui_listbox_item <br />{ <br />public: <br />gui_listbox_item() { m_isselected = 0; m_indent = 0; } <br />virtual ~gui_listbox_item() { } <br /><br />virtual draw(int colnum, uti_rectangle &amp;where); <br /><br />void clearallcolumns(void); // boring <br />void setindent(int i) { m_indent = i; } <br />int getindent(void) { return(m_indent); } <br /><br />void settext(int colnum, const char *text); // boring <br />uti_string gettext(int colnum = 0); // boring <br /><br />void setitemdata(unsigned long itemdata) { m_itemdata = itemdata; } <br />unsigned long getitemdata(void) { return(m_itemdata); } <br /><br />void setselected(int s = 1) { m_isselected = s; } <br />int getselected(void) { return(m_isselected); } <br /><br />private: <br />int m_isselected; <br />int m_indent; // # of pixels to indent this item <br />unsigned long m_itemdata; <br />uti_pointerarray m_coltext; <br />}; <br /><br />// the listbox itself <br />class gui_fancylistbox : public gui_window <br />{ <br />public: <br />gui_fancylistbox() { m_multiselect = 0; } <br />virtual ~gui_fancylistbox() { clear(); } <br /><br />int getselected(int iter = 0); <br /><br />virtual int wm_command(gui_window *win, int cmd, int param); <br />virtual int wm_paint(coord x, coord y); <br />virtual int wm_lbuttondown(coord x, coord y); <br /><br />gui_scrollbar_horz &amp;gethscroll(void) { return(m_hscroll); } <br />gui_scrollbar_vert &amp;getvscroll(void) { return(m_vscroll); } <br /><br />virtual int wm_sizechanged(void); // the window's size has changed somehow <br /><br />gui_listbox_item *getitemat(int index); // boring <br />gui_listbox_item *additem(const char *text); // boring <br />int delitem(int index); // boring <br />int delallitems(void); // boring <br />gui_listbox_column *getcolumn(int index); // boring <br />int addcolumn(const char *name, int width); // boring <br />gui_listbox_column *getcolumnat(int index); // boring <br />int delcolumn(int index); // boring <br />int delallcolumns(void); // boring <br /><br />int clear(void); // delete columns &amp; items <br /><br />int getnumitems(void); <br />int getnumcols(void); <br /><br />void deselectall(void); <br />void selectitem(int item); <br />void selecttoggleitem(int item); <br /><br />void deselitem(int item); <br /><br />private: <br />int m_numdispobjsy; <br />int m_vertgutterwidth; // # of pixels between items vertically <br /><br />gui_scrollbar_horz m_hscroll; <br />gui_scrollbar_vert m_vscroll; <br /><br />bool m_multiselect; // is this multi-selectable? <br />uti_pointerarray m_items; // array of gui_listbox_items <br />uti_pointerarray m_columns; // array of gui_listbox_columns <br />}; <br /><br />  列表框是到现在为止你做的最难的控件吧?但这仅仅是因为它是最通用的.一个能够处理多列、缩进、多重选择列表框控件将在实践中证明他对你的游戏是不可或缺的.停下来并想想在大多数游戏里用到列表框的地方,你就会很快发现这一点. <br /><br />  我把我的列表框控件分成两部分:一个多列的"报表风格"的列表控件和一个图标列表控件,它创建一个类似于当你在windows"我的电脑"里选择大图标察看方式的显示. <br /><br />  图表列表控件比较容易建立.它使用了一列静态图标(在一次代码重用),所有的具有相同的大小.我使用图标的宽度除列表框的宽,这让我知道有几列可用.(如果证明我的列表框比大图表小,我假设我只有一列,并让绘制系统剪裁图标以使他们不会超出我的绘制区域).一旦我有了列数,我通过图标的总数除以它计算出我所需要的行数.这样我就知道我该怎样设定要包括的滚动条. <br /><br />  注意当控件改变大小时必须重新计算这些值.为此我设定了一个wm_sizechanged()消息,calcall()将会在窗口绘制区域被改变的时候调用它. <br /><br />  报表风格列表控件要复杂一些.我先写了两个辅助类,gui_listbox_column和gui_listbox_item,它们包含了所有的关于列表中给定物件和列的信息. <br /><br />  gui_listbox_column是两者中较简单的.主要的列表框类有一个成员变量身份的gui_listbox_column的动态数组,这代表了目前列表框中的列.gui_listbox_column包含了在列表框中所需要的列的所有信息,包括列的名字,列的对齐,显示或隐藏,大小等等. <br /><br />  主要的列表框类也有一个gui_listbox_item的动态数.gui_listbox_item类包含了与我们的报表风格列表框中特定行(或物件)相关的所有信息.目前这个类最重要的数据成员是代表每列数据的字串数组.我也让每个物件通过m_itemdata成员存储一个附加的32位数据.这个技术类似于windows允许你通过位你的列表物件调用SetItemData()和GetItemData()来存储32位数据.这个细节很重要,因为它允许列表框的用户为每个物件存储一个指针-通常一个与该物件有关的特定类,以使它以后可用. <br /><br />  怎么绘制列和物件呢?我倾向于在要绘制的列表框中在每个单独的物件/列上有个绝对的控件.到最后,我决定让列表控件通过不断调用两个虚函数,gui_listbox_item::draw()和gui_listbox_column::draw()来绘制他的物件和列.每个函数使用一个代表列或者物件在屏幕上位置的矩形.默认的对这些draw()函数的开发仅仅分划出与矩形中特定列和子物件相关的文本;然而,我先在可以简单的为需要独特外观的物件或列派生和重载draw().这种技术目前工作的很好,但是我还不足以宣称这是最好的方法. <br /><br />  然而,绘制物件比行需要更多的工作.物件需要用高光绘制,这决定于他们是否被选择.这并不很难,但一定不能忘记. <br /><br />  然后就是滚动条的问题了.我的列表框包含两个成员,m_horzscrollbar和m_vertscrollbar,他们都是GUI滚动条.当列表框的大小被改变时(wm_sizechanged()),他会看看数据的宽度和高度并决定是否显示滚动条. <br /><br />总结 <br /><br />  真是绕了一大圈子,但是幸运的是你对为GUI创建控件有了个大致的想法.这里我想强调的是"风格就是乐趣".在做你的GUI时不要害怕创新-做做你曾经梦想过的东西,和使你的游戏最酷的东西.如果你的游戏很依赖你的GUI的效能这一点尤其重要,比如你在作即时战略游戏. <br /><br />  还要记住当创建控件的时候,你需要为你的游戏的其他部分考虑平衡问题-细节表现力和开发时间是成正比的.尽量给你的玩家最易于上手的GUI,但同时不要花时间做50种不同的控件.你要在功能、好事、复杂性、坏事中做出平衡. <br /><br />  控件就到这吧.下一章也是最后一章中我们会看看资源编辑器,序列化窗口和创建对话框.祝愉快! <br /><img src ="http://www.cppblog.com/tx7do/aggbug/9526.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tx7do/" target="_blank">杨粼波</a> 2006-07-07 12:01 <a href="http://www.cppblog.com/tx7do/archive/2006/07/07/9526.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用C++和DirectX开发游戏GUI(六)</title><link>http://www.cppblog.com/tx7do/archive/2006/07/07/9527.html</link><dc:creator>杨粼波</dc:creator><author>杨粼波</author><pubDate>Fri, 07 Jul 2006 04:01:00 GMT</pubDate><guid>http://www.cppblog.com/tx7do/archive/2006/07/07/9527.html</guid><wfw:comment>http://www.cppblog.com/tx7do/comments/9527.html</wfw:comment><comments>http://www.cppblog.com/tx7do/archive/2006/07/07/9527.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/tx7do/comments/commentRss/9527.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tx7do/services/trackbacks/9527.html</trackback:ping><description><![CDATA[作者:Mason McCuskey 翻译:Rick Cart <br />原文：<a href="http://asp3.6to23.com/rickcart/program/devGUIwithDX4.html" target="_blank"><font color="#002c99">http://asp3.6to23.com/rickcart/program/devGUIwithDX4.html</font></a> ，欢迎访问！ <br /><br />  欢迎回到"使用C++和DX开发GUI"的第四部分.接着我们的主题(我是如何为我未来的游戏,Quaternion,开发GUI的),本文将关注所有的有关游戏GUI的细节问题. <br /><br />保存窗口 <br /><br />  窗口序列化(存储和载入窗口)对你的工程而言或许不重要.如果你的游戏GUI很简单,你可以全靠程序在游戏中实现窗口.但如果你的GUI相对复杂,或者随着开发的过程经常会改变,那么你会想写程序以把一个窗口(和所有它的子窗口)存到文件里,然后再装载它.对初学者,窗口序列化代码允许你改变游戏的GUI而不用重新编译,而且它对于多人协调工作也是有益的. <br /><br />  我的计划是从主对话窗口开始,然后遍历它的所有子窗口,把每一个存到磁盘上.如果我用c语言写程序的话,我告诉自己的第一句话是"好的,如果我必须保存这些窗口,我需要每个窗口有一个字节来告诉我它是什么样的窗口,以使我能正确的载入它.比如1是按钮,2是列表框,3是图表,等等." <br /><br />  这种问题是C++的RTTI(运行期类型识别)关心的.RTTI提供了两个东东,type_info类和typeid()函数,两者允许我查询一个对象的所属类名称,例如gui_window,gui_button,等等.我没有使用枚举和ID,而是简单地为每个将要保存的窗口调用typid(),并"写下"窗口的类名称. <br /><br />  我注意到使用RTTI的对象识别函数来帮助保存窗口的两个小缺点.第一,RTTI ID是字符串而不是整型,这意味着他们将占用磁盘上的更多空间(按照pascal方式存储字串将是前4个字节代表字串的长度,接下来是字串本身的数据).第二,如果你改变一个窗口类的名字,你会破坏已经存好的所有窗口文件. <br /><br />  由于这些原因,你可能不会这样使用RTTI.毕竟,并不是有技术就一定要使用它.然而,我发现RTTI对我的代码而言却是救生员.要获得更多的关于RTTI和这两个函数的信息,请在你的联机帮助文档里查找. <br /><br />  另外,如果你决定在VC++里使用RTTI,确保你在工程属性的C/C++栏和C++语言选项中打开它. <br /><br />载入窗口 <br /><br />  载入窗口比存储他们要难一点儿,这主要是因为你必须新建(new)每个窗口,载入,并当它不再需要的时候删除. <br /><br />  这个函数是第归的,用PDL表达的话如下所示: <br /><br />void gui_window:load(int filehandle) <br />{ <br />// read window properties (colorsets, etc.) <br />// read total number of children for this window <br />// for each child? // read window ID from disk <br />// new a gui_window derivative based on that ID <br />// tell the newly created window to load itself (recurse!) <br />// next child <br />} <br /><br />  换句话说,你得像你所想得那样从磁盘载入窗口.第一,要处理基类窗口:读取他的属性.然后,读取基类窗口的所有子窗口的数目.对每个子窗口,读取ID字节,根据ID新建一个窗口,然后让新窗口载入自己(低轨到它).当所有的字窗口载入完毕时,就结束了. <br /><br />  当然,你的文件结构一致也非常重要.确保你的存储代码以你想要载入的顺序存储信息. <br /><br />资源编辑器 <br /><br />  要想真正使你的GUI大放光彩,你必须有一个资源编辑器.当然你不需要做个象开发环境提供的资源编辑器那样的华丽和强大,但是你起码得有个基本的程序来完成加入,编辑,删除,排列,免除你为对话框的每个控件计算虚拟坐标位置的麻烦事儿. <br /><br />  写一个功能完善的,WYSIWYG(所见即所得)的资源编辑器超出了本文的范围,但是我能给你一些小提示来帮助你完成这个壮举: <br /><br />  1.共享你的代码.特别地,让你的资源编辑器和你的游戏一起分享同样的渲染代码.这样,你就得到了所见即所得支持,并且免除了开发两套GUI代码的麻烦.我向你保证,调整你的DX代码以使它渲染一个GDI表面而不是一个双缓冲系统将比重新开发一整套新的绘制代码简单.记住过一段时间之后你的GUI系统可能会改变,你不会想要经常在两个不同的地方改写代码. <br /><br />  2.不要试图模仿开发环境的外表和感觉.换句话说,不要费时间模仿开发环境的细节(例如,属性页和预览窗口).如果你的编辑器相对而言比较难看的话,不要沮丧;的确,小组的效率是和他使用的工具的效能成直接正比关系的,但是同时,小组之外的人是不可能使用你的资源编辑器的,你也不会用它去开发一个完整的GUI程序;你不过只是做几个对话框而已.你不需要环境文本帮助(context sensitive help).你不需要环境文本菜单(context menus),除非你觉得这会简化一个特定的繁复的操作.如果你的资源编辑器不那么漂亮也无所谓,只要它能完成工作就行了. <br /><br />  3.强调数据完整而不是速度.资源编辑器是个数据整合者,而不是个高性能程序,没有什么比你花了一个小时来设计的东西由于程序错误而丢失而更让人恼火的事儿了.当写你的GUI的时候,保存数据是你的最高目标.花些时间来做自动存储,undo缓冲等等,别把优化看得那么重要. <br /><br />生成子类(subclass) <br /><br />  那些熟悉Win32处理窗口的人们可能已经知道"subclass"这个术语的含义了.如果不知道的话,当你"subclass"一个窗口的时候,你就"derive(衍生)"一个新的窗口类型,然后把新的窗口类型嵌入到旧窗口要使用的地方. <br /><br />  让我做更详细地解释.比如我们需要一个超级列表框.我们已经有个普通的列表框类,但是因为某种原因它不适合;我们的游戏需要超级列表框.所以我们从普通的列表框类中衍生出一个超级列表框类.就是这样. <br /><br />  但是我们如何在我们的游戏对话框中放置这个超级列表框呢?由于超级列表框是为我们的程序特制的,我们不能为我们的资源编辑器增加函数来支持它.但同时,我们怎样通知GUI系统为这个特殊的实例(我们的游戏),让所有的列表框都是超级列表框呢?这就是生成子类(subclass)要做的事情.这不是个精确的技术定义,但是表达了足够的信息. <br /><br />  这里我要讲述的方法称作"载入过程生成子类(subclassing at load time)".要理解它,让我们从上一节所述的基本的载入代码开始.我们有个载入函数,它第归地完成创建,载入,增加窗口.这里我们用PDL表述如下: <br /><br />// read total number of children for this window <br />// for each child... <br />// read window ID from disk <br />// new a gui_window derivative based on that ID <br />// ... <br />// next child <br /><br />  要完成生成子类,我让我的窗口载入函数"给程序一个创建这一类型窗口的机会",像这样: <br /><br />// read total number of children for this window <br />// for each child... <br />// read window ID from disk <br />// give application a chance to create a window of this type <br />// if the application didn't create a window, <br />// then new a gui_window derivative based on the ID <br />// else, use the application's created window <br />// ... <br />// next child <br /><br />  我通过一个函数指针给程序这个机会.如果程序需要为一个窗口生成子类,就在函数指针里填上自己函数的地址.当窗口载入的过程中,调用这个函数,传入想要创建的窗口ID.如果程序想要根据ID为一个窗口生成子类,新建一个适当的对象并把新指针返回给窗口.如果程序不需要这个ID,则返回NULL,窗口函数根据返回值创建恰当的默认对象.这种方法允许程序"预先过滤"引入的窗口ID信息,并为特定的窗口类型重载默认函数.太完美了! <br /><br />(译者注:这一段我翻译的实在不能说是完美,相反是简直不知所云,这里把原文贴出来,请您自己斟酌吧，天天上网也觉得还是看原文来的直接，翻译的话确实有点把握不好。) <br />Specifically, I give the application this chance by way of a function pointer. If the application needs to subclass a window, it fills in the function pointer with the address of its own function. When the windows are loading, they call this application function, passing in the ID of the window they want to create. If the application wants to subclass a window from this ID, it news up the appropriate object and returns the new pointer back to the window. If the app doesn't want to do anything special for this ID, it returns NULL, and the window function senses this and news up the appropriate default object. This method allows the app to "pre-filter" the incoming window ID bytes, and to override the default behavior for certain window types. Perfect! <br /><br />  用这种方法在创建自定控件的时候给了我很大的自由.我为我的资源编辑器增加代码以使我能为每个存储的窗口改变ID.然后,当我需要自定控间的时候,我只需用资源编辑器改变保存这个窗口ID的字节.在磁盘上保存的是ID和所有为自定控件的其他基类属性. <br /><br />  很快吧?还有其他的方法来做同样的事,这是在模仿STL需要创建对象时使用的方法.STL使用特定的"allocator(分配符)"类,这有点儿像"类厂"(factories),他们按照客户告诉他们的需要来创建类.你可以使用这种方法来创建窗口. <br /><br />  这种方法的工作原理如下:创建一个类并把它叫做"gui_window_allocator".写一个虚拟函数,叫做CreateWindowOfType,它接受一个给定的窗口ID并传出一个新的指针给窗口.现在你就得到了一个简单的分配符类,你的窗口载入代码将使用它来新建需要的窗口. <br /><br /><br /><br />现在,当你的程序需要为窗口重载"new"操作符,衍生一个新的、程序相关的gui_window_allocator类,并告诉你的窗口载入代码来使用这个分配符,而不是默认的那个.这种方法就象提供一个函数指针,只用了一点儿C++. <br /><br />加速GUI渲染 <br /><br />  还有一个能帮助你加速GUI渲染的小提示. <br /><br />  关键的概念是,就象其他绘制函数的优化一样,不要画你不需要的东西.默认方式,GUI花很多时间绘制没有变化的部分.然而,你能通过告诉GUI绘制改变的窗口(windows that are dirty)作些优化.当窗口的外观需要改变的时候,窗口设定他们的dirty标志,在绘制的时候清除它们的dirty标志. <br /><br />  由于我们的GUI控件可能是透明的,当一个控件被标记为dirty,它的父窗口必须也被标记为dirty.这样,当它被绘制的时候,背景没有改变,因为父窗口也刚刚被重绘. <br /><br />总结:相逢在XGDC! <br /><br />  我准备在即将来临的Armageddon XGDC(eXtreme Game Developer's Conference)上讲述GUI.我将尽力让我的发言有用,现在你已经看了所有的文章,如果你有什么需要扩展的问题,或是我有什么遗漏,请给我写信让我了解. <br /><br />祝各位做游戏愉快! <br /><br />======================================================================================================================= <br /><br />Mason McCuskey 是Spin Studio(一个正在制作名为Quaternion的伟大游戏的制作小组)的领导者.他盼望着你的建议和评论。 <br />他的email是<a href="mailto:mason@spin-studios.com"><font color="#002c99">mason@spin-studios.com</font></a>. <br /><img src ="http://www.cppblog.com/tx7do/aggbug/9527.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tx7do/" target="_blank">杨粼波</a> 2006-07-07 12:01 <a href="http://www.cppblog.com/tx7do/archive/2006/07/07/9527.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用C++和DirectX开发游戏GUI(三)</title><link>http://www.cppblog.com/tx7do/archive/2006/07/07/9524.html</link><dc:creator>杨粼波</dc:creator><author>杨粼波</author><pubDate>Fri, 07 Jul 2006 04:00:00 GMT</pubDate><guid>http://www.cppblog.com/tx7do/archive/2006/07/07/9524.html</guid><wfw:comment>http://www.cppblog.com/tx7do/comments/9524.html</wfw:comment><comments>http://www.cppblog.com/tx7do/archive/2006/07/07/9524.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/tx7do/comments/commentRss/9524.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tx7do/services/trackbacks/9524.html</trackback:ping><description><![CDATA[现在,进入有趣的坐标系统。 <br /><br />坐标系统 <br /><br />/**************************************************************************** <br />virtual coordinate system to graphics card resolution converters <br />****************************************************************************/ <br />const double GUI_SCALEX = 10000.0; <br />const double GUI_SCALEY = 10000.0; <br /><br />int gui_window::virtxtopixels(int virtx) <br />{ <br />int width = (m_parent) ? m_parent-&gt;getpos().getwidth() : getscreendims().getwidth(); <br />return((int)((double)virtx*(double)width/GUI_SCALEX)); <br />} <br /><br />int gui_window::virtytopixels(int virty) <br />{ <br />int height = (m_parent) ? m_parent-&gt;getpos().getheight() : getscreendims().getheight(); <br />return((int)((double)virty*(double)height/GUI_SCALEY)); <br />} <br /><br />/**************************************************************************** <br />findchildatcoord: returns the top-most child window at coord (x,y); <br />recursive. <br />****************************************************************************/ <br />gui_window *gui_window::findchildatcoord(coord x, coord y, int flags) <br />{ <br />for (int q = m_subwins.getsize()-1; q &gt;= 0; q--) <br />{ <br />gui_window *ww = (gui_window *)m_subwins.getat(q); <br />if (ww) <br />{ <br />gui_window *found = ww-&gt;findchildatcoord(x-m_position.getx1(), y-m_position.gety1(), flags); <br />if (found) return(found); <br />} <br />} <br /><br />// check to see if this window itself is at the coord - this breaks the recursion <br />if (!getinvisible() &amp;&amp; m_position.ispointin(x,y)) <br />return(this); <br />return(NULL); <br />} <br /><br />  我的GUI最大的优势是独立的解决方案,我称之为"弹性对话框".基本上,我希望我的窗体和对话框根据它们运行系统的屏幕设置决定它们的大小.对系统的更高的要求是,我希望窗体,控件等在*0 x 480的屏幕上扩张或缩小.同时我也希望不管它们父窗体的大小,它们都可以适合. <br /><br />  这就意味着我需要实现一个像微软窗体一样的虚拟坐标系统.我以一个任意的数据定义我的虚拟坐标系统--或者说,"从现在起,我将不管窗体的实际尺寸假设每一个窗体都是10000 x 10000个单元",然后我的GUI将在这套坐标下工作.对于桌面,坐标将对应显示器的物理尺寸. <br /><br />  我通过以下四个函数实现我的想法:virtxtopixels(),virtytopixels(), pixelstovirtx(), 和pixelstovirty(). (注意:在代码中之列出了两个;我估计你已理解这个想法了).这些函数负责把虚拟的10000 x 10000单元坐标要么转换为父窗体的真实尺寸要么转换为显示器的物理坐标.显然,显示窗体的函数将倚重它们. <br /><br />  函数screentoclient()负责取得屏幕的绝对位置并将它转换为相对的虚拟坐标.相对的坐标从窗体的左上角开始,这和3D空间的想法是相同的.相对坐标对对话框是必不可少的. <br /><br />  在GUI系统中所有的坐标都是相对于其他的某物的．唯一的一个例外就是桌面窗体，它的坐标是绝对的．相对的方法可以保证当父窗体移动时它的子窗体也跟着移动，而且可以保证当用户拖动对话框到不同位置时其结构是一致的．同时，因为我们整个虚拟坐标系统都是相对的，当用户拉伸或缩小一个对话框时其中的所有控件都会随之变化，自动的尽量适合新的尺寸．对我们这些曾在win32中试过相同特性的人来说，这是个令人惊异的特点． <br /><br />  最后，函数findchildatcoord()取得(虚拟)坐标确定哪个(如果有)子窗体在当前坐标--非常有用,比如,当鼠标单击时,我们需要知道哪个窗体处理鼠标单击事件.这个函数通过反向搜寻子窗体列阵(记住,最前的窗体在列真的最后面),看那个点在哪个窗体的矩形中.标志参数提供了更多的条件去判断点击是否发生;比如,当我们开始实现控制时,我们会意识到不让标示和光标控件响应单击是有用的,取而带之应给在它们下面的窗体一个机会响应--如果一个标示放在一个按钮上面,即使用户单击标示仍表示单击按钮.标志参数控制着这些特例. <br /><br />  现在,我们已经有了坐标,我们可以开始绘制我们的窗体了? <br /><br />绘制窗体 <br /><br />  递归是一柄双刃剑.它使得绘制窗体的代码很容易跟踪，但是它也会造成重复绘制像素，而这将严重的影响性能。(这就是说，例如你有一个存放50个相同大小相同位置的窗体，程序会一直跑完50个循环，每个像素都会被走上50遍)。这是个臭名昭著的问题。肯定有裁剪算法针对这种情况，实际上，这是个我需要花些时间的领域。在我自己的程序-Quaternion's GUI 在非游戏屏幕过程(列标题和关闭等等)中一般是激活状态的，要放在对GUI而言最精确的位置是很蠢的想法，因为根本就没有任何其他的动作在进行。 <br /><br />  但是，我在对它进行修补。现在我试图在我的绘制方法中利用DirectDrawClipper对象。到现在为止，初始的代码看起来很有希望。下面是它的工作方式：桌面窗口“清除”裁剪对象。然后每个窗口绘制它的子窗口，先画顶端的，在画底端的。当每个窗口绘制完毕后，把它的屏幕矩形加入到裁剪器，有效地从它之下的窗口中“排除”这个区域(这假设所有的窗口都是100%不透光的).这有助于确保起码每个像素将被只绘制一次；当然，程序还是被所有的GUI渲染所需要的计算和调用搞的乱糟糟的，(并且裁剪器可能已经满负载工作了),但是起码程序不会绘制多余的像素.裁剪器对象运行的快慢与否使得这是否值得还不明了。 <br /><br />  我也在尝试其他的几个主意-也许利用3D显卡的内建Z缓冲,或者某种复杂的矩形创建器(dirty rectangle setup).如果你有什么意见，请告诉我;或者自己尝试并告诉我你的发现。 <br /><br />  我剪掉了大量的窗体绘制代码，因为这些代码是这对我的情况的(它调用了我自定的精灵类).一旦你知晓你要绘制窗体的确切的屏幕维数(screen dimensions)时,实际的绘制代码就能够直接被利用。基本上，我的绘制代码用了9个精灵-角落4个，边缘4个，背景1个-并用这些精灵绘制窗体. <br /><br />  色彩集需要一点儿解释.我决定每个窗口有两套独特的色彩集;一套当窗口激活时使用,一套不激活时使用.在绘制代码开始之前，调用getappropriatecolorset(),这个函数根据窗口的激活状态返回正确的色彩集.具有针对激活和非激活状态的不同色彩的窗口是GUI设计的基本规则;它也比较容易使用. <br /><br />  现在我们的窗口已经画完了，开始看看消息吧。 <br /><br />窗口消息 <br /><br />  这一节是执行GUI的核心。窗口消息是当用户执行特定操作(点击鼠标，移动鼠标，击键等等)时发送给窗口的事件.某些消息(例如WM_KEYDOWN)是发给激活窗口的，一些(WM_MOUSEMOVE)是发给鼠标移动其上的窗口,还有一些(WM_UPDATE)总是发给桌面的. <br /><br />  微软的Windows有个消息队列.我的GUI则没有-当calcall()计算出需要给窗口送消息时,它在此停下并且发送消息-它为窗口调用适当的WM_XXXX()虚函数.我发现这种方法对于简单的GUI是合适的.除非你有很好的理由，不要使用一个太复杂的消息队列，在其中存储和使用线程获取和发送消息.对大多说的游戏GUI而言，它并不值得. <br /><br />  此外，注意WM_XXXX()都是虚函数.这将使C++的多态性为我们服务.需要改变某些形式的窗口(或者控件,比如按钮),处理鼠标左键刚刚被按下的事件？很简单,从基类派生出一个类并重载它的wm_lbuttondown()方法.系统会在恰当的时候自动调用派生类的方法;这体现了C++的力量. <br /><br />  就我自己的意愿，我不能太深入calcall()的细节,这个函数得到所有的输入设备并发出消息.它做很多事,并有很多对我的GUI而言特定的行为.例如,你或许想让你的GUI像X-Window一样运行,在鼠标活动范围之内的窗口总是处于激活状态的窗口.或者,你想要使得激活窗口成为系统模态窗口(指不可能发生其他的事直到用户关闭它),就像许多基于苹果平台(Mac)的程序那样.你会想要在窗口内的任何位置点击来关闭窗口,而不是仅仅在标题栏,像winamp那样.calcall()的执行结果根据你想要GUI完成什么样的功能而会有很大的不同. <br /><br />  我会给你一个提示,虽然-calcall()函数不是没有状态的,实际上,你的calcall()函数可能会变成一个很复杂的状态机(state machine).关于这一点的例子是拖放物体.为了恰当的计算普通的"鼠标键释放"事件和相似的但完全不同的"用户在拖动的物体刚刚放下"事件之间的不同,calcall()必须有一个状态参数.如果你对有限状态机已经生疏了,那么在你执行calcall()之前复习复习将会使你不那么头痛. <br /><br />  在窗口头文件中包括的wm_xxxx()函数是我感觉代表了一个GUI要计算和发送的信息的最小集合.你的需要可能会不同,你也不必拘泥于微软视窗的消息集合;如果自定的消息对你很合适,那么就自己做一个. <br /><br />窗口消息 <br /><br />  在文章的第一部分我提到了一个叫做CApplication::RenderGUI()的函数,它是在计算之后绘制我们的GUI的主函数: <br /><br />void CApplication::RenderGUI(void) <br />{ <br />// get position and button status of mouse cursor <br />// calculate mouse cursor's effects on windows / send messages <br />// render all windows <br />// render mouse <br />// flip to screen <br />} <br /><br />  最后,让我们开始加入一些PDL(页面描述语言). <br /><br />void CApplication::RenderGUI(void) <br />{ <br />// get position and button status of mouse cursor <br />m_mouse.Refresh(); <br /><br />// calculate mouse cursor's effects on windows / send messages <br />GetDesktop()-&gt;calcall(); <br /><br />// render all windows <br />GetDesktop()-&gt;renderall(); <br /><br />// render mouse <br />m_mouse.Render(); <br /><br />// flip to screen <br />GetBackBuffer()-&gt;Flip(); <br />} <br /><br />查看这些代码将会使你看到程序是如何开始在一起工作的. <br /><br />在下一章,第三部分中,我们会处理对话框控件.按钮,文本框和进度条. <br /><img src ="http://www.cppblog.com/tx7do/aggbug/9524.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tx7do/" target="_blank">杨粼波</a> 2006-07-07 12:00 <a href="http://www.cppblog.com/tx7do/archive/2006/07/07/9524.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用C++和Directx开发游戏GUI(四)</title><link>http://www.cppblog.com/tx7do/archive/2006/07/07/9525.html</link><dc:creator>杨粼波</dc:creator><author>杨粼波</author><pubDate>Fri, 07 Jul 2006 04:00:00 GMT</pubDate><guid>http://www.cppblog.com/tx7do/archive/2006/07/07/9525.html</guid><wfw:comment>http://www.cppblog.com/tx7do/comments/9525.html</wfw:comment><comments>http://www.cppblog.com/tx7do/archive/2006/07/07/9525.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/tx7do/comments/commentRss/9525.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tx7do/services/trackbacks/9525.html</trackback:ping><description><![CDATA[原文：<a href="http://asp3.6to23.com/rickcart/program/devGUIwithDX3.html" target="_blank"><font color="#002c99">http://asp3.6to23.com/rickcart/program/devGUIwithDX3.html</font></a>，请大家访问。 <br /><br />  欢迎回到"使用C++和DX开发GUI"的第三部分。接着我们的主题(描述我如何为我未来的游戏构建GUI),本文将探讨建造GUI所需的一些通用控件.我们将详细描述几种不同的控件形式,包括按钮,列表框,文本框等等. <br /><br />  这一节并不像其他章节那样有很多的代码--这主要是因为我们程序员对于GUI的外观是很挑剔的.我们喜欢把我们的按钮,文本框和GUI做的看起来独一无二,并且符合我们自己的审美标准.这样的结果是,每个人的控件代码都很不同,而且不会想要我的特殊的绘制代码.此外,写绘制GUI元素的代码是很有趣的,事实上,以我来看,这是在写GUI过程中最有趣的部分了.现在继续. <br /><br />  一个很重要的问题是,在我们开始之前-把你的gui_window析构函数做成虚函数.在第二部分里我没有提到这一点,因为我们没有从gui_window中派生出任何子类,但是现在我提出这一点-把你的gui_window和所有它的派生类的析构函数做成虚函数是很明智的做法,因为这将确保没有内存泄漏--由于派生的析构函数没有被调用.小心C++的陷阱. <br /><br />  说完这点之后,让我们首先判断我们需要什么样的GUI控件. <br /><br />我们需要的GUI控件 <br /><br />  我不想花太多的时间来为我的GUI开发控件;我只会专注于最简单的控件集.所以,我先列出我认为是最小控件集的控件: <br /><br />  1.静态文本,图标和组合框(最重要).这些空间将对话框中的其他控件标志或分组.静态控件很重要;我们可能不需要帧控件,但它非常简单,并且在某些情况下能够使对话框易于导航,所以我会包括它.图标控件也很简单,但是应该能够表现动画-为我们的对话框和菜单提供很酷的背景动画(神偷:黑暗计划). <br /><br />  2.按钮和选择框(最重要).特殊形式的按钮不是必需的,然而大多数的游戏不能没有基本的按钮和选择框. <br /><br />  3.列表框(重要).我发现列表框,特别是多列列表控件,在创建游戏GUI时是不可或缺的.他们的应用无所不在.你需要一个智能的,重量级的列表控件,和windows的列表控件一样好或者更为出色.对我而言,列表控件是最难开发的控件了. <br /><br />  4.滑动条和滚动条(重要).最常见于音量控制.坏消息是我们可能需要水平和垂直滚动条,好消息是他们很相似所以开发很简单. <br /><br />  5.文本框(最重要).你必须能够键入你的mega-3133t,super-kewl玩家标志,对吧? <br /><br />  6.进度条-对显示生命值是必需的,"我快要装载好了!"等等情况也是如此. <br /><br />  这里缺少的是纺锤状按钮(spin button),单选框(我们可以用一个单选列表框代替),下拉组合框(同样我们可以用列表框代替)以及树状控件.通过设计巧妙的列表控件来缩进特定物体,我们能够实现树状列表德功能. <br /><br />  由于我的游戏并没有足够的GUI来保证表状控件,所以在此没有包含它,虽然你可能会需要. 即使有这些遗漏,上述"最小"列表可能看上去还是很繁杂,但是我们能够简化一点儿. <br /><br />把它打破:组合简单空间来实现复杂控件 <br /><br />  如果我们意识到复杂控件仅仅是简单控件的巧妙组合,列表就会更易于控制.例如,一个滚动条基本上只是两个按钮和一个滑动条.一个选择框是一个静态文本和两个按钮(一个"打开"按钮,一个"关闭"按钮).一个平面按钮能够使用三个图标控件来实现(仅仅显示/隐藏适当的图标来使按钮显得被按下),这样你能够重用你的绘制代码.如果你的确没有时间,你甚至可以把一个进度条当作滑动条来用,虽然我更倾向于是用一个独立的控件. <br /><br />  然而,这样做是有缺陷的,名义上你的GUI控件会比他们实际需要的占用更多的系统资源.仔细考虑它-每个控件是一个窗体.让我们说你使用了重用法则创建了一个实际上是三个静态控件的按钮控件.那么每个按钮就是三个窗体.现在你使用两个按钮控件创建一个滚动条,那就是每个滚动条6个窗体.使用水平和垂直滚动条创建一个列表控件,那么每个列表就是12个窗体.它增加得很快. <br /><br />  所以这就是另一个经典的关于"我能多快的开发"和"我会使用多少资源"的矛盾的例子.如果你需要一个高性能,没有浪费的GUI,从基础来开发每一个控件.如果你想要快速开发,那就不要介意性能损失,你或许会选择开发控件以使实际上绘制到屏幕上的是静态控件,所有其他控件都是由静态控件组合而成的. <br /><br />  我开发GUI的时候,我尽力在两个极端之间取得良好的平衡. <br /><br />  现在,让我们开始关注每个控件的实际开发,从每个人最喜欢的静态标志开始吧. <br /><br />  我们需要关注三种静态控件:静态文本控件,静态图标控件和框架控件.这三种控件都很简单,因为他们不接收消息-他们所作的只是在某个位置绘制本身而已. <br /><br />  静态文本控件是你将开发的最简单的控件了-仅仅在窗口的左上角绘制窗口的标题,就行了.如果你想增加代码来以某种方式调整你的文本-比如,在绘制框中居中你的文本,你可能会使用经典的居中算法.-用窗体的宽度减去要绘制的文本的宽度,然后除以2,告诉你从距离窗体左边多少像素开始绘制. <br /><br />  静态图标控件稍微难一点儿.实际上,"静态图标控件"这个术语有些歧义,假定我们想要我们的图标控件可以表现动画的话.即使如此,开发这些图标控件也不难,假设你已经有了丰富的精灵库来处理所有开发动画的细节:检测两帧之间的时间差,使用这个差值来判断你的精灵将要走多少帧,等等. <br /><br />  图标控件只有当你在每一帧并不绘制整个GUI系统的时候才变得麻烦.这种情况下,你多少要处理一些图标控件的裁剪工作,这样即使每帧都绘制,也不会覆盖属于在其上的窗口的像素(但是没有改变,所以没有绘制).我没有开发这个-我的GUI每一帧都重画-但是如果你面临这个问题,你可能会想试试为每个图标设立裁剪列表,用它来绘制图标,当有任何一个窗体移动、关闭或者打开时重新计算它.这或许是个可行的方法-我只是如此构想-但是这起码是一个好的切入点. <br /><br />  框架控件也很简单.我开发我的框架控件时只是围绕m_position绘制边框,然后在大约绘制坐标(5,5)点附近(大约从框架控件的左上角向右向下5个像素)绘制窗口标题,你可以依照自己的想象自己决定. <br /><br />  你在开发静态控件中可能碰到的麻烦事是稍微改变findwindow函数的功能以使它跳过所有的静态控件窗口.这样,如果一个静态文本控件是在一个按钮之上的,用户可以透过静态控件来按这个按钮.当开发"简易移动"窗口(即你可以通过按住窗口的任何部位来移动窗口,而不仅仅是标题栏,就象winamp)的时候,这很有用. <br /><br />  现在让我们来看看如何开发按钮. <br /><br />按钮控件 <br /><br />  按钮只比静态控件难一点儿.你的按钮控件需要不断跟踪是否它被按下或松开.它通过两个虚函数来实现,wm_mousedown()和wm_mouseup(),你的calcall()函数需要在适当的时候调用它们. <br /><br />  基本上,在wm_mousedown()里,你要设定一个布尔变量,我把它叫做"depressed flag"(按下标志)为真,而在wm_mouseup()里,把它设为假.然后再你的绘制代码里如果按下标志为真,绘制按钮的按下状态,否则,绘制松开状态. <br /><br />  然后,增加一个附加状态-即"只有当按下标志为真和鼠标指针在绘制区域之中时绘制按钮的按下状态,否则把按下标志设为假."如果你把鼠标移出按钮这将使你的按钮弹起,并且对于精确判断一个按钮何时被按下非常重要. <br /><br />  对于普通的GUI,当一个按钮被点击,将为他的父窗体引发一个事件,窗体会做按钮所代表的任何事-例如,点击关闭按钮将关闭窗口,点击存储按钮将存储文件,等等.我的GUI在且仅在wm_mouseup()中判断按钮是否被点击,按下标志是否为真.按下标志在mouseup()中还为真的唯一情况是用户在鼠标在按钮之内按下和松开鼠标键.这允许用户在最后放弃选择-通过保持鼠标键按下并把鼠标指针拖到按钮之外松开,就象其他的GUI一样. <br /><br />  这就是按钮了.现在来看看文本框吧. <br /><br />插入符和文本控件 <br /><br />  我选择的是非常简单的文本控件.它仅仅捕捉击键,而且还不卷屏-但是你可能会要更加复杂的,也就是一个可以精确处理跳到开始(home)、跳到末尾(end)、插入和删除字符,或者可能还要通过windows剪贴板支持剪切、拷贝、粘贴. <br /><br />  但是在我们做文本框之前,我们需要一个插入符.如果你对这个术语不熟悉,这里解释一下.插入符是光标的另一种说法-是的,就是那个小小的闪动的竖线.插入符告诉用户他们的击键将会在哪里出现文字. <br /><br />  从我的GUI考虑,我很简单的处理这些事-我指定活动窗口是具有插入符和句号(这里rick不是很明白)的窗口.大多数GUI都是这样的,好像也是最好的解决办法.而且我的GUI象windows那样把文本框的标题(caption)当作文本框里的文字来处理. <br /><br />  那么你怎么开发插入符呢?好的,我想因为我们知道插入符总是在活动窗口里被绘制,并且插入符只有在活动窗口是文本框的时候出现,很容易联想到插入符绘制代码是文本框的一部分并且在文本框的绘制函数里完成.这就使它很易于开发-只要用一个整形变量来代表窗口标题字符数组的索引,你的文本框就有要绘制插入符的所有信息了. <br /><br />  这就基本上表示,如果是个文本框的话,你要做的所有绘制工作就是围绕绘制区域画边线,在边线之内绘制窗口标题,然后如果是活动窗口,在正确的位置画出插入符.在我的GUI里,文本框中字符的最大长度是由文本框窗口的大小来决定的,也就是说我不用处理在文本框之内滚动文字.然而你或许会想要用户可以在很小的文本框里输入很长的字串并可以滚动查看文本框中的内容. <br /><br />  现在来看看关于文本框的最难的东西-键盘处理.一旦会有击键发生,很容易建立一个wm_keypressed()虚函数并且调用它,同样很容易为wm_keypressed开发文本框处理器,然后要么把字符放到窗口标题的末尾,要么处理特殊击键(backspace键,等等-这是你的字串类要关注的东西),然后移动插入符. <br /><br />  难的地方在于在第一位置得到击键.windows提供了至少三种完全不同的方法来查询键盘-WM_KEYDOWN事件,GetKeyboardState()和GetAsyncKeyState()函数,当然还有DirectInput.我使用了DirectInput方法,这是因为我在开发鼠标光标的时候就已经作了大量的和DirectInput相关的工作,另外通过DirectInput来获取键盘状态对我也是最简洁和优雅的方法. <br /><br />  要使用DirectInput的键盘函数,你要做的第一件事是建立键盘设备.这和我们在第一章中建立DirectInput的鼠标设备的方法令人难以相信的相似.基本上,唯一的差别在于不是告诉DirectInput把我们的新设备当作鼠标来处理,而是当作键盘.如果你已经了解DirectInput处理鼠标的方法,那么再把同样的事情为键盘再做一遍. <br /><br />  一旦获取了键盘设备我们就可以查询它. <br /><br />  要实际判断一个键是否被按下需要多一点工作.基本上,要判断哪个键被按下,你需要对所有101个键的状态的两个快照-一个来自上一帧另一个当前帧.当前帧中被按下的而上一帧没有按下的键是被"点击"的,你要为他们发送wm_keypressed()消息. <br /><br /><br /><br />  来看看进度条。 <br /><br />进度条 <br /><br />  进度条如同静态控件一样易于开发,因为他们只接收很少几个消息. <br /><br />  基本上,你需要为进度条做两件事-你要告诉它最大/最小范围和步长.例如,我要创建一个载入进度条,由于我要载入100个不同的游戏资源.我会创建一个范围为0到100的进度条.我会把进度条初始为0,然后,当我载入一个资源的时候我会用单位长度来让进度条前进一个步长.当进度条前进时,它都会重画自身,图形上用一个和绘制区成比例的长条来表示出它有多长. <br /><br />  进度条很象滚动条;实际上,可以用滚动条的方法来开发进度条.我把进度条和滚动条分开开发是因为我想要他们有非常不同的外观和细微差别的行为-你的需要可能会不同. <br /><br />滑动条和滚动条 <br /><br />  绘制滑动条或者滚动条和绘制进度条很相似,这表现在你需要用滑动条的绘制矩形的百分比,它提供了绘制滑快的位置信息,来表现它的当前位置.你要为垂直和水平控件作些细微的修改-我先做了个基类,gui_slider,其中包含了所有的公用代码和所有的成员变量,然后开发两个不同的派生类,gui_slider_horz和gui_slider_vert,它们处理绘制和点击逻辑的不同. <br /><br />  就象处理鼠标点击一样,我为滑动条选择了简便的方法.如果鼠标点击在滚动条绘制区内发生,直接自动地滚动到那个位置.在我的滑动条里,你不能同时在轴上点击和移动位置-直接跳到你点击的地方.我这么做主要是因为这样会很简单,而且我不喜欢windows默认的方法. <br /><br />  关于滚动条/滑动条的逻辑,你知道和进度条的基本设定是一样的-最小、最大、当前位置.然而不象进度条,用户可以通过在控件上点击改变当前位置. <br /><br />  现在看看滚动条.我的GUI里滚动条就是有两边各有一个按钮的滑动条.这两个按钮(上/下或左/右箭头)会移动滑快单位距离.这种方法消除了大量的按钮类和滚动条之间的代码复制,我强烈推荐你看看做相似的事. <br /> <img src ="http://www.cppblog.com/tx7do/aggbug/9525.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tx7do/" target="_blank">杨粼波</a> 2006-07-07 12:00 <a href="http://www.cppblog.com/tx7do/archive/2006/07/07/9525.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用C++和DirectX开发游戏GUI(一)</title><link>http://www.cppblog.com/tx7do/archive/2006/07/07/9522.html</link><dc:creator>杨粼波</dc:creator><author>杨粼波</author><pubDate>Fri, 07 Jul 2006 03:59:00 GMT</pubDate><guid>http://www.cppblog.com/tx7do/archive/2006/07/07/9522.html</guid><wfw:comment>http://www.cppblog.com/tx7do/comments/9522.html</wfw:comment><comments>http://www.cppblog.com/tx7do/archive/2006/07/07/9522.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/tx7do/comments/commentRss/9522.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tx7do/services/trackbacks/9522.html</trackback:ping><description><![CDATA[作者:Mason McCuskey 翻译:Rick Cart <br /><br />写在前面的话，由于前一阵子在ogdev上看到有朋友请教如何开发GUI，今天有幸找到Rick的个人站点，发现竟然有这么好的文章，感谢Mason McCuskey ，感谢Rick Cart。 <br />鉴于目前一些个人主页不稳定的原因，又不至于让这么好的文章随之而去，特转载过来，发布在ogdev。 <br />原文请看：<a href="http://asp3.6to23.com/rickcart/program/devGUIwithDX1.html" target="_blank"><font color="#002c99">http://asp3.6to23.com/rickcart/program/devGUIwithDX1.html</font></a>，请大家支持Rick Cart的个人小站。 <br /><br />  看起来我在做发明车轮的浪费时间的事--windows已经有一套非常复杂功能完善的GUI.不幸的是windows的GUI适用于办公软件,而这通常不适合游戏软件.游戏一般需要比windows更精确的控制(例如,使用自己的GUI实现用alpha混合创造的部分透明的窗口比较容易,而使用windows的GUI则几乎做不到). <br /><br />  这篇文章将讲述如何使用C++和DirectX来创建自己的GUI.文章分为几部分,每部分涉及一个特定的GUI编程主题.这并不需要按顺序阅读,所以你可以从你需要的部分开始. <br /><br />  这里我假设读者有以下的背景知识:事件驱动的编程原理;对PDL和C++的熟练掌握.我使用C++来建立我的GUI系统,因为我是C++爱好者俱乐部的持卡会员,并且C++的OOP很适用于windows编程和控制方式. <br /><br />  让我们从定义工作范围开始.应该认识到我们不是要设计windows95,我们只是想要为一个游戏开发一套简单的GUI.所以我们不用实现每一个简单控制和GUI结构.我们只需要几个部分而已:一个鼠标指针,一个普通窗口,一些在窗口中的对话框控制.我们也需要一个资源编辑器--一个允许我们在图形环境中使用拖动控制来设计对话框. <br /><br />从基础开始:渲染循环 <br /><br />  我将通过定义一个计算并绘制框线的函数开始.我们在RenderGUI()函数中调用这个函数.RenderGUI用PDL描述如下: <br /><br />void CApplication::RenderGUI(void) <br /><br />{ <br /><br />  // get position and button status of mouse cursor <br /><br />  // calculate mouse cursor's effects on windows / send messages <br /><br />  // render all windows <br /><br />  // render mouse <br /><br />  // flip to screen <br /><br />} <br /><br />  我们得到新的位置和鼠标光标的状态,计算由新的数据引起的任何改变,渲染所有的窗口,鼠标指针并在屏幕上绘制. <br /><br />鼠标 <br /><br />class CMouse { <br /><br />public: <br /><br />CMouse(); // boring <br /><br />~CMouse(); // boring <br /><br />int Init(LPDIRECTINPUT di); // we'll talk about this later <br /><br />int Refresh(void); // we'll talk about this later <br /><br />int GetButton(int index) <br /><br />{ <br /><br />  if (index &lt; 0 || index &gt; NUMMOUSEBUTTONS) return(0); <br /><br />  return(m_button[index]); <br /><br />} <br /><br />void clear(void); // sets all vars to zero <br /><br />// makes sure p is a valid on-screen point <br /><br />void ConstrainPosToScreenSize(CPoint &amp;p); <br /><br />CPoint GetAbsPosition(void) { return(m_absposition); } <br /><br />CPoint GetRelPosition(void) { return(m_relposition); } <br /><br />enum { NUMMOUSEBUTTONS = 3 }; // three button mouse <br /><br />private: <br /><br />LPDIRECTINPUTDEVICE m_mousedev; <br /><br />char m_button[NUMMOUSEBUTTONS]; // state of buttons <br /><br />CPoint m_absposition; // actual screen position <br /><br />CPoint m_relposition; // relative position <br /><br />}; <br /><br />绝对位置和相对位置,DirectInput <br /><br />  为什么我要使用DirectInput?这实际是一个口味问题.有两种方法可得到windows的鼠标信息,从DirectInput中或通过一条叫做GetCursorPos()的Win32函数.主要的区别在于DirectInput提供的是相对坐标,即相对于上次位置的当前位置;而GetCursorPos()将提供屏幕坐标系的绝对坐标.绝对坐标对GUI很有用;而相对坐标则适合于没有光标的鼠标,例如在FPS游戏中的环视(译者:即光标位置固定的情况).然而你可以由绝对坐标计算出相对坐标,反之亦然. <br /><br />  由于很多原因我选择了DirectInput,所有这些原因超出了本文的范围.对你来说GetCursorPos()可能是个更好的选择?如果是这样,鼠标类可能就会非常庞大.DirectInput更加技巧化(也更有趣),所以本文将集中于DirectInput. <br /><br />初始化DirectInput <br /><br />  在我们详述CMouse之前,让我们看看如何初始化DirectInput.注意这些代码并不属于我们的CMouse::Init()函数;DirectInput的指针在整个游戏中都会使用,而并不仅仅在鼠标类中,所以DirectInput的初始化应在主初始化函数中和DirectDraw,DirectSound的初始化同时完成.DirectInput指针和DirectInput device指针不同;DirectInput指针用以得到DirectInput device指针.注意理解这一区别,