PageRenderTime 51ms CodeModel.GetById 12ms RepoModel.GetById 1ms app.codeStats 0ms

/Languages/IronPython/Samples/Direct3D/readme.htm

http://github.com/IronLanguages/main
HTML | 5154 lines | 3500 code | 1606 blank | 48 comment | 0 complexity | c43fd7937dd862529aa3ab5214c8e60d MD5 | raw file
Possible License(s): CPL-1.0, BSD-3-Clause, ISC, GPL-2.0, MPL-2.0-no-copyleft-exception

Large files files are truncated, but you can click here to view the full file

  1. <html>
  2. <head>
  3. <meta http-equiv=Content-Type content="text/html; charset=windows-1252">
  4. <meta name=Generator content="Microsoft Word 12 (filtered)">
  5. <title>3D Graphics in IronPython</title>
  6. <style>
  7. <!--
  8. /* Font Definitions */
  9. @font-face
  10. {font-family:"Cambria Math";
  11. panose-1:2 4 5 3 5 4 6 3 2 4;}
  12. @font-face
  13. {font-family:Tahoma;
  14. panose-1:2 11 6 4 3 5 4 4 2 4;}
  15. @font-face
  16. {font-family:Consolas;
  17. panose-1:2 11 6 9 2 2 4 3 2 4;}
  18. /* Style Definitions */
  19. span.MsoHyperlink
  20. {color:blue;
  21. text-decoration:underline;}
  22. p.Offset, div.Offset
  23. {
  24. mso-style-name: Offset;
  25. margin-top: 0in;
  26. margin-right: .5in;
  27. margin-bottom: 0in;
  28. margin-left: .5in;
  29. margin-bottom: .0001pt;
  30. border: none;
  31. padding: 0in;
  32. font-size: 12.0pt;
  33. font-family: Verdana;
  34. }
  35. p.OffsetHeader, div.OffsetHeader
  36. {
  37. mso-style-name: "Offset Header";
  38. margin-top: 0in;
  39. margin-right: .5in;
  40. margin-bottom: 0in;
  41. margin-left: .5in;
  42. margin-bottom: .0001pt;
  43. text-align: center;
  44. border: none;
  45. padding: 0in;
  46. font-size: 12.0pt;
  47. font-family: Verdana;
  48. font-weight: bold;
  49. }
  50. @page Section1
  51. {size:8.5in 11.0in;
  52. margin:1.0in 1.25in 1.0in 1.25in;}
  53. /* List Definitions */
  54. -->
  55. </style>
  56. <link rel="stylesheet" type="text/css" href="../Samples.css">
  57. </head>
  58. <body lang=EN-US link=blue vlink=purple>
  59. <div class=Section1>
  60. <hr />
  61. <p class="CopyrightText">
  62. Information in this document is subject to change without notice. The example companies,
  63. organizations, products, people, and events depicted herein are fictitious. No association
  64. with any real company, organization, product, person or event is intended or should
  65. be inferred. Complying with all applicable copyright laws is the responsibility
  66. of the user. Without limiting the rights under copyright, no part of this document
  67. may be reproduced, stored in or introduced into a retrieval system, or transmitted
  68. in any form or by any means (electronic, mechanical, photocopying, recording, or
  69. otherwise), or for any purpose, without the express written permission of Microsoft
  70. Corporation.</p>
  71. <p class="CopyrightText">
  72. &nbsp;</p>
  73. <p class="CopyrightText">
  74. Microsoft may have patents, patent applications, trademarked, copyrights, or other
  75. intellectual property rights covering subject matter in this document. Except as
  76. expressly provided in any written license agreement from Microsoft, the furnishing
  77. of this document does not give you any license to these patents, trademarks, copyrights,
  78. or other intellectual property.</p>
  79. <p class="CopyrightText">
  80. &nbsp;</p>
  81. <div class="Section1">
  82. <p class="CopyrightText">© Microsoft Corporation. All rights
  83. reserved.</p>
  84. <p class="CopyrightText">&nbsp;</p>
  85. <p class="CopyrightText">Microsoft, MS-DOS, MS, Windows, Windows NT,
  86. MSDN, Active Directory, BizTalk, SQL Server, SharePoint, Outlook, PowerPoint, FrontPage, Visual Basic,
  87. Visual C++, Visual J++, Visual InterDev, Visual SourceSafe, Visual C#, Visual J#,&nbsp; and Visual Studio
  88. are either registered trademarks or trademarks of Microsoft Corporation in the U.S.A. and/or other
  89. countries.</p>
  90. <p class="CopyrightText">&nbsp;</p>
  91. <p class="CopyrightText">Other product and company names herein may
  92. be the trademarks of their respective owners.</div>
  93. <hr>
  94. <p class="body">&nbsp;</p>
  95. <p class="CopyrightText">This source code is subject to terms and conditions of the Apache License, Version 2.0. A
  96. copy of the license can be found in the License.html file at the root of this distribution. If
  97. you cannot locate the Apache License, Version 2.0, please send an email to
  98. ironpy@microsoft.com. By using this source code in any fashion, you are agreeing to be bound
  99. by the terms of the Apache License, Version 2.0.</p>
  100. <p class="CopyrightText">
  101. &nbsp;</p>
  102. <p class="CopyrightText">
  103. &nbsp;</p>
  104. <p class=Normal><b>
  105. <span style='font-size:16.0pt;font-family:"Arial","sans-serif"'>3D
  106. Graphics in IronPython</span></b></p>
  107. <p class=Normal><span style='font-size:14.0pt;font-family:"Arial","sans-serif"'>A
  108. Flexible DirectX Framework in IronPython</span></p>
  109. <p class=Normal><span style='font-size:14.0pt;font-family:"Arial","sans-serif"'>By
  110. Lee Culver</span></p>
  111. <p class=Normal><span style='font-size:10.0pt;font-family:"Courier New"'>&nbsp;</span></p>
  112. <p class=Normal><span style='font-size:10.0pt;font-family:"Courier New"'>&nbsp;</span></p>
  113. <p class=Toc1><span
  114. class=MsoHyperlink><a href="#_Toc140655628">Getting Started<span
  115. style='color:windowtext;display:none;text-decoration:none'>. 2</span></a></span></p>
  116. <p class=Toc2><span class=MsoHyperlink><a href="#_Toc140655629">Introduction<span
  117. style='color:windowtext;display:none;text-decoration:none'>. 2</span></a></span></p>
  118. <p class=Toc2><span class=MsoHyperlink><a href="#_Toc140655630">Prerequisites<span
  119. style='color:windowtext;display:none;text-decoration:none'>. 2</span></a></span></p>
  120. <p class=Toc2><span class=MsoHyperlink><a href="#_Toc140655631">How to Use
  121. this Tutorial<span style='color:windowtext;display:none;text-decoration:none'> 2</span></a></span></p>
  122. <p class=Toc2><span class=MsoHyperlink><a href="#_Toc140655632">Objectives
  123. for this Tutorial<span style='color:windowtext;display:none;text-decoration:
  124. none'> </span><span
  125. style='color:windowtext;display:none;text-decoration:none'>2</span></a></span></p>
  126. <p class=Toc2><span class=MsoHyperlink><a href="#_Toc140655633">Final Note<span
  127. style='color:windowtext;display:none;text-decoration:none'>. 2</span></a></span></p>
  128. <p class=Toc1><span class=MsoHyperlink><a href="#_Toc140655634">Creating the
  129. Framework for a DirectX Application<span style='color:windowtext;display:none;
  130. text-decoration:none'>. </span><span
  131. style='color:windowtext;display:none;text-decoration:none'>3</span></a></span></p>
  132. </div>
  133. <p class=Toc2><span class=MsoHyperlink><a href="#_Toc140655635">Loading
  134. Assemblies and Importing Them<span style='color:windowtext;display:none;
  135. text-decoration:none'>.. </span>
  136. <span
  137. style='color:windowtext;display:none;text-decoration:none'>3</span></a></span></p>
  138. <div class=Section1>
  139. <p class=Toc2><span class=MsoHyperlink><a href="#_Toc140655636">The
  140. RenderWindow Class<span style='color:windowtext;display:none;text-decoration:
  141. none'>. </span><span
  142. style='color:windowtext;display:none;text-decoration:none'>4</span></a></span></p>
  143. <p class=Toc2><span class=MsoHyperlink><a href="#_Toc140655637">Code
  144. Checkpoint 1<span style='color:windowtext;display:none;text-decoration:none'>. 6</span></a></span></p>
  145. <p class=Toc1><span class=MsoHyperlink><a href="#_Toc140655638">Your First
  146. DirectX Application (in IronPython)<span style='color:windowtext;display:none;
  147. text-decoration:none'> </span><span
  148. style='color:windowtext;display:none;text-decoration:none'>6</span></a></span></p>
  149. <p class=Toc2><span class=MsoHyperlink><a href="#_Toc140655639">Setting up
  150. DirectX<span style='color:windowtext;display:none;text-decoration:none'>.. 6</span></a></span></p>
  151. <p class=Toc2><span class=MsoHyperlink><a href="#_Toc140655640">Code
  152. Checkpoint 2<span style='color:windowtext;display:none;text-decoration:none'>. 9</span></a></span></p>
  153. <p class=Toc2><span class=MsoHyperlink><a href="#_Toc140655641">An
  154. Introduction to Duck Typing<span style='color:windowtext;display:none;
  155. text-decoration:none'>. </span><span
  156. style='color:windowtext;display:none;text-decoration:none'>9</span></a></span></p>
  157. <p class=Toc2><span class=MsoHyperlink><a href="#_Toc140655642">Loading
  158. Meshes<span style='color:windowtext;display:none;text-decoration:none'>. 10</span></a></span></p>
  159. <p class=Toc2><span class=MsoHyperlink><a href="#_Toc140655643">Rendering
  160. Meshes<span style='color:windowtext;display:none;text-decoration:none'>. 11</span></a></span></p>
  161. <p class=Toc2><span class=MsoHyperlink><a href="#_Toc140655644">Code
  162. Checkpoint 3<span style='color:windowtext;display:none;text-decoration:none'>. 13</span></a></span></p>
  163. <p class=Toc1><span class=MsoHyperlink><a href="#_Toc140655645">Cameras,
  164. Moving Objects, and Events<span style='color:windowtext;display:none;
  165. text-decoration:none'>. </span><span
  166. style='color:windowtext;display:none;text-decoration:none'>13</span></a></span></p>
  167. <p class=Toc2><span class=MsoHyperlink><a href="#_Toc140655646">The Event
  168. System<span style='color:windowtext;display:none;text-decoration:none'>.. 14</span></a></span></p>
  169. <p class=Toc2><span class=MsoHyperlink><a href="#_Toc140655647">Code
  170. Checkpoint 4<span style='color:windowtext;display:none;text-decoration:none'>. 17</span></a></span></p>
  171. <p class=Toc2><span class=MsoHyperlink><a href="#_Toc140655648">Exercises<span
  172. style='color:windowtext;display:none;text-decoration:none'>. 17</span></a></span></p>
  173. <p class=Toc2><span class=MsoHyperlink><a href="#_Toc140655649">Moving
  174. Objects on Screen<span style='color:windowtext;display:none;text-decoration:
  175. none'>. </span><span
  176. style='color:windowtext;display:none;text-decoration:none'>17</span></a></span></p>
  177. <p class=Toc2><span class=MsoHyperlink><a href="#_Toc140655650">Rotating
  178. Objects on the Screen<span style='color:windowtext;display:none;text-decoration:
  179. none'>. </span><span
  180. style='color:windowtext;display:none;text-decoration:none'>20</span></a></span></p>
  181. <p class=Toc2><span class=MsoHyperlink><a href="#_Toc140655651">Putting it
  182. All Together<span style='color:windowtext;display:none;text-decoration:none'> 20</span></a></span></p>
  183. <p class=Toc2><span class=MsoHyperlink><a href="#_Toc140655652">Cameras<span
  184. style='color:windowtext;display:none;text-decoration:none'>. 21</span></a></span></p>
  185. <p class=Toc2><span class=MsoHyperlink><a href="#_Toc140655653">Code
  186. Checkpoint<span style='color:windowtext;display:none;text-decoration:none'> 23</span></a></span></p>
  187. <p class=Toc2><span class=MsoHyperlink><a href="#_Toc140655654">Exercises<span
  188. style='color:windowtext;display:none;text-decoration:none'>. 23</span></a></span></p>
  189. <p class=Toc2><span class=MsoHyperlink><a href="#_Toc140655655">Framework
  190. Optimization<span style='color:windowtext;display:none;text-decoration:none'>. 24</span></a></span></p>
  191. <p class=Toc2><span class=MsoHyperlink><a href="#_Toc140655656">Adding Other
  192. Types of Objects<span style='color:windowtext;display:none;text-decoration:
  193. none'>. </span><span
  194. style='color:windowtext;display:none;text-decoration:none'>26</span></a></span></p>
  195. <p class=Toc2><span class=MsoHyperlink><a href="#_Toc140655657">A Better
  196. Main Function<span style='color:windowtext;display:none;text-decoration:none'>. 28</span></a></span></p>
  197. <p class=Toc2><span class=MsoHyperlink><a href="#_Toc140655658">Code Checkpoint
  198. 6<span style='color:windowtext;display:none;text-decoration:none'>. 29</span></a></span></p>
  199. <p class=Toc1><span class=MsoHyperlink><a href="#_Toc140655659">Cool Things
  200. to Do with the Project<span style='color:windowtext;display:none;text-decoration:
  201. none'> </span><span
  202. style='color:windowtext;display:none;text-decoration:none'>30</span></a></span></p>
  203. <p class=Toc2><span class=MsoHyperlink><a href="#_Toc140655660">Moving
  204. Objects Around, Part I<span style='color:windowtext;display:none;text-decoration:
  205. none'>. </span><span
  206. style='color:windowtext;display:none;text-decoration:none'>30</span></a></span></p>
  207. <p class=Toc2><span class=MsoHyperlink><a href="#_Toc140655661">Moving
  208. Objects Around, Part II<span style='color:windowtext;display:none;text-decoration:
  209. none'>. </span><span
  210. style='color:windowtext;display:none;text-decoration:none'>31</span></a></span></p>
  211. <p class=Toc2><span class=MsoHyperlink><a href="#_Toc140655662">Moving
  212. Objects Around, Part III<span style='color:windowtext;display:none;text-decoration:
  213. none'>. </span><span
  214. style='color:windowtext;display:none;text-decoration:none'>33</span></a></span></p>
  215. <p class=Toc2><span class=MsoHyperlink><a href="#_Toc140655663">Auto
  216. Tracking<span style='color:windowtext;display:none;text-decoration:none'>. 35</span></a></span></p>
  217. <p class=Toc2><span class=MsoHyperlink><a href="#_Toc140655664">Gravity and
  218. Free Floating Bodies<span style='color:windowtext;display:none;text-decoration:
  219. none'>. </span><span
  220. style='color:windowtext;display:none;text-decoration:none'>36</span></a></span></p>
  221. <p class=Toc1><span class=MsoHyperlink><a href="#_Toc140655665">Where to Go
  222. from Here<span style='color:windowtext;display:none;text-decoration:none'>. 40</span></a></span></p>
  223. <p class=Toc2><span class=MsoHyperlink><a href="#_Toc140655666">Managed
  224. DirectX and XNA<span style='color:windowtext;display:none;text-decoration:none'>.. 40</span></a></span></p>
  225. <p class=Toc2><span class=MsoHyperlink><a href="#_Toc140655667">IronPython<span
  226. style='color:windowtext;display:none;text-decoration:none'>. 41</span></a></span></p>
  227. <p class=Toc2><span class=MsoHyperlink><a href="#_Toc140655668">Extending
  228. the Framework<span style='color:windowtext;display:none;text-decoration:none'>. 41</span></a></span></p>
  229. <p class=Normal><span style='font-size:10.0pt;font-family:"Courier New"'>&nbsp;</span></p>
  230. <p class=Normal><span style='font-size:10.0pt;font-family:"Courier New"'>&nbsp;</span></p>
  231. <h1><a name="_Toc140655628">Getting Started</a></h1>
  232. <p class=Normal>&nbsp;</p>
  233. <h2><a name="_Toc140655629">Introduction</a></h2>
  234. <p class=Normal>In this tutorial we will be creating a highly flexible
  235. Python graphical framework as an introduction to IronPython.  By the end of
  236. this tutorial you will have a better understanding of IronPython, a basic grasp
  237. of DirectX, and a better understanding of how IronPython utilizes and interacts
  238. with the .NET framework. </p>
  239. <h2><a name="_Toc140655630">Prerequisites</a></h2>
  240. <p class=Normal>This tutorial assumes only a basic knowledge of the Python
  241. syntax and how to use some of its basic constructs (such as lists and tuples). 
  242. No prior knowledge of DirectX or Windows.Forms is required, though a basic
  243. grasp of the .Net platform will go a long way to understanding a few sections
  244. of code.</p>
  245. <p class=Normal>&nbsp;</p>
  246. <p class=Normal>We will be building this application from scratch, and all
  247. portions of the code will be fully explained.  Note that if you are already
  248. familiar with Python, you should probably skip the sections labeled For Python
  249. Beginners.</p>
  250. <p class=Normal>&nbsp;</p>
  251. <p class="body">
  252. Further, you will need the following:</p>
  253. <ul>
  254. <li class="normal">IronPython 2.6 distribution
  255. <ul>
  256. <li>If you are new to IronPython, please go over the tutorial
  257. that comes with this distribution</li>
  258. <li>Download from
  259. <a href="http://ironpython.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=12482">here</a></li>
  260. </ul>
  261. </li>
  262. <li class="normal">DirectX End-user Runtime and a compatible video card<ul>
  263. <li>Download from
  264. <a href="http://www.microsoft.com/games/en-US/aboutgfw/Pages/directx10-a.aspx">here</a>.</li>
  265. </ul>
  266. </li>
  267. </ul>
  268. <p class=Normal>&nbsp;</p><p class=Normal><b><font size="3">Important Note </font></b></p>
  269. <p class=Normal>If you've previously installed a DirectX SDK there's a good chance you might have the
  270. Managed DirectX 2.0 Beta assembly installed.&nbsp; This assembly is incompatible with the Python sample code
  271. distributed with this tutorial and cannot be uninstalled.&nbsp; If you experience difficulties running the
  272. samples (particularly when there are error messages stating that the <i>Matrix</i> class has no
  273. <i>LookAtLH</i> method) and are sure you meet the prerequisites above, please replace all occurrences
  274. of:</p><p class=Normal><b>&nbsp;&nbsp;&nbsp; </b><i>clr.AddReference(Microsoft.DirectX)</i></p>
  275. <p class=Normal>with:</p><p class=Normal><b>&nbsp;&nbsp;&nbsp; </b><i>clr.AddReferenceByName('Microsoft.DirectX, Version=1.0.2902.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35')</i></p>
  276. <p class=Normal>&nbsp;</p><p class=Normal>throughout the samples.&nbsp; This change basically means that the
  277. sample code will use Managed DirectX 1 instead of the 2.0 beta which would normally have precedence.</p>
  278. <h2><a name="_Toc140655631">How to Use this Tutorial</a></h2>
  279. <p class=Normal>This tutorial will start from a small set of code and slowly
  280. build a full framework from scratch.  Throughout this tutorial you should be
  281. slowly adding code to a Python source file of your own and watching the results
  282. as we build it.  There is no substitute for actual programming; I highly
  283. recommend that you resist the urge to simply read along.</p>
  284. <p class=Normal>&nbsp;</p>
  285. <h2><a name="_Toc140655632">Objectives for this Tutorial</a></h2>
  286. <p class=Normal>By the end of the first part of this tutorial we will build a framework which will allow you to import any number of DirectX meshes and view
  287. them inside of a .NET form.&nbsp; The framework will provide methods for positioning and rotating objects and the camera, as well as examples of using the
  288. framework to implement more advanced functionality such as having objects move around a track and have cameras auto-track objects in the scene.&nbsp; Lastly, we
  289. will implement a small scale demo which demonstrates Newtons law of universal
  290. gravitation, which will allow you to specify an arbitrary number of free
  291. floating bodies in space (planets), and watch them interact with each other.</p>
  292. <p class=Normal>&nbsp;</p>
  293. <h2><a name="_Toc140655633">Final Note</a></h2>
  294. <p class=Normal>Throughout this tutorial be very careful to keep the same
  295. indentation levels that have been used here.  In Python, white space is a part of
  296. the language, and you must take care to ensure that everything is correctly
  297. aligned or you will receive errors.  I suggest setting your text editor of
  298. choice to use 4 spaces instead of tabs (which I have done for all code
  299. presented here).</p>
  300. <p class=Normal>&nbsp;</p>
  301. <p class=Normal>Lastly, if you are getting compile errors, check to make
  302. sure you have not inserted extra returns in the middle of statements.  The code
  303. may be slightly skewed if you have word wrap turned on.</p>
  304. <p class=Normal>&nbsp;</p>
  305. <h1><a name="_Toc140655634">Creating the Framework for a DirectX Application</a></h1>
  306. <p class=Normal>&nbsp;</p>
  307. <h3><a name="_Toc140655635">Loading Assemblies and Importing Them</a></h3>
  308. <p class=Normal>&nbsp;</p>
  309. <p class=Normal>The first thing we will do is add a few references to
  310. assemblies we will be using.  Create a new file called tutorial.py and add
  311. the following code to it:</p>
  312. <p class=Normal>&nbsp;</p>
  313. <div style='border:solid windowtext 1.0pt;padding:1.0pt 4.0pt 1.0pt 4.0pt;
  314. background:silver;margin-left:.25in;margin-right:.25in'>
  315. <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
  316. border:none;padding:0in'>import clr</p>
  317. <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
  318. border:none;padding:0in'>clr.AddReferenceByPartialName(&quot;System.Drawing&quot;)</p>
  319. <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
  320. border:none;padding:0in'>clr.AddReferenceByPartialName(&quot;System.Windows.Forms&quot;)</p>
  321. <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
  322. border:none;padding:0in'>clr.AddReferenceByPartialName(&quot;Microsoft.DirectX&quot;)</p><p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
  323. border:none;padding:0in'>clr.AddReferenceByPartialName(&quot;Microsoft.DirectX.Direct3D&quot;)<span style="background-color: #C0C0C0; background-position: 0% 0%"><br>
  324. </span>clr.AddReferenceByPartialName(&quot;Microsoft.DirectX.Direct3DX&quot;)</p>
  325. </div>
  326. <p class=Normal>&nbsp;</p>
  327. <p class=Normal>If you do not add the reference to assemblies that you use,
  328. the IronPython interpreter will not know how to load them.  If you run into
  329. problems where an import statement does not give the expected results, check to
  330. make sure you have referenced all of the appropriate assemblies first.  Note
  331. that IronPython automatically adds the System library.</p><p class=Normal>&nbsp;</p><p class=Normal>If you encounter
  332. difficulties running the snippet of code above, please see the <b>Important Notes</b> section in the
  333. <a href="#_Toc140655630">Prerequisites</a>.</p>
  334. <p class=Normal>&nbsp;</p>
  335. <div>
  336. <table cellspacing=0 cellpadding=0 hspace=0 vspace=0 align=right>
  337. <tr>
  338. <td valign=top align=left style='padding-top:0in;padding-right:0in;
  339. padding-bottom:0in;padding-left:0in'>
  340. <div style='border:solid windowtext 1.0pt;padding:1.0pt 4.0pt 1.0pt 4.0pt;
  341. margin-left:.5in;margin-right:.5in'>
  342. <p class=OffsetHeader style='margin:0in;margin-bottom:.0001pt;border:none;
  343. padding:0in'>New to IronPython?</p>
  344. <p class=Offset style='margin:0in;margin-bottom:.0001pt;border:none;
  345. padding:0in'>The clr import is not just a library; it actually changes the
  346. dynamics of several basic constructs.  To see this first hand, open up a
  347. fresh IronPython interpreter and run this code:</p>
  348. <p class=Offset style='margin:0in;margin-bottom:.0001pt;border:none;
  349. padding:0in'>&nbsp;</p>
  350. <p class=Offset style='margin:0in;margin-bottom:.0001pt;border:none;
  351. padding:0in'><span style='font-size:10.0pt;font-family:"Courier New"'>print
  352. dir([])</span></p>
  353. <p class=Offset style='margin:0in;margin-bottom:.0001pt;border:none;
  354. padding:0in'><span style='font-size:10.0pt;font-family:"Courier New"'>import
  355. clr</span></p>
  356. <p class=Offset style='margin:0in;margin-bottom:.0001pt;border:none;
  357. padding:0in'><span style='font-size:10.0pt;font-family:"Courier New"'>print
  358. dir([])</span></p>
  359. <p class=Offset style='margin:0in;margin-bottom:.0001pt;border:none;
  360. padding:0in'><span style='font-size:10.0pt;font-family:"Courier New"'>&nbsp;</span></p>
  361. <p class=Offset style='margin:0in;margin-bottom:.0001pt;border:none;
  362. padding:0in'>Notice that it adds a number of functions which makes IronPython
  363. very similar to .NET (though all of the Python functions are still there). 
  364. This also replaces the standard Python string with the .Net string class. 
  365. Throughout this tutorial I will be using the IronPython methods instead of
  366. the standard Python methods as this produces a more consistent code base.</p>
  367. </div>
  368. </td>
  369. </tr>
  370. </table>
  371. </div>
  372. <br clear=ALL>
  373. <p class=Normal>&nbsp;</p>
  374. <p class=Normal>Next we will import all of the libraries we will need for
  375. this tutorial.</p>
  376. <p class=Normal>&nbsp;</p>
  377. <div style='border:solid windowtext 1.0pt;padding:1.0pt 4.0pt 1.0pt 4.0pt;
  378. background:silver;margin-left:.25in;margin-right:.25in'>
  379. <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
  380. border:none;padding:0in'>import System</p>
  381. <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
  382. border:none;padding:0in'>from System import Drawing</p>
  383. <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
  384. border:none;padding:0in'>from System.Windows import Forms</p>
  385. <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
  386. border:none;padding:0in'>from Microsoft import DirectX</p>
  387. <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
  388. border:none;padding:0in'>from Microsoft.DirectX import Direct3D</p>
  389. </div>
  390. <p class=Normal>&nbsp;</p>
  391. <p class=Normal>In this tutorial I have kept namespaces and never imported
  392. everything into the global namespace.  This will make the rest of the tutorial
  393. slightly more verbose, but it will also be very explicit as to which functions
  394. we are calling.</p>
  395. <p class=Normal>&nbsp;</p>
  396. <h3><a name="_Toc140655636">The RenderWindow Class</a></h3>
  397. <p class=Normal>&nbsp;</p>
  398. <p class=Normal>The next thing we need to do is to create a new Form to
  399. house our application.  In IronPython we can natively derive from any .Net
  400. class which is not sealed or a value type.  We will define a constructor which
  401. takes in a single argument (a class which contains a Paused attribute). 
  402. Though I am calling this variable sceneManager here, and we will be providing a
  403. class called SceneManager later, we could easily swap it for any other class
  404. which understands how to pause and unpause the system:</p>
  405. <p class=Normal><span style='font-size:10.0pt;font-family:"Courier New"'>&nbsp;</span></p>
  406. <div style='border:solid windowtext 1.0pt;padding:1.0pt 4.0pt 1.0pt 4.0pt;
  407. background:silver;margin-left:.25in;margin-right:.25in'>
  408. <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
  409. border:none;padding:0in'>class RenderWindow(Forms.Form):</p>
  410. <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
  411. border:none;padding:0in'>    def __init__(self, sceneManager):</p>
  412. <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
  413. border:none;padding:0in'>        self.SceneManager = sceneManager</p>
  414. <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
  415. border:none;padding:0in'>        self.Text = &quot;IronPython Direct3D&quot;</p>
  416. <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
  417. border:none;padding:0in'>        self.ClientSize = Drawing.Size(640, 480)</p>
  418. </div>
  419. <p class=Normal>&nbsp;</p>
  420. <p class=Normal>Here we have set our own instance variable SceneManager to
  421. be the sceneManager variable that was passed in.  We have also set the Text
  422. and ClientSize properties, which are properties defined by the Forms.Form
  423. class.</p>
  424. <p class=Normal>&nbsp;</p>
  425. <div>
  426. <table cellspacing=0 cellpadding=0 hspace=0 vspace=0 align=right>
  427. <tr>
  428. <td valign=top align=left style='padding-top:0in;padding-right:0in;
  429. padding-bottom:0in;padding-left:0in'>
  430. <div style='border:solid windowtext 1.0pt;padding:1.0pt 4.0pt 1.0pt 4.0pt;
  431. margin-left:.5in;margin-right:.5in'>
  432. <p class=OffsetHeader style='margin:0in;margin-bottom:.0001pt;border:none;
  433. padding:0in'>New to Python?</p>
  434. <p class=Offset style='margin:0in;margin-bottom:.0001pt;border:none;
  435. padding:0in'>When defining a class’s method in Python, you always add a
  436. parameter for the object you are currently operating on.  In languages such
  437. as C# or C++ this parameter is implicitly passed as the this parameter. 
  438. Note that we cannot access a classs member methods or data without using
  439. this self parameter.</p>
  440. </div>
  441. </td>
  442. </tr>
  443. </table>
  444. </div>
  445. <br clear=ALL>
  446. <p class=Normal>&nbsp;</p>
  447. <p class=Normal>Next, we want our window to close (and the application to
  448. exit) whenever the escape key is pressed.  We will override the OnKeyDown
  449. method of Forms.Form to do this.</p>
  450. <p class=Normal>&nbsp;</p>
  451. <div style='border:solid windowtext 1.0pt;padding:1.0pt 4.0pt 1.0pt 4.0pt;
  452. background:silver;margin-left:.25in;margin-right:.25in'>
  453. <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
  454. border:none;padding:0in'>    def OnKeyDown(self, args):</p>
  455. <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
  456. border:none;padding:0in'>        if args.KeyCode ==
  457. System.Windows.Forms.Keys.Escape:</p>
  458. <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
  459. border:none;padding:0in'>            self.Dispose()</p>
  460. </div>
  461. <p class=Normal>&nbsp;</p>
  462. <p class=Normal>Finally, we want the application to pause and stop rendering
  463. any time the application is minimized or not visible.  For now we will set the
  464. Paused variable on the SceneManager variable we have created.  We will actually
  465. implement the code for this later.</p>
  466. <p class=Normal>&nbsp;</p>
  467. <div style='border:solid windowtext 1.0pt;padding:1.0pt 4.0pt 1.0pt 4.0pt;
  468. background:silver;margin-left:.25in;margin-right:.25in'>
  469. <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
  470. border:none;padding:0in'>    def OnResize(self, args):</p>
  471. <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
  472. border:none;padding:0in'>        self.SceneManager.Paused = not self.Visible or
  473. \</p>
  474. <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
  475. border:none;padding:0in'>                (self.WindowState ==
  476. Forms.FormWindowState.Minimized)</p>
  477. </div>
  478. <p class=Normal>&nbsp;</p>
  479. <p class=Normal>Next we are going to add the shell of the SceneManager
  480. class.  The first three methods are very simple (and we will revisit their
  481. implementations later).  The first is the constructor, the second is a method
  482. which sets up DirectX, and the third is the Render method, which is called
  483. from within our render loop.  We will cover these in detail later.</p>
  484. <p class=Normal>&nbsp;</p>
  485. <div style='border:solid windowtext 1.0pt;padding:1.0pt 4.0pt 1.0pt 4.0pt;
  486. background:silver;margin-left:.25in;margin-right:.25in'>
  487. <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
  488. border:none;padding:0in'>class SceneManager(object):</p>
  489. <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
  490. border:none;padding:0in'>    def __init__(self):</p>
  491. <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
  492. border:none;padding:0in'>        pass</p>
  493. <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
  494. border:none;padding:0in'>&nbsp;</p>
  495. <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
  496. border:none;padding:0in'>    def InitGraphics(self, handle):</p>
  497. <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
  498. border:none;padding:0in'>        return True</p>
  499. <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
  500. border:none;padding:0in'>&nbsp;</p>
  501. <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
  502. border:none;padding:0in'>    def Render(self):</p>
  503. <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
  504. border:none;padding:0in'>        pass</p>
  505. </div>
  506. <p class=Normal>&nbsp;</p>
  507. <div>
  508. <table cellspacing=0 cellpadding=0 hspace=0 vspace=0 align=right>
  509. <tr>
  510. <td valign=top align=left style='padding-top:0in;padding-right:0in;
  511. padding-bottom:0in;padding-left:0in'>
  512. <div style='border:solid windowtext 1.0pt;padding:1.0pt 4.0pt 1.0pt 4.0pt;
  513. margin-left:.5in;margin-right:.5in'>
  514. <p class=OffsetHeader style='margin:0in;margin-bottom:.0001pt;border:none;
  515. padding:0in'>New to Python?</p>
  516. <p class=Offset style='margin:0in;margin-bottom:.0001pt;border:none;
  517. padding:0in'>Whenever we define a method or class which has no body, we
  518. always must use the pass keyword.  This keyword has no meaning outside of
  519. saying empty code block.</p>
  520. <p class=Offset style='margin:0in;margin-bottom:.0001pt;border:none;
  521. padding:0in'>&nbsp;</p>
  522. <p class=Offset style='margin:0in;margin-bottom:.0001pt;border:none;
  523. padding:0in'>Note that we have returned True from InitGraphics.  One
  524. important thing to note about Python is that any time you do not return a
  525. value, you are implicitly returning the None type (which is roughly
  526. equivalent to null, with a few exceptions).  This is why you will see some
  527. code paths in Python which have return statements and some which do not. 
  528. This is perfectly valid, and generally accepted as normal.</p>
  529. </div>
  530. </td>
  531. </tr>
  532. </table>
  533. </div>
  534. <br clear=ALL>
  535. <p class=Normal>&nbsp;</p>
  536. <p class=Normal>Next we need to create the render loop for the application. 
  537. This loop will pump the Windows.Forms event queue and call the Render method:</p>
  538. <p class=Normal style='text-autospace:none'><span style='font-size:10.0pt;
  539. font-family:Consolas'>&nbsp;</span></p>
  540. <div style='border:solid windowtext 1.0pt;padding:1.0pt 4.0pt 1.0pt 4.0pt;
  541. background:silver;margin-left:.25in;margin-right:.25in'>
  542. <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
  543. border:none;padding:0in'>    def Go(self, window):</p>
  544. <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
  545. border:none;padding:0in'>        while window.Created:</p>
  546. <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
  547. border:none;padding:0in'>            self.Render()</p>
  548. <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
  549. border:none;padding:0in'>            Forms.Application.DoEvents()</p>
  550. </div>
  551. <p class=Normal><span style='font-size:10.0pt;font-family:Consolas'>&nbsp;</span></p>
  552. <p class=Normal>Finally, we will create the main function which creates the
  553. basic objects and starts the render loop.</p>
  554. <p class=Normal>&nbsp;</p>
  555. <div style='border:solid windowtext 1.0pt;padding:1.0pt 4.0pt 1.0pt 4.0pt;
  556. background:silver;margin-left:.25in;margin-right:.25in'>
  557. <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
  558. border:none;padding:0in'>def main():</p>
  559. <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
  560. border:none;padding:0in'>    sceneManager = SceneManager()</p>
  561. <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
  562. border:none;padding:0in'>    window = RenderWindow(sceneManager)</p>
  563. <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
  564. border:none;padding:0in'>&nbsp;</p>
  565. <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
  566. border:none;padding:0in'>    if not sceneManager.InitGraphics(window.Handle):</p>
  567. <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
  568. border:none;padding:0in'>        Forms.MessageBox.Show(&quot;Could not init
  569. Direct3D.&quot;)</p>
  570. <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
  571. border:none;padding:0in'>&nbsp;</p>
  572. <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
  573. border:none;padding:0in'>    else:</p>
  574. <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
  575. border:none;padding:0in'>        window.Show()</p>
  576. <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
  577. border:none;padding:0in'>        sceneManager.Go(window)</p>
  578. <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
  579. border:none;padding:0in'>&nbsp;</p>
  580. <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
  581. border:none;padding:0in'>if __name__ == '__main__':</p>
  582. <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
  583. border:none;padding:0in'>    main()</p>
  584. </div>
  585. <p class=Normal>&nbsp;</p>
  586. <div>
  587. <table cellspacing=0 cellpadding=0 hspace=0 vspace=0 align=right>
  588. <tr>
  589. <td valign=top align=left style='padding-top:0in;padding-right:0in;
  590. padding-bottom:0in;padding-left:0in'>
  591. <div style='border:solid windowtext 1.0pt;padding:1.0pt 4.0pt 1.0pt 4.0pt;
  592. margin-left:.5in;margin-right:.5in'>
  593. <p class=OffsetHeader style='margin:0in;margin-bottom:.0001pt;border:none;
  594. padding:0in'>New to Python?</p>
  595. <p class=Offset style='margin:0in;margin-bottom:.0001pt;border:none;
  596. padding:0in'>In a Python script it is ok to have code which runs at the file
  597. level (that is, not inside of a function, not inside of a class).  This code
  598. is run every time the code is imported.  If you want to have the code run
  599. only when the module is explicitly ran (not imported) we use the built in
  600. __name__ variable to determine if we have been explicitly invoked from the
  601. command line.  It will always equal __main__ if we have been run from the
  602. command line.  If the module was loaded using the import statement,
  603. __name__ would be the name of the file otherwise.</p>
  604. <p class=Offset style='margin:0in;margin-bottom:.0001pt;border:none;
  605. padding:0in'>&nbsp;</p>
  606. <p class=Offset style='margin:0in;margin-bottom:.0001pt;border:none;
  607. padding:0in'>We have explicitly created a main function so that if this code
  608. is imported into an IronPython console, the main function can be invoked
  609. explicitly.  If we replaced the call to main with the contents of the main
  610. function, there would be no way to run the code outside of actually running
  611. it from the command line (and not importing it).  This is sometimes
  612. desirable, but not in our application.  We will be using this much later in
  613. the tutorial when we actually import our framework from a separate file.</p>
  614. <p class=Offset style='margin:0in;margin-bottom:.0001pt;border:none;
  615. padding:0in'>&nbsp;</p>
  616. <p class=Offset style='margin:0in;margin-bottom:.0001pt;border:none;
  617. padding:0in'>Notice also that creating a class does not use the “new” keyword
  618. like C# and C++ do.  The syntax for creating a new class is the exact same
  619. as calling a function.  This is by design.  In many cases we can use function
  620. calls and class constructors interchangeably when we are passing functions as
  621. parameters.</p>
  622. </div>
  623. </td>
  624. </tr>
  625. </table>
  626. </div>
  627. <br clear=ALL>
  628. <p class=Normal>&nbsp;</p>
  629. <p class=Normal>&nbsp;</p>
  630. <h2><a name="_Toc140655637">Code Checkpoint 1</a></h2>
  631. <p class=Normal>&nbsp;</p>
  632. <p class=Normal>Run the code from within IronPython.  You should see an empty
  633. Windows.Forms window.  If you are having problems with the code, you should
  634. compare your source file with checkpoint1.py.</p>
  635. <p class=Normal>&nbsp;</p>
  636. <h1><a name="_Toc140655638">Your First DirectX Application (in IronPython)</a></h1>
  637. <p class=Normal>&nbsp;</p>
  638. <p class=Normal>In this section we will create a basic scene in DirectX.  By
  639. the end of this section, we will have created a DirectX context, rendered a
  640. mesh to the scene, and explored the Python concept of Duck Typing along the
  641. way.</p>
  642. <p class=Normal>&nbsp;</p>
  643. <h2><a name="_Toc140655639">Setting up DirectX</a></h2>
  644. <p class=Normal>This section will deal exclusively with the SceneManager
  645. class.  The first thing we need to do is initialize a few variables which we
  646. will be using in this code.  Be sure to always remove the pass statement when
  647. we add code to empty methods.</p>
  648. <p class=Normal>&nbsp;</p>
  649. <p class=Normal>We will add three variables:  The first will contain our
  650. DirectX device when we have created it.  The second will determine if the
  651. DirectX context is paused (in case we are minimized or hidden).  The third will
  652. be the background color for the DirectX rendering device.</p>
  653. <p class=Normal>&nbsp;</p>
  654. <div style='border:solid windowtext 1.0pt;padding:1.0pt 4.0pt 1.0pt 4.0pt;
  655. background:silver;margin-left:.25in;margin-right:.25in'>
  656. <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
  657. border:none;padding:0in'>class SceneManager(object):</p>
  658. <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
  659. border:none;padding:0in'>    def __init__(self):</p>
  660. <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
  661. border:none;padding:0in'>        self.Device = None</p>
  662. <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
  663. border:none;padding:0in'>        self.Paused = False</p>
  664. <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
  665. border:none;padding:0in'>        self.Background = System.Drawing.Color.Black</p>
  666. </div>
  667. <p class=Normal>&nbsp;</p>
  668. <p class=Normal>Next we will fill in the InitGraphics method.  This
  669. section of code creates the DirectX device we will use in this tutorial.</p>
  670. <p class=Normal>&nbsp;</p>
  671. <p class=Normal>The first thing we will do is set up the parameters that we
  672. will pass to DirectX.  We will set DirectX to be in windowed mode, set the swap
  673. effect for drawing frames, and enable the auto depth stencil (so that DirectX
  674. tracks the depth of our objects for us).  For more information on the specifics
  675. on these properties and parameters, consult the DirectX documentation.  Since
  676. creating a DirectX device requires a window handle to place it in, we will take
  677. in a handle parameter to use this.</p>
  678. <p class=Normal>&nbsp;</p>
  679. <div style='border:solid windowtext 1.0pt;padding:1.0pt 4.0pt 1.0pt 4.0pt;
  680. background:silver;margin-left:.25in;margin-right:.25in'>
  681. <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
  682. border:none;padding:0in'>    def InitGraphics(self, handle):</p>
  683. <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
  684. border:none;padding:0in'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; params = Direct3D.PresentParameters()</p>
  685. <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
  686. border:none;padding:0in'>        params.Windowed = True</p>
  687. <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
  688. border:none;padding:0in'>        params.SwapEffect =
  689. Direct3D.SwapEffect.Discard</p>
  690. <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
  691. border:none;padding:0in'>        params.EnableAutoDepthStencil = True</p>
  692. <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
  693. border:none;padding:0in'>        params.AutoDepthStencilFormat =
  694. Direct3D.DepthFormat.D16</p>
  695. </div>
  696. <p class=Normal>&nbsp;</p>
  697. <p class=Normal>Now we need to actually create the Direct3D device.  Note
  698. that we are passing in the handle parameter to the constructor of the Direct3D
  699. device.  This is what tells DirectX to use the window that we have created.  We
  700. also pass in the PresentParameters object we just created.   For more specifics
  701. on the Device creation parameters, consult the managed DirectX documentation. </p>
  702. <p class=Normal>&nbsp;</p>
  703. <div style='border:solid windowtext 1.0pt;padding:1.0pt 4.0pt 1.0pt 4.0pt;
  704. background:silver;margin-left:.25in;margin-right:.25in'>
  705. <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
  706. border:none;padding:0in'>        self.Device = Direct3D.Device(0,
  707. Direct3D.DeviceType.Hardware, handle,</p>
  708. <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
  709. border:none;padding:0in'>                                     
  710. Direct3D.CreateFlags.SoftwareVertexProcessing,</p>
  711. <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
  712. border:none;padding:0in'>                                      params)</p>
  713. </div>
  714. <p class=Normal>&nbsp;</p>
  715. <p class=Normal>After creating the device, we need to set a couple of
  716. properties on the Device.  The first thing we need to do is enable the
  717. ZBuffer.  If we did not do this, we could not draw in 3 dimensions (which is
  718. basically the point of this tutorial).  We also need to set the ambient light
  719. to be a full white.  There are multiple types of lighting which DirectX uses:
  720. diffuse, ambient, specular and emissive.  A full treatise on lighting would be
  721. far beyond the scope of this document.  For this tutorial we are going to
  722. simply set the ambient light to full (white), and force every mesh we load to
  723. use ambient lighting.  This, effectively, turns off lighting so we do not have
  724. to worry about it.</p>
  725. <p class=Normal>&nbsp;</p>
  726. <div style='border:solid windowtext 1.0pt;padding:1.0pt 4.0pt 1.0pt 4.0pt;
  727. background:silver;margin-left:.25in;margin-right:.25in'>
  728. <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
  729. border:none;padding:0in'>        self.Device.RenderState.ZBufferEnable =
  730. True</p>
  731. <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
  732. border:none;padding:0in'>        self.Device.RenderState.Ambient =
  733. Drawing.Color.White</p>
  734. </div>
  735. <p class=Normal>&nbsp;</p>
  736. <p class=Normal>&nbsp;</p>
  737. <p class=Normal>Next we need to set up two of the three matricies which
  738. DirectX uses to render the scene.  The Projection matrix is the most
  739. complicated.  It basically transforms the 3D matrix of objects into a 2
  740. dimensional plane to display on the screen.  We will not have to deal with this
  741. matrix after we have set it the first time.</p>
  742. <p class=Normal>&nbsp;</p>
  743. <p class=Normal>The second matrix DirectX uses is the View matrix which
  744. defines where the camera is looking.  DirectX has some very nice methods which
  745. allow us to deal with cameras in a very natural way.  The
  746. Matrix.LookAtLH takes in three parameters.  The first is the position
  747. of the camera.  The second is what the camera looks at.  The third is the up
  748. vector, which is the up direction for the camera.  Setting the up vector
  749. incorrectly would result in the scene being rotated in strange ways.</p>
  750. <p class=Normal>&nbsp;</p>
  751. <div style='border:solid windowtext 1.0pt;padding:1.0pt 4.0pt 1.0pt 4.0pt;
  752. background:silver;margin-left:.25in;margin-right:.25in'>
  753. <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
  754. border:none;padding:0in'>        self.Device.Transform.Projection =
  755. DirectX.Matrix.PerspectiveFovLH(System.Math.PI/4.0, 1, 1, 100)</p>
  756. <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
  757. border:none;padding:0in'>        self.Device.Transform.View =
  758. DirectX.Matrix.LookAtLH(DirectX.Vector3(<span style='font-size:10.0pt'>0,
  759. 3, -5</span>), DirectX.Vector3(0, 0, 0), DirectX.Vector3(0, 1, 0))</p>
  760. </div>
  761. <p class=Normal>&nbsp;</p>
  762. <p class=Normal>The rest of our code simply sets the Paused property to be
  763. false.  We will return true to indicate no error occurred.</p>
  764. <p class=Normal>&nbsp;</p>
  765. <div style='border:solid windowtext 1.0pt;padding:1.0pt 4.0pt 1.0pt 4.0pt;
  766. background:silver;margin-left:.25in;margin-right:.25in'>
  767. <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
  768. border:none;padding:0in'>        # ensure we are not paused</p>
  769. <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
  770. border:none;padding:0in'>        self.Paused = False</p>
  771. <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
  772. border:none;padding:0in'>        return True</p>
  773. </div>
  774. <p class=Normal>&nbsp;</p>
  775. <p class=Normal>The last thing we need to do is render the scene.  For now
  776. this code is very basic, but we will be adding to it later.  First, we only
  777. render if the Device has already been created and we are not paused.</p>
  778. <p class=Normal>&nbsp;</p>
  779. <div style='border:solid windowtext 1.0pt;padding:1.0pt 4.0pt 0in 4.0pt;
  780. background:silver;margin-left:.25in;margin-right:.25in'>
  781. <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
  782. border:none;padding:0in'>    def Render(self):</p>
  783. <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
  784. border:none;padding:0in'>        if self.Device is None or self.Paused:</p>
  785. <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
  786. border:none;padding:0in'>            return</p>
  787. </div>
  788. <p class=Normal>&nbsp;</p>
  789. <p class=Normal>At the beginning of each render, we clear the scene with a
  790. specific background color (which we set in the constructor).</p>
  791. <p class=Normal>&nbsp;</p>
  792. <div style='border:solid windowtext 1.0pt;padding:1.0pt 4.0pt 1.0pt 4.0pt;
  793. background:silver;margin-left:.25in;margin-right:.25in'>
  794. <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
  795. border:none;padding:0in'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.Device.Clear(Direct3D.ClearFlags.Target | Direct3D.ClearFlags.ZBuffer,</p>
  796. <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
  797. border:none;padding:0in'>           &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.Background, </p>
  798. <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
  799. border:none;padding:0in'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1, </p>
  800. <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
  801. border:none;padding:0in'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0)</p>
  802. <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
  803. border:none;padding:0in'>        self.Device.BeginScene()</p>
  804. <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
  805. border:none;padding:0in'>&nbsp;</p>
  806. <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
  807. border:none;padding:0in'>        # scene render here</p>
  808. <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
  809. border:none;padding:0in'>&nbsp;</p>
  810. <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
  811. border:none;padding:0in'>        self.Device.EndScene()</p>
  812. <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
  813. border:none;padding:0in'>        self.Device.Present()</p>
  814. </div>
  815. <p class=Normal>&nbsp;</p>
  816. <p class=Normal>Run the application.  We have now created a DirectX render
  817. loop in under 100 lines of IronPython code.  Now we need to make something
  818. useful out of it</p>
  819. <p class=Normal>&nbsp;</p>
  820. <h2><a name="_Toc140655640">Code Checkpoint 2</a></h2>
  821. <p class=Normal>Run your Python application.  At this point you should have
  822. the same window as the previous checkpoint, but with a black DirectX context. 
  823. If you are having problems with the code, you should compare your source file
  824. with checkpoint2.py.</p>
  825. <p class=Normal>&nbsp;</p>
  826. <h2><a name="_Toc140655641">An Introduction to Duck Typing</a></h2>
  827. <p class=Normal>&nbsp;</p>
  828. <p class=Normal>Now that we have an application running, what we need to do is
  829. load a mesh and render it in the scene.  To do this, DirectX needs four pieces
  830. of information: the Mesh, the World Matrix (to position the object), a list of
  831. materials, and a list of textures.  We will provide one extra constraint that
  832. we will use: every object we render in the scene will need a Name so that we
  833. can place it into a …

Large files files are truncated, but you can click here to view the full file