Browse Source

Add StencilCratersTutorial using Stencils and AlphaTest Effect

Kenneth Pouncey 13 years ago
parent
commit
39f7768a46
24 changed files with 1049 additions and 1 deletions
  1. 2 1
      Samples/MacOS/HoneycombRush/HoneycombRush.csproj
  2. BIN
      Samples/MacOS/StencilsCratersTutorial/Content/crater.tga
  3. BIN
      Samples/MacOS/StencilsCratersTutorial/Content/crater.xnb
  4. BIN
      Samples/MacOS/StencilsCratersTutorial/Content/planet.tga
  5. BIN
      Samples/MacOS/StencilsCratersTutorial/Content/planet.xnb
  6. BIN
      Samples/MacOS/StencilsCratersTutorial/Documentation/Stencil Buffer Craters.docx
  7. 874 0
      Samples/MacOS/StencilsCratersTutorial/Documentation/Stencil Buffer Craters.htm
  8. BIN
      Samples/MacOS/StencilsCratersTutorial/Documentation/Stencil Buffer Craters_files/image001.jpg
  9. BIN
      Samples/MacOS/StencilsCratersTutorial/Documentation/Stencil Buffer Craters_files/image002.jpg
  10. BIN
      Samples/MacOS/StencilsCratersTutorial/Documentation/Stencil Buffer Craters_files/image003.jpg
  11. BIN
      Samples/MacOS/StencilsCratersTutorial/Documentation/Stencil Buffer Craters_files/image004.jpg
  12. BIN
      Samples/MacOS/StencilsCratersTutorial/Documentation/Stencil Buffer Craters_files/image005.jpg
  13. BIN
      Samples/MacOS/StencilsCratersTutorial/Documentation/crater.jpg
  14. BIN
      Samples/MacOS/StencilsCratersTutorial/Documentation/crater_mask.jpg
  15. BIN
      Samples/MacOS/StencilsCratersTutorial/Documentation/crater_planet.jpg
  16. BIN
      Samples/MacOS/StencilsCratersTutorial/Documentation/planet.jpg
  17. BIN
      Samples/MacOS/StencilsCratersTutorial/Documentation/planet_craters.jpg
  18. BIN
      Samples/MacOS/StencilsCratersTutorial/Game.ico
  19. 0 0
      Samples/MacOS/StencilsCratersTutorial/Game1.cs
  20. BIN
      Samples/MacOS/StencilsCratersTutorial/GameThumbnail.png
  21. 16 0
      Samples/MacOS/StencilsCratersTutorial/Info.plist
  22. 55 0
      Samples/MacOS/StencilsCratersTutorial/Program.cs
  23. 65 0
      Samples/MacOS/StencilsCratersTutorial/StencilsCratersTutorial.csproj
  24. 37 0
      Samples/MacOS/StencilsCratersTutorial/StencilsCratersTutorial.sln

+ 2 - 1
Samples/MacOS/HoneycombRush/HoneycombRush.csproj

@@ -42,6 +42,7 @@
     <None Include="Background.png" />
     <None Include="Game.ico" />
     <None Include="GameThumbnail.png" />
+    <None Include="Content\Sounds\FillingHoneyPot_Loop.wav" />
   </ItemGroup>
   <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
   <Import Project="$(MSBuildExtensionsPath)\Mono\MonoMac\v0.0\Mono.MonoMac.targets" />
@@ -111,7 +112,6 @@
     <Content Include="Content\Sounds\BeeBuzzing_Loop.xnb" />
     <Content Include="Content\Sounds\Defeat.xnb" />
     <Content Include="Content\Sounds\DepositingIntoVat_Loop.xnb" />
-    <Content Include="Content\Sounds\FillingHoneyPot_Loop.xnb" />
     <Content Include="Content\Sounds\HighScore.xnb" />
     <Content Include="Content\Sounds\HoneyPotBreak.xnb" />
     <Content Include="Content\Sounds\InGameSong_Loop.wma" />
@@ -154,5 +154,6 @@
     <Content Include="Content\Textures\Backgrounds\instructionsXbox.xnb" />
     <Content Include="Content\Textures\Backgrounds\pauseBackground.xnb" />
     <Content Include="Content\Textures\Backgrounds\titleScreen.xnb" />
+    <Content Include="Content\Sounds\FillingHoneyPot_Loop.xnb" />
   </ItemGroup>
 </Project>

BIN
Samples/MacOS/StencilsCratersTutorial/Content/crater.tga


BIN
Samples/MacOS/StencilsCratersTutorial/Content/crater.xnb


BIN
Samples/MacOS/StencilsCratersTutorial/Content/planet.tga


BIN
Samples/MacOS/StencilsCratersTutorial/Content/planet.xnb


BIN
Samples/MacOS/StencilsCratersTutorial/Documentation/Stencil Buffer Craters.docx


+ 874 - 0
Samples/MacOS/StencilsCratersTutorial/Documentation/Stencil Buffer Craters.htm

@@ -0,0 +1,874 @@
+<html>
+
+<head>
+<meta http-equiv=Content-Type content="text/html; charset=windows-1252">
+<meta name=Generator content="Microsoft Word 14 (filtered)">
+<style>
+<!--
+ /* Font Definitions */
+ @font-face
+	{font-family:Wingdings;
+	panose-1:5 0 0 0 0 0 0 0 0 0;}
+@font-face
+	{font-family:"Cambria Math";
+	panose-1:2 4 5 3 5 4 6 3 2 4;}
+@font-face
+	{font-family:Cambria;
+	panose-1:2 4 5 3 5 4 6 3 2 4;}
+@font-face
+	{font-family:Calibri;
+	panose-1:2 15 5 2 2 2 4 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 */
+ p.MsoNormal, li.MsoNormal, div.MsoNormal
+	{margin-top:0in;
+	margin-right:0in;
+	margin-bottom:10.0pt;
+	margin-left:0in;
+	line-height:115%;
+	font-size:11.0pt;
+	font-family:"Calibri","sans-serif";}
+h1
+	{mso-style-link:"Heading 1 Char";
+	margin-top:24.0pt;
+	margin-right:0in;
+	margin-bottom:0in;
+	margin-left:0in;
+	margin-bottom:.0001pt;
+	line-height:115%;
+	page-break-after:avoid;
+	font-size:14.0pt;
+	font-family:"Cambria","serif";
+	color:#365F91;}
+h2
+	{mso-style-link:"Heading 2 Char";
+	margin-top:10.0pt;
+	margin-right:0in;
+	margin-bottom:0in;
+	margin-left:0in;
+	margin-bottom:.0001pt;
+	line-height:115%;
+	page-break-after:avoid;
+	font-size:13.0pt;
+	font-family:"Cambria","serif";
+	color:#4F81BD;}
+h3
+	{mso-style-link:"Heading 3 Char";
+	margin-top:10.0pt;
+	margin-right:0in;
+	margin-bottom:0in;
+	margin-left:0in;
+	margin-bottom:.0001pt;
+	line-height:115%;
+	page-break-after:avoid;
+	font-size:11.0pt;
+	font-family:"Cambria","serif";
+	color:#4F81BD;}
+h4
+	{mso-style-link:"Heading 4 Char";
+	margin-top:10.0pt;
+	margin-right:0in;
+	margin-bottom:0in;
+	margin-left:0in;
+	margin-bottom:.0001pt;
+	line-height:115%;
+	page-break-after:avoid;
+	font-size:11.0pt;
+	font-family:"Cambria","serif";
+	color:#4F81BD;
+	font-style:italic;}
+h5
+	{mso-style-link:"Heading 5 Char";
+	margin-top:10.0pt;
+	margin-right:0in;
+	margin-bottom:0in;
+	margin-left:0in;
+	margin-bottom:.0001pt;
+	line-height:115%;
+	page-break-after:avoid;
+	font-size:11.0pt;
+	font-family:"Cambria","serif";
+	color:#243F60;
+	font-weight:normal;}
+h6
+	{mso-style-link:"Heading 6 Char";
+	margin-top:10.0pt;
+	margin-right:0in;
+	margin-bottom:0in;
+	margin-left:0in;
+	margin-bottom:.0001pt;
+	line-height:115%;
+	page-break-after:avoid;
+	font-size:11.0pt;
+	font-family:"Cambria","serif";
+	color:#243F60;
+	font-weight:normal;
+	font-style:italic;}
+p.MsoTitle, li.MsoTitle, div.MsoTitle
+	{mso-style-link:"Title Char";
+	margin-top:0in;
+	margin-right:0in;
+	margin-bottom:15.0pt;
+	margin-left:0in;
+	border:none;
+	padding:0in;
+	font-size:26.0pt;
+	font-family:"Cambria","serif";
+	color:#17365D;
+	letter-spacing:.25pt;}
+p.MsoTitleCxSpFirst, li.MsoTitleCxSpFirst, div.MsoTitleCxSpFirst
+	{mso-style-link:"Title Char";
+	margin:0in;
+	margin-bottom:.0001pt;
+	border:none;
+	padding:0in;
+	font-size:26.0pt;
+	font-family:"Cambria","serif";
+	color:#17365D;
+	letter-spacing:.25pt;}
+p.MsoTitleCxSpMiddle, li.MsoTitleCxSpMiddle, div.MsoTitleCxSpMiddle
+	{mso-style-link:"Title Char";
+	margin:0in;
+	margin-bottom:.0001pt;
+	border:none;
+	padding:0in;
+	font-size:26.0pt;
+	font-family:"Cambria","serif";
+	color:#17365D;
+	letter-spacing:.25pt;}
+p.MsoTitleCxSpLast, li.MsoTitleCxSpLast, div.MsoTitleCxSpLast
+	{mso-style-link:"Title Char";
+	margin-top:0in;
+	margin-right:0in;
+	margin-bottom:15.0pt;
+	margin-left:0in;
+	border:none;
+	padding:0in;
+	font-size:26.0pt;
+	font-family:"Cambria","serif";
+	color:#17365D;
+	letter-spacing:.25pt;}
+a:link, span.MsoHyperlink
+	{color:blue;
+	text-decoration:underline;}
+a:visited, span.MsoHyperlinkFollowed
+	{color:purple;
+	text-decoration:underline;}
+p.MsoAcetate, li.MsoAcetate, div.MsoAcetate
+	{mso-style-link:"Balloon Text Char";
+	margin:0in;
+	margin-bottom:.0001pt;
+	font-size:8.0pt;
+	font-family:"Tahoma","sans-serif";}
+p.MsoListParagraph, li.MsoListParagraph, div.MsoListParagraph
+	{margin-top:0in;
+	margin-right:0in;
+	margin-bottom:10.0pt;
+	margin-left:.5in;
+	line-height:115%;
+	font-size:11.0pt;
+	font-family:"Calibri","sans-serif";}
+p.MsoListParagraphCxSpFirst, li.MsoListParagraphCxSpFirst, div.MsoListParagraphCxSpFirst
+	{margin-top:0in;
+	margin-right:0in;
+	margin-bottom:0in;
+	margin-left:.5in;
+	margin-bottom:.0001pt;
+	line-height:115%;
+	font-size:11.0pt;
+	font-family:"Calibri","sans-serif";}
+p.MsoListParagraphCxSpMiddle, li.MsoListParagraphCxSpMiddle, div.MsoListParagraphCxSpMiddle
+	{margin-top:0in;
+	margin-right:0in;
+	margin-bottom:0in;
+	margin-left:.5in;
+	margin-bottom:.0001pt;
+	line-height:115%;
+	font-size:11.0pt;
+	font-family:"Calibri","sans-serif";}
+p.MsoListParagraphCxSpLast, li.MsoListParagraphCxSpLast, div.MsoListParagraphCxSpLast
+	{margin-top:0in;
+	margin-right:0in;
+	margin-bottom:10.0pt;
+	margin-left:.5in;
+	line-height:115%;
+	font-size:11.0pt;
+	font-family:"Calibri","sans-serif";}
+span.Heading1Char
+	{mso-style-name:"Heading 1 Char";
+	mso-style-link:"Heading 1";
+	font-family:"Cambria","serif";
+	color:#365F91;
+	font-weight:bold;}
+span.Heading2Char
+	{mso-style-name:"Heading 2 Char";
+	mso-style-link:"Heading 2";
+	font-family:"Cambria","serif";
+	color:#4F81BD;
+	font-weight:bold;}
+span.TitleChar
+	{mso-style-name:"Title Char";
+	mso-style-link:Title;
+	font-family:"Cambria","serif";
+	color:#17365D;
+	letter-spacing:.25pt;}
+span.Heading3Char
+	{mso-style-name:"Heading 3 Char";
+	mso-style-link:"Heading 3";
+	font-family:"Cambria","serif";
+	color:#4F81BD;
+	font-weight:bold;}
+span.Heading4Char
+	{mso-style-name:"Heading 4 Char";
+	mso-style-link:"Heading 4";
+	font-family:"Cambria","serif";
+	color:#4F81BD;
+	font-weight:bold;
+	font-style:italic;}
+span.Heading5Char
+	{mso-style-name:"Heading 5 Char";
+	mso-style-link:"Heading 5";
+	font-family:"Cambria","serif";
+	color:#243F60;}
+span.Heading6Char
+	{mso-style-name:"Heading 6 Char";
+	mso-style-link:"Heading 6";
+	font-family:"Cambria","serif";
+	color:#243F60;
+	font-style:italic;}
+span.BalloonTextChar
+	{mso-style-name:"Balloon Text Char";
+	mso-style-link:"Balloon Text";
+	font-family:"Tahoma","sans-serif";}
+p.Code, li.Code, div.Code
+	{mso-style-name:Code;
+	mso-style-link:"Code Char";
+	margin:0in;
+	margin-bottom:.0001pt;
+	text-autospace:none;
+	font-size:9.5pt;
+	font-family:Consolas;}
+span.CodeChar
+	{mso-style-name:"Code Char";
+	mso-style-link:Code;
+	font-family:Consolas;}
+.MsoChpDefault
+	{font-family:"Calibri","sans-serif";}
+.MsoPapDefault
+	{margin-bottom:10.0pt;
+	line-height:115%;}
+@page WordSection1
+	{size:8.5in 11.0in;
+	margin:1.0in 1.0in 1.0in 1.0in;}
+div.WordSection1
+	{page:WordSection1;}
+ /* List Definitions */
+ ol
+	{margin-bottom:0in;}
+ul
+	{margin-bottom:0in;}
+-->
+</style>
+
+</head>
+
+<body lang=EN-US link=blue vlink=purple>
+
+<div class=WordSection1>
+
+<div style='border:none;border-bottom:solid #4F81BD 1.0pt;padding:0in 0in 4.0pt 0in'>
+
+<p class=MsoTitle>Texture Modification using Render Targets, with some Stencil
+Buffer Action</p>
+
+</div>
+
+<p class=MsoNormal>Sometimes you need to modify a texture while your game is
+running, and there are a number of ways to do this. One of the first things
+newer game programmers often try to do is use Texture2D.GetData to copy the
+texture data from the GPU to an array on the CPU, modify the bytes, and then
+send it back to the GPU with Texture2D.SetData.</p>
+
+<p class=MsoNormal>This is a bad idea on many, levels. Beyond issues with <a
+href="http://blogs.msdn.com/b/shawnhar/archive/2008/04/14/stalling-the-pipeline.aspx">pipeline
+stalls</a>, GetData and SetData can be slow, especially when working with a
+large texture. Any time you’re tempted grab data from the GPU for use on the
+CPU you should very carefully consider all of your options. There are often
+other solutions that let you keep the data entirely on the GPU and accomplish
+the same thing.</p>
+
+<p class=MsoNormal>This tutorial will use an example that could be solved with
+GetData and SetData, and show you another alternative using render targets and
+the stencil buffer that will let you perform the same function entirely on the
+GPU.</p>
+
+<h1>CPU Craters</h1>
+
+<p class=MsoNormal>Let’s pretend you want to draw 2D planet, and periodically
+add a crater to it.  You want a hole to appear somewhere on the planet, so it
+looks like part of it was removed.</p>
+
+<p class=MsoNormal>&nbsp;</p>
+
+<p class=MsoNormal><img border=0 width=320 height=256 id="Picture 1"
+src="Stencil%20Buffer%20Craters_files/image001.jpg"></p>
+
+<p class=MsoNormal>&nbsp;</p>
+
+<p class=MsoNormal> You could do this using the GetData/SetData method by
+getting the data from a texture into an array, setting the color to the
+background (or alpha to 0) in the shape of the crater, then writing the data
+back to the texture. Or you could be a little cleverer and eliminate GetData by
+always keeping the data in the array, but you still have to do the SetData to
+get it into the texture on the GPU each time it’s changed.</p>
+
+<p class=MsoNormal>&nbsp;</p>
+
+<h1>GPU Craters</h1>
+
+<p class=MsoNormal>The method we’ll use to do this entirely on the GPU involves
+several steps.  First, we need a couple of resources.  We’ll use a simple
+textured circle for a planet, and a “crater” shaped texture for the crater.</p>
+
+<p class=MsoNormal>&nbsp;</p>
+
+<p class=MsoNormal><img border=0 width=256 height=256 id="Picture 2"
+src="Stencil%20Buffer%20Craters_files/image002.jpg">  <img border=0 width=256
+height=256 id="Picture 3" src="Stencil%20Buffer%20Craters_files/image003.jpg"></p>
+
+<p class=MsoNormal>&nbsp;</p>
+
+<p class=MsoNormal>It’s important to note that the black areas on these have an
+alpha value of 0, meaning completely transparent. For the planet this just lets
+us draw the round shape over the background without looking like a square
+image. But for the crater image the alpha value is very important since it will
+control what part of the crater image is removed from the planet.</p>
+
+<p class=MsoNormal>Next, we need to set up two render targets (these will be
+referred to later as Render Target A, and Render Target B). When we need to add
+a crater, one of these will be used as a target for drawing to, while the other
+used as a texture. The next time we add a crater they will swap roles – the
+texture will become the target, and the target will become the texture. This is
+called “ping-ponging” and will be discussed more fully later.</p>
+
+<p class=MsoNormal>Once we have these resources ready to go, the method for
+adding a crater goes like this:</p>
+
+<p class=MsoListParagraphCxSpFirst style='text-indent:-.25in'>1.<span
+style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Activate
+Render Target A using GraphicsDevice.SetRenderTarget.</p>
+
+<p class=MsoListParagraphCxSpMiddle style='text-indent:-.25in'>2.<span
+style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Clear
+the graphics device, setting the color to solid black, and the stencil buffer
+to 0.</p>
+
+<p class=MsoListParagraphCxSpMiddle style='text-indent:-.25in'>3.<span
+style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Set
+up the stencil buffer state so whatever we draw writes a value of 1 to the
+stencil buffer.</p>
+
+<p class=MsoListParagraphCxSpMiddle style='text-indent:-.25in'>4.<span
+style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Set
+up the alpha test state so we only draw where the alpha value is zero.</p>
+
+<p class=MsoListParagraphCxSpLast style='text-indent:-.25in'>5.<span
+style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Draw
+the crater texture. Because of the way we’ve set up the graphics device, only
+the parts of the crater texture that have alpha = 0 will be drawn, and those
+parts will write a 1 to the stencil buffer.  So what we have at this point is a
+“mask” in the stencil buffer that we can use in the next step. The white area
+in the following image represents the stencil mask we’ve set up – the stencil
+buffer contains “1” in the white area, and “0” everywhere else.</p>
+
+<p class=MsoNormal>&nbsp;</p>
+
+<p class=MsoNormal><img border=0 width=256 height=256 id="Picture 6"
+src="Stencil%20Buffer%20Craters_files/image004.jpg"></p>
+
+<p class=MsoNormal>&nbsp;</p>
+
+<p class=MsoListParagraphCxSpFirst style='text-indent:-.25in'>6.<span
+style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Set
+up the stencil buffer so when we draw, anything that has a value of 1 in the
+stencil buffer will be masked out – meaning it won’t draw.</p>
+
+<p class=MsoListParagraphCxSpLast style='text-indent:-.25in'>7.<span
+style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Draw
+the “planet texture”. Because of the way we’ve set up the graphics device,
+anything with a 1 in the stencil buffer won’t be drawn – since these 1’s are in
+the shape of a crater, that shape will be masked out of the planet texture,
+leaving holes that look like craters. </p>
+
+<p class=MsoNormal>&nbsp;</p>
+
+<p class=MsoNormal><img border=0 width=256 height=256 id="Picture 7"
+src="Stencil%20Buffer%20Craters_files/image005.jpg"></p>
+
+<p class=MsoNormal>&nbsp;</p>
+
+<p class=MsoListParagraph style='text-indent:-.25in'>8.<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span>Set the render target to the backbuffer.  We can now access Render
+Target A as a texture, and that texture contains the planet texture with a
+crater-shaped hole in it.</p>
+
+<p class=MsoNormal>&nbsp;</p>
+
+<p class=MsoNormal>From now on, until we need to add another crater, we can
+treat Render Target A as a texture and draw it using SpriteBatch, and we’ll
+have a nice crater. Now, what if we need to add another crater? This is where
+the ping-ponging comes in. Since Render Target A is now the “planet texture”,
+we need to be able to draw somewhere else when we’re filling in the stencil
+buffer with our crater shape. It just so happens that we set up another place
+to draw to, Render Target B.  </p>
+
+<p class=MsoNormal>So now, in Step 1, instead of activating Render Target A we
+need to activate Render Target B and draw the crater shapes into that.  But
+what happens when we get to Step 7? Well, the “planet texture” is now in Render
+Target A, so we draw that.  And in Step 8, Render Target B now contains our new
+planet texture with two craters.</p>
+
+<p class=MsoNormal>And if we add a third crater then we’re back to where we
+started – drawing to Render Target A, and using Render Target B as the source
+texture. In other words, we “ping-pong” between the two render targets – each
+time we need to modify the texture, one is used for a texture, and one is used
+for drawing to, and then those roles are swapped.</p>
+
+<p class=MsoNormal>You may have noticed that there’s one issue here.  The first
+time through, Render Target B has nothing in it, so we can’t use it as the
+planet texture.  This can be handled by using the actual planet texture the
+first time, and the render target thereafter.</p>
+
+<h1>The Code</h1>
+
+<p class=MsoNormal>Now let’s walk through the code involved, using XNA 4.0. 
+You can do this in 3.1, but you’ll have to make significant changes when
+creating the render targets and setting the render states. </p>
+
+<p class=MsoNormal>The complete code is in the downloadable project linked at
+the end of the tutorial.  We’ll just go through the highlights here, referring
+to the steps mentioned above as we go.</p>
+
+<p class=MsoNormal>The XNA 4.0 API has been changed substantially where render
+states are concerned, and for the better. Render states have been grouped by
+functionality into several classes. You create instances of these classes to
+represent the state you want, then set them on the graphics device, or pass
+them to SpriteBatch.  So first we need to create these render state objects. </p>
+
+<p class=MsoNormal>&nbsp;</p>
+
+<h2>Set Up Render State Objects</h2>
+
+<p class=MsoNormal>For Step 3, we need to use the DepthStencilState class to
+set up the device to always set the stencil buffer to 1. We enable the stencil
+buffer, set the stencil function to Always, the pass operation to Replace, and
+ReferenceStencil to 1. This means that as we’re drawing, each pixel will Always
+pass, and the value in the stencil buffer will be Replaced with 1.</p>
+
+<p class=MsoNormal>&nbsp;</p>
+
+<p class=MsoNormal style='margin-bottom:0in;margin-bottom:.0001pt;line-height:
+normal;text-autospace:none'><span style='font-size:9.5pt;font-family:Consolas'>     
+<span style='color:green'>// set up stencil state to always replace stencil
+buffer with 1</span></span></p>
+
+<p class=Code>      stencilAlways = <span style='color:blue'>new</span> <span
+style='color:#2B91AF'>DepthStencilState</span>();</p>
+
+<p class=Code>      stencilAlways.StencilEnable = <span style='color:blue'>true</span>;</p>
+
+<p class=Code>      stencilAlways.StencilFunction = <span style='color:#2B91AF'>CompareFunction</span>.Always;</p>
+
+<p class=Code>      stencilAlways.StencilPass = <span style='color:#2B91AF'>StencilOperation</span>.Replace;</p>
+
+<p class=Code>      stencilAlways.ReferenceStencil = 1;</p>
+
+<p class=Code>      stencilAlways.DepthBufferEnable = <span style='color:blue'>false</span>;</p>
+
+<p class=MsoNormal>&nbsp;</p>
+
+<p class=MsoNormal>And for Step 4 we need to use the standard AlphaTestEffect
+so we can draw the asteroid texture only where the alpha value is 0.</p>
+
+<p class=MsoNormal>&nbsp;</p>
+
+<p class=Code>      // set up alpha test effect</p>
+
+<p class=Code>      <span style='color:#2B91AF'>Matrix</span> projection = <span
+style='color:#2B91AF'>Matrix</span>.CreateOrthographicOffCenter(0,
+PlanetDataSize, PlanetDataSize, 0, 0, 1);</p>
+
+<p class=Code>      <span style='color:#2B91AF'>Matrix</span> halfPixelOffset =
+<span style='color:#2B91AF'>Matrix</span>.CreateTranslation(-0.5f, -0.5f, 0);</p>
+
+<p class=Code>&nbsp;</p>
+
+<p class=Code>      alphaTestEffect = <span style='color:blue'>new</span> <span
+style='color:#2B91AF'>AlphaTestEffect</span>(GraphicsDevice);</p>
+
+<p class=Code>      alphaTestEffect.VertexColorEnabled = <span
+style='color:blue'>true</span>;</p>
+
+<p class=Code>      alphaTestEffect.DiffuseColor = <span style='color:#2B91AF'>Color</span>.White.ToVector3();</p>
+
+<p class=Code>      alphaTestEffect.AlphaFunction = <span style='color:#2B91AF'>CompareFunction</span>.Equal;</p>
+
+<p class=Code>      alphaTestEffect.ReferenceAlpha = 0;</p>
+
+<p class=Code>      alphaTestEffect.World = <span style='color:#2B91AF'>Matrix</span>.Identity;</p>
+
+<p class=Code>      alphaTestEffect.View = <span style='color:#2B91AF'>Matrix</span>.Identity;</p>
+
+<p class=Code>      alphaTestEffect.Projection = halfPixelOffset * projection;</p>
+
+<p class=MsoNormal>&nbsp;</p>
+
+<p class=MsoNormal>We first set up an orthographic projection matrix that
+matches SpriteBatch. We set AlphaFunction to Equal, and ReferenceAlpha to 0. 
+This means the alpha test will pass whenever the alpha value we’re drawing is
+equal to 0. In our crater texture, the crater area has an alpha value of 0,
+while the surrounding area has 1, so only the crater area will be drawn.</p>
+
+<p class=MsoNormal>For Step 6 we need a stencil buffer state that allows
+drawing only where the stencil buffer contains a 0. We enable the stencil
+buffer, set the stencil function to Equal, the pass operation to Keep, and the
+reference stencil to 0. This means that when we’re drawing, each pixel will
+pass if the value in the stencil buffer is Equal to 0.</p>
+
+<p class=Code>      // set up stencil state to pass if the stencil value is 0</p>
+
+<p class=Code>      stencilKeepIfZero = <span style='color:blue'>new</span> <span
+style='color:#2B91AF'>DepthStencilState</span>();</p>
+
+<p class=Code>      stencilKeepIfZero.StencilEnable = <span style='color:blue'>true</span>;</p>
+
+<p class=Code>      stencilKeepIfZero.StencilFunction = <span style='color:
+#2B91AF'>CompareFunction</span>.Equal;</p>
+
+<p class=Code>      stencilKeepIfZero.StencilPass = <span style='color:#2B91AF'>StencilOperation</span>.Keep;</p>
+
+<p class=Code>      stencilKeepIfZero.ReferenceStencil = 0;</p>
+
+<p class=Code>      stencilKeepIfZero.DepthBufferEnable = <span
+style='color:blue'>false</span>;</p>
+
+<p class=Code>&nbsp;</p>
+
+<h2>Create Render Targets</h2>
+
+<p class=MsoNormal>Now that we have the render state objects created, it’s time
+to create the render targets.  Both are the same, so just one is shown here.
+This creates a render target with a Color format, and a depth format that
+includes a stencil buffer.</p>
+
+<p class=Code>      renderTargetA = <span style='color:blue'>new</span> <span
+style='color:#2B91AF'>RenderTarget2D</span>(GraphicsDevice, PlanetDataSize,
+PlanetDataSize,</p>
+
+<p class=Code>                          <span style='color:blue'>false</span>, <span
+style='color:#2B91AF'>SurfaceFormat</span>.Color, <span style='color:#2B91AF'>DepthFormat</span>.Depth24Stencil8,</p>
+
+<p class=Code>                          0, <span style='color:#2B91AF'>RenderTargetUsage</span>.DiscardContents);</p>
+
+<p class=MsoNormal style='margin-bottom:0in;margin-bottom:.0001pt;line-height:
+normal;text-autospace:none'><span style='font-size:9.5pt;font-family:Consolas'>&nbsp;</span></p>
+
+<p class=MsoNormal style='margin-bottom:0in;margin-bottom:.0001pt;line-height:
+normal;text-autospace:none'><span style='font-size:9.5pt;font-family:Consolas'>&nbsp;</span></p>
+
+<p class=MsoNormal style='margin-bottom:0in;margin-bottom:.0001pt;line-height:
+normal;text-autospace:none'><span style='font-size:9.5pt;font-family:Consolas'>&nbsp;</span></p>
+
+<p class=MsoNormal style='margin-bottom:0in;margin-bottom:.0001pt;line-height:
+normal;text-autospace:none'><span style='font-size:9.5pt;font-family:Consolas'>&nbsp;</span></p>
+
+<h2>Draw the Crater Mask</h2>
+
+<p class=MsoNormal>Next up is drawing the crater masks (Steps 2-5). First we
+activate the render target, clear it to solid black, and clear the stencil
+buffer to 0.</p>
+
+<p class=MsoNormal style='margin-bottom:0in;margin-bottom:.0001pt;line-height:
+normal;text-autospace:none'><span style='font-size:9.5pt;font-family:Consolas'>&nbsp;</span></p>
+
+<p class=MsoNormal style='margin-bottom:0in;margin-bottom:.0001pt;line-height:
+normal;text-autospace:none'><span style='font-size:9.5pt;font-family:Consolas'>     
+GraphicsDevice.SetRenderTarget(activeRenderTarget);</span></p>
+
+<p class=MsoNormal style='margin-bottom:0in;margin-bottom:.0001pt;line-height:
+normal;text-autospace:none'><span style='font-size:9.5pt;font-family:Consolas'>     
+GraphicsDevice.Clear(<span style='color:#2B91AF'>ClearOptions</span>.Target | <span
+style='color:#2B91AF'>ClearOptions</span>.Stencil,</span></p>
+
+<p class=MsoNormal style='margin-bottom:0in;margin-bottom:.0001pt;line-height:
+normal;text-autospace:none'><span style='font-size:9.5pt;font-family:Consolas'>                          
+<span style='color:blue'>new</span> <span style='color:#2B91AF'>Color</span>(0,
+0, 0, 1), 0, 0);</span></p>
+
+<p class=MsoNormal style='margin-bottom:0in;margin-bottom:.0001pt;line-height:
+normal;text-autospace:none'><span style='font-size:9.5pt;font-family:Consolas'>&nbsp;</span></p>
+
+<p class=MsoNormal style='margin-bottom:0in;margin-bottom:.0001pt;line-height:
+normal;text-autospace:none'><span style='font-size:9.5pt;font-family:Consolas'>&nbsp;</span></p>
+
+<p class=MsoNormal style='margin-bottom:0in;margin-bottom:.0001pt;line-height:
+normal;text-autospace:none'><span style='font-size:9.5pt;font-family:Consolas'>&nbsp;</span></p>
+
+<p class=MsoNormal style='margin-bottom:0in;margin-bottom:.0001pt;line-height:
+normal;text-autospace:none'><span style='font-size:9.5pt;font-family:Consolas'>&nbsp;</span></p>
+
+<p class=MsoNormal>Next we begin a SpriteBatch, passing in the stencilAlways
+and alphaTestEffect objects that we created earlier. Calculate some random
+rotation, size the crater texture using a Rectangle, and call SpriteBatch.Draw
+to draw the crater.</p>
+
+<p class=MsoNormal style='margin-bottom:0in;margin-bottom:.0001pt;line-height:
+normal;text-autospace:none'><span style='font-size:9.5pt;font-family:Consolas'>&nbsp;</span></p>
+
+<p class=MsoNormal style='margin-bottom:0in;margin-bottom:.0001pt;line-height:
+normal;text-autospace:none'><span style='font-size:9.5pt;font-family:Consolas'>&nbsp;</span></p>
+
+<p class=MsoNormal style='margin-bottom:0in;margin-bottom:.0001pt;line-height:
+normal;text-autospace:none'><span style='font-size:9.5pt;font-family:Consolas'>&nbsp;</span></p>
+
+<p class=MsoNormal style='margin-bottom:0in;margin-bottom:.0001pt;line-height:
+normal;text-autospace:none'><span style='font-size:9.5pt;font-family:Consolas'>     
+spriteBatch.Begin(<span style='color:#2B91AF'>SpriteSortMode</span>.Immediate, <span
+style='color:#2B91AF'>BlendState</span>.Opaque, </span></p>
+
+<p class=MsoNormal style='margin-bottom:0in;margin-bottom:.0001pt;line-height:
+normal;text-autospace:none'><span style='font-size:9.5pt;font-family:Consolas'>                       
+<span style='color:blue'>null</span>, stencilAlways, <span style='color:blue'>null</span>,
+alphaTestEffect);</span></p>
+
+<p class=MsoNormal style='margin-bottom:0in;margin-bottom:.0001pt;line-height:
+normal;text-autospace:none'><span style='font-size:9.5pt;font-family:Consolas'>&nbsp;</span></p>
+
+<p class=MsoNormal style='margin-bottom:0in;margin-bottom:.0001pt;line-height:
+normal;text-autospace:none'><span style='font-size:9.5pt;font-family:Consolas'>     
+<span style='color:#2B91AF'>Vector2</span> origin = <span style='color:blue'>new</span>
+<span style='color:#2B91AF'>Vector2</span>(craterTexture.Width * 0.5f,</span></p>
+
+<p class=MsoNormal style='margin-bottom:0in;margin-bottom:.0001pt;line-height:
+normal;text-autospace:none'><span style='font-size:9.5pt;font-family:Consolas'>                                  
+craterTexture.Height * 0.5f);</span></p>
+
+<p class=MsoNormal style='margin-bottom:0in;margin-bottom:.0001pt;line-height:
+normal;text-autospace:none'><span style='font-size:9.5pt;font-family:Consolas'>&nbsp;</span></p>
+
+<p class=MsoNormal style='margin-bottom:0in;margin-bottom:.0001pt;line-height:
+normal;text-autospace:none'><span style='font-size:9.5pt;font-family:Consolas'>     
+<span style='color:blue'>float</span> rotation = (<span style='color:blue'>float</span>)random.NextDouble()
+* <span style='color:#2B91AF'>MathHelper</span>.TwoPi;</span></p>
+
+<p class=MsoNormal style='margin-bottom:0in;margin-bottom:.0001pt;line-height:
+normal;text-autospace:none'><span style='font-size:9.5pt;font-family:Consolas'>     
+<span style='color:#2B91AF'>Rectangle</span> r = <span style='color:blue'>new</span>
+<span style='color:#2B91AF'>Rectangle</span>((<span style='color:blue'>int</span>)position.X,
+(<span style='color:blue'>int</span>)position.Y, 50, 50);</span></p>
+
+<p class=MsoNormal style='margin-bottom:0in;margin-bottom:.0001pt;line-height:
+normal;text-autospace:none'><span style='font-size:9.5pt;font-family:Consolas'>&nbsp;</span></p>
+
+<p class=MsoNormal style='margin-bottom:0in;margin-bottom:.0001pt;line-height:
+normal;text-autospace:none'><span style='font-size:9.5pt;font-family:Consolas'>     
+spriteBatch.Draw(craterTexture, r, <span style='color:blue'>null</span>, <span
+style='color:#2B91AF'>Color</span>.White, rotation, </span></p>
+
+<p class=MsoNormal style='margin-bottom:0in;margin-bottom:.0001pt;line-height:
+normal;text-autospace:none'><span style='font-size:9.5pt;font-family:Consolas'>                      
+origin, <span style='color:#2B91AF'>SpriteEffects</span>.None, 0);</span></p>
+
+<p class=MsoNormal style='margin-bottom:0in;margin-bottom:.0001pt;line-height:
+normal;text-autospace:none'><span style='font-size:9.5pt;font-family:Consolas'>&nbsp;</span></p>
+
+<p class=MsoNormal style='margin-bottom:0in;margin-bottom:.0001pt;line-height:
+normal;text-autospace:none'><span style='font-size:9.5pt;font-family:Consolas'>     
+spriteBatch.End();</span></p>
+
+<p class=MsoNormal style='margin-bottom:0in;margin-bottom:.0001pt;line-height:
+normal;text-autospace:none'><span style='font-size:9.5pt;font-family:Consolas'>&nbsp;</span></p>
+
+<p class=MsoNormal style='margin-bottom:0in;margin-bottom:.0001pt;line-height:
+normal;text-autospace:none'><span style='font-size:9.5pt;font-family:Consolas'>&nbsp;</span></p>
+
+<p class=MsoNormal style='margin-bottom:0in;margin-bottom:.0001pt;line-height:
+normal;text-autospace:none'><span style='font-size:9.5pt;font-family:Consolas'>&nbsp;</span></p>
+
+<h2>Draw the Planet Texture</h2>
+
+<p class=MsoNormal>Now we need to draw the latest planet texture, using the
+stencil buffer to mask out the craters (Steps 6-7). We begin a SpriteBatch,
+passing in the stencilKeepIfZero object we created earlier. Note that the first
+time we draw the actual planet texture, but subsequently we draw using the
+texture from the previous iteration.</p>
+
+<p class=MsoNormal style='margin-bottom:0in;margin-bottom:.0001pt;line-height:
+normal;text-autospace:none'><span style='font-size:9.5pt;font-family:Consolas'>&nbsp;</span></p>
+
+<p class=MsoNormal style='margin-bottom:0in;margin-bottom:.0001pt;line-height:
+normal;text-autospace:none'><span style='font-size:9.5pt;font-family:Consolas'>     
+spriteBatch.Begin(<span style='color:#2B91AF'>SpriteSortMode</span>.Immediate, <span
+style='color:#2B91AF'>BlendState</span>.Opaque,</span></p>
+
+<p class=MsoNormal style='margin-bottom:0in;margin-bottom:.0001pt;line-height:
+normal;text-autospace:none'><span style='font-size:9.5pt;font-family:Consolas'>                       
+<span style='color:blue'>null</span>, stencilKeepIfZero, <span
+style='color:blue'>null</span>, <span style='color:blue'>null</span>);</span></p>
+
+<p class=MsoNormal style='margin-bottom:0in;margin-bottom:.0001pt;line-height:
+normal;text-autospace:none'><span style='font-size:9.5pt;font-family:Consolas'>&nbsp;</span></p>
+
+<p class=MsoNormal style='margin-bottom:0in;margin-bottom:.0001pt;line-height:
+normal;text-autospace:none'><span style='font-size:9.5pt;font-family:Consolas'>     
+<span style='color:blue'>if</span> (firstTime)</span></p>
+
+<p class=MsoNormal style='margin-bottom:0in;margin-bottom:.0001pt;line-height:
+normal;text-autospace:none'><span style='font-size:9.5pt;font-family:Consolas'>     
+{</span></p>
+
+<p class=MsoNormal style='margin-bottom:0in;margin-bottom:.0001pt;line-height:
+normal;text-autospace:none'><span style='font-size:9.5pt;font-family:Consolas'>       
+spriteBatch.Draw(planetTexture, <span style='color:#2B91AF'>Vector2</span>.Zero,
+<span style='color:#2B91AF'>Color</span>.White);</span></p>
+
+<p class=MsoNormal style='margin-bottom:0in;margin-bottom:.0001pt;line-height:
+normal;text-autospace:none'><span style='font-size:9.5pt;font-family:Consolas'>       
+firstTime = <span style='color:blue'>false</span>;</span></p>
+
+<p class=MsoNormal style='margin-bottom:0in;margin-bottom:.0001pt;line-height:
+normal;text-autospace:none'><span style='font-size:9.5pt;font-family:Consolas'>     
+}</span></p>
+
+<p class=MsoNormal style='margin-bottom:0in;margin-bottom:.0001pt;line-height:
+normal;text-autospace:none'><span style='font-size:9.5pt;font-family:Consolas'>     
+<span style='color:blue'>else</span></span></p>
+
+<p class=MsoNormal style='margin-bottom:0in;margin-bottom:.0001pt;line-height:
+normal;text-autospace:none'><span style='font-size:9.5pt;font-family:Consolas'>       
+spriteBatch.Draw(textureRenderTarget, <span style='color:#2B91AF'>Vector2</span>.Zero,
+<span style='color:#2B91AF'>Color</span>.White);</span></p>
+
+<p class=MsoNormal style='margin-bottom:0in;margin-bottom:.0001pt;line-height:
+normal;text-autospace:none'><span style='font-size:9.5pt;font-family:Consolas'>&nbsp;</span></p>
+
+<p class=MsoNormal style='margin-bottom:0in;margin-bottom:.0001pt;line-height:
+normal;text-autospace:none'><span style='font-size:9.5pt;font-family:Consolas'>     
+spriteBatch.End();</span></p>
+
+<p class=MsoNormal style='margin-bottom:0in;margin-bottom:.0001pt;line-height:
+normal;text-autospace:none'><span style='font-size:9.5pt;font-family:Consolas'>&nbsp;</span></p>
+
+<p class=MsoNormal style='margin-bottom:0in;margin-bottom:.0001pt;line-height:
+normal;text-autospace:none'><span style='font-size:9.5pt;font-family:Consolas'>&nbsp;</span></p>
+
+<p class=MsoNormal style='margin-bottom:0in;margin-bottom:.0001pt;line-height:
+normal;text-autospace:none'><span style='font-size:9.5pt;font-family:Consolas'>&nbsp;</span></p>
+
+<h2>Swap Render Targets</h2>
+
+<p class=MsoNormal>Finally we activate the backbuffer render target.</p>
+
+<p class=MsoNormal style='margin-bottom:0in;margin-bottom:.0001pt;line-height:
+normal;text-autospace:none'><span style='font-size:9.5pt;font-family:Consolas'>&nbsp;</span></p>
+
+<p class=MsoNormal style='margin-bottom:0in;margin-bottom:.0001pt;line-height:
+normal;text-autospace:none'><span style='font-size:9.5pt;font-family:Consolas'>     
+GraphicsDevice.SetRenderTarget(<span style='color:blue'>null</span>);</span></p>
+
+<p class=MsoNormal style='margin-bottom:0in;margin-bottom:.0001pt;line-height:
+normal;text-autospace:none'><span style='font-size:9.5pt;font-family:Consolas'>&nbsp;</span></p>
+
+<p class=MsoNormal style='margin-bottom:0in;margin-bottom:.0001pt;line-height:
+normal;text-autospace:none'><span style='font-size:9.5pt;font-family:Consolas'>&nbsp;</span></p>
+
+<p class=MsoNormal>And then swap the render targets as discussed previously.</p>
+
+<p class=MsoNormal style='margin-bottom:0in;margin-bottom:.0001pt;line-height:
+normal;text-autospace:none'><span style='font-size:9.5pt;font-family:Consolas'>&nbsp;</span></p>
+
+<p class=MsoNormal style='margin-bottom:0in;margin-bottom:.0001pt;line-height:
+normal;text-autospace:none'><span style='font-size:9.5pt;font-family:Consolas'>     
+<span style='color:#2B91AF'>RenderTarget2D</span> t = activeRenderTarget;</span></p>
+
+<p class=MsoNormal style='margin-bottom:0in;margin-bottom:.0001pt;line-height:
+normal;text-autospace:none'><span style='font-size:9.5pt;font-family:Consolas'>     
+activeRenderTarget = textureRenderTarget;</span></p>
+
+<p class=MsoNormal style='margin-bottom:0in;margin-bottom:.0001pt;line-height:
+normal;text-autospace:none'><span style='font-size:9.5pt;font-family:Consolas'>     
+textureRenderTarget = t;</span></p>
+
+<p class=MsoNormal style='margin-bottom:0in;margin-bottom:.0001pt;line-height:
+normal;text-autospace:none'><span style='font-size:9.5pt;font-family:Consolas'>&nbsp;</span></p>
+
+<p class=MsoNormal style='margin-bottom:0in;margin-bottom:.0001pt;line-height:
+normal;text-autospace:none'><span style='font-size:9.5pt;font-family:Consolas'>&nbsp;</span></p>
+
+<p class=MsoNormal style='margin-bottom:0in;margin-bottom:.0001pt;line-height:
+normal;text-autospace:none'><span style='font-size:9.5pt;font-family:Consolas'>&nbsp;</span></p>
+
+<p class=MsoNormal>In the main Draw function, you draw the latest cratered
+planet using the textureRenderTarget. Of course, you need to deal with using
+the planet texture the first time through though. The downloadable code shows
+one simple way to do that.</p>
+
+<p class=MsoNormal style='margin-bottom:0in;margin-bottom:.0001pt;line-height:
+normal;text-autospace:none'><span style='font-size:9.5pt;font-family:Consolas'>&nbsp;</span></p>
+
+<p class=MsoNormal style='margin-bottom:0in;margin-bottom:.0001pt;line-height:
+normal;text-autospace:none'><span style='font-size:9.5pt;font-family:Consolas'>&nbsp;</span></p>
+
+<p class=MsoNormal style='margin-bottom:0in;margin-bottom:.0001pt;line-height:
+normal;text-autospace:none'><span style='font-size:9.5pt;font-family:Consolas'>     
+GraphicsDevice.Clear(<span style='color:#2B91AF'>Color</span>.CornflowerBlue);</span></p>
+
+<p class=MsoNormal style='margin-bottom:0in;margin-bottom:.0001pt;line-height:
+normal;text-autospace:none'><span style='font-size:9.5pt;font-family:Consolas'>&nbsp;</span></p>
+
+<p class=MsoNormal style='margin-bottom:0in;margin-bottom:.0001pt;line-height:
+normal;text-autospace:none'><span style='font-size:9.5pt;font-family:Consolas'>     
+spriteBatch.Begin();</span></p>
+
+<p class=MsoNormal style='margin-bottom:0in;margin-bottom:.0001pt;line-height:
+normal;text-autospace:none'><span style='font-size:9.5pt;font-family:Consolas'>     
+spriteBatch.Draw(textureRenderTarget, planetPosition, <span style='color:#2B91AF'>Color</span>.White);</span></p>
+
+<p class=MsoNormal style='margin-bottom:0in;margin-bottom:.0001pt;line-height:
+normal;text-autospace:none'><span style='font-size:9.5pt;font-family:Consolas'>     
+spriteBatch.End();</span></p>
+
+<p class=MsoNormal style='margin-bottom:0in;margin-bottom:.0001pt;line-height:
+normal;text-autospace:none'><span style='font-size:9.5pt;font-family:Consolas'>&nbsp;</span></p>
+
+<p class=MsoNormal style='margin-bottom:0in;margin-bottom:.0001pt;line-height:
+normal;text-autospace:none'><span style='font-size:9.5pt;font-family:Consolas'>&nbsp;</span></p>
+
+<p class=MsoNormal>&nbsp;</p>
+
+<h1>Conclusion</h1>
+
+<p class=MsoNormal>And there you have it, a powerful technique for altering
+textures during your game. Doing this entirely on the GPU is quite a bit more
+complex than GetData/SetData, but is well worth the extra trouble. </p>
+
+<p class=MsoNormal>There are some things you can do to improve this technique. If
+you need to add a lot of craters, rather than adding them one at a time you can
+batch them up for a while, then in Step 5 draw all of them at once.</p>
+
+<p class=MsoNormal>I hope you found this tutorial informative. Learning about
+render targets and stencil buffers opens up a whole new world of possibilities
+beyond just making craters. What other uses can you think of?</p>
+
+<p class=MsoNormal>&nbsp;</p>
+
+</div>
+
+</body>
+
+</html>

BIN
Samples/MacOS/StencilsCratersTutorial/Documentation/Stencil Buffer Craters_files/image001.jpg


BIN
Samples/MacOS/StencilsCratersTutorial/Documentation/Stencil Buffer Craters_files/image002.jpg


BIN
Samples/MacOS/StencilsCratersTutorial/Documentation/Stencil Buffer Craters_files/image003.jpg


BIN
Samples/MacOS/StencilsCratersTutorial/Documentation/Stencil Buffer Craters_files/image004.jpg


BIN
Samples/MacOS/StencilsCratersTutorial/Documentation/Stencil Buffer Craters_files/image005.jpg


BIN
Samples/MacOS/StencilsCratersTutorial/Documentation/crater.jpg


BIN
Samples/MacOS/StencilsCratersTutorial/Documentation/crater_mask.jpg


BIN
Samples/MacOS/StencilsCratersTutorial/Documentation/crater_planet.jpg


BIN
Samples/MacOS/StencilsCratersTutorial/Documentation/planet.jpg


BIN
Samples/MacOS/StencilsCratersTutorial/Documentation/planet_craters.jpg


BIN
Samples/MacOS/StencilsCratersTutorial/Game.ico


File diff suppressed because it is too large
+ 0 - 0
Samples/MacOS/StencilsCratersTutorial/Game1.cs


BIN
Samples/MacOS/StencilsCratersTutorial/GameThumbnail.png


+ 16 - 0
Samples/MacOS/StencilsCratersTutorial/Info.plist

@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>CFBundleIdentifier</key>
+	<string>com.yourcompany.StencilsCratersTutorial</string>
+	<key>CFBundleName</key>
+	<string>StencilsCratersTutorial</string>
+	<key>CFBundleVersion</key>
+	<string>1</string>
+	<key>LSMinimumSystemVersion</key>
+	<string>10.6</string>
+	<key>NSPrincipalClass</key>
+	<string>NSApplication</string>
+</dict>
+</plist>

+ 55 - 0
Samples/MacOS/StencilsCratersTutorial/Program.cs

@@ -0,0 +1,55 @@
+using System;
+
+namespace StencilCratersTutorial
+{
+#if WINDOWS || XBOX
+    static class Program
+    {
+        /// <summary>
+        /// The main entry point for the application.
+        /// </summary>
+        static void Main(string[] args)
+        {
+            using (Game1 game = new Game1())
+            {
+                game.Run();
+            }
+        }
+    }
+#endif
+#if MAC
+	static class Program
+	{
+		/// <summary>
+		/// The main entry point for the application.
+		/// </summary>
+		static void Main (string[] args)
+		{
+			MonoMac.AppKit.NSApplication.Init ();
+			
+			using (var p = new MonoMac.Foundation.NSAutoreleasePool ()) {
+				MonoMac.AppKit.NSApplication.SharedApplication.Delegate = new AppDelegate();
+				MonoMac.AppKit.NSApplication.Main(args);
+			}
+		}
+	}
+	
+	class AppDelegate : MonoMac.AppKit.NSApplicationDelegate
+	{
+		
+		public override void FinishedLaunching (MonoMac.Foundation.NSObject notification)
+		{
+			using (Game1 game = new Game1()) {
+				game.Run ();
+			}
+		}
+		
+		public override bool ApplicationShouldTerminateAfterLastWindowClosed (MonoMac.AppKit.NSApplication sender)
+		{
+			return true;
+		}
+	}
+
+#endif
+}
+

+ 65 - 0
Samples/MacOS/StencilsCratersTutorial/StencilsCratersTutorial.csproj

@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
+    <ProductVersion>10.0.0</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{CA462192-65AD-4403-9B27-08B02B28453E}</ProjectGuid>
+    <ProjectTypeGuids>{948B3504-5B70-4649-8FE4-BDE1FB46EC69};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+    <OutputType>Exe</OutputType>
+    <RootNamespace>StencilsCratersTutorial</RootNamespace>
+    <AssemblyName>StencilsCratersTutorial</AssemblyName>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug</OutputPath>
+    <DefineConstants>DEBUG;MAC</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <PlatformTarget>x86</PlatformTarget>
+    <ConsolePause>false</ConsolePause>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
+    <DebugType>none</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Release</OutputPath>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <PlatformTarget>x86</PlatformTarget>
+    <ConsolePause>false</ConsolePause>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Xml" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Drawing" />
+    <Reference Include="MonoMac" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="Info.plist" />
+    <None Include="Game.ico" />
+    <None Include="GameThumbnail.png" />
+    <None Include="Content\crater.xnb" />
+    <None Include="Content\planet.xnb" />
+  </ItemGroup>
+  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+  <Import Project="$(MSBuildExtensionsPath)\Mono\MonoMac\v0.0\Mono.MonoMac.targets" />
+  <ItemGroup>
+    <Compile Include="Game1.cs" />
+    <Compile Include="Program.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <Content Include="Content\crater.tga" />
+    <Content Include="Content\planet.tga" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\..\..\..\..\..\Users\Jimmy\Public\Share\MonoMacSource\kjpgit\MonoGame\MonoGame.Framework\MonoGame.Framework.MacOS.csproj">
+      <Project>{36C538E6-C32A-4A8D-A39C-566173D7118E}</Project>
+      <Name>MonoGame.Framework.MacOS</Name>
+    </ProjectReference>
+  </ItemGroup>
+</Project>

+ 37 - 0
Samples/MacOS/StencilsCratersTutorial/StencilsCratersTutorial.sln

@@ -0,0 +1,37 @@
+
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StencilsCratersTutorial", "StencilsCratersTutorial.csproj", "{CA462192-65AD-4403-9B27-08B02B28453E}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MonoGame.Framework.MacOS", "..\..\..\..\..\..\..\Users\Jimmy\Public\Share\MonoMacSource\kjpgit\MonoGame\MonoGame.Framework\MonoGame.Framework.MacOS.csproj", "{36C538E6-C32A-4A8D-A39C-566173D7118E}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lidgren.Network.MacOS", "..\..\..\..\..\..\..\Users\Jimmy\Public\Share\MonoMacSource\kjpgit\MonoGame\ThirdParty\Lidgren.Network\Lidgren.Network.MacOS.csproj", "{AE483C29-042E-4226-BA52-D247CE7676DA}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|x86 = Debug|x86
+		Release|x86 = Release|x86
+		Distribution|Any CPU = Distribution|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{36C538E6-C32A-4A8D-A39C-566173D7118E}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{36C538E6-C32A-4A8D-A39C-566173D7118E}.Debug|x86.Build.0 = Debug|Any CPU
+		{36C538E6-C32A-4A8D-A39C-566173D7118E}.Distribution|Any CPU.ActiveCfg = Distribution|Any CPU
+		{36C538E6-C32A-4A8D-A39C-566173D7118E}.Distribution|Any CPU.Build.0 = Distribution|Any CPU
+		{36C538E6-C32A-4A8D-A39C-566173D7118E}.Release|x86.ActiveCfg = Release|Any CPU
+		{36C538E6-C32A-4A8D-A39C-566173D7118E}.Release|x86.Build.0 = Release|Any CPU
+		{AE483C29-042E-4226-BA52-D247CE7676DA}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{AE483C29-042E-4226-BA52-D247CE7676DA}.Debug|x86.Build.0 = Debug|Any CPU
+		{AE483C29-042E-4226-BA52-D247CE7676DA}.Distribution|Any CPU.ActiveCfg = Debug|Any CPU
+		{AE483C29-042E-4226-BA52-D247CE7676DA}.Distribution|Any CPU.Build.0 = Debug|Any CPU
+		{AE483C29-042E-4226-BA52-D247CE7676DA}.Release|x86.ActiveCfg = Release|Any CPU
+		{AE483C29-042E-4226-BA52-D247CE7676DA}.Release|x86.Build.0 = Release|Any CPU
+		{CA462192-65AD-4403-9B27-08B02B28453E}.Debug|x86.ActiveCfg = Debug|x86
+		{CA462192-65AD-4403-9B27-08B02B28453E}.Debug|x86.Build.0 = Debug|x86
+		{CA462192-65AD-4403-9B27-08B02B28453E}.Release|x86.ActiveCfg = Release|x86
+		{CA462192-65AD-4403-9B27-08B02B28453E}.Release|x86.Build.0 = Release|x86
+	EndGlobalSection
+	GlobalSection(MonoDevelopProperties) = preSolution
+		StartupItem = StencilsCratersTutorial.csproj
+	EndGlobalSection
+EndGlobal

Some files were not shown because too many files changed in this diff