| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982 |
- <html xmlns:MSHelp="http://msdn.microsoft.com/mshelp" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:xanx="http://schemas.microsoft.com/developer/xanx/2005"><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><meta name="save" content="history" /><title>Custom Model Class Sample</title>
- <style><!--
- /***********************************************************
- * SCRIPT-SUPPORTING STYLES
- ***********************************************************/
- /* Defines the userData cache persistence mechanism. */
- .userDataStyle
- {
- behavior: url(#default#userData);
- }
- /* Used to save the scroll bar position when navigating away from a page. */
- div.saveHistory
- {
- behavior: url(#default#saveHistory);
- }
- /* Formats the expand/collapse images for all collapsible regions. */
- img.toggle
- {
- border: 0;
- margin-right: 5;
- }
- /* Formats the Language filter drop-down image. */
- img#languageFilterImage
- {
- border: 0;
- margin-left: 0;
- vertical-align: middle;
- }
- /* Formats the Members Options filter drop-down image. */
- img#membersOptionsFilterImage
- {
- border: 0;
- margin-left: 0;
- vertical-align: middle;
- }
- /* Formats the Collapse All/Expand All images. */
- img#toggleAllImage
- {
- margin-left: 0;
- vertical-align: middle;
- }
- /* Supports XLinks */
- MSHelp\:link
- {
- text-decoration: underline;
- color: #0000ff;
- hoverColor: #3366ff;
- filterString: ;
- }
- body
- {
- background: #FFFFFF;
- color: #000000;
- font-family: Verdana;
- font-size: medium;
- font-style: normal;
- font-weight: normal;
- margin-top: 0;
- margin-bottom: 0;
- margin-left: 0;
- margin-right: 0;
- width: 100%;
- /*font-size: 110%;*/
- }
- div.section
- {
- margin-left: 15px;
- }
- div.hxnx5
- {
- margin-left: 1.5em;
- }
- /* Font for all headings */
- h1, h2, h3, h4, h5, h6
- {
- font-family: Verdana, Arial, Helvetica, sans-serif;
- margin-top: 18;
- margin-bottom: 8;
- font-weight: bold;
- }
- h1
- {
- font-size: 130%;
- color: #003399;
- }
- div#scrollyes h1 /* Changes font size for full-scrolling topic */
- {
- font-size: 150%;
- }
- h2
- {
- font-size: 122%;
- }
- h3
- {
- font-size: 115%;
- margin-top: 9;
- margin-bottom: 4;
- }
- h4
- {
- font-size: 115%;
- margin-top: 9;
- margin-bottom: 4;
- }
- h5
- {
- font-size: 100%;
- margin-top: 9;
- margin-bottom: 4;
- }
- h6
- {
- font-size: 100%;
- margin-top: 9;
- margin-bottom: 4;
- }
- ul p, ol p, dl p
- {
- margin-left: 0em;
- }
- p
- {
- margin-top: .6em;
- margin-bottom: .6em;
- }
-
- td p
- {
- margin-top: 0.0em;
- margin-bottom: 0.6em;
- }
- dd p
- {
- margin-top: 0.0em;
- margin-bottom: 0.6em;
- }
- .image
- {
- text-align: center;
- }
- dl
- {
- margin-top: 0em;
- margin-bottom: 1.3em;
- }
- dd
- {
- margin-bottom: 0em;
- margin-left: 1.5em;
- }
- dl.glossary dd
- {
- margin-bottom: 0em;
- margin-left: 1.5em;
- }
- dt
- {
- margin-top: .6em;
- margin-bottom: 1;
- }
- ul, ol
- {
- margin-top: 0.6em;
- margin-bottom: 0.6em;
- }
-
- ol
- {
- margin-left: 2.5em;
- }
-
- ul
- {
- list-style-type: disc;
- margin-left: 1.9em;
- }
- li
- {
- margin-bottom: 0.4em;
- }
- ul ol, ol ol
- {
- list-style-type: lower-alpha;
- }
- pre
- {
- margin-top: .6em;
- margin-bottom: .6em;
- font: 105% Lucida, mono;
- color: #000066;
- }
- code
- {
- font-family: Monospace, Courier New, Courier;
- font-size: 105%;
- color: #000066;
- }
- table.userdata td
- {
- background: #ffffff;
- background-color: #F5F5F5;
- border-color: #ffffff;
- border: none;
- }
- table.clsWarning
- {
- background: #ffffff;
- padding: 0px;
- margin: 0px;
- border: none;
- }
- table.clsWarning td
- {
- padding: 0px;
- margin: 0px;
- background: #ffffff;
- vertical-align: middle;
- font-size: 70%;
- }
- div#mainSection table
- {
- width: 95%;
- background: #ffffff;
- margin-top: 5px;
- margin-bottom: 5px;
- }
- div#mainSection table th
- {
- padding: 5px 6px;
- background: #EFEFF7;
- text-align: left;
- font-size: 70%;
- vertical-align: bottom;
- border-bottom: 1px solid #C8CDDE;
- }
- div#mainSection table td
- {
- padding: 5px 5px;
- background: #F7F7FF;
- vertical-align: top;
- font-size: 70%;
- border-bottom: 1px solid #D5D5D3;
- }
- div#syntaxCodeBlocks table th
- {
- padding: 1px 6px;
- color: #000066;
- }
- div#syntaxCodeBlocks table td
- {
- padding: 1px 5px;
- }
- /* Applies to the running header text in the first row of the upper table in the
- non-scrolling header region. */
- span#runningHeaderText
- {
- color: #003399;
- font-size: 90%;
- padding-left: 13;
- }
- /* Applies to the topic title in the second row of the upper table in the
- non-scrolling header region. */
- span#nsrTitle
- {
- color: #003399;
- font-size: 120%;
- font-weight: 600;
- padding-left: 13;
- }
- /* Applies to everything below the non-scrolling header region. */
- div#mainSection
- {
- font-size: 70%;
- width: 100%;
- }
- /* Applies to everything below the non-scrolling header region, minus the footer. */
- div#mainBody
- {
- font-size: 90%;
- margin-left: 15;
- margin-top: 10;
- padding-bottom: 20;
- }
- /* Adds right padding for all blocks in mainBody */
- div#mainBody p, div#mainBody ol, div#mainBody ul, div#mainBody dl
- {
- padding-right: 5;
- }
- div#mainBody div.alert, div#mainBody div.code, div#mainBody div.tableSection
- {
- width:98.9%;
- }
- div.alert p, div.code p
- {
- margin-top:5;
- margin-bottom:8;
- }
- /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Begin Note Styles - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
- div#mainSection div.alert table
- {
- border: 0;
- }
- div#mainSection div.alert table th
- {
- padding-top: 0;
- padding-bottom: 0;
- padding-left: 5;
- padding-right: 5;
- }
- div#mainSection div.alert table td
- {
- padding-left: 5;
- padding-right: 5;
- }
- img.note
- {
- border: 0;
- margin-left: 0;
- margin-right: 3;
- }
- /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - End Note Styles - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
- /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Begin Non-scrolling Header Region Styles - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
- /* Applies to the entire non-scrolling header region. */
- div#header
- {
- background-color: #D4DFFF;
- padding-top: 0;
- padding-bottom: 0;
- padding-left: 0;
- padding-right: 0;
- width: 100%;
- }
- /* Applies to both tables in the non-scrolling header region. */
- div#header table
- {
- margin-top: 0;
- margin-bottom: 0;
- border-bottom-color: #C8CDDE;
- border-bottom-style: solid;
- border-bottom-width: 1;
- background: #D4DFFF;
- width: 100%;
- }
- /* Applies to cells in both tables in the non-scrolling header region. */
- div#header table td
- {
- color: #0000FF;
- font-size: 70%;
- padding-right: 20;
- padding-top: 1;
- padding-bottom: 1;
- border: none;
- background: #D4DFFF;
- }
- /* Applies to the last row in the upper table of the non-scrolling header region. Text
- in this row includes See Also, Constructors, Methods, and Properties. */
- div#header table tr#headerTableRow3 td
- {
- padding-bottom: 2;
- padding-top: 5;
- padding-left: 15;
- }
- /* Applies to the lower table in the non-scrolling header region. Text in this table
- includes Collapse All/Expand All, Language Filter, and Members Options. */
- div#header table#bottomTable
- {
- border-top-color: #FFFFFF;
- border-top-style: solid;
- border-top-width: 1;
- text-align: left;
- padding-left: 15;
- }
- blockquote
- {
- margin-left: 3.8em;
- margin-right: 3.8em;
- margin-top: .6em;
- margin-bottom: .6em;
- }
- sup
- {
- text-decoration: none;
- font-size: smaller;
- }
- a:link
- {
- color: #0000FF;
- /* font-weight: bold */
- }
-
- a:visited
- {
- color: #0000AA;
- /* font-weight: bold */
- }
-
- a:hover
- {
- color: #3366FF;
- /* font-weight: bold */
- }
-
- .label
- {
- font-weight: bold;
- margin-top: 1em;
- margin-left: -26px;
- }
-
- .tl
- {
- margin-bottom: .75em;
- }
-
- .atl
- {
- padding-left: 1.5em;
- padding-bottom: .75em;
- }
-
- .cfe
- {
- font-weight: bold;
- }
-
- .mini
- {
- font-size: smaller;
- }
-
- .dt
- {
- margin-bottom: -.6em;
- }
-
- .indent
- {
- margin-left: 1.9em;
- margin-right: 1.9em;
- }
- .product
- {
- text-align: right;
- color: #333333;
- font-size: smaller;
- font-style: italic;
- }
- .buttonbarshade
- {
- position: relative;
- margin: 0;
- left: 0px;
- top: 2;
- width: 50%;
- height: 40px;
- }
- .buttonbartable
- {
- position: absolute;
- margin: 0;
- padding:0;
- border:0;
- left:0px;
- top: 2;
- width: 100%;
- height: 40px;
- }
- /* background color, font for header */
- table.buttonbartable td, table.buttonbarshade td
- {
- background: #ffffff; /*#5177B8; #80C615;*/
- border-left: 0px solid #80C615;
- margin: 0;
- padding: 0px 0px 0px 0px;
- font-family: Impact, sans-serif;
- font-size: 14pt;
- }
- table.buttonbartable td.button1
- {
- background: #5177B8; /*#80C615;*/;
- padding: 0;
- font-weight: bold;
- text-align: center;
- cursor: hand;
- }
- table.buttonbartable td.button2
- {
- background: #5177B8; /*#80C615;*/;
- font-weight: bold;
- text-align: center;
- }
- table.buttonbartable td.button3
- {
- background: #5177B8; /*#80C615;*/;
- font-weight: bold;
- text-align: center;
- }
- table.buttonbartable td.runninghead
- {
- padding-left: 0px;
- font-style: italic;
- text-align: left;
- }
- .version
- {
- text-align: left;
- color: #000000;
- margin-top: 3em;
- margin-left: -26px;
- font-size: smaller;
- font-style: italic;
- }
- .lang, .ilang
- {
- color: #0000ff;
- font: normal 7pt Arial, Helvetica, sans-serif;
- }
- div.langMenu
- {
- position: absolute;
- z-index: 1;
- width: 96pt;
- padding: 8pt;
- visibility: hidden;
- border: 1px solid #000000;
- background: #ffffd0;
- }
- div.langMenu ul
- {
- padding-left: 2em;
- margin-left: 0;
- }
- div.filtered
- {
- margin: 4pt 0 8pt -26px;
- padding: 4px 4px 8px 26px;
- width: 100%;
- border: 2px solid #aaaacc;
- background: #ffffff;
- }
- div.filtered2
- {
- margin: 4pt 0 8pt -26px;
- padding: 4px 4px 8px 26px;
- width: 100%;
- border: none;
- background: #ffffff;
- }
- div.filtered h1, div.filtered h2, div.filtered h3, div.filtered h4
- {
- margin-left: -22px;
- }
- div.filtered span.lang
- {
- position: relative;
- left: -22px;
- }
- div.reftip
- {
- position: absolute;
- z-index: 1;
- padding: 8pt;
- visibility: hidden;
- border: 1px solid #000000;
- background: #ffffd0;
- }
- a.synParam
- {
- color: #0000FF;
- /*color: #3F7800;*/
- /*color: #8DC54F;*/
- text-decoration: none;
- font-weight: normal;
- }
- a.synParam:hover
- {
- text-decoration: underline;
- font-weight: normal;
- }
- div.sapop
- {
- position: absolute;
- z-index: 1;
- left: 26px;
- width: 100%;
- padding: 10px 10px 10px 36px;
- visibility: hidden;
- border: 1px solid #000000;
- background: #ffffd0;
- }
- div.footer
- {
- width: 100%;
- border: none;
- background: #ffffff;
- margin-top: 18pt;
- padding-bottom: 12pt;
- color: #0000FF;
- /*color: #228B22; */
- text-align: center;
- font-size: 76%;
- }
- div.preliminary
- {
- margin-top: 8pt;
- padding-bottom: 12pt;
- color: #A0A0A0;
- }
- /* A procedure section. eg. 'To create a file', 'To add a value' */
- div.proc
- {
- margin-left: 0.5em;
- }
-
- /* The title of a 'procedure' section. */
- div.proc h3
- {
- font-family: Verdana, Arial, Helvetica, sans-serif;
- font-weight: bold;
- font-size: 115%;
- margin-top: 1em;
- margin-bottom: 0.4em;
- margin-left: -0.5em;
- color: #003399;
- }
- div.proc ul
- {
- margin-left: 1.5em;
- }
- div.proc ol
- {
- margin-left: 2.0em;
- }
-
- .note
- {
- margin-left: 14pt;
- margin-right: 12pt;
- }
- .indent1
- {
- margin-left: 12pt;
- }
- .indent2
- {
- margin-left: 24pt;
- }
- .indent3
- {
- margin-left: 36pt;
- }
- p.proch
- {
- padding-left: 16px;
- }
- p.proch img
- {
- position: relative;
- vertical-align: top;
- left: -18px;
- margin-right: -14px;
- margin-bottom: -18px;
- }
-
- div.clsPlatSpec
- {
- background-color:#FFF8DC;
- border-style:solid;
- border-width:1pt 0pt 0pt 1pt;
- border-color:#ffE4C4;
- margin-top:0.6em;
- width:100%;
- }
- /* Applies to the language labels in the Language Filter drop-down list. */
- .languageFilter
- {
- color: #0000FF;
- cursor:hand;
- text-decoration:underline;
- padding-bottom:4;
- }
- /* Dropdown areas */
- #languageSpan {
- position: absolute;
- visibility: hidden;
- border-style: solid;
- border-width: 1px;
- border-color: #C8CDDE;
- background: #d4dfff;
- padding: 4px;
- font-size: 70%;
- }
- #membersOptionsSpan {
- position: absolute;
- visibility: hidden;
- border-style: solid;
- border-width: 1px;
- border-color: #C8CDDE;
- background: #d4dfff;
- padding: 4px;
- font-size: 70%;
- }
- --></style>
- <xml>
- <MSHelp:TOCTitle Title="Custom Model Class Sample" />
- <MSHelp:RLTitle Title="Custom Model Class Sample" />
- <MSHelp:Keyword Index="A" Term="O:Microsoft.Xna.CustomModel" />
- <MSHelp:Keyword Index="A" Term="2255a98d-e38f-271c-57d8-46db8f025a5a" />
- <MSHelp:Keyword Index="K" Term="Custom Model Class Sample" />
- <MSHelp:Attr Name="AssetID" Value="2255a98d-e38f-271c-57d8-46db8f025a5a" />
- <MSHelp:Attr Name="Locale" Value="en-us" />
- <MSHelp:Attr Name="CommunityContent" Value="1" />
- <MSHelp:Attr Name="TopicType" Value="kbOrient" />
- </xml>
- </head><body><div id="mainSection"><div id="mainBody">
- <h1>Custom Model Class Sample</h1>
-
- This sample shows how to go beyond the limits of the <b>Model</b> class that comes built into the XNA Framework, loading geometry data into a custom class that can be extended more easily to cope with specialized requirements.
-
- <a id="ID2EN" name="ID2EN"> </a><h1 class="heading">Sample Overview</h1><div id="ID2EN" class="hxnx1">
-
- <p>
- The <b>Model</b> class that comes built into the XNA Framework provides a convenient way to load and display graphics, but it is not especially flexible. <b>Model</b> can be extended in a limited manner by attaching custom data to the <b>Tag</b> property (in fact, many other samples such as the Skinned Model sample or Picking with Triangle-Accuracy do just that), but beyond a certain point, trying to cajole <b>Model</b> into handling scenarios it was never really designed for can become more trouble than it is worth.
- </p>
- <p>
- Fortunately, the layered design of the Content Pipeline makes it easy to replace <b>Model</b> with a custom (and, hence, more easily extensible) alternative. There is no need to alter the importer behavior, so our custom model replacement can still import data from standard file formats such as .X or .FBX. This sample implements a <b>CustomModel</b> class, along with a <b>CustomModelProcessor</b> that extracts the necessary geometry data from the <b>NodeContent</b> format that was output by the importer.
- </p>
- <a id="ID2EHB" name="ID2EHB"> </a><h2 class="subHeading">Sample Controls</h2><div id="ID2EHB" class="hxnx2">
-
- <p>This sample uses the following keyboard and gamepad controls.</p>
- <table>
- <tr>
- <th>Action</th>
- <th>Keyboard control</th>
- <th>Gamepad control</th>
- </tr>
- <tr>
- <td>Exit the sample</td>
- <td>ESC or ALT+F4</td>
- <td>
- <b>BACK</b>
- </td>
- </tr>
- </table>
- </div>
- </div>
- <a id="ID2EHC" name="ID2EHC"> </a><h1 class="heading">How the Sample Works</h1><div id="ID2EHC" class="hxnx1">
-
- <a id="ID2ELC" name="ID2ELC"> </a><h2 class="subHeading">Creating a Custom Processor</h2><div id="ID2ELC" class="hxnx2">
-
- <p>The sample contains two projects, one containing the game code, and one containing the custom Content Pipeline processor. The game project has versions for both Windows and Xbox 360, but the Content Pipeline processor project isfor Windows only. The Content Processor always runs on a Windows computer as part of the build process, even when the output content is going to be used on Xbox 360. For more information about creating your own custom processor project, see the topic "How to: Write a Custom Importer and Processor" in the XNA Game Studio documentation.</p>
- <p>
- If you want to reuse the custom processor from this sample, but would like to move the <b>CustomModel</b> class into a different main game assembly, you must update the <b>CustomModelContent</b> class to correctly reference this new assembly, by changing its <b>ContentSerializerRuntimeType</b> attribute.
- </p>
- </div>
- <a id="ID2E2C" name="ID2E2C"> </a><h2 class="subHeading">Building the Custom Model Data</h2><div id="ID2E2C" class="hxnx2">
-
- <p>
- When you build an asset that has been set to use the <b>CustomModelProcessor</b>, data flows through the Content Pipeline in this order:
- </p>
- <ol>
- <li>First, an importer is used to read model data from a file format such as .X or .FBX. This functionality comes built into the framework, so we do not need to do anything special to enable it.</li>
- <li>
- The importer creates a tree of <b>NodeContent</b> objects. This lets you access the geometry data via a standardized managed object model, regardless of which file format it was originally imported from.
- </li>
- <li>
- <p>
- The tree of <b>NodeContent</b> data is passed into our <b>CustomModelProcessor.Process</b> method. This recurses over the input data, performing various actions:
- </p>
- <ol>
- <li>
- It uses <b>MeshHelper.TransformScene</b> to bake any local transform data into the vertex positions. In the interest of simplicity, this sample does not bother supporting local transforms in the run-time <b>CustomModel</b> class, so we want to get rid of any such data in the processor.
- </li>
- <li>
- It examines each <b>NodeContent</b> to see which ones are <b>MeshContent</b> instances.
- </li>
- <li>
- It calls <b>MeshHelper.OptimizeForCache</b>, which reorders the vertex and index data into a format that will be more efficient to render.
- </li>
- <li>
- It loops over all the <b>GeometryContent</b> data inside each <b>MeshContent</b>.
- </li>
- <li>
- It calls <b>VertexContent.CreateVertexBuffer</b> to flatten vertex data from the flexible multiple channel input format into a simple byte array ready to be fed to the GPU.
- </li>
- <li>
- It chains to the <b>MaterialProcessor</b> class that comes built into the framework, using this to convert whatever material is attached to the geometry. This processor will automatically go off and build any effects or textures that are referenced by the material. When you load the resulting material at run time, you will get back an <b>Effect</b> instance that has the appropriate textures already loaded into it and ready to go.
- </li>
- <li>
- Finally, it stores the result of all this work as part of the output <b>CustomModelContent</b>.
- </li>
- </ol>
- </li>
- <li>
- <b>CustomModelProcessor.Process</b> returns an instance of our new type, <b>CustomModelContent</b>. This class is similar in shape to the run-time <b>CustomModel</b>, but stores the data as simple managed objects rather than GPU data types. This avoids having to instantiate any actual GPU objects during the Content Pipeline build process, which is essential when building graphics for Xbox 360. The build always runs on Windows, and it would be problematic if we tried to instantiate Xbox types on the Windows GPU during this process!
- </li>
- <li>
- Our <b>CustomModelContent</b> object is passed to the Content Pipeline XNB serializer, which saves the data in a binary XNB file. This serialization process is controlled by the <b>ContentSerializerRuntimeType</b> and <b>ContentSerializer</b> attributes that are attached to the <b>CustomModelContent</b> class. The <b>SharedResource</b> flag, for example, tells the serializer that the <b>MaterialContent</b> property should be serialized in a special way.
- </li>
- <li>
- At run time, the sample game calls <b>
- ContentManager.Load<CustomModel>
- </b>. This deserializes data from the XNB file into our <b>CustomModel</b> class. For this to work, it is important that the design-time <b>CustomModelContent</b> class and the run-time <b>CustomModel</b> class have the same data fields in the same order, and the same <b>ContentSerializer</b> control attributes.
- </li>
- <li>
- <b>CustomModel</b> contains a vertex buffer and index buffer storing the geometry data, as well as an effect containing texture and material settings. It provides a simple <b>Draw</b> method to display the model.
- </li>
- </ol>
- <p>
- A subtle point to notice is that although the design time <b>CustomModelContent</b> class looks similar to the run-time <b>CustomModel</b>, not all fields are of the same type! At design time, data is stored in managed types provided by the Content Pipeline, while the run-time <b>CustomModel</b> uses actual GPU types from the <b>Microsoft.Xna.Framework.Graphics</b> namespace. The Content Pipeline knows about the relationship between the design-time types and run-time types, so it can automatically translate one to the other. At design time, we can use types such as <b>VertexBufferContent</b>, but when we read this data back in at run time, it will be loaded into the corresponding <b>VertexBuffer</b> class. The following table lists some of the graphics types that are translated from design-time versions to run-time versions in this way.
- </p>
- <table>
- <tr>
- <th>Design-time type</th>
- <th>Run-time type</th>
- </tr>
- <tr>
- <td>VertexBufferContent</td>
- <td>VertexBuffer</td>
- </tr>
- <tr>
- <td>IndexCollection</td>
- <td>IndexBuffer</td>
- </tr>
- <tr>
- <td>TextureContent</td>
- <td>Texture</td>
- </tr>
- <tr>
- <td>EffectMaterialContent</td>
- <td>Effect</td>
- </tr>
- <tr>
- <td>BasicMaterialContent</td>
- <td>BasicEffect</td>
- </tr>
- <tr>
- <td>CompiledEffect</td>
- <td>Effect</td>
- </tr>
- </table>
- </div>
- </div>
- <a id="ID2E4AAC" name="ID2E4AAC"> </a><h1 class="heading">Extending the Sample</h1><div id="ID2E4AAC" class="hxnx1">
-
- <p>
- This sample discards any nested transforms from the input scene by calling the <b>MeshHelper.TransformScene</b> method at the top of <b>CustomModelProcessor.ProcessNode</b>. You might prefer to retain this data, saving out the local transform matrices for use at run time.
- </p>
- <p>
- The <b>CustomModelProcessor.ProcessMaterial</b> method just chains to the built-in <b>MaterialProcessor</b> class. You might prefer to customize this to build your effects in a more specialized way, or perhaps to use some different material format altogether. Materials do not have to be effects at all if you want to use some other system!
- </p>
- <p>
- You could add extra data to the custom model—for example, animation or collision information.
- </p>
- <p>
- There is a great deal of potential for a smart processor to optimize the geometry data. You could merge the vertex and index data for each <b>ModelPart</b> into larger vertex and index buffers by using different regions of those single buffers for each part. You could detect when more than one <b>ModelPart</b> shares the same vertex declaration, and combine any duplicate declarations. You could even detect if more than one <b>ModelPart</b> uses the same material and vertex declaration, merging the <b>ModelPart</b> data entirely! You also could optimize the size of the vertex data by removing unused channels, or by compressing channels to use more compact data formats.
- </p>
- </div>
- </div><div class="footer" id="footer"><p>© 2010 Microsoft Corporation. All rights reserved.<br />Send feedback to <a href="mailto:[email protected]?subject=Documentation Feedback: Custom Model Class Sample">[email protected]</a>.</p></div></div></body></html>
|