/Languages/IronPython/Samples/Direct3D/readme.htm
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
- <html>
- <head>
- <meta http-equiv=Content-Type content="text/html; charset=windows-1252">
- <meta name=Generator content="Microsoft Word 12 (filtered)">
- <title>3D Graphics in IronPython</title>
- <style>
- <!--
- /* Font Definitions */
- @font-face
- {font-family:"Cambria Math";
- panose-1:2 4 5 3 5 4 6 3 2 4;}
- @font-face
- {font-family:Tahoma;
- panose-1:2 11 6 4 3 5 4 4 2 4;}
- @font-face
- {font-family:Consolas;
- panose-1:2 11 6 9 2 2 4 3 2 4;}
- /* Style Definitions */
- span.MsoHyperlink
- {color:blue;
- text-decoration:underline;}
- p.Offset, div.Offset
- {
- mso-style-name: Offset;
- margin-top: 0in;
- margin-right: .5in;
- margin-bottom: 0in;
- margin-left: .5in;
- margin-bottom: .0001pt;
- border: none;
- padding: 0in;
- font-size: 12.0pt;
- font-family: Verdana;
- }
- p.OffsetHeader, div.OffsetHeader
- {
- mso-style-name: "Offset Header";
- margin-top: 0in;
- margin-right: .5in;
- margin-bottom: 0in;
- margin-left: .5in;
- margin-bottom: .0001pt;
- text-align: center;
- border: none;
- padding: 0in;
- font-size: 12.0pt;
- font-family: Verdana;
- font-weight: bold;
- }
- @page Section1
- {size:8.5in 11.0in;
- margin:1.0in 1.25in 1.0in 1.25in;}
- /* List Definitions */
- -->
- </style>
- <link rel="stylesheet" type="text/css" href="../Samples.css">
- </head>
- <body lang=EN-US link=blue vlink=purple>
- <div class=Section1>
- <hr />
- <p class="CopyrightText">
- Information in this document is subject to change without notice. The example companies,
- organizations, products, people, and events depicted herein are fictitious. No association
- with any real company, organization, product, person or event is intended or should
- be inferred. Complying with all applicable copyright laws is the responsibility
- of the user. Without limiting the rights under copyright, no part of this document
- may be reproduced, stored in or introduced into a retrieval system, or transmitted
- in any form or by any means (electronic, mechanical, photocopying, recording, or
- otherwise), or for any purpose, without the express written permission of Microsoft
- Corporation.</p>
- <p class="CopyrightText">
- </p>
- <p class="CopyrightText">
- Microsoft may have patents, patent applications, trademarked, copyrights, or other
- intellectual property rights covering subject matter in this document. Except as
- expressly provided in any written license agreement from Microsoft, the furnishing
- of this document does not give you any license to these patents, trademarks, copyrights,
- or other intellectual property.</p>
- <p class="CopyrightText">
- </p>
- <div class="Section1">
- <p class="CopyrightText">© Microsoft Corporation. All rights
- reserved.</p>
- <p class="CopyrightText"> </p>
- <p class="CopyrightText">Microsoft, MS-DOS, MS, Windows, Windows NT,
- MSDN, Active Directory, BizTalk, SQL Server, SharePoint, Outlook, PowerPoint, FrontPage, Visual Basic,
- Visual C++, Visual J++, Visual InterDev, Visual SourceSafe, Visual C#, Visual J#, and Visual Studio
- are either registered trademarks or trademarks of Microsoft Corporation in the U.S.A. and/or other
- countries.</p>
- <p class="CopyrightText"> </p>
- <p class="CopyrightText">Other product and company names herein may
- be the trademarks of their respective owners.</div>
- <hr>
- <p class="body"> </p>
- <p class="CopyrightText">This source code is subject to terms and conditions of the Apache License, Version 2.0. A
- copy of the license can be found in the License.html file at the root of this distribution. If
- you cannot locate the Apache License, Version 2.0, please send an email to
- ironpy@microsoft.com. By using this source code in any fashion, you are agreeing to be bound
- by the terms of the Apache License, Version 2.0.</p>
- <p class="CopyrightText">
- </p>
- <p class="CopyrightText">
- </p>
- <p class=Normal><b>
- <span style='font-size:16.0pt;font-family:"Arial","sans-serif"'>3D
- Graphics in IronPython</span></b></p>
- <p class=Normal><span style='font-size:14.0pt;font-family:"Arial","sans-serif"'>A
- Flexible DirectX Framework in IronPython</span></p>
- <p class=Normal><span style='font-size:14.0pt;font-family:"Arial","sans-serif"'>By
- Lee Culver</span></p>
- <p class=Normal><span style='font-size:10.0pt;font-family:"Courier New"'> </span></p>
- <p class=Normal><span style='font-size:10.0pt;font-family:"Courier New"'> </span></p>
- <p class=Toc1><span
- class=MsoHyperlink><a href="#_Toc140655628">Getting Started<span
- style='color:windowtext;display:none;text-decoration:none'>. 2</span></a></span></p>
- <p class=Toc2><span class=MsoHyperlink><a href="#_Toc140655629">Introduction<span
- style='color:windowtext;display:none;text-decoration:none'>. 2</span></a></span></p>
- <p class=Toc2><span class=MsoHyperlink><a href="#_Toc140655630">Prerequisites<span
- style='color:windowtext;display:none;text-decoration:none'>. 2</span></a></span></p>
- <p class=Toc2><span class=MsoHyperlink><a href="#_Toc140655631">How to Use
- this Tutorial<span style='color:windowtext;display:none;text-decoration:none'> 2</span></a></span></p>
- <p class=Toc2><span class=MsoHyperlink><a href="#_Toc140655632">Objectives
- for this Tutorial<span style='color:windowtext;display:none;text-decoration:
- none'> </span><span
- style='color:windowtext;display:none;text-decoration:none'>2</span></a></span></p>
- <p class=Toc2><span class=MsoHyperlink><a href="#_Toc140655633">Final Note<span
- style='color:windowtext;display:none;text-decoration:none'>. 2</span></a></span></p>
- <p class=Toc1><span class=MsoHyperlink><a href="#_Toc140655634">Creating the
- Framework for a DirectX Application<span style='color:windowtext;display:none;
- text-decoration:none'>. </span><span
- style='color:windowtext;display:none;text-decoration:none'>3</span></a></span></p>
- </div>
- <p class=Toc2><span class=MsoHyperlink><a href="#_Toc140655635">Loading
- Assemblies and Importing Them<span style='color:windowtext;display:none;
- text-decoration:none'>.. </span>
- <span
- style='color:windowtext;display:none;text-decoration:none'>3</span></a></span></p>
- <div class=Section1>
- <p class=Toc2><span class=MsoHyperlink><a href="#_Toc140655636">The
- RenderWindow Class<span style='color:windowtext;display:none;text-decoration:
- none'>. </span><span
- style='color:windowtext;display:none;text-decoration:none'>4</span></a></span></p>
- <p class=Toc2><span class=MsoHyperlink><a href="#_Toc140655637">Code
- Checkpoint 1<span style='color:windowtext;display:none;text-decoration:none'>. 6</span></a></span></p>
- <p class=Toc1><span class=MsoHyperlink><a href="#_Toc140655638">Your First
- DirectX Application (in IronPython)<span style='color:windowtext;display:none;
- text-decoration:none'> </span><span
- style='color:windowtext;display:none;text-decoration:none'>6</span></a></span></p>
- <p class=Toc2><span class=MsoHyperlink><a href="#_Toc140655639">Setting up
- DirectX<span style='color:windowtext;display:none;text-decoration:none'>.. 6</span></a></span></p>
- <p class=Toc2><span class=MsoHyperlink><a href="#_Toc140655640">Code
- Checkpoint 2<span style='color:windowtext;display:none;text-decoration:none'>. 9</span></a></span></p>
- <p class=Toc2><span class=MsoHyperlink><a href="#_Toc140655641">An
- Introduction to Duck Typing<span style='color:windowtext;display:none;
- text-decoration:none'>. </span><span
- style='color:windowtext;display:none;text-decoration:none'>9</span></a></span></p>
- <p class=Toc2><span class=MsoHyperlink><a href="#_Toc140655642">Loading
- Meshes<span style='color:windowtext;display:none;text-decoration:none'>. 10</span></a></span></p>
- <p class=Toc2><span class=MsoHyperlink><a href="#_Toc140655643">Rendering
- Meshes<span style='color:windowtext;display:none;text-decoration:none'>. 11</span></a></span></p>
- <p class=Toc2><span class=MsoHyperlink><a href="#_Toc140655644">Code
- Checkpoint 3<span style='color:windowtext;display:none;text-decoration:none'>. 13</span></a></span></p>
- <p class=Toc1><span class=MsoHyperlink><a href="#_Toc140655645">Cameras,
- Moving Objects, and Events<span style='color:windowtext;display:none;
- text-decoration:none'>. </span><span
- style='color:windowtext;display:none;text-decoration:none'>13</span></a></span></p>
- <p class=Toc2><span class=MsoHyperlink><a href="#_Toc140655646">The Event
- System<span style='color:windowtext;display:none;text-decoration:none'>.. 14</span></a></span></p>
- <p class=Toc2><span class=MsoHyperlink><a href="#_Toc140655647">Code
- Checkpoint 4<span style='color:windowtext;display:none;text-decoration:none'>. 17</span></a></span></p>
- <p class=Toc2><span class=MsoHyperlink><a href="#_Toc140655648">Exercises<span
- style='color:windowtext;display:none;text-decoration:none'>. 17</span></a></span></p>
- <p class=Toc2><span class=MsoHyperlink><a href="#_Toc140655649">Moving
- Objects on Screen<span style='color:windowtext;display:none;text-decoration:
- none'>. </span><span
- style='color:windowtext;display:none;text-decoration:none'>17</span></a></span></p>
- <p class=Toc2><span class=MsoHyperlink><a href="#_Toc140655650">Rotating
- Objects on the Screen<span style='color:windowtext;display:none;text-decoration:
- none'>. </span><span
- style='color:windowtext;display:none;text-decoration:none'>20</span></a></span></p>
- <p class=Toc2><span class=MsoHyperlink><a href="#_Toc140655651">Putting it
- All Together<span style='color:windowtext;display:none;text-decoration:none'> 20</span></a></span></p>
- <p class=Toc2><span class=MsoHyperlink><a href="#_Toc140655652">Cameras<span
- style='color:windowtext;display:none;text-decoration:none'>. 21</span></a></span></p>
- <p class=Toc2><span class=MsoHyperlink><a href="#_Toc140655653">Code
- Checkpoint<span style='color:windowtext;display:none;text-decoration:none'> 23</span></a></span></p>
- <p class=Toc2><span class=MsoHyperlink><a href="#_Toc140655654">Exercises<span
- style='color:windowtext;display:none;text-decoration:none'>. 23</span></a></span></p>
- <p class=Toc2><span class=MsoHyperlink><a href="#_Toc140655655">Framework
- Optimization<span style='color:windowtext;display:none;text-decoration:none'>. 24</span></a></span></p>
- <p class=Toc2><span class=MsoHyperlink><a href="#_Toc140655656">Adding Other
- Types of Objects<span style='color:windowtext;display:none;text-decoration:
- none'>. </span><span
- style='color:windowtext;display:none;text-decoration:none'>26</span></a></span></p>
- <p class=Toc2><span class=MsoHyperlink><a href="#_Toc140655657">A Better
- Main Function<span style='color:windowtext;display:none;text-decoration:none'>. 28</span></a></span></p>
- <p class=Toc2><span class=MsoHyperlink><a href="#_Toc140655658">Code Checkpoint
- 6<span style='color:windowtext;display:none;text-decoration:none'>. 29</span></a></span></p>
- <p class=Toc1><span class=MsoHyperlink><a href="#_Toc140655659">Cool Things
- to Do with the Project<span style='color:windowtext;display:none;text-decoration:
- none'> </span><span
- style='color:windowtext;display:none;text-decoration:none'>30</span></a></span></p>
- <p class=Toc2><span class=MsoHyperlink><a href="#_Toc140655660">Moving
- Objects Around, Part I<span style='color:windowtext;display:none;text-decoration:
- none'>. </span><span
- style='color:windowtext;display:none;text-decoration:none'>30</span></a></span></p>
- <p class=Toc2><span class=MsoHyperlink><a href="#_Toc140655661">Moving
- Objects Around, Part II<span style='color:windowtext;display:none;text-decoration:
- none'>. </span><span
- style='color:windowtext;display:none;text-decoration:none'>31</span></a></span></p>
- <p class=Toc2><span class=MsoHyperlink><a href="#_Toc140655662">Moving
- Objects Around, Part III<span style='color:windowtext;display:none;text-decoration:
- none'>. </span><span
- style='color:windowtext;display:none;text-decoration:none'>33</span></a></span></p>
- <p class=Toc2><span class=MsoHyperlink><a href="#_Toc140655663">Auto
- Tracking<span style='color:windowtext;display:none;text-decoration:none'>. 35</span></a></span></p>
- <p class=Toc2><span class=MsoHyperlink><a href="#_Toc140655664">Gravity and
- Free Floating Bodies<span style='color:windowtext;display:none;text-decoration:
- none'>. </span><span
- style='color:windowtext;display:none;text-decoration:none'>36</span></a></span></p>
- <p class=Toc1><span class=MsoHyperlink><a href="#_Toc140655665">Where to Go
- from Here<span style='color:windowtext;display:none;text-decoration:none'>. 40</span></a></span></p>
- <p class=Toc2><span class=MsoHyperlink><a href="#_Toc140655666">Managed
- DirectX and XNA<span style='color:windowtext;display:none;text-decoration:none'>.. 40</span></a></span></p>
- <p class=Toc2><span class=MsoHyperlink><a href="#_Toc140655667">IronPython<span
- style='color:windowtext;display:none;text-decoration:none'>. 41</span></a></span></p>
- <p class=Toc2><span class=MsoHyperlink><a href="#_Toc140655668">Extending
- the Framework<span style='color:windowtext;display:none;text-decoration:none'>. 41</span></a></span></p>
- <p class=Normal><span style='font-size:10.0pt;font-family:"Courier New"'> </span></p>
- <p class=Normal><span style='font-size:10.0pt;font-family:"Courier New"'> </span></p>
- <h1><a name="_Toc140655628">Getting Started</a></h1>
- <p class=Normal> </p>
- <h2><a name="_Toc140655629">Introduction</a></h2>
- <p class=Normal>In this tutorial we will be creating a highly flexible
- Python graphical framework as an introduction to IronPython. By the end of
- this tutorial you will have a better understanding of IronPython, a basic grasp
- of DirectX, and a better understanding of how IronPython utilizes and interacts
- with the .NET framework. </p>
- <h2><a name="_Toc140655630">Prerequisites</a></h2>
- <p class=Normal>This tutorial assumes only a basic knowledge of the Python
- syntax and how to use some of its basic constructs (such as lists and tuples).
- No prior knowledge of DirectX or Windows.Forms is required, though a basic
- grasp of the .Net platform will go a long way to understanding a few sections
- of code.</p>
- <p class=Normal> </p>
- <p class=Normal>We will be building this application from scratch, and all
- portions of the code will be fully explained. Note that if you are already
- familiar with Python, you should probably skip the sections labeled “For Python
- Beginners.”</p>
- <p class=Normal> </p>
- <p class="body">
- Further, you will need the following:</p>
- <ul>
- <li class="normal">IronPython 2.6 distribution
- <ul>
- <li>If you are new to IronPython, please go over the tutorial
- that comes with this distribution</li>
- <li>Download from
- <a href="http://ironpython.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=12482">here</a></li>
- </ul>
- </li>
- <li class="normal">DirectX End-user Runtime and a compatible video card<ul>
- <li>Download from
- <a href="http://www.microsoft.com/games/en-US/aboutgfw/Pages/directx10-a.aspx">here</a>.</li>
- </ul>
- </li>
- </ul>
- <p class=Normal> </p><p class=Normal><b><font size="3">Important Note </font></b></p>
- <p class=Normal>If you've previously installed a DirectX SDK there's a good chance you might have the
- Managed DirectX 2.0 Beta assembly installed. This assembly is incompatible with the Python sample code
- distributed with this tutorial and cannot be uninstalled. If you experience difficulties running the
- samples (particularly when there are error messages stating that the <i>Matrix</i> class has no
- <i>LookAtLH</i> method) and are sure you meet the prerequisites above, please replace all occurrences
- of:</p><p class=Normal><b> </b><i>clr.AddReference(“Microsoft.DirectX”)</i></p>
- <p class=Normal>with:</p><p class=Normal><b> </b><i>clr.AddReferenceByName('Microsoft.DirectX, Version=1.0.2902.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35')</i></p>
- <p class=Normal> </p><p class=Normal>throughout the samples. This change basically means that the
- sample code will use Managed DirectX 1 instead of the 2.0 beta which would normally have precedence.</p>
- <h2><a name="_Toc140655631">How to Use this Tutorial</a></h2>
- <p class=Normal>This tutorial will start from a small set of code and slowly
- build a full framework from scratch. Throughout this tutorial you should be
- slowly adding code to a Python source file of your own and watching the results
- as we build it. There is no substitute for actual programming; I highly
- recommend that you resist the urge to simply read along.</p>
- <p class=Normal> </p>
- <h2><a name="_Toc140655632">Objectives for this Tutorial</a></h2>
- <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
- them inside of a .NET form. The framework will provide methods for positioning and rotating objects and the camera, as well as examples of using the
- framework to implement more advanced functionality such as having objects move around a track and have cameras auto-track objects in the scene. Lastly, we
- will implement a small scale demo which demonstrates Newton’s law of universal
- gravitation, which will allow you to specify an arbitrary number of free
- floating bodies in space (planets), and watch them interact with each other.</p>
- <p class=Normal> </p>
- <h2><a name="_Toc140655633">Final Note</a></h2>
- <p class=Normal>Throughout this tutorial be very careful to keep the same
- indentation levels that have been used here. In Python, white space is a part of
- the language, and you must take care to ensure that everything is correctly
- aligned or you will receive errors. I suggest setting your text editor of
- choice to use 4 spaces instead of tabs (which I have done for all code
- presented here).</p>
- <p class=Normal> </p>
- <p class=Normal>Lastly, if you are getting compile errors, check to make
- sure you have not inserted extra returns in the middle of statements. The code
- may be slightly skewed if you have word wrap turned on.</p>
- <p class=Normal> </p>
- <h1><a name="_Toc140655634">Creating the Framework for a DirectX Application</a></h1>
- <p class=Normal> </p>
- <h3><a name="_Toc140655635">Loading Assemblies and Importing Them</a></h3>
- <p class=Normal> </p>
- <p class=Normal>The first thing we will do is add a few references to
- assemblies we will be using. Create a new file called “tutorial.py” and add
- the following code to it:</p>
- <p class=Normal> </p>
- <div style='border:solid windowtext 1.0pt;padding:1.0pt 4.0pt 1.0pt 4.0pt;
- background:silver;margin-left:.25in;margin-right:.25in'>
- <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
- border:none;padding:0in'>import clr</p>
- <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
- border:none;padding:0in'>clr.AddReferenceByPartialName("System.Drawing")</p>
- <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
- border:none;padding:0in'>clr.AddReferenceByPartialName("System.Windows.Forms")</p>
- <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
- border:none;padding:0in'>clr.AddReferenceByPartialName("Microsoft.DirectX")</p><p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
- border:none;padding:0in'>clr.AddReferenceByPartialName("Microsoft.DirectX.Direct3D")<span style="background-color: #C0C0C0; background-position: 0% 0%"><br>
- </span>clr.AddReferenceByPartialName("Microsoft.DirectX.Direct3DX")</p>
- </div>
- <p class=Normal> </p>
- <p class=Normal>If you do not add the reference to assemblies that you use,
- the IronPython interpreter will not know how to load them. If you run into
- problems where an import statement does not give the expected results, check to
- make sure you have referenced all of the appropriate assemblies first. Note
- that IronPython automatically adds the “System” library.</p><p class=Normal> </p><p class=Normal>If you encounter
- difficulties running the snippet of code above, please see the <b>Important Notes</b> section in the
- <a href="#_Toc140655630">Prerequisites</a>.</p>
- <p class=Normal> </p>
- <div>
- <table cellspacing=0 cellpadding=0 hspace=0 vspace=0 align=right>
- <tr>
- <td valign=top align=left style='padding-top:0in;padding-right:0in;
- padding-bottom:0in;padding-left:0in'>
- <div style='border:solid windowtext 1.0pt;padding:1.0pt 4.0pt 1.0pt 4.0pt;
- margin-left:.5in;margin-right:.5in'>
- <p class=OffsetHeader style='margin:0in;margin-bottom:.0001pt;border:none;
- padding:0in'>New to IronPython?</p>
- <p class=Offset style='margin:0in;margin-bottom:.0001pt;border:none;
- padding:0in'>The clr import is not just a library; it actually changes the
- dynamics of several basic constructs. To see this first hand, open up a
- fresh IronPython interpreter and run this code:</p>
- <p class=Offset style='margin:0in;margin-bottom:.0001pt;border:none;
- padding:0in'> </p>
- <p class=Offset style='margin:0in;margin-bottom:.0001pt;border:none;
- padding:0in'><span style='font-size:10.0pt;font-family:"Courier New"'>print
- dir([])</span></p>
- <p class=Offset style='margin:0in;margin-bottom:.0001pt;border:none;
- padding:0in'><span style='font-size:10.0pt;font-family:"Courier New"'>import
- clr</span></p>
- <p class=Offset style='margin:0in;margin-bottom:.0001pt;border:none;
- padding:0in'><span style='font-size:10.0pt;font-family:"Courier New"'>print
- dir([])</span></p>
- <p class=Offset style='margin:0in;margin-bottom:.0001pt;border:none;
- padding:0in'><span style='font-size:10.0pt;font-family:"Courier New"'> </span></p>
- <p class=Offset style='margin:0in;margin-bottom:.0001pt;border:none;
- padding:0in'>Notice that it adds a number of functions which makes IronPython
- very similar to .NET (though all of the Python functions are still there).
- This also replaces the standard Python string with the .Net string class.
- Throughout this tutorial I will be using the IronPython methods instead of
- the standard Python methods as this produces a more consistent code base.</p>
- </div>
- </td>
- </tr>
- </table>
- </div>
- <br clear=ALL>
- <p class=Normal> </p>
- <p class=Normal>Next we will import all of the libraries we will need for
- this tutorial.</p>
- <p class=Normal> </p>
- <div style='border:solid windowtext 1.0pt;padding:1.0pt 4.0pt 1.0pt 4.0pt;
- background:silver;margin-left:.25in;margin-right:.25in'>
- <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
- border:none;padding:0in'>import System</p>
- <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
- border:none;padding:0in'>from System import Drawing</p>
- <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
- border:none;padding:0in'>from System.Windows import Forms</p>
- <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
- border:none;padding:0in'>from Microsoft import DirectX</p>
- <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
- border:none;padding:0in'>from Microsoft.DirectX import Direct3D</p>
- </div>
- <p class=Normal> </p>
- <p class=Normal>In this tutorial I have kept namespaces and never imported
- everything into the global namespace. This will make the rest of the tutorial
- slightly more verbose, but it will also be very explicit as to which functions
- we are calling.</p>
- <p class=Normal> </p>
- <h3><a name="_Toc140655636">The RenderWindow Class</a></h3>
- <p class=Normal> </p>
- <p class=Normal>The next thing we need to do is to create a new Form to
- house our application. In IronPython we can natively derive from any .Net
- class which is not sealed or a value type. We will define a constructor which
- takes in a single argument (a class which contains a “Paused” attribute).
- Though I am calling this variable sceneManager here, and we will be providing a
- class called SceneManager later, we could easily swap it for any other class
- which understands how to pause and unpause the system:</p>
- <p class=Normal><span style='font-size:10.0pt;font-family:"Courier New"'> </span></p>
- <div style='border:solid windowtext 1.0pt;padding:1.0pt 4.0pt 1.0pt 4.0pt;
- background:silver;margin-left:.25in;margin-right:.25in'>
- <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
- border:none;padding:0in'>class RenderWindow(Forms.Form):</p>
- <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
- border:none;padding:0in'> def __init__(self, sceneManager):</p>
- <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
- border:none;padding:0in'> self.SceneManager = sceneManager</p>
- <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
- border:none;padding:0in'> self.Text = "IronPython Direct3D"</p>
- <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
- border:none;padding:0in'> self.ClientSize = Drawing.Size(640, 480)</p>
- </div>
- <p class=Normal> </p>
- <p class=Normal>Here we have set our own instance variable SceneManager to
- be the sceneManager variable that was passed in. We have also set the “Text”
- and “ClientSize” properties, which are properties defined by the Forms.Form
- class.</p>
- <p class=Normal> </p>
- <div>
- <table cellspacing=0 cellpadding=0 hspace=0 vspace=0 align=right>
- <tr>
- <td valign=top align=left style='padding-top:0in;padding-right:0in;
- padding-bottom:0in;padding-left:0in'>
- <div style='border:solid windowtext 1.0pt;padding:1.0pt 4.0pt 1.0pt 4.0pt;
- margin-left:.5in;margin-right:.5in'>
- <p class=OffsetHeader style='margin:0in;margin-bottom:.0001pt;border:none;
- padding:0in'>New to Python?</p>
- <p class=Offset style='margin:0in;margin-bottom:.0001pt;border:none;
- padding:0in'>When defining a class’s method in Python, you always add a
- parameter for the object you are currently operating on. In languages such
- as C# or C++ this parameter is implicitly passed as the “this” parameter.
- Note that we cannot access a class’s member methods or data without using
- this self parameter.</p>
- </div>
- </td>
- </tr>
- </table>
- </div>
- <br clear=ALL>
- <p class=Normal> </p>
- <p class=Normal>Next, we want our window to close (and the application to
- exit) whenever the escape key is pressed. We will override the OnKeyDown
- method of Forms.Form to do this.</p>
- <p class=Normal> </p>
- <div style='border:solid windowtext 1.0pt;padding:1.0pt 4.0pt 1.0pt 4.0pt;
- background:silver;margin-left:.25in;margin-right:.25in'>
- <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
- border:none;padding:0in'> def OnKeyDown(self, args):</p>
- <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
- border:none;padding:0in'> if args.KeyCode ==
- System.Windows.Forms.Keys.Escape:</p>
- <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
- border:none;padding:0in'> self.Dispose()</p>
- </div>
- <p class=Normal> </p>
- <p class=Normal>Finally, we want the application to pause and stop rendering
- any time the application is minimized or not visible. For now we will set the
- Paused variable on the SceneManager variable we have created. We will actually
- implement the code for this later.</p>
- <p class=Normal> </p>
- <div style='border:solid windowtext 1.0pt;padding:1.0pt 4.0pt 1.0pt 4.0pt;
- background:silver;margin-left:.25in;margin-right:.25in'>
- <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
- border:none;padding:0in'> def OnResize(self, args):</p>
- <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
- border:none;padding:0in'> self.SceneManager.Paused = not self.Visible or
- \</p>
- <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
- border:none;padding:0in'> (self.WindowState ==
- Forms.FormWindowState.Minimized)</p>
- </div>
- <p class=Normal> </p>
- <p class=Normal>Next we are going to add the shell of the SceneManager
- class. The first three methods are very simple (and we will revisit their
- implementations later). The first is the constructor, the second is a method
- which sets up DirectX, and the third is the Render method, which is called
- from within our render loop. We will cover these in detail later.</p>
- <p class=Normal> </p>
- <div style='border:solid windowtext 1.0pt;padding:1.0pt 4.0pt 1.0pt 4.0pt;
- background:silver;margin-left:.25in;margin-right:.25in'>
- <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
- border:none;padding:0in'>class SceneManager(object):</p>
- <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
- border:none;padding:0in'> def __init__(self):</p>
- <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
- border:none;padding:0in'> pass</p>
- <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
- border:none;padding:0in'> </p>
- <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
- border:none;padding:0in'> def InitGraphics(self, handle):</p>
- <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
- border:none;padding:0in'> return True</p>
- <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
- border:none;padding:0in'> </p>
- <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
- border:none;padding:0in'> def Render(self):</p>
- <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
- border:none;padding:0in'> pass</p>
- </div>
- <p class=Normal> </p>
- <div>
- <table cellspacing=0 cellpadding=0 hspace=0 vspace=0 align=right>
- <tr>
- <td valign=top align=left style='padding-top:0in;padding-right:0in;
- padding-bottom:0in;padding-left:0in'>
- <div style='border:solid windowtext 1.0pt;padding:1.0pt 4.0pt 1.0pt 4.0pt;
- margin-left:.5in;margin-right:.5in'>
- <p class=OffsetHeader style='margin:0in;margin-bottom:.0001pt;border:none;
- padding:0in'>New to Python?</p>
- <p class=Offset style='margin:0in;margin-bottom:.0001pt;border:none;
- padding:0in'>Whenever we define a method or class which has no body, we
- always must use the pass keyword. This keyword has no meaning outside of
- saying “empty code block.”</p>
- <p class=Offset style='margin:0in;margin-bottom:.0001pt;border:none;
- padding:0in'> </p>
- <p class=Offset style='margin:0in;margin-bottom:.0001pt;border:none;
- padding:0in'>Note that we have returned True from InitGraphics. One
- important thing to note about Python is that any time you do not return a
- value, you are implicitly returning the None type (which is roughly
- equivalent to null, with a few exceptions). This is why you will see some
- code paths in Python which have return statements and some which do not.
- This is perfectly valid, and generally accepted as normal.</p>
- </div>
- </td>
- </tr>
- </table>
- </div>
- <br clear=ALL>
- <p class=Normal> </p>
- <p class=Normal>Next we need to create the render loop for the application.
- This loop will pump the Windows.Forms event queue and call the Render method:</p>
- <p class=Normal style='text-autospace:none'><span style='font-size:10.0pt;
- font-family:Consolas'> </span></p>
- <div style='border:solid windowtext 1.0pt;padding:1.0pt 4.0pt 1.0pt 4.0pt;
- background:silver;margin-left:.25in;margin-right:.25in'>
- <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
- border:none;padding:0in'> def Go(self, window):</p>
- <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
- border:none;padding:0in'> while window.Created:</p>
- <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
- border:none;padding:0in'> self.Render()</p>
- <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
- border:none;padding:0in'> Forms.Application.DoEvents()</p>
- </div>
- <p class=Normal><span style='font-size:10.0pt;font-family:Consolas'> </span></p>
- <p class=Normal>Finally, we will create the main function which creates the
- basic objects and starts the render loop.</p>
- <p class=Normal> </p>
- <div style='border:solid windowtext 1.0pt;padding:1.0pt 4.0pt 1.0pt 4.0pt;
- background:silver;margin-left:.25in;margin-right:.25in'>
- <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
- border:none;padding:0in'>def main():</p>
- <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
- border:none;padding:0in'> sceneManager = SceneManager()</p>
- <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
- border:none;padding:0in'> window = RenderWindow(sceneManager)</p>
- <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
- border:none;padding:0in'> </p>
- <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
- border:none;padding:0in'> if not sceneManager.InitGraphics(window.Handle):</p>
- <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
- border:none;padding:0in'> Forms.MessageBox.Show("Could not init
- Direct3D.")</p>
- <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
- border:none;padding:0in'> </p>
- <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
- border:none;padding:0in'> else:</p>
- <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
- border:none;padding:0in'> window.Show()</p>
- <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
- border:none;padding:0in'> sceneManager.Go(window)</p>
- <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
- border:none;padding:0in'> </p>
- <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
- border:none;padding:0in'>if __name__ == '__main__':</p>
- <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
- border:none;padding:0in'> main()</p>
- </div>
- <p class=Normal> </p>
- <div>
- <table cellspacing=0 cellpadding=0 hspace=0 vspace=0 align=right>
- <tr>
- <td valign=top align=left style='padding-top:0in;padding-right:0in;
- padding-bottom:0in;padding-left:0in'>
- <div style='border:solid windowtext 1.0pt;padding:1.0pt 4.0pt 1.0pt 4.0pt;
- margin-left:.5in;margin-right:.5in'>
- <p class=OffsetHeader style='margin:0in;margin-bottom:.0001pt;border:none;
- padding:0in'>New to Python?</p>
- <p class=Offset style='margin:0in;margin-bottom:.0001pt;border:none;
- padding:0in'>In a Python script it is ok to have code which runs at the file
- level (that is, not inside of a function, not inside of a class). This code
- is run every time the code is imported. If you want to have the code run
- only when the module is explicitly ran (not imported) we use the built in
- __name__ variable to determine if we have been explicitly invoked from the
- command line. It will always equal ‘__main__’ if we have been run from the
- command line. If the module was loaded using the “import” statement,
- __name__ would be the name of the file otherwise.</p>
- <p class=Offset style='margin:0in;margin-bottom:.0001pt;border:none;
- padding:0in'> </p>
- <p class=Offset style='margin:0in;margin-bottom:.0001pt;border:none;
- padding:0in'>We have explicitly created a main function so that if this code
- is imported into an IronPython console, the main function can be invoked
- explicitly. If we replaced the call to main with the contents of the main
- function, there would be no way to run the code outside of actually running
- it from the command line (and not importing it). This is sometimes
- desirable, but not in our application. We will be using this much later in
- the tutorial when we actually import our framework from a separate file.</p>
- <p class=Offset style='margin:0in;margin-bottom:.0001pt;border:none;
- padding:0in'> </p>
- <p class=Offset style='margin:0in;margin-bottom:.0001pt;border:none;
- padding:0in'>Notice also that creating a class does not use the “new” keyword
- like C# and C++ do. The syntax for creating a new class is the exact same
- as calling a function. This is by design. In many cases we can use function
- calls and class constructors interchangeably when we are passing functions as
- parameters.</p>
- </div>
- </td>
- </tr>
- </table>
- </div>
- <br clear=ALL>
- <p class=Normal> </p>
- <p class=Normal> </p>
- <h2><a name="_Toc140655637">Code Checkpoint 1</a></h2>
- <p class=Normal> </p>
- <p class=Normal>Run the code from within IronPython. You should see an empty
- Windows.Forms window. If you are having problems with the code, you should
- compare your source file with checkpoint1.py.</p>
- <p class=Normal> </p>
- <h1><a name="_Toc140655638">Your First DirectX Application (in IronPython)</a></h1>
- <p class=Normal> </p>
- <p class=Normal>In this section we will create a basic scene in DirectX. By
- the end of this section, we will have created a DirectX context, rendered a
- mesh to the scene, and explored the Python concept of Duck Typing along the
- way.</p>
- <p class=Normal> </p>
- <h2><a name="_Toc140655639">Setting up DirectX</a></h2>
- <p class=Normal>This section will deal exclusively with the SceneManager
- class. The first thing we need to do is initialize a few variables which we
- will be using in this code. Be sure to always remove the “pass” statement when
- we add code to empty methods.</p>
- <p class=Normal> </p>
- <p class=Normal>We will add three variables: The first will contain our
- DirectX device when we have created it. The second will determine if the
- DirectX context is paused (in case we are minimized or hidden). The third will
- be the background color for the DirectX rendering device.</p>
- <p class=Normal> </p>
- <div style='border:solid windowtext 1.0pt;padding:1.0pt 4.0pt 1.0pt 4.0pt;
- background:silver;margin-left:.25in;margin-right:.25in'>
- <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
- border:none;padding:0in'>class SceneManager(object):</p>
- <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
- border:none;padding:0in'> def __init__(self):</p>
- <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
- border:none;padding:0in'> self.Device = None</p>
- <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
- border:none;padding:0in'> self.Paused = False</p>
- <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
- border:none;padding:0in'> self.Background = System.Drawing.Color.Black</p>
- </div>
- <p class=Normal> </p>
- <p class=Normal>Next we will fill in the InitGraphics method. This
- section of code creates the DirectX device we will use in this tutorial.</p>
- <p class=Normal> </p>
- <p class=Normal>The first thing we will do is set up the parameters that we
- will pass to DirectX. We will set DirectX to be in windowed mode, set the swap
- effect for drawing frames, and enable the auto depth stencil (so that DirectX
- tracks the depth of our objects for us). For more information on the specifics
- on these properties and parameters, consult the DirectX documentation. Since
- creating a DirectX device requires a window handle to place it in, we will take
- in a “handle” parameter to use this.</p>
- <p class=Normal> </p>
- <div style='border:solid windowtext 1.0pt;padding:1.0pt 4.0pt 1.0pt 4.0pt;
- background:silver;margin-left:.25in;margin-right:.25in'>
- <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
- border:none;padding:0in'> def InitGraphics(self, handle):</p>
- <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
- border:none;padding:0in'> params = Direct3D.PresentParameters()</p>
- <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
- border:none;padding:0in'> params.Windowed = True</p>
- <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
- border:none;padding:0in'> params.SwapEffect =
- Direct3D.SwapEffect.Discard</p>
- <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
- border:none;padding:0in'> params.EnableAutoDepthStencil = True</p>
- <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
- border:none;padding:0in'> params.AutoDepthStencilFormat =
- Direct3D.DepthFormat.D16</p>
- </div>
- <p class=Normal> </p>
- <p class=Normal>Now we need to actually create the Direct3D device. Note
- that we are passing in the handle parameter to the constructor of the Direct3D
- device. This is what tells DirectX to use the window that we have created. We
- also pass in the PresentParameters object we just created. For more specifics
- on the Device creation parameters, consult the managed DirectX documentation. </p>
- <p class=Normal> </p>
- <div style='border:solid windowtext 1.0pt;padding:1.0pt 4.0pt 1.0pt 4.0pt;
- background:silver;margin-left:.25in;margin-right:.25in'>
- <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
- border:none;padding:0in'> self.Device = Direct3D.Device(0,
- Direct3D.DeviceType.Hardware, handle,</p>
- <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
- border:none;padding:0in'>
- Direct3D.CreateFlags.SoftwareVertexProcessing,</p>
- <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
- border:none;padding:0in'> params)</p>
- </div>
- <p class=Normal> </p>
- <p class=Normal>After creating the device, we need to set a couple of
- properties on the Device. The first thing we need to do is enable the
- ZBuffer. If we did not do this, we could not draw in 3 dimensions (which is
- basically the point of this tutorial). We also need to set the ambient light
- to be a full white. There are multiple types of lighting which DirectX uses:
- diffuse, ambient, specular and emissive. A full treatise on lighting would be
- far beyond the scope of this document. For this tutorial we are going to
- simply set the ambient light to full (white), and force every mesh we load to
- use ambient lighting. This, effectively, turns off lighting so we do not have
- to worry about it.</p>
- <p class=Normal> </p>
- <div style='border:solid windowtext 1.0pt;padding:1.0pt 4.0pt 1.0pt 4.0pt;
- background:silver;margin-left:.25in;margin-right:.25in'>
- <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
- border:none;padding:0in'> self.Device.RenderState.ZBufferEnable =
- True</p>
- <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
- border:none;padding:0in'> self.Device.RenderState.Ambient =
- Drawing.Color.White</p>
- </div>
- <p class=Normal> </p>
- <p class=Normal> </p>
- <p class=Normal>Next we need to set up two of the three matricies which
- DirectX uses to render the scene. The Projection matrix is the most
- complicated. It basically transforms the 3D matrix of objects into a 2
- dimensional plane to display on the screen. We will not have to deal with this
- matrix after we have set it the first time.</p>
- <p class=Normal> </p>
- <p class=Normal>The second matrix DirectX uses is the View matrix which
- defines where the camera is looking. DirectX has some very nice methods which
- allow us to deal with cameras in a very natural way. The
- Matrix.LookAtLH takes in three parameters. The first is the position
- of the camera. The second is what the camera looks at. The third is the “up”
- vector, which is the up direction for the camera. Setting the up vector
- incorrectly would result in the scene being rotated in strange ways.</p>
- <p class=Normal> </p>
- <div style='border:solid windowtext 1.0pt;padding:1.0pt 4.0pt 1.0pt 4.0pt;
- background:silver;margin-left:.25in;margin-right:.25in'>
- <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
- border:none;padding:0in'> self.Device.Transform.Projection =
- DirectX.Matrix.PerspectiveFovLH(System.Math.PI/4.0, 1, 1, 100)</p>
- <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
- border:none;padding:0in'> self.Device.Transform.View =
- DirectX.Matrix.LookAtLH(DirectX.Vector3(<span style='font-size:10.0pt'>0,
- 3, -5</span>), DirectX.Vector3(0, 0, 0), DirectX.Vector3(0, 1, 0))</p>
- </div>
- <p class=Normal> </p>
- <p class=Normal>The rest of our code simply sets the Paused property to be
- false. We will return true to indicate no error occurred.</p>
- <p class=Normal> </p>
- <div style='border:solid windowtext 1.0pt;padding:1.0pt 4.0pt 1.0pt 4.0pt;
- background:silver;margin-left:.25in;margin-right:.25in'>
- <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
- border:none;padding:0in'> # ensure we are not paused</p>
- <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
- border:none;padding:0in'> self.Paused = False</p>
- <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
- border:none;padding:0in'> return True</p>
- </div>
- <p class=Normal> </p>
- <p class=Normal>The last thing we need to do is render the scene. For now
- this code is very basic, but we will be adding to it later. First, we only
- render if the Device has already been created and we are not paused.</p>
- <p class=Normal> </p>
- <div style='border:solid windowtext 1.0pt;padding:1.0pt 4.0pt 0in 4.0pt;
- background:silver;margin-left:.25in;margin-right:.25in'>
- <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
- border:none;padding:0in'> def Render(self):</p>
- <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
- border:none;padding:0in'> if self.Device is None or self.Paused:</p>
- <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
- border:none;padding:0in'> return</p>
- </div>
- <p class=Normal> </p>
- <p class=Normal>At the beginning of each render, we clear the scene with a
- specific background color (which we set in the constructor).</p>
- <p class=Normal> </p>
- <div style='border:solid windowtext 1.0pt;padding:1.0pt 4.0pt 1.0pt 4.0pt;
- background:silver;margin-left:.25in;margin-right:.25in'>
- <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
- border:none;padding:0in'> self.Device.Clear(Direct3D.ClearFlags.Target | Direct3D.ClearFlags.ZBuffer,</p>
- <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
- border:none;padding:0in'> self.Background, </p>
- <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
- border:none;padding:0in'> 1, </p>
- <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
- border:none;padding:0in'> 0)</p>
- <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
- border:none;padding:0in'> self.Device.BeginScene()</p>
- <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
- border:none;padding:0in'> </p>
- <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
- border:none;padding:0in'> # scene render here</p>
- <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
- border:none;padding:0in'> </p>
- <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
- border:none;padding:0in'> self.Device.EndScene()</p>
- <p class=Code-Highlighted style='margin:0in;margin-bottom:.0001pt;background:silver;
- border:none;padding:0in'> self.Device.Present()</p>
- </div>
- <p class=Normal> </p>
- <p class=Normal>Run the application. We have now created a DirectX render
- loop in under 100 lines of IronPython code. Now we need to make something
- useful out of it…</p>
- <p class=Normal> </p>
- <h2><a name="_Toc140655640">Code Checkpoint 2</a></h2>
- <p class=Normal>Run your Python application. At this point you should have
- the same window as the previous checkpoint, but with a black DirectX context.
- If you are having problems with the code, you should compare your source file
- with checkpoint2.py.</p>
- <p class=Normal> </p>
- <h2><a name="_Toc140655641">An Introduction to Duck Typing</a></h2>
- <p class=Normal> </p>
- <p class=Normal>Now that we have an application running, what we need to do is
- load a mesh and render it in the scene. To do this, DirectX needs four pieces
- of information: the Mesh, the World Matrix (to position the object), a list of
- materials, and a list of textures. We will provide one extra constraint that
- we will use: every object we render in the scene will need a Name so that we
- can place it into a …
Large files files are truncated, but you can click here to view the full file